Page 1 of 1

no page fault with esp

Posted: Mon Jan 14, 2013 10:13 am
by tonydemann
Hi @all,

i have a question. I've tried to set up Paging in my Kernel and i've mapped my physical Kernel location (1mb, 0x100000) to virtual 3gb (0xc0000000). Everything is fine with it, but then i want to have my stack pointer 4 bytes below the virtual kernel position at 0xbffffffc. So i allocate another 4mb in my physical memory manager and create a new page table and add it to my page directory at the 0xbfc00000 location so it maps the allocated 4mb from 0xbfc00000 to 0xc0000000. When i try to write a simple value to all of the 4mb to test it, it works, like so:

Code: Select all

uint32_t* test = (uint32_t *) 0xBFC00000;
for(int i = 0; i < (1024 * 1024); i++)
{
*test = 123456;
}
No page fault or somewhat else. Then i put the esp to the 0xBFFFFFFC location (_asm mov esp, 0xBFFFFFFC) and it still works fine. So i decided to check, if it throws a page fault, when i push the 4mb i allocated for the stack until its full like so:

Code: Select all

for(int i = 0; i < (1024 * 1024); i++)
{
_asm push eax
}
And this doesnt work. I figured out, that the last value for esp without crashing is 0xBFCC908C. Then it crashes without a page fault, it only halts and that was it. What am i doing wrong here?

Re: no page fault with esp

Posted: Mon Jan 14, 2013 12:17 pm
by bluemoon
In kernel mode if the stack is not usable and a fault occur, the CPU cannot push information on the stack and will cause double fault, if that is not handled properly you get tripple fault and reset.

To test page fault you may just access the location with data pointer instead of messing with stack.

Re: no page fault with esp

Posted: Mon Jan 14, 2013 12:32 pm
by tonydemann
Ok i know that the CPU cannot push information on the stack if it is not usable. But it crashes at virtual address 0xBFCC908C. Normally i would expect it to crash at 0xBFC00000 because the PageDirectory begins here (so it ends for the stack).

Another question is, what size is a good solution for the stack in the Kernel? I figured out that the Kernel-Mode stack in Windows Nt for example is only 12k, is that right? And where is a good place for the stack? Like I did, 4bytes below the kernel or another location?

Re: no page fault with esp

Posted: Mon Jan 14, 2013 12:40 pm
by bluemoon
tonydemann wrote:Ok i know that the CPU cannot push information on the stack if it is not usable. But it crashes at virtual address 0xBFCC908C. Normally i would expect it to crash at 0xBFC00000 because the PageDirectory begins here (so it ends for the stack).
It should crash at CR2=BFBFFFFC if you have the correct mechanism to catch the fault (e.g. task gate, IST, or debugger),
So I suspect either there is bug elsewhere or problem in the method that you come up to get the magic number 0xBFCC908C.
tonydemann wrote:Another question is, what size is a good solution for the stack in the Kernel? I figured out that the Kernel-Mode stack in Windows Nt for example is only 12k, is that right? And where is a good place for the stack? Like I did, 4bytes below the kernel or another location?
The two major design are one kernel stack per thread, and one kernel stack per core.
For one kernel stack per thread you normally squeeze everything out of stack to minimize footprint and thus use a few KB for just handling IRQs and simple things - small stack is not a requirement, but a goal.

For one kernel stack per core the budget is more flexible.

Re: no page fault with esp

Posted: Mon Jan 14, 2013 12:42 pm
by chaoscode
maybe you shoud increment the address when performing a writetest?
*test++ = 123456;
To Which physical Address range is the Stack Mapped?
maybe you're writing in a special Memory Region?
(Bios, APIC, SMM?)

Re: no page fault with esp

Posted: Mon Jan 14, 2013 12:58 pm
by tonydemann
I pass the BiosMemoryMap from the bootloader to my Kernel and only initialize the physical memory as free, which is marked as available in the BiosMemoryMap, so i think i cant write into a special memory location. When i test writing to the allocated 4mb block i want to use for the stack with a normal pointer it works, only with the esp it does not :/

Re: no page fault with esp

Posted: Mon Jan 14, 2013 1:34 pm
by chaoscode
Well, i read your testcode as if it writes always to the same location...

Re: no page fault with esp

Posted: Mon Jan 14, 2013 2:17 pm
by tonydemann
Oh, i'm sorry, i forgot "test++" in this post, the real source code is:

Code: Select all

uint32_t* test = (uint32_t *) 0xBFC00000;
for(int i = 0; i < (1024 * 1024); i++, test++)
{
*test = 123456;
}

Re: no page fault with esp

Posted: Mon Jan 14, 2013 2:34 pm
by bluemoon
tonydemann wrote:I pass the BiosMemoryMap from the bootloader to my Kernel and only initialize the physical memory as free, which is marked as available in the BiosMemoryMap, so i think i cant write into a special memory location. When i test writing to the allocated 4mb block i want to use for the stack with a normal pointer it works, only with the esp it does not :/
Since using push within inline assembly block is generally no-no, I suggest you dump the assembly code and double check.

Re: no page fault with esp

Posted: Mon Jan 14, 2013 3:25 pm
by Combuster
I can see it reaching the end of the push loop, followed by a function epilogue which sends code flying to wherever EAX was pointing to - probably in data land with all the random consequences thereof.

Re: no page fault with esp

Posted: Tue Jan 15, 2013 3:12 am
by tonydemann
Ok, but then i have another question. When the page fault interrupt tries to put some things on the stack, it double faults because the stack pointer is not valid. But how can i catch stack overflows then?

Re: no page fault with esp

Posted: Tue Jan 15, 2013 3:22 am
by bubach
That's not very hard depending on what you want to do in your fault handler. Do you expect to recover from it? You could output error messages directly to 0xb8000 without using the stack or have a secondary stack space just for that handler.

Re: no page fault with esp

Posted: Tue Jan 15, 2013 3:42 am
by bluemoon
tonydemann wrote:Ok, but then i have another question. When the page fault interrupt tries to put some things on the stack, it double faults because the stack pointer is not valid. But how can i catch stack overflows then?
Hints are on my 2nd reply. But if the kernel stack messed up you are doomed anyway.