summaryrefslogtreecommitdiff
path: root/mm/memory.c
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2025-11-19 17:26:25 +0300
committerThomas Zimmermann <tzimmermann@suse.de>2025-11-19 17:26:25 +0300
commitd4f14fa5c6c4d39b5187e1f410d59e38d76f283f (patch)
tree8666bd4fcd78149936221a64707c4dc6ca75a9f8 /mm/memory.c
parent949f1fd2225baefbea2995afa807dba5cbdb6bd3 (diff)
parent6a23ae0a96a600d1d12557add110e0bb6e32730c (diff)
downloadlinux-d4f14fa5c6c4d39b5187e1f410d59e38d76f283f.tar.xz
Merge drm/drm-fixes into drm-misc-fixes
Backmerging to get fixes from v6.18-rc6. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c20
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;