[PATCH 6/7] KVM: selftests: Automatically run xAPIC IPI migration test when possible
From: Sean Christopherson
Date: Wed Sep 02 2026 - 20:22:15 EST
Rework the interface to the xAPIC IPI test to automatically run the
migration testcase if at least two NUMA nodes are found. The test exists
specifically to validate KVM's handling of migration of the APIC backing
page, i.e. forcing end users to opt-in to running the test in migration
mode largely defeats the purpose of the test.
Run both the "sleeping" and "migration" testcases by default, e.g. so that
the more basic testcase will fail if KVM completely breaks IPI delivery.
Keep the -m / migration parameter so that infrastructure that wants to
specifically test the migration case can do so and not get false passes.
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
.../selftests/kvm/x86/xapic_ipi_test.c | 40 +++++++++++++------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c
index 42c601617f5a..c5b506eb5e7f 100644
--- a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c
+++ b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c
@@ -245,14 +245,13 @@ void do_migrations(struct test_data_page *data, int run_secs, int delay_usecs,
delay_usecs);
nodes = kvm_get_numa_memory_nodes(&nodemask);
+ TEST_ASSERT(nodes > 1,
+ "NUMA nodes disappeared? nodemask = 0x%lx", nodemask);
fprintf(stderr, "Numa nodes found amongst first %lu possible nodes "
"(each 1-bit indicates node is present): %#lx\n",
BITS_PER_TYPE(nodemask), nodemask);
- TEST_ASSERT(nodes > 1,
- "Did not find at least 2 numa nodes. Can't do migration");
-
fprintf(stderr, "Migrating amongst %d nodes found\n", nodes);
from = kvm_get_next_numa_node(nodemask, -1);
@@ -351,26 +350,17 @@ void get_cmdline_args(int argc, char *argv[], int *run_secs,
}
}
-int main(int argc, char *argv[])
+static void test_xapic_ipi(int run_secs, int delay_usecs, bool migrate)
{
int wait_secs;
const int max_halter_wait = 10;
- int run_secs = 0;
- int delay_usecs = 0;
struct test_data_page *data;
gva_t test_data_page_gva;
- bool migrate = false;
pthread_t threads[2];
struct thread_params params[2];
struct kvm_vm *vm;
u64 *pipis_rcvd;
- get_cmdline_args(argc, argv, &run_secs, &migrate, &delay_usecs);
- if (run_secs <= 0)
- run_secs = DEFAULT_RUN_SECS;
- if (delay_usecs <= 0)
- delay_usecs = DEFAULT_DELAY_USECS;
-
vm = vm_create_with_one_vcpu(¶ms[0].vcpu, halter_guest_code);
vm_install_exception_handler(vm, IPI_VECTOR, guest_ipi_handler);
@@ -458,5 +448,29 @@ int main(int argc, char *argv[])
kvm_vm_free(vm);
+}
+
+int main(int argc, char *argv[])
+{
+ bool force_migrate = false;
+ unsigned long nodemask;
+ int run_secs = 0;
+ int delay_usecs = 0;
+
+ get_cmdline_args(argc, argv, &run_secs, &force_migrate, &delay_usecs);
+ if (run_secs <= 0)
+ run_secs = DEFAULT_RUN_SECS;
+ if (delay_usecs <= 0)
+ delay_usecs = DEFAULT_DELAY_USECS;
+
+ if (!force_migrate)
+ test_xapic_ipi(run_secs, delay_usecs, false);
+
+ if (kvm_get_numa_memory_nodes(&nodemask) > 1)
+ test_xapic_ipi(run_secs, delay_usecs, true);
+ else
+ TEST_ASSERT(!force_migrate,
+ "Did not find at least 2 numa nodes. Can't do migration");
+
return 0;
}
--
2.55.0.970.g62bdec98f9-goog