lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230228080257.28807-5-hejinyang@loongson.cn>
Date:   Tue, 28 Feb 2023 16:02:55 +0800
From:   Jinyang He <hejinyang@...ngson.cn>
To:     Huacai Chen <chenhuacai@...nel.org>,
        WANG Xuerui <kernel@...0n.name>
Cc:     Xi Ruoyao <xry111@...111.site>,
        Youling Tang <tangyouling@...ngson.cn>,
        loongarch@...ts.linux.dev, linux-kernel@...r.kernel.org
Subject: [PATCH v2 4/6] LoongArch: Drop pernode exception handlers

1, set the value of CSR.EENTRY to &__ex_handlers.
2, set the value of CSR.TLBRENTRY to &__tlbr_entry.
3, set the value of CSR.MERRENTRY to &__ex_handlers.
Then, we can drop the pernode exception handlers.

Signed-off-by: Jinyang He <hejinyang@...ngson.cn>
---
 arch/loongarch/include/asm/setup.h      |  7 ---
 arch/loongarch/include/asm/traps.h      | 29 ++++++++++
 arch/loongarch/kernel/genex.S           |  8 ---
 arch/loongarch/kernel/traps.c           | 74 +------------------------
 arch/loongarch/kernel/unwind_prologue.c | 62 +--------------------
 arch/loongarch/mm/cache.c               |  6 --
 arch/loongarch/mm/tlb.c                 | 40 -------------
 arch/loongarch/power/suspend.c          |  5 +-
 8 files changed, 33 insertions(+), 198 deletions(-)

diff --git a/arch/loongarch/include/asm/setup.h b/arch/loongarch/include/asm/setup.h
index be05c0e706a2..4074225339ec 100644
--- a/arch/loongarch/include/asm/setup.h
+++ b/arch/loongarch/include/asm/setup.h
@@ -9,17 +9,10 @@
 #include <linux/types.h>
 #include <uapi/asm/setup.h>
 
-#define VECSIZE 0x200
-
-extern unsigned long eentry;
-extern unsigned long tlbrentry;
 extern char init_command_line[COMMAND_LINE_SIZE];
 extern void tlb_init(int cpu);
 extern void cpu_cache_init(void);
-extern void cache_error_setup(void);
 extern void per_cpu_trap_init(int cpu);
-extern void set_handler(unsigned long offset, void *addr, unsigned long len);
-extern void set_merr_handler(unsigned long offset, void *addr, unsigned long len);
 
 #ifdef CONFIG_RELOCATABLE
 
diff --git a/arch/loongarch/include/asm/traps.h b/arch/loongarch/include/asm/traps.h
index b348d66c16a1..8f276253f145 100644
--- a/arch/loongarch/include/asm/traps.h
+++ b/arch/loongarch/include/asm/traps.h
@@ -34,6 +34,35 @@
 	.pushsection .tlbrhandler, "ax";			\
 	__VA_ARGS__;						\
 	.popsection;
