Revert "xen/balloon: Mark unallocated host memory as UNUSABLE"

This reverts commit b3cf8528bb21febb650a7ecbf080d0647be40b9f.

That commit unintentionally broke Xen balloon memory hotplug with
"hotplug_unpopulated" set to 1. As long as "System RAM" resource
got assigned under a new "Unusable memory" resource in IO/Mem tree
any attempt to online this memory would fail due to general kernel
restrictions on having "System RAM" resources as 1st level only.

The original issue that commit has tried to workaround fa564ad96366
("x86/PCI: Enable a 64bit BAR on AMD Family 15h (Models 00-1f, 30-3f,
60-7f)") also got amended by the following 03a551734 ("x86/PCI: Move
and shrink AMD 64-bit window to avoid conflict") which made the
original fix to Xen ballooning unnecessary.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Juergen Gross <jgross@suse.com>

authored by Igor Druzhinin and committed by Juergen Gross 12366410 72791ac8

Changed files
+13 -141
arch
drivers
xen
include
xen
-78
arch/x86/xen/enlighten.c
··· 10 10 #include <xen/xen.h> 11 11 #include <xen/features.h> 12 12 #include <xen/page.h> 13 - #include <xen/interface/memory.h> 14 13 15 14 #include <asm/xen/hypercall.h> 16 15 #include <asm/xen/hypervisor.h> ··· 345 346 } 346 347 EXPORT_SYMBOL(xen_arch_unregister_cpu); 347 348 #endif 348 - 349 - #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG 350 - void __init arch_xen_balloon_init(struct resource *hostmem_resource) 351 - { 352 - struct xen_memory_map memmap; 353 - int rc; 354 - unsigned int i, last_guest_ram; 355 - phys_addr_t max_addr = PFN_PHYS(max_pfn); 356 - struct e820_table *xen_e820_table; 357 - const struct e820_entry *entry; 358 - struct resource *res; 359 - 360 - if (!xen_initial_domain()) 361 - return; 362 - 363 - xen_e820_table = kmalloc(sizeof(*xen_e820_table), GFP_KERNEL); 364 - if (!xen_e820_table) 365 - return; 366 - 367 - memmap.nr_entries = ARRAY_SIZE(xen_e820_table->entries); 368 - set_xen_guest_handle(memmap.buffer, xen_e820_table->entries); 369 - rc = HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap); 370 - if (rc) { 371 - pr_warn("%s: Can't read host e820 (%d)\n", __func__, rc); 372 - goto out; 373 - } 374 - 375 - last_guest_ram = 0; 376 - for (i = 0; i < memmap.nr_entries; i++) { 377 - if (xen_e820_table->entries[i].addr >= max_addr) 378 - break; 379 - if (xen_e820_table->entries[i].type == E820_TYPE_RAM) 380 - last_guest_ram = i; 381 - } 382 - 383 - entry = &xen_e820_table->entries[last_guest_ram]; 384 - if (max_addr >= entry->addr + entry->size) 385 - goto out; /* No unallocated host RAM. */ 386 - 387 - hostmem_resource->start = max_addr; 388 - hostmem_resource->end = entry->addr + entry->size; 389 - 390 - /* 391 - * Mark non-RAM regions between the end of dom0 RAM and end of host RAM 392 - * as unavailable. The rest of that region can be used for hotplug-based 393 - * ballooning. 394 - */ 395 - for (; i < memmap.nr_entries; i++) { 396 - entry = &xen_e820_table->entries[i]; 397 - 398 - if (entry->type == E820_TYPE_RAM) 399 - continue; 400 - 401 - if (entry->addr >= hostmem_resource->end) 402 - break; 403 - 404 - res = kzalloc(sizeof(*res), GFP_KERNEL); 405 - if (!res) 406 - goto out; 407 - 408 - res->name = "Unavailable host RAM"; 409 - res->start = entry->addr; 410 - res->end = (entry->addr + entry->size < hostmem_resource->end) ? 411 - entry->addr + entry->size : hostmem_resource->end; 412 - rc = insert_resource(hostmem_resource, res); 413 - if (rc) { 414 - pr_warn("%s: Can't insert [%llx - %llx) (%d)\n", 415 - __func__, res->start, res->end, rc); 416 - kfree(res); 417 - goto out; 418 - } 419 - } 420 - 421 - out: 422 - kfree(xen_e820_table); 423 - } 424 - #endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */
+4 -2
arch/x86/xen/setup.c
··· 808 808 addr = xen_e820_table.entries[0].addr; 809 809 size = xen_e820_table.entries[0].size; 810 810 while (i < xen_e820_table.nr_entries) { 811 + bool discard = false; 811 812 812 813 chunk_size = size; 813 814 type = xen_e820_table.entries[i].type; ··· 824 823 xen_add_extra_mem(pfn_s, n_pfns); 825 824 xen_max_p2m_pfn = pfn_s + n_pfns; 826 825 } else 827 - type = E820_TYPE_UNUSABLE; 826 + discard = true; 828 827 } 829 828 830 - xen_align_and_add_e820_region(addr, chunk_size, type); 829 + if (!discard) 830 + xen_align_and_add_e820_region(addr, chunk_size, type); 831 831 832 832 addr += chunk_size; 833 833 size -= chunk_size;
+9 -56
drivers/xen/balloon.c
··· 251 251 kfree(resource); 252 252 } 253 253 254 - /* 255 - * Host memory not allocated to dom0. We can use this range for hotplug-based 256 - * ballooning. 257 - * 258 - * It's a type-less resource. Setting IORESOURCE_MEM will make resource 259 - * management algorithms (arch_remove_reservations()) look into guest e820, 260 - * which we don't want. 261 - */ 262 - static struct resource hostmem_resource = { 263 - .name = "Host RAM", 264 - }; 265 - 266 - void __attribute__((weak)) __init arch_xen_balloon_init(struct resource *res) 267 - {} 268 - 269 254 static struct resource *additional_memory_resource(phys_addr_t size) 270 255 { 271 - struct resource *res, *res_hostmem; 272 - int ret = -ENOMEM; 256 + struct resource *res; 257 + int ret; 273 258 274 259 res = kzalloc(sizeof(*res), GFP_KERNEL); 275 260 if (!res) ··· 263 278 res->name = "System RAM"; 264 279 res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; 265 280 266 - res_hostmem = kzalloc(sizeof(*res), GFP_KERNEL); 267 - if (res_hostmem) { 268 - /* Try to grab a range from hostmem */ 269 - res_hostmem->name = "Host memory"; 270 - ret = allocate_resource(&hostmem_resource, res_hostmem, 271 - size, 0, -1, 272 - PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); 273 - } 274 - 275 - if (!ret) { 276 - /* 277 - * Insert this resource into iomem. Because hostmem_resource 278 - * tracks portion of guest e820 marked as UNUSABLE noone else 279 - * should try to use it. 280 - */ 281 - res->start = res_hostmem->start; 282 - res->end = res_hostmem->end; 283 - ret = insert_resource(&iomem_resource, res); 284 - if (ret < 0) { 285 - pr_err("Can't insert iomem_resource [%llx - %llx]\n", 286 - res->start, res->end); 287 - release_memory_resource(res_hostmem); 288 - res_hostmem = NULL; 289 - res->start = res->end = 0; 290 - } 291 - } 292 - 293 - if (ret) { 294 - ret = allocate_resource(&iomem_resource, res, 295 - size, 0, -1, 296 - PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); 297 - if (ret < 0) { 298 - pr_err("Cannot allocate new System RAM resource\n"); 299 - kfree(res); 300 - return NULL; 301 - } 281 + ret = allocate_resource(&iomem_resource, res, 282 + size, 0, -1, 283 + PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); 284 + if (ret < 0) { 285 + pr_err("Cannot allocate new System RAM resource\n"); 286 + kfree(res); 287 + return NULL; 302 288 } 303 289 304 290 #ifdef CONFIG_SPARSEMEM ··· 281 325 pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", 282 326 pfn, limit); 283 327 release_memory_resource(res); 284 - release_memory_resource(res_hostmem); 285 328 return NULL; 286 329 } 287 330 } ··· 702 747 set_online_page_callback(&xen_online_page); 703 748 register_memory_notifier(&xen_memory_nb); 704 749 register_sysctl_table(xen_root); 705 - 706 - arch_xen_balloon_init(&hostmem_resource); 707 750 #endif 708 751 709 752 #ifdef CONFIG_XEN_PV
-5
include/xen/balloon.h
··· 44 44 { 45 45 } 46 46 #endif 47 - 48 - #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG 49 - struct resource; 50 - void arch_xen_balloon_init(struct resource *hostmem_resource); 51 - #endif