Commit d6f38752 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-microcode-for-linus' of...

Merge branch 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86/microcode: Use nonseekable_open()
  x86: Improve Intel microcode loader performance
parents cb41838b 3f10940e
...@@ -201,9 +201,9 @@ static int do_microcode_update(const void __user *buf, size_t size) ...@@ -201,9 +201,9 @@ static int do_microcode_update(const void __user *buf, size_t size)
return error; return error;
} }
static int microcode_open(struct inode *unused1, struct file *unused2) static int microcode_open(struct inode *inode, struct file *file)
{ {
return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; return capable(CAP_SYS_RAWIO) ? nonseekable_open(inode, file) : -EPERM;
} }
static ssize_t microcode_write(struct file *file, const char __user *buf, static ssize_t microcode_write(struct file *file, const char __user *buf,
......
...@@ -343,10 +343,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, ...@@ -343,10 +343,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
int (*get_ucode_data)(void *, const void *, size_t)) int (*get_ucode_data)(void *, const void *, size_t))
{ {
struct ucode_cpu_info *uci = ucode_cpu_info + cpu; struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
u8 *ucode_ptr = data, *new_mc = NULL, *mc; u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL;
int new_rev = uci->cpu_sig.rev; int new_rev = uci->cpu_sig.rev;
unsigned int leftover = size; unsigned int leftover = size;
enum ucode_state state = UCODE_OK; enum ucode_state state = UCODE_OK;
unsigned int curr_mc_size = 0;
while (leftover) { while (leftover) {
struct microcode_header_intel mc_header; struct microcode_header_intel mc_header;
...@@ -361,9 +362,15 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, ...@@ -361,9 +362,15 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
break; break;
} }
mc = vmalloc(mc_size); /* For performance reasons, reuse mc area when possible */
if (!mc) if (!mc || mc_size > curr_mc_size) {
break; if (mc)
vfree(mc);
mc = vmalloc(mc_size);
if (!mc)
break;
curr_mc_size = mc_size;
}
if (get_ucode_data(mc, ucode_ptr, mc_size) || if (get_ucode_data(mc, ucode_ptr, mc_size) ||
microcode_sanity_check(mc) < 0) { microcode_sanity_check(mc) < 0) {
...@@ -376,13 +383,16 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, ...@@ -376,13 +383,16 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
vfree(new_mc); vfree(new_mc);
new_rev = mc_header.rev; new_rev = mc_header.rev;
new_mc = mc; new_mc = mc;
} else mc = NULL; /* trigger new vmalloc */
vfree(mc); }
ucode_ptr += mc_size; ucode_ptr += mc_size;
leftover -= mc_size; leftover -= mc_size;
} }
if (mc)
vfree(mc);
if (leftover) { if (leftover) {
if (new_mc) if (new_mc)
vfree(new_mc); vfree(new_mc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment