xref: /titanic_41/usr/src/uts/i86pc/os/microcode.c (revision 728f047ccdb8a96a1aecc448cb87706241a08c94)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <sys/asm_linkage.h>
28 #include <sys/bootconf.h>
29 #include <sys/cpuvar.h>
30 #include <sys/cmn_err.h>
31 #include <sys/controlregs.h>
32 #include <sys/debug.h>
33 #include <sys/kobj.h>
34 #include <sys/kobj_impl.h>
35 #include <sys/machsystm.h>
36 #include <sys/param.h>
37 #include <sys/machparam.h>
38 #include <sys/promif.h>
39 #include <sys/sysmacros.h>
40 #include <sys/systm.h>
41 #include <sys/types.h>
42 #include <sys/thread.h>
43 #include <sys/ucode.h>
44 #include <sys/x86_archext.h>
45 #include <sys/x_call.h>
46 #ifdef	__xpv
47 #include <sys/hypervisor.h>
48 #endif
49 
50 /*
51  * Microcode specific information per core
52  */
53 struct cpu_ucode_info {
54 	uint32_t	cui_platid;	/* platform id */
55 	uint32_t	cui_rev;	/* microcode revision */
56 };
57 
58 /*
59  * Data structure used for xcall
60  */
61 struct ucode_update_struct {
62 	uint32_t		sig;	/* signature */
63 	struct cpu_ucode_info	info;	/* ucode info */
64 	uint32_t		expected_rev;
65 	uint32_t		new_rev;
66 	uint8_t			*ucodep; /* pointer to ucode body */
67 };
68 
69 /*
70  * mcpu_ucode_info for the boot CPU.  Statically allocated.
71  */
72 static struct cpu_ucode_info cpu_ucode_info0;
73 
74 static ucode_file_t ucodefile = { 0 };
75 
76 static int ucode_capable(cpu_t *);
77 static void ucode_file_reset(ucode_file_t *, processorid_t);
78 static ucode_errno_t ucode_match(int, struct cpu_ucode_info *,
79     ucode_header_t *, ucode_ext_table_t *);
80 static ucode_errno_t ucode_locate(cpu_t *, struct cpu_ucode_info *,
81     ucode_file_t *);
82 static void ucode_update_intel(uint8_t *, struct cpu_ucode_info *);
83 static void ucode_read_rev(struct cpu_ucode_info *);
84 #ifdef	__xpv
85 static void ucode_update_xpv(struct ucode_update_struct *, uint8_t *, uint32_t);
86 #endif
87 
88 static const char ucode_failure_fmt[] =
89 	"cpu%d: failed to update microcode from version 0x%x to 0x%x\n";
90 static const char ucode_success_fmt[] =
91 	"?cpu%d: microcode has been updated from version 0x%x to 0x%x\n";
92 
93 /*
94  * Force flag.  If set, the first microcode binary that matches
95  * signature and platform id will be used for microcode update,
96  * regardless of version.  Should only be used for debugging.
97  */
98 int ucode_force_update = 0;
99 
100 /*
101  * Allocate space for mcpu_ucode_info in the machcpu structure
102  * for all non-boot CPUs.
103  */
104 void
105 ucode_alloc_space(cpu_t *cp)
106 {
107 	ASSERT(cp->cpu_id != 0);
108 	cp->cpu_m.mcpu_ucode_info =
109 	    kmem_zalloc(sizeof (*cp->cpu_m.mcpu_ucode_info), KM_SLEEP);
110 }
111 
112 void
113 ucode_free_space(cpu_t *cp)
114 {
115 	ASSERT(cp->cpu_id != 0);
116 	kmem_free(cp->cpu_m.mcpu_ucode_info,
117 	    sizeof (*cp->cpu_m.mcpu_ucode_info));
118 }
119 
120 /*
121  * Called when we are done with microcode update on all processors to free up
122  * space allocated for the microcode file.
123  */
124 void
125 ucode_free()
126 {
127 	ucode_file_reset(&ucodefile, -1);
128 }
129 
130 /*
131  * Check whether or not a processor is capable of microcode operations
132  * Returns 1 if it is capable, 0 if not.
133  */
134 static int
135 ucode_capable(cpu_t *cp)
136 {
137 	/* i86xpv guest domain can't update microcode */
138 #ifndef	__xpv
139 	extern int xpv_is_hvm;
140 	if (xpv_is_hvm) {
141 		return (0);
142 	}
143 #else
144 	if (!DOMAIN_IS_INITDOMAIN(xen_info)) {
145 		return (0);
146 	}
147 #endif
148 
149 	/*
150 	 * At this point we only support microcode update for Intel
151 	 * processors family 6 and above.
152 	 *
153 	 * We also assume that we don't support a mix of Intel and
154 	 * AMD processors in the same box.
155 	 */
156 	if (cpuid_getvendor(cp) != X86_VENDOR_Intel ||
157 	    cpuid_getfamily(cp) < 6)
158 		return (0);
159 	else
160 		return (1);
161 }
162 
163 /*
164  * Called when it is no longer necessary to keep the microcode around,
165  * or when the cached microcode doesn't match the CPU being processed.
166  */
167 static void
168 ucode_file_reset(ucode_file_t *ucodefp, processorid_t id)
169 {
170 	int total_size, body_size;
171 
172 	if (ucodefp == NULL)
173 		return;
174 
175 	total_size = UCODE_TOTAL_SIZE(ucodefp->uf_header.uh_total_size);
176 	body_size = UCODE_BODY_SIZE(ucodefp->uf_header.uh_body_size);
177 	if (ucodefp->uf_body) {
178 		/*
179 		 * Space for the boot CPU is allocated with BOP_ALLOC()
180 		 * and does not require a free.
181 		 */
182 		if (id != 0)
183 			kmem_free(ucodefp->uf_body, body_size);
184 		ucodefp->uf_body = NULL;
185 	}
186 
187 	if (ucodefp->uf_ext_table) {
188 		int size = total_size - body_size - UCODE_HEADER_SIZE;
189 		/*
190 		 * Space for the boot CPU is allocated with BOP_ALLOC()
191 		 * and does not require a free.
192 		 */
193 		if (id != 0)
194 			kmem_free(ucodefp->uf_ext_table, size);
195 		ucodefp->uf_ext_table = NULL;
196 	}
197 
198 	bzero(&ucodefp->uf_header, UCODE_HEADER_SIZE);
199 }
200 
201 /*
202  * Populate the ucode file structure from microcode file corresponding to
203  * this CPU, if exists.
204  *
205  * Return EM_OK on success, corresponding error code on failure.
206  */
207 static ucode_errno_t
208 ucode_locate(cpu_t *cp, struct cpu_ucode_info *uinfop, ucode_file_t *ucodefp)
209 {
210 	char		name[MAXPATHLEN];
211 	intptr_t	fd;
212 	int		count;
213 	int		header_size = UCODE_HEADER_SIZE;
214 	int		cpi_sig = cpuid_getsig(cp);
215 	ucode_errno_t	rc = EM_OK;
216 
217 	/*
218 	 * If the microcode matches the CPU we are processing, use it.
219 	 */
220 	if (ucode_match(cpi_sig, uinfop, &ucodefp->uf_header,
221 	    ucodefp->uf_ext_table) == EM_OK && ucodefp->uf_body != NULL) {
222 		return (EM_OK);
223 	}
224 
225 	/*
226 	 * Look for microcode file with the right name.
227 	 */
228 	(void) snprintf(name, MAXPATHLEN, "/%s/%s/%08X-%02X",
229 	    UCODE_INSTALL_PATH, cpuid_getvendorstr(cp), cpi_sig,
230 	    uinfop->cui_platid);
231 	if ((fd = kobj_open(name)) == -1) {
232 		return (EM_OPENFILE);
233 	}
234 
235 	/*
236 	 * We found a microcode file for the CPU we are processing,
237 	 * reset the microcode data structure and read in the new
238 	 * file.
239 	 */
240 	ucode_file_reset(ucodefp, cp->cpu_id);
241 
242 	count = kobj_read(fd, (char *)&ucodefp->uf_header, header_size, 0);
243 
244 	switch (count) {
245 	case UCODE_HEADER_SIZE: {
246 
247 		ucode_header_t	*uhp = &ucodefp->uf_header;
248 		uint32_t	offset = header_size;
249 		int		total_size, body_size, ext_size;
250 		uint32_t	sum = 0;
251 
252 		/*
253 		 * Make sure that the header contains valid fields.
254 		 */
255 		if ((rc = ucode_header_validate(uhp)) == EM_OK) {
256 			total_size = UCODE_TOTAL_SIZE(uhp->uh_total_size);
257 			body_size = UCODE_BODY_SIZE(uhp->uh_body_size);
258 			if (cp->cpu_id != 0) {
259 				if ((ucodefp->uf_body = kmem_zalloc(body_size,
260 				    KM_NOSLEEP)) == NULL) {
261 					rc = EM_NOMEM;
262 					break;
263 				}
264 			} else {
265 				/*
266 				 * BOP_ALLOC() failure results in panic so we
267 				 * don't have to check for NULL return.
268 				 */
269 				ucodefp->uf_body =
270 				    (uint8_t *)BOP_ALLOC(bootops,
271 				    NULL, body_size, MMU_PAGESIZE);
272 			}
273 
274 			if (kobj_read(fd, (char *)ucodefp->uf_body,
275 			    body_size, offset) != body_size)
276 				rc = EM_FILESIZE;
277 		}
278 
279 		if (rc)
280 			break;
281 
282 		sum = ucode_checksum(0, header_size,
283 		    (uint8_t *)&ucodefp->uf_header);
284 		if (ucode_checksum(sum, body_size, ucodefp->uf_body)) {
285 			rc = EM_CHECKSUM;
286 			break;
287 		}
288 
289 		/*
290 		 * Check to see if there is extended signature table.
291 		 */
292 		offset = body_size + header_size;
293 		ext_size = total_size - offset;
294 
295 		if (ext_size <= 0)
296 			break;
297 
298 		if (cp->cpu_id != 0) {
299 			if ((ucodefp->uf_ext_table = kmem_zalloc(ext_size,
300 			    KM_NOSLEEP)) == NULL) {
301 				rc = EM_NOMEM;
302 				break;
303 			}
304 		} else {
305 			/*
306 			 * BOP_ALLOC() failure results in panic so we
307 			 * don't have to check for NULL return.
308 			 */
309 			ucodefp->uf_ext_table =
310 			    (ucode_ext_table_t *)BOP_ALLOC(bootops, NULL,
311 			    ext_size, MMU_PAGESIZE);
312 		}
313 
314 		if (kobj_read(fd, (char *)ucodefp->uf_ext_table,
315 		    ext_size, offset) != ext_size) {
316 			rc = EM_FILESIZE;
317 		} else if (ucode_checksum(0, ext_size,
318 		    (uint8_t *)(ucodefp->uf_ext_table))) {
319 			rc = EM_CHECKSUM;
320 		} else {
321 			int i;
322 
323 			ext_size -= UCODE_EXT_TABLE_SIZE;
324 			for (i = 0; i < ucodefp->uf_ext_table->uet_count;
325 			    i++) {
326 				if (ucode_checksum(0, UCODE_EXT_SIG_SIZE,
327 				    (uint8_t *)(&(ucodefp->uf_ext_table->
328 				    uet_ext_sig[i])))) {
329 					rc = EM_CHECKSUM;
330 					break;
331 				}
332 			}
333 		}
334 		break;
335 	}
336 
337 	default:
338 		rc = EM_FILESIZE;
339 		break;
340 	}
341 
342 	kobj_close(fd);
343 
344 	if (rc != EM_OK)
345 		return (rc);
346 
347 	rc = ucode_match(cpi_sig, uinfop, &ucodefp->uf_header,
348 	    ucodefp->uf_ext_table);
349 
350 	return (rc);
351 }
352 
353 
354 /*
355  * Returns 1 if the microcode is for this processor; 0 otherwise.
356  */
357 static ucode_errno_t
358 ucode_match(int cpi_sig, struct cpu_ucode_info *uinfop,
359     ucode_header_t *uhp, ucode_ext_table_t *uetp)
360 {
361 	ASSERT(uhp);
362 
363 	if (UCODE_MATCH(cpi_sig, uhp->uh_signature,
364 	    uinfop->cui_platid, uhp->uh_proc_flags)) {
365 
366 		if (uinfop->cui_rev >= uhp->uh_rev && !ucode_force_update)
367 			return (EM_HIGHERREV);
368 
369 		return (EM_OK);
370 	}
371 
372 	if (uetp != NULL) {
373 		int i;
374 
375 		for (i = 0; i < uetp->uet_count; i++) {
376 			ucode_ext_sig_t *uesp;
377 
378 			uesp = &uetp->uet_ext_sig[i];
379 
380 			if (UCODE_MATCH(cpi_sig, uesp->ues_signature,
381 			    uinfop->cui_platid, uesp->ues_proc_flags)) {
382 
383 				if (uinfop->cui_rev >= uhp->uh_rev &&
384 				    !ucode_force_update)
385 					return (EM_HIGHERREV);
386 
387 				return (EM_OK);
388 			}
389 		}
390 	}
391 
392 	return (EM_NOMATCH);
393 }
394 
395 /*ARGSUSED*/
396 static int
397 ucode_write(xc_arg_t arg1, xc_arg_t unused2, xc_arg_t unused3)
398 {
399 	struct ucode_update_struct *uusp = (struct ucode_update_struct *)arg1;
400 	struct cpu_ucode_info *uinfop = CPU->cpu_m.mcpu_ucode_info;
401 
402 	ASSERT(uusp->ucodep);
403 
404 #ifndef	__xpv
405 	/*
406 	 * Check one more time to see if it is really necessary to update
407 	 * microcode just in case this is a hyperthreaded processor where
408 	 * the threads share the same microcode.
409 	 */
410 	if (!ucode_force_update) {
411 		ucode_read_rev(uinfop);
412 		uusp->new_rev = uinfop->cui_rev;
413 		if (uinfop->cui_rev >= uusp->expected_rev)
414 			return (0);
415 	}
416 
417 	wrmsr(MSR_INTC_UCODE_WRITE,
418 	    (uint64_t)(intptr_t)(uusp->ucodep));
419 #endif
420 	ucode_read_rev(uinfop);
421 	uusp->new_rev = uinfop->cui_rev;
422 
423 	return (0);
424 }
425 
426 
427 static void
428 ucode_update_intel(uint8_t *ucode_body, struct cpu_ucode_info *uinfop)
429 {
430 	kpreempt_disable();
431 	wrmsr(MSR_INTC_UCODE_WRITE, (uint64_t)(uintptr_t)ucode_body);
432 	ucode_read_rev(uinfop);
433 	kpreempt_enable();
434 }
435 
436 
437 #ifdef	__xpv
438 static void
439 ucode_update_xpv(struct ucode_update_struct *uusp, uint8_t *ucode,
440     uint32_t size)
441 {
442 	struct cpu_ucode_info *uinfop;
443 	xen_platform_op_t op;
444 	int e;
445 
446 	ASSERT(DOMAIN_IS_INITDOMAIN(xen_info));
447 
448 	kpreempt_disable();
449 	uinfop = CPU->cpu_m.mcpu_ucode_info;
450 	op.cmd = XENPF_microcode_update;
451 	op.interface_version = XENPF_INTERFACE_VERSION;
452 	/*LINTED: constant in conditional context*/
453 	set_xen_guest_handle(op.u.microcode.data, ucode);
454 	op.u.microcode.length = size;
455 	e = HYPERVISOR_platform_op(&op);
456 	if (e != 0) {
457 		cmn_err(CE_WARN, "hypervisor failed to accept uCode update");
458 	}
459 	ucode_read_rev(uinfop);
460 	if (uusp != NULL) {
461 		uusp->new_rev = uinfop->cui_rev;
462 	}
463 	kpreempt_enable();
464 }
465 #endif /* __xpv */
466 
467 
468 static void
469 ucode_read_rev(struct cpu_ucode_info *uinfop)
470 {
471 	struct cpuid_regs crs;
472 
473 	/*
474 	 * The Intel 64 and IA-32 Architecture Software Developer's Manual
475 	 * recommends that MSR_INTC_UCODE_REV be loaded with 0 first, then
476 	 * execute cpuid to guarantee the correct reading of this register.
477 	 */
478 	wrmsr(MSR_INTC_UCODE_REV, 0);
479 	(void) __cpuid_insn(&crs);
480 	uinfop->cui_rev = (rdmsr(MSR_INTC_UCODE_REV) >> INTC_UCODE_REV_SHIFT);
481 }
482 
483 /*
484  * Entry point to microcode update from the ucode_drv driver.
485  *
486  * Returns EM_OK on success, corresponding error code on failure.
487  */
488 ucode_errno_t
489 ucode_update(uint8_t *ucodep, int size)
490 {
491 	uint32_t	header_size = UCODE_HEADER_SIZE;
492 	int		remaining;
493 	int		found = 0;
494 	processorid_t	id;
495 	struct ucode_update_struct cached = { 0 };
496 	struct ucode_update_struct *cachedp = NULL;
497 	ucode_errno_t	rc = EM_OK;
498 	ucode_errno_t	search_rc = EM_NOMATCH; /* search result */
499 	cpuset_t cpuset;
500 #ifdef	__xpv
501 	uint8_t *ustart;
502 	uint32_t usize;
503 #endif
504 
505 	ASSERT(ucodep);
506 	CPUSET_ZERO(cpuset);
507 
508 	if (!ucode_capable(CPU))
509 		return (EM_NOTSUP);
510 
511 	mutex_enter(&cpu_lock);
512 
513 	for (id = 0; id < max_ncpus; id++) {
514 		cpu_t *cpu;
515 		struct ucode_update_struct uus = { 0 };
516 		struct ucode_update_struct *uusp = &uus;
517 
518 		/*
519 		 * If there is no such CPU or it is not xcall ready, skip it.
520 		 */
521 		if ((cpu = cpu_get(id)) == NULL ||
522 		    !(cpu->cpu_flags & CPU_READY))
523 			continue;
524 
525 		uusp->sig = cpuid_getsig(cpu);
526 		bcopy(cpu->cpu_m.mcpu_ucode_info, &uusp->info,
527 		    sizeof (uusp->info));
528 
529 		/*
530 		 * If the current CPU has the same signature and platform
531 		 * id as the previous one we processed, reuse the information.
532 		 */
533 		if (cachedp && cachedp->sig == cpuid_getsig(cpu) &&
534 		    cachedp->info.cui_platid == uusp->info.cui_platid) {
535 			uusp->ucodep = cachedp->ucodep;
536 			uusp->expected_rev = cachedp->expected_rev;
537 			/*
538 			 * Intuitively we should check here to see whether the
539 			 * running microcode rev is >= the expected rev, and
540 			 * quit if it is.  But we choose to proceed with the
541 			 * xcall regardless of the running version so that
542 			 * the other threads in an HT processor can update
543 			 * the cpu_ucode_info structure in machcpu.
544 			 */
545 		} else {
546 			/*
547 			 * Go through the whole buffer in case there are
548 			 * multiple versions of matching microcode for this
549 			 * processor.
550 			 */
551 			for (remaining = size; remaining > 0; ) {
552 				int	total_size, body_size, ext_size;
553 				uint8_t	*curbuf = &ucodep[size - remaining];
554 				ucode_header_t	*uhp = (ucode_header_t *)curbuf;
555 				ucode_ext_table_t *uetp = NULL;
556 				ucode_errno_t tmprc;
557 
558 				total_size =
559 				    UCODE_TOTAL_SIZE(uhp->uh_total_size);
560 				body_size = UCODE_BODY_SIZE(uhp->uh_body_size);
561 				ext_size = total_size -
562 				    (header_size + body_size);
563 
564 				if (ext_size > 0)
565 					uetp = (ucode_ext_table_t *)
566 					    &curbuf[header_size + body_size];
567 
568 				tmprc = ucode_match(uusp->sig, &uusp->info,
569 				    uhp, uetp);
570 
571 				/*
572 				 * Since we are searching through a big file
573 				 * containing microcode for pretty much all the
574 				 * processors, we are bound to get EM_NOMATCH
575 				 * at one point.  However, if we return
576 				 * EM_NOMATCH to users, it will really confuse
577 				 * them.  Therefore, if we ever find a match of
578 				 * a lower rev, we will set return code to
579 				 * EM_HIGHERREV.
580 				 */
581 				if (tmprc == EM_HIGHERREV)
582 					search_rc = EM_HIGHERREV;
583 
584 				if (tmprc == EM_OK &&
585 				    uusp->expected_rev < uhp->uh_rev) {
586 					uusp->ucodep = &curbuf[header_size];
587 #ifdef	__xpv
588 					ustart = (uint8_t *)curbuf;
589 					usize = UCODE_TOTAL_SIZE(
590 					    uhp->uh_total_size);
591 #endif
592 					uusp->expected_rev = uhp->uh_rev;
593 					bcopy(uusp, &cached, sizeof (cached));
594 					cachedp = &cached;
595 					found = 1;
596 				}
597 
598 				remaining -= total_size;
599 			}
600 		}
601 
602 		/* Nothing to do */
603 		if (uusp->ucodep == NULL)
604 			continue;
605 
606 #ifdef	__xpv
607 		/*
608 		 * for i86xpv, the hypervisor will update all the CPUs.
609 		 * the hypervisor wants the header, data, and extended
610 		 * signature tables. ucode_write will just read in the
611 		 * updated version on all the CPUs after the update has
612 		 * completed.
613 		 */
614 		if (id == 0) {
615 			ucode_update_xpv(uusp, ustart, usize);
616 		}
617 #endif
618 
619 		CPUSET_ADD(cpuset, id);
620 		kpreempt_disable();
621 		xc_sync((xc_arg_t)uusp, 0, 0, X_CALL_HIPRI, cpuset,
622 		    ucode_write);
623 		kpreempt_enable();
624 		CPUSET_DEL(cpuset, id);
625 
626 		if (uusp->expected_rev == uusp->new_rev) {
627 			cmn_err(CE_CONT, ucode_success_fmt,
628 			    id, uusp->info.cui_rev, uusp->expected_rev);
629 		} else {
630 			cmn_err(CE_WARN, ucode_failure_fmt,
631 			    id, uusp->info.cui_rev, uusp->expected_rev);
632 			rc = EM_UPDATE;
633 		}
634 	}
635 
636 	mutex_exit(&cpu_lock);
637 
638 	if (!found)
639 		rc = search_rc;
640 
641 	return (rc);
642 }
643 
644 /*
645  * Initialize mcpu_ucode_info, and perform microcode update if necessary.
646  * This is the entry point from boot path where pointer to CPU structure
647  * is available.
648  *
649  * cpuid_info must be initialized before ucode_check can be called.
650  */
651 void
652 ucode_check(cpu_t *cp)
653 {
654 	struct cpu_ucode_info *uinfop;
655 	ucode_errno_t rc = EM_OK;
656 #ifdef	__xpv
657 	uint32_t ext_offset;
658 	uint32_t body_size;
659 	uint32_t ext_size;
660 	uint8_t *ustart;
661 	uint32_t usize;
662 #endif
663 
664 	ASSERT(cp);
665 	if (cp->cpu_id == 0)
666 		cp->cpu_m.mcpu_ucode_info = &cpu_ucode_info0;
667 
668 	uinfop = cp->cpu_m.mcpu_ucode_info;
669 	ASSERT(uinfop);
670 
671 	if (!ucode_capable(cp))
672 		return;
673 
674 	/*
675 	 * The MSR_INTC_PLATFORM_ID is supported in Celeron and Xeon
676 	 * (Family 6, model 5 and above) and all processors after.
677 	 */
678 	if ((cpuid_getmodel(cp) >= 5) || (cpuid_getfamily(cp) > 6)) {
679 		uinfop->cui_platid = 1 << ((rdmsr(MSR_INTC_PLATFORM_ID) >>
680 		    INTC_PLATFORM_ID_SHIFT) & INTC_PLATFORM_ID_MASK);
681 	}
682 
683 	ucode_read_rev(uinfop);
684 
685 #ifdef	__xpv
686 	/*
687 	 * for i86xpv, the hypervisor will update all the CPUs. We only need
688 	 * do do this on one of the CPUs (and there always is a CPU 0).
689 	 */
690 	if (cp->cpu_id != 0) {
691 		return;
692 	}
693 #endif
694 
695 	/*
696 	 * Check to see if we need ucode update
697 	 */
698 	if ((rc = ucode_locate(cp, uinfop, &ucodefile)) == EM_OK) {
699 #ifndef	__xpv
700 		ucode_update_intel(ucodefile.uf_body, uinfop);
701 #else
702 		/*
703 		 * the hypervisor wants the header, data, and extended
704 		 * signature tables. We can only get here from the boot
705 		 * CPU (cpu #0), so use BOP_ALLOC. Since we're using BOP_ALLOC,
706 		 * We don't need to free.
707 		 */
708 		usize = UCODE_TOTAL_SIZE(ucodefile.uf_header.uh_total_size);
709 		ustart = (uint8_t *)BOP_ALLOC(bootops, NULL, usize,
710 		    MMU_PAGESIZE);
711 
712 		body_size = UCODE_BODY_SIZE(ucodefile.uf_header.uh_body_size);
713 		ext_offset = body_size + UCODE_HEADER_SIZE;
714 		ext_size = usize - ext_offset;
715 		ASSERT(ext_size >= 0);
716 
717 		(void) memcpy(ustart, &ucodefile.uf_header, UCODE_HEADER_SIZE);
718 		(void) memcpy(&ustart[UCODE_HEADER_SIZE], ucodefile.uf_body,
719 		    body_size);
720 		if (ext_size > 0) {
721 			(void) memcpy(&ustart[ext_offset],
722 			    ucodefile.uf_ext_table, ext_size);
723 		}
724 		ucode_update_xpv(NULL, ustart, usize);
725 #endif
726 
727 		if (uinfop->cui_rev != ucodefile.uf_header.uh_rev)
728 			cmn_err(CE_WARN, ucode_failure_fmt, cp->cpu_id,
729 			    uinfop->cui_rev, ucodefile.uf_header.uh_rev);
730 	}
731 
732 	/*
733 	 * If we fail to find a match for any reason, free the file structure
734 	 * just in case we have read in a partial file.
735 	 *
736 	 * Since the scratch memory for holding the microcode for the boot CPU
737 	 * came from BOP_ALLOC, we will reset the data structure as if we
738 	 * never did the allocation so we don't have to keep track of this
739 	 * special chunk of memory.  We free the memory used for the rest
740 	 * of the CPUs in start_other_cpus().
741 	 */
742 	if (rc != EM_OK || cp->cpu_id == 0)
743 		ucode_file_reset(&ucodefile, cp->cpu_id);
744 }
745 
746 /*
747  * Returns microcode revision from the machcpu structure.
748  */
749 ucode_errno_t
750 ucode_get_rev(uint32_t *revp)
751 {
752 	int i;
753 
754 	ASSERT(revp);
755 
756 	if (!ucode_capable(CPU))
757 		return (EM_NOTSUP);
758 
759 	mutex_enter(&cpu_lock);
760 	for (i = 0; i < max_ncpus; i++) {
761 		cpu_t *cpu;
762 
763 		if ((cpu = cpu_get(i)) == NULL)
764 			continue;
765 
766 		revp[i] = cpu->cpu_m.mcpu_ucode_info->cui_rev;
767 	}
768 	mutex_exit(&cpu_lock);
769 
770 	return (EM_OK);
771 }
772