7373#include <linux/numa.h>
7474#include <linux/perf_event.h>
7575#include <linux/ptrace.h>
76+ #include <linux/vmalloc.h>
7677
7778#include <trace/events/kmem.h>
7879
8384#include <asm/tlb.h>
8485#include <asm/tlbflush.h>
8586
87+ #include "pgalloc-track.h"
8688#include "internal.h"
8789
8890#if defined(LAST_CPUPID_NOT_IN_PAGE_FLAGS ) && !defined(CONFIG_COMPILE_TEST )
@@ -2206,15 +2208,16 @@ EXPORT_SYMBOL(vm_iomap_memory);
22062208
22072209static int apply_to_pte_range (struct mm_struct * mm , pmd_t * pmd ,
22082210 unsigned long addr , unsigned long end ,
2209- pte_fn_t fn , void * data , bool create )
2211+ pte_fn_t fn , void * data , bool create ,
2212+ pgtbl_mod_mask * mask )
22102213{
22112214 pte_t * pte ;
22122215 int err = 0 ;
22132216 spinlock_t * ptl ;
22142217
22152218 if (create ) {
22162219 pte = (mm == & init_mm ) ?
2217- pte_alloc_kernel (pmd , addr ) :
2220+ pte_alloc_kernel_track (pmd , addr , mask ) :
22182221 pte_alloc_map_lock (mm , pmd , addr , & ptl );
22192222 if (!pte )
22202223 return - ENOMEM ;
@@ -2235,6 +2238,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
22352238 break ;
22362239 }
22372240 } while (addr += PAGE_SIZE , addr != end );
2241+ * mask |= PGTBL_PTE_MODIFIED ;
22382242
22392243 arch_leave_lazy_mmu_mode ();
22402244
@@ -2245,7 +2249,8 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
22452249
22462250static int apply_to_pmd_range (struct mm_struct * mm , pud_t * pud ,
22472251 unsigned long addr , unsigned long end ,
2248- pte_fn_t fn , void * data , bool create )
2252+ pte_fn_t fn , void * data , bool create ,
2253+ pgtbl_mod_mask * mask )
22492254{
22502255 pmd_t * pmd ;
22512256 unsigned long next ;
@@ -2254,7 +2259,7 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
22542259 BUG_ON (pud_huge (* pud ));
22552260
22562261 if (create ) {
2257- pmd = pmd_alloc (mm , pud , addr );
2262+ pmd = pmd_alloc_track (mm , pud , addr , mask );
22582263 if (!pmd )
22592264 return - ENOMEM ;
22602265 } else {
@@ -2264,7 +2269,7 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
22642269 next = pmd_addr_end (addr , end );
22652270 if (create || !pmd_none_or_clear_bad (pmd )) {
22662271 err = apply_to_pte_range (mm , pmd , addr , next , fn , data ,
2267- create );
2272+ create , mask );
22682273 if (err )
22692274 break ;
22702275 }
@@ -2274,14 +2279,15 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
22742279
22752280static int apply_to_pud_range (struct mm_struct * mm , p4d_t * p4d ,
22762281 unsigned long addr , unsigned long end ,
2277- pte_fn_t fn , void * data , bool create )
2282+ pte_fn_t fn , void * data , bool create ,
2283+ pgtbl_mod_mask * mask )
22782284{
22792285 pud_t * pud ;
22802286 unsigned long next ;
22812287 int err = 0 ;
22822288
22832289 if (create ) {
2284- pud = pud_alloc (mm , p4d , addr );
2290+ pud = pud_alloc_track (mm , p4d , addr , mask );
22852291 if (!pud )
22862292 return - ENOMEM ;
22872293 } else {
@@ -2291,7 +2297,7 @@ static int apply_to_pud_range(struct mm_struct *mm, p4d_t *p4d,
22912297 next = pud_addr_end (addr , end );
22922298 if (create || !pud_none_or_clear_bad (pud )) {
22932299 err = apply_to_pmd_range (mm , pud , addr , next , fn , data ,
2294- create );
2300+ create , mask );
22952301 if (err )
22962302 break ;
22972303 }
@@ -2301,14 +2307,15 @@ static int apply_to_pud_range(struct mm_struct *mm, p4d_t *p4d,
23012307
23022308static int apply_to_p4d_range (struct mm_struct * mm , pgd_t * pgd ,
23032309 unsigned long addr , unsigned long end ,
2304- pte_fn_t fn , void * data , bool create )
2310+ pte_fn_t fn , void * data , bool create ,
2311+ pgtbl_mod_mask * mask )
23052312{
23062313 p4d_t * p4d ;
23072314 unsigned long next ;
23082315 int err = 0 ;
23092316
23102317 if (create ) {
2311- p4d = p4d_alloc (mm , pgd , addr );
2318+ p4d = p4d_alloc_track (mm , pgd , addr , mask );
23122319 if (!p4d )
23132320 return - ENOMEM ;
23142321 } else {
@@ -2318,7 +2325,7 @@ static int apply_to_p4d_range(struct mm_struct *mm, pgd_t *pgd,
23182325 next = p4d_addr_end (addr , end );
23192326 if (create || !p4d_none_or_clear_bad (p4d )) {
23202327 err = apply_to_pud_range (mm , p4d , addr , next , fn , data ,
2321- create );
2328+ create , mask );
23222329 if (err )
23232330 break ;
23242331 }
@@ -2331,8 +2338,9 @@ static int __apply_to_page_range(struct mm_struct *mm, unsigned long addr,
23312338 void * data , bool create )
23322339{
23332340 pgd_t * pgd ;
2334- unsigned long next ;
2341+ unsigned long start = addr , next ;
23352342 unsigned long end = addr + size ;
2343+ pgtbl_mod_mask mask = 0 ;
23362344 int err = 0 ;
23372345
23382346 if (WARN_ON (addr >= end ))
@@ -2343,11 +2351,14 @@ static int __apply_to_page_range(struct mm_struct *mm, unsigned long addr,
23432351 next = pgd_addr_end (addr , end );
23442352 if (!create && pgd_none_or_clear_bad (pgd ))
23452353 continue ;
2346- err = apply_to_p4d_range (mm , pgd , addr , next , fn , data , create );
2354+ err = apply_to_p4d_range (mm , pgd , addr , next , fn , data , create , & mask );
23472355 if (err )
23482356 break ;
23492357 } while (pgd ++ , addr = next , addr != end );
23502358
2359+ if (mask & ARCH_PAGE_TABLE_SYNC_MASK )
2360+ arch_sync_kernel_mappings (start , start + size );
2361+
23512362 return err ;
23522363}
23532364
0 commit comments