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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox