Re: [PATCH v3 2/3] KVM: selftests: Enable pre_fault_memory_test for arm64

2025-12-05 Thread Vincent Donnefort
On Wed, Nov 19, 2025 at 03:49:09PM +, Jack Thomson wrote:
> From: Jack Thomson 
> 
> Enable the pre_fault_memory_test to run on arm64 by making it work with
> different guest page sizes and testing multiple guest configurations.
> 
> Update the test_assert to compare against the UCALL_EXIT_REASON, for
> portability, as arm64 exits with KVM_EXIT_MMIO while x86 uses
> KVM_EXIT_IO.
> 
> Signed-off-by: Jack Thomson 
> ---
>  tools/testing/selftests/kvm/Makefile.kvm  |  1 +
>  .../selftests/kvm/pre_fault_memory_test.c | 78 ++-
>  2 files changed, 58 insertions(+), 21 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/Makefile.kvm 
> b/tools/testing/selftests/kvm/Makefile.kvm
> index 148d427ff24b..0ddd8db60197 100644
> --- a/tools/testing/selftests/kvm/Makefile.kvm
> +++ b/tools/testing/selftests/kvm/Makefile.kvm
> @@ -183,6 +183,7 @@ TEST_GEN_PROGS_arm64 += memslot_perf_test
>  TEST_GEN_PROGS_arm64 += mmu_stress_test
>  TEST_GEN_PROGS_arm64 += rseq_test
>  TEST_GEN_PROGS_arm64 += steal_time
> +TEST_GEN_PROGS_arm64 += pre_fault_memory_test
>  
>  TEST_GEN_PROGS_s390 = $(TEST_GEN_PROGS_COMMON)
>  TEST_GEN_PROGS_s390 += s390/memop
> diff --git a/tools/testing/selftests/kvm/pre_fault_memory_test.c 
> b/tools/testing/selftests/kvm/pre_fault_memory_test.c
> index f04768c1d2e4..674931e7bb3a 100644
> --- a/tools/testing/selftests/kvm/pre_fault_memory_test.c
> +++ b/tools/testing/selftests/kvm/pre_fault_memory_test.c
> @@ -11,19 +11,29 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  /* Arbitrarily chosen values */
> -#define TEST_SIZE(SZ_2M + PAGE_SIZE)
> -#define TEST_NPAGES  (TEST_SIZE / PAGE_SIZE)

After applying on top of the base commit
8a4821412cf2c1429fffa07c012dd150f2edf78c, it does not build.

That TEST_NPAGES seems to still be used in delete_slot_worker(). I believe
that's because of

  "KVM: selftests: Test prefault memory during concurrent memslot removal"

Related issues with the pre_fault_memory() prototype.

Is that the correct base-commit or shall I use something else?

> +#define TEST_BASE_SIZE   SZ_2M
>  #define TEST_SLOT10
>

[...]



[PATCH v3 2/3] KVM: selftests: Enable pre_fault_memory_test for arm64

2025-11-19 Thread Jack Thomson
From: Jack Thomson 

Enable the pre_fault_memory_test to run on arm64 by making it work with
different guest page sizes and testing multiple guest configurations.

Update the test_assert to compare against the UCALL_EXIT_REASON, for
portability, as arm64 exits with KVM_EXIT_MMIO while x86 uses
KVM_EXIT_IO.

Signed-off-by: Jack Thomson 
---
 tools/testing/selftests/kvm/Makefile.kvm  |  1 +
 .../selftests/kvm/pre_fault_memory_test.c | 78 ++-
 2 files changed, 58 insertions(+), 21 deletions(-)

diff --git a/tools/testing/selftests/kvm/Makefile.kvm 
b/tools/testing/selftests/kvm/Makefile.kvm
index 148d427ff24b..0ddd8db60197 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -183,6 +183,7 @@ TEST_GEN_PROGS_arm64 += memslot_perf_test
 TEST_GEN_PROGS_arm64 += mmu_stress_test
 TEST_GEN_PROGS_arm64 += rseq_test
 TEST_GEN_PROGS_arm64 += steal_time
+TEST_GEN_PROGS_arm64 += pre_fault_memory_test
 
 TEST_GEN_PROGS_s390 = $(TEST_GEN_PROGS_COMMON)
 TEST_GEN_PROGS_s390 += s390/memop
