diff --git a/.cvsignore b/.cvsignore index 19c10ab..2c30915 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,3 +1 @@ -qemu-kvm-0.12.1.2.tar.gz -qemu-kvm-0.12.2.tar.gz -qemu-kvm-0.12.3.tar.gz +qemu-kvm-0.13.0-b81fe95.tar.gz diff --git a/0038-msix-migration-fix.patch b/0038-msix-migration-fix.patch deleted file mode 100644 index b7d2c08..0000000 --- a/0038-msix-migration-fix.patch +++ /dev/null @@ -1,43 +0,0 @@ -From af483cb870ad81dce8e10215e0add284fcc38da4 Mon Sep 17 00:00:00 2001 -From: Michael S. Tsirkin -Date: Wed, 24 Feb 2010 21:09:45 +0200 -Subject: [PATCH] msix: migration fix - -Be careful to match mask/unmask callbacks from msix. -Fixes crash during migration. - -Signed-off-by: Michael S. Tsirkin ---- - hw/msix.c | 16 +++++++++++++--- - 1 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/hw/msix.c b/hw/msix.c -index 3fcf3a1..fafaf09 100644 ---- a/hw/msix.c -+++ b/hw/msix.c -@@ -614,9 +614,19 @@ int msix_set_mask_notifier(PCIDevice *dev, unsigned vector, void *opaque) - if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) - return 0; - -- if (dev->msix_mask_notifier) -- r = dev->msix_mask_notifier(dev, vector, opaque, -- msix_is_masked(dev, vector)); -+ if (dev->msix_mask_notifier && !msix_is_masked(dev, vector)) { -+ /* Mask previous notifier if any */ -+ if (dev->msix_mask_notifier_opaque[vector]) { -+ r = dev->msix_mask_notifier(dev, vector, -+ dev->msix_mask_notifier_opaque[vector], -+ 1); -+ assert(r >= 0); -+ } -+ /* Unmask new notifier, assumed to be masked at start */ -+ if (opaque) { -+ r = dev->msix_mask_notifier(dev, vector, opaque, 0); -+ } -+ } - if (r >= 0) - dev->msix_mask_notifier_opaque[vector] = opaque; - return r; --- -1.6.6.1 - diff --git a/0039-vhost-logging-thinko-fix.patch b/0039-vhost-logging-thinko-fix.patch deleted file mode 100644 index 9f0435a..0000000 --- a/0039-vhost-logging-thinko-fix.patch +++ /dev/null @@ -1,28 +0,0 @@ -From c96adfe57a5a7ceed488fd6f198a762dd84c1d9c Mon Sep 17 00:00:00 2001 -From: Michael S. Tsirkin -Date: Wed, 24 Feb 2010 21:09:48 +0200 -Subject: [PATCH] vhost: logging thinko fix - -Fix logging: set it to requested value. - -Signed-off-by: Michael S. Tsirkin ---- - hw/vhost.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/hw/vhost.c b/hw/vhost.c -index e5c1ead..3c54596 100644 ---- a/hw/vhost.c -+++ b/hw/vhost.c -@@ -310,7 +310,7 @@ static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log) - { - uint64_t features = dev->acked_features; - int r; -- if (dev->log_enabled) { -+ if (enable_log) { - features |= 0x1 << VHOST_F_LOG_ALL; - } - r = ioctl(dev->control, VHOST_SET_FEATURES, &features); --- -1.6.6.1 - diff --git a/0040-vhost-move-vhost_set_vq_addr.patch b/0040-vhost-move-vhost_set_vq_addr.patch deleted file mode 100644 index e63119a..0000000 --- a/0040-vhost-move-vhost_set_vq_addr.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 575c00a2880177295a116d43132566143af69a0b Mon Sep 17 00:00:00 2001 -From: Michael S. Tsirkin -Date: Wed, 24 Feb 2010 21:09:51 +0200 -Subject: [PATCH] vhost: move vhost_set_vq_addr - -Move function in file: we'll add another -call site in the following patch. - -Signed-off-by: Michael S. Tsirkin ---- - hw/vhost.c | 38 +++++++++++++++++++------------------- - 1 files changed, 19 insertions(+), 19 deletions(-) - -diff --git a/hw/vhost.c b/hw/vhost.c -index 3c54596..54386e1 100644 ---- a/hw/vhost.c -+++ b/hw/vhost.c -@@ -306,6 +306,25 @@ static void vhost_client_set_memory(CPUPhysMemoryClient *client, - } - } - -+static int vhost_virtqueue_set_addr(struct vhost_dev *dev, -+ struct vhost_virtqueue *vq, -+ unsigned idx, bool enable_log) -+{ -+ struct vhost_vring_addr addr = { -+ .index = idx, -+ .desc_user_addr = (u_int64_t)(unsigned long)vq->desc, -+ .avail_user_addr = (u_int64_t)(unsigned long)vq->avail, -+ .used_user_addr = (u_int64_t)(unsigned long)vq->used, -+ .log_guest_addr = vq->used_phys, -+ .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0, -+ }; -+ int r = ioctl(dev->control, VHOST_SET_VRING_ADDR, &addr); -+ if (r < 0) { -+ return -errno; -+ } -+ return 0; -+} -+ - static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log) - { - uint64_t features = dev->acked_features; -@@ -350,25 +369,6 @@ static int vhost_client_migration_log(struct CPUPhysMemoryClient *client, - return 0; - } - --static int vhost_virtqueue_set_addr(struct vhost_dev *dev, -- struct vhost_virtqueue *vq, -- unsigned idx, bool enable_log) --{ -- struct vhost_vring_addr addr = { -- .index = idx, -- .desc_user_addr = (u_int64_t)(unsigned long)vq->desc, -- .avail_user_addr = (u_int64_t)(unsigned long)vq->avail, -- .used_user_addr = (u_int64_t)(unsigned long)vq->used, -- .log_guest_addr = vq->used_phys, -- .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0, -- }; -- int r = ioctl(dev->control, VHOST_SET_VRING_ADDR, &addr); -- if (r < 0) { -- return -errno; -- } -- return 0; --} -- - static int vhost_virtqueue_init(struct vhost_dev *dev, - struct VirtIODevice *vdev, - struct vhost_virtqueue *vq, --- -1.6.6.1 - diff --git a/0041-vhost-used-addr-migration-fix.patch b/0041-vhost-used-addr-migration-fix.patch deleted file mode 100644 index 90f027a..0000000 --- a/0041-vhost-used-addr-migration-fix.patch +++ /dev/null @@ -1,70 +0,0 @@ -From ac48d782f3b91b2e9962ded5f8a55bd3929a82a5 Mon Sep 17 00:00:00 2001 -From: Michael S. Tsirkin -Date: Wed, 24 Feb 2010 21:09:54 +0200 -Subject: [PATCH] vhost: used addr migration fix - -Enable used buffer logging when migration starts. -Fixed 'id XX is not a head' message after migration. - -Signed-off-by: Michael S. Tsirkin ---- - hw/vhost.c | 29 +++++++++++++++++++++++++++-- - 1 files changed, 27 insertions(+), 2 deletions(-) - -diff --git a/hw/vhost.c b/hw/vhost.c -index 54386e1..48034ba 100644 ---- a/hw/vhost.c -+++ b/hw/vhost.c -@@ -325,7 +325,7 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev, - return 0; - } - --static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log) -+static int vhost_dev_set_features(struct vhost_dev *dev, bool enable_log) - { - uint64_t features = dev->acked_features; - int r; -@@ -336,6 +336,31 @@ static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log) - return r < 0 ? -errno : 0; - } - -+static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log) -+{ -+ int r, t, i; -+ r = vhost_dev_set_features(dev, enable_log); -+ if (r < 0) -+ goto err_features; -+ for (i = 0; i < dev->nvqs; ++i) { -+ r = vhost_virtqueue_set_addr(dev, dev->vqs + i, i, -+ enable_log); -+ if (r < 0) -+ goto err_vq; -+ } -+ return 0; -+err_vq: -+ for (; i >= 0; --i) { -+ t = vhost_virtqueue_set_addr(dev, dev->vqs + i, i, -+ dev->log_enabled); -+ assert(t >= 0); -+ } -+ t = vhost_dev_set_features(dev, dev->log_enabled); -+ assert(t >= 0); -+err_features: -+ return r; -+} -+ - static int vhost_client_migration_log(struct CPUPhysMemoryClient *client, - int enable) - { -@@ -544,7 +569,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) - { - int i, r; - -- r = vhost_dev_set_log(hdev, hdev->log_enabled); -+ r = vhost_dev_set_features(hdev, hdev->log_enabled); - if (r < 0) - goto fail; - r = ioctl(hdev->control, VHOST_SET_MEM_TABLE, hdev->mem); --- -1.6.6.1 - diff --git a/0042-vhost-fix-used-logging-size-math.patch b/0042-vhost-fix-used-logging-size-math.patch deleted file mode 100644 index a17058c..0000000 --- a/0042-vhost-fix-used-logging-size-math.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 91c827f000a94908b043b5de68eb0cd4fb6ff83d Mon Sep 17 00:00:00 2001 -From: Michael S. Tsirkin -Date: Wed, 24 Feb 2010 21:09:58 +0200 -Subject: [PATCH] vhost: fix used logging size math - -Must include used header as well, not only ring - -Signed-off-by: Michael S. Tsirkin ---- - hw/vhost.c | 4 +++- - 1 files changed, 3 insertions(+), 1 deletions(-) - -diff --git a/hw/vhost.c b/hw/vhost.c -index 48034ba..7391bd1 100644 ---- a/hw/vhost.c -+++ b/hw/vhost.c -@@ -62,7 +62,8 @@ static int vhost_client_sync_dirty_bitmap(struct CPUPhysMemoryClient *client, - } - for (i = 0; i < dev->nvqs; ++i) { - struct vhost_virtqueue *vq = dev->vqs + i; -- unsigned size = sizeof(struct vring_used_elem) * vq->num; -+ unsigned size = offsetof(struct vring_used, ring) + -+ sizeof(struct vring_used_elem) * vq->num; - vhost_dev_sync_region(dev, start_addr, end_addr, vq->used_phys, - range_get_last(vq->used_phys, size)); - } -@@ -230,6 +231,7 @@ static uint64_t vhost_get_log_size(struct vhost_dev *dev) - for (i = 0; i < dev->nvqs; ++i) { - struct vhost_virtqueue *vq = dev->vqs + i; - uint64_t last = vq->used_phys + -+ offsetof(struct vring_used, ring) + - sizeof(struct vring_used_elem) * vq->num - 1; - log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1); - } --- -1.6.6.1 - diff --git a/0043-vhost-logging-mistake-enable-not-disable-log.patch b/0043-vhost-logging-mistake-enable-not-disable-log.patch deleted file mode 100644 index 58889da..0000000 --- a/0043-vhost-logging-mistake-enable-not-disable-log.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b4654f7911adb1352c2c47c76f650e8419a20b91 Mon Sep 17 00:00:00 2001 -From: Michael S. Tsirkin -Date: Wed, 24 Feb 2010 21:10:01 +0200 -Subject: [PATCH] vhost: logging mistake enable, not disable log - -Correctly pass log enable value from memory client to vhost device. ---- - hw/vhost.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/hw/vhost.c b/hw/vhost.c -index 7391bd1..019afc2 100644 ---- a/hw/vhost.c -+++ b/hw/vhost.c -@@ -387,7 +387,7 @@ static int vhost_client_migration_log(struct CPUPhysMemoryClient *client, - dev->log_size = 0; - } else { - vhost_dev_log_resize(dev, vhost_get_log_size(dev)); -- r = vhost_dev_set_log(dev, false); -+ r = vhost_dev_set_log(dev, true); - if (r < 0) { - return r; - } --- -1.6.6.1 - diff --git a/0044-vhost-fix-log-base.patch b/0044-vhost-fix-log-base.patch deleted file mode 100644 index 1e97d89..0000000 --- a/0044-vhost-fix-log-base.patch +++ /dev/null @@ -1,38 +0,0 @@ -From d42430f94c77a653da486e6f96f6695818f3e81b Mon Sep 17 00:00:00 2001 -From: Michael S. Tsirkin -Date: Wed, 24 Feb 2010 21:10:04 +0200 -Subject: [PATCH] vhost: fix log base - -LOG_BASE ioctl gets a pointer to a 64 bit value, not -a pointer cast to 64 bit value. - -Signed-off-by: Michael S. Tsirkin ---- - hw/vhost.c | 5 +++-- - 1 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/hw/vhost.c b/hw/vhost.c -index 019afc2..b63eafa 100644 ---- a/hw/vhost.c -+++ b/hw/vhost.c -@@ -241,14 +241,15 @@ static uint64_t vhost_get_log_size(struct vhost_dev *dev) - static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size) - { - vhost_log_chunk_t *log; -+ uint64_t log_base; - int r; - if (size) { - log = qemu_mallocz(size * sizeof *log); - } else { - log = NULL; - } -- r = ioctl(dev->control, VHOST_SET_LOG_BASE, -- (uint64_t)(unsigned long)log); -+ log_base = (uint64_t)(unsigned long)log; -+ r = ioctl(dev->control, VHOST_SET_LOG_BASE, &log_base); - assert(r >= 0); - vhost_client_sync_dirty_bitmap(&dev->client, 0, - (target_phys_addr_t)~0x0ull); --- -1.6.6.1 - diff --git a/0045-pc-Add-a-Fedora-13-machine-type-that-contains-backpo.patch b/0045-pc-Add-a-Fedora-13-machine-type-that-contains-backpo.patch deleted file mode 100644 index d7d5c27..0000000 --- a/0045-pc-Add-a-Fedora-13-machine-type-that-contains-backpo.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 9aa404a57823c9fbf2bf2e0189d31a2b0d8bf3b9 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Thu, 25 Feb 2010 18:41:13 +0530 -Subject: [PATCH] pc: Add a Fedora-13 machine type that contains backports from upstream - -We have a few features backported from the upstream 0.13 machine type -in the repo here. - -Add a 'fedora-13' machine type and use that by default so that users can -fall back to a released upstream machine type if desired. - -The fedora-13 machine type has the new multiport-supported virtio-serial -and vhost-net patches as of now not present in the 0.12 machine type. - -This is based on upstream commit -d76fa62dba54a156ca0f5e79eb33756c9015e02c - -Signed-off-by: Amit Shah ---- - hw/pc.c | 19 +++++++++++++++++-- - 1 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/hw/pc.c b/hw/pc.c -index 56be728..26c65c1 100644 ---- a/hw/pc.c -+++ b/hw/pc.c -@@ -1327,11 +1327,9 @@ void cmos_set_s3_resume(void) - - static QEMUMachine pc_machine = { - .name = "pc-0.12", -- .alias = "pc", - .desc = "Standard PC", - .init = pc_init_pci, - .max_cpus = 255, -- .is_default = 1, - }; - - static QEMUMachine pc_machine_v0_11 = { -@@ -1416,3 +1414,20 @@ static void pc_machine_init(void) - } - - machine_init(pc_machine_init); -+ -+/* Fedora machine types */ -+static QEMUMachine pc_machine_f13 = { -+ .name = "fedora-13", -+ .alias = "pc", -+ .desc = "Standard PC", -+ .init = pc_init_pci, -+ .max_cpus = 255, -+ .is_default = 1, -+}; -+ -+static void fedora_machine_init(void) -+{ -+ qemu_register_machine(&pc_machine_f13); -+} -+ -+machine_init(fedora_machine_init); --- -1.6.6.1 - diff --git a/0046-pc-Add-backward-compatibility-options-for-virtio-ser.patch b/0046-pc-Add-backward-compatibility-options-for-virtio-ser.patch deleted file mode 100644 index 2c6c8fd..0000000 --- a/0046-pc-Add-backward-compatibility-options-for-virtio-ser.patch +++ /dev/null @@ -1,72 +0,0 @@ -From f32e21e2828cf7a8aba2fb27945dc46ca2debe09 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Thu, 25 Feb 2010 18:41:14 +0530 -Subject: [PATCH] pc: Add backward compatibility options for virtio-serial - -virtio-serial-pci can support multiple ports in the current F-13 -version that will become upstream version 0.13. Add compatibility options -for the 0.12, 0.11 and 0.10 pc machine types. - -Based on upstream commit 8bfbde6d35c82cc376681289dae2de5e18a087a4 - -Signed-off-by: Amit Shah ---- - hw/pc.c | 28 ++++++++++++++++++++++++++++ - 1 files changed, 28 insertions(+), 0 deletions(-) - -diff --git a/hw/pc.c b/hw/pc.c -index 26c65c1..90bbfe8 100644 ---- a/hw/pc.c -+++ b/hw/pc.c -@@ -1330,6 +1330,18 @@ static QEMUMachine pc_machine = { - .desc = "Standard PC", - .init = pc_init_pci, - .max_cpus = 255, -+ .compat_props = (GlobalProperty[]) { -+ { -+ .driver = "virtio-serial-pci", -+ .property = "max_nr_ports", -+ .value = stringify(1), -+ },{ -+ .driver = "virtio-serial-pci", -+ .property = "vectors", -+ .value = stringify(0), -+ }, -+ { /* end of list */ } -+ } - }; - - static QEMUMachine pc_machine_v0_11 = { -@@ -1351,6 +1363,14 @@ static QEMUMachine pc_machine_v0_11 = { - .property = "ver", - .value = "0.11", - },{ -+ .driver = "virtio-serial-pci", -+ .property = "max_nr_ports", -+ .value = stringify(1), -+ },{ -+ .driver = "virtio-serial-pci", -+ .property = "vectors", -+ .value = stringify(0), -+ },{ - .driver = "PCI", - .property = "rombar", - .value = stringify(0), -@@ -1374,6 +1394,14 @@ static QEMUMachine pc_machine_v0_10 = { - .property = "class", - .value = stringify(PCI_CLASS_DISPLAY_OTHER), - },{ -+ .driver = "virtio-serial-pci", -+ .property = "max_nr_ports", -+ .value = stringify(1), -+ },{ -+ .driver = "virtio-serial-pci", -+ .property = "vectors", -+ .value = stringify(0), -+ },{ - .driver = "virtio-net-pci", - .property = "vectors", - .value = stringify(0), --- -1.6.6.1 - diff --git a/0047-virtio-serial-don-t-set-MULTIPORT-for-1-port-dev.patch b/0047-virtio-serial-don-t-set-MULTIPORT-for-1-port-dev.patch deleted file mode 100644 index 997898d..0000000 --- a/0047-virtio-serial-don-t-set-MULTIPORT-for-1-port-dev.patch +++ /dev/null @@ -1,39 +0,0 @@ -From e3b132568eef8491decbe30639a9814bdd2d82c0 Mon Sep 17 00:00:00 2001 -From: Michael S. Tsirkin -Date: Thu, 25 Feb 2010 18:41:15 +0530 -Subject: [PATCH] virtio-serial: don't set MULTIPORT for 1 port dev - -Since commit 98b19252cf1bd97c54bc4613f3537c5ec0aae263, all -serial devices declare MULTIPORT feature. -To allow 0.12 compatibility, we should clear this when -max_nr_ports is 1. - -Upsream commit: ee4d45be0d791eb8bb0f767cd0f17ea8f697281b - -Signed-off-by: Michael S. Tsirkin -Signed-off-by: Amit Shah -Signed-off-by: Anthony Liguori ---- - hw/virtio-serial-bus.c | 6 ++++-- - 1 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c -index ab456ea..d0e0219 100644 ---- a/hw/virtio-serial-bus.c -+++ b/hw/virtio-serial-bus.c -@@ -335,8 +335,10 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq) - - static uint32_t get_features(VirtIODevice *vdev, uint32_t features) - { -- features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT); -- -+ VirtIOSerial *vser = DO_UPCAST(VirtIOSerial, vdev, vdev); -+ if (vser->bus->max_nr_ports > 1) { -+ features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT); -+ } - return features; - } - --- -1.6.6.1 - diff --git a/0048-virtio-serial-pci-Allow-MSI-to-be-disabled.patch b/0048-virtio-serial-pci-Allow-MSI-to-be-disabled.patch deleted file mode 100644 index 387ab87..0000000 --- a/0048-virtio-serial-pci-Allow-MSI-to-be-disabled.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 8a881734bccddf707a42ba2effff699b824d3c8f Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Thu, 25 Feb 2010 18:41:16 +0530 -Subject: [PATCH] virtio-serial: pci: Allow MSI to be disabled - -Michael noted we don't allow disabling of MSI for the virtio-serial-pci -device. Fix that. - -Upstream commit: 7b665b668aa92bf0bba696f085dff87539d95529 - -Signed-off-by: Amit Shah -CC: "Michael S. Tsirkin" -Signed-off-by: Anthony Liguori ---- - hw/virtio-pci.c | 6 +++--- - 1 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c -index 9a02682..636c8c3 100644 ---- a/hw/virtio-pci.c -+++ b/hw/virtio-pci.c -@@ -598,8 +598,8 @@ static int virtio_serial_init_pci(PCIDevice *pci_dev) - if (!vdev) { - return -1; - } -- vdev->nvectors = proxy->nvectors ? proxy->nvectors -- : proxy->max_virtserial_ports + 1; -+ vdev->nvectors = proxy->nvectors == -1 ? proxy->max_virtserial_ports + 1 -+ : proxy->nvectors; - virtio_init_pci(proxy, vdev, - PCI_VENDOR_ID_REDHAT_QUMRANET, - PCI_DEVICE_ID_VIRTIO_CONSOLE, -@@ -683,7 +683,7 @@ static PCIDeviceInfo virtio_info[] = { - .init = virtio_serial_init_pci, - .exit = virtio_exit_pci, - .qdev.props = (Property[]) { -- DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 0), -+ DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, -1), - DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), - DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, max_virtserial_ports, --- -1.6.6.1 - diff --git a/0049-migration-Clear-fd-also-in-error-cases.patch b/0049-migration-Clear-fd-also-in-error-cases.patch deleted file mode 100644 index 22a88da..0000000 --- a/0049-migration-Clear-fd-also-in-error-cases.patch +++ /dev/null @@ -1,100 +0,0 @@ -From a0591dc91ad795ffb47476b37730e46977a6be36 Mon Sep 17 00:00:00 2001 -From: Juan Quintela -Date: Tue, 9 Mar 2010 23:58:50 +0100 -Subject: [PATCH] migration: Clear fd also in error cases - -Not clearing the fd and closing the file makes qemu spin using 100%CPU -after incoming migration error. - -See for instance bug: -https://bugzilla.redhat.com/show_bug.cgi?id=518032 - -Signed-off-by: Juan Quintela ---- - migration-exec.c | 3 +-- - migration-fd.c | 3 +-- - migration-tcp.c | 5 ++--- - migration-unix.c | 5 ++--- - 4 files changed, 6 insertions(+), 10 deletions(-) - -diff --git a/migration-exec.c b/migration-exec.c -index 87f645b..e57a55d 100644 ---- a/migration-exec.c -+++ b/migration-exec.c -@@ -120,12 +120,11 @@ static void exec_accept_incoming_migration(void *opaque) - } - qemu_announce_self(); - dprintf("successfully loaded vm state\n"); -- /* we've successfully migrated, close the fd */ -- qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL); - if (autostart) - vm_start(); - - err: -+ qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL); - qemu_fclose(f); - } - -diff --git a/migration-fd.c b/migration-fd.c -index ef7edbc..7325d13 100644 ---- a/migration-fd.c -+++ b/migration-fd.c -@@ -113,12 +113,11 @@ static void fd_accept_incoming_migration(void *opaque) - } - qemu_announce_self(); - dprintf("successfully loaded vm state\n"); -- /* we've successfully migrated, close the fd */ -- qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL); - if (autostart) - vm_start(); - - err: -+ qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL); - qemu_fclose(f); - } - -diff --git a/migration-tcp.c b/migration-tcp.c -index 2cfa8cb..c328e73 100644 ---- a/migration-tcp.c -+++ b/migration-tcp.c -@@ -170,15 +170,14 @@ static void tcp_accept_incoming_migration(void *opaque) - qemu_announce_self(); - dprintf("successfully loaded vm state\n"); - -- /* we've successfully migrated, close the server socket */ -- qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); -- close(s); - if (autostart) - vm_start(); - - out_fopen: - qemu_fclose(f); - out: -+ qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); -+ close(s); - close(c); - } - -diff --git a/migration-unix.c b/migration-unix.c -index a141dbb..9685c4b 100644 ---- a/migration-unix.c -+++ b/migration-unix.c -@@ -176,13 +176,12 @@ static void unix_accept_incoming_migration(void *opaque) - qemu_announce_self(); - dprintf("successfully loaded vm state\n"); - -- /* we've successfully migrated, close the server socket */ -- qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); -- close(s); - - out_fopen: - qemu_fclose(f); - out: -+ qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); -+ close(s); - close(c); - } - --- -1.6.6.1 - diff --git a/0050-raw-posix-Detect-CDROM-via-ioctl-on-linux.patch b/0050-raw-posix-Detect-CDROM-via-ioctl-on-linux.patch deleted file mode 100644 index 72f245a..0000000 --- a/0050-raw-posix-Detect-CDROM-via-ioctl-on-linux.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 361f29d46ce4a310818e88adaef0912573847295 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Thu, 14 Jan 2010 16:19:40 +0000 -Subject: [PATCH] raw-posix: Detect CDROM via ioctl on linux - -Current CDROM detection is hardcoded based on source file name. -Make this smarter on linux by attempting a CDROM specific ioctl. - -This makes '-cdrom /dev/sr0' succeed with no media present. - -v2: - Give ioctl check higher priority than filename check. - -v3: - Actually initialize 'prio' variable. - Check for ioctl success rather than absence of specific failure. - -v4: - Explicitly mention that change is linux specific. - -Signed-off-by: Cole Robinson -Signed-off-by: Anthony Liguori ---- - block/raw-posix.c | 20 ++++++++++++++++++-- - 1 files changed, 18 insertions(+), 2 deletions(-) - -diff --git a/block/raw-posix.c b/block/raw-posix.c -index c204cf9..1c777a1 100644 ---- a/block/raw-posix.c -+++ b/block/raw-posix.c -@@ -1142,9 +1142,25 @@ static int cdrom_open(BlockDriverState *bs, const char *filename, int flags) - - static int cdrom_probe_device(const char *filename) - { -+ int fd, ret; -+ int prio = 0; -+ - if (strstart(filename, "/dev/cd", NULL)) -- return 100; -- return 0; -+ prio = 50; -+ -+ fd = open(filename, O_RDONLY | O_NONBLOCK); -+ if (fd < 0) { -+ goto out; -+ } -+ -+ /* Attempt to detect via a CDROM specific ioctl */ -+ ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); -+ if (ret >= 0) -+ prio = 100; -+ -+ close(fd); -+out: -+ return prio; - } - - static int cdrom_is_inserted(BlockDriverState *bs) --- -1.6.6.1 - diff --git a/0051-usb-linux-increase-buffer-for-USB-control-requests.patch b/0051-usb-linux-increase-buffer-for-USB-control-requests.patch deleted file mode 100644 index 225e0f4..0000000 --- a/0051-usb-linux-increase-buffer-for-USB-control-requests.patch +++ /dev/null @@ -1,33 +0,0 @@ -From afba60f63354fc6376e30dd51cadeda7170bcf4b Mon Sep 17 00:00:00 2001 -From: Christian Krause -Date: Sun, 24 Jan 2010 16:34:52 +0000 -Subject: [PATCH] usb-linux: increase buffer for USB control requests - -The WLAN USB stick ZyXEL NWD271N (0586:3417) uses very large -usb control transfers of more than 2048 bytes which won't fit -into the buffer of the ctrl_struct. This results in an error message -"husb: ctrl buffer too small" and a non-working device. -Increasing the buffer size to 8192 seems to be a safe choice. - -Signed-off-by: Christian Krause -Signed-off-by: Aurelien Jarno ---- - usb-linux.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/usb-linux.c b/usb-linux.c -index 5619b30..e6cd432 100644 ---- a/usb-linux.c -+++ b/usb-linux.c -@@ -113,7 +113,7 @@ struct ctrl_struct { - uint16_t offset; - uint8_t state; - struct usb_ctrlrequest req; -- uint8_t buffer[2048]; -+ uint8_t buffer[8192]; - }; - - struct USBAutoFilter { --- -1.6.6.1 - diff --git a/0052-virtio-console-patches.patch b/0052-virtio-console-patches.patch deleted file mode 100644 index c8570d9..0000000 --- a/0052-virtio-console-patches.patch +++ /dev/null @@ -1,936 +0,0 @@ -From 8fe39316da28bdff610da708148f87b21e7ba045 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Tue, 6 Apr 2010 23:36:50 +0530 -Subject: [PATCH] virtio-console patches - -Hey Justin, - -Attached are the kernel and qemu patches for the new abi. Rusty is ok -with the kernel patches and Juan and Gerd are ok with the userspace -ones. - -The kernel one is big because of some code movement. - -The qemu one is big because of code being moved and some fixes being -applied to make the host less vulnerable to malicious guests. - -There's also a patch at - -http://lkml.org/lkml/2010/4/6/110 - -that we should apply (affects the virt-console-fix-race.patch in the -repo). - -Please let me know if you need any more information! - -Thanks, - Amit - -Content-Disposition: attachment; filename=",qemu-virtio-serial-rollup-2.patch" ---- - Makefile.hw | 1 + - hw/iov.c | 70 ++++++++++ - hw/iov.h | 19 +++ - hw/virtio-balloon.c | 31 +---- - hw/virtio-console.c | 11 +- - hw/virtio-net.c | 20 +--- - hw/virtio-serial-bus.c | 332 ++++++++++++++++++++++++++++++++++++------------ - hw/virtio-serial.h | 34 ++++-- - 8 files changed, 372 insertions(+), 146 deletions(-) - create mode 100644 hw/iov.c - create mode 100644 hw/iov.h - -diff --git a/Makefile.hw b/Makefile.hw -index 43ca541..079c5d2 100644 ---- a/Makefile.hw -+++ b/Makefile.hw -@@ -13,6 +13,7 @@ QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu - - obj-y = - obj-y += loader.o -+obj-y += iov.o - obj-y += virtio.o virtio-console.o - obj-y += fw_cfg.o - obj-y += watchdog.o -diff --git a/hw/iov.c b/hw/iov.c -new file mode 100644 -index 0000000..588cd04 ---- /dev/null -+++ b/hw/iov.c -@@ -0,0 +1,70 @@ -+/* -+ * Helpers for getting linearized buffers from iov / filling buffers into iovs -+ * -+ * Copyright IBM, Corp. 2007, 2008 -+ * Copyright (C) 2010 Red Hat, Inc. -+ * -+ * Author(s): -+ * Anthony Liguori -+ * Amit Shah -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2. See -+ * the COPYING file in the top-level directory. -+ */ -+ -+#include "iov.h" -+ -+size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt, -+ const void *buf, size_t size) -+{ -+ size_t offset; -+ unsigned int i; -+ -+ offset = 0; -+ for (i = 0; offset < size && i < iovcnt; i++) { -+ size_t len; -+ -+ len = MIN(iov[i].iov_len, size - offset); -+ -+ memcpy(iov[i].iov_base, buf + offset, len); -+ offset += len; -+ } -+ return offset; -+} -+ -+size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt, -+ void *buf, size_t offset, size_t size) -+{ -+ uint8_t *ptr; -+ size_t iov_off, buf_off; -+ unsigned int i; -+ -+ ptr = buf; -+ iov_off = 0; -+ buf_off = 0; -+ for (i = 0; i < iovcnt && size; i++) { -+ if (offset < (iov_off + iov[i].iov_len)) { -+ size_t len = MIN((iov_off + iov[i].iov_len) - offset , size); -+ -+ memcpy(ptr + buf_off, iov[i].iov_base + (offset - iov_off), len); -+ -+ buf_off += len; -+ offset += len; -+ size -= len; -+ } -+ iov_off += iov[i].iov_len; -+ } -+ return buf_off; -+} -+ -+size_t iov_size(const struct iovec *iov, const unsigned int iovcnt) -+{ -+ size_t len; -+ unsigned int i; -+ -+ len = 0; -+ for (i = 0; i < iovcnt; i++) { -+ len += iov[i].iov_len; -+ } -+ return len; -+} -diff --git a/hw/iov.h b/hw/iov.h -new file mode 100644 -index 0000000..60a8547 ---- /dev/null -+++ b/hw/iov.h -@@ -0,0 +1,19 @@ -+/* -+ * Helpers for getting linearized buffers from iov / filling buffers into iovs -+ * -+ * Copyright (C) 2010 Red Hat, Inc. -+ * -+ * Author(s): -+ * Amit Shah -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2. See -+ * the COPYING file in the top-level directory. -+ */ -+ -+#include "qemu-common.h" -+ -+size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt, -+ const void *buf, size_t size); -+size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt, -+ void *buf, size_t offset, size_t size); -+size_t iov_size(const struct iovec *iov, const unsigned int iovcnt); -diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c -index 242c6c8..10e2647 100644 ---- a/hw/virtio-balloon.c -+++ b/hw/virtio-balloon.c -@@ -11,6 +11,7 @@ - * - */ - -+#include "iov.h" - #include "qemu-common.h" - #include "virtio.h" - #include "pc.h" -@@ -47,33 +48,6 @@ static void balloon_page(void *addr, int deflate) - #endif - } - --/* FIXME: once we do a virtio refactoring, this will get subsumed into common -- * code */ --static size_t memcpy_from_iovector(void *data, size_t offset, size_t size, -- struct iovec *iov, int iovlen) --{ -- int i; -- uint8_t *ptr = data; -- size_t iov_off = 0; -- size_t data_off = 0; -- -- for (i = 0; i < iovlen && size; i++) { -- if (offset < (iov_off + iov[i].iov_len)) { -- size_t len = MIN((iov_off + iov[i].iov_len) - offset , size); -- -- memcpy(ptr + data_off, iov[i].iov_base + (offset - iov_off), len); -- -- data_off += len; -- offset += len; -- size -= len; -- } -- -- iov_off += iov[i].iov_len; -- } -- -- return data_off; --} -- - static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) - { - VirtIOBalloon *s = to_virtio_balloon(vdev); -@@ -83,8 +57,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) - size_t offset = 0; - uint32_t pfn; - -- while (memcpy_from_iovector(&pfn, offset, 4, -- elem.out_sg, elem.out_num) == 4) { -+ while (iov_to_buf(elem.out_sg, elem.out_num, &pfn, offset, 4) == 4) { - ram_addr_t pa; - ram_addr_t addr; - -diff --git a/hw/virtio-console.c b/hw/virtio-console.c -index bd44ec6..caea11f 100644 ---- a/hw/virtio-console.c -+++ b/hw/virtio-console.c -@@ -1,7 +1,7 @@ - /* - * Virtio Console and Generic Serial Port Devices - * -- * Copyright Red Hat, Inc. 2009 -+ * Copyright Red Hat, Inc. 2009, 2010 - * - * Authors: - * Amit Shah -@@ -20,14 +20,11 @@ typedef struct VirtConsole { - - - /* Callback function that's called when the guest sends us data */ --static size_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) -+static void flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) - { - VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -- ssize_t ret; - -- ret = qemu_chr_write(vcon->chr, buf, len); -- -- return ret < 0 ? 0 : ret; -+ qemu_chr_write(vcon->chr, buf, len); - } - - /* Readiness of the guest to accept data on a port */ -@@ -99,6 +96,7 @@ static VirtIOSerialPortInfo virtconsole_info = { - .exit = virtconsole_exitfn, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT8("is_console", VirtConsole, port.is_console, 1), -+ DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID), - DEFINE_PROP_CHR("chardev", VirtConsole, chr), - DEFINE_PROP_STRING("name", VirtConsole, port.name), - DEFINE_PROP_END_OF_LIST(), -@@ -133,6 +131,7 @@ static VirtIOSerialPortInfo virtserialport_info = { - .init = virtserialport_initfn, - .exit = virtconsole_exitfn, - .qdev.props = (Property[]) { -+ DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID), - DEFINE_PROP_CHR("chardev", VirtConsole, chr), - DEFINE_PROP_STRING("name", VirtConsole, port.name), - DEFINE_PROP_END_OF_LIST(), -diff --git a/hw/virtio-net.c b/hw/virtio-net.c -index f8e228f..320e99f 100644 ---- a/hw/virtio-net.c -+++ b/hw/virtio-net.c -@@ -11,6 +11,7 @@ - * - */ - -+#include "iov.h" - #include "virtio.h" - #include "net.h" - #include "net/checksum.h" -@@ -436,21 +437,6 @@ static void work_around_broken_dhclient(struct virtio_net_hdr *hdr, - } - } - --static int iov_fill(struct iovec *iov, int iovcnt, const void *buf, int count) --{ -- int offset, i; -- -- offset = i = 0; -- while (offset < count && i < iovcnt) { -- int len = MIN(iov[i].iov_len, count - offset); -- memcpy(iov[i].iov_base, buf + offset, len); -- offset += len; -- i++; -- } -- -- return offset; --} -- - static int receive_header(VirtIONet *n, struct iovec *iov, int iovcnt, - const void *buf, size_t size, size_t hdr_len) - { -@@ -586,8 +572,8 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ - } - - /* copy in packet. ugh */ -- len = iov_fill(sg, elem.in_num, -- buf + offset, size - offset); -+ len = iov_from_buf(sg, elem.in_num, -+ buf + offset, size - offset); - total += len; - - /* signal other side */ -diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c -index d0e0219..6245f6e 100644 ---- a/hw/virtio-serial-bus.c -+++ b/hw/virtio-serial-bus.c -@@ -1,7 +1,7 @@ - /* - * A bus for connecting virtio serial and console ports - * -- * Copyright (C) 2009 Red Hat, Inc. -+ * Copyright (C) 2009, 2010 Red Hat, Inc. - * - * Author(s): - * Amit Shah -@@ -15,6 +15,7 @@ - * the COPYING file in the top-level directory. - */ - -+#include "iov.h" - #include "monitor.h" - #include "qemu-queue.h" - #include "sysbus.h" -@@ -41,6 +42,10 @@ struct VirtIOSerial { - VirtIOSerialBus *bus; - - QTAILQ_HEAD(, VirtIOSerialPort) ports; -+ -+ /* bitmap for identifying active ports */ -+ uint32_t *ports_map; -+ - struct virtio_console_config config; - }; - -@@ -48,6 +53,10 @@ static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id) - { - VirtIOSerialPort *port; - -+ if (id == VIRTIO_CONSOLE_BAD_ID) { -+ return NULL; -+ } -+ - QTAILQ_FOREACH(port, &vser->ports, next) { - if (port->id == id) - return port; -@@ -76,30 +85,25 @@ static size_t write_to_port(VirtIOSerialPort *port, - { - VirtQueueElement elem; - VirtQueue *vq; -- size_t offset = 0; -- size_t len = 0; -+ size_t offset; - - vq = port->ivq; - if (!virtio_queue_ready(vq)) { - return 0; - } -- if (!size) { -- return 0; -- } - -+ offset = 0; - while (offset < size) { -- int i; -+ size_t len; - - if (!virtqueue_pop(vq, &elem)) { - break; - } - -- for (i = 0; offset < size && i < elem.in_num; i++) { -- len = MIN(elem.in_sg[i].iov_len, size - offset); -+ len = iov_from_buf(elem.in_sg, elem.in_num, -+ buf + offset, size - offset); -+ offset += len; - -- memcpy(elem.in_sg[i].iov_base, buf + offset, len); -- offset += len; -- } - virtqueue_push(vq, &elem, len); - } - -@@ -107,6 +111,29 @@ static size_t write_to_port(VirtIOSerialPort *port, - return offset; - } - -+static void flush_queued_data(VirtIOSerialPort *port, bool discard) -+{ -+ VirtQueue *vq; -+ VirtQueueElement elem; -+ -+ vq = port->ovq; -+ while (virtqueue_pop(vq, &elem)) { -+ uint8_t *buf; -+ size_t ret, buf_size; -+ -+ if (!discard) { -+ buf_size = iov_size(elem.out_sg, elem.out_num); -+ buf = qemu_malloc(buf_size); -+ ret = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, buf_size); -+ -+ port->info->have_data(port, buf, ret); -+ qemu_free(buf); -+ } -+ virtqueue_push(vq, &elem, 0); -+ } -+ virtio_notify(&port->vser->vdev, vq); -+} -+ - static size_t send_control_msg(VirtIOSerialPort *port, void *buf, size_t len) - { - VirtQueueElement elem; -@@ -158,6 +185,13 @@ int virtio_serial_open(VirtIOSerialPort *port) - int virtio_serial_close(VirtIOSerialPort *port) - { - port->host_connected = false; -+ /* -+ * If there's any data the guest sent which the app didn't -+ * consume, discard it and reset the throttling flag. -+ */ -+ flush_queued_data(port, true); -+ port->throttled = false; -+ - send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 0); - - return 0; -@@ -199,8 +233,23 @@ size_t virtio_serial_guest_ready(VirtIOSerialPort *port) - return 0; - } - -+void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle) -+{ -+ if (!port) { -+ return; -+ } -+ -+ if (throttle) { -+ port->throttled = true; -+ return; -+ } -+ -+ port->throttled = false; -+ flush_queued_data(port, false); -+} -+ - /* Guest wants to notify us of some event */ --static void handle_control_message(VirtIOSerial *vser, void *buf) -+static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) - { - struct VirtIOSerialPort *port; - struct virtio_console_control cpkt, *gcpkt; -@@ -208,15 +257,41 @@ static void handle_control_message(VirtIOSerial *vser, void *buf) - size_t buffer_len; - - gcpkt = buf; -- port = find_port_by_id(vser, ldl_p(&gcpkt->id)); -- if (!port) -+ -+ if (len < sizeof(cpkt)) { -+ /* The guest sent an invalid control packet */ - return; -+ } - - cpkt.event = lduw_p(&gcpkt->event); - cpkt.value = lduw_p(&gcpkt->value); - -+ port = find_port_by_id(vser, ldl_p(&gcpkt->id)); -+ if (!port && cpkt.event != VIRTIO_CONSOLE_DEVICE_READY) -+ return; -+ - switch(cpkt.event) { -+ case VIRTIO_CONSOLE_DEVICE_READY: -+ if (!cpkt.value) { -+ qemu_error("virtio-serial-bus: Guest failure in adding device %s\n", -+ vser->bus->qbus.name); -+ break; -+ } -+ /* -+ * The device is up, we can now tell the device about all the -+ * ports we have here. -+ */ -+ QTAILQ_FOREACH(port, &vser->ports, next) { -+ send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1); -+ } -+ break; -+ - case VIRTIO_CONSOLE_PORT_READY: -+ if (!cpkt.value) { -+ qemu_error("virtio-serial-bus: Guest failure in adding port %u for device %s\n", -+ port->id, vser->bus->qbus.name); -+ break; -+ } - /* - * Now that we know the guest asked for the port name, we're - * sure the guest has initialised whatever state is necessary -@@ -281,12 +356,35 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq) - { - VirtQueueElement elem; - VirtIOSerial *vser; -+ uint8_t *buf; -+ size_t len; - - vser = DO_UPCAST(VirtIOSerial, vdev, vdev); - -+ len = 0; -+ buf = NULL; - while (virtqueue_pop(vq, &elem)) { -- handle_control_message(vser, elem.out_sg[0].iov_base); -- virtqueue_push(vq, &elem, elem.out_sg[0].iov_len); -+ size_t cur_len, copied; -+ -+ cur_len = iov_size(elem.out_sg, elem.out_num); -+ /* -+ * Allocate a new buf only if we didn't have one previously or -+ * if the size of the buf differs -+ */ -+ if (cur_len > len) { -+ if (len) { -+ qemu_free(buf); -+ } -+ buf = qemu_malloc(cur_len); -+ len = cur_len; -+ } -+ copied = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, len); -+ -+ handle_control_message(vser, buf, copied); -+ virtqueue_push(vq, &elem, 0); -+ } -+ if (len) { -+ qemu_free(buf); - } - virtio_notify(vdev, vq); - } -@@ -295,38 +393,22 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq) - static void handle_output(VirtIODevice *vdev, VirtQueue *vq) - { - VirtIOSerial *vser; -- VirtQueueElement elem; -+ VirtIOSerialPort *port; -+ bool discard; - - vser = DO_UPCAST(VirtIOSerial, vdev, vdev); -+ port = find_port_by_vq(vser, vq); - -- while (virtqueue_pop(vq, &elem)) { -- VirtIOSerialPort *port; -- size_t ret; -- -- port = find_port_by_vq(vser, vq); -- if (!port) { -- ret = 0; -- goto next_buf; -- } -- -- /* -- * A port may not have any handler registered for consuming the -- * data that the guest sends or it may not have a chardev associated -- * with it. Just ignore the data in that case. -- */ -- if (!port->info->have_data) { -- ret = 0; -- goto next_buf; -- } -- -- /* The guest always sends only one sg */ -- ret = port->info->have_data(port, elem.out_sg[0].iov_base, -- elem.out_sg[0].iov_len); -+ discard = false; -+ if (!port || !port->host_connected || !port->info->have_data) { -+ discard = true; -+ } - -- next_buf: -- virtqueue_push(vq, &elem, ret); -+ if (!discard && port->throttled) { -+ return; - } -- virtio_notify(vdev, vq); -+ -+ flush_queued_data(port, discard); - } - - static void handle_input(VirtIODevice *vdev, VirtQueue *vq) -@@ -335,7 +417,10 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq) - - static uint32_t get_features(VirtIODevice *vdev, uint32_t features) - { -- VirtIOSerial *vser = DO_UPCAST(VirtIOSerial, vdev, vdev); -+ VirtIOSerial *vser; -+ -+ vser = DO_UPCAST(VirtIOSerial, vdev, vdev); -+ - if (vser->bus->max_nr_ports > 1) { - features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT); - } -@@ -370,14 +455,20 @@ static void virtio_serial_save(QEMUFile *f, void *opaque) - /* The config space */ - qemu_put_be16s(f, &s->config.cols); - qemu_put_be16s(f, &s->config.rows); -- qemu_put_be32s(f, &s->config.nr_ports); - -- /* Items in struct VirtIOSerial */ -+ qemu_put_be32s(f, &s->config.max_nr_ports); -+ -+ /* The ports map */ -+ -+ qemu_put_buffer(f, (uint8_t *)s->ports_map, -+ sizeof(uint32_t) * (s->config.max_nr_ports + 31) / 32); -+ -+ /* Ports */ - -- /* Do this because we might have hot-unplugged some ports */ - nr_active_ports = 0; -- QTAILQ_FOREACH(port, &s->ports, next) -+ QTAILQ_FOREACH(port, &s->ports, next) { - nr_active_ports++; -+ } - - qemu_put_be32s(f, &nr_active_ports); - -@@ -385,13 +476,9 @@ static void virtio_serial_save(QEMUFile *f, void *opaque) - * Items in struct VirtIOSerialPort. - */ - QTAILQ_FOREACH(port, &s->ports, next) { -- /* -- * We put the port number because we may not have an active -- * port at id 0 that's reserved for a console port, or in case -- * of ports that might have gotten unplugged -- */ - qemu_put_be32s(f, &port->id); - qemu_put_byte(f, port->guest_connected); -+ qemu_put_byte(f, port->host_connected); - } - } - -@@ -399,7 +486,8 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) - { - VirtIOSerial *s = opaque; - VirtIOSerialPort *port; -- uint32_t nr_active_ports; -+ size_t ports_map_size; -+ uint32_t max_nr_ports, nr_active_ports, *ports_map; - unsigned int i; - - if (version_id > 2) { -@@ -416,22 +504,50 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) - /* The config space */ - qemu_get_be16s(f, &s->config.cols); - qemu_get_be16s(f, &s->config.rows); -- s->config.nr_ports = qemu_get_be32(f); - -- /* Items in struct VirtIOSerial */ -+ qemu_get_be32s(f, &max_nr_ports); -+ if (max_nr_ports > s->config.max_nr_ports) { -+ /* Source could have had more ports than us. Fail migration. */ -+ return -EINVAL; -+ } -+ -+ ports_map_size = sizeof(uint32_t) * (max_nr_ports + 31) / 32; -+ ports_map = qemu_malloc(ports_map_size); -+ qemu_get_buffer(f, (uint8_t *)ports_map, ports_map_size); -+ -+ for (i = 0; i < (max_nr_ports + 31) / 32; i++) { -+ if (ports_map[i] != s->ports_map[i]) { -+ /* -+ * Ports active on source and destination don't -+ * match. Fail migration. -+ */ -+ qemu_free(ports_map); -+ return -EINVAL; -+ } -+ } -+ qemu_free(ports_map); - - qemu_get_be32s(f, &nr_active_ports); - - /* Items in struct VirtIOSerialPort */ - for (i = 0; i < nr_active_ports; i++) { - uint32_t id; -+ bool host_connected; - - id = qemu_get_be32(f); - port = find_port_by_id(s, id); - - port->guest_connected = qemu_get_byte(f); -+ host_connected = qemu_get_byte(f); -+ if (host_connected != port->host_connected) { -+ /* -+ * We have to let the guest know of the host connection -+ * status change -+ */ -+ send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, -+ port->host_connected); -+ } - } -- - return 0; - } - -@@ -466,6 +582,54 @@ static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent) - indent, "", port->host_connected); - } - -+/* This function is only used if a port id is not provided by the user */ -+static uint32_t find_free_port_id(VirtIOSerial *vser) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < (vser->config.max_nr_ports + 31) / 32; i++) { -+ uint32_t map, bit; -+ -+ map = vser->ports_map[i]; -+ bit = ffs(~map); -+ if (bit) { -+ return (bit - 1) + i * 32; -+ } -+ } -+ return VIRTIO_CONSOLE_BAD_ID; -+} -+ -+static void mark_port_added(VirtIOSerial *vser, uint32_t port_id) -+{ -+ unsigned int i; -+ -+ i = port_id / 32; -+ vser->ports_map[i] |= 1U << (port_id % 32); -+} -+ -+static void add_port(VirtIOSerial *vser, uint32_t port_id) -+{ -+ mark_port_added(vser, port_id); -+ -+ send_control_event(find_port_by_id(vser, port_id), -+ VIRTIO_CONSOLE_PORT_ADD, 1); -+} -+ -+static void remove_port(VirtIOSerial *vser, uint32_t port_id) -+{ -+ VirtIOSerialPort *port; -+ unsigned int i; -+ -+ i = port_id / 32; -+ vser->ports_map[i] &= ~(1U << (port_id % 32)); -+ -+ port = find_port_by_id(vser, port_id); -+ /* Flush out any unconsumed buffers first */ -+ flush_queued_data(port, true); -+ -+ send_control_event(port, VIRTIO_CONSOLE_PORT_REMOVE, 1); -+} -+ - static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) - { - VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev); -@@ -484,19 +648,36 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) - */ - plugging_port0 = port->is_console && !find_port_by_id(port->vser, 0); - -- if (port->vser->config.nr_ports == bus->max_nr_ports && !plugging_port0) { -- qemu_error("virtio-serial-bus: Maximum device limit reached\n"); -+ if (find_port_by_id(port->vser, port->id)) { -+ qemu_error("virtio-serial-bus: A port already exists at id %u\n", -+ port->id); - return -1; - } -- dev->info = info; - -+ if (port->id == VIRTIO_CONSOLE_BAD_ID) { -+ if (plugging_port0) { -+ port->id = 0; -+ } else { -+ port->id = find_free_port_id(port->vser); -+ if (port->id == VIRTIO_CONSOLE_BAD_ID) { -+ qemu_error("virtio-serial-bus: Maximum port limit for this device reached\n"); -+ return -1; -+ } -+ } -+ } -+ -+ if (port->id >= port->vser->config.max_nr_ports) { -+ qemu_error("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u\n", -+ port->vser->config.max_nr_ports - 1); -+ return -1; -+ } -+ -+ dev->info = info; - ret = info->init(dev); - if (ret) { - return ret; - } - -- port->id = plugging_port0 ? 0 : port->vser->config.nr_ports++; -- - if (!use_multiport(port->vser)) { - /* - * Allow writes to guest in this case; we have no way of -@@ -509,6 +690,8 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) - port->ivq = port->vser->ivqs[port->id]; - port->ovq = port->vser->ovqs[port->id]; - -+ add_port(port->vser, port->id); -+ - /* Send an update to the guest about this new port added */ - virtio_notify_config(&port->vser->vdev); - -@@ -521,26 +704,8 @@ static int virtser_port_qdev_exit(DeviceState *qdev) - VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); - VirtIOSerial *vser = port->vser; - -- send_control_event(port, VIRTIO_CONSOLE_PORT_REMOVE, 1); -+ remove_port(port->vser, port->id); - -- /* -- * Don't decrement nr_ports here; thus we keep a linearly -- * increasing port id. Not utilising an id again saves us a couple -- * of complications: -- * -- * - Not having to bother about sending the port id to the guest -- * kernel on hotplug or on addition of new ports; the guest can -- * also linearly increment the port number. This is preferable -- * because the config space won't have the need to store a -- * ports_map. -- * -- * - Extra state to be stored for all the "holes" that got created -- * so that we keep filling in the ids from the least available -- * index. -- * -- * When such a functionality is desired, a control message to add -- * a port can be introduced. -- */ - QTAILQ_REMOVE(&vser->ports, port, next); - - if (port->info->exit) -@@ -600,11 +765,12 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports) - } - - vser->config.max_nr_ports = max_nr_ports; -+ vser->ports_map = qemu_mallocz((max_nr_ports + 31) / 32); - /* - * Reserve location 0 for a console port for backward compat - * (old kernel, new qemu) - */ -- vser->config.nr_ports = 1; -+ mark_port_added(vser, 0); - - vser->vdev.get_features = get_features; - vser->vdev.get_config = get_config; -diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h -index f297b00..a93b545 100644 ---- a/hw/virtio-serial.h -+++ b/hw/virtio-serial.h -@@ -2,7 +2,7 @@ - * Virtio Serial / Console Support - * - * Copyright IBM, Corp. 2008 -- * Copyright Red Hat, Inc. 2009 -+ * Copyright Red Hat, Inc. 2009, 2010 - * - * Authors: - * Christian Ehrhardt -@@ -27,6 +27,8 @@ - /* Features supported */ - #define VIRTIO_CONSOLE_F_MULTIPORT 1 - -+#define VIRTIO_CONSOLE_BAD_ID (~(uint32_t)0) -+ - struct virtio_console_config { - /* - * These two fields are used by VIRTIO_CONSOLE_F_SIZE which -@@ -36,7 +38,6 @@ struct virtio_console_config { - uint16_t rows; - - uint32_t max_nr_ports; -- uint32_t nr_ports; - } __attribute__((packed)); - - struct virtio_console_control { -@@ -46,12 +47,14 @@ struct virtio_console_control { - }; - - /* Some events for the internal messages (control packets) */ --#define VIRTIO_CONSOLE_PORT_READY 0 --#define VIRTIO_CONSOLE_CONSOLE_PORT 1 --#define VIRTIO_CONSOLE_RESIZE 2 --#define VIRTIO_CONSOLE_PORT_OPEN 3 --#define VIRTIO_CONSOLE_PORT_NAME 4 --#define VIRTIO_CONSOLE_PORT_REMOVE 5 -+#define VIRTIO_CONSOLE_DEVICE_READY 0 -+#define VIRTIO_CONSOLE_PORT_ADD 1 -+#define VIRTIO_CONSOLE_PORT_REMOVE 2 -+#define VIRTIO_CONSOLE_PORT_READY 3 -+#define VIRTIO_CONSOLE_CONSOLE_PORT 4 -+#define VIRTIO_CONSOLE_RESIZE 5 -+#define VIRTIO_CONSOLE_PORT_OPEN 6 -+#define VIRTIO_CONSOLE_PORT_NAME 7 - - /* == In-qemu interface == */ - -@@ -107,6 +110,8 @@ struct VirtIOSerialPort { - bool guest_connected; - /* Is this device open for IO on the host? */ - bool host_connected; -+ /* Do apps not want to receive data? */ -+ bool throttled; - }; - - struct VirtIOSerialPortInfo { -@@ -133,10 +138,10 @@ struct VirtIOSerialPortInfo { - - /* - * Guest wrote some data to the port. This data is handed over to -- * the app via this callback. The app should return the number of -- * bytes it successfully consumed. -+ * the app via this callback. The app is supposed to consume all -+ * the data that is presented to it. - */ -- size_t (*have_data)(VirtIOSerialPort *port, const uint8_t *buf, size_t len); -+ void (*have_data)(VirtIOSerialPort *port, const uint8_t *buf, size_t len); - }; - - /* Interface to the virtio-serial bus */ -@@ -170,4 +175,11 @@ ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf, - */ - size_t virtio_serial_guest_ready(VirtIOSerialPort *port); - -+/* -+ * Flow control: Ports can signal to the virtio-serial core to stop -+ * sending data or re-start sending data, depending on the 'throttle' -+ * value here. -+ */ -+void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle); -+ - #endif --- -1.6.6.1 - diff --git a/0053-net-remove-NICInfo.bootable-field.patch b/0053-net-remove-NICInfo.bootable-field.patch deleted file mode 100644 index 02c110b..0000000 --- a/0053-net-remove-NICInfo.bootable-field.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 30397a024f57f14800975bbb4312be54cc75202b Mon Sep 17 00:00:00 2001 -From: Eduardo Habkost -Date: Tue, 6 Apr 2010 19:38:51 -0300 -Subject: [PATCH] net: remove NICInfo.bootable field - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=561078 - -It is just set by net_set_boot_mask() and never used. The logic for rom loading -changed a lot since this field was introduced. It is not needed anymore. - -Signed-off-by: Eduardo Habkost ---- - net.c | 1 - - net.h | 1 - - 2 files changed, 0 insertions(+), 2 deletions(-) - -diff --git a/net.c b/net.c -index de7d626..5cebb1a 100644 ---- a/net.c -+++ b/net.c -@@ -1204,7 +1204,6 @@ void net_set_boot_mask(int net_boot_mask) - - for (i = 0; i < nb_nics; i++) { - if (net_boot_mask & (1 << i)) { -- nd_table[i].bootable = 1; - net_boot_mask &= ~(1 << i); - } - } -diff --git a/net.h b/net.h -index 33a1eaf..5b6e814 100644 ---- a/net.h -+++ b/net.h -@@ -135,7 +135,6 @@ struct NICInfo { - VLANState *vlan; - VLANClientState *netdev; - int used; -- int bootable; - int nvectors; - }; - --- -1.6.6.1 - diff --git a/0054-net-remove-broken-net_set_boot_mask-boot-device-vali.patch b/0054-net-remove-broken-net_set_boot_mask-boot-device-vali.patch deleted file mode 100644 index 09b5ee3..0000000 --- a/0054-net-remove-broken-net_set_boot_mask-boot-device-vali.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 905a4bcaf9d4ed3662b901a2820b6e6ca80dc285 Mon Sep 17 00:00:00 2001 -From: Eduardo Habkost -Date: Tue, 6 Apr 2010 19:38:52 -0300 -Subject: [PATCH] net: remove broken net_set_boot_mask() boot device validation - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=561078 - -There are many problems with net_set_boot_mask(): - -1) It is broken when using the device model instead of "-net nic". Example: - $ qemu-system-x86_64 -device rtl8139,vlan=0,id=net0,mac=52:54:00:82:41:fd,bus=pci.0,addr=0x4 -net user,vlan=0,name=hostnet0 -vnc 0.0.0.0:0 -boot n - Cannot boot from non-existent NIC - $ -2) The mask was previously used to set which boot ROMs were supposed to be - loaded, but this was changed long time ago. Now all ROM images are loaded, - and SeaBIOS takes care of jumping to the right boot entry point depending on - the boot settings. -3) Interpretation and validation of the boot parameter letters is done on - the machine type code. Examples: PC accepts only a,b,c,d,n as valid boot - device letters. mac99 accepts only a,b,c,d,e,f. - -As a side-effect of this change, qemu-kvm won't abort anymore if using "-boot n" -on a machine with no network devices. Checking if the requested boot device is -valid is now a task for the BIOS or the machine-type code. - -Signed-off-by: Eduardo Habkost ---- - net.c | 19 ------------------- - net.h | 1 - - vl.c | 5 +---- - 3 files changed, 1 insertions(+), 24 deletions(-) - -diff --git a/net.c b/net.c -index 5cebb1a..71c0f08 100644 ---- a/net.c -+++ b/net.c -@@ -1195,25 +1195,6 @@ void net_host_device_remove(Monitor *mon, const QDict *qdict) - qemu_del_vlan_client(vc); - } - --void net_set_boot_mask(int net_boot_mask) --{ -- int i; -- -- /* Only the first four NICs may be bootable */ -- net_boot_mask = net_boot_mask & 0xF; -- -- for (i = 0; i < nb_nics; i++) { -- if (net_boot_mask & (1 << i)) { -- net_boot_mask &= ~(1 << i); -- } -- } -- -- if (net_boot_mask) { -- fprintf(stderr, "Cannot boot from non-existent NIC\n"); -- exit(1); -- } --} -- - void do_info_network(Monitor *mon) - { - VLANState *vlan; -diff --git a/net.h b/net.h -index 5b6e814..2b2ee4c 100644 ---- a/net.h -+++ b/net.h -@@ -165,7 +165,6 @@ int net_client_parse(QemuOptsList *opts_list, const char *str); - int net_init_clients(void); - void net_check_clients(void); - void net_cleanup(void); --void net_set_boot_mask(int boot_mask); - void net_host_device_add(Monitor *mon, const QDict *qdict); - void net_host_device_remove(Monitor *mon, const QDict *qdict); - -diff --git a/vl.c b/vl.c -index c75f891..349f945 100644 ---- a/vl.c -+++ b/vl.c -@@ -4922,7 +4922,7 @@ int main(int argc, char **argv, char **envp) - const char *gdbstub_dev = NULL; - uint32_t boot_devices_bitmap = 0; - int i; -- int snapshot, linux_boot, net_boot; -+ int snapshot, linux_boot; - const char *initrd_filename; - const char *kernel_filename, *kernel_cmdline; - char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */ -@@ -5961,9 +5961,6 @@ int main(int argc, char **argv, char **envp) - exit(1); - } - -- net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF; -- net_set_boot_mask(net_boot); -- - /* init the bluetooth world */ - if (foreach_device_config(DEV_BT, bt_parse)) - exit(1); --- -1.6.6.1 - diff --git a/0055-boot-remove-unused-boot_devices_bitmap-variable.patch b/0055-boot-remove-unused-boot_devices_bitmap-variable.patch deleted file mode 100644 index e84aa13..0000000 --- a/0055-boot-remove-unused-boot_devices_bitmap-variable.patch +++ /dev/null @@ -1,63 +0,0 @@ -From dfbaa3059414b158ff7ce7a74ffff80b0fa2db9c Mon Sep 17 00:00:00 2001 -From: Eduardo Habkost -Date: Tue, 6 Apr 2010 19:38:53 -0300 -Subject: [PATCH] boot: remove unused boot_devices_bitmap variable - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=561078 - -In addition to removing the variable, this also renames the parse_bootdevices() -function to validate_bootdevices(), as we don't need its return value anymore. - -Signed-off-by: Eduardo Habkost ---- - vl.c | 8 +++----- - 1 files changed, 3 insertions(+), 5 deletions(-) - -diff --git a/vl.c b/vl.c -index 349f945..a71127c 100644 ---- a/vl.c -+++ b/vl.c -@@ -2517,7 +2517,7 @@ int qemu_boot_set(const char *boot_devices) - return boot_set_handler(boot_set_opaque, boot_devices); - } - --static int parse_bootdevices(char *devices) -+static void validate_bootdevices(char *devices) - { - /* We just do some generic consistency checks */ - const char *p; -@@ -2543,7 +2543,6 @@ static int parse_bootdevices(char *devices) - } - bitmap |= 1 << (*p - 'a'); - } -- return bitmap; - } - - static void restore_boot_devices(void *opaque) -@@ -4920,7 +4919,6 @@ static int virtcon_parse(const char *devname) - int main(int argc, char **argv, char **envp) - { - const char *gdbstub_dev = NULL; -- uint32_t boot_devices_bitmap = 0; - int i; - int snapshot, linux_boot; - const char *initrd_filename; -@@ -5215,13 +5213,13 @@ int main(int argc, char **argv, char **envp) - - if (legacy || - get_param_value(buf, sizeof(buf), "order", optarg)) { -- boot_devices_bitmap = parse_bootdevices(buf); -+ validate_bootdevices(buf); - pstrcpy(boot_devices, sizeof(boot_devices), buf); - } - if (!legacy) { - if (get_param_value(buf, sizeof(buf), - "once", optarg)) { -- boot_devices_bitmap |= parse_bootdevices(buf); -+ validate_bootdevices(buf); - standard_boot_devices = qemu_strdup(boot_devices); - pstrcpy(boot_devices, sizeof(boot_devices), buf); - qemu_register_reset(restore_boot_devices, --- -1.6.6.1 - diff --git a/ksm.init b/ksm.init index 0603243..8561993 100644 --- a/ksm.init +++ b/ksm.init @@ -40,15 +40,12 @@ default_max_kernel_pages () { start() { echo -n $"Starting $prog: " - if [ -f /sys/kernel/mm/ksm/max_kernel_pages ]; then - KSM_MAX_KERNEL_PAGES=${KSM_MAX_KERNEL_PAGES:-`default_max_kernel_pages`} - echo $KSM_MAX_KERNEL_PAGES > /sys/kernel/mm/ksm/max_kernel_pages - fi + KSM_MAX_KERNEL_PAGES=${KSM_MAX_KERNEL_PAGES:-`default_max_kernel_pages`} + echo $KSM_MAX_KERNEL_PAGES > /sys/kernel/mm/ksm/max_kernel_pages echo 1 > /sys/kernel/mm/ksm/run RETVAL=$? [ $RETVAL = 0 ] && success $"$prog startup" || failure $"$prog startup" echo - return $RETVAL } stop() { @@ -72,6 +69,11 @@ status() { fi; fi } +restart() { + stop + start +} + case "$1" in start) start @@ -83,14 +85,18 @@ case "$1" in status ;; restart) - stop - start + restart ;; - condrestart) + condrestart|try-restart) + status >/dev/null 2>&1 || exit 0 + restart ;; + force-reload) + restart + ;; *) - echo $"Usage: $prog {start|stop|restart|condrestart|status|help}" - RETVAL=3 + echo $"Usage: $prog {start|stop|restart|force-reload|condrestart|try-restart|status|help}" + RETVAL=2 esac exit $RETVAL diff --git a/ksmtuned b/ksmtuned index 205ff84..4e0414f 100644 --- a/ksmtuned +++ b/ksmtuned @@ -76,7 +76,7 @@ committed_memory () { } free_memory () { - awk '/^(MemFree|Buffers|MemCached):/ {free += $2}; END {print free}' \ + awk '/^(MemFree|Buffers|Cached):/ {free += $2}; END {print free}' \ /proc/meminfo } diff --git a/ksmtuned.init b/ksmtuned.init index 2f32f28..e055785 100644 --- a/ksmtuned.init +++ b/ksmtuned.init @@ -70,10 +70,10 @@ case "$1" in status -p ${pidfile} $prog RETVAL=$? ;; - restart) + restart|force-reload) restart ;; - condrestart) + condrestart|try-restart) condrestart ;; retune) @@ -81,8 +81,8 @@ case "$1" in RETVAL=$? ;; *) - echo $"Usage: $prog {start|stop|restart|condrestart|status|retune|help}" - RETVAL=3 + echo $"Usage: $prog {start|stop|restart|force-reload|condrestart|try-restart|status|retune|help}" + RETVAL=2 esac exit $RETVAL diff --git a/qemu-Move-virtio-serial-to-Makefile.objs.patch b/qemu-Move-virtio-serial-to-Makefile.objs.patch deleted file mode 100644 index fd62df4..0000000 --- a/qemu-Move-virtio-serial-to-Makefile.objs.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 12a074387284fc530876ef709b3d344adea9b226 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Wed, 20 Jan 2010 00:36:57 +0530 -Subject: [PATCH 7/9] Move virtio-serial to Makefile.objs - -There's nothing target-dependent in the virtio-serial code so allow it -to be compiled just once for all the targets. - -Signed-off-by: Amit Shah -Signed-off-by: Anthony Liguori ---- - Makefile.hw | 2 +- - Makefile.target | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/Makefile.hw b/Makefile.hw -index 6f4dbc4..de8a0c5 100644 ---- a/Makefile.hw -+++ b/Makefile.hw -@@ -13,7 +13,7 @@ QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu - - obj-y = - obj-y += loader.o --obj-y += virtio.o -+obj-y += virtio.o virtio-serial.o - obj-y += fw_cfg.o - obj-y += watchdog.o - obj-$(CONFIG_ECC) += ecc.o -diff --git a/Makefile.target b/Makefile.target -index 234577c..0e4cfd1 100644 ---- a/Makefile.target -+++ b/Makefile.target -@@ -166,7 +166,7 @@ ifdef CONFIG_SOFTMMU - obj-y = vl.o async.o monitor.o pci.o pci_host.o pcie_host.o machine.o gdbstub.o - # virtio has to be here due to weird dependency between PCI and virtio-net. - # need to fix this properly --obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial.o virtio-serial-bus.o virtio-pci.o -+obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-pci.o virtio-serial-bus.o - obj-$(CONFIG_KVM) += kvm.o kvm-all.o - # MSI-X depends on kvm for interrupt injection, - # so moved it from Makefile.hw to Makefile.target for now --- -1.6.2.5 - diff --git a/qemu-exec-memory-notifiers.patch b/qemu-exec-memory-notifiers.patch deleted file mode 100644 index 09c0ea9..0000000 --- a/qemu-exec-memory-notifiers.patch +++ /dev/null @@ -1,199 +0,0 @@ -This adds notifiers for phys memory changes: a set of callbacks that -vhost can register and update kernel accordingly. Down the road, kvm -code can be switched to use these as well, instead of calling kvm code -directly from exec.c as is done now. - -Signed-off-by: Michael S. Tsirkin ---- - cpu-common.h | 19 ++++++++++ - exec.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 130 insertions(+), 3 deletions(-) - -diff --git a/cpu-common.h b/cpu-common.h -index 5e59564..326513d 100644 ---- a/cpu-common.h -+++ b/cpu-common.h -@@ -8,6 +8,7 @@ - #endif - - #include "bswap.h" -+#include "qemu-queue.h" - - /* address in the RAM (different from a physical address) */ - typedef unsigned long ram_addr_t; -@@ -62,6 +63,24 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len, - void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque)); - void cpu_unregister_map_client(void *cookie); - -+struct CPUPhysMemoryClient; -+typedef struct CPUPhysMemoryClient CPUPhysMemoryClient; -+struct CPUPhysMemoryClient { -+ void (*set_memory)(struct CPUPhysMemoryClient *client, -+ target_phys_addr_t start_addr, -+ ram_addr_t size, -+ ram_addr_t phys_offset); -+ int (*sync_dirty_bitmap)(struct CPUPhysMemoryClient *client, -+ target_phys_addr_t start_addr, -+ target_phys_addr_t end_addr); -+ int (*migration_log)(struct CPUPhysMemoryClient *client, -+ int enable); -+ QLIST_ENTRY(CPUPhysMemoryClient) list; -+}; -+ -+void cpu_register_phys_memory_client(CPUPhysMemoryClient *); -+void cpu_unregister_phys_memory_client(CPUPhysMemoryClient *); -+ - uint32_t ldub_phys(target_phys_addr_t addr); - uint32_t lduw_phys(target_phys_addr_t addr); - uint32_t ldl_phys(target_phys_addr_t addr); -diff --git a/exec.c b/exec.c -index 8f873ab..cbba15e 100644 ---- a/exec.c -+++ b/exec.c -@@ -1640,6 +1640,101 @@ const CPULogItem cpu_log_items[] = { - { 0, NULL, NULL }, - }; - -+#ifndef CONFIG_USER_ONLY -+static QLIST_HEAD(memory_client_list, CPUPhysMemoryClient) memory_client_list -+ = QLIST_HEAD_INITIALIZER(memory_client_list); -+ -+static void cpu_notify_set_memory(target_phys_addr_t start_addr, -+ ram_addr_t size, -+ ram_addr_t phys_offset) -+{ -+ CPUPhysMemoryClient *client; -+ QLIST_FOREACH(client, &memory_client_list, list) { -+ client->set_memory(client, start_addr, size, phys_offset); -+ } -+} -+ -+static int cpu_notify_sync_dirty_bitmap(target_phys_addr_t start, -+ target_phys_addr_t end) -+{ -+ CPUPhysMemoryClient *client; -+ QLIST_FOREACH(client, &memory_client_list, list) { -+ int r = client->sync_dirty_bitmap(client, start, end); -+ if (r < 0) -+ return r; -+ } -+ return 0; -+} -+ -+static int cpu_notify_migration_log(int enable) -+{ -+ CPUPhysMemoryClient *client; -+ QLIST_FOREACH(client, &memory_client_list, list) { -+ int r = client->migration_log(client, enable); -+ if (r < 0) -+ return r; -+ } -+ return 0; -+} -+ -+static void phys_page_for_each_in_l1_map(PhysPageDesc **phys_map, -+ CPUPhysMemoryClient *client) -+{ -+ PhysPageDesc *pd; -+ int l1, l2; -+ -+ for (l1 = 0; l1 < L1_SIZE; ++l1) { -+ pd = phys_map[l1]; -+ if (!pd) { -+ continue; -+ } -+ for (l2 = 0; l2 < L2_SIZE; ++l2) { -+ if (pd[l2].phys_offset == IO_MEM_UNASSIGNED) { -+ continue; -+ } -+ client->set_memory(client, pd[l2].region_offset, -+ TARGET_PAGE_SIZE, pd[l2].phys_offset); -+ } -+ } -+} -+ -+static void phys_page_for_each(CPUPhysMemoryClient *client) -+{ -+#if TARGET_PHYS_ADDR_SPACE_BITS > 32 -+ -+#if TARGET_PHYS_ADDR_SPACE_BITS > (32 + L1_BITS) -+#error unsupported TARGET_PHYS_ADDR_SPACE_BITS -+#endif -+ void **phys_map = (void **)l1_phys_map; -+ int l1; -+ if (!l1_phys_map) { -+ return; -+ } -+ for (l1 = 0; l1 < L1_SIZE; ++l1) { -+ if (phys_map[l1]) { -+ phys_page_for_each_in_l1_map(phys_map[l1], client); -+ } -+ } -+#else -+ if (!l1_phys_map) { -+ return; -+ } -+ phys_page_for_each_in_l1_map(l1_phys_map, client); -+#endif -+} -+ -+void cpu_register_phys_memory_client(CPUPhysMemoryClient *client) -+{ -+ QLIST_INSERT_HEAD(&memory_client_list, client, list); -+ phys_page_for_each(client); -+} -+ -+void cpu_unregister_phys_memory_client(CPUPhysMemoryClient *client) -+{ -+ QLIST_REMOVE(client, list); -+} -+#endif -+ - static int cmp1(const char *s1, int n, const char *s2) - { - if (strlen(s2) != n) -@@ -1899,10 +1994,16 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, - - int cpu_physical_memory_set_dirty_tracking(int enable) - { -+ int ret = 0; -+ in_migration = enable; - if (kvm_enabled()) { -- return kvm_set_migration_log(enable); -+ ret = kvm_set_migration_log(enable); - } -- return 0; -+ if (ret < 0) { -+ return ret; -+ } -+ ret = cpu_notify_migration_log(!!enable); -+ return ret; - } - - int cpu_physical_memory_get_dirty_tracking(void) -@@ -1915,8 +2016,13 @@ int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, - { - int ret = 0; - -- if (kvm_enabled()) -+ if (kvm_enabled()) { - ret = kvm_physical_sync_dirty_bitmap(start_addr, end_addr); -+ } -+ if (ret < 0) { -+ return ret; -+ } -+ ret = cpu_notify_sync_dirty_bitmap(start_addr, end_addr); - return ret; - } - -@@ -2331,6 +2437,8 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, - if (kvm_enabled()) - kvm_set_phys_mem(start_addr, size, phys_offset); - -+ cpu_notify_set_memory(start_addr, size, phys_offset); -+ - if (phys_offset == IO_MEM_UNASSIGNED) { - region_offset = start_addr; - } --- -1.6.6.144.g5c3af diff --git a/qemu-fix-linux-user-build-on-ppc.patch b/qemu-fix-linux-user-build-on-ppc.patch deleted file mode 100644 index f8dccc1..0000000 --- a/qemu-fix-linux-user-build-on-ppc.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 8f4d4cb4e4e73d0533aa2cb421c14210c75f6edc Mon Sep 17 00:00:00 2001 -From: Mark McLoughlin -Date: Mon, 29 Jun 2009 14:49:03 +0100 -Subject: [PATCH] Fix linux-user build on ppc - -kvm-87 build fails on ppc: - - https://koji.fedoraproject.org/koji/getfile?taskID=1441042&name=build.log - - gcc -I. -I.. -I/builddir/build/BUILD/qemu-kvm-devel-87/target-i386 - -I/builddir/build/BUILD/qemu-kvm-devel-87 -MMD -MT elfload.o -MP - -DNEED_CPU_H -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE - -D__user= -I/builddir/build/BUILD/qemu-kvm-devel-87/tcg - -I/builddir/build/BUILD/qemu-kvm-devel-87/tcg/ppc64 - -I/builddir/build/BUILD/qemu-kvm-devel-87/fpu - -I/builddir/build/BUILD/qemu-kvm-devel-87/linux-user - -I/builddir/build/BUILD/qemu-kvm-devel-87/linux-user/i386 -O2 -g -pipe - -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector - --param=ssp-buffer-size=4 -m64 -mminimal-toc -g -fno-strict-aliasing - -O2 -Wall -Wundef -Wendif-labels -Wwrite-strings -Wmissing-prototypes - -Wstrict-prototypes -Wredundant-decls -c -o elfload.o - /builddir/build/BUILD/qemu-kvm-devel-87/linux-user/elfload.c - /builddir/build/BUILD/qemu-kvm-devel-87/linux-user/elfload.c:214: error: conflicting types for 'elf_greg_t' - /usr/include/asm/elf.h:123: note: previous declaration of 'elf_greg_t' was here - /builddir/build/BUILD/qemu-kvm-devel-87/linux-user/elfload.c:220: error: conflicting types for 'elf_gregset_t' - /usr/include/asm/elf.h:124: note: previous declaration of 'elf_gregset_t' was here - In file included from /builddir/build/BUILD/qemu-kvm-devel-87/linux-user/elfload.c:697: - ../elf.h:457:1: warning: "R_PPC_NUM" redefined - In file included from /usr/include/asm/sigcontext.h:13, - from /usr/include/bits/sigcontext.h:28, - from /usr/include/signal.h:339, - from /builddir/build/BUILD/qemu-kvm-devel-87/linux-user/qemu.h:4, - from /builddir/build/BUILD/qemu-kvm-devel-87/linux-user/elfload.c:16: - /usr/include/asm/elf.h:81:1: warning: this is the location of the previous definition - -Problem seems to be that signal.h is pulling in a bunch of ppc -headers which expose elf_greg_t, R_PPC_* and PPC_FEATURE_*. - -Signed-off-by: Mark McLoughlin -Fedora-patch: qemu-fix-linux-user-build-on-ppc.patch ---- - elf.h | 2 ++ - linux-user/elfload.c | 10 ++++++++++ - 2 files changed, 12 insertions(+), 0 deletions(-) - -diff --git a/elf.h b/elf.h -index b042002..14f8aa1 100644 ---- a/elf.h -+++ b/elf.h -@@ -454,7 +454,9 @@ typedef struct { - #define R_PPC_SECTOFF_HI 35 - #define R_PPC_SECTOFF_HA 36 - /* Keep this the last entry. */ -+#ifndef R_PPC_NUM - #define R_PPC_NUM 37 -+#endif /* R_PPC_NUM */ - - /* ARM specific declarations */ - -diff --git a/linux-user/elfload.c b/linux-user/elfload.c -index 3a8268b..d283f73 100644 ---- a/linux-user/elfload.c -+++ b/linux-user/elfload.c -@@ -134,6 +134,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i - regs->rip = infop->entry; - } - -+#ifdef FIX_BROKEN_PPC_BUILD - typedef target_ulong elf_greg_t; - typedef uint32_t target_uid_t; - typedef uint32_t target_gid_t; -@@ -179,6 +180,7 @@ static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env) - (*regs)[25] = env->segs[R_FS].selector & 0xffff; - (*regs)[26] = env->segs[R_GS].selector & 0xffff; - } -+#endif /* FIX_BROKEN_PPC_BUILD */ - - #else - -@@ -211,6 +213,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i - regs->edx = 0; - } - -+#ifdef FIX_BROKEN_PPC_BUILD - typedef target_ulong elf_greg_t; - typedef uint16_t target_uid_t; - typedef uint16_t target_gid_t; -@@ -246,9 +249,12 @@ static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env) - (*regs)[15] = env->regs[R_ESP]; - (*regs)[16] = env->segs[R_SS].selector & 0xffff; - } -+#endif /* FIX_BROKEN_PPC_BUILD */ - #endif - -+#ifdef FIX_BROKEN_PPC_BUILD - #define USE_ELF_CORE_DUMP -+#endif /* FIX_BROKEN_PPC_BUILD */ - #define ELF_EXEC_PAGESIZE 4096 - - #endif -@@ -286,6 +292,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i - regs->ARM_r10 = infop->start_data; - } - -+#ifdef FIX_BROKEN_PPC_BUILD - typedef uint32_t elf_greg_t; - typedef uint16_t target_uid_t; - typedef uint16_t target_gid_t; -@@ -318,6 +325,7 @@ static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env) - } - - #define USE_ELF_CORE_DUMP -+#endif /* FIX_BROKEN_PPC_BUILD */ - #define ELF_EXEC_PAGESIZE 4096 - - enum -@@ -421,6 +429,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i - - /* Feature masks for the Aux Vector Hardware Capabilities (AT_HWCAP). - See arch/powerpc/include/asm/cputable.h. */ -+#ifndef PPC_FEATURE_32 - enum { - PPC_FEATURE_32 = 0x80000000, - PPC_FEATURE_64 = 0x40000000, -@@ -452,6 +461,7 @@ enum { - PPC_FEATURE_TRUE_LE = 0x00000002, - PPC_FEATURE_PPC_LE = 0x00000001, - }; -+#endif /* !defined(PPC_FEATURE_32) */ - - #define ELF_HWCAP get_elf_hwcap() - --- -1.6.2.5 - diff --git a/qemu-fix-qcow2-backing-file-with-virtio.patch b/qemu-fix-qcow2-backing-file-with-virtio.patch deleted file mode 100644 index 2dc56ac..0000000 --- a/qemu-fix-qcow2-backing-file-with-virtio.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 1df18d4a961a66b9ea28ab83b409f4d9d470f148 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Thu, 8 Oct 2009 15:02:08 +0200 -Subject: [PATCH] qcow2: Bring synchronous read/write back to life - -When the synchronous read and write functions were dropped, they were replaced -by generic emulation functions. Unfortunately, these emulation functions don't -provide the same semantics as the original functions did. - -The original bdrv_read would mean that we read some data synchronously and that -we won't be interrupted during this read. The latter assumption is no longer -true with the emulation function which needs to use qemu_aio_poll and therefore -allows the callback of any other concurrent AIO request to be run during the -read. Which in turn means that (meta)data read earlier could have changed and -be invalid now. qcow2 is not prepared to work in this way and it's just scary -how many places there are where other requests could run. - -I'm not sure yet where exactly it breaks, but you'll see breakage with virtio -on qcow2 with a backing file. Providing synchronous functions again fixes the -problem for me. - -Signed-off-by: Kevin Wolf -Signed-off-by: Mark McLoughlin -Fedora-patch: qemu-fix-qcow2-backing-file-with-virtio.patch ---- - block/qcow2-cluster.c | 6 ++-- - block/qcow2.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++- - block/qcow2.h | 3 ++ - 3 files changed, 55 insertions(+), 5 deletions(-) - -diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c -index d4631c3..4d0ce16 100644 ---- a/block/qcow2-cluster.c -+++ b/block/qcow2-cluster.c -@@ -306,8 +306,8 @@ void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num, - } - - --static int qcow_read(BlockDriverState *bs, int64_t sector_num, -- uint8_t *buf, int nb_sectors) -+int qcow2_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, -+ int nb_sectors) - { - BDRVQcowState *s = bs->opaque; - int ret, index_in_cluster, n, n1; -@@ -358,7 +358,7 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect, - n = n_end - n_start; - if (n <= 0) - return 0; -- ret = qcow_read(bs, start_sect + n_start, s->cluster_data, n); -+ ret = qcow2_read(bs, start_sect + n_start, s->cluster_data, n); - if (ret < 0) - return ret; - if (s->crypt_method) { -diff --git a/block/qcow2.c b/block/qcow2.c -index dd32ea2..ced257e 100644 ---- a/block/qcow2.c -+++ b/block/qcow2.c -@@ -855,6 +855,51 @@ static int qcow_make_empty(BlockDriverState *bs) - return 0; - } - -+static int qcow2_write(BlockDriverState *bs, int64_t sector_num, -+ const uint8_t *buf, int nb_sectors) -+{ -+ BDRVQcowState *s = bs->opaque; -+ int ret, index_in_cluster, n; -+ uint64_t cluster_offset; -+ int n_end; -+ QCowL2Meta l2meta; -+ -+ while (nb_sectors > 0) { -+ memset(&l2meta, 0, sizeof(l2meta)); -+ -+ index_in_cluster = sector_num & (s->cluster_sectors - 1); -+ n_end = index_in_cluster + nb_sectors; -+ if (s->crypt_method && -+ n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) -+ n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; -+ cluster_offset = qcow2_alloc_cluster_offset(bs, sector_num << 9, -+ index_in_cluster, -+ n_end, &n, &l2meta); -+ if (!cluster_offset) -+ return -1; -+ if (s->crypt_method) { -+ qcow2_encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1, -+ &s->aes_encrypt_key); -+ ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, -+ s->cluster_data, n * 512); -+ } else { -+ ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512); -+ } -+ if (ret != n * 512 || qcow2_alloc_cluster_link_l2(bs, cluster_offset, &l2meta) < 0) { -+ qcow2_free_any_clusters(bs, cluster_offset, l2meta.nb_clusters); -+ return -1; -+ } -+ nb_sectors -= n; -+ sector_num += n; -+ buf += n * 512; -+ if (l2meta.nb_clusters != 0) { -+ LIST_REMOVE(&l2meta, next_in_flight); -+ } -+ } -+ s->cluster_cache_offset = -1; /* disable compressed cache */ -+ return 0; -+} -+ - /* XXX: put compressed sectors first, then all the cluster aligned - tables to avoid losing bytes in alignment */ - static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num, -@@ -1037,8 +1082,10 @@ static BlockDriver bdrv_qcow2 = { - .bdrv_set_key = qcow_set_key, - .bdrv_make_empty = qcow_make_empty, - -- .bdrv_aio_readv = qcow_aio_readv, -- .bdrv_aio_writev = qcow_aio_writev, -+ .bdrv_read = qcow2_read, -+ .bdrv_write = qcow2_write, -+ .bdrv_aio_readv = qcow_aio_readv, -+ .bdrv_aio_writev = qcow_aio_writev, - .bdrv_write_compressed = qcow_write_compressed, - - .bdrv_snapshot_create = qcow2_snapshot_create, -diff --git a/block/qcow2.h b/block/qcow2.h -index 965a2f4..b41aa63 100644 ---- a/block/qcow2.h -+++ b/block/qcow2.h -@@ -202,6 +202,9 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, - int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, uint64_t cluster_offset, - QCowL2Meta *m); - -+int qcow2_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, -+ int nb_sectors); -+ - /* qcow2-snapshot.c functions */ - int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info); - int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id); --- -1.6.2.5 - diff --git a/qemu-kvm-add-API-to-set-ioeventfd.patch b/qemu-kvm-add-API-to-set-ioeventfd.patch deleted file mode 100644 index 365bae8..0000000 --- a/qemu-kvm-add-API-to-set-ioeventfd.patch +++ /dev/null @@ -1,81 +0,0 @@ -This adds API to set ioeventfd to kvm, -as well as stubs for non-eventfd case, -making it possible for users to use this API -without ifdefs. - -Signed-off-by: Michael S. Tsirkin ---- - kvm-all.c | 20 ++++++++++++++++++++ - kvm.h | 16 ++++++++++++++++ - 2 files changed, 36 insertions(+), 0 deletions(-) - -diff --git a/kvm-all.c b/kvm-all.c -index 0423fff..efdf40c 100644 ---- a/kvm-all.c -+++ b/kvm-all.c -@@ -1102,4 +1102,24 @@ void kvm_remove_all_breakpoints(CPUState *current_env) - } - #endif /* !KVM_CAP_SET_GUEST_DEBUG */ - -+#ifdef KVM_IOEVENTFD -+int kvm_set_ioeventfd(uint16_t addr, uint16_t data, int fd, bool assigned) -+{ -+ struct kvm_ioeventfd kick = { -+ .datamatch = data, -+ .addr = addr, -+ .len = 2, -+ .flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO, -+ .fd = fd, -+ }; -+ int r; -+ if (!assigned) -+ kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; -+ r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick); -+ if (r < 0) -+ return r; -+ return 0; -+} -+#endif -+ - #include "qemu-kvm.c" -diff --git a/kvm.h b/kvm.h -index 9fa4e25..e98b5c8 100644 ---- a/kvm.h -+++ b/kvm.h -@@ -14,6 +14,8 @@ - #ifndef QEMU_KVM_H - #define QEMU_KVM_H - -+#include -+#include - #include "config.h" - #include "qemu-queue.h" - #include "qemu-kvm.h" -@@ -21,6 +23,10 @@ - #ifdef KVM_UPSTREAM - - #ifdef CONFIG_KVM -+#include -+#endif -+ -+#ifdef CONFIG_KVM - extern int kvm_allowed; - - #define kvm_enabled() (kvm_allowed) -@@ -151,4 +157,14 @@ static inline void cpu_synchronize_state(CPUState *env) - - #endif - -+#if defined(KVM_IOEVENTFD) && defined(CONFIG_KVM) -+int kvm_set_ioeventfd(uint16_t addr, uint16_t data, int fd, bool assigned); -+#else -+static inline -+int kvm_set_ioeventfd(uint16_t data, uint16_t addr, int fd, bool assigned) -+{ -+ return -ENOSYS; -+} -+#endif -+ - #endif --- -1.6.6.144.g5c3af diff --git a/qemu-kvm-add-vhost.h-header.patch b/qemu-kvm-add-vhost.h-header.patch deleted file mode 100644 index e820504..0000000 --- a/qemu-kvm-add-vhost.h-header.patch +++ /dev/null @@ -1,147 +0,0 @@ -This makes it possible to build vhost support -on systems which do not have this header. - -Signed-off-by: Michael S. Tsirkin ---- - kvm/include/linux/vhost.h | 130 +++++++++++++++++++++++++++++++++++++++++++++ - 1 files changed, 130 insertions(+), 0 deletions(-) - create mode 100644 kvm/include/linux/vhost.h - -diff --git a/kvm/include/linux/vhost.h b/kvm/include/linux/vhost.h -new file mode 100644 -index 0000000..165a484 ---- /dev/null -+++ b/kvm/include/linux/vhost.h -@@ -0,0 +1,130 @@ -+#ifndef _LINUX_VHOST_H -+#define _LINUX_VHOST_H -+/* Userspace interface for in-kernel virtio accelerators. */ -+ -+/* vhost is used to reduce the number of system calls involved in virtio. -+ * -+ * Existing virtio net code is used in the guest without modification. -+ * -+ * This header includes interface used by userspace hypervisor for -+ * device configuration. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+ -+struct vhost_vring_state { -+ unsigned int index; -+ unsigned int num; -+}; -+ -+struct vhost_vring_file { -+ unsigned int index; -+ int fd; /* Pass -1 to unbind from file. */ -+ -+}; -+ -+struct vhost_vring_addr { -+ unsigned int index; -+ /* Option flags. */ -+ unsigned int flags; -+ /* Flag values: */ -+ /* Whether log address is valid. If set enables logging. */ -+#define VHOST_VRING_F_LOG 0 -+ -+ /* Start of array of descriptors (virtually contiguous) */ -+ __u64 desc_user_addr; -+ /* Used structure address. Must be 32 bit aligned */ -+ __u64 used_user_addr; -+ /* Available structure address. Must be 16 bit aligned */ -+ __u64 avail_user_addr; -+ /* Logging support. */ -+ /* Log writes to used structure, at offset calculated from specified -+ * address. Address must be 32 bit aligned. */ -+ __u64 log_guest_addr; -+}; -+ -+struct vhost_memory_region { -+ __u64 guest_phys_addr; -+ __u64 memory_size; /* bytes */ -+ __u64 userspace_addr; -+ __u64 flags_padding; /* No flags are currently specified. */ -+}; -+ -+/* All region addresses and sizes must be 4K aligned. */ -+#define VHOST_PAGE_SIZE 0x1000 -+ -+struct vhost_memory { -+ __u32 nregions; -+ __u32 padding; -+ struct vhost_memory_region regions[0]; -+}; -+ -+/* ioctls */ -+ -+#define VHOST_VIRTIO 0xAF -+ -+/* Features bitmask for forward compatibility. Transport bits are used for -+ * vhost specific features. */ -+#define VHOST_GET_FEATURES _IOR(VHOST_VIRTIO, 0x00, __u64) -+#define VHOST_SET_FEATURES _IOW(VHOST_VIRTIO, 0x00, __u64) -+ -+/* Set current process as the (exclusive) owner of this file descriptor. This -+ * must be called before any other vhost command. Further calls to -+ * VHOST_OWNER_SET fail until VHOST_OWNER_RESET is called. */ -+#define VHOST_SET_OWNER _IO(VHOST_VIRTIO, 0x01) -+/* Give up ownership, and reset the device to default values. -+ * Allows subsequent call to VHOST_OWNER_SET to succeed. */ -+#define VHOST_RESET_OWNER _IO(VHOST_VIRTIO, 0x02) -+ -+/* Set up/modify memory layout */ -+#define VHOST_SET_MEM_TABLE _IOW(VHOST_VIRTIO, 0x03, struct vhost_memory) -+ -+/* Write logging setup. */ -+/* Memory writes can optionally be logged by setting bit at an offset -+ * (calculated from the physical address) from specified log base. -+ * The bit is set using an atomic 32 bit operation. */ -+/* Set base address for logging. */ -+#define VHOST_SET_LOG_BASE _IOW(VHOST_VIRTIO, 0x04, __u64) -+/* Specify an eventfd file descriptor to signal on log write. */ -+#define VHOST_SET_LOG_FD _IOW(VHOST_VIRTIO, 0x07, int) -+ -+/* Ring setup. */ -+/* Set number of descriptors in ring. This parameter can not -+ * be modified while ring is running (bound to a device). */ -+#define VHOST_SET_VRING_NUM _IOW(VHOST_VIRTIO, 0x10, struct vhost_vring_state) -+/* Set addresses for the ring. */ -+#define VHOST_SET_VRING_ADDR _IOW(VHOST_VIRTIO, 0x11, struct vhost_vring_addr) -+/* Base value where queue looks for available descriptors */ -+#define VHOST_SET_VRING_BASE _IOW(VHOST_VIRTIO, 0x12, struct vhost_vring_state) -+/* Get accessor: reads index, writes value in num */ -+#define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state) -+ -+/* The following ioctls use eventfd file descriptors to signal and poll -+ * for events. */ -+ -+/* Set eventfd to poll for added buffers */ -+#define VHOST_SET_VRING_KICK _IOW(VHOST_VIRTIO, 0x20, struct vhost_vring_file) -+/* Set eventfd to signal when buffers have beed used */ -+#define VHOST_SET_VRING_CALL _IOW(VHOST_VIRTIO, 0x21, struct vhost_vring_file) -+/* Set eventfd to signal an error */ -+#define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file) -+ -+/* VHOST_NET specific defines */ -+ -+/* Attach virtio net ring to a raw socket, or tap device. -+ * The socket must be already bound to an ethernet device, this device will be -+ * used for transmit. Pass fd -1 to unbind from the socket and the transmit -+ * device. This can be used to stop the ring (e.g. for migration). */ -+#define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct vhost_vring_file) -+ -+/* Feature bits */ -+/* Log all write descriptors. Can be changed while device is active. */ -+#define VHOST_F_LOG_ALL 26 -+/* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */ -+#define VHOST_NET_F_VIRTIO_NET_HDR 27 -+ -+#endif --- -1.6.6.144.g5c3af diff --git a/qemu-kvm-irqfd-support.patch b/qemu-kvm-irqfd-support.patch deleted file mode 100644 index 4f74d87..0000000 --- a/qemu-kvm-irqfd-support.patch +++ /dev/null @@ -1,59 +0,0 @@ -Add API to assign/deassign irqfd to kvm. -Add stub so that users do not have to use -ifdefs. - -Signed-off-by: Michael S. Tsirkin ---- - kvm-all.c | 19 +++++++++++++++++++ - kvm.h | 10 ++++++++++ - 2 files changed, 29 insertions(+), 0 deletions(-) - -diff --git a/kvm-all.c b/kvm-all.c -index efdf40c..b3fdf29 100644 ---- a/kvm-all.c -+++ b/kvm-all.c -@@ -1122,4 +1122,23 @@ int kvm_set_ioeventfd(uint16_t addr, uint16_t data, int fd, bool assigned) - } - #endif - -+#if defined(KVM_IRQFD) -+int kvm_set_irqfd(int gsi, int fd, bool assigned) -+{ -+ struct kvm_irqfd irqfd = { -+ .fd = fd, -+ .gsi = gsi, -+ .flags = assigned ? 0 : KVM_IRQFD_FLAG_DEASSIGN, -+ }; -+ int r; -+ if (!kvm_irqchip_in_kernel()) -+ return -ENOSYS; -+ -+ r = kvm_vm_ioctl(kvm_state, KVM_IRQFD, &irqfd); -+ if (r < 0) -+ return r; -+ return 0; -+} -+#endif -+ - #include "qemu-kvm.c" -diff --git a/kvm.h b/kvm.h -index e98b5c8..ad8d122 100644 ---- a/kvm.h -+++ b/kvm.h -@@ -167,4 +167,14 @@ int kvm_set_ioeventfd(uint16_t data, uint16_t addr, int fd, bool assigned) - } - #endif - -+#if defined(KVM_IRQFD) && defined(CONFIG_KVM) -+int kvm_set_irqfd(int gsi, int fd, bool assigned); -+#else -+static inline -+int kvm_set_irqfd(int gsi, int fd, bool assigned) -+{ -+ return -ENOSYS; -+} -+#endif -+ - #endif --- -1.6.6.144.g5c3af diff --git a/qemu-msix-add-mask-unmask-notifiers.patch b/qemu-msix-add-mask-unmask-notifiers.patch deleted file mode 100644 index 845bbc0..0000000 --- a/qemu-msix-add-mask-unmask-notifiers.patch +++ /dev/null @@ -1,121 +0,0 @@ -Support per-vector callbacks for msix mask/unmask. -Will be used for vhost net. - -Signed-off-by: Michael S. Tsirkin ---- - hw/msix.c | 36 +++++++++++++++++++++++++++++++++++- - hw/msix.h | 1 + - hw/pci.h | 6 ++++++ - 3 files changed, 42 insertions(+), 1 deletions(-) - -diff --git a/hw/msix.c b/hw/msix.c -index d117bcf..3fcf3a1 100644 ---- a/hw/msix.c -+++ b/hw/msix.c -@@ -318,6 +318,13 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr, - if (kvm_enabled() && kvm_irqchip_in_kernel()) { - kvm_msix_update(dev, vector, was_masked, msix_is_masked(dev, vector)); - } -+ if (was_masked != msix_is_masked(dev, vector) && -+ dev->msix_mask_notifier && dev->msix_mask_notifier_opaque[vector]) { -+ int r = dev->msix_mask_notifier(dev, vector, -+ dev->msix_mask_notifier_opaque[vector], -+ msix_is_masked(dev, vector)); -+ assert(r >= 0); -+ } - msix_handle_mask_update(dev, vector); - } - -@@ -356,10 +363,18 @@ void msix_mmio_map(PCIDevice *d, int region_num, - - static void msix_mask_all(struct PCIDevice *dev, unsigned nentries) - { -- int vector; -+ int vector, r; - for (vector = 0; vector < nentries; ++vector) { - unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL; -+ int was_masked = msix_is_masked(dev, vector); - dev->msix_table_page[offset] |= MSIX_VECTOR_MASK; -+ if (was_masked != msix_is_masked(dev, vector) && -+ dev->msix_mask_notifier && dev->msix_mask_notifier_opaque[vector]) { -+ r = dev->msix_mask_notifier(dev, vector, -+ dev->msix_mask_notifier_opaque[vector], -+ msix_is_masked(dev, vector)); -+ assert(r >= 0); -+ } - } - } - -@@ -382,6 +397,9 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries, - sizeof *dev->msix_irq_entries); - } - #endif -+ dev->msix_mask_notifier_opaque = -+ qemu_mallocz(nentries * sizeof *dev->msix_mask_notifier_opaque); -+ dev->msix_mask_notifier = NULL; - dev->msix_entry_used = qemu_mallocz(MSIX_MAX_ENTRIES * - sizeof *dev->msix_entry_used); - -@@ -444,6 +462,8 @@ int msix_uninit(PCIDevice *dev) - dev->msix_entry_used = NULL; - qemu_free(dev->msix_irq_entries); - dev->msix_irq_entries = NULL; -+ qemu_free(dev->msix_mask_notifier_opaque); -+ dev->msix_mask_notifier_opaque = NULL; - dev->cap_present &= ~QEMU_PCI_CAP_MSIX; - return 0; - } -@@ -587,3 +607,17 @@ void msix_unuse_all_vectors(PCIDevice *dev) - return; - msix_free_irq_entries(dev); - } -+ -+int msix_set_mask_notifier(PCIDevice *dev, unsigned vector, void *opaque) -+{ -+ int r = 0; -+ if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) -+ return 0; -+ -+ if (dev->msix_mask_notifier) -+ r = dev->msix_mask_notifier(dev, vector, opaque, -+ msix_is_masked(dev, vector)); -+ if (r >= 0) -+ dev->msix_mask_notifier_opaque[vector] = opaque; -+ return r; -+} -diff --git a/hw/msix.h b/hw/msix.h -index a9f7993..f167231 100644 ---- a/hw/msix.h -+++ b/hw/msix.h -@@ -33,4 +33,5 @@ void msix_reset(PCIDevice *dev); - - extern int msix_supported; - -+int msix_set_mask_notifier(PCIDevice *dev, unsigned vector, void *opaque); - #endif -diff --git a/hw/pci.h b/hw/pci.h -index a225a6a..bf722ca 100644 ---- a/hw/pci.h -+++ b/hw/pci.h -@@ -217,6 +217,9 @@ enum { - #define PCI_CAPABILITY_CONFIG_MSI_LENGTH 0x10 - #define PCI_CAPABILITY_CONFIG_MSIX_LENGTH 0x10 - -+typedef int (*msix_mask_notifier_func)(PCIDevice *, unsigned vector, -+ void *opaque, int masked); -+ - struct PCIDevice { - DeviceState qdev; - /* PCI config space */ -@@ -282,6 +285,9 @@ struct PCIDevice { - - struct kvm_irq_routing_entry *msix_irq_entries; - -+ void **msix_mask_notifier_opaque; -+ msix_mask_notifier_func msix_mask_notifier; -+ - /* Device capability configuration space */ - struct { - int supported; --- -1.6.6.144.g5c3af diff --git a/qemu-net-add-API-to-disable-enable-polling.patch b/qemu-net-add-API-to-disable-enable-polling.patch deleted file mode 100644 index d41adef..0000000 --- a/qemu-net-add-API-to-disable-enable-polling.patch +++ /dev/null @@ -1,68 +0,0 @@ -When vhost is bound to a backend device, we need to stop polling it when -vhost is started, and restart polling when vhost is stopped. -Add an API for that for use by vhost, and implement in tap backend. - -Signed-off-by: Michael S. Tsirkin -Signed-off-by: Anthony Liguori -(cherry picked from commit ceb696159d569db5b2a7659ce38752398c236742) ---- - net.h | 3 +++ - net/tap.c | 8 ++++++++ - 2 files changed, 11 insertions(+), 0 deletions(-) - -diff --git a/net.h b/net.h -index 4971fcb..116bb80 100644 ---- a/net.h -+++ b/net.h -@@ -1,6 +1,7 @@ - #ifndef QEMU_NET_H - #define QEMU_NET_H - -+#include - #include "qemu-queue.h" - #include "qemu-common.h" - #include "qdict.h" -@@ -36,6 +37,7 @@ typedef enum { - NET_CLIENT_TYPE_DUMP - } net_client_type; - -+typedef void (NetPoll)(VLANClientState *, bool enable); - typedef int (NetCanReceive)(VLANClientState *); - typedef ssize_t (NetReceive)(VLANClientState *, const uint8_t *, size_t); - typedef ssize_t (NetReceiveIOV)(VLANClientState *, const struct iovec *, int); -@@ -51,6 +53,7 @@ typedef struct NetClientInfo { - NetCanReceive *can_receive; - NetCleanup *cleanup; - LinkStatusChanged *link_status_changed; -+ NetPoll *poll; - } NetClientInfo; - - struct VLANClientState { -diff --git a/net/tap.c b/net/tap.c -index 0d8b424..d3492de 100644 ---- a/net/tap.c -+++ b/net/tap.c -@@ -262,6 +262,13 @@ static void tap_cleanup(VLANClientState *nc) - close(s->fd); - } - -+static void tap_poll(VLANClientState *nc, bool enable) -+{ -+ TAPState *s = DO_UPCAST(TAPState, nc, nc); -+ tap_read_poll(s, enable); -+ tap_write_poll(s, enable); -+} -+ - /* fd support */ - - static NetClientInfo net_tap_info = { -@@ -270,6 +277,7 @@ static NetClientInfo net_tap_info = { - .receive = tap_receive, - .receive_raw = tap_receive_raw, - .receive_iov = tap_receive_iov, -+ .poll = tap_poll, - .cleanup = tap_cleanup, - }; - --- -1.6.6.144.g5c3af diff --git a/qemu-notifier-event-notifier-implementation.patch b/qemu-notifier-event-notifier-implementation.patch deleted file mode 100644 index b5c2d27..0000000 --- a/qemu-notifier-event-notifier-implementation.patch +++ /dev/null @@ -1,122 +0,0 @@ -event notifiers are slightly generalized eventfd descriptors. Current -implementation depends on eventfd because vhost is the only user, and -vhost depends on eventfd anyway, but a stub is provided for non-eventfd -case. - -We'll be able to further generalize this when another user comes along -and we see how to best do this. - -Signed-off-by: Michael S. Tsirkin ---- - Makefile.target | 1 + - hw/notifier.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ - hw/notifier.h | 16 ++++++++++++++++ - qemu-common.h | 1 + - 4 files changed, 68 insertions(+), 0 deletions(-) - create mode 100644 hw/notifier.c - create mode 100644 hw/notifier.h - -diff --git a/Makefile.target b/Makefile.target -index 6037fed..0c844a9 100644 ---- a/Makefile.target -+++ b/Makefile.target -@@ -167,6 +167,7 @@ obj-y = vl.o async.o monitor.o pci.o pci_host.o pcie_host.o machine.o gdbstub.o - # virtio has to be here due to weird dependency between PCI and virtio-net. - # need to fix this properly - obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-pci.o virtio-serial-bus.o -+obj-y += notifier.o - obj-$(CONFIG_KVM) += kvm.o kvm-all.o - # MSI-X depends on kvm for interrupt injection, - # so moved it from Makefile.hw to Makefile.target for now -diff --git a/hw/notifier.c b/hw/notifier.c -new file mode 100644 -index 0000000..dff38de ---- /dev/null -+++ b/hw/notifier.c -@@ -0,0 +1,50 @@ -+#include "hw.h" -+#include "notifier.h" -+#ifdef CONFIG_EVENTFD -+#include -+#endif -+ -+int event_notifier_init(EventNotifier *e, int active) -+{ -+#ifdef CONFIG_EVENTFD -+ int fd = eventfd(!!active, EFD_NONBLOCK | EFD_CLOEXEC); -+ if (fd < 0) -+ return -errno; -+ e->fd = fd; -+ return 0; -+#else -+ return -ENOSYS; -+#endif -+} -+ -+void event_notifier_cleanup(EventNotifier *e) -+{ -+ close(e->fd); -+} -+ -+int event_notifier_get_fd(EventNotifier *e) -+{ -+ return e->fd; -+} -+ -+int event_notifier_test_and_clear(EventNotifier *e) -+{ -+ uint64_t value; -+ int r = read(e->fd, &value, sizeof value); -+ return r == sizeof value; -+} -+ -+int event_notifier_test(EventNotifier *e) -+{ -+ uint64_t value; -+ int r = read(e->fd, &value, sizeof value); -+ if (r == sizeof value) { -+ /* restore previous value. */ -+ int s = write(e->fd, &value, sizeof value); -+ /* never blocks because we use EFD_SEMAPHORE. -+ * If we didn't we'd get EAGAIN on overflow -+ * and we'd have to write code to ignore it. */ -+ assert(s == sizeof value); -+ } -+ return r == sizeof value; -+} -diff --git a/hw/notifier.h b/hw/notifier.h -new file mode 100644 -index 0000000..24117ea ---- /dev/null -+++ b/hw/notifier.h -@@ -0,0 +1,16 @@ -+#ifndef QEMU_EVENT_NOTIFIER_H -+#define QEMU_EVENT_NOTIFIER_H -+ -+#include "qemu-common.h" -+ -+struct EventNotifier { -+ int fd; -+}; -+ -+int event_notifier_init(EventNotifier *, int active); -+void event_notifier_cleanup(EventNotifier *); -+int event_notifier_get_fd(EventNotifier *); -+int event_notifier_test_and_clear(EventNotifier *); -+int event_notifier_test(EventNotifier *); -+ -+#endif -diff --git a/qemu-common.h b/qemu-common.h -index 5fbe0f9..cdead98 100644 ---- a/qemu-common.h -+++ b/qemu-common.h -@@ -217,6 +217,7 @@ typedef struct uWireSlave uWireSlave; - typedef struct I2SCodec I2SCodec; - typedef struct DeviceState DeviceState; - typedef struct SSIBus SSIBus; -+typedef struct EventNotifier EventNotifier; - - /* CPU save/load. */ - void cpu_save(QEMUFile *f, void *opaque); --- -1.6.6.144.g5c3af diff --git a/qemu-qdev-add-bit-property-type.patch b/qemu-qdev-add-bit-property-type.patch deleted file mode 100644 index 35a5958..0000000 --- a/qemu-qdev-add-bit-property-type.patch +++ /dev/null @@ -1,156 +0,0 @@ -This adds "bit" property type, which is a boolean stored in a 32 bit -integer field, with legal values on and off. Will be used by virtio for -feature bits. - -Signed-off-by: Michael S. Tsirkin -Acked-by: Gerd Hoffmann -Signed-off-by: Anthony Liguori -(cherry picked from commit d2364ee424ebf9180afaf21128a71da55321ad00) ---- - hw/qdev-properties.c | 62 ++++++++++++++++++++++++++++++++++++++++++++----- - hw/qdev.h | 11 +++++++++ - 2 files changed, 66 insertions(+), 7 deletions(-) - -diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c -index 217ddc0..9e123ae 100644 ---- a/hw/qdev-properties.c -+++ b/hw/qdev-properties.c -@@ -9,6 +9,59 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop) - return ptr; - } - -+static uint32_t qdev_get_prop_mask(Property *prop) -+{ -+ assert(prop->info->type == PROP_TYPE_BIT); -+ return 0x1 << prop->bitnr; -+} -+ -+static void bit_prop_set(DeviceState *dev, Property *props, bool val) -+{ -+ uint32_t *p = qdev_get_prop_ptr(dev, props); -+ uint32_t mask = qdev_get_prop_mask(props); -+ if (val) -+ *p |= ~mask; -+ else -+ *p &= ~mask; -+} -+ -+static void qdev_prop_cpy(DeviceState *dev, Property *props, void *src) -+{ -+ if (props->info->type == PROP_TYPE_BIT) { -+ bool *defval = src; -+ bit_prop_set(dev, props, *defval); -+ } else { -+ char *dst = qdev_get_prop_ptr(dev, props); -+ memcpy(dst, src, props->info->size); -+ } -+} -+ -+/* Bit */ -+static int parse_bit(DeviceState *dev, Property *prop, const char *str) -+{ -+ if (!strncasecmp(str, "on", 2)) -+ bit_prop_set(dev, prop, true); -+ else if (!strncasecmp(str, "off", 3)) -+ bit_prop_set(dev, prop, false); -+ else -+ return -1; -+ return 0; -+} -+ -+static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len) -+{ -+ uint8_t *p = qdev_get_prop_ptr(dev, prop); -+ return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off"); -+} -+ -+PropertyInfo qdev_prop_bit = { -+ .name = "on/off", -+ .type = PROP_TYPE_BIT, -+ .size = sizeof(uint32_t), -+ .parse = parse_bit, -+ .print = print_bit, -+}; -+ - /* --- 8bit integer --- */ - - static int parse_uint8(DeviceState *dev, Property *prop, const char *str) -@@ -511,7 +564,6 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value) - void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type) - { - Property *prop; -- void *dst; - - prop = qdev_prop_find(dev, name); - if (!prop) { -@@ -524,8 +576,7 @@ void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyT - __FUNCTION__, dev->info->name, name); - abort(); - } -- dst = qdev_get_prop_ptr(dev, prop); -- memcpy(dst, src, prop->info->size); -+ qdev_prop_cpy(dev, prop, src); - } - - void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) -@@ -585,14 +636,11 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) - - void qdev_prop_set_defaults(DeviceState *dev, Property *props) - { -- char *dst; -- - if (!props) - return; - while (props->name) { - if (props->defval) { -- dst = qdev_get_prop_ptr(dev, props); -- memcpy(dst, props->defval, props->info->size); -+ qdev_prop_cpy(dev, props, props->defval); - } - props++; - } -diff --git a/hw/qdev.h b/hw/qdev.h -index bbcdba1..07b9603 100644 ---- a/hw/qdev.h -+++ b/hw/qdev.h -@@ -64,6 +64,7 @@ struct Property { - const char *name; - PropertyInfo *info; - int offset; -+ int bitnr; - void *defval; - }; - -@@ -82,6 +83,7 @@ enum PropertyType { - PROP_TYPE_NETDEV, - PROP_TYPE_VLAN, - PROP_TYPE_PTR, -+ PROP_TYPE_BIT, - }; - - struct PropertyInfo { -@@ -173,6 +175,7 @@ void do_device_del(Monitor *mon, const QDict *qdict); - - /*** qdev-properties.c ***/ - -+extern PropertyInfo qdev_prop_bit; - extern PropertyInfo qdev_prop_uint8; - extern PropertyInfo qdev_prop_uint16; - extern PropertyInfo qdev_prop_uint32; -@@ -202,6 +205,14 @@ extern PropertyInfo qdev_prop_pci_devfn; - + type_check(_type,typeof_field(_state, _field)), \ - .defval = (_type[]) { _defval }, \ - } -+#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \ -+ .name = (_name), \ -+ .info = &(qdev_prop_bit), \ -+ .bitnr = (_bit), \ -+ .offset = offsetof(_state, _field) \ -+ + type_check(uint32_t,typeof_field(_state, _field)), \ -+ .defval = (bool[]) { (_defval) }, \ -+ } - - #define DEFINE_PROP_UINT8(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t) --- -1.6.6.144.g5c3af diff --git a/qemu-qdev-fix-thinko-leading-to-guest-crashes.patch b/qemu-qdev-fix-thinko-leading-to-guest-crashes.patch deleted file mode 100644 index f6ed7dc..0000000 --- a/qemu-qdev-fix-thinko-leading-to-guest-crashes.patch +++ /dev/null @@ -1,24 +0,0 @@ -Without this fix, guest crashes with drive=virtio. - -Signed-off-by: Michael S. Tsirkin -Signed-off-by: Anthony Liguori -(cherry picked from commit dbd483242c2e6dfaacb9fd3d20c333bbdad87243) ---- - hw/qdev-properties.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c -index 9e123ae..277ff9e 100644 ---- a/hw/qdev-properties.c -+++ b/hw/qdev-properties.c -@@ -20,7 +20,7 @@ static void bit_prop_set(DeviceState *dev, Property *props, bool val) - uint32_t *p = qdev_get_prop_ptr(dev, props); - uint32_t mask = qdev_get_prop_mask(props); - if (val) -- *p |= ~mask; -+ *p |= mask; - else - *p &= ~mask; - } --- -1.6.6.144.g5c3af diff --git a/qemu-tap-add-API-to-retrieve-vhost-net-header.patch b/qemu-tap-add-API-to-retrieve-vhost-net-header.patch deleted file mode 100644 index 1b10ed3..0000000 --- a/qemu-tap-add-API-to-retrieve-vhost-net-header.patch +++ /dev/null @@ -1,37 +0,0 @@ -will be used by virtio-net for vhost net support - -Signed-off-by: Michael S. Tsirkin ---- - net/tap.c | 7 +++++++ - net/tap.h | 3 +++ - 2 files changed, 10 insertions(+), 0 deletions(-) - -diff --git a/net/tap.c b/net/tap.c -index d9f2e41..166cf05 100644 ---- a/net/tap.c -+++ b/net/tap.c -@@ -491,3 +491,10 @@ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan - - return 0; - } -+ -+struct vhost_net *tap_get_vhost_net(VLANClientState *nc) -+{ -+ TAPState *s = DO_UPCAST(TAPState, nc, nc); -+ assert(nc->info->type == NET_CLIENT_TYPE_TAP); -+ return s->vhost_net; -+} -diff --git a/net/tap.h b/net/tap.h -index a244b28..b8cec83 100644 ---- a/net/tap.h -+++ b/net/tap.h -@@ -50,4 +50,7 @@ void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo); - - int tap_get_fd(VLANClientState *vc); - -+struct vhost_net; -+struct vhost_net *tap_get_vhost_net(VLANClientState *vc); -+ - #endif /* QEMU_NET_TAP_H */ --- -1.6.6.144.g5c3af diff --git a/qemu-tap-add-interface-to-get-device-fd.patch b/qemu-tap-add-interface-to-get-device-fd.patch deleted file mode 100644 index 6a198b3..0000000 --- a/qemu-tap-add-interface-to-get-device-fd.patch +++ /dev/null @@ -1,39 +0,0 @@ -Will be used by vhost to attach/detach to backend. - -Signed-off-by: Michael S. Tsirkin ---- - net/tap.c | 7 +++++++ - net/tap.h | 2 ++ - 2 files changed, 9 insertions(+), 0 deletions(-) - -diff --git a/net/tap.c b/net/tap.c -index d3492de..7e9ca79 100644 ---- a/net/tap.c -+++ b/net/tap.c -@@ -269,6 +269,13 @@ static void tap_poll(VLANClientState *nc, bool enable) - tap_write_poll(s, enable); - } - -+int tap_get_fd(VLANClientState *nc) -+{ -+ TAPState *s = DO_UPCAST(TAPState, nc, nc); -+ assert(nc->info->type == NET_CLIENT_TYPE_TAP); -+ return s->fd; -+} -+ - /* fd support */ - - static NetClientInfo net_tap_info = { -diff --git a/net/tap.h b/net/tap.h -index 538a562..a244b28 100644 ---- a/net/tap.h -+++ b/net/tap.h -@@ -48,4 +48,6 @@ int tap_probe_vnet_hdr(int fd); - int tap_probe_has_ufo(int fd); - void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo); - -+int tap_get_fd(VLANClientState *vc); -+ - #endif /* QEMU_NET_TAP_H */ --- -1.6.6.144.g5c3af diff --git a/qemu-tap-add-vhost-vhostfd-options.patch b/qemu-tap-add-vhost-vhostfd-options.patch deleted file mode 100644 index 1a3dfb9..0000000 --- a/qemu-tap-add-vhost-vhostfd-options.patch +++ /dev/null @@ -1,117 +0,0 @@ -Signed-off-by: Michael S. Tsirkin ---- - net.c | 8 ++++++++ - net/tap.c | 29 +++++++++++++++++++++++++++++ - qemu-options.hx | 4 +++- - 3 files changed, 40 insertions(+), 1 deletions(-) - -diff --git a/net.c b/net.c -index 6ef93e6..b942d03 100644 ---- a/net.c -+++ b/net.c -@@ -976,6 +976,14 @@ static struct { - .name = "vnet_hdr", - .type = QEMU_OPT_BOOL, - .help = "enable the IFF_VNET_HDR flag on the tap interface" -+ }, { -+ .name = "vhost", -+ .type = QEMU_OPT_BOOL, -+ .help = "enable vhost-net network accelerator", -+ }, { -+ .name = "vhostfd", -+ .type = QEMU_OPT_STRING, -+ .help = "file descriptor of an already opened vhost net device", - }, - #endif /* _WIN32 */ - { /* end of list */ } -diff --git a/net/tap.c b/net/tap.c -index 7e9ca79..d9f2e41 100644 ---- a/net/tap.c -+++ b/net/tap.c -@@ -41,6 +41,8 @@ - - #include "net/tap-linux.h" - -+#include "hw/vhost_net.h" -+ - /* Maximum GSO packet size (64k) plus plenty of room for - * the ethernet and virtio_net headers - */ -@@ -57,6 +59,7 @@ typedef struct TAPState { - unsigned int has_vnet_hdr : 1; - unsigned int using_vnet_hdr : 1; - unsigned int has_ufo: 1; -+ struct vhost_net *vhost_net; - } TAPState; - - static int launch_script(const char *setup_script, const char *ifname, int fd); -@@ -252,6 +255,10 @@ static void tap_cleanup(VLANClientState *nc) - { - TAPState *s = DO_UPCAST(TAPState, nc, nc); - -+ if (s->vhost_net) { -+ vhost_net_cleanup(s->vhost_net); -+ } -+ - qemu_purge_queued_packets(nc); - - if (s->down_script[0]) -@@ -307,6 +314,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan, - s->has_ufo = tap_probe_has_ufo(s->fd); - tap_set_offload(&s->nc, 0, 0, 0, 0, 0); - tap_read_poll(s, 1); -+ s->vhost_net = NULL; - return s; - } - -@@ -456,5 +464,26 @@ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan - } - } - -+ if (qemu_opt_get_bool(opts, "vhost", 0)) { -+ int vhostfd, r; -+ if (qemu_opt_get(opts, "vhostfd")) { -+ r = net_handle_fd_param(mon, qemu_opt_get(opts, "vhostfd")); -+ if (r == -1) { -+ return -1; -+ } -+ vhostfd = r; -+ } else { -+ vhostfd = -1; -+ } -+ s->vhost_net = vhost_net_init(&s->nc, vhostfd); -+ if (!s->vhost_net) { -+ qemu_error("vhost-net requested but could not be initialized\n"); -+ return -1; -+ } -+ } else if (qemu_opt_get(opts, "vhostfd")) { -+ qemu_error("vhostfd= is not valid without vhost\n"); -+ return -1; -+ } -+ - return 0; - } -diff --git a/qemu-options.hx b/qemu-options.hx -index ca73ba5..2b3d9b8 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -814,7 +814,7 @@ DEF("net", HAS_ARG, QEMU_OPTION_net, - "-net tap[,vlan=n][,name=str],ifname=name\n" - " connect the host TAP network interface to VLAN 'n'\n" - #else -- "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes][,vnet_hdr=on|off]\n" -+ "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h]\n" - " connect the host TAP network interface to VLAN 'n' and use the\n" - " network scripts 'file' (default=%s)\n" - " and 'dfile' (default=%s);\n" -@@ -824,6 +824,8 @@ DEF("net", HAS_ARG, QEMU_OPTION_net, - " default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n" - " use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag; use\n" - " vnet_hdr=on to make the lack of IFF_VNET_HDR support an error condition\n" -+ " use vhost=on to enable experimental in kernel accelerator\n" -+ " use 'vhostfd=h' to connect to an already opened vhost net device\n" - #endif - "-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n" - " connect the vlan 'n' to another VLAN using a socket connection\n" --- -1.6.6.144.g5c3af diff --git a/qemu-v2-block-avoid-creating-too-large-iovecs-in-multiwrite_merge.patch b/qemu-v2-block-avoid-creating-too-large-iovecs-in-multiwrite_merge.patch deleted file mode 100644 index c9b918b..0000000 --- a/qemu-v2-block-avoid-creating-too-large-iovecs-in-multiwrite_merge.patch +++ /dev/null @@ -1,41 +0,0 @@ -If we go over the maximum number of iovecs support by syscall we get -back EINVAL from the kernel which translate to I/O errors for the guest. - -Add a MAX_IOV defintion for platforms that don't have it. For now we use -the same 1024 define that's used on Linux and various other platforms, -but until the windows block backend implements some kind of vectored I/O -it doesn't matter. - -Signed-off-by: Christoph Hellwig - -Index: qemu/block.c -=================================================================== ---- qemu.orig/block.c 2010-01-26 10:59:39.757004445 +0100 -+++ qemu/block.c 2010-01-26 11:01:38.056023231 +0100 -@@ -1689,6 +1689,10 @@ static int multiwrite_merge(BlockDriverS - merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]); - } - -+ if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) { -+ merge = 0; -+ } -+ - if (merge) { - size_t size; - QEMUIOVector *qiov = qemu_mallocz(sizeof(*qiov)); -Index: qemu/qemu-common.h -=================================================================== ---- qemu.orig/qemu-common.h 2010-01-26 14:41:40.894254285 +0100 -+++ qemu/qemu-common.h 2010-01-26 14:42:27.267275698 +0100 -@@ -54,6 +54,10 @@ struct iovec { - void *iov_base; - size_t iov_len; - }; -+/* -+ * Use the same value as Linux for now. -+ */ -+#define IOV_MAX 1024 - #else - #include - #endif - diff --git a/qemu-vhost-add-configure-check.patch b/qemu-vhost-add-configure-check.patch deleted file mode 100644 index 28ad946..0000000 --- a/qemu-vhost-add-configure-check.patch +++ /dev/null @@ -1,118 +0,0 @@ -Teach configure to check for vhost.h -and disable vhost_net if not present. - -Signed-off-by: Michael S. Tsirkin ' - ---- - -diff --git a/Makefile.target b/Makefile.target -index 2ebd30c..38783da 100644 ---- a/Makefile.target -+++ b/Makefile.target -@@ -168,7 +168,8 @@ obj-y = vl.o async.o monitor.o pci.o pci_host.o pcie_host.o machine.o gdbstub.o - # need to fix this properly - obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-pci.o virtio-serial-bus.o - obj-y += notifier.o --obj-y += vhost_net.o vhost.o -+obj-y += vhost_net.o -+obj-$(CONFIG_VHOST_NET) += vhost.o - obj-$(CONFIG_KVM) += kvm.o kvm-all.o - # MSI-X depends on kvm for interrupt injection, - # so moved it from Makefile.hw to Makefile.target for now -diff --git a/configure b/configure -index 88ba002..4994506 100755 ---- a/configure -+++ b/configure -@@ -1510,6 +1510,23 @@ EOF - fi - - ########################################## -+# test for vhost net -+ -+if test "$kvm" != "no"; then -+ cat > $TMPC < -+int main(void) { return 0; } -+EOF -+ if compile_prog "$kvm_cflags" "" ; then -+ vhost_net=yes -+ else -+ vhost_net=no -+ fi -+else -+ vhost_net=no -+fi -+ -+########################################## - # libpci probe for kvm_cap_device_assignment - if test $kvm_cap_device_assignment = "yes" ; then - cat > $TMPC << EOF -@@ -2058,6 +2075,7 @@ echo "fdt support $fdt" - echo "preadv support $preadv" - echo "fdatasync $fdatasync" - echo "uuid support $uuid" -+echo "vhost-net support $vhost_net" - - if test $sdl_too_old = "yes"; then - echo "-> Your SDL version is too old - please upgrade to have SDL support" -@@ -2593,6 +2611,9 @@ case "$target_arch2" in - if test $kvm_cap_device_assignment = "yes" ; then - echo "CONFIG_KVM_DEVICE_ASSIGNMENT=y" >> $config_target_mak - fi -+ if test $vhost_net = "yes" ; then -+ echo "CONFIG_VHOST_NET=y" >> $config_target_mak -+ fi - fi - esac - echo "TARGET_PHYS_ADDR_BITS=$target_phys_bits" >> $config_target_mak -diff --git a/hw/vhost_net.c b/hw/vhost_net.c -index c89ff40..cab9a0a 100644 ---- a/hw/vhost_net.c -+++ b/hw/vhost_net.c -@@ -16,9 +16,13 @@ - #include "net/tap.h" - - #include "virtio-net.h" --#include "vhost.h" - #include "vhost_net.h" - -+#include "config.h" -+ -+#ifdef CONFIG_VHOST_NET -+#include "vhost.h" -+ - struct vhost_net { - struct vhost_dev dev; - struct vhost_virtqueue vqs[2]; -@@ -145,3 +149,31 @@ void vhost_net_cleanup(struct vhost_net *net) - qemu_free(net); - } - /* TODO: log */ -+#else -+struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd) -+{ -+ return NULL; -+} -+ -+int vhost_net_start(struct vhost_net *net, -+ VirtIODevice *dev) -+{ -+ return -ENOSYS; -+} -+void vhost_net_stop(struct vhost_net *net, -+ VirtIODevice *dev) -+{ -+} -+ -+void vhost_net_cleanup(struct vhost_net *net) -+{ -+} -+ -+unsigned vhost_net_get_features(struct vhost_net *net, unsigned features) -+{ -+ return features; -+} -+void vhost_net_ack_features(struct vhost_net *net, unsigned features) -+{ -+} -+#endif diff --git a/qemu-vhost-vhost-net-support.patch b/qemu-vhost-vhost-net-support.patch deleted file mode 100644 index aea0418..0000000 --- a/qemu-vhost-vhost-net-support.patch +++ /dev/null @@ -1,869 +0,0 @@ -This adds vhost net support in qemu. Will be tied to tap device and -virtio by following patches. Raw backend is currently missing, will be -worked on/submitted separately. - -Signed-off-by: Michael S. Tsirkin ---- - Makefile.target | 1 + - hw/vhost.c | 603 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - hw/vhost.h | 44 ++++ - hw/vhost_net.c | 147 ++++++++++++++ - hw/vhost_net.h | 20 ++ - 5 files changed, 815 insertions(+), 0 deletions(-) - create mode 100644 hw/vhost.c - create mode 100644 hw/vhost.h - create mode 100644 hw/vhost_net.c - create mode 100644 hw/vhost_net.h - -diff --git a/Makefile.target b/Makefile.target -index 0c844a9..2ebd30c 100644 ---- a/Makefile.target -+++ b/Makefile.target -@@ -168,6 +168,7 @@ obj-y = vl.o async.o monitor.o pci.o pci_host.o pcie_host.o machine.o gdbstub.o - # need to fix this properly - obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-pci.o virtio-serial-bus.o - obj-y += notifier.o -+obj-y += vhost_net.o vhost.o - obj-$(CONFIG_KVM) += kvm.o kvm-all.o - # MSI-X depends on kvm for interrupt injection, - # so moved it from Makefile.hw to Makefile.target for now -diff --git a/hw/vhost.c b/hw/vhost.c -new file mode 100644 -index 0000000..e5c1ead ---- /dev/null -+++ b/hw/vhost.c -@@ -0,0 +1,603 @@ -+#include "linux/vhost.h" -+#include -+#include -+#include "vhost.h" -+#include "hw/hw.h" -+/* For range_get_last */ -+#include "pci.h" -+ -+static void vhost_dev_sync_region(struct vhost_dev *dev, -+ uint64_t mfirst, uint64_t mlast, -+ uint64_t rfirst, uint64_t rlast) -+{ -+ uint64_t start = MAX(mfirst, rfirst); -+ uint64_t end = MIN(mlast, rlast); -+ vhost_log_chunk_t *from = dev->log + start / VHOST_LOG_CHUNK; -+ vhost_log_chunk_t *to = dev->log + end / VHOST_LOG_CHUNK + 1; -+ uint64_t addr = (start / VHOST_LOG_CHUNK) * VHOST_LOG_CHUNK; -+ -+ assert(end / VHOST_LOG_CHUNK < dev->log_size); -+ assert(start / VHOST_LOG_CHUNK < dev->log_size); -+ if (end < start) { -+ return; -+ } -+ for (;from < to; ++from) { -+ vhost_log_chunk_t log; -+ int bit; -+ /* We first check with non-atomic: much cheaper, -+ * and we expect non-dirty to be the common case. */ -+ if (!*from) { -+ continue; -+ } -+ /* Data must be read atomically. We don't really -+ * need the barrier semantics of __sync -+ * builtins, but it's easier to use them than -+ * roll our own. */ -+ log = __sync_fetch_and_and(from, 0); -+ while ((bit = sizeof(log) > sizeof(int) ? -+ ffsll(log) : ffs(log))) { -+ bit -= 1; -+ cpu_physical_memory_set_dirty(addr + bit * VHOST_LOG_PAGE); -+ log &= ~(0x1ull << bit); -+ } -+ addr += VHOST_LOG_CHUNK; -+ } -+} -+ -+static int vhost_client_sync_dirty_bitmap(struct CPUPhysMemoryClient *client, -+ target_phys_addr_t start_addr, -+ target_phys_addr_t end_addr) -+{ -+ struct vhost_dev *dev = container_of(client, struct vhost_dev, client); -+ int i; -+ if (!dev->log_enabled || !dev->started) { -+ return 0; -+ } -+ for (i = 0; i < dev->mem->nregions; ++i) { -+ struct vhost_memory_region *reg = dev->mem->regions + i; -+ vhost_dev_sync_region(dev, start_addr, end_addr, -+ reg->guest_phys_addr, -+ range_get_last(reg->guest_phys_addr, -+ reg->memory_size)); -+ } -+ for (i = 0; i < dev->nvqs; ++i) { -+ struct vhost_virtqueue *vq = dev->vqs + i; -+ unsigned size = sizeof(struct vring_used_elem) * vq->num; -+ vhost_dev_sync_region(dev, start_addr, end_addr, vq->used_phys, -+ range_get_last(vq->used_phys, size)); -+ } -+ return 0; -+} -+ -+/* Assign/unassign. Keep an unsorted array of non-overlapping -+ * memory regions in dev->mem. */ -+static void vhost_dev_unassign_memory(struct vhost_dev *dev, -+ uint64_t start_addr, -+ uint64_t size) -+{ -+ int from, to, n = dev->mem->nregions; -+ /* Track overlapping/split regions for sanity checking. */ -+ int overlap_start = 0, overlap_end = 0, overlap_middle = 0, split = 0; -+ -+ for (from = 0, to = 0; from < n; ++from, ++to) { -+ struct vhost_memory_region *reg = dev->mem->regions + to; -+ uint64_t reglast; -+ uint64_t memlast; -+ uint64_t change; -+ -+ /* clone old region */ -+ if (to != from) { -+ memcpy(reg, dev->mem->regions + from, sizeof *reg); -+ } -+ -+ /* No overlap is simple */ -+ if (!ranges_overlap(reg->guest_phys_addr, reg->memory_size, -+ start_addr, size)) { -+ continue; -+ } -+ -+ /* Split only happens if supplied region -+ * is in the middle of an existing one. Thus it can not -+ * overlap with any other existing region. */ -+ assert(!split); -+ -+ reglast = range_get_last(reg->guest_phys_addr, reg->memory_size); -+ memlast = range_get_last(start_addr, size); -+ -+ /* Remove whole region */ -+ if (start_addr <= reg->guest_phys_addr && memlast >= reglast) { -+ --dev->mem->nregions; -+ --to; -+ assert(to >= 0); -+ ++overlap_middle; -+ continue; -+ } -+ -+ /* Shrink region */ -+ if (memlast >= reglast) { -+ reg->memory_size = start_addr - reg->guest_phys_addr; -+ assert(reg->memory_size); -+ assert(!overlap_end); -+ ++overlap_end; -+ continue; -+ } -+ -+ /* Shift region */ -+ if (start_addr <= reg->guest_phys_addr) { -+ change = memlast + 1 - reg->guest_phys_addr; -+ reg->memory_size -= change; -+ reg->guest_phys_addr += change; -+ reg->userspace_addr += change; -+ assert(reg->memory_size); -+ assert(!overlap_start); -+ ++overlap_start; -+ continue; -+ } -+ -+ /* This only happens if supplied region -+ * is in the middle of an existing one. Thus it can not -+ * overlap with any other existing region. */ -+ assert(!overlap_start); -+ assert(!overlap_end); -+ assert(!overlap_middle); -+ /* Split region: shrink first part, shift second part. */ -+ memcpy(dev->mem->regions + n, reg, sizeof *reg); -+ reg->memory_size = start_addr - reg->guest_phys_addr; -+ assert(reg->memory_size); -+ change = memlast + 1 - reg->guest_phys_addr; -+ reg = dev->mem->regions + n; -+ reg->memory_size -= change; -+ assert(reg->memory_size); -+ reg->guest_phys_addr += change; -+ reg->userspace_addr += change; -+ /* Never add more than 1 region */ -+ assert(dev->mem->nregions == n); -+ ++dev->mem->nregions; -+ ++split; -+ } -+} -+ -+/* Called after unassign, so no regions overlap the given range. */ -+static void vhost_dev_assign_memory(struct vhost_dev *dev, -+ uint64_t start_addr, -+ uint64_t size, -+ uint64_t uaddr) -+{ -+ int from, to; -+ struct vhost_memory_region *merged = NULL; -+ for (from = 0, to = 0; from < dev->mem->nregions; ++from, ++to) { -+ struct vhost_memory_region *reg = dev->mem->regions + to; -+ uint64_t prlast, urlast; -+ uint64_t pmlast, umlast; -+ uint64_t s, e, u; -+ -+ /* clone old region */ -+ if (to != from) { -+ memcpy(reg, dev->mem->regions + from, sizeof *reg); -+ } -+ prlast = range_get_last(reg->guest_phys_addr, reg->memory_size); -+ pmlast = range_get_last(start_addr, size); -+ urlast = range_get_last(reg->userspace_addr, reg->memory_size); -+ umlast = range_get_last(uaddr, size); -+ -+ /* check for overlapping regions: should never happen. */ -+ assert(prlast < start_addr || pmlast < reg->guest_phys_addr); -+ /* Not an adjacent or overlapping region - do not merge. */ -+ if ((prlast + 1 != start_addr || urlast + 1 != uaddr) && -+ (pmlast + 1 != reg->guest_phys_addr || -+ umlast + 1 != reg->userspace_addr)) { -+ continue; -+ } -+ -+ if (merged) { -+ --to; -+ assert(to >= 0); -+ } else { -+ merged = reg; -+ } -+ u = MIN(uaddr, reg->userspace_addr); -+ s = MIN(start_addr, reg->guest_phys_addr); -+ e = MAX(pmlast, prlast); -+ uaddr = merged->userspace_addr = u; -+ start_addr = merged->guest_phys_addr = s; -+ size = merged->memory_size = e - s + 1; -+ assert(merged->memory_size); -+ } -+ -+ if (!merged) { -+ struct vhost_memory_region *reg = dev->mem->regions + to; -+ memset(reg, 0, sizeof *reg); -+ reg->memory_size = size; -+ assert(reg->memory_size); -+ reg->guest_phys_addr = start_addr; -+ reg->userspace_addr = uaddr; -+ ++to; -+ } -+ assert(to <= dev->mem->nregions + 1); -+ dev->mem->nregions = to; -+} -+ -+static uint64_t vhost_get_log_size(struct vhost_dev *dev) -+{ -+ uint64_t log_size = 0; -+ int i; -+ for (i = 0; i < dev->mem->nregions; ++i) { -+ struct vhost_memory_region *reg = dev->mem->regions + i; -+ uint64_t last = range_get_last(reg->guest_phys_addr, -+ reg->memory_size); -+ log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1); -+ } -+ for (i = 0; i < dev->nvqs; ++i) { -+ struct vhost_virtqueue *vq = dev->vqs + i; -+ uint64_t last = vq->used_phys + -+ sizeof(struct vring_used_elem) * vq->num - 1; -+ log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1); -+ } -+ return log_size; -+} -+ -+static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size) -+{ -+ vhost_log_chunk_t *log; -+ int r; -+ if (size) { -+ log = qemu_mallocz(size * sizeof *log); -+ } else { -+ log = NULL; -+ } -+ r = ioctl(dev->control, VHOST_SET_LOG_BASE, -+ (uint64_t)(unsigned long)log); -+ assert(r >= 0); -+ vhost_client_sync_dirty_bitmap(&dev->client, 0, -+ (target_phys_addr_t)~0x0ull); -+ if (dev->log) { -+ qemu_free(dev->log); -+ } -+ dev->log = log; -+ dev->log_size = size; -+} -+ -+static void vhost_client_set_memory(CPUPhysMemoryClient *client, -+ target_phys_addr_t start_addr, -+ ram_addr_t size, -+ ram_addr_t phys_offset) -+{ -+ struct vhost_dev *dev = container_of(client, struct vhost_dev, client); -+ ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK; -+ int s = offsetof(struct vhost_memory, regions) + -+ (dev->mem->nregions + 1) * sizeof dev->mem->regions[0]; -+ uint64_t log_size; -+ int r; -+ dev->mem = qemu_realloc(dev->mem, s); -+ -+ assert(size); -+ -+ vhost_dev_unassign_memory(dev, start_addr, size); -+ if (flags == IO_MEM_RAM) { -+ /* Add given mapping, merging adjacent regions if any */ -+ vhost_dev_assign_memory(dev, start_addr, size, -+ (uintptr_t)qemu_get_ram_ptr(phys_offset)); -+ } else { -+ /* Remove old mapping for this memory, if any. */ -+ vhost_dev_unassign_memory(dev, start_addr, size); -+ } -+ -+ if (!dev->started) { -+ return; -+ } -+ if (!dev->log_enabled) { -+ r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); -+ assert(r >= 0); -+ return; -+ } -+ log_size = vhost_get_log_size(dev); -+ /* We allocate an extra 4K bytes to log, -+ * to reduce the * number of reallocations. */ -+#define VHOST_LOG_BUFFER (0x1000 / sizeof *dev->log) -+ /* To log more, must increase log size before table update. */ -+ if (dev->log_size < log_size) { -+ vhost_dev_log_resize(dev, log_size + VHOST_LOG_BUFFER); -+ } -+ r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); -+ assert(r >= 0); -+ /* To log less, can only decrease log size after table update. */ -+ if (dev->log_size > log_size + VHOST_LOG_BUFFER) { -+ vhost_dev_log_resize(dev, log_size); -+ } -+} -+ -+static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log) -+{ -+ uint64_t features = dev->acked_features; -+ int r; -+ if (dev->log_enabled) { -+ features |= 0x1 << VHOST_F_LOG_ALL; -+ } -+ r = ioctl(dev->control, VHOST_SET_FEATURES, &features); -+ return r < 0 ? -errno : 0; -+} -+ -+static int vhost_client_migration_log(struct CPUPhysMemoryClient *client, -+ int enable) -+{ -+ struct vhost_dev *dev = container_of(client, struct vhost_dev, client); -+ int r; -+ if (!!enable == dev->log_enabled) { -+ return 0; -+ } -+ if (!dev->started) { -+ dev->log_enabled = enable; -+ return 0; -+ } -+ if (!enable) { -+ r = vhost_dev_set_log(dev, false); -+ if (r < 0) { -+ return r; -+ } -+ if (dev->log) { -+ qemu_free(dev->log); -+ } -+ dev->log = NULL; -+ dev->log_size = 0; -+ } else { -+ vhost_dev_log_resize(dev, vhost_get_log_size(dev)); -+ r = vhost_dev_set_log(dev, false); -+ if (r < 0) { -+ return r; -+ } -+ } -+ dev->log_enabled = enable; -+ return 0; -+} -+ -+static int vhost_virtqueue_set_addr(struct vhost_dev *dev, -+ struct vhost_virtqueue *vq, -+ unsigned idx, bool enable_log) -+{ -+ struct vhost_vring_addr addr = { -+ .index = idx, -+ .desc_user_addr = (u_int64_t)(unsigned long)vq->desc, -+ .avail_user_addr = (u_int64_t)(unsigned long)vq->avail, -+ .used_user_addr = (u_int64_t)(unsigned long)vq->used, -+ .log_guest_addr = vq->used_phys, -+ .flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0, -+ }; -+ int r = ioctl(dev->control, VHOST_SET_VRING_ADDR, &addr); -+ if (r < 0) { -+ return -errno; -+ } -+ return 0; -+} -+ -+static int vhost_virtqueue_init(struct vhost_dev *dev, -+ struct VirtIODevice *vdev, -+ struct vhost_virtqueue *vq, -+ unsigned idx) -+{ -+ target_phys_addr_t s, l, a; -+ int r; -+ struct vhost_vring_file file = { -+ .index = idx, -+ }; -+ struct vhost_vring_state state = { -+ .index = idx, -+ }; -+ struct VirtQueue *q = virtio_queue(vdev, idx); -+ -+ vq->num = state.num = virtio_queue_get_num(vdev, idx); -+ r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state); -+ if (r) { -+ return -errno; -+ } -+ -+ state.num = virtio_queue_last_avail_idx(vdev, idx); -+ r = ioctl(dev->control, VHOST_SET_VRING_BASE, &state); -+ if (r) { -+ return -errno; -+ } -+ -+ s = l = sizeof(struct vring_desc) * vq->num; -+ a = virtio_queue_get_desc(vdev, idx); -+ vq->desc = cpu_physical_memory_map(a, &l, 0); -+ if (!vq->desc || l != s) { -+ r = -ENOMEM; -+ goto fail_alloc; -+ } -+ s = l = offsetof(struct vring_avail, ring) + -+ sizeof(u_int64_t) * vq->num; -+ a = virtio_queue_get_avail(vdev, idx); -+ vq->avail = cpu_physical_memory_map(a, &l, 0); -+ if (!vq->avail || l != s) { -+ r = -ENOMEM; -+ goto fail_alloc; -+ } -+ s = l = offsetof(struct vring_used, ring) + -+ sizeof(struct vring_used_elem) * vq->num; -+ vq->used_phys = a = virtio_queue_get_used(vdev, idx); -+ vq->used = cpu_physical_memory_map(a, &l, 1); -+ if (!vq->used || l != s) { -+ r = -ENOMEM; -+ goto fail_alloc; -+ } -+ -+ r = vhost_virtqueue_set_addr(dev, vq, idx, dev->log_enabled); -+ if (r < 0) { -+ r = -errno; -+ goto fail_alloc; -+ } -+ if (!vdev->binding->guest_notifier || !vdev->binding->host_notifier) { -+ fprintf(stderr, "binding does not support irqfd/queuefd\n"); -+ r = -ENOSYS; -+ goto fail_alloc; -+ } -+ r = vdev->binding->guest_notifier(vdev->binding_opaque, idx, true); -+ if (r < 0) { -+ fprintf(stderr, "Error binding guest notifier: %d\n", -r); -+ goto fail_guest_notifier; -+ } -+ -+ r = vdev->binding->host_notifier(vdev->binding_opaque, idx, true); -+ if (r < 0) { -+ fprintf(stderr, "Error binding host notifier: %d\n", -r); -+ goto fail_host_notifier; -+ } -+ -+ file.fd = event_notifier_get_fd(virtio_queue_host_notifier(q)); -+ r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file); -+ if (r) { -+ goto fail_kick; -+ } -+ -+ file.fd = event_notifier_get_fd(virtio_queue_guest_notifier(q)); -+ r = ioctl(dev->control, VHOST_SET_VRING_CALL, &file); -+ if (r) { -+ goto fail_call; -+ } -+ -+ return 0; -+ -+fail_call: -+fail_kick: -+ vdev->binding->host_notifier(vdev->binding_opaque, idx, false); -+fail_host_notifier: -+ vdev->binding->guest_notifier(vdev->binding_opaque, idx, false); -+fail_guest_notifier: -+fail_alloc: -+ return r; -+} -+ -+static void vhost_virtqueue_cleanup(struct vhost_dev *dev, -+ struct VirtIODevice *vdev, -+ struct vhost_virtqueue *vq, -+ unsigned idx) -+{ -+ struct vhost_vring_state state = { -+ .index = idx, -+ }; -+ int r; -+ r = vdev->binding->guest_notifier(vdev->binding_opaque, idx, false); -+ if (r < 0) { -+ fprintf(stderr, "vhost VQ %d guest cleanup failed: %d\n", idx, r); -+ fflush(stderr); -+ } -+ assert (r >= 0); -+ -+ r = vdev->binding->host_notifier(vdev->binding_opaque, idx, false); -+ if (r < 0) { -+ fprintf(stderr, "vhost VQ %d host cleanup failed: %d\n", idx, r); -+ fflush(stderr); -+ } -+ assert (r >= 0); -+ r = ioctl(dev->control, VHOST_GET_VRING_BASE, &state); -+ if (r < 0) { -+ fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r); -+ fflush(stderr); -+ } -+ virtio_queue_set_last_avail_idx(vdev, idx, state.num); -+ assert (r >= 0); -+} -+ -+int vhost_dev_init(struct vhost_dev *hdev, int devfd) -+{ -+ uint64_t features; -+ int r; -+ if (devfd >= 0) { -+ hdev->control = devfd; -+ } else { -+ hdev->control = open("/dev/vhost-net", O_RDWR); -+ if (hdev->control < 0) -+ return -errno; -+ } -+ r = ioctl(hdev->control, VHOST_SET_OWNER, NULL); -+ if (r < 0) -+ goto fail; -+ -+ r = ioctl(hdev->control, VHOST_GET_FEATURES, &features); -+ if (r < 0) -+ goto fail; -+ hdev->features = features; -+ -+ hdev->client.set_memory = vhost_client_set_memory; -+ hdev->client.sync_dirty_bitmap = vhost_client_sync_dirty_bitmap; -+ hdev->client.migration_log = vhost_client_migration_log; -+ hdev->mem = qemu_mallocz(offsetof(struct vhost_memory, regions)); -+ hdev->log = NULL; -+ hdev->log_size = 0; -+ hdev->log_enabled = false; -+ hdev->started = false; -+ cpu_register_phys_memory_client(&hdev->client); -+ return 0; -+fail: -+ r = -errno; -+ close(hdev->control); -+ return r; -+} -+ -+void vhost_dev_cleanup(struct vhost_dev *hdev) -+{ -+ cpu_unregister_phys_memory_client(&hdev->client); -+ qemu_free(hdev->mem); -+ close(hdev->control); -+} -+ -+int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) -+{ -+ int i, r; -+ -+ r = vhost_dev_set_log(hdev, hdev->log_enabled); -+ if (r < 0) -+ goto fail; -+ r = ioctl(hdev->control, VHOST_SET_MEM_TABLE, hdev->mem); -+ if (r < 0) { -+ r = -errno; -+ goto fail; -+ } -+ if (hdev->log_enabled) { -+ hdev->log_size = vhost_get_log_size(hdev); -+ hdev->log = hdev->log_size ? -+ qemu_mallocz(hdev->log_size * sizeof *hdev->log) : NULL; -+ r = ioctl(hdev->control, VHOST_SET_LOG_BASE, -+ (uint64_t)(unsigned long)hdev->log); -+ if (r < 0) { -+ r = -errno; -+ goto fail; -+ } -+ } -+ -+ for (i = 0; i < hdev->nvqs; ++i) { -+ r = vhost_virtqueue_init(hdev, -+ vdev, -+ hdev->vqs + i, -+ i); -+ if (r < 0) -+ goto fail_vq; -+ } -+ hdev->started = true; -+ -+ return 0; -+fail_vq: -+ while (--i >= 0) { -+ vhost_virtqueue_cleanup(hdev, -+ vdev, -+ hdev->vqs + i, -+ i); -+ } -+fail: -+ return r; -+} -+ -+void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) -+{ -+ int i; -+ for (i = 0; i < hdev->nvqs; ++i) { -+ vhost_virtqueue_cleanup(hdev, -+ vdev, -+ hdev->vqs + i, -+ i); -+ } -+ vhost_client_sync_dirty_bitmap(&hdev->client, 0, -+ (target_phys_addr_t)~0x0ull); -+ hdev->started = false; -+ qemu_free(hdev->log); -+ hdev->log_size = 0; -+} -diff --git a/hw/vhost.h b/hw/vhost.h -new file mode 100644 -index 0000000..2ed3933 ---- /dev/null -+++ b/hw/vhost.h -@@ -0,0 +1,44 @@ -+#ifndef VHOST_H -+#define VHOST_H -+ -+#include "hw/hw.h" -+#include "hw/virtio.h" -+ -+/* Generic structures common for any vhost based device. */ -+struct vhost_virtqueue { -+ int kick; -+ int call; -+ void *desc; -+ void *avail; -+ void *used; -+ int num; -+ unsigned long long used_phys; -+}; -+ -+typedef unsigned long vhost_log_chunk_t; -+#define VHOST_LOG_PAGE 0x1000 -+#define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t)) -+#define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS) -+ -+struct vhost_memory; -+struct vhost_dev { -+ CPUPhysMemoryClient client; -+ int control; -+ struct vhost_memory *mem; -+ struct vhost_virtqueue *vqs; -+ int nvqs; -+ unsigned long long features; -+ unsigned long long acked_features; -+ unsigned long long backend_features; -+ bool started; -+ bool log_enabled; -+ vhost_log_chunk_t *log; -+ unsigned long long log_size; -+}; -+ -+int vhost_dev_init(struct vhost_dev *hdev, int devfd); -+void vhost_dev_cleanup(struct vhost_dev *hdev); -+int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); -+void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); -+ -+#endif -diff --git a/hw/vhost_net.c b/hw/vhost_net.c -new file mode 100644 -index 0000000..c89ff40 ---- /dev/null -+++ b/hw/vhost_net.c -@@ -0,0 +1,147 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "net.h" -+#include "net/tap.h" -+ -+#include "virtio-net.h" -+#include "vhost.h" -+#include "vhost_net.h" -+ -+struct vhost_net { -+ struct vhost_dev dev; -+ struct vhost_virtqueue vqs[2]; -+ int backend; -+ VLANClientState *vc; -+}; -+ -+unsigned vhost_net_get_features(struct vhost_net *net, unsigned features) -+{ -+ /* Clear features not supported by host kernel. */ -+ if (!(net->dev.features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY))) -+ features &= ~(1 << VIRTIO_F_NOTIFY_ON_EMPTY); -+ if (!(net->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) -+ features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC); -+ if (!(net->dev.features & (1 << VIRTIO_NET_F_MRG_RXBUF))) -+ features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF); -+ return features; -+} -+ -+void vhost_net_ack_features(struct vhost_net *net, unsigned features) -+{ -+ net->dev.acked_features = net->dev.backend_features; -+ if (features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) -+ net->dev.acked_features |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY); -+ if (features & (1 << VIRTIO_RING_F_INDIRECT_DESC)) -+ net->dev.acked_features |= (1 << VIRTIO_RING_F_INDIRECT_DESC); -+} -+ -+static int vhost_net_get_fd(VLANClientState *backend) -+{ -+ switch (backend->info->type) { -+ case NET_CLIENT_TYPE_TAP: -+ return tap_get_fd(backend); -+ default: -+ fprintf(stderr, "vhost-net requires tap backend\n"); -+ return -EBADFD; -+ } -+} -+ -+struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd) -+{ -+ int r; -+ struct vhost_net *net = qemu_malloc(sizeof *net); -+ if (!backend) { -+ fprintf(stderr, "vhost-net requires backend to be setup\n"); -+ goto fail; -+ } -+ r = vhost_net_get_fd(backend); -+ if (r < 0) -+ goto fail; -+ net->vc = backend; -+ net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 : -+ (1 << VHOST_NET_F_VIRTIO_NET_HDR); -+ net->backend = r; -+ -+ r = vhost_dev_init(&net->dev, devfd); -+ if (r < 0) -+ goto fail; -+ if (~net->dev.features & net->dev.backend_features) { -+ fprintf(stderr, "vhost lacks feature mask %llu for backend\n", -+ ~net->dev.features & net->dev.backend_features); -+ vhost_dev_cleanup(&net->dev); -+ goto fail; -+ } -+ -+ /* Set sane init value. Override when guest acks. */ -+ vhost_net_ack_features(net, 0); -+ return net; -+fail: -+ qemu_free(net); -+ return NULL; -+} -+ -+int vhost_net_start(struct vhost_net *net, -+ VirtIODevice *dev) -+{ -+ struct vhost_vring_file file = { }; -+ int r; -+ -+ net->dev.nvqs = 2; -+ net->dev.vqs = net->vqs; -+ r = vhost_dev_start(&net->dev, dev); -+ if (r < 0) -+ return r; -+ -+ net->vc->info->poll(net->vc, false); -+ qemu_set_fd_handler(net->backend, NULL, NULL, NULL); -+ file.fd = net->backend; -+ for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { -+ r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file); -+ if (r < 0) { -+ r = -errno; -+ goto fail; -+ } -+ } -+ return 0; -+fail: -+ file.fd = -1; -+ while (--file.index >= 0) { -+ int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file); -+ assert(r >= 0); -+ } -+ net->vc->info->poll(net->vc, true); -+ vhost_dev_stop(&net->dev, dev); -+ return r; -+} -+ -+void vhost_net_stop(struct vhost_net *net, -+ VirtIODevice *dev) -+{ -+ struct vhost_vring_file file = { .fd = -1 }; -+ -+ for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { -+ int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file); -+ assert(r >= 0); -+ } -+ net->vc->info->poll(net->vc, true); -+ vhost_dev_stop(&net->dev, dev); -+} -+ -+void vhost_net_cleanup(struct vhost_net *net) -+{ -+ vhost_dev_cleanup(&net->dev); -+ qemu_free(net); -+} -+/* TODO: log */ -diff --git a/hw/vhost_net.h b/hw/vhost_net.h -new file mode 100644 -index 0000000..21f0277 ---- /dev/null -+++ b/hw/vhost_net.h -@@ -0,0 +1,20 @@ -+#ifndef VHOST_NET_H -+#define VHOST_NET_H -+ -+#include "net.h" -+ -+struct vhost_net; -+ -+struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd); -+ -+int vhost_net_start(struct vhost_net *net, -+ VirtIODevice *dev); -+void vhost_net_stop(struct vhost_net *net, -+ VirtIODevice *dev); -+ -+void vhost_net_cleanup(struct vhost_net *net); -+ -+unsigned vhost_net_get_features(struct vhost_net *net, unsigned features); -+void vhost_net_ack_features(struct vhost_net *net, unsigned features); -+ -+#endif --- -1.6.6.144.g5c3af diff --git a/qemu-virtio-Remove-duplicate-macro-definition-for-max.-v.patch b/qemu-virtio-Remove-duplicate-macro-definition-for-max.-v.patch deleted file mode 100644 index e5fa7e7..0000000 --- a/qemu-virtio-Remove-duplicate-macro-definition-for-max.-v.patch +++ /dev/null @@ -1,47 +0,0 @@ -From c11631e8bc91a1d1be2b89196e886a1385820dfb Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Wed, 20 Jan 2010 00:36:51 +0530 -Subject: [PATCH 1/9] virtio: Remove duplicate macro definition for max. virtqueues, bump up the max - -VIRTIO_PCI_QUEUE_MAX is redefined in hw/virtio.c. Let's just keep it in -hw/virtio.h. - -Also, bump up the value of the maximum allowed virtqueues to 64. This is -in preparation to allow multiple ports per virtio-console device. - -Signed-off-by: Amit Shah -Signed-off-by: Anthony Liguori ---- - hw/virtio.c | 2 -- - hw/virtio.h | 2 +- - 2 files changed, 1 insertions(+), 3 deletions(-) - -diff --git a/hw/virtio.c b/hw/virtio.c -index cecd0dc..88f4e78 100644 ---- a/hw/virtio.c -+++ b/hw/virtio.c -@@ -75,8 +75,6 @@ struct VirtQueue - void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq); - }; - --#define VIRTIO_PCI_QUEUE_MAX 16 -- - /* virt queue functions */ - static void virtqueue_init(VirtQueue *vq) - { -diff --git a/hw/virtio.h b/hw/virtio.h -index 35532a6..051910a 100644 ---- a/hw/virtio.h -+++ b/hw/virtio.h -@@ -90,7 +90,7 @@ typedef struct { - unsigned (*get_features)(void * opaque); - } VirtIOBindings; - --#define VIRTIO_PCI_QUEUE_MAX 16 -+#define VIRTIO_PCI_QUEUE_MAX 64 - - #define VIRTIO_NO_VECTOR 0xffff - --- -1.6.2.5 - diff --git a/qemu-virtio-add-APIs-for-queue-fields.patch b/qemu-virtio-add-APIs-for-queue-fields.patch deleted file mode 100644 index e2a57ed..0000000 --- a/qemu-virtio-add-APIs-for-queue-fields.patch +++ /dev/null @@ -1,111 +0,0 @@ -vhost needs physical addresses for ring and other queue fields, -so add APIs for these. - -Signed-off-by: Michael S. Tsirkin ---- - hw/virtio.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- - hw/virtio.h | 10 +++++++++- - 2 files changed, 56 insertions(+), 5 deletions(-) - -diff --git a/hw/virtio.c b/hw/virtio.c -index c2b80aa..b16ee1a 100644 ---- a/hw/virtio.c -+++ b/hw/virtio.c -@@ -73,6 +73,9 @@ struct VirtQueue - int inuse; - uint16_t vector; - void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq); -+ VirtIODevice *vdev; -+ EventNotifier guest_notifier; -+ EventNotifier host_notifier; - }; - - /* virt queue functions */ -@@ -594,10 +597,10 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, - return &vdev->vq[i]; - } - --void virtio_irq(VirtIODevice *vdev, VirtQueue *vq) -+void virtio_irq(VirtQueue *vq) - { -- vdev->isr |= 0x01; -- virtio_notify_vector(vdev, vq->vector); -+ vq->vdev->isr |= 0x01; -+ virtio_notify_vector(vq->vdev, vq->vector); - } - - void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) -@@ -608,7 +611,8 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) - (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx))) - return; - -- virtio_irq(vdev, vq); -+ vdev->isr |= 0x01; -+ virtio_notify_vector(vdev, vq->vector); - } - - void virtio_notify_config(VirtIODevice *vdev) -@@ -742,3 +746,42 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding, - vdev->binding = binding; - vdev->binding_opaque = opaque; - } -+ -+target_phys_addr_t virtio_queue_get_desc(VirtIODevice *vdev, int n) -+{ -+ return vdev->vq[n].vring.desc; -+} -+ -+target_phys_addr_t virtio_queue_get_avail(VirtIODevice *vdev, int n) -+{ -+ return vdev->vq[n].vring.avail; -+} -+ -+target_phys_addr_t virtio_queue_get_used(VirtIODevice *vdev, int n) -+{ -+ return vdev->vq[n].vring.used; -+} -+ -+uint16_t virtio_queue_last_avail_idx(VirtIODevice *vdev, int n) -+{ -+ return vdev->vq[n].last_avail_idx; -+} -+ -+void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx) -+{ -+ vdev->vq[n].last_avail_idx = idx; -+} -+ -+VirtQueue *virtio_queue(VirtIODevice *vdev, int n) -+{ -+ return vdev->vq + n; -+} -+ -+EventNotifier *virtio_queue_guest_notifier(VirtQueue *vq) -+{ -+ return &vq->guest_notifier; -+} -+EventNotifier *virtio_queue_host_notifier(VirtQueue *vq) -+{ -+ return &vq->host_notifier; -+} -diff --git a/hw/virtio.h b/hw/virtio.h -index 10a0959..f140ca3 100644 ---- a/hw/virtio.h -+++ b/hw/virtio.h -@@ -183,5 +183,13 @@ void virtio_net_exit(VirtIODevice *vdev); - DEFINE_PROP_BIT("indirect_desc", _state, _field, \ - VIRTIO_RING_F_INDIRECT_DESC, true) - --void virtio_irq(VirtIODevice *vdev, VirtQueue *vq); -+target_phys_addr_t virtio_queue_get_desc(VirtIODevice *vdev, int n); -+target_phys_addr_t virtio_queue_get_avail(VirtIODevice *vdev, int n); -+target_phys_addr_t virtio_queue_get_used(VirtIODevice *vdev, int n); -+uint16_t virtio_queue_last_avail_idx(VirtIODevice *vdev, int n); -+void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx); -+VirtQueue *virtio_queue(VirtIODevice *vdev, int n); -+EventNotifier *virtio_queue_guest_notifier(VirtQueue *vq); -+EventNotifier *virtio_queue_host_notifier(VirtQueue *vq); -+void virtio_irq(VirtQueue *vq); - #endif --- -1.6.6.144.g5c3af diff --git a/qemu-virtio-add-features-as-qdev-properties.patch b/qemu-virtio-add-features-as-qdev-properties.patch deleted file mode 100644 index fc9bcac..0000000 --- a/qemu-virtio-add-features-as-qdev-properties.patch +++ /dev/null @@ -1,400 +0,0 @@ -Add feature bits as properties to virtio. This makes it possible to e.g. define -machine without indirect buffer support, which is required for 0.10 -compatibility, or without hardware checksum support, which is required for 0.11 -compatibility. Since default values for optional features are now set by qdev, -get_features callback has been modified: it sets non-optional bits, and clears -bits not supported by host. - -Signed-off-by: Michael S. Tsirkin -Acked-by: Gerd Hoffmann -Signed-off-by: Anthony Liguori -(cherry picked from commit 8172539d21a03e982aa7f139ddc1607dc1422045) ---- - hw/s390-virtio-bus.c | 12 +++++++++--- - hw/s390-virtio-bus.h | 1 + - hw/syborg_virtio.c | 13 ++++++++----- - hw/virtio-balloon.c | 4 ++-- - hw/virtio-blk.c | 6 +----- - hw/virtio-blk.h | 8 ++++++++ - hw/virtio-net.c | 39 ++++++++++++++++----------------------- - hw/virtio-net.h | 20 ++++++++++++++++++++ - hw/virtio-pci.c | 25 +++++++++++++++++-------- - hw/virtio.c | 2 +- - hw/virtio.h | 7 ++++++- - 12 files changed, 91 insertions(+), 50 deletions(-) - ---- a/hw/s390-virtio-bus.c 2010-02-09 00:18:58.000000000 -0600 -+++ b/hw/s390-virtio-bus.c 2010-02-09 00:02:12.000000000 -0600 -@@ -101,6 +101,7 @@ static int s390_virtio_device_init(VirtI - bus->dev_offs += dev_len; - - virtio_bind_device(vdev, &virtio_s390_bindings, dev); -+ dev->host_features = vdev->get_features(vdev, dev->host_features); - s390_virtio_device_sync(dev); - - return 0; -@@ -222,9 +223,7 @@ static void s390_virtio_device_sync(Virt - cur_offs += num_vq * VIRTIO_VQCONFIG_LEN; - - /* Sync feature bitmap */ -- if (dev->vdev->get_features) { -- stl_phys(cur_offs, dev->vdev->get_features(dev->vdev)); -- } -+ stl_phys(cur_offs, dev->host_features); - - dev->feat_offs = cur_offs + dev->feat_len; - cur_offs += dev->feat_len * 2; -@@ -310,10 +309,17 @@ static void virtio_s390_notify(void *opa - kvm_s390_virtio_irq(s390_cpu_addr2state(0), 0, token); - } - -+static unsigned virtio_s390_get_features(void *opaque) -+{ -+ VirtIOS390Device *dev = (VirtIOS390Device*)opaque; -+ return dev->host_features; -+} -+ - /**************** S390 Virtio Bus Device Descriptions *******************/ - - static const VirtIOBindings virtio_s390_bindings = { - .notify = virtio_s390_notify, -+ .get_features = virtio_s390_get_features, - }; - - static VirtIOS390DeviceInfo s390_virtio_net = { ---- a/hw/s390-virtio-bus.h 2010-02-09 00:18:58.000000000 -0600 -+++ b/s390-virtio-bus.h 2010-02-09 00:18:16.000000000 -0600 -@@ -40,6 +40,7 @@ typedef struct VirtIOS390Device { - VirtIODevice *vdev; - DriveInfo *dinfo; - NICConf nic; -+ uint32_t host_features; - /* Max. number of ports we can have for a the virtio-serial device */ - uint32_t max_virtserial_ports; - } VirtIOS390Device; ---- a/hw/syborg_virtio.c 2010-02-09 00:18:58.000000000 -0600 -+++ b/hw/syborg_virtio.c 2010-02-09 00:02:12.000000000 -0600 -@@ -25,6 +25,7 @@ - #include "syborg.h" - #include "sysbus.h" - #include "virtio.h" -+#include "virtio-net.h" - #include "sysemu.h" - - //#define DEBUG_SYBORG_VIRTIO -@@ -66,6 +67,7 @@ typedef struct { - uint32_t int_enable; - uint32_t id; - NICConf nic; -+ uint32_t host_features; - } SyborgVirtIOProxy; - - static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset) -@@ -86,8 +88,7 @@ static uint32_t syborg_virtio_readl(void - ret = s->id; - break; - case SYBORG_VIRTIO_HOST_FEATURES: -- ret = vdev->get_features(vdev); -- ret |= vdev->binding->get_features(s); -+ ret = s->host_features; - break; - case SYBORG_VIRTIO_GUEST_FEATURES: - ret = vdev->guest_features; -@@ -244,9 +245,8 @@ static void syborg_virtio_update_irq(voi - - static unsigned syborg_virtio_get_features(void *opaque) - { -- unsigned ret = 0; -- ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY); -- return ret; -+ SyborgVirtIOProxy *proxy = opaque; -+ return proxy->host_features; - } - - static VirtIOBindings syborg_virtio_bindings = { -@@ -272,6 +272,8 @@ static int syborg_virtio_init(SyborgVirt - qemu_register_reset(virtio_reset, vdev); - - virtio_bind_device(vdev, &syborg_virtio_bindings, proxy); -+ proxy->host_features |= (0x1 << VIRTIO_F_NOTIFY_ON_EMPTY); -+ proxy->host_features = vdev->get_features(vdev, proxy->host_features); - return 0; - } - -@@ -292,6 +294,7 @@ static SysBusDeviceInfo syborg_virtio_ne - .qdev.size = sizeof(SyborgVirtIOProxy), - .qdev.props = (Property[]) { - DEFINE_NIC_PROPERTIES(SyborgVirtIOProxy, nic), -+ DEFINE_VIRTIO_NET_FEATURES(SyborgVirtIOProxy, host_features), - DEFINE_PROP_END_OF_LIST(), - } - }; ---- a/hw/virtio-balloon.c 2010-01-18 12:48:25.000000000 -0600 -+++ b/hw/virtio-balloon.c 2010-02-09 00:02:12.000000000 -0600 -@@ -125,9 +125,9 @@ static void virtio_balloon_set_config(Vi - dev->actual = config.actual; - } - --static uint32_t virtio_balloon_get_features(VirtIODevice *vdev) -+static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f) - { -- return 0; -+ return f; - } - - static ram_addr_t virtio_balloon_to_target(void *opaque, ram_addr_t target) ---- a/hw/virtio-blk.c 2010-01-18 12:48:25.000000000 -0600 -+++ b/hw/virtio-blk.c 2010-02-09 00:02:12.000000000 -0600 -@@ -432,19 +432,15 @@ static void virtio_blk_update_config(Vir - memcpy(config, &blkcfg, s->config_size); - } - --static uint32_t virtio_blk_get_features(VirtIODevice *vdev) -+static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features) - { - VirtIOBlock *s = to_virtio_blk(vdev); -- uint32_t features = 0; - - features |= (1 << VIRTIO_BLK_F_SEG_MAX); - features |= (1 << VIRTIO_BLK_F_GEOMETRY); - - if (bdrv_enable_write_cache(s->bs)) - features |= (1 << VIRTIO_BLK_F_WCACHE); --#ifdef __linux__ -- features |= (1 << VIRTIO_BLK_F_SCSI); --#endif - if (strcmp(s->serial_str, "0")) - features |= 1 << VIRTIO_BLK_F_IDENTIFY; - ---- a/hw/virtio-blk.h 2010-01-18 12:48:25.000000000 -0600 -+++ b/hw/virtio-blk.h 2010-02-09 00:02:12.000000000 -0600 -@@ -92,4 +92,12 @@ struct virtio_scsi_inhdr - uint32_t residual; - }; - -+#ifdef __linux__ -+#define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \ -+ DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \ -+ DEFINE_PROP_BIT("scsi", _state, _field, VIRTIO_BLK_F_SCSI, true) -+#else -+#define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \ -+ DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) -+#endif - #endif ---- a/hw/virtio.c 2010-02-09 00:18:58.000000000 -0600 -+++ b/hw/virtio.c 2010-02-09 00:02:12.000000000 -0600 -@@ -650,7 +650,7 @@ int virtio_load(VirtIODevice *vdev, QEMU - { - int num, i, ret; - uint32_t features; -- uint32_t supported_features = vdev->get_features(vdev) | -+ uint32_t supported_features = - vdev->binding->get_features(vdev->binding_opaque); - - if (vdev->binding->load_config) { ---- a/hw/virtio.h 2010-02-09 00:18:58.000000000 -0600 -+++ bhw/virtio.h 2010-02-09 00:02:12.000000000 -0600 -@@ -105,7 +105,7 @@ struct VirtIODevice - void *config; - uint16_t config_vector; - int nvectors; -- uint32_t (*get_features)(VirtIODevice *vdev); -+ uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features); - uint32_t (*bad_features)(VirtIODevice *vdev); - void (*set_features)(VirtIODevice *vdev, uint32_t val); - void (*get_config)(VirtIODevice *vdev, uint8_t *config); -@@ -176,4 +176,9 @@ VirtIODevice *virtio_balloon_init(Device - - void virtio_net_exit(VirtIODevice *vdev); - -+#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \ -+ DEFINE_PROP_BIT("indirect_desc", _state, _field, \ -+ VIRTIO_RING_F_INDIRECT_DESC, true) -+ -+ - #endif ---- a/hw/virtio-net.c 2010-02-09 00:18:58.000000000 -0600 -+++ b/hw/virtio-net.c 2010-02-09 00:02:12.000000000 -0600 -@@ -147,34 +147,27 @@ static int peer_has_ufo(VirtIONet *n) - return n->has_ufo; - } - --static uint32_t virtio_net_get_features(VirtIODevice *vdev) -+static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features) - { - VirtIONet *n = to_virtio_net(vdev); -- uint32_t features = (1 << VIRTIO_NET_F_MAC) | -- (1 << VIRTIO_NET_F_MRG_RXBUF) | -- (1 << VIRTIO_NET_F_STATUS) | -- (1 << VIRTIO_NET_F_CTRL_VQ) | -- (1 << VIRTIO_NET_F_CTRL_RX) | -- (1 << VIRTIO_NET_F_CTRL_VLAN) | -- (1 << VIRTIO_NET_F_CTRL_RX_EXTRA); - - if (peer_has_vnet_hdr(n)) { - tap_using_vnet_hdr(n->nic->nc.peer, 1); -+ } else { -+ features &= ~(0x1 << VIRTIO_NET_F_CSUM); -+ features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO4); -+ features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO6); -+ features &= ~(0x1 << VIRTIO_NET_F_HOST_ECN); -+ -+ features &= ~(0x1 << VIRTIO_NET_F_GUEST_CSUM); -+ features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO4); -+ features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO6); -+ features &= ~(0x1 << VIRTIO_NET_F_GUEST_ECN); -+ } - -- features |= (1 << VIRTIO_NET_F_CSUM); -- features |= (1 << VIRTIO_NET_F_HOST_TSO4); -- features |= (1 << VIRTIO_NET_F_HOST_TSO6); -- features |= (1 << VIRTIO_NET_F_HOST_ECN); -- -- features |= (1 << VIRTIO_NET_F_GUEST_CSUM); -- features |= (1 << VIRTIO_NET_F_GUEST_TSO4); -- features |= (1 << VIRTIO_NET_F_GUEST_TSO6); -- features |= (1 << VIRTIO_NET_F_GUEST_ECN); -- -- if (peer_has_ufo(n)) { -- features |= (1 << VIRTIO_NET_F_GUEST_UFO); -- features |= (1 << VIRTIO_NET_F_HOST_UFO); -- } -+ if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) { -+ features &= ~(0x1 << VIRTIO_NET_F_GUEST_UFO); -+ features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO); - } - - return features; -@@ -192,7 +185,7 @@ static uint32_t virtio_net_bad_features( - features |= (1 << VIRTIO_NET_F_HOST_TSO6); - features |= (1 << VIRTIO_NET_F_HOST_ECN); - -- return features & virtio_net_get_features(vdev); -+ return features; - } - - static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features) ---- a/hw/virtio-net.h 2010-01-18 12:48:25.000000000 -0600 -+++ b/hw/virtio-net.h 2010-02-09 00:02:12.000000000 -0600 -@@ -153,4 +153,24 @@ struct virtio_net_ctrl_mac { - #define VIRTIO_NET_CTRL_VLAN_ADD 0 - #define VIRTIO_NET_CTRL_VLAN_DEL 1 - -+#define DEFINE_VIRTIO_NET_FEATURES(_state, _field) \ -+ DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \ -+ DEFINE_PROP_BIT("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \ -+ DEFINE_PROP_BIT("guest_csum", _state, _field, VIRTIO_NET_F_GUEST_CSUM, true), \ -+ DEFINE_PROP_BIT("mac", _state, _field, VIRTIO_NET_F_MAC, true), \ -+ DEFINE_PROP_BIT("gso", _state, _field, VIRTIO_NET_F_GSO, true), \ -+ DEFINE_PROP_BIT("guest_tso4", _state, _field, VIRTIO_NET_F_GUEST_TSO4, true), \ -+ DEFINE_PROP_BIT("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \ -+ DEFINE_PROP_BIT("guest_ecn", _state, _field, VIRTIO_NET_F_GUEST_ECN, true), \ -+ DEFINE_PROP_BIT("guest_ufo", _state, _field, VIRTIO_NET_F_GUEST_UFO, true), \ -+ DEFINE_PROP_BIT("host_tso4", _state, _field, VIRTIO_NET_F_HOST_TSO4, true), \ -+ DEFINE_PROP_BIT("host_tso6", _state, _field, VIRTIO_NET_F_HOST_TSO6, true), \ -+ DEFINE_PROP_BIT("host_ecn", _state, _field, VIRTIO_NET_F_HOST_ECN, true), \ -+ DEFINE_PROP_BIT("host_ufo", _state, _field, VIRTIO_NET_F_HOST_UFO, true), \ -+ DEFINE_PROP_BIT("mrg_rxbuf", _state, _field, VIRTIO_NET_F_MRG_RXBUF, true), \ -+ DEFINE_PROP_BIT("status", _state, _field, VIRTIO_NET_F_STATUS, true), \ -+ DEFINE_PROP_BIT("ctrl_vq", _state, _field, VIRTIO_NET_F_CTRL_VQ, true), \ -+ DEFINE_PROP_BIT("ctrl_rx", _state, _field, VIRTIO_NET_F_CTRL_RX, true), \ -+ DEFINE_PROP_BIT("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \ -+ DEFINE_PROP_BIT("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true) - #endif ---- a/hw/virtio-pci.c 2010-02-09 00:18:58.000000000 -0600 -+++ b/hw/virtio-pci.c 2010-02-09 00:16:13.000000000 -0600 -@@ -16,6 +16,8 @@ - #include - - #include "virtio.h" -+#include "virtio-blk.h" -+#include "virtio-net.h" - #include "pci.h" - #include "sysemu.h" - #include "msix.h" -@@ -92,6 +94,7 @@ typedef struct { - uint32_t nvectors; - DriveInfo *dinfo; - NICConf nic; -+ uint32_t host_features; - /* Max. number of ports we can have for a the virtio-serial device */ - uint32_t max_virtserial_ports; - } VirtIOPCIProxy; -@@ -177,7 +180,7 @@ static void virtio_ioport_write(void *op - /* Guest does not negotiate properly? We have to assume nothing. */ - if (val & (1 << VIRTIO_F_BAD_FEATURE)) { - if (vdev->bad_features) -- val = vdev->bad_features(vdev); -+ val = proxy->host_features & vdev->bad_features(vdev); - else - val = 0; - } -@@ -237,8 +240,7 @@ static uint32_t virtio_ioport_read(VirtI - - switch (addr) { - case VIRTIO_PCI_HOST_FEATURES: -- ret = vdev->get_features(vdev); -- ret |= vdev->binding->get_features(proxy); -+ ret = proxy->host_features; - break; - case VIRTIO_PCI_GUEST_FEATURES: - ret = vdev->guest_features; -@@ -384,11 +386,8 @@ static void virtio_write_config(PCIDevic - - static unsigned virtio_pci_get_features(void *opaque) - { -- unsigned ret = 0; -- ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY); -- ret |= (1 << VIRTIO_RING_F_INDIRECT_DESC); -- ret |= (1 << VIRTIO_F_BAD_FEATURE); -- return ret; -+ VirtIOPCIProxy *proxy = opaque; -+ return proxy->host_features; - } - - static const VirtIOBindings virtio_pci_bindings = { -@@ -444,6 +443,9 @@ static void virtio_init_pci(VirtIOPCIPro - virtio_map); - - virtio_bind_device(vdev, &virtio_pci_bindings, proxy); -+ proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY; -+ proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE; -+ proxy->host_features = vdev->get_features(vdev, proxy->host_features); - } - - static int virtio_blk_init_pci(PCIDevice *pci_dev) -@@ -558,6 +560,7 @@ static PCIDeviceInfo virtio_info[] = { - DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), - DEFINE_PROP_DRIVE("drive", VirtIOPCIProxy, dinfo), - DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), -+ DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_PROP_END_OF_LIST(), - }, - .qdev.reset = virtio_pci_reset, -@@ -569,6 +572,7 @@ static PCIDeviceInfo virtio_info[] = { - .romfile = "pxe-virtio.bin", - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3), -+ DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic), - DEFINE_PROP_END_OF_LIST(), - }, -@@ -582,6 +586,7 @@ static PCIDeviceInfo virtio_info[] = { - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 0), - DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), -+ DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, max_virtserial_ports, - 31), - DEFINE_PROP_END_OF_LIST(), -@@ -592,6 +597,10 @@ static PCIDeviceInfo virtio_info[] = { - .qdev.size = sizeof(VirtIOPCIProxy), - .init = virtio_balloon_init_pci, - .exit = virtio_exit_pci, -+ .qdev.props = (Property[]) { -+ DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), -+ DEFINE_PROP_END_OF_LIST(), -+ }, - .qdev.reset = virtio_pci_reset, - },{ - /* end of list */ diff --git a/qemu-virtio-add-notifier-support.patch b/qemu-virtio-add-notifier-support.patch deleted file mode 100644 index 7a58ad2..0000000 --- a/qemu-virtio-add-notifier-support.patch +++ /dev/null @@ -1,78 +0,0 @@ -Add binding API to set host/guest notifiers. -Will be used by vhost. - -Signed-off-by: Michael S. Tsirkin ---- - hw/virtio.c | 13 ++++++++++--- - hw/virtio.h | 5 ++++- - 2 files changed, 14 insertions(+), 4 deletions(-) - -diff --git a/hw/virtio.c b/hw/virtio.c -index fa7184a..c2b80aa 100644 ---- a/hw/virtio.c -+++ b/hw/virtio.c -@@ -594,6 +594,12 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, - return &vdev->vq[i]; - } - -+void virtio_irq(VirtIODevice *vdev, VirtQueue *vq) -+{ -+ vdev->isr |= 0x01; -+ virtio_notify_vector(vdev, vq->vector); -+} -+ - void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) - { - /* Always notify when queue is empty (when feature acknowledge) */ -@@ -602,8 +608,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) - (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx))) - return; - -- vdev->isr |= 0x01; -- virtio_notify_vector(vdev, vq->vector); -+ virtio_irq(vdev, vq); - } - - void virtio_notify_config(VirtIODevice *vdev) -@@ -716,8 +721,10 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, - vdev->queue_sel = 0; - vdev->config_vector = VIRTIO_NO_VECTOR; - vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX); -- for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) -+ for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { - vdev->vq[i].vector = VIRTIO_NO_VECTOR; -+ vdev->vq[i].vdev = vdev; -+ } - - vdev->name = name; - vdev->config_len = config_size; -diff --git a/hw/virtio.h b/hw/virtio.h -index 3994cc9..10a0959 100644 ---- a/hw/virtio.h -+++ b/hw/virtio.h -@@ -18,6 +18,7 @@ - #include "net.h" - #include "qdev.h" - #include "sysemu.h" -+#include "notifier.h" - - /* from Linux's linux/virtio_config.h */ - -@@ -88,6 +89,8 @@ typedef struct { - int (*load_config)(void * opaque, QEMUFile *f); - int (*load_queue)(void * opaque, int n, QEMUFile *f); - unsigned (*get_features)(void * opaque); -+ int (*guest_notifier)(void * opaque, int n, bool assigned); -+ int (*host_notifier)(void * opaque, int n, bool assigned); - } VirtIOBindings; - - #define VIRTIO_PCI_QUEUE_MAX 64 -@@ -180,5 +183,5 @@ void virtio_net_exit(VirtIODevice *vdev); - DEFINE_PROP_BIT("indirect_desc", _state, _field, \ - VIRTIO_RING_F_INDIRECT_DESC, true) - -- -+void virtio_irq(VirtIODevice *vdev, VirtQueue *vq); - #endif --- -1.6.6.144.g5c3af diff --git a/qemu-virtio-add-status-change-callback.patch b/qemu-virtio-add-status-change-callback.patch deleted file mode 100644 index 3a85748..0000000 --- a/qemu-virtio-add-status-change-callback.patch +++ /dev/null @@ -1,76 +0,0 @@ -vhost net backend needs to be notified when -frontend status changes. Add a callback. - -Signed-off-by: Michael S. Tsirkin ---- - hw/s390-virtio-bus.c | 3 +++ - hw/syborg_virtio.c | 2 ++ - hw/virtio-pci.c | 6 ++++++ - hw/virtio.h | 1 + - 4 files changed, 12 insertions(+), 0 deletions(-) - -diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c -index 980e7eb..f45b67d 100644 ---- a/hw/s390-virtio-bus.c -+++ b/hw/s390-virtio-bus.c -@@ -243,6 +243,9 @@ void s390_virtio_device_update_status(VirtIOS390Device *dev) - uint32_t features; - - vdev->status = ldub_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS); -+ if (vdev->set_status) { -+ vdev->set_status(vdev); -+ } - - /* Update guest supported feature bitmap */ - -diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c -index 65239a0..19f6473 100644 ---- a/hw/syborg_virtio.c -+++ b/hw/syborg_virtio.c -@@ -152,6 +152,8 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset, - vdev->status = value & 0xFF; - if (vdev->status == 0) - virtio_reset(vdev); -+ if (vdev->set_status) -+ vdev->set_status(vdev); - break; - case SYBORG_VIRTIO_INT_ENABLE: - s->int_enable = value; -diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c -index 573c98a..05898c8 100644 ---- a/hw/virtio-pci.c -+++ b/hw/virtio-pci.c -@@ -208,6 +208,9 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) - virtio_reset(proxy->vdev); - msix_unuse_all_vectors(&proxy->pci_dev); - } -+ if (vdev->set_status) { -+ vdev->set_status(vdev); -+ } - break; - case VIRTIO_MSI_CONFIG_VECTOR: - msix_vector_unuse(&proxy->pci_dev, vdev->config_vector); -@@ -375,6 +378,9 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, - if (PCI_COMMAND == address) { - if (!(val & PCI_COMMAND_MASTER)) { - proxy->vdev->status &= ~VIRTIO_CONFIG_S_DRIVER_OK; -+ if (proxy->vdev->set_status) { -+ proxy->vdev->set_status(proxy->vdev); -+ } - } - } - -diff --git a/hw/virtio.h b/hw/virtio.h -index f140ca3..39d0763 100644 ---- a/hw/virtio.h -+++ b/hw/virtio.h -@@ -114,6 +114,7 @@ struct VirtIODevice - void (*get_config)(VirtIODevice *vdev, uint8_t *config); - void (*set_config)(VirtIODevice *vdev, const uint8_t *config); - void (*reset)(VirtIODevice *vdev); -+ void (*set_status)(VirtIODevice *vdev); - VirtQueue *vq; - const VirtIOBindings *binding; - void *binding_opaque; --- -1.6.6.144.g5c3af diff --git a/qemu-virtio-avoid-crash-with-non-tap-backends.patch b/qemu-virtio-avoid-crash-with-non-tap-backends.patch deleted file mode 100644 index de869d0..0000000 --- a/qemu-virtio-avoid-crash-with-non-tap-backends.patch +++ /dev/null @@ -1,25 +0,0 @@ -verify that peer is tap before checking for vhost net - -Reported-by: Shirley Ma -Signed-off-by: Michael S. Tsirkin ---- - hw/virtio-net.c | 4 ++++ - 1 files changed, 4 insertions(+), 0 deletions(-) - -diff --git a/hw/virtio-net.c b/hw/virtio-net.c -index 088029b..b28fd92 100644 ---- a/hw/virtio-net.c -+++ b/hw/virtio-net.c -@@ -179,6 +179,10 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features) - features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO); - } - -+ if (!n->nic->nc.peer || -+ n->nic->nc.peer->info->type != NET_CLIENT_TYPE_TAP) { -+ return features; -+ } - if (!tap_get_vhost_net(n->nic->nc.peer)) { - return features; - } --- -1.6.6.144.g5c3af diff --git a/qemu-virtio-console-Rename-virtio-serial.c-back-to-virti.patch b/qemu-virtio-console-Rename-virtio-serial.c-back-to-virti.patch deleted file mode 100644 index a0a6af4..0000000 --- a/qemu-virtio-console-Rename-virtio-serial.c-back-to-virti.patch +++ /dev/null @@ -1,341 +0,0 @@ -From 9c7f6b094950f7772068b957c795d76463cdeba0 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Thu, 21 Jan 2010 15:43:26 +0530 -Subject: [PATCH 9/9] virtio-console: Rename virtio-serial.c back to virtio-console.c - -This file was renamed to ease the reviews of the recent changes -that went in. - -Now that the changes are done, rename the file back to its original -name. - -Signed-off-by: Amit Shah -Signed-off-by: Anthony Liguori ---- - Makefile.hw | 2 +- - hw/virtio-console.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++ - hw/virtio-serial.c | 146 --------------------------------------------------- - 3 files changed, 147 insertions(+), 147 deletions(-) - create mode 100644 hw/virtio-console.c - delete mode 100644 hw/virtio-serial.c - -diff --git a/Makefile.hw b/Makefile.hw -index de8a0c5..43ca541 100644 ---- a/Makefile.hw -+++ b/Makefile.hw -@@ -13,7 +13,7 @@ QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu - - obj-y = - obj-y += loader.o --obj-y += virtio.o virtio-serial.o -+obj-y += virtio.o virtio-console.o - obj-y += fw_cfg.o - obj-y += watchdog.o - obj-$(CONFIG_ECC) += ecc.o -diff --git a/hw/virtio-console.c b/hw/virtio-console.c -new file mode 100644 -index 0000000..bd44ec6 ---- /dev/null -+++ b/hw/virtio-console.c -@@ -0,0 +1,146 @@ -+/* -+ * Virtio Console and Generic Serial Port Devices -+ * -+ * Copyright Red Hat, Inc. 2009 -+ * -+ * Authors: -+ * Amit Shah -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2. See -+ * the COPYING file in the top-level directory. -+ */ -+ -+#include "qemu-char.h" -+#include "virtio-serial.h" -+ -+typedef struct VirtConsole { -+ VirtIOSerialPort port; -+ CharDriverState *chr; -+} VirtConsole; -+ -+ -+/* Callback function that's called when the guest sends us data */ -+static size_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) -+{ -+ VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -+ ssize_t ret; -+ -+ ret = qemu_chr_write(vcon->chr, buf, len); -+ -+ return ret < 0 ? 0 : ret; -+} -+ -+/* Readiness of the guest to accept data on a port */ -+static int chr_can_read(void *opaque) -+{ -+ VirtConsole *vcon = opaque; -+ -+ return virtio_serial_guest_ready(&vcon->port); -+} -+ -+/* Send data from a char device over to the guest */ -+static void chr_read(void *opaque, const uint8_t *buf, int size) -+{ -+ VirtConsole *vcon = opaque; -+ -+ virtio_serial_write(&vcon->port, buf, size); -+} -+ -+static void chr_event(void *opaque, int event) -+{ -+ VirtConsole *vcon = opaque; -+ -+ switch (event) { -+ case CHR_EVENT_OPENED: { -+ virtio_serial_open(&vcon->port); -+ break; -+ } -+ case CHR_EVENT_CLOSED: -+ virtio_serial_close(&vcon->port); -+ break; -+ } -+} -+ -+/* Virtio Console Ports */ -+static int virtconsole_initfn(VirtIOSerialDevice *dev) -+{ -+ VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -+ VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -+ -+ port->info = dev->info; -+ -+ port->is_console = true; -+ -+ if (vcon->chr) { -+ qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event, -+ vcon); -+ port->info->have_data = flush_buf; -+ } -+ return 0; -+} -+ -+static int virtconsole_exitfn(VirtIOSerialDevice *dev) -+{ -+ VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -+ VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -+ -+ if (vcon->chr) { -+ port->info->have_data = NULL; -+ qemu_chr_close(vcon->chr); -+ } -+ -+ return 0; -+} -+ -+static VirtIOSerialPortInfo virtconsole_info = { -+ .qdev.name = "virtconsole", -+ .qdev.size = sizeof(VirtConsole), -+ .init = virtconsole_initfn, -+ .exit = virtconsole_exitfn, -+ .qdev.props = (Property[]) { -+ DEFINE_PROP_UINT8("is_console", VirtConsole, port.is_console, 1), -+ DEFINE_PROP_CHR("chardev", VirtConsole, chr), -+ DEFINE_PROP_STRING("name", VirtConsole, port.name), -+ DEFINE_PROP_END_OF_LIST(), -+ }, -+}; -+ -+static void virtconsole_register(void) -+{ -+ virtio_serial_port_qdev_register(&virtconsole_info); -+} -+device_init(virtconsole_register) -+ -+/* Generic Virtio Serial Ports */ -+static int virtserialport_initfn(VirtIOSerialDevice *dev) -+{ -+ VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -+ VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -+ -+ port->info = dev->info; -+ -+ if (vcon->chr) { -+ qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event, -+ vcon); -+ port->info->have_data = flush_buf; -+ } -+ return 0; -+} -+ -+static VirtIOSerialPortInfo virtserialport_info = { -+ .qdev.name = "virtserialport", -+ .qdev.size = sizeof(VirtConsole), -+ .init = virtserialport_initfn, -+ .exit = virtconsole_exitfn, -+ .qdev.props = (Property[]) { -+ DEFINE_PROP_CHR("chardev", VirtConsole, chr), -+ DEFINE_PROP_STRING("name", VirtConsole, port.name), -+ DEFINE_PROP_END_OF_LIST(), -+ }, -+}; -+ -+static void virtserialport_register(void) -+{ -+ virtio_serial_port_qdev_register(&virtserialport_info); -+} -+device_init(virtserialport_register) -diff --git a/hw/virtio-serial.c b/hw/virtio-serial.c -deleted file mode 100644 -index bd44ec6..0000000 ---- a/hw/virtio-serial.c -+++ /dev/null -@@ -1,146 +0,0 @@ --/* -- * Virtio Console and Generic Serial Port Devices -- * -- * Copyright Red Hat, Inc. 2009 -- * -- * Authors: -- * Amit Shah -- * -- * This work is licensed under the terms of the GNU GPL, version 2. See -- * the COPYING file in the top-level directory. -- */ -- --#include "qemu-char.h" --#include "virtio-serial.h" -- --typedef struct VirtConsole { -- VirtIOSerialPort port; -- CharDriverState *chr; --} VirtConsole; -- -- --/* Callback function that's called when the guest sends us data */ --static size_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) --{ -- VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -- ssize_t ret; -- -- ret = qemu_chr_write(vcon->chr, buf, len); -- -- return ret < 0 ? 0 : ret; --} -- --/* Readiness of the guest to accept data on a port */ --static int chr_can_read(void *opaque) --{ -- VirtConsole *vcon = opaque; -- -- return virtio_serial_guest_ready(&vcon->port); --} -- --/* Send data from a char device over to the guest */ --static void chr_read(void *opaque, const uint8_t *buf, int size) --{ -- VirtConsole *vcon = opaque; -- -- virtio_serial_write(&vcon->port, buf, size); --} -- --static void chr_event(void *opaque, int event) --{ -- VirtConsole *vcon = opaque; -- -- switch (event) { -- case CHR_EVENT_OPENED: { -- virtio_serial_open(&vcon->port); -- break; -- } -- case CHR_EVENT_CLOSED: -- virtio_serial_close(&vcon->port); -- break; -- } --} -- --/* Virtio Console Ports */ --static int virtconsole_initfn(VirtIOSerialDevice *dev) --{ -- VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -- VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -- -- port->info = dev->info; -- -- port->is_console = true; -- -- if (vcon->chr) { -- qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event, -- vcon); -- port->info->have_data = flush_buf; -- } -- return 0; --} -- --static int virtconsole_exitfn(VirtIOSerialDevice *dev) --{ -- VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -- VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -- -- if (vcon->chr) { -- port->info->have_data = NULL; -- qemu_chr_close(vcon->chr); -- } -- -- return 0; --} -- --static VirtIOSerialPortInfo virtconsole_info = { -- .qdev.name = "virtconsole", -- .qdev.size = sizeof(VirtConsole), -- .init = virtconsole_initfn, -- .exit = virtconsole_exitfn, -- .qdev.props = (Property[]) { -- DEFINE_PROP_UINT8("is_console", VirtConsole, port.is_console, 1), -- DEFINE_PROP_CHR("chardev", VirtConsole, chr), -- DEFINE_PROP_STRING("name", VirtConsole, port.name), -- DEFINE_PROP_END_OF_LIST(), -- }, --}; -- --static void virtconsole_register(void) --{ -- virtio_serial_port_qdev_register(&virtconsole_info); --} --device_init(virtconsole_register) -- --/* Generic Virtio Serial Ports */ --static int virtserialport_initfn(VirtIOSerialDevice *dev) --{ -- VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -- VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -- -- port->info = dev->info; -- -- if (vcon->chr) { -- qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event, -- vcon); -- port->info->have_data = flush_buf; -- } -- return 0; --} -- --static VirtIOSerialPortInfo virtserialport_info = { -- .qdev.name = "virtserialport", -- .qdev.size = sizeof(VirtConsole), -- .init = virtserialport_initfn, -- .exit = virtconsole_exitfn, -- .qdev.props = (Property[]) { -- DEFINE_PROP_CHR("chardev", VirtConsole, chr), -- DEFINE_PROP_STRING("name", VirtConsole, port.name), -- DEFINE_PROP_END_OF_LIST(), -- }, --}; -- --static void virtserialport_register(void) --{ -- virtio_serial_port_qdev_register(&virtserialport_info); --} --device_init(virtserialport_register) --- -1.6.2.5 - diff --git a/qemu-virtio-console-qdev-conversion-new-virtio-serial-b.patch b/qemu-virtio-console-qdev-conversion-new-virtio-serial-b.patch deleted file mode 100644 index 950647b..0000000 --- a/qemu-virtio-console-qdev-conversion-new-virtio-serial-b.patch +++ /dev/null @@ -1,1366 +0,0 @@ -From 76c8fc3a48dcaf6161d7cb68976db99aaf97efdd Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Wed, 20 Jan 2010 00:36:52 +0530 -Subject: [PATCH 2/9] virtio-console: qdev conversion, new virtio-serial-bus - -This commit converts the virtio-console device to create a new -virtio-serial bus that can host console and generic serial ports. The -file hosting this code is now called virtio-serial-bus.c. - -The virtio console is now a very simple qdev device that sits on the -virtio-serial-bus and communicates between the bus and qemu's chardevs. - -This commit also includes a few changes to the virtio backing code for -pci and s390 to spawn the virtio-serial bus. - -As a result of the qdev conversion, we get rid of a lot of legacy code. -The old-style way of instantiating a virtio console using - - -virtioconsole ... - -is maintained, but the new, preferred way is to use - - -device virtio-serial -device virtconsole,chardev=... - -With this commit, multiple devices as well as multiple ports with a -single device can be supported. - -For multiple ports support, each port gets an IO vq pair. Since the -guest needs to know in advance how many vqs a particular device will -need, we have to set this number as a property of the virtio-serial -device and also as a config option. - -In addition, we also spawn a pair of control IO vqs. This is an internal -channel meant for guest-host communication for things like port -open/close, sending port properties over to the guest, etc. - -This commit is a part of a series of other commits to get the full -implementation of multiport support. Future commits will add other -support as well as ride on the savevm version that we bump up here. - -Signed-off-by: Amit Shah -Signed-off-by: Anthony Liguori ---- - Makefile.target | 2 +- - hw/pc.c | 11 +- - hw/ppc440_bamboo.c | 7 - - hw/qdev.c | 10 +- - hw/s390-virtio-bus.c | 17 +- - hw/s390-virtio-bus.h | 2 + - hw/s390-virtio.c | 8 - - hw/virtio-console.c | 146 -------------- - hw/virtio-console.h | 19 -- - hw/virtio-pci.c | 13 +- - hw/virtio-serial-bus.c | 504 ++++++++++++++++++++++++++++++++++++++++++++++++ - hw/virtio-serial.c | 111 +++++++++++ - hw/virtio-serial.h | 158 +++++++++++++++ - hw/virtio.h | 2 +- - qemu-options.hx | 4 + - sysemu.h | 6 - - vl.c | 17 ++- - 17 files changed, 819 insertions(+), 218 deletions(-) - delete mode 100644 hw/virtio-console.c - delete mode 100644 hw/virtio-console.h - create mode 100644 hw/virtio-serial-bus.c - create mode 100644 hw/virtio-serial.c - create mode 100644 hw/virtio-serial.h - -diff --git a/Makefile.target b/Makefile.target -index 6037fed..234577c 100644 ---- a/Makefile.target -+++ b/Makefile.target -@@ -166,7 +166,7 @@ ifdef CONFIG_SOFTMMU - obj-y = vl.o async.o monitor.o pci.o pci_host.o pcie_host.o machine.o gdbstub.o - # virtio has to be here due to weird dependency between PCI and virtio-net. - # need to fix this properly --obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o virtio-pci.o -+obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial.o virtio-serial-bus.o virtio-pci.o - obj-$(CONFIG_KVM) += kvm.o kvm-all.o - # MSI-X depends on kvm for interrupt injection, - # so moved it from Makefile.hw to Makefile.target for now -diff --git a/hw/pc.c b/hw/pc.c -index 78a07c2..acbfeba 100644 ---- a/hw/pc.c -+++ b/hw/pc.c -@@ -1284,15 +1284,6 @@ static void pc_init1(ram_addr_t ram_size, - extboot_init(info->bdrv, 1); - } - -- /* Add virtio console devices */ -- if (pci_enabled) { -- for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { -- if (virtcon_hds[i]) { -- pci_create_simple(pci_bus, -1, "virtio-console-pci"); -- } -- } -- } -- - #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT - if (kvm_enabled()) { - add_assigned_devices(pci_bus, assigned_devices, assigned_devices_index); -@@ -1373,7 +1364,7 @@ static QEMUMachine pc_machine_v0_10 = { - .property = "class", - .value = stringify(PCI_CLASS_STORAGE_OTHER), - },{ -- .driver = "virtio-console-pci", -+ .driver = "virtio-serial-pci", - .property = "class", - .value = stringify(PCI_CLASS_DISPLAY_OTHER), - },{ -diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c -index 25417e3..c94c961 100644 ---- a/hw/ppc440_bamboo.c -+++ b/hw/ppc440_bamboo.c -@@ -109,13 +109,6 @@ static void bamboo_init(ram_addr_t ram_size, - env = ppc440ep_init(&ram_size, &pcibus, pci_irq_nrs, 1, cpu_model); - - if (pcibus) { -- /* Add virtio console devices */ -- for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { -- if (virtcon_hds[i]) { -- pci_create_simple(pcibus, -1, "virtio-console-pci"); -- } -- } -- - /* Register network interfaces. */ - for (i = 0; i < nb_nics; i++) { - /* There are no PCI NICs on the Bamboo board, but there are -diff --git a/hw/qdev.c b/hw/qdev.c -index b6bd4ae..c643576 100644 ---- a/hw/qdev.c -+++ b/hw/qdev.c -@@ -321,13 +321,9 @@ void qdev_machine_creation_done(void) - CharDriverState *qdev_init_chardev(DeviceState *dev) - { - static int next_serial; -- static int next_virtconsole; -- /* FIXME: This is a nasty hack that needs to go away. */ -- if (strncmp(dev->info->name, "virtio", 6) == 0) { -- return virtcon_hds[next_virtconsole++]; -- } else { -- return serial_hds[next_serial++]; -- } -+ -+ /* FIXME: This function needs to go away: use chardev properties! */ -+ return serial_hds[next_serial++]; - } - - BusState *qdev_get_parent_bus(DeviceState *dev) -diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c -index dc154ed..95c516a 100644 ---- a/hw/s390-virtio-bus.c -+++ b/hw/s390-virtio-bus.c -@@ -26,7 +26,7 @@ - #include "loader.h" - #include "elf.h" - #include "hw/virtio.h" --#include "hw/virtio-console.h" -+#include "hw/virtio-serial.h" - #include "hw/sysbus.h" - #include "kvm.h" - -@@ -130,7 +130,7 @@ static int s390_virtio_blk_init(VirtIOS390Device *dev) - return s390_virtio_device_init(dev, vdev); - } - --static int s390_virtio_console_init(VirtIOS390Device *dev) -+static int s390_virtio_serial_init(VirtIOS390Device *dev) - { - VirtIOS390Bus *bus; - VirtIODevice *vdev; -@@ -138,7 +138,7 @@ static int s390_virtio_console_init(VirtIOS390Device *dev) - - bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus); - -- vdev = virtio_console_init((DeviceState *)dev); -+ vdev = virtio_serial_init((DeviceState *)dev, dev->max_virtserial_ports); - if (!vdev) { - return -1; - } -@@ -336,11 +336,14 @@ static VirtIOS390DeviceInfo s390_virtio_blk = { - }, - }; - --static VirtIOS390DeviceInfo s390_virtio_console = { -- .init = s390_virtio_console_init, -- .qdev.name = "virtio-console-s390", -+static VirtIOS390DeviceInfo s390_virtio_serial = { -+ .init = s390_virtio_serial_init, -+ .qdev.name = "virtio-serial-s390", -+ .qdev.alias = "virtio-serial", - .qdev.size = sizeof(VirtIOS390Device), - .qdev.props = (Property[]) { -+ DEFINE_PROP_UINT32("max_ports", VirtIOS390Device, max_virtserial_ports, -+ 31), - DEFINE_PROP_END_OF_LIST(), - }, - }; -@@ -364,7 +367,7 @@ static void s390_virtio_bus_register_withprop(VirtIOS390DeviceInfo *info) - - static void s390_virtio_register(void) - { -- s390_virtio_bus_register_withprop(&s390_virtio_console); -+ s390_virtio_bus_register_withprop(&s390_virtio_serial); - s390_virtio_bus_register_withprop(&s390_virtio_blk); - s390_virtio_bus_register_withprop(&s390_virtio_net); - } -diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h -index ef36714..ad85ed3 100644 ---- a/hw/s390-virtio-bus.h -+++ b/hw/s390-virtio-bus.h -@@ -40,6 +40,8 @@ typedef struct VirtIOS390Device { - VirtIODevice *vdev; - DriveInfo *dinfo; - NICConf nic; -+ /* Max. number of ports we can have for a the virtio-serial device */ -+ uint32_t max_virtserial_ports; - } VirtIOS390Device; - - typedef struct VirtIOS390Bus { -diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c -index 0fa6ba6..3582728 100644 ---- a/hw/s390-virtio.c -+++ b/hw/s390-virtio.c -@@ -26,7 +26,6 @@ - #include "loader.h" - #include "elf.h" - #include "hw/virtio.h" --#include "hw/virtio-console.h" - #include "hw/sysbus.h" - #include "kvm.h" - -@@ -207,13 +206,6 @@ static void s390_init(ram_addr_t ram_size, - strlen(kernel_cmdline), 1); - } - -- /* Create VirtIO console */ -- for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { -- if (virtcon_hds[i]) { -- qdev_init_nofail(qdev_create((BusState *)s390_bus, "virtio-console-s390")); -- } -- } -- - /* Create VirtIO network adapters */ - for(i = 0; i < nb_nics; i++) { - NICInfo *nd = &nd_table[i]; -diff --git a/hw/virtio-console.c b/hw/virtio-console.c -deleted file mode 100644 -index 92c953c..0000000 ---- a/hw/virtio-console.c -+++ /dev/null -@@ -1,146 +0,0 @@ --/* -- * Virtio Console Device -- * -- * Copyright IBM, Corp. 2008 -- * -- * Authors: -- * Christian Ehrhardt -- * -- * This work is licensed under the terms of the GNU GPL, version 2. See -- * the COPYING file in the top-level directory. -- * -- */ -- --#include "hw.h" --#include "qemu-char.h" --#include "virtio.h" --#include "virtio-console.h" -- -- --typedef struct VirtIOConsole --{ -- VirtIODevice vdev; -- VirtQueue *ivq, *ovq; -- CharDriverState *chr; --} VirtIOConsole; -- --static VirtIOConsole *to_virtio_console(VirtIODevice *vdev) --{ -- return (VirtIOConsole *)vdev; --} -- --static void virtio_console_handle_output(VirtIODevice *vdev, VirtQueue *vq) --{ -- VirtIOConsole *s = to_virtio_console(vdev); -- VirtQueueElement elem; -- -- while (virtqueue_pop(vq, &elem)) { -- ssize_t len = 0; -- int d; -- -- for (d = 0; d < elem.out_num; d++) { -- len += qemu_chr_write(s->chr, (uint8_t *)elem.out_sg[d].iov_base, -- elem.out_sg[d].iov_len); -- } -- virtqueue_push(vq, &elem, len); -- virtio_notify(vdev, vq); -- } --} -- --static void virtio_console_handle_input(VirtIODevice *vdev, VirtQueue *vq) --{ --} -- --static uint32_t virtio_console_get_features(VirtIODevice *vdev) --{ -- return 0; --} -- --static int vcon_can_read(void *opaque) --{ -- VirtIOConsole *s = (VirtIOConsole *) opaque; -- -- if (!virtio_queue_ready(s->ivq) || -- !(s->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK) || -- virtio_queue_empty(s->ivq)) -- return 0; -- -- /* current implementations have a page sized buffer. -- * We fall back to a one byte per read if there is not enough room. -- * It would be cool to have a function that returns the available byte -- * instead of checking for a limit */ -- if (virtqueue_avail_bytes(s->ivq, TARGET_PAGE_SIZE, 0)) -- return TARGET_PAGE_SIZE; -- if (virtqueue_avail_bytes(s->ivq, 1, 0)) -- return 1; -- return 0; --} -- --static void vcon_read(void *opaque, const uint8_t *buf, int size) --{ -- VirtIOConsole *s = (VirtIOConsole *) opaque; -- VirtQueueElement elem; -- int offset = 0; -- -- /* The current kernel implementation has only one outstanding input -- * buffer of PAGE_SIZE. Nevertheless, this function is prepared to -- * handle multiple buffers with multiple sg element for input */ -- while (offset < size) { -- int i = 0; -- if (!virtqueue_pop(s->ivq, &elem)) -- break; -- while (offset < size && i < elem.in_num) { -- int len = MIN(elem.in_sg[i].iov_len, size - offset); -- memcpy(elem.in_sg[i].iov_base, buf + offset, len); -- offset += len; -- i++; -- } -- virtqueue_push(s->ivq, &elem, size); -- } -- virtio_notify(&s->vdev, s->ivq); --} -- --static void vcon_event(void *opaque, int event) --{ -- /* we will ignore any event for the time being */ --} -- --static void virtio_console_save(QEMUFile *f, void *opaque) --{ -- VirtIOConsole *s = opaque; -- -- virtio_save(&s->vdev, f); --} -- --static int virtio_console_load(QEMUFile *f, void *opaque, int version_id) --{ -- VirtIOConsole *s = opaque; -- -- if (version_id != 1) -- return -EINVAL; -- -- virtio_load(&s->vdev, f); -- return 0; --} -- --VirtIODevice *virtio_console_init(DeviceState *dev) --{ -- VirtIOConsole *s; -- s = (VirtIOConsole *)virtio_common_init("virtio-console", -- VIRTIO_ID_CONSOLE, -- 0, sizeof(VirtIOConsole)); -- if (s == NULL) -- return NULL; -- -- s->vdev.get_features = virtio_console_get_features; -- -- s->ivq = virtio_add_queue(&s->vdev, 128, virtio_console_handle_input); -- s->ovq = virtio_add_queue(&s->vdev, 128, virtio_console_handle_output); -- -- s->chr = qdev_init_chardev(dev); -- qemu_chr_add_handlers(s->chr, vcon_can_read, vcon_read, vcon_event, s); -- -- register_savevm("virtio-console", -1, 1, virtio_console_save, virtio_console_load, s); -- -- return &s->vdev; --} -diff --git a/hw/virtio-console.h b/hw/virtio-console.h -deleted file mode 100644 -index 84d0717..0000000 ---- a/hw/virtio-console.h -+++ /dev/null -@@ -1,19 +0,0 @@ --/* -- * Virtio Console Support -- * -- * Copyright IBM, Corp. 2008 -- * -- * Authors: -- * Christian Ehrhardt -- * -- * This work is licensed under the terms of the GNU GPL, version 2. See -- * the COPYING file in the top-level directory. -- * -- */ --#ifndef _QEMU_VIRTIO_CONSOLE_H --#define _QEMU_VIRTIO_CONSOLE_H -- --/* The ID for virtio console */ --#define VIRTIO_ID_CONSOLE 3 -- --#endif -diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c -index 3594152..c1a1e4c 100644 ---- a/hw/virtio-pci.c -+++ b/hw/virtio-pci.c -@@ -92,6 +92,8 @@ typedef struct { - uint32_t nvectors; - DriveInfo *dinfo; - NICConf nic; -+ /* Max. number of ports we can have for a the virtio-serial device */ -+ uint32_t max_virtserial_ports; - } VirtIOPCIProxy; - - /* virtio device */ -@@ -481,7 +483,7 @@ static int virtio_blk_exit_pci(PCIDevice *pci_dev) - return virtio_exit_pci(pci_dev); - } - --static int virtio_console_init_pci(PCIDevice *pci_dev) -+static int virtio_serial_init_pci(PCIDevice *pci_dev) - { - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - VirtIODevice *vdev; -@@ -491,7 +493,7 @@ static int virtio_console_init_pci(PCIDevice *pci_dev) - proxy->class_code != PCI_CLASS_OTHERS) /* qemu-kvm */ - proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER; - -- vdev = virtio_console_init(&pci_dev->qdev); -+ vdev = virtio_serial_init(&pci_dev->qdev, proxy->max_virtserial_ports); - if (!vdev) { - return -1; - } -@@ -569,12 +571,15 @@ static PCIDeviceInfo virtio_info[] = { - }, - .qdev.reset = virtio_pci_reset, - },{ -- .qdev.name = "virtio-console-pci", -+ .qdev.name = "virtio-serial-pci", -+ .qdev.alias = "virtio-serial", - .qdev.size = sizeof(VirtIOPCIProxy), -- .init = virtio_console_init_pci, -+ .init = virtio_serial_init_pci, - .exit = virtio_exit_pci, - .qdev.props = (Property[]) { - DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), -+ DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, max_virtserial_ports, -+ 31), - DEFINE_PROP_END_OF_LIST(), - }, - .qdev.reset = virtio_pci_reset, -diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c -new file mode 100644 -index 0000000..5132c9c ---- /dev/null -+++ b/hw/virtio-serial-bus.c -@@ -0,0 +1,504 @@ -+/* -+ * A bus for connecting virtio serial and console ports -+ * -+ * Copyright (C) 2009 Red Hat, Inc. -+ * -+ * Author(s): -+ * Amit Shah -+ * -+ * Some earlier parts are: -+ * Copyright IBM, Corp. 2008 -+ * authored by -+ * Christian Ehrhardt -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2. See -+ * the COPYING file in the top-level directory. -+ */ -+ -+#include "monitor.h" -+#include "qemu-queue.h" -+#include "sysbus.h" -+#include "virtio-serial.h" -+ -+/* The virtio-serial bus on top of which the ports will ride as devices */ -+struct VirtIOSerialBus { -+ BusState qbus; -+ -+ /* This is the parent device that provides the bus for ports. */ -+ VirtIOSerial *vser; -+ -+ /* The maximum number of ports that can ride on top of this bus */ -+ uint32_t max_nr_ports; -+}; -+ -+struct VirtIOSerial { -+ VirtIODevice vdev; -+ -+ VirtQueue *c_ivq, *c_ovq; -+ /* Arrays of ivqs and ovqs: one per port */ -+ VirtQueue **ivqs, **ovqs; -+ -+ VirtIOSerialBus *bus; -+ -+ QTAILQ_HEAD(, VirtIOSerialPort) ports; -+ struct virtio_console_config config; -+}; -+ -+static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id) -+{ -+ VirtIOSerialPort *port; -+ -+ QTAILQ_FOREACH(port, &vser->ports, next) { -+ if (port->id == id) -+ return port; -+ } -+ return NULL; -+} -+ -+static VirtIOSerialPort *find_port_by_vq(VirtIOSerial *vser, VirtQueue *vq) -+{ -+ VirtIOSerialPort *port; -+ -+ QTAILQ_FOREACH(port, &vser->ports, next) { -+ if (port->ivq == vq || port->ovq == vq) -+ return port; -+ } -+ return NULL; -+} -+ -+static size_t write_to_port(VirtIOSerialPort *port, -+ const uint8_t *buf, size_t size) -+{ -+ VirtQueueElement elem; -+ VirtQueue *vq; -+ size_t offset = 0; -+ size_t len = 0; -+ -+ vq = port->ivq; -+ if (!virtio_queue_ready(vq)) { -+ return 0; -+ } -+ if (!size) { -+ return 0; -+ } -+ -+ while (offset < size) { -+ int i; -+ -+ if (!virtqueue_pop(vq, &elem)) { -+ break; -+ } -+ -+ for (i = 0; offset < size && i < elem.in_num; i++) { -+ len = MIN(elem.in_sg[i].iov_len, size - offset); -+ -+ memcpy(elem.in_sg[i].iov_base, buf + offset, len); -+ offset += len; -+ } -+ virtqueue_push(vq, &elem, len); -+ } -+ -+ virtio_notify(&port->vser->vdev, vq); -+ return offset; -+} -+ -+static size_t send_control_msg(VirtIOSerialPort *port, void *buf, size_t len) -+{ -+ VirtQueueElement elem; -+ VirtQueue *vq; -+ struct virtio_console_control *cpkt; -+ -+ vq = port->vser->c_ivq; -+ if (!virtio_queue_ready(vq)) { -+ return 0; -+ } -+ if (!virtqueue_pop(vq, &elem)) { -+ return 0; -+ } -+ -+ cpkt = (struct virtio_console_control *)buf; -+ stl_p(&cpkt->id, port->id); -+ memcpy(elem.in_sg[0].iov_base, buf, len); -+ -+ virtqueue_push(vq, &elem, len); -+ virtio_notify(&port->vser->vdev, vq); -+ return len; -+} -+ -+static size_t send_control_event(VirtIOSerialPort *port, uint16_t event, -+ uint16_t value) -+{ -+ struct virtio_console_control cpkt; -+ -+ stw_p(&cpkt.event, event); -+ stw_p(&cpkt.value, value); -+ -+ return send_control_msg(port, &cpkt, sizeof(cpkt)); -+} -+ -+/* Functions for use inside qemu to open and read from/write to ports */ -+int virtio_serial_open(VirtIOSerialPort *port) -+{ -+ return 0; -+} -+ -+int virtio_serial_close(VirtIOSerialPort *port) -+{ -+ return 0; -+} -+ -+/* Individual ports/apps call this function to write to the guest. */ -+ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf, -+ size_t size) -+{ -+ return write_to_port(port, buf, size); -+} -+ -+/* -+ * Readiness of the guest to accept data on a port. -+ * Returns max. data the guest can receive -+ */ -+size_t virtio_serial_guest_ready(VirtIOSerialPort *port) -+{ -+ VirtQueue *vq = port->ivq; -+ -+ if (!virtio_queue_ready(vq) || -+ !(port->vser->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK) || -+ virtio_queue_empty(vq)) { -+ return 0; -+ } -+ -+ if (virtqueue_avail_bytes(vq, 4096, 0)) { -+ return 4096; -+ } -+ if (virtqueue_avail_bytes(vq, 1, 0)) { -+ return 1; -+ } -+ return 0; -+} -+ -+/* Guest wants to notify us of some event */ -+static void handle_control_message(VirtIOSerial *vser, void *buf) -+{ -+ struct VirtIOSerialPort *port; -+ struct virtio_console_control cpkt, *gcpkt; -+ -+ gcpkt = buf; -+ port = find_port_by_id(vser, ldl_p(&gcpkt->id)); -+ if (!port) -+ return; -+ -+ cpkt.event = lduw_p(&gcpkt->event); -+ cpkt.value = lduw_p(&gcpkt->value); -+ -+ switch(cpkt.event) { -+ case VIRTIO_CONSOLE_PORT_READY: -+ /* -+ * Now that we know the guest asked for the port name, we're -+ * sure the guest has initialised whatever state is necessary -+ * for this port. Now's a good time to let the guest know if -+ * this port is a console port so that the guest can hook it -+ * up to hvc. -+ */ -+ if (port->is_console) { -+ send_control_event(port, VIRTIO_CONSOLE_CONSOLE_PORT, 1); -+ } -+ /* -+ * When the guest has asked us for this information it means -+ * the guest is all setup and has its virtqueues -+ * initialised. If some app is interested in knowing about -+ * this event, let it know. -+ */ -+ if (port->info->guest_ready) { -+ port->info->guest_ready(port); -+ } -+ break; -+ } -+} -+ -+static void control_in(VirtIODevice *vdev, VirtQueue *vq) -+{ -+} -+ -+static void control_out(VirtIODevice *vdev, VirtQueue *vq) -+{ -+ VirtQueueElement elem; -+ VirtIOSerial *vser; -+ -+ vser = DO_UPCAST(VirtIOSerial, vdev, vdev); -+ -+ while (virtqueue_pop(vq, &elem)) { -+ handle_control_message(vser, elem.out_sg[0].iov_base); -+ virtqueue_push(vq, &elem, elem.out_sg[0].iov_len); -+ } -+ virtio_notify(vdev, vq); -+} -+ -+/* Guest wrote something to some port. */ -+static void handle_output(VirtIODevice *vdev, VirtQueue *vq) -+{ -+ VirtIOSerial *vser; -+ VirtQueueElement elem; -+ -+ vser = DO_UPCAST(VirtIOSerial, vdev, vdev); -+ -+ while (virtqueue_pop(vq, &elem)) { -+ VirtIOSerialPort *port; -+ size_t ret; -+ -+ port = find_port_by_vq(vser, vq); -+ if (!port) { -+ ret = 0; -+ goto next_buf; -+ } -+ -+ /* -+ * A port may not have any handler registered for consuming the -+ * data that the guest sends or it may not have a chardev associated -+ * with it. Just ignore the data in that case. -+ */ -+ if (!port->info->have_data) { -+ ret = 0; -+ goto next_buf; -+ } -+ -+ /* The guest always sends only one sg */ -+ ret = port->info->have_data(port, elem.out_sg[0].iov_base, -+ elem.out_sg[0].iov_len); -+ -+ next_buf: -+ virtqueue_push(vq, &elem, ret); -+ } -+ virtio_notify(vdev, vq); -+} -+ -+static void handle_input(VirtIODevice *vdev, VirtQueue *vq) -+{ -+} -+ -+static uint32_t get_features(VirtIODevice *vdev) -+{ -+ return 1 << VIRTIO_CONSOLE_F_MULTIPORT; -+} -+ -+/* Guest requested config info */ -+static void get_config(VirtIODevice *vdev, uint8_t *config_data) -+{ -+ VirtIOSerial *vser; -+ -+ vser = DO_UPCAST(VirtIOSerial, vdev, vdev); -+ memcpy(config_data, &vser->config, sizeof(struct virtio_console_config)); -+} -+ -+static void set_config(VirtIODevice *vdev, const uint8_t *config_data) -+{ -+ struct virtio_console_config config; -+ -+ memcpy(&config, config_data, sizeof(config)); -+} -+ -+static void virtio_serial_save(QEMUFile *f, void *opaque) -+{ -+ VirtIOSerial *s = opaque; -+ -+ /* The virtio device */ -+ virtio_save(&s->vdev, f); -+ -+ /* The config space */ -+ qemu_put_be16s(f, &s->config.cols); -+ qemu_put_be16s(f, &s->config.rows); -+ qemu_put_be32s(f, &s->config.nr_ports); -+} -+ -+static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) -+{ -+ VirtIOSerial *s = opaque; -+ -+ if (version_id > 2) { -+ return -EINVAL; -+ } -+ /* The virtio device */ -+ virtio_load(&s->vdev, f); -+ -+ if (version_id < 2) { -+ return 0; -+ } -+ -+ /* The config space */ -+ qemu_get_be16s(f, &s->config.cols); -+ qemu_get_be16s(f, &s->config.rows); -+ s->config.nr_ports = qemu_get_be32(f); -+ -+ return 0; -+} -+ -+static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent); -+ -+static struct BusInfo virtser_bus_info = { -+ .name = "virtio-serial-bus", -+ .size = sizeof(VirtIOSerialBus), -+ .print_dev = virtser_bus_dev_print, -+}; -+ -+static VirtIOSerialBus *virtser_bus_new(DeviceState *dev) -+{ -+ VirtIOSerialBus *bus; -+ -+ bus = FROM_QBUS(VirtIOSerialBus, qbus_create(&virtser_bus_info, dev, NULL)); -+ bus->qbus.allow_hotplug = 1; -+ -+ return bus; -+} -+ -+static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent) -+{ -+ VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev); -+ VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -+ -+ monitor_printf(mon, "%*s dev-prop-int: id: %u\n", -+ indent, "", port->id); -+} -+ -+static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) -+{ -+ VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev); -+ VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev, base); -+ VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -+ VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus); -+ int ret; -+ bool plugging_port0; -+ -+ port->vser = bus->vser; -+ -+ /* -+ * Is the first console port we're seeing? If so, put it up at -+ * location 0. This is done for backward compatibility (old -+ * kernel, new qemu). -+ */ -+ plugging_port0 = port->is_console && !find_port_by_id(port->vser, 0); -+ -+ if (port->vser->config.nr_ports == bus->max_nr_ports && !plugging_port0) { -+ qemu_error("virtio-serial-bus: Maximum device limit reached\n"); -+ return -1; -+ } -+ dev->info = info; -+ -+ ret = info->init(dev); -+ if (ret) { -+ return ret; -+ } -+ -+ port->id = plugging_port0 ? 0 : port->vser->config.nr_ports++; -+ -+ QTAILQ_INSERT_TAIL(&port->vser->ports, port, next); -+ port->ivq = port->vser->ivqs[port->id]; -+ port->ovq = port->vser->ovqs[port->id]; -+ -+ /* Send an update to the guest about this new port added */ -+ virtio_notify_config(&port->vser->vdev); -+ -+ return ret; -+} -+ -+static int virtser_port_qdev_exit(DeviceState *qdev) -+{ -+ VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev); -+ VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -+ VirtIOSerial *vser = port->vser; -+ -+ /* -+ * Don't decrement nr_ports here; thus we keep a linearly -+ * increasing port id. Not utilising an id again saves us a couple -+ * of complications: -+ * -+ * - Not having to bother about sending the port id to the guest -+ * kernel on hotplug or on addition of new ports; the guest can -+ * also linearly increment the port number. This is preferable -+ * because the config space won't have the need to store a -+ * ports_map. -+ * -+ * - Extra state to be stored for all the "holes" that got created -+ * so that we keep filling in the ids from the least available -+ * index. -+ * -+ * When such a functionality is desired, a control message to add -+ * a port can be introduced. -+ */ -+ QTAILQ_REMOVE(&vser->ports, port, next); -+ -+ if (port->info->exit) -+ port->info->exit(dev); -+ -+ return 0; -+} -+ -+void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info) -+{ -+ info->qdev.init = virtser_port_qdev_init; -+ info->qdev.bus_info = &virtser_bus_info; -+ info->qdev.exit = virtser_port_qdev_exit; -+ info->qdev.unplug = qdev_simple_unplug_cb; -+ qdev_register(&info->qdev); -+} -+ -+VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports) -+{ -+ VirtIOSerial *vser; -+ VirtIODevice *vdev; -+ uint32_t i; -+ -+ if (!max_nr_ports) -+ return NULL; -+ -+ vdev = virtio_common_init("virtio-serial", VIRTIO_ID_CONSOLE, -+ sizeof(struct virtio_console_config), -+ sizeof(VirtIOSerial)); -+ -+ vser = DO_UPCAST(VirtIOSerial, vdev, vdev); -+ -+ /* Spawn a new virtio-serial bus on which the ports will ride as devices */ -+ vser->bus = virtser_bus_new(dev); -+ vser->bus->vser = vser; -+ QTAILQ_INIT(&vser->ports); -+ -+ vser->bus->max_nr_ports = max_nr_ports; -+ vser->ivqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *)); -+ vser->ovqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *)); -+ -+ /* Add a queue for host to guest transfers for port 0 (backward compat) */ -+ vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input); -+ /* Add a queue for guest to host transfers for port 0 (backward compat) */ -+ vser->ovqs[0] = virtio_add_queue(vdev, 128, handle_output); -+ -+ /* control queue: host to guest */ -+ vser->c_ivq = virtio_add_queue(vdev, 16, control_in); -+ /* control queue: guest to host */ -+ vser->c_ovq = virtio_add_queue(vdev, 16, control_out); -+ -+ for (i = 1; i < vser->bus->max_nr_ports; i++) { -+ /* Add a per-port queue for host to guest transfers */ -+ vser->ivqs[i] = virtio_add_queue(vdev, 128, handle_input); -+ /* Add a per-per queue for guest to host transfers */ -+ vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output); -+ } -+ -+ vser->config.max_nr_ports = max_nr_ports; -+ /* -+ * Reserve location 0 for a console port for backward compat -+ * (old kernel, new qemu) -+ */ -+ vser->config.nr_ports = 1; -+ -+ vser->vdev.get_features = get_features; -+ vser->vdev.get_config = get_config; -+ vser->vdev.set_config = set_config; -+ -+ /* -+ * Register for the savevm section with the virtio-console name -+ * to preserve backward compat -+ */ -+ register_savevm("virtio-console", -1, 2, virtio_serial_save, -+ virtio_serial_load, vser); -+ -+ return vdev; -+} -diff --git a/hw/virtio-serial.c b/hw/virtio-serial.c -new file mode 100644 -index 0000000..1dc031e ---- /dev/null -+++ b/hw/virtio-serial.c -@@ -0,0 +1,111 @@ -+/* -+ * Virtio Console and Generic Serial Port Devices -+ * -+ * Copyright Red Hat, Inc. 2009 -+ * -+ * Authors: -+ * Amit Shah -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2. See -+ * the COPYING file in the top-level directory. -+ */ -+ -+#include "qemu-char.h" -+#include "virtio-serial.h" -+ -+typedef struct VirtConsole { -+ VirtIOSerialPort port; -+ CharDriverState *chr; -+} VirtConsole; -+ -+ -+/* Callback function that's called when the guest sends us data */ -+static size_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) -+{ -+ VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -+ ssize_t ret; -+ -+ ret = qemu_chr_write(vcon->chr, buf, len); -+ -+ return ret < 0 ? 0 : ret; -+} -+ -+/* Readiness of the guest to accept data on a port */ -+static int chr_can_read(void *opaque) -+{ -+ VirtConsole *vcon = opaque; -+ -+ return virtio_serial_guest_ready(&vcon->port); -+} -+ -+/* Send data from a char device over to the guest */ -+static void chr_read(void *opaque, const uint8_t *buf, int size) -+{ -+ VirtConsole *vcon = opaque; -+ -+ virtio_serial_write(&vcon->port, buf, size); -+} -+ -+static void chr_event(void *opaque, int event) -+{ -+ VirtConsole *vcon = opaque; -+ -+ switch (event) { -+ case CHR_EVENT_OPENED: { -+ virtio_serial_open(&vcon->port); -+ break; -+ } -+ case CHR_EVENT_CLOSED: -+ virtio_serial_close(&vcon->port); -+ break; -+ } -+} -+ -+/* Virtio Console Ports */ -+static int virtconsole_initfn(VirtIOSerialDevice *dev) -+{ -+ VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -+ VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -+ -+ port->info = dev->info; -+ -+ port->is_console = true; -+ -+ if (vcon->chr) { -+ qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event, -+ vcon); -+ port->info->have_data = flush_buf; -+ } -+ return 0; -+} -+ -+static int virtconsole_exitfn(VirtIOSerialDevice *dev) -+{ -+ VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -+ VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -+ -+ if (vcon->chr) { -+ port->info->have_data = NULL; -+ qemu_chr_close(vcon->chr); -+ } -+ -+ return 0; -+} -+ -+static VirtIOSerialPortInfo virtconsole_info = { -+ .qdev.name = "virtconsole", -+ .qdev.size = sizeof(VirtConsole), -+ .init = virtconsole_initfn, -+ .exit = virtconsole_exitfn, -+ .qdev.props = (Property[]) { -+ DEFINE_PROP_UINT8("is_console", VirtConsole, port.is_console, 1), -+ DEFINE_PROP_CHR("chardev", VirtConsole, chr), -+ DEFINE_PROP_END_OF_LIST(), -+ }, -+}; -+ -+static void virtconsole_register(void) -+{ -+ virtio_serial_port_qdev_register(&virtconsole_info); -+} -+device_init(virtconsole_register) -diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h -new file mode 100644 -index 0000000..fe8e357 ---- /dev/null -+++ b/hw/virtio-serial.h -@@ -0,0 +1,158 @@ -+/* -+ * Virtio Serial / Console Support -+ * -+ * Copyright IBM, Corp. 2008 -+ * Copyright Red Hat, Inc. 2009 -+ * -+ * Authors: -+ * Christian Ehrhardt -+ * Amit Shah -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2. See -+ * the COPYING file in the top-level directory. -+ * -+ */ -+#ifndef _QEMU_VIRTIO_SERIAL_H -+#define _QEMU_VIRTIO_SERIAL_H -+ -+#include -+#include "qdev.h" -+#include "virtio.h" -+ -+/* == Interface shared between the guest kernel and qemu == */ -+ -+/* The Virtio ID for virtio console / serial ports */ -+#define VIRTIO_ID_CONSOLE 3 -+ -+/* Features supported */ -+#define VIRTIO_CONSOLE_F_MULTIPORT 1 -+ -+struct virtio_console_config { -+ /* -+ * These two fields are used by VIRTIO_CONSOLE_F_SIZE which -+ * isn't implemented here yet -+ */ -+ uint16_t cols; -+ uint16_t rows; -+ -+ uint32_t max_nr_ports; -+ uint32_t nr_ports; -+} __attribute__((packed)); -+ -+struct virtio_console_control { -+ uint32_t id; /* Port number */ -+ uint16_t event; /* The kind of control event (see below) */ -+ uint16_t value; /* Extra information for the key */ -+}; -+ -+/* Some events for the internal messages (control packets) */ -+#define VIRTIO_CONSOLE_PORT_READY 0 -+#define VIRTIO_CONSOLE_CONSOLE_PORT 1 -+#define VIRTIO_CONSOLE_RESIZE 2 -+ -+/* == In-qemu interface == */ -+ -+typedef struct VirtIOSerial VirtIOSerial; -+typedef struct VirtIOSerialBus VirtIOSerialBus; -+typedef struct VirtIOSerialPort VirtIOSerialPort; -+typedef struct VirtIOSerialPortInfo VirtIOSerialPortInfo; -+ -+typedef struct VirtIOSerialDevice { -+ DeviceState qdev; -+ VirtIOSerialPortInfo *info; -+} VirtIOSerialDevice; -+ -+/* -+ * This is the state that's shared between all the ports. Some of the -+ * state is configurable via command-line options. Some of it can be -+ * set by individual devices in their initfn routines. Some of the -+ * state is set by the generic qdev device init routine. -+ */ -+struct VirtIOSerialPort { -+ DeviceState dev; -+ VirtIOSerialPortInfo *info; -+ -+ QTAILQ_ENTRY(VirtIOSerialPort) next; -+ -+ /* -+ * This field gives us the virtio device as well as the qdev bus -+ * that we are associated with -+ */ -+ VirtIOSerial *vser; -+ -+ VirtQueue *ivq, *ovq; -+ -+ /* -+ * This id helps identify ports between the guest and the host. -+ * The guest sends a "header" with this id with each data packet -+ * that it sends and the host can then find out which associated -+ * device to send out this data to -+ */ -+ uint32_t id; -+ -+ /* Identify if this is a port that binds with hvc in the guest */ -+ uint8_t is_console; -+}; -+ -+struct VirtIOSerialPortInfo { -+ DeviceInfo qdev; -+ /* -+ * The per-port (or per-app) init function that's called when a -+ * new device is found on the bus. -+ */ -+ int (*init)(VirtIOSerialDevice *dev); -+ /* -+ * Per-port exit function that's called when a port gets -+ * hot-unplugged or removed. -+ */ -+ int (*exit)(VirtIOSerialDevice *dev); -+ -+ /* Callbacks for guest events */ -+ /* Guest opened device. */ -+ void (*guest_open)(VirtIOSerialPort *port); -+ /* Guest closed device. */ -+ void (*guest_close)(VirtIOSerialPort *port); -+ -+ /* Guest is now ready to accept data (virtqueues set up). */ -+ void (*guest_ready)(VirtIOSerialPort *port); -+ -+ /* -+ * Guest wrote some data to the port. This data is handed over to -+ * the app via this callback. The app should return the number of -+ * bytes it successfully consumed. -+ */ -+ size_t (*have_data)(VirtIOSerialPort *port, const uint8_t *buf, size_t len); -+}; -+ -+/* Interface to the virtio-serial bus */ -+ -+/* -+ * Individual ports/apps should call this function to register the port -+ * with the virtio-serial bus -+ */ -+void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info); -+ -+/* -+ * Open a connection to the port -+ * Returns 0 on success (always). -+ */ -+int virtio_serial_open(VirtIOSerialPort *port); -+ -+/* -+ * Close the connection to the port -+ * Returns 0 on success (always). -+ */ -+int virtio_serial_close(VirtIOSerialPort *port); -+ -+/* -+ * Send data to Guest -+ */ -+ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf, -+ size_t size); -+ -+/* -+ * Query whether a guest is ready to receive data. -+ */ -+size_t virtio_serial_guest_ready(VirtIOSerialPort *port); -+ -+#endif -diff --git a/hw/virtio.h b/hw/virtio.h -index 051910a..a574928 100644 ---- a/hw/virtio.h -+++ b/hw/virtio.h -@@ -171,7 +171,7 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding, - /* Base devices. */ - VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo); - VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf); --VirtIODevice *virtio_console_init(DeviceState *dev); -+VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports); - VirtIODevice *virtio_balloon_init(DeviceState *dev); - - void virtio_net_exit(VirtIODevice *vdev); -diff --git a/qemu-options.hx b/qemu-options.hx -index ca73ba5..173b1ec 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -1874,6 +1874,10 @@ DEF("virtioconsole", HAS_ARG, QEMU_OPTION_virtiocon, \ - STEXI - @item -virtioconsole @var{c} - Set virtio console. -+ -+This option is maintained for backward compatibility. -+ -+Please use @code{-device virtconsole} for the new way of invocation. - ETEXI - - DEF("show-cursor", 0, QEMU_OPTION_show_cursor, \ -diff --git a/sysemu.h b/sysemu.h -index a545a2b..ff97786 100644 ---- a/sysemu.h -+++ b/sysemu.h -@@ -237,12 +237,6 @@ extern CharDriverState *serial_hds[MAX_SERIAL_PORTS]; - - extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; - --/* virtio consoles */ -- --#define MAX_VIRTIO_CONSOLES 1 -- --extern CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; -- - #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) - - #ifdef HAS_AUDIO -diff --git a/vl.c b/vl.c -index c9d46de..a479ef3 100644 ---- a/vl.c -+++ b/vl.c -@@ -175,6 +175,8 @@ int main(int argc, char **argv) - - #define DEFAULT_RAM_SIZE 128 - -+#define MAX_VIRTIO_CONSOLES 1 -+ - static const char *data_dir; - const char *bios_name = NULL; - /* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available -@@ -300,8 +302,9 @@ static struct { - { .driver = "isa-parallel", .flag = &default_parallel }, - { .driver = "isa-fdc", .flag = &default_floppy }, - { .driver = "ide-drive", .flag = &default_cdrom }, -- { .driver = "virtio-console-pci", .flag = &default_virtcon }, -- { .driver = "virtio-console-s390", .flag = &default_virtcon }, -+ { .driver = "virtio-serial-pci", .flag = &default_virtcon }, -+ { .driver = "virtio-serial-s390", .flag = &default_virtcon }, -+ { .driver = "virtio-serial", .flag = &default_virtcon }, - { .driver = "VGA", .flag = &default_vga }, - { .driver = "cirrus-vga", .flag = &default_vga }, - { .driver = "vmware-svga", .flag = &default_vga }, -@@ -4885,6 +4888,7 @@ static int virtcon_parse(const char *devname) - { - static int index = 0; - char label[32]; -+ QemuOpts *bus_opts, *dev_opts; - - if (strcmp(devname, "none") == 0) - return 0; -@@ -4892,6 +4896,13 @@ static int virtcon_parse(const char *devname) - fprintf(stderr, "qemu: too many virtio consoles\n"); - exit(1); - } -+ -+ bus_opts = qemu_opts_create(&qemu_device_opts, NULL, 0); -+ qemu_opt_set(bus_opts, "driver", "virtio-serial"); -+ -+ dev_opts = qemu_opts_create(&qemu_device_opts, NULL, 0); -+ qemu_opt_set(dev_opts, "driver", "virtconsole"); -+ - snprintf(label, sizeof(label), "virtcon%d", index); - virtcon_hds[index] = qemu_chr_open(label, devname, NULL); - if (!virtcon_hds[index]) { -@@ -4899,6 +4910,8 @@ static int virtcon_parse(const char *devname) - devname, strerror(errno)); - return -1; - } -+ qemu_opt_set(dev_opts, "chardev", label); -+ - index++; - return 0; - } --- -1.6.2.5 - diff --git a/qemu-virtio-move-typedef-to-qemu-common.patch b/qemu-virtio-move-typedef-to-qemu-common.patch deleted file mode 100644 index 6b50335..0000000 --- a/qemu-virtio-move-typedef-to-qemu-common.patch +++ /dev/null @@ -1,34 +0,0 @@ -make it possible to use type without header include - -Signed-off-by: Michael S. Tsirkin ---- - hw/virtio.h | 1 - - qemu-common.h | 1 + - 2 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/hw/virtio.h b/hw/virtio.h -index 39d0763..a5bd0ba 100644 ---- a/hw/virtio.h -+++ b/hw/virtio.h -@@ -68,7 +68,6 @@ static inline target_phys_addr_t vring_align(target_phys_addr_t addr, - } - - typedef struct VirtQueue VirtQueue; --typedef struct VirtIODevice VirtIODevice; - - #define VIRTQUEUE_MAX_SIZE 1024 - -diff --git a/qemu-common.h b/qemu-common.h -index cdead98..1a54f9e 100644 ---- a/qemu-common.h -+++ b/qemu-common.h -@@ -218,6 +218,7 @@ typedef struct I2SCodec I2SCodec; - typedef struct DeviceState DeviceState; - typedef struct SSIBus SSIBus; - typedef struct EventNotifier EventNotifier; -+typedef struct VirtIODevice VirtIODevice; - - /* CPU save/load. */ - void cpu_save(QEMUFile *f, void *opaque); --- -1.6.6.144.g5c3af diff --git a/qemu-virtio-net-mac-property-is-mandatory.patch b/qemu-virtio-net-mac-property-is-mandatory.patch deleted file mode 100644 index 8058b14..0000000 --- a/qemu-virtio-net-mac-property-is-mandatory.patch +++ /dev/null @@ -1,40 +0,0 @@ -Mac feature bit isn't going to work as all network cards already have a -'mac' property to set the mac address. Remove it from mask and add in -get_features. - -Reported-by: Gerd Hoffmann -Signed-off-by: Michael S. Tsirkin -Signed-off-by: Anthony Liguori -(cherry picked from commit c9f79a3f79a48de28b4575cb5644bcf45d3754d0) ---- - hw/virtio-net.c | 2 ++ - hw/virtio-net.h | 1 - - 2 files changed, 2 insertions(+), 1 deletions(-) - -diff --git a/hw/virtio-net.c b/hw/virtio-net.c -index c2a389f..02d9180 100644 ---- a/hw/virtio-net.c -+++ b/hw/virtio-net.c -@@ -151,6 +151,8 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features) - { - VirtIONet *n = to_virtio_net(vdev); - -+ features |= (1 << VIRTIO_NET_F_MAC); -+ - if (peer_has_vnet_hdr(n)) { - tap_using_vnet_hdr(n->nic->nc.peer, 1); - } else { -diff --git a/hw/virtio-net.h b/hw/virtio-net.h -index 9130d75..e55119b 100644 ---- a/hw/virtio-net.h -+++ b/hw/virtio-net.h -@@ -157,7 +157,6 @@ struct virtio_net_ctrl_mac { - DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \ - DEFINE_PROP_BIT("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \ - DEFINE_PROP_BIT("guest_csum", _state, _field, VIRTIO_NET_F_GUEST_CSUM, true), \ -- DEFINE_PROP_BIT("mac", _state, _field, VIRTIO_NET_F_MAC, true), \ - DEFINE_PROP_BIT("gso", _state, _field, VIRTIO_NET_F_GSO, true), \ - DEFINE_PROP_BIT("guest_tso4", _state, _field, VIRTIO_NET_F_GUEST_TSO4, true), \ - DEFINE_PROP_BIT("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \ --- -1.6.6.144.g5c3af diff --git a/qemu-virtio-net-vhost-net-support.patch b/qemu-virtio-net-vhost-net-support.patch deleted file mode 100644 index 147fb82..0000000 --- a/qemu-virtio-net-vhost-net-support.patch +++ /dev/null @@ -1,153 +0,0 @@ -This connects virtio-net to vhost net backend. -The code is structured in a way analogous to what we have with vnet -header capability in tap. We start/stop backend on driver start/stop as -well as on save and vm start (for migration). - -Signed-off-by: Michael S. Tsirkin ---- - hw/virtio-net.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 files changed, 65 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio-net.c b/hw/virtio-net.c -index 02d9180..088029b 100644 ---- a/hw/virtio-net.c -+++ b/hw/virtio-net.c -@@ -17,6 +17,7 @@ - #include "net/tap.h" - #include "qemu-timer.h" - #include "virtio-net.h" -+#include "vhost_net.h" - - #define VIRTIO_NET_VM_VERSION 11 - -@@ -47,6 +48,8 @@ typedef struct VirtIONet - uint8_t nomulti; - uint8_t nouni; - uint8_t nobcast; -+ uint8_t vhost_started; -+ VMChangeStateEntry *vmstate; - struct { - int in_use; - int first_multi; -@@ -114,6 +117,10 @@ static void virtio_net_reset(VirtIODevice *vdev) - n->nomulti = 0; - n->nouni = 0; - n->nobcast = 0; -+ if (n->vhost_started) { -+ vhost_net_stop(tap_get_vhost_net(n->nic->nc.peer), vdev); -+ n->vhost_started = 0; -+ } - - /* Flush any MAC and VLAN filter table state */ - n->mac_table.in_use = 0; -@@ -172,7 +179,10 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features) - features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO); - } - -- return features; -+ if (!tap_get_vhost_net(n->nic->nc.peer)) { -+ return features; -+ } -+ return vhost_net_get_features(tap_get_vhost_net(n->nic->nc.peer), features); - } - - static uint32_t virtio_net_bad_features(VirtIODevice *vdev) -@@ -690,6 +700,12 @@ static void virtio_net_save(QEMUFile *f, void *opaque) - { - VirtIONet *n = opaque; - -+ if (n->vhost_started) { -+ /* TODO: should we really stop the backend? -+ * If we don't, it might keep writing to memory. */ -+ vhost_net_stop(tap_get_vhost_net(n->nic->nc.peer), &n->vdev); -+ n->vhost_started = 0; -+ } - virtio_save(&n->vdev, f); - - qemu_put_buffer(f, n->mac, ETH_ALEN); -@@ -802,7 +818,6 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) - qemu_mod_timer(n->tx_timer, - qemu_get_clock(vm_clock) + TX_TIMER_INTERVAL); - } -- - return 0; - } - -@@ -822,6 +837,47 @@ static NetClientInfo net_virtio_info = { - .link_status_changed = virtio_net_set_link_status, - }; - -+static void virtio_net_set_status(struct VirtIODevice *vdev) -+{ -+ VirtIONet *n = to_virtio_net(vdev); -+ if (!n->nic->nc.peer) { -+ return; -+ } -+ if (n->nic->nc.peer->info->type != NET_CLIENT_TYPE_TAP) { -+ return; -+ } -+ -+ if (!tap_get_vhost_net(n->nic->nc.peer)) { -+ return; -+ } -+ if (!!n->vhost_started == !!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) { -+ return; -+ } -+ if (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) { -+ int r = vhost_net_start(tap_get_vhost_net(n->nic->nc.peer), vdev); -+ if (r < 0) { -+ fprintf(stderr, "unable to start vhost net: %d: " -+ "falling back on userspace virtio\n", -r); -+ } else { -+ n->vhost_started = 1; -+ } -+ } else { -+ vhost_net_stop(tap_get_vhost_net(n->nic->nc.peer), vdev); -+ n->vhost_started = 0; -+ } -+} -+ -+static void virtio_net_vmstate_change(void *opaque, int running, int reason) -+{ -+ VirtIONet *n = opaque; -+ if (!running) { -+ return; -+ } -+ /* This is called when vm is started, it will start vhost backend if it -+ * appropriate e.g. after migration. */ -+ virtio_net_set_status(&n->vdev); -+} -+ - VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf) - { - VirtIONet *n; -@@ -837,6 +893,7 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf) - n->vdev.set_features = virtio_net_set_features; - n->vdev.bad_features = virtio_net_bad_features; - n->vdev.reset = virtio_net_reset; -+ n->vdev.set_status = virtio_net_set_status; - n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx); - n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx); - n->ctrl_vq = virtio_add_queue(&n->vdev, 64, virtio_net_handle_ctrl); -@@ -859,6 +916,7 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf) - - register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION, - virtio_net_save, virtio_net_load, n); -+ n->vmstate = qemu_add_vm_change_state_handler(virtio_net_vmstate_change, n); - - return &n->vdev; - } -@@ -866,6 +924,11 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf) - void virtio_net_exit(VirtIODevice *vdev) - { - VirtIONet *n = DO_UPCAST(VirtIONet, vdev, vdev); -+ qemu_del_vm_change_state_handler(n->vmstate); -+ -+ if (n->vhost_started) { -+ vhost_net_stop(tap_get_vhost_net(n->nic->nc.peer), vdev); -+ } - - qemu_purge_queued_packets(&n->nic->nc); - --- -1.6.6.144.g5c3af diff --git a/qemu-virtio-pci-fill-in-notifier-support.patch b/qemu-virtio-pci-fill-in-notifier-support.patch deleted file mode 100644 index f294576..0000000 --- a/qemu-virtio-pci-fill-in-notifier-support.patch +++ /dev/null @@ -1,98 +0,0 @@ -Support host/guest notifiers in virtio-pci. -The last one only with kvm, that's okay -because vhost relies on kvm anyway. - -Signed-off-by: Michael S. Tsirkin ---- - hw/virtio-pci.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 files changed, 62 insertions(+), 0 deletions(-) - -diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c -index 05898c8..c454093 100644 ---- a/hw/virtio-pci.c -+++ b/hw/virtio-pci.c -@@ -23,6 +23,7 @@ - #include "msix.h" - #include "net.h" - #include "loader.h" -+#include "kvm.h" - - /* from Linux's linux/virtio_pci.h */ - -@@ -394,6 +395,65 @@ static unsigned virtio_pci_get_features(void *opaque) - return proxy->host_features; - } - -+static void virtio_pci_guest_notifier_read(void *opaque) -+{ -+ VirtQueue *vq = opaque; -+ EventNotifier *n = virtio_queue_guest_notifier(vq); -+ if (event_notifier_test_and_clear(n)) { -+ virtio_irq(vq); -+ } -+} -+ -+static int virtio_pci_guest_notifier(void *opaque, int n, bool assign) -+{ -+ VirtIOPCIProxy *proxy = opaque; -+ VirtQueue *vq = virtio_queue(proxy->vdev, n); -+ EventNotifier *notifier = virtio_queue_guest_notifier(vq); -+ -+ if (assign) { -+ int r = event_notifier_init(notifier, 0); -+ if (r < 0) -+ return r; -+ qemu_set_fd_handler(event_notifier_get_fd(notifier), -+ virtio_pci_guest_notifier_read, NULL, vq); -+ } else { -+ qemu_set_fd_handler(event_notifier_get_fd(notifier), -+ NULL, NULL, vq); -+ event_notifier_cleanup(notifier); -+ } -+ -+ return 0; -+} -+ -+static int virtio_pci_host_notifier(void *opaque, int n, bool assign) -+{ -+ VirtIOPCIProxy *proxy = opaque; -+ VirtQueue *vq = virtio_queue(proxy->vdev, n); -+ EventNotifier *notifier = virtio_queue_host_notifier(vq); -+ int r; -+ if (assign) { -+ r = event_notifier_init(notifier, 1); -+ if (r < 0) { -+ return r; -+ } -+ r = kvm_set_ioeventfd(proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY, -+ n, event_notifier_get_fd(notifier), -+ assign); -+ if (r < 0) { -+ event_notifier_cleanup(notifier); -+ } -+ } else { -+ r = kvm_set_ioeventfd(proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY, -+ n, event_notifier_get_fd(notifier), -+ assign); -+ if (r < 0) { -+ return r; -+ } -+ event_notifier_cleanup(notifier); -+ } -+ return r; -+} -+ - static const VirtIOBindings virtio_pci_bindings = { - .notify = virtio_pci_notify, - .save_config = virtio_pci_save_config, -@@ -401,6 +461,8 @@ static const VirtIOBindings virtio_pci_bindings = { - .save_queue = virtio_pci_save_queue, - .load_queue = virtio_pci_load_queue, - .get_features = virtio_pci_get_features, -+ .host_notifier = virtio_pci_host_notifier, -+ .guest_notifier = virtio_pci_guest_notifier, - }; - - static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, --- -1.6.6.144.g5c3af diff --git a/qemu-virtio-pci-irqfd-fix-nonkvm-build.patch b/qemu-virtio-pci-irqfd-fix-nonkvm-build.patch deleted file mode 100644 index cbdd372..0000000 --- a/qemu-virtio-pci-irqfd-fix-nonkvm-build.patch +++ /dev/null @@ -1,34 +0,0 @@ -Signed-off-by: Michael S. Tsirkin - ---- - -diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c -index e8e0d82..fd0c73f 100644 ---- a/hw/virtio-pci.c -+++ b/hw/virtio-pci.c -@@ -404,6 +404,7 @@ static void virtio_pci_guest_notifier_read(void *opaque) - } - } - -+#ifdef CONFIG_KVM - static int virtio_pci_mask_notifier(PCIDevice *dev, unsigned vector, - void *opaque, int masked) - { -@@ -424,6 +425,7 @@ static int virtio_pci_mask_notifier(PCIDevice *dev, unsigned vector, - } - return 0; - } -+#endif - - static int virtio_pci_guest_notifier(void *opaque, int n, bool assign) - { -@@ -526,7 +528,9 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, - - proxy->pci_dev.config_write = virtio_write_config; - -+#ifdef CONFIG_KVM - proxy->pci_dev.msix_mask_notifier = virtio_pci_mask_notifier; -+#endif - - size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len; - if (size & (size-1)) diff --git a/qemu-virtio-pci-irqfd-support.patch b/qemu-virtio-pci-irqfd-support.patch deleted file mode 100644 index 385f2a4..0000000 --- a/qemu-virtio-pci-irqfd-support.patch +++ /dev/null @@ -1,70 +0,0 @@ -Use irqfd when supported by kernel. -This uses msix mask notifiers: when vector is masked, we poll it from -userspace. When it is unmasked, we poll it from kernel. - -Signed-off-by: Michael S. Tsirkin ---- - hw/virtio-pci.c | 31 +++++++++++++++++++++++++++++-- - 1 files changed, 29 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c -index c454093..e8e0d82 100644 ---- a/hw/virtio-pci.c -+++ b/hw/virtio-pci.c -@@ -404,6 +404,27 @@ static void virtio_pci_guest_notifier_read(void *opaque) - } - } - -+static int virtio_pci_mask_notifier(PCIDevice *dev, unsigned vector, -+ void *opaque, int masked) -+{ -+ VirtQueue *vq = opaque; -+ EventNotifier *notifier = virtio_queue_guest_notifier(vq); -+ int r = kvm_set_irqfd(dev->msix_irq_entries[vector].gsi, -+ event_notifier_get_fd(notifier), -+ !masked); -+ if (r < 0) { -+ return (r == -ENOSYS) ? 0 : r; -+ } -+ if (masked) { -+ qemu_set_fd_handler(event_notifier_get_fd(notifier), -+ virtio_pci_guest_notifier_read, NULL, vq); -+ } else { -+ qemu_set_fd_handler(event_notifier_get_fd(notifier), -+ NULL, NULL, vq); -+ } -+ return 0; -+} -+ - static int virtio_pci_guest_notifier(void *opaque, int n, bool assign) - { - VirtIOPCIProxy *proxy = opaque; -@@ -412,11 +433,15 @@ static int virtio_pci_guest_notifier(void *opaque, int n, bool assign) - - if (assign) { - int r = event_notifier_init(notifier, 0); -- if (r < 0) -- return r; -+ if (r < 0) -+ return r; - qemu_set_fd_handler(event_notifier_get_fd(notifier), - virtio_pci_guest_notifier_read, NULL, vq); -+ msix_set_mask_notifier(&proxy->pci_dev, -+ virtio_queue_vector(proxy->vdev, n), vq); - } else { -+ msix_set_mask_notifier(&proxy->pci_dev, -+ virtio_queue_vector(proxy->vdev, n), NULL); - qemu_set_fd_handler(event_notifier_get_fd(notifier), - NULL, NULL, vq); - event_notifier_cleanup(notifier); -@@ -501,6 +526,8 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, - - proxy->pci_dev.config_write = virtio_write_config; - -+ proxy->pci_dev.msix_mask_notifier = virtio_pci_mask_notifier; -+ - size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len; - if (size & (size-1)) - size = 1 << qemu_fls(size); --- -1.6.6.144.g5c3af diff --git a/qemu-virtio-rename-features-guest_features.patch b/qemu-virtio-rename-features-guest_features.patch deleted file mode 100644 index 8ffc084..0000000 --- a/qemu-virtio-rename-features-guest_features.patch +++ /dev/null @@ -1,149 +0,0 @@ -Rename features->guest_features. This is -what they are, avoid confusion with -host features which we also need to keep around. - -Signed-off-by: Michael S. Tsirkin -Signed-off-by: Anthony Liguori -(cherry picked from commit 704a76fcd24372a683652651b4597f6654084975) ---- - hw/s390-virtio-bus.c | 2 +- - hw/syborg_virtio.c | 4 ++-- - hw/virtio-net.c | 10 +++++----- - hw/virtio-pci.c | 4 ++-- - hw/virtio.c | 8 ++++---- - hw/virtio.h | 2 +- - 6 files changed, 15 insertions(+), 15 deletions(-) - -diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c -index dc154ed..6c0da11 100644 ---- a/hw/s390-virtio-bus.c -+++ b/hw/s390-virtio-bus.c -@@ -251,7 +251,7 @@ void s390_virtio_device_update_status(VirtIOS390Device *dev) - if (vdev->set_features) { - vdev->set_features(vdev, features); - } -- vdev->features = features; -+ vdev->guest_features = features; - } - - VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus) -diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c -index a84206a..fe6fc23 100644 ---- a/hw/syborg_virtio.c -+++ b/hw/syborg_virtio.c -@@ -90,7 +90,7 @@ static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset) - ret |= vdev->binding->get_features(s); - break; - case SYBORG_VIRTIO_GUEST_FEATURES: -- ret = vdev->features; -+ ret = vdev->guest_features; - break; - case SYBORG_VIRTIO_QUEUE_BASE: - ret = virtio_queue_get_addr(vdev, vdev->queue_sel); -@@ -132,7 +132,7 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset, - case SYBORG_VIRTIO_GUEST_FEATURES: - if (vdev->set_features) - vdev->set_features(vdev, value); -- vdev->features = value; -+ vdev->guest_features = value; - break; - case SYBORG_VIRTIO_QUEUE_BASE: - if (value == 0) -diff --git a/hw/virtio-net.c b/hw/virtio-net.c -index 2f201ff..ab20a33 100644 ---- a/hw/virtio-net.c -+++ b/hw/virtio-net.c -@@ -768,11 +768,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) - if (n->has_vnet_hdr) { - tap_using_vnet_hdr(n->nic->nc.peer, 1); - tap_set_offload(n->nic->nc.peer, -- (n->vdev.features >> VIRTIO_NET_F_GUEST_CSUM) & 1, -- (n->vdev.features >> VIRTIO_NET_F_GUEST_TSO4) & 1, -- (n->vdev.features >> VIRTIO_NET_F_GUEST_TSO6) & 1, -- (n->vdev.features >> VIRTIO_NET_F_GUEST_ECN) & 1, -- (n->vdev.features >> VIRTIO_NET_F_GUEST_UFO) & 1); -+ (n->vdev.guest_features >> VIRTIO_NET_F_GUEST_CSUM) & 1, -+ (n->vdev.guest_features >> VIRTIO_NET_F_GUEST_TSO4) & 1, -+ (n->vdev.guest_features >> VIRTIO_NET_F_GUEST_TSO6) & 1, -+ (n->vdev.guest_features >> VIRTIO_NET_F_GUEST_ECN) & 1, -+ (n->vdev.guest_features >> VIRTIO_NET_F_GUEST_UFO) & 1); - } - } - -diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c -index 3594152..c23dbc0 100644 ---- a/hw/virtio-pci.c -+++ b/hw/virtio-pci.c -@@ -181,7 +181,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) - } - if (vdev->set_features) - vdev->set_features(vdev, val); -- vdev->features = val; -+ vdev->guest_features = val; - break; - case VIRTIO_PCI_QUEUE_PFN: - pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT; -@@ -239,7 +239,7 @@ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr) - ret |= vdev->binding->get_features(proxy); - break; - case VIRTIO_PCI_GUEST_FEATURES: -- ret = vdev->features; -+ ret = vdev->guest_features; - break; - case VIRTIO_PCI_QUEUE_PFN: - ret = virtio_queue_get_addr(vdev, vdev->queue_sel) -diff --git a/hw/virtio.c b/hw/virtio.c -index cecd0dc..c25a5f1 100644 ---- a/hw/virtio.c -+++ b/hw/virtio.c -@@ -445,7 +445,7 @@ void virtio_reset(void *opaque) - if (vdev->reset) - vdev->reset(vdev); - -- vdev->features = 0; -+ vdev->guest_features = 0; - vdev->queue_sel = 0; - vdev->status = 0; - vdev->isr = 0; -@@ -598,7 +598,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) - { - /* Always notify when queue is empty (when feature acknowledge) */ - if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) && -- (!(vdev->features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) || -+ (!(vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) || - (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx))) - return; - -@@ -625,7 +625,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) - qemu_put_8s(f, &vdev->status); - qemu_put_8s(f, &vdev->isr); - qemu_put_be16s(f, &vdev->queue_sel); -- qemu_put_be32s(f, &vdev->features); -+ qemu_put_be32s(f, &vdev->guest_features); - qemu_put_be32(f, vdev->config_len); - qemu_put_buffer(f, vdev->config, vdev->config_len); - -@@ -670,7 +670,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) - features, supported_features); - return -1; - } -- vdev->features = features; -+ vdev->guest_features = features; - vdev->config_len = qemu_get_be32(f); - qemu_get_buffer(f, vdev->config, vdev->config_len); - -diff --git a/hw/virtio.h b/hw/virtio.h -index 35532a6..85ef171 100644 ---- a/hw/virtio.h -+++ b/hw/virtio.h -@@ -100,7 +100,7 @@ struct VirtIODevice - uint8_t status; - uint8_t isr; - uint16_t queue_sel; -- uint32_t features; -+ uint32_t guest_features; - size_t config_len; - void *config; - uint16_t config_vector; --- -1.6.6.144.g5c3af diff --git a/qemu-virtio-serial-Add-a-virtserialport-device-for-gen.patch b/qemu-virtio-serial-Add-a-virtserialport-device-for-gen.patch deleted file mode 100644 index d23e96e..0000000 --- a/qemu-virtio-serial-Add-a-virtserialport-device-for-gen.patch +++ /dev/null @@ -1,63 +0,0 @@ -From fcb66d7ac2271bcf0b46d6b1ae2d3db38e78bf2b Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Wed, 20 Jan 2010 00:36:56 +0530 -Subject: [PATCH 6/9] virtio-serial: Add a 'virtserialport' device for generic serial port support - -This commit adds a simple chardev-based serial port. Any data the guest -sends is forwarded to the chardev and vice-versa. - -Sample uses for such a device can be obtaining info from the guest like -the file systems used, apps installed, etc. for offline usage and -logged-in users, clipboard copy-paste, etc. for online usage. - -Signed-off-by: Amit Shah -Signed-off-by: Anthony Liguori ---- - hw/virtio-serial.c | 34 ++++++++++++++++++++++++++++++++++ - 1 files changed, 34 insertions(+), 0 deletions(-) - -diff --git a/hw/virtio-serial.c b/hw/virtio-serial.c -index 9c2c93c..bd44ec6 100644 ---- a/hw/virtio-serial.c -+++ b/hw/virtio-serial.c -@@ -110,3 +110,37 @@ static void virtconsole_register(void) - virtio_serial_port_qdev_register(&virtconsole_info); - } - device_init(virtconsole_register) -+ -+/* Generic Virtio Serial Ports */ -+static int virtserialport_initfn(VirtIOSerialDevice *dev) -+{ -+ VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); -+ VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -+ -+ port->info = dev->info; -+ -+ if (vcon->chr) { -+ qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event, -+ vcon); -+ port->info->have_data = flush_buf; -+ } -+ return 0; -+} -+ -+static VirtIOSerialPortInfo virtserialport_info = { -+ .qdev.name = "virtserialport", -+ .qdev.size = sizeof(VirtConsole), -+ .init = virtserialport_initfn, -+ .exit = virtconsole_exitfn, -+ .qdev.props = (Property[]) { -+ DEFINE_PROP_CHR("chardev", VirtConsole, chr), -+ DEFINE_PROP_STRING("name", VirtConsole, port.name), -+ DEFINE_PROP_END_OF_LIST(), -+ }, -+}; -+ -+static void virtserialport_register(void) -+{ -+ virtio_serial_port_qdev_register(&virtserialport_info); -+} -+device_init(virtserialport_register) --- -1.6.2.5 - diff --git a/qemu-virtio-serial-Use-MSI-vectors-for-port-virtqueues.patch b/qemu-virtio-serial-Use-MSI-vectors-for-port-virtqueues.patch deleted file mode 100644 index 94fbd23..0000000 --- a/qemu-virtio-serial-Use-MSI-vectors-for-port-virtqueues.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 43fa8533e10c478825952d489269d55e5c652c1a Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Wed, 20 Jan 2010 00:36:58 +0530 -Subject: [PATCH 8/9] virtio-serial: Use MSI vectors for port virtqueues - -This commit enables the use of MSI interrupts for virtqueue -notifications for ports. We use nr_ports + 1 (for control channel) msi -entries for the ports, as only the in_vq operations need an interrupt on -the guest. - -Signed-off-by: Amit Shah -Signed-off-by: Anthony Liguori ---- - hw/virtio-pci.c | 4 ++++ - 1 files changed, 4 insertions(+), 0 deletions(-) - -diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c -index c1a1e4c..4451a63 100644 ---- a/hw/virtio-pci.c -+++ b/hw/virtio-pci.c -@@ -497,10 +497,13 @@ static int virtio_serial_init_pci(PCIDevice *pci_dev) - if (!vdev) { - return -1; - } -+ vdev->nvectors = proxy->nvectors ? proxy->nvectors -+ : proxy->max_virtserial_ports + 1; - virtio_init_pci(proxy, vdev, - PCI_VENDOR_ID_REDHAT_QUMRANET, - PCI_DEVICE_ID_VIRTIO_CONSOLE, - proxy->class_code, 0x00); -+ proxy->nvectors = vdev->nvectors; - return 0; - } - -@@ -577,6 +580,7 @@ static PCIDeviceInfo virtio_info[] = { - .init = virtio_serial_init_pci, - .exit = virtio_exit_pci, - .qdev.props = (Property[]) { -+ DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 0), - DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), - DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, max_virtserial_ports, - 31), --- -1.6.2.5 - diff --git a/qemu-virtio-serial-bus-Add-a-port-name-property-for-po.patch b/qemu-virtio-serial-bus-Add-a-port-name-property-for-po.patch deleted file mode 100644 index c3f3ec5..0000000 --- a/qemu-virtio-serial-bus-Add-a-port-name-property-for-po.patch +++ /dev/null @@ -1,116 +0,0 @@ -From ed4daf8c7722562ec05e83ec98a4d4d8adf20f7f Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Wed, 20 Jan 2010 00:36:54 +0530 -Subject: [PATCH 4/9] virtio-serial-bus: Add a port 'name' property for port discovery in guests - -The port 'id' or number is internal state between the guest kernel and -our bus implementation. This is invocation-dependent and isn't part of -the guest-host ABI. - -To correcly enumerate and map ports between the host and the guest, the -'name' property is used. - -Example: - - -device virtserialport,name=org.qemu.port.0 - -This invocation will get us a char device in the guest at: - - /dev/virtio-ports/org.qemu.port.0 - -which can be a symlink to - - /dev/vport0p3 - -This 'name' property is exposed by the guest kernel in a sysfs -attribute: - - /sys/kernel/virtio-ports/vport0p3/name - -A simple udev script can pick up this name and create the symlink -mentioned above. - -Signed-off-by: Amit Shah -Signed-off-by: Anthony Liguori ---- - hw/virtio-serial-bus.c | 17 +++++++++++++++++ - hw/virtio-serial.c | 1 + - hw/virtio-serial.h | 8 ++++++++ - 3 files changed, 26 insertions(+), 0 deletions(-) - -diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c -index 9af21df..6d69c56 100644 ---- a/hw/virtio-serial-bus.c -+++ b/hw/virtio-serial-bus.c -@@ -204,6 +204,8 @@ static void handle_control_message(VirtIOSerial *vser, void *buf) - { - struct VirtIOSerialPort *port; - struct virtio_console_control cpkt, *gcpkt; -+ uint8_t *buffer; -+ size_t buffer_len; - - gcpkt = buf; - port = find_port_by_id(vser, ldl_p(&gcpkt->id)); -@@ -226,6 +228,21 @@ static void handle_control_message(VirtIOSerial *vser, void *buf) - send_control_event(port, VIRTIO_CONSOLE_CONSOLE_PORT, 1); - } - -+ if (port->name) { -+ stw_p(&cpkt.event, VIRTIO_CONSOLE_PORT_NAME); -+ stw_p(&cpkt.value, 1); -+ -+ buffer_len = sizeof(cpkt) + strlen(port->name) + 1; -+ buffer = qemu_malloc(buffer_len); -+ -+ memcpy(buffer, &cpkt, sizeof(cpkt)); -+ memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name)); -+ buffer[buffer_len - 1] = 0; -+ -+ send_control_msg(port, buffer, buffer_len); -+ qemu_free(buffer); -+ } -+ - if (port->host_connected) { - send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1); - } -diff --git a/hw/virtio-serial.c b/hw/virtio-serial.c -index 1dc031e..9c2c93c 100644 ---- a/hw/virtio-serial.c -+++ b/hw/virtio-serial.c -@@ -100,6 +100,7 @@ static VirtIOSerialPortInfo virtconsole_info = { - .qdev.props = (Property[]) { - DEFINE_PROP_UINT8("is_console", VirtConsole, port.is_console, 1), - DEFINE_PROP_CHR("chardev", VirtConsole, chr), -+ DEFINE_PROP_STRING("name", VirtConsole, port.name), - DEFINE_PROP_END_OF_LIST(), - }, - }; -diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h -index d9c7acb..28ea7da 100644 ---- a/hw/virtio-serial.h -+++ b/hw/virtio-serial.h -@@ -50,6 +50,7 @@ struct virtio_console_control { - #define VIRTIO_CONSOLE_CONSOLE_PORT 1 - #define VIRTIO_CONSOLE_RESIZE 2 - #define VIRTIO_CONSOLE_PORT_OPEN 3 -+#define VIRTIO_CONSOLE_PORT_NAME 4 - - /* == In-qemu interface == */ - -@@ -84,6 +85,13 @@ struct VirtIOSerialPort { - VirtQueue *ivq, *ovq; - - /* -+ * This name is sent to the guest and exported via sysfs. -+ * The guest could create symlinks based on this information. -+ * The name is in the reverse fqdn format, like org.qemu.console.0 -+ */ -+ char *name; -+ -+ /* - * This id helps identify ports between the guest and the host. - * The guest sends a "header" with this id with each data packet - * that it sends and the host can then find out which associated --- -1.6.2.5 - diff --git a/qemu-virtio-serial-bus-Add-ability-to-hot-unplug-ports.patch b/qemu-virtio-serial-bus-Add-ability-to-hot-unplug-ports.patch deleted file mode 100644 index 6a426b8..0000000 --- a/qemu-virtio-serial-bus-Add-ability-to-hot-unplug-ports.patch +++ /dev/null @@ -1,40 +0,0 @@ -From c101ff585d5b156a1f3461015a9acd73f15a45f6 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Wed, 20 Jan 2010 00:36:55 +0530 -Subject: [PATCH 5/9] virtio-serial-bus: Add ability to hot-unplug ports - -Signed-off-by: Amit Shah -Signed-off-by: Anthony Liguori ---- - hw/virtio-serial-bus.c | 2 ++ - hw/virtio-serial.h | 1 + - 2 files changed, 3 insertions(+), 0 deletions(-) - -diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c -index 6d69c56..037864f 100644 ---- a/hw/virtio-serial-bus.c -+++ b/hw/virtio-serial-bus.c -@@ -517,6 +517,8 @@ static int virtser_port_qdev_exit(DeviceState *qdev) - VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); - VirtIOSerial *vser = port->vser; - -+ send_control_event(port, VIRTIO_CONSOLE_PORT_REMOVE, 1); -+ - /* - * Don't decrement nr_ports here; thus we keep a linearly - * increasing port id. Not utilising an id again saves us a couple -diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h -index 28ea7da..f297b00 100644 ---- a/hw/virtio-serial.h -+++ b/hw/virtio-serial.h -@@ -51,6 +51,7 @@ struct virtio_console_control { - #define VIRTIO_CONSOLE_RESIZE 2 - #define VIRTIO_CONSOLE_PORT_OPEN 3 - #define VIRTIO_CONSOLE_PORT_NAME 4 -+#define VIRTIO_CONSOLE_PORT_REMOVE 5 - - /* == In-qemu interface == */ - --- -1.6.2.5 - diff --git a/qemu-virtio-serial-bus-Maintain-guest-and-host-port-open.patch b/qemu-virtio-serial-bus-Maintain-guest-and-host-port-open.patch deleted file mode 100644 index 56ee29f..0000000 --- a/qemu-virtio-serial-bus-Maintain-guest-and-host-port-open.patch +++ /dev/null @@ -1,232 +0,0 @@ -From 4945aee74f494cc8a17ce1634b5200eb9ee227d2 Mon Sep 17 00:00:00 2001 -From: Amit Shah -Date: Wed, 20 Jan 2010 00:36:53 +0530 -Subject: [PATCH 3/9] virtio-serial-bus: Maintain guest and host port open/close state - -Via control channel messages, the guest can tell us whether a port got -opened or closed. Similarly, we can also indicate to the guest of host -port open/close events. - -Signed-off-by: Amit Shah -Signed-off-by: Anthony Liguori ---- - hw/virtio-serial-bus.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ - hw/virtio-serial.h | 6 +++ - 2 files changed, 100 insertions(+), 0 deletions(-) - -diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c -index 5132c9c..9af21df 100644 ---- a/hw/virtio-serial-bus.c -+++ b/hw/virtio-serial-bus.c -@@ -66,6 +66,11 @@ static VirtIOSerialPort *find_port_by_vq(VirtIOSerial *vser, VirtQueue *vq) - return NULL; - } - -+static bool use_multiport(VirtIOSerial *vser) -+{ -+ return vser->vdev.features & (1 << VIRTIO_CONSOLE_F_MULTIPORT); -+} -+ - static size_t write_to_port(VirtIOSerialPort *port, - const uint8_t *buf, size_t size) - { -@@ -139,11 +144,22 @@ static size_t send_control_event(VirtIOSerialPort *port, uint16_t event, - /* Functions for use inside qemu to open and read from/write to ports */ - int virtio_serial_open(VirtIOSerialPort *port) - { -+ /* Don't allow opening an already-open port */ -+ if (port->host_connected) { -+ return 0; -+ } -+ /* Send port open notification to the guest */ -+ port->host_connected = true; -+ send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1); -+ - return 0; - } - - int virtio_serial_close(VirtIOSerialPort *port) - { -+ port->host_connected = false; -+ send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 0); -+ - return 0; - } - -@@ -151,6 +167,9 @@ int virtio_serial_close(VirtIOSerialPort *port) - ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf, - size_t size) - { -+ if (!port || !port->host_connected || !port->guest_connected) { -+ return 0; -+ } - return write_to_port(port, buf, size); - } - -@@ -167,6 +186,9 @@ size_t virtio_serial_guest_ready(VirtIOSerialPort *port) - virtio_queue_empty(vq)) { - return 0; - } -+ if (use_multiport(port->vser) && !port->guest_connected) { -+ return 0; -+ } - - if (virtqueue_avail_bytes(vq, 4096, 0)) { - return 4096; -@@ -203,6 +225,11 @@ static void handle_control_message(VirtIOSerial *vser, void *buf) - if (port->is_console) { - send_control_event(port, VIRTIO_CONSOLE_CONSOLE_PORT, 1); - } -+ -+ if (port->host_connected) { -+ send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1); -+ } -+ - /* - * When the guest has asked us for this information it means - * the guest is all setup and has its virtqueues -@@ -213,6 +240,19 @@ static void handle_control_message(VirtIOSerial *vser, void *buf) - port->info->guest_ready(port); - } - break; -+ -+ case VIRTIO_CONSOLE_PORT_OPEN: -+ port->guest_connected = cpkt.value; -+ if (cpkt.value && port->info->guest_open) { -+ /* Send the guest opened notification if an app is interested */ -+ port->info->guest_open(port); -+ } -+ -+ if (!cpkt.value && port->info->guest_close) { -+ /* Send the guest closed notification if an app is interested */ -+ port->info->guest_close(port); -+ } -+ break; - } - } - -@@ -300,6 +340,8 @@ static void set_config(VirtIODevice *vdev, const uint8_t *config_data) - static void virtio_serial_save(QEMUFile *f, void *opaque) - { - VirtIOSerial *s = opaque; -+ VirtIOSerialPort *port; -+ uint32_t nr_active_ports; - - /* The virtio device */ - virtio_save(&s->vdev, f); -@@ -308,15 +350,41 @@ static void virtio_serial_save(QEMUFile *f, void *opaque) - qemu_put_be16s(f, &s->config.cols); - qemu_put_be16s(f, &s->config.rows); - qemu_put_be32s(f, &s->config.nr_ports); -+ -+ /* Items in struct VirtIOSerial */ -+ -+ /* Do this because we might have hot-unplugged some ports */ -+ nr_active_ports = 0; -+ QTAILQ_FOREACH(port, &s->ports, next) -+ nr_active_ports++; -+ -+ qemu_put_be32s(f, &nr_active_ports); -+ -+ /* -+ * Items in struct VirtIOSerialPort. -+ */ -+ QTAILQ_FOREACH(port, &s->ports, next) { -+ /* -+ * We put the port number because we may not have an active -+ * port at id 0 that's reserved for a console port, or in case -+ * of ports that might have gotten unplugged -+ */ -+ qemu_put_be32s(f, &port->id); -+ qemu_put_byte(f, port->guest_connected); -+ } - } - - static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) - { - VirtIOSerial *s = opaque; -+ VirtIOSerialPort *port; -+ uint32_t nr_active_ports; -+ unsigned int i; - - if (version_id > 2) { - return -EINVAL; - } -+ - /* The virtio device */ - virtio_load(&s->vdev, f); - -@@ -329,6 +397,20 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) - qemu_get_be16s(f, &s->config.rows); - s->config.nr_ports = qemu_get_be32(f); - -+ /* Items in struct VirtIOSerial */ -+ -+ qemu_get_be32s(f, &nr_active_ports); -+ -+ /* Items in struct VirtIOSerialPort */ -+ for (i = 0; i < nr_active_ports; i++) { -+ uint32_t id; -+ -+ id = qemu_get_be32(f); -+ port = find_port_by_id(s, id); -+ -+ port->guest_connected = qemu_get_byte(f); -+ } -+ - return 0; - } - -@@ -357,6 +439,10 @@ static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent) - - monitor_printf(mon, "%*s dev-prop-int: id: %u\n", - indent, "", port->id); -+ monitor_printf(mon, "%*s dev-prop-int: guest_connected: %d\n", -+ indent, "", port->guest_connected); -+ monitor_printf(mon, "%*s dev-prop-int: host_connected: %d\n", -+ indent, "", port->host_connected); - } - - static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) -@@ -390,6 +476,14 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) - - port->id = plugging_port0 ? 0 : port->vser->config.nr_ports++; - -+ if (!use_multiport(port->vser)) { -+ /* -+ * Allow writes to guest in this case; we have no way of -+ * knowing if a guest port is connected. -+ */ -+ port->guest_connected = true; -+ } -+ - QTAILQ_INSERT_TAIL(&port->vser->ports, port, next); - port->ivq = port->vser->ivqs[port->id]; - port->ovq = port->vser->ovqs[port->id]; -diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h -index fe8e357..d9c7acb 100644 ---- a/hw/virtio-serial.h -+++ b/hw/virtio-serial.h -@@ -49,6 +49,7 @@ struct virtio_console_control { - #define VIRTIO_CONSOLE_PORT_READY 0 - #define VIRTIO_CONSOLE_CONSOLE_PORT 1 - #define VIRTIO_CONSOLE_RESIZE 2 -+#define VIRTIO_CONSOLE_PORT_OPEN 3 - - /* == In-qemu interface == */ - -@@ -92,6 +93,11 @@ struct VirtIOSerialPort { - - /* Identify if this is a port that binds with hvc in the guest */ - uint8_t is_console; -+ -+ /* Is the corresponding guest device open? */ -+ bool guest_connected; -+ /* Is this device open for IO on the host? */ -+ bool host_connected; - }; - - struct VirtIOSerialPortInfo { --- -1.6.2.5 - diff --git a/qemu-virtio-serial-features-build-fix.patch b/qemu-virtio-serial-features-build-fix.patch deleted file mode 100644 index b05629e..0000000 --- a/qemu-virtio-serial-features-build-fix.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/hw/virtio-serial-bus.c 2010-02-09 00:41:21.000000000 -0600 -+++ b/hw/virtio-serial-bus.c 2010-02-09 00:07:13.000000000 -0600 -@@ -68,7 +68,7 @@ static VirtIOSerialPort *find_port_by_vq - - static bool use_multiport(VirtIOSerial *vser) - { -- return vser->vdev.features & (1 << VIRTIO_CONSOLE_F_MULTIPORT); -+ return vser->vdev.guest_features & (1 << VIRTIO_CONSOLE_F_MULTIPORT); - } - - static size_t write_to_port(VirtIOSerialPort *port, -@@ -333,9 +333,11 @@ static void handle_input(VirtIODevice *v - { - } - --static uint32_t get_features(VirtIODevice *vdev) -+static uint32_t get_features(VirtIODevice *vdev, uint32_t features) - { -- return 1 << VIRTIO_CONSOLE_F_MULTIPORT; -+ features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT); -+ -+ return features; - } - - /* Guest requested config info */ diff --git a/qemu.spec b/qemu.spec index 44b26b7..562aed0 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,7 +1,9 @@ +%define githead b81fe95 + Summary: QEMU is a FAST! processor emulator Name: qemu -Version: 0.12.3 -Release: 8%{?dist} +Version: 0.13.0 +Release: 0.1.20100727git%{githead}%{?dist} # Epoch because we pushed a qemu-1.0 package Epoch: 2 License: GPLv2+ and LGPLv2+ and BSD @@ -17,7 +19,11 @@ URL: http://www.qemu.org/ %define _smp_mflags %{nil} %endif -Source0: http://downloads.sourceforge.net/sourceforge/kvm/qemu-kvm-%{version}.tar.gz +# Source0: http://downloads.sourceforge.net/sourceforge/kvm/qemu-kvm-%{version}.tar.gz +# The source for this package was pulled from upstream's git. Use the +# following commands to generate the tarball: +# git archive --format=tar --prefix=qemu-kvm-0.13/ b81fe95 | gzip > qemu-kvm-0.13-b81fe95.tar.gz +Source0: qemu-kvm-%{version}-%{githead}.tar.gz Source1: qemu.init # Loads kvm kernel modules at boot @@ -33,68 +39,6 @@ Source6: ksmtuned.init Source7: ksmtuned Source8: ksmtuned.conf -# virtio-console changes for the F13 VirtioSerial feature -Patch01: qemu-virtio-Remove-duplicate-macro-definition-for-max.-v.patch -Patch02: qemu-virtio-console-qdev-conversion-new-virtio-serial-b.patch -Patch03: qemu-virtio-serial-bus-Maintain-guest-and-host-port-open.patch -Patch04: qemu-virtio-serial-bus-Add-a-port-name-property-for-po.patch -Patch05: qemu-virtio-serial-bus-Add-ability-to-hot-unplug-ports.patch -Patch06: qemu-virtio-serial-Add-a-virtserialport-device-for-gen.patch -Patch07: qemu-Move-virtio-serial-to-Makefile.objs.patch -Patch08: qemu-virtio-serial-Use-MSI-vectors-for-port-virtqueues.patch -Patch09: qemu-virtio-console-Rename-virtio-serial.c-back-to-virti.patch - -Patch10: qemu-v2-block-avoid-creating-too-large-iovecs-in-multiwrite_merge.patch - -# VHostNet Patches -Patch11: qemu-net-add-API-to-disable-enable-polling.patch -Patch12: qemu-virtio-rename-features-guest_features.patch -Patch13: qemu-qdev-add-bit-property-type.patch -Patch14: qemu-qdev-fix-thinko-leading-to-guest-crashes.patch -Patch15: qemu-virtio-add-features-as-qdev-properties.patch -Patch16: qemu-virtio-net-mac-property-is-mandatory.patch -Patch17: qemu-exec-memory-notifiers.patch -Patch18: qemu-kvm-add-API-to-set-ioeventfd.patch -Patch19: qemu-notifier-event-notifier-implementation.patch -Patch20: qemu-virtio-add-notifier-support.patch -Patch21: qemu-virtio-add-APIs-for-queue-fields.patch -Patch22: qemu-virtio-add-status-change-callback.patch -Patch23: qemu-virtio-move-typedef-to-qemu-common.patch -Patch24: qemu-virtio-pci-fill-in-notifier-support.patch -Patch25: qemu-tap-add-interface-to-get-device-fd.patch -Patch26: qemu-vhost-vhost-net-support.patch -Patch27: qemu-tap-add-vhost-vhostfd-options.patch -Patch28: qemu-tap-add-API-to-retrieve-vhost-net-header.patch -Patch29: qemu-virtio-net-vhost-net-support.patch -Patch30: qemu-kvm-add-vhost.h-header.patch -Patch31: qemu-kvm-irqfd-support.patch -Patch32: qemu-msix-add-mask-unmask-notifiers.patch -Patch33: qemu-virtio-pci-irqfd-support.patch -Patch34: qemu-virtio-avoid-crash-with-non-tap-backends.patch -Patch35: qemu-virtio-serial-features-build-fix.patch -Patch36: qemu-virtio-pci-irqfd-fix-nonkvm-build.patch -Patch37: qemu-vhost-add-configure-check.patch - -# Fixes from upstream -Patch38: 0038-msix-migration-fix.patch -Patch39: 0039-vhost-logging-thinko-fix.patch -Patch40: 0040-vhost-move-vhost_set_vq_addr.patch -Patch41: 0041-vhost-used-addr-migration-fix.patch -Patch42: 0042-vhost-fix-used-logging-size-math.patch -Patch43: 0043-vhost-logging-mistake-enable-not-disable-log.patch -Patch44: 0044-vhost-fix-log-base.patch -Patch45: 0045-pc-Add-a-Fedora-13-machine-type-that-contains-backpo.patch -Patch46: 0046-pc-Add-backward-compatibility-options-for-virtio-ser.patch -Patch47: 0047-virtio-serial-don-t-set-MULTIPORT-for-1-port-dev.patch -Patch48: 0048-virtio-serial-pci-Allow-MSI-to-be-disabled.patch -Patch49: 0049-migration-Clear-fd-also-in-error-cases.patch -Patch50: 0050-raw-posix-Detect-CDROM-via-ioctl-on-linux.patch -Patch51: 0051-usb-linux-increase-buffer-for-USB-control-requests.patch -Patch52: 0052-virtio-console-patches.patch -Patch53: 0053-net-remove-NICInfo.bootable-field.patch -Patch54: 0054-net-remove-broken-net_set_boot_mask-boot-device-vali.patch -Patch55: 0055-boot-remove-unused-boot_devices_bitmap-variable.patch -Patch56: block-vvfat.c-fix-warnings-with-_FORTIFY_SOURCE.patch Patch57: avoid-llseek.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -287,64 +231,6 @@ such as kvmtrace and kvm_stat. %prep %setup -q -n qemu-kvm-%{version} -%patch01 -p1 -%patch02 -p1 -%patch03 -p1 -%patch04 -p1 -%patch05 -p1 -%patch06 -p1 -%patch07 -p1 -%patch08 -p1 -%patch09 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 -%patch20 -p1 -%patch21 -p1 -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 -%patch27 -p1 -%patch28 -p1 -%patch29 -p1 -%patch30 -p1 -%patch31 -p1 -%patch32 -p1 -%patch33 -p1 -%patch34 -p1 -%patch35 -p1 -%patch36 -p1 -%patch37 -p1 -%patch38 -p1 -%patch39 -p1 -%patch40 -p1 -%patch41 -p1 -%patch42 -p1 -%patch43 -p1 -%patch44 -p1 -%patch45 -p1 -%patch46 -p1 -%patch47 -p1 -%patch48 -p1 -%patch49 -p1 -%patch50 -p1 -%patch51 -p1 -%patch52 -p1 -%patch53 -p1 -%patch54 -p1 -%patch55 -p1 -%patch56 -p1 -%patch57 -p1 - %build # By default we build everything, but allow x86 to build a minimal version # with only similar arch target support @@ -372,6 +258,7 @@ buildldflags="VL_LDFLAGS=-Wl,--build-id" # oss works, but is very problematic because it grabs exclusive control of the device causing other apps to go haywire ./configure --target-list=x86_64-softmmu \ --prefix=%{_prefix} \ + --sysconfdir=%{_sysconfdir} \ --audio-drv-list=pa,sdl,alsa,oss \ --disable-strip \ --extra-ldflags=$extraldflags \ @@ -387,7 +274,7 @@ make V=1 %{?_smp_mflags} $buildldflags cp -a x86_64-softmmu/qemu-system-x86_64 qemu-kvm make clean -cd kvm/user +cd kvm/test ./configure --prefix=%{_prefix} --kerneldir=$(pwd)/../kernel/ make kvmtrace cd ../../ @@ -396,13 +283,15 @@ cd ../../ ./configure \ --target-list="$buildarch" \ --prefix=%{_prefix} \ + --sysconfdir=%{_sysconfdir} \ --interp-prefix=%{_prefix}/qemu-%%M \ --audio-drv-list=pa,sdl,alsa,oss \ --disable-kvm \ --disable-strip \ --extra-ldflags=$extraldflags \ --extra-cflags="$RPM_OPT_FLAGS" \ - --disable-xen + --disable-xen \ + --disable-werror echo "config-host.mak contents:" echo "===" @@ -428,8 +317,8 @@ mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{name} mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/udev/rules.d install -m 0755 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/modules/kvm.modules -install -m 0755 kvm/user/kvmtrace $RPM_BUILD_ROOT%{_bindir}/ -install -m 0755 kvm/user/kvmtrace_format $RPM_BUILD_ROOT%{_bindir}/ +install -m 0755 kvm/test/kvmtrace $RPM_BUILD_ROOT%{_bindir}/ +install -m 0755 kvm/test/kvmtrace_format $RPM_BUILD_ROOT%{_bindir}/ install -m 0755 kvm/kvm_stat $RPM_BUILD_ROOT%{_bindir}/ install -m 0755 qemu-kvm $RPM_BUILD_ROOT%{_bindir}/ install -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/udev/rules.d @@ -440,7 +329,8 @@ make prefix="${RPM_BUILD_ROOT}%{_prefix}" \ sharedir="${RPM_BUILD_ROOT}%{_datadir}/%{name}" \ mandir="${RPM_BUILD_ROOT}%{_mandir}" \ docdir="${RPM_BUILD_ROOT}%{_docdir}/%{name}-%{version}" \ - datadir="${RPM_BUILD_ROOT}%{_datadir}/%{name}" install + datadir="${RPM_BUILD_ROOT}%{_datadir}/%{name}" \ + sysconfdir="${RPM_BUILD_ROOT}%{_sysconfdir}" install chmod -x ${RPM_BUILD_ROOT}%{_mandir}/man1/* install -D -p -m 0755 %{SOURCE1} $RPM_BUILD_ROOT%{_initddir}/qemu install -D -p -m 0644 -t ${RPM_BUILD_ROOT}%{qemudocdir} Changelog README TODO COPYING COPYING.LIB LICENSE @@ -448,12 +338,14 @@ install -D -p -m 0644 -t ${RPM_BUILD_ROOT}%{qemudocdir} Changelog README TODO CO install -D -p -m 0644 qemu.sasl $RPM_BUILD_ROOT%{_sysconfdir}/sasl2/qemu.conf rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/pxe*bin +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/gpxe*rom rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/vgabios*bin rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/bios.bin rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/openbios-ppc rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/openbios-sparc32 rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/openbios-sparc64 rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/petalogix-s3adsp1800.dtb +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/s390-zipl.rom %if %{with_x86only} rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/bamboo.dtb rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/ppc_rom.bin @@ -598,6 +490,7 @@ fi %{_bindir}/qemu-kvm %{_sysconfdir}/sysconfig/modules/kvm.modules %{_sysconfdir}/udev/rules.d/80-kvm.rules +%{_sysconfdir}/qemu/target-* %files kvm-tools %defattr(-,root,root,-) %{_bindir}/kvmtrace @@ -647,6 +540,10 @@ fi %{_mandir}/man1/qemu-img.1* %changelog +* Tue Jul 27 2010 Justin M. Forbes - 2:0.13.0-0.1.20100727gitb81fe95 +- Update to 0.13.0 upstream snapshot +- ksm init fixes from upstream + * Tue Jul 20 2010 Dan HorĂ¡k - 2:0.12.3-8 - Add avoid-llseek patch from upstream needed for building on s390(x) - Don't use parallel make on s390(x) diff --git a/sources b/sources index c17d439..6e5d966 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -ab484975004f66fb48cb5589bd9b9dcb qemu-kvm-0.12.3.tar.gz +940a1af9eafdebcf7c746b837fee3613 qemu-kvm-0.13.0-b81fe95.tar.gz