From 13a1aaf64119ca170212b5a836b697aa0037a115 Mon Sep 17 00:00:00 2001 From: Srivatsa Vaddagiri Date: Wed, 6 Jan 2021 08:00:41 -0800 Subject: [PATCH 1/2] virtual io: mmio: Use memory-region attribute to get memory address Handled changed DT format to extract memory region address. Change-Id: Ia6b2d77c018d8639fe5eeaf6883e472f477bacc7 Signed-off-by: Srivatsa Vaddagiri --- drivers/virtio/virtio_mmio.c | 56 ++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index b7e5e617046e..0c47bdcf12a5 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -611,28 +612,45 @@ static phys_addr_t virtio_swiotlb_base; static phys_addr_t virtio_swiotlb_dma_base; static size_t virtio_swiotlb_size; -static int get_swiotlb_base(struct device_node *np, phys_addr_t *base, +static int virtio_get_shm(struct device_node *np, phys_addr_t *base, phys_addr_t *dma_base, size_t *size) { const __be64 *val; int len; + struct device_node *shm_np; + struct resource res_mem; + int ret; - val = of_get_property(np, "reg", &len); - if (!val || len != 16) + shm_np = of_parse_phandle(np, "memory-region", 0); + if (!shm_np) { + pr_err("%s: Invalid memory-region\n", __func__); return -EINVAL; + } - *base = __be64_to_cpup(val); - val++; - *size = __be64_to_cpup(val); - - if (!*base || !*size) + ret = of_address_to_resource(shm_np, 0, &res_mem); + if (ret) { + pr_err("%s: of_address_to_resource failed ret %d\n", __func__, ret); return -EINVAL; + } + + *base = res_mem.start; + *size = resource_size(&res_mem); + of_node_put(shm_np); + + if (!*base || !*size) { + pr_err("%s: Invalid memory-region base %llx size %d\n", __func__, *base, *size); + return -EINVAL; + } val = of_get_property(np, "dma_base", &len); - if (!val || len != 8) + if (!val || len != 8) { + pr_err("%s: Invalid dma_base prop val %llx size %d\n", __func__, val, len); return -EINVAL; + } *dma_base = __be64_to_cpup(val); + pr_debug("%s: shm base %llx size %llx dma_base %llx\n", __func__, *base, *size, *dma_base); + return 0; } @@ -650,7 +668,7 @@ static int __init virtio_swiotlb_init(void) if (!np) return 0; - ret = get_swiotlb_base(np, &base, &dma_base, &size); + ret = virtio_get_shm(np, &base, &dma_base, &size); of_node_put(np); if (ret) @@ -767,26 +785,14 @@ static inline int get_ring_base(struct platform_device *pdev, phys_addr_t *ring_base, phys_addr_t *ring_dma_base, size_t *ring_size) { - struct device *dev = &pdev->dev; - const __be64 *val; - int len; + int ret; if (!virtio_swiotlb_base) return 0; - val = of_get_property(pdev->dev.of_node, "ring_base", &len); - if (!val || len != 24) - return 0; + ret = virtio_get_shm(pdev->dev.of_node, ring_base, ring_dma_base, ring_size); - *ring_base = __be64_to_cpup(val); - val++; - *ring_dma_base = __be64_to_cpup(val); - val++; - *ring_size = __be64_to_cpup(val); - - dev_dbg(dev, "ring_base %pK ring_dma_base %pK ring_size %llx\n", - *ring_base, *ring_dma_base, *ring_size); - return 1; + return ret ? 0 : 1; } static int setup_virtio_dma_ops(struct platform_device *pdev) From 8dbe481c4553f8bdd6d146e2d85ddefb8587f2b6 Mon Sep 17 00:00:00 2001 From: Srivatsa Vaddagiri Date: Thu, 7 Jan 2021 09:08:14 -0800 Subject: [PATCH 2/2] swiotlb: Limit max bounce buffer size Limiting to 4096, assuming this is used for virtual io block device. The default maximum (256kB) would result in overflowing of bounce buffers and stalling of IO (max_segments of 254 for block device and max bounce size of 256kB could result in block layer submitting a huge IO request that can never be finished successfully). With 4096, we have the max size of request set to 254*4096, which is a reasonable space to set aside per block device. Change-Id: I8a3b0ec6d26a1b7f5ccdcee649f02c3556bce93b Signed-off-by: Srivatsa Vaddagiri --- kernel/dma/swiotlb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index c0e877cf4348..342e3694ca25 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -794,7 +794,12 @@ dma_addr_t swiotlb_map(struct device *dev, phys_addr_t paddr, size_t size, } #ifdef CONFIG_SWIOTLB_NONLINEAR EXPORT_SYMBOL(swiotlb_map); -#endif + +size_t swiotlb_max_mapping_size(struct device *dev) +{ + return 4096; +} +#else size_t swiotlb_max_mapping_size(struct device *dev) { @@ -811,6 +816,7 @@ size_t swiotlb_max_mapping_size(struct device *dev) return ((size_t)IO_TLB_SIZE) * IO_TLB_SEGSIZE - min_align; } +#endif bool is_swiotlb_active(struct device *dev) {