Fixed int 10 problems

Guard pages for all thread stacks

svn path=/trunk/; revision=1744
This commit is contained in:
David Welch 2001-03-29 01:14:00 +00:00
parent d9925196f3
commit ca5d9b1a2d
8 changed files with 400 additions and 20 deletions

View file

@ -101,6 +101,7 @@ void InitVGAMode()
// FIXME: Use Vidport to map the memory properly
vidmem = (char *)(0xd0000000 + 0xa0000);
memset(&vxba, 0, sizeof(vxba));
vxba.Eax = 0x0012;
vps = VideoPortInt10(NULL, &vxba);
// setMode(Mode12);

View file

@ -25,6 +25,7 @@ typedef ULONG SWAPENTRY;
#define MEMORY_AREA_CACHE_SEGMENT (10)
#define MEMORY_AREA_SHARED_DATA (11)
#define MEMORY_AREA_WORKING_SET (12)
#define MEMORY_AREA_KERNEL_STACK (13)
#define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
((x) / (4*1024*1024))

View file

@ -74,12 +74,25 @@ Ke386CallBios(UCHAR Int, PKV86M_REGISTERS Regs)
Regs->Flags = KV86M_EMULATE_CLI_STI | KV86M_ALLOW_IO_PORT_ACCESS;
Regs->Vif = 1;
Regs->PStatus = &Status;
WRITE_PORT_UCHAR((PUCHAR)0xea, 0);
/*
* Execute the BIOS interrupt
*/
Ki386RetToV86Mode(Regs, &ORegs);
WRITE_PORT_UCHAR((PUCHAR)0xea, 1);
if (!NT_SUCCESS(Status))
{
DPRINT1("Ke386CallBios() failed (Status %x)\n", Status);
}
else
{
DPRINT1("Ke386CallBios succeeded\n");
}
/*
* Copy the return values back to the caller
*/

View file

