lguest: switch segment-voodoo-numbers to readable symbols
Jacek Galowicz [Thu, 12 Jan 2012 05:14:47 +0000 (15:14 +1030)]
When studying lguest's x86 segment descriptor code, it is not longer
necessary to have the Intel x86 architecture manual open on the page
with the segment descriptor illustration to understand the crazy
numbers assigned to both descriptor structure halves a/b.
Now the struct desc_struct's fields, like suggested by
Glauber de Oliveira Costa in 2008, are used.

Signed-off-by: Jacek Galowicz <jacek@galowicz.de>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

drivers/lguest/segments.c

index ede4658..c4fb424 100644 (file)
@@ -81,8 +81,8 @@ static void fixup_gdt_table(struct lg_cpu *cpu, unsigned start, unsigned end)
                 * sometimes careless and leaves this as 0, even though it's
                 * running at privilege level 1.  If so, we fix it here.
                 */
-               if ((cpu->arch.gdt[i].b & 0x00006000) == 0)
-                       cpu->arch.gdt[i].b |= (GUEST_PL << 13);
+               if (cpu->arch.gdt[i].dpl == 0)
+                       cpu->arch.gdt[i].dpl |= GUEST_PL;
 
                /*
                 * Each descriptor has an "accessed" bit.  If we don't set it
@@ -90,7 +90,7 @@ static void fixup_gdt_table(struct lg_cpu *cpu, unsigned start, unsigned end)
                 * that entry into a segment register.  But the GDT isn't
                 * writable by the Guest, so bad things can happen.
                 */
-               cpu->arch.gdt[i].b |= 0x00000100;
+               cpu->arch.gdt[i].type |= 0x1;
        }
 }
 
@@ -114,13 +114,19 @@ void setup_default_gdt_entries(struct lguest_ro_state *state)
 
        /*
         * The TSS segment refers to the TSS entry for this particular CPU.
-        * Forgive the magic flags: the 0x8900 means the entry is Present, it's
-        * privilege level 0 Available 386 TSS system segment, and the 0x67
-        * means Saturn is eclipsed by Mercury in the twelfth house.
         */
-       gdt[GDT_ENTRY_TSS].a = 0x00000067 | (tss << 16);
-       gdt[GDT_ENTRY_TSS].b = 0x00008900 | (tss & 0xFF000000)
-               | ((tss >> 16) & 0x000000FF);
+       gdt[GDT_ENTRY_TSS].a = 0;
+       gdt[GDT_ENTRY_TSS].b = 0;
+
+       gdt[GDT_ENTRY_TSS].limit0 = 0x67;
+       gdt[GDT_ENTRY_TSS].base0  = tss & 0xFFFF;
+       gdt[GDT_ENTRY_TSS].base1  = (tss >> 16) & 0xFF;
+       gdt[GDT_ENTRY_TSS].base2  = tss >> 24;
+       gdt[GDT_ENTRY_TSS].type   = 0x9; /* 32-bit TSS (available) */
+       gdt[GDT_ENTRY_TSS].p      = 0x1; /* Entry is present */
+       gdt[GDT_ENTRY_TSS].dpl    = 0x0; /* Privilege level 0 */
+       gdt[GDT_ENTRY_TSS].s      = 0x0; /* system segment */
+
 }
 
 /*
@@ -135,8 +141,8 @@ void setup_guest_gdt(struct lg_cpu *cpu)
         */
        cpu->arch.gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT;
        cpu->arch.gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT;
-       cpu->arch.gdt[GDT_ENTRY_KERNEL_CS].b |= (GUEST_PL << 13);
-       cpu->arch.gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13);
+       cpu->arch.gdt[GDT_ENTRY_KERNEL_CS].dpl |= GUEST_PL;
+       cpu->arch.gdt[GDT_ENTRY_KERNEL_DS].dpl |= GUEST_PL;
 }
 
 /*H:650