Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+21
+21
tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
··· 5 5 #include <stdbool.h> 6 6 #include <stdint.h> 7 7 8 + #include "test_util.h" 9 + 8 10 extern bool is_forced_emulation_enabled; 9 11 10 12 struct kvm_vm_arch { ··· 23 21 24 22 #define vm_arch_has_protected_memory(vm) \ 25 23 __vm_arch_has_protected_memory(&(vm)->arch) 24 + 25 + #define vcpu_arch_put_guest(mem, __val) \ 26 + do { \ 27 + const typeof(mem) val = (__val); \ 28 + \ 29 + if (!is_forced_emulation_enabled || guest_random_bool(&guest_rng)) { \ 30 + (mem) = val; \ 31 + } else if (guest_random_bool(&guest_rng)) { \ 32 + __asm__ __volatile__(KVM_FEP "mov %1, %0" \ 33 + : "+m" (mem) \ 34 + : "r" (val) : "memory"); \ 35 + } else { \ 36 + uint64_t __old = READ_ONCE(mem); \ 37 + \ 38 + __asm__ __volatile__(KVM_FEP LOCK_PREFIX "cmpxchg %[new], %[ptr]" \ 39 + : [ptr] "+m" (mem), [old] "+a" (__old) \ 40 + : [new]"r" (val) : "memory", "cc"); \ 41 + } \ 42 + } while (0) 26 43 27 44 #endif // SELFTEST_KVM_UTIL_ARCH_H