diff options
-rw-r--r-- | arch/x86_64/kernel/mce.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 6ca066424dee..3a89d735a4f6 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -379,18 +379,23 @@ static void collect_tscs(void *data) | |||
379 | 379 | ||
380 | static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff_t *off) | 380 | static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff_t *off) |
381 | { | 381 | { |
382 | unsigned long cpu_tsc[NR_CPUS]; | 382 | unsigned long *cpu_tsc; |
383 | static DECLARE_MUTEX(mce_read_sem); | 383 | static DECLARE_MUTEX(mce_read_sem); |
384 | unsigned next; | 384 | unsigned next; |
385 | char __user *buf = ubuf; | 385 | char __user *buf = ubuf; |
386 | int i, err; | 386 | int i, err; |
387 | 387 | ||
388 | cpu_tsc = kmalloc(NR_CPUS * sizeof(long), GFP_KERNEL); | ||
389 | if (!cpu_tsc) | ||
390 | return -ENOMEM; | ||
391 | |||
388 | down(&mce_read_sem); | 392 | down(&mce_read_sem); |
389 | next = rcu_dereference(mcelog.next); | 393 | next = rcu_dereference(mcelog.next); |
390 | 394 | ||
391 | /* Only supports full reads right now */ | 395 | /* Only supports full reads right now */ |
392 | if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) { | 396 | if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) { |
393 | up(&mce_read_sem); | 397 | up(&mce_read_sem); |
398 | kfree(cpu_tsc); | ||
394 | return -EINVAL; | 399 | return -EINVAL; |
395 | } | 400 | } |
396 | 401 | ||
@@ -421,6 +426,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff | |||
421 | } | 426 | } |
422 | } | 427 | } |
423 | up(&mce_read_sem); | 428 | up(&mce_read_sem); |
429 | kfree(cpu_tsc); | ||
424 | return err ? -EFAULT : buf - ubuf; | 430 | return err ? -EFAULT : buf - ubuf; |
425 | } | 431 | } |
426 | 432 | ||