uint16_t reserved;
};
-struct __packed microcode_header_amd {
+struct microcode_patch {
uint32_t data_code;
uint32_t patch_id;
uint8_t mc_patch_data_id[2];
#define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000
#define UCODE_UCODE_TYPE 0x00000001
-struct microcode_patch {
- struct microcode_header_amd *mpb;
-};
-
-/* Temporary, until the microcode_* structure are disentangled. */
-#define microcode_amd microcode_patch
-
struct mpbhdr {
uint32_t type;
uint32_t len;
struct container_microcode {
uint32_t type; /* UCODE_UCODE_TYPE */
uint32_t len;
- struct microcode_header_amd patch[];
+ struct microcode_patch patch[];
};
/*
}
static enum microcode_match_result microcode_fits(
- const struct microcode_header_amd *patch)
+ const struct microcode_patch *patch)
{
unsigned int cpu = smp_processor_id();
const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu);
static bool match_cpu(const struct microcode_patch *patch)
{
- return patch && (microcode_fits(patch->mpb) == NEW_UCODE);
+ return patch && (microcode_fits(patch) == NEW_UCODE);
}
-static void free_patch(struct microcode_patch *mc_amd)
+static void free_patch(struct microcode_patch *patch)
{
- if ( mc_amd )
- {
- xfree(mc_amd->mpb);
- xfree(mc_amd);
- }
+ xfree(patch);
}
static enum microcode_match_result compare_header(
- const struct microcode_header_amd *new_header,
- const struct microcode_header_amd *old_header)
+ const struct microcode_patch *new, const struct microcode_patch *old)
{
- if ( new_header->processor_rev_id == old_header->processor_rev_id )
- return (new_header->patch_id > old_header->patch_id) ? NEW_UCODE
- : OLD_UCODE;
+ if ( new->processor_rev_id != old->processor_rev_id )
+ return MIS_UCODE;
- return MIS_UCODE;
+ return new->patch_id > old->patch_id ? NEW_UCODE : OLD_UCODE;
}
static enum microcode_match_result compare_patch(
const struct microcode_patch *new, const struct microcode_patch *old)
{
/* Both patches to compare are supposed to be applicable to local CPU. */
- ASSERT(microcode_fits(new->mpb) != MIS_UCODE);
- ASSERT(microcode_fits(old->mpb) != MIS_UCODE);
+ ASSERT(microcode_fits(new) != MIS_UCODE);
+ ASSERT(microcode_fits(old) != MIS_UCODE);
- return compare_header(new->mpb, old->mpb);
+ return compare_header(new, old);
}
static int apply_microcode(const struct microcode_patch *patch)
int hw_err;
unsigned int cpu = smp_processor_id();
struct cpu_signature *sig = &per_cpu(cpu_sig, cpu);
- const struct microcode_header_amd *hdr;
uint32_t rev, old_rev = sig->rev;
if ( !patch )
return -ENXIO;
}
- hdr = patch->mpb;
-
- hw_err = wrmsr_safe(MSR_AMD_PATCHLOADER, (unsigned long)hdr);
+ hw_err = wrmsr_safe(MSR_AMD_PATCHLOADER, (unsigned long)patch);
/* get patch id after patching */
rdmsrl(MSR_AMD_PATCHLEVEL, rev);
* Some processors leave the ucode blob mapping as UC after the update.
* Flush the mapping to regain normal cacheability.
*/
- flush_area_local(hdr, FLUSH_TLB_GLOBAL | FLUSH_ORDER(0));
+ flush_area_local(patch, FLUSH_TLB_GLOBAL | FLUSH_ORDER(0));
/* check current patch id and patch's id for match */
- if ( hw_err || (rev != hdr->patch_id) )
+ if ( hw_err || (rev != patch->patch_id) )
{
printk(XENLOG_ERR
"microcode: CPU%u update rev %#x to %#x failed, result %#x\n",
- cpu, old_rev, hdr->patch_id, rev);
+ cpu, old_rev, patch->patch_id, rev);
return -EIO;
}
static struct microcode_patch *cpu_request_microcode(const void *buf, size_t size)
{
- struct microcode_amd *mc_amd;
- const struct microcode_header_amd *saved = NULL;
+ const struct microcode_patch *saved = NULL;
struct microcode_patch *patch = NULL;
size_t offset = 0, saved_size = 0;
int error = 0;
goto out;
}
- mc_amd = xzalloc(struct microcode_amd);
- if ( !mc_amd )
- {
- printk(KERN_ERR "microcode: Cannot allocate memory for microcode patch\n");
- error = -ENOMEM;
- goto out;
- }
-
/*
* Multiple container file support:
* 1. check if this container file has equiv_cpu_id match
if ( error == -ENODATA )
error = 0;
- xfree(mc_amd);
goto out;
}
if ( saved )
{
- mc_amd->mpb = xmemdup_bytes(saved, saved_size);
- if ( mc_amd->mpb )
- patch = mc_amd;
- else
+ patch = xmemdup_bytes(saved, saved_size);
+ if ( !patch )
error = -ENOMEM;
}
- else
- free_patch(mc_amd);
out:
if ( error && !patch )