ia64/xen-unstable
changeset 19060:fb0dc8143932
x86: update microcode support
- Container header file holding the patches changed. Update to new
format.
- in cpu_request_microcode() move heap re-allocation & copy out of the
loop.
Side-effect: Remove limitation in only supporting fixed sized
microcode patches. Also simplifies code a lot.
- cleanup: use rdmsr and wrmsrl instead of inlined assembler
- pass ucode_cpu_info as arguments. Improves reentrancy.
- cleanup: simplify struct ucode_cpu_info and remove
get_matching_microcode hook. Side-effect: reduces kernel size.
- bugfix: fix xen kernel memory leak in error path. equiv_cpu_table
was not freed.
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
- Container header file holding the patches changed. Update to new
format.
- in cpu_request_microcode() move heap re-allocation & copy out of the
loop.
Side-effect: Remove limitation in only supporting fixed sized
microcode patches. Also simplifies code a lot.
- cleanup: use rdmsr and wrmsrl instead of inlined assembler
- pass ucode_cpu_info as arguments. Improves reentrancy.
- cleanup: simplify struct ucode_cpu_info and remove
get_matching_microcode hook. Side-effect: reduces kernel size.
- bugfix: fix xen kernel memory leak in error path. equiv_cpu_table
was not freed.
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Tue Jan 20 13:27:08 2009 +0000 (2009-01-20) |
parents | 0ab2b283e892 |
children | 681af1946724 |
files | xen/arch/x86/microcode.c xen/arch/x86/microcode_amd.c xen/arch/x86/microcode_intel.c xen/include/asm-x86/microcode.h |
line diff
1.1 --- a/xen/arch/x86/microcode.c Tue Jan 20 13:22:28 2009 +0000 1.2 +++ b/xen/arch/x86/microcode.c Tue Jan 20 13:27:08 2009 +0000 1.3 @@ -49,39 +49,28 @@ 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(struct ucode_cpu_info *uci, int cpu) 1.9 { 1.10 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.11 - 1.12 spin_lock(µcode_mutex); 1.13 - xfree(uci->mc.valid_mc); 1.14 - uci->mc.valid_mc = NULL; 1.15 - uci->valid = 0; 1.16 + xfree(uci->mc.mc_valid); 1.17 + uci->mc.mc_valid = NULL; 1.18 spin_unlock(µcode_mutex); 1.19 } 1.20 1.21 -static int collect_cpu_info(int cpu) 1.22 +static int collect_cpu_info(struct ucode_cpu_info *uci, int cpu) 1.23 +{ 1.24 + memset(uci, 0, sizeof(*uci)); 1.25 + return microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); 1.26 +} 1.27 + 1.28 +static int microcode_resume_cpu(struct ucode_cpu_info *uci, int cpu) 1.29 { 1.30 int err = 0; 1.31 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.32 - 1.33 - memset(uci, 0, sizeof(*uci)); 1.34 - err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); 1.35 - if ( !err ) 1.36 - uci->valid = 1; 1.37 - 1.38 - return err; 1.39 -} 1.40 - 1.41 -static int microcode_resume_cpu(int cpu) 1.42 -{ 1.43 - int err = 0; 1.44 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.45 struct cpu_signature nsig; 1.46 1.47 gdprintk(XENLOG_INFO, "microcode: CPU%d resumed\n", cpu); 1.48 1.49 - if ( !uci->mc.valid_mc ) 1.50 + if ( !uci->mc.mc_valid ) 1.51 return -EIO; 1.52 1.53 /* 1.54 @@ -91,43 +80,38 @@ static int microcode_resume_cpu(int cpu) 1.55 err = microcode_ops->collect_cpu_info(cpu, &nsig); 1.56 if ( err ) 1.57 { 1.58 - microcode_fini_cpu(cpu); 1.59 + microcode_fini_cpu(uci, cpu); 1.60 return err; 1.61 } 1.62 1.63 if ( memcmp(&nsig, &uci->cpu_sig, sizeof(nsig)) ) 1.64 { 1.65 - microcode_fini_cpu(cpu); 1.66 + microcode_fini_cpu(uci, cpu); 1.67 /* Should we look for a new ucode here? */ 1.68 return -EIO; 1.69 } 1.70 1.71 - err = microcode_ops->apply_microcode(cpu); 1.72 - 1.73 - return err; 1.74 + return microcode_ops->apply_microcode(uci, cpu); 1.75 } 1.76 1.77 static int microcode_update_cpu(const void *buf, size_t size) 1.78 { 1.79 int err; 1.80 unsigned int cpu = smp_processor_id(); 1.81 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 1.82 + struct ucode_cpu_info *uci = &ucode_cpu_info[cpu]; 1.83 1.84 spin_lock(µcode_mutex); 1.85 1.86 /* 1.87 - * Check if the system resume is in progress (uci->valid != NULL), 1.88 + * Check if the system resume is in progress (uci->mc.mc_valid != NULL), 1.89 * otherwise just request a firmware: 1.90 */ 1.91 - if ( uci->valid ) 1.92 - { 1.93 - err = microcode_resume_cpu(cpu); 1.94 - } 1.95 - else 1.96 - { 1.97 - err = collect_cpu_info(cpu); 1.98 - if ( !err && uci->valid ) 1.99 - err = microcode_ops->cpu_request_microcode(cpu, buf, size); 1.100 + if ( uci->mc.mc_valid ) { 1.101 + err = microcode_resume_cpu(uci, cpu); 1.102 + } else { 1.103 + err = collect_cpu_info(uci, cpu); 1.104 + if ( !err ) 1.105 + err = microcode_ops->cpu_request_microcode(uci, cpu, buf, size); 1.106 } 1.107 1.108 spin_unlock(µcode_mutex); 1.109 @@ -153,7 +137,6 @@ static long do_microcode_update(void *_i 1.110 error = info->error; 1.111 xfree(info); 1.112 return error; 1.113 - 1.114 } 1.115 1.116 int microcode_update(XEN_GUEST_HANDLE(const_void) buf, unsigned long len)
2.1 --- a/xen/arch/x86/microcode_amd.c Tue Jan 20 13:22:28 2009 +0000 2.2 +++ b/xen/arch/x86/microcode_amd.c Tue Jan 20 13:27:08 2009 +0000 2.3 @@ -38,21 +38,16 @@ 2.4 #define MC_HEADER_SIZE (sizeof(struct microcode_header_amd)) 2.5 #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) 2.6 #define DWSIZE (sizeof(uint32_t)) 2.7 -/* For now we support a fixed ucode total size only */ 2.8 -#define get_totalsize(mc) \ 2.9 - ((((struct microcode_amd *)mc)->hdr.mc_patch_data_len * 28) \ 2.10 - + MC_HEADER_SIZE) 2.11 2.12 /* serialize access to the physical write */ 2.13 static DEFINE_SPINLOCK(microcode_update_lock); 2.14 2.15 struct equiv_cpu_entry *equiv_cpu_table; 2.16 2.17 -static long install_equiv_cpu_table(const void *, uint32_t, long); 2.18 - 2.19 static int collect_cpu_info(int cpu, struct cpu_signature *csig) 2.20 { 2.21 struct cpuinfo_x86 *c = &cpu_data[cpu]; 2.22 + uint32_t dummy; 2.23 2.24 memset(csig, 0, sizeof(*csig)); 2.25 2.26 @@ -60,13 +55,10 @@ static int collect_cpu_info(int cpu, str 2.27 { 2.28 printk(KERN_ERR "microcode: CPU%d not a capable AMD processor\n", 2.29 cpu); 2.30 - return -1; 2.31 + return -EINVAL; 2.32 } 2.33 2.34 - asm volatile ( 2.35 - "movl %1, %%ecx; rdmsr" 2.36 - : "=a" (csig->rev) 2.37 - : "i" (MSR_AMD_PATCHLEVEL) : "ecx" ); 2.38 + rdmsr(MSR_AMD_PATCHLEVEL, csig->rev, dummy); 2.39 2.40 printk(KERN_INFO "microcode: collect_cpu_info: patch_id=0x%x\n", 2.41 csig->rev); 2.42 @@ -74,29 +66,17 @@ static int collect_cpu_info(int cpu, str 2.43 return 0; 2.44 } 2.45 2.46 -static int get_matching_microcode(void *mc, int cpu) 2.47 +static int microcode_fits(void *mc, int cpu) 2.48 { 2.49 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 2.50 struct microcode_header_amd *mc_header = mc; 2.51 - unsigned long total_size = get_totalsize(mc_header); 2.52 - void *new_mc; 2.53 unsigned int current_cpu_id; 2.54 - unsigned int equiv_cpu_id = 0x00; 2.55 + unsigned int equiv_cpu_id = 0x0; 2.56 unsigned int i; 2.57 2.58 /* We should bind the task to the CPU */ 2.59 BUG_ON(cpu != raw_smp_processor_id()); 2.60 2.61 - /* This is a tricky part. We might be called from a write operation 2.62 - * to the device file instead of the usual process of firmware 2.63 - * loading. This routine needs to be able to distinguish both 2.64 - * cases. This is done by checking if there already is a equivalent 2.65 - * CPU table installed. If not, we're written through 2.66 - * /dev/cpu/microcode. 2.67 - * Since we ignore all checks. The error case in which going through 2.68 - * firmware loading and that table is not loaded has already been 2.69 - * checked earlier. 2.70 - */ 2.71 if ( equiv_cpu_table == NULL ) 2.72 { 2.73 printk(KERN_INFO "microcode: CPU%d microcode update with " 2.74 @@ -111,7 +91,7 @@ static int get_matching_microcode(void * 2.75 { 2.76 if ( current_cpu_id == equiv_cpu_table[i].installed_cpu ) 2.77 { 2.78 - equiv_cpu_id = equiv_cpu_table[i].equiv_cpu; 2.79 + equiv_cpu_id = equiv_cpu_table[i].equiv_cpu & 0xffff; 2.80 break; 2.81 } 2.82 } 2.83 @@ -119,171 +99,135 @@ static int get_matching_microcode(void * 2.84 if ( !equiv_cpu_id ) 2.85 { 2.86 printk(KERN_ERR "microcode: CPU%d cpu_id " 2.87 - "not found in equivalent cpu table \n", cpu); 2.88 - return 0; 2.89 + "not found in equivalent cpu table\n", cpu); 2.90 + return -EINVAL; 2.91 } 2.92 2.93 - if ( (mc_header->processor_rev_id[0]) != (equiv_cpu_id & 0xff) ) 2.94 - { 2.95 - printk(KERN_INFO 2.96 - "microcode: CPU%d patch does not match " 2.97 - "(patch is %x, cpu extended is %x) \n", 2.98 - cpu, mc_header->processor_rev_id[0], 2.99 - (equiv_cpu_id & 0xff)); 2.100 - return 0; 2.101 - } 2.102 - 2.103 - if ( (mc_header->processor_rev_id[1]) != ((equiv_cpu_id >> 16) & 0xff) ) 2.104 + if ( (mc_header->processor_rev_id) != equiv_cpu_id ) 2.105 { 2.106 printk(KERN_INFO "microcode: CPU%d patch does not match " 2.107 "(patch is %x, cpu base id is %x) \n", 2.108 - cpu, mc_header->processor_rev_id[1], 2.109 - ((equiv_cpu_id >> 16) & 0xff)); 2.110 - return 0; 2.111 + cpu, mc_header->processor_rev_id, equiv_cpu_id); 2.112 + return -EINVAL; 2.113 } 2.114 2.115 if ( mc_header->patch_id <= uci->cpu_sig.rev ) 2.116 - return 0; 2.117 + return -EINVAL; 2.118 2.119 printk(KERN_INFO "microcode: CPU%d found a matching microcode " 2.120 "update with version 0x%x (current=0x%x)\n", 2.121 cpu, mc_header->patch_id, uci->cpu_sig.rev); 2.122 2.123 - out: 2.124 - new_mc = xmalloc_bytes(UCODE_MAX_SIZE); 2.125 - if ( new_mc == NULL ) 2.126 - { 2.127 - printk(KERN_ERR "microcode: error, can't allocate memory\n"); 2.128 - return -ENOMEM; 2.129 - } 2.130 - memset(new_mc, 0, UCODE_MAX_SIZE); 2.131 - 2.132 - /* free previous update file */ 2.133 - xfree(uci->mc.mc_amd); 2.134 - 2.135 - memcpy(new_mc, mc, total_size); 2.136 - 2.137 - uci->mc.mc_amd = new_mc; 2.138 - return 1; 2.139 +out: 2.140 + return 0; 2.141 } 2.142 2.143 -static int apply_microcode(int cpu) 2.144 +static int apply_microcode(struct ucode_cpu_info *uci, int cpu) 2.145 { 2.146 unsigned long flags; 2.147 - uint32_t eax, edx, rev; 2.148 - int cpu_num = raw_smp_processor_id(); 2.149 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 2.150 - uint64_t addr; 2.151 + uint32_t rev, dummy; 2.152 + struct microcode_amd *mc_amd = uci->mc.mc_amd; 2.153 2.154 /* We should bind the task to the CPU */ 2.155 - BUG_ON(cpu_num != cpu); 2.156 + BUG_ON(raw_smp_processor_id() != cpu); 2.157 2.158 - if ( uci->mc.mc_amd == NULL ) 2.159 + if ( mc_amd == NULL ) 2.160 return -EINVAL; 2.161 2.162 spin_lock_irqsave(µcode_update_lock, flags); 2.163 2.164 - addr = (unsigned long)&uci->mc.mc_amd->hdr.data_code; 2.165 - edx = (uint32_t)(addr >> 32); 2.166 - eax = (uint32_t)addr; 2.167 - 2.168 - asm volatile ( 2.169 - "movl %0, %%ecx; wrmsr" : 2.170 - : "i" (MSR_AMD_PATCHLOADER), "a" (eax), "d" (edx) : "ecx" ); 2.171 + wrmsrl(MSR_AMD_PATCHLOADER, (unsigned long)&mc_amd->hdr.data_code); 2.172 2.173 /* get patch id after patching */ 2.174 - asm volatile ( 2.175 - "movl %1, %%ecx; rdmsr" 2.176 - : "=a" (rev) 2.177 - : "i" (MSR_AMD_PATCHLEVEL) : "ecx"); 2.178 + rdmsr(MSR_AMD_PATCHLEVEL, rev, dummy); 2.179 2.180 spin_unlock_irqrestore(µcode_update_lock, flags); 2.181 2.182 /* check current patch id and patch's id for match */ 2.183 - if ( rev != uci->mc.mc_amd->hdr.patch_id ) 2.184 + if ( rev != mc_amd->hdr.patch_id ) 2.185 { 2.186 printk(KERN_ERR "microcode: CPU%d update from revision " 2.187 - "0x%x to 0x%x failed\n", cpu_num, 2.188 - uci->mc.mc_amd->hdr.patch_id, rev); 2.189 + "0x%x to 0x%x failed\n", cpu, 2.190 + mc_amd->hdr.patch_id, rev); 2.191 return -EIO; 2.192 } 2.193 2.194 printk("microcode: CPU%d updated from revision " 2.195 "0x%x to 0x%x \n", 2.196 - cpu_num, uci->cpu_sig.rev, uci->mc.mc_amd->hdr.patch_id); 2.197 + cpu, uci->cpu_sig.rev, mc_amd->hdr.patch_id); 2.198 2.199 uci->cpu_sig.rev = rev; 2.200 2.201 return 0; 2.202 } 2.203 2.204 -static long get_next_ucode_from_buffer_amd(void **mc, const void *buf, 2.205 - unsigned long size, long offset) 2.206 +static int get_next_ucode_from_buffer_amd(void *mc, const void *buf, 2.207 + size_t size, unsigned long *offset) 2.208 { 2.209 struct microcode_header_amd *mc_header; 2.210 - unsigned long total_size; 2.211 - const uint8_t *buf_pos = buf; 2.212 + size_t total_size; 2.213 + const uint8_t *bufp = buf; 2.214 + unsigned long off; 2.215 + 2.216 + off = *offset; 2.217 2.218 /* No more data */ 2.219 - if ( offset >= size ) 2.220 - return 0; 2.221 + if ( off >= size ) 2.222 + return 1; 2.223 2.224 - if ( buf_pos[offset] != UCODE_UCODE_TYPE ) 2.225 + if ( bufp[off] != UCODE_UCODE_TYPE ) 2.226 { 2.227 printk(KERN_ERR "microcode: error! " 2.228 "Wrong microcode payload type field\n"); 2.229 return -EINVAL; 2.230 } 2.231 2.232 - mc_header = (struct microcode_header_amd *)(&buf_pos[offset+8]); 2.233 + mc_header = (struct microcode_header_amd *)(&bufp[off+8]); 2.234 2.235 - total_size = (unsigned long) (buf_pos[offset+4] + 2.236 - (buf_pos[offset+5] << 8)); 2.237 + total_size = (unsigned long) (bufp[off+4] + (bufp[off+5] << 8)); 2.238 2.239 printk(KERN_INFO "microcode: size %lu, total_size %lu, offset %ld\n", 2.240 - size, total_size, offset); 2.241 + (unsigned long)size, total_size, off); 2.242 2.243 - if ( (offset + total_size) > size ) 2.244 + if ( (off + total_size) > size ) 2.245 { 2.246 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 2.247 return -EINVAL; 2.248 } 2.249 2.250 - *mc = xmalloc_bytes(UCODE_MAX_SIZE); 2.251 - if ( *mc == NULL ) 2.252 - { 2.253 - printk(KERN_ERR "microcode: error! " 2.254 - "Can not allocate memory for microcode patch\n"); 2.255 - return -ENOMEM; 2.256 - } 2.257 + memset(mc, 0, UCODE_MAX_SIZE); 2.258 + memcpy(mc, (const void *)(&bufp[off + 8]), total_size); 2.259 2.260 - memset(*mc, 0, UCODE_MAX_SIZE); 2.261 - memcpy(*mc, (const void *)(buf + offset + 8), total_size); 2.262 + *offset = off + total_size + 8; 2.263 2.264 - return offset + total_size + 8; 2.265 + return 0; 2.266 } 2.267 2.268 -static long install_equiv_cpu_table(const void *buf, 2.269 - uint32_t size, long offset) 2.270 +static int install_equiv_cpu_table(const void *buf, uint32_t size, 2.271 + unsigned long *offset) 2.272 { 2.273 const uint32_t *buf_pos = buf; 2.274 + unsigned long off; 2.275 + 2.276 + off = *offset; 2.277 + *offset = 0; 2.278 2.279 /* No more data */ 2.280 - if ( offset >= size ) 2.281 - return 0; 2.282 + if ( off >= size ) 2.283 + return -EINVAL; 2.284 2.285 if ( buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE ) 2.286 { 2.287 printk(KERN_ERR "microcode: error! " 2.288 - "Wrong microcode equivalnet cpu table type field\n"); 2.289 - return 0; 2.290 + "Wrong microcode equivalent cpu table type field\n"); 2.291 + return -EINVAL; 2.292 } 2.293 2.294 if ( size == 0 ) 2.295 { 2.296 printk(KERN_ERR "microcode: error! " 2.297 "Wrong microcode equivalnet cpu table length\n"); 2.298 - return 0; 2.299 + return -EINVAL; 2.300 } 2.301 2.302 equiv_cpu_table = xmalloc_bytes(size); 2.303 @@ -291,24 +235,29 @@ static long install_equiv_cpu_table(cons 2.304 { 2.305 printk(KERN_ERR "microcode: error, can't allocate " 2.306 "memory for equiv CPU table\n"); 2.307 - return 0; 2.308 + return -ENOMEM; 2.309 } 2.310 2.311 memset(equiv_cpu_table, 0, size); 2.312 memcpy(equiv_cpu_table, (const void *)&buf_pos[3], size); 2.313 2.314 - return size + 12; /* add header length */ 2.315 + *offset = size + 12; /* add header length */ 2.316 + 2.317 + return 0; 2.318 } 2.319 2.320 -static int cpu_request_microcode(int cpu, const void *buf, size_t size) 2.321 +static int cpu_request_microcode(struct ucode_cpu_info *uci, 2.322 + int cpu, const void *buf, size_t size) 2.323 { 2.324 const uint32_t *buf_pos; 2.325 - long offset = 0; 2.326 + unsigned long offset = 0; 2.327 int error = 0; 2.328 + int ret; 2.329 void *mc; 2.330 2.331 /* We should bind the task to the CPU */ 2.332 BUG_ON(cpu != raw_smp_processor_id()); 2.333 + BUG_ON(uci != &ucode_cpu_info[cpu]); 2.334 2.335 buf_pos = (const uint32_t *)buf; 2.336 2.337 @@ -319,41 +268,57 @@ static int cpu_request_microcode(int cpu 2.338 return -EINVAL; 2.339 } 2.340 2.341 - offset = install_equiv_cpu_table(buf, (uint32_t)(buf_pos[2]), offset); 2.342 - if ( !offset ) 2.343 + error = install_equiv_cpu_table(buf, (uint32_t)(buf_pos[2]), &offset); 2.344 + if ( error ) 2.345 { 2.346 printk(KERN_ERR "microcode: installing equivalent cpu table failed\n"); 2.347 return -EINVAL; 2.348 } 2.349 2.350 - while ( (offset = 2.351 - get_next_ucode_from_buffer_amd(&mc, buf, size, offset)) > 0 ) 2.352 + mc = xmalloc_bytes(UCODE_MAX_SIZE); 2.353 + if ( mc == NULL ) 2.354 { 2.355 - error = get_matching_microcode(mc, cpu); 2.356 - if ( error < 0 ) 2.357 + printk(KERN_ERR "microcode: error! " 2.358 + "Can not allocate memory for microcode patch\n"); 2.359 + error = -ENOMEM; 2.360 + goto out; 2.361 + } 2.362 + 2.363 + /* implicitely validates uci->mc.mc_valid */ 2.364 + uci->mc.mc_amd = mc; 2.365 + 2.366 + /* 2.367 + * It's possible the data file has multiple matching ucode, 2.368 + * lets keep searching till the latest version 2.369 + */ 2.370 + while ( (ret = get_next_ucode_from_buffer_amd(mc, buf, size, &offset)) == 0) 2.371 + { 2.372 + error = microcode_fits(mc, cpu); 2.373 + if (error != 0) 2.374 + continue; 2.375 + 2.376 + error = apply_microcode(uci, cpu); 2.377 + if (error == 0) 2.378 break; 2.379 - /* 2.380 - * It's possible the data file has multiple matching ucode, 2.381 - * lets keep searching till the latest version 2.382 - */ 2.383 - if ( error == 1 ) 2.384 - error = apply_microcode(cpu); 2.385 - xfree(mc); 2.386 } 2.387 - if ( offset > 0 ) 2.388 - { 2.389 + 2.390 + /* On success keep the microcode patch for 2.391 + * re-apply on resume. 2.392 + */ 2.393 + if (error) { 2.394 xfree(mc); 2.395 - xfree(equiv_cpu_table); 2.396 - equiv_cpu_table = NULL; 2.397 + mc = NULL; 2.398 } 2.399 - if ( offset < 0 ) 2.400 - error = offset; 2.401 + uci->mc.mc_amd = mc; 2.402 + 2.403 +out: 2.404 + xfree(equiv_cpu_table); 2.405 + equiv_cpu_table = NULL; 2.406 2.407 return error; 2.408 } 2.409 2.410 static struct microcode_ops microcode_amd_ops = { 2.411 - .get_matching_microcode = get_matching_microcode, 2.412 .cpu_request_microcode = cpu_request_microcode, 2.413 .collect_cpu_info = collect_cpu_info, 2.414 .apply_microcode = apply_microcode,
3.1 --- a/xen/arch/x86/microcode_intel.c Tue Jan 20 13:22:28 2009 +0000 3.2 +++ b/xen/arch/x86/microcode_intel.c Tue Jan 20 13:27:08 2009 +0000 3.3 @@ -244,12 +244,11 @@ static int get_matching_microcode(void * 3.4 return 1; 3.5 } 3.6 3.7 -static int apply_microcode(int cpu) 3.8 +static int apply_microcode(struct ucode_cpu_info *uci, int cpu) 3.9 { 3.10 unsigned long flags; 3.11 unsigned int val[2]; 3.12 int cpu_num = raw_smp_processor_id(); 3.13 - struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 3.14 3.15 /* We should bind the task to the CPU */ 3.16 BUG_ON(cpu_num != cpu); 3.17 @@ -318,7 +317,8 @@ static long get_next_ucode_from_buffer(v 3.18 return offset + total_size; 3.19 } 3.20 3.21 -static int cpu_request_microcode(int cpu, const void *buf, size_t size) 3.22 +static int cpu_request_microcode(struct ucode_cpu_info *uci, 3.23 + int cpu, const void *buf, size_t size) 3.24 { 3.25 long offset = 0; 3.26 int error = 0; 3.27 @@ -341,7 +341,7 @@ static int cpu_request_microcode(int cpu 3.28 */ 3.29 if ( error == 1 ) 3.30 { 3.31 - apply_microcode(cpu); 3.32 + apply_microcode(uci, cpu); 3.33 error = 0; 3.34 } 3.35 xfree(mc); 3.36 @@ -355,7 +355,6 @@ static int cpu_request_microcode(int cpu 3.37 } 3.38 3.39 static struct microcode_ops microcode_intel_ops = { 3.40 - .get_matching_microcode = get_matching_microcode, 3.41 .cpu_request_microcode = cpu_request_microcode, 3.42 .collect_cpu_info = collect_cpu_info, 3.43 .apply_microcode = apply_microcode,
4.1 --- a/xen/include/asm-x86/microcode.h Tue Jan 20 13:22:28 2009 +0000 4.2 +++ b/xen/include/asm-x86/microcode.h Tue Jan 20 13:27:08 2009 +0000 4.3 @@ -2,12 +2,13 @@ 4.4 #define ASM_X86__MICROCODE_H 4.5 4.6 struct cpu_signature; 4.7 +struct ucode_cpu_info; 4.8 4.9 struct microcode_ops { 4.10 - int (*get_matching_microcode)(void *mc, int cpu); 4.11 - int (*cpu_request_microcode)(int cpu, const void *buf, size_t size); 4.12 - int (*collect_cpu_info)(int cpu_num, struct cpu_signature *csig); 4.13 - int (*apply_microcode)(int cpu); 4.14 + int (*cpu_request_microcode)(struct ucode_cpu_info *uci, 4.15 + int cpu, const void *buf, size_t size); 4.16 + int (*collect_cpu_info)(int cpu, struct cpu_signature *csig); 4.17 + int (*apply_microcode)(struct ucode_cpu_info *uci, int cpu); 4.18 }; 4.19 4.20 struct microcode_header_intel { 4.21 @@ -43,28 +44,29 @@ struct extended_sigtable { 4.22 }; 4.23 4.24 struct equiv_cpu_entry { 4.25 - unsigned int installed_cpu; 4.26 - unsigned int fixed_errata_mask; 4.27 - unsigned int fixed_errata_compare; 4.28 - unsigned int equiv_cpu; 4.29 -}; 4.30 + uint32_t installed_cpu; 4.31 + uint32_t fixed_errata_mask; 4.32 + uint32_t fixed_errata_compare; 4.33 + uint16_t equiv_cpu; 4.34 + uint16_t reserved; 4.35 +} __attribute__((packed)); 4.36 4.37 struct microcode_header_amd { 4.38 - unsigned int data_code; 4.39 - unsigned int patch_id; 4.40 - unsigned char mc_patch_data_id[2]; 4.41 - unsigned char mc_patch_data_len; 4.42 - unsigned char init_flag; 4.43 - unsigned int mc_patch_data_checksum; 4.44 - unsigned int nb_dev_id; 4.45 - unsigned int sb_dev_id; 4.46 - unsigned char processor_rev_id[2]; 4.47 - unsigned char nb_rev_id; 4.48 - unsigned char sb_rev_id; 4.49 - unsigned char bios_api_rev; 4.50 - unsigned char reserved1[3]; 4.51 - unsigned int match_reg[8]; 4.52 -}; 4.53 + uint32_t data_code; 4.54 + uint32_t patch_id; 4.55 + uint8_t mc_patch_data_id[2]; 4.56 + uint8_t mc_patch_data_len; 4.57 + uint8_t init_flag; 4.58 + uint32_t mc_patch_data_checksum; 4.59 + uint32_t nb_dev_id; 4.60 + uint32_t sb_dev_id; 4.61 + uint16_t processor_rev_id; 4.62 + uint8_t nb_rev_id; 4.63 + uint8_t sb_rev_id; 4.64 + uint8_t bios_api_rev; 4.65 + uint8_t reserved1[3]; 4.66 + uint32_t match_reg[8]; 4.67 +} __attribute__((packed)); 4.68 4.69 struct microcode_amd { 4.70 struct microcode_header_amd hdr; 4.71 @@ -79,11 +81,10 @@ struct cpu_signature { 4.72 4.73 struct ucode_cpu_info { 4.74 struct cpu_signature cpu_sig; 4.75 - int valid; 4.76 union { 4.77 struct microcode_intel *mc_intel; 4.78 struct microcode_amd *mc_amd; 4.79 - void *valid_mc; 4.80 + void *mc_valid; 4.81 } mc; 4.82 }; 4.83