Skip to content

Commit 424f8ac

Browse files
Gautham R. Shenoympe
authored andcommitted
powerpc/powernv: Fix bug due to labeling ambiguity in power_enter_stop
Commit 09206b6 ("powernv: Pass PSSCR value and mask to power9_idle_stop") added additional code in power_enter_stop() to distinguish between stop requests whose PSSCR had ESL=EC=1 from those which did not. When ESL=EC=1, we do a forward-jump to a location labelled by "1", which had the code to handle the ESL=EC=1 case. Unfortunately just a couple of instructions before this label, is the macro IDLE_STATE_ENTER_SEQ() which also has a label "1" in its expansion. As a result, the current code can result in directly executing stop instruction for deep stop requests with PSSCR ESL=EC=1, without saving the hypervisor state. Fix this BUG by labeling the location that handles ESL=EC=1 case with a more descriptive label ".Lhandle_esl_ec_set" (local label suggestion a la .Lxx from Anton Blanchard). While at it, rename the label "2" labelling the location of the code handling entry into deep stop states with ".Lhandle_deep_stop". For a good measure, change the label in IDLE_STATE_ENTER_SEQ() macro to an not-so commonly used value in order to avoid similar mishaps in the future. Fixes: 09206b6 ("powernv: Pass PSSCR value and mask to power9_idle_stop") Signed-off-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent 7a70d72 commit 424f8ac

File tree

2 files changed

+8
-6
lines changed

2 files changed

+8
-6
lines changed

arch/powerpc/include/asm/cpuidle.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ static inline void report_invalid_psscr_val(u64 psscr_val, int err)
7070
std r0,0(r1); \
7171
ptesync; \
7272
ld r0,0(r1); \
73-
1: cmpd cr0,r0,r0; \
74-
bne 1b; \
73+
236: cmpd cr0,r0,r0; \
74+
bne 236b; \
7575
IDLE_INST; \
7676

7777
#define IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \

arch/powerpc/kernel/idle_book3s.S

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,19 +276,21 @@ power_enter_stop:
276276
*/
277277
andis. r4,r3,PSSCR_EC_ESL_MASK_SHIFTED
278278
clrldi r3,r3,60 /* r3 = Bits[60:63] = Requested Level (RL) */
279-
bne 1f
279+
bne .Lhandle_esl_ec_set
280280
IDLE_STATE_ENTER_SEQ(PPC_STOP)
281281
li r3,0 /* Since we didn't lose state, return 0 */
282282
b pnv_wakeup_noloss
283+
284+
.Lhandle_esl_ec_set:
283285
/*
284286
* Check if the requested state is a deep idle state.
285287
*/
286-
1: LOAD_REG_ADDRBASE(r5,pnv_first_deep_stop_state)
288+
LOAD_REG_ADDRBASE(r5,pnv_first_deep_stop_state)
287289
ld r4,ADDROFF(pnv_first_deep_stop_state)(r5)
288290
cmpd r3,r4
289-
bge 2f
291+
bge .Lhandle_deep_stop
290292
IDLE_STATE_ENTER_SEQ_NORET(PPC_STOP)
291-
2:
293+
.Lhandle_deep_stop:
292294
/*
293295
* Entering deep idle state.
294296
* Clear thread bit in PACA_CORE_IDLE_STATE, save SPRs to

0 commit comments

Comments
 (0)