@ -64,10 +64,12 @@ _Ki386ContextSwitch:
* Set the base of the TEB selector to the base of the TEB for
* this thread.
*/
pushl %ebx
pushl KTHREAD_TEB(%ebx)
pushl $TEB_SELECTOR
call _KeSetBaseGdtSelector
addl $8, %esp
popl %ebx
/*
* Set the current thread information in the PCR

View file

@ -1,6 +1,6 @@
/*
* ReactOS kernel
* Copyright (C) 2000 ReactOS Team
* Copyright (C) 2000, 2001 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -40,6 +40,7 @@
#define IOPL_FLAG ((1 << 12) | (1 << 13))
#define INTERRUPT_FLAG (1 << 9)
#define TRAP_FLAG (1 << 8)
#define DIRECTION_FLAG (1 << 10)
#define VALID_FLAGS (0xDFF)
@ -53,7 +54,7 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
PULONG dsp;
BOOL BigDataPrefix = FALSE;
BOOL BigAddressPrefix = FALSE;
// BOOL RepPrefix = FALSE;
BOOL RepPrefix = FALSE;
ULONG i = 0;
BOOL Exit = FALSE;
@ -82,10 +83,18 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
Tf->Eip++;
break;
/* rep prefix */
case 0xFC:
RepPrefix = TRUE;
i++;
Tf->Eip++;
break;
/* sti */
case 0xFB:
if (BigDataPrefix || BigAddressPrefix)
if (BigDataPrefix || BigAddressPrefix || RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
@ -99,8 +108,9 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* cli */
case 0xFA:
if (BigDataPrefix || BigAddressPrefix)
if (BigDataPrefix || BigAddressPrefix || RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
@ -114,6 +124,11 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* pushf */
case 0x9C:
if (RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
{
Tf->Eip++;
@ -153,6 +168,11 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* popf */
case 0x9D:
if (RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
{
Tf->Eip++;
@ -192,6 +212,11 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* iret */
case 0xCF:
if (RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
{
Tf->Eip = sp[0];
@ -215,9 +240,14 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* out imm8, al */
case 0xE6:
if (RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
WRITE_PORT_UCHAR((PUCHAR)(ULONG)ip[1],
WRITE_PORT_UCHAR((PUCHAR)(ULONG)ip[i + 1],
Tf->Eax & 0xFF);
Tf->Eip = Tf->Eip + 2;
return(0);
@ -227,9 +257,21 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* out imm8, ax */
case 0xE7:
if (RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
WRITE_PORT_USHORT((PUSHORT)(ULONG)ip[1], Tf->Eax & 0xFFFF);
if (!BigDataPrefix)
{
WRITE_PORT_USHORT((PUSHORT)(ULONG)ip[1], Tf->Eax & 0xFFFF);
}
else
{
WRITE_PORT_ULONG((PULONG)(ULONG)ip[1], Tf->Eax);
}
Tf->Eip = Tf->Eip + 2;
return(0);
}
@ -238,6 +280,11 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* out dx, al */
case 0xEE:
if (RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
WRITE_PORT_UCHAR((PUCHAR)(Tf->Edx & 0xFFFF), Tf->Eax & 0xFF);
@ -249,9 +296,23 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* out dx, ax */
case 0xEF:
if (RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
WRITE_PORT_USHORT((PUSHORT)(Tf->Edx & 0xFFFF), Tf->Eax & 0xFFFF);
if (!BigDataPrefix)
{
WRITE_PORT_USHORT((PUSHORT)(Tf->Edx & 0xFFFF),
Tf->Eax & 0xFFFF);
}
else
{
WRITE_PORT_ULONG((PULONG)(Tf->Edx & 0xFFFF),
Tf->Eax);
}
Tf->Eip = Tf->Eip + 1;
return(0);
}
@ -260,6 +321,11 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* in al, imm8 */
case 0xE4:
if (RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
UCHAR v;
@ -275,6 +341,11 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* in ax, imm8 */
case 0xE5:
if (RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
USHORT v;
@ -290,6 +361,11 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* in al, dx */
case 0xEC:
if (RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
UCHAR v;
@ -305,6 +381,11 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* in ax, dx */
case 0xED:
if (RepPrefix)
{
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
USHORT v;
@ -317,16 +398,241 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
}
Exit = TRUE;
break;
/* outsb */
case 0x6E:
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
ULONG Count;
PUCHAR Port;
PUCHAR Buffer;
ULONG Offset;
Count = 1;
if (RepPrefix)
{
Count = Tf->Ecx;
if (!BigAddressPrefix)
{
Count = Count & 0xFFFF;
}
}
Port = (PUCHAR)(Tf->Edx & 0xFFFF);
Offset = Tf->Edi;
if (!BigAddressPrefix)
{
Offset = Offset & 0xFFFF;
}
Buffer = (PUCHAR)((Tf->Es * 16) + Offset);
for (; Count > 0; Count--)
{
WRITE_PORT_UCHAR(Port, *Buffer);
if (Tf->Eflags & DIRECTION_FLAG)
{
Buffer++;
}
else
{
Buffer--;
}
}
Tf->Eip++;
return(0);
}
Exit = TRUE;
break;
/* insw/insd */
case 0x6F:
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
ULONG Count;
PUCHAR Port;
PUSHORT BufferS;
PULONG BufferL;
ULONG Offset;
Count = 1;
if (RepPrefix)
{
Count = Tf->Ecx;
if (!BigAddressPrefix)
{
Count = Count & 0xFFFF;
}
}
Port = (PUCHAR)(Tf->Edx & 0xFFFF);
Offset = Tf->Edi;
if (!BigAddressPrefix)
{
Offset = Offset & 0xFFFF;
}
if (BigDataPrefix)
{
BufferL = (PULONG)((Tf->Es * 16) + Offset);
}
else
{
BufferS = (PUSHORT)((Tf->Es * 16) + Offset);
}
for (; Count > 0; Count--)
{
if (BigDataPrefix)
{
WRITE_PORT_ULONG((PULONG)Port, *BufferL);
}
else
{
WRITE_PORT_USHORT((PUSHORT)Port, *BufferS);
}
if (Tf->Eflags & DIRECTION_FLAG)
{
if (BigDataPrefix)
{
BufferL++;
}
else
{
BufferS++;
}
}
else
{
if (BigDataPrefix)
{
BufferL--;
}
else
{
BufferS--;
}
}
}
Tf->Eip++;
return(0);
}
Exit = TRUE;
break;
/* insb */
case 0x6C:
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
ULONG Count;
PUCHAR Port;
PUCHAR Buffer;
ULONG Offset;
Count = 1;
if (RepPrefix)
{
Count = Tf->Ecx;
if (!BigAddressPrefix)
{
Count = Count & 0xFFFF;
}
}
Port = (PUCHAR)(Tf->Edx & 0xFFFF);
Offset = Tf->Edi;
if (!BigAddressPrefix)
{
Offset = Offset & 0xFFFF;
}
Buffer = (PUCHAR)((Tf->Es * 16) + Offset);
for (; Count > 0; Count--)
{
*Buffer = READ_PORT_UCHAR(Port);
if (Tf->Eflags & DIRECTION_FLAG)
{
Buffer++;
}
else
{
Buffer--;
}
}
Tf->Eip++;
return(0);
}
Exit = TRUE;
break;
/* insw/insd */
case 0x6D:
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
ULONG Count;
PUCHAR Port;
PUSHORT BufferS;
PULONG BufferL;
ULONG Offset;
Count = 1;
if (RepPrefix)
{
Count = Tf->Ecx;
if (!BigAddressPrefix)
{
Count = Count & 0xFFFF;
}
}
Port = (PUCHAR)(Tf->Edx & 0xFFFF);
Offset = Tf->Edi;
if (!BigAddressPrefix)
{
Offset = Offset & 0xFFFF;
}
if (BigDataPrefix)
{
BufferL = (PULONG)((Tf->Es * 16) + Offset);
}
else
{
BufferS = (PUSHORT)((Tf->Es * 16) + Offset);
}
for (; Count > 0; Count--)
{
if (BigDataPrefix)
{
*BufferL = READ_PORT_ULONG((PULONG)Port);
}
else
{
*BufferS = READ_PORT_USHORT((PUSHORT)Port);
}
if (Tf->Eflags & DIRECTION_FLAG)
{
if (BigDataPrefix)
{
BufferL++;
}
else
{
BufferS++;
}
}
else
{
if (BigDataPrefix)
{
BufferL--;
}
else
{
BufferS--;
}
}
}
Tf->Eip++;
return(0);
}
Exit = TRUE;
break;
/* Int nn */
case 0xCD:
{
@ -360,7 +666,7 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
/* FIXME: Don't allow the BIOS to write to sensitive I/O ports */
}
DPRINT("V86GPF unhandled\n");
DPRINT1("V86GPF unhandled (was %x)\n", ip[i]);
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}

View file

@ -52,12 +52,17 @@ PiSuspendThreadNormalRoutine(PVOID NormalContext,
PVOID SystemArgument1,
PVOID SystemArgument2);
/* GLOBALS *******************************************************************/
#define TAG_THREAD_STACK TAG('T', 'S', 'T', 'K')
/* FUNCTIONS *****************************************************************/
VOID
KeFreeStackPage(PVOID Context, PVOID Address, ULONG PhysAddr)
{
if (PhysAddr != 0)
{
MmDereferencePage((PVOID)PhysAddr);
}
}
NTSTATUS
HalReleaseTask(PETHREAD Thread)
/*
@ -67,10 +72,14 @@ HalReleaseTask(PETHREAD Thread)
*/
{
extern unsigned int init_stack;
if (Thread->Tcb.StackLimit != (ULONG)&init_stack)
{
ExFreePool((PVOID)Thread->Tcb.StackLimit);
MmFreeMemoryArea(MmGetKernelAddressSpace(),
(PVOID)Thread->Tcb.StackLimit,
MM_STACK_SIZE,
KeFreeStackPage,
NULL);
}
Thread->Tcb.StackLimit = 0;
Thread->Tcb.InitialStack = NULL;
@ -86,8 +95,11 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
*/
{
PVOID KernelStack;
NTSTATUS Status;
extern unsigned int init_stack_top;
extern unsigned int init_stack;
PMEMORY_AREA StackArea;
ULONG i;
KeInitializeDispatcherHeader(&Thread->DispatcherHeader,
InternalThreadType,
@ -96,8 +108,27 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
InitializeListHead(&Thread->MutantListHead);
if (!First)
{
KernelStack = ExAllocatePoolWithTag(NonPagedPool, MM_STACK_SIZE,
TAG_THREAD_STACK);
KernelStack = NULL;
Status = MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
MEMORY_AREA_KERNEL_STACK,
&KernelStack,
MM_STACK_SIZE,
0,
&StackArea,
FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create thread stack\n");
KeBugCheck(0);
}
for (i = 0; i < (MM_STACK_SIZE / PAGESIZE); i++)
{
Status = MmCreateVirtualMapping(NULL,
KernelStack + (i * PAGESIZE),
PAGE_EXECUTE_READWRITE,
(ULONG)MmAllocPage(0));
}
Thread->InitialStack = KernelStack + MM_STACK_SIZE;
Thread->StackBase = KernelStack + MM_STACK_SIZE;
Thread->StackLimit = (ULONG)KernelStack;

View file

@ -16,8 +16,8 @@
/* GLOBALS *******************************************************************/
/* static */ UCHAR OrigIVT[1024];
/* static UCHAR OrigBDA[]; */
static UCHAR OrigIVT[1024];
static UCHAR OrigBDA[256];
/* static UCHAR OrigEBDA[]; */
/* FUNCTIONS *****************************************************************/
@ -30,12 +30,22 @@ NtEarlyInitVdm(VOID)
* map is still active so we can just copy the data from low memory.
*/
memcpy(OrigIVT, (PVOID)0x0, 1024);
memcpy(OrigBDA, (PVOID)0x400, 256);
}
NTSTATUS STDCALL NtVdmControl(ULONG ControlCode,
PVOID ControlData)
{
memcpy(ControlData, OrigIVT, 1024);
switch (ControlCode)
{
case 0:
memcpy(ControlData, OrigIVT, 1024);
break;
case 1:
memcpy(ControlData, OrigBDA, 256);
break;
}
return(STATUS_SUCCESS);
}

View file

@ -12,6 +12,7 @@ InitializeVideoAddressSpace(VOID)
ULONG ViewSize;
PUCHAR TextMap;
CHAR IVT[1024];
CHAR BDA[256];
/*
* Open the physical memory section
@ -99,5 +100,20 @@ InitializeVideoAddressSpace(VOID)
*/
memcpy((PVOID)0x0, IVT, 1024);
/*
* Get the BDA from the kernel
*/
Status = NtVdmControl(1, BDA);
if (!NT_SUCCESS(Status))
{
DbgPrint("NtVdmControl failed (status %x)\n", Status);
return(0);
}
/*
* Copy the BDA into the right place
*/
memcpy((PVOID)0x400, BDA, 256);
return(1);
}