aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/mcelog.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen/mcelog.c')
-rw-r--r--drivers/xen/mcelog.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/xen/mcelog.c b/drivers/xen/mcelog.c
index 804aa3c181c2..8feee08bcb43 100644
--- a/drivers/xen/mcelog.c
+++ b/drivers/xen/mcelog.c
@@ -41,6 +41,8 @@
41#include <linux/miscdevice.h> 41#include <linux/miscdevice.h>
42#include <linux/uaccess.h> 42#include <linux/uaccess.h>
43#include <linux/capability.h> 43#include <linux/capability.h>
44#include <linux/poll.h>
45#include <linux/sched.h>
44 46
45#include <xen/interface/xen.h> 47#include <xen/interface/xen.h>
46#include <xen/events.h> 48#include <xen/events.h>
@@ -67,6 +69,8 @@ static DEFINE_SPINLOCK(xen_mce_chrdev_state_lock);
67static int xen_mce_chrdev_open_count; /* #times opened */ 69static int xen_mce_chrdev_open_count; /* #times opened */
68static int xen_mce_chrdev_open_exclu; /* already open exclusive? */ 70static int xen_mce_chrdev_open_exclu; /* already open exclusive? */
69 71
72static DECLARE_WAIT_QUEUE_HEAD(xen_mce_chrdev_wait);
73
70static int xen_mce_chrdev_open(struct inode *inode, struct file *file) 74static int xen_mce_chrdev_open(struct inode *inode, struct file *file)
71{ 75{
72 spin_lock(&xen_mce_chrdev_state_lock); 76 spin_lock(&xen_mce_chrdev_state_lock);
@@ -135,6 +139,16 @@ out:
135 return err ? err : buf - ubuf; 139 return err ? err : buf - ubuf;
136} 140}
137 141
142static unsigned int xen_mce_chrdev_poll(struct file *file, poll_table *wait)
143{
144 poll_wait(file, &xen_mce_chrdev_wait, wait);
145
146 if (xen_mcelog.next)
147 return POLLIN | POLLRDNORM;
148
149 return 0;
150}
151
138static long xen_mce_chrdev_ioctl(struct file *f, unsigned int cmd, 152static long xen_mce_chrdev_ioctl(struct file *f, unsigned int cmd,
139 unsigned long arg) 153 unsigned long arg)
140{ 154{
@@ -166,6 +180,7 @@ static const struct file_operations xen_mce_chrdev_ops = {
166 .open = xen_mce_chrdev_open, 180 .open = xen_mce_chrdev_open,
167 .release = xen_mce_chrdev_release, 181 .release = xen_mce_chrdev_release,
168 .read = xen_mce_chrdev_read, 182 .read = xen_mce_chrdev_read,
183 .poll = xen_mce_chrdev_poll,
169 .unlocked_ioctl = xen_mce_chrdev_ioctl, 184 .unlocked_ioctl = xen_mce_chrdev_ioctl,
170 .llseek = no_llseek, 185 .llseek = no_llseek,
171}; 186};
@@ -329,6 +344,9 @@ static void xen_mce_work_fn(struct work_struct *work)
329 pr_err(XEN_MCELOG 344 pr_err(XEN_MCELOG
330 "Failed to handle nonurgent mc_info queue.\n"); 345 "Failed to handle nonurgent mc_info queue.\n");
331 346
347 /* wake processes polling /dev/mcelog */
348 wake_up_interruptible(&xen_mce_chrdev_wait);
349
332 mutex_unlock(&mcelog_lock); 350 mutex_unlock(&mcelog_lock);
333} 351}
334static DECLARE_WORK(xen_mce_work, xen_mce_work_fn); 352static DECLARE_WORK(xen_mce_work, xen_mce_work_fn);