mirror of
https://github.com/torvalds/linux.git
synced 2026-10-25 01:05:03 +02:00
The execbuffer relocation fast path writes each updated presumed_offset back to the user's relocation array with __put_user(), ignoring any failure. It does that while holding the objects' dma_resv locks, and with page faults enabled unless the relocation cache happens to have an atomic mapping active. So if that write faults, for example on a copy-on-write page after a fork(), the fault handler takes mmap_lock under dma_resv. That is the opposite of the order the i915 fault handler uses, which takes the object lock under mmap_lock. The comment above it claimed this could not happen, because "we did previously check if the relocations were writable (access_ok)". access_ok() is purely a range check. The comment dates from when this was access_ok(VERIFY_WRITE), and that only ever made a difference on the original i386, whose write-protect bit did not stop supervisor writes. So nothing has made sure the array was writable for decades. Do the write with page faults disabled, and if it fails, fall back to the slow path exactly as we already do when reading the relocations fails part-way through. We cannot just ignore the failure: the object has already been relocated, and a stale presumed_offset could later match again and skip a relocation that is needed. The slow path prefaults and retries. If the write still fails, it copies the relocations and marks every presumed_offset invalid with faults allowed and no locks held, which breaks copy-on-write as needed. One user-visible change: a relocation array in genuinely read-only memory used to get through the fast path, silently losing the presumed_offset updates. It now gets -EFAULT from the slow path, as it already did whenever anything else sent execbuffer there. The uapi has the kernel updating presumed_offset, so the array is expected to be writable. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
||
|---|---|---|
| .. | ||
| drm | ||
| host1x | ||
| ipu-v3 | ||
| nova-core | ||
| tests | ||
| trace | ||
| vga | ||
| buddy.c | ||
| Kconfig | ||
| Makefile | ||