Merge remote-tracking branches 'spi/topic/spidev', 'spi/topic/st-ssc4' and 'spi/topic...
[sfrench/cifs-2.6.git] / arch / x86 / mm / init_64.c
index 41270b96403d15a9b497810f29bcee51adcc1ce8..0a59daf799f8ed95ad6cef315ff23818e1a110ea 100644 (file)
@@ -94,10 +94,10 @@ __setup("noexec32=", nonx32_setup);
  */
 void sync_global_pgds(unsigned long start, unsigned long end)
 {
-       unsigned long address;
+       unsigned long addr;
 
-       for (address = start; address <= end; address += PGDIR_SIZE) {
-               pgd_t *pgd_ref = pgd_offset_k(address);
+       for (addr = start; addr <= end; addr = ALIGN(addr + 1, PGDIR_SIZE)) {
+               pgd_t *pgd_ref = pgd_offset_k(addr);
                const p4d_t *p4d_ref;
                struct page *page;
 
@@ -106,7 +106,7 @@ void sync_global_pgds(unsigned long start, unsigned long end)
                 * handle synchonization on p4d level.
                 */
                BUILD_BUG_ON(pgd_none(*pgd_ref));
-               p4d_ref = p4d_offset(pgd_ref, address);
+               p4d_ref = p4d_offset(pgd_ref, addr);
 
                if (p4d_none(*p4d_ref))
                        continue;
@@ -117,8 +117,8 @@ void sync_global_pgds(unsigned long start, unsigned long end)
                        p4d_t *p4d;
                        spinlock_t *pgt_lock;
 
-                       pgd = (pgd_t *)page_address(page) + pgd_index(address);
-                       p4d = p4d_offset(pgd, address);
+                       pgd = (pgd_t *)page_address(page) + pgd_index(addr);
+                       p4d = p4d_offset(pgd, addr);
                        /* the pgt_lock only for Xen */
                        pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
                        spin_lock(pgt_lock);
@@ -990,7 +990,13 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end,
 
                pud_base = pud_offset(p4d, 0);
                remove_pud_table(pud_base, addr, next, direct);
-               free_pud_table(pud_base, p4d);
+               /*
+                * For 4-level page tables we do not want to free PUDs, but in the
+                * 5-level case we should free them. This code will have to change
+                * to adapt for boot-time switching between 4 and 5 level page tables.
+                */
+               if (CONFIG_PGTABLE_LEVELS == 5)
+                       free_pud_table(pud_base, p4d);
        }
 
        if (direct)