All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
To: Andrew Cooper <andrew.cooper3@citrix.com>,
	<xen-devel@lists.xenproject.org>
Cc: "Doug Goldstein" <cardoe@cardoe.com>,
	"Stefano Stabellini" <sstabellini@kernel.org>,
	"Anthony PERARD" <anthony.perard@vates.tech>,
	"Michal Orzel" <michal.orzel@amd.com>,
	"Jan Beulich" <jbeulich@suse.com>,
	"Julien Grall" <julien@xen.org>,
	"Roger Pau Monné" <roger.pau@citrix.com>,
	"Daniel P. Smith" <dpsmith@apertussolutions.com>,
	"Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>,
	Xen-devel <xen-devel-bounces@lists.xenproject.org>
Subject: Re: [PATCH v2 2/2] x86/ucode: Add Kconfig option to remove microcode loading
Date: Mon, 12 Jan 2026 19:47:24 +0100	[thread overview]
Message-ID: <DFMU244K4E7W.6M0TQ5AI1TUE@amd.com> (raw)
In-Reply-To: <96f4f3fe-46c4-4854-af55-d5adea07c847@citrix.com>

On Mon Jan 12, 2026 at 6:15 PM CET, Andrew Cooper wrote:
> On 12/01/2026 3:02 pm, Alejandro Vallejo wrote:
>>  automation/gitlab-ci/build.yaml    |  2 +-
>>  docs/misc/efi.pandoc               |  2 ++
>>  docs/misc/xen-command-line.pandoc  |  4 ++--
>>  xen/arch/x86/Kconfig               | 14 +++++++++++++-
>>  xen/arch/x86/cpu/microcode/amd.c   | 22 +++++++++++++---------
>>  xen/arch/x86/cpu/microcode/core.c  | 25 ++++++++++++++++++-------
>>  xen/arch/x86/cpu/microcode/intel.c | 16 +++++++++-------
>>  xen/arch/x86/efi/efi-boot.h        |  3 ++-
>>  xen/arch/x86/platform_hypercall.c  |  2 ++
>>  xen/common/Makefile                |  3 ++-
>>  10 files changed, 64 insertions(+), 29 deletions(-)
>
> Much nicer in terms of (non) invasiveness.
>
> First, please split the rename of CONFIG_UCODE_SCAN_DEFAULT into an
> earlier patch.

Sure

>
>> diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
>> index 50d7edb248..866fa2f951 100644
>> --- a/docs/misc/xen-command-line.pandoc
>> +++ b/docs/misc/xen-command-line.pandoc
>> @@ -2748,7 +2748,7 @@ performance.
>>  ### ucode
>>  > `= List of [ <integer> | scan=<bool>, nmi=<bool>, digest-check=<bool> ]`
>>  
>> -    Applicability: x86
>> +    Applicability: x86 with CONFIG_MICROCODE_LOADING active
>>      Default: `scan` is selectable via Kconfig, `nmi,digest-check`
>
> You want to include this too:
>
> diff --git a/docs/admin-guide/microcode-loading.rst b/docs/admin-guide/microcode-loading.rst
> index a07e25802fab..91668e6f9b3f 100644
> --- a/docs/admin-guide/microcode-loading.rst
> +++ b/docs/admin-guide/microcode-loading.rst
> @@ -23,6 +23,9 @@ TSX errata which necessitated disabling the feature entirely), or the addition
>  of brand new features (e.g. the Spectre v2 controls to work around speculative
>  execution vulnerabilities).
>  
> +Microcode loading support in Xen is controlled by the
> +``CONFIG_MICROCODE_LOADING`` Kconfig option.

Ack

> +
>  
>  Boot time microcode loading
>  ---------------------------
>
>
> while changing the docs.
>
>>  
>>  Controls for CPU microcode loading. For early loading, this parameter can
>> @@ -2773,7 +2773,7 @@ microcode in the cpio name space must be:
>>    - on AMD  : kernel/x86/microcode/AuthenticAMD.bin
>>  When using xen.efi, the `ucode=<filename>` config file setting takes
>>  precedence over `scan`. The default value for `scan` is set with
>> -`CONFIG_UCODE_SCAN_DEFAULT`.
>> +`CONFIG_MICROCODE_SCAN_DEFAULT`.
>>  
>>  'nmi' determines late loading is performed in NMI handler or just in
>>  stop_machine context. In NMI handler, even NMIs are blocked, which is
>> diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
>> index c808c989fc..1353ec9a3f 100644
>> --- a/xen/arch/x86/Kconfig
>> +++ b/xen/arch/x86/Kconfig
>> @@ -331,8 +331,20 @@ config REQUIRE_NX
>>  	  was unavailable. However, if enabled, Xen will no longer boot on
>>  	  any CPU which is lacking NX support.
>>  
>> -config UCODE_SCAN_DEFAULT
>> +config MICROCODE_LOADING
>> +	bool "Microcode loading"
>> +	default y
>> +	help
>> +	  Support updating the microcode revision of available CPUs with a newer
>> +	  vendor-provided microcode blob. Microcode updates address some classes of
>> +	  silicon defects. It's a very common delivery mechanism for fixes or
>> +	  workarounds for speculative execution vulnerabilities.
>> +
>> +	  If unsure, say Y.
>
> Please don't re-iterate the default.  It's a waste.  As to the main
> text, that's not great for the target audience of a distro packager /
> power user.  How about:
>
> --8<--
> Microcode updates for CPUs fix errata and provide new functionality for
> software to work around bugs, such as the speculative execution
> vulnerabilities.  It is common for OSes to carry updated microcode as
> software tends to get updated more frequently than firmware.
>
> For embedded environments where a full firmware/software stack is being
> provided, it might not be necessary for Xen to need to load microcode
> itself.
> --8<--

Sure. I don't mind.

>
>> diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c
>> index fe47c3a6c1..aec99834fd 100644
>> --- a/xen/arch/x86/cpu/microcode/core.c
>> +++ b/xen/arch/x86/cpu/microcode/core.c
>> @@ -44,6 +44,9 @@
>>  
>>  #include "private.h"
>>  
>> +#define can_apply_microcode(ops) (IS_ENABLED(CONFIG_MICROCODE_LOADING) && \
>> +                                  (ops).apply_microcode)
>
> I don't think this is a useful macro.  It's used 3 times, despite ...
>
>> @@ -613,6 +618,7 @@ static long cf_check ucode_update_hcall_cont(void *data)
>>      return ret;
>>  }
>>  
>> +#ifdef CONFIG_MICROCODE_LOADING
>>  int ucode_update_hcall(XEN_GUEST_HANDLE(const_void) buf,
>>                         unsigned long len, unsigned int flags)
>>  {
>> @@ -622,7 +628,7 @@ int ucode_update_hcall(XEN_GUEST_HANDLE(const_void) buf,
>>      if ( flags & ~XENPF_UCODE_FORCE )
>>          return -EINVAL;
>>  
>> -    if ( !ucode_ops.apply_microcode )
>> +    if ( !can_apply_microcode(ucode_ops) )
>>          return -EINVAL;
>>  
>>      buffer = xmalloc_flex_struct(struct ucode_buf, buffer, len);
>> @@ -645,6 +651,7 @@ int ucode_update_hcall(XEN_GUEST_HANDLE(const_void) buf,
>>       */
>>      return continue_hypercall_on_cpu(0, ucode_update_hcall_cont, buffer);
>>  }
>> +#endif /* CONFIG_MICROCODE_LOADING */
>
> ... this use being redundant.  Just expand it for the two other cases
> and consistently use IS_ENABLED() in view.

Ack.

>
>> @@ -907,10 +916,12 @@ int __init early_microcode_init(struct boot_info *bi)
>>       *
>>       * Take the hint in either case and ignore the microcode interface.
>>       */
>> -    if ( !ucode_ops.apply_microcode || this_cpu(cpu_sig).rev == ~0 )
>> +    if ( !can_apply_microcode(ucode_ops) || this_cpu(cpu_sig).rev == ~0 )
>>      {
>>          printk(XENLOG_INFO "Microcode loading disabled due to: %s\n",
>> -               ucode_ops.apply_microcode ? "rev = ~0" : "HW toggle");
>> +               !IS_ENABLED(CONFIG_MICROCODE_LOADING) ? "not compiled in" :
>> +               ucode_ops.apply_microcode             ? "rev = ~0"        :
>> +                                                       "HW toggle");
>>          ucode_ops.apply_microcode = NULL;
>>          return -ENODEV;
>>      }
>
> Don't complicate this messy printk() further.  Just exit early; it's not
> interesting to read "not loading microcode because it's not compiled in".
>
> This is a rare example of a subsystem where it remains partially
> compiled in, and it's even possible to write such a printk().

Ack.

>
>> diff --git a/xen/arch/x86/cpu/microcode/intel.c b/xen/arch/x86/cpu/microcode/intel.c
>> index 281993e725..d9895018b4 100644
>> --- a/xen/arch/x86/cpu/microcode/intel.c
>> +++ b/xen/arch/x86/cpu/microcode/intel.c
>> @@ -404,21 +404,23 @@ static bool __init can_load_microcode(void)
>>      return !(mcu_ctrl & MCU_CONTROL_DIS_MCU_LOAD);
>>  }
>>  
>> -static const char __initconst intel_cpio_path[] =
>> +static const char __initconst __maybe_unused intel_cpio_path[] =
>>      "kernel/x86/microcode/GenuineIntel.bin";
>>  
>>  static const struct microcode_ops __initconst_cf_clobber intel_ucode_ops = {
>> -    .cpu_request_microcode            = cpu_request_microcode,
>>      .collect_cpu_info                 = collect_cpu_info,
>> +#ifdef CONFIG_MICROCODE_LOADING
>> +    .cpu_request_microcode            = cpu_request_microcode,
>>      .apply_microcode                  = apply_microcode,
>>      .compare                          = intel_compare,
>>      .cpio_path                        = intel_cpio_path,
>> +#endif /* CONFIG_MICROCODE_LOADING */
>>  };
>>  
>>  void __init ucode_probe_intel(struct microcode_ops *ops)
>>  {
>>      *ops = intel_ucode_ops;
>>  
>> -    if ( !can_load_microcode() )
>> +    if ( IS_ENABLED(CONFIG_MICROCODE_LOADING) && !can_load_microcode() )
>>          ops->apply_microcode = NULL;
>>  }
>
> ! ||, surely?

When !CONFIG_MICROCODE_LOADING apply_microcode is already NULL. It's a needless
assignment. This is strictly so the compiler can avoid assigning anything.

Functionally it's irrelevant.

>
>
>> diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c
>> index 79bb99e0b6..5e83965d21 100644
>> --- a/xen/arch/x86/platform_hypercall.c
>> +++ b/xen/arch/x86/platform_hypercall.c
>> @@ -307,6 +307,7 @@ ret_t do_platform_op(
>>          break;
>>      }
>>  
>> +#ifdef CONFIG_MICROCODE_LOADING
>>      case XENPF_microcode_update:
>>      {
>>          XEN_GUEST_HANDLE(const_void) data;
>> @@ -327,6 +328,7 @@ ret_t do_platform_op(
>>                                   op->u.microcode2.flags);
>>          break;
>>      }
>> +#endif /* CONFIG_MICROCODE_LOADING */
>
> You mustn't #ifdef out a case like this, because it causes the op to
> fall into the default case, and some of the default chains go a long way
> and make unwise assumptions, like hitting a BUG().

It's normally more convenient for us (AMD) to physically remove code where
possible for coverage reasons, but in this case it probably doesn't matter.

That said, I think we can both agree if dom0 can crash the hypervisor requesting
a non existing op the bug is probably in such a BUG() statement and not
elsewhere. Note CONFIG_VIDEO already removes an op in this way in this very
file. The default case returns with ENOSYS, with BUG() being in helpers for
other data, as far as I can see.

>
> Always use this form:
>
>     if ( !IS_ENABLED(CONFIG_MICROCODE_LOADING) )
>         // EOPNOTSUPP
>
> and leave the case intact.

... but sure.

>
>>  
>>      case XENPF_platform_quirk:
>>      {
>> diff --git a/xen/common/Makefile b/xen/common/Makefile
>> index 92c97d641e..1e6c92e554 100644
>> --- a/xen/common/Makefile
>> +++ b/xen/common/Makefile
>> @@ -65,7 +65,8 @@ obj-y += wait.o
>>  obj-bin-y += warning.init.o
>>  obj-y += xmalloc_tlsf.o
>>  
>> -obj-bin-$(CONFIG_X86) += $(foreach n,decompress bunzip2 unxz unlzma lzo unlzo unlz4 unzstd earlycpio,$(n).init.o)
>> +obj-bin-$(CONFIG_MICROCODE_LOADING) += earlycpio.init.o
>> +obj-bin-$(CONFIG_X86) += $(foreach n,decompress bunzip2 unxz unlzma lzo unlzo unlz4 unzstd,$(n).init.o)
>>  
>>  obj-$(CONFIG_COMPAT) += $(addprefix compat/,domain.o memory.o multicall.o xlat.o)
>>  
>
> In a prereq patch, please move earlycpio out of common/ into xen/lib/. 
> It shouldn't be tied to CONFIG_MICROCODE_LOADING like this, and it can
> simply be discarded at link time when it's librified and unreferenced.
>
> ~Andrew

That would preclude having it in the init section though, AIUI.

Cheers,
Alejandro


  reply	other threads:[~2026-01-12 18:48 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-12 15:02 [PATCH v2 0/2] Add Kconfig option to remove microcode loading support Alejandro Vallejo
2026-01-12 15:02 ` [PATCH v2 1/2] x86/ucode: Fix typo s/mitigiated/mitigated/ Alejandro Vallejo
2026-01-12 15:44   ` Andrew Cooper
2026-01-12 15:02 ` [PATCH v2 2/2] x86/ucode: Add Kconfig option to remove microcode loading Alejandro Vallejo
2026-01-12 17:15   ` Andrew Cooper
2026-01-12 18:47     ` Alejandro Vallejo [this message]
2026-01-12 19:12       ` Alejandro Vallejo
2026-01-12 19:51         ` Andrew Cooper
2026-01-12 19:47       ` Andrew Cooper
2026-01-13 10:43         ` Alejandro Vallejo
2026-01-13  8:58     ` Jan Beulich
2026-01-13 10:45       ` Alejandro Vallejo
2026-01-13 10:49         ` Jan Beulich

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=DFMU244K4E7W.6M0TQ5AI1TUE@amd.com \
    --to=alejandro.garciavallejo@amd.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=anthony.perard@vates.tech \
    --cc=cardoe@cardoe.com \
    --cc=dpsmith@apertussolutions.com \
    --cc=jbeulich@suse.com \
    --cc=julien@xen.org \
    --cc=marmarek@invisiblethingslab.com \
    --cc=michal.orzel@amd.com \
    --cc=roger.pau@citrix.com \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel-bounces@lists.xenproject.org \
    --cc=xen-devel@lists.xenproject.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.