mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-25 22:43:35 -04:00
KVM: nVMX: pass advanced EPT violation vmexit info to guest
KVM will use advanced vmexit information for EPT violations to virtualize MBEC. Pass it to the guest since it is easy and allows testing nested nested. Tested-by: David Riley <d.riley@proxmox.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
@@ -535,6 +535,7 @@ enum vmcs_field {
|
||||
#define VMX_EPT_1GB_PAGE_BIT (1ull << 17)
|
||||
#define VMX_EPT_INVEPT_BIT (1ull << 20)
|
||||
#define VMX_EPT_AD_BIT (1ull << 21)
|
||||
#define VMX_EPT_ADVANCED_VMEXIT_INFO_BIT (1ull << 22)
|
||||
#define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25)
|
||||
#define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26)
|
||||
|
||||
@@ -617,6 +618,9 @@ enum vm_entry_failure_code {
|
||||
EPT_VIOLATION_PROT_USER_EXEC)
|
||||
#define EPT_VIOLATION_GVA_IS_VALID BIT(7)
|
||||
#define EPT_VIOLATION_GVA_TRANSLATED BIT(8)
|
||||
#define EPT_VIOLATION_GVA_USER BIT(9)
|
||||
#define EPT_VIOLATION_GVA_WRITABLE BIT(10)
|
||||
#define EPT_VIOLATION_GVA_NX BIT(11)
|
||||
|
||||
#define EPT_VIOLATION_RWX_TO_PROT(__epte) (((__epte) & VMX_EPT_RWX_MASK) << 3)
|
||||
#define EPT_VIOLATION_USER_EXEC_TO_PROT(__epte) (((__epte) & VMX_EPT_USER_EXECUTABLE_MASK) >> 4)
|
||||
|
||||
@@ -494,7 +494,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
|
||||
* [2:0] - Derive from the access bits. The exit_qualification might be
|
||||
* out of date if it is serving an EPT misconfiguration.
|
||||
* [5:3] - Calculated by the page walk of the guest EPT page tables
|
||||
* [7:8] - Derived from [7:8] of real exit_qualification
|
||||
* [7:11] - Derived from [7:11] of real exit_qualification
|
||||
*
|
||||
* The other bits are set to 0.
|
||||
*/
|
||||
|
||||
@@ -443,10 +443,14 @@ static void nested_ept_inject_page_fault(struct kvm_vcpu *vcpu,
|
||||
vm_exit_reason = EXIT_REASON_EPT_MISCONFIG;
|
||||
exit_qualification = 0;
|
||||
} else {
|
||||
u64 mask = EPT_VIOLATION_GVA_IS_VALID |
|
||||
EPT_VIOLATION_GVA_TRANSLATED;
|
||||
if (vmx->nested.msrs.ept_caps & VMX_EPT_ADVANCED_VMEXIT_INFO_BIT)
|
||||
mask |= EPT_VIOLATION_GVA_USER |
|
||||
EPT_VIOLATION_GVA_WRITABLE |
|
||||
EPT_VIOLATION_GVA_NX;
|
||||
exit_qualification = fault->exit_qualification;
|
||||
exit_qualification |= vmx_get_exit_qual(vcpu) &
|
||||
(EPT_VIOLATION_GVA_IS_VALID |
|
||||
EPT_VIOLATION_GVA_TRANSLATED);
|
||||
exit_qualification |= vmx_get_exit_qual(vcpu) & mask;
|
||||
vm_exit_reason = EXIT_REASON_EPT_VIOLATION;
|
||||
}
|
||||
|
||||
@@ -7240,7 +7244,8 @@ static void nested_vmx_setup_secondary_ctls(u32 ept_caps,
|
||||
VMX_EPT_PAGE_WALK_5_BIT |
|
||||
VMX_EPTP_WB_BIT |
|
||||
VMX_EPT_INVEPT_BIT |
|
||||
VMX_EPT_EXECUTE_ONLY_BIT;
|
||||
VMX_EPT_EXECUTE_ONLY_BIT |
|
||||
VMX_EPT_ADVANCED_VMEXIT_INFO_BIT;
|
||||
|
||||
msrs->ept_caps &= ept_caps;
|
||||
msrs->ept_caps |= VMX_EPT_EXTENT_GLOBAL_BIT |
|
||||
|
||||
Reference in New Issue
Block a user