mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Chang S. Bae" <chang.seok.bae@intel.com>
To: Borislav Petkov <bp@alien8.de>
Cc: <linux-kernel@vger.kernel.org>, <x86@kernel.org>,
	<tglx@linutronix.de>, <mingo@redhat.com>,
	<dave.hansen@linux.intel.com>, <chao.gao@intel.com>,
	<abusse@amazon.de>
Subject: Re: [PATCH v5 3/7] x86/microcode/intel: Establish staging control logic
Date: Thu, 4 Sep 2025 17:04:24 -0700	[thread overview]
Message-ID: <641f321d-4266-46c0-9383-d06bcb909529@intel.com> (raw)
In-Reply-To: <20250904121318.GKaLmCXlU4kwhsxG9h@fat_crate.local>

[-- Attachment #1: Type: text/plain, Size: 2587 bytes --]

On 9/4/2025 5:13 AM, Borislav Petkov wrote:
> On Sat, Aug 23, 2025 at 08:52:06AM -0700, Chang S. Bae wrote:
>>
>> Also, define cpu_primary_thread_mask for the CONFIG_SMP=n case, allowing
>> consistent use when narrowing down primary threads to locate the
>> per-package interface.
> 
> This paragraph is stale now and can go.

Ah, right. Sorry, I had to chop it out.

>> diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
>> index b65c3ba5fa14..0356155f9264 100644
>> --- a/arch/x86/include/asm/msr-index.h
>> +++ b/arch/x86/include/asm/msr-index.h
>> @@ -913,6 +913,8 @@
>>   #define MSR_IA32_UCODE_WRITE		0x00000079
>>   #define MSR_IA32_UCODE_REV		0x0000008b
>>   
>> +#define MSR_IA32_MCU_STAGING_MBOX_ADDR	0x000007a5
> 
> Doesn't look sorted to me.

Okay, I think this 'MCU' looks a bit fuzzy. Intel folks already use this 
acronym elsewhere (e.g. MSR_IA32_MCU_OPT_CTRL). It might be clearer to 
consolidate them under one section, like:

/* Intel microcode update MSRs */
#define MSR_IA32_MCU_OPT_CTRL           0x00000123
#define MSR_IA32_MCU_ENUMERATION        0x0000007b  <- patch7 adds this
#define MSR_IA32_MCU_STAGING_MBOX_ADDR  0x000007a5
...

>> +	/*
>> +	 * The MMIO address is unique per package, and all the SMT
>> +	 * primary threads are online here. Find each MMIO space by
>> +	 * their package ids to avoid duplicate staging.
>> +	 */
>> +	for_each_cpu(cpu, cpu_primary_thread_mask) {
>> +		if (topology_logical_package_id(cpu) == pkg_id)
>> +			continue;
> 
> <---- newline here.

Fixed. Thanks.

>> +		ret = do_stage(mmio_pa);
>> +		if (ret != UCODE_OK) {
>> +			pr_err("Error: staging failed with %s for CPU%d at package %u.\n",
>> +			       ret == UCODE_TIMEOUT ? "timeout" : "error state",
> 
> What does "error state" mean?
> 
> Are we going to dump additional error state so that it is clear why it failed?

Yeah, right. The wording "error state" is vague.

The next two patches in this series introduce helpers that return an 
error code and *also* update this ucode_state. The latter could go away. 
Instead, the error code could be just down through here and decoded like:

static const char *staging_errstr(int code)
{
   switch (code) {
   case -ETIMEDOUT:	return "timeout";
   ...
   default:		return "unknown error";
   }
}

static void stage_microcode(void)
{
   ...

   err = do_stage(mmio_pa);
   if (err) {
     pr_err("Error: staging failed with %s for CPU%d at package %u.\n",
            staging_errstr(err), cpu, pkg_id);
     return;
   }
}

I've attached a diff on top of V5 to picture what it will look like.

[-- Attachment #2: tmp.diff --]
[-- Type: text/plain, Size: 5703 bytes --]

diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 455b50514d87..ae4b08e71e20 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -98,7 +98,6 @@ struct extended_sigtable {
  * @chunk_size:		Size of each data piece
  * @bytes_sent:		Total bytes transmitted so far
  * @offset:		Current offset in the microcode image
- * @state:		Current state of the staging process
  */
 struct staging_state {
 	void __iomem		*mmio_base;
@@ -106,7 +105,6 @@ struct staging_state {
 	unsigned int		chunk_size;
 	unsigned int		bytes_sent;
 	unsigned int		offset;
-	enum ucode_state	state;
 };
 
 #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)
@@ -425,7 +423,7 @@ static inline unsigned int calc_next_chunk_size(unsigned int ucode_len, unsigned
  * Update the chunk size and decide whether another chunk can be sent.
  * This accounts for remaining data and retry limits.
  */
-static bool can_send_next_chunk(struct staging_state *ss)
+static bool can_send_next_chunk(struct staging_state *ss, int *err)
 {
 	ss->chunk_size = calc_next_chunk_size(ss->ucode_len, ss->offset);
 	/*
@@ -445,10 +443,11 @@ static bool can_send_next_chunk(struct staging_state *ss)
 	 * likely stuck and mark the state as timeout.
 	 */
 	if (ss->bytes_sent + ss->chunk_size > ss->ucode_len * 2) {
-		ss->state = UCODE_TIMEOUT;
+		*err = -ETIMEDOUT;
 		return false;
 	}
 
+	*err = 0;
 	return true;
 }
 
@@ -465,9 +464,9 @@ static inline bool is_end_offset(u32 offset)
  * the end offset, or no more transactions are permitted (retry limit
  * reached).
  */
-static inline bool staging_is_complete(struct staging_state *ss)
+static inline bool staging_is_complete(struct staging_state *ss, int *err)
 {
-	return is_end_offset(ss->offset) || !can_send_next_chunk(ss);
+	return is_end_offset(ss->offset) || !can_send_next_chunk(ss, err);
 }
 
 /*
@@ -489,21 +488,16 @@ static int wait_for_transaction(struct staging_state *ss)
 	}
 
 	/* Check for explicit error response */
-	if (status & MASK_MBOX_STATUS_ERROR) {
-		ss->state = UCODE_ERROR;
-		return -EPROTO;
-	}
+	if (status & MASK_MBOX_STATUS_ERROR)
+		return -EIO;
 
 	/*
 	 * Hardware is neither responded to the action nor signaled any
 	 * error. Treat this as timeout.
 	 */
-	if (!(status & MASK_MBOX_STATUS_READY)) {
-		ss->state = UCODE_TIMEOUT;
+	if (!(status & MASK_MBOX_STATUS_READY))
 		return -ETIMEDOUT;
-	}
 
-	ss->state = UCODE_OK;
 	return 0;
 }
 
@@ -545,7 +539,6 @@ static int fetch_next_offset(struct staging_state *ss)
 	const u64 expected_header = MBOX_HEADER(MBOX_HEADER_SIZE + MBOX_RESPONSE_SIZE);
 	u32 offset, status;
 	u64 header;
-	int err;
 
 	/*
 	 * The 'response' mailbox returns three fields, in order:
@@ -558,55 +551,42 @@ static int fetch_next_offset(struct staging_state *ss)
 	status = read_mbox_dword(ss->mmio_base);
 
 	/* All valid responses must start with the expected header. */
-	if (header != expected_header) {
-		pr_err_once("staging: invalid response header\n");
-		err = -EINVAL;
-		goto err_out;
-	}
+	if (header != expected_header)
+		return -EBADR;
 
 	/*
 	 * Verify the offset: If not at the end marker, it must not
 	 * exceed the microcode image length
 	 */
-	if (!is_end_offset(offset) && offset > ss->ucode_len) {
-		pr_err_once("staging: invalid response offset\n");
-		err = -EINVAL;
-		goto err_out;
-	}
+	if (!is_end_offset(offset) && offset > ss->ucode_len)
+		return -EINVAL;
 
 	/* Hardware may report errors explicitly in the status field */
-	if (status & MASK_MBOX_RESP_ERROR) {
-		err = -EPROTO;
-		goto err_out;
-	}
+	if (status & MASK_MBOX_RESP_ERROR)
+		return -EPROTO;
 
 	ss->offset = offset;
-	ss->state  = UCODE_OK;
 	return 0;
-
-err_out:
-	ss->state = UCODE_ERROR;
-	return err;
 }
 
 /*
  * Handle the staging process using the mailbox MMIO interface. The
  * microcode image is transferred in chunks until completion. Return the
- * result state.
+ * error code.
  */
-static enum ucode_state do_stage(u64 mmio_pa)
+static int do_stage(u64 mmio_pa)
 {
 	struct staging_state ss = {};
 	int err;
 
 	ss.mmio_base = ioremap(mmio_pa, MBOX_REG_NUM * MBOX_REG_SIZE);
 	if (WARN_ON_ONCE(!ss.mmio_base))
-		return UCODE_ERROR;
+		return -EADDRNOTAVAIL;
 
 	init_stage(&ss);
 
 	/* Perform the staging process while within the retry limit */
-	while (!staging_is_complete(&ss)) {
+	while (!staging_is_complete(&ss, &err)) {
 		/* Send a chunk of microcode each time: */
 		err = send_data_chunk(&ss, ucode_patch_late);
 		if (err)
@@ -622,17 +602,25 @@ static enum ucode_state do_stage(u64 mmio_pa)
 
 	iounmap(ss.mmio_base);
 
-	/*
-	 * The helpers update ss.state on error. The final state is
-	 * returned to the caller.
-	 */
-	return ss.state;
+	return err;
+}
+
+static const char *staging_errstr(int code)
+{
+	switch (code) {
+	case -EBADR:		return "invalid response header";
+	case -EINVAL:		return "invalid next offset";
+	case -EIO:		return "transaction error";
+	case -ETIMEDOUT:	return "timeout";
+	case -EPROTO:		return "response error";
+	case -EADDRNOTAVAIL:	return "ioremap() failure";
+	default:		return "unknown error";
+	};
 }
 
 static void stage_microcode(void)
 {
 	unsigned int pkg_id = UINT_MAX;
-	enum ucode_state ret;
 	int cpu, err;
 	u64 mmio_pa;
 
@@ -656,11 +644,10 @@ static void stage_microcode(void)
 		if (WARN_ON_ONCE(err))
 			return;
 
-		ret = do_stage(mmio_pa);
-		if (ret != UCODE_OK) {
+		err = do_stage(mmio_pa);
+		if (err) {
 			pr_err("Error: staging failed with %s for CPU%d at package %u.\n",
-			       ret == UCODE_TIMEOUT ? "timeout" : "error state",
-			       cpu, pkg_id);
+			       staging_errstr(err), cpu, pkg_id);
 			return;
 		}
 	}

  reply	other threads:[~2025-09-05  0:04 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-20 23:40 [PATCH v2 0/6] x86: Support for Intel Microcode Staging Feature Chang S. Bae
2025-03-20 23:40 ` [PATCH v2 1/6] x86/microcode: Introduce staging step to reduce late-loading time Chang S. Bae
2025-03-20 23:40 ` [PATCH v2 2/6] x86/microcode/intel: Define staging state struct Chang S. Bae
2025-03-20 23:40 ` [PATCH v2 3/6] x86/microcode/intel: Establish staging control logic Chang S. Bae
2025-03-21 21:18   ` [PATCH v2a " Chang S. Bae
2025-03-26  7:35     ` Chao Gao
2025-03-26 18:43       ` Chang S. Bae
2025-03-27  1:44         ` Chao Gao
2025-03-28 14:12           ` Chang S. Bae
2025-03-20 23:40 ` [PATCH v2 4/6] x86/microcode/intel: Implement staging handler Chang S. Bae
2025-03-21  0:15   ` Dave Hansen
2025-03-21 21:19     ` [PATCH v2a " Chang S. Bae
2025-03-26  8:34       ` Chao Gao
2025-03-26 18:43         ` Chang S. Bae
2025-03-21 21:19     ` [PATCH v2 " Chang S. Bae
2025-03-20 23:40 ` [PATCH v2 5/6] x86/microcode/intel: Support mailbox transfer Chang S. Bae
2025-03-21 21:19   ` [PATCH v2a " Chang S. Bae
2025-03-27  3:32   ` [PATCH v2 " Chao Gao
2025-03-27 14:11     ` Chang S. Bae
2025-03-31 19:16     ` Dave Hansen
2025-03-20 23:40 ` [PATCH v2 6/6] x86/microcode/intel: Enable staging when available Chang S. Bae
2025-04-09 23:27 ` [PATCH v3 0/6] x86: Support for Intel Microcode Staging Feature Chang S. Bae
2025-04-09 23:27   ` [PATCH v3 1/6] x86/microcode: Introduce staging step to reduce late-loading time Chang S. Bae
2025-04-09 23:27   ` [PATCH v3 2/6] x86/microcode/intel: Establish staging control logic Chang S. Bae
2025-04-09 23:27   ` [PATCH v3 3/6] x86/microcode/intel: Define staging state struct Chang S. Bae
2025-04-09 23:27   ` [PATCH v3 4/6] x86/microcode/intel: Implement staging handler Chang S. Bae
2025-04-09 23:27   ` [PATCH v3 5/6] x86/microcode/intel: Support mailbox transfer Chang S. Bae
2025-04-16 14:14     ` Chao Gao
2025-04-16 17:22       ` Chang S. Bae
2025-04-16 17:37         ` Dave Hansen
2025-04-09 23:27   ` [PATCH v3 6/6] x86/microcode/intel: Enable staging when available Chang S. Bae
2025-08-13 17:26   ` [PATCH v4 0/6] x86: Support for Intel Microcode Staging Feature Chang S. Bae
2025-08-13 17:26     ` [PATCH v4 1/6] x86/microcode: Introduce staging step to reduce late-loading time Chang S. Bae
2025-08-18  7:45       ` Chao Gao
2025-08-13 17:26     ` [PATCH v4 2/6] x86/microcode/intel: Establish staging control logic Chang S. Bae
2025-08-13 18:21       ` Dave Hansen
2025-08-13 20:46         ` Chang S. Bae
2025-08-13 20:55           ` Dave Hansen
2025-08-14 18:30             ` Chang S. Bae
2025-08-22 22:39             ` [PATCH] x86/cpu/topology: Make primary thread mask available with SMP=n Chang S. Bae
2025-08-23 16:05               ` Chang S. Bae
2025-08-22 22:39         ` [PATCH v4a 2/6] x86/microcode/intel: Establish staging control logic Chang S. Bae
2025-08-22 23:34           ` Dave Hansen
2025-08-13 17:26     ` [PATCH v4 3/6] x86/microcode/intel: Define staging state struct Chang S. Bae
2025-08-13 18:25       ` Dave Hansen
2025-08-22 22:39         ` [PATCH v4a " Chang S. Bae
2025-08-13 17:26     ` [PATCH v4 4/6] x86/microcode/intel: Implement staging handler Chang S. Bae
2025-08-13 18:44       ` Dave Hansen
2025-08-22 22:39         ` [PATCH v4a " Chang S. Bae
2025-08-13 17:26     ` [PATCH v4 5/6] x86/microcode/intel: Support mailbox transfer Chang S. Bae
2025-08-13 19:07       ` Dave Hansen
2025-08-22 22:40         ` [PATCH v4a " Chang S. Bae
2025-08-13 17:26     ` [PATCH v4 6/6] x86/microcode/intel: Enable staging when available Chang S. Bae
2025-08-18  8:35       ` Chao Gao
2025-08-22 22:42         ` Chang S. Bae
2025-08-13 19:08     ` [PATCH v4 0/6] x86: Support for Intel Microcode Staging Feature Dave Hansen
2025-08-23 15:52     ` [PATCH v5 0/7] " Chang S. Bae
2025-08-23 15:52       ` [PATCH v5 1/7] x86/cpu/topology: Make primary thread mask available with SMP=n Chang S. Bae
2025-08-23 15:52       ` [PATCH v5 2/7] x86/microcode: Introduce staging step to reduce late-loading time Chang S. Bae
2025-09-04 12:08         ` Borislav Petkov
2025-09-05  0:06           ` Chang S. Bae
2025-08-23 15:52       ` [PATCH v5 3/7] x86/microcode/intel: Establish staging control logic Chang S. Bae
2025-09-04 12:13         ` Borislav Petkov
2025-09-05  0:04           ` Chang S. Bae [this message]
2025-09-05 11:13             ` Borislav Petkov
2025-09-05 16:31               ` Chang S. Bae
2025-08-23 15:52       ` [PATCH v5 4/7] x86/microcode/intel: Define staging state struct Chang S. Bae
2025-09-04 13:48         ` Borislav Petkov
2025-09-05  0:05           ` Chang S. Bae
2025-08-23 15:52       ` [PATCH v5 5/7] x86/microcode/intel: Implement staging handler Chang S. Bae
2025-09-10 18:33         ` Borislav Petkov
2025-09-10 21:31           ` Chang S. Bae
2025-08-23 15:52       ` [PATCH v5 6/7] x86/microcode/intel: Support mailbox transfer Chang S. Bae
2025-09-12 16:34         ` Borislav Petkov
2025-09-13  0:51           ` Chang S. Bae
2025-09-13 19:01             ` Borislav Petkov
2025-08-23 15:52       ` [PATCH v5 7/7] x86/microcode/intel: Enable staging when available Chang S. Bae
2025-08-26 22:13       ` [PATCH v5 0/7] x86: Support for Intel Microcode Staging Feature Luck, Tony
2025-08-26 22:15         ` Chang S. Bae

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=641f321d-4266-46c0-9383-d06bcb909529@intel.com \
    --to=chang.seok.bae@intel.com \
    --cc=abusse@amazon.de \
    --cc=bp@alien8.de \
    --cc=chao.gao@intel.com \
    --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®