From patchwork Mon Jun 15 16:42:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Long X-Patchwork-Id: 49892 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f70.google.com (mail-la0-f70.google.com [209.85.215.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id C6134205DE for ; Mon, 15 Jun 2015 16:43:09 +0000 (UTC) Received: by laka10 with SMTP id a10sf6111981lak.2 for ; Mon, 15 Jun 2015 09:43:08 -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=Oac50nrh7gZXIXlvy9wI4qzRaGrp8Ap5QunkxHcnX8A=; b=X+eQvGlcrcvNxz13LiEOTBfhk6K+CPSnNzOuT5dSo7wgA0ZycqlvHbMPIAYtaVEEZ9 5LdQejahIJFecZIzsFEo+92TRwWTfLUIAxs6sm9+6UODgmK/a13/51OE8sesemNvbbcM hHVdeme3aFcfmEJ43ykkcvx9/7CzzZkYMFVpwWaRLiLzVQtaKUa/tX4wpyyDJgZmEqVX vOa/0LfojGeuEZNxn4E5hiVlFE6s4dPruY/3yhjYeFLKYXFnA38Yf8ixGUfrxqNCKwmp /2DSQm1WMMP9JUz9r+kUfTLVdwnck2VMLkGVptyxBeML+wyM1FL0KR9vyYHYtpv1NhIU 6gWw== X-Gm-Message-State: ALoCoQmr97F1EMWSLryrCCHRwVLGmNGgwE+64PUU4VqqK3gOMxX/X3UA+sMNfnyQdeyfXd1X7Cc4 X-Received: by 10.180.90.106 with SMTP id bv10mr20357886wib.6.1434386588837; Mon, 15 Jun 2015 09:43:08 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.44.228 with SMTP id h4ls929734lam.23.gmail; Mon, 15 Jun 2015 09:43:08 -0700 (PDT) X-Received: by 10.112.162.70 with SMTP id xy6mr1119858lbb.122.1434386588654; Mon, 15 Jun 2015 09:43:08 -0700 (PDT) Received: from mail-la0-f49.google.com (mail-la0-f49.google.com. [209.85.215.49]) by mx.google.com with ESMTPS id s10si10900765laj.84.2015.06.15.09.43.08 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Jun 2015 09:43:08 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.49 as permitted sender) client-ip=209.85.215.49; Received: by labbc20 with SMTP id bc20so25538764lab.1 for ; Mon, 15 Jun 2015 09:43:08 -0700 (PDT) X-Received: by 10.112.131.98 with SMTP id ol2mr1147414lbb.56.1434386588542; Mon, 15 Jun 2015 09:43:08 -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.108.230 with SMTP id hn6csp1538730lbb; Mon, 15 Jun 2015 09:43:07 -0700 (PDT) X-Received: by 10.140.92.132 with SMTP id b4mr36399737qge.93.1434386586591; Mon, 15 Jun 2015 09:43:06 -0700 (PDT) Received: from mail-qg0-f50.google.com (mail-qg0-f50.google.com. [209.85.192.50]) by mx.google.com with ESMTPS id m70si6007360qhb.89.2015.06.15.09.43.06 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Jun 2015 09:43:06 -0700 (PDT) Received-SPF: pass (google.com: domain of dave.long@linaro.org designates 209.85.192.50 as permitted sender) client-ip=209.85.192.50; Received: by qged89 with SMTP id d89so8859246qge.0 for ; Mon, 15 Jun 2015 09:43:06 -0700 (PDT) X-Received: by 10.55.43.170 with SMTP id r42mr14801226qkr.95.1434386585899; Mon, 15 Jun 2015 09:43:05 -0700 (PDT) Received: from localhost.localdomain (pool-72-71-243-249.cncdnh.fast00.myfairpoint.net. [72.71.243.249]) by mx.google.com with ESMTPSA id 67sm6544026qkx.38.2015.06.15.09.43.04 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 15 Jun 2015 09:43:05 -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 2/2] Consolidate redundant register/stack access code Date: Mon, 15 Jun 2015 12:42:59 -0400 Message-Id: <1434386579-6045-3-git-send-email-dave.long@linaro.org> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1434386579-6045-1-git-send-email-dave.long@linaro.org> References: <1434386579-6045-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.215.49 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 | 70 ++++++++++------------------------ 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, 107 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 fb45cf1..d63ad99 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -63,7 +63,7 @@ {.name = #r, .offset = offsetof(struct pt_regs, ARM_##r)} #define REG_OFFSET_END {.name = NULL, .offset = 0} -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[] = { REG_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 ab81733..e35c731 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -58,7 +58,7 @@ {.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])} #define REG_OFFSET_END {.name = NULL, .offset = 0} -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), @@ -108,38 +108,6 @@ static const struct pt_regs_offset regoffset_table[] = { REG_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..a7eb15f 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -1474,9 +1474,27 @@ 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} +#define REG_OFFSET_END {.name = NULL, .offset = 0} + +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), + REG_OFFSET_END }; unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset) @@ -1485,49 +1503,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 677c72b..acfdc81 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -31,10 +31,6 @@ #define REG_OFFSET_END {.name = NULL, .offset = 0} /* 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 @@ -53,41 +49,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 c1a6b89..839f4e7 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[] = { REGS_OFFSET_NAME(0), REGS_OFFSET_NAME(1), REGS_OFFSET_NAME(2), diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index 5cea973..68faa1f 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[] = { REG_OFFSET_NAME(pc), REG_OFFSET_NAME(sr), REG_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 f135d35..9daab75 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -56,7 +56,7 @@ enum x86_regset { #define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)} #define REG_OFFSET_END {.name = NULL, .offset = 0} -static const struct pt_regs_offset regoffset_table[] = { +const struct pt_regs_offset regs_offset_table[] = { #ifdef CONFIG_X86_64 REG_OFFSET_NAME(r15), REG_OFFSET_NAME(r14), @@ -89,38 +89,6 @@ static const struct pt_regs_offset regoffset_table[] = { REG_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 b0b1ee6..055d9ac 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -390,6 +390,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 */