@@ -29,11 +29,7 @@ static char *mce_helper_argv[2] = { mce_helper, NULL };
29
29
* separate MCEs from kernel messages to avoid bogus bug reports.
30
30
*/
31
31
32
- static struct mce_log_buffer mcelog = {
33
- .signature = MCE_LOG_SIGNATURE ,
34
- .len = MCE_LOG_LEN ,
35
- .recordlen = sizeof (struct mce ),
36
- };
32
+ static struct mce_log_buffer * mcelog ;
37
33
38
34
static DECLARE_WAIT_QUEUE_HEAD (mce_chrdev_wait );
39
35
@@ -45,21 +41,21 @@ static int dev_mce_log(struct notifier_block *nb, unsigned long val,
45
41
46
42
mutex_lock (& mce_chrdev_read_mutex );
47
43
48
- entry = mcelog . next ;
44
+ entry = mcelog -> next ;
49
45
50
46
/*
51
47
* When the buffer fills up discard new entries. Assume that the
52
48
* earlier errors are the more interesting ones:
53
49
*/
54
- if (entry >= MCE_LOG_LEN ) {
55
- set_bit (MCE_OVERFLOW , (unsigned long * )& mcelog . flags );
50
+ if (entry >= mcelog -> len ) {
51
+ set_bit (MCE_OVERFLOW , (unsigned long * )& mcelog -> flags );
56
52
goto unlock ;
57
53
}
58
54
59
- mcelog . next = entry + 1 ;
55
+ mcelog -> next = entry + 1 ;
60
56
61
- memcpy (mcelog . entry + entry , mce , sizeof (struct mce ));
62
- mcelog . entry [entry ].finished = 1 ;
57
+ memcpy (mcelog -> entry + entry , mce , sizeof (struct mce ));
58
+ mcelog -> entry [entry ].finished = 1 ;
63
59
64
60
/* wake processes polling /dev/mcelog */
65
61
wake_up_interruptible (& mce_chrdev_wait );
@@ -214,21 +210,21 @@ static ssize_t mce_chrdev_read(struct file *filp, char __user *ubuf,
214
210
215
211
/* Only supports full reads right now */
216
212
err = - EINVAL ;
217
- if (* off != 0 || usize < MCE_LOG_LEN * sizeof (struct mce ))
213
+ if (* off != 0 || usize < mcelog -> len * sizeof (struct mce ))
218
214
goto out ;
219
215
220
- next = mcelog . next ;
216
+ next = mcelog -> next ;
221
217
err = 0 ;
222
218
223
219
for (i = 0 ; i < next ; i ++ ) {
224
- struct mce * m = & mcelog . entry [i ];
220
+ struct mce * m = & mcelog -> entry [i ];
225
221
226
222
err |= copy_to_user (buf , m , sizeof (* m ));
227
223
buf += sizeof (* m );
228
224
}
229
225
230
- memset (mcelog . entry , 0 , next * sizeof (struct mce ));
231
- mcelog . next = 0 ;
226
+ memset (mcelog -> entry , 0 , next * sizeof (struct mce ));
227
+ mcelog -> next = 0 ;
232
228
233
229
if (err )
234
230
err = - EFAULT ;
@@ -242,7 +238,7 @@ static ssize_t mce_chrdev_read(struct file *filp, char __user *ubuf,
242
238
static __poll_t mce_chrdev_poll (struct file * file , poll_table * wait )
243
239
{
244
240
poll_wait (file , & mce_chrdev_wait , wait );
245
- if (READ_ONCE (mcelog . next ))
241
+ if (READ_ONCE (mcelog -> next ))
246
242
return EPOLLIN | EPOLLRDNORM ;
247
243
if (!mce_apei_read_done && apei_check_mce ())
248
244
return EPOLLIN | EPOLLRDNORM ;
@@ -261,13 +257,13 @@ static long mce_chrdev_ioctl(struct file *f, unsigned int cmd,
261
257
case MCE_GET_RECORD_LEN :
262
258
return put_user (sizeof (struct mce ), p );
263
259
case MCE_GET_LOG_LEN :
264
- return put_user (MCE_LOG_LEN , p );
260
+ return put_user (mcelog -> len , p );
265
261
case MCE_GETCLEAR_FLAGS : {
266
262
unsigned flags ;
267
263
268
264
do {
269
- flags = mcelog . flags ;
270
- } while (cmpxchg (& mcelog . flags , flags , 0 ) != flags );
265
+ flags = mcelog -> flags ;
266
+ } while (cmpxchg (& mcelog -> flags , flags , 0 ) != flags );
271
267
272
268
return put_user (flags , p );
273
269
}
@@ -339,8 +335,18 @@ static struct miscdevice mce_chrdev_device = {
339
335
340
336
static __init int dev_mcelog_init_device (void )
341
337
{
338
+ int mce_log_len ;
342
339
int err ;
343
340
341
+ mce_log_len = max (MCE_LOG_MIN_LEN , num_online_cpus ());
342
+ mcelog = kzalloc (sizeof (* mcelog ) + mce_log_len * sizeof (struct mce ), GFP_KERNEL );
343
+ if (!mcelog )
344
+ return - ENOMEM ;
345
+
346
+ strncpy (mcelog -> signature , MCE_LOG_SIGNATURE , sizeof (mcelog -> signature ));
347
+ mcelog -> len = mce_log_len ;
348
+ mcelog -> recordlen = sizeof (struct mce );
349
+
344
350
/* register character device /dev/mcelog */
345
351
err = misc_register (& mce_chrdev_device );
346
352
if (err ) {
@@ -350,6 +356,7 @@ static __init int dev_mcelog_init_device(void)
350
356
else
351
357
pr_err ("Unable to init device /dev/mcelog (rc: %d)\n" , err );
352
358
359
+ kfree (mcelog );
353
360
return err ;
354
361
}
355
362
0 commit comments