Skip to content

Commit dd81e1c

Browse files
committed
Merge tag 'powerpc-5.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: - A series of bpf fixes, including an oops fix and some codegen fixes. - Fix a regression in syscall_get_arch() for compat processes. - Fix boot failure on some 32-bit systems with KASAN enabled. - A couple of other build/minor fixes. Thanks to Athira Rajeev, Christophe Leroy, Dmitry V. Levin, Jiri Olsa, Johan Almbladh, Maxime Bizon, Naveen N. Rao, and Nicholas Piggin. * tag 'powerpc-5.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/64s: Mask SRR0 before checking against the masked NIP powerpc/perf: Only define power_pmu_wants_prompt_pmi() for CONFIG_PPC64 powerpc/32s: Fix kasan_init_region() for KASAN powerpc/time: Fix build failure due to do_hard_irq_enable() on PPC32 powerpc/audit: Fix syscall_get_arch() powerpc64/bpf: Limit 'ldbrx' to processors compliant with ISA v2.06 tools/bpf: Rename 'struct event' to avoid naming conflict powerpc/bpf: Update ldimm64 instructions during extra pass powerpc32/bpf: Fix codegen for bpf-to-bpf calls bpf: Guard against accessing NULL pt_regs in bpf_get_task_stack()
2 parents ac5a9bb + aee101d commit dd81e1c

File tree

16 files changed

+131
-87
lines changed

16 files changed

+131
-87
lines changed

arch/powerpc/include/asm/book3s/32/mmu-hash.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ static __always_inline void update_user_segments(u32 val)
223223
update_user_segment(15, val);
224224
}
225225

226+
int __init find_free_bat(void);
227+
unsigned int bat_block_size(unsigned long base, unsigned long top);
226228
#endif /* !__ASSEMBLY__ */
227229

