Page 1 of 1

Lguest32: Setting SS gives a general protection exception

Posted: Thu Aug 12, 2010 4:39 pm
by dc740
Hello everyone. I've been trying to set the GDT under LGuest for a testing OS.

I can load the GDT, update ES;DS;CS... but when I also update SS, the OS crashes and leaves lguest.

Code: Select all

static gdt_entry_t gdt_entries[5] =
{GDT_ENTRY_INIT(0x0,0x0,0x0),
GDT_ENTRY_INIT(0xC09A,0x0,0xFFFFFFFF),
GDT_ENTRY_INIT(0xC092,0x0,0xFFFFFFFF),
GDT_ENTRY_INIT(0xC0FA,0x0,0xFFFFFFFF),
GDT_ENTRY_INIT(0xC0F2,0x0,0xFFFFFFFF)};
that's my GDT table.
then I try to load SS, and I get the general protection exception. This is my "setup_GDT"

Code: Select all

setup_gdt:
	movw  $0x10,%ax
	movw %ax,%ds
	movw %ax,%es
	movw %ax,%fs
	movw %ax,%gs
// TODO: FIXME!!!!If I comment out this, it works without issues
	movw %ax,%ss
	ljmp $0x08,$fake_label2
	fake_label2:
And this is the code I use in lguest to load the GDT:

Code: Select all

static void init_gdt()
{
   gdt_ptr.size = (sizeof(gdt_entry_t) * 5 -1); //we have 5 entries
   gdt_ptr.address  = (u32)&gdt_entries;
   const struct desc_ptr * gdt_address = &gdt_ptr;
   lguest_load_gdt(gdt_address);
   setup_gdt();
}


static void lguest_load_gdt(const struct desc_ptr *desc)
{
unsigned int i;
struct desc_struct *gdt = (void *)desc->address;
for (i = 0; i < (unsigned int) (desc->size+1)/8; i++)
hcall(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b, 0);
}
I've been trying to debug this error since a week ago and I just don't seem to find the reason... the asm part can be called from inline asembly inside the init_gdt function but the result is the same.

Any hints?

As always, thanks for reading this far. Suggestions are welcome.

Re: Lguest32: Setting SS gives a general protection exceptio

Posted: Thu Aug 12, 2010 5:14 pm
by skyking
Have you confirmed that it is the loading of the SS register that causes the crash or the use of the stack segment that causes it. If the later have you checked if using the data segment works? Have you checked that the correct data is in the GDT - the code provided does not tell the whole story about the actual data in the GDT? Also note that the order you're doing the load of the segments is different from what is normal (normal thing is to load the CS ie making the ljmp first), have you checked that it is OK to do it in this way.

Re: Lguest32: Setting SS gives a general protection exceptio

Posted: Thu Aug 12, 2010 5:32 pm
by gerryg400
If the ljmp works then I guess your GDT_ENTRY_INIT macro is formatting the descriptors correctly. The difference between loading SS and DS is that the DPL and RPL must both be equal to the CPL. Looks like both DPL and RPL are 0.

What is your CPL ?

Re: Lguest32: Setting SS gives a general protection exceptio

Posted: Thu Aug 12, 2010 6:18 pm
by dc740
The data in the GDT is correct, because I'm using linux headers for GDT macros and structs. I used known and working code.

gerryg400 is completely right. CPL = 1, so I changed RPL and DPL to see if it works. and yeah... that was the problem. Why didn't I do it before? Simple because I didn't know about this. And also because I don't know why I'm running with CPL = 1... Maybe lguest loaded it that way.

Thanks, really. That was very helpful, and I learnt a lot in the process (which is the best part of it)