diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-03 14:02:39 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-03 14:02:39 -0400 |
| commit | d7a0dab82fef61bebd34f2bbb9314b075153b646 (patch) | |
| tree | 1ec0a1d31ed8231bcce7f20c6b289e57a8969ca9 /drivers | |
| parent | 4b978934a440c1aafce986353001b03289eaa040 (diff) | |
| parent | 8db549491c4a3ce9e1d509b75f78516e497f48ec (diff) | |
Merge branch 'core-smp-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull core SMP updates from Ingo Molnar:
"Two main change is generic vCPU pinning and physical CPU SMP-call
support, for Xen to be able to perform certain calls on specific
physical CPUs - by Juergen Gross"
* 'core-smp-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
smp: Allocate smp_call_on_cpu() workqueue on stack too
hwmon: Use smp_call_on_cpu() for dell-smm i8k
dcdbas: Make use of smp_call_on_cpu()
xen: Add xen_pin_vcpu() to support calling functions on a dedicated pCPU
smp: Add function to execute a function synchronously on a CPU
virt, sched: Add generic vCPU pinning support
xen: Sync xen header
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/firmware/dcdbas.c | 51 | ||||
| -rw-r--r-- | drivers/hwmon/dell-smm-hwmon.c | 36 |
2 files changed, 46 insertions, 41 deletions
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index 829eec8959f2..2fe1a130189f 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/dma-mapping.h> | 24 | #include <linux/dma-mapping.h> |
| 25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
| 26 | #include <linux/cpu.h> | ||
| 26 | #include <linux/gfp.h> | 27 | #include <linux/gfp.h> |
| 27 | #include <linux/init.h> | 28 | #include <linux/init.h> |
| 28 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
| @@ -238,33 +239,14 @@ static ssize_t host_control_on_shutdown_store(struct device *dev, | |||
| 238 | return count; | 239 | return count; |
| 239 | } | 240 | } |
| 240 | 241 | ||
| 241 | /** | 242 | static int raise_smi(void *par) |
| 242 | * dcdbas_smi_request: generate SMI request | ||
| 243 | * | ||
| 244 | * Called with smi_data_lock. | ||
| 245 | */ | ||
| 246 | int dcdbas_smi_request(struct smi_cmd *smi_cmd) | ||
| 247 | { | 243 | { |
| 248 | cpumask_var_t old_mask; | 244 | struct smi_cmd *smi_cmd = par; |
| 249 | int ret = 0; | ||
| 250 | |||
| 251 | if (smi_cmd->magic != SMI_CMD_MAGIC) { | ||
| 252 | dev_info(&dcdbas_pdev->dev, "%s: invalid magic value\n", | ||
| 253 | __func__); | ||
| 254 | return -EBADR; | ||
| 255 | } | ||
| 256 | 245 | ||
| 257 | /* SMI requires CPU 0 */ | ||
| 258 | if (!alloc_cpumask_var(&old_mask, GFP_KERNEL)) | ||
| 259 | return -ENOMEM; | ||
| 260 | |||
| 261 | cpumask_copy(old_mask, ¤t->cpus_allowed); | ||
| 262 | set_cpus_allowed_ptr(current, cpumask_of(0)); | ||
| 263 | if (smp_processor_id() != 0) { | 246 | if (smp_processor_id() != 0) { |
| 264 | dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n", | 247 | dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n", |
| 265 | __func__); | 248 | __func__); |
| 266 | ret = -EBUSY; | 249 | return -EBUSY; |
| 267 | goto out; | ||
| 268 | } | 250 | } |
| 269 | 251 | ||
| 270 | /* generate SMI */ | 252 | /* generate SMI */ |
| @@ -280,9 +262,28 @@ int dcdbas_smi_request(struct smi_cmd *smi_cmd) | |||
| 280 | : "memory" | 262 | : "memory" |
| 281 | ); | 263 | ); |
| 282 | 264 | ||
| 283 | out: | 265 | return 0; |
| 284 | set_cpus_allowed_ptr(current, old_mask); | 266 | } |
| 285 | free_cpumask_var(old_mask); | 267 | /** |
| 268 | * dcdbas_smi_request: generate SMI request | ||
| 269 | * | ||
| 270 | * Called with smi_data_lock. | ||
| 271 | */ | ||
| 272 | int dcdbas_smi_request(struct smi_cmd *smi_cmd) | ||
| 273 | { | ||
| 274 | int ret; | ||
| 275 | |||
| 276 | if (smi_cmd->magic != SMI_CMD_MAGIC) { | ||
| 277 | dev_info(&dcdbas_pdev->dev, "%s: invalid magic value\n", | ||
| 278 | __func__); | ||
| 279 | return -EBADR; | ||
| 280 | } | ||
| 281 | |||
| 282 | /* SMI requires CPU 0 */ | ||
| 283 | get_online_cpus(); | ||
| 284 | ret = smp_call_on_cpu(0, raise_smi, smi_cmd, true); | ||
| 285 | put_online_cpus(); | ||
| 286 | |||
| 286 | return ret; | 287 | return ret; |
| 287 | } | 288 | } |
| 288 | 289 | ||
diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c index acf9c0361d9f..34704b0451b4 100644 --- a/drivers/hwmon/dell-smm-hwmon.c +++ b/drivers/hwmon/dell-smm-hwmon.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 23 | 23 | ||
| 24 | #include <linux/cpu.h> | ||
| 24 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
| 25 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 26 | #include <linux/types.h> | 27 | #include <linux/types.h> |
| @@ -36,6 +37,7 @@ | |||
| 36 | #include <linux/io.h> | 37 | #include <linux/io.h> |
| 37 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
| 38 | #include <linux/ctype.h> | 39 | #include <linux/ctype.h> |
| 40 | #include <linux/smp.h> | ||
| 39 | 41 | ||
| 40 | #include <linux/i8k.h> | 42 | #include <linux/i8k.h> |
| 41 | 43 | ||
| @@ -134,11 +136,11 @@ static inline const char *i8k_get_dmi_data(int field) | |||
| 134 | /* | 136 | /* |
| 135 | * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard. | 137 | * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard. |
| 136 | */ | 138 | */ |
| 137 | static int i8k_smm(struct smm_regs *regs) | 139 | static int i8k_smm_func(void *par) |
| 138 | { | 140 | { |
| 139 | int rc; | 141 | int rc; |
| 142 | struct smm_regs *regs = par; | ||
| 140 | int eax = regs->eax; | 143 | int eax = regs->eax; |
| 141 | cpumask_var_t old_mask; | ||
| 142 | 144 | ||
| 143 | #ifdef DEBUG | 145 | #ifdef DEBUG |
| 144 | int ebx = regs->ebx; | 146 | int ebx = regs->ebx; |
| @@ -149,16 +151,8 @@ static int i8k_smm(struct smm_regs *regs) | |||
| 149 | #endif | 151 | #endif |
| 150 | 152 | ||
| 151 | /* SMM requires CPU 0 */ | 153 | /* SMM requires CPU 0 */ |
| 152 | if (!alloc_cpumask_var(&old_mask, GFP_KERNEL)) | 154 | if (smp_processor_id() != 0) |
| 153 | return -ENOMEM; | 155 | return -EBUSY; |
| 154 | cpumask_copy(old_mask, ¤t->cpus_allowed); | ||
| 155 | rc = set_cpus_allowed_ptr(current, cpumask_of(0)); | ||
| 156 | if (rc) | ||
| 157 | goto out; | ||
| 158 | if (smp_processor_id() != 0) { | ||
| 159 | rc = -EBUSY; | ||
| 160 | goto out; | ||
| 161 | } | ||
| 162 | 156 | ||
| 163 | #if defined(CONFIG_X86_64) | 157 | #if defined(CONFIG_X86_64) |
| 164 | asm volatile("pushq %%rax\n\t" | 158 | asm volatile("pushq %%rax\n\t" |
| @@ -216,10 +210,6 @@ static int i8k_smm(struct smm_regs *regs) | |||
| 216 | if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax) | 210 | if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax) |
| 217 | rc = -EINVAL; | 211 | rc = -EINVAL; |
| 218 | 212 | ||
| 219 | out: | ||
| 220 | set_cpus_allowed_ptr(current, old_mask); | ||
| 221 | free_cpumask_var(old_mask); | ||
| 222 | |||
| 223 | #ifdef DEBUG | 213 | #ifdef DEBUG |
| 224 | rettime = ktime_get(); | 214 | rettime = ktime_get(); |
| 225 | delta = ktime_sub(rettime, calltime); | 215 | delta = ktime_sub(rettime, calltime); |
| @@ -232,6 +222,20 @@ out: | |||
| 232 | } | 222 | } |
| 233 | 223 | ||
| 234 | /* | 224 | /* |
| 225 | * Call the System Management Mode BIOS. | ||
| 226 | */ | ||
| 227 | static int i8k_smm(struct smm_regs *regs) | ||
| 228 | { | ||
| 229 | int ret; | ||
| 230 | |||
| 231 | get_online_cpus(); | ||
| 232 | ret = smp_call_on_cpu(0, i8k_smm_func, regs, true); | ||
| 233 | put_online_cpus(); | ||
| 234 | |||
| 235 | return ret; | ||
| 236 | } | ||
| 237 | |||
| 238 | /* | ||
| 235 | * Read the fan status. | 239 | * Read the fan status. |
| 236 | */ | 240 | */ |
| 237 | static int i8k_get_fan_status(int fan) | 241 | static int i8k_get_fan_status(int fan) |