228230
/* We happily ignore the smaller BATs on 601, we don't actually use

arch/powerpc/include/asm/hw_irq.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
473473
return !(regs->msr & MSR_EE);
474474
}
475475

476-
static inline bool should_hard_irq_enable(void)
476+
static __always_inline bool should_hard_irq_enable(void)
477477
{
478478
return false;
479479
}

arch/powerpc/include/asm/ppc-opcode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@
500500
#define PPC_RAW_LDX(r, base, b) (0x7c00002a | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
501501
#define PPC_RAW_LHZ(r, base, i) (0xa0000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
502502
#define PPC_RAW_LHBRX(r, base, b) (0x7c00062c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
503+
#define PPC_RAW_LWBRX(r, base, b) (0x7c00042c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
503504
#define PPC_RAW_LDBRX(r, base, b) (0x7c000428 | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
504505
#define PPC_RAW_STWCX(s, a, b) (0x7c00012d | ___PPC_RS(s) | ___PPC_RA(a) | ___PPC_RB(b))
505506
#define PPC_RAW_CMPWI(a, i) (0x2c000000 | ___PPC_RA(a) | IMM_L(i))

arch/powerpc/include/asm/syscall.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static inline void syscall_get_arguments(struct task_struct *task,
9090
unsigned long val, mask = -1UL;
9191
unsigned int n = 6;
9292

93-
if (is_32bit_task())
93+
if (is_tsk_32bit_task(task))
9494
mask = 0xffffffff;
9595

9696
while (n--) {
@@ -105,7 +105,7 @@ static inline void syscall_get_arguments(struct task_struct *task,
105105

106106
static inline int syscall_get_arch(struct task_struct *task)
107107
{
108-
if (is_32bit_task())
108+
if (is_tsk_32bit_task(task))
109109
return AUDIT_ARCH_PPC;
110110
else if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
111111
return AUDIT_ARCH_PPC64LE;

arch/powerpc/include/asm/thread_info.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,10 @@ static inline bool test_thread_local_flags(unsigned int flags)
168168

169169
#ifdef CONFIG_COMPAT
170170
#define is_32bit_task() (test_thread_flag(TIF_32BIT))
171+
#define is_tsk_32bit_task(tsk) (test_tsk_thread_flag(tsk, TIF_32BIT))
171172
#else
172173
#define is_32bit_task() (IS_ENABLED(CONFIG_PPC32))
174+
#define is_tsk_32bit_task(tsk) (IS_ENABLED(CONFIG_PPC32))
173175
#endif
174176

175177
#if defined(CONFIG_PPC64)

arch/powerpc/kernel/interrupt_64.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ COMPAT_SYS_CALL_TABLE:
3030
.ifc \srr,srr
3131
mfspr r11,SPRN_SRR0
3232
ld r12,_NIP(r1)
33+
clrrdi r11,r11,2
3334
clrrdi r12,r12,2
3435
100: tdne r11,r12
3536
EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
@@ -40,6 +41,7 @@ COMPAT_SYS_CALL_TABLE:
4041
.else
4142
mfspr r11,SPRN_HSRR0
4243
ld r12,_NIP(r1)
44+
clrrdi r11,r11,2
4345
clrrdi r12,r12,2
4446
100: tdne r11,r12
4547
EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)

arch/powerpc/mm/book3s32/mmu.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ unsigned long p_block_mapped(phys_addr_t pa)
7676
return 0;
7777
}
7878

79-
static int __init find_free_bat(void)
79+
int __init find_free_bat(void)
8080
{
8181
int b;
8282
int n = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4;
@@ -100,7 +100,7 @@ static int __init find_free_bat(void)
100100
* - block size has to be a power of two. This is calculated by finding the
101101
* highest bit set to 1.
102102
*/
103-
static unsigned int block_size(unsigned long base, unsigned long top)
103+
unsigned int bat_block_size(unsigned long base, unsigned long top)
104104
{
105105
unsigned int max_size = SZ_256M;
106106
unsigned int base_shift = (ffs(base) - 1) & 31;
@@ -145,7 +145,7 @@ static unsigned long __init __mmu_mapin_ram(unsigned long base, unsigned long to
145145
int idx;
146146

147147
while ((idx = find_free_bat()) != -1 && base != top) {
148-
unsigned int size = block_size(base, top);
148+
unsigned int size = bat_block_size(base, top);
149149

150150
if (size < 128 << 10)
151151
break;
@@ -201,12 +201,12 @@ void mmu_mark_initmem_nx(void)
201201
unsigned long size;
202202

203203
for (i = 0; i < nb - 1 && base < top;) {
204-
size = block_size(base, top);
204+
size = bat_block_size(base, top);
205205
setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
206206
base += size;
207207
}
208208
if (base < top) {
209-
size = block_size(base, top);
209+
size = bat_block_size(base, top);
210210
if ((top - base) > size) {
211211
size <<= 1;
212212
if (strict_kernel_rwx_enabled() && base + size > border)

arch/powerpc/mm/kasan/book3s_32.c

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,48 +10,51 @@ int __init kasan_init_region(void *start, size_t size)
1010
{
1111
unsigned long k_start = (unsigned long)kasan_mem_to_shadow(start);
1212
unsigned long k_end = (unsigned long)kasan_mem_to_shadow(start + size);
13-
unsigned long k_cur = k_start;
14-
int k_size = k_end - k_start;
15-
int k_size_base = 1 << (ffs(k_size) - 1);
13+
unsigned long k_nobat = k_start;
14+
unsigned long k_cur;
15+
phys_addr_t phys;
1616
int ret;
17-
void *block;
1817

19-
block = memblock_alloc(k_size, k_size_base);
20-
21-
if (block && k_size_base >= SZ_128K && k_start == ALIGN(k_start, k_size_base)) {
22-
int shift = ffs(k_size - k_size_base);
23-
int k_size_more = shift ? 1 << (shift - 1) : 0;
24-
25-
setbat(-1, k_start, __pa(block), k_size_base, PAGE_KERNEL);
26-
if (k_size_more >= SZ_128K)
27-
setbat(-1, k_start + k_size_base, __pa(block) + k_size_base,
28-
k_size_more, PAGE_KERNEL);
29-
if (v_block_mapped(k_start))
30-
k_cur = k_start + k_size_base;
31-
if (v_block_mapped(k_start + k_size_base))
32-
k_cur = k_start + k_size_base + k_size_more;
33-
34-
update_bats();
18+
while (k_nobat < k_end) {
19+
unsigned int k_size = bat_block_size(k_nobat, k_end);
20+
int idx = find_free_bat();
21+
22+
if (idx == -1)
23+
break;
24+
if (k_size < SZ_128K)
25+
break;
26+
phys = memblock_phys_alloc_range(k_size, k_size, 0,
27+
MEMBLOCK_ALLOC_ANYWHERE);
28+
if (!phys)
29+
break;
30+
31+
setbat(idx, k_nobat, phys, k_size, PAGE_KERNEL);
32+
k_nobat += k_size;
3533
}
34+
if (k_nobat != k_start)
35+
update_bats();
3636

37-
if (!block)
38-
block = memblock_alloc(k_size, PAGE_SIZE);
39-
if (!block)
40-
return -ENOMEM;
37+
if (k_nobat < k_end) {
38+
phys = memblock_phys_alloc_range(k_end - k_nobat, PAGE_SIZE, 0,
39+
MEMBLOCK_ALLOC_ANYWHERE);
40+
if (!phys)
41+
return -ENOMEM;
42+
}
4143

4244
ret = kasan_init_shadow_page_tables(k_start, k_end);
4345
if (ret)
4446
return ret;
4547

46-
kasan_update_early_region(k_start, k_cur, __pte(0));
48+
kasan_update_early_region(k_start, k_nobat, __pte(0));
4749

48-
for (; k_cur < k_end; k_cur += PAGE_SIZE) {
50+
for (k_cur = k_nobat; k_cur < k_end; k_cur += PAGE_SIZE) {
4951
pmd_t *pmd = pmd_off_k(k_cur);
50-
void *va = block + k_cur - k_start;
51-
pte_t pte = pfn_pte(PHYS_PFN(__pa(va)), PAGE_KERNEL);
52+
pte_t pte = pfn_pte(PHYS_PFN(phys + k_cur - k_nobat), PAGE_KERNEL);
5253

5354
__set_pte_at(&init_mm, k_cur, pte_offset_kernel(pmd, k_cur), pte, 0);
5455
}
5556
flush_tlb_kernel_range(k_start, k_end);
57+
memset(kasan_mem_to_shadow(start), 0, k_end - k_start);
58+
5659
return 0;
5760
}

arch/powerpc/net/bpf_jit_comp.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ static void bpf_jit_fill_ill_insns(void *area, unsigned int size)
2323
memset32(area, BREAKPOINT_INSTRUCTION, size / 4);
2424
}
2525

26-
/* Fix the branch target addresses for subprog calls */
27-
static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image,
28-
struct codegen_context *ctx, u32 *addrs)
26+
/* Fix updated addresses (for subprog calls, ldimm64, et al) during extra pass */
27+
static int bpf_jit_fixup_addresses(struct bpf_prog *fp, u32 *image,
28+
struct codegen_context *ctx, u32 *addrs)
2929
{
3030
const struct bpf_insn *insn = fp->insnsi;
3131
bool func_addr_fixed;
3232
u64 func_addr;
3333
u32 tmp_idx;
34-
int i, ret;
34+
int i, j, ret;
3535

3636
for (i = 0; i < fp->len; i++) {
3737
/*
@@ -66,6 +66,23 @@ static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image,
6666
* of the JITed sequence remains unchanged.
6767
*/
6868
ctx->idx = tmp_idx;
69+
} else if (insn[i].code == (BPF_LD | BPF_IMM | BPF_DW)) {
70+
tmp_idx = ctx->idx;
71+
ctx->idx = addrs[i] / 4;
72+
#ifdef CONFIG_PPC32
73+
PPC_LI32(ctx->b2p[insn[i].dst_reg] - 1, (u32)insn[i + 1].imm);
74+
PPC_LI32(ctx->b2p[insn[i].dst_reg], (u32)insn[i].imm);
75+
for (j = ctx->idx - addrs[i] / 4; j < 4; j++)
76+
EMIT(PPC_RAW_NOP());
77+
#else
78+
func_addr = ((u64)(u32)insn[i].imm) | (((u64)(u32)insn[i + 1].imm) << 32);
79+
PPC_LI64(b2p[insn[i].dst_reg], func_addr);
80+
/* overwrite rest with nops */
81+
for (j = ctx->idx - addrs[i] / 4; j < 5; j++)
82+
EMIT(PPC_RAW_NOP());
83+
#endif
84+
ctx->idx = tmp_idx;
85+
i++;
6986
}
7087
}
7188

@@ -200,13 +217,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
200217
/*
201218
* Do not touch the prologue and epilogue as they will remain
202219
* unchanged. Only fix the branch target address for subprog
203-
* calls in the body.
220+
* calls in the body, and ldimm64 instructions.
204221
*
205222
* This does not change the offsets and lengths of the subprog
206223
* call instruction sequences and hence, the size of the JITed
207224
* image as well.
208225
*/
209-
bpf_jit_fixup_subprog_calls(fp, code_base, &cgctx, addrs);
226+
bpf_jit_fixup_addresses(fp, code_base, &cgctx, addrs);
210227

211228
/* There is no need to perform the usual passes. */
212229
goto skip_codegen_passes;

arch/powerpc/net/bpf_jit_comp32.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
191191

192192
if (image && rel < 0x2000000 && rel >= -0x2000000) {
193193
PPC_BL_ABS(func);
194+
EMIT(PPC_RAW_NOP());
195+
EMIT(PPC_RAW_NOP());
196+
EMIT(PPC_RAW_NOP());
194197
} else {
195198
/* Load function address into r0 */
196199
EMIT(PPC_RAW_LIS(_R0, IMM_H(func)));
@@ -290,6 +293,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
290293
bool func_addr_fixed;
291294
u64 func_addr;
292295
u32 true_cond;
296+
u32 tmp_idx;
297+
int j;
293298

294299
/*
295300
* addrs[] maps a BPF bytecode address into a real offset from
@@ -905,8 +910,12 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
905910
* 16 byte instruction that uses two 'struct bpf_insn'
906911
*/
907912
case BPF_LD | BPF_IMM | BPF_DW: /* dst = (u64) imm */
913+
tmp_idx = ctx->idx;
908914
PPC_LI32(dst_reg_h, (u32)insn[i + 1].imm);
909915
PPC_LI32(dst_reg, (u32)insn[i].imm);
916+
/* padding to allow full 4 instructions for later patching */
917+
for (j = ctx->idx - tmp_idx; j < 4; j++)
918+
EMIT(PPC_RAW_NOP());
910919
/* Adjust for two bpf instructions */
911920
addrs[++i] = ctx->idx * 4;
912921
break;

arch/powerpc/net/bpf_jit_comp64.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
319319
u64 imm64;
320320
u32 true_cond;
321321
u32 tmp_idx;
322+
int j;
322323

323324
/*
324325
* addrs[] maps a BPF bytecode address into a real offset from
@@ -633,17 +634,21 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
633634
EMIT(PPC_RAW_MR(dst_reg, b2p[TMP_REG_1]));
634635
break;
635636
case 64:
636-
/*
637-
* Way easier and faster(?) to store the value
638-
* into stack and then use ldbrx
639-
*
640-
* ctx->seen will be reliable in pass2, but
641-
* the instructions generated will remain the
642-
* same across all passes
643-
*/
637+
/* Store the value to stack and then use byte-reverse loads */
644638
PPC_BPF_STL(dst_reg, 1, bpf_jit_stack_local(ctx));
645639
EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], 1, bpf_jit_stack_local(ctx)));
646-
EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1]));
640+
if (cpu_has_feature(CPU_FTR_ARCH_206)) {
641+
EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1]));
642+
} else {
643+
EMIT(PPC_RAW_LWBRX(dst_reg, 0, b2p[TMP_REG_1]));
644+
if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
645+
EMIT(PPC_RAW_SLDI(dst_reg, dst_reg, 32));
646+
EMIT(PPC_RAW_LI(b2p[TMP_REG_2], 4));
647+
EMIT(PPC_RAW_LWBRX(b2p[TMP_REG_2], b2p[TMP_REG_2], b2p[TMP_REG_1]));
648+
if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
649+
EMIT(PPC_RAW_SLDI(b2p[TMP_REG_2], b2p[TMP_REG_2], 32));
650+
EMIT(PPC_RAW_OR(dst_reg, dst_reg, b2p[TMP_REG_2]));
651+
}
647652
break;
648653
}
649654
break;
@@ -848,9 +853,13 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
848853
case BPF_LD | BPF_IMM | BPF_DW: /* dst = (u64) imm */
849854
imm64 = ((u64)(u32) insn[i].imm) |
850855
(((u64)(u32) insn[i+1].imm) << 32);
856+
tmp_idx = ctx->idx;
857+
PPC_LI64(dst_reg, imm64);
858+
/* padding to allow full 5 instructions for later patching */
859+
for (j = ctx->idx - tmp_idx; j < 5; j++)
860+
EMIT(PPC_RAW_NOP());
851861
/* Adjust for two bpf instructions */
852862
addrs[++i] = ctx->idx * 4;
853-
PPC_LI64(dst_reg, imm64);
854863
break;
855864

856865
/*

0 commit comments

Comments
 (0)