From 1b788400bbcbfe25280dc0b8000d2142bfe3be3b Mon Sep 17 00:00:00 2001 From: "K.Prasad" Date: Thu, 10 May 2012 22:43:38 +0000 Subject: powerpc/hw-breakpoint: Use generic hw-breakpoint interfaces for new PPC ptrace flags PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG and PPC_PTRACE_DELHWDEBUG are PowerPC specific ptrace flags that use the watchpoint register. While they are targeted primarily towards BookE users, user-space applications such as GDB have started using them for BookS too. This patch enables the use of generic hardware breakpoint interfaces for these new flags. Apart from the usual benefits of using generic hw-breakpoint interfaces, these changes allow debuggers (such as GDB) to use a common set of ptrace flags for their watchpoint needs and allow more precise breakpoint specification (length of the variable can be specified). Signed-off-by: K.Prasad Acked-by: David Gibson Signed-off-by: Benjamin Herrenschmidt --- Documentation/powerpc/ptrace.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'Documentation') diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt index f4a5499b7bc6..f2a7a3919772 100644 --- a/Documentation/powerpc/ptrace.txt +++ b/Documentation/powerpc/ptrace.txt @@ -127,6 +127,22 @@ Some examples of using the structure to: p.addr2 = (uint64_t) end_range; p.condition_value = 0; +- set a watchpoint in server processors (BookS) + + p.version = 1; + p.trigger_type = PPC_BREAKPOINT_TRIGGER_RW; + p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE; + or + p.addr_mode = PPC_BREAKPOINT_MODE_EXACT; + + p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; + p.addr = (uint64_t) begin_range; + /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where + * addr2 - addr <= 8 Bytes. + */ + p.addr2 = (uint64_t) end_range; + p.condition_value = 0; + 3. PTRACE_DELHWDEBUG Takes an integer which identifies an existing breakpoint or watchpoint -- cgit v1.2.3 From 175e0e23466185a861339796efc5b51958a48dc1 Mon Sep 17 00:00:00 2001 From: Kent Yoder Date: Thu, 12 Apr 2012 05:38:54 +0000 Subject: powerpc/crypto: debugfs routines and docs for the nx device driver These routines add debugfs files supporting the Power7+ in-Nest encryption accelerator driver. Signed-off-by: Kent Yoder Signed-off-by: Benjamin Herrenschmidt --- Documentation/ABI/testing/debugfs-pfo-nx-crypto | 45 +++++++++++ drivers/crypto/nx/nx_debugfs.c | 103 ++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 Documentation/ABI/testing/debugfs-pfo-nx-crypto create mode 100644 drivers/crypto/nx/nx_debugfs.c (limited to 'Documentation') diff --git a/Documentation/ABI/testing/debugfs-pfo-nx-crypto b/Documentation/ABI/testing/debugfs-pfo-nx-crypto new file mode 100644 index 000000000000..685d5a448423 --- /dev/null +++ b/Documentation/ABI/testing/debugfs-pfo-nx-crypto @@ -0,0 +1,45 @@ +What: /sys/kernel/debug/nx-crypto/* +Date: March 2012 +KernelVersion: 3.4 +Contact: Kent Yoder +Description: + + These debugfs interfaces are built by the nx-crypto driver, built in +arch/powerpc/crypto/nx. + +Error Detection +=============== + +errors: +- A u32 providing a total count of errors since the driver was loaded. The +only errors counted here are those returned from the hcall, H_COP_OP. + +last_error: +- The most recent non-zero return code from the H_COP_OP hcall. -EBUSY is not +recorded here (the hcall will retry until -EBUSY goes away). + +last_error_pid: +- The process ID of the process who received the most recent error from the +hcall. + +Device Use +========== + +aes_bytes: +- The total number of bytes encrypted using AES in any of the driver's +supported modes. + +aes_ops: +- The total number of AES operations submitted to the hardware. + +sha256_bytes: +- The total number of bytes hashed by the hardware using SHA-256. + +sha256_ops: +- The total number of SHA-256 operations submitted to the hardware. + +sha512_bytes: +- The total number of bytes hashed by the hardware using SHA-512. + +sha512_ops: +- The total number of SHA-512 operations submitted to the hardware. diff --git a/drivers/crypto/nx/nx_debugfs.c b/drivers/crypto/nx/nx_debugfs.c new file mode 100644 index 000000000000..7ab2e8dcd9b4 --- /dev/null +++ b/drivers/crypto/nx/nx_debugfs.c @@ -0,0 +1,103 @@ +/** + * debugfs routines supporting the Power 7+ Nest Accelerators driver + * + * Copyright (C) 2011-2012 International Business Machines Inc. + * + * 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; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Kent Yoder + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nx_csbcpb.h" +#include "nx.h" + +#ifdef CONFIG_DEBUG_FS + +/* + * debugfs + * + * For documentation on these attributes, please see: + * + * Documentation/ABI/testing/debugfs-pfo-nx-crypto + */ + +int nx_debugfs_init(struct nx_crypto_driver *drv) +{ + struct nx_debugfs *dfs = &drv->dfs; + + dfs->dfs_root = debugfs_create_dir(NX_NAME, NULL); + + dfs->dfs_aes_ops = + debugfs_create_u32("aes_ops", + S_IRUSR | S_IRGRP | S_IROTH, + dfs->dfs_root, (u32 *)&drv->stats.aes_ops); + dfs->dfs_sha256_ops = + debugfs_create_u32("sha256_ops", + S_IRUSR | S_IRGRP | S_IROTH, + dfs->dfs_root, + (u32 *)&drv->stats.sha256_ops); + dfs->dfs_sha512_ops = + debugfs_create_u32("sha512_ops", + S_IRUSR | S_IRGRP | S_IROTH, + dfs->dfs_root, + (u32 *)&drv->stats.sha512_ops); + dfs->dfs_aes_bytes = + debugfs_create_u64("aes_bytes", + S_IRUSR | S_IRGRP | S_IROTH, + dfs->dfs_root, + (u64 *)&drv->stats.aes_bytes); + dfs->dfs_sha256_bytes = + debugfs_create_u64("sha256_bytes", + S_IRUSR | S_IRGRP | S_IROTH, + dfs->dfs_root, + (u64 *)&drv->stats.sha256_bytes); + dfs->dfs_sha512_bytes = + debugfs_create_u64("sha512_bytes", + S_IRUSR | S_IRGRP | S_IROTH, + dfs->dfs_root, + (u64 *)&drv->stats.sha512_bytes); + dfs->dfs_errors = + debugfs_create_u32("errors", + S_IRUSR | S_IRGRP | S_IROTH, + dfs->dfs_root, (u32 *)&drv->stats.errors); + dfs->dfs_last_error = + debugfs_create_u32("last_error", + S_IRUSR | S_IRGRP | S_IROTH, + dfs->dfs_root, + (u32 *)&drv->stats.last_error); + dfs->dfs_last_error_pid = + debugfs_create_u32("last_error_pid", + S_IRUSR | S_IRGRP | S_IROTH, + dfs->dfs_root, + (u32 *)&drv->stats.last_error_pid); + return 0; +} + +void +nx_debugfs_fini(struct nx_crypto_driver *drv) +{ + debugfs_remove_recursive(drv->dfs.dfs_root); +} + +#endif -- cgit v1.2.3 From 6749ef0b8b1f8aa72cc93c874edef39f4c0533ba Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 21 May 2012 10:44:12 +1000 Subject: Revert "powerpc/hw-breakpoint: Use generic hw-breakpoint interfaces for new PPC ptrace flags" This reverts commit 1b788400bbcbfe25280dc0b8000d2142bfe3be3b. It causes oopses when passed incorrect arguments and has a design fault using IPIs with interrupts disabled. Signed-off-by: Benjamin Herrenschmidt --- --- Documentation/powerpc/ptrace.txt | 16 --------- arch/powerpc/kernel/ptrace.c | 77 ++++------------------------------------ 2 files changed, 6 insertions(+), 87 deletions(-) (limited to 'Documentation') diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt index f2a7a3919772..f4a5499b7bc6 100644 --- a/Documentation/powerpc/ptrace.txt +++ b/Documentation/powerpc/ptrace.txt @@ -127,22 +127,6 @@ Some examples of using the structure to: p.addr2 = (uint64_t) end_range; p.condition_value = 0; -- set a watchpoint in server processors (BookS) - - p.version = 1; - p.trigger_type = PPC_BREAKPOINT_TRIGGER_RW; - p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE; - or - p.addr_mode = PPC_BREAKPOINT_MODE_EXACT; - - p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; - p.addr = (uint64_t) begin_range; - /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where - * addr2 - addr <= 8 Bytes. - */ - p.addr2 = (uint64_t) end_range; - p.condition_value = 0; - 3. PTRACE_DELHWDEBUG Takes an integer which identifies an existing breakpoint or watchpoint diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 8643ac890235..ac3cb008fb31 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -1336,12 +1336,6 @@ static int set_dac_range(struct task_struct *child, static long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) { -#ifdef CONFIG_HAVE_HW_BREAKPOINT - int len = 0; - struct thread_struct *thread = &(child->thread); - struct perf_event *bp; - struct perf_event_attr attr; -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ #ifndef CONFIG_PPC_ADV_DEBUG_REGS unsigned long dabr; #endif @@ -1385,9 +1379,13 @@ static long ppc_set_hwdebug(struct task_struct *child, */ if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 || (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 || + bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT || bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE) return -EINVAL; + if (child->thread.dabr) + return -ENOSPC; + if ((unsigned long)bp_info->addr >= TASK_SIZE) return -EIO; @@ -1397,63 +1395,15 @@ static long ppc_set_hwdebug(struct task_struct *child, dabr |= DABR_DATA_READ; if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) dabr |= DABR_DATA_WRITE; -#ifdef CONFIG_HAVE_HW_BREAKPOINT - if (ptrace_get_breakpoints(child) < 0) - return -ESRCH; - - /* - * Check if the request is for 'range' breakpoints. We can - * support it if range < 8 bytes. - */ - if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) { - len = bp_info->addr2 - bp_info->addr; - } else if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) { - ptrace_put_breakpoints(child); - return -EINVAL; - } - bp = thread->ptrace_bps[0]; - if (bp) { - ptrace_put_breakpoints(child); - return -ENOSPC; - } - - /* Create a new breakpoint request if one doesn't exist already */ - hw_breakpoint_init(&attr); - attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIGN; - attr.bp_len = len; - arch_bp_generic_fields(dabr & (DABR_DATA_WRITE | DABR_DATA_READ), - &attr.bp_type); - - thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr, - ptrace_triggered, NULL, child); - if (IS_ERR(bp)) { - thread->ptrace_bps[0] = NULL; - ptrace_put_breakpoints(child); - return PTR_ERR(bp); - } - - ptrace_put_breakpoints(child); - return 1; -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ - - if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) - return -EINVAL; - - if (child->thread.dabr) - return -ENOSPC; child->thread.dabr = dabr; + return 1; #endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */ } static long ppc_del_hwdebug(struct task_struct *child, long addr, long data) { -#ifdef CONFIG_HAVE_HW_BREAKPOINT - int ret = 0; - struct thread_struct *thread = &(child->thread); - struct perf_event *bp; -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ #ifdef CONFIG_PPC_ADV_DEBUG_REGS int rc; @@ -1473,25 +1423,10 @@ static long ppc_del_hwdebug(struct task_struct *child, long addr, long data) #else if (data != 1) return -EINVAL; - -#ifdef CONFIG_HAVE_HW_BREAKPOINT - if (ptrace_get_breakpoints(child) < 0) - return -ESRCH; - - bp = thread->ptrace_bps[0]; - if (bp) { - unregister_hw_breakpoint(bp); - thread->ptrace_bps[0] = NULL; - } else - ret = -ENOENT; - ptrace_put_breakpoints(child); - return ret; -#else /* CONFIG_HAVE_HW_BREAKPOINT */ if (child->thread.dabr == 0) return -ENOENT; child->thread.dabr = 0; -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ return 0; #endif @@ -1598,7 +1533,7 @@ long arch_ptrace(struct task_struct *child, long request, dbginfo.data_bp_alignment = 4; #endif dbginfo.sizeof_condition = 0; - dbginfo.features = PPC_DEBUG_FEATURE_DATA_BP_RANGE; + dbginfo.features = 0; #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ if (!access_ok(VERIFY_WRITE, datavp, -- cgit v1.2.3