+
+#else /* __ASSEMBLY__ */
+
+#define VECSIZE	0x200
+extern void *__ex_handlers;
+extern void *__tlbr_entry;
+
+static inline void set_eentry(void *entry)
+{
+	csr_write64((unsigned long)entry, LOONGARCH_CSR_EENTRY);
+}
+
+static inline void set_tlbrentry(void *entry)
+{
+	csr_write64((unsigned long)entry, LOONGARCH_CSR_TLBRENTRY);
+}
+
+static inline void set_merrentry(void *entry)
+{
+	csr_write64((unsigned long)entry, LOONGARCH_CSR_MERRENTRY);
+}
+
+static inline void configure_exception_vector(void)
+{
+	set_eentry(&__ex_handlers);
+	set_tlbrentry(&__tlbr_entry);
+	set_merrentry(&__ex_handlers);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_TRAPS_H */
diff --git a/arch/loongarch/kernel/genex.S b/arch/loongarch/kernel/genex.S
index 86abafc8b95b..256e2e5b83d4 100644
--- a/arch/loongarch/kernel/genex.S
+++ b/arch/loongarch/kernel/genex.S
@@ -72,19 +72,14 @@ SYM_FUNC_END(except_vec_cex)
 	.macro	BUILD_HANDLER exception handler prep
 	.align	5
 SYM_FUNC_START(handle_\exception)
-	666:
 	BACKUP_T0T1
 	SAVE_ALL
 	build_prep_\prep
 	move	a0, sp
 	la_abs	t0, do_\handler
 	jirl	ra, t0, 0
-	668:
 	RESTORE_ALL_AND_RET
 SYM_FUNC_END(handle_\exception)
-	.pushsection .rodata
-SYM_DATA(unwind_hint_\exception, .word 668b - 666b)
-	.popsection
 	.endm
 
 SET_EXCEPTION_HANDLER(EXCCODE_SIP0,  _handle_vint)
@@ -123,6 +118,3 @@ SET_EXCEPTION_HANDLER(\i, BUILD_HANDLER reserved\i reserved none)
 .irp i, EXCCODE_NOHND
 SET_EXCEPTION_HANDLER(\i, BUILD_HANDLER reserved\i reserved none)
 .endr
-
-/* Create handle_reserved for temporary build. */
-BUILD_HANDLER reserved reserved none
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
index c8b3bd76c941..84ac78bc8c57 100644
--- a/arch/loongarch/kernel/traps.c
+++ b/arch/loongarch/kernel/traps.c
@@ -43,6 +43,7 @@
 #include <asm/siginfo.h>
 #include <asm/stacktrace.h>
 #include <asm/tlb.h>
+#include <asm/traps.h>
 #include <asm/types.h>
 #include <asm/unwind.h>
 
@@ -798,25 +799,8 @@ asmlinkage void noinstr do_vint(struct pt_regs *regs, unsigned long sp)
 	irqentry_exit(regs, state);
 }
 
-unsigned long eentry;
-unsigned long tlbrentry;
-
-long exception_handlers[VECSIZE * 128 / sizeof(long)] __aligned(SZ_64K);
-
-static void configure_exception_vector(void)
-{
-	eentry    = (unsigned long)exception_handlers;
-	tlbrentry = (unsigned long)exception_handlers + 80*VECSIZE;
-
-	csr_write64(eentry, LOONGARCH_CSR_EENTRY);
-	csr_write64(eentry, LOONGARCH_CSR_MERRENTRY);
-	csr_write64(tlbrentry, LOONGARCH_CSR_TLBRENTRY);
-}
-
 void per_cpu_trap_init(int cpu)
 {
-	unsigned int i;
-
 	setup_vint_size(VECSIZE);
 
 	configure_exception_vector();
@@ -829,62 +813,6 @@ void per_cpu_trap_init(int cpu)
 	BUG_ON(current->mm);
 	enter_lazy_tlb(&init_mm, current);
 
-	/* Initialise exception handlers */
-	if (cpu == 0)
-		for (i = 0; i < 64; i++)
-			set_handler(i * VECSIZE, handle_reserved, VECSIZE);
-
 	tlb_init(cpu);
 	cpu_cache_init();
 }
