#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/capability.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
#include <xen/interface/xen.h>
#include <xen/events.h>
static int xen_mce_chrdev_open_count; /* #times opened */
static int xen_mce_chrdev_open_exclu; /* already open exclusive? */
+static DECLARE_WAIT_QUEUE_HEAD(xen_mce_chrdev_wait);
+
static int xen_mce_chrdev_open(struct inode *inode, struct file *file)
{
spin_lock(&xen_mce_chrdev_state_lock);
return err ? err : buf - ubuf;
}
+static unsigned int xen_mce_chrdev_poll(struct file *file, poll_table *wait)
+{
+ poll_wait(file, &xen_mce_chrdev_wait, wait);
+
+ if (xen_mcelog.next)
+ return POLLIN | POLLRDNORM;
+
+ return 0;
+}
+
static long xen_mce_chrdev_ioctl(struct file *f, unsigned int cmd,
unsigned long arg)
{
.open = xen_mce_chrdev_open,
.release = xen_mce_chrdev_release,
.read = xen_mce_chrdev_read,
+ .poll = xen_mce_chrdev_poll,
.unlocked_ioctl = xen_mce_chrdev_ioctl,
.llseek = no_llseek,
};
pr_err(XEN_MCELOG
"Failed to handle nonurgent mc_info queue.\n");
+ /* wake processes polling /dev/mcelog */
+ wake_up_interruptible(&xen_mce_chrdev_wait);
+
mutex_unlock(&mcelog_lock);
}
static DECLARE_WORK(xen_mce_work, xen_mce_work_fn);