From: Yicong Yang <yangyicong@xxxxxxxxxxxxx> Extend cpu_cache_invalidate_memregion() to support invalidate certain range of memory. Control of types of invalidation is left for when usecases turn up. For now everything is Clean and Invalidate. Signed-off-by: Yicong Yang <yangyicong@xxxxxxxxxxxxx> --- arch/x86/mm/pat/set_memory.c | 2 +- drivers/cxl/core/region.c | 6 +++++- drivers/nvdimm/region.c | 3 ++- drivers/nvdimm/region_devs.c | 3 ++- include/linux/memregion.h | 8 ++++++-- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index ef4514d64c05..5d2adec1b0d4 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -354,7 +354,7 @@ bool cpu_cache_has_invalidate_memregion(void) } EXPORT_SYMBOL_NS_GPL(cpu_cache_has_invalidate_memregion, "DEVMEM"); -int cpu_cache_invalidate_memregion(int res_desc) +int cpu_cache_invalidate_memregion(int res_desc, phys_addr_t start, size_t len) { if (WARN_ON_ONCE(!cpu_cache_has_invalidate_memregion())) return -ENXIO; diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index e8d11a988fd9..6d1c9eee4cd9 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -238,7 +238,11 @@ static int cxl_region_invalidate_memregion(struct cxl_region *cxlr) } } - cpu_cache_invalidate_memregion(IORES_DESC_CXL); + if (!cxlr->params.res) + return -ENXIO; + cpu_cache_invalidate_memregion(IORES_DESC_CXL, + cxlr->params.res->start, + resource_size(cxlr->params.res)); return 0; } diff --git a/drivers/nvdimm/region.c b/drivers/nvdimm/region.c index 88dc062af5f8..033e40f4dc52 100644 --- a/drivers/nvdimm/region.c +++ b/drivers/nvdimm/region.c @@ -110,7 +110,8 @@ static void nd_region_remove(struct device *dev) * here is ok. */ if (cpu_cache_has_invalidate_memregion()) - cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY); + cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY, + 0, -1); } static int child_notify(struct device *dev, void *data) diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index 37417ce5ec7b..eefd294a0f13 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -90,7 +90,8 @@ static int nd_region_invalidate_memregion(struct nd_region *nd_region) } } - cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY); + cpu_cache_invalidate_memregion(IORES_DESC_PERSISTENT_MEMORY, + 0, -1); out: for (i = 0; i < nd_region->ndr_mappings; i++) { struct nd_mapping *nd_mapping = &nd_region->mapping[i]; diff --git a/include/linux/memregion.h b/include/linux/memregion.h index c01321467789..91d088ee3695 100644 --- a/include/linux/memregion.h +++ b/include/linux/memregion.h @@ -28,6 +28,9 @@ static inline void memregion_free(int id) * cpu_cache_invalidate_memregion - drop any CPU cached data for * memregions described by @res_desc * @res_desc: one of the IORES_DESC_* types + * @start: start physical address of the target memory region. + * @len: length of the target memory region. -1 for all the regions of + * the target type. * * Perform cache maintenance after a memory event / operation that * changes the contents of physical memory in a cache-incoherent manner. @@ -46,7 +49,7 @@ static inline void memregion_free(int id) * the cache maintenance. */ #ifdef CONFIG_ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION -int cpu_cache_invalidate_memregion(int res_desc); +int cpu_cache_invalidate_memregion(int res_desc, phys_addr_t start, size_t len); bool cpu_cache_has_invalidate_memregion(void); #else static inline bool cpu_cache_has_invalidate_memregion(void) @@ -54,7 +57,8 @@ static inline bool cpu_cache_has_invalidate_memregion(void) return false; } -static inline int cpu_cache_invalidate_memregion(int res_desc) +static inline int cpu_cache_invalidate_memregion(int res_desc, + phys_addr_t start, size_t len) { WARN_ON_ONCE("CPU cache invalidation required"); return -ENXIO; -- 2.43.0