1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
From 56c1cfd4797af7367c5d830d5125baa75d4f0bdb Mon Sep 17 00:00:00 2001
From: Justus Winter <4winter@informatik.uni-hamburg.de>
Date: Tue, 5 May 2015 21:25:58 +0200
Subject: [PATCH gnumach 10/10] fix error handling
---
i386/i386/locore.S | 38 ++++++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/i386/i386/locore.S b/i386/i386/locore.S
index 0d08be5..d8241a7 100644
--- a/i386/i386/locore.S
+++ b/i386/i386/locore.S
@@ -1305,11 +1305,12 @@ ENTRY(sysenter_entry)
xchgl %ebx, %esp /* switch to kernel stack */
/* %ebx points to user registers */
negl %eax /* get system call number */
- /* xxx sysenter_mach_call_range */
- jl mach_call_range /* out of range if it was positive */
- cmpl EXT(mach_trap_count),%eax /* check system call table bounds */
- /* xxx sysenter_mach_call_range */
- jg mach_call_range /* error if out of range */
+ jl sysenter_mach_call_range
+ /* out of range if it was positive */
+ cmpl EXT(mach_trap_count),%eax
+ /* check system call table bounds */
+ jg sysenter_mach_call_range
+ /* error if out of range */
shll $4,%eax /* manual indexing */
movl EXT(mach_trap_table)(%eax),%ecx
@@ -1339,6 +1340,7 @@ se_args_5plus:
movl $USER_DS,%edx /* use user data segment for accesses */
mov %dx,%fs
+ movl %esp,%edx /* save kernel ESP for error recovery */
0: subl $4,%esi
RECOVER(sysenter_mach_call_addr_push)
@@ -1370,12 +1372,28 @@ return_from_sysenter: /* return here */
sti /* xxx: sti/cli where ? */
sysexit
+/*
+ * Address out of range. Change to page fault.
+ * %esi holds failing address.
+ */
sysenter_mach_call_addr_push:
- movl %ebx,%esp /* clean parameters from stack */
- /* xxx signal page-fault */
- jmp sysenter_mach_call_addr_push
-#undef SE_STACK_POINTER
-#undef SE_RETURN_ADDRESS
+ movl %edx,%esp /* clean parameters from stack */
+ movl %esi,R_CR2(%ebx) /* set fault address */
+ movl $(T_PAGE_FAULT),R_TRAPNO(%ebx)
+ /* set page-fault trap */
+ movl $(T_PF_USER),R_ERR(%ebx)
+ /* set error code - read user space */
+ jmp _take_trap /* treat as a trap */
+
+/*
+ * System call out of range. Treat as invalid-instruction trap.
+ * (? general protection?)
+ */
+sysenter_mach_call_range:
+ movl $(T_INVALID_OPCODE),R_TRAPNO(%ebx)
+ /* set invalid-operation trap */
+ movl $0,R_ERR(%ebx) /* clear error code */
+ jmp _take_trap /* treat as a trap */
.data
DATA(cpu_features)
--
2.1.4
|