Page fault in user space

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
snbuback
Posts: 3
Joined: Sun Apr 01, 2018 7:35 am

Page fault in user space

Post by snbuback »

After a lot of refactors in my OS (so many that I totally lost the track) I end up with an issue that I couldn't find the reason. Seems a trivial issue:
When my OS starts the first program in user mode, the program, after execute a "call something" raises a page fault. I couldn't understand what is wrong.
Note that if I change the programs in user mode to run in ring 0 everything works fine.

# Here I'm still in the SO mode (just before iretq)

Code: Select all

(qemu) info registers
RAX=0000000000000000 RBX=0000000000000000 RCX=0000000000000000 RDX=0000000000000000
RSI=0000000000000000 RDI=0000000000000000 RBP=0000000000109ff8 RSP=0000000000015e60
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=00000000000049c1 RFL=00203046 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0043 0000000000000000 ffffffff 00bff300 DPL=3 DS   [-WA]
CS =0010 0000000000000000 ffffffff 00bf9a00 DPL=0 CS64 [-R-]
SS =0000 0000000000000000 00000000 00000000
DS =0043 0000000000000000 ffffffff 00bff300 DPL=3 DS   [-WA]
FS =0043 0000000000000000 ffffffff 00bff300 DPL=3 DS   [-WA]
GS =0043 0000000000000000 ffffffff 00bff300 DPL=3 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0050 000000000000d0a0 00000fff 00b08900 DPL=0 TSS64-avl
GDT=     000000000000d000 0000009f
IDT=     000000000000d120 0000032f
CR0=80000013 CR2=0000000000000000 CR3=000000000002e000 CR4=000006a0
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
EFER=0000000000000501
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80

(qemu) info mem
0000000000002000-000000000004b000 0000000000049000 -rw
0000000000100000-000000000010a000 000000000000a000 -rw
0000000000400000-0000000000404000 0000000000004000 -r-

(qemu) x/1i $eip
0x000049c1:  48 cf                    iretq

(qemu) x /1gx $esp
0000000000015e60: 0x00000000004010bb

(qemu) info tlb
0000000000002000: 0000000000002000 ----A---W
0000000000003000: 0000000000003000 ----A---W
...
0000000000100000: 0000000004001000 -------UW
0000000000101000: 0000000004002000 -------UW
0000000000102000: 0000000004003000 -------UW
0000000000103000: 0000000004004000 -------UW
0000000000104000: 0000000004005000 -------UW
0000000000105000: 0000000004006000 -------UW
0000000000106000: 0000000004007000 -------UW
0000000000107000: 0000000004008000 -------UW
0000000000108000: 0000000004009000 -------UW
0000000000109000: 000000000400a000 -------UW
0000000000400000: 0000000000128000 -------U-
0000000000401000: 0000000000129000 -------U-  <--- this is the page!
0000000000402000: 000000000012a000 -------U-
0000000000403000: 0000000004000000 -------UW
So, everything seems ready to the iretq. Actually the iretq itself runs ok, but the next instruction, just a call fails (now in user mode)

After execute iretq:

Code: Select all

(qemu) check_exception old: 0xffffffff new 0xe
2: v=0e e=0005 i=0 cpl=3 IP=0033:00000000004010bb pc=00000000004010bb SP=0043:0000000000109ff8 CR2=00000000004010bb
RAX=0000000000000000 RBX=0000000000000000 RCX=0000000000000000 RDX=0000000000000000
RSI=0000000000000000 RDI=0000000000000000 RBP=0000000000109ff8 RSP=0000000000109ff8
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=00000000004010bb RFL=00203202 [-------] CPL=3 II=0 A20=1 SMM=0 HLT=0
ES =0043 0000000000000000 ffffffff 00bff300 DPL=3 DS   [-WA]
CS =0033 0000000000000000 ffffffff 00bffa00 DPL=3 CS64 [-R-]
SS =0043 0000000000000000 ffffffff 00bff300 DPL=3 DS   [-WA]
DS =0043 0000000000000000 ffffffff 00bff300 DPL=3 DS   [-WA]
FS =0043 0000000000000000 ffffffff 00bff300 DPL=3 DS   [-WA]
GS =0043 0000000000000000 ffffffff 00bff300 DPL=3 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0050 000000000000d0a0 00000fff 00b08900 DPL=0 TSS64-avl
GDT=     000000000000d000 0000009f
IDT=     000000000000d120 0000032f
CR0=80000013 CR2=00000000004010bb CR3=000000000002e000 CR4=000006a0
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=0000000000000000 CCO=EFLAGS
EFER=0000000000000501
This is my OS logging, but I don't think is relevant at this stage.

Code: Select all

TRACE: Switching to task hello [1]. Code at 0x4010BB, stack at 0x109FF8                                                                                                                             [26/181]
DEBUG: Interruption 14 (0xE) on task hello. kernel-stack=0x15F10
FATAL: PF: addr=0x4010BB valid=1 !r=1 !w=0 !x=0 task=hello
DEBUG: =============== Dump page table begin ===============
DEBUG: ==> vaddr=0x2000          - 0x4AFFF      paddr=0x2000-0x4AFFF     size=292 KB     -rwx
DEBUG: ==> vaddr=0x100000        - 0x109FFF     paddr=0x4001000-0x400AFFF        size=40 KB      urwx
DEBUG: ==> vaddr=0x400000        - 0x402FFF     paddr=0x128000-0x12AFFF          size=12 KB      ur-x
DEBUG: ==> vaddr=0x403000        - 0x403FFF     paddr=0x4000000-0x4000FFF        size=4 KB       urwx
DEBUG: ---------------  Dump page table end  ---------------
As you could see the page fault happens on 0x4010BB due to lack of read permission, but the permission is there.
Any idea what code be wrong?
Octocontrabass
Member
Member
Posts: 5574
Joined: Mon Mar 25, 2013 7:01 pm

Re: Page fault in user space

Post by Octocontrabass »

snbuback wrote:

Code: Select all

(qemu) info mem
0000000000002000-000000000004b000 0000000000049000 -rw
0000000000100000-000000000010a000 000000000000a000 -rw
0000000000400000-0000000000404000 0000000000004000 -r-
Shouldn't that last one say "ur-" for access from user mode? All levels of the page tables need to allow user-mode access.
snbuback
Posts: 3
Joined: Sun Apr 01, 2018 7:35 am

Re: Page fault in user space

Post by snbuback »

But in the TLB they are:

Code: Select all

(qemu) info tlb
0000000000400000: 0000000000128000 -------U-
0000000000401000: 0000000000129000 -------U-  <--- this is the page!
0000000000402000: 000000000012a000 -------U-
0000000000403000: 0000000004000000 -------UW
AFAIK I just need to setup them in the TLB and in the segment. As you can see in the exception all segments are user mode (DPL=3)
I'm probably missing something, but I'm not aware.
Octocontrabass
Member
Member
Posts: 5574
Joined: Mon Mar 25, 2013 7:01 pm

Re: Page fault in user space

Post by Octocontrabass »

"info tlb" only shows the lowest level of the page table. You need to allow user access in all levels of the page table.
snbuback
Posts: 3
Joined: Sun Apr 01, 2018 7:35 am

Re: Page fault in user space

Post by snbuback »

Thanks @Octocontrabass.
That was the issue. I didn't know the the processor needs user permission to read the page tables when in user mode.
Post Reply