summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2026-04-08 11:42:07 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2026-05-10 14:55:06 +0200
commit9c167cb3c14c486e683fe4248a8309eb4dd3042b (patch)
treeaeec37180d611a5cb05ec2275b50b2bb0740165d /arch
parenta0efd8cb221fff20f511ecf759c42c076a513ebb (diff)
downloadlinux-next-9c167cb3c14c486e683fe4248a8309eb4dd3042b.tar.gz
linux-next-9c167cb3c14c486e683fe4248a8309eb4dd3042b.zip
KVM: nVMX: pass PFERR_USER_MASK to MMU on EPT violations
For EPT, PFERR_USER_MASK refers not to the CPL of the guest, but to the AND of the U bits encountered while walking guest page tables; this is consistent with how MBEC differentiates between XS and XU. This is available through the "advanced vmexit information for EPT violations" feature. Tested-by: David Riley <d.riley@proxmox.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/vmx/common.h12
-rw-r--r--arch/x86/kvm/vmx/vmx.c10
2 files changed, 19 insertions, 3 deletions
diff --git a/arch/x86/kvm/vmx/common.h b/arch/x86/kvm/vmx/common.h
index 40fa72f31fc7..08005676702c 100644
--- a/arch/x86/kvm/vmx/common.h
+++ b/arch/x86/kvm/vmx/common.h
@@ -100,9 +100,15 @@ static inline int __vmx_handle_ept_violation(struct kvm_vcpu *vcpu, gpa_t gpa,
error_code |= (exit_qualification & EPT_VIOLATION_PROT_USER_EXEC)
? PFERR_PRESENT_MASK : 0;
- if (exit_qualification & EPT_VIOLATION_GVA_IS_VALID)
- error_code |= (exit_qualification & EPT_VIOLATION_GVA_TRANSLATED) ?
- PFERR_GUEST_FINAL_MASK : PFERR_GUEST_PAGE_MASK;
+ if (exit_qualification & EPT_VIOLATION_GVA_IS_VALID) {
+ if (exit_qualification & EPT_VIOLATION_GVA_TRANSLATED) {
+ error_code |= PFERR_GUEST_FINAL_MASK;
+ if (exit_qualification & EPT_VIOLATION_GVA_USER)
+ error_code |= PFERR_USER_MASK;
+ } else {
+ error_code |= PFERR_GUEST_PAGE_MASK;
+ }
+ }
if (vt_is_tdx_private_gpa(vcpu->kvm, gpa))
error_code |= PFERR_PRIVATE_ACCESS;
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index d9ba9f14ffd1..3173b3a73836 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -2790,6 +2790,16 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf,
vmx_cap->vpid = 0;
}
+ /*
+ * Virtualizing MBEC requires advanced vmexit information in order to
+ * distinguish supervisor and user accesses. For simplicity and clarity
+ * disable MBEC entirely if advanced vmexit information is not available,
+ * this way mbec=1 in the kvm_intel module parameters implies availability
+ * to nested guests as well.
+ */
+ if (!(vmx_cap->ept & VMX_EPT_ADVANCED_VMEXIT_INFO_BIT))
+ _cpu_based_2nd_exec_control &= ~SECONDARY_EXEC_MODE_BASED_EPT_EXEC;
+
if (!cpu_has_sgx())
_cpu_based_2nd_exec_control &= ~SECONDARY_EXEC_ENCLS_EXITING;