Skip to content

Commit 251e484

Browse files
yosrym93sean-jc
authored andcommitted
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: Yosry Ahmed <yosry.ahmed@linux.dev> Link: https://patch.msgid.link/20251230230150.4150236-18-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 753c0d5 commit 251e484

4 files changed

Lines changed: 9 additions & 2 deletions

File tree

tools/testing/selftests/kvm/include/x86/kvm_util_arch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ struct pte_masks {
2222
uint64_t nx;
2323
uint64_t c;
2424
uint64_t s;
25+
26+
uint64_t always_set;
2527
};
2628

2729
struct kvm_mmu_arch {

tools/testing/selftests/kvm/include/x86/processor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,7 @@ enum pg_level {
14521452
#define PTE_NX_MASK(mmu) ((mmu)->arch.pte_masks.nx)
14531453
#define PTE_C_BIT_MASK(mmu) ((mmu)->arch.pte_masks.c)
14541454
#define PTE_S_BIT_MASK(mmu) ((mmu)->arch.pte_masks.s)
1455+
#define PTE_ALWAYS_SET_MASK(mmu) ((mmu)->arch.pte_masks.always_set)
14551456

14561457
/*
14571458
* For PTEs without a PRESENT bit (i.e. EPT entries), treat the PTE as present

tools/testing/selftests/kvm/lib/x86/processor.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *vm,
231231

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

304305
/*
305306
* Neither SEV nor TDX supports shared page tables, so only the final

tools/testing/selftests/kvm/lib/x86/svm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ void vm_enable_npt(struct kvm_vm *vm)
7575
pte_masks = vm->mmu.arch.pte_masks;
7676
pte_masks.c = 0;
7777

78+
/* NPT walks are treated as user accesses, so set the 'user' bit. */
79+
pte_masks.always_set = pte_masks.user;
80+
7881
tdp_mmu_init(vm, vm->mmu.pgtable_levels, &pte_masks);
7982
}
8083

0 commit comments

Comments
 (0)