diff --git a/tools/testing/selftests/kvm/pre_fault_memory_test.c 
b/tools/testing/selftests/kvm/pre_fault_memory_test.c
index f04768c1d2e4..674931e7bb3a 100644
--- a/tools/testing/selftests/kvm/pre_fault_memory_test.c
+++ b/tools/testing/selftests/kvm/pre_fault_memory_test.c
@@ -11,19 +11,29 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Arbitrarily chosen values */
-#define TEST_SIZE  (SZ_2M + PAGE_SIZE)
-#define TEST_NPAGES(TEST_SIZE / PAGE_SIZE)
+#define TEST_BASE_SIZE SZ_2M
 #define TEST_SLOT  10
 
+/* Storage of test info to share with guest code */
+struct test_config {
+   int page_size;
+   uint64_t test_size;
+   uint64_t test_num_pages;
+};
+
+struct test_config test_config;
+
 static void guest_code(uint64_t base_gpa)
 {
volatile uint64_t val __used;
+   struct test_config *config = &test_config;
int i;
 
-   for (i = 0; i < TEST_NPAGES; i++) {
-   uint64_t *src = (uint64_t *)(base_gpa + i * PAGE_SIZE);
+   for (i = 0; i < config->test_num_pages; i++) {
+   uint64_t *src = (uint64_t *)(base_gpa + i * config->page_size);
 
val = *src;
}
@@ -159,11 +169,17 @@ static void pre_fault_memory(struct kvm_vcpu *vcpu, u64 
base_gpa, u64 offset,
  KVM_PRE_FAULT_MEMORY, ret, vcpu->vm);
 }
 
-static void __test_pre_fault_memory(unsigned long vm_type, bool private)
+struct test_params {
+   unsigned long vm_type;
+   bool private;
+};
+
+static void __test_pre_fault_memory(enum vm_guest_mode guest_mode, void *arg)
 {
+   struct test_params *p = arg;
const struct vm_shape shape = {
-   .mode = VM_MODE_DEFAULT,
-   .type = vm_type,
+   .mode = guest_mode,
+   .type = p->vm_type,
};
struct kvm_vcpu *vcpu;
struct kvm_run *run;
@@ -174,10 +190,17 @@ static void __test_pre_fault_memory(unsigned long 
vm_type, bool private)
uint64_t guest_test_virt_mem;
uint64_t alignment, guest_page_size;
 
+   pr_info("Testing guest mode: %s\n", vm_guest_mode_string(guest_mode));
+
vm = vm_create_shape_with_one_vcpu(shape, &vcpu, guest_code);
 
-   alignment = guest_page_size = 
vm_guest_mode_params[VM_MODE_DEFAULT].page_size;
-   guest_test_phys_mem = (vm->max_gfn - TEST_NPAGES) * guest_page_size;
+   guest_page_size = vm_guest_mode_params[guest_mode].page_size;
+
+   test_config.page_size = guest_page_size;
+   test_config.test_size = TEST_BASE_SIZE + test_config.page_size;
+   test_config.test_num_pages = vm_calc_num_guest_pages(vm->mode, 
test_config.test_size);
+
+   guest_test_phys_mem = (vm->max_gfn - test_config.test_num_pages) * 
test_config.page_size;
 #ifdef __s390x__
alignment = max(0x10UL, guest_page_size);
 #else
@@ -187,23 +210,31 @@ static void __test_pre_fault_memory(unsigned long 
vm_type, bool private)
guest_test_virt_mem = guest_test_phys_mem & ((1ULL << (vm->va_bits - 
1)) - 1);
 
vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,
-   guest_test_phys_mem, TEST_SLOT, TEST_NPAGES,
-   private ? KVM_MEM_GUEST_MEMFD : 0);
-   virt_map(vm, guest_test_virt_mem, guest_test_phys_mem, TEST_NPAGES);
+   guest_test_phys_mem, TEST_SLOT, 
test_config.test_num_pages,
+   p->private ? KVM_MEM_GUEST_MEMFD : 0);
+   virt_map(vm, guest_test_virt_mem, guest_test_phys_mem, 
test_config.test_num_pages);
+
+   if (p->private)
+   vm_mem_set_private(vm, guest_test_phys_mem, 
test_config.test_size);
+   pre_fault_memory(vcpu, guest_test_phys_mem, TEST_BASE_SIZE, 0, 
p->private);
+   /* Test pre-faulting over an already faulted range */
+   pre_fault_memory(vcpu, guest_test_phys_mem, T