[RFC PATCH 33/55] KVM: x86: Report a real write-access walk from KVM_TRANSLATE
From: David Woodhouse
Date: Sat Oct 17 2026 - 08:49:26 EST
From: David Woodhouse <dwmw@xxxxxxxxxxxx>
KVM_TRANSLATE hardcodes writeable = 1, so userspace answering
HvCallTranslateVirtualAddress from this ioctl cannot honour the
hypercall's write-validation flag: validating write access against a
read-only PTE succeeds instead of reporting the address unmapped, and
the Windows secure kernel's page verification trusts a mapping it
cannot write.
Walk the address a second time with PFERR_WRITE_MASK at supervisor
level and report the outcome, matching the reference hypervisor's
validation walk.
Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
Assisted-by: LLM
---
arch/x86/kvm/x86.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index afd668c6db3f..491a0360c403 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -13305,10 +13305,19 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
idx = srcu_read_lock(&vcpu->kvm->srcu);
gpa = kvm_mmu_gva_to_gpa_system(vcpu, vaddr, NULL);
+ /*
+ * Report write access from a supervisor-level walk instead of the
+ * hardcoded 1: Hyper-V's TranslateVirtualAddress write validation
+ * is answered from this ioctl, and the reference hypervisor walks
+ * with PFERR_WRITE_MASK and no user bit.
+ */
+ tr->writeable = vcpu->arch.walk_mmu->gva_to_gpa(vcpu,
+ vcpu->arch.walk_mmu,
+ vaddr, PFERR_WRITE_MASK,
+ NULL) != INVALID_GPA;
srcu_read_unlock(&vcpu->kvm->srcu, idx);
tr->physical_address = gpa;
tr->valid = gpa != INVALID_GPA;
- tr->writeable = 1;
tr->usermode = 0;
vcpu_put(vcpu);
--
2.50.1