Skip to content

Commit 625ab90

Browse files
Oleksandr Tyshchenkojgross1
authored andcommitted
xen/grant-dma-ops: Retrieve the ID of backend's domain for DT devices
Use the presence of "iommus" property pointed to the IOMMU node with recently introduced "xen,grant-dma" compatible as a clear indicator of enabling Xen grant mappings scheme for that device and read the ID of Xen domain where the corresponding backend is running. The domid (domain ID) is used as an argument to the Xen grant mapping APIs. To avoid the deferred probe timeout which takes place after reusing generic IOMMU device tree bindings (because the IOMMU device never becomes available) enable recently introduced stub IOMMU driver by selecting XEN_GRANT_DMA_IOMMU. Also introduce xen_is_grant_dma_device() to check whether xen-grant DMA ops need to be set for a passed device. Remove the hardcoded domid 0 in xen_grant_setup_dma_ops(). Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Link: https://lore.kernel.org/r/1654197833-25362-8-git-send-email-olekstysh@gmail.com Signed-off-by: Juergen Gross <jgross@suse.com>
1 parent 1ca55d5 commit 625ab90

3 files changed

Lines changed: 47 additions & 7 deletions

File tree

drivers/xen/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ config XEN_VIRTIO
347347
bool "Xen virtio support"
348348
depends on VIRTIO
349349
select XEN_GRANT_DMA_OPS
350+
select XEN_GRANT_DMA_IOMMU if OF
350351
help
351352
Enable virtio support for running as Xen guest. Depending on the
352353
guest type this will require special support on the backend side

drivers/xen/grant-dma-ops.c

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,6 @@ static struct xen_grant_dma_data *find_xen_grant_dma_data(struct device *dev)
5656
* Such a DMA address is formed by using the grant reference as a frame
5757
* number and setting the highest address bit (this bit is for the backend
5858
* to be able to distinguish it from e.g. a mmio address).
59-
*
60-
* Note that for now we hard wire dom0 to be the backend domain. In order
61-
* to support any domain as backend we'd need to add a way to communicate
62-
* the domid of this backend, e.g. via Xenstore, via the PCI-device's
63-
* config space or DT/ACPI.
6459
*/
6560
static void *xen_grant_dma_alloc(struct device *dev, size_t size,
6661
dma_addr_t *dma_handle, gfp_t gfp,
@@ -276,22 +271,61 @@ static const struct dma_map_ops xen_grant_dma_ops = {
276271
.dma_supported = xen_grant_dma_supported,
277272
};
278273

274+
bool xen_is_grant_dma_device(struct device *dev)
275+
{
276+
struct device_node *iommu_np;
277+
bool has_iommu;
278+
279+
/* XXX Handle only DT devices for now */
280+
if (!dev->of_node)
281+
return false;
282+
283+
iommu_np = of_parse_phandle(dev->of_node, "iommus", 0);
284+
has_iommu = iommu_np && of_device_is_compatible(iommu_np, "xen,grant-dma");
285+
of_node_put(iommu_np);
286+
287+
return has_iommu;
288+
}
289+
279290
void xen_grant_setup_dma_ops(struct device *dev)
280291
{
281292
struct xen_grant_dma_data *data;
293+
struct of_phandle_args iommu_spec;
282294

283295
data = find_xen_grant_dma_data(dev);
284296
if (data) {
285297
dev_err(dev, "Xen grant DMA data is already created\n");
286298
return;
287299
}
288300

301+
/* XXX ACPI device unsupported for now */
302+
if (!dev->of_node)
303+
goto err;
304+
305+
if (of_parse_phandle_with_args(dev->of_node, "iommus", "#iommu-cells",
306+
0, &iommu_spec)) {
307+
dev_err(dev, "Cannot parse iommus property\n");
308+
goto err;
309+
}
310+
311+
if (!of_device_is_compatible(iommu_spec.np, "xen,grant-dma") ||
312+
iommu_spec.args_count != 1) {
313+
dev_err(dev, "Incompatible IOMMU node\n");
314+
of_node_put(iommu_spec.np);
315+
goto err;
316+
}
317+
318+
of_node_put(iommu_spec.np);
319+
289320
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
290321
if (!data)
291322
goto err;
292323

293-
/* XXX The dom0 is hardcoded as the backend domain for now */
294-
data->backend_domid = 0;
324+
/*
325+
* The endpoint ID here means the ID of the domain where the corresponding
326+
* backend is running
327+
*/
328+
data->backend_domid = iommu_spec.args[0];
295329

296330
if (xa_err(xa_store(&xen_grant_dma_devices, (unsigned long)dev, data,
297331
GFP_KERNEL))) {

include/xen/xen-ops.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,15 @@ static inline void xen_preemptible_hcall_end(void) { }
216216

217217
#ifdef CONFIG_XEN_GRANT_DMA_OPS
218218
void xen_grant_setup_dma_ops(struct device *dev);
219+
bool xen_is_grant_dma_device(struct device *dev);
219220
#else
220221
static inline void xen_grant_setup_dma_ops(struct device *dev)
221222
{
222223
}
224+
static inline bool xen_is_grant_dma_device(struct device *dev)
225+
{
226+
return false;
227+
}
223228
#endif /* CONFIG_XEN_GRANT_DMA_OPS */
224229

225230
#endif /* INCLUDE_XEN_OPS_H */

0 commit comments

Comments
 (0)