* [PATCH 00/20] KVM: selftests: PPC pre-enabling
@ 2026-08-26 23:04 Sean Christopherson
2026-08-26 23:04 ` [PATCH 01/20] KVM: selftests: Use MEM_REGION_PT memslot instead of '0' for s390 regions/segments Sean Christopherson
` (20 more replies)
0 siblings, 21 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:04 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
This is a big pile of cleanups and refactoring to prepare for PPC support in
KVM selftests. PPC has paging modes that require multi-page page tables, and
those page tables need to be naturally aligned. The original proposal was to
plumb in an @align param to the page allocators[*], but I didn't love the idea
of adding another rarely used param to the allocators.
Reworking the APIs to take a region type requires a fair bit of churn, and was
more painful than expected as I didn't realize just how many one-off tests did
weird things, but overall I think it's worth it? If only to keep cutting down
on the use of magic memslot numbers in tests.
This needs explicit testing on s390. I tested on arm64 and x86, and given the
number of failures I had to wade through, I wouldn't be at all suprised if I
broke something subtle on s390 as well.
I'm less concerned about RISC-V and LoongArch as they don't have any custom
tests that are affected (which is where I got burned).
[*] https://lore.kernel.org/all/df86b5ccdbdafc3509d9538bd5e6796737bab2db.1781093720.git.ritesh.list@gmail.com
Nicholas Piggin (1):
KVM: selftests: Use goto instead of do-while to retry finding unused
physical pages
Sean Christopherson (19):
KVM: selftests: Use MEM_REGION_PT memslot instead of '0' for s390
regions/segments
KVM: selftests: Bump the minimum GPA for page tables to 0x200000
KVM: selftests: Use vm_alloc_page_table() to allocate LoongArch page
tables
KVM: selftests: Rename "num" param to "nr_pages" for physical page
allocators
KVM: selftests: Extend page allocator to support naturally aligned
allocations
KVM: selftests: Make the single-page allocator APIs static inline
KVM: selftests: Use the innermost page allocator API in the memslot
perf test
KVM: selftests: Use the innermost page allocator API in s390's IRQ
routing test
KVM: selftests: Add a wrapper API to allocate multiple page table
pages
KVM: selftests: Initialize vm->memslots[] with invalid memslots during
creation
KVM: selftests: Add APIs to override memory region types with custom
memslots
KVM: selftests: Add TEST_EXTRA memory region type for "special"
memslots
KVM: selftests: Use TEST_EXTRA region in arm64's vGIC LPI stress test
KVM: selftests: Use TEST_EXTRA region in x86's smaller MAXPHYADDR test
KVM: selftests: Use TEST_EXTRA region in set memory region test
KVM: selftests: Take the memory region type, not memslot, in page
allocators
KVM: selftests: Use TEST_ASSERT(), not assert(), in
vm_get_mem_region()
KVM: selftests: Automatically pick min_gpa for allocations based on
region type
KVM: selftests: Add arch hook to force page tables to be naturally
aligned
.../selftests/kvm/arm64/page_fault_test.c | 18 ++-
.../selftests/kvm/arm64/vgic_lpi_stress.c | 19 ++-
.../testing/selftests/kvm/include/kvm_util.h | 106 +++++++++++++--
tools/testing/selftests/kvm/include/x86/smm.h | 2 +-
.../selftests/kvm/lib/arm64/processor.c | 4 +-
tools/testing/selftests/kvm/lib/kvm_util.c | 127 +++++++++++-------
.../selftests/kvm/lib/loongarch/processor.c | 5 +-
.../selftests/kvm/lib/riscv/processor.c | 4 +-
.../selftests/kvm/lib/s390/processor.c | 7 +-
.../testing/selftests/kvm/lib/x86/processor.c | 15 ++-
.../testing/selftests/kvm/memslot_perf_test.c | 3 +-
tools/testing/selftests/kvm/s390/cmma_test.c | 19 +--
.../testing/selftests/kvm/s390/irq_routing.c | 2 +-
.../selftests/kvm/set_memory_region_test.c | 8 +-
.../x86/smaller_maxphyaddr_emulation_test.c | 9 +-
15 files changed, 219 insertions(+), 129 deletions(-)
base-commit: 76671054f9a1ff6abb976583cd8da37650acdc97
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 01/20] KVM: selftests: Use MEM_REGION_PT memslot instead of '0' for s390 regions/segments
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
@ 2026-08-26 23:04 ` Sean Christopherson
2026-08-26 23:04 ` [PATCH 02/20] KVM: selftests: Bump the minimum GPA for page tables to 0x200000 Sean Christopherson
` (19 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:04 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Use MEM_REGION_PT to indirectly specify memslot '0' instead of hardcoding
the memslot in s390's virtual memory allocator, as a first step towards
taking the allocation type instead of the exact, raw memslot in the
physical memory allocator.
Note, the only tests that set MEM_REGION_PT to a memslot other than '0' are
arm64-only, i.e. s390 always uses memslot '0' for page tables.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/lib/s390/processor.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/lib/s390/processor.c b/tools/testing/selftests/kvm/lib/s390/processor.c
index a9adb3782b35..fb9dab92d4d1 100644
--- a/tools/testing/selftests/kvm/lib/s390/processor.c
+++ b/tools/testing/selftests/kvm/lib/s390/processor.c
@@ -39,7 +39,8 @@ static u64 virt_alloc_region(struct kvm_vm *vm, int ri)
u64 taddr;
taddr = vm_phy_pages_alloc(vm, ri < 4 ? PAGES_PER_REGION : 1,
- KVM_GUEST_PAGE_TABLE_MIN_PADDR, 0);
+ KVM_GUEST_PAGE_TABLE_MIN_PADDR,
+ vm->memslots[MEM_REGION_PT]);
memset(addr_gpa2hva(vm, taddr), 0xff, PAGES_PER_REGION * vm->page_size);
return (taddr & REGION_ENTRY_ORIGIN)
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 02/20] KVM: selftests: Bump the minimum GPA for page tables to 0x200000
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
2026-08-26 23:04 ` [PATCH 01/20] KVM: selftests: Use MEM_REGION_PT memslot instead of '0' for s390 regions/segments Sean Christopherson
@ 2026-08-26 23:04 ` Sean Christopherson
2026-08-26 23:04 ` [PATCH 03/20] KVM: selftests: Use vm_alloc_page_table() to allocate LoongArch page tables Sean Christopherson
` (18 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:04 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Bump selftests completely arbitrary minimum GPA for page tables from
0x180000 to 0x200000 (LoongArch's minimum), so that LoongArch can use
vm_alloc_page_table() instead of open coding a rough equivalent.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/include/kvm_util.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 5a7a455b5387..70906a0d1003 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -175,7 +175,7 @@ static inline struct userspace_mem_region *vm_get_mem_region(struct kvm_vm *vm,
/* Minimum allocated guest virtual and physical addresses */
#define KVM_UTIL_MIN_VADDR 0x2000
-#define KVM_GUEST_PAGE_TABLE_MIN_PADDR 0x180000
+#define KVM_GUEST_PAGE_TABLE_MIN_PADDR 0x200000
#define DEFAULT_GUEST_STACK_VADDR_MIN 0xab6000
#define DEFAULT_STACK_PGS 5
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 03/20] KVM: selftests: Use vm_alloc_page_table() to allocate LoongArch page tables
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
2026-08-26 23:04 ` [PATCH 01/20] KVM: selftests: Use MEM_REGION_PT memslot instead of '0' for s390 regions/segments Sean Christopherson
2026-08-26 23:04 ` [PATCH 02/20] KVM: selftests: Bump the minimum GPA for page tables to 0x200000 Sean Christopherson
@ 2026-08-26 23:04 ` Sean Christopherson
2026-08-27 6:43 ` Bibo Mao
2026-08-26 23:04 ` [PATCH 04/20] KVM: selftests: Rename "num" param to "nr_pages" for physical page allocators Sean Christopherson
` (17 subsequent siblings)
20 siblings, 1 reply; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:04 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Now that KVM_GUEST_PAGE_TABLE_MIN_PADDR == LOONGARCH_PAGE_TABLE_PHYS_MIN,
use the common vm_alloc_page_table() instead of open coding the same.
Opportunistically drop the assert that the allocation succeeded, as the
allocator itself guarantees success.
For all intents and purposes, no functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/lib/loongarch/processor.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/tools/testing/selftests/kvm/lib/loongarch/processor.c b/tools/testing/selftests/kvm/lib/loongarch/processor.c
index 47bbde3e205a..fcd41bc6fbda 100644
--- a/tools/testing/selftests/kvm/lib/loongarch/processor.c
+++ b/tools/testing/selftests/kvm/lib/loongarch/processor.c
@@ -9,7 +9,6 @@
#include "processor.h"
#include "ucall_common.h"
-#define LOONGARCH_PAGE_TABLE_PHYS_MIN 0x200000
#define LOONGARCH_GUEST_STACK_VADDR_MIN 0x200000
static gpa_t invalid_pgtable[4];
@@ -57,9 +56,7 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm)
child = table = 0;
for (i = 0; i < vm->mmu.pgtable_levels; i++) {
invalid_pgtable[i] = child;
- table = vm_phy_page_alloc(vm, LOONGARCH_PAGE_TABLE_PHYS_MIN,
- vm->memslots[MEM_REGION_PT]);
- TEST_ASSERT(table, "Fail to allocate page tale at level %d\n", i);
+ table = vm_alloc_page_table(vm);
virt_set_pgtable(vm, table, child);
child = table;
}
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 04/20] KVM: selftests: Rename "num" param to "nr_pages" for physical page allocators
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (2 preceding siblings ...)
2026-08-26 23:04 ` [PATCH 03/20] KVM: selftests: Use vm_alloc_page_table() to allocate LoongArch page tables Sean Christopherson
@ 2026-08-26 23:04 ` Sean Christopherson
2026-08-26 23:04 ` [PATCH 05/20] KVM: selftests: Use goto instead of do-while to retry finding unused physical pages Sean Christopherson
` (16 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:04 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Rename the "num" param in the physical page allocator APIs to "nr_pages" to
make the unit and role of the param more obvious.
Opportunistically rework the function comment to drop the superfluous
kerneldoc style, and to very explicitly call out that success is guaranteed.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
.../testing/selftests/kvm/include/kvm_util.h | 6 ++--
tools/testing/selftests/kvm/lib/kvm_util.c | 35 ++++++-------------
2 files changed, 14 insertions(+), 27 deletions(-)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 70906a0d1003..b1c5597b1def 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -991,11 +991,11 @@ void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing);
const char *exit_reason_str(unsigned int exit_reason);
gpa_t vm_phy_page_alloc(struct kvm_vm *vm, gpa_t min_gpa, u32 memslot);
-gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num, gpa_t min_gpa,
+gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
u32 memslot, bool protected);
gpa_t vm_alloc_page_table(struct kvm_vm *vm);
-static inline gpa_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
+static inline gpa_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
gpa_t min_gpa, u32 memslot)
{
/*
@@ -1003,7 +1003,7 @@ static inline gpa_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
* protected memory, as the majority of memory for such VMs is
* protected, i.e. using shared memory is effectively opt-in.
*/
- return __vm_phy_pages_alloc(vm, num, min_gpa, memslot,
+ return __vm_phy_pages_alloc(vm, nr_pages, min_gpa, memslot,
vm_arch_has_protected_memory(vm));
}
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 9ddc047d5c27..b071d77dd301 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -2025,33 +2025,20 @@ const char *exit_reason_str(unsigned int exit_reason)
}
/*
- * Physical Contiguous Page Allocator
+ * Allocate contiguous (guest) physical pages in a given memory region, at or
+ * the minimum specific GPA. If the memory is protected/private, also add the
+ * allocate pages to the region's set of protected pages, e.g. so that arch
+ * code knows which pages need to be encrypted when launching the VM.
*
- * Input Args:
- * vm - Virtual Machine
- * num - number of pages
- * min_gpa - Physical address minimum
- * memslot - Memory region to allocate page from
- * protected - True if the pages will be used as protected/private memory
- *
- * Output Args: None
- *
- * Return:
- * Starting physical address
- *
- * Within the VM specified by vm, locates a range of available physical
- * pages at or above min_gpa. If found, the pages are marked as in use
- * and their base address is returned. A TEST_ASSERT failure occurs if
- * not enough pages are available at or above min_gpa.
+ * Note, success is guaranteed!
*/
-gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
- gpa_t min_gpa, u32 memslot,
- bool protected)
+gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
+ u32 memslot, bool protected)
{
struct userspace_mem_region *region;
sparsebit_idx_t pg, base;
- TEST_ASSERT(num > 0, "Must allocate at least one page");
+ TEST_ASSERT(nr_pages, "Must allocate at least one page");
TEST_ASSERT((min_gpa % vm->page_size) == 0, "Min physical address "
"not divisible by page size.\n"
@@ -2064,13 +2051,13 @@ gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
base = pg = min_gpa >> vm->page_shift;
do {
- for (; pg < base + num; ++pg) {
+ for (; pg < base + nr_pages; ++pg) {
if (!sparsebit_is_set(region->unused_phy_pages, pg)) {
base = pg = sparsebit_next_set(region->unused_phy_pages, pg);
break;
}
}
- } while (pg && pg != base + num);
+ } while (pg && pg != base + nr_pages);
if (pg == 0) {
fprintf(stderr, "No guest physical page available, "
@@ -2081,7 +2068,7 @@ gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
abort();
}
- for (pg = base; pg < base + num; ++pg) {
+ for (pg = base; pg < base + nr_pages; ++pg) {
sparsebit_clear(region->unused_phy_pages, pg);
if (protected)
sparsebit_set(region->protected_phy_pages, pg);
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 05/20] KVM: selftests: Use goto instead of do-while to retry finding unused physical pages
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (3 preceding siblings ...)
2026-08-26 23:04 ` [PATCH 04/20] KVM: selftests: Rename "num" param to "nr_pages" for physical page allocators Sean Christopherson
@ 2026-08-26 23:04 ` Sean Christopherson
2026-08-26 23:04 ` [PATCH 06/20] KVM: selftests: Extend page allocator to support naturally aligned allocations Sean Christopherson
` (15 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:04 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
From: Nicholas Piggin <npiggin@gmail.com>
Rework the core loop of the physical page allocator to use a goto instead
of do-while loop when retrying with a new base address. The do-while loop
obviously works, but it obfuscates the success vs. failure paths, and in
general is convoluted.
For all intents and purposes, no functional change intended.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[Rebased to latest mainline tree]
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
[sean: separate from alignment change, use enomem label, write changelog]
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/lib/kvm_util.c | 32 +++++++++++-----------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index b071d77dd301..bbf6d7684c0c 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -2049,23 +2049,15 @@ gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
TEST_ASSERT(!protected || region->protected_phy_pages,
"Region doesn't support protected memory");
- base = pg = min_gpa >> vm->page_shift;
- do {
- for (; pg < base + nr_pages; ++pg) {
- if (!sparsebit_is_set(region->unused_phy_pages, pg)) {
- base = pg = sparsebit_next_set(region->unused_phy_pages, pg);
- break;
- }
+ base = min_gpa >> vm->page_shift;
+again:
+ for (pg = base; pg < base + nr_pages; ++pg) {
+ if (!sparsebit_is_set(region->unused_phy_pages, pg)) {
+ base = sparsebit_next_set(region->unused_phy_pages, pg);
+ if (!base)
+ goto enomem;
+ goto again;
}
- } while (pg && pg != base + nr_pages);
-
- if (pg == 0) {
- fprintf(stderr, "No guest physical page available, "
- "min_gpa: 0x%lx page_size: 0x%x memslot: %u\n",
- min_gpa, vm->page_size, memslot);
- fputs("---- vm dump ----\n", stderr);
- vm_dump(stderr, vm, 2);
- abort();
}
for (pg = base; pg < base + nr_pages; ++pg) {
@@ -2075,6 +2067,14 @@ gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
}
return base * vm->page_size;
+
+enomem:
+ fprintf(stderr, "No guest physical page available, min_gpa: 0x%lx page_size: 0x%x memslot: %u\n",
+ min_gpa, vm->page_size, memslot);
+ fputs("---- vm dump ----\n", stderr);
+ vm_dump(stderr, vm, 2);
+ abort();
+ __builtin_unreachable();
}
gpa_t vm_phy_page_alloc(struct kvm_vm *vm, gpa_t min_gpa, u32 memslot)
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 06/20] KVM: selftests: Extend page allocator to support naturally aligned allocations
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (4 preceding siblings ...)
2026-08-26 23:04 ` [PATCH 05/20] KVM: selftests: Use goto instead of do-while to retry finding unused physical pages Sean Christopherson
@ 2026-08-26 23:04 ` Sean Christopherson
2026-08-26 23:04 ` [PATCH 07/20] KVM: selftests: Make the single-page allocator APIs static inline Sean Christopherson
` (14 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:04 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Extend the page allocator to support naturally aligned allocations, as some
flavors of PowerPC page tables require multiple guest pages per table, and
those tables need to be naturally aligned.
Take care to align the potential base address *inside* the retry loop, i.e.
the base needs to be (re)aligned on every attempt.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/include/kvm_util.h | 2 ++
tools/testing/selftests/kvm/lib/kvm_util.c | 13 +++++++++++--
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index b1c5597b1def..96c8251c224a 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -991,6 +991,8 @@ void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing);
const char *exit_reason_str(unsigned int exit_reason);
gpa_t vm_phy_page_alloc(struct kvm_vm *vm, gpa_t min_gpa, u32 memslot);
+gpa_t ____vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
+ u32 memslot, bool protected, bool naturally_aligned);
gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
u32 memslot, bool protected);
gpa_t vm_alloc_page_table(struct kvm_vm *vm);
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index bbf6d7684c0c..896da440659e 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -17,6 +17,7 @@
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
+#include <linux/align.h>
#include <linux/kernel.h>
#define KVM_UTIL_MIN_PFN 2
@@ -2032,9 +2033,10 @@ const char *exit_reason_str(unsigned int exit_reason)
*
* Note, success is guaranteed!
*/
-gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
- u32 memslot, bool protected)
+gpa_t ____vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
+ u32 memslot, bool protected, bool naturally_aligned)
{
+ size_t alignment = naturally_aligned ? nr_pages : 1;
struct userspace_mem_region *region;
sparsebit_idx_t pg, base;
@@ -2051,6 +2053,7 @@ gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
base = min_gpa >> vm->page_shift;
again:
+ base = ALIGN(base, alignment);
for (pg = base; pg < base + nr_pages; ++pg) {
if (!sparsebit_is_set(region->unused_phy_pages, pg)) {
base = sparsebit_next_set(region->unused_phy_pages, pg);
@@ -2077,6 +2080,12 @@ gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
__builtin_unreachable();
}
+gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
+ u32 memslot, bool protected)
+{
+ return ____vm_phy_pages_alloc(vm, nr_pages, min_gpa, memslot, protected, false);
+}
+
gpa_t vm_phy_page_alloc(struct kvm_vm *vm, gpa_t min_gpa, u32 memslot)
{
return vm_phy_pages_alloc(vm, 1, min_gpa, memslot);
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 07/20] KVM: selftests: Make the single-page allocator APIs static inline
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (5 preceding siblings ...)
2026-08-26 23:04 ` [PATCH 06/20] KVM: selftests: Extend page allocator to support naturally aligned allocations Sean Christopherson
@ 2026-08-26 23:04 ` Sean Christopherson
2026-08-26 23:04 ` [PATCH 08/20] KVM: selftests: Use the innermost page allocator API in the memslot perf test Sean Christopherson
` (13 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:04 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Move the single-page allocator APIs to kvm_util.h as inline functions, as
the are trivial wrappers, and unlike __vm_phy_pages_alloc(), are expected
to remain that way for the foreseeable future.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/include/kvm_util.h | 14 ++++++++++++--
tools/testing/selftests/kvm/lib/kvm_util.c | 11 -----------
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 96c8251c224a..2525c2cacc22 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -990,12 +990,10 @@ void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing);
const char *exit_reason_str(unsigned int exit_reason);
-gpa_t vm_phy_page_alloc(struct kvm_vm *vm, gpa_t min_gpa, u32 memslot);
gpa_t ____vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
u32 memslot, bool protected, bool naturally_aligned);
gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
u32 memslot, bool protected);
-gpa_t vm_alloc_page_table(struct kvm_vm *vm);
static inline gpa_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
gpa_t min_gpa, u32 memslot)
@@ -1009,6 +1007,18 @@ static inline gpa_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
vm_arch_has_protected_memory(vm));
}
+static inline gpa_t vm_phy_page_alloc(struct kvm_vm *vm, gpa_t min_gpa,
+ u32 memslot)
+{
+ return vm_phy_pages_alloc(vm, 1, min_gpa, memslot);
+}
+
+static inline gpa_t vm_alloc_page_table(struct kvm_vm *vm)
+{
+ return vm_phy_page_alloc(vm, KVM_GUEST_PAGE_TABLE_MIN_PADDR,
+ vm->memslots[MEM_REGION_PT]);
+}
+
/*
* ____vm_create() does KVM_CREATE_VM and little else. __vm_create() also
* loads the test binary into guest memory and creates an IRQ chip (x86 only).
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 896da440659e..ce0d8fba4624 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -2086,17 +2086,6 @@ gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
return ____vm_phy_pages_alloc(vm, nr_pages, min_gpa, memslot, protected, false);
}
-gpa_t vm_phy_page_alloc(struct kvm_vm *vm, gpa_t min_gpa, u32 memslot)
-{
- return vm_phy_pages_alloc(vm, 1, min_gpa, memslot);
-}
-
-gpa_t vm_alloc_page_table(struct kvm_vm *vm)
-{
- return vm_phy_page_alloc(vm, KVM_GUEST_PAGE_TABLE_MIN_PADDR,
- vm->memslots[MEM_REGION_PT]);
-}
-
/*
* Address Guest Virtual to Host Virtual
*
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 08/20] KVM: selftests: Use the innermost page allocator API in the memslot perf test
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (6 preceding siblings ...)
2026-08-26 23:04 ` [PATCH 07/20] KVM: selftests: Make the single-page allocator APIs static inline Sean Christopherson
@ 2026-08-26 23:04 ` Sean Christopherson
2026-08-26 23:05 ` [PATCH 09/20] KVM: selftests: Use the innermost page allocator API in s390's IRQ routing test Sean Christopherson
` (12 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:04 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Use the quad-underscores physical page allocator API in the memslot perf
test in anticipation of converting the outer versions to take the memory
region type instead of the raw memslot. Stating the obvious, the memslot
perf test creates and allocates from multiple memslots, and so can't use
MEM_REGION_TEST_DATA to communicate which region/slot to allocate from.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/memslot_perf_test.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/memslot_perf_test.c b/tools/testing/selftests/kvm/memslot_perf_test.c
index e1299611be32..844ea9b7bb41 100644
--- a/tools/testing/selftests/kvm/memslot_perf_test.c
+++ b/tools/testing/selftests/kvm/memslot_perf_test.c
@@ -339,7 +339,8 @@ static bool prepare_vm(struct vm_data *data, int nslots, u64 *maxslots,
if (slot == data->nslots)
npages += rempages;
- gpa = vm_phy_pages_alloc(data->vm, npages, guest_addr, slot);
+ gpa = ____vm_phy_pages_alloc(data->vm, npages, guest_addr, slot,
+ false, false);
TEST_ASSERT(gpa == guest_addr,
"vm_phy_pages_alloc() failed");
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 09/20] KVM: selftests: Use the innermost page allocator API in s390's IRQ routing test
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (7 preceding siblings ...)
2026-08-26 23:04 ` [PATCH 08/20] KVM: selftests: Use the innermost page allocator API in the memslot perf test Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-26 23:05 ` [PATCH 10/20] KVM: selftests: Add a wrapper API to allocate multiple page table pages Sean Christopherson
` (11 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Use the quad-underscores page allocator in s390's IRQ routing test in
anticipation of dropping the @min_gpa param from the primary APIs.
Note, it's not entirely clear that the test *needs* to use a very magical
@min_gpa, i.e. it's possible a more elegant solution exists. But that's a
problem for a different day.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/s390/irq_routing.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/s390/irq_routing.c b/tools/testing/selftests/kvm/s390/irq_routing.c
index f3839284ac08..cd26cc1aed80 100644
--- a/tools/testing/selftests/kvm/s390/irq_routing.c
+++ b/tools/testing/selftests/kvm/s390/irq_routing.c
@@ -36,7 +36,7 @@ static void test(void)
};
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
- mem = vm_phy_pages_alloc(vm, 2, 4096 * 42, 0);
+ mem = ____vm_phy_pages_alloc(vm, 2, 4096 * 42, 0, false, false);
routing = kvm_gsi_routing_create();
routing->nr = 1;
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 10/20] KVM: selftests: Add a wrapper API to allocate multiple page table pages
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (8 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 09/20] KVM: selftests: Use the innermost page allocator API in s390's IRQ routing test Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-27 5:27 ` Itaru Kitayama
2026-08-26 23:05 ` [PATCH 11/20] KVM: selftests: Initialize vm->memslots[] with invalid memslots during creation Sean Christopherson
` (10 subsequent siblings)
20 siblings, 1 reply; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Add vm_alloc_page_table_pages() and use it throughout arch code to replace
open coded equivalents.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/include/kvm_util.h | 9 +++++++--
tools/testing/selftests/kvm/lib/arm64/processor.c | 4 +---
tools/testing/selftests/kvm/lib/riscv/processor.c | 4 +---
tools/testing/selftests/kvm/lib/s390/processor.c | 8 ++------
4 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 2525c2cacc22..21354434de0a 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -1013,10 +1013,15 @@ static inline gpa_t vm_phy_page_alloc(struct kvm_vm *vm, gpa_t min_gpa,
return vm_phy_pages_alloc(vm, 1, min_gpa, memslot);
}
+static inline gpa_t vm_alloc_page_table_pages(struct kvm_vm *vm, size_t nr_pages)
+{
+ return vm_phy_pages_alloc(vm, nr_pages, KVM_GUEST_PAGE_TABLE_MIN_PADDR,
+ vm->memslots[MEM_REGION_PT]);
+}
+
static inline gpa_t vm_alloc_page_table(struct kvm_vm *vm)
{
- return vm_phy_page_alloc(vm, KVM_GUEST_PAGE_TABLE_MIN_PADDR,
- vm->memslots[MEM_REGION_PT]);
+ return vm_alloc_page_table_pages(vm, 1);
}
/*
diff --git a/tools/testing/selftests/kvm/lib/arm64/processor.c b/tools/testing/selftests/kvm/lib/arm64/processor.c
index 01325bf4d36f..2dcaa2c4a038 100644
--- a/tools/testing/selftests/kvm/lib/arm64/processor.c
+++ b/tools/testing/selftests/kvm/lib/arm64/processor.c
@@ -115,9 +115,7 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm)
if (vm->mmu.pgd_created)
return;
- vm->mmu.pgd = vm_phy_pages_alloc(vm, nr_pages,
- KVM_GUEST_PAGE_TABLE_MIN_PADDR,
- vm->memslots[MEM_REGION_PT]);
+ vm->mmu.pgd = vm_alloc_page_table_pages(vm, nr_pages);
vm->mmu.pgd_created = true;
}
diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
index ded5429f3448..c175dcd14114 100644
--- a/tools/testing/selftests/kvm/lib/riscv/processor.c
+++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
@@ -69,9 +69,7 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm)
if (vm->mmu.pgd_created)
return;
- vm->mmu.pgd = vm_phy_pages_alloc(vm, nr_pages,
- KVM_GUEST_PAGE_TABLE_MIN_PADDR,
- vm->memslots[MEM_REGION_PT]);
+ vm->mmu.pgd = vm_alloc_page_table_pages(vm, nr_pages);
vm->mmu.pgd_created = true;
}
diff --git a/tools/testing/selftests/kvm/lib/s390/processor.c b/tools/testing/selftests/kvm/lib/s390/processor.c
index fb9dab92d4d1..33f49d743b5f 100644
--- a/tools/testing/selftests/kvm/lib/s390/processor.c
+++ b/tools/testing/selftests/kvm/lib/s390/processor.c
@@ -20,9 +20,7 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm)
if (vm->mmu.pgd_created)
return;
- gpa = vm_phy_pages_alloc(vm, PAGES_PER_REGION,
- KVM_GUEST_PAGE_TABLE_MIN_PADDR,
- vm->memslots[MEM_REGION_PT]);
+ gpa = vm_alloc_page_table_pages(vm, PAGES_PER_REGION);
memset(addr_gpa2hva(vm, gpa), 0xff, PAGES_PER_REGION * vm->page_size);
vm->mmu.pgd = gpa;
@@ -38,9 +36,7 @@ static u64 virt_alloc_region(struct kvm_vm *vm, int ri)
{
u64 taddr;
- taddr = vm_phy_pages_alloc(vm, ri < 4 ? PAGES_PER_REGION : 1,
- KVM_GUEST_PAGE_TABLE_MIN_PADDR,
- vm->memslots[MEM_REGION_PT]);
+ taddr = vm_alloc_page_table_pages(vm, ri < 4 ? PAGES_PER_REGION : 1);
memset(addr_gpa2hva(vm, taddr), 0xff, PAGES_PER_REGION * vm->page_size);
return (taddr & REGION_ENTRY_ORIGIN)
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 11/20] KVM: selftests: Initialize vm->memslots[] with invalid memslots during creation
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (9 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 10/20] KVM: selftests: Add a wrapper API to allocate multiple page table pages Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-26 23:05 ` [PATCH 12/20] KVM: selftests: Add APIs to override memory region types with custom memslots Sean Christopherson
` (9 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Initialize vm->memslots[] with an invalid memslots value during very
initial VM creation so that failure to configure the core memory regions
generates an immediate assert instead of potential weirdness, e.g. if slot0
is coincidentally valid. This will also allow hardening the region APIs to
guard overriding a region's memslot multiple times.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/include/kvm_util.h | 2 ++
tools/testing/selftests/kvm/lib/kvm_util.c | 5 +++++
tools/testing/selftests/kvm/lib/x86/processor.c | 5 ++++-
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 21354434de0a..70e77992dd2f 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -33,6 +33,8 @@
#define NSEC_PER_SEC 1000000000L
+#define KVM_INVALID_MEMSLOT UINT_MAX
+
struct userspace_mem_region {
struct kvm_userspace_memory_region2 region;
struct sparsebit *unused_phy_pages;
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index ce0d8fba4624..56df5b1d9c79 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -288,6 +288,7 @@ __weak void vm_populate_gva_bitmap(struct kvm_vm *vm)
struct kvm_vm *____vm_create(struct vm_shape shape)
{
struct kvm_vm *vm;
+ int i;
vm = calloc(1, sizeof(*vm));
TEST_ASSERT(vm != NULL, "Insufficient Memory");
@@ -296,6 +297,8 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
vm->regions.gpa_tree = RB_ROOT;
vm->regions.hva_tree = RB_ROOT;
hash_init(vm->regions.slot_hash);
+ for (i = 0; i < NR_MEM_REGIONS; i++)
+ vm->memslots[i] = KVM_INVALID_MEMSLOT;
vm->mode = shape.mode;
vm->type = shape.type;
@@ -1190,6 +1193,8 @@ memslot2region(struct kvm_vm *vm, u32 memslot)
{
struct userspace_mem_region *region;
+ TEST_ASSERT(memslot != KVM_INVALID_MEMSLOT, "vm->memslots[] unpopulated?");
+
hash_for_each_possible(vm->regions.slot_hash, region, slot_node,
memslot)
if (region->region.slot == memslot)
diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
index d31fa81ea075..ea5fa59888af 100644
--- a/tools/testing/selftests/kvm/lib/x86/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86/processor.c
@@ -529,7 +529,10 @@ void tdp_identity_map_default_memslots(struct kvm_vm *vm)
/* 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);
+ TEST_ASSERT(!vm->memslots[s] ||
+ vm->memslots[s] == KVM_INVALID_MEMSLOT,
+ "Unhandled memslot '%u' for type '%u'",
+ vm->memslots[s], s);
i = (region->region.guest_phys_addr >> vm->page_shift) - 1;
last = i + (region->region.memory_size >> vm->page_shift);
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 12/20] KVM: selftests: Add APIs to override memory region types with custom memslots
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (10 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 11/20] KVM: selftests: Initialize vm->memslots[] with invalid memslots during creation Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-26 23:05 ` [PATCH 13/20] KVM: selftests: Add TEST_EXTRA memory region type for "special" memslots Sean Christopherson
` (8 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Add and use APIs to override memory region types instead of open coding the
logic in tests, partly to dedup test code, but mostly to add some amount of
protection against conflicting overrides. This will allow converting more
tests to override memory regions without taking on too much risk of bugs in
the long term, e.g. due to silently overriding a region multiple times.
Deliberately "unroll" the loops in __vm_create() and the CMMA test's
create_main_memslot() to avoid filling all memslots in anticipation of
adding an "extra" memslot that is for test use and *only* test use, i.e.
shouldn't be configured by core library code.
Converting tests to overriding memory regions will allow taking the region
type instead of the raw memslot in the physical page allocator APIs.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
.../selftests/kvm/arm64/page_fault_test.c | 18 +++++------
.../testing/selftests/kvm/include/kvm_util.h | 30 +++++++++++++++++++
tools/testing/selftests/kvm/lib/kvm_util.c | 8 +++--
tools/testing/selftests/kvm/s390/cmma_test.c | 19 ++++--------
4 files changed, 49 insertions(+), 26 deletions(-)
diff --git a/tools/testing/selftests/kvm/arm64/page_fault_test.c b/tools/testing/selftests/kvm/arm64/page_fault_test.c
index 6bb3d82906b2..b0e3fc8cd76a 100644
--- a/tools/testing/selftests/kvm/arm64/page_fault_test.c
+++ b/tools/testing/selftests/kvm/arm64/page_fault_test.c
@@ -597,18 +597,16 @@ static void setup_memslots(struct kvm_vm *vm, struct test_params *p)
vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, 0,
CODE_AND_DATA_MEMSLOT, code_npages, 0);
- vm->memslots[MEM_REGION_CODE] = CODE_AND_DATA_MEMSLOT;
- vm->memslots[MEM_REGION_DATA] = CODE_AND_DATA_MEMSLOT;
+ ____vm_override_mem_region(vm, MEM_REGION_CODE, CODE_AND_DATA_MEMSLOT);
+ ____vm_override_mem_region(vm, MEM_REGION_DATA, CODE_AND_DATA_MEMSLOT);
- vm_userspace_mem_region_add(vm, p->src_type, data_gpa - pt_size,
- PAGE_TABLE_MEMSLOT, pt_size / guest_page_size,
- p->test_desc->pt_memslot_flags);
- vm->memslots[MEM_REGION_PT] = PAGE_TABLE_MEMSLOT;
+ __vm_override_mem_region(vm, MEM_REGION_PT, p->src_type, data_gpa - pt_size,
+ PAGE_TABLE_MEMSLOT, pt_size / guest_page_size,
+ p->test_desc->pt_memslot_flags);
- vm_userspace_mem_region_add(vm, p->src_type, data_gpa, TEST_DATA_MEMSLOT,
- data_size / guest_page_size,
- p->test_desc->data_memslot_flags);
- vm->memslots[MEM_REGION_TEST_DATA] = TEST_DATA_MEMSLOT;
+ __vm_override_mem_region(vm, MEM_REGION_TEST_DATA, p->src_type, data_gpa,
+ TEST_DATA_MEMSLOT, data_size / guest_page_size,
+ p->test_desc->data_memslot_flags);
}
static void setup_ucall(struct kvm_vm *vm)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 70e77992dd2f..14f87c8a00ec 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -704,6 +704,36 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type,
gpa_t gpa, u32 slot, u64 npages, u32 flags,
int guest_memfd_fd, u64 guest_memfd_offset);
+
+static inline void ____vm_override_mem_region(struct kvm_vm *vm,
+ enum kvm_mem_region_type type,
+ u32 slot)
+{
+ TEST_ASSERT(vm->memslots[type] == KVM_INVALID_MEMSLOT,
+ "Memory region type '%u' was already overridden with slot=%u",
+ type, vm->memslots[type]);
+
+ vm->memslots[type] = slot;
+}
+
+static inline void __vm_override_mem_region(struct kvm_vm *vm,
+ enum kvm_mem_region_type type,
+ enum vm_mem_backing_src_type src_type,
+ gpa_t gpa, u32 slot, u64 npages,
+ u32 flags)
+{
+ ____vm_override_mem_region(vm, type, slot);
+ vm_userspace_mem_region_add(vm, src_type, gpa, slot, npages, flags);
+}
+
+static inline void vm_override_mem_region(struct kvm_vm *vm,
+ enum kvm_mem_region_type type,
+ enum vm_mem_backing_src_type src_type,
+ gpa_t gpa, u32 slot, u64 npages)
+{
+ __vm_override_mem_region(vm, type, src_type, gpa, slot, npages, 0);
+}
+
#ifndef vm_arch_has_protected_memory
static inline bool vm_arch_has_protected_memory(struct kvm_vm *vm)
{
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 56df5b1d9c79..781af2928d04 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -495,7 +495,7 @@ struct kvm_vm *__vm_create(struct vm_shape shape, u32 nr_runnable_vcpus,
nr_extra_pages);
struct userspace_mem_region *slot0;
struct kvm_vm *vm;
- int i, flags;
+ int flags;
kvm_set_files_rlimit(nr_runnable_vcpus);
@@ -513,8 +513,10 @@ struct kvm_vm *__vm_create(struct vm_shape shape, u32 nr_runnable_vcpus,
flags |= KVM_MEM_GUEST_MEMFD;
vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, 0, 0, nr_pages, flags);
- for (i = 0; i < NR_MEM_REGIONS; i++)
- vm->memslots[i] = 0;
+ ____vm_override_mem_region(vm, MEM_REGION_CODE, 0);
+ ____vm_override_mem_region(vm, MEM_REGION_PT, 0);
+ ____vm_override_mem_region(vm, MEM_REGION_DATA, 0);
+ ____vm_override_mem_region(vm, MEM_REGION_TEST_DATA, 0);
kvm_vm_elf_load(vm, program_invocation_name);
diff --git a/tools/testing/selftests/kvm/s390/cmma_test.c b/tools/testing/selftests/kvm/s390/cmma_test.c
index 15d81b2ed7ad..73387cc3bca7 100644
--- a/tools/testing/selftests/kvm/s390/cmma_test.c
+++ b/tools/testing/selftests/kvm/s390/cmma_test.c
@@ -102,24 +102,17 @@ static void guest_dirty_test_data(void)
static void create_main_memslot(struct kvm_vm *vm)
{
- int i;
-
vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, 0, 0, MAIN_PAGE_COUNT, 0);
- /* set the array of memslots to zero like __vm_create does */
- for (i = 0; i < NR_MEM_REGIONS; i++)
- vm->memslots[i] = 0;
+ ____vm_override_mem_region(vm, MEM_REGION_CODE, 0);
+ ____vm_override_mem_region(vm, MEM_REGION_PT, 0);
+ ____vm_override_mem_region(vm, MEM_REGION_DATA, 0);
}
static void create_test_memslot(struct kvm_vm *vm)
{
- vm_userspace_mem_region_add(vm,
- VM_MEM_SRC_ANONYMOUS,
- TEST_DATA_START_GFN << vm->page_shift,
- TEST_DATA_MEMSLOT,
- TEST_DATA_PAGE_COUNT,
- 0
- );
- vm->memslots[MEM_REGION_TEST_DATA] = TEST_DATA_MEMSLOT;
+ vm_override_mem_region(vm, MEM_REGION_TEST_DATA, VM_MEM_SRC_ANONYMOUS,
+ TEST_DATA_START_GFN << vm->page_shift,
+ TEST_DATA_MEMSLOT, TEST_DATA_PAGE_COUNT);
}
static void create_memslots(struct kvm_vm *vm)
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 13/20] KVM: selftests: Add TEST_EXTRA memory region type for "special" memslots
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (11 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 12/20] KVM: selftests: Add APIs to override memory region types with custom memslots Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-27 4:37 ` Itaru Kitayama
2026-08-26 23:05 ` [PATCH 14/20] KVM: selftests: Use TEST_EXTRA region in arm64's vGIC LPI stress test Sean Christopherson
` (7 subsequent siblings)
20 siblings, 1 reply; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
And another memory region type to deal with extra, one-off memory regions,
and use the new type to manage x86's SMRAM memslot, as another step towards
taking the region type instead of the raw memslot in the physical page
allocator APIs.
Alternatively, SMRAM setup could simply use the quad-underscore API to
continue passing in the memslot, but a surprising number of tests use an
"extra" memslot for a variety of reasons. I.e. allocating memory from one
(and exactly one) extra memslot isn't all that rare, and so should be
treated as normal behavior, not as something extraordinary, as
quad-underscore functions typically suggest.
Opportunistically add comments to document the intended usage of the types,
as the difference between DATA, TEST_DATA, and TEST_EXTRA in particular
isn't exactly obvious.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
.../testing/selftests/kvm/include/kvm_util.h | 37 ++++++++++++++++---
tools/testing/selftests/kvm/include/x86/smm.h | 2 +-
.../testing/selftests/kvm/lib/x86/processor.c | 7 ++--
3 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 14f87c8a00ec..f4f4f360a10b 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -82,11 +82,43 @@ struct userspace_mem_regions {
DECLARE_HASHTABLE(slot_hash, 9);
};
+/*
+ * Memory region types are passed to various page allocators to communicate
+ * various properties and metadata related to the allocation. Note, the
+ * descriptions below described the primary usage of each type. Individual
+ * tests may allocate memory for other purposes.
+ *
+ * By default, all regions are mapped to memslot '0'. Tests can override the
+ * memslot for any or all types, e.g. so that all test data is allocated from a
+ * curated memslot.
+ */
enum kvm_mem_region_type {
+ /*
+ * The CODE region is used by lib/elf when loading the test's code into
+ * guest memory.
+ */
MEM_REGION_CODE,
+ /*
+ * The DATA region is used to allocate core data structures, e.g. vCPU
+ * stacks, VM exception tables, x86's TSS, etc.
+ */
MEM_REGION_DATA,
+ /*
+ * The PT region, a.k.a. Page Table region, is used to allocate page
+ * table pages.
+ */
MEM_REGION_PT,
+ /*
+ * The TEST_DATA region is used for allocating test data that is either
+ * test specific, and/or isn't considered a "core" data structure.
+ */
MEM_REGION_TEST_DATA,
+ /*
+ * The TEST_EXTRA region is for special snowflakes, where a test wants
+ * to create and use a one-off memslot, without impacting "normal" test
+ * data allocations.
+ */
+ MEM_REGION_TEST_EXTRA,
NR_MEM_REGIONS,
};
@@ -129,11 +161,6 @@ struct kvm_vm {
struct kvm_binary_stats stats;
- /*
- * KVM region slots. These are the default memslots used by page
- * allocators, e.g., lib/elf uses the memslots[MEM_REGION_CODE]
- * memslot.
- */
u32 memslots[NR_MEM_REGIONS];
};
diff --git a/tools/testing/selftests/kvm/include/x86/smm.h b/tools/testing/selftests/kvm/include/x86/smm.h
index 2d1afa09819b..15faaa060126 100644
--- a/tools/testing/selftests/kvm/include/x86/smm.h
+++ b/tools/testing/selftests/kvm/include/x86/smm.h
@@ -8,7 +8,7 @@
#define SMRAM_MEMSLOT ((1 << 16) | 1)
#define SMRAM_PAGES (SMRAM_SIZE / PAGE_SIZE)
-void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, u64 smram_gpa,
+void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, gpa_t smram_gpa,
const void *smi_handler, size_t handler_size);
void inject_smi(struct kvm_vcpu *vcpu);
diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
index ea5fa59888af..b988eea373ad 100644
--- a/tools/testing/selftests/kvm/lib/x86/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86/processor.c
@@ -1468,11 +1468,12 @@ bool kvm_arch_has_default_irqchip(void)
return true;
}
-void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, u64 smram_gpa,
+void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, gpa_t smram_gpa,
const void *smi_handler, size_t handler_size)
{
- vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, smram_gpa,
- SMRAM_MEMSLOT, SMRAM_PAGES, 0);
+ vm_override_mem_region(vm, MEM_REGION_TEST_EXTRA, VM_MEM_SRC_ANONYMOUS,
+ smram_gpa, SMRAM_MEMSLOT, SMRAM_PAGES);
+
TEST_ASSERT(vm_phy_pages_alloc(vm, SMRAM_PAGES, smram_gpa,
SMRAM_MEMSLOT) == smram_gpa,
"Could not allocate guest physical addresses for SMRAM");
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 14/20] KVM: selftests: Use TEST_EXTRA region in arm64's vGIC LPI stress test
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (12 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 13/20] KVM: selftests: Add TEST_EXTRA memory region type for "special" memslots Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-26 23:05 ` [PATCH 15/20] KVM: selftests: Use TEST_EXTRA region in x86's smaller MAXPHYADDR test Sean Christopherson
` (6 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Use the TEST_EXTRA region/memslot for arm64's vGIC LPI stress test instead
of a custom memslot, so that the primary vm_phy_pages_alloc() APIs can be
reworked to take a region type instead of a raw memslot.
For all intents and purposes, no functional change intended, as
vm_override_mem_region() is barely more than a wrapper for
vm_userspace_mem_region_add().
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c b/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
index 9a69c439a0f8..9865b204fdeb 100644
--- a/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
+++ b/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
@@ -164,8 +164,8 @@ static void setup_memslot(void)
pages = sz / vm->page_size;
gpa_base = ((vm_compute_max_gfn(vm) + 1) * vm->page_size) - sz;
- vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, gpa_base,
- TEST_MEMSLOT_INDEX, pages, 0);
+ vm_override_mem_region(vm, MEM_REGION_TEST_EXTRA, VM_MEM_SRC_ANONYMOUS,
+ gpa_base, TEST_MEMSLOT_INDEX, pages);
}
#define LPI_PROP_DEFAULT_PRIO 0xa0
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 15/20] KVM: selftests: Use TEST_EXTRA region in x86's smaller MAXPHYADDR test
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (13 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 14/20] KVM: selftests: Use TEST_EXTRA region in arm64's vGIC LPI stress test Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-26 23:05 ` [PATCH 16/20] KVM: selftests: Use TEST_EXTRA region in set memory region test Sean Christopherson
` (5 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Use the TEST_EXTRA region/memslot for x86's smaller MAXPHYADDR test instead
of a custom memslot, so that the primary vm_phy_pages_alloc() APIs can be
reworked to take a region type instead of a raw memslot.
For all intents and purposes, no functional change intended, as
vm_add_extra_mem_region() is barely more than a wrapper for
vm_userspace_mem_region_add().
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
.../selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c b/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
index 3dca85e95478..b21798a385ca 100644
--- a/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
+++ b/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
@@ -62,9 +62,10 @@ int main(int argc, char *argv[])
TEST_ASSERT(rc, "KVM_CAP_EXIT_ON_EMULATION_FAILURE is unavailable");
vm_enable_cap(vm, KVM_CAP_EXIT_ON_EMULATION_FAILURE, 1);
- vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,
- MEM_REGION_GPA, MEM_REGION_SLOT,
- MEM_REGION_SIZE / PAGE_SIZE, 0);
+ vm_override_mem_region(vm, MEM_REGION_TEST_EXTRA, VM_MEM_SRC_ANONYMOUS,
+ MEM_REGION_GPA, MEM_REGION_SLOT,
+ MEM_REGION_SIZE / PAGE_SIZE);
+
gpa = vm_phy_pages_alloc(vm, MEM_REGION_SIZE / PAGE_SIZE,
MEM_REGION_GPA, MEM_REGION_SLOT);
TEST_ASSERT(gpa == MEM_REGION_GPA, "Failed vm_phy_pages_alloc");
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 16/20] KVM: selftests: Use TEST_EXTRA region in set memory region test
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (14 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 15/20] KVM: selftests: Use TEST_EXTRA region in x86's smaller MAXPHYADDR test Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-26 23:05 ` [PATCH 17/20] KVM: selftests: Take the memory region type, not memslot, in page allocators Sean Christopherson
` (4 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Use the TEST_EXTRA region/memslot in the "set memory region" test instead
of a custom memslot, so that the primary vm_phy_pages_alloc() APIs can be
reworked to take a region type instead of a raw memslot.
For all intents and purposes, no functional change intended, as
vm_override_mem_region() is barely more than a wrapper for
vm_userspace_mem_region_add().
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/set_memory_region_test.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/testing/selftests/kvm/set_memory_region_test.c
index dffe9654f45b..9d21594e2f81 100644
--- a/tools/testing/selftests/kvm/set_memory_region_test.c
+++ b/tools/testing/selftests/kvm/set_memory_region_test.c
@@ -116,9 +116,9 @@ static struct kvm_vm *spawn_vm(struct kvm_vcpu **vcpu, pthread_t *vcpu_thread,
vm = vm_create_with_one_vcpu(vcpu, guest_code);
- vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS_THP,
- MEM_REGION_GPA, MEM_REGION_SLOT,
- MEM_REGION_SIZE / getpagesize(), 0);
+ vm_override_mem_region(vm, MEM_REGION_TEST_EXTRA, VM_MEM_SRC_ANONYMOUS_THP,
+ MEM_REGION_GPA, MEM_REGION_SLOT,
+ MEM_REGION_SIZE / getpagesize());
/*
* Allocate and map two pages so that the GPA accessed by guest_code()
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 17/20] KVM: selftests: Take the memory region type, not memslot, in page allocators
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (15 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 16/20] KVM: selftests: Use TEST_EXTRA region in set memory region test Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-26 23:05 ` [PATCH 18/20] KVM: selftests: Use TEST_ASSERT(), not assert(), in vm_get_mem_region() Sean Christopherson
` (3 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Take the memory region type instead of the memslot in all page allocator
APIs, except for the innermost quad-underscores function. This will allow
automatically selecting the minimum GPA based on the allocation type, which
can't be done using the memslot due to all regions sharing a single memslot
by default. PowerPC support will also leverage the type to ensure that
page table allocations are naturally aligned.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c | 12 ++++++------
tools/testing/selftests/kvm/include/kvm_util.h | 13 +++++++------
tools/testing/selftests/kvm/lib/kvm_util.c | 10 +++++++---
tools/testing/selftests/kvm/lib/x86/processor.c | 2 +-
.../testing/selftests/kvm/set_memory_region_test.c | 2 +-
.../kvm/x86/smaller_maxphyaddr_emulation_test.c | 2 +-
6 files changed, 23 insertions(+), 18 deletions(-)
diff --git a/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c b/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
index 9865b204fdeb..a45c0849a47a 100644
--- a/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
+++ b/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
@@ -192,27 +192,27 @@ static void setup_test_data(void)
test_data.device_table = vm_phy_pages_alloc(vm, pages_per_64k,
gpa_base,
- TEST_MEMSLOT_INDEX);
+ MEM_REGION_TEST_EXTRA);
test_data.collection_table = vm_phy_pages_alloc(vm, pages_per_64k,
gpa_base,
- TEST_MEMSLOT_INDEX);
+ MEM_REGION_TEST_EXTRA);
cmdq_base = vm_phy_pages_alloc(vm, pages_per_64k, gpa_base,
- TEST_MEMSLOT_INDEX);
+ MEM_REGION_TEST_EXTRA);
virt_map(vm, cmdq_base, cmdq_base, pages_per_64k);
test_data.cmdq_base = cmdq_base;
test_data.cmdq_base_va = (void *)cmdq_base;
test_data.itt_tables = vm_phy_pages_alloc(vm, pages_per_64k * nr_devices,
- gpa_base, TEST_MEMSLOT_INDEX);
+ gpa_base, MEM_REGION_TEST_EXTRA);
test_data.lpi_prop_table = vm_phy_pages_alloc(vm, pages_per_64k,
- gpa_base, TEST_MEMSLOT_INDEX);
+ gpa_base, MEM_REGION_TEST_EXTRA);
configure_lpis();
test_data.lpi_pend_tables = vm_phy_pages_alloc(vm, pages_per_64k * nr_cpus,
- gpa_base, TEST_MEMSLOT_INDEX);
+ gpa_base, MEM_REGION_TEST_EXTRA);
sync_global_to_guest(vm, test_data);
}
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index f4f4f360a10b..783f060faf9e 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -1052,30 +1052,31 @@ const char *exit_reason_str(unsigned int exit_reason);
gpa_t ____vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
u32 memslot, bool protected, bool naturally_aligned);
gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
- u32 memslot, bool protected);
+ enum kvm_mem_region_type type, bool protected);
static inline gpa_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
- gpa_t min_gpa, u32 memslot)
+ gpa_t min_gpa,
+ enum kvm_mem_region_type type)
{
/*
* By default, allocate memory as protected for VMs that support
* protected memory, as the majority of memory for such VMs is
* protected, i.e. using shared memory is effectively opt-in.
*/
- return __vm_phy_pages_alloc(vm, nr_pages, min_gpa, memslot,
+ return __vm_phy_pages_alloc(vm, nr_pages, min_gpa, type,
vm_arch_has_protected_memory(vm));
}
static inline gpa_t vm_phy_page_alloc(struct kvm_vm *vm, gpa_t min_gpa,
- u32 memslot)
+ enum kvm_mem_region_type type)
{
- return vm_phy_pages_alloc(vm, 1, min_gpa, memslot);
+ return vm_phy_pages_alloc(vm, 1, min_gpa, type);
}
static inline gpa_t vm_alloc_page_table_pages(struct kvm_vm *vm, size_t nr_pages)
{
return vm_phy_pages_alloc(vm, nr_pages, KVM_GUEST_PAGE_TABLE_MIN_PADDR,
- vm->memslots[MEM_REGION_PT]);
+ MEM_REGION_PT);
}
static inline gpa_t vm_alloc_page_table(struct kvm_vm *vm)
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 781af2928d04..e500d1799151 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1475,7 +1475,7 @@ static gva_t ____vm_alloc(struct kvm_vm *vm, size_t sz, gva_t min_gva,
virt_pgd_alloc(vm);
gpa_t gpa = __vm_phy_pages_alloc(vm, pages,
KVM_UTIL_MIN_PFN * vm->page_size,
- vm->memslots[type], protected);
+ type, protected);
/*
* Find an unused range of virtual page addresses of at least
@@ -2088,9 +2088,13 @@ gpa_t ____vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
}
gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
- u32 memslot, bool protected)
+ enum kvm_mem_region_type type, bool protected)
{
- return ____vm_phy_pages_alloc(vm, nr_pages, min_gpa, memslot, protected, false);
+ TEST_ASSERT(type < NR_MEM_REGIONS,
+ "Invalid memory region type '%u'", type);
+
+ return ____vm_phy_pages_alloc(vm, nr_pages, min_gpa, vm->memslots[type],
+ protected, false);
}
/*
diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
index b988eea373ad..39d9ca6ceb1d 100644
--- a/tools/testing/selftests/kvm/lib/x86/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86/processor.c
@@ -1475,7 +1475,7 @@ void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, gpa_t smram_gpa,
smram_gpa, SMRAM_MEMSLOT, SMRAM_PAGES);
TEST_ASSERT(vm_phy_pages_alloc(vm, SMRAM_PAGES, smram_gpa,
- SMRAM_MEMSLOT) == smram_gpa,
+ MEM_REGION_TEST_EXTRA) == smram_gpa,
"Could not allocate guest physical addresses for SMRAM");
memset(addr_gpa2hva(vm, smram_gpa), 0x0, SMRAM_SIZE);
diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/testing/selftests/kvm/set_memory_region_test.c
index 9d21594e2f81..160bbe3d7203 100644
--- a/tools/testing/selftests/kvm/set_memory_region_test.c
+++ b/tools/testing/selftests/kvm/set_memory_region_test.c
@@ -124,7 +124,7 @@ static struct kvm_vm *spawn_vm(struct kvm_vcpu **vcpu, pthread_t *vcpu_thread,
* Allocate and map two pages so that the GPA accessed by guest_code()
* stays valid across the memslot move.
*/
- gpa = vm_phy_pages_alloc(vm, 2, MEM_REGION_GPA, MEM_REGION_SLOT);
+ gpa = vm_phy_pages_alloc(vm, 2, MEM_REGION_GPA, MEM_REGION_TEST_EXTRA);
TEST_ASSERT(gpa == MEM_REGION_GPA, "Failed vm_phy_pages_alloc\n");
virt_map(vm, MEM_REGION_GPA, MEM_REGION_GPA, 2);
diff --git a/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c b/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
index b21798a385ca..4e125eb5e0cf 100644
--- a/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
+++ b/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
@@ -67,7 +67,7 @@ int main(int argc, char *argv[])
MEM_REGION_SIZE / PAGE_SIZE);
gpa = vm_phy_pages_alloc(vm, MEM_REGION_SIZE / PAGE_SIZE,
- MEM_REGION_GPA, MEM_REGION_SLOT);
+ MEM_REGION_GPA, MEM_REGION_TEST_EXTRA);
TEST_ASSERT(gpa == MEM_REGION_GPA, "Failed vm_phy_pages_alloc");
virt_map(vm, MEM_REGION_GVA, MEM_REGION_GPA, 1);
hva = addr_gpa2hva(vm, MEM_REGION_GPA);
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 18/20] KVM: selftests: Use TEST_ASSERT(), not assert(), in vm_get_mem_region()
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (16 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 17/20] KVM: selftests: Take the memory region type, not memslot, in page allocators Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-26 23:05 ` [PATCH 19/20] KVM: selftests: Automatically pick min_gpa for allocations based on region type Sean Christopherson
` (2 subsequent siblings)
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Use a proper selftests TEST_ASSERT() in vm_get_mem_region() so that bad
input is guaranteed to fail the test, and with the standard error message
format.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/include/kvm_util.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 783f060faf9e..a0cd1b6598d4 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -198,7 +198,8 @@ memslot2region(struct kvm_vm *vm, u32 memslot);
static inline struct userspace_mem_region *vm_get_mem_region(struct kvm_vm *vm,
enum kvm_mem_region_type type)
{
- assert(type < NR_MEM_REGIONS);
+ TEST_ASSERT(type < NR_MEM_REGIONS,
+ "Invalid memory region type '%u'", type);
return memslot2region(vm, vm->memslots[type]);
}
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 19/20] KVM: selftests: Automatically pick min_gpa for allocations based on region type
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (17 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 18/20] KVM: selftests: Use TEST_ASSERT(), not assert(), in vm_get_mem_region() Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-26 23:05 ` [PATCH 20/20] KVM: selftests: Add arch hook to force page tables to be naturally aligned Sean Christopherson
2026-08-27 8:07 ` [PATCH 00/20] KVM: selftests: PPC pre-enabling Itaru Kitayama
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Automatically choose the minimum GPA for physical page allocations based on
the region type instead of sprinkling the logic over various wrappers and
tests. All usage falls into three categories: (a) don't care, just use the
bare minimum GPA, (b) page tables, use a slightly higher min to keep low
memory available, (c) custom memslot, use the base of the memslot. I.e.
there isn't a strong need to allow completely custom minimums.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
.../selftests/kvm/arm64/vgic_lpi_stress.c | 11 ++----
.../testing/selftests/kvm/include/kvm_util.h | 12 +++---
tools/testing/selftests/kvm/lib/kvm_util.c | 38 ++++++++++++++++---
.../testing/selftests/kvm/lib/x86/processor.c | 3 +-
.../selftests/kvm/set_memory_region_test.c | 2 +-
.../x86/smaller_maxphyaddr_emulation_test.c | 2 +-
6 files changed, 44 insertions(+), 24 deletions(-)
diff --git a/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c b/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
index a45c0849a47a..b4c651ea385d 100644
--- a/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
+++ b/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
@@ -191,28 +191,25 @@ static void setup_test_data(void)
gpa_t cmdq_base;
test_data.device_table = vm_phy_pages_alloc(vm, pages_per_64k,
- gpa_base,
MEM_REGION_TEST_EXTRA);
test_data.collection_table = vm_phy_pages_alloc(vm, pages_per_64k,
- gpa_base,
MEM_REGION_TEST_EXTRA);
- cmdq_base = vm_phy_pages_alloc(vm, pages_per_64k, gpa_base,
- MEM_REGION_TEST_EXTRA);
+ cmdq_base = vm_phy_pages_alloc(vm, pages_per_64k, MEM_REGION_TEST_EXTRA);
virt_map(vm, cmdq_base, cmdq_base, pages_per_64k);
test_data.cmdq_base = cmdq_base;
test_data.cmdq_base_va = (void *)cmdq_base;
test_data.itt_tables = vm_phy_pages_alloc(vm, pages_per_64k * nr_devices,
- gpa_base, MEM_REGION_TEST_EXTRA);
+ MEM_REGION_TEST_EXTRA);
test_data.lpi_prop_table = vm_phy_pages_alloc(vm, pages_per_64k,
- gpa_base, MEM_REGION_TEST_EXTRA);
+ MEM_REGION_TEST_EXTRA);
configure_lpis();
test_data.lpi_pend_tables = vm_phy_pages_alloc(vm, pages_per_64k * nr_cpus,
- gpa_base, MEM_REGION_TEST_EXTRA);
+ MEM_REGION_TEST_EXTRA);
sync_global_to_guest(vm, test_data);
}
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index a0cd1b6598d4..1264cd1a343a 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -1052,11 +1052,10 @@ const char *exit_reason_str(unsigned int exit_reason);
gpa_t ____vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
u32 memslot, bool protected, bool naturally_aligned);
-gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
+gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
enum kvm_mem_region_type type, bool protected);
static inline gpa_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
- gpa_t min_gpa,
enum kvm_mem_region_type type)
{
/*
@@ -1064,20 +1063,19 @@ static inline gpa_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
* protected memory, as the majority of memory for such VMs is
* protected, i.e. using shared memory is effectively opt-in.
*/
- return __vm_phy_pages_alloc(vm, nr_pages, min_gpa, type,
+ return __vm_phy_pages_alloc(vm, nr_pages, type,
vm_arch_has_protected_memory(vm));
}
-static inline gpa_t vm_phy_page_alloc(struct kvm_vm *vm, gpa_t min_gpa,
+static inline gpa_t vm_phy_page_alloc(struct kvm_vm *vm,
enum kvm_mem_region_type type)
{
- return vm_phy_pages_alloc(vm, 1, min_gpa, type);
+ return vm_phy_pages_alloc(vm, 1, type);
}
static inline gpa_t vm_alloc_page_table_pages(struct kvm_vm *vm, size_t nr_pages)
{
- return vm_phy_pages_alloc(vm, nr_pages, KVM_GUEST_PAGE_TABLE_MIN_PADDR,
- MEM_REGION_PT);
+ return vm_phy_pages_alloc(vm, nr_pages, MEM_REGION_PT);
}
static inline gpa_t vm_alloc_page_table(struct kvm_vm *vm)
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index e500d1799151..8b5b330a5889 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1473,9 +1473,7 @@ static gva_t ____vm_alloc(struct kvm_vm *vm, size_t sz, gva_t min_gva,
u64 pages = (sz >> vm->page_shift) + ((sz % vm->page_size) != 0);
virt_pgd_alloc(vm);
- gpa_t gpa = __vm_phy_pages_alloc(vm, pages,
- KVM_UTIL_MIN_PFN * vm->page_size,
- type, protected);
+ gpa_t gpa = __vm_phy_pages_alloc(vm, pages, type, protected);
/*
* Find an unused range of virtual page addresses of at least
@@ -2087,11 +2085,39 @@ gpa_t ____vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
__builtin_unreachable();
}
-gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
+gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
enum kvm_mem_region_type type, bool protected)
{
- TEST_ASSERT(type < NR_MEM_REGIONS,
- "Invalid memory region type '%u'", type);
+ struct userspace_mem_region *region = vm_get_mem_region(vm, type);
+ gpa_t min_gpa;
+
+ TEST_ASSERT(region, "No region for type '%u', memslot '%u'",
+ type, vm->memslots[type]);
+
+ switch (type) {
+ case MEM_REGION_CODE:
+ case MEM_REGION_DATA:
+ case MEM_REGION_TEST_DATA:
+ /*
+ * If the region is backed by the default memslot (id=0), use
+ * selftests' hardcoded minimum PFN, otherwise use the base of
+ * the custom memory slot that backs the region.
+ */
+ if (!vm->memslots[type])
+ min_gpa = KVM_UTIL_MIN_PFN * vm->page_size;
+ else
+ min_gpa = region->region.guest_phys_addr;
+ break;
+ case MEM_REGION_PT:
+ min_gpa = KVM_GUEST_PAGE_TABLE_MIN_PADDR;
+ break;
+ case MEM_REGION_TEST_EXTRA:
+ min_gpa = region->region.guest_phys_addr;
+ break;
+ default:
+ TEST_FAIL("Invalid memory region type '%u'", type);
+ break;
+ }
return ____vm_phy_pages_alloc(vm, nr_pages, min_gpa, vm->memslots[type],
protected, false);
diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
index 39d9ca6ceb1d..479e9a481687 100644
--- a/tools/testing/selftests/kvm/lib/x86/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86/processor.c
@@ -1474,8 +1474,7 @@ void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, gpa_t smram_gpa,
vm_override_mem_region(vm, MEM_REGION_TEST_EXTRA, VM_MEM_SRC_ANONYMOUS,
smram_gpa, SMRAM_MEMSLOT, SMRAM_PAGES);
- TEST_ASSERT(vm_phy_pages_alloc(vm, SMRAM_PAGES, smram_gpa,
- MEM_REGION_TEST_EXTRA) == smram_gpa,
+ TEST_ASSERT(vm_phy_pages_alloc(vm, SMRAM_PAGES, MEM_REGION_TEST_EXTRA) == smram_gpa,
"Could not allocate guest physical addresses for SMRAM");
memset(addr_gpa2hva(vm, smram_gpa), 0x0, SMRAM_SIZE);
diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/testing/selftests/kvm/set_memory_region_test.c
index 160bbe3d7203..bfa5ac8ce029 100644
--- a/tools/testing/selftests/kvm/set_memory_region_test.c
+++ b/tools/testing/selftests/kvm/set_memory_region_test.c
@@ -124,7 +124,7 @@ static struct kvm_vm *spawn_vm(struct kvm_vcpu **vcpu, pthread_t *vcpu_thread,
* Allocate and map two pages so that the GPA accessed by guest_code()
* stays valid across the memslot move.
*/
- gpa = vm_phy_pages_alloc(vm, 2, MEM_REGION_GPA, MEM_REGION_TEST_EXTRA);
+ gpa = vm_phy_pages_alloc(vm, 2, MEM_REGION_TEST_EXTRA);
TEST_ASSERT(gpa == MEM_REGION_GPA, "Failed vm_phy_pages_alloc\n");
virt_map(vm, MEM_REGION_GPA, MEM_REGION_GPA, 2);
diff --git a/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c b/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
index 4e125eb5e0cf..8d1822717abd 100644
--- a/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
+++ b/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
@@ -67,7 +67,7 @@ int main(int argc, char *argv[])
MEM_REGION_SIZE / PAGE_SIZE);
gpa = vm_phy_pages_alloc(vm, MEM_REGION_SIZE / PAGE_SIZE,
- MEM_REGION_GPA, MEM_REGION_TEST_EXTRA);
+ MEM_REGION_TEST_EXTRA);
TEST_ASSERT(gpa == MEM_REGION_GPA, "Failed vm_phy_pages_alloc");
virt_map(vm, MEM_REGION_GVA, MEM_REGION_GPA, 1);
hva = addr_gpa2hva(vm, MEM_REGION_GPA);
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 20/20] KVM: selftests: Add arch hook to force page tables to be naturally aligned
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (18 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 19/20] KVM: selftests: Automatically pick min_gpa for allocations based on region type Sean Christopherson
@ 2026-08-26 23:05 ` Sean Christopherson
2026-08-27 8:07 ` [PATCH 00/20] KVM: selftests: PPC pre-enabling Itaru Kitayama
20 siblings, 0 replies; 25+ messages in thread
From: Sean Christopherson @ 2026-08-26 23:05 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Sean Christopherson, Paolo Bonzini,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
Add an arch hook to communicate to the core physical page allocator that
page table allocations need to be naturally aligned. The hook will be used
for upcoming PowerPC support, which has MMU tables that are larger than the
guest base page size and need to be naturally aligned.
Bury the hook in the physical page allocator to avoid having to plumb a
rarely used param into the main APIs.
Cc: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/include/kvm_util.h | 2 ++
tools/testing/selftests/kvm/lib/kvm_util.c | 9 ++++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 1264cd1a343a..ffd4cf740d7f 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -1050,6 +1050,8 @@ void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing);
const char *exit_reason_str(unsigned int exit_reason);
+bool kvm_arch_needs_naturally_aligned_page_tables(void);
+
gpa_t ____vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
u32 memslot, bool protected, bool naturally_aligned);
gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 8b5b330a5889..57b653fbd0b1 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -2085,10 +2085,16 @@ gpa_t ____vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages, gpa_t min_gpa,
__builtin_unreachable();
}
+__weak bool kvm_arch_needs_naturally_aligned_page_tables(void)
+{
+ return false;
+}
+
gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
enum kvm_mem_region_type type, bool protected)
{
struct userspace_mem_region *region = vm_get_mem_region(vm, type);
+ bool naturally_aligned = false;
gpa_t min_gpa;
TEST_ASSERT(region, "No region for type '%u', memslot '%u'",
@@ -2110,6 +2116,7 @@ gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
break;
case MEM_REGION_PT:
min_gpa = KVM_GUEST_PAGE_TABLE_MIN_PADDR;
+ naturally_aligned = kvm_arch_needs_naturally_aligned_page_tables();
break;
case MEM_REGION_TEST_EXTRA:
min_gpa = region->region.guest_phys_addr;
@@ -2120,7 +2127,7 @@ gpa_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t nr_pages,
}
return ____vm_phy_pages_alloc(vm, nr_pages, min_gpa, vm->memslots[type],
- protected, false);
+ protected, naturally_aligned);
}
/*
--
2.55.0.887.g758fc8c411-goog
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 13/20] KVM: selftests: Add TEST_EXTRA memory region type for "special" memslots
2026-08-26 23:05 ` [PATCH 13/20] KVM: selftests: Add TEST_EXTRA memory region type for "special" memslots Sean Christopherson
@ 2026-08-27 4:37 ` Itaru Kitayama
0 siblings, 0 replies; 25+ messages in thread
From: Itaru Kitayama @ 2026-08-27 4:37 UTC (permalink / raw)
To: Sean Christopherson
Cc: Marc Zyngier, Oliver Upton, Paolo Bonzini, Tianrui Zhao, Bibo Mao,
Huacai Chen, Anup Patel, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Christian Borntraeger, Janosch Frank, Claudio Imbrenda,
Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
On Wed, Aug 26, 2026 at 04:05:04PM -0700, Sean Christopherson wrote:
> And another memory region type to deal with extra, one-off memory regions,
> and use the new type to manage x86's SMRAM memslot, as another step towards
> taking the region type instead of the raw memslot in the physical page
> allocator APIs.
>
> Alternatively, SMRAM setup could simply use the quad-underscore API to
> continue passing in the memslot, but a surprising number of tests use an
> "extra" memslot for a variety of reasons. I.e. allocating memory from one
> (and exactly one) extra memslot isn't all that rare, and so should be
> treated as normal behavior, not as something extraordinary, as
> quad-underscore functions typically suggest.
>
> Opportunistically add comments to document the intended usage of the types,
> as the difference between DATA, TEST_DATA, and TEST_EXTRA in particular
> isn't exactly obvious.
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> .../testing/selftests/kvm/include/kvm_util.h | 37 ++++++++++++++++---
> tools/testing/selftests/kvm/include/x86/smm.h | 2 +-
> .../testing/selftests/kvm/lib/x86/processor.c | 7 ++--
> 3 files changed, 37 insertions(+), 9 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
> index 14f87c8a00ec..f4f4f360a10b 100644
> --- a/tools/testing/selftests/kvm/include/kvm_util.h
> +++ b/tools/testing/selftests/kvm/include/kvm_util.h
> @@ -82,11 +82,43 @@ struct userspace_mem_regions {
> DECLARE_HASHTABLE(slot_hash, 9);
> };
>
> +/*
> + * Memory region types are passed to various page allocators to communicate
> + * various properties and metadata related to the allocation. Note, the
> + * descriptions below described the primary usage of each type. Individual
> + * tests may allocate memory for other purposes.
> + *
> + * By default, all regions are mapped to memslot '0'. Tests can override the
> + * memslot for any or all types, e.g. so that all test data is allocated from a
> + * curated memslot.
> + */
This is helpful as it wasn't so obvious to me. Thanks for adding the comments
on the default behaviour.
Thanks,
Itaru.
> enum kvm_mem_region_type {
> + /*
> + * The CODE region is used by lib/elf when loading the test's code into
> + * guest memory.
> + */
> MEM_REGION_CODE,
> + /*
> + * The DATA region is used to allocate core data structures, e.g. vCPU
> + * stacks, VM exception tables, x86's TSS, etc.
> + */
> MEM_REGION_DATA,
> + /*
> + * The PT region, a.k.a. Page Table region, is used to allocate page
> + * table pages.
> + */
> MEM_REGION_PT,
> + /*
> + * The TEST_DATA region is used for allocating test data that is either
> + * test specific, and/or isn't considered a "core" data structure.
> + */
> MEM_REGION_TEST_DATA,
> + /*
> + * The TEST_EXTRA region is for special snowflakes, where a test wants
> + * to create and use a one-off memslot, without impacting "normal" test
> + * data allocations.
> + */
> + MEM_REGION_TEST_EXTRA,
> NR_MEM_REGIONS,
> };
>
> @@ -129,11 +161,6 @@ struct kvm_vm {
>
> struct kvm_binary_stats stats;
>
> - /*
> - * KVM region slots. These are the default memslots used by page
> - * allocators, e.g., lib/elf uses the memslots[MEM_REGION_CODE]
> - * memslot.
> - */
> u32 memslots[NR_MEM_REGIONS];
> };
>
> diff --git a/tools/testing/selftests/kvm/include/x86/smm.h b/tools/testing/selftests/kvm/include/x86/smm.h
> index 2d1afa09819b..15faaa060126 100644
> --- a/tools/testing/selftests/kvm/include/x86/smm.h
> +++ b/tools/testing/selftests/kvm/include/x86/smm.h
> @@ -8,7 +8,7 @@
> #define SMRAM_MEMSLOT ((1 << 16) | 1)
> #define SMRAM_PAGES (SMRAM_SIZE / PAGE_SIZE)
>
> -void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, u64 smram_gpa,
> +void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, gpa_t smram_gpa,
> const void *smi_handler, size_t handler_size);
>
> void inject_smi(struct kvm_vcpu *vcpu);
> diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
> index ea5fa59888af..b988eea373ad 100644
> --- a/tools/testing/selftests/kvm/lib/x86/processor.c
> +++ b/tools/testing/selftests/kvm/lib/x86/processor.c
> @@ -1468,11 +1468,12 @@ bool kvm_arch_has_default_irqchip(void)
> return true;
> }
>
> -void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, u64 smram_gpa,
> +void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, gpa_t smram_gpa,
> const void *smi_handler, size_t handler_size)
> {
> - vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, smram_gpa,
> - SMRAM_MEMSLOT, SMRAM_PAGES, 0);
> + vm_override_mem_region(vm, MEM_REGION_TEST_EXTRA, VM_MEM_SRC_ANONYMOUS,
> + smram_gpa, SMRAM_MEMSLOT, SMRAM_PAGES);
> +
> TEST_ASSERT(vm_phy_pages_alloc(vm, SMRAM_PAGES, smram_gpa,
> SMRAM_MEMSLOT) == smram_gpa,
> "Could not allocate guest physical addresses for SMRAM");
> --
> 2.55.0.887.g758fc8c411-goog
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 10/20] KVM: selftests: Add a wrapper API to allocate multiple page table pages
2026-08-26 23:05 ` [PATCH 10/20] KVM: selftests: Add a wrapper API to allocate multiple page table pages Sean Christopherson
@ 2026-08-27 5:27 ` Itaru Kitayama
0 siblings, 0 replies; 25+ messages in thread
From: Itaru Kitayama @ 2026-08-27 5:27 UTC (permalink / raw)
To: Sean Christopherson
Cc: Marc Zyngier, Oliver Upton, Paolo Bonzini, Tianrui Zhao, Bibo Mao,
Huacai Chen, Anup Patel, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Christian Borntraeger, Janosch Frank, Claudio Imbrenda,
Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
On Wed, Aug 26, 2026 at 04:05:01PM -0700, Sean Christopherson wrote:
> Add vm_alloc_page_table_pages() and use it throughout arch code to replace
> open coded equivalents.
>
> No functional change intended.
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> tools/testing/selftests/kvm/include/kvm_util.h | 9 +++++++--
> tools/testing/selftests/kvm/lib/arm64/processor.c | 4 +---
> tools/testing/selftests/kvm/lib/riscv/processor.c | 4 +---
> tools/testing/selftests/kvm/lib/s390/processor.c | 8 ++------
> 4 files changed, 11 insertions(+), 14 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
> index 2525c2cacc22..21354434de0a 100644
> --- a/tools/testing/selftests/kvm/include/kvm_util.h
> +++ b/tools/testing/selftests/kvm/include/kvm_util.h
> @@ -1013,10 +1013,15 @@ static inline gpa_t vm_phy_page_alloc(struct kvm_vm *vm, gpa_t min_gpa,
> return vm_phy_pages_alloc(vm, 1, min_gpa, memslot);
> }
>
> +static inline gpa_t vm_alloc_page_table_pages(struct kvm_vm *vm, size_t nr_pages)
> +{
> + return vm_phy_pages_alloc(vm, nr_pages, KVM_GUEST_PAGE_TABLE_MIN_PADDR,
> + vm->memslots[MEM_REGION_PT]);
> +}
> +
> static inline gpa_t vm_alloc_page_table(struct kvm_vm *vm)
> {
> - return vm_phy_page_alloc(vm, KVM_GUEST_PAGE_TABLE_MIN_PADDR,
> - vm->memslots[MEM_REGION_PT]);
> + return vm_alloc_page_table_pages(vm, 1);
> }
>
> /*
> diff --git a/tools/testing/selftests/kvm/lib/arm64/processor.c b/tools/testing/selftests/kvm/lib/arm64/processor.c
> index 01325bf4d36f..2dcaa2c4a038 100644
> --- a/tools/testing/selftests/kvm/lib/arm64/processor.c
> +++ b/tools/testing/selftests/kvm/lib/arm64/processor.c
> @@ -115,9 +115,7 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm)
> if (vm->mmu.pgd_created)
> return;
>
> - vm->mmu.pgd = vm_phy_pages_alloc(vm, nr_pages,
> - KVM_GUEST_PAGE_TABLE_MIN_PADDR,
> - vm->memslots[MEM_REGION_PT]);
> + vm->mmu.pgd = vm_alloc_page_table_pages(vm, nr_pages);
> vm->mmu.pgd_created = true;
> }
Reviewed-by: Itaru Kitayama <itaru.kitayama@fujitsu.com>
>
> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
> index ded5429f3448..c175dcd14114 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> @@ -69,9 +69,7 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm)
> if (vm->mmu.pgd_created)
> return;
>
> - vm->mmu.pgd = vm_phy_pages_alloc(vm, nr_pages,
> - KVM_GUEST_PAGE_TABLE_MIN_PADDR,
> - vm->memslots[MEM_REGION_PT]);
> + vm->mmu.pgd = vm_alloc_page_table_pages(vm, nr_pages);
> vm->mmu.pgd_created = true;
> }
>
> diff --git a/tools/testing/selftests/kvm/lib/s390/processor.c b/tools/testing/selftests/kvm/lib/s390/processor.c
> index fb9dab92d4d1..33f49d743b5f 100644
> --- a/tools/testing/selftests/kvm/lib/s390/processor.c
> +++ b/tools/testing/selftests/kvm/lib/s390/processor.c
> @@ -20,9 +20,7 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm)
> if (vm->mmu.pgd_created)
> return;
>
> - gpa = vm_phy_pages_alloc(vm, PAGES_PER_REGION,
> - KVM_GUEST_PAGE_TABLE_MIN_PADDR,
> - vm->memslots[MEM_REGION_PT]);
> + gpa = vm_alloc_page_table_pages(vm, PAGES_PER_REGION);
> memset(addr_gpa2hva(vm, gpa), 0xff, PAGES_PER_REGION * vm->page_size);
>
> vm->mmu.pgd = gpa;
> @@ -38,9 +36,7 @@ static u64 virt_alloc_region(struct kvm_vm *vm, int ri)
> {
> u64 taddr;
>
> - taddr = vm_phy_pages_alloc(vm, ri < 4 ? PAGES_PER_REGION : 1,
> - KVM_GUEST_PAGE_TABLE_MIN_PADDR,
> - vm->memslots[MEM_REGION_PT]);
> + taddr = vm_alloc_page_table_pages(vm, ri < 4 ? PAGES_PER_REGION : 1);
> memset(addr_gpa2hva(vm, taddr), 0xff, PAGES_PER_REGION * vm->page_size);
>
> return (taddr & REGION_ENTRY_ORIGIN)
> --
> 2.55.0.887.g758fc8c411-goog
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 03/20] KVM: selftests: Use vm_alloc_page_table() to allocate LoongArch page tables
2026-08-26 23:04 ` [PATCH 03/20] KVM: selftests: Use vm_alloc_page_table() to allocate LoongArch page tables Sean Christopherson
@ 2026-08-27 6:43 ` Bibo Mao
0 siblings, 0 replies; 25+ messages in thread
From: Bibo Mao @ 2026-08-27 6:43 UTC (permalink / raw)
To: Sean Christopherson, Marc Zyngier, Oliver Upton, Paolo Bonzini,
Tianrui Zhao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Christian Borntraeger, Janosch Frank,
Claudio Imbrenda
Cc: Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
On 2026/8/27 上午7:04, Sean Christopherson wrote:
> Now that KVM_GUEST_PAGE_TABLE_MIN_PADDR == LOONGARCH_PAGE_TABLE_PHYS_MIN,
> use the common vm_alloc_page_table() instead of open coding the same.
>
> Opportunistically drop the assert that the allocation succeeded, as the
> allocator itself guarantees success.
>
> For all intents and purposes, no functional change intended.
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> tools/testing/selftests/kvm/lib/loongarch/processor.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/lib/loongarch/processor.c b/tools/testing/selftests/kvm/lib/loongarch/processor.c
> index 47bbde3e205a..fcd41bc6fbda 100644
> --- a/tools/testing/selftests/kvm/lib/loongarch/processor.c
> +++ b/tools/testing/selftests/kvm/lib/loongarch/processor.c
> @@ -9,7 +9,6 @@
> #include "processor.h"
> #include "ucall_common.h"
>
> -#define LOONGARCH_PAGE_TABLE_PHYS_MIN 0x200000
> #define LOONGARCH_GUEST_STACK_VADDR_MIN 0x200000
>
> static gpa_t invalid_pgtable[4];
> @@ -57,9 +56,7 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm)
> child = table = 0;
> for (i = 0; i < vm->mmu.pgtable_levels; i++) {
> invalid_pgtable[i] = child;
> - table = vm_phy_page_alloc(vm, LOONGARCH_PAGE_TABLE_PHYS_MIN,
> - vm->memslots[MEM_REGION_PT]);
> - TEST_ASSERT(table, "Fail to allocate page tale at level %d\n", i);
> + table = vm_alloc_page_table(vm);
> virt_set_pgtable(vm, table, child);
> child = table;
> }
>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 00/20] KVM: selftests: PPC pre-enabling
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
` (19 preceding siblings ...)
2026-08-26 23:05 ` [PATCH 20/20] KVM: selftests: Add arch hook to force page tables to be naturally aligned Sean Christopherson
@ 2026-08-27 8:07 ` Itaru Kitayama
20 siblings, 0 replies; 25+ messages in thread
From: Itaru Kitayama @ 2026-08-27 8:07 UTC (permalink / raw)
To: Sean Christopherson
Cc: Marc Zyngier, Oliver Upton, Paolo Bonzini, Tianrui Zhao, Bibo Mao,
Huacai Chen, Anup Patel, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Christian Borntraeger, Janosch Frank, Claudio Imbrenda,
Fuad Tabba, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
Zenghui Yu, Atish Patra, Alexandre Ghiti, David Hildenbrand,
linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv, linux-riscv,
linux-kernel, Nicholas Piggin, Ritesh Harjani
On Wed, Aug 26, 2026 at 04:04:51PM -0700, Sean Christopherson wrote:
> This is a big pile of cleanups and refactoring to prepare for PPC support in
> KVM selftests. PPC has paging modes that require multi-page page tables, and
> those page tables need to be naturally aligned. The original proposal was to
> plumb in an @align param to the page allocators[*], but I didn't love the idea
> of adding another rarely used param to the allocators.
>
> Reworking the APIs to take a region type requires a fair bit of churn, and was
> more painful than expected as I didn't realize just how many one-off tests did
> weird things, but overall I think it's worth it? If only to keep cutting down
> on the use of magic memslot numbers in tests.
>
> This needs explicit testing on s390. I tested on arm64 and x86, and given the
> number of failures I had to wade through, I wouldn't be at all suprised if I
> broke something subtle on s390 as well.
>
> I'm less concerned about RISC-V and LoongArch as they don't have any custom
> tests that are affected (which is where I got burned).
I ran kvm_page_table_test with this series applied on Grace CPUs.
Passes across all the arm64 guest modes supported.
Tested-by: Itaru Kitayama <itaru.kitayama@fujitsu.com>
>
> [*] https://lore.kernel.org/all/df86b5ccdbdafc3509d9538bd5e6796737bab2db.1781093720.git.ritesh.list@gmail.com
>
> Nicholas Piggin (1):
> KVM: selftests: Use goto instead of do-while to retry finding unused
> physical pages
>
> Sean Christopherson (19):
> KVM: selftests: Use MEM_REGION_PT memslot instead of '0' for s390
> regions/segments
> KVM: selftests: Bump the minimum GPA for page tables to 0x200000
> KVM: selftests: Use vm_alloc_page_table() to allocate LoongArch page
> tables
> KVM: selftests: Rename "num" param to "nr_pages" for physical page
> allocators
> KVM: selftests: Extend page allocator to support naturally aligned
> allocations
> KVM: selftests: Make the single-page allocator APIs static inline
> KVM: selftests: Use the innermost page allocator API in the memslot
> perf test
> KVM: selftests: Use the innermost page allocator API in s390's IRQ
> routing test
> KVM: selftests: Add a wrapper API to allocate multiple page table
> pages
> KVM: selftests: Initialize vm->memslots[] with invalid memslots during
> creation
> KVM: selftests: Add APIs to override memory region types with custom
> memslots
> KVM: selftests: Add TEST_EXTRA memory region type for "special"
> memslots
> KVM: selftests: Use TEST_EXTRA region in arm64's vGIC LPI stress test
> KVM: selftests: Use TEST_EXTRA region in x86's smaller MAXPHYADDR test
> KVM: selftests: Use TEST_EXTRA region in set memory region test
> KVM: selftests: Take the memory region type, not memslot, in page
> allocators
> KVM: selftests: Use TEST_ASSERT(), not assert(), in
> vm_get_mem_region()
> KVM: selftests: Automatically pick min_gpa for allocations based on
> region type
> KVM: selftests: Add arch hook to force page tables to be naturally
> aligned
>
> .../selftests/kvm/arm64/page_fault_test.c | 18 ++-
> .../selftests/kvm/arm64/vgic_lpi_stress.c | 19 ++-
> .../testing/selftests/kvm/include/kvm_util.h | 106 +++++++++++++--
> tools/testing/selftests/kvm/include/x86/smm.h | 2 +-
> .../selftests/kvm/lib/arm64/processor.c | 4 +-
> tools/testing/selftests/kvm/lib/kvm_util.c | 127 +++++++++++-------
> .../selftests/kvm/lib/loongarch/processor.c | 5 +-
> .../selftests/kvm/lib/riscv/processor.c | 4 +-
> .../selftests/kvm/lib/s390/processor.c | 7 +-
> .../testing/selftests/kvm/lib/x86/processor.c | 15 ++-
> .../testing/selftests/kvm/memslot_perf_test.c | 3 +-
> tools/testing/selftests/kvm/s390/cmma_test.c | 19 +--
> .../testing/selftests/kvm/s390/irq_routing.c | 2 +-
> .../selftests/kvm/set_memory_region_test.c | 8 +-
> .../x86/smaller_maxphyaddr_emulation_test.c | 9 +-
> 15 files changed, 219 insertions(+), 129 deletions(-)
>
>
> base-commit: 76671054f9a1ff6abb976583cd8da37650acdc97
> --
> 2.55.0.887.g758fc8c411-goog
>
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2026-08-27 8:08 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-26 23:04 [PATCH 00/20] KVM: selftests: PPC pre-enabling Sean Christopherson
2026-08-26 23:04 ` [PATCH 01/20] KVM: selftests: Use MEM_REGION_PT memslot instead of '0' for s390 regions/segments Sean Christopherson
2026-08-26 23:04 ` [PATCH 02/20] KVM: selftests: Bump the minimum GPA for page tables to 0x200000 Sean Christopherson
2026-08-26 23:04 ` [PATCH 03/20] KVM: selftests: Use vm_alloc_page_table() to allocate LoongArch page tables Sean Christopherson
2026-08-27 6:43 ` Bibo Mao
2026-08-26 23:04 ` [PATCH 04/20] KVM: selftests: Rename "num" param to "nr_pages" for physical page allocators Sean Christopherson
2026-08-26 23:04 ` [PATCH 05/20] KVM: selftests: Use goto instead of do-while to retry finding unused physical pages Sean Christopherson
2026-08-26 23:04 ` [PATCH 06/20] KVM: selftests: Extend page allocator to support naturally aligned allocations Sean Christopherson
2026-08-26 23:04 ` [PATCH 07/20] KVM: selftests: Make the single-page allocator APIs static inline Sean Christopherson
2026-08-26 23:04 ` [PATCH 08/20] KVM: selftests: Use the innermost page allocator API in the memslot perf test Sean Christopherson
2026-08-26 23:05 ` [PATCH 09/20] KVM: selftests: Use the innermost page allocator API in s390's IRQ routing test Sean Christopherson
2026-08-26 23:05 ` [PATCH 10/20] KVM: selftests: Add a wrapper API to allocate multiple page table pages Sean Christopherson
2026-08-27 5:27 ` Itaru Kitayama
2026-08-26 23:05 ` [PATCH 11/20] KVM: selftests: Initialize vm->memslots[] with invalid memslots during creation Sean Christopherson
2026-08-26 23:05 ` [PATCH 12/20] KVM: selftests: Add APIs to override memory region types with custom memslots Sean Christopherson
2026-08-26 23:05 ` [PATCH 13/20] KVM: selftests: Add TEST_EXTRA memory region type for "special" memslots Sean Christopherson
2026-08-27 4:37 ` Itaru Kitayama
2026-08-26 23:05 ` [PATCH 14/20] KVM: selftests: Use TEST_EXTRA region in arm64's vGIC LPI stress test Sean Christopherson
2026-08-26 23:05 ` [PATCH 15/20] KVM: selftests: Use TEST_EXTRA region in x86's smaller MAXPHYADDR test Sean Christopherson
2026-08-26 23:05 ` [PATCH 16/20] KVM: selftests: Use TEST_EXTRA region in set memory region test Sean Christopherson
2026-08-26 23:05 ` [PATCH 17/20] KVM: selftests: Take the memory region type, not memslot, in page allocators Sean Christopherson
2026-08-26 23:05 ` [PATCH 18/20] KVM: selftests: Use TEST_ASSERT(), not assert(), in vm_get_mem_region() Sean Christopherson
2026-08-26 23:05 ` [PATCH 19/20] KVM: selftests: Automatically pick min_gpa for allocations based on region type Sean Christopherson
2026-08-26 23:05 ` [PATCH 20/20] KVM: selftests: Add arch hook to force page tables to be naturally aligned Sean Christopherson
2026-08-27 8:07 ` [PATCH 00/20] KVM: selftests: PPC pre-enabling Itaru Kitayama
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox