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 | } |