mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-04 04:04:19 +00:00
MIPS: Allow vectored interrupt handler to reside everywhere for 64bit
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>
This commit is contained in:
parent
efe8ee1a8b
commit
682fb5be35
@ -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 */
|
||||
|
@ -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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user