diff options
author | John David Anglin <danglin@gcc.gnu.org> | 2022-01-02 17:13:45 +0000 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2022-01-02 17:13:45 +0000 |
commit | 2c8e273ed11c31fc28784ddd0a8263080f43ba7b (patch) | |
tree | b2df0d62715f6caa491b8483c9638dc789463553 /libgcc | |
parent | 21a0bd00f62af9dec87a10ec512aacf1db08e70f (diff) |
Generate illegal instruction fault if LWS syscall returns -EFAULT.
2022-01-02 John David Anglin <danglin@gcc.gnu.org>
libgcc/ChangeLog:
* config/pa/linux-atomic.c (_ASM_EFAULT): Define.
(__kernel_cmpxchg): Nullify illegal iitlbp instruction if error
return is not equal _ASM_EFAULT.
(__kernel_cmpxchg2): Likewise.
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/config/pa/linux-atomic.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/libgcc/config/pa/linux-atomic.c b/libgcc/config/pa/linux-atomic.c index 500a3652499..e4d74b2d598 100644 --- a/libgcc/config/pa/linux-atomic.c +++ b/libgcc/config/pa/linux-atomic.c @@ -28,6 +28,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define EBUSY 16 #define ENOSYS 251 +#define _ASM_EFAULT "-14" + typedef unsigned char u8; typedef short unsigned int u16; #ifdef __LP64__ @@ -58,6 +60,8 @@ __kernel_cmpxchg (volatile void *mem, int oldval, int newval) register long lws_errno asm("r21"); asm volatile ( "ble 0xb0(%%sr2, %%r0) \n\t" "ldi %2, %%r20 \n\t" + "cmpiclr,<> " _ASM_EFAULT ", %%r21, %%r0\n\t" + "iitlbp %%r0,(%%sr0, %%r0) \n\t" : "=r" (lws_ret), "=r" (lws_errno) : "i" (LWS_CAS), "r" (lws_mem), "r" (lws_old), "r" (lws_new) : "r1", "r20", "r22", "r23", "r29", "r31", "memory" @@ -84,6 +88,8 @@ __kernel_cmpxchg2 (volatile void *mem, const void *oldval, const void *newval, register long lws_errno asm("r21"); asm volatile ( "ble 0xb0(%%sr2, %%r0) \n\t" "ldi %6, %%r20 \n\t" + "cmpiclr,<> " _ASM_EFAULT ", %%r21, %%r0\n\t" + "iitlbp %%r0,(%%sr0, %%r0) \n\t" : "=r" (lws_ret), "=r" (lws_errno), "+r" (lws_mem), "+r" (lws_old), "+r" (lws_new), "+r" (lws_size) : "i" (2) |