]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/sysctl.c
Merge tag 'hwmon-for-linus-v4.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / kernel / sysctl.c
index d12078fc215fef4a90a1e75586c53cd108b83cb7..6648fbbb8157fc12703d02fa0fdc9ff85c527ac4 100644 (file)
@@ -900,6 +900,14 @@ static struct ctl_table kern_table[] = {
                .extra2         = &zero,
 #endif
        },
+       {
+               .procname       = "watchdog_cpumask",
+               .data           = &watchdog_cpumask_bits,
+               .maxlen         = NR_CPUS,
+               .mode           = 0644,
+               .proc_handler   = proc_watchdog_cpumask,
+       },
+#ifdef CONFIG_SOFTLOCKUP_DETECTOR
        {
                .procname       = "soft_watchdog",
                .data           = &soft_watchdog_enabled,
@@ -909,13 +917,6 @@ static struct ctl_table kern_table[] = {
                .extra1         = &zero,
                .extra2         = &one,
        },
-       {
-               .procname       = "watchdog_cpumask",
-               .data           = &watchdog_cpumask_bits,
-               .maxlen         = NR_CPUS,
-               .mode           = 0644,
-               .proc_handler   = proc_watchdog_cpumask,
-       },
        {
                .procname       = "softlockup_panic",
                .data           = &softlockup_panic,
@@ -925,27 +926,29 @@ static struct ctl_table kern_table[] = {
                .extra1         = &zero,
                .extra2         = &one,
        },
-#ifdef CONFIG_HARDLOCKUP_DETECTOR
+#ifdef CONFIG_SMP
        {
-               .procname       = "hardlockup_panic",
-               .data           = &hardlockup_panic,
+               .procname       = "softlockup_all_cpu_backtrace",
+               .data           = &sysctl_softlockup_all_cpu_backtrace,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = proc_dointvec_minmax,
                .extra1         = &zero,
                .extra2         = &one,
        },
+#endif /* CONFIG_SMP */
 #endif
-#ifdef CONFIG_SMP
+#ifdef CONFIG_HARDLOCKUP_DETECTOR
        {
-               .procname       = "softlockup_all_cpu_backtrace",
-               .data           = &sysctl_softlockup_all_cpu_backtrace,
+               .procname       = "hardlockup_panic",
+               .data           = &hardlockup_panic,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = proc_dointvec_minmax,
                .extra1         = &zero,
                .extra2         = &one,
        },
+#ifdef CONFIG_SMP
        {
                .procname       = "hardlockup_all_cpu_backtrace",
                .data           = &sysctl_hardlockup_all_cpu_backtrace,
@@ -957,6 +960,8 @@ static struct ctl_table kern_table[] = {
        },
 #endif /* CONFIG_SMP */
 #endif
+#endif
+
 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
        {
                .procname       = "unknown_nmi_panic",
@@ -2567,6 +2572,65 @@ int proc_dointvec_minmax(struct ctl_table *table, int write,
                                do_proc_dointvec_minmax_conv, &param);
 }
 
+struct do_proc_douintvec_minmax_conv_param {
+       unsigned int *min;
+       unsigned int *max;
+};
+
+static int do_proc_douintvec_minmax_conv(unsigned long *lvalp,
+                                        unsigned int *valp,
+                                        int write, void *data)
+{
+       struct do_proc_douintvec_minmax_conv_param *param = data;
+
+       if (write) {
+               unsigned int val = *lvalp;
+
+               if ((param->min && *param->min > val) ||
+                   (param->max && *param->max < val))
+                       return -ERANGE;
+
+               if (*lvalp > UINT_MAX)
+                       return -EINVAL;
+               *valp = val;
+       } else {
+               unsigned int val = *valp;
+               *lvalp = (unsigned long) val;
+       }
+
+       return 0;
+}
+
+/**
+ * proc_douintvec_minmax - read a vector of unsigned ints with min/max values
+ * @table: the sysctl table
+ * @write: %TRUE if this is a write to the sysctl file
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
+ * values from/to the user buffer, treated as an ASCII string. Negative
+ * strings are not allowed.
+ *
+ * This routine will ensure the values are within the range specified by
+ * table->extra1 (min) and table->extra2 (max). There is a final sanity
+ * check for UINT_MAX to avoid having to support wrap around uses from
+ * userspace.
+ *
+ * Returns 0 on success.
+ */
+int proc_douintvec_minmax(struct ctl_table *table, int write,
+                         void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       struct do_proc_douintvec_minmax_conv_param param = {
+               .min = (unsigned int *) table->extra1,
+               .max = (unsigned int *) table->extra2,
+       };
+       return do_proc_douintvec(table, write, buffer, lenp, ppos,
+                                do_proc_douintvec_minmax_conv, &param);
+}
+
 static void validate_coredump_safety(void)
 {
 #ifdef CONFIG_COREDUMP
@@ -3066,6 +3130,12 @@ int proc_dointvec_minmax(struct ctl_table *table, int write,
        return -ENOSYS;
 }
 
+int proc_douintvec_minmax(struct ctl_table *table, int write,
+                         void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       return -ENOSYS;
+}
+
 int proc_dointvec_jiffies(struct ctl_table *table, int write,
                    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -3108,6 +3178,7 @@ EXPORT_SYMBOL(proc_dointvec);
 EXPORT_SYMBOL(proc_douintvec);
 EXPORT_SYMBOL(proc_dointvec_jiffies);
 EXPORT_SYMBOL(proc_dointvec_minmax);
+EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
 EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
 EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
 EXPORT_SYMBOL(proc_dostring);