Re: [PATCH] powerpc: mitigate impact of decrementer reset
On Tue, 2014-10-07 at 14:13 -0500, Paul Clarke wrote: The POWER ISA defines an always-running decrementer which can be used to schedule interrupts after a certain time interval has elapsed. The decrementer counts down at the same frequency as the Time Base, which is 512 MHz. The maximum value of the decrementer is 0x7fff. This works out to a maximum interval of about 4.19 seconds. If a larger interval is desired, the kernel will set the decrementer to its maximum value and reset it after it expires (underflows) a sufficient number of times until the desired interval has elapsed. The negative effect of this is that an unwanted latency spike will impact normal processing at most every 4.19 seconds. On an IBM POWER8-based system, this spike was measured at about 25-30 microseconds, much of which was basic, opportunistic housekeeping tasks that could otherwise have waited. This patch short-circuits the reset of the decrementer, exiting after the decrementer reset, but before the housekeeping tasks if the only need for the interrupt is simply to reset it. After this patch, the latency spike was measured at about 150 nanoseconds. Doesn't this break the irq_work stuff ? We trigger it with a set_dec(1); and your patch will probably cause it to be skipped... Cheers, Ben. Signed-off-by: Paul A. Clarke p...@us.ibm.com --- arch/powerpc/kernel/time.c | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 368ab37..962a06b 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -528,6 +528,7 @@ void timer_interrupt(struct pt_regs * regs) { struct pt_regs *old_regs; u64 *next_tb = __get_cpu_var(decrementers_next_tb); + u64 now; /* Ensure a positive value is written to the decrementer, or else * some CPUs will continue to take decrementer exceptions. @@ -550,6 +551,18 @@ void timer_interrupt(struct pt_regs * regs) */ may_hard_irq_enable(); + /* If this is simply the decrementer expiring (underflow) due to + * the limited size of the decrementer, and not a set timer, + * reset (if needed) and return + */ + now = get_tb_or_rtc(); + if (now *next_tb) { + now = *next_tb - now; + if (now = DECREMENTER_MAX) + set_dec((int)now); + __get_cpu_var(irq_stat).timer_irqs_others++; + return; + } #if defined(CONFIG_PPC32) defined(CONFIG_PPC_PMAC) if (atomic_read(ppc_n_lost_interrupts) != 0) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCH] DT: add MDIO node for FMan node
Ping. Best Regards, Shaohui Xie -Original Message- From: shh@gmail.com [mailto:shh@gmail.com] Sent: Tuesday, November 04, 2014 7:57 PM To: linuxppc-dev@lists.ozlabs.org; devicet...@vger.kernel.org; Wood Scott-B07421 Cc: Medve Emilian-EMMEDVE1; Xie Shaohui-B21989 Subject: [PATCH] DT: add MDIO node for FMan node From: Shaohui Xie shaohui@freescale.com This binding is for FMan MDIO, it covers FMan v2 FMan v3. Signed-off-by: Shaohui Xie shaohui@freescale.com --- based on http://patchwork.ozlabs.org/patch/390351/ for 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git .../devicetree/bindings/powerpc/fsl/fman.txt | 69 ++ 1 file changed, 69 insertions(+) diff --git a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt index da8e5f2..83c2f14 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt @@ -7,6 +7,7 @@ CONTENTS - FMan MURAM Node - FMan dTSEC/XGEC/mEMAC Node - FMan IEEE 1588 Node + - FMan MDIO Node - Example = @@ -352,6 +353,67 @@ ptp-timer@fe000 { }; = +FMan MDIO Node + +DESCRIPTION + +The MDIO is a bus to which the PHY devices are connected. + +PROPERTIES + +- compatible + Usage: required + Value type: stringlist + Definition: A standard property. + Must include fsl,fman-mdio for 1 Gb/s MDIO from FMan v2. + Must include fsl,fman-xmdio for 10 Gb/s MDIO from FMan v2. + Must include fsl,fman-memac-mdio for 1/10 Gb/s MDIO from + FMan v3. + +- reg + Usage: required + Value type: prop-encoded-array + Definition: A standard property. + +- bus-frequency + Usage: optional + Value type: u32 + Definition: Default MDIO bus clock speed. + +- interrupts + Usage: optional + Value type: prop-encoded-array + Definition: MDIO controller event interrupts. + +- type + Usage: required for FMan v3 + Value type: stringlist + Definition: A standard property. + FMan v3 has internal MDIO for internal PCS(Physical Coding + Sublayer) PHYs and external MDIO for external PHYs. + The settings and programming routines for internal/external + MDIO are different. Must include internal for internal MDIO, + must include external for external MDIO. + +EXAMPLE + +Example for FMan v2: + +mdio@f1000 { + compatible = fsl,fman-xmdio; + reg = 0xf1000 0x1000; +}; + +Example for FMan v3: + +mdio@fd000 { + compatible = fsl,fman-memac-mdio; + reg = 0xfd000 0x1000; + bus-frequency = 250; + type = external; +}; + + = Example fman@40 { @@ -526,4 +588,11 @@ fman@40 { compatible = fsl,fman-ptp-timer; reg = 0xfe000 0x1000; }; + + mdio@fd000 { + compatible = fsl,fman-memac-mdio; + reg = 0xfd000 0x1000; + bus-frequency = 250; + type = external; + }; }; -- 1.8.4.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 net-next] PPC: bpf_jit_comp: add SKF_AD_HATYPE instruction
On Sun, Nov 9, 2014 at 9:59 PM, Denis Kirjanov k...@linux-powerpc.org wrote: Add BPF extension SKF_AD_HATYPE to ppc JIT to check the hw type of the interface Before: [ 57.723666] test_bpf: #20 LD_HATYPE [ 57.723675] BPF filter opcode 0020 (@0) unsupported [ 57.724168] 48 48 PASS After: [ 103.053184] test_bpf: #20 LD_HATYPE 7 6 PASS CC: Alexei Starovoitovalexei.starovoi...@gmail.com CC: Daniel Borkmanndbork...@redhat.com CC: Philippe Bergheaudfe...@linux.vnet.ibm.com Signed-off-by: Denis Kirjanov k...@linux-powerpc.org v2: address Alexei's comments --- arch/powerpc/net/bpf_jit_comp.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index d110e28..d3fa80d 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -361,6 +361,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, protocol)); break; case BPF_ANC | SKF_AD_IFINDEX: + case BPF_ANC | SKF_AD_HATYPE: + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, + ifindex) != 4); + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, + type) != 2); PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, dev)); PPC_CMPDI(r_scratch1, 0); @@ -368,14 +373,18 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, PPC_BCC(COND_EQ, addrs[ctx-pc_ret0]); } else { /* Exit, returning 0; first pass hits here. */ - PPC_BCC_SHORT(COND_NE, (ctx-idx*4)+12); + PPC_BCC_SHORT(COND_NE, ctx-idx * 4 + 12); PPC_LI(r_ret, 0); PPC_JMP(exit_addr); } - BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, - ifindex) != 4); - PPC_LWZ_OFFS(r_A, r_scratch1, + if (code == (BPF_ANC | SKF_AD_IFINDEX)) { + PPC_LWZ_OFFS(r_A, r_scratch1, offsetof(struct net_device, ifindex)); + } else { + PPC_LHZ_OFFS(r_A, r_scratch1, +offsetof(struct net_device, type)); formatting is a bit off here, but that's minor. Acked-by: Alexei Starovoitov a...@plumgrid.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: mitigate impact of decrementer reset
On 11/10/2014 04:08 AM, Benjamin Herrenschmidt wrote: On Tue, 2014-10-07 at 14:13 -0500, Paul Clarke wrote: The POWER ISA defines an always-running decrementer which can be used to schedule interrupts after a certain time interval has elapsed. The decrementer counts down at the same frequency as the Time Base, which is 512 MHz. The maximum value of the decrementer is 0x7fff. This works out to a maximum interval of about 4.19 seconds. If a larger interval is desired, the kernel will set the decrementer to its maximum value and reset it after it expires (underflows) a sufficient number of times until the desired interval has elapsed. The negative effect of this is that an unwanted latency spike will impact normal processing at most every 4.19 seconds. On an IBM POWER8-based system, this spike was measured at about 25-30 microseconds, much of which was basic, opportunistic housekeeping tasks that could otherwise have waited. This patch short-circuits the reset of the decrementer, exiting after the decrementer reset, but before the housekeeping tasks if the only need for the interrupt is simply to reset it. After this patch, the latency spike was measured at about 150 nanoseconds. Doesn't this break the irq_work stuff ? We trigger it with a set_dec(1); and your patch will probably cause it to be skipped... You're right. I'm confused by the division between timer_interrupt() and __timer_interrupt(). The former is called with interrupts disabled (and enables them), but also calls irq_enter()/irq_exit(). Why are those calls not in __timer_interrupt()? (If they were, the short-circuit logic might be a bit easier to put directly in __timer_interrupt(), which would eliminate any duplicate code.) It looks like __timer_interrupt is only called directly by the broadcast timer IPI handler. (Why is __timer_interrupt not static?) Does this path not need irq_enter/irq_exit? Signed-off-by: Paul A. Clarke p...@us.ibm.com --- arch/powerpc/kernel/time.c | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 368ab37..962a06b 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -528,6 +528,7 @@ void timer_interrupt(struct pt_regs * regs) { struct pt_regs *old_regs; u64 *next_tb = __get_cpu_var(decrementers_next_tb); + u64 now; /* Ensure a positive value is written to the decrementer, or else * some CPUs will continue to take decrementer exceptions. @@ -550,6 +551,18 @@ void timer_interrupt(struct pt_regs * regs) */ may_hard_irq_enable(); + /* If this is simply the decrementer expiring (underflow) due to +* the limited size of the decrementer, and not a set timer, +* reset (if needed) and return +*/ + now = get_tb_or_rtc(); + if (now *next_tb) { + now = *next_tb - now; + if (now = DECREMENTER_MAX) + set_dec((int)now); + __get_cpu_var(irq_stat).timer_irqs_others++; + return; + } #if defined(CONFIG_PPC32) defined(CONFIG_PPC_PMAC) if (atomic_read(ppc_n_lost_interrupts) != 0) Regards, PC ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Bad NULL pointer check in udbg_uart_getc_poll
We have some code in udbg_uart_getc_poll that tries to protect against a NULL udbg_uart_in, but gets it all wrong. Found with the LLVM static analyzer (scan-build). Fixes: 309257484cc1 (powerpc: Cleanup udbg_16550 and add support for LPC PIO-only UARTs) Cc: sta...@vger.kernel.org Signed-off-by: Anton Blanchard an...@samba.org --- arch/powerpc/kernel/udbg_16550.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index 6e7c492..3faf393 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c @@ -69,7 +69,9 @@ static void udbg_uart_putc(char c) static int udbg_uart_getc_poll(void) { - if (!udbg_uart_in || !(udbg_uart_in(UART_LSR) LSR_DR)) + if (!udbg_uart_in) + return -1; + if (!(udbg_uart_in(UART_LSR) LSR_DR)) return udbg_uart_in(UART_RBR); return -1; } -- 1.9.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] DT: add MDIO node for FMan node
On Tue, 2014-11-04 at 19:56 +0800, shh@gmail.com wrote: From: Shaohui Xie shaohui@freescale.com This binding is for FMan MDIO, it covers FMan v2 FMan v3. Signed-off-by: Shaohui Xie shaohui@freescale.com --- based on http://patchwork.ozlabs.org/patch/390351/ for 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git Are there any other FMan pieces that are missing from the above patch? .../devicetree/bindings/powerpc/fsl/fman.txt | 69 ++ 1 file changed, 69 insertions(+) diff --git a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt index da8e5f2..83c2f14 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt @@ -7,6 +7,7 @@ CONTENTS - FMan MURAM Node - FMan dTSEC/XGEC/mEMAC Node - FMan IEEE 1588 Node + - FMan MDIO Node - Example = @@ -352,6 +353,67 @@ ptp-timer@fe000 { }; = +FMan MDIO Node + +DESCRIPTION + +The MDIO is a bus to which the PHY devices are connected. + +PROPERTIES + +- compatible + Usage: required + Value type: stringlist + Definition: A standard property. + Must include fsl,fman-mdio for 1 Gb/s MDIO from FMan v2. + Must include fsl,fman-xmdio for 10 Gb/s MDIO from FMan v2. + Must include fsl,fman-memac-mdio for 1/10 Gb/s MDIO from + FMan v3. + +- reg + Usage: required + Value type: prop-encoded-array + Definition: A standard property. + +- bus-frequency + Usage: optional + Value type: u32 + Definition: Default MDIO bus clock speed. Use clocks/clock-names +- interrupts + Usage: optional + Value type: prop-encoded-array + Definition: MDIO controller event interrupts. One interrupt or multiple? + +- type + Usage: required for FMan v3 + Value type: stringlist + Definition: A standard property. What standard is type defined in? + FMan v3 has internal MDIO for internal PCS(Physical Coding + Sublayer) PHYs and external MDIO for external PHYs. + The settings and programming routines for internal/external + MDIO are different. Must include internal for internal MDIO, + must include external for external MDIO. I assume fman v2 is always internal? How about a boolean fsl,fman-internal-phy property instead? + +EXAMPLE + +Example for FMan v2: + +mdio@f1000 { + compatible = fsl,fman-xmdio; + reg = 0xf1000 0x1000; +}; + +Example for FMan v3: + +mdio@fd000 { + compatible = fsl,fman-memac-mdio; + reg = 0xfd000 0x1000; + bus-frequency = 250; + type = external; +}; + += Example fman@40 { @@ -526,4 +588,11 @@ fman@40 { compatible = fsl,fman-ptp-timer; reg = 0xfe000 0x1000; }; + + mdio@fd000 { + compatible = fsl,fman-memac-mdio; + reg = 0xfd000 0x1000; + bus-frequency = 250; + type = external; + }; }; The rest of the example is fman v2; don't mix an fman v3 node in with that. -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V4 0/8] Add new PowerPC specific ELF core notes
This patch series adds five new ELF core note sections which can be used with existing ptrace request PTRACE_GETREGSET-SETREGSET for accessing various transactional memory and miscellaneous debug register sets on PowerPC platform. Previous versions: == RFC: https://lkml.org/lkml/2014/4/1/292 V1: https://lkml.org/lkml/2014/4/2/43 V2: https://lkml.org/lkml/2014/5/5/88 V3: https://lkml.org/lkml/2014/5/23/486 Changes in V4: -- - Added one test program into the powerpc selftest bucket in this regard - Split the 2nd patch in the previous series into four different patches - Accommodated most of the review comments on the previous patch series - Added a patch to merge functions __switch_to_tm and tm_reclaim_task Changes in V3: -- - Added two new error paths in every TM related get/set functions when regset support is not present on the system (ENODEV) or when the process does not have any transaction active (ENODATA) in the context - Installed the active hooks for all the newly added regset core note types Changes in V2: -- - Removed all the power specific ptrace requests corresponding to new NT_PPC_* elf core note types. Now all the register sets can be accessed from ptrace through PTRACE_GETREGSET/PTRACE_SETREGSET using the individual NT_PPC* core note type instead - Fixed couple of attribute values for REGSET_TM_CGPR register set - Renamed flush_tmreg_to_thread as flush_tmregs_to_thread - Fixed 32 bit checkpointed GPR support - Changed commit messages accordingly Test Result --- The patch series has been verified both in 32 bit and 64 bit compiled mode. Test result for the selftest test (64 bit compiled mode) can be found here. test: tm_ptrace tags: git_version:v3.18-rc4-9-g000adb7 =Testing TM based PTRACE calls== ---TM Specific SPR-- TFHAR: 1cc8 TEXASR: de018c01 TFIAR: c00414f0 TM ORIG_MSR: 5f032 TM CH DSCR: a (PASSED) TM CH TAR: 14 (PASSED) TM CH PPR: 8 (PASSED) ---TM Checkpointed GPR- TM CH NIP: 1cc8 TM CH LINK: 1af8 TM CH CCR: 22000422 TM CH GPR[0]: 0 (PASSED) TM CH GPR[1]: 1 (PASSED) TM CH GPR[2]: 2 (PASSED) TM CH GPR[3]: 3 (PASSED) TM CH GPR[4]: 4 (PASSED) TM CH GPR[5]: 5 (PASSED) TM CH GPR[6]: 6 (PASSED) TM CH GPR[7]: 7 (PASSED) TM CH GPR[8]: 8 (PASSED) TM CH GPR[9]: 9 (PASSED) TM CH GPR[10]: a (PASSED) TM CH GPR[11]: b (PASSED) TM CH GPR[12]: c (PASSED) TM CH GPR[13]: d (PASSED) TM CH GPR[14]: e (PASSED) TM CH GPR[15]: f (PASSED) TM CH GPR[16]: 0 (PASSED) TM CH GPR[17]: 1 (PASSED) TM CH GPR[18]: 2 (PASSED) TM CH GPR[19]: 3 (PASSED) TM CH GPR[20]: 4 (PASSED) TM CH GPR[21]: 5 (PASSED) TM CH GPR[22]: 6 (PASSED) TM CH GPR[23]: 7 (PASSED) TM CH GPR[24]: 8 (PASSED) TM CH GPR[25]: 9 (PASSED) TM CH GPR[26]: a (PASSED) TM CH GPR[27]: b (PASSED) TM CH GPR[28]: c (PASSED) TM CH GPR[29]: d (PASSED) TM CH GPR[30]: e (PASSED) TM CH GPR[31]: f (PASSED) ---TM Checkpointed FPR- TM CH FPSCR: 0 TM CH FPR[0]: 0 (PASSED) TM CH FPR[1]: 1 (PASSED) TM CH FPR[2]: 2 (PASSED) TM CH FPR[3]: 3 (PASSED) TM CH FPR[4]: 4 (PASSED) TM CH FPR[5]: 5 (PASSED) TM CH FPR[6]: 6 (PASSED) TM CH FPR[7]: 7 (PASSED) TM CH FPR[8]: 8 (PASSED) TM CH FPR[9]: 9 (PASSED) TM CH FPR[10]: a (PASSED) TM CH FPR[11]: b (PASSED) TM CH FPR[12]: c (PASSED) TM CH FPR[13]: d (PASSED) TM CH FPR[14]: e (PASSED) TM CH FPR[15]: f (PASSED) TM CH FPR[16]: 0 (PASSED) TM CH FPR[17]: 1 (PASSED) TM CH FPR[18]: 2 (PASSED) TM CH FPR[19]: 3 (PASSED) TM CH FPR[20]: 4 (PASSED) TM CH FPR[21]: 5 (PASSED) TM CH FPR[22]: 6 (PASSED) TM CH FPR[23]: 7 (PASSED) TM CH FPR[24]: 8 (PASSED) TM CH FPR[25]: 9 (PASSED) TM CH FPR[26]: a (PASSED) TM CH FPR[27]: b (PASSED) TM CH FPR[28]: c (PASSED) TM CH FPR[29]: d (PASSED) TM CH FPR[30]: e (PASSED) TM CH FPR[31]: f (PASSED) ---TM Running GPR- TM RN NIP: 1de0 TM RN LINK: 1af8 TM RN CCR: 2000422 TM RN GPR[0]: f (PASSED) TM RN GPR[1]: e (PASSED) TM RN GPR[2]: d (PASSED) TM RN GPR[3]: c (PASSED) TM RN GPR[4]: b (PASSED) TM RN GPR[5]: a (PASSED) TM RN GPR[6]: 9 (PASSED) TM RN GPR[7]: 8 (PASSED) TM RN GPR[8]: 7 (PASSED) TM RN GPR[9]: 6 (PASSED) TM RN GPR[10]: 5 (PASSED) TM RN GPR[11]: 4 (PASSED) TM RN GPR[12]: 3 (PASSED) TM RN GPR[13]: 2 (PASSED) TM RN GPR[14]: 1 (PASSED) TM RN GPR[15]: 0 (PASSED) TM RN GPR[16]: f (PASSED) TM RN GPR[17]: e (PASSED) TM RN GPR[18]: d (PASSED) TM RN GPR[19]: c (PASSED) TM RN GPR[20]: b (PASSED) TM RN GPR[21]: a (PASSED) TM RN GPR[22]: 9 (PASSED) TM RN GPR[23]: 8 (PASSED) TM RN GPR[24]: 7 (PASSED) TM RN GPR[25]: 6 (PASSED) TM RN GPR[26]: 5 (PASSED) TM RN GPR[27]: 4 (PASSED) TM RN GPR[28]: 3 (PASSED) TM RN GPR[29]: 2 (PASSED) TM RN GPR[30]: 1 (PASSED) TM RN GPR[31]: 0 (PASSED) ---TM Running FPR- TM RN FPSCR: 0 TM RN FPR[0]: f (PASSED) TM RN FPR[1]: e (PASSED) TM RN FPR[2]: d (PASSED) TM RN FPR[3]: c (PASSED) TM RN FPR[4]: b (PASSED) TM RN FPR[5]: a (PASSED) TM RN FPR[6]: 9 (PASSED) TM RN FPR[7]: 8 (PASSED) TM RN FPR[8]: 7
[PATCH V4 2/8] powerpc, process: Add functions flush_tm_state, flush_tmregs_to_thread
This patch creates a new function called flush_tm_state to flush the existing transactional memory state from the thread. It also creates a function called flush_tmregs_to_thread which will then be used on subsequent patches in this series. Signed-off-by: Anshuman Khandual khand...@linux.vnet.ibm.com --- arch/powerpc/include/asm/switch_to.h | 8 ++ arch/powerpc/kernel/process.c| 49 +--- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 58abeda..23752a9 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -82,6 +82,14 @@ static inline void flush_spe_to_thread(struct task_struct *t) } #endif +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +extern void flush_tmregs_to_thread(struct task_struct *); +#else +static inline void flush_tmregs_to_thread(struct task_struct *t) +{ +} +#endif + static inline void clear_task_ebb(struct task_struct *t) { #ifdef CONFIG_PPC_BOOK3S_64 diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index aa1df89..c36477b 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -745,6 +745,45 @@ void restore_tm_state(struct pt_regs *regs) #define __switch_to_tm(prev) #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ +/* + * flush_tm_state + * + * Flush TM state out so we can copy it. __switch_to_tm() does this + * flush but it removes the checkpointed state from the current CPU and + * transitions the CPU out of TM mode. Hence we need to call + * tm_recheckpoint_new_task() (on the same task) to restore the + * checkpointed state back and the TM mode. + */ +static void flush_tm_state(struct task_struct *src) +{ + __switch_to_tm(src); + tm_recheckpoint_new_task(src); +} + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +void flush_tmregs_to_thread(struct task_struct *tsk) +{ + /* +* If task is not current, it should have been flushed +* already to it's thread_struct during __switch_to(). +*/ + if (tsk != current) + return; + + preempt_disable(); + if (tsk-thread.regs) { + /* +* If we are still current, the TM state need to +* be flushed to thread_struct as it will be still +* present in the current cpu. +*/ + if (MSR_TM_ACTIVE(tsk-thread.regs-msr)) + flush_tm_state(tsk); + } + preempt_enable(); +} +#endif + struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *new) { @@ -1079,15 +1118,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) flush_altivec_to_thread(src); flush_vsx_to_thread(src); flush_spe_to_thread(src); - /* -* Flush TM state out so we can copy it. __switch_to_tm() does this -* flush but it removes the checkpointed state from the current CPU and -* transitions the CPU out of TM mode. Hence we need to call -* tm_recheckpoint_new_task() (on the same task) to restore the -* checkpointed state back and the TM mode. -*/ - __switch_to_tm(src); - tm_recheckpoint_new_task(src); + flush_tm_state(src); *dst = *src; -- 1.9.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V4 1/8] elf: Add new PowerPC specifc core note sections
This patch adds four new core note sections for PowerPC transactional memory and one core note section for general miscellaneous debug registers. These addition of new elf core note sections extends the existing elf ABI without affecting it in any manner. Signed-off-by: Anshuman Khandual khand...@linux.vnet.ibm.com --- include/uapi/linux/elf.h | 5 + 1 file changed, 5 insertions(+) diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index ea9bf25..2260fc0 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h @@ -379,6 +379,11 @@ typedef struct elf64_shdr { #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ #define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ #define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ +#define NT_PPC_TM_SPR 0x103 /* PowerPC TM special registers */ +#define NT_PPC_TM_CGPR 0x104 /* PowerpC TM checkpointed GPR */ +#define NT_PPC_TM_CFPR 0x105 /* PowerPC TM checkpointed FPR */ +#define NT_PPC_TM_CVMX 0x106 /* PowerPC TM checkpointed VMX */ +#define NT_PPC_MISC0x107 /* PowerPC miscellaneous registers */ #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ #define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ -- 1.9.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V4 4/8] powerpc, ptrace: Enable fpr_(get/set) for transactional memory
This patch enables the fpr_get which gets the running value of all the FPR registers and the fpr_set which sets the running value of of all the FPR registers to accommodate in transaction ptrace interface based requests. Signed-off-by: Anshuman Khandual khand...@linux.vnet.ibm.com --- arch/powerpc/kernel/ptrace.c | 103 --- 1 file changed, 97 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index f21897b..fd36b32 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -357,6 +357,33 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset, return ret; } + +/* + * fpr_get + * + * When the transaction is active, 'transact_fp' holds the current running + * value of all FPR registers and 'fp_state' holds the last checkpointed + * value of all FPR registers for the current transaction. When transaction + * is not active 'fp_state' holds the current running state of all the FPR + * registers. So this function which returns the current running values of + * all the FPR registers, needs to know whether any transaction is active + * or not. + * + * Userspace interface buffer layout: + * + * struct data { + * u64 fpr[32]; + * u64 fpscr; + * }; + * + * There are two config options CONFIG_VSX and CONFIG_PPC_TRANSACTIONAL_MEM + * which determines the final code in this function. All the combinations of + * these two config options are possible except the one below as transactional + * memory config pulls in CONFIG_VSX automatically. + * + * !defined(CONFIG_VSX) defined(CONFIG_PPC_TRANSACTIONAL_MEM) + * + */ static int fpr_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) @@ -367,22 +394,64 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset, #endif flush_fp_to_thread(target); -#ifdef CONFIG_VSX +#if defined(CONFIG_VSX) defined(CONFIG_PPC_TRANSACTIONAL_MEM) + /* copy to local buffer then write that out */ + if (MSR_TM_ACTIVE(target-thread.regs-msr)) { + flush_altivec_to_thread(target); + flush_tmregs_to_thread(target); + for (i = 0; i 32 ; i++) + buf[i] = target-thread.TS_TRANS_FPR(i); + buf[32] = target-thread.transact_fp.fpscr; + } else { + for (i = 0; i 32 ; i++) + buf[i] = target-thread.TS_FPR(i); + buf[32] = target-thread.fp_state.fpscr; + } + return user_regset_copyout(pos, count, kbuf, ubuf, buf, 0, -1); +#endif + +#if defined(CONFIG_VSX) !defined(CONFIG_PPC_TRANSACTIONAL_MEM) /* copy to local buffer then write that out */ for (i = 0; i 32 ; i++) buf[i] = target-thread.TS_FPR(i); buf[32] = target-thread.fp_state.fpscr; return user_regset_copyout(pos, count, kbuf, ubuf, buf, 0, -1); +#endif -#else + +#if !defined(CONFIG_VSX) !defined(CONFIG_PPC_TRANSACTIONAL_MEM) BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) != offsetof(struct thread_fp_state, fpr[32][0])); - return user_regset_copyout(pos, count, kbuf, ubuf, target-thread.fp_state, 0, -1); #endif } +/* + * fpr_set + * + * When the transaction is active, 'transact_fp' holds the current running + * value of all FPR registers and 'fp_state' holds the last checkpointed + * value of all FPR registers for the current transaction. When transaction + * is not active 'fp_state' holds the current running state of all the FPR + * registers. So this function which setss the current running values of + * all the FPR registers, needs to know whether any transaction is active + * or not. + * + * Userspace interface buffer layout: + * + * struct data { + * u64 fpr[32]; + * u64 fpscr; + * }; + * + * There are two config options CONFIG_VSX and CONFIG_PPC_TRANSACTIONAL_MEM + * which determines the final code in this function. All the combinations of + * these two config options are possible except the one below as transactional + * memory config pulls in CONFIG_VSX automatically. + * + * !defined(CONFIG_VSX) defined(CONFIG_PPC_TRANSACTIONAL_MEM) + */ static int fpr_set(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) @@ -393,7 +462,27 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset, #endif flush_fp_to_thread(target); -#ifdef CONFIG_VSX +#if defined(CONFIG_VSX) defined(CONFIG_PPC_TRANSACTIONAL_MEM) + /* copy to local buffer then write that out */ + i = user_regset_copyin(pos, count, kbuf, ubuf, buf, 0, -1); + if (i) +
[PATCH V4 5/8] powerpc, ptrace: Enable vr_(get/set) for transactional memory
This patch enables the vr_get which gets the running value of all the VMX registers and the vr_set which sets the running value of of all the VMX registers to accommodate in transaction ptrace interface based requests. Signed-off-by: Anshuman Khandual khand...@linux.vnet.ibm.com --- arch/powerpc/kernel/ptrace.c | 94 ++-- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index fd36b32..2bbbd10 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -523,10 +523,30 @@ static int vr_active(struct task_struct *target, return target-thread.used_vr ? regset-n : 0; } +/* + * vr_get + * + * When the transaction is active, 'transact_vr' holds the current running + * value of all the VMX registers and 'vr_state' holds the last checkpointed + * value of all the VMX registers for the current transaction to fall back + * on in case it aborts. When transaction is not active 'vr_state' holds + * the current running state of all the VMX registers. So this function which + * gets the current running values of all the VMX registers, needs to know + * whether any transaction is active or not. + * + * Userspace interface buffer layout: + * + * struct data { + * vector128 vr[32]; + * vector128 vscr; + * vector128 vrsave; + * }; + */ static int vr_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { + struct thread_vr_state *addr; int ret; flush_altivec_to_thread(target); @@ -534,8 +554,19 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset, BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) != offsetof(struct thread_vr_state, vr[32])); +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + if (MSR_TM_ACTIVE(target-thread.regs-msr)) { + flush_fp_to_thread(target); + flush_tmregs_to_thread(target); + addr = target-thread.transact_vr; + } else { + addr = target-thread.vr_state; + } +#else + addr = target-thread.vr_state; +#endif ret = user_regset_copyout(pos, count, kbuf, ubuf, - target-thread.vr_state, 0, + addr, 0, 33 * sizeof(vector128)); if (!ret) { /* @@ -546,7 +577,16 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset, u32 word; } vrsave; memset(vrsave, 0, sizeof(vrsave)); + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + if (MSR_TM_ACTIVE(target-thread.regs-msr)) + vrsave.word = target-thread.transact_vrsave; + else + vrsave.word = target-thread.vrsave; +#else vrsave.word = target-thread.vrsave; +#endif + ret = user_regset_copyout(pos, count, kbuf, ubuf, vrsave, 33 * sizeof(vector128), -1); } @@ -554,10 +594,30 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset, return ret; } +/* + * vr_set + * + * When the transaction is active, 'transact_vr' holds the current running + * value of all the VMX registers and 'vr_state' holds the last checkpointed + * value of all the VMX registers for the current transaction to fall back + * on in case it aborts. When transaction is not active 'vr_state' holds + * the current running state of all the VMX registers. So this function which + * sets the current running values of all the VMX registers, needs to know + * whether any transaction is active or not. + * + * Userspace interface buffer layout: + * + * struct data { + * vector128 vr[32]; + * vector128 vscr; + * vector128 vrsave; + * }; + */ static int vr_set(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { + struct thread_vr_state *addr; int ret; flush_altivec_to_thread(target); @@ -565,8 +625,19 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset, BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) != offsetof(struct thread_vr_state, vr[32])); +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + if (MSR_TM_ACTIVE(target-thread.regs-msr)) { + flush_fp_to_thread(target); + flush_tmregs_to_thread(target); + addr = target-thread.transact_vr; + } else { + addr = target-thread.vr_state; + } +#else + addr = target-thread.vr_state; +#endif ret = user_regset_copyin(pos, count,
[PATCH V4 6/8] powerpc, ptrace: Enable support for transactional memory register sets
This patch enables get and set of transactional memory related register sets through PTRACE_GETREGSET-PTRACE_SETREGSET interface by implementing four new powerpc specific register sets i.e REGSET_TM_SPR, REGSET_TM_CGPR, REGSET_TM_CFPR, REGSET_CVMX support corresponding to these following new ELF core note types added previously in this regard. (1) NT_PPC_TM_SPR (2) NT_PPC_TM_CGPR (3) NT_PPC_TM_CFPR (4) NT_PPC_TM_CVMX Signed-off-by: Anshuman Khandual khand...@linux.vnet.ibm.com --- arch/powerpc/include/uapi/asm/elf.h | 2 + arch/powerpc/kernel/ptrace.c| 666 +++- 2 files changed, 653 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h index 59dad11..fdc8e2f 100644 --- a/arch/powerpc/include/uapi/asm/elf.h +++ b/arch/powerpc/include/uapi/asm/elf.h @@ -91,6 +91,8 @@ #define ELF_NGREG 48 /* includes nip, msr, lr, etc. */ #define ELF_NFPREG 33 /* includes fpscr */ +#define ELF_NVMX 34 /* includes all vector registers */ +#define ELF_NTMSPRREG 7 /* includes TM sprs, org_msr, dscr, tar, ppr */ typedef unsigned long elf_greg_t64; typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG]; diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 2bbbd10..b279947 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -63,6 +63,11 @@ struct pt_regs_offset { {.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])} #define REG_OFFSET_END {.name = NULL, .offset = 0} +/* Some common structure offsets */ +#define TSO(f) (offsetof(struct thread_struct, f)) +#define TVSO(f)(offsetof(struct thread_vr_state, f)) +#define TFSO(f)(offsetof(struct thread_fp_state, f)) + static const struct pt_regs_offset regoffset_table[] = { GPR_OFFSET_NAME(0), GPR_OFFSET_NAME(1), @@ -792,6 +797,534 @@ static int evr_set(struct task_struct *target, const struct user_regset *regset, } #endif /* CONFIG_SPE */ +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +/* + * tm_spr_active + * + * This function checks number of available regisers in + * the transactional memory SPR category. + */ +static int tm_spr_active(struct task_struct *target, +const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target-thread.regs-msr)) + return 0; + + return regset-n; +} + +/* + * tm_spr_get + * + * This function gets transactional memory related SPR registers + * + * Userspace interface buffer layout: + * + * struct { + * u64 tm_tfhar; + * u64 tm_texasr; + * u64 tm_tfiar; + * unsigned long tm_orig_msr; + * unsigned long tm_tar; + * unsigned long tm_ppr; + * unsigned long tm_dscr; + * }; + */ +static int tm_spr_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + int ret; + + /* Build tests */ + BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr)); + BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar)); + BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(tm_orig_msr)); + BUILD_BUG_ON(TSO(tm_orig_msr) + sizeof(unsigned long) + + sizeof(struct pt_regs) != TSO(tm_tar)); + BUILD_BUG_ON(TSO(tm_tar) + sizeof(unsigned long) != TSO(tm_ppr)); + BUILD_BUG_ON(TSO(tm_ppr) + sizeof(unsigned long) != TSO(tm_dscr)); + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target-thread.regs-msr)) + return -ENODATA; + + /* Flush the states */ + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + flush_tmregs_to_thread(target); + + /* TFHAR register */ + ret = user_regset_copyout(pos, count, kbuf, ubuf, + target-thread.tm_tfhar, 0, sizeof(u64)); + + /* TEXASR register */ + if (!ret) + ret = user_regset_copyout(pos, count, kbuf, ubuf, + target-thread.tm_texasr, sizeof(u64), + 2 * sizeof(u64)); + + /* TFIAR register */ + if (!ret) + ret = user_regset_copyout(pos, count, kbuf, ubuf, + target-thread.tm_tfiar, + 2 * sizeof(u64), 3 * sizeof(u64)); + + /* TM checkpointed original MSR */ + if (!ret) + ret = user_regset_copyout(pos, count, kbuf, ubuf, + target-thread.tm_orig_msr, 3 * sizeof(u64), + 3 * sizeof(u64) + sizeof(unsigned long)); + + /* TM checkpointed TAR register */ +
[PATCH V4 7/8] powerpc, ptrace: Enable support for miscellaneous debug registers
This patch enables get and set of miscellaneous debug registers through ptrace PTRACE_GETREGSET-PTRACE_SETREGSET interface by implementing new powerpc specific register set REGSET_MISC support corresponding to the new ELF core note NT_PPC_MISC added previously in this regard. Signed-off-by: Anshuman Khandual khand...@linux.vnet.ibm.com --- arch/powerpc/include/uapi/asm/elf.h | 1 + arch/powerpc/kernel/ptrace.c| 102 2 files changed, 103 insertions(+) diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h index fdc8e2f..a41bd98 100644 --- a/arch/powerpc/include/uapi/asm/elf.h +++ b/arch/powerpc/include/uapi/asm/elf.h @@ -93,6 +93,7 @@ #define ELF_NFPREG 33 /* includes fpscr */ #define ELF_NVMX 34 /* includes all vector registers */ #define ELF_NTMSPRREG 7 /* includes TM sprs, org_msr, dscr, tar, ppr */ +#define ELF_NMISCREG 3 /* includes dscr, tar, ppr */ typedef unsigned long elf_greg_t64; typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG]; diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index b279947..61a2581 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -1327,6 +1327,97 @@ static int tm_cvmx_set(struct task_struct *target, #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ /* + * get_misc_dbg + * + * This function gets miscellaneous debug registers + * which includes DSCR, PPR and TAR. + * + * Userspace intarface buffer layout: + * + * struct { + * unsigned long dscr; + * unsigned long ppr; + * unsigned long tar; + * }; + */ +static int get_misc_dbg(struct task_struct *target, + const struct user_regset *regset, unsigned int pos, + unsigned int count, void *kbuf, void __user *ubuf) +{ + int ret; + + /* Build test */ + BUILD_BUG_ON(TSO(dscr) + 2 * sizeof(unsigned long) != TSO(ppr)); + BUILD_BUG_ON(TSO(ppr) + sizeof(unsigned long) != TSO(tar)); + + /* DSCR register */ + ret = user_regset_copyout(pos, count, kbuf, ubuf, + target-thread.dscr, 0, + sizeof(unsigned long)); + + /* PPR register */ + if (!ret) + ret = user_regset_copyout(pos, count, kbuf, ubuf, + target-thread.ppr, + sizeof(unsigned long), + 2 * sizeof(unsigned long)); + + /* TAR register */ + if (!ret) + ret = user_regset_copyout(pos, count, kbuf, ubuf, + target-thread.tar, + 2 * sizeof(unsigned long), + 3 * sizeof(unsigned long)); + return ret; +} + +/* + * set_misc_dbg + * + * This function sets miscellaneous debug registers + * which includes DSCR, PPR and TAR. + * + * Userspace intarface buffer layout: + * + * struct { + * unsigned long dscr; + * unsigned long ppr; + * unsigned long tar; + * }; + */ +static int set_misc_dbg(struct task_struct *target, + const struct user_regset *regset, unsigned int pos, + unsigned int count, const void *kbuf, + const void __user *ubuf) +{ + int ret; + + /* Build test */ + BUILD_BUG_ON(TSO(dscr) + 2 * sizeof(unsigned long) != TSO(ppr)); + BUILD_BUG_ON(TSO(ppr) + sizeof(unsigned long) != TSO(tar)); + + /* DSCR register */ + ret = user_regset_copyin(pos, count, kbuf, ubuf, + target-thread.dscr, 0, + sizeof(unsigned long)); + + /* PPR register */ + if (!ret) + ret = user_regset_copyin(pos, count, kbuf, ubuf, + target-thread.ppr, + sizeof(unsigned long), + 2 * sizeof(unsigned long)); + + /* TAR register */ + if (!ret) + ret = user_regset_copyin(pos, count, kbuf, ubuf, + target-thread.tar, + 2 * sizeof(unsigned long), + 3 * sizeof(unsigned long)); + return ret; +} + +/* * These are our native regset flavors. */ enum powerpc_regset { @@ -1347,6 +1438,7 @@ enum powerpc_regset { REGSET_TM_CFPR, /* TM checkpointed FPR registers */ REGSET_TM_CVMX, /* TM checkpointed VMX registers */ #endif + REGSET_MISC /* Miscellaneous debug registers */ }; static const struct user_regset native_regsets[] = { @@ -1403,6 +1495,11 @@ static const struct user_regset native_regsets[] = {
[PATCH V4 8/8] selftests, powerpc: Add new test case for TM related ptrace interfaces
This patch adds one more test case called tm-ptrace targeting TM related ptrace interfaces. This test creates one child process to run some basic transactions and the parent process attaches the child to do some ptrace probing using the recently added regset interfaces. The parent process then compares the received values against the expected values to verify whether it passed the test or not. Signed-off-by: Anshuman Khandual khand...@linux.vnet.ibm.com --- tools/testing/selftests/powerpc/tm/Makefile| 2 +- tools/testing/selftests/powerpc/tm/tm-ptrace.c | 529 + 2 files changed, 530 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/tm/tm-ptrace.c diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index 2cede23..71d400a 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile @@ -1,4 +1,4 @@ -PROGS := tm-resched-dscr +PROGS := tm-resched-dscr tm-ptrace all: $(PROGS) diff --git a/tools/testing/selftests/powerpc/tm/tm-ptrace.c b/tools/testing/selftests/powerpc/tm/tm-ptrace.c new file mode 100644 index 000..858e77e --- /dev/null +++ b/tools/testing/selftests/powerpc/tm/tm-ptrace.c @@ -0,0 +1,529 @@ +/* + * Test program for TM ptrace interface + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Copyright 2014 IBM Corporation + * + * Author: Anshuman Khandual khand...@linux.vnet.ibm.com + */ +#include inttypes.h +#include unistd.h +#include stdlib.h +#include string.h +#include malloc.h +#include errno.h +#include sys/ptrace.h +#include sys/uio.h +#include sys/types.h +#include sys/wait.h +#include sys/signal.h +#include sys/user.h +#include linux/elf.h +#include linux/types.h +#include linux/ptrace.h + +#include utils.h + +#define MAX_OUTPUT 100 + +/* ELF core notes */ +#define NT_PPC_TM_SPR 0x103 /* PowerPC TM special registers */ +#define NT_PPC_TM_CGPR 0x104 /* PowerpC TM checkpointed GPR */ +#define NT_PPC_TM_CFPR 0x105 /* PowerPC TM checkpointed FPR */ +#define NT_PPC_TM_CVMX 0x106 /* PowerPC TM checkpointed VMX */ +#define NT_PPC_MISC0x107 /* PowerPC miscellaneous registers */ + +/* TM instructions */ +#define TBEGIN .long 0x7C00051D ; +#define TEND .long 0x7C00055D ; + +/* SPR number */ +#define SPRN_DSCR 3 +#define SPRN_TAR 815 +#define SPRN_PPR 896 + +#define C_DSCR 10 /* TM checkpointed DSCR */ +#define C_TAR 20 /* TM checkpointed TAR */ +#define C_PPR 0x8 /* TM checkpointed PPR */ + +#define DSCR 50 /* TM running DSCR */ +#define TAR60 /* TM running TAR */ +#define PPR0x4 /* TM running PPR */ + +/* Values for GPR-FPR[0..31] */ +#define VAL0 0 +#define VAL1 1 +#define VAL2 2 +#define VAL3 3 +#define VAL4 4 +#define VAL5 5 +#define VAL6 6 +#define VAL7 7 +#define VAL8 8 +#define VAL9 9 +#define VAL10 10 +#define VAL11 11 +#define VAL12 12 +#define VAL13 13 +#define VAL14 14 +#define VAL15 15 +#define VAL_MAX16 + +/* Standard data types */ +typedef unsigned int u32; +typedef __vector128 vector128; + +/* NT_PPC_TM_SPR buffer layout */ +struct tm_spr_regs { + u64 tm_tfhar; + u64 tm_texasr; + u64 tm_tfiar; + u64 tm_orig_msr; + u64 tm_tar; + u64 tm_ppr; + u64 tm_dscr; +}; + +/* + * NT_PPC_TM_CGPR buffer layout + * + * Same as that of struct pt_regs + */ + +/* NT_PPC_TM_CFPR buffer layout */ +struct tm_cfpr { + u64 fpr[32]; + u64 fpscr; +}; + +/* NT_PPC_TM_CVMX buffer layout */ +struct tm_cvmx { + vector128 vr[32] __attribute__((aligned(16))); + vector128 vscr __attribute__((aligned(16))); + u32 vrsave; +}; + +/* NT_PPC_MISC buffer layout */ +struct misc_regs { + u64 dscr; + u64 ppr; + u64 tar; +}; + +/* + * do_transaction + * + * This functions sets the values for TAR, DSCR, PPR, GPR[0..31], + * FPR[0..31] registers before starting the trasanction which will + * enable the kernel to save them as checkpointed values. Then it + * starts the transaction where it loads a different set of values + * into the same registers again thus enabling the kernel to save + * them off as running values for this transaction. Then the function + * gets stuck forcing the process to loop at one single instruction. + * The transaction never finishes, thus giving the parent process + * the opportunity to trace the running and checkpointed values of + * various registers. + */ +void do_transaction(void) +{ + asm __volatile__( + /* TM checkpointed values */ + + /* SPR */ +
[PATCH V4 3/8] powerpc, process: Merge functions __switch_to_tm and tm_reclaim_task
The function tm_reclaim_task is only called from the function __switch_to_tm. This patch merges these two functions to make it more readable without changing the functionality in any way. Signed-off-by: Anshuman Khandual khand...@linux.vnet.ibm.com --- arch/powerpc/kernel/process.c | 20 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index c36477b..99b41ed 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -585,6 +585,10 @@ static inline void tm_reclaim_task(struct task_struct *tsk) */ struct thread_struct *thr = tsk-thread; + if (!cpu_has_feature(CPU_FTR_TM)) + return; + tm_enable(); + if (!thr-regs) return; @@ -696,14 +700,6 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new) new-pid, mfmsr()); } -static inline void __switch_to_tm(struct task_struct *prev) -{ - if (cpu_has_feature(CPU_FTR_TM)) { - tm_enable(); - tm_reclaim_task(prev); - } -} - /* * This is called if we are on the way out to userspace and the * TIF_RESTORE_TM flag is set. It checks if we need to reload @@ -742,13 +738,13 @@ void restore_tm_state(struct pt_regs *regs) #else #define tm_recheckpoint_new_task(new) -#define __switch_to_tm(prev) +#define tm_reclaim_task(prev) #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ /* * flush_tm_state * - * Flush TM state out so we can copy it. __switch_to_tm() does this + * Flush TM state out so we can copy it. tm_reclaim_task() does this * flush but it removes the checkpointed state from the current CPU and * transitions the CPU out of TM mode. Hence we need to call * tm_recheckpoint_new_task() (on the same task) to restore the @@ -756,7 +752,7 @@ void restore_tm_state(struct pt_regs *regs) */ static void flush_tm_state(struct task_struct *src) { - __switch_to_tm(src); + tm_reclaim_task(src); tm_recheckpoint_new_task(src); } @@ -805,7 +801,7 @@ struct task_struct *__switch_to(struct task_struct *prev, */ save_early_sprs(prev-thread); - __switch_to_tm(prev); + tm_reclaim_task(prev); #ifdef CONFIG_SMP /* avoid complexity of lazy save/restore of fpu -- 1.9.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Fix comment typos in arch/powerpc/include/asm/bitops.h
In arch/powerpc/include/asm/bitops.h, the comments about bit numbers in large ( 1 word) bitmaps have two typos: - On ppc64 system, the LSB of the 4th word should be bit 192 rather than 196, because if it's bit 196, bit 192-195 will be missing in the bitmap. - On ppc32 system, the LSB of the second word should be bit 32 rather than 31, because bit 31 is already in the first word. This patch fixes these typos. Signed-off-by: Boqun Feng boqun.f...@linux.vnet.ibm.com --- arch/powerpc/include/asm/bitops.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index bd3bd57..a39ab08 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h @@ -14,9 +14,9 @@ * * The bitop functions are defined to work on unsigned longs, so for a * ppc64 system the bits end up numbered: - * |63..0|12764|191...128|255...196| + * |63..0|12764|191...128|255...192| * and on ppc32: - * |31.0|6331|9564|127...96|159..128|191..160|223..192|255..224| + * |31.0|6332|9564|127...96|159..128|191..160|223..192|255..224| * * There are a few little-endian macros used mostly for filesystem * bitmaps, these work on similar bit arrays layouts, but -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v6 41/48] powerpc: Register with kernel power-off handler
On Sun, 2014-11-09 at 17:42 -0800, Guenter Roeck wrote: Register with kernel power-off handler instead of setting pm_power_off directly. If there is an indication that there can be more than one power-off handler, use register_power_off_handler, otherwise use register_power_off_handler_simple to register the power-off handler. If the power-off handler only resets or stops the system, select the fallback priority to indicate that the power-off handler is one of last resort. If the power-off handler powers off the system, select the default priority, unless the power-off handler installation code suggests that there can be more than one power-off handler and the new handler is only installed conditionally. In this case, install the handler with low priority. Cc: Alexander Graf ag...@suse.de Cc: Michael Ellerman m...@ellerman.id.au Signed-off-by: Guenter Roeck li...@roeck-us.net Can you fold in the patch below. I know pm.h is included by device.h, so most things will already have it, but I'd rather be explicit. With that you can add my: Acked-by: Michael Ellerman m...@ellerman.id.au cheers diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c index 590d31fbbfc0..adbf36d8c5d9 100644 --- a/arch/powerpc/platforms/44x/ppc476.c +++ b/arch/powerpc/platforms/44x/ppc476.c @@ -24,6 +24,7 @@ #include linux/init.h #include linux/of.h #include linux/of_platform.h +#include linux/pm.h #include linux/rtc.h #include asm/machdep.h diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index 321a7a76eb80..7bdf4e8f7b99 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c @@ -13,6 +13,7 @@ #include generated/utsrelease.h #include linux/pci.h #include linux/of.h +#include linux/pm.h #include asm/dma.h #include asm/prom.h #include asm/time.h diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c index f0c4b5106103..4892491969ab 100644 --- a/arch/powerpc/platforms/85xx/corenet_generic.c +++ b/arch/powerpc/platforms/85xx/corenet_generic.c @@ -16,6 +16,7 @@ #include linux/kdev_t.h #include linux/delay.h #include linux/interrupt.h +#include linux/pm.h #include asm/time.h #include asm/machdep.h diff --git a/arch/powerpc/platforms/cell/celleb_setup.c b/arch/powerpc/platforms/cell/celleb_setup.c index e301b1ae9c2d..1e14047f98d6 100644 --- a/arch/powerpc/platforms/cell/celleb_setup.c +++ b/arch/powerpc/platforms/cell/celleb_setup.c @@ -42,6 +42,7 @@ #include linux/root_dev.h #include linux/console.h #include linux/of_platform.h +#include linux/pm.h #include asm/mmu.h #include asm/processor.h diff --git a/arch/powerpc/platforms/cell/qpace_setup.c b/arch/powerpc/platforms/cell/qpace_setup.c index 223d40a73130..429fefd30e4e 100644 --- a/arch/powerpc/platforms/cell/qpace_setup.c +++ b/arch/powerpc/platforms/cell/qpace_setup.c @@ -22,6 +22,7 @@ #include linux/irq.h #include linux/console.h #include linux/of_platform.h +#include linux/pm.h #include asm/mmu.h #include asm/processor.h diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index ea5460c0b8e7..1203a9d6cd53 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -31,6 +31,7 @@ #include linux/mutex.h #include linux/memory_hotplug.h #include linux/of_platform.h +#include linux/pm.h #include asm/mmu.h #include asm/processor.h diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 0c0288ed0c3b..910bd8b45fae 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -31,6 +31,7 @@ #include linux/root_dev.h #include linux/initrd.h #include linux/timer.h +#include linux/pm.h #include asm/io.h #include asm/pgtable.h diff --git a/arch/powerpc/platforms/embedded6xx/gamecube.c b/arch/powerpc/platforms/embedded6xx/gamecube.c index af40f0fc2579..c90caff045bb 100644 --- a/arch/powerpc/platforms/embedded6xx/gamecube.c +++ b/arch/powerpc/platforms/embedded6xx/gamecube.c @@ -18,6 +18,7 @@ #include linux/kexec.h #include linux/seq_file.h #include linux/of_platform.h +#include linux/pm.h #include asm/io.h #include asm/machdep.h diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c index 0c4dcf86fc7b..e1aec530f0ad 100644 --- a/arch/powerpc/platforms/embedded6xx/linkstation.c +++ b/arch/powerpc/platforms/embedded6xx/linkstation.c @@ -13,6 +13,7 @@ #include linux/kernel.h #include linux/initrd.h #include linux/of_platform.h +#include linux/pm.h #include asm/time.h #include asm/prom.h diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c index eea88245a9de..8c93b95bcc29 100644 --- a/arch/powerpc/platforms/embedded6xx/wii.c +++ b/arch/powerpc/platforms/embedded6xx/wii.c @@ -20,6 +20,7 @@ #include