diff options
Diffstat (limited to 'drivers/lguest/x86')
-rw-r--r-- | drivers/lguest/x86/core.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index fd6a8512443c..e9c3ba8aa1ec 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c | |||
@@ -117,7 +117,6 @@ 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 | struct lguest *lg = cpu->lg; | ||
121 | 120 | ||
122 | /* Copy the guest-specific information into this CPU's "struct | 121 | /* Copy the guest-specific information into this CPU's "struct |
123 | * lguest_pages". */ | 122 | * lguest_pages". */ |
@@ -144,7 +143,7 @@ static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages) | |||
144 | * 0-th argument above, ie "a"). %ebx contains the | 143 | * 0-th argument above, ie "a"). %ebx contains the |
145 | * physical address of the Guest's top-level page | 144 | * physical address of the Guest's top-level page |
146 | * directory. */ | 145 | * directory. */ |
147 | : "0"(pages), "1"(__pa(lg->pgdirs[cpu->cpu_pgd].pgdir)) | 146 | : "0"(pages), "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir)) |
148 | /* We tell gcc that all these registers could change, | 147 | /* We tell gcc that all these registers could change, |
149 | * 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 |
150 | * the Switcher. */ | 149 | * the Switcher. */ |
@@ -217,7 +216,6 @@ void lguest_arch_run_guest(struct lg_cpu *cpu) | |||
217 | * instructions and skip over it. We return true if we did. */ | 216 | * instructions and skip over it. We return true if we did. */ |
218 | static int emulate_insn(struct lg_cpu *cpu) | 217 | static int emulate_insn(struct lg_cpu *cpu) |
219 | { | 218 | { |
220 | struct lguest *lg = cpu->lg; | ||
221 | u8 insn; | 219 | u8 insn; |
222 | unsigned int insnlen = 0, in = 0, shift = 0; | 220 | unsigned int insnlen = 0, in = 0, shift = 0; |
223 | /* The eip contains the *virtual* address of the Guest's instruction: | 221 | /* The eip contains the *virtual* address of the Guest's instruction: |
@@ -231,7 +229,7 @@ static int emulate_insn(struct lg_cpu *cpu) | |||
231 | return 0; | 229 | return 0; |
232 | 230 | ||
233 | /* Decoding x86 instructions is icky. */ | 231 | /* Decoding x86 instructions is icky. */ |
234 | insn = lgread(lg, physaddr, u8); | 232 | insn = lgread(cpu, physaddr, u8); |
235 | 233 | ||
236 | /* 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 |
237 | of the eax register. */ | 235 | of the eax register. */ |
@@ -239,7 +237,7 @@ static int emulate_insn(struct lg_cpu *cpu) | |||
239 | shift = 16; | 237 | shift = 16; |
240 | /* The instruction is 1 byte so far, read the next byte. */ | 238 | /* The instruction is 1 byte so far, read the next byte. */ |
241 | insnlen = 1; | 239 | insnlen = 1; |
242 | insn = lgread(lg, physaddr + insnlen, u8); | 240 | insn = lgread(cpu, physaddr + insnlen, u8); |
243 | } | 241 | } |
244 | 242 | ||
245 | /* 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 |
@@ -283,7 +281,6 @@ static int emulate_insn(struct lg_cpu *cpu) | |||
283 | /*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. */ |
284 | void lguest_arch_handle_trap(struct lg_cpu *cpu) | 282 | void lguest_arch_handle_trap(struct lg_cpu *cpu) |
285 | { | 283 | { |
286 | struct lguest *lg = cpu->lg; | ||
287 | switch (cpu->regs->trapnum) { | 284 | switch (cpu->regs->trapnum) { |
288 | case 13: /* We've intercepted a General Protection Fault. */ | 285 | case 13: /* We've intercepted a General Protection Fault. */ |
289 | /* Check if this was one of those annoying IN or OUT | 286 | /* Check if this was one of those annoying IN or OUT |
@@ -315,9 +312,10 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu) | |||
315 | * Note that if the Guest were really messed up, this could | 312 | * Note that if the Guest were really messed up, this could |
316 | * happen before it's done the LHCALL_LGUEST_INIT hypercall, so | 313 | * happen before it's done the LHCALL_LGUEST_INIT hypercall, so |
317 | * lg->lguest_data could be NULL */ | 314 | * lg->lguest_data could be NULL */ |
318 | if (lg->lguest_data && | 315 | if (cpu->lg->lguest_data && |
319 | put_user(cpu->arch.last_pagefault, &lg->lguest_data->cr2)) | 316 | put_user(cpu->arch.last_pagefault, |
320 | kill_guest(lg, "Writing cr2"); | 317 | &cpu->lg->lguest_data->cr2)) |
318 | kill_guest(cpu, "Writing cr2"); | ||
321 | break; | 319 | break; |
322 | case 7: /* We've intercepted a Device Not Available fault. */ | 320 | case 7: /* We've intercepted a Device Not Available fault. */ |
323 | /* 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 |
@@ -345,7 +343,7 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu) | |||
345 | /* 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 |
346 | * 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 |
347 | * it handle), it dies with a cryptic error message. */ | 345 | * it handle), it dies with a cryptic error message. */ |
348 | kill_guest(lg, "unhandled trap %li at %#lx (%#lx)", | 346 | kill_guest(cpu, "unhandled trap %li at %#lx (%#lx)", |
349 | cpu->regs->trapnum, cpu->regs->eip, | 347 | cpu->regs->trapnum, cpu->regs->eip, |
350 | cpu->regs->trapnum == 14 ? cpu->arch.last_pagefault | 348 | cpu->regs->trapnum == 14 ? cpu->arch.last_pagefault |
351 | : cpu->regs->errcode); | 349 | : cpu->regs->errcode); |
@@ -514,11 +512,11 @@ int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args) | |||
514 | int lguest_arch_init_hypercalls(struct lg_cpu *cpu) | 512 | int lguest_arch_init_hypercalls(struct lg_cpu *cpu) |
515 | { | 513 | { |
516 | u32 tsc_speed; | 514 | u32 tsc_speed; |
517 | struct lguest *lg = cpu->lg; | ||
518 | 515 | ||
519 | /* 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 |
520 | * argument. We check that address now. */ | 517 | * argument. We check that address now. */ |
521 | if (!lguest_address_ok(lg, cpu->hcall->arg1, sizeof(*lg->lguest_data))) | 518 | if (!lguest_address_ok(cpu->lg, cpu->hcall->arg1, |
519 | sizeof(*cpu->lg->lguest_data))) | ||
522 | return -EFAULT; | 520 | return -EFAULT; |
523 | 521 | ||
524 | /* 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 |
@@ -526,7 +524,7 @@ int lguest_arch_init_hypercalls(struct lg_cpu *cpu) | |||
526 | * 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 |
527 | * 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 |
528 | * optimizations. */ | 526 | * optimizations. */ |
529 | lg->lguest_data = lg->mem_base + cpu->hcall->arg1; | 527 | cpu->lg->lguest_data = cpu->lg->mem_base + cpu->hcall->arg1; |
530 | 528 | ||
531 | /* 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 |
532 | * cpu frequency. Some devious chip manufacturers decided that TSC | 530 | * cpu frequency. Some devious chip manufacturers decided that TSC |
@@ -539,12 +537,12 @@ int lguest_arch_init_hypercalls(struct lg_cpu *cpu) | |||
539 | tsc_speed = tsc_khz; | 537 | tsc_speed = tsc_khz; |
540 | else | 538 | else |
541 | tsc_speed = 0; | 539 | tsc_speed = 0; |
542 | if (put_user(tsc_speed, &lg->lguest_data->tsc_khz)) | 540 | if (put_user(tsc_speed, &cpu->lg->lguest_data->tsc_khz)) |
543 | return -EFAULT; | 541 | return -EFAULT; |
544 | 542 | ||
545 | /* The interrupt code might not like the system call vector. */ | 543 | /* The interrupt code might not like the system call vector. */ |
546 | if (!check_syscall_vector(lg)) | 544 | if (!check_syscall_vector(cpu->lg)) |
547 | kill_guest(lg, "bad syscall vector"); | 545 | kill_guest(cpu, "bad syscall vector"); |
548 | 546 | ||
549 | return 0; | 547 | return 0; |
550 | } | 548 | } |