[PATCH] x86/ucode: Exit early from early_update_cache() if loading not available

Andrew Cooper posted 1 patch 10 months, 3 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://gitlab.com/xen-project/patchew/xen tags/patchew/20230601143813.1553740-1-andrew.cooper3@citrix.com
xen/arch/x86/cpu/microcode/core.c | 3 +++
1 file changed, 3 insertions(+)
[PATCH] x86/ucode: Exit early from early_update_cache() if loading not available
Posted by Andrew Cooper 10 months, 3 weeks ago
If for any reason early_microcode_init() concludes that no microcode loading
is available, early_update_cache() will fall over a NULL function pointer:

  (XEN) Xen call trace:
  (XEN)    [<ffff82d04037372e>] R show_code+0x91/0x18f
  (XEN)    [<ffff82d040373a49>] F show_execution_state+0x2d/0x1fc
  (XEN)    [<ffff82d040374210>] F fatal_trap+0x87/0x19a
  (XEN)    [<ffff82d040647f2c>] F init_idt_traps+0/0x1bd
  (XEN)    [<ffff82d04063854f>] F early_page_fault+0x8f/0x94
  (XEN)    [<0000000000000000>] F 0000000000000000
  (XEN)    [<ffff82d040628c46>] F arch/x86/cpu/microcode/core.c#early_update_cache+0x11/0x74
  (XEN)    [<ffff82d040628e5c>] F microcode_init_cache+0x5a/0x5c
  (XEN)    [<ffff82d04064388f>] F __start_xen+0x1e11/0x27ee
  (XEN)    [<ffff82d040206184>] F __high_start+0x94/0xa0

which is actually parse_blob()'s use of ucode_ops.collect_cpu_info.

Skip trying to cache anything if microcode loading is unavailable.

Fixes: dc380df12acf ("x86/ucode: load microcode earlier on boot CPU")
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Wei Liu <wl@xen.org>
CC: Alejandro Vallejo <alejandro.vallejo@cloud.com>

Found while doing something unrelated, but this is going to interact poorly
with MCU_CONTROL_DIS_MCU_LOAD.
---
 xen/arch/x86/cpu/microcode/core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c
index 5a5c0a8c70db..9029301107d6 100644
--- a/xen/arch/x86/cpu/microcode/core.c
+++ b/xen/arch/x86/cpu/microcode/core.c
@@ -789,6 +789,9 @@ int __init microcode_init_cache(unsigned long *module_map,
 {
     int rc = 0;
 
+    if ( !ucode_ops.apply_microcode )
+        return -ENODEV;
+
     if ( ucode_scan )
         /* Need to rescan the modules because they might have been relocated */
         microcode_scan_module(module_map, mbi);

base-commit: 59d0bf62861f5c9b317ccf89f8b5c8b4d19927ad
prerequisite-patch-id: c3f6ae7def85b63808449493e3b5185bc40c405d
prerequisite-patch-id: 59a20dfb4778c62bf512f746e36b1bea0949b0a8
prerequisite-patch-id: a70c8dd42245affe402b08cacd5872b5a32a6d69
prerequisite-patch-id: 3efc26e008858670286c173f77f8ec34ddfd9df1
prerequisite-patch-id: 5f6ddddf7dd6029f401d13bbb87ac3bb88c15700
prerequisite-patch-id: 4133b7d49c978a89042e95f899f46c4ec4ac4498
prerequisite-patch-id: d2d3a24a650f6b1b50e279be158cdd097eb43a4b
prerequisite-patch-id: 358299b6b56983e3c069ea1f30e7cf214b0a2c54
prerequisite-patch-id: b17530cf5672ada3e7792606b7a3bef55c8aa372
prerequisite-patch-id: e9bc40cc80e61b24d90eeb7097cd9b703f0170a6
-- 
2.30.2


Re: [PATCH] x86/ucode: Exit early from early_update_cache() if loading not available
Posted by Alejandro Vallejo 10 months, 3 weeks ago
On Thu, Jun 01, 2023 at 03:38:13PM +0100, Andrew Cooper wrote:
> If for any reason early_microcode_init() concludes that no microcode loading
> is available, early_update_cache() will fall over a NULL function pointer:
> 
>   (XEN) Xen call trace:
>   (XEN)    [<ffff82d04037372e>] R show_code+0x91/0x18f
>   (XEN)    [<ffff82d040373a49>] F show_execution_state+0x2d/0x1fc
>   (XEN)    [<ffff82d040374210>] F fatal_trap+0x87/0x19a
>   (XEN)    [<ffff82d040647f2c>] F init_idt_traps+0/0x1bd
>   (XEN)    [<ffff82d04063854f>] F early_page_fault+0x8f/0x94
>   (XEN)    [<0000000000000000>] F 0000000000000000
>   (XEN)    [<ffff82d040628c46>] F arch/x86/cpu/microcode/core.c#early_update_cache+0x11/0x74
>   (XEN)    [<ffff82d040628e5c>] F microcode_init_cache+0x5a/0x5c
>   (XEN)    [<ffff82d04064388f>] F __start_xen+0x1e11/0x27ee
>   (XEN)    [<ffff82d040206184>] F __high_start+0x94/0xa0
> 
> which is actually parse_blob()'s use of ucode_ops.collect_cpu_info.
> 
> Skip trying to cache anything if microcode loading is unavailable.
> [...]
> ---
>  xen/arch/x86/cpu/microcode/core.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c
> index 5a5c0a8c70db..9029301107d6 100644
> --- a/xen/arch/x86/cpu/microcode/core.c
> +++ b/xen/arch/x86/cpu/microcode/core.c
> @@ -789,6 +789,9 @@ int __init microcode_init_cache(unsigned long *module_map,
>  {
>      int rc = 0;
>  
> +    if ( !ucode_ops.apply_microcode )
> +        return -ENODEV;
> +
>      if ( ucode_scan )
>          /* Need to rescan the modules because they might have been relocated */
>          microcode_scan_module(module_map, mbi);

Ugh. These bugs are forever. IMO, it would be helpful to have a default set
of stubs (ucode_ops_default?) that unconditionally return -ENODEV when
called. At least the whole system won't crash under our feet if we forgot
an "if ( !ucode_ops.foo ) return -1".

It's still imperfect but there's far less room for errors.

Alejandro
Re: [PATCH] x86/ucode: Exit early from early_update_cache() if loading not available
Posted by Jan Beulich 10 months, 3 weeks ago
On 01.06.2023 16:38, Andrew Cooper wrote:
> If for any reason early_microcode_init() concludes that no microcode loading
> is available, early_update_cache() will fall over a NULL function pointer:
> 
>   (XEN) Xen call trace:
>   (XEN)    [<ffff82d04037372e>] R show_code+0x91/0x18f
>   (XEN)    [<ffff82d040373a49>] F show_execution_state+0x2d/0x1fc
>   (XEN)    [<ffff82d040374210>] F fatal_trap+0x87/0x19a
>   (XEN)    [<ffff82d040647f2c>] F init_idt_traps+0/0x1bd
>   (XEN)    [<ffff82d04063854f>] F early_page_fault+0x8f/0x94
>   (XEN)    [<0000000000000000>] F 0000000000000000
>   (XEN)    [<ffff82d040628c46>] F arch/x86/cpu/microcode/core.c#early_update_cache+0x11/0x74
>   (XEN)    [<ffff82d040628e5c>] F microcode_init_cache+0x5a/0x5c
>   (XEN)    [<ffff82d04064388f>] F __start_xen+0x1e11/0x27ee
>   (XEN)    [<ffff82d040206184>] F __high_start+0x94/0xa0
> 
> which is actually parse_blob()'s use of ucode_ops.collect_cpu_info.
> 
> Skip trying to cache anything if microcode loading is unavailable.
> 
> Fixes: dc380df12acf ("x86/ucode: load microcode earlier on boot CPU")
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>