• Linus Torvalds's avatar
    x86: Make __put_user() generate an out-of-line call · d55564cf
    Linus Torvalds authored
    Instead of inlining the stac/mov/clac sequence (which also requires
    individual exception table entries and several asm instruction
    alternatives entries), just generate "call __put_user_nocheck_X" for the
    __put_user() cases, the same way we changed __get_user earlier.
    
    Unlike the get_user() case, we didn't have the same nice infrastructure
    to just generate the call with a single case, so this actually has to
    change some of the infrastructure in order to do this.  But that only
    cleans up the code further.
    
    So now, instead of using a case statement for the sizes, we just do the
    same thing we've done on the get_user() side for a long time: use the
    size as an immediate constant to the asm, and generate the asm that way
    directly.
    
    In order to handle the special case of 64-bit data on a 32-bit kernel, I
    needed to change the calling convention slightly: the data is passed in
    %eax[:%edx], the pointer in %ecx, and the return value is also returned
    in %ecx.  It used to be returned in %eax, but because of how %eax can
    now be a double register input, we don't want mix that with a
    single-register output.
    
    The actual low-level asm is easier to handle: we'll just share the code
    between the checking and non-checking case, with the non-checking case
    jumping into the middle of the function.  That may sound a bit too
    special, but this code is all very very special anyway, so...
    
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Ingo Molnar <mingo@kernel.org>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    d55564cf
putuser.S 2.56 KB