mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
Merge branches 'stable/backend.base.v3' and 'stable/gntalloc.v7' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
* 'stable/backend.base.v3' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: xen/pci: Fix compiler error when CONFIG_XEN_PRIVILEGED_GUEST is not set. xen/p2m: Add EXPORT_SYMBOL_GPL to the M2P override functions. xen/p2m/m2p/gnttab: Support GNTMAP_host_map in the M2P override. xen/irq: The Xen hypervisor cleans up the PIRQs if the other domain forgot. xen/irq: Export 'xen_pirq_from_irq' function. xen/irq: Add support to check if IRQ line is shared with other domains. xen/irq: Check if the PCI device is owned by a domain different than DOMID_SELF. xen/pci: Add xen_[find|register|unregister]_device_domain_owner functions. * 'stable/gntalloc.v7' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: xen/gntdev,gntalloc: Remove unneeded VM flags
This commit is contained in:
commit
5318991645
9 changed files with 208 additions and 31 deletions
|
|
@ -101,6 +101,7 @@ struct irq_info
|
|||
unsigned short gsi;
|
||||
unsigned char vector;
|
||||
unsigned char flags;
|
||||
uint16_t domid;
|
||||
} pirq;
|
||||
} u;
|
||||
};
|
||||
|
|
@ -184,6 +185,7 @@ static void xen_irq_info_pirq_init(unsigned irq,
|
|||
unsigned short pirq,
|
||||
unsigned short gsi,
|
||||
unsigned short vector,
|
||||
uint16_t domid,
|
||||
unsigned char flags)
|
||||
{
|
||||
struct irq_info *info = info_for_irq(irq);
|
||||
|
|
@ -193,6 +195,7 @@ static void xen_irq_info_pirq_init(unsigned irq,
|
|||
info->u.pirq.pirq = pirq;
|
||||
info->u.pirq.gsi = gsi;
|
||||
info->u.pirq.vector = vector;
|
||||
info->u.pirq.domid = domid;
|
||||
info->u.pirq.flags = flags;
|
||||
}
|
||||
|
||||
|
|
@ -655,7 +658,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
|
|||
goto out;
|
||||
}
|
||||
|
||||
xen_irq_info_pirq_init(irq, 0, pirq, gsi, irq_op.vector,
|
||||
xen_irq_info_pirq_init(irq, 0, pirq, gsi, irq_op.vector, DOMID_SELF,
|
||||
shareable ? PIRQ_SHAREABLE : 0);
|
||||
|
||||
out:
|
||||
|
|
@ -680,7 +683,8 @@ int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc)
|
|||
}
|
||||
|
||||
int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
|
||||
int pirq, int vector, const char *name)
|
||||
int pirq, int vector, const char *name,
|
||||
domid_t domid)
|
||||
{
|
||||
int irq, ret;
|
||||
|
||||
|
|
@ -693,7 +697,7 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
|
|||
irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq,
|
||||
name);
|
||||
|
||||
xen_irq_info_pirq_init(irq, 0, pirq, 0, vector, 0);
|
||||
xen_irq_info_pirq_init(irq, 0, pirq, 0, vector, domid, 0);
|
||||
ret = irq_set_msi_desc(irq, msidesc);
|
||||
if (ret < 0)
|
||||
goto error_irq;
|
||||
|
|
@ -722,9 +726,16 @@ int xen_destroy_irq(int irq)
|
|||
|
||||
if (xen_initial_domain()) {
|
||||
unmap_irq.pirq = info->u.pirq.pirq;
|
||||
unmap_irq.domid = DOMID_SELF;
|
||||
unmap_irq.domid = info->u.pirq.domid;
|
||||
rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq);
|
||||
if (rc) {
|
||||
/* If another domain quits without making the pci_disable_msix
|
||||
* call, the Xen hypervisor takes care of freeing the PIRQs
|
||||
* (free_domain_pirqs).
|
||||
*/
|
||||
if ((rc == -ESRCH && info->u.pirq.domid != DOMID_SELF))
|
||||
printk(KERN_INFO "domain %d does not have %d anymore\n",
|
||||
info->u.pirq.domid, info->u.pirq.pirq);
|
||||
else if (rc) {
|
||||
printk(KERN_WARNING "unmap irq failed %d\n", rc);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -759,6 +770,12 @@ out:
|
|||
return irq;
|
||||
}
|
||||
|
||||
|
||||
int xen_pirq_from_irq(unsigned irq)
|
||||
{
|
||||
return pirq_from_irq(irq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xen_pirq_from_irq);
|
||||
int bind_evtchn_to_irq(unsigned int evtchn)
|
||||
{
|
||||
int irq;
|
||||
|
|
@ -1502,6 +1519,18 @@ void xen_poll_irq(int irq)
|
|||
xen_poll_irq_timeout(irq, 0 /* no timeout */);
|
||||
}
|
||||
|
||||
/* Check whether the IRQ line is shared with other guests. */
|
||||
int xen_test_irq_shared(int irq)
|
||||
{
|
||||
struct irq_info *info = info_for_irq(irq);
|
||||
struct physdev_irq_status_query irq_status = { .irq = info->u.pirq.pirq };
|
||||
|
||||
if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status))
|
||||
return 0;
|
||||
return !(irq_status.flags & XENIRQSTAT_shared);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xen_test_irq_shared);
|
||||
|
||||
void xen_irq_resume(void)
|
||||
{
|
||||
unsigned int cpu, evtchn;
|
||||
|
|
|
|||
|
|
@ -427,6 +427,17 @@ static long gntalloc_ioctl(struct file *filp, unsigned int cmd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void gntalloc_vma_open(struct vm_area_struct *vma)
|
||||
{
|
||||
struct gntalloc_gref *gref = vma->vm_private_data;
|
||||
if (!gref)
|
||||
return;
|
||||
|
||||
spin_lock(&gref_lock);
|
||||
gref->users++;
|
||||
spin_unlock(&gref_lock);
|
||||
}
|
||||
|
||||
static void gntalloc_vma_close(struct vm_area_struct *vma)
|
||||
{
|
||||
struct gntalloc_gref *gref = vma->vm_private_data;
|
||||
|
|
@ -441,6 +452,7 @@ static void gntalloc_vma_close(struct vm_area_struct *vma)
|
|||
}
|
||||
|
||||
static struct vm_operations_struct gntalloc_vmops = {
|
||||
.open = gntalloc_vma_open,
|
||||
.close = gntalloc_vma_close,
|
||||
};
|
||||
|
||||
|
|
@ -471,8 +483,6 @@ static int gntalloc_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
vma->vm_private_data = gref;
|
||||
|
||||
vma->vm_flags |= VM_RESERVED;
|
||||
vma->vm_flags |= VM_DONTCOPY;
|
||||
vma->vm_flags |= VM_PFNMAP | VM_PFN_AT_MMAP;
|
||||
|
||||
vma->vm_ops = &gntalloc_vmops;
|
||||
|
||||
|
|
|
|||
|
|
@ -330,17 +330,26 @@ static int unmap_grant_pages(struct grant_map *map, int offset, int pages)
|
|||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void gntdev_vma_open(struct vm_area_struct *vma)
|
||||
{
|
||||
struct grant_map *map = vma->vm_private_data;
|
||||
|
||||
pr_debug("gntdev_vma_open %p\n", vma);
|
||||
atomic_inc(&map->users);
|
||||
}
|
||||
|
||||
static void gntdev_vma_close(struct vm_area_struct *vma)
|
||||
{
|
||||
struct grant_map *map = vma->vm_private_data;
|
||||
|
||||
pr_debug("close %p\n", vma);
|
||||
pr_debug("gntdev_vma_close %p\n", vma);
|
||||
map->vma = NULL;
|
||||
vma->vm_private_data = NULL;
|
||||
gntdev_put_map(map);
|
||||
}
|
||||
|
||||
static struct vm_operations_struct gntdev_vmops = {
|
||||
.open = gntdev_vma_open,
|
||||
.close = gntdev_vma_close,
|
||||
};
|
||||
|
||||
|
|
@ -652,7 +661,10 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
|
|||
|
||||
vma->vm_ops = &gntdev_vmops;
|
||||
|
||||
vma->vm_flags |= VM_RESERVED|VM_DONTCOPY|VM_DONTEXPAND|VM_PFNMAP;
|
||||
vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;
|
||||
|
||||
if (use_ptemod)
|
||||
vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP;
|
||||
|
||||
vma->vm_private_data = map;
|
||||
|
||||
|
|
|
|||
|
|
@ -466,13 +466,30 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
|
|||
if (map_ops[i].status)
|
||||
continue;
|
||||
|
||||
/* m2p override only supported for GNTMAP_contains_pte mappings */
|
||||
if (!(map_ops[i].flags & GNTMAP_contains_pte))
|
||||
continue;
|
||||
pte = (pte_t *) (mfn_to_virt(PFN_DOWN(map_ops[i].host_addr)) +
|
||||
if (map_ops[i].flags & GNTMAP_contains_pte) {
|
||||
pte = (pte_t *) (mfn_to_virt(PFN_DOWN(map_ops[i].host_addr)) +
|
||||
(map_ops[i].host_addr & ~PAGE_MASK));
|
||||
mfn = pte_mfn(*pte);
|
||||
ret = m2p_add_override(mfn, pages[i]);
|
||||
mfn = pte_mfn(*pte);
|
||||
} else {
|
||||
/* If you really wanted to do this:
|
||||
* mfn = PFN_DOWN(map_ops[i].dev_bus_addr);
|
||||
*
|
||||
* The reason we do not implement it is b/c on the
|
||||
* unmap path (gnttab_unmap_refs) we have no means of
|
||||
* checking whether the page is !GNTMAP_contains_pte.
|
||||
*
|
||||
* That is without some extra data-structure to carry
|
||||
* the struct page, bool clear_pte, and list_head next
|
||||
* tuples and deal with allocation/delallocation, etc.
|
||||
*
|
||||
* The users of this API set the GNTMAP_contains_pte
|
||||
* flag so lets just return not supported until it
|
||||
* becomes neccessary to implement.
|
||||
*/
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
ret = m2p_add_override(mfn, pages[i],
|
||||
map_ops[i].flags & GNTMAP_contains_pte);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -494,7 +511,7 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
|
|||
return ret;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = m2p_remove_override(pages[i]);
|
||||
ret = m2p_remove_override(pages[i], true /* clear the PTE */);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue