Commit 61146f67 authored by Sean Christopherson's avatar Sean Christopherson
Browse files

KVM: nVMX: Decouple EPT RWX bits from EPT Violation protection bits



Define independent macros for the RWX protection bits that are enumerated
via EXIT_QUALIFICATION for EPT Violations, and tie them to the RWX bits in
EPT entries via compile-time asserts.  Piggybacking the EPTE defines works
for now, but it creates holes in the EPT_VIOLATION_xxx macros and will
cause headaches if/when KVM emulates Mode-Based Execution (MBEC), or any
other features that introduces additional protection information.

Opportunistically rename EPT_VIOLATION_RWX_MASK to EPT_VIOLATION_PROT_MASK
so that it doesn't become stale if/when MBEC support is added.

No functional change intended.

Cc: Jon Kohler <jon@nutanix.com>
Cc: Nikolay Borisov <nik.borisov@suse.com>
Reviewed-by: default avatarNikolay Borisov <nik.borisov@suse.com>
Link: https://lore.kernel.org/r/20250227000705.3199706-3-seanjc@google.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent fa6c8fc2
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -580,14 +580,23 @@ enum vm_entry_failure_code {
/*
 * Exit Qualifications for EPT Violations
 */
#define EPT_VIOLATION_RWX_SHIFT		3
#define EPT_VIOLATION_ACC_READ		BIT(0)
#define EPT_VIOLATION_ACC_WRITE		BIT(1)
#define EPT_VIOLATION_ACC_INSTR		BIT(2)
#define EPT_VIOLATION_RWX_MASK		(VMX_EPT_RWX_MASK << EPT_VIOLATION_RWX_SHIFT)
#define EPT_VIOLATION_PROT_READ		BIT(3)
#define EPT_VIOLATION_PROT_WRITE	BIT(4)
#define EPT_VIOLATION_PROT_EXEC		BIT(5)
#define EPT_VIOLATION_PROT_MASK		(EPT_VIOLATION_PROT_READ  | \
					 EPT_VIOLATION_PROT_WRITE | \
					 EPT_VIOLATION_PROT_EXEC)
#define EPT_VIOLATION_GVA_IS_VALID	BIT(7)
#define EPT_VIOLATION_GVA_TRANSLATED	BIT(8)

#define EPT_VIOLATION_RWX_TO_PROT(__epte) (((__epte) & VMX_EPT_RWX_MASK) << 3)

static_assert(EPT_VIOLATION_RWX_TO_PROT(VMX_EPT_RWX_MASK) ==
	      (EPT_VIOLATION_PROT_READ | EPT_VIOLATION_PROT_WRITE | EPT_VIOLATION_PROT_EXEC));

/*
 * Exit Qualifications for NOTIFY VM EXIT
 */
+1 −2
Original line number Diff line number Diff line
@@ -510,8 +510,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
		 * Note, pte_access holds the raw RWX bits from the EPTE, not
		 * ACC_*_MASK flags!
		 */
		walker->fault.exit_qualification |= (pte_access & VMX_EPT_RWX_MASK) <<
						     EPT_VIOLATION_RWX_SHIFT;
		walker->fault.exit_qualification |= EPT_VIOLATION_RWX_TO_PROT(pte_access);
	}
#endif
	walker->fault.address = addr;
+1 −1
Original line number Diff line number Diff line
@@ -5822,7 +5822,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
	error_code |= (exit_qualification & EPT_VIOLATION_ACC_INSTR)
		      ? PFERR_FETCH_MASK : 0;
	/* ept page table entry is present? */
	error_code |= (exit_qualification & EPT_VIOLATION_RWX_MASK)
	error_code |= (exit_qualification & EPT_VIOLATION_PROT_MASK)
		      ? PFERR_PRESENT_MASK : 0;

	if (error_code & EPT_VIOLATION_GVA_IS_VALID)