[PATCH v3 16/16] libqos: add VIRTIO PCI 1.0 support

2019-10-18 Thread Stefan Hajnoczi
Implement the VIRTIO 1.0 virtio-pci interface.  The main change here is
that the register layout is no longer a fixed layout in BAR 0.  Instead
we have to iterate of PCI Capabilities to find descriptions of where
various registers are located.  The vring registers are also more
fine-grained, allowing for more flexible vring layouts, but we don't
take advantage of that.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Sergio Lopez 
---
 tests/Makefile.include   |   1 +
 tests/libqos/virtio-pci-modern.h |  17 ++
 tests/libqos/virtio-pci.h|  10 +
 tests/libqos/virtio-pci-modern.c | 443 +++
 tests/libqos/virtio-pci.c|   6 +-
 5 files changed, 476 insertions(+), 1 deletion(-)
 create mode 100644 tests/libqos/virtio-pci-modern.h
 create mode 100644 tests/libqos/virtio-pci-modern.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 3543451ed3..3f633c8313 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -715,6 +715,7 @@ qos-test-obj-y += tests/libqos/virtio-blk.o
 qos-test-obj-y += tests/libqos/virtio-mmio.o
 qos-test-obj-y += tests/libqos/virtio-net.o
 qos-test-obj-y += tests/libqos/virtio-pci.o
+qos-test-obj-y += tests/libqos/virtio-pci-modern.o
 qos-test-obj-y += tests/libqos/virtio-rng.o
 qos-test-obj-y += tests/libqos/virtio-scsi.o
 qos-test-obj-y += tests/libqos/virtio-serial.o
diff --git a/tests/libqos/virtio-pci-modern.h b/tests/libqos/virtio-pci-modern.h
new file mode 100644
index 00..6bf2b207c3
--- /dev/null
+++ b/tests/libqos/virtio-pci-modern.h
@@ -0,0 +1,17 @@
+/*
+ * libqos virtio PCI VIRTIO 1.0 definitions
+ *
+ * Copyright (c) 2019 Red Hat, Inc
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef LIBQOS_VIRTIO_PCI_MODERN_H
+#define LIBQOS_VIRTIO_PCI_MODERN_H
+
+#include "virtio-pci.h"
+
+bool qvirtio_pci_init_virtio_1(QVirtioPCIDevice *dev);
+
+#endif /* LIBQOS_VIRTIO_PCI_MODERN_H */
diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index 6b3a385b06..294d5567ee 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -27,6 +27,13 @@ typedef struct QVirtioPCIDevice {
 uint32_t config_msix_data;
 
 int bar_idx;
+
+/* VIRTIO 1.0 */
+uint32_t common_cfg_offset;
+uint32_t notify_cfg_offset;
+uint32_t notify_off_multiplier;
+uint32_t isr_cfg_offset;
+uint32_t device_cfg_offset;
 } QVirtioPCIDevice;
 
 struct QVirtioPCIMSIXOps {
@@ -43,6 +50,9 @@ typedef struct QVirtQueuePCI {
 uint16_t msix_entry;
 uint64_t msix_addr;
 uint32_t msix_data;
+
+/* VIRTIO 1.0 */
+uint64_t notify_offset;
 } QVirtQueuePCI;
 
 void virtio_pci_init(QVirtioPCIDevice *dev, QPCIBus *bus, QPCIAddress * addr);
diff --git a/tests/libqos/virtio-pci-modern.c b/tests/libqos/virtio-pci-modern.c
new file mode 100644
index 00..18d118866f
--- /dev/null
+++ b/tests/libqos/virtio-pci-modern.c
@@ -0,0 +1,443 @@
+/*
+ * libqos VIRTIO 1.0 PCI driver
+ *
+ * Copyright (c) 2019 Red Hat, Inc
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "standard-headers/linux/pci_regs.h"
+#include "standard-headers/linux/virtio_pci.h"
+#include "standard-headers/linux/virtio_config.h"
+#include "virtio-pci-modern.h"
+
+static uint8_t config_readb(QVirtioDevice *d, uint64_t addr)
+{
+QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
+return qpci_io_readb(dev->pdev, dev->bar, dev->device_cfg_offset + addr);
+}
+
+static uint16_t config_readw(QVirtioDevice *d, uint64_t addr)
+{
+QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
+return qpci_io_readw(dev->pdev, dev->bar, dev->device_cfg_offset + addr);
+}
+
+static uint32_t config_readl(QVirtioDevice *d, uint64_t addr)
+{
+QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
+return qpci_io_readl(dev->pdev, dev->bar, dev->device_cfg_offset + addr);
+}
+
+static uint64_t config_readq(QVirtioDevice *d, uint64_t addr)
+{
+QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
+return qpci_io_readq(dev->pdev, dev->bar, dev->device_cfg_offset + addr);
+}
+
+static uint64_t get_features(QVirtioDevice *d)
+{
+QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
+uint64_t lo, hi;
+
+qpci_io_writel(dev->pdev, dev->bar, dev->common_cfg_offset +
+   offsetof(struct virtio_pci_common_cfg,
+device_feature_select),
+   0);
+lo = qpci_io_readl(dev->pdev, dev->bar, dev->common_cfg_offset +
+   offsetof(struct virtio_pci_common_cfg, device_feature));
+
+qpci_io_writel(dev->pdev, dev->bar, dev->common_cfg_offset +
+   offsetof(struct virtio_pci_common_cfg,
+device_feature_select),
+   

[PATCH v3 15/16] libqos: extract Legacy virtio-pci.c code

2019-10-18 Thread Stefan Hajnoczi
The current libqos virtio-pci.c code implements the VIRTIO Legacy
interface.  Extract existing code in preparation for VIRTIO 1.0 support.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Sergio Lopez 
Reviewed-by: Thomas Huth 
---
 tests/libqos/virtio-pci.h |  2 --
 tests/libqos/virtio-pci.c | 29 -
 2 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index 78a1c15c2a..6b3a385b06 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -45,8 +45,6 @@ typedef struct QVirtQueuePCI {
 uint32_t msix_data;
 } QVirtQueuePCI;
 
-extern const QVirtioBus qvirtio_pci;
-
 void virtio_pci_init(QVirtioPCIDevice *dev, QPCIBus *bus, QPCIAddress * addr);
 QVirtioPCIDevice *virtio_pci_new(QPCIBus *bus, QPCIAddress * addr);
 
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index e9595603f5..11866f7772 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -35,14 +35,6 @@
  * original qvirtio_pci_destructor and qvirtio_pci_start_hw.
  */
 
-static inline bool qvirtio_pci_is_big_endian(QVirtioPCIDevice *dev)
-{
-QPCIBus *bus = dev->pdev->bus;
-
-/* FIXME: virtio 1.0 is always little-endian */
-return qtest_big_endian(bus->qts);
-}
-
 #define CONFIG_BASE(dev) (VIRTIO_PCI_CONFIG_OFF((dev)->pdev->msix_enabled))
 
 static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t off)
@@ -55,8 +47,7 @@ static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, 
uint64_t off)
  * but virtio ( < 1.0) is in guest order
  * so with a big-endian guest the order has been reversed,
  * reverse it again
- * virtio-1.0 is always little-endian, like PCI, but this
- * case will be managed inside qvirtio_pci_is_big_endian()
+ * virtio-1.0 is always little-endian, like PCI
  */
 
 static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, uint64_t off)
@@ -262,7 +253,7 @@ static void qvirtio_pci_virtqueue_kick(QVirtioDevice *d, 
QVirtQueue *vq)
 qpci_io_writew(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_NOTIFY, vq->index);
 }
 
-const QVirtioBus qvirtio_pci = {
+static const QVirtioBus qvirtio_pci_legacy = {
 .config_readb = qvirtio_pci_config_readb,
 .config_readw = qvirtio_pci_config_readw,
 .config_readl = qvirtio_pci_config_readl,
@@ -396,17 +387,21 @@ void qvirtio_pci_start_hw(QOSGraphObject *obj)
 qvirtio_start_device(&dev->vdev);
 }
 
+static void qvirtio_pci_init_legacy(QVirtioPCIDevice *dev)
+{
+dev->vdev.device_type = qpci_config_readw(dev->pdev, PCI_SUBSYSTEM_ID);
+dev->bar_idx = 0;
+dev->vdev.bus = &qvirtio_pci_legacy;
+dev->msix_ops = &qvirtio_pci_msix_ops_legacy;
+dev->vdev.big_endian = qtest_big_endian(dev->pdev->bus->qts);
+}
+
 static void qvirtio_pci_init_from_pcidev(QVirtioPCIDevice *dev, QPCIDevice 
*pci_dev)
 {
 dev->pdev = pci_dev;
-dev->vdev.device_type = qpci_config_readw(pci_dev, PCI_SUBSYSTEM_ID);
-dev->bar_idx = 0;
-
 dev->config_msix_entry = -1;
-dev->msix_ops = &qvirtio_pci_msix_ops_legacy;
 
-dev->vdev.bus = &qvirtio_pci;
-dev->vdev.big_endian = qvirtio_pci_is_big_endian(dev);
+qvirtio_pci_init_legacy(dev);
 
 /* each virtio-xxx-pci device should override at least this function */
 dev->obj.get_driver = NULL;
-- 
2.21.0




[PATCH v3 12/16] libqos: add MSI-X callbacks to QVirtioPCIDevice

2019-10-18 Thread Stefan Hajnoczi
The MSI-X vectors are programmed differently in the VIRTIO 1.0 and
Legacy interfaces.  Introduce callbacks so different implementations can
be used depending on the interface version.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Sergio Lopez 
Reviewed-by: Thomas Huth 
---
 tests/libqos/virtio-pci.h | 12 
 tests/libqos/virtio-pci.c | 37 -
 2 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index 728b4715f1..4299efc023 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -14,16 +14,28 @@
 #include "libqos/pci.h"
 #include "libqos/qgraph.h"
 
+typedef struct QVirtioPCIMSIXOps QVirtioPCIMSIXOps;
+
 typedef struct QVirtioPCIDevice {
 QOSGraphObject obj;
 QVirtioDevice vdev;
 QPCIDevice *pdev;
 QPCIBar bar;
+const QVirtioPCIMSIXOps *msix_ops;
 uint16_t config_msix_entry;
 uint64_t config_msix_addr;
 uint32_t config_msix_data;
 } QVirtioPCIDevice;
 
+struct QVirtioPCIMSIXOps {
+/* Set the Configuration Vector for MSI-X */
+void (*set_config_vector)(QVirtioPCIDevice *d, uint16_t entry);
+
+/* Set the Queue Vector for MSI-X */
+void (*set_queue_vector)(QVirtioPCIDevice *d, uint16_t vq_idx,
+ uint16_t entry);
+};
+
 typedef struct QVirtQueuePCI {
 QVirtQueue vq;
 uint16_t msix_entry;
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index e4fa318dcc..0725777a8d 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -281,6 +281,31 @@ const QVirtioBus qvirtio_pci = {
 .virtqueue_kick = qvirtio_pci_virtqueue_kick,
 };
 
+static void qvirtio_pci_set_config_vector(QVirtioPCIDevice *d, uint16_t entry)
+{
+uint16_t vector;
+
+qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR, entry);
+vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR);
+g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
+}
+
+static void qvirtio_pci_set_queue_vector(QVirtioPCIDevice *d, uint16_t vq_idx,
+ uint16_t entry)
+{
+uint16_t vector;
+
+qvirtio_pci_queue_select(&d->vdev, vq_idx);
+qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR, entry);
+vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR);
+g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
+}
+
+static const QVirtioPCIMSIXOps qvirtio_pci_msix_ops_legacy = {
+.set_config_vector = qvirtio_pci_set_config_vector,
+.set_queue_vector = qvirtio_pci_set_queue_vector,
+};
+
 void qvirtio_pci_device_enable(QVirtioPCIDevice *d)
 {
 qpci_device_enable(d->pdev);
@@ -295,7 +320,6 @@ void qvirtio_pci_device_disable(QVirtioPCIDevice *d)
 void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,
 QGuestAllocator *alloc, uint16_t entry)
 {
-uint16_t vector;
 uint32_t control;
 uint64_t off;
 
@@ -321,16 +345,12 @@ void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, 
QVirtQueuePCI *vqpci,
off + PCI_MSIX_ENTRY_VECTOR_CTRL,
control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
 
-qvirtio_pci_queue_select(&d->vdev, vqpci->vq.index);
-qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR, entry);
-vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR);
-g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
+d->msix_ops->set_queue_vector(d, vqpci->vq.index, entry);
 }
 
 void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
 QGuestAllocator *alloc, uint16_t entry)
 {
-uint16_t vector;
 uint32_t control;
 uint64_t off;
 
@@ -358,9 +378,7 @@ void 
qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
off + PCI_MSIX_ENTRY_VECTOR_CTRL,
control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
 
-qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR, entry);
-vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR);
-g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
+d->msix_ops->set_config_vector(d, entry);
 }
 
 void qvirtio_pci_destructor(QOSGraphObject *obj)
@@ -383,6 +401,7 @@ static void qvirtio_pci_init_from_pcidev(QVirtioPCIDevice 
*dev, QPCIDevice *pci_
 dev->vdev.device_type = qpci_config_readw(pci_dev, PCI_SUBSYSTEM_ID);
 
 dev->config_msix_entry = -1;
+dev->msix_ops = &qvirtio_pci_msix_ops_legacy;
 
 dev->vdev.bus = &qvirtio_pci;
 dev->vdev.big_endian = qvirtio_pci_is_big_endian(dev);
-- 
2.21.0




[PATCH v3 11/16] libqos: pass full QVirtQueue to set_queue_address()

2019-10-18 Thread Stefan Hajnoczi
Instead of just passing the vring page frame number, pass the full
QVirtQueue.  This will allow the VIRTIO 1.0 transport to program the
fine-grained vring address registers in the future.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Sergio Lopez 
Reviewed-by: Thomas Huth 
---
 tests/libqos/virtio.h  | 2 +-
 tests/libqos/virtio-mmio.c | 6 --
 tests/libqos/virtio-pci.c  | 6 --
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index 5777683a2a..407d8fc088 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -80,7 +80,7 @@ struct QVirtioBus {
 uint16_t (*get_queue_size)(QVirtioDevice *d);
 
 /* Set the address of the selected queue */
-void (*set_queue_address)(QVirtioDevice *d, uint32_t pfn);
+void (*set_queue_address)(QVirtioDevice *d, QVirtQueue *vq);
 
 /* Setup the virtqueue specified by index */
 QVirtQueue *(*virtqueue_setup)(QVirtioDevice *d, QGuestAllocator *alloc,
diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index 4db1f1b8bc..e0a2bd7bc6 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -143,9 +143,11 @@ static uint16_t qvirtio_mmio_get_queue_size(QVirtioDevice 
*d)
 return (uint16_t)qtest_readl(dev->qts, dev->addr + 
QVIRTIO_MMIO_QUEUE_NUM_MAX);
 }
 
-static void qvirtio_mmio_set_queue_address(QVirtioDevice *d, uint32_t pfn)
+static void qvirtio_mmio_set_queue_address(QVirtioDevice *d, QVirtQueue *vq)
 {
 QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+uint64_t pfn = vq->desc / dev->page_size;
+
 qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_PFN, pfn);
 }
 
@@ -179,7 +181,7 @@ static QVirtQueue 
*qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
 
 addr = guest_alloc(alloc, qvring_size(vq->size, dev->page_size));
 qvring_init(dev->qts, alloc, vq, addr);
-qvirtio_mmio_set_queue_address(d, vq->desc / dev->page_size);
+qvirtio_mmio_set_queue_address(d, vq);
 
 return vq;
 }
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 7ecf5d0a52..e4fa318dcc 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -199,9 +199,11 @@ static uint16_t qvirtio_pci_get_queue_size(QVirtioDevice 
*d)
 return qpci_io_readw(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_NUM);
 }
 
-static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn)
+static void qvirtio_pci_set_queue_address(QVirtioDevice *d, QVirtQueue *vq)
 {
 QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
+uint64_t pfn = vq->desc / VIRTIO_PCI_VRING_ALIGN;
+
 qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_PFN, pfn);
 }
 
@@ -239,7 +241,7 @@ static QVirtQueue 
*qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
 addr = guest_alloc(alloc, qvring_size(vqpci->vq.size,
   VIRTIO_PCI_VRING_ALIGN));
 qvring_init(qvpcidev->pdev->bus->qts, alloc, &vqpci->vq, addr);
-qvirtio_pci_set_queue_address(d, vqpci->vq.desc / VIRTIO_PCI_VRING_ALIGN);
+qvirtio_pci_set_queue_address(d, &vqpci->vq);
 
 return &vqpci->vq;
 }
-- 
2.21.0




[PATCH v3 14/16] libqos: make the virtio-pci BAR index configurable

2019-10-18 Thread Stefan Hajnoczi
The Legacy virtio-pci interface always uses BAR 0.  VIRTIO 1.0 may need
to use a different BAR index, so make it configurable.

Signed-off-by: Stefan Hajnoczi 
---
v3:
 * Change uint8_t bar_idx to int [Thomas]
---
 tests/libqos/virtio-pci.h | 2 ++
 tests/libqos/virtio-pci.c | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index 0e4a8b7b00..78a1c15c2a 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -25,6 +25,8 @@ typedef struct QVirtioPCIDevice {
 uint16_t config_msix_entry;
 uint64_t config_msix_addr;
 uint32_t config_msix_data;
+
+int bar_idx;
 } QVirtioPCIDevice;
 
 struct QVirtioPCIMSIXOps {
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index c900742f96..e9595603f5 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -310,7 +310,7 @@ static const QVirtioPCIMSIXOps qvirtio_pci_msix_ops_legacy 
= {
 void qvirtio_pci_device_enable(QVirtioPCIDevice *d)
 {
 qpci_device_enable(d->pdev);
-d->bar = qpci_iomap(d->pdev, 0, NULL);
+d->bar = qpci_iomap(d->pdev, d->bar_idx, NULL);
 }
 
 void qvirtio_pci_device_disable(QVirtioPCIDevice *d)
@@ -400,6 +400,7 @@ static void qvirtio_pci_init_from_pcidev(QVirtioPCIDevice 
*dev, QPCIDevice *pci_
 {
 dev->pdev = pci_dev;
 dev->vdev.device_type = qpci_config_readw(pci_dev, PCI_SUBSYSTEM_ID);
+dev->bar_idx = 0;
 
 dev->config_msix_entry = -1;
 dev->msix_ops = &qvirtio_pci_msix_ops_legacy;
-- 
2.21.0




[PATCH v3 10/16] libqos: add iteration support to qpci_find_capability()

2019-10-18 Thread Stefan Hajnoczi
VIRTIO 1.0 PCI devices have multiple PCI_CAP_ID_VNDR capabilities so we
need a way to iterate over them.  Extend qpci_find_capability() to take
the last address.

Signed-off-by: Stefan Hajnoczi 
--
v3:
 * Document qpci_find_capability()
---
 tests/libqos/pci.h |  2 +-
 tests/libqos/pci.c | 30 --
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/tests/libqos/pci.h b/tests/libqos/pci.h
index a5389a5845..590c175190 100644
--- a/tests/libqos/pci.h
+++ b/tests/libqos/pci.h
@@ -86,7 +86,7 @@ bool qpci_has_buggy_msi(QPCIDevice *dev);
 bool qpci_check_buggy_msi(QPCIDevice *dev);
 
 void qpci_device_enable(QPCIDevice *dev);
-uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id);
+uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id, uint8_t start_addr);
 void qpci_msix_enable(QPCIDevice *dev);
 void qpci_msix_disable(QPCIDevice *dev);
 bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry);
diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c
index 662ee7a517..2309a724e4 100644
--- a/tests/libqos/pci.c
+++ b/tests/libqos/pci.c
@@ -115,10 +115,28 @@ void qpci_device_enable(QPCIDevice *dev)
 g_assert_cmphex(cmd & PCI_COMMAND_MASTER, ==, PCI_COMMAND_MASTER);
 }
 
-uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id)
+/**
+ * qpci_find_capability:
+ * @dev: the PCI device
+ * @id: the PCI Capability ID (PCI_CAP_ID_*)
+ * @start_addr: 0 to begin iteration or the last return value to continue
+ *  iteration
+ *
+ * Iterate over the PCI Capabilities List.
+ *
+ * Returns: PCI Configuration Space offset of the capabililty structure or
+ *  0 if no further matching capability is found
+ */
+uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id, uint8_t start_addr)
 {
 uint8_t cap;
-uint8_t addr = qpci_config_readb(dev, PCI_CAPABILITY_LIST);
+uint8_t addr;
+
+if (start_addr) {
+addr = qpci_config_readb(dev, start_addr + PCI_CAP_LIST_NEXT);
+} else {
+addr = qpci_config_readb(dev, PCI_CAPABILITY_LIST);
+}
 
 do {
 cap = qpci_config_readb(dev, addr);
@@ -138,7 +156,7 @@ void qpci_msix_enable(QPCIDevice *dev)
 uint8_t bir_table;
 uint8_t bir_pba;
 
-addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX);
+addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
 g_assert_cmphex(addr, !=, 0);
 
 val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
@@ -167,7 +185,7 @@ void qpci_msix_disable(QPCIDevice *dev)
 uint16_t val;
 
 g_assert(dev->msix_enabled);
-addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX);
+addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
 g_assert_cmphex(addr, !=, 0);
 val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
 qpci_config_writew(dev, addr + PCI_MSIX_FLAGS,
@@ -203,7 +221,7 @@ bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry)
 uint64_t vector_off = dev->msix_table_off + entry * PCI_MSIX_ENTRY_SIZE;
 
 g_assert(dev->msix_enabled);
-addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX);
+addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
 g_assert_cmphex(addr, !=, 0);
 val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
 
@@ -221,7 +239,7 @@ uint16_t qpci_msix_table_size(QPCIDevice *dev)
 uint8_t addr;
 uint16_t control;
 
-addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX);
+addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
 g_assert_cmphex(addr, !=, 0);
 
 control = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
-- 
2.21.0




[PATCH v3 09/16] libqos: access VIRTIO 1.0 vring in little-endian

2019-10-18 Thread Stefan Hajnoczi
VIRTIO 1.0 uses little-endian for the vring.  Legacy VIRTIO uses guest
endianness.  Adjust the code to handle both.

Note that qvirtio_readq() is not defined because it has no users.  All
the other accessors are really needed.

Signed-off-by: Stefan Hajnoczi 
---
 tests/libqos/virtio.h  |   4 +-
 tests/libqos/virtio-mmio.c |   1 +
 tests/libqos/virtio-pci.c  |   1 +
 tests/libqos/virtio.c  | 131 +++--
 tests/virtio-blk-test.c|   8 +--
 5 files changed, 106 insertions(+), 39 deletions(-)

diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index a5c99fb3c9..5777683a2a 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -26,6 +26,7 @@ typedef struct QVirtioDevice {
 } QVirtioDevice;
 
 typedef struct QVirtQueue {
+QVirtioDevice *vdev;
 uint64_t desc; /* This points to an array of struct vring_desc */
 uint64_t avail; /* This points to a struct vring_avail */
 uint64_t used; /* This points to a struct vring_used */
@@ -134,7 +135,8 @@ void qvring_init(QTestState *qts, const QGuestAllocator 
*alloc, QVirtQueue *vq,
 QVRingIndirectDesc *qvring_indirect_desc_setup(QTestState *qs, QVirtioDevice 
*d,
QGuestAllocator *alloc,
uint16_t elem);
-void qvring_indirect_desc_add(QTestState *qts, QVRingIndirectDesc *indirect,
+void qvring_indirect_desc_add(QVirtioDevice *d, QTestState *qts,
+  QVRingIndirectDesc *indirect,
   uint64_t data, uint32_t len, bool write);
 uint32_t qvirtqueue_add(QTestState *qts, QVirtQueue *vq, uint64_t data,
 uint32_t len, bool write, bool next);
diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index 78066e6e05..4db1f1b8bc 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -157,6 +157,7 @@ static QVirtQueue 
*qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
 uint64_t addr;
 
 vq = g_malloc0(sizeof(*vq));
+vq->vdev = d;
 qvirtio_mmio_queue_select(d, index);
 qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_ALIGN, 
dev->page_size);
 
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 1b6b760fc6..7ecf5d0a52 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -217,6 +217,7 @@ static QVirtQueue 
*qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
 feat = qvirtio_pci_get_guest_features(d);
 
 qvirtio_pci_queue_select(d, index);
+vqpci->vq.vdev = d;
 vqpci->vq.index = index;
 vqpci->vq.size = qvirtio_pci_get_queue_size(d);
 vqpci->vq.free_head = 0;
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index 57fa79373b..b9b501a3d4 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/bswap.h"
 #include "libqtest.h"
 #include "libqos/virtio.h"
 #include "standard-headers/linux/virtio_config.h"
@@ -19,6 +20,62 @@ static void check_features_negotiated(QVirtioDevice *d)
 g_assert_cmphex(d->features, !=, 0);
 }
 
+/*
+ * qtest_readX/writeX() functions transfer host endian from/to guest endian.
+ * This works great for Legacy VIRTIO devices where we need guest endian
+ * accesses.  For VIRTIO 1.0 the vring is little-endian so the automatic guest
+ * endianness conversion is not wanted.
+ *
+ * The following qvirtio_readX/writeX() functions handle Legacy and VIRTIO 1.0
+ * accesses seamlessly.
+ */
+static uint16_t qvirtio_readw(QVirtioDevice *d, QTestState *qts, uint64_t addr)
+{
+uint16_t val = qtest_readw(qts, addr);
+
+if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) {
+val = bswap16(val);
+}
+return val;
+}
+
+static uint32_t qvirtio_readl(QVirtioDevice *d, QTestState *qts, uint64_t addr)
+{
+uint32_t val = qtest_readl(qts, addr);
+
+if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) {
+val = bswap32(val);
+}
+return val;
+}
+
+static void qvirtio_writew(QVirtioDevice *d, QTestState *qts,
+   uint64_t addr, uint16_t val)
+{
+if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) {
+val = bswap16(val);
+}
+qtest_writew(qts, addr, val);
+}
+
+static void qvirtio_writel(QVirtioDevice *d, QTestState *qts,
+   uint64_t addr, uint32_t val)
+{
+if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) {
+val = bswap32(val);
+}
+qtest_writel(qts, addr, val);
+}
+
+static void qvirtio_writeq(QVirtioDevice *d, QTestState *qts,
+   uint64_t addr, uint64_t val)
+{
+if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) {
+val = bswap64(val);
+}
+qtest_writeq(qts, addr, val);
+}
+
 uint8_t qvirtio_config_readb(QVirtioDevice *d, uint64_t addr)
 {
 check_features_negotiated(d);
@@ 

[PATCH v3 13/16] libqos: expose common virtqueue setup/cleanup functions

2019-10-18 Thread Stefan Hajnoczi
The VIRTIO 1.0 code will need to perform additional steps but it will
reuse the common virtqueue setup/cleanup code.  Make these functions
public.

Make sure to invoke callbacks via QVirtioBus instead of directly calling
the virtio-pci Legacy versions of these functions.

Signed-off-by: Stefan Hajnoczi 
Reviewed-by: Sergio Lopez 
Reviewed-by: Thomas Huth 
---
 tests/libqos/virtio-pci.h |  8 
 tests/libqos/virtio-pci.c | 19 ++-
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index 4299efc023..0e4a8b7b00 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -65,4 +65,12 @@ void 
qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
 QGuestAllocator *alloc, uint16_t 
entry);
 void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,
 QGuestAllocator *alloc, uint16_t 
entry);
+
+/* Used by Legacy and Modern virtio-pci code */
+QVirtQueue *qvirtio_pci_virtqueue_setup_common(QVirtioDevice *d,
+   QGuestAllocator *alloc,
+   uint16_t index);
+void qvirtio_pci_virtqueue_cleanup_common(QVirtQueue *vq,
+  QGuestAllocator *alloc);
+
 #endif
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 0725777a8d..c900742f96 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -207,8 +207,9 @@ static void qvirtio_pci_set_queue_address(QVirtioDevice *d, 
QVirtQueue *vq)
 qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_PFN, pfn);
 }
 
-static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
-QGuestAllocator *alloc, uint16_t index)
+QVirtQueue *qvirtio_pci_virtqueue_setup_common(QVirtioDevice *d,
+   QGuestAllocator *alloc,
+   uint16_t index)
 {
 uint64_t feat;
 uint64_t addr;
@@ -216,12 +217,12 @@ static QVirtQueue 
*qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
 QVirtioPCIDevice *qvpcidev = container_of(d, QVirtioPCIDevice, vdev);
 
 vqpci = g_malloc0(sizeof(*vqpci));
-feat = qvirtio_pci_get_guest_features(d);
+feat = d->bus->get_guest_features(d);
 
-qvirtio_pci_queue_select(d, index);
+d->bus->queue_select(d, index);
 vqpci->vq.vdev = d;
 vqpci->vq.index = index;
-vqpci->vq.size = qvirtio_pci_get_queue_size(d);
+vqpci->vq.size = d->bus->get_queue_size(d);
 vqpci->vq.free_head = 0;
 vqpci->vq.num_free = vqpci->vq.size;
 vqpci->vq.align = VIRTIO_PCI_VRING_ALIGN;
@@ -241,12 +242,12 @@ static QVirtQueue 
*qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
 addr = guest_alloc(alloc, qvring_size(vqpci->vq.size,
   VIRTIO_PCI_VRING_ALIGN));
 qvring_init(qvpcidev->pdev->bus->qts, alloc, &vqpci->vq, addr);
-qvirtio_pci_set_queue_address(d, &vqpci->vq);
+d->bus->set_queue_address(d, &vqpci->vq);
 
 return &vqpci->vq;
 }
 
-static void qvirtio_pci_virtqueue_cleanup(QVirtQueue *vq,
+void qvirtio_pci_virtqueue_cleanup_common(QVirtQueue *vq,
   QGuestAllocator *alloc)
 {
 QVirtQueuePCI *vqpci = container_of(vq, QVirtQueuePCI, vq);
@@ -276,8 +277,8 @@ const QVirtioBus qvirtio_pci = {
 .queue_select = qvirtio_pci_queue_select,
 .get_queue_size = qvirtio_pci_get_queue_size,
 .set_queue_address = qvirtio_pci_set_queue_address,
-.virtqueue_setup = qvirtio_pci_virtqueue_setup,
-.virtqueue_cleanup = qvirtio_pci_virtqueue_cleanup,
+.virtqueue_setup = qvirtio_pci_virtqueue_setup_common,
+.virtqueue_cleanup = qvirtio_pci_virtqueue_cleanup_common,
 .virtqueue_kick = qvirtio_pci_virtqueue_kick,
 };
 
-- 
2.21.0




[PATCH v3 07/16] libqos: enforce Device Initialization order

2019-10-18 Thread Stefan Hajnoczi
According to VIRTIO 1.1 "3.1.1 Driver Requirements: Device
Initialization", configuration space and virtqueues cannot be accessed
before features have been negotiated.  Enforce this requirement.

Signed-off-by: Stefan Hajnoczi 
---
 tests/libqos/virtio.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index 4f7e6bb8a1..2593996c98 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -13,23 +13,33 @@
 #include "standard-headers/linux/virtio_config.h"
 #include "standard-headers/linux/virtio_ring.h"
 
+/* Features must be negotiated before config space or virtqueue access */
+static void check_features_negotiated(QVirtioDevice *d)
+{
+g_assert_cmphex(d->features, !=, 0);
+}
+
 uint8_t qvirtio_config_readb(QVirtioDevice *d, uint64_t addr)
 {
+check_features_negotiated(d);
 return d->bus->config_readb(d, addr);
 }
 
 uint16_t qvirtio_config_readw(QVirtioDevice *d, uint64_t addr)
 {
+check_features_negotiated(d);
 return d->bus->config_readw(d, addr);
 }
 
 uint32_t qvirtio_config_readl(QVirtioDevice *d, uint64_t addr)
 {
+check_features_negotiated(d);
 return d->bus->config_readl(d, addr);
 }
 
 uint64_t qvirtio_config_readq(QVirtioDevice *d, uint64_t addr)
 {
+check_features_negotiated(d);
 return d->bus->config_readq(d, addr);
 }
 
@@ -47,6 +57,7 @@ void qvirtio_set_features(QVirtioDevice *d, uint64_t features)
 QVirtQueue *qvirtqueue_setup(QVirtioDevice *d,
  QGuestAllocator *alloc, uint16_t index)
 {
+check_features_negotiated(d);
 return d->bus->virtqueue_setup(d, alloc, index);
 }
 
-- 
2.21.0




[PATCH v3 08/16] libqos: implement VIRTIO 1.0 FEATURES_OK step

2019-10-18 Thread Stefan Hajnoczi
Device initialization has an extra step in VIRTIO 1.0.  The FEATURES_OK
status bit is set to indicate that feature negotiation has completed.
The driver then reads the status register again to check that the device
agrees with the final features.

Implement this step as part of qvirtio_set_features() instead of
introducing a separate function.  This way all existing code works
without modifications.

Signed-off-by: Stefan Hajnoczi 
---
 tests/libqos/virtio.c | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index 2593996c98..57fa79373b 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -52,6 +52,19 @@ void qvirtio_set_features(QVirtioDevice *d, uint64_t 
features)
 {
 d->features = features;
 d->bus->set_features(d, features);
+
+/*
+ * This could be a separate function for drivers that want to access
+ * configuration space before setting FEATURES_OK, but no existing users
+ * need that and it's less code for callers if this is done implicitly.
+*/
+if (features & (1ull << VIRTIO_F_VERSION_1)) {
+uint8_t status = d->bus->get_status(d) |
+ VIRTIO_CONFIG_S_FEATURES_OK;
+
+d->bus->set_status(d, status);
+g_assert_cmphex(d->bus->get_status(d), ==, status);
+}
 }
 
 QVirtQueue *qvirtqueue_setup(QVirtioDevice *d,
@@ -88,9 +101,10 @@ void qvirtio_set_driver(QVirtioDevice *d)
 
 void qvirtio_set_driver_ok(QVirtioDevice *d)
 {
-d->bus->set_status(d, d->bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER_OK);
-g_assert_cmphex(d->bus->get_status(d), ==, VIRTIO_CONFIG_S_DRIVER_OK |
-VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE);
+uint8_t status = d->bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER_OK;
+
+d->bus->set_status(d, status);
+g_assert_cmphex(d->bus->get_status(d), ==, status);
 }
 
 void qvirtio_wait_queue_isr(QTestState *qts, QVirtioDevice *d,
-- 
2.21.0




[PATCH v3 06/16] libqos: add missing virtio-9p feature negotiation

2019-10-18 Thread Stefan Hajnoczi
VIRTIO Device Initialization requires feature negotiation.  The libqos
virtio-9p driver lacks feature negotiation and is therefore
non-compliant.

Signed-off-by: Stefan Hajnoczi 
---
 tests/libqos/virtio-9p.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/tests/libqos/virtio-9p.c b/tests/libqos/virtio-9p.c
index 8c9efce3e1..77dbfb62ad 100644
--- a/tests/libqos/virtio-9p.c
+++ b/tests/libqos/virtio-9p.c
@@ -32,6 +32,12 @@ static void virtio_9p_cleanup(QVirtio9P *interface)
 
 static void virtio_9p_setup(QVirtio9P *interface)
 {
+uint64_t features;
+
+features = qvirtio_get_features(interface->vdev);
+features &= ~(QVIRTIO_F_BAD_FEATURE | (1ull << VIRTIO_RING_F_EVENT_IDX));
+qvirtio_set_features(interface->vdev, features);
+
 interface->vq = qvirtqueue_setup(interface->vdev, alloc, 0);
 qvirtio_set_driver_ok(interface->vdev);
 }
-- 
2.21.0




[PATCH v3 05/16] tests/virtio-blk-test: set up virtqueue after feature negotiation

2019-10-18 Thread Stefan Hajnoczi
VIRTIO Device Initialization requires that feature negotiation has
completed before virtqueues are set up.  This makes sense because the
driver must know whether it is operating in Legacy or VIRTIO 1.0 mode
before it can access vring fields with the correct endianness.

Signed-off-by: Stefan Hajnoczi 
---
 tests/virtio-blk-test.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 31680cc159..fe0dc4a896 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -113,8 +113,8 @@ static uint64_t virtio_blk_request(QGuestAllocator *alloc, 
QVirtioDevice *d,
 return addr;
 }
 
-static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
-   QVirtQueue *vq)
+/* Returns the request virtqueue so the caller can perform further tests */
+static QVirtQueue *test_basic(QVirtioDevice *dev, QGuestAllocator *alloc)
 {
 QVirtioBlkReq req;
 uint64_t req_addr;
@@ -124,6 +124,7 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator 
*alloc,
 uint8_t status;
 char *data;
 QTestState *qts = global_qtest;
+QVirtQueue *vq;
 
 features = qvirtio_get_features(dev);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
@@ -135,6 +136,8 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator 
*alloc,
 capacity = qvirtio_config_readq(dev, 0);
 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
+vq = qvirtqueue_setup(dev, alloc, 0);
+
 qvirtio_set_driver_ok(dev);
 
 /* Write and read with 3 descriptor layout */
@@ -331,14 +334,16 @@ static void test_basic(QVirtioDevice *dev, 
QGuestAllocator *alloc,
 
 guest_free(alloc, req_addr);
 }
+
+return vq;
 }
 
 static void basic(void *obj, void *data, QGuestAllocator *t_alloc)
 {
 QVirtioBlk *blk_if = obj;
 QVirtQueue *vq;
-vq = qvirtqueue_setup(blk_if->vdev, t_alloc, 0);
-test_basic(blk_if->vdev, t_alloc, vq);
+
+vq = test_basic(blk_if->vdev, t_alloc);
 qvirtqueue_cleanup(blk_if->vdev->bus, vq, t_alloc);
 
 }
@@ -746,9 +751,7 @@ static void resize(void *obj, void *data, QGuestAllocator 
*t_alloc)
 QVirtQueue *vq;
 QTestState *qts = global_qtest;
 
-vq = qvirtqueue_setup(dev, t_alloc, 0);
-
-test_basic(dev, t_alloc, vq);
+vq = test_basic(dev, t_alloc);
 
 qmp_discard_response("{ 'execute': 'block_resize', "
  " 'arguments': { 'device': 'drive0', "
-- 
2.21.0




[PATCH v3 01/16] tests/virtio-blk-test: read config space after feature negotiation

2019-10-18 Thread Stefan Hajnoczi
The VIRTIO Configuration Space cannot be accessed before device feature
bits have been read because a driver doesn't know the endianness until
it has checked VIRTIO_F_VERSION_1.

Fix this problem in preparation for VIRTIO 1.0 support.

Signed-off-by: Stefan Hajnoczi 
---
 tests/virtio-blk-test.c | 33 -
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index ed13167392..f6674fb233 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -125,10 +125,6 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator 
*alloc,
 char *data;
 QTestState *qts = global_qtest;
 
-capacity = qvirtio_config_readq(dev, 0);
-
-g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
-
 features = qvirtio_get_features(dev);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
 (1u << VIRTIO_RING_F_INDIRECT_DESC) |
@@ -136,6 +132,9 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator 
*alloc,
 (1u << VIRTIO_BLK_F_SCSI));
 qvirtio_set_features(dev, features);
 
+capacity = qvirtio_config_readq(dev, 0);
+g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
 qvirtio_set_driver_ok(dev);
 
 /* Write and read with 3 descriptor layout */
@@ -359,9 +358,6 @@ static void indirect(void *obj, void *u_data, 
QGuestAllocator *t_alloc)
 char *data;
 QTestState *qts = global_qtest;
 
-capacity = qvirtio_config_readq(dev, 0);
-g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
-
 features = qvirtio_get_features(dev);
 g_assert_cmphex(features & (1u << VIRTIO_RING_F_INDIRECT_DESC), !=, 0);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
@@ -369,6 +365,9 @@ static void indirect(void *obj, void *u_data, 
QGuestAllocator *t_alloc)
 (1u << VIRTIO_BLK_F_SCSI));
 qvirtio_set_features(dev, features);
 
+capacity = qvirtio_config_readq(dev, 0);
+g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
 vq = qvirtqueue_setup(dev, t_alloc, 0);
 qvirtio_set_driver_ok(dev);
 
@@ -434,8 +433,16 @@ static void config(void *obj, void *data, QGuestAllocator 
*t_alloc)
 QVirtioBlk *blk_if = obj;
 QVirtioDevice *dev = blk_if->vdev;
 int n_size = TEST_IMAGE_SIZE / 2;
+uint64_t features;
 uint64_t capacity;
 
+features = qvirtio_get_features(dev);
+features = features & ~(QVIRTIO_F_BAD_FEATURE |
+(1u << VIRTIO_RING_F_INDIRECT_DESC) |
+(1u << VIRTIO_RING_F_EVENT_IDX) |
+(1u << VIRTIO_BLK_F_SCSI));
+qvirtio_set_features(dev, features);
+
 capacity = qvirtio_config_readq(dev, 0);
 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
@@ -475,9 +482,6 @@ static void msix(void *obj, void *u_data, QGuestAllocator 
*t_alloc)
 qpci_msix_enable(pdev->pdev);
 qvirtio_pci_set_msix_configuration_vector(pdev, t_alloc, 0);
 
-capacity = qvirtio_config_readq(dev, 0);
-g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
-
 features = qvirtio_get_features(dev);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
 (1u << VIRTIO_RING_F_INDIRECT_DESC) |
@@ -485,6 +489,9 @@ static void msix(void *obj, void *u_data, QGuestAllocator 
*t_alloc)
 (1u << VIRTIO_BLK_F_SCSI));
 qvirtio_set_features(dev, features);
 
+capacity = qvirtio_config_readq(dev, 0);
+g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
 vq = qvirtqueue_setup(dev, t_alloc, 0);
 qvirtqueue_pci_msix_setup(pdev, (QVirtQueuePCI *)vq, t_alloc, 1);
 
@@ -584,9 +591,6 @@ static void idx(void *obj, void *u_data, QGuestAllocator 
*t_alloc)
 qpci_msix_enable(pdev->pdev);
 qvirtio_pci_set_msix_configuration_vector(pdev, t_alloc, 0);
 
-capacity = qvirtio_config_readq(dev, 0);
-g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
-
 features = qvirtio_get_features(dev);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
 (1u << VIRTIO_RING_F_INDIRECT_DESC) |
@@ -594,6 +598,9 @@ static void idx(void *obj, void *u_data, QGuestAllocator 
*t_alloc)
 (1u << VIRTIO_BLK_F_SCSI));
 qvirtio_set_features(dev, features);
 
+capacity = qvirtio_config_readq(dev, 0);
+g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
 vq = qvirtqueue_setup(dev, t_alloc, 0);
 qvirtqueue_pci_msix_setup(pdev, (QVirtQueuePCI *)vq, t_alloc, 1);
 
-- 
2.21.0




[PATCH v3 00/16] libqos: add VIRTIO PCI 1.0 support

2019-10-18 Thread Stefan Hajnoczi
v3:
 * Now implements VIRTIO 1.0 fully (vring, device initialization).
   This required several new patches to address the following issues:
   1. Tests that do not negotiate features (non-compliant!)
   2. Tests that access configuration space before feature negotiation
  (non-compliant!)
   3. Tests that set up virtqueues before feature negotiation (non-compliant!)
   4. vring accesses require byte-swapping when VIRTIO 1.0 is used with a
  big-endian guest because the qtest_readX/writeX() API automatically
  converts to guest-endian
   5. VIRTIO 1.0 has an additional FEATURES_OK step during Device
  Initialization
 * Change uint8_t bar_idx to int [Thomas]
 * Document qpci_find_capability() [Thomas]
 * Every commit tested with arm, ppc64, and x86_64 targets using:
   git rebase -i origin/master -x 'make tests/qos-test &&
   QTEST_QEMU_BINARY=ppc64-softmmu/qemu-system-ppc64 tests/qos-test &&
   QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 tests/qos-test'
   QTEST_QEMU_BINARY=arm-softmmu/qemu-system-arm tests/qos-test'
v2:
 * Fix checkpatch.pl issues, except MAINTAINERS file warning.  libqos already
   has maintainers and the new virtio-pci-modern.[ch] files don't need extra
   entries since they are already covered by the existing libqos/ entry.

New VIRTIO devices are Non-Transitional.  This means they only expose the
VIRTIO 1.0 interface, not the Legacy interface.

The libqos only supports Legacy and Transitional devices (in Legacy mode).
This patch series add VIRTIO 1.0 support so that tests can run against
Non-Transitional devices too.

The virtio-fs device is Non-Transitional, so this is a prerequisite for
virtio-fs qos tests.

Stefan Hajnoczi (16):
  tests/virtio-blk-test: read config space after feature negotiation
  libqos: read QVIRTIO_MMIO_VERSION register
  libqos: extend feature bits to 64-bit
  virtio-scsi-test: add missing feature negotiation
  tests/virtio-blk-test: set up virtqueue after feature negotiation
  libqos: add missing virtio-9p feature negotiation
  libqos: enforce Device Initialization order
  libqos: implement VIRTIO 1.0 FEATURES_OK step
  libqos: access VIRTIO 1.0 vring in little-endian
  libqos: add iteration support to qpci_find_capability()
  libqos: pass full QVirtQueue to set_queue_address()
  libqos: add MSI-X callbacks to QVirtioPCIDevice
  libqos: expose common virtqueue setup/cleanup functions
  libqos: make the virtio-pci BAR index configurable
  libqos: extract Legacy virtio-pci.c code
  libqos: add VIRTIO PCI 1.0 support

 tests/Makefile.include   |   1 +
 tests/libqos/pci.h   |   2 +-
 tests/libqos/virtio-mmio.h   |   1 +
 tests/libqos/virtio-pci-modern.h |  17 ++
 tests/libqos/virtio-pci.h|  34 ++-
 tests/libqos/virtio.h|  18 +-
 tests/libqos/pci.c   |  30 ++-
 tests/libqos/virtio-9p.c |   6 +
 tests/libqos/virtio-mmio.c   |  38 ++-
 tests/libqos/virtio-net.c|   6 +-
 tests/libqos/virtio-pci-modern.c | 443 +++
 tests/libqos/virtio-pci.c| 105 +---
 tests/libqos/virtio.c| 166 +---
 tests/virtio-blk-test.c  |  66 +++--
 tests/virtio-scsi-test.c |   8 +
 15 files changed, 805 insertions(+), 136 deletions(-)
 create mode 100644 tests/libqos/virtio-pci-modern.h
 create mode 100644 tests/libqos/virtio-pci-modern.c

-- 
2.21.0




[PATCH v3 02/16] libqos: read QVIRTIO_MMIO_VERSION register

2019-10-18 Thread Stefan Hajnoczi
There was no real virtio-mmio ABI change between Legacy and VIRTIO 1.0
except that the Version field was incremented from 1 to 2.

However, QEMU does not allow Legacy drivers to perform VIRTIO 1.0
operations like accessing 64-bit feature bits.  Since we will introduce
64-bit feature bit support we need a way to differentiate between
virtio-mmio Version 1 and 2 to avoid upsetting QEMU when we operate in
Legacy mode.

Stash away the Version field so later patches can change behavior
depending on the version.

Signed-off-by: Stefan Hajnoczi 
---
 tests/libqos/virtio-mmio.h | 1 +
 tests/libqos/virtio-mmio.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/tests/libqos/virtio-mmio.h b/tests/libqos/virtio-mmio.h
index 17a17141c3..0e45778b07 100644
--- a/tests/libqos/virtio-mmio.h
+++ b/tests/libqos/virtio-mmio.h
@@ -40,6 +40,7 @@ typedef struct QVirtioMMIODevice {
 uint64_t addr;
 uint32_t page_size;
 uint32_t features; /* As it cannot be read later, save it */
+uint32_t version;
 } QVirtioMMIODevice;
 
 extern const QVirtioBus qvirtio_mmio;
diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index d0047876a8..7154b03c1d 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -223,6 +223,9 @@ void qvirtio_mmio_init_device(QVirtioMMIODevice *dev, 
QTestState *qts,
 magic = qtest_readl(qts, addr + QVIRTIO_MMIO_MAGIC_VALUE);
 g_assert(magic == ('v' | 'i' << 8 | 'r' << 16 | 't' << 24));
 
+dev->version = qtest_readl(qts, addr + QVIRTIO_MMIO_VERSION);
+g_assert(dev->version == 1 || dev->version == 2);
+
 dev->qts = qts;
 dev->addr = addr;
 dev->page_size = page_size;
-- 
2.21.0




[PATCH v3 04/16] virtio-scsi-test: add missing feature negotiation

2019-10-18 Thread Stefan Hajnoczi
VIRTIO Device Initialization requires feature negotiation.  Currently
virtio-scsi-test.c is non-compliant.

Signed-off-by: Stefan Hajnoczi 
---
 tests/virtio-scsi-test.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
index 7c8f9b27f8..0415e75876 100644
--- a/tests/virtio-scsi-test.c
+++ b/tests/virtio-scsi-test.c
@@ -123,10 +123,16 @@ static QVirtioSCSIQueues *qvirtio_scsi_init(QVirtioDevice 
*dev)
 QVirtioSCSIQueues *vs;
 const uint8_t test_unit_ready_cdb[VIRTIO_SCSI_CDB_SIZE] = {};
 struct virtio_scsi_cmd_resp resp;
+uint64_t features;
 int i;
 
 vs = g_new0(QVirtioSCSIQueues, 1);
 vs->dev = dev;
+
+features = qvirtio_get_features(dev);
+features &= ~(QVIRTIO_F_BAD_FEATURE | (1ull << VIRTIO_RING_F_EVENT_IDX));
+qvirtio_set_features(dev, features);
+
 vs->num_queues = qvirtio_config_readl(dev, 0);
 
 g_assert_cmpint(vs->num_queues, <, MAX_NUM_QUEUES);
@@ -135,6 +141,8 @@ static QVirtioSCSIQueues *qvirtio_scsi_init(QVirtioDevice 
*dev)
 vs->vq[i] = qvirtqueue_setup(dev, alloc, i);
 }
 
+qvirtio_set_driver_ok(dev);
+
 /* Clear the POWER ON OCCURRED unit attention */
 g_assert_cmpint(virtio_scsi_do_command(vs, test_unit_ready_cdb,
NULL, 0, NULL, 0, &resp),
-- 
2.21.0




[PATCH v3 03/16] libqos: extend feature bits to 64-bit

2019-10-18 Thread Stefan Hajnoczi
In VIRTIO 1.0 feature bits changed from 32-bit to 64-bit.  (In fact, the
transports allow even more feature bits but nothing uses more than 64
bits today.)

Add 64-bit feature bit support to virtio-mmio and virtio-pci.  This will
be necessary for VIRTIO 1.0 support.

Signed-off-by: Stefan Hajnoczi 
---
 tests/libqos/virtio.h  | 12 ++--
 tests/libqos/virtio-mmio.c | 28 ++--
 tests/libqos/virtio-net.c  |  6 +++---
 tests/libqos/virtio-pci.c  | 12 ++--
 tests/libqos/virtio.c  |  4 ++--
 tests/virtio-blk-test.c|  8 
 6 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index 2cb2448f46..a5c99fb3c9 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -13,7 +13,7 @@
 #include "libqos/malloc.h"
 #include "standard-headers/linux/virtio_ring.h"
 
-#define QVIRTIO_F_BAD_FEATURE   0x4000
+#define QVIRTIO_F_BAD_FEATURE   0x4000ull
 
 typedef struct QVirtioBus QVirtioBus;
 
@@ -52,13 +52,13 @@ struct QVirtioBus {
 uint64_t (*config_readq)(QVirtioDevice *d, uint64_t addr);
 
 /* Get features of the device */
-uint32_t (*get_features)(QVirtioDevice *d);
+uint64_t (*get_features)(QVirtioDevice *d);
 
 /* Set features of the device */
-void (*set_features)(QVirtioDevice *d, uint32_t features);
+void (*set_features)(QVirtioDevice *d, uint64_t features);
 
 /* Get features of the guest */
-uint32_t (*get_guest_features)(QVirtioDevice *d);
+uint64_t (*get_guest_features)(QVirtioDevice *d);
 
 /* Get status of the device */
 uint8_t (*get_status)(QVirtioDevice *d);
@@ -103,8 +103,8 @@ uint8_t qvirtio_config_readb(QVirtioDevice *d, uint64_t 
addr);
 uint16_t qvirtio_config_readw(QVirtioDevice *d, uint64_t addr);
 uint32_t qvirtio_config_readl(QVirtioDevice *d, uint64_t addr);
 uint64_t qvirtio_config_readq(QVirtioDevice *d, uint64_t addr);
-uint32_t qvirtio_get_features(QVirtioDevice *d);
-void qvirtio_set_features(QVirtioDevice *d, uint32_t features);
+uint64_t qvirtio_get_features(QVirtioDevice *d);
+void qvirtio_set_features(QVirtioDevice *d, uint64_t features);
 bool qvirtio_is_big_endian(QVirtioDevice *d);
 
 void qvirtio_reset(QVirtioDevice *d);
diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index 7154b03c1d..78066e6e05 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -40,22 +40,38 @@ static uint64_t qvirtio_mmio_config_readq(QVirtioDevice *d, 
uint64_t off)
 return qtest_readq(dev->qts, dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + 
off);
 }
 
-static uint32_t qvirtio_mmio_get_features(QVirtioDevice *d)
+static uint64_t qvirtio_mmio_get_features(QVirtioDevice *d)
 {
 QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+uint64_t lo;
+uint64_t hi = 0;
+
 qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 0);
-return qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
+lo = qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
+
+if (dev->version >= 2) {
+qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 1);
+hi = qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
+}
+
+return (hi << 32) | lo;
 }
 
-static void qvirtio_mmio_set_features(QVirtioDevice *d, uint32_t features)
+static void qvirtio_mmio_set_features(QVirtioDevice *d, uint64_t features)
 {
 QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
 dev->features = features;
 qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 0);
 qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES, features);
+
+if (dev->version >= 2) {
+qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 1);
+qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES,
+ features >> 32);
+}
 }
 
-static uint32_t qvirtio_mmio_get_guest_features(QVirtioDevice *d)
+static uint64_t qvirtio_mmio_get_guest_features(QVirtioDevice *d)
 {
 QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
 return dev->features;
@@ -149,8 +165,8 @@ static QVirtQueue 
*qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
 vq->free_head = 0;
 vq->num_free = vq->size;
 vq->align = dev->page_size;
-vq->indirect = (dev->features & (1u << VIRTIO_RING_F_INDIRECT_DESC)) != 0;
-vq->event = (dev->features & (1u << VIRTIO_RING_F_EVENT_IDX)) != 0;
+vq->indirect = dev->features & (1ull << VIRTIO_RING_F_INDIRECT_DESC);
+vq->event = dev->features & (1ull << VIRTIO_RING_F_EVENT_IDX);
 
 qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_NUM, vq->size);
 
diff --git a/tests/libqos/virtio-net.c b/tests/libqos/virtio-net.c
index 6567beb553..710d440c3d 100644
--- a/tests/libqos/virtio-net.c
+++ b/tests/libqos/virtio-net.c
@@ -44,11 +44,11 @@ static void virtio_net_setup(QVirtioNet *interface)
 
  

Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Aleksandar Markovic
On Saturday, October 19, 2019, Anup Patel  wrote:

> Hi,
>
> From: Aleksandar Markovic 
> Sent: Saturday, October 19, 2019 2:45 AM
> To: Anup Patel 
> Cc: Peter Maydell ; Palmer Dabbelt <
> pal...@sifive.com>; Alistair Francis ; Sagar
> Karandikar ; Bastian Koppelmann <
> kbast...@mail.uni-paderborn.de>; Atish Patra ;
> qemu-ri...@nongnu.org; qemu-devel@nongnu.org; Anup Patel <
> a...@brainfault.org>
> Subject: Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device
>
> ū
>
> On Tuesday, October 15, 2019, Anup Patel 
> wrote:
> This patch adds model for Google Goldfish virtual platform RTC device.
>
> We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
> for providing real date-time to Guest Linux. The corresponding Linux
> driver for Goldfish RTC device is already available in upstream Linux.
>
> For now, VM migration support is available but untested for Goldfish RTC
> device. It will be hardened in-future when we implement VM migration for
> KVM RISC-V.
>
> Signed-off-by: Anup Patel 
> ---
>  hw/rtc/Kconfig  |   3 +
>  hw/rtc/Makefile.objs|   1 +
>  hw/rtc/goldfish_rtc.c   | 278 
>  include/hw/timer/goldfish_rtc.h |  46 ++
>  4 files changed, 328 insertions(+)
>  create mode 100644 hw/rtc/goldfish_rtc.c
>  create mode 100644 include/hw/timer/goldfish_rtc.h
>
> Do you plan to add some other devices from Goldfish platform?
>
> [Anup] Nopes, we just needed a simple RTC device for RISC-V
> [Anup] virt machine hence this patch.
>
> [Anup] Most of the required devices are already there in
> [Anup] the VirtIO spec. The RTC device was missing in
> [Anup] VirtIO spec so instead of creating new virtual RTC
> [Anup] device we just re-use Goldfish RTC. This help us
> [Anup] re-use the Linux Goldfish RTC driver.
>
> Did you base your code on Android emulator code?
>
> [Anup] Nopes, the android emulator code seemed too simple
> [Anup] and lacking. In fact, the Linux Goldfish RTC driver does
> [Anup] much more.
>
> [Anup] Based on the documentation and Linux Goldfish RTC
> [Anup] driver, I wrote it from scratch.
>
>
Ok, that is great, nice work. I just wanted to doublecheck if we are OK
from the aspect of authorship. "Western Digital" in copyright preamble is
certainly fine in this case.

A.

[Anup] I first added Goldfish RTC emulator to Xvisor RISC-V
> [Anup] virt machine. Got it working over there and then
> [Anup] ported it to QEMU. For qemu emulation, I looked
> [Anup] at existing RTC emulators (such as PL031) for QEMU
> [Anup] API usage.
>
> Related to the previous question, are you sure the copyright line should
> go to Western Digital only?
>
> [Anup] I thought copyright will be of implementer hence I
> [Anup] put Western Digital only. The spec and Linux driver
> [Anup] can be written by totally different folks.
>
> Regards,
> Anup
>
> diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
> index 45daa8d655..bafe6ac2c9 100644
> --- a/hw/rtc/Kconfig
> +++ b/hw/rtc/Kconfig
> @@ -21,3 +21,6 @@ config MC146818RTC
>
>  config SUN4V_RTC
>  bool
> +
> +config GOLDFISH_RTC
> +bool
> diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs
> index 8dc9fcd3a9..aa208d0d10 100644
> --- a/hw/rtc/Makefile.objs
> +++ b/hw/rtc/Makefile.objs
> @@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
>  obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
>  common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
>  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
> +common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
> diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
> new file mode 100644
> index 00..223616ed75
> --- /dev/null
> +++ b/hw/rtc/goldfish_rtc.c
> @@ -0,0 +1,278 @@
> +/*
> + * Goldfish virtual platform RTC
> + *
> + * Copyright (C) 2019 Western Digital Corporation or its affiliates.
> + *
> + * For more details on Google Goldfish virtual platform refer:
> + * https://android.googlesource.com/platform/external/qemu/+/
> master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
> + *
> + * 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 .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +#include "hw/timer/goldfish_rtc.h"
> +#include "migration/vmstate.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "qemu/timer.h"
> +#include "sysemu/sysemu.h"
> +#

Re: Using virtual IOMMU in guest hypervisors other than KVM and Xen?

2019-10-18 Thread Jintack Lim
On Fri, Oct 18, 2019 at 8:37 PM Peter Xu  wrote:
>
> On Wed, Oct 16, 2019 at 03:01:22PM -0700, Jintack Lim wrote:
> > On Mon, Oct 14, 2019 at 7:50 PM Peter Xu  wrote:
> > >
> > > On Mon, Oct 14, 2019 at 01:28:49PM -0700, Jintack Lim wrote:
> > > > Hi,
> > >
> > > Hello, Jintack,
> > >
> > Hi Peter,
> >
> > > >
> > > > I'm trying to pass through a physical network device to a nested VM
> > > > using virtual IOMMU. While I was able to do it successfully using KVM
> > > > and Xen guest hypervisors running in a VM respectively, I couldn't do
> > > > it with Hyper-V as I described below. I wonder if anyone have
> > > > successfully used virtual IOMMU in other hypervisors other than KVM
> > > > and Xen? (like Hyper-V or VMware)
> > > >
> > > > The issue I have with Hyper-V is that Hyper-V gives an error that the
> > > > underlying hardware is not capable of doing passthrough. The exact
> > > > error message is as follows.
> > > >
> > > > Windows Power-shell > (Get-VMHost).IovSupportReasons
> > > > The chipset on the system does not do DMA remapping, without which
> > > > SR-IOV cannot be supported.
> > > >
> > > > I'm pretty sure that Hyper-V recognizes virtual IOMMU, though; I have
> > > > enabled iommu in windows boot loader[1], and I see differences when
> > > > booing a Windows VM with and without virtual IOMMU. I also checked
> > > > that virtual IOMMU traces are printed.
> > >
> > > What traces have you checked?  More explicitly, have you seen DMAR
> > > enabled and page table setup for that specific device to be
> > > pass-throughed?
> >
> > Thanks for the pointers. I checked that DMAR is NOT enabled. The only
> > registers that Windows guest accessed were Version Register,
> > Capability Register, and Extended Capability Register. On the other
> > hand, a Linux guest accessed other registers and enabled DMAR.
> > Here's a link to the trace I got using QEMU 4.1.0. Do you see anything
> > interesting there?
> > http://paste.ubuntu.com/p/YcSyxG9Z3x/
>
> Then I feel like Windows is reluctant to enable DMAR due to lacking of
> some caps.
>
> >
> > >
> > > >
> > > > I have tried multiple KVM/QEMU versions including the latest ones
> > > > (kernel v5.3, QEMU 4.1.0) as well as two different Windows servers
> > > > (2016 and 2019), but I see the same result. [4]
> > > >
> > > > I'd love to hear if somebody is using virtual IOMMU in Hyper-V or
> > > > VMware successfully, especially for passthrough. I also appreciate if
> > > > somebody can point out any configuration errors I have.
> > > >
> > > > Here's the qemu command line I use, basically from the QEMU vt-d
> > > > page[2] and Hyper-v on KVM from kvmforum [3].
> > > >
> > > > ./qemu/x86_64-softmmu/qemu-system-x86_64 -device
> > > > intel-iommu,intremap=on,caching-mode=on -smp 6 -m 24G -M
> > >
> > > Have you tried to use 4-level IOMMU page table (aw-bits=48 on latest
> > > QEMU, or x-aw-bits=48 on some old ones)?  IIRC we've encountered
> > > issues when trying to pass the SVVP Windows test with this, in which
> > > 4-level is required.  I'm not sure whether whether that is required in
> > > general usages of vIOMMU in Windows.
> >
> > I just tried the option you mentioned, but it didn't change anything.
> > BTW, what version of Windows was it?
>
> Sorry I don't remember that. I didn't do the test but I was just
> acknowledged that with it the test passed.  I assume you're using the
> latest QEMU here because I know Windows could require another
> capability (DMA draining) and it should be on by default in latest
> qemu master.

Thanks. Yes, I plan to use v2.11.0 eventually, but I'm trying to make
things work with the latest version first.

>
> At that time the complete cmdline to pass the test should be:
>
>   -device intel-iommu,intremap=on,aw-bits=48,caching-mode=off,eim=on
>
> I also don't remember on why caching-mode needs to be off at that
> time (otherwise SVVP fails too).

Thanks for providing the cmdline. However, turning off the
caching-mode with an assigned device resulted in the following error
on VM boot.
"We need to set caching-mode=on for intel-iommu to enable device assignment."
Does this mean that we can't assign a physical device all the way to a
nested VM with a Windows L1 hypervisor as of now?

Without assigning a device, I was able to boot a Windows VM with the
cmdline above and I see that DMAR in vIOMMU is enabled. Windows still
complains about DMA remapping, though. I'll investigate further.

>
> --
> Peter Xu
>



Re: [PATCH v2 2/2] spapr/xive: Set the OS CAM line at reset

2019-10-18 Thread Greg Kurz
On Fri, 18 Oct 2019 19:22:19 +0200
Cédric Le Goater  wrote:

> When a Virtual Processor is scheduled to run on a HW thread, the
> hypervisor pushes its identifier in the OS CAM line. When running with
> kernel_irqchip=off, QEMU needs to emulate the same behavior.
> 
> Set the OS CAM line when the interrupt presenter of the sPAPR core is
> reseted. This will also cover the case of hot-plugged CPUs.
> 
> This change also has the benefit to remove the use of CPU_FOREACH()
> which can be unsafe.
> 

Yeah, CPU_FOREACH() can bite hard... it's easy as 1-2-3 to crash QEMU with the
ones in xics_spapr_print_info() and spapr_xive_print_info(). I'll post fixes
soon.

> Signed-off-by: Cédric Le Goater 
> ---

Reviewed-by: Greg Kurz 

>  include/hw/ppc/spapr_xive.h |  1 -
>  hw/intc/spapr_xive.c| 18 +++---
>  2 files changed, 3 insertions(+), 16 deletions(-)
> 
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index d84bd5c229f0..742b7e834f2a 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -57,7 +57,6 @@ typedef struct SpaprXive {
>  void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
>  
>  void spapr_xive_hcall_init(SpaprMachineState *spapr);
> -void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx);
>  void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable);
>  void spapr_xive_map_mmio(SpaprXive *xive);
>  
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 258b1c5fb5ff..4f584e582b6c 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -210,7 +210,7 @@ void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool 
> enable)
>   * hypervisor pushes its identifier in the OS CAM line. Emulate the
>   * same behavior under QEMU.
>   */
> -void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx)
> +static void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx)
>  {
>  uint8_t  nvt_blk;
>  uint32_t nvt_idx;
> @@ -544,12 +544,6 @@ static int 
> spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
>  }
>  
>  spapr_cpu->tctx = XIVE_TCTX(obj);
> -
> -/*
> - * (TCG) Early setting the OS CAM line for hotplugged CPUs as they
> - * don't beneficiate from the reset of the XIVE IRQ backend
> - */
> -spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
>  return 0;
>  }
>  
> @@ -557,6 +551,8 @@ static void 
> spapr_xive_cpu_intc_reset(SpaprInterruptController *intc,
>   PowerPCCPU *cpu)
>  {
>  xive_tctx_reset(spapr_cpu_state(cpu)->tctx);
> +
> +spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
>  }
>  
>  static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int 
> val)
> @@ -649,14 +645,6 @@ static void spapr_xive_dt(SpaprInterruptController 
> *intc, uint32_t nr_servers,
>  static int spapr_xive_activate(SpaprInterruptController *intc, Error **errp)
>  {
>  SpaprXive *xive = SPAPR_XIVE(intc);
> -CPUState *cs;
> -
> -CPU_FOREACH(cs) {
> -PowerPCCPU *cpu = POWERPC_CPU(cs);
> -
> -/* (TCG) Set the OS CAM line of the thread interrupt context. */
> -spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
> -}
>  
>  if (kvm_enabled()) {
>  int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp);




Re: [PATCH v2 1/2] spapr: Introduce a interrupt presenter reset handler

2019-10-18 Thread Greg Kurz
On Fri, 18 Oct 2019 19:22:18 +0200
Cédric Le Goater  wrote:

> The interrupt presenters are created by a machine handler at the core
> level and are reseted independently. This is not consistent and it
> raises some issues when it comes to handle hot-plugged CPUs. These are
> reseted from the realize handler of the core and the presenters are
> not. This is less of an issue in XICS, although a zero MFFR could be a
> concern, but in XIVE, the OS CAM line is not set and this breaks the
> presenting algorithm. The current code has workarounds which need a
> global cleanup.
> 
> Extend the sPAPR IRQ backend with a new cpu_intc_reset() handler which
> will be called by the CPU reset handler and remove the XiveTCTX reset
> handler which is redundant.
> 
> spapr_realize_vcpu() is modified to call the CPU reset only after the
> intc presenter has been created.
> 
> Signed-off-by: Cédric Le Goater 
> ---
> 
>  The change of order of the CPU reset and the intc creation could be
>  in its own patch for bisect. This is fragile.
>  

And there's a nit. See below.

Otherwise, LGTM.

>  include/hw/ppc/spapr_irq.h |  2 ++
>  include/hw/ppc/xics.h  |  1 +
>  include/hw/ppc/xive.h  |  1 +
>  hw/intc/spapr_xive.c   |  7 +++
>  hw/intc/xics.c |  8 ++--
>  hw/intc/xics_spapr.c   |  7 +++
>  hw/intc/xive.c | 12 +---
>  hw/ppc/spapr_cpu_core.c| 14 ++
>  hw/ppc/spapr_irq.c | 14 ++
>  9 files changed, 45 insertions(+), 21 deletions(-)
> 
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 5e150a667902..09232999b07e 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -52,6 +52,7 @@ typedef struct SpaprInterruptControllerClass {
>   */
>  int (*cpu_intc_create)(SpaprInterruptController *intc,
>  PowerPCCPU *cpu, Error **errp);
> +void (*cpu_intc_reset)(SpaprInterruptController *intc, PowerPCCPU *cpu);
>  int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
>   Error **errp);
>  void (*free_irq)(SpaprInterruptController *intc, int irq);
> @@ -68,6 +69,7 @@ void spapr_irq_update_active_intc(SpaprMachineState *spapr);
>  
>  int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>PowerPCCPU *cpu, Error **errp);
> +void spapr_irq_cpu_intc_reset(SpaprMachineState *spapr, PowerPCCPU *cpu);
>  void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
>  void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
>void *fdt, uint32_t phandle);
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 1e6a9300eb2b..602173c12250 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -161,6 +161,7 @@ void icp_set_mfrr(ICPState *icp, uint8_t mfrr);
>  uint32_t icp_accept(ICPState *ss);
>  uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr);
>  void icp_eoi(ICPState *icp, uint32_t xirr);
> +void icp_reset(ICPState *icp);
>  
>  void ics_write_xive(ICSState *ics, int nr, int server,
>  uint8_t priority, uint8_t saved_priority);
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index fd3319bd3202..99381639f50c 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -415,6 +415,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, 
> unsigned size);
>  
>  void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
>  Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
> +void xive_tctx_reset(XiveTCTX *tctx);
>  
>  static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
>  {
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index ba32d2cc5b0f..258b1c5fb5ff 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -553,6 +553,12 @@ static int 
> spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
>  return 0;
>  }
>  
> +static void spapr_xive_cpu_intc_reset(SpaprInterruptController *intc,
> + PowerPCCPU *cpu)
> +{
> +xive_tctx_reset(spapr_cpu_state(cpu)->tctx);
> +}
> +
>  static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int 
> val)
>  {
>  SpaprXive *xive = SPAPR_XIVE(intc);
> @@ -697,6 +703,7 @@ static void spapr_xive_class_init(ObjectClass *klass, 
> void *data)
>  sicc->activate = spapr_xive_activate;
>  sicc->deactivate = spapr_xive_deactivate;
>  sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
> +sicc->cpu_intc_reset = spapr_xive_cpu_intc_reset;
>  sicc->claim_irq = spapr_xive_claim_irq;
>  sicc->free_irq = spapr_xive_free_irq;
>  sicc->set_irq = spapr_xive_set_irq;
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index b5ac408f7b74..6da05763f9db 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -274,10 +274,8 @@ static const VMStateDescription vmstate_icp_server = {
>  },
>  };
> 

RE: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Anup Patel
Hi,

From: Aleksandar Markovic  
Sent: Saturday, October 19, 2019 2:45 AM
To: Anup Patel 
Cc: Peter Maydell ; Palmer Dabbelt 
; Alistair Francis ; Sagar 
Karandikar ; Bastian Koppelmann 
; Atish Patra ; 
qemu-ri...@nongnu.org; qemu-devel@nongnu.org; Anup Patel 
Subject: Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

ū

On Tuesday, October 15, 2019, Anup Patel  wrote:
This patch adds model for Google Goldfish virtual platform RTC device.

We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
for providing real date-time to Guest Linux. The corresponding Linux
driver for Goldfish RTC device is already available in upstream Linux.

For now, VM migration support is available but untested for Goldfish RTC
device. It will be hardened in-future when we implement VM migration for
KVM RISC-V.

Signed-off-by: Anup Patel 
---
 hw/rtc/Kconfig                  |   3 +
 hw/rtc/Makefile.objs            |   1 +
 hw/rtc/goldfish_rtc.c           | 278 
 include/hw/timer/goldfish_rtc.h |  46 ++
 4 files changed, 328 insertions(+)
 create mode 100644 hw/rtc/goldfish_rtc.c
 create mode 100644 include/hw/timer/goldfish_rtc.h

Do you plan to add some other devices from Goldfish platform?

[Anup] Nopes, we just needed a simple RTC device for RISC-V
[Anup] virt machine hence this patch. 

[Anup] Most of the required devices are already there in
[Anup] the VirtIO spec. The RTC device was missing in
[Anup] VirtIO spec so instead of creating new virtual RTC
[Anup] device we just re-use Goldfish RTC. This help us
[Anup] re-use the Linux Goldfish RTC driver.

Did you base your code on Android emulator code?

[Anup] Nopes, the android emulator code seemed too simple
[Anup] and lacking. In fact, the Linux Goldfish RTC driver does
[Anup] much more.

[Anup] Based on the documentation and Linux Goldfish RTC
[Anup] driver, I wrote it from scratch.

[Anup] I first added Goldfish RTC emulator to Xvisor RISC-V
[Anup] virt machine. Got it working over there and then
[Anup] ported it to QEMU. For qemu emulation, I looked
[Anup] at existing RTC emulators (such as PL031) for QEMU
[Anup] API usage.

Related to the previous question, are you sure the copyright line should go to 
Western Digital only?

[Anup] I thought copyright will be of implementer hence I
[Anup] put Western Digital only. The spec and Linux driver
[Anup] can be written by totally different folks.

Regards,
Anup
 
diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
index 45daa8d655..bafe6ac2c9 100644
--- a/hw/rtc/Kconfig
+++ b/hw/rtc/Kconfig
@@ -21,3 +21,6 @@ config MC146818RTC

 config SUN4V_RTC
     bool
+
+config GOLDFISH_RTC
+    bool
diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs
index 8dc9fcd3a9..aa208d0d10 100644
--- a/hw/rtc/Makefile.objs
+++ b/hw/rtc/Makefile.objs
@@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
 obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
