Return-path: Received: from mga04.intel.com ([192.55.52.120]) by Galois.linutronix.de with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1fEMoF-00061g-Hk for speck@linutronix.de; Fri, 04 May 2018 00:34:44 +0200 From: Dave Hansen Subject: [MODERATED] [PATCH 4/5] SSB extra 5 Date: Thu, 3 May 2018 15:29:47 -0700 Message-Id: =?utf-8?q?=3C1eb9618baa7b4d021ee5255cf138a6ebc3c3984a=2E152538?= =?utf-8?q?3411=2Egit=2Edave=2Ehansen=40intel=2Ecom=3E?= In-Reply-To: References: In-Reply-To: References: Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit MIME-Version: 1.0 To: speck@linutronix.de Cc: Dave Hansen List-ID: From: Dave Hansen The KVM code manipualtes the SPEC_CTRL MSR when it enters and exits the guest. It overwrites the "kernel" value when it enters the guest and restores the "kernel" value after leaving the guest. Both code paths take into account the "base" (x86_spec_ctrl_base) value and the per-task TIF_RDS flag (on Intel). They then see if the new state differs from the existing state and avoid the MSR write if no change is made. But, these two paths could be a bit more unified. Introduce a new function: x86_calculate_kernel_spec_ctrl() which will figure out the "kernel" value to contrast it with the "guest" value. We also rename the arguments to the set/restore functions to make it clear that while the arguments are both "guest" state, they really mean different things to the two functions. This will make the next step easier when we have more state to consult in doing the x86_calculate_kernel_spec_ctrl() calculatione Signed-off-by: Dave Hansen Cc: Andi Kleen Cc: Tim Chen --- arch/x86/kernel/cpu/bugs.c | 50 ++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index c28856e..0e17379 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -146,33 +146,49 @@ u64 x86_get_default_spec_ctrl(void) } EXPORT_SYMBOL_GPL(x86_get_default_spec_ctrl); -void x86_set_guest_spec_ctrl(u64 guest_spec_ctrl) +static inline u64 intel_rds_mask(void) { - u64 host = x86_spec_ctrl_base; + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) + return 0; + + return rds_tif_to_spec_ctrl(current_thread_info()->flags); +} + +/* + * Calculate the SPEC_CTRL MSR value that the kernel + * should be using under normal operation. + */ +static u64 x86_calculate_kernel_spec_ctrl(void) +{ + u64 spec_ctrl; if (!boot_cpu_has(X86_FEATURE_IBRS)) - return; + return 0; - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - host |= rds_tif_to_spec_ctrl(current_thread_info()->flags); + spec_ctrl = x86_spec_ctrl_base; + spec_ctrl |= intel_rds_mask(); - if (host != guest_spec_ctrl) - wrmsrl(MSR_IA32_SPEC_CTRL, guest_spec_ctrl); + return spec_ctrl; } -EXPORT_SYMBOL_GPL(x86_set_guest_spec_ctrl); -void x86_restore_host_spec_ctrl(u64 guest_spec_ctrl) +/* We are entering a guest and need to set its MSR value. */ +void x86_set_guest_spec_ctrl(u64 new_spec_ctrl) { - u64 host = x86_spec_ctrl_base; - - if (!boot_cpu_has(X86_FEATURE_IBRS)) - return; + if (x86_calculate_kernel_spec_ctrl() != new_spec_ctrl) + wrmsrl(MSR_IA32_SPEC_CTRL, new_spec_ctrl); +} +EXPORT_SYMBOL_GPL(x86_set_guest_spec_ctrl); - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - host |= rds_tif_to_spec_ctrl(current_thread_info()->flags); +/* + * We are leaving a guest and need to restore the kernel's MSR + * value that it uses for normal operation. + */ +void x86_restore_host_spec_ctrl(u64 current_spec_ctrl) +{ + u64 new_spec_ctrl = x86_calculate_kernel_spec_ctrl(); - if (host != guest_spec_ctrl) - wrmsrl(MSR_IA32_SPEC_CTRL, host); + if (new_spec_ctrl != current_spec_ctrl) + wrmsrl(MSR_IA32_SPEC_CTRL, new_spec_ctrl); } EXPORT_SYMBOL_GPL(x86_restore_host_spec_ctrl); -- 2.9.5