Search code examples
linuxkernel32-bitmode

Linux: Detect 64-bit kernel (long mode) from 32-bit user mode program


What's the best and most reliable way to detect if a 32-bit user mode program is running on a 64-bit kernel or not (i.e. if the system is in 'long mode')? I'd rather not call external programs if possible (or have to load any kernel modules).

Note: I want to detect whether a 64-bit kernel is being used (or really, whether the CPU is in long mode), not simply if a 64-bit capable processor is present (/proc/cpuinfo tells me that but not whether the 64-bit capability is being used).

The kernel fakes a 32-bit processor if uname is compiled 32-bit or if setarch i686 is used.


Solution

  • Call the uname() function and check the returned machine string, which will be x86_64 for a 64-bit Intel platform.

    One way of reversing the effect of the use of setarch is to reset the personality:

    #include <stdio.h>
    #include <sys/utsname.h>
    #include <sys/personality.h>
    
    int main()
    {
        struct utsname u;
    
        personality(PER_LINUX);
    
        uname(&u);
        puts(u.machine);
        return 0;
    }
    

    This shows the right results when compiled in 32-bit mode and run on a 64-bit system:

    $ gcc -m32 -o u u.c
    $ ./u
    x86_64
    $ setarch i686 ./u
    x86_64
    

    EDIT: Fixed code to reverse effect of setarch.

    Reference.