linux_dsm_epyc7002/drivers/gpu/drm
Linus Torvalds 17839856fd gup: document and work around "COW can break either way" issue
Doing a "get_user_pages()" on a copy-on-write page for reading can be
ambiguous: the page can be COW'ed at any time afterwards, and the
direction of a COW event isn't defined.

Yes, whoever writes to it will generally do the COW, but if the thread
that did the get_user_pages() unmapped the page before the write (and
that could happen due to memory pressure in addition to any outright
action), the writer could also just take over the old page instead.

End result: the get_user_pages() call might result in a page pointer
that is no longer associated with the original VM, and is associated
with - and controlled by - another VM having taken it over instead.

So when doing a get_user_pages() on a COW mapping, the only really safe
thing to do would be to break the COW when getting the page, even when
only getting it for reading.

At the same time, some users simply don't even care.

For example, the perf code wants to look up the page not because it
cares about the page, but because the code simply wants to look up the
physical address of the access for informational purposes, and doesn't
really care about races when a page might be unmapped and remapped
elsewhere.

This adds logic to force a COW event by setting FOLL_WRITE on any
copy-on-write mapping when FOLL_GET (or FOLL_PIN) is used to get a page
pointer as a result.

The current semantics end up being:

 - __get_user_pages_fast(): no change. If you don't ask for a write,
   you won't break COW. You'd better know what you're doing.

 - get_user_pages_fast(): the fast-case "look it up in the page tables
   without anything getting mmap_sem" now refuses to follow a read-only
   page, since it might need COW breaking.  Which happens in the slow
   path - the fast path doesn't know if the memory might be COW or not.

 - get_user_pages() (including the slow-path fallback for gup_fast()):
   for a COW mapping, turn on FOLL_WRITE for FOLL_GET/FOLL_PIN, with
   very similar semantics to FOLL_FORCE.

If it turns out that we want finer granularity (ie "only break COW when
it might actually matter" - things like the zero page are special and
don't need to be broken) we might need to push these semantics deeper
into the lookup fault path.  So if people care enough, it's possible
that we might end up adding a new internal FOLL_BREAK_COW flag to go
with the internal FOLL_COW flag we already have for tracking "I had a
COW".

Alternatively, if it turns out that different callers might want to
explicitly control the forced COW break behavior, we might even want to
make such a flag visible to the users of get_user_pages() instead of
using the above default semantics.

But for now, this is mostly commentary on the issue (this commit message
being a lot bigger than the patch, and that patch in turn is almost all
comments), with that minimal "enable COW breaking early" logic using the
existing FOLL_WRITE behavior.

[ It might be worth noting that we've always had this ambiguity, and it
  could arguably be seen as a user-space issue.

  You only get private COW mappings that could break either way in
  situations where user space is doing cooperative things (ie fork()
  before an execve() etc), but it _is_ surprising and very subtle, and
  fork() is supposed to give you independent address spaces.

  So let's treat this as a kernel issue and make the semantics of
  get_user_pages() easier to understand. Note that obviously a true
  shared mapping will still get a page that can change under us, so this
  does _not_ mean that get_user_pages() somehow returns any "stable"
  page ]

Reported-by: Jann Horn <jannh@google.com>
Tested-by: Christoph Hellwig <hch@lst.de>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Kirill Shutemov <kirill@shutemov.name>
Acked-by: Jan Kara <jack@suse.cz>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-06-02 10:19:17 -07:00
..
amd drm fixes for 5.7 final 2020-05-29 12:32:46 -07:00
arc drm/bridge: Extend bridge API to disable connector creation 2020-02-26 13:31:23 +02:00
arm drm/komeda: mark PM functions as __maybe_unused 2020-03-06 11:25:58 +08:00
armada Update rmk's email address in various drivers 2020-04-21 17:50:09 +01:00
aspeed
ast drm/ast: Use simple encoder 2020-03-02 09:22:43 +01:00
atmel-hlcdc drm/bridge: Extend bridge API to disable connector creation 2020-02-26 13:31:23 +02:00
bochs Linux 5.6 2020-03-31 15:15:47 +10:00
bridge ARM updates for 5.8-rc1: 2020-06-01 15:36:32 -07:00
cirrus drm/cirrus: add drm_driver.release callback. 2020-02-12 10:24:08 +01:00
etnaviv ARM updates for 5.8-rc1: 2020-06-01 15:36:32 -07:00
exynos drm/bridge: analogix_dp: Split bind() into probe() and real bind() 2020-04-09 10:29:35 +02:00
fsl-dcu drm/bridge: Extend bridge API to disable connector creation 2020-02-26 13:31:23 +02:00
gma500 drm: Remove drm_fb_helper add, add all and remove connector calls 2020-03-06 14:19:58 +01:00
hisilicon Linux 5.6-rc5 2020-03-11 07:27:21 +10:00
i2c drm/bridge: Extend bridge API to disable connector creation 2020-02-26 13:31:23 +02:00
i810 drm/i810: Don't include <drm/drm_pci.h> 2019-12-05 08:44:12 +01:00
i915 gup: document and work around "COW can break either way" issue 2020-06-02 10:19:17 -07:00
imx drm/bridge: Extend bridge API to disable connector creation 2020-02-26 13:31:23 +02:00
ingenic gpu/drm: Ingenic: Fix opaque pointer casted to wrong type 2020-05-17 14:16:15 +02:00
lib
lima drm-misc-next for 5.7: 2020-02-21 05:44:40 +10:00
mcde drm/bridge: Extend bridge API to disable connector creation 2020-02-26 13:31:23 +02:00
mediatek sound updates for 5.7-rc1 2020-04-02 15:50:04 -07:00
meson drm/meson: pm resume add return errno branch 2020-05-13 12:00:37 +02:00
mga drm/mga: Don't include <drm/drm_pci.h> 2019-12-05 08:44:16 +01:00
mgag200 drm/mgag200: Use simple encoder 2020-03-02 09:22:49 +01:00
msm docs: filesystems: fix renamed references 2020-04-20 15:45:22 -06:00
mxsfb drm/panel: decouple connector from drm_panel 2019-12-09 22:57:26 +01:00
nouveau Merge branch 'linux-5.7' of git://github.com/skeggsb/linux into drm-fixes 2020-04-16 15:40:02 +10:00
omapdrm ARM: driver updates 2020-04-03 15:05:35 -07:00
panel drm/panel-simple: drop use of data-mapping property 2020-03-25 21:59:22 +01:00
panfrost drm-misc-next for 5.7: 2020-03-12 12:42:56 +10:00
pl111 drm/pl111: Support Integrator IM-PD1 module 2020-02-16 14:31:30 +01:00
qxl drm/qxl: qxl_release use after free 2020-04-29 13:21:34 +02:00
r128 drm/r128: Don't include <drm/drm_pci.h> 2019-12-05 08:44:23 +01:00
radeon pci-v5.7-changes 2020-04-03 14:25:02 -07:00
rcar-du drm/bridge: Extend bridge API to disable connector creation 2020-02-26 13:31:23 +02:00
rockchip drm/bridge: analogix_dp: Split bind() into probe() and real bind() 2020-04-09 10:29:35 +02:00
savage drm/savage: Don't include <drm/drm_pci.h> 2019-12-05 08:44:34 +01:00
scheduler drm/scheduler: fix drm_sched_get_cleanup_job 2020-04-15 11:09:13 +02:00
selftests drm/modes: Make sure to parse valid rotation value from cmdline 2020-02-12 18:32:54 +01:00
shmobile
sis drm/sis: Don't include <drm/drm_pci.h> 2019-12-05 08:44:55 +01:00
sti drm/bridge: Extend bridge API to disable connector creation 2020-02-26 13:31:23 +02:00
stm drm/bridge: Extend bridge API to disable connector creation 2020-02-26 13:31:23 +02:00
sun4i sun6i: dsi: fix gcc-4.8 2020-05-04 13:48:42 +02:00
tdfx drm/tdfx: Don't include <drm/drm_pci.h> 2019-12-05 08:45:01 +01:00
tegra drm/tegra: Fix SMMU support on Tegra124 and Tegra210 2020-04-28 11:44:07 +02:00
tidss drm/tidss: fix crash related to accessing freed memory 2020-04-20 10:07:35 +03:00
tilcdc drm/bridge: Extend bridge API to disable connector creation 2020-02-26 13:31:23 +02:00
tiny drm/tiny: fix sparse warning: incorrect type in assignment (different base types) 2020-03-14 08:31:30 +01:00
ttm drm fixes for 5.7-rc1 (part two) 2020-04-10 12:38:28 -07:00
tve200 drm: get drm_bridge_panel connector via helper 2019-12-09 22:57:26 +01:00
udl drm/udl: Clear struct drm_connector_funcs.dpms 2020-02-10 09:24:09 +01:00
v3d drm/v3d: Replace wait_for macros to remove use of msleep 2020-03-04 22:15:34 -08:00
vboxvideo drm/vboxvideo: Add missing remove_conflicting_pci_framebuffers call, v2 2020-03-26 17:03:03 +01:00
vc4 drm/vc4: Fix HDMI mode validation 2020-03-27 13:38:47 +01:00
vgem drm/vgem: Close use-after-free race in vgem_gem_create 2020-02-06 19:04:41 +01:00
via Merge branch 'akpm' (patches from Andrew) 2020-01-31 12:16:36 -08:00
virtio A few minor fixes for an ordering issue in virtio, an (old) gcc warning 2020-05-08 15:04:25 +10:00
vkms drm/vkms: Convert to CRTC VBLANK callbacks 2020-02-13 13:10:10 +01:00
vmwgfx drm/vmwgfx: Return true in function vmw_fence_obj_signaled() 2020-05-16 06:50:37 +02:00
xen drm/xen: fix passing zero to 'PTR_ERR' warning 2020-03-31 17:14:51 +02:00
zte drm/zte: plane_state->fb iff plane_state->crtc 2020-01-28 15:43:58 +01:00
drm_agpsupport.c drm: use DIV_ROUND_UP helper macro for calculations 2019-11-04 18:17:36 +01:00
drm_atomic_helper.c drm/bridge: Add the necessary bits to support bus format negotiation 2020-01-31 16:39:53 +01:00
drm_atomic_state_helper.c drm/atomic-helper: fix kerneldoc 2020-02-15 13:21:22 +01:00
drm_atomic_uapi.c drm/atomic: Spell CRTC consistently 2019-12-22 11:13:00 +01:00
drm_atomic.c drm/bridge: Fix the bridge kernel doc 2020-02-18 16:50:45 +01:00
drm_auth.c drm/auth: Drop master_create/destroy hooks 2020-01-29 09:14:11 +01:00
drm_blend.c drm: two planes with the same zpos have undefined ordering 2019-10-09 20:04:55 +02:00
drm_bridge_connector.c drm: Add helper to create a connector for a chain of bridges 2020-02-26 13:31:41 +02:00
drm_bridge.c drm: Add helper to create a connector for a chain of bridges 2020-02-26 13:31:41 +02:00
drm_bufs.c drm: bufs: Clean up documentation 2020-03-16 09:26:18 +01:00
drm_cache.c drm/gpu: Fix Memory barrier without comment Issue 2019-10-25 09:35:06 +02:00
drm_client_modeset.c Linux 5.6-rc5 2020-03-11 07:27:21 +10:00
drm_client.c drm/client: Dual licence the file in GPL-2 and MIT 2020-02-29 00:16:12 +01:00
drm_color_mgmt.c drm: Inline drm_color_lut_extract() 2019-11-29 21:29:17 +02:00
drm_connector.c drm/connector: Add helper to get a connector type name 2020-02-26 13:31:18 +02:00
drm_context.c drm: context: Clean up documentation 2020-03-16 09:23:55 +01:00
drm_crtc_helper_internal.h
drm_crtc_helper.c drm: drop unused drm_crtc callback 2020-02-15 21:15:17 +01:00
drm_crtc_internal.h drm: Add getfb2 ioctl 2020-01-14 16:22:17 -05:00
drm_crtc.c
drm_damage_helper.c
drm_debugfs_crc.c drm/crc: Actually allow to change the crc source 2020-01-28 16:49:22 +01:00
drm_debugfs.c drm/debugfs: also take per device driver features into account 2020-01-25 15:49:11 +02:00
drm_dma.c drm: fix parameters documentation style in drm_dma 2020-01-18 10:33:12 +01:00
drm_dp_aux_dev.c drm/dp_mst: Add MST support to DP DPCD R/W functions 2020-01-09 18:07:46 -05:00
drm_dp_cec.c
drm_dp_dual_mode_helper.c
drm_dp_helper.c UAPI Changes: 2020-03-19 10:40:27 +10:00
drm_dp_mst_topology_internal.h
drm_dp_mst_topology.c Merge tag 'noinstr-lds-2020-05-19' into core/rcu 2020-05-19 15:50:34 +02:00
drm_drv.c drm: Nerf drm_global_mutex BKL for good drivers 2020-02-11 15:03:09 +01:00
drm_dsc.c
drm_dumb_buffers.c
drm_edid_load.c
drm_edid.c drm/edid: Add Oculus Rift S to non-desktop list 2020-05-20 12:56:49 +10:00
drm_encoder_slave.c
drm_encoder.c drm/bridge: Make the bridge chain a double-linked list 2019-12-09 10:03:01 +01:00
drm_fb_cma_helper.c drm/fb-cma-helpers: Fix include issue 2020-01-09 17:33:41 +01:00
drm_fb_helper.c drm: Remove unused arg from drm_fb_helper_init 2020-03-06 14:19:57 +01:00
drm_file.c drm_read(): get rid of pointless access_ok() 2020-05-29 11:05:54 -04:00
drm_flip_work.c
drm_format_helper.c drm/format_helper: Dual licence the file in GPL 2 and MIT 2020-02-17 10:27:13 +01:00
drm_fourcc.c drm/fourcc: Fill out all block sizes for P210 2019-11-28 11:19:32 +01:00
drm_framebuffer.c drm: Add getfb2 ioctl 2020-01-14 16:22:17 -05:00
drm_gem_cma_helper.c
drm_gem_framebuffer_helper.c drm/gem-fb-helper: convert to drm device based logging 2019-12-19 15:55:10 +02:00
drm_gem_shmem_helper.c drm/shmem: drop pgprot_decrypted() 2020-03-02 07:13:19 +01:00
drm_gem_ttm_helper.c drm/ttm: fix mmap refcounting 2019-11-15 08:00:08 +01:00
drm_gem_vram_helper.c drm/vram: Add helpers to validate a display mode's memory requirements 2020-02-06 10:32:54 +01:00
drm_gem.c drm: Mark up racy check of drm_gem_object.handle_count 2020-03-16 10:31:35 +00:00
drm_hashtab.c
drm_hdcp.c drm: Fix HDCP failures when SRM fw is missing 2020-05-05 14:01:53 -04:00
drm_internal.h drm/hdcp: optimizing the srm handling 2020-03-04 06:33:00 +05:30
drm_ioc32.c
drm_ioctl.c docs: fix broken references to text files 2020-04-20 15:35:59 -06:00
drm_irq.c drm/irq: remove check on dev->dev_private 2020-02-11 18:39:47 +02:00
drm_kms_helper_common.c
drm_lease.c drm/lease: fix WARNING in idr_destroy 2020-03-18 14:42:18 +01:00
drm_legacy_misc.c
drm_legacy.h
drm_lock.c drm: lock: Clean up documentation 2020-03-16 09:27:09 +01:00
drm_memory.c
drm_mipi_dbi.c drm/mipi-dbi: Remove sending of vblank event 2020-01-30 09:00:45 +01:00
drm_mipi_dsi.c drm/dsi: add helpers for DSI compression mode and PPS packets 2019-11-07 15:00:16 +02:00
drm_mm.c drm/mm: revert "Break long searches in fragmented address spaces" 2020-03-31 17:35:56 +02:00
drm_mode_config.c drm/modeset: Prime modeset lock vs dma_resv 2019-11-21 11:03:31 +01:00
drm_mode_object.c drm/property: Enforce more lifetime rules 2019-11-04 18:17:36 +01:00
drm_modes.c drm/modes: Make sure to parse valid rotation value from cmdline 2020-02-12 18:32:54 +01:00
drm_modeset_helper.c
drm_modeset_lock.c
drm_of.c drm: of: Add drm_of_lvds_get_dual_link_pixel_order 2019-12-18 02:40:16 +02:00
drm_panel_orientation_quirks.c
drm_panel.c drm/drm_panel: Fix EXPORT of drm_panel_of_backlight() one more time 2019-12-17 20:39:33 +01:00
drm_pci.c drm: Make drm_pci_agp_init legacy 2020-03-09 09:22:50 +00:00
drm_plane_helper.c
drm_plane.c
drm_prime.c drm/prime: fix extracting of the DMA addresses from a scatterlist 2020-04-05 10:44:12 -04:00
drm_print.c drm/print: convert debug category macros into an enum 2019-11-14 14:08:57 +02:00
drm_probe_helper.c drm: Stop accessing encoder->bridge directly 2019-12-09 10:02:45 +01:00
drm_property.c drm: limit to INT_MAX in create_blob ioctl 2019-12-04 19:44:13 -08:00
drm_rect.c drm/rect: update kerneldoc for drm_rect_clip_scaled() 2019-11-28 13:15:43 +01:00
drm_scatter.c drm: prevent a harmless integer overflow in drm_legacy_sg_alloc() 2020-02-29 00:16:12 +01:00
drm_scdc_helper.c
drm_self_refresh_helper.c drm/atomic: fix self-refresh helpers crtc state dereference 2019-11-06 13:00:21 -05:00
drm_simple_kms_helper.c drm/simple-kms: Fix documentation for drm_simple_encoder_init() 2020-03-06 09:24:29 +01:00
drm_syncobj.c drm/syncobj: Add documentation for timeline syncobj 2020-01-20 14:22:21 +01:00
drm_sysfs.c drm: sysfs: Use scnprintf() for avoiding potential buffer overflow 2020-03-11 14:54:09 +01:00
drm_trace_points.c
drm_trace.h
drm_vblank.c drm/vblank: Fix documentation of VBLANK timestamp helper 2020-03-06 09:24:54 +01:00
drm_vm.c drm: vm: Clean up documentation 2020-03-16 09:25:22 +01:00
drm_vma_manager.c
drm_vram_helper_common.c
drm_writeback.c
Kconfig docs: fix broken references to text files 2020-04-20 15:35:59 -06:00
Makefile drm: Add helper to create a connector for a chain of bridges 2020-02-26 13:31:41 +02:00