7/8 Create accessors that allow the i386 kernel to run at CPLs 0-2
PATCH 1/1 7/8 Create accessors that allow the i386 kernel to run at CPLs 0-2
i386 Transparent paravirtualization subarch patch #7.
These changes allow a sub-architecture to change the notion of privilege by running the kernel at CPL 0, 1, or 2. The make_kernel_segment() macro can be redefined by a subarchitecture to change the RPL on kernel segments to the appropriate value, and the tests user_mode() and user_mode_vm() may be similarly overridden.
Changes to the assembly code are required to fully support this, and provided in a separate patch.
Diffs against: 2.6.13-rc4-mm1
arch/i386/kernel/process.c +1 -1
@@ -356,7 +356,7 @@ regs.xes = __USER_DS; regs.orig_eax =-1 ; regs.eip = (unsigned long ) kernel_thread_helper; - regs.xcs = __KERNEL_CS; + regs.xcs =make_kernel_segment (__KERNEL_CS); regs.eflags =X86_EFLAGS_IF |X86_EFLAGS_SF |X86_EFLAGS_PF |0x2 ;/* Ok, create the new process.. */
arch/i386/kernel/traps.c +2 -2
@@ -1025,10 +1025,10 @@memcpy ((void *)(stack_bot + iret_frame16_off), ®s->eip,20 );/* fill in the switch pointers */ switch16_ptr[0 ] = (regs->esp &0xffff0000 ) | iret_frame16_off; - switch16_ptr[1 ] = __ESPFIX_SS; + switch16_ptr[1 ] =make_kernel_segment (__ESPFIX_SS); switch32_ptr[0 ] = (unsigned long )stk +sizeof (struct pt_regs ) +8 -CPU_16BIT_STACK_SIZE ; - switch32_ptr[1 ] = __KERNEL_DS; + switch32_ptr[1 ] =make_kernel_segment (__KERNEL_DS); } fastcall unsigned char * fixup_x86_bogus_stack(unsigned short sp)
include/asm-i386/ptrace.h +1 -15
@@ -57,25 +57,11 @@#ifdef __KERNEL__#include <asm/vm86.h> +#include <mach_segment.h> struct task_struct ;extern void send_sigtrap (struct task_struct *tsk,struct pt_regs *regs,int error_code); -/* -* 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. -*/ -static inline int user_mode (struct pt_regs *regs) -{ -return (regs->xcs &3 ) !=0 ; -} -static inline int user_mode_vm (struct pt_regs *regs) -{ -return ((regs->xcs &3 ) | (regs->eflags &VM_MASK )) !=0 ; -}#define instruction_pointer (regs) ((regs)->eip)#if defined(CONFIG_SMP ) && defined(CONFIG_FRAME_POINTER )extern unsigned long profile_pc (struct pt_regs *regs);
include/asm-i386/mach-default/mach_segment.h +28 -0
@@ -0,0 +1,28 @@ +/* +* include/asm-i386/mach-default/mach_segment.h +* +* user_mode macros moved from include/asm-i386/ptrace.h 08/05 +*/ + +#ifndef __MACH_SEGMENT_H +#define __MACH_SEGMENT_H + +/* +* 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. +*/ +static inline int user_mode (struct pt_regs *regs) +{ +return (regs->xcs &3 ) !=0 ; +} +static inline int user_mode_vm (struct pt_regs *regs) +{ +return ((regs->xcs &3 ) | (regs->eflags &VM_MASK )) !=0 ; +} + +#define make_kernel_segment (seg) (seg) + +#endif
Quoted 5 lines · * Zachary Amsden ([email protected]) wrote:
These changes allow a sub-architecture to change the notion of privilege by running the kernel at CPL 0, 1, or 2. The
make_kernel_segment()macro can be redefined by a subarchitecture to change the RPL on kernel segments to the appropriate value, and the testsuser_mode()anduser_mode_vm()may be similarly overridden.
No issue here, but there's some overlap from my side that needs merging (note, as with all the others, mine are against 2.6.12, to user_mode(), for example, has changed since then). Also note, the segment bit is still much too heavy handed on my side (looks like you are generally further along than I am ;-) so I still have some refactoring to do.
include/asm-i386/ptrace.h +1 -1
@@ -55,9 +55,9 @@ struct pt_regs {#define PTRACE_SET_THREAD_AREA 26#ifdef __KERNEL__ +#include <mach_ptrace.h> struct task_struct ;extern void send_sigtrap (struct task_struct *tsk,struct pt_regs *regs,int error_code); -#define user_mode (regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs))#define instruction_pointer (regs) ((regs)->eip)#if defined(CONFIG_SMP ) && defined(CONFIG_FRAME_POINTER )extern unsigned long profile_pc (struct pt_regs *regs);
include/asm-i386/mach-default/mach_ptrace.h new file +6 -0
@@ -0,0 +1,6 @@ +#ifndef __ASM_MACH_PTRACE_H +#define __ASM_MACH_PTRACE_H + +#define user_mode (regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) + +#endif
include/asm-i386/segment.h +1 -96
102 lines not on this page · raw message
include/asm-i386/mach-default/mach_segment.h new file +101 -0
101 lines not on this page · raw message