diff options
| -rw-r--r-- | Documentation/x86/x86_64/mm.txt | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/numa.h | 1 | ||||
| -rw-r--r-- | arch/x86/include/asm/pgtable_32.h | 3 | ||||
| -rw-r--r-- | arch/x86/include/asm/pgtable_64.h | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/e820.c | 7 | ||||
| -rw-r--r-- | arch/x86/mm/fault.c | 2 | ||||
| -rw-r--r-- | arch/x86/mm/init_64.c | 36 | ||||
| -rw-r--r-- | arch/x86/mm/numa.c | 34 | ||||
| -rw-r--r-- | arch/x86/mm/pgtable_32.c | 35 | ||||
| -rw-r--r-- | mm/page_alloc.c | 2 |
10 files changed, 47 insertions, 78 deletions
diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt index afe68ddbe6a4..052ee643a32e 100644 --- a/Documentation/x86/x86_64/mm.txt +++ b/Documentation/x86/x86_64/mm.txt | |||
| @@ -5,7 +5,7 @@ Virtual memory map with 4 level page tables: | |||
| 5 | 5 | ||
| 6 | 0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm | 6 | 0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm |
| 7 | hole caused by [48:63] sign extension | 7 | hole caused by [48:63] sign extension |
| 8 | ffff800000000000 - ffff80ffffffffff (=40 bits) guard hole | 8 | ffff800000000000 - ffff87ffffffffff (=43 bits) guard hole, reserved for hypervisor |
| 9 | ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory | 9 | ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory |
| 10 | ffffc80000000000 - ffffc8ffffffffff (=40 bits) hole | 10 | ffffc80000000000 - ffffc8ffffffffff (=40 bits) hole |
| 11 | ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space | 11 | ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space |
diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h index 4064acae625d..01b493e5a99b 100644 --- a/arch/x86/include/asm/numa.h +++ b/arch/x86/include/asm/numa.h | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | #ifdef CONFIG_NUMA | 9 | #ifdef CONFIG_NUMA |
| 10 | 10 | ||
| 11 | #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) | 11 | #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) |
| 12 | #define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT)) | ||
| 13 | 12 | ||
| 14 | /* | 13 | /* |
| 15 | * Too small node sizes may confuse the VM badly. Usually they | 14 | * Too small node sizes may confuse the VM badly. Usually they |
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h index 9ee322103c6d..b6c0b404898a 100644 --- a/arch/x86/include/asm/pgtable_32.h +++ b/arch/x86/include/asm/pgtable_32.h | |||
| @@ -32,9 +32,6 @@ static inline void pgtable_cache_init(void) { } | |||
| 32 | static inline void check_pgt_cache(void) { } | 32 | static inline void check_pgt_cache(void) { } |
| 33 | void paging_init(void); | 33 | void paging_init(void); |
| 34 | 34 | ||
| 35 | extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t); | ||
| 36 | |||
| 37 | |||
| 38 | /* | 35 | /* |
| 39 | * Define this if things work differently on an i386 and an i486: | 36 | * Define this if things work differently on an i386 and an i486: |
| 40 | * it will (on an i486) warn about kernel memory accesses that are | 37 | * it will (on an i486) warn about kernel memory accesses that are |
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 3874693c0e53..4572b2f30237 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h | |||
| @@ -116,7 +116,8 @@ 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 | ||
| 119 | extern void sync_global_pgds(unsigned long start, unsigned long end); | 119 | extern void sync_global_pgds(unsigned long start, unsigned long end, |
| 120 | int removed); | ||
| 120 | 121 | ||
| 121 | /* | 122 | /* |
| 122 | * Conversion functions: convert a page and protection to a page entry, | 123 | * Conversion functions: convert a page and protection to a page entry, |
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 988c00a1f60d..49f886481615 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
| @@ -682,15 +682,14 @@ void __init parse_e820_ext(u64 phys_addr, u32 data_len) | |||
| 682 | * hibernation (32 bit) or software suspend and suspend to RAM (64 bit). | 682 | * hibernation (32 bit) or software suspend and suspend to RAM (64 bit). |
| 683 | * | 683 | * |
| 684 | * This function requires the e820 map to be sorted and without any | 684 | * This function requires the e820 map to be sorted and without any |
| 685 | * overlapping entries and assumes the first e820 area to be RAM. | 685 | * overlapping entries. |
| 686 | */ | 686 | */ |
| 687 | void __init e820_mark_nosave_regions(unsigned long limit_pfn) | 687 | void __init e820_mark_nosave_regions(unsigned long limit_pfn) |
| 688 | { | 688 | { |
| 689 | int i; | 689 | int i; |
| 690 | unsigned long pfn; | 690 | unsigned long pfn = 0; |
| 691 | 691 | ||
| 692 | pfn = PFN_DOWN(e820.map[0].addr + e820.map[0].size); | 692 | for (i = 0; i < e820.nr_map; i++) { |
| 693 | for (i = 1; i < e820.nr_map; i++) { | ||
| 694 | struct e820entry *ei = &e820.map[i]; | 693 | struct e820entry *ei = &e820.map[i]; |
| 695 | 694 | ||
| 696 | if (pfn < PFN_UP(ei->addr)) | 695 | if (pfn < PFN_UP(ei->addr)) |
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 9c5b32e2bdc0..d973e61e450d 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
| @@ -349,7 +349,7 @@ out: | |||
| 349 | 349 | ||
| 350 | void vmalloc_sync_all(void) | 350 | void vmalloc_sync_all(void) |
| 351 | { | 351 | { |
| 352 | sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END); | 352 | sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END, 0); |
| 353 | } | 353 | } |
| 354 | 354 | ||
| 355 | /* | 355 | /* |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 5d984769cbd8..4cb8763868fc 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
| @@ -178,7 +178,7 @@ __setup("noexec32=", nonx32_setup); | |||
| 178 | * When memory was added/removed make sure all the processes MM have | 178 | * When memory was added/removed make sure all the processes MM have |
| 179 | * suitable PGD entries in the local PGD level page. | 179 | * suitable PGD entries in the local PGD level page. |
| 180 | */ | 180 | */ |
| 181 | void sync_global_pgds(unsigned long start, unsigned long end) | 181 | void sync_global_pgds(unsigned long start, unsigned long end, int removed) |
| 182 | { | 182 | { |
| 183 | unsigned long address; | 183 | unsigned long address; |
| 184 | 184 | ||
| @@ -186,7 +186,12 @@ void sync_global_pgds(unsigned long start, unsigned long end) | |||
| 186 | const pgd_t *pgd_ref = pgd_offset_k(address); | 186 | const pgd_t *pgd_ref = pgd_offset_k(address); |
| 187 | struct page *page; | 187 | struct page *page; |
| 188 | 188 | ||
| 189 | if (pgd_none(*pgd_ref)) | 189 | /* |
| 190 | * When it is called after memory hot remove, pgd_none() | ||
| 191 | * returns true. In this case (removed == 1), we must clear | ||
| 192 | * the PGD entries in the local PGD level page. | ||
| 193 | */ | ||
| 194 | if (pgd_none(*pgd_ref) && !removed) | ||
| 190 | continue; | 195 | continue; |
| 191 | 196 | ||
| 192 | spin_lock(&pgd_lock); | 197 | spin_lock(&pgd_lock); |
| @@ -199,12 +204,18 @@ void sync_global_pgds(unsigned long start, unsigned long end) | |||
| 199 | pgt_lock = &pgd_page_get_mm(page)->page_table_lock; | 204 | pgt_lock = &pgd_page_get_mm(page)->page_table_lock; |
| 200 | spin_lock(pgt_lock); | 205 | spin_lock(pgt_lock); |
| 201 | 206 | ||
| 202 | if (pgd_none(*pgd)) | 207 | if (!pgd_none(*pgd_ref) && !pgd_none(*pgd)) |
| 203 | set_pgd(pgd, *pgd_ref); | ||
| 204 | else | ||
| 205 | BUG_ON(pgd_page_vaddr(*pgd) | 208 | BUG_ON(pgd_page_vaddr(*pgd) |
| 206 | != pgd_page_vaddr(*pgd_ref)); | 209 | != pgd_page_vaddr(*pgd_ref)); |
| 207 | 210 | ||
| 211 | if (removed) { | ||
| 212 | if (pgd_none(*pgd_ref) && !pgd_none(*pgd)) | ||
| 213 | pgd_clear(pgd); | ||
| 214 | } else { | ||
| 215 | if (pgd_none(*pgd)) | ||
| 216 | set_pgd(pgd, *pgd_ref); | ||
| 217 | } | ||
| 218 | |||
| 208 | spin_unlock(pgt_lock); | 219 | spin_unlock(pgt_lock); |
| 209 | } | 220 | } |
| 210 | spin_unlock(&pgd_lock); | 221 | spin_unlock(&pgd_lock); |
| @@ -633,7 +644,7 @@ kernel_physical_mapping_init(unsigned long start, | |||
| 633 | } | 644 | } |
| 634 | 645 | ||
| 635 | if (pgd_changed) | 646 | if (pgd_changed) |
| 636 | sync_global_pgds(addr, end - 1); | 647 | sync_global_pgds(addr, end - 1, 0); |
| 637 | 648 | ||
| 638 | __flush_tlb_all(); | 649 | __flush_tlb_all(); |
| 639 | 650 | ||
| @@ -976,25 +987,26 @@ static void __meminit | |||
| 976 | remove_pagetable(unsigned long start, unsigned long end, bool direct) | 987 | remove_pagetable(unsigned long start, unsigned long end, bool direct) |
| 977 | { | 988 | { |
| 978 | unsigned long next; | 989 | unsigned long next; |
| 990 | unsigned long addr; | ||
| 979 | pgd_t *pgd; | 991 | pgd_t *pgd; |
| 980 | pud_t *pud; | 992 | pud_t *pud; |
| 981 | bool pgd_changed = false; | 993 | bool pgd_changed = false; |
| 982 | 994 | ||
| 983 | for (; start < end; start = next) { | 995 | for (addr = start; addr < end; addr = next) { |
| 984 | next = pgd_addr_end(start, end); | 996 | next = pgd_addr_end(addr, end); |
| 985 | 997 | ||
| 986 | pgd = pgd_offset_k(start); | 998 | pgd = pgd_offset_k(addr); |
| 987 | if (!pgd_present(*pgd)) | 999 | if (!pgd_present(*pgd)) |
| 988 | continue; | 1000 | continue; |
| 989 | 1001 | ||
| 990 | pud = (pud_t *)pgd_page_vaddr(*pgd); | 1002 | pud = (pud_t *)pgd_page_vaddr(*pgd); |
| 991 | remove_pud_table(pud, start, next, direct); | 1003 | remove_pud_table(pud, addr, next, direct); |
