aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-09-16 13:53:47 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-09-16 13:53:47 +0100
commitacd6ae0ad4c86b5a13e1a2665fc0c5c6d06dffa0 (patch)
treed5d21535ffe0a24a9ee7f01c2b89224904922acb
parent4ba317f9faac5b6a07d6ffeafd7e211b1b45e891 (diff)
parent8530055bc0020592dab1ff8fedd6880ffb13e1bc (diff)
downloadxen-acd6ae0ad4c86b5a13e1a2665fc0c5c6d06dffa0.tar.gz
xen-acd6ae0ad4c86b5a13e1a2665fc0c5c6d06dffa0.tar.bz2
xen-acd6ae0ad4c86b5a13e1a2665fc0c5c6d06dffa0.zip
Merge with IA64 tree.
-rw-r--r--xen/arch/x86/microcode.c78
-rw-r--r--xen/arch/x86/traps.c11
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(&microcode_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) )
{