Long Mode Interrupts - Stack Alignment
Posted: Mon Jan 14, 2008 4:36 am
Hi All,
I was really hoping to solve this without posting, but it's really getting annoying now - I think I have made a small mistake which is causing me 64 bit interrupt handing problems. I think that whenever I IRET, my stack has somehow become misaligned. My ISR:
Fairly simple, then. but, the first time the timer IRQ fires, the IRET causes a GPF:
Fine - I would expect the GDT index to be outside the limits with a selector of 0xF007, but why is it trying to load that descriptor? If I pop 5 registers manually from the stack before the IRET and then do a HLT, I see my expected values of RIP, CS, RFLAGS, RSP and SS in Bochs.
Of course, the GPF keeps happening after the first IRQ and I eventually triple fault when I run out of stack space. Oh - I am using proper 64 bit IDT entries with IST set to zero.
In case it helps, here is the Bochs Register Dump:
You can see here what I mean about overrunning the stack - this is fine and is not the immediate problem as I haven't written my stack-space paging code yet.
So, what really obvious point have I missed in the AMD 64 bit architecture guide?
Cheers,
Adam
[edit - I just posted that I had fixed this, but I hadn't - same problem after an update to Bochs 2.3.6]
I was really hoping to solve this without posting, but it's really getting annoying now - I think I have made a small mistake which is causing me 64 bit interrupt handing problems. I think that whenever I IRET, my stack has somehow become misaligned. My ISR:
Code: Select all
[BITS 64]
%macro mIRQ 1 ;Hardware IRQ
[global irq%1]
irq%1:
cli
push qword %1
push qword %1+IRQ_START
jmp int_common ;see below for this routine
%endmacro
; 16 IRQs
%assign i 0
%rep 16
mIRQ i
%assign i i+1
%endrep
int_common:
; when I have this working, I will push regs and call a C++ handler here
add rsp, 16 ;remove error code and irq #
iret
Code: Select all
00023924389e[CPU0 ] fetch_raw_descriptor: GDT: index (f007)1e00 > limit (38)
Of course, the GPF keeps happening after the first IRQ and I eventually triple fault when I run out of stack space. Oh - I am using proper 64 bit IDT entries with IST set to zero.
In case it helps, here is the Bochs Register Dump:
Code: Select all
00023924389e[CPU0 ] fetch_raw_descriptor: GDT: index (f007)1e00 > limit (38)
... (above line * loads of times)...
00023924389i[CPU0 ] long mode
00023924389i[CPU0 ] CS.d_b = 16 bit
00023924389i[CPU0 ] SS.d_b = 16 bit
00023924389i[CPU0 ] EFER = 0x00000501
00023924389i[CPU0 ] | RAX=fffff00000005380 RBX=fffff00000006bf0
00023924389i[CPU0 ] | RCX=000000000000008e RDX=0000000000000008
00023924389i[CPU0 ] | RSP=ffffffbfffff0018 RBP=0000000000000000
00023924389i[CPU0 ] | RSI=00000000fffff000 RDI=fffff00000006370
00023924389i[CPU0 ] | R8=0000000000000000 R9=fffff00000005380
00023924389i[CPU0 ] | R10=000000000000000a R11=0000000000000258
00023924389i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00023924389i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00023924389i[CPU0 ] | IOPL=0 ID vip vif ac vm RF nt of df if tf SF zf af PF cf
00023924389i[CPU0 ] | SEG selector base limit G D
00023924389i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00023924389i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 0
00023924389i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 0
00023924389i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 0
00023924389i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 0
00023924389i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 0
00023924389i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 0
00023924389i[CPU0 ] | MSR_FS_BASE:0000000000000000
00023924389i[CPU0 ] | MSR_GS_BASE:0000000000000000
00023924389i[CPU0 ] | RIP=fffff00000002069 (fffff00000002069)
00023924389i[CPU0 ] | CR0=0x80000011 CR1=0x0 CR2=0xffffffbffffefff8
00023924389i[CPU0 ] | CR3=0x0141d000 CR4=0x00000031
00023924389i[CPU0 ] >> iretd : CF
00023924389p[CPU0 ] >>PANIC<< exception(): 3rd (14) exception with no resolution
So, what really obvious point have I missed in the AMD 64 bit architecture guide?
Cheers,
Adam
[edit - I just posted that I had fixed this, but I hadn't - same problem after an update to Bochs 2.3.6]