diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2006-09-26 04:52:39 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-26 04:52:39 -0400 |
commit | 78be3706b21a232310590fe00258b224177ac05f (patch) | |
tree | 57dbe444e57241613067145b04c0e15c98278cd6 /include/asm-i386/ptrace.h | |
parent | 0da5db313317e3195482d3e660a1074857374a89 (diff) |
[PATCH] i386: Allow a kernel not to be in ring 0
We allow for the fact that the guest kernel may not run in ring 0. This
requires some abstraction in a few places when setting %cs or checking
privilege level (user vs kernel).
This is Chris' [RFC PATCH 15/33] move segment checks to subarch, except rather
than using #define USER_MODE_MASK which depends on a config option, we use
Zach's more flexible approach of assuming ring 3 == userspace. I also used
"get_kernel_rpl()" over "get_kernel_cs()" because I think it reads better in
the code...
1) Remove the hardcoded 3 and introduce #define SEGMENT_RPL_MASK 3 2) Add a
get_kernel_rpl() macro, and don't assume it's zero.
And:
Clean up of patch for letting kernel run other than ring 0:
a. Add some comments about the SEGMENT_IS_*_CODE() macros.
b. Add a USER_RPL macro. (Code was comparing a value to a mask
in some places and to the magic number 3 in other places.)
c. Add macros for table indicator field and use them.
d. Change the entry.S tests for LDT stack segment to use the macros
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Zachary Amsden <zach@vmware.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'include/asm-i386/ptrace.h')
-rw-r--r-- | include/asm-i386/ptrace.h | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h index 30a442ec2059..21bb91679c82 100644 --- a/include/asm-i386/ptrace.h +++ b/include/asm-i386/ptrace.h | |||
@@ -60,6 +60,7 @@ struct pt_regs { | |||
60 | #ifdef __KERNEL__ | 60 | #ifdef __KERNEL__ |
61 | 61 | ||
62 | #include <asm/vm86.h> | 62 | #include <asm/vm86.h> |
63 | #include <asm/segment.h> | ||
63 | 64 | ||
64 | struct task_struct; | 65 | struct task_struct; |
65 | extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); | 66 | extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); |
@@ -73,11 +74,11 @@ extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int erro | |||
73 | */ | 74 | */ |
74 | static inline int user_mode(struct pt_regs *regs) | 75 | static inline int user_mode(struct pt_regs *regs) |
75 | { | 76 | { |
76 | return (regs->xcs & 3) != 0; | 77 | return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL; |
77 | } | 78 | } |
78 | static inline int user_mode_vm(struct pt_regs *regs) | 79 | static inline int user_mode_vm(struct pt_regs *regs) |
79 | { | 80 | { |
80 | return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0; | 81 | return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL; |
81 | } | 82 | } |
82 | #define instruction_pointer(regs) ((regs)->eip) | 83 | #define instruction_pointer(regs) ((regs)->eip) |
83 | extern unsigned long profile_pc(struct pt_regs *regs); | 84 | extern unsigned long profile_pc(struct pt_regs *regs); |