diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-08-31 03:45:21 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-08-31 03:45:46 -0400 |
commit | daab7fc734a53fdeaf844b7c03053118ad1769da (patch) | |
tree | 575deb3cdcc6dda562acaed6f7c29bc81ae01cf2 /arch/x86/xen/setup.c | |
parent | 774ea0bcb27f57b6fd521b3b6c43237782fed4b9 (diff) | |
parent | 2bfc96a127bc1cc94d26bfaa40159966064f9c8c (diff) |
Merge commit 'v2.6.36-rc3' into x86/memblock
Conflicts:
arch/x86/kernel/trampoline.c
mm/memblock.c
Merge reason: Resolve the conflicts, update to latest upstream.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/xen/setup.c')
-rw-r--r-- | arch/x86/xen/setup.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 2ac8f29f89cb..9729c903404b 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <xen/page.h> | 21 | #include <xen/page.h> |
22 | #include <xen/interface/callback.h> | 22 | #include <xen/interface/callback.h> |
23 | #include <xen/interface/physdev.h> | 23 | #include <xen/interface/physdev.h> |
24 | #include <xen/interface/memory.h> | ||
24 | #include <xen/features.h> | 25 | #include <xen/features.h> |
25 | 26 | ||
26 | #include "xen-ops.h" | 27 | #include "xen-ops.h" |
@@ -33,6 +34,73 @@ extern void xen_sysenter_target(void); | |||
33 | extern void xen_syscall_target(void); | 34 | extern void xen_syscall_target(void); |
34 | extern void xen_syscall32_target(void); | 35 | extern void xen_syscall32_target(void); |
35 | 36 | ||
37 | static unsigned long __init xen_release_chunk(phys_addr_t start_addr, | ||
38 | phys_addr_t end_addr) | ||
39 | { | ||
40 | struct xen_memory_reservation reservation = { | ||
41 | .address_bits = 0, | ||
42 | .extent_order = 0, | ||
43 | .domid = DOMID_SELF | ||
44 | }; | ||
45 | unsigned long start, end; | ||
46 | unsigned long len = 0; | ||
47 | unsigned long pfn; | ||
48 | int ret; | ||
49 | |||
50 | start = PFN_UP(start_addr); | ||
51 | end = PFN_DOWN(end_addr); | ||
52 | |||
53 | if (end <= start) | ||
54 | return 0; | ||
55 | |||
56 | printk(KERN_INFO "xen_release_chunk: looking at area pfn %lx-%lx: ", | ||
57 | start, end); | ||
58 | for(pfn = start; pfn < end; pfn++) { | ||
59 | unsigned long mfn = pfn_to_mfn(pfn); | ||
60 | |||
61 | /* Make sure pfn exists to start with */ | ||
62 | if (mfn == INVALID_P2M_ENTRY || mfn_to_pfn(mfn) != pfn) | ||
63 | continue; | ||
64 | |||
65 | set_xen_guest_handle(reservation.extent_start, &mfn); | ||
66 | reservation.nr_extents = 1; | ||
67 | |||
68 | ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, | ||
69 | &reservation); | ||
70 | WARN(ret != 1, "Failed to release memory %lx-%lx err=%d\n", | ||
71 | start, end, ret); | ||
72 | if (ret == 1) { | ||
73 | set_phys_to_machine(pfn, INVALID_P2M_ENTRY); | ||
74 | len++; | ||
75 | } | ||
76 | } | ||
77 | printk(KERN_CONT "%ld pages freed\n", len); | ||
78 | |||
79 | return len; | ||
80 | } | ||
81 | |||
82 | static unsigned long __init xen_return_unused_memory(unsigned long max_pfn, | ||
83 | const struct e820map *e820) | ||
84 | { | ||
85 | phys_addr_t max_addr = PFN_PHYS(max_pfn); | ||
86 | phys_addr_t last_end = 0; | ||
87 | unsigned long released = 0; | ||
88 | int i; | ||
89 | |||
90 | for (i = 0; i < e820->nr_map && last_end < max_addr; i++) { | ||
91 | phys_addr_t end = e820->map[i].addr; | ||
92 | end = min(max_addr, end); | ||
93 | |||
94 | released += xen_release_chunk(last_end, end); | ||
95 | last_end = e820->map[i].addr + e820->map[i].size; | ||
96 | } | ||
97 | |||
98 | if (last_end < max_addr) | ||
99 | released += xen_release_chunk(last_end, max_addr); | ||
100 | |||
101 | printk(KERN_INFO "released %ld pages of unused memory\n", released); | ||
102 | return released; | ||
103 | } | ||
36 | 104 | ||
37 | /** | 105 | /** |
38 | * machine_specific_memory_setup - Hook for machine specific memory setup. | 106 | * machine_specific_memory_setup - Hook for machine specific memory setup. |
@@ -68,6 +136,8 @@ char * __init xen_memory_setup(void) | |||
68 | 136 | ||
69 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); | 137 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); |
70 | 138 | ||
139 | xen_return_unused_memory(xen_start_info->nr_pages, &e820); | ||
140 | |||
71 | return "Xen"; | 141 | return "Xen"; |
72 | } | 142 | } |
73 | 143 | ||
@@ -157,6 +227,8 @@ void __init xen_arch_setup(void) | |||
157 | struct physdev_set_iopl set_iopl; | 227 | struct physdev_set_iopl set_iopl; |
158 | int rc; | 228 | int rc; |
159 | 229 | ||
230 | xen_panic_handler_init(); | ||
231 | |||
160 | HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); | 232 | HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); |
161 | HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); | 233 | HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); |
162 | 234 | ||