aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorIzik Eidus <ieidus@redhat.com>2008-12-28 18:42:20 -0500
committerAvi Kivity <avi@redhat.com>2009-03-24 05:02:54 -0400
commit0f346074403bc109f9569f14b45cb09e83729032 (patch)
tree484cfe57495d1a0e45452b8041dc41c4de044d3e /arch/x86/kvm
parent77c2002e7c6f019f59a6f3cc5f8b16b41748dbe1 (diff)
KVM: remove the vmap usage
vmap() on guest pages hides those pages from the Linux mm for an extended (userspace determined) amount of time. Get rid of it. Signed-off-by: Izik Eidus <ieidus@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/x86.c62
1 files changed, 13 insertions, 49 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 67f91764e99b..2a4f3a697343 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2371,40 +2371,19 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
2371} 2371}
2372EXPORT_SYMBOL_GPL(emulate_instruction); 2372EXPORT_SYMBOL_GPL(emulate_instruction);
2373 2373
2374static void free_pio_guest_pages(struct kvm_vcpu *vcpu)
2375{
2376 int i;
2377
2378 for (i = 0; i < ARRAY_SIZE(vcpu->arch.pio.guest_pages); ++i)
2379 if (vcpu->arch.pio.guest_pages[i]) {
2380 kvm_release_page_dirty(vcpu->arch.pio.guest_pages[i]);
2381 vcpu->arch.pio.guest_pages[i] = NULL;
2382 }
2383}
2384
2385static int pio_copy_data(struct kvm_vcpu *vcpu) 2374static int pio_copy_data(struct kvm_vcpu *vcpu)
2386{ 2375{
2387 void *p = vcpu->arch.pio_data; 2376 void *p = vcpu->arch.pio_data;
2388 void *q; 2377 gva_t q = vcpu->arch.pio.guest_gva;
2389 unsigned bytes; 2378 unsigned bytes;
2390 int nr_pages = vcpu->arch.pio.guest_pages[1] ? 2 : 1; 2379 int ret;
2391 2380
2392 q = vmap(vcpu->arch.pio.guest_pages, nr_pages, VM_READ|VM_WRITE,
2393 PAGE_KERNEL);
2394 if (!q) {
2395 free_pio_guest_pages(vcpu);
2396 return -ENOMEM;
2397 }
2398 q += vcpu->arch.pio.guest_page_offset;
2399 bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count; 2381 bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count;
2400 if (vcpu->arch.pio.in) 2382 if (vcpu->arch.pio.in)
2401 memcpy(q, p, bytes); 2383 ret = kvm_write_guest_virt(q, p, bytes, vcpu);
2402 else 2384 else
2403 memcpy(p, q, bytes); 2385 ret = kvm_read_guest_virt(q, p, bytes, vcpu);
2404 q -= vcpu->arch.pio.guest_page_offset; 2386 return ret;
2405 vunmap(q);
2406 free_pio_guest_pages(vcpu);
2407 return 0;
2408} 2387}
2409 2388
2410int complete_pio(struct kvm_vcpu *vcpu) 2389int complete_pio(struct kvm_vcpu *vcpu)
@@ -2515,7 +2494,6 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2515 vcpu->arch.pio.in = in; 2494 vcpu->arch.pio.in = in;
2516 vcpu->arch.pio.string = 0; 2495 vcpu->arch.pio.string = 0;
2517 vcpu->arch.pio.down = 0; 2496 vcpu->arch.pio.down = 0;
2518 vcpu->arch.pio.guest_page_offset = 0;
2519 vcpu->arch.pio.rep = 0; 2497 vcpu->arch.pio.rep = 0;
2520 2498
2521 if (vcpu->run->io.direction == KVM_EXIT_IO_IN) 2499 if (vcpu->run->io.direction == KVM_EXIT_IO_IN)
@@ -2543,9 +2521,7 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2543 gva_t address, int rep, unsigned port) 2521 gva_t address, int rep, unsigned port)
2544{ 2522{
2545 unsigned now, in_page; 2523 unsigned now, in_page;
2546 int i, ret = 0; 2524 int ret = 0;
2547 int nr_pages = 1;
2548 struct page *page;
2549 struct kvm_io_device *pio_dev; 2525 struct kvm_io_device *pio_dev;
2550 2526
2551 vcpu->run->exit_reason = KVM_EXIT_IO; 2527 vcpu->run->exit_reason = KVM_EXIT_IO;
@@ -2557,7 +2533,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2557 vcpu->arch.pio.in = in; 2533 vcpu->arch.pio.in = in;
2558 vcpu->arch.pio.string = 1; 2534 vcpu->arch.pio.string = 1;
2559 vcpu->arch.pio.down = down; 2535 vcpu->arch.pio.down = down;
2560 vcpu->arch.pio.guest_page_offset = offset_in_page(address);
2561 vcpu->arch.pio.rep = rep; 2536 vcpu->arch.pio.rep = rep;
2562 2537
2563 if (vcpu->run->io.direction == KVM_EXIT_IO_IN) 2538 if (vcpu->run->io.direction == KVM_EXIT_IO_IN)
@@ -2577,15 +2552,8 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2577 else 2552 else
2578 in_page = offset_in_page(address) + size; 2553 in_page = offset_in_page(address) + size;
2579 now = min(count, (unsigned long)in_page / size); 2554 now = min(count, (unsigned long)in_page / size);
2580 if (!now) { 2555 if (!now)
2581 /*
2582 * String I/O straddles page boundary. Pin two guest pages
2583 * so that we satisfy atomicity constraints. Do just one
2584 * transaction to avoid complexity.
2585 */
2586 nr_pages = 2;
2587 now = 1; 2556 now = 1;
2588 }
2589 if (down) { 2557 if (down) {
2590 /* 2558 /*
2591 * String I/O in reverse. Yuck. Kill the guest, fix later. 2559 * String I/O in reverse. Yuck. Kill the guest, fix later.
@@ -2600,15 +2568,7 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2600 if (vcpu->arch.pio.cur_count == vcpu->arch.pio.count) 2568 if (vcpu->arch.pio.cur_count == vcpu->arch.pio.count)
2601 kvm_x86_ops->skip_emulated_instruction(vcpu); 2569 kvm_x86_ops->skip_emulated_instruction(vcpu);
2602 2570
2603 for (i = 0; i < nr_pages; ++i) { 2571 vcpu->arch.pio.guest_gva = address;
2604 page = gva_to_page(vcpu, address + i * PAGE_SIZE);
2605 vcpu->arch.pio.guest_pages[i] = page;
2606 if (!page) {
2607 kvm_inject_gp(vcpu, 0);
2608 free_pio_guest_pages(vcpu);
2609 return 1;
2610 }
2611 }
2612 2572
2613 pio_dev = vcpu_find_pio_dev(vcpu, port, 2573 pio_dev = vcpu_find_pio_dev(vcpu, port,
2614 vcpu->arch.pio.cur_count, 2574 vcpu->arch.pio.cur_count,
@@ -2616,7 +2576,11 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2616 if (!vcpu->arch.pio.in) { 2576 if (!vcpu->arch.pio.in) {
2617 /* string PIO write */ 2577 /* string PIO write */
2618 ret = pio_copy_data(vcpu); 2578 ret = pio_copy_data(vcpu);
2619 if (ret >= 0 && pio_dev) { 2579 if (ret == X86EMUL_PROPAGATE_FAULT) {
2580 kvm_inject_gp(vcpu, 0);
2581 return 1;
2582 }
2583 if (ret == 0 && pio_dev) {
2620 pio_string_write(pio_dev, vcpu); 2584 pio_string_write(pio_dev, vcpu);
2621 complete_pio(vcpu); 2585 complete_pio(vcpu);
2622 if (vcpu->arch.pio.count == 0) 2586 if (vcpu->arch.pio.count == 0)