All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Fitzhardinge <jeremy@xensource.com>
To: akpm@osdl.org
Cc: linux-kernel@vger.kernel.org, virtualization@lists.osdl.org,
	xen-devel@lists.xensource.com,
	Jeremy Fitzhardinge <jeremy@goop.org>,
	Rusty Russell <rusty@rustcorp.com.au>,
	Zachary Amsden <zach@vmware.com>
Subject: [patch 3/8] Allow a kernel to not be in ring 0.
Date: Wed, 02 Aug 2006 17:25:13 -0700	[thread overview]
Message-ID: <20060803002518.190834642@xensource.com> (raw)
In-Reply-To: 20060803002510.634721860@xensource.com

[-- Attachment #1: 003-remove-ring0-assumptions.patch --]
[-- Type: text/plain, Size: 5249 bytes --]

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.

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>

---
 arch/i386/kernel/entry.S   |    5 +++--
 arch/i386/kernel/process.c |    2 +-
 arch/i386/mm/extable.c     |    2 +-
 arch/i386/mm/fault.c       |   11 ++++-------
 include/asm-i386/ptrace.h  |    5 +++--
 include/asm-i386/segment.h |   10 ++++++++++
 6 files changed, 22 insertions(+), 13 deletions(-)


===================================================================
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -229,8 +229,9 @@ check_userspace:
 check_userspace:
 	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
 	movb CS(%esp), %al
-	testl $(VM_MASK | 3), %eax
-	jz resume_kernel
+	andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
+	cmpl $SEGMENT_RPL_MASK, %eax
+	jb resume_kernel		# not returning to v8086 or userspace
 ENTRY(resume_userspace)
  	cli				# make sure we don't miss an interrupt
 					# setting need_resched or sigpending
===================================================================
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -346,7 +346,7 @@ int kernel_thread(int (*fn)(void *), voi
 	regs.xes = __USER_DS;
 	regs.orig_eax = -1;
 	regs.eip = (unsigned long) kernel_thread_helper;
-	regs.xcs = __KERNEL_CS;
+	regs.xcs = __KERNEL_CS | get_kernel_rpl();
 	regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
 
 	/* Ok, create the new process.. */
===================================================================
--- a/arch/i386/mm/extable.c
+++ b/arch/i386/mm/extable.c
@@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs
 	const struct exception_table_entry *fixup;
 
 #ifdef CONFIG_PNPBIOS
-	if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3)))
+	if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
 	{
 		extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
 		extern u32 pnp_bios_is_utter_crap;
===================================================================
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -27,6 +27,7 @@
 #include <asm/uaccess.h>
 #include <asm/desc.h>
 #include <asm/kdebug.h>
+#include <asm/segment.h>
 
 extern void die(const char *,struct pt_regs *,long);
 
@@ -119,10 +120,10 @@ static inline unsigned long get_segment_
 	}
 
 	/* The standard kernel/user address space limit. */
-	*eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg;
+	*eip_limit = user_mode(regs) ? USER_DS.seg : KERNEL_DS.seg;
 	
 	/* By far the most common cases. */
-	if (likely(seg == __USER_CS || seg == __KERNEL_CS))
+	if (likely(SEGMENT_IS_FLAT_CODE(seg)))
 		return eip;
 
 	/* Check the segment exists, is within the current LDT/GDT size,
@@ -436,11 +437,7 @@ good_area:
 	write = 0;
 	switch (error_code & 3) {
 		default:	/* 3: write, present */
-#ifdef TEST_VERIFY_AREA
-			if (regs->cs == KERNEL_CS)
-				printk("WP fault at %08lx\n", regs->eip);
-#endif
-			/* fall through */
+				/* fall through */
 		case 2:		/* write, not present */
 			if (!(vma->vm_flags & VM_WRITE))
 				goto bad_area;
===================================================================
--- a/include/asm-i386/ptrace.h
+++ b/include/asm-i386/ptrace.h
@@ -60,6 +60,7 @@ struct pt_regs {
 #ifdef __KERNEL__
 
 #include <asm/vm86.h>
+#include <asm/segment.h>
 
 struct task_struct;
 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_str
  */
 static inline int user_mode(struct pt_regs *regs)
 {
-	return (regs->xcs & 3) != 0;
+	return (regs->xcs & SEGMENT_RPL_MASK) == 3;
 }
 static inline int user_mode_vm(struct pt_regs *regs)
 {
-	return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0;
+	return (((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= 3);
 }
 #define instruction_pointer(regs) ((regs)->eip)
 #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
===================================================================
--- a/include/asm-i386/segment.h
+++ b/include/asm-i386/segment.h
@@ -83,6 +83,12 @@
 
 #define GDT_SIZE (GDT_ENTRIES * 8)
 
+/*
+ * Some tricky tests to match code segments after a fault
+ */
+#define SEGMENT_IS_FLAT_CODE(x)  (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
+#define SEGMENT_IS_PNP_CODE(x)   (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
+
 /* Simple and small GDT entries for booting only */
 
 #define GDT_ENTRY_BOOT_CS		2
@@ -112,4 +118,8 @@
  */
 #define IDT_ENTRIES 256
 
+/* Bottom three bits of xcs give the ring privilege level */
+#define SEGMENT_RPL_MASK 0x3
+
+#define get_kernel_rpl()  0
 #endif

--


  parent reply	other threads:[~2006-08-03  0:26 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-03  0:25 [patch 0/8] Basic infrastructure patches for a paravirtualized kernel Jeremy Fitzhardinge
2006-08-03  0:25 ` Jeremy Fitzhardinge
2006-08-03  0:25 ` [patch 1/8] Remove locally-defined ldt structure in favour of standard type Jeremy Fitzhardinge
2006-08-03  0:25 ` [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor Jeremy Fitzhardinge
2006-08-03  0:25   ` Jeremy Fitzhardinge
2006-08-03  0:28   ` Christoph Lameter
2006-08-03  0:35     ` Jeremy Fitzhardinge
2006-08-03  1:06       ` Christoph Lameter
2006-08-03  1:18         ` Zachary Amsden
2006-08-03  1:18           ` Zachary Amsden
2006-08-03  1:25           ` Christoph Lameter
2006-08-03  3:55             ` Andi Kleen
2006-08-03  3:55               ` Andi Kleen
2006-08-03  4:25               ` Christoph Lameter
2006-08-03  4:47                 ` Andi Kleen
2006-08-03  4:47                   ` Andi Kleen
2006-08-03  2:45         ` Andi Kleen
2006-08-03  2:45           ` Andi Kleen
2006-08-03  4:27           ` Christoph Lameter
2006-08-03  4:49             ` Andi Kleen
2006-08-03  5:19               ` Christoph Lameter
2006-08-03  5:25                 ` Andi Kleen
2006-08-03  5:25                   ` Andi Kleen
2006-08-03  5:32                   ` Christoph Lameter
2006-08-03  5:39                     ` Andi Kleen
2006-08-03  5:39                       ` Andi Kleen
2006-08-03  5:54                       ` Christoph Lameter
2006-08-03  6:02                         ` Andi Kleen
2006-08-03 16:49                           ` Christoph Lameter
2006-08-03 17:18                             ` Chris Wright
2006-08-03 17:18                               ` Chris Wright
2006-08-04  0:47                             ` Andi Kleen
2006-08-04  2:16                               ` Christoph Lameter
2006-08-03  0:25 ` Jeremy Fitzhardinge [this message]
2006-08-03  0:25 ` [patch 4/8] Replace sensitive instructions with macros Jeremy Fitzhardinge
2006-08-03  0:25   ` Jeremy Fitzhardinge
2006-08-03  0:25 ` [patch 5/8] Roll all the cpuid asm into one __cpuid call Jeremy Fitzhardinge
2006-08-03  0:25 ` [patch 6/8] Make __FIXADDR_TOP variable to allow it to make space for a hypervisor Jeremy Fitzhardinge
2006-08-03  0:25 ` [patch 7/8] Add a bootparameter to reserve high linear address space Jeremy Fitzhardinge
1970-01-01  0:15   ` Pavel Machek
2006-08-07  2:10     ` Andi Kleen
2006-08-07  2:10       ` Andi Kleen
2010-05-04 23:37     ` Jeremy Fitzhardinge
2010-05-04 23:37       ` Jeremy Fitzhardinge
2006-08-03  6:19   ` Andrew Morton
2006-08-03  7:33     ` Zachary Amsden
2006-08-03  7:33       ` Zachary Amsden
2006-08-03  7:41       ` Andrew Morton
2006-08-03  8:58         ` Zachary Amsden
2006-08-03  8:58           ` Zachary Amsden
2006-08-05 21:58           ` Andrew Morton
2006-08-05 21:58             ` Andrew Morton
2006-08-05 22:52             ` Zachary Amsden
2006-08-05 22:52               ` Zachary Amsden
2006-08-05 23:17             ` Rusty Russell
2006-08-05 23:17               ` Rusty Russell
2006-08-06 22:00   ` Pavel Machek
2006-08-06 22:02   ` Pavel Machek
2006-08-07  9:12   ` Pavel Machek
2006-08-03  0:25 ` [patch 8/8] Put .note.* sections into a PT_NOTE segment in vmlinux Jeremy Fitzhardinge
  -- strict thread matches above, loose matches on Subject: below --
2006-08-05  0:41 [patch 3/8] Allow a kernel to not be in ring 0 Chuck Ebbert
2006-08-05  0:41 ` Chuck Ebbert
2006-08-05  4:26 ` Zachary Amsden
2006-08-05  4:26   ` Zachary Amsden
2006-08-05  5:40 Chuck Ebbert
2006-08-05  5:40 ` Chuck Ebbert

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=20060803002518.190834642@xensource.com \
    --to=jeremy@xensource.com \
    --cc=akpm@osdl.org \
    --cc=jeremy@goop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rusty@rustcorp.com.au \
    --cc=virtualization@lists.osdl.org \
    --cc=xen-devel@lists.xensource.com \
    --cc=zach@vmware.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.