Skip to content

Commit 14c50a6

Browse files
committed
Merge tag 'powerpc-5.11-5' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: - Fix a bad interaction between the scv handling and the fallback L1D flush, which could lead to user register corruption. Only affects people using scv (~no one) on machines with old firmware that are missing the L1D flush. - Two small selftest fixes. Thanks to Eirik Fuller, Libor Pechacek, Nicholas Piggin, Sandipan Das, and Tulio Magno Quites Machado Filho. * tag 'powerpc-5.11-5' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/64s: fix scv entry fallback flush vs interrupt selftests/powerpc: Only test lwm/stmw on big endian selftests/powerpc: Fix exit status of pkey tests
2 parents c509ce2 + 08685be commit 14c50a6

File tree

9 files changed

+77
-7
lines changed

9 files changed

+77
-7
lines changed

arch/powerpc/include/asm/exception-64s.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,26 @@
6363
nop; \
6464
nop;
6565

66+
#define SCV_ENTRY_FLUSH_SLOT \
67+
SCV_ENTRY_FLUSH_FIXUP_SECTION; \
68+
nop; \
69+
nop; \
70+
nop;
71+
6672
/*
6773
* r10 must be free to use, r13 must be paca
6874
*/
6975
#define INTERRUPT_TO_KERNEL \
7076
STF_ENTRY_BARRIER_SLOT; \
7177
ENTRY_FLUSH_SLOT
7278

79+
/*
80+
* r10, ctr must be free to use, r13 must be paca
81+
*/
82+
#define SCV_INTERRUPT_TO_KERNEL \
83+
STF_ENTRY_BARRIER_SLOT; \
84+
SCV_ENTRY_FLUSH_SLOT
85+
7386
/*
7487
* Macros for annotating the expected destination of (h)rfid
7588
*

arch/powerpc/include/asm/feature-fixups.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,14 @@ label##3: \
240240
FTR_ENTRY_OFFSET 957b-958b; \
241241
.popsection;
242242

243+
#define SCV_ENTRY_FLUSH_FIXUP_SECTION \
244+
957: \
245+
.pushsection __scv_entry_flush_fixup,"a"; \
246+
.align 2; \
247+
958: \
248+
FTR_ENTRY_OFFSET 957b-958b; \
249+
.popsection;
250+
243251
#define RFI_FLUSH_FIXUP_SECTION \
244252
951: \
245253
.pushsection __rfi_flush_fixup,"a"; \
@@ -273,10 +281,12 @@ label##3: \
273281

274282
extern long stf_barrier_fallback;
275283
extern long entry_flush_fallback;
284+
extern long scv_entry_flush_fallback;
276285
extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup;
277286
extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup;
278287
extern long __start___uaccess_flush_fixup, __stop___uaccess_flush_fixup;
279288
extern long __start___entry_flush_fixup, __stop___entry_flush_fixup;
289+
extern long __start___scv_entry_flush_fixup, __stop___scv_entry_flush_fixup;
280290
extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
281291
extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup;
282292
extern long __start__btb_flush_fixup, __stop__btb_flush_fixup;

arch/powerpc/kernel/entry_64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ BEGIN_FTR_SECTION
7575
bne .Ltabort_syscall
7676
END_FTR_SECTION_IFSET(CPU_FTR_TM)
7777
#endif
78-
INTERRUPT_TO_KERNEL
78+
SCV_INTERRUPT_TO_KERNEL
7979
mr r10,r1
8080
ld r1,PACAKSAVE(r13)
8181
std r10,0(r1)

arch/powerpc/kernel/exceptions-64s.S

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2993,6 +2993,25 @@ TRAMP_REAL_BEGIN(entry_flush_fallback)
29932993
ld r11,PACA_EXRFI+EX_R11(r13)
29942994
blr
29952995

2996+
/*
2997+
* The SCV entry flush happens with interrupts enabled, so it must disable
2998+
* to prevent EXRFI being clobbered by NMIs (e.g., soft_nmi_common). r10
2999+
* (containing LR) does not need to be preserved here because scv entry
3000+
* puts 0 in the pt_regs, CTR can be clobbered for the same reason.
3001+
*/
3002+
TRAMP_REAL_BEGIN(scv_entry_flush_fallback)
3003+
li r10,0
3004+
mtmsrd r10,1
3005+
lbz r10,PACAIRQHAPPENED(r13)
3006+
ori r10,r10,PACA_IRQ_HARD_DIS
3007+
stb r10,PACAIRQHAPPENED(r13)
3008+
std r11,PACA_EXRFI+EX_R11(r13)
3009+
L1D_DISPLACEMENT_FLUSH
3010+
ld r11,PACA_EXRFI+EX_R11(r13)
3011+
li r10,MSR_RI
3012+
mtmsrd r10,1
3013+
blr
3014+
29963015
TRAMP_REAL_BEGIN(rfi_flush_fallback)
29973016
SET_SCRATCH0(r13);
29983017
GET_PACA(r13);

