diff options
Diffstat (limited to 'mm/huge_memory.c')
| -rw-r--r-- | mm/huge_memory.c | 18 | 
1 files changed, 14 insertions, 4 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 94ef5c02b459..94c958f7ebb5 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -37,6 +37,7 @@  #include <linux/page_owner.h>  #include <linux/sched/sysctl.h>  #include <linux/memory-tiers.h> +#include <linux/compat.h>  #include <asm/tlb.h>  #include <asm/pgalloc.h> @@ -809,7 +810,10 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,  {  	loff_t off_end = off + len;  	loff_t off_align = round_up(off, size); -	unsigned long len_pad, ret; +	unsigned long len_pad, ret, off_sub; + +	if (IS_ENABLED(CONFIG_32BIT) || in_compat_syscall()) +		return 0;  	if (off_end <= off_align || (off_end - off_align) < size)  		return 0; @@ -835,7 +839,13 @@ static unsigned long __thp_get_unmapped_area(struct file *filp,  	if (ret == addr)  		return addr; -	ret += (off - ret) & (size - 1); +	off_sub = (off - ret) & (size - 1); + +	if (current->mm->get_unmapped_area == arch_get_unmapped_area_topdown && +	    !off_sub) +		return ret + size; + +	ret += off_sub;  	return ret;  } @@ -2437,7 +2447,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,  			page = pmd_page(old_pmd);  			folio = page_folio(page);  			if (!folio_test_dirty(folio) && pmd_dirty(old_pmd)) -				folio_set_dirty(folio); +				folio_mark_dirty(folio);  			if (!folio_test_referenced(folio) && pmd_young(old_pmd))  				folio_set_referenced(folio);  			folio_remove_rmap_pmd(folio, page, vma); @@ -3563,7 +3573,7 @@ int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw,  	}  	if (pmd_dirty(pmdval)) -		folio_set_dirty(folio); +		folio_mark_dirty(folio);  	if (pmd_write(pmdval))  		entry = make_writable_migration_entry(page_to_pfn(page));  	else if (anon_exclusive)  | 
