[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 2/5] x86_64: disable V86 mode on full 64-bit configuration
From: |
Samuel Thibault |
Subject: |
Re: [PATCH 2/5] x86_64: disable V86 mode on full 64-bit configuration |
Date: |
Fri, 4 Aug 2023 23:39:34 +0200 |
User-agent: |
NeoMutt/20170609 (1.8.3) |
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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [PATCH 2/5] x86_64: disable V86 mode on full 64-bit configuration,
Samuel Thibault <=