Alexander Graf
2010-Aug-23 21:31 UTC
[PATCH 1/2] S390: take a full byte as ext_param indicator
Currenty the ext_param field only distinguishes between "config change" and "vring interrupt". We can do a lot more with it though, so let's enable a full byte of possible values and constants to #defines while at it. Signed-off-by: Alexander Graf <agraf at suse.de> --- drivers/s390/kvm/kvm_virtio.c | 22 ++++++++++++++++------ 1 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 4e298bc..ada7e2c 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c @@ -27,6 +27,9 @@ #include <asm/s390_ext.h> #define VIRTIO_SUBCODE_64 0x0D00 +#define VIRTIO_PARAM_MASK 0xff +#define VIRTIO_PARAM_VRING_INTERRUPT 0x0 +#define VIRTIO_PARAM_CONFIG_CHANGED 0x1 /* * The pointer to our (page) of device descriptions. @@ -334,7 +337,7 @@ static void kvm_extint_handler(u16 code) { struct virtqueue *vq; u16 subcode; - int config_changed; + u32 param; subcode = S390_lowcore.cpu_addr; if ((subcode & 0xff00) != VIRTIO_SUBCODE_64) @@ -343,18 +346,25 @@ static void kvm_extint_handler(u16 code) /* The LSB might be overloaded, we have to mask it */ vq = (struct virtqueue *)(S390_lowcore.ext_params2 & ~1UL); - /* We use the LSB of extparam, to decide, if this interrupt is a config - * change or a "standard" interrupt */ - config_changed = S390_lowcore.ext_params & 1; + /* We use ext_params to decide what this interrupt means */ + param = S390_lowcore.ext_params & VIRTIO_PARAM_MASK; - if (config_changed) { + switch (param) { + case VIRTIO_PARAM_CONFIG_CHANGED: + { struct virtio_driver *drv; drv = container_of(vq->vdev->dev.driver, struct virtio_driver, driver); if (drv->config_changed) drv->config_changed(vq->vdev); - } else + + break; + } + case VIRTIO_PARAM_VRING_INTERRUPT: + default: vring_interrupt(0, vq); + break; + } } /* -- 1.6.0.2
The one big missing feature in s390-virtio was hotplugging. This is no more. This patch implements hotplug add support, so you can on the fly add new devices in the guest. Keep in mind that this needs a patch for qemu to actually leverage the functionality. Signed-off-by: Alexander Graf <agraf at suse.de> --- drivers/s390/kvm/kvm_virtio.c | 48 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 48 insertions(+), 0 deletions(-) diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index ada7e2c..35383a3 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c @@ -30,11 +30,13 @@ #define VIRTIO_PARAM_MASK 0xff #define VIRTIO_PARAM_VRING_INTERRUPT 0x0 #define VIRTIO_PARAM_CONFIG_CHANGED 0x1 +#define VIRTIO_PARAM_DEV_ADD 0x2 /* * The pointer to our (page) of device descriptions. */ static void *kvm_devices; +struct work_struct hotplug_work; struct kvm_device { struct virtio_device vdev; @@ -331,6 +333,47 @@ static void scan_devices(void) } /* + * match for a kvm device with a specific desc pointer + */ +static int match_desc(struct device *dev, void *data) +{ + if ((ulong)to_kvmdev(dev_to_virtio(dev))->desc == (ulong)data) + return 1; + + return 0; +} + +/* + * hotplug_device tries to find changes in the device page. + */ +static void hotplug_devices(struct work_struct *dummy) +{ + unsigned int i; + struct kvm_device_desc *d; + struct device *dev; + + for (i = 0; i < PAGE_SIZE; i += desc_size(d)) { + d = kvm_devices + i; + + /* end of list */ + if (d->type == 0) + break; + + /* device already exists */ + dev = device_find_child(kvm_root, d, match_desc); + if (dev) { + /* XXX check for hotplug remove */ + put_device(dev); + continue; + } + + /* new device */ + printk(KERN_INFO "Adding new virtio device %p\n", d); + add_kvm_device(d, i); + } +} + +/* * we emulate the request_irq behaviour on top of s390 extints */ static void kvm_extint_handler(u16 code) @@ -360,6 +403,9 @@ static void kvm_extint_handler(u16 code) break; } + case VIRTIO_PARAM_DEV_ADD: + schedule_work(&hotplug_work); + break; case VIRTIO_PARAM_VRING_INTERRUPT: default: vring_interrupt(0, vq); @@ -393,6 +439,8 @@ static int __init kvm_devices_init(void) kvm_devices = (void *) real_memory_size; + INIT_WORK(&hotplug_work, hotplug_devices); + ctl_set_bit(0, 9); register_external_interrupt(0x2603, kvm_extint_handler); -- 1.6.0.2
Christian Borntraeger
2010-Aug-24 07:03 UTC
[PATCH 1/2] S390: take a full byte as ext_param indicator
Am 23.08.2010 23:31, schrieb Alexander Graf:> Currenty the ext_param field only distinguishes between "config change" and > "vring interrupt". We can do a lot more with it though, so let's enable a > full byte of possible values and constants to #defines while at it.Makes a lot of sense. [...]> #define VIRTIO_SUBCODE_64 0x0D00 > +#define VIRTIO_PARAM_MASK 0xff > +#define VIRTIO_PARAM_VRING_INTERRUPT 0x0 > +#define VIRTIO_PARAM_CONFIG_CHANGED 0x1Maybe this should be exported in a header, something like arch/s390/include/asm/kvm_virtio.h? In that case this file must be added to Kbuild for make headers_install. Christian
Christian Borntraeger
2010-Aug-24 07:13 UTC
[PATCH 2/2] S390: Add virtio hotplug add support
Am 23.08.2010 23:31, schrieb Alexander Graf:> The one big missing feature in s390-virtio was hotplugging. This is no more. > This patch implements hotplug add support, so you can on the fly add new devices > in the guest.Nice :-)> Keep in mind that this needs a patch for qemu to actually leverage the > functionality. > > Signed-off-by: Alexander Graf <agraf at suse.de>With the minor nits below fixed: Acked-by: Christian Borntraeger <borntraeger at de.ibm.com>> #define VIRTIO_PARAM_MASK 0xff > #define VIRTIO_PARAM_VRING_INTERRUPT 0x0 > #define VIRTIO_PARAM_CONFIG_CHANGED 0x1 > +#define VIRTIO_PARAM_DEV_ADD 0x2See the other patch. This becomes an interface and should go into a header file.> > /* > * The pointer to our (page) of device descriptions. > */ > static void *kvm_devices; > +struct work_struct hotplug_work; > > struct kvm_device { > struct virtio_device vdev; > @@ -331,6 +333,47 @@ static void scan_devices(void) > } > > /* > + * match for a kvm device with a specific desc pointer > + */ > +static int match_desc(struct device *dev, void *data) > +{ > + if ((ulong)to_kvmdev(dev_to_virtio(dev))->desc == (ulong)data)ulong doesnt look like kernel coding style.
Maybe Matching Threads
- [PATCH 1/2] S390: take a full byte as ext_param indicator
- [PATCH 1/3] S390: take a full byte as ext_param indicator
- [PATCH 1/3] S390: take a full byte as ext_param indicator
- [PATCH] drivers/s390/virtio: Remove the old KVM virtio transport
- [PATCH] drivers/s390/virtio: Remove the old KVM virtio transport