Skip to content

Commit ecb9194

Browse files
committed
Merge tag 'mips-fixes_6.15_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
Pull MIPS fixes from Thomas Bogendoerfer: - Fix delayed timers - Fix NULL pointer deref - Fix wrong range check * tag 'mips-fixes_6.15_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: MIPS: Fix MAX_REG_OFFSET MIPS: CPS: Fix potential NULL pointer dereferences in cps_prepare_cpus() MIPS: rename rollback_handler with skipover_handler MIPS: Move r4k_wait() to .cpuidle.text section MIPS: Fix idle VS timer enqueue
2 parents b9e62a2 + c44572e commit ecb9194

File tree

6 files changed

+54
-46
lines changed

6 files changed

+54
-46
lines changed

arch/mips/include/asm/idle.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
#include <linux/linkage.h>
77

88
extern void (*cpu_wait)(void);
9-
extern void r4k_wait(void);
10-
extern asmlinkage void __r4k_wait(void);
9+
extern asmlinkage void r4k_wait(void);
1110
extern void r4k_wait_irqoff(void);
1211

13-
static inline int using_rollback_handler(void)
12+
static inline int using_skipover_handler(void)
1413
{
1514
return cpu_wait == r4k_wait;
1615
}

arch/mips/include/asm/ptrace.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ static inline void instruction_pointer_set(struct pt_regs *regs,
6565

6666
/* Query offset/name of register from its name/offset */
6767
extern int regs_query_register_offset(const char *name);
68-
#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last))
68+
#define MAX_REG_OFFSET \
69+
(offsetof(struct pt_regs, __last) - sizeof(unsigned long))
6970

7071
/**
7172
* regs_get_register() - get register value from its offset

arch/mips/kernel/genex.S

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -104,48 +104,59 @@ handle_vcei:
104104

105105
__FINIT
106106

107-
.align 5 /* 32 byte rollback region */
108-
LEAF(__r4k_wait)
109-
.set push
110-
.set noreorder
111-
/* start of rollback region */
112-
LONG_L t0, TI_FLAGS($28)
113-
nop
114-
andi t0, _TIF_NEED_RESCHED
115-
bnez t0, 1f
116-
nop
117-
nop
118-
nop
119-
#ifdef CONFIG_CPU_MICROMIPS
120-
nop
121-
nop
122-
nop
123-
nop
124-
#endif
107+
.section .cpuidle.text,"ax"
108+
/* Align to 32 bytes for the maximum idle interrupt region size. */
109+
.align 5
110+
LEAF(r4k_wait)
111+
/* Keep the ISA bit clear for calculations on local labels here. */
112+
0: .fill 0
113+
/* Start of idle interrupt region. */
114+
local_irq_enable
115+
/*
116+
* If an interrupt lands here, before going idle on the next
117+
* instruction, we must *NOT* go idle since the interrupt could
118+
* have set TIF_NEED_RESCHED or caused a timer to need resched.
119+
* Fall through -- see skipover_handler below -- and have the
120+
* idle loop take care of things.
121+
*/
122+
1: .fill 0
123+
/* The R2 EI/EHB sequence takes 8 bytes, otherwise pad up. */
124+
.if 1b - 0b > 32
125+
.error "overlong idle interrupt region"
126+
.elseif 1b - 0b > 8
127+
.align 4
128+
.endif
129+
2: .fill 0
130+
.equ r4k_wait_idle_size, 2b - 0b
131+
/* End of idle interrupt region; size has to be a power of 2. */
125132
.set MIPS_ISA_ARCH_LEVEL_RAW
133+
r4k_wait_insn:
126134
wait
127-
/* end of rollback region (the region size must be power of two) */
128-
1:
135+
r4k_wait_exit:
136+
.set mips0
137+
local_irq_disable
129138
jr ra
130-
nop
131-
.set pop
132-
END(__r4k_wait)
139+
END(r4k_wait)
140+
.previous
133141

134-
.macro BUILD_ROLLBACK_PROLOGUE handler
135-
FEXPORT(rollback_\handler)
142+
.macro BUILD_SKIPOVER_PROLOGUE handler
143+
FEXPORT(skipover_\handler)
136144
.set push
137145
.set noat
138146
MFC0 k0, CP0_EPC
139-
PTR_LA k1, __r4k_wait
140-
ori k0, 0x1f /* 32 byte rollback region */
141-
xori k0, 0x1f
147+
/* Subtract/add 2 to let the ISA bit propagate through the mask. */
148+
PTR_LA k1, r4k_wait_insn - 2
149+
ori k0, r4k_wait_idle_size - 2
150+
.set noreorder
142151
bne k0, k1, \handler
152+
PTR_ADDIU k0, r4k_wait_exit - r4k_wait_insn + 2
153+
.set reorder
143154
MTC0 k0, CP0_EPC
144155
.set pop
145156
.endm
146157

147158
.align 5
148-
BUILD_ROLLBACK_PROLOGUE handle_int
159+
BUILD_SKIPOVER_PROLOGUE handle_int
149160
NESTED(handle_int, PT_SIZE, sp)
150161
.cfi_signal_frame
151162
#ifdef CONFIG_TRACE_IRQFLAGS
@@ -265,7 +276,7 @@ NESTED(except_vec_ejtag_debug, 0, sp)
265276
* This prototype is copied to ebase + n*IntCtl.VS and patched
266277
* to invoke the handler
267278
*/
268-
BUILD_ROLLBACK_PROLOGUE except_vec_vi
279+
BUILD_SKIPOVER_PROLOGUE except_vec_vi
269280
NESTED(except_vec_vi, 0, sp)
270281
SAVE_SOME docfi=1
271282
SAVE_AT docfi=1

arch/mips/kernel/idle.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,6 @@ static void __cpuidle r3081_wait(void)
3535
write_c0_conf(cfg | R30XX_CONF_HALT);
3636
}
3737

