* Such a DMA address is formed by using the grant reference as a frame
  * number and setting the highest address bit (this bit is for the backend
  * to be able to distinguish it from e.g. a mmio address).
- *
- * Note that for now we hard wire dom0 to be the backend domain. In order
- * to support any domain as backend we'd need to add a way to communicate
- * the domid of this backend, e.g. via Xenstore, via the PCI-device's
- * config space or DT/ACPI.
  */
 static void *xen_grant_dma_alloc(struct device *dev, size_t size,
                                 dma_addr_t *dma_handle, gfp_t gfp,
        .dma_supported = xen_grant_dma_supported,
 };
 
+bool xen_is_grant_dma_device(struct device *dev)
+{
+       struct device_node *iommu_np;
+       bool has_iommu;
+
+       /* XXX Handle only DT devices for now */
+       if (!dev->of_node)
+               return false;
+
+       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);
+
+       return has_iommu;
+}
+
 void xen_grant_setup_dma_ops(struct device *dev)
 {
        struct xen_grant_dma_data *data;
+       struct of_phandle_args iommu_spec;
 
        data = find_xen_grant_dma_data(dev);
        if (data) {
                return;
        }
 
+       /* XXX ACPI device unsupported for now */
+       if (!dev->of_node)
+               goto err;
+
+       if (of_parse_phandle_with_args(dev->of_node, "iommus", "#iommu-cells",
+                       0, &iommu_spec)) {
+               dev_err(dev, "Cannot parse iommus property\n");
+               goto err;
+       }
+
+       if (!of_device_is_compatible(iommu_spec.np, "xen,grant-dma") ||
+                       iommu_spec.args_count != 1) {
+               dev_err(dev, "Incompatible IOMMU node\n");
+               of_node_put(iommu_spec.np);
+               goto err;
+       }
+
+       of_node_put(iommu_spec.np);
+
        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
        if (!data)
                goto err;
 
-       /* XXX The dom0 is hardcoded as the backend domain for now */
-       data->backend_domid = 0;
+       /*
+        * The endpoint ID here means the ID of the domain where the corresponding
+        * backend is running
+        */
+       data->backend_domid = iommu_spec.args[0];
 
        if (xa_err(xa_store(&xen_grant_dma_devices, (unsigned long)dev, data,
                        GFP_KERNEL))) {