ring3 triple fault

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
summersong
Member
Member
Posts: 32
Joined: Sat Mar 26, 2011 5:26 am
Location: Moscow

ring3 triple fault

Post by summersong »

Long mode, triple fault instead calling exception handler.

Code: Select all

align 16
tss:
	dd		0
	dq		9fc00h	; rsp 0 = rsp
	dq		0	; rsp 1
	dq		0	; rsp 2
	dq		0
	dq		0	; ist 1
	dq		0	; ist 2
	dq		0	; ist 3
	dq		0	; ist 4
	dq		0	; ist 5
	dq		0	; ist 6
	dq		0	; ist 7
	dq		0
	dw		0
	dw		$-tss	; i/o map offset
tsse equ $-tss-1

gdtr:						; ##	type	  offs     size 	  DPL    attr
	dq		0			;
	dw		0ffffh,0,09b00h,0afh	; 08	code	00000000-0009FC00  0	R
	dw		0ffffh,0,09300h,0afh	; 10	data	00000000-FFFFFFFF  0	RW
	dw		0ffffh,0,0fa00h,0afh	; 18	code	00000000-FFFFFFFF  3	R
	dw		0ffffh,0,0f200h,0afh	; 20	data	00000000-FFFFFFFF  3	RW
	DEFINE_TSS tss,tsse-1			; 28	TSS	00000000-FFFFFFFF  0	R

use64
align 16
longmode:
	mov		ax,10h
	mov		ds,ax
	mov		es,ax
	mov		fs,ax
	mov		gs,ax
	mov		ss,ax
	mov		rsp,9fc00h

	; enable SYSCALL/SYSRET
	mov		ecx,0c0000081h			; MSR_STAR
	xor		eax,eax
	mov		edx,(8+16)*65536 or 18h	; (syscode+16)*65536 or appcode
	wrmsr

	mov		ecx,0c0000082h			; MSR_LSTAR
	mov		eax,sys				; RIP
	xor		edx,edx
	wrmsr

	mov		ecx,0c0000084h			; MSR_FMASK
	mov		eax,202h				; RFLAGS
	xor		edx,edx
	wrmsr

	; enable NMI and int's
	in		al,70h
	and		al,7fh
	out		70h,al
	sti

	; goto to ring3
	mov		ax,28h				; tss
	ltr		ax

	mov		rcx,idle
	sysretq

align 16
idle:
	mov		rsi,100*1024*1024
	mov		ax,[rsi]				;!! TRIPLE FAULT HERE !!
	jmp		$

; IDT table
exc_table:
	dd		exc00 or 80000h, 8e00h
	dd		exc01 or 80000h, 8e00h
	dd		exc02 or 80000h, 8e00h
	; ....
	dd		exc31 or 80000h, 8e00h

exc00:
	jmp $

Code: Select all

00015424046i[CPU0 ] CPU is in long mode (active)
00015424046i[CPU0 ] CS.d_b = 16 bit
00015424046i[CPU0 ] SS.d_b = 16 bit
00015424046i[CPU0 ] EFER   = 0x00000501
00015424046i[CPU0 ] | RAX=0000000000000028  RBX=0000000000201027
00015424046i[CPU0 ] | RCX=0000000000001310  RDX=0000000000000000
00015424046i[CPU0 ] | RSP=000000000009fc00  RBP=0000000000000005
00015424046i[CPU0 ] | RSI=0000000006400000  RDI=0000000000001000
00015424046i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00015424046i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00015424046i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00015424046i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00015424046i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af pf cf
00015424046i[CPU0 ] | SEG selector     base    limit G D
00015424046i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00015424046i[CPU0 ] |  CS:002b( 0005| 0|  3) 00000000 ffffffff 1 0
00015424046i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 ffffffff 1 0
00015424046i[CPU0 ] |  SS:0023( 0004| 0|  3) 00000000 ffffffff 1 0
00015424046i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 ffffffff 1 0
00015424046i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 ffffffff 1 0
00015424046i[CPU0 ] |  GS:0010( 0002| 0|  0) 00000000 ffffffff 1 0
00015424046i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00015424046i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00015424046i[CPU0 ] | RIP=0000000000001317 (0000000000001317)
00015424046i[CPU0 ] | CR0=0x80000011 CR2=0x00000000009b1204
00015424046i[CPU0 ] | CR3=0x00100000 CR4=0x00000020
00015424046i[CPU0 ] 0x0000000000001317>> mov ax, word ptr ds:[rsi] : 668B06
00015424046e[CPU0 ] exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting
00015424046i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00015424046i[CPU0 ] cpu hardware reset
What the problem?

Sorry for my English.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: ring3 triple fault

Post by thepowersgang »

Check the contents of 'info idt' in the bochs debugger.

Also, from reading through your code, it doesn't quite look like the IDT is right.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
summersong
Member
Member
Posts: 32
Joined: Sat Mar 26, 2011 5:26 am
Location: Moscow

Re: ring3 triple fault

Post by summersong »

Code: Select all

Interrupt Descriptor Table (base=0x0000000000000000, limit=4095):
IDT[0x00]=64-Bit Interrupt Gate target=0x0008:00000000000017e8, DPL=0
IDT[0x01]=64-Bit Interrupt Gate target=0x0008:0000000000001880, DPL=0
IDT[0x02]=64-Bit Interrupt Gate target=0x0008:00000000000017ef, DPL=0
IDT[0x03]=64-Bit Interrupt Gate target=0x0008:0000000000001330, DPL=0
IDT[0x04]=64-Bit Interrupt Gate target=0x0008:0000000000001880, DPL=0
IDT[0x05]=64-Bit Interrupt Gate target=0x0008:0000000000001880, DPL=0
IDT[0x06]=64-Bit Interrupt Gate target=0x0008:00000000000017f6, DPL=0
IDT[0x07]=64-Bit Interrupt Gate target=0x0008:0000000000001880, DPL=0
IDT[0x08]=64-Bit Interrupt Gate target=0x0008:00000000000017fd, DPL=0
IDT[0x09]=64-Bit Interrupt Gate target=0x0008:000000000000182e, DPL=0
IDT[0x0a]=64-Bit Interrupt Gate target=0x0008:0000000000001804, DPL=0
IDT[0x0b]=64-Bit Interrupt Gate target=0x0008:000000000000180b, DPL=0
IDT[0x0c]=64-Bit Interrupt Gate target=0x0008:0000000000001812, DPL=0
IDT[0x0d]=64-Bit Interrupt Gate target=0x0008:0000000000001819, DPL=0
IDT[0x0e]=64-Bit Interrupt Gate target=0x0018:0000000000001820, DPL=0 << PF exeption: code segment with DPL=3 => working!
IDT[0x0f]=64-Bit Interrupt Gate target=0x0008:000000000000182e, DPL=0
IDT[0x10]=64-Bit Interrupt Gate target=0x0008:0000000000001880, DPL=0
IDT[0x11]=64-Bit Interrupt Gate target=0x0008:0000000000001880, DPL=0
IDT[0x12]=64-Bit Interrupt Gate target=0x0008:000000000000182e, DPL=0
IDT[0x13]=64-Bit Interrupt Gate target=0x0008:0000000000001880, DPL=0
IDT[0x14]=64-Bit Interrupt Gate target=0x0008:000000000000182e, DPL=0
IDT[0x15]=64-Bit Interrupt Gate target=0x0008:000000000000182e, DPL=0
IDT[0x16]=64-Bit Interrupt Gate target=0x0008:000000000000182e, DPL=0
I found that the exeption works if set selector of code segment with DPL=3 (app code), but I want DPL=0 (sys code).
User avatar
casnix
Member
Member
Posts: 67
Joined: Fri Jan 14, 2011 7:24 pm

