Re: [Qemu-devel] [PULL 6/7] net: complete all queued packets on VM stop
On 09/04/2014 11:50 PM, Stefan Hajnoczi wrote: From: Michael S. Tsirkin m...@redhat.com This completes all packets, ensuring that callbacks will not run when VM is stopped. Cc: qemu-sta...@nongnu.org Cc: Jason Wang jasow...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- net/net.c | 33 - 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/net/net.c b/net/net.c index 962c05f..7acc162 100644 --- a/net/net.c +++ b/net/net.c @@ -48,6 +48,7 @@ # define CONFIG_NET_BRIDGE #endif +static VMChangeStateEntry *net_change_state_entry; static QTAILQ_HEAD(, NetClientState) net_clients; const char *host_net_devices[] = { @@ -511,7 +512,8 @@ void qemu_purge_queued_packets(NetClientState *nc) qemu_net_queue_purge(nc-peer-incoming_queue, nc); } -void qemu_flush_queued_packets(NetClientState *nc) +static +void qemu_flush_or_purge_queued_packets(NetClientState *nc, bool purge) { nc-receive_disabled = 0; @@ -525,9 +527,17 @@ void qemu_flush_queued_packets(NetClientState *nc) * the file descriptor (for tap, for example). */ qemu_notify_event(); +} else if (purge) { +/* Unable to empty the queue, purge remaining packets */ +qemu_net_queue_purge(nc-incoming_queue, nc); } } +void qemu_flush_queued_packets(NetClientState *nc) +{ +qemu_flush_or_purge_queued_packets(nc, false); +} + static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender, unsigned flags, const uint8_t *buf, int size, @@ -1175,6 +1185,22 @@ void qmp_set_link(const char *name, bool up, Error **errp) } } +static void net_vm_change_state_handler(void *opaque, int running, +RunState state) +{ +/* Complete all queued packets, to guarantee we don't modify + * state later when VM is not running. + */ +if (!running) { +NetClientState *nc; +NetClientState *tmp; + +QTAILQ_FOREACH_SAFE(nc, net_clients, next, tmp) { +qemu_flush_or_purge_queued_packets(nc, true); +} +} +} Something like net_drain_all_queue() in do_vm_stop() looks simpler. And doing this is tricky if it depends on other handlers to be called first. E.g virtio-net vm change state handler will set vm_running to false. And net_vm_change_state_handler() will be called after this. This means virtio_net_flush_tx() will still hit the assert since it will be called by packet cb (virtio_net_tx_complete()). + void net_cleanup(void) { NetClientState *nc; @@ -1190,6 +1216,8 @@ void net_cleanup(void) qemu_del_net_client(nc); } } + +qemu_del_vm_change_state_handler(net_change_state_entry); } void net_check_clients(void) @@ -1275,6 +1303,9 @@ int net_init_clients(void) #endif } +net_change_state_entry = +qemu_add_vm_change_state_handler(net_vm_change_state_handler, NULL); + QTAILQ_INIT(net_clients); if (qemu_opts_foreach(qemu_find_opts(netdev), net_init_netdev, NULL, 1) == -1)
Re: [Qemu-devel] [RFC PATCH v6 00/14] Reverse execution.
From: Frederic Konrad [mailto:fred.kon...@greensocs.com] On 08/09/2014 10:29, Paolo Bonzini wrote: Il 08/09/2014 10:09, Frederic Konrad ha scritto: By the way how do you want to have this discussion? At the KVM forum? Or by phone on KVM phone call? Or both. :) Seriously, Pavel is presenting on record/replay at KVM Forum. I guess there will be some discussion after his presentation, but anything that happens _before_ could make the presentation more interesting. Paolo Ok fine with us, So is that possible to allocate time for this on the next KVM phone calls I think it's next week? If that suits to you Pavel? Yes, I can take part in phone calls next week. What should I do for that? Pavel Dovgalyuk
[Qemu-devel] [PATCH v2 4/9] virtio/vhost-scsi: fix virtio-scsi/vhost-scsi child refcount in transports
From: Gonglei arei.gong...@huawei.com object_initialize() leaves the object with a refcount of 1. object_property_add_child() adds its own reference which is dropped again when the property is deleted. The upshot of this is that we always have a refcount = 1. Upon hot unplug the virtio-scsi/vhost-scsi child is not finalized! Drop our reference after the child property has been added to the parent. Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/s390x/s390-virtio-bus.c | 2 ++ hw/s390x/virtio-ccw.c | 2 ++ hw/virtio/virtio-pci.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index eaaa275..4276034 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -258,6 +258,7 @@ static void s390_virtio_scsi_instance_init(Object *obj) VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SCSI); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } @@ -280,6 +281,7 @@ static void s390_vhost_scsi_instance_init(Object *obj) VHostSCSIS390 *dev = VHOST_SCSI_S390(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VHOST_SCSI); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } #endif diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 458aabc..a466674 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -938,6 +938,7 @@ static void virtio_ccw_scsi_instance_init(Object *obj) VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SCSI); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } @@ -960,6 +961,7 @@ static void vhost_ccw_scsi_instance_init(Object *obj) VHostSCSICcw *dev = VHOST_SCSI_CCW(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VHOST_SCSI); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } #endif diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 2dd8360..00dbfc9 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1175,6 +1175,7 @@ static void virtio_scsi_pci_instance_init(Object *obj) VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SCSI); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } @@ -1231,6 +1232,7 @@ static void vhost_scsi_pci_instance_init(Object *obj) VHostSCSIPCI *dev = VHOST_SCSI_PCI(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VHOST_SCSI); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } -- 1.7.12.4
[Qemu-devel] [PATCH v2 7/9] virtio-rng: use aliases instead of duplicate qdev properties
From: Gonglei arei.gong...@huawei.com virtio-rng-{pci, s390, ccw} all duplicate the qdev properties of their VirtIORNG child. This approach does not work well with string or pointer properties since we must be careful about leaking or double-freeing them. Use the QOM alias property to forward property accesses to the VirtIORNG child. This way no duplication is necessary. Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/s390x/s390-virtio-bus.c | 2 +- hw/s390x/virtio-ccw.c | 2 +- hw/virtio/virtio-pci.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 422402e..6d0a7f3 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -311,6 +311,7 @@ static void s390_virtio_rng_instance_init(Object *obj) VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_RNG); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); object_property_add_link(obj, rng, TYPE_RNG_BACKEND, (Object **)dev-vdev.conf.rng, qdev_prop_allow_set_link_before_realize, @@ -561,7 +562,6 @@ static const TypeInfo s390_virtio_serial = { static Property s390_virtio_rng_properties[] = { DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features), -DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGS390, vdev.conf), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 5d7f3a6..da2e427 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1542,6 +1542,7 @@ static void virtio_ccw_rng_instance_init(Object *obj) VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_RNG); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); object_property_add_link(obj, rng, TYPE_RNG_BACKEND, (Object **)dev-vdev.conf.rng, qdev_prop_allow_set_link_before_realize, @@ -1550,7 +1551,6 @@ static void virtio_ccw_rng_instance_init(Object *obj) static Property virtio_ccw_rng_properties[] = { DEFINE_PROP_STRING(devno, VirtioCcwDevice, bus_id), -DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGCcw, vdev.conf), DEFINE_PROP_BIT(ioeventfd, VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 87ceea3..28b9b74 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1472,7 +1472,6 @@ static const TypeInfo virtio_net_pci_info = { /* virtio-rng-pci */ static Property virtio_rng_pci_properties[] = { -DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORngPCI, vdev.conf), DEFINE_PROP_END_OF_LIST(), }; @@ -1514,6 +1513,7 @@ static void virtio_rng_initfn(Object *obj) VirtIORngPCI *dev = VIRTIO_RNG_PCI(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_RNG); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); object_property_add_link(obj, rng, TYPE_RNG_BACKEND, (Object **)dev-vdev.conf.rng, qdev_prop_allow_set_link_before_realize, -- 1.7.12.4
[Qemu-devel] [PATCH v2 9/9] virtio-balloon: fix virtio-balloon child refcount in transports
From: Gonglei arei.gong...@huawei.com object_initialize() leaves the object with a refcount of 1. object_property_add_child() adds its own reference which is dropped again when the property is deleted. The upshot of this is that we always have a refcount = 1. Upon hot unplug the virtio-balloon child is not finalized! Drop our reference after the child property has been added to the parent. Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/s390x/virtio-ccw.c | 2 +- hw/virtio/virtio-pci.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index de0764d..c074f64 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -900,7 +900,7 @@ static void virtio_ccw_balloon_instance_init(Object *obj) VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_BALLOON); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); - +object_unref(OBJECT(dev-vdev)); object_property_add(obj, guest-stats, guest statistics, balloon_ccw_stats_get_all, NULL, NULL, dev, NULL); diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index d93ffad..e6cdaca 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1314,7 +1314,7 @@ static void virtio_balloon_pci_instance_init(Object *obj) VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_BALLOON); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); - +object_unref(OBJECT(dev-vdev)); object_property_add(obj, guest-stats, guest statistics, balloon_pci_stats_get_all, NULL, NULL, dev, NULL); -- 1.7.12.4
[Qemu-devel] [PATCH v2 2/9] virtio: fix virtio-net child refcount in transports
From: Gonglei arei.gong...@huawei.com object_initialize() leaves the object with a refcount of 1. object_property_add_child() adds its own reference which is dropped again when the property is deleted. The upshot of this is that we always have a refcount = 1. Upon hot unplug the virtio-net child is not finalized! Drop our reference after the child property has been added to the parent. Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/s390x/s390-virtio-bus.c | 1 + hw/s390x/virtio-ccw.c | 1 + hw/virtio/virtio-pci.c | 1 + 3 files changed, 3 insertions(+) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 5b5d595..297eac2 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -161,6 +161,7 @@ static void s390_virtio_net_instance_init(Object *obj) VirtIONetS390 *dev = VIRTIO_NET_S390(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_NET); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 7d67577..bb699f2 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -794,6 +794,7 @@ static void virtio_ccw_net_instance_init(Object *obj) VirtIONetCcw *dev = VIRTIO_NET_CCW(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_NET); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 6722156..19c9a6c 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1454,6 +1454,7 @@ static void virtio_net_pci_instance_init(Object *obj) VirtIONetPCI *dev = VIRTIO_NET_PCI(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_NET); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } -- 1.7.12.4
[Qemu-devel] [PATCH v2 8/9] virtio-rng: fix virtio-rng child refcount in transports
From: Gonglei arei.gong...@huawei.com object_initialize() leaves the object with a refcount of 1. object_property_add_child() adds its own reference which is dropped again when the property is deleted. The upshot of this is that we always have a refcount = 1. Upon hot unplug the virtio-rng child is not finalized! Drop our reference after the child property has been added to the parent. Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/s390x/s390-virtio-bus.c | 1 + hw/s390x/virtio-ccw.c | 1 + hw/virtio/virtio-pci.c | 1 + 3 files changed, 3 insertions(+) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 6d0a7f3..ca682bb 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -312,6 +312,7 @@ static void s390_virtio_rng_instance_init(Object *obj) object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_RNG); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); qdev_alias_all_properties(DEVICE(dev-vdev), obj); +object_unref(OBJECT(dev-vdev)); object_property_add_link(obj, rng, TYPE_RNG_BACKEND, (Object **)dev-vdev.conf.rng, qdev_prop_allow_set_link_before_realize, diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index da2e427..de0764d 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1543,6 +1543,7 @@ static void virtio_ccw_rng_instance_init(Object *obj) object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_RNG); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); qdev_alias_all_properties(DEVICE(dev-vdev), obj); +object_unref(OBJECT(dev-vdev)); object_property_add_link(obj, rng, TYPE_RNG_BACKEND, (Object **)dev-vdev.conf.rng, qdev_prop_allow_set_link_before_realize, diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 28b9b74..d93ffad 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1514,6 +1514,7 @@ static void virtio_rng_initfn(Object *obj) object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_RNG); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); qdev_alias_all_properties(DEVICE(dev-vdev), obj); +object_unref(OBJECT(dev-vdev)); object_property_add_link(obj, rng, TYPE_RNG_BACKEND, (Object **)dev-vdev.conf.rng, qdev_prop_allow_set_link_before_realize, -- 1.7.12.4
[Qemu-devel] [PATCH v2 3/9] virtio/vhost scsi: use aliases instead of duplicate qdev properties
From: Gonglei arei.gong...@huawei.com {virtio, vhost}-scsi-{pci, s390, ccw} all duplicate the qdev properties of their VirtIOSCSI/VHostSCSI child. This approach does not work well with string or pointer properties since we must be careful about leaking or double-freeing them. Use the QOM alias property to forward property accesses to the VirtIOSCSI/VHostSCSI child. This way no duplication is necessary. Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/s390x/s390-virtio-bus.c | 4 ++-- hw/s390x/virtio-ccw.c | 4 ++-- hw/virtio/virtio-pci.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 297eac2..eaaa275 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -258,6 +258,7 @@ static void s390_virtio_scsi_instance_init(Object *obj) VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SCSI); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } #ifdef CONFIG_VHOST_SCSI @@ -279,6 +280,7 @@ static void s390_vhost_scsi_instance_init(Object *obj) VHostSCSIS390 *dev = VHOST_SCSI_S390(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VHOST_SCSI); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } #endif @@ -614,7 +616,6 @@ static const TypeInfo virtio_s390_device_info = { }; static Property s390_virtio_scsi_properties[] = { -DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIS390, vdev.parent_obj.conf), DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features), DEFINE_VIRTIO_SCSI_FEATURES(VirtIOS390Device, host_features), DEFINE_PROP_END_OF_LIST(), @@ -640,7 +641,6 @@ static const TypeInfo s390_virtio_scsi = { #ifdef CONFIG_VHOST_SCSI static Property s390_vhost_scsi_properties[] = { DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features), -DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSIS390, vdev.parent_obj.conf), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index bb699f2..458aabc 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -938,6 +938,7 @@ static void virtio_ccw_scsi_instance_init(Object *obj) VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SCSI); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } #ifdef CONFIG_VHOST_SCSI @@ -959,6 +960,7 @@ static void vhost_ccw_scsi_instance_init(Object *obj) VHostSCSICcw *dev = VHOST_SCSI_CCW(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VHOST_SCSI); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } #endif @@ -1481,7 +1483,6 @@ static const TypeInfo virtio_ccw_balloon = { static Property virtio_ccw_scsi_properties[] = { DEFINE_PROP_STRING(devno, VirtioCcwDevice, bus_id), -DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf), DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]), DEFINE_PROP_BIT(ioeventfd, VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), @@ -1510,7 +1511,6 @@ static const TypeInfo virtio_ccw_scsi = { #ifdef CONFIG_VHOST_SCSI static Property vhost_ccw_scsi_properties[] = { DEFINE_PROP_STRING(devno, VirtioCcwDevice, bus_id), -DEFINE_VHOST_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 19c9a6c..2dd8360 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1124,7 +1124,6 @@ static Property virtio_scsi_pci_properties[] = { DEFINE_PROP_UINT32(vectors, VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED), DEFINE_VIRTIO_SCSI_FEATURES(VirtIOPCIProxy, host_features), -DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIPCI, vdev.parent_obj.conf), DEFINE_PROP_END_OF_LIST(), }; @@ -1176,6 +1175,7 @@ static void virtio_scsi_pci_instance_init(Object *obj) VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SCSI); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } static const TypeInfo virtio_scsi_pci_info = { @@ -1192,7 +1192,6 @@ static const TypeInfo virtio_scsi_pci_info = { static Property vhost_scsi_pci_properties[] = { DEFINE_PROP_UINT32(vectors, VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED), -DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSIPCI, vdev.parent_obj.conf), DEFINE_PROP_END_OF_LIST(), }; @@ -1232,6 +1231,7 @@
[Qemu-devel] [PATCH v2 1/9] virtio-net: use aliases instead of duplicate qdev properties
From: Gonglei arei.gong...@huawei.com virtio-net-pci, virtio-net-s390, and virtio-net-ccw all duplicate the qdev properties of their VirtIONet child. This approach does not work well with string or pointer properties since we must be careful about leaking or double-freeing them. Use the QOM alias property to forward property accesses to the VirtIONet child. This way no duplication is necessary. Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/s390x/s390-virtio-bus.c | 3 +-- hw/s390x/virtio-ccw.c | 3 +-- hw/virtio/virtio-pci.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 6b6fb61..5b5d595 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -161,6 +161,7 @@ static void s390_virtio_net_instance_init(Object *obj) VirtIONetS390 *dev = VIRTIO_NET_S390(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_NET); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } static int s390_virtio_blk_init(VirtIOS390Device *s390_dev) @@ -493,10 +494,8 @@ static unsigned virtio_s390_get_features(DeviceState *d) / S390 Virtio Bus Device Descriptions ***/ static Property s390_virtio_net_properties[] = { -DEFINE_NIC_PROPERTIES(VirtIONetS390, vdev.nic_conf), DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features), DEFINE_VIRTIO_NET_FEATURES(VirtIOS390Device, host_features), -DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetS390, vdev.net_conf), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 33a1d86..7d67577 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -794,6 +794,7 @@ static void virtio_ccw_net_instance_init(Object *obj) VirtIONetCcw *dev = VIRTIO_NET_CCW(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_NET); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev) @@ -1374,8 +1375,6 @@ static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f) static Property virtio_ccw_net_properties[] = { DEFINE_PROP_STRING(devno, VirtioCcwDevice, bus_id), DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]), -DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetCcw, vdev.net_conf), -DEFINE_NIC_PROPERTIES(VirtIONetCcw, vdev.nic_conf), DEFINE_PROP_BIT(ioeventfd, VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index ddb5da1..6722156 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1414,8 +1414,6 @@ static Property virtio_net_properties[] = { VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false), DEFINE_PROP_UINT32(vectors, VirtIOPCIProxy, nvectors, 3), DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features), -DEFINE_NIC_PROPERTIES(VirtIONetPCI, vdev.nic_conf), -DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetPCI, vdev.net_conf), DEFINE_PROP_END_OF_LIST(), }; @@ -1456,6 +1454,7 @@ static void virtio_net_pci_instance_init(Object *obj) VirtIONetPCI *dev = VIRTIO_NET_PCI(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_NET); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } static const TypeInfo virtio_net_pci_info = { -- 1.7.12.4
[Qemu-devel] [PATCH v2 5/9] virtio-serial: use aliases instead of duplicate qdev properties
From: Gonglei arei.gong...@huawei.com virtio-serial-{pci, s390, ccw} all duplicate the qdev properties of their VirtIOSerial child. This approach does not work well with string or pointer properties since we must be careful about leaking or double-freeing them. Use the QOM alias property to forward property accesses to the VirtIOSerial child. This way no duplication is necessary. Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/s390x/s390-virtio-bus.c | 2 +- hw/s390x/virtio-ccw.c | 2 +- hw/virtio/virtio-pci.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 4276034..31f5286 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -226,6 +226,7 @@ static void s390_virtio_serial_instance_init(Object *obj) VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SERIAL); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev) @@ -537,7 +538,6 @@ static const TypeInfo s390_virtio_blk = { }; static Property s390_virtio_serial_properties[] = { -DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialS390, vdev.serial), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index a466674..271104d 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -852,6 +852,7 @@ static void virtio_ccw_serial_instance_init(Object *obj) VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SERIAL); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } static int virtio_ccw_balloon_init(VirtioCcwDevice *ccw_dev) @@ -1432,7 +1433,6 @@ static const TypeInfo virtio_ccw_blk = { static Property virtio_ccw_serial_properties[] = { DEFINE_PROP_STRING(devno, VirtioCcwDevice, bus_id), -DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial), DEFINE_PROP_BIT(ioeventfd, VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 00dbfc9..5a5b534 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1376,7 +1376,6 @@ static Property virtio_serial_pci_properties[] = { VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32(vectors, VirtIOPCIProxy, nvectors, 2), DEFINE_PROP_UINT32(class, VirtIOPCIProxy, class_code, 0), -DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialPCI, vdev.serial), DEFINE_PROP_END_OF_LIST(), }; @@ -1399,6 +1398,7 @@ static void virtio_serial_pci_instance_init(Object *obj) VirtIOSerialPCI *dev = VIRTIO_SERIAL_PCI(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SERIAL); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } static const TypeInfo virtio_serial_pci_info = { -- 1.7.12.4
[Qemu-devel] [PATCH v2 0/9] virtio: fix virtio child recount in transports
From: Gonglei arei.gong...@huawei.com virtio-$device-{pci, s390, ccw} all duplicate the qdev properties of their virtio child. This approach does not work well with string or pointer properties since we must be careful about leaking or double-freeing them. Use the QOM alias property to forward property accesses to the VirtIORNG child. This way no duplication is necessary. For their child, object_initialize() leaves the object with a refcount of 1. object_property_add_child() adds its own reference which is dropped again when the property is deleted. The upshot of this is that we always have a refcount = 1. Upon hot unplug the virtio-$device child is not finalized! Drop our reference after the child property has been added to the parent. The v1 as below: http://lists.gnu.org/archive/html/qemu-devel/2014-09/msg01208.html Changes since v1: 1. using alias properties avoid to double-free property.(Stefan) 2. add handling all other virtio-devices had the same probleam. 3. same handling for CCW and s390-virito. Acknowledgements: I copied Stefan's commit message about virtio-blk which summarized reasons very well, I cannot agree more with him. Holp Stefan do not mind, thank you so much! Gonglei (9): virtio-net: use aliases instead of duplicate qdev properties virtio: fix virtio-net child refcount in transports virtio/vhost scsi: use aliases instead of duplicate qdev properties virtio/vhost-scsi: fix virtio-scsi/vhost-scsi child refcount in transports virtio-serial: use aliases instead of duplicate qdev properties virtio-serial: fix virtio-serial child refcount in transports virtio-rng: use aliases instead of duplicate qdev properties virtio-rng: fix virtio-rng child refcount in transports virtio-balloon: fix virtio-balloon child refcount in transports hw/s390x/s390-virtio-bus.c | 16 ++-- hw/s390x/virtio-ccw.c | 18 +++--- hw/virtio/virtio-pci.c | 18 +++--- 3 files changed, 32 insertions(+), 20 deletions(-) -- 1.7.12.4
[Qemu-devel] [PATCH v2 6/9] virtio-serial: fix virtio-serial child refcount in transports
From: Gonglei arei.gong...@huawei.com object_initialize() leaves the object with a refcount of 1. object_property_add_child() adds its own reference which is dropped again when the property is deleted. The upshot of this is that we always have a refcount = 1. Upon hot unplug the virtio-serial child is not finalized! Drop our reference after the child property has been added to the parent. Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/s390x/s390-virtio-bus.c | 1 + hw/s390x/virtio-ccw.c | 1 + hw/virtio/virtio-pci.c | 1 + 3 files changed, 3 insertions(+) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 31f5286..422402e 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -227,6 +227,7 @@ static void s390_virtio_serial_instance_init(Object *obj) object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SERIAL); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); qdev_alias_all_properties(DEVICE(dev-vdev), obj); +object_unref(OBJECT(dev-vdev)); } static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 271104d..5d7f3a6 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -853,6 +853,7 @@ static void virtio_ccw_serial_instance_init(Object *obj) object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SERIAL); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); qdev_alias_all_properties(DEVICE(dev-vdev), obj); +object_unref(OBJECT(dev-vdev)); } static int virtio_ccw_balloon_init(VirtioCcwDevice *ccw_dev) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 5a5b534..87ceea3 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1399,6 +1399,7 @@ static void virtio_serial_pci_instance_init(Object *obj) object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_SERIAL); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); qdev_alias_all_properties(DEVICE(dev-vdev), obj); +object_unref(OBJECT(dev-vdev)); } static const TypeInfo virtio_serial_pci_info = { -- 1.7.12.4
Re: [Qemu-devel] [PATCH v2 0/5] Convert remaining legacy chardevs to QAPI
Il 02/09/2014 12:24, Peter Maydell ha scritto: This patchset converts the two remaining legacy chardevs ('socket' and 'udp') to use the new-style parse/kind mechanisms, and removes all the no-longer-required legacy machinery. Patch 1 was posted to the list back in June (https://patches.linaro.org/32298/). I've fixed the obvious bug picked up in code review, and as far as I can tell from the thread we decided that the blocking/non-blocking difference between QAPI and legacy wasn't a problem. Patch 2 fixes a hole in the functionality of QAPI-described UDP chardevs, to avoid regressing the commandline functionality when we convert the UDP backend in patch 3. Patch 4 may be easier to review as an ignore-whitespaces diff (the de-indentation makes the diff a bit awkward). Changes v1-v2: * fixed the has_* values as suggested by Markus * added patch 5 which renames the _qapi() function now the legacy version has gone (again, as suggested by Markus) Peter Maydell (5): qemu-char: Convert socket backend to QAPI util/qemu-sockets.c: Support specifying IPv4 or IPv6 in socket_dgram() qemu-char: Convert udp backend to QAPI qemu-char: Remove register_char_driver() machinery qemu-char: Rename register_char_driver_qapi() to register_char_driver() backends/baum.c | 2 +- backends/msmouse.c| 2 +- backends/testdev.c| 2 +- include/sysemu/char.h | 3 +- qemu-char.c | 353 -- spice-qemu-char.c | 8 +- ui/console.c | 3 +- util/qemu-sockets.c | 3 +- 8 files changed, 180 insertions(+), 196 deletions(-) Hi Peter, are you going to apply these directly? Paolo
[Qemu-devel] [PATCH] hw/dma: Print error message only once
otherwise the message dma: unregistered DMA channel used nchan=0 dma_pos=0 dma_len=1 gets printed every time and fills up the log-file with 50 MiB / minute. Signed-off-by: Philipp Hahn h...@univention.de --- hw/dma/i8257.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index dd370ed..9673ab6 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -473,8 +473,14 @@ static void dma_reset(void *opaque) static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len) { -dolog (unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d\n, - nchan, dma_pos, dma_len); +static int once; +int mask = 1 nchan; + +if (0 == (once mask)) { +once |= mask; +dolog(unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d\n, + nchan, dma_pos, dma_len); +} return dma_pos; } -- 1.9.1
[Qemu-devel] [Bug 1366836] Re: Core2Duo and KVM may not boot Win8 properly on 3.x kernels
Here the register dump of the stalled Win8 QEMU 2.1.0 monitor - type 'help' for more information (qemu) info registers EAX=3e2009e3 EBX=3e2009e3 ECX=8000 EDX=8000 ESI=3e2009e3 EDI=8220c108 EBP=81f9b33c ESP=81f9b2f0 EIP=80c98d83 EFL=00010282 [--S] CPL=0 II=0 A20=1 SMM=0 HLT=0 ES =0023 00c0f300 DPL=3 DS [-WA] CS =0008 00c09b00 DPL=0 CS32 [-RA] SS =0010 00c09300 DPL=0 DS [-WA] DS =0023 00c0f300 DPL=3 DS [-WA] FS =0030 80e65000 4280 00409300 DPL=0 DS [-WA] GS = LDT= TR =0028 80353000 20ab 8b00 DPL=0 TSS32-busy GDT= 80a37000 03ff IDT= 80a37400 07ff CR0=8001003b CR2=8b206090 CR3=00185000 CR4=000406e9 DR0= DR1= DR2=0005 DR3= DR6=0ff0 DR7=0400 EFER=0800 FCW=027f FSW= [ST=0] FTW=00 MXCSR=1f80 FPR0= FPR1= FPR2= FPR3= FPR4= FPR5= FPR6= FPR7= XMM00= XMM01= XMM02= XMM03= XMM04= XMM05= XMM06= XMM07= -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1366836 Title: Core2Duo and KVM may not boot Win8 properly on 3.x kernels Status in QEMU: New Bug description: When I start up QEMU w/ KVM 1.7.0 on a Core2Duo machine running a vanilla kernel 3.4.67 or 3.10.12 to run a Windows 8.0 guest, the guest freezes at Windows 8 boot without any error. When I dump the CPU registers via info registers, nothing changes, that means the system really stalled. Same happens with QEMU 2.0.0 and QEMU 2.1.0. It stalls when the Windows logo is displayed and the balled circle starts rotating. But - when I run the very same guest using Kernel 2.6.32.12 and QEMU 1.7.0 or 2.0.0 on the host side it works on the Core2Duo. Also the system above but just with an i3 or i5 CPU it works fine. I already disabled networking and USB for the guest and changed the graphics card - no effect. I assume that some mean bits and bytes have to be set up properly to get the thing running. Seems to be related to a kvm/processor incompatibility. Windows XP runs on all combinations without any issues. Windows 8.1 guests have the same issues as Windows 8.0. An example command line that does not boot Windows 8 is: qemu-system-x86_64 -machine pc-i440fx-1.5,accel=kvm,kernel_irqchip=off -daemonize -cpu kvm32,+sep,+nx -nodefaults -vga std -readconfig /usr/X11R6/X11etc/ich9-ehci-uhci.cfg -device usb-host,bus=ehci.0,hostport=1.2 -device usb-tablet -drive file=/dev/sdb,cache=writethrough,if=none,id=x -device ide-drive,drive=x -m 1024 -monitor telnet:127.0.0.1:5100,nowait,server -vnc :1 -L /usr/X11R6/share/qemu -boot c -localtime -enable-kvm -no-shutdown enabling the kernel_irqchip, removing the sep, disabling usb, changing the machine type or changing the monitor type (SDL or VNC) has no effect. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1366836/+subscriptions
[Qemu-devel] [PATCH v6 00/16] KVM platform device passthrough
This RFC series aims at enabling KVM platform device passthrough. It implements a VFIO platform device, derived from VFIO PCI device. The VFIO platform device uses the host VFIO platform driver which must be bound to the assigned device prior to the QEMU system start. - the guest can directly access the device register space - assigned device IRQs are transparently routed to the guest by QEMU/KVM (3 methods currently are supported: user-level eventfd handling, irqfd, forwarded IRQs) - iommu is transparently programmed to prevent the device from accessing physical pages outside of the guest address space This patch series is made of the following patch files: 1-7) Modifications to PCI code to prepare for VFIO platform device 8) split of PCI specific code and generic code (move) 9-11) creation of the VFIO calxeda xgmac platform device, without irqfd support (MMIO direct access and IRQ assignment). 12) fake injection test modality (to test multiple IRQ) 13) addition of irqfd/virqfd support 14-16) forwarded IRQ Dependency List: QEMU dependencies: [1] [PATCH v2 0/9] Dynamic sysbus device allocation support, Alex Graf http://lists.gnu.org/archive/html/qemu-ppc/2014-07/msg00047.html [2] [RFC v3] machvirt dynamic sysbus device instantiation, Eric Auger [3] [PATCH v2 0/2] actual checks of KVM_CAP_IRQFD and KVM_CAP_IRQFD_RESAMPLE, Eric Auger http://lists.nongnu.org/archive/html/qemu-devel/2014-09/msg00589.html [4] [RFC] vfio: migration to trace points, Eric Auger http://lists.nongnu.org/archive/html/qemu-devel/2014-09/msg00569.html Kernel Dependencies: [5] [RFC Patch v6 0/20] VFIO support for platform devices, Antonios Motakis https://www.mail-archive.com/kvm@vger.kernel.org/msg103247.html [6] [PATCH v3] ARM: KVM: add irqfd support, Eric Auger https://lkml.org/lkml/2014/9/1/141 [7] arm/arm64: KVM: Various VGIC cleanups and improvements, Christoffer Dall http://comments.gmane.org/gmane.linux.ports.arm.kernel/340430 [8] [RFC v2 0/9] KVM-VFIO IRQ forward control, Eric Auger https://lkml.org/lkml/2014/9/1/344 [9] [RFC PATCH 0/9] ARM: Forwarding physical interrupts to a guest VM, Marc Zyngier http://lwn.net/Articles/603514/ kernel pieces can be found at: http://git.linaro.org/people/eric.auger/linux.git (branch 3.17rc3_irqfd_forward_integ_v2) QEMU pieces can be found at: http://git.linaro.org/people/eric.auger/qemu.git (branch vfio_integ_v6) The patch series was tested on Calxeda Midway (ARMv7) where one xgmac is assigned to KVM host while the second one is assigned to the guest. Reworked PCI device is not tested. Wiki for Calxeda Midway setup: https://wiki.linaro.org/LEG/Engineering/Virtualization/Platform_Device_Passthrough_on_Midway History: v5-v6: - rebase on 2.1rc5 PCI code - forwarded IRQ first integraton - vfio_device property renamed into host property - split IRQ setup in different functions that match the 3 supported injection techniques (user handled eventfd, irqfd, forwarded IRQ): removes dynamic switch between injection methods - introduce fake interrupts as a test modality: x makes possible to test multiple IRQ user-side handling. x this is a test feature only: enable to trigger a fd as if the real physical IRQ hit. No virtual IRQ is injected into the guest but handling is simulated so that the state machine can be tested - user handled eventfd: x add mutex to protect IRQ state list manipulation, x correct misleading comment in vfio_intp_interrupt. x Fix bugs using fake interrupt modality - irqfd no more advertised in this patchset (handled in [3]) - VFIOPlatformDeviceClass becomes abstract and Calxeda xgmac device and class is re-introduced (as per v4) - all DPRINTF removed in platform and replaced by trace-points - corrects compilation with configure --disable-kvm - simplifies the split for vfio_get_device and introduce a unique specialized function named vfio_populate_device - group_list renamed into vfio_group_list - hw/arm/dyn_sysbus_devtree.c currently only support vfio-calxeda-xgmac instantiation. Needs to be specialized for other VFIO devices - fix 2 bugs in dyn_sysbus_devtree(reg_attr index and compat) v4-v5: - rebase on v2.1.0 PCI code - take into account Alex Williamson comments on PCI code rework - trace updates in vfio_region_write/read - remove fd from VFIORegion - get/put ckeanup - bug fix: bar region's vbasedev field duly initialization - misc cleanups in platform device - device tree node generation removed from device and handled in hw/arm/dyn_sysbus_devtree.c - remove hw/vfio: add an example calxeda_xgmac: with removal of device tree node generation we do not have so many things to implement in that derived device yet. May be re-introduced later on if needed typically for reset/migration. - no GSI routing table anymore v3-v4 changes (Eric Auger, Alvise Rigo) - rebase on last VFIO PCI code (v2.1.0-rc0) - full git history rework to ease PCI code change review - mv include files in
[Qemu-devel] [PATCH v6 02/16] hw/vfio/pci: Rename VFIODevice into VFIOPCIDevice
This prepares for the introduction of VFIOPlatformDevice Signed-off-by: Eric Auger eric.au...@linaro.org --- hw/vfio/pci.c | 209 +- 1 file changed, 105 insertions(+), 104 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 7e6a1bc..ad5da4b 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -48,11 +48,11 @@ #define VFIO_ALLOW_KVM_MSI 1 #define VFIO_ALLOW_KVM_MSIX 1 -struct VFIODevice; +struct VFIOPCIDevice; typedef struct VFIOQuirk { MemoryRegion mem; -struct VFIODevice *vdev; +struct VFIOPCIDevice *vdev; QLIST_ENTRY(VFIOQuirk) next; struct { uint32_t base_offset:TARGET_PAGE_BITS; @@ -123,7 +123,7 @@ typedef struct VFIOMSIVector { */ EventNotifier interrupt; EventNotifier kvm_interrupt; -struct VFIODevice *vdev; /* back pointer to device */ +struct VFIOPCIDevice *vdev; /* back pointer to device */ int virq; bool use; } VFIOMSIVector; @@ -185,7 +185,7 @@ typedef struct VFIOMSIXInfo { void *mmap; } VFIOMSIXInfo; -typedef struct VFIODevice { +typedef struct VFIOPCIDevice { PCIDevice pdev; int fd; VFIOINTx intx; @@ -203,7 +203,7 @@ typedef struct VFIODevice { VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */ VFIOVGA vga; /* 0xa, 0x3b0, 0x3c0 */ PCIHostDeviceAddress host; -QLIST_ENTRY(VFIODevice) next; +QLIST_ENTRY(VFIOPCIDevice) next; struct VFIOGroup *group; EventNotifier err_notifier; uint32_t features; @@ -218,13 +218,13 @@ typedef struct VFIODevice { bool has_pm_reset; bool needs_reset; bool rom_read_failed; -} VFIODevice; +} VFIOPCIDevice; typedef struct VFIOGroup { int fd; int groupid; VFIOContainer *container; -QLIST_HEAD(, VFIODevice) device_list; +QLIST_HEAD(, VFIOPCIDevice) device_list; QLIST_ENTRY(VFIOGroup) next; QLIST_ENTRY(VFIOGroup) container_next; } VFIOGroup; @@ -268,16 +268,16 @@ static QLIST_HEAD(, VFIOGroup) static int vfio_kvm_device_fd = -1; #endif -static void vfio_disable_interrupts(VFIODevice *vdev); +static void vfio_disable_interrupts(VFIOPCIDevice *vdev); static uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len); static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr, uint32_t val, int len); -static void vfio_mmap_set_enabled(VFIODevice *vdev, bool enabled); +static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled); /* * Common VFIO interrupt disable */ -static void vfio_disable_irqindex(VFIODevice *vdev, int index) +static void vfio_disable_irqindex(VFIOPCIDevice *vdev, int index) { struct vfio_irq_set irq_set = { .argsz = sizeof(irq_set), @@ -293,7 +293,7 @@ static void vfio_disable_irqindex(VFIODevice *vdev, int index) /* * INTx */ -static void vfio_unmask_intx(VFIODevice *vdev) +static void vfio_unmask_intx(VFIOPCIDevice *vdev) { struct vfio_irq_set irq_set = { .argsz = sizeof(irq_set), @@ -307,7 +307,7 @@ static void vfio_unmask_intx(VFIODevice *vdev) } #ifdef CONFIG_KVM /* Unused outside of CONFIG_KVM code */ -static void vfio_mask_intx(VFIODevice *vdev) +static void vfio_mask_intx(VFIOPCIDevice *vdev) { struct vfio_irq_set irq_set = { .argsz = sizeof(irq_set), @@ -338,7 +338,7 @@ static void vfio_mask_intx(VFIODevice *vdev) */ static void vfio_intx_mmap_enable(void *opaque) { -VFIODevice *vdev = opaque; +VFIOPCIDevice *vdev = opaque; if (vdev-intx.pending) { timer_mod(vdev-intx.mmap_timer, @@ -351,7 +351,7 @@ static void vfio_intx_mmap_enable(void *opaque) static void vfio_intx_interrupt(void *opaque) { -VFIODevice *vdev = opaque; +VFIOPCIDevice *vdev = opaque; if (!event_notifier_test_and_clear(vdev-intx.interrupt)) { return; @@ -370,7 +370,7 @@ static void vfio_intx_interrupt(void *opaque) } } -static void vfio_eoi(VFIODevice *vdev) +static void vfio_eoi(VFIOPCIDevice *vdev) { if (!vdev-intx.pending) { return; @@ -384,7 +384,7 @@ static void vfio_eoi(VFIODevice *vdev) vfio_unmask_intx(vdev); } -static void vfio_enable_intx_kvm(VFIODevice *vdev) +static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev) { #ifdef CONFIG_KVM struct kvm_irqfd irqfd = { @@ -462,7 +462,7 @@ fail: #endif } -static void vfio_disable_intx_kvm(VFIODevice *vdev) +static void vfio_disable_intx_kvm(VFIOPCIDevice *vdev) { #ifdef CONFIG_KVM struct kvm_irqfd irqfd = { @@ -506,7 +506,7 @@ static void vfio_disable_intx_kvm(VFIODevice *vdev) static void vfio_update_irq(PCIDevice *pdev) { -VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev); +VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); PCIINTxRoute route; if (vdev-interrupt != VFIO_INT_INTx) { @@ -537,7 +537,7 @@ static void vfio_update_irq(PCIDevice *pdev) vfio_eoi(vdev); } -static int vfio_enable_intx(VFIODevice
[Qemu-devel] [PATCH v6 03/16] hw/vfio/pci: introduce VFIODevice
Introduce the VFIODevice struct that is going to be shared by VFIOPCIDevice and VFIOPlatformDevice. Additional fields will be added there later on for review convenience. the group's device_list becomes a list of VFIODevice This obliges to rework the reset_handler which becomes generic and calls VFIODevice ops that are specialized in each parent object. Also functions that iterate on this list must take care that the devices can be something else than VFIOPCIDevice. The type is used to discriminate them. we profit from this step to change the prototype of vfio_unmask_intx, vfio_mask_intx, vfio_disable_irqindex which now apply to VFIODevice. They are renamed as *_irqindex. The index is passed as parameter to anticipate their usage for platform IRQs Signed-off-by: Eric Auger eric.au...@linaro.org --- v4-v5: - fix style issues - in vfio_initfn, rework allocation of vdev-vbasedev.name and replace snprintf by g_strdup_printf --- hw/vfio/pci.c | 241 +++--- 1 file changed, 147 insertions(+), 94 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index ad5da4b..e2caa08 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -48,6 +48,11 @@ #define VFIO_ALLOW_KVM_MSI 1 #define VFIO_ALLOW_KVM_MSIX 1 +enum { +VFIO_DEVICE_TYPE_PCI = 0, +VFIO_DEVICE_TYPE_PLATFORM = 1, +}; + struct VFIOPCIDevice; typedef struct VFIOQuirk { @@ -185,9 +190,27 @@ typedef struct VFIOMSIXInfo { void *mmap; } VFIOMSIXInfo; +typedef struct VFIODeviceOps VFIODeviceOps; + +typedef struct VFIODevice { +QLIST_ENTRY(VFIODevice) next; +struct VFIOGroup *group; +char *name; +int fd; +int type; +bool reset_works; +bool needs_reset; +VFIODeviceOps *ops; +} VFIODevice; + +struct VFIODeviceOps { +bool (*vfio_compute_needs_reset)(VFIODevice *vdev); +int (*vfio_hot_reset_multi)(VFIODevice *vdev); +}; + typedef struct VFIOPCIDevice { PCIDevice pdev; -int fd; +VFIODevice vbasedev; VFIOINTx intx; unsigned int config_size; uint8_t *emulated_config_bits; /* QEMU emulated bits, little-endian */ @@ -203,20 +226,16 @@ typedef struct VFIOPCIDevice { VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */ VFIOVGA vga; /* 0xa, 0x3b0, 0x3c0 */ PCIHostDeviceAddress host; -QLIST_ENTRY(VFIOPCIDevice) next; -struct VFIOGroup *group; EventNotifier err_notifier; uint32_t features; #define VFIO_FEATURE_ENABLE_VGA_BIT 0 #define VFIO_FEATURE_ENABLE_VGA (1 VFIO_FEATURE_ENABLE_VGA_BIT) int32_t bootindex; uint8_t pm_cap; -bool reset_works; bool has_vga; bool pci_aer; bool has_flr; bool has_pm_reset; -bool needs_reset; bool rom_read_failed; } VFIOPCIDevice; @@ -224,7 +243,7 @@ typedef struct VFIOGroup { int fd; int groupid; VFIOContainer *container; -QLIST_HEAD(, VFIOPCIDevice) device_list; +QLIST_HEAD(, VFIODevice) device_list; QLIST_ENTRY(VFIOGroup) next; QLIST_ENTRY(VFIOGroup) container_next; } VFIOGroup; @@ -277,7 +296,7 @@ static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled); /* * Common VFIO interrupt disable */ -static void vfio_disable_irqindex(VFIOPCIDevice *vdev, int index) +static void vfio_disable_irqindex(VFIODevice *vbasedev, int index) { struct vfio_irq_set irq_set = { .argsz = sizeof(irq_set), @@ -287,37 +306,37 @@ static void vfio_disable_irqindex(VFIOPCIDevice *vdev, int index) .count = 0, }; -ioctl(vdev-fd, VFIO_DEVICE_SET_IRQS, irq_set); +ioctl(vbasedev-fd, VFIO_DEVICE_SET_IRQS, irq_set); } /* * INTx */ -static void vfio_unmask_intx(VFIOPCIDevice *vdev) +static void vfio_unmask_irqindex(VFIODevice *vbasedev, int index) { struct vfio_irq_set irq_set = { .argsz = sizeof(irq_set), .flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_UNMASK, -.index = VFIO_PCI_INTX_IRQ_INDEX, +.index = index, .start = 0, .count = 1, }; -ioctl(vdev-fd, VFIO_DEVICE_SET_IRQS, irq_set); +ioctl(vbasedev-fd, VFIO_DEVICE_SET_IRQS, irq_set); } #ifdef CONFIG_KVM /* Unused outside of CONFIG_KVM code */ -static void vfio_mask_intx(VFIOPCIDevice *vdev) +static void vfio_mask_irqindex(VFIODevice *vbasedev, int index) { struct vfio_irq_set irq_set = { .argsz = sizeof(irq_set), .flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_MASK, -.index = VFIO_PCI_INTX_IRQ_INDEX, +.index = index, .start = 0, .count = 1, }; -ioctl(vdev-fd, VFIO_DEVICE_SET_IRQS, irq_set); +ioctl(vbasedev-fd, VFIO_DEVICE_SET_IRQS, irq_set); } #endif @@ -381,7 +400,7 @@ static void vfio_eoi(VFIOPCIDevice *vdev) vdev-intx.pending = false; pci_irq_deassert(vdev-pdev); -vfio_unmask_intx(vdev); +vfio_unmask_irqindex(vdev-vbasedev, VFIO_PCI_INTX_IRQ_INDEX); } static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev) @@ -404,7
[Qemu-devel] [PATCH v6 01/16] vfio: move hw/misc/vfio.c to hw/vfio/pci.c Move vfio.h into include/hw/vfio
From: Kim Phillips kim.phill...@linaro.org This is done in preparation for the addition of VFIO platform device support. Signed-off-by: Kim Phillips kim.phill...@linaro.org --- LICENSE | 2 +- MAINTAINERS | 2 +- hw/Makefile.objs | 1 + hw/misc/Makefile.objs| 1 - hw/ppc/spapr_pci_vfio.c | 2 +- hw/vfio/Makefile.objs| 3 +++ hw/{misc/vfio.c = vfio/pci.c} | 2 +- include/hw/{misc = vfio}/vfio.h | 0 8 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 hw/vfio/Makefile.objs rename hw/{misc/vfio.c = vfio/pci.c} (99%) rename include/hw/{misc = vfio}/vfio.h (100%) diff --git a/LICENSE b/LICENSE index da70e94..0e0b4b9 100644 --- a/LICENSE +++ b/LICENSE @@ -11,7 +11,7 @@ option) any later version. As of July 2013, contributions under version 2 of the GNU General Public License (and no later version) are only accepted for the following files -or directories: bsd-user/, linux-user/, hw/misc/vfio.c, hw/xen/xen_pt*. +or directories: bsd-user/, linux-user/, hw/vfio/, hw/xen/xen_pt*. 3) The Tiny Code Generator (TCG) is released under the BSD license (see license headers in files). diff --git a/MAINTAINERS b/MAINTAINERS index 206bf7e..8683f62 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -625,7 +625,7 @@ F: tests/usb-*-test.c VFIO M: Alex Williamson alex.william...@redhat.com S: Supported -F: hw/misc/vfio.c +F: hw/vfio/* vhost M: Michael S. Tsirkin m...@redhat.com diff --git a/hw/Makefile.objs b/hw/Makefile.objs index 52a1464..73afa41 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -26,6 +26,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += ssi/ devices-dirs-$(CONFIG_SOFTMMU) += timer/ devices-dirs-$(CONFIG_TPM) += tpm/ devices-dirs-$(CONFIG_SOFTMMU) += usb/ +devices-dirs-$(CONFIG_SOFTMMU) += vfio/ devices-dirs-$(CONFIG_VIRTIO) += virtio/ devices-dirs-$(CONFIG_SOFTMMU) += watchdog/ devices-dirs-$(CONFIG_SOFTMMU) += xen/ diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 86f6243..9b77554 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -21,7 +21,6 @@ common-obj-$(CONFIG_MACIO) += macio/ ifeq ($(CONFIG_PCI), y) obj-$(CONFIG_KVM) += ivshmem.o -obj-$(CONFIG_LINUX) += vfio.o endif obj-$(CONFIG_REALVIEW) += arm_sysctl.o diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c index d3bddf2..144912b 100644 --- a/hw/ppc/spapr_pci_vfio.c +++ b/hw/ppc/spapr_pci_vfio.c @@ -20,7 +20,7 @@ #include hw/ppc/spapr.h #include hw/pci-host/spapr.h #include linux/vfio.h -#include hw/misc/vfio.h +#include hw/vfio/vfio.h static Property spapr_phb_vfio_properties[] = { DEFINE_PROP_INT32(iommu, sPAPRPHBVFIOState, iommugroupid, -1), diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs new file mode 100644 index 000..31c7dab --- /dev/null +++ b/hw/vfio/Makefile.objs @@ -0,0 +1,3 @@ +ifeq ($(CONFIG_LINUX), y) +obj-$(CONFIG_PCI) += pci.o +endif diff --git a/hw/misc/vfio.c b/hw/vfio/pci.c similarity index 99% rename from hw/misc/vfio.c rename to hw/vfio/pci.c index 3d32657..7e6a1bc 100644 --- a/hw/misc/vfio.c +++ b/hw/vfio/pci.c @@ -39,8 +39,8 @@ #include qemu/range.h #include sysemu/kvm.h #include sysemu/sysemu.h -#include hw/misc/vfio.h #include trace.h +#include hw/vfio/vfio.h /* Extra debugging, trap acceleration paths for more logging */ #define VFIO_ALLOW_MMAP 1 diff --git a/include/hw/misc/vfio.h b/include/hw/vfio/vfio.h similarity index 100% rename from include/hw/misc/vfio.h rename to include/hw/vfio/vfio.h -- 1.8.3.2
[Qemu-devel] [PATCH v6 04/16] hw/vfio/pci: Introduce VFIORegion
This structure is going to be shared by VFIOPCIDevice and VFIOPlatformDevice. VFIOBAR includes it. vfio_eoi becomes an ops of VFIODevice specialized by parent device. This makes possible to transform vfio_bar_write/read into generic vfio_region_write/read that will be used by VFIOPlatformDevice too. vfio_mmap_bar becomes vfio_map_region Signed-off-by: Eric Auger eric.au...@linaro.org --- v4-v5: - remove fd field from VFIORegion - change error_report format string in vfio_region_write/read - remove #ifdef DEBUG_VFIO in the same function - correct missing initialization of bar region's vbasedev field - change Object * parameter name of vfio_mmap_region and remove useless OBJECT() --- hw/vfio/pci.c | 193 ++ trace-events | 4 +- 2 files changed, 103 insertions(+), 94 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index e2caa08..5e34504 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -78,15 +78,19 @@ typedef struct VFIOQuirk { } data; } VFIOQuirk; -typedef struct VFIOBAR { -off_t fd_offset; /* offset of BAR within device fd */ -int fd; /* device fd, allows us to pass VFIOBAR as opaque data */ +typedef struct VFIORegion { +struct VFIODevice *vbasedev; +off_t fd_offset; /* offset of region within device fd */ MemoryRegion mem; /* slow, read/write access */ MemoryRegion mmap_mem; /* direct mapped access */ void *mmap; size_t size; uint32_t flags; /* VFIO region flags (rd/wr/mmap) */ -uint8_t nr; /* cache the BAR number for debug */ +uint8_t nr; /* cache the region number for debug */ +} VFIORegion; + +typedef struct VFIOBAR { +VFIORegion region; bool ioport; bool mem64; QLIST_HEAD(, VFIOQuirk) quirks; @@ -206,6 +210,7 @@ typedef struct VFIODevice { struct VFIODeviceOps { bool (*vfio_compute_needs_reset)(VFIODevice *vdev); int (*vfio_hot_reset_multi)(VFIODevice *vdev); +void (*vfio_eoi)(VFIODevice *vdev); }; typedef struct VFIOPCIDevice { @@ -389,8 +394,10 @@ static void vfio_intx_interrupt(void *opaque) } } -static void vfio_eoi(VFIOPCIDevice *vdev) +static void vfio_eoi(VFIODevice *vbasedev) { +VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev); + if (!vdev-intx.pending) { return; } @@ -400,7 +407,7 @@ static void vfio_eoi(VFIOPCIDevice *vdev) vdev-intx.pending = false; pci_irq_deassert(vdev-pdev); -vfio_unmask_irqindex(vdev-vbasedev, VFIO_PCI_INTX_IRQ_INDEX); +vfio_unmask_irqindex(vbasedev, VFIO_PCI_INTX_IRQ_INDEX); } static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev) @@ -553,7 +560,7 @@ static void vfio_update_irq(PCIDevice *pdev) vfio_enable_intx_kvm(vdev); /* Re-enable the interrupt in cased we missed an EOI */ -vfio_eoi(vdev); +vfio_eoi(vdev-vbasedev); } static int vfio_enable_intx(VFIOPCIDevice *vdev) @@ -1090,10 +1097,11 @@ static void vfio_update_msi(VFIOPCIDevice *vdev) /* * IO Port/MMIO - Beware of the endians, VFIO is always little endian */ -static void vfio_bar_write(void *opaque, hwaddr addr, - uint64_t data, unsigned size) +static void vfio_region_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) { -VFIOBAR *bar = opaque; +VFIORegion *region = opaque; +VFIODevice *vbasedev = region-vbasedev; union { uint8_t byte; uint16_t word; @@ -1116,20 +1124,14 @@ static void vfio_bar_write(void *opaque, hwaddr addr, break; } -if (pwrite(bar-fd, buf, size, bar-fd_offset + addr) != size) { -error_report(%s(,0x%HWADDR_PRIx, 0x%PRIx64, %d) failed: %m, - __func__, addr, data, size); +if (pwrite(vbasedev-fd, buf, size, region-fd_offset + addr) != size) { +error_report(%s(%s:region%d+0x%HWADDR_PRIx, 0x%PRIx64 + ,%d) failed: %m, + __func__, vbasedev-name, region-nr, + addr, data, size); } -#ifdef DEBUG_VFIO -{ -VFIOPCIDevice *vdev = container_of(bar, VFIOPCIDevice, bars[bar-nr]); - -trace_vfio_bar_write(vdev-host.domain, vdev-host.bus, - vdev-host.slot, vdev-host.function, - region-nr, addr, data, size); -} -#endif +trace_vfio_region_write(vbasedev-name, region-nr, addr, data, size); /* * A read or write to a BAR always signals an INTx EOI. This will @@ -1139,13 +1141,14 @@ static void vfio_bar_write(void *opaque, hwaddr addr, * which access will service the interrupt, so we're potentially * getting quite a few host interrupts per guest interrupt. */ -vfio_eoi(container_of(bar, VFIOPCIDevice, bars[bar-nr])); +vbasedev-ops-vfio_eoi(vbasedev); } -static uint64_t vfio_bar_read(void *opaque, - hwaddr addr, unsigned size) +static uint64_t vfio_region_read(void
[Qemu-devel] [PATCH v6 10/16] hw/vfio: calxeda xgmac device
The platform device class has become abstract. The device can be be instantiated on command line using such option. -device vfio-calxeda-xgmac,host=fff51000.ethernet compat string is hardcoded in the code except if user overrides it Signed-off-by: Eric Auger eric.au...@linaro.org --- v5 - v6 - back again following Alex Graf advises - fix a bug related to compat override v4 - v5: removed since device tree was moved to hw/arm/dyn_sysbus_devtree.c v4: creation for device tree specialization --- hw/vfio/Makefile.objs| 1 + hw/vfio/calxeda_xgmac.c | 57 include/hw/vfio/vfio-calxeda-xgmac.h | 41 ++ 3 files changed, 99 insertions(+) create mode 100644 hw/vfio/calxeda_xgmac.c create mode 100644 include/hw/vfio/vfio-calxeda-xgmac.h diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs index c5c76fe..913ab14 100644 --- a/hw/vfio/Makefile.objs +++ b/hw/vfio/Makefile.objs @@ -2,4 +2,5 @@ ifeq ($(CONFIG_LINUX), y) obj-$(CONFIG_SOFTMMU) += common.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_SOFTMMU) += platform.o +obj-$(CONFIG_SOFTMMU) += calxeda_xgmac.o endif diff --git a/hw/vfio/calxeda_xgmac.c b/hw/vfio/calxeda_xgmac.c new file mode 100644 index 000..5e655ae --- /dev/null +++ b/hw/vfio/calxeda_xgmac.c @@ -0,0 +1,57 @@ +/* + * calxeda xgmac example VFIO device + * + * Copyright Linaro Limited, 2014 + * + * Authors: + * Eric Auger eric.au...@linaro.org + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include hw/vfio/vfio-calxeda-xgmac.h + +static void calxeda_xgmac_realize(DeviceState *dev, Error **errp) +{ +VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(dev); +VFIOCalxedaXgmacDeviceClass *k = VFIO_CALXEDA_XGMAC_DEVICE_GET_CLASS(dev); +const char compat[] = calxeda,hb-xgmac; + +if (vdev-compat == NULL) { +vdev-compat = g_strdup(compat); +} /* else use user-provided compat string */ + +k-parent_realize(dev, errp); +} + +static const VMStateDescription vfio_platform_vmstate = { +.name = TYPE_VFIO_CALXEDA_XGMAC, +.unmigratable = 1, +}; + +static void vfio_calxeda_xgmac_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(klass); +VFIOCalxedaXgmacDeviceClass *vcxc = +VFIO_CALXEDA_XGMAC_DEVICE_CLASS(klass); +vcxc-parent_realize = dc-realize; +dc-realize = calxeda_xgmac_realize; +dc-desc = VFIO Calxeda XGMAC; +} + +static const TypeInfo vfio_calxeda_xgmac_dev_info = { +.name = TYPE_VFIO_CALXEDA_XGMAC, +.parent = TYPE_VFIO_PLATFORM, +.instance_size = sizeof(VFIOCalxedaXgmacDevice), +.class_init = vfio_calxeda_xgmac_class_init, +.class_size = sizeof(VFIOCalxedaXgmacDeviceClass), +}; + +static void register_calxeda_xgmac_dev_type(void) +{ +type_register_static(vfio_calxeda_xgmac_dev_info); +} + +type_init(register_calxeda_xgmac_dev_type) diff --git a/include/hw/vfio/vfio-calxeda-xgmac.h b/include/hw/vfio/vfio-calxeda-xgmac.h new file mode 100644 index 000..1529cf5 --- /dev/null +++ b/include/hw/vfio/vfio-calxeda-xgmac.h @@ -0,0 +1,41 @@ +/* + * VFIO calxeda xgmac device + * + * Copyright Linaro Limited, 2014 + * + * Authors: + * Eric Auger eric.au...@linaro.org + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#ifndef HW_VFIO_VFIO_CALXEDA_XGMAC_H +#define HW_VFIO_VFIO_CALXEDA_XGMAC_H + +#include hw/vfio/vfio-platform.h + +#define TYPE_VFIO_CALXEDA_XGMAC vfio-calxeda-xgmac + +typedef struct VFIOCalxedaXgmacDevice { +VFIOPlatformDevice vdev; +} VFIOCalxedaXgmacDevice; + +typedef struct VFIOCalxedaXgmacDeviceClass { +/* private */ +VFIOPlatformDeviceClass parent_class; +/* public */ +DeviceRealize parent_realize; +} VFIOCalxedaXgmacDeviceClass; + +#define VFIO_CALXEDA_XGMAC_DEVICE(obj) \ + OBJECT_CHECK(VFIOCalxedaXgmacDevice, (obj), TYPE_VFIO_CALXEDA_XGMAC) +#define VFIO_CALXEDA_XGMAC_DEVICE_CLASS(klass) \ + OBJECT_CLASS_CHECK(VFIOCalxedaXgmacDeviceClass, (klass), \ +TYPE_VFIO_CALXEDA_XGMAC) +#define VFIO_CALXEDA_XGMAC_DEVICE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VFIOCalxedaXgmacDeviceClass, (obj), \ + TYPE_VFIO_CALXEDA_XGMAC) + +#endif -- 1.8.3.2
[Qemu-devel] [PATCH v6 09/16] hw/vfio/platform: add vfio-platform support
Minimal VFIO platform implementation supporting - register space user mapping, - IRQ assignment based on eventfds handled on qemu side. irqfd kernel acceleration comes in a subsequent patch. Signed-off-by: Kim Phillips kim.phill...@linaro.org Signed-off-by: Eric Auger eric.au...@linaro.org --- v5 - v6: - vfio_device property renamed into host property - correct error handling of VFIO_DEVICE_GET_IRQ_INFO ioctl and remove PCI related comment - remove declaration of vfio_setup_irqfd and irqfd_allowed property.Both belong to next patch (irqfd) - remove declaration of vfio_intp_interrupt in vfio-platform.h - functions that can be static get this characteristic - remove declarations of vfio_region_ops, vfio_memory_listener, group_list, vfio_address_spaces. All are moved to vfio-common.h - remove vfio_put_device declaration and definition - print_regions removed. code moved into vfio_populate_regions - replace DPRINTF by trace events - new helper routine to set the trigger eventfd - dissociate intp init from the injection enablement: vfio_enable_intp renamed into vfio_init_intp and new function named vfio_start_eventfd_injection - injection start moved to vfio_start_irq_injection (not anymore in vfio_populate_interrupt) - new start_irq_fn field in VFIOPlatformDevice corresponding to the function that will be used for starting injection - user handled eventfd: x add mutex to protect IRQ state list manipulation, x correct misleading comment in vfio_intp_interrupt. x Fix bugs thanks to fake interrupt modality - VFIOPlatformDeviceClass becomes abstract - add error_setg in vfio_platform_realize v4 - v5: - vfio-plaform.h included first - cleanup error handling in *populate*, vfio_get_device, vfio_enable_intp - vfio_put_device not called anymore - add some includes to follow vfio policy v3 - v4: [Eric Auger] - merge of vfio: Add initial IRQ support in platform device to get a full functional patch although perfs are limited. - removal of unrealize function since I currently understand it is only used with device hot-plug feature. v2 - v3: [Eric Auger] - further factorization between PCI and platform (VFIORegion, VFIODevice). same level of functionality. = v2: [Kim Philipps] - Initial Creation of the device supporting register space mapping --- hw/vfio/Makefile.objs | 1 + hw/vfio/platform.c | 599 include/hw/vfio/vfio-platform.h | 79 ++ trace-events| 12 + 4 files changed, 691 insertions(+) create mode 100644 hw/vfio/platform.c create mode 100644 include/hw/vfio/vfio-platform.h diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs index e31f30e..c5c76fe 100644 --- a/hw/vfio/Makefile.objs +++ b/hw/vfio/Makefile.objs @@ -1,4 +1,5 @@ ifeq ($(CONFIG_LINUX), y) obj-$(CONFIG_SOFTMMU) += common.o obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_SOFTMMU) += platform.o endif diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c new file mode 100644 index 000..9987b25 --- /dev/null +++ b/hw/vfio/platform.c @@ -0,0 +1,599 @@ +/* + * vfio based device assignment support - platform devices + * + * Copyright Linaro Limited, 2014 + * + * Authors: + * Kim Phillips kim.phill...@linaro.org + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + * Based on vfio based PCI device assignment support: + * Copyright Red Hat, Inc. 2012 + */ + +#include linux/vfio.h +#include sys/ioctl.h + +#include hw/vfio/vfio-platform.h +#include qemu/error-report.h +#include qemu/range.h +#include sysemu/sysemu.h +#include exec/memory.h +#include qemu/queue.h +#include hw/sysbus.h +#include trace.h + +static void vfio_intp_interrupt(VFIOINTp *intp); +typedef void (*eventfd_user_side_handler_t)(VFIOINTp *intp); +static int vfio_set_trigger_eventfd(VFIOINTp *intp, +eventfd_user_side_handler_t handler); + +/* + * Functions only used when eventfd are handled on user-side + * ie. without irqfd + */ + +/** + * vfio_platform_eoi - IRQ completion routine + * @vbasedev: the VFIO device + * + * de-asserts the active virtual IRQ and unmask the physical IRQ + * (masked by the VFIO driver). Handle pending IRQs if any. + * eoi function is called on the first access to any MMIO region + * after an IRQ was triggered. It is assumed this access corresponds + * to the IRQ status register reset. With such a mechanism, a single + * IRQ can be handled at a time since there is no way to know which + * IRQ was completed by the guest (we would need additional details + * about the IRQ status register mask) + */ +static void vfio_platform_eoi(VFIODevice *vbasedev) +{ +VFIOINTp *intp; +VFIOPlatformDevice *vdev = +container_of(vbasedev, VFIOPlatformDevice, vbasedev); + +qemu_mutex_lock(vdev-intp_mutex); +QLIST_FOREACH(intp, vdev-intp_list, next) { +if (intp-state == VFIO_IRQ_ACTIVE) { +
[Qemu-devel] [PATCH v6 05/16] hw/vfio/pci: split vfio_get_device
vfio_get_device now takes a VFIODevice as argument. The function is split into 2 parts: vfio_get_device which is generic and vfio_populate_device which is bus specific. 3 new fields are introduced in VFIODevice to store dev_info. vfio_put_base_device is created. --- v5-v6: - simplifies the split for vfio_get_device: vfio_check_device, vfio_populate_regions, vfio_populate_interrupts are now gathered into a unique specialization function dubbed vfio_populate_device v4-v5: - cleanup up of error handling and get/put operations in vfio_check_device, vfio_populate_regions, vfio_populate_interrupts and vfio_get_device. - correct misuse of errno - vfio_populate_regions always returns 0 - VFIODevice .name deallocation done in vfio_put_device instead of vfio_put_base_device - vfio_put_base_device done at vfio_get_device level. Signed-off-by: Eric Auger eric.au...@linaro.org --- hw/vfio/pci.c | 130 +++--- trace-events | 10 ++--- 2 files changed, 83 insertions(+), 57 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 5e34504..d48ca04 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -205,12 +205,16 @@ typedef struct VFIODevice { bool reset_works; bool needs_reset; VFIODeviceOps *ops; +unsigned int num_irqs; +unsigned int num_regions; +unsigned int flags; } VFIODevice; struct VFIODeviceOps { bool (*vfio_compute_needs_reset)(VFIODevice *vdev); int (*vfio_hot_reset_multi)(VFIODevice *vdev); void (*vfio_eoi)(VFIODevice *vdev); +int (*vfio_populate_device)(VFIODevice *vdev); }; typedef struct VFIOPCIDevice { @@ -297,6 +301,8 @@ static uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len); static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr, uint32_t val, int len); static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled); +static void vfio_put_base_device(VFIODevice *vbasedev); +static int vfio_populate_device(VFIODevice *vbasedev); /* * Common VFIO interrupt disable @@ -3611,6 +3617,7 @@ static VFIODeviceOps vfio_pci_ops = { .vfio_compute_needs_reset = vfio_pci_compute_needs_reset, .vfio_hot_reset_multi = vfio_pci_hot_reset_multi, .vfio_eoi = vfio_eoi, +.vfio_populate_device = vfio_populate_device, }; static void vfio_reset_handler(void *opaque) @@ -3952,70 +3959,45 @@ static void vfio_put_group(VFIOGroup *group) } } -static int vfio_get_device(VFIOGroup *group, const char *name, - VFIOPCIDevice *vdev) +static int vfio_populate_device(VFIODevice *vbasedev) { -struct vfio_device_info dev_info = { .argsz = sizeof(dev_info) }; +VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev); struct vfio_region_info reg_info = { .argsz = sizeof(reg_info) }; struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) }; -int ret, i; - -ret = ioctl(group-fd, VFIO_GROUP_GET_DEVICE_FD, name); -if (ret 0) { -error_report(vfio: error getting device %s from group %d: %m, - name, group-groupid); -error_printf(Verify all devices in group %d are bound to vfio-pci - or pci-stub and not already in use\n, group-groupid); -return ret; -} - -vdev-vbasedev.fd = ret; -vdev-vbasedev.group = group; -QLIST_INSERT_HEAD(group-device_list, vdev-vbasedev, next); +int i, ret = -1; /* Sanity check device */ -ret = ioctl(vdev-vbasedev.fd, VFIO_DEVICE_GET_INFO, dev_info); -if (ret) { -error_report(vfio: error getting device info: %m); -goto error; -} - -trace_vfio_get_device_irq(name, dev_info.flags, - dev_info.num_regions, dev_info.num_irqs); - -if (!(dev_info.flags VFIO_DEVICE_FLAGS_PCI)) { +if (!(vbasedev-flags VFIO_DEVICE_FLAGS_PCI)) { error_report(vfio: Um, this isn't a PCI device); goto error; } -vdev-vbasedev.reset_works = !!(dev_info.flags VFIO_DEVICE_FLAGS_RESET); - -if (dev_info.num_regions VFIO_PCI_CONFIG_REGION_INDEX + 1) { +if (vbasedev-num_regions VFIO_PCI_CONFIG_REGION_INDEX + 1) { error_report(vfio: unexpected number of io regions %u, - dev_info.num_regions); + vbasedev-num_regions); goto error; } -if (dev_info.num_irqs VFIO_PCI_MSIX_IRQ_INDEX + 1) { -error_report(vfio: unexpected number of irqs %u, dev_info.num_irqs); +if (vbasedev-num_irqs VFIO_PCI_MSIX_IRQ_INDEX + 1) { +error_report(vfio: unexpected number of irqs %u, vbasedev-num_irqs); goto error; } for (i = VFIO_PCI_BAR0_REGION_INDEX; i VFIO_PCI_ROM_REGION_INDEX; i++) { reg_info.index = i; -ret = ioctl(vdev-vbasedev.fd, VFIO_DEVICE_GET_REGION_INFO, reg_info); +ret = ioctl(vbasedev-fd, VFIO_DEVICE_GET_REGION_INFO,
[Qemu-devel] [PATCH v6 11/16] hw/arm/dyn_sysbus_devtree: enable vfio-calxeda-xgmac dynamic instantiation
vfio-calxeda-xgmac now can be instantiated using the -device option Signed-off-by: Eric Auger eric.au...@linaro.org --- v2 - v3: - correct bug of reg_attr[2*i] in vfio_fdt_add_device_node - fix a bug related to compat_str_len computed on original compat instead of corrected compat - wrap_vfio_fdt_add_node take a node creation function: this function needs to be specialized for each VFIO device. wrap function must be called in sysbus_device_create_devtree --- hw/arm/dyn_sysbus_devtree.c | 141 1 file changed, 141 insertions(+) diff --git a/hw/arm/dyn_sysbus_devtree.c b/hw/arm/dyn_sysbus_devtree.c index 61e5b5f..3ef9430 100644 --- a/hw/arm/dyn_sysbus_devtree.c +++ b/hw/arm/dyn_sysbus_devtree.c @@ -20,6 +20,141 @@ #include hw/arm/dyn_sysbus_devtree.h #include qemu/error-report.h #include sysemu/device_tree.h +#include hw/vfio/vfio-platform.h +#include hw/vfio/vfio-calxeda-xgmac.h + +typedef void (*vfio_fdt_add_device_node_t)(SysBusDevice *sbdev, void *opaque); + +static char *format_compat(char * compat) +{ +char *str_ptr, *corrected_compat; +/* + * process compatibility property string passed by end-user + * replaces / by , and ; by NUL character + */ +corrected_compat = g_strdup(compat); + +str_ptr = corrected_compat; +while ((str_ptr = strchr(str_ptr, '/')) != NULL) { +*str_ptr = ','; +} + +/* substitute ; with the NUL char */ +str_ptr = corrected_compat; +while ((str_ptr = strchr(str_ptr, ';')) != NULL) { +*str_ptr = '\0'; +} + +/* + * corrected compat includes a \0 before or at the same location + * as compat's one + */ +return corrected_compat; +} + +static void wrap_vfio_fdt_add_node(SysBusDevice *sbdev, void *opaque, + vfio_fdt_add_device_node_t add_node_fn) +{ +PlatformDevtreeData *data = opaque; +VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev); +VFIODevice *vbasedev = vdev-vbasedev; +gchar irq_number_prop[8]; +Object *obj = OBJECT(sbdev); +char *corrected_compat; +uint64_t irq_number; +int corrected_compat_str_len, i; + +corrected_compat = format_compat(vdev-compat); +corrected_compat_str_len = strlen(corrected_compat) + 1; +/* we copy the corrected_compat string + its \0 */ +snprintf(vdev-compat, corrected_compat_str_len, %s, corrected_compat); +g_free(corrected_compat); + +add_node_fn(sbdev, opaque); + +for (i = 0; i vbasedev-num_irqs; i++) { +snprintf(irq_number_prop, sizeof(irq_number_prop), irq[%d], i); +irq_number = object_property_get_int(obj, irq_number_prop, NULL) + + data-irq_start; +/* + * for setting irqfd up we must provide the virtual IRQ number + * which is the sum of irq_start and actual platform bus irq + * index. At realize point we do not have this info. + */ +vfio_start_irq_injection(sbdev, i, irq_number); +} +} + +static void vfio_basic_fdt_add_device_node(SysBusDevice *sbdev, +void *opaque) +{ +PlatformDevtreeData *data = opaque; +void *fdt = data-fdt; +const char *parent_node = data-node; +int compat_str_len; +char *nodename; +int i, ret; +uint32_t *irq_attr; +uint64_t *reg_attr; +uint64_t mmio_base; +uint64_t irq_number; +gchar mmio_base_prop[8]; +gchar irq_number_prop[8]; +VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev); +VFIODevice *vbasedev = vdev-vbasedev; +Object *obj = OBJECT(sbdev); + +mmio_base = object_property_get_int(obj, mmio[0], NULL); + +nodename = g_strdup_printf(%s/%s@% PRIx64, parent_node, + vbasedev-name, + mmio_base); + +qemu_fdt_add_subnode(fdt, nodename); + +compat_str_len = strlen(vdev-compat) + 1; +qemu_fdt_setprop(fdt, nodename, compatible, + vdev-compat, compat_str_len); + +reg_attr = g_new(uint64_t, vbasedev-num_regions*4); + +for (i = 0; i vbasedev-num_regions; i++) { +snprintf(mmio_base_prop, sizeof(mmio_base_prop), mmio[%d], i); +mmio_base = object_property_get_int(obj, mmio_base_prop, NULL); +reg_attr[4*i] = 1; +reg_attr[4*i+1] = mmio_base; +reg_attr[4*i+2] = 1; +reg_attr[4*i+3] = memory_region_size(vdev-regions[i]-mem); +} + +ret = qemu_fdt_setprop_sized_cells_from_array(fdt, nodename, reg, + vbasedev-num_regions*2, reg_attr); +if (ret 0) { +error_report(could not set reg property of node %s, nodename); +} + +irq_attr = g_new(uint32_t, vbasedev-num_irqs*3); + +for (i = 0; i vbasedev-num_irqs; i++) { +snprintf(irq_number_prop, sizeof(irq_number_prop), irq[%d], i); +irq_number = object_property_get_int(obj, irq_number_prop, NULL) +
[Qemu-devel] [PATCH v6 13/16] hw/vfio/platform: Add irqfd support
This patch aims at optimizing IRQ handling using irqfd framework. Instead of handling the eventfds on user-side they are handled on kernel side using - the KVM irqfd framework, - the VFIO driver virqfd framework. the virtual IRQ completion is trapped at interrupt controller This removes the need for fast/slow path swap. Overall this brings significant performance improvements. it depends on host kernel KVM irqfd. Signed-off-by: Alvise Rigo a.r...@virtualopensystems.com Signed-off-by: Eric Auger eric.au...@linaro.org --- v5 - v6 - rely on kvm_irqfds_enabled() and kvm_resamplefds_enabled() - guard KVM code with #ifdef CONFIG_KVM v3 - v4: [Alvise Rigo] Use of VFIO Platform driver v6 unmask/virqfd feature and removal of resamplefd handler. Physical IRQ unmasking is now done in VFIO driver. v3: [Eric Auger] initial support with resamplefd handled on QEMU side since the unmask was not supported on VFIO platform driver v5. --- hw/vfio/platform.c | 96 + include/hw/vfio/vfio-platform.h | 1 + trace-events| 2 + 3 files changed, 99 insertions(+) diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c index 93aa94a..a59a842 100644 --- a/hw/vfio/platform.c +++ b/hw/vfio/platform.c @@ -24,6 +24,7 @@ #include qemu/queue.h #include hw/sysbus.h #include trace.h +#include sysemu/kvm.h #define MAX_FAKE_INTP 5 @@ -323,6 +324,83 @@ static void vfio_fake_intp_injection(void *opaque) } /* + * Functions used for irqfd + */ + +#ifdef CONFIG_KVM + +/** + * vfio_set_resample_eventfd - sets the resamplefd for an IRQ + * @intp: the IRQ struct pointer + * programs the VFIO driver to unmask this IRQ when the + * intp-unmask eventfd is triggered + */ +static int vfio_set_resample_eventfd(VFIOINTp *intp) +{ +VFIODevice *vbasedev = intp-vdev-vbasedev; +struct vfio_irq_set *irq_set; +int argsz, ret; +int32_t *pfd; + +argsz = sizeof(*irq_set) + sizeof(*pfd); +irq_set = g_malloc0(argsz); +irq_set-argsz = argsz; +irq_set-flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_UNMASK; +irq_set-index = intp-pin; +irq_set-start = 0; +irq_set-count = 1; +pfd = (int32_t *)irq_set-data; +*pfd = event_notifier_get_fd(intp-unmask); +qemu_set_fd_handler(*pfd, NULL, NULL, intp); +ret = ioctl(vbasedev-fd, VFIO_DEVICE_SET_IRQS, irq_set); +g_free(irq_set); +if (ret 0) { +error_report(vfio: Failed to set resample eventfd: %m); +qemu_set_fd_handler(*pfd, NULL, NULL, NULL); +} +return ret; +} + +/** + * vfio_start_irqfd_injection - starts irqfd injection for an IRQ + * programs VFIO driver with both the trigger and resamplefd + * programs KVM with the gsi, trigger resample eventfds + */ +static int vfio_start_irqfd_injection(VFIOINTp *intp) +{ +struct kvm_irqfd irqfd = { +.fd = event_notifier_get_fd(intp-interrupt), +.resamplefd = event_notifier_get_fd(intp-unmask), +.gsi = intp-virtualID, +.flags = KVM_IRQFD_FLAG_RESAMPLE, +}; + +if (kvm_vm_ioctl(kvm_state, KVM_IRQFD, irqfd)) { +error_report(vfio: Error: Failed to assign the irqfd: %m); +goto fail_irqfd; +} +if (vfio_set_trigger_eventfd(intp, NULL) 0) { +goto fail_vfio; +} +if (vfio_set_resample_eventfd(intp) 0) { +goto fail_vfio; +} + +intp-kvm_accel = true; +trace_vfio_platform_start_irqfd_injection(intp-pin, intp-virtualID, + irqfd.fd, irqfd.resamplefd); +return 0; + +fail_vfio: +irqfd.flags = KVM_IRQFD_FLAG_DEASSIGN; +kvm_vm_ioctl(kvm_state, KVM_IRQFD, irqfd); +fail_irqfd: +return -1; +} + +#endif + +/* * Functions used whatever the injection method */ @@ -418,6 +496,13 @@ static VFIOINTp *vfio_init_intp(VFIODevice *vbasedev, unsigned int index) error_report(vfio: Error: trigger event_notifier_init failed ); return NULL; } +/* Get an eventfd for resample/unmask */ +ret = event_notifier_init(intp-unmask, 0); +if (ret) { +g_free(intp); +error_report(vfio: Error: resample event_notifier_init failed eoi); +return NULL; +} /* store the new intp in qlist */ QLIST_INSERT_HEAD(vdev-intp_list, intp, next); @@ -660,7 +745,17 @@ static void vfio_platform_realize(DeviceState *dev, Error **errp) vbasedev-type = VFIO_DEVICE_TYPE_PLATFORM; vbasedev-ops = vfio_platform_ops; + +#ifdef CONFIG_KVM +if (kvm_irqfds_enabled() kvm_resamplefds_enabled() +vdev-irqfd_allowed) { +vdev-start_irq_fn = vfio_start_irqfd_injection; +} else { +vdev-start_irq_fn = vfio_start_eventfd_injection; +} +#else vdev-start_irq_fn = vfio_start_eventfd_injection; +#endif trace_vfio_platform_realize(vbasedev-name, vdev-compat); @@ -694,6 +789,7 @@ static Property vfio_platform_dev_properties[] = { qdev_prop_uint32, uint32_t),
[Qemu-devel] [PATCH v6 07/16] hw/vfio/pci: use name field in format strings
Signed-off-by: Eric Auger eric.au...@linaro.org --- hw/vfio/pci.c | 213 -- trace-events | 105 ++--- 2 files changed, 111 insertions(+), 207 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 5623539..c617b79 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -387,9 +387,7 @@ static void vfio_intx_interrupt(void *opaque) return; } -trace_vfio_intx_interrupt(vdev-host.domain, vdev-host.bus, - vdev-host.slot, vdev-host.function, - 'A' + vdev-intx.pin); +trace_vfio_intx_interrupt(vdev-vbasedev.name, 'A' + vdev-intx.pin); vdev-intx.pending = true; pci_irq_assert(vdev-pdev); @@ -408,8 +406,7 @@ static void vfio_eoi(VFIODevice *vbasedev) return; } -trace_vfio_eoi(vdev-host.domain, vdev-host.bus, - vdev-host.slot, vdev-host.function); +trace_vfio_eoi(vbasedev-name); vdev-intx.pending = false; pci_irq_deassert(vdev-pdev); @@ -478,8 +475,7 @@ static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev) vdev-intx.kvm_accel = true; -trace_vfio_enable_intx_kvm(vdev-host.domain, vdev-host.bus, - vdev-host.slot, vdev-host.function); +trace_vfio_enable_intx_kvm(vdev-vbasedev.name); return; @@ -531,8 +527,7 @@ static void vfio_disable_intx_kvm(VFIOPCIDevice *vdev) /* If we've missed an event, let it re-fire through QEMU */ vfio_unmask_irqindex(vdev-vbasedev, VFIO_PCI_INTX_IRQ_INDEX); -trace_vfio_disable_intx_kvm(vdev-host.domain, vdev-host.bus, -vdev-host.slot, vdev-host.function); +trace_vfio_disable_intx_kvm(vdev-vbasedev.name); #endif } @@ -551,8 +546,7 @@ static void vfio_update_irq(PCIDevice *pdev) return; /* Nothing changed */ } -trace_vfio_update_irq(vdev-host.domain, vdev-host.bus, - vdev-host.slot, vdev-host.function, +trace_vfio_update_irq(vdev-vbasedev.name, vdev-intx.route.irq, route.irq); vfio_disable_intx_kvm(vdev); @@ -628,8 +622,7 @@ static int vfio_enable_intx(VFIOPCIDevice *vdev) vdev-interrupt = VFIO_INT_INTx; -trace_vfio_enable_intx(vdev-host.domain, vdev-host.bus, - vdev-host.slot, vdev-host.function); +trace_vfio_enable_intx(vdev-vbasedev.name); return 0; } @@ -651,8 +644,7 @@ static void vfio_disable_intx(VFIOPCIDevice *vdev) vdev-interrupt = VFIO_INT_NONE; -trace_vfio_disable_intx(vdev-host.domain, vdev-host.bus, -vdev-host.slot, vdev-host.function); +trace_vfio_disable_intx(vdev-vbasedev.name); } /* @@ -679,9 +671,7 @@ static void vfio_msi_interrupt(void *opaque) abort(); } -trace_vfio_msi_interrupt(vdev-host.domain, vdev-host.bus, - vdev-host.slot, vdev-host.function, - nr, msg.address, msg.data); +trace_vfio_msi_interrupt(vbasedev-name, nr, msg.address, msg.data); #endif if (vdev-interrupt == VFIO_INT_MSIX) { @@ -788,9 +778,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr, VFIOMSIVector *vector; int ret; -trace_vfio_msix_vector_do_use(vdev-host.domain, vdev-host.bus, - vdev-host.slot, vdev-host.function, - nr); +trace_vfio_msix_vector_do_use(vdev-vbasedev.name, nr); vector = vdev-msi_vectors[nr]; @@ -876,9 +864,7 @@ static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr) VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); VFIOMSIVector *vector = vdev-msi_vectors[nr]; -trace_vfio_msix_vector_release(vdev-host.domain, vdev-host.bus, - vdev-host.slot, vdev-host.function, - nr); +trace_vfio_msix_vector_release(vdev-vbasedev.name, nr); /* * There are still old guests that mask and unmask vectors on every @@ -941,8 +927,7 @@ static void vfio_enable_msix(VFIOPCIDevice *vdev) error_report(vfio: msix_set_vector_notifiers failed); } -trace_vfio_enable_msix(vdev-host.domain, vdev-host.bus, - vdev-host.slot, vdev-host.function); +trace_vfio_enable_msix(vdev-vbasedev.name); } static void vfio_enable_msi(VFIOPCIDevice *vdev) @@ -1018,9 +1003,7 @@ retry: return; } -trace_vfio_enable_msi(vdev-host.domain, vdev-host.bus, - vdev-host.slot, vdev-host.function, - vdev-nr_vectors); +trace_vfio_enable_msi(vdev-vbasedev.name, vdev-nr_vectors); } static void vfio_disable_msi_common(VFIOPCIDevice *vdev) @@ -1070,8 +1053,7 @@ static void vfio_disable_msix(VFIOPCIDevice *vdev) vfio_disable_msi_common(vdev); -
[Qemu-devel] [PATCH v6 12/16] vfio/platform: add fake injection modality
This code is aimed at testing multiple IRQ injection with user-side handled eventfds. Principle is a timer periodically triggers an IRQ at VFIO driver level. Then this IRQ follows regular VFIO driver - eventfd trigger - user-side eventfd handler. The IRQ is not injected into the guest. the IRQ is completed on another timer timeout to emulate eoi on write/read access. for instance, following options x-fake-irq[0]=1,x-fake-period[0]=10,x-fake-duration[0]=50, x-fake-irq[1]=2,x-fake-period[i]=20,x-fake-duration[1]=100 set vfio platform IRQ indexed #1 and #2 as fake IRQ Signed-off-by: Eric Auger eric.au...@linaro.org --- this modality was used to test calxeda xgmac assignment with main IRQ generated by the HW and IRQ #1 and #2 as fake IRQs --- hw/vfio/platform.c | 131 +++- include/hw/vfio/vfio-platform.h | 13 trace-events| 3 + 3 files changed, 145 insertions(+), 2 deletions(-) diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c index 9987b25..93aa94a 100644 --- a/hw/vfio/platform.c +++ b/hw/vfio/platform.c @@ -25,6 +25,8 @@ #include hw/sysbus.h #include trace.h +#define MAX_FAKE_INTP 5 + static void vfio_intp_interrupt(VFIOINTp *intp); typedef void (*eventfd_user_side_handler_t)(VFIOINTp *intp); static int vfio_set_trigger_eventfd(VFIOINTp *intp, @@ -141,6 +143,27 @@ static void vfio_intp_mmap_enable(void *opaque) } /** + * vfio_fake_intp_index - returns the fake IRQ index + * + * @intp the interrupt struct pointer + * if the IRQ is not fake, returns 0 + * if it is fake returns the index of the fake IRQ + * ie the index i for which x-fake-irq[i]=intp-pin + */ +static int vfio_fake_intp_index(VFIOINTp *intp) +{ +VFIOPlatformDevice *vdev = intp-vdev; +int i; + +for (i = 0; i MAX_FAKE_INTP; i++) { +if (intp-pin == vdev-fake_intp_index[i]) { +return i; +} +} +return -1; +} + +/** * vfio_intp_interrupt - The user-side eventfd handler * @opaque: opaque pointer which in practice is the VFIOINTp* * @@ -199,8 +222,18 @@ static void vfio_intp_interrupt(VFIOINTp *intp) /* sets slow path */ vfio_mmap_set_enabled(vdev, false); -/* trigger the virtual IRQ */ -qemu_set_irq(intp-qemuirq, 1); +if (intp-fake_intp_index 0) { +/* trigger the virtual IRQ */ +qemu_set_irq(intp-qemuirq, 1); +} else { +/* + * the vIRQ is not triggered but we emulate a handling + * duration + */ +timer_mod(intp-fake_eoi_timer, + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + + intp-fake_intp_duration); +} /* schedule the mmap timer which will restore mmap path after EOI*/ if (vdev-mmap_timeout) { @@ -231,9 +264,64 @@ static int vfio_start_eventfd_injection(VFIOINTp *intp) return ret; } vfio_unmask_irqindex(vbasedev, intp-pin); + +/* in case of fake irq, starts its injection */ +if (intp-fake_intp_index = 0) { +timer_mod(intp-fake_intp_timer, + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + + intp-fake_intp_period); +} return 0; } +/** + * vfio_fake_intp_eoi - fake interrupt completion routine + * @opaque: actually is an IRQ struct pointer + * + * called on timer handler context + */ +static void vfio_fake_intp_eoi(void *opaque) +{ +VFIOINTp *intp = (VFIOINTp *)opaque; +trace_vfio_fake_intp_eoi(intp-pin); +vfio_platform_eoi(intp-vdev-vbasedev); +} + +/** + * vfio_fake_intp_eoi - fake interrupt injection routine + * @opaque: actually is an IRQ struct pointer + * + * called on timer context + * use the VFIO loopback mode, ie. triggers the eventfd + * associated to the intp-pin although no physical IRQ hit. + */ +static void vfio_fake_intp_injection(void *opaque) +{ +VFIOINTp *intp = (VFIOINTp *)opaque; +VFIODevice *vbasedev = intp-vdev-vbasedev; +struct vfio_irq_set *irq_set; +int argsz, ret; +int32_t *pfd; + +argsz = sizeof(*irq_set) + sizeof(*pfd); +irq_set = g_malloc0(argsz); +irq_set-argsz = argsz; +irq_set-flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER; +irq_set-index = intp-pin; +irq_set-start = 0; +irq_set-count = 1; +ret = ioctl(vbasedev-fd, VFIO_DEVICE_SET_IRQS, irq_set); +g_free(irq_set); +if (ret 0) { +error_report(vfio: Failed to trigger fake IRQ: %m); +} else { +trace_vfio_fake_intp_injection(intp-pin); +timer_mod(intp-fake_intp_timer, + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + + intp-fake_intp_period); +} +} + /* * Functions used whatever the injection method */ @@ -304,6 +392,23 @@ static VFIOINTp *vfio_init_intp(VFIODevice *vbasedev, unsigned int index) intp-vdev = vdev; intp-pin = index; intp-state = VFIO_IRQ_INACTIVE; +intp-fake_intp_index = vfio_fake_intp_index(intp); + +if (intp-fake_intp_index = 0)
[Qemu-devel] [PATCH v6 14/16] linux-headers: Update KVM headers from linux-next tag ToBeFilled
Syncup KVM related linux headers from linux-next tree using scripts/update-linux-headers.sh. Integrate updated KVM-VFIO API related to forwarded IRQ Signed-off-by: Eric Auger eric.au...@linaro.org --- linux-headers/linux/kvm.h | 9 + 1 file changed, 9 insertions(+) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index f5d2c38..42128d5 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -940,6 +940,12 @@ struct kvm_device_attr { __u64 addr; /* userspace address of attr data */ }; +struct kvm_arch_forwarded_irq { +__u32 fd; /* file desciptor of the VFIO device */ +__u32 index; /* VFIO device IRQ index */ +__u32 gsi; /* gsi, ie. virtual IRQ number */ +}; + #define KVM_DEV_TYPE_FSL_MPIC_20 1 #define KVM_DEV_TYPE_FSL_MPIC_42 2 #define KVM_DEV_TYPE_XICS 3 @@ -947,6 +953,9 @@ struct kvm_device_attr { #define KVM_DEV_VFIO_GROUP1 #define KVM_DEV_VFIO_GROUP_ADD 1 #define KVM_DEV_VFIO_GROUP_DEL 2 +#define KVM_DEV_VFIO_DEVICE 2 +#define KVM_DEV_VFIO_DEVICE_FORWARD_IRQ 1 +#define KVM_DEV_VFIO_DEVICE_UNFORWARD_IRQ2 #define KVM_DEV_TYPE_ARM_VGIC_V2 5 #define KVM_DEV_TYPE_FLIC 6 -- 1.8.3.2
[Qemu-devel] [PATCH v6 15/16] VFIO: COMMON: vfio_kvm_device_fd moved in the common header
the device is now used in platform for forwarded IRQ setup Signed-off-by: Eric Auger eric.au...@linaro.org --- hw/vfio/common.c | 3 ++- include/hw/vfio/vfio-common.h | 5 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 252c0b8..466b0e8 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -44,9 +44,10 @@ struct vfio_as_head vfio_address_spaces = * initialized, this file descriptor is only released on QEMU exit and * we'll re-use it should another vfio device be attached before then. */ -static int vfio_kvm_device_fd = -1; +int vfio_kvm_device_fd = -1; #endif + /* * Common VFIO interrupt disable */ diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index 83c7876..0ae0153 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -41,6 +41,11 @@ #define VFIO_ALLOW_KVM_MSI 1 #define VFIO_ALLOW_KVM_MSIX 1 +#ifdef CONFIG_KVM +extern int vfio_kvm_device_fd; +#endif + + enum { VFIO_DEVICE_TYPE_PCI = 0, VFIO_DEVICE_TYPE_PLATFORM = 1, -- 1.8.3.2
[Qemu-devel] [PATCH v6 16/16] VFIO: PLATFORM: add forwarded irq support
Tests whether the forwarded IRQ modality is available. In the positive device IRQs are forwarded. This control is achieved with KVM-VFIO device. with such a modality injection still is handled through irqfds. However end of interrupt is not trapped anymore. As soon as the guest completes its virtual IRQ, the corresponding physical IRQ is completed and the same physical IRQ can hit again. A new x-forward property enables to force forwarding off although enabled by the kernel. Signed-off-by: Eric Auger eric.au...@linaro.org --- hw/vfio/platform.c | 52 + include/hw/vfio/vfio-platform.h | 2 ++ trace-events| 1 + 3 files changed, 55 insertions(+) diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c index a59a842..2d07d2f 100644 --- a/hw/vfio/platform.c +++ b/hw/vfio/platform.c @@ -324,6 +324,52 @@ static void vfio_fake_intp_injection(void *opaque) } /* + * Functions used with forwarding capability + */ + +#ifdef CONFIG_KVM + +static bool has_kvm_vfio_forward_capability(void) +{ +struct kvm_device_attr attr = { + .group = KVM_DEV_VFIO_DEVICE, + .attr = KVM_DEV_VFIO_DEVICE_FORWARD_IRQ}; + +if (ioctl(vfio_kvm_device_fd, KVM_HAS_DEVICE_ATTR, attr) == 0) { +return true; +} else { +return false; +} +} + +static int vfio_set_forwarding(VFIOINTp *intp) +{ +int ret; +struct kvm_device_attr attr = { + .group = KVM_DEV_VFIO_DEVICE, + .attr = KVM_DEV_VFIO_DEVICE_FORWARD_IRQ}; + +intp-fwd_irq = g_malloc0(sizeof(*intp-fwd_irq)); +intp-fwd_irq-fd = intp-vdev-vbasedev.fd; +intp-fwd_irq-index = intp-pin; +intp-fwd_irq-gsi = intp-virtualID; + +attr.addr = (uint64_t)(unsigned long)intp-fwd_irq; + +if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, attr)) { +error_report(Failed to forward IRQ %d through KVM VFIO device, + intp-pin); +g_free(intp-fwd_irq); +return -errno; +} +trace_vfio_start_fwd_injection(intp-pin); + +return ret; +} + +#endif + +/* * Functions used for irqfd */ @@ -375,6 +421,11 @@ static int vfio_start_irqfd_injection(VFIOINTp *intp) .flags = KVM_IRQFD_FLAG_RESAMPLE, }; +if (has_kvm_vfio_forward_capability() + intp-vdev-forward_allowed) { +vfio_set_forwarding(intp); +} + if (kvm_vm_ioctl(kvm_state, KVM_IRQFD, irqfd)) { error_report(vfio: Error: Failed to assign the irqfd: %m); goto fail_irqfd; @@ -790,6 +841,7 @@ static Property vfio_platform_dev_properties[] = { DEFINE_PROP_UINT32(mmap-timeout-ms, VFIOPlatformDevice, mmap_timeout, 1100), DEFINE_PROP_BOOL(x-irqfd, VFIOPlatformDevice, irqfd_allowed, true), +DEFINE_PROP_BOOL(x-forward, VFIOPlatformDevice, forward_allowed, true), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/vfio/vfio-platform.h b/include/hw/vfio/vfio-platform.h index e896c86..6c46295 100644 --- a/include/hw/vfio/vfio-platform.h +++ b/include/hw/vfio/vfio-platform.h @@ -48,6 +48,7 @@ typedef struct VFIOINTp { QEMUTimer *fake_eoi_timer; /* timer to handle fake IRQ completion */ uint32_t fake_intp_period; /* delay between fake IRQ injections */ uint32_t fake_intp_duration; /* duration of the IRQ */ +struct kvm_arch_forwarded_irq *fwd_irq; } VFIOINTp; typedef int (*start_irq_fn_t)(VFIOINTp *intp); @@ -72,6 +73,7 @@ typedef struct VFIOPlatformDevice { uint32_t len_x_fake_period; uint32_t len_x_fake_duration; bool irqfd_allowed; /* debug option to force irqfd on/off */ +bool forward_allowed; /* debug option to force forwarding on/off */ } VFIOPlatformDevice; diff --git a/trace-events b/trace-events index 1b81b66..29e03d2 100644 --- a/trace-events +++ b/trace-events @@ -1378,6 +1378,7 @@ vfio_get_device(const char * name, unsigned int flags, unsigned int num_regions, vfio_put_base_device(int fd) close vdev-fd=%d # hw/vfio/platform.c +vfio_start_fwd_injection(int pin) forwarding set for IRQ pin %d vfio_platform_eoi(int pin, int fd) EOI IRQ pin %d (fd=%d) vfio_platform_mmap_set_enabled(bool enabled) fast path = %d vfio_platform_intp_mmap_enable(int pin) IRQ #%d still active, stay in slow path -- 1.8.3.2
[Qemu-devel] [PATCH] Prevent segmentation fault in case of relative resolve of uri
From: Miroslav Rezanina mreza...@redhat.com It was possible to call strcmp with NULL argument, that can cause segmentation fault. Properly checking parameters to prevent this situation. Signed-off-by: Miroslav Rezanina mreza...@redhat.com --- util/uri.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/uri.c b/util/uri.c index e348c17..16c01d0 100644 --- a/util/uri.c +++ b/util/uri.c @@ -1985,7 +1985,8 @@ uri_resolve_relative (const char *uri, const char * base) val = g_strdup (uri); goto done; } -if (!strcmp(bas-path, ref-path)) { +if (bas-path != NULL ref-path != NULL +!strcmp(bas-path, ref-path)) { val = g_strdup(); goto done; } -- 1.9.3
[Qemu-devel] [PATCH v6 06/16] hw/vfio/pci: rename group_list into vfio_group_list
better fit in the rest of the namespace Signed-off-by: Eric Auger eric.au...@linaro.org --- hw/vfio/pci.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index d48ca04..5623539 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -283,7 +283,7 @@ static const VFIORomBlacklistEntry romblacklist[] = { #define MSIX_CAP_LENGTH 12 static QLIST_HEAD(, VFIOGroup) -group_list = QLIST_HEAD_INITIALIZER(group_list); +vfio_group_list = QLIST_HEAD_INITIALIZER(vfio_group_list); #ifdef CONFIG_KVM /* @@ -3454,7 +3454,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) continue; } -QLIST_FOREACH(group, group_list, next) { +QLIST_FOREACH(group, vfio_group_list, next) { if (group-groupid == devices[i].group_id) { break; } @@ -3501,7 +3501,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) /* Determine how many group fds need to be passed */ count = 0; -QLIST_FOREACH(group, group_list, next) { +QLIST_FOREACH(group, vfio_group_list, next) { for (i = 0; i info-count; i++) { if (group-groupid == devices[i].group_id) { count++; @@ -3515,7 +3515,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single) fds = reset-group_fds[0]; /* Fill in group fds */ -QLIST_FOREACH(group, group_list, next) { +QLIST_FOREACH(group, vfio_group_list, next) { for (i = 0; i info-count; i++) { if (group-groupid == devices[i].group_id) { fds[reset-count++] = group-fd; @@ -3550,7 +3550,7 @@ out: continue; } -QLIST_FOREACH(group, group_list, next) { +QLIST_FOREACH(group, vfio_group_list, next) { if (group-groupid == devices[i].group_id) { break; } @@ -3625,13 +3625,13 @@ static void vfio_reset_handler(void *opaque) VFIOGroup *group; VFIODevice *vbasedev; -QLIST_FOREACH(group, group_list, next) { +QLIST_FOREACH(group, vfio_group_list, next) { QLIST_FOREACH(vbasedev, group-device_list, next) { vbasedev-ops-vfio_compute_needs_reset(vbasedev); } } -QLIST_FOREACH(group, group_list, next) { +QLIST_FOREACH(group, vfio_group_list, next) { QLIST_FOREACH(vbasedev, group-device_list, next) { if (vbasedev-needs_reset) { vbasedev-ops-vfio_hot_reset_multi(vbasedev); @@ -3880,7 +3880,7 @@ static VFIOGroup *vfio_get_group(int groupid, AddressSpace *as) char path[32]; struct vfio_group_status status = { .argsz = sizeof(status) }; -QLIST_FOREACH(group, group_list, next) { +QLIST_FOREACH(group, vfio_group_list, next) { if (group-groupid == groupid) { /* Found it. Now is it already in the right context? */ if (group-container-space-as == as) { @@ -3922,11 +3922,11 @@ static VFIOGroup *vfio_get_group(int groupid, AddressSpace *as) goto close_fd_exit; } -if (QLIST_EMPTY(group_list)) { +if (QLIST_EMPTY(vfio_group_list)) { qemu_register_reset(vfio_reset_handler, NULL); } -QLIST_INSERT_HEAD(group_list, group, next); +QLIST_INSERT_HEAD(vfio_group_list, group, next); vfio_kvm_device_add_group(group); @@ -3954,7 +3954,7 @@ static void vfio_put_group(VFIOGroup *group) close(group-fd); g_free(group); -if (QLIST_EMPTY(group_list)) { +if (QLIST_EMPTY(vfio_group_list)) { qemu_unregister_reset(vfio_reset_handler, NULL); } } -- 1.8.3.2
[Qemu-devel] [PATCH v6 08/16] hw/vfio: create common module
A new common module is created. It implements all functions that have no device specificity (PCI, Platform). This patch only consists in move (no functional changes) Signed-off-by: Kim Phillips kim.phill...@linaro.org Signed-off-by: Eric Auger eric.au...@linaro.org --- v5 - v6: - follow all evolutions of original PCI code from v5 to V6 - move declaration of vfio_region_ops, vfio_memory_listener, vfio_group_list, vfio_address_spaces into vfio-common.h v4 - v5: - integrate sPAPR/IOMMU: Fix TCE entry permission - VFIOdevice .name dealloc removed from vfio_put_base_device - add some includes according to vfio inclusion policy v3 - v4: [Eric Auger] move done after all PCI modifications to anticipate for VFIO Platform needs. Purpose is to alleviate the whole review process. = v3 First split done by Kim Phillips --- hw/vfio/Makefile.objs |1 + hw/vfio/common.c | 958 ++ hw/vfio/pci.c | 1028 + include/hw/vfio/vfio-common.h | 152 ++ trace-events |1 + 5 files changed, 1113 insertions(+), 1027 deletions(-) create mode 100644 hw/vfio/common.c create mode 100644 include/hw/vfio/vfio-common.h diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs index 31c7dab..e31f30e 100644 --- a/hw/vfio/Makefile.objs +++ b/hw/vfio/Makefile.objs @@ -1,3 +1,4 @@ ifeq ($(CONFIG_LINUX), y) +obj-$(CONFIG_SOFTMMU) += common.o obj-$(CONFIG_PCI) += pci.o endif diff --git a/hw/vfio/common.c b/hw/vfio/common.c new file mode 100644 index 000..252c0b8 --- /dev/null +++ b/hw/vfio/common.c @@ -0,0 +1,958 @@ +/* + * generic functions used by VFIO devices + * + * Copyright Red Hat, Inc. 2012 + * + * Authors: + * Alex Williamson alex.william...@redhat.com + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + * Based on qemu-kvm device-assignment: + * Adapted for KVM by Qumranet. + * Copyright (c) 2007, Neocleus, Alex Novik (a...@neocleus.com) + * Copyright (c) 2007, Neocleus, Guy Zana (g...@neocleus.com) + * Copyright (C) 2008, Qumranet, Amit Shah (amit.s...@qumranet.com) + * Copyright (C) 2008, Red Hat, Amit Shah (amit.s...@redhat.com) + * Copyright (C) 2008, IBM, Muli Ben-Yehuda (m...@il.ibm.com) + */ + +#include sys/ioctl.h +#include sys/mman.h +#include linux/vfio.h + +#include hw/vfio/vfio-common.h +#include hw/vfio/vfio.h +#include exec/address-spaces.h +#include exec/memory.h +#include hw/hw.h +#include qemu/error-report.h +#include sysemu/kvm.h +#include trace.h + +struct vfio_group_head vfio_group_list = +QLIST_HEAD_INITIALIZER(vfio_address_spaces); +struct vfio_as_head vfio_address_spaces = +QLIST_HEAD_INITIALIZER(vfio_address_spaces); + +#ifdef CONFIG_KVM +/* + * We have a single VFIO pseudo device per KVM VM. Once created it lives + * for the life of the VM. Closing the file descriptor only drops our + * reference to it and the device's reference to kvm. Therefore once + * initialized, this file descriptor is only released on QEMU exit and + * we'll re-use it should another vfio device be attached before then. + */ +static int vfio_kvm_device_fd = -1; +#endif + +/* + * Common VFIO interrupt disable + */ +void vfio_disable_irqindex(VFIODevice *vbasedev, int index) +{ +struct vfio_irq_set irq_set = { +.argsz = sizeof(irq_set), +.flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER, +.index = index, +.start = 0, +.count = 0, +}; + +ioctl(vbasedev-fd, VFIO_DEVICE_SET_IRQS, irq_set); +} + +void vfio_unmask_irqindex(VFIODevice *vbasedev, int index) +{ +struct vfio_irq_set irq_set = { +.argsz = sizeof(irq_set), +.flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_UNMASK, +.index = index, +.start = 0, +.count = 1, +}; + +ioctl(vbasedev-fd, VFIO_DEVICE_SET_IRQS, irq_set); +} + +void vfio_mask_irqindex(VFIODevice *vbasedev, int index) +{ +struct vfio_irq_set irq_set = { +.argsz = sizeof(irq_set), +.flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_MASK, +.index = index, +.start = 0, +.count = 1, +}; + +ioctl(vbasedev-fd, VFIO_DEVICE_SET_IRQS, irq_set); +} + +/* + * IO Port/MMIO - Beware of the endians, VFIO is always little endian + */ +void vfio_region_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ +VFIORegion *region = opaque; +VFIODevice *vbasedev = region-vbasedev; +union { +uint8_t byte; +uint16_t word; +uint32_t dword; +uint64_t qword; +} buf; + +switch (size) { +case 1: +buf.byte = data; +break; +case 2: +buf.word = data; +break; +case 4: +buf.dword = data; +break; +default: +hw_error(vfio: unsupported write size, %d bytes, size); +break; +
Re: [Qemu-devel] [PATCH] hw/dma: Print error message only once
Il 09/09/2014 09:01, Philipp Hahn ha scritto: otherwise the message dma: unregistered DMA channel used nchan=0 dma_pos=0 dma_len=1 gets printed every time and fills up the log-file with 50 MiB / minute. Signed-off-by: Philipp Hahn h...@univention.de --- hw/dma/i8257.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index dd370ed..9673ab6 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -473,8 +473,14 @@ static void dma_reset(void *opaque) static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len) { -dolog (unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d\n, - nchan, dma_pos, dma_len); +static int once; +int mask = 1 nchan; + +if (0 == (once mask)) { +once |= mask; +dolog(unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d\n, + nchan, dma_pos, dma_len); +} return dma_pos; } Can you just convert it to a tracepoint and remove the message? Thanks, Paolo
[Qemu-devel] [PATCH v3 1/6] hw/misc/dyn_sysbus_binding: helpers for sysbus device dynamic binding
This new module implements routines which help in dynamic device binding (mmio regions, irq). They are supposed to be used by machine files that support dynamic sysbus instantiation. Signed-off-by: Alexander Graf ag...@suse.de Signed-off-by: Eric Auger eric.au...@linaro.org --- v1 - v2: - platform_devices renamed into dyn_sysbus_binding - PlatformParams renamed into DynSysbusParams - PlatformBusNotifier renamed into DynSysbusNotifier - platform_bus_map_irq, platform_bus_map_mmio, sysbus_device_check, platform_bus_init become static - PlatformBusInitData becomes private to the module - page_shift becomes a member of DynSysbusParams v1: Dynamic sysbus device allocation fully written by Alex Graf. Those functions were initially in ppc e500 machine file. Now moved to a separate module. PPCE500Params is replaced by a generic struct named PlatformParams --- hw/misc/Makefile.objs| 1 + hw/misc/dyn_sysbus_binding.c | 163 +++ include/hw/misc/dyn_sysbus_binding.h | 24 ++ 3 files changed, 188 insertions(+) create mode 100644 hw/misc/dyn_sysbus_binding.c create mode 100644 include/hw/misc/dyn_sysbus_binding.h diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 979e532..86f6243 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -41,3 +41,4 @@ obj-$(CONFIG_SLAVIO) += slavio_misc.o obj-$(CONFIG_ZYNQ) += zynq_slcr.o obj-$(CONFIG_PVPANIC) += pvpanic.o +obj-y += dyn_sysbus_binding.o diff --git a/hw/misc/dyn_sysbus_binding.c b/hw/misc/dyn_sysbus_binding.c new file mode 100644 index 000..0f34f0b --- /dev/null +++ b/hw/misc/dyn_sysbus_binding.c @@ -0,0 +1,163 @@ +#include hw/misc/dyn_sysbus_binding.h +#include qemu/error-report.h + +typedef struct PlatformBusInitData { +unsigned long *used_irqs; +unsigned long *used_mem; +MemoryRegion *mem; +qemu_irq *irqs; +int device_count; +DynSysbusParams *params; +} PlatformBusInitData; + + +static int platform_bus_map_irq(DynSysbusParams *params, +SysBusDevice *sbdev, +int n, unsigned long *used_irqs, +qemu_irq *platform_irqs) +{ +int max_irqs = params-platform_bus_num_irqs; +char *prop = g_strdup_printf(irq[%d], n); +int irqn = object_property_get_int(OBJECT(sbdev), prop, NULL); + +if (irqn == SYSBUS_DYNAMIC) { +/* Find the first available IRQ */ +irqn = find_first_zero_bit(used_irqs, max_irqs); +} + +if ((irqn = max_irqs) || test_and_set_bit(irqn, used_irqs)) { +hw_error(IRQ %d is already allocated or no free IRQ left, irqn); +} + +sysbus_connect_irq(sbdev, n, platform_irqs[irqn]); +object_property_set_int(OBJECT(sbdev), irqn, prop, NULL); + +g_free(prop); +return 0; +} + +static int platform_bus_map_mmio(DynSysbusParams *params, + SysBusDevice *sbdev, + int n, unsigned long *used_mem, + MemoryRegion *pmem) +{ +MemoryRegion *device_mem = sbdev-mmio[n].memory; +uint64_t size = memory_region_size(device_mem); +uint64_t page_size = (1 params-page_shift); +uint64_t page_mask = page_size - 1; +uint64_t size_pages = (size + page_mask) params-page_shift; +uint64_t max_size = params-platform_bus_size; +uint64_t max_pages = max_size params-page_shift; +char *prop = g_strdup_printf(mmio[%d], n); +hwaddr addr = object_property_get_int(OBJECT(sbdev), prop, NULL); +int page; +int i; + +page = addr params-page_shift; +if (addr == SYSBUS_DYNAMIC) { +uint64_t size_pages_align; + +/* Align the region to at least its own size granularity */ +if (is_power_of_2(size_pages)) { +size_pages_align = size_pages; +} else { +size_pages_align = pow2floor(size_pages) 1; +} + +/* Find the first available region that fits */ +page = bitmap_find_next_zero_area(used_mem, max_pages, 0, size_pages, + size_pages_align); + +addr = (uint64_t)page params-page_shift; +} + +if (page = max_pages || test_bit(page, used_mem) || +(find_next_bit(used_mem, max_pages, page) size_pages)) { +hw_error(Memory [%PRIx64:%PRIx64 is already allocated or + no slot left, addr, size); +} + +for (i = page; i (page + size_pages); i++) { +set_bit(i, used_mem); +} + +memory_region_add_subregion(pmem, addr, device_mem); +sbdev-mmio[n].addr = addr; +object_property_set_int(OBJECT(sbdev), addr, prop, NULL); + +g_free(prop); +return 0; +} + +static int sysbus_device_check(Object *obj, void *opaque) +{ +PlatformBusInitData *init = opaque; +Object *dev; +SysBusDevice *sbdev; +int i; + +dev = object_dynamic_cast(obj, TYPE_SYS_BUS_DEVICE); +sbdev = (SysBusDevice *)dev; + +if
[Qemu-devel] [PATCH v3 2/6] hw/arm/dyn_sysbus_devtree: helpers for sysbus device dynamic dt node generation
This module will be used by ARM machine files to generate device tree nodes of dynamically instantiated sysbus devices (ie. those instantiated with -device option). Signed-off-by: Alexander Graf ag...@suse.de Signed-off-by: Eric Auger eric.au...@linaro.org --- v2 - v3: - add arm_ prefix - arm_sysbus_device_create_devtree becomes static v1 - v2: - Code moved in an arch specific file to accomodate architecture dependent specificities. - remove platform_bus_base from PlatformDevtreeData v1: code originally written by Alex Graf in e500.c and reused for ARM [Eric Auger] code originally moved in hw/misc/platform_devices and device itself --- hw/arm/Makefile.objs| 1 + hw/arm/dyn_sysbus_devtree.c | 66 + include/hw/arm/dyn_sysbus_devtree.h | 16 + 3 files changed, 83 insertions(+) create mode 100644 hw/arm/dyn_sysbus_devtree.c create mode 100644 include/hw/arm/dyn_sysbus_devtree.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 6088e53..bc5e014 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -3,6 +3,7 @@ obj-$(CONFIG_DIGIC) += digic_boards.o obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o +obj-y += dyn_sysbus_devtree.o obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o obj-$(CONFIG_DIGIC) += digic.o diff --git a/hw/arm/dyn_sysbus_devtree.c b/hw/arm/dyn_sysbus_devtree.c new file mode 100644 index 000..6375024 --- /dev/null +++ b/hw/arm/dyn_sysbus_devtree.c @@ -0,0 +1,66 @@ +#include hw/arm/dyn_sysbus_devtree.h +#include qemu/error-report.h +#include sysemu/device_tree.h + +static int arm_sysbus_device_create_devtree(Object *obj, void *opaque) +{ +PlatformDevtreeData *data = opaque; +Object *dev; +SysBusDevice *sbdev; +bool matched = false; + +dev = object_dynamic_cast(obj, TYPE_SYS_BUS_DEVICE); +sbdev = (SysBusDevice *)dev; + +if (!sbdev) { +/* Container, traverse it for children */ +return object_child_foreach(obj, +arm_sysbus_device_create_devtree, data); +} + +if (!matched) { +error_report(Device %s is not supported by this machine yet., + qdev_fw_name(DEVICE(dev))); +exit(1); +} + +return 0; +} + +void arm_platform_bus_create_devtree(DynSysbusParams *params, + void *fdt, const char *intc) +{ +gchar *node = g_strdup_printf(/platform@%PRIx64, + params-platform_bus_base); +const char platcomp[] = qemu,platform\0simple-bus; +PlatformDevtreeData data; +Object *container; +uint64_t addr = params-platform_bus_base; +uint64_t size = params-platform_bus_size; +int irq_start = params-platform_bus_first_irq; + +/* Create a /platform node that we can put all devices into */ +qemu_fdt_add_subnode(fdt, node); +qemu_fdt_setprop(fdt, node, compatible, platcomp, sizeof(platcomp)); + +/* Our platform bus region is less than 32bit big, so 1 cell is enough for + address and size */ +qemu_fdt_setprop_cells(fdt, node, #size-cells, 1); +qemu_fdt_setprop_cells(fdt, node, #address-cells, 1); +qemu_fdt_setprop_cells(fdt, node, ranges, 0, addr 32, addr, size); + +qemu_fdt_setprop_phandle(fdt, node, interrupt-parent, intc); + +/* Loop through all devices and create nodes for known ones */ +data.fdt = fdt; +data.intc = intc; +data.irq_start = irq_start; +data.node = node; + +container = container_get(qdev_get_machine(), /peripheral); +arm_sysbus_device_create_devtree(container, data); +container = container_get(qdev_get_machine(), /peripheral-anon); +arm_sysbus_device_create_devtree(container, data); + +g_free(node); +} diff --git a/include/hw/arm/dyn_sysbus_devtree.h b/include/hw/arm/dyn_sysbus_devtree.h new file mode 100644 index 000..b072365 --- /dev/null +++ b/include/hw/arm/dyn_sysbus_devtree.h @@ -0,0 +1,16 @@ +#ifndef HW_ARM_DYN_SYSBUS_DEVTREE_H +#define HW_ARM_DYN_SYSBUS_DEVTREE_H + +#include hw/misc/dyn_sysbus_binding.h + +typedef struct PlatformDevtreeData { +void *fdt; +const char *intc; +int irq_start; +const char *node; +} PlatformDevtreeData; + +void arm_platform_bus_create_devtree(DynSysbusParams *params, +void *fdt, const char *intc); + +#endif -- 1.8.3.2
[Qemu-devel] [PATCH v3 0/6] machvirt dynamic sysbus device instantiation
This patch series enables machvirt to dynamically instantiate sysbus devices from command line (using -device option). It applies on top of Alex Graf's series - Dynamic sysbus device allocation support http://lists.gnu.org/archive/html/qemu-ppc/2014-07/msg00047.html and transposes the work done for PPC e500 on machvirt. The code related to dynamic sysbus device IRQ/mmio region binding, originally located in PPC e500.c, is moved into hw/misc/dyn_sysbus_binding new module for ARM only, the code related to device tree node generation is moved into hw/arm/dyn_sysbus_devtree module. Both e500 and machvirt are adapted to use dyn_sysbus_binding helper routines. integrated branch can be found on http://git.linaro.org/people/eric.auger/qemu.git, branch vfio_integ_v6 A related discussion can be found at https://lists.nongnu.org/archive/html/qemu-devel/2014-07/msg04065.html For e500 the device tree generation is kept in the machine file, according to Alex will. For machvirt we use dyn_sysbus_devtree since the code becomes large with the expected support of vfio devices. Best Regards Eric v2 - v3: - patch now applies on top of Alex full patchset - dyn_sysbus_devtree: add arm_prefix to emphasize the fact those functions are arm specific; arm_sysbus_device_create_devtree becomes static - load_dtb renamed into arm_load_dtb - add copyright in hw/arm/dyn_sysbus_devtree.c v1 - v2: - device node generation no more in sysbus device but in dyn_sysbus_devtree - VFIO region shrinked to 4MB and relocated in machvirt to avoid PCI shrink (dynamic vfio-mmio support might come latter) - platform_bus_base removed from PlatformDevtreeData Alexander Graf (1): PPC: e500: use dyn_sysbus_binding helper routines Eric Auger (5): hw/misc/dyn_sysbus_binding: helpers for sysbus device dynamic binding hw/arm/dyn_sysbus_devtree: helpers for sysbus device dynamic dt node generation hw/arm/boot: load_dtb becomes non static arm_load_dtb hw/arm/virt: new add_fdt_*_node functions hw/arm/virt: Support dynamically spawned sysbus devices hw/arm/Makefile.objs | 1 + hw/arm/boot.c| 4 +- hw/arm/dyn_sysbus_devtree.c | 92 ++ hw/arm/virt.c| 129 +++- hw/misc/Makefile.objs| 1 + hw/misc/dyn_sysbus_binding.c | 163 +++ hw/ppc/e500.c| 183 +++ hw/ppc/e500.h| 7 +- hw/ppc/e500plat.c| 13 ++- include/hw/arm/arm.h | 1 + include/hw/arm/dyn_sysbus_devtree.h | 16 +++ include/hw/misc/dyn_sysbus_binding.h | 24 + 12 files changed, 426 insertions(+), 208 deletions(-) create mode 100644 hw/arm/dyn_sysbus_devtree.c create mode 100644 hw/misc/dyn_sysbus_binding.c create mode 100644 include/hw/arm/dyn_sysbus_devtree.h create mode 100644 include/hw/misc/dyn_sysbus_binding.h -- 1.8.3.2
[Qemu-devel] [PATCH v3 3/6] PPC: e500: use dyn_sysbus_binding helper routines
From: Alexander Graf ag...@suse.de Now platform_bus_init_notify and functions it calls were moved to dyn_sysbus_binding.c, remove those functions from e500. PPCE500Params includes a DynSysbusParams struct which contains the settings related to platform device instantiation. Signed-off-by: Eric Auger eric.au...@linaro.org --- v2 - v3: - Modify e500.c to use platform_bus_init_notify now implemented in dyn_sysbus_binding - new DynSysbusParams that contains dynamic sysbus settings - PPCE500Params includes a DynSysbusParams struct --- hw/ppc/e500.c | 183 -- hw/ppc/e500.h | 7 +-- hw/ppc/e500plat.c | 13 ++-- 3 files changed, 22 insertions(+), 181 deletions(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index fe9497a..0741412 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -38,6 +38,7 @@ #include hw/pci-host/ppce500.h #include qemu/error-report.h #include hw/net/fsl_etsec/etsec.h +#include hw/misc/dyn_sysbus_binding.h #define EPAPR_MAGIC(0x45504150) #define BINARY_DEVICE_TREE_FILEmpc8544ds.dtb @@ -196,13 +197,14 @@ static int sysbus_device_create_devtree(Object *obj, void *opaque) static void platform_bus_create_devtree(PPCE500Params *params, void *fdt, const char *mpic) { -gchar *node = g_strdup_printf(/platform@%PRIx64, params-platform_bus_base); +gchar *node = g_strdup_printf(/platform@%PRIx64, + params-dyn_sysbus_params.platform_bus_base); const char platcomp[] = qemu,platform\0simple-bus; PlatformDevtreeData data; Object *container; -uint64_t addr = params-platform_bus_base; -uint64_t size = params-platform_bus_size; -int irq_start = params-platform_bus_first_irq; +uint64_t addr = params-dyn_sysbus_params.platform_bus_base; +uint64_t size = params-dyn_sysbus_params.platform_bus_size; +int irq_start = params-dyn_sysbus_params.platform_bus_first_irq; /* Create a /platform node that we can put all devices into */ @@ -489,7 +491,7 @@ static int ppce500_load_device_tree(MachineState *machine, qemu_fdt_setprop_cell(fdt, pci, #address-cells, 3); qemu_fdt_setprop_string(fdt, /aliases, pci0, pci); -if (params-has_platform_bus) { +if (params-dyn_sysbus_params.has_platform_bus) { platform_bus_create_devtree(params, fdt, mpic); } @@ -732,169 +734,6 @@ static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr, return mpic; } -typedef struct PlatformBusNotifier { -Notifier notifier; -MemoryRegion *address_space_mem; -qemu_irq *mpic; -PPCE500Params params; -} PlatformBusNotifier; - -typedef struct PlatformBusInitData { -unsigned long *used_irqs; -unsigned long *used_mem; -MemoryRegion *mem; -qemu_irq *irqs; -int device_count; -PPCE500Params *params; -} PlatformBusInitData; - -static int platform_bus_map_irq(PPCE500Params *params, SysBusDevice *sbdev, -int n, unsigned long *used_irqs, -qemu_irq *platform_irqs) -{ -int max_irqs = params-platform_bus_num_irqs; -char *prop = g_strdup_printf(irq[%d], n); -int irqn = object_property_get_int(OBJECT(sbdev), prop, NULL); - -if (irqn == SYSBUS_DYNAMIC) { -/* Find the first available IRQ */ -irqn = find_first_zero_bit(used_irqs, max_irqs); -} - -if ((irqn = max_irqs) || test_and_set_bit(irqn, used_irqs)) { -hw_error(e500: IRQ %d is already allocated or no free IRQ left, irqn); -} - -sysbus_connect_irq(sbdev, n, platform_irqs[irqn]); -object_property_set_int(OBJECT(sbdev), irqn, prop, NULL); - -g_free(prop); -return 0; -} - -static int platform_bus_map_mmio(PPCE500Params *params, SysBusDevice *sbdev, - int n, unsigned long *used_mem, - MemoryRegion *pmem) -{ -MemoryRegion *device_mem = sbdev-mmio[n].memory; -uint64_t size = memory_region_size(device_mem); -uint64_t page_size = (1 E500_PLATFORM_BUS_PAGE_SHIFT); -uint64_t page_mask = page_size - 1; -uint64_t size_pages = (size + page_mask) E500_PLATFORM_BUS_PAGE_SHIFT; -uint64_t max_size = params-platform_bus_size; -uint64_t max_pages = max_size E500_PLATFORM_BUS_PAGE_SHIFT; -char *prop = g_strdup_printf(mmio[%d], n); -hwaddr addr = object_property_get_int(OBJECT(sbdev), prop, NULL); -int page; -int i; - -page = addr E500_PLATFORM_BUS_PAGE_SHIFT; -if (addr == SYSBUS_DYNAMIC) { -uint64_t size_pages_align; - -/* Align the region to at least its own size granularity */ -if (is_power_of_2(size_pages)) { -size_pages_align = size_pages; -} else { -size_pages_align = pow2floor(size_pages) 1; -} - -/* Find the first available region that fits */ -page =
Re: [Qemu-devel] [PATCH v7 24/28] ide: add bootindex to qom property
Hi, Subject: RE: [Qemu-devel] [PATCH v7 24/28] ide: add bootindex to qom property Subject: Re: [Qemu-devel] [PATCH v7 24/28] ide: add bootindex to qom property On Fri, Sep 05, 2014 at 04:37:32PM +0800, arei.gong...@huawei.com wrote: From: Gonglei arei.gong...@huawei.com Add a qom property with the same name 'bootindex', when we remove it form qdev property, things will continue to work just fine, and we can use qom features which are not supported by qdev property. Signed-off-by: Gonglei arei.gong...@huawei.com --- hw/ide/qdev.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index efab95b..9e2ed40 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -191,6 +191,17 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind) return 0; } +static void ide_dev_instance_init(Object *obj) +{ +DeviceState *dev = DEVICE(obj); +IDEDevice *d = DO_UPCAST(IDEDevice, qdev, dev); + +device_add_bootindex_property(obj, d-conf.bootindex, + bootindex, + d-unit ? /disk@1 : /disk@0, + d-qdev, NULL); +} + Oops, I found a thorny issue that the d-unit parameter had not been initialized in ide_dev_instance_init(). d-unit maybe is a random value, which will against the original purpose in this situation. What's your opinion, Eduardo? Thanks! Best regards, -Gonglei
[Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5
This patch adds the stm32f205 timers: TIM2, TIM3, TIM4 and TIM5 to QEMU. Signed-off-by: Alistair Francis alistai...@gmail.com --- V2: - Small changes to functionality and style. Thanks to Peter C - Rename for the Netduino 2 and it's SoC default-configs/arm-softmmu.mak| 1 + hw/timer/Makefile.objs | 1 + hw/timer/stm32f205_timer.c | 334 + include/hw/timer/stm32f205_timer.h | 84 ++ 4 files changed, 420 insertions(+) create mode 100644 hw/timer/stm32f205_timer.c create mode 100644 include/hw/timer/stm32f205_timer.h diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index f3513fa..8550084 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -78,6 +78,7 @@ CONFIG_NSERIES=y CONFIG_REALVIEW=y CONFIG_ZAURUS=y CONFIG_ZYNQ=y +CONFIG_NETDUINO2=y CONFIG_VERSATILE_PCI=y CONFIG_VERSATILE_I2C=y diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index 2c86c3d..ce68c4a 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -17,6 +17,7 @@ common-obj-$(CONFIG_IMX) += imx_epit.o common-obj-$(CONFIG_IMX) += imx_gpt.o common-obj-$(CONFIG_LM32) += lm32_timer.o common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o +common-obj-$(CONFIG_NETDUINO2) += stm32f205_timer.o obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o obj-$(CONFIG_EXYNOS4) += exynos4210_pwm.o diff --git a/hw/timer/stm32f205_timer.c b/hw/timer/stm32f205_timer.c new file mode 100644 index 000..bbeaf6b --- /dev/null +++ b/hw/timer/stm32f205_timer.c @@ -0,0 +1,334 @@ +/* + * STM32F205xx Timer 2 to 5 + * + * Copyright (c) 2014 Alistair Francis alist...@alistair23.me + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include hw/timer/stm32f205_timer.h + +#ifndef ST_TIM2_5_ERR_DEBUG +#define ST_TIM2_5_ERR_DEBUG 0 +#endif + +#define DB_PRINT_L(lvl, fmt, args...) do { \ +if (ST_TIM2_5_ERR_DEBUG = lvl) { \ +fprintf(stderr, stm32f205xx_timer: %s: fmt, __func__, ## args); \ +} \ +} while (0); + +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args) + +static void stm32f205xx_timer_update(Stm32f205TimerState *s) +{ +s-tim_sr |= 1; +qemu_irq_pulse(s-irq); +} + +static void stm32f205xx_timer_interrupt(void *opaque) +{ +Stm32f205TimerState *s = (Stm32f205TimerState *)opaque; + +DB_PRINT(Interrupt in: %s\n, __func__); + +if (s-tim_dier == 0x01 s-tim_cr1 TIM_CR1_CEN) { +stm32f205xx_timer_update(s); +} +} + +static uint32_t stm32f205xx_timer_get_count(Stm32f205TimerState *s) +{ +int64_t now = qemu_clock_get_ns(rtc_clock); +return s-tick_offset + now / get_ticks_per_sec(); +} + +static void stm32f205xx_timer_set_alarm(Stm32f205TimerState *s) +{ +uint32_t ticks; + +DB_PRINT(Alarm raised in: %s at 0x%x\n, __func__, s-tim_cr1); + +ticks = s-tim_arr - stm32f205xx_timer_get_count(s)/ + (s-tim_psc + 1); +DB_PRINT(Alarm set in %u ticks\n, ticks); + +if (ticks == 0) { +timer_del(s-timer); +stm32f205xx_timer_interrupt(s); +} else { +int64_t now = qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec(); +timer_mod(s-timer, now + (int64_t)ticks); +DB_PRINT(Wait Time: 0x%x\n, (uint32_t) (now + ticks)); +} +} + +static void stm32f205xx_timer_reset(DeviceState *dev) +{ +struct Stm32f205TimerState *s = STM32F205xxTIMER(dev); + +s-tim_cr1 = 0; +s-tim_cr2 = 0; +s-tim_smcr = 0; +s-tim_dier = 0; +s-tim_sr = 0; +s-tim_egr = 0; +s-tim_ccmr1 = 0; +s-tim_ccmr2 = 0; +s-tim_ccer = 0; +s-tim_cnt = 0; +s-tim_psc = 0; +s-tim_arr = 0; +s-tim_ccr1 = 0; +s-tim_ccr2 = 0; +s-tim_ccr3 = 0; +s-tim_ccr4 = 0; +s-tim_dcr = 0; +s-tim_dmar = 0; +s-tim_or = 0; +} + +static uint64_t stm32f205xx_timer_read(void *opaque, hwaddr offset, + unsigned size) +{ +
[Qemu-devel] [RFC v1 2/6] stm32f205_USART: Add the stm32f205 SoC USART Controller
This patch adds the stm32f205 USART controller (UART also uses the same controller). Signed-off-by: Alistair Francis alistai...@gmail.com --- V2: - Small changes thanks to Peter C - Rename for the Netduino 2 and it's SoC hw/char/Makefile.objs | 1 + hw/char/stm32f205_usart.c | 205 ++ include/hw/char/stm32f205_usart.h | 64 3 files changed, 270 insertions(+) create mode 100644 hw/char/stm32f205_usart.c create mode 100644 include/hw/char/stm32f205_usart.h diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs index 317385d..b1f7e80 100644 --- a/hw/char/Makefile.objs +++ b/hw/char/Makefile.objs @@ -15,6 +15,7 @@ obj-$(CONFIG_OMAP) += omap_uart.o obj-$(CONFIG_SH4) += sh_serial.o obj-$(CONFIG_PSERIES) += spapr_vty.o obj-$(CONFIG_DIGIC) += digic-uart.o +obj-$(CONFIG_NETDUINO2) += stm32f205_usart.o common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o diff --git a/hw/char/stm32f205_usart.c b/hw/char/stm32f205_usart.c new file mode 100644 index 000..c042b4b --- /dev/null +++ b/hw/char/stm32f205_usart.c @@ -0,0 +1,205 @@ +/* + * STM32F205xx USART + * + * Copyright (c) 2014 Alistair Francis alist...@alistair23.me + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include hw/char/stm32f205_usart.h + +#ifndef STM_USART_ERR_DEBUG +#define STM_USART_ERR_DEBUG 0 +#endif + +#define DB_PRINT_L(lvl, fmt, args...) do { \ +if (STM_USART_ERR_DEBUG = lvl) { \ +fprintf(stderr, stm32f205xx_usart: %s: fmt, __func__, ## args); \ +} \ +} while (0); + +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args) + +static int usart_can_receive(void *opaque) +{ +Stm32f205UsartState *s = opaque; + +if (s-usart_cr1 USART_CR1_UE s-usart_cr1 USART_CR1_TE) { +return 1; +} + +return 0; +} + +static void usart_receive(void *opaque, const uint8_t *buf, int size) +{ +Stm32f205UsartState *s = opaque; + +s-usart_dr = *buf; + +s-usart_sr |= USART_SR_RXNE; + +if (s-usart_cr1 USART_CR1_RXNEIE) { +qemu_set_irq(s-irq, 1); +} + +DB_PRINT(Receiving: %c\n, s-usart_dr); +} + +static void usart_reset(DeviceState *dev) +{ +Stm32f205UsartState *s = STM32F205xx_USART(dev); + +s-usart_sr = 0x00C0; +s-usart_dr = 0x; +s-usart_brr = 0x; +s-usart_cr1 = 0x; +s-usart_cr2 = 0x; +s-usart_cr3 = 0x; +s-usart_gtpr = 0x; +} + +static uint64_t stm32f205xx_usart_read(void *opaque, hwaddr addr, +unsigned int size) +{ +Stm32f205UsartState *s = opaque; +uint64_t retvalue; + +DB_PRINT(Read 0x%x\n, (uint) addr); + +switch (addr) { +case USART_SR: +retvalue = s-usart_sr; +s-usart_sr = (USART_SR_TC ^ 0x); +return retvalue; +case USART_DR: +DB_PRINT(Value: 0x%x, %c\n, s-usart_dr, (char) s-usart_dr); +s-usart_sr |= USART_SR_TXE; +return s-usart_dr 0x3FF; +case USART_BRR: +return s-usart_brr; +case USART_CR1: +return s-usart_cr1; +case USART_CR2: +return s-usart_cr2; +case USART_CR3: +return s-usart_cr3; +case USART_GTPR: +return s-usart_gtpr; +default: +qemu_log_mask(LOG_GUEST_ERROR, + STM32F205xx_usart_read: Bad offset %x\n, (int)addr); +return 0; +} + +return 0; +} + +static void stm32f205xx_usart_write(void *opaque, hwaddr addr, + uint64_t val64, unsigned int size) +{ +Stm32f205UsartState *s = opaque; +uint32_t value = (uint32_t) val64; +unsigned char ch; + +DB_PRINT(Write 0x%x, 0x%x\n, value, (uint) addr); + +switch (addr) { +case USART_SR: +if (value = 0x3FF) { +s-usart_sr = value; +} else { +s-usart_sr = value; +} +return; +case USART_DR:
[Qemu-devel] [RFC v1 3/6] stm32f205_SYSCFG: Add the stm32f205 SYSCFG
This patch adds the stm32f205 System Configuration Controller. This is used to configure what memory is mapped at address 0 (although that is not supported) as well as configure how the EXTI interrupts work (also not supported at the moment). This device is not required for basic examples, but more complex systems will require it (as well as the EXTI device) Signed-off-by: Alistair Francis alistai...@gmail.com --- V2: - Update the commit message - Small changes thanks to Peter C - Rename for the Netduino 2 and it's SoC hw/misc/Makefile.objs | 1 + hw/misc/stm32f205_syscfg.c | 160 + include/hw/misc/stm32f205_syscfg.h | 59 ++ 3 files changed, 220 insertions(+) create mode 100644 hw/misc/stm32f205_syscfg.c create mode 100644 include/hw/misc/stm32f205_syscfg.h diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 979e532..83a7703 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -39,5 +39,6 @@ obj-$(CONFIG_OMAP) += omap_sdrc.o obj-$(CONFIG_OMAP) += omap_tap.o obj-$(CONFIG_SLAVIO) += slavio_misc.o obj-$(CONFIG_ZYNQ) += zynq_slcr.o +obj-$(CONFIG_NETDUINO2) += stm32f205_syscfg.o obj-$(CONFIG_PVPANIC) += pvpanic.o diff --git a/hw/misc/stm32f205_syscfg.c b/hw/misc/stm32f205_syscfg.c new file mode 100644 index 000..226bf74 --- /dev/null +++ b/hw/misc/stm32f205_syscfg.c @@ -0,0 +1,160 @@ +/* + * STM32F205xx SYSCFG + * + * Copyright (c) 2014 Alistair Francis alist...@alistair23.me + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include hw/misc/stm32f205_syscfg.h + +#ifndef STM_SYSCFG_ERR_DEBUG +#define STM_SYSCFG_ERR_DEBUG 1 +#endif + +#define DB_PRINT_L(lvl, fmt, args...) do { \ +if (STM_SYSCFG_ERR_DEBUG = lvl) { \ +fprintf(stderr, stm32f205xx_syscfg: %s: fmt, __func__, ## args); \ +} \ +} while (0); + +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args) + +static void syscfg_reset(DeviceState *dev) +{ +Stm32f205SyscfgState *s = STM32F205xx_SYSCFG(dev); + +s-syscfg_memrmp = 0x; +s-syscfg_pmc = 0x; +s-syscfg_exticr1 = 0x; +s-syscfg_exticr2 = 0x; +s-syscfg_exticr3 = 0x; +s-syscfg_exticr4 = 0x; +s-syscfg_cmpcr = 0x; +} + +static uint64_t stm32f205xx_syscfg_read(void *opaque, hwaddr addr, + unsigned int size) +{ +Stm32f205SyscfgState *s = opaque; + +DB_PRINT(0x%x\n, (uint) addr); + +switch (addr) { +case SYSCFG_MEMRMP: +return s-syscfg_memrmp; +case SYSCFG_PMC: +return s-syscfg_pmc; +case SYSCFG_EXTICR1: +return s-syscfg_exticr1; +case SYSCFG_EXTICR2: +return s-syscfg_exticr2; +case SYSCFG_EXTICR3: +return s-syscfg_exticr3; +case SYSCFG_EXTICR4: +return s-syscfg_exticr4; +case SYSCFG_CMPCR: +return s-syscfg_cmpcr; +default: +qemu_log_mask(LOG_GUEST_ERROR, + STM32F205xx_syscfg_read: Bad offset %x\n, (int)addr); +return 0; +} + +return 0; +} + +static void stm32f205xx_syscfg_write(void *opaque, hwaddr addr, + uint64_t val64, unsigned int size) +{ +Stm32f205SyscfgState *s = opaque; +uint32_t value = (uint32_t) val64; + +DB_PRINT(0x%x, 0x%x\n, value, (uint) addr); + +switch (addr) { +case SYSCFG_MEMRMP: +qemu_log_mask(LOG_UNIMP, + STM32F205xx_syscfg_write: Changeing the memory \ + mapping isn't supported in QEMU\n); +return; +case SYSCFG_PMC: +qemu_log_mask(LOG_UNIMP, + STM32F205xx_syscfg_write: Peripheral mode \ + configuration isn't supported in QEMU\n); +return; +case SYSCFG_EXTICR1: +s-syscfg_exticr1 = (value 0xFF); +return; +case SYSCFG_EXTICR2: +s-syscfg_exticr2 = (value 0xFF); +
[Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters
This patch is a hack This patch makes the smallest number of changes possible to extend armv7m_init() so that it can be used to init the Netduino 2. Signed-off-by: Alistair Francis alistai...@gmail.com --- I understand that this is probably not the way that everyone would like this done. What I do want to know though, is what the prefered method for extending this function would be? I am expecting that it will have to be a QOM device that can be attached. hw/arm/armv7m.c | 33 ++--- hw/arm/stellaris.c | 2 +- include/hw/arm/arm.h | 3 ++- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index aedef13..e4f7d8c 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -155,11 +155,21 @@ static void armv7m_bitband_init(void) /* Board init. */ +typedef struct ARMV7MResetArgs { +ARMCPU *cpu; +uint32_t reset_sp; +uint32_t reset_pc; +} ARMV7MResetArgs; + static void armv7m_reset(void *opaque) { -ARMCPU *cpu = opaque; +ARMV7MResetArgs *args = opaque; + +cpu_reset(CPU(args-cpu)); -cpu_reset(CPU(cpu)); +args-cpu-env.regs[13] = args-reset_sp 0xFFFC; +args-cpu-env.thumb = args-reset_pc 1; +args-cpu-env.regs[15] = args-reset_pc ~1; } /* Init CPU and memory for a v7-M based board. @@ -167,14 +177,15 @@ static void armv7m_reset(void *opaque) Returns the NVIC array. */ qemu_irq *armv7m_init(MemoryRegion *system_memory, - int flash_size, int sram_size, + int flash_size, uint64_t flash_base, + int sram_size, int num_irq, const char *kernel_filename, const char *cpu_model) { ARMCPU *cpu; CPUARMState *env; DeviceState *nvic; /* FIXME: make this local state. */ -static qemu_irq pic[64]; +qemu_irq *pic = g_new(qemu_irq, num_irq); int image_size; uint64_t entry; uint64_t lowaddr; @@ -183,6 +194,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, MemoryRegion *sram = g_new(MemoryRegion, 1); MemoryRegion *flash = g_new(MemoryRegion, 1); MemoryRegion *hack = g_new(MemoryRegion, 1); +ARMV7MResetArgs reset_args; flash_size *= 1024; sram_size *= 1024; @@ -213,18 +225,19 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, memory_region_init_ram(flash, NULL, armv7m.flash, flash_size); vmstate_register_ram_global(flash); memory_region_set_readonly(flash, true); -memory_region_add_subregion(system_memory, 0, flash); +memory_region_add_subregion(system_memory, flash_base, flash); memory_region_init_ram(sram, NULL, armv7m.sram, sram_size); vmstate_register_ram_global(sram); memory_region_add_subregion(system_memory, 0x2000, sram); armv7m_bitband_init(); nvic = qdev_create(NULL, armv7m_nvic); +qdev_prop_set_uint32(nvic, num-irq, num_irq); env-nvic = nvic; qdev_init_nofail(nvic); sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0, qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ)); -for (i = 0; i 64; i++) { +for (i = 0; i num_irq; i++) { pic[i] = qdev_get_gpio_in(nvic, i); } @@ -259,7 +272,13 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, vmstate_register_ram_global(hack); memory_region_add_subregion(system_memory, 0xf000, hack); -qemu_register_reset(armv7m_reset, cpu); +reset_args = (ARMV7MResetArgs) { +.cpu = cpu, +.reset_pc = entry, +.reset_sp = (0x2000 + ((192 * 1024) * 2)/3), +}; +qemu_register_reset(armv7m_reset, +g_memdup(reset_args, sizeof(reset_args))); return pic; } diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index 64bd4b4..41dc712 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -1223,7 +1223,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, flash_size = ((board-dc0 0x) + 1) 1; sram_size = (board-dc0 18) + 1; pic = armv7m_init(get_system_memory(), - flash_size, sram_size, kernel_filename, cpu_model); + flash_size, 0, sram_size, 64, kernel_filename, cpu_model); if (board-dc1 (1 16)) { dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000, diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h index cefc9e6..72f0266 100644 --- a/include/hw/arm/arm.h +++ b/include/hw/arm/arm.h @@ -16,7 +16,8 @@ /* armv7m.c */ qemu_irq *armv7m_init(MemoryRegion *system_memory, - int flash_size, int sram_size, + int flash_size, uint64_t flash_base, + int sram_size, int num_irq, const char *kernel_filename, const char *cpu_model); /* arm_boot.c */ -- 1.9.1
[Qemu-devel] [RFC v1 5/6] stm32f205: Add the SoC
This patch adds the stm32f205 SoC. This will be used by the Netduino 2 to create a machine Signed-off-by: Alistair Francis alistai...@gmail.com --- hw/arm/Makefile.objs | 2 +- hw/arm/stm32f205_soc.c | 140 + include/hw/arm/stm32f205_soc.h | 61 ++ 3 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 hw/arm/stm32f205_soc.c create mode 100644 include/hw/arm/stm32f205_soc.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 6088e53..673feef 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -2,7 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o obj-$(CONFIG_DIGIC) += digic_boards.o obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o -obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o +obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o stm32f205_soc.o obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o obj-$(CONFIG_DIGIC) += digic.o diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c new file mode 100644 index 000..da36f61 --- /dev/null +++ b/hw/arm/stm32f205_soc.c @@ -0,0 +1,140 @@ +/* + * STM32F205xx SoC + * + * Copyright (c) 2014 Alistair Francis alist...@alistair23.me + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include hw/arm/stm32f205_soc.h + +#define FLASH_BASE_ADDRESS 0x0800 +#define FLASH_SIZE 1024 +#define SRAM_BASE_ADDRESS 0x2000 +#define SRAM_SIZE 192 + +static void stm32f205_soc_initfn(Object *obj) +{ +STM32F205State *s = STM32F205_SOC(obj); +int i; + +object_initialize(s-syscfg, sizeof(s-syscfg), TYPE_STM32F205_SYSCFG); +qdev_set_parent_bus(DEVICE(s-syscfg), sysbus_get_default()); + +for (i = 0; i 5; i++) { +object_initialize(s-usart[i], sizeof(s-usart[i]), + TYPE_STM32F205_USART); +qdev_set_parent_bus(DEVICE(s-usart[i]), sysbus_get_default()); +} + +for (i = 0; i 4; i++) { +object_initialize(s-timer[i], sizeof(s-timer[i]), + TYPE_STM32F205_TIMER); +qdev_set_parent_bus(DEVICE(s-timer[i]), sysbus_get_default()); +} +} + +static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) +{ +static const uint32_t timer_addr[] = { 0x4000, 0x4400, +0x4800, 0x4C00 }; +static const uint32_t usart_addr[] = { 0x40011000, 0x40004400, +0x40004800, 0x40004C00, 0x40005000, 0x40011400 }; + +static const int timer_irq[] = {28, 29, 30, 50}; +static const int usart_irq[] = {37, 38, 39, 52, 53, 71, 82, 83}; + +STM32F205State *s = STM32F205_SOC(dev_soc); +DeviceState *syscfgdev, *usartdev, *timerdev; +SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev; +qemu_irq *pic;; +Error *err = NULL; +int i; + +pic = armv7m_init(get_system_memory(), + FLASH_SIZE, FLASH_BASE_ADDRESS, SRAM_SIZE, 96, + s-kernel_filename, s-cpu_model); + +/* System configuration controller */ +syscfgdev = DEVICE(s-syscfg); +syscfgdev-id = stm32f205xx-syscfg; +object_property_set_bool(OBJECT(s-syscfg), true, realized, err); +if (err != NULL) { +error_propagate(errp, err); +return; +} +syscfgbusdev = SYS_BUS_DEVICE(syscfgdev); +sysbus_mmio_map(syscfgbusdev, 0, 0x40013800); +sysbus_connect_irq(syscfgbusdev, 0, pic[71]); + +/* Attach a UART (uses USART registers) and USART controllers */ +for (i = 0; i 5; i++) { +usartdev = DEVICE((s-usart[i])); +object_property_set_bool(OBJECT(s-usart[i]), true, realized, err); +if (err != NULL) { +error_propagate(errp, err); +return; +} +usartbusdev = SYS_BUS_DEVICE(usartdev); +sysbus_mmio_map(usartbusdev, 0, usart_addr[i]); +
Re: [Qemu-devel] [PATCH] block: extend BLOCK_IO_ERROR event with nospace indicator
Am 08.09.2014 um 18:57 hat Luiz Capitulino geschrieben: On Mon, 8 Sep 2014 17:33:18 +0200 Kevin Wolf kw...@redhat.com wrote: Am 08.09.2014 um 16:42 hat Luiz Capitulino geschrieben: On Fri, 29 Aug 2014 16:07:27 -0400 Luiz Capitulino lcapitul...@redhat.com wrote: Management software, such as RHEV's vdsm, want to be able to allocate disk space on demand. The basic use case is to start a VM with a small disk and then the disk is enlarged when QEMU hits a ENOSPC condition. To this end, the management software has to be notified when QEMU encounters ENOSPC. The solution implemented by this commit is simple: it extends the BLOCK_IO_ERROR with a 'nospace' key, which is true when QEMU is stopped due to ENOSPC. Note that support for querying this event is already present in query-block by means of the 'io-status' key. Also, the new 'nospace' BLOCK_IO_ERROR field shares the same semantics with 'io-status', which basically means that werror= has to be set to either 'stop' or 'enospc' to enable 'nospace'. Finally, this commit also updates the 'io-status' key doc in the schema with a list of supported device models. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com Kevin, are you going to take this via block layer tree? Yes, thanks, I've applied it now. What was our conclusion wrt the human-readable strerror() string for debugging? Didn't we want to add that as well? I can do it on top of this patch. So, just adding a new field for this is fine? I think so. Perhaps we should give it an 'x-' name to make clear that it's a debugging help and not supposed to be parsed by management tools. Or would that be abuse of that namespace? The alternative solution (or actually we could do both) would be to store it somewhere in bs and put it into query-block. Kevin
[Qemu-devel] [RFC v1 6/6] netduino2: Add the Netduino 2 Machine
This patch adds the Netduino 2 Machine. This is a Cortex-M3 based machine. Information can be found at: http://www.netduino.com/netduino2/specs.htm Signed-off-by: Alistair Francis alistai...@gmail.com --- hw/arm/Makefile.objs | 2 +- hw/arm/netduino2.c | 60 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 hw/arm/netduino2.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 673feef..eb12353 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -2,7 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o obj-$(CONFIG_DIGIC) += digic_boards.o obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o -obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o stm32f205_soc.o +obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o netduino2.o stm32f205_soc.o obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o obj-$(CONFIG_DIGIC) += digic.o diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c new file mode 100644 index 000..08101db --- /dev/null +++ b/hw/arm/netduino2.c @@ -0,0 +1,60 @@ +/* + * Netduino 2 Machine Model + * + * Copyright (c) 2014 Alistair Francis alist...@alistair23.me + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include hw/arm/stm32f205_soc.h + +static void netduino2_init(MachineState *machine) +{ +DeviceState *dev; +const char *cpu_model = machine-cpu_model; +Error *err = NULL; + +if (!cpu_model) { +cpu_model = cortex-m3; +} + +dev = qdev_create(NULL, TYPE_STM32F205_SOC); +if (machine-kernel_filename) { +qdev_prop_set_string(dev, kernel-filename, machine-kernel_filename); +} +qdev_prop_set_string(dev, cpu-model, cpu_model); +object_property_set_bool(OBJECT(dev), true, realized, err); +if (err != NULL) { +error_report(%s, error_get_pretty(err)); +exit(1); +} +} + +static QEMUMachine netduino2_machine = { +.name = netduino2, +.desc = Netduino 2 Machine, +.init = netduino2_init, +}; + +static void netduino2_machine_init(void) +{ +qemu_register_machine(netduino2_machine); +} + +machine_init(netduino2_machine_init); -- 1.9.1
Re: [Qemu-devel] [PATCH 0/4] Block-related miscellaneous cleanups
Am 08.09.2014 um 18:50 hat Markus Armbruster geschrieben: Random crap I ran into while working on a bigger task. Markus Armbruster (4): qemu-io: Clean up openfile() after commit 2e40134 xen_disk: Plug memory leak on error path xen: Drop redundant bdrv_close() from pci_piix3_xen_ide_unplug() thread-pool: Drop unnecessary includes Thanks, applied all to the block branch. Kevin
Re: [Qemu-devel] [PATCH] IDE: MMIO IDE device control should be little endian
Am 31.08.2014 um 10:32 hat Valentin Manea geschrieben: Set the IDE MMIO memory type to little endian. The ATA specs identify words part of the control commands encoded as little endian. While this has no impact on little endian systems, it's required for big endian systems(eg OpenRisc). Signed-off-by: Valentin Manea valentin.ma...@gmail.com Thanks, applied to the block branch. static uint64_t mmio_ide_status_read(void *opaque, hwaddr addr, @@ -102,7 +102,7 @@ static void mmio_ide_cmd_write(void *opaque, hwaddr addr, Please make sure that your patch isn't corrupted by your mail client, like by this line wrap. I had to manually fix the patch before I could apply it. For larger patches, I would simply have rejected it. Kevin
Re: [Qemu-devel] [PATCH v2] Support vhd type VHD_DIFFERENCING
Hello, I'm no qemu-devel expert, but as I tried myself at adding VHD_DIFF support some time ago, here are some comments: On 08.09.2014 16:41, Xiaodong Gong wrote: diff --git a/block/vpc.c b/block/vpc.c ... +/* Read backing file location from dyn header table */ +if (dyndisk_header-parent_name[0] || dyndisk_header-parent_name[1]) { +for (i = 0; i PARENT_LOCATOR_NUM; i++) { ... +if (MACX == platform) { Most images I have luckily have the MACX entry, but from reading the spec I think this is not guaranteed. What about the other more Windows-agnostic types? There's also dyndisk_header-parent_name (which uses UTF-16-BE). +ret = bdrv_pread(bs-file, data_offset + PARENT_PREFIX_LEN, +bs-backing_file, data_length - PARENT_PREFIX_LEN); You assume that the system locale is UTF-8 (which MACX uses as the encoding). I don't know how QEMU handles that internally, but AFAIK for correctness you would need to convert that from UTF-8 to $LC_CTYPE. Using iconv() is currently is not possible, since it requires calling setlocale() to be called from all main programs using that code. static int vpc_write(BlockDriverState *bs, int64_t sector_num, ... +bool isdiff = true; ... +if (true == isdiff) { if (isdiff) { is enough - no need to add any confusing ==true IMHO. Other notes: - Using backing files requires CONFIG_UUID. I once created a VHD file using qemu-img, which set UUID:=0. This lead to Xen handling the image as a raw-file instead of a vhd file instead. Otherwise thank you for working on VHD support. Sincerely Philipp
[Qemu-devel] [TRIVIAL][PATCH] libqos virtio: Increase ISR timeout
Signed-off-by: Marc Marí marc.mari.barc...@gmail.com --- tests/libqos/virtio.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c index 128dbd0..9b6de2c 100644 --- a/tests/libqos/virtio.c +++ b/tests/libqos/virtio.c @@ -82,7 +82,7 @@ bool qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq, uint64_t timeout) { do { -clock_step(10); +clock_step(100); if (bus-get_queue_isr_status(d, vq)) { break; /* It has ended */ } @@ -95,7 +95,7 @@ bool qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d, uint64_t timeout) { do { -clock_step(10); +clock_step(100); if (bus-get_config_isr_status(d)) { break; /* It has ended */ } -- 1.7.10.4
Re: [Qemu-devel] [PATCH 0/4] Extract block accounting statistic code in it's own module
Am 05.09.2014 um 15:46 hat Benoît Canet geschrieben: With the need to add new statistics it's better to modularize asap the I/O block accounting code. This series takes care of extracting this code and making it independant of the BlockDriverState structure. Compile tested and basically runtime tested excepted for the xen_disk.c backend. Best regards Benoît Benoît Canet (4): block: Extract the BlockAcctStats structure block: Extract the block accounting code block: rename BlockAcctType members to start with BLOCK_ instead of BDRV_ block: Make the block accounting functions operate on BlockAcctStats Thanks, applied all to the block branch. By the way, I was only CCed on the patches, but not on the cover letter. Can you please make sure to explicitly CC me for the whole series so I won't miss comments and can easier reply to the whole series? Kevin
[Qemu-devel] [PATCH 1/1] xhci PCIe endpoint migration compatibility fix
From: Dr. David Alan Gilbert dgilb...@redhat.com Add back the PCIe config capabilities on XHCI cards in non-PCIe slots, but only for machine types before 2.1. This fixes a migration incompatibility in the XHCI PCI devices caused by: 058fdcf52cdbf57b67e7 - xhci: add endpoint cap on express bus only Note that in fixing it for compatibility with older QEMUs, it breaks compatibility with existing QEMU 2.1's on older machine types. The status before this patch was (if it used an XHCI adapter): machine type | source qemu any pre-2.1 - FAIL any 2.1... - PASS With this patch: machine type | source qemu any pre-2.1- PASS pre-2.1 2.1... - FAIL 2.1 2.1... - PASS A test to trigger it is to add '-device nec-usb-xhci,id=xhci,addr=0x12' to the command line. Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com --- hw/usb/hcd-xhci.c| 6 +- include/hw/i386/pc.h | 5 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index bbe4c5f..73ced1f 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -499,6 +499,7 @@ enum xhci_flags { XHCI_FLAG_USE_MSI = 1, XHCI_FLAG_USE_MSI_X, XHCI_FLAG_SS_FIRST, +XHCI_FLAG_FORCE_PCIE_ENDCAP, }; static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, @@ -3626,7 +3627,8 @@ static int usb_xhci_initfn(struct PCIDevice *dev) PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64, xhci-mem); -if (pci_bus_is_express(dev-bus)) { +if (pci_bus_is_express(dev-bus) || +xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) { ret = pcie_endpoint_cap_init(dev, 0xa0); assert(ret = 0); } @@ -3855,6 +3857,8 @@ static Property xhci_properties[] = { DEFINE_PROP_BIT(msix, XHCIState, flags, XHCI_FLAG_USE_MSI_X, true), DEFINE_PROP_BIT(superspeed-ports-first, XHCIState, flags, XHCI_FLAG_SS_FIRST, true), +DEFINE_PROP_BIT(force-pcie-endcap, XHCIState, flags, +XHCI_FLAG_FORCE_PCIE_ENDCAP, false), DEFINE_PROP_UINT32(intrs, XHCIState, numintrs, MAXINTRS), DEFINE_PROP_UINT32(slots, XHCIState, numslots, MAXSLOTS), DEFINE_PROP_UINT32(p2,XHCIState, numports_2, 4), diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index a39cb42..77316d5 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -330,6 +330,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .value= off,\ },\ {\ +.driver = nec-usb-xhci,\ +.property = force-pcie-endcap,\ +.value= on,\ +},\ +{\ .driver = pci-serial,\ .property = prog_if,\ .value= stringify(0),\ -- 1.9.3
Re: [Qemu-devel] [PATCH 06/12] kvmvapic: fixing loading vmstate
From: Paolo Bonzini [mailto:pbonz...@redhat.com] Il 27/08/2014 15:03, Pavel Dovgaluk ha scritto: Hmm, probably not. The bug would not be other timers accessing the APIC, because that would also call apic_sync_vapic and the only effect would be an extra useless synchronization. The bug would happen if the APIC is accessed by the CPU before the timer has the occasion to run. Sorry, but I don't understand which problem we will solve with apic_sync_vapic. Taking inspiration from what KVM does, the fix could be even simpler than a change state handler. run_on_cpu functions do not run while the VM is stopped, so the following should work: diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index ce3d903..81d1ad7 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -91,13 +91,20 @@ void apic_enable_tpr_access_reporting(DeviceState *dev, bool enable) } } +static void do_apic_enable_vapic(void *data) +{ +APICCommonState *s = APIC_COMMON(data); +APICCommonClass *info = APIC_COMMON_GET_CLASS(s); + +info-vapic_base_update(s); +} + void apic_enable_vapic(DeviceState *dev, hwaddr paddr) { APICCommonState *s = APIC_COMMON(dev); -APICCommonClass *info = APIC_COMMON_GET_CLASS(s); s-vapic_paddr = paddr; -info-vapic_base_update(s); +run_on_cpu(CPU(s-cpu), do_apic_enable_vapic, s); } I've tried this one and it doesn't work. do_apic_enable_vapic runs on cpu, at the same time the VM state is loaded. APIC state still remains broken because of this. Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH 0/4] Extract block accounting statistic code in it's own module
On Tue, Sep 09, 2014 at 11:56:28AM +0200, Kevin Wolf wrote: Am 05.09.2014 um 15:46 hat Benoît Canet geschrieben: With the need to add new statistics it's better to modularize asap the I/O block accounting code. This series takes care of extracting this code and making it independant of the BlockDriverState structure. Compile tested and basically runtime tested excepted for the xen_disk.c backend. Best regards Benoît Benoît Canet (4): block: Extract the BlockAcctStats structure block: Extract the block accounting code block: rename BlockAcctType members to start with BLOCK_ instead of BDRV_ block: Make the block accounting functions operate on BlockAcctStats Thanks, applied all to the block branch. Thanks, By the way, I was only CCed on the patches, but not on the cover letter. Can you please make sure to explicitly CC me for the whole series so I won't miss comments and can easier reply to the whole series? Yes sure, Kevin
Re: [Qemu-devel] [PATCH v3 1/6] hw/misc/dyn_sysbus_binding: helpers for sysbus device dynamic binding
Il 09/09/2014 09:54, Eric Auger ha scritto: This new module implements routines which help in dynamic device binding (mmio regions, irq). They are supposed to be used by machine files that support dynamic sysbus instantiation. Signed-off-by: Alexander Graf ag...@suse.de Signed-off-by: Eric Auger eric.au...@linaro.org --- v1 - v2: - platform_devices renamed into dyn_sysbus_binding Please use dynamic instead of dyn. - PlatformParams renamed into DynSysbusParams - PlatformBusNotifier renamed into DynSysbusNotifier - platform_bus_map_irq, platform_bus_map_mmio, sysbus_device_check, platform_bus_init become static - PlatformBusInitData becomes private to the module - page_shift becomes a member of DynSysbusParams v1: Dynamic sysbus device allocation fully written by Alex Graf. Those functions were initially in ppc e500 machine file. Now moved to a separate module. PPCE500Params is replaced by a generic struct named PlatformParams --- hw/misc/Makefile.objs| 1 + hw/misc/dyn_sysbus_binding.c | 163 +++ Please put these in hw/core/sysbus.c and include/hw/sysbus.h, and rename everything called Platform or platform_ to Sysbus or sysbus_. +void platform_bus_init_notify(Notifier *notifier, void *data) +{ +DynSysbusNotifier *pn = (DynSysbusNotifier *)notifier; +platform_bus_init(pn-params, pn-address_space_mem, pn-mpic); +} Please provide a wrapper like sysbus_register_dynamic that takes the params/address_space_mem/mpic as parameter. platform_bus_init_notify and DynSysbusNotifier can remain hidden within the .c file. Also, why not move the address_space_mem and mpic into the parameters struct? Paolo include/hw/misc/dyn_sysbus_binding.h | 24 ++ 3 files changed, 188 insertions(+) create mode 100644 hw/misc/dyn_sysbus_binding.c create mode 100644 include/hw/misc/dyn_sysbus_binding.h diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 979e532..86f6243 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -41,3 +41,4 @@ obj-$(CONFIG_SLAVIO) += slavio_misc.o obj-$(CONFIG_ZYNQ) += zynq_slcr.o obj-$(CONFIG_PVPANIC) += pvpanic.o +obj-y += dyn_sysbus_binding.o diff --git a/hw/misc/dyn_sysbus_binding.c b/hw/misc/dyn_sysbus_binding.c new file mode 100644 index 000..0f34f0b --- /dev/null +++ b/hw/misc/dyn_sysbus_binding.c @@ -0,0 +1,163 @@ +#include hw/misc/dyn_sysbus_binding.h +#include qemu/error-report.h + +typedef struct PlatformBusInitData { +unsigned long *used_irqs; +unsigned long *used_mem; +MemoryRegion *mem; +qemu_irq *irqs; +int device_count; +DynSysbusParams *params; +} PlatformBusInitData; + + +static int platform_bus_map_irq(DynSysbusParams *params, +SysBusDevice *sbdev, +int n, unsigned long *used_irqs, +qemu_irq *platform_irqs) +{ +int max_irqs = params-platform_bus_num_irqs; +char *prop = g_strdup_printf(irq[%d], n); +int irqn = object_property_get_int(OBJECT(sbdev), prop, NULL); + +if (irqn == SYSBUS_DYNAMIC) { +/* Find the first available IRQ */ +irqn = find_first_zero_bit(used_irqs, max_irqs); +} + +if ((irqn = max_irqs) || test_and_set_bit(irqn, used_irqs)) { +hw_error(IRQ %d is already allocated or no free IRQ left, irqn); +} + +sysbus_connect_irq(sbdev, n, platform_irqs[irqn]); +object_property_set_int(OBJECT(sbdev), irqn, prop, NULL); + +g_free(prop); +return 0; +} + +static int platform_bus_map_mmio(DynSysbusParams *params, + SysBusDevice *sbdev, + int n, unsigned long *used_mem, + MemoryRegion *pmem) +{ +MemoryRegion *device_mem = sbdev-mmio[n].memory; +uint64_t size = memory_region_size(device_mem); +uint64_t page_size = (1 params-page_shift); +uint64_t page_mask = page_size - 1; +uint64_t size_pages = (size + page_mask) params-page_shift; +uint64_t max_size = params-platform_bus_size; +uint64_t max_pages = max_size params-page_shift; +char *prop = g_strdup_printf(mmio[%d], n); +hwaddr addr = object_property_get_int(OBJECT(sbdev), prop, NULL); +int page; +int i; + +page = addr params-page_shift; +if (addr == SYSBUS_DYNAMIC) { +uint64_t size_pages_align; + +/* Align the region to at least its own size granularity */ +if (is_power_of_2(size_pages)) { +size_pages_align = size_pages; +} else { +size_pages_align = pow2floor(size_pages) 1; +} + +/* Find the first available region that fits */ +page = bitmap_find_next_zero_area(used_mem, max_pages, 0, size_pages, + size_pages_align); + +addr =
Re: [Qemu-devel] [PATCH v3 2/6] hw/arm/dyn_sysbus_devtree: helpers for sysbus device dynamic dt node generation
Il 09/09/2014 09:54, Eric Auger ha scritto: This module will be used by ARM machine files to generate device tree nodes of dynamically instantiated sysbus devices (ie. those instantiated with -device option). Signed-off-by: Alexander Graf ag...@suse.de Signed-off-by: Eric Auger eric.au...@linaro.org --- v2 - v3: - add arm_ prefix - arm_sysbus_device_create_devtree becomes static v1 - v2: - Code moved in an arch specific file to accomodate architecture dependent specificities. - remove platform_bus_base from PlatformDevtreeData v1: code originally written by Alex Graf in e500.c and reused for ARM [Eric Auger] code originally moved in hw/misc/platform_devices and device itself --- hw/arm/Makefile.objs| 1 + hw/arm/dyn_sysbus_devtree.c | 66 + File names in QEMU typically use a dash instead of an underscore. Also, I see the fdt moniker used more often than devtree (ouch, I checked now and it's 7 vs. 851 uses :)). So what about hw/arm/sysbus-fdt.c? include/hw/arm/dyn_sysbus_devtree.h | 16 + 3 files changed, 83 insertions(+) create mode 100644 hw/arm/dyn_sysbus_devtree.c create mode 100644 include/hw/arm/dyn_sysbus_devtree.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 6088e53..bc5e014 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -3,6 +3,7 @@ obj-$(CONFIG_DIGIC) += digic_boards.o obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o +obj-y += dyn_sysbus_devtree.o obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o obj-$(CONFIG_DIGIC) += digic.o diff --git a/hw/arm/dyn_sysbus_devtree.c b/hw/arm/dyn_sysbus_devtree.c new file mode 100644 index 000..6375024 --- /dev/null +++ b/hw/arm/dyn_sysbus_devtree.c @@ -0,0 +1,66 @@ +#include hw/arm/dyn_sysbus_devtree.h +#include qemu/error-report.h +#include sysemu/device_tree.h + +static int arm_sysbus_device_create_devtree(Object *obj, void *opaque) +{ +PlatformDevtreeData *data = opaque; +Object *dev; +SysBusDevice *sbdev; +bool matched = false; + +dev = object_dynamic_cast(obj, TYPE_SYS_BUS_DEVICE); +sbdev = (SysBusDevice *)dev; + +if (!sbdev) { +/* Container, traverse it for children */ +return object_child_foreach(obj, +arm_sysbus_device_create_devtree, data); +} + +if (!matched) { Who is going to set matched, since it doesn't escape? +error_report(Device %s is not supported by this machine yet., + qdev_fw_name(DEVICE(dev))); +exit(1); +} + +return 0; +} + +void arm_platform_bus_create_devtree(DynSysbusParams *params, + void *fdt, const char *intc) Let's just call this arm_create_fdt_dynamic. +{ +gchar *node = g_strdup_printf(/platform@%PRIx64, + params-platform_bus_base); +const char platcomp[] = qemu,platform\0simple-bus; +PlatformDevtreeData data; +Object *container; +uint64_t addr = params-platform_bus_base; +uint64_t size = params-platform_bus_size; +int irq_start = params-platform_bus_first_irq; + +/* Create a /platform node that we can put all devices into */ +qemu_fdt_add_subnode(fdt, node); +qemu_fdt_setprop(fdt, node, compatible, platcomp, sizeof(platcomp)); + +/* Our platform bus region is less than 32bit big, so 1 cell is enough for + address and size */ +qemu_fdt_setprop_cells(fdt, node, #size-cells, 1); +qemu_fdt_setprop_cells(fdt, node, #address-cells, 1); +qemu_fdt_setprop_cells(fdt, node, ranges, 0, addr 32, addr, size); + +qemu_fdt_setprop_phandle(fdt, node, interrupt-parent, intc); + +/* Loop through all devices and create nodes for known ones */ +data.fdt = fdt; +data.intc = intc; +data.irq_start = irq_start; +data.node = node; Why does arm_sysbus_device_create_devtree need intc and irq_start? + +container = container_get(qdev_get_machine(), /peripheral); +arm_sysbus_device_create_devtree(container, data); +container = container_get(qdev_get_machine(), /peripheral-anon); +arm_sysbus_device_create_devtree(container, data); + +g_free(node); +} diff --git a/include/hw/arm/dyn_sysbus_devtree.h b/include/hw/arm/dyn_sysbus_devtree.h new file mode 100644 index 000..b072365 --- /dev/null +++ b/include/hw/arm/dyn_sysbus_devtree.h @@ -0,0 +1,16 @@ +#ifndef HW_ARM_DYN_SYSBUS_DEVTREE_H +#define HW_ARM_DYN_SYSBUS_DEVTREE_H + +#include hw/misc/dyn_sysbus_binding.h + +typedef struct PlatformDevtreeData { +void *fdt; +const char *intc; +int irq_start; +const char *node; +} PlatformDevtreeData; + +void
Re: [Qemu-devel] [PATCH v3 5/6] hw/arm/virt: new add_fdt_*_node functions
Il 09/09/2014 09:54, Eric Auger ha scritto: Create new functions: - add_fdt_uart_node - add_fdt_rtc_node - add_fdt_virtio_nodes Actually they are fdt_add_uart_node etc. They will be used for dynamic sysbus instantiation. Signed-off-by: Eric Auger eric.au...@linaro.org --- v2 - v3: reword title to avoid content violation --- hw/arm/virt.c | 67 +++ 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index d6fffc7..9085b88 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -351,18 +351,15 @@ static void create_gic(const VirtBoardInfo *vbi, qemu_irq *pic) fdt_add_gic_node(vbi); } -static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic) +static void fdt_add_uart_node(const VirtBoardInfo *vbi) { -char *nodename; hwaddr base = vbi-memmap[VIRT_UART].base; hwaddr size = vbi-memmap[VIRT_UART].size; int irq = vbi-irqmap[VIRT_UART]; const char compat[] = arm,pl011\0arm,primecell; const char clocknames[] = uartclk\0apb_pclk; +char *nodename = g_strdup_printf(/pl011@% PRIx64, base); -sysbus_create_simple(pl011, base, pic[irq]); - -nodename = g_strdup_printf(/pl011@% PRIx64, base); qemu_fdt_add_subnode(vbi-fdt, nodename); /* Note that we can't use setprop_string because of the embedded NUL */ qemu_fdt_setprop(vbi-fdt, nodename, compatible, @@ -379,17 +376,23 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic) g_free(nodename); } -static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic) +static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic) +{ +hwaddr base = vbi-memmap[VIRT_UART].base; +int irq = vbi-irqmap[VIRT_UART]; + +sysbus_create_simple(pl011, base, pic[irq]); +fdt_add_uart_node(vbi); +} + +static void fdt_add_rtc_node(const VirtBoardInfo *vbi) { -char *nodename; hwaddr base = vbi-memmap[VIRT_RTC].base; hwaddr size = vbi-memmap[VIRT_RTC].size; int irq = vbi-irqmap[VIRT_RTC]; const char compat[] = arm,pl031\0arm,primecell; +char *nodename = g_strdup_printf(/pl031@% PRIx64, base); -sysbus_create_simple(pl031, base, pic[irq]); - -nodename = g_strdup_printf(/pl031@% PRIx64, base); qemu_fdt_add_subnode(vbi-fdt, nodename); qemu_fdt_setprop(vbi-fdt, nodename, compatible, compat, sizeof(compat)); qemu_fdt_setprop_sized_cells(vbi-fdt, nodename, reg, @@ -402,22 +405,20 @@ static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic) g_free(nodename); } -static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic) +static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic) { -int i; -hwaddr size = vbi-memmap[VIRT_MMIO].size; +hwaddr base = vbi-memmap[VIRT_RTC].base; +int irq = vbi-irqmap[VIRT_RTC]; -/* Note that we have to create the transports in forwards order - * so that command line devices are inserted lowest address first, - * and then add dtb nodes in reverse order so that they appear in - * the finished device tree lowest address first. - */ -for (i = 0; i NUM_VIRTIO_TRANSPORTS; i++) { -int irq = vbi-irqmap[VIRT_MMIO] + i; -hwaddr base = vbi-memmap[VIRT_MMIO].base + i * size; +sysbus_create_simple(pl031, base, pic[irq]); -sysbus_create_simple(virtio-mmio, base, pic[irq]); -} +fdt_add_rtc_node(vbi); +} + +static void fdt_add_virtio_nodes(const VirtBoardInfo *vbi) +{ +int i; +hwaddr size = vbi-memmap[VIRT_MMIO].size; for (i = NUM_VIRTIO_TRANSPORTS - 1; i = 0; i--) { char *nodename; @@ -437,6 +438,26 @@ static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic) } } +static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic) +{ +int i; +hwaddr size = vbi-memmap[VIRT_MMIO].size; + +/* Note that we have to create the transports in forwards order + * so that command line devices are inserted lowest address first, + * and then add dtb nodes in reverse order so that they appear in + * the finished device tree lowest address first. + */ +for (i = 0; i NUM_VIRTIO_TRANSPORTS; i++) { +int irq = vbi-irqmap[VIRT_MMIO] + i; +hwaddr base = vbi-memmap[VIRT_MMIO].base + i * size; + +sysbus_create_simple(virtio-mmio, base, pic[irq]); +} + +fdt_add_virtio_nodes(vbi); +} + static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size) { const VirtBoardInfo *board = (const VirtBoardInfo *)binfo;
Re: [Qemu-devel] [PATCH v3 6/6] hw/arm/virt: Support dynamically spawned sysbus devices
Il 09/09/2014 09:54, Eric Auger ha scritto: Allows sysbus devices to be instantiated from command line by using -device option Signed-off-by: Alexander Graf ag...@suse.de Signed-off-by: Eric Auger eric.au...@linaro.org --- v2 - v3 - renaming of arm_platform_bus_create_devtree and arm_load_dtb - add copyright in hw/arm/dyn_sysbus_devtree.c v1 - v2: - remove useless vfio-platform.h include file - s/MACHVIRT_PLATFORM_HOLE/MACHVIRT_PLATFORM_SIZE - use dyn_sysbus_binding and dyn_sysbus_devtree - dynamic sysbus platform buse size shrinked to 4MB and moved between RTC and MMIO v1: Inspired from what Alex Graf did in ppc e500 https://lists.gnu.org/archive/html/qemu-ppc/2014-07/msg00012.html --- hw/arm/dyn_sysbus_devtree.c | 26 +++ hw/arm/virt.c | 62 +++-- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/hw/arm/dyn_sysbus_devtree.c b/hw/arm/dyn_sysbus_devtree.c index 6375024..61e5b5f 100644 --- a/hw/arm/dyn_sysbus_devtree.c +++ b/hw/arm/dyn_sysbus_devtree.c @@ -1,7 +1,30 @@ +/* + * ARM Platform Bus device tree generation helpers + * + * Copyright (c) 2014 Linaro Limited + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see http://www.gnu.org/licenses/. + * + */ + #include hw/arm/dyn_sysbus_devtree.h #include qemu/error-report.h #include sysemu/device_tree.h +/** + * arm_sysbus_device_create_devtree - create the node of devices + * attached to the platform bus + */ static int arm_sysbus_device_create_devtree(Object *obj, void *opaque) { PlatformDevtreeData *data = opaque; @@ -27,6 +50,9 @@ static int arm_sysbus_device_create_devtree(Object *obj, void *opaque) return 0; } +/** + * arm_platform_bus_create_devtree - create the platform bus node + */ void arm_platform_bus_create_devtree(DynSysbusParams *params, void *fdt, const char *intc) { All this should go in patch 2. For the documentation comments, please follow the model of include/hw/memory.h (including putting the documentation in the header for public functions). diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 9085b88..16acf44 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -40,6 +40,8 @@ #include exec/address-spaces.h #include qemu/bitops.h #include qemu/error-report.h +#include hw/misc/dyn_sysbus_binding.h +#include hw/arm/dyn_sysbus_devtree.h #define NUM_VIRTIO_TRANSPORTS 32 @@ -57,6 +59,14 @@ #define GIC_FDT_IRQ_PPI_CPU_START 8 #define GIC_FDT_IRQ_PPI_CPU_WIDTH 8 +#define MACHVIRT_PLATFORM_BASE 0x940 +#define MACHVIRT_PLATFORM_SIZE (4ULL * 1024 * 1024) /* 4 MB */ +#define MACHVIRT_PLATFORM_PAGE_SHIFT 12 +#define MACHVIRT_PLATFORM_SIZE_PAGES (MACHVIRT_PLATFORM_SIZE \ +MACHVIRT_PLATFORM_PAGE_SHIFT) +#define MACHVIRT_PLATFORM_FIRST_IRQ48 +#define MACHVIRT_PLATFORM_NUM_IRQS 20 + enum { VIRT_FLASH, VIRT_MEM, @@ -66,6 +76,7 @@ enum { VIRT_UART, VIRT_MMIO, VIRT_RTC, +VIRT_PLATFORM, }; typedef struct MemMapEntry { @@ -105,16 +116,27 @@ static const MemMapEntry a15memmap[] = { [VIRT_GIC_CPU] ={ 0x0801, 0x0001 }, [VIRT_UART] = { 0x0900, 0x1000 }, [VIRT_RTC] ={ 0x0901, 0x1000 }, +[VIRT_PLATFORM] = {MACHVIRT_PLATFORM_BASE , MACHVIRT_PLATFORM_SIZE}, [VIRT_MMIO] = { 0x0a00, 0x0200 }, /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ /* 0x1000 .. 0x4000 reserved for PCI */ -[VIRT_MEM] ={ 0x4000, 30ULL * 1024 * 1024 * 1024 }, +[VIRT_MEM] = { 0x4000, 30ULL * 1024 * 1024 * 1024 }, }; static const int a15irqmap[] = { [VIRT_UART] = 1, [VIRT_RTC] = 2, [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */ +[VIRT_PLATFORM] = MACHVIRT_PLATFORM_FIRST_IRQ, +}; + +static DynSysbusParams dyn_sysbus_platform_params = { +.has_platform_bus = true, +.platform_bus_base = MACHVIRT_PLATFORM_BASE, +.platform_bus_size = MACHVIRT_PLATFORM_SIZE, +.platform_bus_first_irq = MACHVIRT_PLATFORM_FIRST_IRQ, +.platform_bus_num_irqs = MACHVIRT_PLATFORM_NUM_IRQS, +.page_shift = MACHVIRT_PLATFORM_PAGE_SHIFT, }; static VirtBoardInfo machines[] = { @@ -458,6 +480,18 @@
Re: [Qemu-devel] [PATCH v3 6/6] hw/arm/virt: Support dynamically spawned sysbus devices
On 9 September 2014 12:11, Paolo Bonzini pbonz...@redhat.com wrote: And if arm_load_dtb used rom_add_blob_fixed instead of cpu_physical_memory_write, you wouldn't need a reset hook at all. We need to do this anyway, because currently we don't do anything to ensure the DTB hangs around for the OS to find again on reset, even in the simple just boot Linux setups. -- PMM
Re: [Qemu-devel] [PATCH v7 RESEND 3/8] memory: add parameter errp to memory_region_init_ram_ptr
Il 09/09/2014 07:27, Hu Tao ha scritto: Add parameter errp to memory_region_init_ram_ptr and update all call sites to pass in error_abort. Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com Aborting in VFIO would be wrong, since VFIO devices can be hotplugged. But actually, ram_block_add can never fail when called from qemu_ram_alloc_from_ptr, so let's instead do: diff --git a/exec.c b/exec.c index 2b9c4c5..0ca73c8 100644 --- a/exec.c +++ b/exec.c @@ -1373,7 +1373,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, #endif ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, - MemoryRegion *mr, Error **errp) + MemoryRegion *mr) { RAMBlock *new_block; ram_addr_t addr; @@ -1388,13 +1388,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, if (host) { new_block-flags |= RAM_PREALLOC; } -addr = ram_block_add(new_block, local_err); -if (local_err) { -g_free(new_block); -error_propagate(errp, local_err); -return -1; -} -return addr; +return ram_block_add(new_block, error_abort); } ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr, Error **errp) diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index cf1d4c7..7c6f80e 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -26,7 +26,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, bool share, const char *mem_path, Error **errp); ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, - MemoryRegion *mr, Error **errp); + MemoryRegion *mr); ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr, Error **errp); int qemu_get_ram_fd(ram_addr_t addr); void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
[Qemu-devel] [PATCH v2] qemu-char: fix terminal crash when using -monitor stdio -nographic
From: Li Liu john.li...@huawei.com Eeay to reproduce, just try qemu -monitor stdio -nographic and type quit, then the terminal will be crashed. There are two pathes try to call tcgetattr of stdio in vl.c: 1) Monitor_parse(optarg, readline); . qemu_opts_foreach(qemu_find_opts(chardev), chardev_init_func, NULL, 1) != 0) 2) if (default_serial) add_device_config(DEV_SERIAL, stdio); if (foreach_device_config(DEV_SERIAL, serial_parse) 0) Both of them will trigger qemu_chr_open_stdio which will disable ECHO attributes. First one has updated the attributes of stdio by calling qemu_chr_fe_set_echo(chr, false). And the tty attributes has been saved in oldtty. Then the second path will redo such actions, and the oldtty is overlapped. So till quit, term_exit can't recove the correct attributes. Signed-off-by: Li Liu john.li...@huawei.com --- changes v1 - v2: 1) as Markus Armbruster and Gerd Hoffmann suggested : Multiple character devices can't use the same terminal. So catch and reject the attempt if stdio is opened already. --- qemu-char.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/qemu-char.c b/qemu-char.c index d4f327a..f8f0c48 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1017,6 +1017,7 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts) /* init terminal so that we can grab keys */ static struct termios oldtty; static int old_fd0_flags; +static bool stdio_is_ready; static bool stdio_allow_signal; static void term_exit(void) @@ -1060,8 +1061,15 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) error_report(cannot use stdio with -daemonize); return NULL; } + +if (stdio_is_ready) { +error_report(cannot use stdio by multiple character devices); +exit(1); +} + +stdio_is_ready = true; old_fd0_flags = fcntl(0, F_GETFL); -tcgetattr (0, oldtty); +tcgetattr(0, oldtty); qemu_set_nonblock(0); atexit(term_exit); -- 1.7.9.5
Re: [Qemu-devel] [PATCH v7 RESEND 4/8] memory: add parameter errp to memory_region_init_rom_device
Il 09/09/2014 07:27, Hu Tao ha scritto: Add parameter errp to memory_region_init_rom_device and update all call sites to pass in error_abort. Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com Better not use error_abort if we can avoid it, and here it's particularly easy... Paolo diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index f15b4fe..688184e 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -750,6 +750,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp) int ret; uint64_t blocks_per_device, device_len; int num_devices; +Error *local_err = NULL; total_len = pfl-sector_len * pfl-nb_blocs; @@ -770,7 +771,12 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp) memory_region_init_rom_device( pfl-mem, OBJECT(dev), pfl-be ? pflash_cfi01_ops_be : pflash_cfi01_ops_le, pfl, -pfl-name, total_len, error_abort); +pfl-name, total_len, local_err); +if (local_err) { +error_propagate(errp, local_err); +return NULL; +} + vmstate_register_ram(pfl-mem, DEVICE(pfl)); pfl-storage = memory_region_get_ram_ptr(pfl-mem); sysbus_init_mmio(SYS_BUS_DEVICE(dev), pfl-mem); diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index 29bb0dc..39b44f3 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -597,6 +597,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp) pflash_t *pfl = CFI_PFLASH02(dev); uint32_t chip_len; int ret; +Error *local_err = NULL; chip_len = pfl-sector_len * pfl-nb_blocs; /* XXX: to be fixed */ @@ -608,7 +609,12 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp) memory_region_init_rom_device(pfl-orig_mem, OBJECT(pfl), pfl-be ? pflash_cfi02_ops_be : pflash_cfi02_ops_le, - pfl, pfl-name, chip_len, error_abort); + pfl, pfl-name, chip_len, local_err); +if (local_err) { +error_propagate(errp, local_err); +return NULL; +} + vmstate_register_ram(pfl-orig_mem, DEVICE(pfl)); pfl-storage = memory_region_get_ram_ptr(pfl-orig_mem); pfl-chip_len = chip_len; --- hw/block/pflash_cfi01.c | 2 +- hw/block/pflash_cfi02.c | 2 +- include/exec/memory.h | 4 +++- memory.c| 5 +++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 593fbc5..4d51bfd 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -773,7 +773,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp) memory_region_init_rom_device( pfl-mem, OBJECT(dev), pfl-be ? pflash_cfi01_ops_be : pflash_cfi01_ops_le, pfl, -pfl-name, total_len); +pfl-name, total_len, error_abort); vmstate_register_ram(pfl-mem, DEVICE(pfl)); pfl-storage = memory_region_get_ram_ptr(pfl-mem); sysbus_init_mmio(SYS_BUS_DEVICE(dev), pfl-mem); diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index e196f4d..29bb0dc 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -608,7 +608,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp) memory_region_init_rom_device(pfl-orig_mem, OBJECT(pfl), pfl-be ? pflash_cfi02_ops_be : pflash_cfi02_ops_le, - pfl, pfl-name, chip_len); + pfl, pfl-name, chip_len, error_abort); vmstate_register_ram(pfl-orig_mem, DEVICE(pfl)); pfl-storage = memory_region_get_ram_ptr(pfl-orig_mem); pfl-chip_len = chip_len; diff --git a/include/exec/memory.h b/include/exec/memory.h index dcb35a2..4921d27 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -388,13 +388,15 @@ void memory_region_init_alias(MemoryRegion *mr, * @ops: callbacks for write access handling. * @name: the name of the region. * @size: size of the region. + * @errp: pointer to Error*, to store an error if it happens. */ void memory_region_init_rom_device(MemoryRegion *mr, struct Object *owner, const MemoryRegionOps *ops, void *opaque, const char *name, - uint64_t size); + uint64_t size, + Error **errp); /** * memory_region_init_reservation: Initialize a memory region that reserves diff --git a/memory.c b/memory.c index ffe24ff..38c29df 100644 --- a/memory.c +++ b/memory.c @@ -1202,7 +1202,8 @@ void memory_region_init_rom_device(MemoryRegion *mr,
Re: [Qemu-devel] [PATCH v7 RESEND 6/8] exec: file_ram_alloc: don't exit if failed to preallocate memory
Il 09/09/2014 07:27, Hu Tao ha scritto: diff --git a/exec.c b/exec.c index 2b9c4c5..0362cd8 100644 --- a/exec.c +++ b/exec.c @@ -1129,8 +1129,8 @@ static void *file_ram_alloc(RAMBlock *block, return area; error: -if (mem_prealloc) { -exit(1); +if (area area != MAP_FAILED) { +munmap(area, memory); } area is being used uninitialized here, and os_mem_prealloc can still do exit(1). I'm not sure what this patch is doing... Paolo return NULL;
Re: [Qemu-devel] [PATCH v7 RESEND 2/8] memory: add parameter errp to memory_region_init_ram
Il 09/09/2014 07:27, Hu Tao ha scritto: Add parameter errp to memory_region_init_ram and update all call sites to pass in error_abort. Signed-off-by: Hu Tao hu...@cn.fujitsu.com Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- backends/hostmem-ram.c | 2 +- hw/alpha/typhoon.c | 3 ++- hw/arm/armv7m.c | 7 --- hw/arm/cubieboard.c | 2 +- hw/arm/digic_boards.c| 2 +- hw/arm/exynos4210.c | 9 + hw/arm/highbank.c| 5 +++-- hw/arm/integratorcp.c| 5 +++-- hw/arm/kzm.c | 4 ++-- hw/arm/mainstone.c | 3 ++- hw/arm/musicpal.c| 6 -- hw/arm/omap1.c | 6 -- hw/arm/omap2.c | 6 -- hw/arm/omap_sx1.c| 6 -- hw/arm/palm.c| 3 ++- hw/arm/pxa2xx.c | 11 +++ hw/arm/realview.c| 9 ++--- hw/arm/spitz.c | 2 +- hw/arm/strongarm.c | 3 ++- hw/arm/tosa.c| 2 +- hw/arm/versatilepb.c | 3 ++- hw/arm/vexpress.c| 15 ++- hw/arm/virt.c| 3 ++- hw/arm/xilinx_zynq.c | 6 -- hw/block/onenand.c | 2 +- hw/core/loader.c | 2 +- hw/cris/axis_dev88.c | 6 -- hw/display/cg3.c | 6 -- hw/display/qxl.c | 6 +++--- hw/display/sm501.c | 2 +- hw/display/tc6393xb.c| 3 ++- hw/display/tcx.c | 5 +++-- hw/display/vga.c | 3 ++- hw/display/vmware_vga.c | 3 ++- hw/i386/kvm/pci-assign.c | 3 ++- hw/i386/pc.c | 3 ++- hw/i386/pc_sysfw.c | 5 +++-- hw/input/milkymist-softusb.c | 4 ++-- hw/lm32/lm32_boards.c| 6 -- hw/lm32/milkymist.c | 3 ++- hw/m68k/an5206.c | 4 ++-- hw/m68k/dummy_m68k.c | 2 +- hw/m68k/mcf5208.c| 4 ++-- hw/microblaze/petalogix_ml605_mmu.c | 5 +++-- hw/microblaze/petalogix_s3adsp1800_mmu.c | 6 -- hw/mips/mips_fulong2e.c | 5 +++-- hw/mips/mips_jazz.c | 8 +--- hw/mips/mips_malta.c | 6 -- hw/mips/mips_mipssim.c | 6 -- hw/mips/mips_r4k.c | 5 +++-- hw/moxie/moxiesim.c | 4 ++-- hw/net/milkymist-minimac2.c | 2 +- hw/openrisc/openrisc_sim.c | 2 +- hw/pci-host/prep.c | 3 ++- hw/pci/pci.c | 2 +- hw/ppc/mac_newworld.c| 3 ++- hw/ppc/mac_oldworld.c| 3 ++- hw/ppc/ppc405_boards.c | 8 +--- hw/ppc/ppc405_uc.c | 3 ++- hw/s390x/s390-virtio-ccw.c | 2 +- hw/s390x/s390-virtio.c | 2 +- hw/sh4/r2d.c | 2 +- hw/sh4/shix.c| 8 +--- hw/sparc/leon3.c | 4 ++-- hw/sparc/sun4m.c | 10 ++ hw/sparc64/sun4u.c | 6 -- hw/unicore32/puv3.c | 3 ++- hw/xtensa/sim.c | 4 ++-- hw/xtensa/xtfpga.c | 8 +--- include/exec/memory.h| 4 +++- memory.c | 5 +++-- numa.c | 4 ++-- xen-hvm.c| 3 ++- 73 files changed, 203 insertions(+), 128 deletions(-) Please modify the init or realize functions to not use error_abort (PCI devices will have to use qerror_report_err). A patch on top of this one will do. Paolo diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c index d9a8290..e55d066 100644 --- a/backends/hostmem-ram.c +++ b/backends/hostmem-ram.c @@ -27,7 +27,7 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) path = object_get_canonical_path_component(OBJECT(backend)); memory_region_init_ram(backend-mr, OBJECT(backend), path, - backend-size); + backend-size, error_abort); g_free(path); } diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c index 31947d9..5310006 100644 --- a/hw/alpha/typhoon.c +++
Re: [Qemu-devel] [PATCH v7 RESEND 0/8] memory API improvements and bug fixes for memory backends
Il 09/09/2014 07:27, Hu Tao ha scritto: This is merely a rebase of v7, and fixes two merge conflicts. This series includes two parts: 1. part 1 includes patches 1-4, which improves error handling of memory_region_init_ram, memory_region_init_ram_ptr and memory_region_init_rom_device 2. part 2 includes patches 5-8, each fixes a bug of memory backend. changes: v7: - split the memory-file preallocation fix into its own patch(patch 6) - some commit messages tweaks v6: - split patch 6 in v5 into 2 - use local_err instead of errp - typo fixes v5: - don't introduce _may_fail and _nofail versions of memory API - the patches order of bug fix and memory API change is exchanged, first comes the API change, then bug fix. v4: - fix build on 32bit host - add memory API renaming - rebase on latest master v3: - introduce memory_region_init_ram_may_fail and memory_region_init_ram_ptr_may_fail - address comments by MST - missing the functions renaming. will send later. v2: - split patch 1 in v1 into 2 patches - don't rely on ram_block_add to return -1 - error message tweak in file_ram_alloc - add error messages reported by qemu to commit message of patch 3 v1: - initial version Hu Tao (8): exec: add parameter errp to qemu_ram_alloc and qemu_ram_alloc_from_ptr memory: add parameter errp to memory_region_init_ram memory: add parameter errp to memory_region_init_ram_ptr memory: add parameter errp to memory_region_init_rom_device hostmem-ram: don't exit qemu if size of memory-backend-ram is way too big exec: file_ram_alloc: don't exit if failed to preallocate memory exec: report error when memory hpagesize exec: add parameter errp to gethugepagesize backends/hostmem-ram.c | 2 +- exec.c | 60 ++-- hw/alpha/typhoon.c | 3 +- hw/arm/armv7m.c | 7 ++-- hw/arm/cubieboard.c | 2 +- hw/arm/digic_boards.c| 2 +- hw/arm/exynos4210.c | 9 ++--- hw/arm/highbank.c| 5 +-- hw/arm/integratorcp.c| 5 +-- hw/arm/kzm.c | 4 +-- hw/arm/mainstone.c | 3 +- hw/arm/musicpal.c| 6 ++-- hw/arm/omap1.c | 6 ++-- hw/arm/omap2.c | 6 ++-- hw/arm/omap_sx1.c| 6 ++-- hw/arm/palm.c| 3 +- hw/arm/pxa2xx.c | 11 +++--- hw/arm/realview.c| 9 +++-- hw/arm/spitz.c | 2 +- hw/arm/strongarm.c | 3 +- hw/arm/tosa.c| 2 +- hw/arm/versatilepb.c | 3 +- hw/arm/vexpress.c| 15 +--- hw/arm/virt.c| 3 +- hw/arm/xilinx_zynq.c | 6 ++-- hw/block/onenand.c | 2 +- hw/block/pflash_cfi01.c | 2 +- hw/block/pflash_cfi02.c | 2 +- hw/core/loader.c | 2 +- hw/cris/axis_dev88.c | 6 ++-- hw/display/cg3.c | 6 ++-- hw/display/g364fb.c | 2 +- hw/display/qxl.c | 6 ++-- hw/display/sm501.c | 2 +- hw/display/tc6393xb.c| 3 +- hw/display/tcx.c | 5 +-- hw/display/vga.c | 3 +- hw/display/vmware_vga.c | 3 +- hw/i386/kvm/pci-assign.c | 6 ++-- hw/i386/pc.c | 3 +- hw/i386/pc_sysfw.c | 5 +-- hw/input/milkymist-softusb.c | 4 +-- hw/lm32/lm32_boards.c| 6 ++-- hw/lm32/milkymist.c | 3 +- hw/m68k/an5206.c | 4 +-- hw/m68k/dummy_m68k.c | 2 +- hw/m68k/mcf5208.c| 4 +-- hw/microblaze/petalogix_ml605_mmu.c | 5 +-- hw/microblaze/petalogix_s3adsp1800_mmu.c | 6 ++-- hw/mips/mips_fulong2e.c | 5 +-- hw/mips/mips_jazz.c | 8 +++-- hw/mips/mips_malta.c | 6 ++-- hw/mips/mips_mipssim.c | 6 ++-- hw/mips/mips_r4k.c | 5 +-- hw/misc/ivshmem.c| 5 +-- hw/misc/vfio.c | 3 +- hw/moxie/moxiesim.c | 4 +-- hw/net/milkymist-minimac2.c | 2 +- hw/openrisc/openrisc_sim.c | 2 +- hw/pci-host/prep.c | 3 +- hw/pci/pci.c
[Qemu-devel] ppc: Test
Please ignore this mail.
[Qemu-devel] [PATCH 0/2] vfio: Another try to fix ROM BAR endianness
I did some tests on LE/BE guest/host combinations and came up with these 2 patches. Please comment. Thanks. Alexey Kardashevskiy (1): Revert vfio: Make BARs native endian Nikunj A Dadhania (1): vfio: make rom read endian sensitive hw/misc/vfio.c | 24 1 file changed, 12 insertions(+), 12 deletions(-) -- 2.0.0
[Qemu-devel] [PATCH 2/2] vfio: make rom read endian sensitive
From: Nikunj A Dadhania nik...@linux.vnet.ibm.com All memory regions used by VFIO are LITTLE_ENDIAN and they already take care of endiannes when accessing real device BARs except ROM - it was broken on BE hosts. This fixes endiannes for ROM BARs the same way as it is done for other BARs. Signed-off-by: Nikunj A Dadhania nik...@linux.vnet.ibm.com [aik: added commit log] Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- hw/misc/vfio.c | 27 --- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index 22ebcbd..d66f3d2 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -1250,7 +1250,13 @@ static void vfio_pci_load_rom(VFIODevice *vdev) static uint64_t vfio_rom_read(void *opaque, hwaddr addr, unsigned size) { VFIODevice *vdev = opaque; -uint64_t val = ((uint64_t)1 (size * 8)) - 1; +union { +uint8_t byte; +uint16_t word; +uint32_t dword; +uint64_t qword; +} val; +uint64_t data = 0; /* Load the ROM lazily when the guest tries to read it */ if (unlikely(!vdev-rom !vdev-rom_read_failed)) { @@ -1260,11 +1266,26 @@ static uint64_t vfio_rom_read(void *opaque, hwaddr addr, unsigned size) memcpy(val, vdev-rom + addr, (addr vdev-rom_size) ? MIN(size, vdev-rom_size - addr) : 0); +switch (size) { +case 1: +data = val.byte; +break; +case 2: +data = le16_to_cpu(val.word); +break; +case 4: +data = le32_to_cpu(val.dword); +break; +default: +hw_error(vfio: unsupported read size, %d bytes\n, size); +break; +} + DPRINTF(%s(%04x:%02x:%02x.%x, 0x%HWADDR_PRIx, 0x%x) = 0x%PRIx64\n, __func__, vdev-host.domain, vdev-host.bus, vdev-host.slot, -vdev-host.function, addr, size, val); +vdev-host.function, addr, size, data); -return val; +return data; } static void vfio_rom_write(void *opaque, hwaddr addr, -- 2.0.0
[Qemu-devel] [PATCH 1/2] Revert vfio: Make BARs native endian
This reverts commit c40708176a6b52b73bec14796b7c71b882ceb102. The idea not to swap bytes at all did not work out as MMIO interface is defined as target host endian and it is always big-endian for PPC64 so the original part broke PPC64 guests on LE hosts (x86/ppc64le). Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- hw/misc/vfio.c | 41 ++--- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index 40dcaa6..22ebcbd 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -1098,10 +1098,10 @@ static void vfio_bar_write(void *opaque, hwaddr addr, buf.byte = data; break; case 2: -buf.word = data; +buf.word = cpu_to_le16(data); break; case 4: -buf.dword = data; +buf.dword = cpu_to_le32(data); break; default: hw_error(vfio: unsupported write size, %d bytes, size); @@ -1158,10 +1158,10 @@ static uint64_t vfio_bar_read(void *opaque, data = buf.byte; break; case 2: -data = buf.word; +data = le16_to_cpu(buf.word); break; case 4: -data = buf.dword; +data = le32_to_cpu(buf.dword); break; default: hw_error(vfio: unsupported read size, %d bytes, size); @@ -1188,7 +1188,7 @@ static uint64_t vfio_bar_read(void *opaque, static const MemoryRegionOps vfio_bar_ops = { .read = vfio_bar_read, .write = vfio_bar_write, -.endianness = DEVICE_NATIVE_ENDIAN, +.endianness = DEVICE_LITTLE_ENDIAN, }; static void vfio_pci_load_rom(VFIODevice *vdev) @@ -1250,42 +1250,21 @@ static void vfio_pci_load_rom(VFIODevice *vdev) static uint64_t vfio_rom_read(void *opaque, hwaddr addr, unsigned size) { VFIODevice *vdev = opaque; -union { -uint8_t byte; -uint16_t word; -uint32_t dword; -uint64_t qword; -} buf; -uint64_t data = 0; +uint64_t val = ((uint64_t)1 (size * 8)) - 1; /* Load the ROM lazily when the guest tries to read it */ if (unlikely(!vdev-rom !vdev-rom_read_failed)) { vfio_pci_load_rom(vdev); } -memcpy(buf, vdev-rom + addr, +memcpy(val, vdev-rom + addr, (addr vdev-rom_size) ? MIN(size, vdev-rom_size - addr) : 0); -switch (size) { -case 1: -data = buf.byte; -break; -case 2: -data = buf.word; -break; -case 4: -data = buf.dword; -break; -default: -hw_error(vfio: unsupported read size, %d bytes, size); -break; -} - DPRINTF(%s(%04x:%02x:%02x.%x, 0x%HWADDR_PRIx, 0x%x) = 0x%PRIx64\n, __func__, vdev-host.domain, vdev-host.bus, vdev-host.slot, -vdev-host.function, addr, size, data); +vdev-host.function, addr, size, val); -return data; +return val; } static void vfio_rom_write(void *opaque, hwaddr addr, @@ -1296,7 +1275,7 @@ static void vfio_rom_write(void *opaque, hwaddr addr, static const MemoryRegionOps vfio_rom_ops = { .read = vfio_rom_read, .write = vfio_rom_write, -.endianness = DEVICE_NATIVE_ENDIAN, +.endianness = DEVICE_LITTLE_ENDIAN, }; static bool vfio_blacklist_opt_rom(VFIODevice *vdev) -- 2.0.0
Re: [Qemu-devel] the userspace process vapp mmap filed // [PULL 13/37] vhost-user: fix regions provied with VHOST_USER_SET_MEM_TABLE message
On 2014/9/3 15:08, Michael S. Tsirkin wrote: On Wed, Sep 03, 2014 at 02:26:03PM +0800, linhafieng wrote: I run the user process vapp to test the VHOST_USER_SET_MEM_TABLE message found that the user sapce failed to mmap. Why off-list? pls copy qemu mailing list and pbonz...@redhat.com I wrote a patch for the vapp to test the patch of broken mem regions.The vapp can receive data from VM but there is a mmap failed error. i have some qeusions about the patch and vhost-user: 1.can i mmap all the fd of the mem regions? why some region failed?Have any impact on it? 2.the vapp why not update with the path of broken mem regions? 3.is the test program of vhost user test vring mem more meaningful? 4.the port of switch how to find the vhost-user device?by the socket path? 5.should the process of vhost-user manage all vhost-user backend socket fd? or any better advise? my patch is for vapp is : diff -uNr vapp/vhost_server.c vapp-for-broken-mem-region//vhost_server.c --- vapp/vhost_server.c 2014-08-30 09:39:20.0 + +++ vapp-for-broken-mem-region//vhost_server.c 2014-09-09 11:36:50.0 + @@ -147,18 +147,22 @@ for (idx = 0; idx msg-msg.memory.nregions; idx++) { if (msg-fds[idx] 0) { +size_t size; +uint64_t *guest_mem; VhostServerMemoryRegion *region = vhost_server-memory.regions[idx]; region-guest_phys_addr = msg-msg.memory.regions[idx].guest_phys_addr; region-memory_size = msg-msg.memory.regions[idx].memory_size; region-userspace_addr = msg-msg.memory.regions[idx].userspace_addr; - +region-mmap_offset = msg-msg.memory.regions[idx].mmap_offset; + assert(idx msg-fd_num); assert(msg-fds[idx] 0); -region-mmap_addr = -(uintptr_t) init_shm_from_fd(msg-fds[idx], region-memory_size); - +size = region-memory_size + region-mmap_offset; +guest_mem = init_shm_from_fd(msg-fds[idx], size); +guest_mem += (region-mmap_offset / sizeof(*guest_mem)); +region-mmap_addr = (uint64_t)guest_mem; vhost_server-memory.nregions++; } } diff -uNr vapp/vhost_server.h vapp-for-broken-mem-region//vhost_server.h --- vapp/vhost_server.h 2014-08-30 09:39:20.0 + +++ vapp-for-broken-mem-region//vhost_server.h 2014-09-05 01:41:27.0 + @@ -13,7 +13,9 @@ uint64_t guest_phys_addr; uint64_t memory_size; uint64_t userspace_addr; + uint64_t mmap_offset; uint64_t mmap_addr; + } VhostServerMemoryRegion; typedef struct VhostServerMemory { diff -uNr vapp/vhost_user.h vapp-for-broken-mem-region//vhost_user.h --- vapp/vhost_user.h 2014-08-30 09:39:20.0 + +++ vapp-for-broken-mem-region//vhost_user.h2014-09-05 01:40:20.0 + @@ -13,6 +13,7 @@ uint64_t guest_phys_addr; uint64_t memory_size; uint64_t userspace_addr; + uint64_t mmap_offset; } VhostUserMemoryRegion; typedef struct VhostUserMemory { the result of the vapp with my patch : Processing message: VHOST_USER_SET_OWNER _set_owner Cmd: VHOST_USER_GET_FEATURES (0x1) Flags: 0x1 u64: 0x0 Processing message: VHOST_USER_GET_FEATURES _get_features Cmd: VHOST_USER_SET_VRING_CALL (0xd) Flags: 0x1 u64: 0x0 Processing message: VHOST_USER_SET_VRING_CALL _set_vring_call Got callfd 0x5 Cmd: VHOST_USER_SET_VRING_CALL (0xd) Flags: 0x1 u64: 0x1 Processing message: VHOST_USER_SET_VRING_CALL _set_vring_call Got callfd 0x6 Cmd: VHOST_USER_SET_FEATURES (0x2) Flags: 0x1 u64: 0x0 Processing message: VHOST_USER_SET_FEATURES _set_features Cmd: VHOST_USER_SET_MEM_TABLE (0x5) Flags: 0x1 nregions: 2 region: gpa = 0x0 size = 655360 ua = 0x7f76c000 [0] region: gpa = 0xC size = 2146697216 ua = 0x7f76c00c [1] Processing message: VHOST_USER_SET_MEM_TABLE _set_mem_table mmap: Invalid argument //@@@ region 0 mmap failed! Got memory.nregions 2 Cmd: VHOST_USER_SET_VRING_NUM (0x8) Flags: 0x1 state: 0 256 Processing message: VHOST_USER_SET_VRING_NUM _set_vring_num Cmd: VHOST_USER_SET_VRING_BASE (0xa) Flags: 0x1 state: 0 0 Processing message: VHOST_USER_SET_VRING_BASE _set_vring_base Cmd: VHOST_USER_SET_VRING_ADDR
Re: [Qemu-devel] [PATCH] block: Make op blockers recursive
Am 22.08.2014 um 18:11 hat Benoît Canet geschrieben: Since the block layer code is starting to modify the BDS graph right in the middle of BDS chains (block-mirror's replace parameter for example) QEMU needs to properly block and unblock whole BDS subtrees; recursion is a neat way to achieve this task. This patch also takes care of modifying the op blockers users. Signed-off-by: Benoit Canet benoit.ca...@nodalink.com --- block.c | 69 --- block/blkverify.c | 21 +++ block/commit.c| 3 +++ block/mirror.c| 17 block/quorum.c| 25 + block/stream.c| 3 +++ block/vmdk.c | 34 +++ include/block/block.h | 2 +- include/block/block_int.h | 6 + 9 files changed, 171 insertions(+), 9 deletions(-) diff --git a/block.c b/block.c index 6fa0201..d964b6c 100644 --- a/block.c +++ b/block.c @@ -5446,7 +5446,9 @@ bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp) return false; } -void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason) +/* do the real work of blocking a BDS */ +static void bdrv_do_op_block(BlockDriverState *bs, BlockOpType op, + Error *reason) { BdrvOpBlocker *blocker; assert((int) op = 0 op BLOCK_OP_TYPE_MAX); @@ -5456,7 +5458,9 @@ void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason) QLIST_INSERT_HEAD(bs-op_blockers[op], blocker, list); } -void bdrv_op_unblock(BlockDriverState *bs, BlockOpType op, Error *reason) +/* do the real work of unblocking a BDS */ +static void bdrv_do_op_unblock(BlockDriverState *bs, BlockOpType op, + Error *reason) { BdrvOpBlocker *blocker, *next; assert((int) op = 0 op BLOCK_OP_TYPE_MAX); @@ -5468,6 +5472,65 @@ void bdrv_op_unblock(BlockDriverState *bs, BlockOpType op, Error *reason) } } +static bool bdrv_op_is_blocked_by(BlockDriverState *bs, BlockOpType op, + Error *reason) +{ +BdrvOpBlocker *blocker, *next; +assert((int) op = 0 op BLOCK_OP_TYPE_MAX); +QLIST_FOREACH_SAFE(blocker, bs-op_blockers[op], list, next) { This doesn't actually need the SAFE version. +if (blocker-reason == reason) { +return true; +} +} +return false; +} + +/* block recursively a BDS */ +void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason) +{ +if (!bs) { +return; +} + +/* prevent recursion loop */ +if (bdrv_op_is_blocked_by(bs, op, reason)) { +return; +} + +/* block first for recursion loop protection to work */ +bdrv_do_op_block(bs, op, reason); + +bdrv_op_block(bs-file, op, reason); +bdrv_op_block(bs-backing_hd, op, reason); + +if (bs-drv bs-drv-bdrv_op_recursive_block) { +bs-drv-bdrv_op_recursive_block(bs, op, reason); +} Here you block bs-file/bs-backing_hd automatically, no matter whether the block driver implements the callback or not. I'm not sure if we can do it like this for all times, but for now that should be okay. +} + +/* unblock recursively a BDS */ +void bdrv_op_unblock(BlockDriverState *bs, BlockOpType op, Error *reason) +{ +if (!bs) { +return; +} + +/* prevent recursion loop */ +if (!bdrv_op_is_blocked_by(bs, op, reason)) { +return; +} + +/* unblock first for recursion loop protection to work */ +bdrv_do_op_unblock(bs, op, reason); + +bdrv_op_unblock(bs-file, op, reason); +bdrv_op_unblock(bs-backing_hd, op, reason); + +if (bs-drv bs-drv-bdrv_op_recursive_unblock) { +bs-drv-bdrv_op_recursive_unblock(bs, op, reason); +} +} + void bdrv_op_block_all(BlockDriverState *bs, Error *reason) { int i; @@ -5848,7 +5911,7 @@ BlockDriverState *check_to_replace_node(const char *node_name, Error **errp) return NULL; } -if (bdrv_op_is_blocked(to_replace_bs, BLOCK_OP_TYPE_REPLACE, errp)) { +if (bdrv_op_is_blocked(to_replace_bs, BLOCK_OP_TYPE_MIRROR_REPLACE, errp)) { That rename could have been a separate patch. return NULL; } diff --git a/block/blkverify.c b/block/blkverify.c index 621b785..75ec3df 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -320,6 +320,24 @@ static void blkverify_attach_aio_context(BlockDriverState *bs, bdrv_attach_aio_context(s-test_file, new_context); } +static void blkverify_op_recursive_block(BlockDriverState *bs, BlockOpType op, + Error *reason) +{ +BDRVBlkverifyState *s = bs-opaque; + +bdrv_op_block(bs-file, op, reason); +bdrv_op_block(s-test_file, op, reason); +} + +static void
Re: [Qemu-devel] [PATCH v14 1/5] block: round up file size to nearest sector
The Tuesday 09 Sep 2014 à 11:54:27 (+0800), Hu Tao wrote : Taking the time to systematically write a nice sentence in the commit message body about why your commit exists and explaining the long term purpose of the patch will: -improve the quality of your commit -please everyone involved in the review -ultimately help your to get the patch merged faster Signed-off-by: Hu Tao hu...@cn.fujitsu.com Reviewed-by: Kevin Wolf kw...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com Reviewed-by: Max Reitz mre...@redhat.com --- block/archipelago.c | 3 ++- block/cow.c | 3 ++- block/gluster.c | 4 +-- block/iscsi.c| 4 +-- block/nfs.c | 3 ++- block/qcow.c | 3 ++- block/qcow2.c| 3 ++- block/qed.c | 3 ++- block/raw-posix.c| 8 +++--- block/raw-win32.c| 4 +-- block/rbd.c | 3 ++- block/sheepdog.c | 3 ++- block/ssh.c | 3 ++- block/vdi.c | 3 ++- block/vhdx.c | 3 ++- block/vmdk.c | 3 ++- block/vpc.c | 3 ++- tests/qemu-iotests/104 | 57 tests/qemu-iotests/104.out | 12 + tests/qemu-iotests/common.filter | 21 +++ tests/qemu-iotests/group | 1 + 21 files changed, 127 insertions(+), 23 deletions(-) create mode 100755 tests/qemu-iotests/104 create mode 100644 tests/qemu-iotests/104.out diff --git a/block/archipelago.c b/block/archipelago.c index 22a7daa..06c51f9 100644 --- a/block/archipelago.c +++ b/block/archipelago.c @@ -708,7 +708,8 @@ static int qemu_archipelago_create(const char *filename, parse_filename_opts(filename, errp, volname, segment_name, mport, vport); -total_size = qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0); +total_size = ROUND_UP(qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0), + BDRV_SECTOR_SIZE); if (segment_name == NULL) { segment_name = g_strdup(archipelago); diff --git a/block/cow.c b/block/cow.c index 6ee4833..c3769fe 100644 --- a/block/cow.c +++ b/block/cow.c @@ -335,7 +335,8 @@ static int cow_create(const char *filename, QemuOpts *opts, Error **errp) BlockDriverState *cow_bs = NULL; /* Read out options */ -image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512; +image_sectors = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), + BDRV_SECTOR_SIZE); image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); ret = bdrv_create_file(filename, opts, local_err); diff --git a/block/gluster.c b/block/gluster.c index 1912cf9..65c7a58 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -494,8 +494,8 @@ static int qemu_gluster_create(const char *filename, goto out; } -total_size = -qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE; +total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), + BDRV_SECTOR_SIZE); tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); if (!tmp || !strcmp(tmp, off)) { diff --git a/block/iscsi.c b/block/iscsi.c index 3e19202..84bcae8 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -1531,8 +1531,8 @@ static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp) bs = bdrv_new(, error_abort); /* Read out options */ -total_size = -qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE; +total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), + BDRV_SECTOR_SIZE); bs-opaque = g_new0(struct IscsiLun, 1); iscsilun = bs-opaque; diff --git a/block/nfs.c b/block/nfs.c index 194f301..c76e368 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -418,7 +418,8 @@ static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp) client-aio_context = qemu_get_aio_context(); /* Read out options */ -total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); +total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), + BDRV_SECTOR_SIZE); ret = nfs_client_open(client, url, O_CREAT, errp); if (ret 0) { diff --git a/block/qcow.c b/block/qcow.c index 67c237f..041af26 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -725,7 +725,8 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) BlockDriverState *qcow_bs; /* Read out options */ -total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512; +total_size =
Re: [Qemu-devel] [PATCH 06/12] kvmvapic: fixing loading vmstate
Il 09/09/2014 12:30, Pavel Dovgaluk ha scritto: From: Paolo Bonzini [mailto:pbonz...@redhat.com] Il 27/08/2014 15:03, Pavel Dovgaluk ha scritto: Hmm, probably not. The bug would not be other timers accessing the APIC, because that would also call apic_sync_vapic and the only effect would be an extra useless synchronization. The bug would happen if the APIC is accessed by the CPU before the timer has the occasion to run. Sorry, but I don't understand which problem we will solve with apic_sync_vapic. Taking inspiration from what KVM does, the fix could be even simpler than a change state handler. run_on_cpu functions do not run while the VM is stopped, so the following should work: diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index ce3d903..81d1ad7 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -91,13 +91,20 @@ void apic_enable_tpr_access_reporting(DeviceState *dev, bool enable) } } +static void do_apic_enable_vapic(void *data) +{ +APICCommonState *s = APIC_COMMON(data); +APICCommonClass *info = APIC_COMMON_GET_CLASS(s); + +info-vapic_base_update(s); +} + void apic_enable_vapic(DeviceState *dev, hwaddr paddr) { APICCommonState *s = APIC_COMMON(dev); -APICCommonClass *info = APIC_COMMON_GET_CLASS(s); s-vapic_paddr = paddr; -info-vapic_base_update(s); +run_on_cpu(CPU(s-cpu), do_apic_enable_vapic, s); } I've tried this one and it doesn't work. do_apic_enable_vapic runs on cpu, at the same time the VM state is loaded. APIC state still remains broken because of this. You're right (in fact run_on_cpu is synchronous so the alternative would have been deadlock). A change state handler can work. I'll submit your patches to the migration maintainers, including an alternative fix for this VAPIC problem. Paolo
Re: [Qemu-devel] [RFC V2 02/10] qom/cpu: move register_vmstate to common CPUClass.realizefn
On Thu, 28 Aug 2014 11:36:34 +0800 Gu Zheng guz.f...@cn.fujitsu.com wrote: Move cpu vmstate register from cpu_exec_init into cpu_common_realizefn, apic vmstate register into x86_cpu_apic_realize. And use the cc-get_arch_id as the instance id that suggested by Igor to fix the migration issue. Besides, also use cc-get_arch_id as the cpu index of HMP/QMP command output to fix the index duplicated issue when hotadd a hot-removed cpu. v2: -fix the cpu index duplicated issue in the QMP/HMP command output. Signed-off-by: Gu Zheng guz.f...@cn.fujitsu.com Please split CPU vmstate/APIC vmstate/QMP-monitor changes into separate patches. --- cpus.c |4 +++- exec.c | 32 +++- hw/intc/apic_common.c |3 +-- include/hw/i386/apic_internal.h |2 ++ include/qom/cpu.h |2 ++ monitor.c |4 +++- qom/cpu.c |2 ++ target-i386/cpu.c | 10 -- 8 files changed, 40 insertions(+), 19 deletions(-) diff --git a/cpus.c b/cpus.c index 2b5c0bd..cce2744 100644 --- a/cpus.c +++ b/cpus.c @@ -1394,6 +1394,7 @@ CpuInfoList *qmp_query_cpus(Error **errp) { CpuInfoList *head = NULL, *cur_item = NULL; CPUState *cpu; +CPUClass *cc; CPU_FOREACH(cpu) { CpuInfoList *info; @@ -1411,11 +1412,12 @@ CpuInfoList *qmp_query_cpus(Error **errp) CPUMIPSState *env = mips_cpu-env; #endif +cc = CPU_GET_CLASS(cpu); cpu_synchronize_state(cpu); info = g_malloc0(sizeof(*info)); info-value = g_malloc0(sizeof(*info-value)); -info-value-CPU = cpu-cpu_index; +info-value-CPU = cc-get_arch_id(cpu); info-value-current = (cpu == first_cpu); info-value-halted = cpu-halted; info-value-thread_id = cpu-thread_id; diff --git a/exec.c b/exec.c index 5f9857c..c514492 100644 --- a/exec.c +++ b/exec.c @@ -473,10 +473,28 @@ void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as) } #endif +void cpu_vmstate_register(CPUState *cpu) +{ +CPUClass *cc = CPU_GET_CLASS(cpu); +int cpu_index = cc-get_arch_id(cpu); + +if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { +vmstate_register(NULL, cpu_index, vmstate_cpu_common, cpu); +} +#if defined(CPU_SAVE_VERSION) !defined(CONFIG_USER_ONLY) +register_savevm(NULL, cpu, cpu_index, CPU_SAVE_VERSION, +cpu_save, cpu_load, cpu-env_ptr); +assert(cc-vmsd == NULL); +assert(qdev_get_vmsd(DEVICE(cpu)) == NULL); +#endif +if (cc-vmsd != NULL) { +vmstate_register(NULL, cpu_index, cc-vmsd, cpu); +} +} + void cpu_exec_init(CPUArchState *env) { CPUState *cpu = ENV_GET_CPU(env); -CPUClass *cc = CPU_GET_CLASS(cpu); CPUState *some_cpu; int cpu_index; @@ -499,18 +517,6 @@ void cpu_exec_init(CPUArchState *env) #if defined(CONFIG_USER_ONLY) cpu_list_unlock(); #endif -if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { -vmstate_register(NULL, cpu_index, vmstate_cpu_common, cpu); -} -#if defined(CPU_SAVE_VERSION) !defined(CONFIG_USER_ONLY) -register_savevm(NULL, cpu, cpu_index, CPU_SAVE_VERSION, -cpu_save, cpu_load, env); -assert(cc-vmsd == NULL); -assert(qdev_get_vmsd(DEVICE(cpu)) == NULL); -#endif -if (cc-vmsd != NULL) { -vmstate_register(NULL, cpu_index, cc-vmsd, cpu); -} } #if defined(TARGET_HAS_ICE) diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index ce3d903..029f67d 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -345,7 +345,7 @@ static int apic_dispatch_post_load(void *opaque, int version_id) return 0; } -static const VMStateDescription vmstate_apic_common = { +const VMStateDescription vmstate_apic_common = { .name = apic, .version_id = 3, .minimum_version_id = 3, @@ -391,7 +391,6 @@ static void apic_common_class_init(ObjectClass *klass, void *data) ICCDeviceClass *idc = ICC_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); -dc-vmsd = vmstate_apic_common; dc-reset = apic_reset_common; dc-props = apic_properties_common; idc-realize = apic_common_realize; diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h index 83e2a42..2c91609 100644 --- a/include/hw/i386/apic_internal.h +++ b/include/hw/i386/apic_internal.h @@ -23,6 +23,7 @@ #include exec/memory.h #include hw/cpu/icc_bus.h #include qemu/timer.h +#include migration/vmstate.h /* APIC Local Vector Table */ #define APIC_LVT_TIMER 0 @@ -136,6 +137,7 @@ typedef struct VAPICState { } QEMU_PACKED VAPICState; extern bool apic_report_tpr_access; +extern const VMStateDescription vmstate_apic_common; void apic_report_irq_delivered(int delivered);
Re: [Qemu-devel] [PATCH] Fix typos and misspellings in comments
On 2014/9/9 16:09, Peter Maydell wrote: On 9 September 2014 04:23, zhanghailiangzhang.zhanghaili...@huawei.com wrote: Found by codespell: occured - occurred formated - formatted Comander - Commander gaurantee - guarantee Signed-off-by: zhanghailiangzhang.zhanghaili...@huawei.com --- hw/ppc/spapr.c | 2 +- hw/usb/quirks.h | 2 +- libcacard/vcard_emul_nss.c | 2 +- linux-headers/asm-powerpc/epapr_hcalls.h | 4 ++-- You can't change linux-headers files except by importing them from the kernel, I'm afraid. You'd need to submit that change as a patch to the kernel and then wait for it to be committed there and then we can re-sync our copies of the kernel's headers. OK, i will remove this change from this patch, and send a patch to kernel:) 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 2ab4460..bedef2f 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -541,7 +541,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, _FDT((fdt_property_cell(fdt, rtas-error-log-max, RTAS_ERROR_LOG_MAX))); /* - * According to PAPR, rtas ibm,os-term, does not gaurantee a return + * According to PAPR, rtas ibm,os-term, does not guarantee a return * back to the guest cpu. * * While an additional ibm,extended-os-term property indicates that OK diff --git a/hw/usb/quirks.h b/hw/usb/quirks.h index 8dc6065..2d5d98d 100644 --- a/hw/usb/quirks.h +++ b/hw/usb/quirks.h @@ -90,7 +90,7 @@ static const struct usb_device_id usbredir_raw_serial_ids[] = { { USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */ { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */ { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ -{ USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ +{ USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Commander 2 */ Google suggests this spelling for this device name is correct: http://www.agito.pl/iplus-usb-comander-2-edge-plus-1-37295.html (Polish product?) Interesting;), i will drop this change also. { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */ { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */ { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c index f1bba57..ad9530c 100644 --- a/libcacard/vcard_emul_nss.c +++ b/libcacard/vcard_emul_nss.c @@ -286,7 +286,7 @@ vcard_emul_rsa_op(VCard *card, VCardKey *key, } } if ((i buffer_size) (buffer[i] == 0)) { -/* yes, we have a properly formated PKCS #1 signature */ +/* yes, we have a properly formatted PKCS #1 signature */ OK /* * NOTE: even if we accidentally got an encrypt buffer, which * through shear luck started with 00, 01, ff, 00, it won't matter Another typo here: s/shear/sheer/. OK! diff --git a/linux-headers/asm-powerpc/epapr_hcalls.h b/linux-headers/asm-powerpc/epapr_hcalls.h index 06f7247..33b3f89 100644 --- a/linux-headers/asm-powerpc/epapr_hcalls.h +++ b/linux-headers/asm-powerpc/epapr_hcalls.h @@ -78,7 +78,7 @@ #define EV_SUCCESS 0 #define EV_EPERM 1 /* Operation not permitted */ #define EV_ENOENT 2 /* Entry Not Found */ -#define EV_EIO 3 /* I/O error occured */ +#define EV_EIO 3 /* I/O error occurred */ #define EV_EAGAIN 4 /* The operation had insufficient * resources to complete and should be * retried @@ -89,7 +89,7 @@ #define EV_ENODEV 7 /* No such device */ #define EV_EINVAL 8 /* An argument supplied to the hcall was out of range or invalid */ -#define EV_INTERNAL9 /* An internal error occured */ +#define EV_INTERNAL9 /* An internal error occurred */ #define EV_CONFIG 10 /* A configuration error was detected */ #define EV_INVALID_STATE 11 /* The object is in an invalid state */ #define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */ These fixes should go via the kernel. OK, Thanks.
Re: [Qemu-devel] [PATCH v2 08/12] hpet: fixing saving and loading process
Il 28/08/2014 13:58, Paolo Bonzini ha scritto: This also breaks migration to 2.1, unless you use -no-hpet. Actually, this is also only needed for your record/replay implementation. Paolo
Re: [Qemu-devel] [PATCH v14 2/5] block: don't convert file size to sector size
The Tuesday 09 Sep 2014 à 11:54:28 (+0800), Hu Tao wrote : and avoid converting it back later. Signed-off-by: Hu Tao hu...@cn.fujitsu.com Reviewed-by: Max Reitz mre...@redhat.com --- block/gluster.c | 9 - block/qcow.c | 8 block/qcow2.c | 10 +- block/raw-posix.c | 12 ++-- block/raw-win32.c | 6 +++--- 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/block/gluster.c b/block/gluster.c index 65c7a58..1eb3a8c 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -494,8 +494,8 @@ static int qemu_gluster_create(const char *filename, goto out; } -total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), - BDRV_SECTOR_SIZE); +total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), + BDRV_SECTOR_SIZE); tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); if (!tmp || !strcmp(tmp, off)) { @@ -516,9 +516,8 @@ static int qemu_gluster_create(const char *filename, if (!fd) { ret = -errno; } else { -if (!glfs_ftruncate(fd, total_size * BDRV_SECTOR_SIZE)) { -if (prealloc qemu_gluster_zerofill(fd, 0, -total_size * BDRV_SECTOR_SIZE)) { +if (!glfs_ftruncate(fd, total_size)) { +if (prealloc qemu_gluster_zerofill(fd, 0, total_size)) { ret = -errno; } } else { diff --git a/block/qcow.c b/block/qcow.c index 041af26..a87bd69 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -725,8 +725,8 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) BlockDriverState *qcow_bs; /* Read out options */ -total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), - BDRV_SECTOR_SIZE); +total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), + BDRV_SECTOR_SIZE); backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { flags |= BLOCK_FLAG_ENCRYPT; @@ -754,7 +754,7 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) memset(header, 0, sizeof(header)); header.magic = cpu_to_be32(QCOW_MAGIC); header.version = cpu_to_be32(QCOW_VERSION); -header.size = cpu_to_be64(total_size * 512); +header.size = cpu_to_be64(total_size); header_size = sizeof(header); backing_filename_len = 0; if (backing_file) { @@ -776,7 +776,7 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) } header_size = (header_size + 7) ~7; shift = header.cluster_bits + header.l2_bits; -l1_size = ((total_size * 512) + (1LL shift) - 1) shift; +l1_size = (total_size + (1LL shift) - 1) shift; header.l1_table_offset = cpu_to_be64(header_size); if (flags BLOCK_FLAG_ENCRYPT) { diff --git a/block/qcow2.c b/block/qcow2.c index c8050e5..cf27c3f 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1859,7 +1859,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, } /* Okay, now that we have a valid image, let's give it the right size */ -ret = bdrv_truncate(bs, total_size * BDRV_SECTOR_SIZE); +ret = bdrv_truncate(bs, total_size); if (ret 0) { error_setg_errno(errp, -ret, Could not resize image); goto out; @@ -1912,7 +1912,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) char *backing_file = NULL; char *backing_fmt = NULL; char *buf = NULL; -uint64_t sectors = 0; +uint64_t size = 0; int flags = 0; size_t cluster_size = DEFAULT_CLUSTER_SIZE; int prealloc = 0; @@ -1921,8 +1921,8 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) int ret; /* Read out options */ -sectors = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), - BDRV_SECTOR_SIZE); +size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), +BDRV_SECTOR_SIZE); backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT); if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { @@ -1972,7 +1972,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) goto finish; } -ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags, +ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags, cluster_size, prealloc, opts, version, local_err); if (local_err) { error_propagate(errp, local_err); diff --git a/block/raw-posix.c b/block/raw-posix.c index 9c22e3f..7208c05
[Qemu-devel] Fwd: Re: the userspace process vapp mmap filed // [PULL 13/37] vhost-user: fix regions provied with VHOST_USER_SET_MEM_TABLE message
Forwarded Message Subject: Re: the userspace process vapp mmap filed //[Qemu-devel] [PULL 13/37] vhost-user: fix regions provied with VHOST_USER_SET_MEM_TABLE message Date: Tue, 09 Sep 2014 19:45:08 +0800 From: linhafieng haifeng@huawei.com To: Michael S. Tsirkin m...@redhat.com CC: n.nikol...@virtualopensystems.com, jerry.lili...@huawei.com, qemu-devel@nongnu.org, pbonz...@redhat.com, damar...@cisco.com, t...@virtualopensystems.com On 2014/9/3 15:08, Michael S. Tsirkin wrote: On Wed, Sep 03, 2014 at 02:26:03PM +0800, linhafieng wrote: I run the user process vapp to test the VHOST_USER_SET_MEM_TABLE message found that the user sapce failed to mmap. Why off-list? pls copy qemu mailing list and pbonz...@redhat.com I wrote a patch for the vapp to test the patch of broken mem regions.The vapp can receive data from VM but there is a mmap failed error. i have some qeusions about the patch and vhost-user: 1.can i mmap all the fd of the mem regions? why some region failed?Have any impact on it? 2.the vapp why not update with the path of broken mem regions? 3.is the test program of vhost user test vring mem more meaningful? 4.the port of switch how to find the vhost-user device?by the socket path? 5.should the process of vhost-user manage all vhost-user backend socket fd? or any better advise? my patch is for vapp is : diff -uNr vapp/vhost_server.c vapp-for-broken-mem-region//vhost_server.c --- vapp/vhost_server.c 2014-08-30 09:39:20.0 + +++ vapp-for-broken-mem-region//vhost_server.c 2014-09-09 11:36:50.0 + @@ -147,18 +147,22 @@ for (idx = 0; idx msg-msg.memory.nregions; idx++) { if (msg-fds[idx] 0) { +size_t size; +uint64_t *guest_mem; VhostServerMemoryRegion *region = vhost_server-memory.regions[idx]; region-guest_phys_addr = msg-msg.memory.regions[idx].guest_phys_addr; region-memory_size = msg-msg.memory.regions[idx].memory_size; region-userspace_addr = msg-msg.memory.regions[idx].userspace_addr; - +region-mmap_offset = msg-msg.memory.regions[idx].mmap_offset; + assert(idx msg-fd_num); assert(msg-fds[idx] 0); -region-mmap_addr = -(uintptr_t) init_shm_from_fd(msg-fds[idx], region-memory_size); - +size = region-memory_size + region-mmap_offset; +guest_mem = init_shm_from_fd(msg-fds[idx], size); +guest_mem += (region-mmap_offset / sizeof(*guest_mem)); +region-mmap_addr = (uint64_t)guest_mem; vhost_server-memory.nregions++; } } diff -uNr vapp/vhost_server.h vapp-for-broken-mem-region//vhost_server.h --- vapp/vhost_server.h 2014-08-30 09:39:20.0 + +++ vapp-for-broken-mem-region//vhost_server.h 2014-09-05 01:41:27.0 + @@ -13,7 +13,9 @@ uint64_t guest_phys_addr; uint64_t memory_size; uint64_t userspace_addr; + uint64_t mmap_offset; uint64_t mmap_addr; + } VhostServerMemoryRegion; typedef struct VhostServerMemory { diff -uNr vapp/vhost_user.h vapp-for-broken-mem-region//vhost_user.h --- vapp/vhost_user.h 2014-08-30 09:39:20.0 + +++ vapp-for-broken-mem-region//vhost_user.h2014-09-05 01:40:20.0 + @@ -13,6 +13,7 @@ uint64_t guest_phys_addr; uint64_t memory_size; uint64_t userspace_addr; + uint64_t mmap_offset; } VhostUserMemoryRegion; typedef struct VhostUserMemory { the result of the vapp with my patch : Processing message: VHOST_USER_SET_OWNER _set_owner Cmd: VHOST_USER_GET_FEATURES (0x1) Flags: 0x1 u64: 0x0 Processing message: VHOST_USER_GET_FEATURES _get_features Cmd: VHOST_USER_SET_VRING_CALL (0xd) Flags: 0x1 u64: 0x0 Processing message: VHOST_USER_SET_VRING_CALL _set_vring_call Got callfd 0x5 Cmd: VHOST_USER_SET_VRING_CALL (0xd) Flags: 0x1 u64: 0x1 Processing message: VHOST_USER_SET_VRING_CALL _set_vring_call Got callfd 0x6 Cmd: VHOST_USER_SET_FEATURES (0x2) Flags: 0x1 u64: 0x0 Processing message: VHOST_USER_SET_FEATURES _set_features Cmd: VHOST_USER_SET_MEM_TABLE (0x5) Flags: 0x1 nregions: 2 region: gpa = 0x0 size = 655360 ua = 0x7f76c000 [0] region: gpa = 0xC size = 2146697216 ua = 0x7f76c00c [1] Processing message: VHOST_USER_SET_MEM_TABLE _set_mem_table mmap: Invalid argument //@@@ region 0 mmap
Re: [Qemu-devel] [PATCH v2 08/12] hpet: fixing saving and loading process
From: Paolo Bonzini [mailto:paolo.bonz...@gmail.com] On Behalf Of Paolo Bonzini Il 28/08/2014 13:58, Paolo Bonzini ha scritto: This also breaks migration to 2.1, unless you use -no-hpet. Actually, this is also only needed for your record/replay implementation. Ok, I'll move it to the replay series. Pavel Dovgalyuk
[Qemu-devel] [PATCH 01/10] vl: use QLIST_FOREACH_SAFE to visit change state handlers
This lets a handler delete itself. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- vl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vl.c b/vl.c index 9c9acf5..15aea95 100644 --- a/vl.c +++ b/vl.c @@ -1721,11 +1721,11 @@ void qemu_del_vm_change_state_handler(VMChangeStateEntry *e) void vm_state_notify(int running, RunState state) { -VMChangeStateEntry *e; +VMChangeStateEntry *e, *next; trace_vm_state_notify(running, state); -for (e = vm_change_state_head.lh_first; e; e = e-entries.le_next) { +QLIST_FOREACH_SAFE(e, vm_change_state_head, entries, next) { e-cb(e-opaque, running, state); } } -- 2.1.0
[Qemu-devel] [PATCH 02/10] apic_common: vapic_paddr synchronization fix
From: Pavel Dovgalyuk pavel.dovga...@ispras.ru This patch postpones vapic_paddr initialization, which is performed during migration. When vapic_paddr is synchronized within the migration process, apic_common functions could operate with incorrect apic state, if it hadn't loaded yet. This patch postpones the synchronization until the virtual machine is started, ensuring that the whole virtual machine state has been loaded. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/i386/kvmvapic.c | 37 ++--- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index ee95963..2bcc249 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -59,6 +59,7 @@ typedef struct VAPICROMState { GuestROMState rom_state; size_t rom_size; bool rom_mapped_writable; +VMChangeStateEntry *vmsentry; } VAPICROMState; #define TYPE_VAPIC kvmvapic @@ -734,11 +735,34 @@ static void do_vapic_enable(void *data) vapic_enable(s, cpu); } -static int vapic_post_load(void *opaque, int version_id) +static void kvmvapic_vm_state_change(void *opaque, int running, +RunState state) { VAPICROMState *s = opaque; uint8_t *zero; +if (!running) { +return; +} + +if (s-state == VAPIC_ACTIVE) { +if (smp_cpus == 1) { +run_on_cpu(first_cpu, do_vapic_enable, s); +} else { +zero = g_malloc0(s-rom_state.vapic_size); +cpu_physical_memory_write(s-vapic_paddr, zero, + s-rom_state.vapic_size); +g_free(zero); +} +} + +qemu_del_vm_change_state_handler(s-vmsentry); +} + +static int vapic_post_load(void *opaque, int version_id) +{ +VAPICROMState *s = opaque; + /* * The old implementation of qemu-kvm did not provide the state * VAPIC_STANDBY. Reconstruct it. @@ -752,17 +776,8 @@ static int vapic_post_load(void *opaque, int version_id) return -1; } } -if (s-state == VAPIC_ACTIVE) { -if (smp_cpus == 1) { -run_on_cpu(first_cpu, do_vapic_enable, s); -} else { -zero = g_malloc0(s-rom_state.vapic_size); -cpu_physical_memory_write(s-vapic_paddr, zero, - s-rom_state.vapic_size); -g_free(zero); -} -} +s-vmsentry = qemu_add_vm_change_state_handler(kvmvapic_vm_state_change, s); return 0; } -- 2.1.0
[Qemu-devel] [PATCH 03/10] cpu: init vmstate for ticks and clock offset
From: Pavel Dovgalyuk pavel.dovga...@ispras.ru Ticks and clock offset used by CPU timers have to be saved in vmstate. But vmstate for these fields registered only in icount mode. Missing registration leads to breaking the continuity when vmstate is loaded. This patch introduces new initialization function which fixes this. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- cpus.c| 8 ++-- include/qemu-common.h | 2 ++ vl.c | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/cpus.c b/cpus.c index 0f7d0ea..2a0e133 100644 --- a/cpus.c +++ b/cpus.c @@ -493,13 +493,17 @@ static const VMStateDescription vmstate_timers = { } }; +void cpu_ticks_init(void) +{ +seqlock_init(timers_state.vm_clock_seqlock, NULL); +vmstate_register(NULL, 0, vmstate_timers, timers_state); +} + void configure_icount(QemuOpts *opts, Error **errp) { const char *option; char *rem_str = NULL; -seqlock_init(timers_state.vm_clock_seqlock, NULL); -vmstate_register(NULL, 0, vmstate_timers, timers_state); option = qemu_opt_get(opts, shift); if (!option) { if (qemu_opt_get(opts, align) != NULL) { diff --git a/include/qemu-common.h b/include/qemu-common.h index bcf7a6a..dcb57ab 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -105,6 +105,8 @@ static inline char *realpath(const char *path, char *resolved_path) } #endif +void cpu_ticks_init(void); + /* icount */ void configure_icount(QemuOpts *opts, Error **errp); extern int use_icount; diff --git a/vl.c b/vl.c index 15aea95..5db0d08 100644 --- a/vl.c +++ b/vl.c @@ -4334,6 +4334,7 @@ int main(int argc, char **argv, char **envp) qemu_spice_init(); #endif +cpu_ticks_init(); if (icount_opts) { if (kvm_enabled() || xen_enabled()) { fprintf(stderr, -icount is not allowed with kvm or xen\n); -- 2.1.0
[Qemu-devel] [PATCH 05/10] fdc: adding vmstate for save/restore
From: Pavel Dovgalyuk pavel.dovga...@ispras.ru VMState added by this patch preserves correct loading of the FDC device state. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/block/fdc.c | 74 ++ 1 file changed, 74 insertions(+) diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 490d127..6c86a6b 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -695,10 +695,34 @@ static const VMStateDescription vmstate_fdrive_media_rate = { } }; +static bool fdrive_perpendicular_needed(void *opaque) +{ +FDrive *drive = opaque; + +return drive-perpendicular != 0; +} + +static const VMStateDescription vmstate_fdrive_perpendicular = { +.name = fdrive/perpendicular, +.version_id = 1, +.minimum_version_id = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT8(perpendicular, FDrive), +VMSTATE_END_OF_LIST() +} +}; + +static int fdrive_post_load(void *opaque, int version_id) +{ +fd_revalidate(opaque); +return 0; +} + static const VMStateDescription vmstate_fdrive = { .name = fdrive, .version_id = 1, .minimum_version_id = 1, +.post_load = fdrive_post_load, .fields = (VMStateField[]) { VMSTATE_UINT8(head, FDrive), VMSTATE_UINT8(track, FDrive), @@ -713,6 +737,9 @@ static const VMStateDescription vmstate_fdrive = { .vmsd = vmstate_fdrive_media_rate, .needed = fdrive_media_rate_needed, } , { +.vmsd = vmstate_fdrive_perpendicular, +.needed = fdrive_perpendicular_needed, +} , { /* empty */ } } @@ -734,6 +761,40 @@ static int fdc_post_load(void *opaque, int version_id) return 0; } +static bool fdc_reset_sensei_needed(void *opaque) +{ +FDCtrl *s = opaque; + +return s-reset_sensei != 0; +} + +static const VMStateDescription vmstate_fdc_reset_sensei = { +.name = fdc/reset_sensei, +.version_id = 1, +.minimum_version_id = 1, +.fields = (VMStateField[]) { +VMSTATE_INT32(reset_sensei, FDCtrl), +VMSTATE_END_OF_LIST() +} +}; + +static bool fdc_result_timer_needed(void *opaque) +{ +FDCtrl *s = opaque; + +return timer_pending(s-result_timer); +} + +static const VMStateDescription vmstate_fdc_result_timer = { +.name = fdc/result_timer, +.version_id = 1, +.minimum_version_id = 1, +.fields = (VMStateField[]) { +VMSTATE_TIMER(result_timer, FDCtrl), +VMSTATE_END_OF_LIST() +} +}; + static const VMStateDescription vmstate_fdc = { .name = fdc, .version_id = 2, @@ -770,6 +831,17 @@ static const VMStateDescription vmstate_fdc = { VMSTATE_STRUCT_ARRAY(drives, FDCtrl, MAX_FD, 1, vmstate_fdrive, FDrive), VMSTATE_END_OF_LIST() +}, +.subsections = (VMStateSubsection[]) { +{ +.vmsd = vmstate_fdc_reset_sensei, +.needed = fdc_reset_sensei_needed, +} , { +.vmsd = vmstate_fdc_result_timer, +.needed = fdc_result_timer_needed, +} , { +/* empty */ +} } }; @@ -844,6 +916,8 @@ static void fdctrl_reset(FDCtrl *fdctrl, int do_irq) fdctrl-dor = FD_DOR_nRESET; fdctrl-dor |= (fdctrl-dma_chann != -1) ? FD_DOR_DMAEN : 0; fdctrl-msr = FD_MSR_RQM; +fdctrl-reset_sensei = 0; +timer_del(fdctrl-result_timer); /* FIFO state */ fdctrl-data_pos = 0; fdctrl-data_len = 0; -- 2.1.0
[Qemu-devel] [PATCH 00/10] x86: migrate more data
Juan, David, Amit, here are Pavel's fixes for x86 migration. Please help applying them, or ack them so that I can merge them through the KVM tree. Thanks, Paolo Paolo Bonzini (1): vl: use QLIST_FOREACH_SAFE to visit change state handlers Pavel Dovgalyuk (9): apic_common: vapic_paddr synchronization fix cpu: init vmstate for ticks and clock offset pcspk: adding vmstate for save/restore fdc: adding vmstate for save/restore parallel: adding vmstate for save/restore serial: fixing vmstate for save/restore pckbd: adding new fields to vmstate piix: do not raise irq while loading vmstate mc146818rtc: add missed field to vmstate cpus.c | 8 +- hw/audio/pcspk.c | 16 ++- hw/block/fdc.c | 74 ++ hw/char/parallel.c | 18 hw/char/serial.c | 265 - hw/i386/kvmvapic.c | 37 +-- hw/input/pckbd.c | 51 ++ hw/pci-host/piix.c | 26 - hw/timer/mc146818rtc.c | 25 + include/qemu-common.h | 2 + vl.c | 5 +- 12 files changed, 463 insertions(+), 64 deletions(-) -- 2.1.0
[Qemu-devel] [PATCH 04/10] pcspk: adding vmstate for save/restore
From: Pavel Dovgalyuk pavel.dovga...@ispras.ru VMState added by this patch preserves correct loading of the PC speaker device state. This breaks migration to 2.1 and earlier. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/audio/pcspk.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c index 1d81bbe..62dfabe 100644 --- a/hw/audio/pcspk.c +++ b/hw/audio/pcspk.c @@ -50,8 +50,8 @@ typedef struct { unsigned int pit_count; unsigned int samples; unsigned int play_pos; -int data_on; -int dummy_refresh_clock; +uint8_t data_on; +uint8_t dummy_refresh_clock; } PCSpkState; static const char *s_spk = pcspk; @@ -163,6 +163,17 @@ static const MemoryRegionOps pcspk_io_ops = { }, }; +static const VMStateDescription vmstate_spk = { +.name = pcspk, +.version_id = 1, +.minimum_version_id = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT8(data_on, PCSpkState), +VMSTATE_UINT8(dummy_refresh_clock, PCSpkState), +VMSTATE_END_OF_LIST() +} +}; + static void pcspk_initfn(Object *obj) { PCSpkState *s = PC_SPEAKER(obj); @@ -192,6 +203,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data) dc-realize = pcspk_realizefn; set_bit(DEVICE_CATEGORY_SOUND, dc-categories); +dc-vmsd = vmstate_spk; dc-props = pcspk_properties; /* Reason: pointer property pit, realize sets global pcspk_state */ dc-cannot_instantiate_with_device_add_yet = true; -- 2.1.0
[Qemu-devel] [PATCH 06/10] parallel: adding vmstate for save/restore
From: Pavel Dovgalyuk pavel.dovga...@ispras.ru VMState added by this patch preserves correct loading of the parallel port controller state. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/char/parallel.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/hw/char/parallel.c b/hw/char/parallel.c index 7ac90a5..c2b553f 100644 --- a/hw/char/parallel.c +++ b/hw/char/parallel.c @@ -477,6 +477,23 @@ static const MemoryRegionPortio isa_parallel_portio_sw_list[] = { PORTIO_END_OF_LIST(), }; + +static const VMStateDescription vmstate_parallel_isa = { +.name = parallel_isa, +.version_id = 1, +.minimum_version_id = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT8(state.dataw, ISAParallelState), +VMSTATE_UINT8(state.datar, ISAParallelState), +VMSTATE_UINT8(state.status, ISAParallelState), +VMSTATE_UINT8(state.control, ISAParallelState), +VMSTATE_INT32(state.irq_pending, ISAParallelState), +VMSTATE_INT32(state.epp_timeout, ISAParallelState), +VMSTATE_END_OF_LIST() +} +}; + + static void parallel_isa_realizefn(DeviceState *dev, Error **errp) { static int index; @@ -606,6 +623,7 @@ static void parallel_isa_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc-realize = parallel_isa_realizefn; +dc-vmsd = vmstate_parallel_isa; dc-props = parallel_isa_properties; set_bit(DEVICE_CATEGORY_INPUT, dc-categories); } -- 2.1.0
[Qemu-devel] [PATCH 08/10] pckbd: adding new fields to vmstate
From: Pavel Dovgalyuk pavel.dovga...@ispras.ru This patch adds outport to VMState to allow correct saving and restoring the state of PC keyboard controller. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/input/pckbd.c | 51 +++ 1 file changed, 51 insertions(+) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 2ab8c87..2b0cd3d 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -131,6 +131,7 @@ typedef struct KBDState { uint8_t status; uint8_t mode; uint8_t outport; +bool outport_present; /* Bitmask of devices with data available. */ uint8_t pending; void *kbd; @@ -367,18 +368,68 @@ static void kbd_reset(void *opaque) s-mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; s-status = KBD_STAT_CMD | KBD_STAT_UNLOCKED; s-outport = KBD_OUT_RESET | KBD_OUT_A20; +s-outport_present = false; +} + +static uint8_t kbd_outport_default(KBDState *s) +{ +return KBD_OUT_RESET | KBD_OUT_A20 + | (s-status KBD_STAT_OBF ? KBD_OUT_OBF : 0) + | (s-status KBD_STAT_MOUSE_OBF ? KBD_OUT_MOUSE_OBF : 0); +} + +static int kbd_outport_post_load(void *opaque, int version_id) +{ +KBDState *s = opaque; +s-outport_present = true; +return 0; +} + +static const VMStateDescription vmstate_kbd_outport = { +.name = pckbd_outport, +.version_id = 1, +.minimum_version_id = 1, +.post_load = kbd_outport_post_load, +.fields = (VMStateField[]) { +VMSTATE_UINT8(outport, KBDState), +VMSTATE_END_OF_LIST() +} +}; + +static bool kbd_outport_needed(void *opaque) +{ +KBDState *s = opaque; +return s-outport != kbd_outport_default(s); +} + +static int kbd_post_load(void *opaque, int version_id) +{ +KBDState *s = opaque; +if (!s-outport_present) { +s-outport = kbd_outport_default(s); +} +s-outport_present = false; +return 0; } static const VMStateDescription vmstate_kbd = { .name = pckbd, .version_id = 3, .minimum_version_id = 3, +.post_load = kbd_post_load, .fields = (VMStateField[]) { VMSTATE_UINT8(write_cmd, KBDState), VMSTATE_UINT8(status, KBDState), VMSTATE_UINT8(mode, KBDState), VMSTATE_UINT8(pending, KBDState), VMSTATE_END_OF_LIST() +}, +.subsections = (VMStateSubsection[]) { +{ +.vmsd = vmstate_kbd_outport, +.needed = kbd_outport_needed, +}, +VMSTATE_END_OF_LIST() } }; -- 2.1.0
[Qemu-devel] [PATCH 07/10] serial: fixing vmstate for save/restore
From: Pavel Dovgalyuk pavel.dovga...@ispras.ru Some fields were added to VMState by this patch to preserve correct loading of the serial port controller state. Updating FCR value while loading was also modified to disable generating an interrupt by loadvm. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/char/serial.c | 265 +-- 1 file changed, 220 insertions(+), 45 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index 764e184..2b04927 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -272,6 +272,64 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) } +/* Setter for FCR. + is_load flag means, that value is set while loading VM state + and interrupt should not be invoked */ +static void serial_write_fcr(void *opaque, uint32_t val, int is_load) +{ +SerialState *s = opaque; +val = val 0xFF; + +if (s-fcr == val) { +return; +} + +/* Did the enable/disable flag change? If so, make sure FIFOs get flushed */ +if ((val ^ s-fcr) UART_FCR_FE) { +val |= UART_FCR_XFR | UART_FCR_RFR; +} + +/* FIFO clear */ + +if (val UART_FCR_RFR) { +timer_del(s-fifo_timeout_timer); +s-timeout_ipending = 0; +fifo8_reset(s-recv_fifo); +} + +if (val UART_FCR_XFR) { +fifo8_reset(s-xmit_fifo); +} + +if (val UART_FCR_FE) { +s-iir |= UART_IIR_FE; +/* Set recv_fifo trigger Level */ +switch (val 0xC0) { +case UART_FCR_ITL_1: +s-recv_fifo_itl = 1; +break; +case UART_FCR_ITL_2: +s-recv_fifo_itl = 4; +break; +case UART_FCR_ITL_3: +s-recv_fifo_itl = 8; +break; +case UART_FCR_ITL_4: +s-recv_fifo_itl = 14; +break; +} +} else { +s-iir = ~UART_IIR_FE; +} + +/* Set fcr - or at least the bits in it that are supposed to stick */ +s-fcr = val 0xC9; + +if (!is_load) { +serial_update_irq(s); +} +} + static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { @@ -327,50 +385,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, } break; case 2: -val = val 0xFF; - -if (s-fcr == val) -break; - -/* Did the enable/disable flag change? If so, make sure FIFOs get flushed */ -if ((val ^ s-fcr) UART_FCR_FE) -val |= UART_FCR_XFR | UART_FCR_RFR; - -/* FIFO clear */ - -if (val UART_FCR_RFR) { -timer_del(s-fifo_timeout_timer); -s-timeout_ipending=0; -fifo8_reset(s-recv_fifo); -} - -if (val UART_FCR_XFR) { -fifo8_reset(s-xmit_fifo); -} - -if (val UART_FCR_FE) { -s-iir |= UART_IIR_FE; -/* Set recv_fifo trigger Level */ -switch (val 0xC0) { -case UART_FCR_ITL_1: -s-recv_fifo_itl = 1; -break; -case UART_FCR_ITL_2: -s-recv_fifo_itl = 4; -break; -case UART_FCR_ITL_3: -s-recv_fifo_itl = 8; -break; -case UART_FCR_ITL_4: -s-recv_fifo_itl = 14; -break; -} -} else -s-iir = ~UART_IIR_FE; - -/* Set fcr - or at least the bits in it that are supposed to stick */ -s-fcr = val 0xC9; -serial_update_irq(s); +serial_write_fcr(s, val, 0); break; case 3: { @@ -590,6 +605,14 @@ static void serial_pre_save(void *opaque) s-fcr_vmstate = s-fcr; } +static int serial_pre_load(void *opaque) +{ +SerialState *s = (SerialState *)opaque; +s-thr_ipending = -1; +s-poll_msl = -1; +return 0; +} + static int serial_post_load(void *opaque, int version_id) { SerialState *s = opaque; @@ -597,17 +620,139 @@ static int serial_post_load(void *opaque, int version_id) if (version_id 3) { s-fcr_vmstate = 0; } +if (s-thr_ipending == -1) { +s-thr_ipending = ((s-iir UART_IIR_ID) == UART_IIR_THRI); +} +s-last_break_enable = (s-lcr 6) 1; /* Initialize fcr via setter to perform essential side-effects */ -serial_ioport_write(s, 0x02, s-fcr_vmstate, 1); +serial_write_fcr(s, s-fcr_vmstate, 1); serial_update_parameters(s); return 0; } +static bool serial_thr_ipending_needed(void *opaque) +{ +SerialState *s = opaque; +bool expected_value = ((s-iir UART_IIR_ID) == UART_IIR_THRI); +return s-thr_ipending != expected_value; +} + +const VMStateDescription vmstate_serial_thr_ipending = { +.name = serial/thr_ipending, +.version_id = 1, +.minimum_version_id = 1, +
[Qemu-devel] [PATCH 10/10] mc146818rtc: add missed field to vmstate
From: Pavel Dovgalyuk pavel.dovga...@ispras.ru This patch adds irq_reinject_on_ack_count field to VMState to allow correct saving/loading the state of MC146818 RTC. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/timer/mc146818rtc.c | 24 + 1 file changed, 24 insertions(+) diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 17912b8..2c4b650 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -733,6 +733,22 @@ static int rtc_post_load(void *opaque, int version_id) return 0; } +static const VMStateDescription vmstate_rtc_irq_reinject_on_ack_count = { +.name = irq_reinject_on_ack_count, +.version_id = 1, +.minimum_version_id = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT16(irq_reinject_on_ack_count, RTCState), +VMSTATE_END_OF_LIST() +} +}; + +static bool rtc_irq_reinject_on_ack_count_needed(void *opaque) +{ +RTCState *s = (RTCState *)opaque; +return s-irq_reinject_on_ack_count != 0; +} + static const VMStateDescription vmstate_rtc = { .name = mc146818rtc, .version_id = 3, @@ -753,6 +769,14 @@ static const VMStateDescription vmstate_rtc = { VMSTATE_TIMER_V(update_timer, RTCState, 3), VMSTATE_UINT64_V(next_alarm_time, RTCState, 3), VMSTATE_END_OF_LIST() +}, +.subsections = (VMStateSubsection[]) { +{ +.vmsd = vmstate_rtc_irq_reinject_on_ack_count, +.needed = rtc_irq_reinject_on_ack_count_needed, +}, { +/* empty */ +} } }; -- 2.1.0
[Qemu-devel] [PATCH 09/10] piix: do not raise irq while loading vmstate
From: Pavel Dovgalyuk pavel.dovga...@ispras.ru This patch disables raising an irq while loading the state of PCI bridge. The aim of this patch is preserving the same behavior while saving and restoring the VM state. IRQ is not raised while saving the state of the bridge. That's why the behavior of the restored system will differ from the original one. This patch eliminates raising an irq and just restores the calculated state fields in post_load function. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/pci-host/piix.c | 26 -- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index e0e0946..cd50435 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -409,7 +409,7 @@ static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq) (pic_irq * PIIX_NUM_PIRQS; } -static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level) +static void piix3_set_irq_level_internal(PIIX3State *piix3, int pirq, int level) { int pic_irq; uint64_t mask; @@ -422,6 +422,18 @@ static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level) mask = 1ULL ((pic_irq * PIIX_NUM_PIRQS) + pirq); piix3-pic_levels = ~mask; piix3-pic_levels |= mask * !!level; +} + +static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level) +{ +int pic_irq; + +pic_irq = piix3-dev.config[PIIX_PIRQC + pirq]; +if (pic_irq = PIIX_NUM_PIC_IRQS) { +return; +} + +piix3_set_irq_level_internal(piix3, pirq, level); piix3_set_irq_pic(piix3, pic_irq); } @@ -527,7 +539,18 @@ static void piix3_reset(void *opaque) static int piix3_post_load(void *opaque, int version_id) { PIIX3State *piix3 = opaque; -piix3_update_irq_levels(piix3); +int pirq; + +/* Update irq levels without raising an interrupt which could + * happen in piix3_update_irq_levels. Raising an IRQ will + * bring the system to a different state than the saved one. + * Interrupt state is serialized separately through the i8259. + */ +piix3-pic_levels = 0; +for (pirq = 0; pirq PIIX_NUM_PIRQS; pirq++) { +piix3_set_irq_level_internal(piix3, pirq, +pci_bus_get_irq_level(piix3-dev.bus, pirq)); +} return 0; } -- 2.1.0
Re: [Qemu-devel] [PATCH] block: extend BLOCK_IO_ERROR event with nospace indicator
On 09/09/2014 02:27 AM, Kevin Wolf wrote: What was our conclusion wrt the human-readable strerror() string for debugging? Didn't we want to add that as well? I can do it on top of this patch. So, just adding a new field for this is fine? I think so. Perhaps we should give it an 'x-' name to make clear that it's a debugging help and not supposed to be parsed by management tools. Or would that be abuse of that namespace? I think using x- would be okay for the namespace, but am not sure we need to go that far. We already have other fields without x- that are documented as human-readable only; for example, CommandLineParameterInfo has: # @help: #optional human readable text string, not suitable for parsing. or in our events, QUORUM_REPORT_BAD has: # @error: #optional, error message. Only present on failure. This field # contains a human-readable error message. There are no semantics other # than that the block layer reported an error and clients should not # try to interpret the error string. So I'd be fine with something as simple as 'message' or 'error'. The alternative solution (or actually we could do both) would be to store it somewhere in bs and put it into query-block. Enhancing query-block in addition to the event makes sense, if it is easy enough to do. At this point, we are talking about debugging aids, so as long as they are documented appropriately, I won't be too fussy. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH v14 3/5] qapi: introduce PreallocMode and new PreallocModes full and falloc.
On 09/08/2014 09:54 PM, Hu Tao wrote: This patch prepares for the subsequent patches. Signed-off-by: Hu Tao hu...@cn.fujitsu.com Reviewed-by: Max Reitz mre...@redhat.com Reviewed-by: Kevin Wolf kw...@redhat.com --- block/qcow2.c | 23 +++ qapi/block-core.json | 17 + tests/qemu-iotests/049.out | 2 +- 3 files changed, 33 insertions(+), 9 deletions(-) buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); -if (!buf || !strcmp(buf, off)) { -prealloc = 0; -} else if (!strcmp(buf, metadata)) { -prealloc = 1; -} else { -error_setg(errp, Invalid preallocation mode: '%s', buf); +prealloc = qapi_enum_parse(PreallocMode_lookup, buf, + PREALLOC_MODE_MAX, PREALLOC_MODE_OFF, + local_err); +if (local_err) { +error_propagate(errp, local_err); ret = -EINVAL; goto finish; } @@ -1958,6 +1958,13 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) flags |= BLOCK_FLAG_LAZY_REFCOUNTS; } +if (prealloc prealloc != PREALLOC_MODE_METADATA) { +ret = -EINVAL; +error_setg(errp, Unsupported preallocate mode: %s, + PreallocMode_lookup[prealloc]); +goto finish; +} I _still_ think this looks weird, and would be better as either: if (prealloc != PREALLOC_MODE_NONE prealloc != PREALLOC_MODE_METADATA) { to make it obvious that you are filtering for two acceptable modes, or as: if (prealloc == PREALLOC_MODE_FALLOC || prealloc == PREALLOC_MODE_FULL) { to make it obvious the modes that you do not support. But my complaint is not strong enough to prevent this patch, especially if later in the series revisits this code. Reviewed-by: Eric Blake ebl...@redhat.com -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH] block: extend BLOCK_IO_ERROR event with nospace indicator
On Tue, 09 Sep 2014 06:37:31 -0600 Eric Blake ebl...@redhat.com wrote: On 09/09/2014 02:27 AM, Kevin Wolf wrote: What was our conclusion wrt the human-readable strerror() string for debugging? Didn't we want to add that as well? I can do it on top of this patch. So, just adding a new field for this is fine? I think so. Perhaps we should give it an 'x-' name to make clear that it's a debugging help and not supposed to be parsed by management tools. Or would that be abuse of that namespace? I think using x- would be okay for the namespace, but am not sure we need to go that far. We already have other fields without x- that are documented as human-readable only; for example, CommandLineParameterInfo has: # @help: #optional human readable text string, not suitable for parsing. or in our events, QUORUM_REPORT_BAD has: # @error: #optional, error message. Only present on failure. This field # contains a human-readable error message. There are no semantics other # than that the block layer reported an error and clients should not # try to interpret the error string. So I'd be fine with something as simple as 'message' or 'error'. The alternative solution (or actually we could do both) would be to store it somewhere in bs and put it into query-block. Enhancing query-block in addition to the event makes sense, if it is easy enough to do. At this point, we are talking about debugging aids, so as long as they are documented appropriately, I won't be too fussy. OK, but I'm wondering if we need to add the string field to both, BLOCK_IO_ERROR and query-block, or only to one to the other. In my opinion, we should only add it to BLOCK_IO_ERROR if libvirt is going to consume. Otherwise, it makes more sense to add it to query-block because that's where we'll meet the user. Btw, by consume I mean read it and make it available to libvirt clients so that they can print it to their users. If we don't want libvirt to consume that field then I think we should only add it to query-block and info block.
Re: [Qemu-devel] [RFC V2 03/10] cpu: add device_add foo-x86_64-cpu support
On Thu, 28 Aug 2014 11:36:35 +0800 Gu Zheng guz.f...@cn.fujitsu.com wrote: From: Chen Fan chen.fan.f...@cn.fujitsu.com Add support to device_add foo-x86_64-cpu, and additional checks of apic id are added into x86_cpuid_set_apic_id() and x86_cpu_apic_create() for duplicate. Besides, in order to support device/device_add foo-x86_64-cpu which without specified apic id, we add a new function get_free_apic_id() to provide the first free apid id each time to avoid apic id duplicate. Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com Signed-off-by: Gu Zheng guz.f...@cn.fujitsu.com --- include/qom/cpu.h |1 + qdev-monitor.c |1 + target-i386/cpu.c | 61 +++- target-i386/topology.h | 18 ++ 4 files changed, 80 insertions(+), 1 deletions(-) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index bc32c9a..2fc00ef 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -292,6 +292,7 @@ struct CPUState { QTAILQ_HEAD(CPUTailQ, CPUState); extern struct CPUTailQ cpus; #define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node) +#define CPU_REMOVE(cpu) QTAILQ_REMOVE(cpus, cpu, node) #define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, cpus, node) #define CPU_FOREACH_SAFE(cpu, next_cpu) \ QTAILQ_FOREACH_SAFE(cpu, cpus, node, next_cpu) diff --git a/qdev-monitor.c b/qdev-monitor.c index fb9ee24..1aa446d 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -24,6 +24,7 @@ #include qmp-commands.h #include sysemu/arch_init.h #include qemu/config-file.h +#include qom/object_interfaces.h /* * Aliases were a bad idea from the start. Let's keep them diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 2aa2b31..5255ddb 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -49,6 +49,7 @@ #include hw/i386/apic_internal.h #endif +#include qom/object_interfaces.h This probably belongs to another patch. /* Cache topology CPUID constants: */ @@ -1634,6 +1635,7 @@ static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque, const int64_t max = UINT32_MAX; Error *error = NULL; int64_t value; +X86CPUTopoInfo topo; if (dev-realized) { error_setg(errp, Attempt to set property '%s' on '%s' after @@ -1653,6 +1655,19 @@ static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque, return; } +if (value x86_cpu_apic_id_from_index(max_cpus - 1)) { +error_setg(errp, CPU with APIC ID % PRIi64 +is more than MAX APIC ID limits, value); +return; +} + +x86_topo_ids_from_apic_id(smp_cores, smp_threads, value, topo); +if (topo.smt_id = smp_threads || topo.core_id = smp_cores) { +error_setg(errp, CPU with APIC ID % PRIi64 does not match + topology configuration., value); +return; +} + if ((value != cpu-env.cpuid_apic_id) cpu_exists(value)) { error_setg(errp, CPU with APIC ID % PRIi64 exists, value); return; @@ -2096,12 +2111,21 @@ out: return cpu; } +static void x86_cpu_cpudef_instance_init(Object *obj) +{ +DeviceState *dev = DEVICE(obj); + +dev-hotplugged = true; +} looks unnecessary, see device_initfn() which already does above. + static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data) { X86CPUDefinition *cpudef = data; X86CPUClass *xcc = X86_CPU_CLASS(oc); +DeviceClass *dc = DEVICE_CLASS(oc); xcc-cpu_def = cpudef; +dc-cannot_instantiate_with_device_add_yet = false; } static void x86_register_cpudef_type(X86CPUDefinition *def) @@ -2110,6 +2134,8 @@ static void x86_register_cpudef_type(X86CPUDefinition *def) TypeInfo ti = { .name = typename, .parent = TYPE_X86_CPU, +.instance_size = sizeof(X86CPU), +.instance_init = x86_cpu_cpudef_instance_init, this hunk is not needed, providing x86_cpu_cpudef_instance_init() is not necessary. .class_init = x86_cpu_cpudef_class_init, .class_data = def, }; @@ -2652,6 +2678,14 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp) return; } +if (env-cpuid_apic_id x86_cpu_apic_id_from_index(max_cpus - 1)) { +error_setg(errp, CPU with APIC ID % PRIi32 + is more than MAX APIC ID:% PRIi32, +env-cpuid_apic_id, +x86_cpu_apic_id_from_index(max_cpus - 1)); +return; +} use property apic-id here that has checks instead of duplicating them. + object_property_add_child(OBJECT(cpu), apic, OBJECT(cpu-apic_state), NULL); qdev_prop_set_uint8(cpu-apic_state, id, env-cpuid_apic_id); @@ -2777,6 +2811,21 @@ uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index) } } +static uint32_t get_free_apic_id(void) +{ +int i; + +
Re: [Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5
On Tue, Sep 9, 2014 at 6:23 PM, Alistair Francis alistai...@gmail.com wrote: This patch adds the stm32f205 timers: TIM2, TIM3, TIM4 and TIM5 to QEMU. Signed-off-by: Alistair Francis alistai...@gmail.com --- V2: - Small changes to functionality and style. Thanks to Peter C - Rename for the Netduino 2 and it's SoC default-configs/arm-softmmu.mak| 1 + hw/timer/Makefile.objs | 1 + hw/timer/stm32f205_timer.c | 334 + include/hw/timer/stm32f205_timer.h | 84 ++ 4 files changed, 420 insertions(+) create mode 100644 hw/timer/stm32f205_timer.c create mode 100644 include/hw/timer/stm32f205_timer.h diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index f3513fa..8550084 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -78,6 +78,7 @@ CONFIG_NSERIES=y CONFIG_REALVIEW=y CONFIG_ZAURUS=y CONFIG_ZYNQ=y +CONFIG_NETDUINO2=y I think we were moving aware from SoC level shared configs, i.e. it's ok to have a confing per-dev in the arm-softmmu defconfig. You also want to avoid tying the device (and the SoC) to netduino as much as possible so even if CONFIG_NETDUINO existed it would simply set another config for STM etc. Easiest to just go flat with one config per dev (the ZYNQ example right above does do it wrong too :( ). CONFIG_VERSATILE_PCI=y CONFIG_VERSATILE_I2C=y diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index 2c86c3d..ce68c4a 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -17,6 +17,7 @@ common-obj-$(CONFIG_IMX) += imx_epit.o common-obj-$(CONFIG_IMX) += imx_gpt.o common-obj-$(CONFIG_LM32) += lm32_timer.o common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o +common-obj-$(CONFIG_NETDUINO2) += stm32f205_timer.o obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o obj-$(CONFIG_EXYNOS4) += exynos4210_pwm.o diff --git a/hw/timer/stm32f205_timer.c b/hw/timer/stm32f205_timer.c new file mode 100644 index 000..bbeaf6b --- /dev/null +++ b/hw/timer/stm32f205_timer.c @@ -0,0 +1,334 @@ +/* + * STM32F205xx Timer 2 to 5 + * Looking at the TRM i notice some of the other timers may be similar. Are TIM9-14 potentially modellable with a slight parameterisation of this? I think its ok in first series to limit functionality to TIM2-5 but you should soften the naming, probably just to stm32f205_timer throughout (removing all ref to TIM2-5) and leave this 2-5 1/8 9-13 configury to the SoC level. + * Copyright (c) 2014 Alistair Francis alist...@alistair23.me + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include hw/timer/stm32f205_timer.h + +#ifndef ST_TIM2_5_ERR_DEBUG +#define ST_TIM2_5_ERR_DEBUG 0 +#endif + +#define DB_PRINT_L(lvl, fmt, args...) do { \ +if (ST_TIM2_5_ERR_DEBUG = lvl) { \ +fprintf(stderr, stm32f205xx_timer: %s: fmt, __func__, ## args); \ qemu_log() +} \ +} while (0); + +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args) + +static void stm32f205xx_timer_update(Stm32f205TimerState *s) +{ +s-tim_sr |= 1; +qemu_irq_pulse(s-irq); +} This only serves the purpose of interrupt assertion on the timer callback below and is single use. Just inline it. + +static void stm32f205xx_timer_interrupt(void *opaque) +{ +Stm32f205TimerState *s = (Stm32f205TimerState *)opaque; + No explicit cast needed. +DB_PRINT(Interrupt in: %s\n, __func__); + +if (s-tim_dier == 0x01 s-tim_cr1 TIM_CR1_CEN) { The UIE bit of dier is only a single bit so you should use a mask and macro (just like with TIM_CR1_CEN). +stm32f205xx_timer_update(s); +} +} + +static uint32_t stm32f205xx_timer_get_count(Stm32f205TimerState *s) +{ +int64_t now = qemu_clock_get_ns(rtc_clock); Why use the RTC rather than the virtual clock? Most timer use the virtual unless they are
Re: [Qemu-devel] [PATCH v14 3/5] qapi: introduce PreallocMode and new PreallocModes full and falloc.
The Tuesday 09 Sep 2014 à 11:54:29 (+0800), Hu Tao wrote : This patch prepares for the subsequent patches. Signed-off-by: Hu Tao hu...@cn.fujitsu.com Reviewed-by: Max Reitz mre...@redhat.com Reviewed-by: Kevin Wolf kw...@redhat.com --- block/qcow2.c | 23 +++ qapi/block-core.json | 17 + tests/qemu-iotests/049.out | 2 +- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index cf27c3f..94d1225 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -30,6 +30,7 @@ #include qemu/error-report.h #include qapi/qmp/qerror.h #include qapi/qmp/qbool.h +#include qapi/util.h #include trace.h #include qemu/option_int.h @@ -1738,7 +1739,7 @@ static int preallocate(BlockDriverState *bs) static int qcow2_create2(const char *filename, int64_t total_size, const char *backing_file, const char *backing_format, - int flags, size_t cluster_size, int prealloc, + int flags, size_t cluster_size, PreallocMode prealloc, QemuOpts *opts, int version, Error **errp) below that. Carefull study of the code tell us that here prealloc will be 0 or 1 but i think you could prepare a bit sooner the next patch by doing: -if (prealloc) { +if (prealloc == PREALLOC_MODE_METADATA) { BDRVQcowState *s = bs-opaque; in the same qcow2_create2 function. If you do so someone who start reading the code at this precise commit will not have to lookup the declaration order of PreallocMode in the QAPI file. { @@ -1915,7 +1916,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) uint64_t size = 0; int flags = 0; size_t cluster_size = DEFAULT_CLUSTER_SIZE; -int prealloc = 0; +PreallocMode prealloc; int version = 3; Error *local_err = NULL; int ret; @@ -1931,12 +1932,11 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, DEFAULT_CLUSTER_SIZE); buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); -if (!buf || !strcmp(buf, off)) { -prealloc = 0; -} else if (!strcmp(buf, metadata)) { -prealloc = 1; -} else { -error_setg(errp, Invalid preallocation mode: '%s', buf); +prealloc = qapi_enum_parse(PreallocMode_lookup, buf, + PREALLOC_MODE_MAX, PREALLOC_MODE_OFF, + local_err); +if (local_err) { +error_propagate(errp, local_err); ret = -EINVAL; goto finish; } @@ -1958,6 +1958,13 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) flags |= BLOCK_FLAG_LAZY_REFCOUNTS; } +if (prealloc prealloc != PREALLOC_MODE_METADATA) { +ret = -EINVAL; +error_setg(errp, Unsupported preallocate mode: %s, + PreallocMode_lookup[prealloc]); +goto finish; +} + if (backing_file prealloc) { error_setg(errp, Backing file and preallocation cannot be used at the same time); diff --git a/qapi/block-core.json b/qapi/block-core.json index a685d02..a29dbe1 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1697,3 +1697,20 @@ 'len' : 'int', 'offset': 'int', 'speed' : 'int' } } + +# @PreallocMode +# +# Preallocation mode of QEMU image file +# +# @off: no preallocation +# @metadata: preallocate only for metadata +# @falloc: like @full preallocation but allocate disk space by +# posix_fallocate() rather than writing zeros. +# @full: preallocate all data by writing zeros to device to ensure disk +#space is really available. @full preallocation also sets up +#metadata correctly. +# +# Since 2.2 +## +{ 'enum': 'PreallocMode', + 'data': [ 'off', 'metadata', 'falloc', 'full' ] } diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out index 71ca44d..09ca0ae 100644 --- a/tests/qemu-iotests/049.out +++ b/tests/qemu-iotests/049.out @@ -179,7 +179,7 @@ qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='metadata' lazy_refcounts=off qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M -qemu-img: TEST_DIR/t.qcow2: Invalid preallocation mode: '1234' +qemu-img: TEST_DIR/t.qcow2: invalid parameter value: 1234 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='1234' lazy_refcounts=off == Check encryption option == -- 1.9.3
Re: [Qemu-devel] [PATCH] block: extend BLOCK_IO_ERROR event with nospace indicator
On 09/09/2014 06:43 AM, Luiz Capitulino wrote: Enhancing query-block in addition to the event makes sense, if it is easy enough to do. At this point, we are talking about debugging aids, so as long as they are documented appropriately, I won't be too fussy. OK, but I'm wondering if we need to add the string field to both, BLOCK_IO_ERROR and query-block, or only to one to the other. In my opinion, we should only add it to BLOCK_IO_ERROR if libvirt is going to consume. Otherwise, it makes more sense to add it to query-block because that's where we'll meet the user. Btw, by consume I mean read it and make it available to libvirt clients so that they can print it to their users. If we don't want libvirt to consume that field then I think we should only add it to query-block and info block. [For those not aware, qemu built for downstream RHEL already has an error string in the __com.redhat_ namespace; we're trying to figure out what upstream should have so that downstream doesn't have to perpetually maintain an extension] Downstream libvirt does not currently consume any error string. With downstream qemu, the _only_ way to get the error string in the event is to parse libvirt logs, or use upstream libvirt with its backdoor of 'virsh qemu-monitor-event' (through the explicitly unsupported libvirt-qemu.so) to get at the raw event information. Changing libvirt to expose such an error string to the end user would require a new libvirt event number (the existing libvirt event is not extensible), so existing clients would not be able to get at the information without being recompiled to a new libvirt. Since the whole point of this field is for debugging, I think that it is sufficient to add it to JUST query-block, and not to the event. That is, if the app on top of libvirt gets an error, in the common case, they won't care about the message (it won't change how they act), and in the debug case, a developer trying to learn more about what happened can do their own query-block directly (via 'virsh qemu-monitor-command', also in libvirt-qemu.so) rather than trying to wire up libvirt to pass through an error string through a new event. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH 10/10] mc146818rtc: add missed field to vmstate
Paolo Bonzini pbonz...@redhat.com wrote: From: Pavel Dovgalyuk pavel.dovga...@ispras.ru This patch adds irq_reinject_on_ack_count field to VMState to allow correct saving/loading the state of MC146818 RTC. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru Signed-off-by: Paolo Bonzini pbonz...@redhat.com Acked-by: Juan Quintela quint...@redhat.com --- hw/timer/mc146818rtc.c | 24 + 1 file changed, 24 insertions(+) diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 17912b8..2c4b650 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -733,6 +733,22 @@ static int rtc_post_load(void *opaque, int version_id) return 0; } +static const VMStateDescription vmstate_rtc_irq_reinject_on_ack_count = { +.name = irq_reinject_on_ack_count, +.version_id = 1, +.minimum_version_id = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT16(irq_reinject_on_ack_count, RTCState), +VMSTATE_END_OF_LIST() +} +}; + +static bool rtc_irq_reinject_on_ack_count_needed(void *opaque) +{ +RTCState *s = (RTCState *)opaque; If you have to resend for any reason, please remove this unneeded cast. +return s-irq_reinject_on_ack_count != 0; +} + static const VMStateDescription vmstate_rtc = { .name = mc146818rtc, .version_id = 3, @@ -753,6 +769,14 @@ static const VMStateDescription vmstate_rtc = { VMSTATE_TIMER_V(update_timer, RTCState, 3), VMSTATE_UINT64_V(next_alarm_time, RTCState, 3), VMSTATE_END_OF_LIST() +}, +.subsections = (VMStateSubsection[]) { +{ +.vmsd = vmstate_rtc_irq_reinject_on_ack_count, +.needed = rtc_irq_reinject_on_ack_count_needed, +}, { +/* empty */ +} } };
Re: [Qemu-devel] [PATCH 08/10] pckbd: adding new fields to vmstate
Paolo Bonzini pbonz...@redhat.com wrote: From: Pavel Dovgalyuk pavel.dovga...@ispras.ru This patch adds outport to VMState to allow correct saving and restoring the state of PC keyboard controller. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru Signed-off-by: Paolo Bonzini pbonz...@redhat.com Acked-by: Juan Quintela quint...@redhat.com --- hw/input/pckbd.c | 51 +++ 1 file changed, 51 insertions(+) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 2ab8c87..2b0cd3d 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -131,6 +131,7 @@ typedef struct KBDState { uint8_t status; uint8_t mode; uint8_t outport; +bool outport_present; I don't like this one, but /* Bitmask of devices with data available. */ uint8_t pending; void *kbd; @@ -367,18 +368,68 @@ static void kbd_reset(void *opaque) s-mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; s-status = KBD_STAT_CMD | KBD_STAT_UNLOCKED; s-outport = KBD_OUT_RESET | KBD_OUT_A20; +s-outport_present = false; +} + +static uint8_t kbd_outport_default(KBDState *s) +{ +return KBD_OUT_RESET | KBD_OUT_A20 + | (s-status KBD_STAT_OBF ? KBD_OUT_OBF : 0) + | (s-status KBD_STAT_MOUSE_OBF ? KBD_OUT_MOUSE_OBF : 0); +} + +static int kbd_outport_post_load(void *opaque, int version_id) +{ +KBDState *s = opaque; +s-outport_present = true; +return 0; +} + +static const VMStateDescription vmstate_kbd_outport = { +.name = pckbd_outport, +.version_id = 1, +.minimum_version_id = 1, +.post_load = kbd_outport_post_load, +.fields = (VMStateField[]) { +VMSTATE_UINT8(outport, KBDState), +VMSTATE_END_OF_LIST() +} +}; + +static bool kbd_outport_needed(void *opaque) +{ +KBDState *s = opaque; +return s-outport != kbd_outport_default(s); +} + +static int kbd_post_load(void *opaque, int version_id) +{ +KBDState *s = opaque; Only solution that I thought of is putting here: s-outport |= | (s-status KBD_STAT_OBF ? KBD_OUT_OBF : 0) | (s-status KBD_STAT_MOUSE_OBF ? KBD_OUT_MOUSE_OBF : 0); But I am not sure if that bits can be off if status bits are on. Thinking about it, why it is that it is not necessary to have on postload something like that? PD: no, I don't claim to understand how the pc keyboard work ... Later, Juan.
Re: [Qemu-devel] [PATCH 01/10] vl: use QLIST_FOREACH_SAFE to visit change state handlers
Paolo Bonzini pbonz...@redhat.com wrote: This lets a handler delete itself. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Acked-by: Juan Quintela quint...@redhat.com