This innocent code takes the value of the CR2 register and puts it in the provided variable.
Code: Select all
static inline void store_cr2(u64_t *cr2)
{
bochs_bp();
__asm__ __volatile__(
"movq %%cr2,%%rax\n\t"
:"=A"(*cr2));
}
As you can easily guess this is invoked in my do_page_fault ISR.
What I didn't expect was is that, in long mode, only the low four bytes are copied and the remaining are all set.
To be more explicit if the faulting address is 0xc0010000 what is copied in RAX is 0xFFFFFFFFc0010000.
Just think what happens to my mmap routines when they want to get the PML4 offset of the linear address: in the case above they get 511 rather than 0.
This gave me headaches because I looked elsewhere for days to find where the problem was.
In long mode the CR2 is 64 bits wide but the internal debugger of Bochs shows it 32 bits wide while CPU is running in long mode.
What am I missing?? I'm cross compiling in a 32 bit environment with gcc 4.x
Thank you in advance!
Teo