diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2014-07-31 14:40:57 -0400 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2014-08-14 03:59:31 -0400 |
commit | d1b6ba82a50cecf94be540a3a153aa89d97511a0 (patch) | |
tree | 4e77c4cc78304f8253bd56da69bada62b08e8717 | |
parent | a83b02e9bd0c28d27b6c6e5b184585f7a1b8bf86 (diff) |
xtensa: fix a6 and a7 handling in fast_syscall_xtensa
Remove restoring a6 on some return paths and instead modify and restore
it in a single place, using symbolic name.
Correctly restore a7 from PT_AREG7 in case of illegal a6 value.
Cc: stable@vger.kernel.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
-rw-r--r-- | arch/xtensa/kernel/entry.S | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 21917e5fd53a..a06b7efaae82 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
@@ -1001,9 +1001,8 @@ ENTRY(fast_syscall_xtensa) | |||
1001 | movi a7, 4 # sizeof(unsigned int) | 1001 | movi a7, 4 # sizeof(unsigned int) |
1002 | access_ok a3, a7, a0, a2, .Leac # a0: scratch reg, a2: sp | 1002 | access_ok a3, a7, a0, a2, .Leac # a0: scratch reg, a2: sp |
1003 | 1003 | ||
1004 | addi a6, a6, -1 # assuming SYS_XTENSA_ATOMIC_SET = 1 | 1004 | _bgeui a6, SYS_XTENSA_COUNT, .Lill |
1005 | _bgeui a6, SYS_XTENSA_COUNT - 1, .Lill | 1005 | _bnei a6, SYS_XTENSA_ATOMIC_CMP_SWP, .Lnswp |
1006 | _bnei a6, SYS_XTENSA_ATOMIC_CMP_SWP - 1, .Lnswp | ||
1007 | 1006 | ||
1008 | /* Fall through for ATOMIC_CMP_SWP. */ | 1007 | /* Fall through for ATOMIC_CMP_SWP. */ |
1009 | 1008 | ||
@@ -1015,27 +1014,26 @@ TRY s32i a5, a3, 0 # different, modify value | |||
1015 | l32i a7, a2, PT_AREG7 # restore a7 | 1014 | l32i a7, a2, PT_AREG7 # restore a7 |
1016 | l32i a0, a2, PT_AREG0 # restore a0 | 1015 | l32i a0, a2, PT_AREG0 # restore a0 |
1017 | movi a2, 1 # and return 1 | 1016 | movi a2, 1 # and return 1 |
1018 | addi a6, a6, 1 # restore a6 (really necessary?) | ||
1019 | rfe | 1017 | rfe |
1020 | 1018 | ||
1021 | 1: l32i a7, a2, PT_AREG7 # restore a7 | 1019 | 1: l32i a7, a2, PT_AREG7 # restore a7 |
1022 | l32i a0, a2, PT_AREG0 # restore a0 | 1020 | l32i a0, a2, PT_AREG0 # restore a0 |
1023 | movi a2, 0 # return 0 (note that we cannot set | 1021 | movi a2, 0 # return 0 (note that we cannot set |
1024 | addi a6, a6, 1 # restore a6 (really necessary?) | ||
1025 | rfe | 1022 | rfe |
1026 | 1023 | ||
1027 | .Lnswp: /* Atomic set, add, and exg_add. */ | 1024 | .Lnswp: /* Atomic set, add, and exg_add. */ |
1028 | 1025 | ||
1029 | TRY l32i a7, a3, 0 # orig | 1026 | TRY l32i a7, a3, 0 # orig |
1027 | addi a6, a6, -SYS_XTENSA_ATOMIC_SET | ||
1030 | add a0, a4, a7 # + arg | 1028 | add a0, a4, a7 # + arg |
1031 | moveqz a0, a4, a6 # set | 1029 | moveqz a0, a4, a6 # set |
1030 | addi a6, a6, SYS_XTENSA_ATOMIC_SET | ||
1032 | TRY s32i a0, a3, 0 # write new value | 1031 | TRY s32i a0, a3, 0 # write new value |
1033 | 1032 | ||
1034 | mov a0, a2 | 1033 | mov a0, a2 |
1035 | mov a2, a7 | 1034 | mov a2, a7 |
1036 | l32i a7, a0, PT_AREG7 # restore a7 | 1035 | l32i a7, a0, PT_AREG7 # restore a7 |
1037 | l32i a0, a0, PT_AREG0 # restore a0 | 1036 | l32i a0, a0, PT_AREG0 # restore a0 |
1038 | addi a6, a6, 1 # restore a6 (really necessary?) | ||
1039 | rfe | 1037 | rfe |
1040 | 1038 | ||
1041 | CATCH | 1039 | CATCH |
@@ -1044,7 +1042,7 @@ CATCH | |||
1044 | movi a2, -EFAULT | 1042 | movi a2, -EFAULT |
1045 | rfe | 1043 | rfe |
1046 | 1044 | ||
1047 | .Lill: l32i a7, a2, PT_AREG0 # restore a7 | 1045 | .Lill: l32i a7, a2, PT_AREG7 # restore a7 |
1048 | l32i a0, a2, PT_AREG0 # restore a0 | 1046 | l32i a0, a2, PT_AREG0 # restore a0 |
1049 | movi a2, -EINVAL | 1047 | movi a2, -EINVAL |
1050 | rfe | 1048 | rfe |