KVM: selftests: Verify KVM preserves userspace writes to "durable" MSRs
authorSean Christopherson <seanjc@google.com>
Sat, 11 Mar 2023 00:46:09 +0000 (16:46 -0800)
committerSean Christopherson <seanjc@google.com>
Thu, 6 Apr 2023 21:58:44 +0000 (14:58 -0700)
Assert that KVM provides "read what you wrote" semantics for all "durable"
MSRs (for lack of a better name).  The extra coverage is cheap from a
runtime performance perspective, and verifying the behavior in the common
helper avoids gratuitous copy+paste in individual tests.

Note, this affects all tests that set MSRs from userspace!

Link: https://lore.kernel.org/r/20230311004618.920745-13-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
tools/testing/selftests/kvm/include/x86_64/processor.h

index 293a9085311d0aba32c105d96c30f43c3a88d793..e1d65d933310d5021a875fea098d3b2c485b12e0 100644 (file)
@@ -945,12 +945,27 @@ do {                                                                              \
        }                                                                       \
 } while (0)
 
+/*
+ * Returns true if KVM should return the last written value when reading an MSR
+ * from userspace, e.g. the MSR isn't a command MSR, doesn't emulate state that
+ * is changing, etc.  This is NOT an exhaustive list!  The intent is to filter
+ * out MSRs that are not durable _and_ that a selftest wants to write.
+ */
+static inline bool is_durable_msr(uint32_t msr)
+{
+       return msr != MSR_IA32_TSC;
+}
+
 #define vcpu_set_msr(vcpu, msr, val)                                                   \
 do {                                                                                   \
-       uint64_t v = val;                                                               \
+       uint64_t r, v = val;                                                            \
                                                                                        \
        TEST_ASSERT_MSR(_vcpu_set_msr(vcpu, msr, v) == 1,                               \
                        "KVM_SET_MSRS failed on %s, value = 0x%lx", msr, #msr, v);      \
+       if (!is_durable_msr(msr))                                                       \
+               break;                                                                  \
+       r = vcpu_get_msr(vcpu, msr);                                                    \
+       TEST_ASSERT_MSR(r == v, "Set %s to '0x%lx', got back '0x%lx'", msr, #msr, v, r);\
 } while (0)
 
 void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits);