On Sun, 24 Nov 2024 at 08:11, David Laight <david.lai...@aculab.com> wrote: > > Is there an 'unsafe_get_user_nofault()' that uses a trap handler > that won't fault in a page?
Nope. I was thinking about the same thing, but we actually don't look up the fault handler early - we only do it at failure time. So the pagefault_disable() thus acts as the failure trigger that makes us look up the fault handler. Without that, we'd never even check if there's a exception note on the instruction. > I'd also have thought that the trap handler for unsafe_get_user() > would jump to the Efault label having already done user_access_end(). > But maybe it doesn't work out that way? I actually at one point had a local version that did exactly that, because it allowed us to avoid doing the user_access_end in the exception path. It got ugly. In particular, it gets really ugly for the "copy_to/from_user()" case where we want to be byte-accurate, and a 64-bit access fails, and we go back to doing the last few accesses one byte at a time. See the exception table in arch/x86/lib/copy_user_64.S where it jumps to .Lcopy_user_tail for an example of this. Yes, yes, you could just do a "stac" again in the exception path to undo the fact that the fault handler would have turned off user accesses again... But look at that copy_user_64 code again and you'll see that it's actually a generic replacement for "rep movs" with fault handling, and can be used for the "copy_from_kernel_nofault" cases too. So I decided that it was just too ugly for words to have the fault handler basically change the state of the faultee that way. Linus