Merge tag 'kvmarm-for-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm...
[linux-2.6-block.git] / virt / kvm / kvm_main.c
index f25aa98a94df430b6064c31e89ff1d614d8846b8..d22b1f4bfa56ae0a181363573e0eb99be2f78919 100644 (file)
@@ -1134,11 +1134,11 @@ EXPORT_SYMBOL_GPL(kvm_get_dirty_log);
 
 #ifdef CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT
 /**
- * kvm_get_dirty_log_protect - get a snapshot of dirty pages, and if any pages
+ * kvm_get_dirty_log_protect - get a snapshot of dirty pages
  *     and reenable dirty page tracking for the corresponding pages.
  * @kvm:       pointer to kvm instance
  * @log:       slot id and address to which we copy the log
- * @is_dirty:  flag set if any page is dirty
+ * @flush:     true if TLB flush is needed by caller
  *
  * We need to keep it in mind that VCPU threads can write to the bitmap
  * concurrently. So, to avoid losing track of dirty pages we keep the
@@ -1223,6 +1223,7 @@ EXPORT_SYMBOL_GPL(kvm_get_dirty_log_protect);
  *     and reenable dirty page tracking for the corresponding pages.
  * @kvm:       pointer to kvm instance
  * @log:       slot id and address from which to fetch the bitmap of dirty pages
+ * @flush:     true if TLB flush is needed by caller
  */
 int kvm_clear_dirty_log_protect(struct kvm *kvm,
                                struct kvm_clear_dirty_log *log, bool *flush)
