Skip to content

Commit 682fb5b

Browse files
committed
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>
1 parent efe8ee1 commit 682fb5b

File tree

2 files changed

+7
-10
lines changed

2 files changed

+7
-10
lines changed

arch/mips/kernel/genex.S

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,18 +272,17 @@ NESTED(except_vec_vi, 0, sp)
272272
.set push
273273
.set noreorder
274274
PTR_LA v1, except_vec_vi_handler
275-
FEXPORT(except_vec_vi_lui)
276-
lui v0, 0 /* Patched */
277275
jr v1
278276
FEXPORT(except_vec_vi_ori)
279-
ori v0, 0 /* Patched */
277+
ori v0, zero, 0 /* Offset in vi_handlers[] */
280278
.set pop
281279
END(except_vec_vi)
282280
EXPORT(except_vec_vi_end)
283281

284282
/*
285283
* Common Vectored Interrupt code
286-
* Complete the register saves and invoke the handler which is passed in $v0
284+
* Complete the register saves and invoke the handler, $v0 holds
285+
* offset into vi_handlers[]
287286
*/
288287
NESTED(except_vec_vi_handler, 0, sp)
289288
SAVE_TEMP
@@ -331,6 +330,7 @@ NESTED(except_vec_vi_handler, 0, sp)
331330
/* Save task's sp on IRQ stack so that unwinding can follow it */
332331
LONG_S s1, 0(sp)
333332
2:
333+
PTR_L v0, vi_handlers(v0)
334334
jalr v0
335335

336336
/* Restore sp */

arch/mips/kernel/traps.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,16 +2091,14 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
20912091
* If no shadow set is selected then use the default handler
20922092
* that does normal register saving and standard interrupt exit
20932093
*/
2094-
extern const u8 except_vec_vi[], except_vec_vi_lui[];
2094+
extern const u8 except_vec_vi[];
20952095
extern const u8 except_vec_vi_ori[], except_vec_vi_end[];
20962096
extern const u8 rollback_except_vec_vi[];
20972097
const u8 *vec_start = using_rollback_handler() ?
20982098
rollback_except_vec_vi : except_vec_vi;
20992099
#if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
2100-
const int lui_offset = except_vec_vi_lui - vec_start + 2;
21012100
const int ori_offset = except_vec_vi_ori - vec_start + 2;
21022101
#else
2103-
const int lui_offset = except_vec_vi_lui - vec_start;
21042102
const int ori_offset = except_vec_vi_ori - vec_start;
21052103
#endif
21062104
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)
21192117
#else
21202118
handler_len);
21212119
#endif
2122-
h = (u16 *)(b + lui_offset);
2123-
*h = (handler >> 16) & 0xffff;
2120+
/* insert offset into vi_handlers[] */
21242121
h = (u16 *)(b + ori_offset);
2125-
*h = (handler & 0xffff);
2122+
*h = n * sizeof(handler);
21262123
local_flush_icache_range((unsigned long)b,
21272124
(unsigned long)(b+handler_len));
21282125
}

0 commit comments

Comments
 (0)