krnl386: Call DOSVM_IntProcRelay() via the application stack.

Instead of using a dedicated stack.

The dedicated stack was introduced by 9d7ff6c85b,
in order to support potentially nested DPMI interrupts. DPMI support was removed
by ed6bdb3c51cd4b8c94f9839806321703e7aa9765; hence there is no longer a reason
to account for nested interrupts.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-09-28 20:39:03 -05:00 committed by Alexandre Julliard
parent 43d14fd808
commit a6118baa56
4 changed files with 3 additions and 148 deletions

View file

@ -41,7 +41,6 @@ typedef void (WINAPI *INTPROC)(CONTEXT*);
extern WORD DOSVM_psp DECLSPEC_HIDDEN; /* psp of current DOS task */
extern WORD int16_sel DECLSPEC_HIDDEN;
extern WORD relay_code_sel DECLSPEC_HIDDEN;
extern WORD relay_data_sel DECLSPEC_HIDDEN;
#define ADD_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val)))
@ -247,7 +246,6 @@ extern DWORD DOSVM_inport( int port, int size ) DECLSPEC_HIDDEN;
extern void DOSVM_outport( int port, int size, DWORD value ) DECLSPEC_HIDDEN;
/* relay.c */
void DOSVM_RelayHandler( CONTEXT * ) DECLSPEC_HIDDEN;
void DOSVM_BuildCallFrame( CONTEXT *, DOSRELAY, LPVOID ) DECLSPEC_HIDDEN;
#endif /* __WINE_DOSEXE_H */

View file

