[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