60 #define UCODE_MAX_HT 8 63 #define UCODE_WAIT_MS 10 138 char text[
sizeof ( *vendor ) + 1 ];
143 u.text[
sizeof (
u.text ) - 1 ] =
'\0';
160 unsigned int id,
int optional ) {
172 if ( optional && ( !
status.signature ) )
174 DBGC ( update,
"UCODE %#08x signature %#08x ucode %#08x->%#08x\n",
178 if ( !
status.signature ) {
179 DBGC2 ( update,
"UCODE %#08x has no signature\n",
id );
185 DBGC ( update,
"UCODE %#08x wrong APIC ID %#08x\n",
191 if (
control->apic_unexpected ) {
192 DBGC ( update,
"UCODE %#08x saw unexpected APIC ID %#08x\n",
193 id,
control->apic_unexpected );
199 DBGC ( update,
"UCODE %#08x was downgraded %#08x->%#08x\n",
206 if ( (
desc->signature ==
status.signature ) &&
208 DBGC ( update,
"UCODE %#08x failed update %#08x->%#08x " 209 "(wanted %#08x)\n",
id,
status.before,
254 DBGC (
image,
"UCODE %s could not allocate %d status reports\n",
279 DBGC (
image,
"UCODE %s failed on boot processor: %s\n",
296 for ( i = 0 ; i <=
max ; i++ ) {
344 if ( update->
desc ) {
346 DBGC (
image,
"UCODE %s+%#04zx found %s %#08x version %#08x\n",
367 if ( (
len %
sizeof (
dword ) ) != 0 ) {
368 DBGC (
image,
"UCODE %s+%#04zx invalid length %#zx\n",
381 DBGC (
image,
"UCODE %s+%#04zx bad checksum %#08x\n",
412 if ( remaining <
sizeof (
hdr ) ) {
413 DBGC (
image,
"UCODE %s+%#04zx too small for Intel header\n",
430 (
len <
sizeof (
hdr ) ) ||
431 (
len > remaining ) ||
435 DBGC2 (
image,
"UCODE %s+%#04zx is not an Intel update\n",
439 DBGC2 (
image,
"UCODE %s+%#04zx is an Intel update\n",
447 desc.signature =
hdr.signature;
458 if (
offset <= (
len -
sizeof ( exthdr ) ) ) {
463 offset +=
sizeof ( exthdr );
466 for ( i = 0 ; i < exthdr.
count ; i++ ) {
470 DBGC (
image,
"UCODE %s+%#04zx extended " 471 "signature overrun\n",
480 if ( (
ext.signature ==
hdr.signature ) &&
481 (
ext.platforms ==
hdr.platforms ) ) {
486 desc.signature =
ext.signature;
488 ext.platforms, update );
518 if ( remaining <
sizeof (
hdr ) ) {
519 DBGC (
image,
"UCODE %s+%#04zx too small for AMD header\n",
527 DBGC2 (
image,
"UCODE %s+%#04zx is not an AMD update\n",
531 DBGC2 (
image,
"UCODE %s+%#04zx is an AMD update\n",
534 DBGC (
image,
"UCODE %s+%#04zx unsupported equivalence table " 538 if (
hdr.len > ( remaining - sizeof (
hdr ) ) ) {
539 DBGC (
image,
"UCODE %s+%#04zx truncated equivalence table\n",
553 DBGC2 (
image,
"UCODE %s+%#04zx has %d equivalence table entries\n",
559 while ( used <
count ) {
562 if ( (
offset +
sizeof ( phdr ) ) > remaining ) {
563 DBGC (
image,
"UCODE %s+%#04zx truncated patch " 569 offset +=
sizeof ( phdr );
573 DBGC (
image,
"UCODE %s+%#04zx unsupported patch type " 577 if ( phdr.
len < sizeof ( patch ) ) {
578 DBGC (
image,
"UCODE %s+%#04zx underlength patch\n",
582 if ( phdr.
len > ( remaining -
offset ) ) {
583 DBGC (
image,
"UCODE %s+%#04zx truncated patch\n",
596 for ( i = 0 ; i <
count ; i++ ) {
599 ( i * (
sizeof ( equiv ) ) ) ),
601 if ( patch.
id == equiv.
id ) {
638 DBGC (
image,
"UCODE %s+%zx not recognised\n",
668 memset ( &update, 0,
sizeof ( update ) );
690 DBGC (
image,
"UCODE %s applying to %s %#08x",
697 DBGC (
image,
"UCODE %s found %d matching update(s)\n",
702 sizeof ( update.
desc[0] ) );
704 if ( ! update.
desc ) {
710 check = update.
count;
723 if ( summary.
low == summary.
high ) {
724 printf (
"already version %#x", summary.
low );
726 printf (
"updated version %#x->%#x",
774 ( (
header.intel.date.century == 0x19 ) ||
775 ( (
header.intel.date.century >= 0x20 ) &&
776 (
header.intel.date.century <= 0x29 ) ) ) ) {
777 DBGC (
image,
"UCODE %s+%#04zx looks like an Intel update\n",
785 DBGC (
image,
"UCODE %s+%#04zx looks like an AMD update\n",
uint16_t id
Equivalence ID.
#define EINVAL
Invalid argument.
#define INTEL_UCODE_HVER
Intel microcode header version number.
struct arbelprm_rc_send_wqe rc
static int ucode_parse_amd(struct image *image, size_t start, struct ucode_update *update)
Parse AMD microcode image.
static int ucode_parse_intel(struct image *image, size_t start, struct ucode_update *update)
Parse Intel microcode image.
uint8_t checksum
Checksum.
int printf(const char *fmt,...)
Write a formatted string to the console.
userptr_t data
Raw file image.
#define CPUID_FEATURES
Get standard features.
static void ucode_describe(struct image *image, size_t start, const struct ucode_vendor *vendor, const struct ucode_descriptor *desc, uint32_t platforms, struct ucode_update *update)
Add descriptor to list (if applicable)
struct ucode_descriptor * desc
Update descriptors (if being populated)
#define MSR_UCODE_TRIGGER_INTEL
Intel microcode load trigger MSR.
static int ucode_parse(struct image *image, struct ucode_update *update)
Parse microcode image.
static struct ucode_vendor ucode_amd
AMD CPU vendor.
struct golan_inbox_hdr hdr
Message header.
#define UCODE_VERSION_MIN
Minimum possible microcode version.
#define AMD_UCODE_EQUIV_TYPE
AMD microcode equivalence table type.
#define ENOEXEC
Exec format error.
static unsigned short vendor
An Intel microcode extended signature.
static int ucode_verify(struct image *image, size_t start, size_t len)
Verify checksum.
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
#define CPUID_VENDOR_ID
Get vendor ID and largest standard function.
unsigned long user_to_phys(userptr_t userptr, off_t offset)
Convert user pointer to physical address.
uint64_t desc
Microcode descriptor list physical address.
struct ucode_vendor * vendor
CPU vendor, if known.
An executable image type.
#define ENOENT
No such file or directory.
#define PROBE_NORMAL
Normal image probe priority.
unsigned long long uint64_t
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
A microcode update summary.
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
uint8_t ver_high
Microcode version is reported via high dword.
static int ucode_exec(struct image *image)
Execute microcode update.
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Access to external ("user") memory.
uint32_t platforms
Supported platforms.
unsigned int count
Number of CPUs processed.
static int ucode_probe(struct image *image)
Probe microcode update image.
char * name
Name of this image type.
#define ENOTSUP
Operation not supported.
char * cmdline
Command line to pass to image.
#define MSR_PLATFORM_ID
Platform ID MSR.
uint32_t start
Starting offset.
void mp_start_all(mp_func_t func, void *opaque)
Start a multiprocessor function on all application processors.
void memset_user(userptr_t userptr, off_t offset, int c, size_t len)
Fill user buffer with a constant byte.
char * strstr(const char *haystack, const char *needle)
Find substring.
A microcode update descriptor.
#define ENOMEM
Not enough space.
static struct ucode_vendor ucode_intel
Intel CPU vendor.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint32_t userptr_t
A pointer to a user buffer.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define build_assert(condition)
Assert a condition at build time (after dead code elimination)
#define MSR_PLATFORM_ID_VALUE(value)
Extract platform ID from MSR value.
uint16_t count
Number of entries.
An AMD microcode equivalence table entry.
A microcode update control.
uint8_t id
Request identifier.
unsigned int mp_max_cpuid(void)
Get maximum CPU identifier.
#define ERANGE
Result too large.
char * strerror(int errno)
Retrieve string representation of error number.
static void(* free)(struct refcnt *refcnt))
x86 CPU feature detection
void * zalloc(size_t size)
Allocate cleared memory.
uint8_t platform_id
Platform ID.
size_t len
Length of raw file image.
int32_t low
Lowest observed microcode version.
static struct ucode_vendor * ucode_vendors[]
List of known CPU vendors.
unsigned int mp_boot_cpuid(void)
Get boot CPU identifier.
#define AMD_UCODE_PATCH_TYPE
AMD patch type.
uint32_t trigger_msr
Microcode load trigger MSR.
uint32_t signature
CPU signature.
Multiprocessor functions.
#define UCODE_VERSION_MAX
Maximum possible microcode version.
uint16_t ext
Extended status.
A microcode update status report.
#define UCODE_MAX_HT
Maximum number of hyperthread siblings.
static int ucode_status(struct ucode_update *update, struct ucode_control *control, struct ucode_summary *summary, unsigned int id, int optional)
Check status report.
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
static __always_inline void ufree(userptr_t userptr)
Free external memory.
static __always_inline userptr_t umalloc(size_t size)
Allocate external memory.
#define AMD_UCODE_MAGIC
AMD microcode magic signature.
#define ENOTTY
Inappropriate I/O control operation.
static const char * ucode_vendor_name(const union ucode_vendor_id *vendor)
Get CPU vendor name (for debugging)
uint16_t id
Equivalence ID.
int32_t version
Microcode version.
#define EIO
Input/output error.
struct image_type ucode_image_type __image_type(PROBE_NORMAL)
Microcode update image type.
#define MSR_UCODE_TRIGGER_AMD
AMD microcode load trigger MSR.
struct ena_aq_header header
Header.
unsigned int count
Number of potentially relevant signatures found.
uint32_t signature
Boot processor CPU signature.
uint32_t platform
Platform ID.
#define INTEL_UCODE_LVER
Intel microcode loader version number.
union ucode_vendor_id id
Vendor string.
uint8_t string[12]
Human-readable string.
uint16_t offset
Offset to command line.
uint8_t ver_clear
Microcode version requires manual clear.
void mp_exec_boot(mp_func_t func, void *opaque)
Execute a multiprocessor function on the boot processor.
#define UCODE_WAIT_MS
Time to wait for a microcode update to complete.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
int32_t high
Highest observed microcode version.
#define INTEL_UCODE_DATA_LEN
Intel microcode default data length.
#define UCODE_SIGNATURE_MASK
CPUID signature applicability mask.
#define INTEL_UCODE_ALIGN
Intel microcode file alignment.
Model-specific registers.
uint32_t apic_max
Maximum expected APIC ID.
void * memset(void *dest, int character, size_t len) __nonnull
static int ucode_update_all(struct image *image, struct ucode_update *update, struct ucode_summary *summary)
Update microcode on all CPUs.