Commit 251e4849 authored by Yosry Ahmed's avatar Yosry Ahmed Committed by Sean Christopherson
Browse files

KVM: selftests: Set the user bit on nested NPT PTEs



According to the APM, NPT walks are treated as user accesses. In
preparation for supporting NPT mappings, set the 'user' bit on NPTs by
adding a mask of bits to always be set on PTEs in kvm_mmu.

Signed-off-by: default avatarYosry Ahmed <yosry.ahmed@linux.dev>
Link: https://patch.msgid.link/20251230230150.4150236-18-seanjc@google.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent 753c0d5a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ struct pte_masks {
	uint64_t nx;
	uint64_t c;
	uint64_t s;

	uint64_t always_set;
};

struct kvm_mmu_arch {
+1 −0
Original line number Diff line number Diff line
@@ -1452,6 +1452,7 @@ enum pg_level {
#define PTE_NX_MASK(mmu)		((mmu)->arch.pte_masks.nx)
#define PTE_C_BIT_MASK(mmu)		((mmu)->arch.pte_masks.c)
#define PTE_S_BIT_MASK(mmu)		((mmu)->arch.pte_masks.s)
#define PTE_ALWAYS_SET_MASK(mmu)	((mmu)->arch.pte_masks.always_set)

/*
 * For PTEs without a PRESENT bit (i.e. EPT entries), treat the PTE as present
+3 −2
Original line number Diff line number Diff line
@@ -231,7 +231,8 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *vm,

	if (!is_present_pte(mmu, pte)) {
		*pte = PTE_PRESENT_MASK(mmu) | PTE_READABLE_MASK(mmu) |
		       PTE_WRITABLE_MASK(mmu) | PTE_EXECUTABLE_MASK(mmu);
		       PTE_WRITABLE_MASK(mmu) | PTE_EXECUTABLE_MASK(mmu) |
		       PTE_ALWAYS_SET_MASK(mmu);
		if (current_level == target_level)
			*pte |= PTE_HUGE_MASK(mmu) | (paddr & PHYSICAL_PAGE_MASK);
		else
@@ -299,7 +300,7 @@ void __virt_pg_map(struct kvm_vm *vm, struct kvm_mmu *mmu, uint64_t vaddr,
		    "PTE already present for 4k page at vaddr: 0x%lx", vaddr);
	*pte = PTE_PRESENT_MASK(mmu) | PTE_READABLE_MASK(mmu) |
	       PTE_WRITABLE_MASK(mmu) | PTE_EXECUTABLE_MASK(mmu) |
	       (paddr & PHYSICAL_PAGE_MASK);
	       PTE_ALWAYS_SET_MASK(mmu) | (paddr & PHYSICAL_PAGE_MASK);

	/*
	 * Neither SEV nor TDX supports shared page tables, so only the final
+3 −0
Original line number Diff line number Diff line
@@ -75,6 +75,9 @@ void vm_enable_npt(struct kvm_vm *vm)
	pte_masks = vm->mmu.arch.pte_masks;
	pte_masks.c = 0;

	/* NPT walks are treated as user accesses, so set the 'user' bit. */
	pte_masks.always_set = pte_masks.user;

	tdp_mmu_init(vm, vm->mmu.pgtable_levels, &pte_masks);
}