73
73
#include <linux/numa.h>
74
74
#include <linux/perf_event.h>
75
75
#include <linux/ptrace.h>
76
+ #include <linux/vmalloc.h>
76
77
77
78
#include <trace/events/kmem.h>
78
79
83
84
#include <asm/tlb.h>
84
85
#include <asm/tlbflush.h>
85
86
87
+ #include "pgalloc-track.h"
86
88
#include "internal.h"
87
89
88
90
#if defined(LAST_CPUPID_NOT_IN_PAGE_FLAGS ) && !defined(CONFIG_COMPILE_TEST )
@@ -2206,15 +2208,16 @@ EXPORT_SYMBOL(vm_iomap_memory);
2206
2208
2207
2209
static int apply_to_pte_range (struct mm_struct * mm , pmd_t * pmd ,
2208
2210
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 )
2210
2213
{
2211
2214
pte_t * pte ;
2212
2215
int err = 0 ;
2213
2216
spinlock_t * ptl ;
2214
2217
2215
2218
if (create ) {
2216
2219
pte = (mm == & init_mm ) ?
2217
- pte_alloc_kernel (pmd , addr ) :
2220
+ pte_alloc_kernel_track (pmd , addr , mask ) :
2218
2221
pte_alloc_map_lock (mm , pmd , addr , & ptl );
2219
2222
if (!pte )
2220
2223
return - ENOMEM ;
@@ -2235,6 +2238,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
2235
2238
break ;
2236
2239
}
2237
2240
} while (addr += PAGE_SIZE , addr != end );
2241
+ * mask |= PGTBL_PTE_MODIFIED ;
2238
2242
2239
2243
arch_leave_lazy_mmu_mode ();
2240
2244
@@ -2245,7 +2249,8 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
2245
2249
2246
2250
static int apply_to_pmd_range (struct mm_struct * mm , pud_t * pud ,
2247
2251
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 )
2249
2254
{
2250
2255
pmd_t * pmd ;
2251
2256
unsigned long next ;
@@ -2254,7 +2259,7 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
2254
2259
BUG_ON (pud_huge (* pud ));
2255
2260
2256
2261
if (create ) {
2257
- pmd = pmd_alloc (mm , pud , addr );
2262
+ pmd = pmd_alloc_track (mm , pud , addr , mask );
2258
2263
if (!pmd )
2259
2264
return - ENOMEM ;
2260
2265
} else {
@@ -2264,7 +2269,7 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
2264
2269
next = pmd_addr_end (addr , end );
2265
2270
if (create || !pmd_none_or_clear_bad (pmd )) {
2266
2271
err = apply_to_pte_range (mm , pmd , addr , next , fn , data ,
2267
- create );
2272
+ create , mask );
2268
2273
if (err )
2269
2274
break ;
2270
2275
}
@@ -2274,14 +2279,15 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
2274
2279
2275
2280
static int apply_to_pud_range (struct mm_struct * mm , p4d_t * p4d ,
2276
2281
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 )
2278
2284
{
2279
2285
pud_t * pud ;
2280
2286
unsigned long next ;
2281
2287
int err = 0 ;
2282
2288
2283
2289
if (create ) {
2284
- pud = pud_alloc (mm , p4d , addr );
2290
+ pud = pud_alloc_track (mm , p4d , addr , mask );
2285
2291
if (!pud )
2286
2292
return - ENOMEM ;
2287
2293
} else {
@@ -2291,7 +2297,7 @@ static int apply_to_pud_range(struct mm_struct *mm, p4d_t *p4d,
2291
2297
next = pud_addr_end (addr , end );
2292
2298
if (create || !pud_none_or_clear_bad (pud )) {
2293
2299
err = apply_to_pmd_range (mm , pud , addr , next , fn , data ,
2294
- create );
2300
+ create , mask );
2295
2301
if (err )
2296
2302
break ;
2297
2303
}
@@ -2301,14 +2307,15 @@ static int apply_to_pud_range(struct mm_struct *mm, p4d_t *p4d,
2301
2307
2302
2308
static int apply_to_p4d_range (struct mm_struct * mm , pgd_t * pgd ,
2303
2309
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 )
2305
2312
{
2306
2313
p4d_t * p4d ;
2307
2314
unsigned long next ;
2308
2315
int err = 0 ;
2309
2316
2310
2317
if (create ) {
2311
- p4d = p4d_alloc (mm , pgd , addr );
2318
+ p4d = p4d_alloc_track (mm , pgd , addr , mask );
2312
2319
if (!p4d )
2313
2320
return - ENOMEM ;
2314
2321
} else {
@@ -2318,7 +2325,7 @@ static int apply_to_p4d_range(struct mm_struct *mm, pgd_t *pgd,
2318
2325
next = p4d_addr_end (addr , end );
2319
2326
if (create || !p4d_none_or_clear_bad (p4d )) {
2320
2327
err = apply_to_pud_range (mm , p4d , addr , next , fn , data ,
2321
- create );
2328
+ create , mask );
2322
2329
if (err )
2323
2330
break ;
2324
2331
}
@@ -2331,8 +2338,9 @@ static int __apply_to_page_range(struct mm_struct *mm, unsigned long addr,
2331
2338
void * data , bool create )
2332
2339
{
2333
2340
pgd_t * pgd ;
2334
- unsigned long next ;
2341
+ unsigned long start = addr , next ;
2335
2342
unsigned long end = addr + size ;
2343
+ pgtbl_mod_mask mask = 0 ;
2336
2344
int err = 0 ;
2337
2345
2338
2346
if (WARN_ON (addr >= end ))
@@ -2343,11 +2351,14 @@ static int __apply_to_page_range(struct mm_struct *mm, unsigned long addr,
2343
2351
next = pgd_addr_end (addr , end );
2344
2352
if (!create && pgd_none_or_clear_bad (pgd ))
2345
2353
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 );
2347
2355
if (err )
2348
2356
break ;
2349
2357
} while (pgd ++ , addr = next , addr != end );
2350
2358
2359
+ if (mask & ARCH_PAGE_TABLE_SYNC_MASK )
2360
+ arch_sync_kernel_mappings (start , start + size );
2361
+
2351
2362
return err ;
2352
2363
}
2353
2364
0 commit comments