diff options
author | Joel Stanley <joel@jms.id.au> | 2014-04-24 03:25:33 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-04-27 23:08:47 -0400 |
commit | ba9a32b176c31ec4d3d7314bb2e529a85423f7a4 (patch) | |
tree | 850f591bebcd208090d2db64329cd551c958f538 /arch/powerpc | |
parent | 4fb8d027dca0236c811272d342cf185569d91311 (diff) |
powerpc/powernv: Fix sysparam sysfs error handling
When a sysparam query in OPAL returned a negative value (error code),
sysfs would spew out a decent chunk of memory; almost 64K more than
expected. This was traced to a sign/unsigned mix up in the OPAL sysparam
sysfs code at sys_param_show.
The return value of sys_param_show is a ssize_t, calculated using
return ret ? ret : attr->param_size;
Alan Modra explains:
"attr->param_size" is an unsigned int, "ret" an int, so the overall
expression has type unsigned int. Result is that ret is cast to
unsigned int before being cast to ssize_t.
Instead of using the ternary operator, set ret to the param_size if an
error is not detected. The same bug exists in the sysfs write callback;
this patch fixes it in the same way.
A note on debugging this next time: on my system gcc will warn about
this if compiled with -Wsign-compare, which is not enabled by -Wall,
only -Wextra.
Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-sysparam.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c index 6b614726baf2..a51ea189aec3 100644 --- a/arch/powerpc/platforms/powernv/opal-sysparam.c +++ b/arch/powerpc/platforms/powernv/opal-sysparam.c | |||
@@ -121,9 +121,10 @@ static ssize_t sys_param_show(struct kobject *kobj, | |||
121 | 121 | ||
122 | memcpy(buf, param_data_buf, attr->param_size); | 122 | memcpy(buf, param_data_buf, attr->param_size); |
123 | 123 | ||
124 | ret = attr->param_size; | ||
124 | out: | 125 | out: |
125 | mutex_unlock(&opal_sysparam_mutex); | 126 | mutex_unlock(&opal_sysparam_mutex); |
126 | return ret ? ret : attr->param_size; | 127 | return ret; |
127 | } | 128 | } |
128 | 129 | ||
129 | static ssize_t sys_param_store(struct kobject *kobj, | 130 | static ssize_t sys_param_store(struct kobject *kobj, |
@@ -138,7 +139,9 @@ static ssize_t sys_param_store(struct kobject *kobj, | |||
138 | ret = opal_set_sys_param(attr->param_id, attr->param_size, | 139 | ret = opal_set_sys_param(attr->param_id, attr->param_size, |
139 | param_data_buf); | 140 | param_data_buf); |
140 | mutex_unlock(&opal_sysparam_mutex); | 141 | mutex_unlock(&opal_sysparam_mutex); |
141 | return ret ? ret : count; | 142 | if (!ret) |
143 | ret = count; | ||
144 | return ret; | ||
142 | } | 145 | } |
143 | 146 | ||
144 | void __init opal_sys_param_init(void) | 147 | void __init opal_sys_param_init(void) |