• Nicolas Pitre's avatar
    [ARM] 4659/1: remove possibilities for spurious false negative with __kuser_cmpxchg · b49c0f24
    Nicolas Pitre authored
    The ARM __kuser_cmpxchg routine is meant to implement an atomic cmpxchg
    in user space.  It however can produce spurious false negative if a
    processor exception occurs in the middle of the operation.  Normally
    this is not a problem since cmpxchg is typically called in a loop until
    it succeeds to implement an atomic increment for example.
    
    Some use cases which don't involve a loop require that the operation be
    100% reliable though.  This patch changes the implementation so to
    reattempt the operation after an exception has occurred in the critical
    section rather than abort it.
    
    Here's a simple program to test the fix (don't use CONFIG_NO_HZ in your
    kernel as this depends on a sufficiently high interrupt rate):
    
    	#include <stdio.h>
    
    	typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
    	#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
    
    	int main()
    	{
    		int i, x = 0;
    		for (i = 0; i < 100000000; i++) {
    			int v = x;
    			if (__kernel_cmpxchg(v, v+1, &x))
    				printf("failed at %d: %d vs %d\n", i, v, x);
    		}
    		printf("done with %d vs %d\n", i, x);
    		return 0;
    	}
    Signed-off-by: default avatarNicolas Pitre <nico@marvell.com>
    Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
    b49c0f24
traps.c 17.8 KB