diff options
author | Luck, Tony <tony.luck@intel.com> | 2011-11-03 14:46:47 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-11-08 10:17:11 -0500 |
commit | 66f5ddf30a59f811818656cb2833c80da0340cfa (patch) | |
tree | f10616e055f5c92007bf4a4304884a3a66b9b652 /arch | |
parent | 1ea6b8f48918282bdca0b32a34095504ee65bab5 (diff) |
x86/mce: Make mce_chrdev_ops 'static const'
Arjan would like to make struct file_operations const, but
mce-inject directly writes to the mce_chrdev_ops to install its
write handler. In an ideal world mce-inject would have its own
character device, but we have a sizable legacy of test scripts
that hardwire "/dev/mcelog", so it would be painful to switch to
a separate device now. Instead, this patch switches to a stub
function in the mce code, with a registration helper that
mce-inject can call when it is loaded.
Note that this would also allow for a sane process to allow
mce-inject to be unloaded again (with an unregister function,
and appropriate module_{get,put}() calls), but that is left for
potential future patches.
Reported-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: http://lkml.kernel.org/r/4eb2e1971326651a3b@agluck-desktop.sc.intel.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/mce.h | 5 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-inject.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 25 |
3 files changed, 27 insertions, 5 deletions
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index c9321f34e55b..0e8ae57d3656 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h | |||
@@ -201,7 +201,10 @@ int mce_notify_irq(void); | |||
201 | void mce_notify_process(void); | 201 | void mce_notify_process(void); |
202 | 202 | ||
203 | DECLARE_PER_CPU(struct mce, injectm); | 203 | DECLARE_PER_CPU(struct mce, injectm); |
204 | extern struct file_operations mce_chrdev_ops; | 204 | |
205 | extern void register_mce_write_callback(ssize_t (*)(struct file *filp, | ||
206 | const char __user *ubuf, | ||
207 | size_t usize, loff_t *off)); | ||
205 | 208 | ||
206 | /* | 209 | /* |
207 | * Exception handler | 210 | * Exception handler |
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c index 6199232161cf..319882ef848d 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-inject.c +++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c | |||
@@ -208,7 +208,7 @@ static int inject_init(void) | |||
208 | if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) | 208 | if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) |
209 | return -ENOMEM; | 209 | return -ENOMEM; |
210 | printk(KERN_INFO "Machine check injector initialized\n"); | 210 | printk(KERN_INFO "Machine check injector initialized\n"); |
211 | mce_chrdev_ops.write = mce_write; | 211 | register_mce_write_callback(mce_write); |
212 | register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, | 212 | register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, |
213 | "mce_notify"); | 213 | "mce_notify"); |
214 | return 0; | 214 | return 0; |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 362056aefeb4..2af127d4c3d1 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -1634,16 +1634,35 @@ static long mce_chrdev_ioctl(struct file *f, unsigned int cmd, | |||
1634 | } | 1634 | } |
1635 | } | 1635 | } |
1636 | 1636 | ||
1637 | /* Modified in mce-inject.c, so not static or const */ | 1637 | static ssize_t (*mce_write)(struct file *filp, const char __user *ubuf, |
1638 | struct file_operations mce_chrdev_ops = { | 1638 | size_t usize, loff_t *off); |
1639 | |||
1640 | void register_mce_write_callback(ssize_t (*fn)(struct file *filp, | ||
1641 | const char __user *ubuf, | ||
1642 | size_t usize, loff_t *off)) | ||
1643 | { | ||
1644 | mce_write = fn; | ||
1645 | } | ||
1646 | EXPORT_SYMBOL_GPL(register_mce_write_callback); | ||
1647 | |||
1648 | ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf, | ||
1649 | size_t usize, loff_t *off) | ||
1650 | { | ||
1651 | if (mce_write) | ||
1652 | return mce_write(filp, ubuf, usize, off); | ||
1653 | else | ||
1654 | return -EINVAL; | ||
1655 | } | ||
1656 | |||
1657 | static const struct file_operations mce_chrdev_ops = { | ||
1639 | .open = mce_chrdev_open, | 1658 | .open = mce_chrdev_open, |
1640 | .release = mce_chrdev_release, | 1659 | .release = mce_chrdev_release, |
1641 | .read = mce_chrdev_read, | 1660 | .read = mce_chrdev_read, |
1661 | .write = mce_chrdev_write, | ||
1642 | .poll = mce_chrdev_poll, | 1662 | .poll = mce_chrdev_poll, |
1643 | .unlocked_ioctl = mce_chrdev_ioctl, | 1663 | .unlocked_ioctl = mce_chrdev_ioctl, |
1644 | .llseek = no_llseek, | 1664 | .llseek = no_llseek, |
1645 | }; | 1665 | }; |
1646 | EXPORT_SYMBOL_GPL(mce_chrdev_ops); | ||
1647 | 1666 | ||
1648 | static struct miscdevice mce_chrdev_device = { | 1667 | static struct miscdevice mce_chrdev_device = { |
1649 | MISC_MCELOG_MINOR, | 1668 | MISC_MCELOG_MINOR, |