Thread (48 messages) 48 messages, 9 authors, 2021-08-27

Re: [PATCH v15 10/12] swiotlb: Add restricted DMA pool initialization

From: Andy Shevchenko <hidden>
Date: 2021-08-27 06:59:19
Also in: dri-devel, intel-gfx, linux-devicetree, linux-iommu, linux-pci, lkml, xen-devel

On Thu, Jun 24, 2021 at 6:59 PM Claire Chang [off-list ref] wrote:
Add the initialization function to create restricted DMA pools from
matching reserved-memory nodes.

Regardless of swiotlb setting, the restricted DMA pool is preferred if
available.

The restricted DMA pools provide a basic level of protection against the
DMA overwriting buffer contents at unexpected times. However, to protect
against general data leakage and system memory corruption, the system
needs to provide a way to lock down the memory access, e.g., MPU.



+static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
+                                   struct device *dev)
+{
+       struct io_tlb_mem *mem = rmem->priv;
+       unsigned long nslabs = rmem->size >> IO_TLB_SHIFT;
+
+       /*
+        * Since multiple devices can share the same pool, the private data,
+        * io_tlb_mem struct, will be initialized by the first device attached
+        * to it.
+        */
+       if (!mem) {
Can it be rather

if (mem)
  goto out_assign;

or so?
+               mem = kzalloc(struct_size(mem, slots, nslabs), GFP_KERNEL);
+               if (!mem)
+                       return -ENOMEM;
+
+               set_memory_decrypted((unsigned long)phys_to_virt(rmem->base),
+                                    rmem->size >> PAGE_SHIFT);
Below you are using a macro from pfn.h, but not here, I think it's PFN_DOWN().
+               swiotlb_init_io_tlb_mem(mem, rmem->base, nslabs, false);
+               mem->force_bounce = true;
+               mem->for_alloc = true;
+
+               rmem->priv = mem;
+
+               if (IS_ENABLED(CONFIG_DEBUG_FS)) {
+                       mem->debugfs =
+                               debugfs_create_dir(rmem->name, debugfs_dir);
+                       swiotlb_create_debugfs_files(mem);
+               }
+       }
+
+       dev->dma_io_tlb_mem = mem;
+
+       return 0;
+}
+
+static void rmem_swiotlb_device_release(struct reserved_mem *rmem,
+                                       struct device *dev)
+{
+       dev->dma_io_tlb_mem = io_tlb_default_mem;
+}
+
+static const struct reserved_mem_ops rmem_swiotlb_ops = {
+       .device_init = rmem_swiotlb_device_init,
+       .device_release = rmem_swiotlb_device_release,
+};
+
+static int __init rmem_swiotlb_setup(struct reserved_mem *rmem)
+{
+       unsigned long node = rmem->fdt_node;
+
+       if (of_get_flat_dt_prop(node, "reusable", NULL) ||
+           of_get_flat_dt_prop(node, "linux,cma-default", NULL) ||
+           of_get_flat_dt_prop(node, "linux,dma-default", NULL) ||
+           of_get_flat_dt_prop(node, "no-map", NULL))
+               return -EINVAL;
+
+       if (PageHighMem(pfn_to_page(PHYS_PFN(rmem->base)))) {
+               pr_err("Restricted DMA pool must be accessible within the linear mapping.");
+               return -EINVAL;
+       }
+
+       rmem->ops = &rmem_swiotlb_ops;
+       pr_info("Reserved memory: created restricted DMA pool at %pa, size %ld MiB\n",
+               &rmem->base, (unsigned long)rmem->size / SZ_1M);
Oh là là, besides explicit casting that I believe can be avoided, %ld
!= unsigned long. Can you check the printk-formats.rst document?
+       return 0;
+}
+
+RESERVEDMEM_OF_DECLARE(dma, "restricted-dma-pool", rmem_swiotlb_setup);
 #endif /* CONFIG_DMA_RESTRICTED_POOL */
-- 
With Best Regards,
Andy Shevchenko
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help