From: Nikolay Borisov <nik.borisov@suse.com>
To: Daniel Sneddon <daniel.sneddon@linux.intel.com>,
Jonathan Corbet <corbet@lwn.net>,
Thomas Gleixner <tglx@linutronix.de>,
Borislav Petkov <bp@alien8.de>,
Peter Zijlstra <peterz@infradead.org>,
Josh Poimboeuf <jpoimboe@kernel.org>,
Ingo Molnar <mingo@redhat.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org
Cc: hpa@zytor.com, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, pawan.kumar.gupta@linux.intel.com
Subject: Re: [PATCH 6/6] x86/bugs: Clean-up verw mitigations
Date: Wed, 2 Oct 2024 17:20:58 +0300 [thread overview]
Message-ID: <fe2dfd0b-6b2a-496e-b059-0600d2ae474c@suse.com> (raw)
In-Reply-To: <20240924223140.1054918-7-daniel.sneddon@linux.intel.com>
On 25.09.24 г. 1:31 ч., Daniel Sneddon wrote:
> The current md_clear routines duplicate a lot of code, and have to be
> called twice because if one of the mitigations gets enabled they all
> get enabled since it's the same instruction. This approach leads to
> code duplication and extra complexity.
>
> The only piece that really changes between the first call of
> *_select_mitigation() and the second is X86_FEATURE_CLEAR_CPU_BUF
> being set. Determine if this feature should be set prior to calling
> the _select_mitigation() routines. This not only means those functions
> only get called once, but it also simplifies them as well.
>
> Signed-off-by: Daniel Sneddon <daniel.sneddon@linux.intel.com>
> ---
> arch/x86/kernel/cpu/bugs.c | 191 +++++++++++++++----------------------
> 1 file changed, 77 insertions(+), 114 deletions(-)
>
> diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
> index 45411880481c..412855391184 100644
> --- a/arch/x86/kernel/cpu/bugs.c
> +++ b/arch/x86/kernel/cpu/bugs.c
> @@ -41,7 +41,6 @@ static void __init spectre_v2_user_select_mitigation(void);
> static void __init ssb_select_mitigation(void);
> static void __init l1tf_select_mitigation(void);
> static void __init mds_select_mitigation(void);
> -static void __init md_clear_update_mitigation(void);
> static void __init md_clear_select_mitigation(void);
> static void __init taa_select_mitigation(void);
> static void __init mmio_select_mitigation(void);
> @@ -244,21 +243,9 @@ static const char * const mds_strings[] = {
>
> static void __init mds_select_mitigation(void)
> {
> - if (!boot_cpu_has_bug(X86_BUG_MDS) || cpu_mitigations_off()) {
> - mds_mitigation = MDS_MITIGATION_OFF;
> - return;
> - }
> -
> - if (mds_mitigation == MDS_MITIGATION_FULL) {
> - if (!boot_cpu_has(X86_FEATURE_MD_CLEAR))
> - mds_mitigation = MDS_MITIGATION_VMWERV;
> -
> - setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
> -
> - if (!boot_cpu_has(X86_BUG_MSBDS_ONLY) &&
> - (mds_nosmt || cpu_mitigations_auto_nosmt()))
> - cpu_smt_disable(false);
> - }
> + if (mds_mitigation == MDS_MITIGATION_FULL &&
> + !boot_cpu_has(X86_FEATURE_MD_CLEAR))
> + mds_mitigation = MDS_MITIGATION_VMWERV;
> }
>
> #undef pr_fmt
> @@ -284,35 +271,17 @@ static const char * const taa_strings[] = {
>
> static void __init taa_select_mitigation(void)
> {
> - if (!boot_cpu_has_bug(X86_BUG_TAA)) {
> - taa_mitigation = TAA_MITIGATION_OFF;
> - return;
> - }
> -
> /* TSX previously disabled by tsx=off */
> if (!boot_cpu_has(X86_FEATURE_RTM)) {
> taa_mitigation = TAA_MITIGATION_TSX_DISABLED;
> return;
> }
>
> - if (cpu_mitigations_off()) {
> - taa_mitigation = TAA_MITIGATION_OFF;
> + if (!boot_cpu_has(X86_FEATURE_MD_CLEAR)) {
> + taa_mitigation = TAA_MITIGATION_UCODE_NEEDED;
> return;
> }
>
> - /*
> - * TAA mitigation via VERW is turned off if both
> - * tsx_async_abort=off and mds=off are specified.
> - */
> - if (taa_mitigation == TAA_MITIGATION_OFF &&
> - mds_mitigation == MDS_MITIGATION_OFF)
> - return;
> -
> - if (boot_cpu_has(X86_FEATURE_MD_CLEAR))
> - taa_mitigation = TAA_MITIGATION_VERW;
> - else
> - taa_mitigation = TAA_MITIGATION_UCODE_NEEDED;
> -
> /*
> * VERW doesn't clear the CPU buffers when MD_CLEAR=1 and MDS_NO=1.
> * A microcode update fixes this behavior to clear CPU buffers. It also
> @@ -325,18 +294,6 @@ static void __init taa_select_mitigation(void)
> if ( (x86_arch_cap_msr & ARCH_CAP_MDS_NO) &&
> !(x86_arch_cap_msr & ARCH_CAP_TSX_CTRL_MSR))
> taa_mitigation = TAA_MITIGATION_UCODE_NEEDED;
> -
> - /*
> - * TSX is enabled, select alternate mitigation for TAA which is
> - * the same as MDS. Enable MDS static branch to clear CPU buffers.
> - *
> - * For guests that can't determine whether the correct microcode is
> - * present on host, enable the mitigation for UCODE_NEEDED as well.
> - */
> - setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
> -
> - if (taa_nosmt || cpu_mitigations_auto_nosmt())
> - cpu_smt_disable(false);
> }
>
> #undef pr_fmt
> @@ -360,24 +317,6 @@ static const char * const mmio_strings[] = {
>
> static void __init mmio_select_mitigation(void)
> {
> - if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) ||
> - boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN) ||
> - cpu_mitigations_off()) {
> - mmio_mitigation = MMIO_MITIGATION_OFF;
> - return;
> - }
> -
> - if (mmio_mitigation == MMIO_MITIGATION_OFF)
> - return;
> -
> - /*
> - * Enable CPU buffer clear mitigation for host and VMM, if also affected
> - * by MDS or TAA. Otherwise, enable mitigation for VMM only.
> - */
> - if (boot_cpu_has_bug(X86_BUG_MDS) || (boot_cpu_has_bug(X86_BUG_TAA) &&
> - boot_cpu_has(X86_FEATURE_RTM)))
> - setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
> -
> /*
> * X86_FEATURE_CLEAR_CPU_BUF could be enabled by other VERW based
> * mitigations, disable KVM-only mitigation in that case.
> @@ -409,9 +348,6 @@ static void __init mmio_select_mitigation(void)
> mmio_mitigation = MMIO_MITIGATION_VERW;
> else
> mmio_mitigation = MMIO_MITIGATION_UCODE_NEEDED;
> -
> - if (mmio_nosmt || cpu_mitigations_auto_nosmt())
> - cpu_smt_disable(false);
> }
>
> #undef pr_fmt
> @@ -435,16 +371,7 @@ static const char * const rfds_strings[] = {
>
> static void __init rfds_select_mitigation(void)
> {
> - if (!boot_cpu_has_bug(X86_BUG_RFDS) || cpu_mitigations_off()) {
> - rfds_mitigation = RFDS_MITIGATION_OFF;
> - return;
> - }
> - if (rfds_mitigation == RFDS_MITIGATION_OFF)
> - return;
> -
> - if (x86_arch_cap_msr & ARCH_CAP_RFDS_CLEAR)
> - setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
> - else
> + if (!(x86_arch_cap_msr & ARCH_CAP_RFDS_CLEAR))
> rfds_mitigation = RFDS_MITIGATION_UCODE_NEEDED;
> }
>
> @@ -485,41 +412,92 @@ static int __init clear_cpu_buffers_cmdline(char *str)
> }
> early_param("clear_cpu_buffers", clear_cpu_buffers_cmdline);
>
> -static void __init md_clear_update_mitigation(void)
> +static bool __init cpu_bug_needs_verw(void)
> {
> - if (cpu_mitigations_off())
> - return;
> + return boot_cpu_has_bug(X86_BUG_MDS) ||
> + boot_cpu_has_bug(X86_BUG_TAA) ||
> + boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) ||
> + boot_cpu_has_bug(X86_BUG_RFDS);
> +}
>
> - if (!boot_cpu_has(X86_FEATURE_CLEAR_CPU_BUF))
> - goto out;
> +static bool __init verw_mitigations_disabled(void)
> +{
> + /*
> + * TODO: Create a single mitigation variable that will allow for setting
> + * the location of the mitigation, i.e.:
> + *
> + * kernel->user
> + * kvm->guest
> + * kvm->guest if device passthrough
> + * kernel->idle
> + */
> + return (mds_mitigation == MDS_MITIGATION_OFF &&
> + taa_mitigation == TAA_MITIGATION_OFF &&
> + mmio_mitigation == MMIO_MITIGATION_OFF &&
> + rfds_mitigation == RFDS_MITIGATION_OFF);
> +}
>
> +static void __init md_clear_select_mitigation(void)
> +{
> /*
> - * X86_FEATURE_CLEAR_CPU_BUF is now enabled. Update MDS, TAA and MMIO
> - * Stale Data mitigation, if necessary.
> + * If no CPU bug needs VERW, all VERW mitigations are disabled, or all
> + * mitigations are disabled we bail.
> */
> - if (mds_mitigation == MDS_MITIGATION_OFF &&
> - boot_cpu_has_bug(X86_BUG_MDS)) {
> + if (!cpu_bug_needs_verw() || verw_mitigations_disabled() ||
> + cpu_mitigations_off()) {
> + mds_mitigation = MDS_MITIGATION_OFF;
> + taa_mitigation = TAA_MITIGATION_OFF;
> + mmio_mitigation = MMIO_MITIGATION_OFF;
> + rfds_mitigation = RFDS_MITIGATION_OFF;
> + goto out;
> + }
> +
> + /* Check that at least one mitigation is using the verw mitigaiton.
> + * If the cpu doesn't have the correct ucode or if the BUG_* is mitigated
> + * by disabling a feature we won't want to use verw. Ignore MMIO
> + * for now since it depends on what the others choose.
> + */
> +
> + if (boot_cpu_has_bug(X86_BUG_MDS)) {
> mds_mitigation = MDS_MITIGATION_FULL;
> mds_select_mitigation();
> + } else {
> + mds_mitigation = MDS_MITIGATION_OFF;
> }
BUt with this logic if CONFIG_MITIGATION_MDS is deselected meaning
mds_mitigations will have the value MDS_MITIGATION_OFF, yet now you will
set it to _FULL thereby overriding the compile-time value of the user.
So shouldn't this condition be augmented to alsoo consider
CONFIG_MITIGATION_MDS compile time value?
<snip>
next prev parent reply other threads:[~2024-10-02 14:21 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-24 22:31 [PATCH 0/6] VERW based clean-up Daniel Sneddon
2024-09-24 22:31 ` [PATCH 1/6] x86/bugs: Create single parameter for VERW based mitigations Daniel Sneddon
2024-10-08 19:24 ` Kaplan, David
2024-10-09 16:17 ` Daniel Sneddon
2024-10-09 16:36 ` Kaplan, David
2024-10-09 16:39 ` Daniel Sneddon
2024-10-09 19:44 ` Daniel Sneddon
2024-10-09 20:02 ` Kaplan, David
2024-10-09 20:34 ` Daniel Sneddon
2024-10-10 4:52 ` Josh Poimboeuf
2024-10-10 14:57 ` Borislav Petkov
2024-10-14 15:42 ` Daniel Sneddon
2024-10-15 13:52 ` Borislav Petkov
2024-10-15 14:05 ` Daniel Sneddon
2024-09-24 22:31 ` [PATCH 2/6] x86/bugs: Remove MDS command line Daniel Sneddon
2024-09-24 22:34 ` Dave Hansen
2024-09-24 22:41 ` Daniel Sneddon
2024-09-24 22:31 ` [PATCH 3/6] x86/bugs: Remove TAA kernel parameter Daniel Sneddon
2024-09-24 22:31 ` [PATCH 4/6] x86/bugs: Remove MMIO " Daniel Sneddon
2024-09-24 22:31 ` [PATCH 5/6] x86/bugs: Remove RFDS " Daniel Sneddon
2024-09-24 22:31 ` [PATCH 6/6] x86/bugs: Clean-up verw mitigations Daniel Sneddon
2024-10-02 14:20 ` Nikolay Borisov [this message]
2024-10-02 14:46 ` Daniel Sneddon
2024-10-02 14:54 ` Nikolay Borisov
2024-10-07 19:37 ` Josh Poimboeuf
2024-10-08 16:17 ` Daniel Sneddon
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=fe2dfd0b-6b2a-496e-b059-0600d2ae474c@suse.com \
--to=nik.borisov@suse.com \
--cc=bp@alien8.de \
--cc=corbet@lwn.net \
--cc=daniel.sneddon@linux.intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=jpoimboe@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=pawan.kumar.gupta@linux.intel.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=x86@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.