bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/5] x86_64: disable V86 mode on full 64-bit configuration


From: Luca Dariz
Subject: [PATCH 2/5] x86_64: disable V86 mode on full 64-bit configuration
Date: Sat, 29 Jul 2023 19:47:50 +0200

* 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]