* 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