Messages in this thread |  | | Date | Fri, 22 Dec 2023 12:58:43 +0000 | | Subject | Re: [PATCH 1/2] MIPS: Allow vectored interrupt handler to reside everywhere for 64bit | | From | Jiaxun Yang <> |
| |
在 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)); > }
|  |