Merge branch 'params' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus

* 'params' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus: (22 commits)
  param: don't deref arg in __same_type() checks
  param: update drivers/acpi/debug.c to new scheme
  param: use module_param in drivers/message/fusion/mptbase.c
  ide: use module_param_named rather than module_param_call
  param: update drivers/char/ipmi/ipmi_watchdog.c to new scheme
  param: lock if_sdio's lbs_helper_name and lbs_fw_name against sysfs changes.
  param: lock myri10ge_fw_name against sysfs changes.
  param: simple locking for sysfs-writable charp parameters
  param: remove unnecessary writable charp
  param: add kerneldoc to moduleparam.h
  param: locking for kernel parameters
  param: make param sections const.
  param: use free hook for charp (fix leak of charp parameters)
  param: add a free hook to kernel_param_ops.
  param: silence .init.text references from param ops
  Add param ops struct for hvc_iucv driver.
  nfs: update for module_param_named API change
  AppArmor: update for module_param_named API change
  param: use ops in struct kernel_param, rather than get and set fns directly
  param: move the EXPORT_SYMBOL to after the definitions.
  ...
This commit is contained in:
Linus Torvalds 2010-08-12 10:01:59 -07:00
commit 26df0766a7
30 changed files with 658 additions and 253 deletions

View File

@ -2,7 +2,7 @@
Maintainers: Maintainers:
CPU Hotplug Core: CPU Hotplug Core:
Rusty Russell <rusty@rustycorp.com.au> Rusty Russell <rusty@rustcorp.com.au>
Srivatsa Vaddagiri <vatsa@in.ibm.com> Srivatsa Vaddagiri <vatsa@in.ibm.com>
i386: i386:
Zwane Mwaikambo <zwane@arm.linux.org.uk> Zwane Mwaikambo <zwane@arm.linux.org.uk>

View File

@ -187,7 +187,9 @@ static int hostaudio_open(struct inode *inode, struct file *file)
int ret; int ret;
#ifdef DEBUG #ifdef DEBUG
kparam_block_sysfs_write(dsp);
printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp); printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp);
kparam_unblock_sysfs_write(dsp);
#endif #endif
state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
@ -199,9 +201,11 @@ static int hostaudio_open(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE) if (file->f_mode & FMODE_WRITE)
w = 1; w = 1;
kparam_block_sysfs_write(dsp);
lock_kernel(); lock_kernel();
ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
unlock_kernel(); unlock_kernel();
kparam_unblock_sysfs_write(dsp);
if (ret < 0) { if (ret < 0) {
kfree(state); kfree(state);
@ -258,13 +262,17 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE) if (file->f_mode & FMODE_WRITE)
w = 1; w = 1;
kparam_block_sysfs_write(mixer);
lock_kernel(); lock_kernel();
ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
unlock_kernel(); unlock_kernel();
kparam_unblock_sysfs_write(mixer);
if (ret < 0) { if (ret < 0) {
kparam_block_sysfs_write(dsp);
printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', " printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', "
"err = %d\n", dsp, -ret); "err = %d\n", dsp, -ret);
kparam_unblock_sysfs_write(dsp);
kfree(state); kfree(state);
return ret; return ret;
} }
@ -320,8 +328,10 @@ MODULE_LICENSE("GPL");
static int __init hostaudio_init_module(void) static int __init hostaudio_init_module(void)
{ {
__kernel_param_lock();
printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n", printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
dsp, mixer); dsp, mixer);
__kernel_param_unlock();
module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
if (module_data.dev_audio < 0) { if (module_data.dev_audio < 0) {

View File

@ -96,7 +96,8 @@ static const struct acpi_dlevel acpi_debug_levels[] = {
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
FS Interface (/sys) FS Interface (/sys)
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
static int param_get_debug_layer(char *buffer, struct kernel_param *kp) { static int param_get_debug_layer(char *buffer, const struct kernel_param *kp)
{
int result = 0; int result = 0;
int i; int i;
@ -118,7 +119,8 @@ static int param_get_debug_layer(char *buffer, struct kernel_param *kp) {
return result; return result;
} }
static int param_get_debug_level(char *buffer, struct kernel_param *kp) { static int param_get_debug_level(char *buffer, const struct kernel_param *kp)
{
int result = 0; int result = 0;
int i; int i;
@ -137,8 +139,18 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp) {
return result; return result;
} }
module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644); static struct kernel_param_ops acpi_debug_layer_ops = {
module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644); .set = param_set_uint,
.get = param_get_debug_layer,
};
static struct kernel_param_ops acpi_debug_level_ops = {
.set = param_set_uint,
.get = param_get_debug_level,
};
module_param_cb(debug_layer, &acpi_debug_layer_ops, &acpi_dbg_layer, 0644);
module_param_cb(debug_level, &acpi_debug_level_ops, &acpi_dbg_level, 0644);
static char trace_method_name[6]; static char trace_method_name[6];
module_param_string(trace_method_name, trace_method_name, 6, 0644); module_param_string(trace_method_name, trace_method_name, 6, 0644);
@ -147,7 +159,7 @@ module_param(trace_debug_layer, uint, 0644);
static unsigned int trace_debug_level; static unsigned int trace_debug_level;
module_param(trace_debug_level, uint, 0644); module_param(trace_debug_level, uint, 0644);
static int param_set_trace_state(const char *val, struct kernel_param *kp) static int param_set_trace_state(const char *val, const struct kernel_param *kp)
{ {
int result = 0; int result = 0;
@ -181,7 +193,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp)
return result; return result;
} }
static int param_get_trace_state(char *buffer, struct kernel_param *kp) static int param_get_trace_state(char *buffer, const struct kernel_param *kp)
{ {
if (!acpi_gbl_trace_method_name) if (!acpi_gbl_trace_method_name)
return sprintf(buffer, "disable"); return sprintf(buffer, "disable");
@ -194,8 +206,12 @@ static int param_get_trace_state(char *buffer, struct kernel_param *kp)
return 0; return 0;
} }
module_param_call(trace_state, param_set_trace_state, param_get_trace_state, static struct kernel_param_ops param_ops_trace_state = {
NULL, 0644); .set = param_set_trace_state,
.get = param_get_trace_state,
};
module_param_cb(trace_state, &param_ops_trace_state, NULL, 0644);
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
DebugFS Interface DebugFS Interface

View File

@ -1149,7 +1149,7 @@ static int hvc_iucv_setup_filter(const char *val)
* Note: If it is called early in the boot process, @val is stored and * Note: If it is called early in the boot process, @val is stored and
* parsed later in hvc_iucv_init(). * parsed later in hvc_iucv_init().
*/ */
static int param_set_vmidfilter(const char *val, struct kernel_param *kp) static int param_set_vmidfilter(const char *val, const struct kernel_param *kp)
{ {
int rc; int rc;
@ -1176,7 +1176,7 @@ static int param_set_vmidfilter(const char *val, struct kernel_param *kp)
* The function stores the filter as a comma-separated list of z/VM user IDs * The function stores the filter as a comma-separated list of z/VM user IDs
* in @buffer. Typically, sysfs routines call this function for attr show. * in @buffer. Typically, sysfs routines call this function for attr show.
*/ */
static int param_get_vmidfilter(char *buffer, struct kernel_param *kp) static int param_get_vmidfilter(char *buffer, const struct kernel_param *kp)
{ {
int rc; int rc;
size_t index, len; size_t index, len;
@ -1203,6 +1203,11 @@ static int param_get_vmidfilter(char *buffer, struct kernel_param *kp)
#define param_check_vmidfilter(name, p) __param_check(name, p, void) #define param_check_vmidfilter(name, p) __param_check(name, p, void)
static struct kernel_param_ops param_ops_vmidfilter = {
.set = param_set_vmidfilter,
.get = param_get_vmidfilter,
};
/** /**
* hvc_iucv_init() - z/VM IUCV HVC device driver initialization * hvc_iucv_init() - z/VM IUCV HVC device driver initialization
*/ */

View File

@ -196,7 +196,7 @@ static void ipmi_unregister_watchdog(int ipmi_intf);
*/ */
static int start_now; static int start_now;
static int set_param_int(const char *val, struct kernel_param *kp) static int set_param_timeout(const char *val, const struct kernel_param *kp)
{ {
char *endp; char *endp;
int l; int l;
@ -215,10 +215,11 @@ static int set_param_int(const char *val, struct kernel_param *kp)
return rv; return rv;
} }
static int get_param_int(char *buffer, struct kernel_param *kp) static struct kernel_param_ops param_ops_timeout = {
{ .set = set_param_timeout,
return sprintf(buffer, "%i", *((int *)kp->arg)); .get = param_get_int,
} };
#define param_check_timeout param_check_int
typedef int (*action_fn)(const char *intval, char *outval); typedef int (*action_fn)(const char *intval, char *outval);
@ -227,7 +228,7 @@ static int preaction_op(const char *inval, char *outval);
static int preop_op(const char *inval, char *outval); static int preop_op(const char *inval, char *outval);
static void check_parms(void); static void check_parms(void);
static int set_param_str(const char *val, struct kernel_param *kp) static int set_param_str(const char *val, const struct kernel_param *kp)
{ {
action_fn fn = (action_fn) kp->arg; action_fn fn = (action_fn) kp->arg;
int rv = 0; int rv = 0;
@ -251,7 +252,7 @@ static int set_param_str(const char *val, struct kernel_param *kp)
return rv; return rv;
} }
static int get_param_str(char *buffer, struct kernel_param *kp) static int get_param_str(char *buffer, const struct kernel_param *kp)
{ {
action_fn fn = (action_fn) kp->arg; action_fn fn = (action_fn) kp->arg;
int rv; int rv;
@ -263,7 +264,7 @@ static int get_param_str(char *buffer, struct kernel_param *kp)
} }
static int set_param_wdog_ifnum(const char *val, struct kernel_param *kp) static int set_param_wdog_ifnum(const char *val, const struct kernel_param *kp)
{ {
int rv = param_set_int(val, kp); int rv = param_set_int(val, kp);
if (rv) if (rv)
@ -276,27 +277,38 @@ static int set_param_wdog_ifnum(const char *val, struct kernel_param *kp)
return 0; return 0;
} }
module_param_call(ifnum_to_use, set_param_wdog_ifnum, get_param_int, static struct kernel_param_ops param_ops_wdog_ifnum = {
&ifnum_to_use, 0644); .set = set_param_wdog_ifnum,
.get = param_get_int,
};
#define param_check_wdog_ifnum param_check_int
static struct kernel_param_ops param_ops_str = {
.set = set_param_str,
.get = get_param_str,
};
module_param(ifnum_to_use, wdog_ifnum, 0644);
MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog " MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog "
"timer. Setting to -1 defaults to the first registered " "timer. Setting to -1 defaults to the first registered "
"interface"); "interface");
module_param_call(timeout, set_param_int, get_param_int, &timeout, 0644); module_param(timeout, timeout, 0644);
MODULE_PARM_DESC(timeout, "Timeout value in seconds."); MODULE_PARM_DESC(timeout, "Timeout value in seconds.");
module_param_call(pretimeout, set_param_int, get_param_int, &pretimeout, 0644); module_param(pretimeout, timeout, 0644);
MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds."); MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds.");
module_param_call(action, set_param_str, get_param_str, action_op, 0644); module_param_cb(action, &param_ops_str, action_op, 0644);
MODULE_PARM_DESC(action, "Timeout action. One of: " MODULE_PARM_DESC(action, "Timeout action. One of: "
"reset, none, power_cycle, power_off."); "reset, none, power_cycle, power_off.");
module_param_call(preaction, set_param_str, get_param_str, preaction_op, 0644); module_param_cb(preaction, &param_ops_str, preaction_op, 0644);
MODULE_PARM_DESC(preaction, "Pretimeout action. One of: " MODULE_PARM_DESC(preaction, "Pretimeout action. One of: "
"pre_none, pre_smi, pre_nmi, pre_int."); "pre_none, pre_smi, pre_nmi, pre_int.");
module_param_call(preop, set_param_str, get_param_str, preop_op, 0644); module_param_cb(preop, &param_ops_str, preop_op, 0644);
MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: " MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: "
"preop_none, preop_panic, preop_give_data."); "preop_none, preop_panic, preop_give_data.");

View File

@ -177,7 +177,7 @@ EXPORT_SYMBOL_GPL(ide_pci_clk);
module_param_named(pci_clock, ide_pci_clk, int, 0); module_param_named(pci_clock, ide_pci_clk, int, 0);
MODULE_PARM_DESC(pci_clock, "PCI bus clock frequency (in MHz)"); MODULE_PARM_DESC(pci_clock, "PCI bus clock frequency (in MHz)");
static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp) static int ide_set_dev_param_mask(const char *s, const struct kernel_param *kp)
{ {
int a, b, i, j = 1; int a, b, i, j = 1;
unsigned int *dev_param_mask = (unsigned int *)kp->arg; unsigned int *dev_param_mask = (unsigned int *)kp->arg;
@ -200,34 +200,40 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp)
return 0; return 0;
} }
static struct kernel_param_ops param_ops_ide_dev_mask = {
.set = ide_set_dev_param_mask
};
#define param_check_ide_dev_mask(name, p) param_check_uint(name, p)
static unsigned int ide_nodma; static unsigned int ide_nodma;
module_param_call(nodma, ide_set_dev_param_mask, NULL, &ide_nodma, 0); module_param_named(nodma, ide_nodma, ide_dev_mask, 0);
MODULE_PARM_DESC(nodma, "disallow DMA for a device"); MODULE_PARM_DESC(nodma, "disallow DMA for a device");
static unsigned int ide_noflush; static unsigned int ide_noflush;
module_param_call(noflush, ide_set_dev_param_mask, NULL, &ide_noflush, 0); module_param_named(noflush, ide_noflush, ide_dev_mask, 0);
MODULE_PARM_DESC(noflush, "disable flush requests for a device"); MODULE_PARM_DESC(noflush, "disable flush requests for a device");
static unsigned int ide_nohpa; static unsigned int ide_nohpa;
module_param_call(nohpa, ide_set_dev_param_mask, NULL, &ide_nohpa, 0); module_param_named(nohpa, ide_nohpa, ide_dev_mask, 0);
MODULE_PARM_DESC(nohpa, "disable Host Protected Area for a device"); MODULE_PARM_DESC(nohpa, "disable Host Protected Area for a device");
static unsigned int ide_noprobe; static unsigned int ide_noprobe;
module_param_call(noprobe, ide_set_dev_param_mask, NULL, &ide_noprobe, 0); module_param_named(noprobe, ide_noprobe, ide_dev_mask, 0);
MODULE_PARM_DESC(noprobe, "skip probing for a device"); MODULE_PARM_DESC(noprobe, "skip probing for a device");
static unsigned int ide_nowerr; static unsigned int ide_nowerr;
module_param_call(nowerr, ide_set_dev_param_mask, NULL, &ide_nowerr, 0); module_param_named(nowerr, ide_nowerr, ide_dev_mask, 0);
MODULE_PARM_DESC(nowerr, "ignore the ATA_DF bit for a device"); MODULE_PARM_DESC(nowerr, "ignore the ATA_DF bit for a device");
static unsigned int ide_cdroms; static unsigned int ide_cdroms;
module_param_call(cdrom, ide_set_dev_param_mask, NULL, &ide_cdroms, 0); module_param_named(cdrom, ide_cdroms, ide_dev_mask, 0);
MODULE_PARM_DESC(cdrom, "force device as a CD-ROM"); MODULE_PARM_DESC(cdrom, "force device as a CD-ROM");
struct chs_geom { struct chs_geom {

View File

@ -38,7 +38,8 @@ enum {
}; };
static int ati_remote2_set_mask(const char *val, static int ati_remote2_set_mask(const char *val,
struct kernel_param *kp, unsigned int max) const struct kernel_param *kp,
unsigned int max)
{ {
unsigned long mask; unsigned long mask;
int ret; int ret;
@ -59,28 +60,31 @@ static int ati_remote2_set_mask(const char *val,
} }
static int ati_remote2_set_channel_mask(const char *val, static int ati_remote2_set_channel_mask(const char *val,
struct kernel_param *kp) const struct kernel_param *kp)
{ {
pr_debug("%s()\n", __func__); pr_debug("%s()\n", __func__);
return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK); return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK);
} }
static int ati_remote2_get_channel_mask(char *buffer, struct kernel_param *kp) static int ati_remote2_get_channel_mask(char *buffer,
const struct kernel_param *kp)
{ {
pr_debug("%s()\n", __func__); pr_debug("%s()\n", __func__);
return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg); return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg);
} }
static int ati_remote2_set_mode_mask(const char *val, struct kernel_param *kp) static int ati_remote2_set_mode_mask(const char *val,
const struct kernel_param *kp)
{ {
pr_debug("%s()\n", __func__); pr_debug("%s()\n", __func__);
return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK); return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK);
} }
static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp) static int ati_remote2_get_mode_mask(char *buffer,
const struct kernel_param *kp)
{ {
pr_debug("%s()\n", __func__); pr_debug("%s()\n", __func__);
@ -89,15 +93,19 @@ static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp)
static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK; static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK;
#define param_check_channel_mask(name, p) __param_check(name, p, unsigned int) #define param_check_channel_mask(name, p) __param_check(name, p, unsigned int)
#define param_set_channel_mask ati_remote2_set_channel_mask static struct kernel_param_ops param_ops_channel_mask = {
#define param_get_channel_mask ati_remote2_get_channel_mask .set = ati_remote2_set_channel_mask,
.get = ati_remote2_get_channel_mask,
};
module_param(channel_mask, channel_mask, 0644); module_param(channel_mask, channel_mask, 0644);
MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>");
static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK; static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK;
#define param_check_mode_mask(name, p) __param_check(name, p, unsigned int) #define param_check_mode_mask(name, p) __param_check(name, p, unsigned int)
#define param_set_mode_mask ati_remote2_set_mode_mask static struct kernel_param_ops param_ops_mode_mask = {
#define param_get_mode_mask ati_remote2_get_mode_mask .set = ati_remote2_set_mode_mask,
.get = ati_remote2_get_mode_mask,
};
module_param(mode_mask, mode_mask, 0644); module_param(mode_mask, mode_mask, 0644);
MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");

View File

@ -39,11 +39,13 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static unsigned int psmouse_max_proto = PSMOUSE_AUTO; static unsigned int psmouse_max_proto = PSMOUSE_AUTO;
static int psmouse_set_maxproto(const char *val, struct kernel_param *kp); static int psmouse_set_maxproto(const char *val, const struct kernel_param *);
static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp); static int psmouse_get_maxproto(char *buffer, const struct kernel_param *kp);
static struct kernel_param_ops param_ops_proto_abbrev = {
.set = psmouse_set_maxproto,
.get = psmouse_get_maxproto,
};
#define param_check_proto_abbrev(name, p) __param_check(name, p, unsigned int) #define param_check_proto_abbrev(name, p) __param_check(name, p, unsigned int)
#define param_set_proto_abbrev psmouse_set_maxproto
#define param_get_proto_abbrev psmouse_get_maxproto
module_param_named(proto, psmouse_max_proto, proto_abbrev, 0644); module_param_named(proto, psmouse_max_proto, proto_abbrev, 0644);
MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, any). Useful for KVM switches."); MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, any). Useful for KVM switches.");
@ -1679,7 +1681,7 @@ static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data,
} }
static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) static int psmouse_set_maxproto(const char *val, const struct kernel_param *kp)
{ {
const struct psmouse_protocol *proto; const struct psmouse_protocol *proto;
@ -1696,7 +1698,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp)
return 0; return 0;
} }
static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) static int psmouse_get_maxproto(char *buffer, const struct kernel_param *kp)
{ {
int type = *((unsigned int *)kp->arg); int type = *((unsigned int *)kp->arg);

View File

@ -110,8 +110,7 @@ MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \
int mpt_fwfault_debug; int mpt_fwfault_debug;
EXPORT_SYMBOL(mpt_fwfault_debug); EXPORT_SYMBOL(mpt_fwfault_debug);
module_param_call(mpt_fwfault_debug, param_set_int, param_get_int, module_param(mpt_fwfault_debug, int, 0600);
&mpt_fwfault_debug, 0600);
MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault" MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
" and halt Firmware on fault - (default=0)"); " and halt Firmware on fault - (default=0)");

View File

@ -124,9 +124,9 @@ static int count = DEFAULT_COUNT;
module_param(recur_count, int, 0644); module_param(recur_count, int, 0644);
MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\
"default is 10"); "default is 10");
module_param(cpoint_name, charp, 0644); module_param(cpoint_name, charp, 0444);
MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed");
module_param(cpoint_type, charp, 0644); module_param(cpoint_type, charp, 0444);
MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\ MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\
"hitting the crash point"); "hitting the crash point");
module_param(cpoint_count, int, 0644); module_param(cpoint_count, int, 0644);

View File

@ -239,6 +239,7 @@ struct myri10ge_priv {
int watchdog_resets; int watchdog_resets;
int watchdog_pause; int watchdog_pause;
int pause; int pause;
bool fw_name_allocated;
char *fw_name; char *fw_name;
char eeprom_strings[MYRI10GE_EEPROM_STRINGS_SIZE]; char eeprom_strings[MYRI10GE_EEPROM_STRINGS_SIZE];
char *product_code_string; char *product_code_string;
@ -271,6 +272,7 @@ MODULE_FIRMWARE("myri10ge_eth_z8e.dat");
MODULE_FIRMWARE("myri10ge_rss_ethp_z8e.dat"); MODULE_FIRMWARE("myri10ge_rss_ethp_z8e.dat");
MODULE_FIRMWARE("myri10ge_rss_eth_z8e.dat"); MODULE_FIRMWARE("myri10ge_rss_eth_z8e.dat");
/* Careful: must be accessed under kparam_block_sysfs_write */
static char *myri10ge_fw_name = NULL; static char *myri10ge_fw_name = NULL;
module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR); module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name"); MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name");
@ -376,6 +378,14 @@ static inline void put_be32(__be32 val, __be32 __iomem * p)
static struct net_device_stats *myri10ge_get_stats(struct net_device *dev); static struct net_device_stats *myri10ge_get_stats(struct net_device *dev);
static void set_fw_name(struct myri10ge_priv *mgp, char *name, bool allocated)
{
if (mgp->fw_name_allocated)
kfree(mgp->fw_name);
mgp->fw_name = name;
mgp->fw_name_allocated = allocated;
}
static int static int
myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
struct myri10ge_cmd *data, int atomic) struct myri10ge_cmd *data, int atomic)
@ -747,7 +757,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp, int adopt)
dev_warn(&mgp->pdev->dev, "via hotplug\n"); dev_warn(&mgp->pdev->dev, "via hotplug\n");
} }
mgp->fw_name = "adopted"; set_fw_name(mgp, "adopted", false);
mgp->tx_boundary = 2048; mgp->tx_boundary = 2048;
myri10ge_dummy_rdma(mgp, 1); myri10ge_dummy_rdma(mgp, 1);
status = myri10ge_get_firmware_capabilities(mgp); status = myri10ge_get_firmware_capabilities(mgp);
@ -3233,7 +3243,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
* load the optimized firmware (which assumes aligned PCIe * load the optimized firmware (which assumes aligned PCIe
* completions) in order to see if it works on this host. * completions) in order to see if it works on this host.
*/ */
mgp->fw_name = myri10ge_fw_aligned; set_fw_name(mgp, myri10ge_fw_aligned, false);
status = myri10ge_load_firmware(mgp, 1); status = myri10ge_load_firmware(mgp, 1);
if (status != 0) { if (status != 0) {
goto abort; goto abort;
@ -3261,7 +3271,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
abort: abort:
/* fall back to using the unaligned firmware */ /* fall back to using the unaligned firmware */
mgp->tx_boundary = 2048; mgp->tx_boundary = 2048;
mgp->fw_name = myri10ge_fw_unaligned; set_fw_name(mgp, myri10ge_fw_unaligned, false);
} }
@ -3284,7 +3294,7 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
dev_info(&mgp->pdev->dev, "PCIE x%d Link\n", dev_info(&mgp->pdev->dev, "PCIE x%d Link\n",
link_width); link_width);
mgp->tx_boundary = 4096; mgp->tx_boundary = 4096;
mgp->fw_name = myri10ge_fw_aligned; set_fw_name(mgp, myri10ge_fw_aligned, false);
} else { } else {
myri10ge_firmware_probe(mgp); myri10ge_firmware_probe(mgp);
} }
@ -3293,22 +3303,29 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
dev_info(&mgp->pdev->dev, dev_info(&mgp->pdev->dev,
"Assuming aligned completions (forced)\n"); "Assuming aligned completions (forced)\n");
mgp->tx_boundary = 4096; mgp->tx_boundary = 4096;
mgp->fw_name = myri10ge_fw_aligned; set_fw_name(mgp, myri10ge_fw_aligned, false);
} else { } else {
dev_info(&mgp->pdev->dev, dev_info(&mgp->pdev->dev,
"Assuming unaligned completions (forced)\n"); "Assuming unaligned completions (forced)\n");
mgp->tx_boundary = 2048; mgp->tx_boundary = 2048;
mgp->fw_name = myri10ge_fw_unaligned; set_fw_name(mgp, myri10ge_fw_unaligned, false);
} }
} }
kparam_block_sysfs_write(myri10ge_fw_name);
if (myri10ge_fw_name != NULL) { if (myri10ge_fw_name != NULL) {
char *fw_name = kstrdup(myri10ge_fw_name, GFP_KERNEL);
if (fw_name) {
overridden = 1; overridden = 1;
mgp->fw_name = myri10ge_fw_name; set_fw_name(mgp, fw_name, true);
} }
}
kparam_unblock_sysfs_write(myri10ge_fw_name);
if (mgp->board_number < MYRI10GE_MAX_BOARDS && if (mgp->board_number < MYRI10GE_MAX_BOARDS &&
myri10ge_fw_names[mgp->board_number] != NULL && myri10ge_fw_names[mgp->board_number] != NULL &&
strlen(myri10ge_fw_names[mgp->board_number])) { strlen(myri10ge_fw_names[mgp->board_number])) {
mgp->fw_name = myri10ge_fw_names[mgp->board_number]; set_fw_name(mgp, myri10ge_fw_names[mgp->board_number], false);
overridden = 1; overridden = 1;
} }
if (overridden) if (overridden)
@ -3660,6 +3677,7 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
struct myri10ge_cmd cmd; struct myri10ge_cmd cmd;
struct pci_dev *pdev = mgp->pdev; struct pci_dev *pdev = mgp->pdev;
char *old_fw; char *old_fw;
bool old_allocated;
int i, status, ncpus, msix_cap; int i, status, ncpus, msix_cap;
mgp->num_slices = 1; mgp->num_slices = 1;
@ -3672,17 +3690,23 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
/* try to load the slice aware rss firmware */ /* try to load the slice aware rss firmware */
old_fw = mgp->fw_name; old_fw = mgp->fw_name;
old_allocated = mgp->fw_name_allocated;
/* don't free old_fw if we override it. */
mgp->fw_name_allocated = false;
if (myri10ge_fw_name != NULL) { if (myri10ge_fw_name != NULL) {
dev_info(&mgp->pdev->dev, "overriding rss firmware to %s\n", dev_info(&mgp->pdev->dev, "overriding rss firmware to %s\n",
myri10ge_fw_name); myri10ge_fw_name);
mgp->fw_name = myri10ge_fw_name; set_fw_name(mgp, myri10ge_fw_name, false);
} else if (old_fw == myri10ge_fw_aligned) } else if (old_fw == myri10ge_fw_aligned)
mgp->fw_name = myri10ge_fw_rss_aligned; set_fw_name(mgp, myri10ge_fw_rss_aligned, false);
else else
mgp->fw_name = myri10ge_fw_rss_unaligned; set_fw_name(mgp, myri10ge_fw_rss_unaligned, false);
status = myri10ge_load_firmware(mgp, 0); status = myri10ge_load_firmware(mgp, 0);
if (status != 0) { if (status != 0) {
dev_info(&pdev->dev, "Rss firmware not found\n"); dev_info(&pdev->dev, "Rss firmware not found\n");
if (old_allocated)
kfree(old_fw);
return; return;
} }
@ -3747,6 +3771,8 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
mgp->num_slices); mgp->num_slices);
if (status == 0) { if (status == 0) {
pci_disable_msix(pdev); pci_disable_msix(pdev);
if (old_allocated)
kfree(old_fw);
return; return;
} }
if (status > 0) if (status > 0)
@ -3763,7 +3789,7 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
abort_with_fw: abort_with_fw:
mgp->num_slices = 1; mgp->num_slices = 1;
mgp->fw_name = old_fw; set_fw_name(mgp, old_fw, old_allocated);
myri10ge_load_firmware(mgp, 0); myri10ge_load_firmware(mgp, 0);
} }
@ -3993,6 +4019,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_disable_device(pdev); pci_disable_device(pdev);
abort_with_netdev: abort_with_netdev:
set_fw_name(mgp, NULL, false);
free_netdev(netdev); free_netdev(netdev);
return status; return status;
} }
@ -4037,6 +4064,7 @@ static void myri10ge_remove(struct pci_dev *pdev)
dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd), dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
mgp->cmd, mgp->cmd_bus); mgp->cmd, mgp->cmd_bus);
set_fw_name(mgp, NULL, false);
free_netdev(netdev); free_netdev(netdev);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);

View File

@ -125,6 +125,8 @@ struct if_sdio_card {
const char *helper; const char *helper;
const char *firmware; const char *firmware;
bool helper_allocated;
bool firmware_allocated;
u8 buffer[65536]; u8 buffer[65536];
@ -984,16 +986,34 @@ static int if_sdio_probe(struct sdio_func *func,
card->helper = if_sdio_models[i].helper; card->helper = if_sdio_models[i].helper;
card->firmware = if_sdio_models[i].firmware; card->firmware = if_sdio_models[i].firmware;
kparam_block_sysfs_write(helper_name);
if (lbs_helper_name) { if (lbs_helper_name) {
char *helper = kstrdup(lbs_helper_name, GFP_KERNEL);
if (!helper) {
kparam_unblock_sysfs_write(helper_name);
ret = -ENOMEM;
goto free;
}
lbs_deb_sdio("overriding helper firmware: %s\n", lbs_deb_sdio("overriding helper firmware: %s\n",
lbs_helper_name); lbs_helper_name);
card->helper = lbs_helper_name; card->helper = helper;
card->helper_allocated = true;
} }
kparam_unblock_sysfs_write(helper_name);
kparam_block_sysfs_write(fw_name);
if (lbs_fw_name) { if (lbs_fw_name) {
lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name); char *fw_name = kstrdup(lbs_fw_name, GFP_KERNEL);
card->firmware = lbs_fw_name; if (!fw_name) {
kparam_unblock_sysfs_write(fw_name);
ret = -ENOMEM;
goto free;
} }
lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name);
card->firmware = fw_name;
card->firmware_allocated = true;
}
kparam_unblock_sysfs_write(fw_name);
sdio_claim_host(func); sdio_claim_host(func);
@ -1127,6 +1147,10 @@ static int if_sdio_probe(struct sdio_func *func,
kfree(packet); kfree(packet);
} }
if (card->helper_allocated)
kfree(card->helper);
if (card->firmware_allocated)
kfree(card->firmware);
kfree(card); kfree(card);
goto out; goto out;
@ -1177,6 +1201,10 @@ static void if_sdio_remove(struct sdio_func *func)
kfree(packet); kfree(packet);
} }
if (card->helper_allocated)
kfree(card->helper);
if (card->firmware_allocated)
kfree(card->firmware);
kfree(card); kfree(card);
lbs_deb_leave(LBS_DEB_SDIO); lbs_deb_leave(LBS_DEB_SDIO);

View File

@ -289,10 +289,13 @@ static int if_usb_probe(struct usb_interface *intf,
} }
/* Upload firmware */ /* Upload firmware */
kparam_block_sysfs_write(fw_name);
if (__if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) { if (__if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) {
kparam_unblock_sysfs_write(fw_name);
lbs_deb_usbd(&udev->dev, "FW upload failed\n"); lbs_deb_usbd(&udev->dev, "FW upload failed\n");
goto err_prog_firmware; goto err_prog_firmware;
} }
kparam_unblock_sysfs_write(fw_name);
if (!(priv = lbs_add_card(cardp, &udev->dev))) if (!(priv = lbs_add_card(cardp, &udev->dev)))
goto err_prog_firmware; goto err_prog_firmware;

View File

@ -811,12 +811,15 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp)
lbtf_deb_enter(LBTF_DEB_USB); lbtf_deb_enter(LBTF_DEB_USB);
kparam_block_sysfs_write(fw_name);
ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev);
if (ret < 0) { if (ret < 0) {
pr_err("request_firmware() failed with %#x\n", ret); pr_err("request_firmware() failed with %#x\n", ret);
pr_err("firmware %s not found\n", lbtf_fw_name); pr_err("firmware %s not found\n", lbtf_fw_name);
kparam_unblock_sysfs_write(fw_name);
goto done; goto done;
} }
kparam_unblock_sysfs_write(fw_name);
if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
goto release_fw; goto release_fw;

View File

@ -788,6 +788,7 @@ bfad_drv_init(struct bfad_s *bfad)
memset(&driver_info, 0, sizeof(driver_info)); memset(&driver_info, 0, sizeof(driver_info));
strncpy(driver_info.version, BFAD_DRIVER_VERSION, strncpy(driver_info.version, BFAD_DRIVER_VERSION,
sizeof(driver_info.version) - 1); sizeof(driver_info.version) - 1);
__kernel_param_lock();
if (host_name) if (host_name)
strncpy(driver_info.host_machine_name, host_name, strncpy(driver_info.host_machine_name, host_name,
sizeof(driver_info.host_machine_name) - 1); sizeof(driver_info.host_machine_name) - 1);
@ -797,6 +798,7 @@ bfad_drv_init(struct bfad_s *bfad)
if (os_patch) if (os_patch)
strncpy(driver_info.host_os_patch, os_patch, strncpy(driver_info.host_os_patch, os_patch,
sizeof(driver_info.host_os_patch) - 1); sizeof(driver_info.host_os_patch) - 1);
__kernel_param_unlock();
strncpy(driver_info.os_device_name, bfad->pci_name, strncpy(driver_info.os_device_name, bfad->pci_name,
sizeof(driver_info.os_device_name - 1)); sizeof(driver_info.os_device_name - 1));

View File

@ -61,7 +61,7 @@ static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = {
}; };
static char *ifname = "wlan%d"; static char ifname[IFNAMSIZ] = "wlan%d";
static int hwseqnum = 0; static int hwseqnum = 0;
static int hwwep = 0; static int hwwep = 0;
static int channels = 0x3fff; static int channels = 0x3fff;
@ -72,7 +72,7 @@ MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
MODULE_DESCRIPTION("Linux driver for Realtek RTL8180 / RTL8185 WiFi cards"); MODULE_DESCRIPTION("Linux driver for Realtek RTL8180 / RTL8185 WiFi cards");
module_param(ifname, charp, S_IRUGO|S_IWUSR); module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
module_param(hwseqnum, int, S_IRUGO|S_IWUSR); module_param(hwseqnum, int, S_IRUGO|S_IWUSR);
module_param(hwwep, int, S_IRUGO|S_IWUSR); module_param(hwwep, int, S_IRUGO|S_IWUSR);
module_param(channels, int, S_IRUGO|S_IWUSR); module_param(channels, int, S_IRUGO|S_IWUSR);
@ -3609,7 +3609,7 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
if (dev_alloc_name(dev, ifname) < 0) { if (dev_alloc_name(dev, ifname) < 0) {
DMESG("Oops: devname already taken! Trying wlan%%d...\n"); DMESG("Oops: devname already taken! Trying wlan%%d...\n");
ifname = "wlan%d"; strcpy(ifname, "wlan%d");
dev_alloc_name(dev, ifname); dev_alloc_name(dev, ifname);
} }

View File

@ -112,7 +112,7 @@ static const struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
{} {}
}; };
static char* ifname = "wlan%d"; static char ifname[IFNAMSIZ] = "wlan%d";
static int hwwep = 1; //default use hw. set 0 to use software security static int hwwep = 1; //default use hw. set 0 to use software security
static int channels = 0x3fff; static int channels = 0x3fff;
@ -123,7 +123,7 @@ MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl);
MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards"); MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
module_param(ifname, charp, S_IRUGO|S_IWUSR ); module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
//module_param(hwseqnum,int, S_IRUGO|S_IWUSR); //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
module_param(hwwep,int, S_IRUGO|S_IWUSR); module_param(hwwep,int, S_IRUGO|S_IWUSR);
module_param(channels,int, S_IRUGO|S_IWUSR); module_param(channels,int, S_IRUGO|S_IWUSR);
@ -6446,7 +6446,7 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
if (dev_alloc_name(dev, ifname) < 0){ if (dev_alloc_name(dev, ifname) < 0){
RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n"); RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
ifname = "wlan%d"; strcpy(ifname, "wlan%d");
dev_alloc_name(dev, ifname); dev_alloc_name(dev, ifname);
} }

View File

@ -144,13 +144,13 @@ MODULE_VERSION("V 1.1");
MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl); MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards"); MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
static char* ifname = "wlan%d"; static char ifname[IFNAMSIZ] = "wlan%d";
static int hwwep = 1; //default use hw. set 0 to use software security static int hwwep = 1; //default use hw. set 0 to use software security
static int channels = 0x3fff; static int channels = 0x3fff;
module_param(ifname, charp, S_IRUGO|S_IWUSR ); module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
//module_param(hwseqnum,int, S_IRUGO|S_IWUSR); //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
module_param(hwwep,int, S_IRUGO|S_IWUSR); module_param(hwwep,int, S_IRUGO|S_IWUSR);
module_param(channels,int, S_IRUGO|S_IWUSR); module_param(channels,int, S_IRUGO|S_IWUSR);
@ -7406,7 +7406,7 @@ static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
if (dev_alloc_name(dev, ifname) < 0){ if (dev_alloc_name(dev, ifname) < 0){
RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n"); RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
ifname = "wlan%d"; strcpy(ifname, "wlan%d");
dev_alloc_name(dev, ifname); dev_alloc_name(dev, ifname);
} }

View File

@ -1577,6 +1577,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver)
char file_arr[] = "CMVxy.bin"; char file_arr[] = "CMVxy.bin";
char *file; char *file;
kparam_block_sysfs_write(cmv_file);
/* set proper name corresponding modem version and line type */ /* set proper name corresponding modem version and line type */
if (cmv_file[sc->modem_index] == NULL) { if (cmv_file[sc->modem_index] == NULL) {
if (UEA_CHIP_VERSION(sc) == ADI930) if (UEA_CHIP_VERSION(sc) == ADI930)
@ -1595,6 +1596,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver)
strlcat(cmv_name, file, UEA_FW_NAME_MAX); strlcat(cmv_name, file, UEA_FW_NAME_MAX);
if (ver == 2) if (ver == 2)
strlcat(cmv_name, ".v2", UEA_FW_NAME_MAX); strlcat(cmv_name, ".v2", UEA_FW_NAME_MAX);
kparam_unblock_sysfs_write(cmv_file);
} }
static int request_cmvs_old(struct uea_softc *sc, static int request_cmvs_old(struct uea_softc *sc,

View File

@ -1977,8 +1977,7 @@ static void __devexit uvesafb_exit(void)
module_exit(uvesafb_exit); module_exit(uvesafb_exit);
#define param_get_scroll NULL static int param_set_scroll(const char *val, const struct kernel_param *kp)
static int param_set_scroll(const char *val, struct kernel_param *kp)
{ {
ypan = 0; ypan = 0;
@ -1993,7 +1992,9 @@ static int param_set_scroll(const char *val, struct kernel_param *kp)
return 0; return 0;
} }
static struct kernel_param_ops param_ops_scroll = {
.set = param_set_scroll,
};
#define param_check_scroll(name, p) __param_check(name, p, void) #define param_check_scroll(name, p) __param_check(name, p, void)
module_param_named(scroll, ypan, scroll, 0); module_param_named(scroll, ypan, scroll, 0);

View File

@ -726,7 +726,9 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi
/* Prepare startup mode */ /* Prepare startup mode */
kparam_block_sysfs_write(mode_option);
rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8); rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8);
kparam_unblock_sysfs_write(mode_option);
if (! ((rc == 1) || (rc == 2))) { if (! ((rc == 1) || (rc == 2))) {
rc = -EINVAL; rc = -EINVAL;
dev_err(info->device, "mode %s not found\n", mode_option); dev_err(info->device, "mode %s not found\n", mode_option);

View File

@ -45,7 +45,7 @@ unsigned short nfs_callback_tcpport;
unsigned short nfs_callback_tcpport6; unsigned short nfs_callback_tcpport6;
#define NFS_CALLBACK_MAXPORTNR (65535U) #define NFS_CALLBACK_MAXPORTNR (65535U)
static int param_set_portnr(const char *val, struct kernel_param *kp) static int param_set_portnr(const char *val, const struct kernel_param *kp)
{ {
unsigned long num; unsigned long num;
int ret; int ret;
@ -58,11 +58,10 @@ static int param_set_portnr(const char *val, struct kernel_param *kp)
*((unsigned int *)kp->arg) = num; *((unsigned int *)kp->arg) = num;
return 0; return 0;
} }
static struct kernel_param_ops param_ops_portnr = {
static int param_get_portnr(char *buffer, struct kernel_param *kp) .set = param_set_portnr,
{ .get = param_get_uint,
return param_get_uint(buffer, kp); };
}
#define param_check_portnr(name, p) __param_check(name, p, unsigned int); #define param_check_portnr(name, p) __param_check(name, p, unsigned int);
module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644); module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);

View File

@ -31,20 +31,23 @@ static const char __module_cat(name,__LINE__)[] \
struct kernel_param; struct kernel_param;
struct kernel_param_ops {
/* Returns 0, or -errno. arg is in kp->arg. */ /* Returns 0, or -errno. arg is in kp->arg. */
typedef int (*param_set_fn)(const char *val, struct kernel_param *kp); int (*set)(const char *val, const struct kernel_param *kp);
/* Returns length written or -errno. Buffer is 4k (ie. be short!) */ /* Returns length written or -errno. Buffer is 4k (ie. be short!) */
typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp); int (*get)(char *buffer, const struct kernel_param *kp);
/* Optional function to free kp->arg when module unloaded. */
void (*free)(void *arg);
};
/* Flag bits for kernel_param.flags */ /* Flag bits for kernel_param.flags */
#define KPARAM_ISBOOL 2 #define KPARAM_ISBOOL 2
struct kernel_param { struct kernel_param {
const char *name; const char *name;
const struct kernel_param_ops *ops;
u16 perm; u16 perm;
u16 flags; u16 flags;
param_set_fn set;
param_get_fn get;
union { union {
void *arg; void *arg;
const struct kparam_string *str; const struct kparam_string *str;
@ -63,12 +66,67 @@ struct kparam_array
{ {
unsigned int max; unsigned int max;
unsigned int *num; unsigned int *num;
param_set_fn set; const struct kernel_param_ops *ops;
param_get_fn get;
unsigned int elemsize; unsigned int elemsize;
void *elem; void *elem;
}; };
/**
* module_param - typesafe helper for a module/cmdline parameter
* @value: the variable to alter, and exposed parameter name.
* @type: the type of the parameter
* @perm: visibility in sysfs.
*
* @value becomes the module parameter, or (prefixed by KBUILD_MODNAME and a
* ".") the kernel commandline parameter. Note that - is changed to _, so
* the user can use "foo-bar=1" even for variable "foo_bar".
*
* @perm is 0 if the the variable is not to appear in sysfs, or 0444
* for world-readable, 0644 for root-writable, etc. Note that if it
* is writable, you may need to use kparam_block_sysfs_write() around
* accesses (esp. charp, which can be kfreed when it changes).
*
* The @type is simply pasted to refer to a param_ops_##type and a
* param_check_##type: for convenience many standard types are provided but
* you can create your own by defining those variables.
*
* Standard types are:
* byte, short, ushort, int, uint, long, ulong
* charp: a character pointer
* bool: a bool, values 0/1, y/n, Y/N.
* invbool: the above, only sense-reversed (N = true).
*/
#define module_param(name, type, perm) \
module_param_named(name, name, type, perm)
/**
* module_param_named - typesafe helper for a renamed module/cmdline parameter
* @name: a valid C identifier which is the parameter name.
* @value: the actual lvalue to alter.
* @type: the type of the parameter
* @perm: visibility in sysfs.
*
* Usually it's a good idea to have variable names and user-exposed names the
* same, but that's harder if the variable must be non-static or is inside a
* structure. This allows exposure under a different name.
*/
#define module_param_named(name, value, type, perm) \
param_check_##type(name, &(value)); \
module_param_cb(name, &param_ops_##type, &value, perm); \
__MODULE_PARM_TYPE(name, #type)
/**
* module_param_cb - general callback for a module/cmdline parameter
* @name: a valid C identifier which is the parameter name.
* @ops: the set & get operations for this parameter.
* @perm: visibility in sysfs.
*
* The ops can have NULL set or get functions.
*/
#define module_param_cb(name, ops, arg, perm) \
__module_param_call(MODULE_PARAM_PREFIX, \
name, ops, arg, __same_type((arg), bool *), perm)
/* On alpha, ia64 and ppc64 relocations to global data cannot go into /* On alpha, ia64 and ppc64 relocations to global data cannot go into
read-only sections (which is part of respective UNIX ABI on these read-only sections (which is part of respective UNIX ABI on these
platforms). So 'const' makes no sense and even causes compile failures platforms). So 'const' makes no sense and even causes compile failures
@ -80,10 +138,8 @@ struct kparam_array
#endif #endif
/* This is the fundamental function for registering boot/module /* This is the fundamental function for registering boot/module
parameters. perm sets the visibility in sysfs: 000 means it's parameters. */
not there, read bits mean it's readable, write bits mean it's #define __module_param_call(prefix, name, ops, arg, isbool, perm) \
writable. */
#define __module_param_call(prefix, name, set, get, arg, isbool, perm) \
/* Default value instead of permissions? */ \ /* Default value instead of permissions? */ \
static int __param_perm_check_##name __attribute__((unused)) = \ static int __param_perm_check_##name __attribute__((unused)) = \
BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \
@ -92,31 +148,87 @@ struct kparam_array
static struct kernel_param __moduleparam_const __param_##name \ static struct kernel_param __moduleparam_const __param_##name \
__used \ __used \
__attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
= { __param_str_##name, perm, isbool ? KPARAM_ISBOOL : 0, \ = { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \
set, get, { arg } } { arg } }
/* Obsolete - use module_param_cb() */
#define module_param_call(name, set, get, arg, perm) \ #define module_param_call(name, set, get, arg, perm) \
static struct kernel_param_ops __param_ops_##name = \
{ (void *)set, (void *)get }; \
__module_param_call(MODULE_PARAM_PREFIX, \ __module_param_call(MODULE_PARAM_PREFIX, \
name, set, get, arg, \ name, &__param_ops_##name, arg, \
__same_type(*(arg), bool), perm) __same_type(arg, bool *), \
(perm) + sizeof(__check_old_set_param(set))*0)
/* Helper functions: type is byte, short, ushort, int, uint, long, /* We don't get oldget: it's often a new-style param_get_uint, etc. */
ulong, charp, bool or invbool, or XXX if you define param_get_XXX, static inline int
param_set_XXX and param_check_XXX. */ __check_old_set_param(int (*oldset)(const char *, struct kernel_param *))
#define module_param_named(name, value, type, perm) \ {
param_check_##type(name, &(value)); \ return 0;
module_param_call(name, param_set_##type, param_get_##type, &value, perm); \ }
__MODULE_PARM_TYPE(name, #type)
#define module_param(name, type, perm) \ /**
module_param_named(name, name, type, perm) * kparam_block_sysfs_write - make sure a parameter isn't written via sysfs.
* @name: the name of the parameter
*
* There's no point blocking write on a paramter that isn't writable via sysfs!
*/
#define kparam_block_sysfs_write(name) \
do { \
BUG_ON(!(__param_##name.perm & 0222)); \
__kernel_param_lock(); \
} while (0)
/**
* kparam_unblock_sysfs_write - allows sysfs to write to a parameter again.
* @name: the name of the parameter
*/
#define kparam_unblock_sysfs_write(name) \
do { \
BUG_ON(!(__param_##name.perm & 0222)); \
__kernel_param_unlock(); \
} while (0)
/**
* kparam_block_sysfs_read - make sure a parameter isn't read via sysfs.
* @name: the name of the parameter
*
* This also blocks sysfs writes.
*/
#define kparam_block_sysfs_read(name) \
do { \
BUG_ON(!(__param_##name.perm & 0444)); \
__kernel_param_lock(); \
} while (0)
/**
* kparam_unblock_sysfs_read - allows sysfs to read a parameter again.
* @name: the name of the parameter
*/
#define kparam_unblock_sysfs_read(name) \
do { \
BUG_ON(!(__param_##name.perm & 0444)); \
__kernel_param_unlock(); \
} while (0)
#ifdef CONFIG_SYSFS
extern void __kernel_param_lock(void);
extern void __kernel_param_unlock(void);
#else
static inline void __kernel_param_lock(void)
{
}
static inline void __kernel_param_unlock(void)
{
}
#endif
#ifndef MODULE #ifndef MODULE
/** /**
* core_param - define a historical core kernel parameter. * core_param - define a historical core kernel parameter.
* @name: the name of the cmdline and sysfs parameter (often the same as var) * @name: the name of the cmdline and sysfs parameter (often the same as var)
* @var: the variable * @var: the variable
* @type: the type (for param_set_##type and param_get_##type) * @type: the type of the parameter
* @perm: visibility in sysfs * @perm: visibility in sysfs
* *
* core_param is just like module_param(), but cannot be modular and * core_param is just like module_param(), but cannot be modular and
@ -126,23 +238,32 @@ struct kparam_array
*/ */
#define core_param(name, var, type, perm) \ #define core_param(name, var, type, perm) \
param_check_##type(name, &(var)); \ param_check_##type(name, &(var)); \
__module_param_call("", name, param_set_##type, param_get_##type, \ __module_param_call("", name, &param_ops_##type, \
&var, __same_type(var, bool), perm) &var, __same_type(var, bool), perm)
#endif /* !MODULE */ #endif /* !MODULE */
/* Actually copy string: maxlen param is usually sizeof(string). */ /**
* module_param_string - a char array parameter
* @name: the name of the parameter
* @string: the string variable
* @len: the maximum length of the string, incl. terminator
* @perm: visibility in sysfs.
*
* This actually copies the string when it's set (unlike type charp).
* @len is usually just sizeof(string).
*/
#define module_param_string(name, string, len, perm) \ #define module_param_string(name, string, len, perm) \
static const struct kparam_string __param_string_##name \ static const struct kparam_string __param_string_##name \
= { len, string }; \ = { len, string }; \
__module_param_call(MODULE_PARAM_PREFIX, name, \ __module_param_call(MODULE_PARAM_PREFIX, name, \
param_set_copystring, param_get_string, \ &param_ops_string, \
.str = &__param_string_##name, 0, perm); \ .str = &__param_string_##name, 0, perm); \
__MODULE_PARM_TYPE(name, "string") __MODULE_PARM_TYPE(name, "string")
/* Called on module insert or kernel boot */ /* Called on module insert or kernel boot */
extern int parse_args(const char *name, extern int parse_args(const char *name,
char *args, char *args,
struct kernel_param *params, const struct kernel_param *params,
unsigned num, unsigned num,
int (*unknown)(char *param, char *val)); int (*unknown)(char *param, char *val));
@ -162,72 +283,105 @@ static inline void destroy_params(const struct kernel_param *params,
#define __param_check(name, p, type) \ #define __param_check(name, p, type) \
static inline type *__check_##name(void) { return(p); } static inline type *__check_##name(void) { return(p); }
extern int param_set_byte(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_byte;
extern int param_get_byte(char *buffer, struct kernel_param *kp); extern int param_set_byte(const char *val, const struct kernel_param *kp);
extern int param_get_byte(char *buffer, const struct kernel_param *kp);
#define param_check_byte(name, p) __param_check(name, p, unsigned char) #define param_check_byte(name, p) __param_check(name, p, unsigned char)
extern int param_set_short(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_short;
extern int param_get_short(char *buffer, struct kernel_param *kp); extern int param_set_short(const char *val, const struct kernel_param *kp);
extern int param_get_short(char *buffer, const struct kernel_param *kp);
#define param_check_short(name, p) __param_check(name, p, short) #define param_check_short(name, p) __param_check(name, p, short)
extern int param_set_ushort(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_ushort;
extern int param_get_ushort(char *buffer, struct kernel_param *kp); extern int param_set_ushort(const char *val, const struct kernel_param *kp);
extern int param_get_ushort(char *buffer, const struct kernel_param *kp);
#define param_check_ushort(name, p) __param_check(name, p, unsigned short) #define param_check_ushort(name, p) __param_check(name, p, unsigned short)
extern int param_set_int(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_int;
extern int param_get_int(char *buffer, struct kernel_param *kp); extern int param_set_int(const char *val, const struct kernel_param *kp);
extern int param_get_int(char *buffer, const struct kernel_param *kp);
#define param_check_int(name, p) __param_check(name, p, int) #define param_check_int(name, p) __param_check(name, p, int)
extern int param_set_uint(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_uint;
extern int param_get_uint(char *buffer, struct kernel_param *kp); extern int param_set_uint(const char *val, const struct kernel_param *kp);
extern int param_get_uint(char *buffer, const struct kernel_param *kp);
#define param_check_uint(name, p) __param_check(name, p, unsigned int) #define param_check_uint(name, p) __param_check(name, p, unsigned int)
extern int param_set_long(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_long;
extern int param_get_long(char *buffer, struct kernel_param *kp); extern int param_set_long(const char *val, const struct kernel_param *kp);
extern int param_get_long(char *buffer, const struct kernel_param *kp);
#define param_check_long(name, p) __param_check(name, p, long) #define param_check_long(name, p) __param_check(name, p, long)
extern int param_set_ulong(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_ulong;
extern int param_get_ulong(char *buffer, struct kernel_param *kp); extern int param_set_ulong(const char *val, const struct kernel_param *kp);
extern int param_get_ulong(char *buffer, const struct kernel_param *kp);
#define param_check_ulong(name, p) __param_check(name, p, unsigned long) #define param_check_ulong(name, p) __param_check(name, p, unsigned long)
extern int param_set_charp(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_charp;
extern int param_get_charp(char *buffer, struct kernel_param *kp); extern int param_set_charp(const char *val, const struct kernel_param *kp);
extern int param_get_charp(char *buffer, const struct kernel_param *kp);
#define param_check_charp(name, p) __param_check(name, p, char *) #define param_check_charp(name, p) __param_check(name, p, char *)
/* For historical reasons "bool" parameters can be (unsigned) "int". */ /* For historical reasons "bool" parameters can be (unsigned) "int". */
extern int param_set_bool(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_bool;
extern int param_get_bool(char *buffer, struct kernel_param *kp); extern int param_set_bool(const char *val, const struct kernel_param *kp);
extern int param_get_bool(char *buffer, const struct kernel_param *kp);
#define param_check_bool(name, p) \ #define param_check_bool(name, p) \
static inline void __check_##name(void) \ static inline void __check_##name(void) \
{ \ { \
BUILD_BUG_ON(!__same_type(*(p), bool) && \ BUILD_BUG_ON(!__same_type((p), bool *) && \
!__same_type(*(p), unsigned int) && \ !__same_type((p), unsigned int *) && \
!__same_type(*(p), int)); \ !__same_type((p), int *)); \
} }
extern int param_set_invbool(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_invbool;
extern int param_get_invbool(char *buffer, struct kernel_param *kp); extern int param_set_invbool(const char *val, const struct kernel_param *kp);
extern int param_get_invbool(char *buffer, const struct kernel_param *kp);
#define param_check_invbool(name, p) __param_check(name, p, bool) #define param_check_invbool(name, p) __param_check(name, p, bool)
/* Comma-separated array: *nump is set to number they actually specified. */ /**
* module_param_array - a parameter which is an array of some type
* @name: the name of the array variable
* @type: the type, as per module_param()
* @nump: optional pointer filled in with the number written
* @perm: visibility in sysfs
*
* Input and output are as comma-separated values. Commas inside values
* don't work properly (eg. an array of charp).
*
* ARRAY_SIZE(@name) is used to determine the number of elements in the
* array, so the definition must be visible.
*/
#define module_param_array(name, type, nump, perm) \
module_param_array_named(name, name, type, nump, perm)
/**
* module_param_array_named - renamed parameter which is an array of some type
* @name: a valid C identifier which is the parameter name
* @array: the name of the array variable
* @type: the type, as per module_param()
* @nump: optional pointer filled in with the number written
* @perm: visibility in sysfs
*
* This exposes a different name than the actual variable name. See
* module_param_named() for why this might be necessary.
*/
#define module_param_array_named(name, array, type, nump, perm) \ #define module_param_array_named(name, array, type, nump, perm) \
static const struct kparam_array __param_arr_##name \ static const struct kparam_array __param_arr_##name \
= { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type,\ = { ARRAY_SIZE(array), nump, &param_ops_##type, \
sizeof(array[0]), array }; \ sizeof(array[0]), array }; \
__module_param_call(MODULE_PARAM_PREFIX, name, \ __module_param_call(MODULE_PARAM_PREFIX, name, \
param_array_set, param_array_get, \ &param_array_ops, \
.arr = &__param_arr_##name, \ .arr = &__param_arr_##name, \
__same_type(array[0], bool), perm); \ __same_type(array[0], bool), perm); \
__MODULE_PARM_TYPE(name, "array of " #type) __MODULE_PARM_TYPE(name, "array of " #type)
#define module_param_array(name, type, nump, perm) \ extern struct kernel_param_ops param_array_ops;
module_param_array_named(name, name, type, nump, perm)
extern int param_array_set(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_string;
extern int param_array_get(char *buffer, struct kernel_param *kp); extern int param_set_copystring(const char *val, const struct kernel_param *);
extern int param_get_string(char *buffer, const struct kernel_param *kp);
extern int param_set_copystring(const char *val, struct kernel_param *kp);
extern int param_get_string(char *buffer, struct kernel_param *kp);
/* for exporting parameters in /sys/parameters */ /* for exporting parameters in /sys/parameters */
@ -235,13 +389,13 @@ struct module;
#if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES) #if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES)
extern int module_param_sysfs_setup(struct module *mod, extern int module_param_sysfs_setup(struct module *mod,
struct kernel_param *kparam, const struct kernel_param *kparam,
unsigned int num_params); unsigned int num_params);
extern void module_param_sysfs_remove(struct module *mod); extern void module_param_sysfs_remove(struct module *mod);
#else #else
static inline int module_param_sysfs_setup(struct module *mod, static inline int module_param_sysfs_setup(struct module *mod,
struct kernel_param *kparam, const struct kernel_param *kparam,
unsigned int num_params) unsigned int num_params)
{ {
return 0; return 0;

View File

@ -201,11 +201,11 @@ static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
static const char *panic_later, *panic_param; static const char *panic_later, *panic_param;
extern struct obs_kernel_param __setup_start[], __setup_end[]; extern const struct obs_kernel_param __setup_start[], __setup_end[];
static int __init obsolete_checksetup(char *line) static int __init obsolete_checksetup(char *line)
{ {
struct obs_kernel_param *p; const struct obs_kernel_param *p;
int had_early_param = 0; int had_early_param = 0;
p = __setup_start; p = __setup_start;
@ -458,7 +458,7 @@ static noinline void __init_refok rest_init(void)
/* Check for early params. */ /* Check for early params. */
static int __init do_early_param(char *param, char *val) static int __init do_early_param(char *param, char *val)
{ {
struct obs_kernel_param *p; const struct obs_kernel_param *p;
for (p = __setup_start; p < __setup_end; p++) { for (p = __setup_start; p < __setup_end; p++) {
if ((p->early && strcmp(param, p->str) == 0) || if ((p->early && strcmp(param, p->str) == 0) ||
@ -536,7 +536,7 @@ static void __init mm_init(void)
asmlinkage void __init start_kernel(void) asmlinkage void __init start_kernel(void)
{ {
char * command_line; char * command_line;
extern struct kernel_param __start___param[], __stop___param[]; extern const struct kernel_param __start___param[], __stop___param[];
smp_setup_processor_id(); smp_setup_processor_id();

View File

@ -31,6 +31,42 @@
#define DEBUGP(fmt, a...) #define DEBUGP(fmt, a...)
#endif #endif
/* Protects all parameters, and incidentally kmalloced_param list. */
static DEFINE_MUTEX(param_lock);
/* This just allows us to keep track of which parameters are kmalloced. */
struct kmalloced_param {
struct list_head list;
char val[];
};
static LIST_HEAD(kmalloced_params);
static void *kmalloc_parameter(unsigned int size)
{
struct kmalloced_param *p;
p = kmalloc(sizeof(*p) + size, GFP_KERNEL);
if (!p)
return NULL;
list_add(&p->list, &kmalloced_params);
return p->val;
}
/* Does nothing if parameter wasn't kmalloced above. */
static void maybe_kfree_parameter(void *param)
{
struct kmalloced_param *p;
list_for_each_entry(p, &kmalloced_params, list) {
if (p->val == param) {
list_del(&p->list);
kfree(p);
break;
}
}
}
static inline char dash2underscore(char c) static inline char dash2underscore(char c)
{ {
if (c == '-') if (c == '-')
@ -49,18 +85,25 @@ static inline int parameq(const char *input, const char *paramname)
static int parse_one(char *param, static int parse_one(char *param,
char *val, char *val,
struct kernel_param *params, const struct kernel_param *params,
unsigned num_params, unsigned num_params,
int (*handle_unknown)(char *param, char *val)) int (*handle_unknown)(char *param, char *val))
{ {
unsigned int i; unsigned int i;
int err;
/* Find parameter */ /* Find parameter */
for (i = 0; i < num_params; i++) { for (i = 0; i < num_params; i++) {
if (parameq(param, params[i].name)) { if (parameq(param, params[i].name)) {
/* Noone handled NULL, so do it here. */
if (!val && params[i].ops->set != param_set_bool)
return -EINVAL;
DEBUGP("They are equal! Calling %p\n", DEBUGP("They are equal! Calling %p\n",
params[i].set); params[i].ops->set);
return params[i].set(val, &params[i]); mutex_lock(&param_lock);
err = params[i].ops->set(val, &params[i]);
mutex_unlock(&param_lock);
return err;
} }
} }
@ -128,7 +171,7 @@ static char *next_arg(char *args, char **param, char **val)
/* Args looks like "foo=bar,bar2 baz=fuz wiz". */ /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
int parse_args(const char *name, int parse_args(const char *name,
char *args, char *args,
struct kernel_param *params, const struct kernel_param *params,
unsigned num, unsigned num,
int (*unknown)(char *param, char *val)) int (*unknown)(char *param, char *val))
{ {
@ -176,22 +219,29 @@ int parse_args(const char *name,
/* Lazy bastard, eh? */ /* Lazy bastard, eh? */
#define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \
int param_set_##name(const char *val, struct kernel_param *kp) \ int param_set_##name(const char *val, const struct kernel_param *kp) \
{ \ { \
tmptype l; \ tmptype l; \
int ret; \ int ret; \
\ \
if (!val) return -EINVAL; \
ret = strtolfn(val, 0, &l); \ ret = strtolfn(val, 0, &l); \
if (ret == -EINVAL || ((type)l != l)) \ if (ret == -EINVAL || ((type)l != l)) \
return -EINVAL; \ return -EINVAL; \
*((type *)kp->arg) = l; \ *((type *)kp->arg) = l; \
return 0; \ return 0; \
} \ } \
int param_get_##name(char *buffer, struct kernel_param *kp) \ int param_get_##name(char *buffer, const struct kernel_param *kp) \
{ \ { \
return sprintf(buffer, format, *((type *)kp->arg)); \ return sprintf(buffer, format, *((type *)kp->arg)); \
} } \
struct kernel_param_ops param_ops_##name = { \
.set = param_set_##name, \
.get = param_get_##name, \
}; \
EXPORT_SYMBOL(param_set_##name); \
EXPORT_SYMBOL(param_get_##name); \
EXPORT_SYMBOL(param_ops_##name)
STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul); STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul);
STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol); STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol);
@ -201,39 +251,50 @@ STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, strict_strtoul);
STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol); STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol);
STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul); STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul);
int param_set_charp(const char *val, struct kernel_param *kp) int param_set_charp(const char *val, const struct kernel_param *kp)
{ {
if (!val) {
printk(KERN_ERR "%s: string parameter expected\n",
kp->name);
return -EINVAL;
}
if (strlen(val) > 1024) { if (strlen(val) > 1024) {
printk(KERN_ERR "%s: string parameter too long\n", printk(KERN_ERR "%s: string parameter too long\n",
kp->name); kp->name);
return -ENOSPC; return -ENOSPC;
} }
/* This is a hack. We can't need to strdup in early boot, and we maybe_kfree_parameter(*(char **)kp->arg);
/* This is a hack. We can't kmalloc in early boot, and we
* don't need to; this mangled commandline is preserved. */ * don't need to; this mangled commandline is preserved. */
if (slab_is_available()) { if (slab_is_available()) {
*(char **)kp->arg = kstrdup(val, GFP_KERNEL); *(char **)kp->arg = kmalloc_parameter(strlen(val)+1);
if (!*(char **)kp->arg) if (!*(char **)kp->arg)
return -ENOMEM; return -ENOMEM;
strcpy(*(char **)kp->arg, val);
} else } else
*(const char **)kp->arg = val; *(const char **)kp->arg = val;
return 0; return 0;
} }
EXPORT_SYMBOL(param_set_charp);
int param_get_charp(char *buffer, struct kernel_param *kp) int param_get_charp(char *buffer, const struct kernel_param *kp)
{ {
return sprintf(buffer, "%s", *((char **)kp->arg)); return sprintf(buffer, "%s", *((char **)kp->arg));
} }
EXPORT_SYMBOL(param_get_charp);
static void param_free_charp(void *arg)
{
maybe_kfree_parameter(*((char **)arg));
}
struct kernel_param_ops param_ops_charp = {
.set = param_set_charp,
.get = param_get_charp,
.free = param_free_charp,
};
EXPORT_SYMBOL(param_ops_charp);
/* Actually could be a bool or an int, for historical reasons. */ /* Actually could be a bool or an int, for historical reasons. */
int param_set_bool(const char *val, struct kernel_param *kp) int param_set_bool(const char *val, const struct kernel_param *kp)
{ {
bool v; bool v;
@ -258,8 +319,9 @@ int param_set_bool(const char *val, struct kernel_param *kp)
*(int *)kp->arg = v; *(int *)kp->arg = v;
return 0; return 0;
} }
EXPORT_SYMBOL(param_set_bool);
int param_get_bool(char *buffer, struct kernel_param *kp) int param_get_bool(char *buffer, const struct kernel_param *kp)
{ {
bool val; bool val;
if (kp->flags & KPARAM_ISBOOL) if (kp->flags & KPARAM_ISBOOL)
@ -270,9 +332,16 @@ int param_get_bool(char *buffer, struct kernel_param *kp)
/* Y and N chosen as being relatively non-coder friendly */ /* Y and N chosen as being relatively non-coder friendly */
return sprintf(buffer, "%c", val ? 'Y' : 'N'); return sprintf(buffer, "%c", val ? 'Y' : 'N');
} }
EXPORT_SYMBOL(param_get_bool);
struct kernel_param_ops param_ops_bool = {
.set = param_set_bool,
.get = param_get_bool,
};
EXPORT_SYMBOL(param_ops_bool);
/* This one must be bool. */ /* This one must be bool. */
int param_set_invbool(const char *val, struct kernel_param *kp) int param_set_invbool(const char *val, const struct kernel_param *kp)
{ {
int ret; int ret;
bool boolval; bool boolval;
@ -285,18 +354,26 @@ int param_set_invbool(const char *val, struct kernel_param *kp)
*(bool *)kp->arg = !boolval; *(bool *)kp->arg = !boolval;
return ret; return ret;
} }
EXPORT_SYMBOL(param_set_invbool);
int param_get_invbool(char *buffer, struct kernel_param *kp) int param_get_invbool(char *buffer, const struct kernel_param *kp)
{ {
return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y'); return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y');
} }
EXPORT_SYMBOL(param_get_invbool);
struct kernel_param_ops param_ops_invbool = {
.set = param_set_invbool,
.get = param_get_invbool,
};
EXPORT_SYMBOL(param_ops_invbool);
/* We break the rule and mangle the string. */ /* We break the rule and mangle the string. */
static int param_array(const char *name, static int param_array(const char *name,
const char *val, const char *val,
unsigned int min, unsigned int max, unsigned int min, unsigned int max,
void *elem, int elemsize, void *elem, int elemsize,
int (*set)(const char *, struct kernel_param *kp), int (*set)(const char *, const struct kernel_param *kp),
u16 flags, u16 flags,
unsigned int *num) unsigned int *num)
{ {
@ -309,12 +386,6 @@ static int param_array(const char *name,
kp.arg = elem; kp.arg = elem;
kp.flags = flags; kp.flags = flags;
/* No equals sign? */
if (!val) {
printk(KERN_ERR "%s: expects arguments\n", name);
return -EINVAL;
}
*num = 0; *num = 0;
/* We expect a comma-separated list of values. */ /* We expect a comma-separated list of values. */
do { do {
@ -330,6 +401,7 @@ static int param_array(const char *name,
/* nul-terminate and parse */ /* nul-terminate and parse */
save = val[len]; save = val[len];
((char *)val)[len] = '\0'; ((char *)val)[len] = '\0';
BUG_ON(!mutex_is_locked(&param_lock));
ret = set(val, &kp); ret = set(val, &kp);
if (ret != 0) if (ret != 0)
@ -347,17 +419,17 @@ static int param_array(const char *name,
return 0; return 0;
} }
int param_array_set(const char *val, struct kernel_param *kp) static int param_array_set(const char *val, const struct kernel_param *kp)
{ {
const struct kparam_array *arr = kp->arr; const struct kparam_array *arr = kp->arr;
unsigned int temp_num; unsigned int temp_num;
return param_array(kp->name, val, 1, arr->max, arr->elem, return param_array(kp->name, val, 1, arr->max, arr->elem,
arr->elemsize, arr->set, kp->flags, arr->elemsize, arr->ops->set, kp->flags,
arr->num ?: &temp_num); arr->num ?: &temp_num);
} }
int param_array_get(char *buffer, struct kernel_param *kp) static int param_array_get(char *buffer, const struct kernel_param *kp)
{ {
int i, off, ret; int i, off, ret;
const struct kparam_array *arr = kp->arr; const struct kparam_array *arr = kp->arr;
@ -368,7 +440,8 @@ int param_array_get(char *buffer, struct kernel_param *kp)
if (i) if (i)
buffer[off++] = ','; buffer[off++] = ',';
p.arg = arr->elem + arr->elemsize * i; p.arg = arr->elem + arr->elemsize * i;
ret = arr->get(buffer + off, &p); BUG_ON(!mutex_is_locked(&param_lock));
ret = arr->ops->get(buffer + off, &p);
if (ret < 0) if (ret < 0)
return ret; return ret;
off += ret; off += ret;
@ -377,14 +450,27 @@ int param_array_get(char *buffer, struct kernel_param *kp)
return off; return off;
} }
int param_set_copystring(const char *val, struct kernel_param *kp) static void param_array_free(void *arg)
{
unsigned int i;
const struct kparam_array *arr = arg;
if (arr->ops->free)
for (i = 0; i < (arr->num ? *arr->num : arr->max); i++)
arr->ops->free(arr->elem + arr->elemsize * i);
}
struct kernel_param_ops param_array_ops = {
.set = param_array_set,
.get = param_array_get,
.free = param_array_free,
};
EXPORT_SYMBOL(param_array_ops);
int param_set_copystring(const char *val, const struct kernel_param *kp)
{ {
const struct kparam_string *kps = kp->str; const struct kparam_string *kps = kp->str;
if (!val) {
printk(KERN_ERR "%s: missing param set value\n", kp->name);
return -EINVAL;
}
if (strlen(val)+1 > kps->maxlen) { if (strlen(val)+1 > kps->maxlen) {
printk(KERN_ERR "%s: string doesn't fit in %u chars.\n", printk(KERN_ERR "%s: string doesn't fit in %u chars.\n",
kp->name, kps->maxlen-1); kp->name, kps->maxlen-1);
@ -393,12 +479,20 @@ int param_set_copystring(const char *val, struct kernel_param *kp)
strcpy(kps->string, val); strcpy(kps->string, val);
return 0; return 0;
} }
EXPORT_SYMBOL(param_set_copystring);
int param_get_string(char *buffer, struct kernel_param *kp) int param_get_string(char *buffer, const struct kernel_param *kp)
{ {
const struct kparam_string *kps = kp->str; const struct kparam_string *kps = kp->str;
return strlcpy(buffer, kps->string, kps->maxlen); return strlcpy(buffer, kps->string, kps->maxlen);
} }
EXPORT_SYMBOL(param_get_string);
struct kernel_param_ops param_ops_string = {
.set = param_set_copystring,
.get = param_get_string,
};
EXPORT_SYMBOL(param_ops_string);
/* sysfs output in /sys/modules/XYZ/parameters/ */ /* sysfs output in /sys/modules/XYZ/parameters/ */
#define to_module_attr(n) container_of(n, struct module_attribute, attr) #define to_module_attr(n) container_of(n, struct module_attribute, attr)
@ -409,7 +503,7 @@ extern struct kernel_param __start___param[], __stop___param[];
struct param_attribute struct param_attribute
{ {
struct module_attribute mattr; struct module_attribute mattr;
struct kernel_param *param; const struct kernel_param *param;
}; };
struct module_param_attrs struct module_param_attrs
@ -428,10 +522,12 @@ static ssize_t param_attr_show(struct module_attribute *mattr,
int count; int count;
struct param_attribute *attribute = to_param_attr(mattr); struct param_attribute *attribute = to_param_attr(mattr);
if (!attribute->param->get) if (!attribute->param->ops->get)
return -EPERM; return -EPERM;
count = attribute->param->get(buf, attribute->param); mutex_lock(&param_lock);
count = attribute->param->ops->get(buf, attribute->param);
mutex_unlock(&param_lock);
if (count > 0) { if (count > 0) {
strcat(buf, "\n"); strcat(buf, "\n");
++count; ++count;
@ -447,10 +543,12 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
int err; int err;
struct param_attribute *attribute = to_param_attr(mattr); struct param_attribute *attribute = to_param_attr(mattr);
if (!attribute->param->set) if (!attribute->param->ops->set)
return -EPERM; return -EPERM;
err = attribute->param->set(buf, attribute->param); mutex_lock(&param_lock);
err = attribute->param->ops->set(buf, attribute->param);
mutex_unlock(&param_lock);
if (!err) if (!err)
return len; return len;
return err; return err;
@ -464,6 +562,18 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
#endif #endif
#ifdef CONFIG_SYSFS #ifdef CONFIG_SYSFS
void __kernel_param_lock(void)
{
mutex_lock(&param_lock);
}
EXPORT_SYMBOL(__kernel_param_lock);
void __kernel_param_unlock(void)
{
mutex_unlock(&param_lock);
}
EXPORT_SYMBOL(__kernel_param_unlock);
/* /*
* add_sysfs_param - add a parameter to sysfs * add_sysfs_param - add a parameter to sysfs
* @mk: struct module_kobject * @mk: struct module_kobject
@ -475,7 +585,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
* if there's an error. * if there's an error.
*/ */
static __modinit int add_sysfs_param(struct module_kobject *mk, static __modinit int add_sysfs_param(struct module_kobject *mk,
struct kernel_param *kp, const struct kernel_param *kp,
const char *name) const char *name)
{ {
struct module_param_attrs *new; struct module_param_attrs *new;
@ -557,7 +667,7 @@ static void free_module_param_attrs(struct module_kobject *mk)
* /sys/module/[mod->name]/parameters/ * /sys/module/[mod->name]/parameters/
*/ */
int module_param_sysfs_setup(struct module *mod, int module_param_sysfs_setup(struct module *mod,
struct kernel_param *kparam, const struct kernel_param *kparam,
unsigned int num_params) unsigned int num_params)
{ {
int i, err; int i, err;
@ -602,7 +712,11 @@ void module_param_sysfs_remove(struct module *mod)
void destroy_params(const struct kernel_param *params, unsigned num) void destroy_params(const struct kernel_param *params, unsigned num)
{ {
/* FIXME: This should free kmalloced charp parameters. It doesn't. */ unsigned int i;
for (i = 0; i < num; i++)
if (params[i].ops->free)
params[i].ops->free(params[i].arg);
} }
static void __init kernel_add_sysfs_param(const char *name, static void __init kernel_add_sysfs_param(const char *name,
@ -768,28 +882,3 @@ static int __init param_sysfs_init(void)
subsys_initcall(param_sysfs_init); subsys_initcall(param_sysfs_init);
#endif /* CONFIG_SYSFS */ #endif /* CONFIG_SYSFS */
EXPORT_SYMBOL(param_set_byte);
EXPORT_SYMBOL(param_get_byte);
EXPORT_SYMBOL(param_set_short);
EXPORT_SYMBOL(param_get_short);
EXPORT_SYMBOL(param_set_ushort);
EXPORT_SYMBOL(param_get_ushort);
EXPORT_SYMBOL(param_set_int);
EXPORT_SYMBOL(param_get_int);
EXPORT_SYMBOL(param_set_uint);
EXPORT_SYMBOL(param_get_uint);
EXPORT_SYMBOL(param_set_long);
EXPORT_SYMBOL(param_get_long);
EXPORT_SYMBOL(param_set_ulong);
EXPORT_SYMBOL(param_get_ulong);
EXPORT_SYMBOL(param_set_charp);
EXPORT_SYMBOL(param_get_charp);
EXPORT_SYMBOL(param_set_bool);
EXPORT_SYMBOL(param_get_bool);
EXPORT_SYMBOL(param_set_invbool);
EXPORT_SYMBOL(param_get_invbool);
EXPORT_SYMBOL(param_array_set);
EXPORT_SYMBOL(param_array_get);
EXPORT_SYMBOL(param_set_copystring);
EXPORT_SYMBOL(param_get_string);

View File

@ -103,6 +103,7 @@ ieee80211_rate_control_ops_get(const char *name)
struct rate_control_ops *ops; struct rate_control_ops *ops;
const char *alg_name; const char *alg_name;
kparam_block_sysfs_write(ieee80211_default_rc_algo);
if (!name) if (!name)
alg_name = ieee80211_default_rc_algo; alg_name = ieee80211_default_rc_algo;
else else
@ -120,6 +121,7 @@ ieee80211_rate_control_ops_get(const char *name)
/* try built-in one if specific alg requested but not found */ /* try built-in one if specific alg requested but not found */
if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT)) if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT))
ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT); ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT);
kparam_unblock_sysfs_write(ieee80211_default_rc_algo);
return ops; return ops;
} }

View File

@ -39,7 +39,7 @@ static LIST_HEAD(cred_unused);
static unsigned long number_cred_unused; static unsigned long number_cred_unused;
#define MAX_HASHTABLE_BITS (10) #define MAX_HASHTABLE_BITS (10)
static int param_set_hashtbl_sz(const char *val, struct kernel_param *kp) static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp)
{ {
unsigned long num; unsigned long num;
unsigned int nbits; unsigned int nbits;
@ -61,7 +61,7 @@ static int param_set_hashtbl_sz(const char *val, struct kernel_param *kp)
return -EINVAL; return -EINVAL;
} }
static int param_get_hashtbl_sz(char *buffer, struct kernel_param *kp) static int param_get_hashtbl_sz(char *buffer, const struct kernel_param *kp)
{ {
unsigned int nbits; unsigned int nbits;
@ -71,6 +71,11 @@ static int param_get_hashtbl_sz(char *buffer, struct kernel_param *kp)
#define param_check_hashtbl_sz(name, p) __param_check(name, p, unsigned int); #define param_check_hashtbl_sz(name, p) __param_check(name, p, unsigned int);
static struct kernel_param_ops param_ops_hashtbl_sz = {
.set = param_set_hashtbl_sz,
.get = param_get_hashtbl_sz,
};
module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644); module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644);
MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size"); MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size");

View File

@ -2577,7 +2577,8 @@ void cleanup_socket_xprt(void)
xprt_unregister_transport(&xs_bc_tcp_transport); xprt_unregister_transport(&xs_bc_tcp_transport);
} }
static int param_set_uint_minmax(const char *val, struct kernel_param *kp, static int param_set_uint_minmax(const char *val,
const struct kernel_param *kp,
unsigned int min, unsigned int max) unsigned int min, unsigned int max)
{ {
unsigned long num; unsigned long num;
@ -2592,34 +2593,37 @@ static int param_set_uint_minmax(const char *val, struct kernel_param *kp,
return 0; return 0;
} }
static int param_set_portnr(const char *val, struct kernel_param *kp) static int param_set_portnr(const char *val, const struct kernel_param *kp)
{ {
return param_set_uint_minmax(val, kp, return param_set_uint_minmax(val, kp,
RPC_MIN_RESVPORT, RPC_MIN_RESVPORT,
RPC_MAX_RESVPORT); RPC_MAX_RESVPORT);
} }
static int param_get_portnr(char *buffer, struct kernel_param *kp) static struct kernel_param_ops param_ops_portnr = {
{ .set = param_set_portnr,
return param_get_uint(buffer, kp); .get = param_get_uint,
} };
#define param_check_portnr(name, p) \ #define param_check_portnr(name, p) \
__param_check(name, p, unsigned int); __param_check(name, p, unsigned int);
module_param_named(min_resvport, xprt_min_resvport, portnr, 0644); module_param_named(min_resvport, xprt_min_resvport, portnr, 0644);
module_param_named(max_resvport, xprt_max_resvport, portnr, 0644); module_param_named(max_resvport, xprt_max_resvport, portnr, 0644);
static int param_set_slot_table_size(const char *val, struct kernel_param *kp) static int param_set_slot_table_size(const char *val,
const struct kernel_param *kp)
{ {
return param_set_uint_minmax(val, kp, return param_set_uint_minmax(val, kp,
RPC_MIN_SLOT_TABLE, RPC_MIN_SLOT_TABLE,
RPC_MAX_SLOT_TABLE); RPC_MAX_SLOT_TABLE);
} }
static int param_get_slot_table_size(char *buffer, struct kernel_param *kp) static struct kernel_param_ops param_ops_slot_table_size = {
{ .set = param_set_slot_table_size,
return param_get_uint(buffer, kp); .get = param_get_uint,
} };
#define param_check_slot_table_size(name, p) \ #define param_check_slot_table_size(name, p) \
__param_check(name, p, unsigned int); __param_check(name, p, unsigned int);

View File

@ -1035,6 +1035,13 @@ static const struct sectioncheck *section_mismatch(
* fromsec = .data* * fromsec = .data*
* atsym =__param* * atsym =__param*
* *
* Pattern 1a:
* module_param_call() ops can refer to __init set function if permissions=0
* The pattern is identified by:
* tosec = .init.text
* fromsec = .data*
* atsym = __param_ops_*
*
* Pattern 2: * Pattern 2:
* Many drivers utilise a *driver container with references to * Many drivers utilise a *driver container with references to
* add, remove, probe functions etc. * add, remove, probe functions etc.
@ -1069,6 +1076,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch,
(strncmp(fromsym, "__param", strlen("__param")) == 0)) (strncmp(fromsym, "__param", strlen("__param")) == 0))
return 0; return 0;
/* Check for pattern 1a */
if (strcmp(tosec, ".init.text") == 0 &&
match(fromsec, data_sections) &&
(strncmp(fromsym, "__param_ops_", strlen("__param_ops_")) == 0))
return 0;
/* Check for pattern 2 */ /* Check for pattern 2 */
if (match(tosec, init_exit_sections) && if (match(tosec, init_exit_sections) &&
match(fromsec, data_sections) && match(fromsec, data_sections) &&

View File

@ -667,17 +667,29 @@ static struct security_operations apparmor_ops = {
* AppArmor sysfs module parameters * AppArmor sysfs module parameters
*/ */
static int param_set_aabool(const char *val, struct kernel_param *kp); static int param_set_aabool(const char *val, const struct kernel_param *kp);
static int param_get_aabool(char *buffer, struct kernel_param *kp); static int param_get_aabool(char *buffer, const struct kernel_param *kp);
#define param_check_aabool(name, p) __param_check(name, p, int) #define param_check_aabool(name, p) __param_check(name, p, int)
static struct kernel_param_ops param_ops_aabool = {
.set = param_set_aabool,
.get = param_get_aabool
};
static int param_set_aauint(const char *val, struct kernel_param *kp); static int param_set_aauint(const char *val, const struct kernel_param *kp);
static int param_get_aauint(char *buffer, struct kernel_param *kp); static int param_get_aauint(char *buffer, const struct kernel_param *kp);
#define param_check_aauint(name, p) __param_check(name, p, int) #define param_check_aauint(name, p) __param_check(name, p, int)
static struct kernel_param_ops param_ops_aauint = {
.set = param_set_aauint,
.get = param_get_aauint
};
static int param_set_aalockpolicy(const char *val, struct kernel_param *kp); static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp);
static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp); static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp);
#define param_check_aalockpolicy(name, p) __param_check(name, p, int) #define param_check_aalockpolicy(name, p) __param_check(name, p, int)
static struct kernel_param_ops param_ops_aalockpolicy = {
.set = param_set_aalockpolicy,
.get = param_get_aalockpolicy
};
static int param_set_audit(const char *val, struct kernel_param *kp); static int param_set_audit(const char *val, struct kernel_param *kp);
static int param_get_audit(char *buffer, struct kernel_param *kp); static int param_get_audit(char *buffer, struct kernel_param *kp);
@ -751,7 +763,7 @@ static int __init apparmor_enabled_setup(char *str)
__setup("apparmor=", apparmor_enabled_setup); __setup("apparmor=", apparmor_enabled_setup);
/* set global flag turning off the ability to load policy */ /* set global flag turning off the ability to load policy */
static int param_set_aalockpolicy(const char *val, struct kernel_param *kp) static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp)
{ {
if (!capable(CAP_MAC_ADMIN)) if (!capable(CAP_MAC_ADMIN))
return -EPERM; return -EPERM;
@ -760,35 +772,35 @@ static int param_set_aalockpolicy(const char *val, struct kernel_param *kp)
return param_set_bool(val, kp); return param_set_bool(val, kp);
} }
static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp) static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp)
{ {
if (!capable(CAP_MAC_ADMIN)) if (!capable(CAP_MAC_ADMIN))
return -EPERM; return -EPERM;
return param_get_bool(buffer, kp); return param_get_bool(buffer, kp);
} }
static int param_set_aabool(const char *val, struct kernel_param *kp) static int param_set_aabool(const char *val, const struct kernel_param *kp)
{ {
if (!capable(CAP_MAC_ADMIN)) if (!capable(CAP_MAC_ADMIN))
return -EPERM; return -EPERM;
return param_set_bool(val, kp); return param_set_bool(val, kp);
} }
static int param_get_aabool(char *buffer, struct kernel_param *kp) static int param_get_aabool(char *buffer, const struct kernel_param *kp)
{ {
if (!capable(CAP_MAC_ADMIN)) if (!capable(CAP_MAC_ADMIN))
return -EPERM; return -EPERM;
return param_get_bool(buffer, kp); return param_get_bool(buffer, kp);
} }
static int param_set_aauint(const char *val, struct kernel_param *kp) static int param_set_aauint(const char *val, const struct kernel_param *kp)
{ {
if (!capable(CAP_MAC_ADMIN)) if (!capable(CAP_MAC_ADMIN))
return -EPERM; return -EPERM;
return param_set_uint(val, kp); return param_set_uint(val, kp);
} }
static int param_get_aauint(char *buffer, struct kernel_param *kp) static int param_get_aauint(char *buffer, const struct kernel_param *kp)
{ {
if (!capable(CAP_MAC_ADMIN)) if (!capable(CAP_MAC_ADMIN))
return -EPERM; return -EPERM;