Page 2 of 4

Posted: Fri May 02, 2008 4:31 am
by jal
If you are using GCC, put this after your variables:

Code: Select all

__attribute__((aligned(4096)))
This will ensure proper allignment.


JAL

Posted: Mon May 05, 2008 4:53 am
by White-spirit
jal wrote:If you are using GCC, put this after your variables:

Code: Select all

__attribute__((aligned(4096)))
This will ensure proper allignment.


JAL
Thanks very much, it works perfectly :-)

Posted: Mon May 05, 2008 6:22 am
by jal
White-spirit wrote:Thanks very much, it works perfectly :-)
Glad I could be of help. This trick should also be used for other structures that need to be alligned at a certain boundary, e.g. TSS (also needs 4Kb allignment) and GDT/IDT (which should have 8 byte allignment, for cache optimalization, see Intel manuals).


JAL

Posted: Mon May 05, 2008 7:21 am
by White-spirit
Okay thanks for the info :)

Just one more question, it is normal that many GPF happen after a page fault ?
I'm trying to access 0xFFFFFFFF to see if the page fault handler works, effectively, an interrupt 14 is executed, but after, I get so many GPFs, with this error message in Bochs :

Code: Select all

read_virtual_checks(): read beyond limit

Posted: Mon May 05, 2008 9:19 am
by jal
White-spirit wrote:Just one more question, it is normal that many GPF happen after a page fault ?
No, I'm afraid not :).
I'm trying to access 0xFFFFFFFF to see if the page fault handler works, effectively, an interrupt 14 is executed, but after, I get so many GPFs, with this error message in Bochs :

Code: Select all

read_virtual_checks(): read beyond limit
What is 'after'? Still in your handler, or after the IRET?


JAL

Posted: Mon May 05, 2008 10:25 am
by AJ
In all likelyhood, your stack is getting trashed in your PFE handler, resulting in an attempt to IRET to an invalid segment.

Cheers,
Adam

Posted: Mon May 05, 2008 11:32 am
by White-spirit
Hello,

It's after IRET according to Bochs's debugger .
I've tested int $0xE ( instead of initializing a pointer to 0xFFFFFFFF ) to test a page fault exception, and I get an interrupt 14 followed by GPFs, in the bochs console I see this : "check_cs: conforming code seg descriptor dpl > cpl" .

Posted: Mon May 05, 2008 12:08 pm
by AJ
Yup - as I said, that would indicate your stack is becoming misaligned. Check that you really are popping everything which you push in your PFE handler. For example, if your PFE handler starts with:

Code: Select all

   push 0x0E    ; interrupt #
   push 0         ; dummy error code
as many people seem to do, make sure you add 8 to your ESP before doing an IRET.

OTOH, If you don't push an interrupt # and error code, make sure you haven't copied code from a stub which does, because it will add 8 to ESP and you don't need to.

In the example above, I have assumed that you are in 32 bit PMode. In long mode, you will of course need to add 16 to RSP (rather than adding 8 to ESP) and do an IRETQ instead of an IRET(D).

Cheers,
Adam

Posted: Tue May 06, 2008 1:53 am
by White-spirit
Yes I'm sure the handler does add 8 to esp register ( all the interrupts have the same handler, and all they work except of interrupt 14 ... :/ ) .

One more question, the interrupt 14 pushes an error code ? So there are two pushes ? That's what I'm doing and it doesn't work :/

Posted: Tue May 06, 2008 1:57 am
by pcmattman
So there are two pushes
There's your problem :D

The processor automatically pushes the error code, so there's only one push. On non-error-code faults, you need to push a fake error code (hence two pushes).

Posted: Tue May 06, 2008 2:02 am
by White-spirit
pcmattman wrote:
So there are two pushes
There's your problem :D

The processor automatically pushes the error code, so there's only one push. On non-error-code faults, you need to push a fake error code (hence two pushes).
That's what I say ^^"

Here's the isr code, and it seem to be correct :

Code: Select all

public isr0

isr0:

cli

push 0

push 0

jmp isr_common_stub



rept 31 id

{

public isr#id

isr#id:

cli

if ~ ( id > 7 & id < 15 )

push 0

end if

push id

jmp isr_common_stub

}
isr_common_stub:

pusha

mov ax,ds

push eax

mov ax,0x10				; ax <== 10h

mov ds,ax				; ds <== 10h

mov es,ax				; es <== 10h

mov fs,ax				; fs <== 10h

mov gs,ax				; eg <== 10h

call isr_handler

pop ebx					; restores the old values

mov ds,bx

mov es,bx

mov fs,bx

mov gs,bx

popa

add esp, 8

sti

iret


Posted: Tue May 06, 2008 2:04 am
by pcmattman
Ah, sorry, didn't understand what you'd said. It seems that your code should work (though that macro looks trippy...).

Posted: Tue May 06, 2008 2:11 am
by White-spirit
It's the same if I don't use paging ... I'ill see how many values are pushed by isr14 .

Posted: Tue May 06, 2008 2:12 am
by pcmattman
This looks suspicious, but I'm not 100% sure:

Code: Select all

if ~ ( id > 7 & id < 15 ) 
Shouldn't that & be an &&? Or do I just not understand the syntax?

Posted: Tue May 06, 2008 4:03 am
by jal
pcmattman wrote:This looks suspicious, but I'm not 100% sure:

Code: Select all

if ~ ( id > 7 & id < 15 ) 
Shouldn't that & be an &&? Or do I just not understand the syntax?
It looks suspicious indeed, but it works, since & has a low priority. So id > 7 and id < 15 are evaluated (yielding 0 or 1), and the result is 0 or 1.


JAL