Page 1 of 1

[SOLVED] Problem using task gate as double fault handler

Posted: Sat Jul 25, 2009 12:03 pm
by gzaloprgm
Hi, I am trying to create a double fault handler in order to catch stack faults and hopefully show useful information.

To do so, I created a TSS and added it to the GDT. (base=Address of TSS, limit=sizeof(TSS), access=0xE9, gran=0xCF)

Then, I set in the new TSS eip, cr3, cs, ds, es, fs, gs, ss, esp and eflags of the handler.

To set the task gate into the IDT, I am using index=8, base=0, selector=0x30, flags=0x85.

Now I am trying some tests to check if it works:

Code: Select all

asm volatile("int $8");
/
asm volatile("jmp $(0x30),$0");
Both work fine in qemu, bochs, virtual box and vmware.

However, when I try to do a double fault (ie. by changing esp to a unmapped page and then trying to push/pop something), the handler does not work :shock:

In qemu it crashes.
In bochs and vmware works.
In vbox doesn't crash but the handler isn't executed.

Why whould this happen? Am I missing some flag?
Thanks,
Gzaloprgm

Re: Problem using task gate as double fault handler

Posted: Sat Jul 25, 2009 4:05 pm
by pcmattman
Did you zero your TSS first?

Re: Problem using task gate as double fault handler

Posted: Sat Jul 25, 2009 4:09 pm
by gzaloprgm
Yes, I am zeroing it.

Re: Problem using task gate as double fault handler

Posted: Sat Jul 25, 2009 4:27 pm
by pcmattman
Apart from the fields you specified, are you setting anything else in the TSS (SS0:ESP0, for instance)?

Re: Problem using task gate as double fault handler

Posted: Sat Jul 25, 2009 4:58 pm
by gzaloprgm
Nope, I am memseting every other field to zero. Should I set them? The double fault I want to catch is happening in ring0.

Code: Select all

-GDT:

gdtSetGate(6, (unsigned int) &tssEntryDFault, sizeof( tssEntry_t ), 0xE9, 0xCF );

memset(&tssEntryDFault,0,sizeof(tssEntry_t));
tssEntryDFault.eip=(unsigned int)&test;
tssEntryDFault.cr3=0x1000;
tssEntryDFault.cs = 0x08;
tssEntryDFault.ds = 0x10;
tssEntryDFault.es = 0x10;
tssEntryDFault.fs = 0x10;
tssEntryDFault.gs = 0x10;
tssEntryDFault.ss = 0x10;
tssEntryDFault.esp= (unsigned int)stack + 0x1000;
tssEntryDFault.eflags = 2;

-IDT:

idtSetGate(8, 0, 0x30, 0x85);

Stack is just a an array of chars. Test function only displays a message and halts.

EDIT: If I make the page fault handler with a task gate, it works. So I think that either is a bug of qemu and vbox or a really nasty bug in my kernel. Can anyone confirm that?

EDIT2: My structs are correctly packed, GDT and IDT limits are ok.

EDIT3: After running it in a newer version of qemu, it works. (I was using 0.9.0, now 0.10.5)

Thanks,
gzaloprgm

Re: [SOLVED] Problem using task gate as double fault handler

Posted: Sat Aug 01, 2009 5:18 am
by Combuster
I suggest trying real hardware and check if it works there. Hardware task switching isn't a common application nowadays, so I expect qemu (and its descendant vbox) are a bit less tested on that, while real hardware doesn't quite have that excuse.

That can help you eliminate vbox, as well as being a good thing to do anyway :wink: