diff -r 848049b14ec7 xen/arch/x86/microcode_amd.c --- a/xen/arch/x86/microcode_amd.c Mon Nov 14 20:15:35 2011 +0000 +++ b/xen/arch/x86/microcode_amd.c Mon Dec 12 14:36:07 2011 +0100 @@ -27,18 +27,10 @@ #include #include -#define pr_debug(x...) ((void)0) - #define UCODE_MAGIC 0x00414d44 #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000 #define UCODE_UCODE_TYPE 0x00000001 -#define UCODE_MAX_SIZE (2048) -#define DEFAULT_UCODE_DATASIZE (896) -#define MC_HEADER_SIZE (sizeof(struct microcode_header_amd)) -#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) -#define DWSIZE (sizeof(uint32_t)) - /* serialize access to the physical write */ static DEFINE_SPINLOCK(microcode_update_lock); @@ -99,7 +91,7 @@ static int microcode_fits(void *mc, int } if ( mc_header->patch_id <= uci->cpu_sig.rev ) - return -EINVAL; + return 1; printk(KERN_DEBUG "microcode: CPU%d found a matching microcode " "update with version 0x%x (current=0x%x)\n", @@ -147,8 +139,8 @@ static int apply_microcode(int cpu) return 0; } -static int get_next_ucode_from_buffer_amd(void *mc, const void *buf, - size_t size, unsigned long *offset) +static int get_next_ucode_from_buffer_amd(void *mc, size_t *mc_size, + const void *buf, size_t size, unsigned long *offset) { size_t total_size; const uint8_t *bufp = buf; @@ -178,7 +170,12 @@ static int get_next_ucode_from_buffer_am return -EINVAL; } - memset(mc, 0, UCODE_MAX_SIZE); + if (*mc_size < total_size) { + xfree(mc); + mc = xmalloc_bytes(total_size); + *mc_size = total_size; + } + memset(mc, 0, *mc_size); memcpy(mc, (const void *)(&bufp[off + 8]), total_size); *offset = off + total_size + 8; @@ -231,11 +228,12 @@ static int install_equiv_cpu_table(const static int cpu_request_microcode(int cpu, const void *buf, size_t size) { const uint32_t *buf_pos; - unsigned long offset = 0; + size_t offset = 0; int error = 0; int ret; struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); void *mc; + size_t mc_size; /* We should bind the task to the CPU */ BUG_ON(cpu != raw_smp_processor_id()); @@ -245,7 +243,7 @@ static int cpu_request_microcode(int cpu if ( buf_pos[0] != UCODE_MAGIC ) { printk(KERN_ERR "microcode: error! Wrong " - "microcode patch file magic\n"); + "microcode patch file magic\n"); return -EINVAL; } @@ -256,7 +254,8 @@ static int cpu_request_microcode(int cpu return -EINVAL; } - mc = xmalloc_bytes(UCODE_MAX_SIZE); + mc_size = buf_pos[offset + 1]; /* Size of 1st microcode patch in bytes */ + mc = xmalloc_bytes(size); if ( mc == NULL ) { printk(KERN_ERR "microcode: error! " @@ -272,7 +271,8 @@ static int cpu_request_microcode(int cpu * It's possible the data file has multiple matching ucode, * lets keep searching till the latest version */ - while ( (ret = get_next_ucode_from_buffer_amd(mc, buf, size, &offset)) == 0) + while ( (ret = get_next_ucode_from_buffer_amd(mc, &mc_size, + buf, size, &offset)) == 0) { error = microcode_fits(mc, cpu); if (error <= 0)