Skip to content

Commit a0c1343

Browse files
committed
KVM: VMX: introduce vmx_need_pf_intercept
Signed-off-by: Paolo Bonzini <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 32de2b5 commit a0c1343

File tree

3 files changed

+23
-12
lines changed

3 files changed

+23
-12
lines changed

arch/x86/kvm/vmx/nested.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,22 +2438,28 @@ static void prepare_vmcs02_rare(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12)
24382438

24392439
/*
24402440
* Whether page-faults are trapped is determined by a combination of
2441-
* 3 settings: PFEC_MASK, PFEC_MATCH and EXCEPTION_BITMAP.PF.
2442-
* If enable_ept, L0 doesn't care about page faults and we should
2443-
* set all of these to L1's desires. However, if !enable_ept, L0 does
2444-
* care about (at least some) page faults, and because it is not easy
2445-
* (if at all possible?) to merge L0 and L1's desires, we simply ask
2446-
* to exit on each and every L2 page fault. This is done by setting
2447-
* MASK=MATCH=0 and (see below) EB.PF=1.
2441+
* 3 settings: PFEC_MASK, PFEC_MATCH and EXCEPTION_BITMAP.PF. If L0
2442+
* doesn't care about page faults then we should set all of these to
2443+
* L1's desires. However, if L0 does care about (some) page faults, it
2444+
* is not easy (if at all possible?) to merge L0 and L1's desires, we
2445+
* simply ask to exit on each and every L2 page fault. This is done by
2446+
* setting MASK=MATCH=0 and (see below) EB.PF=1.
24482447
* Note that below we don't need special code to set EB.PF beyond the
24492448
* "or"ing of the EB of vmcs01 and vmcs12, because when enable_ept,
24502449
* vmcs01's EB.PF is 0 so the "or" will take vmcs12's value, and when
24512450
* !enable_ept, EB.PF is 1, so the "or" will always be 1.
24522451
*/
2453-
vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK,
2454-
enable_ept ? vmcs12->page_fault_error_code_mask : 0);
2455-
vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH,
2456-
enable_ept ? vmcs12->page_fault_error_code_match : 0);
2452+
if (vmx_need_pf_intercept(&vmx->vcpu)) {
2453+
/*
2454+
* TODO: if both L0 and L1 need the same MASK and MATCH,
2455+
* go ahead and use it?
2456+
*/
2457+
vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, 0);
2458+
vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, 0);
2459+
} else {
2460+
vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, vmcs12->page_fault_error_code_mask);
2461+
vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, vmcs12->page_fault_error_code_match);
2462+
}
24572463

24582464
if (cpu_has_vmx_apicv()) {
24592465
vmcs_write64(EOI_EXIT_BITMAP0, vmcs12->eoi_exit_bitmap0);

arch/x86/kvm/vmx/vmx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ void update_exception_bitmap(struct kvm_vcpu *vcpu)
780780
eb |= 1u << BP_VECTOR;
781781
if (to_vmx(vcpu)->rmode.vm86_active)
782782
eb = ~0;
783-
if (enable_ept)
783+
if (!vmx_need_pf_intercept(vcpu))
784784
eb &= ~(1u << PF_VECTOR);
785785

786786
/* When we are running a nested L2 guest and L1 specified for it a

arch/x86/kvm/vmx/vmx.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,11 @@ static inline bool vmx_has_waitpkg(struct vcpu_vmx *vmx)
550550
SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
551551
}
552552

553+
static inline bool vmx_need_pf_intercept(struct kvm_vcpu *vcpu)
554+
{
555+
return !enable_ept;
556+
}
557+
553558
void dump_vmcs(void);
554559

555560
#endif /* __KVM_X86_VMX_H */

0 commit comments

Comments
 (0)