[PATCH 3/3] powerpc: Implement emulation of string loads and stores
The size field of the op.type word is now the total number of bytes to be loaded or stored. Signed-off-by: Paul Mackerras --- arch/powerpc/lib/sstep.c | 59 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 209a506..54651fc 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -1433,11 +1433,24 @@ int __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs, break; #endif + case 533: /* lswx */ + op->type = MKOP(LOAD_MULTI, 0, regs->xer & 0x7f); + break; case 534: /* lwbrx */ op->type = MKOP(LOAD, BYTEREV, 4); break; + case 597: /* lswi */ + if (rb == 0) + rb = 32;/* # bytes to load */ + op->type = MKOP(LOAD_MULTI, 0, rb); + op->ea = 0; + if (ra) + op->ea = truncate_if_32bit(regs->msr, + regs->gpr[ra]); + break; + #ifdef CONFIG_PPC_FPU case 535: /* lfsx */ case 567: /* lfsux */ @@ -1475,11 +1488,25 @@ int __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs, break; #endif + case 661: /* stswx */ + op->type = MKOP(STORE_MULTI, 0, regs->xer & 0x7f); + break; + case 662: /* stwbrx */ op->type = MKOP(STORE, BYTEREV, 4); op->val = byterev_4(regs->gpr[rd]); break; + case 725: + if (rb == 0) + rb = 32;/* # bytes to store */ + op->type = MKOP(STORE_MULTI, 0, rb); + op->ea = 0; + if (ra) + op->ea = truncate_if_32bit(regs->msr, + regs->gpr[ra]); + break; + case 790: /* lhbrx */ op->type = MKOP(LOAD, BYTEREV, 2); break; @@ -1553,15 +1580,14 @@ int __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs, break; case 46:/* lmw */ - ra = (instr >> 16) & 0x1f; if (ra >= rd) break; /* invalid form, ra in range to load */ - op->type = MKOP(LOAD_MULTI, 0, 4); + op->type = MKOP(LOAD_MULTI, 0, 4 * (32 - rd)); op->ea = dform_ea(instr, regs); break; case 47:/* stmw */ - op->type = MKOP(STORE_MULTI, 0, 4); + op->type = MKOP(STORE_MULTI, 0, 4 * (32 - rd)); op->ea = dform_ea(instr, regs); break; @@ -1744,7 +1770,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) int r, err, size; unsigned long val; unsigned int cr; - int rd; + int i, rd, nb; r = analyse_instr(&op, regs, instr); if (r != 0) @@ -1866,12 +1892,18 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) if (regs->msr & MSR_LE) return 0; rd = op.reg; - do { - err = read_mem(®s->gpr[rd], op.ea, 4, regs); + for (i = 0; i < size; i += 4) { + nb = size - i; + if (nb > 4) + nb = 4; + err = read_mem(®s->gpr[rd], op.ea, nb, regs); if (err) return 0; + if (nb < 4) /* left-justify last bytes */ + regs->gpr[rd] <<= 32 - 8 * nb; op.ea += 4; - } while (++rd < 32); + ++rd; + } goto instr_done; case STORE: @@ -1914,12 +1946,19 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) if (regs->msr & MSR_LE) return 0; rd = op.reg; - do { - err = write_mem(regs->gpr[rd], op.ea, 4, regs); + for (i = 0; i < size; i += 4) { + val = regs->gpr[rd]; + nb = size - i; + if (nb > 4) + nb = 4; + else + val >>= 32 - 8 * nb; + err = writ
[PATCH 2/3] powerpc: Emulate icbi, mcrf and conditional-trap instructions
This extends the instruction emulation done by analyse_instr() and emulate_step() to handle a few more instructions that are found in the kernel. Signed-off-by: Paul Mackerras --- arch/powerpc/include/asm/sstep.h | 1 + arch/powerpc/lib/sstep.c | 60 2 files changed, 61 insertions(+) diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h index 1a693b1..d3a42cc 100644 --- a/arch/powerpc/include/asm/sstep.h +++ b/arch/powerpc/include/asm/sstep.h @@ -66,6 +66,7 @@ enum instruction_type { #define DCBF 0x100 #define DCBTST 0x200 #define DCBT 0x300 +#define ICBI 0x400 /* Size field in type word */ #define SIZE(n)((n) << 8) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 3726a03..209a506 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -600,6 +600,23 @@ static void __kprobes do_cmp_unsigned(struct pt_regs *regs, unsigned long v1, regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift); } +static int __kprobes trap_compare(long v1, long v2) +{ + int ret = 0; + + if (v1 < v2) + ret |= 0x10; + else if (v1 > v2) + ret |= 0x08; + else + ret |= 0x04; + if ((unsigned long)v1 < (unsigned long)v2) + ret |= 0x02; + else if ((unsigned long)v1 > (unsigned long)v2) + ret |= 0x01; + return ret; +} + /* * Elements of 32-bit rotate and mask instructions. */ @@ -669,6 +686,13 @@ int __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs, return 1; case 19: switch ((instr >> 1) & 0x3ff) { + case 0: /* mcrf */ + rd = (instr >> 21) & 0x1c; + ra = (instr >> 16) & 0x1c; + val = (regs->ccr >> ra) & 0xf; + regs->ccr = (regs->ccr & ~(0xfUL << rd)) | (val << rd); + goto instr_done; + case 16:/* bclr */ case 528: /* bcctr */ op->type = BRANCH; @@ -745,6 +769,17 @@ int __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs, rb = (instr >> 11) & 0x1f; switch (opcode) { +#ifdef __powerpc64__ + case 2: /* tdi */ + if (rd & trap_compare(regs->gpr[ra], (short) instr)) + goto trap; + goto instr_done; +#endif + case 3: /* twi */ + if (rd & trap_compare((int)regs->gpr[ra], (short) instr)) + goto trap; + goto instr_done; + case 7: /* mulli */ regs->gpr[rd] = regs->gpr[ra] * (short) instr; goto instr_done; @@ -893,6 +928,18 @@ int __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs, case 31: switch ((instr >> 1) & 0x3ff) { + case 4: /* tw */ + if (rd == 0x1f || + (rd & trap_compare((int)regs->gpr[ra], + (int)regs->gpr[rb]))) + goto trap; + goto instr_done; +#ifdef __powerpc64__ + case 68:/* td */ + if (rd & trap_compare(regs->gpr[ra], regs->gpr[rb])) + goto trap; + goto instr_done; +#endif case 83:/* mfmsr */ if (regs->msr & MSR_PR) goto priv; @@ -1269,6 +1316,11 @@ int __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs, op->ea = xform_ea(instr, regs); op->reg = rd; return 0; + + case 982: /* icbi */ + op->type = MKOP(CACHEOP, ICBI, 0); + op->ea = xform_ea(instr, regs); + return 0; } break; } @@ -1597,6 +1649,11 @@ int __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs, op->val = SRR1_PROGPRIV; return 0; + trap: + op->type = INTERRUPT | 0x700; + op->val = SRR1_PROGTRAP; + return 0; + #ifdef CONFIG_PPC_FPU fpunavail: op->type = INTERRUPT | 0x800; @@ -1714,6 +1771,9 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) if (op.reg == 0) prefetch((void *) op.ea); break; + case ICBI: + __cacheop_user_asmx(op.ea, err, "icbi"); + break; } if (err) return 0; -- 2.1.0.rc1 _
[PATCH 1/3] powerpc: Split out instruction analysis part of emulate_step()
This splits out the instruction analysis part of emulate_step() into a separate analyse_instr() function, which decodes the instruction, but doesn't execute any load or store instructions. It does execute integer instructions and branches which can be executed purely by updating register values in the pt_regs struct. For other instructions, it returns the instruction type and other details in a new instruction_op struct. emulate_step() then uses that information to execute loads, stores, cache operations, mfmsr, mtmsr[d], and (on 64-bit) sc instructions. The reason for doing this is so that the KVM code can use it instead of having its own separate instruction emulation code. Possibly the alignment interrupt handler could also use this. Signed-off-by: Paul Mackerras --- arch/powerpc/include/asm/sstep.h | 61 +++ arch/powerpc/lib/sstep.c | 897 +++ 2 files changed, 598 insertions(+), 360 deletions(-) diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h index f593b0f..1a693b1 100644 --- a/arch/powerpc/include/asm/sstep.h +++ b/arch/powerpc/include/asm/sstep.h @@ -25,3 +25,64 @@ struct pt_regs; /* Emulate instructions that cause a transfer of control. */ extern int emulate_step(struct pt_regs *regs, unsigned int instr); + +enum instruction_type { + COMPUTE,/* arith/logical/CR op, etc. */ + LOAD, + LOAD_MULTI, + LOAD_FP, + LOAD_VMX, + LOAD_VSX, + STORE, + STORE_MULTI, + STORE_FP, + STORE_VMX, + STORE_VSX, + LARX, + STCX, + BRANCH, + MFSPR, + MTSPR, + CACHEOP, + BARRIER, + SYSCALL, + MFMSR, + MTMSR, + RFI, + INTERRUPT, + UNKNOWN +}; + +#define INSTR_TYPE_MASK0x1f + +/* Load/store flags, ORed in with type */ +#define SIGNEXT0x20 +#define UPDATE 0x40/* matches bit in opcode 31 instructions */ +#define BYTEREV0x80 + +/* Cacheop values, ORed in with type */ +#define CACHEOP_MASK 0x700 +#define DCBST 0 +#define DCBF 0x100 +#define DCBTST 0x200 +#define DCBT 0x300 + +/* Size field in type word */ +#define SIZE(n)((n) << 8) +#define GETSIZE(w) ((w) >> 8) + +#define MKOP(t, f, s) ((t) | (f) | SIZE(s)) + +struct instruction_op { + int type; + int reg; + unsigned long val; + /* For LOAD/STORE/LARX/STCX */ + unsigned long ea; + int update_reg; + /* For MFSPR */ + int spr; +}; + +extern int analyse_instr(struct instruction_op *op, struct pt_regs *regs, +unsigned int instr); diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 5c09f36..3726a03 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -98,13 +98,8 @@ static unsigned long __kprobes dform_ea(unsigned int instr, struct pt_regs *regs ra = (instr >> 16) & 0x1f; ea = (signed short) instr; /* sign-extend */ - if (ra) { + if (ra) ea += regs->gpr[ra]; - if (instr & 0x0400) { /* update forms */ - if ((instr>>26) != 47) /* stmw is not an update form */ - regs->gpr[ra] = ea; - } - } return truncate_if_32bit(regs->msr, ea); } @@ -120,11 +115,8 @@ static unsigned long __kprobes dsform_ea(unsigned int instr, struct pt_regs *reg ra = (instr >> 16) & 0x1f; ea = (signed short) (instr & ~3); /* sign-extend */ - if (ra) { + if (ra) ea += regs->gpr[ra]; - if ((instr & 3) == 1) /* update forms */ - regs->gpr[ra] = ea; - } return truncate_if_32bit(regs->msr, ea); } @@ -133,8 +125,8 @@ static unsigned long __kprobes dsform_ea(unsigned int instr, struct pt_regs *reg /* * Calculate effective address for an X-form instruction */ -static unsigned long __kprobes xform_ea(unsigned int instr, struct pt_regs *regs, -int do_update) +static unsigned long __kprobes xform_ea(unsigned int instr, + struct pt_regs *regs) { int ra, rb; unsigned long ea; @@ -142,11 +134,8 @@ static unsigned long __kprobes xform_ea(unsigned int instr, struct pt_regs *regs ra = (instr >> 16) & 0x1f; rb = (instr >> 11) & 0x1f; ea = regs->gpr[rb]; - if (ra) { + if (ra) ea += regs->gpr[ra]; - if (do_update) /* update forms */ - regs->gpr[ra] = ea; - } return truncate_if_32bit(regs->msr, ea); } @@ -627,26 +616,27 @@ static void __kprobes do_cmp_unsigned(struct pt_regs *regs, unsigned long v1, #define ROTATE(x, n) ((n) ? (((x) << (n)) | ((x) >> (8 * sizeof(long
[PATCH v2 0/3] powerpc: Make sstep.c more generally useful
This patch series modifies the code in arch/powerpc/lib/sstep.c so that it can be used by KVM in its instruction emulation, thereby reducing the number of different PowerPC instruction emulators that we have in the kernel. It does this by splitting the existing emulate_step() function into two: an analyse_instr() function that decodes an instruction and executes the easy ones, and an emulate_step() function that uses analyse_instr() and then executes the loads and stores. The subsequent two patches add emulation of some extra instructions. v2: add #ifdef CONFIG_ALTIVEC around do_vec_{load,store} calls. The patch series is against v3.17-rc1. arch/powerpc/include/asm/sstep.h | 62 +++ arch/powerpc/lib/sstep.c | 996 +-- 2 files changed, 698 insertions(+), 360 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/powernv: Don't call generic code on offline cpus
On PowerNV platforms, when a CPU is offline, we put it into nap mode. It's possible that the CPU wakes up from nap mode while it is still offline due to a stray IPI. A misdirected device interrupt could also potentially cause it to wake up. In that circumstance, we need to clear the interrupt so that the CPU can go back to nap mode. In the past the clearing of the interrupt was accomplished by briefly enabling interrupts and allowing the normal interrupt handling code (do_IRQ() etc.) to handle the interrupt. This has the problem that this code calls irq_enter() and irq_exit(), which call functions such as account_system_vtime() which use RCU internally. Use of RCU is not permitted on offline CPUs and will trigger errors if RCU checking is enabled. To avoid calling into any generic code which might use RCU, we adopt a different method of clearing interrupts on offline CPUs. Since we are on the PowerNV platform, we know that the system interrupt controller is a XICS being driven directly (i.e. not via hcalls) by the kernel. Hence this adds a new icp_native_flush_interrupt() function to the native-mode XICS driver and arranges to call that when an offline CPU is woken from nap. This new function reads the interrupt from the XICS. If it is an IPI, it clears the IPI; if it is a device interrupt, it prints a warning and disables the source. Then it does the end-of-interrupt processing for the interrupt. The other thing that briefly enabling interrupts did was to check and clear the irq_happened flag in this CPU's PACA. Therefore, after flushing the interrupt from the XICS, we also clear all bits except the PACA_IRQ_HARD_DIS (interrupts are hard disabled) bit from the irq_happened flag. The PACA_IRQ_HARD_DIS flag is set by power7_nap() and is left set to indicate that interrupts are hard disabled. This means we then have to ignore that flag in power7_nap(), which is reasonable since it doesn't indicate that any interrupt event needs servicing. Signed-off-by: Paul Mackerras --- arch/powerpc/include/asm/xics.h | 1 + arch/powerpc/kernel/idle_power7.S | 2 +- arch/powerpc/platforms/powernv/smp.c | 6 +++--- arch/powerpc/sysdev/xics/icp-native.c | 25 + 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index 282d43a..0d050ea 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h @@ -29,6 +29,7 @@ /* Native ICP */ #ifdef CONFIG_PPC_ICP_NATIVE extern int icp_native_init(void); +extern void icp_native_flush_interrupt(void); #else static inline int icp_native_init(void) { return -ENODEV; } #endif diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S index be05841..c0754bb 100644 --- a/arch/powerpc/kernel/idle_power7.S +++ b/arch/powerpc/kernel/idle_power7.S @@ -73,7 +73,7 @@ _GLOBAL(power7_powersave_common) /* Check if something happened while soft-disabled */ lbz r0,PACAIRQHAPPENED(r13) - cmpwi cr0,r0,0 + andi. r0,r0,~PACA_IRQ_HARD_DIS@l beq 1f cmpwi cr0,r4,0 beq 1f diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 5fcfcf4..9b71a5c 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -168,9 +168,9 @@ static void pnv_smp_cpu_kill_self(void) power7_nap(1); ppc64_runlatch_on(); - /* Reenable IRQs briefly to clear the IPI that woke us */ - local_irq_enable(); - local_irq_disable(); + /* Clear the IPI that woke us up */ + icp_native_flush_interrupt(); + local_paca->irq_happened &= PACA_IRQ_HARD_DIS; mb(); if (cpu_core_split_required()) diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c index de8d948..2fc4cf1 100644 --- a/arch/powerpc/sysdev/xics/icp-native.c +++ b/arch/powerpc/sysdev/xics/icp-native.c @@ -155,6 +155,31 @@ static void icp_native_cause_ipi(int cpu, unsigned long data) icp_native_set_qirr(cpu, IPI_PRIORITY); } +/* + * Called when an interrupt is received on an off-line CPU to + * clear the interrupt, so that the CPU can go back to nap mode. + */ +void icp_native_flush_interrupt(void) +{ + unsigned int xirr = icp_native_get_xirr(); + unsigned int vec = xirr & 0x00ff; + + if (vec == XICS_IRQ_SPURIOUS) + return; + if (vec == XICS_IPI) { + /* Clear pending IPI */ + int cpu = smp_processor_id(); + kvmppc_set_host_ipi(cpu, 0); + icp_native_set_qirr(cpu, 0xff); + } else { + pr_err("XICS: hw interrupt 0x%x to offline cpu, disabling\n", + vec); + xics_mask_unknown_vec(vec); + } + /* EOI the inter
[PATCH] powerpc: Wire up three sys calls
This patch wires up three new syscalls for powerpc. The three new syscalls are seccomp, getrandom and memfd_create. Signed-off-by: Pranith Kumar Reviewed-by: David Herrmann --- arch/powerpc/include/asm/systbl.h | 3 +++ arch/powerpc/include/asm/unistd.h | 2 +- arch/powerpc/include/uapi/asm/unistd.h | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 542bc0f..7d8a600 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -362,3 +362,6 @@ SYSCALL(ni_syscall) /* sys_kcmp */ SYSCALL_SPU(sched_setattr) SYSCALL_SPU(sched_getattr) SYSCALL_SPU(renameat2) +SYSCALL_SPU(seccomp) +SYSCALL_SPU(getrandom) +SYSCALL_SPU(memfd_create) diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 5ce5552..4e9af3f 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@ -12,7 +12,7 @@ #include -#define __NR_syscalls 358 +#define __NR_syscalls 361 #define __NR__exit __NR_exit #define NR_syscalls__NR_syscalls diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h index 2d526f7..0688fc0 100644 --- a/arch/powerpc/include/uapi/asm/unistd.h +++ b/arch/powerpc/include/uapi/asm/unistd.h @@ -380,5 +380,8 @@ #define __NR_sched_setattr 355 #define __NR_sched_getattr 356 #define __NR_renameat2 357 +#define __NR_seccomp 358 +#define __NR_getrandom 359 +#define __NR_memfd_create 360 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ -- 2.1.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH] powerpc: Wire up three syscalls
Hi On Mon, Sep 1, 2014 at 7:16 PM, Pranith Kumar wrote: > On Mon, Sep 1, 2014 at 11:31 AM, David Herrmann wrote: > >> >> Btw., the original patch (wire up syscalls) can be applied unchanged. >> > > Great! Can I use that as an Ack-by? I will send in the patch with > updated changelog. Sure, go ahead! This syscall patch is: Reviewed-by: David Herrmann Thanks David ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH] powerpc: Wire up three syscalls
On Mon, Sep 1, 2014 at 11:31 AM, David Herrmann wrote: > > Btw., the original patch (wire up syscalls) can be applied unchanged. > Great! Can I use that as an Ack-by? I will send in the patch with updated changelog. -- Pranith ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH] powerpc: Wire up three syscalls
Hi On Mon, Sep 1, 2014 at 5:21 PM, Pranith Kumar wrote: > Hi David, > > On Mon, Sep 1, 2014 at 7:33 AM, David Herrmann wrote: >> >> Nice catch. We changed 'flags' from u64 to "unsigned int" in the last >> revision of the series. Patch looks good, but I'd prefer using >> "unsigned int" as type, instead of __u32. Just to be consistent with >> the syscall interface. The return type of F_GET_SEALS is actually >> "int" and the MSB is reserved for signed error codes, so you can >> savely use "int r = fcntl(fd, F_GET_SEALS, 0)" in >> mfd_assert_get_seals(). >> > > OK. Should I send a new patch with these changes or do you have one > line up already? I'd appreciate if you can resend it. Btw., the original patch (wire up syscalls) can be applied unchanged. Thanks David ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH] powerpc: Wire up three syscalls
Hi David, On Mon, Sep 1, 2014 at 7:33 AM, David Herrmann wrote: > > Nice catch. We changed 'flags' from u64 to "unsigned int" in the last > revision of the series. Patch looks good, but I'd prefer using > "unsigned int" as type, instead of __u32. Just to be consistent with > the syscall interface. The return type of F_GET_SEALS is actually > "int" and the MSB is reserved for signed error codes, so you can > savely use "int r = fcntl(fd, F_GET_SEALS, 0)" in > mfd_assert_get_seals(). > OK. Should I send a new patch with these changes or do you have one line up already? -- Pranith ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH] powerpc: Wire up three syscalls
Hi On Sun, Aug 31, 2014 at 7:51 PM, Pranith Kumar wrote: > > On 08/31/2014 10:34 AM, David Herrmann wrote: >> The only arch-dependent code for memfd_test.c is the syscall invocation: >> memfd_create(const char *name, unsigned int flags); >> via glibc as: >> syscall(__NR_memfd_create, name, flags); >> >> Can you debug your test-run (maybe via simple printk() in mm/shmem.c >> memfd_create()) and see what's going wrong there? >> > Hi David, > > I figured out the problem. I am on a 32-bit system and using u64 for flags in > fcntl() is the cause of the problem. Will you accept a patch making the test > work on 32-bit systems as below? > > Thanks! > -- > Pranith > > From: Pranith Kumar > Date: Sun, 31 Aug 2014 13:38:07 -0400 > Subject: [PATCH] memfd_test: Make it work on 32-bit systems > > This test currently fails on 32-bit systems since we use u64 type to pass the > flags to fcntl. > > This commit changes this to use u32 type for flags to fcntl making it work on > 32-bit systems. Nice catch. We changed 'flags' from u64 to "unsigned int" in the last revision of the series. Patch looks good, but I'd prefer using "unsigned int" as type, instead of __u32. Just to be consistent with the syscall interface. The return type of F_GET_SEALS is actually "int" and the MSB is reserved for signed error codes, so you can savely use "int r = fcntl(fd, F_GET_SEALS, 0)" in mfd_assert_get_seals(). Thanks David > Signed-off-by: Pranith Kumar > --- > tools/testing/selftests/memfd/memfd_test.c | 32 > +++--- > 1 file changed, 16 insertions(+), 16 deletions(-) > > diff --git a/tools/testing/selftests/memfd/memfd_test.c > b/tools/testing/selftests/memfd/memfd_test.c > index 3634c90..77e56ff 100644 > --- a/tools/testing/selftests/memfd/memfd_test.c > +++ b/tools/testing/selftests/memfd/memfd_test.c > @@ -59,9 +59,9 @@ static void mfd_fail_new(const char *name, unsigned int > flags) > } > } > > -static __u64 mfd_assert_get_seals(int fd) > +static __u32 mfd_assert_get_seals(int fd) > { > -long r; > +int r; > > r = fcntl(fd, F_GET_SEALS); > if (r < 0) { > @@ -72,36 +72,36 @@ static __u64 mfd_assert_get_seals(int fd) > return r; > } > > -static void mfd_assert_has_seals(int fd, __u64 seals) > +static void mfd_assert_has_seals(int fd, __u32 seals) > { > -__u64 s; > +__u32 s; > > s = mfd_assert_get_seals(fd); > if (s != seals) { > -printf("%llu != %llu = GET_SEALS(%d)\n", > - (unsigned long long)seals, (unsigned long long)s, fd); > +printf("%lu != %lu = GET_SEALS(%d)\n", > + (unsigned long)seals, (unsigned long)s, fd); > abort(); > } > } > > -static void mfd_assert_add_seals(int fd, __u64 seals) > +static void mfd_assert_add_seals(int fd, __u32 seals) > { > -long r; > -__u64 s; > +int r; > +__u32 s; > > s = mfd_assert_get_seals(fd); > r = fcntl(fd, F_ADD_SEALS, seals); > if (r < 0) { > -printf("ADD_SEALS(%d, %llu -> %llu) failed: %m\n", > - fd, (unsigned long long)s, (unsigned long long)seals); > +printf("ADD_SEALS(%d, %lu -> %lu) failed: %m\n", > + fd, (unsigned long)s, (unsigned long)seals); > abort(); > } > } > > -static void mfd_fail_add_seals(int fd, __u64 seals) > +static void mfd_fail_add_seals(int fd, __u32 seals) > { > -long r; > -__u64 s; > +int r; > +__u32 s; > > r = fcntl(fd, F_GET_SEALS); > if (r < 0) > @@ -111,8 +111,8 @@ static void mfd_fail_add_seals(int fd, __u64 seals) > > r = fcntl(fd, F_ADD_SEALS, seals); > if (r >= 0) { > -printf("ADD_SEALS(%d, %llu -> %llu) didn't fail as expected\n", > - fd, (unsigned long long)s, (unsigned long long)seals); > +printf("ADD_SEALS(%d, %lu -> %lu) didn't fail as expected\n", > + fd, (unsigned long)s, (unsigned long)seals); > abort(); > } > } > -- > 2.1.0 > ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCH v2] cpufreq: powernv: Set the cpus to nominal frequency during reboot/kexec
From: Shilpa Bhat > Hi Viresh, > On Fri, 2014-08-29 at 05:33 +0530, Viresh Kumar wrote: > > On 28 August 2014 19:36, Shilpasri G Bhat > > wrote: > > > > > > Changes v1->v2: > > > Invoke .target() driver callback to set the cpus to nominal frequency > > > in reboot notifier, instead of calling cpufreq_suspend() as suggested > > > by Viresh Kumar. > > > Modified the commit message. > > > > This changelog will get commited, is this what you want? > > > > + if (unlikely(rebooting) && new_index != get_nominal_index()) > > > + return -EBUSY; > > > > Have you placed the unlikely only around 'rebooting' intentionally or > > should it cover whole if statement? > > > > Yes unlikely() should cover the whole if statement... Actually it probably shouldn't. You need to look at the generated code with each different set of 'unlikely()' to see how gcc processes them. In this case, if 'rebooting' is false you want to 'fall through' on a statically predicted 'not taken' branch. You don't ever care about the second clause. With an 'unlikely' covering the entire statement gcc could easily add a forwards conditional branch (that will be mis-predicted) for the 'rebooting' test. (Yes, I spent a lot of time getting gcc to generate branches that were correctly statically predicted for some code where every cycle mattered.) David ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH] powerpc: Wire up three syscalls
Hi On Sun, Aug 31, 2014 at 2:52 PM, Pranith Kumar wrote: > Hi Geert, > > On Sun, Aug 31, 2014 at 4:53 AM, Geert Uytterhoeven > wrote: >> Hi Pranith, >> >> On Sat, Aug 30, 2014 at 5:36 AM, Pranith Kumar wrote: >>> I see that the three syscalls seccomp, getrandom and memfd_create are not >>> wired >>> because of which we get a warning while compilation. >>> >>> So I wired them up in this patch. What else needs to be done? I tried the >>> memfd_test after compiling this kernel, but it is failing. What am I >>> missing for >>> this to work? Any advice is really appreciated! :) >> >> Did it fail due to the (silly) "ifeq ($(ARCH),X86)" checks in >> tools/testing/selftests/memfd/Makefile? >> > > I removed that check and compiled memfd_test.c by hand. This is the > following error which I get when I run the test: > > $ ./memfd_test > memfd: CREATE > memfd: BASIC > 10 != 0 = GET_SEALS(3) > Aborted > > This is basically when checking the seals which we already added. It > should return 10 (F_SEAL_SHRINK | F_SEAL_WRITE), instead it is returning 0. > > What else needs to be done for this to properly work? I see that for > m68k, you just wired it up like in this patch. Did it work after that? The only arch-dependent code for memfd_test.c is the syscall invocation: memfd_create(const char *name, unsigned int flags); via glibc as: syscall(__NR_memfd_create, name, flags); Can you debug your test-run (maybe via simple printk() in mm/shmem.c memfd_create()) and see what's going wrong there? Thanks David ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] Freescale Frame Manager Device Tree binding document
From: Igal Liberman The Frame Manager (FMan) combines the Ethernet network interfaces with packet distribution logic to provide intelligent distribution and queuing decisions for incoming traffic at line rate. This binding document describes Freescale's Frame Manager hardware attributes that are used by the Frame Manager driver for its basic initialization and configuration. Signed-off-by: Igal Liberman --- .../devicetree/bindings/powerpc/fsl/fman.txt | 462 1 file changed, 462 insertions(+) create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/fman.txt diff --git a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt new file mode 100644 index 000..ce0793f --- /dev/null +++ b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt @@ -0,0 +1,462 @@ += +Freescale Frame Manager Device Bindings + +CONTENTS + - FMan Node + - FMan Port Node + - FMan MURAM Node + - FMan dTSEC/XGEC/mEMAC Node + - FMan IEEE 1588 Node + - Example + += +FMan Node + +DESCRIPTION + +Due to the fact that the FMan is an aggregation of sub-engines (ports, MACs, +etc.) the FMan node will have child nodes for each of them. + +PROPERTIES + +- compatible + Usage: required + Value type: + Definition: Must include "fsl,fman" + FMan version can be determined via FM_IP_REV_1 register in the + FMan block. The offset is 0xc4 from the beginning of the + Frame Processing Manager memory map (0xc3000 from the + beginning of the FMan node). + +- cell-index + Usage: required + Value type: + Definition: Specifies the index of the FMan unit. + + The cell-index value may be used, for example, to disable or + enable the FMan via "Device disable register 2" + (DCFG_DEVDISR2, located at the SoC reference manual under + "Device Configuration and Pin Control Memory Map"). + +- reg + Usage: required + Value type: + Definition: A standard property. Specifies the offset of the + following configuration registers: + - BMI configuration registers. + - QMI configuration registers. + - DMA configuration registers. + - FPM configuration registers. + - FMan controller configuration registers. + +- ranges + Usage: required + Value type: + Definition: A standard property. + +- clocks + Usage: required + Value type: + Definition: phandle for fman clock. + +- clock-names + usage: optional + Value type: + Definition: A standard property + +- interrupts + Usage: required + Value type: + Definition: A pair of IRQs are specified in this property. + The first element is associated with the event interrupts and + the second element is associated with the error interrupts. + +- fsl,qman-channel-range + Usage: required + Value type: + Definition: Specifies the ranges of the available dedicated + channels in the FMan. The first cell specifies the beginning + of the range and the second cell specifies the number of + channels. + Further information available at: + "Work Queue (WQ) Channel Assignments in the QMan" section + in DPAA Reference Manual. + += +FMan MURAM Node + +DESCRIPTION + +FMan Internal memory - shared between all the FMan modules. +It contains data structures that are common and written to or read by +the modules. +FMan internal memory is split into the following parts: + Packet buffering (Tx/Rx FIFOs) + Frames internal context + +PROPERTIES + +- compatible + Usage: required + Value type: + Definition: Must include "fsl,fman-muram" + +- ranges + Usage: required + Value type: + Definition: A standard property. Specifies the physical + address and length of the FMan memory space + +EXAMPLE + +muram@0 { + compatible = "fsl,fman-muram"; + ranges = <0 0x00 0x28000>; +}; + += +FMan Port Node + +DESCRIPTION + +The Frame Manager (FMan) supports several types of hardware ports: + Ethernet receiver (RX) + Ethernet transmitter (TX) + Offline/Host command (O/H) + +PROPERTIES + +- comp
[PATCH] spi: fsl: Don't use devm_kzalloc in master->setup callback
device_add() expects that any memory allocated via devm_* API is only done in the device's probe function. Fix below boot warning: [3.092348] WARNING: at drivers/base/dd.c:286 [3.096637] Modules linked in: [3.099697] CPU: 0 PID: 25 Comm: kworker/u2:1 Tainted: G W 3.16.1-s3k-drv-999-svn5771_knld-999 #158 [ 3.109610] Workqueue: deferwq deferred_probe_work_func [3.114736] task: c787f020 ti: c790c000 task.ti: c790c000 [3.120062] NIP: c01df158 LR: c01df144 CTR: [3.124983] REGS: c790db30 TRAP: 0700 Tainted: GW (3.16.1-s3k-drv-999-svn5771_knld-999) [3.134162] MSR: 00029032 CR: 22002082 XER: 2000 [3.140703] [3.140703] GPR00: 0001 c790dbe0 c787f020 0044 0054 0308 c056da0e 20737069 [3.140703] GPR08: 33323736 000ebfe0 0308 000ebfdf 22002082 c046c5a0 c046c608 [3.140703] GPR16: c046c614 c046c620 c046c62c c046c638 c046c648 c046c654 c046c68c c046c6c4 [3.140703] GPR24: 0003 c0401aa0 c0596638 c059662c c054e7a8 c7996800 [3.170102] NIP [c01df158] driver_probe_device+0xf8/0x334 [3.175431] LR [c01df144] driver_probe_device+0xe4/0x334 [3.180633] Call Trace: [3.183093] [c790dbe0] [c01df144] driver_probe_device+0xe4/0x334 (unreliable) [3.190147] [c790dc10] [c01dd15c] bus_for_each_drv+0x7c/0xc0 [3.195741] [c790dc40] [c01df5fc] device_attach+0xcc/0xf8 [3.201076] [c790dc60] [c01dd6d4] bus_probe_device+0xb4/0xc4 [3.20] [c790dc80] [c01db9f8] device_add+0x270/0x564 [3.211923] [c790dcc0] [c0219e84] spi_add_device+0xc0/0x190 [3.217427] [c790dce0] [c021a79c] spi_register_master+0x720/0x834 [3.223455] [c790dd40] [c021cb48] of_fsl_spi_probe+0x55c/0x614 [3.229234] [c790dda0] [c01e0d2c] platform_drv_probe+0x30/0x74 [3.234987] [c790ddb0] [c01df18c] driver_probe_device+0x12c/0x334 [3.241008] [c790dde0] [c01dd15c] bus_for_each_drv+0x7c/0xc0 [3.246602] [c790de10] [c01df5fc] device_attach+0xcc/0xf8 [3.251937] [c790de30] [c01dd6d4] bus_probe_device+0xb4/0xc4 [3.257536] [c790de50] [c01de9d8] deferred_probe_work_func+0x98/0xe0 [3.263816] [c790de70] [c00305b8] process_one_work+0x18c/0x440 [3.269577] [c790dea0] [c0030a00] worker_thread+0x194/0x67c [3.275105] [c790def0] [c0039198] kthread+0xd0/0xe4 [3.279911] [c790df40] [c000c6d0] ret_from_kernel_thread+0x5c/0x64 [3.285970] Instruction dump: [3.288900] 80de 419e01d0 3b7b0038 3c60c046 7f65db78 38635264 48211b99 813f00a0 [3.296559] 381f00a0 7d290278 3169 7c0b4910 <0f00> 93df0044 7fe3fb78 4bfffd4d Reported-by: leroy christophe Signed-off-by: Axel Lin --- Hi Leroy, Can you test this path? Thanks, Axel drivers/spi/spi-fsl-espi.c | 15 --- drivers/spi/spi-fsl-spi.c | 10 +++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 8ebd724..b5d879a 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -452,16 +452,16 @@ static int fsl_espi_setup(struct spi_device *spi) int retval; u32 hw_mode; u32 loop_mode; - struct spi_mpc8xxx_cs *cs = spi->controller_state; + struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi); if (!spi->max_speed_hz) return -EINVAL; if (!cs) { - cs = devm_kzalloc(&spi->dev, sizeof(*cs), GFP_KERNEL); + cs = kzalloc(sizeof(*cs), GFP_KERNEL); if (!cs) return -ENOMEM; - spi->controller_state = cs; + spi_set_ctldata(spi, cs); } mpc8xxx_spi = spi_master_get_devdata(spi->master); @@ -496,6 +496,14 @@ static int fsl_espi_setup(struct spi_device *spi) return 0; } +static void fsl_espi_cleanup(struct spi_device *spi) +{ + struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi); + + kfree(cs); + spi_set_ctldata(spi, NULL); +} + void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) { struct fsl_espi_reg *reg_base = mspi->reg_base; @@ -605,6 +613,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev, master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); master->setup = fsl_espi_setup; + master->cleanup = fsl_espi_cleanup; mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi->spi_do_one_msg = fsl_espi_do_one_msg; diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 9452f674..590f31b 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -425,16 +425,16 @@ static int fsl_spi_setup(struct spi_device *spi) struct fsl_spi_reg *reg_base; int retval; u32 hw_mode; - struct spi_mpc8xxx_cs *cs = spi->controller_state; + struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi); if (!spi->max_speed_hz) return -EINVAL; if (!cs) { - cs = devm_kzalloc(&spi->dev, sizeo
Re: [PATCH] spi: fsl: Don't use devm_kzalloc in master->setup callback
Le 31/08/2014 06:44, Axel Lin a écrit : device_add() expects that any memory allocated via devm_* API is only done in the device's probe function. Fix below boot warning: [3.092348] WARNING: at drivers/base/dd.c:286 [3.096637] Modules linked in: [3.099697] CPU: 0 PID: 25 Comm: kworker/u2:1 Tainted: G W 3.16.1-s3k-drv-999-svn5771_knld-999 #158 [ 3.109610] Workqueue: deferwq deferred_probe_work_func [3.114736] task: c787f020 ti: c790c000 task.ti: c790c000 [3.120062] NIP: c01df158 LR: c01df144 CTR: [3.124983] REGS: c790db30 TRAP: 0700 Tainted: GW (3.16.1-s3k-drv-999-svn5771_knld-999) [3.134162] MSR: 00029032 CR: 22002082 XER: 2000 [3.140703] [3.140703] GPR00: 0001 c790dbe0 c787f020 0044 0054 0308 c056da0e 20737069 [3.140703] GPR08: 33323736 000ebfe0 0308 000ebfdf 22002082 c046c5a0 c046c608 [3.140703] GPR16: c046c614 c046c620 c046c62c c046c638 c046c648 c046c654 c046c68c c046c6c4 [3.140703] GPR24: 0003 c0401aa0 c0596638 c059662c c054e7a8 c7996800 [3.170102] NIP [c01df158] driver_probe_device+0xf8/0x334 [3.175431] LR [c01df144] driver_probe_device+0xe4/0x334 [3.180633] Call Trace: [3.183093] [c790dbe0] [c01df144] driver_probe_device+0xe4/0x334 (unreliable) [3.190147] [c790dc10] [c01dd15c] bus_for_each_drv+0x7c/0xc0 [3.195741] [c790dc40] [c01df5fc] device_attach+0xcc/0xf8 [3.201076] [c790dc60] [c01dd6d4] bus_probe_device+0xb4/0xc4 [3.20] [c790dc80] [c01db9f8] device_add+0x270/0x564 [3.211923] [c790dcc0] [c0219e84] spi_add_device+0xc0/0x190 [3.217427] [c790dce0] [c021a79c] spi_register_master+0x720/0x834 [3.223455] [c790dd40] [c021cb48] of_fsl_spi_probe+0x55c/0x614 [3.229234] [c790dda0] [c01e0d2c] platform_drv_probe+0x30/0x74 [3.234987] [c790ddb0] [c01df18c] driver_probe_device+0x12c/0x334 [3.241008] [c790dde0] [c01dd15c] bus_for_each_drv+0x7c/0xc0 [3.246602] [c790de10] [c01df5fc] device_attach+0xcc/0xf8 [3.251937] [c790de30] [c01dd6d4] bus_probe_device+0xb4/0xc4 [3.257536] [c790de50] [c01de9d8] deferred_probe_work_func+0x98/0xe0 [3.263816] [c790de70] [c00305b8] process_one_work+0x18c/0x440 [3.269577] [c790dea0] [c0030a00] worker_thread+0x194/0x67c [3.275105] [c790def0] [c0039198] kthread+0xd0/0xe4 [3.279911] [c790df40] [c000c6d0] ret_from_kernel_thread+0x5c/0x64 [3.285970] Instruction dump: [3.288900] 80de 419e01d0 3b7b0038 3c60c046 7f65db78 38635264 48211b99 813f00a0 [3.296559] 381f00a0 7d290278 3169 7c0b4910 <0f00> 93df0044 7fe3fb78 4bfffd4d Reported-by: leroy christophe Signed-off-by: Axel Lin --- Hi Leroy, Can you test this path? Thanks, Axel drivers/spi/spi-fsl-espi.c | 15 --- drivers/spi/spi-fsl-spi.c | 10 +++--- 2 files changed, 19 insertions(+), 6 deletions(-) Tested-by: Christophe Leroy Thanks for this patch. SPI still works ok, no warning anymore. Tested on MPC8xx (spi-fsl-spi). Not tested the removal of drivers (I don't use modules) Christophe (NB: Leroy is my family name) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v16 4/7] powerpc: add pmd_[dirty|mkclean] for THP
MADV_FREE needs pmd_dirty and pmd_mkclean for detecting recent overwrite of the contents since MADV_FREE syscall is called for THP page. This patch adds pmd_dirty and pmd_mkclean for THP page MADV_FREE support. Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: linuxppc-dev@lists.ozlabs.org Reviewed-by: Aneesh Kumar K.V Signed-off-by: Minchan Kim --- arch/powerpc/include/asm/pgtable-ppc64.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h index 7b3d54fae46f..fb89d8eb96c8 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h @@ -468,9 +468,11 @@ static inline pte_t *pmdp_ptep(pmd_t *pmd) #define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd)) #define pmd_young(pmd) pte_young(pmd_pte(pmd)) +#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd)) #define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd))) #define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd))) #define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) +#define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd))) #define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd))) #define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd))) -- 2.0.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev