diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-30 17:35:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-30 17:35:32 -0500 |
commit | d145c7253c8cb2ed8a75a8839621b0bb8f778820 (patch) | |
tree | fac21920d149a2cddfdfbde65066ff98935a9c57 /drivers/lguest/x86 | |
parent | 44c3b59102e3ecc7a01e9811862633e670595e51 (diff) | |
parent | 84f12e39c856a8b1ab407f8216ecebaf4204b94d (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus: (27 commits)
lguest: use __PAGE_KERNEL instead of _PAGE_KERNEL
lguest: Use explicit includes rateher than indirect
lguest: get rid of lg variable assignments
lguest: change gpte_addr header
lguest: move changed bitmap to lg_cpu
lguest: move last_pages to lg_cpu
lguest: change last_guest to last_cpu
lguest: change spte_addr header
lguest: per-vcpu lguest pgdir management
lguest: make pending notifications per-vcpu
lguest: makes special fields be per-vcpu
lguest: per-vcpu lguest task management
lguest: replace lguest_arch with lg_cpu_arch.
lguest: make registers per-vcpu
lguest: make emulate_insn receive a vcpu struct.
lguest: map_switcher_in_guest() per-vcpu
lguest: per-vcpu interrupt processing.
lguest: per-vcpu lguest timers
lguest: make hypercalls use the vcpu struct
lguest: make write() operation smp aware
...
Manual conflict resolved (maybe even correctly, who knows) in
drivers/lguest/x86/core.c
Diffstat (limited to 'drivers/lguest/x86')
-rw-r--r-- | drivers/lguest/x86/core.c | 127 |
1 files changed, 65 insertions, 62 deletions
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index 44adb00e1490..61f2f8eb8cad 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c | |||
@@ -60,7 +60,7 @@ static struct lguest_pages *lguest_pages(unsigned int cpu) | |||
60 | (SWITCHER_ADDR + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]); | 60 | (SWITCHER_ADDR + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]); |
61 | } | 61 | } |
62 | 62 | ||
63 | static DEFINE_PER_CPU(struct lguest *, last_guest); | 63 | static DEFINE_PER_CPU(struct lg_cpu *, last_cpu); |
64 | 64 | ||
65 | /*S:010 | 65 | /*S:010 |
66 | * We approach the Switcher. | 66 | * We approach the Switcher. |
@@ -73,16 +73,16 @@ static DEFINE_PER_CPU(struct lguest *, last_guest); | |||
73 | * since it last ran. We saw this set in interrupts_and_traps.c and | 73 | * since it last ran. We saw this set in interrupts_and_traps.c and |
74 | * segments.c. | 74 | * segments.c. |
75 | */ | 75 | */ |
76 | static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages) | 76 | static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages) |
77 | { | 77 | { |
78 | /* Copying all this data can be quite expensive. We usually run the | 78 | /* Copying all this data can be quite expensive. We usually run the |
79 | * same Guest we ran last time (and that Guest hasn't run anywhere else | 79 | * same Guest we ran last time (and that Guest hasn't run anywhere else |
80 | * meanwhile). If that's not the case, we pretend everything in the | 80 | * meanwhile). If that's not the case, we pretend everything in the |
81 | * Guest has changed. */ | 81 | * Guest has changed. */ |
82 | if (__get_cpu_var(last_guest) != lg || lg->last_pages != pages) { | 82 | if (__get_cpu_var(last_cpu) != cpu || cpu->last_pages != pages) { |
83 | __get_cpu_var(last_guest) = lg; | 83 | __get_cpu_var(last_cpu) = cpu; |
84 | lg->last_pages = pages; | 84 | cpu->last_pages = pages; |
85 | lg->changed = CHANGED_ALL; | 85 | cpu->changed = CHANGED_ALL; |
86 | } | 86 | } |
87 | 87 | ||
88 | /* These copies are pretty cheap, so we do them unconditionally: */ | 88 | /* These copies are pretty cheap, so we do them unconditionally: */ |
@@ -90,42 +90,42 @@ static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages) | |||
90 | pages->state.host_cr3 = __pa(current->mm->pgd); | 90 | pages->state.host_cr3 = __pa(current->mm->pgd); |
91 | /* Set up the Guest's page tables to see this CPU's pages (and no | 91 | /* Set up the Guest's page tables to see this CPU's pages (and no |
92 | * other CPU's pages). */ | 92 | * other CPU's pages). */ |
93 | map_switcher_in_guest(lg, pages); | 93 | map_switcher_in_guest(cpu, pages); |
94 | /* Set up the two "TSS" members which tell the CPU what stack to use | 94 | /* Set up the two "TSS" members which tell the CPU what stack to use |
95 | * for traps which do directly into the Guest (ie. traps at privilege | 95 | * for traps which do directly into the Guest (ie. traps at privilege |
96 | * level 1). */ | 96 | * level 1). */ |
97 | pages->state.guest_tss.sp1 = lg->esp1; | 97 | pages->state.guest_tss.esp1 = cpu->esp1; |
98 | pages->state.guest_tss.ss1 = lg->ss1; | 98 | pages->state.guest_tss.ss1 = cpu->ss1; |
99 | 99 | ||
100 | /* Copy direct-to-Guest trap entries. */ | 100 | /* Copy direct-to-Guest trap entries. */ |
101 | if (lg->changed & CHANGED_IDT) | 101 | if (cpu->changed & CHANGED_IDT) |
102 | copy_traps(lg, pages->state.guest_idt, default_idt_entries); | 102 | copy_traps(cpu, pages->state.guest_idt, default_idt_entries); |
103 | 103 | ||
104 | /* Copy all GDT entries which the Guest can change. */ | 104 | /* Copy all GDT entries which the Guest can change. */ |
105 | if (lg->changed & CHANGED_GDT) | 105 | if (cpu->changed & CHANGED_GDT) |
106 | copy_gdt(lg, pages->state.guest_gdt); | 106 | copy_gdt(cpu, pages->state.guest_gdt); |
107 | /* If only the TLS entries have changed, copy them. */ | 107 | /* If only the TLS entries have changed, copy them. */ |
108 | else if (lg->changed & CHANGED_GDT_TLS) | 108 | else if (cpu->changed & CHANGED_GDT_TLS) |
109 | copy_gdt_tls(lg, pages->state.guest_gdt); | 109 | copy_gdt_tls(cpu, pages->state.guest_gdt); |
110 | 110 | ||
111 | /* Mark the Guest as unchanged for next time. */ | 111 | /* Mark the Guest as unchanged for next time. */ |
112 | lg->changed = 0; | 112 | cpu->changed = 0; |
113 | } | 113 | } |
114 | 114 | ||
115 | /* Finally: the code to actually call into the Switcher to run the Guest. */ | 115 | /* Finally: the code to actually call into the Switcher to run the Guest. */ |
116 | static void run_guest_once(struct lguest *lg, struct lguest_pages *pages) | 116 | static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages) |
117 | { | 117 | { |
118 | /* This is a dummy value we need for GCC's sake. */ | 118 | /* This is a dummy value we need for GCC's sake. */ |
119 | unsigned int clobber; | 119 | unsigned int clobber; |
120 | 120 | ||
121 | /* Copy the guest-specific information into this CPU's "struct | 121 | /* Copy the guest-specific information into this CPU's "struct |
122 | * lguest_pages". */ | 122 | * lguest_pages". */ |
123 | copy_in_guest_info(lg, pages); | 123 | copy_in_guest_info(cpu, pages); |
124 | 124 | ||
125 | /* Set the trap number to 256 (impossible value). If we fault while | 125 | /* Set the trap number to 256 (impossible value). If we fault while |
126 | * switching to the Guest (bad segment registers or bug), this will | 126 | * switching to the Guest (bad segment registers or bug), this will |
127 | * cause us to abort the Guest. */ | 127 | * cause us to abort the Guest. */ |
128 | lg->regs->trapnum = 256; | 128 | cpu->regs->trapnum = 256; |
129 | 129 | ||
130 | /* Now: we push the "eflags" register on the stack, then do an "lcall". | 130 | /* Now: we push the "eflags" register on the stack, then do an "lcall". |
131 | * This is how we change from using the kernel code segment to using | 131 | * This is how we change from using the kernel code segment to using |
@@ -143,7 +143,7 @@ static void run_guest_once(struct lguest *lg, struct lguest_pages *pages) | |||
143 | * 0-th argument above, ie "a"). %ebx contains the | 143 | * 0-th argument above, ie "a"). %ebx contains the |
144 | * physical address of the Guest's top-level page | 144 | * physical address of the Guest's top-level page |
145 | * directory. */ | 145 | * directory. */ |
146 | : "0"(pages), "1"(__pa(lg->pgdirs[lg->pgdidx].pgdir)) | 146 | : "0"(pages), "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir)) |
147 | /* We tell gcc that all these registers could change, | 147 | /* We tell gcc that all these registers could change, |
148 | * which means we don't have to save and restore them in | 148 | * which means we don't have to save and restore them in |
149 | * the Switcher. */ | 149 | * the Switcher. */ |
@@ -161,12 +161,12 @@ static void run_guest_once(struct lguest *lg, struct lguest_pages *pages) | |||
161 | 161 | ||
162 | /*H:040 This is the i386-specific code to setup and run the Guest. Interrupts | 162 | /*H:040 This is the i386-specific code to setup and run the Guest. Interrupts |
163 | * are disabled: we own the CPU. */ | 163 | * are disabled: we own the CPU. */ |
164 | void lguest_arch_run_guest(struct lguest *lg) | 164 | void lguest_arch_run_guest(struct lg_cpu *cpu) |
165 | { | 165 | { |
166 | /* Remember the awfully-named TS bit? If the Guest has asked to set it | 166 | /* Remember the awfully-named TS bit? If the Guest has asked to set it |
167 | * we set it now, so we can trap and pass that trap to the Guest if it | 167 | * we set it now, so we can trap and pass that trap to the Guest if it |
168 | * uses the FPU. */ | 168 | * uses the FPU. */ |
169 | if (lg->ts) | 169 | if (cpu->ts) |
170 | lguest_set_ts(); | 170 | lguest_set_ts(); |
171 | 171 | ||
172 | /* SYSENTER is an optimized way of doing system calls. We can't allow | 172 | /* SYSENTER is an optimized way of doing system calls. We can't allow |
@@ -180,7 +180,7 @@ void lguest_arch_run_guest(struct lguest *lg) | |||
180 | /* Now we actually run the Guest. It will return when something | 180 | /* Now we actually run the Guest. It will return when something |
181 | * interesting happens, and we can examine its registers to see what it | 181 | * interesting happens, and we can examine its registers to see what it |
182 | * was doing. */ | 182 | * was doing. */ |
183 | run_guest_once(lg, lguest_pages(raw_smp_processor_id())); | 183 | run_guest_once(cpu, lguest_pages(raw_smp_processor_id())); |
184 | 184 | ||
185 | /* Note that the "regs" pointer contains two extra entries which are | 185 | /* Note that the "regs" pointer contains two extra entries which are |
186 | * not really registers: a trap number which says what interrupt or | 186 | * not really registers: a trap number which says what interrupt or |
@@ -191,11 +191,11 @@ void lguest_arch_run_guest(struct lguest *lg) | |||
191 | * bad virtual address. We have to grab this now, because once we | 191 | * bad virtual address. We have to grab this now, because once we |
192 | * re-enable interrupts an interrupt could fault and thus overwrite | 192 | * re-enable interrupts an interrupt could fault and thus overwrite |
193 | * cr2, or we could even move off to a different CPU. */ | 193 | * cr2, or we could even move off to a different CPU. */ |
194 | if (lg->regs->trapnum == 14) | 194 | if (cpu->regs->trapnum == 14) |
195 | lg->arch.last_pagefault = read_cr2(); | 195 | cpu->arch.last_pagefault = read_cr2(); |
196 | /* Similarly, if we took a trap because the Guest used the FPU, | 196 | /* Similarly, if we took a trap because the Guest used the FPU, |
197 | * we have to restore the FPU it expects to see. */ | 197 | * we have to restore the FPU it expects to see. */ |
198 | else if (lg->regs->trapnum == 7) | 198 | else if (cpu->regs->trapnum == 7) |
199 | math_state_restore(); | 199 | math_state_restore(); |
200 | 200 | ||
201 | /* Restore SYSENTER if it's supposed to be on. */ | 201 | /* Restore SYSENTER if it's supposed to be on. */ |
@@ -214,22 +214,22 @@ void lguest_arch_run_guest(struct lguest *lg) | |||
214 | * When the Guest uses one of these instructions, we get a trap (General | 214 | * When the Guest uses one of these instructions, we get a trap (General |
215 | * Protection Fault) and come here. We see if it's one of those troublesome | 215 | * Protection Fault) and come here. We see if it's one of those troublesome |
216 | * instructions and skip over it. We return true if we did. */ | 216 | * instructions and skip over it. We return true if we did. */ |
217 | static int emulate_insn(struct lguest *lg) | 217 | static int emulate_insn(struct lg_cpu *cpu) |
218 | { | 218 | { |
219 | u8 insn; | 219 | u8 insn; |
220 | unsigned int insnlen = 0, in = 0, shift = 0; | 220 | unsigned int insnlen = 0, in = 0, shift = 0; |
221 | /* The eip contains the *virtual* address of the Guest's instruction: | 221 | /* The eip contains the *virtual* address of the Guest's instruction: |
222 | * guest_pa just subtracts the Guest's page_offset. */ | 222 | * guest_pa just subtracts the Guest's page_offset. */ |
223 | unsigned long physaddr = guest_pa(lg, lg->regs->eip); | 223 | unsigned long physaddr = guest_pa(cpu, cpu->regs->eip); |
224 | 224 | ||
225 | /* This must be the Guest kernel trying to do something, not userspace! | 225 | /* This must be the Guest kernel trying to do something, not userspace! |
226 | * The bottom two bits of the CS segment register are the privilege | 226 | * The bottom two bits of the CS segment register are the privilege |
227 | * level. */ | 227 | * level. */ |
228 | if ((lg->regs->cs & 3) != GUEST_PL) | 228 | if ((cpu->regs->cs & 3) != GUEST_PL) |
229 | return 0; | 229 | return 0; |
230 | 230 | ||
231 | /* Decoding x86 instructions is icky. */ | 231 | /* Decoding x86 instructions is icky. */ |
232 | insn = lgread(lg, physaddr, u8); | 232 | insn = lgread(cpu, physaddr, u8); |
233 | 233 | ||
234 | /* 0x66 is an "operand prefix". It means it's using the upper 16 bits | 234 | /* 0x66 is an "operand prefix". It means it's using the upper 16 bits |
235 | of the eax register. */ | 235 | of the eax register. */ |
@@ -237,7 +237,7 @@ static int emulate_insn(struct lguest *lg) | |||
237 | shift = 16; | 237 | shift = 16; |
238 | /* The instruction is 1 byte so far, read the next byte. */ | 238 | /* The instruction is 1 byte so far, read the next byte. */ |
239 | insnlen = 1; | 239 | insnlen = 1; |
240 | insn = lgread(lg, physaddr + insnlen, u8); | 240 | insn = lgread(cpu, physaddr + insnlen, u8); |
241 | } | 241 | } |
242 | 242 | ||
243 | /* We can ignore the lower bit for the moment and decode the 4 opcodes | 243 | /* We can ignore the lower bit for the moment and decode the 4 opcodes |
@@ -268,26 +268,26 @@ static int emulate_insn(struct lguest *lg) | |||
268 | if (in) { | 268 | if (in) { |
269 | /* Lower bit tells is whether it's a 16 or 32 bit access */ | 269 | /* Lower bit tells is whether it's a 16 or 32 bit access */ |
270 | if (insn & 0x1) | 270 | if (insn & 0x1) |
271 | lg->regs->eax = 0xFFFFFFFF; | 271 | cpu->regs->eax = 0xFFFFFFFF; |
272 | else | 272 | else |
273 | lg->regs->eax |= (0xFFFF << shift); | 273 | cpu->regs->eax |= (0xFFFF << shift); |
274 | } | 274 | } |
275 | /* Finally, we've "done" the instruction, so move past it. */ | 275 | /* Finally, we've "done" the instruction, so move past it. */ |
276 | lg->regs->eip += insnlen; | 276 | cpu->regs->eip += insnlen; |
277 | /* Success! */ | 277 | /* Success! */ |
278 | return 1; | 278 | return 1; |
279 | } | 279 | } |
280 | 280 | ||
281 | /*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */ | 281 | /*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */ |
282 | void lguest_arch_handle_trap(struct lguest *lg) | 282 | void lguest_arch_handle_trap(struct lg_cpu *cpu) |
283 | { | 283 | { |
284 | switch (lg->regs->trapnum) { | 284 | switch (cpu->regs->trapnum) { |
285 | case 13: /* We've intercepted a General Protection Fault. */ | 285 | case 13: /* We've intercepted a General Protection Fault. */ |
286 | /* Check if this was one of those annoying IN or OUT | 286 | /* Check if this was one of those annoying IN or OUT |
287 | * instructions which we need to emulate. If so, we just go | 287 | * instructions which we need to emulate. If so, we just go |
288 | * back into the Guest after we've done it. */ | 288 | * back into the Guest after we've done it. */ |
289 | if (lg->regs->errcode == 0) { | 289 | if (cpu->regs->errcode == 0) { |
290 | if (emulate_insn(lg)) | 290 | if (emulate_insn(cpu)) |
291 | return; | 291 | return; |
292 | } | 292 | } |
293 | break; | 293 | break; |
@@ -301,7 +301,8 @@ void lguest_arch_handle_trap(struct lguest *lg) | |||
301 | * | 301 | * |
302 | * The errcode tells whether this was a read or a write, and | 302 | * The errcode tells whether this was a read or a write, and |
303 | * whether kernel or userspace code. */ | 303 | * whether kernel or userspace code. */ |
304 | if (demand_page(lg, lg->arch.last_pagefault, lg->regs->errcode)) | 304 | if (demand_page(cpu, cpu->arch.last_pagefault, |
305 | cpu->regs->errcode)) | ||
305 | return; | 306 | return; |
306 | 307 | ||
307 | /* OK, it's really not there (or not OK): the Guest needs to | 308 | /* OK, it's really not there (or not OK): the Guest needs to |
@@ -311,15 +312,16 @@ void lguest_arch_handle_trap(struct lguest *lg) | |||
311 | * Note that if the Guest were really messed up, this could | 312 | * Note that if the Guest were really messed up, this could |
312 | * happen before it's done the LHCALL_LGUEST_INIT hypercall, so | 313 | * happen before it's done the LHCALL_LGUEST_INIT hypercall, so |
313 | * lg->lguest_data could be NULL */ | 314 | * lg->lguest_data could be NULL */ |
314 | if (lg->lguest_data && | 315 | if (cpu->lg->lguest_data && |
315 | put_user(lg->arch.last_pagefault, &lg->lguest_data->cr2)) | 316 | put_user(cpu->arch.last_pagefault, |
316 | kill_guest(lg, "Writing cr2"); | 317 | &cpu->lg->lguest_data->cr2)) |
318 | kill_guest(cpu, "Writing cr2"); | ||
317 | break; | 319 | break; |
318 | case 7: /* We've intercepted a Device Not Available fault. */ | 320 | case 7: /* We've intercepted a Device Not Available fault. */ |
319 | /* If the Guest doesn't want to know, we already restored the | 321 | /* If the Guest doesn't want to know, we already restored the |
320 | * Floating Point Unit, so we just continue without telling | 322 | * Floating Point Unit, so we just continue without telling |
321 | * it. */ | 323 | * it. */ |
322 | if (!lg->ts) | 324 | if (!cpu->ts) |
323 | return; | 325 | return; |
324 | break; | 326 | break; |
325 | case 32 ... 255: | 327 | case 32 ... 255: |
@@ -332,19 +334,19 @@ void lguest_arch_handle_trap(struct lguest *lg) | |||
332 | case LGUEST_TRAP_ENTRY: | 334 | case LGUEST_TRAP_ENTRY: |
333 | /* Our 'struct hcall_args' maps directly over our regs: we set | 335 | /* Our 'struct hcall_args' maps directly over our regs: we set |
334 | * up the pointer now to indicate a hypercall is pending. */ | 336 | * up the pointer now to indicate a hypercall is pending. */ |
335 | lg->hcall = (struct hcall_args *)lg->regs; | 337 | cpu->hcall = (struct hcall_args *)cpu->regs; |
336 | return; | 338 | return; |
337 | } | 339 | } |
338 | 340 | ||
339 | /* We didn't handle the trap, so it needs to go to the Guest. */ | 341 | /* We didn't handle the trap, so it needs to go to the Guest. */ |
340 | if (!deliver_trap(lg, lg->regs->trapnum)) | 342 | if (!deliver_trap(cpu, cpu->regs->trapnum)) |
341 | /* If the Guest doesn't have a handler (either it hasn't | 343 | /* If the Guest doesn't have a handler (either it hasn't |
342 | * registered any yet, or it's one of the faults we don't let | 344 | * registered any yet, or it's one of the faults we don't let |
343 | * it handle), it dies with a cryptic error message. */ | 345 | * it handle), it dies with a cryptic error message. */ |
344 | kill_guest(lg, "unhandled trap %li at %#lx (%#lx)", | 346 | kill_guest(cpu, "unhandled trap %li at %#lx (%#lx)", |
345 | lg->regs->trapnum, lg->regs->eip, | 347 | cpu->regs->trapnum, cpu->regs->eip, |
346 | lg->regs->trapnum == 14 ? lg->arch.last_pagefault | 348 | cpu->regs->trapnum == 14 ? cpu->arch.last_pagefault |
347 | : lg->regs->errcode); | 349 | : cpu->regs->errcode); |
348 | } | 350 | } |
349 | 351 | ||
350 | /* Now we can look at each of the routines this calls, in increasing order of | 352 | /* Now we can look at each of the routines this calls, in increasing order of |
@@ -487,17 +489,17 @@ void __exit lguest_arch_host_fini(void) | |||
487 | 489 | ||
488 | 490 | ||
489 | /*H:122 The i386-specific hypercalls simply farm out to the right functions. */ | 491 | /*H:122 The i386-specific hypercalls simply farm out to the right functions. */ |
490 | int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args) | 492 | int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args) |
491 | { | 493 | { |
492 | switch (args->arg0) { | 494 | switch (args->arg0) { |
493 | case LHCALL_LOAD_GDT: | 495 | case LHCALL_LOAD_GDT: |
494 | load_guest_gdt(lg, args->arg1, args->arg2); | 496 | load_guest_gdt(cpu, args->arg1, args->arg2); |
495 | break; | 497 | break; |
496 | case LHCALL_LOAD_IDT_ENTRY: | 498 | case LHCALL_LOAD_IDT_ENTRY: |
497 | load_guest_idt_entry(lg, args->arg1, args->arg2, args->arg3); | 499 | load_guest_idt_entry(cpu, args->arg1, args->arg2, args->arg3); |
498 | break; | 500 | break; |
499 | case LHCALL_LOAD_TLS: | 501 | case LHCALL_LOAD_TLS: |
500 | guest_load_tls(lg, args->arg1); | 502 | guest_load_tls(cpu, args->arg1); |
501 | break; | 503 | break; |
502 | default: | 504 | default: |
503 | /* Bad Guest. Bad! */ | 505 | /* Bad Guest. Bad! */ |
@@ -507,13 +509,14 @@ int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args) | |||
507 | } | 509 | } |
508 | 510 | ||
509 | /*H:126 i386-specific hypercall initialization: */ | 511 | /*H:126 i386-specific hypercall initialization: */ |
510 | int lguest_arch_init_hypercalls(struct lguest *lg) | 512 | int lguest_arch_init_hypercalls(struct lg_cpu *cpu) |
511 | { | 513 | { |
512 | u32 tsc_speed; | 514 | u32 tsc_speed; |
513 | 515 | ||
514 | /* The pointer to the Guest's "struct lguest_data" is the only | 516 | /* The pointer to the Guest's "struct lguest_data" is the only |
515 | * argument. We check that address now. */ | 517 | * argument. We check that address now. */ |
516 | if (!lguest_address_ok(lg, lg->hcall->arg1, sizeof(*lg->lguest_data))) | 518 | if (!lguest_address_ok(cpu->lg, cpu->hcall->arg1, |
519 | sizeof(*cpu->lg->lguest_data))) | ||
517 | return -EFAULT; | 520 | return -EFAULT; |
518 | 521 | ||
519 | /* Having checked it, we simply set lg->lguest_data to point straight | 522 | /* Having checked it, we simply set lg->lguest_data to point straight |
@@ -521,7 +524,7 @@ int lguest_arch_init_hypercalls(struct lguest *lg) | |||
521 | * copy_to_user/from_user from now on, instead of lgread/write. I put | 524 | * copy_to_user/from_user from now on, instead of lgread/write. I put |
522 | * this in to show that I'm not immune to writing stupid | 525 | * this in to show that I'm not immune to writing stupid |
523 | * optimizations. */ | 526 | * optimizations. */ |
524 | lg->lguest_data = lg->mem_base + lg->hcall->arg1; | 527 | cpu->lg->lguest_data = cpu->lg->mem_base + cpu->hcall->arg1; |
525 | 528 | ||
526 | /* We insist that the Time Stamp Counter exist and doesn't change with | 529 | /* We insist that the Time Stamp Counter exist and doesn't change with |
527 | * cpu frequency. Some devious chip manufacturers decided that TSC | 530 | * cpu frequency. Some devious chip manufacturers decided that TSC |
@@ -534,12 +537,12 @@ int lguest_arch_init_hypercalls(struct lguest *lg) | |||
534 | tsc_speed = tsc_khz; | 537 | tsc_speed = tsc_khz; |
535 | else | 538 | else |
536 | tsc_speed = 0; | 539 | tsc_speed = 0; |
537 | if (put_user(tsc_speed, &lg->lguest_data->tsc_khz)) | 540 | if (put_user(tsc_speed, &cpu->lg->lguest_data->tsc_khz)) |
538 | return -EFAULT; | 541 | return -EFAULT; |
539 | 542 | ||
540 | /* The interrupt code might not like the system call vector. */ | 543 | /* The interrupt code might not like the system call vector. */ |
541 | if (!check_syscall_vector(lg)) | 544 | if (!check_syscall_vector(cpu->lg)) |
542 | kill_guest(lg, "bad syscall vector"); | 545 | kill_guest(cpu, "bad syscall vector"); |
543 | 546 | ||
544 | return 0; | 547 | return 0; |
545 | } | 548 | } |
@@ -548,9 +551,9 @@ int lguest_arch_init_hypercalls(struct lguest *lg) | |||
548 | * | 551 | * |
549 | * Most of the Guest's registers are left alone: we used get_zeroed_page() to | 552 | * Most of the Guest's registers are left alone: we used get_zeroed_page() to |
550 | * allocate the structure, so they will be 0. */ | 553 | * allocate the structure, so they will be 0. */ |
551 | void lguest_arch_setup_regs(struct lguest *lg, unsigned long start) | 554 | void lguest_arch_setup_regs(struct lg_cpu *cpu, unsigned long start) |
552 | { | 555 | { |
553 | struct lguest_regs *regs = lg->regs; | 556 | struct lguest_regs *regs = cpu->regs; |
554 | 557 | ||
555 | /* There are four "segment" registers which the Guest needs to boot: | 558 | /* There are four "segment" registers which the Guest needs to boot: |
556 | * The "code segment" register (cs) refers to the kernel code segment | 559 | * The "code segment" register (cs) refers to the kernel code segment |
@@ -577,5 +580,5 @@ void lguest_arch_setup_regs(struct lguest *lg, unsigned long start) | |||
577 | 580 | ||
578 | /* There are a couple of GDT entries the Guest expects when first | 581 | /* There are a couple of GDT entries the Guest expects when first |
579 | * booting. */ | 582 | * booting. */ |
580 | setup_guest_gdt(lg); | 583 | setup_guest_gdt(cpu); |
581 | } | 584 | } |