aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest/segments.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/lguest/segments.c')
-rw-r--r--drivers/lguest/segments.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
index ede46581351a..c4fb424dfddb 100644
--- a/drivers/lguest/segments.c
+++ b/drivers/lguest/segments.c
@@ -81,8 +81,8 @@ static void fixup_gdt_table(struct lg_cpu *cpu, unsigned start, unsigned end)
81 * sometimes careless and leaves this as 0, even though it's 81 * sometimes careless and leaves this as 0, even though it's
82 * running at privilege level 1. If so, we fix it here. 82 * running at privilege level 1. If so, we fix it here.
83 */ 83 */
84 if ((cpu->arch.gdt[i].b & 0x00006000) == 0) 84 if (cpu->arch.gdt[i].dpl == 0)
85 cpu->arch.gdt[i].b |= (GUEST_PL << 13); 85 cpu->arch.gdt[i].dpl |= GUEST_PL;
86 86
87 /* 87 /*
88 * Each descriptor has an "accessed" bit. If we don't set it 88 * 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)
90 * that entry into a segment register. But the GDT isn't 90 * that entry into a segment register. But the GDT isn't
91 * writable by the Guest, so bad things can happen. 91 * writable by the Guest, so bad things can happen.
92 */ 92 */
93 cpu->arch.gdt[i].b |= 0x00000100; 93 cpu->arch.gdt[i].type |= 0x1;
94 } 94 }
95} 95}
96 96
@@ -114,13 +114,19 @@ void setup_default_gdt_entries(struct lguest_ro_state *state)
114 114
115 /* 115 /*
116 * The TSS segment refers to the TSS entry for this particular CPU. 116 * The TSS segment refers to the TSS entry for this particular CPU.
117 * Forgive the magic flags: the 0x8900 means the entry is Present, it's
118 * privilege level 0 Available 386 TSS system segment, and the 0x67
119 * means Saturn is eclipsed by Mercury in the twelfth house.
120 */ 117 */
121 gdt[GDT_ENTRY_TSS].a = 0x00000067 | (tss << 16); 118 gdt[GDT_ENTRY_TSS].a = 0;
122 gdt[GDT_ENTRY_TSS].b = 0x00008900 | (tss & 0xFF000000) 119 gdt[GDT_ENTRY_TSS].b = 0;
123 | ((tss >> 16) & 0x000000FF); 120
121 gdt[GDT_ENTRY_TSS].limit0 = 0x67;
122 gdt[GDT_ENTRY_TSS].base0 = tss & 0xFFFF;
123 gdt[GDT_ENTRY_TSS].base1 = (tss >> 16) & 0xFF;
124 gdt[GDT_ENTRY_TSS].base2 = tss >> 24;
125 gdt[GDT_ENTRY_TSS].type = 0x9; /* 32-bit TSS (available) */
126 gdt[GDT_ENTRY_TSS].p = 0x1; /* Entry is present */
127 gdt[GDT_ENTRY_TSS].dpl = 0x0; /* Privilege level 0 */
128 gdt[GDT_ENTRY_TSS].s = 0x0; /* system segment */
129
124} 130}
125 131
126/* 132/*
@@ -135,8 +141,8 @@ void setup_guest_gdt(struct lg_cpu *cpu)
135 */ 141 */
136 cpu->arch.gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT; 142 cpu->arch.gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT;
137 cpu->arch.gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT; 143 cpu->arch.gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT;
138 cpu->arch.gdt[GDT_ENTRY_KERNEL_CS].b |= (GUEST_PL << 13); 144 cpu->arch.gdt[GDT_ENTRY_KERNEL_CS].dpl |= GUEST_PL;
139 cpu->arch.gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13); 145 cpu->arch.gdt[GDT_ENTRY_KERNEL_DS].dpl |= GUEST_PL;
140} 146}
141 147
142/*H:650 148/*H:650