diff options
| author | Helge Deller <deller@gmx.de> | 2017-03-25 06:59:15 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-04-08 03:30:34 -0400 |
| commit | 09b931fcb87c8aad178475a7db1d4bfc939f7faa (patch) | |
| tree | 077051ef17e98a0655d3690508c30dda5ec30974 /arch/parisc/kernel | |
| parent | 3967cf7e6a9180e09b42ecc154731a570efafa49 (diff) | |
parisc: Clean up fixup routines for get_user()/put_user()
commit d19f5e41b344a057bb2450024a807476f30978d2 upstream.
Al Viro noticed that userspace accesses via get_user()/put_user() can be
simplified a lot with regard to usage of the exception handling.
This patch implements a fixup routine for get_user() and put_user() in such
that the exception handler will automatically load -EFAULT into the register
%r8 (the error value) in case on a fault on userspace. Additionally the fixup
routine will zero the target register on fault in case of a get_user() call.
The target register is extracted out of the faulting assembly instruction.
This patch brings a few benefits over the old implementation:
1. Exception handling gets much cleaner, easier and smaller in size.
2. Helper functions like fixup_get_user_skip_1 (all of fixup.S) can be dropped.
3. No need to hardcode %r9 as target register for get_user() any longer. This
helps the compiler register allocator and thus creates less assembler
statements.
4. No dependency on the exception_data contents any longer.
5. Nested faults will be handled cleanly.
Reported-by: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/parisc/kernel')
| -rw-r--r-- | arch/parisc/kernel/parisc_ksyms.c | 10 |
1 files changed, 0 insertions, 10 deletions
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 3cad8aadc69e..4e6f0d93154f 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c | |||
| @@ -47,16 +47,6 @@ EXPORT_SYMBOL(__cmpxchg_u64); | |||
| 47 | EXPORT_SYMBOL(lclear_user); | 47 | EXPORT_SYMBOL(lclear_user); |
| 48 | EXPORT_SYMBOL(lstrnlen_user); | 48 | EXPORT_SYMBOL(lstrnlen_user); |
| 49 | 49 | ||
| 50 | /* Global fixups - defined as int to avoid creation of function pointers */ | ||
| 51 | extern int fixup_get_user_skip_1; | ||
| 52 | extern int fixup_get_user_skip_2; | ||
| 53 | extern int fixup_put_user_skip_1; | ||
| 54 | extern int fixup_put_user_skip_2; | ||
| 55 | EXPORT_SYMBOL(fixup_get_user_skip_1); | ||
| 56 | EXPORT_SYMBOL(fixup_get_user_skip_2); | ||
| 57 | EXPORT_SYMBOL(fixup_put_user_skip_1); | ||
| 58 | EXPORT_SYMBOL(fixup_put_user_skip_2); | ||
| 59 | |||
| 60 | #ifndef CONFIG_64BIT | 50 | #ifndef CONFIG_64BIT |
| 61 | /* Needed so insmod can set dp value */ | 51 | /* Needed so insmod can set dp value */ |
| 62 | extern int $global$; | 52 | extern int $global$; |
