ACPI/IORT: Handle memory address size limits as limits
authorRobin Murphy <robin.murphy@arm.com>
Fri, 19 Apr 2024 16:54:42 +0000 (17:54 +0100)
committerJoerg Roedel <jroedel@suse.de>
Fri, 26 Apr 2024 10:07:23 +0000 (12:07 +0200)
Return the Root Complex/Named Component memory address size limit as an
inclusive limit value, rather than an exclusive size. This saves having
to fudge an off-by-one for the 64-bit case, and simplifies our caller.

Acked-by: Hanjun Guo <guohanjun@huawei.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Hanjun Guo <guohanjun@huawei.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Link: https://lore.kernel.org/r/284ae9fbadb12f2e3b5a30cd4d037d0e6843a8f4.1713523152.git.robin.murphy@arm.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/acpi/arm64/dma.c
drivers/acpi/arm64/iort.c
include/linux/acpi_iort.h

index 93d796531af307d59965e7bf62a2d70a1fa13a75..b98a149f8d509f75c07c869a71953ffd80b657da 100644 (file)
@@ -8,7 +8,6 @@ void acpi_arch_dma_setup(struct device *dev)
 {
        int ret;
        u64 end, mask;
-       u64 size = 0;
        const struct bus_dma_region *map = NULL;
 
        /*
@@ -23,9 +22,9 @@ void acpi_arch_dma_setup(struct device *dev)
        }
 
        if (dev->coherent_dma_mask)
-               size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
+               end = dev->coherent_dma_mask;
        else
-               size = 1ULL << 32;
+               end = (1ULL << 32) - 1;
 
        ret = acpi_dma_get_range(dev, &map);
        if (!ret && map) {
@@ -36,18 +35,16 @@ void acpi_arch_dma_setup(struct device *dev)
                                end = r->dma_start + r->size - 1;
                }
 
-               size = end + 1;
                dev->dma_range_map = map;
        }
 
        if (ret == -ENODEV)
-               ret = iort_dma_get_ranges(dev, &size);
+               ret = iort_dma_get_ranges(dev, &end);
        if (!ret) {
                /*
                 * Limit coherent and dma mask based on size retrieved from
                 * firmware.
                 */
-               end = size - 1;
                mask = DMA_BIT_MASK(ilog2(end) + 1);
                dev->bus_dma_limit = end;
                dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
index 6496ff5a6ba20d50773ef84673d28c5748cd0dd3..c0b1c2c194442b71eeea02d56838117eb41d2e9a 100644 (file)
@@ -1367,7 +1367,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *input_id)
 { return -ENODEV; }
 #endif
 
-static int nc_dma_get_range(struct device *dev, u64 *size)
+static int nc_dma_get_range(struct device *dev, u64 *limit)
 {
        struct acpi_iort_node *node;
        struct acpi_iort_named_component *ncomp;
@@ -1384,13 +1384,13 @@ static int nc_dma_get_range(struct device *dev, u64 *size)
                return -EINVAL;
        }
 
-       *size = ncomp->memory_address_limit >= 64 ? U64_MAX :
-                       1ULL<<ncomp->memory_address_limit;
+       *limit = ncomp->memory_address_limit >= 64 ? U64_MAX :
+                       (1ULL << ncomp->memory_address_limit) - 1;
 
        return 0;
 }
 
-static int rc_dma_get_range(struct device *dev, u64 *size)
+static int rc_dma_get_range(struct device *dev, u64 *limit)
 {
        struct acpi_iort_node *node;
        struct acpi_iort_root_complex *rc;
@@ -1408,8 +1408,8 @@ static int rc_dma_get_range(struct device *dev, u64 *size)
                return -EINVAL;
        }
 
-       *size = rc->memory_address_limit >= 64 ? U64_MAX :
-                       1ULL<<rc->memory_address_limit;
+       *limit = rc->memory_address_limit >= 64 ? U64_MAX :
+                       (1ULL << rc->memory_address_limit) - 1;
 
        return 0;
 }
@@ -1417,16 +1417,16 @@ static int rc_dma_get_range(struct device *dev, u64 *size)
 /**
  * iort_dma_get_ranges() - Look up DMA addressing limit for the device
  * @dev: device to lookup
- * @size: DMA range size result pointer
+ * @limit: DMA limit result pointer
  *
  * Return: 0 on success, an error otherwise.
  */
-int iort_dma_get_ranges(struct device *dev, u64 *size)
+int iort_dma_get_ranges(struct device *dev, u64 *limit)
 {
        if (dev_is_pci(dev))
-               return rc_dma_get_range(dev, size);
+               return rc_dma_get_range(dev, limit);
        else
-               return nc_dma_get_range(dev, size);
+               return nc_dma_get_range(dev, limit);
 }
 
 static void __init acpi_iort_register_irq(int hwirq, const char *name,
index 1cb65592c95dd3376e6ca66b629bb69bb11a5dd7..d4ed5622cf2b02060e6f748177e6286afff094e2 100644 (file)
@@ -39,7 +39,7 @@ void iort_get_rmr_sids(struct fwnode_handle *iommu_fwnode,
 void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
                       struct list_head *head);
 /* IOMMU interface */
-int iort_dma_get_ranges(struct device *dev, u64 *size);
+int iort_dma_get_ranges(struct device *dev, u64 *limit);
 int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
 void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
 phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
@@ -55,7 +55,7 @@ void iort_get_rmr_sids(struct fwnode_handle *iommu_fwnode, struct list_head *hea
 static inline
 void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode, struct list_head *head) { }
 /* IOMMU interface */
-static inline int iort_dma_get_ranges(struct device *dev, u64 *size)
+static inline int iort_dma_get_ranges(struct device *dev, u64 *limit)
 { return -ENODEV; }
 static inline int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 { return -ENODEV; }