7 #include <linux/module.h>
8 #include <linux/sched.h>
18 #include <asm/setup.h>
21 #include <asm/xen/hypervisor.h>
22 #include <asm/xen/hypercall.h>
56 #define EXTRA_MEM_RATIO (10)
76 if (i == XEN_EXTRA_MEM_MAX_REGIONS)
85 if (
WARN(mfn == pfn,
"Trying to over-write 1-1 mapping (pfn: %lx)\n", pfn))
94 static unsigned long __init xen_do_chunk(
unsigned long start,
102 unsigned long len = 0;
106 for (pfn = start; pfn <
end; pfn++) {
125 WARN(ret != 1,
"Failed to %s pfn %lx err=%d\n",
126 release ?
"release" :
"populate", pfn, ret);
144 release ?
"Freeing" :
"Populating",
146 release ?
"freed" :
"added");
151 static unsigned long __init xen_release_chunk(
unsigned long start,
154 return xen_do_chunk(start, end,
true);
157 static unsigned long __init xen_populate_chunk(
159 unsigned long max_pfn,
unsigned long *last_pfn,
160 unsigned long credits_left)
164 unsigned long done = 0;
165 unsigned long dest_pfn;
167 for (i = 0, entry = list; i < map_size; i++, entry++) {
173 if (credits_left <= 0)
182 if (e_pfn <= max_pfn)
190 if (s_pfn <= max_pfn) {
194 capacity = e_pfn - s_pfn;
198 if (credits_left < capacity)
199 capacity = credits_left;
201 pfns = xen_do_chunk(dest_pfn, dest_pfn + capacity,
false);
203 *last_pfn = (dest_pfn + pfns);
206 credits_left -= pfns;
211 static void __init xen_set_identity_and_release_chunk(
212 unsigned long start_pfn,
unsigned long end_pfn,
unsigned long nr_pages,
213 unsigned long *released,
unsigned long *identity)
221 for (pfn = start_pfn; pfn <=
max_pfn_mapped && pfn < end_pfn; pfn++)
226 if (start_pfn < nr_pages)
227 *released += xen_release_chunk(
228 start_pfn,
min(end_pfn, nr_pages));
233 static unsigned long __init xen_set_identity_and_release(
234 const struct e820entry *list,
size_t map_size,
unsigned long nr_pages)
237 unsigned long released = 0;
238 unsigned long identity = 0;
253 for (i = 0, entry = list; i < map_size; i++, entry++) {
256 unsigned long start_pfn =
PFN_DOWN(start);
257 unsigned long end_pfn =
PFN_UP(end);
262 if (start_pfn < end_pfn)
263 xen_set_identity_and_release_chunk(
264 start_pfn, end_pfn, nr_pages,
265 &released, &identity);
279 static unsigned long __init xen_get_max_pages(
void)
303 static void xen_align_and_add_e820_region(
u64 start,
u64 size,
int type)
321 static struct e820entry map[E820MAX] __initdata;
327 unsigned long max_pages;
328 unsigned long last_pfn = 0;
329 unsigned long extra_pages = 0;
330 unsigned long populated;
350 map[0].
size += 8ULL << 20;
359 max_pages = xen_get_max_pages();
360 if (max_pages > max_pfn)
361 extra_pages += max_pages -
max_pfn;
374 populated = xen_populate_chunk(map, memmap.
nr_entries,
380 if (last_pfn > max_pfn) {
404 if (addr < mem_end) {
405 size =
min(size, mem_end - addr);
406 }
else if (extra_pages) {
409 xen_add_extra_mem(addr, size);
414 xen_align_and_add_e820_region(addr, size, type);
418 if (map[i].size == 0)
467 static void __init fiddle_vdso(
void)
471 mask = VDSO32_SYMBOL(&vdso32_int80_start, NOTE_MASK);
473 mask = VDSO32_SYMBOL(&vdso32_sysenter_start, NOTE_MASK);
478 static int __cpuinit register_callback(
unsigned type,
const void *
func)
492 unsigned sysenter_feature;
500 if (!boot_cpu_has(sysenter_feature))
505 setup_clear_cpu_cap(sysenter_feature);