From 1f8051876a194d7f7fe7834d9853f240d6b4b9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Tue, 22 Jan 2013 09:51:20 +1030 Subject: [PATCH 1/8] virtio_console: Let unconnected rproc device receive data. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow rproc serial ports to receive data before the port is connected. Rproc serial ports usually talk to very simple remote devices with no control queue managing open/close events. So we must let remote devices write to the virtio ring even if the device is not yet fully initialized. Signed-off-by: Sjur Brændeland Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 684b0d53764f..95cae778bd73 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1763,8 +1763,11 @@ static void in_intr(struct virtqueue *vq) * tty is spawned) and the host sends out data to console * ports. For generic serial ports, the host won't * (shouldn't) send data till the guest is connected. + * However a remote device might send data before the port is + * connected. So don't remove data from a rproc_serial device. */ - if (!port->guest_connected) + + if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev)) discard_port_data(port); spin_unlock_irqrestore(&port->inbuf_lock, flags); From 0d34cc2d6d904e2d0160e42734bccc1cb391cec0 Mon Sep 17 00:00:00 2001 From: Ryota Ozaki Date: Mon, 4 Feb 2013 10:35:30 +1030 Subject: [PATCH 2/8] virtio-mmio: fix wrong comment about register offset The register offset of InterruptACK is 0x064, not 0x060. Fix it. Signed-off-by: Ryota Ozaki Reviewed-by: Wanlong Gao Acked-by: Pawel Moll CC: Jiri Kosina Signed-off-by: Rusty Russell --- drivers/virtio/virtio_mmio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 31f966f4d27f..833e6dbf38db 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -75,7 +75,7 @@ * * 0x050 W QueueNotify Queue notifier * 0x060 R InterruptStatus Interrupt status register - * 0x060 W InterruptACK Interrupt acknowledge register + * 0x064 W InterruptACK Interrupt acknowledge register * 0x070 RW Status Device status register * * 0x100+ RW Device-specific configuration space From 9350393239153c4a98cbed4d69b9ed81e37d5e74 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 10 Feb 2013 15:57:38 +1030 Subject: [PATCH 3/8] virtio: make config_ops const It is just a table of function pointers, make it const for cleanliness and security reasons. Signed-off-by: Stephen Hemminger Signed-off-by: Rusty Russell --- drivers/lguest/lguest_device.c | 2 +- drivers/remoteproc/remoteproc_virtio.c | 2 +- drivers/s390/kvm/kvm_virtio.c | 2 +- drivers/virtio/virtio_mmio.c | 2 +- drivers/virtio/virtio_pci.c | 2 +- include/linux/virtio.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index fc92ccbd71dc..b3256ff0d426 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c @@ -396,7 +396,7 @@ static const char *lg_bus_name(struct virtio_device *vdev) } /* The ops structure which hooks everything together. */ -static struct virtio_config_ops lguest_config_ops = { +static const struct virtio_config_ops lguest_config_ops = { .get_features = lg_get_features, .finalize_features = lg_finalize_features, .get = lg_get, diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index 9e198e590675..afed9b7731c4 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c @@ -222,7 +222,7 @@ static void rproc_virtio_finalize_features(struct virtio_device *vdev) rvdev->gfeatures = vdev->features[0]; } -static struct virtio_config_ops rproc_virtio_config_ops = { +static const struct virtio_config_ops rproc_virtio_config_ops = { .get_features = rproc_virtio_get_features, .finalize_features = rproc_virtio_finalize_features, .find_vqs = rproc_virtio_find_vqs, diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 8491111aec12..7d08fba7542d 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c @@ -275,7 +275,7 @@ static const char *kvm_bus_name(struct virtio_device *vdev) /* * The config ops structure as defined by virtio config */ -static struct virtio_config_ops kvm_vq_configspace_ops = { +static const struct virtio_config_ops kvm_vq_configspace_ops = { .get_features = kvm_get_features, .finalize_features = kvm_finalize_features, .get = kvm_get, diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 833e6dbf38db..1ba0d6831015 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -423,7 +423,7 @@ static const char *vm_bus_name(struct virtio_device *vdev) return vm_dev->pdev->name; } -static struct virtio_config_ops virtio_mmio_config_ops = { +static const struct virtio_config_ops virtio_mmio_config_ops = { .get = vm_get, .set = vm_set, .get_status = vm_get_status, diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 0c142892c105..52c5ce6aec8d 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -652,7 +652,7 @@ static int vp_set_vq_affinity(struct virtqueue *vq, int cpu) return 0; } -static struct virtio_config_ops virtio_pci_config_ops = { +static const struct virtio_config_ops virtio_pci_config_ops = { .get = vp_get, .set = vp_set, .get_status = vp_get_status, diff --git a/include/linux/virtio.h b/include/linux/virtio.h index cf8adb1f5b2c..eb34cf774473 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -78,7 +78,7 @@ struct virtio_device { int index; struct device dev; struct virtio_device_id id; - struct virtio_config_ops *config; + const struct virtio_config_ops *config; struct list_head vqs; /* Note that this is a Linux set_bit-style bitmap. */ unsigned long features[1]; From 35cdc9eb65837687bdfc9ea1d2515eb03ea5048a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 10 Feb 2013 15:57:39 +1030 Subject: [PATCH 4/8] virtio: make pci_device_id const Use DEVICE_TABLE macro which also makes table const. Signed-off-by: Stephen Hemminger Signed-off-by: Rusty Russell --- drivers/virtio/virtio_pci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 52c5ce6aec8d..a7ce73029f59 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -91,9 +91,9 @@ struct virtio_pci_vq_info }; /* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */ -static struct pci_device_id virtio_pci_id_table[] = { - { 0x1af4, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { 0 }, +static DEFINE_PCI_DEVICE_TABLE(virtio_pci_id_table) = { + { PCI_DEVICE(0x1af4, PCI_ANY_ID) }, + { 0 } }; MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); From dc18f0800f5f16460030a9623d4fcc165d607edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Tue, 12 Feb 2013 16:24:59 +1030 Subject: [PATCH 5/8] virtio_console: Use virtio device index to generate port name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use virtio device index for creating unique device port names. Current index allocation in virtio is based on a monotonically increasing variable "index". A better handling of this is to use device index which is allocated by ida. Signed-off-by: Sjur Brændeland Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 95cae778bd73..2cfd5a0575ab 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -61,9 +61,6 @@ struct ports_driver_data { /* List of all the devices we're handling */ struct list_head portdevs; - /* Number of devices this driver is handling */ - unsigned int index; - /* * This is used to keep track of the number of hvc consoles * spawned by this driver. This number is given as the first @@ -169,9 +166,6 @@ struct ports_device { /* Array of per-port IO virtqueues */ struct virtqueue **in_vqs, **out_vqs; - /* Used for numbering devices for sysfs and debugfs */ - unsigned int drv_index; - /* Major number for this device. Ports will be created as minors. */ int chr_major; }; @@ -1415,7 +1409,7 @@ static int add_port(struct ports_device *portdev, u32 id) } port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev, devt, port, "vport%up%u", - port->portdev->drv_index, id); + port->portdev->vdev->index, id); if (IS_ERR(port->dev)) { err = PTR_ERR(port->dev); dev_err(&port->portdev->vdev->dev, @@ -1470,7 +1464,7 @@ static int add_port(struct ports_device *portdev, u32 id) * inspect a port's state at any time */ sprintf(debugfs_name, "vport%up%u", - port->portdev->drv_index, id); + port->portdev->vdev->index, id); port->debugfs_file = debugfs_create_file(debugfs_name, 0444, pdrvdata.debugfs_dir, port, @@ -1961,16 +1955,12 @@ static int virtcons_probe(struct virtio_device *vdev) portdev->vdev = vdev; vdev->priv = portdev; - spin_lock_irq(&pdrvdata_lock); - portdev->drv_index = pdrvdata.index++; - spin_unlock_irq(&pdrvdata_lock); - portdev->chr_major = register_chrdev(0, "virtio-portsdev", &portdev_fops); if (portdev->chr_major < 0) { dev_err(&vdev->dev, "Error %d registering chrdev for device %u\n", - portdev->chr_major, portdev->drv_index); + portdev->chr_major, vdev->index); err = portdev->chr_major; goto free; } From 6e105e0593055dc4aae21df7bca3868045754148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Wed, 13 Feb 2013 15:52:36 +1030 Subject: [PATCH 6/8] virtio: Add module driver macro for virtio drivers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add helper macro for drivers that don't do anything special in module init/exit. Signed-off-by: Sjur Brændeland Signed-off-by: Rusty Russell --- include/linux/virtio.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/linux/virtio.h b/include/linux/virtio.h index eb34cf774473..ff6714e6d0f5 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -126,4 +126,13 @@ static inline struct virtio_driver *drv_to_virtio(struct device_driver *drv) int register_virtio_driver(struct virtio_driver *drv); void unregister_virtio_driver(struct virtio_driver *drv); + +/* module_virtio_driver() - Helper macro for drivers that don't do + * anything special in module init/exit. This eliminates a lot of + * boilerplate. Each module may only use this macro once, and + * calling it replaces module_init() and module_exit() + */ +#define module_virtio_driver(__virtio_driver) \ + module_driver(__virtio_driver, register_virtio_driver, \ + unregister_virtio_driver) #endif /* _LINUX_VIRTIO_H */ From b2a17029c29bb6f7dec580feffa715b9fcf51e42 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Feb 2013 16:59:28 +1030 Subject: [PATCH 7/8] virtio: use module_virtio_driver. Signed-off-by: Rusty Russell --- drivers/char/hw_random/virtio-rng.c | 13 +------------ drivers/net/virtio_net.c | 12 +----------- drivers/virtio/virtio_balloon.c | 13 +------------ 3 files changed, 3 insertions(+), 35 deletions(-) diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index b65c10395959..10fd71ccf587 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -154,18 +154,7 @@ static struct virtio_driver virtio_rng_driver = { #endif }; -static int __init init(void) -{ - return register_virtio_driver(&virtio_rng_driver); -} - -static void __exit fini(void) -{ - unregister_virtio_driver(&virtio_rng_driver); -} -module_init(init); -module_exit(fini); - +module_virtio_driver(virtio_rng_driver); MODULE_DEVICE_TABLE(virtio, id_table); MODULE_DESCRIPTION("Virtio random number driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index a6fcf15adc4f..80fb683d9d3a 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1645,17 +1645,7 @@ static struct virtio_driver virtio_net_driver = { #endif }; -static int __init init(void) -{ - return register_virtio_driver(&virtio_net_driver); -} - -static void __exit fini(void) -{ - unregister_virtio_driver(&virtio_net_driver); -} -module_init(init); -module_exit(fini); +module_virtio_driver(virtio_net_driver); MODULE_DEVICE_TABLE(virtio, id_table); MODULE_DESCRIPTION("Virtio network driver"); diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 797e1c79a104..8dab163c5ef0 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -560,18 +560,7 @@ static struct virtio_driver virtio_balloon_driver = { #endif }; -static int __init init(void) -{ - return register_virtio_driver(&virtio_balloon_driver); -} - -static void __exit fini(void) -{ - unregister_virtio_driver(&virtio_balloon_driver); -} -module_init(init); -module_exit(fini); - +module_virtio_driver(virtio_balloon_driver); MODULE_DEVICE_TABLE(virtio, id_table); MODULE_DESCRIPTION("Virtio balloon driver"); MODULE_LICENSE("GPL"); From 8078db789a92b10ff6e2d713231b5367e014c53b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Wed, 13 Feb 2013 20:57:21 +1030 Subject: [PATCH 8/8] virtio_console: Initialize guest_connected=true for rproc_serial MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When rproc_serial is initialized, guest_connected should be set to true. We can then revert the extra checks introduced in commit: "virtio_console: Let unconnected rproc device receive data." Signed-off-by: Sjur Brændeland Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 2cfd5a0575ab..5afc8f614b1c 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1436,7 +1436,7 @@ static int add_port(struct ports_device *portdev, u32 id) * rproc_serial does not want the console port, only * the generic port implementation. */ - port->host_connected = true; + port->host_connected = port->guest_connected = true; else if (!use_multiport(port->portdev)) { /* * If we're not using multiport support, @@ -1757,11 +1757,8 @@ static void in_intr(struct virtqueue *vq) * tty is spawned) and the host sends out data to console * ports. For generic serial ports, the host won't * (shouldn't) send data till the guest is connected. - * However a remote device might send data before the port is - * connected. So don't remove data from a rproc_serial device. */ - - if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev)) + if (!port->guest_connected) discard_port_data(port); spin_unlock_irqrestore(&port->inbuf_lock, flags);