diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-12-12 10:55:53 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-12-12 10:55:53 -0800 |
commit | e6b160bc4daa1227695ef807e11097a3e9934d66 (patch) | |
tree | 2a39a4ded74b968752d69faed772bf50982de652 /drivers | |
parent | 0ec5a38bf8499f403f81cb81a0e3a60887d1993c (diff) | |
parent | 8b997b2bb2c53b76a6db6c195930e9ab8e4b0c79 (diff) |
Merge tag 'for-linus-6.2-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen updates from Juergen Gross:
- fix memory leaks in error paths
- add support for virtio PCI-devices in Xen guests on ARM
- two minor fixes
* tag 'for-linus-6.2-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
xen/privcmd: Fix a possible warning in privcmd_ioctl_mmap_resource()
x86/xen: Fix memory leak in xen_init_lock_cpu()
x86/xen: Fix memory leak in xen_smp_intr_init{_pv}()
xen: fix xen.h build for CONFIG_XEN_PVH=y
xen/virtio: Handle PCI devices which Host controller is described in DT
xen/virtio: Optimize the setup of "xen-grant-dma" devices
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/xen/grant-dma-ops.c | 105 | ||||
-rw-r--r-- | drivers/xen/privcmd.c | 2 |
2 files changed, 59 insertions, 48 deletions
diff --git a/drivers/xen/grant-dma-ops.c b/drivers/xen/grant-dma-ops.c index daa525df7bdc..9784a77fa3c9 100644 --- a/drivers/xen/grant-dma-ops.c +++ b/drivers/xen/grant-dma-ops.c @@ -10,6 +10,7 @@ #include <linux/module.h> #include <linux/dma-map-ops.h> #include <linux/of.h> +#include <linux/pci.h> #include <linux/pfn.h> #include <linux/xarray.h> #include <linux/virtio_anchor.h> @@ -292,50 +293,48 @@ static const struct dma_map_ops xen_grant_dma_ops = { .dma_supported = xen_grant_dma_supported, }; -static bool xen_is_dt_grant_dma_device(struct device *dev) +static struct device_node *xen_dt_get_node(struct device *dev) { - struct device_node *iommu_np; - bool has_iommu; + if (dev_is_pci(dev)) { + struct pci_dev *pdev = to_pci_dev(dev); + struct pci_bus *bus = pdev->bus; - iommu_np = of_parse_phandle(dev->of_node, "iommus", 0); - has_iommu = iommu_np && - of_device_is_compatible(iommu_np, "xen,grant-dma"); - of_node_put(iommu_np); + /* Walk up to the root bus to look for PCI Host controller */ + while (!pci_is_root_bus(bus)) + bus = bus->parent; - return has_iommu; -} - -bool xen_is_grant_dma_device(struct device *dev) -{ - /* XXX Handle only DT devices for now */ - if (dev->of_node) - return xen_is_dt_grant_dma_device(dev); - - return false; -} - -bool xen_virtio_mem_acc(struct virtio_device *dev) -{ - if (IS_ENABLED(CONFIG_XEN_VIRTIO_FORCE_GRANT) || xen_pv_domain()) - return true; + return of_node_get(bus->bridge->parent->of_node); + } - return xen_is_grant_dma_device(dev->dev.parent); + return of_node_get(dev->of_node); } static int xen_dt_grant_init_backend_domid(struct device *dev, - struct xen_grant_dma_data *data) + struct device_node *np, + domid_t *backend_domid) { - struct of_phandle_args iommu_spec; + struct of_phandle_args iommu_spec = { .args_count = 1 }; - if (of_parse_phandle_with_args(dev->of_node, "iommus", "#iommu-cells", - 0, &iommu_spec)) { - dev_err(dev, "Cannot parse iommus property\n"); - return -ESRCH; + if (dev_is_pci(dev)) { + struct pci_dev *pdev = to_pci_dev(dev); + u32 rid = PCI_DEVID(pdev->bus->number, pdev->devfn); + + if (of_map_id(np, rid, "iommu-map", "iommu-map-mask", &iommu_spec.np, + iommu_spec.args)) { + dev_dbg(dev, "Cannot translate ID\n"); + return -ESRCH; + } + } else { + if (of_parse_phandle_with_args(np, "iommus", "#iommu-cells", + 0, &iommu_spec)) { + dev_dbg(dev, "Cannot parse iommus property\n"); + return -ESRCH; + } } if (!of_device_is_compatible(iommu_spec.np, "xen,grant-dma") || iommu_spec.args_count != 1) { - dev_err(dev, "Incompatible IOMMU node\n"); + dev_dbg(dev, "Incompatible IOMMU node\n"); of_node_put(iommu_spec.np); return -ESRCH; } @@ -346,12 +345,31 @@ static int xen_dt_grant_init_backend_domid(struct device *dev, * The endpoint ID here means the ID of the domain where the * corresponding backend is running */ - data->backend_domid = iommu_spec.args[0]; + *backend_domid = iommu_spec.args[0]; return 0; } -void xen_grant_setup_dma_ops(struct device *dev) +static int xen_grant_init_backend_domid(struct device *dev, + domid_t *backend_domid) +{ + struct device_node *np; + int ret = -ENODEV; + + np = xen_dt_get_node(dev); + if (np) { + ret = xen_dt_grant_init_backend_domid(dev, np, backend_domid); + of_node_put(np); + } else if (IS_ENABLED(CONFIG_XEN_VIRTIO_FORCE_GRANT) || xen_pv_domain()) { + dev_info(dev, "Using dom0 as backend\n"); + *backend_domid = 0; + ret = 0; + } + + return ret; +} + +static void xen_grant_setup_dma_ops(struct device *dev, domid_t backend_domid) { struct xen_grant_dma_data *data; @@ -365,16 +383,7 @@ void xen_grant_setup_dma_ops(struct device *dev) if (!data) goto err; - if (dev->of_node) { - if (xen_dt_grant_init_backend_domid(dev, data)) - goto err; - } else if (IS_ENABLED(CONFIG_XEN_VIRTIO_FORCE_GRANT)) { - dev_info(dev, "Using dom0 as backend\n"); - data->backend_domid = 0; - } else { - /* XXX ACPI device unsupported for now */ - goto err; - } + data->backend_domid = backend_domid; if (store_xen_grant_dma_data(dev, data)) { dev_err(dev, "Cannot store Xen grant DMA data\n"); @@ -392,12 +401,14 @@ err: bool xen_virtio_restricted_mem_acc(struct virtio_device *dev) { - bool ret = xen_virtio_mem_acc(dev); + domid_t backend_domid; - if (ret) - xen_grant_setup_dma_ops(dev->dev.parent); + if (!xen_grant_init_backend_domid(dev->dev.parent, &backend_domid)) { + xen_grant_setup_dma_ops(dev->dev.parent, backend_domid); + return true; + } - return ret; + return false; } MODULE_DESCRIPTION("Xen grant DMA-mapping layer"); diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index fae50a24630b..1edf45ee9890 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -760,7 +760,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file, goto out; } - pfns = kcalloc(kdata.num, sizeof(*pfns), GFP_KERNEL); + pfns = kcalloc(kdata.num, sizeof(*pfns), GFP_KERNEL | __GFP_NOWARN); if (!pfns) { rc = -ENOMEM; goto out; |