[PATCH v3 2/7] KVM: SVM: Check that RAX has legal GPA on #GP interception of SVM insns

Yosry Ahmed posted 7 patches 3 weeks, 4 days ago
There is a newer version of this series
[PATCH v3 2/7] KVM: SVM: Check that RAX has legal GPA on #GP interception of SVM insns
Posted by Yosry Ahmed 3 weeks, 4 days ago
KVM intercepts #GP when EFER.SVME is set if the CPU does not have
X86_FEATURE_SVME_ADDR_CHK to work around an erratum where some CPUs
check EAX against reserved memory regions. KVM re-injects the #GP if an
SVM instruction was executed with mis-aligned RAX, and it otherwise
emulates it.

However, a #GP should also be reinjected if RAX contains an illegal GPA,
according to the APM, one of #GP conditions is:

  rAX referenced a physical address above the maximum
  supported physical address.

Replace the PAGE_MASK check with page_address_valid(), which checks both
page-alignment as well as the legality of the GPA based on the vCPU's
MAXPHYADDR.

Note that this is currently not a problem, because kvm_vcpu_map() should
fail on illegal GPAs and inject a #GP anyway. However, following patches
will change the failure behavior of kvm_vcpu_map(), so make sure the #GP
interception handler does this appropriately.

Fixes: 82a11e9c6fa2 ("KVM: SVM: Add emulation support for #GP triggered by SVM instructions")
Fixes: d1cba6c92237 ("KVM: x86: nSVM: test eax for 4K alignment for GP errata workaround")
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Yosry Ahmed <yosry@kernel.org>
---
 arch/x86/kvm/svm/svm.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index d98fbc0e58e8f..796a6887305d6 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -2319,8 +2319,7 @@ static int gp_interception(struct kvm_vcpu *vcpu)
 			return kvm_emulate_instruction(vcpu,
 				EMULTYPE_VMWARE_GP | EMULTYPE_NO_DECODE);
 	} else {
-		/* All SVM instructions expect page aligned RAX */
-		if (svm->vmcb->save.rax & ~PAGE_MASK)
+		if (!page_address_valid(vcpu, svm->vmcb->save.rax))
 			goto reinject;
 
 		return emulate_svm_instr(vcpu, opcode);
-- 
2.53.0.851.ga537e3e6e9-goog