Skip to content

Commit 2865936

Browse files
committed
Merge tag 'powerpc-5.6-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: "Some more powerpc fixes for 5.6. This is two weeks worth as I was out sick last week: - Three fixes for the recently added VMAP_STACK on 32-bit. - Three fixes related to hugepages on 8xx (32-bit). - A fix for a bug in our transactional memory handling that could lead to a kernel crash if we saw a page fault during signal delivery. - A fix for a deadlock in our PCI EEH (Enhanced Error Handling) code. - A couple of other minor fixes. Thanks to: Christophe Leroy, Erhard F, Frederic Barrat, Gustavo Luiz Duarte, Larry Finger, Leonardo Bras, Oliver O'Halloran, Sam Bobroff" * tag 'powerpc-5.6-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/entry: Fix an #if which should be an #ifdef in entry_32.S powerpc/xmon: Fix whitespace handling in getstring() powerpc/6xx: Fix power_save_ppc32_restore() with CONFIG_VMAP_STACK powerpc/chrp: Fix enter_rtas() with CONFIG_VMAP_STACK powerpc/32s: Fix DSI and ISI exceptions for CONFIG_VMAP_STACK powerpc/tm: Fix clearing MSR[TS] in current when reclaiming on signal delivery powerpc/8xx: Fix clearing of bits 20-23 in ITLB miss powerpc/hugetlb: Fix 8M hugepages on 8xx powerpc/hugetlb: Fix 512k hugepages on 8xx with 16k page size powerpc/eeh: Fix deadlock handling dead PHB
2 parents 0c0ddd6 + 9eb425b commit 2865936

File tree

17 files changed

+308
-99
lines changed

17 files changed

+308
-99
lines changed

arch/powerpc/include/asm/page.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,13 @@ static inline bool pfn_valid(unsigned long pfn)
295295
/*
296296
* Some number of bits at the level of the page table that points to
297297
* a hugepte are used to encode the size. This masks those bits.
298+
* On 8xx, HW assistance requires 4k alignment for the hugepte.
298299
*/
300+
#ifdef CONFIG_PPC_8xx
301+
#define HUGEPD_SHIFT_MASK 0xfff
302+
#else
299303
#define HUGEPD_SHIFT_MASK 0x3f
304+
#endif
300305

301306
#ifndef __ASSEMBLY__
302307

arch/powerpc/include/asm/processor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ struct thread_struct {
168168
unsigned long srr1;
169169
unsigned long dar;
170170
unsigned long dsisr;
171+
#ifdef CONFIG_PPC_BOOK3S_32
172+
unsigned long r0, r3, r4, r5, r6, r8, r9, r11;
173+
unsigned long lr, ctr;
174+
#endif
171175
#endif
172176
/* Debug Registers */
173177
struct debug_reg debug;

arch/powerpc/kernel/asm-offsets.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,18 @@ int main(void)
132132
OFFSET(SRR1, thread_struct, srr1);
133133
OFFSET(DAR, thread_struct, dar);
134134
OFFSET(DSISR, thread_struct, dsisr);
135+
#ifdef CONFIG_PPC_BOOK3S_32
136+
OFFSET(THR0, thread_struct, r0);
137+
OFFSET(THR3, thread_struct, r3);
138+
OFFSET(THR4, thread_struct, r4);
139+
OFFSET(THR5, thread_struct, r5);
140+
OFFSET(THR6, thread_struct, r6);
141+
OFFSET(THR8, thread_struct, r8);
142+
OFFSET(THR9, thread_struct, r9);
143+
OFFSET(THR11, thread_struct, r11);
144+
OFFSET(THLR, thread_struct, lr);
145+
OFFSET(THCTR, thread_struct, ctr);
146+
#endif
135147
#endif
136148
#ifdef CONFIG_SPE
137149
OFFSET(THREAD_EVR0, thread_struct, evr[0]);

arch/powerpc/kernel/eeh_driver.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,17 @@ void eeh_handle_special_event(void)
11841184
eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
11851185
eeh_handle_normal_event(pe);
11861186
} else {
1187+
eeh_for_each_pe(pe, tmp_pe)
1188+
eeh_pe_for_each_dev(tmp_pe, edev, tmp_edev)
1189+
edev->mode &= ~EEH_DEV_NO_HANDLER;
1190+
1191+
/* Notify all devices to be down */
1192+
eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true);
1193+
eeh_set_channel_state(pe, pci_channel_io_perm_failure);
1194+
eeh_pe_report(
1195+
"error_detected(permanent failure)", pe,
1196+
eeh_report_failure, NULL);
1197+
11871198
pci_lock_rescan_remove();
11881199
list_for_each_entry(hose, &hose_list, list_node) {
11891200
phb_pe = eeh_phb_pe_get(hose);
@@ -1192,16 +1203,6 @@ void eeh_handle_special_event(void)
11921203
(phb_pe->state & EEH_PE_RECOVERING))
11931204
continue;
11941205

1195-
eeh_for_each_pe(pe, tmp_pe)
1196-
eeh_pe_for_each_dev(tmp_pe, edev, tmp_edev)
1197-
edev->mode &= ~EEH_DEV_NO_HANDLER;
1198-
1199-
/* Notify all devices to be down */
1200-
eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true);
1201-
eeh_set_channel_state(pe, pci_channel_io_perm_failure);
1202-
eeh_pe_report(
1203-
"error_detected(permanent failure)", pe,
1204-
eeh_report_failure, NULL);
12051206
bus = eeh_pe_bus_get(phb_pe);
12061207
if (!bus) {
12071208
pr_err("%s: Cannot find PCI bus for "

arch/powerpc/kernel/entry_32.S

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -783,15 +783,15 @@ fast_exception_return:
783783
1: lis r3,exc_exit_restart_end@ha
784784
addi r3,r3,exc_exit_restart_end@l
785785
cmplw r12,r3
786-
#if CONFIG_PPC_BOOK3S_601
786+
#ifdef CONFIG_PPC_BOOK3S_601
787787
bge 2b
788788
#else
789789
bge 3f
790790
#endif
791791
lis r4,exc_exit_restart@ha
792792
addi r4,r4,exc_exit_restart@l
793793
cmplw r12,r4
794-
#if CONFIG_PPC_BOOK3S_601
794+
#ifdef CONFIG_PPC_BOOK3S_601
795795
blt 2b
796796
#else
797797
blt 3f
@@ -1354,12 +1354,17 @@ _GLOBAL(enter_rtas)
13541354
mtspr SPRN_SRR0,r8
13551355
mtspr SPRN_SRR1,r9
13561356
RFI
1357-
1: tophys(r9,r1)
1357+
1: tophys_novmstack r9, r1
1358+
#ifdef CONFIG_VMAP_STACK
1359+
li r0, MSR_KERNEL & ~MSR_IR /* can take DTLB miss */
1360+
mtmsr r0
1361+
isync
1362+
#endif
13581363
lwz r8,INT_FRAME_SIZE+4(r9) /* get return address */
13591364
lwz r9,8(r9) /* original msr value */
13601365
addi r1,r1,INT_FRAME_SIZE
13611366
li r0,0
1362-
tophys(r7, r2)
1367+
tophys_novmstack r7, r2
13631368
stw r0, THREAD + RTAS_SP(r7)
13641369
mtspr SPRN_SRR0,r8
13651370
mtspr SPRN_SRR1,r9

arch/powerpc/kernel/head_32.S

Lines changed: 150 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,17 +290,55 @@ MachineCheck:
290290
7: EXCEPTION_PROLOG_2
291291
addi r3,r1,STACK_FRAME_OVERHEAD
292292
#ifdef CONFIG_PPC_CHRP
293-
bne cr1,1f
293+
#ifdef CONFIG_VMAP_STACK
294+
mfspr r4, SPRN_SPRG_THREAD
295+
tovirt(r4, r4)
296+
lwz r4, RTAS_SP(r4)
297+
cmpwi cr1, r4, 0
294298
#endif
295-
EXC_XFER_STD(0x200, machine_check_exception)
296-
#ifdef CONFIG_PPC_CHRP
297-
1: b machine_check_in_rtas
299+
beq cr1, machine_check_tramp
300+
b machine_check_in_rtas
301+
#else
302+
b machine_check_tramp
298303
#endif
299304

300305
/* Data access exception. */
301306
. = 0x300
302307
DO_KVM 0x300
303308
DataAccess:
309+
#ifdef CONFIG_VMAP_STACK
310+
mtspr SPRN_SPRG_SCRATCH0,r10
311+
mfspr r10, SPRN_SPRG_THREAD
312+
BEGIN_MMU_FTR_SECTION
313+
stw r11, THR11(r10)
314+
mfspr r10, SPRN_DSISR
315+
mfcr r11
316+
#ifdef CONFIG_PPC_KUAP
317+
andis. r10, r10, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH | DSISR_PROTFAULT)@h
318+
#else
319+
andis. r10, r10, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h
320+
#endif
321+
mfspr r10, SPRN_SPRG_THREAD
322+
beq hash_page_dsi
323+
.Lhash_page_dsi_cont:
324+
mtcr r11
325+
lwz r11, THR11(r10)
326+
END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
327+
mtspr SPRN_SPRG_SCRATCH1,r11
328+
mfspr r11, SPRN_DAR
329+
stw r11, DAR(r10)
330+
mfspr r11, SPRN_DSISR
331+
stw r11, DSISR(r10)
332+
mfspr r11, SPRN_SRR0
333+
stw r11, SRR0(r10)
334+
mfspr r11, SPRN_SRR1 /* check whether user or kernel */
335+
stw r11, SRR1(r10)
336+
mfcr r10
337+
andi. r11, r11, MSR_PR
338+
339+
EXCEPTION_PROLOG_1
340+
b handle_page_fault_tramp_1
341+
#else /* CONFIG_VMAP_STACK */
304342
EXCEPTION_PROLOG handle_dar_dsisr=1
305343
get_and_save_dar_dsisr_on_stack r4, r5, r11
306344
BEGIN_MMU_FTR_SECTION
@@ -316,11 +354,32 @@ BEGIN_MMU_FTR_SECTION
316354
FTR_SECTION_ELSE
317355
b handle_page_fault_tramp_2
318356
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
357+
#endif /* CONFIG_VMAP_STACK */
319358

320359
/* Instruction access exception. */
321360
. = 0x400
322361
DO_KVM 0x400
323362
InstructionAccess:
363+
#ifdef CONFIG_VMAP_STACK
364+
mtspr SPRN_SPRG_SCRATCH0,r10
365+
mtspr SPRN_SPRG_SCRATCH1,r11
366+
mfspr r10, SPRN_SPRG_THREAD
367+
mfspr r11, SPRN_SRR0
368+
stw r11, SRR0(r10)
369+
mfspr r11, SPRN_SRR1 /* check whether user or kernel */
370+
stw r11, SRR1(r10)
371+
mfcr r10
372+
BEGIN_MMU_FTR_SECTION
373+
andis. r11, r11, SRR1_ISI_NOPT@h /* no pte found? */
374+
bne hash_page_isi
375+
.Lhash_page_isi_cont:
376+
mfspr r11, SPRN_SRR1 /* check whether user or kernel */
377+
END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
378+
andi. r11, r11, MSR_PR
379+
380+
EXCEPTION_PROLOG_1
381+
EXCEPTION_PROLOG_2
382+
#else /* CONFIG_VMAP_STACK */
324383
EXCEPTION_PROLOG
325384
andis. r0,r9,SRR1_ISI_NOPT@h /* no pte found? */
326385
beq 1f /* if so, try to put a PTE */
@@ -329,6 +388,7 @@ InstructionAccess:
329388
BEGIN_MMU_FTR_SECTION
330389
bl hash_page
331390
END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
391+
#endif /* CONFIG_VMAP_STACK */
332392
1: mr r4,r12
333393
andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
334394
stw r4, _DAR(r11)
@@ -344,7 +404,7 @@ Alignment:
344404
EXCEPTION_PROLOG handle_dar_dsisr=1
345405
save_dar_dsisr_on_stack r4, r5, r11
346406
addi r3,r1,STACK_FRAME_OVERHEAD
347-
EXC_XFER_STD(0x600, alignment_exception)
407+
b alignment_exception_tramp
348408

349409
/* Program check exception */
350410
EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
@@ -645,15 +705,100 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
645705

646706
. = 0x3000
647707

708+
machine_check_tramp:
709+
EXC_XFER_STD(0x200, machine_check_exception)
710+
711+
alignment_exception_tramp:
712+
EXC_XFER_STD(0x600, alignment_exception)
713+
648714
handle_page_fault_tramp_1:
715+
#ifdef CONFIG_VMAP_STACK
716+
EXCEPTION_PROLOG_2 handle_dar_dsisr=1
717+
#endif
649718
lwz r4, _DAR(r11)
650719
lwz r5, _DSISR(r11)
651720
/* fall through */
652721
handle_page_fault_tramp_2:
653722
EXC_XFER_LITE(0x300, handle_page_fault)
654723

724+
#ifdef CONFIG_VMAP_STACK
725+
.macro save_regs_thread thread
726+
stw r0, THR0(\thread)
727+
stw r3, THR3(\thread)
728+
stw r4, THR4(\thread)
729+
stw r5, THR5(\thread)
730+
stw r6, THR6(\thread)
731+
stw r8, THR8(\thread)
732+
stw r9, THR9(\thread)
733+
mflr r0
734+
stw r0, THLR(\thread)
735+
mfctr r0
736+
stw r0, THCTR(\thread)
737+
.endm
738+
739+
.macro restore_regs_thread thread
740+
lwz r0, THLR(\thread)
741+
mtlr r0
742+
lwz r0, THCTR(\thread)
743+
mtctr r0
744+
lwz r0, THR0(\thread)
745+
lwz r3, THR3(\thread)
746+
lwz r4, THR4(\thread)
747+
lwz r5, THR5(\thread)
748+
lwz r6, THR6(\thread)
749+
lwz r8, THR8(\thread)
750+
lwz r9, THR9(\thread)
751+
.endm
752+
753+
hash_page_dsi:
754+
save_regs_thread r10
755+
mfdsisr r3
756+
mfdar r4
757+
mfsrr0 r5
758+
mfsrr1 r9
759+
rlwinm r3, r3, 32 - 15, _PAGE_RW /* DSISR_STORE -> _PAGE_RW */
760+
bl hash_page
761+
mfspr r10, SPRN_SPRG_THREAD
762+
restore_regs_thread r10
763+
b .Lhash_page_dsi_cont
764+
765+
hash_page_isi:
766+
mr r11, r10
767+
mfspr r10, SPRN_SPRG_THREAD
768+
save_regs_thread r10
769+
li r3, 0
770+
lwz r4, SRR0(r10)
771+
lwz r9, SRR1(r10)
772+
bl hash_page
773+
mfspr r10, SPRN_SPRG_THREAD
774+
restore_regs_thread r10
775+
mr r10, r11
776+
b .Lhash_page_isi_cont
777+
778+
.globl fast_hash_page_return
779+
fast_hash_page_return:
780+
andis. r10, r9, SRR1_ISI_NOPT@h /* Set on ISI, cleared on DSI */
781+
mfspr r10, SPRN_SPRG_THREAD
782+
restore_regs_thread r10
783+
bne 1f
784+
785+
/* DSI */
786+
mtcr r11
787+
lwz r11, THR11(r10)
788+
mfspr r10, SPRN_SPRG_SCRATCH0
789+
SYNC
790+
RFI
791+
792+
1: /* ISI */
793+
mtcr r11
794+
mfspr r11, SPRN_SPRG_SCRATCH1
795+
mfspr r10, SPRN_SPRG_SCRATCH0
796+
SYNC
797+
RFI
798+
655799
stack_overflow:
656800
vmap_stack_overflow_exception
801+
#endif
657802

658803
AltiVecUnavailable:
659804
EXCEPTION_PROLOG

arch/powerpc/kernel/head_32.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,25 @@
6464
.endm
6565

6666
.macro EXCEPTION_PROLOG_2 handle_dar_dsisr=0
67+
#if defined(CONFIG_VMAP_STACK) && defined(CONFIG_PPC_BOOK3S)
68+
BEGIN_MMU_FTR_SECTION
69+
mtcr r10
70+
FTR_SECTION_ELSE
71+
stw r10, _CCR(r11)
72+
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
73+
#else
6774
stw r10,_CCR(r11) /* save registers */
75+
#endif
76+
mfspr r10, SPRN_SPRG_SCRATCH0
6877
stw r12,GPR12(r11)
6978
stw r9,GPR9(r11)
70-
mfspr r10,SPRN_SPRG_SCRATCH0
7179
stw r10,GPR10(r11)
80+
#if defined(CONFIG_VMAP_STACK) && defined(CONFIG_PPC_BOOK3S)
81+
BEGIN_MMU_FTR_SECTION
82+
mfcr r10
83+
stw r10, _CCR(r11)
84+
END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
85+
#endif
7286
mfspr r12,SPRN_SPRG_SCRATCH1
7387
stw r12,GPR11(r11)
7488
mflr r10
@@ -83,6 +97,11 @@
8397
stw r10, _DSISR(r11)
8498
.endif
8599
lwz r9, SRR1(r12)
100+
#if defined(CONFIG_VMAP_STACK) && defined(CONFIG_PPC_BOOK3S)
101+
BEGIN_MMU_FTR_SECTION
102+
andi. r10, r9, MSR_PR
103+
END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
104+
#endif
86105
lwz r12, SRR0(r12)
87106
#else
88107
mfspr r12,SPRN_SRR0

arch/powerpc/kernel/head_8xx.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ InstructionTLBMiss:
256256
* set. All other Linux PTE bits control the behavior
257257
* of the MMU.
258258
*/
259-
rlwimi r10, r10, 0, 0x0f00 /* Clear bits 20-23 */
259+
rlwinm r10, r10, 0, ~0x0f00 /* Clear bits 20-23 */
260260
rlwimi r10, r10, 4, 0x0400 /* Copy _PAGE_EXEC into bit 21 */
261261
ori r10, r10, RPN_PATTERN | 0x200 /* Set 22 and 24-27 */
262262
mtspr SPRN_MI_RPN, r10 /* Update TLB entry */

arch/powerpc/kernel/idle_6xx.S

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,23 @@ BEGIN_FTR_SECTION
166166
mfspr r9,SPRN_HID0
167167
andis. r9,r9,HID0_NAP@h
168168
beq 1f
169+
#ifdef CONFIG_VMAP_STACK
170+
addis r9, r11, nap_save_msscr0@ha
171+
#else
169172
addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha
173+
#endif
170174
lwz r9,nap_save_msscr0@l(r9)
171175
mtspr SPRN_MSSCR0, r9
172176
sync
173177
isync
174178
1:
175179
END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
176180
BEGIN_FTR_SECTION
181+
#ifdef CONFIG_VMAP_STACK
182+
addis r9, r11, nap_save_hid1@ha
183+
#else
177184
addis r9,r11,(nap_save_hid1-KERNELBASE)@ha
185+
#endif
178186
lwz r9,nap_save_hid1@l(r9)
179187
mtspr SPRN_HID1, r9
180188
END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)

0 commit comments

Comments
 (0)