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>
Subject: Re: [PATCH RFC 4/7] x86/microcode/intel: Prepare for microcode staging
Date: Wed, 6 Nov 2024 10:28:25 -0800	[thread overview]
Message-ID: <d8d3959a-8c38-4ce4-885d-6a1e40219831@intel.com> (raw)
In-Reply-To: <20241104111630.GSZyitDuXnBYmEFxvo@fat_crate.local>

On 11/4/2024 3:16 AM, Borislav Petkov wrote:
> On Tue, Oct 01, 2024 at 09:10:39AM -0700, Chang S. Bae wrote:
>> +
>> +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;
> 
> This is a weird function - its name is supposed to mean it queries something
> but then it has side effects too.

I think I've carved out a bit more out of the loop and convoluted them
into a single function.

Instead, let the helper simply find the position in the array,

         static unsigned int find_pos(u64 *mmio_addrs, u64 mmio_pa)
         {
                 unsigned int i;

                 for (i = 0; mmio_addrs[i] != 0; i++) {
                         if (mmio_addrs[i] == mmio_pa)
                                 break;
                 }
                 return i;
         }

and update the array from there:

         static void stage_microcode(void)
         {
                 unsigned int pos;
                 ...
                 for_each_cpu(cpu, cpu_online_mask) {
                         /* set 'mmio_pa' from RDMSR */

                         pos = find_pos(mmio_addrs, mmio_pa);
                         if (mmio_addrs[pos] == mmio_pa)
                                 continue;

                         /* do staging */

                         mmio_addrs[pos] = mmio_pa;
                 }
                 ...
         }

Or, even the loop code can include it:

         for_each_cpu(...) {
                 /* set 'mmio_pa' from RDMSR */

                 /* Find either the last position or a match */
                 for (i = 0; mmio_addrs[i] != 0 && mmio_addrs[i] != 
mmio_pa; i++);

                 if (mmio_addrs[i] == mmio_pa)
                         continue;

                 /* do staging */

                 mmio_addrs[i] = mmio_pa;
         }

Maybe, if this unusual one line for-loop is not an issue, this can make
the code simple. Otherwise, at least the helper should remain doing one
thing.

    >> +	for_each_cpu(cpu, cpu_online_mask) {
> 
> Oh great, and someone went and offlined one of those CPUs right here. Fun.

Yes, offlining matters. Let me summarize a few things related to the
patchset for the record:

   *  The staging flow is tiggered by load_late_locked(), which already
      holds cpus_read_lock() [1].

   *  When any SMT primary threads is offlined, setup_cpus() makes it
      exit right away [2].

   *  When an offlined CPU is brought up online, it follows the early
      loading path, which does not include staging.

[1]: 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/microcode/core.c#n705
[2]: 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/microcode/core.c#n658

> 
>> +		mmio_pa = staging_addr(cpu);
>> +
>> +		if (need_staging(mmio_addrs, mmio_pa) &&
>> +		    !staging_work(mmio_pa, ucode_patch_late, totalsize)) {
> 
> do_stage()
> 
>> +			pr_err("Error: staging failed.\n");
> 
> 							... on CPU%d, err_val: 0x%x"\n"
> 
> perhaps?
> 
> For more info debugging something like that?

Maybe, either one of two ways:

The work function remains returning bool value, then it can print the
error message from there.

         bool do_stage(...)
         {
                 ...
                 pr_err("Error: staging failed on CPU%d, with %s.\n",
                         smp_processor_id(), state == UCODE_TIMEOUT ? 
"timeout" : "error");
                 return false
         }

Then, this function may simply return on error.

         static void stage_microcode(void)
         {
                 ...
                 if (!do_stage(...))
                         goto out;
                 ...
         out:
                 kfree(mmio_addrs);
         }

Or, let the work function return a value like an enum ucode_state
indicating the status, and print the error message here.

         static void stage_microcode(void)
         {
                 enum ucode_state state;

                 ...
                 state = do_stage(...);
                 if (state != UCODE_OK)
                         goto err_out;

         err_out:
                 pr_err("Error: ...);
         out:
                 ...
         }

> 
>> +			goto out;
>> +		}
>> +	}
>> +
>> +	pr_info("Staging succeeded.\n");
> 
> 		"Staging of patch revision 0x%x succeeded.\n"...
> 
> more user-friendly.

Yes, that seems to be useful to put it on:

+       pr_info("Staging of patch revision 0x%x succeeded.\n",
+               ((struct microcode_header_intel *)ucode_patch_late)->rev);

If successful, users will see something like this:

[   25.352716] microcode: Staging is available.
[   25.357684] microcode: Current revision: 0x1234
[  136.203269] microcode: Staging of patch revision 0xabcd succeeded.
[  137.398491] microcode: load: updated on xx primary CPUs with yy siblings
[  137.427386] microcode: revision: 0x1234 -> 0xabcd

Thanks,
Chang

  parent reply	other threads:[~2024-11-06 18:28 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 ` [PATCH RFC 4/7] x86/microcode/intel: Prepare for microcode staging Chang S. Bae
2024-11-04 11:16   ` 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     ` Chang S. Bae [this message]
2024-11-07  1:12       ` [PATCH RFC 4/7] x86/microcode/intel: Prepare for microcode staging 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=d8d3959a-8c38-4ce4-885d-6a1e40219831@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®