Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: arm64: nv: Respect stage-2 write permssion when setting stage-1 AF

Naturally, updating the Access Flag in a stage-1 descriptor requires
write permission at stage-2, although this isn't actually enforced in
KVM's software PTW.

Generate a stage-2 permission fault if the stage-1 walk attempts to
update the descriptor and its corresponding stage-2 translation lacks
write permission.

Fixes: bff8aa213dee ("KVM: arm64: Implement HW access flag management in stage-1 SW PTW")
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://msgid.link/20260108204230.677172-1-oupton@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>

+6 -2
+6 -2
arch/arm64/kvm/at.c
··· 403 403 struct s1_walk_result *wr, u64 va) 404 404 { 405 405 u64 va_top, va_bottom, baddr, desc, new_desc, ipa; 406 + struct kvm_s2_trans s2_trans = {}; 406 407 int level, stride, ret; 407 408 408 409 level = wi->sl; ··· 421 420 ipa = baddr | index; 422 421 423 422 if (wi->s2) { 424 - struct kvm_s2_trans s2_trans = {}; 425 - 426 423 ret = kvm_walk_nested_s2(vcpu, ipa, &s2_trans); 427 424 if (ret) { 428 425 fail_s1_walk(wr, ··· 514 515 new_desc |= PTE_AF; 515 516 516 517 if (new_desc != desc) { 518 + if (wi->s2 && !kvm_s2_trans_writable(&s2_trans)) { 519 + fail_s1_walk(wr, ESR_ELx_FSC_PERM_L(level), true); 520 + return -EPERM; 521 + } 522 + 517 523 ret = kvm_swap_s1_desc(vcpu, ipa, desc, new_desc, wi); 518 524 if (ret) 519 525 return ret;