lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <200812012325.08606.rusty@rustcorp.com.au>
Date:	Mon, 1 Dec 2008 23:25:08 +1030
From:	Rusty Russell <rusty@...tcorp.com.au>
To:	linux-kernel@...r.kernel.org
Subject: [RFC 2/8] core_param: call these really, really early.


As soon as we have command line, so even before early_param.  They
just set vars, so it makes sense to do them as early as possible.

This allows them to replace early_param, and fixes a bug in the new
cpu_alloc implementation patches which was a complete PITA to find.

Signed-off-by: Rusty Russell <rusty@...tcorp.com.au>
---
 include/asm-generic/vmlinux.lds.h |    3 +++
 include/linux/moduleparam.h       |   26 ++++++++++++++++----------
 init/main.c                       |   25 ++++++++++++++++++++++++-
 kernel/params.c                   |   20 ++++++++++----------
 4 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -213,6 +213,9 @@
 		VMLINUX_SYMBOL(__start___param) = .;			\
 		*(__param)						\
 		VMLINUX_SYMBOL(__stop___param) = .;			\
+		VMLINUX_SYMBOL(__start___core_param) = .;		\
+		*(__core_param)						\
+		VMLINUX_SYMBOL(__stop___core_param) = .;		\
 		. = ALIGN((align));					\
 		VMLINUX_SYMBOL(__end_rodata) = .;			\
 	}								\
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -79,7 +79,7 @@ struct kparam_array
    parameters.  perm sets the visibility in sysfs: 000 means it's
    not there, read bits mean it's readable, write bits mean it's
    writable. */
-#define __module_param_call(prefix, name, set, get, arg, perm)		\
+#define __module_param_call(prefix, section, name, set, get, arg, perm)	\
 	/* Default value instead of permissions? */			\
 	static int __param_perm_check_##name __attribute__((unused)) =	\
 	BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2))	\
@@ -87,11 +87,12 @@ struct kparam_array
 	static const char __param_str_##name[] = prefix #name;		\
 	static struct kernel_param __moduleparam_const __param_##name	\
 	__used								\
-    __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
+    __attribute__ ((unused, __section__(section), aligned(sizeof(void *)))) \
 	= { __param_str_##name, perm, set, get, { arg } }
 
 #define module_param_call(name, set, get, arg, perm)			      \
-	__module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm)
+	__module_param_call(MODULE_PARAM_PREFIX, "__param",		      \
+			    name, set, get, arg, perm)
 
 /* Helper functions: type is byte, short, ushort, int, uint, long,
    ulong, charp, bool or invbool, or XXX if you define param_get_XXX,
@@ -106,21 +107,22 @@ struct kparam_array
 
 #ifndef MODULE
 /**
- * core_param - define a historical core kernel parameter.
+ * core_param - define a core kernel parameter to be set very early
  * @name: the name of the cmdline and sysfs parameter (often the same as var)
  * @var: the variable
  * @type: the type (for param_set_##type and param_get_##type)
  * @perm: visibility in sysfs
  *
- * core_param is just like module_param(), but cannot be modular and
- * doesn't add a prefix (such as "printk.").  This is for compatibility
- * with __setup(), and it makes sense as truly core parameters aren't
- * tied to the particular file they're in.
+ * core_param is just like module_param(), but cannot be modular,
+ * doesn't add a prefix (such as "printk.") and is called insanely
+ * early in boot.  This is for compatibility with __setup(), and it
+ * makes sense as truly core parameters aren't tied to the particular
+ * file they're in.
  */
 #define core_param(name, var, type, perm)				\
 	param_check_##type(name, &(var));				\
-	__module_param_call("", name, param_set_##type, param_get_##type, \
-			    &var, perm)
+	__module_param_call("", "__core_param", name, param_set_##type, \
+			    param_get_##type, &var, perm)
 #endif /* !MODULE */
 
 /* Actually copy string: maxlen param is usually sizeof(string). */
@@ -224,4 +226,8 @@ static inline void module_param_sysfs_re
 { }
 #endif
 
+/* Created by include/asm-generic/vmlinux.lds.h */
+extern struct kernel_param __start___core_param[], __stop___core_param[];
+extern struct kernel_param __start___param[], __stop___param[];
+
 #endif /* _LINUX_MODULE_PARAMS_H */
diff --git a/init/main.c b/init/main.c
--- a/init/main.c
+++ b/init/main.c
@@ -256,12 +256,32 @@ static int __init loglevel(char *str)
 
 early_param("loglevel", loglevel);
 
+static bool __init is_core_param(const char *param)
+{
+	const struct kernel_param *i;
+
+	for (i = __start___core_param; i < __stop___core_param; i++)
+		if (strcmp(param, i->name) == 0)
+			return true;
+	return false;
+}
+
+/* We can ignore options not found in core params. */
+static int __init unknown_core_ok(char *param, char *val)
+{
+	return 0;
+}
+
 /*
  * Unknown boot options get handed to init, unless they look like
  * failed parameters
  */
 static int __init unknown_bootoption(char *param, char *val)
 {
+	/* Already handled as a core param? */
+	if (is_core_param(param))
+		return 0;
+
 	/* Change NUL term back to "=", to make "param" the whole string. */
 	if (val) {
 		/* param=val or param="val"? */
@@ -537,7 +557,6 @@ asmlinkage void __init start_kernel(void
 asmlinkage void __init start_kernel(void)
 {
 	char * command_line;
-	extern struct kernel_param __start___param[], __stop___param[];
 
 	smp_setup_processor_id();
 
@@ -567,6 +586,10 @@ asmlinkage void __init start_kernel(void
 	setup_arch(&command_line);
 	mm_init_owner(&init_mm, &init_task);
 	setup_command_line(command_line);
+	parse_args("Core params", command_line, __start___core_param,
+		   __stop___core_param - __start___core_param,
+		   unknown_core_ok, true);
+
 	unwind_setup();
 	setup_per_cpu_areas();
 	setup_nr_cpu_ids();
diff --git a/kernel/params.c b/kernel/params.c
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -376,8 +376,6 @@ int param_get_string(char *buffer, struc
 #define to_module_attr(n) container_of(n, struct module_attribute, attr);
 #define to_module_kobject(n) container_of(n, struct module_kobject, kobj);
 
-extern struct kernel_param __start___param[], __stop___param[];
-
 struct param_attribute
 {
 	struct module_attribute mattr;
@@ -636,15 +634,19 @@ static void __init param_sysfs_builtin(v
 			continue;
 
 		dot = strchr(kp->name, '.');
-		if (!dot) {
-			/* This happens for core_param() */
-			strcpy(modname, "kernel");
-			name_len = 0;
-		} else {
-			name_len = dot - kp->name + 1;
-			strlcpy(modname, kp->name, name_len);
-		}
+		/* FIXME: USB code sets prefix to "".  Should use core_param */
+		if (!dot)
+			continue;
+		name_len = dot - kp->name + 1;
+		strlcpy(modname, kp->name, name_len);
 		kernel_add_sysfs_param(modname, kp, name_len);
+	}
+
+	for (kp = __start___core_param; kp < __stop___core_param; kp++) {
+		if (kp->perm == 0)
+			continue;
+
+		kernel_add_sysfs_param("kernel", kp, 0);
 	}
 }
 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