From: Jinrong Liang <ljr.kernel@gmail.com>
To: Sean Christopherson <seanjc@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Wanpeng Li <wanpengli@tencent.com>,
Like Xu <like.xu.linux@gmail.com>,
Jinrong Liang <cloudliang@tencent.com>,
linux-kselftest@vger.kernel.org, kvm@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 1/2] KVM: selftests: Test consistency of setting MSR_IA32_DS_AREA
Date: Thu, 8 Jun 2023 19:34:19 +0800 [thread overview]
Message-ID: <20230608113420.14695-2-cloudliang@tencent.com> (raw)
In-Reply-To: <20230608113420.14695-1-cloudliang@tencent.com>
From: Jinrong Liang <cloudliang@tencent.com>
Tests have been added to this commit to check if setting
MSR_IA32_DS_AREA with a non-classical address causes a fault. By
verifying that KVM is correctly faulting non-classical addresses
in MSR_IA32_DS_AREA, it helps ensure the accuracy and stability
of the KVM subsystem.
Signed-off-by: Jinrong Liang <cloudliang@tencent.com>
---
.../selftests/kvm/x86_64/vmx_pmu_caps_test.c | 100 ++++++++++++++++++
1 file changed, 100 insertions(+)
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c
index 4c90f76930f9..02903084598f 100644
--- a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c
+++ b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c
@@ -19,6 +19,9 @@
#include "kvm_util.h"
#include "vmx.h"
+#define MAX_LINEAR_ADDR_MASK GENMASK_ULL(15, 8)
+#define ADDR_OFS_BIT 8
+
union perf_capabilities {
struct {
u64 lbr_format:6;
@@ -232,6 +235,102 @@ static void test_lbr_perf_capabilities(union perf_capabilities host_cap)
kvm_vm_free(vm);
}
+/*
+ * Generate a non-canonical address for a given number of address bits.
+ * @addr_bits: The number of address bits used in the system.
+ *
+ * This function calculates a non-canonical address by setting the most
+ * significant bit to 1 and adding an offset equal to the maximum value
+ * that can be represented by the remaining bits. This ensures that the
+ * generated address is outside the valid address range and is consistent.
+ */
+static inline uint64_t non_canonical_address(unsigned int addr_bits)
+{
+ return (1ULL << (addr_bits - 1)) + ((1ULL << (addr_bits - 1)) - 1);
+}
+
+static uint64_t get_addr_bits(struct kvm_vcpu *vcpu)
+{
+ const struct kvm_cpuid_entry2 *kvm_entry;
+ unsigned int addr_bits;
+ struct kvm_sregs sregs;
+
+ kvm_entry = get_cpuid_entry(kvm_get_supported_cpuid(), 0x80000008, 0);
+ addr_bits = (kvm_entry->eax & MAX_LINEAR_ADDR_MASK) >> ADDR_OFS_BIT;
+ /*
+ * Get the size of the virtual address space by checking the LA57 bit
+ * in the CR4 control register. If the LA57 bit is set, then the virtual
+ * address space is 57 bits. Otherwise, it's 48 bits.
+ */
+ if (addr_bits != 32) {
+ vcpu_sregs_get(vcpu, &sregs);
+ addr_bits = (sregs.cr4 & X86_CR4_LA57) ? 57 : 48;
+ }
+
+ return addr_bits;
+}
+
+static void test_ds_guest_code(uint64_t bad_addr)
+{
+ uint8_t vector = 0;
+
+ vector = wrmsr_safe(MSR_IA32_DS_AREA, bad_addr);
+ GUEST_SYNC(vector);
+}
+
+/* Check if setting MSR_IA32_DS_AREA in guest and kvm userspace will fail. */
+static void test_ds_area_noncanonical_address(union perf_capabilities host_cap)
+{
+ struct kvm_vm *vm;
+ struct kvm_vcpu *vcpu;
+ unsigned int r, addr_bits;
+ uint64_t bad_addr, without_pebs_fmt_caps;
+ struct ucall uc;
+
+ vm = vm_create_with_one_vcpu(&vcpu, test_ds_guest_code);
+ vm_init_descriptor_tables(vm);
+ vcpu_init_descriptor_tables(vcpu);
+
+ /* Check that Setting MSR_IA32_DS_AREA with 0 should succeed. */
+ r = _vcpu_set_msr(vcpu, MSR_IA32_DS_AREA, 0);
+ TEST_ASSERT(r, "Setting MSR_IA32_DS_AREA with 0 should succeed.");
+
+ /*
+ * Check that if PEBS_FMT is not set setting MSR_IA32_DS_AREA will
+ * succeed.
+ */
+ without_pebs_fmt_caps = host_cap.capabilities & ~PERF_CAP_PEBS_FORMAT;
+ vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, without_pebs_fmt_caps);
+ r = _vcpu_set_msr(vcpu, MSR_IA32_DS_AREA, 1);
+ TEST_ASSERT(r, "Setting MSR_IA32_DS_AREA with bad addr should fail.");
+
+ /*
+ * Check that setting MSR_IA32_DS_AREA in kvm userspace to use a
+ * non-canonical address should fail.
+ */
+ vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.capabilities);
+ addr_bits = get_addr_bits(vcpu);
+ bad_addr = non_canonical_address(addr_bits);
+ r = _vcpu_set_msr(vcpu, MSR_IA32_DS_AREA, bad_addr);
+ TEST_ASSERT(!r, "Setting MSR_IA32_DS_AREA with bad addr should fail.");
+
+ /*
+ * Check that setting MSR_IA32_DS_AREA in guest to use a non-canonical
+ * address should cause the #GP.
+ */
+ vcpu_args_set(vcpu, 1, bad_addr);
+ vcpu_run(vcpu);
+
+ TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
+ get_ucall(vcpu, &uc);
+ TEST_ASSERT(uc.cmd == UCALL_SYNC,
+ "Received ucall other than UCALL_SYNC: %lu", uc.cmd);
+ TEST_ASSERT(uc.args[1] == GP_VECTOR,
+ "Setting MSR_IA32_DS_AREA with bad addr should fail.");
+
+ kvm_vm_free(vm);
+}
+
int main(int argc, char *argv[])
{
union perf_capabilities host_cap;
@@ -252,4 +351,5 @@ int main(int argc, char *argv[])
test_immutable_perf_capabilities(host_cap);
test_guest_wrmsr_perf_capabilities(host_cap);
test_lbr_perf_capabilities(host_cap);
+ test_ds_area_noncanonical_address(host_cap);
}
--
2.31.1
next prev parent reply other threads:[~2023-06-08 11:34 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-08 11:34 [PATCH 0/2] KVM: selftests: Add tests for PEBS and MSR_IA32_DS_AREA Jinrong Liang
2023-06-08 11:34 ` Jinrong Liang [this message]
2023-06-28 21:48 ` [PATCH 1/2] KVM: selftests: Test consistency of setting MSR_IA32_DS_AREA Sean Christopherson
2023-06-08 11:34 ` [PATCH 2/2] KVM: selftests: Add PEBS test for MSR_IA32_PERF_CAPABILITIES Jinrong Liang
2023-06-28 21:55 ` Sean Christopherson
2023-06-30 8:59 ` Jinrong Liang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230608113420.14695-2-cloudliang@tencent.com \
--to=ljr.kernel@gmail.com \
--cc=cloudliang@tencent.com \
--cc=kvm@vger.kernel.org \
--cc=like.xu.linux@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=wanpengli@tencent.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox