[PULL 10/57] hw/arm/aspeed: Describe each PCA9552 device

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

We have 2 distinct PCA9552 devices. Set their description
to distinguish them when looking at the trace events.

Description name taken from:
https://github.com/open-power/witherspoon-xml/blob/master/witherspoon.xml

Reviewed-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Corey Minyard 
Reviewed-by: Markus Armbruster 
Tested-by: Cédric Le Goater 
Message-id: 20200623072723.6324-8-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 hw/arm/aspeed.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 665d04fbf68..379f9672a56 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -508,12 +508,15 @@ static void witherspoon_bmc_i2c_init(AspeedMachineState 
*bmc)
 {
 AspeedSoCState *soc = &bmc->soc;
 uint8_t *eeprom_buf = g_malloc0(8 * 1024);
+DeviceState *dev;
 
 /* Bus 3: TODO bmp280@77 */
 /* Bus 3: TODO max31785@52 */
 /* Bus 3: TODO dps310@76 */
-i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
- 0x60);
+dev = i2c_try_create_slave(TYPE_PCA9552, 0x60);
+qdev_prop_set_string(dev, "description", "pca1");
+i2c_realize_and_unref(dev, aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3),
+  &error_fatal);
 
 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
@@ -528,8 +531,10 @@ static void witherspoon_bmc_i2c_init(AspeedMachineState 
*bmc)
 
 smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
   eeprom_buf);
-i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
- 0x60);
+dev = i2c_try_create_slave(TYPE_PCA9552, 0x60);
+qdev_prop_set_string(dev, "description", "pca0");
+i2c_realize_and_unref(dev, aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11),
+  &error_fatal);
 /* Bus 11: TODO ucd90160@64 */
 }
 
-- 
2.20.1




[PULL 22/57] target/arm: Revise decoding for disas_add_sub_imm

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

The current Arm ARM has adjusted the official decode of
"Add/subtract (immediate)" so that the shift field is only bit 22,
and bit 23 is part of the op1 field of the parent category
"Data processing - immediate".

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-11-richard.hender...@linaro.org
Suggested-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-a64.c | 23 ---
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 30683061f94..03aa0925983 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -3754,22 +3754,22 @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t 
insn)
 /*
  * Add/subtract (immediate)
  *
- *  31 30 29 28   24 23 22 21 10 9   5 4   0
- * +--+--+--+---+-+-+-+-+
- * |sf|op| S| 1 0 0 0 1 |shift|imm12|  Rn | Rd  |
- * +--+--+--+---+-+-+-+-+
+ *  31 30 29 28 23 22 21 10 9   5 4   0
+ * +--+--+--+-+--+-+-+-+
+ * |sf|op| S| 1 0 0 0 1 0 |sh|imm12|  Rn | Rd  |
+ * +--+--+--+-+--+-+-+-+
  *
  *sf: 0 -> 32bit, 1 -> 64bit
  *op: 0 -> add  , 1 -> sub
  * S: 1 -> set flags
- * shift: 00 -> LSL imm by 0, 01 -> LSL imm by 12
+ *sh: 1 -> LSL imm by 12
  */
 static void disas_add_sub_imm(DisasContext *s, uint32_t insn)
 {
 int rd = extract32(insn, 0, 5);
 int rn = extract32(insn, 5, 5);
 uint64_t imm = extract32(insn, 10, 12);
-int shift = extract32(insn, 22, 2);
+bool shift = extract32(insn, 22, 1);
 bool setflags = extract32(insn, 29, 1);
 bool sub_op = extract32(insn, 30, 1);
 bool is_64bit = extract32(insn, 31, 1);
@@ -3778,15 +3778,8 @@ static void disas_add_sub_imm(DisasContext *s, uint32_t 
insn)
 TCGv_i64 tcg_rd = setflags ? cpu_reg(s, rd) : cpu_reg_sp(s, rd);
 TCGv_i64 tcg_result;
 
-switch (shift) {
-case 0x0:
-break;
-case 0x1:
+if (shift) {
 imm <<= 12;
-break;
-default:
-unallocated_encoding(s);
-return;
 }
 
 tcg_result = tcg_temp_new_i64();
@@ -4174,7 +4167,7 @@ static void disas_data_proc_imm(DisasContext *s, uint32_t 
insn)
 case 0x20: case 0x21: /* PC-rel. addressing */
 disas_pc_rel_adr(s, insn);
 break;
-case 0x22: case 0x23: /* Add/subtract (immediate) */
+case 0x22: /* Add/subtract (immediate) */
 disas_add_sub_imm(s, insn);
 break;
 case 0x24: /* Logical (immediate) */
-- 
2.20.1




[PULL 31/57] target/arm: Implement the LDGM, STGM, STZGM instructions

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-20-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/helper-a64.h|  3 ++
 target/arm/translate.h |  2 +
 target/arm/mte_helper.c| 84 ++
 target/arm/translate-a64.c | 72 
 4 files changed, 153 insertions(+), 8 deletions(-)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index 2fa61b86fa7..7b628d100e0 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -113,3 +113,6 @@ DEF_HELPER_FLAGS_2(stg_stub, TCG_CALL_NO_WG, void, env, i64)
 DEF_HELPER_FLAGS_3(st2g, TCG_CALL_NO_WG, void, env, i64, i64)
 DEF_HELPER_FLAGS_3(st2g_parallel, TCG_CALL_NO_WG, void, env, i64, i64)
 DEF_HELPER_FLAGS_2(st2g_stub, TCG_CALL_NO_WG, void, env, i64)
+DEF_HELPER_FLAGS_2(ldgm, TCG_CALL_NO_WG, i64, env, i64)
+DEF_HELPER_FLAGS_3(stgm, TCG_CALL_NO_WG, void, env, i64, i64)
+DEF_HELPER_FLAGS_3(stzgm_tags, TCG_CALL_NO_WG, void, env, i64, i64)
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 98bcc37c479..16f2699ad72 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -91,6 +91,8 @@ typedef struct DisasContext {
  *  < 0, set by the current instruction.
  */
 int8_t btype;
+/* A copy of cpu->dcz_blocksize. */
+uint8_t dcz_blocksize;
 /* True if this page is guarded.  */
 bool guarded_page;
 /* Bottom two bits of XScale c15_cpar coprocessor access control reg */
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 7ec7930dfc8..27d4b4536c0 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -274,3 +274,87 @@ void HELPER(st2g_stub)(CPUARMState *env, uint64_t ptr)
 probe_write(env, ptr + TAG_GRANULE, TAG_GRANULE, mmu_idx, ra);
 }
 }
+
+#define LDGM_STGM_SIZE  (4 << GMID_EL1_BS)
+
+uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
+{
+int mmu_idx = cpu_mmu_index(env, false);
+uintptr_t ra = GETPC();
+void *tag_mem;
+
+ptr = QEMU_ALIGN_DOWN(ptr, LDGM_STGM_SIZE);
+
+/* Trap if accessing an invalid page.  */
+tag_mem = allocation_tag_mem(env, mmu_idx, ptr, MMU_DATA_LOAD,
+ LDGM_STGM_SIZE, MMU_DATA_LOAD,
+ LDGM_STGM_SIZE / (2 * TAG_GRANULE), ra);
+
+/* The tag is squashed to zero if the page does not support tags.  */
+if (!tag_mem) {
+return 0;
+}
+
+QEMU_BUILD_BUG_ON(GMID_EL1_BS != 6);
+/*
+ * We are loading 64-bits worth of tags.  The ordering of elements
+ * within the word corresponds to a 64-bit little-endian operation.
+ */
+return ldq_le_p(tag_mem);
+}
+
+void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
+{
+int mmu_idx = cpu_mmu_index(env, false);
+uintptr_t ra = GETPC();
+void *tag_mem;
+
+ptr = QEMU_ALIGN_DOWN(ptr, LDGM_STGM_SIZE);
+
+/* Trap if accessing an invalid page.  */
+tag_mem = allocation_tag_mem(env, mmu_idx, ptr, MMU_DATA_STORE,
+ LDGM_STGM_SIZE, MMU_DATA_LOAD,
+ LDGM_STGM_SIZE / (2 * TAG_GRANULE), ra);
+
+/*
+ * Tag store only happens if the page support tags,
+ * and if the OS has enabled access to the tags.
+ */
+if (!tag_mem) {
+return;
+}
+
+QEMU_BUILD_BUG_ON(GMID_EL1_BS != 6);
+/*
+ * We are storing 64-bits worth of tags.  The ordering of elements
+ * within the word corresponds to a 64-bit little-endian operation.
+ */
+stq_le_p(tag_mem, val);
+}
+
+void HELPER(stzgm_tags)(CPUARMState *env, uint64_t ptr, uint64_t val)
+{
+uintptr_t ra = GETPC();
+int mmu_idx = cpu_mmu_index(env, false);
+int log2_dcz_bytes, log2_tag_bytes;
+intptr_t dcz_bytes, tag_bytes;
+uint8_t *mem;
+
+/*
+ * In arm_cpu_realizefn, we assert that dcz > LOG2_TAG_GRANULE+1,
+ * i.e. 32 bytes, which is an unreasonably small dcz anyway,
+ * to make sure that we can access one complete tag byte here.
+ */
+log2_dcz_bytes = env_archcpu(env)->dcz_blocksize + 2;
+log2_tag_bytes = log2_dcz_bytes - (LOG2_TAG_GRANULE + 1);
+dcz_bytes = (intptr_t)1 << log2_dcz_bytes;
+tag_bytes = (intptr_t)1 << log2_tag_bytes;
+ptr &= -dcz_bytes;
+
+mem = allocation_tag_mem(env, mmu_idx, ptr, MMU_DATA_STORE, dcz_bytes,
+ MMU_DATA_STORE, tag_bytes, ra);
+if (mem) {
+int tag_pair = (val & 0xf) * 0x11;
+memset(mem, tag_pair, tag_bytes);
+}
+}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index e2295a371b2..7dc493774ec 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -3736,7 +3736,7 @@ static void disas_ldst_tag(DisasContext *s, uint32_t insn)
 uint64_t offset = sextract64(insn, 12, 9) << LOG2_TAG_GRANULE;
 int op2 = extract32(insn, 10, 2);
 int op1 = extract3

[PULL 33/57] target/arm: Move regime_el to internals.h

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

We will shortly need this in mte_helper.c as well.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-22-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/internals.h | 36 
 target/arm/helper.c| 36 
 2 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 5c69d4e5a56..c36fcb151b7 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -913,6 +913,42 @@ static inline bool regime_is_pan(CPUARMState *env, 
ARMMMUIdx mmu_idx)
 }
 }
 
+/* Return the exception level which controls this address translation regime */
+static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
+{
+switch (mmu_idx) {
+case ARMMMUIdx_E20_0:
+case ARMMMUIdx_E20_2:
+case ARMMMUIdx_E20_2_PAN:
+case ARMMMUIdx_Stage2:
+case ARMMMUIdx_E2:
+return 2;
+case ARMMMUIdx_SE3:
+return 3;
+case ARMMMUIdx_SE10_0:
+return arm_el_is_aa64(env, 3) ? 1 : 3;
+case ARMMMUIdx_SE10_1:
+case ARMMMUIdx_SE10_1_PAN:
+case ARMMMUIdx_Stage1_E0:
+case ARMMMUIdx_Stage1_E1:
+case ARMMMUIdx_Stage1_E1_PAN:
+case ARMMMUIdx_E10_0:
+case ARMMMUIdx_E10_1:
+case ARMMMUIdx_E10_1_PAN:
+case ARMMMUIdx_MPrivNegPri:
+case ARMMMUIdx_MUserNegPri:
+case ARMMMUIdx_MPriv:
+case ARMMMUIdx_MUser:
+case ARMMMUIdx_MSPrivNegPri:
+case ARMMMUIdx_MSUserNegPri:
+case ARMMMUIdx_MSPriv:
+case ARMMMUIdx_MSUser:
+return 1;
+default:
+g_assert_not_reached();
+}
+}
+
 /* Return the FSR value for a debug exception (watchpoint, hardware
  * breakpoint or BKPT insn) targeting the specified exception level.
  */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d8c31d03dad..d14313de664 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9793,42 +9793,6 @@ void arm_cpu_do_interrupt(CPUState *cs)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-/* Return the exception level which controls this address translation regime */
-static uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
-{
-switch (mmu_idx) {
-case ARMMMUIdx_E20_0:
-case ARMMMUIdx_E20_2:
-case ARMMMUIdx_E20_2_PAN:
-case ARMMMUIdx_Stage2:
-case ARMMMUIdx_E2:
-return 2;
-case ARMMMUIdx_SE3:
-return 3;
-case ARMMMUIdx_SE10_0:
-return arm_el_is_aa64(env, 3) ? 1 : 3;
-case ARMMMUIdx_SE10_1:
-case ARMMMUIdx_SE10_1_PAN:
-case ARMMMUIdx_Stage1_E0:
-case ARMMMUIdx_Stage1_E1:
-case ARMMMUIdx_Stage1_E1_PAN:
-case ARMMMUIdx_E10_0:
-case ARMMMUIdx_E10_1:
-case ARMMMUIdx_E10_1_PAN:
-case ARMMMUIdx_MPrivNegPri:
-case ARMMMUIdx_MUserNegPri:
-case ARMMMUIdx_MPriv:
-case ARMMMUIdx_MUser:
-case ARMMMUIdx_MSPrivNegPri:
-case ARMMMUIdx_MSUserNegPri:
-case ARMMMUIdx_MSPriv:
-case ARMMMUIdx_MSUser:
-return 1;
-default:
-g_assert_not_reached();
-}
-}
-
 uint64_t arm_sctlr(CPUARMState *env, int el)
 {
 /* Only EL0 needs to be adjusted for EL1&0 or EL2&0. */
-- 
2.20.1




[PULL 04/57] hw/i2c/core: Add i2c_try_create_slave() and i2c_realize_and_unref()

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

Extract i2c_try_create_slave() and i2c_realize_and_unref()
from i2c_create_slave().
We can now set properties on a I2CSlave before it is realized.

This is in line with the recent qdev/QOM changes merged
in commit 6675a653d2e.

Reviewed-by: Corey Minyard 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Markus Armbruster 
Tested-by: Cédric Le Goater 
Message-id: 20200623072723.6324-2-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 include/hw/i2c/i2c.h |  2 ++
 hw/i2c/core.c| 18 --
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
index 41172115652..d6e3d85faf0 100644
--- a/include/hw/i2c/i2c.h
+++ b/include/hw/i2c/i2c.h
@@ -80,6 +80,8 @@ int i2c_send(I2CBus *bus, uint8_t data);
 uint8_t i2c_recv(I2CBus *bus);
 
 DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr);
+DeviceState *i2c_try_create_slave(const char *name, uint8_t addr);
+bool i2c_realize_and_unref(DeviceState *dev, I2CBus *bus, Error **errp);
 
 /* lm832x.c */
 void lm832x_key_event(DeviceState *dev, int key, int state);
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 1aac457a2a0..acf34a12d6d 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -267,13 +267,27 @@ const VMStateDescription vmstate_i2c_slave = {
 }
 };
 
-DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr)
+DeviceState *i2c_try_create_slave(const char *name, uint8_t addr)
 {
 DeviceState *dev;
 
 dev = qdev_new(name);
 qdev_prop_set_uint8(dev, "address", addr);
-qdev_realize_and_unref(dev, &bus->qbus, &error_fatal);
+return dev;
+}
+
+bool i2c_realize_and_unref(DeviceState *dev, I2CBus *bus, Error **errp)
+{
+return qdev_realize_and_unref(dev, &bus->qbus, errp);
+}
+
+DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr)
+{
+DeviceState *dev;
+
+dev = i2c_try_create_slave(name, addr);
+i2c_realize_and_unref(dev, bus, &error_fatal);
+
 return dev;
 }
 
-- 
2.20.1




[PULL 21/57] target/arm: Implement the IRG instruction

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-10-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/helper-a64.h|  2 ++
 target/arm/internals.h |  5 +++
 target/arm/mte_helper.c| 72 ++
 target/arm/translate-a64.c | 18 ++
 target/arm/Makefile.objs   |  1 +
 5 files changed, 98 insertions(+)
 create mode 100644 target/arm/mte_helper.c

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index 3df7c185aa1..587ccbe42ff 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -103,3 +103,5 @@ DEF_HELPER_FLAGS_3(autda, TCG_CALL_NO_WG, i64, env, i64, 
i64)
 DEF_HELPER_FLAGS_3(autdb, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
 DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
+
+DEF_HELPER_FLAGS_3(irg, TCG_CALL_NO_RWG, i64, env, i64, i64)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 53e249687ba..ae611a6ff5d 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1261,4 +1261,9 @@ void arm_log_exception(int idx);
  */
 #define GMID_EL1_BS  6
 
+static inline uint64_t address_with_allocation_tag(uint64_t ptr, int rtag)
+{
+return deposit64(ptr, 56, 4, rtag);
+}
+
 #endif
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
new file mode 100644
index 000..539a04de84b
--- /dev/null
+++ b/target/arm/mte_helper.c
@@ -0,0 +1,72 @@
+/*
+ * ARM v8.5-MemTag Operations
+ *
+ * Copyright (c) 2020 Linaro, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "internals.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "exec/helper-proto.h"
+
+
+static int choose_nonexcluded_tag(int tag, int offset, uint16_t exclude)
+{
+if (exclude == 0x) {
+return 0;
+}
+if (offset == 0) {
+while (exclude & (1 << tag)) {
+tag = (tag + 1) & 15;
+}
+} else {
+do {
+do {
+tag = (tag + 1) & 15;
+} while (exclude & (1 << tag));
+} while (--offset > 0);
+}
+return tag;
+}
+
+uint64_t HELPER(irg)(CPUARMState *env, uint64_t rn, uint64_t rm)
+{
+int rtag;
+
+/*
+ * Our IMPDEF choice for GCR_EL1.RRND==1 is to behave as if
+ * GCR_EL1.RRND==0, always producing deterministic results.
+ */
+uint16_t exclude = extract32(rm | env->cp15.gcr_el1, 0, 16);
+int start = extract32(env->cp15.rgsr_el1, 0, 4);
+int seed = extract32(env->cp15.rgsr_el1, 8, 16);
+int offset, i;
+
+/* RandomTag */
+for (i = offset = 0; i < 4; ++i) {
+/* NextRandomTagBit */
+int top = (extract32(seed, 5, 1) ^ extract32(seed, 3, 1) ^
+   extract32(seed, 2, 1) ^ extract32(seed, 0, 1));
+seed = (top << 15) | (seed >> 1);
+offset |= top << i;
+}
+rtag = choose_nonexcluded_tag(start, offset, exclude);
+env->cp15.rgsr_el1 = rtag | (seed << 8);
+
+return address_with_allocation_tag(rn, rtag);
+}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 55f49585be4..30683061f94 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -226,6 +226,12 @@ static TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 
addr)
 return clean;
 }
 
+/* Insert a zero tag into src, with the result at dst. */
+static void gen_address_with_allocation_tag0(TCGv_i64 dst, TCGv_i64 src)
+{
+tcg_gen_andi_i64(dst, src, ~MAKE_64BIT_MASK(56, 4));
+}
+
 typedef struct DisasCompare64 {
 TCGCond cond;
 TCGv_i64 value;
@@ -5284,6 +5290,18 @@ static void disas_data_proc_2src(DisasContext *s, 
uint32_t insn)
 case 3: /* SDIV */
 handle_div(s, true, sf, rm, rn, rd);
 break;
+case 4: /* IRG */
+if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) {
+goto do_unallocated;
+}
+if (s->ata) {
+gen_helper_irg(cpu_reg_sp(s, rd), cpu_env,
+   cpu_reg_sp(s, rn), cpu_reg(s, rm));
+} else {
+gen_address_with_allocation_tag0(cpu_reg_sp(s, rd),
+ cpu_reg_sp(s, rn));
+}
+break;
 case 8: /* LSL

[PULL 28/57] target/arm: Implement the STGP instruction

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-17-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/translate-a64.c | 29 ++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 436191c15cf..e2295a371b2 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -2690,7 +2690,7 @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
  * +-+---+---+---+---+---+---+---+--+--+
  *
  * opc: LDP/STP/LDNP/STNP00 -> 32 bit, 10 -> 64 bit
- *  LDPSW01
+ *  LDPSW/STGP   01
  *  LDP/STP/LDNP/STNP (SIMD) 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit
  *   V: 0 -> GPR, 1 -> Vector
  * idx: 00 -> signed offset with non-temporal hint, 01 -> post-index,
@@ -2715,6 +2715,7 @@ static void disas_ldst_pair(DisasContext *s, uint32_t 
insn)
 bool is_signed = false;
 bool postindex = false;
 bool wback = false;
+bool set_tag = false;
 
 TCGv_i64 clean_addr, dirty_addr;
 
@@ -2727,6 +2728,14 @@ static void disas_ldst_pair(DisasContext *s, uint32_t 
insn)
 
 if (is_vector) {
 size = 2 + opc;
+} else if (opc == 1 && !is_load) {
+/* STGP */
+if (!dc_isar_feature(aa64_mte_insn_reg, s) || index == 0) {
+unallocated_encoding(s);
+return;
+}
+size = 3;
+set_tag = true;
 } else {
 size = 2 + extract32(opc, 1, 1);
 is_signed = extract32(opc, 0, 1);
@@ -2767,7 +2776,7 @@ static void disas_ldst_pair(DisasContext *s, uint32_t 
insn)
 return;
 }
 
-offset <<= size;
+offset <<= (set_tag ? LOG2_TAG_GRANULE : size);
 
 if (rn == 31) {
 gen_check_sp_alignment(s);
@@ -2777,8 +2786,22 @@ static void disas_ldst_pair(DisasContext *s, uint32_t 
insn)
 if (!postindex) {
 tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
 }
-clean_addr = clean_data_tbi(s, dirty_addr);
 
+if (set_tag) {
+if (!s->ata) {
+/*
+ * TODO: We could rely on the stores below, at least for
+ * system mode, if we arrange to add MO_ALIGN_16.
+ */
+gen_helper_stg_stub(cpu_env, dirty_addr);
+} else if (tb_cflags(s->base.tb) & CF_PARALLEL) {
+gen_helper_stg_parallel(cpu_env, dirty_addr, dirty_addr);
+} else {
+gen_helper_stg(cpu_env, dirty_addr, dirty_addr);
+}
+}
+
+clean_addr = clean_data_tbi(s, dirty_addr);
 if (is_vector) {
 if (is_load) {
 do_fp_ld(s, rt, clean_addr, size);
-- 
2.20.1




[PULL 30/57] target/arm: Simplify DC_ZVA

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

Now that we know that the operation is on a single page,
we need not loop over pages while probing.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-19-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/helper-a64.c | 94 +++--
 1 file changed, 25 insertions(+), 69 deletions(-)

diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index bc0649a44aa..8682630ff6c 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -1119,85 +1119,41 @@ void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
  * (which matches the usual QEMU behaviour of not implementing either
  * alignment faults or any memory attribute handling).
  */
-
-ARMCPU *cpu = env_archcpu(env);
-uint64_t blocklen = 4 << cpu->dcz_blocksize;
+int blocklen = 4 << env_archcpu(env)->dcz_blocksize;
 uint64_t vaddr = vaddr_in & ~(blocklen - 1);
+int mmu_idx = cpu_mmu_index(env, false);
+void *mem;
+
+/*
+ * Trapless lookup.  In addition to actual invalid page, may
+ * return NULL for I/O, watchpoints, clean pages, etc.
+ */
+mem = tlb_vaddr_to_host(env, vaddr, MMU_DATA_STORE, mmu_idx);
 
 #ifndef CONFIG_USER_ONLY
-{
+if (unlikely(!mem)) {
+uintptr_t ra = GETPC();
+
 /*
- * Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than
- * the block size so we might have to do more than one TLB lookup.
- * We know that in fact for any v8 CPU the page size is at least 4K
- * and the block size must be 2K or less, but TARGET_PAGE_SIZE is only
- * 1K as an artefact of legacy v5 subpage support being present in the
- * same QEMU executable. So in practice the hostaddr[] array has
- * two entries, given the current setting of TARGET_PAGE_BITS_MIN.
+ * Trap if accessing an invalid page.  DC_ZVA requires that we supply
+ * the original pointer for an invalid page.  But watchpoints require
+ * that we probe the actual space.  So do both.
  */
-int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE);
-void *hostaddr[DIV_ROUND_UP(2 * KiB, 1 << TARGET_PAGE_BITS_MIN)];
-int try, i;
-unsigned mmu_idx = cpu_mmu_index(env, false);
-TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
+(void) probe_write(env, vaddr_in, 1, mmu_idx, ra);
+mem = probe_write(env, vaddr, blocklen, mmu_idx, ra);
 
-assert(maxidx <= ARRAY_SIZE(hostaddr));
-
-for (try = 0; try < 2; try++) {
-
-for (i = 0; i < maxidx; i++) {
-hostaddr[i] = tlb_vaddr_to_host(env,
-vaddr + TARGET_PAGE_SIZE * i,
-1, mmu_idx);
-if (!hostaddr[i]) {
-break;
-}
-}
-if (i == maxidx) {
-/*
- * If it's all in the TLB it's fair game for just writing to;
- * we know we don't need to update dirty status, etc.
- */
-for (i = 0; i < maxidx - 1; i++) {
-memset(hostaddr[i], 0, TARGET_PAGE_SIZE);
-}
-memset(hostaddr[i], 0, blocklen - (i * TARGET_PAGE_SIZE));
-return;
-}
+if (unlikely(!mem)) {
 /*
- * OK, try a store and see if we can populate the tlb. This
- * might cause an exception if the memory isn't writable,
- * in which case we will longjmp out of here. We must for
- * this purpose use the actual register value passed to us
- * so that we get the fault address right.
+ * The only remaining reason for mem == NULL is I/O.
+ * Just do a series of byte writes as the architecture demands.
  */
-helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETPC());
-/* Now we can populate the other TLB entries, if any */
-for (i = 0; i < maxidx; i++) {
-uint64_t va = vaddr + TARGET_PAGE_SIZE * i;
-if (va != (vaddr_in & TARGET_PAGE_MASK)) {
-helper_ret_stb_mmu(env, va, 0, oi, GETPC());
-}
+for (int i = 0; i < blocklen; i++) {
+cpu_stb_mmuidx_ra(env, vaddr + i, 0, mmu_idx, ra);
 }
-}
-
-/*
- * Slow path (probably attempt to do this to an I/O device or
- * similar, or clearing of a block of code we have translations
- * cached for). Just do a series of byte writes as the architecture
- * demands. It's not worth trying to use a cpu_physical_memory_map(),
- * memset(), unmap() sequence here because:
- *  + we'd need to account for the blocksize being larger than a page
- *  + the direct-RAM 

[PULL 05/57] hw/misc/pca9552: Rename 'nr_leds' as 'pin_count'

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

The PCA9552 device does not expose LEDs, but simple pins
to connnect LEDs to. To be clearer with the device model,
rename 'nr_leds' as 'pin_count'.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
Tested-by: Cédric Le Goater 
Message-id: 20200623072723.6324-3-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 include/hw/misc/pca9552.h |  2 +-
 hw/misc/pca9552.c | 10 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/hw/misc/pca9552.h b/include/hw/misc/pca9552.h
index ebb43c63fe1..bc5ed310878 100644
--- a/include/hw/misc/pca9552.h
+++ b/include/hw/misc/pca9552.h
@@ -26,7 +26,7 @@ typedef struct PCA9552State {
 
 uint8_t regs[PCA9552_NR_REGS];
 uint8_t max_reg;
-uint8_t nr_leds;
+uint8_t pin_count;
 } PCA9552State;
 
 #endif
diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index cac729e35af..81da757a7ea 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -37,7 +37,7 @@ static void pca9552_update_pin_input(PCA9552State *s)
 {
 int i;
 
-for (i = 0; i < s->nr_leds; i++) {
+for (i = 0; i < s->pin_count; i++) {
 uint8_t input_reg = PCA9552_INPUT0 + (i / 8);
 uint8_t input_shift = (i % 8);
 uint8_t config = pca9552_pin_get_config(s, i);
@@ -185,7 +185,7 @@ static void pca9552_get_led(Object *obj, Visitor *v, const 
char *name,
 error_setg(errp, "%s: error reading %s", __func__, name);
 return;
 }
-if (led < 0 || led > s->nr_leds) {
+if (led < 0 || led > s->pin_count) {
 error_setg(errp, "%s invalid led %s", __func__, name);
 return;
 }
@@ -228,7 +228,7 @@ static void pca9552_set_led(Object *obj, Visitor *v, const 
char *name,
 error_setg(errp, "%s: error reading %s", __func__, name);
 return;
 }
-if (led < 0 || led > s->nr_leds) {
+if (led < 0 || led > s->pin_count) {
 error_setg(errp, "%s invalid led %s", __func__, name);
 return;
 }
@@ -291,9 +291,9 @@ static void pca9552_initfn(Object *obj)
  * PCA955X device
  */
 s->max_reg = PCA9552_LS3;
-s->nr_leds = 16;
+s->pin_count = 16;
 
-for (led = 0; led < s->nr_leds; led++) {
+for (led = 0; led < s->pin_count; led++) {
 char *name;
 
 name = g_strdup_printf("led%d", led);
-- 
2.20.1




[PULL 24/57] target/arm: Implement the GMI instruction

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-13-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/translate-a64.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 2ec02c8a5f3..ee9dfa8e439 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -5346,6 +5346,21 @@ static void disas_data_proc_2src(DisasContext *s, 
uint32_t insn)
  cpu_reg_sp(s, rn));
 }
 break;
+case 5: /* GMI */
+if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) {
+goto do_unallocated;
+} else {
+TCGv_i64 t1 = tcg_const_i64(1);
+TCGv_i64 t2 = tcg_temp_new_i64();
+
+tcg_gen_extract_i64(t2, cpu_reg_sp(s, rn), 56, 4);
+tcg_gen_shl_i64(t1, t1, t2);
+tcg_gen_or_i64(cpu_reg(s, rd), cpu_reg(s, rm), t1);
+
+tcg_temp_free_i64(t1);
+tcg_temp_free_i64(t2);
+}
+break;
 case 8: /* LSLV */
 handle_shift_reg(s, A64_SHIFT_TYPE_LSL, sf, rm, rn, rd);
 break;
-- 
2.20.1




[PULL 27/57] target/arm: Implement LDG, STG, ST2G instructions

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-16-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/helper-a64.h|   7 ++
 target/arm/helper.h|   2 +
 target/arm/mte_helper.c| 194 +
 target/arm/op_helper.c |  16 +++
 target/arm/translate-a64.c | 172 +++-
 5 files changed, 386 insertions(+), 5 deletions(-)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index 6c116481e8f..2fa61b86fa7 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -106,3 +106,10 @@ DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, 
i64)
 
 DEF_HELPER_FLAGS_3(irg, TCG_CALL_NO_RWG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_4(addsubg, TCG_CALL_NO_RWG_SE, i64, env, i64, s32, i32)
+DEF_HELPER_FLAGS_3(ldg, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(stg, TCG_CALL_NO_WG, void, env, i64, i64)
+DEF_HELPER_FLAGS_3(stg_parallel, TCG_CALL_NO_WG, void, env, i64, i64)
+DEF_HELPER_FLAGS_2(stg_stub, TCG_CALL_NO_WG, void, env, i64)
+DEF_HELPER_FLAGS_3(st2g, TCG_CALL_NO_WG, void, env, i64, i64)
+DEF_HELPER_FLAGS_3(st2g_parallel, TCG_CALL_NO_WG, void, env, i64, i64)
+DEF_HELPER_FLAGS_2(st2g_stub, TCG_CALL_NO_WG, void, env, i64)
diff --git a/target/arm/helper.h b/target/arm/helper.h
index 2a20c8174cf..759639a63a2 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -96,6 +96,8 @@ DEF_HELPER_FLAGS_1(rebuild_hflags_a32_newel, TCG_CALL_NO_RWG, 
void, env)
 DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, int)
 DEF_HELPER_FLAGS_2(rebuild_hflags_a64, TCG_CALL_NO_RWG, void, env, int)
 
+DEF_HELPER_FLAGS_5(probe_access, TCG_CALL_NO_WG, void, env, tl, i32, i32, i32)
+
 DEF_HELPER_1(vfp_get_fpscr, i32, env)
 DEF_HELPER_2(vfp_set_fpscr, void, env, i32)
 
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 9ab9ed749d8..7ec7930dfc8 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -44,6 +44,40 @@ static int choose_nonexcluded_tag(int tag, int offset, 
uint16_t exclude)
 return tag;
 }
 
+/**
+ * allocation_tag_mem:
+ * @env: the cpu environment
+ * @ptr_mmu_idx: the addressing regime to use for the virtual address
+ * @ptr: the virtual address for which to look up tag memory
+ * @ptr_access: the access to use for the virtual address
+ * @ptr_size: the number of bytes in the normal memory access
+ * @tag_access: the access to use for the tag memory
+ * @tag_size: the number of bytes in the tag memory access
+ * @ra: the return address for exception handling
+ *
+ * Our tag memory is formatted as a sequence of little-endian nibbles.
+ * That is, the byte at (addr >> (LOG2_TAG_GRANULE + 1)) contains two
+ * tags, with the tag at [3:0] for the lower addr and the tag at [7:4]
+ * for the higher addr.
+ *
+ * Here, resolve the physical address from the virtual address, and return
+ * a pointer to the corresponding tag byte.  Exit with exception if the
+ * virtual address is not accessible for @ptr_access.
+ *
+ * The @ptr_size and @tag_size values may not have an obvious relation
+ * due to the alignment of @ptr, and the number of tag checks required.
+ *
+ * If there is no tag storage corresponding to @ptr, return NULL.
+ */
+static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
+   uint64_t ptr, MMUAccessType ptr_access,
+   int ptr_size, MMUAccessType tag_access,
+   int tag_size, uintptr_t ra)
+{
+/* Tag storage not implemented.  */
+return NULL;
+}
+
 uint64_t HELPER(irg)(CPUARMState *env, uint64_t rn, uint64_t rm)
 {
 int rtag;
@@ -80,3 +114,163 @@ uint64_t HELPER(addsubg)(CPUARMState *env, uint64_t ptr,
 
 return address_with_allocation_tag(ptr + offset, rtag);
 }
+
+static int load_tag1(uint64_t ptr, uint8_t *mem)
+{
+int ofs = extract32(ptr, LOG2_TAG_GRANULE, 1) * 4;
+return extract32(*mem, ofs, 4);
+}
+
+uint64_t HELPER(ldg)(CPUARMState *env, uint64_t ptr, uint64_t xt)
+{
+int mmu_idx = cpu_mmu_index(env, false);
+uint8_t *mem;
+int rtag = 0;
+
+/* Trap if accessing an invalid page.  */
+mem = allocation_tag_mem(env, mmu_idx, ptr, MMU_DATA_LOAD, 1,
+ MMU_DATA_LOAD, 1, GETPC());
+
+/* Load if page supports tags. */
+if (mem) {
+rtag = load_tag1(ptr, mem);
+}
+
+return address_with_allocation_tag(xt, rtag);
+}
+
+static void check_tag_aligned(CPUARMState *env, uint64_t ptr, uintptr_t ra)
+{
+if (unlikely(!QEMU_IS_ALIGNED(ptr, TAG_GRANULE))) {
+arm_cpu_do_unaligned_access(env_cpu(env), ptr, MMU_DATA_STORE,
+cpu_mmu_index(env, false), ra);
+g_assert_not_reached();
+}
+}
+
+/* For use in a non-parallel context, store to the given nibble.  */
+static void store_tag1(uint64_t ptr, uint8_t *mem, int tag)
+{
+int

[PULL 01/57] hw/arm/aspeed: Remove extraneous MemoryRegion object owner

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

I'm confused by this code, 'bmc' is created as:

  bmc = g_new0(AspeedBoardState, 1);

Then we use it as QOM owner for different MemoryRegion objects.
But looking at memory_region_init_ram (similarly for ROM):

  void memory_region_init_ram(MemoryRegion *mr,
  struct Object *owner,
  const char *name,
  uint64_t size,
  Error **errp)
  {
  DeviceState *owner_dev;
  Error *err = NULL;

  memory_region_init_ram_nomigrate(mr, owner, name, size, &err);
  if (err) {
  error_propagate(errp, err);
  return;
  }
  /* This will assert if owner is neither NULL nor a DeviceState.
   * We only want the owner here for the purposes of defining a
   * unique name for migration. TODO: Ideally we should implement
   * a naming scheme for Objects which are not DeviceStates, in
   * which case we can relax this restriction.
   */
  owner_dev = DEVICE(owner);
  vmstate_register_ram(mr, owner_dev);
  }

The expected assertion is not triggered ('bmc' is not NULL neither
a DeviceState).

'bmc' structure is defined as:

  struct AspeedBoardState {
  AspeedSoCState soc;
  MemoryRegion ram_container;
  MemoryRegion max_ram;
  };

What happens is when using 'OBJECT(bmc)', the QOM macros cast the
memory pointed by bmc, which first member is 'soc', which is
initialized ...:

  object_initialize_child(OBJECT(machine), "soc",
  &bmc->soc, amc->soc_name);

The 'soc' object is indeed a DeviceState, so the assertion passes.

Since this is fragile and only happens to work by luck, remove the
dangerous OBJECT(bmc) owner argument.

Note, this probably breaks migration for this machine.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
Message-id: 20200623072132.2868-2-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 hw/arm/aspeed.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 863757e1f03..167fd5ed1c7 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -329,12 +329,12 @@ static void aspeed_machine_init(MachineState *machine)
  * needed by the flash modules of the Aspeed machines.
  */
 if (ASPEED_MACHINE(machine)->mmio_exec) {
-memory_region_init_alias(boot_rom, OBJECT(bmc), "aspeed.boot_rom",
+memory_region_init_alias(boot_rom, NULL, "aspeed.boot_rom",
  &fl->mmio, 0, fl->size);
 memory_region_add_subregion(get_system_memory(), FIRMWARE_ADDR,
 boot_rom);
 } else {
-memory_region_init_rom(boot_rom, OBJECT(bmc), "aspeed.boot_rom",
+memory_region_init_rom(boot_rom, NULL, "aspeed.boot_rom",
fl->size, &error_abort);
 memory_region_add_subregion(get_system_memory(), FIRMWARE_ADDR,
 boot_rom);
@@ -345,7 +345,7 @@ static void aspeed_machine_init(MachineState *machine)
 if (machine->kernel_filename && sc->num_cpus > 1) {
 /* With no u-boot we must set up a boot stub for the secondary CPU */
 MemoryRegion *smpboot = g_new(MemoryRegion, 1);
-memory_region_init_ram(smpboot, OBJECT(bmc), "aspeed.smpboot",
+memory_region_init_ram(smpboot, NULL, "aspeed.smpboot",
0x80, &error_abort);
 memory_region_add_subregion(get_system_memory(),
 AST_SMP_MAILBOX_BASE, smpboot);
-- 
2.20.1




[PULL 19/57] target/arm: Add MTE system registers

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

This is TFSRE0_EL1, TFSR_EL1, TFSR_EL2, TFSR_EL3,
RGSR_EL1, GCR_EL1, GMID_EL1, and PSTATE.TCO.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-8-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/cpu.h   |  4 ++
 target/arm/internals.h |  9 
 target/arm/helper.c| 94 ++
 target/arm/translate-a64.c | 21 +
 4 files changed, 128 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ff70115801f..0a98b6a06d6 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -502,6 +502,9 @@ typedef struct CPUARMState {
 uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
 uint64_t vpidr_el2; /* Virtualization Processor ID Register */
 uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
+uint64_t tfsr_el[4]; /* tfsre0_el1 is index 0.  */
+uint64_t gcr_el1;
+uint64_t rgsr_el1;
 } cp15;
 
 struct {
@@ -1282,6 +1285,7 @@ void pmu_init(ARMCPU *cpu);
 #define PSTATE_SS (1U << 21)
 #define PSTATE_PAN (1U << 22)
 #define PSTATE_UAO (1U << 23)
+#define PSTATE_TCO (1U << 25)
 #define PSTATE_V (1U << 28)
 #define PSTATE_C (1U << 29)
 #define PSTATE_Z (1U << 30)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 4bdbc3a8ace..56b46726857 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1159,6 +1159,9 @@ static inline uint32_t aarch64_pstate_valid_mask(const 
ARMISARegisters *id)
 if (isar_feature_aa64_uao(id)) {
 valid |= PSTATE_UAO;
 }
+if (isar_feature_aa64_mte(id)) {
+valid |= PSTATE_TCO;
+}
 
 return valid;
 }
@@ -1234,4 +1237,10 @@ void arm_log_exception(int idx);
 
 #endif /* !CONFIG_USER_ONLY */
 
+/*
+ * The log2 of the words in the tag block, for GMID_EL1.BS.
+ * The is the maximum, 256 bytes, which manipulates 64-bits of tags.
+ */
+#define GMID_EL1_BS  6
+
 #endif
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d6c326b58e8..b4842ea23eb 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5881,6 +5881,9 @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU 
*cpu)
 { K(3, 0,  1, 2, 0), K(3, 4,  1, 2, 0), K(3, 5, 1, 2, 0),
   "ZCR_EL1", "ZCR_EL2", "ZCR_EL12", isar_feature_aa64_sve },
 
+{ K(3, 0,  5, 6, 0), K(3, 4,  5, 6, 0), K(3, 5, 5, 6, 0),
+  "TFSR_EL1", "TFSR_EL2", "TFSR_EL12", isar_feature_aa64_mte },
+
 /* TODO: ARMv8.2-SPE -- PMSCR_EL2 */
 /* TODO: ARMv8.4-Trace -- TRFCR_EL2 */
 };
@@ -6855,6 +6858,86 @@ static const ARMCPRegInfo dcpodp_reg[] = {
 };
 #endif /*CONFIG_USER_ONLY*/
 
+static CPAccessResult access_aa64_tid5(CPUARMState *env, const ARMCPRegInfo 
*ri,
+   bool isread)
+{
+if ((arm_current_el(env) < 2) && (arm_hcr_el2_eff(env) & HCR_TID5)) {
+return CP_ACCESS_TRAP_EL2;
+}
+
+return CP_ACCESS_OK;
+}
+
+static CPAccessResult access_mte(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+int el = arm_current_el(env);
+
+if (el < 2 &&
+arm_feature(env, ARM_FEATURE_EL2) &&
+!(arm_hcr_el2_eff(env) & HCR_ATA)) {
+return CP_ACCESS_TRAP_EL2;
+}
+if (el < 3 &&
+arm_feature(env, ARM_FEATURE_EL3) &&
+!(env->cp15.scr_el3 & SCR_ATA)) {
+return CP_ACCESS_TRAP_EL3;
+}
+return CP_ACCESS_OK;
+}
+
+static uint64_t tco_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+return env->pstate & PSTATE_TCO;
+}
+
+static void tco_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
+{
+env->pstate = (env->pstate & ~PSTATE_TCO) | (val & PSTATE_TCO);
+}
+
+static const ARMCPRegInfo mte_reginfo[] = {
+{ .name = "TFSRE0_EL1", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 1,
+  .access = PL1_RW, .accessfn = access_mte,
+  .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[0]) },
+{ .name = "TFSR_EL1", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 0,
+  .access = PL1_RW, .accessfn = access_mte,
+  .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
+{ .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 6, .opc2 = 0,
+  .access = PL2_RW, .accessfn = access_mte,
+  .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[2]) },
+{ .name = "TFSR_EL3", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 6, .opc2 = 0,
+  .access = PL3_RW,
+  .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[3]) },
+{ .name = "RGSR_EL1", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 5,
+  .access = PL1_RW, .accessfn = access_mte,
+  .fieldoffset = offsetof(CPUARMState, cp15.rgsr_el1) },
+{ .name = "GCR_EL1", .state = ARM_CP_STATE_AA

[PULL 23/57] target/arm: Implement the ADDG, SUBG instructions

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-12-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/helper-a64.h|  1 +
 target/arm/internals.h |  9 +++
 target/arm/mte_helper.c| 10 
 target/arm/translate-a64.c | 51 ++
 4 files changed, 71 insertions(+)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index 587ccbe42ff..6c116481e8f 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -105,3 +105,4 @@ DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
 DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
 
 DEF_HELPER_FLAGS_3(irg, TCG_CALL_NO_RWG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_4(addsubg, TCG_CALL_NO_RWG_SE, i64, env, i64, s32, i32)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index ae611a6ff5d..5c69d4e5a56 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1261,6 +1261,15 @@ void arm_log_exception(int idx);
  */
 #define GMID_EL1_BS  6
 
+/* We associate one allocation tag per 16 bytes, the minimum.  */
+#define LOG2_TAG_GRANULE 4
+#define TAG_GRANULE  (1 << LOG2_TAG_GRANULE)
+
+static inline int allocation_tag_from_addr(uint64_t ptr)
+{
+return extract64(ptr, 56, 4);
+}
+
 static inline uint64_t address_with_allocation_tag(uint64_t ptr, int rtag)
 {
 return deposit64(ptr, 56, 4, rtag);
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 539a04de84b..9ab9ed749d8 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -70,3 +70,13 @@ uint64_t HELPER(irg)(CPUARMState *env, uint64_t rn, uint64_t 
rm)
 
 return address_with_allocation_tag(rn, rtag);
 }
+
+uint64_t HELPER(addsubg)(CPUARMState *env, uint64_t ptr,
+ int32_t offset, uint32_t tag_offset)
+{
+int start_tag = allocation_tag_from_addr(ptr);
+uint16_t exclude = extract32(env->cp15.gcr_el1, 0, 16);
+int rtag = choose_nonexcluded_tag(start_tag, tag_offset, exclude);
+
+return address_with_allocation_tag(ptr + offset, rtag);
+}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 03aa0925983..2ec02c8a5f3 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -3808,6 +3808,54 @@ static void disas_add_sub_imm(DisasContext *s, uint32_t 
insn)
 tcg_temp_free_i64(tcg_result);
 }
 
+/*
+ * Add/subtract (immediate, with tags)
+ *
+ *  31 30 29 28 23 22 21 16 14  10 9   5 4   0
+ * +--+--+--+-+--+-+--+---+-+-+
+ * |sf|op| S| 1 0 0 0 1 1 |o2|  uimm6  |o3| uimm4 |  Rn | Rd  |
+ * +--+--+--+-+--+-+--+---+-+-+
+ *
+ *op: 0 -> add, 1 -> sub
+ */
+static void disas_add_sub_imm_with_tags(DisasContext *s, uint32_t insn)
+{
+int rd = extract32(insn, 0, 5);
+int rn = extract32(insn, 5, 5);
+int uimm4 = extract32(insn, 10, 4);
+int uimm6 = extract32(insn, 16, 6);
+bool sub_op = extract32(insn, 30, 1);
+TCGv_i64 tcg_rn, tcg_rd;
+int imm;
+
+/* Test all of sf=1, S=0, o2=0, o3=0.  */
+if ((insn & 0xa040c000u) != 0x8000u ||
+!dc_isar_feature(aa64_mte_insn_reg, s)) {
+unallocated_encoding(s);
+return;
+}
+
+imm = uimm6 << LOG2_TAG_GRANULE;
+if (sub_op) {
+imm = -imm;
+}
+
+tcg_rn = cpu_reg_sp(s, rn);
+tcg_rd = cpu_reg_sp(s, rd);
+
+if (s->ata) {
+TCGv_i32 offset = tcg_const_i32(imm);
+TCGv_i32 tag_offset = tcg_const_i32(uimm4);
+
+gen_helper_addsubg(tcg_rd, cpu_env, tcg_rn, offset, tag_offset);
+tcg_temp_free_i32(tag_offset);
+tcg_temp_free_i32(offset);
+} else {
+tcg_gen_addi_i64(tcg_rd, tcg_rn, imm);
+gen_address_with_allocation_tag0(tcg_rd, tcg_rd);
+}
+}
+
 /* The input should be a value in the bottom e bits (with higher
  * bits zero); returns that value replicated into every element
  * of size e in a 64 bit integer.
@@ -4170,6 +4218,9 @@ static void disas_data_proc_imm(DisasContext *s, uint32_t 
insn)
 case 0x22: /* Add/subtract (immediate) */
 disas_add_sub_imm(s, insn);
 break;
+case 0x23: /* Add/subtract (immediate, with tags) */
+disas_add_sub_imm_with_tags(s, insn);
+break;
 case 0x24: /* Logical (immediate) */
 disas_logic_imm(s, insn);
 break;
-- 
2.20.1




[PULL 18/57] target/arm: Add DISAS_UPDATE_NOCHAIN

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

Add an option that writes back the PC, like DISAS_UPDATE_EXIT,
but does not exit back to the main loop.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-7-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/translate.h | 2 ++
 target/arm/translate-a64.c | 3 +++
 target/arm/translate.c | 4 
 3 files changed, 9 insertions(+)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index d5edef2943f..6dfe24cedc0 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -173,6 +173,8 @@ static inline void disas_set_insn_syndrome(DisasContext *s, 
uint32_t syn)
  * return from cpu_tb_exec.
  */
 #define DISAS_EXIT  DISAS_TARGET_9
+/* CPU state was modified dynamically; no need to exit, but do not chain. */
+#define DISAS_UPDATE_NOCHAIN  DISAS_TARGET_10
 
 #ifdef TARGET_AARCH64
 void a64_translate_init(void);
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index e4795ae100c..027be7d8c29 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14298,6 +14298,9 @@ static void aarch64_tr_tb_stop(DisasContextBase 
*dcbase, CPUState *cpu)
 case DISAS_EXIT:
 tcg_gen_exit_tb(NULL, 0);
 break;
+case DISAS_UPDATE_NOCHAIN:
+gen_a64_set_pc_im(dc->base.pc_next);
+/* fall through */
 case DISAS_JUMP:
 tcg_gen_lookup_and_goto_ptr();
 break;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 146ff5ddc24..c39a929b938 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -8874,6 +8874,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, 
CPUState *cpu)
 case DISAS_NEXT:
 case DISAS_TOO_MANY:
 case DISAS_UPDATE_EXIT:
+case DISAS_UPDATE_NOCHAIN:
 gen_set_pc_im(dc, dc->base.pc_next);
 /* fall through */
 default:
@@ -8897,6 +8898,9 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, 
CPUState *cpu)
 case DISAS_TOO_MANY:
 gen_goto_tb(dc, 1, dc->base.pc_next);
 break;
+case DISAS_UPDATE_NOCHAIN:
+gen_set_pc_im(dc, dc->base.pc_next);
+/* fall through */
 case DISAS_JUMP:
 gen_goto_ptr();
 break;
-- 
2.20.1




[PULL 14/57] target/arm: Improve masking of SCR RES0 bits

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

Protect reads of aa64 id registers with ARM_CP_STATE_AA64.
Use this as a simpler test than arm_el_is_aa64, since EL3
cannot change mode.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-3-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/helper.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 972a7667309..a29f0a28d84 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -2011,9 +2011,16 @@ static void scr_write(CPUARMState *env, const 
ARMCPRegInfo *ri, uint64_t value)
 uint32_t valid_mask = 0x3fff;
 ARMCPU *cpu = env_archcpu(env);
 
-if (arm_el_is_aa64(env, 3)) {
+if (ri->state == ARM_CP_STATE_AA64) {
 value |= SCR_FW | SCR_AW;   /* these two bits are RES1.  */
 valid_mask &= ~SCR_NET;
+
+if (cpu_isar_feature(aa64_lor, cpu)) {
+valid_mask |= SCR_TLOR;
+}
+if (cpu_isar_feature(aa64_pauth, cpu)) {
+valid_mask |= SCR_API | SCR_APK;
+}
 } else {
 valid_mask &= ~(SCR_RW | SCR_ST);
 }
@@ -2032,12 +2039,6 @@ static void scr_write(CPUARMState *env, const 
ARMCPRegInfo *ri, uint64_t value)
 valid_mask &= ~SCR_SMD;
 }
 }
-if (cpu_isar_feature(aa64_lor, cpu)) {
-valid_mask |= SCR_TLOR;
-}
-if (cpu_isar_feature(aa64_pauth, cpu)) {
-valid_mask |= SCR_API | SCR_APK;
-}
 
 /* Clear all-context RES0 bits.  */
 value &= valid_mask;
-- 
2.20.1




[PULL 00/57] target-arm queue

2020-06-26 Thread Peter Maydell
Mostly this is RTH's memtag series, but there are also some cleanups
from Philippe.

thanks
-- PMM

The following changes since commit 10f7ffabf9c507fc02382b89912003b1c43c3231:

  Merge remote-tracking branch 'remotes/mcayland/tags/qemu-macppc-20200626' 
into staging (2020-06-26 12:14:18 +0100)

are available in the Git repository at:

  https://git.linaro.org/people/pmaydell/qemu-arm.git 
tags/pull-target-arm-20200626

for you to fetch changes up to c7459633baa71d1781fde4a245d6ec9ce2f008cf:

  target/arm: Enable MTE (2020-06-26 14:32:24 +0100)


target-arm queue:
 * hw/arm/aspeed: improve QOM usage
 * hw/misc/pca9552: trace GPIO change events
 * target/arm: Implement ARMv8.5-MemTag for system emulation


Philippe Mathieu-Daudé (12):
  hw/arm/aspeed: Remove extraneous MemoryRegion object owner
  hw/arm/aspeed: Rename AspeedBoardState as AspeedMachineState
  hw/arm/aspeed: QOM'ify AspeedMachineState
  hw/i2c/core: Add i2c_try_create_slave() and i2c_realize_and_unref()
  hw/misc/pca9552: Rename 'nr_leds' as 'pin_count'
  hw/misc/pca9552: Rename generic code as pca955x
  hw/misc/pca9552: Add generic PCA955xClass, parent of TYPE_PCA9552
  hw/misc/pca9552: Add a 'description' property for debugging purpose
  hw/misc/pca9552: Trace GPIO High/Low events
  hw/arm/aspeed: Describe each PCA9552 device
  hw/misc/pca9552: Trace GPIO change events
  hw/misc/pca9552: Model qdev output GPIOs

Richard Henderson (45):
  target/arm: Add isar tests for mte
  target/arm: Improve masking of SCR RES0 bits
  target/arm: Add support for MTE to SCTLR_ELx
  target/arm: Add support for MTE to HCR_EL2 and SCR_EL3
  target/arm: Rename DISAS_UPDATE to DISAS_UPDATE_EXIT
  target/arm: Add DISAS_UPDATE_NOCHAIN
  target/arm: Add MTE system registers
  target/arm: Add MTE bits to tb_flags
  target/arm: Implement the IRG instruction
  target/arm: Revise decoding for disas_add_sub_imm
  target/arm: Implement the ADDG, SUBG instructions
  target/arm: Implement the GMI instruction
  target/arm: Implement the SUBP instruction
  target/arm: Define arm_cpu_do_unaligned_access for user-only
  target/arm: Implement LDG, STG, ST2G instructions
  target/arm: Implement the STGP instruction
  target/arm: Restrict the values of DCZID.BS under TCG
  target/arm: Simplify DC_ZVA
  target/arm: Implement the LDGM, STGM, STZGM instructions
  target/arm: Implement the access tag cache flushes
  target/arm: Move regime_el to internals.h
  target/arm: Move regime_tcr to internals.h
  target/arm: Add gen_mte_check1
  target/arm: Add gen_mte_checkN
  target/arm: Implement helper_mte_check1
  target/arm: Implement helper_mte_checkN
  target/arm: Add helper_mte_check_zva
  target/arm: Use mte_checkN for sve unpredicated loads
  target/arm: Use mte_checkN for sve unpredicated stores
  target/arm: Use mte_check1 for sve LD1R
  target/arm: Tidy trans_LD1R_zpri
  target/arm: Add arm_tlb_bti_gp
  target/arm: Add mte helpers for sve scalar + int loads
  target/arm: Add mte helpers for sve scalar + int stores
  target/arm: Add mte helpers for sve scalar + int ff/nf loads
  target/arm: Handle TBI for sve scalar + int memory ops
  target/arm: Add mte helpers for sve scatter/gather memory ops
  target/arm: Complete TBI clearing for user-only for SVE
  target/arm: Implement data cache set allocation tags
  target/arm: Set PSTATE.TCO on exception entry
  target/arm: Always pass cacheattr to get_phys_addr
  target/arm: Cache the Tagged bit for a page in MemTxAttrs
  target/arm: Create tagged ram when MTE is enabled
  target/arm: Add allocation tag storage for system mode
  target/arm: Enable MTE

 include/hw/arm/aspeed.h|   12 +-
 include/hw/i2c/i2c.h   |2 +
 include/hw/misc/pca9552.h  |   16 +-
 target/arm/cpu.h   |   50 +-
 target/arm/helper-a64.h|   16 +
 target/arm/helper-sve.h|  488 ++
 target/arm/helper.h|2 +
 target/arm/internals.h |  153 -
 target/arm/translate-a64.h |5 +
 target/arm/translate.h |   23 +-
 hw/arm/aspeed.c|   46 +-
 hw/arm/virt.c  |   55 +-
 hw/i2c/core.c  |   18 +-
 hw/misc/pca9552.c  |  216 +--
 target/arm/cpu.c   |   81 ++-
 target/arm/cpu64.c |5 +
 target/arm/helper-a64.c|   94 +--
 target/arm/helper.c|  423 ++---
 target/arm/m_helper.c  |   11 +-
 target/arm/mte_helper.c|  906 ++
 target/arm/op_helper.c |   16 +
 target/arm/sve_helper.c|  616 ++
 ta

Re: [PATCH v9 00/46] target/arm: Implement ARMv8.5-MemTag, system mode

2020-06-26 Thread Peter Maydell
On Fri, 26 Jun 2020 at 04:31, Richard Henderson
 wrote:
>
> Version 9 incorporates some review:
>
>   * Adjust some commentary.
>   * Added an assert for tbi in aarch64_tr_init_disas_context
>   * Split arm,armv8.5-memtag to a new, final, patch.  We might
> just leave this one out of qemu mainline until the kernel
> patch set that requires it gets merged.
>

Thanks, applied all but patch 46 to target-arm.next.

-- PMM



[PULL 17/57] target/arm: Rename DISAS_UPDATE to DISAS_UPDATE_EXIT

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

Emphasize that the is_jmp option exits to the main loop.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-6-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/translate.h | 14 --
 target/arm/translate-a64.c |  8 
 target/arm/translate-vfp.inc.c |  4 ++--
 target/arm/translate.c | 12 ++--
 4 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index 19650a9e2d7..d5edef2943f 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -148,7 +148,8 @@ static inline void disas_set_insn_syndrome(DisasContext *s, 
uint32_t syn)
 
 /* is_jmp field values */
 #define DISAS_JUMP  DISAS_TARGET_0 /* only pc was modified dynamically */
-#define DISAS_UPDATEDISAS_TARGET_1 /* cpu state was modified dynamically */
+/* CPU state was modified dynamically; exit to main loop for interrupts. */
+#define DISAS_UPDATE_EXIT  DISAS_TARGET_1
 /* These instructions trap after executing, so the A32/T32 decoder must
  * defer them until after the conditional execution state has been updated.
  * WFI also needs special handling when single-stepping.
@@ -164,11 +165,12 @@ static inline void disas_set_insn_syndrome(DisasContext 
*s, uint32_t syn)
  * custom end-of-TB code)
  */
 #define DISAS_BX_EXCRET DISAS_TARGET_8
-/* For instructions which want an immediate exit to the main loop,
- * as opposed to attempting to use lookup_and_goto_ptr. Unlike
- * DISAS_UPDATE this doesn't write the PC on exiting the translation
- * loop so you need to ensure something (gen_a64_set_pc_im or runtime
- * helper) has done so before we reach return from cpu_tb_exec.
+/*
+ * For instructions which want an immediate exit to the main loop, as opposed
+ * to attempting to use lookup_and_goto_ptr.  Unlike DISAS_UPDATE_EXIT, this
+ * doesn't write the PC on exiting the translation loop so you need to ensure
+ * something (gen_a64_set_pc_im or runtime helper) has done so before we reach
+ * return from cpu_tb_exec.
  */
 #define DISAS_EXIT  DISAS_TARGET_9
 
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 4cef862c415..e4795ae100c 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1616,7 +1616,7 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
 gen_helper_msr_i_daifclear(cpu_env, t1);
 tcg_temp_free_i32(t1);
 /* For DAIFClear, exit the cpu loop to re-evaluate pending IRQs.  */
-s->base.is_jmp = DISAS_UPDATE;
+s->base.is_jmp = DISAS_UPDATE_EXIT;
 break;
 
 default:
@@ -1795,7 +1795,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, 
bool isread,
 
 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
 /* I/O operations must end the TB here (whether read or write) */
-s->base.is_jmp = DISAS_UPDATE;
+s->base.is_jmp = DISAS_UPDATE_EXIT;
 }
 if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
 /*
@@ -1810,7 +1810,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, 
bool isread,
  * but allow this to be suppressed by the register definition
  * (usually only necessary to work around guest bugs).
  */
-s->base.is_jmp = DISAS_UPDATE;
+s->base.is_jmp = DISAS_UPDATE_EXIT;
 }
 }
 
@@ -14292,7 +14292,7 @@ static void aarch64_tr_tb_stop(DisasContextBase 
*dcbase, CPUState *cpu)
 gen_goto_tb(dc, 1, dc->base.pc_next);
 break;
 default:
-case DISAS_UPDATE:
+case DISAS_UPDATE_EXIT:
 gen_a64_set_pc_im(dc->base.pc_next);
 /* fall through */
 case DISAS_EXIT:
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
index bf31b186578..afa8a5f8885 100644
--- a/target/arm/translate-vfp.inc.c
+++ b/target/arm/translate-vfp.inc.c
@@ -123,7 +123,7 @@ static bool full_vfp_access_check(DisasContext *s, bool 
ignore_vfp_enabled)
  * this to be the last insn in the TB).
  */
 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-s->base.is_jmp = DISAS_UPDATE;
+s->base.is_jmp = DISAS_UPDATE_EXIT;
 gen_io_start();
 }
 gen_helper_v7m_preserve_fp_state(cpu_env);
@@ -2860,6 +2860,6 @@ static bool trans_VLLDM_VLSTM(DisasContext *s, 
arg_VLLDM_VLSTM *a)
 tcg_temp_free_i32(fptr);
 
 /* End the TB, because we have updated FP control bits */
-s->base.is_jmp = DISAS_UPDATE;
+s->base.is_jmp = DISAS_UPDATE_EXIT;
 return true;
 }
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 795964da1f1..146ff5ddc24 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -2775,7 +2775,7 @@ static void gen_msr_banked(DisasContext *s, int r, int 
sysm, int rn)
 tcg_temp_free_i32(tcg_tgtmode);
 tcg_temp_free_i3

[PULL 15/57] target/arm: Add support for MTE to SCTLR_ELx

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

This does not attempt to rectify all of the res0 bits, but does
clear the mte bits when not enabled.  Since there is no high-part
mapping of SCTLR, aa32 mode cannot write to these bits.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-4-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/helper.c | 23 +--
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index a29f0a28d84..8a0fb015819 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4698,6 +4698,22 @@ static void sctlr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 {
 ARMCPU *cpu = env_archcpu(env);
 
+if (arm_feature(env, ARM_FEATURE_PMSA) && !cpu->has_mpu) {
+/* M bit is RAZ/WI for PMSA with no MPU implemented */
+value &= ~SCTLR_M;
+}
+
+/* ??? Lots of these bits are not implemented.  */
+
+if (ri->state == ARM_CP_STATE_AA64 && !cpu_isar_feature(aa64_mte, cpu)) {
+if (ri->opc1 == 6) { /* SCTLR_EL3 */
+value &= ~(SCTLR_ITFSB | SCTLR_TCF | SCTLR_ATA);
+} else {
+value &= ~(SCTLR_ITFSB | SCTLR_TCF0 | SCTLR_TCF |
+   SCTLR_ATA0 | SCTLR_ATA);
+}
+}
+
 if (raw_read(env, ri) == value) {
 /* Skip the TLB flush if nothing actually changed; Linux likes
  * to do a lot of pointless SCTLR writes.
@@ -4705,13 +4721,8 @@ static void sctlr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 return;
 }
 
-if (arm_feature(env, ARM_FEATURE_PMSA) && !cpu->has_mpu) {
-/* M bit is RAZ/WI for PMSA with no MPU implemented */
-value &= ~SCTLR_M;
-}
-
 raw_write(env, ri, value);
-/* ??? Lots of these bits are not implemented.  */
+
 /* This may enable/disable the MMU, so do a TLB flush.  */
 tlb_flush(CPU(cpu));
 
-- 
2.20.1




[PULL 08/57] hw/misc/pca9552: Add a 'description' property for debugging purpose

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

Add a description field to distinguish between multiple devices.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
Tested-by: Cédric Le Goater 
Message-id: 20200623072723.6324-6-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 include/hw/misc/pca9552.h |  1 +
 hw/misc/pca9552.c | 18 ++
 2 files changed, 19 insertions(+)

diff --git a/include/hw/misc/pca9552.h b/include/hw/misc/pca9552.h
index 90843b03b8a..bf1a5891378 100644
--- a/include/hw/misc/pca9552.h
+++ b/include/hw/misc/pca9552.h
@@ -27,6 +27,7 @@ typedef struct PCA955xState {
 uint8_t pointer;
 
 uint8_t regs[PCA955X_NR_REGS];
+char *description; /* For debugging purpose only */
 } PCA955xState;
 
 #endif
diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index 4de57dbe2e2..2cc52b02057 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -13,6 +13,7 @@
 #include "qemu/osdep.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
+#include "hw/qdev-properties.h"
 #include "hw/misc/pca9552.h"
 #include "hw/misc/pca9552_regs.h"
 #include "migration/vmstate.h"
@@ -317,13 +318,30 @@ static void pca955x_initfn(Object *obj)
 }
 }
 
+static void pca955x_realize(DeviceState *dev, Error **errp)
+{
+PCA955xState *s = PCA955X(dev);
+
+if (!s->description) {
+s->description = g_strdup("pca-unspecified");
+}
+}
+
+static Property pca955x_properties[] = {
+DEFINE_PROP_STRING("description", PCA955xState, description),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void pca955x_class_init(ObjectClass *klass, void *data)
 {
+DeviceClass *dc = DEVICE_CLASS(klass);
 I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
 
 k->event = pca955x_event;
 k->recv = pca955x_recv;
 k->send = pca955x_send;
+dc->realize = pca955x_realize;
+device_class_set_props(dc, pca955x_properties);
 }
 
 static const TypeInfo pca955x_info = {
-- 
2.20.1




[PULL 16/57] target/arm: Add support for MTE to HCR_EL2 and SCR_EL3

2020-06-26 Thread Peter Maydell
From: Richard Henderson 

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
Message-id: 20200626033144.790098-5-richard.hender...@linaro.org
Signed-off-by: Peter Maydell 
---
 target/arm/helper.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 8a0fb015819..d6c326b58e8 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -2021,6 +2021,9 @@ static void scr_write(CPUARMState *env, const 
ARMCPRegInfo *ri, uint64_t value)
 if (cpu_isar_feature(aa64_pauth, cpu)) {
 valid_mask |= SCR_API | SCR_APK;
 }
+if (cpu_isar_feature(aa64_mte, cpu)) {
+valid_mask |= SCR_ATA;
+}
 } else {
 valid_mask &= ~(SCR_RW | SCR_ST);
 }
@@ -5248,17 +5251,22 @@ static void do_hcr_write(CPUARMState *env, uint64_t 
value, uint64_t valid_mask)
 if (cpu_isar_feature(aa64_pauth, cpu)) {
 valid_mask |= HCR_API | HCR_APK;
 }
+if (cpu_isar_feature(aa64_mte, cpu)) {
+valid_mask |= HCR_ATA | HCR_DCT | HCR_TID5;
+}
 }
 
 /* Clear RES0 bits.  */
 value &= valid_mask;
 
-/* These bits change the MMU setup:
+/*
+ * These bits change the MMU setup:
  * HCR_VM enables stage 2 translation
  * HCR_PTW forbids certain page-table setups
- * HCR_DC Disables stage1 and enables stage2 translation
+ * HCR_DC disables stage1 and enables stage2 translation
+ * HCR_DCT enables tagging on (disabled) stage1 translation
  */
-if ((env->cp15.hcr_el2 ^ value) & (HCR_VM | HCR_PTW | HCR_DC)) {
+if ((env->cp15.hcr_el2 ^ value) & (HCR_VM | HCR_PTW | HCR_DC | HCR_DCT)) {
 tlb_flush(CPU(cpu));
 }
 env->cp15.hcr_el2 = value;
-- 
2.20.1




[PULL 09/57] hw/misc/pca9552: Trace GPIO High/Low events

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

Add a trivial representation of the PCA9552 GPIOs.

Example booting obmc-phosphor-image:

  $ qemu-system-arm -M witherspoon-bmc -trace pca955x_gpio_status
  1592689902.327837:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[*...]
  1592689902.329934:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[**..]
  1592689902.330717:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[***.]
  1592689902.331431:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[]
  1592689902.332163:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[.*..]
  1592689902.332888:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[.**.]
  1592689902.333629:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[.***]
  1592690032.793289:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[.*.*]
  1592690033.303163:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[.***]
  1592690033.812962:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[.*.*]
  1592690034.323234:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[.***]
  1592690034.832922:pca955x_gpio_status pca-unspecified GPIOs 0-15 
[.*.*]

We notice the GPIO #14 (front-power LED) starts to blink.

This LED is described in the witherspoon device-tree [*]:

  front-power {
  retain-state-shutdown;
  default-state = "keep";
  gpios = <&pca0 14 GPIO_ACTIVE_LOW>;
  };

[*] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts?id=b1f9be9392f0#n140

Suggested-by: Cédric Le Goater 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
Tested-by: Cédric Le Goater 
Message-id: 20200623072723.6324-7-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 hw/misc/pca9552.c| 39 +++
 hw/misc/trace-events |  3 +++
 2 files changed, 42 insertions(+)

diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index 2cc52b02057..41f8ad213dd 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -13,12 +13,14 @@
 #include "qemu/osdep.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
+#include "qemu/bitops.h"
 #include "hw/qdev-properties.h"
 #include "hw/misc/pca9552.h"
 #include "hw/misc/pca9552_regs.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
+#include "trace.h"
 
 typedef struct PCA955xClass {
 /*< private >*/
@@ -49,6 +51,39 @@ static uint8_t pca955x_pin_get_config(PCA955xState *s, int 
pin)
 return extract32(s->regs[reg], shift, 2);
 }
 
+/* Return INPUT status (bit #N belongs to GPIO #N) */
+static uint16_t pca955x_pins_get_status(PCA955xState *s)
+{
+return (s->regs[PCA9552_INPUT1] << 8) | s->regs[PCA9552_INPUT0];
+}
+
+static void pca955x_display_pins_status(PCA955xState *s,
+uint16_t previous_pins_status)
+{
+PCA955xClass *k = PCA955X_GET_CLASS(s);
+uint16_t pins_status, pins_changed;
+int i;
+
+pins_status = pca955x_pins_get_status(s);
+pins_changed = previous_pins_status ^ pins_status;
+if (!pins_changed) {
+return;
+}
+if (trace_event_get_state_backends(TRACE_PCA955X_GPIO_STATUS)) {
+char *buf = g_newa(char, k->pin_count + 1);
+
+for (i = 0; i < k->pin_count; i++) {
+if (extract32(pins_status, i, 1)) {
+buf[i] = '*';
+} else {
+buf[i] = '.';
+}
+}
+buf[i] = '\0';
+trace_pca955x_gpio_status(s->description, buf);
+}
+}
+
 static void pca955x_update_pin_input(PCA955xState *s)
 {
 PCA955xClass *k = PCA955X_GET_CLASS(s);
@@ -98,6 +133,8 @@ static uint8_t pca955x_read(PCA955xState *s, uint8_t reg)
 
 static void pca955x_write(PCA955xState *s, uint8_t reg, uint8_t data)
 {
+uint16_t pins_status;
+
 switch (reg) {
 case PCA9552_PSC0:
 case PCA9552_PWM0:
@@ -110,8 +147,10 @@ static void pca955x_write(PCA955xState *s, uint8_t reg, 
uint8_t data)
 case PCA9552_LS1:
 case PCA9552_LS2:
 case PCA9552_LS3:
+pins_status = pca955x_pins_get_status(s);
 s->regs[reg] = data;
 pca955x_update_pin_input(s);
+pca955x_display_pins_status(s, pins_status);
 break;
 
 case PCA9552_INPUT0:
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 68a6d9f2ab8..bd7bd37ea8d 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -209,3 +209,6 @@ via1_adb_poll(uint8_t data, const char *vadbint, int 
status, int index, int size
 # grlib_ahb_apb_pnp.c
 grlib_ahb_pnp_read(uint64_t addr, uint32_t value) "AHB PnP read 
addr:0x%03"PRIx64" data:0x%08x"
 grlib_apb_pnp_read(uint64_t addr, uint32_t value) "APB PnP read 
addr:0x%03"PRIx64" data:0x%08x"
+
+# pca9552.c
+pca955x_gpio_status(const char *description, const char *buf) "%s GPIOs 0-15 
[%s]"
-- 
2.20.1




[PULL 06/57] hw/misc/pca9552: Rename generic code as pca955x

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

Various code from the PCA9552 device model is generic to the
PCA955X family. We'll split the generic code in a base class
in the next commit. To ease review, first do a dumb renaming.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
Tested-by: Cédric Le Goater 
Message-id: 20200623072723.6324-4-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 include/hw/misc/pca9552.h | 10 ++---
 hw/misc/pca9552.c | 80 +++
 2 files changed, 45 insertions(+), 45 deletions(-)

diff --git a/include/hw/misc/pca9552.h b/include/hw/misc/pca9552.h
index bc5ed310878..db527595a38 100644
--- a/include/hw/misc/pca9552.h
+++ b/include/hw/misc/pca9552.h
@@ -12,11 +12,11 @@
 #include "hw/i2c/i2c.h"
 
 #define TYPE_PCA9552 "pca9552"
-#define PCA9552(obj) OBJECT_CHECK(PCA9552State, (obj), TYPE_PCA9552)
+#define PCA955X(obj) OBJECT_CHECK(PCA955xState, (obj), TYPE_PCA9552)
 
-#define PCA9552_NR_REGS 10
+#define PCA955X_NR_REGS 10
 
-typedef struct PCA9552State {
+typedef struct PCA955xState {
 /*< private >*/
 I2CSlave i2c;
 /*< public >*/
@@ -24,9 +24,9 @@ typedef struct PCA9552State {
 uint8_t len;
 uint8_t pointer;
 
-uint8_t regs[PCA9552_NR_REGS];
+uint8_t regs[PCA955X_NR_REGS];
 uint8_t max_reg;
 uint8_t pin_count;
-} PCA9552State;
+} PCA955xState;
 
 #endif
diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index 81da757a7ea..5681ff3b22d 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -25,7 +25,7 @@
 
 static const char *led_state[] = {"on", "off", "pwm0", "pwm1"};
 
-static uint8_t pca9552_pin_get_config(PCA9552State *s, int pin)
+static uint8_t pca955x_pin_get_config(PCA955xState *s, int pin)
 {
 uint8_t reg   = PCA9552_LS0 + (pin / 4);
 uint8_t shift = (pin % 4) << 1;
@@ -33,14 +33,14 @@ static uint8_t pca9552_pin_get_config(PCA9552State *s, int 
pin)
 return extract32(s->regs[reg], shift, 2);
 }
 
-static void pca9552_update_pin_input(PCA9552State *s)
+static void pca955x_update_pin_input(PCA955xState *s)
 {
 int i;
 
 for (i = 0; i < s->pin_count; i++) {
 uint8_t input_reg = PCA9552_INPUT0 + (i / 8);
 uint8_t input_shift = (i % 8);
-uint8_t config = pca9552_pin_get_config(s, i);
+uint8_t config = pca955x_pin_get_config(s, i);
 
 switch (config) {
 case PCA9552_LED_ON:
@@ -58,7 +58,7 @@ static void pca9552_update_pin_input(PCA9552State *s)
 }
 }
 
-static uint8_t pca9552_read(PCA9552State *s, uint8_t reg)
+static uint8_t pca955x_read(PCA955xState *s, uint8_t reg)
 {
 switch (reg) {
 case PCA9552_INPUT0:
@@ -79,7 +79,7 @@ static uint8_t pca9552_read(PCA9552State *s, uint8_t reg)
 }
 }
 
-static void pca9552_write(PCA9552State *s, uint8_t reg, uint8_t data)
+static void pca955x_write(PCA955xState *s, uint8_t reg, uint8_t data)
 {
 switch (reg) {
 case PCA9552_PSC0:
@@ -94,7 +94,7 @@ static void pca9552_write(PCA9552State *s, uint8_t reg, 
uint8_t data)
 case PCA9552_LS2:
 case PCA9552_LS3:
 s->regs[reg] = data;
-pca9552_update_pin_input(s);
+pca955x_update_pin_input(s);
 break;
 
 case PCA9552_INPUT0:
@@ -110,7 +110,7 @@ static void pca9552_write(PCA9552State *s, uint8_t reg, 
uint8_t data)
  * after each byte is sent to or received by the device. The index
  * rollovers to 0 when the maximum register address is reached.
  */
-static void pca9552_autoinc(PCA9552State *s)
+static void pca955x_autoinc(PCA955xState *s)
 {
 if (s->pointer != 0xFF && s->pointer & PCA9552_AUTOINC) {
 uint8_t reg = s->pointer & 0xf;
@@ -120,12 +120,12 @@ static void pca9552_autoinc(PCA9552State *s)
 }
 }
 
-static uint8_t pca9552_recv(I2CSlave *i2c)
+static uint8_t pca955x_recv(I2CSlave *i2c)
 {
-PCA9552State *s = PCA9552(i2c);
+PCA955xState *s = PCA955X(i2c);
 uint8_t ret;
 
-ret = pca9552_read(s, s->pointer & 0xf);
+ret = pca955x_read(s, s->pointer & 0xf);
 
 /*
  * From the Specs:
@@ -143,40 +143,40 @@ static uint8_t pca9552_recv(I2CSlave *i2c)
   __func__);
 }
 
-pca9552_autoinc(s);
+pca955x_autoinc(s);
 
 return ret;
 }
 
-static int pca9552_send(I2CSlave *i2c, uint8_t data)
+static int pca955x_send(I2CSlave *i2c, uint8_t data)
 {
-PCA9552State *s = PCA9552(i2c);
+PCA955xState *s = PCA955X(i2c);
 
 /* First byte sent by is the register address */
 if (s->len == 0) {
 s->pointer = data;
 s->len++;
 } else {
-pca9552_write(s, s->pointer & 0xf, data);
+pca955x_write(s, s->pointer & 0xf, data);
 
-pca9552_autoinc(s);
+pca955x_autoinc(s);
 }
 
 return 0;
 }
 
-static int pca9552_event(I2CSlave *i2c, enum i2c_event event)
+static int pca955x_event(I2CSlave *i2c, enum i2c_event event)
 {
-PCA9552State *s = PCA9552(i2c);
+PCA955xState *s = PCA955X(i2c);
 
 s->len = 0;
 return 0;
 }
 
-static void pca9552_get_led(Ob

[PULL 11/57] hw/misc/pca9552: Trace GPIO change events

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

Emit a trace event when a GPIO change its state.

Example booting obmc-phosphor-image:

  $ qemu-system-arm -M witherspoon-bmc -trace pca955x_gpio_change
  1592690552.687372:pca955x_gpio_change pca1 GPIO id:0 status: 0 -> 1
  1592690552.690169:pca955x_gpio_change pca1 GPIO id:1 status: 0 -> 1
  1592690552.691673:pca955x_gpio_change pca1 GPIO id:2 status: 0 -> 1
  1592690552.696886:pca955x_gpio_change pca1 GPIO id:3 status: 0 -> 1
  1592690552.698614:pca955x_gpio_change pca1 GPIO id:13 status: 0 -> 1
  1592690552.699833:pca955x_gpio_change pca1 GPIO id:14 status: 0 -> 1
  1592690552.700842:pca955x_gpio_change pca1 GPIO id:15 status: 0 -> 1
  1592690683.841921:pca955x_gpio_change pca1 GPIO id:14 status: 1 -> 0
  1592690683.861660:pca955x_gpio_change pca1 GPIO id:14 status: 0 -> 1
  1592690684.371460:pca955x_gpio_change pca1 GPIO id:14 status: 1 -> 0
  1592690684.882115:pca955x_gpio_change pca1 GPIO id:14 status: 0 -> 1
  1592690685.391411:pca955x_gpio_change pca1 GPIO id:14 status: 1 -> 0
  1592690685.901391:pca955x_gpio_change pca1 GPIO id:14 status: 0 -> 1
  1592690686.411678:pca955x_gpio_change pca1 GPIO id:14 status: 1 -> 0
  1592690686.921279:pca955x_gpio_change pca1 GPIO id:14 status: 0 -> 1

We notice the GPIO #14 (front-power LED) starts to blink.

This LED is described in the witherspoon device-tree [*]:

  front-power {
  retain-state-shutdown;
  default-state = "keep";
  gpios = <&pca0 14 GPIO_ACTIVE_LOW>;
  };

[*] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts?id=b1f9be9392f0#n140

Reviewed-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
Tested-by: Cédric Le Goater 
Message-id: 20200623072723.6324-9-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 hw/misc/pca9552.c| 15 +++
 hw/misc/trace-events |  1 +
 2 files changed, 16 insertions(+)

diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index 41f8ad213dd..1c3ad57432a 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -82,6 +82,21 @@ static void pca955x_display_pins_status(PCA955xState *s,
 buf[i] = '\0';
 trace_pca955x_gpio_status(s->description, buf);
 }
+if (trace_event_get_state_backends(TRACE_PCA955X_GPIO_CHANGE)) {
+for (i = 0; i < k->pin_count; i++) {
+if (extract32(pins_changed, i, 1)) {
+unsigned new_state = extract32(pins_status, i, 1);
+
+/*
+ * We display the state using the PCA logic ("active-high").
+ * This is not the state of the LED, which signal might be
+ * wired "active-low" on the board.
+ */
+trace_pca955x_gpio_change(s->description, i,
+  !new_state, new_state);
+}
+}
+}
 }
 
 static void pca955x_update_pin_input(PCA955xState *s)
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index bd7bd37ea8d..ebea53735c4 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -212,3 +212,4 @@ grlib_apb_pnp_read(uint64_t addr, uint32_t value) "APB PnP 
read addr:0x%03"PRIx6
 
 # pca9552.c
 pca955x_gpio_status(const char *description, const char *buf) "%s GPIOs 0-15 
[%s]"
+pca955x_gpio_change(const char *description, unsigned id, unsigned prev_state, 
unsigned current_state) "%s GPIO id:%u status: %u -> %u"
-- 
2.20.1




[PULL 07/57] hw/misc/pca9552: Add generic PCA955xClass, parent of TYPE_PCA9552

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

Extract the code common to the PCA955x family in PCA955xClass,
keeping the PCA9552 specific parts into pca9552_class_init().
Remove the 'TODO' comment added in commit 5141d4158cf.

Suggested-by: Cédric Le Goater 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
Tested-by: Cédric Le Goater 
Message-id: 20200623072723.6324-5-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 include/hw/misc/pca9552.h |  6 ++--
 hw/misc/pca9552.c | 66 ---
 2 files changed, 51 insertions(+), 21 deletions(-)

diff --git a/include/hw/misc/pca9552.h b/include/hw/misc/pca9552.h
index db527595a38..90843b03b8a 100644
--- a/include/hw/misc/pca9552.h
+++ b/include/hw/misc/pca9552.h
@@ -12,9 +12,11 @@
 #include "hw/i2c/i2c.h"
 
 #define TYPE_PCA9552 "pca9552"
-#define PCA955X(obj) OBJECT_CHECK(PCA955xState, (obj), TYPE_PCA9552)
+#define TYPE_PCA955X "pca955x"
+#define PCA955X(obj) OBJECT_CHECK(PCA955xState, (obj), TYPE_PCA955X)
 
 #define PCA955X_NR_REGS 10
+#define PCA955X_PIN_COUNT_MAX 16
 
 typedef struct PCA955xState {
 /*< private >*/
@@ -25,8 +27,6 @@ typedef struct PCA955xState {
 uint8_t pointer;
 
 uint8_t regs[PCA955X_NR_REGS];
-uint8_t max_reg;
-uint8_t pin_count;
 } PCA955xState;
 
 #endif
diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index 5681ff3b22d..4de57dbe2e2 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -4,6 +4,7 @@
  * https://www.nxp.com/docs/en/application-note/AN264.pdf
  *
  * Copyright (c) 2017-2018, IBM Corporation.
+ * Copyright (c) 2020 Philippe Mathieu-Daudé
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or
  * later. See the COPYING file in the top-level directory.
@@ -18,6 +19,20 @@
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 
+typedef struct PCA955xClass {
+/*< private >*/
+I2CSlaveClass parent_class;
+/*< public >*/
+
+uint8_t pin_count;
+uint8_t max_reg;
+} PCA955xClass;
+
+#define PCA955X_CLASS(klass) \
+OBJECT_CLASS_CHECK(PCA955xClass, (klass), TYPE_PCA955X)
+#define PCA955X_GET_CLASS(obj) \
+OBJECT_GET_CLASS(PCA955xClass, (obj), TYPE_PCA955X)
+
 #define PCA9552_LED_ON   0x0
 #define PCA9552_LED_OFF  0x1
 #define PCA9552_LED_PWM0 0x2
@@ -35,9 +50,10 @@ static uint8_t pca955x_pin_get_config(PCA955xState *s, int 
pin)
 
 static void pca955x_update_pin_input(PCA955xState *s)
 {
+PCA955xClass *k = PCA955X_GET_CLASS(s);
 int i;
 
-for (i = 0; i < s->pin_count; i++) {
+for (i = 0; i < k->pin_count; i++) {
 uint8_t input_reg = PCA9552_INPUT0 + (i / 8);
 uint8_t input_shift = (i % 8);
 uint8_t config = pca955x_pin_get_config(s, i);
@@ -112,10 +128,12 @@ static void pca955x_write(PCA955xState *s, uint8_t reg, 
uint8_t data)
  */
 static void pca955x_autoinc(PCA955xState *s)
 {
+PCA955xClass *k = PCA955X_GET_CLASS(s);
+
 if (s->pointer != 0xFF && s->pointer & PCA9552_AUTOINC) {
 uint8_t reg = s->pointer & 0xf;
 
-reg = (reg + 1) % (s->max_reg + 1);
+reg = (reg + 1) % (k->max_reg + 1);
 s->pointer = reg | PCA9552_AUTOINC;
 }
 }
@@ -176,6 +194,7 @@ static int pca955x_event(I2CSlave *i2c, enum i2c_event 
event)
 static void pca955x_get_led(Object *obj, Visitor *v, const char *name,
 void *opaque, Error **errp)
 {
+PCA955xClass *k = PCA955X_GET_CLASS(obj);
 PCA955xState *s = PCA955X(obj);
 int led, rc, reg;
 uint8_t state;
@@ -185,7 +204,7 @@ static void pca955x_get_led(Object *obj, Visitor *v, const 
char *name,
 error_setg(errp, "%s: error reading %s", __func__, name);
 return;
 }
-if (led < 0 || led > s->pin_count) {
+if (led < 0 || led > k->pin_count) {
 error_setg(errp, "%s invalid led %s", __func__, name);
 return;
 }
@@ -212,6 +231,7 @@ static inline uint8_t pca955x_ledsel(uint8_t oldval, int 
led_num, int state)
 static void pca955x_set_led(Object *obj, Visitor *v, const char *name,
 void *opaque, Error **errp)
 {
+PCA955xClass *k = PCA955X_GET_CLASS(obj);
 PCA955xState *s = PCA955X(obj);
 Error *local_err = NULL;
 int led, rc, reg, val;
@@ -228,7 +248,7 @@ static void pca955x_set_led(Object *obj, Visitor *v, const 
char *name,
 error_setg(errp, "%s: error reading %s", __func__, name);
 return;
 }
-if (led < 0 || led > s->pin_count) {
+if (led < 0 || led > k->pin_count) {
 error_setg(errp, "%s invalid led %s", __func__, name);
 return;
 }
@@ -283,17 +303,11 @@ static void pca9552_reset(DeviceState *dev)
 
 static void pca955x_initfn(Object *obj)
 {
-PCA955xState *s = PCA955X(obj);
+PCA955xClass *k = PCA955X_GET_CLASS(obj);
 int led;
 
-/* If support for the other PCA955X devices are implemented, these
- * constant values might be part of class structure describing the
- * PCA955X device
- */
-s->max_reg = PCA9552_LS3

[PULL 03/57] hw/arm/aspeed: QOM'ify AspeedMachineState

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

AspeedMachineState seems crippled. We use incorrectly 2
different structures to do the same thing. Merge them
altogether:
- Move AspeedMachine fields to AspeedMachineState
- AspeedMachineState is now QOM
- Remove unused AspeedMachine structure

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Cédric Le Goater 
Message-id: 20200623072132.2868-4-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 include/hw/arm/aspeed.h |  8 +---
 hw/arm/aspeed.c | 11 +++
 2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
index 5114ba0bd4f..09da9d9accf 100644
--- a/include/hw/arm/aspeed.h
+++ b/include/hw/arm/aspeed.h
@@ -15,13 +15,7 @@ typedef struct AspeedMachineState AspeedMachineState;
 
 #define TYPE_ASPEED_MACHINE   MACHINE_TYPE_NAME("aspeed")
 #define ASPEED_MACHINE(obj) \
-OBJECT_CHECK(AspeedMachine, (obj), TYPE_ASPEED_MACHINE)
-
-typedef struct AspeedMachine {
-MachineState parent_obj;
-
-bool mmio_exec;
-} AspeedMachine;
+OBJECT_CHECK(AspeedMachineState, (obj), TYPE_ASPEED_MACHINE)
 
 #define ASPEED_MAC0_ON   (1 << 0)
 #define ASPEED_MAC1_ON   (1 << 1)
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index a167b736970..665d04fbf68 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -33,9 +33,14 @@ static struct arm_boot_info aspeed_board_binfo = {
 };
 
 struct AspeedMachineState {
+/* Private */
+MachineState parent_obj;
+/* Public */
+
 AspeedSoCState soc;
 MemoryRegion ram_container;
 MemoryRegion max_ram;
+bool mmio_exec;
 };
 
 /* Palmetto hardware value: 0x120CE416 */
@@ -253,7 +258,7 @@ static void sdhci_attach_drive(SDHCIState *sdhci, DriveInfo 
*dinfo)
 
 static void aspeed_machine_init(MachineState *machine)
 {
-AspeedMachineState *bmc;
+AspeedMachineState *bmc = ASPEED_MACHINE(machine);
 AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
 AspeedSoCClass *sc;
 DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
@@ -261,8 +266,6 @@ static void aspeed_machine_init(MachineState *machine)
 int i;
 NICInfo *nd = &nd_table[0];
 
-bmc = g_new0(AspeedMachineState, 1);
-
 memory_region_init(&bmc->ram_container, NULL, "aspeed-ram-container",
4 * GiB);
 memory_region_add_subregion(&bmc->ram_container, 0, machine->ram);
@@ -751,7 +754,7 @@ static const TypeInfo aspeed_machine_types[] = {
 }, {
 .name  = TYPE_ASPEED_MACHINE,
 .parent= TYPE_MACHINE,
-.instance_size = sizeof(AspeedMachine),
+.instance_size = sizeof(AspeedMachineState),
 .instance_init = aspeed_machine_instance_init,
 .class_size= sizeof(AspeedMachineClass),
 .class_init= aspeed_machine_class_init,
-- 
2.20.1




[PULL 12/57] hw/misc/pca9552: Model qdev output GPIOs

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

The PCA9552 has 16 GPIOs which can be used as input,
output or PWM mode. QEMU models the output GPIO with
the qemu_irq type. Let the device expose the 16 GPIOs
to allow us to later connect LEDs to these outputs.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
Tested-by: Cédric Le Goater 
Message-id: 20200623072723.6324-10-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 include/hw/misc/pca9552.h | 1 +
 hw/misc/pca9552.c | 6 ++
 2 files changed, 7 insertions(+)

diff --git a/include/hw/misc/pca9552.h b/include/hw/misc/pca9552.h
index bf1a5891378..600356fbf90 100644
--- a/include/hw/misc/pca9552.h
+++ b/include/hw/misc/pca9552.h
@@ -27,6 +27,7 @@ typedef struct PCA955xState {
 uint8_t pointer;
 
 uint8_t regs[PCA955X_NR_REGS];
+qemu_irq gpio[PCA955X_PIN_COUNT_MAX];
 char *description; /* For debugging purpose only */
 } PCA955xState;
 
diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index 1c3ad57432a..80caa9ec8fc 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -17,6 +17,7 @@
 #include "hw/qdev-properties.h"
 #include "hw/misc/pca9552.h"
 #include "hw/misc/pca9552_regs.h"
+#include "hw/irq.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
@@ -111,9 +112,11 @@ static void pca955x_update_pin_input(PCA955xState *s)
 
 switch (config) {
 case PCA9552_LED_ON:
+qemu_set_irq(s->gpio[i], 1);
 s->regs[input_reg] |= 1 << input_shift;
 break;
 case PCA9552_LED_OFF:
+qemu_set_irq(s->gpio[i], 0);
 s->regs[input_reg] &= ~(1 << input_shift);
 break;
 case PCA9552_LED_PWM0:
@@ -374,11 +377,14 @@ static void pca955x_initfn(Object *obj)
 
 static void pca955x_realize(DeviceState *dev, Error **errp)
 {
+PCA955xClass *k = PCA955X_GET_CLASS(dev);
 PCA955xState *s = PCA955X(dev);
 
 if (!s->description) {
 s->description = g_strdup("pca-unspecified");
 }
+
+qdev_init_gpio_out(dev, s->gpio, k->pin_count);
 }
 
 static Property pca955x_properties[] = {
-- 
2.20.1




[PULL 02/57] hw/arm/aspeed: Rename AspeedBoardState as AspeedMachineState

2020-06-26 Thread Peter Maydell
From: Philippe Mathieu-Daudé 

To have a more consistent naming, rename AspeedBoardState
as AspeedMachineState.

Suggested-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Cédric Le Goater 
Message-id: 20200623072132.2868-3-f4...@amsat.org
Signed-off-by: Peter Maydell 
---
 include/hw/arm/aspeed.h |  4 ++--
 hw/arm/aspeed.c | 20 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
index 95b4daece86..5114ba0bd4f 100644
--- a/include/hw/arm/aspeed.h
+++ b/include/hw/arm/aspeed.h
@@ -11,7 +11,7 @@
 
 #include "hw/boards.h"
 
-typedef struct AspeedBoardState AspeedBoardState;
+typedef struct AspeedMachineState AspeedMachineState;
 
 #define TYPE_ASPEED_MACHINE   MACHINE_TYPE_NAME("aspeed")
 #define ASPEED_MACHINE(obj) \
@@ -45,7 +45,7 @@ typedef struct AspeedMachineClass {
 const char *spi_model;
 uint32_t num_cs;
 uint32_t macs_mask;
-void (*i2c_init)(AspeedBoardState *bmc);
+void (*i2c_init)(AspeedMachineState *bmc);
 } AspeedMachineClass;
 
 
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 167fd5ed1c7..a167b736970 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -32,7 +32,7 @@ static struct arm_boot_info aspeed_board_binfo = {
 .board_id = -1, /* device-tree-only board */
 };
 
-struct AspeedBoardState {
+struct AspeedMachineState {
 AspeedSoCState soc;
 MemoryRegion ram_container;
 MemoryRegion max_ram;
@@ -253,7 +253,7 @@ static void sdhci_attach_drive(SDHCIState *sdhci, DriveInfo 
*dinfo)
 
 static void aspeed_machine_init(MachineState *machine)
 {
-AspeedBoardState *bmc;
+AspeedMachineState *bmc;
 AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
 AspeedSoCClass *sc;
 DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
@@ -261,7 +261,7 @@ static void aspeed_machine_init(MachineState *machine)
 int i;
 NICInfo *nd = &nd_table[0];
 
-bmc = g_new0(AspeedBoardState, 1);
+bmc = g_new0(AspeedMachineState, 1);
 
 memory_region_init(&bmc->ram_container, NULL, "aspeed-ram-container",
4 * GiB);
@@ -374,7 +374,7 @@ static void aspeed_machine_init(MachineState *machine)
 arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo);
 }
 
-static void palmetto_bmc_i2c_init(AspeedBoardState *bmc)
+static void palmetto_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = &bmc->soc;
 DeviceState *dev;
@@ -396,7 +396,7 @@ static void palmetto_bmc_i2c_init(AspeedBoardState *bmc)
 object_property_set_int(OBJECT(dev), 11, "temperature3", &error_abort);
 }
 
-static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
+static void ast2500_evb_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = &bmc->soc;
 uint8_t *eeprom_buf = g_malloc0(8 * 1024);
@@ -413,13 +413,13 @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 
0x32);
 }
 
-static void ast2600_evb_i2c_init(AspeedBoardState *bmc)
+static void ast2600_evb_i2c_init(AspeedMachineState *bmc)
 {
 /* Start with some devices on our I2C busses */
 ast2500_evb_i2c_init(bmc);
 }
 
-static void romulus_bmc_i2c_init(AspeedBoardState *bmc)
+static void romulus_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = &bmc->soc;
 
@@ -428,7 +428,7 @@ static void romulus_bmc_i2c_init(AspeedBoardState *bmc)
 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 
0x32);
 }
 
-static void swift_bmc_i2c_init(AspeedBoardState *bmc)
+static void swift_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = &bmc->soc;
 
@@ -457,7 +457,7 @@ static void swift_bmc_i2c_init(AspeedBoardState *bmc)
 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 12), "tmp105", 
0x4a);
 }
 
-static void sonorapass_bmc_i2c_init(AspeedBoardState *bmc)
+static void sonorapass_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = &bmc->soc;
 
@@ -501,7 +501,7 @@ static void sonorapass_bmc_i2c_init(AspeedBoardState *bmc)
 
 }
 
-static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
+static void witherspoon_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = &bmc->soc;
 uint8_t *eeprom_buf = g_malloc0(8 * 1024);
-- 
2.20.1




Re: [PATCH v2 00/16] Crazy shit around -global (pardon my french)

2020-06-26 Thread John Snow



On 6/25/20 12:45 AM, Markus Armbruster wrote:
> John Snow  writes:
> 
>> On 6/22/20 5:42 AM, Markus Armbruster wrote:
>>> There are three ways to configure backends:
>>>
>>> * -nic, -serial, -drive, ... (onboard devices)
>>>
>>> * Set the property with -device, or, if you feel masochistic, with
>>>   -set device (pluggable devices)
>>>
>>> * Set the property with -global (both)
>>>
>>> The trouble is -global is terrible.
>>>
>>> It gets applied in object_new(), which can't fail.  We treat failure
>>> to apply -global as fatal error, except when hot-plugging, where we
>>> treat it as warning *boggle*.  I'm not addressing that today.
>>>
>>> Some code falls apart when you use both -global and the other way.
>>>
>>> To make life more interesting, we gave -drive two roles: with
>>> interface type other than none, it's for configuring onboard devices,
>>> and with interface type none, it's for defining backends for use with
>>> -device and such.  Since we neglect to require interface type none for
>>> the latter, you can use one -drive in both roles.  This confuses the
>>> code about as much as you, dear reader, probably are by now.
>>>
>>> Because this still isn't interesting enough, there's yet another way
>>> to configure backends, just for floppies: set the floppy controller's
>>> property.  Goes back to the time when floppy wasn't a separate device,
>>> and involves some Bad Magic.  Now -global can interact with itself!
>>>
>>> Digging through all this took me an embarrassing amount of time.
>>> Hair, too.
>>>
>>> My patches reject some the silliest uses outright, and deprecate some
>>> not so silly ones that have replacements.
>>>
>>> Apply on top of my "[PATCH v2 00/58] qdev: Rework how we plug into the
>>> parent bus".
>>>
>>
>> Oof. Thank you for your work in fixing our darkest corners. I sincerely
>> appreciate it.
>>
>> The qdev tree ordering problems don't cause any issues for migration, do
>> they?
> 
> This series should only change device configuration, not device state or
> its encoding in the migration stream.
> 
> I'm not sure what you mean by "qdev tree ordering problems".  Ist it
> commit e8c9e65816 'qom: Make "info qom-tree" show children sorted'?
> 
>> (I see you already sent a PR, so whatever!)
> 
> A question that might avoid a later migration debugging session is
> *never* "whatever"!
> 

I thought I had read that one of these patches changes the order in
which devices get instantiated, which I thought might change their QOM
paths. Which I thought *might* have some ramifications for migration,
but wasn't sure.

If it's just showing the same path outputs *sorted*, then there's no
problem.

Likely misread.

--js




Re: [PATCH QEMU v25 09/17] vfio: Add load state functions to SaveVMHandlers

2020-06-26 Thread Dr. David Alan Gilbert
* Alex Williamson (alex.william...@redhat.com) wrote:
> On Sun, 21 Jun 2020 01:51:18 +0530
> Kirti Wankhede  wrote:
> 
> > Sequence  during _RESUMING device state:
> > While data for this device is available, repeat below steps:
> > a. read data_offset from where user application should write data.
> > b. write data of data_size to migration region from data_offset.
> > c. write data_size which indicates vendor driver that data is written in
> >staging buffer.
> > 
> > For user, data is opaque. User should write data in the same order as
> > received.
> > 
> > Signed-off-by: Kirti Wankhede 
> > Reviewed-by: Neo Jia 
> > Reviewed-by: Dr. David Alan Gilbert 
> > ---
> >  hw/vfio/migration.c  | 177 
> > +++
> >  hw/vfio/trace-events |   3 +
> >  2 files changed, 180 insertions(+)
> > 
> > diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
> > index ef1150c1ff02..faacea5327cb 100644
> > --- a/hw/vfio/migration.c
> > +++ b/hw/vfio/migration.c
> > @@ -302,6 +302,33 @@ static int vfio_save_device_config_state(QEMUFile *f, 
> > void *opaque)
> >  return qemu_file_get_error(f);
> >  }
> >  
> > +static int vfio_load_device_config_state(QEMUFile *f, void *opaque)
> > +{
> > +VFIODevice *vbasedev = opaque;
> > +uint64_t data;
> > +
> > +if (vbasedev->ops && vbasedev->ops->vfio_load_config) {
> > +int ret;
> > +
> > +ret = vbasedev->ops->vfio_load_config(vbasedev, f);
> > +if (ret) {
> > +error_report("%s: Failed to load device config space",
> > + vbasedev->name);
> > +return ret;
> > +}
> > +}
> > +
> > +data = qemu_get_be64(f);
> > +if (data != VFIO_MIG_FLAG_END_OF_STATE) {
> > +error_report("%s: Failed loading device config space, "
> > + "end flag incorrect 0x%"PRIx64, vbasedev->name, data);
> > +return -EINVAL;
> > +}
> > +
> > +trace_vfio_load_device_config_state(vbasedev->name);
> > +return qemu_file_get_error(f);
> > +}
> > +
> >  /* -- 
> > */
> >  
> >  static int vfio_save_setup(QEMUFile *f, void *opaque)
> > @@ -472,12 +499,162 @@ static int vfio_save_complete_precopy(QEMUFile *f, 
> > void *opaque)
> >  return ret;
> >  }
> >  
> > +static int vfio_load_setup(QEMUFile *f, void *opaque)
> > +{
> > +VFIODevice *vbasedev = opaque;
> > +VFIOMigration *migration = vbasedev->migration;
> > +int ret = 0;
> > +
> > +if (migration->region.mmaps) {
> > +ret = vfio_region_mmap(&migration->region);
> > +if (ret) {
> > +error_report("%s: Failed to mmap VFIO migration region %d: %s",
> > + vbasedev->name, migration->region.nr,
> > + strerror(-ret));
> > +return ret;
> 
> 
> Not fatal.
> 
> 
> > +}
> > +}
> > +
> > +ret = vfio_migration_set_state(vbasedev, ~VFIO_DEVICE_STATE_MASK,
> > +   VFIO_DEVICE_STATE_RESUMING);
> > +if (ret) {
> > +error_report("%s: Failed to set state RESUMING", vbasedev->name);
> > +}
> > +return ret;
> > +}
> > +
> > +static int vfio_load_cleanup(void *opaque)
> > +{
> > +vfio_save_cleanup(opaque);
> > +return 0;
> > +}
> > +
> > +static int vfio_load_state(QEMUFile *f, void *opaque, int version_id)
> > +{
> > +VFIODevice *vbasedev = opaque;
> > +VFIOMigration *migration = vbasedev->migration;
> > +int ret = 0;
> > +uint64_t data, data_size;
> > +
> > +data = qemu_get_be64(f);
> > +while (data != VFIO_MIG_FLAG_END_OF_STATE) {
> > +
> > +trace_vfio_load_state(vbasedev->name, data);
> > +
> > +switch (data) {
> > +case VFIO_MIG_FLAG_DEV_CONFIG_STATE:
> > +{
> > +ret = vfio_load_device_config_state(f, opaque);
> > +if (ret) {
> > +return ret;
> > +}
> > +break;
> > +}
> > +case VFIO_MIG_FLAG_DEV_SETUP_STATE:
> > +{
> > +data = qemu_get_be64(f);
> > +if (data == VFIO_MIG_FLAG_END_OF_STATE) {
> > +return ret;
> > +} else {
> > +error_report("%s: SETUP STATE: EOS not found 0x%"PRIx64,
> > + vbasedev->name, data);
> > +return -EINVAL;
> 
> This is essentially just a compatibility failure, right?  For instance
> some future version of QEMU might include additional data between these
> markers that we don't understand and therefore we fail the migration.

Or any other screwup in data layout;  we've found having a canary at the
end of state is quite useful for when we screwup for one reason or
another.

Dave

> Thanks,
> 
> Alex
> 
> > +}
> > +break;
> > +}
> > +case VFIO_MIG_FLAG_DEV_DATA_STATE:
> > +{
> > +VFIORegion *region = &migratio

Re: [PATCH QEMU v25 05/17] vfio: Add VM state change handler to know state of VM

2020-06-26 Thread Dr. David Alan Gilbert
* Kirti Wankhede (kwankh...@nvidia.com) wrote:
> 
> 
> On 6/23/2020 4:20 AM, Alex Williamson wrote:
> > On Sun, 21 Jun 2020 01:51:14 +0530
> > Kirti Wankhede  wrote:
> > 
> > > VM state change handler gets called on change in VM's state. This is used 
> > > to set
> > > VFIO device state to _RUNNING.
> > > 
> > > Signed-off-by: Kirti Wankhede 
> > > Reviewed-by: Neo Jia 
> > > Reviewed-by: Dr. David Alan Gilbert 
> > > ---
> > >   hw/vfio/migration.c   | 87 
> > > +++
> > >   hw/vfio/trace-events  |  2 +
> > >   include/hw/vfio/vfio-common.h |  4 ++
> > >   3 files changed, 93 insertions(+)
> > > 
> > > diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
> > > index 48ac385d80a7..fcecc0bb0874 100644
> > > --- a/hw/vfio/migration.c
> > > +++ b/hw/vfio/migration.c
> > > @@ -10,6 +10,7 @@
> > >   #include "qemu/osdep.h"
> > >   #include 
> > > +#include "sysemu/runstate.h"
> > >   #include "hw/vfio/vfio-common.h"
> > >   #include "cpu.h"
> > >   #include "migration/migration.h"
> > > @@ -74,6 +75,85 @@ err:
> > >   return ret;
> > >   }
> > > +static int vfio_migration_set_state(VFIODevice *vbasedev, uint32_t mask,
> > > +uint32_t value)
> > > +{
> > > +VFIOMigration *migration = vbasedev->migration;
> > > +VFIORegion *region = &migration->region;
> > > +uint32_t device_state;
> > > +int ret;
> > > +
> > > +ret = pread(vbasedev->fd, &device_state, sizeof(device_state),
> > > +region->fd_offset + offsetof(struct 
> > > vfio_device_migration_info,
> > > +  device_state));
> > > +if (ret < 0) {
> > > +error_report("%s: Failed to read device state %d %s",
> > > + vbasedev->name, ret, strerror(errno));
> > > +return ret;
> > > +}
> > > +
> > > +device_state = (device_state & mask) | value;
> > > +
> > > +if (!VFIO_DEVICE_STATE_VALID(device_state)) {
> > > +return -EINVAL;
> > > +}
> > > +
> > > +ret = pwrite(vbasedev->fd, &device_state, sizeof(device_state),
> > > + region->fd_offset + offsetof(struct 
> > > vfio_device_migration_info,
> > > +  device_state));
> > > +if (ret < 0) {
> > > +error_report("%s: Failed to set device state %d %s",
> > > + vbasedev->name, ret, strerror(errno));
> > > +
> > > +ret = pread(vbasedev->fd, &device_state, sizeof(device_state),
> > > +region->fd_offset + offsetof(struct 
> > > vfio_device_migration_info,
> > > +device_state));
> > > +if (ret < 0) {
> > > +error_report("%s: On failure, failed to read device state %d 
> > > %s",
> > > +vbasedev->name, ret, strerror(errno));
> > > +return ret;
> > > +}
> > > +
> > > +if (VFIO_DEVICE_STATE_IS_ERROR(device_state)) {
> > > +error_report("%s: Device is in error state 0x%x",
> > > + vbasedev->name, device_state);
> > > +return -EFAULT;
> > > +}
> > > +}
> > > +
> > > +vbasedev->device_state = device_state;
> > > +trace_vfio_migration_set_state(vbasedev->name, device_state);
> > > +return 0;
> > > +}
> > > +
> > > +static void vfio_vmstate_change(void *opaque, int running, RunState 
> > > state)
> > > +{
> > > +VFIODevice *vbasedev = opaque;
> > > +
> > > +if ((vbasedev->vm_running != running)) {
> > > +int ret;
> > > +uint32_t value = 0, mask = 0;
> > > +
> > > +if (running) {
> > > +value = VFIO_DEVICE_STATE_RUNNING;
> > > +if (vbasedev->device_state & VFIO_DEVICE_STATE_RESUMING) {
> > > +mask = ~VFIO_DEVICE_STATE_RESUMING;
> > > +}
> > > +} else {
> > > +mask = ~VFIO_DEVICE_STATE_RUNNING;
> > > +}
> > > +
> > > +ret = vfio_migration_set_state(vbasedev, mask, value);
> > > +if (ret) {
> > > +error_report("%s: Failed to set device state 0x%x",
> > > + vbasedev->name, value & mask);
> > 
> > 
> > Is there nothing more we should do here?  It seems like in either the
> > case of an outbound migration where we can't stop the device or an
> > inbound migration where we can't start the device, we'd want this to
> > trigger an abort of the migration.  Should there at least be a TODO
> > comment if the reason is that QEMU migration doesn't yet support failure
> > here?  Thanks,
> > 
> 
> Checked other modules in QEMU, at some places error message is reported as
> above while at some places abort() is called (for example
> kvmclock_vm_state_change() in hw/i386/kvm/clock.c). Abort will abort QEMU
> process, that is VM crash. Should we abort here on error case? Anyways VM
> will not recover properly on migration if there is such error.

I prefer to avoid aborts on migration if 

Re: [PATCH] hw/timer/a9gtimer: Clear pending interrupt, after the clear of Event flag

2020-06-26 Thread Peter Maydell
On Tue, 16 Jun 2020 at 08:04, Václav Vanc  wrote:
>
> On 6/15/20 1:04 PM, Peter Maydell wrote:
> We must distinguish between two cases:
> 1, Auto-increment is disabled.
> I just run some test on SABRE Lite (i.MX6) board.
> I had auto-increment disabled, I verified, that GIC is configured for
> Edge interrupts. Once count went past the compare value I got the
> interrupt. I did not touch Timer registers, just signal EOI to GIC and
> surprisingly, I got a another interrupt. If I stopped the timer
> interrupts stopped coming (Status was still set to 1).
>
>  From this behavior I assume, that every time the Timer is incremented
> (and Timer value is past the compare value) an EDGE interrupt (that
> means actual X->0->1 transition) is asserted. This is really interesting
> from HW point of view. This would mean, that a9_gtimer_update function
> should generate the pulse and not level on compare event.

That's interesting. Which version of the Cortex-A9 does this
board have? The TRM documents that the comparator behaviour
changed in r2p0...

thanks
-- PMM



Re: [PATCH QEMU v25 13/17] vfio: create mapped iova list when vIOMMU is enabled

2020-06-26 Thread Peter Xu
On Thu, Jun 25, 2020 at 11:40:39AM -0600, Alex Williamson wrote:
> On Thu, 25 Jun 2020 20:04:08 +0530
> Kirti Wankhede  wrote:
> 
> > On 6/25/2020 12:25 AM, Alex Williamson wrote:
> > > On Sun, 21 Jun 2020 01:51:22 +0530
> > > Kirti Wankhede  wrote:
> > >   
> > >> Create mapped iova list when vIOMMU is enabled. For each mapped iova
> > >> save translated address. Add node to list on MAP and remove node from
> > >> list on UNMAP.
> > >> This list is used to track dirty pages during migration.  
> > > 
> > > This seems like a lot of overhead to support that the VM might migrate.
> > > Is there no way we can build this when we start migration, for example
> > > replaying the mappings at that time?  Thanks,
> > >   
> > 
> > In my previous version I tried to go through whole range and find valid 
> > iotlb, as below:
> > 
> > +if (memory_region_is_iommu(section->mr)) {
> > +iotlb = address_space_get_iotlb_entry(container->space->as, 
> > iova,
> > + true, 
> > MEMTXATTRS_UNSPECIFIED);
> > 
> > When mapping doesn't exist, qemu throws error as below:
> > 
> > qemu-system-x86_64: vtd_iova_to_slpte: detected slpte permission error 
> > (iova=0x0, level=0x3, slpte=0x0, write=1)
> > qemu-system-x86_64: vtd_iommu_translate: detected translation failure 
> > (dev=00:03:00, iova=0x0)
> > qemu-system-x86_64: New fault is not recorded due to compression of faults
> 
> My assumption would have been that we use the replay mechanism, which
> is known to work because we need to use it when we hot-add a device.
> We'd make use of iommu_notifier_init() to create a new handler for this
> purpose, then we'd walk our container->giommu_list and call
> memory_region_iommu_replay() for each.
> 
> Peter, does this sound like the right approach to you?

(Sorry I may not have the complete picture of this series, please bear with
 me...)

This seems to be a workable approach to me.  However then we might have a
similar mapping entry cached the 3rd time...  VFIO kernel has a copy initially,
then QEMU vIOMMU has another one (please grep iova_tree in intel_iommu.c).

My wild guess is that the mapping should still be in control in most cases, so
even if we cache it multiple times (for better layering) it would still be
fine.  However since we're in QEMU right now, I'm also thinking whether we can
share the information with the vIOMMU somehow, because even if the page table
entry is wiped off at that time we may still have a chance to use the DMAMap
object that cached in vIOMMU when iommu notify() happens.  Though that may
require some vIOMMU change too (e.g., vtd_page_walk_one may need to postpone
the iova_tree_remove to be after the hook_fn is called, also we may need to
pass the DMAMap object or at least the previous translated addr to the hook
somehow before removal), so maybe that can also be done on top.

> 
> > Secondly, it iterates through whole range with IOMMU page size 
> > granularity which is 4K, so it takes long time resulting in large 
> > downtime. With this optimization, downtime with vIOMMU reduced 
> > significantly.
> 
> Right, but we amortize that overhead and the resulting bloat across the
> 99.% of the time that we're not migrating.  I wonder if we could
> startup another thread to handle this when we enable dirty logging.  We
> don't really need the result until we start processing the dirty
> bitmap, right?  Also, if we're dealing with this many separate pages,
> shouldn't we be using a tree rather than a list to give us O(logN)
> rather than O(N)?

Yep I agree.  At least the vIOMMU cache is using gtree.

Btw, IIUC we won't walk the whole range using 4K granularity always, not for
VT-d emulation.  Because vtd_page_walk_level() is smart enough to skip higher
levels of invalid entries so it can jump with 2M/1G/... chunks if the whole
chunk is invalid.

Thanks,

-- 
Peter Xu




Re: [RFC PATCH 1/3] hw/i2c/smbus_eeprom: Set QOM parent

2020-06-26 Thread Philippe Mathieu-Daudé
On 6/26/20 4:26 PM, BALATON Zoltan wrote:
> On Fri, 26 Jun 2020, Philippe Mathieu-Daudé wrote:
>> On 6/26/20 4:03 PM, BALATON Zoltan wrote:
>>> On Fri, 26 Jun 2020, Philippe Mathieu-Daudé wrote:
 + Eduardo / Mark / Edgard / Alistair / Fred for QOM design.

 On 6/26/20 12:54 PM, BALATON Zoltan wrote:
> On Fri, 26 Jun 2020, BALATON Zoltan wrote:
>> On Fri, 26 Jun 2020, Philippe Mathieu-Daudé wrote:
>>> Suggested-by: Markus Armbruster 
>>> Signed-off-by: Philippe Mathieu-Daudé 
>>> ---
>>> Aspeed change pending latest ARM pull-request, so meanwhile sending
>>> as RFC.
>>> ---
>>> include/hw/i2c/smbus_eeprom.h |  9 ++---
>>> hw/i2c/smbus_eeprom.c | 13 ++---
>>> hw/mips/fuloong2e.c   |  2 +-
>>> hw/ppc/sam460ex.c |  2 +-
>>> 4 files changed, 18 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/include/hw/i2c/smbus_eeprom.h
>>> b/include/hw/i2c/smbus_eeprom.h
>>> index 68b0063ab6..037612 100644
>>> --- a/include/hw/i2c/smbus_eeprom.h
>>> +++ b/include/hw/i2c/smbus_eeprom.h
>>> @@ -26,9 +26,12 @@
>>> #include "exec/cpu-common.h"
>>> #include "hw/i2c/i2c.h"
>>>
>>> -void smbus_eeprom_init_one(I2CBus *bus, uint8_t address, uint8_t
>>> *eeprom_buf);
>>> -void smbus_eeprom_init(I2CBus *bus, int nb_eeprom,
>>> -   const uint8_t *eeprom_spd, int size);
>>> +void smbus_eeprom_init_one(Object *parent_obj, const char
>>> *child_name,
>>> +   I2CBus *smbus, uint8_t address,
>>> +   uint8_t *eeprom_buf);
>>> +void smbus_eeprom_init(Object *parent_obj, const char
>>> *child_name_prefix,
>>> +   I2CBus *smbus, int nb_eeprom,
>>> +   const uint8_t *eeprom_spd, int
>>> eeprom_spd_size);
>>
>> Keeping I2CBus *smbus and uint8_t address as first parameters before
>> parent_obj and name looks better to me. These functions still operate
>> on an I2Cbus so could be regarded as methods of I2CBus therefore
>> first
>> parameter should be that.
>
> Also isn't parent_obj is the I2Cbus itself? Why is that need to be
> passed? The i2c_init_bus() also takes parent and name params so both
> I2Cbus and it's parent should be available as parents of the new I2C
> device here without more parameters. What am I missing here?

 This is where I'm confused too and what I want to resolve with this
 RFC series :)

 The SPD EEPROM is soldered on the DIMM module. The DIMM exposes the
 memory address/data pins and the i2c pins. We plug DIMMs on a
 (mother)board.

 I see the DIMM module being the parent. As we don't model it in QOM,
 I used the MemoryRegion (which is what the SPD is describing).

 We could represent the DIMM as a container of DRAM + SPD EEPROM, but
 it makes the modeling slightly more complex. The only benefit is a
 clearer modeling.

 I'm not sure why the I2C bus is expected to be the parent. Maybe an
 old wrong assumption?
>>>
>>> I guess it's a question of what the parent should mean? Is it parent of
>>> the object in which case it's the I2CBus (which is kind of logical view
>>> of the object tree modelling the machine) or the parent of the thing
>>> modelled in the machine (which is physical view of the machine
>>> components) then it should be the RAM module. The confusion probably
>>> comes from this question not answered. Also the DIMM module is not
>>> modelled so when you assign SPD eeproms to memory region it could be
>>> multiple SPD eeproms will be parented by a single RAM memory region
>>> (possibly not covering it fully as in the mac_oldworld or sam460ex case
>>> discussed in another thread). This does not seem too intuitive.
>>
>> From the bus perspective, requests are sent hoping for a device to
>> answer to the requested address ("Hello, do I have children? Hello?
>> Anybody here?"), if nobody is here, the request timeouts.
>> So there is not really a strong family relationship here.
>>
>> If you unplug a DIMM, you remove both the MemoryRegion and the EEPROM.
>> This is how I understand the QOM parent relationship so far (if you
>> remove a parent, you also remove its children).
> 
> OK but what if we don't have a DIMM object as that is not modelled?
> Should you set parent to the board in that case? Or is it still modelled
> as an I2C device that is plugged in an I2C bus. Does it need to have a
> parent in this case at all or is it a case for an unattached device
> (becuase its physical parent is not modelled)?

So you reduced the dependency as SPD -> RAM, which is clever because
we won't have DIMM without RAM =)

Suggestion for new prototype (eeprom content populated in callee):

  SMBusEEPROMDevice spd_eeprom_new(MemoryDeviceState *memdev,
   const char *eeprom_name,
   

Re: [PATCH 1/3] haiku build fix second batch

2020-06-26 Thread David CARLIER
No idea if I ll have energy to redo all over again I lost previous
patches. Fine no problems...

On Fri, 26 Jun 2020 at 15:33, Peter Maydell  wrote:
>
> On Fri, 26 Jun 2020 at 15:10, David CARLIER  wrote:
> >
> > I sent again minux the ones already approved.
>
> Sorry, I intended that you should send the whole
> series, including the ones which I've reviewed.
> (Where I gave a reviewed-by tag, include that
> tag in the commit message when you resend the patch.)
>
> thanks
> -- PMM



Re: [PATCH 06/46] error: Avoid error_propagate() when error is not used here

2020-06-26 Thread Vladimir Sementsov-Ogievskiy

24.06.2020 19:43, Markus Armbruster wrote:

When all we do with an Error we receive into a local variable is
propagating to somewhere else, we can just as well receive it there
right away.  Coccinelle script:

 @@
 identifier fun, err, errp;
 expression list args;
 @@
 -fun(args, &err);
 +fun(args, errp);
  ... when != err
  when strict
 -error_propagate(errp, err);

 @@
 identifier fun, err, errp;
 expression list args;
 expression ret;
 @@
 -ret = fun(args, &err);
 +ret = fun(args, errp);
  ... when != err
  when strict
 -error_propagate(errp, err);

 @@
 identifier fun, err, errp;
 expression list args;
 expression ret;
 @@
 -ret = fun(args, &err);
 +ret = fun(args, errp);
  ... when != err
  when strict
  if (
 (
  ret
 |
  !ret
 |
  ret == 0
 |
  ret != 0
 |
  ret < 0
 |
  ret != NULL
 |
  ret == NULL
 )
 )
  {
  ... when != err
  when strict
 -error_propagate(errp, err);
  ...
  }

 @@
 identifier fun, err, errp;
 expression list args;
 @@
  if (
 (
 -fun(args, &err)
 +fun(args, errp)
 |
 -!fun(args, &err)
 +!fun(args, errp)
 |
 -fun(args, &err) == 0
 +fun(args, errp) == 0
 |
 -fun(args, &err) != 0
 +fun(args, errp) != 0
 |
 -fun(args, &err) < 0
 +fun(args, errp) < 0
 |
 -fun(args, &err) == NULL
 +fun(args, errp) == NULL
 |
 -fun(args, &err) != NULL
 +fun(args, errp) != NULL
 )
 )
  {
  ... when != err;
  when strict
 -error_propagate(errp, err);
  ...
  }

The first two rules are prone to fail with "error_propagate(...)
... reachable by inconsistent control-flow paths".  Script without
them re-run where that happens.

Manually double-check @err is not used afterwards.  Dereferencing it
would be use after free, but checking whether it's null would be
legitimate.  One such change to qbus_realize() backed out.

Suboptimal line breaks tweaked manually.

Signed-off-by: Markus Armbruster 
---


[..]


diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 8d6156578f..6705220380 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -316,9 +316,8 @@ int ics_set_kvm_state(ICSState *ics, Error **errp)
  continue;
  }


local_err becomes unused in this function, we should drop it

with this fixed:
Reviewed-by: Vladimir Sementsov-Ogievskiy 

  
-ret = ics_set_kvm_state_one(ics, i, &local_err);

+ret = ics_set_kvm_state_one(ics, i, errp);
  if (ret < 0) {
-error_propagate(errp, local_err);
  return ret;
  }
  }


--
Best regards,
Vladimir



Re: [PATCH 1/3] haiku build fix second batch

2020-06-26 Thread Peter Maydell
On Fri, 26 Jun 2020 at 15:10, David CARLIER  wrote:
>
> I sent again minux the ones already approved.

Sorry, I intended that you should send the whole
series, including the ones which I've reviewed.
(Where I gave a reviewed-by tag, include that
tag in the commit message when you resend the patch.)

thanks
-- PMM



Re: [PATCH] migration/block-dirty-bitmap: fix add_bitmaps_to_list

2020-06-26 Thread Eric Blake

On 6/26/20 8:06 AM, Vladimir Sementsov-Ogievskiy wrote:

We shouldn't fail, if found unnamed bitmap in a unnamed node or node


We shouldn't fail when finding an unnamed


with auto-generated node name, as bitmap migration ignores such bitmaps
at all.


such bitmaps in the first place.



Fixes: 82640edb88faa
Fixes: 4ff5cc121b089
Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  migration/block-dirty-bitmap.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)



Reviewed-by: Eric Blake 

Will queue through the bitmaps tree.

Is this easy enough to reproduce that it would be worth having iotest 
coverage?



diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
index 47bc0f650c..b0dbf9eeed 100644
--- a/migration/block-dirty-bitmap.c
+++ b/migration/block-dirty-bitmap.c
@@ -274,7 +274,11 @@ static int add_bitmaps_to_list(BlockDriverState *bs, const 
char *bs_name)
  DirtyBitmapMigBitmapState *dbms;
  Error *local_err = NULL;
  
-bitmap = bdrv_dirty_bitmap_first(bs);

+FOR_EACH_DIRTY_BITMAP(bs, bitmap) {
+if (bdrv_dirty_bitmap_name(bitmap)) {
+break;
+}
+}
  if (!bitmap) {
  return 0;
  }



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




[PATCH v2] scripts/simplebench: compare write request performance

2020-06-26 Thread Andrey Shinkevich
The script 'bench_write_req.py' allows comparing performances of write
request for two qemu-img binary files.
An example with (qemu-img binary 1) and without (qemu-img binary 2) the
applied patch "qcow2: skip writing zero buffers to empty COW areas"
(git commit ID: c8bb23cbdbe32f5)
The  case does not involve the COW optimization.

SSD:
-  ---  ---
 
  2.72 +- 0.00 11.67 +- 1.04
 0.34 +- 0.00 8.64 +- 1.55
   0.33 +- 0.01 8.13 +- 2.05
  8.46 +- 0.06 12.97 +- 1.07
9.27 +- 2.04 8.83 +- 0.84
-  ---  ---
HDD:
-  ---  ---
 
  617.86 +- 6.78   608.84 +- 10.72
 57.53 +- 3.5652.99 +- 7.48
   60.50 +- 1.9256.11 +- 5.20
  12.10 +- 1.1015.16 +- 2.56
6.23 +- 0.05 6.40 +- 0.07
-  ---  ---

Suggested-by: Denis V. Lunev 
Suggested-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Andrey Shinkevich 
---
v2:
  01: Three more test cases added to the script:
  
  
  

 scripts/simplebench/bench_write_req.py | 201 +
 1 file changed, 201 insertions(+)
 create mode 100755 scripts/simplebench/bench_write_req.py

diff --git a/scripts/simplebench/bench_write_req.py 
b/scripts/simplebench/bench_write_req.py
new file mode 100755
index 000..fe92d01
--- /dev/null
+++ b/scripts/simplebench/bench_write_req.py
@@ -0,0 +1,201 @@
+#!/usr/bin/env python3
+#
+# Test to compare performance of write requests for two qemu-img binary files.
+#
+# Copyright (c) 2020 Virtuozzo International GmbH.
+#
+# 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 .
+#
+
+
+import sys
+import os
+import subprocess
+import simplebench
+
+
+def bench_func(env, case):
+""" Handle one "cell" of benchmarking table. """
+return bench_write_req(env['qemu_img'], env['image_name'],
+   case['block_size'], case['block_offset'],
+   case['requests'], case['empty_image'])
+
+
+def qemu_img_pipe(*args):
+'''Run qemu-img and return its output'''
+subp = subprocess.Popen(list(args),
+stdout=subprocess.PIPE,
+stderr=subprocess.STDOUT,
+universal_newlines=True)
+exitcode = subp.wait()
+if exitcode < 0:
+sys.stderr.write('qemu-img received signal %i: %s\n'
+ % (-exitcode, ' '.join(list(args
+return subp.communicate()[0]
+
+
+def bench_write_req(qemu_img, image_name, block_size, block_offset, requests,
+empty_image):
+"""Benchmark write requests
+
+qemu_img -- path to qemu_img executable file
+image_name   -- QCOW2 image name to create
+block_size   -- size of a block to write to clusters
+block_offset -- offset of the block in clusters
+requests -- number of write requests per cluster, customize if zero
+empty_image  -- if True, fill image with random data
+
+Returns {'seconds': int} on success and {'error': str} on failure.
+Return value is compatible with simplebench lib.
+"""
+
+if not os.path.isfile(qemu_img):
+print('File not found: {}'.format(qemu_img))
+sys.exit(1)
+
+image_dir = os.path.dirname(os.path.abspath(image_name))
+if not os.path.isdir(image_dir):
+print('Path not found: {}'.format(image_name))
+sys.exit(1)
+
+cluster_size = 1024 * 1024
+image_size = 1024 * cluster_size
+seek = 4
+dd_count = int(image_size / cluster_size) - seek
+
+args_create = [qemu_img, 'create', '-f', 'qcow2', '-o',
+   'cluster_size={}'.format(cluster_size),
+   image_name, str(image_size)]
+
+if requests:
+count = requests * int(image_size / cluster_size)
+step = str(cluster_size)
+else:
+# Create unaligned write requests
+assert block_size
+shift = int(block_size * 1.01)
+count = int((image_size - block_offset) / shift)
+step = str(shift)
+depth = ['-d', '2']
+
+offset = str(block_offset)
+cnt = str(count)
+size = []
+if block_size:
+size = ['-s', '{}'.format(block_size)]
+
+args

Re: [PATCH QEMU v25 07/17] vfio: Register SaveVMHandlers for VFIO device

2020-06-26 Thread Dr. David Alan Gilbert
* Kirti Wankhede (kwankh...@nvidia.com) wrote:
> Define flags to be used as delimeter in migration file stream.
> Added .save_setup and .save_cleanup functions. Mapped & unmapped migration
> region from these functions at source during saving or pre-copy phase.
> Set VFIO device state depending on VM's state. During live migration, VM is
> running when .save_setup is called, _SAVING | _RUNNING state is set for VFIO
> device. During save-restore, VM is paused, _SAVING state is set for VFIO 
> device.
> 
> Signed-off-by: Kirti Wankhede 
> Reviewed-by: Neo Jia 
> ---
>  hw/vfio/migration.c  | 92 
> 
>  hw/vfio/trace-events |  2 ++
>  2 files changed, 94 insertions(+)
> 
> diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
> index e30bd8768701..133bb5b1b3b2 100644
> --- a/hw/vfio/migration.c
> +++ b/hw/vfio/migration.c
> @@ -8,12 +8,15 @@
>   */
>  
>  #include "qemu/osdep.h"
> +#include "qemu/main-loop.h"
> +#include "qemu/cutils.h"
>  #include 
>  
>  #include "sysemu/runstate.h"
>  #include "hw/vfio/vfio-common.h"
>  #include "cpu.h"
>  #include "migration/migration.h"
> +#include "migration/vmstate.h"
>  #include "migration/qemu-file.h"
>  #include "migration/register.h"
>  #include "migration/blocker.h"
> @@ -24,6 +27,17 @@
>  #include "pci.h"
>  #include "trace.h"
>  
> +/*
> + * Flags used as delimiter:
> + * 0x => MSB 32-bit all 1s
> + * 0xef10 => emulated (virtual) function IO
> + * 0x => 16-bits reserved for flags
> + */
> +#define VFIO_MIG_FLAG_END_OF_STATE  (0xef11ULL)
> +#define VFIO_MIG_FLAG_DEV_CONFIG_STATE  (0xef12ULL)
> +#define VFIO_MIG_FLAG_DEV_SETUP_STATE   (0xef13ULL)
> +#define VFIO_MIG_FLAG_DEV_DATA_STATE(0xef14ULL)
> +
>  static void vfio_migration_region_exit(VFIODevice *vbasedev)
>  {
>  VFIOMigration *migration = vbasedev->migration;
> @@ -126,6 +140,65 @@ static int vfio_migration_set_state(VFIODevice 
> *vbasedev, uint32_t mask,
>  return 0;
>  }
>  
> +/* -- */
> +
> +static int vfio_save_setup(QEMUFile *f, void *opaque)
> +{
> +VFIODevice *vbasedev = opaque;
> +VFIOMigration *migration = vbasedev->migration;
> +int ret;
> +
> +trace_vfio_save_setup(vbasedev->name);
> +
> +qemu_put_be64(f, VFIO_MIG_FLAG_DEV_SETUP_STATE);
> +
> +if (migration->region.mmaps) {
> +qemu_mutex_lock_iothread();
> +ret = vfio_region_mmap(&migration->region);
> +qemu_mutex_unlock_iothread();
> +if (ret) {
> +error_report("%s: Failed to mmap VFIO migration region %d: %s",
> + vbasedev->name, migration->region.nr,
> + strerror(-ret));
> +return ret;
> +}
> +}
> +
> +ret = vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_MASK,
> +   VFIO_DEVICE_STATE_SAVING);
> +if (ret) {
> +error_report("%s: Failed to set state SAVING", vbasedev->name);
> +return ret;
> +}
> +
> +qemu_put_be64(f, VFIO_MIG_FLAG_END_OF_STATE);
> +
> +ret = qemu_file_get_error(f);
> +if (ret) {
> +return ret;
> +}
> +
> +return 0;
> +}
> +
> +static void vfio_save_cleanup(void *opaque)
> +{
> +VFIODevice *vbasedev = opaque;
> +VFIOMigration *migration = vbasedev->migration;
> +
> +if (migration->region.mmaps) {
> +vfio_region_unmap(&migration->region);
> +}
> +trace_vfio_save_cleanup(vbasedev->name);
> +}
> +
> +static SaveVMHandlers savevm_vfio_handlers = {
> +.save_setup = vfio_save_setup,
> +.save_cleanup = vfio_save_cleanup,
> +};
> +
> +/* -- */
> +
>  static void vfio_vmstate_change(void *opaque, int running, RunState state)
>  {
>  VFIODevice *vbasedev = opaque;
> @@ -180,6 +253,7 @@ static int vfio_migration_init(VFIODevice *vbasedev,
> struct vfio_region_info *info)
>  {
>  int ret;
> +char id[256] = "";
>  
>  vbasedev->migration = g_new0(VFIOMigration, 1);
>  
> @@ -192,6 +266,24 @@ static int vfio_migration_init(VFIODevice *vbasedev,
>  return ret;
>  }
>  
> +if (vbasedev->ops->vfio_get_object) {
> +Object *obj = vbasedev->ops->vfio_get_object(vbasedev);
> +
> +if (obj) {
> +DeviceState *dev = DEVICE(obj);
> +char *oid = vmstate_if_get_id(VMSTATE_IF(dev));
> +
> +if (oid) {
> +pstrcpy(id, sizeof(id), oid);
> +pstrcat(id, sizeof(id), "/");
> +g_free(oid);
> +}
> +}
> +}
> +pstrcat(id, sizeof(id), "vfio");
> +
> +register_savevm_live(id, VMSTATE_INSTANCE_ID_ANY, 1, 
> &savevm_vfio_handlers,
> + vbasedev);

Right, so this version has finally changed to using this 'id' string
with a c

Re: [PATCH 5/5] haiku build fix

2020-06-26 Thread Eric Blake

On 6/26/20 7:54 AM, David CARLIER wrote:

From 6fa7a4108236f513201192654e07c7044a3d7e58 Mon Sep 17 00:00:00 2001

From: David Carlier 
Date: Fri, 26 Jun 2020 13:51:37 +
Subject: [PATCH 3/3] qemu_init_exec_dir Haiku implementation


meta-comment: the original subject line says 5/5, while this line says 
3/3, which adds to the confusion of which patches are actually doing 
what, as well as which iteration of the patches we are on.  Also, the 
original subject line "haiku build fix" has been repeated for multiple 
distinct emails; better is to have the subject line come from the patch 
itself (the contents of this line would have been better as the overall 
patch subject).


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




Re: [RFC PATCH 2/3] hw/i2c/smbus_eeprom: Add description based on child name

2020-06-26 Thread Philippe Mathieu-Daudé
On 6/26/20 1:00 PM, BALATON Zoltan wrote:
> On Fri, 26 Jun 2020, Philippe Mathieu-Daudé wrote:
>> Suggested-by: Markus Armbruster 
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
>> hw/i2c/smbus_eeprom.c | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c
>> index 879fd7c416..22ba7b20d4 100644
>> --- a/hw/i2c/smbus_eeprom.c
>> +++ b/hw/i2c/smbus_eeprom.c
>> @@ -47,6 +47,7 @@ typedef struct SMBusEEPROMDevice {
>>     uint8_t *init_data;
>>     uint8_t offset;
>>     bool accessed;
>> +    char *description;
>> } SMBusEEPROMDevice;
>>
>> static uint8_t eeprom_receive_byte(SMBusDevice *dev)
>> @@ -134,7 +135,9 @@ static void smbus_eeprom_realize(DeviceState *dev,
>> Error **errp)
>>     smbus_eeprom_reset(dev);
>>     if (eeprom->init_data == NULL) {
>>     error_setg(errp, "init_data cannot be NULL");
>> +    return;
>>     }
>> +    eeprom->description =
>> object_get_canonical_path_component(OBJECT(dev));
>> }
>>
>> static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
> 
> What is this for? Shouldn't this description field be in some parent
> object and whatever wants to print it could use the
> object_get_canonical_path_component() as default value if it's not set
> instead of adding more boiler plate to every object?

You are right, if we want to use this field generically, it should be
a static Object field. I'll defer that question to Eduardo/Markus.

> 
> Regards,
> BALATON Zoltan



Re: [RFC PATCH 1/3] hw/i2c/smbus_eeprom: Set QOM parent

2020-06-26 Thread BALATON Zoltan

On Fri, 26 Jun 2020, Philippe Mathieu-Daudé wrote:

On 6/26/20 4:03 PM, BALATON Zoltan wrote:

On Fri, 26 Jun 2020, Philippe Mathieu-Daudé wrote:

+ Eduardo / Mark / Edgard / Alistair / Fred for QOM design.

On 6/26/20 12:54 PM, BALATON Zoltan wrote:

On Fri, 26 Jun 2020, BALATON Zoltan wrote:

On Fri, 26 Jun 2020, Philippe Mathieu-Daudé wrote:

Suggested-by: Markus Armbruster 
Signed-off-by: Philippe Mathieu-Daudé 
---
Aspeed change pending latest ARM pull-request, so meanwhile sending
as RFC.
---
include/hw/i2c/smbus_eeprom.h |  9 ++---
hw/i2c/smbus_eeprom.c | 13 ++---
hw/mips/fuloong2e.c   |  2 +-
hw/ppc/sam460ex.c |  2 +-
4 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/include/hw/i2c/smbus_eeprom.h
b/include/hw/i2c/smbus_eeprom.h
index 68b0063ab6..037612 100644
--- a/include/hw/i2c/smbus_eeprom.h
+++ b/include/hw/i2c/smbus_eeprom.h
@@ -26,9 +26,12 @@
#include "exec/cpu-common.h"
#include "hw/i2c/i2c.h"

-void smbus_eeprom_init_one(I2CBus *bus, uint8_t address, uint8_t
*eeprom_buf);
-void smbus_eeprom_init(I2CBus *bus, int nb_eeprom,
-   const uint8_t *eeprom_spd, int size);
+void smbus_eeprom_init_one(Object *parent_obj, const char
*child_name,
+   I2CBus *smbus, uint8_t address,
+   uint8_t *eeprom_buf);
+void smbus_eeprom_init(Object *parent_obj, const char
*child_name_prefix,
+   I2CBus *smbus, int nb_eeprom,
+   const uint8_t *eeprom_spd, int
eeprom_spd_size);


Keeping I2CBus *smbus and uint8_t address as first parameters before
parent_obj and name looks better to me. These functions still operate
on an I2Cbus so could be regarded as methods of I2CBus therefore first
parameter should be that.


Also isn't parent_obj is the I2Cbus itself? Why is that need to be
passed? The i2c_init_bus() also takes parent and name params so both
I2Cbus and it's parent should be available as parents of the new I2C
device here without more parameters. What am I missing here?


This is where I'm confused too and what I want to resolve with this
RFC series :)

The SPD EEPROM is soldered on the DIMM module. The DIMM exposes the
memory address/data pins and the i2c pins. We plug DIMMs on a
(mother)board.

I see the DIMM module being the parent. As we don't model it in QOM,
I used the MemoryRegion (which is what the SPD is describing).

We could represent the DIMM as a container of DRAM + SPD EEPROM, but
it makes the modeling slightly more complex. The only benefit is a
clearer modeling.

I'm not sure why the I2C bus is expected to be the parent. Maybe an
old wrong assumption?


I guess it's a question of what the parent should mean? Is it parent of
the object in which case it's the I2CBus (which is kind of logical view
of the object tree modelling the machine) or the parent of the thing
modelled in the machine (which is physical view of the machine
components) then it should be the RAM module. The confusion probably
comes from this question not answered. Also the DIMM module is not
modelled so when you assign SPD eeproms to memory region it could be
multiple SPD eeproms will be parented by a single RAM memory region
(possibly not covering it fully as in the mac_oldworld or sam460ex case
discussed in another thread). This does not seem too intuitive.


From the bus perspective, requests are sent hoping for a device to
answer to the requested address ("Hello, do I have children? Hello?
Anybody here?"), if nobody is here, the request timeouts.
So there is not really a strong family relationship here.

If you unplug a DIMM, you remove both the MemoryRegion and the EEPROM.
This is how I understand the QOM parent relationship so far (if you
remove a parent, you also remove its children).


OK but what if we don't have a DIMM object as that is not modelled? Should 
you set parent to the board in that case? Or is it still modelled as an 
I2C device that is plugged in an I2C bus. Does it need to have a parent in 
this case at all or is it a case for an unattached device (becuase its 
physical parent is not modelled)?


Regards,
BALATON Zoltan

Re: [PATCH 1/5] haiku build fix

2020-06-26 Thread Eric Blake

On 6/26/20 5:07 AM, David CARLIER wrote:

From 4d0933384d2bfcd0fc8c4c06eed2d07f3f1b7f8b Mon Sep 17 00:00:00 2001

From: David Carlier 
Date: Fri, 26 Jun 2020 10:35:40 +
Subject: [PATCH 1/5] Haiku build fix enabling BSD symbols.

Signed-off-by: David Carlier 
---
  configure | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)


meta-comment: when sending a series, it's best to send a 0/5 cover 
letter with the rest of the messages in-reply-to the cover.  This way, 
it's easier to track the related messages when viewing in a mail reader 
that groups by threads.


More patch submission hints, including how to make 'git send-email' 
automatically create a cover letter when needed, at:

https://wiki.qemu.org/Contribute/SubmitAPatch

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




Re: [PATCH QEMU v25 07/17] vfio: Register SaveVMHandlers for VFIO device

2020-06-26 Thread Dr. David Alan Gilbert
* Alex Williamson (alex.william...@redhat.com) wrote:
> On Wed, 24 Jun 2020 00:51:06 +0530
> Kirti Wankhede  wrote:
> 
> > On 6/23/2020 4:20 AM, Alex Williamson wrote:
> > > On Sun, 21 Jun 2020 01:51:16 +0530
> > > Kirti Wankhede  wrote:
> > >   
> > >> Define flags to be used as delimeter in migration file stream.
> > >> Added .save_setup and .save_cleanup functions. Mapped & unmapped 
> > >> migration
> > >> region from these functions at source during saving or pre-copy phase.
> > >> Set VFIO device state depending on VM's state. During live migration, VM 
> > >> is
> > >> running when .save_setup is called, _SAVING | _RUNNING state is set for 
> > >> VFIO
> > >> device. During save-restore, VM is paused, _SAVING state is set for VFIO 
> > >> device.
> > >>
> > >> Signed-off-by: Kirti Wankhede 
> > >> Reviewed-by: Neo Jia 
> > >> ---
> > >>   hw/vfio/migration.c  | 92 
> > >> 
> > >>   hw/vfio/trace-events |  2 ++
> > >>   2 files changed, 94 insertions(+)
> > >>
> > >> diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
> > >> index e30bd8768701..133bb5b1b3b2 100644
> > >> --- a/hw/vfio/migration.c
> > >> +++ b/hw/vfio/migration.c
> > >> @@ -8,12 +8,15 @@
> > >>*/
> > >>   
> > >>   #include "qemu/osdep.h"
> > >> +#include "qemu/main-loop.h"
> > >> +#include "qemu/cutils.h"
> > >>   #include 
> > >>   
> > >>   #include "sysemu/runstate.h"
> > >>   #include "hw/vfio/vfio-common.h"
> > >>   #include "cpu.h"
> > >>   #include "migration/migration.h"
> > >> +#include "migration/vmstate.h"
> > >>   #include "migration/qemu-file.h"
> > >>   #include "migration/register.h"
> > >>   #include "migration/blocker.h"
> > >> @@ -24,6 +27,17 @@
> > >>   #include "pci.h"
> > >>   #include "trace.h"
> > >>   
> > >> +/*
> > >> + * Flags used as delimiter:
> > >> + * 0x => MSB 32-bit all 1s
> > >> + * 0xef10 => emulated (virtual) function IO
> > >> + * 0x => 16-bits reserved for flags
> > >> + */
> > >> +#define VFIO_MIG_FLAG_END_OF_STATE  (0xef11ULL)
> > >> +#define VFIO_MIG_FLAG_DEV_CONFIG_STATE  (0xef12ULL)
> > >> +#define VFIO_MIG_FLAG_DEV_SETUP_STATE   (0xef13ULL)
> > >> +#define VFIO_MIG_FLAG_DEV_DATA_STATE(0xef14ULL)
> > >> +
> > >>   static void vfio_migration_region_exit(VFIODevice *vbasedev)
> > >>   {
> > >>   VFIOMigration *migration = vbasedev->migration;
> > >> @@ -126,6 +140,65 @@ static int vfio_migration_set_state(VFIODevice 
> > >> *vbasedev, uint32_t mask,
> > >>   return 0;
> > >>   }
> > >>   
> > >> +/* 
> > >> -- */
> > >> +
> > >> +static int vfio_save_setup(QEMUFile *f, void *opaque)
> > >> +{
> > >> +VFIODevice *vbasedev = opaque;
> > >> +VFIOMigration *migration = vbasedev->migration;
> > >> +int ret;
> > >> +
> > >> +trace_vfio_save_setup(vbasedev->name);
> > >> +
> > >> +qemu_put_be64(f, VFIO_MIG_FLAG_DEV_SETUP_STATE);
> > >> +
> > >> +if (migration->region.mmaps) {
> > >> +qemu_mutex_lock_iothread();
> > >> +ret = vfio_region_mmap(&migration->region);
> > >> +qemu_mutex_unlock_iothread();
> > >> +if (ret) {
> > >> +error_report("%s: Failed to mmap VFIO migration region %d: 
> > >> %s",
> > >> + vbasedev->name, migration->region.nr,
> > >> + strerror(-ret));
> > >> +return ret;  
> > > 
> > > OTOH to my previous comments, this shouldn't be fatal, right?  mmaps
> > > are optional anyway so it should be sufficient to push an error report
> > > to explain why this might be slower than normal, but we can still
> > > proceed.
> > >   
> > 
> > Right, defining region to be sparse mmap is optional.
> > migration->region.mmaps is set if vendor driver defines sparse mmapable 
> > regions and VFIO_REGION_INFO_FLAG_MMAP flag is set. If this flag is set 
> > then error on mmap() should be fatal.
> > 
> > If there is not mmapable region, then migration will proceed.
> 
> It's both optional for the vendor to define sparse mmap support (or any
> mmap support) and optional for the user to make use of it.  The user
> can recover from an mmap failure by using read/write accesses.  The
> vendor MUST support this.  It doesn't make sense to worry about
> aborting the VM in replying to comments for 05/17, where it's not clear
> how we proceed, yet intentionally cause a fatal error here when there
> is a very clear path to proceed.
> 
> > >> +}
> > >> +}
> > >> +
> > >> +ret = vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_MASK,
> > >> +   VFIO_DEVICE_STATE_SAVING);
> > >> +if (ret) {
> > >> +error_report("%s: Failed to set state SAVING", vbasedev->name);
> > >> +return ret;
> > >> +}  
> > > 
> > > We seem to be lacking support in the callers for detecting if the
> > > device is in an error state.  I'm

Re: [PATCH v3 1/3] scripts/performance: Add topN_perf.py script

2020-06-26 Thread Ahmed Karaman
On Thu, Jun 25, 2020 at 11:45 AM Aleksandar Markovic
 wrote:
>
> сре, 24. јун 2020. у 17:32 Ahmed Karaman
>  је написао/ла:
> >
> > Syntax:
> > topN_perf.py [-h] [-n]   -- \
> >   [] \
> >   []
> >
> > [-h] - Print the script arguments help message.
> > [-n] - Specify the number of top functions to print.
> >  - If this flag is not specified, the tool defaults to 25.
> >
> > Example of usage:
> > topN_perf.py -n 20 -- qemu-arm coulomb_double-arm
> >
> > Example Output:
> >  No.  Percentage  Name   Caller
> >   --  -  -
> >1  16.25%  float64_mulqemu-x86_64
> >2  12.01%  float64_subqemu-x86_64
> >3  11.99%  float64_addqemu-x86_64
> >4   5.69%  helper_mulsd   qemu-x86_64
> >5   4.68%  helper_addsd   qemu-x86_64
> >6   4.43%  helper_lookup_tb_ptr   qemu-x86_64
> >7   4.28%  helper_subsd   qemu-x86_64
> >8   2.71%  f64_compareqemu-x86_64
> >9   2.71%  helper_ucomisd qemu-x86_64
> >   10   1.04%  helper_pand_xmmqemu-x86_64
> >   11   0.71%  float64_divqemu-x86_64
> >   12   0.63%  helper_pxor_xmmqemu-x86_64
> >   13   0.50%  0x7f7b7004ef95 [JIT] tid 491
> >   14   0.50%  0x7f7b70044e83 [JIT] tid 491
> >   15   0.36%  helper_por_xmm qemu-x86_64
> >   16   0.32%  helper_cc_compute_all  qemu-x86_64
> >   17   0.30%  0x7f7b700433f0 [JIT] tid 491
> >   18   0.30%  float64_compare_quiet  qemu-x86_64
> >   19   0.27%  soft_f64_addsubqemu-x86_64
> >   20   0.26%  round_to_int   qemu-x86_64
> >
> > Signed-off-by: Ahmed Karaman 
> > ---
> >  scripts/performance/topN_perf.py | 142 +++
> >  1 file changed, 142 insertions(+)
> >  create mode 100755 scripts/performance/topN_perf.py
> >
> > diff --git a/scripts/performance/topN_perf.py 
> > b/scripts/performance/topN_perf.py
> > new file mode 100755
> > index 00..d2b939c375
> > --- /dev/null
> > +++ b/scripts/performance/topN_perf.py
> > @@ -0,0 +1,142 @@
> > +#!/usr/bin/env python3
> > +
> > +#  Print the top N most executed functions in QEMU using perf.
> > +#  Syntax:
> > +#  topN_perf.py [-h] [-n]   -- \
> > +#[] \
> > +#[]
> > +#
> > +#  [-h] - Print the script arguments help message.
> > +#  [-n] - Specify the number of top functions to print.
> > +#   - If this flag is not specified, the tool defaults to 25.
> > +#
> > +#  Example of usage:
> > +#  topN_perf.py -n 20 -- qemu-arm coulomb_double-arm
> > +#
> > +#  This file is a part of the project "TCG Continuous Benchmarking".
> > +#
> > +#  Copyright (C) 2020  Ahmed Karaman 
> > +#  Copyright (C) 2020  Aleksandar Markovic 
> > 
> > +#
> > +#  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 .
> > +
> > +import argparse
> > +import os
> > +import subprocess
> > +import sys
> > +
> > +
> > +# Parse the command line arguments
> > +parser = argparse.ArgumentParser(
> > +usage='topN_perf.py [-h] [-n]   -- 
> > '
> > +  ' [] '
> > +  ' []')
> > +
> > +parser.add_argument('-n', dest='top', type=int, default=25,
> > +help='Specify the number of top functions to print.')
> > +
> > +parser.add_argument('command', type=str, nargs='+', help=argparse.SUPPRESS)
> > +
> > +args = parser.parse_args()
> > +
> > +# Extract the needed variables from the args
> > +command = args.command
> > +top = args.top
> > +
> > +# Insure that perf is installed
> > +check_perf = subprocess.run(["which", "perf"], stdout=subprocess.DEVNULL)
> > +if check_perf.returncode:
> > +sys.exit("Please install perf before running the script!")
>
> I would rename "chech_perf" to "check_perf_presence". It is more
> specific, clearer.
>
> > +
> > +# Insure user has previllage to run perf
> > +check_perf_executability = subprocess.run(["perf", "stat", "ls", "/"],
> > +   stdout=subprocess.DEVNULL, 
> > stderr=subprocess.DEVNULL)
> > +if check_perf_executability.returncode:
> > +sys.exit(
> > +"""
> > +Error:
> > +You may not have permission to

Re: [RFC PATCH 1/3] hw/i2c/smbus_eeprom: Set QOM parent

2020-06-26 Thread Philippe Mathieu-Daudé
On 6/26/20 4:03 PM, BALATON Zoltan wrote:
> On Fri, 26 Jun 2020, Philippe Mathieu-Daudé wrote:
>> + Eduardo / Mark / Edgard / Alistair / Fred for QOM design.
>>
>> On 6/26/20 12:54 PM, BALATON Zoltan wrote:
>>> On Fri, 26 Jun 2020, BALATON Zoltan wrote:
 On Fri, 26 Jun 2020, Philippe Mathieu-Daudé wrote:
> Suggested-by: Markus Armbruster 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
> Aspeed change pending latest ARM pull-request, so meanwhile sending
> as RFC.
> ---
> include/hw/i2c/smbus_eeprom.h |  9 ++---
> hw/i2c/smbus_eeprom.c | 13 ++---
> hw/mips/fuloong2e.c   |  2 +-
> hw/ppc/sam460ex.c |  2 +-
> 4 files changed, 18 insertions(+), 8 deletions(-)
>
> diff --git a/include/hw/i2c/smbus_eeprom.h
> b/include/hw/i2c/smbus_eeprom.h
> index 68b0063ab6..037612 100644
> --- a/include/hw/i2c/smbus_eeprom.h
> +++ b/include/hw/i2c/smbus_eeprom.h
> @@ -26,9 +26,12 @@
> #include "exec/cpu-common.h"
> #include "hw/i2c/i2c.h"
>
> -void smbus_eeprom_init_one(I2CBus *bus, uint8_t address, uint8_t
> *eeprom_buf);
> -void smbus_eeprom_init(I2CBus *bus, int nb_eeprom,
> -   const uint8_t *eeprom_spd, int size);
> +void smbus_eeprom_init_one(Object *parent_obj, const char
> *child_name,
> +   I2CBus *smbus, uint8_t address,
> +   uint8_t *eeprom_buf);
> +void smbus_eeprom_init(Object *parent_obj, const char
> *child_name_prefix,
> +   I2CBus *smbus, int nb_eeprom,
> +   const uint8_t *eeprom_spd, int
> eeprom_spd_size);

 Keeping I2CBus *smbus and uint8_t address as first parameters before
 parent_obj and name looks better to me. These functions still operate
 on an I2Cbus so could be regarded as methods of I2CBus therefore first
 parameter should be that.
>>>
>>> Also isn't parent_obj is the I2Cbus itself? Why is that need to be
>>> passed? The i2c_init_bus() also takes parent and name params so both
>>> I2Cbus and it's parent should be available as parents of the new I2C
>>> device here without more parameters. What am I missing here?
>>
>> This is where I'm confused too and what I want to resolve with this
>> RFC series :)
>>
>> The SPD EEPROM is soldered on the DIMM module. The DIMM exposes the
>> memory address/data pins and the i2c pins. We plug DIMMs on a
>> (mother)board.
>>
>> I see the DIMM module being the parent. As we don't model it in QOM,
>> I used the MemoryRegion (which is what the SPD is describing).
>>
>> We could represent the DIMM as a container of DRAM + SPD EEPROM, but
>> it makes the modeling slightly more complex. The only benefit is a
>> clearer modeling.
>>
>> I'm not sure why the I2C bus is expected to be the parent. Maybe an
>> old wrong assumption?
> 
> I guess it's a question of what the parent should mean? Is it parent of
> the object in which case it's the I2CBus (which is kind of logical view
> of the object tree modelling the machine) or the parent of the thing
> modelled in the machine (which is physical view of the machine
> components) then it should be the RAM module. The confusion probably
> comes from this question not answered. Also the DIMM module is not
> modelled so when you assign SPD eeproms to memory region it could be
> multiple SPD eeproms will be parented by a single RAM memory region
> (possibly not covering it fully as in the mac_oldworld or sam460ex case
> discussed in another thread). This does not seem too intuitive.

>From the bus perspective, requests are sent hoping for a device to
answer to the requested address ("Hello, do I have children? Hello?
Anybody here?"), if nobody is here, the request timeouts.
So there is not really a strong family relationship here.

If you unplug a DIMM, you remove both the MemoryRegion and the EEPROM.
This is how I understand the QOM parent relationship so far (if you
remove a parent, you also remove its children).

> 
> Regards,
> BALATON Zoltan



Re: [PATCH QEMU v25 15/17] vfio: Add ioctl to get dirty pages bitmap during dma unmap.

2020-06-26 Thread Dr. David Alan Gilbert
* Alex Williamson (alex.william...@redhat.com) wrote:
> On Thu, 25 Jun 2020 20:31:12 +0530
> Kirti Wankhede  wrote:
> 
> > On 6/25/2020 12:26 AM, Alex Williamson wrote:
> > > On Sun, 21 Jun 2020 01:51:24 +0530
> > > Kirti Wankhede  wrote:
> > >   
> > >> With vIOMMU, IO virtual address range can get unmapped while in pre-copy
> > >> phase of migration. In that case, unmap ioctl should return pages pinned
> > >> in that range and QEMU should find its correcponding guest physical
> > >> addresses and report those dirty.
> > >>
> > >> Suggested-by: Alex Williamson 
> > >> Signed-off-by: Kirti Wankhede 
> > >> Reviewed-by: Neo Jia 
> > >> ---
> > >>   hw/vfio/common.c | 85 
> > >> +---
> > >>   1 file changed, 81 insertions(+), 4 deletions(-)
> > >>
> > >> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > >> index 0518cf228ed5..a06b8f2f66e2 100644
> > >> --- a/hw/vfio/common.c
> > >> +++ b/hw/vfio/common.c
> > >> @@ -311,11 +311,83 @@ static bool 
> > >> vfio_devices_are_stopped_and_saving(void)
> > >>   return true;
> > >>   }
> > >>   
> > >> +static bool vfio_devices_are_running_and_saving(void)
> > >> +{
> > >> +VFIOGroup *group;
> > >> +VFIODevice *vbasedev;
> > >> +
> > >> +QLIST_FOREACH(group, &vfio_group_list, next) {  
> > > 
> > > Same as previous, I'm curious if we should instead be looking at
> > > container granularity.  It especially seems to make sense here where
> > > we're unmapping from a container, so iterating every device in every
> > > group seems excessive.
> > >   
> > 
> > changing it with container argument.
> > 
> > >> +QLIST_FOREACH(vbasedev, &group->device_list, next) {
> > >> +if ((vbasedev->device_state & VFIO_DEVICE_STATE_SAVING) &&
> > >> +(vbasedev->device_state & VFIO_DEVICE_STATE_RUNNING)) {
> > >> +continue;
> > >> +} else {
> > >> +return false;
> > >> +}  
> > > 
> > > I'm also not sure about the polarity of this function, should it be if
> > > any device is _SAVING we should report the dirty bitmap?  For example,
> > > what if we have a set of paried failover NICs where we intend to unplug
> > > one just prior to stopping the devices, aren't we going to lose dirtied
> > > pages with this logic that they all must be running and saving?  Thanks,
> > >   
> > 
> > If migration is initiated, is device unplug allowed? Ideally it 
> > shouldn't. If it is, then how QEMU handles data stream of device which 
> > doesn't exist at destination?
> 
> include/hw/qdev-core.h
> struct DeviceState {
> ...
> bool allow_unplug_during_migration;
> 
> AIUI, the failover_pair_id device is likely to be a vfio-pci NIC,
> otherwise they'd simply migrate the primary NIC, so there's a very good
> chance that a user would configure a VM with a migratable mdev device
> and an failover NIC so that they have high speed networking on either
> end of the migration.

My understanding for that failover code is that happens right at the
beginning of migration while we're still in MIGRATION_STATUS_SETUP;
whether there's anything that enforces that is a different matter.
But, in that case, I don't think you'd be interested in that dirtying.

Dave

> > _SAVING flag is set during pre-copy and stop-and-copy phase. Here we 
> > only want to track pages which are unmapped during pre-copy phase, i.e. 
> > when vCPU are running. In case of VM suspend /saveVM, there is no 
> > pre-copy phase, but ideally we shouldn't see unmaps when vCPUs are 
> > stopped, right? But still for safer side, since we know exact phase, I 
> > would prefer to check for _SAVING and _RUNNING flags.
> 
> We can't have unmaps while vCPUs are stopped, but I think the failover
> code allows that we can be in the pre-copy phase where not all devices
> support migration.  As coded here, it appears that dirty tracking of any
> unmap while in that phase is lost.  Thanks,
> 
> Alex
> 
> 
> > >> +}
> > >> +}
> > >> +return true;
> > >> +}
> > >> +
> > >> +static int vfio_dma_unmap_bitmap(VFIOContainer *container,
> > >> + hwaddr iova, ram_addr_t size,
> > >> + IOMMUTLBEntry *iotlb)
> > >> +{
> > >> +struct vfio_iommu_type1_dma_unmap *unmap;
> > >> +struct vfio_bitmap *bitmap;
> > >> +uint64_t pages = TARGET_PAGE_ALIGN(size) >> TARGET_PAGE_BITS;
> > >> +int ret;
> > >> +
> > >> +unmap = g_malloc0(sizeof(*unmap) + sizeof(*bitmap));
> > >> +
> > >> +unmap->argsz = sizeof(*unmap) + sizeof(*bitmap);
> > >> +unmap->iova = iova;
> > >> +unmap->size = size;
> > >> +unmap->flags |= VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP;
> > >> +bitmap = (struct vfio_bitmap *)&unmap->data;
> > >> +
> > >> +/*
> > >> + * cpu_physical_memory_set_dirty_lebitmap() expects pages in bitmap 
> > >> of
> > >> + * TARGET_PAGE_SIZE to mark those dirty. Hence set bitmap_pgsize to
> > >> +  

Re: [PATCH 1/3] haiku build fix second batch

2020-06-26 Thread David CARLIER
I sent again minux the ones already approved.

On Fri, 26 Jun 2020 at 14:39, Peter Maydell  wrote:
>
> On Fri, 26 Jun 2020 at 14:02, David CARLIER  wrote:
> >
> > From 95ef79ddff73eebd1f1bec6673c2c68209fab107 Mon Sep 17 00:00:00 2001
> > From: David Carlier 
> > Date: Fri, 26 Jun 2020 13:56:14 +
> > Subject: [PATCH 1/3] Include endian.h for Haiku to solve bswap* macros build
> >  failure.
> >
> > Signed-off-by: David Carlier 
>
> I'm afraid I'm now confused about which is the right version
> of the various patches you've sent to the list. Our
> https://wiki.qemu.org/Contribute/SubmitAPatch
> documentation asks:
>  * Include a meaningful cover letter
>  * When resending patches add a version tag
>  * even if you only change one patch, you resend the entire series
>and mark it as "v2"
>
> Please could you send the whole set of patches you'd like
> applied, with the subject header including "[PATCH v2]" and
> with a cover letter email that describes the whole series?
>
> thanks
> -- PMM



Re: [PATCH] timer: Handle decrements of PIT counter

2020-06-26 Thread Kevin O'Connor
On Fri, Jun 26, 2020 at 04:09:57PM +0300, Roman Bolshakov wrote:
> On Tue, Jun 23, 2020 at 11:00:24PM -0400, Kevin O'Connor wrote:
> > Good catch.  Could we fix it using the patch below instead though?
> > 
> > -Kevin
> > 
> > 
> > --- a/src/hw/timer.c
> > +++ b/src/hw/timer.c
> > @@ -180,7 +180,7 @@ timer_read(void)
> >  // Read from PIT.
> >  outb(PM_SEL_READBACK | PM_READ_VALUE | PM_READ_COUNTER0, 
> > PORT_PIT_MODE);
> >  u16 v = inb(PORT_PIT_COUNTER0) | (inb(PORT_PIT_COUNTER0) << 8);
> > -return timer_adjust_bits(v, 0x);
> > +return timer_adjust_bits(-v, 0x);
> >  }
> >  
> >  // Return the TSC value that is 'msecs' time in the future.
> 
> Hi Kevin,
> 
> I like the approach much more. Initial count value is 0, PIT rearms the
> timer when 1 is hit, unary negation on unsigned u16 fits perfectly, then
> timer_adjust_bits recieves 0, 1, 2, ... and timer is rearmed at 0x.
> 
> Do you want me to send v2 or you plan to apply the fix on your own?

I'm fine with either.

Thanks,
-Kevin



[PATCH 3/3] syscall skipped for haiku used only in qemu_signalfd anyway

2020-06-26 Thread David CARLIER
>From a548479cab82200d9df33a70f24aeebb00eb70ad Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 13:58:34 +
Subject: [PATCH 3/3] syscall skipped for haiku used only in qemu_signalfd
 anyway

Signed-off-by: David Carlier 
---
 util/compatfd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/util/compatfd.c b/util/compatfd.c
index c296f55d14..ee47dd8089 100644
--- a/util/compatfd.c
+++ b/util/compatfd.c
@@ -16,7 +16,9 @@
 #include "qemu/osdep.h"
 #include "qemu/thread.h"

+#if defined(CONFIG_SIGNALFD)
 #include 
+#endif

 struct sigfd_compat_info
 {
-- 
2.26.0



[PATCH 2/3] drm build ignored for Haiku.

2020-06-26 Thread David CARLIER
>From 338a25285d945c891eb4fa34a18cb45b8b05dbb1 Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 13:57:08 +
Subject: [PATCH 2/3] drm build ignored for Haiku.

Signed-off-by: David Carlier 
---
 util/Makefile.objs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/util/Makefile.objs b/util/Makefile.objs
index cc5e37177a..faebc13fac 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -39,7 +39,7 @@ util-obj-y += qsp.o
 util-obj-y += range.o
 util-obj-y += stats64.o
 util-obj-y += systemd.o
-util-obj-$(CONFIG_POSIX) += drm.o
+util-obj-$(CONFIG_LINUX) += drm.o
 util-obj-y += guest-random.o
 util-obj-$(CONFIG_GIO) += dbus.o
 dbus.o-cflags = $(GIO_CFLAGS)
-- 
2.26.0



Re: [PATCH 2/3] define SIGIO for haiku

2020-06-26 Thread Philippe Mathieu-Daudé
Maybe "Define SIGIO on Haiku OS" as patch subject...

On 6/26/20 4:03 PM, David CARLIER wrote:
> From d36aba6190152c626f668fef3704ee6b61bfc323 Mon Sep 17 00:00:00 2001
> From: David Carlier 
> Date: Fri, 26 Jun 2020 13:45:04 +
> Subject: [PATCH 2/3] define SIGIO for haiku
> 
> Signed-off-by: David Carlier 
> ---
>  include/qemu/osdep.h | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> index f88fe23936..860bb3c16c 100644
> --- a/include/qemu/osdep.h
> +++ b/include/qemu/osdep.h
> @@ -388,6 +388,10 @@ void qemu_anon_ram_free(void *ptr, size_t size);
>  #define HAVE_CHARDEV_PARPORT 1
>  #endif
> 
> +#if defined(__HAIKU__)

Maybe safer as:

   #if defined(__HAIKU__) && !defined(SIGIO)

> +#define SIGIO SIGPOLL
> +#endif
> +
>  #if defined(CONFIG_LINUX)
>  #ifndef BUS_MCEERR_AR
>  #define BUS_MCEERR_AR 4
> 

Preferably with the suggested changes:
Reviewed-by: Philippe Mathieu-Daudé 




[PATCH 1/3] Include endian.h for Haiku to solve bswap* macros build

2020-06-26 Thread David CARLIER
>From 95ef79ddff73eebd1f1bec6673c2c68209fab107 Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 13:56:14 +
Subject: [PATCH 1/3] Include endian.h for Haiku to solve bswap* macros build
 failure.

Signed-off-by: David Carlier 
---
 include/qemu/bswap.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 2a9f3fe783..1d3e4c24e4 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -8,6 +8,8 @@
 # include 
 #elif defined(__FreeBSD__)
 # include 
+#elif defined(__HAIKU__)
+# include 
 #elif defined(CONFIG_BYTESWAP_H)
 # include 

-- 
2.26.0



[PATCH 0/3] second batch of haiku build fix

2020-06-26 Thread David CARLIER
>From a548479cab82200d9df33a70f24aeebb00eb70ad Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 15:04:30 +
Subject: [PATCH 0/3] second batch of haiku build fix

David Carlier (3):
  Include endian.h for Haiku to solve bswap* macros build failure.
  drm build ignored for Haiku.
  syscall skipped for haiku used only in qemu_signalfd anyway

 include/qemu/bswap.h | 2 ++
 util/Makefile.objs   | 2 +-
 util/compatfd.c  | 2 ++
 3 files changed, 5 insertions(+), 1 deletion(-)

-- 
2.26.0



Re: [PATCH] MAINTAINERS: Add an entry for OpenSBI firmware

2020-06-26 Thread Philippe Mathieu-Daudé
On 6/26/20 3:13 PM, Bin Meng wrote:
> List me as the maintainer for OpenSBI firmware related files.
> 
> Signed-off-by: Bin Meng 
> ---
> 
>  MAINTAINERS | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1b40446..b0e2dd2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2609,6 +2609,13 @@ F: tests/uefi-test-tools/
>  F: .gitlab-ci.d/edk2.yml
>  F: .gitlab-ci.d/edk2/
>  
> +OpenSBI Firmware
> +M: Bin Meng 
> +S: Supported
> +F: pc-bios/opensbi-*
> +F: .gitlab-ci.d/opensbi.yml
> +F: .gitlab-ci.d/opensbi/

Or simply:

   F: .gitlab-ci.d/opensbi*

Reviewed-by: Philippe Mathieu-Daudé 

> +
>  Usermode Emulation
>  --
>  Overall usermode emulation
> 




Re: [REPORT] [GSoC - TCG Continuous Benchmarking] [#1] Measuring Basic Performance Metrics of QEMU

2020-06-26 Thread Ahmed Karaman
On Thu, Jun 25, 2020 at 3:38 PM Aleksandar Markovic
 wrote:
>
> In introductory section on Callgrind, maybe you could add the general
> form of command line that performs profiling using Callgrind,
> something like this:
>
> valgrind --tool=callgrind [callgrind options] prog [prog options]
>
> Not a big deal, you can do some fine adjustments throughout the project.
>
> Thanks,
> Aleksandar
>

Thanks for the tip, Mr. Aleksandar. I've added it to the report.

Regards,
Ahmed Karaman



[PATCH 3/3] qemu_init_exec_dir Haiku implementation

2020-06-26 Thread David CARLIER
>From 6fa7a4108236f513201192654e07c7044a3d7e58 Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 13:51:37 +
Subject: [PATCH 3/3] qemu_init_exec_dir Haiku implementation

Signed-off-by: David Carlier 
---
 util/oslib-posix.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 7ad9195c44..459e3f8093 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -60,6 +60,10 @@
 #include 
 #endif

+#ifdef __HAIKU__
+#include 
+#endif
+
 #include "qemu/mmap-alloc.h"

 #ifdef CONFIG_DEBUG_STACK_USAGE
@@ -389,6 +393,21 @@ void qemu_init_exec_dir(const char *argv0)
 }
 }
 }
+#elif defined(__HAIKU__)
+{
+image_info ii;
+int32_t c = 0;
+
+*buf = '\0';
+while (get_next_image_info(0, &c, &ii) == B_OK) {
+if (ii.type == B_APP_IMAGE) {
+strncpy(buf, ii.name, sizeof(buf));
+buf[sizeof(buf) - 1] = 0;
+p = buf;
+break;
+}
+}
+}
 #endif
 /* If we don't have any way of figuring out the actual executable
location then try argv[0].  */
-- 
2.26.0



Re: [RFC PATCH 1/3] hw/i2c/smbus_eeprom: Set QOM parent

2020-06-26 Thread BALATON Zoltan

On Fri, 26 Jun 2020, Philippe Mathieu-Daudé wrote:

+ Eduardo / Mark / Edgard / Alistair / Fred for QOM design.

On 6/26/20 12:54 PM, BALATON Zoltan wrote:

On Fri, 26 Jun 2020, BALATON Zoltan wrote:

On Fri, 26 Jun 2020, Philippe Mathieu-Daudé wrote:

Suggested-by: Markus Armbruster 
Signed-off-by: Philippe Mathieu-Daudé 
---
Aspeed change pending latest ARM pull-request, so meanwhile sending
as RFC.
---
include/hw/i2c/smbus_eeprom.h |  9 ++---
hw/i2c/smbus_eeprom.c | 13 ++---
hw/mips/fuloong2e.c   |  2 +-
hw/ppc/sam460ex.c |  2 +-
4 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/include/hw/i2c/smbus_eeprom.h
b/include/hw/i2c/smbus_eeprom.h
index 68b0063ab6..037612 100644
--- a/include/hw/i2c/smbus_eeprom.h
+++ b/include/hw/i2c/smbus_eeprom.h
@@ -26,9 +26,12 @@
#include "exec/cpu-common.h"
#include "hw/i2c/i2c.h"

-void smbus_eeprom_init_one(I2CBus *bus, uint8_t address, uint8_t
*eeprom_buf);
-void smbus_eeprom_init(I2CBus *bus, int nb_eeprom,
-   const uint8_t *eeprom_spd, int size);
+void smbus_eeprom_init_one(Object *parent_obj, const char *child_name,
+   I2CBus *smbus, uint8_t address,
+   uint8_t *eeprom_buf);
+void smbus_eeprom_init(Object *parent_obj, const char
*child_name_prefix,
+   I2CBus *smbus, int nb_eeprom,
+   const uint8_t *eeprom_spd, int eeprom_spd_size);


Keeping I2CBus *smbus and uint8_t address as first parameters before
parent_obj and name looks better to me. These functions still operate
on an I2Cbus so could be regarded as methods of I2CBus therefore first
parameter should be that.


Also isn't parent_obj is the I2Cbus itself? Why is that need to be
passed? The i2c_init_bus() also takes parent and name params so both
I2Cbus and it's parent should be available as parents of the new I2C
device here without more parameters. What am I missing here?


This is where I'm confused too and what I want to resolve with this
RFC series :)

The SPD EEPROM is soldered on the DIMM module. The DIMM exposes the
memory address/data pins and the i2c pins. We plug DIMMs on a
(mother)board.

I see the DIMM module being the parent. As we don't model it in QOM,
I used the MemoryRegion (which is what the SPD is describing).

We could represent the DIMM as a container of DRAM + SPD EEPROM, but
it makes the modeling slightly more complex. The only benefit is a
clearer modeling.

I'm not sure why the I2C bus is expected to be the parent. Maybe an
old wrong assumption?


I guess it's a question of what the parent should mean? Is it parent of 
the object in which case it's the I2CBus (which is kind of logical view of 
the object tree modelling the machine) or the parent of the thing modelled 
in the machine (which is physical view of the machine components) then it 
should be the RAM module. The confusion probably comes from this question 
not answered. Also the DIMM module is not modelled so when you assign SPD 
eeproms to memory region it could be multiple SPD eeproms will be parented 
by a single RAM memory region (possibly not covering it fully as in the 
mac_oldworld or sam460ex case discussed in another thread). This does not 
seem too intuitive.


Regards,
BALATON Zoltan

[PATCH 2/3] define SIGIO for haiku

2020-06-26 Thread David CARLIER
>From d36aba6190152c626f668fef3704ee6b61bfc323 Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 13:45:04 +
Subject: [PATCH 2/3] define SIGIO for haiku

Signed-off-by: David Carlier 
---
 include/qemu/osdep.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index f88fe23936..860bb3c16c 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -388,6 +388,10 @@ void qemu_anon_ram_free(void *ptr, size_t size);
 #define HAVE_CHARDEV_PARPORT 1
 #endif

+#if defined(__HAIKU__)
+#define SIGIO SIGPOLL
+#endif
+
 #if defined(CONFIG_LINUX)
 #ifndef BUS_MCEERR_AR
 #define BUS_MCEERR_AR 4
-- 
2.26.0



[PATCH 1/3] : haiku check sys signal.h presence

2020-06-26 Thread David CARLIER
>From a4dfa918e6eea7a5ccc4375d83d1f0162e3bb122 Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 13:43:59 +
Subject: [PATCH 1/3] check sys/signal.h presence

Signed-off-by: David Carlier 
---
 configure   | 8 
 hw/xen/xen-legacy-backend.c | 1 -
 include/qemu/osdep.h| 2 +-
 util/oslib-posix.c  | 1 -
 4 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index ba88fd1824..5101fd79fd 100755
--- a/configure
+++ b/configure
@@ -3181,6 +3181,11 @@ if ! check_include "ifaddrs.h" ; then
   have_ifaddrs_h=no
 fi

+have_sys_signal_h=no
+if check_include "sys/signal.h" ; then
+  have_sys_signal_h=yes
+fi
+
 ##
 # VTE probe

@@ -7286,6 +7291,9 @@ fi
 if test "$have_broken_size_max" = "yes" ; then
 echo "HAVE_BROKEN_SIZE_MAX=y" >> $config_host_mak
 fi
+if test "$have_sys_signal_h" = "yes" ; then
+echo "CONFIG_SYS_SIGNAL=y" >> $config_host_mak
+fi

 # Work around a system header bug with some kernel/XFS header
 # versions where they both try to define 'struct fsxattr':
diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c
index 2335ee2e65..92f08fca29 100644
--- a/hw/xen/xen-legacy-backend.c
+++ b/hw/xen/xen-legacy-backend.c
@@ -23,7 +23,6 @@
  */

 #include "qemu/osdep.h"
-#include 

 #include "hw/sysbus.h"
 #include "hw/boards.h"
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index ff7c17b857..f88fe23936 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -104,7 +104,7 @@ extern int daemon(int, int);
 #include 
 #include 

-#ifdef __OpenBSD__
+#ifdef CONFIG_SYS_SIGNAL
 #include 
 #endif

diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 39ddc77c85..7ad9195c44 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -38,7 +38,6 @@
 #include "qemu/sockets.h"
 #include "qemu/thread.h"
 #include 
-#include 
 #include "qemu/cutils.h"

 #ifdef CONFIG_LINUX
-- 
2.26.0



Re: [PATCH 01/17] block/nvme: Avoid further processing if trace event not enabled

2020-06-26 Thread Philippe Mathieu-Daudé
On 6/26/20 12:36 PM, Stefan Hajnoczi wrote:
> On Thu, Jun 25, 2020 at 08:48:22PM +0200, Philippe Mathieu-Daudé wrote:
>> Avoid further processing if TRACE_NVME_SUBMIT_COMMAND_RAW is
>> not enabled.
> 
> Why?
> 
> This saves 8 trace events, each with 8 arguments. I guess the intent is
> to improve performance. Did you measure an improvement?

No testing, I just tried to outsmart the compiler :/




[PATCH v2 0/3] following up haiku build fix

2020-06-26 Thread David CARLIER
>From 6fa7a4108236f513201192654e07c7044a3d7e58 Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 14:48:28 +
Subject: [PATCH 0/3] following up haiku build fix

David Carlier (3):
  check sys/signal.h presence
  define SIGIO for haiku
  qemu_init_exec_dir Haiku implementation

 configure   |  8 
 hw/xen/xen-legacy-backend.c |  1 -
 include/qemu/osdep.h|  6 +-
 util/oslib-posix.c  | 20 +++-
 4 files changed, 32 insertions(+), 3 deletions(-)

-- 
2.26.0



QEMU | Pipeline #160473765 has failed for master | 10f7ffab

2020-06-26 Thread GitLab via


Your pipeline has failed.

Project: QEMU ( https://gitlab.com/qemu-project/qemu )
Branch: master ( https://gitlab.com/qemu-project/qemu/-/commits/master )

Commit: 10f7ffab ( 
https://gitlab.com/qemu-project/qemu/-/commit/10f7ffabf9c507fc02382b89912003b1c43c3231
 )
Commit Message: Merge remote-tracking branch 'remotes/mcayland/...
Commit Author: Peter Maydell ( https://gitlab.com/pm215 )

Pipeline #160473765 ( 
https://gitlab.com/qemu-project/qemu/-/pipelines/160473765 ) triggered by Alex 
Bennée ( https://gitlab.com/stsquad )
had 2 failed builds.

Job #613138921 ( https://gitlab.com/qemu-project/qemu/-/jobs/613138921/raw )

Stage: test
Name: build-disabled
Trace: qemu-system-i386: falling back to tcg
Could not access KVM kernel module: No such file or directory
qemu-system-i386: -accel kvm: failed to initialize kvm: No such file or 
directory
qemu-system-i386: falling back to tcg
Could not access KVM kernel module: No such file or directory
qemu-system-i386: -accel kvm: failed to initialize kvm: No such file or 
directory
qemu-system-i386: falling back to tcg
  TESTcheck-qtest-i386: tests/qtest/device-introspect-test
  TESTcheck-qtest-i386: tests/qtest/machine-none-test
  TESTcheck-qtest-i386: tests/qtest/qmp-test
  TESTcheck-qtest-i386: tests/qtest/qmp-cmd-test
  TESTcheck-qtest-i386: tests/qtest/qom-test
  TESTcheck-qtest-i386: tests/qtest/test-hmp
  TESTcheck-qtest-i386: tests/qtest/qos-test
  TESTcheck-qtest-mips64: tests/qtest/endianness-test
  TESTcheck-qtest-mips64: tests/qtest/display-vga-test
  TESTcheck-qtest-mips64: tests/qtest/cdrom-test
  TESTcheck-qtest-mips64: tests/qtest/device-introspect-test
  TESTcheck-qtest-mips64: tests/qtest/machine-none-test
  TESTcheck-qtest-mips64: tests/qtest/qmp-test
  TESTcheck-qtest-mips64: tests/qtest/qmp-cmd-test
  TESTcheck-qtest-mips64: tests/qtest/qom-test
  TESTcheck-qtest-mips64: tests/qtest/test-hmp
  TESTcheck-qtest-mips64: tests/qtest/qos-test
  TESTcheck-qtest-ppc64: tests/qtest/machine-none-test
  TESTcheck-qtest-ppc64: tests/qtest/qmp-test
  TESTcheck-qtest-ppc64: tests/qtest/qmp-cmd-test
  TESTcheck-qtest-ppc64: tests/qtest/qom-test
section_end:1593179952:step_script
ERROR: Job failed: execution took longer than 1h0m0s seconds


Job #613138923 ( https://gitlab.com/qemu-project/qemu/-/jobs/613138923/raw )

Stage: test
Name: build-tcg-disabled
Trace: 208  ...[13:21:51] ...  
208  pass   [13:21:51] [13:21:52]   1s   
209  ...[13:21:52] ...  
209  pass   [13:21:52] [13:21:52]   0s   
215  ...[13:21:52] ...  
215  pass   [13:21:52] [13:23:43]  111s   
216  ...[13:23:43] ...  
216  pass   [13:23:43] [13:23:48]   5s   
218  ...[13:23:48] ...  
218  pass   [13:23:48] [13:23:50]   2s   
222  ...[13:23:50] ...  
222  pass   [13:23:50] [13:23:50]   0s   
227  ...[13:23:50] ...  
227  pass   [13:23:50] [13:23:51]   1s   
234  ...[13:23:51] ...  
234  pass   [13:23:51] [13:23:52]   1s   
246  ...[13:23:52] ...  
246  pass   [13:23:52] [13:23:53]   1s   
247  ...[13:23:53] ...  
247  pass   [13:23:53] [13:23:54]   1s   
248  ...[13:23:54] ...  
248  pass   [13:23:54] [13:23:55]   1s   
250  ...[13:23:55] ...  
250  pass   [13:23:55] [13:23:55]   0s   
254  ...[13:23:55] ...  
254  pass   [13:23:55] [13:23:55]   0s   
255  ...[13:23:55] ...  
255  pass   [13:23:55] [13:23:57]   2s   
257  ...[13:23:57] ...  
257  pass   [13:23:57] [13:24:12]  15s   
258  ...[13:24:12] ...  
258  pass   [13:24:12] [13:24:12]   0s   
260  ...[13:24:12] ...  
260  pass   [13:24:12] [13:24:13]   1s   
261  ...[13:24:13] ...  
261  pass   [13:24:13] [13:24:39]  26s   
262  ...[13:24:39] ...  
262  pass   [13:24:39] [13:24:39]   0s   
263  ...[13:24:39]

Re: [PATCH RESEND 5/9] hw/arm/smmuv3: Store the starting level in SMMUTransTableInfo

2020-06-26 Thread Auger Eric
Hi Peter,

On 6/25/20 5:15 PM, Peter Maydell wrote:
> On Thu, 11 Jun 2020 at 17:15, Eric Auger  wrote:
>>
>> Compute the starting level on CD decoding and store it
>> into SMMUTransTableInfo. We will need this information
>> on IOTLB lookup so let's avoid to recompute it each time.
>>
>> Signed-off-by: Eric Auger 
> 
>> --- a/hw/arm/smmu-common.c
>> +++ b/hw/arm/smmu-common.c
>> @@ -224,7 +224,7 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
>>  granule_sz = tt->granule_sz;
>>  stride = granule_sz - 3;
>>  inputsize = 64 - tt->tsz;
>> -level = 4 - (inputsize - 4) / stride;
>> +level = tt->starting_level;
> 
> "4 - (x - 4) / y" doesn't really seem like it's complicated
> enough to be worth caching given everything else we do on
> a page table walk. Do you have perf figures to indicate that
> this change is worthwhile?

no I don't have any figure or any setup at the moment to perform that
bench.

I thought it could only help, was not complicated to store and was of
the same kind as the granule size, the input range, ... already stored
in SMMUTransTableInfo.

Thanks

Eric
> 
> thanks
> -- PMM
> 




[PULL v2 09/31] exec: fetch the alignment of Linux devdax pmem character device nodes

2020-06-26 Thread Paolo Bonzini
From: Jingqi Liu 

If the backend file is devdax pmem character device, the alignment
specified by the option 'align=NUM' in the '-object memory-backend-file'
needs to match the alignment requirement of the devdax pmem character device.

This patch uses the interfaces of libdaxctl to fetch the devdax pmem file
'align', so that we can compare it with the NUM of 'align=NUM'.
The NUM needs to be larger than or equal to the devdax pmem file 'align'.

It also fixes the problem that mmap() returns failure in qemu_ram_mmap()
when the NUM of 'align=NUM' is less than the devdax pmem file 'align'.

Suggested-by: Dan Williams 
Reviewed-by: Joao Martins 
Signed-off-by: Jingqi Liu 
Message-Id: <20200429085011.63752-2-jingqi@intel.com>
Signed-off-by: Paolo Bonzini 
---
 exec.c | 54 +-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/exec.c b/exec.c
index d6712fba7e..21926dc9c7 100644
--- a/exec.c
+++ b/exec.c
@@ -77,6 +77,10 @@
 
 #include "monitor/monitor.h"
 
+#ifdef CONFIG_LIBDAXCTL
+#include 
+#endif
+
 //#define DEBUG_SUBPAGE
 
 #if !defined(CONFIG_USER_ONLY)
@@ -1745,6 +1749,46 @@ static int64_t get_file_size(int fd)
 return size;
 }
 
+static int64_t get_file_align(int fd)
+{
+int64_t align = -1;
+#if defined(__linux__) && defined(CONFIG_LIBDAXCTL)
+struct stat st;
+
+if (fstat(fd, &st) < 0) {
+return -errno;
+}
+
+/* Special handling for devdax character devices */
+if (S_ISCHR(st.st_mode)) {
+g_autofree char *path = NULL;
+g_autofree char *rpath = NULL;
+struct daxctl_ctx *ctx;
+struct daxctl_region *region;
+int rc = 0;
+
+path = g_strdup_printf("/sys/dev/char/%d:%d",
+major(st.st_rdev), minor(st.st_rdev));
+rpath = realpath(path, NULL);
+
+rc = daxctl_new(&ctx);
+if (rc) {
+return -1;
+}
+
+daxctl_region_foreach(ctx, region) {
+if (strstr(rpath, daxctl_region_get_path(region))) {
+align = daxctl_region_get_align(region);
+break;
+}
+}
+daxctl_unref(ctx);
+}
+#endif /* defined(__linux__) && defined(CONFIG_LIBDAXCTL) */
+
+return align;
+}
+
 static int file_ram_open(const char *path,
  const char *region_name,
  bool *created,
@@ -2296,7 +2340,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, 
MemoryRegion *mr,
 {
 RAMBlock *new_block;
 Error *local_err = NULL;
-int64_t file_size;
+int64_t file_size, file_align;
 
 /* Just support these ram flags by now. */
 assert((ram_flags & ~(RAM_SHARED | RAM_PMEM)) == 0);
@@ -2332,6 +2376,14 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, 
MemoryRegion *mr,
 return NULL;
 }
 
+file_align = get_file_align(fd);
+if (file_align > 0 && mr && file_align > mr->align) {
+error_setg(errp, "backing store align 0x%" PRIx64
+   " is larger than 'align' option 0x%" PRIx64,
+   file_align, mr->align);
+return NULL;
+}
+
 new_block = g_malloc0(sizeof(*new_block));
 new_block->mr = mr;
 new_block->used_length = size;
-- 
2.26.2





[PULL v2 25/31] osdep: Make MIN/MAX evaluate arguments only once

2020-06-26 Thread Paolo Bonzini
From: Eric Blake 

I'm not aware of any immediate bugs in qemu where a second runtime
evaluation of the arguments to MIN() or MAX() causes a problem, but
proactively preventing such abuse is easier than falling prey to an
unintended case down the road.  At any rate, here's the conversation
that sparked the current patch:
https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg05718.html

Update the MIN/MAX macros to only evaluate their argument once at
runtime; this uses typeof(1 ? (a) : (b)) to ensure that we are
promoting the temporaries to the same type as the final comparison (we
have to trigger type promotion, as typeof(bitfield) won't compile; and
we can't use typeof((a) + (b)) or even typeof((a) + 0), as some of our
uses of MAX are on void* pointers where such addition is undefined).

However, we are unable to work around gcc refusing to compile ({}) in
a constant context (such as the array length of a static variable),
even when only used in the dead branch of a __builtin_choose_expr(),
so we have to provide a second macro pair MIN_CONST and MAX_CONST for
use when both arguments are known to be compile-time constants and
where the result must also be usable as a constant; this second form
evaluates arguments multiple times but that doesn't matter for
constants.  By using a void expression as the expansion if a
non-constant is presented to this second form, we can enlist the
compiler to ensure the double evaluation is not attempted on
non-constants.

Alas, as both macros now rely on compiler intrinsics, they are no
longer usable in preprocessor #if conditions; those will just have to
be open-coded or the logic rewritten into #define or runtime 'if'
conditions (but where the compiler dead-code-elimination will probably
still apply).

I tested that both gcc 10.1.1 and clang 10.0.0 produce errors for all
forms of macro mis-use.  As the errors can sometimes be cryptic, I'm
demonstrating the gcc output:

Use of MIN when MIN_CONST is needed:

In file included from /home/eblake/qemu/qemu-img.c:25:
/home/eblake/qemu/include/qemu/osdep.h:249:5: error: braced-group within 
expression allowed only inside a function
  249 | ({  \
  | ^
/home/eblake/qemu/qemu-img.c:92:12: note: in expansion of macro ‘MIN’
   92 | char array[MIN(1, 2)] = "";
  |^~~

Use of MIN_CONST when MIN is needed:

/home/eblake/qemu/qemu-img.c: In function ‘is_allocated_sectors’:
/home/eblake/qemu/qemu-img.c:1225:15: error: void value not ignored as it ought 
to be
 1225 | i = MIN_CONST(i, n);
  |   ^

Use of MIN in the preprocessor:

In file included from /home/eblake/qemu/accel/tcg/translate-all.c:20:
/home/eblake/qemu/accel/tcg/translate-all.c: In function ‘page_check_range’:
/home/eblake/qemu/include/qemu/osdep.h:249:6: error: token "{" is not valid in 
preprocessor expressions
  249 | ({  \
  |  ^

Fix the resulting callsites that used #if or computed a compile-time
constant min or max to use the new macros.  cpu-defs.h is interesting,
as CPU_TLB_DYN_MAX_BITS is sometimes used as a constant and sometimes
dynamic.

It may be worth improving glib's MIN/MAX definitions to be saner, but
that is a task for another day.

Signed-off-by: Eric Blake 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20200625162602.700741-1-ebl...@redhat.com>
Signed-off-by: Paolo Bonzini 
---
 accel/tcg/translate-all.c |  6 ++---
 hw/usb/hcd-xhci.h |  2 +-
 include/block/block.h |  4 +--
 include/exec/cpu-all.h|  8 +++---
 include/exec/cpu-defs.h   |  7 -
 include/qemu/osdep.h  | 57 ---
 migration/qemu-file.c |  2 +-
 7 files changed, 63 insertions(+), 23 deletions(-)

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index c3d37058a1..2afa46bd2b 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -2582,9 +2582,9 @@ int page_check_range(target_ulong start, target_ulong 
len, int flags)
 /* This function should never be called with addresses outside the
guest address space.  If this assert fires, it probably indicates
a missing call to h2g_valid.  */
-#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
-assert(start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
-#endif
+if (TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS) {
+assert(start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
+}
 
 if (len == 0) {
 return 0;
diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h
index 2fad4df2a7..946af51fc2 100644
--- a/hw/usb/hcd-xhci.h
+++ b/hw/usb/hcd-xhci.h
@@ -214,7 +214,7 @@ struct XHCIState {
 uint32_t dcbaap_high;
 uint32_t config;
 
-USBPort  uports[MAX(MAXPORTS_2, MAXPORTS_3)];
+USBPort  uports[MAX_CONST(MAXPORTS_2, MAXPORTS_3)];
 XHCIPort ports[MAXPORTS];
 XHCISlot slots[MAXSLOTS];
 uint32_t numports;

[PULL v2 00/31] Misc patches for 2020-06-24

2020-06-26 Thread Paolo Bonzini
The following changes since commit 5acc270a355120ce967ca1f1eeca0abbdb9303c8:

  Merge remote-tracking branch 'remotes/xtensa/tags/20200625-xtensa' into 
staging (2020-06-25 21:20:45 +0100)

are available in the Git repository at:

  git://github.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to 730319aef0fcb94f11a4a2d32656437fdde7efdd:

  i386: Mask SVM features if nested SVM is disabled (2020-06-26 09:39:40 -0400)


* Various fixes
* libdaxctl support to correctly align devdax character devices (Jingqi)
* initial-all-set support for live migration (Jay)
* forbid '-numa node, mem' for 5.1 and newer machine types (Igor)
* x87 fixes (Joseph)
* Tighten memory_region_access_valid (Michael) and fix fallout (myself)
* Replay fixes (Pavel)


v1->v2: update MIN/MAX patch, fix 32-bit compilation

Anthony PERARD (1):
  xen: Actually fix build without passthrough

David CARLIER (1):
  util/getauxval: Porting to FreeBSD getauxval feature

Eduardo Habkost (1):
  i386: Mask SVM features if nested SVM is disabled

Eric Blake (1):
  osdep: Make MIN/MAX evaluate arguments only once

Igor Mammedov (1):
  numa: forbid '-numa node, mem' for 5.1 and newer machine types

Jay Zhou (1):
  kvm: support to get/set dirty log initial-all-set capability

Jingqi Liu (3):
  configure: add libdaxctl support
  exec: fetch the alignment of Linux devdax pmem character device nodes
  docs/nvdimm: add description of alignment requirement of device dax

Jon Doron (1):
  hyperv: vmbus: Remove the 2nd IRQ

Joseph Myers (10):
  target/i386: reimplement f2xm1 using floatx80 operations
  softfloat: merge floatx80_mod and floatx80_rem
  softfloat: fix floatx80 remainder pseudo-denormal check for zero
  softfloat: do not return pseudo-denormal from floatx80 remainder
  softfloat: do not set denominator high bit for floatx80 remainder
  softfloat: return low bits of quotient from floatx80_modrem
  target/i386: reimplement fprem, fprem1 using floatx80 operations
  target/i386: reimplement fyl2xp1 using floatx80 operations
  target/i386: reimplement fyl2x using floatx80 operations
  target/i386: reimplement fpatan using floatx80 operations

Liao Pingfang (1):
  Makefile: Install qemu-[qmp/ga]-ref.* into the directory "interop"

Marcelo Tosatti (1):
  kvm: i386: allow TSC to differ by NTP correction bounds without TSC 
scaling

Michael S. Tsirkin (1):
  memory: Revert "memory: accept mismatching sizes in 
memory_region_access_valid"

Paolo Bonzini (4):
  libqos: usb-hcd-ehci: use 32-bit write for config register
  libqos: pci-pc: use 32-bit write for EJ register
  vmport: move compat properties to hw_compat_5_0
  ibex_uart: fix XOR-as-pow

Pavel Dovgaluk (2):
  replay: notify the main loop when there are no instructions
  replay: synchronize on every virtual timer callback

Tao Xu (1):
  target/i386: Add notes for versioned CPU models

Thomas Huth (1):
  hw/scsi/megasas: Fix possible out-of-bounds array access in tracepoints

 Makefile|   10 +-
 accel/kvm/kvm-all.c |   21 +-
 accel/tcg/translate-all.c   |6 +-
 configure   |   29 +
 cpus.c  |   15 +-
 docs/index.html.in  |4 +-
 docs/nvdimm.txt |   10 +
 docs/system/deprecated.rst  |   37 +-
 exec.c  |   54 +-
 fpu/softfloat.c |   87 ++-
 hw/arm/virt.c   |2 +-
 hw/char/ibex_uart.c |2 +-
 hw/core/machine.c   |8 +-
 hw/core/numa.c  |7 +
 hw/hyperv/vmbus.c   |3 +-
 hw/i386/acpi-build.c|4 +-
 hw/i386/pc.c|1 -
 hw/i386/pc_piix.c   |1 +
 hw/i386/pc_q35.c|1 +
 hw/ppc/spapr.c  |2 +-
 hw/scsi/megasas.c   |   36 +-
 hw/usb/hcd-xhci.h   |2 +-
 hw/xen/Makefile.objs|2 +-
 include/block/block.h   |4 +-
 include/exec/cpu-all.h  |8 +-
 include/exec/cpu-defs.h |7 +-
 include/fpu/softfloat.h |3 +
 include/hw/hyperv/vmbus-bridge.h|3 +-
 include/qemu/osdep.h|   57 +-
 memory.c|   29 +-
 migration/qemu-file.c   |2 +-
 qemu-options.hx |9 +-
 replay/replay.c |2 +-
 target/i386/cpu.c   |9 +
 target/i386/fpu_helper.c| 1396 +++
 target/i386/kvm.c   |   46 +-
 target/m68k/softfloat.c |   83 ---
 target/m68k/softfloat.h 

Re: [PATCH RESEND 1/9] hw/arm/smmu-common: Factorize some code in smmu_ptw_64()

2020-06-26 Thread Auger Eric
Hi Peter,

On 6/25/20 4:49 PM, Peter Maydell wrote:
> On Thu, 11 Jun 2020 at 17:15, Eric Auger  wrote:
>>
>> Page and block PTE decoding can share some code. Let's
>> first handle table PTE and factorize some code shared by
>> page and block PTEs.
>>
>> Signed-off-by: Eric Auger 
>> ---
>>  hw/arm/smmu-common.c | 51 
>>  1 file changed, 18 insertions(+), 33 deletions(-)
>>
>> diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
>> index e13a5f4a7c..f2de2be527 100644
>> --- a/hw/arm/smmu-common.c
>> +++ b/hw/arm/smmu-common.c
>> @@ -186,12 +186,12 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
>>  uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
>>  uint64_t mask = subpage_size - 1;
>>  uint32_t offset = iova_level_offset(iova, inputsize, level, 
>> granule_sz);
>> -uint64_t pte;
>> +uint64_t pte, gpa;
>>  dma_addr_t pte_addr = baseaddr + offset * sizeof(pte);
>>  uint8_t ap;
>>
>>  if (get_pte(baseaddr, offset, &pte, info)) {
>> -goto error;
>> +break;
> 
> get_pte() fills in info->type (to SMMU_PTW_ERR_WALK_EABT) on
> error; changing this from "goto error" to "break" means we'll
> now execute the "info->type = SMMU_PTW_ERR_TRANSLATION" that
> comes between the end of the while loop and the error: label,
> overwriting the wrong error type.

Agreed.

Thanks

Eric
> 
> thanks
> -- PMM
> 




Re: [PATCH RESEND 6/9] hw/arm/smmu-common: Manage IOTLB block entries

2020-06-26 Thread Auger Eric
Hi Peter,

On 6/25/20 5:30 PM, Peter Maydell wrote:
> On Thu, 11 Jun 2020 at 17:16, Eric Auger  wrote:
>>
>> At the moment each entry in the IOTLB corresponds to a page sized
>> mapping (4K, 16K or 64K), even if the page belongs to a mapped
>> block. In case of block mapping this unefficiently consume IOTLB
>> entries.
>>
>> Change the value of the entry so that it reflects the actual
>> mapping it belongs to (block or page start address and size).
>>
>> Also the level/tg of the entry is encoded in the key. In subsequent
>> patches we will enable range invalidation. This latter is able
>> to provide the level/tg of the entry.
>>
>> Signed-off-by: Eric Auger 
> 
> 
>> -uint64_t smmu_get_iotlb_key(uint16_t asid, uint64_t iova)
>> +uint64_t smmu_get_iotlb_key(uint16_t asid, uint64_t iova,
>> +uint8_t tg, uint8_t level)
>>  {
>> -return iova >> 12 | (uint64_t)(asid) << SMMU_IOTLB_ASID_SHIFT;
>> +return iova >> 12 | (uint64_t)(asid) << SMMU_IOTLB_ASID_SHIFT |
>> +   (uint64_t)(level) << SMMU_IOTLB_LEVEL_SHIFT |
>> +   (uint64_t)(tg) << SMMU_IOTLB_TG_SHIFT;
>>  }
> 
>>  SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg,
>> - hwaddr iova)
>> +SMMUTransTableInfo *tt, hwaddr iova)
>>  {
>> -uint64_t key = smmu_get_iotlb_key(cfg->asid, iova);
>> -SMMUTLBEntry *entry = g_hash_table_lookup(bs->iotlb, &key);
>> +uint8_t tg = (tt->granule_sz - 10) / 2;
>> +int level = tt->starting_level;
>> +SMMUTLBEntry *entry = NULL;
>> +
>> +while (level <= 3) {
>> +uint64_t subpage_size = 1ULL << level_shift(level, tt->granule_sz);
>> +uint64_t mask = subpage_size - 1;
>> +uint64_t key;
>> +
>> +key = smmu_get_iotlb_key(cfg->asid, iova & ~mask, tg, level);
>> +entry = g_hash_table_lookup(bs->iotlb, &key);
>> +if (entry) {
>> +break;
>> +}
>> +level++;
> 
> Rather than looping around doing multiple hash table lookups like
> this, why not just avoid including the tg and level in the
> key equality test?
> 
> If I understand the range-based-invalidation feature correctly,
> the only time we care about the TG/LVL is if we're processing
> an invalidate-range command that specifies them. But in that
> case there should never be multiple entries in the bs->iotlb
> with the same iova, so we can just check whether the entry
> matches the requested TG/LVL once we've pulled it out of the
> hash table. (Or we could architecturally validly just blow
> it away regardless of requested TG/LVL -- they are only hints,
> not required-to-match.)

This change could have been done independently on the RIL feature. As we
now put block entries in the IOTLB , when we look for an iova
translation, the IOVA can be mapped using different block sizes or using
page entries. So we start looking at blocks of the bigger size (entry
level) downto the page, for instance 4TB/512MB/64KB. We cannot know
which block and size the address belongs to. I do not know if we can
make any hypothesis on whether the driver is forbidden to invalidate an
address that is not the starting address of an initial mapping.

Not a justification but an info, this is implemented the same way on x86
(except they don't have variable TG), see vtd_lookup_iotlb in
hw/i386/intel_iommu.c

Thanks

Eric
> 
> thanks
> -- PMM
> 




Re: [PATCH RESEND 3/9] hw/arm/smmu: Simplify the IOTLB key format

2020-06-26 Thread Auger Eric
Hi Peter,

On 6/25/20 5:03 PM, Peter Maydell wrote:
> On Thu, 11 Jun 2020 at 17:15, Eric Auger  wrote:
>>
>> Instead of using a Jenkins hash function to generate
>> the key let's just use a 64 bit unsigned integer that
>> contains the asid and the 40 upper bits of the iova.
>> A maximum of 52-bit IOVA is supported. This change in the
>> key format also prepares for the addition of new fields
>> in subsequent patches (granule and level).
>>
>> Signed-off-by: Eric Auger 
> 
>> diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
>> index 1dceec5cb1..7b9d2f0eb7 100644
>> --- a/include/hw/arm/smmu-common.h
>> +++ b/include/hw/arm/smmu-common.h
>> @@ -88,11 +88,6 @@ typedef struct SMMUPciBus {
>>  SMMUDevice   *pbdev[]; /* Parent array is sparse, so dynamically alloc 
>> */
>>  } SMMUPciBus;
>>
>> -typedef struct SMMUIOTLBKey {
>> -uint64_t iova;
>> -uint16_t asid;
>> -} SMMUIOTLBKey;
> 
> I think we should keep the SMMUIOTLBKey type to abstract out what
> the key type is under the hood, so it would now be
>  typedef uint64_t SMMUIOTLBKey;

OK
> 
> (and then the code that works with SMMUIOTLBKeys should never
> directly look at it as a uint64_t. If you wanted you could
> put the abstraction layer into place with the existing
> SMMUIOTLBKey type and then change the type in a second patch.)

done this way

> 
>> +uint64_t smmu_get_iotlb_key(uint16_t asid, uint64_t iova);
> 
> This should return SMMUIOTLBKey rather than uint64_t,
> or pass in the pointer, like:
>smmu_get_iotlb_key(SMMUIOTLBKey *key, uint16_t asid, uint64_t iova);
sure

Thanks

Eric
> 
> thanks
> -- PMM
> 




[PATCH 04/13] iotests: update snapshot test for new output format

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

This patch updates iotests that verify qemu monitor output.
New output format for snapshot listing include ICOUNT column.

Signed-off-by: Pavel Dovgalyuk 
---
 0 files changed

diff --git a/tests/qemu-iotests/267.out b/tests/qemu-iotests/267.out
index 8dddb4baa4..c4f3d8dd33 100644
--- a/tests/qemu-iotests/267.out
+++ b/tests/qemu-iotests/267.out
@@ -33,8 +33,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm snap0
 (qemu) info snapshots
 List of snapshots present on all disks:
-IDTAG VM SIZEDATE   VM CLOCK
---snap0  SIZE -mm-dd hh:mm:ss   00:00:00.000
+IDTAG   VM SIZEDATE VM CLOCK ICOUNT
+--snap0SIZE -mm-dd hh:mm:ss 00:00:00.000   
 (qemu) loadvm snap0
 (qemu) quit
 
@@ -44,8 +44,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm snap0
 (qemu) info snapshots
 List of snapshots present on all disks:
-IDTAG VM SIZEDATE   VM CLOCK
---snap0  SIZE -mm-dd hh:mm:ss   00:00:00.000
+IDTAG   VM SIZEDATE VM CLOCK ICOUNT
+--snap0SIZE -mm-dd hh:mm:ss 00:00:00.000   
 (qemu) loadvm snap0
 (qemu) quit
 
@@ -69,8 +69,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm snap0
 (qemu) info snapshots
 List of snapshots present on all disks:
-IDTAG VM SIZEDATE   VM CLOCK
---snap0  SIZE -mm-dd hh:mm:ss   00:00:00.000
+IDTAG   VM SIZEDATE VM CLOCK ICOUNT
+--snap0SIZE -mm-dd hh:mm:ss 00:00:00.000   
 (qemu) loadvm snap0
 (qemu) quit
 
@@ -94,8 +94,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm snap0
 (qemu) info snapshots
 List of snapshots present on all disks:
-IDTAG VM SIZEDATE   VM CLOCK
---snap0  SIZE -mm-dd hh:mm:ss   00:00:00.000
+IDTAG   VM SIZEDATE VM CLOCK ICOUNT
+--snap0SIZE -mm-dd hh:mm:ss 00:00:00.000   
 (qemu) loadvm snap0
 (qemu) quit
 
@@ -105,8 +105,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm snap0
 (qemu) info snapshots
 List of snapshots present on all disks:
-IDTAG VM SIZEDATE   VM CLOCK
---snap0  SIZE -mm-dd hh:mm:ss   00:00:00.000
+IDTAG   VM SIZEDATE VM CLOCK ICOUNT
+--snap0SIZE -mm-dd hh:mm:ss 00:00:00.000   
 (qemu) loadvm snap0
 (qemu) quit
 
@@ -119,8 +119,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm snap0
 (qemu) info snapshots
 List of snapshots present on all disks:
-IDTAG VM SIZEDATE   VM CLOCK
---snap0  SIZE -mm-dd hh:mm:ss   00:00:00.000
+IDTAG   VM SIZEDATE VM CLOCK ICOUNT
+--snap0SIZE -mm-dd hh:mm:ss 00:00:00.000   
 (qemu) loadvm snap0
 (qemu) quit
 
@@ -134,8 +134,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm snap0
 (qemu) info snapshots
 List of snapshots present on all disks:
-IDTAG VM SIZEDATE   VM CLOCK
---snap0  SIZE -mm-dd hh:mm:ss   00:00:00.000
+IDTAG   VM SIZEDATE VM CLOCK ICOUNT
+--snap0SIZE -mm-dd hh:mm:ss 00:00:00.000   
 (qemu) loadvm snap0
 (qemu) quit
 
@@ -145,15 +145,15 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm snap0
 (qemu) info snapshots
 List of snapshots present on all disks:
-IDTAG VM SIZEDATE   VM CLOCK
---snap0  SIZE -mm-dd hh:mm:ss   00:00:00.000
+IDTAG   VM SIZEDATE VM CLOCK ICOUNT
+--snap0SIZE -mm-dd hh:mm:ss 00:00:00.000   
 (qemu) loadvm snap0
 (qemu) quit
 
 Internal snapshots on overlay:
 Snapshot list:
-IDTAG VM SIZEDATE   VM CLOCK
-1 snap0  SIZE -mm-dd hh:mm:ss   00:00:00.000
+IDTAG   VM SIZEDATE VM CLOCK ICOUNT
+1 snap0SIZE -mm-dd hh:mm:ss 00:00:00.000   
 Internal snapshots on backing file:
 
 === -blockdev with NBD server on the backing file ===
@@ -166,17 +166,17 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm snap0
 (qemu) info snapshots
 List of snapshots pr

[PATCH 11/13] gdbstub: add reverse continue support in replay mode

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

This patch adds support of the reverse continue operation for gdbstub.
Reverse continue finds the last breakpoint that would happen in normal
execution from the beginning to the current moment.
Implementation of the reverse continue replays the execution twice:
to find the breakpoints that were hit and to seek to the last breakpoint.
Reverse continue loads the previous snapshot and tries to find the breakpoint
since that moment. If there are no such breakpoints, it proceeds to
the earlier snapshot, and so on. When no breakpoints or watchpoints were
hit at all, execution stops at the beginning of the replay log.

Signed-off-by: Pavel Dovgalyuk 
---
 0 files changed

diff --git a/cpus.c b/cpus.c
index 35381ea941..6aed096eab 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1106,6 +1106,11 @@ static void cpu_handle_guest_debug(CPUState *cpu)
 cpu->stopped = true;
 } else {
 if (!cpu->singlestep_enabled) {
+/*
+ * Report about the breakpoint and
+ * make a single step to skip it
+ */
+replay_breakpoint();
 cpu_single_step(cpu, SSTEP_ENABLE);
 } else {
 cpu_single_step(cpu, 0);
diff --git a/exec.c b/exec.c
index 4bde79ea3b..0f4665d858 100644
--- a/exec.c
+++ b/exec.c
@@ -2725,6 +2725,7 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, 
vaddr len,
  * Don't process the watchpoints when we are
  * in a reverse debugging operation.
  */
+replay_breakpoint();
 return;
 }
 if (flags == BP_MEM_READ) {
diff --git a/gdbstub.c b/gdbstub.c
index a81b3b5fb8..5d1cb2dde1 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1907,6 +1907,13 @@ static void handle_backward(GdbCmdContext *gdb_ctx, void 
*user_ctx)
 put_packet("E14");
 }
 return;
+case 'c':
+if (replay_reverse_continue()) {
+gdb_continue();
+} else {
+put_packet("E14");
+}
+return;
 }
 }
 
@@ -2161,7 +2168,8 @@ static void handle_query_supported(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 }
 
 if (replay_mode == REPLAY_MODE_PLAY) {
-g_string_append(gdbserver_state.str_buf, ";ReverseStep+");
+g_string_append(gdbserver_state.str_buf,
+";ReverseStep+;ReverseContinue+");
 }
 
 if (gdb_ctx->num_params &&
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index 13a8123b09..b6cac175c4 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -81,11 +81,19 @@ const char *replay_get_filename(void);
  * Returns true on success.
  */
 bool replay_reverse_step(void);
+/*
+ * Start searching the last breakpoint/watchpoint.
+ * Used by gdbstub for backwards debugging.
+ * Returns true if the process successfully started.
+ */
+bool replay_reverse_continue(void);
 /*
  * Returns true if replay module is processing
  * reverse_continue or reverse_step request
  */
 bool replay_running_debug(void);
+/* Called in reverse debugging mode to collect breakpoint information */
+void replay_breakpoint(void);
 
 /* Processing the instructions */
 
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
index aa3ca040e2..27af103118 100644
--- a/replay/replay-debugging.c
+++ b/replay/replay-debugging.c
@@ -23,6 +23,8 @@
 #include "migration/snapshot.h"
 
 static bool replay_is_debugging;
+static int64_t replay_last_breakpoint;
+static int64_t replay_last_snapshot;
 
 bool replay_running_debug(void)
 {
@@ -252,3 +254,72 @@ bool replay_reverse_step(void)
 
 return false;
 }
+
+static void replay_continue_end(void)
+{
+replay_is_debugging = false;
+vm_stop(RUN_STATE_DEBUG);
+replay_delete_break();
+}
+
+static void replay_continue_stop(void *opaque)
+{
+Error *err = NULL;
+if (replay_last_breakpoint != -1LL) {
+replay_seek(replay_last_breakpoint, replay_stop_vm_debug, &err);
+if (err) {
+error_free(err);
+replay_continue_end();
+}
+return;
+}
+/*
+ * No breakpoints since the last snapshot.
+ * Find previous snapshot and try again.
+ */
+if (replay_last_snapshot != 0) {
+replay_seek(replay_last_snapshot - 1, replay_continue_stop, &err);
+if (err) {
+error_free(err);
+replay_continue_end();
+}
+replay_last_snapshot = replay_get_current_icount();
+return;
+} else {
+/* Seek to the very first step */
+replay_seek(0, replay_stop_vm_debug, &err);
+if (err) {
+error_free(err);
+replay_continue_end();
+}
+return;
+}
+replay_continue_end();
+}
+
+bool replay_reverse_continue(void)
+{
+Error *err = NULL;
+
+assert(replay_mode == REPLAY_MODE_PLAY);
+
+if (replay_get_current_icount() != 0) {
+replay_seek(replay_ge

[PATCH 03/13] migration: introduce icount field for snapshots

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

Saving icount as a parameters of the snapshot allows navigation between
them in the execution replay scenario.
This information can be used for finding a specific snapshot for proceeding
the recorded execution to the specific moment of the time.
E.g., 'reverse step' action (introduced in one of the following patches)
needs to load the nearest snapshot which is prior to the current moment
of time.

Signed-off-by: Pavel Dovgalyuk 
Acked-by: Markus Armbruster 
Acked-by: Kevin Wolf 
---
 0 files changed

diff --git a/block/qapi.c b/block/qapi.c
index afd9f3b4a7..3c73db54c4 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -226,6 +226,8 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
 info->date_nsec = sn_tab[i].date_nsec;
 info->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 10;
 info->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 10;
+info->icount= sn_tab[i].icount;
+info->has_icount= sn_tab[i].icount != -1ULL;
 
 info_list = g_new0(SnapshotInfoList, 1);
 info_list->value = info;
@@ -658,14 +660,15 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
 void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
 {
 char date_buf[128], clock_buf[128];
+char icount_buf[128] = {0};
 struct tm tm;
 time_t ti;
 int64_t secs;
 char *sizing = NULL;
 
 if (!sn) {
-qemu_printf("%-10s%-20s%11s%20s%15s",
-"ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
+qemu_printf("%-10s%-18s%7s%20s%13s%11s",
+"ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT");
 } else {
 ti = sn->date_sec;
 localtime_r(&ti, &tm);
@@ -679,11 +682,16 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
  (int)(secs % 60),
  (int)((sn->vm_clock_nsec / 100) % 1000));
 sizing = size_to_str(sn->vm_state_size);
-qemu_printf("%-10s%-20s%11s%20s%15s",
+if (sn->icount != -1ULL) {
+snprintf(icount_buf, sizeof(icount_buf),
+"%"PRId64, sn->icount);
+}
+qemu_printf("%-10s%-18s%7s%20s%13s%11s",
 sn->id_str, sn->name,
 sizing,
 date_buf,
-clock_buf);
+clock_buf,
+icount_buf);
 }
 g_free(sizing);
 }
@@ -845,6 +853,8 @@ void bdrv_image_info_dump(ImageInfo *info)
 .date_nsec = elem->value->date_nsec,
 .vm_clock_nsec = elem->value->vm_clock_sec * 10ULL +
  elem->value->vm_clock_nsec,
+.icount = elem->value->has_icount ?
+  elem->value->icount : -1ULL,
 };
 
 pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index d14e7be1aa..4b127ea6af 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -663,6 +663,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, 
QEMUSnapshotInfo *sn_info)
 sn->date_sec = sn_info->date_sec;
 sn->date_nsec = sn_info->date_nsec;
 sn->vm_clock_nsec = sn_info->vm_clock_nsec;
+sn->icount = sn_info->icount;
 sn->extra_data_size = sizeof(QCowSnapshotExtraData);
 
 /* Allocate the L1 table of the snapshot and copy the current one there. */
@@ -1007,6 +1008,7 @@ int qcow2_snapshot_list(BlockDriverState *bs, 
QEMUSnapshotInfo **psn_tab)
 sn_info->date_sec = sn->date_sec;
 sn_info->date_nsec = sn->date_nsec;
 sn_info->vm_clock_nsec = sn->vm_clock_nsec;
+sn_info->icount = sn->icount;
 }
 *psn_tab = sn_tab;
 return s->nb_snapshots;
diff --git a/blockdev.c b/blockdev.c
index 31d5eaf6bf..50496700af 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -59,6 +59,7 @@
 #include "sysemu/arch_init.h"
 #include "sysemu/qtest.h"
 #include "sysemu/runstate.h"
+#include "sysemu/replay.h"
 #include "qemu/cutils.h"
 #include "qemu/help_option.h"
 #include "qemu/main-loop.h"
@@ -1200,6 +1201,10 @@ SnapshotInfo 
*qmp_blockdev_snapshot_delete_internal_sync(const char *device,
 info->vm_state_size = sn.vm_state_size;
 info->vm_clock_nsec = sn.vm_clock_nsec % 10;
 info->vm_clock_sec = sn.vm_clock_nsec / 10;
+if (sn.icount != -1ULL) {
+info->icount = sn.icount;
+info->has_icount = true;
+}
 
 return info;
 
@@ -1360,6 +1365,11 @@ static void internal_snapshot_prepare(BlkActionState 
*common,
 sn->date_sec = tv.tv_sec;
 sn->date_nsec = tv.tv_usec * 1000;
 sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+if (replay_mode != REPLAY_MODE_NONE) {
+sn->icount = replay_get_current_icount();
+} else {
+sn->icount = -1ULL;
+}
 
 ret1 = bdrv_snapshot_create(bs, sn);
 if (ret1 < 0) {
diff --git a/include/block/snapshot.h b/include/block/snapshot.h
index 2bfcd57578..b0fe42993d 1

[PATCH 02/13] qcow2: introduce icount field for snapshots

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

This patch introduces the icount field for saving within the snapshot.
It is required for navigation between the snapshots in record/replay mode.

Signed-off-by: Pavel Dovgalyuk 
Acked-by: Kevin Wolf 
---
 0 files changed

diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 2756b37d24..d14e7be1aa 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -164,6 +164,12 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs, 
bool repair,
 sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
 }
 
+if (sn->extra_data_size >= endof(QCowSnapshotExtraData, icount)) {
+sn->icount = be64_to_cpu(extra.icount);
+} else {
+sn->icount = -1ULL;
+}
+
 if (sn->extra_data_size > sizeof(extra)) {
 uint64_t extra_data_end;
 size_t unknown_extra_data_size;
@@ -333,6 +339,7 @@ int qcow2_write_snapshots(BlockDriverState *bs)
 memset(&extra, 0, sizeof(extra));
 extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size);
 extra.disk_size = cpu_to_be64(sn->disk_size);
+extra.icount = cpu_to_be64(sn->icount);
 
 id_str_size = strlen(sn->id_str);
 name_size = strlen(sn->name);
diff --git a/block/qcow2.h b/block/qcow2.h
index 7ce2c23bdb..9c81086991 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -179,6 +179,7 @@ typedef struct QEMU_PACKED QCowSnapshotHeader {
 typedef struct QEMU_PACKED QCowSnapshotExtraData {
 uint64_t vm_state_size_large;
 uint64_t disk_size;
+uint64_t icount;
 } QCowSnapshotExtraData;
 
 
@@ -192,6 +193,8 @@ typedef struct QCowSnapshot {
 uint32_t date_sec;
 uint32_t date_nsec;
 uint64_t vm_clock_nsec;
+/* icount value for the moment when snapshot was taken */
+uint64_t icount;
 /* Size of all extra data, including QCowSnapshotExtraData if available */
 uint32_t extra_data_size;
 /* Data beyond QCowSnapshotExtraData, if any */
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
index cb723463f2..06014c0e90 100644
--- a/docs/interop/qcow2.txt
+++ b/docs/interop/qcow2.txt
@@ -645,6 +645,11 @@ Snapshot table entry:
 
 Byte 48 - 55:   Virtual disk size of the snapshot in bytes
 
+Byte 56 - 63:   icount value which corresponds to
+the record/replay instruction count
+when the snapshot was taken. Set to -1
+if icount was disabled
+
 Version 3 images must include extra data at least up to
 byte 55.
 




[PATCH 05/13] qapi: introduce replay.json for record/replay-related stuff

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

This patch adds replay.json file. It will be
used for adding record/replay-related data structures and commands.

Signed-off-by: Pavel Dovgalyuk 
Reviewed-by: Markus Armbruster 
---
 0 files changed

diff --git a/MAINTAINERS b/MAINTAINERS
index 5dd86c7f94..ca5b1cf7f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2572,6 +2572,7 @@ F: docs/replay.txt
 F: stubs/replay.c
 F: tests/acceptance/replay_kernel.py
 F: tests/acceptance/replay_linux.py
+F: qapi/replay.json
 
 IOVA Tree
 M: Peter Xu 
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index c9c896ae8d..e00ed2f4a5 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -14,6 +14,7 @@
 
 #include "qapi/qapi-types-misc.h"
 #include "qapi/qapi-types-run-state.h"
+#include "qapi/qapi-types-replay.h"
 #include "qapi/qapi-types-ui.h"
 #include "block/aio.h"
 
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
index 4673ab7490..eff501a97d 100644
--- a/qapi/Makefile.objs
+++ b/qapi/Makefile.objs
@@ -7,8 +7,8 @@ util-obj-y += qapi-util.o
 
 QAPI_COMMON_MODULES = audio authz block-core block char common control crypto
 QAPI_COMMON_MODULES += dump error introspect job machine migration misc
-QAPI_COMMON_MODULES += net pragma qdev qom rdma rocker run-state sockets tpm
-QAPI_COMMON_MODULES += trace transaction ui
+QAPI_COMMON_MODULES += net pragma qdev qom rdma replay rocker run-state sockets
+QAPI_COMMON_MODULES += tpm trace transaction ui
 QAPI_TARGET_MODULES = machine-target misc-target
 QAPI_MODULES = $(QAPI_COMMON_MODULES) $(QAPI_TARGET_MODULES)
 
diff --git a/qapi/misc.json b/qapi/misc.json
index a5a0beb902..2a7af56887 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -1493,24 +1493,6 @@
 { 'event': 'ACPI_DEVICE_OST',
  'data': { 'info': 'ACPIOSTInfo' } }
 
-##
-# @ReplayMode:
-#
-# Mode of the replay subsystem.
-#
-# @none: normal execution mode. Replay or record are not enabled.
-#
-# @record: record mode. All non-deterministic data is written into the
-#  replay log.
-#
-# @play: replay mode. Non-deterministic data required for system execution
-#is read from the log.
-#
-# Since: 2.5
-##
-{ 'enum': 'ReplayMode',
-  'data': [ 'none', 'record', 'play' ] }
-
 ##
 # @xen-load-devices-state:
 #
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
index 43b0ba0dea..ce48897b94 100644
--- a/qapi/qapi-schema.json
+++ b/qapi/qapi-schema.json
@@ -81,6 +81,7 @@
 { 'include': 'qdev.json' }
 { 'include': 'machine.json' }
 { 'include': 'machine-target.json' }
+{ 'include': 'replay.json' }
 { 'include': 'misc.json' }
 { 'include': 'misc-target.json' }
 { 'include': 'audio.json' }
diff --git a/qapi/replay.json b/qapi/replay.json
new file mode 100644
index 00..9e13551d20
--- /dev/null
+++ b/qapi/replay.json
@@ -0,0 +1,26 @@
+# -*- Mode: Python -*-
+#
+
+##
+# = Record/replay
+##
+
+{ 'include': 'common.json' }
+
+##
+# @ReplayMode:
+#
+# Mode of the replay subsystem.
+#
+# @none: normal execution mode. Replay or record are not enabled.
+#
+# @record: record mode. All non-deterministic data is written into the
+#  replay log.
+#
+# @play: replay mode. Non-deterministic data required for system execution
+#is read from the log.
+#
+# Since: 2.5
+##
+{ 'enum': 'ReplayMode',
+  'data': [ 'none', 'record', 'play' ] }




[PATCH 10/13] gdbstub: add reverse step support in replay mode

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

GDB remote protocol supports two reverse debugging commands:
reverse step and reverse continue.
This patch adds support of the first one to the gdbstub.
Reverse step is intended to step one instruction in the backwards
direction. This is not possible in regular execution.
But replayed execution is deterministic, therefore we can load one of
the prior snapshots and proceed to the desired step. It is equivalent
to stepping one instruction back.
There should be at least one snapshot preceding the debugged part of
the replay log.

Signed-off-by: Pavel Dovgalyuk 
---
 0 files changed

diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index 603d17ff83..fb1e19c585 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -17,6 +17,7 @@
 #include "exec/log.h"
 #include "exec/translator.h"
 #include "exec/plugin-gen.h"
+#include "sysemu/replay.h"
 
 /* Pairs with tcg_clear_temp_count.
To be called by #TranslatorOps.{translate_insn,tb_stop} if
diff --git a/cpus.c b/cpus.c
index 41d1c5099f..35381ea941 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1100,9 +1100,17 @@ static bool cpu_can_run(CPUState *cpu)
 
 static void cpu_handle_guest_debug(CPUState *cpu)
 {
-gdb_set_stop_cpu(cpu);
-qemu_system_debug_request();
-cpu->stopped = true;
+if (!replay_running_debug()) {
+gdb_set_stop_cpu(cpu);
+qemu_system_debug_request();
+cpu->stopped = true;
+} else {
+if (!cpu->singlestep_enabled) {
+cpu_single_step(cpu, SSTEP_ENABLE);
+} else {
+cpu_single_step(cpu, 0);
+}
+}
 }
 
 #ifdef CONFIG_LINUX
diff --git a/exec.c b/exec.c
index d6712fba7e..4bde79ea3b 100644
--- a/exec.c
+++ b/exec.c
@@ -2720,6 +2720,13 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, 
vaddr len,
 QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
 if (watchpoint_address_matches(wp, addr, len)
 && (wp->flags & flags)) {
+if (replay_running_debug()) {
+/*
+ * Don't process the watchpoints when we are
+ * in a reverse debugging operation.
+ */
+return;
+}
 if (flags == BP_MEM_READ) {
 wp->flags |= BP_WATCHPOINT_HIT_READ;
 } else {
diff --git a/gdbstub.c b/gdbstub.c
index 6950fd243f..a81b3b5fb8 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -51,6 +51,7 @@
 #include "sysemu/runstate.h"
 #include "hw/semihosting/semihost.h"
 #include "exec/exec-all.h"
+#include "sysemu/replay.h"
 
 #ifdef CONFIG_USER_ONLY
 #define GDB_ATTACHED "0"
@@ -375,6 +376,20 @@ typedef struct GDBState {
  */
 static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
 
+/* Retrieves flags for single step mode. */
+static int get_sstep_flags(void)
+{
+/*
+ * In replay mode all events written into the log should be replayed.
+ * That is why NOIRQ flag is removed in this mode.
+ */
+if (replay_mode != REPLAY_MODE_NONE) {
+return SSTEP_ENABLE;
+} else {
+return sstep_flags;
+}
+}
+
 static GDBState gdbserver_state;
 
 static void init_gdbserver_state(void)
@@ -501,7 +516,7 @@ static int gdb_continue_partial(char *newstates)
 break; /* nothing to do here */
 case 's':
 trace_gdbstub_op_stepping(cpu->cpu_index);
-cpu_single_step(cpu, sstep_flags);
+cpu_single_step(cpu, get_sstep_flags());
 cpu_resume(cpu);
 flag = 1;
 break;
@@ -1874,10 +1889,31 @@ static void handle_step(GdbCmdContext *gdb_ctx, void 
*user_ctx)
 gdb_set_cpu_pc((target_ulong)gdb_ctx->params[0].val_ull);
 }
 
-cpu_single_step(gdbserver_state.c_cpu, sstep_flags);
+cpu_single_step(gdbserver_state.c_cpu, get_sstep_flags());
 gdb_continue();
 }
 
+static void handle_backward(GdbCmdContext *gdb_ctx, void *user_ctx)
+{
+if (replay_mode != REPLAY_MODE_PLAY) {
+put_packet("E22");
+}
+if (gdb_ctx->num_params == 1) {
+switch (gdb_ctx->params[0].opcode) {
+case 's':
+if (replay_reverse_step()) {
+gdb_continue();
+} else {
+put_packet("E14");
+}
+return;
+}
+}
+
+/* Default invalid command */
+put_packet("");
+}
+
 static void handle_v_cont_query(GdbCmdContext *gdb_ctx, void *user_ctx)
 {
 put_packet("vCont;c;C;s;S");
@@ -2124,6 +2160,10 @@ static void handle_query_supported(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
 }
 
+if (replay_mode == REPLAY_MODE_PLAY) {
+g_string_append(gdbserver_state.str_buf, ";ReverseStep+");
+}
+
 if (gdb_ctx->num_params &&
 strstr(gdb_ctx->params[0].data, "multiprocess+")) {
 gdbserver_state.multiprocess = true;
@@ -2460,6 +2500,17 @@ static int gdb_handle_packet(const char *

[PATCH 01/13] replay: provide an accessor for rr filename

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

This patch adds an accessor function for the name of the record/replay
log file. Adding an accessor instead of making variable global,
prevents accidental modification of this variable by other modules.

Signed-off-by: Pavel Dovgalyuk 
---
 0 files changed

diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index 5471bb514d..c9c896ae8d 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -72,6 +72,8 @@ void replay_start(void);
 void replay_finish(void);
 /*! Adds replay blocker with the specified error description */
 void replay_add_blocker(Error *reason);
+/* Returns name of the replay log file */
+const char *replay_get_filename(void);
 
 /* Processing the instructions */
 
diff --git a/replay/replay.c b/replay/replay.c
index 83ed9e0e24..42e82f7bc7 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -399,3 +399,8 @@ void replay_add_blocker(Error *reason)
 {
 replay_blockers = g_slist_prepend(replay_blockers, reason);
 }
+
+const char *replay_get_filename(void)
+{
+return replay_filename;
+}




[PATCH 07/13] replay: introduce breakpoint at the specified step

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

This patch introduces replay_break, replay_delete_break
qmp and hmp commands.
These commands allow stopping at the specified instruction.
It may be useful for debugging when there are some known
events that should be investigated.
replay_break command has one argument - number of instructions
executed since the start of the replay.
replay_delete_break removes previously set breakpoint.

Signed-off-by: Pavel Dovgalyuk 
Acked-by: Markus Armbruster 
---
 0 files changed

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 60f395c276..e8ce385879 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1819,6 +1819,38 @@ SRST
   Set QOM property *property* of object at location *path* to value *value*
 ERST
 
+{
+.name   = "replay_break",
+.args_type  = "icount:i",
+.params = "icount",
+.help   = "set breakpoint at the specified instruction count",
+.cmd= hmp_replay_break,
+},
+
+SRST
+``replay_break`` *icount*
+  Set replay breakpoint at instruction count *icount*.
+  Execution stops when the specified instruction is reached.
+  There can be at most one breakpoint. When breakpoint is set, any prior
+  one is removed.  The breakpoint may be set only in replay mode and only
+  "in the future", i.e. at instruction counts greater than the current one.
+  The current instruction count can be observed with ``info replay``.
+ERST
+
+{
+.name   = "replay_delete_break",
+.args_type  = "",
+.params = "",
+.help   = "remove replay breakpoint",
+.cmd= hmp_replay_delete_break,
+},
+
+SRST
+``replay_delete_break``
+  Remove replay breakpoint which was previously set with ``replay_break``.
+  The command is ignored when there are no replay breakpoints.
+ERST
+
 {
 .name   = "info",
 .args_type  = "item:s?",
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index a790589b9e..21849bdda5 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -131,5 +131,7 @@ void hmp_info_vm_generation_id(Monitor *mon, const QDict 
*qdict);
 void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict);
 void hmp_info_sev(Monitor *mon, const QDict *qdict);
 void hmp_info_replay(Monitor *mon, const QDict *qdict);
+void hmp_replay_break(Monitor *mon, const QDict *qdict);
+void hmp_replay_delete_break(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/qapi/replay.json b/qapi/replay.json
index 0a160466f2..edf7cc9265 100644
--- a/qapi/replay.json
+++ b/qapi/replay.json
@@ -63,3 +63,39 @@
 ##
 { 'command': 'query-replay',
   'returns': 'ReplayInfo' }
+
+##
+# @replay-break:
+#
+# Set replay breakpoint at instruction count @icount.
+# Execution stops when the specified instruction is reached.
+# There can be at most one breakpoint. When breakpoint is set, any prior
+# one is removed.  The breakpoint may be set only in replay mode and only
+# "in the future", i.e. at instruction counts greater than the current one.
+# The current instruction count can be observed with @query-replay.
+#
+# @icount: instruction count to stop at
+#
+# Since: 5.1
+#
+# Example:
+#
+# -> { "execute": "replay-break", "data": { "icount": 220414 } }
+#
+##
+{ 'command': 'replay-break', 'data': { 'icount': 'int' } }
+
+##
+# @replay-delete-break:
+#
+# Remove replay breakpoint which was set with @replay-break.
+# The command is ignored when there are no replay breakpoints.
+#
+# Since: 5.1
+#
+# Example:
+#
+# -> { "execute": "replay-delete-break" }
+#
+##
+{ 'command': 'replay-delete-break' }
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
index 51a6de4e81..86e19bb217 100644
--- a/replay/replay-debugging.c
+++ b/replay/replay-debugging.c
@@ -12,10 +12,13 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "sysemu/replay.h"
+#include "sysemu/runstate.h"
 #include "replay-internal.h"
 #include "monitor/hmp.h"
 #include "monitor/monitor.h"
 #include "qapi/qapi-commands-replay.h"
+#include "qapi/qmp/qdict.h"
+#include "qemu/timer.h"
 
 void hmp_info_replay(Monitor *mon, const QDict *qdict)
 {
@@ -41,3 +44,86 @@ ReplayInfo *qmp_query_replay(Error **errp)
 retval->icount = replay_get_current_icount();
 return retval;
 }
+
+static void replay_break(uint64_t icount, QEMUTimerCB callback, void *opaque)
+{
+assert(replay_mode == REPLAY_MODE_PLAY);
+assert(replay_mutex_locked());
+assert(replay_break_icount >= replay_get_current_icount());
+assert(callback);
+
+replay_break_icount = icount;
+
+if (replay_break_timer) {
+timer_del(replay_break_timer);
+}
+replay_break_timer = timer_new_ns(QEMU_CLOCK_REALTIME,
+  callback, opaque);
+}
+
+static void replay_delete_break(void)
+{
+assert(replay_mode == REPLAY_MODE_PLAY);
+assert(replay_mutex_locked());
+
+if (replay_break_timer) {
+timer_del(replay_break_timer);
+timer_free(replay_break_tim

[PATCH 00/13] Reverse debugging

2020-06-26 Thread Pavel Dovgalyuk
GDB remote protocol supports reverse debugging of the targets.
It includes 'reverse step' and 'reverse continue' operations.
The first one finds the previous step of the execution,
and the second one is intended to stop at the last breakpoint that
would happen when the program is executed normally.

Reverse debugging is possible in the replay mode, when at least
one snapshot was created at the record or replay phase.
QEMU can use these snapshots for travelling back in time with GDB.

Running the execution in replay mode allows using GDB reverse debugging
commands:
 - reverse-stepi (or rsi): Steps one instruction to the past.
   QEMU loads on of the prior snapshots and proceeds to the desired
   instruction forward. When that step is reaches, execution stops.
 - reverse-continue (or rc): Runs execution "backwards".
   QEMU tries to find breakpoint or watchpoint by loaded prior snapshot
   and replaying the execution. Then QEMU loads snapshots again and
   replays to the latest breakpoint. When there are no breakpoints in
   the examined section of the execution, QEMU finds one more snapshot
   and tries again. After the first snapshot is processed, execution
   stops at this snapshot.

The set of patches include the following modifications:
 - gdbstub update for reverse debugging support
 - functions that automatically perform reverse step and reverse
   continue operations
 - hmp/qmp commands for manipulating the replay process
 - improvement of the snapshotting for saving the execution step
   in the snapshot parameters
 - avocado-based acceptance tests for reverse debugging

Acceptance tests intended to use the version of avocado framework, that
will be released after 25.06.20, because it includes significant
fixes of the remote GDB protocol.

The patches are available in the repository:
https://github.com/ispras/qemu/tree/rr-200626

---

Pavel Dovgaluk (13):
  replay: provide an accessor for rr filename
  qcow2: introduce icount field for snapshots
  migration: introduce icount field for snapshots
  iotests: update snapshot test for new output format
  qapi: introduce replay.json for record/replay-related stuff
  replay: introduce info hmp/qmp command
  replay: introduce breakpoint at the specified step
  replay: implement replay-seek command
  replay: flush rr queue before loading the vmstate
  gdbstub: add reverse step support in replay mode
  gdbstub: add reverse continue support in replay mode
  replay: describe reverse debugging in docs/replay.txt
  tests/acceptance: add reverse debugging test


 0 files changed

--
Pavel Dovgalyuk



[PATCH 09/13] replay: flush rr queue before loading the vmstate

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

Non-empty record/replay queue prevents saving and loading the VM state,
because it includes pending bottom halves and block coroutines.
But when the new VM state is loaded, we don't have to preserve the consistency
of the current state anymore. Therefore this patch just flushes the queue
allowing the coroutines to finish and removes checking for empty rr queue
for load_snapshot function.

Signed-off-by: Pavel Dovgalyuk 
---
 0 files changed

diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index e00ed2f4a5..239c01e7df 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -149,6 +149,8 @@ void replay_disable_events(void);
 void replay_enable_events(void);
 /*! Returns true when saving events is enabled */
 bool replay_events_enabled(void);
+/* Flushes events queue */
+void replay_flush_events(void);
 /*! Adds bottom half event to the queue */
 void replay_bh_schedule_event(QEMUBH *bh);
 /* Adds oneshot bottom half event to the queue */
diff --git a/migration/savevm.c b/migration/savevm.c
index f583b9bd08..7d9d57ac33 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2842,12 +2842,6 @@ int load_snapshot(const char *name, Error **errp)
 AioContext *aio_context;
 MigrationIncomingState *mis = migration_incoming_get_current();
 
-if (!replay_can_snapshot()) {
-error_setg(errp, "Record/replay does not allow loading snapshot "
-   "right now. Try once more later.");
-return -EINVAL;
-}
-
 if (!bdrv_all_can_snapshot(&bs)) {
 error_setg(errp,
"Device '%s' is writable but does not support snapshots",
@@ -2881,6 +2875,12 @@ int load_snapshot(const char *name, Error **errp)
 return -EINVAL;
 }
 
+/*
+ * Flush the record/replay queue. Now the VM state is going
+ * to change. Therefore we don't need to preserve its consistency
+ */
+replay_flush_events();
+
 /* Flush all IO requests so they don't interfere with the new state.  */
 bdrv_drain_all_begin();
 
diff --git a/replay/replay-events.c b/replay/replay-events.c
index 302b84043a..a1c6bb934e 100644
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -77,6 +77,10 @@ bool replay_has_events(void)
 
 void replay_flush_events(void)
 {
+if (replay_mode == REPLAY_MODE_NONE) {
+return;
+}
+
 g_assert(replay_mutex_locked());
 
 while (!QTAILQ_EMPTY(&events_list)) {
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 2f6145ec7c..97649ed8d7 100644
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -149,8 +149,6 @@ void replay_read_next_clock(unsigned int kind);
 void replay_init_events(void);
 /*! Clears internal data structures for events handling */
 void replay_finish_events(void);
-/*! Flushes events queue */
-void replay_flush_events(void);
 /*! Returns true if there are any unsaved events in the queue */
 bool replay_has_events(void);
 /*! Saves events from queue into the file */




[PATCH 06/13] replay: introduce info hmp/qmp command

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

This patch introduces 'info replay' monitor command and
corresponding qmp request.
These commands request the current record/replay mode, replay log file
name, and the instruction count (number of recorded/replayed
instructions).  The instruction count can be used with the
replay_seek/replay_break commands added in the next two patches.

Signed-off-by: Pavel Dovgalyuk 
Acked-by: Dr. David Alan Gilbert 
Acked-by: Markus Armbruster 
---
 0 files changed

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 30209e3903..117ba25f91 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -881,4 +881,15 @@ SRST
 Show SEV information.
 ERST
 
+{
+.name   = "replay",
+.args_type  = "",
+.params = "",
+.help   = "show record/replay information",
+.cmd= hmp_info_replay,
+},
 
+SRST
+  ``info replay``
+Display the record/replay information: mode and the current icount.
+ERST
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index c986cfd28b..a790589b9e 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -130,5 +130,6 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict 
*qdict);
 void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict);
 void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict);
 void hmp_info_sev(Monitor *mon, const QDict *qdict);
+void hmp_info_replay(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 125ef7b1c2..947ef00a96 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -28,7 +28,8 @@
 #
 # @icount: Current instruction count. Appears when execution record/replay
 #  is enabled. Used for "time-traveling" to match the moment
-#  in the recorded execution with the snapshots. (since 5.1)
+#  in the recorded execution with the snapshots. This counter may
+#  be obtained through @query-replay command (since 5.1)
 #
 # Since: 1.3
 #
diff --git a/qapi/replay.json b/qapi/replay.json
index 9e13551d20..0a160466f2 100644
--- a/qapi/replay.json
+++ b/qapi/replay.json
@@ -24,3 +24,42 @@
 ##
 { 'enum': 'ReplayMode',
   'data': [ 'none', 'record', 'play' ] }
+
+##
+# @ReplayInfo:
+#
+# Record/replay information.
+#
+# @mode: current mode.
+#
+# @filename: name of the record/replay log file.
+#It is present only in record or replay modes, when the log
+#is recorded or replayed.
+#
+# @icount: current number of executed instructions.
+#
+# Since: 5.1
+#
+##
+{ 'struct': 'ReplayInfo',
+  'data': { 'mode': 'ReplayMode', '*filename': 'str', 'icount': 'int' } }
+
+##
+# @query-replay:
+#
+# Retrieve the record/replay information.
+# It includes current instruction count which may be used for
+# @replay-break and @replay-seek commands.
+#
+# Returns: record/replay information.
+#
+# Since: 5.1
+#
+# Example:
+#
+# -> { "execute": "query-replay" }
+# <- { "return": { "mode": "play", "filename": "log.rr", "icount": 220414 } }
+#
+##
+{ 'command': 'query-replay',
+  'returns': 'ReplayInfo' }
diff --git a/replay/Makefile.objs b/replay/Makefile.objs
index 939be964a9..f847c5c023 100644
--- a/replay/Makefile.objs
+++ b/replay/Makefile.objs
@@ -8,3 +8,4 @@ common-obj-y += replay-snapshot.o
 common-obj-y += replay-net.o
 common-obj-y += replay-audio.o
 common-obj-y += replay-random.o
+common-obj-y += replay-debugging.o
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
new file mode 100644
index 00..51a6de4e81
--- /dev/null
+++ b/replay/replay-debugging.c
@@ -0,0 +1,43 @@
+/*
+ * replay-debugging.c
+ *
+ * Copyright (c) 2010-2020 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * 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 "qapi/error.h"
+#include "sysemu/replay.h"
+#include "replay-internal.h"
+#include "monitor/hmp.h"
+#include "monitor/monitor.h"
+#include "qapi/qapi-commands-replay.h"
+
+void hmp_info_replay(Monitor *mon, const QDict *qdict)
+{
+if (replay_mode == REPLAY_MODE_NONE) {
+monitor_printf(mon, "Record/replay is not active\n");
+} else {
+monitor_printf(mon,
+"%s execution '%s': instruction count = %"PRId64"\n",
+replay_mode == REPLAY_MODE_RECORD ? "Recording" : "Replaying",
+replay_get_filename(), replay_get_current_icount());
+}
+}
+
+ReplayInfo *qmp_query_replay(Error **errp)
+{
+ReplayInfo *retval = g_new0(ReplayInfo, 1);
+
+retval->mode = replay_mode;
+if (replay_get_filename()) {
+retval->filename = g_strdup(replay_get_filename());
+retval->has_filename = true;
+}
+retval->icount = replay_get_current_icount();
+return retval;
+}




[PATCH 13/13] tests/acceptance: add reverse debugging test

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

This is a test for GDB reverse debugging commands: reverse step and reverse 
continue.
Every test in this suite consists of two phases: record and replay.
Recording saves the execution of some instructions and makes an initial
VM snapshot to allow reverse execution.
Replay saves the order of the first instructions and then checks that they
are executed backwards in the correct order.
After that the execution is replayed to the end, and reverse continue
command is checked by setting several breakpoints, and asserting
that the execution is stopped at the last of them.

Signed-off-by: Pavel Dovgalyuk 
---
 0 files changed

diff --git a/MAINTAINERS b/MAINTAINERS
index ca5b1cf7f1..906af395fe 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2572,6 +2572,7 @@ F: docs/replay.txt
 F: stubs/replay.c
 F: tests/acceptance/replay_kernel.py
 F: tests/acceptance/replay_linux.py
+F: tests/acceptance/reverse_debugging.py
 F: qapi/replay.json
 
 IOVA Tree
diff --git a/tests/acceptance/reverse_debugging.py 
b/tests/acceptance/reverse_debugging.py
new file mode 100644
index 00..dda42e1c1a
--- /dev/null
+++ b/tests/acceptance/reverse_debugging.py
@@ -0,0 +1,203 @@
+# Reverse debugging test
+#
+# Copyright (c) 2020 ISP RAS
+#
+# Author:
+#  Pavel Dovgalyuk 
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+import os
+import logging
+
+from avocado_qemu import BUILD_DIR
+from avocado.utils import gdb
+from avocado.utils import process
+from avocado.utils.path import find_command
+from boot_linux_console import LinuxKernelTest
+
+class ReverseDebugging(LinuxKernelTest):
+"""
+Test GDB reverse debugging commands: reverse step and reverse continue.
+Recording saves the execution of some instructions and makes an initial
+VM snapshot to allow reverse execution.
+Replay saves the order of the first instructions and then checks that they
+are executed backwards in the correct order.
+After that the execution is replayed to the end, and reverse continue
+command is checked by setting several breakpoints, and asserting
+that the execution is stopped at the last of them.
+"""
+
+timeout = 10
+STEPS = 10
+endian_is_le = True
+
+def run_vm(self, record, shift, args, replay_path, image_path):
+logger = logging.getLogger('replay')
+vm = self.get_vm()
+vm.set_console()
+if record:
+logger.info('recording the execution...')
+mode = 'record'
+else:
+logger.info('replaying the execution...')
+mode = 'replay'
+vm.add_args('-s', '-S')
+vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s,rrsnapshot=init' %
+(shift, mode, replay_path),
+'-net', 'none')
+vm.add_args('-drive', 'file=%s,if=none' % image_path)
+if args:
+vm.add_args(*args)
+vm.launch()
+return vm
+
+@staticmethod
+def get_reg_le(g, reg):
+res = g.cmd(b'p%x' % reg)
+num = 0
+for i in range(len(res))[-2::-2]:
+num = 0x100 * num + int(res[i:i + 2], 16)
+return num
+
+@staticmethod
+def get_reg_be(g, reg):
+res = g.cmd(b'p%x' % reg)
+return int(res, 16)
+
+def get_reg(self, g, reg):
+# value may be encoded in BE or LE order
+if self.endian_is_le:
+return self.get_reg_le(g, reg)
+else:
+return self.get_reg_be(g, reg)
+
+def get_pc(self, g):
+return self.get_reg(g, self.REG_PC)
+
+def check_pc(self, g, addr):
+pc = self.get_pc(g)
+if pc != addr:
+self.fail('Invalid PC (read %x instead of %x)' % (pc, addr))
+
+@staticmethod
+def gdb_step(g):
+g.cmd(b's', b'T05thread:01;')
+
+@staticmethod
+def gdb_bstep(g):
+g.cmd(b'bs', b'T05thread:01;')
+
+@staticmethod
+def vm_get_icount(vm):
+return vm.qmp('query-replay')['return']['icount']
+
+def reverse_debugging(self, shift=7, args=None):
+logger = logging.getLogger('replay')
+
+# create qcow2 for snapshots
+logger.info('creating qcow2 image for VM snapshots')
+image_path = os.path.join(self.workdir, 'disk.qcow2')
+qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
+if not os.path.exists(qemu_img):
+qemu_img = find_command('qemu-img', False)
+if qemu_img is False:
+self.cancel('Could not find "qemu-img", which is required to '
+'create the temporary qcow2 image')
+cmd = '%s create -f qcow2 %s 128M' % (qemu_img, image_path)
+process.run(cmd)
+
+replay_path = os.path.join(self.workdir, 'replay.bin')
+
+# record the log
+vm = self.run_vm(True, shift, args, replay_path, image_path)
+while self.vm_get_icount(vm) <= self.STEPS:
+

[PATCH 08/13] replay: implement replay-seek command

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

This patch adds hmp/qmp commands replay_seek/replay-seek that proceed
the execution to the specified instruction count.
The command automatically loads nearest snapshot and replays the execution
to find the desired instruction count.

Signed-off-by: Pavel Dovgalyuk 
Acked-by: Markus Armbruster 
---
 0 files changed

diff --git a/hmp-commands.hx b/hmp-commands.hx
index e8ce385879..4288274c4e 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1851,6 +1851,24 @@ SRST
   The command is ignored when there are no replay breakpoints.
 ERST
 
+{
+.name   = "replay_seek",
+.args_type  = "icount:i",
+.params = "icount",
+.help   = "replay execution to the specified instruction count",
+.cmd= hmp_replay_seek,
+},
+
+SRST
+``replay_seek`` *icount*
+Automatically proceed to the instruction count *icount*, when
+replaying the execution. The command automatically loads nearest
+snapshot and replays the execution to find the desired instruction.
+When there is no preceding snapshot or the execution is not replayed,
+then the command fails.
+*icount* for the reference may be observed with ``info replay`` command.
+ERST
+
 {
 .name   = "info",
 .args_type  = "item:s?",
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 21849bdda5..655eb81a4c 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -133,5 +133,6 @@ void hmp_info_sev(Monitor *mon, const QDict *qdict);
 void hmp_info_replay(Monitor *mon, const QDict *qdict);
 void hmp_replay_break(Monitor *mon, const QDict *qdict);
 void hmp_replay_delete_break(Monitor *mon, const QDict *qdict);
+void hmp_replay_seek(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/qapi/replay.json b/qapi/replay.json
index edf7cc9265..060e42129d 100644
--- a/qapi/replay.json
+++ b/qapi/replay.json
@@ -99,3 +99,23 @@
 #
 ##
 { 'command': 'replay-delete-break' }
+
+##
+# @replay-seek:
+#
+# Automatically proceed to the instruction count @icount, when
+# replaying the execution. The command automatically loads nearest
+# snapshot and replays the execution to find the desired instruction.
+# When there is no preceding snapshot or the execution is not replayed,
+# then the command fails.
+# icount for the reference may be obtained with @query-replay command.
+#
+# @icount: target instruction count
+#
+# Since: 5.1
+#
+# Example:
+#
+# -> { "execute": "replay-seek", "data": { "icount": 220414 } }
+##
+{ 'command': 'replay-seek', 'data': { 'icount': 'int' } }
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
index 86e19bb217..cfd0221692 100644
--- a/replay/replay-debugging.c
+++ b/replay/replay-debugging.c
@@ -19,6 +19,8 @@
 #include "qapi/qapi-commands-replay.h"
 #include "qapi/qmp/qdict.h"
 #include "qemu/timer.h"
+#include "block/snapshot.h"
+#include "migration/snapshot.h"
 
 void hmp_info_replay(Monitor *mon, const QDict *qdict)
 {
@@ -127,3 +129,93 @@ void hmp_replay_delete_break(Monitor *mon, const QDict 
*qdict)
 return;
 }
 }
+
+static char *replay_find_nearest_snapshot(int64_t icount,
+  int64_t *snapshot_icount)
+{
+BlockDriverState *bs;
+QEMUSnapshotInfo *sn_tab;
+QEMUSnapshotInfo *nearest = NULL;
+char *ret = NULL;
+int nb_sns, i;
+AioContext *aio_context;
+
+*snapshot_icount = -1;
+
+bs = bdrv_all_find_vmstate_bs();
+if (!bs) {
+goto fail;
+}
+aio_context = bdrv_get_aio_context(bs);
+
+aio_context_acquire(aio_context);
+nb_sns = bdrv_snapshot_list(bs, &sn_tab);
+aio_context_release(aio_context);
+
+for (i = 0; i < nb_sns; i++) {
+if (bdrv_all_find_snapshot(sn_tab[i].name, &bs) == 0) {
+if (sn_tab[i].icount != -1ULL
+&& sn_tab[i].icount <= icount
+&& (!nearest || nearest->icount < sn_tab[i].icount)) {
+nearest = &sn_tab[i];
+}
+}
+}
+if (nearest) {
+ret = g_strdup(nearest->name);
+*snapshot_icount = nearest->icount;
+}
+g_free(sn_tab);
+
+fail:
+return ret;
+}
+
+static void replay_seek(int64_t icount, QEMUTimerCB callback, Error **errp)
+{
+char *snapshot = NULL;
+int64_t snapshot_icount;
+
+if (replay_mode != REPLAY_MODE_PLAY) {
+error_setg(errp, "replay must be enabled to seek");
+return;
+}
+if (!replay_snapshot) {
+error_setg(errp, "snapshotting is disabled");
+return;
+}
+
+snapshot = replay_find_nearest_snapshot(icount, &snapshot_icount);
+if (snapshot) {
+if (icount < replay_get_current_icount()
+|| replay_get_current_icount() < snapshot_icount) {
+vm_stop(RUN_STATE_RESTORE_VM);
+load_snapshot(snapshot, errp);
+}
+g_free(snapshot);
+}
+if (replay_get_current_icount() <= icount) {
+replay_break(icount, callback, NULL);
+vm_start()

[PATCH 12/13] replay: describe reverse debugging in docs/replay.txt

2020-06-26 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

This patch updates the documentation and describes usage of the reverse
debugging in QEMU+GDB.

Signed-off-by: Pavel Dovgalyuk 
---
 0 files changed

diff --git a/docs/replay.txt b/docs/replay.txt
index 70c27edb36..18d6169f3b 100644
--- a/docs/replay.txt
+++ b/docs/replay.txt
@@ -294,6 +294,39 @@ for recording and replaying must contain identical number 
of ports in record
 and replay modes, but their backends may differ.
 E.g., '-serial stdio' in record mode, and '-serial null' in replay mode.
 
+Reverse debugging
+-
+
+Reverse debugging allows "executing" the program in reverse direction.
+GDB remote protocol supports "reverse step" and "reverse continue"
+commands. The first one steps single instruction backwards in time,
+and the second one finds the last breakpoint in the past.
+
+Recorded executions may be used to enable reverse debugging. QEMU can't
+execute the code in backwards direction, but can load a snapshot and
+replay forward to find the desired position or breakpoint.
+
+The following GDB commands are supported:
+ - reverse-stepi (or rsi) - step one instruction backwards
+ - reverse-continue (or rc) - find last breakpoint in the past
+
+Reverse step loads the nearest snapshot and replays the execution until
+the required instruction is met.
+
+Reverse continue may include several passes of examining the execution
+between the snapshots. Each of the passes include the following steps:
+ 1. loading the snapshot
+ 2. replaying to examine the breakpoints
+ 3. if breakpoint or watchpoint was met
+- loading the snaphot again
+- replaying to the required breakpoint
+ 4. else
+- proceeding to the p.1 with the earlier snapshot
+
+Therefore usage of the reverse debugging requires at least one snapshot
+created in advance. See the "Snapshotting" section to learn about running
+record/replay and creating the snapshot in these modes.
+
 Replay log format
 -
 




Re: [PATCH 1/3] haiku build fix second batch

2020-06-26 Thread Peter Maydell
On Fri, 26 Jun 2020 at 14:02, David CARLIER  wrote:
>
> From 95ef79ddff73eebd1f1bec6673c2c68209fab107 Mon Sep 17 00:00:00 2001
> From: David Carlier 
> Date: Fri, 26 Jun 2020 13:56:14 +
> Subject: [PATCH 1/3] Include endian.h for Haiku to solve bswap* macros build
>  failure.
>
> Signed-off-by: David Carlier 

I'm afraid I'm now confused about which is the right version
of the various patches you've sent to the list. Our
https://wiki.qemu.org/Contribute/SubmitAPatch
documentation asks:
 * Include a meaningful cover letter
 * When resending patches add a version tag
 * even if you only change one patch, you resend the entire series
   and mark it as "v2"

Please could you send the whole set of patches you'd like
applied, with the subject header including "[PATCH v2]" and
with a cover letter email that describes the whole series?

thanks
-- PMM



Re: [PATCH 5/5] haiku build fix

2020-06-26 Thread Thomas Huth

On 26/06/2020 12.07, David CARLIER wrote:

 From 68d4d4312eccd212b4d2484e09425816ebd2346a Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 11:01:54 +
Subject: [PATCH 5/5] Last chunk of build fix

Signed-off-by: David Carlier 
---
  include/qemu/bswap.h | 2 ++
  util/Makefile.objs   | 2 +-
  util/compatfd.c  | 2 ++
  3 files changed, 5 insertions(+), 1 deletion(-)


 Hi David,

not directly related to this patch, but: do you know whether Haiku can 
also be installed non-interactively? We've got a set of VM-based 
compilation tests for FreeBSD, NetBSD and OpenBSD, see tests/vm/ in the 
QEMU sources (or run "make vm-help" for more information about the make 
targets) ... if something similar would be possible for Haiku, that 
would certainly help to prevent that the Haiku port bitrots so easily 
again...


 Thomas




Re: RFC: use VFIO over a UNIX domain socket to implement device offloading

2020-06-26 Thread Stefan Hajnoczi
On Thu, Jun 25, 2020 at 08:54:25PM -0700, John G Johnson wrote:
> 
> 
> > On Jun 23, 2020, at 5:27 AM, Stefan Hajnoczi  wrote:
> > 
> > On Thu, Jun 18, 2020 at 02:38:04PM -0700, John G Johnson wrote:
> >>> On Jun 15, 2020, at 3:49 AM, Stefan Hajnoczi  wrote:
> >>> An issue with file descriptor passing is that it's hard to revoke access
> >>> once the file descriptor has been passed. memfd supports sealing with
> >>> fnctl(F_ADD_SEALS) it doesn't revoke mmap(MAP_WRITE) on other processes.
> >>> 
> >>> Memory Protection Keys don't seem to be useful here either and their
> >>> availability is limited (see pkeys(7)).
> >>> 
> >>> One crazy idea is to use KVM as a sandbox for running the device and let
> >>> the vIOMMU control the page tables instead of the device (guest). That
> >>> way the hardware MMU provides memory translation, but I think this is
> >>> impractical because the guest environment is too different from the
> >>> Linux userspace environment.
> >>> 
> >>> As a starting point adding DMA_READ/DMA_WRITE messages would provide the
> >>> functionality and security. Unfortunately it makes DMA expensive and
> >>> performance will suffer.
> >>> 
> >> 
> >>Are you advocating for only using VFIO_USER_DMA_READ/WRITE and
> >> not passing FDs at all?  The performance penalty would be large for the
> >> cases where the client and server are equally trusted.  Or are you
> >> advocating for an option where the slower methods are used for cases
> >> where the server is less trusted?
> > 
> > I think the enforcing IOMMU should be optional (due to the performance
> > overhead) but part of the spec from the start.
> > 
> 
> 
>   With this in mind, we will collapse the current memory region
> messages (VFIO_USER_ADD_MEMORY_REGION and VFIO_USER_SUB_MEMORY_REGION)
> and the IOMMU messages (VFIO_USER_IOMMU_MAP and VFIO_USER_IOMMU_UNMAP)
> into new messages (VFIO_USER_DMA_MAP and VFIO_USER_DMA_UNMAP).  Their
> contents will be the same as the memory region messages.
> 
>   On a system without an IOMMU, the new messages will be used to
> export the system physical address space as DMA addresses.  On a system
> with an IOMMU they will be used to export the valid device DMA ranges
> programmed into the IOMMU by the guest.  This behavior matches how the
> existing QEMU VFIO object programs the host IOMMU.  The server will not
> be aware of whether the client is using an IOMMU.
>
>   In the QEMU VFIO implementation, will will add a ‘secure-dma’
> option that suppresses exporting mmap()able FDs to the server.  All
> DMA will use the slow path to be validated by the client before accessing
> guest memory.
> 
>   Is this acceptable to you (and Alex, of course)?

Sounds good to me.

Stefan


signature.asc
Description: PGP signature


Re: [PATCH v9 46/46] target/arm: Add arm,armv8.5-memtag to dtb

2020-06-26 Thread Peter Maydell
On Fri, 26 Jun 2020 at 04:32, Richard Henderson
 wrote:
>
> The mte-v4 linux arm kernel development branch requires these tags.
> It is still an open question as to whether they will be required
> for the final commit.
>
> Signed-off-by: Richard Henderson 
> ---
> v9: Split from patch creating the tag memory; sort to the end
> since it's not yet certain that it's a requirement.

Not going to bother reviewing this one for now since I'm pretty
sure it's moot :-)

thanks
-- PMM



Re: [PATCH v9 44/46] target/arm: Add allocation tag storage for system mode

2020-06-26 Thread Peter Maydell
On Fri, 26 Jun 2020 at 04:32, Richard Henderson
 wrote:
>
> Look up the physical address for the given virtual address,
> convert that to a tag physical address, and finally return
> the host address that backs it.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH v3 0/2] linux-user: support of semtimedop syscall

2020-06-26 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200626124612.58593-1-mky...@tachyum.com/



Hi,

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

Subject: [PATCH v3 0/2] linux-user: support of semtimedop syscall 
Type: series
Message-id: 20200626124612.58593-1-mky...@tachyum.com

=== 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
   611ac63..10f7ffa  master -> master
 * [new tag] 
patchew/1593177220-28143-1-git-send-email-bmeng...@gmail.com -> 
patchew/1593177220-28143-1-git-send-email-bmeng...@gmail.com
 - [tag update]  patchew/20200625184838.28172-1-phi...@redhat.com -> 
patchew/20200625184838.28172-1-phi...@redhat.com
 - [tag update]  
patchew/20200626033144.790098-1-richard.hender...@linaro.org -> 
patchew/20200626033144.790098-1-richard.hender...@linaro.org
 - [tag update]  
patchew/20200626092317.3875-1-mark.cave-ayl...@ilande.co.uk -> 
patchew/20200626092317.3875-1-mark.cave-ayl...@ilande.co.uk
 * [new tag] patchew/20200626124612.58593-1-mky...@tachyum.com -> 
patchew/20200626124612.58593-1-mky...@tachyum.com
 * [new tag] patchew/20200626130658.76498-1-vsement...@virtuozzo.com -> 
patchew/20200626130658.76498-1-vsement...@virtuozzo.com
 - [tag update]  patchew/cover.1592315226.git.bala...@eik.bme.hu -> 
patchew/cover.1592315226.git.bala...@eik.bme.hu
Switched to a new branch 'test'
9b6fb16 linux-user: support of semtimedop syscall
230a3ca linux-user: refactor ipc syscall

=== OUTPUT BEGIN ===
1/2 Checking commit 230a3cadaac4 (linux-user: refactor ipc syscall)
WARNING: architecture specific defines should be avoided
#20: FILE: linux-user/syscall.c:817:
+#ifdef __s390x__

WARNING: architecture specific defines should be avoided
#35: FILE: linux-user/syscall.c:4061:
+#ifdef __s390x__

WARNING: architecture specific defines should be avoided
#49: FILE: linux-user/syscall.c:4076:
+#ifdef __NR_ipc

WARNING: architecture specific defines should be avoided
#50: FILE: linux-user/syscall.c:4077:
+#if defined(__sparc__)

ERROR: Macros with complex values should be enclosed in parenthesis
#52: FILE: linux-user/syscall.c:4079:
+#define MSGRCV_ARGS(__msgp, __msgtyp) __msgp, __msgtyp

ERROR: Macros with complex values should be enclosed in parenthesis
#58: FILE: linux-user/syscall.c:4085:
+#define MSGRCV_ARGS(__msgp, __msgtyp) \
+((long int[]){(long int)__msgp, __msgtyp}), 0

total: 2 errors, 4 warnings, 55 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 9b6fb16d5bb7 (linux-user: support of semtimedop syscall)
WARNING: architecture specific defines should be avoided
#40: FILE: linux-user/syscall.c:3891:
+#ifdef __s390x__

ERROR: Macros with complex values should be enclosed in parenthesis
#41: FILE: linux-user/syscall.c:3892:
+#define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
+  (__nsops), (__timeout), (__sops)

ERROR: Macros with complex values should be enclosed in parenthesis
#44: FILE: linux-user/syscall.c:3895:
+#define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
+  (__nsops), 0, (__sops), (__timeout)

total: 2 errors, 1 warnings, 98 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/20200626124612.58593-1-mky...@tachyum.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[PATCH] MAINTAINERS: Add an entry for OpenSBI firmware

2020-06-26 Thread Bin Meng
List me as the maintainer for OpenSBI firmware related files.

Signed-off-by: Bin Meng 
---

 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1b40446..b0e2dd2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2609,6 +2609,13 @@ F: tests/uefi-test-tools/
 F: .gitlab-ci.d/edk2.yml
 F: .gitlab-ci.d/edk2/
 
+OpenSBI Firmware
+M: Bin Meng 
+S: Supported
+F: pc-bios/opensbi-*
+F: .gitlab-ci.d/opensbi.yml
+F: .gitlab-ci.d/opensbi/
+
 Usermode Emulation
 --
 Overall usermode emulation
-- 
2.7.4




Re: [PATCH v9 43/46] target/arm: Create tagged ram when MTE is enabled

2020-06-26 Thread Peter Maydell
On Fri, 26 Jun 2020 at 04:32, Richard Henderson
 wrote:
>
> Signed-off-by: Richard Henderson 
> ---
> v5: Assign cs->num_ases to the final value first.
> Downgrade to ID_AA64PFR1.MTE=1 if tag memory is not available.
> v6: Add secure tag memory for EL3.
> v8: Add arm,armv8.5-memtag.
> v9: Split arm,armv8.5-memtag to another patch;
> adjust how address spaces are allocated.

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH v5 09/11] macio: Add dummy screamer register area

2020-06-26 Thread Mark Cave-Ayland
On 16/06/2020 14:47, BALATON Zoltan wrote:

> The only thing this returns is an idle status so the firmware
> continues, otherwise just ignores and logs access for debugging. This
> is a stop gap until proper implementation of this device lands.
> 
> Signed-off-by: BALATON Zoltan 
> ---
>  hw/misc/macio/macio.c | 34 ++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
> index 8ba7af073c..c7e8556ca6 100644
> --- a/hw/misc/macio/macio.c
> +++ b/hw/misc/macio/macio.c
> @@ -26,6 +26,7 @@
>  #include "qemu/osdep.h"
>  #include "qapi/error.h"
>  #include "qemu/module.h"
> +#include "qemu/log.h"
>  #include "hw/ppc/mac.h"
>  #include "hw/misc/macio/cuda.h"
>  #include "hw/pci/pci.h"
> @@ -94,6 +95,33 @@ static void macio_bar_setup(MacIOState *s)
>  macio_escc_legacy_setup(s);
>  }
>  
> +#define AWAC_CODEC_STATUS_REG 0x20
> +
> +#define AWAC_MAKER_CRYSTAL 1
> +#define AWAC_REV_SCREAMER 3
> +#define AWAC_VALID_DATA 0x40
> +
> +static uint64_t screamer_read(void *opaque, hwaddr addr, unsigned size)
> +{
> +qemu_log_mask(LOG_UNIMP,
> +  "macio: screamer read %" HWADDR_PRIx "  %d\n", addr, size);
> +return (addr == AWAC_CODEC_STATUS_REG ? AWAC_VALID_DATA << 8 |
> +AWAC_MAKER_CRYSTAL << 16 | AWAC_REV_SCREAMER << 20 : 0);
> +}
> +
> +static void screamer_write(void *opaque, hwaddr addr,
> +   uint64_t val, unsigned size)
> +{
> +qemu_log_mask(LOG_UNIMP,
> +  "macio: screamer write %" HWADDR_PRIx "  %d = %"PRIx64"\n",
> +  addr, size, val);
> +}
> +
> +const MemoryRegionOps screamer_ops = {
> +.read = screamer_read,
> +.write = screamer_write,
> +};

static const.

>  static void macio_common_realize(PCIDevice *d, Error **errp)
>  {
>  MacIOState *s = MACIO(d);
> @@ -149,6 +177,7 @@ static void macio_oldworld_realize(PCIDevice *d, Error 
> **errp)
>  DeviceState *pic_dev = DEVICE(os->pic);
>  Error *err = NULL;
>  SysBusDevice *sysbus_dev;
> +MemoryRegion *screamer = g_new(MemoryRegion, 1);
>  
>  macio_common_realize(d, &err);
>  if (err) {
> @@ -208,6 +237,11 @@ static void macio_oldworld_realize(PCIDevice *d, Error 
> **errp)
>  error_propagate(errp, err);
>  return;
>  }
> +
> +/* Dummy screamer sound device */
> +memory_region_init_io(screamer, OBJECT(d), &screamer_ops, NULL,
> +  "screamer", 0x2000);
> +memory_region_add_subregion(&s->bar, 0x14000, screamer);
>  }
>  
>  static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, int index)

Again I'm wary of adding empty devices here as the main issue around the 
screamer
code (and why it has not been submitted upstream) is that it can cause random 
hangs
for MacOS on startup. Does it regress any MacOS 9 through 10.5 boot tests?

FWIW I've rebased the latest version of my screamer branch at
https://github.com/mcayland/qemu/commits/screamer to git master if you want to 
see if
any noise comes out.


ATB,

Mark.



Re: [PATCH] timer: Handle decrements of PIT counter

2020-06-26 Thread Roman Bolshakov
On Tue, Jun 23, 2020 at 11:00:24PM -0400, Kevin O'Connor wrote:
> On Sat, Jun 13, 2020 at 02:19:12PM +0300, Roman Bolshakov wrote:
> > There's a fallback to PIT if TSC is not present but it doesn't work
> > properly. It prevents boot from floppy on isapc and 486 cpu [1][2].
> > 
> > SeaBIOS configures PIT in Mode 2. PIT counter is decremented in the mode
> > but timer_adjust_bits() thinks that the counter overflows and increases
> > 32-bit tick counter on each detected "overflow". Invalid overflow
> > detection results in 55ms time advance (1 / 18.2Hz) on each read from
> > PIT counter. So all timers expire much faster and 5-second floppy
> > timeout expires in 83 real microseconds (or just a bit longer).
> > 
> > Provide counter direction to timer_adjust_bits() and normalize the
> > counter to advance ticks in monotonically increasing TimerLast.
> 
> Good catch.  Could we fix it using the patch below instead though?
> 
> -Kevin
> 
> 
> --- a/src/hw/timer.c
> +++ b/src/hw/timer.c
> @@ -180,7 +180,7 @@ timer_read(void)
>  // Read from PIT.
>  outb(PM_SEL_READBACK | PM_READ_VALUE | PM_READ_COUNTER0, PORT_PIT_MODE);
>  u16 v = inb(PORT_PIT_COUNTER0) | (inb(PORT_PIT_COUNTER0) << 8);
> -return timer_adjust_bits(v, 0x);
> +return timer_adjust_bits(-v, 0x);
>  }
>  
>  // Return the TSC value that is 'msecs' time in the future.

Hi Kevin,

I like the approach much more. Initial count value is 0, PIT rearms the
timer when 1 is hit, unary negation on unsigned u16 fits perfectly, then
timer_adjust_bits recieves 0, 1, 2, ... and timer is rearmed at 0x.

Do you want me to send v2 or you plan to apply the fix on your own?

If you plan to apply it on your own, here are the tags:

Reviewed-by: Roman Bolshakov 
Tested-by: Roman Bolshakov 

Thanks,
Roman



Re: [PATCH v5 08/11] mac_oldworld: Add machine ID register

2020-06-26 Thread Mark Cave-Ayland
On 16/06/2020 14:47, BALATON Zoltan wrote:

> The G3 beige machine has a machine ID register that is accessed by the
> firmware to deternine the board config. Add basic emulation of it.
> 
> Signed-off-by: BALATON Zoltan 
> ---
> v4: Move MermoryRegion to MachineState, use constants
> 
>  hw/ppc/mac.h  |  1 +
>  hw/ppc/mac_oldworld.c | 24 
>  2 files changed, 25 insertions(+)
> 
> diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
> index 79ccf8775d..32b7928a96 100644
> --- a/hw/ppc/mac.h
> +++ b/hw/ppc/mac.h
> @@ -64,6 +64,7 @@ typedef struct HeathrowMachineState {
>  /*< private >*/
>  MachineState parent;
>  
> +MemoryRegion machine_id;
>  PCIDevice *macio;
>  } HeathrowMachineState;
>  
> diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
> index 13562e26e6..14a191ff88 100644
> --- a/hw/ppc/mac_oldworld.c
> +++ b/hw/ppc/mac_oldworld.c
> @@ -52,6 +52,9 @@
>  
>  #define MAX_IDE_BUS 2
>  #define CFG_ADDR 0xf510
> +#define MACHINE_ID_ADDR 0xff04
> +#define MACHINE_ID_VAL 0x3d8c
> +
>  #define TBFREQ 1660UL
>  #define CLOCKFREQ 26600UL
>  #define BUSFREQ 6600UL
> @@ -89,6 +92,22 @@ static void ppc_heathrow_cpu_reset(void *opaque)
>  cpu_reset(CPU(cpu));
>  }
>  
> +static uint64_t machine_id_read(void *opaque, hwaddr addr, unsigned size)
> +{
> +return (addr == 0 && size == 2 ? MACHINE_ID_VAL : 0);
> +}
> +
> +static void machine_id_write(void *opaque, hwaddr addr,
> + uint64_t val, unsigned size)
> +{
> +return;
> +}
> +
> +const MemoryRegionOps machine_id_reg_ops = {
> +.read = machine_id_read,
> +.write = machine_id_write,
> +};

static const here?

>  static void ppc_heathrow_init(MachineState *machine)
>  {
>  HeathrowMachineState *hm = HEATHROW_MACHINE(machine);
> @@ -239,6 +258,11 @@ static void ppc_heathrow_init(MachineState *machine)
>  }
>  }
>  
> +memory_region_init_io(&hm->machine_id, OBJECT(machine),
> +  &machine_id_reg_ops, NULL, "machine_id", 2);
> +memory_region_add_subregion(get_system_memory(), MACHINE_ID_ADDR,
> +&hm->machine_id);
> +
>  /* XXX: we register only 1 output pin for heathrow PIC */
>  pic_dev = qdev_new(TYPE_HEATHROW);
>  sysbus_realize_and_unref(SYS_BUS_DEVICE(pic_dev), &error_fatal);

Have you done some boot tests with MacOS 9 and X to ensure that it doesn't 
cause any
regressions there?


ATB,

Mark.



[PATCH] migration/block-dirty-bitmap: fix add_bitmaps_to_list

2020-06-26 Thread Vladimir Sementsov-Ogievskiy
We shouldn't fail, if found unnamed bitmap in a unnamed node or node
with auto-generated node name, as bitmap migration ignores such bitmaps
at all.

Fixes: 82640edb88faa
Fixes: 4ff5cc121b089
Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 migration/block-dirty-bitmap.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
index 47bc0f650c..b0dbf9eeed 100644
--- a/migration/block-dirty-bitmap.c
+++ b/migration/block-dirty-bitmap.c
@@ -274,7 +274,11 @@ static int add_bitmaps_to_list(BlockDriverState *bs, const 
char *bs_name)
 DirtyBitmapMigBitmapState *dbms;
 Error *local_err = NULL;
 
-bitmap = bdrv_dirty_bitmap_first(bs);
+FOR_EACH_DIRTY_BITMAP(bs, bitmap) {
+if (bdrv_dirty_bitmap_name(bitmap)) {
+break;
+}
+}
 if (!bitmap) {
 return 0;
 }
-- 
2.18.0




[PATCH 3/3] haiku build fix

2020-06-26 Thread David CARLIER
>From a548479cab82200d9df33a70f24aeebb00eb70ad Mon Sep 17 00:00:00 2001
From: David Carlier 
Date: Fri, 26 Jun 2020 13:58:34 +
Subject: [PATCH 3/3] syscall skipped for haiku used only in qemu_signalfd
 anyway

Signed-off-by: David Carlier 
---
 util/compatfd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/util/compatfd.c b/util/compatfd.c
index c296f55d14..ee47dd8089 100644
--- a/util/compatfd.c
+++ b/util/compatfd.c
@@ -16,7 +16,9 @@
 #include "qemu/osdep.h"
 #include "qemu/thread.h"

+#if defined(CONFIG_SIGNALFD)
 #include 
+#endif

 struct sigfd_compat_info
 {
-- 
2.26.0



Re: [PATCH] gitlab-ci: Fix the change rules after moving the YML files

2020-06-26 Thread Bin Meng
Hi Philippe,

On Thu, Jun 25, 2020 at 11:28 PM Philippe Mathieu-Daudé
 wrote:
>
> On 6/25/20 5:16 PM, Thomas Huth wrote:
> > The edk2.yml and opensbi.yml files have recently been moved/renamed,
> > but the change has not been reflected in the rules in the YML files
> > yet.
> >
> > Fixes: 922febe2af ("Move edk2 and opensbi YAML files to .gitlab-ci.d 
> > folder")
> > Signed-off-by: Thomas Huth 
> > ---
> >  .gitlab-ci.d/edk2.yml| 2 +-
> >  .gitlab-ci.d/opensbi.yml | 2 +-
> >  2 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/.gitlab-ci.d/edk2.yml b/.gitlab-ci.d/edk2.yml
> > index 088ba4b43a..a9990b7147 100644
> > --- a/.gitlab-ci.d/edk2.yml
> > +++ b/.gitlab-ci.d/edk2.yml
> > @@ -2,7 +2,7 @@ docker-edk2:
> >   stage: build
> >   rules: # Only run this job when the Dockerfile is modified
> >   - changes:
> > -   - .gitlab-ci-edk2.yml
> > +   - .gitlab-ci.d/edk2.yml
>
> Thanks!
>
> > - .gitlab-ci.d/edk2/Dockerfile
> > when: always
> >   image: docker:19.03.1
> > diff --git a/.gitlab-ci.d/opensbi.yml b/.gitlab-ci.d/opensbi.yml
> > index dd051c0124..6a1750784a 100644
> > --- a/.gitlab-ci.d/opensbi.yml
> > +++ b/.gitlab-ci.d/opensbi.yml
> > @@ -2,7 +2,7 @@ docker-opensbi:
> >   stage: build
> >   rules: # Only run this job when the Dockerfile is modified
> >   - changes:
> > -   - .gitlab-ci-opensbi.yml
> > +   - .gitlab-ci.d/opensbi.yml
>
> FWIW:
>
> ./scripts/get_maintainer.pl -f .gitlab-ci.d/opensbi.yml
> get_maintainer.pl: No maintainers found, printing recent contributors.
> get_maintainer.pl: Do not blindly cc: them on patches!  Use common sense.
>
> Missed in c6fc0fc1a71a (apparently patchew bot was down when Bin
> sent the patch).

I will add an entry to MAINTAINERS file for this. Thanks!

>
> Cc'ing Alistair who Acked the patch (also missed in the same commit,
> see https://www.mail-archive.com/qemu-devel@nongnu.org/msg682407.html)
>
> > - .gitlab-ci.d/opensbi/Dockerfile
> > when: always
> >   image: docker:19.03.1
> >
>
> Reviewed-by: Philippe Mathieu-Daudé 

Regards,
Bin



<    1   2   3   4   5   6   >