Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / kernel / sysctl.c
index cbbc4f6..f49a10f 100644 (file)
@@ -23,7 +23,9 @@
 #include <linux/swap.h>
 #include <linux/slab.h>
 #include <linux/sysctl.h>
+#include <linux/bitmap.h>
 #include <linux/signal.h>
+#include <linux/printk.h>
 #include <linux/proc_fs.h>
 #include <linux/security.h>
 #include <linux/ctype.h>
@@ -55,6 +57,9 @@
 #include <linux/kprobes.h>
 #include <linux/pipe_fs_i.h>
 #include <linux/oom.h>
+#include <linux/kmod.h>
+#include <linux/capability.h>
+#include <linux/binfmts.h>
 
 #include <asm/uaccess.h>
 #include <asm/processor.h>
@@ -64,6 +69,9 @@
 #include <asm/stacktrace.h>
 #include <asm/io.h>
 #endif
+#ifdef CONFIG_SPARC
+#include <asm/setup.h>
+#endif
 #ifdef CONFIG_BSD_PROCESS_ACCT
 #include <linux/acct.h>
 #endif
@@ -116,6 +124,7 @@ static int neg_one = -1;
 static int zero;
 static int __maybe_unused one = 1;
 static int __maybe_unused two = 2;
+static int __maybe_unused three = 3;
 static unsigned long one_ul = 1;
 static int one_hundred = 100;
 #ifdef CONFIG_PRINTK
@@ -131,12 +140,12 @@ static int minolduid;
 static int min_percpu_pagelist_fract = 8;
 
 static int ngroups_max = NGROUPS_MAX;
+static const int cap_last_cap = CAP_LAST_CAP;
 
 #ifdef CONFIG_INOTIFY_USER
 #include <linux/inotify.h>
 #endif
 #ifdef CONFIG_SPARC
-#include <asm/system.h>
 #endif
 
 #ifdef CONFIG_SPARC64
@@ -148,21 +157,11 @@ extern int pwrsw_enabled;
 extern int unaligned_enabled;
 #endif
 
-#ifdef CONFIG_S390
-#ifdef CONFIG_MATHEMU
-extern int sysctl_ieee_emulation_warnings;
-#endif
-extern int sysctl_userprocess_debug;
-extern int spin_retry;
-#endif
-
 #ifdef CONFIG_IA64
 extern int no_unaligned_warning;
 extern int unaligned_dump_stack;
 #endif
 
-extern struct ratelimit_state printk_ratelimit_state;
-
 #ifdef CONFIG_PROC_SYSCTL
 static int proc_do_cad_pid(struct ctl_table *table, int write,
                  void __user *buffer, size_t *lenp, loff_t *ppos);
@@ -170,8 +169,14 @@ static int proc_taint(struct ctl_table *table, int write,
                               void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
 
+#ifdef CONFIG_PRINTK
+static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
+                               void __user *buffer, size_t *lenp, loff_t *ppos);
+#endif
+
 #ifdef CONFIG_MAGIC_SYSRQ
-static int __sysrq_enabled; /* Note: sysrq code ises it's own private copy */
+/* Note: sysrq code uses it's own private copy */
+static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
 
 static int sysrq_sysctl_handler(ctl_table *table, int write,
                                void __user *buffer, size_t *lenp,
@@ -191,20 +196,6 @@ static int sysrq_sysctl_handler(ctl_table *table, int write,
 
 #endif
 
-static struct ctl_table root_table[];
-static struct ctl_table_root sysctl_table_root;
-static struct ctl_table_header root_table_header = {
-       .count = 1,
-       .ctl_table = root_table,
-       .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),
-       .root = &sysctl_table_root,
-       .set = &sysctl_table_root.default_set,
-};
-static struct ctl_table_root sysctl_table_root = {
-       .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
-       .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry),
-};
-
 static struct ctl_table kern_table[];
 static struct ctl_table vm_table[];
 static struct ctl_table fs_table[];
@@ -221,7 +212,7 @@ int sysctl_legacy_va_layout;
 
 /* The default sysctl tables: */
 
