2005-04-16 18:20:36 -04:00
|
|
|
#ifndef _I386_PTRACE_H
|
|
|
|
#define _I386_PTRACE_H
|
|
|
|
|
[PATCH] Split i386 and x86_64 ptrace.h
The use of SEGMENT_RPL_MASK in the i386 ptrace.h introduced by
x86-allow-a-kernel-to-not-be-in-ring-0.patch broke the UML build, as UML
includes the underlying architecture's ptrace.h, but has no easy access to the
x86 segment definitions.
Rather than kludging around this, as in the past, this patch splits the
userspace-usable parts, which are the bits that UML needs, of ptrace.h into
ptrace-abi.h, which is included back into ptrace.h. Thus, there is no net
effect on i386.
As a side-effect, this creates a ptrace header which is close to being usable
in /usr/include.
x86_64 is also treated in this way for consistency. There was some trailing
whitespace there, which is cleaned up.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-09-26 02:33:09 -04:00
|
|
|
#include <asm/ptrace-abi.h>
|
2005-04-16 18:20:36 -04:00
|
|
|
|
|
|
|
/* this struct defines the way the registers are stored on the
|
|
|
|
stack during a system call. */
|
|
|
|
|
|
|
|
struct pt_regs {
|
|
|
|
long ebx;
|
|
|
|
long ecx;
|
|
|
|
long edx;
|
|
|
|
long esi;
|
|
|
|
long edi;
|
|
|
|
long ebp;
|
|
|
|
long eax;
|
|
|
|
int xds;
|
|
|
|
int xes;
|
[PATCH] i386: Use %gs as the PDA base-segment in the kernel
This patch is the meat of the PDA change. This patch makes several related
changes:
1: Most significantly, %gs is now used in the kernel. This means that on
entry, the old value of %gs is saved away, and it is reloaded with
__KERNEL_PDA.
2: entry.S constructs the stack in the shape of struct pt_regs, and this
is passed around the kernel so that the process's saved register
state can be accessed.
Unfortunately struct pt_regs doesn't currently have space for %gs
(or %fs). This patch extends pt_regs to add space for gs (no space
is allocated for %fs, since it won't be used, and it would just
complicate the code in entry.S to work around the space).
3: Because %gs is now saved on the stack like %ds, %es and the integer
registers, there are a number of places where it no longer needs to
be handled specially; namely context switch, and saving/restoring the
register state in a signal context.
4: And since kernel threads run in kernel space and call normal kernel
code, they need to be created with their %gs == __KERNEL_PDA.
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Chuck Ebbert <76306.1226@compuserve.com>
Cc: Zachary Amsden <zach@vmware.com>
Cc: Jan Beulich <jbeulich@novell.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
2006-12-06 20:14:02 -05:00
|
|
|
/* int xfs; */
|
|
|
|
int xgs;
|
2005-04-16 18:20:36 -04:00
|
|
|
long orig_eax;
|
|
|
|
long eip;
|
|
|
|
int xcs;
|
|
|
|
long eflags;
|
|
|
|
long esp;
|
|
|
|
int xss;
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef __KERNEL__
|
2005-07-27 14:43:25 -04:00
|
|
|
|
|
|
|
#include <asm/vm86.h>
|
2006-09-26 04:52:39 -04:00
|
|
|
#include <asm/segment.h>
|
2005-07-27 14:43:25 -04:00
|
|
|
|
2005-04-16 18:20:36 -04:00
|
|
|
struct task_struct;
|
|
|
|
extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
|
2005-07-26 21:57:24 -04:00
|
|
|
|
2005-09-03 18:56:43 -04:00
|
|
|
/*
|
|
|
|
* user_mode_vm(regs) determines whether a register set came from user mode.
|
|
|
|
* This is true if V8086 mode was enabled OR if the register set was from
|
|
|
|
* protected mode with RPL-3 CS value. This tricky test checks that with
|
|
|
|
* one comparison. Many places in the kernel can bypass this full check
|
|
|
|
* if they have already ruled out V8086 mode, so user_mode(regs) can be used.
|
|
|
|
*/
|
2005-07-26 21:57:24 -04:00
|
|
|
static inline int user_mode(struct pt_regs *regs)
|
|
|
|
{
|
2006-09-26 04:52:39 -04:00
|
|
|
return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
|
2005-07-26 21:57:24 -04:00
|
|
|
}
|
|
|
|
static inline int user_mode_vm(struct pt_regs *regs)
|
|
|
|
{
|
2006-09-26 04:52:39 -04:00
|
|
|
return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
|
2005-07-26 21:57:24 -04:00
|
|
|
}
|
2006-10-02 05:17:31 -04:00
|
|
|
|
2005-04-16 18:20:36 -04:00
|
|
|
#define instruction_pointer(regs) ((regs)->eip)
|
2006-10-02 05:17:31 -04:00
|
|
|
#define regs_return_value(regs) ((regs)->eax)
|
|
|
|
|
2005-04-16 18:20:36 -04:00
|
|
|
extern unsigned long profile_pc(struct pt_regs *regs);
|
2005-07-26 21:57:24 -04:00
|
|
|
#endif /* __KERNEL__ */
|
2005-04-16 18:20:36 -04:00
|
|
|
|
|
|
|
#endif
|