[PATCH resend v11 3/4] tests/qtest: Introduce tests for Xilinx ZynqMP CAN controller

2020-10-13 Thread Vikram Garhwal
The QTests perform five tests on the Xilinx ZynqMP CAN controller:
Tests the CAN controller in loopback, sleep and snoop mode.
Tests filtering of incoming CAN messages.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Francisco Iglesias 
Signed-off-by: Vikram Garhwal 
---
 tests/qtest/xlnx-can-test.c | 360 
 tests/qtest/meson.build |   1 +
 2 files changed, 361 insertions(+)
 create mode 100644 tests/qtest/xlnx-can-test.c

diff --git a/tests/qtest/xlnx-can-test.c b/tests/qtest/xlnx-can-test.c
new file mode 100644
index 000..3d11200
--- /dev/null
+++ b/tests/qtest/xlnx-can-test.c
@@ -0,0 +1,360 @@
+/*
+ * QTests for the Xilinx ZynqMP CAN controller.
+ *
+ * Copyright (c) 2020 Xilinx Inc.
+ *
+ * Written-by: Vikram Garhwal
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "libqos/libqtest.h"
+
+/* Base address. */
+#define CAN0_BASE_ADDR  0xFF06
+#define CAN1_BASE_ADDR  0xFF07
+
+/* Register addresses. */
+#define R_SRR_OFFSET0x00
+#define R_MSR_OFFSET0x04
+#define R_SR_OFFSET 0x18
+#define R_ISR_OFFSET0x1C
+#define R_ICR_OFFSET0x24
+#define R_TXID_OFFSET   0x30
+#define R_TXDLC_OFFSET  0x34
+#define R_TXDATA1_OFFSET0x38
+#define R_TXDATA2_OFFSET0x3C
+#define R_RXID_OFFSET   0x50
+#define R_RXDLC_OFFSET  0x54
+#define R_RXDATA1_OFFSET0x58
+#define R_RXDATA2_OFFSET0x5C
+#define R_AFR   0x60
+#define R_AFMR1 0x64
+#define R_AFIR1 0x68
+#define R_AFMR2 0x6C
+#define R_AFIR2 0x70
+#define R_AFMR3 0x74
+#define R_AFIR3 0x78
+#define R_AFMR4 0x7C
+#define R_AFIR4 0x80
+
+/* CAN modes. */
+#define CONFIG_MODE 0x00
+#define NORMAL_MODE 0x00
+#define LOOPBACK_MODE   0x02
+#define SNOOP_MODE  0x04
+#define SLEEP_MODE  0x01
+#define ENABLE_CAN  (1 << 1)
+#define STATUS_NORMAL_MODE  (1 << 3)
+#define STATUS_LOOPBACK_MODE(1 << 1)
+#define STATUS_SNOOP_MODE   (1 << 12)
+#define STATUS_SLEEP_MODE   (1 << 2)
+#define ISR_TXOK(1 << 1)
+#define ISR_RXOK(1 << 4)
+
+static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx,
+ uint8_t can_timestamp)
+{
+uint16_t size = 0;
+uint8_t len = 4;
+
+while (size < len) {
+if (R_RXID_OFFSET + 4 * size == R_RXDLC_OFFSET)  {
+g_assert_cmpint(buf_rx[size], ==, buf_tx[size] + can_timestamp);
+} else {
+g_assert_cmpint(buf_rx[size], ==, buf_tx[size]);
+}
+
+size++;
+}
+}
+
+static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t 
*buf_rx)
+{
+uint32_t int_status;
+
+/* Read the interrupt on CAN rx. */
+int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK;
+
+g_assert_cmpint(int_status, ==, ISR_RXOK);
+
+/* Read the RX register data for CAN. */
+buf_rx[0] = qtest_readl(qts, can_base_addr + R_RXID_OFFSET);
+buf_rx[1] = qtest_readl(qts, can_base_addr + R_RXDLC_OFFSET);
+buf_rx[2] = qtest_readl(qts, can_base_addr + R_RXDATA1_OFFSET);
+buf_rx[3] = qtest_readl(qts, can_base_addr + R_RXDATA2_OFFSET);
+
+/* Clear the RX interrupt. */
+qtest_writel(qts, CAN1_BASE_ADDR + R_ICR_OFFSET, ISR_RXOK);
+}
+
+static void send_data(QTestState *qts, uint64_t can_base_addr,
+  const uint32_t *buf_tx)
+{
+uint32_t int_status;
+
+/* Write the TX register data for CAN. */
+qtest_writel(qts, can_base_addr + R_TXID_OFFSET, buf_tx[0]);
+qtest_writel(qts, can_base_addr + R_TXDLC_OFFSET, buf_tx[1]);
+qtest_writel(qts, can_base_addr + R_TXDATA1_OFFSET, 

[PATCH resend v11 0/4] Introduce Xilinx ZynqMP CAN controller

2020-10-13 Thread Vikram Garhwal
Changelog:

v10 -> v11:
Resending the series with correct cc.
Replace DB_PRINTS with trace-events.
Removed unnecessary local variables.
Added const with tx/rx buffers in qtest.
Added reviewed-by tags for qtest.

v9 -> v10:
Rebase the series with the new meson build system.

v8 -> v9:
Use g_autofree to do automatic cleanup the object_get_canonical_path() used.

v7 -> v8:
Change CAN controller to keep one canbus per controller.
Add canbus connections at machine level.
Remove ctrl_idx from CAN controller.

v6 -> v7:
Remove '-m 4G' option from xlnx-can-test. This option causes the fail of
docker-quick@centos7 build test.

v5 -> v6:
Add ptimer based counter for time stamping on RX messages.
Fix reset issues.
Rebase the patches with master latest changes.
Added reference clock property for CAN ptimer.

v4 -> v5:
Add XlnxZynqMPCAN controller id to debug messages.
Drop parameter errp of object_property_add().
Add formatting related suggestions.

v3 -> v4:
Correct formatting issues.

v2 -> v3:
Rectify the build issue.
Rearrange the patch order.

v1 -> v2:
Rename the CAN device state and address code style issues.
Connect the CAN device to Xlnx-ZCU102 board.
Add maintainer entry.
Add QTEST for the CAN device.


Vikram Garhwal (4):
  hw/net/can: Introduce Xilinx ZynqMP CAN controller
  xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers
  tests/qtest: Introduce tests for Xilinx ZynqMP CAN controller
  MAINTAINERS: Add maintainer entry for Xilinx ZynqMP CAN controller

 meson.build  |1 +
 hw/net/can/trace.h   |1 +
 include/hw/arm/xlnx-zynqmp.h |8 +
 include/hw/net/xlnx-zynqmp-can.h |   78 +++
 hw/arm/xlnx-zcu102.c |   20 +
 hw/arm/xlnx-zynqmp.c |   34 ++
 hw/net/can/xlnx-zynqmp-can.c | 1159 ++
 tests/qtest/xlnx-can-test.c  |  360 
 MAINTAINERS  |8 +
 hw/Kconfig   |1 +
 hw/net/can/meson.build   |1 +
 hw/net/can/trace-events  |9 +
 tests/qtest/meson.build  |1 +
 13 files changed, 1681 insertions(+)
 create mode 100644 hw/net/can/trace.h
 create mode 100644 include/hw/net/xlnx-zynqmp-can.h
 create mode 100644 hw/net/can/xlnx-zynqmp-can.c
 create mode 100644 tests/qtest/xlnx-can-test.c
 create mode 100644 hw/net/can/trace-events

--
2.7.4




[PATCH resend v11 2/4] xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers

2020-10-13 Thread Vikram Garhwal
Connect CAN0 and CAN1 on the ZynqMP.

Reviewed-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
Signed-off-by: Vikram Garhwal 
---
 include/hw/arm/xlnx-zynqmp.h |  8 
 hw/arm/xlnx-zcu102.c | 20 
 hw/arm/xlnx-zynqmp.c | 34 ++
 3 files changed, 62 insertions(+)

diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index 567d0db..6f45387 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -22,6 +22,7 @@
 #include "hw/intc/arm_gic.h"
 #include "hw/net/cadence_gem.h"
 #include "hw/char/cadence_uart.h"
+#include "hw/net/xlnx-zynqmp-can.h"
 #include "hw/ide/ahci.h"
 #include "hw/sd/sdhci.h"
 #include "hw/ssi/xilinx_spips.h"
@@ -33,6 +34,7 @@
 #include "hw/cpu/cluster.h"
 #include "target/arm/cpu.h"
 #include "qom/object.h"
+#include "net/can_emu.h"
 
 #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
 OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
@@ -41,6 +43,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
 #define XLNX_ZYNQMP_NUM_RPU_CPUS 2
 #define XLNX_ZYNQMP_NUM_GEMS 4
 #define XLNX_ZYNQMP_NUM_UARTS 2
+#define XLNX_ZYNQMP_NUM_CAN 2
+#define XLNX_ZYNQMP_CAN_REF_CLK (24 * 1000 * 1000)
 #define XLNX_ZYNQMP_NUM_SDHCI 2
 #define XLNX_ZYNQMP_NUM_SPIS 2
 #define XLNX_ZYNQMP_NUM_GDMA_CH 8
@@ -92,6 +96,7 @@ struct XlnxZynqMPState {
 
 CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS];
 CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS];
+XlnxZynqMPCANState can[XLNX_ZYNQMP_NUM_CAN];
 SysbusAHCIState sata;
 SDHCIState sdhci[XLNX_ZYNQMP_NUM_SDHCI];
 XilinxSPIPS spi[XLNX_ZYNQMP_NUM_SPIS];
@@ -112,6 +117,9 @@ struct XlnxZynqMPState {
 bool virt;
 /* Has the RPU subsystem?  */
 bool has_rpu;
+
+/* CAN bus. */
+CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
 };
 
 #endif
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
index ad7fff9..4ef0c51 100644
--- a/hw/arm/xlnx-zcu102.c
+++ b/hw/arm/xlnx-zcu102.c
@@ -25,6 +25,7 @@
 #include "sysemu/qtest.h"
 #include "sysemu/device_tree.h"
 #include "qom/object.h"
+#include "net/can_emu.h"
 
 struct XlnxZCU102 {
 MachineState parent_obj;
@@ -34,6 +35,8 @@ struct XlnxZCU102 {
 bool secure;
 bool virt;
 
+CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
+
 struct arm_boot_info binfo;
 };
 
@@ -125,6 +128,14 @@ static void xlnx_zcu102_init(MachineState *machine)
 object_property_set_bool(OBJECT(>soc), "virtualization", s->virt,
  _fatal);
 
+for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+gchar *bus_name = g_strdup_printf("canbus%d", i);
+
+object_property_set_link(OBJECT(>soc), bus_name,
+ OBJECT(s->canbus[i]), _fatal);
+g_free(bus_name);
+}
+
 qdev_realize(DEVICE(>soc), NULL, _fatal);
 
 /* Create and plug in the SD cards */
@@ -208,6 +219,15 @@ static void xlnx_zcu102_machine_instance_init(Object *obj)
 s->secure = false;
 /* Default to virt (EL2) being disabled */
 s->virt = false;
+object_property_add_link(obj, "xlnx-zcu102.canbus0", TYPE_CAN_BUS,
+ (Object **)>canbus[0],
+ object_property_allow_set_link,
+ 0);
+
+object_property_add_link(obj, "xlnx-zcu102.canbus1", TYPE_CAN_BUS,
+ (Object **)>canbus[1],
+ object_property_allow_set_link,
+ 0);
 }
 
 static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 7885bb1..8818472 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -81,6 +81,14 @@ static const int uart_intr[XLNX_ZYNQMP_NUM_UARTS] = {
 21, 22,
 };
 
+static const uint64_t can_addr[XLNX_ZYNQMP_NUM_CAN] = {
+0xFF06, 0xFF07,
+};
+
+static const int can_intr[XLNX_ZYNQMP_NUM_CAN] = {
+23, 24,
+};
+
 static const uint64_t sdhci_addr[XLNX_ZYNQMP_NUM_SDHCI] = {
 0xFF16, 0xFF17,
 };
@@ -243,6 +251,11 @@ static void xlnx_zynqmp_init(Object *obj)
 TYPE_CADENCE_UART);
 }
 
+for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+object_initialize_child(obj, "can[*]", >can[i],
+TYPE_XLNX_ZYNQMP_CAN);
+}
+
 object_initialize_child(obj, "sata", >sata, TYPE_SYSBUS_AHCI);
 
 for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
@@ -482,6 +495,23 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
**errp)
gic_spi[uart_intr[i]]);
 }
 
+for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+object_property_set_int(OBJECT(>can[i]), "ext_clk_freq",
+XLNX_ZYNQMP_CAN_REF_CLK, _abort);
+
+object_property_set_link(OBJECT(>can[i]), "canbus",
+ OBJECT(s->canbus[i]), _fatal);
+
+sysbus_realize(SYS_BUS_DEVICE(>can[i]), );
+  

[PATCH resend v11 1/4] hw/net/can: Introduce Xilinx ZynqMP CAN controller

2020-10-13 Thread Vikram Garhwal
The Xilinx ZynqMP CAN controller is developed based on SocketCAN, QEMU CAN bus
implementation. Bus connection and socketCAN connection for each CAN module
can be set through command lines.

Example for using single CAN:
-object can-bus,id=canbus0 \
-machine xlnx-zcu102.canbus0=canbus0 \
-object can-host-socketcan,id=socketcan0,if=vcan0,canbus=canbus0

Example for connecting both CAN to same virtual CAN on host machine:
-object can-bus,id=canbus0 -object can-bus,id=canbus1 \
-machine xlnx-zcu102.canbus0=canbus0 \
-machine xlnx-zcu102.canbus1=canbus1 \
-object can-host-socketcan,id=socketcan0,if=vcan0,canbus=canbus0 \
-object can-host-socketcan,id=socketcan1,if=vcan0,canbus=canbus1

To create virtual CAN on the host machine, please check the QEMU CAN docs:
https://github.com/qemu/qemu/blob/master/docs/can.txt

Signed-off-by: Vikram Garhwal 
---
 meson.build  |1 +
 hw/net/can/trace.h   |1 +
 include/hw/net/xlnx-zynqmp-can.h |   78 +++
 hw/net/can/xlnx-zynqmp-can.c | 1159 ++
 hw/Kconfig   |1 +
 hw/net/can/meson.build   |1 +
 hw/net/can/trace-events  |9 +
 7 files changed, 1250 insertions(+)
 create mode 100644 hw/net/can/trace.h
 create mode 100644 include/hw/net/xlnx-zynqmp-can.h
 create mode 100644 hw/net/can/xlnx-zynqmp-can.c
 create mode 100644 hw/net/can/trace-events

diff --git a/meson.build b/meson.build
index ad6c7c9..13b9dbb 100644
--- a/meson.build
+++ b/meson.build
@@ -1274,6 +1274,7 @@ if have_system
 'hw/misc',
 'hw/misc/macio',
 'hw/net',
+'hw/net/can',
 'hw/nvram',
 'hw/pci',
 'hw/pci-host',
diff --git a/hw/net/can/trace.h b/hw/net/can/trace.h
new file mode 100644
index 000..d391c64
--- /dev/null
+++ b/hw/net/can/trace.h
@@ -0,0 +1 @@
+#include "trace/trace-hw_net_can.h"
diff --git a/include/hw/net/xlnx-zynqmp-can.h b/include/hw/net/xlnx-zynqmp-can.h
new file mode 100644
index 000..eb15587
--- /dev/null
+++ b/include/hw/net/xlnx-zynqmp-can.h
@@ -0,0 +1,78 @@
+/*
+ * QEMU model of the Xilinx ZynqMP CAN controller.
+ *
+ * Copyright (c) 2020 Xilinx Inc.
+ *
+ * Written-by: Vikram Garhwal
+ *
+ * Based on QEMU CAN Device emulation implemented by Jin Yang, Deniz Eren and
+ * Pavel Pisa.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef XLNX_ZYNQMP_CAN_H
+#define XLNX_ZYNQMP_CAN_H
+
+#include "hw/register.h"
+#include "net/can_emu.h"
+#include "net/can_host.h"
+#include "qemu/fifo32.h"
+#include "hw/ptimer.h"
+#include "hw/qdev-clock.h"
+
+#define TYPE_XLNX_ZYNQMP_CAN "xlnx.zynqmp-can"
+
+#define XLNX_ZYNQMP_CAN(obj) \
+ OBJECT_CHECK(XlnxZynqMPCANState, (obj), TYPE_XLNX_ZYNQMP_CAN)
+
+#define MAX_CAN_CTRLS  2
+#define XLNX_ZYNQMP_CAN_R_MAX (0x84 / 4)
+#define MAILBOX_CAPACITY   64
+#define CAN_TIMER_MAX  0XUL
+#define CAN_DEFAULT_CLOCK (24 * 1000 * 1000)
+
+/* Each CAN_FRAME will have 4 * 32bit size. */
+#define CAN_FRAME_SIZE 4
+#define RXFIFO_SIZE(MAILBOX_CAPACITY * CAN_FRAME_SIZE)
+
+typedef struct XlnxZynqMPCANState {
+SysBusDeviceparent_obj;
+MemoryRegioniomem;
+
+qemu_irqirq;
+
+CanBusClientState   bus_client;
+CanBusState *canbus;
+
+struct {
+uint32_text_clk_freq;
+} cfg;
+
+RegisterInforeg_info[XLNX_ZYNQMP_CAN_R_MAX];
+uint32_tregs[XLNX_ZYNQMP_CAN_R_MAX];
+
+Fifo32  rx_fifo;
+Fifo32  tx_fifo;
+Fifo32  txhpb_fifo;
+
+ptimer_state*can_timer;
+} XlnxZynqMPCANState;
+
+#endif
diff --git a/hw/net/can/xlnx-zynqmp-can.c b/hw/net/can/xlnx-zynqmp-can.c
new file mode 100644
index 000..41bc40a
--- /dev/null
+++ b/hw/net/can/xlnx-zynqmp-can.c
@@ -0,0 +1,1159 @@
+/*
+ * QEMU model of the Xilinx ZynqMP CAN controller.
+ * This implementation is based on the following 

[PATCH resend v11 4/4] MAINTAINERS: Add maintainer entry for Xilinx ZynqMP CAN controller

2020-10-13 Thread Vikram Garhwal
Reviewed-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
Signed-off-by: Vikram Garhwal 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 47dd38a..a8c672c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1559,6 +1559,14 @@ F: hw/net/opencores_eth.c
 
 Devices
 ---
+Xilinx CAN
+M: Vikram Garhwal 
+M: Francisco Iglesias 
+S: Maintained
+F: hw/net/can/xlnx-*
+F: include/hw/net/xlnx-*
+F: tests/qtest/xlnx-can-test*
+
 EDU
 M: Jiri Slaby 
 S: Maintained
-- 
2.7.4




[PATCH resend v11 4/4] MAINTAINERS: Add maintainer entry for Xilinx ZynqMP CAN controller

2020-10-13 Thread Vikram Garhwal
Reviewed-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
Signed-off-by: Vikram Garhwal 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 47dd38a..a8c672c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1559,6 +1559,14 @@ F: hw/net/opencores_eth.c
 
 Devices
 ---
+Xilinx CAN
+M: Vikram Garhwal 
+M: Francisco Iglesias 
+S: Maintained
+F: hw/net/can/xlnx-*
+F: include/hw/net/xlnx-*
+F: tests/qtest/xlnx-can-test*
+
 EDU
 M: Jiri Slaby 
 S: Maintained
-- 
2.7.4




[PATCH resend v11 2/4] xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers

2020-10-13 Thread Vikram Garhwal
Connect CAN0 and CAN1 on the ZynqMP.

Reviewed-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
Signed-off-by: Vikram Garhwal 
---
 include/hw/arm/xlnx-zynqmp.h |  8 
 hw/arm/xlnx-zcu102.c | 20 
 hw/arm/xlnx-zynqmp.c | 34 ++
 3 files changed, 62 insertions(+)

diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index 567d0db..6f45387 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -22,6 +22,7 @@
 #include "hw/intc/arm_gic.h"
 #include "hw/net/cadence_gem.h"
 #include "hw/char/cadence_uart.h"
+#include "hw/net/xlnx-zynqmp-can.h"
 #include "hw/ide/ahci.h"
 #include "hw/sd/sdhci.h"
 #include "hw/ssi/xilinx_spips.h"
@@ -33,6 +34,7 @@
 #include "hw/cpu/cluster.h"
 #include "target/arm/cpu.h"
 #include "qom/object.h"
+#include "net/can_emu.h"
 
 #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
 OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
@@ -41,6 +43,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
 #define XLNX_ZYNQMP_NUM_RPU_CPUS 2
 #define XLNX_ZYNQMP_NUM_GEMS 4
 #define XLNX_ZYNQMP_NUM_UARTS 2
+#define XLNX_ZYNQMP_NUM_CAN 2
+#define XLNX_ZYNQMP_CAN_REF_CLK (24 * 1000 * 1000)
 #define XLNX_ZYNQMP_NUM_SDHCI 2
 #define XLNX_ZYNQMP_NUM_SPIS 2
 #define XLNX_ZYNQMP_NUM_GDMA_CH 8
@@ -92,6 +96,7 @@ struct XlnxZynqMPState {
 
 CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS];
 CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS];
+XlnxZynqMPCANState can[XLNX_ZYNQMP_NUM_CAN];
 SysbusAHCIState sata;
 SDHCIState sdhci[XLNX_ZYNQMP_NUM_SDHCI];
 XilinxSPIPS spi[XLNX_ZYNQMP_NUM_SPIS];
@@ -112,6 +117,9 @@ struct XlnxZynqMPState {
 bool virt;
 /* Has the RPU subsystem?  */
 bool has_rpu;
+
+/* CAN bus. */
+CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
 };
 
 #endif
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
index ad7fff9..4ef0c51 100644
--- a/hw/arm/xlnx-zcu102.c
+++ b/hw/arm/xlnx-zcu102.c
@@ -25,6 +25,7 @@
 #include "sysemu/qtest.h"
 #include "sysemu/device_tree.h"
 #include "qom/object.h"
+#include "net/can_emu.h"
 
 struct XlnxZCU102 {
 MachineState parent_obj;
@@ -34,6 +35,8 @@ struct XlnxZCU102 {
 bool secure;
 bool virt;
 
+CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
+
 struct arm_boot_info binfo;
 };
 
@@ -125,6 +128,14 @@ static void xlnx_zcu102_init(MachineState *machine)
 object_property_set_bool(OBJECT(>soc), "virtualization", s->virt,
  _fatal);
 
+for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+gchar *bus_name = g_strdup_printf("canbus%d", i);
+
+object_property_set_link(OBJECT(>soc), bus_name,
+ OBJECT(s->canbus[i]), _fatal);
+g_free(bus_name);
+}
+
 qdev_realize(DEVICE(>soc), NULL, _fatal);
 
 /* Create and plug in the SD cards */
@@ -208,6 +219,15 @@ static void xlnx_zcu102_machine_instance_init(Object *obj)
 s->secure = false;
 /* Default to virt (EL2) being disabled */
 s->virt = false;
+object_property_add_link(obj, "xlnx-zcu102.canbus0", TYPE_CAN_BUS,
+ (Object **)>canbus[0],
+ object_property_allow_set_link,
+ 0);
+
+object_property_add_link(obj, "xlnx-zcu102.canbus1", TYPE_CAN_BUS,
+ (Object **)>canbus[1],
+ object_property_allow_set_link,
+ 0);
 }
 
 static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 7885bb1..8818472 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -81,6 +81,14 @@ static const int uart_intr[XLNX_ZYNQMP_NUM_UARTS] = {
 21, 22,
 };
 
+static const uint64_t can_addr[XLNX_ZYNQMP_NUM_CAN] = {
+0xFF06, 0xFF07,
+};
+
+static const int can_intr[XLNX_ZYNQMP_NUM_CAN] = {
+23, 24,
+};
+
 static const uint64_t sdhci_addr[XLNX_ZYNQMP_NUM_SDHCI] = {
 0xFF16, 0xFF17,
 };
@@ -243,6 +251,11 @@ static void xlnx_zynqmp_init(Object *obj)
 TYPE_CADENCE_UART);
 }
 
+for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+object_initialize_child(obj, "can[*]", >can[i],
+TYPE_XLNX_ZYNQMP_CAN);
+}
+
 object_initialize_child(obj, "sata", >sata, TYPE_SYSBUS_AHCI);
 
 for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
@@ -482,6 +495,23 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
**errp)
gic_spi[uart_intr[i]]);
 }
 
+for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+object_property_set_int(OBJECT(>can[i]), "ext_clk_freq",
+XLNX_ZYNQMP_CAN_REF_CLK, _abort);
+
+object_property_set_link(OBJECT(>can[i]), "canbus",
+ OBJECT(s->canbus[i]), _fatal);
+
+sysbus_realize(SYS_BUS_DEVICE(>can[i]), );
+  

[PATCH resend v11 3/4] tests/qtest: Introduce tests for Xilinx ZynqMP CAN controller

2020-10-13 Thread Vikram Garhwal
The QTests perform five tests on the Xilinx ZynqMP CAN controller:
Tests the CAN controller in loopback, sleep and snoop mode.
Tests filtering of incoming CAN messages.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Francisco Iglesias 
Signed-off-by: Vikram Garhwal 
---
 tests/qtest/xlnx-can-test.c | 360 
 tests/qtest/meson.build |   1 +
 2 files changed, 361 insertions(+)
 create mode 100644 tests/qtest/xlnx-can-test.c

diff --git a/tests/qtest/xlnx-can-test.c b/tests/qtest/xlnx-can-test.c
new file mode 100644
index 000..3d11200
--- /dev/null
+++ b/tests/qtest/xlnx-can-test.c
@@ -0,0 +1,360 @@
+/*
+ * QTests for the Xilinx ZynqMP CAN controller.
+ *
+ * Copyright (c) 2020 Xilinx Inc.
+ *
+ * Written-by: Vikram Garhwal
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "libqos/libqtest.h"
+
+/* Base address. */
+#define CAN0_BASE_ADDR  0xFF06
+#define CAN1_BASE_ADDR  0xFF07
+
+/* Register addresses. */
+#define R_SRR_OFFSET0x00
+#define R_MSR_OFFSET0x04
+#define R_SR_OFFSET 0x18
+#define R_ISR_OFFSET0x1C
+#define R_ICR_OFFSET0x24
+#define R_TXID_OFFSET   0x30
+#define R_TXDLC_OFFSET  0x34
+#define R_TXDATA1_OFFSET0x38
+#define R_TXDATA2_OFFSET0x3C
+#define R_RXID_OFFSET   0x50
+#define R_RXDLC_OFFSET  0x54
+#define R_RXDATA1_OFFSET0x58
+#define R_RXDATA2_OFFSET0x5C
+#define R_AFR   0x60
+#define R_AFMR1 0x64
+#define R_AFIR1 0x68
+#define R_AFMR2 0x6C
+#define R_AFIR2 0x70
+#define R_AFMR3 0x74
+#define R_AFIR3 0x78
+#define R_AFMR4 0x7C
+#define R_AFIR4 0x80
+
+/* CAN modes. */
+#define CONFIG_MODE 0x00
+#define NORMAL_MODE 0x00
+#define LOOPBACK_MODE   0x02
+#define SNOOP_MODE  0x04
+#define SLEEP_MODE  0x01
+#define ENABLE_CAN  (1 << 1)
+#define STATUS_NORMAL_MODE  (1 << 3)
+#define STATUS_LOOPBACK_MODE(1 << 1)
+#define STATUS_SNOOP_MODE   (1 << 12)
+#define STATUS_SLEEP_MODE   (1 << 2)
+#define ISR_TXOK(1 << 1)
+#define ISR_RXOK(1 << 4)
+
+static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx,
+ uint8_t can_timestamp)
+{
+uint16_t size = 0;
+uint8_t len = 4;
+
+while (size < len) {
+if (R_RXID_OFFSET + 4 * size == R_RXDLC_OFFSET)  {
+g_assert_cmpint(buf_rx[size], ==, buf_tx[size] + can_timestamp);
+} else {
+g_assert_cmpint(buf_rx[size], ==, buf_tx[size]);
+}
+
+size++;
+}
+}
+
+static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t 
*buf_rx)
+{
+uint32_t int_status;
+
+/* Read the interrupt on CAN rx. */
+int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK;
+
+g_assert_cmpint(int_status, ==, ISR_RXOK);
+
+/* Read the RX register data for CAN. */
+buf_rx[0] = qtest_readl(qts, can_base_addr + R_RXID_OFFSET);
+buf_rx[1] = qtest_readl(qts, can_base_addr + R_RXDLC_OFFSET);
+buf_rx[2] = qtest_readl(qts, can_base_addr + R_RXDATA1_OFFSET);
+buf_rx[3] = qtest_readl(qts, can_base_addr + R_RXDATA2_OFFSET);
+
+/* Clear the RX interrupt. */
+qtest_writel(qts, CAN1_BASE_ADDR + R_ICR_OFFSET, ISR_RXOK);
+}
+
+static void send_data(QTestState *qts, uint64_t can_base_addr,
+  const uint32_t *buf_tx)
+{
+uint32_t int_status;
+
+/* Write the TX register data for CAN. */
+qtest_writel(qts, can_base_addr + R_TXID_OFFSET, buf_tx[0]);
+qtest_writel(qts, can_base_addr + R_TXDLC_OFFSET, buf_tx[1]);
+qtest_writel(qts, can_base_addr + R_TXDATA1_OFFSET, 

[PATCH resend v11 0/4] Introduce Xilinx ZynqMP CAN controller

2020-10-13 Thread Vikram Garhwal
Changelog:

v10 -> v11:
Resending the series with correct cc.
Replace DB_PRINTS with trace-events.
Removed unnecessary local variables.
Added const with tx/rx buffers in qtest.
Added reviewed-by tags for qtest.

v9 -> v10:
Rebase the series with the new meson build system.

v8 -> v9:
Use g_autofree to do automatic cleanup the object_get_canonical_path() used.

v7 -> v8:
Change CAN controller to keep one canbus per controller.
Add canbus connections at machine level.
Remove ctrl_idx from CAN controller.

v6 -> v7:
Remove '-m 4G' option from xlnx-can-test. This option causes the fail of
docker-quick@centos7 build test.

v5 -> v6:
Add ptimer based counter for time stamping on RX messages.
Fix reset issues.
Rebase the patches with master latest changes.
Added reference clock property for CAN ptimer.

v4 -> v5:
Add XlnxZynqMPCAN controller id to debug messages.
Drop parameter errp of object_property_add().
Add formatting related suggestions.

v3 -> v4:
Correct formatting issues.

v2 -> v3:
Rectify the build issue.
Rearrange the patch order.

v1 -> v2:
Rename the CAN device state and address code style issues.
Connect the CAN device to Xlnx-ZCU102 board.
Add maintainer entry.
Add QTEST for the CAN device.


Vikram Garhwal (4):
  hw/net/can: Introduce Xilinx ZynqMP CAN controller
  xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers
  tests/qtest: Introduce tests for Xilinx ZynqMP CAN controller
  MAINTAINERS: Add maintainer entry for Xilinx ZynqMP CAN controller

 meson.build  |1 +
 hw/net/can/trace.h   |1 +
 include/hw/arm/xlnx-zynqmp.h |8 +
 include/hw/net/xlnx-zynqmp-can.h |   78 +++
 hw/arm/xlnx-zcu102.c |   20 +
 hw/arm/xlnx-zynqmp.c |   34 ++
 hw/net/can/xlnx-zynqmp-can.c | 1159 ++
 tests/qtest/xlnx-can-test.c  |  360 
 MAINTAINERS  |8 +
 hw/Kconfig   |1 +
 hw/net/can/meson.build   |1 +
 hw/net/can/trace-events  |9 +
 tests/qtest/meson.build  |1 +
 13 files changed, 1681 insertions(+)
 create mode 100644 hw/net/can/trace.h
 create mode 100644 include/hw/net/xlnx-zynqmp-can.h
 create mode 100644 hw/net/can/xlnx-zynqmp-can.c
 create mode 100644 tests/qtest/xlnx-can-test.c
 create mode 100644 hw/net/can/trace-events

--
2.7.4




[PATCH v11 2/4] xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers

2020-10-13 Thread Vikram Garhwal
Connect CAN0 and CAN1 on the ZynqMP.

Reviewed-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
Signed-off-by: Vikram Garhwal 
---
 include/hw/arm/xlnx-zynqmp.h |  8 
 hw/arm/xlnx-zcu102.c | 20 
 hw/arm/xlnx-zynqmp.c | 34 ++
 3 files changed, 62 insertions(+)

diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index 567d0db..6f45387 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -22,6 +22,7 @@
 #include "hw/intc/arm_gic.h"
 #include "hw/net/cadence_gem.h"
 #include "hw/char/cadence_uart.h"
+#include "hw/net/xlnx-zynqmp-can.h"
 #include "hw/ide/ahci.h"
 #include "hw/sd/sdhci.h"
 #include "hw/ssi/xilinx_spips.h"
@@ -33,6 +34,7 @@
 #include "hw/cpu/cluster.h"
 #include "target/arm/cpu.h"
 #include "qom/object.h"
+#include "net/can_emu.h"
 
 #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
 OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
@@ -41,6 +43,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
 #define XLNX_ZYNQMP_NUM_RPU_CPUS 2
 #define XLNX_ZYNQMP_NUM_GEMS 4
 #define XLNX_ZYNQMP_NUM_UARTS 2
+#define XLNX_ZYNQMP_NUM_CAN 2
+#define XLNX_ZYNQMP_CAN_REF_CLK (24 * 1000 * 1000)
 #define XLNX_ZYNQMP_NUM_SDHCI 2
 #define XLNX_ZYNQMP_NUM_SPIS 2
 #define XLNX_ZYNQMP_NUM_GDMA_CH 8
@@ -92,6 +96,7 @@ struct XlnxZynqMPState {
 
 CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS];
 CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS];
+XlnxZynqMPCANState can[XLNX_ZYNQMP_NUM_CAN];
 SysbusAHCIState sata;
 SDHCIState sdhci[XLNX_ZYNQMP_NUM_SDHCI];
 XilinxSPIPS spi[XLNX_ZYNQMP_NUM_SPIS];
@@ -112,6 +117,9 @@ struct XlnxZynqMPState {
 bool virt;
 /* Has the RPU subsystem?  */
 bool has_rpu;
+
+/* CAN bus. */
+CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
 };
 
 #endif
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
index ad7fff9..4ef0c51 100644
--- a/hw/arm/xlnx-zcu102.c
+++ b/hw/arm/xlnx-zcu102.c
@@ -25,6 +25,7 @@
 #include "sysemu/qtest.h"
 #include "sysemu/device_tree.h"
 #include "qom/object.h"
+#include "net/can_emu.h"
 
 struct XlnxZCU102 {
 MachineState parent_obj;
@@ -34,6 +35,8 @@ struct XlnxZCU102 {
 bool secure;
 bool virt;
 
+CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
+
 struct arm_boot_info binfo;
 };
 
@@ -125,6 +128,14 @@ static void xlnx_zcu102_init(MachineState *machine)
 object_property_set_bool(OBJECT(>soc), "virtualization", s->virt,
  _fatal);
 
+for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+gchar *bus_name = g_strdup_printf("canbus%d", i);
+
+object_property_set_link(OBJECT(>soc), bus_name,
+ OBJECT(s->canbus[i]), _fatal);
+g_free(bus_name);
+}
+
 qdev_realize(DEVICE(>soc), NULL, _fatal);
 
 /* Create and plug in the SD cards */
@@ -208,6 +219,15 @@ static void xlnx_zcu102_machine_instance_init(Object *obj)
 s->secure = false;
 /* Default to virt (EL2) being disabled */
 s->virt = false;
+object_property_add_link(obj, "xlnx-zcu102.canbus0", TYPE_CAN_BUS,
+ (Object **)>canbus[0],
+ object_property_allow_set_link,
+ 0);
+
+object_property_add_link(obj, "xlnx-zcu102.canbus1", TYPE_CAN_BUS,
+ (Object **)>canbus[1],
+ object_property_allow_set_link,
+ 0);
 }
 
 static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 7885bb1..8818472 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -81,6 +81,14 @@ static const int uart_intr[XLNX_ZYNQMP_NUM_UARTS] = {
 21, 22,
 };
 
+static const uint64_t can_addr[XLNX_ZYNQMP_NUM_CAN] = {
+0xFF06, 0xFF07,
+};
+
+static const int can_intr[XLNX_ZYNQMP_NUM_CAN] = {
+23, 24,
+};
+
 static const uint64_t sdhci_addr[XLNX_ZYNQMP_NUM_SDHCI] = {
 0xFF16, 0xFF17,
 };
@@ -243,6 +251,11 @@ static void xlnx_zynqmp_init(Object *obj)
 TYPE_CADENCE_UART);
 }
 
+for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+object_initialize_child(obj, "can[*]", >can[i],
+TYPE_XLNX_ZYNQMP_CAN);
+}
+
 object_initialize_child(obj, "sata", >sata, TYPE_SYSBUS_AHCI);
 
 for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
@@ -482,6 +495,23 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
**errp)
gic_spi[uart_intr[i]]);
 }
 
+for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+object_property_set_int(OBJECT(>can[i]), "ext_clk_freq",
+XLNX_ZYNQMP_CAN_REF_CLK, _abort);
+
+object_property_set_link(OBJECT(>can[i]), "canbus",
+ OBJECT(s->canbus[i]), _fatal);
+
+sysbus_realize(SYS_BUS_DEVICE(>can[i]), );
+  

Re: [PATCH v4 3/3] replay: do not build if TCG is not available

2020-10-13 Thread Pavel Dovgalyuk

On 13.10.2020 22:21, Claudio Fontana wrote:

this fixes non-TCG builds broken recently by replay reverse debugging.

stub the needed functions in stub/, including errors for hmp and qmp.
This includes duplicating some code in replay/, and puts the logic
for non-replay related events in the replay/ module (+ the stubs),
so this should be revisited in the future.

Surprisingly, only _one_ qtest was affected by this, ide-test.c, which
resulted in a buzz as the bh events were never delivered, and the bh
never executed.

Many other subsystems _should_ have been affected.

This fixes the immediate issue, however a better way to group replay
functionality to TCG-only code could be developed in the long term.

Signed-off-by: Claudio Fontana 
---
  block/meson.build  |  3 +-
  migration/savevm.c | 11 +++--
  net/meson.build|  3 +-
  replay/meson.build |  2 +-
  replay/replay-input.c  |  4 +-
  stubs/meson.build  |  1 -
  stubs/replay-user.c|  9 
  stubs/replay.c | 98 ++
  tests/ptimer-test-stubs.c  |  5 --
  tests/qtest/qmp-cmd-test.c |  3 ++
  ui/input.c | 12 -
  11 files changed, 125 insertions(+), 26 deletions(-)
  delete mode 100644 stubs/replay-user.c

diff --git a/block/meson.build b/block/meson.build
index 78e8b25232..01fe6f84d2 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -7,7 +7,6 @@ block_ss.add(files(
'backup-top.c',
'blkdebug.c',
'blklogwrites.c',
-  'blkreplay.c',
'blkverify.c',
'block-backend.c',
'block-copy.c',
@@ -42,6 +41,8 @@ block_ss.add(files(
'write-threshold.c',
  ), zstd, zlib)
  
+block_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))

+
  block_ss.add(when: 'CONFIG_QCOW1', if_true: files('qcow.c'))
  block_ss.add(when: 'CONFIG_VDI', if_true: files('vdi.c'))
  block_ss.add(when: 'CONFIG_CLOOP', if_true: files('cloop.c'))
diff --git a/migration/savevm.c b/migration/savevm.c
index d2e141f7b1..d9181ca520 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -63,6 +63,7 @@
  #include "migration/colo.h"
  #include "qemu/bitmap.h"
  #include "net/announce.h"
+#include "sysemu/tcg.h"
  
  const unsigned int postcopy_ram_discard_version = 0;
  
@@ -2674,10 +2675,12 @@ int save_snapshot(const char *name, Error **errp)

  return ret;
  }
  
-if (!replay_can_snapshot()) {

-error_setg(errp, "Record/replay does not allow making snapshot "
-   "right now. Try once more later.");
-return ret;
+if (tcg_enabled()) {
+if (!replay_can_snapshot()) {
+error_setg(errp, "Record/replay does not allow making snapshot "
+   "right now. Try once more later.");
+return ret;
+}
  }
  
  if (!bdrv_all_can_snapshot()) {

diff --git a/net/meson.build b/net/meson.build
index 1c7e3a3cb9..1076b0a7ab 100644
--- a/net/meson.build
+++ b/net/meson.build
@@ -7,7 +7,6 @@ softmmu_ss.add(files(
'eth.c',
'filter-buffer.c',
'filter-mirror.c',
-  'filter-replay.c',
'filter-rewriter.c',
'filter.c',
'hub.c',
@@ -17,6 +16,8 @@ softmmu_ss.add(files(
'util.c',
  ))
  
+softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('filter-replay.c'))

+
  softmmu_ss.add(when: 'CONFIG_L2TPV3', if_true: files('l2tpv3.c'))
  softmmu_ss.add(when: slirp, if_true: files('slirp.c'))
  softmmu_ss.add(when: ['CONFIG_VDE', vde], if_true: files('vde.c'))
diff --git a/replay/meson.build b/replay/meson.build
index f91163fb1e..cb3207740a 100644
--- a/replay/meson.build
+++ b/replay/meson.build
@@ -1,4 +1,4 @@
-softmmu_ss.add(files(
+softmmu_ss.add(when: 'CONFIG_TCG', if_true: files(
'replay.c',
'replay-internal.c',
'replay-events.c',
diff --git a/replay/replay-input.c b/replay/replay-input.c
index 1147e3d34e..5d1fd92e79 100644
--- a/replay/replay-input.c
+++ b/replay/replay-input.c
@@ -124,7 +124,7 @@ void replay_input_event(QemuConsole *src, InputEvent *evt)
  } else if (replay_mode == REPLAY_MODE_RECORD) {
  replay_add_input_event(QAPI_CLONE(InputEvent, evt));
  } else {
-qemu_input_event_send_impl(src, evt);
+g_assert_not_reached();
  }
  }
  
@@ -135,6 +135,6 @@ void replay_input_sync_event(void)

  } else if (replay_mode == REPLAY_MODE_RECORD) {
  replay_add_input_sync_event();
  } else {
-qemu_input_event_sync_impl();
+g_assert_not_reached();
  }
  }
diff --git a/stubs/meson.build b/stubs/meson.build
index 67f2a8c069..bbd2230d69 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -32,7 +32,6 @@ stub_ss.add(files('qtest.c'))
  stub_ss.add(files('ram-block.c'))
  stub_ss.add(files('ramfb.c'))
  stub_ss.add(files('replay.c'))
-stub_ss.add(files('replay-user.c'))
  stub_ss.add(files('runstate-check.c'))
  stub_ss.add(files('set-fd-handler.c'))
  stub_ss.add(files('sysbus.c'))
diff --git a/stubs/replay-user.c b/stubs/replay-user.c
deleted file mode 

Re: [RFC PATCH v6 2/2] hw/misc/sifive_u_otp: Add backend drive support

2020-10-13 Thread Bin Meng
On Mon, Sep 28, 2020 at 6:12 PM Green Wan  wrote:
>
> Add '-drive' support to OTP device. Allow users to assign a raw file
> as OTP image.
>
> test commands for 16k otp.img filled with zero:
>
> dd if=/dev/zero of=./otp.img bs=1k count=16

nits: please prefix the command with a leading "$ ", like

$ dd if=/dev/zero of=./otp.img bs=1k count=16

> ./qemu-system-riscv64 -M sifive_u -m 256M -nographic -bios none \
> -kernel ../opensbi/build/platform/sifive/fu540/firmware/fw_payload.elf \
> -d guest_errors -drive if=none,format=raw,file=otp.img
>
> Signed-off-by: Green Wan 
> ---
>  hw/misc/sifive_u_otp.c | 51 ++
>  include/hw/misc/sifive_u_otp.h |  2 ++
>  2 files changed, 53 insertions(+)
>
> diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
> index 685c1f8e07..f2585c1ed7 100644
> --- a/hw/misc/sifive_u_otp.c
> +++ b/hw/misc/sifive_u_otp.c
> @@ -19,11 +19,14 @@
>   */
>
>  #include "qemu/osdep.h"
> +#include "qapi/error.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/sysbus.h"
>  #include "qemu/log.h"
>  #include "qemu/module.h"
>  #include "hw/misc/sifive_u_otp.h"
> +#include "sysemu/blockdev.h"
> +#include "sysemu/block-backend.h"
>
>  #define WRITTEN_BIT_ON 0x1
>
> @@ -54,6 +57,16 @@ static uint64_t sifive_u_otp_read(void *opaque, hwaddr 
> addr, unsigned int size)
>  if ((s->pce & SIFIVE_U_OTP_PCE_EN) &&
>  (s->pdstb & SIFIVE_U_OTP_PDSTB_EN) &&
>  (s->ptrim & SIFIVE_U_OTP_PTRIM_EN)) {
> +
> +/* read from backend */
> +if (s->blk) {
> +int32_t buf;
> +
> +blk_pread(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD, ,
> +  SIFIVE_U_OTP_FUSE_WORD);
> +return buf;
> +}
> +
>  return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
>  } else {
>  return 0xff;
> @@ -145,6 +158,12 @@ static void sifive_u_otp_write(void *opaque, hwaddr addr,
>  /* write bit data */
>  SET_FUSEARRAY_BIT(s->fuse, s->pa, s->paio, s->pdin);
>
> +/* write to backend */
> +if (s->blk) {
> +blk_pwrite(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD, ,
> +   SIFIVE_U_OTP_FUSE_WORD, 0);
> +}
> +
>  /* update written bit */
>  SET_FUSEARRAY_BIT(s->fuse_wo, s->pa, s->paio, WRITTEN_BIT_ON);
>  }
> @@ -168,16 +187,48 @@ static const MemoryRegionOps sifive_u_otp_ops = {
>
>  static Property sifive_u_otp_properties[] = {
>  DEFINE_PROP_UINT32("serial", SiFiveUOTPState, serial, 0),
> +DEFINE_PROP_DRIVE("drive", SiFiveUOTPState, blk),
>  DEFINE_PROP_END_OF_LIST(),
>  };
>
>  static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
>  {
>  SiFiveUOTPState *s = SIFIVE_U_OTP(dev);
> +DriveInfo *dinfo;
>
>  memory_region_init_io(>mmio, OBJECT(dev), _u_otp_ops, s,
>TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE);
>  sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mmio);
> +
> +dinfo = drive_get_next(IF_NONE);
> +if (dinfo) {
> +int ret;
> +uint64_t perm;
> +int filesize;
> +BlockBackend *blk;
> +
> +blk = blk_by_legacy_dinfo(dinfo);
> +filesize = SIFIVE_U_OTP_NUM_FUSES * SIFIVE_U_OTP_FUSE_WORD;
> +if (blk_getlength(blk) < filesize) {
> +error_setg(errp, "OTP drive size < 16K");
> +return;
> +}
> +
> +qdev_prop_set_drive_err(dev, "drive", blk, errp);
> +
> +if (s->blk) {
> +perm = BLK_PERM_CONSISTENT_READ |
> +   (blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
> +ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
> +if (ret < 0) {
> +return;
> +}
> +
> +if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) {
> +error_setg(errp, "failed to read the initial flash content");
> +}
> +}
> +}
>  }
>
>  static void sifive_u_otp_reset(DeviceState *dev)
> diff --git a/include/hw/misc/sifive_u_otp.h b/include/hw/misc/sifive_u_otp.h
> index ebffbc1fa5..5d0d7df455 100644
> --- a/include/hw/misc/sifive_u_otp.h
> +++ b/include/hw/misc/sifive_u_otp.h
> @@ -46,6 +46,7 @@
>
>  #define SIFIVE_U_OTP_PA_MASK0xfff
>  #define SIFIVE_U_OTP_NUM_FUSES  0x1000
> +#define SIFIVE_U_OTP_FUSE_WORD  4
>  #define SIFIVE_U_OTP_SERIAL_ADDR0xfc
>
>  #define SIFIVE_U_OTP_REG_SIZE   0x1000
> @@ -80,6 +81,7 @@ struct SiFiveUOTPState {
>  uint32_t fuse_wo[SIFIVE_U_OTP_NUM_FUSES];
>  /* config */
>  uint32_t serial;
> +BlockBackend *blk;
>  };
>

Please add the serial number initialization for the block backend as
well in sifive_u_otp_reset().

The logic should be something like testing offset 0x3f0 and 0x3f4
numbers to see if they follow the rule: value 0x3f0 == ~(value 0x3f4).
If not, the data should be initialized per the 

Re: [RFC PATCH v6 1/2] hw/misc/sifive_u_otp: Add write function and write-once protection

2020-10-13 Thread Bin Meng
Hi Green,

On Mon, Sep 28, 2020 at 6:12 PM Green Wan  wrote:
>
>  - Add write operation to update fuse data bit when PWE bit is on.
>  - Add array, fuse_wo, to store the 'written' status for all bits
>of OTP to block the write operation.
>
> Signed-off-by: Green Wan 
> Reviewed-by: Alistair Francis 
> ---
>  hw/misc/sifive_u_otp.c | 30 +-
>  include/hw/misc/sifive_u_otp.h |  3 +++
>  2 files changed, 32 insertions(+), 1 deletion(-)
>

I am not sure how you tested this. I wrote a simple U-Boot command to
call U-Boot sifive-otp driver to test the write functionality, but it
failed.

=> misc write otp@1007 0 8020 10
=> misc read  otp@1007 0 8040 10
=> md 8040
8040:    
80400010:    
80400020:    
80400030:    
80400040:    
80400050:    
80400060:    
80400070:    
80400080:    
80400090:    
804000a0:    
804000b0:    
804000c0:    
804000d0:    
804000e0:    
804000f0:    
=> misc write otp@1007 0 80200010 10
=> misc read  otp@1007 0 80400010 10
=> md 8040
8040:    
80400010:    
80400020:    
80400030:    
80400040:    
80400050:    
80400060:    
80400070:    
80400080:    
80400090:    
804000a0:    
804000b0:    
804000c0:    
804000d0:    
804000e0:    
804000f0:    

But it can read the serial number at offset 0x3f0

=> misc read  otp@1007 3f0 80400010 10
=> md 8040
8040:    
80400010: 0001 fffe  
80400020:    
80400030:    
80400040:    
80400050:    
80400060:    
80400070:    
80400080:    
80400090:    
804000a0:    
804000b0:    
804000c0:    
804000d0:    
804000e0:    
804000f0:    

Regards,
Bin



[PATCH v3 0/4] GitLab Custom Runners and Jobs (was: QEMU Gating CI)

2020-10-13 Thread Cleber Rosa
TL;DR: this should allow the QEMU maintainer to push to the staging
branch, and have custom jobs running on the project's aarch64 and
s390x machines.  Simple usage looks like:

   git push remote staging
   ./scripts/ci/gitlab-pipeline-status --verbose --wait

Long version:

The idea about a public facing Gating CI for QEMU was summarized in an
RFC[1].  Since then, it was decided that a simpler version should be
attempted first.

At this point, there are two specific runners (an aarch64 and an s390)
registered with GitLab, at https://gitlab.com/qemu-project, currently
setup to the "qemu" repository.

Changes from v2:

- The overall idea of "Gating CI" has been re-worded "custom runners",
  given that the other jobs running on shared runners are also
  considered gating (Daniel)

- Fixed wording and typos on the documentation, including:
 * update -> up to date (Erik)
 * a different set of CI jobs -> different CI jobs (Erik)
 * Pull requests will only be merged -> code will only be merged (Stefan)
 * Setup -> set up (Stefan)
 * them -> they (Stefan)
 * the -> where the (Stefan)
 * dropped "in the near future" (Stefan)

- Changed comment on "build-environment.yml" regarding the origin of
  the package list (Stefan)

- Removed inclusion of "vars.yml" from "build-environment.yml", given that
  no external variable is used there

- Updated package list in "build-environment.yml" from current
  dockerfiles

- Tested "build-environment" on Fedora 31 and 32 (in addition to Fedora 30),
  and noted that it's possible to use it on those distros

- Moved CI documentation from "testing.rst" to its own file (Phillipe)

- Split "GitLab Gating CI: initial set of jobs, documentation and scripts"
  into (Phillipe):
  1) Basic documentation and configuration (gitlab-ci.yml) placeholder
  2) Playbooks for setting up a build environment
  3) Playbooks for setting up gitlab-runner
  4) Actual GitLab CI jobs configuration

- Set custom jobs to be on the "build" stage, given that they combine
  build and test.

- Set custom jobs to not depend on any other job, so they can start
  right away.

- Set rules for starting jobs so that all pushing to any branch that
  start with name "staging".  This allows the project maintainer to
  use the "push to staging" workflow, while also allowing others to
  generate similar jobs.  If this project has configured custom
  runners, the jobs will run, if not, the pipeline will be marked as
  "stuck".

- Changed "scripts" on custom jobs to follow the now common pattern
  (on other jobs) of creating a "build" directory.

Changes from v1:

- Added jobs that require specific GitLab runners already available
  (Ubuntu 20.04 on aarch64, and Ubuntu 18.04 on s390x)
- Removed jobs that require specific GitLab runners not yet available
  (Fedora 30, FreeBSD 12.1)
- Updated documentation
- Added copyright and license to new scripts
- Moved script to from "contrib" to "scripts/ci/"
- Moved setup playbooks form "contrib" to "scripts/ci/setup"
- Moved "gating.yml" to ".gitlab-ci.d" directory
- Removed "staging" only branch restriction on jobs defined in
  ".gitlab-ci.yml", assumes that the additional jobs on the staging
  branch running on the freely available gitlab shared runner are
  positive
- Dropped patches 1-3 (already merged)
- Simplified amount of version specifity on Ubuntu, from 18.04.3 to
  simply 18.04 (assumes no diverse minor levels will be used or
  specific runners)

Changes from the RFC patches[2] accompanying the RFC document:

- Moved gating job definitions to .gitlab-ci-gating.yml
- Added info on "--disable-libssh" build option requirement
  (https://bugs.launchpad.net/qemu/+bug/1838763) to Ubuntu 18.04 jobs
- Added info on "--disable-glusterfs" build option requirement
  (there's no static version of those libs in distro supplied
  packages) to one
- Dropped ubuntu-18.04.3-x86_64-notools job definition, because it
  doesn't fall into the general scope of gating job described by PMM
  (and it did not run any test)
- Added w32 and w64 cross builds based on Fedora 30
- Added a FreeBSD based job that builds all targets and runs `make
  check`
- Added "-j`nproc`" and "-j`sysctl -n hw.ncpu`" options to make as a
  simple but effective way of speeding up the builds and tests by
  using a number of make jobs matching the number of CPUs
- Because the Ansible playbooks reference the content on Dockerfiles,
  some fixes to some Dockerfiles caught in the process were included
- New patch with script to check or wait on a pipeline execution

[1] - https://lists.gnu.org/archive/html/qemu-devel/2019-12/msg00231.html
[2] - https://lists.gnu.org/archive/html/qemu-devel/2020-02/msg00154.html

Cleber Rosa (4):
  Jobs based on custom runners: documentation and configuration
placeholder
  Jobs based on custom runners: build environment docs and playbook
  Jobs based on custom runners: docs and gitlab-runner setup playbook
  Jobs based on custom runners: add job definitions for QEMU's machines

 

[PATCH v3 3/4] Jobs based on custom runners: docs and gitlab-runner setup playbook

2020-10-13 Thread Cleber Rosa
To have the jobs dispatched to custom runners, gitlab-runner must
be installed, active as a service and properly configured.  The
variables file and playbook introduced here should help with those
steps.

The playbook introduced here covers a number of different Linux
distributions and FreeBSD, and are intended to provide a reproducible
environment.

Signed-off-by: Cleber Rosa 
---
 docs/devel/ci.rst  | 63 ++
 scripts/ci/setup/.gitignore|  1 +
 scripts/ci/setup/gitlab-runner.yml | 72 ++
 scripts/ci/setup/vars.yml.template | 13 ++
 4 files changed, 149 insertions(+)
 create mode 100644 scripts/ci/setup/.gitignore
 create mode 100644 scripts/ci/setup/gitlab-runner.yml
 create mode 100644 scripts/ci/setup/vars.yml.template

diff --git a/docs/devel/ci.rst b/docs/devel/ci.rst
index 208b5e399b..a234a5e24c 100644
--- a/docs/devel/ci.rst
+++ b/docs/devel/ci.rst
@@ -84,3 +84,66 @@ To run the playbook, execute::
 
   cd scripts/ci/setup
   ansible-playbook -i inventory build-environment.yml
+
+gitlab-runner setup and registration
+
+
+The gitlab-runner agent needs to be installed on each machine that
+will run jobs.  The association between a machine and a GitLab project
+happens with a registration token.  To find the registration token for
+your repository/project, navigate on GitLab's web UI to:
+
+ * Settings (the gears like icon), then
+ * CI/CD, then
+ * Runners, and click on the "Expand" button, then
+ * Under "Set up a specific Runner manually", look for the value under
+   "Use the following registration token during setup"
+
+Copy the ``scripts/ci/setup/vars.yml.template`` file to
+``scripts/ci/setup/vars.yml``.  Then, set the
+``gitlab_runner_registration_token`` variable to the value obtained
+earlier.
+
+.. note:: gitlab-runner is not available from the standard location
+  for all OS and architectures combinations.  For some systems,
+  a custom build may be necessary.  Some builds are avaiable
+  at https://cleber.fedorapeople.org/gitlab-runner/ and this
+  URI may be used as a value on ``vars.yml``
+
+To run the playbook, execute::
+
+  cd scripts/ci/setup
+  ansible-playbook -i inventory gitlab-runner.yml
+
+.. note:: there are currently limitations to gitlab-runner itself when
+  setting up a service under FreeBSD systems.  You will need to
+  perform steps 4 to 10 manually, as described at
+  https://docs.gitlab.com/runner/install/freebsd.html
+
+Following the registration, it's necessary to configure the runner tags,
+and optionally other configurations on the GitLab UI.  Navigate to:
+
+ * Settings (the gears like icon), then
+ * CI/CD, then
+ * Runners, and click on the "Expand" button, then
+ * "Runners activated for this project", then
+ * Click on the "Edit" icon (next to the "Lock" Icon)
+
+Under tags, add values matching the jobs a runner should run.  For a
+FreeBSD 12.1 x86_64 system, the tags should be set as::
+
+  freebsd12.1,x86_64
+
+Because the job definition at ``.gitlab-ci.d/custom-runners.yml``
+would contain::
+
+  freebsd-12.1-x86_64-all:
+   tags:
+   - freebsd_12.1
+   - x86_64
+
+It's also recommended to:
+
+ * increase the "Maximum job timeout" to something like ``2h``
+ * uncheck the "Run untagged jobs" check box
+ * give it a better Description
diff --git a/scripts/ci/setup/.gitignore b/scripts/ci/setup/.gitignore
new file mode 100644
index 00..f112d05dd0
--- /dev/null
+++ b/scripts/ci/setup/.gitignore
@@ -0,0 +1 @@
+vars.yml
\ No newline at end of file
diff --git a/scripts/ci/setup/gitlab-runner.yml 
b/scripts/ci/setup/gitlab-runner.yml
new file mode 100644
index 00..c2f52dad10
--- /dev/null
+++ b/scripts/ci/setup/gitlab-runner.yml
@@ -0,0 +1,72 @@
+---
+- name: Installation of gitlab-runner
+  hosts: all
+  vars_files:
+- vars.yml
+  tasks:
+- debug:
+msg: 'Checking for a valid GitLab registration token'
+  failed_when: "gitlab_runner_registration_token == 
'PLEASE_PROVIDE_A_VALID_TOKEN'"
+
+- name: Checks the availability of official gitlab-runner builds in the 
archive
+  uri:
+url: https://s3.amazonaws.com/gitlab-runner-downloads/v{{ 
gitlab_runner_version  }}/binaries/gitlab-runner-linux-386
+method: HEAD
+status_code:
+  - 200
+  - 403
+  register: gitlab_runner_available_archive
+
+- name: Update base url
+  set_fact:
+gitlab_runner_base_url: 
https://s3.amazonaws.com/gitlab-runner-downloads/v{{ gitlab_runner_version  
}}/binaries/gitlab-runner-
+  when: gitlab_runner_available_archive.status == 200
+- debug:
+msg: Base gitlab-runner url is {{ gitlab_runner_base_url  }}
+
+- name: Set OS name (FreeBSD)
+  set_fact:
+gitlab_runner_os: freebsd
+  when: "ansible_facts['system'] == 'FreeBSD'"
+
+- name: Create a group for the gitlab-runner service
+  

[PATCH v3 2/4] Jobs based on custom runners: build environment docs and playbook

2020-10-13 Thread Cleber Rosa
To run basic jobs on custom runners, the environment needs to be
properly set up.  The most common requirement is having the right
packages installed.

The playbook introduced here covers a number of different Linux
distributions and FreeBSD, and are intended to provide a reproducible
environment.

Signed-off-by: Cleber Rosa 
---
 docs/devel/ci.rst  |  32 
 scripts/ci/setup/build-environment.yml | 220 +
 scripts/ci/setup/inventory |   2 +
 3 files changed, 254 insertions(+)
 create mode 100644 scripts/ci/setup/build-environment.yml
 create mode 100644 scripts/ci/setup/inventory

diff --git a/docs/devel/ci.rst b/docs/devel/ci.rst
index 41a4bbddad..208b5e399b 100644
--- a/docs/devel/ci.rst
+++ b/docs/devel/ci.rst
@@ -52,3 +52,35 @@ As a general rule, those newly added contributed jobs should 
run as
 The precise minimum requirements and exact rules for machine
 configuration documentation/scripts, and the success rate of jobs are
 still to be defined.
+
+Machine Setup Howto
+---
+
+For all Linux based systems, the setup can be mostly automated by the
+execution of two Ansible playbooks.  Start by adding your machines to
+the ``inventory`` file under ``scripts/ci/setup``, such as this::
+
+  [local]
+  fully.qualified.domain
+  other.machine.hostname
+
+You may need to set some variables in the inventory file itself.  One
+very common need is to tell Ansible to use a Python 3 interpreter on
+those hosts.  This would look like::
+
+  [local]
+  fully.qualified.domain ansible_python_interpreter=/usr/bin/python3
+  other.machine.hostname ansible_python_interpreter=/usr/bin/python3
+
+Build environment
+~
+
+The ``scripts/ci/setup/build-environment.yml`` Ansible playbook will
+set up machines with the environment needed to perform builds and run
+QEMU tests.  It covers a number of different Linux distributions and
+FreeBSD.
+
+To run the playbook, execute::
+
+  cd scripts/ci/setup
+  ansible-playbook -i inventory build-environment.yml
diff --git a/scripts/ci/setup/build-environment.yml 
b/scripts/ci/setup/build-environment.yml
new file mode 100644
index 00..0e8894bca9
--- /dev/null
+++ b/scripts/ci/setup/build-environment.yml
@@ -0,0 +1,220 @@
+---
+- name: Installation of basic packages to build QEMU
+  hosts: all
+  tasks:
+- name: Install basic packages to build QEMU on Ubuntu 18.04/20.04
+  apt:
+update_cache: yes
+# Originally from tests/docker/dockerfiles/ubuntu1804.docker
+pkg:
+  - ccache
+  - clang
+  - gcc
+  - gettext
+  - git
+  - glusterfs-common
+  - libaio-dev
+  - libattr1-dev
+  - libbrlapi-dev
+  - libbz2-dev
+  - libcacard-dev
+  - libcap-ng-dev
+  - libcurl4-gnutls-dev
+  - libdrm-dev
+  - libepoxy-dev
+  - libfdt-dev
+  - libgbm-dev
+  - libgtk-3-dev
+  - libibverbs-dev
+  - libiscsi-dev
+  - libjemalloc-dev
+  - libjpeg-turbo8-dev
+  - liblzo2-dev
+  - libncurses5-dev
+  - libncursesw5-dev
+  - libnfs-dev
+  - libnss3-dev
+  - libnuma-dev
+  - libpixman-1-dev
+  - librados-dev
+  - librbd-dev
+  - librdmacm-dev
+  - libsasl2-dev
+  - libsdl2-dev
+  - libseccomp-dev
+  - libsnappy-dev
+  - libspice-protocol-dev
+  - libssh-dev
+  - libusb-1.0-0-dev
+  - libusbredirhost-dev
+  - libvdeplug-dev
+  - libvte-2.91-dev
+  - libzstd-dev
+  - make
+  - python3-yaml
+  - python3-sphinx
+  - sparse
+  - xfslibs-dev
+state: present
+  when: "ansible_facts['distribution'] == 'Ubuntu'"
+
+- name: Install packages to build QEMU on Ubuntu 18.04/20.04 on non-s390x
+  apt:
+update_cache: yes
+pkg:
+ - libspice-server-dev
+ - libxen-dev
+state: present
+  when:
+- "ansible_facts['distribution'] == 'Ubuntu'"
+- "ansible_facts['architecture'] != 's390x'"
+
+- name: Install basic packages to build QEMU on FreeBSD 12.x
+  pkgng:
+# This matches the packages on .cirrus.yml under the freebsd_12_task
+name: 
bash,bison,curl,cyrus-sasl,git,glib,gmake,gnutls,gsed,nettle,perl5,pixman,pkgconf,png,usbredir
+state: present
+  when: "ansible_facts['os_family'] == 'FreeBSD'"
+
+- name: Install basic packages to build QEMU on Fedora 30, 31 and 32
+  dnf:
+# Originally from tests/docker/dockerfiles/fedora.docker
+name:
+  - SDL2-devel
+  - bc
+  - brlapi-devel
+  - bzip2
+  - bzip2-devel
+  - ccache
+  - clang
+  - cyrus-sasl-devel
+  - dbus-daemon
+  - device-mapper-multipath-devel
+  - 

[PATCH v3 1/4] Jobs based on custom runners: documentation and configuration placeholder

2020-10-13 Thread Cleber Rosa
As described in the included documentation, the "custom runner" jobs
extend the GitLab CI jobs already in place.

Those jobs are intended to run on hardware and/or Operating Systems
not provided by GitLab's shared runners.

Signed-off-by: Cleber Rosa 
---
 .gitlab-ci.d/custom-runners.yml | 14 +
 .gitlab-ci.yml  |  1 +
 docs/devel/ci.rst   | 54 +
 docs/devel/index.rst|  1 +
 4 files changed, 70 insertions(+)
 create mode 100644 .gitlab-ci.d/custom-runners.yml
 create mode 100644 docs/devel/ci.rst

diff --git a/.gitlab-ci.d/custom-runners.yml b/.gitlab-ci.d/custom-runners.yml
new file mode 100644
index 00..3004da2bda
--- /dev/null
+++ b/.gitlab-ci.d/custom-runners.yml
@@ -0,0 +1,14 @@
+# The CI jobs defined here require GitLab runners installed and
+# registered on machines that match their operating system names,
+# versions and architectures.  This is in contrast to the other CI
+# jobs that are intended to run on GitLab's "shared" runners.
+
+# Different than the default approach on "shared" runners, based on
+# containers, the custom runners have no such *requirement*, as those
+# jobs should be capable of running on operating systems with no
+# compatible container implementation, or no support from
+# gitlab-runner.  To avoid problems that gitlab-runner can cause while
+# reusing the GIT repository, let's enable the recursive submodule
+# strategy.
+variables:
+  GIT_SUBMODULE_STRATEGY: recursive
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8ffd415ca5..b33c433fd7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -18,6 +18,7 @@ include:
   - local: '/.gitlab-ci.d/opensbi.yml'
   - local: '/.gitlab-ci.d/containers.yml'
   - local: '/.gitlab-ci.d/crossbuilds.yml'
+  - local: '/.gitlab-ci.d/custom-runners.yml'
 
 .native_build_job_template: _build_job_definition
   stage: build
diff --git a/docs/devel/ci.rst b/docs/devel/ci.rst
new file mode 100644
index 00..41a4bbddad
--- /dev/null
+++ b/docs/devel/ci.rst
@@ -0,0 +1,54 @@
+==
+CI
+==
+
+QEMU has configurations enabled for a number of different CI services.
+The most up to date information about them and their status can be
+found at::
+
+   https://wiki.qemu.org/Testing/CI
+
+Jobs on Custom Runners
+==
+
+Besides the jobs run under the various CI systems listed before, there
+are a number additional jobs that will run before an actual merge.
+These use the same GitLab CI's service/framework already used for all
+other GitLab based CI jobs, but rely on additional systems, not the
+ones provided by GitLab as "shared runners".
+
+The architecture of GitLab's CI service allows different machines to
+be set up with GitLab's "agent", called gitlab-runner, which will take
+care of running jobs created by events such as a push to a branch.
+Here, the combination of a machine, properly configured with GitLab's
+gitlab-runner, is called a "custom runner" here.
+
+The GitLab CI jobs definition for the custom runners are located under::
+
+  .gitlab-ci.d/custom-runners.yml
+
+Current Jobs
+
+
+The current CI jobs based on custom runners have the primary goal of
+catching and preventing regressions on a wider number of host systems
+than the ones provided by GitLab's shared runners.
+
+Also, the mechanics of reliability, capacity and overall maintanance
+of the machines provided by the QEMU project itself for those jobs
+will be evaluated.
+
+Future Plans and Jobs
+-
+
+Once the CI Jobs based on custom runners have been proved mature with
+the initial set of jobs run on machines from the QEMU project, other
+members in the community should be able provide their own machine
+configuration documentation/scripts, and accompanying job definitions.
+
+As a general rule, those newly added contributed jobs should run as
+"non-gating", until their reliability is verified.
+
+The precise minimum requirements and exact rules for machine
+configuration documentation/scripts, and the success rate of jobs are
+still to be defined.
diff --git a/docs/devel/index.rst b/docs/devel/index.rst
index 77baae5c77..2fdd36e751 100644
--- a/docs/devel/index.rst
+++ b/docs/devel/index.rst
@@ -21,6 +21,7 @@ Contents:
atomics
stable-process
testing
+   ci
qtest
decodetree
secure-coding-practices
-- 
2.25.4




[PATCH v3 4/4] Jobs based on custom runners: add job definitions for QEMU's machines

2020-10-13 Thread Cleber Rosa
The QEMU project has two machines (aarch64 and s390) that can be used
for jobs that do build and run tests.  This introduces those jobs,
which are a mapping of custom scripts used for the same purpose.

Signed-off-by: Cleber Rosa 
---
 .gitlab-ci.d/custom-runners.yml | 192 
 1 file changed, 192 insertions(+)

diff --git a/.gitlab-ci.d/custom-runners.yml b/.gitlab-ci.d/custom-runners.yml
index 3004da2bda..5b51d1b336 100644
--- a/.gitlab-ci.d/custom-runners.yml
+++ b/.gitlab-ci.d/custom-runners.yml
@@ -12,3 +12,195 @@
 # strategy.
 variables:
   GIT_SUBMODULE_STRATEGY: recursive
+
+# All ubuntu-18.04 jobs should run successfully in an environment
+# setup by the scripts/ci/setup/build-environment.yml task
+# "Install basic packages to build QEMU on Ubuntu 18.04/20.04"
+ubuntu-18.04-s390x-all-linux-static:
+ needs: []
+ stage: build
+ tags:
+ - ubuntu_18.04
+ - s390x
+ rules:
+ - if: '$CI_COMMIT_BRANCH =~ /^staging/'
+ script:
+ # --disable-libssh is needed because of 
https://bugs.launchpad.net/qemu/+bug/1838763
+ # --disable-glusterfs is needed because there's no static version of those 
libs in distro supplied packages
+ - mkdir build
+ - cd build
+ - ../configure --enable-debug --static --disable-system --disable-glusterfs 
--disable-libssh
+ - make --output-sync -j`nproc`
+ - make --output-sync -j`nproc` check V=1
+ - make --output-sync -j`nproc` check-tcg V=1
+
+ubuntu-18.04-s390x-all:
+ needs: []
+ stage: build
+ tags:
+ - ubuntu_18.04
+ - s390x
+ rules:
+ - if: '$CI_COMMIT_BRANCH =~ /^staging/'
+ script:
+ - mkdir build
+ - cd build
+ - ../configure --disable-libssh
+ - make --output-sync -j`nproc`
+ - make --output-sync -j`nproc` check V=1
+
+ubuntu-18.04-s390x-alldbg:
+ needs: []
+ stage: build
+ tags:
+ - ubuntu_18.04
+ - s390x
+ rules:
+ - if: '$CI_COMMIT_BRANCH =~ /^staging/'
+ script:
+ - mkdir build
+ - cd build
+ - ../configure --enable-debug --disable-libssh
+ - make clean
+ - make --output-sync -j`nproc`
+ - make --output-sync -j`nproc` check V=1
+
+ubuntu-18.04-s390x-clang:
+ needs: []
+ stage: build
+ tags:
+ - ubuntu_18.04
+ - s390x
+ rules:
+ - if: '$CI_COMMIT_BRANCH =~ /^staging/'
+ script:
+ - mkdir build
+ - cd build
+ - ../configure --disable-libssh --cc=clang --cxx=clang++ --enable-sanitizers
+ - make --output-sync -j`nproc`
+ - make --output-sync -j`nproc` check V=1
+
+ubuntu-18.04-s390x-tci:
+ needs: []
+ stage: build
+ tags:
+ - ubuntu_18.04
+ - s390x
+ rules:
+ - if: '$CI_COMMIT_BRANCH =~ /^staging/'
+ script:
+ - mkdir build
+ - cd build
+ - ../configure --disable-libssh --enable-tcg-interpreter
+ - make --output-sync -j`nproc`
+
+ubuntu-18.04-s390x-notcg:
+ needs: []
+ stage: build
+ tags:
+ - ubuntu_18.04
+ - s390x
+ rules:
+ - if: '$CI_COMMIT_BRANCH =~ /^staging/'
+ script:
+ - mkdir build
+ - cd build
+ - ../configure --disable-libssh --disable-tcg
+ - make --output-sync -j`nproc`
+ - make --output-sync -j`nproc` check V=1
+
+# All ubuntu-20.04 jobs should run successfully in an environment
+# setup by the scripts/ci/setup/qemu/build-environment.yml task
+# "Install basic packages to build QEMU on Ubuntu 18.04/20.04"
+ubuntu-20.04-aarch64-all-linux-static:
+ needs: []
+ stage: build
+ tags:
+ - ubuntu_20.04
+ - aarch64
+ rules:
+ - if: '$CI_COMMIT_BRANCH =~ /^staging/'
+ script:
+ # --disable-libssh is needed because of 
https://bugs.launchpad.net/qemu/+bug/1838763
+ # --disable-glusterfs is needed because there's no static version of those 
libs in distro supplied packages
+ - mkdir build
+ - cd build
+ - ../configure --enable-debug --static --disable-system --disable-glusterfs 
--disable-libssh
+ - make --output-sync -j`nproc`
+ - make --output-sync -j`nproc` check V=1
+ - make --output-sync -j`nproc` check-tcg V=1
+
+ubuntu-20.04-aarch64-all:
+ needs: []
+ stage: build
+ tags:
+ - ubuntu_20.04
+ - aarch64
+ rules:
+ - if: '$CI_COMMIT_BRANCH =~ /^staging/'
+ script:
+ - mkdir build
+ - cd build
+ - ../configure --disable-libssh
+ - make --output-sync -j`nproc`
+ - make --output-sync -j`nproc` check V=1
+
+ubuntu-20.04-aarch64-alldbg:
+ needs: []
+ stage: build
+ tags:
+ - ubuntu_20.04
+ - aarch64
+ rules:
+ - if: '$CI_COMMIT_BRANCH =~ /^staging/'
+ script:
+ - mkdir build
+ - cd build
+ - ../configure --enable-debug --disable-libssh
+ - make clean
+ - make --output-sync -j`nproc`
+ - make --output-sync -j`nproc` check V=1
+
+ubuntu-20.04-aarch64-clang:
+ needs: []
+ stage: build
+ tags:
+ - ubuntu_20.04
+ - aarch64
+ rules:
+ - if: '$CI_COMMIT_BRANCH =~ /^staging/'
+ script:
+ - mkdir build
+ - cd build
+ - ../configure --disable-libssh --cc=clang --cxx=clang++ --enable-sanitizers
+ - make --output-sync -j`nproc`
+ - make --output-sync -j`nproc` check V=1
+
+ubuntu-20.04-aarch64-tci:
+ needs: []
+ stage: build
+ tags:
+ - ubuntu_20.04
+ - aarch64
+ rules:
+ - if: '$CI_COMMIT_BRANCH =~ /^staging/'
+ script:
+ - mkdir build
+ - cd build
+ - ../configure --disable-libssh --enable-tcg-interpreter
+ - make --output-sync -j`nproc`
+

[Bug 1899728] [NEW] Qemu-5.1.0 build from source man entry not found

2020-10-13 Thread Damian Tometzki
Public bug reported:

Hello together,

i build qemu-5.1.0 from source on centos 8 withe the following command:

../configure --prefix=/usr --target-list=x86_64-softmmu,x86_64-linux-
user

make -j4

make install

The build and the installation finished successfully. But when i try the
command

man qemu-system-x86_64

i got the message "No manual entry found". What i do wrong ?

Best regards
Damian

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  Qemu-5.1.0 build from source man entry not found

Status in QEMU:
  New

Bug description:
  Hello together,

  i build qemu-5.1.0 from source on centos 8 withe the following
  command:

  ../configure --prefix=/usr --target-list=x86_64-softmmu,x86_64-linux-
  user

  make -j4

  make install

  The build and the installation finished successfully. But when i try
  the command

  man qemu-system-x86_64

  i got the message "No manual entry found". What i do wrong ?

  Best regards
  Damian

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



Re: [RFC PATCH 0/3] target/mips: Make the number of TLB entries a CPU property

2020-10-13 Thread Victor Kamensky (kamensky)
Hi Richard,

Please forgive my cumbersome mailing agent at work.
Please look inline for 'victor>' 


From: Richard Henderson 
Sent: Tuesday, October 13, 2020 7:22 PM
To: Philippe Mathieu-Daudé; qemu-devel@nongnu.org; Victor Kamensky (kamensky)
Cc: Aleksandar Rikalo; Khem Raj; Aleksandar Markovic; Richard Purdie; Aurelien 
Jarno; Richard Henderson
Subject: Re: [RFC PATCH 0/3] target/mips: Make the number of TLB entries a CPU 
property

On 10/13/20 4:11 PM, Richard Henderson wrote:
> On 10/13/20 6:25 AM, Philippe Mathieu-Daudé wrote:
>> Yocto developers have expressed interest in running MIPS32
>> CPU with custom number of TLB:
>> https://lists.gnu.org/archive/html/qemu-devel/2020-10/msg03428.html
>>
>> Help them by making the number of TLB entries a CPU property,
>> keeping our set of CPU definitions in sync with real hardware.
>
> You mean keeping the 34kf model within qemu in sync, rather than creating a
> nonsense model that doesn't exist.

victor> Question: do current MIPS "generic" qemu cpu models exist for real
victor> out there? I agree my choice was not ideal, but it is not that 
outlandish
victor> and IMO somewhat inline with existence of MIPS generic cpu models.

> Question: is this cpu parameter useful for anything else?

victor> If you are interested here are my testing numbers of how #TLBs impact
victor> user land execution time:
victor> https://lists.openembedded.org/g/openembedded-core/message/143115

> Because the ideal solution for a CI loop is to use one of the mips cpu models
> that has the hw page table walker (CP0C3_PW).  Having qemu being able to 
> refill
> the tlb itself is massively faster.
>
> We do not currently implement a mips cpu that has the PW.  When I downloaded

Bah, "mips32 cpu".

We do have the P5600 that does has it, though the code is wrapped up in
TARGET_MIPS64.  I'll also note that the code could be better placed [*]

> (1) anyone know if the PW incompatible with mips32?

I've since found a copy of the mips32-pra in the wayback machine and have
answered this as "no" -- PW is documented for mips32.

> (2) if not, was there any mips32 hw built with PW
> that we could model?

But I still don't know about this.

A further question for the Yocto folks: could you make use of a 64-bit kernel
in testing a 32-bit userspace?

victor> Such test does exist and it is part of CI already, it is dubbed as MIPS 
multi-lib
victor> tests where on top mips64 kernel tests are run for n64, n32, and o32 
MIPS ABIs
victor> user-land.
victor> Note mips32 CI in question does cover kernel functionality for example
victor> KLM build and check, SystemTap test, ltp and other kernel operations 
are tested.
victor> I.e it does test 32 bit MIPS kernel as well, but user-land is involved 
in such
victor> tests, and as it was described, it is slow compared to other qemu cases.

Thanks,
Victor

And I guess maybe we should update our recommendations in the docs.  Thoughts
on this, Phil?


r~


[*] Where it is now, it can't be used for gdb (mips_cpu_get_phys_page_debug).
When used there, we should not modify cpu state, i.e. actually insert the PTE
into the MIPS TLB, but we could still make use of the information available.



Re: [RFC PATCH 0/3] target/mips: Make the number of TLB entries a CPU property

2020-10-13 Thread Richard Henderson
On 10/13/20 4:11 PM, Richard Henderson wrote:
> On 10/13/20 6:25 AM, Philippe Mathieu-Daudé wrote:
>> Yocto developers have expressed interest in running MIPS32
>> CPU with custom number of TLB:
>> https://lists.gnu.org/archive/html/qemu-devel/2020-10/msg03428.html
>>
>> Help them by making the number of TLB entries a CPU property,
>> keeping our set of CPU definitions in sync with real hardware.
> 
> You mean keeping the 34kf model within qemu in sync, rather than creating a
> nonsense model that doesn't exist.
> 
> Question: is this cpu parameter useful for anything else?
> 
> Because the ideal solution for a CI loop is to use one of the mips cpu models
> that has the hw page table walker (CP0C3_PW).  Having qemu being able to 
> refill
> the tlb itself is massively faster.
> 
> We do not currently implement a mips cpu that has the PW.  When I downloaded

Bah, "mips32 cpu".

We do have the P5600 that does has it, though the code is wrapped up in
TARGET_MIPS64.  I'll also note that the code could be better placed [*]

> (1) anyone know if the PW incompatible with mips32?

I've since found a copy of the mips32-pra in the wayback machine and have
answered this as "no" -- PW is documented for mips32.

> (2) if not, was there any mips32 hw built with PW
> that we could model?

But I still don't know about this.

A further question for the Yocto folks: could you make use of a 64-bit kernel
in testing a 32-bit userspace?

And I guess maybe we should update our recommendations in the docs.  Thoughts
on this, Phil?


r~


[*] Where it is now, it can't be used for gdb (mips_cpu_get_phys_page_debug).
When used there, we should not modify cpu state, i.e. actually insert the PTE
into the MIPS TLB, but we could still make use of the information available.



Re: [RFC PATCH 0/3] target/mips: Make the number of TLB entries a CPU property

2020-10-13 Thread Victor Kamensky (kamensky)
Hi Philippe,

Thank you very much for looking at this. I gave a spin to
your 3 patch series in original setup, and as expected with
'-cpu 34Kf,tlb-entries=64' option it works great.

If nobody objects, and your patches could be merged, we
would greatly appreciate it.

Thanks,
Victor


From: Philippe Mathieu-Daudé  on behalf of 
Philippe Mathieu-Daudé 
Sent: Tuesday, October 13, 2020 6:25 AM
To: qemu-devel@nongnu.org; Victor Kamensky (kamensky)
Cc: Khem Raj; Richard Henderson; Aleksandar Rikalo; Aleksandar Markovic; Jiaxun 
Yang; Aurelien Jarno; Richard Purdie; Philippe Mathieu-Daudé
Subject: [RFC PATCH 0/3] target/mips: Make the number of TLB entries a CPU 
property

Yocto developers have expressed interest in running MIPS32

CPU with custom number of TLB:

https://lists.gnu.org/archive/html/qemu-devel/2020-10/msg03428.html



Help them by making the number of TLB entries a CPU property,

keeping our set of CPU definitions in sync with real hardware.



Please test/review,



Phil.



Philippe Mathieu-Daudé (3):

  target/mips: Make cpu_mips_realize_env() propagate Error

  target/mips: Store number of TLB entries in CPUMIPSState

  target/mips: Make the number of TLB entries a CPU property



 target/mips/cpu.h|  1 +

 target/mips/internal.h   | 10 +-

 target/mips/cpu.c| 12 ++--

 target/mips/translate.c  | 16 ++--

 target/mips/translate_init.c.inc |  2 +-

 5 files changed, 35 insertions(+), 6 deletions(-)



--

2.26.2






Re: [PATCH v2 1/8] migration: Do not use C99 // comments

2020-10-13 Thread Bihong Yu
OK, I will modify it later.

On 2020/10/14 9:29, Zheng Chuan wrote:
> Also DEBUG_CACHE in migration/page_cache.c is need to rebase on trace_calls.
> 
> On 2020/10/13 21:20, Bihong Yu wrote:
>> Thank you for your review. OK, I will try to rewrite the DPRINTF to use 
>> trace_ instead.
>>
>> On 2020/10/13 17:39, Dr. David Alan Gilbert wrote:
>>> * Bihong Yu (yubih...@huawei.com) wrote:
 Signed-off-by: Bihong Yu 
 Reviewed-by: Chuan Zheng 
>>>
>>> Reviewed-by: Dr. David Alan Gilbert 
>>>
>>> another task at some point would be to rewrite the DPRINTF's in
>>> migration/block.c to use trace_ instead.
>>>
 ---
  migration/block.c | 2 +-
  migration/rdma.c  | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

 diff --git a/migration/block.c b/migration/block.c
 index 737b649..4b8576b 100644
 --- a/migration/block.c
 +++ b/migration/block.c
 @@ -40,7 +40,7 @@
  #define MAX_IO_BUFFERS 512
  #define MAX_PARALLEL_IO 16
  
 -//#define DEBUG_BLK_MIGRATION
 +/* #define DEBUG_BLK_MIGRATION */
  
  #ifdef DEBUG_BLK_MIGRATION
  #define DPRINTF(fmt, ...) \
 diff --git a/migration/rdma.c b/migration/rdma.c
 index 0340841..0eb42b7 100644
 --- a/migration/rdma.c
 +++ b/migration/rdma.c
 @@ -1288,7 +1288,7 @@ const char *print_wrid(int wrid)
   * workload information or LRU information is available, do not attempt 
 to use
   * this feature except for basic testing.
   */
 -//#define RDMA_UNREGISTRATION_EXAMPLE
 +/* #define RDMA_UNREGISTRATION_EXAMPLE */
  
  /*
   * Perform a non-optimized memory unregistration after every transfer
 -- 
 1.8.3.1

>> .
>>
> 



Re: [PATCH v2 1/8] migration: Do not use C99 // comments

2020-10-13 Thread Zheng Chuan
Also DEBUG_CACHE in migration/page_cache.c is need to rebase on trace_calls.

On 2020/10/13 21:20, Bihong Yu wrote:
> Thank you for your review. OK, I will try to rewrite the DPRINTF to use 
> trace_ instead.
> 
> On 2020/10/13 17:39, Dr. David Alan Gilbert wrote:
>> * Bihong Yu (yubih...@huawei.com) wrote:
>>> Signed-off-by: Bihong Yu 
>>> Reviewed-by: Chuan Zheng 
>>
>> Reviewed-by: Dr. David Alan Gilbert 
>>
>> another task at some point would be to rewrite the DPRINTF's in
>> migration/block.c to use trace_ instead.
>>
>>> ---
>>>  migration/block.c | 2 +-
>>>  migration/rdma.c  | 2 +-
>>>  2 files changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/migration/block.c b/migration/block.c
>>> index 737b649..4b8576b 100644
>>> --- a/migration/block.c
>>> +++ b/migration/block.c
>>> @@ -40,7 +40,7 @@
>>>  #define MAX_IO_BUFFERS 512
>>>  #define MAX_PARALLEL_IO 16
>>>  
>>> -//#define DEBUG_BLK_MIGRATION
>>> +/* #define DEBUG_BLK_MIGRATION */
>>>  
>>>  #ifdef DEBUG_BLK_MIGRATION
>>>  #define DPRINTF(fmt, ...) \
>>> diff --git a/migration/rdma.c b/migration/rdma.c
>>> index 0340841..0eb42b7 100644
>>> --- a/migration/rdma.c
>>> +++ b/migration/rdma.c
>>> @@ -1288,7 +1288,7 @@ const char *print_wrid(int wrid)
>>>   * workload information or LRU information is available, do not attempt to 
>>> use
>>>   * this feature except for basic testing.
>>>   */
>>> -//#define RDMA_UNREGISTRATION_EXAMPLE
>>> +/* #define RDMA_UNREGISTRATION_EXAMPLE */
>>>  
>>>  /*
>>>   * Perform a non-optimized memory unregistration after every transfer
>>> -- 
>>> 1.8.3.1
>>>
> .
> 

-- 
Thanks, Chuan



Re: [PATCH V13 8/9] hw/mips: Add Loongson-3 machine support

2020-10-13 Thread Huacai Chen
Hi, Philippe,

On Tue, Oct 13, 2020 at 9:45 PM Philippe Mathieu-Daudé  wrote:
>
> On 10/13/20 1:12 PM, Huacai Chen wrote:
> > Hi, Philippe,
> >
> > On Mon, Oct 12, 2020 at 4:12 PM Philippe Mathieu-Daudé  
> > wrote:
> >>
> >> On 10/11/20 4:53 AM, Huacai Chen wrote:
> >>> Hi, Philippe,
> >>>
> >>> On Sat, Oct 10, 2020 at 5:09 PM Philippe Mathieu-Daudé  
> >>> wrote:
> 
>  Hi Huacai,
> 
>  On 10/7/20 10:39 AM, Huacai Chen wrote:
> > Add Loongson-3 based machine support, it use liointc as the interrupt
> > controler and use GPEX as the pci controller. Currently it can work with
> > both TCG and KVM.
> >
> > As the machine model is not based on any exiting physical hardware, the
> > name of the machine is "loongson3-virt". It may be superseded in future
> > by a real machine model. If this happens, then a regular deprecation
> > procedure shall occur for "loongson3-virt" machine.
> >
> > We now already have a full functional Linux kernel (based on Linux-5.4.x
> > LTS, the kvm host side and guest side have both been upstream for Linux-
> > 5.9, but Linux-5.9 has not been released yet) here:
> >
> > https://github.com/chenhuacai/linux
> >
> > Of course the upstream kernel is also usable (though it is "unstable"
> > now):
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> >
> > How to use QEMU/Loongson-3?
> > 1, Download kernel source from the above URL;
> > 2, Build a kernel with arch/mips/configs/loongson3_defconfig;
> > 3, Boot a Loongson-3A4000 host with this kernel (for KVM mode);
> > 4, Build QEMU-master with this patchset;
> > 5, modprobe kvm (only necessary for KVM mode);
> > 6, Use QEMU with TCG:
> >   qemu-system-mips64el -M loongson3-virt,accel=tcg -cpu 
> > Loongson-3A1000 -kernel  -append ...
> >   Use QEMU with KVM:
> >   qemu-system-mips64el -M loongson3-virt,accel=kvm -cpu 
> > Loongson-3A4000 -kernel  -append ...
> >
> >   The "-cpu" parameter is optional here and QEMU will use the 
> > correct type for TCG/KVM automatically.
> >
> > Signed-off-by: Huacai Chen 
> > Co-developed-by: Jiaxun Yang 
> > ---
> > default-configs/devices/mips64el-softmmu.mak |   1 +
> > hw/mips/Kconfig  |  12 +
> > hw/mips/loongson3_bootp.c| 162 +++
> > hw/mips/loongson3_bootp.h| 225 ++
> 
>  In a previous version I asked if you could split the bootp* files
>  (firmware related) in a previous separate patch to ease the review
>  of the machine part.
> >>   >
> >>> In previous version you told me to split the fw_cfg to a separate
> >>> patch, but split the efi-related helpers to seprate files (not to a
> >>> patch). But anyway, I will split them to a patch in the next version.
> >>
> >> Sorry if I wasn't clear enough. It is very hard to review a patch
> >> of more than 1000 lines of C code without loosing focus or missing
> >> problems. It explains why big patches might stay unreviewed on the
> >> list. If you can split in smaller logical units, it will be very
> >> helpful.
> >>
> >> Peter Maydell rule of thumb is to keep patch below 200 lines.
> >> This is a good limit.
> >>
> >>>
> 
> > hw/mips/loongson3_virt.c | 615 
> > +++
> > hw/mips/meson.build  |   1 +
> > 6 files changed, 1016 insertions(+)
>  [...]
> 
> > diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
> > new file mode 100644
> > index 000..4e573d6
> > --- /dev/null
> > +++ b/hw/mips/loongson3_virt.c
> > @@ -0,0 +1,615 @@
> > +/*
> > + * Generic Loongson-3 Platform support
> > + *
> > + * Copyright (c) 2017-2020 Huacai Chen (che...@lemote.com)
> > + * Copyright (c) 2017-2020 Jiaxun Yang 
> > + *
> > + * This program is free software: you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation, either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that 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 
> > .
> > + */
> > +
> > +/*
> > + * Generic virtualized PC Platform based on Loongson-3 CPU (MIPS64R2 
> > with
> > + * extensions, 800~2000MHz)
> > + */
> > +
> > 

Re: [PATCH] vhost-user: add separate memslot counter for vhost-user

2020-10-13 Thread Raphael Norwitz
On Mon, Oct 12, 2020 at 7:12 AM chenjiajun  wrote:
>
>
>
> On 2020/10/2 10:05, Raphael Norwitz wrote:
> > On Mon, Sep 28, 2020 at 9:17 AM Jiajun Chen  wrote:
> >>
> >> Used_memslots is equal to dev->mem->nregions now, it is true for
> >> vhost kernel, but not for vhost user, which uses the memory regions
> >> that have file descriptor. In fact, not all of the memory regions
> >> have file descriptor.
> >> It is usefully in some scenarios, e.g. used_memslots is 8, and only
> >> 5 memory slots can be used by vhost user, it is failed to hot plug
> >> a new memory RAM because vhost_has_free_slot just returned false,
> >> but we can hot plug it safely in fact.
> >>
> >> --
> >> ChangeList:
> >> v3:
> >> -make used_memslots a member of struct vhost_dev instead of a global 
> >> static value
> >>
> >> v2:
> >> -eliminating useless used_memslots_exceeded variable and 
> >> used_memslots_is_exceeded() API
> >>
> >> v1:
> >> -vhost-user: add separate memslot counter for vhost-user
> >>
> >> Signed-off-by: Jiajun Chen 
> >> Signed-off-by: Jianjay Zhou 
> >
> > I'm happy with this from a vhost/vhost-user perspective. vhost-backend
> > change looks good too. I'm a little confused by what's going on with
> > net/vhost-user.c.
> >
> >> ---
> >>  hw/virtio/vhost-backend.c | 12 ++
> >>  hw/virtio/vhost-user.c| 25 +
> >>  hw/virtio/vhost.c | 37 +++
> >>  include/hw/virtio/vhost-backend.h |  5 +
> >>  include/hw/virtio/vhost.h |  1 +
> >>  net/vhost-user.c  |  7 ++
> >>  6 files changed, 78 insertions(+), 9 deletions(-)
> >>
> >
> >> diff --git a/net/vhost-user.c b/net/vhost-user.c
> >> index 17532daaf3..7e93955537 100644
> >> --- a/net/vhost-user.c
> >> +++ b/net/vhost-user.c
> >> @@ -20,6 +20,7 @@
> >>  #include "qemu/error-report.h"
> >>  #include "qemu/option.h"
> >>  #include "trace.h"
> >> +#include "include/hw/virtio/vhost.h"
> >>
> >>  typedef struct NetVhostUserState {
> >>  NetClientState nc;
> >> @@ -347,6 +348,12 @@ static int net_vhost_user_init(NetClientState *peer, 
> >> const char *device,
> >>  qemu_chr_fe_set_handlers(>chr, NULL, NULL,
> >>   net_vhost_user_event, NULL, nc0->name, 
> >> NULL,
> >>   true);
> >
> > Can you elaborate on this check here? What does it have to do with
> > fixing memslots accounting? Maybe it should be in a separate change?
> >
> When the number of virtual machine memslots exceeds the upper limit of the 
> back-end support,
> QEMU main thread may enters an endless loop and cannot process other requests.
> And number of memslots will not automatically decrease, so add a check here 
> to exit from loop
> in this scenario. For the newly started virtual machine, boot fails; for the 
> hot plug network card,
> hot plug fails.

I don't understand what you mean by "number of memslots will not
automatically decrease". Where did this happen before and what changes
when the new memslots counter is introduced?

> >> +
> >> +if (!vhost_has_free_slot()) {
> >> +error_report("used memslots exceeded the backend limit, quit "
> >> + "loop");
> >> +goto err;
> >> +}
> >>  } while (!s->started);
> >>
> >>  assert(s->vhost_net);
> >> --
> >> 2.27.0.dirty
> >>
> > .
> >



RE: [PATCH v2] migration/block-dirty-bitmap: fix uninitialized variable warning

2020-10-13 Thread Chenqun (kuhn)


> -Original Message-
> From: Max Reitz [mailto:mre...@redhat.com]
> Sent: Tuesday, October 13, 2020 10:47 PM
> To: Chenqun (kuhn) ; qemu-devel@nongnu.org;
> qemu-triv...@nongnu.org
> Cc: vsement...@virtuozzo.com; stefa...@redhat.com; f...@euphon.net;
> ebl...@redhat.com; js...@redhat.com; quint...@redhat.com;
> dgilb...@redhat.com; Zhanghailiang ;
> ganqixin ; qemu-bl...@nongnu.org; Euler Robot
> ; Laurent Vivier ; Li Qiang
> 
> Subject: Re: [PATCH v2] migration/block-dirty-bitmap: fix uninitialized 
> variable
> warning
> 
> On 13.10.20 14:33, Chen Qun wrote:
> > A default value is provided for the variable 'bitmap_name' to avoid compiler
> warning.
> >
> > The compiler show warning:
> > migration/block-dirty-bitmap.c:1090:13: warning: ‘bitmap_name’
> > may be used uninitialized in this function [-Wmaybe-uninitialized]
> >g_strlcpy(s->bitmap_name, bitmap_name,
> sizeof(s->bitmap_name));
> >
> ^~
> >
> > Reported-by: Euler Robot 
> > Signed-off-by: Chen Qun 
> > ---
> > Cc: Vladimir Sementsov-Ogievskiy 
> > Cc: Laurent Vivier 
> > Cc: Li Qiang 
> > ---
> >  migration/block-dirty-bitmap.c | 9 ++---
> >  1 file changed, 2 insertions(+), 7 deletions(-)
> 
> No objections, semantically, but...
> 
> > diff --git a/migration/block-dirty-bitmap.c
> > b/migration/block-dirty-bitmap.c index 5bef793ac0..bcb79c04ce 100644
> > --- a/migration/block-dirty-bitmap.c
> > +++ b/migration/block-dirty-bitmap.c
> > @@ -1064,15 +1064,13 @@ static int dirty_bitmap_load_header(QEMUFile
> *f, DBMLoadState *s,
> >  assert(nothing || s->cancelled || !!alias_map ==
> > !!bitmap_alias_map);
> >
> >  if (s->flags & DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME) {
> > -const char *bitmap_name;
> > -
> >  if (!qemu_get_counted_string(f, s->bitmap_alias)) {
> >  error_report("Unable to read bitmap alias string");
> >  return -EINVAL;
> >  }
> >
> > -if (!s->cancelled) {
> > -if (bitmap_alias_map) {
> > +const char *bitmap_name = s->bitmap_alias;
> 
> qemu’s coding style mandates declarations to be placed at the beginning of
> their block, so the declaration has to stay where it is.  (Putting the 
> assignment
> here looks reasonable.)
> 
Hi Max,
  Declaration variables here to ensure that the above exceptions(Unable to read 
bitmap alias string) are avoided.
If the declaration has to stay where it is, is there a possibility that the 
assignment fails?

> > +if (!s->cancelled && bitmap_alias_map) {
> >  bitmap_name =
> g_hash_table_lookup(bitmap_alias_map,
> >
> s->bitmap_alias);
> 
> This block of course needs to be re-indented.
> 
I forgot this. I will update it later.

Thanks,
ChenQun

> 
> >  if (!bitmap_name) {
> > @@ -1081,9 +1079,6 @@ static int dirty_bitmap_load_header(QEMUFile *f,
> DBMLoadState *s,
> >   s->bs->node_name,
> s->node_alias);
> >  cancel_incoming_locked(s);
> >  }
> > -} else {
> > -bitmap_name = s->bitmap_alias;
> > -}
> >  }
> >
> >  if (!s->cancelled) {
> >
> 



MacOS network bridging using vmnet framework

2020-10-13 Thread g...@ekarma.org
Hi all -

I've been playing around with qemu-system-arm on a MacOS 10.15 box.  I'm trying 
to bridge the guest but I haven't had any luck.  It looks like the proper way 
to do this is with a TAP device.  AFAIK, this was done in the past by 
installing a TUN/TAP kernel extension (kext), which Apple has since clamped 
down upon.   I haven't pursued this since it's looks like a dead-end.   I did 
notice that Apple has a framework called vmnet 
(https://developer.apple.com/documentation/vmnet) which offers VM network 
bridging.  I didn't see any references to vmnet in master,  Is vmnet a good fit 
in this case as a new TAP implementation, like tap-macos-vmnet.c.  Or am I 
going off into the weeds and there is something obvious I'm missing.

G.



Re: [PATCH] vhost-user: add separate memslot counter for vhost-user

2020-10-13 Thread Raphael Norwitz
On Tue, Oct 6, 2020 at 5:48 AM Igor Mammedov  wrote:
>
> On Mon, 28 Sep 2020 21:17:31 +0800
> Jiajun Chen  wrote:
>
> > Used_memslots is equal to dev->mem->nregions now, it is true for
> > vhost kernel, but not for vhost user, which uses the memory regions
> > that have file descriptor. In fact, not all of the memory regions
> > have file descriptor.
> > It is usefully in some scenarios, e.g. used_memslots is 8, and only
> > 5 memory slots can be used by vhost user, it is failed to hot plug
> > a new memory RAM because vhost_has_free_slot just returned false,
> > but we can hot plug it safely in fact.
>
> I had an impression that all guest RAM has to be shared with vhost,
> so combination of anon and fd based RAM couldn't work.
> Am I wrong?

I'm not sure about the kernel backend, but I've tested adding anon
memory to a VM with a vhost-user-scsi device and it works (eventually
the VM crashed, but I could see the guest recognized the anon RAM).
The vhost-user code is designed to work with both. I'm not sure I see
a use case, but if there is one, this would be a valid issue. Maybe
Jiajun or Jianjay can elaborate.

>
> >
> > --
> > ChangeList:
> > v3:
> > -make used_memslots a member of struct vhost_dev instead of a global static 
> > value
> it's global resource, so why?

I suggested it because I thought it made the code a little cleaner.
I'm not opposed to changing it back, or having it stored at the
vhost_user level.



Re: [PATCH v6 01/11] hw/block/nvme: Add Commands Supported and Effects log

2020-10-13 Thread Keith Busch
On Wed, Oct 14, 2020 at 06:42:02AM +0900, Dmitry Fomichev wrote:
> +{
> +NvmeEffectsLog log = {};
> +uint32_t *dst_acs = log.acs, *dst_iocs = log.iocs;
> +uint32_t trans_len;
> +int i;
> +
> +trace_pci_nvme_cmd_supp_and_effects_log_read();
> +
> +if (off >= sizeof(log)) {
> +trace_pci_nvme_err_invalid_effects_log_offset(off);
> +return NVME_INVALID_FIELD | NVME_DNR;
> +}
> +
> +for (i = 0; i < 256; i++) {
> +dst_acs[i] = nvme_cse_acs[i];
> +}
> +
> +for (i = 0; i < 256; i++) {
> +dst_iocs[i] = nvme_cse_iocs_nvm[i];
> +}

You're just copying the array, so let's do it like this:

memcpy(log.acs, nvme_cse_acs, sizeof(nvme_cse_acs));
memcpy(log.iocs, nvme_cse_iocs_nvm, sizeof(nvme_cse_iocs_nvm));

I think you also need to check

if (NVME_CC_CSS(n->bar.cc) != NVME_CC_CSS_ADMIN_ONLY)

before copying iocs.



Re: [PATCH for-5.1] hw/arm/netduino2, netduinoplus2: Set system_clock_scale

2020-10-13 Thread Alistair Francis
On Tue, Oct 13, 2020 at 5:29 PM Alistair Francis  wrote:
>
> On Mon, Oct 12, 2020 at 8:45 AM Peter Maydell  
> wrote:
> >
> > The netduino2 and netduinoplus2 boards forgot to set the system_clock_scale
> > global, which meant that if guest code used the systick timer in "use
> > the processor clock" mode it would hang because time never advances.
> >
> > Set the global to match the documented CPU clock speed of these boards.
> > Judging by the data sheet this is slightly simplistic because the
> > SoC allows configuration of the SYSCLK source and frequency via the
> > RCC (reset and clock control) module, but we don't model that.
> >
> > Fixes: https://bugs.launchpad.net/qemu/+bug/1876187

Thanks for fixing this Peter.

Alistair

> > Signed-off-by: Peter Maydell 
>
> Reviewed-by: Alistair Francis 
>
> Alistair
>
> > ---
> > NB: tested with "make check" only...
> >
> >  hw/arm/netduino2.c | 10 ++
> >  hw/arm/netduinoplus2.c | 10 ++
> >  2 files changed, 20 insertions(+)
> >
> > diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
> > index 79e19392b56..8f103341443 100644
> > --- a/hw/arm/netduino2.c
> > +++ b/hw/arm/netduino2.c
> > @@ -30,10 +30,20 @@
> >  #include "hw/arm/stm32f205_soc.h"
> >  #include "hw/arm/boot.h"
> >
> > +/* Main SYSCLK frequency in Hz (120MHz) */
> > +#define SYSCLK_FRQ 12000ULL
> > +
> >  static void netduino2_init(MachineState *machine)
> >  {
> >  DeviceState *dev;
> >
> > +/*
> > + * TODO: ideally we would model the SoC RCC and let it handle
> > + * system_clock_scale, including its ability to define different
> > + * possible SYSCLK sources.
> > + */
> > +system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
> > +
> >  dev = qdev_new(TYPE_STM32F205_SOC);
> >  qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
> >  sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
> > diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
> > index 958d21dd9f9..68abd3ec69d 100644
> > --- a/hw/arm/netduinoplus2.c
> > +++ b/hw/arm/netduinoplus2.c
> > @@ -30,10 +30,20 @@
> >  #include "hw/arm/stm32f405_soc.h"
> >  #include "hw/arm/boot.h"
> >
> > +/* Main SYSCLK frequency in Hz (168MHz) */
> > +#define SYSCLK_FRQ 16800ULL
> > +
> >  static void netduinoplus2_init(MachineState *machine)
> >  {
> >  DeviceState *dev;
> >
> > +/*
> > + * TODO: ideally we would model the SoC RCC and let it handle
> > + * system_clock_scale, including its ability to define different
> > + * possible SYSCLK sources.
> > + */
> > +system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
> > +
> >  dev = qdev_new(TYPE_STM32F405_SOC);
> >  qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
> >  sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
> > --
> > 2.20.1
> >
> >



Re: [PATCH for-5.1] hw/arm/netduino2, netduinoplus2: Set system_clock_scale

2020-10-13 Thread Alistair Francis
On Mon, Oct 12, 2020 at 8:45 AM Peter Maydell  wrote:
>
> The netduino2 and netduinoplus2 boards forgot to set the system_clock_scale
> global, which meant that if guest code used the systick timer in "use
> the processor clock" mode it would hang because time never advances.
>
> Set the global to match the documented CPU clock speed of these boards.
> Judging by the data sheet this is slightly simplistic because the
> SoC allows configuration of the SYSCLK source and frequency via the
> RCC (reset and clock control) module, but we don't model that.
>
> Fixes: https://bugs.launchpad.net/qemu/+bug/1876187
> Signed-off-by: Peter Maydell 

Reviewed-by: Alistair Francis 

Alistair

> ---
> NB: tested with "make check" only...
>
>  hw/arm/netduino2.c | 10 ++
>  hw/arm/netduinoplus2.c | 10 ++
>  2 files changed, 20 insertions(+)
>
> diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
> index 79e19392b56..8f103341443 100644
> --- a/hw/arm/netduino2.c
> +++ b/hw/arm/netduino2.c
> @@ -30,10 +30,20 @@
>  #include "hw/arm/stm32f205_soc.h"
>  #include "hw/arm/boot.h"
>
> +/* Main SYSCLK frequency in Hz (120MHz) */
> +#define SYSCLK_FRQ 12000ULL
> +
>  static void netduino2_init(MachineState *machine)
>  {
>  DeviceState *dev;
>
> +/*
> + * TODO: ideally we would model the SoC RCC and let it handle
> + * system_clock_scale, including its ability to define different
> + * possible SYSCLK sources.
> + */
> +system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
> +
>  dev = qdev_new(TYPE_STM32F205_SOC);
>  qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
>  sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
> diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
> index 958d21dd9f9..68abd3ec69d 100644
> --- a/hw/arm/netduinoplus2.c
> +++ b/hw/arm/netduinoplus2.c
> @@ -30,10 +30,20 @@
>  #include "hw/arm/stm32f405_soc.h"
>  #include "hw/arm/boot.h"
>
> +/* Main SYSCLK frequency in Hz (168MHz) */
> +#define SYSCLK_FRQ 16800ULL
> +
>  static void netduinoplus2_init(MachineState *machine)
>  {
>  DeviceState *dev;
>
> +/*
> + * TODO: ideally we would model the SoC RCC and let it handle
> + * system_clock_scale, including its ability to define different
> + * possible SYSCLK sources.
> + */
> +system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
> +
>  dev = qdev_new(TYPE_STM32F405_SOC);
>  qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
>  sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
> --
> 2.20.1
>
>



[PATCH v2 3/4] hw/riscv: Add a riscv_is_32_bit() function

2020-10-13 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/boot.h | 2 ++
 hw/riscv/boot.c | 9 +
 2 files changed, 11 insertions(+)

diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 0acbd8aa6e..2975ed1a31 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -23,6 +23,8 @@
 #include "exec/cpu-defs.h"
 #include "hw/loader.h"
 
+bool riscv_is_32_bit(MachineState *machine);
+
 target_ulong riscv_find_and_load_firmware(MachineState *machine,
   const char *default_machine_firmware,
   hwaddr firmware_load_addr,
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index fa699308a0..5dea644f47 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -40,6 +40,15 @@
 #define fw_dynamic_info_data(__val) cpu_to_le64(__val)
 #endif
 
+bool riscv_is_32_bit(MachineState *machine)
+{
+if (!strncmp(machine->cpu_type, "rv32", 4)) {
+return true;
+} else {
+return false;
+}
+}
+
 target_ulong riscv_find_and_load_firmware(MachineState *machine,
   const char *default_machine_firmware,
   hwaddr firmware_load_addr,
-- 
2.28.0




[PATCH v2 4/4] hw/riscv: Load the kernel after the firmware

2020-10-13 Thread Alistair Francis
Instead of loading the kernel at a hardcoded start address, let's load
the kernel at the next alligned address after the end of the firmware.

This should have no impact for current users of OpenSBI, but will
allow loading a noMMU kernel at the start of memory.

Signed-off-by: Alistair Francis 
---
 include/hw/riscv/boot.h |  3 +++
 hw/riscv/boot.c | 19 ++-
 hw/riscv/opentitan.c|  3 ++-
 hw/riscv/sifive_e.c |  3 ++-
 hw/riscv/sifive_u.c | 10 --
 hw/riscv/spike.c| 11 ---
 hw/riscv/virt.c | 11 ---
 7 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 2975ed1a31..0b01988727 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -25,6 +25,8 @@
 
 bool riscv_is_32_bit(MachineState *machine);
 
+target_ulong riscv_calc_kernel_start_addr(MachineState *machine,
+  target_ulong firmware_end_addr);
 target_ulong riscv_find_and_load_firmware(MachineState *machine,
   const char *default_machine_firmware,
   hwaddr firmware_load_addr,
@@ -34,6 +36,7 @@ target_ulong riscv_load_firmware(const char 
*firmware_filename,
  hwaddr firmware_load_addr,
  symbol_fn_t sym_cb);
 target_ulong riscv_load_kernel(const char *kernel_filename,
+   target_ulong firmware_end_addr,
symbol_fn_t sym_cb);
 hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
  uint64_t kernel_entry, hwaddr *start);
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 5dea644f47..9b3fe3fb1e 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -33,10 +33,8 @@
 #include 
 
 #if defined(TARGET_RISCV32)
-# define KERNEL_BOOT_ADDRESS 0x8040
 #define fw_dynamic_info_data(__val) cpu_to_le32(__val)
 #else
-# define KERNEL_BOOT_ADDRESS 0x8020
 #define fw_dynamic_info_data(__val) cpu_to_le64(__val)
 #endif
 
@@ -49,6 +47,15 @@ bool riscv_is_32_bit(MachineState *machine)
 }
 }
 
+target_ulong riscv_calc_kernel_start_addr(MachineState *machine,
+  target_ulong firmware_end_addr) {
+if (riscv_is_32_bit(machine)) {
+return QEMU_ALIGN_UP(firmware_end_addr, 4 * MiB);
+} else {
+return QEMU_ALIGN_UP(firmware_end_addr, 2 * MiB);
+}
+}
+
 target_ulong riscv_find_and_load_firmware(MachineState *machine,
   const char *default_machine_firmware,
   hwaddr firmware_load_addr,
@@ -123,7 +130,9 @@ target_ulong riscv_load_firmware(const char 
*firmware_filename,
 exit(1);
 }
 
-target_ulong riscv_load_kernel(const char *kernel_filename, symbol_fn_t sym_cb)
+target_ulong riscv_load_kernel(const char *kernel_filename,
+   target_ulong kernel_start_addr,
+   symbol_fn_t sym_cb)
 {
 uint64_t kernel_entry;
 
@@ -138,9 +147,9 @@ target_ulong riscv_load_kernel(const char *kernel_filename, 
symbol_fn_t sym_cb)
 return kernel_entry;
 }
 
-if (load_image_targphys_as(kernel_filename, KERNEL_BOOT_ADDRESS,
+if (load_image_targphys_as(kernel_filename, kernel_start_addr,
ram_size, NULL) > 0) {
-return KERNEL_BOOT_ADDRESS;
+return kernel_start_addr;
 }
 
 error_report("could not load kernel '%s'", kernel_filename);
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 0531bd879b..cc758b78b8 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -75,7 +75,8 @@ static void opentitan_board_init(MachineState *machine)
 }
 
 if (machine->kernel_filename) {
-riscv_load_kernel(machine->kernel_filename, NULL);
+riscv_load_kernel(machine->kernel_filename,
+  memmap[IBEX_DEV_RAM].base, NULL);
 }
 }
 
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index fcfac16816..59bac4cc9a 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -114,7 +114,8 @@ static void sifive_e_machine_init(MachineState *machine)
   memmap[SIFIVE_E_DEV_MROM].base, 
_space_memory);
 
 if (machine->kernel_filename) {
-riscv_load_kernel(machine->kernel_filename, NULL);
+riscv_load_kernel(machine->kernel_filename,
+  memmap[SIFIVE_E_DEV_DTIM].base, NULL);
 }
 }
 
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 5f3ad9bc0f..b2472c6627 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -415,6 +415,7 @@ static void sifive_u_machine_init(MachineState *machine)
 MemoryRegion *main_mem = g_new(MemoryRegion, 1);
 MemoryRegion *flash0 = g_new(MemoryRegion, 1);
 target_ulong start_addr = memmap[SIFIVE_U_DEV_DRAM].base;
+

[PATCH v2 0/4] Allow loading a no MMU kernel

2020-10-13 Thread Alistair Francis
This series allows loading a noMMU kernel using the -kernel option.
Currently if using -kernel QEMU assumes you also have firmware and loads
the kernel at a hardcoded offset. This series changes that so we only
load the kernel at an offset if a firmware (-bios) was loaded.

This series also adds a function to check if the CPU is 32-bit. This is
a step towards running 32-bit and 64-bit CPUs on the 64-bit RISC-V build
by using run time checks instead of compile time checks. We also allow
the user to sepcify a CPU for the sifive_u machine.

Alistair Francis (4):
  hw/riscv: sifive_u: Allow specifying the CPU
  hw/riscv: Return the end address of the loaded firmware
  hw/riscv: Add a riscv_is_32_bit() function
  hw/riscv: Load the kernel after the firmware

 include/hw/riscv/boot.h | 13 ++---
 include/hw/riscv/sifive_u.h |  1 +
 hw/riscv/boot.c | 56 ++---
 hw/riscv/opentitan.c|  3 +-
 hw/riscv/sifive_e.c |  3 +-
 hw/riscv/sifive_u.c | 28 ++-
 hw/riscv/spike.c| 11 ++--
 hw/riscv/virt.c | 11 ++--
 8 files changed, 91 insertions(+), 35 deletions(-)

-- 
2.28.0




[PATCH v2 1/4] hw/riscv: sifive_u: Allow specifying the CPU

2020-10-13 Thread Alistair Francis
Allow the user to specify the main application CPU for the sifive_u
machine.

Signed-off-by: Alistair Francis 
Reviewed-by: Bin Meng 
---
 include/hw/riscv/sifive_u.h |  1 +
 hw/riscv/sifive_u.c | 18 +-
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 22e7e6efa1..a9f7b4a084 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -48,6 +48,7 @@ typedef struct SiFiveUSoCState {
 CadenceGEMState gem;
 
 uint32_t serial;
+char *cpu_type;
 } SiFiveUSoCState;
 
 #define TYPE_RISCV_U_MACHINE MACHINE_TYPE_NAME("sifive_u")
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 6ad975d692..5f3ad9bc0f 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -424,6 +424,8 @@ static void sifive_u_machine_init(MachineState *machine)
 object_initialize_child(OBJECT(machine), "soc", >soc, TYPE_RISCV_U_SOC);
 object_property_set_uint(OBJECT(>soc), "serial", s->serial,
  _abort);
+object_property_set_str(OBJECT(>soc), "cpu-type", machine->cpu_type,
+ _abort);
 qdev_realize(DEVICE(>soc), NULL, _abort);
 
 /* register RAM */
@@ -590,6 +592,11 @@ static void sifive_u_machine_class_init(ObjectClass *oc, 
void *data)
 mc->init = sifive_u_machine_init;
 mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + SIFIVE_U_COMPUTE_CPU_COUNT;
 mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
+#if defined(TARGET_RISCV32)
+mc->default_cpu_type = TYPE_RISCV_CPU_SIFIVE_U34;
+#elif defined(TARGET_RISCV64)
+mc->default_cpu_type = TYPE_RISCV_CPU_SIFIVE_U54;
+#endif
 mc->default_cpus = mc->min_cpus;
 
 object_class_property_add_bool(oc, "start-in-flash",
@@ -618,7 +625,6 @@ type_init(sifive_u_machine_init_register_types)
 
 static void sifive_u_soc_instance_init(Object *obj)
 {
-MachineState *ms = MACHINE(qdev_get_machine());
 SiFiveUSoCState *s = RISCV_U_SOC(obj);
 
 object_initialize_child(obj, "e-cluster", >e_cluster, TYPE_CPU_CLUSTER);
@@ -636,10 +642,6 @@ static void sifive_u_soc_instance_init(Object *obj)
 
 object_initialize_child(OBJECT(>u_cluster), "u-cpus", >u_cpus,
 TYPE_RISCV_HART_ARRAY);
-qdev_prop_set_uint32(DEVICE(>u_cpus), "num-harts", ms->smp.cpus - 1);
-qdev_prop_set_uint32(DEVICE(>u_cpus), "hartid-base", 1);
-qdev_prop_set_string(DEVICE(>u_cpus), "cpu-type", SIFIVE_U_CPU);
-qdev_prop_set_uint64(DEVICE(>u_cpus), "resetvec", 0x1004);
 
 object_initialize_child(obj, "prci", >prci, TYPE_SIFIVE_U_PRCI);
 object_initialize_child(obj, "otp", >otp, TYPE_SIFIVE_U_OTP);
@@ -661,6 +663,11 @@ static void sifive_u_soc_realize(DeviceState *dev, Error 
**errp)
 int i;
 NICInfo *nd = _table[0];
 
+qdev_prop_set_uint32(DEVICE(>u_cpus), "num-harts", ms->smp.cpus - 1);
+qdev_prop_set_uint32(DEVICE(>u_cpus), "hartid-base", 1);
+qdev_prop_set_string(DEVICE(>u_cpus), "cpu-type", s->cpu_type);
+qdev_prop_set_uint64(DEVICE(>u_cpus), "resetvec", 0x1004);
+
 sysbus_realize(SYS_BUS_DEVICE(>e_cpus), _abort);
 sysbus_realize(SYS_BUS_DEVICE(>u_cpus), _abort);
 /*
@@ -792,6 +799,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error 
**errp)
 
 static Property sifive_u_soc_props[] = {
 DEFINE_PROP_UINT32("serial", SiFiveUSoCState, serial, OTP_SERIAL),
+DEFINE_PROP_STRING("cpu-type", SiFiveUSoCState, cpu_type),
 DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.28.0




[PATCH v2 2/4] hw/riscv: Return the end address of the loaded firmware

2020-10-13 Thread Alistair Francis
Instead of returning the unused entry address from riscv_load_firmware()
instead return the end address. Also return the end address from
riscv_find_and_load_firmware().

This tells the caller if a firmware was loaded and how big it is. This
can be used to determine the load address of the next image (usually the
kernel).

Signed-off-by: Alistair Francis 
---
 include/hw/riscv/boot.h |  8 
 hw/riscv/boot.c | 28 +---
 2 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 451338780a..0acbd8aa6e 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -23,10 +23,10 @@
 #include "exec/cpu-defs.h"
 #include "hw/loader.h"
 
-void riscv_find_and_load_firmware(MachineState *machine,
-  const char *default_machine_firmware,
-  hwaddr firmware_load_addr,
-  symbol_fn_t sym_cb);
+target_ulong riscv_find_and_load_firmware(MachineState *machine,
+  const char *default_machine_firmware,
+  hwaddr firmware_load_addr,
+  symbol_fn_t sym_cb);
 char *riscv_find_firmware(const char *firmware_filename);
 target_ulong riscv_load_firmware(const char *firmware_filename,
  hwaddr firmware_load_addr,
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 21adaae56e..fa699308a0 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -40,12 +40,13 @@
 #define fw_dynamic_info_data(__val) cpu_to_le64(__val)
 #endif
 
-void riscv_find_and_load_firmware(MachineState *machine,
-  const char *default_machine_firmware,
-  hwaddr firmware_load_addr,
-  symbol_fn_t sym_cb)
+target_ulong riscv_find_and_load_firmware(MachineState *machine,
+  const char *default_machine_firmware,
+  hwaddr firmware_load_addr,
+  symbol_fn_t sym_cb)
 {
 char *firmware_filename = NULL;
+target_ulong firmware_end_addr = firmware_load_addr;
 
 if ((!machine->firmware) || (!strcmp(machine->firmware, "default"))) {
 /*
@@ -60,9 +61,12 @@ void riscv_find_and_load_firmware(MachineState *machine,
 
 if (firmware_filename) {
 /* If not "none" load the firmware */
-riscv_load_firmware(firmware_filename, firmware_load_addr, sym_cb);
+firmware_end_addr = riscv_load_firmware(firmware_filename,
+firmware_load_addr, sym_cb);
 g_free(firmware_filename);
 }
+
+return firmware_end_addr;
 }
 
 char *riscv_find_firmware(const char *firmware_filename)
@@ -91,17 +95,19 @@ target_ulong riscv_load_firmware(const char 
*firmware_filename,
  hwaddr firmware_load_addr,
  symbol_fn_t sym_cb)
 {
-uint64_t firmware_entry;
+uint64_t firmware_entry, firmware_size, firmware_end;
 
 if (load_elf_ram_sym(firmware_filename, NULL, NULL, NULL,
- _entry, NULL, NULL, NULL,
+ _entry, NULL, _end, NULL,
  0, EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
-return firmware_entry;
+return firmware_end;
 }
 
-if (load_image_targphys_as(firmware_filename, firmware_load_addr,
-   ram_size, NULL) > 0) {
-return firmware_load_addr;
+firmware_size = load_image_targphys_as(firmware_filename,
+   firmware_load_addr, ram_size, NULL);
+
+if (firmware_size > 0) {
+return firmware_load_addr + firmware_size;
 }
 
 error_report("could not load firmware '%s'", firmware_filename);
-- 
2.28.0




Re: [PATCH] linux-user/elfload: Avoid leaking interp_name using GLib memory API

2020-10-13 Thread Richard Henderson
On 10/3/20 10:49 AM, Philippe Mathieu-Daudé wrote:
> Fix an unlikely memory leak in load_elf_image().
> 
> Fixes: bf858897b7 ("linux-user: Re-use load_elf_image for the main binary.")
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  linux-user/elfload.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)

Thanks, looks good.  I'll pull this into my bti patch set, in which you noticed
the problem.


r~



Re: [Qemu-devel][PATCH v6 1/6] x86/cpu: Rename XSAVE related feature words.

2020-10-13 Thread Sean Christopherson
On Tue, Oct 13, 2020 at 01:19:30PM +0800, Yang Weijiang wrote:
> With more components in XSS being developed on Intel platform,
> it's necessary to clean up existing XSAVE related feature words to
> make the name clearer. It's to prepare for adding CET related support
> in following patches.
> 
> Signed-off-by: Yang Weijiang 
> ---
>  target/i386/cpu.c| 60 
>  target/i386/cpu.h|  6 ++--
>  target/i386/fpu_helper.c |  2 +-
>  target/i386/translate.c  |  2 +-
>  4 files changed, 35 insertions(+), 35 deletions(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 588f32e136..e2891740f1 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -1050,7 +1050,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] 
> = {
>  .tcg_features = 0,
>  .unmigratable_flags = 0,
>  },
> -[FEAT_XSAVE] = {
> +[FEAT_XSAVE_INSTRUCTION] = {

The COMP->XCRO change is great, but I don't think XSAVE->XSAVE_INSTRUCTION
makes sense.  There is no guarantee the word will only be used for
instructions; it already blurs the line, e.g. XSAVEC also changes the behavior
of XRSTOR, and XSAVES also means the XSS MSR is available.

FWIW, I also don't find FEAT_XSAVE to be confusing.

>  .type = CPUID_FEATURE_WORD,
>  .feat_names = {
>  "xsaveopt", "xsavec", "xgetbv1", "xsaves",
> @@ -1084,7 +1084,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] 
> = {
>  .cpuid = { .eax = 6, .reg = R_EAX, },
>  .tcg_features = TCG_6_EAX_FEATURES,
>  },
> -[FEAT_XSAVE_COMP_LO] = {
> +[FEAT_XSAVE_XCR0_LO] = {
>  .type = CPUID_FEATURE_WORD,
>  .cpuid = {
>  .eax = 0xD,



Re: [PATCH 0/2] hw/mips/malta: Minor housekeeping in mips_malta_init()

2020-10-13 Thread Richard Henderson
On 10/12/20 9:05 AM, Philippe Mathieu-Daudé wrote:
> Philippe Mathieu-Daudé (2):
>   hw/mips/malta: Move gt64120 related code together
>   hw/mips/malta: Use clearer qdev style

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 0/5] hw: Replace some magic by definitions

2020-10-13 Thread Richard Henderson
On 10/12/20 6:20 AM, Philippe Mathieu-Daudé wrote:
> Philippe Mathieu-Daudé (5):
>   hw: Replace magic value by PCI_NUM_PINS definition
>   hw/pci-host/pam: Use ARRAY_SIZE() instead of magic value
>   hw/pci-host/versatile: Add the MEMORY_WINDOW_COUNT definition
>   hw/pci-host/versatile: Add the PCI_BAR_COUNT definition
>   tests/qtest: Replace magic value by NANOSECONDS_PER_SECOND definition

Reviewed-by: Richard Henderson 

r~



Re: [PATCH] accel/tcg: Add CPU_LOG_EXEC tracing for cpu_io_recompile()

2020-10-13 Thread Richard Henderson
On 10/13/20 5:26 AM, Peter Maydell wrote:
> When using -icount, it's useful for the CPU_LOG_EXEC logging
> to include information about when cpu_io_recompile() was
> called, because it alerts the reader of the log that the
> tracing of a previous TB execution may not actually
> correspond to an actually executed instruction. For instance
> if you're using -icount and also -singlestep then a guest
> instruction that makes an IO access appears in two
> "Trace" lines, once in a TB that triggers the cpu_io_recompile()
> and then again in the TB that actually executes.
> 
> (This is a similar reason to why the "Stopped execution of
> TB chain before..." logging in cpu_tb_exec() is helpful
> when trying to track execution flow in the logs.)
> 
> Signed-off-by: Peter Maydell 

Thanks, queued to tcg-next.


r~

> ---
>  accel/tcg/translate-all.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
> index d76097296df..4572b4901fb 100644
> --- a/accel/tcg/translate-all.c
> +++ b/accel/tcg/translate-all.c
> @@ -2267,6 +2267,10 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
>  tb_destroy(tb);
>  }
>  
> +qemu_log_mask_and_addr(CPU_LOG_EXEC, tb->pc,
> +   "cpu_io_recompile: rewound execution of TB to "
> +   TARGET_FMT_lx "\n", tb->pc);
> +
>  /* TODO: If env->pc != tb->pc (i.e. the faulting instruction was not
>   * the first in the TB) then we end up generating a whole new TB and
>   *  repeating the fault, which is horribly inefficient.
> 




Re: [RFC PATCH 0/3] target/mips: Make the number of TLB entries a CPU property

2020-10-13 Thread Richard Henderson
On 10/13/20 6:25 AM, Philippe Mathieu-Daudé wrote:
> Yocto developers have expressed interest in running MIPS32
> CPU with custom number of TLB:
> https://lists.gnu.org/archive/html/qemu-devel/2020-10/msg03428.html
> 
> Help them by making the number of TLB entries a CPU property,
> keeping our set of CPU definitions in sync with real hardware.

You mean keeping the 34kf model within qemu in sync, rather than creating a
nonsense model that doesn't exist.

Question: is this cpu parameter useful for anything else?

Because the ideal solution for a CI loop is to use one of the mips cpu models
that has the hw page table walker (CP0C3_PW).  Having qemu being able to refill
the tlb itself is massively faster.

We do not currently implement a mips cpu that has the PW.  When I downloaded
the document set in 2014, I only got the mips64-pra and neglected to get the
mips32-pra.  So I don't actually know if the PW applies to mips32.  I do know
that there's nothing in the kernel that ifdefs around it.

So:

(1) anyone know if the PW incompatible with mips32?
(2) if not, was there any mips32 hw built with PW
that we could model?
(3) if not, would a cpu parameter to force-enable PW
for any r2+ cpu be more useful that frobbing the
number of tlb entries?


r~



[PATCH v2 4/7] i386: Add default_version parameter to CPU version functions

2020-10-13 Thread Eduardo Habkost
Currently, the functions that resolve CPU model versions
(x86_cpu_model_resolve_version(), x86_cpu_model_resolve_alias())
need a machine to be initialized first.  Get rid of this
requirement by making those functions get an explicit
default_version argument.

No behavior changes are introduced by this patch, as all callers
are being changed to use default_cpu_version as argument.

Signed-off-by: Eduardo Habkost 
---
 target/i386/cpu.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 2c8dd3fa32..c78b2abfb8 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4158,11 +4158,12 @@ static X86CPUVersion x86_cpu_model_last_version(const 
X86CPUModel *model)
 }
 
 /* Return the actual version being used for a specific CPU model */
-static X86CPUVersion x86_cpu_model_resolve_version(const X86CPUModel *model)
+static X86CPUVersion x86_cpu_model_resolve_version(const X86CPUModel *model,
+   X86CPUVersion 
default_version)
 {
 X86CPUVersion v = model->version;
 if (v == CPU_VERSION_AUTO) {
-v = default_cpu_version;
+v = default_version;
 }
 if (v == CPU_VERSION_LATEST) {
 return x86_cpu_model_last_version(model);
@@ -4171,14 +4172,15 @@ static X86CPUVersion 
x86_cpu_model_resolve_version(const X86CPUModel *model)
 }
 
 /* Resolve CPU model alias to actual CPU model name */
-static char *x86_cpu_model_resolve_alias(const X86CPUModel *model)
+static char *x86_cpu_model_resolve_alias(const X86CPUModel *model,
+ X86CPUVersion default_version)
 {
 X86CPUVersion version;
 
 if (!model->is_alias) {
 return NULL;
 }
-version = x86_cpu_model_resolve_version(model);
+version = x86_cpu_model_resolve_version(model, default_version);
 if (version <= 0) {
 return NULL;
 }
@@ -5004,7 +5006,8 @@ static void x86_cpu_definition_entry(gpointer data, 
gpointer user_data)
  * doesn't break compatibility with previous QEMU versions.
  */
 if (cc->model && default_cpu_version != CPU_VERSION_LEGACY) {
-info->alias_of = x86_cpu_model_resolve_alias(cc->model);
+info->alias_of = x86_cpu_model_resolve_alias(cc->model,
+ default_cpu_version);
 info->has_alias_of = !!info->alias_of;
 }
 
@@ -5075,7 +5078,8 @@ static void x86_cpu_apply_props(X86CPU *cpu, PropValue 
*props)
 static void x86_cpu_apply_version_props(X86CPU *cpu, X86CPUModel *model)
 {
 const X86CPUVersionDefinition *vdef;
-X86CPUVersion version = x86_cpu_model_resolve_version(model);
+X86CPUVersion version = x86_cpu_model_resolve_version(model,
+  default_cpu_version);
 
 if (version == CPU_VERSION_LEGACY) {
 return;
-- 
2.28.0




[PATCH v2 7/7] cpu: Add `machine` parameter to query-cpu-definitions

2020-10-13 Thread Eduardo Habkost
The new parameter can be used by management software to query for
CPU model alias information for multiple machines without
restarting QEMU.

Signed-off-by: Eduardo Habkost 
---
Changes v1 -> v2:
* Rewrite documentation, with suggestions from Markus
---
 qapi/machine-target.json   | 14 ++-
 target/arm/helper.c|  4 +-
 target/i386/cpu.c  | 24 ++-
 target/mips/helper.c   |  4 +-
 target/s390x/cpu_models.c  |  4 +-
 target/ppc/translate_init.c.inc|  4 +-
 tests/acceptance/x86_cpu_model_versions.py | 48 ++
 7 files changed, 95 insertions(+), 7 deletions(-)

diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index 698850cc78..211cb2d7c9 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -282,6 +282,10 @@
 #
 # @alias-of: Name of CPU model this model is an alias for.  The target of the
 #CPU model alias may change depending on the machine type.
+#If the @machine argument was provided to query-cpu-definitions,
+#alias information for that machine type will be returned.
+#If @machine is not provided, alias information for
+#the current machine will be returned.
 #Management software is supposed to translate CPU model aliases
 #in the VM configuration, because aliases may stop being
 #migration-safe in the future (since 4.1)
@@ -318,9 +322,17 @@
 #
 # Return a list of supported virtual CPU definitions
 #
+# @machine: Name of machine type.  The value of the @alias-of field
+#   is machine-specific.  This overrides the machine type
+#   used to look up that information.  This can be used
+#   to query machine-specific CPU model aliases without
+#   restarting QEMU (since 5.2)
+#
 # Returns: a list of CpuDefInfo
 #
 # Since: 1.2.0
 ##
-{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'],
+{ 'command': 'query-cpu-definitions',
+  'data': { '*machine': 'str' },
+  'returns': ['CpuDefinitionInfo'],
   'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) || 
defined(TARGET_S390X) || defined(TARGET_MIPS)' }
diff --git a/target/arm/helper.c b/target/arm/helper.c
index cd0779ff5f..fc339a19ba 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8276,7 +8276,9 @@ static void arm_cpu_add_definition(gpointer data, 
gpointer user_data)
 *cpu_list = entry;
 }
 
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+CpuDefinitionInfoList *qmp_query_cpu_definitions(bool has_machine,
+ const char *machine,
+ Error **errp)
 {
 CpuDefinitionInfoList *cpu_list = NULL;
 GSList *list;
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 0807d12ffa..d78ff6a563 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -56,6 +56,7 @@
 #ifndef CONFIG_USER_ONLY
 #include "exec/address-spaces.h"
 #include "hw/i386/apic_internal.h"
+#include "hw/i386/pc.h"
 #include "hw/boards.h"
 #endif
 
@@ -4187,6 +4188,13 @@ static char *x86_cpu_model_resolve_alias(const 
X86CPUModel *model,
 }
 return x86_cpu_versioned_model_name(model->cpudef, version);
 }
+
+static X86CPUVersion default_cpu_version_for_machine(MachineClass *mc)
+{
+PCMachineClass *pcmc =
+(PCMachineClass *)object_class_dynamic_cast(OBJECT_CLASS(mc), 
TYPE_PC_MACHINE);
+return pcmc ? pcmc->default_cpu_version : 1;
+}
 #endif
 
 void x86_cpu_change_kvm_default(const char *prop, const char *value)
@@ -5027,12 +5035,24 @@ static void x86_cpu_definition_entry(gpointer data, 
gpointer user_data)
 args->cpu_list = entry;
 }
 
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+CpuDefinitionInfoList *qmp_query_cpu_definitions(bool has_machine,
+ const char *machine,
+ Error **errp)
 {
 X86CPUDefinitionArgs args = { .cpu_list = NULL };
 GSList *list = get_sorted_cpu_model_list();
 
-args.default_version = default_cpu_version;
+if (!has_machine) {
+args.default_version = default_cpu_version;
+} else {
+MachineClass *mc = machine_find_class(machine);
+if (!mc) {
+error_setg(errp, "Machine type '%s' not found", machine);
+return NULL;
+}
+args.default_version = default_cpu_version_for_machine(mc);
+}
+
 g_slist_foreach(list, x86_cpu_definition_entry, );
 g_slist_free(list);
 return args.cpu_list;
diff --git a/target/mips/helper.c b/target/mips/helper.c
index afd78b1990..33351e9578 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -1518,7 +1518,9 @@ static void mips_cpu_add_definition(gpointer data, 
gpointer user_data)
 *cpu_list = entry;
 }
 
-CpuDefinitionInfoList 

[PATCH v2 3/7] i386: Replace x86_cpu_class_get_alias_of() with x86_cpu_model_resolve_alias()

2020-10-13 Thread Eduardo Habkost
New function is very similar to the old function, but it just
takes a X86CPUModel as argument, and its name makes its purpose
clearer.

Signed-off-by: Eduardo Habkost 
---
 target/i386/cpu.c | 33 +
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 43e633ddd3..2c8dd3fa32 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4170,6 +4170,21 @@ static X86CPUVersion x86_cpu_model_resolve_version(const 
X86CPUModel *model)
 return v;
 }
 
+/* Resolve CPU model alias to actual CPU model name */
+static char *x86_cpu_model_resolve_alias(const X86CPUModel *model)
+{
+X86CPUVersion version;
+
+if (!model->is_alias) {
+return NULL;
+}
+version = x86_cpu_model_resolve_version(model);
+if (version <= 0) {
+return NULL;
+}
+return x86_cpu_versioned_model_name(model->cpudef, version);
+}
+
 void x86_cpu_change_kvm_default(const char *prop, const char *value)
 {
 PropValue *pv;
@@ -4913,20 +4928,6 @@ static char *x86_cpu_class_get_model_id(X86CPUClass *xc)
 return r;
 }
 
-static char *x86_cpu_class_get_alias_of(X86CPUClass *cc)
-{
-X86CPUVersion version;
-
-if (!cc->model || !cc->model->is_alias) {
-return NULL;
-}
-version = x86_cpu_model_resolve_version(cc->model);
-if (version <= 0) {
-return NULL;
-}
-return x86_cpu_versioned_model_name(cc->model->cpudef, version);
-}
-
 static void x86_cpu_list_entry(gpointer data, gpointer user_data)
 {
 ObjectClass *oc = data;
@@ -5002,8 +5003,8 @@ static void x86_cpu_definition_entry(gpointer data, 
gpointer user_data)
  * Old machine types won't report aliases, so that alias translation
  * doesn't break compatibility with previous QEMU versions.
  */
-if (default_cpu_version != CPU_VERSION_LEGACY) {
-info->alias_of = x86_cpu_class_get_alias_of(cc);
+if (cc->model && default_cpu_version != CPU_VERSION_LEGACY) {
+info->alias_of = x86_cpu_model_resolve_alias(cc->model);
 info->has_alias_of = !!info->alias_of;
 }
 
-- 
2.28.0




[PATCH v2 6/7] i386: Don't use default_cpu_version inside x86_cpu_definition_entry()

2020-10-13 Thread Eduardo Habkost
We will change query-cpu-definitions to have a new `machine`
parameter.  Move the code that reads default_cpu_version to
qmp_query_cpu_definitions() to make that easier to implement.

This patch shouldn't introduce any behavior change.  Results of
query-cpu-definition will be exactly the same.

Signed-off-by: Eduardo Habkost 
---
 target/i386/cpu.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index bf4b4a4812..0807d12ffa 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4990,11 +4990,16 @@ void x86_cpu_list(void)
 }
 
 #ifndef CONFIG_USER_ONLY
+typedef struct X86CPUDefinitionArgs {
+CpuDefinitionInfoList *cpu_list;
+X86CPUVersion default_version;
+} X86CPUDefinitionArgs;
+
 static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
 {
 ObjectClass *oc = data;
 X86CPUClass *cc = X86_CPU_CLASS(oc);
-CpuDefinitionInfoList **cpu_list = user_data;
+X86CPUDefinitionArgs *args = user_data;
 CpuDefinitionInfoList *entry;
 CpuDefinitionInfo *info;
 
@@ -5010,25 +5015,27 @@ static void x86_cpu_definition_entry(gpointer data, 
gpointer user_data)
  * Old machine types won't report aliases, so that alias translation
  * doesn't break compatibility with previous QEMU versions.
  */
-if (cc->model && default_cpu_version != CPU_VERSION_LEGACY) {
+if (cc->model && args->default_version != CPU_VERSION_LEGACY) {
 info->alias_of = x86_cpu_model_resolve_alias(cc->model,
- default_cpu_version);
+ args->default_version);
 info->has_alias_of = !!info->alias_of;
 }
 
 entry = g_malloc0(sizeof(*entry));
 entry->value = info;
-entry->next = *cpu_list;
-*cpu_list = entry;
+entry->next = args->cpu_list;
+args->cpu_list = entry;
 }
 
 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 {
-CpuDefinitionInfoList *cpu_list = NULL;
+X86CPUDefinitionArgs args = { .cpu_list = NULL };
 GSList *list = get_sorted_cpu_model_list();
-g_slist_foreach(list, x86_cpu_definition_entry, _list);
+
+args.default_version = default_cpu_version;
+g_slist_foreach(list, x86_cpu_definition_entry, );
 g_slist_free(list);
-return cpu_list;
+return args.cpu_list;
 }
 #endif
 
-- 
2.28.0




[PATCH v2 0/7] i386: Add `machine` parameter to query-cpu-definitions

2020-10-13 Thread Eduardo Habkost
Changes v1 -> v2:
* Rewrite documentation, with suggestions from Markus
* Try to reduce churn and keep the existing default_cpu_version
  static variable
* Replace x86_cpu_class_get_alias_of() with x86_cpu_model_resolve_alias()

Link to v1:
https://lore.kernel.org/qemu-devel/20191025022553.25298-1-ehabk...@redhat.com

We had introduced versioned CPU models in QEMU 4.1, including a
method for querying for CPU model versions using
query-cpu-definitions.  This solution had one problem: fetching
CPU alias information for multiple machine types required
restarting QEMU for each machine being queried.

This series adds a new `machine` parameter to
query-cpu-definitions, that can be used to query CPU model alias
information for multiple machines without restarting QEMU.

About CPU model versioning vs query-cpu-model-expansion
---

There had been some discussion[1] about using a mechanism for
this similar to what's done in s390x, based on
query-cpu-model-expansion.  I had considered that approach in the
beginning, but this would require
  query-cpu-model-expansion type=static
to resolve to a useful base CPU model that is static.

Unfortunately, we have no useful static CPU model in x86 yet,
except for "base", because of the complex accelerator-dependent
rules that affect expansion of CPU models.  Maybe in the future
we'll be able to define static versions of each CPU model, and
unify the CPU model versioning approaches in all architectures.

While we don't have this, we need to work with what we have.
What we have today in x86 are CPU models that are not static and
not accelerator-independent.

[1] 
https://lore.kernel.org/qemu-devel/dbf9e4c1-0acf-9469-84f9-f80c41e2c...@redhat.com/

Eduardo Habkost (7):
  machine: machine_find_class() function
  i386: Add X86CPUModel.alias_of field
  i386: Replace x86_cpu_class_get_alias_of() with
x86_cpu_model_resolve_alias()
  i386: Add default_version parameter to CPU version functions
  i386: Wrap QMP code in !CONFIG_USER_ONLY
  i386: Don't use default_cpu_version inside x86_cpu_definition_entry()
  cpu: Add `machine` parameter to query-cpu-definitions

 qapi/machine-target.json   |  14 ++-
 include/hw/boards.h|   2 +
 hw/core/machine.c  |  16 
 softmmu/vl.c   |  17 +---
 target/arm/helper.c|   4 +-
 target/i386/cpu.c  | 105 +++--
 target/mips/helper.c   |   4 +-
 target/s390x/cpu_models.c  |   4 +-
 target/ppc/translate_init.c.inc|   4 +-
 tests/acceptance/x86_cpu_model_versions.py |  48 ++
 10 files changed, 167 insertions(+), 51 deletions(-)

-- 
2.28.0





[PATCH v2 2/7] i386: Add X86CPUModel.alias_of field

2020-10-13 Thread Eduardo Habkost
Instead of calling x86_cpu_class_get_alias_of(), just save the
actual CPU model name in X86CPUModel and use it in `-cpu help`.

Signed-off-by: Eduardo Habkost 
---
 target/i386/cpu.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 9eafbe3690..43e633ddd3 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1647,6 +1647,12 @@ struct X86CPUModel {
  * This matters only for "-cpu help" and query-cpu-definitions
  */
 bool is_alias;
+/*
+ * Valid only if is_alias is true.
+ * If NULL, actual alias depend on machine type.
+ * If not NULL, name of actual CPU model this is an alias to.
+ */
+const char *alias_of;
 };
 
 /* Get full model name for CPU version */
@@ -4927,14 +4933,13 @@ static void x86_cpu_list_entry(gpointer data, gpointer 
user_data)
 X86CPUClass *cc = X86_CPU_CLASS(oc);
 g_autofree char *name = x86_cpu_class_get_model_name(cc);
 g_autofree char *desc = g_strdup(cc->model_description);
-g_autofree char *alias_of = x86_cpu_class_get_alias_of(cc);
 g_autofree char *model_id = x86_cpu_class_get_model_id(cc);
 
-if (!desc && alias_of) {
-if (cc->model && cc->model->version == CPU_VERSION_AUTO) {
+if (!desc && cc->model && cc->model->is_alias) {
+if (!cc->model->alias_of) {
 desc = g_strdup("(alias configured by machine type)");
 } else {
-desc = g_strdup_printf("(alias of %s)", alias_of);
+desc = g_strdup_printf("(alias of %s)", cc->model->alias_of);
 }
 }
 if (!desc && cc->model && cc->model->note) {
@@ -5418,6 +5423,7 @@ static void x86_register_cpudef_types(X86CPUDefinition 
*def)
 m->cpudef = def;
 m->version = CPU_VERSION_AUTO;
 m->is_alias = true;
+m->alias_of = NULL; /* depends on machine type */
 x86_register_cpu_model_type(def->name, m);
 
 /* Versioned models: */
@@ -5436,6 +5442,7 @@ static void x86_register_cpudef_types(X86CPUDefinition 
*def)
 am->cpudef = def;
 am->version = vdef->version;
 am->is_alias = true;
+am->alias_of = g_strdup(name);
 x86_register_cpu_model_type(vdef->alias, am);
 }
 }
-- 
2.28.0




[PATCH v2 5/7] i386: Wrap QMP code in !CONFIG_USER_ONLY

2020-10-13 Thread Eduardo Habkost
The QMP code was never called by *-user, and we will add
machine-type-specific code there, so add #ifdefs to make it safe.

Signed-off-by: Eduardo Habkost 
---
 target/i386/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index c78b2abfb8..bf4b4a4812 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4171,6 +4171,7 @@ static X86CPUVersion x86_cpu_model_resolve_version(const 
X86CPUModel *model,
 return v;
 }
 
+#ifndef CONFIG_USER_ONLY
 /* Resolve CPU model alias to actual CPU model name */
 static char *x86_cpu_model_resolve_alias(const X86CPUModel *model,
  X86CPUVersion default_version)
@@ -4186,6 +4187,7 @@ static char *x86_cpu_model_resolve_alias(const 
X86CPUModel *model,
 }
 return x86_cpu_versioned_model_name(model->cpudef, version);
 }
+#endif
 
 void x86_cpu_change_kvm_default(const char *prop, const char *value)
 {
@@ -4838,6 +4840,7 @@ static void x86_cpu_get_unavailable_features(Object *obj, 
Visitor *v,
 visit_type_strList(v, "unavailable-features", , errp);
 }
 
+#ifndef CONFIG_USER_ONLY
 /* Check for missing features that may prevent the CPU class from
  * running using the current machine and accelerator.
  */
@@ -4876,6 +4879,7 @@ static void 
x86_cpu_class_check_missing_features(X86CPUClass *xcc,
 
 object_unref(OBJECT(xc));
 }
+#endif
 
 /* Print all cpuid feature names in featureset
  */
@@ -4985,6 +4989,7 @@ void x86_cpu_list(void)
 g_list_free(names);
 }
 
+#ifndef CONFIG_USER_ONLY
 static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
 {
 ObjectClass *oc = data;
@@ -5025,6 +5030,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error 
**errp)
 g_slist_free(list);
 return cpu_list;
 }
+#endif
 
 static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
bool migratable_only)
-- 
2.28.0




[PATCH v2 1/7] machine: machine_find_class() function

2020-10-13 Thread Eduardo Habkost
Move find_machine() from vl.c to core/machine.c and rename it to
machine_find_class(), so it can be reused by other code.

The function won't reuse the results of the previous
object_class_get_list() call like it did in vl.c, but this
shouldn't be a problem because the function is expected to be
called only once during regular QEMU usage.

Signed-off-by: Eduardo Habkost 
---
 include/hw/boards.h |  2 ++
 hw/core/machine.c   | 16 
 softmmu/vl.c| 17 +
 3 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/include/hw/boards.h b/include/hw/boards.h
index bf53e8a16e..922b710be3 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -43,6 +43,8 @@ void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, 
const char *type);
 MemoryRegion *machine_consume_memdev(MachineState *machine,
  HostMemoryBackend *backend);
 
+MachineClass *machine_find_class(const char *name);
+
 /**
  * CPUArchId:
  * @arch_id - architecture-dependent CPU ID of present or possible CPU
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 7e2f4ec08e..879a596643 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1136,6 +1136,22 @@ void machine_run_board_init(MachineState *machine)
 machine_class->init(machine);
 }
 
+MachineClass *machine_find_class(const char *name)
+{
+g_autoptr(GSList) machines = object_class_get_list(TYPE_MACHINE, false);
+GSList *el;
+
+for (el = machines; el; el = el->next) {
+MachineClass *mc = el->data;
+
+if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
+return mc;
+}
+}
+
+return NULL;
+}
+
 static const TypeInfo machine_info = {
 .name = TYPE_MACHINE,
 .parent = TYPE_OBJECT,
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 254ee5e525..b74f377a1c 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -1159,21 +1159,6 @@ static int usb_parse(const char *cmdline)
 
 MachineState *current_machine;
 
-static MachineClass *find_machine(const char *name, GSList *machines)
-{
-GSList *el;
-
-for (el = machines; el; el = el->next) {
-MachineClass *mc = el->data;
-
-if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
-return mc;
-}
-}
-
-return NULL;
-}
-
 static MachineClass *find_default_machine(GSList *machines)
 {
 GSList *el;
@@ -2341,7 +2326,7 @@ static MachineClass *machine_parse(const char *name, 
GSList *machines)
 exit(0);
 }
 
-mc = find_machine(name, machines);
+mc = machine_find_class(name);
 if (!mc) {
 error_report("unsupported machine type");
 error_printf("Use -machine help to list supported machines\n");
-- 
2.28.0




Re: Why guest physical addresses are not the same as the corresponding host virtual addresses in QEMU/KVM? Thanks!

2020-10-13 Thread harry harry
Hi Sean,

Thanks much for your detailed replies. It's clear to me why GPAs are
different from HVAs in QEM/KVM. Thanks! I appreciate it if you could
help with the following two more questions.

On Tue, Oct 13, 2020 at 3:03 AM Sean Christopherson
 wrote:
>
> This is where memslots come in.  Think of memslots as a one-level page tablea
> that translate GPAs to HVAs.  A memslot, set by userspace, tells KVM the
> corresponding HVA for a given GPA.
>
> Before the guest is running (assuming host userspace isn't broken), the
> userspace VMM will first allocate virtual memory (HVA) for all physical
> memory it wants to map into the guest (GPA).  It then tells KVM how to
> translate a given GPA to its HVA by creating a memslot.
>
> To avoid getting lost in a tangent about page offsets, let's assume array[0]'s
> GPA = 0xa000.  For KVM to create a GPA->HPA mapping for the guest, there 
> _must_
> be a memslot that translates GPA 0xa000 to an HVA[*].  Let's say HVA = 0xb000.
>
> On an EPT violation, KVM does a memslot lookup to translate the GPA (0xa000) 
> to
> its HVA (0xb000), and then walks the host page tables to translate the HVA 
> into
> a HPA (let's say that ends up being 0xc000).  KVM then stuffs 0xc000 into the
> EPT tables, which yields:
>
>   GPA-> HVA(KVM memslots)
>   0xa0000xb000
>
>   HVA-> HPA(host page tables)
>   0xb0000xc000
>
>   GPA-> HPA(extended page tables)
>   0xa0000xc000
>
> To keep the EPT tables synchronized with the host page tables, if HVA->HPA
> changes, e.g. HVA 0xb000 is remapped to HPA 0xd000, then KVM will get notified
> by the host kernel that the HVA has been unmapped and will find and unmap
> the corresponding GPA (again via memslots) to HPA translations.
>
> Ditto for the case where userspace moves a memslot, e.g. if HVA is changed
> to 0xe000, KVM will first unmap all old GPA->HPA translations so that accesses
> to GPA 0xa000 from the guest will take an EPT violation and see the new HVA
> (and presumably a new HPA).

Q1: Is there any file like ``/proc/pid/pagemap'' to record the
mappings between GPAs and HVAs in the host OS?

Q2: Seems that there might be extra overhead (e.g., synchronization
between EPT tables and host regular page tables; maintaining extra
regular page tables and data structures), which is caused by the extra
translation between GPAs to HVAs via memslots. Why doesn't KVM
directly use GPAs as HVAs and leverage extended/nested page tables to
translate HVAs (i.e., GPAs) to HPAs?

Thanks,
Harry



Re: [PATCH 07/10] target/arm: Implement v8.1M low-overhead-loop instructions

2020-10-13 Thread Richard Henderson
On 10/12/20 8:37 AM, Peter Maydell wrote:
> +nextlabel = gen_new_label();
> +tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[a->rn], 0, nextlabel);
> +gen_jmp(s, read_pc(s) + a->imm);
> +
> +gen_set_label(nextlabel);
> +tmp = load_reg(s, a->rn);
> +store_reg(s, 14, tmp);
> +gen_jmp(s, s->base.pc_next);
> +return true;

Oh, fwiw, with the tcg optimization patches just posted, this branch is better
inverted.  That way the load of rn can be reused on the non-taken branch path.

Maybe sometime I'll try to propagate the data to the taken path, but that
automatically requires extra memory allocation, so it'll be difficult to do
that without a tcg slowdown.


r~



Re: [PATCH v7 8/8] mac_oldworld: Add SPD data to cover RAM

2020-10-13 Thread BALATON Zoltan via

On Wed, 14 Oct 2020, BALATON Zoltan via wrote:

On Tue, 13 Oct 2020, Philippe Mathieu-Daudé wrote:

On 6/29/20 8:55 PM, BALATON Zoltan wrote:

This patch is more complex as it should be which I intend to fix once
agreement can be made on how to get back the necessary functionality
removed by previous patches. See in this thread:
https://lists.nongnu.org/archive/html/qemu-devel/2020-06/msg08710.html

Signed-off-by: BALATON Zoltan 
---


I plan to rewrite this patch eliminating this part and un-breaking 
spd_data_generate() instead to allow it to signal an error again so we don't 
need to duplicate part of it here to avoid aborting. (You may remember the 
thread where this was discussed in, I don't have a link to it now.) So just


Oh, I actually have the link in the commit message... Maybe I should also 
read what I write sometimes.


Regards,
BALATON Zoltan

[PATCH 2/2] tcg/optimize: Flush data at labels not TCG_OPF_BB_END

2020-10-13 Thread Richard Henderson
We can easily propagate temp values through the entire extended
basic block (in this case, the set of blocks connected by fallthru),
simply by not discarding the register state at the branch.

Signed-off-by: Richard Henderson 
---
 tcg/optimize.c | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 220f4601d5..9952c28bdc 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -1484,29 +1484,30 @@ void tcg_optimize(TCGContext *s)
 }
 }
 }
-goto do_reset_output;
+/* fall through */
 
 default:
 do_default:
-/* Default case: we know nothing about operation (or were unable
-   to compute the operation result) so no propagation is done.
-   We trash everything if the operation is the end of a basic
-   block, otherwise we only trash the output args.  "mask" is
-   the non-zero bits mask for the first output arg.  */
-if (def->flags & TCG_OPF_BB_END) {
-bitmap_zero(temps_used.l, nb_temps);
-} else {
-do_reset_output:
-for (i = 0; i < nb_oargs; i++) {
-reset_temp(op->args[i]);
-/* Save the corresponding known-zero bits mask for the
-   first output argument (only one supported so far). */
-if (i == 0) {
-arg_info(op->args[i])->mask = mask;
-}
+/*
+ * Default case: we know nothing about operation (or were unable
+ * to compute the operation result) so no propagation is done.
+ */
+for (i = 0; i < nb_oargs; i++) {
+reset_temp(op->args[i]);
+/*
+ * Save the corresponding known-zero bits mask for the
+ * first output argument (only one supported so far).
+ */
+if (i == 0) {
+arg_info(op->args[i])->mask = mask;
 }
 }
 break;
+
+case INDEX_op_set_label:
+/* Trash everything at the start of a new extended bb. */
+bitmap_zero(temps_used.l, nb_temps);
+break;
 }
 
 /* Eliminate duplicate and redundant fence instructions.  */
-- 
2.25.1




[PATCH 0/2] tcg: optimize across branches

2020-10-13 Thread Richard Henderson
In several cases, it's easy to optimize across a non-taken branch
simply by *not* flushing the relevant tables.  This is true both
for value propagation and register allocation.

This comes up in quite a number of cases with arm, most simply in
how conditional execution is implemented.  But it also came up in
discussion of how to implement low-overhead looping for v8.1m.


r~


Richard Henderson (2):
  tcg: Do not kill globals at conditional branches
  tcg/optimize: Flush data at labels not TCG_OPF_BB_END

 include/tcg/tcg-opc.h |  7 +++---
 include/tcg/tcg.h |  4 +++-
 tcg/optimize.c| 35 ++-
 tcg/tcg.c | 55 +--
 4 files changed, 78 insertions(+), 23 deletions(-)

-- 
2.25.1




[PATCH 1/2] tcg: Do not kill globals at conditional branches

2020-10-13 Thread Richard Henderson
We can easily register allocate the entire extended basic block
(in this case, the set of blocks connected by fallthru), simply
by not discarding the register state at the branch.

This does not help blocks starting with a label, as they are
reached via a taken branch, and that would require saving the
complete register state at the branch.

Signed-off-by: Richard Henderson 
---
 include/tcg/tcg-opc.h |  7 +++---
 include/tcg/tcg.h |  4 +++-
 tcg/tcg.c | 55 +--
 3 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h
index e3929b80d2..67092e82c6 100644
--- a/include/tcg/tcg-opc.h
+++ b/include/tcg/tcg-opc.h
@@ -81,7 +81,7 @@ DEF(extract_i32, 1, 1, 2, IMPL(TCG_TARGET_HAS_extract_i32))
 DEF(sextract_i32, 1, 1, 2, IMPL(TCG_TARGET_HAS_sextract_i32))
 DEF(extract2_i32, 1, 2, 1, IMPL(TCG_TARGET_HAS_extract2_i32))
 
-DEF(brcond_i32, 0, 2, 2, TCG_OPF_BB_END)
+DEF(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH)
 
 DEF(add2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_add2_i32))
 DEF(sub2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_sub2_i32))
@@ -89,7 +89,8 @@ DEF(mulu2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_mulu2_i32))
 DEF(muls2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_muls2_i32))
 DEF(muluh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i32))
 DEF(mulsh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i32))
-DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | IMPL(TCG_TARGET_REG_BITS == 32))
+DEF(brcond2_i32, 0, 4, 2,
+TCG_OPF_BB_END | TCG_OPF_COND_BRANCH | IMPL(TCG_TARGET_REG_BITS == 32))
 DEF(setcond2_i32, 1, 4, 1, IMPL(TCG_TARGET_REG_BITS == 32))
 
 DEF(ext8s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8s_i32))
@@ -159,7 +160,7 @@ DEF(extrh_i64_i32, 1, 1, 0,
 IMPL(TCG_TARGET_HAS_extrh_i64_i32)
 | (TCG_TARGET_REG_BITS == 32 ? TCG_OPF_NOT_PRESENT : 0))
 
-DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | IMPL64)
+DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH | IMPL64)
 DEF(ext8s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8s_i64))
 DEF(ext16s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16s_i64))
 DEF(ext32s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext32s_i64))
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 8804a8c4a2..8ff9dad4ef 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -990,7 +990,7 @@ typedef struct TCGArgConstraint {
 
 #define TCG_MAX_OP_ARGS 16
 
-/* Bits for TCGOpDef->flags, 8 bits available.  */
+/* Bits for TCGOpDef->flags, 8 bits available, all used.  */
 enum {
 /* Instruction exits the translation block.  */
 TCG_OPF_BB_EXIT  = 0x01,
@@ -1008,6 +1008,8 @@ enum {
 TCG_OPF_NOT_PRESENT  = 0x20,
 /* Instruction operands are vectors.  */
 TCG_OPF_VECTOR   = 0x40,
+/* Instruction is a conditional branch. */
+TCG_OPF_COND_BRANCH  = 0x80
 };
 
 typedef struct TCGOpDef {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index a8c28440e2..f49f1a7f35 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2519,6 +2519,28 @@ static void la_global_sync(TCGContext *s, int ng)
 }
 }
 
+/*
+ * liveness analysis: conditional branch: all temps are dead,
+ * globals and local temps should be synced.
+ */
+static void la_bb_sync(TCGContext *s, int ng, int nt)
+{
+la_global_sync(s, ng);
+
+for (int i = ng; i < nt; ++i) {
+if (s->temps[i].temp_local) {
+int state = s->temps[i].state;
+s->temps[i].state = state | TS_MEM;
+if (state != TS_DEAD) {
+continue;
+}
+} else {
+s->temps[i].state = TS_DEAD;
+}
+la_reset_pref(>temps[i]);
+}
+}
+
 /* liveness analysis: sync globals back to memory and kill.  */
 static void la_global_kill(TCGContext *s, int ng)
 {
@@ -2795,6 +2817,8 @@ static void liveness_pass_1(TCGContext *s)
 /* If end of basic block, update.  */
 if (def->flags & TCG_OPF_BB_EXIT) {
 la_func_end(s, nb_globals, nb_temps);
+} else if (def->flags & TCG_OPF_COND_BRANCH) {
+la_bb_sync(s, nb_globals, nb_temps);
 } else if (def->flags & TCG_OPF_BB_END) {
 la_bb_end(s, nb_globals, nb_temps);
 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
@@ -2907,7 +2931,10 @@ static bool liveness_pass_2(TCGContext *s)
 nb_oargs = def->nb_oargs;
 
 /* Set flags similar to how calls require.  */
-if (def->flags & TCG_OPF_BB_END) {
+if (def->flags & TCG_OPF_COND_BRANCH) {
+/* Like reading globals: sync_globals */
+call_flags = TCG_CALL_NO_WRITE_GLOBALS;
+} else if (def->flags & TCG_OPF_BB_END) {
 /* Like writing globals: save_globals */
 call_flags = 0;
 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
@@ -3379,6 +3406,28 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, 
TCGRegSet allocated_regs)
 save_globals(s, allocated_regs);
 }
 
+/*
+ * At a conditional 

Re: [PATCH v7 8/8] mac_oldworld: Add SPD data to cover RAM

2020-10-13 Thread BALATON Zoltan via

On Tue, 13 Oct 2020, Philippe Mathieu-Daudé wrote:

On 6/29/20 8:55 PM, BALATON Zoltan wrote:

OpenBIOS gets RAM size via fw_cfg but rhe original board firmware


Typo "the".


detects RAM using SPD data so generate and add SDP eeproms to cover as


EEPROMs?


much RAM as possible to describe with SPD (this may be less than the
actual ram_size due to SDRAM size constraints).

This patch is more complex as it should be which I intend to fix once
agreement can be made on how to get back the necessary functionality
removed by previous patches. See in this thread:
https://lists.nongnu.org/archive/html/qemu-devel/2020-06/msg08710.html

Signed-off-by: BALATON Zoltan 
---
  hw/ppc/mac_oldworld.c | 19 ++-
  1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 6276973c95..6a27287c9f 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -34,6 +34,7 @@
  #include "hw/input/adb.h"
  #include "sysemu/sysemu.h"
  #include "net/net.h"
+#include "hw/i2c/smbus_eeprom.h"
  #include "hw/isa/isa.h"
  #include "hw/pci/pci.h"
  #include "hw/pci/pci_host.h"
@@ -104,6 +105,8 @@ static void ppc_heathrow_init(MachineState *machine)
  DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
  void *fw_cfg;
  uint64_t tbfreq;
+uint8_t *spd_data[3] = {};
+I2CBus *i2c_bus;
/* init CPUs */
  for (i = 0; i < smp_cpus; i++) {
@@ -121,8 +124,16 @@ static void ppc_heathrow_init(MachineState *machine)
   "maximum 2047 MB", ram_size / MiB);
  exit(1);
  }
-
  memory_region_add_subregion(get_system_memory(), 0, machine->ram);
+for (i = 0; i < 3; i++) {


3 -> ARRAY_SIZE(spd_data)


+int size_left = ram_size - i * 512 * MiB;
+if (size_left > 0) {
+uint32_t s = size_left / MiB;
+s = (s > 512 ? 512 : s);


MIN()?


Thanks for the review. (You forgot to cc Mark so maybe he missed the other 
R-b tags but hopefully patchwork will pick these up.)


I plan to rewrite this patch eliminating this part and un-breaking 
spd_data_generate() instead to allow it to signal an error again so we 
don't need to duplicate part of it here to avoid aborting. (You may 
remember the thread where this was discussed in, I don't have a link to it 
now.) So just disregard this one patch for now, I'll take your other 
suggestions in account when submitting a rewritten version.


This and the WIP CUDA i2c patches are not yet ready to be merged and you 
had alternative suggestion for [v7,6/7] i2c: Match parameters of 
i2c_start_transfer and i2c_send_recv, but was that ever merged? Do you 
plan to resubmit or send a ping for that? It may have been lost somewhere 
because I have those mails in my mailbox but could not find it in Patchew 
or Patchwork.


Other than these 3 patches in the series others (1-5) should be OK and 
hope most of those could be taken by Mark now in the upcoming Mac fixes 
series to reduce the size of outstanding patches then I can fix up or 
rewrite the remaining ones.


I'm still not sure what to do about the sign extension problem in 
include/hw/elf_ops.h that was holding back patch 1 so if anyone has a 
suggestion please tell me or feel free to propose any fix for it, I'm not 
confident enough to break the elf loader.


Regards,
BALATON Zoltan


+s = 1U << (31 - clz32(s));
+spd_data[i] = spd_data_generate(SDR, s * MiB);
+}
+}
/* allocate and load firmware ROM */
  memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", PROM_SIZE,
@@ -302,6 +313,12 @@ static void ppc_heathrow_init(MachineState *machine)
  macio_ide_init_drives(macio_ide, [MAX_IDE_DEVS]);
dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
+i2c_bus = I2C_BUS(qdev_get_child_bus(dev, "i2c"));
+for (i = 0; i < 3; i++) {


3 -> ARRAY_SIZE(spd_data)


+if (spd_data[i]) {
+smbus_eeprom_init_one(i2c_bus, 0x50 + i, spd_data[i]);
+}
+}
  adb_bus = qdev_get_child_bus(dev, "adb.0");
  dev = qdev_new(TYPE_ADB_KEYBOARD);
  qdev_realize_and_unref(dev, adb_bus, _fatal);






Re: [PATCH v3] SEV: QMP support for Inject-Launch-Secret

2020-10-13 Thread tobin

On 2020-10-12 12:49, Daniel P. Berrangé wrote:

On Mon, Oct 12, 2020 at 05:21:15PM +0100, Dr. David Alan Gilbert wrote:

* Tobin Feldman-Fitzthum (to...@linux.vnet.ibm.com) wrote:
> AMD SEV allows a guest owner to inject a secret blob
> into the memory of a virtual machine. The secret is
> encrypted with the SEV Transport Encryption Key and
> integrity is guaranteed with the Transport Integrity
> Key. Although QEMU faciliates the injection of the


Trivial typo  s/faciliates/facilitates/


> launch secret, it cannot access the secret.
>
> Signed-off-by: Tobin Feldman-Fitzthum 
> ---
>  include/monitor/monitor.h |  3 ++
>  include/sysemu/sev.h  |  2 ++
>  monitor/misc.c|  8 ++---
>  qapi/misc-target.json | 18 +++
>  target/i386/monitor.c |  9 ++
>  target/i386/sev-stub.c|  5 +++
>  target/i386/sev.c | 66 +++
>  target/i386/trace-events  |  1 +
>  8 files changed, 108 insertions(+), 4 deletions(-)




> diff --git a/qapi/misc-target.json b/qapi/misc-target.json
> index dee3b45930..d145f916b3 100644
> --- a/qapi/misc-target.json
> +++ b/qapi/misc-target.json
> @@ -200,6 +200,24 @@
>  { 'command': 'query-sev-capabilities', 'returns': 'SevCapability',
>'if': 'defined(TARGET_I386)' }
>
> +##
> +# @sev-inject-launch-secret:
> +#
> +# This command injects a secret blob into memory of SEV guest.
> +#
> +# @packet-header: the launch secret packet header encoded in base64
> +#
> +# @secret: the launch secret data to be injected encoded in base64


Just to double check, this "secret" is /not/ in clear text, so there's
no way either QEMU nor the QMP client can access sensitive info, right 
?



You are correct. QEMU would only be able to read the secret in the case
of serious user error.

Thank you for your feedback. I have rebased made the changes. Will send
new version in the morning.

-Tobin


If 'secret' was clear text, then we would need to pass the data across
QMP in a different way.


> +#
> +# @gpa: the guest physical address where secret will be injected.
> +#
> +# Since: 5.1


s/5.1/5.2/


> +#
> +##
> +{ 'command': 'sev-inject-launch-secret',
> +  'data': { 'packet-header': 'str', 'secret': 'str', 'gpa': 'uint64' },
> +  'if': 'defined(TARGET_I386)' }
> +
>  ##
>  # @dump-skeys:
>  #
> diff --git a/target/i386/monitor.c b/target/i386/monitor.c
> index 27ebfa3ad2..42bcfe6dc0 100644
> --- a/target/i386/monitor.c
> +++ b/target/i386/monitor.c
> @@ -736,3 +736,12 @@ SevCapability *qmp_query_sev_capabilities(Error **errp)
>
>  return data;
>  }
> +
> +void qmp_sev_inject_launch_secret(const char *packet_hdr,
> +  const char *secret, uint64_t gpa,
> +  Error **errp)
> +{
> +if (sev_inject_launch_secret(packet_hdr, secret, gpa) != 0) {
> +error_setg(errp, "SEV inject secret failed");


This generic error message is useless - sev_inject_launch_secret() 
needs

to take the 'errp' parameter and report what actually failed.


> +}
> +}
> diff --git a/target/i386/sev-stub.c b/target/i386/sev-stub.c
> index e5ee13309c..fed4588185 100644
> --- a/target/i386/sev-stub.c
> +++ b/target/i386/sev-stub.c
> @@ -48,3 +48,8 @@ SevCapability *sev_get_capabilities(void)
>  {
>  return NULL;
>  }
> +int sev_inject_launch_secret(const char *hdr, const char *secret,
> + uint64_t gpa)
> +{
> +return 1;
> +}
> diff --git a/target/i386/sev.c b/target/i386/sev.c
> index d273174ad3..cbeb8f2e02 100644
> --- a/target/i386/sev.c
> +++ b/target/i386/sev.c
> @@ -28,6 +28,8 @@
>  #include "sysemu/runstate.h"
>  #include "trace.h"
>  #include "migration/blocker.h"
> +#include "exec/address-spaces.h"
> +#include "monitor/monitor.h"
>
>  #define TYPE_SEV_GUEST "sev-guest"
>  #define SEV_GUEST(obj)  \
> @@ -769,6 +771,70 @@ sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t 
len)
>  return 0;
>  }
>
> +int sev_inject_launch_secret(const char *packet_hdr,
> + const char *secret, uint64_t gpa)
> +{
> +struct kvm_sev_launch_secret input;
> +guchar *data = NULL, *hdr = NULL;


If you declare with  'g_autofree' you don't need the manual 'g_free'
calls later. This in turn means you can get rid of the "goto err"
jumps and instead directly return.


> +int error, ret = 1;
> +void *hva;
> +gsize hdr_sz = 0, data_sz = 0;
> +Error *local_err = NULL;


Declare with

   g_autoptr(Error) local_err = NULL

to fix the leak David mentions



> +MemoryRegion *mr = NULL;
> +
> +/* secret can be inject only in this state */
> +if (!sev_check_state(sev_guest, SEV_STATE_LAUNCH_SECRET)) {
> +error_report("SEV: Not in correct state. (LSECRET) %x",
> + sev_guest->state);
> +return 1;
> +}
> +
> +hdr = g_base64_decode(packet_hdr, _sz);
> +if (!hdr || !hdr_sz) {
> +error_report("SEV: Failed to decode 

[PATCH v6 05/11] hw/block/nvme: Support Zoned Namespace Command Set

2020-10-13 Thread Dmitry Fomichev
The emulation code has been changed to advertise NVM Command Set when
"zoned" device property is not set (default) and Zoned Namespace
Command Set otherwise.

Define values and structures that are needed to support Zoned
Namespace Command Set (NVMe TP 4053) in PCI NVMe controller emulator.
Define trace events where needed in newly introduced code.

In order to improve scalability, all open, closed and full zones
are organized in separate linked lists. Consequently, almost all
zone operations don't require scanning of the entire zone array
(which potentially can be quite large) - it is only necessary to
enumerate one or more zone lists.

Handlers for three new NVMe commands introduced in Zoned Namespace
Command Set specification are added, namely for Zone Management
Receive, Zone Management Send and Zone Append.

Device initialization code has been extended to create a proper
configuration for zoned operation using device properties.

Read/Write command handler is modified to only allow writes at the
write pointer if the namespace is zoned. For Zone Append command,
writes implicitly happen at the write pointer and the starting write
pointer value is returned as the result of the command. Write Zeroes
handler is modified to add zoned checks that are identical to those
done as a part of Write flow.

Subsequent commits in this series add ZDE support and checks for
active and open zone limits.

Signed-off-by: Niklas Cassel 
Signed-off-by: Hans Holmberg 
Signed-off-by: Ajay Joshi 
Signed-off-by: Chaitanya Kulkarni 
Signed-off-by: Matias Bjorling 
Signed-off-by: Aravind Ramesh 
Signed-off-by: Shin'ichiro Kawasaki 
Signed-off-by: Adam Manzanares 
Signed-off-by: Dmitry Fomichev 
---
 block/nvme.c  |   2 +-
 hw/block/nvme-ns.c| 193 +
 hw/block/nvme-ns.h|  54 +++
 hw/block/nvme.c   | 987 --
 hw/block/nvme.h   |   9 +
 hw/block/trace-events |  21 +
 include/block/nvme.h  | 113 -
 7 files changed, 1349 insertions(+), 30 deletions(-)

diff --git a/block/nvme.c b/block/nvme.c
index 05485fdd11..7a513c9a17 100644
--- a/block/nvme.c
+++ b/block/nvme.c
@@ -333,7 +333,7 @@ static inline int nvme_translate_error(const NvmeCqe *c)
 {
 uint16_t status = (le16_to_cpu(c->status) >> 1) & 0xFF;
 if (status) {
-trace_nvme_error(le32_to_cpu(c->result),
+trace_nvme_error(le32_to_cpu(c->result32),
  le16_to_cpu(c->sq_head),
  le16_to_cpu(c->sq_id),
  le16_to_cpu(c->cid),
diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
index 974aea33f7..fedfad595c 100644
--- a/hw/block/nvme-ns.c
+++ b/hw/block/nvme-ns.c
@@ -25,6 +25,7 @@
 #include "hw/qdev-properties.h"
 #include "hw/qdev-core.h"
 
+#include "trace.h"
 #include "nvme.h"
 #include "nvme-ns.h"
 
@@ -76,6 +77,171 @@ static int nvme_ns_init_blk(NvmeCtrl *n, NvmeNamespace *ns, 
Error **errp)
 return 0;
 }
 
+static int nvme_calc_zone_geometry(NvmeNamespace *ns, Error **errp)
+{
+uint64_t zone_size, zone_cap;
+uint32_t nz, lbasz = ns->blkconf.logical_block_size;
+
+if (ns->params.zone_size_bs) {
+zone_size = ns->params.zone_size_bs;
+} else {
+zone_size = NVME_DEFAULT_ZONE_SIZE;
+}
+if (ns->params.zone_cap_bs) {
+zone_cap = ns->params.zone_cap_bs;
+} else {
+zone_cap = zone_size;
+}
+if (zone_cap > zone_size) {
+error_setg(errp, "zone capacity %luB exceeds zone size %luB",
+   zone_cap, zone_size);
+return -1;
+}
+if (zone_size < lbasz) {
+error_setg(errp, "zone size %luB too small, must be at least %uB",
+   zone_size, lbasz);
+return -1;
+}
+if (zone_cap < lbasz) {
+error_setg(errp, "zone capacity %luB too small, must be at least %uB",
+   zone_cap, lbasz);
+return -1;
+}
+ns->zone_size = zone_size / lbasz;
+ns->zone_capacity = zone_cap / lbasz;
+
+nz = DIV_ROUND_UP(ns->size / lbasz, ns->zone_size);
+ns->num_zones = nz;
+ns->zone_array_size = sizeof(NvmeZone) * nz;
+ns->zone_size_log2 = 0;
+if (is_power_of_2(ns->zone_size)) {
+ns->zone_size_log2 = 63 - clz64(ns->zone_size);
+}
+
+return 0;
+}
+
+static void nvme_init_zone_state(NvmeNamespace *ns)
+{
+uint64_t start = 0, zone_size = ns->zone_size;
+uint64_t capacity = ns->num_zones * zone_size;
+NvmeZone *zone;
+int i;
+
+ns->zone_array = g_malloc0(ns->zone_array_size);
+
+QTAILQ_INIT(>exp_open_zones);
+QTAILQ_INIT(>imp_open_zones);
+QTAILQ_INIT(>closed_zones);
+QTAILQ_INIT(>full_zones);
+
+zone = ns->zone_array;
+for (i = 0; i < ns->num_zones; i++, zone++) {
+if (start + zone_size > capacity) {
+zone_size = capacity - start;
+}
+zone->d.zt = NVME_ZONE_TYPE_SEQ_WRITE;
+nvme_set_zone_state(zone, NVME_ZONE_STATE_EMPTY);
+zone->d.za = 0;
+

[PATCH v6 11/11] hw/block/nvme: Merge nvme_write_zeroes() with nvme_write()

2020-10-13 Thread Dmitry Fomichev
nvme_write() now handles WRITE, WRITE ZEROES and ZONE_APPEND.

Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c   | 95 +--
 hw/block/trace-events |  1 -
 2 files changed, 28 insertions(+), 68 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 1186c16b50..1c164f1d80 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1529,53 +1529,7 @@ invalid:
 return status | NVME_DNR;
 }
 
-static uint16_t nvme_write_zeroes(NvmeCtrl *n, NvmeRequest *req)
-{
-NvmeRwCmd *rw = (NvmeRwCmd *)>cmd;
-NvmeNamespace *ns = req->ns;
-uint64_t slba = le64_to_cpu(rw->slba);
-uint32_t nlb = (uint32_t)le16_to_cpu(rw->nlb) + 1;
-NvmeZone *zone;
-uint64_t offset = nvme_l2b(ns, slba);
-uint32_t count = nvme_l2b(ns, nlb);
-BlockBackend *blk = ns->blkconf.blk;
-uint16_t status;
-
-trace_pci_nvme_write_zeroes(nvme_cid(req), nvme_nsid(ns), slba, nlb);
-
-status = nvme_check_bounds(n, ns, slba, nlb);
-if (status) {
-trace_pci_nvme_err_invalid_lba_range(slba, nlb, ns->id_ns.nsze);
-return status;
-}
-
-if (ns->params.zoned) {
-zone = nvme_get_zone_by_slba(ns, slba);
-
-status = nvme_check_zone_write(n, ns, zone, slba, nlb, false);
-if (status != NVME_SUCCESS) {
-goto invalid;
-}
-
-status = nvme_auto_open_zone(ns, zone);
-if (status != NVME_SUCCESS) {
-goto invalid;
-}
-
-req->cqe.result64 = nvme_advance_zone_wp(ns, zone, nlb);
-}
-
-block_acct_start(blk_get_stats(blk), >acct, 0, BLOCK_ACCT_WRITE);
-req->aiocb = blk_aio_pwrite_zeroes(blk, offset, count,
-   BDRV_REQ_MAY_UNMAP, nvme_rw_cb, req);
-return NVME_NO_COMPLETE;
-
-invalid:
-block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
-return status | NVME_DNR;
-}
-
-static uint16_t nvme_write(NvmeCtrl *n, NvmeRequest *req, bool append)
+static uint16_t nvme_write(NvmeCtrl *n, NvmeRequest *req, bool append, bool 
wrz)
 {
 NvmeRwCmd *rw = (NvmeRwCmd *)>cmd;
 NvmeNamespace *ns = req->ns;
@@ -1590,10 +1544,12 @@ static uint16_t nvme_write(NvmeCtrl *n, NvmeRequest 
*req, bool append)
 trace_pci_nvme_write(nvme_cid(req), nvme_io_opc_str(rw->opcode),
  nvme_nsid(ns), nlb, data_size, slba);
 
-status = nvme_check_mdts(n, data_size);
-if (status) {
-trace_pci_nvme_err_mdts(nvme_cid(req), data_size);
-goto invalid;
+if (!wrz) {
+status = nvme_check_mdts(n, data_size);
+if (status) {
+trace_pci_nvme_err_mdts(nvme_cid(req), data_size);
+goto invalid;
+}
 }
 
 status = nvme_check_bounds(n, ns, slba, nlb);
@@ -1628,21 +1584,26 @@ static uint16_t nvme_write(NvmeCtrl *n, NvmeRequest 
*req, bool append)
 
 data_offset = nvme_l2b(ns, slba);
 
-status = nvme_map_dptr(n, data_size, req);
-if (status) {
-goto invalid;
-}
+if (!wrz) {
+status = nvme_map_dptr(n, data_size, req);
+if (status) {
+goto invalid;
+}
 
-data_offset = nvme_l2b(ns, slba);
-
-block_acct_start(blk_get_stats(blk), >acct, data_size,
- BLOCK_ACCT_WRITE);
-if (req->qsg.sg) {
-req->aiocb = dma_blk_write(blk, >qsg, data_offset,
-   BDRV_SECTOR_SIZE, nvme_rw_cb, req);
+block_acct_start(blk_get_stats(blk), >acct, data_size,
+ BLOCK_ACCT_WRITE);
+if (req->qsg.sg) {
+req->aiocb = dma_blk_write(blk, >qsg, data_offset,
+   BDRV_SECTOR_SIZE, nvme_rw_cb, req);
+} else {
+req->aiocb = blk_aio_pwritev(blk, data_offset, >iov, 0,
+ nvme_rw_cb, req);
+}
 } else {
-req->aiocb = blk_aio_pwritev(blk, data_offset, >iov, 0,
- nvme_rw_cb, req);
+block_acct_start(blk_get_stats(blk), >acct, 0, BLOCK_ACCT_WRITE);
+req->aiocb = blk_aio_pwrite_zeroes(blk, data_offset, data_size,
+   BDRV_REQ_MAY_UNMAP, nvme_rw_cb,
+   req);
 }
 return NVME_NO_COMPLETE;
 
@@ -2126,11 +2087,11 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest 
*req)
 case NVME_CMD_FLUSH:
 return nvme_flush(n, req);
 case NVME_CMD_WRITE_ZEROES:
-return nvme_write_zeroes(n, req);
+return nvme_write(n, req, false, true);
 case NVME_CMD_ZONE_APPEND:
-return nvme_write(n, req, true);
+return nvme_write(n, req, true, false);
 case NVME_CMD_WRITE:
-return nvme_write(n, req, false);
+return nvme_write(n, req, false, false);
 case NVME_CMD_READ:
 return nvme_read(n, req);
 case NVME_CMD_ZONE_MGMT_SEND:
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 

[PATCH v6 04/11] hw/block/nvme: Support allocated CNS command variants

2020-10-13 Thread Dmitry Fomichev
From: Niklas Cassel 

Many CNS commands have "allocated" command variants. These include
a namespace as long as it is allocated, that is a namespace is
included regardless if it is active (attached) or not.

While these commands are optional (they are mandatory for controllers
supporting the namespace attachment command), our QEMU implementation
is more complete by actually providing support for these CNS values.

However, since our QEMU model currently does not support the namespace
attachment command, these new allocated CNS commands will return the
same result as the active CNS command variants.

In NVMe, a namespace is active if it exists and is attached to the
controller.

CAP.CSS (together with the I/O Command Set data structure) defines
what command sets are supported by the controller.

CC.CSS (together with Set Profile) can be set to enable a subset of
the available command sets.

Even if a user configures CC.CSS to e.g. Admin only, NVM namespaces
will still be attached (and thus marked as active).
Similarly, if a user configures CC.CSS to e.g. NVM, ZNS namespaces
will still be attached (and thus marked as active).

However, any operation from a disabled command set will result in a
Invalid Command Opcode.

Add a new Boolean namespace property, "attached", to provide the most
basic namespace attachment support. The default value for this new
property is true. Also, implement the logic in the new CNS values to
include/exclude namespaces based on this new property. The only thing
missing is hooking up the actual Namespace Attachment command opcode,
which will allow a user to toggle the "attached" flag per namespace.

The reason for not hooking up this command completely is because the
NVMe specification requires the namespace management command to be
supported if the namespace attachment command is supported.

Signed-off-by: Niklas Cassel 
Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme-ns.c   |  1 +
 hw/block/nvme-ns.h   |  1 +
 hw/block/nvme.c  | 68 
 include/block/nvme.h | 20 +++--
 4 files changed, 70 insertions(+), 20 deletions(-)

diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
index c0362426cc..974aea33f7 100644
--- a/hw/block/nvme-ns.c
+++ b/hw/block/nvme-ns.c
@@ -132,6 +132,7 @@ static Property nvme_ns_props[] = {
 DEFINE_BLOCK_PROPERTIES(NvmeNamespace, blkconf),
 DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0),
 DEFINE_PROP_UUID("uuid", NvmeNamespace, params.uuid),
+DEFINE_PROP_BOOL("attached", NvmeNamespace, params.attached, true),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/block/nvme-ns.h b/hw/block/nvme-ns.h
index d795e44bab..d6b2808b97 100644
--- a/hw/block/nvme-ns.h
+++ b/hw/block/nvme-ns.h
@@ -21,6 +21,7 @@
 
 typedef struct NvmeNamespaceParams {
 uint32_t nsid;
+bool attached;
 QemuUUID uuid;
 } NvmeNamespaceParams;
 
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index af46448234..2b4488575b 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1062,6 +1062,9 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest *req)
 if (unlikely(!req->ns)) {
 return NVME_INVALID_FIELD | NVME_DNR;
 }
+if (!req->ns->params.attached) {
+return NVME_INVALID_FIELD | NVME_DNR;
+}
 
 if (!(req->ns->iocs[req->cmd.opcode] & NVME_CMD_EFF_CSUPP)) {
 trace_pci_nvme_err_invalid_opc(req->cmd.opcode);
@@ -1222,6 +1225,7 @@ static uint16_t nvme_smart_info(NvmeCtrl *n, uint8_t rae, 
uint32_t buf_len,
 uint32_t trans_len;
 NvmeNamespace *ns;
 time_t current_ms;
+int i;
 
 if (off >= sizeof(smart)) {
 return NVME_INVALID_FIELD | NVME_DNR;
@@ -1232,15 +1236,18 @@ static uint16_t nvme_smart_info(NvmeCtrl *n, uint8_t 
rae, uint32_t buf_len,
 if (!ns) {
 return NVME_INVALID_NSID | NVME_DNR;
 }
-nvme_set_blk_stats(ns, );
+if (ns->params.attached) {
+nvme_set_blk_stats(ns, );
+}
 } else {
-int i;
-
 for (i = 1; i <= n->num_namespaces; i++) {
 ns = nvme_ns(n, i);
 if (!ns) {
 continue;
 }
+if (!ns->params.attached) {
+continue;
+}
 nvme_set_blk_stats(ns, );
 }
 }
@@ -1529,7 +1536,8 @@ static uint16_t nvme_identify_ctrl_csi(NvmeCtrl *n, 
NvmeRequest *req)
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
-static uint16_t nvme_identify_ns(NvmeCtrl *n, NvmeRequest *req)
+static uint16_t nvme_identify_ns(NvmeCtrl *n, NvmeRequest *req,
+ bool only_active)
 {
 NvmeNamespace *ns;
 NvmeIdentify *c = (NvmeIdentify *)>cmd;
@@ -1546,11 +1554,16 @@ static uint16_t nvme_identify_ns(NvmeCtrl *n, 
NvmeRequest *req)
 return nvme_rpt_empty_id_struct(n, req);
 }
 
+if (only_active && !ns->params.attached) {
+return nvme_rpt_empty_id_struct(n, req);
+}
+
 return nvme_dma(n, (uint8_t 

[PATCH v6 08/11] hw/block/nvme: Add injection of Offline/Read-Only zones

2020-10-13 Thread Dmitry Fomichev
ZNS specification defines two zone conditions for the zones that no
longer can function properly, possibly because of flash wear or other
internal fault. It is useful to be able to "inject" a small number of
such zones for testing purposes.

This commit defines two optional device properties, "offline_zones"
and "rdonly_zones". Users can assign non-zero values to these variables
to specify the number of zones to be initialized as Offline or
Read-Only. The actual number of injected zones may be smaller than the
requested amount - Read-Only and Offline counts are expected to be much
smaller than the total number of zones on a drive.

Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme-ns.c | 64 ++
 hw/block/nvme-ns.h |  2 ++
 2 files changed, 66 insertions(+)

diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
index 255ded2b43..d050f97909 100644
--- a/hw/block/nvme-ns.c
+++ b/hw/block/nvme-ns.c
@@ -21,6 +21,7 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/block-backend.h"
 #include "qapi/error.h"
+#include "crypto/random.h"
 
 #include "hw/qdev-properties.h"
 #include "hw/qdev-core.h"
@@ -132,6 +133,32 @@ static int nvme_calc_zone_geometry(NvmeNamespace *ns, 
Error **errp)
 return -1;
 }
 
+if (ns->params.zd_extension_size) {
+if (ns->params.zd_extension_size & 0x3f) {
+error_setg(errp,
+"zone descriptor extension size must be a multiple of 64B");
+return -1;
+}
+if ((ns->params.zd_extension_size >> 6) > 0xff) {
+error_setg(errp, "zone descriptor extension size is too large");
+return -1;
+}
+}
+
+if (ns->params.max_open_zones < nz) {
+if (ns->params.nr_offline_zones > nz - ns->params.max_open_zones) {
+error_setg(errp, "offline_zones value %u is too large",
+ns->params.nr_offline_zones);
+return -1;
+}
+if (ns->params.nr_rdonly_zones >
+nz - ns->params.max_open_zones - ns->params.nr_offline_zones) {
+error_setg(errp, "rdonly_zones value %u is too large",
+ns->params.nr_rdonly_zones);
+return -1;
+}
+}
+
 return 0;
 }
 
@@ -140,7 +167,9 @@ static void nvme_init_zone_state(NvmeNamespace *ns)
 uint64_t start = 0, zone_size = ns->zone_size;
 uint64_t capacity = ns->num_zones * zone_size;
 NvmeZone *zone;
+uint32_t rnd;
 int i;
+uint16_t zs;
 
 ns->zone_array = g_malloc0(ns->zone_array_size);
 if (ns->params.zd_extension_size) {
@@ -167,6 +196,37 @@ static void nvme_init_zone_state(NvmeNamespace *ns)
 zone->w_ptr = start;
 start += zone_size;
 }
+
+/* If required, make some zones Offline or Read Only */
+
+for (i = 0; i < ns->params.nr_offline_zones; i++) {
+do {
+qcrypto_random_bytes(, sizeof(rnd), NULL);
+rnd %= ns->num_zones;
+} while (rnd < ns->params.max_open_zones);
+zone = >zone_array[rnd];
+zs = nvme_get_zone_state(zone);
+if (zs != NVME_ZONE_STATE_OFFLINE) {
+nvme_set_zone_state(zone, NVME_ZONE_STATE_OFFLINE);
+} else {
+i--;
+}
+}
+
+for (i = 0; i < ns->params.nr_rdonly_zones; i++) {
+do {
+qcrypto_random_bytes(, sizeof(rnd), NULL);
+rnd %= ns->num_zones;
+} while (rnd < ns->params.max_open_zones);
+zone = >zone_array[rnd];
+zs = nvme_get_zone_state(zone);
+if (zs != NVME_ZONE_STATE_OFFLINE &&
+zs != NVME_ZONE_STATE_READ_ONLY) {
+nvme_set_zone_state(zone, NVME_ZONE_STATE_READ_ONLY);
+} else {
+i--;
+}
+}
 }
 
 static int nvme_zoned_init_ns(NvmeCtrl *n, NvmeNamespace *ns, int lba_index,
@@ -360,6 +420,10 @@ static Property nvme_ns_props[] = {
 DEFINE_PROP_UINT32("max_open", NvmeNamespace, params.max_open_zones, 0),
 DEFINE_PROP_UINT32("zone_descr_ext_size", NvmeNamespace,
params.zd_extension_size, 0),
+DEFINE_PROP_UINT32("offline_zones", NvmeNamespace,
+   params.nr_offline_zones, 0),
+DEFINE_PROP_UINT32("rdonly_zones", NvmeNamespace,
+   params.nr_rdonly_zones, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/block/nvme-ns.h b/hw/block/nvme-ns.h
index 2d70a13701..d65d8b0930 100644
--- a/hw/block/nvme-ns.h
+++ b/hw/block/nvme-ns.h
@@ -37,6 +37,8 @@ typedef struct NvmeNamespaceParams {
 uint32_t max_active_zones;
 uint32_t max_open_zones;
 uint32_t zd_extension_size;
+uint32_t nr_offline_zones;
+uint32_t nr_rdonly_zones;
 } NvmeNamespaceParams;
 
 typedef struct NvmeNamespace {
-- 
2.21.0




[PATCH v6 07/11] hw/block/nvme: Support Zone Descriptor Extensions

2020-10-13 Thread Dmitry Fomichev
Zone Descriptor Extension is a label that can be assigned to a zone.
It can be set to an Empty zone and it stays assigned until the zone
is reset.

This commit adds a new optional module property, "zone_descr_ext_size".
Its value must be a multiple of 64 bytes. If this value is non-zero,
it becomes possible to assign extensions of that size to any Empty
zones. The default value for this property is 0, therefore setting
extensions is disabled by default.

Signed-off-by: Hans Holmberg 
Signed-off-by: Dmitry Fomichev 
Reviewed-by: Klaus Jensen 
---
 hw/block/nvme-ns.c| 14 ++--
 hw/block/nvme-ns.h|  8 +++
 hw/block/nvme.c   | 51 +--
 hw/block/trace-events |  2 ++
 4 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
index 8d9e11eef2..255ded2b43 100644
--- a/hw/block/nvme-ns.c
+++ b/hw/block/nvme-ns.c
@@ -143,6 +143,10 @@ static void nvme_init_zone_state(NvmeNamespace *ns)
 int i;
 
 ns->zone_array = g_malloc0(ns->zone_array_size);
+if (ns->params.zd_extension_size) {
+ns->zd_extensions = g_malloc0(ns->params.zd_extension_size *
+  ns->num_zones);
+}
 
 QTAILQ_INIT(>exp_open_zones);
 QTAILQ_INIT(>imp_open_zones);
@@ -192,7 +196,8 @@ static int nvme_zoned_init_ns(NvmeCtrl *n, NvmeNamespace 
*ns, int lba_index,
 id_ns_z->ozcs = ns->params.cross_zone_read ? 0x01 : 0x00;
 
 id_ns_z->lbafe[lba_index].zsze = cpu_to_le64(ns->zone_size);
-id_ns_z->lbafe[lba_index].zdes = 0;
+id_ns_z->lbafe[lba_index].zdes =
+ns->params.zd_extension_size >> 6; /* Units of 64B */
 
 ns->csi = NVME_CSI_ZONED;
 ns->id_ns.nsze = cpu_to_le64(ns->zone_size * ns->num_zones);
@@ -232,7 +237,9 @@ static void nvme_zoned_clear_ns(NvmeNamespace *ns)
 continue;
 }
 
-if (zone->d.wp == zone->d.zslba) {
+if (zone->d.za & NVME_ZA_ZD_EXT_VALID) {
+set_state = NVME_ZONE_STATE_CLOSED;
+} else if (zone->d.wp == zone->d.zslba) {
 set_state = NVME_ZONE_STATE_EMPTY;
 } else if (ns->params.max_active_zones == 0 ||
ns->nr_active_zones < ns->params.max_active_zones) {
@@ -320,6 +327,7 @@ void nvme_ns_cleanup(NvmeNamespace *ns)
 if (ns->params.zoned) {
 g_free(ns->id_ns_zoned);
 g_free(ns->zone_array);
+g_free(ns->zd_extensions);
 }
 }
 
@@ -350,6 +358,8 @@ static Property nvme_ns_props[] = {
  params.cross_zone_read, false),
 DEFINE_PROP_UINT32("max_active", NvmeNamespace, params.max_active_zones, 
0),
 DEFINE_PROP_UINT32("max_open", NvmeNamespace, params.max_open_zones, 0),
+DEFINE_PROP_UINT32("zone_descr_ext_size", NvmeNamespace,
+   params.zd_extension_size, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/block/nvme-ns.h b/hw/block/nvme-ns.h
index b0633d0def..2d70a13701 100644
--- a/hw/block/nvme-ns.h
+++ b/hw/block/nvme-ns.h
@@ -36,6 +36,7 @@ typedef struct NvmeNamespaceParams {
 uint64_t zone_cap_bs;
 uint32_t max_active_zones;
 uint32_t max_open_zones;
+uint32_t zd_extension_size;
 } NvmeNamespaceParams;
 
 typedef struct NvmeNamespace {
@@ -58,6 +59,7 @@ typedef struct NvmeNamespace {
 uint64_tzone_capacity;
 uint64_tzone_array_size;
 uint32_tzone_size_log2;
+uint8_t *zd_extensions;
 int32_t nr_open_zones;
 int32_t nr_active_zones;
 
@@ -127,6 +129,12 @@ static inline bool nvme_wp_is_valid(NvmeZone *zone)
st != NVME_ZONE_STATE_OFFLINE;
 }
 
+static inline uint8_t *nvme_get_zd_extension(NvmeNamespace *ns,
+ uint32_t zone_idx)
+{
+return >zd_extensions[zone_idx * ns->params.zd_extension_size];
+}
+
 static inline void nvme_aor_inc_open(NvmeNamespace *ns)
 {
 assert(ns->nr_open_zones >= 0);
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 088df2e813..18547722af 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1747,6 +1747,26 @@ static bool nvme_cond_offline_all(uint8_t state)
 return state == NVME_ZONE_STATE_READ_ONLY;
 }
 
+static uint16_t nvme_set_zd_ext(NvmeNamespace *ns, NvmeZone *zone,
+uint8_t state)
+{
+uint16_t status;
+
+if (state == NVME_ZONE_STATE_EMPTY) {
+nvme_auto_transition_zone(ns, false, true);
+status = nvme_aor_check(ns, 1, 0);
+if (status != NVME_SUCCESS) {
+return status;
+}
+nvme_aor_inc_active(ns);
+zone->d.za |= NVME_ZA_ZD_EXT_VALID;
+nvme_assign_zone_state(ns, zone, NVME_ZONE_STATE_CLOSED);
+return NVME_SUCCESS;
+}
+
+return NVME_ZONE_INVAL_TRANSITION;
+}
+
 typedef uint16_t (*op_handler_t)(NvmeNamespace *, NvmeZone *,
  uint8_t);
 typedef bool (*need_to_proc_zone_t)(uint8_t);
@@ -1787,6 +1807,7 @@ static uint16_t 

[PATCH v6 02/11] hw/block/nvme: Generate namespace UUIDs

2020-10-13 Thread Dmitry Fomichev
In NVMe 1.4, a namespace must report an ID descriptor of UUID type
if it doesn't support EUI64 or NGUID. Add a new namespace property,
"uuid", that provides the user the option to either specify the UUID
explicitly or have a UUID generated automatically every time a
namespace is initialized.

Suggested-by: Klaus Jansen 
Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme-ns.c | 1 +
 hw/block/nvme-ns.h | 1 +
 hw/block/nvme.c| 9 +
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
index b69cdaf27e..de735eb9f3 100644
--- a/hw/block/nvme-ns.c
+++ b/hw/block/nvme-ns.c
@@ -129,6 +129,7 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
 static Property nvme_ns_props[] = {
 DEFINE_BLOCK_PROPERTIES(NvmeNamespace, blkconf),
 DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0),
+DEFINE_PROP_UUID("uuid", NvmeNamespace, params.uuid),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/block/nvme-ns.h b/hw/block/nvme-ns.h
index ea8c2f785d..a38071884a 100644
--- a/hw/block/nvme-ns.h
+++ b/hw/block/nvme-ns.h
@@ -21,6 +21,7 @@
 
 typedef struct NvmeNamespaceParams {
 uint32_t nsid;
+QemuUUID uuid;
 } NvmeNamespaceParams;
 
 typedef struct NvmeNamespace {
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index ee0eff98da..89d91926d9 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1571,6 +1571,7 @@ static uint16_t nvme_identify_nslist(NvmeCtrl *n, 
NvmeRequest *req)
 
 static uint16_t nvme_identify_ns_descr_list(NvmeCtrl *n, NvmeRequest *req)
 {
+NvmeNamespace *ns;
 NvmeIdentify *c = (NvmeIdentify *)>cmd;
 uint32_t nsid = le32_to_cpu(c->nsid);
 uint8_t list[NVME_IDENTIFY_DATA_SIZE];
@@ -1590,7 +1591,8 @@ static uint16_t nvme_identify_ns_descr_list(NvmeCtrl *n, 
NvmeRequest *req)
 return NVME_INVALID_NSID | NVME_DNR;
 }
 
-if (unlikely(!nvme_ns(n, nsid))) {
+ns = nvme_ns(n, nsid);
+if (unlikely(!ns)) {
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
@@ -1599,12 +1601,11 @@ static uint16_t nvme_identify_ns_descr_list(NvmeCtrl 
*n, NvmeRequest *req)
 /*
  * Because the NGUID and EUI64 fields are 0 in the Identify Namespace data
  * structure, a Namespace UUID (nidt = 0x3) must be reported in the
- * Namespace Identification Descriptor. Add a very basic Namespace UUID
- * here.
+ * Namespace Identification Descriptor. Add the namespace UUID here.
  */
 ns_descrs->uuid.hdr.nidt = NVME_NIDT_UUID;
 ns_descrs->uuid.hdr.nidl = NVME_NIDT_UUID_LEN;
-stl_be_p(_descrs->uuid.v, nsid);
+memcpy(_descrs->uuid.v, ns->params.uuid.data, NVME_NIDT_UUID_LEN);
 
 return nvme_dma(n, list, NVME_IDENTIFY_DATA_SIZE,
 DMA_DIRECTION_FROM_DEVICE, req);
-- 
2.21.0




[PATCH v6 10/11] hw/block/nvme: Separate read and write handlers

2020-10-13 Thread Dmitry Fomichev
With ZNS support in place, the majority of code in nvme_rw() has
become read- or write-specific. Move these parts to two separate
handlers, nvme_read() and nvme_write() to make the code more
readable and to remove multiple is_write checks that so far existed
in the i/o path.

This is a refactoring patch, no change in functionality.

Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c   | 191 +-
 hw/block/trace-events |   3 +-
 2 files changed, 114 insertions(+), 80 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 41caf35430..1186c16b50 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1162,10 +1162,10 @@ typedef struct NvmeReadFillCtx {
 uint32_t  post_rd_fill_nlb;
 } NvmeReadFillCtx;
 
-static uint16_t nvme_check_zone_read(NvmeNamespace *ns, NvmeZone *zone,
- uint64_t slba, uint32_t nlb,
- NvmeReadFillCtx *rfc)
+static uint16_t nvme_check_zone_read(NvmeNamespace *ns, uint64_t slba,
+ uint32_t nlb, NvmeReadFillCtx *rfc)
 {
+NvmeZone *zone = nvme_get_zone_by_slba(ns, slba);
 NvmeZone *next_zone;
 uint64_t bndry = nvme_zone_rd_boundary(ns, zone);
 uint64_t end = slba + nlb, wp1, wp2;
@@ -1449,6 +1449,86 @@ static uint16_t nvme_flush(NvmeCtrl *n, NvmeRequest *req)
 return NVME_NO_COMPLETE;
 }
 
+static uint16_t nvme_read(NvmeCtrl *n, NvmeRequest *req)
+{
+NvmeRwCmd *rw = (NvmeRwCmd *)>cmd;
+NvmeNamespace *ns = req->ns;
+uint64_t slba = le64_to_cpu(rw->slba);
+uint32_t nlb = (uint32_t)le16_to_cpu(rw->nlb) + 1;
+uint32_t fill_len;
+uint64_t data_size = nvme_l2b(ns, nlb);
+uint64_t data_offset, fill_ofs;
+NvmeReadFillCtx rfc;
+BlockBackend *blk = ns->blkconf.blk;
+uint16_t status;
+
+trace_pci_nvme_read(nvme_cid(req), nvme_nsid(ns), nlb, data_size, slba);
+
+status = nvme_check_mdts(n, data_size);
+if (status) {
+trace_pci_nvme_err_mdts(nvme_cid(req), data_size);
+goto invalid;
+}
+
+status = nvme_check_bounds(n, ns, slba, nlb);
+if (status) {
+trace_pci_nvme_err_invalid_lba_range(slba, nlb, ns->id_ns.nsze);
+goto invalid;
+}
+
+if (ns->params.zoned) {
+status = nvme_check_zone_read(ns, slba, nlb, );
+if (status != NVME_SUCCESS) {
+trace_pci_nvme_err_zone_read_not_ok(slba, nlb, status);
+goto invalid;
+}
+}
+
+status = nvme_map_dptr(n, data_size, req);
+if (status) {
+goto invalid;
+}
+
+if (ns->params.zoned) {
+if (rfc.pre_rd_fill_nlb) {
+fill_ofs = nvme_l2b(ns, rfc.pre_rd_fill_slba - slba);
+fill_len = nvme_l2b(ns, rfc.pre_rd_fill_nlb);
+nvme_fill_read_data(req, fill_ofs, fill_len,
+n->params.fill_pattern);
+}
+if (!rfc.read_nlb) {
+/* No backend I/O necessary, only needed to fill the buffer */
+req->status = NVME_SUCCESS;
+return NVME_SUCCESS;
+}
+if (rfc.post_rd_fill_nlb) {
+req->fill_ofs = nvme_l2b(ns, rfc.post_rd_fill_slba - slba);
+req->fill_len = nvme_l2b(ns, rfc.post_rd_fill_nlb);
+} else {
+req->fill_len = 0;
+}
+slba = rfc.read_slba;
+data_size = nvme_l2b(ns, rfc.read_nlb);
+}
+
+data_offset = nvme_l2b(ns, slba);
+
+block_acct_start(blk_get_stats(blk), >acct, data_size,
+ BLOCK_ACCT_READ);
+if (req->qsg.sg) {
+req->aiocb = dma_blk_read(blk, >qsg, data_offset,
+  BDRV_SECTOR_SIZE, nvme_rw_cb, req);
+} else {
+req->aiocb = blk_aio_preadv(blk, data_offset, >iov, 0,
+nvme_rw_cb, req);
+}
+return NVME_NO_COMPLETE;
+
+invalid:
+block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
+return status | NVME_DNR;
+}
+
 static uint16_t nvme_write_zeroes(NvmeCtrl *n, NvmeRequest *req)
 {
 NvmeRwCmd *rw = (NvmeRwCmd *)>cmd;
@@ -1495,25 +1575,20 @@ invalid:
 return status | NVME_DNR;
 }
 
-static uint16_t nvme_rw(NvmeCtrl *n, NvmeRequest *req, bool append)
+static uint16_t nvme_write(NvmeCtrl *n, NvmeRequest *req, bool append)
 {
 NvmeRwCmd *rw = (NvmeRwCmd *)>cmd;
 NvmeNamespace *ns = req->ns;
-uint32_t nlb = (uint32_t)le16_to_cpu(rw->nlb) + 1;
 uint64_t slba = le64_to_cpu(rw->slba);
+uint32_t nlb = (uint32_t)le16_to_cpu(rw->nlb) + 1;
 uint64_t data_size = nvme_l2b(ns, nlb);
-uint64_t data_offset, fill_ofs;
-
+uint64_t data_offset;
 NvmeZone *zone;
-uint32_t fill_len;
-NvmeReadFillCtx rfc;
-bool is_write = rw->opcode == NVME_CMD_WRITE || append;
-enum BlockAcctType acct = is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ;
 BlockBackend *blk = ns->blkconf.blk;
 uint16_t status;
 
-trace_pci_nvme_rw(nvme_cid(req), 

[PATCH v6 06/11] hw/block/nvme: Introduce max active and open zone limits

2020-10-13 Thread Dmitry Fomichev
Add two module properties, "max_active" and "max_open" to control
the maximum number of zones that can be active or open. Once these
variables are set to non-default values, these limits are checked
during I/O and Too Many Active or Too Many Open command status is
returned if they are exceeded.

Signed-off-by: Hans Holmberg 
Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme-ns.c | 28 -
 hw/block/nvme-ns.h | 41 +++
 hw/block/nvme.c| 99 ++
 3 files changed, 166 insertions(+), 2 deletions(-)

diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
index fedfad595c..8d9e11eef2 100644
--- a/hw/block/nvme-ns.c
+++ b/hw/block/nvme-ns.c
@@ -118,6 +118,20 @@ static int nvme_calc_zone_geometry(NvmeNamespace *ns, 
Error **errp)
 ns->zone_size_log2 = 63 - clz64(ns->zone_size);
 }
 
+/* Make sure that the values of all ZNS properties are sane */
+if (ns->params.max_open_zones > nz) {
+error_setg(errp,
+   "max_open_zones value %u exceeds the number of zones %u",
+   ns->params.max_open_zones, nz);
+return -1;
+}
+if (ns->params.max_active_zones > nz) {
+error_setg(errp,
+   "max_active_zones value %u exceeds the number of zones %u",
+   ns->params.max_active_zones, nz);
+return -1;
+}
+
 return 0;
 }
 
@@ -172,8 +186,8 @@ static int nvme_zoned_init_ns(NvmeCtrl *n, NvmeNamespace 
*ns, int lba_index,
 id_ns_z = g_malloc0(sizeof(NvmeIdNsZoned));
 
 /* MAR/MOR are zeroes-based, 0x means no limit */
-id_ns_z->mar = 0x;
-id_ns_z->mor = 0x;
+id_ns_z->mar = cpu_to_le32(ns->params.max_active_zones - 1);
+id_ns_z->mor = cpu_to_le32(ns->params.max_open_zones - 1);
 id_ns_z->zoc = 0;
 id_ns_z->ozcs = ns->params.cross_zone_read ? 0x01 : 0x00;
 
@@ -199,6 +213,9 @@ static void nvme_zoned_clear_ns(NvmeNamespace *ns)
 uint32_t set_state;
 int i;
 
+ns->nr_active_zones = 0;
+ns->nr_open_zones = 0;
+
 zone = ns->zone_array;
 for (i = 0; i < ns->num_zones; i++, zone++) {
 switch (nvme_get_zone_state(zone)) {
@@ -209,6 +226,7 @@ static void nvme_zoned_clear_ns(NvmeNamespace *ns)
 QTAILQ_REMOVE(>exp_open_zones, zone, entry);
 break;
 case NVME_ZONE_STATE_CLOSED:
+nvme_aor_inc_active(ns);
 /* fall through */
 default:
 continue;
@@ -216,6 +234,9 @@ static void nvme_zoned_clear_ns(NvmeNamespace *ns)
 
 if (zone->d.wp == zone->d.zslba) {
 set_state = NVME_ZONE_STATE_EMPTY;
+} else if (ns->params.max_active_zones == 0 ||
+   ns->nr_active_zones < ns->params.max_active_zones) {
+set_state = NVME_ZONE_STATE_CLOSED;
 } else {
 set_state = NVME_ZONE_STATE_CLOSED;
 }
@@ -224,6 +245,7 @@ static void nvme_zoned_clear_ns(NvmeNamespace *ns)
 case NVME_ZONE_STATE_CLOSED:
 trace_pci_nvme_clear_ns_close(nvme_get_zone_state(zone),
   zone->d.zslba);
+nvme_aor_inc_active(ns);
 QTAILQ_INSERT_TAIL(>closed_zones, zone, entry);
 break;
 case NVME_ZONE_STATE_EMPTY:
@@ -326,6 +348,8 @@ static Property nvme_ns_props[] = {
 DEFINE_PROP_SIZE("zone_capacity", NvmeNamespace, params.zone_cap_bs, 0),
 DEFINE_PROP_BOOL("cross_zone_read", NvmeNamespace,
  params.cross_zone_read, false),
+DEFINE_PROP_UINT32("max_active", NvmeNamespace, params.max_active_zones, 
0),
+DEFINE_PROP_UINT32("max_open", NvmeNamespace, params.max_open_zones, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/block/nvme-ns.h b/hw/block/nvme-ns.h
index 170cbb8cdc..b0633d0def 100644
--- a/hw/block/nvme-ns.h
+++ b/hw/block/nvme-ns.h
@@ -34,6 +34,8 @@ typedef struct NvmeNamespaceParams {
 bool cross_zone_read;
 uint64_t zone_size_bs;
 uint64_t zone_cap_bs;
+uint32_t max_active_zones;
+uint32_t max_open_zones;
 } NvmeNamespaceParams;
 
 typedef struct NvmeNamespace {
@@ -56,6 +58,8 @@ typedef struct NvmeNamespace {
 uint64_tzone_capacity;
 uint64_tzone_array_size;
 uint32_tzone_size_log2;
+int32_t nr_open_zones;
+int32_t nr_active_zones;
 
 NvmeNamespaceParams params;
 } NvmeNamespace;
@@ -123,6 +127,43 @@ static inline bool nvme_wp_is_valid(NvmeZone *zone)
st != NVME_ZONE_STATE_OFFLINE;
 }
 
+static inline void nvme_aor_inc_open(NvmeNamespace *ns)
+{
+assert(ns->nr_open_zones >= 0);
+if (ns->params.max_open_zones) {
+ns->nr_open_zones++;
+assert(ns->nr_open_zones <= ns->params.max_open_zones);
+}
+}
+
+static inline void nvme_aor_dec_open(NvmeNamespace *ns)
+{
+if (ns->params.max_open_zones) {
+assert(ns->nr_open_zones > 0);
+ns->nr_open_zones--;
+}
+

[PATCH v6 09/11] hw/block/nvme: Document zoned parameters in usage text

2020-10-13 Thread Dmitry Fomichev
Added brief descriptions of the new device properties that are
now available to users to configure features of Zoned Namespace
Command Set in the emulator.

This patch is for documentation only, no functionality change.

Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c | 41 +++--
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 18547722af..41caf35430 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -9,7 +9,7 @@
  */
 
 /**
- * Reference Specs: http://www.nvmexpress.org, 1.2, 1.1, 1.0e
+ * Reference Specs: http://www.nvmexpress.org, 1.4, 1.3, 1.2, 1.1, 1.0e
  *
  *  https://nvmexpress.org/developers/nvme-specification/
  */
@@ -23,7 +23,8 @@
  *  max_ioqpairs=, \
  *  aerl=, aer_max_queued=, \
  *  mdts=
- *  -device nvme-ns,drive=,bus=bus_name,nsid=
+ *  -device nvme-ns,drive=,bus=,nsid=, \
+ *  zoned=
  *
  * Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at
  * offset 0 in BAR2 and supports only WDS, RDS and SQS for now.
@@ -49,6 +50,42 @@
  *   completion when there are no oustanding AERs. When the maximum number of
  *   enqueued events are reached, subsequent events will be dropped.
  *
+ * Setting `zoned` to true selects Zoned Command Set at the namespace.
+ * In this case, the following options are available to configure zoned
+ * operation:
+ * zone_size=
+ * The number may be followed by K, M, G as in kilo-, mega- or giga.
+ *
+ * zone_capacity=
+ * The value 0 (default) forces zone capacity to be the same as zone
+ * size. The value of this property may not exceed zone size.
+ *
+ * zone_descr_ext_size=
+ * This value needs to be specified in 64B units. If it is zero,
+ * namespace(s) will not support zone descriptor extensions.
+ *
+ * max_active=
+ *
+ * max_open=
+ *
+ * zone_append_size_limit=
+ * The maximum I/O size that can be supported by Zone Append
+ * command. Since internally this this value is maintained as
+ * ZASL = log2( / ), some
+ * values assigned to this property may be rounded down and
+ * result in a lower maximum ZA data size being in effect.
+ * By setting this property to 0, user can make ZASL to be
+ * equial to MDTS.
+ *
+ * offline_zones=
+ *
+ * rdonly_zones=
+ *
+ * cross_zone_read=
+ *
+ * fill_pattern=
+ * The byte pattern to return for any portions of unwritten data
+ * during read.
  */
 
 #include "qemu/osdep.h"
-- 
2.21.0




[PATCH v6 01/11] hw/block/nvme: Add Commands Supported and Effects log

2020-10-13 Thread Dmitry Fomichev
This log page becomes necessary to implement to allow checking for
Zone Append command support in Zoned Namespace Command Set.

This commit adds the code to report this log page for NVM Command
Set only. The parts that are specific to zoned operation will be
added later in the series.

All incoming admin and i/o commands are now only processed if their
corresponding support bits are set in this log. This provides an
easy way to control what commands to support and what not to
depending on set CC.CSS.

Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme-ns.h|  1 +
 hw/block/nvme.c   | 69 +++
 hw/block/trace-events |  2 ++
 include/block/nvme.h  | 19 
 4 files changed, 86 insertions(+), 5 deletions(-)

diff --git a/hw/block/nvme-ns.h b/hw/block/nvme-ns.h
index 83734f4606..ea8c2f785d 100644
--- a/hw/block/nvme-ns.h
+++ b/hw/block/nvme-ns.h
@@ -29,6 +29,7 @@ typedef struct NvmeNamespace {
 int32_t  bootindex;
 int64_t  size;
 NvmeIdNs id_ns;
+const uint32_t *iocs;
 
 NvmeNamespaceParams params;
 } NvmeNamespace;
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 9d30ca69dc..ee0eff98da 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -111,6 +111,25 @@ static const uint32_t nvme_feature_cap[NVME_FID_MAX] = {
 [NVME_TIMESTAMP]= NVME_FEAT_CAP_CHANGE,
 };
 
+static const uint32_t nvme_cse_acs[256] = {
+[NVME_ADM_CMD_DELETE_SQ]= NVME_CMD_EFF_CSUPP,
+[NVME_ADM_CMD_CREATE_SQ]= NVME_CMD_EFF_CSUPP,
+[NVME_ADM_CMD_DELETE_CQ]= NVME_CMD_EFF_CSUPP,
+[NVME_ADM_CMD_CREATE_CQ]= NVME_CMD_EFF_CSUPP,
+[NVME_ADM_CMD_IDENTIFY] = NVME_CMD_EFF_CSUPP,
+[NVME_ADM_CMD_SET_FEATURES] = NVME_CMD_EFF_CSUPP,
+[NVME_ADM_CMD_GET_FEATURES] = NVME_CMD_EFF_CSUPP,
+[NVME_ADM_CMD_GET_LOG_PAGE] = NVME_CMD_EFF_CSUPP,
+[NVME_ADM_CMD_ASYNC_EV_REQ] = NVME_CMD_EFF_CSUPP,
+};
+
+static const uint32_t nvme_cse_iocs_nvm[256] = {
+[NVME_CMD_FLUSH]= NVME_CMD_EFF_CSUPP | NVME_CMD_EFF_LBCC,
+[NVME_CMD_WRITE_ZEROES] = NVME_CMD_EFF_CSUPP | NVME_CMD_EFF_LBCC,
+[NVME_CMD_WRITE]= NVME_CMD_EFF_CSUPP | NVME_CMD_EFF_LBCC,
+[NVME_CMD_READ] = NVME_CMD_EFF_CSUPP,
+};
+
 static void nvme_process_sq(void *opaque);
 
 static uint16_t nvme_cid(NvmeRequest *req)
@@ -1045,6 +1064,11 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest 
*req)
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
+if (!(req->ns->iocs[req->cmd.opcode] & NVME_CMD_EFF_CSUPP)) {
+trace_pci_nvme_err_invalid_opc(req->cmd.opcode);
+return NVME_INVALID_OPCODE | NVME_DNR;
+}
+
 switch (req->cmd.opcode) {
 case NVME_CMD_FLUSH:
 return nvme_flush(n, req);
@@ -1054,8 +1078,7 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest *req)
 case NVME_CMD_READ:
 return nvme_rw(n, req);
 default:
-trace_pci_nvme_err_invalid_opc(req->cmd.opcode);
-return NVME_INVALID_OPCODE | NVME_DNR;
+assert(false);
 }
 }
 
@@ -1291,6 +1314,35 @@ static uint16_t nvme_error_info(NvmeCtrl *n, uint8_t 
rae, uint32_t buf_len,
 DMA_DIRECTION_FROM_DEVICE, req);
 }
 
+static uint16_t nvme_cmd_effects(NvmeCtrl *n, uint32_t buf_len,
+ uint64_t off, NvmeRequest *req)
+{
+NvmeEffectsLog log = {};
+uint32_t *dst_acs = log.acs, *dst_iocs = log.iocs;
+uint32_t trans_len;
+int i;
+
+trace_pci_nvme_cmd_supp_and_effects_log_read();
+
+if (off >= sizeof(log)) {
+trace_pci_nvme_err_invalid_effects_log_offset(off);
+return NVME_INVALID_FIELD | NVME_DNR;
+}
+
+for (i = 0; i < 256; i++) {
+dst_acs[i] = nvme_cse_acs[i];
+}
+
+for (i = 0; i < 256; i++) {
+dst_iocs[i] = nvme_cse_iocs_nvm[i];
+}
+
+trans_len = MIN(sizeof(log) - off, buf_len);
+
+return nvme_dma(n, ((uint8_t *)) + off, trans_len,
+DMA_DIRECTION_FROM_DEVICE, req);
+}
+
 static uint16_t nvme_get_log(NvmeCtrl *n, NvmeRequest *req)
 {
 NvmeCmd *cmd = >cmd;
@@ -1334,6 +1386,8 @@ static uint16_t nvme_get_log(NvmeCtrl *n, NvmeRequest 
*req)
 return nvme_smart_info(n, rae, len, off, req);
 case NVME_LOG_FW_SLOT_INFO:
 return nvme_fw_log_info(n, len, off, req);
+case NVME_LOG_CMD_EFFECTS:
+return nvme_cmd_effects(n, len, off, req);
 default:
 trace_pci_nvme_err_invalid_log_page(nvme_cid(req), lid);
 return NVME_INVALID_FIELD | NVME_DNR;
@@ -1920,6 +1974,11 @@ static uint16_t nvme_admin_cmd(NvmeCtrl *n, NvmeRequest 
*req)
 trace_pci_nvme_admin_cmd(nvme_cid(req), nvme_sqid(req), req->cmd.opcode,
  nvme_adm_opc_str(req->cmd.opcode));
 
+if (!(nvme_cse_acs[req->cmd.opcode] & NVME_CMD_EFF_CSUPP)) {
+trace_pci_nvme_err_invalid_admin_opc(req->cmd.opcode);
+return 

[PATCH v6 00/11] hw/block/nvme: Support Namespace Types and Zoned Namespace Command Set

2020-10-13 Thread Dmitry Fomichev
v5 -> v6

 - Remove zoned state persistence code. Replace position-independent
   zone lists with QTAILQs.

 - Close all open zones upon clearing of the controller. This is
   a similar procedure to the one previously performed upon powering
   up with zone persistence. 

 - Squash NS Types and ZNS triplets of commits to keep definitions
   and trace event definitions together with the implementation code.

 - Move namespace UUID generation to a separate patch. Add the new
   "uuid" property as suggested by Klaus.

 - Rework Commands and Effects patch to make sure that the log is
   always in sync with the actual set of commands supported.

 - Add two refactoring commits at the end of the series to
   optimize read and write i/o path.

- Incorporate feedback from Keith, Klaus and Niklas:

  * fix rebase errors in nvme_identify_ns_descr_list()
  * remove unnecessary code from nvme_write_bar()
  * move csi to NvmeNamespace and use it from the beginning in NSTypes
patch
  * change zone read processing to cover all corner cases with RAZB=1
  * sync w_ptr and d.wp in case of a i/o error at the preceding zone
  * reword the commit message in active/inactive patch with the new
text from Niklas
  * correct dlfeat reporting depending on the fill pattern set
  * add more checks for "attached" n/s parameter to prevent i/o and
get/set features on inactive namespaces
  * Use DEFINE_PROP_SIZE and DEFINE_PROP_SIZE32 for zone size/capacity
and ZASL respectively
  * Improve zone size and capacity validation
  * Correctly report NSZE

v4 -> v5

 - Rebase to the current qemu-nvme.

 - Use HostMemoryBackendFile as the backing storage for persistent
   zone metadata.

 - Fix the issue with filling the valid data in the next zone if RAZBi
   is enabled.

v3 -> v4

 - Fix bugs introduced in v2/v3 for QD > 1 operation. Now, all writes
   to a zone happen at the new write pointer variable, zone->w_ptr,
   that is advanced right after submitting the backend i/o. The existing
   zone->d.wp variable is updated upon the successful write completion
   and it is used for zone reporting. Some code has been split from
   nvme_finalize_zoned_write() function to a new function,
   nvme_advance_zone_wp().

 - Make the code compile under mingw. Switch to using QEMU API for
   mmap/msync, i.e. memory_region...(). Since mmap is not available in
   mingw (even though there is mman-win32 library available on Github),
   conditional compilation is added around these calls to avoid
   undefined symbols under mingw. A better fix would be to add stub
   functions to softmmu/memory.c for the case when CONFIG_POSIX is not
   defined, but such change is beyond the scope of this patchset and it
   can be made in a separate patch.

 - Correct permission mask used to open zone metadata file.

 - Fold "Define 64 bit cqe.result" patch into ZNS commit.

 - Use clz64/clz32 instead of defining nvme_ilog2() function.

 - Simplify rpt_empty_id_struct() code, move nvme_fill_data() back
   to ZNS patch.

 - Fix a power-on processing bug.

 - Rename NVME_CMD_ZONE_APND to NVME_CMD_ZONE_APPEND.

 - Make the list of review comments addressed in v2 of the series
   (see below).

v2 -> v3:

 - Moved nvme_fill_data() function to the NSTypes patch as it is
   now used there to output empty namespace identify structs.
 - Fixed typo in Maxim's email address.

v1 -> v2:

 - Rebased on top of qemu-nvme/next branch.
 - Incorporated feedback from Klaus and Alistair.
* Allow a subset of CSE log to be read, not the entire log
* Assign admin command entries in CSE log to ACS fields
* Set LPA bit 1 to indicate support of CSE log page
* Rename CC.CSS value CSS_ALL_NSTYPES (110b) to CSS_CSI
* Move the code to assign lbaf.ds to a separate patch
* Remove the change in firmware revision
* Change "driver" to "device" in comments and annotations
* Rename ZAMDS to ZASL
* Correct a few format expressions and some wording in
  trace event definitions
* Remove validation code to return NVME_CAP_EXCEEDED error
* Make ZASL to be equal to MDTS if "zone_append_size_limit"
  module parameter is not set
* Clean up nvme_zoned_init_ctrl() to make size calculations
  less confusing
* Avoid changing module parameters, use separate n/s variables
  if additional calculations are necessary to convert parameters
  to running values
* Use NVME_DEFAULT_ZONE_SIZE to assign the default zone size value
* Use default 0 for zone capacity meaning that zone capacity will
  be equal to zone size by default
* Issue warnings if user MAR/MOR values are too large and have
  to be adjusted
* Use unsigned values for MAR/MOR
 - Dropped "Simulate Zone Active excursions" patch.
   Excursion behavior may depend on the internal controller
   architecture and therefore be vendor-specific.
 - Dropped support for Zone Attributes and zoned AENs for now.
   These features can be added in a future series.
 - NS Types 

[PATCH v6 03/11] hw/block/nvme: Add support for Namespace Types

2020-10-13 Thread Dmitry Fomichev
From: Niklas Cassel 

Define the structures and constants required to implement
Namespace Types support.

Namespace Types introduce a new command set, "I/O Command Sets",
that allows the host to retrieve the command sets associated with
a namespace. Introduce support for the command set and enable
detection for the NVM Command Set.

The new workflows for identify commands rely heavily on zero-filled
identify structs. E.g., certain CNS commands are defined to return
a zero-filled identify struct when an inactive namespace NSID
is supplied.

Add a helper function in order to avoid code duplication when
reporting zero-filled identify structures.

Signed-off-by: Niklas Cassel 
Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme-ns.c|   2 +
 hw/block/nvme-ns.h|   1 +
 hw/block/nvme.c   | 198 +++---
 hw/block/trace-events |   7 ++
 include/block/nvme.h  |  65 +++---
 5 files changed, 226 insertions(+), 47 deletions(-)

diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
index de735eb9f3..c0362426cc 100644
--- a/hw/block/nvme-ns.c
+++ b/hw/block/nvme-ns.c
@@ -41,6 +41,8 @@ static void nvme_ns_init(NvmeNamespace *ns)
 
 id_ns->nsze = cpu_to_le64(nvme_ns_nlbas(ns));
 
+ns->csi = NVME_CSI_NVM;
+
 /* no thin provisioning */
 id_ns->ncap = id_ns->nsze;
 id_ns->nuse = id_ns->ncap;
diff --git a/hw/block/nvme-ns.h b/hw/block/nvme-ns.h
index a38071884a..d795e44bab 100644
--- a/hw/block/nvme-ns.h
+++ b/hw/block/nvme-ns.h
@@ -31,6 +31,7 @@ typedef struct NvmeNamespace {
 int64_t  size;
 NvmeIdNs id_ns;
 const uint32_t *iocs;
+uint8_t  csi;
 
 NvmeNamespaceParams params;
 } NvmeNamespace;
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 89d91926d9..af46448234 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -123,6 +123,9 @@ static const uint32_t nvme_cse_acs[256] = {
 [NVME_ADM_CMD_ASYNC_EV_REQ] = NVME_CMD_EFF_CSUPP,
 };
 
+static const uint32_t nvme_cse_iocs_none[256] = {
+};
+
 static const uint32_t nvme_cse_iocs_nvm[256] = {
 [NVME_CMD_FLUSH]= NVME_CMD_EFF_CSUPP | NVME_CMD_EFF_LBCC,
 [NVME_CMD_WRITE_ZEROES] = NVME_CMD_EFF_CSUPP | NVME_CMD_EFF_LBCC,
@@ -1051,10 +1054,6 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest 
*req)
 trace_pci_nvme_io_cmd(nvme_cid(req), nsid, nvme_sqid(req),
   req->cmd.opcode, nvme_io_opc_str(req->cmd.opcode));
 
-if (NVME_CC_CSS(n->bar.cc) == NVME_CC_CSS_ADMIN_ONLY) {
-return NVME_INVALID_OPCODE | NVME_DNR;
-}
-
 if (!nvme_nsid_valid(n, nsid)) {
 return NVME_INVALID_NSID | NVME_DNR;
 }
@@ -1333,8 +1332,10 @@ static uint16_t nvme_cmd_effects(NvmeCtrl *n, uint32_t 
buf_len,
 dst_acs[i] = nvme_cse_acs[i];
 }
 
-for (i = 0; i < 256; i++) {
-dst_iocs[i] = nvme_cse_iocs_nvm[i];
+if (NVME_CC_CSS(n->bar.cc) != NVME_CC_CSS_ADMIN_ONLY) {
+for (i = 0; i < 256; i++) {
+dst_iocs[i] = nvme_cse_iocs_nvm[i];
+}
 }
 
 trans_len = MIN(sizeof(log) - off, buf_len);
@@ -1500,6 +1501,13 @@ static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeRequest 
*req)
 return NVME_SUCCESS;
 }
 
+static uint16_t nvme_rpt_empty_id_struct(NvmeCtrl *n, NvmeRequest *req)
+{
+uint8_t id[NVME_IDENTIFY_DATA_SIZE] = {};
+
+return nvme_dma(n, id, sizeof(id), DMA_DIRECTION_FROM_DEVICE, req);
+}
+
 static uint16_t nvme_identify_ctrl(NvmeCtrl *n, NvmeRequest *req)
 {
 trace_pci_nvme_identify_ctrl();
@@ -1508,11 +1516,23 @@ static uint16_t nvme_identify_ctrl(NvmeCtrl *n, 
NvmeRequest *req)
 DMA_DIRECTION_FROM_DEVICE, req);
 }
 
+static uint16_t nvme_identify_ctrl_csi(NvmeCtrl *n, NvmeRequest *req)
+{
+NvmeIdentify *c = (NvmeIdentify *)>cmd;
+
+trace_pci_nvme_identify_ctrl_csi(c->csi);
+
+if (c->csi == NVME_CSI_NVM) {
+return nvme_rpt_empty_id_struct(n, req);
+}
+
+return NVME_INVALID_FIELD | NVME_DNR;
+}
+
 static uint16_t nvme_identify_ns(NvmeCtrl *n, NvmeRequest *req)
 {
 NvmeNamespace *ns;
 NvmeIdentify *c = (NvmeIdentify *)>cmd;
-NvmeIdNs *id_ns, inactive = { 0 };
 uint32_t nsid = le32_to_cpu(c->nsid);
 
 trace_pci_nvme_identify_ns(nsid);
@@ -1523,23 +1543,46 @@ static uint16_t nvme_identify_ns(NvmeCtrl *n, 
NvmeRequest *req)
 
 ns = nvme_ns(n, nsid);
 if (unlikely(!ns)) {
-id_ns = 
-} else {
-id_ns = >id_ns;
+return nvme_rpt_empty_id_struct(n, req);
 }
 
-return nvme_dma(n, (uint8_t *)id_ns, sizeof(NvmeIdNs),
+return nvme_dma(n, (uint8_t *)>id_ns, sizeof(NvmeIdNs),
 DMA_DIRECTION_FROM_DEVICE, req);
 }
 
+static uint16_t nvme_identify_ns_csi(NvmeCtrl *n, NvmeRequest *req)
+{
+NvmeNamespace *ns;
+NvmeIdentify *c = (NvmeIdentify *)>cmd;
+uint32_t nsid = le32_to_cpu(c->nsid);
+
+trace_pci_nvme_identify_ns_csi(nsid, c->csi);
+
+if (!nvme_nsid_valid(n, nsid) || nsid == NVME_NSID_BROADCAST) {
+ 

Re: [PATCH 2/2] qga: add ssh-{add,remove}-authorized-keys

2020-10-13 Thread Philippe Mathieu-Daudé

Hi Marc-André,

On 10/13/20 10:25 PM, marcandre.lur...@redhat.com wrote:

From: Marc-André Lureau 

Add new commands to add and remove SSH public keys from
~/.ssh/authorized_keys.

I took a different approach for testing, including the unit tests right
with the code. I wanted to overwrite the function to get the user
details, I couldn't easily do that over QMP. Furthermore, I prefer
having unit tests very close to the code, and unit files that are domain
specific (commands-posix is too crowded already). Fwiw, that


FWIW


coding/testing style is Rust-style (where tests can or should even be
part of the documentation!).

Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=1885332

Signed-off-by: Marc-André Lureau 
---

...


diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index cec98c7e06..50e2854b45 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -1306,3 +1306,35 @@
  ##
  { 'command': 'guest-get-devices',
'returns': ['GuestDeviceInfo'] }
+
+##
+# @guest-ssh-add-authorized-keys:
+#
+# @username: the user account to add the authorized key
+# @keys: the public keys to add (in OpenSSH format)


You use plural but the code only seems to add (remove) one key
at a time.

'OpenSSH format' is confusing. From sshd(8):

  Each line of the file contains one key (empty lines and lines
  starting with a ‘#’ are ignored as comments).

  Public keys consist of the following space-separated fields:

options, keytype, base64-encoded key, comment.

  The options field is optional.

  Note that lines in this file can be several hundred bytes long
  (because of the size of the public key encoding) up to a limit
  of 8 kilobytes, which permits RSA keys up to 16 kilobits.

  The options (if present) consist of comma-separated option
  specifications.  No spaces are permitted, except within double
  quotes.

@openssh_authorized_key_line is ugly, maybe use @authorized_key
to make it clearer?


+#
+# Append a public key to user $HOME/.ssh/authorized_keys on Unix systems (not
+# implemented for other systems).


Here "a key" singular, good.


+#
+# Returns: Nothing on success.
+#
+# Since: 5.2
+##
+{ 'command': 'guest-ssh-add-authorized-keys',


Here "keys" plural :/


+  'data': { 'username': 'str', 'keys': ['str'] } }
+
+##
+# @guest-ssh-remove-authorized-keys:
+#
+# @username: the user account to add the authorized key
+# @keys: the public keys to remove (in OpenSSH format)
+#
+# Remove public keys from the user $HOME/.ssh/authorized_keys on Unix systems
+# (not implemented for other systems).
+#
+# Returns: Nothing on success.
+#
+# Since: 5.2
+##
+{ 'command': 'guest-ssh-remove-authorized-keys',
+  'data': { 'username': 'str', 'keys': ['str'] } }






Re: [PATCH] hw/block/nvme: add block utilization tracking

2020-10-13 Thread Keith Busch
On Tue, Oct 13, 2020 at 09:08:46PM +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> This adds support for reporting the Deallocated or Unwritten Logical
> Block error (DULBE). This requires tracking the allocated/deallocated
> status of all logical blocks.
> 
> Introduce a bitmap that does this. The bitmap is always intialized to
> all ones (aka, all blocks are allocated) on boot up. Blocks can then be
> specifically deallocated using Write Zeroes. This ensures that we can
> always guarantee zeroes to be returned from deallocated blocks.
> 
> When the device gains support for persistent state, the intention is to
> remove the "allocated by default" behavior.

I think this is a rather odd feature for this device to support. The
implementation is slow can end up allocating quite a bit of memory. If
we were going to support it here, wouldn't it make more sense to tie it
to the filesystem's ability to support fallocate hole punch for the
backing namespace, and check if the range is allocated with SEEK_HOLE?
Then you don't even need to track persistent state, and we're actually
getting the genuine capability.



Re: [PATCH 09/10] target/arm: Implement FPSCR.LTPSIZE for M-profile LOB extension

2020-10-13 Thread Richard Henderson
On 10/13/20 1:38 PM, Peter Maydell wrote:
>  * has short-vector support (eg Cortex-A9)
>  * v8A, can implement FPSCR.{Stride,Len} as RAZ/WI
>  * no short-vector support, Stride/Len can be written
>but the only effect is that some insns must UNDEF
>(eg Cortex-A7)

Yep.

The other thing I wondered is if it was worthwhile to go ahead and split out
ltpsize now, even with MTE not implemented.

Eventually the conditions here would look like

if (m-profile) {
if (mte) {
ltpsize = [18:16];
}
} else {
if (!v8) {
vec_len = [18:16];
vec_stride = [22:20];
}
}

but for now you could leave out the assignment to ltpsize and just leave it
initialized to 4 since reset.


r~



Re: pvpanic mmio support

2020-10-13 Thread Peter Maydell
On Tue, 13 Oct 2020 at 21:37, Mihai Carabas  wrote:
> Does anyone know if there is any progress with pvpanic patches that
> brings in mmio support [1]?

I don't think so. If I recall correctly there was quite a lot
of discussion on at least one version of that patchset, and it
was never clear to me at least that having an MMIO pvpanic device
was actually useful (as opposed to for instance having a PCI
device, or maybe a virtio backend, both of which have the
virtue of being (a) pluggable by the user and (b) autodetectable
by the guest).

> I see no activity since late 2018, but I do
> see support added to the kernel (also asking myself how this was tested):
>
> 46f934c misc/pvpanic: add support to get pvpanic device info FDT
> b1d9d6c dt-bindings: misc/pvpanic: add document for pvpanic-mmio
> 725eba2 misc/pvpanic: add MMIO support

That was probably tested with somebody's not-actually-in-QEMU
patchset. The documentation in the kernel's
Documentation/devicetree/bindings/misc/pvpanic-mmio.txt
is just wrong when it says
# QEMU's emulation / virtualization targets provide the following
# PVPANIC MMIO Configuration interface on the "virt" machine.

because we definitely do not.

thanks
-- PMM



[PATCH 2/3] hw/misc/mac_via: Replace via2_irq_request() with via_irq_request()

2020-10-13 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/misc/mac_via.c | 18 +-
 1 file changed, 1 insertion(+), 17 deletions(-)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index 9e64c2521fc..54088b6625a 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -362,22 +362,6 @@ static void via1_one_second(void *opaque)
 via1_one_second_update(v1s);
 }
 
-static void via2_irq_request(void *opaque, int irq, int level)
-{
-MOS6522Q800VIA2State *v2s = opaque;
-MOS6522State *s = MOS6522(v2s);
-MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
-
-if (level) {
-s->ifr |= 1 << irq;
-} else {
-s->ifr &= ~(1 << irq);
-}
-
-mdc->update_irq(s);
-}
-
-
 static void pram_update(MacVIAState *m)
 {
 if (m->blk) {
@@ -1238,7 +1222,7 @@ static void mos6522_q800_via2_reset(DeviceState *dev)
 
 static void mos6522_q800_via2_init(Object *obj)
 {
-qdev_init_gpio_in_named(DEVICE(obj), via2_irq_request, "via2-irq",
+qdev_init_gpio_in_named(DEVICE(obj), via_irq_request, "via2-irq",
 VIA2_IRQ_NB);
 }
 
-- 
2.26.2




[PATCH 1/3] hw/misc/mac_via: Make generic via_irq_request() from via1_irq_request()

2020-10-13 Thread Philippe Mathieu-Daudé
Rewrite via1_irq_request() as generic via_irq_request().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/misc/mac_via.c | 31 +++
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index 6db62dab7db..9e64c2521fc 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -324,6 +324,20 @@ static void via1_one_second_update(MOS6522Q800VIA1State 
*v1s)
 }
 }
 
+static void via_irq_request(void *opaque, int irq, int level)
+{
+MOS6522State *s = MOS6522(opaque);
+MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
+
+if (level) {
+s->ifr |= 1 << irq;
+} else {
+s->ifr &= ~(1 << irq);
+}
+
+mdc->update_irq(s);
+}
+
 static void via1_VBL(void *opaque)
 {
 MOS6522Q800VIA1State *v1s = opaque;
@@ -348,21 +362,6 @@ static void via1_one_second(void *opaque)
 via1_one_second_update(v1s);
 }
 
-static void via1_irq_request(void *opaque, int irq, int level)
-{
-MOS6522Q800VIA1State *v1s = opaque;
-MOS6522State *s = MOS6522(v1s);
-MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
-
-if (level) {
-s->ifr |= 1 << irq;
-} else {
-s->ifr &= ~(1 << irq);
-}
-
-mdc->update_irq(s);
-}
-
 static void via2_irq_request(void *opaque, int irq, int level)
 {
 MOS6522Q800VIA2State *v2s = opaque;
@@ -1195,7 +1194,7 @@ static void mos6522_q800_via1_reset(DeviceState *dev)
 
 static void mos6522_q800_via1_init(Object *obj)
 {
-qdev_init_gpio_in_named(DEVICE(obj), via1_irq_request, "via1-irq",
+qdev_init_gpio_in_named(DEVICE(obj), via_irq_request, "via1-irq",
 VIA1_IRQ_NB);
 }
 
-- 
2.26.2




[PATCH 0/3] hw/misc/mac_via: Factor generic via_irq_request() out

2020-10-13 Thread Philippe Mathieu-Daudé
The same logic is used in 4 different places:
- via1_irq_request()
- via2_irq_request()
- via1_VBL()
- via1_one_second()

Extract the common function and reuse it.

Philippe Mathieu-Daudé (3):
  hw/misc/mac_via: Make generic via_irq_request() from
via1_irq_request()
  hw/misc/mac_via: Replace via2_irq_request() with via_irq_request()
  hw/misc/mac_via: Use via_irq_request() in via1_VBL(),
via1_one_second()

 hw/misc/mac_via.c | 59 +++
 1 file changed, 18 insertions(+), 41 deletions(-)

-- 
2.26.2




[PATCH 3/3] hw/misc/mac_via: Use via_irq_request() in via1_VBL(), via1_one_second()

2020-10-13 Thread Philippe Mathieu-Daudé
via1_VBL() and via1_one_second() just call the generic
via_irq_request() handler raising a specific IRQ.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/misc/mac_via.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index 54088b6625a..00877a42447 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -341,11 +341,8 @@ static void via_irq_request(void *opaque, int irq, int 
level)
 static void via1_VBL(void *opaque)
 {
 MOS6522Q800VIA1State *v1s = opaque;
-MOS6522State *s = MOS6522(v1s);
-MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
 
-s->ifr |= VIA1_IRQ_VBLANK;
-mdc->update_irq(s);
+via_irq_request(v1s, VIA1_IRQ_VBLANK, 1);
 
 via1_VBL_update(v1s);
 }
@@ -353,11 +350,8 @@ static void via1_VBL(void *opaque)
 static void via1_one_second(void *opaque)
 {
 MOS6522Q800VIA1State *v1s = opaque;
-MOS6522State *s = MOS6522(v1s);
-MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
 
-s->ifr |= VIA1_IRQ_ONE_SECOND;
-mdc->update_irq(s);
+via_irq_request(v1s, VIA1_IRQ_ONE_SECOND, 1);
 
 via1_one_second_update(v1s);
 }
-- 
2.26.2




Re: [PATCH 09/10] target/arm: Implement FPSCR.LTPSIZE for M-profile LOB extension

2020-10-13 Thread Peter Maydell
On Tue, 13 Oct 2020 at 21:06, Richard Henderson
 wrote:
> I think these two sets of masking are confusing.
> Perhaps usefully rearranged as
>
> if (!fp16) {
> val &= ~fz16;
> }
> vfp_set_fpscr_to_host(env, val);
>
> if (!m-profile) {
> vec_len = extract32(val, 16, 3);
> vec_stride = extract32(val, 20, 2);
> }
> val &= 0xf7c8;
> if (lob) {
> val |= 4 << 16;
> }
> fpscr = val;

Yeah, probably cleaner.

The other thing I wondered about is whether we should
be setting vec_len/vec_stride for an A-profile CPU which
doesn't implement the short-vector extension (ie where
MVFR0.FPShVec is zero). But that gets a bit awkward: v8A
allows an implementation to make Stride and Len be RAZ,
but v7A didn't permit that and so I think we would need
to distinguish:
 * has short-vector support (eg Cortex-A9)
 * v8A, can implement FPSCR.{Stride,Len} as RAZ/WI
 * no short-vector support, Stride/Len can be written
   but the only effect is that some insns must UNDEF
   (eg Cortex-A7)

I think at the moment we currently provide short-vector
support for everything, which is wrong but wrong in
the direction that means more guest code runs...

thanks
-- PMM



Re: Why guest physical addresses are not the same as the corresponding host virtual addresses in QEMU/KVM? Thanks!

2020-10-13 Thread harry harry
Hi Paolo and Sean,

Thanks much for your prompt replies and clear explanations.

On Tue, Oct 13, 2020 at 2:43 AM Paolo Bonzini  wrote:
>
> No, the logic to find the HPA with a given HVA is the same as the
> hardware logic to translate HVA -> HPA.  That is it uses the host
> "regular" page tables, not the nested page tables.
>
> In order to translate GPA to HPA, instead, KVM does not use the nested
> page tables.

I am curious why KVM does not directly use GPAs as HVAs and leverage
nested page tables to translate HVAs (i.e., GPAs) to HPAs? Is that
because 1) the hardware logic of ``GPA -> [extended/nested page
tables] -> HPA[*]'' is different[**] from the hardware logic of ``HVA
-> [host regular page tables] -> HPA''; 2) if 1) is true, it is
natural to reuse Linux's original functionality to translate HVAs to
HPAs through regular page tables.

[*]: Here, the translation means the last step for MMU to translate a
GVA's corresponding GPA to an HPA through the extended/nested page
tables.
[**]: To my knowledge, the hardware logic of ``GPA -> [extended/nested
page tables] -> HPA'' seems to be the same as the hardware logic of
``HVA -> [host regular page tables] -> HPA''. I appreciate it if you
could point out the differences I ignored. Thanks!

Best,
Harry



Re: Contributor wanting to get started with simple contributions

2020-10-13 Thread Rohit Shinde
Hey John,

Sorry for the late reply! I was in the midst of a job change and couldn't
get time to get to this.

The work sounds interesting! I have a couple of questions regarding this:


   1. How do I actually build this part? I am familiar with building and
   using QEMU. Does the qapi parser get built along with the main code?
   2. If not, how do I start using this part and contributing to it?


Thanks,
Rohit.

On Tue, Sep 29, 2020 at 9:38 PM John Snow  wrote:

> On 9/2/20 12:38 PM, Rohit Shinde wrote:
> > Hey John,
> >
> > I wanted to follow up on this, in case you missed my previous email :)
> >
> > Thanks,
> > Rohit.
> >
>
> Sorry Rohit, very buried in my work and haven't been doing a good job
> with my inbox.
>
> Right now, I am working on converting the QAPI parser module to the
> strictly typed mypy subset:
>
> https://lists.gnu.org/archive/html/qemu-devel/2020-09/msg09136.html
>
> There are six parts in all, that is part one. I am posting a v4 right
> now as I write this.
>
>
> Work that remains to be done after these six parts:
>
> - Get ./python/qemu passing under mypy/pylint/flake8 again. I have old
> patches for this that were on-list prior to the 5.1 release.
>
> - Move ./scripts/qapi to ./python/qemu/qapi/
>
> - Move ./python/qemu to ./python/qemu/core/
>
> - Create a "make check" style script that will run
> mypy/pylint/flake8/isort on all the code in ./python. (I have patches
> for this, too.)
>
> - Start investigating python scripts in ./scripts and consider moving
> them to ./python/qemu/tools, fixing them up to pass
> mypy/flake8/pylint/isort (etc) as I go. There are no existing patches to
> do this yet.
>
>
> Other work I am doing:
>
> - Investigating the use of Pydantic to replace ./scripts/qapi/expr.py
> - Investigating a YAML format for the QAPI parser
> - Building a JSON-SCHEMA output format for the QAPI generator
>
>
> > On Sat, Aug 29, 2020 at 1:14 AM Rohit Shinde
> > mailto:rohit.shinde12...@gmail.com>>
> wrote:
> >
> > Hey John,
> >
> > Sorry to bother you! I just wanted to know if you had any thoughts
> > on the mail I sent.
> >
> > Is there anything I can pick up right now with regards to the Python
> > package? You mentioned that linting is something that needs to be
> > completed before we go ahead, so maybe I can start with that?
> >
> > Thanks,
> > Rohit.
> >
>
>


pvpanic mmio support

2020-10-13 Thread Mihai Carabas

Hello,

Does anyone know if there is any progress with pvpanic patches that 
brings in mmio support [1]? I see no activity since late 2018, but I do 
see support added to the kernel (also asking myself how this was tested):


46f934c misc/pvpanic: add support to get pvpanic device info FDT
b1d9d6c dt-bindings: misc/pvpanic: add document for pvpanic-mmio
725eba2 misc/pvpanic: add MMIO support

Thank you,
Mihai


[1] https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg01095.html



Re: [PATCH 0/2] qemu-ga: add ssh-{add,remove}-authorized-keys

2020-10-13 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20201013202502.335336-1-marcandre.lur...@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20201013202502.335336-1-marcandre.lur...@redhat.com
Subject: [PATCH 0/2] qemu-ga: add ssh-{add,remove}-authorized-keys

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20201013103532.13391-1-peter.mayd...@linaro.org -> 
patchew/20201013103532.13391-1-peter.mayd...@linaro.org
 - [tag update]  
patchew/20201013172223.443645-1-georg.kothei...@kernkonzept.com -> 
patchew/20201013172223.443645-1-georg.kothei...@kernkonzept.com
 * [new tag] 
patchew/20201013202502.335336-1-marcandre.lur...@redhat.com -> 
patchew/20201013202502.335336-1-marcandre.lur...@redhat.com
Switched to a new branch 'test'
66c8929 qga: add ssh-{add,remove}-authorized-keys
6aa612c glib-compat: add g_unix_get_passwd_entry_qemu()

=== OUTPUT BEGIN ===
1/2 Checking commit 6aa612cc67ad (glib-compat: add 
g_unix_get_passwd_entry_qemu())
WARNING: Block comments use a leading /* on a separate line
#38: FILE: include/glib-compat.h:79:
+/* Note: The fallback implementation is not MT-safe, and it returns a copy of

WARNING: Block comments use a trailing */ on a separate line
#41: FILE: include/glib-compat.h:82:
+ * GLib API substitution. */

total: 0 errors, 2 warnings, 36 lines checked

Patch 1/2 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
2/2 Checking commit 66c89292c34c (qga: add ssh-{add,remove}-authorized-keys)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#25: 
new file mode 100644

ERROR: line over 90 characters
#52: FILE: qga/commands-posix-ssh.c:23:
+g_set_error_literal(error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "Invalid 
user name");

ERROR: Use g_assert or g_assert_not_reached
#62: FILE: qga/commands-posix-ssh.c:33:
+g_assert_cmpint(ret, ==, 0);

WARNING: line over 80 characters
#67: FILE: qga/commands-posix-ssh.c:38:
+#define g_unix_get_passwd_entry_qemu(username, err) 
test_get_passwd_entry(username, err)

WARNING: line over 80 characters
#89: FILE: qga/commands-posix-ssh.c:60:
+mkdir_for_user(const char *path, const struct passwd *p, mode_t mode, Error 
**errp)

ERROR: Use g_assert or g_assert_not_reached
#313: FILE: qga/commands-posix-ssh.c:284:
+g_assert_cmpint(ret, ==, 0);

ERROR: Use g_assert or g_assert_not_reached
#318: FILE: qga/commands-posix-ssh.c:289:
+g_assert_no_error(err);

ERROR: Use g_assert or g_assert_not_reached
#330: FILE: qga/commands-posix-ssh.c:301:
+g_assert_no_error(err);

ERROR: Use g_assert or g_assert_not_reached
#332: FILE: qga/commands-posix-ssh.c:303:
+g_assert_cmpstr(contents, ==, expected);

ERROR: Use g_assert or g_assert_not_reached
#369: FILE: qga/commands-posix-ssh.c:340:
+g_assert_null(err);

ERROR: Use g_assert or g_assert_not_reached
#375: FILE: qga/commands-posix-ssh.c:346:
+g_assert_null(err);

ERROR: Use g_assert or g_assert_not_reached
#396: FILE: qga/commands-posix-ssh.c:367:
+g_assert_null(err);

ERROR: Use g_assert or g_assert_not_reached
#401: FILE: qga/commands-posix-ssh.c:372:
+g_assert_null(err);

WARNING: line over 80 characters
#433: FILE: qga/commands-win32.c:2461:
+void qmp_guest_ssh_add_authorized_keys(const char *username, strList *keys, 
Error **errp)

ERROR: line over 90 characters
#438: FILE: qga/commands-win32.c:2466:
+void qmp_guest_ssh_remove_authorized_keys(const char *username, strList *keys, 
Error **errp)

total: 11 errors, 4 warnings, 468 lines checked

Patch 2/2 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


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

[PATCH 2/2] qga: add ssh-{add,remove}-authorized-keys

2020-10-13 Thread marcandre . lureau
From: Marc-André Lureau 

Add new commands to add and remove SSH public keys from
~/.ssh/authorized_keys.

I took a different approach for testing, including the unit tests right
with the code. I wanted to overwrite the function to get the user
details, I couldn't easily do that over QMP. Furthermore, I prefer
having unit tests very close to the code, and unit files that are domain
specific (commands-posix is too crowded already). Fwiw, that
coding/testing style is Rust-style (where tests can or should even be
part of the documentation!).

Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=1885332

Signed-off-by: Marc-André Lureau 
---
 qga/commands-posix-ssh.c | 394 +++
 qga/commands-win32.c |  10 +
 qga/meson.build  |  17 +-
 qga/qapi-schema.json |  32 
 4 files changed, 452 insertions(+), 1 deletion(-)
 create mode 100644 qga/commands-posix-ssh.c

diff --git a/qga/commands-posix-ssh.c b/qga/commands-posix-ssh.c
new file mode 100644
index 00..3721ac4975
--- /dev/null
+++ b/qga/commands-posix-ssh.c
@@ -0,0 +1,394 @@
+ /*
+  * 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 
+#include 
+#include 
+#include 
+
+#include "qapi/error.h"
+#include "qga-qapi-commands.h"
+
+#ifdef QGA_BUILD_UNIT_TEST
+static struct passwd *
+test_get_passwd_entry(const gchar *user_name, GError **error)
+{
+struct passwd *p;
+int ret;
+
+if (!user_name || g_strcmp0(user_name, g_get_user_name())) {
+g_set_error_literal(error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "Invalid 
user name");
+return NULL;
+}
+
+p = g_new0(struct passwd, 1);
+p->pw_dir = (char *)g_get_home_dir();
+p->pw_uid = geteuid();
+p->pw_gid = getegid();
+
+ret = g_mkdir_with_parents(p->pw_dir, 0700);
+g_assert_cmpint(ret, ==, 0);
+
+return p;
+}
+
+#define g_unix_get_passwd_entry_qemu(username, err) 
test_get_passwd_entry(username, err)
+#endif
+
+static struct passwd *
+get_passwd_entry(const char *username, Error **errp)
+{
+g_autoptr(GError) err = NULL;
+struct passwd *p;
+
+ERRP_GUARD();
+
+p = g_unix_get_passwd_entry_qemu(username, );
+if (p == NULL) {
+error_setg(errp, "failed to lookup user '%s': %s",
+   username, err->message);
+return NULL;
+}
+
+return p;
+}
+
+static bool
+mkdir_for_user(const char *path, const struct passwd *p, mode_t mode, Error 
**errp)
+{
+ERRP_GUARD();
+
+if (g_mkdir(path, mode) == -1) {
+error_setg(errp, "failed to create directory '%s': %s",
+   path, g_strerror(errno));
+return false;
+}
+
+if (chown(path, p->pw_uid, p->pw_gid) == -1) {
+error_setg(errp, "failed to set ownership of directory '%s': %s",
+   path, g_strerror(errno));
+return false;
+}
+
+if (chmod(path, mode) == -1) {
+error_setg(errp, "failed to set permissions of directory '%s': %s",
+   path, g_strerror(errno));
+return false;
+}
+
+return true;
+}
+
+static bool
+check_openssh_pub_key(const char *key, Error **errp)
+{
+ERRP_GUARD();
+
+/* simple sanity-check, we may want more? */
+if (!key || key[0] == '#' || strchr(key, '\n')) {
+error_setg(errp, "invalid OpenSSH public key: '%s'", key);
+return false;
+}
+
+return true;
+}
+
+static bool
+check_openssh_pub_keys(strList *keys, size_t *nkeys, Error **errp)
+{
+size_t n = 0;
+strList *k;
+
+ERRP_GUARD();
+
+for (k = keys; k != NULL; k = k->next) {
+if (!check_openssh_pub_key(k->value, errp)) {
+return false;
+}
+n++;
+}
+
+if (nkeys) {
+*nkeys = n;
+}
+return true;
+}
+
+static bool
+write_authkeys(const char *path, const GStrv keys, Error **errp)
+{
+g_autofree char *contents = NULL;
+g_autoptr(GError) err = NULL;
+
+ERRP_GUARD();
+
+contents = g_strjoinv("\n", keys);
+if (!g_file_set_contents(path, contents, -1, )) {
+error_setg(errp, "failed to write to '%s': %s", path, err->message);
+return false;
+}
+
+if (chmod(path, 0600) == -1) {
+error_setg(errp, "failed to set permissions of '%s': %s",
+   path, g_strerror(errno));
+return false;
+}
+
+return true;
+}
+
+static GStrv
+read_authkeys(const char *path, Error **errp)
+{
+g_autoptr(GError) err = NULL;
+g_autofree char *contents = NULL;
+
+ERRP_GUARD();
+
+if (!g_file_get_contents(path, , NULL, )) {
+error_setg(errp, "failed to read '%s': %s", path, err->message);
+return NULL;
+}
+
+return g_strsplit(contents, "\n", -1);
+
+}
+
+void
+qmp_guest_ssh_add_authorized_keys(const char *username, strList *keys,
+  Error **errp)
+{
+g_autofree struct passwd *p = NULL;
+  

[PATCH 1/2] glib-compat: add g_unix_get_passwd_entry_qemu()

2020-10-13 Thread marcandre . lureau
From: Marc-André Lureau 

The glib function was introduced in 2.64. It's a safer version of
getpwnam, and also simpler to use than getpwnam_r.

Currently, it's only use by the next patch in qemu-ga, which doesn't
(well well...) need the thread safety guarantees. Since the fallback
version is still unsafe, I would rather keep the _qemu postfix, to make
sure it's not being misused by mistake. When/if necessary, we can
implement a safer fallback and drop the _qemu suffix.

Signed-off-by: Marc-André Lureau 
---
 include/glib-compat.h | 24 
 1 file changed, 24 insertions(+)

diff --git a/include/glib-compat.h b/include/glib-compat.h
index 0b0ec76299..2a56b3462b 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -30,6 +30,9 @@
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 
 #include 
+#if defined(G_OS_UNIX)
+#include 
+#endif
 
 /*
  * Note that because of the GLIB_VERSION_MAX_ALLOWED constant above, allowing
@@ -72,6 +75,27 @@
 gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout);
 #endif
 
+#if defined(G_OS_UNIX)
+/* Note: The fallback implementation is not MT-safe, and it returns a copy of
+ * the libc passwd (must be g_free() after use) but not the content. Because of
+ * these important differences the caller must be aware of, it's not #define 
for
+ * GLib API substitution. */
+static inline struct passwd *
+g_unix_get_passwd_entry_qemu(const gchar *user_name, GError **error)
+{
+#if GLIB_CHECK_VERSION(2, 64, 0)
+return g_unix_get_passwd_entry(user_name, error);
+#else
+struct passwd *p = getpwnam(user_name);
+if (!p) {
+g_set_error(error, G_UNIX_ERROR, 0, g_strerror(errno));
+return NULL;
+}
+return g_memdup(p, sizeof(*p));
+#endif
+}
+#endif /* G_OS_UNIX */
+
 #pragma GCC diagnostic pop
 
 #endif
-- 
2.28.0




[PATCH 0/2] qemu-ga: add ssh-{add,remove}-authorized-keys

2020-10-13 Thread marcandre . lureau
From: Marc-André Lureau 

Hi,

Add two new commands to help modify ~/.ssh/authorized_keys.

Although it's possible already to modify the authorized_keys files via
file-{read,write} or exec, the commands are often denied by default, and the
logic is left to the client. Let's add specific commands for this job.

Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=1885332

Marc-André Lureau (2):
  glib-compat: add g_unix_get_passwd_entry_qemu()
  qga: add ssh-{add,remove}-authorized-keys

 include/glib-compat.h|  24 +++
 qga/commands-posix-ssh.c | 394 +++
 qga/commands-win32.c |  10 +
 qga/meson.build  |  17 +-
 qga/qapi-schema.json |  32 
 5 files changed, 476 insertions(+), 1 deletion(-)
 create mode 100644 qga/commands-posix-ssh.c

-- 
2.28.0





Re: [PATCH 07/10] target/arm: Implement v8.1M low-overhead-loop instructions

2020-10-13 Thread Peter Maydell
On Tue, 13 Oct 2020 at 18:30, Richard Henderson
 wrote:
> Well, the only further comment is that, in the followup, only WLS gains the IT
> block check.  While I understand that's required to avoid an abort in QEMU for
> this case, all three of the insns have that case as CONSTRAINED UNPREDICTABLE.
>  It might be worthwhile checking for IT in all of them, just to continue our
> normal "unpredictable raises sigill, when easy" choice.

Maybe, but there are a lot of instructions that are
unpredictable-in-an-IT-block (CPSID, CRC32B, HVC...)
and our general approach seems to have been "don't check unless
it would cause an actual problem". The only place I can find
where we do check for this case is in trans_B_cond_thumb(),
which we do for the same reason as here.

thanks
-- PMM



Re: [PATCH] target/arm: AArch32 VCVT fixed-point to float is always round-to-nearest

2020-10-13 Thread Richard Henderson
On 10/13/20 3:35 AM, Peter Maydell wrote:
> For AArch32, unlike the VCVT of integer to float, which honours the
> rounding mode specified by the FPSCR, VCVT of fixed-point to float is
> always round-to-nearest. (AArch64 fixed-point-to-float conversions
> always honour the FPCR rounding mode.)
> 
> Implement this by providing _round_to_nearest versions of the
> relevant helpers which set the rounding mode temporarily when making
> the call to the underlying softfloat function.
> 
> We only need to change the VFP VCVT instructions, because the
> standard- FPSCR value used by the Neon VCVT is always set to
> round-to-nearest, so we don't need to do the extra work of saving
> and restoring the rounding mode.
> 
> Signed-off-by: Peter Maydell 
> ---
>  target/arm/helper.h| 13 +
>  target/arm/vfp_helper.c| 23 ++-
>  target/arm/translate-vfp.c.inc | 24 
>  3 files changed, 47 insertions(+), 13 deletions(-)

I guess this is ok.  I do wonder whether these extra helpers are really that
much better than using set_rmode.  But some of our existing *_round_to_zero
helpers are similar.

Reviewed-by: Richard Henderson 


r~



Re: [PATCH 09/10] target/arm: Implement FPSCR.LTPSIZE for M-profile LOB extension

2020-10-13 Thread Richard Henderson
On 10/12/20 8:37 AM, Peter Maydell wrote:
> @@ -198,8 +200,14 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t 
> val)
>  /*
>   * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
>   * and also for the trapped-exception-handling bits IxE.
> + * From v8.1M with the low-overhead-loop extension bits
> + * [18:16] are used for LTPSIZE and (since we don't implement
> + * MVE) always read as 4 and ignore writes.
>   */
>  val &= 0xf7c0009f;
> +if (cpu_isar_feature(aa32_lob, cpu)) {
> +val |= 4 << 16;
> +}
>  }
>  
>  vfp_set_fpscr_to_host(env, val);
> @@ -212,9 +220,18 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t 
> val)
>   * (which are stored in fp_status), and the other RES0 bits
>   * in between, then we clear all of the low 16 bits.
>   */
> -env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c8;
> -env->vfp.vec_len = (val >> 16) & 7;
> -env->vfp.vec_stride = (val >> 20) & 3;
> +if (cpu_isar_feature(aa32_lob, cpu)) {
> +/*
> + * M-profile low-overhead-loop extension: [18:16] are LTPSIZE
> + * and we keep them in vfp.xregs[].
> + */
> +env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7cf;
> +} else {
> +/* Those bits might be the old-style short vector length/stride */
> +env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c8;
> +env->vfp.vec_len = (val >> 16) & 7;
> +env->vfp.vec_stride = (val >> 20) & 3;
> +}

I think these two sets of masking are confusing.
Perhaps usefully rearranged as

if (!fp16) {
val &= ~fz16;
}
vfp_set_fpscr_to_host(env, val);

if (!m-profile) {
vec_len = extract32(val, 16, 3);
vec_stride = extract32(val, 20, 2);
}
val &= 0xf7c8;
if (lob) {
val |= 4 << 16;
}
fpscr = val;

Which then obviates the next patch.


r~



Re: [PATCH v7 8/8] mac_oldworld: Add SPD data to cover RAM

2020-10-13 Thread Philippe Mathieu-Daudé

On 6/29/20 8:55 PM, BALATON Zoltan wrote:

OpenBIOS gets RAM size via fw_cfg but rhe original board firmware


Typo "the".


detects RAM using SPD data so generate and add SDP eeproms to cover as


EEPROMs?


much RAM as possible to describe with SPD (this may be less than the
actual ram_size due to SDRAM size constraints).

This patch is more complex as it should be which I intend to fix once
agreement can be made on how to get back the necessary functionality
removed by previous patches. See in this thread:
https://lists.nongnu.org/archive/html/qemu-devel/2020-06/msg08710.html

Signed-off-by: BALATON Zoltan 
---
  hw/ppc/mac_oldworld.c | 19 ++-
  1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 6276973c95..6a27287c9f 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -34,6 +34,7 @@
  #include "hw/input/adb.h"
  #include "sysemu/sysemu.h"
  #include "net/net.h"
+#include "hw/i2c/smbus_eeprom.h"
  #include "hw/isa/isa.h"
  #include "hw/pci/pci.h"
  #include "hw/pci/pci_host.h"
@@ -104,6 +105,8 @@ static void ppc_heathrow_init(MachineState *machine)
  DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
  void *fw_cfg;
  uint64_t tbfreq;
+uint8_t *spd_data[3] = {};
+I2CBus *i2c_bus;
  
  /* init CPUs */

  for (i = 0; i < smp_cpus; i++) {
@@ -121,8 +124,16 @@ static void ppc_heathrow_init(MachineState *machine)
   "maximum 2047 MB", ram_size / MiB);
  exit(1);
  }
-
  memory_region_add_subregion(get_system_memory(), 0, machine->ram);
+for (i = 0; i < 3; i++) {


3 -> ARRAY_SIZE(spd_data)


+int size_left = ram_size - i * 512 * MiB;
+if (size_left > 0) {
+uint32_t s = size_left / MiB;
+s = (s > 512 ? 512 : s);


MIN()?


+s = 1U << (31 - clz32(s));
+spd_data[i] = spd_data_generate(SDR, s * MiB);
+}
+}
  
  /* allocate and load firmware ROM */

  memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", PROM_SIZE,
@@ -302,6 +313,12 @@ static void ppc_heathrow_init(MachineState *machine)
  macio_ide_init_drives(macio_ide, [MAX_IDE_DEVS]);
  
  dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));

+i2c_bus = I2C_BUS(qdev_get_child_bus(dev, "i2c"));
+for (i = 0; i < 3; i++) {


3 -> ARRAY_SIZE(spd_data)


+if (spd_data[i]) {
+smbus_eeprom_init_one(i2c_bus, 0x50 + i, spd_data[i]);
+}
+}
  adb_bus = qdev_get_child_bus(dev, "adb.0");
  dev = qdev_new(TYPE_ADB_KEYBOARD);
  qdev_realize_and_unref(dev, adb_bus, _fatal);






Re: [PATCH v7 4/8] mac_oldworld: Drop some variables

2020-10-13 Thread Philippe Mathieu-Daudé

On 6/29/20 8:55 PM, BALATON Zoltan wrote:

Values not used frequently enough may not worth putting in a local
variable, especially with names almost as long as the original value
because that does not improve readability, to the contrary it makes it
harder to see what value is used. Drop a few such variables.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Mark Cave-Ayland 
---
  hw/ppc/mac_oldworld.c | 33 -
  1 file changed, 16 insertions(+), 17 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v7 2/8] mac_newworld: Allow loading binary ROM image

2020-10-13 Thread Philippe Mathieu-Daudé

On 6/29/20 8:55 PM, BALATON Zoltan wrote:

Fall back to load binary ROM image if loading ELF fails. This also
moves PROM_BASE and PROM_SIZE defines to board as these are matching
the ROM size and address on this board and removes the now unused
PROM_ADDR and BIOS_SIZE defines from common mac.h.

Signed-off-by: BALATON Zoltan 


Reviewed-by: Philippe Mathieu-Daudé 


---
Unlike mac_oldworld where the openbios-ppc image loads at end of ROM
region here we only check size and assume ELF image is loaded from
PROM_BASE, Checking the load addr here is tricky because this board is
also be compiled both 64 and 32 bit and load_elf seems to always
return 64 bit value so handling that could become a mess. If this is a
problem then it's a preexisting one so should be fixed in a separate
patch. This one just allows loading ROM binary too otherwise
preserving previous behaviour.

  hw/ppc/mac.h  |  2 --
  hw/ppc/mac_newworld.c | 22 ++
  2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 04e498bc57..195967facd 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -40,10 +40,8 @@
  /* SMP is not enabled, for now */
  #define MAX_CPUS 1
  
-#define BIOS_SIZE(1 * MiB)

  #define NVRAM_SIZE0x2000
  #define PROM_FILENAME"openbios-ppc"
-#define PROM_ADDR 0xfff0
  
  #define KERNEL_LOAD_ADDR 0x0100

  #define KERNEL_GAP   0x0010
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 828c5992ae..c88142af57 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -82,6 +82,8 @@
  
  #define NDRV_VGA_FILENAME "qemu_vga.ndrv"
  
+#define PROM_BASE 0xfff0

+#define PROM_SIZE (1 * MiB)
  
  static void fw_cfg_boot_set(void *opaque, const char *boot_device,

  Error **errp)
@@ -100,7 +102,7 @@ static void ppc_core99_reset(void *opaque)
  
  cpu_reset(CPU(cpu));

  /* 970 CPUs want to get their initial IP as part of their boot protocol */
-cpu->env.nip = PROM_ADDR + 0x100;
+cpu->env.nip = PROM_BASE + 0x100;
  }
  
  /* PowerPC Mac99 hardware initialisation */

@@ -153,25 +155,29 @@ static void ppc_core99_init(MachineState *machine)
  /* allocate RAM */
  memory_region_add_subregion(get_system_memory(), 0, machine->ram);
  
-/* allocate and load BIOS */

-memory_region_init_rom(bios, NULL, "ppc_core99.bios", BIOS_SIZE,
+/* allocate and load firmware ROM */
+memory_region_init_rom(bios, NULL, "ppc_core99.bios", PROM_SIZE,
 _fatal);
+memory_region_add_subregion(get_system_memory(), PROM_BASE, bios);
  
-if (bios_name == NULL)

+if (!bios_name) {
  bios_name = PROM_FILENAME;
+}
  filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios);
-
-/* Load OpenBIOS (ELF) */
  if (filename) {
+/* Load OpenBIOS (ELF) */
  bios_size = load_elf(filename, NULL, NULL, NULL, NULL,
   NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
  
+if (bios_size <= 0) {

+/* or load binary ROM image */
+bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE);
+}
  g_free(filename);
  } else {
  bios_size = -1;
  }
-if (bios_size < 0 || bios_size > BIOS_SIZE) {
+if (bios_size < 0 || bios_size > PROM_SIZE) {
  error_report("could not load PowerPC bios '%s'", bios_name);
  exit(1);
  }






Re: [PATCH v7 3/8] mac_oldworld: Drop a variable, use get_system_memory() directly

2020-10-13 Thread Philippe Mathieu-Daudé

On 6/29/20 8:55 PM, BALATON Zoltan wrote:

Half of the occurances already use get_system_memory() directly
instead of sysmem variable, convert the two other uses to
get_system_memory() too which seems to be more common and drop the
variable.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Mark Cave-Ayland 
---
  hw/ppc/mac_oldworld.c | 5 ++---
  1 file changed, 2 insertions(+), 3 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH] target/riscv: Fix implementation of HLVX.WU instruction

2020-10-13 Thread Philippe Mathieu-Daudé

On 10/13/20 7:22 PM, Georg Kotheimer wrote:

The HLVX.WU instruction is supposed to read a machine word,
but prior to this change it read a byte instead.



Fixes: 8c5362acb57 ("target/riscv: Allow generating hlv/hlvx/hsv 
instructions")

Reviewed-by: Philippe Mathieu-Daudé 


Signed-off-by: Georg Kotheimer 
---
  target/riscv/op_helper.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 9b9ada45a9..3b7bd6ee88 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -334,12 +334,12 @@ target_ulong helper_hyp_x_load(CPURISCVState *env, 
target_ulong address,
  riscv_cpu_set_two_stage_lookup(env, true);
  
  switch (memop) {

-case MO_TEUL:
-pte = cpu_ldub_data_ra(env, address, GETPC());
-break;
  case MO_TEUW:
  pte = cpu_lduw_data_ra(env, address, GETPC());
  break;
+case MO_TEUL:
+pte = cpu_ldl_data_ra(env, address, GETPC());
+break;
  default:
  g_assert_not_reached();
  }






[PATCH v4 3/3] replay: do not build if TCG is not available

2020-10-13 Thread Claudio Fontana
this fixes non-TCG builds broken recently by replay reverse debugging.

stub the needed functions in stub/, including errors for hmp and qmp.
This includes duplicating some code in replay/, and puts the logic
for non-replay related events in the replay/ module (+ the stubs),
so this should be revisited in the future.

Surprisingly, only _one_ qtest was affected by this, ide-test.c, which
resulted in a buzz as the bh events were never delivered, and the bh
never executed.

Many other subsystems _should_ have been affected.

This fixes the immediate issue, however a better way to group replay
functionality to TCG-only code could be developed in the long term.

Signed-off-by: Claudio Fontana 
---
 block/meson.build  |  3 +-
 migration/savevm.c | 11 +++--
 net/meson.build|  3 +-
 replay/meson.build |  2 +-
 replay/replay-input.c  |  4 +-
 stubs/meson.build  |  1 -
 stubs/replay-user.c|  9 
 stubs/replay.c | 98 ++
 tests/ptimer-test-stubs.c  |  5 --
 tests/qtest/qmp-cmd-test.c |  3 ++
 ui/input.c | 12 -
 11 files changed, 125 insertions(+), 26 deletions(-)
 delete mode 100644 stubs/replay-user.c

diff --git a/block/meson.build b/block/meson.build
index 78e8b25232..01fe6f84d2 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -7,7 +7,6 @@ block_ss.add(files(
   'backup-top.c',
   'blkdebug.c',
   'blklogwrites.c',
-  'blkreplay.c',
   'blkverify.c',
   'block-backend.c',
   'block-copy.c',
@@ -42,6 +41,8 @@ block_ss.add(files(
   'write-threshold.c',
 ), zstd, zlib)
 
+block_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
+
 block_ss.add(when: 'CONFIG_QCOW1', if_true: files('qcow.c'))
 block_ss.add(when: 'CONFIG_VDI', if_true: files('vdi.c'))
 block_ss.add(when: 'CONFIG_CLOOP', if_true: files('cloop.c'))
diff --git a/migration/savevm.c b/migration/savevm.c
index d2e141f7b1..d9181ca520 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -63,6 +63,7 @@
 #include "migration/colo.h"
 #include "qemu/bitmap.h"
 #include "net/announce.h"
+#include "sysemu/tcg.h"
 
 const unsigned int postcopy_ram_discard_version = 0;
 
@@ -2674,10 +2675,12 @@ int save_snapshot(const char *name, Error **errp)
 return ret;
 }
 
-if (!replay_can_snapshot()) {
-error_setg(errp, "Record/replay does not allow making snapshot "
-   "right now. Try once more later.");
-return ret;
+if (tcg_enabled()) {
+if (!replay_can_snapshot()) {
+error_setg(errp, "Record/replay does not allow making snapshot "
+   "right now. Try once more later.");
+return ret;
+}
 }
 
 if (!bdrv_all_can_snapshot()) {
diff --git a/net/meson.build b/net/meson.build
index 1c7e3a3cb9..1076b0a7ab 100644
--- a/net/meson.build
+++ b/net/meson.build
@@ -7,7 +7,6 @@ softmmu_ss.add(files(
   'eth.c',
   'filter-buffer.c',
   'filter-mirror.c',
-  'filter-replay.c',
   'filter-rewriter.c',
   'filter.c',
   'hub.c',
@@ -17,6 +16,8 @@ softmmu_ss.add(files(
   'util.c',
 ))
 
+softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('filter-replay.c'))
+
 softmmu_ss.add(when: 'CONFIG_L2TPV3', if_true: files('l2tpv3.c'))
 softmmu_ss.add(when: slirp, if_true: files('slirp.c'))
 softmmu_ss.add(when: ['CONFIG_VDE', vde], if_true: files('vde.c'))
diff --git a/replay/meson.build b/replay/meson.build
index f91163fb1e..cb3207740a 100644
--- a/replay/meson.build
+++ b/replay/meson.build
@@ -1,4 +1,4 @@
-softmmu_ss.add(files(
+softmmu_ss.add(when: 'CONFIG_TCG', if_true: files(
   'replay.c',
   'replay-internal.c',
   'replay-events.c',
diff --git a/replay/replay-input.c b/replay/replay-input.c
index 1147e3d34e..5d1fd92e79 100644
--- a/replay/replay-input.c
+++ b/replay/replay-input.c
@@ -124,7 +124,7 @@ void replay_input_event(QemuConsole *src, InputEvent *evt)
 } else if (replay_mode == REPLAY_MODE_RECORD) {
 replay_add_input_event(QAPI_CLONE(InputEvent, evt));
 } else {
-qemu_input_event_send_impl(src, evt);
+g_assert_not_reached();
 }
 }
 
@@ -135,6 +135,6 @@ void replay_input_sync_event(void)
 } else if (replay_mode == REPLAY_MODE_RECORD) {
 replay_add_input_sync_event();
 } else {
-qemu_input_event_sync_impl();
+g_assert_not_reached();
 }
 }
diff --git a/stubs/meson.build b/stubs/meson.build
index 67f2a8c069..bbd2230d69 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -32,7 +32,6 @@ stub_ss.add(files('qtest.c'))
 stub_ss.add(files('ram-block.c'))
 stub_ss.add(files('ramfb.c'))
 stub_ss.add(files('replay.c'))
-stub_ss.add(files('replay-user.c'))
 stub_ss.add(files('runstate-check.c'))
 stub_ss.add(files('set-fd-handler.c'))
 stub_ss.add(files('sysbus.c'))
diff --git a/stubs/replay-user.c b/stubs/replay-user.c
deleted file mode 100644
index 2ad9e27203..00
--- a/stubs/replay-user.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "qemu/osdep.h"

[PATCH v4 1/3] tests/Makefile.include: unbreak non-tcg builds

2020-10-13 Thread Claudio Fontana
From: Paolo Bonzini 

remove dependency of check-block from non-native archs

Signed-off-by: Claudio Fontana 
---
 tests/Makefile.include | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 5aca98e60c..4037490b69 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -140,7 +140,7 @@ QEMU_IOTESTS_HELPERS-$(CONFIG_LINUX) = 
tests/qemu-iotests/socket_scm_helper$(EXE
 check: check-block
 check-block: $(SRC_PATH)/tests/check-block.sh qemu-img$(EXESUF) \
qemu-io$(EXESUF) qemu-nbd$(EXESUF) $(QEMU_IOTESTS_HELPERS-y) \
-   $(patsubst %-softmmu,qemu-system-%,$(filter 
%-softmmu,$(TARGET_DIRS)))
+   $(filter qemu-system-%, $(ninja-targets-c_LINKER) 
$(ninja-targets-cpp_LINKER))
@$<
 endif
 
-- 
2.26.2




[PATCH v4 2/3] qtest: unbreak non-TCG builds in bios-tables-test

2020-10-13 Thread Claudio Fontana
the tests assume TCG is available, thus breaking
for TCG-only tests, where only the TCG accelerator option
is passed to the QEMU binary.

Suggested-by: Paolo Bonzini 
Acked-by: Paolo Bonzini 
Signed-off-by: Claudio Fontana 
---
 tests/qtest/bios-tables-test.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 5647624492..18f535d4e8 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -127,6 +127,9 @@ static void free_test_data(test_data *data)
 {
 int i;
 
+if (!data->tables) {
+return;
+}
 for (i = 0; i < data->tables->len; ++i) {
 cleanup_table_descriptor(_array_index(data->tables, AcpiSdtTable, 
i));
 }
@@ -656,6 +659,13 @@ static void test_acpi_one(const char *params, test_data 
*data)
 char *args;
 bool use_uefi = data->uefi_fl1 && data->uefi_fl2;
 
+#ifndef CONFIG_TCG
+if (data->tcg_only) {
+g_test_skip("TCG disabled, skipping ACPI tcg_only test");
+return;
+}
+#endif /* CONFIG_TCG */
+
 if (use_uefi) {
 /*
  * TODO: convert '-drive if=pflash' to new syntax (see e33763be7cd3)
-- 
2.26.2




[PATCH v4 0/3] unbreak non-tcg builds

2020-10-13 Thread Claudio Fontana
This series now unbreaks current non-tcg builds
(!CONFIG_TCG).

tests Makefiles need to avoid relying on all non-native
archs binaries to be present,

bios-tables-test needs to skip tests that are tcg-only,

and notably the replay framework needs to consider that
it might not be functional (or its code present at all)
without TCG.

Tested ok target x86_64-softmmu on x86_64 host with:

./configure --enable-tcg --disable-kvm
./configure --enable-kvm --disable-tcg
./configure --enable-tcg --enable-kvm

running make check-qtest

v3 => v4:
* abandon attempts to avoid the code duplication and functional code
in stubs, just providing the minimal changes to get things working.

v2 => v3:

* do not alter the replay api, provide a block wrapper
instead to call into replay events handling
or the normal call flow depending on whether replay events are enabled.

v1: initial RFC

Claudio Fontana (2):
  qtest: unbreak non-TCG builds in bios-tables-test
  replay: do not build if TCG is not available

Paolo Bonzini (1):
  tests/Makefile.include: unbreak non-tcg builds

 block/meson.build  |  3 +-
 migration/savevm.c | 11 ++--
 net/meson.build|  3 +-
 replay/meson.build |  2 +-
 replay/replay-input.c  |  4 +-
 stubs/meson.build  |  1 -
 stubs/replay-user.c|  9 
 stubs/replay.c | 98 ++
 tests/Makefile.include |  2 +-
 tests/ptimer-test-stubs.c  |  5 --
 tests/qtest/bios-tables-test.c | 10 
 tests/qtest/qmp-cmd-test.c |  3 ++
 ui/input.c | 12 -
 13 files changed, 136 insertions(+), 27 deletions(-)
 delete mode 100644 stubs/replay-user.c

-- 
2.26.2




[PATCH] hw/block/nvme: add block utilization tracking

2020-10-13 Thread Klaus Jensen
From: Klaus Jensen 

This adds support for reporting the Deallocated or Unwritten Logical
Block error (DULBE). This requires tracking the allocated/deallocated
status of all logical blocks.

Introduce a bitmap that does this. The bitmap is always intialized to
all ones (aka, all blocks are allocated) on boot up. Blocks can then be
specifically deallocated using Write Zeroes. This ensures that we can
always guarantee zeroes to be returned from deallocated blocks.

When the device gains support for persistent state, the intention is to
remove the "allocated by default" behavior.

Signed-off-by: Klaus Jensen 
---
 hw/block/nvme-ns.h| 10 ++
 include/block/nvme.h  |  5 +++
 hw/block/nvme-ns.c| 10 ++
 hw/block/nvme.c   | 81 +++
 hw/block/trace-events |  2 ++
 5 files changed, 108 insertions(+)

diff --git a/hw/block/nvme-ns.h b/hw/block/nvme-ns.h
index 83734f4606e1..e91a83e2a03f 100644
--- a/hw/block/nvme-ns.h
+++ b/hw/block/nvme-ns.h
@@ -30,7 +30,17 @@ typedef struct NvmeNamespace {
 int64_t  size;
 NvmeIdNs id_ns;
 
+struct {
+struct {
+unsigned long *map;
+} utilization;
+} state;
+
 NvmeNamespaceParams params;
+
+struct {
+uint32_t err_rec;
+} features;
 } NvmeNamespace;
 
 static inline uint32_t nvme_nsid(NvmeNamespace *ns)
diff --git a/include/block/nvme.h b/include/block/nvme.h
index 6de2d5aa75a9..2249d77c2129 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -686,6 +686,7 @@ enum NvmeStatusCodes {
 NVME_E2E_REF_ERROR  = 0x0284,
 NVME_CMP_FAILURE= 0x0285,
 NVME_ACCESS_DENIED  = 0x0286,
+NVME_DULB   = 0x0287,
 NVME_MORE   = 0x2000,
 NVME_DNR= 0x4000,
 NVME_NO_COMPLETE= 0x,
@@ -902,6 +903,9 @@ enum NvmeIdCtrlLpa {
 #define NVME_AEC_NS_ATTR(aec)   ((aec >> 8) & 0x1)
 #define NVME_AEC_FW_ACTIVATION(aec) ((aec >> 9) & 0x1)
 
+#define NVME_ERR_REC_TLER(err_rec)  (err_rec & 0x)
+#define NVME_ERR_REC_DULBE(err_rec) (err_rec & 0x1)
+
 enum NvmeFeatureIds {
 NVME_ARBITRATION= 0x1,
 NVME_POWER_MANAGEMENT   = 0x2,
@@ -1022,6 +1026,7 @@ enum NvmeNsIdentifierType {
 
 
 #define NVME_ID_NS_NSFEAT_THIN(nsfeat)  ((nsfeat & 0x1))
+#define NVME_ID_NS_NSFEAT_DULBE(nsfeat) ((nsfeat >> 2) & 0x1)
 #define NVME_ID_NS_FLBAS_EXTENDED(flbas)((flbas >> 4) & 0x1)
 #define NVME_ID_NS_FLBAS_INDEX(flbas)   ((flbas & 0xf))
 #define NVME_ID_NS_MC_SEPARATE(mc)  ((mc >> 1) & 0x1)
diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
index b69cdaf27e43..b221fe02cd13 100644
--- a/hw/block/nvme-ns.c
+++ b/hw/block/nvme-ns.c
@@ -47,6 +47,9 @@ static void nvme_ns_init(NvmeNamespace *ns)
 
 lba_index = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas);
 ns->id_ns.lbaf[lba_index].ds = 31 - clz32(ns->blkconf.logical_block_size);
+
+/* support DULBE */
+id_ns->nsfeat |= 0x4;
 }
 
 static int nvme_ns_init_blk(NvmeCtrl *n, NvmeNamespace *ns, Error **errp)
@@ -86,6 +89,8 @@ static int nvme_ns_check_constraints(NvmeNamespace *ns, Error 
**errp)
 
 int nvme_ns_setup(NvmeCtrl *n, NvmeNamespace *ns, Error **errp)
 {
+uint64_t nlbas;
+
 if (nvme_ns_check_constraints(ns, errp)) {
 return -1;
 }
@@ -95,6 +100,11 @@ int nvme_ns_setup(NvmeCtrl *n, NvmeNamespace *ns, Error 
**errp)
 }
 
 nvme_ns_init(ns);
+
+nlbas = nvme_ns_nlbas(ns);
+ns->state.utilization.map = bitmap_new(nlbas);
+bitmap_fill(ns->state.utilization.map, nlbas);
+
 if (nvme_register_namespace(n, ns, errp)) {
 return -1;
 }
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 9d30ca69dcf1..b0cf328f8f2e 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -105,6 +105,7 @@ static const bool nvme_feature_support[NVME_FID_MAX] = {
 
 static const uint32_t nvme_feature_cap[NVME_FID_MAX] = {
 [NVME_TEMPERATURE_THRESHOLD]= NVME_FEAT_CAP_CHANGE,
+[NVME_ERROR_RECOVERY]   = NVME_FEAT_CAP_CHANGE | NVME_FEAT_CAP_NS,
 [NVME_VOLATILE_WRITE_CACHE] = NVME_FEAT_CAP_CHANGE,
 [NVME_NUMBER_OF_QUEUES] = NVME_FEAT_CAP_CHANGE,
 [NVME_ASYNCHRONOUS_EVENT_CONF]  = NVME_FEAT_CAP_CHANGE,
@@ -888,6 +889,38 @@ static inline uint16_t nvme_check_bounds(NvmeCtrl *n, 
NvmeNamespace *ns,
 return NVME_SUCCESS;
 }
 
+static inline uint16_t nvme_check_dulbe(NvmeNamespace *ns, uint64_t slba,
+uint32_t nlb)
+{
+uint64_t elba = slba + nlb;
+
+if (find_next_zero_bit(ns->state.utilization.map, elba, slba) < elba) {
+return NVME_DULB;
+}
+
+return NVME_SUCCESS;
+}
+
+static inline void nvme_allocate(NvmeNamespace *ns, uint64_t slba,
+ uint32_t nlb)
+{
+if (!nvme_check_dulbe(ns, slba, nlb)) {
+return;
+}
+
+trace_pci_nvme_allocate(nvme_nsid(ns), slba, nlb);
+
+

  1   2   3   4   >