The pthread_attr_setaffinity_np function is a GNU extension that may not be available in non-glibc C libraries. Some KVM selftests use this function for CPU affinity control.
Add a function declaration and weak stub implementation for non-glibc builds. This allows tests to build, with the affinity setting being a no-op and errno set for the caller when the actual function is not available.
Signed-off-by: Aqib Faruqui aqibaf@amazon.com --- tools/testing/selftests/kvm/include/kvm_util.h | 4 ++++ tools/testing/selftests/kvm/lib/kvm_util.c | 11 +++++++++++ 2 files changed, 15 insertions(+)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index 7fae7f5e7..8177178b5 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -31,6 +31,10 @@ #include "kvm_util_types.h" #include "sparsebit.h"
+#ifndef __GLIBC__ +int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset); +#endif /* __GLIBC__ */ + #define KVM_DEV_PATH "/dev/kvm" #define KVM_MAX_VCPUS 512
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index c3f5142b0..5ce80303d 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -20,6 +20,17 @@
#define KVM_UTIL_MIN_PFN 2
+#ifndef __GLIBC__ +int __attribute__((weak)) +pthread_attr_setaffinity_np(pthread_attr_t *__attr, + size_t __cpusetsize, + const cpu_set_t *__cpuset) +{ + errno = ENOSYS; + return -1; +} +#endif + uint32_t guest_random_seed; struct guest_random_state guest_rng; static uint32_t last_guest_seed;
On Fri, Aug 29, 2025, Aqib Faruqui wrote:
The pthread_attr_setaffinity_np function is a GNU extension that may not be available in non-glibc C libraries. Some KVM selftests use this function for CPU affinity control.
Add a function declaration and weak stub implementation for non-glibc builds. This allows tests to build, with the affinity setting being a no-op and errno set for the caller when the actual function is not available.
Except this isn't a fallback, for all intents and purposes it silently breaks the test. A "fallback" is generally something that provides roughly equivalent functionality. This particular test will still pass because forced preemption isn't strictly necessary, but this is still gross.
Luckily, KVM selftests already provides APIs to pin tasks, just use those and the problem naturally goes away.
-- From: Sean Christopherson seanjc@google.com Date: Fri, 29 Aug 2025 15:31:44 -0700 Subject: [PATCH] KVM: selftests: Use KVM's task pinning APIs in steal_time time
Use pin_self_to_cpu() and pin_task_to_cpu() to pin the vCPU thread and the stealer thread to pCPU0 in the steal_time. Eliminating the usage of pthread_attr_setaffinity_np() in particular allows building the test again non-glibc C libraries.
Reported-by: Aqib Faruqui aqibaf@amazon.com Signed-off-by: Sean Christopherson seanjc@google.com --- tools/testing/selftests/kvm/steal_time.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c index cce2520af720..663c99c81703 100644 --- a/tools/testing/selftests/kvm/steal_time.c +++ b/tools/testing/selftests/kvm/steal_time.c @@ -341,9 +341,7 @@ int main(int ac, char **av) { struct kvm_vcpu *vcpus[NR_VCPUS]; struct kvm_vm *vm; - pthread_attr_t attr; pthread_t thread; - cpu_set_t cpuset; unsigned int gpages; long stolen_time; long run_delay; @@ -353,11 +351,7 @@ int main(int ac, char **av) verbose = ac > 1 && (!strncmp(av[1], "-v", 3) || !strncmp(av[1], "--verbose", 10));
/* Set CPU affinity so we can force preemption of the VCPU */ - CPU_ZERO(&cpuset); - CPU_SET(0, &cpuset); - pthread_attr_init(&attr); - pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset); - pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + pin_self_to_cpu(0);
/* Create a VM and an identity mapped memslot for the steal time structure */ vm = vm_create_with_vcpus(NR_VCPUS, guest_code, vcpus); @@ -389,7 +383,9 @@ int main(int ac, char **av)
/* Steal time from the VCPU. The steal time thread has the same CPU affinity as the VCPUs. */ run_delay = get_run_delay(); - pthread_create(&thread, &attr, do_steal_time, NULL); + pthread_create(&thread, NULL, do_steal_time, NULL); + pin_task_to_cpu(thread, 0); + do sched_yield(); while (get_run_delay() - run_delay < MIN_RUN_DELAY_NS);
base-commit: ecbcc2461839e848970468b44db32282e5059925 --
linux-kselftest-mirror@lists.linaro.org