-
-/* Install CPU exception handler */
-void set_handler(unsigned long offset, void *addr, unsigned long size)
-{
-	memcpy((void *)(eentry + offset), addr, size);
-	local_flush_icache_range(eentry + offset, eentry + offset + size);
-}
-
-static const char panic_null_cerr[] =
-	"Trying to set NULL cache error exception handler\n";
-
-/*
- * Install uncached CPU exception handler.
- * This is suitable only for the cache error exception which is the only
- * exception handler that is being run uncached.
- */
-void set_merr_handler(unsigned long offset, void *addr, unsigned long size)
-{
-	unsigned long uncached_eentry = TO_UNCACHE(__pa(eentry));
-
-	if (!addr)
-		panic(panic_null_cerr);
-
-	memcpy((void *)(uncached_eentry + offset), addr, size);
-}
-
-void __init trap_init(void)
-{
-	long i;
-
-	/* Set interrupt vector handler */
-	for (i = EXCCODE_INT_START; i < EXCCODE_INT_END; i++)
-		set_handler(i * VECSIZE, handle_vint, VECSIZE);
-
-	set_handler(EXCCODE_ADE * VECSIZE, handle_ade, VECSIZE);
-	set_handler(EXCCODE_ALE * VECSIZE, handle_ale, VECSIZE);
-	set_handler(EXCCODE_SYS * VECSIZE, handle_sys, VECSIZE);
-	set_handler(EXCCODE_BP * VECSIZE, handle_bp, VECSIZE);
-	set_handler(EXCCODE_INE * VECSIZE, handle_ri, VECSIZE);
-	set_handler(EXCCODE_IPE * VECSIZE, handle_ri, VECSIZE);
-	set_handler(EXCCODE_FPDIS * VECSIZE, handle_fpu, VECSIZE);
-	set_handler(EXCCODE_LSXDIS * VECSIZE, handle_lsx, VECSIZE);
-	set_handler(EXCCODE_LASXDIS * VECSIZE, handle_lasx, VECSIZE);
-	set_handler(EXCCODE_FPE * VECSIZE, handle_fpe, VECSIZE);
-	set_handler(EXCCODE_BTDIS * VECSIZE, handle_lbt, VECSIZE);
-	set_handler(EXCCODE_WATCH * VECSIZE, handle_watch, VECSIZE);
-
-	cache_error_setup();
-
-	local_flush_icache_range(eentry, eentry + 0x400);
-}
diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c
index 9095fde8e55d..de18335c6ba6 100644
--- a/arch/loongarch/kernel/unwind_prologue.c
+++ b/arch/loongarch/kernel/unwind_prologue.c
@@ -12,69 +12,9 @@
 #include <asm/setup.h>
 #include <asm/unwind.h>
 
