diff options
Diffstat (limited to 'arch/x86/xen/setup.c')
-rw-r--r-- | arch/x86/xen/setup.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 60aeeb56948..e1913024687 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/pm.h> | 10 | #include <linux/pm.h> |
11 | #include <linux/memblock.h> | 11 | #include <linux/memblock.h> |
12 | #include <linux/cpuidle.h> | ||
12 | 13 | ||
13 | #include <asm/elf.h> | 14 | #include <asm/elf.h> |
14 | #include <asm/vdso.h> | 15 | #include <asm/vdso.h> |
@@ -92,8 +93,6 @@ static unsigned long __init xen_release_chunk(phys_addr_t start_addr, | |||
92 | if (end <= start) | 93 | if (end <= start) |
93 | return 0; | 94 | return 0; |
94 | 95 | ||
95 | printk(KERN_INFO "xen_release_chunk: looking at area pfn %lx-%lx: ", | ||
96 | start, end); | ||
97 | for(pfn = start; pfn < end; pfn++) { | 96 | for(pfn = start; pfn < end; pfn++) { |
98 | unsigned long mfn = pfn_to_mfn(pfn); | 97 | unsigned long mfn = pfn_to_mfn(pfn); |
99 | 98 | ||
@@ -106,14 +105,14 @@ static unsigned long __init xen_release_chunk(phys_addr_t start_addr, | |||
106 | 105 | ||
107 | ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, | 106 | ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, |
108 | &reservation); | 107 | &reservation); |
109 | WARN(ret != 1, "Failed to release memory %lx-%lx err=%d\n", | 108 | WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret); |
110 | start, end, ret); | ||
111 | if (ret == 1) { | 109 | if (ret == 1) { |
112 | __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); | 110 | __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); |
113 | len++; | 111 | len++; |
114 | } | 112 | } |
115 | } | 113 | } |
116 | printk(KERN_CONT "%ld pages freed\n", len); | 114 | printk(KERN_INFO "Freeing %lx-%lx pfn range: %lu pages freed\n", |
115 | start, end, len); | ||
117 | 116 | ||
118 | return len; | 117 | return len; |
119 | } | 118 | } |
@@ -139,7 +138,7 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn, | |||
139 | if (last_end < max_addr) | 138 | if (last_end < max_addr) |
140 | released += xen_release_chunk(last_end, max_addr); | 139 | released += xen_release_chunk(last_end, max_addr); |
141 | 140 | ||
142 | printk(KERN_INFO "released %ld pages of unused memory\n", released); | 141 | printk(KERN_INFO "released %lu pages of unused memory\n", released); |
143 | return released; | 142 | return released; |
144 | } | 143 | } |
145 | 144 | ||
@@ -185,6 +184,31 @@ static unsigned long __init xen_set_identity(const struct e820entry *list, | |||
185 | PFN_UP(start_pci), PFN_DOWN(last)); | 184 | PFN_UP(start_pci), PFN_DOWN(last)); |
186 | return identity; | 185 | return identity; |
187 | } | 186 | } |
187 | |||
188 | static unsigned long __init xen_get_max_pages(void) | ||
189 | { | ||
190 | unsigned long max_pages = MAX_DOMAIN_PAGES; | ||
191 | domid_t domid = DOMID_SELF; | ||
192 | int ret; | ||
193 | |||
194 | /* | ||
195 | * For the initial domain we use the maximum reservation as | ||
196 | * the maximum page. | ||
197 | * | ||
198 | * For guest domains the current maximum reservation reflects | ||
199 | * the current maximum rather than the static maximum. In this | ||
200 | * case the e820 map provided to us will cover the static | ||
201 | * maximum region. | ||
202 | */ | ||
203 | if (xen_initial_domain()) { | ||
204 | ret = HYPERVISOR_memory_op(XENMEM_maximum_reservation, &domid); | ||
205 | if (ret > 0) | ||
206 | max_pages = ret; | ||
207 | } | ||
208 | |||
209 | return min(max_pages, MAX_DOMAIN_PAGES); | ||
210 | } | ||
211 | |||
188 | /** | 212 | /** |
189 | * machine_specific_memory_setup - Hook for machine specific memory setup. | 213 | * machine_specific_memory_setup - Hook for machine specific memory setup. |
190 | **/ | 214 | **/ |
@@ -293,6 +317,14 @@ char * __init xen_memory_setup(void) | |||
293 | 317 | ||
294 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); | 318 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); |
295 | 319 | ||
320 | extra_limit = xen_get_max_pages(); | ||
321 | if (max_pfn + extra_pages > extra_limit) { | ||
322 | if (extra_limit > max_pfn) | ||
323 | extra_pages = extra_limit - max_pfn; | ||
324 | else | ||
325 | extra_pages = 0; | ||
326 | } | ||
327 | |||
296 | extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820); | 328 | extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820); |
297 | 329 | ||
298 | /* | 330 | /* |
@@ -426,8 +458,8 @@ void __init xen_arch_setup(void) | |||
426 | #ifdef CONFIG_X86_32 | 458 | #ifdef CONFIG_X86_32 |
427 | boot_cpu_data.hlt_works_ok = 1; | 459 | boot_cpu_data.hlt_works_ok = 1; |
428 | #endif | 460 | #endif |
429 | pm_idle = default_idle; | 461 | disable_cpuidle(); |
430 | boot_option_idle_override = IDLE_HALT; | 462 | boot_option_idle_override = IDLE_HALT; |
431 | 463 | WARN_ON(set_pm_idle_to_default()); | |
432 | fiddle_vdso(); | 464 | fiddle_vdso(); |
433 | } | 465 | } |