From: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx> According to TDX Module 1.5 ABI Sepc, Table 2.1 MSR Virtualization, the following modifications are made in MSRs test. 1. Skip sub-tests about MSR_IA32_MISC_ENABLE and MSR_CSTAR, since changing those MSRs are unsupported: - MSR_IA32_MISC_ENABLE is reading native and #VE in writing. - MSR_CSTAR is #VE in reading/writing and its simulation is not supported in TDX host side. 2. Skip the x2apic-msrs test in x2apic disabled mode. The TDX guest only supports X2APIC, and cannot disable APIC. 3. Add readable flag for x2apic MSRs if TDX guest. There is a gap between VMX and TDX about read registers in the virtual APIC page. KVM will intercept reads to non-existent MSRs[1], the TDX doesn't validate it and directly reads **native**. So add a readable flag for x2apic MSRs if TDX guest to avoid #GP checking for RDMSR. 4. Add #VE check for MSR operation fault. For some MSRs, e.g., MCE-related MSR, they are virtualized by #VE in tdx. The exception of invalid RDMSR/WRMSR for it is #VE instead of #GP, so correct it in the test_rdmsr_fault() and test_wrmsr_fault(). [1] KVM: VMX: Always intercept accesses to unsupported "extended" x2APIC regs, https://lore.kernel.org/r/20230107011025.565472-6-seanjc@xxxxxxxxxx Signed-off-by: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx> Reviewed-by: Yu Zhang <yu.c.zhang@xxxxxxxxx> Link: https://lore.kernel.org/r/20220303071907.650203-16-zhenzhong.duan@xxxxxxxxx Co-developed-by: Qian Wen <qian.wen@xxxxxxxxx> Signed-off-by: Qian Wen <qian.wen@xxxxxxxxx> --- x86/msr.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/x86/msr.c b/x86/msr.c index 3a041fab..b1392487 100644 --- a/x86/msr.c +++ b/x86/msr.c @@ -5,6 +5,7 @@ #include "processor.h" #include "msr.h" #include <stdlib.h> +#include "tdx.h" /* * This test allows two modes: @@ -97,9 +98,11 @@ static void test_wrmsr(u32 msr, const char *name, unsigned long long val) static void test_wrmsr_fault(u32 msr, const char *name, unsigned long long val) { unsigned char vector = wrmsr_safe(msr, val); - - report(vector == GP_VECTOR, - "Expected #GP on WRSMR(%s, 0x%llx), got vector %d", + bool pass = false; + if (vector == GP_VECTOR || (vector == VE_VECTOR && is_tdx_guest())) + pass = true; + report(pass, + "Expected #GP/#VE on WRSMR(%s, 0x%llx), got vector %d", name, val, vector); } @@ -107,13 +110,20 @@ static void test_rdmsr_fault(u32 msr, const char *name) { uint64_t ignored; unsigned char vector = rdmsr_safe(msr, &ignored); - - report(vector == GP_VECTOR, - "Expected #GP on RDSMR(%s), got vector %d", name, vector); + bool pass = false; + if (vector == GP_VECTOR || (vector == VE_VECTOR && is_tdx_guest())) + pass = true; + report(pass, + "Expected #GP/#VE on RDSMR(%s), got vector %d", name, vector); } static void test_msr(struct msr_info *msr, bool is_64bit_host) { + /* Changing MSR_IA32_MISC_ENABLE and MSR_CSTAR is unsupported in TDX */ + if ((msr->index == MSR_IA32_MISC_ENABLE || msr->index == MSR_CSTAR) && + is_tdx_guest()) + return; + if (is_64bit_host || !msr->is_64bit_only) { __test_msr_rw(msr->index, msr->name, msr->value, msr->keep); @@ -223,6 +233,24 @@ static void test_mce_msrs(void) } } +static enum x2apic_reg_semantics get_x2apic_reg_semantics2(u32 reg) +{ + enum x2apic_reg_semantics ret; + ret = get_x2apic_reg_semantics(reg); + + if (is_tdx_guest()) { + switch (reg) { + case APIC_ARBPRI: + case APIC_EOI: + case APIC_RRR: + case APIC_DFR: + case APIC_SELF_IPI: + ret |= X2APIC_RO; + } + } + return ret; +} + static void __test_x2apic_msrs(bool x2apic_enabled) { enum x2apic_reg_semantics semantics; @@ -234,7 +262,7 @@ static void __test_x2apic_msrs(bool x2apic_enabled) snprintf(msr_name, sizeof(msr_name), "x2APIC MSR 0x%x", index); if (x2apic_enabled) - semantics = get_x2apic_reg_semantics(i); + semantics = get_x2apic_reg_semantics2(i); else semantics = X2APIC_INVALID; @@ -270,13 +298,15 @@ static void __test_x2apic_msrs(bool x2apic_enabled) static void test_x2apic_msrs(void) { + if (is_tdx_guest()) + goto test_x2apic; reset_apic(); __test_x2apic_msrs(false); if (!enable_x2apic()) return; - +test_x2apic: __test_x2apic_msrs(true); } -- 2.25.1