@@ -74,6 +74,14 @@ config KVM_TRACE
relayfs. Note the ABI is not considered stable and will be
modified in future updates.
+config KVM_MAX_IO_DEVICES
+ int "Maximum IO devices support per VM"
+ depends on KVM
+ default "256"
+ ---help---
+ This option influences the maximum number of MMIO, PIO, and other
+ io-devices that can simultaneously register on a per-guest basis.
+
# OK, it's a little counter-intuitive to do this, but it puts it neatly under
# the virtualization menu.
source drivers/lguest/Kconfig
@@ -621,13 +621,13 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
kvm_iodevice_init(&pit->dev, &pit_dev_ops);
- ret = kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);
+ ret = kvm_io_bus_register_dev(kvm, &kvm->pio_bus, &pit->dev);
if (ret < 0)
goto fail;
if (flags & KVM_PIT_SPEAKER_DUMMY) {
kvm_iodevice_init(&pit->speaker_dev, &speaker_dev_ops);
- ret = kvm_io_bus_register_dev(&kvm->pio_bus,
+ ret = kvm_io_bus_register_dev(kvm, &kvm->pio_bus,
&pit->speaker_dev);
if (ret < 0)
goto fail;
@@ -637,9 +637,10 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
fail:
if (flags & KVM_PIT_SPEAKER_DUMMY)
- kvm_io_bus_unregister_dev(&kvm->pio_bus, &pit->speaker_dev);
+ kvm_io_bus_unregister_dev(kvm, &kvm->pio_bus,
+ &pit->speaker_dev);
- kvm_io_bus_unregister_dev(&kvm->pio_bus, &pit->dev);
+ kvm_io_bus_unregister_dev(kvm, &kvm->pio_bus, &pit->dev);
if (pit->irq_source_id >= 0)
kvm_free_irq_source_id(kvm, pit->irq_source_id);
@@ -550,7 +550,7 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
* Initialize PIO device
*/
kvm_iodevice_init(&s->dev, &picdev_ops);
- ret = kvm_io_bus_register_dev(&kvm->pio_bus, &s->dev);
+ ret = kvm_io_bus_register_dev(kvm, &kvm->pio_bus, &s->dev);
if (ret < 0) {
kfree(s);
return NULL;
@@ -61,10 +61,12 @@ void kvm_io_bus_init(struct kvm_io_bus *bus);
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, int len, int is_write);
-int kvm_io_bus_register_dev(struct kvm_io_bus *bus,
- struct kvm_io_device *dev);
-void kvm_io_bus_unregister_dev(struct kvm_io_bus *bus,
+int kvm_io_bus_register_dev(struct kvm *kvm,
+ struct kvm_io_bus *bus,
struct kvm_io_device *dev);
+void kvm_io_bus_unregister_dev(struct kvm *kvm,
+ struct kvm_io_bus *bus,
+ struct kvm_io_device *dev);
struct kvm_vcpu {
struct kvm *kvm;
@@ -139,6 +141,7 @@ struct kvm {
atomic_t online_vcpus;
struct list_head vm_list;
struct mutex lock;
+ unsigned long io_device_count;
struct kvm_io_bus mmio_bus;
struct kvm_io_bus pio_bus;
#ifdef CONFIG_HAVE_KVM_EVENTFD
@@ -104,7 +104,7 @@ int kvm_coalesced_mmio_init(struct kvm *kvm)
dev->kvm = kvm;
kvm->coalesced_mmio_dev = dev;
- ret = kvm_io_bus_register_dev(&kvm->mmio_bus, &dev->dev);
+ ret = kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &dev->dev);
if (ret < 0)
kfree(dev);
@@ -345,7 +345,7 @@ int kvm_ioapic_init(struct kvm *kvm)
kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops);
ioapic->kvm = kvm;
- ret = kvm_io_bus_register_dev(&kvm->mmio_bus, &ioapic->dev);
+ ret = kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &ioapic->dev);
if (ret < 0)
kfree(ioapic);
@@ -2482,18 +2482,25 @@ struct kvm_io_device *kvm_io_bus_find_dev(struct kvm_io_bus *bus,
}
/* assumes kvm->lock held */
-int kvm_io_bus_register_dev(struct kvm_io_bus *bus, struct kvm_io_device *dev)
+int kvm_io_bus_register_dev(struct kvm *kvm,
+ struct kvm_io_bus *bus,
+ struct kvm_io_device *dev)
{
if (bus->dev_count > (NR_IOBUS_DEVS-1))
return -ENOSPC;
+ if (kvm->io_device_count >= CONFIG_KVM_MAX_IO_DEVICES)
+ return -ENOSPC;
+
bus->devs[bus->dev_count++] = dev;
+ kvm->io_device_count++;
return 0;
}
/* assumes kvm->lock held */
-void kvm_io_bus_unregister_dev(struct kvm_io_bus *bus,
+void kvm_io_bus_unregister_dev(struct kvm *kvm,
+ struct kvm_io_bus *bus,
struct kvm_io_device *dev)
{
int i;
@@ -2502,6 +2509,7 @@ void kvm_io_bus_unregister_dev(struct kvm_io_bus *bus,
if (bus->devs[i] == dev) {
bus->devs[i] = bus->devs[--bus->dev_count];
+ kvm->io_device_count--;
return;
}
}
This patch adds a .config option for setting a upper resource limit on the number of iodevice-like constructs that can be allocated on a per-guest basis. It also adds a per-vm variable (io_device_count) that tracks the aggregate number of io_devices registered. Today this is limited purely to PIO/MMIO devices, though it is intended that this will grow in the future (such as including iosignalfd aliases, etc). This patch has no bearing on the number of devices that a given subsystem may _actually_ support, so other limits may be in play at any given moment. For instance, each PIO/MMIO bus is currently limited to 6 devices max. This will likely need to change soon to accomodate upcoming features, but that work is beyond the scope of this patch. The primary point of this patch is to offer a single, easy to understand upper limit on the number of kmalloc's that may occur as the result of a userspace request. In this way, we are free to design future io subsystems with arbitrary constructs (such as lists and btrees) and to know that they will not be allowed to grow without bound in a way that the userspace side should hopefully understand. Signed-off-by: Gregory Haskins <ghaskins@novell.com> --- arch/x86/kvm/Kconfig | 8 ++++++++ arch/x86/kvm/i8254.c | 9 +++++---- arch/x86/kvm/i8259.c | 2 +- include/linux/kvm_host.h | 9 ++++++--- virt/kvm/coalesced_mmio.c | 2 +- virt/kvm/ioapic.c | 2 +- virt/kvm/kvm_main.c | 12 ++++++++++-- 7 files changed, 32 insertions(+), 12 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html