---
i386/Makefrag.am| 2 +
i386/i386/gdt.c | 17
i386/i386/gdt.h | 7 +-
i386/i386/i386asm.sym | 1 +
i386/i386/locore.S | 224
i386/i386/pcb.c | 24 +++---
i386/i386/syscall.c | 103 ++
i386/i386/syscall.h | 7 ++
i386/i386/tss.h | 1 +
i386/i386at/conf.c | 8 ++
i386/i386at/model_dep.c | 2 +
11 files changed, 383 insertions(+), 13 deletions(-)
create mode 100644 i386/i386/syscall.c
create mode 100644 i386/i386/syscall.h
diff --git a/i386/Makefrag.am b/i386/Makefrag.am
index 4dd6a9f..f59ac29 100644
--- a/i386/Makefrag.am
+++ b/i386/Makefrag.am
@@ -147,6 +147,8 @@ libkernel_a_SOURCES += \
i386/i386/setjmp.h \
i386/i386/spl.S \
i386/i386/spl.h \
+ i386/i386/syscall.c \
+ i386/i386/syscall.h \
i386/i386/task.h \
i386/i386/thread.h \
i386/i386/time_stamp.h \
diff --git a/i386/i386/gdt.c b/i386/i386/gdt.c
index c895eb3..0f9d0e3 100644
--- a/i386/i386/gdt.c
+++ b/i386/i386/gdt.c
@@ -57,6 +57,23 @@ gdt_init(void)
LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS,
LINEAR_MAX_KERNEL_ADDRESS -
(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) - 1,
ACC_PL_K|ACC_DATA_W, SZ_32);
+ fill_gdt_descriptor(KERNEL_ENTER_CS,
+ LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS,
+ LINEAR_MAX_KERNEL_ADDRESS -
(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) - 1,
+ ACC_PL_K|ACC_CODE_R, SZ_32);
+ fill_gdt_descriptor(KERNEL_ENTER_DS,
+ LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS,
+ LINEAR_MAX_KERNEL_ADDRESS -
(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) - 1,
+ ACC_PL_K|ACC_DATA_W, SZ_32);
+ fill_gdt_descriptor(USER_EXIT_CS,
+ VM_MIN_ADDRESS,
+ VM_MAX_ADDRESS-VM_MIN_ADDRESS-4096,
+ /* XXX LINEAR_... */
+ ACC_PL_U|ACC_CODE_R, SZ_32);
+ fill_gdt_descriptor(USER_EXIT_DS,
+ VM_MIN_ADDRESS,
+ VM_MAX_ADDRESS-VM_MIN_ADDRESS-4096,
+ ACC_PL_U|ACC_DATA_W, SZ_32);
#ifndefMACH_PV_DESCRIPTORS
fill_gdt_descriptor(LINEAR_DS,
0,
diff --git a/i386/i386/gdt.h b/i386/i386/gdt.h
index d865640..37ca6f5 100644
--- a/i386/i386/gdt.h
+++ b/i386/i386/gdt.h
@@ -55,7 +55,12 @@
#defineUSER_GDT0x48/* user-defined GDT entries */
#defineUSER_GDT_SLOTS 2
-#defineGDTSZ (USER_GDT/8 + USER_GDT_SLOTS)
+#defineKERNEL_ENTER_CS (0x58 | SEL_PL_K) /* kernel code
*/
+#defineKERNEL_ENTER_DS (0x60 | SEL_PL_K) /* kernel data
*/
+#defineUSER_EXIT_CS(0x68 | SEL_PL_U) /* user code */
+#defineUSER_EXIT_DS(0x70 | SEL_PL_U) /* user data */
+
+#defineGDTSZ (USER_EXIT_DS/8 + 1)
extern struct real_descriptor gdt[GDTSZ];
diff --git a/i386/i386/i386asm.sym b/i386/i386/i386asm.sym
index dd1a2ed..e495d1a 100644
--- a/i386/i386/i386asm.sym
+++ b/i386/i386/i386asm.sym
@@ -70,6 +70,7 @@ size i386_kernel_state iks
size i386_exception_link iel
+size i386_saved_stateiss
offset i386_saved_stater cs
offset i386_saved_stater uesp
offset i386_saved_stater eax
diff --git a/i386/i386/locore.S b/i386/i386/locore.S
index cfda86f..d8241a7 100644
--- a/i386/i386/locore.S
+++ b/i386/i386/locore.S
@@ -521,6 +521,9 @@ _return_to_user:
*/
_return_from_kernel:
+ cmpl$0x7fff, R_TRAPNO(%esp) /* YYY */
+ je return_from_sysenter
+
_kret_popl_gs:
popl%gs /* restore segment registers */
_kret_popl_fs:
@@ -978,6 +981,18 @@ ttd_from_iret_i: /* on interrupt stack */
#endif /* MACH_TTD */
+/* User stub for calling the kernel using the trap gate. */
+ .globl user_trapgate_stub_start
+user_trapgate_stub_start:
+ popl %ecx /* Pop return address into %ecx. */
+ popl %eax /* Pop syscall number into %eax. */
+ pushl %ecx /* Push back return address. */
+ lcall $7, $0
+ subl $4, %esp /* magic */
+ ret
+ .globl user_trapgate_stub_end
+user_trapgate_stub_end:
+
/*
* System call enters through a call gate. Flags are not saved -
* we must shuffle stack to look like trap save area.
@@ -1170,6 +1185,215 @@ syscall_addr:
/* set error code - read user space */
jmp _take_trap /* treat as a trap */
+/*
+ *