[RFC PATCH 15/33] move segment checks to subarch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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).

Signed-off-by: Ian Pratt <[email protected]>
Signed-off-by: Christian Limpach <[email protected]>
Signed-off-by: Chris Wright <[email protected]>

---
 arch/i386/kernel/process.c                   |    2 +-
 arch/i386/mm/fault.c                         |    8 +++++---
 include/asm-i386/mach-default/mach_segment.h |    8 ++++++++
 include/asm-i386/mach-xen/mach_segment.h     |    9 +++++++++
 include/asm-i386/mach-xen/mach_system.h      |    1 +
 include/asm-i386/ptrace.h                    |    6 ++++--
 include/asm-i386/segment.h                   |    2 ++
 include/asm-i386/system.h                    |    1 +
 8 files changed, 31 insertions(+), 6 deletions(-)

diff -r 0bc9790d1ce3 arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c	Tue Jul 18 04:04:39 2006 -0400
+++ b/arch/i386/kernel/process.c	Tue Jul 18 04:33:57 2006 -0400
@@ -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 = get_kernel_cs();
 	regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
 
 	/* Ok, create the new process.. */
diff -r 0bc9790d1ce3 arch/i386/mm/fault.c
--- a/arch/i386/mm/fault.c	Tue Jul 18 04:04:39 2006 -0400
+++ b/arch/i386/mm/fault.c	Tue Jul 18 04:33:57 2006 -0400
@@ -28,6 +28,8 @@
 #include <asm/desc.h>
 #include <asm/kdebug.h>
 
+#include <mach_segment.h>
+
 extern void die(const char *,struct pt_regs *,long);
 
 #ifdef CONFIG_KPROBES
@@ -119,10 +121,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 = (seg & USER_MODE_MASK) ? USER_DS.seg : KERNEL_DS.seg;
 	
 	/* By far the most common cases. */
-	if (likely(seg == __USER_CS || seg == __KERNEL_CS))
+	if (likely(seg == __USER_CS || seg == get_kernel_cs()))
 		return eip;
 
 	/* Check the segment exists, is within the current LDT/GDT size,
@@ -437,7 +439,7 @@ good_area:
 	switch (error_code & 3) {
 		default:	/* 3: write, present */
 #ifdef TEST_VERIFY_AREA
-			if (regs->cs == KERNEL_CS)
+			if (regs->cs == get_kernel_cs())
 				printk("WP fault at %08lx\n", regs->eip);
 #endif
 			/* fall through */
diff -r 0bc9790d1ce3 include/asm-i386/ptrace.h
--- a/include/asm-i386/ptrace.h	Tue Jul 18 04:04:39 2006 -0400
+++ b/include/asm-i386/ptrace.h	Tue Jul 18 04:33:57 2006 -0400
@@ -1,5 +1,7 @@
 #ifndef _I386_PTRACE_H
 #define _I386_PTRACE_H
+
+#include <mach_segment.h>
 
 #define EBX 0
 #define ECX 1
@@ -73,11 +75,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 & USER_MODE_MASK) != 0;
 }
 static inline int user_mode_vm(struct pt_regs *regs)
 {
-	return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0;
+	return ((regs->xcs & USER_MODE_MASK) | (regs->eflags & VM_MASK)) != 0;
 }
 #define instruction_pointer(regs) ((regs)->eip)
 #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
diff -r 0bc9790d1ce3 include/asm-i386/segment.h
--- a/include/asm-i386/segment.h	Tue Jul 18 04:04:39 2006 -0400
+++ b/include/asm-i386/segment.h	Tue Jul 18 04:33:57 2006 -0400
@@ -1,5 +1,7 @@
 #ifndef _ASM_SEGMENT_H
 #define _ASM_SEGMENT_H
+
+#include <mach_segment.h>
 
 /*
  * The layout of the per-CPU GDT under Linux:
diff -r 0bc9790d1ce3 include/asm-i386/system.h
--- a/include/asm-i386/system.h	Tue Jul 18 04:04:39 2006 -0400
+++ b/include/asm-i386/system.h	Tue Jul 18 04:33:57 2006 -0400
@@ -487,6 +487,7 @@ static inline unsigned long long __cmpxc
 #endif
 
 #include <linux/irqflags.h>
+#include <mach_system.h>
 
 /*
  * disable hlt during certain critical i/o operations
diff -r 0bc9790d1ce3 include/asm-i386/mach-xen/mach_system.h
--- a/include/asm-i386/mach-xen/mach_system.h	Tue Jul 18 04:04:39 2006 -0400
+++ b/include/asm-i386/mach-xen/mach_system.h	Tue Jul 18 04:33:57 2006 -0400
@@ -1,5 +1,6 @@
 #ifndef __ASM_MACH_SYSTEM_H
 #define __ASM_MACH_SYSTEM_H
 
+#include <asm/hypervisor.h>
 
 #endif /* __ASM_MACH_SYSTEM_H */
diff -r 0bc9790d1ce3 include/asm-i386/mach-default/mach_segment.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/asm-i386/mach-default/mach_segment.h	Tue Jul 18 04:33:57 2006 -0400
@@ -0,0 +1,8 @@
+#ifndef __ASM_MACH_SEGMENT_H
+#define __ASM_MACH_SEGMENT_H
+
+#define USER_MODE_MASK 3
+
+#define get_kernel_cs() __KERNEL_CS
+
+#endif /* __ASM_MACH_SEGMENT_H */
diff -r 0bc9790d1ce3 include/asm-i386/mach-xen/mach_segment.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/asm-i386/mach-xen/mach_segment.h	Tue Jul 18 04:33:57 2006 -0400
@@ -0,0 +1,9 @@
+#ifndef __ASM_MACH_SEGMENT_H
+#define __ASM_MACH_SEGMENT_H
+
+#define USER_MODE_MASK 2
+
+#define get_kernel_cs() \
+	(__KERNEL_CS + (xen_feature(XENFEAT_supervisor_mode_kernel) ? 0 : 1))
+
+#endif /* __ASM_MACH_SEGMENT_H */

--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux