diff options
Diffstat (limited to 'kernel/params.c')
| -rw-r--r-- | kernel/params.c | 26 | 
1 files changed, 25 insertions, 1 deletions
diff --git a/kernel/params.c b/kernel/params.c index a1e3025b19a..de273ec85bd 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -24,6 +24,9 @@  #include <linux/err.h>  #include <linux/slab.h> +/* We abuse the high bits of "perm" to record whether we kmalloc'ed. */ +#define KPARAM_KMALLOCED	0x80000000 +  #if 0  #define DEBUGP printk  #else @@ -217,7 +220,19 @@ int param_set_charp(const char *val, struct kernel_param *kp)  		return -ENOSPC;  	} -	*(char **)kp->arg = (char *)val; +	if (kp->perm & KPARAM_KMALLOCED) +		kfree(*(char **)kp->arg); + +	/* This is a hack.  We can't need to strdup in early boot, and we +	 * don't need to; this mangled commandline is preserved. */ +	if (slab_is_available()) { +		kp->perm |= KPARAM_KMALLOCED; +		*(char **)kp->arg = kstrdup(val, GFP_KERNEL); +		if (!kp->arg) +			return -ENOMEM; +	} else +		*(const char **)kp->arg = val; +  	return 0;  } @@ -571,6 +586,15 @@ void module_param_sysfs_remove(struct module *mod)  }  #endif +void destroy_params(const struct kernel_param *params, unsigned num) +{ +	unsigned int i; + +	for (i = 0; i < num; i++) +		if (params[i].perm & KPARAM_KMALLOCED) +			kfree(*(char **)params[i].arg); +} +  static void __init kernel_add_sysfs_param(const char *name,  					  struct kernel_param *kparam,  					  unsigned int name_skip)  |