diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-10-27 20:15:09 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-10-27 20:15:09 +0200 |
commit | ce113c4aa7acb5c228ad0bf5bdf8856bd968ffe0 (patch) | |
tree | 68a23a11a17907be5d2ea486b46b88cfacd06283 /i386 | |
parent | 9854a7f9c393c16bf107118f82362bfb14d256ef (diff) | |
download | gnumach-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.S | 124 |
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 |