+common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
new file mode 100644
index 00..223616ed75
--- /dev/null
+++ b/hw/rtc/goldfish_rtc.c
@@ -0,0 +1,278 @@
+/*
+ * Goldfish virtual platform RTC
+ *
+ * Copyright (C) 2019 Western Digital Corporation or its affiliates.
+ *
+ * For more details on Google Goldfish virtual platform refer:
+ * 
https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
+ *
+ * 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 .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/timer/goldfish_rtc.h"
+#include "migration/vmstate.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+
+#define RTC_TIME_LOW            0x00
+#define RTC_TIME_HIGH           0x04
+#define RTC_ALARM_LOW           0x08
+#define RTC_ALARM_HIGH          0x0c
+#define RTC_IRQ_ENABLED         0x10
+#define RTC_CLEAR_ALARM         0x14
+#define RTC_ALARM_STATUS        0x18
+#define RTC_CLEAR_INTERRUPT     0x1c
+
+static void goldfish_rtc_update(GoldfishRTCState *s)
+{
+    qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
+}
+
+static void goldfish_rtc_interrupt(void *opaque)
+{
+    G

[Bug 1834113] Re: QEMU touchpad input erratic after wakeup from sleep

2019-10-18 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1834113

Title:
  QEMU touchpad input erratic after wakeup from sleep

Status in QEMU:
  Expired
Status in libvirt package in Ubuntu:
  Expired
Status in qemu package in Ubuntu:
  Expired

Bug description:
  Using Ubuntu host and guest. Normally the touchpad works great. Within
  the last few days, suddenly, apparently after a wake from sleep, the
  touchpad will behave erratically. For example, it will take two clicks
  to select something, and when moving the cursor it will act as though
  it is dragging even with the button not clicked.

  A reboot fixes the issue temporarily.

  ProblemType: Bug
  DistroRelease: Ubuntu 19.04
  Package: qemu 1:3.1+dfsg-2ubuntu3.1
  Uname: Linux 5.1.14-050114-generic x86_64
  ApportVersion: 2.20.10-0ubuntu27
  Architecture: amd64
  CurrentDesktop: ubuntu:GNOME
  Date: Mon Jun 24 20:55:44 2019
  Dependencies:
   
  EcryptfsInUse: Yes
  InstallationDate: Installed on 2019-02-20 (124 days ago)
  InstallationMedia: Ubuntu 18.04 "Bionic" - Build amd64 LIVE Binary 
20180608-09:38
  Lsusb:
   Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
   Bus 001 Device 002: ID 8087:0025 Intel Corp. 
   Bus 001 Device 003: ID 0c45:671d Microdia 
   Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
  MachineType: Dell Inc. Precision 5530
  ProcEnviron:
   TERM=xterm-256color
   PATH=(custom, no user)
   XDG_RUNTIME_DIR=
   LANG=en_US.UTF-8
   SHELL=/bin/bash
  ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-5.1.14-050114-generic 
root=UUID=18e8777c-1764-41e4-a19f-62476055de23 ro mem_sleep_default=deep 
mem_sleep_default=deep acpi_rev_override=1 scsi_mod.use_blk_mq=1 
nouveau.modeset=0 nouveau.runpm=0 nouveau.blacklist=1 acpi_backlight=none 
acpi_osi=Linux acpi_osi=!
  SourcePackage: qemu
  UpgradeStatus: No upgrade log present (probably fresh install)
  dmi.bios.date: 04/26/2019
  dmi.bios.vendor: Dell Inc.
  dmi.bios.version: 1.10.1
  dmi.board.name: 0FP2W2
  dmi.board.vendor: Dell Inc.
  dmi.board.version: A00
  dmi.chassis.type: 10
  dmi.chassis.vendor: Dell Inc.
  dmi.modalias: 
dmi:bvnDellInc.:bvr1.10.1:bd04/26/2019:svnDellInc.:pnPrecision5530:pvr:rvnDellInc.:rn0FP2W2:rvrA00:cvnDellInc.:ct10:cvr:
  dmi.product.family: Precision
  dmi.product.name: Precision 5530
  dmi.product.sku: 087D
  dmi.sys.vendor: Dell Inc.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1834113/+subscriptions



[Bug 1834113] Re: QEMU touchpad input erratic after wakeup from sleep

2019-10-18 Thread Launchpad Bug Tracker
[Expired for libvirt (Ubuntu) because there has been no activity for 60
days.]

** Changed in: libvirt (Ubuntu)
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1834113

Title:
  QEMU touchpad input erratic after wakeup from sleep

Status in QEMU:
  Expired
Status in libvirt package in Ubuntu:
  Expired
Status in qemu package in Ubuntu:
  Expired

Bug description:
  Using Ubuntu host and guest. Normally the touchpad works great. Within
  the last few days, suddenly, apparently after a wake from sleep, the
  touchpad will behave erratically. For example, it will take two clicks
  to select something, and when moving the cursor it will act as though
  it is dragging even with the button not clicked.

  A reboot fixes the issue temporarily.

  ProblemType: Bug
  DistroRelease: Ubuntu 19.04
  Package: qemu 1:3.1+dfsg-2ubuntu3.1
  Uname: Linux 5.1.14-050114-generic x86_64
  ApportVersion: 2.20.10-0ubuntu27
  Architecture: amd64
  CurrentDesktop: ubuntu:GNOME
  Date: Mon Jun 24 20:55:44 2019
  Dependencies:
   
  EcryptfsInUse: Yes
  InstallationDate: Installed on 2019-02-20 (124 days ago)
  InstallationMedia: Ubuntu 18.04 "Bionic" - Build amd64 LIVE Binary 
20180608-09:38
  Lsusb:
   Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
   Bus 001 Device 002: ID 8087:0025 Intel Corp. 
   Bus 001 Device 003: ID 0c45:671d Microdia 
   Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
  MachineType: Dell Inc. Precision 5530
  ProcEnviron:
   TERM=xterm-256color
   PATH=(custom, no user)
   XDG_RUNTIME_DIR=
   LANG=en_US.UTF-8
   SHELL=/bin/bash
  ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-5.1.14-050114-generic 
root=UUID=18e8777c-1764-41e4-a19f-62476055de23 ro mem_sleep_default=deep 
mem_sleep_default=deep acpi_rev_override=1 scsi_mod.use_blk_mq=1 
nouveau.modeset=0 nouveau.runpm=0 nouveau.blacklist=1 acpi_backlight=none 
acpi_osi=Linux acpi_osi=!
  SourcePackage: qemu
  UpgradeStatus: No upgrade log present (probably fresh install)
  dmi.bios.date: 04/26/2019
  dmi.bios.vendor: Dell Inc.
  dmi.bios.version: 1.10.1
  dmi.board.name: 0FP2W2
  dmi.board.vendor: Dell Inc.
  dmi.board.version: A00
  dmi.chassis.type: 10
  dmi.chassis.vendor: Dell Inc.
  dmi.modalias: 
dmi:bvnDellInc.:bvr1.10.1:bd04/26/2019:svnDellInc.:pnPrecision5530:pvr:rvnDellInc.:rn0FP2W2:rvrA00:cvnDellInc.:ct10:cvr:
  dmi.product.family: Precision
  dmi.product.name: Precision 5530
  dmi.product.sku: 087D
  dmi.sys.vendor: Dell Inc.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1834113/+subscriptions



[Bug 1834113] Re: QEMU touchpad input erratic after wakeup from sleep

2019-10-18 Thread Launchpad Bug Tracker
[Expired for qemu (Ubuntu) because there has been no activity for 60
days.]

** Changed in: qemu (Ubuntu)
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1834113

Title:
  QEMU touchpad input erratic after wakeup from sleep

Status in QEMU:
  Expired
Status in libvirt package in Ubuntu:
  Expired
Status in qemu package in Ubuntu:
  Expired

Bug description:
  Using Ubuntu host and guest. Normally the touchpad works great. Within
  the last few days, suddenly, apparently after a wake from sleep, the
  touchpad will behave erratically. For example, it will take two clicks
  to select something, and when moving the cursor it will act as though
  it is dragging even with the button not clicked.

  A reboot fixes the issue temporarily.

  ProblemType: Bug
  DistroRelease: Ubuntu 19.04
  Package: qemu 1:3.1+dfsg-2ubuntu3.1
  Uname: Linux 5.1.14-050114-generic x86_64
  ApportVersion: 2.20.10-0ubuntu27
  Architecture: amd64
  CurrentDesktop: ubuntu:GNOME
  Date: Mon Jun 24 20:55:44 2019
  Dependencies:
   
  EcryptfsInUse: Yes
  InstallationDate: Installed on 2019-02-20 (124 days ago)
  InstallationMedia: Ubuntu 18.04 "Bionic" - Build amd64 LIVE Binary 
20180608-09:38
  Lsusb:
   Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
   Bus 001 Device 002: ID 8087:0025 Intel Corp. 
   Bus 001 Device 003: ID 0c45:671d Microdia 
   Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
  MachineType: Dell Inc. Precision 5530
  ProcEnviron:
   TERM=xterm-256color
   PATH=(custom, no user)
   XDG_RUNTIME_DIR=
   LANG=en_US.UTF-8
   SHELL=/bin/bash
  ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-5.1.14-050114-generic 
root=UUID=18e8777c-1764-41e4-a19f-62476055de23 ro mem_sleep_default=deep 
mem_sleep_default=deep acpi_rev_override=1 scsi_mod.use_blk_mq=1 
nouveau.modeset=0 nouveau.runpm=0 nouveau.blacklist=1 acpi_backlight=none 
acpi_osi=Linux acpi_osi=!
  SourcePackage: qemu
  UpgradeStatus: No upgrade log present (probably fresh install)
  dmi.bios.date: 04/26/2019
  dmi.bios.vendor: Dell Inc.
  dmi.bios.version: 1.10.1
  dmi.board.name: 0FP2W2
  dmi.board.vendor: Dell Inc.
  dmi.board.version: A00
  dmi.chassis.type: 10
  dmi.chassis.vendor: Dell Inc.
  dmi.modalias: 
dmi:bvnDellInc.:bvr1.10.1:bd04/26/2019:svnDellInc.:pnPrecision5530:pvr:rvnDellInc.:rn0FP2W2:rvrA00:cvnDellInc.:ct10:cvr:
  dmi.product.family: Precision
  dmi.product.name: Precision 5530
  dmi.product.sku: 087D
  dmi.sys.vendor: Dell Inc.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1834113/+subscriptions



RE: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Anup Patel


> -Original Message-
> From: Alistair Francis 
> Sent: Saturday, October 19, 2019 2:29 AM
> To: Anup Patel 
> Cc: Peter Maydell ; Palmer Dabbelt
> ; Alistair Francis ; Sagar
> Karandikar ; Bastian Koppelmann
> ; Atish Patra ;
> qemu-ri...@nongnu.org; qemu-devel@nongnu.org; Anup Patel
> 
> Subject: Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device
> 
> On Tue, Oct 15, 2019 at 1:36 AM Anup Patel  wrote:
> >
> > This patch adds model for Google Goldfish virtual platform RTC device.
> >
> > We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
> > for providing real date-time to Guest Linux. The corresponding Linux
> > driver for Goldfish RTC device is already available in upstream Linux.
> >
> > For now, VM migration support is available but untested for Goldfish
> > RTC device. It will be hardened in-future when we implement VM
> > migration for KVM RISC-V.
> >
> > Signed-off-by: Anup Patel 
> > ---
> >  hw/rtc/Kconfig  |   3 +
> >  hw/rtc/Makefile.objs|   1 +
> >  hw/rtc/goldfish_rtc.c   | 278 
> >  include/hw/timer/goldfish_rtc.h |  46 ++
> >  4 files changed, 328 insertions(+)
> >  create mode 100644 hw/rtc/goldfish_rtc.c  create mode 100644
> > include/hw/timer/goldfish_rtc.h
> >
> > diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig index
> > 45daa8d655..bafe6ac2c9 100644
> > --- a/hw/rtc/Kconfig
> > +++ b/hw/rtc/Kconfig
> > @@ -21,3 +21,6 @@ config MC146818RTC
> >
> >  config SUN4V_RTC
> >  bool
> > +
> > +config GOLDFISH_RTC
> > +bool
> > diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs index
> > 8dc9fcd3a9..aa208d0d10 100644
> > --- a/hw/rtc/Makefile.objs
> > +++ b/hw/rtc/Makefile.objs
> > @@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) +=
> exynos4210_rtc.o
> >  obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
> >  common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
> >  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
> > +common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
> > diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c new file
> > mode 100644 index 00..223616ed75
> > --- /dev/null
> > +++ b/hw/rtc/goldfish_rtc.c
> > @@ -0,0 +1,278 @@
> > +/*
> > + * Goldfish virtual platform RTC
> > + *
> > + * Copyright (C) 2019 Western Digital Corporation or its affiliates.
> > + *
> > + * For more details on Google Goldfish virtual platform refer:
> > + *
> >
> +https://android.googlesource.com/platform/external/qemu/+/master/doc
> s
> > +/GOLDFISH-VIRTUAL-HARDWARE.TXT
> > + *
> > + * 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 .
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu-common.h"
> > +#include "hw/timer/goldfish_rtc.h"
> > +#include "migration/vmstate.h"
> > +#include "hw/irq.h"
> > +#include "hw/qdev-properties.h"
> > +#include "hw/sysbus.h"
> > +#include "qemu/timer.h"
> > +#include "sysemu/sysemu.h"
> > +#include "qemu/cutils.h"
> > +#include "qemu/log.h"
> > +
> > +#define RTC_TIME_LOW0x00
> > +#define RTC_TIME_HIGH   0x04
> > +#define RTC_ALARM_LOW   0x08
> > +#define RTC_ALARM_HIGH  0x0c
> > +#define RTC_IRQ_ENABLED 0x10
> > +#define RTC_CLEAR_ALARM 0x14
> > +#define RTC_ALARM_STATUS0x18
> > +#define RTC_CLEAR_INTERRUPT 0x1c
> > +
> > +static void goldfish_rtc_update(GoldfishRTCState *s) {
> > +qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
> > +}
> > +
> > +static void goldfish_rtc_interrupt(void *opaque) {
> > +GoldfishRTCState *s = (GoldfishRTCState *)opaque;
> > +
> > +s->alarm_running = 0;
> > +s->irq_pending = 1;
> > +goldfish_rtc_update(s);
> > +}
> > +
> > +static uint64_t goldfish_rtc_get_count(GoldfishRTCState *s) {
> > +return s->tick_offset + (uint64_t)qemu_clock_get_ns(rtc_clock);
> > +}
> > +
> > +static void goldfish_rtc_clear_alarm(GoldfishRTCState *s) {
> > +timer_del(s->timer);
> > +s->alarm_running = 0;
> > +}
> > +
> > +static void goldfish_rtc_set_alarm(GoldfishRTCState *s) {
> > +uint64_t ticks = goldfish_rtc_get_count(s);
> > +uint64_t event = s->alarm_next;
> > +
> > +if (event <= ticks) {
> > +goldfish_rtc_clear_alarm(s);
> > +goldfish_rtc_interrupt(s);
> > +} else {
> > +int64_t now = qemu_clock_get_ns(rtc_clock);
> > +timer_mod(s->timer, now + (event - ticks)

Re: [PATCH v2 0/4] apic: Fix migration breakage of >255 vcpus

2019-10-18 Thread Peter Xu
On Wed, Oct 16, 2019 at 11:40:01AM -0300, Eduardo Habkost wrote:
> On Wed, Oct 16, 2019 at 10:29:29AM +0800, Peter Xu wrote:
> > v2:
> > - use uint32_t rather than int64_t [Juan]
> > - one more patch (patch 4) to check dup SaveStateEntry [Dave]
> > - one more patch to define a macro (patch 1) to simplify patch 2
> > 
> > Please review, thanks.
> 
> I wonder how hard it is to write a simple test case to reproduce
> the original bug.  We can extend tests/migration-test.c or
> tests/acceptance/migration.py.  If using -device with explicit
> apic-id, we probably don't even need to create >255 VCPUs.

I can give it a shot next week. :)

-- 
Peter Xu



[PATCH] hw/xtensa: add virt machine

2019-10-18 Thread Max Filippov
virt machine is a sim machine with generic PCI host controller.
Make common parts of sim machine initialization reusable.
Add PCI controller at 0xf000 with PIO space at its base address,
ECAM space at base address + 1M and MMIO space at base address + 64M.
Connect IRQ lines to consecutive CPU external IRQ pins starting from 0.
Instantiate network interfaces on virt machine.

Xtensa linux kernel configuration virt_defconfig can successfully boot
on this machine.

Signed-off-by: Max Filippov 
---
 MAINTAINERS|   5 ++
 default-configs/xtensa-softmmu.mak |   1 +
 hw/xtensa/Kconfig  |   6 ++
 hw/xtensa/Makefile.objs|   1 +
 hw/xtensa/sim.c|  41 +
 hw/xtensa/virt.c   | 135 +
 hw/xtensa/xtensa_sim.h |  34 
 7 files changed, 208 insertions(+), 15 deletions(-)
 create mode 100644 hw/xtensa/virt.c
 create mode 100644 hw/xtensa/xtensa_sim.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 50eaf005f40e..7c2f35a2320f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1302,6 +1302,11 @@ M: Max Filippov 
 S: Maintained
 F: hw/xtensa/sim.c
 
+virt
+M: Max Filippov 
+S: Maintained
+F: hw/xtensa/virt.c
+
 XTFPGA (LX60, LX200, ML605, KC705)
 M: Max Filippov 
 S: Maintained
diff --git a/default-configs/xtensa-softmmu.mak 
b/default-configs/xtensa-softmmu.mak
index 3aa20a47a7fb..4fe1bf00c94b 100644
--- a/default-configs/xtensa-softmmu.mak
+++ b/default-configs/xtensa-softmmu.mak
@@ -5,4 +5,5 @@ CONFIG_SEMIHOSTING=y
 # Boards:
 #
 CONFIG_XTENSA_SIM=y
+CONFIG_XTENSA_VIRT=y
 CONFIG_XTENSA_XTFPGA=y
diff --git a/hw/xtensa/Kconfig b/hw/xtensa/Kconfig
index d72817d012e3..0740657ea58f 100644
--- a/hw/xtensa/Kconfig
+++ b/hw/xtensa/Kconfig
@@ -1,6 +1,12 @@
 config XTENSA_SIM
 bool
 
+config XTENSA_VIRT
+bool
+select XTENSA_SIM
+select PCI_EXPRESS_GENERIC_BRIDGE
+select PCI_DEVICES
+
 config XTENSA_XTFPGA
 bool
 select OPENCORES_ETH
diff --git a/hw/xtensa/Makefile.objs b/hw/xtensa/Makefile.objs
index 0bbfccd6deae..2b40e1b60a0e 100644
--- a/hw/xtensa/Makefile.objs
+++ b/hw/xtensa/Makefile.objs
@@ -2,4 +2,5 @@ obj-y += mx_pic.o
 obj-y += pic_cpu.o
 obj-y += xtensa_memory.o
 obj-$(CONFIG_XTENSA_SIM) += sim.o
+obj-$(CONFIG_XTENSA_VIRT) += virt.o
 obj-$(CONFIG_XTENSA_XTFPGA) += xtfpga.o
diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
index 981dbb7bbebb..a22743a3d61c 100644
--- a/hw/xtensa/sim.c
+++ b/hw/xtensa/sim.c
@@ -37,6 +37,7 @@
 #include "exec/address-spaces.h"
 #include "qemu/error-report.h"
 #include "xtensa_memory.h"
+#include "xtensa_sim.h"
 
 static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
 {
@@ -52,12 +53,11 @@ static void sim_reset(void *opaque)
 cpu_reset(CPU(cpu));
 }
 
-static void xtensa_sim_init(MachineState *machine)
+XtensaCPU *xtensa_sim_common_init(MachineState *machine)
 {
 XtensaCPU *cpu = NULL;
 CPUXtensaState *env = NULL;
 ram_addr_t ram_size = machine->ram_size;
-const char *kernel_filename = machine->kernel_filename;
 int n;
 
 for (n = 0; n < machine->smp.cpus; n++) {
@@ -89,30 +89,41 @@ static void xtensa_sim_init(MachineState *machine)
 xtensa_create_memory_regions(&sysram, "xtensa.sysram",
  get_system_memory());
 }
-
 if (serial_hd(0)) {
 xtensa_sim_open_console(serial_hd(0));
 }
-if (kernel_filename) {
-uint64_t elf_entry;
-uint64_t elf_lowaddr;
+return cpu;
+}
+
+void xtensa_sim_load_kernel(XtensaCPU *cpu, MachineState *machine)
+{
+const char *kernel_filename = machine->kernel_filename;
 #ifdef TARGET_WORDS_BIGENDIAN
-int success = load_elf(kernel_filename, NULL,
-   translate_phys_addr, cpu,
-   &elf_entry, &elf_lowaddr,
-   NULL, 1, EM_XTENSA, 0, 0);
+int big_endian = true;
 #else
-int success = load_elf(kernel_filename, NULL,
-   translate_phys_addr, cpu,
-   &elf_entry, &elf_lowaddr,
-   NULL, 0, EM_XTENSA, 0, 0);
+int big_endian = false;
 #endif
+
+if (kernel_filename) {
+uint64_t elf_entry;
+uint64_t elf_lowaddr;
+int success = load_elf(kernel_filename, NULL, translate_phys_addr, cpu,
+   &elf_entry, &elf_lowaddr, NULL, big_endian,
+   EM_XTENSA, 0, 0);
+
 if (success > 0) {
-env->pc = elf_entry;
+cpu->env.pc = elf_entry;
 }
 }
 }
 
+static void xtensa_sim_init(MachineState *machine)
+{
+XtensaCPU *cpu = xtensa_sim_common_init(machine);
+
+xtensa_sim_load_kernel(cpu, machine);
+}
+
 static void xtensa_sim_machine_init(MachineClass *mc)
 {
 mc->desc = "sim machine (" XTENSA_DEFAULT_CPU_MODEL ")";
diff --git a/hw/xtensa/virt.c b/hw/xtensa/virt.c
new file mode 100644
index 0

Re: Using virtual IOMMU in guest hypervisors other than KVM and Xen?

2019-10-18 Thread Peter Xu
On Wed, Oct 16, 2019 at 03:01:22PM -0700, Jintack Lim wrote:
> On Mon, Oct 14, 2019 at 7:50 PM Peter Xu  wrote:
> >
> > On Mon, Oct 14, 2019 at 01:28:49PM -0700, Jintack Lim wrote:
> > > Hi,
> >
> > Hello, Jintack,
> >
> Hi Peter,
> 
> > >
> > > I'm trying to pass through a physical network device to a nested VM
> > > using virtual IOMMU. While I was able to do it successfully using KVM
> > > and Xen guest hypervisors running in a VM respectively, I couldn't do
> > > it with Hyper-V as I described below. I wonder if anyone have
> > > successfully used virtual IOMMU in other hypervisors other than KVM
> > > and Xen? (like Hyper-V or VMware)
> > >
> > > The issue I have with Hyper-V is that Hyper-V gives an error that the
> > > underlying hardware is not capable of doing passthrough. The exact
> > > error message is as follows.
> > >
> > > Windows Power-shell > (Get-VMHost).IovSupportReasons
> > > The chipset on the system does not do DMA remapping, without which
> > > SR-IOV cannot be supported.
> > >
> > > I'm pretty sure that Hyper-V recognizes virtual IOMMU, though; I have
> > > enabled iommu in windows boot loader[1], and I see differences when
> > > booing a Windows VM with and without virtual IOMMU. I also checked
> > > that virtual IOMMU traces are printed.
> >
> > What traces have you checked?  More explicitly, have you seen DMAR
> > enabled and page table setup for that specific device to be
> > pass-throughed?
> 
> Thanks for the pointers. I checked that DMAR is NOT enabled. The only
> registers that Windows guest accessed were Version Register,
> Capability Register, and Extended Capability Register. On the other
> hand, a Linux guest accessed other registers and enabled DMAR.
> Here's a link to the trace I got using QEMU 4.1.0. Do you see anything
> interesting there?
> http://paste.ubuntu.com/p/YcSyxG9Z3x/

Then I feel like Windows is reluctant to enable DMAR due to lacking of
some caps.

> 
> >
> > >
> > > I have tried multiple KVM/QEMU versions including the latest ones
> > > (kernel v5.3, QEMU 4.1.0) as well as two different Windows servers
> > > (2016 and 2019), but I see the same result. [4]
> > >
> > > I'd love to hear if somebody is using virtual IOMMU in Hyper-V or
> > > VMware successfully, especially for passthrough. I also appreciate if
> > > somebody can point out any configuration errors I have.
> > >
> > > Here's the qemu command line I use, basically from the QEMU vt-d
> > > page[2] and Hyper-v on KVM from kvmforum [3].
> > >
> > > ./qemu/x86_64-softmmu/qemu-system-x86_64 -device
> > > intel-iommu,intremap=on,caching-mode=on -smp 6 -m 24G -M
> >
> > Have you tried to use 4-level IOMMU page table (aw-bits=48 on latest
> > QEMU, or x-aw-bits=48 on some old ones)?  IIRC we've encountered
> > issues when trying to pass the SVVP Windows test with this, in which
> > 4-level is required.  I'm not sure whether whether that is required in
> > general usages of vIOMMU in Windows.
> 
> I just tried the option you mentioned, but it didn't change anything.
> BTW, what version of Windows was it?

Sorry I don't remember that. I didn't do the test but I was just
acknowledged that with it the test passed.  I assume you're using the
latest QEMU here because I know Windows could require another
capability (DMA draining) and it should be on by default in latest
qemu master.

At that time the complete cmdline to pass the test should be:

  -device intel-iommu,intremap=on,aw-bits=48,caching-mode=off,eim=on

I also don't remember on why caching-mode needs to be off at that
time (otherwise SVVP fails too).

-- 
Peter Xu




Re: [PATCH 0/6] migration/postcopy: enable compress during postcopy

2019-10-18 Thread Wei Yang
On Fri, Oct 18, 2019 at 09:50:05AM -0700, no-re...@patchew.org wrote:
>Patchew URL: 
>https://patchew.org/QEMU/20191018004850.9888-1-richardw.y...@linux.intel.com/
>
>
>
>Hi,
>
>This series failed the docker-mingw@fedora build test. Please find the testing 
>commands and
>their output below. If you have Docker installed, you can probably reproduce it
>locally.
>
>=== TEST SCRIPT BEGIN ===
>#! /bin/bash
>export ARCH=x86_64
>make docker-image-fedora V=1 NETWORK=1
>time make docker-test-mingw@fedora J=14 NETWORK=1
>=== TEST SCRIPT END ===
>
>  CC  aarch64-softmmu/hw/timer/allwinner-a10-pit.o
>In file included from /tmp/qemu-test/src/migration/ram.c:29:
>/tmp/qemu-test/src/migration/ram.c: In function 'ram_load_postcopy':
>/tmp/qemu-test/src/migration/ram.c:4177:56: error: cast from pointer to 
>integer of different size [-Werror=pointer-to-int-cast]
> void *place_dest = (void *)QEMU_ALIGN_DOWN((unsigned long)host,
>^

Sounds should use uintptr_t.

Would change it in next version.

>/tmp/qemu-test/src/include/qemu/osdep.h:268:33: note: in definition of macro 
>'QEMU_ALIGN_DOWN'
> #define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
> ^
>cc1: all warnings being treated as errors
>make[1]: *** [/tmp/qemu-test/src/rules.mak:69: migration/ram.o] Error 1
>make[1]: *** Waiting for unfinished jobs
>  CC  x86_64-softmmu/target/i386/arch_dump.o
>  CC  aarch64-softmmu/hw/usb/tusb6010.o
>---
>  CC  aarch64-softmmu/hw/arm/xlnx-zynqmp.o
>In file included from /tmp/qemu-test/src/migration/ram.c:29:
>/tmp/qemu-test/src/migration/ram.c: In function 'ram_load_postcopy':
>/tmp/qemu-test/src/migration/ram.c:4177:56: error: cast from pointer to 
>integer of different size [-Werror=pointer-to-int-cast]
> void *place_dest = (void *)QEMU_ALIGN_DOWN((unsigned long)host,
>^
>/tmp/qemu-test/src/include/qemu/osdep.h:268:33: note: in definition of macro 
>'QEMU_ALIGN_DOWN'
> #define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
> ^
>cc1: all warnings being treated as errors
>make[1]: *** [/tmp/qemu-test/src/rules.mak:69: migration/ram.o] Error 1
>make[1]: *** Waiting for unfinished jobs
>make: *** [Makefile:482: aarch64-softmmu/all] Error 2
>make: *** Waiting for unfinished jobs
>make: *** [Makefile:482: x86_64-softmmu/all] Error 2
>Traceback (most recent call last):
>  File "./tests/docker/docker.py", line 662, in 
>sys.exit(main())
>---
>raise CalledProcessError(retcode, cmd)
>subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
>'--label', 'com.qemu.instance.uuid=90570434880344249cff701baa188163', '-u', 
>'1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
>'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
>'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
>'/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
>'/var/tmp/patchew-tester-tmp-dh8p6f27/src/docker-src.2019-10-18-12.47.19.4164:/var/tmp/qemu:z,ro',
> 'qemu:fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit 
>status 2.
>filter=--filter=label=com.qemu.instance.uuid=90570434880344249cff701baa188163
>make[1]: *** [docker-run] Error 1
>make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-dh8p6f27/src'
>make: *** [docker-run-test-mingw@fedora] Error 2
>
>real2m45.691s
>user0m8.390s
>
>
>The full log is available at
>http://patchew.org/logs/20191018004850.9888-1-richardw.y...@linux.intel.com/testing.docker-mingw@fedora/?type=message.
>---
>Email generated automatically by Patchew [https://patchew.org/].
>Please send your feedback to patchew-de...@redhat.com

-- 
Wei Yang
Help you, Help me



Re: [PATCH] Do not use %m in common code to print error messages

2019-10-18 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20191018104438.6158-1-th...@redhat.com/



Hi,

This series failed the docker-mingw@fedora build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#! /bin/bash
export ARCH=x86_64
make docker-image-fedora V=1 NETWORK=1
time make docker-test-mingw@fedora J=14 NETWORK=1
=== TEST SCRIPT END ===

  CC  hw/ssi/pl022.o
In file included from /tmp/qemu-test/src/hw/misc/tmp421.c:30:
/tmp/qemu-test/src/hw/misc/tmp421.c: In function 'tmp421_set_temperature':
/tmp/qemu-test/src/include/qapi/error.h:166:25: error: format '%s' expects a 
matching 'char *' argument [-Werror=format=]
 (fmt), ## __VA_ARGS__)
 ^
/tmp/qemu-test/src/hw/misc/tmp421.c:166:9: note: in expansion of macro 
'error_setg'
 error_setg(errp, "error reading %s: %s", errmsg);
 ^~
cc1: all warnings being treated as errors
make: *** [/tmp/qemu-test/src/rules.mak:69: hw/misc/tmp421.o] Error 1
make: *** Waiting for unfinished jobs
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 662, in 
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=aeeffa7799634227ba70e98b4d08d799', '-u', 
'1003', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew2/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-4zudpx4q/src/docker-src.2019-10-18-19.29.53.18800:/var/tmp/qemu:z,ro',
 'qemu:fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=aeeffa7799634227ba70e98b4d08d799
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-4zudpx4q/src'
make: *** [docker-run-test-mingw@fedora] Error 2

real2m1.697s
user0m7.284s


The full log is available at
http://patchew.org/logs/20191018104438.6158-1-th...@redhat.com/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH] Do not use %m in common code to print error messages

2019-10-18 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20191018104438.6158-1-th...@redhat.com/



Hi,

This series failed the docker-quick@centos7 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===

  CC  hw/misc/imx6_ccm.o
  CC  hw/misc/imx6ul_ccm.o
/tmp/qemu-test/src/hw/misc/tmp421.c: In function 'tmp421_set_temperature':
/tmp/qemu-test/src/hw/misc/tmp421.c:166:9: error: format '%s' expects a 
matching 'char *' argument [-Werror=format=]
 error_setg(errp, "error reading %s: %s", errmsg);
 ^
cc1: all warnings being treated as errors
  CC  hw/misc/imx7_ccm.o
  CC  hw/misc/imx2_wdt.o
make: *** [hw/misc/tmp421.o] Error 1
make: *** Waiting for unfinished jobs
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 662, in 
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=eae0544322904584b30d3ce7bcb77a82', '-u', 
'1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-786nsriq/src/docker-src.2019-10-18-19.26.59.10681:/var/tmp/qemu:z,ro',
 'qemu:centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=eae0544322904584b30d3ce7bcb77a82
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-786nsriq/src'
make: *** [docker-run-test-quick@centos7] Error 2

real2m5.578s
user0m7.522s


The full log is available at
http://patchew.org/logs/20191018104438.6158-1-th...@redhat.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH] migration: savevm_state_insert_handler: constant-time element insertion

2019-10-18 Thread Juan Quintela
Scott Cheloha  wrote:
> On Thu, Oct 17, 2019 at 10:43:08AM +0200, Juan Quintela wrote:
>> Scott Cheloha  wrote:
>> 
>> > Registering a SaveStateEntry object via savevm_state_insert_handler()
>> > is an O(n) operation because the list is a priority queue maintained by
>> > walking the list from head to tail to find a suitable insertion point.
>> >
>> > This adds considerable overhead for VMs with many such objects.  For
>> > instance, ppc64 machines with large maxmem (8T+) spend ~10% or more of
>> > their CPU time in savevm_state_insert_handler() before attempting to
>> > boot a kernel.

> I was trying to avoid churning the file more than absolutely
> necessary.  There are 18 QTAILQ_FOREACH() loops in savevm.c right now.
> Making ~15 of them double-loops doesn't make the code easier to read.

Change thecode to be something different, I agree that is more churn,
but ...

>
> I think incurring slight complexity on insertion/removal to make
> insertion fast is well worth the conceptual simplicity of addressing
> one big list of elements for every other operation.
>
>> savevm_state_handler_insert() for instance becomes even easier, just a
>> QTALIQ_INSERT_TAIL() in the proper queue, right?
>
> Yes, insertion becomes extremely obvious: you just append the element
> to the tail of its priority queue, which must already exist.
>
> But see above for the cost.
>
>> I agree with the idea of the patch.  Especially when you told us how bad
>> the performance of the current code is.
>> 
>> Out of curiosity, how many objects are we talking about?
>
> At maxmem=8T I'm seeing about 4 elements in that list.  At
> maxmem=64T I'm seeing around 262000.  The vast majority of these
> elements are "spapr_drc" objects, each of which (IIRC) corresponds to
> a 256MB chunk of address space.

We are having trouble because we have too many objects.  So, the right
approach IMHO is just to add the list of queueue.  Looking into the
functions:

static int calculate_new_instance_id(const char *idstr)
static int calculate_compat_instance_id(const char *idstr)
   * We can call QTAILQ_FOREACH in the propper subqueue

static void savevm_state_handler_insert(SaveStateEntry *nse)
   * We don't need the call if we do propper subqueues array

void unregister_savevm(DeviceState *dev, const char *idstr, void
   *opaque)
   * We can use the propper subqueue

vmstate_unregister
   * We can use the propper subqueue

bool qemu_savevm_state_blocked(Error **errp)
  * We need to loop over all queues

void qemu_savevm_state_setup(QEMUFile *f)
int qemu_savevm_state_resume_prepare(MigrationState *s)
int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy)
void qemu_savevm_state_complete_postcopy(QEMUFile *f)
int qemu_savevm_state_complete_precopy_iterable(QEMUFile *f, bool
  in_postcopy)
int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
void qemu_savevm_state_pending(QEMUFile *f, uint64_t threshold_size,
void qemu_savevm_state_cleanup(void)
int qemu_save_device_state(QEMUFile *f)
static int qemu_loadvm_state_setup(QEMUFile *f)
void qemu_loadvm_state_cleanup(void)
 * Loop over all queues

static SaveStateEntry *find_se(const char *idstr, int instance_id)
qemu_loadvm_section_part_end(QEMUFile *f, MigrationIncomingState *mis)
* we know the propper queue


But basically all the ones that we need to loop over all queues don't
have local state, so we can create a

loop_over_all_handlers() function that takes a callback and does all the
work.  They don't share states between iterations.

What do you think?
My problem with your appreach is that it makes insertion/removal more
expensive, that is where you are showing performance problems.  In the
places where we need to loop over all queues, we need to do it over all
elements anyways, so the performance difference is going to be
negigible.

Once told that, having 4 elements on that queue, it will make
"downtime" for migration "interesting", to say the least, no?  How much
size are we talking about?  Should we consider moving it to a live
section?


Later, Juan.



qemu crashing when attaching an ISO file to a virtio-scsi CD-ROM device through libvirt

2019-10-18 Thread Fernando Casas Schössow
Hi,

Today while working with two different Windows Server 2012 R2 guests I 
found that when I try to attach an ISO file to a SCSI CD-ROM device 
through libvirt (virsh or virt-manager) while the guest is running, 
qemu crashes and the following message is logged:

Assertion failed: blk_get_aio_context(d->conf.blk) == s->ctx 
(/home/buildozer/aports/main/qemu/src/qemu-4.0.0/hw/scsi/virtio-scsi.c: 
virtio_scsi_ctx_check: 246)

I can repro this at will. All I have to do is to try to attach an ISO 
file to the SCSI CDROM while the guest is running.
The SCSI controller model is virtio-scsi with iothread enabled.
Please find below all the details about my setup that I considered 
relevant but I missed something please don't hesitate to let me know:

Host arch: x86_64
Distro: Alpine Linux 3.10.2
qemu version: 4.0
Linux kernel version: 4.19.67
libvirt: 5.5.0
Emulated SCSI controller: virtio-scsi (with iothread enabled)
Guest firmware: OVMF-EFI
Guest OS: Window Server 2012 R2
Guest virtio drivers version: 171 (current stable)

qemu command line:

/usr/bin/qemu-system-x86_64 -name guest=DCHOMENET01,debug-threads=on -S 
-object 
secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-78-DCHOMENET01/master-key.aes
 
-machine pc-i440fx-4.0,accel=kvm,usb=off,dump-guest-core=on -cpu 
IvyBridge,ss=on,vmx=off,pcid=on,hypervisor=on,arat=on,tsc_adjust=on,umip=on,xsaveopt=on,hv_time,hv_relaxed,hv_vapic,hv_spinlocks=0x1fff
 
-drive 
file=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd,if=pflash,format=raw,unit=0,readonly=on
 
-drive 
file=/var/lib/libvirt/qemu/nvram/DCHOMENET01_VARS.fd,if=pflash,format=raw,unit=1
 
-m 1536 -overcommit mem-lock=off -smp 1,sockets=1,cores=1,threads=1 
-object iothread,id=iothread1 -uuid 
f06978ad-2734-44ab-a518-5dfcf71d625e -no-user-config -nodefaults 
-chardev socket,id=charmonitor,fd=33,server,nowait -mon 
chardev=charmonitor,id=monitor,mode=control -rtc 
base=localtime,driftfix=slew -global kvm-pit.lost_tick_policy=delay 
-no-hpet -no-shutdown -global PIIX4_PM.disable_s3=1 -global 
PIIX4_PM.disable_s4=1 -boot strict=on -device 
qemu-xhci,id=usb,bus=pci.0,addr=0x4 -device 
virtio-scsi-pci,iothread=iothread1,id=scsi0,num_queues=1,bus=pci.0,addr=0x5 
-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 -drive 
file=/storage/storage-hdd-vms/virtual_machines_hdd/dchomenet01.qcow2,format=qcow2,if=none,id=drive-scsi0-0-0-0,cache=none,discard=unmap,aio=threads
 
-device 
scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,device_id=drive-scsi0-0-0-0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=1,write-cache=on
 
-drive if=none,id=drive-scsi0-0-0-1,readonly=on -device 
scsi-cd,bus=scsi0.0,channel=0,scsi-id=0,lun=1,device_id=drive-scsi0-0-0-1,drive=drive-scsi0-0-0-1,id=scsi0-0-0-1
 
-netdev tap,fd=41,id=hostnet0,vhost=on,vhostfd=43 -device 
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:99:b5:62,bus=pci.0,addr=0x3 
-chardev 
socket,id=charserial0,host=127.0.0.1,port=4900,telnet,server,nowait 
-device isa-serial,chardev=charserial0,id=serial0 -chardev 
spicevmc,id=charchannel0,name=vdagent -device 
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
 
-chardev socket,id=charchannel1,fd=45,server,nowait -device 
virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=org.qemu.guest_agent.0
 
-chardev spiceport,id=charchannel2,name=org.spice-space.webdav.0 
-device 
virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel2,id=channel2,name=org.spice-space.webdav.0
 
-device virtio-tablet-pci,id=input2,bus=pci.0,addr=0x7 -spice 
port=5900,addr=127.0.0.1,disable-ticketing,seamless-migration=on 
-device 
qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pci.0,addr=0x2
 
-chardev spicevmc,id=charredir0,name=usbredir -device 
usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 -chardev 
spicevmc,id=charredir1,name=usbredir -device 
usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 -device 
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 -sandbox 
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny 
-msg timestamp=on

I can provide a core dump of the process if needed for debugging and 
the guest XML as well.

Thanks.

Fernando




qemu crashing when attaching an ISO file to a virtio-scsi CD-ROM device through libvirt

2019-10-18 Thread Fernando Casas Schössow
Hi,

Today while working with two different Windows Server 2012 R2 guests I found 
that when I try to attach an ISO file to a SCSI CD-ROM device through libvirt 
(virsh or virt-manager) while the guest is running, qemu crashes and the 
following message is logged:

Assertion failed: blk_get_aio_context(d->conf.blk) == s->ctx 
(/home/buildozer/aports/main/qemu/src/qemu-4.0.0/hw/scsi/virtio-scsi.c: 
virtio_scsi_ctx_check: 246)

I can repro this at will. All I have to do is to try to attach an ISO file to 
the SCSI CDROM while the guest is running.
The SCSI controller model is virtio-scsi with iothread enabled.
Please find below all the details about my setup that I considered relevant but 
I missed something please don't hesitate to let me know:

Host arch: x86_64
Distro: Alpine Linux 3.10.2
qemu version: 4.0
Linux kernel version: 4.19.67
libvirt: 5.5.0
Emulated SCSI controller: virtio-scsi (with iothread enabled)
Guest firmware: OVMF-EFI
Guest OS: Window Server 2012 R2
Guest virtio drivers version: 171 (current stable)

qemu command line:

/usr/bin/qemu-system-x86_64 -name guest=DCHOMENET01,debug-threads=on -S -object 
secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-78-DCHOMENET01/master-key.aes
 -machine pc-i440fx-4.0,accel=kvm,usb=off,dump-guest-core=on -cpu 
IvyBridge,ss=on,vmx=off,pcid=on,hypervisor=on,arat=on,tsc_adjust=on,umip=on,xsaveopt=on,hv_time,hv_relaxed,hv_vapic,hv_spinlocks=0x1fff
 -drive 
file=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd,if=pflash,format=raw,unit=0,readonly=on
 -drive 
file=/var/lib/libvirt/qemu/nvram/DCHOMENET01_VARS.fd,if=pflash,format=raw,unit=1
 -m 1536 -overcommit mem-lock=off -smp 1,sockets=1,cores=1,threads=1 -object 
iothread,id=iothread1 -uuid f06978ad-2734-44ab-a518-5dfcf71d625e 
-no-user-config -nodefaults -chardev socket,id=charmonitor,fd=33,server,nowait 
-mon chardev=charmonitor,id=monitor,mode=control -rtc 
base=localtime,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet 
-no-shutdown -global PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -boot 
strict=on -device qemu-xhci,id=usb,bus=pci.0,addr=0x4 -device 
virtio-scsi-pci,iothread=iothread1,id=scsi0,num_queues=1,bus=pci.0,addr=0x5 
-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 -drive 
file=/storage/storage-hdd-vms/virtual_machines_hdd/dchomenet01.qcow2,format=qcow2,if=none,id=drive-scsi0-0-0-0,cache=none,discard=unmap,aio=threads
 -device 
scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,device_id=drive-scsi0-0-0-0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=1,write-cache=on
 -drive if=none,id=drive-scsi0-0-0-1,readonly=on -device 
scsi-cd,bus=scsi0.0,channel=0,scsi-id=0,lun=1,device_id=drive-scsi0-0-0-1,drive=drive-scsi0-0-0-1,id=scsi0-0-0-1
 -netdev tap,fd=41,id=hostnet0,vhost=on,vhostfd=43 -device 
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:99:b5:62,bus=pci.0,addr=0x3 
-chardev socket,id=charserial0,host=127.0.0.1,port=4900,telnet,server,nowait 
-device isa-serial,chardev=charserial0,id=serial0 -chardev 
spicevmc,id=charchannel0,name=vdagent -device 
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
 -chardev socket,id=charchannel1,fd=45,server,nowait -device 
virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=org.qemu.guest_agent.0
 -chardev spiceport,id=charchannel2,name=org.spice-space.webdav.0 -device 
virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel2,id=channel2,name=org.spice-space.webdav.0
 -device virtio-tablet-pci,id=input2,bus=pci.0,addr=0x7 -spice 
port=5900,addr=127.0.0.1,disable-ticketing,seamless-migration=on -device 
qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pci.0,addr=0x2
 -chardev spicevmc,id=charredir0,name=usbredir -device 
usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 -chardev 
spicevmc,id=charredir1,name=usbredir -device 
usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 -device 
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 -sandbox 
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny -msg 
timestamp=on

I can provide a core dump of the process if needed for debugging and the guest 
XML as well.

Thanks.

Fernando




Re: [PATCH] configure: Require Python >= 3.5

2019-10-18 Thread John Snow



On 10/18/19 5:14 PM, Eduardo Habkost wrote:
> On Fri, Oct 18, 2019 at 05:07:36PM -0400, John Snow wrote:
>>
>>
>> On 10/16/19 6:42 PM, Eduardo Habkost wrote:
>>> Python 3.5 is the oldest Python version available on our
>>> supported build platforms, and Python 2 end of life will be 3
>>> weeks after the planned release date of QEMU 4.2.0.  Drop Python
>>> 2 support from configure completely, and require Python 3.5 or
>>> newer.
>>>
>>
>> Which distributions constrain us to 3.5 right now? I know Debian9 is one
>> of them, but I'm not sure what others exist.
>>
>> I know I went through and checked a month ago, but I'm very smart and
>> didn't write it down.
>>
>> It might be nice to document (somewhere) so we know when we can require
>> something newer than 3.5 at the next major deprecation event.
> 
> I've summarized the release dates and Python version information I
> could find here: https://wiki.qemu.org/Supported_Build_Platforms
> 

You are an ABSOLUTE CHAMPION. Thank you so much!



Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Aleksandar Markovic
ū

On Tuesday, October 15, 2019, Anup Patel  wrote:

> This patch adds model for Google Goldfish virtual platform RTC device.
>
> We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
> for providing real date-time to Guest Linux. The corresponding Linux
> driver for Goldfish RTC device is already available in upstream Linux.
>
> For now, VM migration support is available but untested for Goldfish RTC
> device. It will be hardened in-future when we implement VM migration for
> KVM RISC-V.
>
> Signed-off-by: Anup Patel 
> ---
>  hw/rtc/Kconfig  |   3 +
>  hw/rtc/Makefile.objs|   1 +
>  hw/rtc/goldfish_rtc.c   | 278 
>  include/hw/timer/goldfish_rtc.h |  46 ++
>  4 files changed, 328 insertions(+)
>  create mode 100644 hw/rtc/goldfish_rtc.c
>  create mode 100644 include/hw/timer/goldfish_rtc.h
>
>
Do you plan to add some other devices from Goldfish platform?

Did you base your code on Android emulator code?

Related to the previous question, are you sure the copyright line should go
to Western Digital only?

Thanks, A.




> diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
> index 45daa8d655..bafe6ac2c9 100644
> --- a/hw/rtc/Kconfig
> +++ b/hw/rtc/Kconfig
> @@ -21,3 +21,6 @@ config MC146818RTC
>
>  config SUN4V_RTC
>  bool
> +
> +config GOLDFISH_RTC
> +bool
> diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs
> index 8dc9fcd3a9..aa208d0d10 100644
> --- a/hw/rtc/Makefile.objs
> +++ b/hw/rtc/Makefile.objs
> @@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
>  obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
>  common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
>  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
> +common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
> diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
> new file mode 100644
> index 00..223616ed75
> --- /dev/null
> +++ b/hw/rtc/goldfish_rtc.c
> @@ -0,0 +1,278 @@
> +/*
> + * Goldfish virtual platform RTC
> + *
> + * Copyright (C) 2019 Western Digital Corporation or its affiliates.
> + *
> + * For more details on Google Goldfish virtual platform refer:
> + * https://android.googlesource.com/platform/external/qemu/+/
> master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
> + *
> + * 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 .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +#include "hw/timer/goldfish_rtc.h"
> +#include "migration/vmstate.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "qemu/timer.h"
> +#include "sysemu/sysemu.h"
> +#include "qemu/cutils.h"
> +#include "qemu/log.h"
> +
> +#define RTC_TIME_LOW0x00
> +#define RTC_TIME_HIGH   0x04
> +#define RTC_ALARM_LOW   0x08
> +#define RTC_ALARM_HIGH  0x0c
> +#define RTC_IRQ_ENABLED 0x10
> +#define RTC_CLEAR_ALARM 0x14
> +#define RTC_ALARM_STATUS0x18
> +#define RTC_CLEAR_INTERRUPT 0x1c
> +
> +static void goldfish_rtc_update(GoldfishRTCState *s)
> +{
> +qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
> +}
> +
> +static void goldfish_rtc_interrupt(void *opaque)
> +{
> +GoldfishRTCState *s = (GoldfishRTCState *)opaque;
> +
> +s->alarm_running = 0;
> +s->irq_pending = 1;
> +goldfish_rtc_update(s);
> +}
> +
> +static uint64_t goldfish_rtc_get_count(GoldfishRTCState *s)
> +{
> +return s->tick_offset + (uint64_t)qemu_clock_get_ns(rtc_clock);
> +}
> +
> +static void goldfish_rtc_clear_alarm(GoldfishRTCState *s)
> +{
> +timer_del(s->timer);
> +s->alarm_running = 0;
> +}
> +
> +static void goldfish_rtc_set_alarm(GoldfishRTCState *s)
> +{
> +uint64_t ticks = goldfish_rtc_get_count(s);
> +uint64_t event = s->alarm_next;
> +
> +if (event <= ticks) {
> +goldfish_rtc_clear_alarm(s);
> +goldfish_rtc_interrupt(s);
> +} else {
> +int64_t now = qemu_clock_get_ns(rtc_clock);
> +timer_mod(s->timer, now + (event - ticks));
> +s->alarm_running = 1;
> +}
> +}
> +
> +static uint64_t goldfish_rtc_read(void *opaque, hwaddr offset,
> +  unsigned size)
> +{
> +GoldfishRTCState *s = (GoldfishRTCState *)opaque;
> +uint64_t r;
> +
> +switch (offset) {
> +case RTC_TIME_LOW:
> +r = goldfish_rtc_get_count(s) & 0x;
> +break;
> +case RT

Re: [PATCH] configure: Require Python >= 3.5

2019-10-18 Thread Eduardo Habkost
On Fri, Oct 18, 2019 at 05:07:36PM -0400, John Snow wrote:
> 
> 
> On 10/16/19 6:42 PM, Eduardo Habkost wrote:
> > Python 3.5 is the oldest Python version available on our
> > supported build platforms, and Python 2 end of life will be 3
> > weeks after the planned release date of QEMU 4.2.0.  Drop Python
> > 2 support from configure completely, and require Python 3.5 or
> > newer.
> > 
> 
> Which distributions constrain us to 3.5 right now? I know Debian9 is one
> of them, but I'm not sure what others exist.
> 
> I know I went through and checked a month ago, but I'm very smart and
> didn't write it down.
> 
> It might be nice to document (somewhere) so we know when we can require
> something newer than 3.5 at the next major deprecation event.

I've summarized the release dates and Python version information I
could find here: https://wiki.qemu.org/Supported_Build_Platforms

> 
> > Signed-off-by: Eduardo Habkost 
> 
> 
> Reviewed-by: John Snow 

Thanks!

-- 
Eduardo



Re: [PATCH] iotests: Remove 130 from the "auto" group

2019-10-18 Thread John Snow



On 10/18/19 12:10 PM, Thomas Huth wrote:
> Peter hit a "Could not open 'TEST_DIR/t.IMGFMT': Failed to get shared
> 'write' lock - Is another process using the image [TEST_DIR/t.IMGFMT]?"
> error with 130 already twice. Looks like this test is a little bit
> shaky, and currently nobody has a real clue what could be causing this
> issue, so for the time being, let's disable it from the "auto" group so
> that it does not gate the pull requests.
> 
> Signed-off-by: Thomas Huth 

Reviewed-by: John Snow 

> ---
>  tests/qemu-iotests/group | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
> index 7dac79a783..6aa4b8d098 100644
> --- a/tests/qemu-iotests/group
> +++ b/tests/qemu-iotests/group
> @@ -151,7 +151,7 @@
>  127 rw backing quick
>  128 rw quick
>  129 rw quick
> -130 rw auto quick
> +130 rw quick
>  131 rw quick
>  132 rw quick
>  133 auto quick
> 

-- 
—js



Re: [PATCH] configure: Require Python >= 3.5

2019-10-18 Thread John Snow



On 10/16/19 6:42 PM, Eduardo Habkost wrote:
> Python 3.5 is the oldest Python version available on our
> supported build platforms, and Python 2 end of life will be 3
> weeks after the planned release date of QEMU 4.2.0.  Drop Python
> 2 support from configure completely, and require Python 3.5 or
> newer.
> 

Which distributions constrain us to 3.5 right now? I know Debian9 is one
of them, but I'm not sure what others exist.

I know I went through and checked a month ago, but I'm very smart and
didn't write it down.

It might be nice to document (somewhere) so we know when we can require
something newer than 3.5 at the next major deprecation event.

> Signed-off-by: Eduardo Habkost 


Reviewed-by: John Snow 

Thanks!

> ---
>  configure  | 18 --
>  tests/Makefile.include |  5 -
>  2 files changed, 4 insertions(+), 19 deletions(-)
> 
> diff --git a/configure b/configure
> index 08ca4bcb46..870657ec7b 100755
> --- a/configure
> +++ b/configure
> @@ -895,9 +895,9 @@ fi
>  : ${install=${INSTALL-install}}
>  # We prefer python 3.x. A bare 'python' is traditionally
>  # python 2.x, but some distros have it as python 3.x, so
> -# we check that before python2
> +# we check that too
>  python=
> -for binary in "${PYTHON-python3}" python python2
> +for binary in "${PYTHON-python3}" python
>  do
>  if has "$binary"
>  then
> @@ -1824,8 +1824,8 @@ fi
>  
>  # Note that if the Python conditional here evaluates True we will exit
>  # with status 1 which is a shell 'false' value.
> -if ! $python -c 'import sys; sys.exit(sys.version_info < (2,7))'; then
> -  error_exit "Cannot use '$python', Python 2 >= 2.7 or Python 3 is 
> required." \
> +if ! $python -c 'import sys; sys.exit(sys.version_info < (3,5))'; then
> +  error_exit "Cannot use '$python', Python >= 3.5 is required." \
>"Use --python=/path/to/python to specify a supported Python."
>  fi
>  
> @@ -6456,15 +6456,6 @@ if test "$supported_os" = "no"; then
>  echo "us upstream at qemu-devel@nongnu.org."
>  fi
>  
> -# Note that if the Python conditional here evaluates True we will exit
> -# with status 1 which is a shell 'false' value.
> -if ! $python -c 'import sys; sys.exit(sys.version_info < (3,0))'; then
> -  echo
> -  echo "warning: Python 2 support is deprecated" >&2
> -  echo "warning: Python 3 will be required for building future versions of 
> QEMU" >&2
> -  python2="y"
> -fi
> -
>  config_host_mak="config-host.mak"
>  
>  echo "# Automatically generated by configure - do not modify" 
> >config-all-disas.mak
> @@ -7282,7 +7273,6 @@ echo "INSTALL_DATA=$install -c -m 0644" >> 
> $config_host_mak
>  echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak
>  echo "INSTALL_LIB=$install -c -m 0644" >> $config_host_mak
>  echo "PYTHON=$python" >> $config_host_mak
> -echo "PYTHON2=$python2" >> $config_host_mak
>  echo "CC=$cc" >> $config_host_mak
>  if $iasl -h > /dev/null 2>&1; then
>echo "IASL=$iasl" >> $config_host_mak
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 3543451ed3..54ee1f0a2f 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -1137,7 +1137,6 @@ TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results
>  AVOCADO_SHOW=app
>  AVOCADO_TAGS=$(patsubst %-softmmu,-t arch:%, $(filter 
> %-softmmu,$(TARGET_DIRS)))
>  
> -ifneq ($(PYTHON2),y)
>  $(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
>   $(call quiet-command, \
>  $(PYTHON) -m venv --system-site-packages $@, \
> @@ -1146,10 +1145,6 @@ $(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
>  $(TESTS_VENV_DIR)/bin/python -m pip -q install -r 
> $(TESTS_VENV_REQ), \
>  PIP, $(TESTS_VENV_REQ))
>   $(call quiet-command, touch $@)
> -else
> -$(TESTS_VENV_DIR):
> - $(error "venv directory for tests requires Python 3")
> -endif
>  
>  $(TESTS_RESULTS_DIR):
>   $(call quiet-command, mkdir -p $@, \
> 



Re: [PATCH v3 2/2] riscv: virt: Use Goldfish RTC device

2019-10-18 Thread Alistair Francis
On Tue, Oct 15, 2019 at 1:37 AM Anup Patel  wrote:
>
> We extend QEMU RISC-V virt machine by adding Goldfish RTC device
> to it. This will allow Guest Linux to sync it's local date/time
> with Host date/time via RTC device.
>
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/Kconfig|  1 +
>  hw/riscv/virt.c | 15 +++
>  include/hw/riscv/virt.h |  2 ++
>  3 files changed, 18 insertions(+)
>
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index fb19b2df3a..b33753c780 100644
> --- a/hw/riscv/Kconfig
> +++ b/hw/riscv/Kconfig
> @@ -34,6 +34,7 @@ config RISCV_VIRT
>  select PCI
>  select HART
>  select SERIAL
> +select GOLDFISH_RTC
>  select VIRTIO_MMIO
>  select PCI_EXPRESS_GENERIC_BRIDGE
>  select SIFIVE
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index d36f5625ec..95c42ab993 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -57,6 +57,7 @@ static const struct MemmapEntry {
>  [VIRT_DEBUG] =   {0x0, 0x100 },
>  [VIRT_MROM] ={ 0x1000,   0x11000 },
>  [VIRT_TEST] ={   0x10,0x1000 },
> +[VIRT_RTC] = {   0x101000,0x1000 },
>  [VIRT_CLINT] =   {  0x200,   0x1 },
>  [VIRT_PLIC] ={  0xc00, 0x400 },
>  [VIRT_UART0] =   { 0x1000, 0x100 },
> @@ -310,6 +311,17 @@ static void create_fdt(RISCVVirtState *s, const struct 
> MemmapEntry *memmap,
>  qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
>  qemu_fdt_setprop_cell(fdt, nodename, "interrupts", UART0_IRQ);
>
> +nodename = g_strdup_printf("/rtc@%lx",
> +(long)memmap[VIRT_RTC].base);
> +qemu_fdt_add_subnode(fdt, nodename);
> +qemu_fdt_setprop_string(fdt, nodename, "compatible",
> +"google,goldfish-rtc");
> +qemu_fdt_setprop_cells(fdt, nodename, "reg",
> +0x0, memmap[VIRT_RTC].base,
> +0x0, memmap[VIRT_RTC].size);
> +qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
> +qemu_fdt_setprop_cell(fdt, nodename, "interrupts", RTC_IRQ);
> +
>  qemu_fdt_add_subnode(fdt, "/chosen");
>  qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
>  if (cmdline) {
> @@ -496,6 +508,9 @@ static void riscv_virt_board_init(MachineState *machine)
>  0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
>  serial_hd(0), DEVICE_LITTLE_ENDIAN);
>
> +sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base,
> +qdev_get_gpio_in(DEVICE(s->plic), RTC_IRQ));
> +
>  g_free(plic_hart_config);
>  }
>
> diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> index 6e5fbe5d3b..e6423258d3 100644
> --- a/include/hw/riscv/virt.h
> +++ b/include/hw/riscv/virt.h
> @@ -37,6 +37,7 @@ enum {
>  VIRT_DEBUG,
>  VIRT_MROM,
>  VIRT_TEST,
> +VIRT_RTC,
>  VIRT_CLINT,
>  VIRT_PLIC,
>  VIRT_UART0,
> @@ -49,6 +50,7 @@ enum {
>
>  enum {
>  UART0_IRQ = 10,
> +RTC_IRQ = 11,
>  VIRTIO_IRQ = 1, /* 1 to 8 */
>  VIRTIO_COUNT = 8,
>  PCIE_IRQ = 0x20, /* 32 to 35 */
> --
> 2.17.1
>
>



Re: [PATCH] configure: Require Python >= 3.5

2019-10-18 Thread John Snow



On 10/18/19 4:15 AM, Kevin Wolf wrote:
> Am 17.10.2019 um 21:39 hat John Snow geschrieben:
>> On 10/17/19 7:21 AM, Kevin Wolf wrote:
>>> Am 17.10.2019 um 00:48 hat John Snow geschrieben:
 On 10/16/19 6:42 PM, Eduardo Habkost wrote:
> Python 3.5 is the oldest Python version available on our
> supported build platforms, and Python 2 end of life will be 3
> weeks after the planned release date of QEMU 4.2.0.  Drop Python
> 2 support from configure completely, and require Python 3.5 or
> newer.
>
> Signed-off-by: Eduardo Habkost 

 Seems like a good time and place to mention this. Kevin, you require
 3.6+ for iotests, which are -- at present -- invoked as part of "make
 check".

 Do we care? Basically, this just means that iotests won't run for
 systems that don't have 3.6+, which would be platforms like Debian 9 --
 which is why ehabkost is choosing 3.5 here.
>>>
>>> I think we were aware of this when we made the change to iotests. That
>>> all tests of the current upstream QEMU version are run on Debian
>>> oldstable (with the distro Python version) is, to say the least, not a
>>> priority for me. They must not fail, but I'd say skipping is fine.
>>>
>>> And actually, we should still have a reasonable coverage there with the
>>> shell-based test cases.
>>
>> This seems like a weirdly arbitrary decision for a benefit that's not
>> clear to me. Is it because you want variable annotations?
> 
> Yes, the discussion about type annotations is what made me check whether
> we could do 3.6, because if we want to make use of type checking, we'll
> need it for both functions and variables to get reasonable results.
> 
> And actually, we currently don't have any Python tests in the auto
> group, so the only effect is for people manually running ./check on
> Debian oldstable. I'm not sure, but I suspect this might be the empty
> set.
> 
> Kevin
> 

