On Tue, 28 Mar 2017, kan.li...@intel.com wrote: > +static void flip_smm_bit(void *data) > +{ > + int val = *(int *)data; > + > + msr_flip_bit(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_FREEZE_WHILE_SMM_BIT, > (bool)val);
I asked you before to use line breaks for lines over 80 chars. Is it that hard? > +static DEFINE_MUTEX(freeze_on_smi_mutex); > + > + static ssize_t freeze_on_smi_store(struct device *cdev, > + struct device_attribute *attr, > + const char *buf, size_t count) > +{ > + unsigned long val; > + ssize_t ret; > + > + ret = kstrtoul(buf, 0, &val); > + if (ret) > + return ret; > + > + if (val > 1) > + return -EINVAL; > + > + if (x86_pmu.attr_freeze_on_smi == val) > + return count; > + > + mutex_lock(&freeze_on_smi_mutex); This wants to protect the check above as well. > + > + get_online_cpus(); > + > + flip_smm_bit(&val); Sigh. This still is racy against preemption and interrupts. > + smp_call_function(flip_smm_bit, &val, 1); Yes, I had smp_call_function() in my example, but I'd expected that you figure out yourself to use on_each_cpu(), which calls the function on the calling cpu with interrupts disabled. > + put_online_cpus(); > + > + x86_pmu.attr_freeze_on_smi = val; Crap. So a CPU coming online between put_online_cpus() and the store will not see it. Sigh, tglx