Page fault on iret?
Posted: Fri Oct 03, 2025 12:37 pm
I've gotten exceptions working for i686, here's my stub for it:
So I've worked on porting everything in my OS so far to x86_64, and it mostly works, except I for some reason get a page fault on iret. Here's my stub:
With gdb (setting a breakpoint at the ISR's first and last instruction) I verified that RSP is the same on entry and exit from the interrupt, so it's not trying to restore some junk state:
Here's the section of the QEMU logs containing the original interrupt (keyboard, 0x21) and the following page fault:
And here's the QEMU monitor's paging information (you'll notice I was too lazy to remove the VGA text buffer's identity mapping
):
Does anybody know what's going on here? Again, this all works fine on 32-bit. As you can see, the address it's trying to access here seems to be 0x187f88: I have no idea where that comes from...
Code: Select all
.macro isr vec
.global _isr_\vec
.type _isr_\vec, @function
_isr_\vec:
pushal
cld
call isr_\vec
popal
iret
.endm
Code: Select all
/* Doesn't save SSE/SSE2/MMX state, but we don't use that in the kernel anyways. */
.macro pushaq
pushq %rax
[...]
pushq %r15
.endm
.macro popaq
popq %r15
[...]
popq %rax
.endm
.macro isr vec
.global _isr_\vec
.type _isr_\vec, @function
_isr_\vec:
pushaq
cld
call isr_\vec
popaq
iret
.endm
Code: Select all
(gdb) print $rsp
$1 = (void *) 0xffffc00000187f88
(gdb) c
Continuing.
(gdb) print $rsp
$2 = (void *) 0xffffc00000187f88
Code: Select all
Servicing hardware INT=0x21
0: v=21 e=0000 i=0 cpl=0 IP=0008:ffffc000000007c0 pc=ffffc000000007c0 SP=0010:ffffc00000187fb0 env->regs[R_EAX]=0000000000000000
RAX=0000000000000000 RBX=ffffc00000100010 RCX=ffffc00000100120 RDX=00000000000003f8
RSI=000000000000000a RDI=0000000000000020 RBP=ffffc00000187ff0 RSP=ffffc00000187fb0
R8 =cccccccccccccccd R9 =ffffc000001989b1 R10=0000000000000000 R11=0000000000000000
R12=ffffc00000000a30 R13=ffffc00000000a80 R14=ffffc00000080052 R15=ffffc000000012a0
RIP=ffffc000000007c0 RFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 0000000000000000 ffffffff 00af9b00 DPL=0 CS64 [-RA]
SS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT= 0000000000200010 00000017
IDT= ffffc00000188fe0 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000203000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000044 CCD=0000000000000000 CCO=EFLAGS
EFER=0000000000000500
check_exception old: 0xffffffff new 0xe
1: v=0e e=0000 i=0 cpl=0 IP=0008:ffffc00000000069 pc=ffffc00000000069 SP=0010:ffffc00000187f88 CR2=0000000000187f88
RAX=0000000000000000 RBX=ffffc00000100010 RCX=ffffc00000100120 RDX=00000000000003f8
RSI=000000000000000a RDI=0000000000000020 RBP=ffffc00000187ff0 RSP=ffffc00000187f88
R8 =cccccccccccccccd R9 =ffffc000001989b1 R10=0000000000000000 R11=0000000000000000
R12=ffffc00000000a30 R13=ffffc00000000a80 R14=ffffc00000080052 R15=ffffc000000012a0
RIP=ffffc00000000069 RFL=00000097 [--S-APC] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 0000000000000000 ffffffff 00af9b00 DPL=0 CS64 [-RA]
SS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT= 0000000000200010 00000017
IDT= ffffc00000188fe0 00000fff
CR0=80000011 CR2=0000000000187f88 CR3=0000000000203000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000008 CCD=fffffffffffffff9 CCO=SUBB
EFER=0000000000000500
Code: Select all
(qemu) info mem
00000000000b8000-00000000000b9000 0000000000001000 -rw
0000000000200000-0000000000201000 0000000000001000 -rw
ffffc00000000000-ffffc00000002000 0000000000002000 -rw
ffffc00000080000-ffffc00000081000 0000000000001000 -rw
ffffc00000100000-ffffc00000101000 0000000000001000 -rw
ffffc00000180000-ffffc0000018b000 000000000000b000 -rw
ffffc00000200000-ffffc00000201000 0000000000001000 -rw
ffffff8000000000-ffffff8000002000 0000000000002000 -rw
ffffffe000000000-ffffffe000002000 0000000000002000 -rw
ffffffffc0000000-ffffffffc0001000 0000000000001000 -rw
fffffffff0000000-fffffffff0001000 0000000000001000 -rw
ffffffffffe00000-ffffffffffe01000 0000000000001000 -rw
fffffffffff80000-fffffffffff81000 0000000000001000 -rw
fffffffffffff000-0001000000000000 0000000000001000 -rw