Page 1 of 1

4-level paging works on QEMU but not on bochs (RESOLVED)

Posted: Fri Oct 19, 2018 5:23 am
by mazzal
Hi,

I have 4-level paging working fine on QEMU, everything works but on bochs it fails very early as soon as I enable paging.
Here is the relevant code: https://pastebin.com/r9Bb5DXw

I use 1GB pages as I can't get 2MB pages to work but that's another issue.

Here are all the register values just before enabling paging:

Code: Select all

<bochs:54> 
Next at t=16809678211
(0) [0x0000010010b2] 0008:00000000010010b2 (unk. ctxt): mov cr0, eax              ; 0f22c0
<bochs:55> creg
CR0=0x60000011: pg CD NW ac wp ne ET ts em mp PE
CR2=page fault laddr=0x0000000000000000
CR3=0x00000100a000
    PCD=page-level cache disable=0
    PWT=page-level write-through=0
CR4=0x00000020: pke smap smep osxsave pcid fsgsbase smx vmx osxmmexcpt umip osfxsr pce pge mce PAE pse de tsd pvi vme
CR8: 0x0
EFER=0x00000100: ffxsr nxe lma LME sce
<bochs:56> sreg
es:0x0000, dh=0x00001000, dl=0x00000000, valid=0
cs:0x0008, dh=0x00cf9f00, dl=0x0000ffff, valid=1
	Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Conforming, Accessed, 32-bit
ss:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=31
	Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
ds:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=31
	Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
fs:0x0010, dh=0x00cf9300, dl=0x0000ffff, valid=1
	Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
gs:0x0000, dh=0x00001000, dl=0x00000000, valid=0
ldtr:0x0000, dh=0x00008200, dl=0x0000ffff, valid=1
tr:0x0000, dh=0x00008b00, dl=0x0000ffff, valid=1
gdtr:base=0x000000000100fd34, limit=0x17
idtr:base=0x0000000000000000, limit=0x0
<bochs:57> reg
CPU0:
rax: 00000000_e0000011
rbx: 00000000_00000083
rcx: 00000000_c0000080
rdx: 00000000_00000000
rsp: 00000000_0101d000
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_010010b2
eflags 0x00000086: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af PF cf
<bochs:58>
Here is my 32-bit GDT:

GDTR:

Code: Select all

(0) [0x000001001023] 0010:0000000001001023 (unk. ctxt): lgdt ds:0x0100fd4c        ; 0f01154cfd0001
<bochs:12> x/2wx 0x100fd4c
[bochs]:
0x000000000100fd4c <bogus+       0>:	0xfd340017	0x00000100
GDT entries:

Code: Select all

<bochs:13> x/10wx 0x100fd34
[bochs]:
0x000000000100fd34 <bogus+       0>:	0x00000000	0x00000000	0x0000ffff	0x00cf9f00
0x000000000100fd44 <bogus+      16>:	0x0000ffff	0x00cf9200	0xfd340017	0x00000100
0x000000000100fd54 <bogus+      32>:	0x00000000	0x00000000
Here are my paging structures:

Code: Select all

<bochs:58> x/2wx 0x00000100a000
[bochs]:
0x000000000100a000 <bogus+       0>:	0x0100b003	0x00000000
<bochs:59> x/2wx 0x00000100b000
[bochs]:
0x000000000100b000 <bogus+       0>:	0x00000083	0x00000000
Not sure why bochs is displaying "bogus"... So as you can see I have the PML4 pointing to a PDPT entry describing a large 1GB page starting at physical address 0x0, this is the identity mapping.

Then when I step, here is the error:

Code: Select all

<bochs:60> step
Next at t=16809678212
(0).[16809678212] ??? (physical address not available)
Here is the bochs version information:

Code: Select all

========================================================================
                     Bochs x86 Emulator 2.6.9.svn
              Built from SVN snapshot after release 2.6.9
                  Compiled on Oct 19 2018 at 11:44:38
========================================================================
Compiled with:

Code: Select all

../configure --prefix=$HOME/opt --enable-smp \
              --enable-cpu-level=6 \
              --enable-all-optimizations \
              --enable-x86-64 \
              --enable-pci \
              --enable-vmx=2 \
              --enable-debugger \
              --enable-disasm \
              --enable-debugger-gui \
              --enable-logging \
              --enable-fpu \
              --enable-3dnow \
              --enable-sb16=dummy \
              --enable-cdrom \
              --enable-x86-debugger \
              --enable-iodebug \
              --disable-plugins \
              --disable-docbook \
              --with-x --with-x11 --with-term --with-sdl2
Am I missing something obvious?

Thanks,

Re: 4-level paging works on QEMU but not on bochs

Posted: Fri Oct 19, 2018 5:57 am
by flerovium
Hi,

I think I faced a similar problem when implementing my 64-bit bootstrap code.
For me it worked in QEMU, but not in QEMU KVM or Bochs iirc. Using 2MiB pages instead of 1GiB pages did fix the issue for me, however I'm
not sure either what the exact cause is. My guess is that not all CPUs or emulators support 1GiB pages.

Best,
hackiosa

Re: 4-level paging works on QEMU but not on bochs

Posted: Fri Oct 19, 2018 6:09 am
by iansjack
Have you enabled 1GB pages (a poor choice IMO) in bochsrc?

Re: 4-level paging works on QEMU but not on bochs

Posted: Fri Oct 19, 2018 6:45 am
by mazzal
Thanks a lot guys, I completely missed the existence of the 1g_pages option for bochs... :oops:

I added

Code: Select all

cpuid: level=6, 1g_pages=1
in my .bochsrc file and now it works.

Now I will try to figure out why I can't get 2MB pages to work but that's a separate issue of course.

EDIT: I had a bug in my 2MB paging code, I used the wrong PDE entry, now everything is working :D .

Thanks!

Re: 4-level paging works on QEMU but not on bochs

Posted: Sat Oct 20, 2018 2:59 am
by stlw
mazzal wrote:Thanks a lot guys, I completely missed the existence of the 1g_pages option for bochs... :oops:

I added

Code: Select all

cpuid: level=6, 1g_pages=1
in my .bochsrc file and now it works.

Thanks!
You have dozen of pre-defined cpu models in Bochs which define entire set of features at once, why to use old CPUID knob ?
I am thinking of removing the old CPUID knob as number of options grow rapidly and people easily get lost between them.

Re: 4-level paging works on QEMU but not on bochs

Posted: Sat Oct 20, 2018 7:29 am
by mazzal
stlw wrote: You have dozen of pre-defined cpu models in Bochs which define entire set of features at once, why to use old CPUID knob ?
I am thinking of removing the old CPUID knob as number of options grow rapidly and people easily get lost between them.
Thanks! I removed the cpuid line and now I have:

Code: Select all

cpu: ips=70000000, model=corei7_sandy_bridge_2600k