[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v8 16/16] microcode: block #NMI handling when loading an ucode
register an nmi callback. And this callback does busy-loop on threads which are waiting for loading completion if 'loading_ucode' is true. Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx> --- Changes in v8: - new --- xen/arch/x86/microcode.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c index 67549be..4ac7e93 100644 --- a/xen/arch/x86/microcode.c +++ b/xen/arch/x86/microcode.c @@ -38,6 +38,7 @@ #include <asm/delay.h> #include <asm/msr.h> +#include <asm/nmi.h> #include <asm/processor.h> #include <asm/setup.h> #include <asm/microcode.h> @@ -439,12 +440,37 @@ static int do_microcode_update(void *patch) return ret; } +static int microcode_nmi_callback(const struct cpu_user_regs *regs, int cpu) +{ + bool print = false; + + /* The first thread of a core is to load an update. Don't block it. */ + if ( cpu == cpumask_first(per_cpu(cpu_sibling_mask, cpu)) ) + return 0; + + if ( loading_state == LOADING_ENTERED ) + { + cpumask_set_cpu(cpu, &cpu_callin_map); + printk(XENLOG_DEBUG "CPU%u enters %s\n", smp_processor_id(), __func__); + print = true; + } + + while ( loading_state == LOADING_ENTERED ) + rep_nop(); + + if ( print ) + printk(XENLOG_DEBUG "CPU%u exits %s\n", smp_processor_id(), __func__); + + return 0; +} + int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void) buf, unsigned long len) { int ret; void *buffer; unsigned int cpu, updated; struct microcode_patch *patch; + nmi_callback_t *saved_nmi_callback; if ( len != (uint32_t)len ) return -E2BIG; @@ -509,6 +535,8 @@ int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void) buf, unsigned long len) * watchdog timeout. */ watchdog_disable(); + + saved_nmi_callback = set_nmi_callback(microcode_nmi_callback); /* * Late loading dance. Why the heavy-handed stop_machine effort? * @@ -521,6 +549,7 @@ int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void) buf, unsigned long len) * conservative and good. */ ret = stop_machine_run(do_microcode_update, patch, NR_CPUS); + set_nmi_callback(saved_nmi_callback); watchdog_enable(); updated = atomic_read(&cpu_updated); -- 1.8.3.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |