lkml.org 
[lkml]   [2016]   [Aug]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v6 6/6] hwmon: use smp_call_on_cpu() for dell-smm i8k
    Date
    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 <jgross@suse.com>
    ---
    V4: add call to get_online_cpus()
    ---
    drivers/hwmon/dell-smm-hwmon.c | 36 ++++++++++++++++++++----------------
    1 file changed, 20 insertions(+), 16 deletions(-)

    diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c
    index acf9c03..34704b0 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>
    @@ -36,6 +37,7 @@
    #include <linux/io.h>
    #include <linux/sched.h>
    #include <linux/ctype.h>
    +#include <linux/smp.h>

    #include <linux/i8k.h>

    @@ -134,11 +136,11 @@ 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;

    #ifdef DEBUG
    int ebx = regs->ebx;
    @@ -149,16 +151,8 @@ static int i8k_smm(struct smm_regs *regs)
    #endif

    /* SMM requires CPU 0 */
    - if (!alloc_cpumask_var(&old_mask, GFP_KERNEL))
    - return -ENOMEM;
    - cpumask_copy(old_mask, &current->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"
    @@ -216,10 +210,6 @@ 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);
    -
    #ifdef DEBUG
    rettime = ktime_get();
    delta = ktime_sub(rettime, calltime);
    @@ -232,6 +222,20 @@ out:
    }

    /*
    + * 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, i8k_smm_func, regs, true);
    + put_online_cpus();
    +
    + return ret;
    +}
    +
    +/*
    * Read the fan status.
    */
    static int i8k_get_fan_status(int fan)
    --
    2.6.6
    \
     
     \ /
      Last update: 2016-09-17 09:58    [W:4.713 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site