aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlauber de Oliveira Costa <gcosta@redhat.com>2008-01-07 08:05:35 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-01-30 06:50:13 -0500
commit4665ac8e28c30c2a015c617c55783c0bf3a49c05 (patch)
tree15992d7e693126be7f758e694c8a544306576dfd
parent66686c2ab08feb721ca4d98285fba64acdf6017f (diff)
lguest: makes special fields be per-vcpu
lguest struct have room for some fields, namely, cr2, ts, esp1 and ss1, that are not really guest-wide, but rather, vcpu-wide. This patch puts it in the vcpu struct Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--drivers/lguest/hypercalls.c10
-rw-r--r--drivers/lguest/interrupts_and_traps.c23
-rw-r--r--drivers/lguest/lg.h17
-rw-r--r--drivers/lguest/page_tables.c11
-rw-r--r--drivers/lguest/x86/core.c10
5 files changed, 36 insertions, 35 deletions
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 83323b1cc0b2..ab70bbebdf25 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -60,7 +60,7 @@ static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
60 /* FLUSH_TLB comes in two flavors, depending on the 60 /* FLUSH_TLB comes in two flavors, depending on the
61 * argument: */ 61 * argument: */
62 if (args->arg1) 62 if (args->arg1)
63 guest_pagetable_clear_all(lg); 63 guest_pagetable_clear_all(cpu);
64 else 64 else
65 guest_pagetable_flush_user(lg); 65 guest_pagetable_flush_user(lg);
66 break; 66 break;
@@ -68,10 +68,10 @@ static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
68 /* All these calls simply pass the arguments through to the right 68 /* All these calls simply pass the arguments through to the right
69 * routines. */ 69 * routines. */
70 case LHCALL_NEW_PGTABLE: 70 case LHCALL_NEW_PGTABLE:
71 guest_new_pagetable(lg, args->arg1); 71 guest_new_pagetable(cpu, args->arg1);
72 break; 72 break;
73 case LHCALL_SET_STACK: 73 case LHCALL_SET_STACK:
74 guest_set_stack(lg, args->arg1, args->arg2, args->arg3); 74 guest_set_stack(cpu, args->arg1, args->arg2, args->arg3);
75 break; 75 break;
76 case LHCALL_SET_PTE: 76 case LHCALL_SET_PTE:
77 guest_set_pte(lg, args->arg1, args->arg2, __pte(args->arg3)); 77 guest_set_pte(lg, args->arg1, args->arg2, __pte(args->arg3));
@@ -84,7 +84,7 @@ static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
84 break; 84 break;
85 case LHCALL_TS: 85 case LHCALL_TS:
86 /* This sets the TS flag, as we saw used in run_guest(). */ 86 /* This sets the TS flag, as we saw used in run_guest(). */
87 lg->ts = args->arg1; 87 cpu->ts = args->arg1;
88 break; 88 break;
89 case LHCALL_HALT: 89 case LHCALL_HALT:
90 /* Similarly, this sets the halted flag for run_guest(). */ 90 /* Similarly, this sets the halted flag for run_guest(). */
@@ -191,7 +191,7 @@ static void initialize(struct lg_cpu *cpu)
191 * first write to a Guest page. This may have caused a copy-on-write 191 * first write to a Guest page. This may have caused a copy-on-write
192 * fault, but the old page might be (read-only) in the Guest 192 * fault, but the old page might be (read-only) in the Guest
193 * pagetable. */ 193 * pagetable. */
194 guest_pagetable_clear_all(lg); 194 guest_pagetable_clear_all(cpu);
195} 195}
196 196
197/*H:100 197/*H:100
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index 9c1c479e8c62..b87d9d6c36a4 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -73,8 +73,8 @@ static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, int has_err)
73 if ((cpu->regs->ss&0x3) != GUEST_PL) { 73 if ((cpu->regs->ss&0x3) != GUEST_PL) {
74 /* The Guest told us their kernel stack with the SET_STACK 74 /* The Guest told us their kernel stack with the SET_STACK
75 * hypercall: both the virtual address and the segment */ 75 * hypercall: both the virtual address and the segment */
76 virtstack = lg->esp1; 76 virtstack = cpu->esp1;
77 ss = lg->ss1; 77 ss = cpu->ss1;
78 78
79 origstack = gstack = guest_pa(lg, virtstack); 79 origstack = gstack = guest_pa(lg, virtstack);
80 /* We push the old stack segment and pointer onto the new 80 /* We push the old stack segment and pointer onto the new
@@ -311,10 +311,11 @@ static int direct_trap(unsigned int num)
311 * the Guest. 311 * the Guest.
312 * 312 *
313 * Which is deeply unfair, because (literally!) it wasn't the Guests' fault. */ 313 * Which is deeply unfair, because (literally!) it wasn't the Guests' fault. */
314void pin_stack_pages(struct lguest *lg) 314void pin_stack_pages(struct lg_cpu *cpu)
315{ 315{
316 unsigned int i; 316 unsigned int i;
317 317
318 struct lguest *lg = cpu->lg;
318 /* Depending on the CONFIG_4KSTACKS option, the Guest can have one or 319 /* Depending on the CONFIG_4KSTACKS option, the Guest can have one or
319 * two pages of stack space. */ 320 * two pages of stack space. */
320 for (i = 0; i < lg->stack_pages; i++) 321 for (i = 0; i < lg->stack_pages; i++)
@@ -322,7 +323,7 @@ void pin_stack_pages(struct lguest *lg)
322 * start of the page after the kernel stack. Subtract one to 323 * start of the page after the kernel stack. Subtract one to
323 * get back onto the first stack page, and keep subtracting to 324 * get back onto the first stack page, and keep subtracting to
324 * get to the rest of the stack pages. */ 325 * get to the rest of the stack pages. */
325 pin_page(lg, lg->esp1 - 1 - i * PAGE_SIZE); 326 pin_page(lg, cpu->esp1 - 1 - i * PAGE_SIZE);
326} 327}
327 328
328/* Direct traps also mean that we need to know whenever the Guest wants to use 329/* Direct traps also mean that we need to know whenever the Guest wants to use
@@ -333,21 +334,21 @@ void pin_stack_pages(struct lguest *lg)
333 * 334 *
334 * In Linux each process has its own kernel stack, so this happens a lot: we 335 * In Linux each process has its own kernel stack, so this happens a lot: we
335 * change stacks on each context switch. */ 336 * change stacks on each context switch. */
336void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages) 337void guest_set_stack(struct lg_cpu *cpu, u32 seg, u32 esp, unsigned int pages)
337{ 338{
338 /* You are not allowed have a stack segment with privilege level 0: bad 339 /* You are not allowed have a stack segment with privilege level 0: bad
339 * Guest! */ 340 * Guest! */
340 if ((seg & 0x3) != GUEST_PL) 341 if ((seg & 0x3) != GUEST_PL)
341 kill_guest(lg, "bad stack segment %i", seg); 342 kill_guest(cpu->lg, "bad stack segment %i", seg);
342 /* We only expect one or two stack pages. */ 343 /* We only expect one or two stack pages. */
343 if (pages > 2) 344 if (pages > 2)
344 kill_guest(lg, "bad stack pages %u", pages); 345 kill_guest(cpu->lg, "bad stack pages %u", pages);
345 /* Save where the stack is, and how many pages */ 346 /* Save where the stack is, and how many pages */
346 lg->ss1 = seg; 347 cpu->ss1 = seg;
347 lg->esp1 = esp; 348 cpu->esp1 = esp;
348 lg->stack_pages = pages; 349 cpu->lg->stack_pages = pages;
349 /* Make sure the new stack pages are mapped */ 350 /* Make sure the new stack pages are mapped */
350 pin_stack_pages(lg); 351 pin_stack_pages(cpu);
351} 352}
352 353
353/* All this reference to mapping stacks leads us neatly into the other complex 354/* All this reference to mapping stacks leads us neatly into the other complex
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index e7123fa6127f..05637648a174 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -46,6 +46,11 @@ struct lg_cpu {
46 struct task_struct *tsk; 46 struct task_struct *tsk;
47 struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */ 47 struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */
48 48
49 u32 cr2;
50 int ts;
51 u32 esp1;
52 u8 ss1;
53
49 /* At end of a page shared mapped over lguest_pages in guest. */ 54 /* At end of a page shared mapped over lguest_pages in guest. */
50 unsigned long regs_page; 55 unsigned long regs_page;
51 struct lguest_regs *regs; 56 struct lguest_regs *regs;
@@ -80,10 +85,6 @@ struct lguest
80 * memory in the Launcher. */ 85 * memory in the Launcher. */
81 void __user *mem_base; 86 void __user *mem_base;
82 unsigned long kernel_address; 87 unsigned long kernel_address;
83 u32 cr2;
84 int ts;
85 u32 esp1;
86 u8 ss1;
87 88
88 /* Bitmap of what has changed: see CHANGED_* above. */ 89 /* Bitmap of what has changed: see CHANGED_* above. */
89 int changed; 90 int changed;
@@ -141,8 +142,8 @@ void maybe_do_interrupt(struct lg_cpu *cpu);
141int deliver_trap(struct lg_cpu *cpu, unsigned int num); 142int deliver_trap(struct lg_cpu *cpu, unsigned int num);
142void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int i, 143void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int i,
143 u32 low, u32 hi); 144 u32 low, u32 hi);
144void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages); 145void guest_set_stack(struct lg_cpu *cpu, u32 seg, u32 esp, unsigned int pages);
145void pin_stack_pages(struct lguest *lg); 146void pin_stack_pages(struct lg_cpu *cpu);
146void setup_default_idt_entries(struct lguest_ro_state *state, 147void setup_default_idt_entries(struct lguest_ro_state *state,
147 const unsigned long *def); 148 const unsigned long *def);
148void copy_traps(const struct lg_cpu *cpu, struct desc_struct *idt, 149void copy_traps(const struct lg_cpu *cpu, struct desc_struct *idt,
@@ -164,9 +165,9 @@ void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt);
164/* page_tables.c: */ 165/* page_tables.c: */
165int init_guest_pagetable(struct lguest *lg, unsigned long pgtable); 166int init_guest_pagetable(struct lguest *lg, unsigned long pgtable);
166void free_guest_pagetable(struct lguest *lg); 167void free_guest_pagetable(struct lguest *lg);
167void guest_new_pagetable(struct lguest *lg, unsigned long pgtable); 168void guest_new_pagetable(struct lg_cpu *cpu, unsigned long pgtable);
168void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 i); 169void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 i);
169void guest_pagetable_clear_all(struct lguest *lg); 170void guest_pagetable_clear_all(struct lg_cpu *cpu);
170void guest_pagetable_flush_user(struct lguest *lg); 171void guest_pagetable_flush_user(struct lguest *lg);
171void guest_set_pte(struct lguest *lg, unsigned long gpgdir, 172void guest_set_pte(struct lguest *lg, unsigned long gpgdir,
172 unsigned long vaddr, pte_t val); 173 unsigned long vaddr, pte_t val);
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index f19add469944..e34c81636a8c 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -432,9 +432,10 @@ static unsigned int new_pgdir(struct lguest *lg,
432 * Now we've seen all the page table setting and manipulation, let's see what 432 * Now we've seen all the page table setting and manipulation, let's see what
433 * what happens when the Guest changes page tables (ie. changes the top-level 433 * what happens when the Guest changes page tables (ie. changes the top-level
434 * pgdir). This occurs on almost every context switch. */ 434 * pgdir). This occurs on almost every context switch. */
435void guest_new_pagetable(struct lguest *lg, unsigned long pgtable) 435void guest_new_pagetable(struct lg_cpu *cpu, unsigned long pgtable)
436{ 436{
437 int newpgdir, repin = 0; 437 int newpgdir, repin = 0;
438 struct lguest *lg = cpu->lg;
438 439
439 /* Look to see if we have this one already. */ 440 /* Look to see if we have this one already. */
440 newpgdir = find_pgdir(lg, pgtable); 441 newpgdir = find_pgdir(lg, pgtable);
@@ -446,7 +447,7 @@ void guest_new_pagetable(struct lguest *lg, unsigned long pgtable)
446 lg->pgdidx = newpgdir; 447 lg->pgdidx = newpgdir;
447 /* If it was completely blank, we map in the Guest kernel stack */ 448 /* If it was completely blank, we map in the Guest kernel stack */
448 if (repin) 449 if (repin)
449 pin_stack_pages(lg); 450 pin_stack_pages(cpu);
450} 451}
451 452
452/*H:470 Finally, a routine which throws away everything: all PGD entries in all 453/*H:470 Finally, a routine which throws away everything: all PGD entries in all
@@ -468,11 +469,11 @@ static void release_all_pagetables(struct lguest *lg)
468 * mapping. Since kernel mappings are in every page table, it's easiest to 469 * mapping. Since kernel mappings are in every page table, it's easiest to
469 * throw them all away. This traps the Guest in amber for a while as 470 * throw them all away. This traps the Guest in amber for a while as
470 * everything faults back in, but it's rare. */ 471 * everything faults back in, but it's rare. */
471void guest_pagetable_clear_all(struct lguest *lg) 472void guest_pagetable_clear_all(struct lg_cpu *cpu)
472{ 473{
473 release_all_pagetables(lg); 474 release_all_pagetables(cpu->lg);
474 /* We need the Guest kernel stack mapped again. */ 475 /* We need the Guest kernel stack mapped again. */
475 pin_stack_pages(lg); 476 pin_stack_pages(cpu);
476} 477}
477/*:*/ 478/*:*/
478/*M:009 Since we throw away all mappings when a kernel mapping changes, our 479/*M:009 Since we throw away all mappings when a kernel mapping changes, our
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index e989b8358864..65f2e3809475 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -95,8 +95,8 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages)
95 /* Set up the two "TSS" members which tell the CPU what stack to use 95 /* Set up the two "TSS" members which tell the CPU what stack to use
96 * for traps which do directly into the Guest (ie. traps at privilege 96 * for traps which do directly into the Guest (ie. traps at privilege
97 * level 1). */ 97 * level 1). */
98 pages->state.guest_tss.esp1 = lg->esp1; 98 pages->state.guest_tss.esp1 = cpu->esp1;
99 pages->state.guest_tss.ss1 = lg->ss1; 99 pages->state.guest_tss.ss1 = cpu->ss1;
100 100
101 /* Copy direct-to-Guest trap entries. */ 101 /* Copy direct-to-Guest trap entries. */
102 if (lg->changed & CHANGED_IDT) 102 if (lg->changed & CHANGED_IDT)
@@ -165,12 +165,10 @@ static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages)
165 * are disabled: we own the CPU. */ 165 * are disabled: we own the CPU. */
166void lguest_arch_run_guest(struct lg_cpu *cpu) 166void lguest_arch_run_guest(struct lg_cpu *cpu)
167{ 167{
168 struct lguest *lg = cpu->lg;
169
170 /* Remember the awfully-named TS bit? If the Guest has asked to set it 168 /* Remember the awfully-named TS bit? If the Guest has asked to set it
171 * we set it now, so we can trap and pass that trap to the Guest if it 169 * we set it now, so we can trap and pass that trap to the Guest if it
172 * uses the FPU. */ 170 * uses the FPU. */
173 if (lg->ts) 171 if (cpu->ts)
174 lguest_set_ts(); 172 lguest_set_ts();
175 173
176 /* SYSENTER is an optimized way of doing system calls. We can't allow 174 /* SYSENTER is an optimized way of doing system calls. We can't allow
@@ -325,7 +323,7 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
325 /* If the Guest doesn't want to know, we already restored the 323 /* If the Guest doesn't want to know, we already restored the
326 * Floating Point Unit, so we just continue without telling 324 * Floating Point Unit, so we just continue without telling
327 * it. */ 325 * it. */
328 if (!lg->ts) 326 if (!cpu->ts)
329 return; 327 return;
330 break; 328 break;
331 case 32 ... 255: 329 case 32 ... 255: