* [PATCH 1/2] ACPI/IORT: add iort_get_memory_address_limit function @ 2017-01-31 20:16 Nate Watterson 2017-01-31 20:16 ` [PATCH 2/2] arm64/dma-mapping: validate dma_masks against IORT defined limits Nate Watterson 0 siblings, 1 reply; 2+ messages in thread From: Nate Watterson @ 2017-01-31 20:16 UTC (permalink / raw) To: Lorenzo Pieralisi, Hanjun Guo, Sudeep Holla, Rafael J. Wysocki, Len Brown, Tomasz Nowicki, Will Deacon, Nate Watterson, linux-acpi, linux-kernel The memory_address_limit field present in IORT named component nodes describes the effective number of address bits that a device can use when accessing memory. Because this information has value when creating or validating device dma_masks, the aforementioned accessor function is introduced. Signed-off-by: Nate Watterson <nwatters@codeaurora.org> --- drivers/acpi/arm64/iort.c | 25 +++++++++++++++++++++++++ include/linux/acpi_iort.h | 3 +++ 2 files changed, 28 insertions(+) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index e0d2e6e..cd5d5f4 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -569,6 +569,31 @@ void iort_set_dma_mask(struct device *dev) } /** + * iort_get_memory_address_limit - If a named component node exists in the IORT + * for a device, get the number of address bits + * that the device can effectively use when + * accessing memory. + * + * @dev: The device + * + * Returns: ENOENT when no corresponding named component node found for dev + * Named component memory_address_limit field otherwise + */ +int iort_get_memory_address_limit(struct device *dev) +{ + struct acpi_iort_node *node; + struct acpi_iort_named_component *ncomp; + + node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, + iort_match_node_callback, dev); + if (!node) + return -ENOENT; + + ncomp = (struct acpi_iort_named_component *)node->node_data; + return ncomp->memory_address_limit; +} + +/** * iort_iommu_configure - Set-up IOMMU configuration for a device. * * @dev: device to configure diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h index 77e0809..677b9c4 100644 --- a/include/linux/acpi_iort.h +++ b/include/linux/acpi_iort.h @@ -36,6 +36,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id); /* IOMMU interface */ void iort_set_dma_mask(struct device *dev); +int iort_get_memory_address_limit(struct device *dev); const struct iommu_ops *iort_iommu_configure(struct device *dev); #else static inline void acpi_iort_init(void) { } @@ -47,6 +48,8 @@ static inline struct irq_domain *iort_get_device_domain(struct device *dev, { return NULL; } /* IOMMU interface */ static inline void iort_set_dma_mask(struct device *dev) { } +static inline int iort_get_memory_address_limit(struct device *dev) +{ return -ENOENT; } static inline const struct iommu_ops *iort_iommu_configure(struct device *dev) { return NULL; } -- Qualcomm Datacenter Technologies, Inc. on behalf of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. ^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 2/2] arm64/dma-mapping: validate dma_masks against IORT defined limits 2017-01-31 20:16 [PATCH 1/2] ACPI/IORT: add iort_get_memory_address_limit function Nate Watterson @ 2017-01-31 20:16 ` Nate Watterson 0 siblings, 0 replies; 2+ messages in thread From: Nate Watterson @ 2017-01-31 20:16 UTC (permalink / raw) To: Catalin Marinas, Will Deacon, Robin Murphy, Joerg Roedel, Geert Uytterhoeven, Jisheng Zhang, Nate Watterson, Marek Szyprowski, Lorenzo Pieralisi, Krzysztof Kozlowski, linux-arm-kernel, linux-kernel Some drivers set the dma_mask of client devices based solely on values read from capability registers which may not account for platform specific bus address width limitations. Fortunately, the ACPI IORT table provides a way to report the effective number of address bits a device can use to access memory. This information, when present, is used to supplement the checks already being done in dma_supported() to avoid setting overly generous dma_masks. Signed-off-by: Nate Watterson <nwatters@codeaurora.org> --- arch/arm64/mm/dma-mapping.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index e040827..467fd23 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -19,6 +19,7 @@ #include <linux/gfp.h> #include <linux/acpi.h> +#include <linux/acpi_iort.h> #include <linux/bootmem.h> #include <linux/cache.h> #include <linux/export.h> @@ -347,6 +348,12 @@ static int __swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt, static int __swiotlb_dma_supported(struct device *hwdev, u64 mask) { + int dma_limit; + + dma_limit = iort_get_memory_address_limit(hwdev); + if (dma_limit >= 0 && DMA_BIT_MASK(dma_limit) < mask) + return 0; + if (swiotlb) return swiotlb_dma_supported(hwdev, mask); return 1; @@ -784,6 +791,17 @@ static void __iommu_unmap_sg_attrs(struct device *dev, iommu_dma_unmap_sg(dev, sgl, nelems, dir, attrs); } +static int __iommu_dma_supported(struct device *hwdev, u64 mask) +{ + int dma_limit; + + dma_limit = iort_get_memory_address_limit(hwdev); + if (dma_limit >= 0 && DMA_BIT_MASK(dma_limit) < mask) + return 0; + + return iommu_dma_supported(hwdev, mask); +} + static struct dma_map_ops iommu_dma_ops = { .alloc = __iommu_alloc_attrs, .free = __iommu_free_attrs, @@ -799,7 +817,7 @@ static void __iommu_unmap_sg_attrs(struct device *dev, .sync_sg_for_device = __iommu_sync_sg_for_device, .map_resource = iommu_dma_map_resource, .unmap_resource = iommu_dma_unmap_resource, - .dma_supported = iommu_dma_supported, + .dma_supported = __iommu_dma_supported, .mapping_error = iommu_dma_mapping_error, }; -- Qualcomm Datacenter Technologies, Inc. on behalf of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. ^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2017-01-31 20:21 UTC | newest] Thread overview: 2+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-01-31 20:16 [PATCH 1/2] ACPI/IORT: add iort_get_memory_address_limit function Nate Watterson 2017-01-31 20:16 ` [PATCH 2/2] arm64/dma-mapping: validate dma_masks against IORT defined limits Nate Watterson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox