Merge tag 'for-linus-4.15-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen fixes from Juergen Gross:
"This contains two fixes for running under Xen:

- a fix avoiding resource conflicts between adding mmio areas and
memory hotplug

- a fix setting NX bits in page table entries copied from Xen when
running a PV guest"

* tag 'for-linus-4.15-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
xen/balloon: Mark unallocated host memory as UNUSABLE
x86-64/Xen: eliminate W+X mappings

Changed files
+159 -13
arch
drivers
xen
include
xen
+81
arch/x86/xen/enlighten.c
··· 1 + #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG 2 + #include <linux/bootmem.h> 3 + #endif 1 4 #include <linux/cpu.h> 2 5 #include <linux/kexec.h> 3 6 4 7 #include <xen/features.h> 5 8 #include <xen/page.h> 9 + #include <xen/interface/memory.h> 6 10 7 11 #include <asm/xen/hypercall.h> 8 12 #include <asm/xen/hypervisor.h> ··· 335 331 } 336 332 EXPORT_SYMBOL(xen_arch_unregister_cpu); 337 333 #endif 334 + 335 + #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG 336 + void __init arch_xen_balloon_init(struct resource *hostmem_resource) 337 + { 338 + struct xen_memory_map memmap; 339 + int rc; 340 + unsigned int i, last_guest_ram; 341 + phys_addr_t max_addr = PFN_PHYS(max_pfn); 342 + struct e820_table *xen_e820_table; 343 + const struct e820_entry *entry; 344 + struct resource *res; 345 + 346 + if (!xen_initial_domain()) 347 + return; 348 + 349 + xen_e820_table = kmalloc(sizeof(*xen_e820_table), GFP_KERNEL); 350 + if (!xen_e820_table) 351 + return; 352 + 353 + memmap.nr_entries = ARRAY_SIZE(xen_e820_table->entries); 354 + set_xen_guest_handle(memmap.buffer, xen_e820_table->entries); 355 + rc = HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap); 356 + if (rc) { 357 + pr_warn("%s: Can't read host e820 (%d)\n", __func__, rc); 358 + goto out; 359 + } 360 + 361 + last_guest_ram = 0; 362 + for (i = 0; i < memmap.nr_entries; i++) { 363 + if (xen_e820_table->entries[i].addr >= max_addr) 364 + break; 365 + if (xen_e820_table->entries[i].type == E820_TYPE_RAM) 366 + last_guest_ram = i; 367 + } 368 + 369 + entry = &xen_e820_table->entries[last_guest_ram]; 370 + if (max_addr >= entry->addr + entry->size) 371 + goto out; /* No unallocated host RAM. */ 372 + 373 + hostmem_resource->start = max_addr; 374 + hostmem_resource->end = entry->addr + entry->size; 375 + 376 + /* 377 + * Mark non-RAM regions between the end of dom0 RAM and end of host RAM 378 + * as unavailable. The rest of that region can be used for hotplug-based 379 + * ballooning. 380 + */ 381 + for (; i < memmap.nr_entries; i++) { 382 + entry = &xen_e820_table->entries[i]; 383 + 384 + if (entry->type == E820_TYPE_RAM) 385 + continue; 386 + 387 + if (entry->addr >= hostmem_resource->end) 388 + break; 389 + 390 + res = kzalloc(sizeof(*res), GFP_KERNEL); 391 + if (!res) 392 + goto out; 393 + 394 + res->name = "Unavailable host RAM"; 395 + res->start = entry->addr; 396 + res->end = (entry->addr + entry->size < hostmem_resource->end) ? 397 + entry->addr + entry->size : hostmem_resource->end; 398 + rc = insert_resource(hostmem_resource, res); 399 + if (rc) { 400 + pr_warn("%s: Can't insert [%llx - %llx) (%d)\n", 401 + __func__, res->start, res->end, rc); 402 + kfree(res); 403 + goto out; 404 + } 405 + } 406 + 407 + out: 408 + kfree(xen_e820_table); 409 + } 410 + #endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */
+3
arch/x86/xen/enlighten_pv.c
··· 88 88 #include "multicalls.h" 89 89 #include "pmu.h" 90 90 91 + #include "../kernel/cpu/cpu.h" /* get_cpu_cap() */ 92 + 91 93 void *xen_initial_gdt; 92 94 93 95 static int xen_cpu_up_prepare_pv(unsigned int cpu); ··· 1260 1258 __userpte_alloc_gfp &= ~__GFP_HIGHMEM; 1261 1259 1262 1260 /* Work out if we support NX */ 1261 + get_cpu_cap(&boot_cpu_data); 1263 1262 x86_configure_nx(); 1264 1263 1265 1264 /* Get mfn list */
+12
arch/x86/xen/mmu_pv.c
··· 1902 1902 /* Graft it onto L4[511][510] */ 1903 1903 copy_page(level2_kernel_pgt, l2); 1904 1904 1905 + /* 1906 + * Zap execute permission from the ident map. Due to the sharing of 1907 + * L1 entries we need to do this in the L2. 1908 + */ 1909 + if (__supported_pte_mask & _PAGE_NX) { 1910 + for (i = 0; i < PTRS_PER_PMD; ++i) { 1911 + if (pmd_none(level2_ident_pgt[i])) 1912 + continue; 1913 + level2_ident_pgt[i] = pmd_set_flags(level2_ident_pgt[i], _PAGE_NX); 1914 + } 1915 + } 1916 + 1905 1917 /* Copy the initial P->M table mappings if necessary. */ 1906 1918 i = pgd_index(xen_start_info->mfn_list); 1907 1919 if (i && i < pgd_index(__START_KERNEL_map))
+2 -4
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; 812 811 813 812 chunk_size = size; 814 813 type = xen_e820_table.entries[i].type; ··· 823 824 xen_add_extra_mem(pfn_s, n_pfns); 824 825 xen_max_p2m_pfn = pfn_s + n_pfns; 825 826 } else 826 - discard = true; 827 + type = E820_TYPE_UNUSABLE; 827 828 } 828 829 829 - if (!discard) 830 - xen_align_and_add_e820_region(addr, chunk_size, type); 830 + xen_align_and_add_e820_region(addr, chunk_size, type); 831 831 832 832 addr += chunk_size; 833 833 size -= chunk_size;
+56 -9
drivers/xen/balloon.c
··· 257 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 275 static struct resource *additional_memory_resource(phys_addr_t size) 261 276 { 262 - struct resource *res; 263 - int ret; 277 + struct resource *res, *res_hostmem; 278 + int ret = -ENOMEM; 264 279 265 280 res = kzalloc(sizeof(*res), GFP_KERNEL); 266 281 if (!res) ··· 284 269 res->name = "System RAM"; 285 270 res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; 286 271 287 - ret = allocate_resource(&iomem_resource, res, 288 - size, 0, -1, 289 - PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); 290 - if (ret < 0) { 291 - pr_err("Cannot allocate new System RAM resource\n"); 292 - kfree(res); 293 - return NULL; 272 + res_hostmem = kzalloc(sizeof(*res), GFP_KERNEL); 273 + if (res_hostmem) { 274 + /* Try to grab a range from hostmem */ 275 + res_hostmem->name = "Host memory"; 276 + ret = allocate_resource(&hostmem_resource, res_hostmem, 277 + size, 0, -1, 278 + PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); 279 + } 280 + 281 + if (!ret) { 282 + /* 283 + * Insert this resource into iomem. Because hostmem_resource 284 + * tracks portion of guest e820 marked as UNUSABLE noone else 285 + * should try to use it. 286 + */ 287 + res->start = res_hostmem->start; 288 + res->end = res_hostmem->end; 289 + ret = insert_resource(&iomem_resource, res); 290 + if (ret < 0) { 291 + pr_err("Can't insert iomem_resource [%llx - %llx]\n", 292 + res->start, res->end); 293 + release_memory_resource(res_hostmem); 294 + res_hostmem = NULL; 295 + res->start = res->end = 0; 296 + } 297 + } 298 + 299 + if (ret) { 300 + ret = allocate_resource(&iomem_resource, res, 301 + size, 0, -1, 302 + PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); 303 + if (ret < 0) { 304 + pr_err("Cannot allocate new System RAM resource\n"); 305 + kfree(res); 306 + return NULL; 307 + } 294 308 } 295 309 296 310 #ifdef CONFIG_SPARSEMEM ··· 331 287 pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", 332 288 pfn, limit); 333 289 release_memory_resource(res); 290 + release_memory_resource(res_hostmem); 334 291 return NULL; 335 292 } 336 293 } ··· 810 765 set_online_page_callback(&xen_online_page); 811 766 register_memory_notifier(&xen_memory_nb); 812 767 register_sysctl_table(xen_root); 768 + 769 + arch_xen_balloon_init(&hostmem_resource); 813 770 #endif 814 771 815 772 #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