It would have an effect on `make docker-test-block@debian-amd64" I
think, but I guess nobody runs that right now.

Well, alright.

--js



Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Alistair Francis
On Tue, Oct 15, 2019 at 1:36 AM Anup Patel  wrote:
>
> This patch adds model for Google Goldfish virtual platform RTC device.
>
> We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
> for providing real date-time to Guest Linux. The corresponding Linux
> driver for Goldfish RTC device is already available in upstream Linux.
>
> For now, VM migration support is available but untested for Goldfish RTC
> device. It will be hardened in-future when we implement VM migration for
> KVM RISC-V.
>
> Signed-off-by: Anup Patel 
> ---
>  hw/rtc/Kconfig  |   3 +
>  hw/rtc/Makefile.objs|   1 +
>  hw/rtc/goldfish_rtc.c   | 278 
>  include/hw/timer/goldfish_rtc.h |  46 ++
>  4 files changed, 328 insertions(+)
>  create mode 100644 hw/rtc/goldfish_rtc.c
>  create mode 100644 include/hw/timer/goldfish_rtc.h
>
> diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
> index 45daa8d655..bafe6ac2c9 100644
> --- a/hw/rtc/Kconfig
> +++ b/hw/rtc/Kconfig
> @@ -21,3 +21,6 @@ config MC146818RTC
>
>  config SUN4V_RTC
>  bool
> +
> +config GOLDFISH_RTC
> +bool
> diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs
> index 8dc9fcd3a9..aa208d0d10 100644
> --- a/hw/rtc/Makefile.objs
> +++ b/hw/rtc/Makefile.objs
> @@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
>  obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
>  common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
>  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
> +common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
> diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
> new file mode 100644
> index 00..223616ed75
> --- /dev/null
> +++ b/hw/rtc/goldfish_rtc.c
> @@ -0,0 +1,278 @@
> +/*
> + * Goldfish virtual platform RTC
> + *
> + * Copyright (C) 2019 Western Digital Corporation or its affiliates.
> + *
> + * For more details on Google Goldfish virtual platform refer:
> + * 
> https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
> + *
> + * 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 .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +#include "hw/timer/goldfish_rtc.h"
> +#include "migration/vmstate.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "qemu/timer.h"
> +#include "sysemu/sysemu.h"
> +#include "qemu/cutils.h"
> +#include "qemu/log.h"
> +
> +#define RTC_TIME_LOW0x00
> +#define RTC_TIME_HIGH   0x04
> +#define RTC_ALARM_LOW   0x08
> +#define RTC_ALARM_HIGH  0x0c
> +#define RTC_IRQ_ENABLED 0x10
> +#define RTC_CLEAR_ALARM 0x14
> +#define RTC_ALARM_STATUS0x18
> +#define RTC_CLEAR_INTERRUPT 0x1c
> +
> +static void goldfish_rtc_update(GoldfishRTCState *s)
> +{
> +qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
> +}
> +
> +static void goldfish_rtc_interrupt(void *opaque)
> +{
> +GoldfishRTCState *s = (GoldfishRTCState *)opaque;
> +
> +s->alarm_running = 0;
> +s->irq_pending = 1;
> +goldfish_rtc_update(s);
> +}
> +
> +static uint64_t goldfish_rtc_get_count(GoldfishRTCState *s)
> +{
> +return s->tick_offset + (uint64_t)qemu_clock_get_ns(rtc_clock);
> +}
> +
> +static void goldfish_rtc_clear_alarm(GoldfishRTCState *s)
> +{
> +timer_del(s->timer);
> +s->alarm_running = 0;
> +}
> +
> +static void goldfish_rtc_set_alarm(GoldfishRTCState *s)
> +{
> +uint64_t ticks = goldfish_rtc_get_count(s);
> +uint64_t event = s->alarm_next;
> +
> +if (event <= ticks) {
> +goldfish_rtc_clear_alarm(s);
> +goldfish_rtc_interrupt(s);
> +} else {
> +int64_t now = qemu_clock_get_ns(rtc_clock);
> +timer_mod(s->timer, now + (event - ticks));

Isn't this just: event - s->tick_offset?

> +s->alarm_running = 1;
> +}
> +}
> +
> +static uint64_t goldfish_rtc_read(void *opaque, hwaddr offset,
> +  unsigned size)
> +{
> +GoldfishRTCState *s = (GoldfishRTCState *)opaque;
> +uint64_t r;

There should be a trace or debug print showing read/write operations.

> +
> +switch (offset) {
> +case RTC_TIME_LOW:
> +r = goldfish_rtc_get_count(s) & 0x;
> +break;
> +case RTC_TIME_HIGH:
> +r = goldfish_rtc_get_count(s) >> 32;
> +break;
> +case RTC_ALARM_LOW:
> +r

Re: [PATCH] qemu-img.texi: Describe data_file and data_file_raw

2019-10-18 Thread John Snow
CC qemu-block

On 10/18/19 5:59 AM, Han Han wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1763105
> 
> Signed-off-by: Han Han 
> ---
>  qemu-img.texi | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/qemu-img.texi b/qemu-img.texi
> index b5156d6316..44596c2d93 100644
> --- a/qemu-img.texi
> +++ b/qemu-img.texi
> @@ -763,6 +763,16 @@ file which is COW and has data blocks already, it 
> couldn't be changed to NOCOW
>  by setting @code{nocow=on}. One can issue @code{lsattr filename} to check if
>  the NOCOW flag is set or not (Capital 'C' is NOCOW flag).
>  
> +@item data_file
> +File name of data file that is stored in the image and used as a default for
> +opening the image. If the option is used, qcow2 file only stores the metadata
> +of the image.
> +

This is a little unclear, and seems to imply the data file is stored
*IN* the image.

"Optional filename to be used as a data store for this qcow2 file. If
this option is used, the qcow2 file only stores metadata for this image."

> +@item data_file_raw
> +This option requires @option{data_file}. If this option is set to @code{on},
> +qemu will always keep the external data file consistent as a standalone
> +read-only raw image. Default value is @code{off}.
> +
>  @end table
>  
>  @item Other
> 




Re: [PATCH v2 1/1] riscv/boot: Fix possible memory leak

2019-10-18 Thread Palmer Dabbelt

On Thu, 17 Oct 2019 05:08:39 PDT (-0700), Peter Maydell wrote:

Ping? It would be nice to see this patch get into master
to silence the coverity errors.


Sorry, it looks like I dropped this.  It's in my queue, I hope to submit a PR 
soon.




thanks
-- PMM

On Thu, 3 Oct 2019 at 18:05, Alistair Francis  wrote:


Coverity (CID 1405786) thinks that there is a possible memory leak as
we don't guarantee that the memory allocated from riscv_find_firmware()
is freed. This is a false positive, but let's tidy up the code to fix
the warning.

Signed-off-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Reviewed-by: Bin Meng 
Reviewed-by: Philippe Mathieu-Daudé 
---
v2:
 - Fix commit typos

 hw/riscv/boot.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 2e92fb0680..7fee98d2f8 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -38,7 +38,7 @@ void riscv_find_and_load_firmware(MachineState *machine,
   const char *default_machine_firmware,
   hwaddr firmware_load_addr)
 {
-char *firmware_filename;
+char *firmware_filename = NULL;

 if (!machine->firmware) {
 /*
@@ -70,14 +70,11 @@ void riscv_find_and_load_firmware(MachineState *machine,
  * if no -bios option is set without breaking anything.
  */
 firmware_filename = riscv_find_firmware(default_machine_firmware);
-} else {
-firmware_filename = machine->firmware;
-if (strcmp(firmware_filename, "none")) {
-firmware_filename = riscv_find_firmware(firmware_filename);
-}
+} else if (strcmp(machine->firmware, "none")) {
+firmware_filename = riscv_find_firmware(machine->firmware);
 }

-if (strcmp(firmware_filename, "none")) {
+if (firmware_filename) {
 /* If not "none" load the firmware */
 riscv_load_firmware(firmware_filename, firmware_load_addr);
 g_free(firmware_filename);
--
2.23.0




Re: [PATCH 05/11] qapi: add unplug primary event

2019-10-18 Thread Eric Blake

On 10/18/19 3:20 PM, Jens Freimann wrote:

This event is emitted when we sent a request to unplug a
failover primary device from the Guest OS and it includes the
device id of the primary device.

Signed-off-by: Jens Freimann 
---
  qapi/migration.json | 19 +++
  1 file changed, 19 insertions(+)

diff --git a/qapi/migration.json b/qapi/migration.json
index 82feb5bd39..52e69e2868 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1448,3 +1448,22 @@
  # Since: 3.0
  ##
  { 'command': 'migrate-pause', 'allow-oob': true }
+
+##
+# @UNPLUG_PRIMARY:
+#
+# Emitted from source side of a migration when migration state is
+# WAIT_UNPLUG. Device was unplugged by guest operating system.
+# Device resources in QEMU are kept on standby to be able to re-plug it in case
+# of migration failure.
+#
+# @device_id: QEMU device id of the unplugged device
+#
+# Since: 4.2
+#
+# Example:
+#   {"event": "UNPLUG_PRIMARY", "data": {"device_id": "hostdev0"} }


Unless there is a strong reason in favor of 'device_id' (such as 
consistency with a similar event), our naming convention prefers this to 
be 'device-id'.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org



[PATCH 07/11] migration: allow unplug during migration for failover devices

2019-10-18 Thread Jens Freimann
In "b06424de62 migration: Disable hotplug/unplug during migration" we
added a check to disable unplug for all devices until we have figured
out what works. For failover primary devices qdev_unplug() is called
from the migration handler, i.e. during migration.

This patch adds a flag to DeviceState which is set to false for all
devices and makes an exception for vfio-pci devices that are also
primary devices in a failover pair.

Signed-off-by: Jens Freimann 
---
 hw/core/qdev.c | 1 +
 include/hw/qdev-core.h | 1 +
 qdev-monitor.c | 2 +-
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 89c134ec53..b1be568af3 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -995,6 +995,7 @@ static void device_initfn(Object *obj)
 
 dev->instance_id_alias = -1;
 dev->realized = false;
+dev->allow_unplug_during_migration = false;
 
 object_property_add_bool(obj, "realized",
  device_get_realized, device_set_realized, NULL);
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 28f594a47d..6b690e85b1 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -143,6 +143,7 @@ struct DeviceState {
 bool pending_deleted_event;
 QemuOpts *opts;
 int hotplugged;
+bool allow_unplug_during_migration;
 BusState *parent_bus;
 QLIST_HEAD(, NamedGPIOList) gpios;
 QLIST_HEAD(, BusState) child_bus;
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 508d85df87..265ab4f0d5 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -848,7 +848,7 @@ void qdev_unplug(DeviceState *dev, Error **errp)
 return;
 }
 
-if (!migration_is_idle()) {
+if (!migration_is_idle() && !dev->allow_unplug_during_migration) {
 error_setg(errp, "device_del not allowed while migrating");
 return;
 }
-- 
2.21.0




[PATCH 10/11] net/virtio: add failover support

2019-10-18 Thread Jens Freimann
This patch adds support to handle failover device pairs of a virtio-net
device and a vfio-pci device, where the virtio-net acts as the standby
device and the vfio-pci device as the primary.

The general idea is that we have a pair of devices, a vfio-pci and a
emulated (virtio-net) device. Before migration the vfio device is
unplugged and data flows to the emulated device, on the target side
another vfio-pci device is plugged in to take over the data-path. In the
guest the net_failover module will pair net devices with the same MAC
address.

To achieve this we need:

1. Provide a callback function for the should_be_hidden DeviceListener.
   It is called when the primary device is plugged in. Evaluate the QOpt
   passed in to check if it is the matching primary device. It returns
   two values:
 - one to signal if the device to be added is the matching
   primary device
 - another one to signal to qdev if it should actually
   continue with adding the device or skip it.

   In the latter case it stores the device options in the VirtioNet
   struct and the device is added once the VIRTIO_NET_F_STANDBY feature is
   negotiated during virtio feature negotiation.

   If the virtio-net devices are not realized at the time the vfio-pci
   devices are realized, we need to connect the devices later. This way
   we make sure primary and standby devices can be specified in any
   order.

2. Register a callback for migration status notifier. When called it
   will unplug its primary device before the migration happens.

3. Register a callback for the migration code that checks if a device
   needs to be unplugged from the guest.

Signed-off-by: Jens Freimann 
---
 hw/net/virtio-net.c| 282 +
 include/hw/virtio/virtio-net.h |  12 ++
 include/hw/virtio/virtio.h |   1 +
 3 files changed, 295 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9f11422337..afe113f083 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/atomic.h"
 #include "qemu/iov.h"
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
@@ -21,6 +22,10 @@
 #include "net/tap.h"
 #include "qemu/error-report.h"
 #include "qemu/timer.h"
+#include "qemu/option.h"
+#include "qemu/option_int.h"
+#include "qemu/config-file.h"
+#include "qapi/qmp/qdict.h"
 #include "hw/virtio/virtio-net.h"
 #include "net/vhost_net.h"
 #include "net/announce.h"
@@ -28,11 +33,15 @@
 #include "qapi/error.h"
 #include "qapi/qapi-events-net.h"
 #include "hw/qdev-properties.h"
+#include "qapi/qapi-types-migration.h"
+#include "qapi/qapi-events-migration.h"
 #include "hw/virtio/virtio-access.h"
 #include "migration/misc.h"
 #include "standard-headers/linux/ethtool.h"
 #include "sysemu/sysemu.h"
 #include "trace.h"
+#include "monitor/qdev.h"
+#include "hw/pci/pci.h"
 
 #define VIRTIO_NET_VM_VERSION11
 
@@ -746,9 +755,85 @@ static inline uint64_t 
virtio_net_supported_guest_offloads(VirtIONet *n)
 return virtio_net_guest_offloads_by_features(vdev->guest_features);
 }
 
+static void failover_add_primary(VirtIONet *n)
+{
+Error *err = NULL;
+
+n->primary_device_opts = qemu_opts_find(qemu_find_opts("device"),
+n->primary_device_id);
+if (n->primary_device_opts) {
+n->primary_dev = qdev_device_add(n->primary_device_opts, &err);
+if (err) {
+qemu_opts_del(n->primary_device_opts);
+}
+if (n->primary_dev) {
+n->primary_bus = n->primary_dev->parent_bus;
+if (err) {
+qdev_unplug(n->primary_dev, &err);
+qdev_set_id(n->primary_dev, "");
+
+}
+}
+}
+if (err) {
+error_report_err(err);
+}
+}
+
+static int is_my_primary(void *opaque, QemuOpts *opts, Error **errp)
+{
+VirtIONet *n = opaque;
+int ret = 0;
+
+const char *standby_id = qemu_opt_get(opts, "net_failover_pair_id");
+
+if (standby_id != NULL && (g_strcmp0(standby_id, n->netclient_name) == 0)) 
{
+n->primary_device_id = g_strdup(opts->id);
+ret = 1;
+}
+
+return ret;
+}
+
+static DeviceState *virtio_net_find_primary(VirtIONet *n, Error *err)
+{
+DeviceState *dev = NULL;
+
+if (qemu_opts_foreach(qemu_find_opts("device"),
+ is_my_primary, n, &err)) {
+if (n->primary_device_id) {
+dev = qdev_find_recursive(sysbus_get_default(),
+n->primary_device_id);
+} else {
+return NULL;
+}
+}
+return dev;
+}
+
+
+
+static DeviceState *virtio_connect_failover_devices(VirtIONet *n,
+DeviceState *dev,
+Error **errp)
+{
+DeviceState *prim_dev = NULL;
+
+prim_dev = virtio_net_find_primary(n, *errp);
+if (prim_dev) {
+n->primary_device_id = g_strdup(prim_dev->id);
+n->

[PATCH 11/11] vfio: unplug failover primary device before migration

2019-10-18 Thread Jens Freimann
As usual block all vfio-pci devices from being migrated, but make an
exception for failover primary devices. This is achieved by setting
unmigratable to 0 but also add a migration blocker for all vfio-pci
devices except failover primary devices. These will be unplugged before
migration happens by the migration handler of the corresponding
virtio-net standby device.

Signed-off-by: Jens Freimann 
---
 hw/vfio/pci.c | 31 +--
 hw/vfio/pci.h |  1 +
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 12fac39804..a15b83c6b6 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -40,6 +40,9 @@
 #include "pci.h"
 #include "trace.h"
 #include "qapi/error.h"
+#include "migration/blocker.h"
+#include "qemu/option.h"
+#include "qemu/option_int.h"
 
 #define TYPE_VFIO_PCI "vfio-pci"
 #define PCI_VFIO(obj)OBJECT_CHECK(VFIOPCIDevice, obj, TYPE_VFIO_PCI)
@@ -2712,12 +2715,26 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 int i, ret;
 bool is_mdev;
 
+if (!pdev->net_failover_pair_id) {
+error_setg(&vdev->migration_blocker,
+"VFIO device doesn't support migration");
+ret = migrate_add_blocker(vdev->migration_blocker, &err);
+if (err) {
+error_propagate(errp, err);
+goto error;
+}
+} else {
+pdev->qdev.allow_unplug_during_migration = true;
+}
+
 if (!vdev->vbasedev.sysfsdev) {
 if (!(~vdev->host.domain || ~vdev->host.bus ||
   ~vdev->host.slot || ~vdev->host.function)) {
 error_setg(errp, "No provided host device");
 error_append_hint(errp, "Use -device vfio-pci,host=:BB:DD.F "
   "or -device vfio-pci,sysfsdev=PATH_TO_DEVICE\n");
+migrate_del_blocker(vdev->migration_blocker);
+error_free(vdev->migration_blocker);
 return;
 }
 vdev->vbasedev.sysfsdev =
@@ -2729,6 +2746,8 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 if (stat(vdev->vbasedev.sysfsdev, &st) < 0) {
 error_setg_errno(errp, errno, "no such host device");
 error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.sysfsdev);
+migrate_del_blocker(vdev->migration_blocker);
+error_free(vdev->migration_blocker);
 return;
 }
 
@@ -3008,6 +3027,8 @@ out_teardown:
 vfio_bars_exit(vdev);
 error:
 error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name);
+migrate_del_blocker(vdev->migration_blocker);
+error_free(vdev->migration_blocker);
 }
 
 static void vfio_instance_finalize(Object *obj)
@@ -3019,6 +3040,10 @@ static void vfio_instance_finalize(Object *obj)
 vfio_bars_finalize(vdev);
 g_free(vdev->emulated_config_bits);
 g_free(vdev->rom);
+if (vdev->migration_blocker) {
+migrate_del_blocker(vdev->migration_blocker);
+error_free(vdev->migration_blocker);
+}
 /*
  * XXX Leaking igd_opregion is not an oversight, we can't remove the
  * fw_cfg entry therefore leaking this allocation seems like the safest
@@ -3151,11 +3176,6 @@ static Property vfio_pci_dev_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
-static const VMStateDescription vfio_pci_vmstate = {
-.name = "vfio-pci",
-.unmigratable = 1,
-};
-
 static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -3163,7 +3183,6 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, 
void *data)
 
 dc->reset = vfio_pci_reset;
 dc->props = vfio_pci_dev_properties;
-dc->vmsd = &vfio_pci_vmstate;
 dc->desc = "VFIO-based PCI device assignment";
 set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 pdc->realize = vfio_realize;
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 834a90d646..b329d50338 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -168,6 +168,7 @@ typedef struct VFIOPCIDevice {
 bool no_vfio_ioeventfd;
 bool enable_ramfb;
 VFIODisplay *dpy;
+Error *migration_blocker;
 } VFIOPCIDevice;
 
 uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len);
-- 
2.21.0




[PATCH 04/11] pci: mark device having guest unplug request pending

2019-10-18 Thread Jens Freimann
Set pending_deleted_event in DeviceState for failover
primary devices that were successfully unplugged by the Guest OS.

Signed-off-by: Jens Freimann 
---
 hw/pci/pcie.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 19363ff8ce..08718188bb 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -457,6 +457,7 @@ static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, 
void *opaque)
 HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(dev));
 
 if (dev->partially_hotplugged) {
+dev->qdev.pending_deleted_event = false;
 return;
 }
 hotplug_handler_unplug(hotplug_ctrl, DEVICE(dev), &error_abort);
@@ -476,6 +477,8 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 return;
 }
 
+dev->pending_deleted_event = true;
+
 /* In case user cancel the operation of multi-function hot-add,
  * remove the function that is unexposed to guest individually,
  * without interaction with guest.
-- 
2.21.0




[PATCH 09/11] libqos: tolerate wait-unplug migration state

2019-10-18 Thread Jens Freimann
Signed-off-by: Jens Freimann 
---
 tests/libqos/libqos.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index d71557c5cb..f229eb2cb8 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -125,7 +125,8 @@ void migrate(QOSState *from, QOSState *to, const char *uri)
 break;
 }
 
-if ((strcmp(st, "setup") == 0) || (strcmp(st, "active") == 0)) {
+if ((strcmp(st, "setup") == 0) || (strcmp(st, "active") == 0)
+|| (strcmp(st, "wait-unplug") == 0)) {
 qobject_unref(rsp);
 g_usleep(5000);
 continue;
-- 
2.21.0




[PATCH 06/11] qapi: add failover negotiated event

2019-10-18 Thread Jens Freimann
This event is sent to let libvirt know that VIRTIO_NET_F_STANDBY
feature was not negotiated during virtio feature negotiation. If this
event is received it means any primary devices hotplugged before
this were were never really added to QEMU devices.

Signed-off-by: Jens Freimann 
---
 qapi/net.json | 16 
 1 file changed, 16 insertions(+)

diff --git a/qapi/net.json b/qapi/net.json
index 728990f4fb..8c5f3f1fb2 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -737,3 +737,19 @@
 ##
 { 'command': 'announce-self', 'boxed': true,
   'data' : 'AnnounceParameters'}
+
+##
+# @FAILOVER_NEGOTIATED:
+#
+# Emitted when VIRTIO_NET_F_STANDBY was negotiated during feature negotiation
+#
+# Since: 4.2
+#
+# Example:
+#
+# <- { "event": "FAILOVER_NEGOTIATED",
+#  "data": {} }
+#
+##
+{ 'event': 'FAILOVER_NEGOTIATED',
+  'data': {} }
-- 
2.21.0




[PATCH 08/11] migration: add new migration state wait-unplug

2019-10-18 Thread Jens Freimann
This patch adds a new migration state called wait-unplug.  It is entered
after the SETUP state if failover devices are present. It will transition
into ACTIVE once all devices were succesfully unplugged from the guest.

So if a guest doesn't respond or takes long to honor the unplug request
the user will see the migration state 'wait-unplug'.

In the migration thread we query failover devices if they're are still
pending the guest unplug. When all are unplugged the migration
continues. If one device won't unplug migration will stay in wait_unplug
state.

Signed-off-by: Jens Freimann 
---
 include/migration/vmstate.h |  2 ++
 migration/migration.c   | 21 +
 migration/migration.h   |  3 +++
 migration/savevm.c  | 36 
 migration/savevm.h  |  2 ++
 qapi/migration.json |  5 -
 6 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index b9ee563aa4..ac4f46a67d 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -186,6 +186,8 @@ struct VMStateDescription {
 int (*pre_save)(void *opaque);
 int (*post_save)(void *opaque);
 bool (*needed)(void *opaque);
+bool (*dev_unplug_pending)(void *opaque);
+
 const VMStateField *fields;
 const VMStateDescription **subsections;
 };
diff --git a/migration/migration.c b/migration/migration.c
index 3febd0f8f3..51764f2565 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -52,6 +52,7 @@
 #include "hw/qdev-properties.h"
 #include "monitor/monitor.h"
 #include "net/announce.h"
+#include "qemu/queue.h"
 
 #define MAX_THROTTLE  (32 << 20)  /* Migration transfer speed throttling */
 
@@ -819,6 +820,7 @@ bool migration_is_setup_or_active(int state)
 case MIGRATION_STATUS_SETUP:
 case MIGRATION_STATUS_PRE_SWITCHOVER:
 case MIGRATION_STATUS_DEVICE:
+case MIGRATION_STATUS_WAIT_UNPLUG:
 return true;
 
 default:
@@ -954,6 +956,9 @@ static void fill_source_migration_info(MigrationInfo *info)
 case MIGRATION_STATUS_CANCELLED:
 info->has_status = true;
 break;
+case MIGRATION_STATUS_WAIT_UNPLUG:
+info->has_status = true;
+break;
 }
 info->status = s->state;
 }
@@ -1694,6 +1699,7 @@ bool migration_is_idle(void)
 case MIGRATION_STATUS_COLO:
 case MIGRATION_STATUS_PRE_SWITCHOVER:
 case MIGRATION_STATUS_DEVICE:
+case MIGRATION_STATUS_WAIT_UNPLUG:
 return false;
 case MIGRATION_STATUS__MAX:
 g_assert_not_reached();
@@ -3264,6 +3270,19 @@ static void *migration_thread(void *opaque)
 
 qemu_savevm_state_setup(s->to_dst_file);
 
+if (qemu_savevm_nr_failover_devices()) {
+migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
+  MIGRATION_STATUS_WAIT_UNPLUG);
+
+while (s->state == MIGRATION_STATUS_WAIT_UNPLUG &&
+!qemu_savevm_state_guest_unplug_pending()) {
+qemu_sem_timedwait(&s->wait_unplug_sem, 250);
+}
+
+migrate_set_state(&s->state, MIGRATION_STATUS_WAIT_UNPLUG,
+MIGRATION_STATUS_ACTIVE);
+}
+
 s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
 migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
   MIGRATION_STATUS_ACTIVE);
@@ -3511,6 +3530,7 @@ static void migration_instance_finalize(Object *obj)
 qemu_mutex_destroy(&ms->qemu_file_lock);
 g_free(params->tls_hostname);
 g_free(params->tls_creds);
+qemu_sem_destroy(&ms->wait_unplug_sem);
 qemu_sem_destroy(&ms->rate_limit_sem);
 qemu_sem_destroy(&ms->pause_sem);
 qemu_sem_destroy(&ms->postcopy_pause_sem);
@@ -3556,6 +3576,7 @@ static void migration_instance_init(Object *obj)
 qemu_sem_init(&ms->postcopy_pause_rp_sem, 0);
 qemu_sem_init(&ms->rp_state.rp_sem, 0);
 qemu_sem_init(&ms->rate_limit_sem, 0);
+qemu_sem_init(&ms->wait_unplug_sem, 0);
 qemu_mutex_init(&ms->qemu_file_lock);
 }
 
diff --git a/migration/migration.h b/migration/migration.h
index 4f2fe193dc..79b3dda146 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -206,6 +206,9 @@ struct MigrationState
 /* Flag set once the migration thread called bdrv_inactivate_all */
 bool block_inactive;
 
+/* Migration is waiting for guest to unplug device */
+QemuSemaphore wait_unplug_sem;
+
 /* Migration is paused due to pause-before-switchover */
 QemuSemaphore pause_sem;
 
diff --git a/migration/savevm.c b/migration/savevm.c
index 8d95e261f6..0f18dea49e 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1113,6 +1113,42 @@ void qemu_savevm_state_header(QEMUFile *f)
 }
 }
 
+int qemu_savevm_nr_failover_devices(void)
+{
+SaveStateEntry *se;
+int n = 0;
+
+QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
+if (se->vmsd && se->vmsd->dev_unplug_pending) {
+n++;
+}
+}
+
+return

[PATCH 05/11] qapi: add unplug primary event

2019-10-18 Thread Jens Freimann
This event is emitted when we sent a request to unplug a
failover primary device from the Guest OS and it includes the
device id of the primary device.

Signed-off-by: Jens Freimann 
---
 qapi/migration.json | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/qapi/migration.json b/qapi/migration.json
index 82feb5bd39..52e69e2868 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1448,3 +1448,22 @@
 # Since: 3.0
 ##
 { 'command': 'migrate-pause', 'allow-oob': true }
+
+##
+# @UNPLUG_PRIMARY:
+#
+# Emitted from source side of a migration when migration state is
+# WAIT_UNPLUG. Device was unplugged by guest operating system.
+# Device resources in QEMU are kept on standby to be able to re-plug it in case
+# of migration failure.
+#
+# @device_id: QEMU device id of the unplugged device
+#
+# Since: 4.2
+#
+# Example:
+#   {"event": "UNPLUG_PRIMARY", "data": {"device_id": "hostdev0"} }
+#
+##
+{ 'event': 'UNPLUG_PRIMARY',
+  'data': { 'device_id': 'str' } }
-- 
2.21.0




[PATCH 03/11] pci: mark devices partially unplugged

2019-10-18 Thread Jens Freimann
Only the guest unplug request was triggered. This is needed for
the failover feature. In case of a failed migration we need to
plug the device back to the guest.

Signed-off-by: Jens Freimann 
---
 hw/pci/pcie.c| 3 +++
 include/hw/pci/pci.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index a6beb567bd..19363ff8ce 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -456,6 +456,9 @@ static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, 
void *opaque)
 {
 HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(dev));
 
+if (dev->partially_hotplugged) {
+return;
+}
 hotplug_handler_unplug(hotplug_ctrl, DEVICE(dev), &error_abort);
 object_unparent(OBJECT(dev));
 }
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index def5435685..7b7eac845c 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -265,6 +265,7 @@ typedef struct PCIReqIDCache PCIReqIDCache;
 
 struct PCIDevice {
 DeviceState qdev;
+bool partially_hotplugged;
 
 /* PCI config space */
 uint8_t *config;
-- 
2.21.0




[PATCH v4 0/11] add failover feature for assigned network devices

2019-10-18 Thread Jens Freimann
This is implementing the host side of the net_failover concept
(https://www.kernel.org/doc/html/latest/networking/net_failover.html)

Changes since v3:
* Patch 1,  make return values of qdev_should_hide_device() more clear
* Patch 1,  clarify comment about new should_be_hidden DeviceListener
* Patch 2   new patch, add net_failover_option_id to PCIDevice, only
allow PCIExpress devices for now 
* Patch 8,  only go into wait_unplug state when failover devices are present
* Patch 8,  add new state to migration_is_setup_or_active, tested cancelling
while migration is in this state
* Patch 8,  simplify handling of wait_unplug state, don't cancel migration after
timeout, let upper layer do this, get rid of retry counter 
(dgilbert)
* Patch 11, move net_failover_pair_id to PCIDev, move check for pci class
to PCI code, only allow PCIe devices for now as we only support
hotplugging these devices (aw)
* verified qemu make check tests ran, checked that docker-test-quick@centos7 
runs
  successful, tested migration with/without failover, without vfio-pci 
* this now allows only PCIe devices because that's the only hotplug
  controller that supports the partial unplug as of now. I'll work on 
  making it discoverable for libvirt or on support for the
  other hotplug controllers in a follow-on patch set
 
The general idea is that we have a pair of devices, a vfio-pci and a
virtio-net device. Before migration the vfio device is unplugged and data
flows to the virtio-net device, on the target side another vfio-pci device
is plugged in to take over the data-path. In the guest the net_failover
module will pair net devices with the same MAC address.

* Patch 1 adds the infrastructure to hide the device for the qbus and qdev APIs

* Patch 2 adds checks to PCIDevice for only allowing ethernet devices as
  failover primary and only PCIExpress capable devices

* Patch 3 sets a new flag for PCIDevice 'partially_hotplugged' which we
  use to skip the unrealize code path when doing a unplug of the primary
  device

* Patch 4 sets the pending_deleted_event before triggering the guest
  unplug request

* Patch 5 and 6 add new qmp events, one sends the device id of a device
  that was just requested to be unplugged from the guest and another one
  to let libvirt know if VIRTIO_NET_F_STANDBY was negotiated

* Patch 7 make sure that we can unplug the vfio-device before
  migration starts

* Patch 8 adds a new migration state that is entered while we wait for
  devices to be unplugged by guest OS

* Patch 9 just adds the new migration state to a check in libqos code

* Patch 10 In the second patch the virtio-net uses the API to defer adding the 
vfio
  device until the VIRTIO_NET_F_STANDBY feature is acked. It also
  implements the migration handler to unplug the device from the guest and
  re-plug in case of migration failure

* Patch 11 allows migration for failover vfio-pci devices

Previous discussion:
  RFC v1 https://patchwork.ozlabs.org/cover/989098/
  RFC v2 https://www.mail-archive.com/qemu-devel@nongnu.org/msg606906.html
  v1: https://lists.gnu.org/archive/html/qemu-devel/2019-05/msg03968.html
  v2: https://www.mail-archive.com/qemu-devel@nongnu.org/msg635214.html
  v3: https://patchew.org/QEMU/2019102015.11785-1-jfreim...@redhat.com/

To summarize concerns/feedback from previous discussion:
1.- guest OS can reject or worse _delay_ unplug by any amount of time.
  Migration might get stuck for unpredictable time with unclear reason.
  This approach combines two tricky things, hot/unplug and migration.
  -> We need to let libvirt know what's happening. Add new qmp events
 and a new migration state. When a primary device is (partially)
 unplugged (only from guest) we send a qmp event with the device id. When
 it is unplugged from the guest the DEVICE_DELETED event is sent.
 Migration will enter the wait-unplug state while waiting for the guest
 os to unplug all primary devices and then move on with migration.
2. PCI devices are a precious ressource. The primary device should never
  be added to QEMU if it won't be used by guest instead of hiding it in
  QEMU.
  -> We only hotplug the device when the standby feature bit was
 negotiated. We save the device cmdline options until we need it for
 qdev_device_add()
 Hiding a device can be a useful concept to model. For example a
 pci device in a powered-off slot could be marked as hidden until the slot 
is
 powered on (mst).
3. Management layer software should handle this. Open Stack already has
  components/code to handle unplug/replug VFIO devices and metadata to
  provide to the guest for detecting which devices should be paired.
  -> An approach that includes all software from firmware to
 higher-level management software wasn't tried in the last years. This is
 an attempt to keep it simple and contained in QEMU as much as possible.
 One of the problems that stopped man

[PATCH 01/11] qdev/qbus: add hidden device support

2019-10-18 Thread Jens Freimann
This adds support for hiding a device to the qbus and qdev APIs.  The
first user of this will be the virtio-net failover feature but the API
introduced with this patch could be used to implement other features as
well, for example hiding pci devices when a pci bus is powered off.

qdev_device_add() is modified to check for a net_failover_pair_id
argument in the option string. A DeviceListener callback
should_be_hidden() is added. It can be used by a standby device to
inform qdev that this device should not be added now. The standby device
handler can store the device options to plug the device in at a later
point in time.

One reason for hiding the device is that we don't want to expose both
devices to the guest kernel until the respective virtio feature bit
VIRTIO_NET_F_STANDBY was negotiated and we know that the devices will be
handled correctly by the guest.

More information on the kernel feature this is using:
 https://www.kernel.org/doc/html/latest/networking/net_failover.html

An example where the primary device is a vfio-pci device and the standby
device is a virtio-net device:

A device is hidden when it has an "net_failover_pair_id" option, e.g.

 -device virtio-net-pci,...,failover=on,...
 -device vfio-pci,...,net_failover_pair_id=net1,...

Signed-off-by: Jens Freimann 
---
 hw/core/qdev.c | 23 +++
 include/hw/qdev-core.h |  8 
 qdev-monitor.c | 36 +---
 vl.c   |  6 --
 4 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index cbad6c1d55..89c134ec53 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -212,6 +212,29 @@ void device_listener_unregister(DeviceListener *listener)
 QTAILQ_REMOVE(&device_listeners, listener, link);
 }
 
+bool qdev_should_hide_device(QemuOpts *opts)
+{
+int rc;
+DeviceListener *listener;
+
+QTAILQ_FOREACH(listener, &device_listeners, link) {
+   if (listener->should_be_hidden) {
+/* should_be_hidden_will return
+ *  1 if device matches opts and it should be hidden
+ *  0 if device matches opts and should not be hidden
+ *  -1 if device doesn't match ops
+ */
+rc = listener->should_be_hidden(listener, opts);
+}
+
+if (rc > 0) {
+break;
+}
+}
+
+return rc > 0;
+}
+
 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
  int required_for_version)
 {
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index aa123f88cb..28f594a47d 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -154,6 +154,12 @@ struct DeviceState {
 struct DeviceListener {
 void (*realize)(DeviceListener *listener, DeviceState *dev);
 void (*unrealize)(DeviceListener *listener, DeviceState *dev);
+/*
+ * This callback is called upon init of the DeviceState and allows to
+ * inform qdev that a device should be hidden, depending on the device
+ * opts, for example, to hide a standby device.
+ */
+int (*should_be_hidden)(DeviceListener *listener, QemuOpts *device_opts);
 QTAILQ_ENTRY(DeviceListener) link;
 };
 
@@ -451,4 +457,6 @@ static inline bool qbus_is_hotpluggable(BusState *bus)
 void device_listener_register(DeviceListener *listener);
 void device_listener_unregister(DeviceListener *listener);
 
+bool qdev_should_hide_device(QemuOpts *opts);
+
 #endif
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 148df9cacf..508d85df87 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -32,9 +32,11 @@
 #include "qemu/help_option.h"
 #include "qemu/option.h"
 #include "qemu/qemu-print.h"
+#include "qemu/option_int.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
 #include "migration/misc.h"
+#include "migration/migration.h"
 
 /*
  * Aliases were a bad idea from the start.  Let's keep them
@@ -562,14 +564,40 @@ void qdev_set_id(DeviceState *dev, const char *id)
 }
 }
 
+static int is_failover_device(void *opaque, const char *name, const char 
*value,
+Error **errp)
+{
+if (strcmp(name, "net_failover_pair_id") == 0) {
+QemuOpts *opts = (QemuOpts *)opaque;
+
+if (qdev_should_hide_device(opts)) {
+return 1;
+}
+}
+
+return 0;
+}
+
+static bool should_hide_device(QemuOpts *opts)
+{
+if (qemu_opt_foreach(opts, is_failover_device, opts, NULL) == 0) {
+return false;
+}
+return true;
+}
+
 DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
 {
 DeviceClass *dc;
 const char *driver, *path;
-DeviceState *dev;
+DeviceState *dev = NULL;
 BusState *bus = NULL;
 Error *err = NULL;
 
+if (opts && should_hide_device(opts)) {
+return NULL;
+}
+
 driver = qemu_opt_get(opts, "driver");
 if (!driver) {
 error_setg(errp, QERR_MISSING_PARAMETER, "driver");
@@ -648,8 +676,10 @@ DeviceSta

[PATCH 02/11] pci: add option for net failover

2019-10-18 Thread Jens Freimann
This patch adds a net_failover_pair_id property to PCIDev which is
used to link the primary device in a failover pair (the PCI dev) to
a standby (a virtio-net-pci) device.

It only supports ethernet devices. Also currently it only supports
PCIe devices. QEMU will exit with an error message otherwise.

Signed-off-by: Jens Freimann 
---
 hw/pci/pci.c | 17 +
 include/hw/pci/pci.h |  3 +++
 2 files changed, 20 insertions(+)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index aa05c2b9b2..fa9b5219f8 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -75,6 +75,8 @@ static Property pci_props[] = {
 QEMU_PCIE_LNKSTA_DLLLA_BITNR, true),
 DEFINE_PROP_BIT("x-pcie-extcap-init", PCIDevice, cap_present,
 QEMU_PCIE_EXTCAP_INIT_BITNR, true),
+DEFINE_PROP_STRING("net_failover_pair_id", PCIDevice,
+net_failover_pair_id),
 DEFINE_PROP_END_OF_LIST()
 };
 
@@ -2077,6 +2079,7 @@ static void pci_qdev_realize(DeviceState *qdev, Error 
**errp)
 ObjectClass *klass = OBJECT_CLASS(pc);
 Error *local_err = NULL;
 bool is_default_rom;
+uint16_t class_id;
 
 /* initialize cap_present for pci_is_express() and pci_config_size(),
  * Note that hybrid PCIs are not set automatically and need to manage
@@ -2101,6 +2104,20 @@ static void pci_qdev_realize(DeviceState *qdev, Error 
**errp)
 }
 }
 
+if (pci_dev->net_failover_pair_id) {
+if (!pci_is_express(pci_dev)) {
+error_setg(errp, "failover device is not a PCIExpress device");
+error_propagate(errp, local_err);
+return;
+}
+class_id = pci_get_word(pci_dev->config + PCI_CLASS_DEVICE);
+if (class_id != PCI_CLASS_NETWORK_ETHERNET) {
+error_setg(errp, "failover device is not an Ethernet device");
+error_propagate(errp, local_err);
+return;
+}
+}
+
 /* rom loading */
 is_default_rom = false;
 if (pci_dev->romfile == NULL && pc->romfile != NULL) {
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index f3f0ffd5fb..def5435685 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -352,6 +352,9 @@ struct PCIDevice {
 MSIVectorUseNotifier msix_vector_use_notifier;
 MSIVectorReleaseNotifier msix_vector_release_notifier;
 MSIVectorPollNotifier msix_vector_poll_notifier;
+
+/* ID of standby device in net_failover pair */
+char *net_failover_pair_id;
 };
 
 void pci_register_bar(PCIDevice *pci_dev, int region_num,
-- 
2.21.0




Re: [PATCH] target/riscv: PMP violation due to wrong size parameter

2019-10-18 Thread Dayeol Lee
I'll move the entire check into pmp_hart_has_privs as it makes more sense.

Thanks!

On Fri, Oct 18, 2019, 3:01 PM Palmer Dabbelt  wrote:

> On Tue, 15 Oct 2019 10:04:32 PDT (-0700), day...@berkeley.edu wrote:
> > Hi,
> >
> > Could this patch go through?
> > If not please let me know so that I can fix.
> > Thank you!
>
> Sorry, I dropped this one.  It's in the patch queue now.  We should also
> check
> for size==0 in pmp_hart_has_privs(), as that won't work.  LMK if you want
> to
> send a patch for that.
>
> >
> > Dayeol
> >
> >
> > On Sat, Oct 12, 2019, 11:30 AM Dayeol Lee  wrote:
> >
> >> No it doesn't mean that.
> >> But the following code will make the size TARGET_PAGE_SIZE - (page
> offset)
> >> if the address is not aligned.
> >>
> >> pmp_size = -(address | TARGET_PAGE_MASK)
> >>
> >>
> >> On Fri, Oct 11, 2019, 7:37 PM Jonathan Behrens 
> wrote:
> >>
> >>> How do you know that the access won't straddle a page boundary? Is
> there
> >>> a guarantee somewhere that size=0 means that the access is naturally
> >>> aligned?
> >>>
> >>> Jonathan
> >>>
> >>>
> >>> On Fri, Oct 11, 2019 at 7:14 PM Dayeol Lee 
> wrote:
> >>>
>  riscv_cpu_tlb_fill() uses the `size` parameter to check PMP violation
>  using pmp_hart_has_privs().
>  However, if the size is unknown (=0), the ending address will be
>  `addr - 1` as it is `addr + size - 1` in `pmp_hart_has_privs()`.
>  This always causes a false PMP violation on the starting address of
> the
>  range, as `addr - 1` is not in the range.
> 
>  In order to fix, we just assume that all bytes from addr to the end of
>  the page will be accessed if the size is unknown.
> 
>  Signed-off-by: Dayeol Lee 
>  Reviewed-by: Richard Henderson 
>  ---
>   target/riscv/cpu_helper.c | 13 -
>   1 file changed, 12 insertions(+), 1 deletion(-)
> 
>  diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
>  index e32b6126af..7d9a22b601 100644
>  --- a/target/riscv/cpu_helper.c
>  +++ b/target/riscv/cpu_helper.c
>  @@ -441,6 +441,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
> address,
>  int size,
>   CPURISCVState *env = &cpu->env;
>   hwaddr pa = 0;
>   int prot;
>  +int pmp_size = 0;
>   bool pmp_violation = false;
>   int ret = TRANSLATE_FAIL;
>   int mode = mmu_idx;
>  @@ -460,9 +461,19 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
>  address, int size,
> "%s address=%" VADDR_PRIx " ret %d physical "
>  TARGET_FMT_plx
> " prot %d\n", __func__, address, ret, pa, prot);
> 
>  +/*
>  + * if size is unknown (0), assume that all bytes
>  + * from addr to the end of the page will be accessed.
>  + */
>  +if (size == 0) {
>  +pmp_size = -(address | TARGET_PAGE_MASK);
>  +} else {
>  +pmp_size = size;
>  +}
>  +
>   if (riscv_feature(env, RISCV_FEATURE_PMP) &&
>   (ret == TRANSLATE_SUCCESS) &&
>  -!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
>  +!pmp_hart_has_privs(env, pa, pmp_size, 1 << access_type,
> mode))
>  {
>   ret = TRANSLATE_PMP_FAIL;
>   }
>   if (ret == TRANSLATE_PMP_FAIL) {
>  --
>  2.20.1
> 
> 
> 
>


Re: [PATCH v1 5/6] s390x/tcg: Fix VECTOR SUBTRACT WITH BORROW INDICATION

2019-10-18 Thread Richard Henderson
On 10/18/19 9:10 AM, David Hildenbrand wrote:
> Testing this, there seems to be something messed up. We are dealing with
> unsigned numbers. "Each operand is treated as an unsigned binary integer."
> Let's just implement as written in the PoP:
> 
> "A subtraction is performed by adding the contents of
>  the second operand with the bitwise complement of
>  the third operand along with a borrow indication from
>  the rightmost bit position of the fourth operand and
>  the result is placed in the first operand."
> 
> Fixes: 48390a7c2716 ("s390x/tcg: Implement VECTOR SUBTRACT WITH BORROW 
> INDICATION")
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/translate_vx.inc.c | 12 +---
>  1 file changed, 9 insertions(+), 3 deletions(-)

Reviewed-by: Richard Henderson 


r~




Re: [PATCH v5 2/3] tests/vm: Let subclasses disable IPv6

2019-10-18 Thread Philippe Mathieu-Daudé

On 10/18/19 8:17 PM, Eduardo Habkost wrote:

The mechanism will be used to work around issues related to IPv6
on the netbsd image builder.

Signed-off-by: Eduardo Habkost 
---
  tests/vm/basevm.py | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index b5d1479bee..2929de23aa 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -57,6 +57,8 @@ class BaseVM(object):
  arch = "#arch"
  # command to halt the guest, can be overridden by subclasses
  poweroff = "poweroff"
+# enable IPv6 networking
+ipv6 = True
  def __init__(self, debug=False, vcpus=None):
  self._guest = None
  self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-",
@@ -81,7 +83,8 @@ class BaseVM(object):
  self._args = [ \
  "-nodefaults", "-m", "4G",
  "-cpu", "max",
-"-netdev", "user,id=vnet,hostfwd=:127.0.0.1:0-:22",
+"-netdev", "user,id=vnet,hostfwd=:127.0.0.1:0-:22" +
+   (",ipv6=no" if not self.ipv6 else ""),
  "-device", "virtio-net-pci,netdev=vnet",
  "-vnc", "127.0.0.1:0,to=20"]
  if vcpus and vcpus > 1:



Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v1 3/6] s390x/tcg: Fix VECTOR SHIFT RIGHT ARITHMETIC BY BYTE

2019-10-18 Thread Richard Henderson
On 10/18/19 9:10 AM, David Hildenbrand wrote:
> We forgot to propagate the highest bit accross the high doubleword in
> two cases (shift >=64).
> 
> Fixes: 5f724887e3dd ("s390x/tcg: Implement VECTOR SHIFT RIGHT ARITHMETIC")
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/vec_int_helper.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)

Reviewed-by: Richard Henderson 


r~




Re: [PATCH v1 2/6] s390x/tcg: Fix VECTOR MULTIPLY AND ADD *

2019-10-18 Thread Richard Henderson
On 10/18/19 9:10 AM, David Hildenbrand wrote:
> We missed that we always read a "double-wide even-odd element
> pair of the fourth operand". Fix it in all four variants.
> 
> Fixes: 1b430aec4157 ("s390x/tcg: Implement VECTOR MULTIPLY AND ADD *")
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/vec_int_helper.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson 


r~




Re: [PATCH v1 1/6] s390x/tcg: Fix VECTOR MULTIPLY LOGICAL ODD

2019-10-18 Thread Richard Henderson
On 10/18/19 9:10 AM, David Hildenbrand wrote:
> We have to read from odd offsets.
> 
> Fixes: 2bf3ee38f1f8 ("s390x/tcg: Implement VECTOR MULTIPLY *")
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/vec_int_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Richard Henderson 


r~



Re: [PATCH] target/riscv: PMP violation due to wrong size parameter

2019-10-18 Thread Palmer Dabbelt

On Tue, 15 Oct 2019 10:04:32 PDT (-0700), day...@berkeley.edu wrote:

Hi,

Could this patch go through?
If not please let me know so that I can fix.
Thank you!


Sorry, I dropped this one.  It's in the patch queue now.  We should also check 
for size==0 in pmp_hart_has_privs(), as that won't work.  LMK if you want to 
send a patch for that.




Dayeol


On Sat, Oct 12, 2019, 11:30 AM Dayeol Lee  wrote:


No it doesn't mean that.
But the following code will make the size TARGET_PAGE_SIZE - (page offset)
if the address is not aligned.

pmp_size = -(address | TARGET_PAGE_MASK)


On Fri, Oct 11, 2019, 7:37 PM Jonathan Behrens  wrote:


How do you know that the access won't straddle a page boundary? Is there
a guarantee somewhere that size=0 means that the access is naturally
aligned?

Jonathan


On Fri, Oct 11, 2019 at 7:14 PM Dayeol Lee  wrote:


riscv_cpu_tlb_fill() uses the `size` parameter to check PMP violation
using pmp_hart_has_privs().
However, if the size is unknown (=0), the ending address will be
`addr - 1` as it is `addr + size - 1` in `pmp_hart_has_privs()`.
This always causes a false PMP violation on the starting address of the
range, as `addr - 1` is not in the range.

In order to fix, we just assume that all bytes from addr to the end of
the page will be accessed if the size is unknown.

Signed-off-by: Dayeol Lee 
Reviewed-by: Richard Henderson 
---
 target/riscv/cpu_helper.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e32b6126af..7d9a22b601 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -441,6 +441,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address,
int size,
 CPURISCVState *env = &cpu->env;
 hwaddr pa = 0;
 int prot;
+int pmp_size = 0;
 bool pmp_violation = false;
 int ret = TRANSLATE_FAIL;
 int mode = mmu_idx;
@@ -460,9 +461,19 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
address, int size,
   "%s address=%" VADDR_PRIx " ret %d physical "
TARGET_FMT_plx
   " prot %d\n", __func__, address, ret, pa, prot);

+/*
+ * if size is unknown (0), assume that all bytes
+ * from addr to the end of the page will be accessed.
+ */
+if (size == 0) {
+pmp_size = -(address | TARGET_PAGE_MASK);
+} else {
+pmp_size = size;
+}
+
 if (riscv_feature(env, RISCV_FEATURE_PMP) &&
 (ret == TRANSLATE_SUCCESS) &&
-!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
+!pmp_hart_has_privs(env, pa, pmp_size, 1 << access_type, mode))
{
 ret = TRANSLATE_PMP_FAIL;
 }
 if (ret == TRANSLATE_PMP_FAIL) {
--
2.20.1







Re: [PATCH v1 6/6] s390x/tcg: Fix VECTOR SUBTRACT WITH BORROW COMPUTE BORROW INDICATION

2019-10-18 Thread Richard Henderson
On 10/18/19 9:10 AM, David Hildenbrand wrote:
> +/* Isolate the carry to the next doubleword */
>  tcg_gen_andi_i64(dl, th, 1);

You can remove this now, since the only possible results are 0/1; it was only
our subtract implementation that produced -1/0.


r~



Re: [PATCH v1 4/6] s390x/tcg: Fix VECTOR SUBTRACT COMPUTE BORROW INDICATION

2019-10-18 Thread Richard Henderson
On 10/18/19 11:18 AM, David Hildenbrand wrote:
> On 18.10.19 19:41, David Hildenbrand wrote:
>> On 18.10.19 18:10, David Hildenbrand wrote:
>>> Looks like my idea of what a "borrow" is was wrong. We are dealing with
>>> unsigned numbers. A subtraction is simply an addition with the bitwise
>>> complement. If we get a carry during the addition, that's the borrow.
>>> "The operands are treated as unsigned binary integers."
>>>
>>> This is nice, as we can reuse the VECTOR ADD COMPUTE CARRY functions
>>> and avoid helpers, all we have to do is compute the bitwise complement.
>>>
>>> Fixes: 1ee2d7ba72f6 ("s390x/tcg: Implement VECTOR SUBTRACT COMPUTE BORROW
>>> INDICATION")
>>> Signed-off-by: David Hildenbrand 
>>> ---
>>>    target/s390x/helper.h   |  2 --
>>>    target/s390x/translate_vx.inc.c | 45 -
>>>    target/s390x/vec_int_helper.c   | 16 
>>>    3 files changed, 33 insertions(+), 30 deletions(-)
>>>
>>> diff --git a/target/s390x/helper.h b/target/s390x/helper.h
>>> index 56e8149866..ca1e08100a 100644
>>> --- a/target/s390x/helper.h
>>> +++ b/target/s390x/helper.h
>>> @@ -207,8 +207,6 @@ DEF_HELPER_FLAGS_4(gvec_verim16, TCG_CALL_NO_RWG, void,
>>> ptr, cptr, cptr, i32)
>>>    DEF_HELPER_FLAGS_4(gvec_vsl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
>>>    DEF_HELPER_FLAGS_4(gvec_vsra, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
>>>    DEF_HELPER_FLAGS_4(gvec_vsrl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
>>> -DEF_HELPER_FLAGS_4(gvec_vscbi8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, 
>>> i32)
>>> -DEF_HELPER_FLAGS_4(gvec_vscbi16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, 
>>> i32)
>>>    DEF_HELPER_4(gvec_vtm, void, ptr, cptr, env, i32)
>>>       /* === Vector String Instructions === */
>>> diff --git a/target/s390x/translate_vx.inc.c 
>>> b/target/s390x/translate_vx.inc.c
>>> index 5ce7bfb0af..40bcc1604e 100644
>>> --- a/target/s390x/translate_vx.inc.c
>>> +++ b/target/s390x/translate_vx.inc.c
>>> @@ -2130,14 +2130,40 @@ static DisasJumpType op_vs(DisasContext *s, DisasOps
>>> *o)
>>>    return DISAS_NEXT;
>>>    }
>>>    +static void gen_scbi8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
>>> +{
>>> +    TCGv_i64 t = tcg_temp_new_i64();
>>> +
>>> +    tcg_gen_not_i64(t, b);
>>> +    gen_acc(d, a, t, ES_8);
>>> +    tcg_temp_free_i64(t);
>>> +}
>>
>> BTW, I would have thought that we need the 2nd complement in all these
>> cases. However, the description of the other functions confused me
>> (VECTOR SUBTRACT WITH BORROW INDICATION) - add bitwise complement and
>> add the borrow.
>>
>> This passes my test cases (that are verified against real HW), but I am
>> not sure if I check all the corner cases.
>>
>> @Richard, do you have any idea how to do it the right way for this
>> instruction?
>>
> 
> My impression was right. A simple "0-0" test makes this visible. The other two
> fixes seem to be correct, though.

Your description seems to indicate that you want carry output, which is
!borrow.  ARM represents things this way, but I didn't recall it for S390.

If you want to implement sub r,x,y with add r,x,~y, you also have to add one --
often times with the carry-in.  But since we don't have a carry-in here, I
wonder if it isn't easier to invert your result:

 tcg_gen_sub2_i64(tl, th, al, zero, bl, zero);
 tcg_gen_andi_i64(th, th, 1);
 tcg_gen_sub2_i64(tl, th, ah, zero, th, zero);
 tcg_gen_sub2_i64(tl, th, tl, th, bh, zero);
-tcg_gen_andi_i64(dl, th, 1);
+/* "invert" the result: -1 -> 0; 0 -> 1 */
+tcg_gen_addi_i64(dl, th, 1);


r~



Re: [PATCH] Fix unsigned integer underflow in fd-trans.c

2019-10-18 Thread Laurent Vivier
Le 18/10/2019 à 20:27, Shu-Chun Weng a écrit :
> (Re-sending to the list because I forgot to turn off HTML before and
> it was bounced.)
> 
> That does prevent the integer underflow, but it also changes the
> behavior and I don't think the new behavior is desirable.
> 
> If the extra payload has a smaller alignment than the header, it makes
> sense for the user program to generate a nlmsg_len that is not a
> multiple of the alignment. When it's the last entry, the new condition
> will it because NLMSG_ALIGN pushes the aligned length over `len`, yet
> the single entry processing function won't actually read beyond the
> buffer as long as it's bounded by nlmsg_len.

Yes, you're right.

So I think your patch is correct.

Reviewed-by: Laurent Vivier 

Thanks,
Laurent




Re: [PATCH v3 2/2] riscv: virt: Use Goldfish RTC device

2019-10-18 Thread Palmer Dabbelt

On Tue, 15 Oct 2019 01:35:42 PDT (-0700), Anup Patel wrote:

We extend QEMU RISC-V virt machine by adding Goldfish RTC device
to it. This will allow Guest Linux to sync it's local date/time
with Host date/time via RTC device.

Signed-off-by: Anup Patel 
---
 hw/riscv/Kconfig|  1 +
 hw/riscv/virt.c | 15 +++
 include/hw/riscv/virt.h |  2 ++
 3 files changed, 18 insertions(+)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index fb19b2df3a..b33753c780 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -34,6 +34,7 @@ config RISCV_VIRT
 select PCI
 select HART
 select SERIAL
+select GOLDFISH_RTC
 select VIRTIO_MMIO
 select PCI_EXPRESS_GENERIC_BRIDGE
 select SIFIVE
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index d36f5625ec..95c42ab993 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -57,6 +57,7 @@ static const struct MemmapEntry {
 [VIRT_DEBUG] =   {0x0, 0x100 },
 [VIRT_MROM] ={ 0x1000,   0x11000 },
 [VIRT_TEST] ={   0x10,0x1000 },
+[VIRT_RTC] = {   0x101000,0x1000 },
 [VIRT_CLINT] =   {  0x200,   0x1 },
 [VIRT_PLIC] ={  0xc00, 0x400 },
 [VIRT_UART0] =   { 0x1000, 0x100 },
@@ -310,6 +311,17 @@ static void create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", UART0_IRQ);
 
+nodename = g_strdup_printf("/rtc@%lx",

+(long)memmap[VIRT_RTC].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_string(fdt, nodename, "compatible",
+"google,goldfish-rtc");
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+0x0, memmap[VIRT_RTC].base,
+0x0, memmap[VIRT_RTC].size);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupts", RTC_IRQ);
+
 qemu_fdt_add_subnode(fdt, "/chosen");
 qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
 if (cmdline) {
@@ -496,6 +508,9 @@ static void riscv_virt_board_init(MachineState *machine)
 0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
 serial_hd(0), DEVICE_LITTLE_ENDIAN);
 
+sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base,

+qdev_get_gpio_in(DEVICE(s->plic), RTC_IRQ));
+
 g_free(plic_hart_config);
 }
 
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h

index 6e5fbe5d3b..e6423258d3 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -37,6 +37,7 @@ enum {
 VIRT_DEBUG,
 VIRT_MROM,
 VIRT_TEST,
+VIRT_RTC,
 VIRT_CLINT,
 VIRT_PLIC,
 VIRT_UART0,
@@ -49,6 +50,7 @@ enum {
 
 enum {

 UART0_IRQ = 10,
+RTC_IRQ = 11,
 VIRTIO_IRQ = 1, /* 1 to 8 */
 VIRTIO_COUNT = 8,
 PCIE_IRQ = 0x20, /* 32 to 35 */


This is a wacky enum, but it's already there.  I'm going to assume this patch 
will get merged and then fix it later.



--
2.17.1


Reviewed-by: Palmer Dabbelt 
Acked-by: Palmer Dabbelt 

I think it's easier to just keep this with the goldfish implementation.  I'm 
assuming that will go in through a different tree, as per my comments on that 
patch.




Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Palmer Dabbelt

On Tue, 15 Oct 2019 01:35:31 PDT (-0700), Anup Patel wrote:

This patch adds model for Google Goldfish virtual platform RTC device.

We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
for providing real date-time to Guest Linux. The corresponding Linux
driver for Goldfish RTC device is already available in upstream Linux.

For now, VM migration support is available but untested for Goldfish RTC
device. It will be hardened in-future when we implement VM migration for
KVM RISC-V.

Signed-off-by: Anup Patel 
---
 hw/rtc/Kconfig  |   3 +
 hw/rtc/Makefile.objs|   1 +
 hw/rtc/goldfish_rtc.c   | 278 
 include/hw/timer/goldfish_rtc.h |  46 ++
 4 files changed, 328 insertions(+)
 create mode 100644 hw/rtc/goldfish_rtc.c
 create mode 100644 include/hw/timer/goldfish_rtc.h


I'd be happy to take a look at this, but I don't have a hw/rtc directory in my 
QEMU.  IIRC there was a refactoring going on here, is there a tree this is 
based on?



diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
index 45daa8d655..bafe6ac2c9 100644
--- a/hw/rtc/Kconfig
+++ b/hw/rtc/Kconfig
@@ -21,3 +21,6 @@ config MC146818RTC
 
 config SUN4V_RTC

 bool
+
+config GOLDFISH_RTC
+bool
diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs
index 8dc9fcd3a9..aa208d0d10 100644
--- a/hw/rtc/Makefile.objs
+++ b/hw/rtc/Makefile.objs
@@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
 obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
+common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
new file mode 100644
index 00..223616ed75
--- /dev/null
+++ b/hw/rtc/goldfish_rtc.c
@@ -0,0 +1,278 @@
+/*
+ * Goldfish virtual platform RTC
+ *
+ * Copyright (C) 2019 Western Digital Corporation or its affiliates.
+ *
+ * For more details on Google Goldfish virtual platform refer:
+ * 
https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
+ *
+ * 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 .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/timer/goldfish_rtc.h"
+#include "migration/vmstate.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+
+#define RTC_TIME_LOW0x00
+#define RTC_TIME_HIGH   0x04
+#define RTC_ALARM_LOW   0x08
+#define RTC_ALARM_HIGH  0x0c
+#define RTC_IRQ_ENABLED 0x10
+#define RTC_CLEAR_ALARM 0x14
+#define RTC_ALARM_STATUS0x18
+#define RTC_CLEAR_INTERRUPT 0x1c
+
+static void goldfish_rtc_update(GoldfishRTCState *s)
+{
+qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
+}
+
+static void goldfish_rtc_interrupt(void *opaque)
+{
+GoldfishRTCState *s = (GoldfishRTCState *)opaque;
+
+s->alarm_running = 0;
+s->irq_pending = 1;
+goldfish_rtc_update(s);
+}
+
+static uint64_t goldfish_rtc_get_count(GoldfishRTCState *s)
+{
+return s->tick_offset + (uint64_t)qemu_clock_get_ns(rtc_clock);
+}
+
+static void goldfish_rtc_clear_alarm(GoldfishRTCState *s)
+{
+timer_del(s->timer);
+s->alarm_running = 0;
+}
+
+static void goldfish_rtc_set_alarm(GoldfishRTCState *s)
+{
+uint64_t ticks = goldfish_rtc_get_count(s);
+uint64_t event = s->alarm_next;
+
+if (event <= ticks) {
+goldfish_rtc_clear_alarm(s);
+goldfish_rtc_interrupt(s);
+} else {
+int64_t now = qemu_clock_get_ns(rtc_clock);
+timer_mod(s->timer, now + (event - ticks));
+s->alarm_running = 1;
+}
+}
+
+static uint64_t goldfish_rtc_read(void *opaque, hwaddr offset,
+  unsigned size)
+{
+GoldfishRTCState *s = (GoldfishRTCState *)opaque;
+uint64_t r;
+
+switch (offset) {
+case RTC_TIME_LOW:
+r = goldfish_rtc_get_count(s) & 0x;
+break;
+case RTC_TIME_HIGH:
+r = goldfish_rtc_get_count(s) >> 32;
+break;
+case RTC_ALARM_LOW:
+r = s->alarm_next & 0x;
+break;
+case RTC_ALARM_HIGH:
+r = s->alarm_next >> 32;
+break;
+case RTC_IRQ_ENABLED:
+r = s->irq_enabled;
+break;
+case RTC_ALARM_STATU

Re: [PATCH v6 1/4] block/replication.c: Ignore requests after failover

2019-10-18 Thread Lukas Straub
On Sat, 5 Oct 2019 15:05:23 +0200
Lukas Straub  wrote:

> After failover the Secondary side of replication shouldn't change state, 
> because
> it now functions as our primary disk.
>
> In replication_start, replication_do_checkpoint, replication_stop, ignore
> the request if current state is BLOCK_REPLICATION_DONE (sucessful failover) or
> BLOCK_REPLICATION_FAILOVER (failover in progres i.e. currently merging active
> and hidden images into the base image).
>
> Signed-off-by: Lukas Straub 
> Reviewed-by: Zhang Chen 
> ---
>  block/replication.c | 38 +++---
>  1 file changed, 35 insertions(+), 3 deletions(-)
>
> diff --git a/block/replication.c b/block/replication.c
> index 3d4dedddfc..97cc65c0cf 100644
> --- a/block/replication.c
> +++ b/block/replication.c
> @@ -454,6 +454,17 @@ static void replication_start(ReplicationState *rs, 
> ReplicationMode mode,
>  aio_context_acquire(aio_context);
>  s = bs->opaque;
>
> +if (s->stage == BLOCK_REPLICATION_DONE ||
> +s->stage == BLOCK_REPLICATION_FAILOVER) {
> +/*
> + * This case happens when a secondary is promoted to primary.
> + * Ignore the request because the secondary side of replication
> + * doesn't have to do anything anymore.
> + */
> +aio_context_release(aio_context);
> +return;
> +}
> +
>  if (s->stage != BLOCK_REPLICATION_NONE) {
>  error_setg(errp, "Block replication is running or done");
>  aio_context_release(aio_context);
> @@ -529,8 +540,7 @@ static void replication_start(ReplicationState *rs, 
> ReplicationMode mode,
> "Block device is in use by internal backup job");
>
>  top_bs = bdrv_lookup_bs(s->top_id, s->top_id, NULL);
> -if (!top_bs || !bdrv_is_root_node(top_bs) ||
> -!check_top_bs(top_bs, bs)) {
> +if (!top_bs || !check_top_bs(top_bs, bs)) {
>  error_setg(errp, "No top_bs or it is invalid");
>  reopen_backing_file(bs, false, NULL);
>  aio_context_release(aio_context);
> @@ -577,6 +587,17 @@ static void replication_do_checkpoint(ReplicationState 
> *rs, Error **errp)
>  aio_context_acquire(aio_context);
>  s = bs->opaque;
>
> +if (s->stage == BLOCK_REPLICATION_DONE ||
> +s->stage == BLOCK_REPLICATION_FAILOVER) {
> +/*
> + * This case happens when a secondary was promoted to primary.
> + * Ignore the request because the secondary side of replication
> + * doesn't have to do anything anymore.
> + */
> +aio_context_release(aio_context);
> +return;
> +}
> +
>  if (s->mode == REPLICATION_MODE_SECONDARY) {
>  secondary_do_checkpoint(s, errp);
>  }
> @@ -593,7 +614,7 @@ static void replication_get_error(ReplicationState *rs, 
> Error **errp)
>  aio_context_acquire(aio_context);
>  s = bs->opaque;
>
> -if (s->stage != BLOCK_REPLICATION_RUNNING) {
> +if (s->stage == BLOCK_REPLICATION_NONE) {
>  error_setg(errp, "Block replication is not running");
>  aio_context_release(aio_context);
>  return;
> @@ -635,6 +656,17 @@ static void replication_stop(ReplicationState *rs, bool 
> failover, Error **errp)
>  aio_context_acquire(aio_context);
>  s = bs->opaque;
>
> +if (s->stage == BLOCK_REPLICATION_DONE ||
> +s->stage == BLOCK_REPLICATION_FAILOVER) {
> +/*
> + * This case happens when a secondary was promoted to primary.
> + * Ignore the request because the secondary side of replication
> + * doesn't have to do anything anymore.
> + */
> +aio_context_release(aio_context);
> +return;
> +}
> +
>  if (s->stage != BLOCK_REPLICATION_RUNNING) {
>  error_setg(errp, "Block replication is not running");
>  aio_context_release(aio_context);

Hello Everyone,
Could the block people have a look at this patch?

Regards,
Lukas Straub



Re: [PATCH v4 0/3] target/riscv: Expose "priv" register for GDB

2019-10-18 Thread Palmer Dabbelt

On Mon, 14 Oct 2019 08:45:26 PDT (-0700), jonat...@fintelia.io wrote:


This series adds a new "priv" virtual register that reports the current
privilege mode. This is helpful for debugging purposes because that information
is not actually available in any of the real CSRs.

The third patch in this series makes the priv virtual register writitable. I'm
not entirely sure this is a good idea, so I split it out into its own patch. In
particular, this change will conflict with the hypervisor extension work which
assumes that the privilege mode does not change in unexpected cases.

As pointed out in a previous version of this series, GDB actually contains some
support already for the accessing the privilege mode via a virtual "priv"
register, including to convert the values into human readable forms:

(gdb) info reg priv
priv   0x3  prv:3 [Machine]

Changlog V4:
- Fix typo in filename

Changlog V3:
- Break patch into series
- Make priv a virtual register

Changelog V2:
- Use PRV_H and PRV_S instead of integer literals

Jonathan Behrens (3)
  target/riscv: Tell gdbstub the correct number of CSRs
  target/riscv: Expose priv register for GDB for reads
  target/riscv: Make the priv register writable by GDB

 configure   |  4 ++--
 gdb-xml/riscv-32bit-virtual.xml | 11 +++
 gdb-xml/riscv-64bit-virtual.xml | 11 +++
 target/riscv/gdbstub.c  | 36 ++--
 4 files changed, 58 insertions(+), 4 deletions(-)


Thanks.  I've taken these into my patch queue, which I hope to submit soon!



Re: [PATCH v5 31/55] target/riscv: fetch code with translator_ld

2019-10-18 Thread Palmer Dabbelt

On Mon, 14 Oct 2019 10:59:07 PDT (-0700), alistai...@gmail.com wrote:

On Mon, Oct 14, 2019 at 4:20 AM Alex Bennée  wrote:


From: "Emilio G. Cota" 

Signed-off-by: Emilio G. Cota 
Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 


Reviewed-by: Alistair Francis 


and

Acked-by: Palmer Dabbelt 

as I'm assuming this will go in with the rest of the patch set.



Alistair


---
 target/riscv/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index adeddb85f6..b26533d4fd 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -779,7 +779,7 @@ static void riscv_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 DisasContext *ctx = container_of(dcbase, DisasContext, base);
 CPURISCVState *env = cpu->env_ptr;

-ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
+ctx->opcode = translator_ldl(env, ctx->base.pc_next);
 decode_opc(ctx);
 ctx->base.pc_next = ctx->pc_succ_insn;

--
2.20.1






Re: [PATCH] Fix unsigned integer underflow in fd-trans.c

2019-10-18 Thread Shu-Chun Weng
(Re-sending to the list because I forgot to turn off HTML before and
it was bounced.)

That does prevent the integer underflow, but it also changes the
behavior and I don't think the new behavior is desirable.

If the extra payload has a smaller alignment than the header, it makes
sense for the user program to generate a nlmsg_len that is not a
multiple of the alignment. When it's the last entry, the new condition
will it because NLMSG_ALIGN pushes the aligned length over `len`, yet
the single entry processing function won't actually read beyond the
buffer as long as it's bounded by nlmsg_len.

Shu-Chun


On Fri, Oct 18, 2019 at 12:26 AM Laurent Vivier  wrote:
>
> Le 18/10/2019 à 02:19, Shu-Chun Weng a écrit :
> > In any of these `*_for_each_*` functions, the last entry in the buffer (so 
> > the
> > "remaining length in the buffer" `len` is equal to the length of the
> > entry `nlmsg_len`/`nla_len`/etc) has size that is not a multiple of the
> > alignment, the aligned lengths `*_ALIGN(*_len)` will be greater than `len`.
> > Since `len` is unsigned (`size_t`), it underflows and the loop will read
> > pass the buffer.
> >
> > This may manifest as random EINVAL or EOPNOTSUPP error on IO or network
> > system calls.
> >
> > Signed-off-by: Shu-Chun Weng 
> > ---
> >  linux-user/fd-trans.c | 51 +--
> >  1 file changed, 40 insertions(+), 11 deletions(-)
> >
> > diff --git a/linux-user/fd-trans.c b/linux-user/fd-trans.c
> > index 60077ce531..9b92386abf 100644
> > --- a/linux-user/fd-trans.c
> > +++ b/linux-user/fd-trans.c
> > @@ -279,6 +279,7 @@ static abi_long host_to_target_for_each_nlmsg(struct 
> > nlmsghdr *nlh,
> > (struct nlmsghdr *))
> >  {
> >  uint32_t nlmsg_len;
> > +uint32_t aligned_nlmsg_len;
> >  abi_long ret;
> >
> >  while (len > sizeof(struct nlmsghdr)) {
> > @@ -312,8 +313,13 @@ static abi_long host_to_target_for_each_nlmsg(struct 
> > nlmsghdr *nlh,
> >  break;
> >  }
> >  tswap_nlmsghdr(nlh);
> > -len -= NLMSG_ALIGN(nlmsg_len);
> > -nlh = (struct nlmsghdr *)(((char*)nlh) + NLMSG_ALIGN(nlmsg_len));
> > +
> > +aligned_nlmsg_len = NLMSG_ALIGN(nlmsg_len);
> > +if (aligned_nlmsg_len >= len) {
> > +break;
> > +}
> > +len -= aligned_nlmsg_len;
> > +nlh = (struct nlmsghdr *)(((char*)nlh) + aligned_nlmsg_len);
> >  }
> >  return 0;
> >  }
>
> Nice catch.
>
> But the first "if" in the loop is already here for that, we only need to
> fix it with something like that in all the for_each functions:
>
> @@ -285,7 +285,7 @@ static abi_long host_to_target_for_each_nlmsg(struct
> nlmsghdr *nlh,
>
>  nlmsg_len = nlh->nlmsg_len;
>  if (nlmsg_len < sizeof(struct nlmsghdr) ||
> -nlmsg_len > len) {
> +NLMSG_ALIGN(nlmsg_len) > len) {
>  break;
>  }
>
> Thanks,
> Laurent
>


smime.p7s
Description: S/MIME Cryptographic Signature


[Bug 1848556] Re: qemu-img check failing on remote image in Eoan

2019-10-18 Thread Rod Smith
I tried qemu from git, but I get an "unknown protocol" error when I try
to access an image via HTTP:

$ ./qemu-img check http://10.193.37.117/cloud/eoan-server-cloudimg-amd64.img
qemu-img: Could not open 
'http://10.193.37.117/cloud/eoan-server-cloudimg-amd64.img': Unknown protocol 
'http'

Is there a development library or ./configure option I need to use to
add this support? I didn't see anything obvious in the ./configure
output.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1848556

Title:
  qemu-img check failing on remote image in Eoan

Status in QEMU:
  Confirmed
Status in qemu package in Ubuntu:
  New

Bug description:
  The "qemu-img check" function is failing on remote (HTTP-hosted)
  images, beginning with Ubuntu 19.10 (qemu-utils version 1:4.0+dfsg-
  0ubuntu9). With previous versions, through Ubuntu 19.04/qemu-utils
  version 1:3.1+dfsg-2ubuntu3.5, the following worked:

  $ /usr/bin/qemu-img check  
http://10.193.37.117/cloud/eoan-server-cloudimg-amd64.img
  No errors were found on the image.
  19778/36032 = 54.89% allocated, 90.34% fragmented, 89.90% compressed clusters
  Image end offset: 514064384

  The 10.193.37.117 server holds an Apache server that hosts the cloud
  images on a LAN. Beginning with Ubuntu 19.10/qemu-utils 1:4.0+dfsg-
  0ubuntu9, the same command never returns. (I've left it for up to an
  hour with no change.) I'm able to wget the image from the same server
  and installation on which qemu-img check fails. I've tried several
  .img files on the server, ranging from Bionic to Eoan, with the same
  results with all of them.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1848556/+subscriptions



Re: [PATCH v1 4/6] s390x/tcg: Fix VECTOR SUBTRACT COMPUTE BORROW INDICATION

2019-10-18 Thread David Hildenbrand

On 18.10.19 19:41, David Hildenbrand wrote:

On 18.10.19 18:10, David Hildenbrand wrote:

Looks like my idea of what a "borrow" is was wrong. We are dealing with
unsigned numbers. A subtraction is simply an addition with the bitwise
complement. If we get a carry during the addition, that's the borrow.
"The operands are treated as unsigned binary integers."

This is nice, as we can reuse the VECTOR ADD COMPUTE CARRY functions
and avoid helpers, all we have to do is compute the bitwise complement.

Fixes: 1ee2d7ba72f6 ("s390x/tcg: Implement VECTOR SUBTRACT COMPUTE BORROW 
INDICATION")
Signed-off-by: David Hildenbrand 
---
   target/s390x/helper.h   |  2 --
   target/s390x/translate_vx.inc.c | 45 -
   target/s390x/vec_int_helper.c   | 16 
   3 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 56e8149866..ca1e08100a 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -207,8 +207,6 @@ DEF_HELPER_FLAGS_4(gvec_verim16, TCG_CALL_NO_RWG, void, 
ptr, cptr, cptr, i32)
   DEF_HELPER_FLAGS_4(gvec_vsl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
   DEF_HELPER_FLAGS_4(gvec_vsra, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
   DEF_HELPER_FLAGS_4(gvec_vsrl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
-DEF_HELPER_FLAGS_4(gvec_vscbi8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
-DEF_HELPER_FLAGS_4(gvec_vscbi16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
   DEF_HELPER_4(gvec_vtm, void, ptr, cptr, env, i32)
   
   /* === Vector String Instructions === */

diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 5ce7bfb0af..40bcc1604e 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2130,14 +2130,40 @@ static DisasJumpType op_vs(DisasContext *s, DisasOps *o)
   return DISAS_NEXT;
   }
   
+static void gen_scbi8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)

+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_not_i64(t, b);
+gen_acc(d, a, t, ES_8);
+tcg_temp_free_i64(t);
+}


BTW, I would have thought that we need the 2nd complement in all these
cases. However, the description of the other functions confused me
(VECTOR SUBTRACT WITH BORROW INDICATION) - add bitwise complement and
add the borrow.

This passes my test cases (that are verified against real HW), but I am
not sure if I check all the corner cases.

@Richard, do you have any idea how to do it the right way for this
instruction?



My impression was right. A simple "0-0" test makes this visible. The 
other two fixes seem to be correct, though.


Will rework.

--

Thanks,

David / dhildenb



[PATCH v5 2/3] tests/vm: Let subclasses disable IPv6

2019-10-18 Thread Eduardo Habkost
The mechanism will be used to work around issues related to IPv6
on the netbsd image builder.

Signed-off-by: Eduardo Habkost 
---
 tests/vm/basevm.py | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index b5d1479bee..2929de23aa 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -57,6 +57,8 @@ class BaseVM(object):
 arch = "#arch"
 # command to halt the guest, can be overridden by subclasses
 poweroff = "poweroff"
+# enable IPv6 networking
+ipv6 = True
 def __init__(self, debug=False, vcpus=None):
 self._guest = None
 self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-",
@@ -81,7 +83,8 @@ class BaseVM(object):
 self._args = [ \
 "-nodefaults", "-m", "4G",
 "-cpu", "max",
-"-netdev", "user,id=vnet,hostfwd=:127.0.0.1:0-:22",
+"-netdev", "user,id=vnet,hostfwd=:127.0.0.1:0-:22" +
+   (",ipv6=no" if not self.ipv6 else ""),
 "-device", "virtio-net-pci,netdev=vnet",
 "-vnc", "127.0.0.1:0,to=20"]
 if vcpus and vcpus > 1:
-- 
2.21.0




[PATCH v5 3/3] tests/vm/netbsd: Disable IPv6

2019-10-18 Thread Eduardo Habkost
Workaround for issues when the host has no IPv6 connectivity.

Signed-off-by: Eduardo Habkost 
---
 tests/vm/netbsd | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/tests/vm/netbsd b/tests/vm/netbsd
index 49a99477f4..5e04dcd9b1 100755
--- a/tests/vm/netbsd
+++ b/tests/vm/netbsd
@@ -62,6 +62,13 @@ class NetBSDVM(basevm.BaseVM):
 """
 poweroff = "/sbin/poweroff"
 
+# Workaround for NetBSD + IPv6 + slirp issues.
+# NetBSD seems to ignore the ICMPv6 Destination Unreachable
+# messages generated by slirp.  When the host has no IPv6
+# connectivity, this causes every connection to ftp.NetBSD.org
+# take more than a minute to be established.
+ipv6 = False
+
 def build_image(self, img):
 cimg = self._download_with_cache(self.link)
 img_tmp = img + ".tmp"
-- 
2.21.0




qemu/powernv: coreboot support?

2019-10-18 Thread Marty E. Plummer
Hello,

First off, thank you for the work you've done on the ppc64 support, it
has been very useful. I'm currently working on a coreboot port for the
talos ii line of systems (which means more ppc64 support, support
specifically for the power9 sforza chip, and specific mainboard support.
My plate is very full lol) and have been using qemu to debug the
bootblock.

It has been very useful for that, but I'm now at the point where I need
to jump to romstage, and that's where it gets tricky. qemu parses the rom
image and looks for a ffs header, locates skiboot on it, and jumps straight
to that. Not exactly ideal for debugging something not produced from op-build.

Do you think it would be within your wheelhouse to provide a generic, non-ffs
pnor interface for loading arbitary rom images? It would be of great help if
you could. (This would still hopefully have the bmc support code as
well, as I'm still needing to support a system using one).

Regards,
Marty



Re: [PATCH] Fix unsigned integer underflow in fd-trans.c

2019-10-18 Thread Shu-Chun Weng
That does prevent the integer underflow, but it also changes the behavior
and I don't think the new behavior is desirable.

If the extra payload has a smaller alignment than the header, it makes
sense for the user program to generate a nlmsg_len that is not a multiple
of the alignment. When it's the last entry, the new condition will it
because NLMSG_ALIGN pushes the aligned length over `len`, yet the single
entry processing function won't actually read beyond the buffer as long as
it's bounded by nlmsg_len.

Shu-Chun

On Fri, Oct 18, 2019 at 12:26 AM Laurent Vivier  wrote:

> Le 18/10/2019 à 02:19, Shu-Chun Weng a écrit :
> > In any of these `*_for_each_*` functions, the last entry in the buffer
> (so the
> > "remaining length in the buffer" `len` is equal to the length of the
> > entry `nlmsg_len`/`nla_len`/etc) has size that is not a multiple of the
> > alignment, the aligned lengths `*_ALIGN(*_len)` will be greater than
> `len`.
> > Since `len` is unsigned (`size_t`), it underflows and the loop will read
> > pass the buffer.
> >
> > This may manifest as random EINVAL or EOPNOTSUPP error on IO or network
> > system calls.
> >
> > Signed-off-by: Shu-Chun Weng 
> > ---
> >  linux-user/fd-trans.c | 51 +--
> >  1 file changed, 40 insertions(+), 11 deletions(-)
> >
> > diff --git a/linux-user/fd-trans.c b/linux-user/fd-trans.c
> > index 60077ce531..9b92386abf 100644
> > --- a/linux-user/fd-trans.c
> > +++ b/linux-user/fd-trans.c
> > @@ -279,6 +279,7 @@ static abi_long host_to_target_for_each_nlmsg(struct
> nlmsghdr *nlh,
> > (struct nlmsghdr
> *))
> >  {
> >  uint32_t nlmsg_len;
> > +uint32_t aligned_nlmsg_len;
> >  abi_long ret;
> >
> >  while (len > sizeof(struct nlmsghdr)) {
> > @@ -312,8 +313,13 @@ static abi_long
> host_to_target_for_each_nlmsg(struct nlmsghdr *nlh,
> >  break;
> >  }
> >  tswap_nlmsghdr(nlh);
> > -len -= NLMSG_ALIGN(nlmsg_len);
> > -nlh = (struct nlmsghdr *)(((char*)nlh) +
> NLMSG_ALIGN(nlmsg_len));
> > +
> > +aligned_nlmsg_len = NLMSG_ALIGN(nlmsg_len);
> > +if (aligned_nlmsg_len >= len) {
> > +break;
> > +}
> > +len -= aligned_nlmsg_len;
> > +nlh = (struct nlmsghdr *)(((char*)nlh) + aligned_nlmsg_len);
> >  }
> >  return 0;
> >  }
>
> Nice catch.
>
> But the first "if" in the loop is already here for that, we only need to
> fix it with something like that in all the for_each functions:
>
> @@ -285,7 +285,7 @@ static abi_long host_to_target_for_each_nlmsg(struct
> nlmsghdr *nlh,
>
>  nlmsg_len = nlh->nlmsg_len;
>  if (nlmsg_len < sizeof(struct nlmsghdr) ||
> -nlmsg_len > len) {
> +NLMSG_ALIGN(nlmsg_len) > len) {
>  break;
>  }
>
> Thanks,
> Laurent
>
>


smime.p7s
Description: S/MIME Cryptographic Signature


[PATCH v5 1/3] tests/vm: netbsd autoinstall, using serial console

2019-10-18 Thread Eduardo Habkost
From: Gerd Hoffmann 

Instead of fetching the prebuilt image from patchew download the install
iso and prepare the image locally.  Install to disk, using the serial
console.  Create qemu user, configure ssh login.  Install packages
needed for qemu builds.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Kamil Rytarowski 
Tested-by: Thomas Huth 
[ehabkost: rebased to latest qemu.git master]
Signed-off-by: Eduardo Habkost 
---
 tests/vm/netbsd | 189 +---
 1 file changed, 179 insertions(+), 10 deletions(-)

diff --git a/tests/vm/netbsd b/tests/vm/netbsd
index ee9eaeab50..49a99477f4 100755
--- a/tests/vm/netbsd
+++ b/tests/vm/netbsd
@@ -2,10 +2,11 @@
 #
 # NetBSD VM image
 #
-# Copyright 2017 Red Hat Inc.
+# Copyright 2017-2019 Red Hat Inc.
 #
 # Authors:
 #  Fam Zheng 
+#  Gerd Hoffmann 
 #
 # This code is licensed under the GPL version 2 or later.  See
 # the COPYING file in the top-level directory.
@@ -13,30 +14,198 @@
 
 import os
 import sys
+import time
 import subprocess
 import basevm
 
 class NetBSDVM(basevm.BaseVM):
 name = "netbsd"
 arch = "x86_64"
+
+link = 
"https://cdn.netbsd.org/pub/NetBSD/NetBSD-8.0/images/NetBSD-8.0-amd64.iso";
+size = "20G"
+pkgs = [
+# tools
+"git-base",
+"pkgconf",
+"xz",
+"python37",
+
+# gnu tools
+"bash",
+"gmake",
+"gsed",
+"flex", "bison",
+
+# libs: crypto
+"gnutls",
+
+# libs: images
+"jpeg",
+"png",
+
+   # libs: ui
+"SDL2",
+"gtk3+",
+"libxkbcommon",
+]
+
 BUILD_SCRIPT = """
 set -e;
-rm -rf /var/tmp/qemu-test.*
-cd $(mktemp -d /var/tmp/qemu-test.XX);
+rm -rf /home/qemu/qemu-test.*
+cd $(mktemp -d /home/qemu/qemu-test.XX);
+mkdir src build; cd src;
 tar -xf /dev/rld1a;
-./configure --python=python2.7 {configure_opts};
+cd ../build
+../src/configure --python=python3.7 --disable-opengl {configure_opts};
 gmake --output-sync -j{jobs} {target} {verbose};
 """
+poweroff = "/sbin/poweroff"
 
 def build_image(self, img):
-cimg = 
self._download_with_cache("http://download.patchew.org/netbsd-7.1-amd64.img.xz";,
- 
sha256sum='b633d565b0eac3d02015cd0c81440bd8a7a8df8512615ac1ee05d318be015732')
-img_tmp_xz = img + ".tmp.xz"
+cimg = self._download_with_cache(self.link)
 img_tmp = img + ".tmp"
-sys.stderr.write("Extracting the image...\n")
-subprocess.check_call(["ln", "-f", cimg, img_tmp_xz])
-subprocess.check_call(["xz", "--keep", "-dvf", img_tmp_xz])
+iso = img + ".install.iso"
+
+self.print_step("Preparing iso and disk image")
+subprocess.check_call(["ln", "-f", cimg, iso])
+subprocess.check_call(["qemu-img", "create", "-f", "qcow2",
+   img_tmp, self.size])
+
+self.print_step("Booting installer")
+self.boot(img_tmp, extra_args = [
+"-bios", "pc-bios/bios-256k.bin",
+"-machine", "graphics=off",
+"-cdrom", iso
+])
+self.console_init()
+self.console_wait("Primary Bootstrap")
+
+# serial console boot menu output doesn't work for some
+# reason, so we have to fly blind ...
+for char in list("5consdev com0\n"):
+time.sleep(0.2)
+self.console_send(char)
+self.console_wait("")
+self.console_wait_send("> ", "boot\n")
+
+self.console_wait_send("Terminal type","xterm\n")
+self.console_wait_send("a: Installation messages", "a\n")
+self.console_wait_send("b: US-English","b\n")
+self.console_wait_send("a: Install NetBSD","a\n")
+self.console_wait("Shall we continue?")
+self.console_wait_send("b: Yes",   "b\n")
+
+self.console_wait_send("a: ld0",   "a\n")
+self.console_wait_send("a: This is the correct",   "a\n")
+self.console_wait_send("b: Use the entire disk",   "b\n")
+self.console_wait("NetBSD bootcode")
+self.console_wait_send("a: Yes",   "a\n")
+self.console_wait_send("b: Use existing part", "b\n")
+self.console_wait_send("x: Partition sizes ok","x\n")
+self.console_wait_send("for your NetBSD disk", "\n")
+self.console_wait("Shall we continue?")
+self.console_wait_send("b: Yes",   "b\n")
+
+self.console_wait_send("b: Use serial port com0",  "b\n")
+self.console_wait_send("f: Set serial baud rate",  "f\n")
+self.console_wait_send("a: 9600",  "a\n")
+self.console_wait_send("x: Exit",  "x\n")
+
+self.console_wait_send("a: Full installation", "a\n")
+self.consol

Re: [PATCH] hw/timer/exynos4210_mct: Initialize ptimer before starting it

2019-10-18 Thread Guenter Roeck
On Fri, Oct 18, 2019 at 03:31:49PM +0100, Peter Maydell wrote:
> From: Guenter Roeck 
> 
> When booting a recent Linux kernel, the qemu message "Timer with delta
> zero, disabling" is seen, apparently because a ptimer is started before
> being initialized.  Fix the problem by initializing the offending ptimer
> before starting it.
> 
> The bug is effectively harmless in the old QEMUBH setup
> because the sequence of events is:
>  * the delta zero means the timer expires immediately
>  * ptimer_reload() arranges for exynos4210_gfrc_event() to be called
>  * ptimer_reload() notices the zero delta and disables the timer
>  * later, the QEMUBH runs, and exynos4210_gfrc_event() correctly
>configures the timer and restarts it
> 
> In the new transaction based API the bug is still harmless,
> but differences of when the callback function runs mean the
> message is not printed any more:
>  * ptimer_run() does nothing as it's inside a transaction block
>  * ptimer_transaction_commit() sees it has work to do and
>calls ptimer_reload()
>  * the zero delta means the timer expires immediately
>  * ptimer_reload() calls exynos4210_gfrc_event() directly
>  * exynos4210_gfrc_event() configures the timer
>  * the delta is no longer zero so ptimer_reload() doesn't complain
>(the zero-delta test is after the trigger-callback in
>the ptimer_reload() function)
> 
> Regardless, the behaviour here was not intentional, and we should
> just program the ptimer correctly to start with.
> 
> Signed-off-by: Guenter Roeck 
> [PMM: Expansion/clarification of the commit message:
>  the message is about a zero delta, not a zero period;
>  added detail to the commit message of the analysis of what
>  is happening and why the kernel boots even with the message;
>  added note that the message goes away with the new ptimer API]
> Signed-off-by: Peter Maydell 
> ---
> Philippe pointed me at this bugfix from Guenter. At one point
> in my working on the ptimer API changes I thought this bugfix
> would be necessary as a prerequisite, but in fact the issue
> was in my ptimer changes, and it just happened that fixing
> the MCT bug was a workaround for my bug. Even though the
> ptimer API changes actually coincidentally now suppress the
> annoying message about a zero delta, the behaviour is definitely
> not intentional, and since I spent the time working through the
> analysis of what was actually going on here I don't want
> to waste it :-)
> ---

Thanks a lot for picking this up, and for the great analysis!

Guenter

>  hw/timer/exynos4210_mct.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
> index 72257584145..944120aea59 100644
> --- a/hw/timer/exynos4210_mct.c
> +++ b/hw/timer/exynos4210_mct.c
> @@ -1254,7 +1254,7 @@ static void exynos4210_mct_write(void *opaque, hwaddr 
> offset,
>  /* Start FRC if transition from disabled to enabled */
>  if ((value & G_TCON_TIMER_ENABLE) > (old_val &
>  G_TCON_TIMER_ENABLE)) {
> -exynos4210_gfrc_start(&s->g_timer);
> +exynos4210_gfrc_restart(s);
>  }
>  if ((value & G_TCON_TIMER_ENABLE) < (old_val &
>  G_TCON_TIMER_ENABLE)) {
> -- 
> 2.20.1
> 



[PATCH v5 0/3] tests/vm: netbsd autoinstall, with IPv6 disabled

2019-10-18 Thread Eduardo Habkost
I'm numbering this series v5 because it's a new version of the
patch sent by Gerd, at:

  Date: Mon, 17 Jun 2019 06:38:56 +0200
  Message-Id: <20190617043858.8290-10-kra...@redhat.com>
  Subject: [PATCH v4 09/11] tests/vm: netbsd autoinstall, using serial console

Changes v4 -> v5:
* Rebase to latest qemu.git master
* Disable IPv6 by default (see
  https://lore.kernel.org/qemu-devel/20191017225548.gl4...@habkost.net/ for 
context)

Eduardo Habkost (2):
  tests/vm: Let subclasses disable IPv6
  tests/vm/netbsd: Disable IPv6

Gerd Hoffmann (1):
  tests/vm: netbsd autoinstall, using serial console

 tests/vm/basevm.py |   5 +-
 tests/vm/netbsd| 196 ++---
 2 files changed, 190 insertions(+), 11 deletions(-)

-- 
2.21.0




Re: [PATCH 4/4] target/arm: Convert PMULL.8 to gvec

2019-10-18 Thread Alex Bennée


Richard Henderson  writes:

> We still need two different helpers, since NEON and SVE2 get the
> inputs from different locations within the source vector.  However,
> we can convert both to the same internal form for computation.
>
> The sve2 helper is not used yet, but adding it with this patch
> helps illustrate why the neon changes are helpful.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Alex Bennée 
Tested-by: Alex Bennée 

> ---
>  target/arm/helper-sve.h|  2 ++
>  target/arm/helper.h|  3 +-
>  target/arm/neon_helper.c   | 32 
>  target/arm/translate-a64.c | 27 +++--
>  target/arm/translate.c | 26 -
>  target/arm/vec_helper.c| 60 ++
>  6 files changed, 95 insertions(+), 55 deletions(-)
>
> diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
> index 9e79182ab4..2f47279155 100644
> --- a/target/arm/helper-sve.h
> +++ b/target/arm/helper-sve.h
> @@ -1574,3 +1574,5 @@ DEF_HELPER_FLAGS_6(sve_stdd_le_zd, TCG_CALL_NO_WG,
> void, env, ptr, ptr, ptr, tl, i32)
>  DEF_HELPER_FLAGS_6(sve_stdd_be_zd, TCG_CALL_NO_WG,
> void, env, ptr, ptr, ptr, tl, i32)
> +
> +DEF_HELPER_FLAGS_4(sve2_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
> diff --git a/target/arm/helper.h b/target/arm/helper.h
> index d954399b7e..8a8517cf34 100644
> --- a/target/arm/helper.h
> +++ b/target/arm/helper.h
> @@ -335,7 +335,6 @@ DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
>  DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
>  DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
>  DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
> -DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
>
>  DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
>  DEF_HELPER_2(neon_tst_u16, i32, i32, i32)
> @@ -688,6 +687,8 @@ DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, 
> ptr, ptr, ptr, i32)
>  DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
>  DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
>
> +DEF_HELPER_FLAGS_4(neon_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
> +
>  #ifdef TARGET_AARCH64
>  #include "helper-a64.h"
>  #include "helper-sve.h"
> diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
> index 6a107da0e1..c7a8438b42 100644
> --- a/target/arm/neon_helper.c
> +++ b/target/arm/neon_helper.c
> @@ -1129,38 +1129,6 @@ NEON_VOP(mul_u8, neon_u8, 4)
>  NEON_VOP(mul_u16, neon_u16, 2)
>  #undef NEON_FN
>
> -/* Polynomial multiplication is like integer multiplication except the
> -   partial products are XORed, not added.  */
> -uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
> -{
> -uint64_t result = 0;
> -uint64_t mask;
> -uint64_t op2ex = op2;
> -op2ex = (op2ex & 0xff) |
> -((op2ex & 0xff00) << 8) |
> -((op2ex & 0xff) << 16) |
> -((op2ex & 0xff00) << 24);
> -while (op1) {
> -mask = 0;
> -if (op1 & 1) {
> -mask |= 0x;
> -}
> -if (op1 & (1 << 8)) {
> -mask |= (0xU << 16);
> -}
> -if (op1 & (1 << 16)) {
> -mask |= (0xULL << 32);
> -}
> -if (op1 & (1 << 24)) {
> -mask |= (0xULL << 48);
> -}
> -result ^= op2ex & mask;
> -op1 = (op1 >> 1) & 0x7f7f7f7f;
> -op2ex <<= 1;
> -}
> -return result;
> -}
> -
>  #define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0
>  NEON_VOP(tst_u8, neon_u8, 4)
>  NEON_VOP(tst_u16, neon_u16, 2)
> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
> index 12588d18df..2934e4fc16 100644
> --- a/target/arm/translate-a64.c
> +++ b/target/arm/translate-a64.c
> @@ -10483,10 +10483,6 @@ static void handle_3rd_widening(DisasContext *s, int 
> is_q, int is_u, int size,
>  gen_helper_neon_addl_saturate_s32(tcg_passres, cpu_env,
>tcg_passres, tcg_passres);
>  break;
> -case 14: /* PMULL */
> -assert(size == 0);
> -gen_helper_neon_mull_p8(tcg_passres, tcg_op1, tcg_op2);
> -break;
>  default:
>  g_assert_not_reached();
>  }
> @@ -10650,11 +10646,21 @@ static void disas_simd_three_reg_diff(DisasContext 
> *s, uint32_t insn)
>  handle_3rd_narrowing(s, is_q, is_u, size, opcode, rd, rn, rm);
>  break;
>  case 14: /* PMULL, PMULL2 */
> -if (is_u || size == 1 || size == 2) {
> +if (is_u) {
>  unallocated_encoding(s);
>  return;
>  }
> -if (size == 3) {
> +switch (size) {
> +case 0: /* PMULL.P8 */
> +if (!fp_access_check(s)) {
> +return;
> +}
> +/* The Q field specifies lo/hi half input for this insn.  */
> +gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
> +

Re: [PATCH 05/14] dp8393x: replace PROP_PTR with PROP_LINK

2019-10-18 Thread Aleksandar Markovic
On Friday, October 18, 2019, Marc-André Lureau 
wrote:

> Signed-off-by: Marc-André Lureau 
> ---
>  hw/mips/mips_jazz.c | 3 ++-
>  hw/net/dp8393x.c| 7 +++
>  2 files changed, 5 insertions(+), 5 deletions(-)
>
>
Marc-Andre,

Can you put together a paragraph on why we need this patch, and place it in
the commit message?

Thanks,

Aleksandar





> diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
> index 8d010a0b6e..878925a963 100644
> --- a/hw/mips/mips_jazz.c
> +++ b/hw/mips/mips_jazz.c
> @@ -284,7 +284,8 @@ static void mips_jazz_init(MachineState *machine,
>  dev = qdev_create(NULL, "dp8393x");
>  qdev_set_nic_properties(dev, nd);
>  qdev_prop_set_uint8(dev, "it_shift", 2);
> -qdev_prop_set_ptr(dev, "dma_mr", rc4030_dma_mr);
> +object_property_set_link(OBJECT(dev), OBJECT(rc4030_dma_mr),
> + "dma_mr", &error_abort);
>  qdev_init_nofail(dev);
>  sysbus = SYS_BUS_DEVICE(dev);
>  sysbus_mmio_map(sysbus, 0, 0x80001000);
> diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> index a5678e11fa..946c7a8f64 100644
> --- a/hw/net/dp8393x.c
> +++ b/hw/net/dp8393x.c
> @@ -173,7 +173,7 @@ typedef struct dp8393xState {
>  int loopback_packet;
>
>  /* Memory access */
> -void *dma_mr;
> +MemoryRegion *dma_mr;
>  AddressSpace as;
>  } dp8393xState;
>
> @@ -922,7 +922,8 @@ static const VMStateDescription vmstate_dp8393x = {
>
>  static Property dp8393x_properties[] = {
>  DEFINE_NIC_PROPERTIES(dp8393xState, conf),
> -DEFINE_PROP_PTR("dma_mr", dp8393xState, dma_mr),
> +DEFINE_PROP_LINK("dma_mr", dp8393xState, dma_mr,
> + TYPE_MEMORY_REGION, MemoryRegion *),
>  DEFINE_PROP_UINT8("it_shift", dp8393xState, it_shift, 0),
>  DEFINE_PROP_END_OF_LIST(),
>  };
> @@ -936,8 +937,6 @@ static void dp8393x_class_init(ObjectClass *klass,
> void *data)
>  dc->reset = dp8393x_reset;
>  dc->vmsd = &vmstate_dp8393x;
>  dc->props = dp8393x_properties;
> -/* Reason: dma_mr property can't be set */
> -dc->user_creatable = false;
>  }
>
>  static const TypeInfo dp8393x_info = {
> --
> 2.23.0.606.g08da6496b6
>
>
>


[PATCH v8 20/22] target/arm: Rebuild hflags for M-profile

2019-10-18 Thread Richard Henderson
Continue setting, but not relying upon, env->hflags.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
v7: Add rebuilds for v7m_msr and nvic_writel to v7m.ccr.
v8: Split nvic update to a new patch and generalize location.
---
 target/arm/m_helper.c  | 6 ++
 target/arm/translate.c | 5 -
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 27cd2f3f96..f2512e448e 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -494,6 +494,7 @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
 switch_v7m_security_state(env, dest & 1);
 env->thumb = 1;
 env->regs[15] = dest & ~1;
+arm_rebuild_hflags(env);
 }
 
 void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
@@ -555,6 +556,7 @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
 switch_v7m_security_state(env, 0);
 env->thumb = 1;
 env->regs[15] = dest;
+arm_rebuild_hflags(env);
 }
 
 static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
@@ -895,6 +897,7 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, 
bool dotailchain,
 env->regs[14] = lr;
 env->regs[15] = addr & 0xfffe;
 env->thumb = addr & 1;
+arm_rebuild_hflags(env);
 }
 
 static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
@@ -1765,6 +1768,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
 
 /* Otherwise, we have a successful exception exit. */
 arm_clear_exclusive(env);
+arm_rebuild_hflags(env);
 qemu_log_mask(CPU_LOG_INT, "...successful exception return\n");
 }
 
@@ -1837,6 +1841,7 @@ static bool do_v7m_function_return(ARMCPU *cpu)
 xpsr_write(env, 0, XPSR_IT);
 env->thumb = newpc & 1;
 env->regs[15] = newpc & ~1;
+arm_rebuild_hflags(env);
 
 qemu_log_mask(CPU_LOG_INT, "...function return successful\n");
 return true;
@@ -1959,6 +1964,7 @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
 switch_v7m_security_state(env, true);
 xpsr_write(env, 0, XPSR_IT);
 env->regs[15] += 4;
+arm_rebuild_hflags(env);
 return true;
 
 gen_invep:
diff --git a/target/arm/translate.c b/target/arm/translate.c
index cb47cd9744..b3720cd59b 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -8325,7 +8325,7 @@ static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
 
 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
 {
-TCGv_i32 addr, reg;
+TCGv_i32 addr, reg, el;
 
 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
 return false;
@@ -8335,6 +8335,9 @@ static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
 gen_helper_v7m_msr(cpu_env, addr, reg);
 tcg_temp_free_i32(addr);
 tcg_temp_free_i32(reg);
+el = tcg_const_i32(s->current_el);
+gen_helper_rebuild_hflags_m32(cpu_env, el);
+tcg_temp_free_i32(el);
 gen_lookup_tb(s);
 return true;
 }
-- 
2.17.1




[PATCH v8 16/22] target/arm: Rebuild hflags at EL changes

2019-10-18 Thread Richard Henderson
Begin setting, but not relying upon, env->hflags.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 linux-user/syscall.c| 1 +
 target/arm/cpu.c| 1 +
 target/arm/helper-a64.c | 3 +++
 target/arm/helper.c | 2 ++
 target/arm/machine.c| 1 +
 target/arm/op_helper.c  | 1 +
 6 files changed, 9 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e2af3c1494..ebefd05140 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9982,6 +9982,7 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 aarch64_sve_narrow_vq(env, vq);
 }
 env->vfp.zcr_el[1] = vq - 1;
+arm_rebuild_hflags(env);
 ret = vq * 16;
 }
 return ret;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 13813fb213..ab3e1a0361 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -406,6 +406,7 @@ static void arm_cpu_reset(CPUState *s)
 
 hw_breakpoint_update_all(cpu);
 hw_watchpoint_update_all(cpu);
+arm_rebuild_hflags(env);
 }
 
 bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index bca80bdc38..b4cd680fc4 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -1025,6 +1025,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t 
new_pc)
 } else {
 env->regs[15] = new_pc & ~0x3;
 }
+helper_rebuild_hflags_a32(env, new_el);
 qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
   "AArch32 EL%d PC 0x%" PRIx32 "\n",
   cur_el, new_el, env->regs[15]);
@@ -1036,10 +1037,12 @@ void HELPER(exception_return)(CPUARMState *env, 
uint64_t new_pc)
 }
 aarch64_restore_sp(env, new_el);
 env->pc = new_pc;
+helper_rebuild_hflags_a64(env, new_el);
 qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
   "AArch64 EL%d PC 0x%" PRIx64 "\n",
   cur_el, new_el, env->pc);
 }
+
 /*
  * Note that cur_el can never be 0.  If new_el is 0, then
  * el0_a64 is return_to_aa64, else el0_a64 is ignored.
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b2d701cf00..aae7b62458 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7998,6 +7998,7 @@ static void take_aarch32_exception(CPUARMState *env, int 
new_mode,
 env->regs[14] = env->regs[15] + offset;
 }
 env->regs[15] = newpc;
+arm_rebuild_hflags(env);
 }
 
 static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
@@ -8345,6 +8346,7 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
 pstate_write(env, PSTATE_DAIF | new_mode);
 env->aarch64 = 1;
 aarch64_restore_sp(env, new_el);
+helper_rebuild_hflags_a64(env, new_el);
 
 env->pc = addr;
 
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 5c36707a7c..eb28b2381b 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -756,6 +756,7 @@ static int cpu_post_load(void *opaque, int version_id)
 if (!kvm_enabled()) {
 pmu_op_finish(&cpu->env);
 }
+arm_rebuild_hflags(&cpu->env);
 
 return 0;
 }
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index 0fd4bd0238..ccc2cecb46 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -404,6 +404,7 @@ void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
  * state. Do the masking now.
  */
 env->regs[15] &= (env->thumb ? ~1 : ~3);
+arm_rebuild_hflags(env);
 
 qemu_mutex_lock_iothread();
 arm_call_el_change_hook(env_archcpu(env));
-- 
2.17.1




[PATCH v8 14/22] target/arm: Hoist store to cs_base in cpu_get_tb_cpu_state

2019-10-18 Thread Richard Henderson
By performing this store early, we avoid having to save and restore
the register holding the address around any function calls.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 3f7d3f257d..37424e3d4d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11225,6 +11225,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 {
 uint32_t flags, pstate_for_ss;
 
+*cs_base = 0;
 flags = rebuild_hflags_internal(env);
 
 if (is_a64(env)) {
@@ -11298,7 +11299,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 }
 
 *pflags = flags;
-*cs_base = 0;
 }
 
 #ifdef TARGET_AARCH64
-- 
2.17.1




Re: [PATCH v32 04/13] target/avr: Add instruction translation - Registers definition

2019-10-18 Thread Aleksandar Markovic
On Friday, October 18, 2019, Aleksandar Markovic <
aleksandar.m.m...@gmail.com> wrote:

>
>
> On Friday, October 18, 2019, Michael Rolnik  wrote:
>
>> On Fri, Oct 18, 2019 at 4:23 PM Aleksandar Markovic
>>  wrote:
>> >
>> >
>> >
>> > On Friday, October 18, 2019, Michael Rolnik  wrote:
>> >>
>> >>
>> >>
>> >> On Fri, Oct 18, 2019 at 11:52 AM Aleksandar Markovic <
>> aleksandar.m.m...@gmail.com> wrote:
>> >>>
>> >>>
>> >>>
>> >>> On Thursday, October 17, 2019, Michael Rolnik 
>> wrote:
>> 
>>  On Thu, Oct 17, 2019 at 11:17 PM Aleksandar Markovic
>>   wrote:
>>  >>
>>  >>
>>  >> >> +static TCGv cpu_Cf;
>>  >> >> +static TCGv cpu_Zf;
>>  >> >> +static TCGv cpu_Nf;
>>  >> >> +static TCGv cpu_Vf;
>>  >> >> +static TCGv cpu_Sf;
>>  >> >> +static TCGv cpu_Hf;
>>  >> >> +static TCGv cpu_Tf;
>>  >> >> +static TCGv cpu_If;
>>  >> >> +
>>  >> >
>>  >> >
>>  >> > Hello, Michael,
>>  >> >
>>  >> > Is there any particular reason or motivation beyond modelling
>> status register flags as TCGv variables?
>>  >>
>>  >>
>>  >>
>>  >> I think it's easier this way as I don't need to convert flag
>> values to
>>  >> bits or bits to flag values.
>>  >
>>  >
>>  > Ok. But, how do you map 0/1 flag value to the value of a TCGv
>> variable and vice versa? In other words, what value or values (out of 2^32
>> vales) of a TCGv variable mean the flag is 1? And the same question for 0.
>>  >
>>  > Is 01111110100 one or zero?
>>  >
>>  > Besides, in such arrangement, how do you display the 8-bit status
>> register in gdb, if at all?
>> 
>>  each flag register is either 0 or 1,
>> 
>> 
>> 
>> >>>
>> >>> Michael,
>> >>>
>> >>> If this is true, why is there a special handling of two flags in the
>> following code:
>> >>>
>> >>>
>> >>> static inline uint8_t cpu_get_sreg(CPUAVRState *env)
>> >>> {
>> >>> uint8_t sreg;
>> >>> sreg = (env->sregC & 0x01) << 0
>> >>> | (env->sregZ == 0 ? 1 : 0) << 1
>> >>> | (env->sregN) << 2
>> >>> | (env->sregV) << 3
>> >>> | (env->sregS) << 4
>> >>> | (env->sregH) << 5
>> >>> | (env->sregT) << 6
>> >>> | (env->sregI) << 7;
>> >>> return sreg;
>> >>> }
>> >>> static inline void cpu_set_sreg(CPUAVRState *env, uint8_t sreg)
>> >>> {
>> >>> env->sregC = (sreg >> 0) & 0x01;
>> >>> env->sregZ = (sreg >> 1) & 0x01 ? 0 : 1;
>> >>> env->sregN = (sreg >> 2) & 0x01;
>> >>> env->sregV = (sreg >> 3) & 0x01;
>> >>> env->sregS = (sreg >> 4) & 0x01;
>> >>> env->sregH = (sreg >> 5) & 0x01;
>> >>> env->sregT = (sreg >> 6) & 0x01;
>> >>> env->sregI = (sreg >> 7) & 0x01;
>> >>> }
>> >>>  ?
>> >>>
>> >> Aleksandar,
>> >>
>> >> If I understand your question correctly cpu_get_sreg assembles SREG
>> value to be presented by GDB, and cpu_set_sreg sets flags values when GDB
>> modifies SREG.
>> >>
>> >> Michael
>> >
>> >
>> >
>> >
>
> Why is handling of sregC and sregZ flags different than handling of other
>> flags? This contradicts your previos statement that 1 (in TCGv) means 1
>> (flag), and 0 (in TCGv) means 0 (flag)?
>> >
>> >
>> > Whatever is the explanation, ot should be included, in my opinion, in
>> code comments.
>> >
>> > Please, Michael, let's first clarify the issue from the question above.
>> >
>> > Thanks, Aleksandar
>> >
>> >
>> there is a comment here
>> https://github.com/michaelrolnik/qemu-avr/blob/master/
>> target/avr/cpu.h#L122-L129
>> >
>
>
>
> ...but it does explain WHY of my question.
>

I meant to say  "does not", not "does".

Michael, don't be discouraged by lenghty review process, just be persistent
and available for communication with reviewers.

Sincerely,
Aleksandar



>
> The reason I insist on your explanation is that when we model a cpu or a
> device in QEMU, a goal is that the model is as close to the hardware as
> possible. One may not, for pletora of reasons, succeed in reaching that
> goal, or, I can imagine, on purpose depart from that goal for some reason -
> perhaps that was the case in your implementation, where you modelled a
> single 8-bit status register with 8 TCGv variables.
>
> But, even that way of modelling was done inconsistently across bits of the
> status register. In that light, I want to know the justification for that,
> so repeat my question: Why is handling of sregC and sregZ flags different
> than handling of other flags in functions cpu_get_sreg()
> and cpu_get_sreg()? This was not explained in any comment or commit
> message. And is in contradiction with one of your previous answers.
>
> Yours,
> Aleksandar
>
>
>> >
>> >
>> >>>
>> >>> Thanks,
>> >>> A.
>> 
>> 
>>   they are calculated here
>>  1. https://github.com/michaelrolnik/qemu-avr/blob/avr-v32/
>> target/avr/translate.c#L146-L148
>>  2. https://github.com/michaelrolnik/qemu-avr/blob/avr-v32/
>> target/avr/translate.c#L166
>>  3. https://github.com/michaelrolnik/qemu-avr/blob/avr-v32/
>> target/avr/translate.c#L185-L187
>>  4. https://gith

[PATCH v8 11/22] target/arm: Hoist computation of TBFLAG_A32.VFPEN

2019-10-18 Thread Richard Henderson
There are 3 conditions that each enable this flag.  M-profile always
enables; A-profile with EL1 as AA64 always enables.  Both of these
conditions can easily be cached.  The final condition relies on the
FPEXC register which we are not prepared to cache.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h|  2 +-
 target/arm/helper.c | 14 ++
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 4d961474ce..9909ff89d4 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3192,7 +3192,7 @@ FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
  * the same thing as the current security state of the processor!
  */
 FIELD(TBFLAG_A32, NS, 6, 1)
-FIELD(TBFLAG_A32, VFPEN, 7, 1)  /* Not cached. */
+FIELD(TBFLAG_A32, VFPEN, 7, 1)  /* Partially cached, minus FPEXC. */
 FIELD(TBFLAG_A32, CONDEXEC, 8, 8)   /* Not cached. */
 FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
 /* For M profile only, set if FPCCR.LSPACT is set */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 398e5f5d6d..89aa6fd933 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11088,6 +11088,9 @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, 
int fp_el,
 {
 uint32_t flags = 0;
 
+/* v8M always enables the fpu.  */
+flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
+
 if (arm_v7m_is_handler_mode(env)) {
 flags = FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1);
 }
@@ -9,6 +11122,10 @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, 
int fp_el,
ARMMMUIdx mmu_idx)
 {
 uint32_t flags = rebuild_hflags_aprofile(env);
+
+if (arm_el_is_aa64(env, 1)) {
+flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
+}
 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
 }
 
@@ -11250,14 +11257,13 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE,
env->vfp.vec_stride);
 }
+if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
+flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
+}
 }
 
 flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
 flags = FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bits);
-if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
-|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
-flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
-}
 pstate_for_ss = env->uncached_cpsr;
 }
 
-- 
2.17.1




[PATCH v8 22/22] target/arm: Rely on hflags correct in cpu_get_tb_cpu_state

2019-10-18 Thread Richard Henderson
This is the payoff.

>From perf record -g data of ubuntu 18 boot and shutdown:

BEFORE:

-   23.02% 2.82%  qemu-system-aar  [.] helper_lookup_tb_ptr
   - 20.22% helper_lookup_tb_ptr
  + 10.05% tb_htable_lookup
  - 9.13% cpu_get_tb_cpu_state
   3.20% aa64_va_parameters_both
   0.55% fp_exception_el

-   11.66% 4.74%  qemu-system-aar  [.] cpu_get_tb_cpu_state
   - 6.96% cpu_get_tb_cpu_state
3.63% aa64_va_parameters_both
0.60% fp_exception_el
0.53% sve_exception_el

AFTER:

-   16.40% 3.40%  qemu-system-aar  [.] helper_lookup_tb_ptr
   - 13.03% helper_lookup_tb_ptr
  + 11.19% tb_htable_lookup
0.55% cpu_get_tb_cpu_state

 0.98% 0.71%  qemu-system-aar  [.] cpu_get_tb_cpu_state

 0.87% 0.24%  qemu-system-aar  [.] rebuild_hflags_a64

Before, helper_lookup_tb_ptr is the second hottest function in the
application, consuming almost a quarter of the runtime.  Within the
entire execution, cpu_get_tb_cpu_state consumes about 12%.

After, helper_lookup_tb_ptr has dropped to the fourth hottest function,
with consumption dropping to a sixth of the runtime.  Within the
entire execution, cpu_get_tb_cpu_state has dropped below 1%, and the
supporting function to rebuild hflags also consumes about 1%.

Assertions are retained for --enable-debug-tcg.

Tested-by: Alex Bennée 
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
v2: Retain asserts for future debugging.
---
 target/arm/helper.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index c55783e540..63815fc4cf 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11259,12 +11259,15 @@ void HELPER(rebuild_hflags_a64)(CPUARMState *env, int 
el)
 void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
   target_ulong *cs_base, uint32_t *pflags)
 {
-uint32_t flags, pstate_for_ss;
+uint32_t flags = env->hflags;
+uint32_t pstate_for_ss;
 
 *cs_base = 0;
-flags = rebuild_hflags_internal(env);
+#ifdef CONFIG_DEBUG_TCG
+assert(flags == rebuild_hflags_internal(env));
+#endif
 
-if (is_a64(env)) {
+if (FIELD_EX32(flags, TBFLAG_ANY, AARCH64_STATE)) {
 *pc = env->pc;
 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
 flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
-- 
2.17.1




[PATCH v8 10/22] target/arm: Simplify set of PSTATE_SS in cpu_get_tb_cpu_state

2019-10-18 Thread Richard Henderson
Hoist the variable load for PSTATE into the existing test vs is_a64.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index e2a62cf19a..398e5f5d6d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11197,7 +11197,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 ARMMMUIdx mmu_idx = arm_mmu_idx(env);
 int current_el = arm_current_el(env);
 int fp_el = fp_exception_el(env, current_el);
-uint32_t flags;
+uint32_t flags, pstate_for_ss;
 
 if (is_a64(env)) {
 *pc = env->pc;
@@ -11205,6 +11205,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
 flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
 }
+pstate_for_ss = env->pstate;
 } else {
 *pc = env->regs[15];
 
@@ -11257,9 +11258,11 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
 flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
 }
+pstate_for_ss = env->uncached_cpsr;
 }
 
-/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
+/*
+ * The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
  * states defined in the ARM ARM for software singlestep:
  *  SS_ACTIVE   PSTATE.SS   State
  * 0x   Inactive (the TB flag for SS is always 0)
@@ -11267,16 +11270,9 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
  * 11   Active-not-pending
  * SS_ACTIVE is set in hflags; PSTATE_SS is computed every TB.
  */
-if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE)) {
-if (is_a64(env)) {
-if (env->pstate & PSTATE_SS) {
-flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
-}
-} else {
-if (env->uncached_cpsr & PSTATE_SS) {
-flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
-}
-}
+if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) &&
+(pstate_for_ss & PSTATE_SS)) {
+flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
 }
 
 *pflags = flags;
-- 
2.17.1




[PATCH v8 21/22] target/arm: Rebuild hflags for M-profile NVIC

2019-10-18 Thread Richard Henderson
Continue setting, but not relying upon, env->hflags.

Suggested-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 hw/intc/armv7m_nvic.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 8e93e51e81..e8c74f9eba 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2251,7 +2251,7 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr 
addr,
 }
 }
 nvic_irq_update(s);
-return MEMTX_OK;
+goto exit_ok;
 case 0x200 ... 0x23f: /* NVIC Set pend */
 /* the special logic in armv7m_nvic_set_pending()
  * is not needed since IRQs are never escalated
@@ -2269,9 +2269,9 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr 
addr,
 }
 }
 nvic_irq_update(s);
-return MEMTX_OK;
+goto exit_ok;
 case 0x300 ... 0x33f: /* NVIC Active */
-return MEMTX_OK; /* R/O */
+goto exit_ok; /* R/O */
 case 0x400 ... 0x5ef: /* NVIC Priority */
 startvec = (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
 
@@ -2281,10 +2281,10 @@ static MemTxResult nvic_sysreg_write(void *opaque, 
hwaddr addr,
 }
 }
 nvic_irq_update(s);
-return MEMTX_OK;
+goto exit_ok;
 case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
 if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
-return MEMTX_OK;
+goto exit_ok;
 }
 /* fall through */
 case 0xd1c ... 0xd23: /* System Handler Priority (SHPR2, SHPR3) */
@@ -2299,10 +2299,10 @@ static MemTxResult nvic_sysreg_write(void *opaque, 
hwaddr addr,
 set_prio(s, hdlidx, sbank, newprio);
 }
 nvic_irq_update(s);
-return MEMTX_OK;
+goto exit_ok;
 case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
 if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
-return MEMTX_OK;
+goto exit_ok;
 }
 /* All bits are W1C, so construct 32 bit value with 0s in
  * the parts not written by the access size
@@ -2322,15 +2322,19 @@ static MemTxResult nvic_sysreg_write(void *opaque, 
hwaddr addr,
  */
 s->cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
 }
-return MEMTX_OK;
+goto exit_ok;
 }
 if (size == 4) {
 nvic_writel(s, offset, value, attrs);
-return MEMTX_OK;
+goto exit_ok;
 }
 qemu_log_mask(LOG_GUEST_ERROR,
   "NVIC: Bad write of size %d at offset 0x%x\n", size, offset);
 /* This is UNPREDICTABLE; treat as RAZ/WI */
+
+ exit_ok:
+/* Ensure any changes made are reflected in the cached hflags.  */
+arm_rebuild_hflags(&s->cpu->env);
 return MEMTX_OK;
 }
 
-- 
2.17.1




Re: [PATCH 0/4] target/arm vector improvements

2019-10-18 Thread Alex Bennée


Richard Henderson  writes:

> The first patch has been seen before.
>
>   https://patchwork.ozlabs.org/patch/1115039/
>
> It had a bug and I didn't fix it right away and then forgot.
> Fixed now; I had mixed up the operand ordering for aarch32.
>
> The next 3 are something that I noticed while doing other stuff.
>
> In particular, pmull is used heavily during https transfers.
> While cloning a repository, the old code peaks at 27% of the
> total runtime, as measured by perf top.  The new code does
> not quite reach 3% repeating the same clone.
>
> In addition, the new helper functions are in the form that
> will be required for the implementation of SVE2.
>
> The comment in patch 2 about ARMv8.4-DIT is perhaps a stretch,
> but re-reading the pmull instruction description in the current
> ARM ARM brought it to mind.
>
> Since TCG is officially not in the security domain, it's
> probably not a bug to just claim to support DIT without
> actually doing anything to ensure the algorithms used are in
> fact timing independent of the data.
>
> On the other hand, I expect the bit distribution of stuff
> going through these sort of hashing algorithms to approach
> 50% 1's and 0's, so I also don't think we gain anything on
> average to terminate the loop early.
>
> Thoughts on DIT specifically?

It would be an interesting academic exercise to see if someone could
exploit the JIT from the guest but as you say not a security domain
so

>
>
> r~
>
>
> Richard Henderson (4):
>   target/arm: Vectorize USHL and SSHL
>   target/arm: Convert PMUL.8 to gvec
>   target/arm: Convert PMULL.64 to gvec
>   target/arm: Convert PMULL.8 to gvec
>
>  target/arm/helper-sve.h|   2 +
>  target/arm/helper.h|  21 ++-
>  target/arm/translate.h |   6 +
>  target/arm/neon_helper.c   | 117 -
>  target/arm/translate-a64.c |  83 -
>  target/arm/translate.c | 350 -
>  target/arm/vec_helper.c| 211 ++
>  7 files changed, 562 insertions(+), 228 deletions(-)


--
Alex Bennée



[PATCH v8 17/22] target/arm: Rebuild hflags at MSR writes

2019-10-18 Thread Richard Henderson
Continue setting, but not relying upon, env->hflags.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 13 +++--
 target/arm/translate.c | 28 +++-
 2 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 2d6cd09634..d4bebbe629 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1789,8 +1789,17 @@ static void handle_sys(DisasContext *s, uint32_t insn, 
bool isread,
 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
 /* I/O operations must end the TB here (whether read or write) */
 s->base.is_jmp = DISAS_UPDATE;
-} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
-/* We default to ending the TB on a coprocessor register write,
+}
+if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
+/*
+ * A write to any coprocessor regiser that ends a TB
+ * must rebuild the hflags for the next TB.
+ */
+TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
+gen_helper_rebuild_hflags_a64(cpu_env, tcg_el);
+tcg_temp_free_i32(tcg_el);
+/*
+ * We default to ending the TB on a coprocessor register write,
  * but allow this to be suppressed by the register definition
  * (usually only necessary to work around guest bugs).
  */
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 698c594e8c..cb47cd9744 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -6890,6 +6890,8 @@ static int disas_coproc_insn(DisasContext *s, uint32_t 
insn)
 ri = get_arm_cp_reginfo(s->cp_regs,
 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
 if (ri) {
+bool need_exit_tb;
+
 /* Check access permissions */
 if (!cp_access_ok(s->current_el, ri, isread)) {
 return 1;
@@ -7068,14 +7070,30 @@ static int disas_coproc_insn(DisasContext *s, uint32_t 
insn)
 }
 }
 
-if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) 
{
-/* I/O operations must end the TB here (whether read or write) */
-gen_lookup_tb(s);
-} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
-/* We default to ending the TB on a coprocessor register write,
+/* I/O operations must end the TB here (whether read or write) */
+need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
+(ri->type & ARM_CP_IO));
+
+if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
+/*
+ * A write to any coprocessor regiser that ends a TB
+ * must rebuild the hflags for the next TB.
+ */
+TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
+if (arm_dc_feature(s, ARM_FEATURE_M)) {
+gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
+} else {
+gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
+}
+tcg_temp_free_i32(tcg_el);
+/*
+ * We default to ending the TB on a coprocessor register write,
  * but allow this to be suppressed by the register definition
  * (usually only necessary to work around guest bugs).
  */
+need_exit_tb = true;
+}
+if (need_exit_tb) {
 gen_lookup_tb(s);
 }
 
-- 
2.17.1




Re: [PATCH 05/14] dp8393x: replace PROP_PTR with PROP_LINK

2019-10-18 Thread Peter Maydell
On Fri, 18 Oct 2019 at 16:42, Marc-André Lureau
 wrote:
>
> Signed-off-by: Marc-André Lureau 
> ---
>  hw/mips/mips_jazz.c | 3 ++-
>  hw/net/dp8393x.c| 7 +++
>  2 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
> index 8d010a0b6e..878925a963 100644
> --- a/hw/mips/mips_jazz.c
> +++ b/hw/mips/mips_jazz.c
> @@ -284,7 +284,8 @@ static void mips_jazz_init(MachineState *machine,
>  dev = qdev_create(NULL, "dp8393x");
>  qdev_set_nic_properties(dev, nd);
>  qdev_prop_set_uint8(dev, "it_shift", 2);
> -qdev_prop_set_ptr(dev, "dma_mr", rc4030_dma_mr);
> +object_property_set_link(OBJECT(dev), OBJECT(rc4030_dma_mr),
> + "dma_mr", &error_abort);
>  qdev_init_nofail(dev);
>  sysbus = SYS_BUS_DEVICE(dev);
>  sysbus_mmio_map(sysbus, 0, 0x80001000);
> diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> index a5678e11fa..946c7a8f64 100644
> --- a/hw/net/dp8393x.c
> +++ b/hw/net/dp8393x.c
> @@ -173,7 +173,7 @@ typedef struct dp8393xState {
>  int loopback_packet;
>
>  /* Memory access */
> -void *dma_mr;
> +MemoryRegion *dma_mr;
>  AddressSpace as;
>  } dp8393xState;
>
> @@ -922,7 +922,8 @@ static const VMStateDescription vmstate_dp8393x = {
>
>  static Property dp8393x_properties[] = {
>  DEFINE_NIC_PROPERTIES(dp8393xState, conf),
> -DEFINE_PROP_PTR("dma_mr", dp8393xState, dma_mr),
> +DEFINE_PROP_LINK("dma_mr", dp8393xState, dma_mr,
> + TYPE_MEMORY_REGION, MemoryRegion *),
>  DEFINE_PROP_UINT8("it_shift", dp8393xState, it_shift, 0),
>  DEFINE_PROP_END_OF_LIST(),
>  };

Link property is the correct way to pass a MemoryRegion to
a device for DMA purposes, so this is a good cleanup.

> @@ -936,8 +937,6 @@ static void dp8393x_class_init(ObjectClass *klass, void 
> *data)
>  dc->reset = dp8393x_reset;
>  dc->vmsd = &vmstate_dp8393x;
>  dc->props = dp8393x_properties;
> -/* Reason: dma_mr property can't be set */
> -dc->user_creatable = false;
>  }

Sidenote: as a sysbus device, this remains non-usercreatable
even though we can drop the specific flag here.


Reviewed-by: Peter Maydell 

thanks
-- PMM



[PATCH v8 19/22] target/arm: Rebuild hflags at Xscale SCTLR writes

2019-10-18 Thread Richard Henderson
Continue setting, but not relying upon, env->hflags.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index aae7b62458..c55783e540 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4174,6 +4174,16 @@ static void sctlr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 /* ??? Lots of these bits are not implemented.  */
 /* This may enable/disable the MMU, so do a TLB flush.  */
 tlb_flush(CPU(cpu));
+
+if (ri->type & ARM_CP_SUPPRESS_TB_END) {
+/*
+ * Normally we would always end the TB on an SCTLR write; see the
+ * comment in ARMCPRegInfo sctlr initialization below for why Xscale
+ * is special.  Setting ARM_CP_SUPPRESS_TB_END also stops the rebuild
+ * of hflags from the translator, so do it here.
+ */
+arm_rebuild_hflags(env);
+}
 }
 
 static CPAccessResult fpexc32_access(CPUARMState *env, const ARMCPRegInfo *ri,
-- 
2.17.1




[PATCH v8 08/22] target/arm: Split out rebuild_hflags_aprofile

2019-10-18 Thread Richard Henderson
Create a function to compute the values of the TBFLAG_ANY bits
that will be cached, and are used by A-profile.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index d1cd54cc93..ddd21edfcf 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11106,18 +11106,28 @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, 
int fp_el,
 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
 }
 
+static uint32_t rebuild_hflags_aprofile(CPUARMState *env)
+{
+int flags = 0;
+
+flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL,
+   arm_debug_target_el(env));
+return flags;
+}
+
 static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
ARMMMUIdx mmu_idx)
 {
-return rebuild_hflags_common_32(env, fp_el, mmu_idx, 0);
+uint32_t flags = rebuild_hflags_aprofile(env);
+return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
 }
 
 static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
ARMMMUIdx mmu_idx)
 {
+uint32_t flags = rebuild_hflags_aprofile(env);
 ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
 ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
-uint32_t flags = 0;
 uint64_t sctlr;
 int tbii, tbid;
 
@@ -11262,12 +11272,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
 }
 }
 
-if (!arm_feature(env, ARM_FEATURE_M)) {
-int target_el = arm_debug_target_el(env);
-
-flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL, target_el);
-}
-
 *pflags = flags;
 *cs_base = 0;
 }
-- 
2.17.1




[PATCH v8 18/22] target/arm: Rebuild hflags at CPSR writes

2019-10-18 Thread Richard Henderson
Continue setting, but not relying upon, env->hflags.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/op_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index ccc2cecb46..b529d6c1bf 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -224,6 +224,7 @@ uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, 
uint32_t shift)
 void HELPER(setend)(CPUARMState *env)
 {
 env->uncached_cpsr ^= CPSR_E;
+arm_rebuild_hflags(env);
 }
 
 /* Function checks whether WFx (WFI/WFE) instructions are set up to be trapped.
@@ -387,6 +388,8 @@ uint32_t HELPER(cpsr_read)(CPUARMState *env)
 void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
 {
 cpsr_write(env, val, mask, CPSRWriteByInstr);
+/* TODO: Not all cpsr bits are relevant to hflags.  */
+arm_rebuild_hflags(env);
 }
 
 /* Write the CPSR for a 32-bit exception return */
-- 
2.17.1




[PATCH v8 04/22] target/arm: Split arm_cpu_data_is_big_endian

2019-10-18 Thread Richard Henderson
Set TBFLAG_ANY.BE_DATA in rebuild_hflags_common_32 and
rebuild_hflags_a64 instead of rebuild_hflags_common, where we do
not need to re-test is_a64() nor re-compute the various inputs.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h| 49 +++--
 target/arm/helper.c | 16 +++
 2 files changed, 42 insertions(+), 23 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ad79a6153b..4d961474ce 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3108,33 +3108,44 @@ static inline uint64_t arm_sctlr(CPUARMState *env, int 
el)
 }
 }
 
+static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env,
+  bool sctlr_b)
+{
+#ifdef CONFIG_USER_ONLY
+/*
+ * In system mode, BE32 is modelled in line with the
+ * architecture (as word-invariant big-endianness), where loads
+ * and stores are done little endian but from addresses which
+ * are adjusted by XORing with the appropriate constant. So the
+ * endianness to use for the raw data access is not affected by
+ * SCTLR.B.
+ * In user mode, however, we model BE32 as byte-invariant
+ * big-endianness (because user-only code cannot tell the
+ * difference), and so we need to use a data access endianness
+ * that depends on SCTLR.B.
+ */
+if (sctlr_b) {
+return true;
+}
+#endif
+/* In 32bit endianness is determined by looking at CPSR's E bit */
+return env->uncached_cpsr & CPSR_E;
+}
+
+static inline bool arm_cpu_data_is_big_endian_a64(int el, uint64_t sctlr)
+{
+return sctlr & (el ? SCTLR_EE : SCTLR_E0E);
+}
 
 /* Return true if the processor is in big-endian mode. */
 static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
 {
-/* In 32bit endianness is determined by looking at CPSR's E bit */
 if (!is_a64(env)) {
-return
-#ifdef CONFIG_USER_ONLY
-/* In system mode, BE32 is modelled in line with the
- * architecture (as word-invariant big-endianness), where loads
- * and stores are done little endian but from addresses which
- * are adjusted by XORing with the appropriate constant. So the
- * endianness to use for the raw data access is not affected by
- * SCTLR.B.
- * In user mode, however, we model BE32 as byte-invariant
- * big-endianness (because user-only code cannot tell the
- * difference), and so we need to use a data access endianness
- * that depends on SCTLR.B.
- */
-arm_sctlr_b(env) ||
-#endif
-((env->uncached_cpsr & CPSR_E) ? 1 : 0);
+return arm_cpu_data_is_big_endian_a32(env, arm_sctlr_b(env));
 } else {
 int cur_el = arm_current_el(env);
 uint64_t sctlr = arm_sctlr(env, cur_el);
-
-return (sctlr & (cur_el ? SCTLR_EE : SCTLR_E0E)) != 0;
+return arm_cpu_data_is_big_endian_a64(cur_el, sctlr);
 }
 }
 
diff --git a/target/arm/helper.c b/target/arm/helper.c
index f05d042474..4c65476d93 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11061,9 +11061,6 @@ static uint32_t rebuild_hflags_common(CPUARMState *env, 
int fp_el,
 flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX,
arm_to_core_mmu_idx(mmu_idx));
 
-if (arm_cpu_data_is_big_endian(env)) {
-flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
-}
 if (arm_singlestep_active(env)) {
 flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
 }
@@ -11073,7 +11070,14 @@ static uint32_t rebuild_hflags_common(CPUARMState 
*env, int fp_el,
 static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
  ARMMMUIdx mmu_idx, uint32_t flags)
 {
-flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
+bool sctlr_b = arm_sctlr_b(env);
+
+if (sctlr_b) {
+flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, 1);
+}
+if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
+flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
+}
 flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
 
 return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
@@ -11122,6 +11126,10 @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, 
int el, int fp_el,
 
 sctlr = arm_sctlr(env, el);
 
+if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
+flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
+}
+
 if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
 /*
  * In order to save space in flags, we record only whether
-- 
2.17.1




  1   2   3   4   5   >