KVM: s390: dont allocate dirty bitmap
[safe/jmp/linux-2.6] / virt / kvm / kvm_main.c
index e4bf88a..9ccaf8f 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
+#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
+#include "coalesced_mmio.h"
+#endif
+
 MODULE_AUTHOR("Qumranet");
 MODULE_LICENSE("GPL");
 
@@ -185,10 +189,23 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_uninit);
 static struct kvm *kvm_create_vm(void)
 {
        struct kvm *kvm = kvm_arch_create_vm();
+#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
+       struct page *page;
+#endif
 
        if (IS_ERR(kvm))
                goto out;
 
+#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
+       page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+       if (!page) {
+               kfree(kvm);
+               return ERR_PTR(-ENOMEM);
+       }
+       kvm->coalesced_mmio_ring =
+                       (struct kvm_coalesced_mmio_ring *)page_address(page);
+#endif
+
        kvm->mm = current->mm;
        atomic_inc(&kvm->mm->mm_count);
        spin_lock_init(&kvm->mmu_lock);
@@ -200,6 +217,9 @@ static struct kvm *kvm_create_vm(void)
        spin_lock(&kvm_lock);
        list_add(&kvm->vm_list, &vm_list);
        spin_unlock(&kvm_lock);
+#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
+       kvm_coalesced_mmio_init(kvm);
+#endif
 out:
        return kvm;
 }
@@ -242,6 +262,10 @@ static void kvm_destroy_vm(struct kvm *kvm)
        spin_unlock(&kvm_lock);
        kvm_io_bus_destroy(&kvm->pio_bus);
        kvm_io_bus_destroy(&kvm->mmio_bus);
+#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
+       if (kvm->coalesced_mmio_ring != NULL)
+               free_page((unsigned long)kvm->coalesced_mmio_ring);
+#endif
        kvm_arch_destroy_vm(kvm);
        mmdrop(mm);
 }
@@ -335,6 +359,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
        r = -ENOMEM;
 
        /* Allocate if a slot is being created */
+#ifndef CONFIG_S390
        if (npages && !new.rmap) {
                new.rmap = vmalloc(npages * sizeof(struct page *));
 
@@ -375,6 +400,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
                        goto out_free;
                memset(new.dirty_bitmap, 0, dirty_bytes);
        }
+#endif /* not defined CONFIG_S390 */
 
        if (mem->slot >= kvm->nmemslots)
                kvm->nmemslots = mem->slot + 1;
@@ -826,6 +852,10 @@ static int kvm_vcpu_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        else if (vmf->pgoff == KVM_PIO_PAGE_OFFSET)
                page = virt_to_page(vcpu->arch.pio_data);
 #endif
+#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
+       else if (vmf->pgoff == KVM_COALESCED_MMIO_PAGE_OFFSET)
+               page = virt_to_page(vcpu->kvm->coalesced_mmio_ring);
+#endif
        else
                return VM_FAULT_SIGBUS;
        get_page(page);
@@ -1148,6 +1178,32 @@ static long kvm_vm_ioctl(struct file *filp,
                        goto out;
                break;
        }
+#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
+       case KVM_REGISTER_COALESCED_MMIO: {
+               struct kvm_coalesced_mmio_zone zone;
+               r = -EFAULT;
+               if (copy_from_user(&zone, argp, sizeof zone))
+                       goto out;
+               r = -ENXIO;
+               r = kvm_vm_ioctl_register_coalesced_mmio(kvm, &zone);
+               if (r)
+                       goto out;
+               r = 0;
+               break;
+       }
+       case KVM_UNREGISTER_COALESCED_MMIO: {
+               struct kvm_coalesced_mmio_zone zone;
+               r = -EFAULT;
+               if (copy_from_user(&zone, argp, sizeof zone))
+                       goto out;
+               r = -ENXIO;
+               r = kvm_vm_ioctl_unregister_coalesced_mmio(kvm, &zone);
+               if (r)
+                       goto out;
+               r = 0;
+               break;
+       }
+#endif
        default:
                r = kvm_arch_vm_ioctl(filp, ioctl, arg);
        }
@@ -1232,6 +1288,9 @@ static long kvm_dev_ioctl(struct file *filp,
 #ifdef CONFIG_X86
                r += PAGE_SIZE;    /* pio data page */
 #endif
+#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
+               r += PAGE_SIZE;    /* coalesced mmio ring page */
+#endif
                break;
        case KVM_TRACE_ENABLE:
        case KVM_TRACE_PAUSE:
@@ -1273,7 +1332,6 @@ static void hardware_disable(void *junk)
        if (!cpu_isset(cpu, cpus_hardware_enabled))
                return;
        cpu_clear(cpu, cpus_hardware_enabled);
-       decache_vcpus_on_cpu(cpu);
        kvm_arch_hardware_disable(NULL);
 }
 
@@ -1351,14 +1409,15 @@ void kvm_io_bus_destroy(struct kvm_io_bus *bus)
        }
 }
 
-struct kvm_io_device *kvm_io_bus_find_dev(struct kvm_io_bus *bus, gpa_t addr)
+struct kvm_io_device *kvm_io_bus_find_dev(struct kvm_io_bus *bus,
+                                         gpa_t addr, int len, int is_write)
 {
        int i;
 
        for (i = 0; i < bus->dev_count; i++) {
                struct kvm_io_device *pos = bus->devs[i];
 
-               if (pos->in_range(pos, addr))
+               if (pos->in_range(pos, addr, len, is_write))
                        return pos;
        }