Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 28981
b: refs/heads/master
c: ba528f2
h: refs/heads/master
i:
  28979: 2338cee
v: v3
  • Loading branch information
Jan Beulich authored and Linus Torvalds committed Jun 23, 2006
1 parent 4322ca9 commit ba074b9
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 25 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 27b07da7332f03a935cd13b6a6beb780bf19e7a4
refs/heads/master: ba528f2854e8632c8d04ddcd45f06c47bc7188b0
73 changes: 49 additions & 24 deletions trunk/arch/i386/kernel/microcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver");
MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>");
MODULE_LICENSE("GPL");

#define MICROCODE_VERSION "1.14"
static int verbose;
module_param(verbose, int, 0644);

#define MICROCODE_VERSION "1.14a"

#define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */
#define MC_HEADER_SIZE (sizeof (microcode_header_t)) /* 48 bytes */
Expand Down Expand Up @@ -122,14 +125,15 @@ static unsigned int user_buffer_size; /* it's size */

typedef enum mc_error_code {
MC_SUCCESS = 0,
MC_NOTFOUND = 1,
MC_MARKED = 2,
MC_ALLOCATED = 3,
MC_IGNORED = 1,
MC_NOTFOUND = 2,
MC_MARKED = 3,
MC_ALLOCATED = 4,
} mc_error_code_t;

static struct ucode_cpu_info {
unsigned int sig;
unsigned int pf;
unsigned int pf, orig_pf;
unsigned int rev;
unsigned int cksum;
mc_error_code_t err;
Expand Down Expand Up @@ -164,6 +168,7 @@ static void collect_cpu_info (void *unused)
rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
uci->pf = 1 << ((val[1] >> 18) & 7);
}
uci->orig_pf = uci->pf;
}

wrmsr(MSR_IA32_UCODE_REV, 0, 0);
Expand Down Expand Up @@ -197,21 +202,34 @@ static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_he
pr_debug(" Checksum 0x%x\n", cksum);

if (mc_header->rev < uci->rev) {
printk(KERN_ERR "microcode: CPU%d not 'upgrading' to earlier revision"
" 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev);
goto out;
if (uci->err == MC_NOTFOUND) {
uci->err = MC_IGNORED;
uci->cksum = mc_header->rev;
} else if (uci->err == MC_IGNORED && uci->cksum < mc_header->rev)
uci->cksum = mc_header->rev;
} else if (mc_header->rev == uci->rev) {
/* notify the caller of success on this cpu */
uci->err = MC_SUCCESS;
goto out;
if (uci->err < MC_MARKED) {
/* notify the caller of success on this cpu */
uci->err = MC_SUCCESS;
}
} else if (uci->err != MC_ALLOCATED || mc_header->rev > uci->mc->hdr.rev) {
pr_debug("microcode: CPU%d found a matching microcode update with "
" revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev);
uci->cksum = cksum;
uci->pf = pf; /* keep the original mc pf for cksum calculation */
uci->err = MC_MARKED; /* found the match */
for_each_online_cpu(cpu_num) {
if (ucode_cpu_info + cpu_num != uci
&& ucode_cpu_info[cpu_num].mc == uci->mc) {
uci->mc = NULL;
break;
}
}
if (uci->mc != NULL) {
vfree(uci->mc);
uci->mc = NULL;
}
}

pr_debug("microcode: CPU%d found a matching microcode update with "
" revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev);
uci->cksum = cksum;
uci->pf = pf; /* keep the original mc pf for cksum calculation */
uci->err = MC_MARKED; /* found the match */
out:
return;
}

Expand Down Expand Up @@ -253,10 +271,8 @@ static int find_matching_ucodes (void)

for_each_online_cpu(cpu_num) {
struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/
continue;

if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->pf))
if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->orig_pf))
mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum);
}

Expand Down Expand Up @@ -295,9 +311,8 @@ static int find_matching_ucodes (void)
}
for_each_online_cpu(cpu_num) {
struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/
continue;
if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->pf)) {

if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->orig_pf)) {
mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum);
}
}
Expand Down Expand Up @@ -368,6 +383,13 @@ static void do_update_one (void * unused)
struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;

if (uci->mc == NULL) {
if (verbose) {
if (uci->err == MC_SUCCESS)
printk(KERN_INFO "microcode: CPU%d already at revision 0x%x\n",
cpu_num, uci->rev);
else
printk(KERN_INFO "microcode: No new microcode data for CPU%d\n", cpu_num);
}
return;
}

Expand Down Expand Up @@ -426,6 +448,9 @@ static int do_microcode_update (void)
ucode_cpu_info[j].mc = NULL;
}
}
if (ucode_cpu_info[i].err == MC_IGNORED && verbose)
printk(KERN_WARNING "microcode: CPU%d not 'upgrading' to earlier revision"
" 0x%x (current=0x%x)\n", i, ucode_cpu_info[i].cksum, ucode_cpu_info[i].rev);
}
out:
return error;
Expand Down

0 comments on commit ba074b9

Please sign in to comment.