diff options
Diffstat (limited to 'virt/kvm/coalesced_mmio.c')
| -rw-r--r-- | virt/kvm/coalesced_mmio.c | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c index 04d69cd7049b..5169736377a3 100644 --- a/virt/kvm/coalesced_mmio.c +++ b/virt/kvm/coalesced_mmio.c | |||
| @@ -92,41 +92,64 @@ static const struct kvm_io_device_ops coalesced_mmio_ops = { | |||
| 92 | int kvm_coalesced_mmio_init(struct kvm *kvm) | 92 | int kvm_coalesced_mmio_init(struct kvm *kvm) |
| 93 | { | 93 | { |
| 94 | struct kvm_coalesced_mmio_dev *dev; | 94 | struct kvm_coalesced_mmio_dev *dev; |
| 95 | struct page *page; | ||
| 95 | int ret; | 96 | int ret; |
| 96 | 97 | ||
| 98 | ret = -ENOMEM; | ||
| 99 | page = alloc_page(GFP_KERNEL | __GFP_ZERO); | ||
| 100 | if (!page) | ||
| 101 | goto out_err; | ||
| 102 | kvm->coalesced_mmio_ring = page_address(page); | ||
| 103 | |||
| 104 | ret = -ENOMEM; | ||
| 97 | dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev), GFP_KERNEL); | 105 | dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev), GFP_KERNEL); |
| 98 | if (!dev) | 106 | if (!dev) |
| 99 | return -ENOMEM; | 107 | goto out_free_page; |
| 100 | spin_lock_init(&dev->lock); | 108 | spin_lock_init(&dev->lock); |
| 101 | kvm_iodevice_init(&dev->dev, &coalesced_mmio_ops); | 109 | kvm_iodevice_init(&dev->dev, &coalesced_mmio_ops); |
| 102 | dev->kvm = kvm; | 110 | dev->kvm = kvm; |
| 103 | kvm->coalesced_mmio_dev = dev; | 111 | kvm->coalesced_mmio_dev = dev; |
| 104 | 112 | ||
| 105 | ret = kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &dev->dev); | 113 | mutex_lock(&kvm->slots_lock); |
| 114 | ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, &dev->dev); | ||
| 115 | mutex_unlock(&kvm->slots_lock); | ||
| 106 | if (ret < 0) | 116 | if (ret < 0) |
| 107 | kfree(dev); | 117 | goto out_free_dev; |
| 118 | |||
| 119 | return ret; | ||
| 108 | 120 | ||
| 121 | out_free_dev: | ||
| 122 | kfree(dev); | ||
| 123 | out_free_page: | ||
| 124 | __free_page(page); | ||
| 125 | out_err: | ||
| 109 | return ret; | 126 | return ret; |
| 110 | } | 127 | } |
| 111 | 128 | ||
| 129 | void kvm_coalesced_mmio_free(struct kvm *kvm) | ||
| 130 | { | ||
| 131 | if (kvm->coalesced_mmio_ring) | ||
| 132 | free_page((unsigned long)kvm->coalesced_mmio_ring); | ||
| 133 | } | ||
| 134 | |||
| 112 | int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, | 135 | int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, |
| 113 | struct kvm_coalesced_mmio_zone *zone) | 136 | struct kvm_coalesced_mmio_zone *zone) |
| 114 | { | 137 | { |
| 115 | struct kvm_coalesced_mmio_dev *dev = kvm->coalesced_mmio_dev; | 138 | struct kvm_coalesced_mmio_dev *dev = kvm->coalesced_mmio_dev; |
| 116 | 139 | ||
| 117 | if (dev == NULL) | 140 | if (dev == NULL) |
| 118 | return -EINVAL; | 141 | return -EINVAL; |
| 119 | 142 | ||
| 120 | down_write(&kvm->slots_lock); | 143 | mutex_lock(&kvm->slots_lock); |
| 121 | if (dev->nb_zones >= KVM_COALESCED_MMIO_ZONE_MAX) { | 144 | if (dev->nb_zones >= KVM_COALESCED_MMIO_ZONE_MAX) { |
| 122 | up_write(&kvm->slots_lock); | 145 | mutex_unlock(&kvm->slots_lock); |
| 123 | return -ENOBUFS; | 146 | return -ENOBUFS; |
| 124 | } | 147 | } |
| 125 | 148 | ||
| 126 | dev->zone[dev->nb_zones] = *zone; | 149 | dev->zone[dev->nb_zones] = *zone; |
| 127 | dev->nb_zones++; | 150 | dev->nb_zones++; |
| 128 | 151 | ||
| 129 | up_write(&kvm->slots_lock); | 152 | mutex_unlock(&kvm->slots_lock); |
| 130 | return 0; | 153 | return 0; |
| 131 | } | 154 | } |
| 132 | 155 | ||
| @@ -140,10 +163,10 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm, | |||
| 140 | if (dev == NULL) | 163 | if (dev == NULL) |
| 141 | return -EINVAL; | 164 | return -EINVAL; |
| 142 | 165 | ||
| 143 | down_write(&kvm->slots_lock); | 166 | mutex_lock(&kvm->slots_lock); |
| 144 | 167 | ||
| 145 | i = dev->nb_zones; | 168 | i = dev->nb_zones; |
| 146 | while(i) { | 169 | while (i) { |
| 147 | z = &dev->zone[i - 1]; | 170 | z = &dev->zone[i - 1]; |
| 148 | 171 | ||
| 149 | /* unregister all zones | 172 | /* unregister all zones |
| @@ -158,7 +181,7 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm, | |||
| 158 | i--; | 181 | i--; |
| 159 | } | 182 | } |
| 160 | 183 | ||
| 161 | up_write(&kvm->slots_lock); | 184 | mutex_unlock(&kvm->slots_lock); |
| 162 | 185 | ||
| 163 | return 0; | 186 | return 0; |
| 164 | } | 187 | } |
