diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-18 12:17:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-18 12:17:17 -0400 |
commit | d6f3875252bb703a9a3de0b92f7ae154f12c986c (patch) | |
tree | d89d745f08f467d0e197056fa956ddc701574d38 /arch/x86/kernel | |
parent | cb41838bbc4403f7270a94b93a9a0d9fc9c2e7ea (diff) | |
parent | 3f10940e4fb69d312602078f2c5234206797ca31 (diff) |
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
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/microcode_core.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/microcode_intel.c | 22 |
2 files changed, 18 insertions, 8 deletions
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index cceb5bc3c3c2..2cd8c544e41a 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c | |||
@@ -201,9 +201,9 @@ static int do_microcode_update(const void __user *buf, size_t size) | |||
201 | return error; | 201 | return error; |
202 | } | 202 | } |
203 | 203 | ||
204 | static int microcode_open(struct inode *unused1, struct file *unused2) | 204 | static int microcode_open(struct inode *inode, struct file *file) |
205 | { | 205 | { |
206 | return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; | 206 | return capable(CAP_SYS_RAWIO) ? nonseekable_open(inode, file) : -EPERM; |
207 | } | 207 | } |
208 | 208 | ||
209 | static ssize_t microcode_write(struct file *file, const char __user *buf, | 209 | static ssize_t microcode_write(struct file *file, const char __user *buf, |
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index 85a343e28937..356170262a93 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c | |||
@@ -343,10 +343,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
343 | int (*get_ucode_data)(void *, const void *, size_t)) | 343 | int (*get_ucode_data)(void *, const void *, size_t)) |
344 | { | 344 | { |
345 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 345 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
346 | u8 *ucode_ptr = data, *new_mc = NULL, *mc; | 346 | u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL; |
347 | int new_rev = uci->cpu_sig.rev; | 347 | int new_rev = uci->cpu_sig.rev; |
348 | unsigned int leftover = size; | 348 | unsigned int leftover = size; |
349 | enum ucode_state state = UCODE_OK; | 349 | enum ucode_state state = UCODE_OK; |
350 | unsigned int curr_mc_size = 0; | ||
350 | 351 | ||
351 | while (leftover) { | 352 | while (leftover) { |
352 | struct microcode_header_intel mc_header; | 353 | 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 | break; | 362 | break; |
362 | } | 363 | } |
363 | 364 | ||
364 | mc = vmalloc(mc_size); | 365 | /* For performance reasons, reuse mc area when possible */ |
365 | if (!mc) | 366 | if (!mc || mc_size > curr_mc_size) { |
366 | break; | 367 | if (mc) |
368 | vfree(mc); | ||
369 | mc = vmalloc(mc_size); | ||
370 | if (!mc) | ||
371 | break; | ||
372 | curr_mc_size = mc_size; | ||
373 | } | ||
367 | 374 | ||
368 | if (get_ucode_data(mc, ucode_ptr, mc_size) || | 375 | if (get_ucode_data(mc, ucode_ptr, mc_size) || |
369 | microcode_sanity_check(mc) < 0) { | 376 | microcode_sanity_check(mc) < 0) { |
@@ -376,13 +383,16 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
376 | vfree(new_mc); | 383 | vfree(new_mc); |
377 | new_rev = mc_header.rev; | 384 | new_rev = mc_header.rev; |
378 | new_mc = mc; | 385 | new_mc = mc; |
379 | } else | 386 | mc = NULL; /* trigger new vmalloc */ |
380 | vfree(mc); | 387 | } |
381 | 388 | ||
382 | ucode_ptr += mc_size; | 389 | ucode_ptr += mc_size; |
383 | leftover -= mc_size; | 390 | leftover -= mc_size; |
384 | } | 391 | } |
385 | 392 | ||
393 | if (mc) | ||
394 | vfree(mc); | ||
395 | |||
386 | if (leftover) { | 396 | if (leftover) { |
387 | if (new_mc) | 397 | if (new_mc) |
388 | vfree(new_mc); | 398 | vfree(new_mc); |