[x64] can not switch from ring3 to ring0 by call gate
Posted: Thu Jun 14, 2018 1:41 pm
can not switch from ring3 to ring0 by call gate, code below generating invlid TSS exception, but via syscall switch works fine. where is bug?
Code: Select all
use64
call [PL3toPL0]
NextPL3PL0:
...
PL3toPL0 dp Gate386-GDT+3:0
GDT: dq 0
; 32-bit code descriptor 0x08
Code32 dw 0xFFFF ; limit low
dw 0 ; base low
db 0 ; base middle
db 10011010b ; access
db 11001111b ; flags and limit high
db 0 ; base high
; 32-bit data descriptor 0x10
Data32: dw 0xFFFF
dw 0
db 0
db 10010010b
db 11001111b
db 0
; 16-bit code descriptor 0x18
Code16 dw 0xFFFF
dw 0
db 0
db 10011010b
db 10001111b
db 0
; 16-bit data descriptor 0x20
Data16 dw 0xFFFF
dw 0
db 0
db 10010010b
db 10001111b
db 0
; 64-bit kernel code descriptor 0x28
Code64 dw 0xFFFF
dw 0
db 0
db 10011010b
db 10101111b
db 0
; 64-bit kernel data descriptor 0x30
Data64 dw 0xFFFF
dw 0
db 0
db 10010010b
db 11001111b
db 0
; Usermode code descriptor 0x38
Code643 dw 0xFFFF
dw 0
db 0
db 11111010b
db 10101111b
db 0
; Usermode data descriptor 0x40
Data643 dw $FFFF
dw 0
db 0
db 11110010b
db 11001111b
db 0
; Usermode code descriptor 0x48
Code64X dw 0xFFFF
dw 0
db 0
db 11111010b
db 10101111b
db 0
; TSS descriptor 0x50-0x58
Tss64 dw 68h+IOLIMIT
dw (TSS64 and 0xFFFF)
db (TSS64 shr 16)and 0xFF
db 11101001b
db 00100000b
db (TSS64 shr 24)and 0xFF
dd (TSS64 shr 32)
dd 0
; 32-bit user descriptor 0x60
Code323 dw 0xFFFF
dw 0
db 0
db 11111010b
db 11001111b
db 0
Gate386 dw (NextPL3PL0 and 0xFFFF)
dw Code64-GDT
db 0
db 11101100b
dw (NextPL3PL0 shr 16)and 0xFFFF
dd (NextPL3PL0 shr 32)
dd 0