Page 1 of 1

General Protection Fault on context switch

Posted: Fri Jul 05, 2019 5:52 am
by Crumble14
Hello,

I'm currently trying to switch to ring 3 on my kernel. However when I try, I get a General Protection Fault.

Here is my GDT:

Code: Select all

.align 8

gdt_start:
gdt_null:
	.quad 0

gdt_kernel_code:
	.word 0xffff
	.word 0
	.byte 0
	.byte 0b10011010
	.byte 0b11001111
	.byte 0

gdt_kernel_data:
	.word 0xffff
	.word 0
	.byte 0
	.byte 0b10010010
	.byte 0b11001111
	.byte 0

gdt_user_code:
	.word 0xffff
	.word 0
	.byte 0
	.byte 0b11111010
	.byte 0b11001111
	.byte 0

gdt_user_data:
	.word 0xffff
	.word 0
	.byte 0
	.byte 0b11110010
	.byte 0b11001111
	.byte 0

gdt_tss:
	.quad 0

gdt:
	.word gdt - gdt_start - 1
	.long gdt_start
(My TSS is initialized somewhere else, see: viewtopic.php?f=1&t=33720)

Here is my code for context switching:

Code: Select all

.global context_switch

context_switch:
	push %ebp
	mov %esp, %ebp

	mov $GDT_USER_DATA_OFFSET, %ax
	mov %ax, %ds
	mov %ax, %es
	mov %ax, %fs
	mov %ax, %gs

	push $GDT_USER_DATA_OFFSET
	push 8(%ebp)
	pushf
	push $GDT_USER_CODE_OFFSET
	push 16(%ebp)

	iret

	# TODO Error handling

	mov %ebp, %esp
	pop %ebp
	ret
I'm calling this function from C code, its prototype is:

Code: Select all

extern void context_switch(void *esp, void *eip);
I'm passing a pointer to the last byte of an allocated page of memory in esp (for the stack) and a function pointer for eip.
The error happens when reaching the iret instruction.
When catching the General Protection Fault interrupt, the error code tells me that the problem comes from segment 0x18 (gdt_user_code).

Am I doing something wrong?