38-
void __cpuidle r4k_wait(void)
39-
{
40-
raw_local_irq_enable();
41-
__r4k_wait();
42-
raw_local_irq_disable();
43-
}
44-
4538
/*
4639
* This variant is preferable as it allows testing need_resched and going to
4740
* sleep depending on the outcome atomically. Unfortunately the "It is

arch/mips/kernel/smp-cps.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
332332
mips_cps_cluster_bootcfg = kcalloc(nclusters,
333333
sizeof(*mips_cps_cluster_bootcfg),
334334
GFP_KERNEL);
335+
if (!mips_cps_cluster_bootcfg)
336+
goto err_out;
335337

336338
if (nclusters > 1)
337339
mips_cm_update_property();
@@ -348,6 +350,8 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
348350
mips_cps_cluster_bootcfg[cl].core_power =
349351
kcalloc(BITS_TO_LONGS(ncores), sizeof(unsigned long),
350352
GFP_KERNEL);
353+
if (!mips_cps_cluster_bootcfg[cl].core_power)
354+
goto err_out;
351355

352356
/* Allocate VPE boot configuration structs */
353357
for (c = 0; c < ncores; c++) {

arch/mips/kernel/traps.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
#include "access-helper.h"
7878

7979
extern void check_wait(void);
80-
extern asmlinkage void rollback_handle_int(void);
80+
extern asmlinkage void skipover_handle_int(void);
8181
extern asmlinkage void handle_int(void);
8282
extern asmlinkage void handle_adel(void);
8383
extern asmlinkage void handle_ades(void);
@@ -2066,7 +2066,7 @@ void *set_vi_handler(int n, vi_handler_t addr)
20662066
{
20672067
extern const u8 except_vec_vi[];
20682068
extern const u8 except_vec_vi_ori[], except_vec_vi_end[];
2069-
extern const u8 rollback_except_vec_vi[];
2069+
extern const u8 skipover_except_vec_vi[];
20702070
unsigned long handler;
20712071
unsigned long old_handler = vi_handlers[n];
20722072
int srssets = current_cpu_data.srsets;
@@ -2095,7 +2095,7 @@ void *set_vi_handler(int n, vi_handler_t addr)
20952095
change_c0_srsmap(0xf << n*4, 0 << n*4);
20962096
}
20972097

2098-
vec_start = using_rollback_handler() ? rollback_except_vec_vi :
2098+
vec_start = using_skipover_handler() ? skipover_except_vec_vi :
20992099
except_vec_vi;
21002100
#if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
21012101
ori_offset = except_vec_vi_ori - vec_start + 2;
@@ -2426,8 +2426,8 @@ void __init trap_init(void)
24262426
if (board_be_init)
24272427
board_be_init();
24282428

2429-
set_except_vector(EXCCODE_INT, using_rollback_handler() ?
2430-
rollback_handle_int : handle_int);
2429+
set_except_vector(EXCCODE_INT, using_skipover_handler() ?
2430+
skipover_handle_int : handle_int);
24312431
set_except_vector(EXCCODE_MOD, handle_tlbm);
24322432
set_except_vector(EXCCODE_TLBL, handle_tlbl);
24332433
set_except_vector(EXCCODE_TLBS, handle_tlbs);

0 commit comments

Comments
 (0)