public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit
@ 2023-12-21 12:54 Thomas Bogendoerfer
  2023-12-21 12:54 ` [PATCH 2/2] MIPS: Remove unused shadow GPR support from vector irq setup Thomas Bogendoerfer
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Thomas Bogendoerfer @ 2023-12-21 12:54 UTC (permalink / raw)
  To: linux-mips, linux-kernel

Setting up vector interrupts worked only with handlers, which resided
in CKSEG0 space. This limits the kernel placement for 64bit platforms.
By patching in the offset into vi_handlers[] instead of the full
handler address, the vectored exception handler can load the
address by itself and jump to it.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/kernel/genex.S | 8 ++++----
 arch/mips/kernel/traps.c | 9 +++------
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index b6de8e88c1bd..a572ce36a24f 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -272,18 +272,17 @@ NESTED(except_vec_vi, 0, sp)
 	.set	push
 	.set	noreorder
 	PTR_LA	v1, except_vec_vi_handler
-FEXPORT(except_vec_vi_lui)
-	lui	v0, 0		/* Patched */
 	jr	v1
 FEXPORT(except_vec_vi_ori)
-	 ori	v0, 0		/* Patched */
+	 ori	v0, zero, 0		/* Offset in vi_handlers[] */
 	.set	pop
 	END(except_vec_vi)
 EXPORT(except_vec_vi_end)
 
 /*
  * Common Vectored Interrupt code
- * Complete the register saves and invoke the handler which is passed in $v0
+ * Complete the register saves and invoke the handler, $v0 holds
+ * offset into vi_handlers[]
  */
 NESTED(except_vec_vi_handler, 0, sp)
 	SAVE_TEMP
@@ -331,6 +330,7 @@ NESTED(except_vec_vi_handler, 0, sp)
 	/* Save task's sp on IRQ stack so that unwinding can follow it */
 	LONG_S	s1, 0(sp)
 2:
+	PTR_L	v0, vi_handlers(v0)
 	jalr	v0
 
 	/* Restore sp */
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 246c6a6b0261..d90b18908692 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -2091,16 +2091,14 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
 		 * If no shadow set is selected then use the default handler
 		 * that does normal register saving and standard interrupt exit
 		 */
-		extern const u8 except_vec_vi[], except_vec_vi_lui[];
+		extern const u8 except_vec_vi[];
 		extern const u8 except_vec_vi_ori[], except_vec_vi_end[];
 		extern const u8 rollback_except_vec_vi[];
 		const u8 *vec_start = using_rollback_handler() ?
 				      rollback_except_vec_vi : except_vec_vi;
 #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
-		const int lui_offset = except_vec_vi_lui - vec_start + 2;
 		const int ori_offset = except_vec_vi_ori - vec_start + 2;
 #else
-		const int lui_offset = except_vec_vi_lui - vec_start;
 		const int ori_offset = except_vec_vi_ori - vec_start;
 #endif
 		const int handler_len = except_vec_vi_end - vec_start;
@@ -2119,10 +2117,9 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
 #else
 				handler_len);
 #endif
-		h = (u16 *)(b + lui_offset);
-		*h = (handler >> 16) & 0xffff;
+		/* insert offset into vi_handlers[] */
 		h = (u16 *)(b + ori_offset);
-		*h = (handler & 0xffff);
+		*h = n * sizeof(handler);
 		local_flush_icache_range((unsigned long)b,
 					 (unsigned long)(b+handler_len));
 	}
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] MIPS: Remove unused shadow GPR support from vector irq setup
  2023-12-21 12:54 [PATCH 1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit Thomas Bogendoerfer
@ 2023-12-21 12:54 ` Thomas Bogendoerfer
  2023-12-30 14:45   ` Thomas Bogendoerfer
  2023-12-22 12:58 ` [PATCH 1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit Jiaxun Yang
  2023-12-30 14:45 ` Thomas Bogendoerfer
  2 siblings, 1 reply; 5+ messages in thread
From: Thomas Bogendoerfer @ 2023-12-21 12:54 UTC (permalink / raw)
  To: linux-mips, linux-kernel

Using shadow GPRs for vectored interrupts has never been used,
time to remove it.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 arch/mips/kernel/traps.c | 94 +++++++++++++---------------------------
 1 file changed, 30 insertions(+), 64 deletions(-)

diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index d90b18908692..c1b2b18b0505 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -2055,105 +2055,71 @@ static void do_default_vi(void)
 	panic("Caught unexpected vectored interrupt.");
 }
 
-static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
+void *set_vi_handler(int n, vi_handler_t addr)
 {
+	extern const u8 except_vec_vi[];
+	extern const u8 except_vec_vi_ori[], except_vec_vi_end[];
+	extern const u8 rollback_except_vec_vi[];
 	unsigned long handler;
 	unsigned long old_handler = vi_handlers[n];
 	int srssets = current_cpu_data.srsets;
 	u16 *h;
 	unsigned char *b;
+	const u8 *vec_start;
+	int ori_offset;
+	int handler_len;
 
 	BUG_ON(!cpu_has_veic && !cpu_has_vint);
 
 	if (addr == NULL) {
 		handler = (unsigned long) do_default_vi;
-		srs = 0;
 	} else
 		handler = (unsigned long) addr;
 	vi_handlers[n] = handler;
 
 	b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING);
 
-	if (srs >= srssets)
-		panic("Shadow register set %d not supported", srs);
-
 	if (cpu_has_veic) {
 		if (board_bind_eic_interrupt)
-			board_bind_eic_interrupt(n, srs);
+			board_bind_eic_interrupt(n, 0);
 	} else if (cpu_has_vint) {
 		/* SRSMap is only defined if shadow sets are implemented */
 		if (srssets > 1)
-			change_c0_srsmap(0xf << n*4, srs << n*4);
+			change_c0_srsmap(0xf << n*4, 0 << n*4);
 	}
 
-	if (srs == 0) {
-		/*
-		 * If no shadow set is selected then use the default handler
-		 * that does normal register saving and standard interrupt exit
-		 */
-		extern const u8 except_vec_vi[];
-		extern const u8 except_vec_vi_ori[], except_vec_vi_end[];
-		extern const u8 rollback_except_vec_vi[];
-		const u8 *vec_start = using_rollback_handler() ?
-				      rollback_except_vec_vi : except_vec_vi;
+	vec_start = using_rollback_handler() ? rollback_except_vec_vi :
+					       except_vec_vi;
 #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
-		const int ori_offset = except_vec_vi_ori - vec_start + 2;
+	ori_offset = except_vec_vi_ori - vec_start + 2;
 #else
-		const int ori_offset = except_vec_vi_ori - vec_start;
+	ori_offset = except_vec_vi_ori - vec_start;
 #endif
-		const int handler_len = except_vec_vi_end - vec_start;
+	handler_len = except_vec_vi_end - vec_start;
 
-		if (handler_len > VECTORSPACING) {
-			/*
-			 * Sigh... panicing won't help as the console
-			 * is probably not configured :(
-			 */
-			panic("VECTORSPACING too small");
-		}
-
-		set_handler(((unsigned long)b - ebase), vec_start,
-#ifdef CONFIG_CPU_MICROMIPS
-				(handler_len - 1));
-#else
-				handler_len);
-#endif
-		/* insert offset into vi_handlers[] */
-		h = (u16 *)(b + ori_offset);
-		*h = n * sizeof(handler);
-		local_flush_icache_range((unsigned long)b,
-					 (unsigned long)(b+handler_len));
-	}
-	else {
+	if (handler_len > VECTORSPACING) {
 		/*
-		 * In other cases jump directly to the interrupt handler. It
-		 * is the handler's responsibility to save registers if required
-		 * (eg hi/lo) and return from the exception using "eret".
+		 * Sigh... panicing won't help as the console
+		 * is probably not configured :(
 		 */
-		u32 insn;
-
-		h = (u16 *)b;
-		/* j handler */
-#ifdef CONFIG_CPU_MICROMIPS
-		insn = 0xd4000000 | (((u32)handler & 0x07ffffff) >> 1);
-#else
-		insn = 0x08000000 | (((u32)handler & 0x0fffffff) >> 2);
-#endif
-		h[0] = (insn >> 16) & 0xffff;
-		h[1] = insn & 0xffff;
-		h[2] = 0;
-		h[3] = 0;
-		local_flush_icache_range((unsigned long)b,
-					 (unsigned long)(b+8));
+		panic("VECTORSPACING too small");
 	}
 
+	set_handler(((unsigned long)b - ebase), vec_start,
+#ifdef CONFIG_CPU_MICROMIPS
+			(handler_len - 1));
+#else
+			handler_len);
+#endif
+	/* insert offset into vi_handlers[] */
+	h = (u16 *)(b + ori_offset);
+	*h = n * sizeof(handler);
+	local_flush_icache_range((unsigned long)b,
+				 (unsigned long)(b+handler_len));
+
 	return (void *)old_handler;
 }
 
-void *set_vi_handler(int n, vi_handler_t addr)
-{
-	return set_vi_srs_handler(n, addr, 0);
-}
-
 extern void tlb_init(void);
 
 /*
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit
  2023-12-21 12:54 [PATCH 1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit Thomas Bogendoerfer
  2023-12-21 12:54 ` [PATCH 2/2] MIPS: Remove unused shadow GPR support from vector irq setup Thomas Bogendoerfer
@ 2023-12-22 12:58 ` Jiaxun Yang
  2023-12-30 14:45 ` Thomas Bogendoerfer
  2 siblings, 0 replies; 5+ messages in thread
From: Jiaxun Yang @ 2023-12-22 12:58 UTC (permalink / raw)
  To: Thomas Bogendoerfer, linux-mips, linux-kernel



在 2023/12/21 12:54, Thomas Bogendoerfer 写道:
> Setting up vector interrupts worked only with handlers, which resided
> in CKSEG0 space. This limits the kernel placement for 64bit platforms.
> By patching in the offset into vi_handlers[] instead of the full
> handler address, the vectored exception handler can load the
> address by itself and jump to it.
>
> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>

Could you please keep me in Cc if you are going to propose a better
solution :-)