arch/powerpc/kernel/vmlinux.lds.S

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ SECTIONS
145145
__stop___entry_flush_fixup = .;
146146
}
147147

148+
. = ALIGN(8);
149+
__scv_entry_flush_fixup : AT(ADDR(__scv_entry_flush_fixup) - LOAD_OFFSET) {
150+
__start___scv_entry_flush_fixup = .;
151+
*(__scv_entry_flush_fixup)
152+
__stop___scv_entry_flush_fixup = .;
153+
}
154+
148155
. = ALIGN(8);
149156
__stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - LOAD_OFFSET) {
150157
__start___stf_exit_barrier_fixup = .;

arch/powerpc/lib/feature-fixups.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,6 @@ void do_entry_flush_fixups(enum l1d_flush_type types)
290290
long *start, *end;
291291
int i;
292292

293-
start = PTRRELOC(&__start___entry_flush_fixup);
294-
end = PTRRELOC(&__stop___entry_flush_fixup);
295-
296293
instrs[0] = 0x60000000; /* nop */
297294
instrs[1] = 0x60000000; /* nop */
298295
instrs[2] = 0x60000000; /* nop */
@@ -312,6 +309,8 @@ void do_entry_flush_fixups(enum l1d_flush_type types)
312309
if (types & L1D_FLUSH_MTTRIG)
313310
instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */
314311

312+
start = PTRRELOC(&__start___entry_flush_fixup);
313+
end = PTRRELOC(&__stop___entry_flush_fixup);
315314
for (i = 0; start < end; start++, i++) {
316315
dest = (void *)start + *start;
317316

@@ -328,6 +327,25 @@ void do_entry_flush_fixups(enum l1d_flush_type types)
328327
patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2]));
329328
}
330329

330+
start = PTRRELOC(&__start___scv_entry_flush_fixup);
331+
end = PTRRELOC(&__stop___scv_entry_flush_fixup);
332+
for (; start < end; start++, i++) {
333+
dest = (void *)start + *start;
334+
335+
pr_devel("patching dest %lx\n", (unsigned long)dest);
336+
337+
patch_instruction((struct ppc_inst *)dest, ppc_inst(instrs[0]));
338+
339+
if (types == L1D_FLUSH_FALLBACK)
340+
patch_branch((struct ppc_inst *)(dest + 1), (unsigned long)&scv_entry_flush_fallback,
341+
BRANCH_SET_LINK);
342+
else
343+
patch_instruction((struct ppc_inst *)(dest + 1), ppc_inst(instrs[1]));
344+
345+
patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2]));
346+
}
347+
348+
331349
printk(KERN_DEBUG "entry-flush: patched %d locations (%s flush)\n", i,
332350
(types == L1D_FLUSH_NONE) ? "no" :
333351
(types == L1D_FLUSH_FALLBACK) ? "fallback displacement" :

tools/testing/selftests/powerpc/alignment/alignment_handler.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,6 @@ int test_alignment_handler_integer(void)
443443
LOAD_DFORM_TEST(ldu);
444444
LOAD_XFORM_TEST(ldx);
445445
LOAD_XFORM_TEST(ldux);
446-
LOAD_DFORM_TEST(lmw);
447446
STORE_DFORM_TEST(stb);
448447
STORE_XFORM_TEST(stbx);
449448
STORE_DFORM_TEST(stbu);
@@ -462,7 +461,11 @@ int test_alignment_handler_integer(void)
462461
STORE_XFORM_TEST(stdx);
463462
STORE_DFORM_TEST(stdu);
464463
STORE_XFORM_TEST(stdux);
464+
465+
#ifdef __BIG_ENDIAN__
466+
LOAD_DFORM_TEST(lmw);
465467
STORE_DFORM_TEST(stmw);
468+
#endif
466469

467470
return rc;
468471
}

tools/testing/selftests/powerpc/mm/pkey_exec_prot.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,5 +290,5 @@ static int test(void)
290290

291291
int main(void)
292292
{
293-
test_harness(test, "pkey_exec_prot");
293+
return test_harness(test, "pkey_exec_prot");
294294
}

tools/testing/selftests/powerpc/mm/pkey_siginfo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,5 +329,5 @@ static int test(void)
329329

330330
int main(void)
331331
{
332-
test_harness(test, "pkey_siginfo");
332+
return test_harness(test, "pkey_siginfo");
333333
}

0 commit comments

Comments
 (0)