diff options
| -rw-r--r-- | arch/x86/xen/enlighten.c | 78 | ||||
| -rw-r--r-- | arch/x86/xen/multicalls.c | 35 | ||||
| -rw-r--r-- | arch/x86/xen/setup.c | 6 | ||||
| -rw-r--r-- | arch/x86/xen/spinlock.c | 7 | ||||
| -rw-r--r-- | drivers/xen/balloon.c | 65 | ||||
| -rw-r--r-- | drivers/xen/pvcalls-front.c | 4 | ||||
| -rw-r--r-- | drivers/xen/xlate_mmu.c | 1 | ||||
| -rw-r--r-- | include/xen/balloon.h | 5 |
8 files changed, 37 insertions, 164 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index e996e8e744cb..750f46ad018a 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -10,7 +10,6 @@ | |||
| 10 | #include <xen/xen.h> | 10 | #include <xen/xen.h> |
| 11 | #include <xen/features.h> | 11 | #include <xen/features.h> |
| 12 | #include <xen/page.h> | 12 | #include <xen/page.h> |
| 13 | #include <xen/interface/memory.h> | ||
| 14 | 13 | ||
| 15 | #include <asm/xen/hypercall.h> | 14 | #include <asm/xen/hypercall.h> |
| 16 | #include <asm/xen/hypervisor.h> | 15 | #include <asm/xen/hypervisor.h> |
| @@ -346,80 +345,3 @@ void xen_arch_unregister_cpu(int num) | |||
| 346 | } | 345 | } |
| 347 | EXPORT_SYMBOL(xen_arch_unregister_cpu); | 346 | EXPORT_SYMBOL(xen_arch_unregister_cpu); |
| 348 | #endif | 347 | #endif |
| 349 | |||
| 350 | #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG | ||
| 351 | void __init arch_xen_balloon_init(struct resource *hostmem_resource) | ||
| 352 | { | ||
| 353 | struct xen_memory_map memmap; | ||
| 354 | int rc; | ||
| 355 | unsigned int i, last_guest_ram; | ||
| 356 | phys_addr_t max_addr = PFN_PHYS(max_pfn); | ||
| 357 | struct e820_table *xen_e820_table; | ||
| 358 | const struct e820_entry *entry; | ||
| 359 | struct resource *res; | ||
| 360 | |||
| 361 | if (!xen_initial_domain()) | ||
| 362 | return; | ||
| 363 | |||
| 364 | xen_e820_table = kmalloc(sizeof(*xen_e820_table), GFP_KERNEL); | ||
| 365 | if (!xen_e820_table) | ||
| 366 | return; | ||
| 367 | |||
| 368 | memmap.nr_entries = ARRAY_SIZE(xen_e820_table->entries); | ||
| 369 | set_xen_guest_handle(memmap.buffer, xen_e820_table->entries); | ||
| 370 | rc = HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap); | ||
| 371 | if (rc) { | ||
| 372 | pr_warn("%s: Can't read host e820 (%d)\n", __func__, rc); | ||
| 373 | goto out; | ||
| 374 | } | ||
| 375 | |||
| 376 | last_guest_ram = 0; | ||
| 377 | for (i = 0; i < memmap.nr_entries; i++) { | ||
| 378 | if (xen_e820_table->entries[i].addr >= max_addr) | ||
| 379 | break; | ||
| 380 | if (xen_e820_table->entries[i].type == E820_TYPE_RAM) | ||
| 381 | last_guest_ram = i; | ||
| 382 | } | ||
| 383 | |||
| 384 | entry = &xen_e820_table->entries[last_guest_ram]; | ||
| 385 | if (max_addr >= entry->addr + entry->size) | ||
| 386 | goto out; /* No unallocated host RAM. */ | ||
| 387 | |||
| 388 | hostmem_resource->start = max_addr; | ||
| 389 | hostmem_resource->end = entry->addr + entry->size; | ||
| 390 | |||
| 391 | /* | ||
| 392 | * Mark non-RAM regions between the end of dom0 RAM and end of host RAM | ||
| 393 | * as unavailable. The rest of that region can be used for hotplug-based | ||
| 394 | * ballooning. | ||
| 395 | */ | ||
| 396 | for (; i < memmap.nr_entries; i++) { | ||
| 397 | entry = &xen_e820_table->entries[i]; | ||
| 398 | |||
| 399 | if (entry->type == E820_TYPE_RAM) | ||
| 400 | continue; | ||
| 401 | |||
| 402 | if (entry->addr >= hostmem_resource->end) | ||
| 403 | break; | ||
| 404 | |||
| 405 | res = kzalloc(sizeof(*res), GFP_KERNEL); | ||
| 406 | if (!res) | ||
| 407 | goto out; | ||
| 408 | |||
| 409 | res->name = "Unavailable host RAM"; | ||
| 410 | res->start = entry->addr; | ||
| 411 | res->end = (entry->addr + entry->size < hostmem_resource->end) ? | ||
| 412 | entry->addr + entry->size : hostmem_resource->end; | ||
| 413 | rc = insert_resource(hostmem_resource, res); | ||
| 414 | if (rc) { | ||
| 415 | pr_warn("%s: Can't insert [%llx - %llx) (%d)\n", | ||
| 416 | __func__, res->start, res->end, rc); | ||
| 417 | kfree(res); | ||
| 418 | goto out; | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | out: | ||
| 423 | kfree(xen_e820_table); | ||
| 424 | } | ||
| 425 | #endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */ | ||
diff --git a/arch/x86/xen/multicalls.c b/arch/x86/xen/multicalls.c index 2bce7958ce8b..0766a08bdf45 100644 --- a/arch/x86/xen/multicalls.c +++ b/arch/x86/xen/multicalls.c | |||
| @@ -69,6 +69,11 @@ void xen_mc_flush(void) | |||
| 69 | 69 | ||
| 70 | trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx); | 70 | trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx); |
| 71 | 71 | ||
| 72 | #if MC_DEBUG | ||
| 73 | memcpy(b->debug, b->entries, | ||
| 74 | b->mcidx * sizeof(struct multicall_entry)); | ||
| 75 | #endif | ||
| 76 | |||
| 72 | switch (b->mcidx) { | 77 | switch (b->mcidx) { |
| 73 | case 0: | 78 | case 0: |
| 74 | /* no-op */ | 79 | /* no-op */ |
| @@ -87,32 +92,34 @@ void xen_mc_flush(void) | |||
| 87 | break; | 92 | break; |
| 88 | 93 | ||
| 89 | default: | 94 | default: |
| 90 | #if MC_DEBUG | ||
| 91 | memcpy(b->debug, b->entries, | ||
| 92 | b->mcidx * sizeof(struct multicall_entry)); | ||
| 93 | #endif | ||
| 94 | |||
| 95 | if (HYPERVISOR_multicall(b->entries, b->mcidx) != 0) | 95 | if (HYPERVISOR_multicall(b->entries, b->mcidx) != 0) |
| 96 | BUG(); | 96 | BUG(); |
| 97 | for (i = 0; i < b->mcidx; i++) | 97 | for (i = 0; i < b->mcidx; i++) |
| 98 | if (b->entries[i].result < 0) | 98 | if (b->entries[i].result < 0) |
| 99 | ret++; | 99 | ret++; |
| 100 | } | ||
| 100 | 101 | ||
| 102 | if (WARN_ON(ret)) { | ||
| 103 | pr_err("%d of %d multicall(s) failed: cpu %d\n", | ||
| 104 | ret, b->mcidx, smp_processor_id()); | ||
| 105 | for (i = 0; i < b->mcidx; i++) { | ||
| 106 | if (b->entries[i].result < 0) { | ||
| 101 | #if MC_DEBUG | 107 | #if MC_DEBUG |
| 102 | if (ret) { | 108 | pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\t%pF\n", |
| 103 | printk(KERN_ERR "%d multicall(s) failed: cpu %d\n", | 109 | i + 1, |
| 104 | ret, smp_processor_id()); | ||
| 105 | dump_stack(); | ||
| 106 | for (i = 0; i < b->mcidx; i++) { | ||
| 107 | printk(KERN_DEBUG " call %2d/%d: op=%lu arg=[%lx] result=%ld\t%pF\n", | ||
| 108 | i+1, b->mcidx, | ||
| 109 | b->debug[i].op, | 110 | b->debug[i].op, |
| 110 | b->debug[i].args[0], | 111 | b->debug[i].args[0], |
| 111 | b->entries[i].result, | 112 | b->entries[i].result, |
| 112 | b->caller[i]); | 113 | b->caller[i]); |
| 114 | #else | ||
| 115 | pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\n", | ||
| 116 | i + 1, | ||
| 117 | b->entries[i].op, | ||
| 118 | b->entries[i].args[0], | ||
| 119 | b->entries[i].result); | ||
| 120 | #endif | ||
| 113 | } | 121 | } |
| 114 | } | 122 | } |
| 115 | #endif | ||
| 116 | } | 123 | } |
| 117 | 124 | ||
| 118 | b->mcidx = 0; | 125 | b->mcidx = 0; |
| @@ -126,8 +133,6 @@ void xen_mc_flush(void) | |||
| 126 | b->cbidx = 0; | 133 | b->cbidx = 0; |
| 127 | 134 | ||
| 128 | local_irq_restore(flags); | 135 | local_irq_restore(flags); |
| 129 | |||
| 130 | WARN_ON(ret); | ||
| 131 | } | 136 | } |
| 132 | 137 | ||
| 133 | struct multicall_space __xen_mc_entry(size_t args) | 138 | struct multicall_space __xen_mc_entry(size_t args) |
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 1163e33121fb..075ed47993bb 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
| @@ -808,6 +808,7 @@ char * __init xen_memory_setup(void) | |||
| 808 | addr = xen_e820_table.entries[0].addr; | 808 | addr = xen_e820_table.entries[0].addr; |
| 809 | size = xen_e820_table.entries[0].size; | 809 | size = xen_e820_table.entries[0].size; |
| 810 | while (i < xen_e820_table.nr_entries) { | 810 | while (i < xen_e820_table.nr_entries) { |
| 811 | bool discard = false; | ||
| 811 | 812 | ||
| 812 | chunk_size = size; | 813 | chunk_size = size; |
| 813 | type = xen_e820_table.entries[i].type; | 814 | type = xen_e820_table.entries[i].type; |
| @@ -823,10 +824,11 @@ char * __init xen_memory_setup(void) | |||
| 823 | xen_add_extra_mem(pfn_s, n_pfns); | 824 | xen_add_extra_mem(pfn_s, n_pfns); |
| 824 | xen_max_p2m_pfn = pfn_s + n_pfns; | 825 | xen_max_p2m_pfn = pfn_s + n_pfns; |
| 825 | } else | 826 | } else |
| 826 | type = E820_TYPE_UNUSABLE; | 827 | discard = true; |
| 827 | } | 828 | } |
| 828 | 829 | ||
| 829 | xen_align_and_add_e820_region(addr, chunk_size, type); | 830 | if (!discard) |
| 831 | xen_align_and_add_e820_region(addr, chunk_size, type); | ||
| 830 | 832 | ||
| 831 | addr += chunk_size; | 833 | addr += chunk_size; |
| 832 | size -= chunk_size; | 834 | size -= chunk_size; |
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 1c8a8816a402..3776122c87cc 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c | |||
| @@ -3,22 +3,17 @@ | |||
| 3 | * Split spinlock implementation out into its own file, so it can be | 3 | * Split spinlock implementation out into its own file, so it can be |
| 4 | * compiled in a FTRACE-compatible way. | 4 | * compiled in a FTRACE-compatible way. |
| 5 | */ | 5 | */ |
| 6 | #include <linux/kernel_stat.h> | 6 | #include <linux/kernel.h> |
| 7 | #include <linux/spinlock.h> | 7 | #include <linux/spinlock.h> |
| 8 | #include <linux/debugfs.h> | ||
| 9 | #include <linux/log2.h> | ||
| 10 | #include <linux/gfp.h> | ||
| 11 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
| 12 | #include <linux/atomic.h> | 9 | #include <linux/atomic.h> |
| 13 | 10 | ||
| 14 | #include <asm/paravirt.h> | 11 | #include <asm/paravirt.h> |
| 15 | #include <asm/qspinlock.h> | 12 | #include <asm/qspinlock.h> |
| 16 | 13 | ||
| 17 | #include <xen/interface/xen.h> | ||
| 18 | #include <xen/events.h> | 14 | #include <xen/events.h> |
| 19 | 15 | ||
| 20 | #include "xen-ops.h" | 16 | #include "xen-ops.h" |
| 21 | #include "debugfs.h" | ||
| 22 | 17 | ||
| 23 | static DEFINE_PER_CPU(int, lock_kicker_irq) = -1; | 18 | static DEFINE_PER_CPU(int, lock_kicker_irq) = -1; |
| 24 | static DEFINE_PER_CPU(char *, irq_name); | 19 | static DEFINE_PER_CPU(char *, irq_name); |
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index fdfc64f5acea..221b7333d067 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
| @@ -251,25 +251,10 @@ static void release_memory_resource(struct resource *resource) | |||
| 251 | kfree(resource); | 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 | static struct resource *additional_memory_resource(phys_addr_t size) | 254 | static struct resource *additional_memory_resource(phys_addr_t size) |
| 270 | { | 255 | { |
| 271 | struct resource *res, *res_hostmem; | 256 | struct resource *res; |
| 272 | int ret = -ENOMEM; | 257 | int ret; |
| 273 | 258 | ||
| 274 | res = kzalloc(sizeof(*res), GFP_KERNEL); | 259 | res = kzalloc(sizeof(*res), GFP_KERNEL); |
| 275 | if (!res) | 260 | if (!res) |
| @@ -278,42 +263,13 @@ static struct resource *additional_memory_resource(phys_addr_t size) | |||
| 278 | res->name = "System RAM"; | 263 | res->name = "System RAM"; |
| 279 | res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; | 264 | res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; |
| 280 | 265 | ||
| 281 | res_hostmem = kzalloc(sizeof(*res), GFP_KERNEL); | 266 | ret = allocate_resource(&iomem_resource, res, |
| 282 | if (res_hostmem) { | 267 | size, 0, -1, |
| 283 | /* Try to grab a range from hostmem */ | 268 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); |
| 284 | res_hostmem->name = "Host memory"; | 269 | if (ret < 0) { |
| 285 | ret = allocate_resource(&hostmem_resource, res_hostmem, | 270 | pr_err("Cannot allocate new System RAM resource\n"); |
| 286 | size, 0, -1, | 271 | kfree(res); |
| 287 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); | 272 | return NULL; |
| 288 | } | ||
| 289 | |||
| 290 | if (!ret) { | ||
| 291 | /* | ||
| 292 | * Insert this resource into iomem. Because hostmem_resource | ||
| 293 | * tracks portion of guest e820 marked as UNUSABLE noone else | ||
| 294 | * should try to use it. | ||
| 295 | */ | ||
| 296 | res->start = res_hostmem->start; | ||
| 297 | res->end = res_hostmem->end; | ||
| 298 | ret = insert_resource(&iomem_resource, res); | ||
| 299 | if (ret < 0) { | ||
| 300 | pr_err("Can't insert iomem_resource [%llx - %llx]\n", | ||
| 301 | res->start, res->end); | ||
| 302 | release_memory_resource(res_hostmem); | ||
| 303 | res_hostmem = NULL; | ||
| 304 | res->start = res->end = 0; | ||
| 305 | } | ||
| 306 | } | ||
| 307 | |||
| 308 | if (ret) { | ||
| 309 | ret = allocate_resource(&iomem_resource, res, | ||
| 310 | size, 0, -1, | ||
| 311 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); | ||
| 312 | if (ret < 0) { | ||
| 313 | pr_err("Cannot allocate new System RAM resource\n"); | ||
| 314 | kfree(res); | ||
| 315 | return NULL; | ||
| 316 | } | ||
| 317 | } | 273 | } |
| 318 | 274 | ||
| 319 | #ifdef CONFIG_SPARSEMEM | 275 | #ifdef CONFIG_SPARSEMEM |
| @@ -325,7 +281,6 @@ static struct resource *additional_memory_resource(phys_addr_t size) | |||
| 325 | pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", | 281 | pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", |
| 326 | pfn, limit); | 282 | pfn, limit); |
| 327 | release_memory_resource(res); | 283 | release_memory_resource(res); |
| 328 | release_memory_resource(res_hostmem); | ||
| 329 | return NULL; | 284 | return NULL; |
| 330 | } | 285 | } |
| 331 | } | 286 | } |
| @@ -750,8 +705,6 @@ static int __init balloon_init(void) | |||
| 750 | set_online_page_callback(&xen_online_page); | 705 | set_online_page_callback(&xen_online_page); |
| 751 | register_memory_notifier(&xen_memory_nb); | 706 | register_memory_notifier(&xen_memory_nb); |
| 752 | register_sysctl_table(xen_root); | 707 | register_sysctl_table(xen_root); |
| 753 | |||
| 754 | arch_xen_balloon_init(&hostmem_resource); | ||
| 755 | #endif | 708 | #endif |
| 756 | 709 | ||
| 757 | #ifdef CONFIG_XEN_PV | 710 | #ifdef CONFIG_XEN_PV |
diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c index 2f11ca72a281..77224d8f3e6f 100644 --- a/drivers/xen/pvcalls-front.c +++ b/drivers/xen/pvcalls-front.c | |||
| @@ -385,8 +385,8 @@ static int create_active(struct sock_mapping *map, int *evtchn) | |||
| 385 | out_error: | 385 | out_error: |
| 386 | if (*evtchn >= 0) | 386 | if (*evtchn >= 0) |
| 387 | xenbus_free_evtchn(pvcalls_front_dev, *evtchn); | 387 | xenbus_free_evtchn(pvcalls_front_dev, *evtchn); |
| 388 | kfree(map->active.data.in); | 388 | free_pages((unsigned long)map->active.data.in, PVCALLS_RING_ORDER); |
| 389 | kfree(map->active.ring); | 389 | free_page((unsigned long)map->active.ring); |
| 390 | return ret; | 390 | return ret; |
| 391 | } | 391 | } |
| 392 | 392 | ||
diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c index 23f1387b3ef7..e7df65d32c91 100644 --- a/drivers/xen/xlate_mmu.c +++ b/drivers/xen/xlate_mmu.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <asm/xen/hypervisor.h> | 36 | #include <asm/xen/hypervisor.h> |
| 37 | 37 | ||
| 38 | #include <xen/xen.h> | 38 | #include <xen/xen.h> |
| 39 | #include <xen/xen-ops.h> | ||
| 39 | #include <xen/page.h> | 40 | #include <xen/page.h> |
| 40 | #include <xen/interface/xen.h> | 41 | #include <xen/interface/xen.h> |
| 41 | #include <xen/interface/memory.h> | 42 | #include <xen/interface/memory.h> |
diff --git a/include/xen/balloon.h b/include/xen/balloon.h index 61f410fd74e4..4914b93a23f2 100644 --- a/include/xen/balloon.h +++ b/include/xen/balloon.h | |||
| @@ -44,8 +44,3 @@ static inline void xen_balloon_init(void) | |||
| 44 | { | 44 | { |
| 45 | } | 45 | } |
| 46 | #endif | 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 | ||
