Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[muen/linux.git] / arch / x86 / kvm / vmx / vmx.c
index 7b2a068..96979c0 100644 (file)
@@ -794,6 +794,18 @@ void update_exception_bitmap(struct kvm_vcpu *vcpu)
         */
        if (is_guest_mode(vcpu))
                eb |= get_vmcs12(vcpu)->exception_bitmap;
+        else {
+               /*
+                * If EPT is enabled, #PF is only trapped if MAXPHYADDR is mismatched
+                * between guest and host.  In that case we only care about present
+                * faults.  For vmcs02, however, PFEC_MASK and PFEC_MATCH are set in
+                * prepare_vmcs02_rare.
+                */
+               bool selective_pf_trap = enable_ept && (eb & (1u << PF_VECTOR));
+               int mask = selective_pf_trap ? PFERR_PRESENT_MASK : 0;
+               vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, mask);
+               vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, mask);
+       }
 
        vmcs_write32(EXCEPTION_BITMAP, eb);
 }
@@ -4355,16 +4367,6 @@ static void init_vmcs(struct vcpu_vmx *vmx)
                vmx->pt_desc.guest.output_mask = 0x7F;
                vmcs_write64(GUEST_IA32_RTIT_CTL, 0);
        }
-
-       /*
-        * If EPT is enabled, #PF is only trapped if MAXPHYADDR is mismatched
-        * between guest and host.  In that case we only care about present
-        * faults.
-        */
-       if (enable_ept) {
-               vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, PFERR_PRESENT_MASK);
-               vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, PFERR_PRESENT_MASK);
-       }
 }
 
 static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)