[PATCH v3 12/18] arm64: __flush_dcache_area to take end parameter instead of size

Mark Rutland mark.rutland at arm.com
Thu May 20 09:06:56 PDT 2021


On Thu, May 20, 2021 at 01:44:00PM +0100, Fuad Tabba wrote:
> To be consistent with other functions with similar names and
> functionality in cacheflush.h, cache.S, and cachetlb.rst, change
> to specify the range in terms of start and end, as opposed to
> start and size.
> 
> No functional change intended.
> 
> Reported-by: Will Deacon <will at kernel.org>
> Signed-off-by: Fuad Tabba <tabba at google.com>

Acked-by Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/arch_gicv3.h |  3 ++-
>  arch/arm64/include/asm/cacheflush.h |  8 ++++----
>  arch/arm64/include/asm/efi.h        |  2 +-
>  arch/arm64/include/asm/kvm_mmu.h    |  3 ++-
>  arch/arm64/kernel/hibernate.c       | 18 +++++++++++-------
>  arch/arm64/kernel/idreg-override.c  |  3 ++-
>  arch/arm64/kernel/kaslr.c           | 12 +++++++++---
>  arch/arm64/kernel/machine_kexec.c   | 20 +++++++++++++-------
>  arch/arm64/kernel/smp.c             |  8 ++++++--
>  arch/arm64/kernel/smp_spin_table.c  |  7 ++++---
>  arch/arm64/kvm/hyp/nvhe/cache.S     |  1 -
>  arch/arm64/kvm/hyp/nvhe/setup.c     |  3 ++-
>  arch/arm64/kvm/hyp/pgtable.c        | 13 ++++++++++---
>  arch/arm64/mm/cache.S               |  9 ++++-----
>  14 files changed, 70 insertions(+), 40 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
> index 934b9be582d2..ed1cc9d8e6df 100644
> --- a/arch/arm64/include/asm/arch_gicv3.h
> +++ b/arch/arm64/include/asm/arch_gicv3.h
> @@ -124,7 +124,8 @@ static inline u32 gic_read_rpr(void)
>  #define gic_read_lpir(c)		readq_relaxed(c)
>  #define gic_write_lpir(v, c)		writeq_relaxed(v, c)
>  
> -#define gic_flush_dcache_to_poc(a,l)	__flush_dcache_area((a), (l))
> +#define gic_flush_dcache_to_poc(a,l)	\
> +	__flush_dcache_area((unsigned long)(a), (unsigned long)(a)+(l))
>  
>  #define gits_read_baser(c)		readq_relaxed(c)
>  #define gits_write_baser(v, c)		writeq_relaxed(v, c)
> diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> index 157234706817..695f88864784 100644
> --- a/arch/arm64/include/asm/cacheflush.h
> +++ b/arch/arm64/include/asm/cacheflush.h
> @@ -50,15 +50,15 @@
>   *		- start  - virtual start address
>   *		- end    - virtual end address
>   *
> - *	__flush_dcache_area(kaddr, size)
> + *	__flush_dcache_area(start, end)
>   *
>   *		Ensure that the data held in page is written back.
> - *		- kaddr  - page address
> - *		- size   - region size
> + *		- start  - virtual start address
> + *		- end    - virtual end address
>   */
>  extern void __flush_icache_range(unsigned long start, unsigned long end);
>  extern void invalidate_icache_range(unsigned long start, unsigned long end);
> -extern void __flush_dcache_area(void *addr, size_t len);
> +extern void __flush_dcache_area(unsigned long start, unsigned long end);
>  extern void __inval_dcache_area(unsigned long start, unsigned long end);
>  extern void __clean_dcache_area_poc(void *addr, size_t len);
>  extern void __clean_dcache_area_pop(void *addr, size_t len);
> diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
> index 3578aba9c608..0ae2397076fd 100644
> --- a/arch/arm64/include/asm/efi.h
> +++ b/arch/arm64/include/asm/efi.h
> @@ -137,7 +137,7 @@ void efi_virtmap_unload(void);
>  
>  static inline void efi_capsule_flush_cache_range(void *addr, int size)
>  {
> -	__flush_dcache_area(addr, size);
> +	__flush_dcache_area((unsigned long)addr, (unsigned long)addr + size);
>  }
>  
>  #endif /* _ASM_EFI_H */
> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index 25ed956f9af1..33293d5855af 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -180,7 +180,8 @@ static inline void *__kvm_vector_slot2addr(void *base,
>  
>  struct kvm;
>  
> -#define kvm_flush_dcache_to_poc(a,l)	__flush_dcache_area((a), (l))
> +#define kvm_flush_dcache_to_poc(a,l)	\
> +	__flush_dcache_area((unsigned long)(a), (unsigned long)(a)+(l))
>  
>  static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu)
>  {
> diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
> index b1cef371df2b..b40ddce71507 100644
> --- a/arch/arm64/kernel/hibernate.c
> +++ b/arch/arm64/kernel/hibernate.c
> @@ -240,8 +240,6 @@ static int create_safe_exec_page(void *src_start, size_t length,
>  	return 0;
>  }
>  
> -#define dcache_clean_range(start, end)	__flush_dcache_area(start, (end - start))
> -
>  #ifdef CONFIG_ARM64_MTE
>  
>  static DEFINE_XARRAY(mte_pages);
> @@ -383,13 +381,18 @@ int swsusp_arch_suspend(void)
>  		ret = swsusp_save();
>  	} else {
>  		/* Clean kernel core startup/idle code to PoC*/
> -		dcache_clean_range(__mmuoff_data_start, __mmuoff_data_end);
> -		dcache_clean_range(__idmap_text_start, __idmap_text_end);
> +		__flush_dcache_area((unsigned long)__mmuoff_data_start,
> +				    (unsigned long)__mmuoff_data_end);
> +		__flush_dcache_area((unsigned long)__idmap_text_start,
> +				    (unsigned long)__idmap_text_end);
>  
>  		/* Clean kvm setup code to PoC? */
>  		if (el2_reset_needed()) {
> -			dcache_clean_range(__hyp_idmap_text_start, __hyp_idmap_text_end);
> -			dcache_clean_range(__hyp_text_start, __hyp_text_end);
> +			__flush_dcache_area(
> +				(unsigned long)__hyp_idmap_text_start,
> +				(unsigned long)__hyp_idmap_text_end);
> +			__flush_dcache_area((unsigned long)__hyp_text_start,
> +					    (unsigned long)__hyp_text_end);
>  		}
>  
>  		swsusp_mte_restore_tags();
> @@ -474,7 +477,8 @@ int swsusp_arch_resume(void)
>  	 * The hibernate exit text contains a set of el2 vectors, that will
>  	 * be executed at el2 with the mmu off in order to reload hyp-stub.
>  	 */
> -	__flush_dcache_area(hibernate_exit, exit_size);
> +	__flush_dcache_area((unsigned long)hibernate_exit,
> +			    (unsigned long)hibernate_exit + exit_size);
>  
>  	/*
>  	 * KASLR will cause the el2 vectors to be in a different location in
> diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
> index e628c8ce1ffe..3dd515baf526 100644
> --- a/arch/arm64/kernel/idreg-override.c
> +++ b/arch/arm64/kernel/idreg-override.c
> @@ -237,7 +237,8 @@ asmlinkage void __init init_feature_override(void)
>  
>  	for (i = 0; i < ARRAY_SIZE(regs); i++) {
>  		if (regs[i]->override)
> -			__flush_dcache_area(regs[i]->override,
> +			__flush_dcache_area((unsigned long)regs[i]->override,
> +					    (unsigned long)regs[i]->override +
>  					    sizeof(*regs[i]->override));
>  	}
>  }
> diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
> index 341342b207f6..49cccd03cb37 100644
> --- a/arch/arm64/kernel/kaslr.c
> +++ b/arch/arm64/kernel/kaslr.c
> @@ -72,7 +72,9 @@ u64 __init kaslr_early_init(void)
>  	 * we end up running with module randomization disabled.
>  	 */
>  	module_alloc_base = (u64)_etext - MODULES_VSIZE;
> -	__flush_dcache_area(&module_alloc_base, sizeof(module_alloc_base));
> +	__flush_dcache_area((unsigned long)&module_alloc_base,
> +			    (unsigned long)&module_alloc_base +
> +				    sizeof(module_alloc_base));
>  
>  	/*
>  	 * Try to map the FDT early. If this fails, we simply bail,
> @@ -170,8 +172,12 @@ u64 __init kaslr_early_init(void)
>  	module_alloc_base += (module_range * (seed & ((1 << 21) - 1))) >> 21;
>  	module_alloc_base &= PAGE_MASK;
>  
> -	__flush_dcache_area(&module_alloc_base, sizeof(module_alloc_base));
> -	__flush_dcache_area(&memstart_offset_seed, sizeof(memstart_offset_seed));
> +	__flush_dcache_area((unsigned long)&module_alloc_base,
> +			    (unsigned long)&module_alloc_base +
> +				    sizeof(module_alloc_base));
> +	__flush_dcache_area((unsigned long)&memstart_offset_seed,
> +			    (unsigned long)&memstart_offset_seed +
> +				    sizeof(memstart_offset_seed));
>  
>  	return offset;
>  }
> diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
> index a03944fd0cd4..3e79110c8f3a 100644
> --- a/arch/arm64/kernel/machine_kexec.c
> +++ b/arch/arm64/kernel/machine_kexec.c
> @@ -72,7 +72,9 @@ int machine_kexec_post_load(struct kimage *kimage)
>  	 * For execution with the MMU off, reloc_code needs to be cleaned to the
>  	 * PoC and invalidated from the I-cache.
>  	 */
> -	__flush_dcache_area(reloc_code, arm64_relocate_new_kernel_size);
> +	__flush_dcache_area((unsigned long)reloc_code,
> +			    (unsigned long)reloc_code +
> +				    arm64_relocate_new_kernel_size);
>  	invalidate_icache_range((uintptr_t)reloc_code,
>  				(uintptr_t)reloc_code +
>  					arm64_relocate_new_kernel_size);
> @@ -106,16 +108,18 @@ static void kexec_list_flush(struct kimage *kimage)
>  
>  	for (entry = &kimage->head; ; entry++) {
>  		unsigned int flag;
> -		void *addr;
> +		unsigned long addr;
>  
>  		/* flush the list entries. */
> -		__flush_dcache_area(entry, sizeof(kimage_entry_t));
> +		__flush_dcache_area((unsigned long)entry,
> +				    (unsigned long)entry +
> +					    sizeof(kimage_entry_t));
>  
>  		flag = *entry & IND_FLAGS;
>  		if (flag == IND_DONE)
>  			break;
>  
> -		addr = phys_to_virt(*entry & PAGE_MASK);
> +		addr = (unsigned long)phys_to_virt(*entry & PAGE_MASK);
>  
>  		switch (flag) {
>  		case IND_INDIRECTION:
> @@ -124,7 +128,7 @@ static void kexec_list_flush(struct kimage *kimage)
>  			break;
>  		case IND_SOURCE:
>  			/* flush the source pages. */
> -			__flush_dcache_area(addr, PAGE_SIZE);
> +			__flush_dcache_area(addr, addr + PAGE_SIZE);
>  			break;
>  		case IND_DESTINATION:
>  			break;
> @@ -151,8 +155,10 @@ static void kexec_segment_flush(const struct kimage *kimage)
>  			kimage->segment[i].memsz,
>  			kimage->segment[i].memsz /  PAGE_SIZE);
>  
> -		__flush_dcache_area(phys_to_virt(kimage->segment[i].mem),
> -			kimage->segment[i].memsz);
> +		__flush_dcache_area(
> +			(unsigned long)phys_to_virt(kimage->segment[i].mem),
> +			(unsigned long)phys_to_virt(kimage->segment[i].mem) +
> +				kimage->segment[i].memsz);
>  	}
>  }
>  
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index dcd7041b2b07..5fcdee331087 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -122,7 +122,9 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
>  	secondary_data.task = idle;
>  	secondary_data.stack = task_stack_page(idle) + THREAD_SIZE;
>  	update_cpu_boot_status(CPU_MMU_OFF);
> -	__flush_dcache_area(&secondary_data, sizeof(secondary_data));
> +	__flush_dcache_area((unsigned long)&secondary_data,
> +			    (unsigned long)&secondary_data +
> +				    sizeof(secondary_data));
>  
>  	/* Now bring the CPU into our world */
>  	ret = boot_secondary(cpu, idle);
> @@ -143,7 +145,9 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
>  	pr_crit("CPU%u: failed to come online\n", cpu);
>  	secondary_data.task = NULL;
>  	secondary_data.stack = NULL;
> -	__flush_dcache_area(&secondary_data, sizeof(secondary_data));
> +	__flush_dcache_area((unsigned long)&secondary_data,
> +			    (unsigned long)&secondary_data +
> +				    sizeof(secondary_data));
>  	status = READ_ONCE(secondary_data.status);
>  	if (status == CPU_MMU_OFF)
>  		status = READ_ONCE(__early_cpu_boot_status);
> diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
> index c45a83512805..58d804582a35 100644
> --- a/arch/arm64/kernel/smp_spin_table.c
> +++ b/arch/arm64/kernel/smp_spin_table.c
> @@ -36,7 +36,7 @@ static void write_pen_release(u64 val)
>  	unsigned long size = sizeof(secondary_holding_pen_release);
>  
>  	secondary_holding_pen_release = val;
> -	__flush_dcache_area(start, size);
> +	__flush_dcache_area((unsigned long)start, (unsigned long)start + size);
>  }
>  
>  
> @@ -90,8 +90,9 @@ static int smp_spin_table_cpu_prepare(unsigned int cpu)
>  	 * the boot protocol.
>  	 */
>  	writeq_relaxed(pa_holding_pen, release_addr);
> -	__flush_dcache_area((__force void *)release_addr,
> -			    sizeof(*release_addr));
> +	__flush_dcache_area((__force unsigned long)release_addr,
> +			    (__force unsigned long)release_addr +
> +				    sizeof(*release_addr));
>  
>  	/*
>  	 * Send an event to wake up the secondary CPU.
> diff --git a/arch/arm64/kvm/hyp/nvhe/cache.S b/arch/arm64/kvm/hyp/nvhe/cache.S
> index 3bcfa3cac46f..36cef6915428 100644
> --- a/arch/arm64/kvm/hyp/nvhe/cache.S
> +++ b/arch/arm64/kvm/hyp/nvhe/cache.S
> @@ -8,7 +8,6 @@
>  #include <asm/alternative.h>
>  
>  SYM_FUNC_START_PI(__flush_dcache_area)
> -	add	x1, x0, x1
>  	dcache_by_line_op civac, sy, x0, x1, x2, x3
>  	ret
>  SYM_FUNC_END_PI(__flush_dcache_area)
> diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
> index 7488f53b0aa2..5dffe928f256 100644
> --- a/arch/arm64/kvm/hyp/nvhe/setup.c
> +++ b/arch/arm64/kvm/hyp/nvhe/setup.c
> @@ -134,7 +134,8 @@ static void update_nvhe_init_params(void)
>  	for (i = 0; i < hyp_nr_cpus; i++) {
>  		params = per_cpu_ptr(&kvm_init_params, i);
>  		params->pgd_pa = __hyp_pa(pkvm_pgtable.pgd);
> -		__flush_dcache_area(params, sizeof(*params));
> +		__flush_dcache_area((unsigned long)params,
> +				    (unsigned long)params + sizeof(*params));
>  	}
>  }
>  
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index c37c1dc4feaf..10d2f04013d4 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -839,8 +839,11 @@ static int stage2_unmap_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep,
>  	stage2_put_pte(ptep, mmu, addr, level, mm_ops);
>  
>  	if (need_flush) {
> -		__flush_dcache_area(kvm_pte_follow(pte, mm_ops),
> -				    kvm_granule_size(level));
> +		kvm_pte_t *pte_follow = kvm_pte_follow(pte, mm_ops);
> +
> +		__flush_dcache_area((unsigned long)pte_follow,
> +				    (unsigned long)pte_follow +
> +					    kvm_granule_size(level));
>  	}
>  
>  	if (childp)
> @@ -988,11 +991,15 @@ static int stage2_flush_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep,
>  	struct kvm_pgtable *pgt = arg;
>  	struct kvm_pgtable_mm_ops *mm_ops = pgt->mm_ops;
>  	kvm_pte_t pte = *ptep;
> +	kvm_pte_t *pte_follow;
>  
>  	if (!kvm_pte_valid(pte) || !stage2_pte_cacheable(pgt, pte))
>  		return 0;
>  
> -	__flush_dcache_area(kvm_pte_follow(pte, mm_ops), kvm_granule_size(level));
> +	pte_follow = kvm_pte_follow(pte, mm_ops);
> +	__flush_dcache_area((unsigned long)pte_follow,
> +			    (unsigned long)pte_follow +
> +				    kvm_granule_size(level));
>  	return 0;
>  }
>  
> diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
> index 3b5461a32b85..35abc8d77c4e 100644
> --- a/arch/arm64/mm/cache.S
> +++ b/arch/arm64/mm/cache.S
> @@ -106,16 +106,15 @@ alternative_else_nop_endif
>  SYM_FUNC_END(invalidate_icache_range)
>  
>  /*
> - *	__flush_dcache_area(kaddr, size)
> + *	__flush_dcache_area(start, end)
>   *
> - *	Ensure that any D-cache lines for the interval [kaddr, kaddr+size)
> + *	Ensure that any D-cache lines for the interval [start, end)
>   *	are cleaned and invalidated to the PoC.
>   *
> - *	- kaddr   - kernel address
> - *	- size    - size in question
> + *	- start   - virtual start address of region
> + *	- end     - virtual end address of region
>   */
>  SYM_FUNC_START_PI(__flush_dcache_area)
> -	add	x1, x0, x1
>  	dcache_by_line_op civac, sy, x0, x1, x2, x3
>  	ret
>  SYM_FUNC_END_PI(__flush_dcache_area)
> -- 
> 2.31.1.751.gd2f1c929bd-goog
> 



More information about the linux-arm-kernel mailing list