[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 06/10] x86/ucode: Enforce invariant about module selection
On 28.10.2024 10:18, Andrew Cooper wrote: > The work to add the `ucode=nmi` cmdline option left a subtle corner case. > Both scan and an explicit index could be selected, and we could really find a > CPIO archive and explicit microcode file. > > Worse, because the if/else chains for processing ucode_{blob,mod} are opposite > ways around in early_microcode_load() and microcode_init_cache(), we can > genuinely perform early microcode loading from the CPIO archive, then cache > from the explicit file. > > Therefore, enforce that only one selection method can be active. Question is - is this really the best of all possible behaviors? One may want to use one approach as the fallback for the other, e.g. preferably use what the CPIO has, but fall back to something pre-installed on the boot or EFI partition. > @@ -139,12 +148,16 @@ static int __init cf_check parse_ucode(const char *s) > else if ( !ucode_mod_forced ) /* Not forced by EFI */ > { > if ( (val = parse_boolean("scan", s, ss)) >= 0 ) > - ucode_scan = val; > + { > + opt_scan = val; > + opt_mod_idx = 0; > + } > else > { > const char *q; > > - ucode_mod_idx = simple_strtol(s, &q, 0); > + opt_scan = false; > + opt_mod_idx = simple_strtol(s, &q, 0); > if ( q != ss ) > rc = -EINVAL; > } I think this latter part rather wants to be opt_mod_idx = simple_strtol(s, &q, 0); if ( q != ss ) { opt_mod_idx = 0; rc = -EINVAL; } else opt_scan = false; to prevent a malformed ucode= to clobber an earlier wellformed ucode=scan. (There are limits to this of course, as an out-of-range value would still invalidate the "scan" request.) > @@ -817,17 +830,42 @@ static int __init early_microcode_load(struct boot_info > *bi) > const void *data = NULL; > size_t size; > struct microcode_patch *patch; > + int idx = opt_mod_idx; > + > + /* > + * Cmdline parsing ensures this invariant holds, so that we don't end up > + * trying to mix multiple ways of finding the microcode. > + */ > + ASSERT(idx == 0 || !opt_scan); > > - if ( ucode_mod_idx < 0 ) > - ucode_mod_idx += bi->nr_modules; > - if ( ucode_mod_idx <= 0 || ucode_mod_idx >= bi->nr_modules || > - !__test_and_clear_bit(ucode_mod_idx, bi->module_map) ) > - goto scan; > - ucode_mod = *bi->mods[ucode_mod_idx].mod; > - scan: Oh, the goto and label are going away here anyway. Never mind the comment on the earlier patch then. Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |