diff options
author | Sean Christopherson <seanjc@google.com> | 2024-03-14 11:54:58 -0700 |
---|---|---|
committer | Sean Christopherson <seanjc@google.com> | 2024-04-29 12:50:43 -0700 |
commit | 87aa264cd89d068f2455fc6e240d4015f6234204 (patch) | |
tree | 670571dd49bd72e7c71cec76251c51f3790bcc26 | |
parent | 2f2bc6af6aa8cc07f84291d625f7113fd13d68e5 (diff) | |
download | linux-87aa264cd89d068f2455fc6e240d4015f6234204.tar.gz linux-87aa264cd89d068f2455fc6e240d4015f6234204.tar.bz2 linux-87aa264cd89d068f2455fc6e240d4015f6234204.zip |
KVM: selftests: Randomly force emulation on x86 writes from guest code
Override vcpu_arch_put_guest() to randomly force emulation on supported
accesses. Force emulation of LOCK CMPXCHG as well as a regular MOV to
stress KVM's emulation of atomic accesses, which has a unique path in
KVM's emulator.
Arbitrarily give all the decisions 50/50 odds; absent much, much more
sophisticated infrastructure for generating random numbers, it's highly
unlikely that doing more than a coin flip with affect selftests' ability
to find KVM bugs.
This is effectively a regression test for commit 910c57dfa4d1 ("KVM: x86:
Mark target gfn of emulated atomic instruction as dirty").
Link: https://lore.kernel.org/r/20240314185459.2439072-6-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
-rw-r--r-- | tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h index 41aba476640a..d0b587c38e07 100644 --- a/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h +++ b/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h @@ -5,6 +5,8 @@ #include <stdbool.h> #include <stdint.h> +#include "test_util.h" + extern bool is_forced_emulation_enabled; struct kvm_vm_arch { @@ -22,4 +24,23 @@ static inline bool __vm_arch_has_protected_memory(struct kvm_vm_arch *arch) #define vm_arch_has_protected_memory(vm) \ __vm_arch_has_protected_memory(&(vm)->arch) +#define vcpu_arch_put_guest(mem, __val) \ +do { \ + const typeof(mem) val = (__val); \ + \ + if (!is_forced_emulation_enabled || guest_random_bool(&guest_rng)) { \ + (mem) = val; \ + } else if (guest_random_bool(&guest_rng)) { \ + __asm__ __volatile__(KVM_FEP "mov %1, %0" \ + : "+m" (mem) \ + : "r" (val) : "memory"); \ + } else { \ + uint64_t __old = READ_ONCE(mem); \ + \ + __asm__ __volatile__(KVM_FEP LOCK_PREFIX "cmpxchg %[new], %[ptr]" \ + : [ptr] "+m" (mem), [old] "+a" (__old) \ + : [new]"r" (val) : "memory", "cc"); \ + } \ +} while (0) + #endif // SELFTEST_KVM_UTIL_ARCH_H |