Message ID | 20231221125405.229100-1-tsbogend@alpha.franken.de (mailing list archive) |
---|---|
State | Accepted |
Commit | 682fb5be353117b7321f1dfb65b7bb98cbfe59ab |
Headers | show |
Series | [1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit | expand |
在 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)); > }
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.
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)); }
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(-)