Commit 66b6a0c9 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'stable/for-linus-3.7-rc4-tag' of...

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
parents d9b482c8 95a7d768
...@@ -48,20 +48,16 @@ ...@@ -48,20 +48,16 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.h> #include <asm/assembler.h>
#include <asm/opcodes-virt.h>
#include <xen/interface/xen.h> #include <xen/interface/xen.h>
/* HVC 0xEA1 */ #define XEN_IMM 0xEA1
#ifdef CONFIG_THUMB2_KERNEL
#define xen_hvc .word 0xf7e08ea1
#else
#define xen_hvc .word 0xe140ea71
#endif
#define HYPERCALL_SIMPLE(hypercall) \ #define HYPERCALL_SIMPLE(hypercall) \
ENTRY(HYPERVISOR_##hypercall) \ ENTRY(HYPERVISOR_##hypercall) \
mov r12, #__HYPERVISOR_##hypercall; \ mov r12, #__HYPERVISOR_##hypercall; \
xen_hvc; \ __HVC(XEN_IMM); \
mov pc, lr; \ mov pc, lr; \
ENDPROC(HYPERVISOR_##hypercall) ENDPROC(HYPERVISOR_##hypercall)
...@@ -76,7 +72,7 @@ ENTRY(HYPERVISOR_##hypercall) \ ...@@ -76,7 +72,7 @@ ENTRY(HYPERVISOR_##hypercall) \
stmdb sp!, {r4} \ stmdb sp!, {r4} \
ldr r4, [sp, #4] \ ldr r4, [sp, #4] \
mov r12, #__HYPERVISOR_##hypercall; \ mov r12, #__HYPERVISOR_##hypercall; \
xen_hvc \ __HVC(XEN_IMM); \
ldm sp!, {r4} \ ldm sp!, {r4} \
mov pc, lr \ mov pc, lr \
ENDPROC(HYPERVISOR_##hypercall) ENDPROC(HYPERVISOR_##hypercall)
...@@ -100,7 +96,7 @@ ENTRY(privcmd_call) ...@@ -100,7 +96,7 @@ ENTRY(privcmd_call)
mov r2, r3 mov r2, r3
ldr r3, [sp, #8] ldr r3, [sp, #8]
ldr r4, [sp, #4] ldr r4, [sp, #4]
xen_hvc __HVC(XEN_IMM)
ldm sp!, {r4} ldm sp!, {r4}
mov pc, lr mov pc, lr
ENDPROC(privcmd_call); ENDPROC(privcmd_call);
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#ifndef _ASM_X86_XEN_HYPERVISOR_H #ifndef _ASM_X86_XEN_HYPERVISOR_H
#define _ASM_X86_XEN_HYPERVISOR_H #define _ASM_X86_XEN_HYPERVISOR_H
/* arch/i386/kernel/setup.c */
extern struct shared_info *HYPERVISOR_shared_info; extern struct shared_info *HYPERVISOR_shared_info;
extern struct start_info *xen_start_info; extern struct start_info *xen_start_info;
......
...@@ -1288,6 +1288,25 @@ unsigned long xen_read_cr2_direct(void) ...@@ -1288,6 +1288,25 @@ unsigned long xen_read_cr2_direct(void)
return this_cpu_read(xen_vcpu_info.arch.cr2); return this_cpu_read(xen_vcpu_info.arch.cr2);
} }
void xen_flush_tlb_all(void)
{
struct mmuext_op *op;
struct multicall_space mcs;
trace_xen_mmu_flush_tlb_all(0);
preempt_disable();
mcs = xen_mc_entry(sizeof(*op));
op = mcs.args;
op->cmd = MMUEXT_TLB_FLUSH_ALL;
MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
xen_mc_issue(PARAVIRT_LAZY_MMU);
preempt_enable();
}
static void xen_flush_tlb(void) static void xen_flush_tlb(void)
{ {
struct mmuext_op *op; struct mmuext_op *op;
...@@ -2518,7 +2537,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma, ...@@ -2518,7 +2537,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
err = 0; err = 0;
out: out:
flush_tlb_all(); xen_flush_tlb_all();
return err; return err;
} }
......
...@@ -311,7 +311,6 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, ...@@ -311,7 +311,6 @@ static void xenkbd_backend_changed(struct xenbus_device *dev,
case XenbusStateReconfiguring: case XenbusStateReconfiguring:
case XenbusStateReconfigured: case XenbusStateReconfigured:
case XenbusStateUnknown: case XenbusStateUnknown:
case XenbusStateClosed:
break; break;
case XenbusStateInitWait: case XenbusStateInitWait:
...@@ -350,6 +349,10 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, ...@@ -350,6 +349,10 @@ static void xenkbd_backend_changed(struct xenbus_device *dev,
break; break;
case XenbusStateClosed:
if (dev->state == XenbusStateClosed)
break;
/* Missed the backend's CLOSING state -- fallthrough */
case XenbusStateClosing: case XenbusStateClosing:
xenbus_frontend_closed(dev); xenbus_frontend_closed(dev);
break; break;
......
...@@ -641,7 +641,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev, ...@@ -641,7 +641,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev,
case XenbusStateReconfiguring: case XenbusStateReconfiguring:
case XenbusStateReconfigured: case XenbusStateReconfigured:
case XenbusStateUnknown: case XenbusStateUnknown:
case XenbusStateClosed:
break; break;
case XenbusStateInitWait: case XenbusStateInitWait:
...@@ -670,6 +669,10 @@ static void xenfb_backend_changed(struct xenbus_device *dev, ...@@ -670,6 +669,10 @@ static void xenfb_backend_changed(struct xenbus_device *dev,
info->feature_resize = val; info->feature_resize = val;
break; break;
case XenbusStateClosed:
if (dev->state == XenbusStateClosed)
break;
/* Missed the backend's CLOSING state -- fallthrough */
case XenbusStateClosing: case XenbusStateClosing:
xenbus_frontend_closed(dev); xenbus_frontend_closed(dev);
break; break;
......
...@@ -105,6 +105,21 @@ static void gntdev_print_maps(struct gntdev_priv *priv, ...@@ -105,6 +105,21 @@ static void gntdev_print_maps(struct gntdev_priv *priv,
#endif #endif
} }
static void gntdev_free_map(struct grant_map *map)
{
if (map == NULL)
return;
if (map->pages)
free_xenballooned_pages(map->count, map->pages);
kfree(map->pages);
kfree(map->grants);
kfree(map->map_ops);
kfree(map->unmap_ops);
kfree(map->kmap_ops);
kfree(map);
}
static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
{ {
struct grant_map *add; struct grant_map *add;
...@@ -142,12 +157,7 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) ...@@ -142,12 +157,7 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
return add; return add;
err: err:
kfree(add->pages); gntdev_free_map(add);
kfree(add->grants);
kfree(add->map_ops);
kfree(add->unmap_ops);
kfree(add->kmap_ops);
kfree(add);
return NULL; return NULL;
} }
...@@ -198,17 +208,9 @@ static void gntdev_put_map(struct grant_map *map) ...@@ -198,17 +208,9 @@ static void gntdev_put_map(struct grant_map *map)
evtchn_put(map->notify.event); evtchn_put(map->notify.event);
} }
if (map->pages) { if (map->pages && !use_ptemod)
if (!use_ptemod)
unmap_grant_pages(map, 0, map->count); unmap_grant_pages(map, 0, map->count);
gntdev_free_map(map);
free_xenballooned_pages(map->count, map->pages);
}
kfree(map->pages);
kfree(map->grants);
kfree(map->map_ops);
kfree(map->unmap_ops);
kfree(map);
} }
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
......
...@@ -458,7 +458,7 @@ static ssize_t xenbus_file_write(struct file *filp, ...@@ -458,7 +458,7 @@ static ssize_t xenbus_file_write(struct file *filp,
goto out; goto out;
/* Can't write a xenbus message larger we can buffer */ /* Can't write a xenbus message larger we can buffer */
if ((len + u->len) > sizeof(u->u.buffer)) { if (len > sizeof(u->u.buffer) - u->len) {
/* On error, dump existing buffer */ /* On error, dump existing buffer */
u->len = 0; u->len = 0;
rc = -EINVAL; rc = -EINVAL;
......
...@@ -377,6 +377,14 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd, ...@@ -377,6 +377,14 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd,
DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin); DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin);
DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin); DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin);
TRACE_EVENT(xen_mmu_flush_tlb_all,
TP_PROTO(int x),
TP_ARGS(x),
TP_STRUCT__entry(__array(char, x, 0)),
TP_fast_assign((void)x),
TP_printk("%s", "")
);
TRACE_EVENT(xen_mmu_flush_tlb, TRACE_EVENT(xen_mmu_flush_tlb,
TP_PROTO(int x), TP_PROTO(int x),
TP_ARGS(x), TP_ARGS(x),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment