Stop mce-inject writing to mce_chrdev_ops
PATCH 1/1 Stop mce-inject writing to mce_chrdev_ops
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.
---
arch/x86/include/asm/mce.h +4 -1
@@ -201,7 +201,10 @@ int mce_notify_irq(void);void mce_notify_process (void ); DECLARE_PER_CPU(struct mce, injectm); -extern struct file_operations mce_chrdev_ops; + +extern void register_mce_write_hook (ssize_t (*)(struct file *filp, +const char __user *ubuf, +size_t usize,loff_t *off));/* * Exception handler
arch/x86/kernel/cpu/mcheck/mce-inject.c +1 -1
@@ -215,7 +215,7 @@ static int inject_init(void)if (!alloc_cpumask_var (&mce_inject_cpumask,GFP_KERNEL ))return -ENOMEM ;printk (KERN_INFO "Machine check injector initialized\n" ); - mce_chrdev_ops.write = mce_write; +register_mce_write_hook (mce_write);register_die_notifier (&mce_raise_nb);return 0 ; }
arch/x86/kernel/cpu/mcheck/mce.c +20 -1
@@ -1628,16 +1628,35 @@ static long mce_chrdev_ioctl(struct file *f, unsigned int cmd, } } +static ssize_t (*mce_write)(struct file *filp,const char __user *ubuf, +size_t usize,loff_t *off); + +void register_mce_write_hook (ssize_t (*fn)(struct file *filp,const char __user *ubuf, +size_t usize,loff_t *off)) +{ + mce_write = fn; +} +EXPORT_SYMBOL_GPL (register_mce_write_hook); + +ssize_t mce_chrdev_write (struct file *filp,const char __user *ubuf, +size_t usize,loff_t *off) +{ +if (mce_write) +return mce_write (filp, ubuf, usize, off); +else +return -ENODEV ; +} +/* Modified in mce-inject.c, so not static or const */ struct file_operations mce_chrdev_ops = { .open = mce_chrdev_open, .release = mce_chrdev_release, .read = mce_chrdev_read, + .write = mce_chrdev_write, .poll = mce_chrdev_poll, .unlocked_ioctl = mce_chrdev_ioctl, .llseek = no_llseek, }; -EXPORT_SYMBOL_GPL (mce_chrdev_ops);static struct miscdevice mce_chrdev_device = {MISC_MCELOG_MINOR ,
PATCH v2 1/1 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.
---
v2 - fixes some checkpatch complaints about tabs/spaces/long-lines, and
more importantly fixes the problems that Arjan wants fixed (rather than enabling him to apply the 2-liner to fix it).
arch/x86/include/asm/mce.h +4 -1
@@ -201,7 +201,10 @@ int mce_notify_irq(void);void mce_notify_process (void ); DECLARE_PER_CPU(struct mce, injectm); -extern struct file_operations mce_chrdev_ops; + +extern void register_mce_write_hook (ssize_t (*)(struct file *filp, +const char __user *ubuf, +size_t usize,loff_t *off));/* * Exception handler
arch/x86/kernel/cpu/mcheck/mce-inject.c +1 -1
@@ -215,7 +215,7 @@ static int inject_init(void)if (!alloc_cpumask_var (&mce_inject_cpumask,GFP_KERNEL ))return -ENOMEM ;printk (KERN_INFO "Machine check injector initialized\n" ); - mce_chrdev_ops.write = mce_write; +register_mce_write_hook (mce_write);register_die_notifier (&mce_raise_nb);return 0 ; }
arch/x86/kernel/cpu/mcheck/mce.c +22 -3
@@ -1628,16 +1628,35 @@ static long mce_chrdev_ioctl(struct file *f, unsigned int cmd, } } -/* Modified in mce-inject.c, so not static or const */ -struct file_operations mce_chrdev_ops = { +static ssize_t (*mce_write)(struct file *filp,const char __user *ubuf, +size_t usize,loff_t *off); + +void register_mce_write_hook (ssize_t (*fn)(struct file *filp, +const char __user *ubuf, +size_t usize,loff_t *off)) +{ + mce_write = fn; +} +EXPORT_SYMBOL_GPL (register_mce_write_hook); + +ssize_t mce_chrdev_write (struct file *filp,const char __user *ubuf, +size_t usize,loff_t *off) +{ +if (mce_write) +return mce_write (filp, ubuf, usize, off); +else +return -ENODEV ; +} + +static const struct file_operations mce_chrdev_ops = { .open = mce_chrdev_open, .release = mce_chrdev_release, .read = mce_chrdev_read, + .write = mce_chrdev_write, .poll = mce_chrdev_poll, .unlocked_ioctl = mce_chrdev_ioctl, .llseek = no_llseek, }; -EXPORT_SYMBOL_GPL (mce_chrdev_ops);static struct miscdevice mce_chrdev_device = {MISC_MCELOG_MINOR ,
PATCH v3 1/1 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.
---
v2 - fixes some checkpatch complaints about tabs/spaces/long-lines, and
more importantly fixes the problems that Arjan wants fixed (rather than enabling him to apply the 2-liner to fix it).
v3 - Error code when hook is not present should be EINVAL, not ENODEV
for backwards compatability.
arch/x86/include/asm/mce.h +4 -1
@@ -201,7 +201,10 @@ int mce_notify_irq(void);void mce_notify_process (void ); DECLARE_PER_CPU(struct mce, injectm); -extern struct file_operations mce_chrdev_ops; + +extern void register_mce_write_hook (ssize_t (*)(struct file *filp, +const char __user *ubuf, +size_t usize,loff_t *off));/* * Exception handler
arch/x86/kernel/cpu/mcheck/mce-inject.c +1 -1
@@ -215,7 +215,7 @@ static int inject_init(void)if (!alloc_cpumask_var (&mce_inject_cpumask,GFP_KERNEL ))return -ENOMEM ;printk (KERN_INFO "Machine check injector initialized\n" ); - mce_chrdev_ops.write = mce_write; +register_mce_write_hook (mce_write);register_die_notifier (&mce_raise_nb);return 0 ; }
arch/x86/kernel/cpu/mcheck/mce.c +22 -3
@@ -1628,16 +1628,35 @@ static long mce_chrdev_ioctl(struct file *f, unsigned int cmd, } } -/* Modified in mce-inject.c, so not static or const */ -struct file_operations mce_chrdev_ops = { +static ssize_t (*mce_write)(struct file *filp,const char __user *ubuf, +size_t usize,loff_t *off); + +void register_mce_write_hook (ssize_t (*fn)(struct file *filp, +const char __user *ubuf, +size_t usize,loff_t *off)) +{ + mce_write = fn; +} +EXPORT_SYMBOL_GPL (register_mce_write_hook); + +ssize_t mce_chrdev_write (struct file *filp,const char __user *ubuf, +size_t usize,loff_t *off) +{ +if (mce_write) +return mce_write (filp, ubuf, usize, off); +else +return -EINVAL ; +} + +static const struct file_operations mce_chrdev_ops = { .open = mce_chrdev_open, .release = mce_chrdev_release, .read = mce_chrdev_read, + .write = mce_chrdev_write, .poll = mce_chrdev_poll, .unlocked_ioctl = mce_chrdev_ioctl, .llseek = no_llseek, }; -EXPORT_SYMBOL_GPL (mce_chrdev_ops);static struct miscdevice mce_chrdev_device = {MISC_MCELOG_MINOR ,
[tip:x86/urgent] x86/mce: Make mce_chrdev_ops 'static const'
Commit-ID: 66f5ddf30a59f811818656cb2833c80da0340cfa Gitweb: http://git.kernel.org/tip/66f5ddf30a59f811818656cb2833c80da0340cfa Author: Luck, Tony <[email protected]> AuthorDate: Thu, 3 Nov 2011 11:46:47 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 8 Nov 2011 16:17:11 +0100
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.
--- arch/x86/include/asm/mce.h | 5 ++++- arch/x86/kernel/cpu/mcheck/mce-inject.c | 2 +- arch/x86/kernel/cpu/mcheck/mce.c | 25 ++++++++++++++++++++++--- 3 files changed, 27 insertions(+), 5 deletions(-)
arch/x86/include/asm/mce.h +4 -1
@@ -201,7 +201,10 @@ int mce_notify_irq(void);void mce_notify_process (void ); DECLARE_PER_CPU(struct mce, injectm); -extern struct file_operations mce_chrdev_ops; + +extern void register_mce_write_callback (ssize_t (*)(struct file *filp, +const char __user *ubuf, +size_t usize,loff_t *off));/* * Exception handler
arch/x86/kernel/cpu/mcheck/mce-inject.c +1 -1
@@ -208,7 +208,7 @@ static int inject_init(void)if (!alloc_cpumask_var (&mce_inject_cpumask,GFP_KERNEL ))return -ENOMEM ;printk (KERN_INFO "Machine check injector initialized\n" ); - mce_chrdev_ops.write = mce_write; +register_mce_write_callback (mce_write);register_nmi_handler (NMI_LOCAL , mce_raise_notify,0 ,"mce_notify" );return 0 ;
arch/x86/kernel/cpu/mcheck/mce.c +22 -3
@@ -1634,16 +1634,35 @@ static long mce_chrdev_ioctl(struct file *f, unsigned int cmd, } } -/* Modified in mce-inject.c, so not static or const */ -struct file_operations mce_chrdev_ops = { +static ssize_t (*mce_write)(struct file *filp,const char __user *ubuf, +size_t usize,loff_t *off); + +void register_mce_write_callback (ssize_t (*fn)(struct file *filp, +const char __user *ubuf, +size_t usize,loff_t *off)) +{ + mce_write = fn; +} +EXPORT_SYMBOL_GPL (register_mce_write_callback); + +ssize_t mce_chrdev_write (struct file *filp,const char __user *ubuf, +size_t usize,loff_t *off) +{ +if (mce_write) +return mce_write (filp, ubuf, usize, off); +else +return -EINVAL ; +} + +static const struct file_operations mce_chrdev_ops = { .open = mce_chrdev_open, .release = mce_chrdev_release, .read = mce_chrdev_read, + .write = mce_chrdev_write, .poll = mce_chrdev_poll, .unlocked_ioctl = mce_chrdev_ioctl, .llseek = no_llseek, }; -EXPORT_SYMBOL_GPL (mce_chrdev_ops);static struct miscdevice mce_chrdev_device = {MISC_MCELOG_MINOR ,