@@ -262,30 +262,85 @@ func (w *Walker) iterateRangeCanonical(start, end uintptr) bool {
262262 nextBoundary := addrEnd (start , end , pgdSize )
263263 pgdIndex := uint16 ((start & pgdMask ) >> pgdShift )
264264 pgdEntry := & w .pageTables .root [pgdIndex ]
265- if ! pgdEntry .Valid () {
266- if ! w .visitor .requiresAlloc () {
267- // Skip over this entry.
268- start = nextBoundary
269- continue
265+ if ! w .pageTables .largeAddressesEnabled {
266+ if ! pgdEntry .Valid () {
267+ if ! w .visitor .requiresAlloc () {
268+ // Skip over this entry.
269+ start = nextBoundary
270+ continue
271+ }
272+
273+ // Allocate a new pgd.
274+ pudEntries = w .pageTables .Allocator .NewPTEs () // escapes: depends on allocator.
275+ pgdEntry .setPageTable (w .pageTables , pudEntries )
276+ } else {
277+ pudEntries = w .pageTables .Allocator .LookupPTEs (pgdEntry .Address ()) // escapes: see above.
278+ }
279+ // Map the next level.
280+ ok , clearPUDEntries := w .walkPUDs (pudEntries , start , nextBoundary )
281+ if ! ok {
282+ return false
270283 }
271284
272- // Allocate a new pgd.
273- pudEntries = w .pageTables .Allocator .NewPTEs () // escapes: depends on allocator.
274- pgdEntry .setPageTable (w .pageTables , pudEntries )
285+ // Check if we no longer need this page table.
286+ if clearPUDEntries == entriesPerPage {
287+ pgdEntry .Clear ()
288+ w .pageTables .Allocator .FreePTEs (pudEntries ) // escapes: see above.
289+ }
275290 } else {
276- pudEntries = w .pageTables .Allocator .LookupPTEs (pgdEntry .Address ()) // escapes: see above.
277- }
291+ var p4dEntries * PTEs
292+ if ! pgdEntry .Valid () {
293+ if ! w .visitor .requiresAlloc () {
294+ // Skip over this entry.
295+ start = nextBoundary
296+ continue
297+ }
278298
279- // Map the next level.
280- ok , clearPUDEntries := w .walkPUDs (pudEntries , start , nextBoundary )
281- if ! ok {
282- return false
283- }
299+ // Allocate a new pgd.
300+ p4dEntries = w .pageTables .Allocator .NewPTEs () // escapes: depends on allocator.
301+ pgdEntry .setPageTable (w .pageTables , p4dEntries )
302+ } else {
303+ p4dEntries = w .pageTables .Allocator .LookupPTEs (pgdEntry .Address ()) // escapes: see above.
304+ }
305+ var clearP4DEntries uint16 = 0
306+ p4dStart := start
307+ p4dEnd := nextBoundary
308+ for p4dStart < p4dEnd {
309+ nextP4DBoundary := addrEnd (p4dStart , p4dEnd , p4dSize )
310+ p4dIndex := uint16 ((p4dStart & p4dMask ) >> p4dShift )
311+ p4dEntry := & p4dEntries [p4dIndex ]
312+ if ! p4dEntry .Valid () {
313+ if ! w .visitor .requiresAlloc () {
314+ // Skip over this entry.
315+ clearP4DEntries ++
316+ p4dStart = nextP4DBoundary
317+ continue
318+ }
319+ // Allocate a new pud.
320+ pudEntries = w .pageTables .Allocator .NewPTEs () // escapes: depends on allocator.
321+ p4dEntry .setPageTable (w .pageTables , pudEntries )
322+ } else {
323+ pudEntries = w .pageTables .Allocator .LookupPTEs (p4dEntry .Address ()) // escapes: see above.
324+ }
325+
326+ ok , clearPUDEntries := w .walkPUDs (pudEntries , p4dStart , nextP4DBoundary )
327+ if ! ok {
328+ return false
329+ }
330+ if clearPUDEntries == entriesPerPage {
331+ p4dEntry .Clear ()
332+ w .pageTables .Allocator .FreePTEs (pudEntries ) // escapes: see above.
333+ clearP4DEntries ++
334+ }
284335
285- // Check if we no longer need this page table.
286- if clearPUDEntries == entriesPerPage {
287- pgdEntry .Clear ()
288- w .pageTables .Allocator .FreePTEs (pudEntries ) // escapes: see above.
336+ p4dStart = nextP4DBoundary
337+ }
338+
339+ // Check if we no longer need this page table.
340+ if clearP4DEntries == entriesPerPage {
341+ pgdEntry .Clear ()
342+ w .pageTables .Allocator .FreePTEs (p4dEntries ) // escapes: see above.
343+ }
289344 }
290345
291346 // Advance to the next PGD entry's range for the next loop.
0 commit comments