As pointed out by Sashiko there is a TOCTOU race between the page table walk (which checks for device memory) and the copy_from_user_inatomic (which reads the frame). Another thread could mmap device memory at the target address in between.
Three options: 1. Accept the race — it requires a cooperating thread with precise timing, and the guard still eliminates the common case (stable device mappings). 2. Use mmap_read_trylock() once per unwind, held across all frames: a. Fall back to the lockless walk (best-effort) when the trylock fails. b. Stop unwinding user space entirely when the trylock fails. Option 2 adds mmap_lock contention per unwind. Is the race narrow enough to accept, or is the trylock approach preferred?

