- Don't do fast system calls with the wrong DS/ES selectors.

- Properly load DS/ES on system startup and GDT load
- Use proper DS/ES during deprecated IRQ handling.
- Always use GS as 0 for all of the above.
- *FINALLY* fixes the oldest bug there ever was -> DS/ES corruption noticed in VMWare (And recently in QEMU+KERNELKQEMU, since it behaves internally like vmware). Hacks in trap code have FINALLY been removed!

svn path=/trunk/; revision=23833
This commit is contained in:
Alex Ionescu 2006-08-31 05:25:58 +00:00
parent d2ba2fdc17
commit e870b20916
6 changed files with 32 additions and 21 deletions

View file

@ -28,8 +28,6 @@
// - Get rid of KiRosPrintAddress and use KiDumpParameterImages instead.
// - Sanitize some context fields during conversions.
// - Implement stack fault and segment fault handlers.
// - Figure out why ES/DS gets messed up in VMWare, when doing KiServiceExit only,
// and only when called from user-mode, and returning to user-mode.
// - Add DR macro/save and VM macro/save.
// - Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion.
//

View file

@ -8,10 +8,20 @@ _KiCommonInterrupt:
pushl %fs
pushl %gs
pushl $0xceafbeef
movl $KGDT_R0_DATA,%eax
movl %eax,%ds
movl %eax,%es
movl %eax,%gs
/* Load DS/ES (with override) */
.intel_syntax noprefix
mov eax, KGDT_R3_DATA + RPL_MASK
.byte 0x66
mov ds, ax
.byte 0x66
mov es, ax
/* Clear gs */
xor eax, eax
.byte 0x66
mov gs, ax
.att_syntax
movl $KGDT_R0_PCR,%eax
movl %eax,%fs
pushl %esp

View file

@ -291,7 +291,7 @@ BadThread:
@KiSwapContextInternal@0:
/* Set the Thread to running */
mov byte ptr [esi+KTHREAD_STATE], Running
mov byte ptr es:[esi+KTHREAD_STATE], Running
/* Save the IRQL */
push ecx

View file

@ -115,9 +115,10 @@ KiInitializeGdt(PKPCR Pcr)
__asm__ ("movl %0, %%ds\n\t"
"movl %0, %%es\n\t"
"movl %1, %%fs\n\t"
"movl %0, %%gs\n\t"
"xor %%ax, %%ax\n\t"
"movw %%ax, %%gs\n\t"
: /* no output */
: "a" (KGDT_R0_DATA), "d" (KGDT_R0_PCR));
: "a" (KGDT_R3_DATA | RPL_MASK), "d" (KGDT_R0_PCR));
__asm__ ("pushl %0\n\t"
"pushl $.l4\n\t"
"lret\n\t"
@ -128,11 +129,12 @@ KiInitializeGdt(PKPCR Pcr)
__asm
{
lgdt Descriptor;
mov ax, KGDT_R0_DATA;
mov ax, KGDT_R3_DATA | RPL_MASK;
mov dx, KGDT_R0_PCR;
mov ds, ax;
mov es, ax;
mov fs, dx;
xor ax, ax
mov gs, ax;
push KGDT_R0_CODE;
push offset l4 ;

View file

@ -39,7 +39,16 @@ _NtProcessStartup:
/* Load the PCR selector */
movl $KGDT_R0_PCR, %eax
movl %eax, %fs
/* Load DS/ES (with override) */
.intel_syntax noprefix
mov eax, KGDT_R3_DATA + RPL_MASK
.byte 0x66
mov ds, ax
.byte 0x66
mov es, ax
.att_syntax
cmpl $AP_MAGIC, %ecx
jne .m1

View file

@ -111,8 +111,8 @@ _KiFastCallEntry:
mov ecx, KGDT_R0_PCR
mov fs, cx
/* Set DS/ES to Kernel Selector */
mov ecx, KGDT_R0_DATA
/* Set DS/ES to User Selector */
mov ecx, KGDT_R3_DATA | RPL_MASK
mov ds, cx
mov es, cx
@ -158,10 +158,6 @@ _KiFastCallEntry:
/* Skip the other registers */
sub esp, 0x48
/* Hack: it seems that on VMWare someone damages ES/DS on exit. Investigate! */
mov dword ptr [esp+KTRAP_FRAME_DS], KGDT_R3_DATA + RPL_MASK
mov dword ptr [esp+KTRAP_FRAME_ES], KGDT_R3_DATA + RPL_MASK
/* Make space for us on the stack */
sub ebp, 0x29C
@ -335,10 +331,6 @@ _KiServiceExit:
/* Check for, and deliver, User-Mode APCs if needed */
CHECK_FOR_APC_DELIVER 1
/* Hack for VMWare: Sometimes ES/DS seem to be invalid when returning to user-mode. Investigate! */
mov es, [ebp+KTRAP_FRAME_ES]
mov ds, [ebp+KTRAP_FRAME_DS]
/* Exit and cleanup */
TRAP_EPILOG FromSystemCall, DoRestorePreviousMode, DoNotRestoreSegments, DoNotRestoreVolatiles, DoRestoreEverything
.endfunc