Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 692b8c66 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull xen bug fixes from David Vrabel:

 - Two scsiback fixes (resource leak and spurious warning).

 - Fix DMA mapping of compound pages on arm/arm64.

 - Fix some pciback regressions in MSI-X handling.

 - Fix a pcifront crash due to some uninitialize state.

* tag 'for-linus-4.5-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen/pcifront: Fix mysterious crashes when NUMA locality information was extracted.
  xen/pcifront: Report the errors better.
  xen/pciback: Save the number of MSI-X entries to be copied later.
  xen/pciback: Check PF instead of VF for PCI_COMMAND_MEMORY
  xen: fix potential integer overflow in queue_reply
  xen/arm: correctly handle DMA mapping of compound pages
  xen/scsiback: avoid warnings when adding multiple LUNs to a domain
  xen/scsiback: correct frontend counting
parents dea08e60 4d8c8bd6
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -35,14 +35,21 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
	     dma_addr_t dev_addr, unsigned long offset, size_t size,
	     enum dma_data_direction dir, struct dma_attrs *attrs)
{
	bool local = XEN_PFN_DOWN(dev_addr) == page_to_xen_pfn(page);
	unsigned long page_pfn = page_to_xen_pfn(page);
	unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
	unsigned long compound_pages =
		(1<<compound_order(page)) * XEN_PFN_PER_PAGE;
	bool local = (page_pfn <= dev_pfn) &&
		(dev_pfn - page_pfn < compound_pages);

	/*
	 * Dom0 is mapped 1:1, while the Linux page can be spanned accross
	 * multiple Xen page, it's not possible to have a mix of local and
	 * foreign Xen page. So if the first xen_pfn == mfn the page is local
	 * otherwise it's a foreign page grant-mapped in dom0. If the page is
	 * local we can safely call the native dma_ops function, otherwise we
	 * call the xen specific function.
	 * Dom0 is mapped 1:1, while the Linux page can span across
	 * multiple Xen pages, it's not possible for it to contain a
	 * mix of local and foreign Xen pages. So if the first xen_pfn
	 * == mfn the page is local otherwise it's a foreign page
	 * grant-mapped in dom0. If the page is local we can safely
	 * call the native dma_ops function, otherwise we call the xen
	 * specific function.
	 */
	if (local)
		__generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
+2 −2
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ static inline int xen_pci_frontend_enable_msi(struct pci_dev *dev,
{
	if (xen_pci_frontend && xen_pci_frontend->enable_msi)
		return xen_pci_frontend->enable_msi(dev, vectors);
	return -ENODEV;
	return -ENOSYS;
}
static inline void xen_pci_frontend_disable_msi(struct pci_dev *dev)
{
@@ -69,7 +69,7 @@ static inline int xen_pci_frontend_enable_msix(struct pci_dev *dev,
{
	if (xen_pci_frontend && xen_pci_frontend->enable_msix)
		return xen_pci_frontend->enable_msix(dev, vectors, nvec);
	return -ENODEV;
	return -ENOSYS;
}
static inline void xen_pci_frontend_disable_msix(struct pci_dev *dev)
{
+4 −1
Original line number Diff line number Diff line
@@ -196,7 +196,10 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
	return 0;

error:
	if (ret == -ENOSYS)
		dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n");
	else if (ret)
		dev_err(&dev->dev, "Xen PCI frontend error: %d!\n", ret);
free:
	kfree(v);
	return ret;
+6 −4
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ struct pcifront_device {
};

struct pcifront_sd {
	int domain;
	struct pci_sysdata sd;
	struct pcifront_device *pdev;
};

@@ -67,7 +67,9 @@ static inline void pcifront_init_sd(struct pcifront_sd *sd,
				    unsigned int domain, unsigned int bus,
				    struct pcifront_device *pdev)
{
	sd->domain = domain;
	/* Because we do not expose that information via XenBus. */
	sd->sd.node = first_online_node;
	sd->sd.domain = domain;
	sd->pdev = pdev;
}

@@ -468,8 +470,8 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
	dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
		 domain, bus);

	bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
	sd = kmalloc(sizeof(*sd), GFP_KERNEL);
	bus_entry = kzalloc(sizeof(*bus_entry), GFP_KERNEL);
	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
	if (!bus_entry || !sd) {
		err = -ENOMEM;
		goto err_out;
+7 −2
Original line number Diff line number Diff line
@@ -227,8 +227,9 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
	/*
	 * PCI_COMMAND_MEMORY must be enabled, otherwise we may not be able
	 * to access the BARs where the MSI-X entries reside.
	 * But VF devices are unique in which the PF needs to be checked.
	 */
	pci_read_config_word(dev, PCI_COMMAND, &cmd);
	pci_read_config_word(pci_physfn(dev), PCI_COMMAND, &cmd);
	if (dev->msi_enabled || !(cmd & PCI_COMMAND_MEMORY))
		return -ENXIO;

@@ -332,6 +333,9 @@ void xen_pcibk_do_op(struct work_struct *data)
	struct xen_pcibk_dev_data *dev_data = NULL;
	struct xen_pci_op *op = &pdev->op;
	int test_intx = 0;
#ifdef CONFIG_PCI_MSI
	unsigned int nr = 0;
#endif

	*op = pdev->sh_info->op;
	barrier();
@@ -360,6 +364,7 @@ void xen_pcibk_do_op(struct work_struct *data)
			op->err = xen_pcibk_disable_msi(pdev, dev, op);
			break;
		case XEN_PCI_OP_enable_msix:
			nr = op->value;
			op->err = xen_pcibk_enable_msix(pdev, dev, op);
			break;
		case XEN_PCI_OP_disable_msix:
@@ -382,7 +387,7 @@ void xen_pcibk_do_op(struct work_struct *data)
	if (op->cmd == XEN_PCI_OP_enable_msix && op->err == 0) {
		unsigned int i;

		for (i = 0; i < op->value; i++)
		for (i = 0; i < nr; i++)
			pdev->sh_info->op.msix_entries[i].vector =
				op->msix_entries[i].vector;
	}
Loading