diff options
| author | Dave Airlie <airlied@redhat.com> | 2025-11-21 08:55:08 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2025-11-21 08:55:08 +1000 |
| commit | ce0478b02ed29465c1de3d03c3eea721355f9d2d (patch) | |
| tree | 79a94d382aa793b762cd974f97fdfa575f603639 /mm/memory.c | |
| parent | f0ded972d37150f9f889de75c9eecc5cb0730013 (diff) | |
| parent | 6a23ae0a96a600d1d12557add110e0bb6e32730c (diff) | |
Merge tag 'v6.18-rc6' into drm-next
Linux 6.18-rc6
Backmerge in order to merge msm next
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'mm/memory.c')
| -rw-r--r-- | mm/memory.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/mm/memory.c b/mm/memory.c index 74b45e258323..b59ae7ce42eb 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -65,6 +65,7 @@ #include <linux/gfp.h> #include <linux/migrate.h> #include <linux/string.h> +#include <linux/shmem_fs.h> #include <linux/memory-tiers.h> #include <linux/debugfs.h> #include <linux/userfaultfd_k.h> @@ -5501,8 +5502,25 @@ fallback: return ret; } + if (!needs_fallback && vma->vm_file) { + struct address_space *mapping = vma->vm_file->f_mapping; + pgoff_t file_end; + + file_end = DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE); + + /* + * Do not allow to map with PTEs beyond i_size and with PMD + * across i_size to preserve SIGBUS semantics. + * + * Make an exception for shmem/tmpfs that for long time + * intentionally mapped with PMDs across i_size. + */ + needs_fallback = !shmem_mapping(mapping) && + file_end < folio_next_index(folio); + } + if (pmd_none(*vmf->pmd)) { - if (folio_test_pmd_mappable(folio)) { + if (!needs_fallback && folio_test_pmd_mappable(folio)) { ret = do_set_pmd(vmf, folio, page); if (ret != VM_FAULT_FALLBACK) return ret; |