From: Thomas Gleixner <tglx@linutronix.de>
To: Balbir Singh <sblbir@amazon.com>, mingo@redhat.com
Cc: peterz@infradead.org, linux-kernel@vger.kernel.org,
keescook@chromium.org, jpoimboe@redhat.com, tony.luck@intel.com,
benh@kernel.crashing.org, x86@kernel.org, dave.hansen@intel.com,
thomas.lendacky@amd.com, torvalds@linux-foundation.org,
Balbir Singh <sblbir@amazon.com>
Subject: Re: [PATCH v3 4/5] prctl: Hook L1D flushing in via prctl
Date: Fri, 04 Dec 2020 23:19:17 +0100 [thread overview]
Message-ID: <87eek59pui.fsf@nanos.tec.linutronix.de> (raw)
In-Reply-To: <20201127065938.8200-5-sblbir@amazon.com>
Balbir,
On Fri, Nov 27 2020 at 17:59, Balbir Singh wrote:
> +enum l1d_flush_out_mitigations {
> + L1D_FLUSH_OUT_OFF,
> + L1D_FLUSH_OUT_ON,
> +};
> +
> +static enum l1d_flush_out_mitigations l1d_flush_out_mitigation __ro_after_init = L1D_FLUSH_OUT_ON;
Why default on and why stays it on when the CPU is not affected by L1TF ...
> /* Default mitigation for TAA-affected CPUs */
> static enum taa_mitigations taa_mitigation __ro_after_init = TAA_MITIGATION_VERW;
> static bool taa_nosmt __ro_after_init;
> @@ -379,6 +386,18 @@ static void __init taa_select_mitigation(void)
> pr_info("%s\n", taa_strings[taa_mitigation]);
> }
>
> +static int __init l1d_flush_out_parse_cmdline(char *str)
> +{
> + if (!boot_cpu_has_bug(X86_BUG_L1TF))
> + return 0;
... while here you check for L1TF.
Also shouldn't it be default off and enabled via command line?
> +static int l1d_flush_out_prctl_get(struct task_struct *task)
> +{
> + int ret;
> +
> + if (l1d_flush_out_mitigation == L1D_FLUSH_OUT_OFF)
> + return PR_SPEC_FORCE_DISABLE;
> +
> + ret = test_ti_thread_flag(&task->thread_info, TIF_SPEC_L1D_FLUSH);
That ret indirection is pointless. Just make it if (test_....)
> +static int l1d_flush_out_prctl_set(struct task_struct *task, unsigned long ctrl)
> +{
> +
> + if (l1d_flush_out_mitigation == L1D_FLUSH_OUT_OFF)
> + return -EPERM;
So here you check for off and then...
> int enable_l1d_flush_for_task(struct task_struct *tsk)
> {
> + /*
> + * Do not enable L1D_FLUSH_OUT if
> + * b. The CPU is not affected by the L1TF bug
> + * c. The CPU does not have L1D FLUSH feature support
> + */
> +
> + if (!boot_cpu_has_bug(X86_BUG_L1TF) ||
> + !boot_cpu_has(X86_FEATURE_FLUSH_L1D))
> + return -EINVAL;
... you check for the feature bits with a malformatted condition at some
other place. It's not supported when these conditions are not there. So
why having this check here?
> +
> set_ti_thread_flag(&tsk->thread_info, TIF_SPEC_L1D_FLUSH);
> return 0;
> }
Aside of that, why is this in tlb.c and not in bugs.c? There is nothing
tlb specific in these enable/disable functions. They just fiddle with
the TIF bit.
> +/*
> + * Sent to a task that opts into L1D flushing via the prctl interface
> + * but ends up running on an SMT enabled core.
> + */
> +static void l1d_flush_kill(struct callback_head *ch)
> +{
> + force_sig(SIGBUS);
> +}
> +
> static inline unsigned long mm_mangle_tif_spec_bits(struct task_struct *next)
> {
> unsigned long next_tif = task_thread_info(next)->flags;
> unsigned long spec_bits = (next_tif >> TIF_SPEC_IB) & LAST_USER_MM_SPEC_MASK;
> + unsigned long next_mm;
>
> BUILD_BUG_ON(TIF_SPEC_L1D_FLUSH != TIF_SPEC_IB + 1);
> - return (unsigned long)next->mm | spec_bits;
> + next_mm = (unsigned long)next->mm | spec_bits;
> +
> + if ((next_mm & LAST_USER_MM_L1D_FLUSH) && this_cpu_read(cpu_info.smt_active)) {
Wheeee. Yet more unconditional checks on every context switch.
> + clear_ti_thread_flag(&next->thread_info, TIF_SPEC_L1D_FLUSH);
> + next->l1d_flush_kill.func = l1d_flush_kill;
> + task_work_add(next, &next->l1d_flush_kill, true);
int task_work_add(struct task_struct *task, struct callback_head *twork,
enum task_work_notify_mode mode);
true is truly not a valid enum constant ....
> + }
So you really want to have:
DEFINE_STATIC_KEY_FALSE(l1dflush_enabled);
static bool l1dflush_mitigation __init_data;
and then with the command line option you set l1dflush_mitigation and in
check_bugs() you invoke l1dflush_select_mitigation() which does:
if (!l1dflush_mitigation || !boot_cpu_has_bug(X86_BUG_L1TF) ||
!boot_cpu_has(X86_FEATURE_FLUSH_L1D))
return;
static_branch_enable(&l1dflush_enabled);
and then in l1d_flush_out_prctl_set()
if (!static_branch_unlikely(&l1dflush_enabled))
return -ENOTSUPP;
Then make the whole switch machinery do:
if (static_branch_unlikely(&l1dflush_enabled)) {
if (unlikely((next_mm | prev_mm) & LAST_USER_MM_L1D_FLUSH))
l1dflush_evaluate(next_mm, prev_mm);
}
and l1dflush_evaluate()
if (prev_mm & LAST_USER_MM_L1D_FLUSH)
l1d_flush();
if ((next_mm & LAST_USER_MM_L1D_FLUSH) &&
this_cpu_read(cpu_info.smt_active)) {
clear_ti_thread_flag(&next->thread_info, TIF_SPEC_L1D_FLUSH);
next->l1d_flush_kill.func = l1d_flush_kill;
task_work_add(next, &next->l1d_flush_kill, TWA_RESUME);
}
That way the overhead is on systems where the admin decides to enable it
and if enabled the evaluation of prev_mm and next_mm is pushed out of
line.
Hmm?
Thanks,
tglx
next prev parent reply other threads:[~2020-12-04 22:20 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-27 6:59 [PATCH v3 0/5] Next revision of the L1D flush patches Balbir Singh
2020-11-27 6:59 ` [PATCH v3 1/5] x86/mm: change l1d flush runtime prctl behaviour Balbir Singh
2020-12-04 21:07 ` Thomas Gleixner
2020-12-04 22:44 ` Singh, Balbir
2020-11-27 6:59 ` [PATCH v3 2/5] x86/mm: Refactor cond_ibpb() to support other use cases Balbir Singh
2020-11-27 6:59 ` [PATCH v3 3/5] x86/mm: Optionally flush L1D on context switch Balbir Singh
2020-12-04 21:21 ` Thomas Gleixner
2020-12-04 22:41 ` Singh, Balbir
2020-11-27 6:59 ` [PATCH v3 4/5] prctl: Hook L1D flushing in via prctl Balbir Singh
2020-12-04 22:19 ` Thomas Gleixner [this message]
2020-12-05 2:56 ` Balbir Singh
2020-11-27 6:59 ` [PATCH v3 5/5] Documentation: Add L1D flushing Documentation Balbir Singh
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=87eek59pui.fsf@nanos.tec.linutronix.de \
--to=tglx@linutronix.de \
--cc=benh@kernel.crashing.org \
--cc=dave.hansen@intel.com \
--cc=jpoimboe@redhat.com \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=sblbir@amazon.com \
--cc=thomas.lendacky@amd.com \
--cc=tony.luck@intel.com \
--cc=torvalds@linux-foundation.org \
--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;
as well as URLs for NNTP newsgroup(s).