diff options
Diffstat (limited to 'arch/parisc/kernel/syscall.S')
| -rw-r--r-- | arch/parisc/kernel/syscall.S | 18 | 
1 files changed, 11 insertions, 7 deletions
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index e767ab733e3..83878601103 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -589,10 +589,13 @@ cas_nocontend:  # endif  /* ENABLE_LWS_DEBUG */ +	rsm	PSW_SM_I, %r0				/* Disable interrupts */ +	/* COW breaks can cause contention on UP systems */  	LDCW	0(%sr2,%r20), %r28			/* Try to acquire the lock */  	cmpb,<>,n	%r0, %r28, cas_action		/* Did we get it? */  cas_wouldblock:  	ldo	2(%r0), %r28				/* 2nd case */ +	ssm	PSW_SM_I, %r0  	b	lws_exit				/* Contended... */  	ldo	-EAGAIN(%r0), %r21			/* Spin in userspace */ @@ -619,15 +622,17 @@ cas_action:  	stw	%r1, 4(%sr2,%r20)  #endif  	/* The load and store could fail */ -1:	ldw	0(%sr3,%r26), %r28 +1:	ldw,ma	0(%sr3,%r26), %r28  	sub,<>	%r28, %r25, %r0 -2:	stw	%r24, 0(%sr3,%r26) +2:	stw,ma	%r24, 0(%sr3,%r26)  	/* Free lock */ -	stw	%r20, 0(%sr2,%r20) +	stw,ma	%r20, 0(%sr2,%r20)  #if ENABLE_LWS_DEBUG  	/* Clear thread register indicator */  	stw	%r0, 4(%sr2,%r20)  #endif +	/* Enable interrupts */ +	ssm	PSW_SM_I, %r0  	/* Return to userspace, set no error */  	b	lws_exit  	copy	%r0, %r21 @@ -639,6 +644,7 @@ cas_action:  #if ENABLE_LWS_DEBUG  	stw	%r0, 4(%sr2,%r20)  #endif +	ssm	PSW_SM_I, %r0  	b	lws_exit  	ldo	-EFAULT(%r0),%r21	/* set errno */  	nop @@ -649,10 +655,8 @@ cas_action:  	/* Two exception table entries, one for the load,  	   the other for the store. Either return -EFAULT.  	   Each of the entries must be relocated. */ -	.section __ex_table,"aw" -	ASM_ULONG_INSN (1b - linux_gateway_page), (3b - linux_gateway_page) -	ASM_ULONG_INSN (2b - linux_gateway_page), (3b - linux_gateway_page) -	.previous +	ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 3b-linux_gateway_page) +	ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 3b-linux_gateway_page)  	/* Make sure nothing else is placed on this page */  | 
