]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
KVM: selftests: Randomly force emulation on x86 writes from guest code
authorSean Christopherson <seanjc@google.com>
Thu, 14 Mar 2024 18:54:58 +0000 (11:54 -0700)
committerSean Christopherson <seanjc@google.com>
Mon, 29 Apr 2024 19:50:43 +0000 (12:50 -0700)
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>
tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h

index 41aba476640a34a70e929643627835bb0b7b8d5d..d0b587c38e076542948f3d7d78017a2ba787f518 100644 (file)
@@ -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