KVM: VMX: Skip #PF(RSVD) intercepts when emulating smaller maxphyaddr
As part of smaller maxphyaddr emulation, kvm needs to intercept present page faults to see if it needs to add the RSVD flag (bit 3) to the error code. However, there is no need to intercept page faults that already have the RSVD flag set. When setting up the page fault intercept, add the RSVD flag into the #PF error code mask field (but not the #PF error code match field) to skip the intercept when the RSVD flag is already set. Signed-off-by: Jim Mattson <jmattson@google.com> Message-Id: <20210618235941.1041604-1-jmattson@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Родитель
0485cf8dbe
Коммит
5140bc7d6b
|
@ -747,16 +747,21 @@ void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu)
|
||||||
if (is_guest_mode(vcpu))
|
if (is_guest_mode(vcpu))
|
||||||
eb |= get_vmcs12(vcpu)->exception_bitmap;
|
eb |= get_vmcs12(vcpu)->exception_bitmap;
|
||||||
else {
|
else {
|
||||||
/*
|
int mask = 0, match = 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
|
if (enable_ept && (eb & (1u << PF_VECTOR))) {
|
||||||
* faults. For vmcs02, however, PFEC_MASK and PFEC_MATCH are set in
|
/*
|
||||||
* prepare_vmcs02_rare.
|
* If EPT is enabled, #PF is currently only intercepted
|
||||||
*/
|
* if MAXPHYADDR is smaller on the guest than on the
|
||||||
bool selective_pf_trap = enable_ept && (eb & (1u << PF_VECTOR));
|
* host. In that case we only care about present,
|
||||||
int mask = selective_pf_trap ? PFERR_PRESENT_MASK : 0;
|
* non-reserved faults. For vmcs02, however, PFEC_MASK
|
||||||
|
* and PFEC_MATCH are set in prepare_vmcs02_rare.
|
||||||
|
*/
|
||||||
|
mask = PFERR_PRESENT_MASK | PFERR_RSVD_MASK;
|
||||||
|
match = PFERR_PRESENT_MASK;
|
||||||
|
}
|
||||||
vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, mask);
|
vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, mask);
|
||||||
vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, mask);
|
vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, match);
|
||||||
}
|
}
|
||||||
|
|
||||||
vmcs_write32(EXCEPTION_BITMAP, eb);
|
vmcs_write32(EXCEPTION_BITMAP, eb);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче