From: Dave Hansen <dave.hansen@linux.intel.com>
To: linux-kernel@vger.kernel.org
Cc: kirill.shutemov@linux.intel.com,pbonzini@redhat.com,tglx@linutronix.de,x86@kernel.org,bp@alien8.de,Dave
Hansen <dave.hansen@linux.intel.com>
Subject: [RFC][PATCH 27/34] x86/cpu: Enforce read-only x86_config state (lightly)
Date: Thu, 22 Feb 2024 10:40:02 -0800 [thread overview]
Message-ID: <20240222184002.690F68EF@davehans-spike.ostc.intel.com> (raw)
In-Reply-To: <20240222183926.517AFCD2@davehans-spike.ostc.intel.com>
From: Dave Hansen <dave.hansen@linux.intel.com>
Part of the reason that this all turned into such a mess is that there
were no rules around when 'struct cpuinfo_x86' was written. It was
(and is) just a free-for-all.
Establish that 'x86_config' has two phases of its lifetime: an
C_INITIALIZING phase where it can be written and a later C_FINALIZED
stage where it can only be read. It is simple to audit the fact
that this state transition happens just where the comment says it
should be.
Check that the config is C_FINALIZED in each of the wrappers that
read a 'x86_config' value. If something reads too early, stash
some information to the caller so that it can spit out a warning
later.
This goofy stash-then-warn construct is necessary here because any
hapless readers are likely to be in a spot where they can not easily
WARN() themselves, like the early Xen PV boot that's caused so many
problems.
This also moves one x86_clflush_size() reference over to the more
direct x86_config.cache_alignment because otherwise it would trip
the !C_FINALIZED check.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
---
b/arch/x86/include/asm/processor.h | 22 ++++++++++++++++++++++
b/arch/x86/kernel/cpu/common.c | 5 ++++-
b/arch/x86/kernel/setup.c | 7 +++++++
3 files changed, 33 insertions(+), 1 deletion(-)
diff -puN arch/x86/include/asm/processor.h~x86_config-finalize arch/x86/include/asm/processor.h
--- a/arch/x86/include/asm/processor.h~x86_config-finalize 2024-02-22 10:09:01.772975960 -0800
+++ b/arch/x86/include/asm/processor.h 2024-02-22 10:09:01.780976274 -0800
@@ -183,6 +183,11 @@ struct x86_addr_config {
u8 min_cache_bits;
};
+enum x86_sys_config_state {
+ C_INITIALIZING,
+ C_FINALIZED
+};
+
/*
* System-wide configuration that is shared by all processors.
*
@@ -190,6 +195,9 @@ struct x86_addr_config {
* modified after that.
*/
struct x86_sys_config {
+ enum x86_sys_config_state conf_state;
+ void *early_reader;
+
/* Address bits supported by all processors */
u8 phys_bits;
u8 virt_bits;
@@ -805,23 +813,37 @@ static inline void weak_wrmsr_fence(void
alternative("mfence; lfence", "", ALT_NOT(X86_FEATURE_APIC_MSRS_FENCE));
}
+static inline void read_x86_config(void)
+{
+ if (x86_config.conf_state == C_FINALIZED)
+ return;
+
+ /* Only record the first one: */
+ if (!x86_config.early_reader)
+ x86_config.early_reader = __builtin_return_address(0);
+}
+
static inline u8 x86_phys_bits(void)
{
+ read_x86_config();
return x86_config.phys_bits;
}
static inline u8 x86_virt_bits(void)
{
+ read_x86_config();
return x86_config.virt_bits;
}
static inline u8 x86_cache_bits(void)
{
+ read_x86_config();
return x86_config.cache_bits;
}
static inline u8 x86_clflush_size(void)
{
+ read_x86_config();
return x86_config.clflush_size;
}
diff -puN arch/x86/kernel/cpu/common.c~x86_config-finalize arch/x86/kernel/cpu/common.c
--- a/arch/x86/kernel/cpu/common.c~x86_config-finalize 2024-02-22 10:09:01.776976117 -0800
+++ b/arch/x86/kernel/cpu/common.c 2024-02-22 10:09:01.780976274 -0800
@@ -1114,6 +1114,9 @@ void get_cpu_address_sizes(struct cpuinf
u32 eax, ebx, ecx, edx;
bool vp_bits_from_cpuid = true;
+ WARN_ON_ONCE(x86_config.conf_state > C_INITIALIZING);
+ x86_config.conf_state = C_INITIALIZING;
+
if (!cpu_has(c, X86_FEATURE_CPUID) ||
(c->extended_cpuid_level < 0x80000008))
vp_bits_from_cpuid = false;
@@ -1142,7 +1145,7 @@ void get_cpu_address_sizes(struct cpuinf
if (x86_config.cache_bits < bsp_addr_config.min_cache_bits)
x86_config.cache_bits = bsp_addr_config.min_cache_bits;
- x86_config.cache_alignment = x86_clflush_size();
+ x86_config.cache_alignment = x86_config.clflush_size;
if (bsp_addr_config.cache_align_mult)
x86_config.cache_alignment *= bsp_addr_config.cache_align_mult;
diff -puN arch/x86/kernel/setup.c~x86_config-finalize arch/x86/kernel/setup.c
--- a/arch/x86/kernel/setup.c~x86_config-finalize 2024-02-22 10:09:01.776976117 -0800
+++ b/arch/x86/kernel/setup.c 2024-02-22 10:09:01.780976274 -0800
@@ -762,7 +762,14 @@ void __init setup_arch(char **cmdline_p)
olpc_ofw_detect();
idt_setup_early_traps();
+
early_cpu_init();
+
+ /* Ensure no readers snuck in before the config was finished: */
+ WARN_ONCE(x86_config.early_reader, "x86_config.early_reader: %pS\n",
+ x86_config.early_reader);
+ x86_config.conf_state = C_FINALIZED;
+
jump_label_init();
static_call_init();
early_ioremap_init();
_
next prev parent reply other threads:[~2024-02-22 18:40 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-22 18:39 [RFC][PATCH 00/34] [RFC] x86: Rework system-wide configuration masquerading as per-cpu data Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 01/34] x86/xen: Explain why calling get_cpu_cap() so early is a hack Dave Hansen
2024-03-07 16:27 ` Borislav Petkov
2024-02-22 18:39 ` [RFC][PATCH 02/34] x86/xen: Remove early "debug" physical address lookups Dave Hansen
2024-03-07 17:01 ` Borislav Petkov
2024-03-11 13:16 ` Jürgen Groß
2024-02-22 18:39 ` [RFC][PATCH 03/34] x86/pci: Assume that clflush size is always provided Dave Hansen
2024-03-08 8:57 ` Borislav Petkov
2024-02-22 18:39 ` [RFC][PATCH 04/34] x86/mm: Introduce physical address limit helper Dave Hansen
2024-02-27 11:05 ` Huang, Kai
2024-02-22 18:39 ` [RFC][PATCH 05/34] x86/cpu: Move /proc per-cpu ->x86_phys_bits reference to global one Dave Hansen
2024-02-27 11:05 ` Huang, Kai
2024-02-22 18:39 ` [RFC][PATCH 06/34] x86/boot: Use consistent value for iomem_resource.end Dave Hansen
2024-02-27 10:59 ` Huang, Kai
2024-02-28 14:22 ` Zhang, Rui
2024-02-22 18:39 ` [RFC][PATCH 07/34] x86/mm: Introduce virtual address space limit helper Dave Hansen
2024-02-27 11:09 ` Huang, Kai
2024-02-22 18:39 ` [RFC][PATCH 08/34] x86/cpu: Add CLFLUSH size helper Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 09/34] x86/cpu: Introduce address configuration structure Dave Hansen
2024-02-27 23:47 ` Huang, Kai
2024-02-28 17:29 ` Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 10/34] x86/cpu/amd: Use new "address configuration" infrastructure Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 11/34] x86/cpu/intel: Prepare MKTME for " Dave Hansen
2024-02-23 11:33 ` Kirill A. Shutemov
2024-02-23 16:22 ` Dave Hansen
2024-02-26 12:14 ` Kirill A. Shutemov
2024-02-27 21:48 ` Huang, Kai
2024-02-28 15:20 ` Kirill A. Shutemov
2024-02-28 16:57 ` Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 12/34] x86/cpu/intel: Actually use "address configuration" infrastructure for MKTME Dave Hansen
2024-02-23 11:41 ` Kirill A. Shutemov
2024-02-23 16:16 ` Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 13/34] x86/boot: Use address reduction config to handle erratum Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 14/34] x86/cpu: Remove default physical address space settings Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 15/34] x86/cpu: Remove default x86_phys_bits assignment Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 16/34] x86/cpu: Move physical address limit out of cpuinfo_x86 Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 17/34] x86/cpu: Move virtual " Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 18/34] x86/cpu/centaur: Move cache alignment override to BSP init Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 19/34] x86/cpu: Introduce cache alignment multiplier Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 20/34] x86/cpu: Remove superfluous cache alignment assignments Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 21/34] x86/cpu: Consolidate CLFLUSH size setting Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 22/34] x86/cpu: Move CLFLUSH size into global config Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 23/34] x86/cpu: Move cache alignment configuration to global struct Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 24/34] x86/cpu: Establish 'min_cache_bits' configuration Dave Hansen
2024-02-22 18:39 ` [RFC][PATCH 25/34] x86/cpu: Move cache bits to global config Dave Hansen
2024-02-22 18:40 ` [RFC][PATCH 26/34] x86/cpu: Zap superfluous get_cpu_address_sizes() Dave Hansen
2024-02-22 18:40 ` Dave Hansen [this message]
2024-02-22 18:40 ` [RFC][PATCH 28/34] x86/cpu: Return sane defaults for early x86_config reads Dave Hansen
2024-02-22 18:40 ` [RFC][PATCH 29/34] x86/xen: Remove extra get_cpu_address_sizes() call Dave Hansen
2024-02-22 18:40 ` [RFC][PATCH 30/34] x86/cpu/centaur: Mark BSP init function as __init Dave Hansen
2024-02-22 18:40 ` [RFC][PATCH 31/34] x86/cpu/intel: " Dave Hansen
2024-02-22 18:40 ` [RFC][PATCH 32/34] x86/cpu/amd: Move memory encryption detection Dave Hansen
2024-02-22 18:40 ` [RFC][PATCH 33/34] x86/cpu: Make get_cpu_address_sizes() static and __init Dave Hansen
2024-02-22 18:40 ` [RFC][PATCH 34/34] x86/cpu: Mark new boot CPU and config structures appropriately Dave Hansen
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=20240222184002.690F68EF@davehans-spike.ostc.intel.com \
--to=dave.hansen@linux.intel.com \
--cc=bp@alien8.de \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--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