__get_user() for 64-bit value broken on 32-bit kernel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We have a problem on the 32bit kernel with __get_user()
for a 64bit value.

In arch/parisc/include/asm/uaccess.h we have
#define __get_user(x, ptr)                               \
({                                                       \
        register long __gu_err __asm__ ("r8") = 0;       \
        register long __gu_val;                          \
                                                         \
        load_sr2();                                      \
        switch (sizeof(*(ptr))) {                        \
            case 1: __get_user_asm("ldb", ptr); break;   \
            case 2: __get_user_asm("ldh", ptr); break;   \
            case 4: __get_user_asm("ldw", ptr); break;   \
            case 8: LDD_USER(ptr);  break;               \
            default: BUILD_BUG(); break;                 \
        }                                                \
                                                         \
        (x) = (__force __typeof__(*(ptr))) __gu_val;     \
        __gu_err;                                        \
})

The problem is, that on a 32bit kernel __gu_val is a 32bit ("long") variable,
but LDD_USER(ptr) returns a 64bit entity.
And since __gu_val is 32bit only, afterwards the (x) = __gu_val will
return a 32bit-truncated value too.

I'm not sure how this can be fixed. My latest approaches always ended
with lots of compiler warnings.

A testcase for this is the test_user_copy.ko kernel module (source
in lib/test_user_copy.c).

Any ideas?

Helge
--
To unsubscribe from this list: send the line "unsubscribe linux-parisc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux SoC]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux