diff mbox series

[RESEND,v13,09/11] KVM: VMX: Add VMCS dump and sanity check for CET states

Message ID 20200716031627.11492-10-weijiang.yang@intel.com (mailing list archive)
State New, archived
Headers show
Series Introduce support for guest CET feature | expand

Commit Message

Yang, Weijiang July 16, 2020, 3:16 a.m. UTC
Dump CET VMCS states for debug purpose. Since CET kernel protection is
not enabled, if related MSRs in host are filled by mistake, warn once on
detecting it.

Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/kvm/vmx/vmx.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

Comments

Sean Christopherson July 22, 2020, 9:29 p.m. UTC | #1
On Thu, Jul 16, 2020 at 11:16:25AM +0800, Yang Weijiang wrote:
> Dump CET VMCS states for debug purpose. Since CET kernel protection is
> not enabled, if related MSRs in host are filled by mistake, warn once on
> detecting it.

This all can be thrown into the enabling patch.  This isn't so much code that
it bloats the enabling patch, and the host MSRs being lost thing is confusing
without the context that KVM doesn't stuff them into the VMCS.

> 
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>  arch/x86/kvm/vmx/vmx.c | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index d465ff990094..5d4250b9dec8 100644

...

> @@ -8205,6 +8217,7 @@ static __init int hardware_setup(void)
>  	unsigned long host_bndcfgs;
>  	struct desc_ptr dt;
>  	int r, i, ept_lpage_level;
> +	u64 cet_msr;
>  
>  	store_idt(&dt);
>  	host_idt_base = dt.address;
> @@ -8365,6 +8378,16 @@ static __init int hardware_setup(void)
>  			return r;
>  	}
>  
> +	if (boot_cpu_has(X86_FEATURE_IBT) || boot_cpu_has(X86_FEATURE_SHSTK)) {
> +		rdmsrl(MSR_IA32_S_CET, cet_msr);
> +		WARN_ONCE(cet_msr, "KVM: CET S_CET in host will be lost!\n");
> +	}
> +
> +	if (boot_cpu_has(X86_FEATURE_SHSTK)) {
> +		rdmsrl(MSR_IA32_PL0_SSP, cet_msr);
> +		WARN_ONCE(cet_msr, "KVM: CET PL0_SSP in host will be lost!\n");
> +	}

Largely arbitrary, but I'd prefer to do these checks up near the BNDCFG check,
just so that all of these sorts of warnings are clustered together.

> +
>  	vmx_set_cpu_caps();
>  
>  	r = alloc_kvm_area();
> -- 
> 2.17.2
>
diff mbox series

Patch

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index d465ff990094..5d4250b9dec8 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6056,6 +6056,12 @@  void dump_vmcs(void)
 		pr_err("InterruptStatus = %04x\n",
 		       vmcs_read16(GUEST_INTR_STATUS));
 
+	if (vmentry_ctl & VM_ENTRY_LOAD_CET_STATE) {
+		pr_err("S_CET = 0x%016lx\n", vmcs_readl(GUEST_S_CET));
+		pr_err("SSP = 0x%016lx\n", vmcs_readl(GUEST_SSP));
+		pr_err("SSP TABLE = 0x%016lx\n",
+		       vmcs_readl(GUEST_INTR_SSP_TABLE));
+	}
 	pr_err("*** Host State ***\n");
 	pr_err("RIP = 0x%016lx  RSP = 0x%016lx\n",
 	       vmcs_readl(HOST_RIP), vmcs_readl(HOST_RSP));
@@ -6130,6 +6136,12 @@  void dump_vmcs(void)
 	if (secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID)
 		pr_err("Virtual processor ID = 0x%04x\n",
 		       vmcs_read16(VIRTUAL_PROCESSOR_ID));
+	if (vmexit_ctl & VM_EXIT_LOAD_CET_STATE) {
+		pr_err("S_CET = 0x%016lx\n", vmcs_readl(HOST_S_CET));
+		pr_err("SSP = 0x%016lx\n", vmcs_readl(HOST_SSP));
+		pr_err("SSP TABLE = 0x%016lx\n",
+		       vmcs_readl(HOST_INTR_SSP_TABLE));
+	}
 }
 
 /*
@@ -8205,6 +8217,7 @@  static __init int hardware_setup(void)
 	unsigned long host_bndcfgs;
 	struct desc_ptr dt;
 	int r, i, ept_lpage_level;
+	u64 cet_msr;
 
 	store_idt(&dt);
 	host_idt_base = dt.address;
@@ -8365,6 +8378,16 @@  static __init int hardware_setup(void)
 			return r;
 	}
 
+	if (boot_cpu_has(X86_FEATURE_IBT) || boot_cpu_has(X86_FEATURE_SHSTK)) {
+		rdmsrl(MSR_IA32_S_CET, cet_msr);
+		WARN_ONCE(cet_msr, "KVM: CET S_CET in host will be lost!\n");
+	}
+
+	if (boot_cpu_has(X86_FEATURE_SHSTK)) {
+		rdmsrl(MSR_IA32_PL0_SSP, cet_msr);
+		WARN_ONCE(cet_msr, "KVM: CET PL0_SSP in host will be lost!\n");
+	}
+
 	vmx_set_cpu_caps();
 
 	r = alloc_kvm_area();