]>
Commit | Line | Data |
---|---|---|
cc90b958 BS |
1 | From: jbeulich@novell.com |
2 | Subject: fix issues with the assignment of huge amounts of memory | |
3 | Patch-mainline: obsolete | |
4 | ||
5 | At the same time remove the non-applicable and broken support for the | |
6 | memmap= command line option. | |
7 | Also fix the overlap of the modules area with the fixmaps on x86-64. | |
8 | ||
9 | Index: head-2008-11-25/arch/x86/kernel/e820-xen.c | |
10 | =================================================================== | |
11 | --- head-2008-11-25.orig/arch/x86/kernel/e820-xen.c 2008-11-27 10:20:43.000000000 +0100 | |
12 | +++ head-2008-11-25/arch/x86/kernel/e820-xen.c 2008-11-25 13:18:07.000000000 +0100 | |
13 | @@ -1235,6 +1235,26 @@ static int __init parse_memopt(char *p) | |
14 | ||
15 | i = e820.nr_map - 1; | |
16 | current_end = e820.map[i].addr + e820.map[i].size; | |
17 | + | |
18 | + /* | |
19 | + * A little less than 2% of available memory are needed for page | |
20 | + * tables, p2m map, and mem_map. Hence the maximum amount of memory | |
21 | + * we can potentially balloon up to can in no case exceed about 50 | |
22 | + * times of what we've been given initially. Since even with that we | |
23 | + * won't be able to boot (due to various calculations done based on | |
24 | + * the total number of pages) we further restrict this to factor 32. | |
25 | + */ | |
26 | + if ((mem_size >> (PAGE_SHIFT + 5)) > xen_start_info->nr_pages) { | |
27 | + u64 size = (u64)xen_start_info->nr_pages << 5; | |
28 | + | |
29 | + printk(KERN_WARNING "mem=%Luk is invalid for an initial" | |
30 | + " allocation of %luk, using %Luk\n", | |
31 | + (unsigned long long)mem_size >> 10, | |
32 | + xen_start_info->nr_pages << (PAGE_SHIFT - 10), | |
33 | + (unsigned long long)size << (PAGE_SHIFT - 10)); | |
34 | + mem_size = size << PAGE_SHIFT; | |
35 | + } | |
36 | + | |
37 | if (current_end < mem_size) { | |
38 | /* | |
39 | * The e820 map ends before our requested size so | |
40 | @@ -1294,6 +1314,7 @@ static int __init parse_memmap_opt(char | |
41 | return *p == '\0' ? 0 : -EINVAL; | |
42 | } | |
43 | early_param("memmap", parse_memmap_opt); | |
44 | +#endif | |
45 | ||
46 | void __init finish_e820_parsing(void) | |
47 | { | |
48 | @@ -1308,7 +1329,6 @@ void __init finish_e820_parsing(void) | |
49 | e820_print_map("user"); | |
50 | } | |
51 | } | |
52 | -#endif | |
53 | ||
54 | static inline const char *e820_type_to_string(int e820_type) | |
55 | { | |
56 | Index: head-2008-11-25/arch/x86/kernel/setup-xen.c | |
57 | =================================================================== | |
58 | --- head-2008-11-25.orig/arch/x86/kernel/setup-xen.c 2008-11-17 13:58:02.000000000 +0100 | |
59 | +++ head-2008-11-25/arch/x86/kernel/setup-xen.c 2008-11-27 10:26:10.000000000 +0100 | |
60 | @@ -128,12 +128,7 @@ static struct notifier_block xen_panic_b | |
61 | unsigned long *phys_to_machine_mapping; | |
62 | EXPORT_SYMBOL(phys_to_machine_mapping); | |
63 | ||
64 | -unsigned long *pfn_to_mfn_frame_list_list, | |
65 | -#ifdef CONFIG_X86_64 | |
66 | - *pfn_to_mfn_frame_list[512]; | |
67 | -#else | |
68 | - *pfn_to_mfn_frame_list[128]; | |
69 | -#endif | |
70 | +unsigned long *pfn_to_mfn_frame_list_list, **pfn_to_mfn_frame_list; | |
71 | ||
72 | /* Raw start-of-day parameters from the hypervisor. */ | |
73 | start_info_t *xen_start_info; | |
74 | @@ -1055,17 +1050,17 @@ void __init setup_arch(char **cmdline_p) | |
75 | p2m_pages = xen_start_info->nr_pages; | |
76 | ||
77 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { | |
78 | - unsigned long i, j; | |
79 | + unsigned long i, j, size; | |
80 | unsigned int k, fpp; | |
81 | ||
82 | /* Make sure we have a large enough P->M table. */ | |
83 | phys_to_machine_mapping = alloc_bootmem_pages( | |
84 | max_pfn * sizeof(unsigned long)); | |
85 | - memset(phys_to_machine_mapping, ~0, | |
86 | - max_pfn * sizeof(unsigned long)); | |
87 | memcpy(phys_to_machine_mapping, | |
88 | (unsigned long *)xen_start_info->mfn_list, | |
89 | p2m_pages * sizeof(unsigned long)); | |
90 | + memset(phys_to_machine_mapping + p2m_pages, ~0, | |
91 | + (max_pfn - p2m_pages) * sizeof(unsigned long)); | |
92 | free_bootmem( | |
93 | __pa(xen_start_info->mfn_list), | |
94 | PFN_PHYS(PFN_UP(xen_start_info->nr_pages * | |
95 | @@ -1075,15 +1070,26 @@ void __init setup_arch(char **cmdline_p) | |
96 | * Initialise the list of the frames that specify the list of | |
97 | * frames that make up the p2m table. Used by save/restore. | |
98 | */ | |
99 | - pfn_to_mfn_frame_list_list = alloc_bootmem_pages(PAGE_SIZE); | |
100 | - | |
101 | fpp = PAGE_SIZE/sizeof(unsigned long); | |
102 | + size = (max_pfn + fpp - 1) / fpp; | |
103 | + size = (size + fpp - 1) / fpp; | |
104 | + ++size; /* include a zero terminator for crash tools */ | |
105 | + size *= sizeof(unsigned long); | |
106 | + pfn_to_mfn_frame_list_list = alloc_bootmem_pages(size); | |
107 | + if (size > PAGE_SIZE | |
108 | + && xen_create_contiguous_region((unsigned long) | |
109 | + pfn_to_mfn_frame_list_list, | |
110 | + get_order(size), 0)) | |
111 | + BUG(); | |
112 | + size -= sizeof(unsigned long); | |
113 | + pfn_to_mfn_frame_list = alloc_bootmem(size); | |
114 | + | |
115 | for (i = j = 0, k = -1; i < max_pfn; i += fpp, j++) { | |
116 | if (j == fpp) | |
117 | j = 0; | |
118 | if (j == 0) { | |
119 | k++; | |
120 | - BUG_ON(k>=ARRAY_SIZE(pfn_to_mfn_frame_list)); | |
121 | + BUG_ON(k * sizeof(unsigned long) >= size); | |
122 | pfn_to_mfn_frame_list[k] = | |
123 | alloc_bootmem_pages(PAGE_SIZE); | |
124 | pfn_to_mfn_frame_list_list[k] = | |
125 | Index: head-2008-11-25/arch/x86/mm/init_64-xen.c | |
126 | =================================================================== | |
127 | --- head-2008-11-25.orig/arch/x86/mm/init_64-xen.c 2008-11-17 13:58:22.000000000 +0100 | |
128 | +++ head-2008-11-25/arch/x86/mm/init_64-xen.c 2008-11-25 13:18:07.000000000 +0100 | |
129 | @@ -660,6 +660,13 @@ static void __init extend_init_mapping(u | |
130 | while (va < (__START_KERNEL_map | |
131 | + (table_cur << PAGE_SHIFT) | |
132 | + tables_space)) { | |
133 | + if (!pmd_index(va) && !pte_index(va)) { | |
134 | + page = (unsigned long *)init_level4_pgt; | |
135 | + addr = page[pgd_index(va)]; | |
136 | + addr_to_page(addr, page); | |
137 | + addr = page[pud_index(va)]; | |
138 | + addr_to_page(addr, page); | |
139 | + } | |
140 | pmd = (pmd_t *)&page[pmd_index(va)]; | |
141 | if (pmd_none(*pmd)) { | |
142 | pte_page = alloc_static_page(&phys); | |
143 | Index: head-2008-11-25/drivers/xen/core/machine_reboot.c | |
144 | =================================================================== | |
145 | --- head-2008-11-25.orig/drivers/xen/core/machine_reboot.c 2008-11-18 18:17:30.000000000 +0100 | |
146 | +++ head-2008-11-25/drivers/xen/core/machine_reboot.c 2008-11-25 13:18:07.000000000 +0100 | |
147 | @@ -84,7 +84,7 @@ static void post_suspend(int suspend_can | |
148 | unsigned long shinfo_mfn; | |
149 | extern unsigned long max_pfn; | |
150 | extern unsigned long *pfn_to_mfn_frame_list_list; | |
151 | - extern unsigned long *pfn_to_mfn_frame_list[]; | |
152 | + extern unsigned long **pfn_to_mfn_frame_list; | |
153 | ||
154 | if (suspend_cancelled) { | |
155 | xen_start_info->store_mfn = | |
156 | Index: head-2008-11-25/include/asm-x86/mach-xen/asm/pgtable_64.h | |
157 | =================================================================== | |
158 | --- head-2008-11-25.orig/include/asm-x86/mach-xen/asm/pgtable_64.h 2008-11-18 17:46:21.000000000 +0100 | |
159 | +++ head-2008-11-25/include/asm-x86/mach-xen/asm/pgtable_64.h 2008-11-25 13:18:07.000000000 +0100 | |
160 | @@ -158,7 +158,7 @@ static inline void xen_set_pgd(pgd_t *pg | |
161 | #define PGDIR_MASK (~(PGDIR_SIZE - 1)) | |
162 | ||
163 | ||
164 | -#define MAXMEM _AC(0x00003fffffffffff, UL) | |
165 | +#define MAXMEM _AC(0x000000dfffffffff, UL) | |
166 | #define VMALLOC_START _AC(0xffffc20000000000, UL) | |
167 | #define VMALLOC_END _AC(0xffffe1ffffffffff, UL) | |
168 | #define VMEMMAP_START _AC(0xffffe20000000000, UL) |