Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI/IORT: Handle memory address size limits as limits

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>

authored by

Robin Murphy and committed by
Joerg Roedel
91cfd679 ba503cf4

+15 -18
+3 -6
drivers/acpi/arm64/dma.c
··· 8 8 { 9 9 int ret; 10 10 u64 end, mask; 11 - u64 size = 0; 12 11 const struct bus_dma_region *map = NULL; 13 12 14 13 /* ··· 22 23 } 23 24 24 25 if (dev->coherent_dma_mask) 25 - size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1); 26 + end = dev->coherent_dma_mask; 26 27 else 27 - size = 1ULL << 32; 28 + end = (1ULL << 32) - 1; 28 29 29 30 ret = acpi_dma_get_range(dev, &map); 30 31 if (!ret && map) { ··· 35 36 end = r->dma_start + r->size - 1; 36 37 } 37 38 38 - size = end + 1; 39 39 dev->dma_range_map = map; 40 40 } 41 41 42 42 if (ret == -ENODEV) 43 - ret = iort_dma_get_ranges(dev, &size); 43 + ret = iort_dma_get_ranges(dev, &end); 44 44 if (!ret) { 45 45 /* 46 46 * Limit coherent and dma mask based on size retrieved from 47 47 * firmware. 48 48 */ 49 - end = size - 1; 50 49 mask = DMA_BIT_MASK(ilog2(end) + 1); 51 50 dev->bus_dma_limit = end; 52 51 dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
+10 -10
drivers/acpi/arm64/iort.c
··· 1367 1367 { return -ENODEV; } 1368 1368 #endif 1369 1369 1370 - static int nc_dma_get_range(struct device *dev, u64 *size) 1370 + static int nc_dma_get_range(struct device *dev, u64 *limit) 1371 1371 { 1372 1372 struct acpi_iort_node *node; 1373 1373 struct acpi_iort_named_component *ncomp; ··· 1384 1384 return -EINVAL; 1385 1385 } 1386 1386 1387 - *size = ncomp->memory_address_limit >= 64 ? U64_MAX : 1388 - 1ULL<<ncomp->memory_address_limit; 1387 + *limit = ncomp->memory_address_limit >= 64 ? U64_MAX : 1388 + (1ULL << ncomp->memory_address_limit) - 1; 1389 1389 1390 1390 return 0; 1391 1391 } 1392 1392 1393 - static int rc_dma_get_range(struct device *dev, u64 *size) 1393 + static int rc_dma_get_range(struct device *dev, u64 *limit) 1394 1394 { 1395 1395 struct acpi_iort_node *node; 1396 1396 struct acpi_iort_root_complex *rc; ··· 1408 1408 return -EINVAL; 1409 1409 } 1410 1410 1411 - *size = rc->memory_address_limit >= 64 ? U64_MAX : 1412 - 1ULL<<rc->memory_address_limit; 1411 + *limit = rc->memory_address_limit >= 64 ? U64_MAX : 1412 + (1ULL << rc->memory_address_limit) - 1; 1413 1413 1414 1414 return 0; 1415 1415 } ··· 1417 1417 /** 1418 1418 * iort_dma_get_ranges() - Look up DMA addressing limit for the device 1419 1419 * @dev: device to lookup 1420 - * @size: DMA range size result pointer 1420 + * @limit: DMA limit result pointer 1421 1421 * 1422 1422 * Return: 0 on success, an error otherwise. 1423 1423 */ 1424 - int iort_dma_get_ranges(struct device *dev, u64 *size) 1424 + int iort_dma_get_ranges(struct device *dev, u64 *limit) 1425 1425 { 1426 1426 if (dev_is_pci(dev)) 1427 - return rc_dma_get_range(dev, size); 1427 + return rc_dma_get_range(dev, limit); 1428 1428 else 1429 - return nc_dma_get_range(dev, size); 1429 + return nc_dma_get_range(dev, limit); 1430 1430 } 1431 1431 1432 1432 static void __init acpi_iort_register_irq(int hwirq, const char *name,
+2 -2
include/linux/acpi_iort.h
··· 39 39 void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode, 40 40 struct list_head *head); 41 41 /* IOMMU interface */ 42 - int iort_dma_get_ranges(struct device *dev, u64 *size); 42 + int iort_dma_get_ranges(struct device *dev, u64 *limit); 43 43 int iort_iommu_configure_id(struct device *dev, const u32 *id_in); 44 44 void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head); 45 45 phys_addr_t acpi_iort_dma_get_max_cpu_address(void); ··· 55 55 static inline 56 56 void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode, struct list_head *head) { } 57 57 /* IOMMU interface */ 58 - static inline int iort_dma_get_ranges(struct device *dev, u64 *size) 58 + static inline int iort_dma_get_ranges(struct device *dev, u64 *limit) 59 59 { return -ENODEV; } 60 60 static inline int iort_iommu_configure_id(struct device *dev, const u32 *id_in) 61 61 { return -ENODEV; }