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

From: Andy Shevchenko
Date: Fri Aug 27 2021 - 02:59:24 EST


On Thu, Jun 24, 2021 at 6:59 PM Claire Chang <tientzu@xxxxxxxxxxxx> 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