[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86, microcode: Do not run microcode update in IRQ context.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1221568859 -3600 # Node ID 879330497672d96ee966c9774d21c437895f6839 # Parent 88445b184dc666fc196cffab19eac75cd9c10b87 x86, microcode: Do not run microcode update in IRQ context. It's unnecessary, and also invalid since the update process tries to allocate memory. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/microcode.c | 77 +++++++++++++++++++---------------------------- 1 files changed, 32 insertions(+), 45 deletions(-) diff -r 88445b184dc6 -r 879330497672 xen/arch/x86/microcode.c --- a/xen/arch/x86/microcode.c Tue Sep 16 13:18:32 2008 +0100 +++ b/xen/arch/x86/microcode.c Tue Sep 16 13:40:59 2008 +0100 @@ -42,13 +42,12 @@ static DEFINE_SPINLOCK(microcode_mutex); struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; -struct microcode_buffer { - void *buf; - size_t size; +struct microcode_info { + unsigned int cpu; + uint32_t buffer_size; + int error; + char buffer[1]; }; - -static struct microcode_buffer microcode_buffer; -static bool_t microcode_error; static void microcode_fini_cpu(int cpu) { @@ -108,13 +107,11 @@ static int microcode_resume_cpu(int cpu) return err; } -static int microcode_update_cpu(int cpu, const void *buf, size_t size) +static int microcode_update_cpu(const void *buf, size_t size) { - int err = 0; + int err; + unsigned int cpu = smp_processor_id(); struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - - /* We should bind the task to the CPU */ - BUG_ON(raw_smp_processor_id() != cpu); spin_lock(µcode_mutex); @@ -138,59 +135,49 @@ static int microcode_update_cpu(int cpu, return err; } -static void do_microcode_update_one(void *info) +static long do_microcode_update(void *_info) { - int error = microcode_update_cpu( - smp_processor_id(), microcode_buffer.buf, microcode_buffer.size); + struct microcode_info *info = _info; + int error; + + BUG_ON(info->cpu != smp_processor_id()); + + error = microcode_update_cpu(info->buffer, info->buffer_size); if ( error ) - microcode_error = error; -} + info->error = error; -static int do_microcode_update(void) -{ - microcode_error = 0; + info->cpu = next_cpu(info->cpu, cpu_online_map); + if ( info->cpu >= NR_CPUS ) + return info->error; - if ( on_each_cpu(do_microcode_update_one, NULL, 1, 1) != 0 ) - { - printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); - return -EIO; - } - - return microcode_error; + return continue_hypercall_on_cpu(info->cpu, do_microcode_update, info); } int microcode_update(XEN_GUEST_HANDLE(const_void) buf, unsigned long len) { int ret; + struct microcode_info *info; - /* XXX FIXME: No allocations in interrupt context. */ - return -EINVAL; - - if ( len != (typeof(microcode_buffer.size))len ) - { - printk(KERN_ERR "microcode: too much data\n"); + if ( len != (uint32_t)len ) return -E2BIG; - } if ( microcode_ops == NULL ) return -EINVAL; - microcode_buffer.buf = xmalloc_array(uint8_t, len); - if ( microcode_buffer.buf == NULL ) + info = xmalloc_bytes(sizeof(*info) + len); + if ( info == NULL ) return -ENOMEM; - ret = copy_from_guest(microcode_buffer.buf, buf, len); + ret = copy_from_guest(info->buffer, buf, len); if ( ret != 0 ) + { + xfree(info); return ret; + } - microcode_buffer.size = len; - wmb(); + info->buffer_size = len; + info->error = 0; + info->cpu = first_cpu(cpu_online_map); - ret = do_microcode_update(); - - xfree(microcode_buffer.buf); - microcode_buffer.buf = NULL; - microcode_buffer.size = 0; - - return ret; + return continue_hypercall_on_cpu(info->cpu, do_microcode_update, info); } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |