From 0e60f0b75884677fb9f4f2ad40d52b43451564d5 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sat, 17 Feb 2024 05:15:42 -0800 Subject: [PATCH 1/3] xtensa: fix MAKE_PC_FROM_RA second argument Xtensa has two-argument MAKE_PC_FROM_RA macro to convert a0 to an actual return address because when windowed ABI is used call{,x}{4,8,12} opcodes stuff encoded window size into the top 2 bits of the register that becomes a return address in the called function. Second argument of that macro is supposed to be an address having these 2 topmost bits set correctly, but the comment suggested that that could be the stack address. However the stack doesn't have to be in the same 1GByte region as the code, especially in noMMU XIP configurations. Fix the comment and use either _text or regs->pc as the second argument for the MAKE_PC_FROM_RA macro. Cc: stable@vger.kernel.org Signed-off-by: Max Filippov --- arch/xtensa/include/asm/processor.h | 8 ++++---- arch/xtensa/include/asm/ptrace.h | 2 +- arch/xtensa/kernel/process.c | 5 +++-- arch/xtensa/kernel/stacktrace.c | 3 ++- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index d008a153a2b9..7ed1a2085bd7 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -115,9 +115,9 @@ #define MAKE_RA_FOR_CALL(ra,ws) (((ra) & 0x3fffffff) | (ws) << 30) /* Convert return address to a valid pc - * Note: We assume that the stack pointer is in the same 1GB ranges as the ra + * Note: 'text' is the address within the same 1GB range as the ra */ -#define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) +#define MAKE_PC_FROM_RA(ra, text) (((ra) & 0x3fffffff) | ((unsigned long)(text) & 0xc0000000)) #elif defined(__XTENSA_CALL0_ABI__) @@ -127,9 +127,9 @@ #define MAKE_RA_FOR_CALL(ra, ws) (ra) /* Convert return address to a valid pc - * Note: We assume that the stack pointer is in the same 1GB ranges as the ra + * Note: 'text' is not used as 'ra' is always the full address */ -#define MAKE_PC_FROM_RA(ra, sp) (ra) +#define MAKE_PC_FROM_RA(ra, text) (ra) #else #error Unsupported Xtensa ABI diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h index a270467556dc..86c70117371b 100644 --- a/arch/xtensa/include/asm/ptrace.h +++ b/arch/xtensa/include/asm/ptrace.h @@ -87,7 +87,7 @@ struct pt_regs { # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) # define instruction_pointer(regs) ((regs)->pc) # define return_pointer(regs) (MAKE_PC_FROM_RA((regs)->areg[0], \ - (regs)->areg[1])) + (regs)->pc)) # ifndef CONFIG_SMP # define profile_pc(regs) instruction_pointer(regs) diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index a815577d25fd..7bd66677f7b6 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -47,6 +47,7 @@ #include #include #include +#include #include extern void ret_from_fork(void); @@ -380,7 +381,7 @@ unsigned long __get_wchan(struct task_struct *p) int count = 0; sp = p->thread.sp; - pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp); + pc = MAKE_PC_FROM_RA(p->thread.ra, _text); do { if (sp < stack_page + sizeof(struct task_struct) || @@ -392,7 +393,7 @@ unsigned long __get_wchan(struct task_struct *p) /* Stack layout: sp-4: ra, sp-3: sp' */ - pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), sp); + pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), _text); sp = SPILL_SLOT(sp, 1); } while (count++ < 16); return 0; diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c index 831ffb648bda..ed324fdf2a2f 100644 --- a/arch/xtensa/kernel/stacktrace.c +++ b/arch/xtensa/kernel/stacktrace.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -189,7 +190,7 @@ void walk_stackframe(unsigned long *sp, if (a1 <= (unsigned long)sp) break; - frame.pc = MAKE_PC_FROM_RA(a0, a1); + frame.pc = MAKE_PC_FROM_RA(a0, _text); frame.sp = a1; if (fn(&frame, data)) From 11cca8ccf2c3643d002e7b421acfdc847a627e9f Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Thu, 4 Apr 2024 09:58:13 +0200 Subject: [PATCH 2/3] tty: xtensa/iss: Use min() to fix Coccinelle warning Inline strlen() and use min() to fix the following Coccinelle/coccicheck warning reported by minmax.cocci: WARNING opportunity for min() Signed-off-by: Thorsten Blum Message-Id: <20240404075811.6936-3-thorsten.blum@toblux.com> Reviewed-by: Jiri Slaby Signed-off-by: Max Filippov --- arch/xtensa/platforms/iss/console.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 8896e691c051..abec44b687df 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -166,10 +166,8 @@ late_initcall(rs_init); static void iss_console_write(struct console *co, const char *s, unsigned count) { - if (s && *s != 0) { - int len = strlen(s); - simc_write(1, s, count < len ? count : len); - } + if (s && *s != 0) + simc_write(1, s, min(count, strlen(s))); } static struct tty_driver* iss_console_device(struct console *c, int *index) From b7cf2a1d9881823133acc48427815a48b35b49f4 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 19 Mar 2024 14:09:20 +1300 Subject: [PATCH 3/3] xtensa: remove redundant flush_dcache_page and ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE macros xtensa's flush_dcache_page() can be a no-op sometimes. There is a generic implementation for this case in include/asm-generic/ cacheflush.h. #ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE static inline void flush_dcache_page(struct page *page) { } #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 #endif So remove the superfluous flush_dcache_page() definition, which also helps silence potential build warnings complaining the page variable passed to flush_dcache_page() is not used. In file included from crypto/scompress.c:12: include/crypto/scatterwalk.h: In function 'scatterwalk_pagedone': include/crypto/scatterwalk.h:76:30: warning: variable 'page' set but not used [-Wunused-but-set-variable] 76 | struct page *page; | ^~~~ crypto/scompress.c: In function 'scomp_acomp_comp_decomp': >> crypto/scompress.c:174:38: warning: unused variable 'dst_page' [-Wunused-variable] 174 | struct page *dst_page = sg_page(req->dst); | The issue was originally reported on LoongArch by kernel test robot (Huacai fixed it on LoongArch), then reported by Guenter and me on xtensa. This patch also removes lots of redundant macros which have been defined by asm-generic/cacheflush.h. Cc: Huacai Chen Cc: Herbert Xu Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202403091614.NeUw5zcv-lkp@intel.com/ Reported-by: Barry Song Closes: https://lore.kernel.org/all/CAGsJ_4yDk1+axbte7FKQEwD7X2oxUCFrEc9M5YOS1BobfDFXPA@mail.gmail.com/ Reported-by: Guenter Roeck Closes: https://lore.kernel.org/all/aaa8b7d7-5abe-47bf-93f6-407942436472@roeck-us.net/ Fixes: 77292bb8ca69 ("crypto: scomp - remove memcpy if sg_nents is 1 and pages are lowmem") Signed-off-by: Barry Song Message-Id: <20240319010920.125192-1-21cnbao@gmail.com> Signed-off-by: Max Filippov --- arch/xtensa/include/asm/cacheflush.h | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h index 38bcecb0e457..a2b6bb5429f5 100644 --- a/arch/xtensa/include/asm/cacheflush.h +++ b/arch/xtensa/include/asm/cacheflush.h @@ -100,6 +100,10 @@ void flush_cache_range(struct vm_area_struct*, ulong, ulong); void flush_icache_range(unsigned long start, unsigned long end); void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned long); +#define flush_cache_all flush_cache_all +#define flush_cache_range flush_cache_range +#define flush_icache_range flush_icache_range +#define flush_cache_page flush_cache_page #else #define flush_cache_all local_flush_cache_all #define flush_cache_range local_flush_cache_range @@ -136,20 +140,7 @@ void local_flush_cache_page(struct vm_area_struct *vma, #else -#define flush_cache_all() do { } while (0) -#define flush_cache_mm(mm) do { } while (0) -#define flush_cache_dup_mm(mm) do { } while (0) - -#define flush_cache_vmap(start,end) do { } while (0) -#define flush_cache_vmap_early(start,end) do { } while (0) -#define flush_cache_vunmap(start,end) do { } while (0) - -#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 -#define flush_dcache_page(page) do { } while (0) - #define flush_icache_range local_flush_icache_range -#define flush_cache_page(vma, addr, pfn) do { } while (0) -#define flush_cache_range(vma, start, end) do { } while (0) #endif @@ -162,15 +153,14 @@ void local_flush_cache_page(struct vm_area_struct *vma, __invalidate_icache_range(start,(end) - (start)); \ } while (0) -#define flush_dcache_mmap_lock(mapping) do { } while (0) -#define flush_dcache_mmap_unlock(mapping) do { } while (0) - #if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE) extern void copy_to_user_page(struct vm_area_struct*, struct page*, unsigned long, void*, const void*, unsigned long); extern void copy_from_user_page(struct vm_area_struct*, struct page*, unsigned long, void*, const void*, unsigned long); +#define copy_to_user_page copy_to_user_page +#define copy_from_user_page copy_from_user_page #else @@ -186,4 +176,6 @@ extern void copy_from_user_page(struct vm_area_struct*, struct page*, #endif +#include + #endif /* _XTENSA_CACHEFLUSH_H */