[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(&microcode_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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.