Messages in this thread Patch in this message | | | From | Arnd Bergmann <> | Date | Fri, 28 Jun 2019 16:46:14 +0200 | Subject | Re: [PATCH] f2fs: fix 32-bit linking |
| |
On Fri, Jun 28, 2019 at 3:17 PM Christoph Hellwig <hch@infradead.org> wrote: > > On Fri, Jun 28, 2019 at 03:09:47PM +0200, Arnd Bergmann wrote: > > I came across this on arm-nommu (which disables > > CONFIG_CPU_SPECTRE) during randconfig testing. > > > > I don't see an easy way to add this in there, short of rewriting the > > whole __get_user_err() function. Any suggestions? > > Can't we just fall back to using copy_from_user with a little wrapper > that switches based on sizeof()?
I came up with something now. It's not pretty, but seems to satisfy the compiler. Not a proper patch yet, but let me know if you find a bug.
This might contain a double uaccess_save_and_enable/uaccess_restore, not sure how much we care about that.
Arnd
index 7e0d2727c6b5..c21cdecadf26 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -307,6 +307,7 @@ static inline void set_fs(mm_segment_t fs) do { \ unsigned long __gu_addr = (unsigned long)(ptr); \ unsigned long __gu_val; \ + unsigned long long __gu_val8; \ unsigned int __ua_flags; \ __chk_user_ptr(ptr); \ might_fault(); \ @@ -315,10 +316,13 @@ do { \ case 1: __get_user_asm_byte(__gu_val, __gu_addr, err); break; \ case 2: __get_user_asm_half(__gu_val, __gu_addr, err); break; \ case 4: __get_user_asm_word(__gu_val, __gu_addr, err); break; \ + case 8: __get_user_asm_dword(__gu_val8, __gu_addr, err);break; \ default: (__gu_val) = __get_user_bad(); \ } \ uaccess_restore(__ua_flags); \ - (x) = (__typeof__(*(ptr)))__gu_val; \ + (x) = __builtin_choose_expr(sizeof(*(ptr)) == 8, \ + (__typeof__(*(ptr)))__gu_val8, \ + (__typeof__(*(ptr)))__gu_val); \ } while (0)
#define __get_user_asm(x, addr, err, instr) \ @@ -373,6 +377,8 @@ do { \ __get_user_asm(x, addr, err, ldr) #endif
+#define __get_user_asm_dword(x, addr, err) \ + do { err = raw_copy_from_user(&x, (void __user *)addr, 8) ? -EFAULT : 0; } while (0)
#define __put_user_switch(x, ptr, __err, __fn) \ do { \
| |