aboutsummaryrefslogtreecommitdiff
path: root/i386
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2023-10-27 20:15:09 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-10-27 20:15:09 +0200
commitce113c4aa7acb5c228ad0bf5bdf8856bd968ffe0 (patch)
tree68a23a11a17907be5d2ea486b46b88cfacd06283 /i386
parent9854a7f9c393c16bf107118f82362bfb14d256ef (diff)
downloadgnumach-ce113c4aa7acb5c228ad0bf5bdf8856bd968ffe0.tar.gz
gnumach-ce113c4aa7acb5c228ad0bf5bdf8856bd968ffe0.tar.bz2
gnumach-ce113c4aa7acb5c228ad0bf5bdf8856bd968ffe0.zip
locore: Also factorize segment management on i386
and harmonize i386/x86_64. This btw fixes not using dx in 32-on-64's alltraps.
Diffstat (limited to 'i386')
-rw-r--r--i386/i386/locore.S124
1 files changed, 52 insertions, 72 deletions
diff --git a/i386/i386/locore.S b/i386/i386/locore.S
index 846f5567..be412af0 100644
--- a/i386/i386/locore.S
+++ b/i386/i386/locore.S
@@ -40,6 +40,44 @@
#include <i386/xen.h>
/*
+ * Note that we have to load the kernel segment registers even if this
+ * is a trap from the kernel, because the kernel uses user segment
+ * registers for copyin/copyout.
+ * (XXX Would it be smarter just to use fs or gs for that?)
+ */
+#define PUSH_SEGMENTS \
+ pushl %ds ;\
+ pushl %es ;\
+ pushl %fs ;\
+ pushl %gs
+
+#define POP_SEGMENTS \
+ popl %gs ;\
+ popl %fs ;\
+ popl %es ;\
+ popl %ds
+
+#define PUSH_SEGMENTS_ISR \
+ pushl %ds ;\
+ pushl %es ;\
+ pushl %fs ;\
+ pushl %gs
+
+#define POP_SEGMENTS_ISR \
+ popl %gs ;\
+ popl %fs ;\
+ popl %es ;\
+ popl %ds
+
+#define SET_KERNEL_SEGMENTS(reg) \
+ mov %ss,reg /* switch to kernel segments */ ;\
+ mov reg,%ds /* (same as kernel stack segment) */ ;\
+ mov reg,%es ;\
+ mov reg,%fs ;\
+ mov $(PERCPU_DS),reg ;\
+ mov reg,%gs
+
+/*
* Fault recovery.
*/
#define RECOVER_TABLE_START \
@@ -456,22 +494,8 @@ ENTRY(t_page_fault)
ENTRY(alltraps)
pusha /* save the general registers */
trap_push_segs:
- pushl %ds /* and the segment registers */
- pushl %es
- pushl %fs
- pushl %gs
-
- /* Note that we have to load the segment registers
- even if this is a trap from the kernel,
- because the kernel uses user segment registers for copyin/copyout.
- (XXX Would it be smarter just to use fs or gs for that?) */
- mov %ss,%ax /* switch to kernel data segment */
- mov %ax,%ds /* (same as kernel stack segment) */
- mov %ax,%es
- mov %ax,%fs
- mov $(PERCPU_DS),%ax
- movw %ax,%gs
-
+ PUSH_SEGMENTS /* and the segment registers */
+ SET_KERNEL_SEGMENTS(%ax) /* switch to kernel data segment */
trap_set_segs:
cld /* clear direction flag */
testl $(EFL_VM),R_EFLAGS(%esp) /* in V86 mode? */
@@ -680,16 +704,8 @@ ENTRY(all_intrs)
cmpl %ss:CX(EXT(int_stack_base),%ecx),%edx
je int_from_intstack /* if not: */
- pushl %ds /* save segment registers */
- pushl %es
- pushl %fs
- pushl %gs
- mov %ss,%dx /* switch to kernel segments */
- mov %dx,%ds
- mov %dx,%es
- mov %dx,%fs
- mov $(PERCPU_DS),%dx
- movw %dx,%gs
+ PUSH_SEGMENTS_ISR /* save segment registers */
+ SET_KERNEL_SEGMENTS(%dx) /* switch to kernel segments */
CPU_NUMBER(%edx)
@@ -737,10 +753,7 @@ LEXT(return_to_iret) /* to find the return from calling interrupt) */
cmpl $0,CX(EXT(need_ast),%edx)
jnz ast_from_interrupt /* take it if so */
1:
- pop %gs /* restore segment regs */
- pop %fs
- pop %es
- pop %ds
+ POP_SEGMENTS_ISR /* restore segment regs */
pop %edx
pop %ecx
pop %eax
@@ -777,27 +790,15 @@ stack_overflowed:
* ss
*/
ast_from_interrupt:
- pop %gs /* restore all registers ... */
- pop %fs
- pop %es
- pop %ds
+ POP_SEGMENTS_ISR /* restore all registers ... */
popl %edx
popl %ecx
popl %eax
pushl $0 /* zero code */
pushl $0 /* zero trap number */
pusha /* save general registers */
- push %ds /* save segment registers */
- push %es
- push %fs
- push %gs
- mov %ss,%dx /* switch to kernel segments */
- mov %dx,%ds
- mov %dx,%es
- mov %dx,%fs
- mov $(PERCPU_DS),%dx
- movw %dx,%gs
-
+ PUSH_SEGMENTS_ISR /* save segment registers */
+ SET_KERNEL_SEGMENTS(%dx) /* switch to kernel segments */
CPU_NUMBER(%edx)
TIME_TRAP_UENTRY
@@ -924,19 +925,13 @@ kdb_from_iret_i: /* on interrupt stack */
pushl $0 /* zero error code */
pushl $0 /* zero trap number */
pusha /* save general registers */
- push %ds /* save segment registers */
- push %es
- push %fs
- push %gs
+ PUSH_SEGMENTS /* save segment registers */
pushl %esp /* pass regs, */
pushl $0 /* code, */
pushl $-1 /* type to kdb */
call EXT(kdb_trap)
addl $12,%esp /* remove parameters */
- pop %gs /* restore segment registers */
- pop %fs
- pop %es
- pop %ds
+ POP_SEGMENTS /* restore segment registers */
popa /* restore general registers */
addl $8,%esp
iret
@@ -1006,19 +1001,13 @@ ttd_from_iret_i: /* on interrupt stack */
pushl $0 /* zero error code */
pushl $0 /* zero trap number */
pusha /* save general registers */
- push %ds /* save segment registers */
- push %es
- push %fs
- push %gs
+ PUSH_SEGMENTS_ISR /* save segment registers */
pushl %esp /* pass regs, */
pushl $0 /* code, */
pushl $-1 /* type to kdb */
call _kttd_trap
addl $12,%esp /* remove parameters */
- pop %gs /* restore segment registers */
- pop %fs
- pop %es
- pop %ds
+ POP_SEGMENTS_ISR /* restore segment registers */
popa /* restore general registers */
addl $8,%esp
iret
@@ -1046,17 +1035,8 @@ syscall_entry_2:
pushl $0 /* clear trap number slot */
pusha /* save the general registers */
- pushl %ds /* and the segment registers */
- pushl %es
- pushl %fs
- pushl %gs
-
- mov %ss,%dx /* switch to kernel data segment */
- mov %dx,%ds
- mov %dx,%es
- mov %dx,%fs
- mov $(PERCPU_DS),%dx
- movw %dx,%gs
+ PUSH_SEGMENTS /* and the segment registers */
+ SET_KERNEL_SEGMENTS(%dx) /* switch to kernel data segment */
/*
* Shuffle eflags,eip,cs into proper places