aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/pgtable_64.h3
-rw-r--r--arch/x86/mm/fault.c2
-rw-r--r--arch/x86/mm/init_64.c24
3 files changed, 9 insertions, 20 deletions
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index 1cc82ece9ac1..62b775926045 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -116,8 +116,7 @@ static inline void native_pgd_clear(pgd_t *pgd)
116 native_set_pgd(pgd, native_make_pgd(0)); 116 native_set_pgd(pgd, native_make_pgd(0));
117} 117}
118 118
119extern void sync_global_pgds(unsigned long start, unsigned long end, 119extern void sync_global_pgds(unsigned long start, unsigned long end);
120 int removed);
121 120
122/* 121/*
123 * Conversion functions: convert a page and protection to a page entry, 122 * Conversion functions: convert a page and protection to a page entry,
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 17c55a536fdd..e3254ca0eec4 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -413,7 +413,7 @@ out:
413 413
414void vmalloc_sync_all(void) 414void vmalloc_sync_all(void)
415{ 415{
416 sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END, 0); 416 sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END);
417} 417}
418 418
419/* 419/*
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 14b9dd71d9e8..963895f9af7f 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -89,10 +89,10 @@ static int __init nonx32_setup(char *str)
89__setup("noexec32=", nonx32_setup); 89__setup("noexec32=", nonx32_setup);
90 90
91/* 91/*
92 * When memory was added/removed make sure all the processes MM have 92 * When memory was added make sure all the processes MM have
93 * suitable PGD entries in the local PGD level page. 93 * suitable PGD entries in the local PGD level page.
94 */ 94 */
95void sync_global_pgds(unsigned long start, unsigned long end, int removed) 95void sync_global_pgds(unsigned long start, unsigned long end)
96{ 96{
97 unsigned long address; 97 unsigned long address;
98 98
@@ -100,12 +100,7 @@ void sync_global_pgds(unsigned long start, unsigned long end, int removed)
100 const pgd_t *pgd_ref = pgd_offset_k(address); 100 const pgd_t *pgd_ref = pgd_offset_k(address);
101 struct page *page; 101 struct page *page;
102 102
103 /* 103 if (pgd_none(*pgd_ref))
104 * When it is called after memory hot remove, pgd_none()
105 * returns true. In this case (removed == 1), we must clear
106 * the PGD entries in the local PGD level page.
107 */
108 if (pgd_none(*pgd_ref) && !removed)
109 continue; 104 continue;
110 105
111 spin_lock(&pgd_lock); 106 spin_lock(&pgd_lock);
@@ -122,13 +117,8 @@ void sync_global_pgds(unsigned long start, unsigned long end, int removed)
122 BUG_ON(pgd_page_vaddr(*pgd) 117 BUG_ON(pgd_page_vaddr(*pgd)
123 != pgd_page_vaddr(*pgd_ref)); 118 != pgd_page_vaddr(*pgd_ref));
124 119
125 if (removed) { 120 if (pgd_none(*pgd))
126 if (pgd_none(*pgd_ref) && !pgd_none(*pgd)) 121 set_pgd(pgd, *pgd_ref);
127 pgd_clear(pgd);
128 } else {
129 if (pgd_none(*pgd))
130 set_pgd(pgd, *pgd_ref);
131 }
132 122
133 spin_unlock(pgt_lock); 123 spin_unlock(pgt_lock);
134 } 124 }
@@ -596,7 +586,7 @@ kernel_physical_mapping_init(unsigned long paddr_start,
596 } 586 }
597 587
598 if (pgd_changed) 588 if (pgd_changed)
599 sync_global_pgds(vaddr_start, vaddr_end - 1, 0); 589 sync_global_pgds(vaddr_start, vaddr_end - 1);
600 590
601 __flush_tlb_all(); 591 __flush_tlb_all();
602 592
@@ -1239,7 +1229,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
1239 } else 1229 } else
1240 err = vmemmap_populate_basepages(start, end, node); 1230 err = vmemmap_populate_basepages(start, end, node);
1241 if (!err) 1231 if (!err)
1242 sync_global_pgds(start, end - 1, 0); 1232 sync_global_pgds(start, end - 1);
1243 return err; 1233 return err;
1244} 1234}
1245 1235