[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v12] microcode: rendezvous CPUs in NMI handler and load ucode
On 27.09.2019 18:12, Chao Gao wrote: > @@ -105,23 +110,40 @@ void __init microcode_set_module(unsigned int idx) > } > > /* > - * The format is '[<integer>|scan]'. Both options are optional. > - * If the EFI has forced which of the multiboot payloads is to be used, > - * no parsing will be attempted. > + * The format is '[<integer>|scan=<bool>, nmi=<bool>]'. Both options are > + * optional. If the EFI has forced which of the multiboot payloads is to be > + * used, only nmi=<bool> is parsed. > */ > static int __init parse_ucode(const char *s) > { > - const char *q = NULL; > + const char *ss; > + int val, rc = 0; > > - if ( ucode_mod_forced ) /* Forced by EFI */ > - return 0; > + do { > + ss = strchr(s, ','); > + if ( !ss ) > + ss = strchr(s, '\0'); > > - if ( !strncmp(s, "scan", 4) ) > - ucode_scan = 1; > - else > - ucode_mod_idx = simple_strtol(s, &q, 0); > + if ( (val = parse_boolean("nmi", s, ss)) >= 0 ) > + ucode_in_nmi = val; > + else if ( !ucode_mod_forced ) /* Not forced by EFI */ > + { > + if ( (val = parse_boolean("scan", s, ss)) >= 0 ) > + ucode_scan = val; > + else > + { > + const char *q = NULL; I don't think the initializer is needed here. > static int primary_thread_fn(const struct microcode_patch *patch) > { > - int ret = 0; > - > if ( !wait_for_state(LOADING_CALLIN) ) > return -EBUSY; > > - cpumask_set_cpu(smp_processor_id(), &cpu_callin_map); > + if ( ucode_in_nmi ) > + { > + self_nmi(); > > - if ( !wait_for_state(LOADING_ENTER) ) > - return -EBUSY; > + /* > + * Wait for ucode loading is done in case that the NMI does not > arrive > + * synchronously, which may lead to a not-yet-updated error is > returned > + * below. > + */ > + if ( unlikely(!wait_for_state(LOADING_EXIT)) ) > + ASSERT_UNREACHABLE(); > > - ret = microcode_ops->apply_microcode(patch); > - if ( !ret ) > - atomic_inc(&cpu_updated); > - atomic_inc(&cpu_out); > + return this_cpu(loading_err); > + } > > - return ret; > + return primary_thread_work(patch); > } A remark on the code structure - the overall amount of indentation would have been less if you negated the if() expression. > @@ -405,6 +489,10 @@ static int control_thread_fn(const struct > microcode_patch *patch) > */ > watchdog_disable(); > > + nmi_patch = patch; > + smp_wmb(); > + saved_nmi_callback = set_nmi_callback(microcode_nmi_callback); > + > /* Allow threads to call in */ > set_state(LOADING_CALLIN); Seeing the blank line you keep here after watchdog_disable(), ... > @@ -455,6 +552,9 @@ static int control_thread_fn(const struct microcode_patch > *patch) > /* Mark loading is done to unblock other threads */ > set_state(LOADING_EXIT); > > + set_nmi_callback(saved_nmi_callback); > + smp_wmb(); > + nmi_patch = ZERO_BLOCK_PTR; > watchdog_enable(); ... for consistency there would better have been one left ahead of watchdog_enable() here as well. Preferably with at least the first and last items taken care of (which ought to be easy enough to do while committing) Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |