hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/virt/kvm/coalesced_mmio.c
....@@ -86,6 +86,7 @@
8686 ring->coalesced_mmio[insert].phys_addr = addr;
8787 ring->coalesced_mmio[insert].len = len;
8888 memcpy(ring->coalesced_mmio[insert].data, val, len);
89
+ ring->coalesced_mmio[insert].pio = dev->zone.pio;
8990 smp_wmb();
9091 ring->last = (insert + 1) % KVM_COALESCED_MMIO_MAX;
9192 spin_unlock(&dev->kvm->ring_lock);
....@@ -109,26 +110,22 @@
109110 int kvm_coalesced_mmio_init(struct kvm *kvm)
110111 {
111112 struct page *page;
112
- int ret;
113113
114
- ret = -ENOMEM;
115114 page = alloc_page(GFP_KERNEL | __GFP_ZERO);
116115 if (!page)
117
- goto out_err;
116
+ return -ENOMEM;
118117
119
- ret = 0;
120118 kvm->coalesced_mmio_ring = page_address(page);
121119
122120 /*
123121 * We're using this spinlock to sync access to the coalesced ring.
124
- * The list doesn't need it's own lock since device registration and
122
+ * The list doesn't need its own lock since device registration and
125123 * unregistration should only happen when kvm->slots_lock is held.
126124 */
127125 spin_lock_init(&kvm->ring_lock);
128126 INIT_LIST_HEAD(&kvm->coalesced_zones);
129127
130
-out_err:
131
- return ret;
128
+ return 0;
132129 }
133130
134131 void kvm_coalesced_mmio_free(struct kvm *kvm)
....@@ -143,7 +140,11 @@
143140 int ret;
144141 struct kvm_coalesced_mmio_dev *dev;
145142
146
- dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev), GFP_KERNEL);
143
+ if (zone->pio != 1 && zone->pio != 0)
144
+ return -EINVAL;
145
+
146
+ dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev),
147
+ GFP_KERNEL_ACCOUNT);
147148 if (!dev)
148149 return -ENOMEM;
149150
....@@ -152,8 +153,9 @@
152153 dev->zone = *zone;
153154
154155 mutex_lock(&kvm->slots_lock);
155
- ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, zone->addr,
156
- zone->size, &dev->dev);
156
+ ret = kvm_io_bus_register_dev(kvm,
157
+ zone->pio ? KVM_PIO_BUS : KVM_MMIO_BUS,
158
+ zone->addr, zone->size, &dev->dev);
157159 if (ret < 0)
158160 goto out_free_dev;
159161 list_add_tail(&dev->list, &kvm->coalesced_zones);
....@@ -172,16 +174,38 @@
172174 struct kvm_coalesced_mmio_zone *zone)
173175 {
174176 struct kvm_coalesced_mmio_dev *dev, *tmp;
177
+ int r;
178
+
179
+ if (zone->pio != 1 && zone->pio != 0)
180
+ return -EINVAL;
175181
176182 mutex_lock(&kvm->slots_lock);
177183
178
- list_for_each_entry_safe(dev, tmp, &kvm->coalesced_zones, list)
179
- if (coalesced_mmio_in_range(dev, zone->addr, zone->size)) {
180
- kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &dev->dev);
184
+ list_for_each_entry_safe(dev, tmp, &kvm->coalesced_zones, list) {
185
+ if (zone->pio == dev->zone.pio &&
186
+ coalesced_mmio_in_range(dev, zone->addr, zone->size)) {
187
+ r = kvm_io_bus_unregister_dev(kvm,
188
+ zone->pio ? KVM_PIO_BUS : KVM_MMIO_BUS, &dev->dev);
189
+
181190 kvm_iodevice_destructor(&dev->dev);
191
+
192
+ /*
193
+ * On failure, unregister destroys all devices on the
194
+ * bus _except_ the target device, i.e. coalesced_zones
195
+ * has been modified. Bail after destroying the target
196
+ * device, there's no need to restart the walk as there
197
+ * aren't any zones left.
198
+ */
199
+ if (r)
200
+ break;
182201 }
202
+ }
183203
184204 mutex_unlock(&kvm->slots_lock);
185205
206
+ /*
207
+ * Ignore the result of kvm_io_bus_unregister_dev(), from userspace's
208
+ * perspective, the coalesced MMIO is most definitely unregistered.
209
+ */
186210 return 0;
187211 }