mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Chang S. Bae" <chang.seok.bae@intel.com>
To: linux-kernel@vger.kernel.org
Cc: x86@kernel.org, tglx@linutronix.de, mingo@redhat.com,
	bp@alien8.de, dave.hansen@linux.intel.com,
	chang.seok.bae@intel.com
Subject: [PATCH RFC 4/7] x86/microcode/intel: Prepare for microcode staging
Date: Tue,  1 Oct 2024 09:10:39 -0700	[thread overview]
Message-ID: <20241001161042.465584-5-chang.seok.bae@intel.com> (raw)
In-Reply-To: <20241001161042.465584-1-chang.seok.bae@intel.com>

When microcode staging is initiated, operations are carried out through
an MMIO interface. Each interface is independently discoverable per CPU
via the IA32_MCU_STAGING_MBOX_ADDR MSR, which points to a set of
dword-sized registers.

Software must first ensure the microcode image is dword-aligned, then
proceed to stage the update for each exposed MMIO space as specified.

Follow these two steps to arrange staging process. Identify each unique
MMIO interface by iterating over the CPUs and reading the MSR for each
one. While this process can be tedious, it remains simple enough and
acceptable in the slow path.

Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
---
Note:

1. Initially, a per-package and parallel staging invocation approach was
considered, but it seemed overly complex. Dave helped to identify a
simpler way.

2. Ideally, the staging_work() function would be as simple as a single
WRMSR execution. If this were the case, the staging flow could be
completed with this patch. From this perspective, the software handling
for interacting with the staging firmware has been separated from this
vendor code and moved into a new file dedicated to staging logic.
---
 arch/x86/kernel/cpu/microcode/intel.c    | 50 ++++++++++++++++++++++++
 arch/x86/kernel/cpu/microcode/internal.h |  5 +++
 2 files changed, 55 insertions(+)

diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index f3d534807d91..03c4b0e7e97c 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -299,6 +299,55 @@ static __init struct microcode_intel *scan_microcode(void *data, size_t size,
 	return size ? NULL : patch;
 }
 
+static inline u64 staging_addr(u32 cpu)
+{
+	u32 lo, hi;
+
+	rdmsr_on_cpu(cpu, MSR_IA32_MCU_STAGING_MBOX_ADDR, &lo, &hi);
+	return lo | ((u64)hi << 32);
+}
+
+static bool need_staging(u64 *mmio_addrs, u64 pa)
+{
+	unsigned int i;
+
+	for (i = 0; mmio_addrs[i] != 0; i++) {
+		if (mmio_addrs[i] == pa)
+			return false;
+	}
+	mmio_addrs[i] = pa;
+	return true;
+}
+
+static void staging_microcode(void)
+{
+	u64 *mmio_addrs, mmio_pa;
+	unsigned int totalsize;
+	int cpu;
+
+	totalsize = get_totalsize(&ucode_patch_late->hdr);
+	if (!IS_ALIGNED(totalsize, sizeof(u32)))
+		return;
+
+	mmio_addrs = kcalloc(nr_cpu_ids, sizeof(*mmio_addrs), GFP_KERNEL);
+	if (WARN_ON_ONCE(!mmio_addrs))
+		return;
+
+	for_each_cpu(cpu, cpu_online_mask) {
+		mmio_pa = staging_addr(cpu);
+
+		if (need_staging(mmio_addrs, mmio_pa) &&
+		    !staging_work(mmio_pa, ucode_patch_late, totalsize)) {
+			pr_err("Error: staging failed.\n");
+			goto out;
+		}
+	}
+
+	pr_info("Staging succeeded.\n");
+out:
+	kfree(mmio_addrs);
+}
+
 static enum ucode_state __apply_microcode(struct ucode_cpu_info *uci,
 					  struct microcode_intel *mc,
 					  u32 *cur_rev)
@@ -627,6 +676,7 @@ static struct microcode_ops microcode_intel_ops = {
 	.collect_cpu_info	= collect_cpu_info,
 	.apply_microcode	= apply_microcode_late,
 	.finalize_late_load	= finalize_late_load,
+	.staging_microcode	= staging_microcode,
 	.use_nmi		= IS_ENABLED(CONFIG_X86_64),
 };
 
diff --git a/arch/x86/kernel/cpu/microcode/internal.h b/arch/x86/kernel/cpu/microcode/internal.h
index cb58e83e4934..06c3c8db4ceb 100644
--- a/arch/x86/kernel/cpu/microcode/internal.h
+++ b/arch/x86/kernel/cpu/microcode/internal.h
@@ -120,6 +120,11 @@ void load_ucode_intel_bsp(struct early_load_data *ed);
 void load_ucode_intel_ap(void);
 void reload_ucode_intel(void);
 struct microcode_ops *init_intel_microcode(void);
+static inline bool staging_work(u64 mmio_pa, void *ucode_ptr, unsigned int totalsize)
+{
+	pr_debug_once("Need to implement the Staging code.\n");
+	return false;
+}
 #else /* CONFIG_CPU_SUP_INTEL */
 static inline void load_ucode_intel_bsp(struct early_load_data *ed) { }
 static inline void load_ucode_intel_ap(void) { }
-- 
2.43.0


  parent reply	other threads:[~2024-10-01 16:11 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-01 16:10 [PATCH RFC 0/7] x86/microcode: Support for Intel Staging Feature Chang S. Bae
2024-10-01 16:10 ` [PATCH RFC 1/7] x86/microcode/intel: Remove unnecessary cache writeback and invalidation Chang S. Bae
2024-10-25 16:24   ` [tip: x86/microcode] " tip-bot2 for Chang S. Bae
2024-10-01 16:10 ` [PATCH RFC 2/7] x86/microcode: Introduce staging option to reduce late-loading latency Chang S. Bae
2024-11-04 10:45   ` Borislav Petkov
2024-10-01 16:10 ` [PATCH RFC 3/7] x86/msr-index: Define MSR index and bit for the microcode staging feature Chang S. Bae
2024-10-01 16:10 ` Chang S. Bae [this message]
2024-11-04 11:16   ` [PATCH RFC 4/7] x86/microcode/intel: Prepare for microcode staging Borislav Petkov
2024-11-04 16:08     ` Dave Hansen
2024-11-04 18:34       ` Chang S. Bae
2024-11-04 20:10         ` Chang S. Bae
2024-11-06 18:23           ` [PATCH] cpufreq: Simplify MSR read on the boot CPU Chang S. Bae
2024-11-12 20:44             ` Rafael J. Wysocki
2024-11-06 18:28     ` [PATCH RFC 4/7] x86/microcode/intel: Prepare for microcode staging Chang S. Bae
2024-11-07  1:12       ` Thomas Gleixner
2024-11-08 22:42         ` Chang S. Bae
2024-11-08 22:51         ` Dave Hansen
2024-10-01 16:10 ` [PATCH RFC 5/7] x86/microcode/intel_staging: Implement staging logic Chang S. Bae
2024-10-01 16:10 ` [PATCH RFC 6/7] x86/microcode/intel_staging: Support mailbox data transfer Chang S. Bae
2024-10-01 16:10 ` [PATCH RFC 7/7] x86/microcode/intel: Enable staging when available Chang S. Bae
2024-12-11  1:42 ` [PATCH 0/6] x86/microcode: Support for Intel Staging Feature Chang S. Bae
2024-12-11  1:42   ` [PATCH 1/6] x86/microcode: Introduce staging option to reduce late-loading latency Chang S. Bae
2025-02-17 13:33     ` Borislav Petkov
2025-02-18  7:51       ` Chang S. Bae
2025-02-18 11:36         ` Borislav Petkov
2025-02-18 15:16     ` Dave Hansen
2024-12-11  1:42   ` [PATCH 2/6] x86/msr-index: Define MSR index and bit for the microcode staging feature Chang S. Bae
2025-02-26 17:19     ` Borislav Petkov
2024-12-11  1:42   ` [PATCH 3/6] x86/microcode/intel: Prepare for microcode staging Chang S. Bae
2025-02-26 17:52     ` Borislav Petkov
2024-12-11  1:42   ` [PATCH 4/6] x86/microcode/intel_staging: Implement staging logic Chang S. Bae
2025-02-18 20:16     ` Dave Hansen
2025-02-26 17:56     ` Borislav Petkov
2024-12-11  1:42   ` [PATCH 5/6] x86/microcode/intel_staging: Support mailbox data transfer Chang S. Bae
2025-02-18 20:54     ` Dave Hansen
2025-03-20 23:42       ` Chang S. Bae
2024-12-11  1:42   ` [PATCH 6/6] x86/microcode/intel: Enable staging when available Chang S. Bae
2025-02-07 18:37   ` [PATCH 0/6] x86/microcode: Support for Intel Staging Feature Chang S. Bae
2025-02-28 22:27     ` Colin Mitchell
2025-02-28 22:52       ` Borislav Petkov
2025-02-28 23:23         ` Dave Hansen
2025-03-26 21:29           ` Colin Mitchell
2025-04-02 17:14             ` Dave Hansen
2025-02-28 23:05       ` 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=20241001161042.465584-5-chang.seok.bae@intel.com \
    --to=chang.seok.bae@intel.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@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

all inboxes | Powered by JetHome®