summaryrefslogtreecommitdiffstats
path: root/drivers/xen/balloon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen/balloon.c')
-rw-r--r--drivers/xen/balloon.c65
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 */
268static struct resource hostmem_resource = {
269 .name = "Host RAM",
270};
271
272void __attribute__((weak)) __init arch_xen_balloon_init(struct resource *res)
273{}
274
260static struct resource *additional_memory_resource(phys_addr_t size) 275static 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