aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-05-07 05:17:13 -0400
committerIngo Molnar <mingo@elte.hu>2009-05-07 05:17:34 -0400
commit44347d947f628060b92449702071bfe1d31dfb75 (patch)
treec6ed74610d5b3295df4296659f80f5feb94b28cc /drivers/lguest
parentd94fc523f3c35bd8013f04827e94756cbc0212f4 (diff)
parent413f81eba35d6ede9289b0c8a920c013a84fac71 (diff)
Merge branch 'linus' into tracing/core
Merge reason: tracing/core was on a .30-rc1 base and was missing out on on a handful of tracing fixes present in .30-rc5-almost. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/lguest')
-rw-r--r--drivers/lguest/lg.h3
-rw-r--r--drivers/lguest/segments.c13
-rw-r--r--drivers/lguest/x86/core.c9
3 files changed, 16 insertions, 9 deletions
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index ac8a4a3741b8..af92a176697f 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -158,7 +158,8 @@ void free_interrupts(void);
158/* segments.c: */ 158/* segments.c: */
159void setup_default_gdt_entries(struct lguest_ro_state *state); 159void setup_default_gdt_entries(struct lguest_ro_state *state);
160void setup_guest_gdt(struct lg_cpu *cpu); 160void setup_guest_gdt(struct lg_cpu *cpu);
161void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, u32 num); 161void load_guest_gdt_entry(struct lg_cpu *cpu, unsigned int i,
162 u32 low, u32 hi);
162void guest_load_tls(struct lg_cpu *cpu, unsigned long tls_array); 163void guest_load_tls(struct lg_cpu *cpu, unsigned long tls_array);
163void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt); 164void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt);
164void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt); 165void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt);
diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
index 4f15439b7f12..7ede64ffeef9 100644
--- a/drivers/lguest/segments.c
+++ b/drivers/lguest/segments.c
@@ -144,18 +144,19 @@ void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt)
144 gdt[i] = cpu->arch.gdt[i]; 144 gdt[i] = cpu->arch.gdt[i];
145} 145}
146 146
147/*H:620 This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT). 147/*H:620 This is where the Guest asks us to load a new GDT entry
148 * We copy it from the Guest and tweak the entries. */ 148 * (LHCALL_LOAD_GDT_ENTRY). We tweak the entry and copy it in. */
149void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, u32 num) 149void load_guest_gdt_entry(struct lg_cpu *cpu, u32 num, u32 lo, u32 hi)
150{ 150{
151 /* We assume the Guest has the same number of GDT entries as the 151 /* We assume the Guest has the same number of GDT entries as the
152 * Host, otherwise we'd have to dynamically allocate the Guest GDT. */ 152 * Host, otherwise we'd have to dynamically allocate the Guest GDT. */
153 if (num > ARRAY_SIZE(cpu->arch.gdt)) 153 if (num > ARRAY_SIZE(cpu->arch.gdt))
154 kill_guest(cpu, "too many gdt entries %i", num); 154 kill_guest(cpu, "too many gdt entries %i", num);
155 155
156 /* We read the whole thing in, then fix it up. */ 156 /* Set it up, then fix it. */
157 __lgread(cpu, cpu->arch.gdt, table, num * sizeof(cpu->arch.gdt[0])); 157 cpu->arch.gdt[num].a = lo;
158 fixup_gdt_table(cpu, 0, ARRAY_SIZE(cpu->arch.gdt)); 158 cpu->arch.gdt[num].b = hi;
159 fixup_gdt_table(cpu, num, num+1);
159 /* Mark that the GDT changed so the core knows it has to copy it again, 160 /* Mark that the GDT changed so the core knows it has to copy it again,
160 * even if the Guest is run on the same CPU. */ 161 * even if the Guest is run on the same CPU. */
161 cpu->changed |= CHANGED_GDT; 162 cpu->changed |= CHANGED_GDT;
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index a6b717644be0..1a83910f674f 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -324,6 +324,11 @@ static void rewrite_hypercall(struct lg_cpu *cpu)
324 u8 insn[3] = {0xcd, 0x1f, 0x90}; 324 u8 insn[3] = {0xcd, 0x1f, 0x90};
325 325
326 __lgwrite(cpu, guest_pa(cpu, cpu->regs->eip), insn, sizeof(insn)); 326 __lgwrite(cpu, guest_pa(cpu, cpu->regs->eip), insn, sizeof(insn));
327 /* The above write might have caused a copy of that page to be made
328 * (if it was read-only). We need to make sure the Guest has
329 * up-to-date pagetables. As this doesn't happen often, we can just
330 * drop them all. */
331 guest_pagetable_clear_all(cpu);
327} 332}
328 333
329static bool is_hypercall(struct lg_cpu *cpu) 334static bool is_hypercall(struct lg_cpu *cpu)
@@ -563,8 +568,8 @@ void __exit lguest_arch_host_fini(void)
563int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args) 568int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
564{ 569{
565 switch (args->arg0) { 570 switch (args->arg0) {
566 case LHCALL_LOAD_GDT: 571 case LHCALL_LOAD_GDT_ENTRY:
567 load_guest_gdt(cpu, args->arg1, args->arg2); 572 load_guest_gdt_entry(cpu, args->arg1, args->arg2, args->arg3);
568 break; 573 break;
569 case LHCALL_LOAD_IDT_ENTRY: 574 case LHCALL_LOAD_IDT_ENTRY:
570 load_guest_idt_entry(cpu, args->arg1, args->arg2, args->arg3); 575 load_guest_idt_entry(cpu, args->arg1, args->arg2, args->arg3);