Thanks
- Jiaxun

> ---
>   arch/mips/kernel/genex.S | 8 ++++----
>   arch/mips/kernel/traps.c | 9 +++------
>   2 files changed, 7 insertions(+), 10 deletions(-)
>
> diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
> index b6de8e88c1bd..a572ce36a24f 100644
> --- a/arch/mips/kernel/genex.S
> +++ b/arch/mips/kernel/genex.S
> @@ -272,18 +272,17 @@ NESTED(except_vec_vi, 0, sp)
>   	.set	push
>   	.set	noreorder
>   	PTR_LA	v1, except_vec_vi_handler
> -FEXPORT(except_vec_vi_lui)
> -	lui	v0, 0		/* Patched */
>   	jr	v1
>   FEXPORT(except_vec_vi_ori)
> -	 ori	v0, 0		/* Patched */
> +	 ori	v0, zero, 0		/* Offset in vi_handlers[] */
>   	.set	pop
>   	END(except_vec_vi)
>   EXPORT(except_vec_vi_end)
>   
>   /*
>    * Common Vectored Interrupt code
> - * Complete the register saves and invoke the handler which is passed in $v0
> + * Complete the register saves and invoke the handler, $v0 holds
> + * offset into vi_handlers[]
>    */
>   NESTED(except_vec_vi_handler, 0, sp)
>   	SAVE_TEMP
> @@ -331,6 +330,7 @@ NESTED(except_vec_vi_handler, 0, sp)
>   	/* Save task's sp on IRQ stack so that unwinding can follow it */
>   	LONG_S	s1, 0(sp)
>   2:
> +	PTR_L	v0, vi_handlers(v0)
>   	jalr	v0
>   
>   	/* Restore sp */
> diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
> index 246c6a6b0261..d90b18908692 100644
> --- a/arch/mips/kernel/traps.c
> +++ b/arch/mips/kernel/traps.c
> @@ -2091,16 +2091,14 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
>   		 * If no shadow set is selected then use the default handler
>   		 * that does normal register saving and standard interrupt exit
>   		 */
> -		extern const u8 except_vec_vi[], except_vec_vi_lui[];
> +		extern const u8 except_vec_vi[];
>   		extern const u8 except_vec_vi_ori[], except_vec_vi_end[];
>   		extern const u8 rollback_except_vec_vi[];
>   		const u8 *vec_start = using_rollback_handler() ?
>   				      rollback_except_vec_vi : except_vec_vi;
>   #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
> -		const int lui_offset = except_vec_vi_lui - vec_start + 2;
>   		const int ori_offset = except_vec_vi_ori - vec_start + 2;
>   #else
> -		const int lui_offset = except_vec_vi_lui - vec_start;
>   		const int ori_offset = except_vec_vi_ori - vec_start;
>   #endif
>   		const int handler_len = except_vec_vi_end - vec_start;
> @@ -2119,10 +2117,9 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
>   #else
>   				handler_len);
>   #endif
> -		h = (u16 *)(b + lui_offset);
> -		*h = (handler >> 16) & 0xffff;
> +		/* insert offset into vi_handlers[] */
>   		h = (u16 *)(b + ori_offset);
> -		*h = (handler & 0xffff);
> +		*h = n * sizeof(handler);
>   		local_flush_icache_range((unsigned long)b,
>   					 (unsigned long)(b+handler_len));
>   	}


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit
  2023-12-21 12:54 [PATCH 1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit Thomas Bogendoerfer
  2023-12-21 12:54 ` [PATCH 2/2] MIPS: Remove unused shadow GPR support from vector irq setup Thomas Bogendoerfer
  2023-12-22 12:58 ` [PATCH 1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit Jiaxun Yang
@ 2023-12-30 14:45 ` Thomas Bogendoerfer
  2 siblings, 0 replies; 5+ messages in thread
From: Thomas Bogendoerfer @ 2023-12-30 14:45 UTC (permalink / raw)
  To: linux-mips, linux-kernel

On Thu, Dec 21, 2023 at 01:54:03PM +0100, Thomas Bogendoerfer wrote:
> Setting up vector interrupts worked only with handlers, which resided
> in CKSEG0 space. This limits the kernel placement for 64bit platforms.
> By patching in the offset into vi_handlers[] instead of the full
> handler address, the vectored exception handler can load the
> address by itself and jump to it.
> 
> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> ---
>  arch/mips/kernel/genex.S | 8 ++++----
>  arch/mips/kernel/traps.c | 9 +++------
>  2 files changed, 7 insertions(+), 10 deletions(-)

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] MIPS: Remove unused shadow GPR support from vector irq setup
  2023-12-21 12:54 ` [PATCH 2/2] MIPS: Remove unused shadow GPR support from vector irq setup Thomas Bogendoerfer
@ 2023-12-30 14:45   ` Thomas Bogendoerfer
  0 siblings, 0 replies; 5+ messages in thread
From: Thomas Bogendoerfer @ 2023-12-30 14:45 UTC (permalink / raw)
  To: linux-mips, linux-kernel

On Thu, Dec 21, 2023 at 01:54:04PM +0100, Thomas Bogendoerfer wrote:
> Using shadow GPRs for vectored interrupts has never been used,
> time to remove it.
> 
> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> ---
>  arch/mips/kernel/traps.c | 94 +++++++++++++---------------------------
>  1 file changed, 30 insertions(+), 64 deletions(-)

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-12-30 15:39 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-21 12:54 [PATCH 1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit Thomas Bogendoerfer
2023-12-21 12:54 ` [PATCH 2/2] MIPS: Remove unused shadow GPR support from vector irq setup Thomas Bogendoerfer
2023-12-30 14:45   ` Thomas Bogendoerfer
2023-12-22 12:58 ` [PATCH 1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit Jiaxun Yang
2023-12-30 14:45 ` Thomas Bogendoerfer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox