Applied, thanks! Damien Zammit, le mar. 24 févr. 2026 01:59:41 +0000, a ecrit: > curr_spl is actually 4 bytes, but the CX() macro > was expanding to 8 byte stride on x86_64. > Add a new macro specifically for 8 byte widths and > use the correct stride macro for every asm instruction. > > Reported by Brent Baccala > --- > i386/i386/cpu_number.h | 7 +-- > i386/i386/locore.S | 4 +- > x86_64/cswitch.S | 6 +- > x86_64/locore.S | 124 ++++++++++++++++++++--------------------- > 4 files changed, 69 insertions(+), 72 deletions(-) > > diff --git a/i386/i386/cpu_number.h b/i386/i386/cpu_number.h > index a549bb56..4e894a00 100644 > --- a/i386/i386/cpu_number.h > +++ b/i386/i386/cpu_number.h > @@ -34,12 +34,8 @@ > > #define MY(stm) %gs:PERCPU_##stm > > -#ifdef __i386__ > #define CX(addr, reg) addr(,reg,4) > -#endif > -#ifdef __x86_64__ > -#define CX(addr, reg) addr(,reg,8) > -#endif > +#define CX8(addr, reg) addr(,reg,8) > > /* Fastest version, requires gs being set up */ > #define CPU_NUMBER(reg) \ > @@ -70,6 +66,7 @@ static inline int cpu_number(void) > #define CPU_NUMBER(reg) \ > xor reg, reg > #define CX(addr,reg) addr > +#define CX8(addr,reg) addr > > #endif /* NCPUS == 1 */ > > diff --git a/i386/i386/locore.S b/i386/i386/locore.S > index 535257c6..905e1af9 100644 > --- a/i386/i386/locore.S > +++ b/i386/i386/locore.S > @@ -250,8 +250,8 @@ LEXT(retry_table_end) ;\ > subl %ebx,%ecx /* elapsed = new-old */ ;\ > movl CX(EXT(current_timer),%edx),%ebx /* get current timer */ > ;\ > addl %ecx,LOW_BITS(%ebx) /* add to low bits */ ;\ > - leal CX(0,%edx),%ecx /* timer is 16 bytes */ ;\ > - lea CX(EXT(kernel_timer),%edx),%ecx /* get interrupt timer*/;\ > + leal CX(0,%edx),%ecx /* timer is 16 bytes: CX(CX( = > 4*4 */ ;\ > + lea CX(EXT(kernel_timer),%ecx),%ecx /* get interrupt timer*/;\ > movl %ecx,CX(EXT(current_timer),%edx) /* set timer */ > > /* > diff --git a/x86_64/cswitch.S b/x86_64/cswitch.S > index a6b390e8..d91fd65c 100644 > --- a/x86_64/cswitch.S > +++ b/x86_64/cswitch.S > @@ -41,7 +41,7 @@ ENTRY(Load_context) > /* point to stack top */ > CPU_NUMBER(%eax) > movq %rcx,MY(ACTIVE_STACK) /* store stack address */ > - movq %rdx,CX(EXT(kernel_stack),%rax) /* store stack top */ > + movq %rdx,CX8(EXT(kernel_stack),%rax) /* store stack top */ > > /* XXX complete */ > > @@ -86,7 +86,7 @@ ENTRY(Switch_context) > CPU_NUMBER(%edx) /* Don't overwrite returned > value %rax */ > movq %rsi,MY(ACTIVE_THREAD) /* new thread is active */ > movq %rcx,MY(ACTIVE_STACK) /* set current stack */ > - movq %rbx,CX(EXT(kernel_stack),%rdx) /* set stack top */ > + movq %rbx,CX8(EXT(kernel_stack),%rdx) /* set stack top */ > > movq KSS_ESP(%rcx),%rsp /* switch stacks */ > movq KSS_EBP(%rcx),%rbp /* restore registers */ > @@ -135,7 +135,7 @@ ud2 > movq S_ARG2,%rsi /* get its argument */ > > CPU_NUMBER(%ecx) > - movq CX(EXT(int_stack_base),%rcx),%rcx /* point to its > interrupt stack */ > + movq CX8(EXT(int_stack_base),%rcx),%rcx /* point to its > interrupt stack */ > lea INTSTACK_SIZE(%rcx),%rsp /* switch to it (top) */ > > movq %rax,%rdi /* push thread */ > diff --git a/x86_64/locore.S b/x86_64/locore.S > index b1ec6197..fad0d73c 100644 > --- a/x86_64/locore.S > +++ b/x86_64/locore.S > @@ -292,8 +292,8 @@ LEXT(retry_table_end) ;\ > /* > * Update time on user trap entry. > * 11 instructions (including cli on entry) > - * Assumes CPU number in %edx. > - * Uses %eax, %ebx, %ecx. > + * Assumes CPU number in %rdx. > + * Uses %rax, %rbx, %rcx. > */ > #define TIME_TRAP_UENTRY \ > pushf /* Save flags */ ;\ > @@ -302,21 +302,21 @@ LEXT(retry_table_end) ;\ > movl CX(EXT(current_tstamp),%rdx),%ecx /* get old time stamp > */;\ > movl %ebx,CX(EXT(current_tstamp),%rdx) /* set new time stamp > */;\ > subl %ecx,%ebx /* elapsed = new-old */ ;\ > - movl CX(EXT(current_timer),%rdx),%ecx /* get current timer */ > ;\ > - addl %ebx,LOW_BITS(%ecx) /* add to low bits */ ;\ > + movq CX8(EXT(current_timer),%rdx),%rcx /* get current timer */ > ;\ > + addl %ebx,LOW_BITS(%rcx) /* add to low bits */ ;\ > jns 0f /* if overflow, */ ;\ > call timer_normalize /* normalize timer */ ;\ > -0: addl $(TH_SYSTEM_TIMER-TH_USER_TIMER),%ecx ;\ > +0: addq $(TH_SYSTEM_TIMER-TH_USER_TIMER),%rcx ;\ > /* switch to sys timer */;\ > - movl %ecx,CX(EXT(current_timer),%rdx) /* make it current */ > ;\ > + movq %rcx,CX8(EXT(current_timer),%rdx) /* make it current */ > ;\ > popf /* allow interrupts */ > > /* > * Update time on system call entry. > * 11 instructions (including cli on entry) > - * Assumes CPU number in %edx. > - * Uses %ebx, %ecx. > - * Same as TIME_TRAP_UENTRY, but preserves %eax. > + * Assumes CPU number in %rdx. > + * Uses %rbx, %rcx. > + * Same as TIME_TRAP_UENTRY, but preserves %rax. > */ > #define TIME_TRAP_SENTRY \ > pushf /* Save flags */ ;\ > @@ -325,22 +325,22 @@ LEXT(retry_table_end) ;\ > movl CX(EXT(current_tstamp),%rdx),%ecx /* get old time stamp > */;\ > movl %ebx,CX(EXT(current_tstamp),%rdx) /* set new time stamp > */;\ > subl %ecx,%ebx /* elapsed = new-old */ ;\ > - movl CX(EXT(current_timer),%rdx),%ecx /* get current timer */ > ;\ > - addl %ebx,LOW_BITS(%ecx) /* add to low bits */ ;\ > + movq CX8(EXT(current_timer),%rdx),%rcx /* get current timer */ > ;\ > + addl %ebx,LOW_BITS(%rcx) /* add to low bits */ ;\ > jns 0f /* if overflow, */ ;\ > pushq %rax /* save %rax */ ;\ > call timer_normalize /* normalize timer */ ;\ > popq %rax /* restore %rax */ ;\ > -0: addl $(TH_SYSTEM_TIMER-TH_USER_TIMER),%ecx ;\ > +0: addq $(TH_SYSTEM_TIMER-TH_USER_TIMER),%rcx ;\ > /* switch to sys timer */;\ > - movl %ecx,CX(EXT(current_timer),%rdx) /* make it current */ > ;\ > + movq %rcx,CX8(EXT(current_timer),%rdx) /* make it current */ > ;\ > popf /* allow interrupts */ > > /* > * update time on user trap exit. > * 10 instructions. > - * Assumes CPU number in %edx. > - * Uses %ebx, %ecx. > + * Assumes CPU number in %rdx. > + * Uses %rbx, %rcx. > */ > #define TIME_TRAP_UEXIT \ > cli /* block interrupts */ ;\ > @@ -348,57 +348,57 @@ LEXT(retry_table_end) ;\ > movl CX(EXT(current_tstamp),%rdx),%ecx /* get old time stamp > */;\ > movl %ebx,CX(EXT(current_tstamp),%rdx) /* set new time stamp > */;\ > subl %ecx,%ebx /* elapsed = new-old */ ;\ > - movl CX(EXT(current_timer),%rdx),%ecx /* get current timer */ > ;\ > - addl %ebx,LOW_BITS(%ecx) /* add to low bits */ ;\ > + movq CX8(EXT(current_timer),%rdx),%rcx /* get current timer */ > ;\ > + addl %ebx,LOW_BITS(%rcx) /* add to low bits */ ;\ > jns 0f /* if overflow, */ ;\ > call timer_normalize /* normalize timer */ ;\ > -0: addl $(TH_USER_TIMER-TH_SYSTEM_TIMER),%ecx ;\ > +0: addq $(TH_USER_TIMER-TH_SYSTEM_TIMER),%rcx ;\ > /* switch to user timer */;\ > - movl %ecx,CX(EXT(current_timer),%rdx) /* make it current */ > + movq %rcx,CX8(EXT(current_timer),%rdx) /* make it current */ > > /* > * update time on interrupt entry. > * 9 instructions. > - * Assumes CPU number in %edx. > - * Leaves old timer in %ebx. > - * Uses %ecx. > + * Assumes CPU number in %rdx. > + * Leaves old timer in %rbx. > + * Uses %rcx. > */ > #define TIME_INT_ENTRY \ > movl VA_ETC,%ecx /* get timer */ ;\ > movl CX(EXT(current_tstamp),%rdx),%ebx /* get old time stamp > */;\ > movl %ecx,CX(EXT(current_tstamp),%rdx) /* set new time stamp > */;\ > subl %ebx,%ecx /* elapsed = new-old */ ;\ > - movl CX(EXT(current_timer),%rdx),%ebx /* get current timer */ > ;\ > - addl %ecx,LOW_BITS(%ebx) /* add to low bits */ ;\ > - leal CX(0,%rdx),%ecx /* timer is 16 bytes */ ;\ > - lea CX(EXT(kernel_timer),%rdx),%ecx /* get interrupt timer*/;\ > - movl %ecx,CX(EXT(current_timer),%rdx) /* set timer */ > + movq CX8(EXT(current_timer),%rdx),%rbx /* get current timer */ > ;\ > + addl %ecx,LOW_BITS(%rbx) /* add to low bits */ ;\ > + leaq CX(0,%rdx),%rcx /* timer is 16 bytes: CX(CX( = > 4*4 */ ;\ > + leaq CX(EXT(kernel_timer),%rcx),%rcx /* get interrupt timer*/;\ > + movq %rcx,CX8(EXT(current_timer),%rdx) /* set timer */ > > /* > * update time on interrupt exit. > * 11 instructions > - * Assumes CPU number in %edx, old timer in %ebx. > - * Uses %eax, %ecx. > + * Assumes CPU number in %rdx, old timer in %rbx. > + * Uses %rax, %rcx. > */ > #define TIME_INT_EXIT \ > movl VA_ETC,%eax /* get timer */ ;\ > movl CX(EXT(current_tstamp),%rdx),%ecx /* get old time stamp > */;\ > movl %eax,CX(EXT(current_tstamp),%rdx) /* set new time stamp > */;\ > subl %ecx,%eax /* elapsed = new-old */ ;\ > - movl CX(EXT(current_timer),%rdx),%ecx /* get current timer */ > ;\ > - addl %eax,LOW_BITS(%ecx) /* add to low bits */ ;\ > + movq CX8(EXT(current_timer),%rdx),%rcx /* get current timer */ > ;\ > + addl %eax,LOW_BITS(%rcx) /* add to low bits */ ;\ > jns 0f /* if overflow, */ ;\ > call timer_normalize /* normalize timer */ ;\ > -0: testb $0x80,LOW_BITS+3(%ebx) /* old timer overflow? */;\ > +0: testb $0x80,LOW_BITS+3(%rbx) /* old timer overflow? */;\ > jz 0f /* if overflow, */ ;\ > - movl %ebx,%ecx /* get old timer */ ;\ > + movq %rbx,%rcx /* get old timer */ ;\ > call timer_normalize /* normalize timer */ ;\ > -0: movl %ebx,CX(EXT(current_timer),%rdx) /* set timer */ > +0: movq %rbx,CX8(EXT(current_timer),%rdx) /* set timer */ > > > /* > - * Normalize timer in ecx. > - * Preserves edx; clobbers eax. > + * Normalize timer in %rcx. > + * Preserves %rdx; clobbers %rax. > */ > .align 2 > timer_high_unit: > @@ -407,12 +407,12 @@ timer_high_unit: > timer_normalize: > pushq %rdx /* save register */ > xorl %edx,%edx /* clear divisor high */ > - movl LOW_BITS(%ecx),%eax /* get divisor low */ > + movl LOW_BITS(%rcx),%eax /* get divisor low */ > divl timer_high_unit,%eax /* quotient in eax */ > /* remainder in edx */ > - addl %eax,HIGH_BITS_CHECK(%ecx) /* add high_inc to check */ > - movl %edx,LOW_BITS(%ecx) /* remainder to low_bits */ > - addl %eax,HIGH_BITS(%ecx) /* add high_inc to high bits */ > + addl %eax,HIGH_BITS_CHECK(%rcx) /* add high_inc to check */ > + movl %edx,LOW_BITS(%rcx) /* remainder to low_bits */ > + addl %eax,HIGH_BITS(%rcx) /* add high_inc to high bits */ > popq %rdx /* restore register */ > ret > > @@ -425,13 +425,13 @@ ENTRY(timer_switch) > movl CX(EXT(current_tstamp),%rdx),%eax /* get old time stamp > */ > movl %ecx,CX(EXT(current_tstamp),%rdx) /* set new time stamp */ > subl %ecx,%eax /* elapsed = new - old */ > - movl CX(EXT(current_timer),%rdx),%ecx /* get current timer */ > - addl %eax,LOW_BITS(%ecx) /* add to low bits */ > + movq CX8(EXT(current_timer),%rdx),%rcx /* get current timer */ > + addl %eax,LOW_BITS(%rcx) /* add to low bits */ > jns 0f /* if overflow, */ > call timer_normalize /* normalize timer */ > 0: > - movl S_ARG0,%ecx /* get new timer */ > - movl %ecx,CX(EXT(current_timer),%rdx) /* set timer */ > + movq S_ARG0,%rcx /* get new timer */ > + movq %rcx,CX8(EXT(current_timer),%rdx) /* set timer */ > ret > > /* > @@ -441,8 +441,8 @@ ENTRY(start_timer) > CPU_NUMBER(%edx) /* get this CPU */ > movl VA_ETC,%ecx /* get timer */ > movl %ecx,CX(EXT(current_tstamp),%rdx) /* set initial time > stamp */ > - movl S_ARG0,%ecx /* get timer */ > - movl %ecx,CX(EXT(current_timer),%rdx) /* set initial timer */ > + movq S_ARG0,%rcx /* get timer */ > + movq %rcx,CX8(EXT(current_timer),%rdx) /* set initial timer */ > ret > > #endif /* accurate timing */ > @@ -669,7 +669,7 @@ trap_from_user: > CPU_NUMBER(%edx) > TIME_TRAP_UENTRY > > - movq CX(EXT(kernel_stack),%rdx),%rbx > + movq CX8(EXT(kernel_stack),%rdx),%rbx > xchgq %rbx,%rsp /* switch to kernel stack */ > /* user regs pointer already set */ > _take_trap: > @@ -691,10 +691,10 @@ _take_trap: > > _return_from_trap: > CPU_NUMBER(%edx) > - cmpl $0,CX(EXT(need_ast),%rdx) > + cmpq $0,CX8(EXT(need_ast),%rdx) > jz _return_to_user /* if we need an AST: */ > > - movq CX(EXT(kernel_stack),%rdx),%rsp > + movq CX8(EXT(kernel_stack),%rdx),%rsp > /* switch to kernel stack */ > call EXT(i386_astintr) /* take the AST */ > popq %rsp /* switch back to PCB stack */ > @@ -739,17 +739,17 @@ trap_from_kernel: > > CPU_NUMBER(%ecx) > and $(~(INTSTACK_SIZE-1)),%rdx > - cmpq CX(EXT(int_stack_base),%rcx),%rdx > + cmpq CX8(EXT(int_stack_base),%rcx),%rdx > je 1f /* OK if so */ > > movq %rcx,%rdx > - cmpq CX(EXT(kernel_stack),%rdx),%rsp > + cmpq CX8(EXT(kernel_stack),%rdx),%rsp > /* already on kernel stack? */ > ja 0f > cmpq MY(ACTIVE_STACK),%rsp > ja 1f /* switch if not */ > 0: > - movq CX(EXT(kernel_stack),%rdx),%rsp > + movq CX8(EXT(kernel_stack),%rdx),%rsp > 1: > pushq %rbx /* save old stack */ > movq %rbx,%rdi /* pass as parameter */ > @@ -919,12 +919,12 @@ ENTRY(all_intrs) > CPU_NUMBER(%ecx) > movq %rsp,%rdx /* on an interrupt stack? */ > and $(~(INTSTACK_SIZE-1)),%rdx > - cmpq %ss:CX(EXT(int_stack_base),%rcx),%rdx > + cmpq %ss:CX8(EXT(int_stack_base),%rcx),%rdx > je int_from_intstack /* if not: */ > > CPU_NUMBER(%edx) > > - movq CX(EXT(int_stack_top),%rdx),%rcx > + movq CX8(EXT(int_stack_top),%rdx),%rcx > > xchgq %rcx,%rsp /* switch to interrupt stack */ > > @@ -938,7 +938,7 @@ ENTRY(all_intrs) > #endif > > #ifdef MACH_LDEBUG > - incl CX(EXT(in_interrupt),%rdx) > + incq CX8(EXT(in_interrupt),%rdx) > #endif > > call EXT(interrupt) /* call generic interrupt routine */ > @@ -947,7 +947,7 @@ LEXT(return_to_iret) /* to find the > return from calling interrupt) */ > > CPU_NUMBER(%edx) > #ifdef MACH_LDEBUG > - decl CX(EXT(in_interrupt),%rdx) > + decq CX8(EXT(in_interrupt),%rdx) > #endif > > #if STAT_TIME > @@ -966,7 +966,7 @@ LEXT(return_to_iret) /* to find the > return from calling interrupt) */ > testb $2,I_CS(%rsp) /* user mode, */ > jz 1f /* check for ASTs */ > 0: > - cmpq $0,CX(EXT(need_ast),%rdx) > + cmpq $0,CX8(EXT(need_ast),%rdx) > jnz ast_from_interrupt /* take it if so */ > 1: > SWAPGS_EXIT_IF_NEEDED_R12 > @@ -977,7 +977,7 @@ LEXT(return_to_iret) /* to find the > return from calling interrupt) */ > > int_from_intstack: > CPU_NUMBER(%edx) > - cmpq CX(EXT(int_stack_base),%rdx),%rsp /* seemingly looping? */ > + cmpq CX8(EXT(int_stack_base),%rdx),%rsp /* seemingly looping? */ > jb stack_overflowed /* if not: */ > call EXT(interrupt) /* call interrupt routine */ > _return_to_iret_i: /* ( label for kdb_kintr) */ > @@ -1017,7 +1017,7 @@ ast_from_interrupt: > CPU_NUMBER(%edx) > TIME_TRAP_UENTRY > > - movq CX(EXT(kernel_stack),%rdx),%rsp > + movq CX8(EXT(kernel_stack),%rdx),%rsp > /* switch to kernel stack */ > call EXT(i386_astintr) /* take the AST */ > popq %rsp /* back to PCB stack */ > @@ -1271,7 +1271,7 @@ syscall_entry_2: > CPU_NUMBER(%edx) > TIME_TRAP_SENTRY > > - movq CX(EXT(kernel_stack),%rdx),%rbx > + movq CX8(EXT(kernel_stack),%rdx),%rbx > /* get current kernel stack */ > xchgq %rbx,%rsp /* switch stacks - %ebx points to */ > /* user registers. */ > @@ -1516,7 +1516,7 @@ ENTRY(syscall64) > > /* switch to kernel stack then enable interrupts */ > CPU_NUMBER(%r11d) /* we can call the fast version here */ > - movq CX(EXT(kernel_stack),%r11),%rsp > + movq CX8(EXT(kernel_stack),%r11),%rsp > sti > > /* Now we have saved state and args 1-6 are in place. > @@ -1560,7 +1560,7 @@ _syscall64_check_for_ast: > /* Check for ast. */ > CPU_NUMBER(%r11d) > > - cmpl $0,CX(EXT(need_ast),%r11) > + cmpq $0,CX8(EXT(need_ast),%r11) > jz _syscall64_restore_state > > /* Save the syscall return value, both on our stack, for the case > -- > 2.51.0 > > >
-- Samuel jr> J'ai fait. Ne bougez pas, l'aide soignante va venir nettoyer. -+- FF in GNU - Le vieil homme et la merde -+-
