ia64/xen-unstable

changeset 19070:a1d0868ffadf

x86 ucode: microcode logic update

Update microcode logic:
1. separate microcode_fini_cpu() into 2 level to avoid deadlock (when
fail at microcode_update_cpu);
2. cancel redundant collect_cpu_info at microcode.c level, use
relative function at microcode driver level;
3. separate microcode_resume_cpu from microcode_update_cpu, because
it's redundant (should only be called when S3 wakeup) and will block newer
microcode update when user update newer microcode.dat from user level

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jan 22 11:11:10 2009 +0000 (2009-01-22)
parents 97228980cd04
children adc3775bb6d8
files xen/arch/x86/microcode.c xen/arch/x86/microcode_intel.c
line diff
     1.1 --- a/xen/arch/x86/microcode.c	Thu Jan 22 11:10:04 2009 +0000
     1.2 +++ b/xen/arch/x86/microcode.c	Thu Jan 22 11:11:10 2009 +0000
     1.3 @@ -49,25 +49,22 @@ struct microcode_info {
     1.4      char buffer[1];
     1.5  };
     1.6  
     1.7 -static void microcode_fini_cpu(int cpu)
     1.8 +static void __microcode_fini_cpu(int cpu)
     1.9  {
    1.10      struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
    1.11  
    1.12 +    xfree(uci->mc.mc_valid);
    1.13 +    memset(uci, 0, sizeof(*uci));
    1.14 +}
    1.15 +
    1.16 +static void microcode_fini_cpu(int cpu)
    1.17 +{
    1.18      spin_lock(&microcode_mutex);
    1.19 -    xfree(uci->mc.mc_valid);
    1.20 -    uci->mc.mc_valid = NULL;
    1.21 +    __microcode_fini_cpu(cpu);
    1.22      spin_unlock(&microcode_mutex);
    1.23  }
    1.24  
    1.25 -static int collect_cpu_info(int cpu)
    1.26 -{
    1.27 -    struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
    1.28 -
    1.29 -    memset(uci, 0, sizeof(*uci));
    1.30 -    return microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
    1.31 -}
    1.32 -
    1.33 -static int microcode_resume_cpu(int cpu)
    1.34 +int microcode_resume_cpu(int cpu)
    1.35  {
    1.36      int err = 0;
    1.37      struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
    1.38 @@ -107,17 +104,11 @@ static int microcode_update_cpu(const vo
    1.39  
    1.40      spin_lock(&microcode_mutex);
    1.41  
    1.42 -    /*
    1.43 -     * Check if the system resume is in progress (uci->mc.mc_valid != NULL),
    1.44 -     * otherwise just request a firmware:
    1.45 -     */
    1.46 -    if ( uci->mc.mc_valid ) {
    1.47 -        err = microcode_resume_cpu(cpu);
    1.48 -    } else {
    1.49 -        err = collect_cpu_info(cpu);
    1.50 -        if ( !err )
    1.51 -            err = microcode_ops->cpu_request_microcode(cpu, buf, size);
    1.52 -    }
    1.53 +    err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
    1.54 +    if ( likely(!err) )
    1.55 +        err = microcode_ops->cpu_request_microcode(cpu, buf, size);
    1.56 +    else
    1.57 +        __microcode_fini_cpu(cpu);
    1.58  
    1.59      spin_unlock(&microcode_mutex);
    1.60  
     2.1 --- a/xen/arch/x86/microcode_intel.c	Thu Jan 22 11:10:04 2009 +0000
     2.2 +++ b/xen/arch/x86/microcode_intel.c	Thu Jan 22 11:11:10 2009 +0000
     2.3 @@ -64,6 +64,8 @@ static int collect_cpu_info(int cpu_num,
     2.4      struct cpuinfo_x86 *c = &cpu_data[cpu_num];
     2.5      unsigned int val[2];
     2.6  
     2.7 +    BUG_ON(cpu_num != smp_processor_id());
     2.8 +
     2.9      memset(csig, 0, sizeof(*csig));
    2.10  
    2.11      if ( (c->x86_vendor != X86_VENDOR_INTEL) || (c->x86 < 6) ||