From ce113c4aa7acb5c228ad0bf5bdf8856bd968ffe0 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Fri, 27 Oct 2023 20:15:09 +0200 Subject: locore: Also factorize segment management on i386 and harmonize i386/x86_64. This btw fixes not using dx in 32-on-64's alltraps. --- i386/i386/locore.S | 124 ++++++++++++++++++++++------------------------------- 1 file changed, 52 insertions(+), 72 deletions(-) (limited to 'i386') 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 @@ -39,6 +39,44 @@ #include #include +/* + * 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. */ @@ -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 -- cgit v1.2.3