diff options
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r-- | kernel/sysctl.c | 166 |
1 files changed, 109 insertions, 57 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index cfc5295f1e82..ff6d45c7626f 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -121,6 +121,10 @@ extern int sg_big_buff; | |||
121 | #include <asm/system.h> | 121 | #include <asm/system.h> |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | #ifdef CONFIG_SPARC64 | ||
125 | extern int sysctl_tsb_ratio; | ||
126 | #endif | ||
127 | |||
124 | #ifdef __hppa__ | 128 | #ifdef __hppa__ |
125 | extern int pwrsw_enabled; | 129 | extern int pwrsw_enabled; |
126 | extern int unaligned_enabled; | 130 | extern int unaligned_enabled; |
@@ -149,7 +153,7 @@ extern int max_lock_depth; | |||
149 | #ifdef CONFIG_PROC_SYSCTL | 153 | #ifdef CONFIG_PROC_SYSCTL |
150 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, | 154 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, |
151 | void __user *buffer, size_t *lenp, loff_t *ppos); | 155 | void __user *buffer, size_t *lenp, loff_t *ppos); |
152 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, | 156 | static int proc_taint(struct ctl_table *table, int write, struct file *filp, |
153 | void __user *buffer, size_t *lenp, loff_t *ppos); | 157 | void __user *buffer, size_t *lenp, loff_t *ppos); |
154 | #endif | 158 | #endif |
155 | 159 | ||
@@ -176,6 +180,9 @@ extern struct ctl_table random_table[]; | |||
176 | #ifdef CONFIG_INOTIFY_USER | 180 | #ifdef CONFIG_INOTIFY_USER |
177 | extern struct ctl_table inotify_table[]; | 181 | extern struct ctl_table inotify_table[]; |
178 | #endif | 182 | #endif |
183 | #ifdef CONFIG_EPOLL | ||
184 | extern struct ctl_table epoll_table[]; | ||
185 | #endif | ||
179 | 186 | ||
180 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT | 187 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT |
181 | int sysctl_legacy_va_layout; | 188 | int sysctl_legacy_va_layout; |
@@ -276,6 +283,16 @@ static struct ctl_table kern_table[] = { | |||
276 | }, | 283 | }, |
277 | { | 284 | { |
278 | .ctl_name = CTL_UNNUMBERED, | 285 | .ctl_name = CTL_UNNUMBERED, |
286 | .procname = "sched_shares_thresh", | ||
287 | .data = &sysctl_sched_shares_thresh, | ||
288 | .maxlen = sizeof(unsigned int), | ||
289 | .mode = 0644, | ||
290 | .proc_handler = &proc_dointvec_minmax, | ||
291 | .strategy = &sysctl_intvec, | ||
292 | .extra1 = &zero, | ||
293 | }, | ||
294 | { | ||
295 | .ctl_name = CTL_UNNUMBERED, | ||
279 | .procname = "sched_child_runs_first", | 296 | .procname = "sched_child_runs_first", |
280 | .data = &sysctl_sched_child_runs_first, | 297 | .data = &sysctl_sched_child_runs_first, |
281 | .maxlen = sizeof(unsigned int), | 298 | .maxlen = sizeof(unsigned int), |
@@ -379,10 +396,9 @@ static struct ctl_table kern_table[] = { | |||
379 | #ifdef CONFIG_PROC_SYSCTL | 396 | #ifdef CONFIG_PROC_SYSCTL |
380 | { | 397 | { |
381 | .procname = "tainted", | 398 | .procname = "tainted", |
382 | .data = &tainted, | 399 | .maxlen = sizeof(long), |
383 | .maxlen = sizeof(int), | ||
384 | .mode = 0644, | 400 | .mode = 0644, |
385 | .proc_handler = &proc_dointvec_taint, | 401 | .proc_handler = &proc_taint, |
386 | }, | 402 | }, |
387 | #endif | 403 | #endif |
388 | #ifdef CONFIG_LATENCYTOP | 404 | #ifdef CONFIG_LATENCYTOP |
@@ -439,6 +455,16 @@ static struct ctl_table kern_table[] = { | |||
439 | .proc_handler = &proc_dointvec, | 455 | .proc_handler = &proc_dointvec, |
440 | }, | 456 | }, |
441 | #endif | 457 | #endif |
458 | #ifdef CONFIG_SPARC64 | ||
459 | { | ||
460 | .ctl_name = CTL_UNNUMBERED, | ||
461 | .procname = "tsb-ratio", | ||
462 | .data = &sysctl_tsb_ratio, | ||
463 | .maxlen = sizeof (int), | ||
464 | .mode = 0644, | ||
465 | .proc_handler = &proc_dointvec, | ||
466 | }, | ||
467 | #endif | ||
442 | #ifdef __hppa__ | 468 | #ifdef __hppa__ |
443 | { | 469 | { |
444 | .ctl_name = KERN_HPPA_PWRSW, | 470 | .ctl_name = KERN_HPPA_PWRSW, |
@@ -465,7 +491,7 @@ static struct ctl_table kern_table[] = { | |||
465 | .mode = 0644, | 491 | .mode = 0644, |
466 | .proc_handler = &proc_dointvec, | 492 | .proc_handler = &proc_dointvec, |
467 | }, | 493 | }, |
468 | #ifdef CONFIG_FTRACE | 494 | #ifdef CONFIG_FUNCTION_TRACER |
469 | { | 495 | { |
470 | .ctl_name = CTL_UNNUMBERED, | 496 | .ctl_name = CTL_UNNUMBERED, |
471 | .procname = "ftrace_enabled", | 497 | .procname = "ftrace_enabled", |
@@ -475,6 +501,26 @@ static struct ctl_table kern_table[] = { | |||
475 | .proc_handler = &ftrace_enable_sysctl, | 501 | .proc_handler = &ftrace_enable_sysctl, |
476 | }, | 502 | }, |
477 | #endif | 503 | #endif |
504 | #ifdef CONFIG_STACK_TRACER | ||
505 | { | ||
506 | .ctl_name = CTL_UNNUMBERED, | ||
507 | .procname = "stack_tracer_enabled", | ||
508 | .data = &stack_tracer_enabled, | ||
509 | .maxlen = sizeof(int), | ||
510 | .mode = 0644, | ||
511 | .proc_handler = &stack_trace_sysctl, | ||
512 | }, | ||
513 | #endif | ||
514 | #ifdef CONFIG_TRACING | ||
515 | { | ||
516 | .ctl_name = CTL_UNNUMBERED, | ||
517 | .procname = "ftrace_dump_on_oops", | ||
518 | .data = &ftrace_dump_on_oops, | ||
519 | .maxlen = sizeof(int), | ||
520 | .mode = 0644, | ||
521 | .proc_handler = &proc_dointvec, | ||
522 | }, | ||
523 | #endif | ||
478 | #ifdef CONFIG_MODULES | 524 | #ifdef CONFIG_MODULES |
479 | { | 525 | { |
480 | .ctl_name = KERN_MODPROBE, | 526 | .ctl_name = KERN_MODPROBE, |
@@ -834,6 +880,16 @@ static struct ctl_table kern_table[] = { | |||
834 | .proc_handler = &proc_dointvec, | 880 | .proc_handler = &proc_dointvec, |
835 | }, | 881 | }, |
836 | #endif | 882 | #endif |
883 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
884 | { | ||
885 | .ctl_name = CTL_UNNUMBERED, | ||
886 | .procname = "scan_unevictable_pages", | ||
887 | .data = &scan_unevictable_pages, | ||
888 | .maxlen = sizeof(scan_unevictable_pages), | ||
889 | .mode = 0644, | ||
890 | .proc_handler = &scan_unevictable_handler, | ||
891 | }, | ||
892 | #endif | ||
837 | /* | 893 | /* |
838 | * NOTE: do not add new entries to this table unless you have read | 894 | * NOTE: do not add new entries to this table unless you have read |
839 | * Documentation/sysctl/ctl_unnumbered.txt | 895 | * Documentation/sysctl/ctl_unnumbered.txt |
@@ -1282,6 +1338,7 @@ static struct ctl_table fs_table[] = { | |||
1282 | .extra2 = &two, | 1338 | .extra2 = &two, |
1283 | }, | 1339 | }, |
1284 | #endif | 1340 | #endif |
1341 | #ifdef CONFIG_AIO | ||
1285 | { | 1342 | { |
1286 | .procname = "aio-nr", | 1343 | .procname = "aio-nr", |
1287 | .data = &aio_nr, | 1344 | .data = &aio_nr, |
@@ -1296,6 +1353,7 @@ static struct ctl_table fs_table[] = { | |||
1296 | .mode = 0644, | 1353 | .mode = 0644, |
1297 | .proc_handler = &proc_doulongvec_minmax, | 1354 | .proc_handler = &proc_doulongvec_minmax, |
1298 | }, | 1355 | }, |
1356 | #endif /* CONFIG_AIO */ | ||
1299 | #ifdef CONFIG_INOTIFY_USER | 1357 | #ifdef CONFIG_INOTIFY_USER |
1300 | { | 1358 | { |
1301 | .ctl_name = FS_INOTIFY, | 1359 | .ctl_name = FS_INOTIFY, |
@@ -1304,6 +1362,13 @@ static struct ctl_table fs_table[] = { | |||
1304 | .child = inotify_table, | 1362 | .child = inotify_table, |
1305 | }, | 1363 | }, |
1306 | #endif | 1364 | #endif |
1365 | #ifdef CONFIG_EPOLL | ||
1366 | { | ||
1367 | .procname = "epoll", | ||
1368 | .mode = 0555, | ||
1369 | .child = epoll_table, | ||
1370 | }, | ||
1371 | #endif | ||
1307 | #endif | 1372 | #endif |
1308 | { | 1373 | { |
1309 | .ctl_name = KERN_SETUID_DUMPABLE, | 1374 | .ctl_name = KERN_SETUID_DUMPABLE, |
@@ -1501,7 +1566,6 @@ void register_sysctl_root(struct ctl_table_root *root) | |||
1501 | /* Perform the actual read/write of a sysctl table entry. */ | 1566 | /* Perform the actual read/write of a sysctl table entry. */ |
1502 | static int do_sysctl_strategy(struct ctl_table_root *root, | 1567 | static int do_sysctl_strategy(struct ctl_table_root *root, |
1503 | struct ctl_table *table, | 1568 | struct ctl_table *table, |
1504 | int __user *name, int nlen, | ||
1505 | void __user *oldval, size_t __user *oldlenp, | 1569 | void __user *oldval, size_t __user *oldlenp, |
1506 | void __user *newval, size_t newlen) | 1570 | void __user *newval, size_t newlen) |
1507 | { | 1571 | { |
@@ -1515,8 +1579,7 @@ static int do_sysctl_strategy(struct ctl_table_root *root, | |||
1515 | return -EPERM; | 1579 | return -EPERM; |
1516 | 1580 | ||
1517 | if (table->strategy) { | 1581 | if (table->strategy) { |
1518 | rc = table->strategy(table, name, nlen, oldval, oldlenp, | 1582 | rc = table->strategy(table, oldval, oldlenp, newval, newlen); |
1519 | newval, newlen); | ||
1520 | if (rc < 0) | 1583 | if (rc < 0) |
1521 | return rc; | 1584 | return rc; |
1522 | if (rc > 0) | 1585 | if (rc > 0) |
@@ -1526,8 +1589,7 @@ static int do_sysctl_strategy(struct ctl_table_root *root, | |||
1526 | /* If there is no strategy routine, or if the strategy returns | 1589 | /* If there is no strategy routine, or if the strategy returns |
1527 | * zero, proceed with automatic r/w */ | 1590 | * zero, proceed with automatic r/w */ |
1528 | if (table->data && table->maxlen) { | 1591 | if (table->data && table->maxlen) { |
1529 | rc = sysctl_data(table, name, nlen, oldval, oldlenp, | 1592 | rc = sysctl_data(table, oldval, oldlenp, newval, newlen); |
1530 | newval, newlen); | ||
1531 | if (rc < 0) | 1593 | if (rc < 0) |
1532 | return rc; | 1594 | return rc; |
1533 | } | 1595 | } |
@@ -1559,7 +1621,7 @@ repeat: | |||
1559 | table = table->child; | 1621 | table = table->child; |
1560 | goto repeat; | 1622 | goto repeat; |
1561 | } | 1623 | } |
1562 | error = do_sysctl_strategy(root, table, name, nlen, | 1624 | error = do_sysctl_strategy(root, table, |
1563 | oldval, oldlenp, | 1625 | oldval, oldlenp, |
1564 | newval, newlen); | 1626 | newval, newlen); |
1565 | return error; | 1627 | return error; |
@@ -1623,7 +1685,7 @@ out: | |||
1623 | 1685 | ||
1624 | static int test_perm(int mode, int op) | 1686 | static int test_perm(int mode, int op) |
1625 | { | 1687 | { |
1626 | if (!current->euid) | 1688 | if (!current_euid()) |
1627 | mode >>= 6; | 1689 | mode >>= 6; |
1628 | else if (in_egroup_p(0)) | 1690 | else if (in_egroup_p(0)) |
1629 | mode >>= 3; | 1691 | mode >>= 3; |
@@ -2228,49 +2290,39 @@ int proc_dointvec(struct ctl_table *table, int write, struct file *filp, | |||
2228 | NULL,NULL); | 2290 | NULL,NULL); |
2229 | } | 2291 | } |
2230 | 2292 | ||
2231 | #define OP_SET 0 | ||
2232 | #define OP_AND 1 | ||
2233 | #define OP_OR 2 | ||
2234 | |||
2235 | static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, | ||
2236 | int *valp, | ||
2237 | int write, void *data) | ||
2238 | { | ||
2239 | int op = *(int *)data; | ||
2240 | if (write) { | ||
2241 | int val = *negp ? -*lvalp : *lvalp; | ||
2242 | switch(op) { | ||
2243 | case OP_SET: *valp = val; break; | ||
2244 | case OP_AND: *valp &= val; break; | ||
2245 | case OP_OR: *valp |= val; break; | ||
2246 | } | ||
2247 | } else { | ||
2248 | int val = *valp; | ||
2249 | if (val < 0) { | ||
2250 | *negp = -1; | ||
2251 | *lvalp = (unsigned long)-val; | ||
2252 | } else { | ||
2253 | *negp = 0; | ||
2254 | *lvalp = (unsigned long)val; | ||
2255 | } | ||
2256 | } | ||
2257 | return 0; | ||
2258 | } | ||
2259 | |||
2260 | /* | 2293 | /* |
2261 | * Taint values can only be increased | 2294 | * Taint values can only be increased |
2295 | * This means we can safely use a temporary. | ||
2262 | */ | 2296 | */ |
2263 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, | 2297 | static int proc_taint(struct ctl_table *table, int write, struct file *filp, |
2264 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2298 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2265 | { | 2299 | { |
2266 | int op; | 2300 | struct ctl_table t; |
2301 | unsigned long tmptaint = get_taint(); | ||
2302 | int err; | ||
2267 | 2303 | ||
2268 | if (write && !capable(CAP_SYS_ADMIN)) | 2304 | if (write && !capable(CAP_SYS_ADMIN)) |
2269 | return -EPERM; | 2305 | return -EPERM; |
2270 | 2306 | ||
2271 | op = OP_OR; | 2307 | t = *table; |
2272 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 2308 | t.data = &tmptaint; |
2273 | do_proc_dointvec_bset_conv,&op); | 2309 | err = proc_doulongvec_minmax(&t, write, filp, buffer, lenp, ppos); |
2310 | if (err < 0) | ||
2311 | return err; | ||
2312 | |||
2313 | if (write) { | ||
2314 | /* | ||
2315 | * Poor man's atomic or. Not worth adding a primitive | ||
2316 | * to everyone's atomic.h for this | ||
2317 | */ | ||
2318 | int i; | ||
2319 | for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) { | ||
2320 | if ((tmptaint >> i) & 1) | ||
2321 | add_taint(i); | ||
2322 | } | ||
2323 | } | ||
2324 | |||
2325 | return err; | ||
2274 | } | 2326 | } |
2275 | 2327 | ||
2276 | struct do_proc_dointvec_minmax_conv_param { | 2328 | struct do_proc_dointvec_minmax_conv_param { |
@@ -2718,7 +2770,7 @@ int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, | |||
2718 | */ | 2770 | */ |
2719 | 2771 | ||
2720 | /* The generic sysctl data routine (used if no strategy routine supplied) */ | 2772 | /* The generic sysctl data routine (used if no strategy routine supplied) */ |
2721 | int sysctl_data(struct ctl_table *table, int __user *name, int nlen, | 2773 | int sysctl_data(struct ctl_table *table, |
2722 | void __user *oldval, size_t __user *oldlenp, | 2774 | void __user *oldval, size_t __user *oldlenp, |
2723 | void __user *newval, size_t newlen) | 2775 | void __user *newval, size_t newlen) |
2724 | { | 2776 | { |
@@ -2752,7 +2804,7 @@ int sysctl_data(struct ctl_table *table, int __user *name, int nlen, | |||
2752 | } | 2804 | } |
2753 | 2805 | ||
2754 | /* The generic string strategy routine: */ | 2806 | /* The generic string strategy routine: */ |
2755 | int sysctl_string(struct ctl_table *table, int __user *name, int nlen, | 2807 | int sysctl_string(struct ctl_table *table, |
2756 | void __user *oldval, size_t __user *oldlenp, | 2808 | void __user *oldval, size_t __user *oldlenp, |
2757 | void __user *newval, size_t newlen) | 2809 | void __user *newval, size_t newlen) |
2758 | { | 2810 | { |
@@ -2798,7 +2850,7 @@ int sysctl_string(struct ctl_table *table, int __user *name, int nlen, | |||
2798 | * are between the minimum and maximum values given in the arrays | 2850 | * are between the minimum and maximum values given in the arrays |
2799 | * table->extra1 and table->extra2, respectively. | 2851 | * table->extra1 and table->extra2, respectively. |
2800 | */ | 2852 | */ |
2801 | int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, | 2853 | int sysctl_intvec(struct ctl_table *table, |
2802 | void __user *oldval, size_t __user *oldlenp, | 2854 | void __user *oldval, size_t __user *oldlenp, |
2803 | void __user *newval, size_t newlen) | 2855 | void __user *newval, size_t newlen) |
2804 | { | 2856 | { |
@@ -2834,7 +2886,7 @@ int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, | |||
2834 | } | 2886 | } |
2835 | 2887 | ||
2836 | /* Strategy function to convert jiffies to seconds */ | 2888 | /* Strategy function to convert jiffies to seconds */ |
2837 | int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, | 2889 | int sysctl_jiffies(struct ctl_table *table, |
2838 | void __user *oldval, size_t __user *oldlenp, | 2890 | void __user *oldval, size_t __user *oldlenp, |
2839 | void __user *newval, size_t newlen) | 2891 | void __user *newval, size_t newlen) |
2840 | { | 2892 | { |
@@ -2868,7 +2920,7 @@ int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, | |||
2868 | } | 2920 | } |
2869 | 2921 | ||
2870 | /* Strategy function to convert jiffies to seconds */ | 2922 | /* Strategy function to convert jiffies to seconds */ |
2871 | int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, | 2923 | int sysctl_ms_jiffies(struct ctl_table *table, |
2872 | void __user *oldval, size_t __user *oldlenp, | 2924 | void __user *oldval, size_t __user *oldlenp, |
2873 | void __user *newval, size_t newlen) | 2925 | void __user *newval, size_t newlen) |
2874 | { | 2926 | { |
@@ -2923,35 +2975,35 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args) | |||
2923 | return error; | 2975 | return error; |
2924 | } | 2976 | } |
2925 | 2977 | ||
2926 | int sysctl_data(struct ctl_table *table, int __user *name, int nlen, | 2978 | int sysctl_data(struct ctl_table *table, |
2927 | void __user *oldval, size_t __user *oldlenp, | 2979 | void __user *oldval, size_t __user *oldlenp, |
2928 | void __user *newval, size_t newlen) | 2980 | void __user *newval, size_t newlen) |
2929 | { | 2981 | { |
2930 | return -ENOSYS; | 2982 | return -ENOSYS; |
2931 | } | 2983 | } |
2932 | 2984 | ||
2933 | int sysctl_string(struct ctl_table *table, int __user *name, int nlen, | 2985 | int sysctl_string(struct ctl_table *table, |
2934 | void __user *oldval, size_t __user *oldlenp, | 2986 | void __user *oldval, size_t __user *oldlenp, |
2935 | void __user *newval, size_t newlen) | 2987 | void __user *newval, size_t newlen) |
2936 | { | 2988 | { |
2937 | return -ENOSYS; | 2989 | return -ENOSYS; |
2938 | } | 2990 | } |
2939 | 2991 | ||
2940 | int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, | 2992 | int sysctl_intvec(struct ctl_table *table, |
2941 | void __user *oldval, size_t __user *oldlenp, | 2993 | void __user *oldval, size_t __user *oldlenp, |
2942 | void __user *newval, size_t newlen) | 2994 | void __user *newval, size_t newlen) |
2943 | { | 2995 | { |
2944 | return -ENOSYS; | 2996 | return -ENOSYS; |
2945 | } | 2997 | } |
2946 | 2998 | ||
2947 | int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, | 2999 | int sysctl_jiffies(struct ctl_table *table, |
2948 | void __user *oldval, size_t __user *oldlenp, | 3000 | void __user *oldval, size_t __user *oldlenp, |
2949 | void __user *newval, size_t newlen) | 3001 | void __user *newval, size_t newlen) |
2950 | { | 3002 | { |
2951 | return -ENOSYS; | 3003 | return -ENOSYS; |
2952 | } | 3004 | } |
2953 | 3005 | ||
2954 | int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, | 3006 | int sysctl_ms_jiffies(struct ctl_table *table, |
2955 | void __user *oldval, size_t __user *oldlenp, | 3007 | void __user *oldval, size_t __user *oldlenp, |
2956 | void __user *newval, size_t newlen) | 3008 | void __user *newval, size_t newlen) |
2957 | { | 3009 | { |