KVM: selftests: Move TDP mapping functions outside of vmx.c

Now that the functions are no longer VMX-specific, move them to
processor.c. Do a minor comment tweak replacing 'EPT' with 'TDP'.

No functional change intended.

Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
Link: https://patch.msgid.link/20251230230150.4150236-15-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
Sean Christopherson 2025-12-30 15:01:43 -08:00
parent 508d1cc3ca
commit 07676c04bd
4 changed files with 57 additions and 74 deletions

View File

@ -1479,6 +1479,10 @@ void __virt_pg_map(struct kvm_vm *vm, struct kvm_mmu *mmu, uint64_t vaddr,
void virt_map_level(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
uint64_t nr_bytes, int level);
void tdp_map(struct kvm_vm *vm, uint64_t nested_paddr, uint64_t paddr, uint64_t size);
void tdp_identity_map_default_memslots(struct kvm_vm *vm);
void tdp_identity_map_1g(struct kvm_vm *vm, uint64_t addr, uint64_t size);
/*
* Basic CPU control in CR0
*/

View File

@ -557,9 +557,6 @@ bool load_vmcs(struct vmx_pages *vmx);
bool ept_1g_pages_supported(void);
void tdp_map(struct kvm_vm *vm, uint64_t nested_paddr, uint64_t paddr, uint64_t size);
void tdp_identity_map_default_memslots(struct kvm_vm *vm);
void tdp_identity_map_1g(struct kvm_vm *vm, uint64_t addr, uint64_t size);
bool kvm_cpu_has_ept(void);
void vm_enable_ept(struct kvm_vm *vm);
void prepare_virtualize_apic_accesses(struct vmx_pages *vmx, struct kvm_vm *vm);

View File

@ -472,6 +472,59 @@ void virt_arch_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
}
}
void __tdp_map(struct kvm_vm *vm, uint64_t nested_paddr, uint64_t paddr,
uint64_t size, int level)
{
size_t page_size = PG_LEVEL_SIZE(level);
size_t npages = size / page_size;
TEST_ASSERT(nested_paddr + size > nested_paddr, "Vaddr overflow");
TEST_ASSERT(paddr + size > paddr, "Paddr overflow");
while (npages--) {
__virt_pg_map(vm, &vm->stage2_mmu, nested_paddr, paddr, level);
nested_paddr += page_size;
paddr += page_size;
}
}
void tdp_map(struct kvm_vm *vm, uint64_t nested_paddr, uint64_t paddr,
uint64_t size)
{
__tdp_map(vm, nested_paddr, paddr, size, PG_LEVEL_4K);
}
/* Prepare an identity extended page table that maps all the
* physical pages in VM.
*/
void tdp_identity_map_default_memslots(struct kvm_vm *vm)
{
uint32_t s, memslot = 0;
sparsebit_idx_t i, last;
struct userspace_mem_region *region = memslot2region(vm, memslot);
/* Only memslot 0 is mapped here, ensure it's the only one being used */
for (s = 0; s < NR_MEM_REGIONS; s++)
TEST_ASSERT_EQ(vm->memslots[s], 0);
i = (region->region.guest_phys_addr >> vm->page_shift) - 1;
last = i + (region->region.memory_size >> vm->page_shift);
for (;;) {
i = sparsebit_next_clear(region->unused_phy_pages, i);
if (i > last)
break;
tdp_map(vm, (uint64_t)i << vm->page_shift,
(uint64_t)i << vm->page_shift, 1 << vm->page_shift);
}
}
/* Identity map a region with 1GiB Pages. */
void tdp_identity_map_1g(struct kvm_vm *vm, uint64_t addr, uint64_t size)
{
__tdp_map(vm, addr, addr, size, PG_LEVEL_1G);
}
/*
* Set Unusable Segment
*

View File

@ -373,77 +373,6 @@ void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp)
init_vmcs_guest_state(guest_rip, guest_rsp);
}
/*
* Map a range of EPT guest physical addresses to the VM's physical address
*
* Input Args:
* vm - Virtual Machine
* nested_paddr - Nested guest physical address to map
* paddr - VM Physical Address
* size - The size of the range to map
* level - The level at which to map the range
*
* Output Args: None
*
* Return: None
*
* Within the VM given by vm, creates a nested guest translation for the
* page range starting at nested_paddr to the page range starting at paddr.
*/
void __tdp_map(struct kvm_vm *vm, uint64_t nested_paddr, uint64_t paddr,
uint64_t size, int level)
{
struct kvm_mmu *mmu = &vm->stage2_mmu;
size_t page_size = PG_LEVEL_SIZE(level);
size_t npages = size / page_size;
TEST_ASSERT(nested_paddr + size > nested_paddr, "Vaddr overflow");
TEST_ASSERT(paddr + size > paddr, "Paddr overflow");
while (npages--) {
__virt_pg_map(vm, mmu, nested_paddr, paddr, level);
nested_paddr += page_size;
paddr += page_size;
}
}
void tdp_map(struct kvm_vm *vm, uint64_t nested_paddr, uint64_t paddr,
uint64_t size)
{
__tdp_map(vm, nested_paddr, paddr, size, PG_LEVEL_4K);
}
/* Prepare an identity extended page table that maps all the
* physical pages in VM.
*/
void tdp_identity_map_default_memslots(struct kvm_vm *vm)
{
uint32_t s, memslot = 0;
sparsebit_idx_t i, last;
struct userspace_mem_region *region = memslot2region(vm, memslot);
/* Only memslot 0 is mapped here, ensure it's the only one being used */
for (s = 0; s < NR_MEM_REGIONS; s++)
TEST_ASSERT_EQ(vm->memslots[s], 0);
i = (region->region.guest_phys_addr >> vm->page_shift) - 1;
last = i + (region->region.memory_size >> vm->page_shift);
for (;;) {
i = sparsebit_next_clear(region->unused_phy_pages, i);
if (i > last)
break;
tdp_map(vm, (uint64_t)i << vm->page_shift,
(uint64_t)i << vm->page_shift, 1 << vm->page_shift);
}
}
/* Identity map a region with 1GiB Pages. */
void tdp_identity_map_1g(struct kvm_vm *vm, uint64_t addr, uint64_t size)
{
__tdp_map(vm, addr, addr, size, PG_LEVEL_1G);
}
bool kvm_cpu_has_ept(void)
{
uint64_t ctrl;