Applied, thanks! Luca Dariz, le sam. 29 juil. 2023 19:47:50 +0200, a ecrit: > * i386/i386/pcb.c: simplify exception stack location and adapt thread > gettrs/setters > * i386/i386/thread.h: don't include V86 fields on full 64-bit > * x86_64/locore.S: don't include checks for V86 mode on full 64-bit > --- > i386/i386/pcb.c | 35 ++++++++++++++++++++++++++--------- > i386/i386/thread.h | 6 ++++++ > x86_64/locore.S | 8 ++++++++ > 3 files changed, 40 insertions(+), 9 deletions(-) > > diff --git a/i386/i386/pcb.c b/i386/i386/pcb.c > index fb535709..d1c5fb50 100644 > --- a/i386/i386/pcb.c > +++ b/i386/i386/pcb.c > @@ -145,9 +145,14 @@ void switch_ktss(pcb_t pcb) > * won`t save the v86 segments, so we leave room. > */ > > +#if !defined(__x86_64__) || defined(USER32) > pcb_stack_top = (pcb->iss.efl & EFL_VM) > ? (long) (&pcb->iss + 1) > : (long) (&pcb->iss.v86_segs); > +#else > + pcb_stack_top = (vm_offset_t) (&pcb->iss + 1); > +#endif > + > #ifdef __x86_64__ > assert((pcb_stack_top & 0xF) == 0); > #endif > @@ -534,6 +539,7 @@ kern_return_t thread_setstatus( > | EFL_USER_SET; > #endif /* __x86_64__ && !USER32 */ > > +#if !defined(__x86_64__) || defined(USER32) > /* > * Segment registers. Set differently in V8086 mode. > */ > @@ -563,8 +569,9 @@ kern_return_t thread_setstatus( > thread->pcb->ims.v86s.flags = > saved_state->efl & (EFL_TF | EFL_IF); > } > - } > - else if (flavor == i386_THREAD_STATE) { > + } else > +#endif > + if (flavor == i386_THREAD_STATE) { > /* > * 386 mode. Set segment registers for flat > * 32-bit address space. > @@ -630,7 +637,7 @@ kern_return_t thread_setstatus( > #endif > break; > } > - > +#if !defined(__x86_64__) || defined(USER32) > case i386_V86_ASSIST_STATE: > { > struct i386_v86_assist_state *state; > @@ -657,7 +664,7 @@ kern_return_t thread_setstatus( > USER_REGS(thread)->efl & (EFL_TF | EFL_IF); > break; > } > - > +#endif > case i386_DEBUG_STATE: > { > struct i386_debug_state *state; > @@ -710,13 +717,20 @@ kern_return_t thread_getstatus( > { > switch (flavor) { > case THREAD_STATE_FLAVOR_LIST: > - if (*count < 4) > +#if !defined(__x86_64__) || defined(USER32) > + unsigned int ncount = 4; > +#else > + unsigned int ncount = 3; > +#endif > + if (*count < ncount) > return (KERN_INVALID_ARGUMENT); > tstate[0] = i386_THREAD_STATE; > tstate[1] = i386_FLOAT_STATE; > tstate[2] = i386_ISA_PORT_MAP_STATE; > +#if !defined(__x86_64__) || defined(USER32) > tstate[3] = i386_V86_ASSIST_STATE; > - *count = 4; > +#endif > + *count = ncount; > break; > > case i386_THREAD_STATE: > @@ -770,6 +784,7 @@ kern_return_t thread_getstatus( > > state->cs = saved_state->cs; > state->ss = saved_state->ss; > +#if !defined(__x86_64__) || defined(USER32) > if (saved_state->efl & EFL_VM) { > /* > * V8086 mode. > @@ -789,7 +804,9 @@ kern_return_t thread_getstatus( > saved_state->efl &= ~EFL_IF; > } > } > - else { > + else > +#endif > + { > /* > * 386 mode. > */ > @@ -835,7 +852,7 @@ kern_return_t thread_getstatus( > *count = i386_ISA_PORT_MAP_STATE_COUNT; > break; > } > - > +#if !defined(__x86_64__) || defined(USER32) > case i386_V86_ASSIST_STATE: > { > struct i386_v86_assist_state *state; > @@ -850,7 +867,7 @@ kern_return_t thread_getstatus( > *count = i386_V86_ASSIST_STATE_COUNT; > break; > } > - > +#endif > case i386_DEBUG_STATE: > { > struct i386_debug_state *state; > diff --git a/i386/i386/thread.h b/i386/i386/thread.h > index b5fc5ffb..2378154f 100644 > --- a/i386/i386/thread.h > +++ b/i386/i386/thread.h > @@ -85,12 +85,14 @@ struct i386_saved_state { > unsigned long efl; > unsigned long uesp; > unsigned long ss; > +#if !defined(__x86_64__) || defined(USER32) > struct v86_segs { > unsigned long v86_es; /* virtual 8086 segment registers */ > unsigned long v86_ds; > unsigned long v86_fs; > unsigned long v86_gs; > } v86_segs; > +#endif > }; > > /* > @@ -144,6 +146,7 @@ struct i386_fpsave_state { > }; > }; > > +#if !defined(__x86_64__) || defined(USER32) > /* > * v86_assist_state: > * > @@ -157,6 +160,7 @@ struct v86_assist_state { > unsigned short flags; /* 8086 flag bits */ > }; > #define V86_IF_PENDING 0x8000 /* unused bit */ > +#endif > > /* > * i386_interrupt_state: > @@ -197,7 +201,9 @@ struct i386_interrupt_state { > struct i386_machine_state { > struct user_ldt * ldt; > struct i386_fpsave_state *ifps; > +#if !defined(__x86_64__) || defined(USER32) > struct v86_assist_state v86s; > +#endif > struct real_descriptor user_gdt[USER_GDT_SLOTS]; > struct i386_debug_state ids; > }; > diff --git a/x86_64/locore.S b/x86_64/locore.S > index ac7138b7..413d43c4 100644 > --- a/x86_64/locore.S > +++ b/x86_64/locore.S > @@ -383,8 +383,10 @@ ENTRY(t_segnp) > /* indicate fault type */ > > trap_check_kernel_exit: > +#ifdef USER32 > testq $(EFL_VM),32(%rsp) /* is trap from V86 mode? */ > jnz EXT(alltraps) /* isn`t kernel trap if so */ > +#endif > /* Note: handling KERNEL_RING value by hand */ > testq $2,24(%rsp) /* is trap from kernel mode? */ > jnz EXT(alltraps) /* if so: */ > @@ -477,8 +479,10 @@ push_segregs: > */ > ENTRY(t_debug) > INT_FIX > +#ifdef USER32 > testq $(EFL_VM),16(%rsp) /* is trap from V86 mode? */ > jnz 0f /* isn`t kernel trap if so */ > +#endif > /* Note: handling KERNEL_RING value by hand */ > testq $2,8(%rsp) /* is trap from kernel mode? */ > jnz 0f /* if so: */ > @@ -544,8 +548,10 @@ trap_push_segs: > #endif > trap_set_segs: > cld /* clear direction flag */ > +#ifdef USER32 > testl $(EFL_VM),R_EFLAGS(%rsp) /* in V86 mode? */ > jnz trap_from_user /* user mode trap if so */ > +#endif > /* Note: handling KERNEL_RING value by hand */ > testb $2,R_CS(%rsp) /* user mode trap? */ > jz trap_from_kernel /* kernel trap if not */ > @@ -799,8 +805,10 @@ LEXT(return_to_iret) /* ( label for > kdb_kintr and hardclock) */ > > popq %rsp /* switch back to old stack */ > > +#ifdef USER32 > testl $(EFL_VM),I_EFL(%rsp) /* if in V86 */ > jnz 0f /* or */ > +#endif > /* Note: handling KERNEL_RING value by hand */ > testb $2,I_CS(%rsp) /* user mode, */ > jz 1f /* check for ASTs */ > -- > 2.39.2 > >
-- Samuel --- Pour une évaluation indépendante, transparente et rigoureuse ! Je soutiens la Commission d'Évaluation de l'Inria.