Re: ring3 triple fault

Post by casnix »

Do you mean you want to generate exceptions in ring 0? I believe (from what I understand, correct me if I'm wrong) that the purpose of ring 3 is to HAVE exceptions so that the user can't screw the machine up. In ring 0, anything is possible.
You are a computer.
~ MCS ~
User avatar
summersong
Member
Member
Posts: 32
Joined: Sat Mar 26, 2011 5:26 am
Location: Moscow

Re: ring3 triple fault

Post by summersong »

"AMD64 Architecture Programmer’s Manual Volume 2: System Programming"

8.7.3 Interrupt To Higher Privilege
When a control transfer to an exception or interrupt handler running at a higher privilege occurs
(numerically lower CPL value), the processor performs a stack switch using the following steps:
1. The target CPL is read by the processor from the target code-segment DPL and used as an index
into the TSS for selecting the new stack pointer (SS:ESP). For example, if the target CPL is 1, the
processor selects the SS:ESP for privilege-level 1 from the TSS.
2. Pushes the return stack pointer (old SS:ESP) onto the new stack. The SS value is padded with two
bytes to form a doubleword.
3. Pushes the EFLAGS register onto the new stack.
4. Clears the following EFLAGS bits to 0: TF, NT, RF, and VM.
5. The processor handles the EFLAGS.IF bit based on the gate-descriptor type:
- If the gate descriptor is an interrupt gate, EFLAGS.IF is cleared to 0.
- If the gate descriptor is a trap gate, EFLAGS.IF is not modified.
6. Saves the return-address pointer (CS:EIP) by pushing it onto the stack. The CS value is padded
with two bytes to form a doubleword.
7. If the interrupt-vector number has an error code associated with it, the error code is pushed onto
the stack.
8. The CS register is loaded from the segment-selector field in the gate descriptor, and the EIP is
loaded from the offset field in the gate descriptor.
9. The interrupt handler begins executing with the instruction referenced by new CS:EIP.
I want to running exception handler in ring 0.

"8. The CS register is loaded from the segment-selector field in the gate descriptor, and the EIP is
loaded from the offset field in the gate descriptor."

But in my situation this doesn't happen.
User avatar
summersong
Member
Member
Posts: 32
Joined: Sat Mar 26, 2011 5:26 am
Location: Moscow

Re: ring3 triple fault

Post by summersong »

Long mode is the same:
8.9.3

In long mode, the return-program stack pointer (SS:RSP) is always pushed onto the interrupt-handler
stack, regardless of whether or not a privilege change occurs. Although the SS register is not used in
64-bit mode, SS is pushed to allow returns into compatibility mode. Pushing SS:RSP unconditionally
presents operating systems with a consistent interrupt-stack-frame size for all interrupts, except for
error codes. Interrupt service-routine entry points that handle interrupts generated by non-error-code
interrupts can push an error code on the stack for consistency.
In long mode, when a control transfer to an interrupt handler occurs, the processor performs the
following:
1-10. blah-blah-blah
11. Loads the segment-selector field from the gate descriptor into the CS register. The processor
checks that the target code-segment is a 64-bit mode code segment.
12. Loads the offset field from the gate descriptor into the target RIP. The interrupt handler begins
execution when control is transferred to the instruction referenced by the new RIP.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: ring3 triple fault

Post by thepowersgang »

Well, you're using the wrong CS value for the PF handler it seems, and those addresses look invalid (unless your kernel _is_ linked to below 1MB)
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
summersong
Member
Member
Posts: 32
Joined: Sat Mar 26, 2011 5:26 am
Location: Moscow

Re: ring3 triple fault

Post by summersong »

The error was in TSS, correct is:
dq 0e90000003001h + ((tss and 0xFFFFFF) shl 16) + ((tss and 0xFF000000) shl 32),tss shr 32
Post Reply