]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - kernel/sysctl.c
x86/spec_ctrl: Add lock to serialize changes to ibrs and ibpb control
[mirror_ubuntu-artful-kernel.git] / kernel / sysctl.c
index 69c37bd6251a625fd4475352506eb91f0ef38261..47a37792109dd7b0043cb6f24f0871da707f2a81 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/mount.h>
 
 #include <linux/uaccess.h>
+#include <linux/mutex.h>
 #include <asm/processor.h>
 
 #ifdef CONFIG_X86
@@ -2634,12 +2635,17 @@ int proc_dointvec_minmax(struct ctl_table *table, int write,
 int proc_dointvec_ibrs_dump(struct ctl_table *table, int write,
        void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       int ret;
+       int ret, orig_inuse;
        unsigned int cpu;
 
+
        ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
        printk("sysctl_ibrs_enabled = %u, sysctl_ibpb_enabled = %u\n", sysctl_ibrs_enabled, sysctl_ibpb_enabled);
        printk("use_ibrs = %d, use_ibpb = %d\n", use_ibrs, use_ibpb);
+       mutex_lock(&spec_ctrl_mutex);
+       orig_inuse = use_ibrs;
+       /* temporary halt to ibrs usage to dump ibrs values */
+       clear_ibrs_inuse();
        for_each_online_cpu(cpu) {
               u64 val;
 
@@ -2649,6 +2655,8 @@ int proc_dointvec_ibrs_dump(struct ctl_table *table, int write,
                       val = 0;
               printk("read cpu %d ibrs val %lu\n", cpu, (unsigned long) val);
        }
+       use_ibrs = orig_inuse;
+       mutex_unlock(&spec_ctrl_mutex);
        return ret;
 }
 
@@ -2661,6 +2669,7 @@ int proc_dointvec_ibrs_ctrl(struct ctl_table *table, int write,
        ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
        pr_debug("sysctl_ibrs_enabled = %u, sysctl_ibpb_enabled = %u\n", sysctl_ibrs_enabled, sysctl_ibpb_enabled);
        pr_debug("before:use_ibrs = %d, use_ibpb = %d\n", use_ibrs, use_ibpb);
+       mutex_lock(&spec_ctrl_mutex);
        if (sysctl_ibrs_enabled == 0) {
                /* always set IBRS off */
                set_ibrs_disabled();
@@ -2684,6 +2693,7 @@ int proc_dointvec_ibrs_ctrl(struct ctl_table *table, int write,
                        /* platform don't support ibrs */
                        sysctl_ibrs_enabled = 0;
        }
+       mutex_unlock(&spec_ctrl_mutex);
        pr_debug("after:use_ibrs = %d, use_ibpb = %d\n", use_ibrs, use_ibpb);
        return ret;
 }
@@ -2696,6 +2706,7 @@ int proc_dointvec_ibpb_ctrl(struct ctl_table *table, int write,
        ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
        pr_debug("sysctl_ibrs_enabled = %u, sysctl_ibpb_enabled = %u\n", sysctl_ibrs_enabled, sysctl_ibpb_enabled);
        pr_debug("before:use_ibrs = %d, use_ibpb = %d\n", use_ibrs, use_ibpb);
+       mutex_lock(&spec_ctrl_mutex);
        if (sysctl_ibpb_enabled == 0)
                set_ibpb_disabled();
        else if (sysctl_ibpb_enabled == 1) {
@@ -2704,6 +2715,7 @@ int proc_dointvec_ibpb_ctrl(struct ctl_table *table, int write,
                        /* platform don't support ibpb */
                        sysctl_ibpb_enabled = 0;
        }
+       mutex_unlock(&spec_ctrl_mutex);
        pr_debug("after:use_ibrs = %d, use_ibpb = %d\n", use_ibrs, use_ibpb);
        return ret;
 }