@@ -1240,7 +1241,7 @@ int kvm_clear_dirty_log_protect(struct kvm *kvm,
        if (as_id >= KVM_ADDRESS_SPACE_NUM || id >= KVM_USER_MEM_SLOTS)
                return -EINVAL;
 
-       if ((log->first_page & 63) || (log->num_pages & 63))
+       if (log->first_page & 63)
                return -EINVAL;
 
        slots = __kvm_memslots(kvm, as_id);
@@ -1250,11 +1251,12 @@ int kvm_clear_dirty_log_protect(struct kvm *kvm,
        if (!dirty_bitmap)
                return -ENOENT;
 
-       n = kvm_dirty_bitmap_bytes(memslot);
+       n = ALIGN(log->num_pages, BITS_PER_LONG) / 8;
 
        if (log->first_page > memslot->npages ||
-           log->num_pages > memslot->npages - log->first_page)
-                       return -EINVAL;
+           log->num_pages > memslot->npages - log->first_page ||
+           (log->num_pages < memslot->npages - log->first_page && (log->num_pages & 63)))
+           return -EINVAL;
 
        *flush = false;
        dirty_bitmap_buffer = kvm_second_dirty_bitmap(memslot);
@@ -1262,8 +1264,8 @@ int kvm_clear_dirty_log_protect(struct kvm *kvm,
                return -EFAULT;
 
        spin_lock(&kvm->mmu_lock);
-       for (offset = log->first_page,
-            i = offset / BITS_PER_LONG, n = log->num_pages / BITS_PER_LONG; n--;
+       for (offset = log->first_page, i = offset / BITS_PER_LONG,
+                n = DIV_ROUND_UP(log->num_pages, BITS_PER_LONG); n--;
             i++, offset += BITS_PER_LONG) {
                unsigned long mask = *dirty_bitmap_buffer++;
                atomic_long_t *p = (atomic_long_t *) &dirty_bitmap[i];
@@ -1740,6 +1742,70 @@ struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
 }
 EXPORT_SYMBOL_GPL(gfn_to_page);
 
+static int __kvm_map_gfn(struct kvm_memory_slot *slot, gfn_t gfn,
+                        struct kvm_host_map *map)
+{
+       kvm_pfn_t pfn;
+       void *hva = NULL;
+       struct page *page = KVM_UNMAPPED_PAGE;
+
+       if (!map)
+               return -EINVAL;
+
+       pfn = gfn_to_pfn_memslot(slot, gfn);
+       if (is_error_noslot_pfn(pfn))
+               return -EINVAL;
+
+       if (pfn_valid(pfn)) {
+               page = pfn_to_page(pfn);
+               hva = kmap(page);
+       } else {
+               hva = memremap(pfn_to_hpa(pfn), PAGE_SIZE, MEMREMAP_WB);
+       }
+
+       if (!hva)
+               return -EFAULT;
+
+       map->page = page;
+       map->hva = hva;
+       map->pfn = pfn;
+       map->gfn = gfn;
+
+       return 0;
+}
+
+int kvm_vcpu_map(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map)
+{
+       return __kvm_map_gfn(kvm_vcpu_gfn_to_memslot(vcpu, gfn), gfn, map);
+}
+EXPORT_SYMBOL_GPL(kvm_vcpu_map);
+
+void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map,
+                   bool dirty)
+{
+       if (!map)
+               return;
+
+       if (!map->hva)
+               return;
+
+       if (map->page)
+               kunmap(map->page);
+       else
+               memunmap(map->hva);
+
+       if (dirty) {
+               kvm_vcpu_mark_page_dirty(vcpu, map->gfn);
+               kvm_release_pfn_dirty(map->pfn);
+       } else {
+               kvm_release_pfn_clean(map->pfn);
+       }
+
+       map->hva = NULL;
+       map->page = NULL;
+}
+EXPORT_SYMBOL_GPL(kvm_vcpu_unmap);
+
 struct page *kvm_vcpu_gfn_to_page(struct kvm_vcpu *vcpu, gfn_t gfn)
 {
        kvm_pfn_t pfn;
@@ -2253,7 +2319,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
        u64 block_ns;
 
        start = cur = ktime_get();
-       if (vcpu->halt_poll_ns) {
+       if (vcpu->halt_poll_ns && !kvm_arch_no_poll(vcpu)) {
                ktime_t stop = ktime_add_ns(ktime_get(), vcpu->halt_poll_ns);
 
                ++vcpu->stat.halt_attempted_poll;
@@ -2884,6 +2950,16 @@ out:
 }
 #endif
 
+static int kvm_device_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+       struct kvm_device *dev = filp->private_data;
+
+       if (dev->ops->mmap)
+               return dev->ops->mmap(dev, vma);
+
+       return -ENODEV;
+}
+
 static int kvm_device_ioctl_attr(struct kvm_device *dev,
                                 int (*accessor)(struct kvm_device *dev,
                                                 struct kvm_device_attr *attr),
@@ -2905,6 +2981,9 @@ static long kvm_device_ioctl(struct file *filp, unsigned int ioctl,
 {
        struct kvm_device *dev = filp->private_data;
 
+       if (dev->kvm->mm != current->mm)
+               return -EIO;
+
        switch (ioctl) {
        case KVM_SET_DEVICE_ATTR:
                return kvm_device_ioctl_attr(dev, dev->ops->set_attr, arg);
@@ -2925,6 +3004,13 @@ static int kvm_device_release(struct inode *inode, struct file *filp)
        struct kvm_device *dev = filp->private_data;
        struct kvm *kvm = dev->kvm;
 
+       if (dev->ops->release) {
+               mutex_lock(&kvm->lock);
+               list_del(&dev->vm_node);
+               dev->ops->release(dev);
+               mutex_unlock(&kvm->lock);
+       }
+
        kvm_put_kvm(kvm);
        return 0;
 }
@@ -2933,6 +3019,7 @@ static const struct file_operations kvm_device_fops = {
        .unlocked_ioctl = kvm_device_ioctl,
        .release = kvm_device_release,
        KVM_COMPAT(kvm_device_ioctl),
+       .mmap = kvm_device_mmap,
 };
 
 struct kvm_device *kvm_device_from_filp(struct file *filp)
@@ -2974,12 +3061,14 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
        struct kvm_device_ops *ops = NULL;
        struct kvm_device *dev;
        bool test = cd->flags & KVM_CREATE_DEVICE_TEST;
+       int type;
        int ret;
 
        if (cd->type >= ARRAY_SIZE(kvm_device_ops_table))
                return -ENODEV;
 
-       ops = kvm_device_ops_table[cd->type];
+       type = array_index_nospec(cd->type, ARRAY_SIZE(kvm_device_ops_table));
+       ops = kvm_device_ops_table[type];
        if (ops == NULL)
                return -ENODEV;
 
@@ -2994,7 +3083,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
        dev->kvm = kvm;
 
        mutex_lock(&kvm->lock);
-       ret = ops->create(dev, cd->type);
+       ret = ops->create(dev, type);
        if (ret < 0) {
                mutex_unlock(&kvm->lock);
                kfree(dev);
@@ -3039,7 +3128,7 @@ static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
        case KVM_CAP_CHECK_EXTENSION_VM:
        case KVM_CAP_ENABLE_CAP_VM:
 #ifdef CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT
-       case KVM_CAP_MANUAL_DIRTY_LOG_PROTECT:
+       case KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2:
 #endif
                return 1;
 #ifdef CONFIG_KVM_MMIO
@@ -3058,6 +3147,8 @@ static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
 #endif
        case KVM_CAP_MAX_VCPU_ID:
                return KVM_MAX_VCPU_ID;
+       case KVM_CAP_NR_MEMSLOTS:
+               return KVM_USER_MEM_SLOTS;
        default:
                break;
        }
@@ -3075,7 +3166,7 @@ static int kvm_vm_ioctl_enable_cap_generic(struct kvm *kvm,
 {
        switch (cap->cap) {
 #ifdef CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT
-       case KVM_CAP_MANUAL_DIRTY_LOG_PROTECT:
+       case KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2:
                if (cap->flags || (cap->args[0] & ~1))
                        return -EINVAL;
                kvm->manual_dirty_log_protect = cap->args[0];