[PATCH 2/2] Transparent privilege levels in entry.S

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

 



i386 Transparent Paravirtualization Patch #2

Changes required to low level fault / system call code for supporting
transparent paravirtualization where the kernel may be running at non-zero
CPL.

The testing of VM_MASK and CS together uses a neat trick which is now extended
to support CPL 0,1,2 kernels.

Note that assembly code must test against __ESPFIX_SS, the 16-bit stack on
interrupts and exceptions.  To do so at non-zero CPL requires masking off
the RPL of the selector (which is a nop for the mach-default implementation).

Also, there is no reason to load __KERNEL_DS into %ds or %es.  __KERNEL_DS
is actually quite poorly named, and is in fact the kernel stack selector.  The
kernel uses __USER_DS internally as both %es and %ds (since it is a flat CPL-3
accessible data segment that allows the kernel to skip reloading segments on
sysexit).  The reason for avoiding the __KERNEL_DS macro is it is predefined
as an RPL zero segment.

Diffs against: linux-2.6.13-rc6
Signed-off-by: Zachary Amsden <zach@xxxxxxxxxx>
Index: linux-2.6.13/arch/i386/kernel/entry.S
===================================================================
--- linux-2.6.13.orig/arch/i386/kernel/entry.S	2005-08-17 11:16:54.000000000 -0700
+++ linux-2.6.13/arch/i386/kernel/entry.S	2005-08-17 11:17:13.000000000 -0700
@@ -159,8 +159,9 @@ ret_from_intr:
 	GET_THREAD_INFO(%ebp)
 	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
 	movb CS(%esp), %al
-	testl $(VM_MASK | 3), %eax
-	jz resume_kernel
+	andl $(VM_MASK | 3), %eax
+	cmpl $3, %eax
+	jb resume_kernel
 ENTRY(resume_userspace)
  	CLI				# make sure we don't miss an interrupt
 					# setting need_resched or sigpending
@@ -399,10 +400,11 @@ syscall_badsys:
 #define UNWIND_ESPFIX_STACK \
 	pushl %eax; \
 	movl %ss, %eax; \
+	MASK_RPL(%ax); \
 	/* see if on 16bit stack */ \
 	cmpw $__ESPFIX_SS, %ax; \
 	jne 28f; \
-	movl $__KERNEL_DS, %edx; \
+	movl $__USER_DS, %edx; \
 	movl %edx, %ds; \
 	movl %edx, %es; \
 	/* switch to 32bit stack */ \
@@ -500,7 +502,7 @@ ENTRY(simd_coprocessor_error)
 ENTRY(device_not_available)
 	pushl $-1			# mark this as an int
 	SAVE_ALL
-	movl %cr0, %eax
+	GET_CR0
 	testl $0x4, %eax		# EM (math emulation bit)
 	jne device_not_available_emulate
 	preempt_stop
@@ -557,6 +559,7 @@ debug_stack_correct:
 ENTRY(nmi)
 	pushl %eax
 	movl %ss, %eax
+	MASK_RPL(%ax)
 	cmpw $__ESPFIX_SS, %ax
 	popl %eax
 	je nmi_16bit_stack
Index: linux-2.6.13/include/asm-i386/mach-default/mach_asm.h
===================================================================
--- linux-2.6.13.orig/include/asm-i386/mach-default/mach_asm.h	2005-08-17 11:17:09.000000000 -0700
+++ linux-2.6.13/include/asm-i386/mach-default/mach_asm.h	2005-08-17 11:17:13.000000000 -0700
@@ -7,5 +7,6 @@
 #define CLI		cli
 #define STI		sti
 #define STI_SYSEXIT	sti; sysexit
+#define MASK_RPL(seg)	/* nop */
 
 #endif

[Index of Archives]     [KVM Development]     [Libvirt Development]     [Libvirt Users]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux