All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chao Gao <chao.gao@intel.com>
To: kvm@vger.kernel.org
Cc: Jiaan Lu <jiaan.lu@intel.com>, Chao Gao <chao.gao@intel.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Shuah Khan <shuah@kernel.org>,
	Arnaldo Carvalho de Melo <acme@redhat.com>,
	Borislav Petkov <bp@suse.de>,
	Pawan Gupta <pawan.kumar.gupta@linux.intel.com>,
	Zhang Chen <chen.zhang@intel.com>,
	Daniel Sneddon <daniel.sneddon@linux.intel.com>,
	linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: [RFC PATCH v2 10/11] KVM: selftests: Add tests for virtual enumeration/mitigation MSRs
Date: Fri, 14 Apr 2023 14:25:31 +0800	[thread overview]
Message-ID: <20230414062545.270178-11-chao.gao@intel.com> (raw)
In-Reply-To: <20230414062545.270178-1-chao.gao@intel.com>

Three virtual MSRs added for guest to report the usage of software
mitigations. They are enumerated in an architectural way. Try to
access the three MSRs to ensure the behavior is expected:
Specifically,

1. below three cases should cause #GP:
 * access to a non-present MSR
 * write to read-only MSRs
 * toggling reserved bit of a writeable MSR

2. rdmsr/wrmsr in other cases should succeed

3. rdmsr should return the value last written

Signed-off-by: Chao Gao <chao.gao@intel.com>
---
 tools/arch/x86/include/asm/msr-index.h        |  23 +++
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../kvm/x86_64/virtual_mitigation_msr_test.c  | 175 ++++++++++++++++++
 3 files changed, 199 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/x86_64/virtual_mitigation_msr_test.c

diff --git a/tools/arch/x86/include/asm/msr-index.h b/tools/arch/x86/include/asm/msr-index.h
index 6079a5fdb40b..55f75e9ebbb7 100644
--- a/tools/arch/x86/include/asm/msr-index.h
+++ b/tools/arch/x86/include/asm/msr-index.h
@@ -166,6 +166,7 @@
 						 * IA32_XAPIC_DISABLE_STATUS MSR
 						 * supported
 						 */
+#define ARCH_CAP_VIRTUAL_ENUM		BIT_ULL(63) /* MSR_VIRTUAL_ENUMERATION supported */
 
 #define MSR_IA32_FLUSH_CMD		0x0000010b
 #define L1D_FLUSH			BIT(0)	/*
@@ -1103,6 +1104,28 @@
 #define MSR_IA32_VMX_MISC_INTEL_PT                 (1ULL << 14)
 #define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29)
 #define MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE   0x1F
+
+/* Intel virtual MSRs */
+#define MSR_VIRTUAL_ENUMERATION			0x50000000
+#define VIRT_ENUM_MITIGATION_CTRL_SUPPORT	BIT(0)  /*
+							 * Mitigation ctrl via virtual
+							 * MSRs supported
+							 */
+
+#define MSR_VIRTUAL_MITIGATION_ENUM		0x50000001
+#define MITI_ENUM_BHB_CLEAR_SEQ_S_SUPPORT	BIT(0)	/* VMM supports BHI_DIS_S */
+#define MITI_ENUM_RETPOLINE_S_SUPPORT		BIT(1)	/* VMM supports RRSBA_DIS_S */
+
+#define MSR_VIRTUAL_MITIGATION_CTRL		0x50000002
+#define MITI_CTRL_BHB_CLEAR_SEQ_S_USED		BIT(0)	/*
+							 * Request VMM to deploy
+							 * BHI_DIS_S mitigation
+							 */
+#define MITI_CTRL_RETPOLINE_S_USED		BIT(1)	/*
+							 * Request VMM to deploy
+							 * RRSBA_DIS_S mitigation
+							 */
+
 /* AMD-V MSRs */
 
 #define MSR_VM_CR                       0xc0010114
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 84a627c43795..9db9a7e49a54 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -115,6 +115,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests
 TEST_GEN_PROGS_x86_64 += x86_64/amx_test
 TEST_GEN_PROGS_x86_64 += x86_64/max_vcpuid_cap_test
 TEST_GEN_PROGS_x86_64 += x86_64/triple_fault_event_test
+TEST_GEN_PROGS_x86_64 += x86_64/virtual_mitigation_msr_test
 TEST_GEN_PROGS_x86_64 += access_tracking_perf_test
 TEST_GEN_PROGS_x86_64 += demand_paging_test
 TEST_GEN_PROGS_x86_64 += dirty_log_test
diff --git a/tools/testing/selftests/kvm/x86_64/virtual_mitigation_msr_test.c b/tools/testing/selftests/kvm/x86_64/virtual_mitigation_msr_test.c
new file mode 100644
index 000000000000..4d924a0cf2dd
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86_64/virtual_mitigation_msr_test.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, Intel, Inc.
+ *
+ * tests for virtual mitigation MSR accesses
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "test_util.h"
+
+#include "kvm_util.h"
+#include "processor.h"
+
+static int guest_exception_count;
+static int expected_exception_count;
+static void guest_gp_handler(struct ex_regs *regs)
+{
+	/* RDMSR/WRMSR are 2 bytes */
+	regs->rip += 2;
+	++guest_exception_count;
+}
+
+static void write_msr_expect_gp(uint32_t msr, uint64_t val)
+{
+	uint64_t old_val;
+
+	old_val = rdmsr(msr);
+	wrmsr(msr, val);
+	expected_exception_count++;
+	GUEST_ASSERT_2(guest_exception_count == expected_exception_count,
+		       guest_exception_count, expected_exception_count);
+	GUEST_ASSERT_2(rdmsr(msr) == old_val, rdmsr(msr), old_val);
+}
+
+static void write_msr_expect_no_gp(uint32_t msr, uint64_t val)
+{
+	wrmsr(msr, val);
+	GUEST_ASSERT_EQ(guest_exception_count, expected_exception_count);
+	GUEST_ASSERT_EQ(rdmsr(msr), val);
+}
+
+static void read_msr_expect_gp(uint32_t msr)
+{
+	(void)rdmsr(msr);
+	expected_exception_count++;
+	GUEST_ASSERT_2(guest_exception_count == expected_exception_count,
+		       guest_exception_count, expected_exception_count);
+}
+
+static void guest_code_with_virtual_mitigation_ctrl(void)
+{
+	uint64_t val, miti_ctrl = 0;
+	int i;
+
+	val = rdmsr(MSR_VIRTUAL_ENUMERATION);
+	/* MSR_VIRTUAL_ENUMERATION is read-only. #GP is expected on write */
+	write_msr_expect_gp(MSR_VIRTUAL_ENUMERATION, val);
+
+	val = rdmsr(MSR_VIRTUAL_MITIGATION_ENUM);
+	/* MSR_VIRTUAL_MITIGATION_ENUM is read-only. #GP is expected on write */
+	write_msr_expect_gp(MSR_VIRTUAL_MITIGATION_ENUM, val);
+
+	for (i = 0; i < 64; i++) {
+		if (val & BIT_ULL(i)) {
+			miti_ctrl |= BIT_ULL(i);
+			write_msr_expect_no_gp(MSR_VIRTUAL_MITIGATION_CTRL, miti_ctrl);
+		} else {
+			write_msr_expect_gp(MSR_VIRTUAL_MITIGATION_CTRL, miti_ctrl | BIT_ULL(i));
+		}
+	}
+
+	write_msr_expect_no_gp(MSR_VIRTUAL_MITIGATION_CTRL, 0);
+	GUEST_DONE();
+}
+
+static void guest_code_no_virtual_enumeration(void)
+{
+	read_msr_expect_gp(MSR_VIRTUAL_ENUMERATION);
+	read_msr_expect_gp(MSR_VIRTUAL_MITIGATION_ENUM);
+	read_msr_expect_gp(MSR_VIRTUAL_MITIGATION_CTRL);
+	GUEST_DONE();
+}
+
+bool kvm_cpu_has_virtual_mitigation_ctrl(void)
+{
+	const struct kvm_msr_list *feature_list;
+	u64 virt_enum = 0;
+	int i;
+
+	feature_list = kvm_get_feature_msr_index_list();
+	for (i = 0; i < feature_list->nmsrs; i++) {
+		if (feature_list->indices[i] == MSR_VIRTUAL_ENUMERATION)
+			virt_enum = kvm_get_feature_msr(MSR_VIRTUAL_ENUMERATION);
+	}
+
+	return virt_enum & VIRT_ENUM_MITIGATION_CTRL_SUPPORT;
+}
+
+static void enable_virtual_mitigation_ctrl(struct kvm_vcpu *vcpu)
+{
+	vcpu_set_msr(vcpu, MSR_IA32_ARCH_CAPABILITIES, ARCH_CAP_VIRTUAL_ENUM);
+	vcpu_set_msr(vcpu, MSR_VIRTUAL_ENUMERATION, VIRT_ENUM_MITIGATION_CTRL_SUPPORT);
+	vcpu_set_msr(vcpu, MSR_VIRTUAL_MITIGATION_ENUM,
+		     kvm_get_feature_msr(MSR_VIRTUAL_MITIGATION_ENUM));
+}
+
+static void disable_virtual_enumeration(struct kvm_vcpu *vcpu)
+{
+	vcpu_set_msr(vcpu, MSR_IA32_ARCH_CAPABILITIES, 0);
+}
+
+static void test_virtual_mitiation_ctrl(bool enable)
+{
+	struct kvm_vcpu *vcpu;
+	struct kvm_run *run;
+	struct kvm_vm *vm;
+	struct ucall uc;
+	void *guest_code;
+
+	guest_code = enable ? guest_code_with_virtual_mitigation_ctrl :
+			      guest_code_no_virtual_enumeration;
+
+	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
+	run = vcpu->run;
+
+	if (enable)
+		enable_virtual_mitigation_ctrl(vcpu);
+	else
+		disable_virtual_enumeration(vcpu);
+
+
+	/* Register #GP handler */
+	vm_init_descriptor_tables(vm);
+	vcpu_init_descriptor_tables(vcpu);
+	vm_install_exception_handler(vm, GP_VECTOR, guest_gp_handler);
+
+	while (1) {
+		vcpu_run(vcpu);
+
+		TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
+			    "Unexpected exit reason: %u (%s),\n",
+			    run->exit_reason,
+			    exit_reason_str(run->exit_reason));
+
+		switch (get_ucall(vcpu, &uc)) {
+		case UCALL_ABORT:
+			REPORT_GUEST_ASSERT_2(uc, "real %ld expected %ld");
+			break;
+		case UCALL_DONE:
+			goto done;
+		default:
+			TEST_FAIL("Unknown ucall %lu", uc.cmd);
+		}
+	}
+
+done:
+	kvm_vm_free(vm);
+}
+
+int main(int argc, char *argv[])
+{
+	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_ARCH_CAPABILITIES));
+	TEST_REQUIRE(kvm_has_cap(KVM_CAP_GET_MSR_FEATURES));
+	TEST_REQUIRE(kvm_cpu_has_virtual_mitigation_ctrl());
+
+	test_virtual_mitiation_ctrl(true);
+	test_virtual_mitiation_ctrl(false);
+
+	return 0;
+}
-- 
2.40.0


  parent reply	other threads:[~2023-04-14  6:30 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-14  6:25 [RFC PATCH v2 00/11] Intel IA32_SPEC_CTRL Virtualization Chao Gao
2023-04-14  6:25 ` [RFC PATCH v2 01/11] x86/msr-index: Add bit definitions for BHI_DIS_S and BHI_NO Chao Gao
2023-04-14  9:52   ` Binbin Wu
2023-04-14  6:25 ` [RFC PATCH v2 02/11] KVM: x86: Advertise CPUID.7.2.EDX and RRSBA_CTRL support Chao Gao
2023-04-16  7:04   ` Binbin Wu
2023-04-16 13:25     ` Chao Gao
2023-05-15  6:53   ` Xiaoyao Li
2023-05-16  2:04     ` Chao Gao
2023-05-16  2:22       ` Xiaoyao Li
2023-05-16  3:01         ` Chao Gao
2023-05-16  7:03           ` Xiaoyao Li
2023-05-16  9:09             ` Chao Gao
2023-05-18  9:50               ` Xiaoyao Li
2023-05-19  9:43                 ` Chao Gao
2023-04-14  6:25 ` [RFC PATCH v2 03/11] KVM: x86: Advertise BHI_CTRL support Chao Gao
2023-05-15  7:14   ` Xiaoyao Li
2023-04-14  6:25 ` [RFC PATCH v2 04/11] KVM: VMX: Add IA32_SPEC_CTRL virtualization support Chao Gao
2023-04-17  3:17   ` Binbin Wu
2023-04-18  2:07     ` Chao Gao
2023-04-17  6:48   ` Chenyi Qiang
2023-04-17  7:31     ` Chao Gao
2023-05-16  7:16   ` Xiaoyao Li
2023-05-16  9:20     ` Chao Gao
2023-04-14  6:25 ` [RFC PATCH v2 05/11] x86/bugs: Use Virtual MSRs to request hardware mitigations Chao Gao
2023-04-17 13:43   ` Binbin Wu
2023-04-18  2:01     ` Chao Gao
2023-04-14  6:25 ` [RFC PATCH v2 06/11] KVM: x86: Advertise ARCH_CAP_VIRTUAL_ENUM support Chao Gao
2023-05-18 10:14   ` Xiaoyao Li
2023-05-19  9:57     ` Chao Gao
2023-05-22  1:02       ` Xiaoyao Li
2023-04-14  6:25 ` [RFC PATCH v2 07/11] KVM: VMX: Advertise MITIGATION_CTRL support Chao Gao
2023-04-14  6:25 ` [RFC PATCH v2 08/11] KVM: VMX: Advertise MITI_ENUM_RETPOLINE_S_SUPPORT Chao Gao
2023-05-18 10:25   ` Xiaoyao Li
2023-05-19 10:26     ` Chao Gao
2023-05-22  9:43   ` Liu, Jingqi
2023-04-14  6:25 ` [RFC PATCH v2 09/11] KVM: VMX: Advertise MITI_CTRL_BHB_CLEAR_SEQ_S_SUPPORT Chao Gao
2023-05-22  9:41   ` Liu, Jingqi
2023-04-14  6:25 ` Chao Gao [this message]
2023-05-22  9:39   ` [RFC PATCH v2 10/11] KVM: selftests: Add tests for virtual enumeration/mitigation MSRs Liu, Jingqi
2023-04-14  6:25 ` [RFC PATCH v2 11/11] KVM: selftests: Add tests for IA32_SPEC_CTRL MSR Chao Gao
2023-04-14  9:51 ` [RFC PATCH v2 00/11] Intel IA32_SPEC_CTRL Virtualization Binbin Wu
2023-04-14 22:10   ` Pawan Gupta

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=20230414062545.270178-11-chao.gao@intel.com \
    --to=chao.gao@intel.com \
    --cc=acme@redhat.com \
    --cc=bp@suse.de \
    --cc=chen.zhang@intel.com \
    --cc=daniel.sneddon@linux.intel.com \
    --cc=jiaan.lu@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=pawan.kumar.gupta@linux.intel.com \
    --cc=pbonzini@redhat.com \
    --cc=shuah@kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.