On Tue, Apr 05, 2016 at 07:10:07AM +0200, Juergen Gross wrote: > Use the smp_call_on_cpu() function to call system management > mode on cpu 0. > Make call secure by adding get_online_cpus() to avoid e.g. suspend > resume cycles in between. > > Signed-off-by: Juergen Gross <jgr...@suse.com> > --- > V4: add call to get_online_cpus()
Pali, any chance to test this ? Thanks, Guenter > --- > drivers/hwmon/dell-smm-hwmon.c | 35 ++++++++++++++++++++--------------- > 1 file changed, 20 insertions(+), 15 deletions(-) > > diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c > index c43318d..643f3a1 100644 > --- a/drivers/hwmon/dell-smm-hwmon.c > +++ b/drivers/hwmon/dell-smm-hwmon.c > @@ -21,6 +21,7 @@ > > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > > +#include <linux/cpu.h> > #include <linux/delay.h> > #include <linux/module.h> > #include <linux/types.h> > @@ -35,6 +36,7 @@ > #include <linux/uaccess.h> > #include <linux/io.h> > #include <linux/sched.h> > +#include <linux/smp.h> > > #include <linux/i8k.h> > > @@ -130,23 +132,15 @@ static inline const char *i8k_get_dmi_data(int field) > /* > * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard. > */ > -static int i8k_smm(struct smm_regs *regs) > +static int i8k_smm_func(void *par) > { > int rc; > + struct smm_regs *regs = par; > int eax = regs->eax; > - cpumask_var_t old_mask; > > /* SMM requires CPU 0 */ > - if (!alloc_cpumask_var(&old_mask, GFP_KERNEL)) > - return -ENOMEM; > - cpumask_copy(old_mask, ¤t->cpus_allowed); > - rc = set_cpus_allowed_ptr(current, cpumask_of(0)); > - if (rc) > - goto out; > - if (smp_processor_id() != 0) { > - rc = -EBUSY; > - goto out; > - } > + if (smp_processor_id() != 0) > + return -EBUSY; > > #if defined(CONFIG_X86_64) > asm volatile("pushq %%rax\n\t" > @@ -204,13 +198,24 @@ static int i8k_smm(struct smm_regs *regs) > if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax) > rc = -EINVAL; > > -out: > - set_cpus_allowed_ptr(current, old_mask); > - free_cpumask_var(old_mask); > return rc; > } > > /* > + * Call the System Management Mode BIOS. > + */ > +static int i8k_smm(struct smm_regs *regs) > +{ > + int ret; > + > + get_online_cpus(); > + ret = smp_call_on_cpu(0, true, i8k_smm_func, regs); > + put_online_cpus(); > + > + return ret; > +} > + > +/* > * Read the fan status. > */ > static int i8k_get_fan_status(int fan) > -- > 2.6.2 >