solved: page-fault after iret, strange address

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
Hellbender
Member
Member
Posts: 63
Joined: Fri May 01, 2015 2:23 am
Libera.chat IRC: Hellbender

solved: page-fault after iret, strange address

Post by Hellbender »

Hi.

Solved! Selector values must be pushed as 32 bit, not as 16 bit values.
My code used "push %ax" while examples used "push $23"..

===

I've spent my whole day trying to figure out why my ring0->ring3 transition code traps at iret. The code is based on the wiki (available at https://github.com/hellbender-os/hellbender-os), and I have working paging, segments, and interrupts. I've used Bochs to validate what is in registers and in memory, and everything seems to be in order.

If I use ring0 selectors, the code works as expected but when I use ring3 selectors, I get a page fault reading an address that points to completely unused memory. All page directory entries and page table entries are 'present', 'writeable' and 'usermode'.

What puzzles me the most, is that the page fault has CR2=0x1770, while all the code and data is mapped above 1MB. Details follow, any help would be very much appreciated.

The offending code:

Code: Select all

0010177f <kernel_enter_ring3>:
  10177f:       b8 23 00 00 00          mov    $0x23,%eax
  101784:       ba 00 f0 10 00          mov    $0x10f000,%edx
  101789:       81 c2 80 3e 00 00       add    $0x3e80,%edx
  10178f:       bb 1b 00 00 00          mov    $0x1b,%ebx
  101794:       b9 10 17 10 00          mov    $0x101710,%ecx
  101799:       fa                      cli
  10179a:       8e d8                   mov    %eax,%ds
  10179c:       8e c0                   mov    %eax,%es
  10179e:       8e e0                   mov    %eax,%fs
  1017a0:       8e e8                   mov    %eax,%gs
  1017a2:       66 50                   push   %ax
  1017a4:       52                      push   %edx
  1017a5:       9c                      pushf
  1017a6:       66 53                   push   %bx
  1017a8:       51                      push   %ecx
  1017a9:       66 87 db                xchg   %bx,%bx
  1017ac:       cf                      iret
State of registers at the iret instruction:

Code: Select all

<bochs:2> r
rax: 00000000_00000023 rcx: 00000000_00101710
rdx: 00000000_00112e80 rbx: 00000000_0000001b
rsp: 00000000_00113fb4 rbp: 00000000_00000000
rsi: 00000000_00000000 rdi: 00000000_00000000
r8 : 00000000_00000000 r9 : 00000000_00000000
r10: 00000000_00000000 r11: 00000000_00000000
r12: 00000000_00000000 r13: 00000000_00000000
r14: 00000000_00000000 r15: 00000000_00000000
rip: 00000000_001017ac
eflags 0x00200002: ID vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf

<bochs:3> sreg
es:0x0023, dh=0x00c7f300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0x7fffffff, Read/Write, Accessed
cs:0x0008, dh=0x80c79b00, dl=0x0000fbff, valid=1
        Code segment, base=0x80000000, limit=0x7fbfffff, Execute/Read, Non-Conforming, Accessed, 32-bit
ss:0x0010, dh=0x00c79300, dl=0x0000ffff, valid=7
        Data segment, base=0x00000000, limit=0x7fffffff, Read/Write, Accessed
ds:0x0023, dh=0x00c7f300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0x7fffffff, Read/Write, Accessed
fs:0x0023, dh=0x00c7f300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0x7fffffff, Read/Write, Accessed
gs:0x0023, dh=0x00c7f300, dl=0x0000ffff, valid=1
        Data segment, base=0x00000000, limit=0x7fffffff, Read/Write, Accessed
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0033, dh=0x00408b10, dl=0xe0000068, valid=1
gdtr:base=0x000000000010d000, limit=0x37
idtr:base=0x000000000010d040, limit=0x7ff
GDT memory:

Code: Select all

<bochs:4> x /14wx 0x000000000010d000
[bochs]:
0x000000000010d000 <bogus+       0>:    0x00000000      0x00400000      0x0000fbff      0x80c79b00
0x000000000010d010 <bogus+      16>:    0x0000ffff      0x00c79300      0x0000fbff      0x80c7fa00
0x000000000010d020 <bogus+      32>:    0x0000ffff      0x00c7f300      0x0000ffff      0x00cf9300
0x000000000010d030 <bogus+      48>:    0xe0000068      0x00408b10
Stack:

Code: Select all

<bochs:6> x /16hx 0x00113fb4
[bochs]:
0x0000000000113fb4 <bogus+       0>:    0x1710  0x0010  0x001b  0x0002  0x0020 0x2e80  0x0011  0x0023
0x0000000000113fc4 <bogus+      16>:    0x1777  0x0010  0x0023  0x0000  0x4000 0x0011  0x001b  0x0000
Memory map:

Code: Select all

<bochs:10> info tab
cr3: 0x00000010a000
0x00103000-0x00106fff -> 0x000000103000-0x000000106fff
0x00107000-0x00107fff -> 0x0000000b8000-0x0000000b8fff
0x00108000-0x00108fff -> 0x000000108000-0x000000108fff
0x0010b000-0x0010bfff -> 0x00000010b000-0x00000010bfff
0x0010d000-0x0010efff -> 0x00000010d000-0x00000010efff
0x00110000-0x00113fff -> 0x000000110000-0x000000113fff
0x00115000-0x00116fff -> 0x000000115000-0x000000116fff
0x80100000-0x80102fff -> 0x000000100000-0x000000102fff
0xffc00000-0xffc00fff -> 0x00000010c000-0x00000010cfff
0xffe00000-0xffe00fff -> 0x000000109000-0x000000109fff
0xfffff000-0xffffffff -> 0x00000010a000-0x00000010afff
When I step over the iret, I get trap 14 with the following stack, CR2:

Code: Select all

0x0000000000113fa4 <bogus+       0>:    0x0000  0x0000  0x17ac  0x0010  0x0008 0x0000  0x0002  0x0021
CR2=page fault laddr=0x0000000000001770
Hellbender OS at github.
Post Reply