All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@kernel.org>
To: Rik van Riel <riel@surriel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>,
	Andy Lutomirski <luto@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	x86@kernel.org, linux-kernel@vger.kernel.org,
	kernel-team@meta.com
Subject: Re: [PATCH] x86/mm: resize user_pcid_flush_mask for PTI / broadcast TLB flush combination
Date: Sat, 17 May 2025 09:59:48 +0200	[thread overview]
Message-ID: <aChB9ORFxaL8VfyD@gmail.com> (raw)
In-Reply-To: <20250516123317.70506358@fangorn>


* Rik van Riel <riel@surriel.com> wrote:

> @@ -121,7 +140,11 @@ struct tlb_state {
>  	 * the corresponding user PCID needs a flush next time we
>  	 * switch to it; see SWITCH_TO_USER_CR3.
>  	 */
> +#if defined(CONFIG_X86_TLB_BROADCAST_TLB_FLUSH) && defined(CONFIG_MITIGATION_PAGE_TABLE_ISOLATION)
> +	unsigned long user_pcid_flush_mask[(1 << CR3_AVAIL_PCID_BITS) / BITS_PER_LONG];
> +#else
>  	unsigned short user_pcid_flush_mask;
> +#endif

1)

CONFIG_X86_TLB_BROADCAST_TLB_FLUSH doesn't actually exist, the name is 
CONFIG_BROADCAST_TLB_FLUSH.

This patch could not possibly have been tested on a vanilla kernel on 
actual hardware in the PTI usecase it claims to fix...

2)

Testing aside, this definition and the usage of user_pcid_flush_mask is 
unnecessarily confusing, as it also defines user_pcid_flush_mask when 
it's not actually used by runtime code. user_pcid_flush_mask is only 
used if CONFIG_MITIGATION_PAGE_TABLE_ISOLATION=y, so as an interim step 
we could make this a more obvious:

   #ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
   # ifdef CONFIG_BROADCAST_TLB_FLUSH
	unsigned long user_pcid_flush_mask[(1 << CR3_AVAIL_PCID_BITS) / BITS_PER_LONG];
   # else
	unsigned short user_pcid_flush_mask;
   # endif
   #endif

And wrap the body of invalidate_user_asid() in an #ifdef 
CONFIG_MITIGATION_PAGE_TABLE_ISOLATION. The entry assembly code is 
already under such an #ifdef.

And once we do that it becomes obvious that the two definitions of 
user_pcid_flush_mask can be merged by doing something like:

   #ifdef CONFIG_BROADCAST_TLB_FLUSH
   # define CR3_AVAIL_PCID_LONGS ((1 << CR3_AVAIL_PCID_BITS) / BITS_PER_LONG)
   #else
   # define CR3_AVAIL_PCID_LONGS 1
   #endif

   #ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
   unsigned long user_pcid_flush_mask[CR3_AVAIL_PCID_LONGS];
   #endif

(Or so, if I counted my bits and longs right.)

And we can drop the ugly & fragile type cast in invalidate_user_asid():

-	__set_bit(kern_pcid(asid),
-		  (unsigned long *)this_cpu_ptr(&cpu_tlbstate.user_pcid_flush_mask));

+	__set_bit(kern_pcid(asid), this_cpu_ptr(cpu_tlbstate.user_pcid_flush_mask));

And yeah, this means user_pcid_flush_mask is a long on 
!CONFIG_BROADCAST_TLB_FLUSH kernels, while it was a short before.
Literally nobody cares, because it's enabled on all distro kernels that 
have CPU_SUP_AMD:

  config BROADCAST_TLB_FLUSH 
        def_bool y
        depends on CPU_SUP_AMD && 64BIT

Literally no Linux distribution is going to have this option disabled.

Ie. we'd be uglifying and obfuscating the code for a config that people 
aren't actually using...

3)

If we are going to grow user_pcid_flush_mask from 2 bytes to 256 bytes 
then please reorder 'struct tlb_state' for cache efficiency: at minimum 
the ::cr4 shadow should move to before ::user_pcid_flush_mask. But I 
think we should probably move user_pcid_flush_mask to the end of the 
structure, where it does the least damage to cache layout.

Thanks,

	Ingo

  reply	other threads:[~2025-05-17  7:59 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-16 16:33 [PATCH] x86/mm: resize user_pcid_flush_mask for PTI / broadcast TLB flush combination Rik van Riel
2025-05-17  7:59 ` Ingo Molnar [this message]
2025-05-17 21:29   ` Rik van Riel
2025-05-18  0:12   ` [PATCH v2] " Rik van Riel
2025-05-18  6:25     ` Ingo Molnar
2025-05-18 16:22       ` Rik van Riel

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=aChB9ORFxaL8VfyD@gmail.com \
    --to=mingo@kernel.org \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=kernel-team@meta.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=riel@surriel.com \
    --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.