Skip to contentSkip to conversation

KVM: nVMX: consult PFEC_MASK and PFEC_MATCH when generating #PF VM-exit

PATCH Superseded Eugene Korenevsky 2 participants 2 messages Dec 15, 2014 – Dec 16, 2014

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 KVM: nVMX: consult PFEC_MASK and PFEC_MATCH when generating #PF VM-exit

When generating #PF VM-exit, check equality:
(PFEC & PFEC_MASK) == PFEC_MATCH
If there is equality, the 14 bit of exception bitmap is used to take decision about generating #PF VM-exit. If there is inequality, inverted 14 bit is used.

---
 arch/x86/kvm/vmx.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx.c +13 -2
index ddb28e2..74d6ad4 100644
@@ -8206,6 +8206,18 @@ static void nested_ept_uninit_mmu_context(struct kvm_vcpu *vcpu)
 	vcpu->arch.walk_mmu = &vcpu->arch.mmu;
 }
 
+static bool nested_vmx_is_page_fault_vmexit(struct vmcs12 *vmcs12,
+					    u16 error_code)
+{
+	u32 inequality, bit;
+
+	bit = (vmcs12->exception_bitmap & (1u << PF_VECTOR)) ? 1u : 0;
+	inequality =
+		(error_code & vmcs12->page_fault_error_code_mask) !=
+		 vmcs12->page_fault_error_code_match ? 1u : 0;
+	return (inequality ^ bit) != 0;
+}
+
 static void vmx_inject_page_fault_nested(struct kvm_vcpu *vcpu,
 		struct x86_exception *fault)
 {
@@ -8213,8 +8225,7 @@ static void vmx_inject_page_fault_nested(struct kvm_vcpu *vcpu,
 
 	WARN_ON(!is_guest_mode(vcpu));
 
-	/* TODO: also check PFEC_MATCH/MASK, not just EB.PF. */
-	if (vmcs12->exception_bitmap & (1u << PF_VECTOR))
+	if (nested_vmx_is_page_fault_vmexit(vmcs12, fault->error_code))
 		nested_vmx_vmexit(vcpu, to_vmx(vcpu)->exit_reason,
 				  vmcs_read32(VM_EXIT_INTR_INFO),
 				  vmcs_readl(EXIT_QUALIFICATION));
Signature · 1 line
2.0.4
maintainer
#1 lore raw

arch/x86/kvm/vmx.c static void nested_ept_uninit_mmu_context(struct kvm_vcpu *vcpu) · line 8217

Quoted 6 lines · Eugene Korenevsky
arch/x86/kvm/vmx.c +6 -0
+	u32 inequality, bit;
+
+	bit = (vmcs12->exception_bitmap & (1u << PF_VECTOR)) ? 1u : 0;
+	inequality =
+		(error_code & vmcs12->page_fault_error_code_mask) !=
+		 vmcs12->page_fault_error_code_match ? 1u : 0;

You should either remove "? 1u : 0" (which is redundant), or flip the bit in the exception bitmap, like

    inequality = ...
          ? (1u << PF_VECTOR) : 0;
    return ((vmcs12->exception_bitmap ^ inequality)
            & (1u << PF_VECTOR)) != 0;

If you choose the former, please use "!= 0" in the assignment of "bit" instead of the ternary operator, and make the two variables bool. Then you can remove the "!= 0" in the "return" below.

Paolo

Quoted 2 lines
arch/x86/kvm/vmx.c +2 -0
+	return (inequality ^ bit) != 0;
+}