aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2009-06-29 15:24:32 -0400
committerAvi Kivity <avi@redhat.com>2009-09-10 01:33:05 -0400
commitbda9020e2463ec94db9f97e8615f3bae22069838 (patch)
tree48125316d4c0f419a35aefdfbf665d30ad0c55ca /arch/x86/kvm/x86.c
parent6c474694530f377507f9aca438c17206e051e6e7 (diff)
KVM: remove in_range from io devices
This changes bus accesses to use high-level kvm_io_bus_read/kvm_io_bus_write functions. in_range now becomes unused so it is removed from device ops in favor of read/write callbacks performing range checks internally. This allows aliasing (mostly for in-kernel virtio), as well as better error handling by making it possible to pass errors up to userspace. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c110
1 files changed, 32 insertions, 78 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7ce6367c1976..96f0ae7d97b6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2333,35 +2333,23 @@ static void kvm_init_msr_list(void)
2333 num_msrs_to_save = j; 2333 num_msrs_to_save = j;
2334} 2334}
2335 2335
2336/* 2336static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len,
2337 * Only apic need an MMIO device hook, so shortcut now.. 2337 const void *v)
2338 */
2339static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,
2340 gpa_t addr, int len,
2341 int is_write)
2342{ 2338{
2343 struct kvm_io_device *dev; 2339 if (vcpu->arch.apic &&
2340 !kvm_iodevice_write(&vcpu->arch.apic->dev, addr, len, v))
2341 return 0;
2344 2342
2345 if (vcpu->arch.apic) { 2343 return kvm_io_bus_write(&vcpu->kvm->mmio_bus, addr, len, v);
2346 dev = &vcpu->arch.apic->dev;
2347 if (kvm_iodevice_in_range(dev, addr, len, is_write))
2348 return dev;
2349 }
2350 return NULL;
2351} 2344}
2352 2345
2353 2346static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
2354static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
2355 gpa_t addr, int len,
2356 int is_write)
2357{ 2347{
2358 struct kvm_io_device *dev; 2348 if (vcpu->arch.apic &&
2349 !kvm_iodevice_read(&vcpu->arch.apic->dev, addr, len, v))
2350 return 0;
2359 2351
2360 dev = vcpu_find_pervcpu_dev(vcpu, addr, len, is_write); 2352 return kvm_io_bus_read(&vcpu->kvm->mmio_bus, addr, len, v);
2361 if (dev == NULL)
2362 dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len,
2363 is_write);
2364 return dev;
2365} 2353}
2366 2354
2367static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes, 2355static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
@@ -2430,7 +2418,6 @@ static int emulator_read_emulated(unsigned long addr,
2430 unsigned int bytes, 2418 unsigned int bytes,
2431 struct kvm_vcpu *vcpu) 2419 struct kvm_vcpu *vcpu)
2432{ 2420{
2433 struct kvm_io_device *mmio_dev;
2434 gpa_t gpa; 2421 gpa_t gpa;
2435 2422
2436 if (vcpu->mmio_read_completed) { 2423 if (vcpu->mmio_read_completed) {
@@ -2455,13 +2442,8 @@ mmio:
2455 /* 2442 /*
2456 * Is this MMIO handled locally? 2443 * Is this MMIO handled locally?
2457 */ 2444 */
2458 mutex_lock(&vcpu->kvm->lock); 2445 if (!vcpu_mmio_read(vcpu, gpa, bytes, val))
2459 mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 0);
2460 mutex_unlock(&vcpu->kvm->lock);
2461 if (mmio_dev) {
2462 kvm_iodevice_read(mmio_dev, gpa, bytes, val);
2463 return X86EMUL_CONTINUE; 2446 return X86EMUL_CONTINUE;
2464 }
2465 2447
2466 vcpu->mmio_needed = 1; 2448 vcpu->mmio_needed = 1;
2467 vcpu->mmio_phys_addr = gpa; 2449 vcpu->mmio_phys_addr = gpa;
@@ -2488,7 +2470,6 @@ static int emulator_write_emulated_onepage(unsigned long addr,
2488 unsigned int bytes, 2470 unsigned int bytes,
2489 struct kvm_vcpu *vcpu) 2471 struct kvm_vcpu *vcpu)
2490{ 2472{
2491 struct kvm_io_device *mmio_dev;
2492 gpa_t gpa; 2473 gpa_t gpa;
2493 2474
2494 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); 2475 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
@@ -2509,13 +2490,8 @@ mmio:
2509 /* 2490 /*
2510 * Is this MMIO handled locally? 2491 * Is this MMIO handled locally?
2511 */ 2492 */
2512 mutex_lock(&vcpu->kvm->lock); 2493 if (!vcpu_mmio_write(vcpu, gpa, bytes, val))
2513 mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 1);
2514 mutex_unlock(&vcpu->kvm->lock);
2515 if (mmio_dev) {
2516 kvm_iodevice_write(mmio_dev, gpa, bytes, val);
2517 return X86EMUL_CONTINUE; 2494 return X86EMUL_CONTINUE;
2518 }
2519 2495
2520 vcpu->mmio_needed = 1; 2496 vcpu->mmio_needed = 1;
2521 vcpu->mmio_phys_addr = gpa; 2497 vcpu->mmio_phys_addr = gpa;
@@ -2850,48 +2826,40 @@ int complete_pio(struct kvm_vcpu *vcpu)
2850 return 0; 2826 return 0;
2851} 2827}
2852 2828
2853static void kernel_pio(struct kvm_io_device *pio_dev, 2829static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
2854 struct kvm_vcpu *vcpu,
2855 void *pd)
2856{ 2830{
2857 /* TODO: String I/O for in kernel device */ 2831 /* TODO: String I/O for in kernel device */
2832 int r;
2858 2833
2859 if (vcpu->arch.pio.in) 2834 if (vcpu->arch.pio.in)
2860 kvm_iodevice_read(pio_dev, vcpu->arch.pio.port, 2835 r = kvm_io_bus_read(&vcpu->kvm->pio_bus, vcpu->arch.pio.port,
2861 vcpu->arch.pio.size, 2836 vcpu->arch.pio.size, pd);
2862 pd);
2863 else 2837 else
2864 kvm_iodevice_write(pio_dev, vcpu->arch.pio.port, 2838 r = kvm_io_bus_write(&vcpu->kvm->pio_bus, vcpu->arch.pio.port,
2865 vcpu->arch.pio.size, 2839 vcpu->arch.pio.size, pd);
2866 pd); 2840 return r;
2867} 2841}
2868 2842
2869static void pio_string_write(struct kvm_io_device *pio_dev, 2843static int pio_string_write(struct kvm_vcpu *vcpu)
2870 struct kvm_vcpu *vcpu)
2871{ 2844{
2872 struct kvm_pio_request *io = &vcpu->arch.pio; 2845 struct kvm_pio_request *io = &vcpu->arch.pio;
2873 void *pd = vcpu->arch.pio_data; 2846 void *pd = vcpu->arch.pio_data;
2874 int i; 2847 int i, r = 0;
2875 2848
2876 for (i = 0; i < io->cur_count; i++) { 2849 for (i = 0; i < io->cur_count; i++) {
2877 kvm_iodevice_write(pio_dev, io->port, 2850 if (kvm_io_bus_write(&vcpu->kvm->pio_bus,
2878 io->size, 2851 io->port, io->size, pd)) {
2879 pd); 2852 r = -EOPNOTSUPP;
2853 break;
2854 }
2880 pd += io->size; 2855 pd += io->size;
2881 } 2856 }
2882} 2857 return r;
2883
2884static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
2885 gpa_t addr, int len,
2886 int is_write)
2887{
2888 return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr, len, is_write);
2889} 2858}
2890 2859
2891int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, 2860int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2892 int size, unsigned port) 2861 int size, unsigned port)
2893{ 2862{
2894 struct kvm_io_device *pio_dev;
2895 unsigned long val; 2863 unsigned long val;
2896 2864
2897 vcpu->run->exit_reason = KVM_EXIT_IO; 2865 vcpu->run->exit_reason = KVM_EXIT_IO;
@@ -2911,11 +2879,7 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2911 val = kvm_register_read(vcpu, VCPU_REGS_RAX); 2879 val = kvm_register_read(vcpu, VCPU_REGS_RAX);
2912 memcpy(vcpu->arch.pio_data, &val, 4); 2880 memcpy(vcpu->arch.pio_data, &val, 4);
2913 2881
2914 mutex_lock(&vcpu->kvm->lock); 2882 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
2915 pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in);
2916 mutex_unlock(&vcpu->kvm->lock);
2917 if (pio_dev) {
2918 kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data);
2919 complete_pio(vcpu); 2883 complete_pio(vcpu);
2920 return 1; 2884 return 1;
2921 } 2885 }
@@ -2929,7 +2893,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2929{ 2893{
2930 unsigned now, in_page; 2894 unsigned now, in_page;
2931 int ret = 0; 2895 int ret = 0;
2932 struct kvm_io_device *pio_dev;
2933 2896
2934 vcpu->run->exit_reason = KVM_EXIT_IO; 2897 vcpu->run->exit_reason = KVM_EXIT_IO;
2935 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; 2898 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
@@ -2973,12 +2936,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2973 2936
2974 vcpu->arch.pio.guest_gva = address; 2937 vcpu->arch.pio.guest_gva = address;
2975 2938
2976 mutex_lock(&vcpu->kvm->lock);
2977 pio_dev = vcpu_find_pio_dev(vcpu, port,
2978 vcpu->arch.pio.cur_count,
2979 !vcpu->arch.pio.in);
2980 mutex_unlock(&vcpu->kvm->lock);
2981
2982 if (!vcpu->arch.pio.in) { 2939 if (!vcpu->arch.pio.in) {
2983 /* string PIO write */ 2940 /* string PIO write */
2984 ret = pio_copy_data(vcpu); 2941 ret = pio_copy_data(vcpu);
@@ -2986,16 +2943,13 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2986 kvm_inject_gp(vcpu, 0); 2943 kvm_inject_gp(vcpu, 0);
2987 return 1; 2944 return 1;
2988 } 2945 }
2989 if (ret == 0 && pio_dev) { 2946 if (ret == 0 && !pio_string_write(vcpu)) {
2990 pio_string_write(pio_dev, vcpu);
2991 complete_pio(vcpu); 2947 complete_pio(vcpu);
2992 if (vcpu->arch.pio.count == 0) 2948 if (vcpu->arch.pio.count == 0)
2993 ret = 1; 2949 ret = 1;
2994 } 2950 }
2995 } else if (pio_dev) 2951 }
2996 pr_unimpl(vcpu, "no string pio read support yet, " 2952 /* no string PIO read support yet */
2997 "port %x size %d count %ld\n",
2998 port, size, count);
2999 2953
3000 return ret; 2954 return ret;
3001} 2955}