public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: tip-bot for Suresh Siddha <suresh.b.siddha@intel.com>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, hpa@zytor.com, mingo@redhat.com,
	suresh.b.siddha@intel.com, tglx@linutronix.de,
	hjl.tools@gmail.com
Subject: [tip:x86/ptrace] ptrace: Add support for generic PTRACE_GETREGSET/PTRACE_SETREGSET
Date: Tue, 9 Feb 2010 22:55:30 GMT	[thread overview]
Message-ID: <tip-b26d3b32b860e4667df88dc2407f8823e2aa7cc6@git.kernel.org> (raw)
In-Reply-To: <20100209202502.406177090@sbs-t61.sc.intel.com>

Commit-ID:  b26d3b32b860e4667df88dc2407f8823e2aa7cc6
Gitweb:     http://git.kernel.org/tip/b26d3b32b860e4667df88dc2407f8823e2aa7cc6
Author:     Suresh Siddha <suresh.b.siddha@intel.com>
AuthorDate: Tue, 9 Feb 2010 12:13:13 -0800
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Tue, 9 Feb 2010 14:10:07 -0800

ptrace: Add support for generic PTRACE_GETREGSET/PTRACE_SETREGSET

Generic support for PTRACE_GETREGSET/PTRACE_SETREGSET commands which
export the regsets supported by each architecture using the correponding
NT_* types.

'addr' parameter for the ptrace system call encode the REGSET type and
the buffer length. 'data' parameter points to the user buffer.

	ptrace(PTRACE_GETREGSET/PTRACE_SETREGSET, pid,
	       (NT_TYPE << 20) | buf_length, buf);

For more information on how to use this API by users like debuggers and core
dump for accessing xstate registers, etc., please refer to comments in
arch/x86/include/asm/ptrace-abi.h

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
LKML-Reference: <20100209202502.406177090@sbs-t61.sc.intel.com>
Acked-by: Hongjiu Lu <hjl.tools@gmail.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/include/asm/ptrace-abi.h |   50 +++++++++++++++++++++++++++++++++++++
 include/linux/elf.h               |   25 +++++++++++++++++-
 include/linux/ptrace.h            |   14 ++++++++++
 kernel/ptrace.c                   |   34 +++++++++++++++++++++++++
 4 files changed, 121 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/ptrace-abi.h b/arch/x86/include/asm/ptrace-abi.h
index 8672303..965a6ce 100644
--- a/arch/x86/include/asm/ptrace-abi.h
+++ b/arch/x86/include/asm/ptrace-abi.h
@@ -139,4 +139,54 @@ struct ptrace_bts_config {
    Returns number of BTS records drained.
 */
 
+/*
+ * The extended register state using xsave/xrstor infrastructure can be
+ * be read and set by the user using the following ptrace command.
+ *
+ *	ptrace(PTRACE_GETREGSET/PTRACE_SETREGSET, pid,
+ *	       (NT_X86_XSTATE << 20) | xstate_buf_length, xstate_buf);
+ *
+ * The structure layout used for the xstate_buf is same as
+ * the memory layout of xsave used by the processor (except for the bytes
+ * 464..511, which can be used by the software) and hence the size
+ * of this structure varies depending on the features supported by the processor
+ * and OS.  The size of the structure that users need to use can be obtained by
+ * doing:
+ *     cpuid_count(0xd, 0, &eax, &ptrace_xstateregs_struct_size, &ecx, &edx);
+ * i.e., cpuid.(eax=0xd,ecx=0).ebx will be the size that user (debuggers, etc.)
+ * need to use.
+ *
+ * The format of this structure will be like:
+ *	struct {
+ *		fxsave_bytes[0..463]
+ *		sw_usable_bytes[464..511]
+ *		xsave_hdr_bytes[512..575]
+ *		avx_bytes[576..831]
+ *		future_state etc
+ *	}
+ *
+ * The same memory layout will be used for the core-dump NT_X86_XSTATE
+ * note representing the xstate registers.
+ *
+ * For now, only the first 8 bytes of the sw_usable_bytes[464..471] will
+ * be used and will be set to OS enabled xstate mask (which is same as the
+ * 64bit mask returned by the xgetbv's xCR0).  Users (analyzing core dump
+ * remotely, etc.) can use this mask as well as the mask saved in the
+ * xstate_hdr bytes and interpret what states the processor/OS supports
+ * and what states are in modified/initialized conditions for the
+ * particular process/thread.
+ *
+ * Also when the user modifies certain state FP/SSE/etc through this
+ * PTRACE_SETXSTATEREGS, they must ensure that the xsave_hdr.xstate_bv
+ * bytes[512..519] of the above memory layout are updated correspondingly.
+ * i.e., for example when FP state is modified to a non-init state,
+ * xsave_hdr.xstate_bv's bit 0 must be set to '1', when SSE is modified to
+ * non-init state, xsave_hdr.xstate_bv's bit 1 must to be set to '1', etc.
+ */
+
+/*
+ * Enable PTRACE_GETREGSET/PTRACE_SETREGSET interface
+ */
+#define PTRACE_EXPORT_REGSET
+
 #endif /* _ASM_X86_PTRACE_ABI_H */
diff --git a/include/linux/elf.h b/include/linux/elf.h
index a8c4af0..5fd7996 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -349,7 +349,29 @@ typedef struct elf64_shdr {
 #define ELF_OSABI ELFOSABI_NONE
 #endif
 
-/* Notes used in ET_CORE */
+/*
+ * Notes used in ET_CORE. Architectures export some of the arch register sets
+ * using the corresponding note types via ptrace
+ * PTRACE_GETREGSET/PTRACE_SETREGSET requests.
+ *
+ * For example,
+ *	long addr = (NT_X86_XSTATE << 20 | buf_length);
+ *	ptrace(PTRACE_GETREGSET, pid, addr, buf);
+ *
+ * will obtain the x86 extended register state of the pid.
+ *
+ * On 32bit architectures, addr argument is 32bits wide and encodes the length
+ * of the buffer in the first 20 bits, followed by NT_* type encoded in the
+ * remaining 12 bits, representing an unique regset.
+ *
+ * Hence on 32bit architectures, NT_PRXFPREG (0x46e62b7f) will be seen as 0xb7f
+ * and we can't allocate 0xb7f to any other note.
+ *
+ * All the other existing NT_* types fall with in the 12 bits and we have
+ * plenty of room for more NT_* types. For now, on all architectures
+ * we use first 20 bits of the addr for the buffer size and the next 12 bits for
+ * the NT_* type representing the corresponding regset.
+ */
 #define NT_PRSTATUS	1
 #define NT_PRFPREG	2
 #define NT_PRPSINFO	3
@@ -364,7 +386,6 @@ typedef struct elf64_shdr {
 #define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */
 #define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves */
 
-
 /* Note header in a PT_NOTE section */
 typedef struct elf32_note {
   Elf32_Word	n_namesz;	/* Name size */
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 56f2d63..4522e5e 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -26,6 +26,18 @@
 #define PTRACE_GETEVENTMSG	0x4201
 #define PTRACE_GETSIGINFO	0x4202
 #define PTRACE_SETSIGINFO	0x4203
+#define PTRACE_GETREGSET	0x4204
+#define PTRACE_SETREGSET	0x4205
+
+/*
+ * First 20 bits of the addr in the PTRACE_GETREGSET/PTRACE_SETREGSET requests
+ * are reserved for communicating the user buffer size and the remaining 12 bits
+ * are reserved for the NT_* types (defined in include/linux/elf.h) which
+ * indicate the regset that the ptrace user is interested in.
+ */
+#define PTRACE_REGSET_BUF_SIZE(addr)	(addr & 0xfffff)
+#define PTRACE_REGSET_TYPE(addr)	((addr >> 20) & 0xfff)
+#define NOTE_TO_REGSET_TYPE(note)	(note & 0xfff)
 
 /* options set using PTRACE_SETOPTIONS */
 #define PTRACE_O_TRACESYSGOOD	0x00000001
@@ -114,6 +126,8 @@ static inline void ptrace_unlink(struct task_struct *child)
 
 int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data);
 int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data);
+int generic_ptrace_regset(struct task_struct *child, long request, long addr,
+			  long data);
 
 /**
  * task_ptrace - return %PT_* flags that apply to a task
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 23bd09c..7040208 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -22,6 +22,7 @@
 #include <linux/pid_namespace.h>
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
+#include <linux/regset.h>
 
 
 /*
@@ -573,6 +574,11 @@ int ptrace_request(struct task_struct *child, long request,
 			return 0;
 		return ptrace_resume(child, request, SIGKILL);
 
+#ifdef PTRACE_EXPORT_REGSET
+	case PTRACE_GETREGSET:
+	case PTRACE_SETREGSET:
+		return generic_ptrace_regset(child, request, addr, data);
+#endif
 	default:
 		break;
 	}
@@ -664,6 +670,34 @@ int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data)
 	return (copied == sizeof(data)) ? 0 : -EIO;
 }
 
+#ifdef PTRACE_EXPORT_REGSET
+int generic_ptrace_regset(struct task_struct *child, long request, long addr,
+			  long data)
+{
+	const struct user_regset_view *view = task_user_regset_view(child);
+	unsigned int buf_size = PTRACE_REGSET_BUF_SIZE(addr);
+	int setno;
+
+	for (setno = 0; setno < view->n; setno++) {
+		const struct user_regset *regset = &view->regsets[setno];
+		if (NOTE_TO_REGSET_TYPE(regset->core_note_type) !=
+		    PTRACE_REGSET_TYPE(addr))
+			continue;
+
+		if (request == PTRACE_GETREGSET)
+			return copy_regset_to_user(child, view, setno, 0,
+						   buf_size,
+						   (void __user *) data);
+		else if (request == PTRACE_SETREGSET)
+			return copy_regset_from_user(child, view, setno, 0,
+						     buf_size,
+						     (void __user *) data);
+	}
+
+	return -EIO;
+}
+#endif
+
 #if defined CONFIG_COMPAT
 #include <linux/compat.h>
 

  reply	other threads:[~2010-02-09 22:56 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-09 20:13 [patch v2 0/4] updated ptrace/core-dump patches for supporting xstate - V2 Suresh Siddha
2010-02-09 20:13 ` [patch v2 1/4] revert "x86: ptrace and core-dump extensions for xstate" Suresh Siddha
2010-02-09 22:54   ` [tip:x86/ptrace] Revert " tip-bot for Suresh Siddha
2010-02-09 20:13 ` [patch v2 2/4] x86, ptrace: regset extensions to support xstate Suresh Siddha
2010-02-09 22:54   ` [tip:x86/ptrace] x86, ptrace: Regset " tip-bot for Suresh Siddha
2010-02-10  1:30   ` [patch v2 2/4] x86, ptrace: regset " Roland McGrath
2010-02-10 10:44     ` Oleg Nesterov
2010-02-10 11:28   ` Oleg Nesterov
2010-02-10 15:43     ` Oleg Nesterov
2010-02-10 18:26       ` Roland McGrath
2010-02-10 14:18   ` Oleg Nesterov
2010-02-10 15:34     ` Oleg Nesterov
2010-02-09 20:13 ` [patch v2 3/4] x86, ptrace: prepare regset get/set routines for user specified lengths Suresh Siddha
2010-02-09 22:55   ` [tip:x86/ptrace] x86, ptrace: Prepare " tip-bot for Suresh Siddha
2010-02-10  1:32   ` [patch v2 3/4] x86, ptrace: prepare " Roland McGrath
2010-02-09 20:13 ` [patch v2 4/4] ptrace: Add support for generic PTRACE_GETREGSET/PTRACE_SETREGSET Suresh Siddha
2010-02-09 22:55   ` tip-bot for Suresh Siddha [this message]
2010-02-10  1:52   ` Roland McGrath
2010-02-10  2:03     ` H.J. Lu
2010-02-10  3:07       ` Roland McGrath
2010-02-10  4:24         ` H.J. Lu
2010-02-10 13:18   ` Oleg Nesterov
2010-02-10 19:12     ` Roland McGrath
2010-02-11  2:17       ` H. Peter Anvin
2010-02-11  3:30         ` Roland McGrath
2010-02-10  1:12 ` [patch v2 0/4] updated ptrace/core-dump patches for supporting xstate - V2 Roland McGrath
2010-02-10  1:22   ` Suresh Siddha
2010-02-10  7:27   ` Ingo Molnar
2010-02-10 18:58     ` Roland McGrath
2010-02-11  2:18       ` H. Peter Anvin
2010-02-11  3:45         ` Roland McGrath
2010-02-11  4:16           ` H. Peter Anvin
  -- strict thread matches above, loose matches on Subject: below --
2010-02-11 19:51 [patch v3 2/2] ptrace: Add support for generic PTRACE_GETREGSET/PTRACE_SETREGSET Suresh Siddha
2010-02-11 23:19 ` [tip:x86/ptrace] " tip-bot for Suresh Siddha
2010-02-22  9:07   ` Ingo Molnar
2010-02-22 18:37     ` Roland McGrath

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tip-b26d3b32b860e4667df88dc2407f8823e2aa7cc6@git.kernel.org \
    --to=suresh.b.siddha@intel.com \
    --cc=hjl.tools@gmail.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox