Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 234799
b: refs/heads/master
c: 44d60c0
h: refs/heads/master
i:
  234797: b8a9ad2
  234795: 32cbb62
  234791: 21f3159
  234783: abb49ff
v: v3
  • Loading branch information
Borislav Petkov committed Feb 10, 2011
1 parent 621948a commit 3338018
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 17 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: 258721ef34fce97a7a6ca9cebebb303827645868
refs/heads/master: 44d60c0f5c58c2168f31df9a481761451840eb54
60 changes: 44 additions & 16 deletions trunk/arch/x86/kernel/microcode_amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ struct microcode_amd {
unsigned int mpb[0];
};

#define UCODE_MAX_SIZE 2048
#define UCODE_CONTAINER_SECTION_HDR 8
#define UCODE_CONTAINER_HEADER_SIZE 12

Expand Down Expand Up @@ -155,31 +154,60 @@ static int apply_microcode_amd(int cpu)
return 0;
}

static unsigned int verify_ucode_size(int cpu, const u8 *buf, unsigned int size)
{
struct cpuinfo_x86 *c = &cpu_data(cpu);
unsigned int max_size, actual_size;

#define F1XH_MPB_MAX_SIZE 2048
#define F14H_MPB_MAX_SIZE 1824
#define F15H_MPB_MAX_SIZE 4096

switch (c->x86) {
case 0x14:
max_size = F14H_MPB_MAX_SIZE;
break;
case 0x15:
max_size = F15H_MPB_MAX_SIZE;
break;
default:
max_size = F1XH_MPB_MAX_SIZE;
break;
}

actual_size = buf[4] + (buf[5] << 8);

if (actual_size > size || actual_size > max_size) {
pr_err("section size mismatch\n");
return 0;
}

return actual_size;
}

static struct microcode_header_amd *
get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size)
get_next_ucode(int cpu, const u8 *buf, unsigned int size, unsigned int *mc_size)
{
struct microcode_header_amd *mc;
unsigned int total_size;
struct microcode_header_amd *mc = NULL;
unsigned int actual_size = 0;

if (buf[0] != UCODE_UCODE_TYPE) {
pr_err("invalid type field in container file section header\n");
return NULL;
goto out;
}

total_size = buf[4] + (buf[5] << 8);

if (total_size > size || total_size > UCODE_MAX_SIZE) {
pr_err("section size mismatch\n");
return NULL;
}
actual_size = verify_ucode_size(cpu, buf, size);
if (!actual_size)
goto out;

mc = vzalloc(UCODE_MAX_SIZE);
mc = vzalloc(actual_size);
if (!mc)
return NULL;
goto out;

get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR, total_size);
*mc_size = total_size + UCODE_CONTAINER_SECTION_HDR;
get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR, actual_size);
*mc_size = actual_size + UCODE_CONTAINER_SECTION_HDR;

out:
return mc;
}

Expand Down Expand Up @@ -234,7 +262,7 @@ generic_load_microcode(int cpu, const u8 *data, size_t size)
leftover = size - offset;

while (leftover) {
mc_hdr = get_next_ucode(ucode_ptr, leftover, &mc_size);
mc_hdr = get_next_ucode(cpu, ucode_ptr, leftover, &mc_size);
if (!mc_hdr)
break;

Expand Down

0 comments on commit 3338018

Please sign in to comment.