Page 1 of 1

long mode, interrupt and stack issue

Posted: Mon Oct 05, 2015 1:28 pm
by spectrum
Hello !

i have the current weird issue:
I am just entered in long mode, from a kernel_main() IDT is set up.
At a certain point, after some code is executed, a "Page Fault" interrupt is issued.

Once from asm interrupt handler i call a C generic handler, stack looks messed up,
the stack "rsp" reg seems containing a nonsense value.

Code: Select all

_isr_0E:
	cli
	pushq	$0
	pushq	$14
	jmp	_isr_common_stub

....

_isr_common_stub:
	save
	pushq	$0x01
	pushq	$0x02
	pushq	$0x03
	movq	%rsp, %rax
	pushq	%rax			/* push struct _irq_regs* on the stack */
	mov	$_isr_handler, %rax
	call	*%rax
	mov	%rax, retval		/* tmp save retval */
	pop	%rax
	restore
	add	$4, %rsp		/* error code and int no */
	mov	retval, %rax		/* set retval in eax */
	iretq

Well, the push 1, 2, 3 are just test values. In the C code
i don't receive anything that have sense.

If some idea on the issue it's really welcome.
I was thinking to some calling convention issue from asm to C, but can be completely wrong.


Thanks

Re: long mode, interrupt and stack issue

Posted: Mon Oct 05, 2015 3:18 pm
by Octocontrabass

Code: Select all

	pushq	$0
	pushq	$14
Page faults push an error code, so you shouldn't push one here.

Code: Select all

	pushq	$0x01
	pushq	$0x02
	pushq	$0x03
	movq	%rsp, %rax
	pushq	%rax			/* push struct _irq_regs* on the stack */
The AMD64 System V ABI specifies that the first six arguments are passed in registers, not on the stack. There are some other important details you need to know in order to call a function correctly, but I'm not familiar enough to list them all.

Code: Select all

	add	$4, %rsp		/* error code and int no */
Are you sure four bytes is the right amount?

Code: Select all

	mov	retval, %rax		/* set retval in eax */
Your interrupt handler is already free to modify registers in the _irq_regs struct, so there's no need to explicitly return a separate value.

Re: long mode, interrupt and stack issue

Posted: Mon Oct 05, 2015 4:56 pm
by spectrum
Hi Octocontrabass,
The AMD64 System V ABI specifies that the first six arguments are passed in registers, not on the stack. There are some other important details you need to know in order to call a function correctly, but I'm not familiar enough to list them all.
A special thanks. This is the "expert" answer i was looking for. And my issue since i was coming from 32bit.

Code: Select all

If the class is INTEGER (pointers too), the next available register of the sequence
%rdi, %rsi, %rdx, %rcx, %r8 and  %r9 is used

Thanks again,
cheers