diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index ec442af3f886..23f559fc1a4c 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -211,6 +211,7 @@ enum mapping_flags { AS_KERNEL_FILE = 10, /* mapping for a fake kernel file that shouldn't account usage to user cgroups */ AS_NO_DATA_INTEGRITY = 11, /* no data integrity guarantees */ + AS_NO_READ_ONLY_THP_FOR_FS = 12, /* Bits 16-25 are used for FOLIO_ORDER */ AS_FOLIO_ORDER_BITS = 5, AS_FOLIO_ORDER_MIN = 16, diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 40cf59301c21..4bdda92ce01e 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -94,6 +94,9 @@ static inline bool file_thp_enabled(struct vm_area_struct *vma) inode = file_inode(vma->vm_file); + if (test_bit(AS_NO_READ_ONLY_THP_FOR_FS, &inode->i_mapping->flags)) + return false; + return !inode_is_open_for_write(inode) && S_ISREG(inode->i_mode); } diff --git a/mm/secretmem.c b/mm/secretmem.c index edf111e0a1bb..56d93a74f5fc 100644 --- a/mm/secretmem.c +++ b/mm/secretmem.c @@ -205,7 +205,8 @@ static struct file *secretmem_file_create(unsigned long flags) mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); mapping_set_unevictable(inode->i_mapping); - + set_bit(AS_NO_READ_ONLY_THP_FOR_FS, &inode->i_mapping->flags); + inode->i_op = &secretmem_iops; inode->i_mapping->a_ops = &secretmem_aops; diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index fdaea3422c30..b93a324c81bd 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -597,6 +597,7 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags) inode->i_size = size; mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); mapping_set_inaccessible(inode->i_mapping); + set_bit(AS_NO_READ_ONLY_THP_FOR_FS, &inode->i_mapping->flags); /* Unmovable mappings are supposed to be marked unevictable as well. */ WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping));