• Linus Torvalds's avatar
    unsafe_[get|put]_user: change interface to use a error target label · 1bd4403d
    Linus Torvalds authored
    When I initially added the unsafe_[get|put]_user() helpers in commit
    5b24a7a2 ("Add 'unsafe' user access functions for batched
    accesses"), I made the mistake of modeling the interface on our
    traditional __[get|put]_user() functions, which return zero on success,
    or -EFAULT on failure.
    That interface is fairly easy to use, but it's actually fairly nasty for
    good code generation, since it essentially forces the caller to check
    the error value for each access.
    In particular, since the error handling is already internally
    implemented with an exception handler, and we already use "asm goto" for
    various other things, we could fairly easily make the error cases just
    jump directly to an error label instead, and avoid the need for explicit
    checking after each operation.
    So switch the interface to pass in an error label, rather than checking
    the error value in the caller.  Best do it now before we start growing
    more users (the signal handling code in particular would be a good place
    to use the new interface).
    So rather than
    	if (unsafe_get_user(x, ptr))
    		... handle error ..
    the interface is now
    	unsafe_get_user(x, ptr, label);
    where an error during the user mode fetch will now just cause a jump to
    'label' in the caller.
    Right now the actual _implementation_ of this all still ends up being a
    "if (err) goto label", and does not take advantage of any exception
    label tricks, but for "unsafe_put_user()" in particular it should be
    fairly straightforward to convert to using the exception table model.
    Note that "unsafe_get_user()" is much harder to convert to a clever
    exception table model, because current versions of gcc do not allow the
    use of "asm goto" (for the exception) with output values (for the actual
    value to be fetched).  But that is hopefully not a limitation in the
    long term.
    [ Also note that it might be a good idea to switch unsafe_get_user() to
      actually _return_ the value it fetches from user space, but this
      commit only changes the error handling semantics ]
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
strnlen_user.c 4.26 KB