-extern const int unwind_hint_ade;
-extern const int unwind_hint_ale;
-extern const int unwind_hint_bp;
-extern const int unwind_hint_fpe;
-extern const int unwind_hint_fpu;
-extern const int unwind_hint_lsx;
-extern const int unwind_hint_lasx;
-extern const int unwind_hint_lbt;
-extern const int unwind_hint_ri;
-extern const int unwind_hint_watch;
-extern unsigned long eentry;
-#ifdef CONFIG_NUMA
-extern unsigned long pcpu_handlers[NR_CPUS];
-#endif
-
-static inline bool scan_handlers(unsigned long entry_offset)
-{
-	int idx, offset;
-
-	if (entry_offset >= EXCCODE_INT_START * VECSIZE)
-		return false;
-
-	idx = entry_offset / VECSIZE;
-	offset = entry_offset % VECSIZE;
-	switch (idx) {
-	case EXCCODE_ADE:
-		return offset == unwind_hint_ade;
-	case EXCCODE_ALE:
-		return offset == unwind_hint_ale;
-	case EXCCODE_BP:
-		return offset == unwind_hint_bp;
-	case EXCCODE_FPE:
-		return offset == unwind_hint_fpe;
-	case EXCCODE_FPDIS:
-		return offset == unwind_hint_fpu;
-	case EXCCODE_LSXDIS:
-		return offset == unwind_hint_lsx;
-	case EXCCODE_LASXDIS:
-		return offset == unwind_hint_lasx;
-	case EXCCODE_BTDIS:
-		return offset == unwind_hint_lbt;
-	case EXCCODE_INE:
-		return offset == unwind_hint_ri;
-	case EXCCODE_WATCH:
-		return offset == unwind_hint_watch;
-	default:
-		return false;
-	}
-}
-
 static inline bool fix_exception(unsigned long pc)
 {
-#ifdef CONFIG_NUMA
-	int cpu;
-
-	for_each_possible_cpu(cpu) {
-		if (!pcpu_handlers[cpu])
-			continue;
-		if (scan_handlers(pc - pcpu_handlers[cpu]))
-			return true;
-	}
-#endif
-	return scan_handlers(pc - eentry);
+	return false;
 }
 
 /*
diff --git a/arch/loongarch/mm/cache.c b/arch/loongarch/mm/cache.c
index 72685a48eaf0..d8e53702d61f 100644
--- a/arch/loongarch/mm/cache.c
+++ b/arch/loongarch/mm/cache.c
@@ -25,12 +25,6 @@
 #include <asm/processor.h>
 #include <asm/setup.h>
 
-void cache_error_setup(void)
-{
-	extern char __weak except_vec_cex;
-	set_merr_handler(0x0, &except_vec_cex, 0x80);
-}
-
 /*
  * LoongArch maintains ICache/DCache coherency by hardware,
  * we just need "ibar" to avoid instruction hazard here.
diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c
index 8bad6b0cff59..dda35eae1c49 100644
--- a/arch/loongarch/mm/tlb.c
+++ b/arch/loongarch/mm/tlb.c
@@ -250,50 +250,10 @@ static void output_pgtable_bits_defines(void)
 	pr_debug("\n");
 }
 
-#ifdef CONFIG_NUMA
-unsigned long pcpu_handlers[NR_CPUS];
-#endif
-extern long exception_handlers[VECSIZE * 128 / sizeof(long)];
-
 void setup_tlb_handler(int cpu)
 {
 	setup_ptwalker();
 	local_flush_tlb_all();
-
-	/* The tlb handlers are generated only once */
-	if (cpu == 0) {
-		memcpy((void *)tlbrentry, handle_tlb_refill, 0x80);
-		local_flush_icache_range(tlbrentry, tlbrentry + 0x80);
-		set_handler(EXCCODE_TLBI * VECSIZE, handle_tlb_load, VECSIZE);
-		set_handler(EXCCODE_TLBL * VECSIZE, handle_tlb_load, VECSIZE);
-		set_handler(EXCCODE_TLBS * VECSIZE, handle_tlb_store, VECSIZE);
-		set_handler(EXCCODE_TLBM * VECSIZE, handle_tlb_modify, VECSIZE);
-		set_handler(EXCCODE_TLBNR * VECSIZE, handle_tlb_protect, VECSIZE);
-		set_handler(EXCCODE_TLBNX * VECSIZE, handle_tlb_protect, VECSIZE);
-		set_handler(EXCCODE_TLBPE * VECSIZE, handle_tlb_protect, VECSIZE);
-	}
-#ifdef CONFIG_NUMA
-	else {
-		void *addr;
-		struct page *page;
-		const int vec_sz = sizeof(exception_handlers);
-
-		if (pcpu_handlers[cpu])
-			return;
-
-		page = alloc_pages_node(cpu_to_node(cpu), GFP_ATOMIC, get_order(vec_sz));
-		if (!page)
-			return;
-
-		addr = page_address(page);
-		pcpu_handlers[cpu] = (unsigned long)addr;
-		memcpy((void *)addr, (void *)eentry, vec_sz);
-		local_flush_icache_range((unsigned long)addr, (unsigned long)addr + vec_sz);
-		csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_EENTRY);
-		csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_MERRENTRY);
-		csr_write64(pcpu_handlers[cpu] + 80*VECSIZE, LOONGARCH_CSR_TLBRENTRY);
-	}
-#endif
 }
 
 void tlb_init(int cpu)
diff --git a/arch/loongarch/power/suspend.c b/arch/loongarch/power/suspend.c
index 5e19733e5e05..b2a10a33b372 100644
--- a/arch/loongarch/power/suspend.c
+++ b/arch/loongarch/power/suspend.c
@@ -14,6 +14,7 @@
 #include <asm/setup.h>
 #include <asm/time.h>
 #include <asm/tlbflush.h>
+#include <asm/traps.h>
 
 u64 loongarch_suspend_addr;
 
@@ -45,9 +46,7 @@ static void arch_common_resume(void)
 	sync_counter();
 	local_flush_tlb_all();
 	csr_write64(per_cpu_offset(0), PERCPU_BASE_KS);
-	csr_write64(eentry, LOONGARCH_CSR_EENTRY);
-	csr_write64(eentry, LOONGARCH_CSR_MERRENTRY);
-	csr_write64(tlbrentry, LOONGARCH_CSR_TLBRENTRY);
+	configure_exception_vector();
 
 	csr_write64(saved_regs.pgd, LOONGARCH_CSR_PGDL);
 	csr_write64(saved_regs.kpgd, LOONGARCH_CSR_PGDH);
-- 
2.34.3

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