Improve atomic memory access and support -mno-atomic.

Use CONFIG_GENERIC_ATOMIC64 if 32-bit.  Add system call to emulate
atomic compare exchange, primarily for targets lacking hardware
support (i.e., lacking RV32A, RV64A).  Support excluding use of
atomic memory instructions (-mno-atomic).

This change is mutually dependent on the corresponding change to
riscv-gcc.
On 08/16/2014 02:03 AM, Albert Ou wrote:
> In arch/riscv/kernel/sys_riscv.c:
> 
>> @@ -9,3 +10,35 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
>>  	return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
>>  }
>>  
>> +#ifdef CONFIG_RV_SYSRISCV_ATOMIC
>> +SYSCALL_DEFINE4(sysriscv, unsigned long, cmd, unsigned long, arg1,
>> +	unsigned long, arg2, unsigned long, arg3)
>> +{
>> +	unsigned long flags;
>> +	unsigned long prev;
>> +	unsigned int err;
>> +
>> +	switch (cmd) {
>> +	case RISCV_ATOMIC_CMPXCHG:
>> +		preempt_disable();
>> +		raw_local_irq_save(flags);
>> +		err = __get_user(prev, (unsigned int *)arg1);
> 
> Ensure |access_ok(VERIFY_WRITE, arg1, sizeof(unsigned long))| before
> calling |__{get,put}_user()|. I have rewritten |<asm/uaccess.h>| so that
> this check prevents userspace from accessing kernel memory.
> 
> Also, be sure to abort if |err| is non-zero (typically |-EFAULT|).
> 

Ok, understood.

// darius