@ -45,7 +45,6 @@ WORD DOSMEM_BiosSysSeg; /* BIOS ROM segment at 0xf000:0 */
WORD DOSVM_psp = 0;
WORD int16_sel = 0;
WORD relay_code_sel = 0;
WORD relay_data_sel = 0;
/* DOS memory highest address (including HMA) */
#define DOSMEM_SIZE 0x110000
@ -306,7 +305,6 @@ static void DOSMEM_InitSegments(void)
static const char relay[]=
{
0xca, 0x04, 0x00, /* 16-bit far return and pop 4 bytes (relay void* arg) */
0xcd, 0x31, /* int 31 */
};
/*
@ -330,17 +328,11 @@ static void DOSMEM_InitSegments(void)
/*
* PM / offset 0: Stub where __wine_call_from_16_regs returns.
* PM / offset 3: Stub which swaps back to 32-bit application code/stack.
*/
relay_code_sel = GLOBAL_Alloc( GMEM_FIXED, sizeof(relay), 0, LDT_FLAGS_CODE );
ptr = GlobalLock16( relay_code_sel );
memcpy( ptr, relay, sizeof(relay) );
GlobalUnlock16( relay_code_sel );
/*
* Space for 16-bit stack used by relay code.
*/
relay_data_sel = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, DOSVM_RELAY_DATA_SIZE );
}
/******************************************************************

View file

@ -250,14 +250,7 @@ BOOL DOSVM_EmulateInterruptPM( CONTEXT *context, BYTE intnum )
DOSMEM_InitDosMemory();
if (context->SegCs == relay_code_sel)
{
/*
* This must not be called using DOSVM_BuildCallFrame.
*/
DOSVM_RelayHandler( context );
}
else if (context->SegCs == int16_sel)
if (context->SegCs == int16_sel)
{
/* Restore original flags stored into the stack by the caller. */
WORD *stack = CTX_SEG_OFF_TO_LIN(context,

View file

@ -34,26 +34,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(relay);
/*
* Magic DWORD used to check stack integrity.
*/
#define RELAY_MAGIC 0xabcdef00
/*
* Memory block for temporary 16-bit stacks used with relay calls.
*/
typedef struct {
DWORD inuse; /* non-zero if stack block is in use */
DWORD eip; /* saved ip */
DWORD seg_cs; /* saved cs */
DWORD esp; /* saved sp */
DWORD seg_ss; /* saved ss */
DWORD stack_bottom; /* guard dword */
BYTE stack[256-7*4]; /* 16-bit stack */
DWORD stack_top; /* guard dword */
} RELAY_Stack16;
static const char **debug_relay_excludelist;
static const char **debug_relay_includelist;
static const char **debug_snoop_excludelist;
@ -572,58 +552,6 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT *conte
return ret_val;
}
/**********************************************************************
* RELAY_GetPointer
*
* Get pointer to stack block when given esp pointing to 16-bit stack
* inside relay data segment.
*/
static RELAY_Stack16 *RELAY_GetPointer( DWORD offset )
{
offset = offset / sizeof(RELAY_Stack16) * sizeof(RELAY_Stack16);
return MapSL(MAKESEGPTR(relay_data_sel, offset));
}
/**********************************************************************
* RELAY_MakeShortContext
*
* Allocate separate 16-bit stack, make stack pointer point to this
* stack and make code pointer point to stub that restores everything.
* So, after this routine, SS and CS are guaranteed to be 16-bit.
*
* Note: This might be called from signal handler, so the stack
* allocation algorithm must be signal safe.
*/
static void RELAY_MakeShortContext( CONTEXT *context )
{
DWORD offset = offsetof(RELAY_Stack16, stack_top);
RELAY_Stack16 *stack = RELAY_GetPointer( 0 );
while (stack->inuse && offset < DOSVM_RELAY_DATA_SIZE) {
stack++;
offset += sizeof(RELAY_Stack16);
}
if (offset >= DOSVM_RELAY_DATA_SIZE)
ERR( "Too many nested interrupts!\n" );
stack->inuse = 1;
stack->eip = context->Eip;
stack->seg_cs = context->SegCs;
stack->esp = context->Esp;
stack->seg_ss = context->SegSs;
stack->stack_bottom = RELAY_MAGIC;
stack->stack_top = RELAY_MAGIC;
context->SegSs = relay_data_sel;
context->Esp = offset;
context->SegCs = relay_code_sel;
context->Eip = 3;
}
/**********************************************************************
* RELAY_RelayStub
*
@ -632,58 +560,9 @@ static void RELAY_MakeShortContext( CONTEXT *context )
*/
static void __stdcall RELAY_RelayStub( DOSRELAY proc, unsigned char *args, CONTEXT *context )
{
if (proc)
{
RELAY_Stack16 *stack = RELAY_GetPointer( context->Esp );
DWORD old_seg_cs = context->SegCs;
DWORD old_eip = context->Eip;
DWORD old_seg_ss = context->SegSs;
DWORD old_esp = context->Esp;
context->SegCs = stack->seg_cs;
context->Eip = stack->eip;
context->SegSs = stack->seg_ss;
context->Esp = stack->esp;
proc( context, *(LPVOID *)args );
stack->seg_cs = context->SegCs;
stack->eip = context->Eip;
stack->seg_ss = context->SegSs;
stack->esp = context->Esp;
context->SegCs = old_seg_cs;
context->Eip = old_eip;
context->SegSs = old_seg_ss;
context->Esp = old_esp;
}
proc( context, *(LPVOID *)args );
}
/**********************************************************************
* DOSVM_RelayHandler
*
* Restore saved code and stack pointers and release stack block.
*/
void DOSVM_RelayHandler( CONTEXT *context )
{
RELAY_Stack16 *stack = RELAY_GetPointer( context->Esp );
context->SegSs = stack->seg_ss;
context->Esp = stack->esp;
context->SegCs = stack->seg_cs;
context->Eip = stack->eip;
if (!stack->inuse ||
stack->stack_bottom != RELAY_MAGIC ||
stack->stack_top != RELAY_MAGIC)
ERR( "Stack corrupted!\n" );
stack->inuse = 0;
}
/**********************************************************************
* DOSVM_BuildCallFrame
*
@ -692,13 +571,6 @@ void DOSVM_RelayHandler( CONTEXT *context )
*/
void DOSVM_BuildCallFrame( CONTEXT *context, DOSRELAY relay, LPVOID data )
{
WORD code_sel = relay_code_sel;
/*
* Allocate separate stack for relay call.
*/
RELAY_MakeShortContext( context );
/*
* Build call frame.
*/
@ -713,7 +585,7 @@ void DOSVM_BuildCallFrame( CONTEXT *context, DOSRELAY relay, LPVOID data )
PUSH_WORD16( context, HIWORD(RELAY_RelayStub) ); /* STACK16FRAME.relay.hiword */
PUSH_WORD16( context, LOWORD(RELAY_RelayStub) ); /* STACK16FRAME.relay.loword */
PUSH_WORD16( context, 0 ); /* STACK16FRAME.module_cs.hiword */
PUSH_WORD16( context, code_sel ); /* STACK16FRAME.module_cs.loword */
PUSH_WORD16( context, relay_code_sel ); /* STACK16FRAME.module_cs.loword */
PUSH_WORD16( context, 0 ); /* STACK16FRAME.callfrom_ip.hiword */
PUSH_WORD16( context, 0 ); /* STACK16FRAME.callfrom_ip.loword */