diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-09-16 13:53:47 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-09-16 13:53:47 +0100 |
commit | acd6ae0ad4c86b5a13e1a2665fc0c5c6d06dffa0 (patch) | |
tree | d5d21535ffe0a24a9ee7f01c2b89224904922acb | |
parent | 4ba317f9faac5b6a07d6ffeafd7e211b1b45e891 (diff) | |
parent | 8530055bc0020592dab1ff8fedd6880ffb13e1bc (diff) | |
download | xen-acd6ae0ad4c86b5a13e1a2665fc0c5c6d06dffa0.tar.gz xen-acd6ae0ad4c86b5a13e1a2665fc0c5c6d06dffa0.tar.bz2 xen-acd6ae0ad4c86b5a13e1a2665fc0c5c6d06dffa0.zip |
Merge with IA64 tree.
-rw-r--r-- | xen/arch/x86/microcode.c | 78 | ||||
-rw-r--r-- | xen/arch/x86/traps.c | 11 |
2 files changed, 36 insertions, 53 deletions
diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c index f39153997a..3b7d6a1356 100644 --- a/xen/arch/x86/microcode.c +++ b/xen/arch/x86/microcode.c @@ -42,14 +42,13 @@ 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) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu; @@ -108,14 +107,12 @@ 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,52 @@ static int microcode_update_cpu(int cpu, const void *buf, size_t size) 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 continue_hypercall_on_cpu(info->cpu, do_microcode_update, info); - 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; - } + error = info->error; + xfree(info); + return error; - return microcode_error; } 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(); - - ret = do_microcode_update(); - - xfree(microcode_buffer.buf); - microcode_buffer.buf = NULL; - microcode_buffer.size = 0; + info->buffer_size = len; + info->error = 0; + info->cpu = first_cpu(cpu_online_map); - return ret; + return continue_hypercall_on_cpu(info->cpu, do_microcode_update, info); } diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index f40a1ed3f7..aad666fb5f 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -2223,10 +2223,6 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) if ( rdmsr_safe(regs->ecx, regs->eax, regs->edx) != 0 ) goto fail; break; - case MSR_EFER: - if ( rdmsr_safe(regs->ecx, regs->eax, regs->edx) ) - goto fail; - break; case MSR_IA32_MISC_ENABLE: if ( rdmsr_safe(regs->ecx, regs->eax, regs->edx) ) goto fail; @@ -2236,12 +2232,9 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL | MSR_IA32_MISC_ENABLE_XTPR_DISABLE; break; + case MSR_EFER: case MSR_IA32_THERM_CONTROL: - if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ) - goto fail; - if ( rdmsr_safe(regs->ecx, regs->eax, regs->edx) ) - goto fail; - break; + case MSR_AMD_PATCHLEVEL: default: if ( rdmsr_hypervisor_regs(regs->ecx, &l, &h) ) { |