|
@@ -46,6 +46,11 @@
|
|
|
|
|
|
#include "mce-internal.h"
|
|
|
|
|
|
+#define rcu_dereference_check_mce(p) \
|
|
|
+ rcu_dereference_check((p), \
|
|
|
+ rcu_read_lock_sched_held() || \
|
|
|
+ lockdep_is_held(&mce_read_mutex))
|
|
|
+
|
|
|
#define CREATE_TRACE_POINTS
|
|
|
#include <trace/events/mce.h>
|
|
|
|
|
@@ -158,7 +163,7 @@ void mce_log(struct mce *mce)
|
|
|
mce->finished = 0;
|
|
|
wmb();
|
|
|
for (;;) {
|
|
|
- entry = rcu_dereference(mcelog.next);
|
|
|
+ entry = rcu_dereference_check_mce(mcelog.next);
|
|
|
for (;;) {
|
|
|
/*
|
|
|
* When the buffer fills up discard new entries.
|
|
@@ -1500,7 +1505,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize,
|
|
|
return -ENOMEM;
|
|
|
|
|
|
mutex_lock(&mce_read_mutex);
|
|
|
- next = rcu_dereference(mcelog.next);
|
|
|
+ next = rcu_dereference_check_mce(mcelog.next);
|
|
|
|
|
|
/* Only supports full reads right now */
|
|
|
if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) {
|
|
@@ -1565,7 +1570,7 @@ timeout:
|
|
|
static unsigned int mce_poll(struct file *file, poll_table *wait)
|
|
|
{
|
|
|
poll_wait(file, &mce_wait, wait);
|
|
|
- if (rcu_dereference(mcelog.next))
|
|
|
+ if (rcu_dereference_check_mce(mcelog.next))
|
|
|
return POLLIN | POLLRDNORM;
|
|
|
return 0;
|
|
|
}
|