From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linutronix.de (146.0.238.70:993) by crypto-ml.lab.linutronix.de with IMAP4-SSL for ; 16 Jul 2018 20:44:33 -0000 Received: from aserp2130.oracle.com ([141.146.126.79]) by Galois.linutronix.de with esmtps (TLS1.2:RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1ffAMB-00045R-QL for speck@linutronix.de; Mon, 16 Jul 2018 22:44:32 +0200 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w6GKYJ7G122353 for ; Mon, 16 Jul 2018 20:44:25 GMT Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp2130.oracle.com with ESMTP id 2k7a3sx4kf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Mon, 16 Jul 2018 20:44:24 +0000 Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id w6GKiNHg003196 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Mon, 16 Jul 2018 20:44:24 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id w6GKiNaG014514 for ; Mon, 16 Jul 2018 20:44:23 GMT Date: Mon, 16 Jul 2018 16:44:18 -0400 From: Konrad Rzeszutek Wilk Subject: [MODERATED] Re: [PATCH] L1TF KVM ARCH_CAPABILITIES #0 Message-ID: <20180716204418.GA17294@char.US.ORACLE.com> References: <20180715135716.1874-1-pbonzini@redhat.com> MIME-Version: 1.0 In-Reply-To: <20180715135716.1874-1-pbonzini@redhat.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit To: speck@linutronix.de List-ID: On Sun, Jul 15, 2018 at 03:57:12PM +0200, speck for Paolo Bonzini wrote: > Support for ARCH_CAPABILITIES bit 3, which can already be used to disable > the mitigations on a nested hypervisor. Patch 3 will shortly go to Linus's > tree. Paolo, I am thinking I am missing something here. I was expecting if I do rdmsr 0x10a inside the guest I would get '8' but instead I got '0'? The guest does see CPUID.7.EDX. Bit 29 so the guest does expose 'arch_capability' in the /proc/cpuinfo flags. And the data |= ARCH_CAP_SKIP.. is certainly run (added a printk there just in case). Thoughts? (I wrote the patch before I saw the Intel's patch). This is on top of yesterday QEMU's master tree. >From 09742087d36c6b786c10cc2bc0539aaed0f80e96 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 13 Jul 2018 13:57:31 +0000 Subject: [PATCH] i386: Define the IA32_ARCH_CAPABILITIES capability. GeminiLake CPUs have this and exposing this to the guest allows kernels to sample the Enhanced IBRS support. The definition of this MSR and detection (CPUID.(EAX=7H,ECX=0):EDX[29]) is nicely described in the Intel whitepaper titled: 336996-Speculative-Execution-Side-Channel-Mitigations.pdf A copy of this document is available at https://bugzilla.kernel.org/show_bug.cgi?id=199511 Signed-off-by: Konrad Rzeszutek Wilk --- target/i386/cpu.c | 2 +- target/i386/cpu.h | 3 ++- target/i386/kvm.c | 13 +++++++++++++ target/i386/machine.c | 20 ++++++++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index e0e2f2e..070cb7c 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1000,7 +1000,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "spec-ctrl", NULL, - NULL, NULL, NULL, "ssbd", + NULL, "arch-cap", NULL, "ssbd", }, .cpuid_eax = 7, .cpuid_needs_ecx = true, .cpuid_ecx = 0, diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 2c5a0d9..2211b01 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -355,7 +355,7 @@ typedef enum X86Seg { #define MSR_IA32_SPEC_CTRL 0x48 #define MSR_VIRT_SSBD 0xc001011f #define MSR_IA32_TSCDEADLINE 0x6e0 - +#define MSR_IA32_ARCH_CAPABILITIES 0x0000010a #define FEATURE_CONTROL_LOCKED (1<<0) #define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2) #define FEATURE_CONTROL_LMCE (1<<20) @@ -1212,6 +1212,7 @@ typedef struct CPUX86State { uint64_t spec_ctrl; uint64_t virt_ssbd; + uint64_t arch_cap; /* End of state preserved by INIT (dummy marker). */ struct {} end_init_save; diff --git a/target/i386/kvm.c b/target/i386/kvm.c index ebb2d23..b96d9f6 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -93,6 +93,7 @@ static bool has_msr_hv_reenlightenment; static bool has_msr_xss; static bool has_msr_spec_ctrl; static bool has_msr_virt_ssbd; +static bool has_msr_arch_cap; static bool has_msr_smi_count; static uint32_t has_architectural_pmu_version; @@ -1288,6 +1289,9 @@ static int kvm_get_supported_msrs(KVMState *s) case MSR_VIRT_SSBD: has_msr_virt_ssbd = true; break; + case MSR_IA32_ARCH_CAPABILITIES: + has_msr_arch_cap = true; + break; } } } @@ -1802,6 +1806,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level) if (has_msr_virt_ssbd) { kvm_msr_entry_add(cpu, MSR_VIRT_SSBD, env->virt_ssbd); } + if (has_msr_arch_cap) { + kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES, env->arch_cap); + } #ifdef TARGET_X86_64 if (lm_capable_kernel) { @@ -2185,6 +2192,9 @@ static int kvm_get_msrs(X86CPU *cpu) if (has_msr_virt_ssbd) { kvm_msr_entry_add(cpu, MSR_VIRT_SSBD, 0); } + if (has_msr_arch_cap) { + kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES, 0); + } if (!env->tsc_valid) { kvm_msr_entry_add(cpu, MSR_IA32_TSC, 0); env->tsc_valid = !runstate_is_running(); @@ -2567,6 +2577,9 @@ static int kvm_get_msrs(X86CPU *cpu) case MSR_VIRT_SSBD: env->virt_ssbd = msrs[i].data; break; + case MSR_IA32_ARCH_CAPABILITIES: + env->arch_cap = msrs[i].data; + break; case MSR_IA32_RTIT_CTL: env->msr_rtit_ctrl = msrs[i].data; break; diff --git a/target/i386/machine.c b/target/i386/machine.c index 8b64dff..963cfc0 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -955,6 +955,25 @@ static const VMStateDescription vmstate_svm_npt = { } }; +static bool arch_cap_needed(void *opaque) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + + return env->arch_cap != 0; +} + +static const VMStateDescription vmstate_msr_arch_cap = { + .name = "cpu/arch_cap", + .version_id = 1, + .minimum_version_id = 1, + .needed = arch_cap_needed, + .fields = (VMStateField[]){ + VMSTATE_UINT64(env.arch_cap, X86CPU), + VMSTATE_END_OF_LIST() + } +}; + VMStateDescription vmstate_x86_cpu = { .name = "cpu", .version_id = 12, @@ -1080,6 +1099,7 @@ VMStateDescription vmstate_x86_cpu = { &vmstate_msr_intel_pt, &vmstate_msr_virt_ssbd, &vmstate_svm_npt, + &vmstate_msr_arch_cap, NULL } }; -- 1.8.3.1 > > Paolo Bonzini (4): > KVM: test L1TF EPT bug separately from X86_BUG_L1TF > x86: use ARCH_CAPABILITIES to skip L1D flush on vmentry > KVM: VMX: support MSR_IA32_ARCH_CAPABILITIES as a feature MSR > KVM: VMX: tell nested hypervisor to skip L1D flush on vmentry > > Documentation/admin-guide/l1tf.rst | 24 ++++++++++++++++++++++++ > arch/x86/include/asm/kvm_host.h | 1 + > arch/x86/include/asm/msr-index.h | 1 + > arch/x86/include/asm/vmx.h | 1 + > arch/x86/kernel/cpu/bugs.c | 26 ++++++++++++++++++++------ > arch/x86/kvm/vmx.c | 35 ++++++++++++++++++++++++----------- > arch/x86/kvm/x86.c | 17 ++++++++++++++++- > 7 files changed, 87 insertions(+), 18 deletions(-) > > -- > 1.8.3.1