From patchwork Mon Jul 27 04:39:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Long X-Patchwork-Id: 51481 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f69.google.com (mail-la0-f69.google.com [209.85.215.69]) by patches.linaro.org (Postfix) with ESMTPS id 3B8A622DA5 for ; Mon, 27 Jul 2015 04:39:45 +0000 (UTC) Received: by laah7 with SMTP id h7sf23455443laa.2 for ; Sun, 26 Jul 2015 21:39:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:subject:date :message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=zTrI5FCNeR9x+ahseex9l0agGvhrNh4BzvtHmpzxNtQ=; b=hRLWCAtF14EUDK3/bRcP6W9aLLqx9GbWVr4tNDXQ4aL7ptl9ZGXD+ibdlYpnNNNAOU rq+MSNmDCVgFuWrTuxCuTtayP5f60QZzHKSO3Va5HLfTN0l+K7FKT/TJIWKNrYkTPb0H Q93JiS38cOJMSo7xwR/k62fG1R9J4+CTnHD4xFv5T3D4E9bQQFpWFDp7BbSQqnPdzQT/ CoqaSRVEgQdVX/PXFp3H3Iv58X2JwVLNyvLUWUBlU0VrIZOtULwhG9V+tAvA6vSANSoF 6Qi84W+edeS44QAeuko0JxZ9DTW7XkCSME+x6b80NgG1BLLtpIm5KfC1FJVXu6u1R84s 29LQ== X-Gm-Message-State: ALoCoQnsca/E4k3fXryRghGxgR+LQ7Lrs+Mv0g/9lDxUs2KFs8Osl3wbv5O3+s0meUjxUbaoadnN X-Received: by 10.180.96.137 with SMTP id ds9mr4524201wib.2.1437971984243; Sun, 26 Jul 2015 21:39:44 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.9.232 with SMTP id d8ls603301lab.13.gmail; Sun, 26 Jul 2015 21:39:44 -0700 (PDT) X-Received: by 10.152.115.199 with SMTP id jq7mr25071501lab.113.1437971984059; Sun, 26 Jul 2015 21:39:44 -0700 (PDT) Received: from mail-lb0-f174.google.com (mail-lb0-f174.google.com. [209.85.217.174]) by mx.google.com with ESMTPS id 9si14312288lal.81.2015.07.26.21.39.43 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Jul 2015 21:39:43 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.174 as permitted sender) client-ip=209.85.217.174; Received: by lbbqi7 with SMTP id qi7so45430439lbb.3 for ; Sun, 26 Jul 2015 21:39:43 -0700 (PDT) X-Received: by 10.112.166.2 with SMTP id zc2mr25102918lbb.29.1437971983324; Sun, 26 Jul 2015 21:39:43 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.112.7.198 with SMTP id l6csp1307883lba; Sun, 26 Jul 2015 21:39:42 -0700 (PDT) X-Received: by 10.140.128.206 with SMTP id 197mr40192480qha.23.1437971981558; Sun, 26 Jul 2015 21:39:41 -0700 (PDT) Received: from mail-qk0-f169.google.com (mail-qk0-f169.google.com. [209.85.220.169]) by mx.google.com with ESMTPS id 42si19639764qkx.120.2015.07.26.21.39.41 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Jul 2015 21:39:41 -0700 (PDT) Received-SPF: pass (google.com: domain of dave.long@linaro.org designates 209.85.220.169 as permitted sender) client-ip=209.85.220.169; Received: by qkdl129 with SMTP id l129so35877124qkd.0 for ; Sun, 26 Jul 2015 21:39:41 -0700 (PDT) X-Received: by 10.55.25.35 with SMTP id k35mr37736736qkh.76.1437971980952; Sun, 26 Jul 2015 21:39:40 -0700 (PDT) Received: from localhost.localdomain (pool-72-71-243-249.cncdnh.fast00.myfairpoint.net. [72.71.243.249]) by smtp.googlemail.com with ESMTPSA id 66sm3187178qhy.27.2015.07.26.21.39.39 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 26 Jul 2015 21:39:40 -0700 (PDT) From: David Long To: "H. Peter Anvin" , Andy Lutomirski , Anton Blanchard , Behan Webster , Benjamin Herrenschmidt , Eric Paris , Heiko Carstens , Ingo Molnar , Jan Willeke , Kees Cook , Martin Schwidefsky , Michael Ellerman , Nikolay Borisov , Oleg Nesterov , Paul Mackerras , Richard Kuo , Robert Richter , Roland McGrath , Russell King , Tejun Heo , Thomas Gleixner , Will Deacon , linux-arm-kernel@lists.infradead.org, linux-hexagon@vger.kernel.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, linux-sh@vger.kernel.org, linux390@de.ibm.com, linuxppc-dev@lists.ozlabs.org, x86@kernel.org Subject: [PATCH v2 2/2] Consolidate redundant register/stack access code Date: Mon, 27 Jul 2015 00:39:34 -0400 Message-Id: <1437971974-2434-3-git-send-email-dave.long@linaro.org> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1437971974-2434-1-git-send-email-dave.long@linaro.org> References: <1437971974-2434-1-git-send-email-dave.long@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: dave.long@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.174 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: "David A. Long" Several architectures have identical or functionally equivalent code implementing parts of the HAVE_REGS_AND_STACK_ACCESS_API feature. Move that code out of the architecture directories. Signed-off-by: David A. Long --- arch/arm/include/asm/ptrace.h | 6 --- arch/arm/kernel/ptrace.c | 67 +-------------------------------- arch/hexagon/include/uapi/asm/ptrace.h | 3 -- arch/powerpc/include/asm/ptrace.h | 38 ------------------- arch/powerpc/kernel/ptrace.c | 34 +---------------- arch/s390/include/asm/ptrace.h | 3 -- arch/s390/kernel/ptrace.c | 69 ++++++++++------------------------ arch/sh/include/asm/ptrace.h | 39 ------------------- arch/sh/kernel/Makefile | 2 +- arch/sh/kernel/ptrace.c | 33 ---------------- arch/sh/kernel/ptrace_32.c | 2 +- arch/sh/kernel/ptrace_64.c | 2 +- arch/x86/include/asm/ptrace.h | 37 ------------------ arch/x86/kernel/ptrace.c | 34 +---------------- include/linux/ptrace.h | 42 +++++++++++++++++++++ kernel/ptrace.c | 38 +++++++++++++++++++ 16 files changed, 106 insertions(+), 343 deletions(-) delete mode 100644 arch/sh/kernel/ptrace.c diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 51622ba..84a0ea4 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -120,12 +120,6 @@ extern unsigned long profile_pc(struct pt_regs *regs); #include #define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0)) -extern int regs_query_register_offset(const char *name); -extern const char *regs_query_register_name(unsigned int offset); -extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr); -extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, - unsigned int n); - /** * regs_get_register() - get register value from its offset * @regs: pt_regs from which register value is gotten diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 3b5a2ba..f26e23b 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -63,7 +63,7 @@ #define REG_OFFSET_NAME(r) \ {.name = #r, .offset = offsetof(struct pt_regs, ARM_##r)} -static const struct pt_regs_offset regoffset_table[] = { +const struct pt_regs_offset regs_offset_table[] = { REG_OFFSET_NAME(r0), REG_OFFSET_NAME(r1), REG_OFFSET_NAME(r2), @@ -85,71 +85,6 @@ static const struct pt_regs_offset regoffset_table[] = { REGS_OFFSET_END, }; -/** - * regs_query_register_offset() - query register offset from its name - * @name: the name of a register - * - * regs_query_register_offset() returns the offset of a register in struct - * pt_regs from its name. If the name is invalid, this returns -EINVAL; - */ -int regs_query_register_offset(const char *name) -{ - const struct pt_regs_offset *roff; - for (roff = regoffset_table; roff->name != NULL; roff++) - if (!strcmp(roff->name, name)) - return roff->offset; - return -EINVAL; -} - -/** - * regs_query_register_name() - query register name from its offset - * @offset: the offset of a register in struct pt_regs. - * - * regs_query_register_name() returns the name of a register from its - * offset in struct pt_regs. If the @offset is invalid, this returns NULL; - */ -const char *regs_query_register_name(unsigned int offset) -{ - const struct pt_regs_offset *roff; - for (roff = regoffset_table; roff->name != NULL; roff++) - if (roff->offset == offset) - return roff->name; - return NULL; -} - -/** - * regs_within_kernel_stack() - check the address in the stack - * @regs: pt_regs which contains kernel stack pointer. - * @addr: address which is checked. - * - * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). - * If @addr is within the kernel stack, it returns true. If not, returns false. - */ -bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) -{ - return ((addr & ~(THREAD_SIZE - 1)) == - (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))); -} - -/** - * regs_get_kernel_stack_nth() - get Nth entry of the stack - * @regs: pt_regs which contains kernel stack pointer. - * @n: stack entry number. - * - * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which - * is specified by @regs. If the @n th entry is NOT in the kernel stack, - * this returns 0. - */ -unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) -{ - unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); - addr += n; - if (regs_within_kernel_stack(regs, (unsigned long)addr)) - return *addr; - else - return 0; -} - /* * this routine will get a word off of the processes privileged stack. * the offset is how far from the base addr as stored in the THREAD. diff --git a/arch/hexagon/include/uapi/asm/ptrace.h b/arch/hexagon/include/uapi/asm/ptrace.h index 065e5b3..0afb664 100644 --- a/arch/hexagon/include/uapi/asm/ptrace.h +++ b/arch/hexagon/include/uapi/asm/ptrace.h @@ -29,9 +29,6 @@ #define profile_pc(regs) instruction_pointer(regs) /* kprobe-based event tracer support */ -extern int regs_query_register_offset(const char *name); -extern const char *regs_query_register_name(unsigned int offset); - #define current_pt_regs() \ ((struct pt_regs *) \ ((unsigned long)current_thread_info() + THREAD_SIZE) - 1) diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index c0c61fa..64b9b3d 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h @@ -156,8 +156,6 @@ do { \ #include #include -extern int regs_query_register_offset(const char *name); -extern const char *regs_query_register_name(unsigned int offset); #define MAX_REG_OFFSET (offsetof(struct pt_regs, dsisr)) /** @@ -177,42 +175,6 @@ static inline unsigned long regs_get_register(struct pt_regs *regs, return *(unsigned long *)((unsigned long)regs + offset); } -/** - * regs_within_kernel_stack() - check the address in the stack - * @regs: pt_regs which contains kernel stack pointer. - * @addr: address which is checked. - * - * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). - * If @addr is within the kernel stack, it returns true. If not, returns false. - */ - -static inline bool regs_within_kernel_stack(struct pt_regs *regs, - unsigned long addr) -{ - return ((addr & ~(THREAD_SIZE - 1)) == - (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))); -} - -/** - * regs_get_kernel_stack_nth() - get Nth entry of the stack - * @regs: pt_regs which contains kernel stack pointer. - * @n: stack entry number. - * - * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which - * is specified by @regs. If the @n th entry is NOT in the kernel stack, - * this returns 0. - */ -static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, - unsigned int n) -{ - unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); - addr += n; - if (regs_within_kernel_stack(regs, (unsigned long)addr)) - return *addr; - else - return 0; -} - #endif /* __ASSEMBLY__ */ #ifndef __powerpc64__ diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index b8f054c..47d28f4 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -56,7 +56,7 @@ #define GPR_OFFSET_NAME(num) \ {.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])} -static const struct pt_regs_offset regoffset_table[] = { +const struct pt_regs_offset regs_offset_table[] = { GPR_OFFSET_NAME(0), GPR_OFFSET_NAME(1), GPR_OFFSET_NAME(2), @@ -106,38 +106,6 @@ static const struct pt_regs_offset regoffset_table[] = { REGS_OFFSET_END, }; -/** - * regs_query_register_offset() - query register offset from its name - * @name: the name of a register - * - * regs_query_register_offset() returns the offset of a register in struct - * pt_regs from its name. If the name is invalid, this returns -EINVAL; - */ -int regs_query_register_offset(const char *name) -{ - const struct pt_regs_offset *roff; - for (roff = regoffset_table; roff->name != NULL; roff++) - if (!strcmp(roff->name, name)) - return roff->offset; - return -EINVAL; -} - -/** - * regs_query_register_name() - query register name from its offset - * @offset: the offset of a register in struct pt_regs. - * - * regs_query_register_name() returns the name of a register from its - * offset in struct pt_regs. If the @offset is invalid, this returns NULL; - */ -const char *regs_query_register_name(unsigned int offset) -{ - const struct pt_regs_offset *roff; - for (roff = regoffset_table; roff->name != NULL; roff++) - if (roff->offset == offset) - return roff->name; - return NULL; -} - /* * does not yet catch signals sent when the child dies. * in exit.c or in signal.c. diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 6feda25..d4f9ad3 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -163,10 +163,7 @@ static inline void instruction_pointer_set(struct pt_regs *regs, regs->psw.addr = val | PSW_ADDR_AMODE; } -int regs_query_register_offset(const char *name); -const char *regs_query_register_name(unsigned int offset); unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset); -unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n); static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) { diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index d363c9c..54d1ec3 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -1474,9 +1474,26 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) return &user_s390_view; } -static const char *gpr_names[NUM_GPRS] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", +#define REG_OFFSET_NAME(r) {.name = "r" #r, .offset = r} + +const struct pt_regs_offset regs_offset_table[NUM_GPRS+1] = { + REG_OFFSET_NAME(0), + REG_OFFSET_NAME(1), + REG_OFFSET_NAME(2), + REG_OFFSET_NAME(3), + REG_OFFSET_NAME(4), + REG_OFFSET_NAME(5), + REG_OFFSET_NAME(6), + REG_OFFSET_NAME(7), + REG_OFFSET_NAME(8), + REG_OFFSET_NAME(9), + REG_OFFSET_NAME(10), + REG_OFFSET_NAME(11), + REG_OFFSET_NAME(12), + REG_OFFSET_NAME(13), + REG_OFFSET_NAME(14), + REG_OFFSET_NAME(15), + REGS_OFFSET_END }; unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset) @@ -1485,49 +1502,3 @@ unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset) return 0; return regs->gprs[offset]; } - -int regs_query_register_offset(const char *name) -{ - unsigned long offset; - - if (!name || *name != 'r') - return -EINVAL; - if (kstrtoul(name + 1, 10, &offset)) - return -EINVAL; - if (offset >= NUM_GPRS) - return -EINVAL; - return offset; -} - -const char *regs_query_register_name(unsigned int offset) -{ - if (offset >= NUM_GPRS) - return NULL; - return gpr_names[offset]; -} - -static int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) -{ - unsigned long ksp = kernel_stack_pointer(regs); - - return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1)); -} - -/** - * regs_get_kernel_stack_nth() - get Nth entry of the stack - * @regs:pt_regs which contains kernel stack pointer. - * @n:stack entry number. - * - * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which - * is specifined by @regs. If the @n th entry is NOT in the kernel stack, - * this returns 0. - */ -unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) -{ - unsigned long addr; - - addr = kernel_stack_pointer(regs) + n * sizeof(long); - if (!regs_within_kernel_stack(regs, addr)) - return 0; - return *(unsigned long *)addr; -} diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index 523955f..8045eb4 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -29,10 +29,6 @@ {.name = __stringify(tr##num), .offset = offsetof(struct pt_regs, tregs[num])} /* Query offset/name of register from its name/offset */ -extern int regs_query_register_offset(const char *name); -extern const char *regs_query_register_name(unsigned int offset); - -extern const struct pt_regs_offset regoffset_table[]; /** * regs_get_register() - get register value from its offset @@ -51,41 +47,6 @@ static inline unsigned long regs_get_register(struct pt_regs *regs, return *(unsigned long *)((unsigned long)regs + offset); } -/** - * regs_within_kernel_stack() - check the address in the stack - * @regs: pt_regs which contains kernel stack pointer. - * @addr: address which is checked. - * - * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). - * If @addr is within the kernel stack, it returns true. If not, returns false. - */ -static inline int regs_within_kernel_stack(struct pt_regs *regs, - unsigned long addr) -{ - return ((addr & ~(THREAD_SIZE - 1)) == - (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))); -} - -/** - * regs_get_kernel_stack_nth() - get Nth entry of the stack - * @regs: pt_regs which contains kernel stack pointer. - * @n: stack entry number. - * - * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which - * is specified by @regs. If the @n th entry is NOT in the kernel stack, - * this returns 0. - */ -static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, - unsigned int n) -{ - unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); - addr += n; - if (regs_within_kernel_stack(regs, (unsigned long)addr)) - return *addr; - else - return 0; -} - struct perf_event; struct perf_sample_data; diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 2ccf36c..4ae9a11 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -14,7 +14,7 @@ CFLAGS_REMOVE_return_address.o = -pg obj-y := debugtraps.o dma-nommu.o dumpstack.o \ idle.o io.o irq.o irq_$(BITS).o kdebugfs.o \ machvec.o nmi_debug.o process.o \ - process_$(BITS).o ptrace.o ptrace_$(BITS).o \ + process_$(BITS).o ptrace_$(BITS).o \ reboot.o return_address.o \ setup.o signal_$(BITS).o sys_sh.o \ syscalls_$(BITS).o time.o topology.o traps.o \ diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c deleted file mode 100644 index 0a05983..0000000 --- a/arch/sh/kernel/ptrace.c +++ /dev/null @@ -1,33 +0,0 @@ -#include - -/** - * regs_query_register_offset() - query register offset from its name - * @name: the name of a register - * - * regs_query_register_offset() returns the offset of a register in struct - * pt_regs from its name. If the name is invalid, this returns -EINVAL; - */ -int regs_query_register_offset(const char *name) -{ - const struct pt_regs_offset *roff; - for (roff = regoffset_table; roff->name != NULL; roff++) - if (!strcmp(roff->name, name)) - return roff->offset; - return -EINVAL; -} - -/** - * regs_query_register_name() - query register name from its offset - * @offset: the offset of a register in struct pt_regs. - * - * regs_query_register_name() returns the name of a register from its - * offset in struct pt_regs. If the @offset is invalid, this returns NULL; - */ -const char *regs_query_register_name(unsigned int offset) -{ - const struct pt_regs_offset *roff; - for (roff = regoffset_table; roff->name != NULL; roff++) - if (roff->offset == offset) - return roff->name; - return NULL; -} diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index e6fe4f4..c5c385c 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -276,7 +276,7 @@ static int dspregs_active(struct task_struct *target, } #endif -const struct pt_regs_offset regoffset_table[] = { +const struct pt_regs_offset regs_offset_table[] = { REG_OFFSET_NAME(0), REG_OFFSET_NAME(1), REG_OFFSET_NAME(2), diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index af55bb6..565227ef 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -252,7 +252,7 @@ static int fpregs_active(struct task_struct *target, } #endif -const struct pt_regs_offset regoffset_table[] = { +const struct pt_regs_offset regs_offset_table[] = { REGS_OFFSET_NAME(pc), REGS_OFFSET_NAME(sr), REGS_OFFSET_NAME(syscall_nr), diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 5fabf13..c01247c 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -157,8 +157,6 @@ static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) #include /* Query offset/name of register from its name/offset */ -extern int regs_query_register_offset(const char *name); -extern const char *regs_query_register_name(unsigned int offset); #define MAX_REG_OFFSET (offsetof(struct pt_regs, ss)) /** @@ -187,41 +185,6 @@ static inline unsigned long regs_get_register(struct pt_regs *regs, return *(unsigned long *)((unsigned long)regs + offset); } -/** - * regs_within_kernel_stack() - check the address in the stack - * @regs: pt_regs which contains kernel stack pointer. - * @addr: address which is checked. - * - * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). - * If @addr is within the kernel stack, it returns true. If not, returns false. - */ -static inline int regs_within_kernel_stack(struct pt_regs *regs, - unsigned long addr) -{ - return ((addr & ~(THREAD_SIZE - 1)) == - (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))); -} - -/** - * regs_get_kernel_stack_nth() - get Nth entry of the stack - * @regs: pt_regs which contains kernel stack pointer. - * @n: stack entry number. - * - * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which - * is specified by @regs. If the @n th entry is NOT in the kernel stack, - * this returns 0. - */ -static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, - unsigned int n) -{ - unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); - addr += n; - if (regs_within_kernel_stack(regs, (unsigned long)addr)) - return *addr; - else - return 0; -} - #define arch_has_single_step() (1) #ifdef CONFIG_X86_DEBUGCTLMSR #define arch_has_block_step() (1) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 2efc6aa..0ddabd5 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -54,7 +54,7 @@ enum x86_regset { }; -static const struct pt_regs_offset regoffset_table[] = { +const struct pt_regs_offset regs_offset_table[] = { #ifdef CONFIG_X86_64 REGS_OFFSET_NAME(r15), REGS_OFFSET_NAME(r14), @@ -87,38 +87,6 @@ static const struct pt_regs_offset regoffset_table[] = { REGS_OFFSET_END, }; -/** - * regs_query_register_offset() - query register offset from its name - * @name: the name of a register - * - * regs_query_register_offset() returns the offset of a register in struct - * pt_regs from its name. If the name is invalid, this returns -EINVAL; - */ -int regs_query_register_offset(const char *name) -{ - const struct pt_regs_offset *roff; - for (roff = regoffset_table; roff->name != NULL; roff++) - if (!strcmp(roff->name, name)) - return roff->offset; - return -EINVAL; -} - -/** - * regs_query_register_name() - query register name from its offset - * @offset: the offset of a register in struct pt_regs. - * - * regs_query_register_name() returns the name of a register from its - * offset in struct pt_regs. If the @offset is invalid, this returns NULL; - */ -const char *regs_query_register_name(unsigned int offset) -{ - const struct pt_regs_offset *roff; - for (roff = regoffset_table; roff->name != NULL; roff++) - if (roff->offset == offset) - return roff->name; - return NULL; -} - static const int arg_offs_table[] = { #ifdef CONFIG_X86_32 [0] = offsetof(struct pt_regs, ax), diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index dbb8df1..f3afbf8 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -393,6 +393,48 @@ struct pt_regs_offset { int offset; }; +extern const struct pt_regs_offset regs_offset_table[]; + +extern int regs_query_register_offset(const char *name); +extern const char *regs_query_register_name(unsigned int offset); + +/** + * regs_within_kernel_stack() - check the address in the stack + * @regs: pt_regs which contains kernel stack pointer. + * @addr: address which is checked. + * + * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). + * If @addr is within the kernel stack, it returns true. If not, returns false. + */ + +static inline bool regs_within_kernel_stack(struct pt_regs *regs, + unsigned long addr) +{ + return ((addr & ~(THREAD_SIZE - 1)) == + (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))); +} + +/** + * regs_get_kernel_stack_nth() - get Nth entry of the stack + * @regs: pt_regs which contains kernel stack pointer. + * @n: stack entry number. + * + * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which + * is specified by @regs. If the @n th entry is NOT in the kernel stack, + * this returns 0. + */ +static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, + unsigned int n) +{ + unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); + + addr += n; + if (regs_within_kernel_stack(regs, (unsigned long)addr)) + return *addr; + else + return 0; +} + #endif /* CONFIG_HAVE_REGS_AND_STACK_ACCESS_API */ #endif diff --git a/kernel/ptrace.c b/kernel/ptrace.c index c8e0e05..20c08d9 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -1217,3 +1217,41 @@ COMPAT_SYSCALL_DEFINE4(ptrace, compat_long_t, request, compat_long_t, pid, return ret; } #endif /* CONFIG_COMPAT */ + +#ifdef CONFIG_HAVE_REGS_AND_STACK_ACCESS_API + +/** + * regs_query_register_offset() - query register offset from its name + * @name: the name of a register + * + * regs_query_register_offset() returns the offset of a register in struct + * pt_regs from its name. If the name is invalid, this returns -EINVAL; + */ +int regs_query_register_offset(const char *name) +{ + const struct pt_regs_offset *roff; + + for (roff = regs_offset_table; roff->name != NULL; roff++) + if (!strcmp(roff->name, name)) + return roff->offset; + return -EINVAL; +} + +/** + * regs_query_register_name() - query register name from its offset + * @offset: the offset of a register in struct pt_regs. + * + * regs_query_register_name() returns the name of a register from its + * offset in struct pt_regs. If the @offset is invalid, this returns NULL; + */ +const char *regs_query_register_name(unsigned int offset) +{ + const struct pt_regs_offset *roff; + + for (roff = regs_offset_table; roff->name != NULL; roff++) + if (roff->offset == offset) + return roff->name; + return NULL; +} + +#endif /* CONFIG_HAVE_REGS_AND_STACK_ACCESS_API */