aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/entry.S
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2006-09-26 04:52:39 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:39 -0400
commit78be3706b21a232310590fe00258b224177ac05f (patch)
tree57dbe444e57241613067145b04c0e15c98278cd6 /arch/i386/kernel/entry.S
parent0da5db313317e3195482d3e660a1074857374a89 (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 'arch/i386/kernel/entry.S')
-rw-r--r--arch/i386/kernel/entry.S9
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 3872fca5c74..284f2e908ad 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -240,8 +240,9 @@ ret_from_intr:
240check_userspace: 240check_userspace:
241 movl EFLAGS(%esp), %eax # mix EFLAGS and CS 241 movl EFLAGS(%esp), %eax # mix EFLAGS and CS
242 movb CS(%esp), %al 242 movb CS(%esp), %al
243 testl $(VM_MASK | 3), %eax 243 andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
244 jz resume_kernel 244 cmpl $USER_RPL, %eax
245 jb resume_kernel # not returning to v8086 or userspace
245ENTRY(resume_userspace) 246ENTRY(resume_userspace)
246 DISABLE_INTERRUPTS # make sure we don't miss an interrupt 247 DISABLE_INTERRUPTS # make sure we don't miss an interrupt
247 # setting need_resched or sigpending 248 # setting need_resched or sigpending
@@ -377,8 +378,8 @@ restore_all:
377 # See comments in process.c:copy_thread() for details. 378 # See comments in process.c:copy_thread() for details.
378 movb OLDSS(%esp), %ah 379 movb OLDSS(%esp), %ah
379 movb CS(%esp), %al 380 movb CS(%esp), %al
380 andl $(VM_MASK | (4 << 8) | 3), %eax 381 andl $(VM_MASK | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
381 cmpl $((4 << 8) | 3), %eax 382 cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
382 CFI_REMEMBER_STATE 383 CFI_REMEMBER_STATE
383 je ldt_ss # returning to user-space with LDT SS 384 je ldt_ss # returning to user-space with LDT SS
384restore_nocheck: 385restore_nocheck: