Skip to content

Commit dbd0b42

Browse files
committed
parisc: Fix some apparent put_user() failures
After commit 4b9d2a7 ("parisc: Switch user access functions to signal errors in r29 instead of r8") bash suddenly started to report those warnings after login: -bash: cannot set terminal process group (-1): Bad file descriptor -bash: no job control in this shell It turned out, that a function call inside a put_user(), e.g.: put_user(vt_do_kdgkbmode(console), (int __user *)arg); clobbered the error register (r29) and thus the put_user() call itself seem to have failed. Rearrange the C-code to pre-calculate the intermediate value and then do the put_user(). Additionally prefer the "+" constraint on pu_err and gu_err registers to tell the compiler that those operands are both read and written by the assembly instruction. Reported-by: John David Anglin <[email protected]> Signed-off-by: Helge Deller <[email protected]> Fixes: 4b9d2a7 ("parisc: Switch user access functions to signal errors in r29 instead of r8") Signed-off-by: Helge Deller <[email protected]>
1 parent b160628 commit dbd0b42

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

arch/parisc/include/asm/uaccess.h

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ struct exception_table_entry {
8989
__asm__("1: " ldx " 0(" sr "%2),%0\n" \
9090
"9:\n" \
9191
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
92-
: "=r"(__gu_val), "=r"(__gu_err) \
93-
: "r"(ptr), "1"(__gu_err)); \
92+
: "=r"(__gu_val), "+r"(__gu_err) \
93+
: "r"(ptr)); \
9494
\
9595
(val) = (__force __typeof__(*(ptr))) __gu_val; \
9696
}
@@ -123,8 +123,8 @@ struct exception_table_entry {
123123
"9:\n" \
124124
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
125125
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \
126-
: "=&r"(__gu_tmp.l), "=r"(__gu_err) \
127-
: "r"(ptr), "1"(__gu_err)); \
126+
: "=&r"(__gu_tmp.l), "+r"(__gu_err) \
127+
: "r"(ptr)); \
128128
\
129129
(val) = __gu_tmp.t; \
130130
}
@@ -135,13 +135,12 @@ struct exception_table_entry {
135135
#define __put_user_internal(sr, x, ptr) \
136136
({ \
137137
ASM_EXCEPTIONTABLE_VAR(__pu_err); \
138-
__typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x); \
139138
\
140139
switch (sizeof(*(ptr))) { \
141-
case 1: __put_user_asm(sr, "stb", __x, ptr); break; \
142-
case 2: __put_user_asm(sr, "sth", __x, ptr); break; \
143-
case 4: __put_user_asm(sr, "stw", __x, ptr); break; \
144-
case 8: STD_USER(sr, __x, ptr); break; \
140+
case 1: __put_user_asm(sr, "stb", x, ptr); break; \
141+
case 2: __put_user_asm(sr, "sth", x, ptr); break; \
142+
case 4: __put_user_asm(sr, "stw", x, ptr); break; \
143+
case 8: STD_USER(sr, x, ptr); break; \
145144
default: BUILD_BUG(); \
146145
} \
147146
\
@@ -150,7 +149,9 @@ struct exception_table_entry {
150149

151150
#define __put_user(x, ptr) \
152151
({ \
153-
__put_user_internal("%%sr3,", x, ptr); \
152+
__typeof__(&*(ptr)) __ptr = ptr; \
153+
__typeof__(*(__ptr)) __x = (__typeof__(*(__ptr)))(x); \
154+
__put_user_internal("%%sr3,", __x, __ptr); \
154155
})
155156

156157
#define __put_kernel_nofault(dst, src, type, err_label) \
@@ -180,8 +181,8 @@ struct exception_table_entry {
180181
"1: " stx " %2,0(" sr "%1)\n" \
181182
"9:\n" \
182183
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
183-
: "=r"(__pu_err) \
184-
: "r"(ptr), "r"(x), "0"(__pu_err))
184+
: "+r"(__pu_err) \
185+
: "r"(ptr), "r"(x))
185186

186187

187188
#if !defined(CONFIG_64BIT)
@@ -193,8 +194,8 @@ struct exception_table_entry {
193194
"9:\n" \
194195
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
195196
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \
196-
: "=r"(__pu_err) \
197-
: "r"(ptr), "r"(__val), "0"(__pu_err)); \
197+
: "+r"(__pu_err) \
198+
: "r"(ptr), "r"(__val)); \
198199
} while (0)
199200

200201
#endif /* !defined(CONFIG_64BIT) */

0 commit comments

Comments
 (0)