diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-11-02 16:26:11 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-11-02 16:26:11 -0400 |
| commit | 66b6a0c979e88810e753e528dd0b9aef30ba21a1 (patch) | |
| tree | a6d89319a80abcdac4da1602dce5d4249358b1ca | |
| parent | d9b482c8ba1973a189f2d4c8175d405b87fbf2d7 (diff) | |
| parent | 95a7d76897c1e7243d4137037c66d15cbf2cce76 (diff) | |
Merge tag 'stable/for-linus-3.7-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
Pull Xen bugfixes from Konrad Rzeszutek Wilk:
- Use appropriate macros instead of hand-rolling our own (ARM).
- Fixes if FB/KBD closed unexpectedly.
- Fix memory leak in /dev/gntdev ioctl calls.
- Fix overflow check in xenbus_file_write.
- Document cleanup.
- Performance optimization when migrating guests.
* tag 'stable/for-linus-3.7-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
xen/mmu: Use Xen specific TLB flush instead of the generic one.
xen/arm: use the __HVC macro
xen/xenbus: fix overflow check in xenbus_file_write()
xen-kbdfront: handle backend CLOSED without CLOSING
xen-fbfront: handle backend CLOSED without CLOSING
xen/gntdev: don't leak memory from IOCTL_GNTDEV_MAP_GRANT_REF
x86: remove obsolete comment from asm/xen/hypervisor.h
| -rw-r--r-- | arch/arm/xen/hypercall.S | 14 | ||||
| -rw-r--r-- | arch/x86/include/asm/xen/hypervisor.h | 1 | ||||
| -rw-r--r-- | arch/x86/xen/mmu.c | 21 | ||||
| -rw-r--r-- | drivers/input/misc/xen-kbdfront.c | 5 | ||||
| -rw-r--r-- | drivers/video/xen-fbfront.c | 5 | ||||
| -rw-r--r-- | drivers/xen/gntdev.c | 36 | ||||
| -rw-r--r-- | drivers/xen/xenbus/xenbus_dev_frontend.c | 2 | ||||
| -rw-r--r-- | include/trace/events/xen.h | 8 |
8 files changed, 61 insertions, 31 deletions
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S index 074f5ed101b..71f723984cb 100644 --- a/arch/arm/xen/hypercall.S +++ b/arch/arm/xen/hypercall.S | |||
| @@ -48,20 +48,16 @@ | |||
| 48 | 48 | ||
| 49 | #include <linux/linkage.h> | 49 | #include <linux/linkage.h> |
| 50 | #include <asm/assembler.h> | 50 | #include <asm/assembler.h> |
| 51 | #include <asm/opcodes-virt.h> | ||
| 51 | #include <xen/interface/xen.h> | 52 | #include <xen/interface/xen.h> |
| 52 | 53 | ||
| 53 | 54 | ||
| 54 | /* HVC 0xEA1 */ | 55 | #define XEN_IMM 0xEA1 |
| 55 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 56 | #define xen_hvc .word 0xf7e08ea1 | ||
| 57 | #else | ||
| 58 | #define xen_hvc .word 0xe140ea71 | ||
| 59 | #endif | ||
| 60 | 56 | ||
| 61 | #define HYPERCALL_SIMPLE(hypercall) \ | 57 | #define HYPERCALL_SIMPLE(hypercall) \ |
| 62 | ENTRY(HYPERVISOR_##hypercall) \ | 58 | ENTRY(HYPERVISOR_##hypercall) \ |
| 63 | mov r12, #__HYPERVISOR_##hypercall; \ | 59 | mov r12, #__HYPERVISOR_##hypercall; \ |
| 64 | xen_hvc; \ | 60 | __HVC(XEN_IMM); \ |
| 65 | mov pc, lr; \ | 61 | mov pc, lr; \ |
| 66 | ENDPROC(HYPERVISOR_##hypercall) | 62 | ENDPROC(HYPERVISOR_##hypercall) |
| 67 | 63 | ||
| @@ -76,7 +72,7 @@ ENTRY(HYPERVISOR_##hypercall) \ | |||
| 76 | stmdb sp!, {r4} \ | 72 | stmdb sp!, {r4} \ |
| 77 | ldr r4, [sp, #4] \ | 73 | ldr r4, [sp, #4] \ |
| 78 | mov r12, #__HYPERVISOR_##hypercall; \ | 74 | mov r12, #__HYPERVISOR_##hypercall; \ |
| 79 | xen_hvc \ | 75 | __HVC(XEN_IMM); \ |
| 80 | ldm sp!, {r4} \ | 76 | ldm sp!, {r4} \ |
| 81 | mov pc, lr \ | 77 | mov pc, lr \ |
| 82 | ENDPROC(HYPERVISOR_##hypercall) | 78 | ENDPROC(HYPERVISOR_##hypercall) |
| @@ -100,7 +96,7 @@ ENTRY(privcmd_call) | |||
| 100 | mov r2, r3 | 96 | mov r2, r3 |
| 101 | ldr r3, [sp, #8] | 97 | ldr r3, [sp, #8] |
| 102 | ldr r4, [sp, #4] | 98 | ldr r4, [sp, #4] |
| 103 | xen_hvc | 99 | __HVC(XEN_IMM) |
| 104 | ldm sp!, {r4} | 100 | ldm sp!, {r4} |
| 105 | mov pc, lr | 101 | mov pc, lr |
| 106 | ENDPROC(privcmd_call); | 102 | ENDPROC(privcmd_call); |
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h index 66d0fff1ee8..125f344f06a 100644 --- a/arch/x86/include/asm/xen/hypervisor.h +++ b/arch/x86/include/asm/xen/hypervisor.h | |||
| @@ -33,7 +33,6 @@ | |||
| 33 | #ifndef _ASM_X86_XEN_HYPERVISOR_H | 33 | #ifndef _ASM_X86_XEN_HYPERVISOR_H |
| 34 | #define _ASM_X86_XEN_HYPERVISOR_H | 34 | #define _ASM_X86_XEN_HYPERVISOR_H |
| 35 | 35 | ||
| 36 | /* arch/i386/kernel/setup.c */ | ||
| 37 | extern struct shared_info *HYPERVISOR_shared_info; | 36 | extern struct shared_info *HYPERVISOR_shared_info; |
| 38 | extern struct start_info *xen_start_info; | 37 | extern struct start_info *xen_start_info; |
| 39 | 38 | ||
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 6226c99729b..dcf5f2dd91e 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
| @@ -1288,6 +1288,25 @@ unsigned long xen_read_cr2_direct(void) | |||
| 1288 | return this_cpu_read(xen_vcpu_info.arch.cr2); | 1288 | return this_cpu_read(xen_vcpu_info.arch.cr2); |
| 1289 | } | 1289 | } |
| 1290 | 1290 | ||
| 1291 | void xen_flush_tlb_all(void) | ||
| 1292 | { | ||
| 1293 | struct mmuext_op *op; | ||
| 1294 | struct multicall_space mcs; | ||
| 1295 | |||
| 1296 | trace_xen_mmu_flush_tlb_all(0); | ||
| 1297 | |||
| 1298 | preempt_disable(); | ||
| 1299 | |||
| 1300 | mcs = xen_mc_entry(sizeof(*op)); | ||
| 1301 | |||
| 1302 | op = mcs.args; | ||
| 1303 | op->cmd = MMUEXT_TLB_FLUSH_ALL; | ||
| 1304 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); | ||
| 1305 | |||
| 1306 | xen_mc_issue(PARAVIRT_LAZY_MMU); | ||
| 1307 | |||
| 1308 | preempt_enable(); | ||
| 1309 | } | ||
| 1291 | static void xen_flush_tlb(void) | 1310 | static void xen_flush_tlb(void) |
| 1292 | { | 1311 | { |
| 1293 | struct mmuext_op *op; | 1312 | struct mmuext_op *op; |
| @@ -2518,7 +2537,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma, | |||
| 2518 | err = 0; | 2537 | err = 0; |
| 2519 | out: | 2538 | out: |
| 2520 | 2539 | ||
| 2521 | flush_tlb_all(); | 2540 | xen_flush_tlb_all(); |
| 2522 | 2541 | ||
| 2523 | return err; | 2542 | return err; |
| 2524 | } | 2543 | } |
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c index 02ca8680ea5..6f7d9901303 100644 --- a/drivers/input/misc/xen-kbdfront.c +++ b/drivers/input/misc/xen-kbdfront.c | |||
| @@ -311,7 +311,6 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, | |||
| 311 | case XenbusStateReconfiguring: | 311 | case XenbusStateReconfiguring: |
| 312 | case XenbusStateReconfigured: | 312 | case XenbusStateReconfigured: |
| 313 | case XenbusStateUnknown: | 313 | case XenbusStateUnknown: |
| 314 | case XenbusStateClosed: | ||
| 315 | break; | 314 | break; |
| 316 | 315 | ||
| 317 | case XenbusStateInitWait: | 316 | case XenbusStateInitWait: |
| @@ -350,6 +349,10 @@ InitWait: | |||
| 350 | 349 | ||
| 351 | break; | 350 | break; |
| 352 | 351 | ||
| 352 | case XenbusStateClosed: | ||
| 353 | if (dev->state == XenbusStateClosed) | ||
| 354 | break; | ||
| 355 | /* Missed the backend's CLOSING state -- fallthrough */ | ||
| 353 | case XenbusStateClosing: | 356 | case XenbusStateClosing: |
| 354 | xenbus_frontend_closed(dev); | 357 | xenbus_frontend_closed(dev); |
| 355 | break; | 358 | break; |
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c index b7f5173ff9e..917bb568168 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/xen-fbfront.c | |||
| @@ -641,7 +641,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev, | |||
| 641 | case XenbusStateReconfiguring: | 641 | case XenbusStateReconfiguring: |
| 642 | case XenbusStateReconfigured: | 642 | case XenbusStateReconfigured: |
| 643 | case XenbusStateUnknown: | 643 | case XenbusStateUnknown: |
| 644 | case XenbusStateClosed: | ||
| 645 | break; | 644 | break; |
| 646 | 645 | ||
| 647 | case XenbusStateInitWait: | 646 | case XenbusStateInitWait: |
| @@ -670,6 +669,10 @@ InitWait: | |||
| 670 | info->feature_resize = val; | 669 | info->feature_resize = val; |
| 671 | break; | 670 | break; |
| 672 | 671 | ||
| 672 | case XenbusStateClosed: | ||
| 673 | if (dev->state == XenbusStateClosed) | ||
| 674 | break; | ||
| 675 | /* Missed the backend's CLOSING state -- fallthrough */ | ||
| 673 | case XenbusStateClosing: | 676 | case XenbusStateClosing: |
| 674 | xenbus_frontend_closed(dev); | 677 | xenbus_frontend_closed(dev); |
| 675 | break; | 678 | break; |
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 610bfc6be17..2e22df2f7a3 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
| @@ -105,6 +105,21 @@ static void gntdev_print_maps(struct gntdev_priv *priv, | |||
| 105 | #endif | 105 | #endif |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static void gntdev_free_map(struct grant_map *map) | ||
| 109 | { | ||
| 110 | if (map == NULL) | ||
| 111 | return; | ||
| 112 | |||
| 113 | if (map->pages) | ||
| 114 | free_xenballooned_pages(map->count, map->pages); | ||
| 115 | kfree(map->pages); | ||
| 116 | kfree(map->grants); | ||
| 117 | kfree(map->map_ops); | ||
| 118 | kfree(map->unmap_ops); | ||
| 119 | kfree(map->kmap_ops); | ||
| 120 | kfree(map); | ||
| 121 | } | ||
| 122 | |||
| 108 | static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) | 123 | static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) |
| 109 | { | 124 | { |
| 110 | struct grant_map *add; | 125 | struct grant_map *add; |
| @@ -142,12 +157,7 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) | |||
| 142 | return add; | 157 | return add; |
| 143 | 158 | ||
| 144 | err: | 159 | err: |
| 145 | kfree(add->pages); | 160 | gntdev_free_map(add); |
| 146 | kfree(add->grants); | ||
| 147 | kfree(add->map_ops); | ||
| 148 | kfree(add->unmap_ops); | ||
| 149 | kfree(add->kmap_ops); | ||
| 150 | kfree(add); | ||
| 151 | return NULL; | 161 | return NULL; |
| 152 | } | 162 | } |
| 153 | 163 | ||
| @@ -198,17 +208,9 @@ static void gntdev_put_map(struct grant_map *map) | |||
| 198 | evtchn_put(map->notify.event); | 208 | evtchn_put(map->notify.event); |
| 199 | } | 209 | } |
| 200 | 210 | ||
| 201 | if (map->pages) { | 211 | if (map->pages && !use_ptemod) |
| 202 | if (!use_ptemod) | 212 | unmap_grant_pages(map, 0, map->count); |
| 203 | unmap_grant_pages(map, 0, map->count); | 213 | gntdev_free_map(map); |
| 204 | |||
| 205 | free_xenballooned_pages(map->count, map->pages); | ||
| 206 | } | ||
| 207 | kfree(map->pages); | ||
| 208 | kfree(map->grants); | ||
| 209 | kfree(map->map_ops); | ||
| 210 | kfree(map->unmap_ops); | ||
| 211 | kfree(map); | ||
| 212 | } | 214 | } |
| 213 | 215 | ||
| 214 | /* ------------------------------------------------------------------ */ | 216 | /* ------------------------------------------------------------------ */ |
diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c index 89f76252a16..ac727028e65 100644 --- a/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c | |||
| @@ -458,7 +458,7 @@ static ssize_t xenbus_file_write(struct file *filp, | |||
| 458 | goto out; | 458 | goto out; |
| 459 | 459 | ||
| 460 | /* Can't write a xenbus message larger we can buffer */ | 460 | /* Can't write a xenbus message larger we can buffer */ |
| 461 | if ((len + u->len) > sizeof(u->u.buffer)) { | 461 | if (len > sizeof(u->u.buffer) - u->len) { |
| 462 | /* On error, dump existing buffer */ | 462 | /* On error, dump existing buffer */ |
| 463 | u->len = 0; | 463 | u->len = 0; |
| 464 | rc = -EINVAL; | 464 | rc = -EINVAL; |
diff --git a/include/trace/events/xen.h b/include/trace/events/xen.h index 15ba03bdd7c..d06b6da5c1e 100644 --- a/include/trace/events/xen.h +++ b/include/trace/events/xen.h | |||
| @@ -377,6 +377,14 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd, | |||
| 377 | DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin); | 377 | DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin); |
| 378 | DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin); | 378 | DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin); |
| 379 | 379 | ||
| 380 | TRACE_EVENT(xen_mmu_flush_tlb_all, | ||
| 381 | TP_PROTO(int x), | ||
| 382 | TP_ARGS(x), | ||
| 383 | TP_STRUCT__entry(__array(char, x, 0)), | ||
| 384 | TP_fast_assign((void)x), | ||
| 385 | TP_printk("%s", "") | ||
| 386 | ); | ||
| 387 | |||
| 380 | TRACE_EVENT(xen_mmu_flush_tlb, | 388 | TRACE_EVENT(xen_mmu_flush_tlb, |
| 381 | TP_PROTO(int x), | 389 | TP_PROTO(int x), |
| 382 | TP_ARGS(x), | 390 | TP_ARGS(x), |
