diff options
Diffstat (limited to 'drivers/xen/balloon.c')
-rw-r--r-- | drivers/xen/balloon.c | 65 |
1 files changed, 56 insertions, 9 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index f77e499afddd..065f0b607373 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
@@ -257,10 +257,25 @@ static void release_memory_resource(struct resource *resource) | |||
257 | kfree(resource); | 257 | kfree(resource); |
258 | } | 258 | } |
259 | 259 | ||
260 | /* | ||
261 | * Host memory not allocated to dom0. We can use this range for hotplug-based | ||
262 | * ballooning. | ||
263 | * | ||
264 | * It's a type-less resource. Setting IORESOURCE_MEM will make resource | ||
265 | * management algorithms (arch_remove_reservations()) look into guest e820, | ||
266 | * which we don't want. | ||
267 | */ | ||
268 | static struct resource hostmem_resource = { | ||
269 | .name = "Host RAM", | ||
270 | }; | ||
271 | |||
272 | void __attribute__((weak)) __init arch_xen_balloon_init(struct resource *res) | ||
273 | {} | ||
274 | |||
260 | static struct resource *additional_memory_resource(phys_addr_t size) | 275 | static struct resource *additional_memory_resource(phys_addr_t size) |
261 | { | 276 | { |
262 | struct resource *res; | 277 | struct resource *res, *res_hostmem; |
263 | int ret; | 278 | int ret = -ENOMEM; |
264 | 279 | ||
265 | res = kzalloc(sizeof(*res), GFP_KERNEL); | 280 | res = kzalloc(sizeof(*res), GFP_KERNEL); |
266 | if (!res) | 281 | if (!res) |
@@ -269,13 +284,42 @@ static struct resource *additional_memory_resource(phys_addr_t size) | |||
269 | res->name = "System RAM"; | 284 | res->name = "System RAM"; |
270 | res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; | 285 | res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; |
271 | 286 | ||
272 | ret = allocate_resource(&iomem_resource, res, | 287 | res_hostmem = kzalloc(sizeof(*res), GFP_KERNEL); |
273 | size, 0, -1, | 288 | if (res_hostmem) { |
274 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); | 289 | /* Try to grab a range from hostmem */ |
275 | if (ret < 0) { | 290 | res_hostmem->name = "Host memory"; |
276 | pr_err("Cannot allocate new System RAM resource\n"); | 291 | ret = allocate_resource(&hostmem_resource, res_hostmem, |
277 | kfree(res); | 292 | size, 0, -1, |
278 | return NULL; | 293 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); |
294 | } | ||
295 | |||
296 | if (!ret) { | ||
297 | /* | ||
298 | * Insert this resource into iomem. Because hostmem_resource | ||
299 | * tracks portion of guest e820 marked as UNUSABLE noone else | ||
300 | * should try to use it. | ||
301 | */ | ||
302 | res->start = res_hostmem->start; | ||
303 | res->end = res_hostmem->end; | ||
304 | ret = insert_resource(&iomem_resource, res); | ||
305 | if (ret < 0) { | ||
306 | pr_err("Can't insert iomem_resource [%llx - %llx]\n", | ||
307 | res->start, res->end); | ||
308 | release_memory_resource(res_hostmem); | ||
309 | res_hostmem = NULL; | ||
310 | res->start = res->end = 0; | ||
311 | } | ||
312 | } | ||
313 | |||
314 | if (ret) { | ||
315 | ret = allocate_resource(&iomem_resource, res, | ||
316 | size, 0, -1, | ||
317 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); | ||
318 | if (ret < 0) { | ||
319 | pr_err("Cannot allocate new System RAM resource\n"); | ||
320 | kfree(res); | ||
321 | return NULL; | ||
322 | } | ||
279 | } | 323 | } |
280 | 324 | ||
281 | #ifdef CONFIG_SPARSEMEM | 325 | #ifdef CONFIG_SPARSEMEM |
@@ -287,6 +331,7 @@ static struct resource *additional_memory_resource(phys_addr_t size) | |||
287 | pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", | 331 | pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", |
288 | pfn, limit); | 332 | pfn, limit); |
289 | release_memory_resource(res); | 333 | release_memory_resource(res); |
334 | release_memory_resource(res_hostmem); | ||
290 | return NULL; | 335 | return NULL; |
291 | } | 336 | } |
292 | } | 337 | } |
@@ -765,6 +810,8 @@ static int __init balloon_init(void) | |||
765 | set_online_page_callback(&xen_online_page); | 810 | set_online_page_callback(&xen_online_page); |
766 | register_memory_notifier(&xen_memory_nb); | 811 | register_memory_notifier(&xen_memory_nb); |
767 | register_sysctl_table(xen_root); | 812 | register_sysctl_table(xen_root); |
813 | |||
814 | arch_xen_balloon_init(&hostmem_resource); | ||
768 | #endif | 815 | #endif |
769 | 816 | ||
770 | #ifdef CONFIG_XEN_PV | 817 | #ifdef CONFIG_XEN_PV |