-static struct ctl_table root_table[] = {
+static struct ctl_table sysctl_base_table[] = {
        {
                .procname       = "kernel",
                .mode           = 0555,
@@ -247,10 +238,6 @@ static struct ctl_table root_table[] = {
                .mode           = 0555,
                .child          = dev_table,
        },
-/*
- * NOTE: do not add new entries to this table unless you have read
- * Documentation/sysctl/ctl_unnumbered.txt
- */
        { }
 };
 
@@ -261,8 +248,6 @@ static int min_wakeup_granularity_ns;                       /* 0 usecs */
 static int max_wakeup_granularity_ns = NSEC_PER_SEC;   /* 1 second */
 static int min_sched_tunable_scaling = SCHED_TUNABLESCALING_NONE;
 static int max_sched_tunable_scaling = SCHED_TUNABLESCALING_END-1;
-static int min_sched_shares_ratelimit = 100000; /* 100 usec */
-static int max_sched_shares_ratelimit = NSEC_PER_SEC; /* 1 second */
 #endif
 
 #ifdef CONFIG_COMPACTION
@@ -307,15 +292,6 @@ static struct ctl_table kern_table[] = {
                .extra2         = &max_wakeup_granularity_ns,
        },
        {
-               .procname       = "sched_shares_ratelimit",
-               .data           = &sysctl_sched_shares_ratelimit,
-               .maxlen         = sizeof(unsigned int),
-               .mode           = 0644,
-               .proc_handler   = sched_proc_update_handler,
-               .extra1         = &min_sched_shares_ratelimit,
-               .extra2         = &max_sched_shares_ratelimit,
-       },
-       {
                .procname       = "sched_tunable_scaling",
                .data           = &sysctl_sched_tunable_scaling,
                .maxlen         = sizeof(enum sched_tunable_scaling),
@@ -325,14 +301,6 @@ static struct ctl_table kern_table[] = {
                .extra2         = &max_sched_tunable_scaling,
        },
        {
-               .procname       = "sched_shares_thresh",
-               .data           = &sysctl_sched_shares_thresh,
-               .maxlen         = sizeof(unsigned int),
-               .mode           = 0644,
-               .proc_handler   = proc_dointvec_minmax,
-               .extra1         = &zero,
-       },
-       {
                .procname       = "sched_migration_cost",
                .data           = &sysctl_sched_migration_cost,
                .maxlen         = sizeof(unsigned int),
@@ -354,6 +322,13 @@ static struct ctl_table kern_table[] = {
                .proc_handler   = proc_dointvec,
        },
        {
+               .procname       = "sched_shares_window",
+               .data           = &sysctl_sched_shares_window,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
+       {
                .procname       = "timer_migration",
                .data           = &sysctl_timer_migration,
                .maxlen         = sizeof(unsigned int),
@@ -377,13 +352,27 @@ static struct ctl_table kern_table[] = {
                .mode           = 0644,
                .proc_handler   = sched_rt_handler,
        },
+#ifdef CONFIG_SCHED_AUTOGROUP
        {
-               .procname       = "sched_compat_yield",
-               .data           = &sysctl_sched_compat_yield,
+               .procname       = "sched_autogroup_enabled",
+               .data           = &sysctl_sched_autogroup_enabled,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &one,
+       },
+#endif
+#ifdef CONFIG_CFS_BANDWIDTH
+       {
+               .procname       = "sched_cfs_bandwidth_slice_us",
+               .data           = &sysctl_sched_cfs_bandwidth_slice,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &one,
        },
+#endif
 #ifdef CONFIG_PROVE_LOCKING
        {
                .procname       = "prove_locking",
@@ -622,6 +611,11 @@ static struct ctl_table kern_table[] = {
                .child          = random_table,
        },
        {
+               .procname       = "usermodehelper",
+               .mode           = 0555,
+               .child          = usermodehelper_table,
+       },
+       {
                .procname       = "overflowuid",
                .data           = &overflowuid,
                .maxlen         = sizeof(int),
@@ -713,6 +707,24 @@ static struct ctl_table kern_table[] = {
                .extra1         = &zero,
                .extra2         = &ten_thousand,
        },
+       {
+               .procname       = "dmesg_restrict",
+               .data           = &dmesg_restrict,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_minmax_sysadmin,
+               .extra1         = &zero,
+               .extra2         = &one,
+       },
+       {
+               .procname       = "kptr_restrict",
+               .data           = &kptr_restrict,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_minmax_sysadmin,
+               .extra1         = &zero,
+               .extra2         = &two,
+       },
 #endif
        {
                .procname       = "ngroups_max",
@@ -721,20 +733,29 @@ static struct ctl_table kern_table[] = {
                .mode           = 0444,
                .proc_handler   = proc_dointvec,
        },
+       {
+               .procname       = "cap_last_cap",
+               .data           = (void *)&cap_last_cap,
+               .maxlen         = sizeof(int),
+               .mode           = 0444,
+               .proc_handler   = proc_dointvec,
+       },
 #if defined(CONFIG_LOCKUP_DETECTOR)
        {
                .procname       = "watchdog",
                .data           = &watchdog_enabled,
                .maxlen         = sizeof (int),
                .mode           = 0644,
-               .proc_handler   = proc_dowatchdog_enabled,
+               .proc_handler   = proc_dowatchdog,
+               .extra1         = &zero,
+               .extra2         = &one,
        },
        {
                .procname       = "watchdog_thresh",
-               .data           = &softlockup_thresh,
+               .data           = &watchdog_thresh,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_dowatchdog_thresh,
+               .proc_handler   = proc_dowatchdog,
                .extra1         = &neg_one,
                .extra2         = &sixty,
        },
@@ -747,25 +768,25 @@ static struct ctl_table kern_table[] = {
                .extra1         = &zero,
                .extra2         = &one,
        },
-#endif
-#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) && !defined(CONFIG_LOCKUP_DETECTOR)
        {
-               .procname       = "unknown_nmi_panic",
-               .data           = &unknown_nmi_panic,
+               .procname       = "nmi_watchdog",
+               .data           = &watchdog_enabled,
                .maxlen         = sizeof (int),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_dowatchdog,
+               .extra1         = &zero,
+               .extra2         = &one,
        },
-#ifdef ARCH_HAS_NMI_WATCHDOG
+#endif
+#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
        {
-               .procname       = "nmi_watchdog",
-               .data           = &nmi_watchdog_enabled,
+               .procname       = "unknown_nmi_panic",
+               .data           = &unknown_nmi_panic,
                .maxlen         = sizeof (int),
                .mode           = 0644,
-               .proc_handler   = proc_nmi_enabled,
+               .proc_handler   = proc_dointvec,
        },
 #endif
-#endif
 #if defined(CONFIG_X86)
        {
                .procname       = "panic_on_unrecovered_nmi",
@@ -781,6 +802,15 @@ static struct ctl_table kern_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+       {
+               .procname       = "panic_on_stackoverflow",
+               .data           = &sysctl_panic_on_stackoverflow,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
+#endif
        {
                .procname       = "bootloader_type",
                .data           = &bootloader_type,
@@ -934,6 +964,12 @@ static struct ctl_table kern_table[] = {
        },
 #endif
 #ifdef CONFIG_PERF_EVENTS
+       /*
+        * User-space scripts rely on the existence of this file
+        * as a feature check for perf_events being enabled.
+        *
+        * So it's an ABI, do not remove!
+        */
        {
                .procname       = "perf_event_paranoid",
                .data           = &sysctl_perf_event_paranoid,
@@ -953,7 +989,7 @@ static struct ctl_table kern_table[] = {
                .data           = &sysctl_perf_event_sample_rate,
                .maxlen         = sizeof(sysctl_perf_event_sample_rate),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = perf_proc_update_handler,
        },
 #endif
 #ifdef CONFIG_KMEMCHECK
@@ -974,10 +1010,6 @@ static struct ctl_table kern_table[] = {
                .proc_handler   = proc_dointvec,
        },
 #endif
-/*
- * NOTE: do not add new entries to this table unless you have read
- * Documentation/sysctl/ctl_unnumbered.txt
- */
        { }
 };
 
@@ -987,14 +1019,18 @@ static struct ctl_table vm_table[] = {
                .data           = &sysctl_overcommit_memory,
                .maxlen         = sizeof(sysctl_overcommit_memory),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &two,
        },
        {
                .procname       = "panic_on_oom",
                .data           = &sysctl_panic_on_oom,
                .maxlen         = sizeof(sysctl_panic_on_oom),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &two,
        },
        {
                .procname       = "oom_kill_allocating_task",
@@ -1022,7 +1058,8 @@ static struct ctl_table vm_table[] = {
                .data           = &page_cluster,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
        },
        {
                .procname       = "dirty_background_ratio",
@@ -1070,7 +1107,8 @@ static struct ctl_table vm_table[] = {
                .data           = &dirty_expire_interval,
                .maxlen         = sizeof(dirty_expire_interval),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
        },
        {
                .procname       = "nr_pdflush_threads",
@@ -1146,6 +1184,8 @@ static struct ctl_table vm_table[] = {
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = drop_caches_sysctl_handler,
+               .extra1         = &one,
+               .extra2         = &three,
        },
 #ifdef CONFIG_COMPACTION
        {
@@ -1318,17 +1358,6 @@ static struct ctl_table vm_table[] = {
                .mode           = 0644,
                .proc_handler   = scan_unevictable_handler,
        },
-#ifdef CONFIG_PRESWAP
-       {
-               .procname       = "preswap",
-               .data           = NULL,
-               .maxlen         = sizeof(unsigned long),
-               .mode           = 0644,
-               .proc_handler   = preswap_sysctl_handler,
-               .extra1         = (void *)&preswap_zero,
-               .extra2         = (void *)&preswap_infinity,
-       },
-#endif
 #ifdef CONFIG_MEMORY_FAILURE
        {
                .procname       = "memory_failure_early_kill",
@@ -1349,11 +1378,6 @@ static struct ctl_table vm_table[] = {
                .extra2         = &one,
        },
 #endif
-
-/*
- * NOTE: do not add new entries to this table unless you have read
- * Documentation/sysctl/ctl_unnumbered.txt
- */
        { }
 };
 
@@ -1369,28 +1393,28 @@ static struct ctl_table fs_table[] = {
                .data           = &inodes_stat,
                .maxlen         = 2*sizeof(int),
                .mode           = 0444,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_nr_inodes,
        },
        {
                .procname       = "inode-state",
                .data           = &inodes_stat,
                .maxlen         = 7*sizeof(int),
                .mode           = 0444,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_nr_inodes,
        },
        {
                .procname       = "file-nr",
                .data           = &files_stat,
-               .maxlen         = 3*sizeof(int),
+               .maxlen         = sizeof(files_stat),
                .mode           = 0444,
                .proc_handler   = proc_nr_files,
        },
        {
                .procname       = "file-max",
                .data           = &files_stat.max_files,
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(files_stat.max_files),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_doulongvec_minmax,
        },
        {
                .procname       = "nr_open",
@@ -1406,7 +1430,7 @@ static struct ctl_table fs_table[] = {
                .data           = &dentry_stat,
                .maxlen         = 6*sizeof(int),
                .mode           = 0444,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_nr_dentry,
        },
        {
                .procname       = "overflowuid",
@@ -1509,16 +1533,12 @@ static struct ctl_table fs_table[] = {
                .proc_handler   = &pipe_proc_fn,
                .extra1         = &pipe_min_size,
        },
-/*
- * NOTE: do not add new entries to this table unless you have read
- * Documentation/sysctl/ctl_unnumbered.txt
- */
        { }
 };
 
 static struct ctl_table debug_table[] = {
 #if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \
-    defined(CONFIG_S390)
+    defined(CONFIG_S390) || defined(CONFIG_TILE)
        {
                .procname       = "exception-trace",
                .data           = &show_unhandled_signals,
@@ -1545,498 +1565,12 @@ static struct ctl_table dev_table[] = {
        { }
 };
 
-static DEFINE_SPINLOCK(sysctl_lock);
-
-/* called under sysctl_lock */
-static int use_table(struct ctl_table_header *p)
-{
-       if (unlikely(p->unregistering))
-               return 0;
-       p->used++;
-       return 1;
-}
-
-/* called under sysctl_lock */
-static void unuse_table(struct ctl_table_header *p)
-{
-       if (!--p->used)
-               if (unlikely(p->unregistering))
-                       complete(p->unregistering);
-}
-
-/* called under sysctl_lock, will reacquire if has to wait */
-static void start_unregistering(struct ctl_table_header *p)
-{
-       /*
-        * if p->used is 0, nobody will ever touch that entry again;
-        * we'll eliminate all paths to it before dropping sysctl_lock
-        */
-       if (unlikely(p->used)) {
-               struct completion wait;
-               init_completion(&wait);
-               p->unregistering = &wait;
-               spin_unlock(&sysctl_lock);
-               wait_for_completion(&wait);
-               spin_lock(&sysctl_lock);
-       } else {
-               /* anything non-NULL; we'll never dereference it */
-               p->unregistering = ERR_PTR(-EINVAL);
-       }
-       /*
-        * do not remove from the list until nobody holds it; walking the
-        * list in do_sysctl() relies on that.
-        */
-       list_del_init(&p->ctl_entry);
-}
-
-void sysctl_head_get(struct ctl_table_header *head)
-{
-       spin_lock(&sysctl_lock);
-       head->count++;
-       spin_unlock(&sysctl_lock);
-}
-
-void sysctl_head_put(struct ctl_table_header *head)
-{
-       spin_lock(&sysctl_lock);
-       if (!--head->count)
-               kfree(head);
-       spin_unlock(&sysctl_lock);
-}
-
-struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
+int __init sysctl_init(void)
 {
-       if (!head)
-               BUG();
-       spin_lock(&sysctl_lock);
-       if (!use_table(head))
-               head = ERR_PTR(-ENOENT);
-       spin_unlock(&sysctl_lock);
-       return head;
-}
-
-void sysctl_head_finish(struct ctl_table_header *head)
-{
-       if (!head)
-               return;
-       spin_lock(&sysctl_lock);
-       unuse_table(head);
-       spin_unlock(&sysctl_lock);
-}
-
-static struct ctl_table_set *
-lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces)
-{
-       struct ctl_table_set *set = &root->default_set;
-       if (root->lookup)
-               set = root->lookup(root, namespaces);
-       return set;
-}
-
-static struct list_head *
-lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
-{
-       struct ctl_table_set *set = lookup_header_set(root, namespaces);
-       return &set->list;
-}
-
-struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
-                                           struct ctl_table_header *prev)
-{
-       struct ctl_table_root *root;
-       struct list_head *header_list;
-       struct ctl_table_header *head;
-       struct list_head *tmp;
-
-       spin_lock(&sysctl_lock);
-       if (prev) {
-               head = prev;
-               tmp = &prev->ctl_entry;
-               unuse_table(prev);
-               goto next;
-       }
-       tmp = &root_table_header.ctl_entry;
-       for (;;) {
-               head = list_entry(tmp, struct ctl_table_header, ctl_entry);
-
-               if (!use_table(head))
-                       goto next;
-               spin_unlock(&sysctl_lock);
-               return head;
-       next:
-               root = head->root;
-               tmp = tmp->next;
-               header_list = lookup_header_list(root, namespaces);
-               if (tmp != header_list)
-                       continue;
-
-               do {
-                       root = list_entry(root->root_list.next,
-                                       struct ctl_table_root, root_list);
-                       if (root == &sysctl_table_root)
-                               goto out;
-                       header_list = lookup_header_list(root, namespaces);
-               } while (list_empty(header_list));
-               tmp = header_list->next;
-       }
-out:
-       spin_unlock(&sysctl_lock);
-       return NULL;
-}
-
-struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
-{
-       return __sysctl_head_next(current->nsproxy, prev);
-}
-
-void register_sysctl_root(struct ctl_table_root *root)
-{
-       spin_lock(&sysctl_lock);
-       list_add_tail(&root->root_list, &sysctl_table_root.root_list);
-       spin_unlock(&sysctl_lock);
-}
-
-/*
- * sysctl_perm does NOT grant the superuser all rights automatically, because
- * some sysctl variables are readonly even to root.
- */
-
-static int test_perm(int mode, int op)
-{
-       if (!current_euid())
-               mode >>= 6;
-       else if (in_egroup_p(0))
-               mode >>= 3;
-       if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
-               return 0;
-       return -EACCES;
-}
-
-int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
-{
-       int error;
-       int mode;
-
-       error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
-       if (error)
-               return error;
-
-       if (root->permissions)
-               mode = root->permissions(root, current->nsproxy, table);
-       else
-               mode = table->mode;
-
-       return test_perm(mode, op);
-}
-
-static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
-{
-       for (; table->procname; table++) {
-               table->parent = parent;
-               if (table->child)
-                       sysctl_set_parent(table, table->child);
-       }
-}
-
-static __init int sysctl_init(void)
-{
-       sysctl_set_parent(NULL, root_table);
-#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
-       {
-               int err;
-               err = sysctl_check_table(current->nsproxy, root_table);
-       }
-#endif
+       register_sysctl_table(sysctl_base_table);
        return 0;
 }
 
-core_initcall(sysctl_init);
-
-static struct ctl_table *is_branch_in(struct ctl_table *branch,
-                                     struct ctl_table *table)
-{
-       struct ctl_table *p;
-       const char *s = branch->procname;
-
-       /* branch should have named subdirectory as its first element */
-       if (!s || !branch->child)
-               return NULL;
-
-       /* ... and nothing else */
-       if (branch[1].procname)
-               return NULL;
-
-       /* table should contain subdirectory with the same name */
-       for (p = table; p->procname; p++) {
-               if (!p->child)
-                       continue;
-               if (p->procname && strcmp(p->procname, s) == 0)
-                       return p;
-       }
-       return NULL;
-}
-
-/* see if attaching q to p would be an improvement */
-static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)
-{
-       struct ctl_table *to = p->ctl_table, *by = q->ctl_table;
-       struct ctl_table *next;
-       int is_better = 0;
-       int not_in_parent = !p->attached_by;
-
-       while ((next = is_branch_in(by, to)) != NULL) {
-               if (by == q->attached_by)
-                       is_better = 1;
-               if (to == p->attached_by)
-                       not_in_parent = 1;
-               by = by->child;
-               to = next->child;
-       }
-
-       if (is_better && not_in_parent) {
-               q->attached_by = by;
-               q->attached_to = to;
-               q->parent = p;
-       }
-}
-
-/**
- * __register_sysctl_paths - register a sysctl hierarchy
- * @root: List of sysctl headers to register on
- * @namespaces: Data to compute which lists of sysctl entries are visible
- * @path: The path to the directory the sysctl table is in.
- * @table: the top-level table structure
- *
- * Register a sysctl table hierarchy. @table should be a filled in ctl_table
- * array. A completely 0 filled entry terminates the table.
- *
- * The members of the &struct ctl_table structure are used as follows:
- *
- * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
- *            enter a sysctl file
- *
- * data - a pointer to data for use by proc_handler
- *
- * maxlen - the maximum size in bytes of the data
- *
- * mode - the file permissions for the /proc/sys file, and for sysctl(2)
- *
- * child - a pointer to the child sysctl table if this entry is a directory, or
- *         %NULL.
- *
- * proc_handler - the text handler routine (described below)
- *
- * de - for internal use by the sysctl routines
- *
- * extra1, extra2 - extra pointers usable by the proc handler routines
- *
- * Leaf nodes in the sysctl tree will be represented by a single file
- * under /proc; non-leaf nodes will be represented by directories.
- *
- * sysctl(2) can automatically manage read and write requests through
- * the sysctl table.  The data and maxlen fields of the ctl_table
- * struct enable minimal validation of the values being written to be
- * performed, and the mode field allows minimal authentication.
- *
- * There must be a proc_handler routine for any terminal nodes
- * mirrored under /proc/sys (non-terminals are handled by a built-in
- * directory handler).  Several default handlers are available to
- * cover common cases -
- *
- * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
- * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(), 
- * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax()
- *
- * It is the handler's job to read the input buffer from user memory
- * and process it. The handler should return 0 on success.
- *
- * This routine returns %NULL on a failure to register, and a pointer
- * to the table header on success.
- */
-struct ctl_table_header *__register_sysctl_paths(
-       struct ctl_table_root *root,
-       struct nsproxy *namespaces,
-       const struct ctl_path *path, struct ctl_table *table)
-{
-       struct ctl_table_header *header;
-       struct ctl_table *new, **prevp;
-       unsigned int n, npath;
-       struct ctl_table_set *set;
-
-       /* Count the path components */
-       for (npath = 0; path[npath].procname; ++npath)
-               ;
-
-       /*
-        * For each path component, allocate a 2-element ctl_table array.
-        * The first array element will be filled with the sysctl entry
-        * for this, the second will be the sentinel (procname == 0).
-        *
-        * We allocate everything in one go so that we don't have to
-        * worry about freeing additional memory in unregister_sysctl_table.
-        */
-       header = kzalloc(sizeof(struct ctl_table_header) +
-                        (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
-       if (!header)
-               return NULL;
-
-       new = (struct ctl_table *) (header + 1);
-
-       /* Now connect the dots */
-       prevp = &header->ctl_table;
-       for (n = 0; n < npath; ++n, ++path) {
-               /* Copy the procname */
-               new->procname = path->procname;
-               new->mode     = 0555;
-
-               *prevp = new;
-               prevp = &new->child;
-
-               new += 2;
-       }
-       *prevp = table;
-       header->ctl_table_arg = table;
-
-       INIT_LIST_HEAD(&header->ctl_entry);
-       header->used = 0;
-       header->unregistering = NULL;
-       header->root = root;
-       sysctl_set_parent(NULL, header->ctl_table);
-       header->count = 1;
-#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
-       if (sysctl_check_table(namespaces, header->ctl_table)) {
-               kfree(header);
-               return NULL;
-       }
-#endif
-       spin_lock(&sysctl_lock);
-       header->set = lookup_header_set(root, namespaces);
-       header->attached_by = header->ctl_table;
-       header->attached_to = root_table;
-       header->parent = &root_table_header;
-       for (set = header->set; set; set = set->parent) {
-               struct ctl_table_header *p;
-               list_for_each_entry(p, &set->list, ctl_entry) {
-                       if (p->unregistering)
-                               continue;
-                       try_attach(p, header);
-               }
-       }
-       header->parent->count++;
-       list_add_tail(&header->ctl_entry, &header->set->list);
-       spin_unlock(&sysctl_lock);
-
-       return header;
-}
-
-/**
- * register_sysctl_table_path - register a sysctl table hierarchy
- * @path: The path to the directory the sysctl table is in.
- * @table: the top-level table structure
- *
- * Register a sysctl table hierarchy. @table should be a filled in ctl_table
- * array. A completely 0 filled entry terminates the table.
- *
- * See __register_sysctl_paths for more details.
- */
-struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
-                                               struct ctl_table *table)
-{
-       return __register_sysctl_paths(&sysctl_table_root, current->nsproxy,
-                                       path, table);
-}
-
-/**
- * register_sysctl_table - register a sysctl table hierarchy
- * @table: the top-level table structure
- *
- * Register a sysctl table hierarchy. @table should be a filled in ctl_table
- * array. A completely 0 filled entry terminates the table.
- *
- * See register_sysctl_paths for more details.
- */
-struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
-{
-       static const struct ctl_path null_path[] = { {} };
-
-       return register_sysctl_paths(null_path, table);
-}
-
-/**
- * unregister_sysctl_table - unregister a sysctl table hierarchy
- * @header: the header returned from register_sysctl_table
- *
- * Unregisters the sysctl table and all children. proc entries may not
- * actually be removed until they are no longer used by anyone.
- */
-void unregister_sysctl_table(struct ctl_table_header * header)
-{
-       might_sleep();
-
-       if (header == NULL)
-               return;
-
-       spin_lock(&sysctl_lock);
-       start_unregistering(header);
-       if (!--header->parent->count) {
-               WARN_ON(1);
-               kfree(header->parent);
-       }
-       if (!--header->count)
-               kfree(header);
-       spin_unlock(&sysctl_lock);
-}
-
-int sysctl_is_seen(struct ctl_table_header *p)
-{
-       struct ctl_table_set *set = p->set;
-       int res;
-       spin_lock(&sysctl_lock);
-       if (p->unregistering)
-               res = 0;
-       else if (!set->is_seen)
-               res = 1;
-       else
-               res = set->is_seen(set);
-       spin_unlock(&sysctl_lock);
-       return res;
-}
-
-void setup_sysctl_set(struct ctl_table_set *p,
-       struct ctl_table_set *parent,
-       int (*is_seen)(struct ctl_table_set *))
-{
-       INIT_LIST_HEAD(&p->list);
-       p->parent = parent ? parent : &sysctl_table_root.default_set;
-       p->is_seen = is_seen;
-}
-
-#else /* !CONFIG_SYSCTL */
-struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
-{
-       return NULL;
-}
-
-struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
-                                                   struct ctl_table *table)
-{
-       return NULL;
-}
-
-void unregister_sysctl_table(struct ctl_table_header * table)
-{
-}
-
-void setup_sysctl_set(struct ctl_table_set *p,
-       struct ctl_table_set *parent,
-       int (*is_seen)(struct ctl_table_set *))
-{
-}
-
-void sysctl_head_put(struct ctl_table_header *head)
-{
-}
-
 #endif /* CONFIG_SYSCTL */
 
 /*
@@ -2424,6 +1958,17 @@ static int proc_taint(struct ctl_table *table, int write,
        return err;
 }
 
+#ifdef CONFIG_PRINTK
+static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
+                               void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       if (write && !capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+}
+#endif
+
 struct do_proc_dointvec_minmax_conv_param {
        int *min;
        int *max;
@@ -2517,7 +2062,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
                kbuf[left] = 0;
        }
 
-       for (; left && vleft--; i++, min++, max++, first=0) {
+       for (; left && vleft--; i++, first = 0) {
                unsigned long val;
 
                if (write) {
@@ -2867,9 +2412,7 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
                                }
                        }
 
-                       while (val_a <= val_b)
-                               set_bit(val_a++, tmp_bitmap);
-
+                       bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1);
                        first = 0;
                        proc_skip_char(&kbuf, &left, '\n');
                }
@@ -2912,8 +2455,7 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
                        if (*ppos)
                                bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len);
                        else
-                               memcpy(bitmap, tmp_bitmap,
-                                       BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long));
+                               bitmap_copy(bitmap, tmp_bitmap, bitmap_len);
                }
                kfree(tmp_bitmap);
                *lenp -= left;
@@ -2925,7 +2467,7 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
        }
 }
 
-#else /* CONFIG_PROC_FS */
+#else /* CONFIG_PROC_SYSCTL */
 
 int proc_dostring(struct ctl_table *table, int write,
                  void __user *buffer, size_t *lenp, loff_t *ppos)
@@ -2977,7 +2519,7 @@ int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
 }
 
 
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_PROC_SYSCTL */
 
 /*
  * No sense putting this after each symbol definition, twice,
@@ -2991,6 +2533,3 @@ EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
 EXPORT_SYMBOL(proc_dostring);
 EXPORT_SYMBOL(proc_doulongvec_minmax);
 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
-EXPORT_SYMBOL(register_sysctl_table);
-EXPORT_SYMBOL(register_sysctl_paths);
-EXPORT_SYMBOL(unregister_sysctl_table);