Right now pgd_alloc() uses pgd_ctor(), which copies over the
current swapper_pg_dir[] to a new task's PGD.

This is not necessary, it's enough if we clear it: the PGD will
then be properly updated by arch_pgd_init_late().

Cc: Andrew Morton <a...@linux-foundation.org>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brge...@gmail.com>
Cc: Denys Vlasenko <dvlas...@redhat.com>
Cc: H. Peter Anvin <h...@zytor.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Rik van Riel <r...@redhat.com>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Waiman Long <waiman.l...@hp.com>
Cc: linux...@vger.kernel.org
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 arch/x86/mm/pgtable.c | 27 +++++++++------------------
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 0666f7796806..b1bd35f452ef 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -87,20 +87,6 @@ void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
 #define UNSHARED_PTRS_PER_PGD                          \
        (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
 
-static void pgd_ctor(struct mm_struct *mm, pgd_t *pgd)
-{
-       /* If the pgd points to a shared pagetable level (either the
-          ptes in non-PAE, or shared PMD in PAE), then just copy the
-          references from swapper_pg_dir. */
-       if (CONFIG_PGTABLE_LEVELS == 2 ||
-           (CONFIG_PGTABLE_LEVELS == 3 && SHARED_KERNEL_PMD) ||
-           CONFIG_PGTABLE_LEVELS == 4) {
-               clone_pgd_range(pgd + KERNEL_PGD_BOUNDARY,
-                               swapper_pg_dir + KERNEL_PGD_BOUNDARY,
-                               KERNEL_PGD_PTRS);
-       }
-}
-
 /*
  * List of all pgd's needed for non-PAE so it can invalidate entries
  * in both cached and uncached pgd's; not needed for PAE since the
@@ -328,11 +314,16 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
                goto out_free_pmds;
 
        /*
-        * No locking is needed here, as the PGD is still private,
-        * so no code walking the task list and looking at mm->pgd
-        * will be able to see it before it's fully constructed:
+        * Zero out the kernel portion here, we'll set them up in
+        * arch_pgd_init_late(), when the pgd is globally
+        * visible already per the task list, so that it cannot
+        * miss updates.
+        *
+        * We need to zero it here, to make sure arch_pgd_init_late()
+        * can initialize them without locking.
         */
-       pgd_ctor(mm, pgd);
+       memset(pgd + KERNEL_PGD_BOUNDARY, 0, KERNEL_PGD_PTRS*sizeof(pgd_t));
+
        pgd_prepopulate_pmd(mm, pgd, pmds);
 
        return pgd;
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to