Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

microblaze: uaccess.h: Fix timerfd syscall

__pu_val must be volatile to ensure that the value is not lost.

It was causing the problem with timerfd syscall
where using inline asm at the end of function call doesn't
save u64 bit value to the stack.
In comparison both cases you can find out this fragment
where you can see the first part which is saved u64
value to stack and then using it in __put_user_asm_8 macro.
Origin broken implementation misses the first two swi instructions.

swi r22, r1, 28 /* missing without volatile */
swi r23, r1, 32
...
addik r4, r1, 28
lwi r3, r4, 0
swi r3, r25, 0
lwi r3, r4, 4
swi r3, r25, 4
addk r3, r0, r0

NOTE: Moving __put_val initialization after declaration
has not impact on this bug. It is just coding style issue.

Signed-off-by: Michal Simek <monstr@monstr.eu>

authored by

Michal Simek and committed by
Michal Simek
bf0e12c7 4336bac5

+1 -2
+1 -2
arch/microblaze/include/asm/uaccess.h
··· 298 298 299 299 #define __put_user_check(x, ptr, size) \ 300 300 ({ \ 301 - typeof(*(ptr)) __pu_val; \ 301 + typeof(*(ptr)) volatile __pu_val = x; \ 302 302 typeof(*(ptr)) __user *__pu_addr = (ptr); \ 303 303 int __pu_err = 0; \ 304 304 \ 305 - __pu_val = (x); \ 306 305 if (access_ok(VERIFY_WRITE, __pu_addr, size)) { \ 307 306 switch (size) { \ 308 307 case 1: \