KVM: nVMX: consult PFEC_MASK and PFEC_MATCH when generating #PF VM-exit
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.
Signed-off-by Eugene Korenevsky <[email protected]>
--- arch/x86/kvm/vmx.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx.c +13 -2
@@ -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
Paolo Bonzini
maintainerarch/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 ; +}