[PULL 37/55] disas/nanomips: Remove argument passing by ref

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Replaced argument passing by reference with passing by address.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-24-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 8b4bc910a4..9647f1a8e3 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -560,7 +560,7 @@ static uint64 extract_op_code_value(const uint16 *data, int 
size)
  *  disassembly string  - on error will constain error string
  */
 static int Disassemble(const uint16 *data, char **dis,
- TABLE_ENTRY_TYPE & type, const Pool *table,
+ TABLE_ENTRY_TYPE *type, const Pool *table,
  int table_size, Dis_info *info)
 {
 for (int i = 0; i < table_size; i++) {
@@ -585,7 +585,7 @@ static int Disassemble(const uint16 *data, char **dis,
 "disassembler failure - bad table entry");
 return -6;
 }
-type = table[i].type;
+*type = table[i].type;
 *dis = dis_fn(op_code, info);
 return table[i].instructions_size;
 } else {
@@ -21914,7 +21914,7 @@ static int nanomips_dis(char **buf,
 uint16 bits[3] = {one, two, three};
 
 TABLE_ENTRY_TYPE type;
-int size = Disassemble(bits, buf, type, MAJOR, 2, info);
+int size = Disassemble(bits, buf, &type, MAJOR, 2, info);
 return size;
 }
 
-- 
2.37.3




[PULL 32/55] disas/nanomips: Prevent memory leaking

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

g_autofree attribute is added for every dynamically allocated string to
prevent memory leaking.

The implementation of the several functions that work with dynamically
allocated strings is slightly changed so we can add those attributes.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-19-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 96 --
 1 file changed, 51 insertions(+), 45 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 3a3a9a9b69..ce93fdad62 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -1937,7 +1937,7 @@ static char *ADDIUPC_32_(uint64 instruction, Dis_info 
*info)
 int64 s_value = extract_s__se21_0_20_to_1_s1(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("ADDIUPC %s, %s", rt, s);
 }
@@ -1959,7 +1959,7 @@ static char *ADDIUPC_48_(uint64 instruction, Dis_info 
*info)
 int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = ADDRESS(s_value, 6, info);
+g_autofree char *s = ADDRESS(s_value, 6, info);
 
 return img_format("ADDIUPC %s, %s", rt, s);
 }
@@ -2417,7 +2417,7 @@ static char *ALUIPC(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("ALUIPC %s, %%pcrel_hi(%s)", rt, s);
 }
@@ -2574,7 +2574,7 @@ static char *BALC_16_(uint64 instruction, Dis_info *info)
 {
 int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 2, info);
+g_autofree char *s = ADDRESS(s_value, 2, info);
 
 return img_format("BALC %s", s);
 }
@@ -2594,7 +2594,7 @@ static char *BALC_32_(uint64 instruction, Dis_info *info)
 {
 int64 s_value = extract_s__se25_0_24_to_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BALC %s", s);
 }
@@ -2639,7 +2639,7 @@ static char *BBEQZC(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BBEQZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s);
 }
@@ -2662,7 +2662,7 @@ static char *BBNEZC(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BBNEZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s);
 }
@@ -2682,7 +2682,7 @@ static char *BC_16_(uint64 instruction, Dis_info *info)
 {
 int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 2, info);
+g_autofree char *s = ADDRESS(s_value, 2, info);
 
 return img_format("BC %s", s);
 }
@@ -2702,7 +2702,7 @@ static char *BC_32_(uint64 instruction, Dis_info *info)
 {
 int64 s_value = extract_s__se25_0_24_to_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BC %s", s);
 }
@@ -2724,7 +2724,7 @@ static char *BC1EQZC(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se14_0_13_to_1_s1(instruction);
 
 const char *ft = FPR(ft_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BC1EQZC %s, %s", ft, s);
 }
@@ -2746,7 +2746,7 @@ static char *BC1NEZC(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se14_0_13_to_1_s1(instruction);
 
 const char *ft = FPR(ft_value);
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BC1NEZC %s, %s", ft, s);
 }
@@ -2767,7 +2767,7 @@ static char *BC2EQZC(uint64 instruction, Dis_info *info)
 uint64 ct_value = extract_ct_25_24_23_22_21(instruction);
 int64 s_value = extract_s__se14_0_13_to_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BC2EQZC CP%" PRIu64 ", %s", ct_value, s);
 }
@@ -2788,7 +2788,7 @@ static char *BC2NEZC(uint64 instruction, Dis_info *info)
 uint64 ct_value = extract_ct_25_24_23_22_21(instruction);
 int64 s_value = extract_s__se14_0_13_to_1_s1(instruction);
 
-char *s = ADDRESS(s_value, 4, info);
+g_autofree char *s = ADDRESS(s_value, 4, info);
 
 return img_format("BC2NEZ

[PULL 35/55] disas/nanomips: Replace exception handling

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Since there's no support for exception handling in C, the try-catch
blocks have been deleted, and throw clauses are replaced. When a runtime
error happens, we're printing out the error message. Disassembling of
the current instruction interrupts. This behavior is achieved by adding
sigsetjmp() to discard further disassembling after the error message
prints and by adding the siglongjmp() function to imitate throwing an
error. The goal was to maintain the same output as it was.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-22-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 100 -
 1 file changed, 45 insertions(+), 55 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 73329462ee..1832c2d3cf 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -31,7 +31,6 @@
 #include "disas/dis-asm.h"
 
 #include 
-#include 
 #include 
 #include 
 
@@ -133,10 +132,9 @@ static uint64 renumber_registers(uint64 index, uint64 
*register_list,
 return register_list[index];
 }
 
-throw std::runtime_error(img_format(
-   "Invalid register mapping index %" PRIu64
-   ", size of list = %zu",
-   index, register_list_size));
+info->fprintf_func(info->stream, "Invalid register mapping index %" PRIu64
+   ", size of list = %zu", index, register_list_size);
+siglongjmp(info->buf, 1);
 }
 
 
@@ -466,8 +464,9 @@ static const char *GPR(uint64 reg, Dis_info *info)
 return gpr_reg[reg];
 }
 
-throw std::runtime_error(img_format("Invalid GPR register index %" PRIu64,
- reg));
+info->fprintf_func(info->stream, "Invalid GPR register index %" PRIu64,
+   reg);
+siglongjmp(info->buf, 1);
 }
 
 
@@ -503,8 +502,9 @@ static const char *FPR(uint64 reg, Dis_info *info)
 return fpr_reg[reg];
 }
 
-throw std::runtime_error(img_format("Invalid FPR register index %" PRIu64,
- reg));
+info->fprintf_func(info->stream, "Invalid FPR register index %" PRIu64,
+   reg);
+siglongjmp(info->buf, 1);
 }
 
 
@@ -518,8 +518,9 @@ static const char *AC(uint64 reg, Dis_info *info)
 return ac_reg[reg];
 }
 
-throw std::runtime_error(img_format("Invalid AC register index %" PRIu64,
- reg));
+info->fprintf_func(info->stream, "Invalid AC register index %" PRIu64,
+   reg);
+siglongjmp(info->buf, 1);
 }
 
 
@@ -562,55 +563,38 @@ static int Disassemble(const uint16 *data, char **dis,
  TABLE_ENTRY_TYPE & type, const Pool *table,
  int table_size, Dis_info *info)
 {
-try
-{
-for (int i = 0; i < table_size; i++) {
-uint64 op_code = extract_op_code_value(data,
- table[i].instructions_size);
-if ((op_code & table[i].mask) == table[i].value) {
-/* possible match */
-conditional_function cond = table[i].condition;
-if ((cond == NULL) || cond(op_code)) {
-try
-{
-if (table[i].type == pool) {
-return Disassemble(data, dis, type,
-   table[i].next_table,
-   table[i].next_table_size,
-   info);
-} else if ((table[i].type == instruction) ||
-   (table[i].type == call_instruction) ||
-   (table[i].type == branch_instruction) ||
-   (table[i].type == return_instruction)) {
-disassembly_function dis_fn = table[i].disassembly;
-if (dis_fn == 0) {
-*dis = g_strdup(
-"disassembler failure - bad table entry");
-return -6;
-}
-type = table[i].type;
-*dis = dis_fn(op_code, info);
-return table[i].instructions_size;
-} else {
-*dis = g_strdup("reserved instruction");
-return -2;
-}
-}
-catch (std::runtime_error & e)
-{
-*dis = g_strdup(e.what());
-return -3;  /* runtime error */
+for (int i = 0; i < table_size; i++) {
+uint64 op_code = extract_op_code_value(data,
+  

[PULL 33/55] disas/nanomips: Remove function overloading

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Disassemble function that calls the other variant of it is deleted.
Where it is called, now we're directly calling the other implementation.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-20-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index ce93fdad62..85f5784770 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -21917,12 +21917,6 @@ static const Pool MAJOR[2] = {
0x0 },/* P16 */
 };
 
-static int Disassemble(const uint16 *data, char **dis,
-   TABLE_ENTRY_TYPE & type, Dis_info *info)
-{
-return Disassemble(data, dis, type, MAJOR, 2, info);
-}
-
 static int nanomips_dis(char **buf,
  Dis_info *info,
  unsigned short one,
@@ -21932,7 +21926,7 @@ static int nanomips_dis(char **buf,
 uint16 bits[3] = {one, two, three};
 
 TABLE_ENTRY_TYPE type;
-int size = Disassemble(bits, buf, type, info);
+int size = Disassemble(bits, buf, type, MAJOR, 2, info);
 return size;
 }
 
-- 
2.37.3




[PULL 42/55] hw/isa/piix3: Add size constraints to rcr_ops

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

According to the PIIX3 datasheet, the reset control register is one byte in 
size.
Moreover, PIIX4 has it, so add it to PIIX3 as well.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-5-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 04895ce2e5..72dbf688d9 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -290,7 +290,11 @@ static uint64_t rcr_read(void *opaque, hwaddr addr, 
unsigned len)
 static const MemoryRegionOps rcr_ops = {
 .read = rcr_read,
 .write = rcr_write,
-.endianness = DEVICE_LITTLE_ENDIAN
+.endianness = DEVICE_LITTLE_ENDIAN,
+.impl = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
 };
 
 static void pci_piix3_realize(PCIDevice *dev, Error **errp)
-- 
2.37.3




[PULL 39/55] disas/mips: Fix branch displacement for BEQZC and BNEZC

2022-10-30 Thread Philippe Mathieu-Daudé
From: David Daney 

disas/mips.c got added in commit 6643d27ea0 ("MIPS disas support")
apparently based on binutils tag 'gdb_6_1-branchpoint' [1].
Back then, MIPSr6 was not supported (added in binutils commit
7361da2c952 during 2014 [2]).

Binutils codebase diverged so much over the last 18 years, it is
not possible to simply cherry-pick their changes, so fix it BEQZC /
BNEZC 21-bit signed branch displacement locally.

[1] 
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=opcodes/mips-dis.c;hb=refs/tags/gdb_6_1-branchpoint
[2] https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=7361da2c952

Fixes: 31837be3ee ("target-mips: add compact and CP1 branches")
Signed-off-by: David Daney 
Reviewed-by: Marcin Nowakowski 
[PMD: Added commit description]
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20221014112322.61119-1-phi...@fungible.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/mips.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index b9a5204304..5aacacb2c8 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public 
License
 along with this program; if not, see .  */
 
 #include "qemu/osdep.h"
+#include "qemu/bitops.h"
 #include "disas/dis-asm.h"
 
 /* mips.h.  Mips opcode list for GDB, the GNU debugger.
@@ -1334,9 +1335,9 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"balc","+p",   0xe800, 0xfc00, UBD|WR_31,0, 
I32R6},
 {"bc",  "+p",   0xc800, 0xfc00, UBD|WR_31,0, 
I32R6},
 {"jic", "t,o",  0xd800, 0xffe0, UBD|RD_t, 0, 
I32R6},
-{"beqzc",   "s,+p", 0xd800, 0xfc00, CBD|RD_s, 0, 
I32R6},
+{"beqzc",   "s,+q", 0xd800, 0xfc00, CBD|RD_s, 0, 
I32R6},
 {"jialc",   "t,o",  0xf800, 0xffe0, UBD|RD_t, 0, 
I32R6},
-{"bnezc",   "s,+p", 0xf800, 0xfc00, CBD|RD_s, 0, 
I32R6},
+{"bnezc",   "s,+q", 0xf800, 0xfc00, CBD|RD_s, 0, 
I32R6},
 {"beqzalc", "s,t,p",0x2000, 0xffe0, CBD|RD_s|RD_t,0, 
I32R6},
 {"bovc","s,t,p",0x2000, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
 {"beqc","s,t,p",0x2000, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
@@ -4462,6 +4463,13 @@ print_insn_args (const char *d,
 (*info->print_address_func) (info->target, info);
 break;
 
+case 'q':
+/* Sign extend the displacement with 21 bits.  */
+delta = sextract32(l, OP_SH_DELTA, 21);
+info->target = (delta << 2) + pc + INSNLEN;
+(*info->print_address_func) (info->target, info);
+break;
+
case 't': /* Coprocessor 0 reg name */
  (*info->fprintf_func) (info->stream, "%s",
 mips_cp0_names[(l >> OP_SH_RT) &
-- 
2.37.3




[PULL 14/55] hw: Remove unused MAX_IDE_BUS define

2022-10-30 Thread Philippe Mathieu-Daudé
From: BALATON Zoltan 

Several machines have an unused MAX_IDE_BUS define. Remove it from
these machines that don't need it.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20220917115136.a32ef746...@zero.eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/alpha/dp264.c| 2 --
 hw/hppa/machine.c   | 2 --
 hw/mips/fuloong2e.c | 1 -
 hw/mips/malta.c | 2 --
 hw/ppc/prep.c   | 2 --
 hw/sparc64/sun4u.c  | 1 -
 6 files changed, 10 deletions(-)

diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index f4349eba83..c502c8c62a 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -20,8 +20,6 @@
 #include "qemu/datadir.h"
 #include "net/net.h"
 
-#define MAX_IDE_BUS 2
-
 static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
 {
 if (((addr >> 41) & 3) == 2) {
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index e53d5f0fa7..355b3aac2e 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -30,8 +30,6 @@
 #include "qemu/log.h"
 #include "net/net.h"
 
-#define MAX_IDE_BUS 2
-
 #define MIN_SEABIOS_HPPA_VERSION 6 /* require at least this fw version */
 
 #define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index b478483706..50c61f0e4a 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -49,7 +49,6 @@
 
 /* Fuloong 2e has a 512k flash: Winbond W39L040AP70Z */
 #define BIOS_SIZE   (512 * KiB)
-#define MAX_IDE_BUS 2
 
 /*
  * PMON is not part of qemu and released with BSD license, anyone
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 0e932988e0..5099ed9592 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -69,8 +69,6 @@
 
 #define FLASH_SIZE  0x40
 
-#define MAX_IDE_BUS 2
-
 typedef struct {
 MemoryRegion iomem;
 MemoryRegion iomem_lo; /* 0 - 0x900 */
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index f08714f2ec..fcbe4c5837 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -50,8 +50,6 @@
 /* SMP is not enabled, for now */
 #define MAX_CPUS 1
 
-#define MAX_IDE_BUS 2
-
 #define CFG_ADDR 0xf510
 
 #define KERNEL_LOAD_ADDR 0x0100
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 0e27715ac4..387181ff77 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -66,7 +66,6 @@
 #define PBM_PCI_IO_BASE  (PBM_SPECIAL_BASE + 0x0200ULL)
 #define PROM_FILENAME"openbios-sparc64"
 #define NVRAM_SIZE   0x2000
-#define MAX_IDE_BUS  2
 #define BIOS_CFG_IOPORT  0x510
 #define FW_CFG_SPARC64_WIDTH (FW_CFG_ARCH_LOCAL + 0x00)
 #define FW_CFG_SPARC64_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
-- 
2.37.3




[PULL 44/55] hw/isa/piix3: Prefer pci_address_space() over get_system_memory()

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

get_system_memory() accesses global state while pci_address_space() uses
whatever has been passed to the device instance, so avoid the global.
Moreover, PIIX4 uses pci_address_space() here as well.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-7-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 723ad0a896..0bea4aefe7 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -301,7 +301,7 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 PIIX3State *d = PIIX3_PCI_DEVICE(dev);
 ISABus *isa_bus;
 
-isa_bus = isa_bus_new(DEVICE(d), get_system_memory(),
+isa_bus = isa_bus_new(DEVICE(d), pci_address_space(dev),
   pci_address_space_io(dev), errp);
 if (!isa_bus) {
 return;
-- 
2.37.3




[PULL 48/55] hw/mips/malta: Reuse dev variable

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

While at it, move the assignments closer to where they are used.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-26-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/mips/malta.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 5099ed9592..6ac811763c 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -1237,7 +1237,6 @@ void mips_malta_init(MachineState *machine)
 MaltaState *s;
 PCIDevice *piix4;
 DeviceState *dev;
-DeviceState *pm_dev;
 
 s = MIPS_MALTA(qdev_new(TYPE_MIPS_MALTA));
 sysbus_realize_and_unref(SYS_BUS_DEVICE(s), &error_fatal);
@@ -1403,13 +1402,13 @@ void mips_malta_init(MachineState *machine)
 TYPE_PIIX4_PCI_DEVICE);
 dev = DEVICE(piix4);
 isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
-pm_dev = DEVICE(object_resolve_path_component(OBJECT(dev), "pm"));
-smbus = I2C_BUS(qdev_get_child_bus(pm_dev, "i2c"));
 
 /* Interrupt controller */
 qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq);
 
 /* generate SPD EEPROM data */
+dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm"));
+smbus = I2C_BUS(qdev_get_child_bus(dev, "i2c"));
 generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size);
 generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]);
 smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);
-- 
2.37.3




[PULL 40/55] hw/i386/pc: Create DMA controllers in south bridges

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Just like in the real hardware (and in PIIX4), create the DMA
controllers in the south bridges.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-2-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c  | 3 ---
 hw/i386/pc_piix.c | 2 ++
 hw/isa/Kconfig| 2 ++
 hw/isa/lpc_ich9.c | 3 +++
 hw/isa/piix3.c| 9 +++--
 5 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 768982ae9a..b39ecd4d0c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -47,7 +47,6 @@
 #include "multiboot.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "hw/intc/i8259.h"
-#include "hw/dma/i8257.h"
 #include "hw/timer/i8254.h"
 #include "hw/input/i8042.h"
 #include "hw/irq.h"
@@ -1320,8 +1319,6 @@ void pc_basic_device_init(struct PCMachineState *pcms,
 pcspk_init(pcms->pcspk, isa_bus, pit);
 }
 
-i8257_dma_init(isa_bus, 0);
-
 /* Super I/O */
 pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled,
 pcms->vmport != ON_OFF_AUTO_ON);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 0b1a79c0fa..7a55b9ca8e 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -26,6 +26,7 @@
 #include CONFIG_DEVICES
 
 #include "qemu/units.h"
+#include "hw/dma/i8257.h"
 #include "hw/loader.h"
 #include "hw/i386/x86.h"
 #include "hw/i386/pc.h"
@@ -225,6 +226,7 @@ static void pc_init1(MachineState *machine,
 pci_bus = NULL;
 isa_bus = isa_bus_new(NULL, get_system_memory(), system_io,
   &error_abort);
+i8257_dma_init(isa_bus, 0);
 pcms->hpet_enabled = false;
 }
 isa_bus_irqs(isa_bus, x86ms->gsi);
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 20de7e9294..60aad28800 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -33,6 +33,7 @@ config PC87312
 
 config PIIX3
 bool
+select I8257
 select ISA_BUS
 
 config PIIX4
@@ -68,6 +69,7 @@ config LPC_ICH9
 bool
 # For historical reasons, SuperIO devices are created in the board
 # for ICH9.
+select I8257
 select ISA_BUS
 select ACPI_SMBUS
 select ACPI_X86_ICH
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 4553b5925b..8694e58b21 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -34,6 +34,7 @@
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include "qemu/range.h"
+#include "hw/dma/i8257.h"
 #include "hw/isa/isa.h"
 #include "migration/vmstate.h"
 #include "hw/irq.h"
@@ -722,6 +723,8 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp)
 qdev_init_gpio_out_named(dev, lpc->gsi, ICH9_GPIO_GSI, GSI_NUM_PINS);
 
 isa_bus_irqs(isa_bus, lpc->gsi);
+
+i8257_dma_init(isa_bus, 0);
 }
 
 static bool ich9_rst_cnt_needed(void *opaque)
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 48f9ab1096..44a9998752 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 #include "qemu/range.h"
 #include "qapi/error.h"
+#include "hw/dma/i8257.h"
 #include "hw/southbridge/piix.h"
 #include "hw/irq.h"
 #include "hw/isa/isa.h"
@@ -295,9 +296,11 @@ static const MemoryRegionOps rcr_ops = {
 static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 {
 PIIX3State *d = PIIX3_PCI_DEVICE(dev);
+ISABus *isa_bus;
 
-if (!isa_bus_new(DEVICE(d), get_system_memory(),
- pci_address_space_io(dev), errp)) {
+isa_bus = isa_bus_new(DEVICE(d), get_system_memory(),
+  pci_address_space_io(dev), errp);
+if (!isa_bus) {
 return;
 }
 
@@ -307,6 +310,8 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 PIIX_RCR_IOPORT, &d->rcr_mem, 1);
 
 qemu_register_reset(piix3_reset, d);
+
+i8257_dma_init(isa_bus, 0);
 }
 
 static void build_pci_isa_aml(AcpiDevAmlIf *adev, Aml *scope)
-- 
2.37.3




[PULL 51/55] hw/isa/piix4: Move pci_ide_create_devs() call to board code

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

For the VIA south bridges there was a comment to have the call in board code.
Move it there for PIIX4 as well for consistency.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-29-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix4.c  |  1 -
 hw/mips/malta.c | 10 ++
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 9126eb9edf..8fc1db6dc9 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -257,7 +257,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
 if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
 return;
 }
-pci_ide_create_devs(PCI_DEVICE(&s->ide));
 
 /* USB */
 qdev_prop_set_int32(DEVICE(&s->uhci), "addr", dev->devfn + 2);
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 6ac811763c..5a4e2abbdf 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -39,7 +39,7 @@
 #include "hw/pci/pci.h"
 #include "qemu/log.h"
 #include "hw/mips/bios.h"
-#include "hw/ide.h"
+#include "hw/ide/pci.h"
 #include "hw/irq.h"
 #include "hw/loader.h"
 #include "elf.h"
@@ -1400,11 +1400,13 @@ void mips_malta_init(MachineState *machine)
 /* Southbridge */
 piix4 = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0), true,
 TYPE_PIIX4_PCI_DEVICE);
-dev = DEVICE(piix4);
-isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
+isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix4), "isa.0"));
+
+dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "ide"));
+pci_ide_create_devs(PCI_DEVICE(dev));
 
 /* Interrupt controller */
-qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq);
+qdev_connect_gpio_out_named(DEVICE(piix4), "intr", 0, i8259_irq);
 
 /* generate SPD EEPROM data */
 dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm"));
-- 
2.37.3




[PULL 43/55] hw/isa/piix3: Modernize reset handling

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Rather than registering the reset handler via a function which
appends the handler to a global list, prefer to implement it as
a virtual method - PIIX4 does the same already.

Note that this means that piix3_reset can now also be called writing to
the relevant configuration space register on a PCI bridge.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-6-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 72dbf688d9..723ad0a896 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -31,7 +31,6 @@
 #include "hw/isa/isa.h"
 #include "hw/xen/xen.h"
 #include "sysemu/xen.h"
-#include "sysemu/reset.h"
 #include "sysemu/runstate.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/acpi_aml_interface.h"
@@ -156,9 +155,9 @@ static void piix3_write_config_xen(PCIDevice *dev,
 piix3_write_config(dev, address, val, len);
 }
 
-static void piix3_reset(void *opaque)
+static void piix3_reset(DeviceState *dev)
 {
-PIIX3State *d = opaque;
+PIIX3State *d = PIIX3_PCI_DEVICE(dev);
 uint8_t *pci_conf = d->dev.config;
 
 pci_conf[0x04] = 0x07; /* master, memory and I/O */
@@ -313,8 +312,6 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 memory_region_add_subregion_overlap(pci_address_space_io(dev),
 PIIX_RCR_IOPORT, &d->rcr_mem, 1);
 
-qemu_register_reset(piix3_reset, d);
-
 i8257_dma_init(isa_bus, 0);
 }
 
@@ -337,6 +334,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void 
*data)
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
 
+dc->reset   = piix3_reset;
 dc->desc= "ISA bridge";
 dc->vmsd= &vmstate_piix3;
 dc->hotpluggable   = false;
-- 
2.37.3




[PULL 13/55] hw/isa/vt82c686: Create rtc-time alias in boards instead

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

According to good QOM practice, an object should only deal with objects
of its own sub tree. Having devices create an alias on the machine
object doesn't respect this good practice. To resolve this, create the
alias in the machine's code.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Daniel Henrique Barboza 
Message-Id: <20220901114127.53914-14-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/vt82c686.c   | 2 --
 hw/mips/fuloong2e.c | 4 
 hw/ppc/pegasos2.c   | 4 
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 48cd4d0036..3f9bd0c04d 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -632,8 +632,6 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) {
 return;
 }
-object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(&s->rtc),
-  "date");
 isa_connect_gpio_out(ISA_DEVICE(&s->rtc), 0, s->rtc.isairq);
 
 for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) {
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 3c46215616..b478483706 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -295,6 +295,10 @@ static void mips_fuloong2e_init(MachineState *machine)
 pci_dev = pci_create_simple_multifunction(pci_bus,
   PCI_DEVFN(FULOONG2E_VIA_SLOT, 0),
   true, TYPE_VT82C686B_ISA);
+object_property_add_alias(OBJECT(machine), "rtc-time",
+  object_resolve_path_component(OBJECT(pci_dev),
+"rtc"),
+  "date");
 qdev_connect_gpio_out(DEVICE(pci_dev), 0, env->irq[5]);
 
 dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide"));
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 474723ee27..49809b2b75 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -161,6 +161,10 @@ static void pegasos2_init(MachineState *machine)
 /* VIA VT8231 South Bridge (multifunction PCI device) */
 via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true,
   TYPE_VT8231_ISA);
+object_property_add_alias(OBJECT(machine), "rtc-time",
+  object_resolve_path_component(OBJECT(via),
+"rtc"),
+  "date");
 qdev_connect_gpio_out(DEVICE(via), 0,
   qdev_get_gpio_in_named(pm->mv, "gpp", 31));
 
-- 
2.37.3




[PULL 30/55] disas/nanomips: Remove IMMEDIATE functions

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Both versions of IMMEDIATE functions have been removed.

Before this patch, we'd been calling img_format twice, the first time
through the IMMEDIATE to get an appropriate string and the second time
to print that string. There's no more need for that. Therefore, calls to
IMMEDIATE are removed, and now we're directly printing the integer
values instead.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-17-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 756 -
 1 file changed, 265 insertions(+), 491 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index e4e122f3cf..3b1ca249ce 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -519,18 +519,6 @@ static const char *AC(uint64 reg)
 }
 
 
-static char *IMMEDIATE(uint64 value)
-{
-return img_format("0x%" PRIx64, value);
-}
-
-
-static char *IMMEDIATE(int64 value)
-{
-return img_format("%" PRId64, value);
-}
-
-
 static char *CPR(uint64 reg)
 {
 /* needs more work */
@@ -1674,11 +1662,10 @@ static char *ACLR(uint64 instruction, Dis_info *info)
 uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
 int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction);
 
-char *bit = IMMEDIATE(bit_value);
-char *s = IMMEDIATE(s_value);
 const char *rs = GPR(rs_value);
 
-return img_format("ACLR %s, %s(%s)", bit, s, rs);
+return img_format("ACLR 0x%" PRIx64 ", %" PRId64 "(%s)",
+  bit_value, s_value, rs);
 }
 
 
@@ -1772,9 +1759,8 @@ static char *ADDIU_32_(uint64 instruction, Dis_info *info)
 
 const char *rt = GPR(rt_value);
 const char *rs = GPR(rs_value);
-char *u = IMMEDIATE(u_value);
 
-return img_format("ADDIU %s, %s, %s", rt, rs, u);
+return img_format("ADDIU %s, %s, 0x%" PRIx64, rt, rs, u_value);
 }
 
 
@@ -1793,9 +1779,8 @@ static char *ADDIU_48_(uint64 instruction, Dis_info *info)
 int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = IMMEDIATE(s_value);
 
-return img_format("ADDIU %s, %s", rt, s);
+return img_format("ADDIU %s, %" PRId64, rt, s_value);
 }
 
 
@@ -1814,9 +1799,8 @@ static char *ADDIU_GP48_(uint64 instruction, Dis_info 
*info)
 int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = IMMEDIATE(s_value);
 
-return img_format("ADDIU %s, $%d, %s", rt, 28, s);
+return img_format("ADDIU %s, $%d, %" PRId64, rt, 28, s_value);
 }
 
 
@@ -1835,9 +1819,8 @@ static char *ADDIU_GP_B_(uint64 instruction, Dis_info 
*info)
 uint64 u_value = extract_u_17_to_0(instruction);
 
 const char *rt = GPR(rt_value);
-char *u = IMMEDIATE(u_value);
 
-return img_format("ADDIU %s, $%d, %s", rt, 28, u);
+return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt, 28, u_value);
 }
 
 
@@ -1856,9 +1839,8 @@ static char *ADDIU_GP_W_(uint64 instruction, Dis_info 
*info)
 uint64 u_value = extract_u_20_to_2__s2(instruction);
 
 const char *rt = GPR(rt_value);
-char *u = IMMEDIATE(u_value);
 
-return img_format("ADDIU %s, $%d, %s", rt, 28, u);
+return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt, 28, u_value);
 }
 
 
@@ -1879,9 +1861,9 @@ static char *ADDIU_NEG_(uint64 instruction, Dis_info 
*info)
 
 const char *rt = GPR(rt_value);
 const char *rs = GPR(rs_value);
-char *u = IMMEDIATE(neg_copy(u_value));
+int64 u = neg_copy(u_value);
 
-return img_format("ADDIU %s, %s, %s", rt, rs, u);
+return img_format("ADDIU %s, %s, %" PRId64, rt, rs, u);
 }
 
 
@@ -1900,9 +1882,8 @@ static char *ADDIU_R1_SP_(uint64 instruction, Dis_info 
*info)
 uint64 rt3_value = extract_rt3_9_8_7(instruction);
 
 const char *rt3 = GPR(decode_gpr_gpr3(rt3_value));
-char *u = IMMEDIATE(u_value);
 
-return img_format("ADDIU %s, $%d, %s", rt3, 29, u);
+return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt3, 29, u_value);
 }
 
 
@@ -1923,9 +1904,8 @@ static char *ADDIU_R2_(uint64 instruction, Dis_info *info)
 
 const char *rt3 = GPR(decode_gpr_gpr3(rt3_value));
 const char *rs3 = GPR(decode_gpr_gpr3(rs3_value));
-char *u = IMMEDIATE(u_value);
 
-return img_format("ADDIU %s, %s, %s", rt3, rs3, u);
+return img_format("ADDIU %s, %s, 0x%" PRIx64, rt3, rs3, u_value);
 }
 
 
@@ -1943,9 +1923,8 @@ static char *ADDIU_RS5_(uint64 instruction, Dis_info 
*info)
 int64 s_value = extract_s__se3_4_2_1_0(instruction);
 
 const char *rt = GPR(rt_value);
-char *s = IMMEDIATE(s_value);
 
-return img_format("ADDIU %s, %s", rt, s);
+return img_format("ADDIU %s, %" PRId64, rt, s_value);
 }
 
 
@@ -2513,9 +2492,9 @@ static char *ANDI_16_(uint64 instruction, Dis_info *info)
 
 const char *rt3 = GPR(decode_gpr_gpr3(rt3_value));
 const char *rs3 = GPR(decode_gpr_gpr3(rs3_value));
-char *eu = IMMEDIATE(encode_

[PULL 52/55] hw/mips/boston: Don't set link_up for xilinx-pcie

2022-10-30 Thread Philippe Mathieu-Daudé
From: Jiaxun Yang 

PCIe port 0 and 1 had link_up set as false previously,
that makes those two ports effectively useless. It can
be annoying for users to find that the device they plug
on those buses won't work at all.

As link_up is true by default, just don't set it again in
boston platform code.

Signed-off-by: Jiaxun Yang 
Message-Id: <20221024143540.97545-1-jiaxun.y...@flygoat.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/mips/boston.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index d2ab9da1a0..aa7942bbc0 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -424,7 +424,7 @@ static inline XilinxPCIEHost *
 xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
  hwaddr cfg_base, uint64_t cfg_size,
  hwaddr mmio_base, uint64_t mmio_size,
- qemu_irq irq, bool link_up)
+ qemu_irq irq)
 {
 DeviceState *dev;
 MemoryRegion *cfg, *mmio;
@@ -436,7 +436,6 @@ xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
 qdev_prop_set_uint64(dev, "cfg_size", cfg_size);
 qdev_prop_set_uint64(dev, "mmio_base", mmio_base);
 qdev_prop_set_uint64(dev, "mmio_size", mmio_size);
-qdev_prop_set_bit(dev, "link_up", link_up);
 
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 
@@ -729,21 +728,21 @@ static void boston_mach_init(MachineState *machine)
  boston_memmap[BOSTON_PCIE0].size,
  boston_memmap[BOSTON_PCIE0_MMIO].base,
  boston_memmap[BOSTON_PCIE0_MMIO].size,
- get_cps_irq(&s->cps, 2), false);
+ get_cps_irq(&s->cps, 2));
 
 xilinx_pcie_init(sys_mem, 1,
  boston_memmap[BOSTON_PCIE1].base,
  boston_memmap[BOSTON_PCIE1].size,
  boston_memmap[BOSTON_PCIE1_MMIO].base,
  boston_memmap[BOSTON_PCIE1_MMIO].size,
- get_cps_irq(&s->cps, 1), false);
+ get_cps_irq(&s->cps, 1));
 
 pcie2 = xilinx_pcie_init(sys_mem, 2,
  boston_memmap[BOSTON_PCIE2].base,
  boston_memmap[BOSTON_PCIE2].size,
  boston_memmap[BOSTON_PCIE2_MMIO].base,
  boston_memmap[BOSTON_PCIE2_MMIO].size,
- get_cps_irq(&s->cps, 0), true);
+ get_cps_irq(&s->cps, 0));
 
 platreg = g_new(MemoryRegion, 1);
 memory_region_init_io(platreg, NULL, &boston_platreg_ops, s,
-- 
2.37.3




[PULL 45/55] hw/isa/piix4: Rename wrongly named method

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

This method post-loads the southbridge, not the IDE device.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-8-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix4.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 15f344dbb7..c88d3bf3bf 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -141,7 +141,7 @@ static void piix4_isa_reset(DeviceState *dev)
 pci_conf[0xae] = 0x00;
 }
 
-static int piix4_ide_post_load(void *opaque, int version_id)
+static int piix4_post_load(void *opaque, int version_id)
 {
 PIIX4State *s = opaque;
 
@@ -156,7 +156,7 @@ static const VMStateDescription vmstate_piix4 = {
 .name = "PIIX4",
 .version_id = 3,
 .minimum_version_id = 2,
-.post_load = piix4_ide_post_load,
+.post_load = piix4_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_PCI_DEVICE(dev, PIIX4State),
 VMSTATE_UINT8_V(rcr, PIIX4State, 3),
-- 
2.37.3




[PULL 38/55] disas/nanomips: Rename nanomips.cpp to nanomips.c

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Now that everything has been converted to C code the nanomips.cpp file
has been renamed. Therefore, meson.build file is also changed.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-25-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/meson.build  | 2 +-
 disas/{nanomips.cpp => nanomips.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename disas/{nanomips.cpp => nanomips.c} (100%)

diff --git a/disas/meson.build b/disas/meson.build
index ba22f7cbcd..1977f5cd92 100644
--- a/disas/meson.build
+++ b/disas/meson.build
@@ -5,7 +5,7 @@ common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c'))
 common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c'))
 common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c'))
 common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c'))
-common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.cpp'))
+common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.c'))
 common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c'))
 common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files('riscv.c'))
 common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
diff --git a/disas/nanomips.cpp b/disas/nanomips.c
similarity index 100%
rename from disas/nanomips.cpp
rename to disas/nanomips.c
-- 
2.37.3




[PULL 41/55] hw/isa/piix3: Remove extra ';' outside of functions

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Fixes the "extra-semi" clang-tidy check.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-4-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 44a9998752..04895ce2e5 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -375,7 +375,7 @@ static void piix3_realize(PCIDevice *dev, Error **errp)
 pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq,
  piix3, PIIX_NUM_PIRQS);
 pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq);
-};
+}
 
 static void piix3_class_init(ObjectClass *klass, void *data)
 {
@@ -410,7 +410,7 @@ static void piix3_xen_realize(PCIDevice *dev, Error **errp)
  */
 pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq,
  piix3, XEN_PIIX_NUM_PIRQS);
-};
+}
 
 static void piix3_xen_class_init(ObjectClass *klass, void *data)
 {
@@ -418,7 +418,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void 
*data)
 
 k->config_write = piix3_write_config_xen;
 k->realize = piix3_xen_realize;
-};
+}
 
 static const TypeInfo piix3_xen_info = {
 .name  = TYPE_PIIX3_XEN_DEVICE,
-- 
2.37.3




[PULL 47/55] hw/isa/piix3: Remove unused include

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Ammends commit 988fb613215993dd0ce642b89ca8182c479d39dd.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-19-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 0bea4aefe7..808fd4eadf 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -30,7 +30,6 @@
 #include "hw/irq.h"
 #include "hw/isa/isa.h"
 #include "hw/xen/xen.h"
-#include "sysemu/xen.h"
 #include "sysemu/runstate.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/acpi_aml_interface.h"
-- 
2.37.3




[PULL 49/55] hw/isa/Kconfig: Fix dependencies of piix4 southbridge

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Signed-off-by: Bernhard Beschow 
Message-Id: <20221022150508.26830-27-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 configs/devices/mips-softmmu/common.mak | 1 -
 hw/isa/Kconfig  | 6 ++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/configs/devices/mips-softmmu/common.mak 
b/configs/devices/mips-softmmu/common.mak
index d2202c839e..416161f833 100644
--- a/configs/devices/mips-softmmu/common.mak
+++ b/configs/devices/mips-softmmu/common.mak
@@ -23,7 +23,6 @@ CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_PIIX4=y
 CONFIG_IDE_ISA=y
-CONFIG_IDE_PIIX=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_I8259=y
 CONFIG_MC146818RTC=y
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 60aad28800..18b5c6bf3f 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -40,7 +40,13 @@ config PIIX4
 bool
 # For historical reasons, SuperIO devices are created in the board
 # for PIIX4.
+select ACPI_PIIX4
+select I8254
+select I8257
+select I8259
+select IDE_PIIX
 select ISA_BUS
+select MC146818RTC
 select USB_UHCI
 
 config VT82C686
-- 
2.37.3




[PULL 46/55] hw/ide/piix: Introduce TYPE_ macros for PIIX IDE controllers

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

Suggested-by: Mark Cave-Ayland 
Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221022150508.26830-9-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc_piix.c | 3 ++-
 hw/ide/piix.c | 5 +++--
 hw/isa/piix4.c| 3 ++-
 include/hw/ide/piix.h | 7 +++
 4 files changed, 14 insertions(+), 4 deletions(-)
 create mode 100644 include/hw/ide/piix.h

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7a55b9ca8e..0ad0ed1603 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -40,6 +40,7 @@
 #include "hw/usb.h"
 #include "net/net.h"
 #include "hw/ide/pci.h"
+#include "hw/ide/piix.h"
 #include "hw/irq.h"
 #include "sysemu/kvm.h"
 #include "hw/kvm/clock.h"
@@ -259,7 +260,7 @@ static void pc_init1(MachineState *machine,
 if (pcmc->pci_enabled) {
 PCIDevice *dev;
 
-dev = pci_create_simple(pci_bus, piix3_devfn + 1, "piix3-ide");
+dev = pci_create_simple(pci_bus, piix3_devfn + 1, TYPE_PIIX3_IDE);
 pci_ide_create_devs(dev);
 idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
 idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index de1f4f0efb..267dbf37db 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -36,6 +36,7 @@
 #include "sysemu/blockdev.h"
 #include "sysemu/dma.h"
 
+#include "hw/ide/piix.h"
 #include "hw/ide/pci.h"
 #include "trace.h"
 
@@ -202,7 +203,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void 
*data)
 }
 
 static const TypeInfo piix3_ide_info = {
-.name  = "piix3-ide",
+.name  = TYPE_PIIX3_IDE,
 .parent= TYPE_PCI_IDE,
 .class_init= piix3_ide_class_init,
 };
@@ -224,7 +225,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void 
*data)
 }
 
 static const TypeInfo piix4_ide_info = {
-.name  = "piix4-ide",
+.name  = TYPE_PIIX4_IDE,
 .parent= TYPE_PCI_IDE,
 .class_init= piix4_ide_class_init,
 };
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index c88d3bf3bf..e05e65d3bc 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -28,6 +28,7 @@
 #include "hw/irq.h"
 #include "hw/southbridge/piix.h"
 #include "hw/pci/pci.h"
+#include "hw/ide/piix.h"
 #include "hw/isa/isa.h"
 #include "hw/intc/i8259.h"
 #include "hw/dma/i8257.h"
@@ -277,7 +278,7 @@ static void piix4_init(Object *obj)
 PIIX4State *s = PIIX4_PCI_DEVICE(obj);
 
 object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
-object_initialize_child(obj, "ide", &s->ide, "piix4-ide");
+object_initialize_child(obj, "ide", &s->ide, TYPE_PIIX4_IDE);
 object_initialize_child(obj, "uhci", &s->uhci, "piix4-usb-uhci");
 
 object_initialize_child(obj, "pm", &s->pm, TYPE_PIIX4_PM);
diff --git a/include/hw/ide/piix.h b/include/hw/ide/piix.h
new file mode 100644
index 00..ef3ef3d62d
--- /dev/null
+++ b/include/hw/ide/piix.h
@@ -0,0 +1,7 @@
+#ifndef HW_IDE_PIIX_H
+#define HW_IDE_PIIX_H
+
+#define TYPE_PIIX3_IDE "piix3-ide"
+#define TYPE_PIIX4_IDE "piix4-ide"
+
+#endif /* HW_IDE_PIIX_H */
-- 
2.37.3




[PULL 36/55] disas/nanomips: Replace Cpp enums for C enums

2022-10-30 Thread Philippe Mathieu-Daudé
From: Milica Lazarevic 

Change enums to typedef enums to keep naming clear.

Signed-off-by: Milica Lazarevic 
Reviewed-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20220912122635.74032-23-milica.lazare...@syrmia.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 disas/nanomips.cpp | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 1832c2d3cf..8b4bc910a4 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -40,16 +40,16 @@ typedef uint32_t uint32;
 typedef uint16_t uint16;
 typedef uint64_t img_address;
 
-enum TABLE_ENTRY_TYPE {
+typedef enum  {
 instruction,
 call_instruction,
 branch_instruction,
 return_instruction,
 reserved_block,
 pool,
-};
+} TABLE_ENTRY_TYPE;
 
-enum TABLE_ATTRIBUTE_TYPE {
+typedef enum {
 MIPS64_= 0x0001,
 XNP_   = 0x0002,
 XMMS_  = 0x0004,
@@ -67,7 +67,7 @@ enum TABLE_ATTRIBUTE_TYPE {
 TLB_   = 0x4000,
 MVH_   = 0x8000,
 ALL_ATTRIBUTES = 0xull,
-};
+} TABLE_ATTRIBUTE_TYPE;
 
 typedef struct Dis_info {
   img_address m_pc;
-- 
2.37.3




[PULL 50/55] hw/isa/piix4: Add missing initialization

2022-10-30 Thread Philippe Mathieu-Daudé
From: Bernhard Beschow 

PIIX3 clears its reset control register, so do the same in PIIX4.

Signed-off-by: Bernhard Beschow 
Message-Id: <20221022150508.26830-28-shen...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix4.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index e05e65d3bc..9126eb9edf 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -140,6 +140,8 @@ static void piix4_isa_reset(DeviceState *dev)
 pci_conf[0xab] = 0x00;
 pci_conf[0xac] = 0x00;
 pci_conf[0xae] = 0x00;
+
+d->rcr = 0;
 }
 
 static int piix4_post_load(void *opaque, int version_id)
-- 
2.37.3




[PATCH] MAINTAINERS: Inherit from nanoMIPS

2022-10-30 Thread Philippe Mathieu-Daudé
6 months ago Stefan Pejic stepped in as nanoMIPS maintainer
(see commit a 8e0e23445a "target/mips: Undeprecate nanoMIPS
ISA support in QEMU"), however today his email is bouncing:

  ** Message blocked **

  Your message to stefan.pe...@syrmia.com has been blocked. See technical 
details below for more information.

  The response from the remote server was:
  550 5.4.1 Recipient address rejected: Access denied. AS(201806281) 
[DBAEUR03FT030.eop-EUR03.prod.protection.outlook.com]

To avoid unmaintained code, I feel forced to merge this code
back with the generic MIPS section.

Historical references:
- 
https://lore.kernel.org/qemu-devel/ty0pr03mb679726901bd6c6be40114a2fe2...@ty0pr03mb6797.apcprd03.prod.outlook.com/
- 
https://lore.kernel.org/qemu-devel/b858a20e97b74e7b90a94948314d0...@mtkmbs62n2.mediatek.inc/

Cc: Vince Del Vecchio 
Signed-off-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 32e495e165..0ba3b589bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -239,16 +239,10 @@ R: Jiaxun Yang 
 R: Aleksandar Rikalo 
 S: Odd Fixes
 F: target/mips/
-F: disas/mips.c
+F: disas/*mips.c
 F: docs/system/cpu-models-mips.rst.inc
 F: tests/tcg/mips/
 
-MIPS TCG CPUs (nanoMIPS ISA)
-M: Stefan Pejic 
-S: Maintained
-F: disas/nanomips.*
-F: target/mips/tcg/*nanomips*
-
 NiosII TCG CPUs
 M: Chris Wulff 
 M: Marek Vasut 
-- 
2.37.3




Re: [PATCH 3/3] target/mips: Disable DSP ASE for Octeon68XX

2022-10-30 Thread Richard Henderson

On 10/29/22 13:00, Jiaxun Yang wrote:

I don't have access to Octeon68XX hardware but accroading to
my investigation Octeon never had DSP ASE support.

As per "Cavium Networks OCTEON Plus CN50XX Hardware Reference
Manual" CP0C3_DSPP is reserved bit and read as 0. Also I do have
access to a Ubiquiti Edgerouter 4 which has Octeon CN7130 processor
and I can confirm CP0C3_DSPP is read as 0 on that processor.

Further more, in linux kernel:
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
cpu_has_dsp is overridden as 0.

So I believe we shouldn't emulate DSP in QEMU as well.

Signed-off-by: Jiaxun Yang
---
  target/mips/cpu-defs.c.inc | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)


Acked-by: Richard Henderson 

r~



Re: [PATCH] tcg/tci: fix logic error when registering helpers via FFI

2022-10-30 Thread Richard Henderson

On 10/29/22 11:44, Icenowy Zheng wrote:

Ah I think this is a C99 feature. Is our C standard baseline high
enough to use it?


Yes, we use C2011.  See the second line of meson.build:

default_options: ... 'c_std=gnu11'


r~



Re: [PATCH 1/3] tcg/sparc: Remove support for sparc32plus

2022-10-30 Thread Richard Henderson

On 10/31/22 02:45, Peter Maydell wrote:

+/* We only support generating code for 64-bit mode.  */
+#ifndef __arch64__
+#error "unsupported code generation mode"


We might as well be more specific:
"no support for generating code for 32-bit SPARC"
(though I guess that configure ought in theory to prevent us getting here
in that situation ?)


Yes, after patch 2 configure should prevent it.


r~



Re: [PATCH] MAINTAINERS: Inherit from nanoMIPS

2022-10-30 Thread Richard Henderson

On 10/31/22 09:50, Philippe Mathieu-Daudé wrote:

6 months ago Stefan Pejic stepped in as nanoMIPS maintainer
(see commit a 8e0e23445a "target/mips: Undeprecate nanoMIPS
ISA support in QEMU"), however today his email is bouncing:

   ** Message blocked **

   Your message tostefan.pe...@syrmia.com  has been blocked. See technical 
details below for more information.

   The response from the remote server was:
   550 5.4.1 Recipient address rejected: Access denied. AS(201806281) 
[DBAEUR03FT030.eop-EUR03.prod.protection.outlook.com]

To avoid unmaintained code, I feel forced to merge this code
back with the generic MIPS section.

Historical references:
-https://lore.kernel.org/qemu-devel/ty0pr03mb679726901bd6c6be40114a2fe2...@ty0pr03mb6797.apcprd03.prod.outlook.com/
-https://lore.kernel.org/qemu-devel/b858a20e97b74e7b90a94948314d0...@mtkmbs62n2.mediatek.inc/

Cc: Vince Del Vecchio
Signed-off-by: Philippe Mathieu-Daudé
---
  MAINTAINERS | 8 +---
  1 file changed, 1 insertion(+), 7 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 1/3] target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F

2022-10-30 Thread Richard Henderson

On 10/29/22 13:00, Jiaxun Yang wrote:

As per "Loongson-2F processor user manual", CP0St_{KX, SX, UX}
should is not writeable and hardcoded to 1.

Without those bits set, kernel is unable to access XKPHYS address
segmant. So just set them up on CPU reset.

Signed-off-by: Jiaxun Yang
---
  target/mips/cpu.c | 6 ++
  1 file changed, 6 insertions(+)


Based on down-thread discussion of the manual:
Acked-by: Richard Henderson 


r~



Re: [PATCH 1/3] tcg/sparc: Remove support for sparc32plus

2022-10-30 Thread Richard Henderson

On 10/31/22 04:21, Philippe Mathieu-Daudé wrote:

On 30/10/22 16:45, Peter Maydell wrote:

-#define TCG_TARGET_REG_BITS 64


Why do we delete this?


We get the default definition from include/tcg/tcg.h:

   58 /* Default target word size to pointer size.  */
   59 #ifndef TCG_TARGET_REG_BITS
   60 # if UINTPTR_MAX == UINT32_MAX
   61 #  define TCG_TARGET_REG_BITS 32
   62 # elif UINTPTR_MAX == UINT64_MAX
   63 #  define TCG_TARGET_REG_BITS 64


Exactly.


r~




Re: [PATCH 1/5] target/riscv: Typo fix in sstc() predicate

2022-10-30 Thread Alistair Francis
On Fri, Oct 28, 2022 at 2:52 AM Anup Patel  wrote:
>
> We should use "&&" instead of "&" when checking hcounteren.TM and
> henvcfg.STCE bits.
>
> Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 5c9a7ee287..716f9d960e 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -838,7 +838,7 @@ static RISCVException sstc(CPURISCVState *env, int csrno)
>  }
>
>  if (riscv_cpu_virt_enabled(env)) {
> -if (!(get_field(env->hcounteren, COUNTEREN_TM) &
> +if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
>get_field(env->henvcfg, HENVCFG_STCE))) {
>  return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>  }
> --
> 2.34.1
>
>



Re: [PATCH 2/5] target/riscv: Update VS timer whenever htimedelta changes

2022-10-30 Thread Alistair Francis
On Fri, Oct 28, 2022 at 2:52 AM Anup Patel  wrote:
>
> The htimedelta[h] CSR has impact on the VS timer comparison so we
> should call riscv_timer_write_timecmp() whenever htimedelta changes.
>
> Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 16 
>  1 file changed, 16 insertions(+)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 716f9d960e..4b1a608260 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -2722,6 +2722,8 @@ static RISCVException read_htimedelta(CPURISCVState 
> *env, int csrno,
>  static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
> target_ulong val)
>  {
> +RISCVCPU *cpu = env_archcpu(env);
> +
>  if (!env->rdtime_fn) {
>  return RISCV_EXCP_ILLEGAL_INST;
>  }
> @@ -2731,6 +2733,12 @@ static RISCVException write_htimedelta(CPURISCVState 
> *env, int csrno,
>  } else {
>  env->htimedelta = val;
>  }
> +
> +if (cpu->cfg.ext_sstc && env->rdtime_fn) {
> +riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
> +  env->htimedelta, MIP_VSTIP);
> +}
> +
>  return RISCV_EXCP_NONE;
>  }
>
> @@ -2748,11 +2756,19 @@ static RISCVException read_htimedeltah(CPURISCVState 
> *env, int csrno,
>  static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
>  target_ulong val)
>  {
> +RISCVCPU *cpu = env_archcpu(env);
> +
>  if (!env->rdtime_fn) {
>  return RISCV_EXCP_ILLEGAL_INST;
>  }
>
>  env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
> +
> +if (cpu->cfg.ext_sstc && env->rdtime_fn) {
> +riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
> +  env->htimedelta, MIP_VSTIP);
> +}
> +
>  return RISCV_EXCP_NONE;
>  }
>
> --
> 2.34.1
>
>



Re: [PATCH 3/5] target/riscv: Don't clear mask in riscv_cpu_update_mip() for VSTIP

2022-10-30 Thread Alistair Francis
On Fri, Oct 28, 2022 at 2:52 AM Anup Patel  wrote:
>
> Instead of clearing mask in riscv_cpu_update_mip() for VSTIP, we
> should call riscv_cpu_update_mip() with mask == 0 from timer_helper.c
> for VSTIP.
>
> Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu_helper.c  |  2 --
>  target/riscv/time_helper.c | 12 
>  2 files changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 5d66246c2c..a403825e49 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -617,8 +617,6 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t 
> mask, uint64_t value)
>  vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
>  }
>
> -/* No need to update mip for VSTIP */
> -mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
>  vstip = env->vstime_irq ? MIP_VSTIP : 0;
>
>  if (!qemu_mutex_iothread_locked()) {
> diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
> index 8cce667dfd..4fb2a471a9 100644
> --- a/target/riscv/time_helper.c
> +++ b/target/riscv/time_helper.c
> @@ -27,7 +27,7 @@ static void riscv_vstimer_cb(void *opaque)
>  RISCVCPU *cpu = opaque;
>  CPURISCVState *env = &cpu->env;
>  env->vstime_irq = 1;
> -riscv_cpu_update_mip(cpu, MIP_VSTIP, BOOL_TO_MASK(1));
> +riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(1));
>  }
>
>  static void riscv_stimer_cb(void *opaque)
> @@ -57,16 +57,20 @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer 
> *timer,
>   */
>  if (timer_irq == MIP_VSTIP) {
>  env->vstime_irq = 1;
> +riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(1));
> +} else {
> +riscv_cpu_update_mip(cpu, MIP_STIP, BOOL_TO_MASK(1));
>  }
> -riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1));
>  return;
>  }
>
> +/* Clear the [VS|S]TIP bit in mip */
>  if (timer_irq == MIP_VSTIP) {
>  env->vstime_irq = 0;
> +riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(0));
> +} else {
> +riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
>  }
> -/* Clear the [V]STIP bit in mip */
> -riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
>
>  /* otherwise, set up the future timer interrupt */
>  diff = timecmp - rtc_r;
> --
> 2.34.1
>
>



Re: [PATCH 4/5] target/riscv: No need to re-start QEMU timer when timecmp == UINT64_MAX

2022-10-30 Thread Alistair Francis
On Fri, Oct 28, 2022 at 2:53 AM Anup Patel  wrote:
>
> The time CSR will wrap-around immediately after reaching UINT64_MAX
> so we don't need to re-start QEMU timer when timecmp == UINT64_MAX
> in riscv_timer_write_timecmp().

I'm not clear what this is fixing?

If the guest sets a timer for UINT64_MAX shouldn't that still trigger
an event at some point?

Alistair

>
> Signed-off-by: Anup Patel 
> ---
>  target/riscv/time_helper.c | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
> index 4fb2a471a9..1ee9f94813 100644
> --- a/target/riscv/time_helper.c
> +++ b/target/riscv/time_helper.c
> @@ -72,6 +72,14 @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer 
> *timer,
>  riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
>  }
>
> +/*
> + * Don't re-start the QEMU timer when timecmp == UINT64_MAX because
> + * time CSR will wrap-around immediately after reaching UINT64_MAX.
> + */
> +if (timecmp == UINT64_MAX) {
> +return;
> +}
> +
>  /* otherwise, set up the future timer interrupt */
>  diff = timecmp - rtc_r;
>  /* back to ns (note args switched in muldiv64) */
> --
> 2.34.1
>
>



[PATCH] cutils: Fix get_relocated_path on Windows

2022-10-30 Thread Akihiko Odaki
get_relocated_path() did not have error handling for PathCchSkipRoot()
because a path given to get_relocated_path() was expected to be a valid
path containing a drive letter or UNC server/share path elements on
Windows, but sometimes it turned out otherwise.

The paths passed to get_relocated_path() are defined by macros generated
by Meson. Meson in turn uses a prefix given by the configure script to
generate them. For Windows, the script passes /qemu as a prefix to
Meson by default.

As documented in docs/about/build-platforms.rst, typically MSYS2 is used
for the build system, but it is also possible to use Linux as well. When
MSYS2 is used, its Bash variant recognizes /qemu as a MSYS2 path, and
converts it to a Windows path, adding the MSYS2 prefix including a drive
letter or UNC server/share path elements. Such a conversion does not
happen on a shell on Linux however, and /qemu will be passed as is in
the case.

Implement a proper error handling of PathCchSkipRoot() in
get_relocated_path() so that it can handle a path without a drive letter
or UNC server/share path elements.

Reported-by: Stefan Weil 
Signed-off-by: Akihiko Odaki 
---
 util/cutils.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/util/cutils.c b/util/cutils.c
index cb43dda213..932c741d2b 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -1088,17 +1088,21 @@ char *get_relocated_path(const char *dir)
 g_string_append(result, "/qemu-bundle");
 if (access(result->str, R_OK) == 0) {
 #ifdef G_OS_WIN32
-size_t size = mbsrtowcs(NULL, &dir, 0, &(mbstate_t){0}) + 1;
+const char *src = dir;
+size_t size = mbsrtowcs(NULL, &src, 0, &(mbstate_t){0}) + 1;
 PWSTR wdir = g_new(WCHAR, size);
-mbsrtowcs(wdir, &dir, size, &(mbstate_t){0});
+mbsrtowcs(wdir, &src, size, &(mbstate_t){0});
 
 PCWSTR wdir_skipped_root;
-PathCchSkipRoot(wdir, &wdir_skipped_root);
+if (PathCchSkipRoot(wdir, &wdir_skipped_root)) {
+g_string_append(result, dir);
+} else {
+size = wcsrtombs(NULL, &wdir_skipped_root, 0, &(mbstate_t){0});
+char *cursor = result->str + result->len;
+g_string_set_size(result, result->len + size);
+wcsrtombs(cursor, &wdir_skipped_root, size + 1, &(mbstate_t){0});
+}
 
-size = wcsrtombs(NULL, &wdir_skipped_root, 0, &(mbstate_t){0});
-char *cursor = result->str + result->len;
-g_string_set_size(result, result->len + size);
-wcsrtombs(cursor, &wdir_skipped_root, size + 1, &(mbstate_t){0});
 g_free(wdir);
 #else
 g_string_append(result, dir);
-- 
2.38.1




Re: [PATCH] ui/cocoa: Support hardware cursor interface

2022-10-30 Thread Akihiko Odaki

On 2022/10/30 19:12, Elliot Nunn wrote:

Akihiko,

Sounds like you've done a lot of work on ui/cocoa, with the goal of
improving the experience with modern Linux guests. My goal is to improve
the experience with antiquated Mac OS 9 guests.


My patch has been only tested with recent Linux, but it certainly should
be ensured that it works well for old systems when upstreaming.

First I'd like to know what display device you use. It looks like
dpy_mouse_set is used only by ati-vga, vhost-user-gpu, virtio-gpu, and
vmware.


I was using my own hardware cursor patches to the VGA device, but now I am
using virtio-gpu. My Mac OS 9 driver for virtio-gpu is in progress.


Interesting, but I'm worried that your driver may be not performant 
enough to drive dpy_mouse_set. Does your driver provide hardware cursor 
as smooth as software cursor? If not, the proper way to fix the problem 
is to fix your driver. Strictly speaking, ignoring dpy_mouse_set and 
using the input information directly violates the semantics and should 
be avoided if possible. That said, if your driver already does the best 
to the extent what Mac OS 9 allows and you want even better, it can be a 
worthwhile option.





1. In absolute pointing mode, re-enable Cocoa's cursor and let the host
OS move it according to user input.
2. Keep the cursor sprite, but move it according to Cocoa's mouse
movement events instead of dpy_mouse_set events.


Also, can you give reasoning while 2 is preferred? 1 would allow to
exploit the hardware's feature for cursor composition, resulting in
smoother experience and a bit less power consumption. But there may be
complications it can cause so I have not decided which one is the better
yet.


Mainly that it would simplify the code. OTOH, if we expect the guest to
use the hardware cursor facility, then it's only fair that the host does
the same. I'm open to either option. We should probably try both.


Regarding the code complexity, option  2 can be still the better option 
because option 1 requires additional code to pass the input information 
to the cursor composition code. But it is just a possibility and I guess 
we will not know which is the better unless we implement them as you say.





And I didn't realise that you had added VirGL support to cocoa.m. Well
done! Is it on track for release?
My patch should be withdrawn from consideration, in favour of a future
solution that does not use cursor warping.


I'm not really pushing my changes hard so it's kind of stale. Perhaps it
is better to rewrite the cursor composition patch in a way that does not
depend on the Virgl patch. I'm also aware that the cursor composition
using Core Graphics is somewhat laggy so it may be better to rewrite it
using subview, Core Animation, Metal, or something else. But I have not
done that yet.


Is there some Cocoa-native way of compositing within the window, that
will work with or without a GL surface? Subviews sound appropriate.


I'm for subview because we can retain the current implementation using 
[-NSView drawRect:] for the screen output in this way. The current 
implementation using Core Graphics or OpenGL for cursor composition 
should be avoided as Core Graphics cannot accelerate it with GPU and 
OpenGL requires the deprecated CGL or an external library like ANGLE.


Regards,
Akihiko Odaki



Not that I have any influence, but I think your virgl patch is an
excellent contribution and should go upstream.

Thanks again,

Elliot




[PATCH v8 0/2] vhost-vdpa: add support for vIOMMU

2022-10-30 Thread Cindy Lu
These patches are to support vIOMMU in vdpa device

changes in V3
1. Move function vfio_get_xlat_addr to memory.c
2. Use the existing memory listener, while the MR is
iommu MR then call the function iommu_region_add/
iommu_region_del

changes in V4
1.make the comments in vfio_get_xlat_addr more general

changes in V5
1. Address the comments in the last version
2. Add a new arg in the function vfio_get_xlat_addr, which shows whether
the memory is backed by a discard manager. So the device can have its
own warning.

changes in V6
move the error_report for the unpopulated discard back to
memeory_get_xlat_addr

changes in V7
organize the error massage to avoid the duplicate information

changes in V8
Organize the code follow the comments in the last version

Cindy Lu (2):
  vfio: move implement of vfio_get_xlat_addr() to memory.c
  vhost-vdpa: add support for vIOMMU

 hw/vfio/common.c   | 101 +++
 hw/virtio/vhost-vdpa.c | 123 ++---
 include/exec/memory.h  |   4 ++
 include/hw/virtio/vhost-vdpa.h |  10 +++
 softmmu/memory.c   |  72 +++
 5 files changed, 224 insertions(+), 86 deletions(-)

-- 
2.34.3




[PATCH v8 2/2] vhost-vdpa: add support for vIOMMU

2022-10-30 Thread Cindy Lu
Add support for vIOMMU. add the new function to deal with iommu MR.
- during iommu_region_add register a specific IOMMU notifier,
 and store all notifiers in a list.
- during iommu_region_del, compare and delete the IOMMU notifier from the list

Verified in vp_vdpa and vdpa_sim_net driver

Signed-off-by: Cindy Lu 
---
 hw/virtio/vhost-vdpa.c | 123 ++---
 include/hw/virtio/vhost-vdpa.h |  10 +++
 2 files changed, 122 insertions(+), 11 deletions(-)

diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 3ff9ce3501..dcfaaccfa9 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -26,6 +26,7 @@
 #include "cpu.h"
 #include "trace.h"
 #include "qapi/error.h"
+#include "hw/virtio/virtio-access.h"
 
 /*
  * Return one past the end of the end of section. Be careful with uint64_t
@@ -44,7 +45,6 @@ static bool 
vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
 uint64_t iova_min,
 uint64_t iova_max)
 {
-Int128 llend;
 
 if ((!memory_region_is_ram(section->mr) &&
  !memory_region_is_iommu(section->mr)) ||
@@ -61,14 +61,6 @@ static bool 
vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
 return true;
 }
 
-llend = vhost_vdpa_section_end(section);
-if (int128_gt(llend, int128_make64(iova_max))) {
-error_report("RAM section out of device range (max=0x%" PRIx64
- ", end addr=0x%" PRIx64 ")",
- iova_max, int128_get64(llend));
-return true;
-}
-
 return false;
 }
 
@@ -173,6 +165,106 @@ static void vhost_vdpa_listener_commit(MemoryListener 
*listener)
 v->iotlb_batch_begin_sent = false;
 }
 
+static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
+{
+struct vdpa_iommu *iommu = container_of(n, struct vdpa_iommu, n);
+
+hwaddr iova = iotlb->iova + iommu->iommu_offset;
+struct vhost_vdpa *v = iommu->dev;
+void *vaddr;
+int ret;
+
+if (iotlb->target_as != &address_space_memory) {
+error_report("Wrong target AS \"%s\", only system memory is allowed",
+ iotlb->target_as->name ? iotlb->target_as->name : "none");
+return;
+}
+RCU_READ_LOCK_GUARD();
+vhost_vdpa_iotlb_batch_begin_once(v);
+
+if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
+bool read_only;
+
+if (!memory_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, NULL)) {
+return;
+}
+ret =
+vhost_vdpa_dma_map(v, iova, iotlb->addr_mask + 1, vaddr, 
read_only);
+if (ret) {
+error_report("vhost_vdpa_dma_map(%p, 0x%" HWADDR_PRIx ", "
+ "0x%" HWADDR_PRIx ", %p) = %d (%m)",
+ v, iova, iotlb->addr_mask + 1, vaddr, ret);
+}
+} else {
+ret = vhost_vdpa_dma_unmap(v, iova, iotlb->addr_mask + 1);
+if (ret) {
+error_report("vhost_vdpa_dma_unmap(%p, 0x%" HWADDR_PRIx ", "
+ "0x%" HWADDR_PRIx ") = %d (%m)",
+ v, iova, iotlb->addr_mask + 1, ret);
+}
+}
+}
+
+static void vhost_vdpa_iommu_region_add(MemoryListener *listener,
+MemoryRegionSection *section)
+{
+struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
+
+struct vdpa_iommu *iommu;
+Int128 end;
+int iommu_idx;
+IOMMUMemoryRegion *iommu_mr;
+int ret;
+
+iommu_mr = IOMMU_MEMORY_REGION(section->mr);
+
+iommu = g_malloc0(sizeof(*iommu));
+end =  int128_add(int128_make64(section->offset_within_region),
+section->size);
+end = int128_sub(end, int128_one());
+iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr,
+MEMTXATTRS_UNSPECIFIED);
+
+iommu->iommu_mr = iommu_mr;
+
+iommu_notifier_init(
+&iommu->n, vhost_vdpa_iommu_map_notify, IOMMU_NOTIFIER_IOTLB_EVENTS,
+section->offset_within_region, int128_get64(end), iommu_idx);
+iommu->iommu_offset =
+section->offset_within_address_space - section->offset_within_region;
+iommu->dev = v;
+
+ret = memory_region_register_iommu_notifier(section->mr, &iommu->n, NULL);
+if (ret) {
+g_free(iommu);
+return;
+}
+
+QLIST_INSERT_HEAD(&v->iommu_list, iommu, iommu_next);
+memory_region_iommu_replay(iommu->iommu_mr, &iommu->n);
+
+return;
+}
+
+static void vhost_vdpa_iommu_region_del(MemoryListener *listener,
+MemoryRegionSection *section)
+{
+struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
+
+struct vdpa_iommu *iommu;
+
+QLIST_FOREACH(iommu, &v->iommu_list, iommu_next)
+{
+if (MEMORY_REGION(iommu->iommu_mr) == section->mr &&
+iommu->n.start == section->offset_within_region) {
+memory_re

[PATCH v8 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Cindy Lu
- Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
  change the name to memory_get_xlat_addr(). So we can use this
  function on other devices, such as vDPA device.
- Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
  whether the memory is backed by a discard manager. the device can
  have its own warning.

Signed-off-by: Cindy Lu 
---
 hw/vfio/common.c  | 101 +++---
 include/exec/memory.h |   4 ++
 softmmu/memory.c  |  72 ++
 3 files changed, 102 insertions(+), 75 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index ace9562a9b..5bfd55de86 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -578,86 +578,37 @@ static bool 
vfio_listener_skipped_section(MemoryRegionSection *section)
 static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
ram_addr_t *ram_addr, bool *read_only)
 {
-MemoryRegion *mr;
-hwaddr xlat;
-hwaddr len = iotlb->addr_mask + 1;
-bool writable = iotlb->perm & IOMMU_WO;
-
-/*
- * The IOMMU TLB entry we have just covers translation through
- * this IOMMU to its immediate target.  We need to translate
- * it the rest of the way through to memory.
- */
-mr = address_space_translate(&address_space_memory,
- iotlb->translated_addr,
- &xlat, &len, writable,
- MEMTXATTRS_UNSPECIFIED);
-if (!memory_region_is_ram(mr)) {
-error_report("iommu map to non memory area %"HWADDR_PRIx"",
- xlat);
-return false;
-} else if (memory_region_has_ram_discard_manager(mr)) {
-RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
-MemoryRegionSection tmp = {
-.mr = mr,
-.offset_within_region = xlat,
-.size = int128_make64(len),
-};
-
+bool mr_has_discard_manager;
+if (memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
+ &mr_has_discard_manager)) {
 /*
- * Malicious VMs can map memory into the IOMMU, which is expected
- * to remain discarded. vfio will pin all pages, populating memory.
- * Disallow that. vmstate priorities make sure any RamDiscardManager
- * were already restored before IOMMUs are restored.
+ * if the mr has the discard_manager and the return value of
+ * memory_get_xlat_addr() is ture then we need to warn
  */
-if (!ram_discard_manager_is_populated(rdm, &tmp)) {
-error_report("iommu map to discarded memory (e.g., unplugged via"
- " virtio-mem): %"HWADDR_PRIx"",
- iotlb->translated_addr);
-return false;
+if (mr_has_discard_manager) {
+/*
+ * Malicious VMs might trigger discarding of IOMMU-mapped memory.
+ * The pages will remain pinned inside vfio until unmapped,
+ * resulting in a higher memory consumption than expected. If 
memory
+ * would get populated again later, there would be an inconsistency
+ * between pages pinned by vfio and pages seen by QEMU. This is the
+ * case until unmapped from the IOMMU (e.g., during device reset).
+ *
+ * With malicious guests, we really only care about pinning more
+ * memory than expected. RLIMIT_MEMLOCK set for the user/process 
can
+ * never be exceeded and can be used to mitigate this problem.
+ */
+warn_report_once(
+"Using vfio with vIOMMUs and coordinated discarding of"
+" RAM (e.g., virtio-mem) works, however, malicious"
+" guests can trigger pinning of more memory than"
+" intended via an IOMMU. It's possible to mitigate "
+" by setting/adjusting RLIMIT_MEMLOCK.");
 }
 
-/*
- * Malicious VMs might trigger discarding of IOMMU-mapped memory. The
- * pages will remain pinned inside vfio until unmapped, resulting in a
- * higher memory consumption than expected. If memory would get
- * populated again later, there would be an inconsistency between pages
- * pinned by vfio and pages seen by QEMU. This is the case until
- * unmapped from the IOMMU (e.g., during device reset).
- *
- * With malicious guests, we really only care about pinning more memory
- * than expected. RLIMIT_MEMLOCK set for the user/process can never be
- * exceeded and can be used to mitigate this problem.
- */
-warn_report_once("Using vfio with vIOMMUs and coordinated discarding 
of"
- " RAM (e.g., virtio-mem) works, however, malicious"
- " guests can trigger pinning of more memory than"
-  

Re: [PATCH v7 1/2] vfio: move function vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Cindy Lu
On Mon, 31 Oct 2022 at 01:35, Alex Williamson
 wrote:
>
> On Mon, 31 Oct 2022 00:45:38 +0800
> Cindy Lu  wrote:
>
> > - Move the function vfio_get_xlat_addr to softmmu/memory.c, and
> >   change the name to memory_get_xlat_addr(). So we can use this
> >   function on other devices, such as vDPA device.
> > - Add a new bool arg in this function, which shows whether the memory is
> >   backed by a discard manager. So the device can have its own warning.
> >
> > Signed-off-by: Cindy Lu 
> > ---
> >  hw/vfio/common.c  | 107 +++---
> >  include/exec/memory.h |   4 ++
> >  softmmu/memory.c  |  72 
> >  3 files changed, 104 insertions(+), 79 deletions(-)
> >
> > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > index ace9562a9b..a934262f39 100644
> > --- a/hw/vfio/common.c
> > +++ b/hw/vfio/common.c
> > @@ -573,61 +573,20 @@ static bool 
> > vfio_listener_skipped_section(MemoryRegionSection *section)
> >  */
> > section->offset_within_address_space & (1ULL << 63);
> >  }
> > -
> > -/* Called with rcu_read_lock held.  */
> > -static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> > -   ram_addr_t *ram_addr, bool *read_only)
> > +static inline void vfio_mr_discard_manager_warn(bool 
> > mr_has_discard_manager)
> >  {
> > -MemoryRegion *mr;
> > -hwaddr xlat;
> > -hwaddr len = iotlb->addr_mask + 1;
> > -bool writable = iotlb->perm & IOMMU_WO;
> > -
> > -/*
> > - * The IOMMU TLB entry we have just covers translation through
> > - * this IOMMU to its immediate target.  We need to translate
> > - * it the rest of the way through to memory.
> > - */
> > -mr = address_space_translate(&address_space_memory,
> > - iotlb->translated_addr,
> > - &xlat, &len, writable,
> > - MEMTXATTRS_UNSPECIFIED);
> > -if (!memory_region_is_ram(mr)) {
> > -error_report("iommu map to non memory area %"HWADDR_PRIx"",
> > - xlat);
> > -return false;
> > -} else if (memory_region_has_ram_discard_manager(mr)) {
> > -RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
> > -MemoryRegionSection tmp = {
> > -.mr = mr,
> > -.offset_within_region = xlat,
> > -.size = int128_make64(len),
> > -};
> > -
> > -/*
> > - * Malicious VMs can map memory into the IOMMU, which is expected
> > - * to remain discarded. vfio will pin all pages, populating memory.
> > - * Disallow that. vmstate priorities make sure any 
> > RamDiscardManager
> > - * were already restored before IOMMUs are restored.
> > - */
> > -if (!ram_discard_manager_is_populated(rdm, &tmp)) {
> > -error_report("iommu map to discarded memory (e.g., unplugged 
> > via"
> > - " virtio-mem): %"HWADDR_PRIx"",
> > - iotlb->translated_addr);
> > -return false;
> > -}
> > -
> > +if (mr_has_discard_manager) {
> >  /*
> > - * Malicious VMs might trigger discarding of IOMMU-mapped memory. 
> > The
> > - * pages will remain pinned inside vfio until unmapped, resulting 
> > in a
> > - * higher memory consumption than expected. If memory would get
> > - * populated again later, there would be an inconsistency between 
> > pages
> > - * pinned by vfio and pages seen by QEMU. This is the case until
> > - * unmapped from the IOMMU (e.g., during device reset).
> > + * Malicious VMs might trigger discarding of IOMMU-mapped memory.
> > + * The pages will remain pinned inside vfio until unmapped,
> > + * resulting in a higher memory consumption than expected. If 
> > memory
> > + * would get populated again later, there would be an inconsistency
> > + * between pages pinned by vfio and pages seen by QEMU. This is the
> > + * case until unmapped from the IOMMU (e.g., during device reset).
> >   *
> > - * With malicious guests, we really only care about pinning more 
> > memory
> > - * than expected. RLIMIT_MEMLOCK set for the user/process can 
> > never be
> > - * exceeded and can be used to mitigate this problem.
> > + * With malicious guests, we really only care about pinning more
> > + * memory than expected. RLIMIT_MEMLOCK set for the user/process 
> > can
> > + * never be exceeded and can be used to mitigate this problem.
> >   */
> >  warn_report_once("Using vfio with vIOMMUs and coordinated 
> > discarding of"
> >   " RAM (e.g., virtio-mem) works, however, 
> > malicious"
> > @@ -635,31 +594,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, 
> > void **vaddr,
> >  

[PATCH qemu.git 01/11] hw/timer/imx_epit: fix typo in comment

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index ec0fa440d7..06785fe6f6 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -254,7 +254,7 @@ static void imx_epit_write(void *opaque, hwaddr offset, 
uint64_t value,
 break;
 
 case 1: /* SR - ACK*/
-/* writing 1 to OCIF clear the OCIF bit */
+/* writing 1 to OCIF clears the OCIF bit */
 if (value & 0x01) {
 s->sr = 0;
 imx_epit_update_int(s);
-- 
2.34.5




[PATCH qemu.git 02/11] hw/timer/imx_epit: improve comments

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 06785fe6f6..b6c013292f 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -352,8 +352,18 @@ static void imx_epit_realize(DeviceState *dev, Error 
**errp)
   0x1000);
 sysbus_init_mmio(sbd, &s->iomem);
 
+/*
+ * The reload timer keeps running when the peripheral is enabled. It is a
+ * kind of wall clock that does not generate any interrupts. The callback
+ * needs to be provided, but it does nothing as the ptimer already supports
+ * all necessary reloading functionality.
+ */
 s->timer_reload = ptimer_init(imx_epit_reload, s, PTIMER_POLICY_LEGACY);
 
+/*
+ * The compare timer is running only when the peripheral configuration is
+ * in a state that will generate compare interrupts.
+ */
 s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_LEGACY);
 }
 
-- 
2.34.5




[PATCH qemu.git 03/11] hw/timer/imx_epit: factor out register write handlers

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 189 
 1 file changed, 103 insertions(+), 86 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index b6c013292f..a79f58c963 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -188,111 +188,128 @@ static void imx_epit_reload_compare_timer(IMXEPITState 
*s)
 }
 }
 
-static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
-   unsigned size)
+static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
 {
-IMXEPITState *s = IMX_EPIT(opaque);
-uint64_t oldcr;
-
-DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(offset >> 2),
-(uint32_t)value);
-
-switch (offset >> 2) {
-case 0: /* CR */
-
-oldcr = s->cr;
-s->cr = value & 0x03ff;
-if (s->cr & CR_SWR) {
-/* handle the reset */
-imx_epit_reset(DEVICE(s));
-/*
- * TODO: could we 'break' here? following operations appear
- * to duplicate the work imx_epit_reset() already did.
- */
-}
-
-ptimer_transaction_begin(s->timer_cmp);
-ptimer_transaction_begin(s->timer_reload);
+uint32_t oldcr = s->cr;
+s->cr = value & 0x03ff;
+if (s->cr & CR_SWR) {
+/* handle the reset */
+imx_epit_reset(DEVICE(s));
+/*
+ * TODO: could we 'break' here? following operations appear
+ * to duplicate the work imx_epit_reset() already did.
+ */
+}
 
-if (!(s->cr & CR_SWR)) {
-imx_epit_set_freq(s);
-}
+ptimer_transaction_begin(s->timer_cmp);
+ptimer_transaction_begin(s->timer_reload);
 
-if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
-if (s->cr & CR_ENMOD) {
-if (s->cr & CR_RLD) {
-ptimer_set_limit(s->timer_reload, s->lr, 1);
-ptimer_set_limit(s->timer_cmp, s->lr, 1);
-} else {
-ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
-ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
-}
-}
+if (!(s->cr & CR_SWR)) {
+imx_epit_set_freq(s);
+}
 
-imx_epit_reload_compare_timer(s);
-ptimer_run(s->timer_reload, 0);
-if (s->cr & CR_OCIEN) {
-ptimer_run(s->timer_cmp, 0);
+if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
+if (s->cr & CR_ENMOD) {
+if (s->cr & CR_RLD) {
+ptimer_set_limit(s->timer_reload, s->lr, 1);
+ptimer_set_limit(s->timer_cmp, s->lr, 1);
 } else {
-ptimer_stop(s->timer_cmp);
-}
-} else if (!(s->cr & CR_EN)) {
-/* stop both timers */
-ptimer_stop(s->timer_reload);
-ptimer_stop(s->timer_cmp);
-} else  if (s->cr & CR_OCIEN) {
-if (!(oldcr & CR_OCIEN)) {
-imx_epit_reload_compare_timer(s);
-ptimer_run(s->timer_cmp, 0);
+ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
+ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
 }
+}
+
+imx_epit_reload_compare_timer(s);
+ptimer_run(s->timer_reload, 0);
+if (s->cr & CR_OCIEN) {
+ptimer_run(s->timer_cmp, 0);
 } else {
 ptimer_stop(s->timer_cmp);
 }
+} else if (!(s->cr & CR_EN)) {
+/* stop both timers */
+ptimer_stop(s->timer_reload);
+ptimer_stop(s->timer_cmp);
+} else if (s->cr & CR_OCIEN) {
+if (!(oldcr & CR_OCIEN)) {
+imx_epit_reload_compare_timer(s);
+ptimer_run(s->timer_cmp, 0);
+}
+} else {
+ptimer_stop(s->timer_cmp);
+}
+
+ptimer_transaction_commit(s->timer_cmp);
+ptimer_transaction_commit(s->timer_reload);
+}
+
+static void imx_epit_write_sr(IMXEPITState *s, uint32_t value)
+{
+/* writing 1 to OCIF clears the OCIF bit */
+if (value & 0x01) {
+s->sr = 0;
+imx_epit_update_int(s);
+}
+}
+
+static void imx_epit_write_lr(IMXEPITState *s, uint32_t value)
+{
+s->lr = value;
+
+ptimer_transaction_begin(s->timer_cmp);
+ptimer_transaction_begin(s->timer_reload);
+if (s->cr & CR_RLD) {
+/* Also set the limit if the LRD bit is set */
+/* If IOVW bit is set then set the timer value */
+ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
+ptimer_set_limit(s->timer_cmp, s->lr, 0);
+} else if (s->cr & CR_IOVW) {
+/* If IOVW bit is set then set the timer value */
+ptimer_set_count(s->timer_reload, s->lr);
+}
+/*
+ * Commit the change to s->timer_reload, so it can propagate. Otherwise
+ * the timer interrupt may not fire properly. The commit must happen
+ * be

[PATCH qemu.git 08/11] hw/timer/imx_epit: simplify CR.ENMOD handling

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index bba9c87cd4..5915d4b3d4 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -198,13 +198,10 @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t 
value)
 
 if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
 if (s->cr & CR_ENMOD) {
-if (s->cr & CR_RLD) {
-ptimer_set_limit(s->timer_reload, s->lr, 1);
-ptimer_set_limit(s->timer_cmp, s->lr, 1);
-} else {
-ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
-ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
-}
+uint64_t limit = (s->cr & CR_RLD) ? s->lr : EPIT_TIMER_MAX;
+/* set new limit and also set timer to this value right now */
+ptimer_set_limit(s->timer_reload, limit, 1);
+ptimer_set_limit(s->timer_cmp, limit, 1);
 }
 
 imx_epit_reload_compare_timer(s);
-- 
2.34.5




[PATCH qemu.git 07/11] hw/timer/imx_epit: do not persist CR.SWR bit

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 2e4ff89613..bba9c87cd4 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -175,9 +175,12 @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
 static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
 {
 uint32_t freq = 0;
+
+/* SWR bit is never persisted, it clears itself once reset is done */
 uint32_t oldcr = s->cr;
-s->cr = value & 0x03ff;
-if (s->cr & CR_SWR) {
+s->cr = (value & ~CR_SWR) & 0x03ff;
+
+if (value & CR_SWR) {
 /* handle the reset */
 imx_epit_reset(DEVICE(s));
 /*
@@ -189,7 +192,7 @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t 
value)
 ptimer_transaction_begin(s->timer_cmp);
 ptimer_transaction_begin(s->timer_reload);
 
-if (!(s->cr & CR_SWR)) {
+if (!(value & CR_SWR)) {
 freq = imx_epit_set_freq(s);
 }
 
-- 
2.34.5




[PATCH qemu.git 06/11] hw/timer/imx_epit: software reset clears the interrupt

2022-10-30 Thread ~axelheider
From: Axel Heider 

---
 hw/timer/imx_epit.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index d21cbf16f6..2e4ff89613 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -97,6 +97,9 @@ static void imx_epit_reset(DeviceState *dev)
 s->sr = 0;
 s->lr = EPIT_TIMER_MAX;
 s->cmp = 0;
+/* clear the interrupt */
+qemu_irq_lower(s->irq);
+
 ptimer_transaction_begin(s->timer_cmp);
 ptimer_transaction_begin(s->timer_reload);
 /* stop both timers */
-- 
2.34.5




[PATCH qemu.git 09/11] hw/timer/imx_epit: cleanup CR defines

2022-10-30 Thread ~axelheider
From: Axel Heider 

remove unused defines, add needed defines

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 4 ++--
 include/hw/timer/imx_epit.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 5915d4b3d4..196fc67c30 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -71,8 +71,8 @@ static uint32_t imx_epit_set_freq(IMXEPITState *s)
 uint32_t prescaler;
 uint32_t freq;
 
-clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
-prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
+clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
+prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
 
 freq = imx_ccm_get_clock_frequency(s->ccm,
 imx_epit_clocks[clksrc]) / prescaler;
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
index 2219a426ab..f6d41be7e1 100644
--- a/include/hw/timer/imx_epit.h
+++ b/include/hw/timer/imx_epit.h
@@ -43,7 +43,7 @@
 #define CR_OCIEN(1 << 2)
 #define CR_RLD  (1 << 3)
 #define CR_PRESCALE_SHIFT (4)
-#define CR_PRESCALE_MASK  (0xfff)
+#define CR_PRESCALE_BITS  (12)
 #define CR_SWR  (1 << 16)
 #define CR_IOVW (1 << 17)
 #define CR_DBGEN(1 << 18)
@@ -51,7 +51,7 @@
 #define CR_DOZEN(1 << 20)
 #define CR_STOPEN   (1 << 21)
 #define CR_CLKSRC_SHIFT (24)
-#define CR_CLKSRC_MASK  (0x3 << CR_CLKSRC_SHIFT)
+#define CR_CLKSRC_BITS  (2)
 
 #define EPIT_TIMER_MAX  0XUL
 
-- 
2.34.5




[PATCH qemu.git 00/11] improve hw/timer/imx_epit

2022-10-30 Thread ~axelheider
This is a follow-up on my initial work to fix https://gitlab.com/qemu-
project/qemu/-/issues/1263.
- fix #1263 for CR writes
- fix compare timer update
- software reset clears the interrupt
- do not persist CR.SWR bit
- general code cleanup and comment improvements

Axel Heider (11):
  hw/timer/imx_epit: fix typo in comment
  hw/timer/imx_epit: improve comments
  hw/timer/imx_epit: factor out register write handlers
  hw/timer/imx_epit: remove explicit fields cnt and freq
  hw/timer/imx_epit: simplify interrupt logic
  hw/timer/imx_epit: software reset clears the interrupt
  hw/timer/imx_epit: do not persist CR.SWR bit
  hw/timer/imx_epit: simplify CR.ENMOD handling
  hw/timer/imx_epit: cleanup CR defines
  hw/timer/imx_epit: fix compare timer update
  hw/timer/imx_epit: rework CR write handling

 hw/timer/imx_epit.c | 372 +++-
 include/hw/timer/imx_epit.h |   6 +-
 2 files changed, 200 insertions(+), 178 deletions(-)

-- 
2.34.5



[PATCH qemu.git 11/11] hw/timer/imx_epit: rework CR write handling

2022-10-30 Thread ~axelheider
From: Axel Heider 

- simplify code, improve comments
- fix https://gitlab.com/qemu-project/qemu/-/issues/1263

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 139 +---
 1 file changed, 65 insertions(+), 74 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 7dd9f54c9c..4a6326b1de 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -69,43 +69,6 @@ static uint32_t imx_epit_get_freq(IMXEPITState *s)
 return f_in / prescaler;
 }
 
-static void imx_epit_reset(DeviceState *dev)
-{
-IMXEPITState *s = IMX_EPIT(dev);
-
-/*
- * Soft reset doesn't touch some bits; hard reset clears them
- */
-s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
-s->sr = 0;
-s->lr = EPIT_TIMER_MAX;
-s->cmp = 0;
-/* clear the interrupt */
-qemu_irq_lower(s->irq);
-
-ptimer_transaction_begin(s->timer_cmp);
-ptimer_transaction_begin(s->timer_reload);
-/* stop both timers */
-ptimer_stop(s->timer_cmp);
-ptimer_stop(s->timer_reload);
-/* compute new frequency */
-uint32_t freq = imx_epit_get_freq(s);
-DPRINTF("Setting ptimer frequency to %u\n", freq);
-if (freq) {
-ptimer_set_freq(s->timer_reload, freq);
-ptimer_set_freq(s->timer_cmp, freq);
-}
-/* init both timers to EPIT_TIMER_MAX */
-ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
-ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
-if (freq && (s->cr & CR_EN)) {
-/* if the timer is still enabled, restart it */
-ptimer_run(s->timer_reload, 0);
-}
-ptimer_transaction_commit(s->timer_cmp);
-ptimer_transaction_commit(s->timer_reload);
-}
-
 static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
 {
 IMXEPITState *s = IMX_EPIT(opaque);
@@ -192,56 +155,75 @@ static void imx_epit_update_compare_timer(IMXEPITState *s)
 
 static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
 {
-uint32_t freq = 0;
+ptimer_transaction_begin(s->timer_cmp);
+ptimer_transaction_begin(s->timer_reload);
 
-/* SWR bit is never persisted, it clears itself once reset is done */
 uint32_t oldcr = s->cr;
 s->cr = (value & ~CR_SWR) & 0x03ff;
 
 if (value & CR_SWR) {
-/* handle the reset */
-imx_epit_reset(DEVICE(s));
 /*
- * TODO: could we 'break' here? following operations appear
- * to duplicate the work imx_epit_reset() already did.
+ * Soft reset doesn't touch some bits, just a hard reset clears all
+ * of them. Clearing CLKSRC disables the input clock, which will
+ * happen when we re-init of the timer frequency below.
+ */
+s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
+/*
+ * We have applied the new CR value and then cleared most bits,
+ * thus some bits from the write request are now lost. The TRM
+ * is not clear about the behavior, maybe these bits are to be
+ * applied after the reset (e.g. for selecting a new clock
+ * source). However, it seem this is undefined behavior and a
+ * it's assumed a reset does not try to do anything else.
  */
+s->sr = 0;
+s->lr = EPIT_TIMER_MAX;
+s->cmp = 0;
+/* turn interrupt off since SR and the OCIEN bit is cleared */
+qemu_irq_lower(s->irq);
+/* reset timer limits, set timer values to the limits */
+ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
+ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
 }
 
-ptimer_transaction_begin(s->timer_cmp);
-ptimer_transaction_begin(s->timer_reload);
-
-if (!(value & CR_SWR)) {
-uint32_t freq = imx_epit_get_freq(s);
+/* re-initialize frequency, or turn off timers if input clock is off */
+uint32_t freq = imx_epit_get_freq(s);
+if (freq) {
 DPRINTF("Setting ptimer frequency to %u\n", freq);
-if (freq) {
-ptimer_set_freq(s->timer_reload, freq);
-ptimer_set_freq(s->timer_cmp, freq);
-}
+ptimer_set_freq(s->timer_reload, freq);
+ptimer_set_freq(s->timer_cmp, freq);
 }
 
-if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
-if (s->cr & CR_ENMOD) {
-uint64_t limit = (s->cr & CR_RLD) ? s->lr : EPIT_TIMER_MAX;
-/* set new limit and also set timer to this value right now */
-ptimer_set_limit(s->timer_reload, limit, 1);
-ptimer_set_limit(s->timer_cmp, limit, 1);
-}
-ptimer_run(s->timer_reload, 0);
-imx_epit_update_compare_timer(s);
-} else if (!(s->cr & CR_EN)) {
-/* stop both timers */
-ptimer_stop(s->timer_reload);
+if (!freq || !(s->cr & CR_EN)) {
+/*
+ * The EPIT timer is effectively disabled if it is not enabled or
+ * the input clock is off. In this case we can stop the ptimers.
+   

[PATCH qemu.git 05/11] hw/timer/imx_epit: simplify interrupt logic

2022-10-30 Thread ~axelheider
From: Axel Heider 

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 23 +--
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 37b04a1b53..d21cbf16f6 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -61,18 +61,6 @@ static const IMXClk imx_epit_clocks[] =  {
 CLK_32k,   /* 11 ipg_clk_32k -- ~32kHz */
 };
 
-/*
- * Update interrupt status
- */
-static void imx_epit_update_int(IMXEPITState *s)
-{
-if (s->sr && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {
-qemu_irq_raise(s->irq);
-} else {
-qemu_irq_lower(s->irq);
-}
-}
-
 /*
  * Must be called from within a ptimer_transaction_begin/commit block
  * for both s->timer_cmp and s->timer_reload.
@@ -242,7 +230,7 @@ static void imx_epit_write_sr(IMXEPITState *s, uint32_t 
value)
 /* writing 1 to OCIF clears the OCIF bit */
 if (value & 0x01) {
 s->sr = 0;
-imx_epit_update_int(s);
+qemu_irq_lower(s->irq);
 }
 }
 
@@ -320,7 +308,14 @@ static void imx_epit_cmp(void *opaque)
 DPRINTF("sr was %d\n", s->sr);
 
 s->sr = 1;
-imx_epit_update_int(s);
+
+/*
+ * An interrupt is generated only if both the peripheral is enabled and the
+ * interrupt generation is enabled.
+ */
+if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN)) {
+qemu_irq_raise(s->irq);
+}
 }
 
 static void imx_epit_reload(void *opaque)
-- 
2.34.5




[PATCH qemu.git 04/11] hw/timer/imx_epit: remove explicit fields cnt and freq

2022-10-30 Thread ~axelheider
From: Axel Heider 

The CNT register is a read-only register. There is no need to
store it's value, it can be calculated on demand.
The calculated frequency is needed temporarily only.

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 42 +++--
 include/hw/timer/imx_epit.h |  2 --
 2 files changed, 17 insertions(+), 27 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index a79f58c963..37b04a1b53 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -77,23 +77,25 @@ static void imx_epit_update_int(IMXEPITState *s)
  * Must be called from within a ptimer_transaction_begin/commit block
  * for both s->timer_cmp and s->timer_reload.
  */
-static void imx_epit_set_freq(IMXEPITState *s)
+static uint32_t imx_epit_set_freq(IMXEPITState *s)
 {
 uint32_t clksrc;
 uint32_t prescaler;
+uint32_t freq;
 
 clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
 prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
 
-s->freq = imx_ccm_get_clock_frequency(s->ccm,
+freq = imx_ccm_get_clock_frequency(s->ccm,
 imx_epit_clocks[clksrc]) / prescaler;
 
-DPRINTF("Setting ptimer frequency to %u\n", s->freq);
+DPRINTF("Setting ptimer frequency to %u\n", freq);
 
-if (s->freq) {
-ptimer_set_freq(s->timer_reload, s->freq);
-ptimer_set_freq(s->timer_cmp, s->freq);
+if (freq) {
+ptimer_set_freq(s->timer_reload, freq);
+ptimer_set_freq(s->timer_cmp, freq);
 }
+return freq;
 }
 
 static void imx_epit_reset(DeviceState *dev)
@@ -107,18 +109,17 @@ static void imx_epit_reset(DeviceState *dev)
 s->sr = 0;
 s->lr = EPIT_TIMER_MAX;
 s->cmp = 0;
-s->cnt = 0;
 ptimer_transaction_begin(s->timer_cmp);
 ptimer_transaction_begin(s->timer_reload);
 /* stop both timers */
 ptimer_stop(s->timer_cmp);
 ptimer_stop(s->timer_reload);
 /* compute new frequency */
-imx_epit_set_freq(s);
+uint32_t freq = imx_epit_set_freq(s);
 /* init both timers to EPIT_TIMER_MAX */
 ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
 ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
-if (s->freq && (s->cr & CR_EN)) {
+if (freq && (s->cr & CR_EN)) {
 /* if the timer is still enabled, restart it */
 ptimer_run(s->timer_reload, 0);
 }
@@ -126,13 +127,6 @@ static void imx_epit_reset(DeviceState *dev)
 ptimer_transaction_commit(s->timer_reload);
 }
 
-static uint32_t imx_epit_update_count(IMXEPITState *s)
-{
-s->cnt = ptimer_get_count(s->timer_reload);
-
-return s->cnt;
-}
-
 static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
 {
 IMXEPITState *s = IMX_EPIT(opaque);
@@ -156,8 +150,7 @@ static uint64_t imx_epit_read(void *opaque, hwaddr offset, 
unsigned size)
 break;
 
 case 4: /* CNT */
-imx_epit_update_count(s);
-reg_value = s->cnt;
+reg_value = ptimer_get_count(s->timer_reload);
 break;
 
 default:
@@ -176,7 +169,7 @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
 {
 if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN))  {
 /* if the compare feature is on and timers are running */
-uint32_t tmp = imx_epit_update_count(s);
+uint32_t tmp = ptimer_get_count(s->timer_reload);
 uint64_t next;
 if (tmp > s->cmp) {
 /* It'll fire in this round of the timer */
@@ -190,6 +183,7 @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
 
 static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
 {
+uint32_t freq = 0;
 uint32_t oldcr = s->cr;
 s->cr = value & 0x03ff;
 if (s->cr & CR_SWR) {
@@ -205,10 +199,10 @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t 
value)
 ptimer_transaction_begin(s->timer_reload);
 
 if (!(s->cr & CR_SWR)) {
-imx_epit_set_freq(s);
+freq = imx_epit_set_freq(s);
 }
 
-if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
+if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
 if (s->cr & CR_ENMOD) {
 if (s->cr & CR_RLD) {
 ptimer_set_limit(s->timer_reload, s->lr, 1);
@@ -342,15 +336,13 @@ static const MemoryRegionOps imx_epit_ops = {
 
 static const VMStateDescription vmstate_imx_timer_epit = {
 .name = TYPE_IMX_EPIT,
-.version_id = 2,
-.minimum_version_id = 2,
+.version_id = 3,
+.minimum_version_id = 3,
 .fields = (VMStateField[]) {
 VMSTATE_UINT32(cr, IMXEPITState),
 VMSTATE_UINT32(sr, IMXEPITState),
 VMSTATE_UINT32(lr, IMXEPITState),
 VMSTATE_UINT32(cmp, IMXEPITState),
-VMSTATE_UINT32(cnt, IMXEPITState),
-VMSTATE_UINT32(freq, IMXEPITState),
 VMSTATE_PTIMER(timer_reload, IMXEPITState),
 VMSTATE_PTIMER(timer_cmp, IMXEPITState),
 VMSTATE_END_OF_LIST()
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
index 2acc41e

[PATCH qemu.git 10/11] hw/timer/imx_epit: fix compare timer update

2022-10-30 Thread ~axelheider
From: Axel Heider 

The compare timer will never fire if the reload value is less
than the compare value, so it must be disabled in this case.
The compare time fire exactly once when the compare value is
less than the current value, but the reload values is less
than the compare value.

Signed-off-by: Axel Heider 
---
 hw/timer/imx_epit.c | 112 +---
 1 file changed, 64 insertions(+), 48 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 196fc67c30..7dd9f54c9c 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -61,29 +61,12 @@ static const IMXClk imx_epit_clocks[] =  {
 CLK_32k,   /* 11 ipg_clk_32k -- ~32kHz */
 };
 
-/*
- * Must be called from within a ptimer_transaction_begin/commit block
- * for both s->timer_cmp and s->timer_reload.
- */
-static uint32_t imx_epit_set_freq(IMXEPITState *s)
+static uint32_t imx_epit_get_freq(IMXEPITState *s)
 {
-uint32_t clksrc;
-uint32_t prescaler;
-uint32_t freq;
-
-clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
-prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
-
-freq = imx_ccm_get_clock_frequency(s->ccm,
-imx_epit_clocks[clksrc]) / prescaler;
-
-DPRINTF("Setting ptimer frequency to %u\n", freq);
-
-if (freq) {
-ptimer_set_freq(s->timer_reload, freq);
-ptimer_set_freq(s->timer_cmp, freq);
-}
-return freq;
+uint32_t clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
+uint32_t prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 
CR_PRESCALE_BITS);
+uint32_t f_in = imx_ccm_get_clock_frequency(s->ccm, 
imx_epit_clocks[clksrc]);
+return f_in / prescaler;
 }
 
 static void imx_epit_reset(DeviceState *dev)
@@ -106,7 +89,12 @@ static void imx_epit_reset(DeviceState *dev)
 ptimer_stop(s->timer_cmp);
 ptimer_stop(s->timer_reload);
 /* compute new frequency */
-uint32_t freq = imx_epit_set_freq(s);
+uint32_t freq = imx_epit_get_freq(s);
+DPRINTF("Setting ptimer frequency to %u\n", freq);
+if (freq) {
+ptimer_set_freq(s->timer_reload, freq);
+ptimer_set_freq(s->timer_cmp, freq);
+}
 /* init both timers to EPIT_TIMER_MAX */
 ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
 ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
@@ -155,21 +143,51 @@ static uint64_t imx_epit_read(void *opaque, hwaddr 
offset, unsigned size)
 return reg_value;
 }
 
-/* Must be called from ptimer_transaction_begin/commit block for s->timer_cmp 
*/
-static void imx_epit_reload_compare_timer(IMXEPITState *s)
+/*
+ * Must be called from a ptimer_transaction_begin/commit block for
+ * s->timer_cmp, but outside of a transaction block of s->timer_reload,
+ * so the proper counter value is read.
+ */
+static void imx_epit_update_compare_timer(IMXEPITState *s)
 {
-if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN))  {
-/* if the compare feature is on and timers are running */
-uint32_t tmp = ptimer_get_count(s->timer_reload);
-uint64_t next;
-if (tmp > s->cmp) {
-/* It'll fire in this round of the timer */
-next = tmp - s->cmp;
-} else { /* catch it next time around */
-next = tmp - s->cmp + ((s->cr & CR_RLD) ? EPIT_TIMER_MAX : s->lr);
+int is_oneshot = 0;
+
+/*
+ * The compare time will only be active when the EPIT timer is enabled
+ * (CR_EN), the compare interrupt generation is enabled (CR_OCIEN) and
+ *  the input clock if not off.
+ */
+uint32_t freq = imx_epit_get_freq(s);
+if (!freq || ((s->cr & (CR_EN | CR_OCIEN)) != (CR_EN | CR_OCIEN))) {
+ptimer_stop(s->timer_cmp);
+return;
+}
+
+/* calculate the next timeout for the compare timer. */
+uint64_t tmp = ptimer_get_count(s->timer_reload);
+uint64_t max = (s->cr & CR_RLD) ? EPIT_TIMER_MAX : s->lr;
+if (s->cmp <= tmp) {
+/* fire in this round */
+tmp -= s->cmp;
+/* if the reload value is less than the compare value, the timer will
+ * only fire once
+ */
+is_oneshot = (s->cmp > max);
+} else {
+/*
+ * fire after a reload - but only if the reload value is equal
+ * or higher than the compare value.
+ */
+if (s->cmp > max) {
+ptimer_stop(s->timer_cmp);
+return;
 }
-ptimer_set_count(s->timer_cmp, next);
+tmp += max - s->cmp;
 }
+
+/* re-initialize the compare timer and run it */
+ptimer_set_count(s->timer_cmp, tmp);
+ptimer_run(s->timer_cmp, is_oneshot);
 }
 
 static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
@@ -193,7 +211,12 @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t 
value)
 ptimer_transaction_begin(s->timer_reload);
 
 if (!(value & CR_SWR)) {
-freq = imx_epit_set_freq(s);
+uint32_t freq = imx_epit_get_freq(s)

Re: [PATCH v8 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Alex Williamson
On Mon, 31 Oct 2022 09:56:04 +0800
Cindy Lu  wrote:

> - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
>   change the name to memory_get_xlat_addr(). So we can use this
>   function on other devices, such as vDPA device.
> - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
>   whether the memory is backed by a discard manager. the device can
>   have its own warning.
> 
> Signed-off-by: Cindy Lu 
> ---
>  hw/vfio/common.c  | 101 +++---
>  include/exec/memory.h |   4 ++
>  softmmu/memory.c  |  72 ++
>  3 files changed, 102 insertions(+), 75 deletions(-)

Some changes I'd like to see below, but otherwise

Acked-by: Alex Williamson 

> 
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index ace9562a9b..5bfd55de86 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -578,86 +578,37 @@ static bool 
> vfio_listener_skipped_section(MemoryRegionSection *section)
>  static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> ram_addr_t *ram_addr, bool *read_only)
>  {
> -MemoryRegion *mr;
> -hwaddr xlat;
> -hwaddr len = iotlb->addr_mask + 1;
> -bool writable = iotlb->perm & IOMMU_WO;
> -
> -/*
> - * The IOMMU TLB entry we have just covers translation through
> - * this IOMMU to its immediate target.  We need to translate
> - * it the rest of the way through to memory.
> - */
> -mr = address_space_translate(&address_space_memory,
> - iotlb->translated_addr,
> - &xlat, &len, writable,
> - MEMTXATTRS_UNSPECIFIED);
> -if (!memory_region_is_ram(mr)) {
> -error_report("iommu map to non memory area %"HWADDR_PRIx"",
> - xlat);
> -return false;
> -} else if (memory_region_has_ram_discard_manager(mr)) {
> -RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
> -MemoryRegionSection tmp = {
> -.mr = mr,
> -.offset_within_region = xlat,
> -.size = int128_make64(len),
> -};
> -
> +bool mr_has_discard_manager;
> +if (memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
> + &mr_has_discard_manager)) {
>  /*
> - * Malicious VMs can map memory into the IOMMU, which is expected
> - * to remain discarded. vfio will pin all pages, populating memory.
> - * Disallow that. vmstate priorities make sure any RamDiscardManager
> - * were already restored before IOMMUs are restored.
> + * if the mr has the discard_manager and the return value of
> + * memory_get_xlat_addr() is ture then we need to warn

s/ture/true/

But then the comment below is really describing why we're generating a
warning, so the above additional comment is mostly just noise.

I'd also prefer to see this as:

{
bool ret, mr_has_discard_manager;

ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
   &mr_has_discard_manager));

if (ret && mr_has_discard_manager) {
// Unmodified comment and warn report from existing code
}

return ret;
}

>   */
> -if (!ram_discard_manager_is_populated(rdm, &tmp)) {
> -error_report("iommu map to discarded memory (e.g., unplugged via"
> - " virtio-mem): %"HWADDR_PRIx"",
> - iotlb->translated_addr);
> -return false;
> +if (mr_has_discard_manager) {
> +/*
> + * Malicious VMs might trigger discarding of IOMMU-mapped memory.
> + * The pages will remain pinned inside vfio until unmapped,
> + * resulting in a higher memory consumption than expected. If 
> memory
> + * would get populated again later, there would be an 
> inconsistency
> + * between pages pinned by vfio and pages seen by QEMU. This is 
> the
> + * case until unmapped from the IOMMU (e.g., during device 
> reset).
> + *
> + * With malicious guests, we really only care about pinning more
> + * memory than expected. RLIMIT_MEMLOCK set for the user/process 
> can
> + * never be exceeded and can be used to mitigate this problem.
> + */
> +warn_report_once(
> +"Using vfio with vIOMMUs and coordinated discarding of"
> +" RAM (e.g., virtio-mem) works, however, malicious"
> +" guests can trigger pinning of more memory than"
> +" intended via an IOMMU. It's possible to mitigate "
> +" by setting/adjusting RLIMIT_MEMLOCK.");
>  }
>  
> -/*
> - * Malicious VMs might trigger discarding of IOMMU-mapped memory. The
> - * pages will remain pinned inside vfio until un

Re: [PATCH v8 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Cindy Lu
On Mon, 31 Oct 2022 at 10:30, Alex Williamson
 wrote:
>
> On Mon, 31 Oct 2022 09:56:04 +0800
> Cindy Lu  wrote:
>
> > - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
> >   change the name to memory_get_xlat_addr(). So we can use this
> >   function on other devices, such as vDPA device.
> > - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
> >   whether the memory is backed by a discard manager. the device can
> >   have its own warning.
> >
> > Signed-off-by: Cindy Lu 
> > ---
> >  hw/vfio/common.c  | 101 +++---
> >  include/exec/memory.h |   4 ++
> >  softmmu/memory.c  |  72 ++
> >  3 files changed, 102 insertions(+), 75 deletions(-)
>
> Some changes I'd like to see below, but otherwise
>
> Acked-by: Alex Williamson 
>
> >
> > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > index ace9562a9b..5bfd55de86 100644
> > --- a/hw/vfio/common.c
> > +++ b/hw/vfio/common.c
> > @@ -578,86 +578,37 @@ static bool 
> > vfio_listener_skipped_section(MemoryRegionSection *section)
> >  static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> > ram_addr_t *ram_addr, bool *read_only)
> >  {
> > -MemoryRegion *mr;
> > -hwaddr xlat;
> > -hwaddr len = iotlb->addr_mask + 1;
> > -bool writable = iotlb->perm & IOMMU_WO;
> > -
> > -/*
> > - * The IOMMU TLB entry we have just covers translation through
> > - * this IOMMU to its immediate target.  We need to translate
> > - * it the rest of the way through to memory.
> > - */
> > -mr = address_space_translate(&address_space_memory,
> > - iotlb->translated_addr,
> > - &xlat, &len, writable,
> > - MEMTXATTRS_UNSPECIFIED);
> > -if (!memory_region_is_ram(mr)) {
> > -error_report("iommu map to non memory area %"HWADDR_PRIx"",
> > - xlat);
> > -return false;
> > -} else if (memory_region_has_ram_discard_manager(mr)) {
> > -RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
> > -MemoryRegionSection tmp = {
> > -.mr = mr,
> > -.offset_within_region = xlat,
> > -.size = int128_make64(len),
> > -};
> > -
> > +bool mr_has_discard_manager;
> > +if (memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
> > + &mr_has_discard_manager)) {
> >  /*
> > - * Malicious VMs can map memory into the IOMMU, which is expected
> > - * to remain discarded. vfio will pin all pages, populating memory.
> > - * Disallow that. vmstate priorities make sure any 
> > RamDiscardManager
> > - * were already restored before IOMMUs are restored.
> > + * if the mr has the discard_manager and the return value of
> > + * memory_get_xlat_addr() is ture then we need to warn
>
> s/ture/true/
>
> But then the comment below is really describing why we're generating a
> warning, so the above additional comment is mostly just noise.
>
sure, will remove this
> I'd also prefer to see this as:
>
> {
> bool ret, mr_has_discard_manager;
>
> ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
>&mr_has_discard_manager));
>
> if (ret && mr_has_discard_manager) {
> // Unmodified comment and warn report from existing code
> }
>
> return ret;
> }
>
sure, Will change this, Thanks Alex
Thanks
Cindy
> >   */
> > -if (!ram_discard_manager_is_populated(rdm, &tmp)) {
> > -error_report("iommu map to discarded memory (e.g., unplugged 
> > via"
> > - " virtio-mem): %"HWADDR_PRIx"",
> > - iotlb->translated_addr);
> > -return false;
> > +if (mr_has_discard_manager) {
> > +/*
> > + * Malicious VMs might trigger discarding of IOMMU-mapped 
> > memory.
> > + * The pages will remain pinned inside vfio until unmapped,
> > + * resulting in a higher memory consumption than expected. If 
> > memory
> > + * would get populated again later, there would be an 
> > inconsistency
> > + * between pages pinned by vfio and pages seen by QEMU. This 
> > is the
> > + * case until unmapped from the IOMMU (e.g., during device 
> > reset).
> > + *
> > + * With malicious guests, we really only care about pinning 
> > more
> > + * memory than expected. RLIMIT_MEMLOCK set for the 
> > user/process can
> > + * never be exceeded and can be used to mitigate this problem.
> > + */
> > +warn_report_once(
> > +"Using vfio with vIOMMUs and coordinated discarding of"
> > +" RAM (e.g., virtio-mem) works, however, malicious"
> > +

[PATCH v9 0/2] vhost-vdpa: add support for vIOMMU

2022-10-30 Thread Cindy Lu
These patches are to support vIOMMU in vdpa device

changes in V3
1. Move function vfio_get_xlat_addr to memory.c
2. Use the existing memory listener, while the MR is
iommu MR then call the function iommu_region_add/
iommu_region_del

changes in V4
1.make the comments in vfio_get_xlat_addr more general

changes in V5
1. Address the comments in the last version
2. Add a new arg in the function vfio_get_xlat_addr, which shows whether
the memory is backed by a discard manager. So the device can have its
own warning.

changes in V6
move the error_report for the unpopulated discard back to
memeory_get_xlat_addr

changes in V7
organize the error massage to avoid the duplicate information

changes in V8
Organize the code follow the comments in the last version

changes in V9
Organize the code follow the comments

Cindy Lu (2):
  vfio: move implement of vfio_get_xlat_addr() to memory.c
  vhost-vdpa: add support for vIOMMU

 hw/vfio/common.c   |  66 ++
 hw/virtio/vhost-vdpa.c | 123 ++---
 include/exec/memory.h  |   4 ++
 include/hw/virtio/vhost-vdpa.h |  10 +++
 softmmu/memory.c   |  72 +++
 5 files changed, 203 insertions(+), 72 deletions(-)

-- 
2.34.3




[PATCH v9 2/2] vhost-vdpa: add support for vIOMMU

2022-10-30 Thread Cindy Lu
Add support for vIOMMU. add the new function to deal with iommu MR.
- during iommu_region_add register a specific IOMMU notifier,
 and store all notifiers in a list.
- during iommu_region_del, compare and delete the IOMMU notifier from the list

Verified in vp_vdpa and vdpa_sim_net driver

Signed-off-by: Cindy Lu 
---
 hw/virtio/vhost-vdpa.c | 123 ++---
 include/hw/virtio/vhost-vdpa.h |  10 +++
 2 files changed, 122 insertions(+), 11 deletions(-)

diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 3ff9ce3501..dcfaaccfa9 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -26,6 +26,7 @@
 #include "cpu.h"
 #include "trace.h"
 #include "qapi/error.h"
+#include "hw/virtio/virtio-access.h"
 
 /*
  * Return one past the end of the end of section. Be careful with uint64_t
@@ -44,7 +45,6 @@ static bool 
vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
 uint64_t iova_min,
 uint64_t iova_max)
 {
-Int128 llend;
 
 if ((!memory_region_is_ram(section->mr) &&
  !memory_region_is_iommu(section->mr)) ||
@@ -61,14 +61,6 @@ static bool 
vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
 return true;
 }
 
-llend = vhost_vdpa_section_end(section);
-if (int128_gt(llend, int128_make64(iova_max))) {
-error_report("RAM section out of device range (max=0x%" PRIx64
- ", end addr=0x%" PRIx64 ")",
- iova_max, int128_get64(llend));
-return true;
-}
-
 return false;
 }
 
@@ -173,6 +165,106 @@ static void vhost_vdpa_listener_commit(MemoryListener 
*listener)
 v->iotlb_batch_begin_sent = false;
 }
 
+static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
+{
+struct vdpa_iommu *iommu = container_of(n, struct vdpa_iommu, n);
+
+hwaddr iova = iotlb->iova + iommu->iommu_offset;
+struct vhost_vdpa *v = iommu->dev;
+void *vaddr;
+int ret;
+
+if (iotlb->target_as != &address_space_memory) {
+error_report("Wrong target AS \"%s\", only system memory is allowed",
+ iotlb->target_as->name ? iotlb->target_as->name : "none");
+return;
+}
+RCU_READ_LOCK_GUARD();
+vhost_vdpa_iotlb_batch_begin_once(v);
+
+if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
+bool read_only;
+
+if (!memory_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, NULL)) {
+return;
+}
+ret =
+vhost_vdpa_dma_map(v, iova, iotlb->addr_mask + 1, vaddr, 
read_only);
+if (ret) {
+error_report("vhost_vdpa_dma_map(%p, 0x%" HWADDR_PRIx ", "
+ "0x%" HWADDR_PRIx ", %p) = %d (%m)",
+ v, iova, iotlb->addr_mask + 1, vaddr, ret);
+}
+} else {
+ret = vhost_vdpa_dma_unmap(v, iova, iotlb->addr_mask + 1);
+if (ret) {
+error_report("vhost_vdpa_dma_unmap(%p, 0x%" HWADDR_PRIx ", "
+ "0x%" HWADDR_PRIx ") = %d (%m)",
+ v, iova, iotlb->addr_mask + 1, ret);
+}
+}
+}
+
+static void vhost_vdpa_iommu_region_add(MemoryListener *listener,
+MemoryRegionSection *section)
+{
+struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
+
+struct vdpa_iommu *iommu;
+Int128 end;
+int iommu_idx;
+IOMMUMemoryRegion *iommu_mr;
+int ret;
+
+iommu_mr = IOMMU_MEMORY_REGION(section->mr);
+
+iommu = g_malloc0(sizeof(*iommu));
+end =  int128_add(int128_make64(section->offset_within_region),
+section->size);
+end = int128_sub(end, int128_one());
+iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr,
+MEMTXATTRS_UNSPECIFIED);
+
+iommu->iommu_mr = iommu_mr;
+
+iommu_notifier_init(
+&iommu->n, vhost_vdpa_iommu_map_notify, IOMMU_NOTIFIER_IOTLB_EVENTS,
+section->offset_within_region, int128_get64(end), iommu_idx);
+iommu->iommu_offset =
+section->offset_within_address_space - section->offset_within_region;
+iommu->dev = v;
+
+ret = memory_region_register_iommu_notifier(section->mr, &iommu->n, NULL);
+if (ret) {
+g_free(iommu);
+return;
+}
+
+QLIST_INSERT_HEAD(&v->iommu_list, iommu, iommu_next);
+memory_region_iommu_replay(iommu->iommu_mr, &iommu->n);
+
+return;
+}
+
+static void vhost_vdpa_iommu_region_del(MemoryListener *listener,
+MemoryRegionSection *section)
+{
+struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
+
+struct vdpa_iommu *iommu;
+
+QLIST_FOREACH(iommu, &v->iommu_list, iommu_next)
+{
+if (MEMORY_REGION(iommu->iommu_mr) == section->mr &&
+iommu->n.start == section->offset_within_region) {
+memory_re

[PATCH v9 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Cindy Lu
- Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
  change the name to memory_get_xlat_addr(). So we can use this
  function on other devices, such as vDPA device.
- Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
  whether the memory is backed by a discard manager. then device can
  have its own warning.

Signed-off-by: Cindy Lu 
---
 hw/vfio/common.c  | 66 +++
 include/exec/memory.h |  4 +++
 softmmu/memory.c  | 72 +++
 3 files changed, 81 insertions(+), 61 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index ace9562a9b..6bc02b32c8 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -578,45 +578,11 @@ static bool 
vfio_listener_skipped_section(MemoryRegionSection *section)
 static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
ram_addr_t *ram_addr, bool *read_only)
 {
-MemoryRegion *mr;
-hwaddr xlat;
-hwaddr len = iotlb->addr_mask + 1;
-bool writable = iotlb->perm & IOMMU_WO;
-
-/*
- * The IOMMU TLB entry we have just covers translation through
- * this IOMMU to its immediate target.  We need to translate
- * it the rest of the way through to memory.
- */
-mr = address_space_translate(&address_space_memory,
- iotlb->translated_addr,
- &xlat, &len, writable,
- MEMTXATTRS_UNSPECIFIED);
-if (!memory_region_is_ram(mr)) {
-error_report("iommu map to non memory area %"HWADDR_PRIx"",
- xlat);
-return false;
-} else if (memory_region_has_ram_discard_manager(mr)) {
-RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
-MemoryRegionSection tmp = {
-.mr = mr,
-.offset_within_region = xlat,
-.size = int128_make64(len),
-};
-
-/*
- * Malicious VMs can map memory into the IOMMU, which is expected
- * to remain discarded. vfio will pin all pages, populating memory.
- * Disallow that. vmstate priorities make sure any RamDiscardManager
- * were already restored before IOMMUs are restored.
- */
-if (!ram_discard_manager_is_populated(rdm, &tmp)) {
-error_report("iommu map to discarded memory (e.g., unplugged via"
- " virtio-mem): %"HWADDR_PRIx"",
- iotlb->translated_addr);
-return false;
-}
+bool ret, mr_has_discard_manager;
 
+ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
+   &mr_has_discard_manager);
+if (ret && mr_has_discard_manager) {
 /*
  * Malicious VMs might trigger discarding of IOMMU-mapped memory. The
  * pages will remain pinned inside vfio until unmapped, resulting in a
@@ -635,29 +601,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void 
**vaddr,
  " intended via an IOMMU. It's possible to mitigate "
  " by setting/adjusting RLIMIT_MEMLOCK.");
 }
-
-/*
- * Translation truncates length to the IOMMU page size,
- * check that it did not truncate too much.
- */
-if (len & iotlb->addr_mask) {
-error_report("iommu has granularity incompatible with target AS");
-return false;
-}
-
-if (vaddr) {
-*vaddr = memory_region_get_ram_ptr(mr) + xlat;
-}
-
-if (ram_addr) {
-*ram_addr = memory_region_get_ram_addr(mr) + xlat;
-}
-
-if (read_only) {
-*read_only = !writable || mr->readonly;
-}
-
-return true;
+return ret;
 }
 
 static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index bfb1de8eea..d1e79c39dc 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -713,6 +713,10 @@ void 
ram_discard_manager_register_listener(RamDiscardManager *rdm,
 void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
  RamDiscardListener *rdl);
 
+bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
+  ram_addr_t *ram_addr, bool *read_only,
+  bool *mr_has_discard_manager);
+
 typedef struct CoalescedMemoryRange CoalescedMemoryRange;
 typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
 
diff --git a/softmmu/memory.c b/softmmu/memory.c
index 7ba2048836..bc0be3f62c 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -33,6 +33,7 @@
 #include "qemu/accel.h"
 #include "hw/boards.h"
 #include "migration/vmstate.h"
+#include "exec/address-spaces.h"
 
 //#define DEBUG_UNASSIGNED
 
@@ -2121,6 +2122,77 @@ void 
ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
 rdmc->unregister_listener(rdm, rdl);
 }
 
+/* Called with 

Re: [PATCH v9 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Alex Williamson
On Mon, 31 Oct 2022 11:10:19 +0800
Cindy Lu  wrote:

> - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
>   change the name to memory_get_xlat_addr(). So we can use this
>   function on other devices, such as vDPA device.
> - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
>   whether the memory is backed by a discard manager. then device can
>   have its own warning.
> 
> Signed-off-by: Cindy Lu 
> ---
>  hw/vfio/common.c  | 66 +++
>  include/exec/memory.h |  4 +++
>  softmmu/memory.c  | 72 +++
>  3 files changed, 81 insertions(+), 61 deletions(-)

Acked-by: Alex Williamson 




Re: [PATCH 4/5] target/riscv: No need to re-start QEMU timer when timecmp == UINT64_MAX

2022-10-30 Thread Anup Patel
On Mon, Oct 31, 2022 at 6:25 AM Alistair Francis  wrote:
>
> On Fri, Oct 28, 2022 at 2:53 AM Anup Patel  wrote:
> >
> > The time CSR will wrap-around immediately after reaching UINT64_MAX
> > so we don't need to re-start QEMU timer when timecmp == UINT64_MAX
> > in riscv_timer_write_timecmp().
>
> I'm not clear what this is fixing?
>
> If the guest sets a timer for UINT64_MAX shouldn't that still trigger
> an event at some point?

Here's what Sstc says about timer interrupt using Sstc:
"A supervisor timer interrupt becomes pending - as reflected in the
STIP bit in the mip and sip registers - whenever time contains a
value greater than or equal to stimecmp, treating the values as
unsigned integers. Writes to stimecmp are guaranteed to be
reflected in STIP eventually, but not necessarily immediately.
The interrupt remains posted until stimecmp becomes greater
than time - typically as a result of writing stimecmp."

When timecmp = UINT64_MAX, the time CSR will eventually reach
timecmp value but on next timer tick the time CSR will wrap-around
and become zero which is less than UINT64_MAX. Now, the timer
interrupt behaves like a level triggered interrupt so it will become 1
when time = timecmp = UINT64_MAX and next timer tick it will
become 0 again because time = 0 < timecmp = UINT64_MAX.

This time CSR wrap-around comparison with timecmp is natural
to implement in HW but not straight forward in QEMU hence this
patch.

Software can potentially use timecmp = UINT64_MAX as a way
to clear the timer interrupt and keep timer disabled instead of
enabling/disabling sie.STIP. This timecmp = UINT64_MAX helps:
1) Linux RISC-V timer driver keep timer interrupt enable/disable
state in-sync with Linux interrupt subsystem.
2) Reduce number of traps taken when emulating Sstc for the
"Nested Guest" (i.e. Guest running under some "Guest Hypervisor"
which in-turn runs under a "Host Hypervisor").

In fact, the SBI set_timer() call also defines similar mechanism to
disable timer: "If the supervisor wishes to clear the timer interrupt
without scheduling the next timer event, it can either request a timer
interrupt infinitely far into the future (i.e., (uint64_t)-1), ...".

Regards,
Anup

>
> Alistair
>
> >
> > Signed-off-by: Anup Patel 
> > ---
> >  target/riscv/time_helper.c | 8 
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
> > index 4fb2a471a9..1ee9f94813 100644
> > --- a/target/riscv/time_helper.c
> > +++ b/target/riscv/time_helper.c
> > @@ -72,6 +72,14 @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer 
> > *timer,
> >  riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
> >  }
> >
> > +/*
> > + * Don't re-start the QEMU timer when timecmp == UINT64_MAX because
> > + * time CSR will wrap-around immediately after reaching UINT64_MAX.
> > + */
> > +if (timecmp == UINT64_MAX) {
> > +return;
> > +}
> > +
> >  /* otherwise, set up the future timer interrupt */
> >  diff = timecmp - rtc_r;
> >  /* back to ns (note args switched in muldiv64) */
> > --
> > 2.34.1
> >
> >



Re: [PATCH v2 3/3] hw/i386/acpi-build: Resolve north rather than south bridges

2022-10-30 Thread Ani Sinha



On Fri, 28 Oct 2022, Bernhard Beschow wrote:

> The code currently assumes Q35 iff ICH9 and i440fx iff PIIX. Now that more
> AML generation has been moved into the south bridges and since the
> machines define themselves primarily through their north bridges, let's
> switch to resolving the north bridges for AML generation instead. This
> also allows for easier experimentation with different south bridges in
> the "pc" machine, e.g. with PIIX4 and VT82xx.
>
> Signed-off-by: Bernhard Beschow 

Reviewed-by: Ani Sinha 

> ---
>  hw/i386/acpi-build.c | 11 ++-
>  1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 73d8a59737..d9eaa5fc4d 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -60,6 +60,7 @@
>  #include "hw/i386/fw_cfg.h"
>  #include "hw/i386/ich9.h"
>  #include "hw/pci/pci_bus.h"
> +#include "hw/pci-host/i440fx.h"
>  #include "hw/pci-host/q35.h"
>  #include "hw/i386/x86-iommu.h"
>
> @@ -1322,8 +1323,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> AcpiPmInfo *pm, AcpiMiscInfo *misc,
> Range *pci_hole, Range *pci_hole64, MachineState *machine)
>  {
> -Object *piix = object_resolve_type_unambiguous(TYPE_PIIX4_PM);
> -Object *lpc = object_resolve_type_unambiguous(TYPE_ICH9_LPC_DEVICE);
> +Object *i440fx = 
> object_resolve_type_unambiguous(TYPE_I440FX_PCI_HOST_BRIDGE);
> +Object *q35 = object_resolve_type_unambiguous(TYPE_Q35_HOST_DEVICE);
>  CrsRangeEntry *entry;
>  Aml *dsdt, *sb_scope, *scope, *dev, *method, *field, *pkg, *crs;
>  CrsRangeSet crs_range_set;
> @@ -1344,13 +1345,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>  AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = x86ms->oem_id,
>  .oem_table_id = x86ms->oem_table_id };
>
> -assert(!!piix != !!lpc);
> +assert(!!i440fx != !!q35);
>
>  acpi_table_begin(&table, table_data);
>  dsdt = init_aml_allocator();
>
>  build_dbg_aml(dsdt);
> -if (piix) {
> +if (i440fx) {
>  sb_scope = aml_scope("_SB");
>  dev = aml_device("PCI0");
>  aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
> @@ -1363,7 +1364,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>  build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
>  }
>  build_piix4_pci0_int(dsdt);
> -} else if (lpc) {
> +} else if (q35) {
>  sb_scope = aml_scope("_SB");
>  dev = aml_device("PCI0");
>  aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
> --
> 2.38.1
>
>



[PATCH] qga: Add initial OpenBSD support

2022-10-30 Thread Brad Smith
qga: Add initial OpenBSD support

Signed-off-by: Brad Smith 
---
 meson.build  | 2 +-
 qga/commands-bsd.c   | 5 +
 qga/commands-posix.c | 9 +++--
 qga/main.c   | 4 ++--
 4 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/meson.build b/meson.build
index 37737913df..fb69a6a683 100644
--- a/meson.build
+++ b/meson.build
@@ -75,7 +75,7 @@ have_tools = get_option('tools') \
   .allowed()
 have_ga = get_option('guest_agent') \
   .disable_auto_if(not have_system and not have_tools) \
-  .require(targetos in ['sunos', 'linux', 'windows', 'freebsd'],
+  .require(targetos in ['sunos', 'linux', 'windows', 'freebsd', 'openbsd'],
error_message: 'unsupported OS for QEMU guest agent') \
   .allowed()
 have_block = have_system or have_tools
diff --git a/qga/commands-bsd.c b/qga/commands-bsd.c
index 15cade2d4c..4deb3bf580 100644
--- a/qga/commands-bsd.c
+++ b/qga/commands-bsd.c
@@ -21,7 +21,12 @@
 #include 
 #include 
 #include 
+#ifdef __OpenBSD__
+#include 
+#include 
+#else
 #include 
+#endif
 #include 
 
 #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM)
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 32493d6383..640f26dc16 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -45,7 +45,12 @@
 #include 
 #include 
 #include 
+#ifdef __OpenBSD__
+#include 
+#include 
+#else
 #include 
+#endif
 #include 
 #ifdef CONFIG_SOLARIS
 #include 
@@ -2881,7 +2886,7 @@ static int guest_get_network_stats(const char *name,
 return -1;
 }
 
-#ifndef __FreeBSD__
+#ifndef CONFIG_BSD
 /*
  * Fill "buf" with MAC address by ifaddrs. Pointer buf must point to a
  * buffer with ETHER_ADDR_LEN length at least.
@@ -2930,7 +2935,7 @@ bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char 
*buf,
 close(sock);
 return true;
 }
-#endif /* __FreeBSD__ */
+#endif /* CONFIG_BSD */
 
 /*
  * Build information about guest interfaces
diff --git a/qga/main.c b/qga/main.c
index b3580508fa..0fe94e80d1 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -40,9 +40,9 @@
 #include "commands-common.h"
 
 #ifndef _WIN32
-#ifdef __FreeBSD__
+#ifdef CONFIG_BSD
 #define QGA_VIRTIO_PATH_DEFAULT "/dev/vtcon/org.qemu.guest_agent.0"
-#else /* __FreeBSD__ */
+#else /* CONFIG_BSD */
 #define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent.0"
 #endif /* __FreeBSD__ */
 #define QGA_SERIAL_PATH_DEFAULT "/dev/ttyS0"
-- 
2.38.0




[PULL 07/11] target/openrisc: Always exit after mtspr npc

2022-10-30 Thread Richard Henderson
We have called cpu_restore_state asserting will_exit.
Do not go back on that promise.  This affects icount.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/openrisc/sys_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index 09b3c97d7c..a3508e421d 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -51,8 +51,8 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, 
target_ulong rb)
 if (env->pc != rb) {
 env->pc = rb;
 env->dflag = 0;
-cpu_loop_exit(cs);
 }
+cpu_loop_exit(cs);
 break;
 
 case TO_SPR(0, 17): /* SR */
-- 
2.34.1




[PULL 04/11] tcg/tci: fix logic error when registering helpers via FFI

2022-10-30 Thread Richard Henderson
From: Icenowy Zheng 

When registering helpers via FFI for TCI, the inner loop that iterates
parameters of the helper reuses (and thus pollutes) the same variable
used by the outer loop that iterates all helpers, thus made some helpers
unregistered.

Fix this logic error by using a dedicated temporary variable for the
inner loop.

Fixes: 22f15579fa ("tcg: Build ffi data structures for helpers")
Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Icenowy Zheng 
Message-Id: <20221028072145.1593205-1-...@icenowy.me>
[rth: Move declaration of j to the for loop itself]
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index c9e664ee31..b6c46b7e25 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -634,9 +634,9 @@ static void tcg_context_init(unsigned max_cpus)
 
 if (nargs != 0) {
 ca->cif.arg_types = ca->args;
-for (i = 0; i < nargs; ++i) {
-int typecode = extract32(typemask, (i + 1) * 3, 3);
-ca->args[i] = typecode_to_ffi[typecode];
+for (int j = 0; j < nargs; ++j) {
+int typecode = extract32(typemask, (j + 1) * 3, 3);
+ca->args[j] = typecode_to_ffi[typecode];
 }
 }
 
-- 
2.34.1




[PULL 08/11] target/openrisc: Use cpu_unwind_state_data for mfspr

2022-10-30 Thread Richard Henderson
Since we do not plan to exit, use cpu_unwind_state_data
and extract exactly the data requested.

This is a bug fix, in that we no longer clobber dflag.

Consider:

l.j   L2 // branch
l.mfspr   r1, ppc// delay

L1: boom
L2: l.lwa r3, (r4)

Here, dflag would be set by cpu_restore_state (because that is the current
state of the cpu), but but not cleared by tb_stop on exiting the TB
(because DisasContext has recorded the current value as zero).

The next TB begins at L2 with dflag incorrectly set.  If the load has a
tlb miss, then the exception will be delivered as per a delay slot:
with DSX set in the status register and PC decremented (delay slots
restart by re-executing the branch). This will cause the return from
interrupt to go to L1, and boom!

Signed-off-by: Richard Henderson 
---
 target/openrisc/sys_helper.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index a3508e421d..dde2fa1623 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -199,6 +199,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, 
target_ulong rd,
target_ulong spr)
 {
 #ifndef CONFIG_USER_ONLY
+uint64_t data[TARGET_INSN_START_WORDS];
 MachineState *ms = MACHINE(qdev_get_machine());
 OpenRISCCPU *cpu = env_archcpu(env);
 CPUState *cs = env_cpu(env);
@@ -232,14 +233,20 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, 
target_ulong rd,
 return env->evbar;
 
 case TO_SPR(0, 16): /* NPC (equals PC) */
-cpu_restore_state(cs, GETPC(), false);
+if (cpu_unwind_state_data(cs, GETPC(), data)) {
+return data[0];
+}
 return env->pc;
 
 case TO_SPR(0, 17): /* SR */
 return cpu_get_sr(env);
 
 case TO_SPR(0, 18): /* PPC */
-cpu_restore_state(cs, GETPC(), false);
+if (cpu_unwind_state_data(cs, GETPC(), data)) {
+if (data[1] & 2) {
+return data[0] - 4;
+}
+}
 return env->ppc;
 
 case TO_SPR(0, 32): /* EPCR */
-- 
2.34.1




[PATCH] accel/tcg: Complete cpu initialization before registration

2022-10-30 Thread Richard Henderson
Delay cpu_list_add until realize is complete, so that cross-cpu
interaction does not happen with incomplete cpu state.  For this,
we must delay plugin initialization out of tcg_exec_realizefn,
because no cpu_index has been assigned.

Fixes a problem with cross-cpu jump cache flushing, when the
jump cache has not yet been allocated.

Fixes: a976a99a2975 ("include/hw/core: Create struct CPUJumpCache")
Reported-by: Ilya Leoshkevich 
Signed-off-by: Richard Henderson 
---
 accel/tcg/cpu-exec.c  |  8 +---
 accel/tcg/translate-all.c | 16 +++-
 cpu.c | 10 +-
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 82b06c1824..356fe348de 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -1052,23 +1052,25 @@ void tcg_exec_realizefn(CPUState *cpu, Error **errp)
 cc->tcg_ops->initialize();
 tcg_target_initialized = true;
 }
-tlb_init(cpu);
-qemu_plugin_vcpu_init_hook(cpu);
 
+cpu->tb_jmp_cache = g_new0(CPUJumpCache, 1);
+tlb_init(cpu);
 #ifndef CONFIG_USER_ONLY
 tcg_iommu_init_notifier_list(cpu);
 #endif /* !CONFIG_USER_ONLY */
+/* qemu_plugin_vcpu_init_hook delayed until cpu_index assigned. */
 }
 
 /* undo the initializations in reverse order */
 void tcg_exec_unrealizefn(CPUState *cpu)
 {
+qemu_plugin_vcpu_exit_hook(cpu);
 #ifndef CONFIG_USER_ONLY
 tcg_iommu_free_notifier_list(cpu);
 #endif /* !CONFIG_USER_ONLY */
 
-qemu_plugin_vcpu_exit_hook(cpu);
 tlb_destroy(cpu);
+g_free(cpu->tb_jmp_cache);
 }
 
 #ifndef CONFIG_USER_ONLY
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 0089578f8f..921944a5ab 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1580,15 +1580,13 @@ void tcg_flush_jmp_cache(CPUState *cpu)
 {
 CPUJumpCache *jc = cpu->tb_jmp_cache;
 
-if (likely(jc)) {
-for (int i = 0; i < TB_JMP_CACHE_SIZE; i++) {
-qatomic_set(&jc->array[i].tb, NULL);
-}
-} else {
-/* This should happen once during realize, and thus never race. */
-jc = g_new0(CPUJumpCache, 1);
-jc = qatomic_xchg(&cpu->tb_jmp_cache, jc);
-assert(jc == NULL);
+/* During early initialization, the cache may not yet be allocated. */
+if (unlikely(jc == NULL)) {
+return;
+}
+
+for (int i = 0; i < TB_JMP_CACHE_SIZE; i++) {
+qatomic_set(&jc->array[i].tb, NULL);
 }
 }
 
diff --git a/cpu.c b/cpu.c
index 2a09b05205..4a7d865427 100644
--- a/cpu.c
+++ b/cpu.c
@@ -134,15 +134,23 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
 /* cache the cpu class for the hotpath */
 cpu->cc = CPU_GET_CLASS(cpu);
 
-cpu_list_add(cpu);
 if (!accel_cpu_realizefn(cpu, errp)) {
 return;
 }
+
 /* NB: errp parameter is unused currently */
 if (tcg_enabled()) {
 tcg_exec_realizefn(cpu, errp);
 }
 
+/* Wait until cpu initialization complete before exposing cpu. */
+cpu_list_add(cpu);
+
+/* Plugin initialization must wait until cpu_index assigned. */
+if (tcg_enabled()) {
+qemu_plugin_vcpu_init_hook(cpu);
+}
+
 #ifdef CONFIG_USER_ONLY
 assert(qdev_get_vmsd(DEVICE(cpu)) == NULL ||
qdev_get_vmsd(DEVICE(cpu))->unmigratable);
-- 
2.34.1




[PULL 00/11] tcg patch queue

2022-10-30 Thread Richard Henderson
The following changes since commit 75d30fde55485b965a1168a21d016dd07b50ed32:

  Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into 
staging (2022-10-30 15:07:25 -0400)

are available in the Git repository at:

  https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20221031

for you to fetch changes up to cb375590983fc3d23600d02ba05a05d34fe44150:

  target/i386: Expand eflags updates inline (2022-10-31 11:39:10 +1100)


Remove sparc32plus support from tcg/sparc.
target/i386: Use cpu_unwind_state_data for tpr access.
target/i386: Expand eflags updates inline


Icenowy Zheng (1):
  tcg/tci: fix logic error when registering helpers via FFI

Richard Henderson (10):
  tcg/sparc: Remove support for sparc32plus
  tcg/sparc64: Rename from tcg/sparc
  tcg/sparc64: Remove sparc32plus constraints
  accel/tcg: Introduce cpu_unwind_state_data
  target/i386: Use cpu_unwind_state_data for tpr access
  target/openrisc: Always exit after mtspr npc
  target/openrisc: Use cpu_unwind_state_data for mfspr
  accel/tcg: Remove will_exit argument from cpu_restore_state
  accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb
  target/i386: Expand eflags updates inline

 meson.build |   4 +-
 accel/tcg/internal.h|   4 +-
 include/exec/exec-all.h |  24 ++-
 target/i386/helper.h|   5 -
 tcg/{sparc => sparc64}/tcg-target-con-set.h |  16 +-
 tcg/{sparc => sparc64}/tcg-target-con-str.h |   3 -
 tcg/{sparc => sparc64}/tcg-target.h |  11 --
 accel/tcg/cpu-exec-common.c |   2 +-
 accel/tcg/tb-maint.c|   4 +-
 accel/tcg/translate-all.c   |  91 +
 target/alpha/helper.c   |   2 +-
 target/alpha/mem_helper.c   |   2 +-
 target/arm/op_helper.c  |   2 +-
 target/arm/tlb_helper.c |   8 +-
 target/cris/helper.c|   2 +-
 target/i386/helper.c|  21 ++-
 target/i386/tcg/cc_helper.c |  41 -
 target/i386/tcg/sysemu/svm_helper.c |   2 +-
 target/i386/tcg/translate.c |  30 ++-
 target/m68k/op_helper.c |   4 +-
 target/microblaze/helper.c  |   2 +-
 target/nios2/op_helper.c|   2 +-
 target/openrisc/sys_helper.c|  17 +-
 target/ppc/excp_helper.c|   2 +-
 target/s390x/tcg/excp_helper.c  |   2 +-
 target/tricore/op_helper.c  |   2 +-
 target/xtensa/helper.c  |   6 +-
 tcg/tcg.c   |  81 +---
 tcg/{sparc => sparc64}/tcg-target.c.inc | 275 
 MAINTAINERS |   2 +-
 30 files changed, 232 insertions(+), 437 deletions(-)
 rename tcg/{sparc => sparc64}/tcg-target-con-set.h (69%)
 rename tcg/{sparc => sparc64}/tcg-target-con-str.h (77%)
 rename tcg/{sparc => sparc64}/tcg-target.h (95%)
 rename tcg/{sparc => sparc64}/tcg-target.c.inc (91%)



[PULL 02/11] tcg/sparc64: Rename from tcg/sparc

2022-10-30 Thread Richard Henderson
Emphasize that we only support full 64-bit code generation.

Reviewed-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 meson.build | 4 +---
 tcg/{sparc => sparc64}/tcg-target-con-set.h | 0
 tcg/{sparc => sparc64}/tcg-target-con-str.h | 0
 tcg/{sparc => sparc64}/tcg-target.h | 0
 tcg/{sparc => sparc64}/tcg-target.c.inc | 0
 MAINTAINERS | 2 +-
 6 files changed, 2 insertions(+), 4 deletions(-)
 rename tcg/{sparc => sparc64}/tcg-target-con-set.h (100%)
 rename tcg/{sparc => sparc64}/tcg-target-con-str.h (100%)
 rename tcg/{sparc => sparc64}/tcg-target.h (100%)
 rename tcg/{sparc => sparc64}/tcg-target.c.inc (100%)

diff --git a/meson.build b/meson.build
index 37737913df..e9853ad21a 100644
--- a/meson.build
+++ b/meson.build
@@ -49,7 +49,7 @@ qapi_trace_events = []
 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 
'darwin']
 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 
'sunos', 'linux']
 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
-  'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
+  'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
 
 cpu = host_machine.cpu_family()
 
@@ -469,8 +469,6 @@ if get_option('tcg').allowed()
   endif
   if get_option('tcg_interpreter')
 tcg_arch = 'tci'
-  elif host_arch == 'sparc64'
-tcg_arch = 'sparc'
   elif host_arch == 'x86_64'
 tcg_arch = 'i386'
   elif host_arch == 'ppc64'
diff --git a/tcg/sparc/tcg-target-con-set.h b/tcg/sparc64/tcg-target-con-set.h
similarity index 100%
rename from tcg/sparc/tcg-target-con-set.h
rename to tcg/sparc64/tcg-target-con-set.h
diff --git a/tcg/sparc/tcg-target-con-str.h b/tcg/sparc64/tcg-target-con-str.h
similarity index 100%
rename from tcg/sparc/tcg-target-con-str.h
rename to tcg/sparc64/tcg-target-con-str.h
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc64/tcg-target.h
similarity index 100%
rename from tcg/sparc/tcg-target.h
rename to tcg/sparc64/tcg-target.h
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
similarity index 100%
rename from tcg/sparc/tcg-target.c.inc
rename to tcg/sparc64/tcg-target.c.inc
diff --git a/MAINTAINERS b/MAINTAINERS
index 64893e36bc..1ab6962b0a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3379,7 +3379,7 @@ L: qemu-s3...@nongnu.org
 
 SPARC TCG target
 S: Odd Fixes
-F: tcg/sparc/
+F: tcg/sparc64/
 F: disas/sparc.c
 
 TCI TCG target
-- 
2.34.1




[PULL 11/11] target/i386: Expand eflags updates inline

2022-10-30 Thread Richard Henderson
The helpers for reset_rf, cli, sti, clac, stac are
completely trivial; implement them inline.

Drop some nearby #if 0 code.

Reviewed-by: Paolo Bonzini 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/i386/helper.h|  5 -
 target/i386/tcg/cc_helper.c | 41 -
 target/i386/tcg/translate.c | 30 ++-
 3 files changed, 25 insertions(+), 51 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 88143b2a24..b7de5429ef 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -56,13 +56,8 @@ DEF_HELPER_2(syscall, void, env, int)
 DEF_HELPER_2(sysret, void, env, int)
 #endif
 DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
-DEF_HELPER_1(reset_rf, void, env)
 DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int)
 DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int)
-DEF_HELPER_1(cli, void, env)
-DEF_HELPER_1(sti, void, env)
-DEF_HELPER_1(clac, void, env)
-DEF_HELPER_1(stac, void, env)
 DEF_HELPER_3(boundw, void, env, tl, int)
 DEF_HELPER_3(boundl, void, env, tl, int)
 
diff --git a/target/i386/tcg/cc_helper.c b/target/i386/tcg/cc_helper.c
index cc7ea9e8b9..6227dbb30b 100644
--- a/target/i386/tcg/cc_helper.c
+++ b/target/i386/tcg/cc_helper.c
@@ -346,44 +346,3 @@ void helper_clts(CPUX86State *env)
 env->cr[0] &= ~CR0_TS_MASK;
 env->hflags &= ~HF_TS_MASK;
 }
-
-void helper_reset_rf(CPUX86State *env)
-{
-env->eflags &= ~RF_MASK;
-}
-
-void helper_cli(CPUX86State *env)
-{
-env->eflags &= ~IF_MASK;
-}
-
-void helper_sti(CPUX86State *env)
-{
-env->eflags |= IF_MASK;
-}
-
-void helper_clac(CPUX86State *env)
-{
-env->eflags &= ~AC_MASK;
-}
-
-void helper_stac(CPUX86State *env)
-{
-env->eflags |= AC_MASK;
-}
-
-#if 0
-/* vm86plus instructions */
-void helper_cli_vm(CPUX86State *env)
-{
-env->eflags &= ~VIF_MASK;
-}
-
-void helper_sti_vm(CPUX86State *env)
-{
-env->eflags |= VIF_MASK;
-if (env->eflags & VIP_MASK) {
-raise_exception_ra(env, EXCP0D_GPF, GETPC());
-}
-}
-#endif
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 546c427c23..0ee548ce56 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2746,6 +2746,26 @@ static void gen_reset_hflag(DisasContext *s, uint32_t 
mask)
 }
 }
 
+static void gen_set_eflags(DisasContext *s, target_ulong mask)
+{
+TCGv t = tcg_temp_new();
+
+tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags));
+tcg_gen_ori_tl(t, t, mask);
+tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags));
+tcg_temp_free(t);
+}
+
+static void gen_reset_eflags(DisasContext *s, target_ulong mask)
+{
+TCGv t = tcg_temp_new();
+
+tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags));
+tcg_gen_andi_tl(t, t, ~mask);
+tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags));
+tcg_temp_free(t);
+}
+
 /* Clear BND registers during legacy branches.  */
 static void gen_bnd_jmp(DisasContext *s)
 {
@@ -2776,7 +2796,7 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool 
recheck_tf, bool jr)
 }
 
 if (s->base.tb->flags & HF_RF_MASK) {
-gen_helper_reset_rf(cpu_env);
+gen_reset_eflags(s, RF_MASK);
 }
 if (recheck_tf) {
 gen_helper_rechecking_single_step(cpu_env);
@@ -5502,12 +5522,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
 #endif
 case 0xfa: /* cli */
 if (check_iopl(s)) {
-gen_helper_cli(cpu_env);
+gen_reset_eflags(s, IF_MASK);
 }
 break;
 case 0xfb: /* sti */
 if (check_iopl(s)) {
-gen_helper_sti(cpu_env);
+gen_set_eflags(s, IF_MASK);
 /* interruptions are enabled only the first insn after sti */
 gen_update_eip_next(s);
 gen_eob_inhibit_irq(s, true);
@@ -5789,7 +5809,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
 || CPL(s) != 0) {
 goto illegal_op;
 }
-gen_helper_clac(cpu_env);
+gen_reset_eflags(s, AC_MASK);
 s->base.is_jmp = DISAS_EOB_NEXT;
 break;
 
@@ -5798,7 +5818,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
 || CPL(s) != 0) {
 goto illegal_op;
 }
-gen_helper_stac(cpu_env);
+gen_set_eflags(s, AC_MASK);
 s->base.is_jmp = DISAS_EOB_NEXT;
 break;
 
-- 
2.34.1




[PULL 06/11] target/i386: Use cpu_unwind_state_data for tpr access

2022-10-30 Thread Richard Henderson
Avoid cpu_restore_state, and modifying env->eip out from
underneath the translator with TARGET_TB_PCREL.  There is
some slight duplication from x86_restore_state_to_opc,
but it's just a few lines.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1269
Reviewed-by: Claudio Fontana 
Signed-off-by: Richard Henderson 
---
 target/i386/helper.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/target/i386/helper.c b/target/i386/helper.c
index b62a1e48e2..2cd1756f1a 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -509,6 +509,23 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int 
bank,
 }
 }
 
+static target_ulong get_memio_eip(CPUX86State *env)
+{
+uint64_t data[TARGET_INSN_START_WORDS];
+CPUState *cs = env_cpu(env);
+
+if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) {
+return env->eip;
+}
+
+/* Per x86_restore_state_to_opc. */
+if (TARGET_TB_PCREL) {
+return (env->eip & TARGET_PAGE_MASK) | data[0];
+} else {
+return data[0] - env->segs[R_CS].base;
+}
+}
+
 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
 {
 X86CPU *cpu = env_archcpu(env);
@@ -519,9 +536,9 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess 
access)
 
 cpu_interrupt(cs, CPU_INTERRUPT_TPR);
 } else if (tcg_enabled()) {
-cpu_restore_state(cs, cs->mem_io_pc, false);
+target_ulong eip = get_memio_eip(env);
 
-apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
+apic_handle_tpr_access_report(cpu->apic_state, eip, access);
 }
 }
 #endif /* !CONFIG_USER_ONLY */
-- 
2.34.1




[PULL 09/11] accel/tcg: Remove will_exit argument from cpu_restore_state

2022-10-30 Thread Richard Henderson
The value passed is always true, and if the target's
synchronize_from_tb hook is non-trivial, not exiting
may be erroneous.

Reviewed-by: Claudio Fontana 
Signed-off-by: Richard Henderson 
---
 include/exec/exec-all.h |  5 +
 accel/tcg/cpu-exec-common.c |  2 +-
 accel/tcg/translate-all.c   | 12 ++--
 target/alpha/helper.c   |  2 +-
 target/alpha/mem_helper.c   |  2 +-
 target/arm/op_helper.c  |  2 +-
 target/arm/tlb_helper.c |  8 
 target/cris/helper.c|  2 +-
 target/i386/tcg/sysemu/svm_helper.c |  2 +-
 target/m68k/op_helper.c |  4 ++--
 target/microblaze/helper.c  |  2 +-
 target/nios2/op_helper.c|  2 +-
 target/openrisc/sys_helper.c|  4 ++--
 target/ppc/excp_helper.c|  2 +-
 target/s390x/tcg/excp_helper.c  |  2 +-
 target/tricore/op_helper.c  |  2 +-
 target/xtensa/helper.c  |  6 +++---
 17 files changed, 25 insertions(+), 36 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 7d851f5907..9b7bfbf09a 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -56,16 +56,13 @@ bool cpu_unwind_state_data(CPUState *cpu, uintptr_t 
host_pc, uint64_t *data);
  * cpu_restore_state:
  * @cpu: the cpu context
  * @host_pc: the host pc within the translation
- * @will_exit: true if the TB executed will be interrupted after some
-   cpu adjustments. Required for maintaining the correct
-   icount valus
  * @return: true if state was restored, false otherwise
  *
  * Attempt to restore the state for a fault occurring in translated
  * code. If @host_pc is not in translated code no state is
  * restored and the function returns false.
  */
-bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit);
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc);
 
 G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu);
 G_NORETURN void cpu_loop_exit(CPUState *cpu);
diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c
index be6fe45aa5..c7bc8c6efa 100644
--- a/accel/tcg/cpu-exec-common.c
+++ b/accel/tcg/cpu-exec-common.c
@@ -71,7 +71,7 @@ void cpu_loop_exit(CPUState *cpu)
 void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc)
 {
 if (pc) {
-cpu_restore_state(cpu, pc, true);
+cpu_restore_state(cpu, pc);
 }
 cpu_loop_exit(cpu);
 }
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 319becb698..90997fed47 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -318,16 +318,8 @@ void cpu_restore_state_from_tb(CPUState *cpu, 
TranslationBlock *tb,
 #endif
 }
 
-bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
 {
-/*
- * The pc update associated with restore without exit will
- * break the relative pc adjustments performed by TARGET_TB_PCREL.
- */
-if (TARGET_TB_PCREL) {
-assert(will_exit);
-}
-
 /*
  * The host_pc has to be in the rx region of the code buffer.
  * If it is not we will not be able to resolve it here.
@@ -341,7 +333,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, 
bool will_exit)
 if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) {
 TranslationBlock *tb = tcg_tb_lookup(host_pc);
 if (tb) {
-cpu_restore_state_from_tb(cpu, tb, host_pc, will_exit);
+cpu_restore_state_from_tb(cpu, tb, host_pc, true);
 return true;
 }
 }
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index a5a389b5a3..970c869771 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -532,7 +532,7 @@ G_NORETURN void dynamic_excp(CPUAlphaState *env, uintptr_t 
retaddr,
 cs->exception_index = excp;
 env->error_code = error;
 if (retaddr) {
-cpu_restore_state(cs, retaddr, true);
+cpu_restore_state(cs, retaddr);
 /* Floating-point exceptions (our only users) point to the next PC.  */
 env->pc += 4;
 }
diff --git a/target/alpha/mem_helper.c b/target/alpha/mem_helper.c
index 47283a0612..a39b52c5dd 100644
--- a/target/alpha/mem_helper.c
+++ b/target/alpha/mem_helper.c
@@ -28,7 +28,7 @@ static void do_unaligned_access(CPUAlphaState *env, vaddr 
addr, uintptr_t retadd
 uint64_t pc;
 uint32_t insn;
 
-cpu_restore_state(env_cpu(env), retaddr, true);
+cpu_restore_state(env_cpu(env), retaddr);
 
 pc = env->pc;
 insn = cpu_ldl_code(env, pc);
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index c5bde1cfcc..70672bcd9f 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -78,7 +78,7 @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, 
uint32_t syndrome,
  * we must restore CPU state here before setting the syndrome
  * the caller passed us, and cannot use cpu_loop_exit_

[PULL 05/11] accel/tcg: Introduce cpu_unwind_state_data

2022-10-30 Thread Richard Henderson
Add a way to examine the unwind data without actually
restoring the data back into env.

Reviewed-by: Claudio Fontana 
Signed-off-by: Richard Henderson 
---
 accel/tcg/internal.h  |  4 +--
 include/exec/exec-all.h   | 21 ---
 accel/tcg/translate-all.c | 74 ++-
 3 files changed, 68 insertions(+), 31 deletions(-)

diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
index 1227bb69bd..9c06b320b7 100644
--- a/accel/tcg/internal.h
+++ b/accel/tcg/internal.h
@@ -106,8 +106,8 @@ void tb_reset_jump(TranslationBlock *tb, int n);
 TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
tb_page_addr_t phys_page2);
 bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
-int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
-  uintptr_t searched_pc, bool reset_icount);
+void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
+   uintptr_t host_pc, bool reset_icount);
 
 /* Return the current PC from CPU, which may be cached in TB. */
 static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index e948992a80..7d851f5907 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -39,20 +39,33 @@ typedef ram_addr_t tb_page_addr_t;
 #define TB_PAGE_ADDR_FMT RAM_ADDR_FMT
 #endif
 
+/**
+ * cpu_unwind_state_data:
+ * @cpu: the cpu context
+ * @host_pc: the host pc within the translation
+ * @data: output data
+ *
+ * Attempt to load the the unwind state for a host pc occurring in
+ * translated code.  If @host_pc is not in translated code, the
+ * function returns false; otherwise @data is loaded.
+ * This is the same unwind info as given to restore_state_to_opc.
+ */
+bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data);
+
 /**
  * cpu_restore_state:
- * @cpu: the vCPU state is to be restore to
- * @searched_pc: the host PC the fault occurred at
+ * @cpu: the cpu context
+ * @host_pc: the host pc within the translation
  * @will_exit: true if the TB executed will be interrupted after some
cpu adjustments. Required for maintaining the correct
icount valus
  * @return: true if state was restored, false otherwise
  *
  * Attempt to restore the state for a fault occurring in translated
- * code. If the searched_pc is not in translated code no state is
+ * code. If @host_pc is not in translated code no state is
  * restored and the function returns false.
  */
-bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc, bool will_exit);
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit);
 
 G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu);
 G_NORETURN void cpu_loop_exit(CPUState *cpu);
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index f185356a36..319becb698 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -247,52 +247,66 @@ static int encode_search(TranslationBlock *tb, uint8_t 
*block)
 return p - block;
 }
 
-/* The cpu state corresponding to 'searched_pc' is restored.
- * When reset_icount is true, current TB will be interrupted and
- * icount should be recalculated.
- */
-int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
-  uintptr_t searched_pc, bool reset_icount)
+static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc,
+   uint64_t *data)
 {
-uint64_t data[TARGET_INSN_START_WORDS];
-uintptr_t host_pc = (uintptr_t)tb->tc.ptr;
+uintptr_t iter_pc = (uintptr_t)tb->tc.ptr;
 const uint8_t *p = tb->tc.ptr + tb->tc.size;
 int i, j, num_insns = tb->icount;
-#ifdef CONFIG_PROFILER
-TCGProfile *prof = &tcg_ctx->prof;
-int64_t ti = profile_getclock();
-#endif
 
-searched_pc -= GETPC_ADJ;
+host_pc -= GETPC_ADJ;
 
-if (searched_pc < host_pc) {
+if (host_pc < iter_pc) {
 return -1;
 }
 
-memset(data, 0, sizeof(data));
+memset(data, 0, sizeof(uint64_t) * TARGET_INSN_START_WORDS);
 if (!TARGET_TB_PCREL) {
 data[0] = tb_pc(tb);
 }
 
-/* Reconstruct the stored insn data while looking for the point at
-   which the end of the insn exceeds the searched_pc.  */
+/*
+ * Reconstruct the stored insn data while looking for the point
+ * at which the end of the insn exceeds host_pc.
+ */
 for (i = 0; i < num_insns; ++i) {
 for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
 data[j] += decode_sleb128(&p);
 }
-host_pc += decode_sleb128(&p);
-if (host_pc > searched_pc) {
-goto found;
+iter_pc += decode_sleb128(&p);
+if (iter_pc > host_pc) {
+return num_insns - i;
 }
 }
 return -1;
+}
+
+/*
+ * The cpu state corresponding to 'host_pc

[PULL 03/11] tcg/sparc64: Remove sparc32plus constraints

2022-10-30 Thread Richard Henderson
With sparc64 we need not distinguish between registers that
can hold 32-bit values and those that can hold 64-bit values.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 tcg/sparc64/tcg-target-con-set.h |  16 +
 tcg/sparc64/tcg-target-con-str.h |   3 -
 tcg/sparc64/tcg-target.c.inc | 109 ---
 3 files changed, 44 insertions(+), 84 deletions(-)

diff --git a/tcg/sparc64/tcg-target-con-set.h b/tcg/sparc64/tcg-target-con-set.h
index 3b751dc3fb..31e6fea1fc 100644
--- a/tcg/sparc64/tcg-target-con-set.h
+++ b/tcg/sparc64/tcg-target-con-set.h
@@ -11,22 +11,12 @@
  */
 C_O0_I1(r)
 C_O0_I2(rZ, r)
-C_O0_I2(RZ, r)
 C_O0_I2(rZ, rJ)
-C_O0_I2(RZ, RJ)
-C_O0_I2(sZ, A)
-C_O0_I2(SZ, A)
-C_O1_I1(r, A)
-C_O1_I1(R, A)
+C_O0_I2(sZ, s)
+C_O1_I1(r, s)
 C_O1_I1(r, r)
-C_O1_I1(r, R)
-C_O1_I1(R, r)
-C_O1_I1(R, R)
-C_O1_I2(R, R, R)
+C_O1_I2(r, r, r)
 C_O1_I2(r, rZ, rJ)
-C_O1_I2(R, RZ, RJ)
 C_O1_I4(r, rZ, rJ, rI, 0)
-C_O1_I4(R, RZ, RJ, RI, 0)
 C_O2_I2(r, r, rZ, rJ)
-C_O2_I4(R, R, RZ, RZ, RJ, RI)
 C_O2_I4(r, r, rZ, rZ, rJ, rJ)
diff --git a/tcg/sparc64/tcg-target-con-str.h b/tcg/sparc64/tcg-target-con-str.h
index fdb25d9313..8f5c7aef97 100644
--- a/tcg/sparc64/tcg-target-con-str.h
+++ b/tcg/sparc64/tcg-target-con-str.h
@@ -9,10 +9,7 @@
  * REGS(letter, register_mask)
  */
 REGS('r', ALL_GENERAL_REGS)
-REGS('R', ALL_GENERAL_REGS64)
 REGS('s', ALL_QLDST_REGS)
-REGS('S', ALL_QLDST_REGS64)
-REGS('A', TARGET_LONG_BITS == 64 ? ALL_QLDST_REGS64 : ALL_QLDST_REGS)
 
 /*
  * Define constraint letters for constants:
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index 097bcfcd12..cb9453efdd 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -80,19 +80,8 @@ static const char * const 
tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
 #else
 #define SOFTMMU_RESERVE_REGS 0
 #endif
-
-/*
- * Note that sparcv8plus can only hold 64 bit quantities in %g and %o
- * registers.  These are saved manually by the kernel in full 64-bit
- * slots.  The %i and %l registers are saved by the register window
- * mechanism, which only allocates space for 32 bits.  Given that this
- * window spill/fill can happen on any signal, we must consider the
- * high bits of the %i and %l registers garbage at all times.
- */
 #define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
-# define ALL_GENERAL_REGS64  ALL_GENERAL_REGS
 #define ALL_QLDST_REGS   (ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
-#define ALL_QLDST_REGS64 (ALL_GENERAL_REGS64 & ~SOFTMMU_RESERVE_REGS)
 
 /* Define some temporary registers.  T2 is used for constant generation.  */
 #define TCG_REG_T1  TCG_REG_G1
@@ -1738,107 +1727,91 @@ static TCGConstraintSetIndex 
tcg_target_op_def(TCGOpcode op)
 return C_O0_I1(r);
 
 case INDEX_op_ld8u_i32:
+case INDEX_op_ld8u_i64:
 case INDEX_op_ld8s_i32:
+case INDEX_op_ld8s_i64:
 case INDEX_op_ld16u_i32:
+case INDEX_op_ld16u_i64:
 case INDEX_op_ld16s_i32:
+case INDEX_op_ld16s_i64:
 case INDEX_op_ld_i32:
+case INDEX_op_ld32u_i64:
+case INDEX_op_ld32s_i64:
+case INDEX_op_ld_i64:
 case INDEX_op_neg_i32:
+case INDEX_op_neg_i64:
 case INDEX_op_not_i32:
+case INDEX_op_not_i64:
+case INDEX_op_ext32s_i64:
+case INDEX_op_ext32u_i64:
+case INDEX_op_ext_i32_i64:
+case INDEX_op_extu_i32_i64:
+case INDEX_op_extrl_i64_i32:
+case INDEX_op_extrh_i64_i32:
 return C_O1_I1(r, r);
 
 case INDEX_op_st8_i32:
+case INDEX_op_st8_i64:
 case INDEX_op_st16_i32:
+case INDEX_op_st16_i64:
 case INDEX_op_st_i32:
+case INDEX_op_st32_i64:
+case INDEX_op_st_i64:
 return C_O0_I2(rZ, r);
 
 case INDEX_op_add_i32:
+case INDEX_op_add_i64:
 case INDEX_op_mul_i32:
+case INDEX_op_mul_i64:
 case INDEX_op_div_i32:
+case INDEX_op_div_i64:
 case INDEX_op_divu_i32:
+case INDEX_op_divu_i64:
 case INDEX_op_sub_i32:
+case INDEX_op_sub_i64:
 case INDEX_op_and_i32:
+case INDEX_op_and_i64:
 case INDEX_op_andc_i32:
+case INDEX_op_andc_i64:
 case INDEX_op_or_i32:
+case INDEX_op_or_i64:
 case INDEX_op_orc_i32:
+case INDEX_op_orc_i64:
 case INDEX_op_xor_i32:
+case INDEX_op_xor_i64:
 case INDEX_op_shl_i32:
+case INDEX_op_shl_i64:
 case INDEX_op_shr_i32:
+case INDEX_op_shr_i64:
 case INDEX_op_sar_i32:
+case INDEX_op_sar_i64:
 case INDEX_op_setcond_i32:
+case INDEX_op_setcond_i64:
 return C_O1_I2(r, rZ, rJ);
 
 case INDEX_op_brcond_i32:
+case INDEX_op_brcond_i64:
 return C_O0_I2(rZ, rJ);
 case INDEX_op_movcond_i32:
+case INDEX_op_movcond_i64:
 return C_O1_I4(r, rZ, rJ, rI, 0);
 case INDEX_op_add2_i32:
+case INDEX_op_add2_i64:
 case INDEX_op_sub2_i32:
+case INDEX_op_sub2_i64:
 return C_O2_I4(r, r, rZ, rZ, rJ, rJ);
 case INDEX_op_mulu2_i32:
 case INDEX_op_muls2_i32:
 return C_O2_I2(r, r, rZ, rJ);
-
-c

[PATCH] target/arm: Copy the entire vector in DO_ZIP

2022-10-30 Thread Richard Henderson
With odd_ofs set, we weren't copying enough data.

Fixes: 09eb6d7025d1 ("target/arm: Move sve zip high_ofs into simd_data")
Reported-by: Idan Horowitz 
Signed-off-by: Richard Henderson 
---
 target/arm/sve_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 3d0d2987cd..1afeadf9c8 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -3366,10 +3366,10 @@ void HELPER(NAME)(void *vd, void *vn, void *vm, 
uint32_t desc)   \
 /* We produce output faster than we consume input.   \
Therefore we must be mindful of possible overlap.  */ \
 if (unlikely((vn - vd) < (uintptr_t)oprsz)) {\
-vn = memcpy(&tmp_n, vn, oprsz_2);\
+vn = memcpy(&tmp_n, vn, oprsz);  \
 }\
 if (unlikely((vm - vd) < (uintptr_t)oprsz)) {\
-vm = memcpy(&tmp_m, vm, oprsz_2);\
+vm = memcpy(&tmp_m, vm, oprsz);  \
 }\
 for (i = 0; i < oprsz_2; i += sizeof(TYPE)) {\
 *(TYPE *)(vd + H(2 * i + 0)) = *(TYPE *)(vn + odd_ofs + H(i)); \
-- 
2.34.1




[PULL 01/11] tcg/sparc: Remove support for sparc32plus

2022-10-30 Thread Richard Henderson
Since 9b9c37c36439, we have only supported sparc64 cpus.
Debian and Gentoo now only support 64-bit sparc64 userland,
so it is time to drop the 32-bit sparc64 userland: sparc32plus.

Reviewed-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/sparc/tcg-target.h |  11 ---
 tcg/tcg.c  |  75 +
 tcg/sparc/tcg-target.c.inc | 166 +++--
 3 files changed, 33 insertions(+), 219 deletions(-)

diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index c050763049..8655acdbe5 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -25,8 +25,6 @@
 #ifndef SPARC_TCG_TARGET_H
 #define SPARC_TCG_TARGET_H
 
-#define TCG_TARGET_REG_BITS 64
-
 #define TCG_TARGET_INSN_UNIT_SIZE 4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
 #define TCG_TARGET_NB_REGS 32
@@ -70,19 +68,10 @@ typedef enum {
 /* used for function call generation */
 #define TCG_REG_CALL_STACK TCG_REG_O6
 
-#ifdef __arch64__
 #define TCG_TARGET_STACK_BIAS   2047
 #define TCG_TARGET_STACK_ALIGN  16
 #define TCG_TARGET_CALL_STACK_OFFSET(128 + 6*8 + TCG_TARGET_STACK_BIAS)
-#else
-#define TCG_TARGET_STACK_BIAS   0
-#define TCG_TARGET_STACK_ALIGN  8
-#define TCG_TARGET_CALL_STACK_OFFSET(64 + 4 + 6*4)
-#endif
-
-#ifdef __arch64__
 #define TCG_TARGET_EXTEND_ARGS 1
-#endif
 
 #if defined(__VIS__) && __VIS__ >= 0x300
 #define use_vis3_instructions  1
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 612a12f58f..c9e664ee31 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1487,39 +1487,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 }
 #endif
 
-#if defined(__sparc__) && !defined(__arch64__) \
-&& !defined(CONFIG_TCG_INTERPRETER)
-/* We have 64-bit values in one register, but need to pass as two
-   separate parameters.  Split them.  */
-int orig_typemask = typemask;
-int orig_nargs = nargs;
-TCGv_i64 retl, reth;
-TCGTemp *split_args[MAX_OPC_PARAM];
-
-retl = NULL;
-reth = NULL;
-typemask = 0;
-for (i = real_args = 0; i < nargs; ++i) {
-int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
-bool is_64bit = (argtype & ~1) == dh_typecode_i64;
-
-if (is_64bit) {
-TCGv_i64 orig = temp_tcgv_i64(args[i]);
-TCGv_i32 h = tcg_temp_new_i32();
-TCGv_i32 l = tcg_temp_new_i32();
-tcg_gen_extr_i64_i32(l, h, orig);
-split_args[real_args++] = tcgv_i32_temp(h);
-typemask |= dh_typecode_i32 << (real_args * 3);
-split_args[real_args++] = tcgv_i32_temp(l);
-typemask |= dh_typecode_i32 << (real_args * 3);
-} else {
-split_args[real_args++] = args[i];
-typemask |= argtype << (real_args * 3);
-}
-}
-nargs = real_args;
-args = split_args;
-#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
+#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
 for (i = 0; i < nargs; ++i) {
 int argtype = extract32(typemask, (i + 1) * 3, 3);
 bool is_32bit = (argtype & ~1) == dh_typecode_i32;
@@ -1542,22 +1510,6 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 
 pi = 0;
 if (ret != NULL) {
-#if defined(__sparc__) && !defined(__arch64__) \
-&& !defined(CONFIG_TCG_INTERPRETER)
-if ((typemask & 6) == dh_typecode_i64) {
-/* The 32-bit ABI is going to return the 64-bit value in
-   the %o0/%o1 register pair.  Prepare for this by using
-   two return temporaries, and reassemble below.  */
-retl = tcg_temp_new_i64();
-reth = tcg_temp_new_i64();
-op->args[pi++] = tcgv_i64_arg(reth);
-op->args[pi++] = tcgv_i64_arg(retl);
-nb_rets = 2;
-} else {
-op->args[pi++] = temp_arg(ret);
-nb_rets = 1;
-}
-#else
 if (TCG_TARGET_REG_BITS < 64 && (typemask & 6) == dh_typecode_i64) {
 #if HOST_BIG_ENDIAN
 op->args[pi++] = temp_arg(ret + 1);
@@ -1571,7 +1523,6 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 op->args[pi++] = temp_arg(ret);
 nb_rets = 1;
 }
-#endif
 } else {
 nb_rets = 0;
 }
@@ -1634,29 +1585,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 tcg_debug_assert(TCGOP_CALLI(op) == real_args);
 tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
 
-#if defined(__sparc__) && !defined(__arch64__) \
-&& !defined(CONFIG_TCG_INTERPRETER)
-/* Free all of the parts we allocated above.  */
-for (i = real_args = 0; i < orig_nargs; ++i) {
-int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
-bool is_64bit = (argtype & ~1) == dh_typecode_i64;
-
-if (is_64bit) {
-tcg_temp_free_internal(args[real_args++]);
-tcg_temp_free_i

[PULL 10/11] accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb

2022-10-30 Thread Richard Henderson
The value passed is always true.

Reviewed-by: Claudio Fontana 
Signed-off-by: Richard Henderson 
---
 accel/tcg/internal.h  |  2 +-
 accel/tcg/tb-maint.c  |  4 ++--
 accel/tcg/translate-all.c | 15 +++
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
index 9c06b320b7..cb13bade4f 100644
--- a/accel/tcg/internal.h
+++ b/accel/tcg/internal.h
@@ -107,7 +107,7 @@ TranslationBlock *tb_link_page(TranslationBlock *tb, 
tb_page_addr_t phys_pc,
tb_page_addr_t phys_page2);
 bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
 void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
-   uintptr_t host_pc, bool reset_icount);
+   uintptr_t host_pc);
 
 /* Return the current PC from CPU, which may be cached in TB. */
 static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index c8e921089d..0cdb35548c 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c
@@ -536,7 +536,7 @@ tb_invalidate_phys_page_range__locked(struct 
page_collection *pages,
  * restore the CPU state.
  */
 current_tb_modified = true;
-cpu_restore_state_from_tb(cpu, current_tb, retaddr, true);
+cpu_restore_state_from_tb(cpu, current_tb, retaddr);
 }
 #endif /* TARGET_HAS_PRECISE_SMC */
 tb_phys_invalidate__locked(tb);
@@ -685,7 +685,7 @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, 
uintptr_t pc)
  * function to partially restore the CPU state.
  */
 current_tb_modified = true;
-cpu_restore_state_from_tb(cpu, current_tb, pc, true);
+cpu_restore_state_from_tb(cpu, current_tb, pc);
 }
 #endif /* TARGET_HAS_PRECISE_SMC */
 tb_phys_invalidate(tb, addr);
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 90997fed47..0089578f8f 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -282,12 +282,11 @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, 
uintptr_t host_pc,
 }
 
 /*
- * The cpu state corresponding to 'host_pc' is restored.
- * When reset_icount is true, current TB will be interrupted and
- * icount should be recalculated.
+ * The cpu state corresponding to 'host_pc' is restored in
+ * preparation for exiting the TB.
  */
 void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
-   uintptr_t host_pc, bool reset_icount)
+   uintptr_t host_pc)
 {
 uint64_t data[TARGET_INSN_START_WORDS];
 #ifdef CONFIG_PROFILER
@@ -300,7 +299,7 @@ void cpu_restore_state_from_tb(CPUState *cpu, 
TranslationBlock *tb,
 return;
 }
 
-if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) {
+if (tb_cflags(tb) & CF_USE_ICOUNT) {
 assert(icount_enabled());
 /*
  * Reset the cycle counter to the start of the block and
@@ -333,7 +332,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
 if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) {
 TranslationBlock *tb = tcg_tb_lookup(host_pc);
 if (tb) {
-cpu_restore_state_from_tb(cpu, tb, host_pc, true);
+cpu_restore_state_from_tb(cpu, tb, host_pc);
 return true;
 }
 }
@@ -1032,7 +1031,7 @@ void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr)
 tb = tcg_tb_lookup(retaddr);
 if (tb) {
 /* We can use retranslation to find the PC.  */
-cpu_restore_state_from_tb(cpu, tb, retaddr, true);
+cpu_restore_state_from_tb(cpu, tb, retaddr);
 tb_phys_invalidate(tb, -1);
 } else {
 /* The exception probably happened in a helper.  The CPU state should
@@ -1068,7 +1067,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
 cpu_abort(cpu, "cpu_io_recompile: could not find TB for pc=%p",
   (void *)retaddr);
 }
-cpu_restore_state_from_tb(cpu, tb, retaddr, true);
+cpu_restore_state_from_tb(cpu, tb, retaddr);
 
 /*
  * Some guests must re-execute the branch when re-executing a delay
-- 
2.34.1




Re: [PULL 25/47] accel/tcg: Add restore_state_to_opc to TCGCPUOps

2022-10-30 Thread Richard Henderson

On 10/29/22 21:42, Alex Bennée wrote:


Richard Henderson  writes:


Add a tcg_ops hook to replace the restore_state_to_opc
function call.  Because these generic hooks cannot depend
on target-specific types, temporarily, copy the current
target_ulong data[] into uint64_t d64[].

Reviewed-by: Claudio Fontana 
Signed-off-by: Richard Henderson 


This has triggered a regression in x86_64 stuff:


Patches posted: 20221027100254.215253-1-richard.hender...@linaro.org
("[PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269)")


r~



Re: [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269)

2022-10-30 Thread Richard Henderson

On 10/27/22 21:02, Richard Henderson wrote:

As per #1269, this affects NetBSD installer boot.

The problem is that one of the x86 acpi callbacks modifies
env->eip during an mmio store, which means that the tracking
that translate.c does is thrown out of whack.

Introduce a method to extract unwind data without the
writeback to env.  This isn't a perfect abstraction, but I
couldn't think of anything better.  There's a couple of lines
of code duplication, but probably less than any abstration
that we might put on top

Changes for v2:
   * Rebase on master, 23 patches merged.
   * Comments adjusted per review (claudio)


r~


Queuing to tcg-next.


r~



Re: [PATCH] target/i386: Expand eflags updates inline

2022-10-30 Thread Richard Henderson

On 10/27/22 21:26, Richard Henderson wrote:

The helpers for reset_rf, cli, sti, clac, stac are
completely trivial; implement them inline.

Drop some nearby #if 0 code.

Signed-off-by: Richard Henderson 
---
  target/i386/helper.h|  5 -
  target/i386/tcg/cc_helper.c | 41 -
  target/i386/tcg/translate.c | 30 ++-
  3 files changed, 25 insertions(+), 51 deletions(-)


Queuing to tcg-next, for convenience.


r~



Re: [PATCH v7 6/7] acpi/tests/avocado/bits/doc: add a doc file to describe the acpi bits test

2022-10-30 Thread Ani Sinha
On Fri, Oct 21, 2022 at 3:32 PM Ani Sinha  wrote:
>
> A doc file is added under docs/devel that describes the purpose of the various
> test files and gives guidance to developers on where and how to make changes.
>
> Cc: Daniel P. Berrange" 
> Cc: Paolo Bonzini 
> Cc: Maydell Peter 
> Cc: John Snow 
> Cc: Thomas Huth 
> Cc: Alex Bennée 
> Cc: Igor Mammedov 
> Cc: Michael Tsirkin 
> Signed-off-by: Ani Sinha 

Michael, you forgot to apply this patch to your tree. You have applied
the rest.

> ---
>  docs/devel/acpi-bits.rst   | 145 +
>  docs/devel/index-build.rst |   1 +
>  2 files changed, 146 insertions(+)
>  create mode 100644 docs/devel/acpi-bits.rst
>
> diff --git a/docs/devel/acpi-bits.rst b/docs/devel/acpi-bits.rst
> new file mode 100644
> index 00..c9564d871a
> --- /dev/null
> +++ b/docs/devel/acpi-bits.rst
> @@ -0,0 +1,145 @@
> +=
> +ACPI/SMBIOS avocado tests using biosbits
> +=
> +
> +Biosbits is a software written by Josh Triplett that can be downloaded
> +from https://biosbits.org/. The github codebase can be found
> +`here `__. It is a software 
> that executes
> +the bios components such as acpi and smbios tables directly through acpica
> +bios interpreter (a freely available C based library written by Intel,
> +downloadable from https://acpica.org/ and is included with biosbits) without 
> an
> +operating system getting involved in between.
> +There are several advantages to directly testing the bios in a real physical
> +machine or VM as opposed to indirectly discovering bios issues through the
> +operating system. For one thing, the OSes tend to hide bios problems from the
> +end user. The other is that we have more control of what we wanted to test
> +and how by directly using acpica interpreter on top of the bios on a running
> +system. More details on the inspiration for developing biosbits and its real
> +life uses can be found in [#a]_ and [#b]_.
> +This directory contains tests written in python using avocado framework that
> +exercises the QEMU bios components using biosbits and reports test failures.
> +For QEMU, we maintain a fork of bios bits in gitlab along with all the
> +dependent submodules:
> +https://gitlab.com/qemu-project/biosbits-bits
> +This fork contains numerous fixes, a newer acpica and changes specific to
> +running this avocado QEMU tests using bits. The author of this document
> +is the sole maintainer of the QEMU fork of bios bits repo.
> +
> +Under the directory ``tests/avocado/``, ``acpi-bits.py`` is a QEMU avocado
> +test that drives all this.
> +
> +A brief description of the various test files follows.
> +
> +Under ``tests/avocado/`` as the root we have:
> +
> +::
> +
> +   ├── acpi-bits
> +   │ ├── bits-config
> +   │ │ └── bits-cfg.txt
> +   │ ├── bits-tests
> +   │ │ ├── smbios.py2
> +   │ │ ├── testacpi.py2
> +   │ │ └── testcpuid.py2
> +   │ └── README
> +   ├── acpi-bits.py
> +
> +* ``tests/avocado``:
> +
> +   ``acpi-bits.py``:
> +   This is the main python avocado test script that generates a
> +   biosbits iso. It then spawns a QEMU VM with it, collects the log and 
> reports
> +   test failures. This is the script one would be interested in if they 
> wanted
> +   to add or change some component of the log parsing, add a new command line
> +   to alter how QEMU is spawned etc. Test writers typically would not need to
> +   modify this script unless they wanted to enhance or change the log parsing
> +   for their tests. In order to enable debugging, you can set **V=1**
> +   environment variable. This enables verbose mode for the test and also 
> dumps
> +   the entire log from bios bits and more information in case failure 
> happens.
> +
> +   In order to run this test, please perform the following steps from the 
> QEMU
> +   build directory:
> +   ::
> +
> + $ make check-venv (needed only the first time to create the venv)
> + $ ./tests/venv/bin/avocado run -t acpi tests/avocado
> +
> +   The above will run all acpi avocado tests including this one.
> +   In order to run the individual tests, perform the following:
> +   ::
> +
> + $ ./tests/venv/bin/avocado run tests/avocado/acpi-bits.py --tap -
> +
> +   The above will produce output in tap format. You can omit "--tap -" in the
> +   end and it will produce output like the following:
> +   ::
> +
> +  $ ./tests/venv/bin/avocado run tests/avocado/acpi-bits.py
> +  Fetching asset from 
> tests/avocado/acpi-bits.py:AcpiBitsTest.test_acpi_smbios_bits
> +  JOB ID : eab225724da7b64c012c65705dc2fa14ab1defef
> +  JOB LOG: 
> /home/anisinha/avocado/job-results/job-2022-10-10T17.58-eab2257/job.log
> +  (1/1) tests/avocado/acpi-bits.py:AcpiBitsTest.test_acpi_smbios_bits: 
> PASS (33.09 s)
> +  RESULTS: PASS 1 | ERROR 0 | 

Re: [PATCH v9 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Michael S. Tsirkin
On Mon, Oct 31, 2022 at 11:10:19AM +0800, Cindy Lu wrote:
> - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
>   change the name to memory_get_xlat_addr(). So we can use this
>   function on other devices, such as vDPA device.
> - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
>   whether the memory is backed by a discard manager. then device can
>   have its own warning.
> 
> Signed-off-by: Cindy Lu 

Could you rebase on top of my tree (config interrupt support conflicts).

> ---
>  hw/vfio/common.c  | 66 +++
>  include/exec/memory.h |  4 +++
>  softmmu/memory.c  | 72 +++
>  3 files changed, 81 insertions(+), 61 deletions(-)
> 
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index ace9562a9b..6bc02b32c8 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -578,45 +578,11 @@ static bool 
> vfio_listener_skipped_section(MemoryRegionSection *section)
>  static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> ram_addr_t *ram_addr, bool *read_only)
>  {
> -MemoryRegion *mr;
> -hwaddr xlat;
> -hwaddr len = iotlb->addr_mask + 1;
> -bool writable = iotlb->perm & IOMMU_WO;
> -
> -/*
> - * The IOMMU TLB entry we have just covers translation through
> - * this IOMMU to its immediate target.  We need to translate
> - * it the rest of the way through to memory.
> - */
> -mr = address_space_translate(&address_space_memory,
> - iotlb->translated_addr,
> - &xlat, &len, writable,
> - MEMTXATTRS_UNSPECIFIED);
> -if (!memory_region_is_ram(mr)) {
> -error_report("iommu map to non memory area %"HWADDR_PRIx"",
> - xlat);
> -return false;
> -} else if (memory_region_has_ram_discard_manager(mr)) {
> -RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
> -MemoryRegionSection tmp = {
> -.mr = mr,
> -.offset_within_region = xlat,
> -.size = int128_make64(len),
> -};
> -
> -/*
> - * Malicious VMs can map memory into the IOMMU, which is expected
> - * to remain discarded. vfio will pin all pages, populating memory.
> - * Disallow that. vmstate priorities make sure any RamDiscardManager
> - * were already restored before IOMMUs are restored.
> - */
> -if (!ram_discard_manager_is_populated(rdm, &tmp)) {
> -error_report("iommu map to discarded memory (e.g., unplugged via"
> - " virtio-mem): %"HWADDR_PRIx"",
> - iotlb->translated_addr);
> -return false;
> -}
> +bool ret, mr_has_discard_manager;
>  
> +ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
> +   &mr_has_discard_manager);
> +if (ret && mr_has_discard_manager) {
>  /*
>   * Malicious VMs might trigger discarding of IOMMU-mapped memory. The
>   * pages will remain pinned inside vfio until unmapped, resulting in 
> a
> @@ -635,29 +601,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, 
> void **vaddr,
>   " intended via an IOMMU. It's possible to mitigate "
>   " by setting/adjusting RLIMIT_MEMLOCK.");
>  }
> -
> -/*
> - * Translation truncates length to the IOMMU page size,
> - * check that it did not truncate too much.
> - */
> -if (len & iotlb->addr_mask) {
> -error_report("iommu has granularity incompatible with target AS");
> -return false;
> -}
> -
> -if (vaddr) {
> -*vaddr = memory_region_get_ram_ptr(mr) + xlat;
> -}
> -
> -if (ram_addr) {
> -*ram_addr = memory_region_get_ram_addr(mr) + xlat;
> -}
> -
> -if (read_only) {
> -*read_only = !writable || mr->readonly;
> -}
> -
> -return true;
> +return ret;
>  }
>  
>  static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index bfb1de8eea..d1e79c39dc 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -713,6 +713,10 @@ void 
> ram_discard_manager_register_listener(RamDiscardManager *rdm,
>  void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
>   RamDiscardListener *rdl);
>  
> +bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> +  ram_addr_t *ram_addr, bool *read_only,
> +  bool *mr_has_discard_manager);
> +
>  typedef struct CoalescedMemoryRange CoalescedMemoryRange;
>  typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
>  
> diff --git a/softmmu/memory.c b/softmmu/memory.c
> index 7ba2048836..bc0be3f62c 

Re: [PATCH V5 4/4] intel-iommu: PASID support

2022-10-30 Thread Michael S. Tsirkin
On Fri, Oct 28, 2022 at 09:49:36PM +0800, Yi Liu wrote:
> On 2022/10/28 14:14, Jason Wang wrote:
> > This patch introduce ECAP_PASID via "x-pasid-mode". Based on the
> > existing support for scalable mode, we need to implement the following
> > missing parts:
> > 
> > 1) tag VTDAddressSpace with PASID and support IOMMU/DMA translation
> > with PASID
> > 2) tag IOTLB with PASID
> > 3) PASID cache and its flush
> > 4) PASID based IOTLB invalidation
> > 
> > For simplicity PASID cache is not implemented so we can simply
> > implement the PASID cache flush as a no and leave it to be implemented
> > in the future. For PASID based IOTLB invalidation, since we haven't
> > had L1 stage support, the PASID based IOTLB invalidation is not
> > implemented yet. For PASID based device IOTLB invalidation, it
> > requires the support for vhost so we forbid enabling device IOTLB when
> > PASID is enabled now. Those work could be done in the future.
> > 
> > Note that though PASID based IOMMU translation is ready but no device
> > can issue PASID DMA right now. In this case, PCI_NO_PASID is used as
> > PASID to identify the address without PASID. vtd_find_add_as() has
> > been extended to provision address space with PASID which could be
> > utilized by the future extension of PCI core to allow device model to
> > use PASID based DMA translation.
> 
> a quick comment. For PCI_NO_PASID. perhaps you can use PASID#0. As below
> code, if RPS bit is 0, then PASID#0 is used as rid2pasid, and rid2pasid
> is supposed to be used for translating requests without PASID. So I guess
> you can use pasid#0 for requests without PASID if RPS bit 0. This is high
> chance, currently no need to report RPS bit as 1.
> 
> static int vtd_dev_get_rid2pasid(IntelIOMMUState *s, uint8_t bus_num,
>  uint8_t devfn, uint32_t *rid_pasid)
> {
> VTDContextEntry ce;
> int ret;
> /*
>  * Currently, ECAP.RPS bit is likely to be reported as "Clear".
>  * And per VT-d 3.1 spec, it will use PASID #0 as RID2PASID when
>  * RPS bit is reported as "Clear".
>  */
> if (likely(!(s->ecap & VTD_ECAP_RPS))) {
> *rid_pasid = 0;
> return 0;
> }
> /*
>  * In future, to improve performance, could try to fetch context
>  * entry from cache firstly.
>  */
> ret = vtd_dev_to_context_entry(s, bus_num, devfn, &ce);
> if (!ret) {
> *rid_pasid = VTD_CE_GET_RID2PASID(&ce);
> }
> return ret;
> }


Jason are you going to be addressing this? Need to send a pull req.

> > 
> > This feature would be useful for:
> > 
> > 1) prototyping PASID support for devices like virtio
> > 2) future vPASID work
> > 3) future PRS and vSVA work
> > 
> > Reviewed-by: Peter Xu 
> > Signed-off-by: Jason Wang 
> > ---
> > Changes since V3:
> > - rearrange the member for vtd_iotlb_key structure
> > - reorder the pasid parameter ahead of addr for vtd_lookup_iotlb()
> > - allow access size from 1 to 8 for vtd_mem_ir_fault_ops
> > Changes since V2:
> > - forbid device-iotlb with PASID
> > - report PASID based qualified fault
> > - log PASID during errors
> > ---
> >   hw/i386/intel_iommu.c  | 416 +
> >   hw/i386/intel_iommu_internal.h |  16 +-
> >   hw/i386/trace-events   |   2 +
> >   include/hw/i386/intel_iommu.h  |   7 +-
> >   include/hw/pci/pci_bus.h   |   2 +
> >   5 files changed, 339 insertions(+), 104 deletions(-)
> > 
> > diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> > index 9029ee98f4..7ca077b824 100644
> > --- a/hw/i386/intel_iommu.c
> > +++ b/hw/i386/intel_iommu.c
> > @@ -58,6 +58,14 @@
> >   struct vtd_as_key {
> >   PCIBus *bus;
> >   uint8_t devfn;
> > +uint32_t pasid;
> > +};
> > +
> > +struct vtd_iotlb_key {
> > +uint64_t gfn;
> > +uint32_t pasid;
> > +uint32_t level;
> > +uint16_t sid;
> >   };
> >   static void vtd_address_space_refresh_all(IntelIOMMUState *s);
> > @@ -199,14 +207,24 @@ static inline gboolean 
> > vtd_as_has_map_notifier(VTDAddressSpace *as)
> >   }
> >   /* GHashTable functions */
> > -static gboolean vtd_uint64_equal(gconstpointer v1, gconstpointer v2)
> > +static gboolean vtd_iotlb_equal(gconstpointer v1, gconstpointer v2)
> >   {
> > -return *((const uint64_t *)v1) == *((const uint64_t *)v2);
> > +const struct vtd_iotlb_key *key1 = v1;
> > +const struct vtd_iotlb_key *key2 = v2;
> > +
> > +return key1->sid == key2->sid &&
> > +   key1->pasid == key2->pasid &&
> > +   key1->level == key2->level &&
> > +   key1->gfn == key2->gfn;
> >   }
> > -static guint vtd_uint64_hash(gconstpointer v)
> > +static guint vtd_iotlb_hash(gconstpointer v)
> >   {
> > -return (guint)*(const uint64_t *)v;
> > +const struct vtd_iotlb_key *key = v;
> > +
> > +return key->gfn | ((key->sid) << VTD_IOTLB_SID_SHIFT) |
> > +   (key->level) << VTD_IOTLB_LVL_SHIFT |
> > +   (key->pasid) << VTD_IOTLB_PASID_SHIFT;
> >

Re: [PATCH 6/7] .gitlab-ci.d/windows.yml: Unify the prerequisite packages

2022-10-30 Thread Thomas Huth

On 29/10/2022 15.06, Bin Meng wrote:

Hi Thomas,

On Sat, Sep 24, 2022 at 5:20 PM Bin Meng  wrote:


Hi Thomas,

On Sat, Sep 10, 2022 at 8:32 AM Bin Meng  wrote:


On Sat, Sep 10, 2022 at 12:32 AM Thomas Huth  wrote:


On 08/09/2022 15.28, Bin Meng wrote:

From: Bin Meng 

At present the prerequisite packages for 64-bit and 32-bit builds
are slightly different. Let's use the same packages for both.


Not sure whether that's a good idea ... I did that on purpose to save some
few time during compilation (since the Windows jobs are running very long
already) ... did you check whether it makes a difference in the run time now?



Not much difference on the build time. Actually I found after we
switched to single thread build the time did not increase too.

One side note regarding the gitlab shared runner:

It seems the shared runner Windows VM is quite slow. Is it possible to
get a faster VM externally?


Any further comment for this patch?



Ping?


As long as the Windows CI runners are still that slow, I'm still not 
convinced that it is a good idea to add more stuff here. Maybe to the 32-bit 
build, since it runs a bit faster, but I think we really should avoid to 
extend the 64-bit build.


 Thomas




Re: [PATCH v9 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Cindy Lu
On Mon, 31 Oct 2022 at 14:38, Michael S. Tsirkin  wrote:
>
> On Mon, Oct 31, 2022 at 11:10:19AM +0800, Cindy Lu wrote:
> > - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
> >   change the name to memory_get_xlat_addr(). So we can use this
> >   function on other devices, such as vDPA device.
> > - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
> >   whether the memory is backed by a discard manager. then device can
> >   have its own warning.
> >
> > Signed-off-by: Cindy Lu 
>
> Could you rebase on top of my tree (config interrupt support conflicts).
>
Hi Micheal,
sure, will do, but I found a crash in config interrupt while testing
vhost user,
should I post a new version for it? Or maybe a patch later?
Thanks
Cindy
> > ---
> >  hw/vfio/common.c  | 66 +++
> >  include/exec/memory.h |  4 +++
> >  softmmu/memory.c  | 72 +++
> >  3 files changed, 81 insertions(+), 61 deletions(-)
> >
> > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > index ace9562a9b..6bc02b32c8 100644
> > --- a/hw/vfio/common.c
> > +++ b/hw/vfio/common.c
> > @@ -578,45 +578,11 @@ static bool 
> > vfio_listener_skipped_section(MemoryRegionSection *section)
> >  static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> > ram_addr_t *ram_addr, bool *read_only)
> >  {
> > -MemoryRegion *mr;
> > -hwaddr xlat;
> > -hwaddr len = iotlb->addr_mask + 1;
> > -bool writable = iotlb->perm & IOMMU_WO;
> > -
> > -/*
> > - * The IOMMU TLB entry we have just covers translation through
> > - * this IOMMU to its immediate target.  We need to translate
> > - * it the rest of the way through to memory.
> > - */
> > -mr = address_space_translate(&address_space_memory,
> > - iotlb->translated_addr,
> > - &xlat, &len, writable,
> > - MEMTXATTRS_UNSPECIFIED);
> > -if (!memory_region_is_ram(mr)) {
> > -error_report("iommu map to non memory area %"HWADDR_PRIx"",
> > - xlat);
> > -return false;
> > -} else if (memory_region_has_ram_discard_manager(mr)) {
> > -RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
> > -MemoryRegionSection tmp = {
> > -.mr = mr,
> > -.offset_within_region = xlat,
> > -.size = int128_make64(len),
> > -};
> > -
> > -/*
> > - * Malicious VMs can map memory into the IOMMU, which is expected
> > - * to remain discarded. vfio will pin all pages, populating memory.
> > - * Disallow that. vmstate priorities make sure any 
> > RamDiscardManager
> > - * were already restored before IOMMUs are restored.
> > - */
> > -if (!ram_discard_manager_is_populated(rdm, &tmp)) {
> > -error_report("iommu map to discarded memory (e.g., unplugged 
> > via"
> > - " virtio-mem): %"HWADDR_PRIx"",
> > - iotlb->translated_addr);
> > -return false;
> > -}
> > +bool ret, mr_has_discard_manager;
> >
> > +ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
> > +   &mr_has_discard_manager);
> > +if (ret && mr_has_discard_manager) {
> >  /*
> >   * Malicious VMs might trigger discarding of IOMMU-mapped memory. 
> > The
> >   * pages will remain pinned inside vfio until unmapped, resulting 
> > in a
> > @@ -635,29 +601,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, 
> > void **vaddr,
> >   " intended via an IOMMU. It's possible to 
> > mitigate "
> >   " by setting/adjusting RLIMIT_MEMLOCK.");
> >  }
> > -
> > -/*
> > - * Translation truncates length to the IOMMU page size,
> > - * check that it did not truncate too much.
> > - */
> > -if (len & iotlb->addr_mask) {
> > -error_report("iommu has granularity incompatible with target AS");
> > -return false;
> > -}
> > -
> > -if (vaddr) {
> > -*vaddr = memory_region_get_ram_ptr(mr) + xlat;
> > -}
> > -
> > -if (ram_addr) {
> > -*ram_addr = memory_region_get_ram_addr(mr) + xlat;
> > -}
> > -
> > -if (read_only) {
> > -*read_only = !writable || mr->readonly;
> > -}
> > -
> > -return true;
> > +return ret;
> >  }
> >
> >  static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> > diff --git a/include/exec/memory.h b/include/exec/memory.h
> > index bfb1de8eea..d1e79c39dc 100644
> > --- a/include/exec/memory.h
> > +++ b/include/exec/memory.h
> > @@ -713,6 +713,10 @@ void 
> > ram_discard_manager_register_listener(RamDiscardManager *rdm,
> >  void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
> >   

Re: [PATCH 0/7] nsis: gitlab-ci: Improve QEMU Windows installer packaging

2022-10-30 Thread Thomas Huth

On 29/10/2022 15.45, Bin Meng wrote:

Hi Thomas,

On Wed, Sep 21, 2022 at 8:24 PM Thomas Huth  wrote:


On 21/09/2022 14.18, Bin Meng wrote:

Hi,

On Thu, Sep 8, 2022 at 9:28 PM Bin Meng  wrote:


At present packaging the required DLLs of QEMU executables is a
manual process, and error prone.

Improve scripts/nsis.py by adding a logic to automatically package
required DLLs of QEMU executables.

'make installer' is tested in the cross-build on Linux in CI, but
not in the Windows native build. Update CI to test the installer
generation on Windows too.

During testing a 32-bit build issue was exposed in block/nfs.c and
the fix is included in this series.


Bin Meng (7):
scripts/nsis.py: Drop the unnecessary path separator
scripts/nsis.py: Fix destination directory name when invoked on
  Windows
scripts/nsis.py: Automatically package required DLLs of QEMU
  executables
.gitlab-ci.d/windows.yml: Drop the sed processing in the 64-bit build
block/nfs: Fix 32-bit Windows build
.gitlab-ci.d/windows.yml: Unify the prerequisite packages
.gitlab-ci.d/windows.yml: Test 'make installer' in the CI

   meson.build  |  1 +
   block/nfs.c  |  8 ++
   .gitlab-ci.d/windows.yml | 40 ---
   scripts/nsis.py  | 60 +---
   4 files changed, 89 insertions(+), 20 deletions(-)



I see Thomas only queued patch #4 (".gitlab-ci.d/windows.yml: Drop the
sed processing in the 64-bit build")

What about other patches?


I hope that Stefan Weil (our W32 maintainer) could have a look at these first...



Stefan has reviewed / tested patch 1-3. Not sure who is going to queue
these 3 patches?


If Stefan has time for a pull request, I think he would be the best fit. Stefan?

Otherwise, maybe Marc-André could take those patches, since he apparently 
wrote that nsis.py script?


(By the way, should we have an entry for that script in MAINTAINERS? ... 
likely in the W32/W64 section?)


 Thomas




Re: [PATCH v9 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Michael S. Tsirkin
On Mon, Oct 31, 2022 at 02:44:11PM +0800, Cindy Lu wrote:
> On Mon, 31 Oct 2022 at 14:38, Michael S. Tsirkin  wrote:
> >
> > On Mon, Oct 31, 2022 at 11:10:19AM +0800, Cindy Lu wrote:
> > > - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
> > >   change the name to memory_get_xlat_addr(). So we can use this
> > >   function on other devices, such as vDPA device.
> > > - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will 
> > > check
> > >   whether the memory is backed by a discard manager. then device can
> > >   have its own warning.
> > >
> > > Signed-off-by: Cindy Lu 
> >
> > Could you rebase on top of my tree (config interrupt support conflicts).
> >
> Hi Micheal,
> sure, will do, but I found a crash in config interrupt while testing
> vhost user,
> should I post a new version for it? Or maybe a patch later?
> Thanks
> Cindy

New version, I will drop this one. So do you want this one picked up and
config interrupt on top?

> > > ---
> > >  hw/vfio/common.c  | 66 +++
> > >  include/exec/memory.h |  4 +++
> > >  softmmu/memory.c  | 72 +++
> > >  3 files changed, 81 insertions(+), 61 deletions(-)
> > >
> > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > > index ace9562a9b..6bc02b32c8 100644
> > > --- a/hw/vfio/common.c
> > > +++ b/hw/vfio/common.c
> > > @@ -578,45 +578,11 @@ static bool 
> > > vfio_listener_skipped_section(MemoryRegionSection *section)
> > >  static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> > > ram_addr_t *ram_addr, bool *read_only)
> > >  {
> > > -MemoryRegion *mr;
> > > -hwaddr xlat;
> > > -hwaddr len = iotlb->addr_mask + 1;
> > > -bool writable = iotlb->perm & IOMMU_WO;
> > > -
> > > -/*
> > > - * The IOMMU TLB entry we have just covers translation through
> > > - * this IOMMU to its immediate target.  We need to translate
> > > - * it the rest of the way through to memory.
> > > - */
> > > -mr = address_space_translate(&address_space_memory,
> > > - iotlb->translated_addr,
> > > - &xlat, &len, writable,
> > > - MEMTXATTRS_UNSPECIFIED);
> > > -if (!memory_region_is_ram(mr)) {
> > > -error_report("iommu map to non memory area %"HWADDR_PRIx"",
> > > - xlat);
> > > -return false;
> > > -} else if (memory_region_has_ram_discard_manager(mr)) {
> > > -RamDiscardManager *rdm = 
> > > memory_region_get_ram_discard_manager(mr);
> > > -MemoryRegionSection tmp = {
> > > -.mr = mr,
> > > -.offset_within_region = xlat,
> > > -.size = int128_make64(len),
> > > -};
> > > -
> > > -/*
> > > - * Malicious VMs can map memory into the IOMMU, which is expected
> > > - * to remain discarded. vfio will pin all pages, populating 
> > > memory.
> > > - * Disallow that. vmstate priorities make sure any 
> > > RamDiscardManager
> > > - * were already restored before IOMMUs are restored.
> > > - */
> > > -if (!ram_discard_manager_is_populated(rdm, &tmp)) {
> > > -error_report("iommu map to discarded memory (e.g., unplugged 
> > > via"
> > > - " virtio-mem): %"HWADDR_PRIx"",
> > > - iotlb->translated_addr);
> > > -return false;
> > > -}
> > > +bool ret, mr_has_discard_manager;
> > >
> > > +ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
> > > +   &mr_has_discard_manager);
> > > +if (ret && mr_has_discard_manager) {
> > >  /*
> > >   * Malicious VMs might trigger discarding of IOMMU-mapped 
> > > memory. The
> > >   * pages will remain pinned inside vfio until unmapped, 
> > > resulting in a
> > > @@ -635,29 +601,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, 
> > > void **vaddr,
> > >   " intended via an IOMMU. It's possible to 
> > > mitigate "
> > >   " by setting/adjusting RLIMIT_MEMLOCK.");
> > >  }
> > > -
> > > -/*
> > > - * Translation truncates length to the IOMMU page size,
> > > - * check that it did not truncate too much.
> > > - */
> > > -if (len & iotlb->addr_mask) {
> > > -error_report("iommu has granularity incompatible with target 
> > > AS");
> > > -return false;
> > > -}
> > > -
> > > -if (vaddr) {
> > > -*vaddr = memory_region_get_ram_ptr(mr) + xlat;
> > > -}
> > > -
> > > -if (ram_addr) {
> > > -*ram_addr = memory_region_get_ram_addr(mr) + xlat;
> > > -}
> > > -
> > > -if (read_only) {
> > > -*read_only = !writable || mr->readonly;
> > > -}
> > > -
> > > -return true;
> > > +return ret;
> > >  }
> > >
> > >  static void 

Re: [PATCH v2 1/4] hw/acpi/aml-build: Only generate cluster node in PPTT when specified

2022-10-30 Thread wangyanan (Y)

Hi Yicong,

On 2022/10/27 11:26, Yicong Yang wrote:

From: Yicong Yang 

Currently we'll always generate a cluster node no matter user has
specified '-smp clusters=X' or not. Cluster is an optional level
and will participant the building of Linux scheduling domains and
only appears on a few platforms. It's unncessary to always build
it which cannot reflect the real topology on platforms have no
cluster and to avoid affecting the linux scheduling domains in the
VM. So only generate it when user specified explicitly.

Tested qemu-system-aarch64 with `-smp 8` and linux 6.1-rc1, without
this patch:
estuary:/sys/devices/system/cpu/cpu0/topology$ cat cluster_*
ff  # cluster_cpus
0-7 # cluster_cpus_list
56  # cluster_id

with this patch:
estuary:/sys/devices/system/cpu/cpu0/topology$ cat cluster_*
ff  # cluster_cpus
0-7 # cluster_cpus_list
36  # cluster_id, with no cluster node kernel will make it to
  physical package id

Signed-off-by: Yicong Yang 
---
  hw/acpi/aml-build.c   | 2 +-
  hw/core/machine-smp.c | 3 +++
  include/hw/boards.h   | 2 ++
  qemu-options.hx   | 2 ++
  4 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index e6bfac95c7..aab73af66d 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -2030,7 +2030,7 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, 
MachineState *ms,
  0, socket_id, NULL, 0);
  }
  
-if (mc->smp_props.clusters_supported) {

+if (mc->smp_props.clusters_supported && ms->smp.build_cluster) {
  if (cpus->cpus[n].props.cluster_id != cluster_id) {
  assert(cpus->cpus[n].props.cluster_id > cluster_id);
  cluster_id = cpus->cpus[n].props.cluster_id;
diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c
index b39ed21e65..5d37e8d07a 100644
--- a/hw/core/machine-smp.c
+++ b/hw/core/machine-smp.c
@@ -158,6 +158,9 @@ void machine_parse_smp_config(MachineState *ms,
  ms->smp.threads = threads;
  ms->smp.max_cpus = maxcpus;
  
+if (config->has_clusters)

+ms->smp.build_cluster = true;
+
  /* sanity-check of the computed topology */
  if (sockets * dies * clusters * cores * threads != maxcpus) {
  g_autofree char *topo_msg = cpu_hierarchy_to_string(ms);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 311ed17e18..c53f047b90 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -305,6 +305,7 @@ typedef struct DeviceMemoryState {
   * @cores: the number of cores in one cluster
   * @threads: the number of threads in one core
   * @max_cpus: the maximum number of logical processors on the machine
+ * @build_cluster: build cluster topology or not
   */
  typedef struct CpuTopology {
  unsigned int cpus;
@@ -314,6 +315,7 @@ typedef struct CpuTopology {
  unsigned int cores;
  unsigned int threads;
  unsigned int max_cpus;
+bool build_cluster;

build_cluster seems a variable defined specifically for ACPI PPTT
generation. It may not be proper to place it in the generic struct
CpuTopology which only holds topo members.

What about a more generic variable in struct SMPCompatProps
together with @clusters_supported. Something like below:

diff --git a/include/hw/boards.h b/include/hw/boards.h
index 1f57ee8ca2..8db0706d5d 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -130,11 +130,14 @@ typedef struct {
  * @prefer_sockets - whether sockets are preferred over cores in smp 
parsing

  * @dies_supported - whether dies are supported by the machine
  * @clusters_supported - whether clusters are supported by the machine
+ * @has_clusters - whether clusters is explicitly specified in the user
+ *    provided SMP configuration.
  */
 typedef struct {
 bool prefer_sockets;
 bool dies_supported;
 bool clusters_supported;
+    bool has_clusters;
 } SMPCompatProps;


  } CpuTopology;
  
  /**

diff --git a/qemu-options.hx b/qemu-options.hx
index eb38e5dc40..0a710e7be3 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -342,6 +342,8 @@ SRST
  were preferred over threads), however, this behaviour is considered
  liable to change. Prior to 6.2 the preference was sockets over cores
  over threads. Since 6.2 the preference is cores over sockets over threads.
+The cluster topology will only be generated if explicitly specified
+by the "-cluster" option.

no "-cluster" option, only "-smp" :)

  For example, the following option defines a machine board with 2 sockets
  of 1 core before 6.2 and 1 socket of 2 cores after 6.2:

Maybe better to add a note at *end* of the doc about -smp like:

Note: The cluster topology will only be generated in ACPI and exposed
to guest if it's explicitly specified in -smp.

Thanks,
Yanan



Re: [PATCH v9 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-10-30 Thread Cindy Lu
On Mon, 31 Oct 2022 at 14:55, Michael S. Tsirkin  wrote:
>
> On Mon, Oct 31, 2022 at 02:44:11PM +0800, Cindy Lu wrote:
> > On Mon, 31 Oct 2022 at 14:38, Michael S. Tsirkin  wrote:
> > >
> > > On Mon, Oct 31, 2022 at 11:10:19AM +0800, Cindy Lu wrote:
> > > > - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
> > > >   change the name to memory_get_xlat_addr(). So we can use this
> > > >   function on other devices, such as vDPA device.
> > > > - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will 
> > > > check
> > > >   whether the memory is backed by a discard manager. then device can
> > > >   have its own warning.
> > > >
> > > > Signed-off-by: Cindy Lu 
> > >
> > > Could you rebase on top of my tree (config interrupt support conflicts).
> > >
> > Hi Micheal,
> > sure, will do, but I found a crash in config interrupt while testing
> > vhost user,
> > should I post a new version for it? Or maybe a patch later?
> > Thanks
> > Cindy
>
> New version, I will drop this one. So do you want this one picked up and
> config interrupt on top?
>
sure, I will rebase the config interrupt patches on top of this
Thanks
Cindy
> > > > ---
> > > >  hw/vfio/common.c  | 66 +++
> > > >  include/exec/memory.h |  4 +++
> > > >  softmmu/memory.c  | 72 +++
> > > >  3 files changed, 81 insertions(+), 61 deletions(-)
> > > >
> > > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > > > index ace9562a9b..6bc02b32c8 100644
> > > > --- a/hw/vfio/common.c
> > > > +++ b/hw/vfio/common.c
> > > > @@ -578,45 +578,11 @@ static bool 
> > > > vfio_listener_skipped_section(MemoryRegionSection *section)
> > > >  static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> > > > ram_addr_t *ram_addr, bool *read_only)
> > > >  {
> > > > -MemoryRegion *mr;
> > > > -hwaddr xlat;
> > > > -hwaddr len = iotlb->addr_mask + 1;
> > > > -bool writable = iotlb->perm & IOMMU_WO;
> > > > -
> > > > -/*
> > > > - * The IOMMU TLB entry we have just covers translation through
> > > > - * this IOMMU to its immediate target.  We need to translate
> > > > - * it the rest of the way through to memory.
> > > > - */
> > > > -mr = address_space_translate(&address_space_memory,
> > > > - iotlb->translated_addr,
> > > > - &xlat, &len, writable,
> > > > - MEMTXATTRS_UNSPECIFIED);
> > > > -if (!memory_region_is_ram(mr)) {
> > > > -error_report("iommu map to non memory area %"HWADDR_PRIx"",
> > > > - xlat);
> > > > -return false;
> > > > -} else if (memory_region_has_ram_discard_manager(mr)) {
> > > > -RamDiscardManager *rdm = 
> > > > memory_region_get_ram_discard_manager(mr);
> > > > -MemoryRegionSection tmp = {
> > > > -.mr = mr,
> > > > -.offset_within_region = xlat,
> > > > -.size = int128_make64(len),
> > > > -};
> > > > -
> > > > -/*
> > > > - * Malicious VMs can map memory into the IOMMU, which is 
> > > > expected
> > > > - * to remain discarded. vfio will pin all pages, populating 
> > > > memory.
> > > > - * Disallow that. vmstate priorities make sure any 
> > > > RamDiscardManager
> > > > - * were already restored before IOMMUs are restored.
> > > > - */
> > > > -if (!ram_discard_manager_is_populated(rdm, &tmp)) {
> > > > -error_report("iommu map to discarded memory (e.g., 
> > > > unplugged via"
> > > > - " virtio-mem): %"HWADDR_PRIx"",
> > > > - iotlb->translated_addr);
> > > > -return false;
> > > > -}
> > > > +bool ret, mr_has_discard_manager;
> > > >
> > > > +ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
> > > > +   &mr_has_discard_manager);
> > > > +if (ret && mr_has_discard_manager) {
> > > >  /*
> > > >   * Malicious VMs might trigger discarding of IOMMU-mapped 
> > > > memory. The
> > > >   * pages will remain pinned inside vfio until unmapped, 
> > > > resulting in a
> > > > @@ -635,29 +601,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry 
> > > > *iotlb, void **vaddr,
> > > >   " intended via an IOMMU. It's possible to 
> > > > mitigate "
> > > >   " by setting/adjusting RLIMIT_MEMLOCK.");
> > > >  }
> > > > -
> > > > -/*
> > > > - * Translation truncates length to the IOMMU page size,
> > > > - * check that it did not truncate too much.
> > > > - */
> > > > -if (len & iotlb->addr_mask) {
> > > > -error_report("iommu has granularity incompatible with target 
> > > > AS");
> > > > -return false;
> > > > -}
> > > > -
> > > > -if (vaddr) {
> > > > -

Re: [PATCH] ui/cocoa: Support hardware cursor interface

2022-10-30 Thread Akihiko Odaki

Hi,

On 2022/10/30 14:20, Elliot Nunn wrote:

Akihiko,

Thanks very much for reviewing my patch.

I think that you were right to use the sprite-within-a-window approach,
and avoid warping the OS cursor. I tried to compensate for the error
that cursor warping causes in the subsequent mouse event, but there is
still some error getting through that makes the cursor feel "janky".

But in absolute pointing mode, will it be possible to remove the guest's
code path from visual updates of the cursor? I find that under Mac OS 9,
this provides better responsiveness. I can think of two methods:

1. In absolute pointing mode, re-enable Cocoa's cursor and let the host
OS move it according to user input.

2. Keep the cursor sprite, but move it according to Cocoa's mouse
movement events instead of dpy_mouse_set events.

I prefer option 2. What do you think?


My patch has been only tested with recent Linux, but it certainly should 
be ensured that it works well for old systems when upstreaming.


First I'd like to know what display device you use. It looks like 
dpy_mouse_set is used only by ati-vga, vhost-user-gpu, virtio-gpu, and 
vmware.


Also, can you give reasoning while 2 is preferred? 1 would allow to 
exploit the hardware's feature for cursor composition, resulting in 
smoother experience and a bit less power consumption. But there may be 
complications it can cause so I have not decided which one is the better 
yet.




And I didn't realise that you had added VirGL support to cocoa.m. Well
done! Is it on track for release?

My patch should be withdrawn from consideration, in favour of a future
solution that does not use cursor warping.


I'm not really pushing my changes hard so it's kind of stale. Perhaps it 
is better to rewrite the cursor composition patch in a way that does not 
depend on the Virgl patch. I'm also aware that the cursor composition 
using Core Graphics is somewhat laggy so it may be better to rewrite it 
using subview, Core Animation, Metal, or something else. But I have not 
done that yet.


Regards,
Akihiko Odaki



Many thanks,

Elliot


On 6 Oct 2022, at 8:15 pm, Akihiko Odaki  wrote:

Thanks Peter and Elliot,

Unfortunately Patchew seems to have failed to apply the patch to the
current master. It would be nice if you rebase it to the current
master.

Actually I have a patch to add hardware support to ui/cocoa, but I
have not submitted to the mailing list because it depends on a number
of other patches:
https://github.com/akihikodaki/qemu/commit/34199fcd4080ce8c705b46df26fdf02966b1610c

My patch avoided using CGWarpMouseCursorPosition because of its
quirks. I'd like to test your patch by myself to see if it avoids them
properly for my own workloads.

I have also added some comments to the patch. Please see the below.

Regards,
Akihiko Odaki

On Wed, Oct 5, 2022 at 12:39 AM Peter Maydell  wrote:


Ccing Akihiko to see if he wants to review this cocoa ui frontend
patch.

also available at:
https://lore.kernel.org/qemu-devel/54930451-d85f-4ce0-9a45-b3478c5a6...@www.fastmail.com/

I can confirm that the patch does build, but I don't have any
interesting graphics-using test images to hand to test with.

thanks
-- PMM

On Thu, 4 Aug 2022 at 07:28, Elliot Nunn  wrote:


Implement dpy_cursor_define() and dpy_mouse_set() on macOS.

The main benefit is from dpy_cursor_define: in absolute pointing mode, the
host can redraw the cursor on the guest's behalf much faster than the guest
can itself.

To provide the programmatic movement expected from a hardware cursor,
dpy_mouse_set is also implemented.

Tricky cases are handled:
- dpy_mouse_set() avoids rounded window corners.
- The sometimes-delay between warping the cursor and an affected mouse-move
  event is accounted for.
- Cursor bitmaps are nearest-neighbor scaled to Retina size.

Signed-off-by: Elliot Nunn 
---
ui/cocoa.m | 263 -
1 file changed, 240 insertions(+), 23 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 5a8bd5dd84..f9d54448e4 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -85,12 +85,20 @@ static void cocoa_switch(DisplayChangeListener *dcl,

static void cocoa_refresh(DisplayChangeListener *dcl);

+static void cocoa_mouse_set(DisplayChangeListener *dcl,
+int x, int y, int on);
+
+static void cocoa_cursor_define(DisplayChangeListener *dcl,
+QEMUCursor *c);
+
static NSWindow *normalWindow;
static const DisplayChangeListenerOps dcl_ops = {
 .dpy_name  = "cocoa",
 .dpy_gfx_update = cocoa_update,
 .dpy_gfx_switch = cocoa_switch,
 .dpy_refresh = cocoa_refresh,
+.dpy_mouse_set = cocoa_mouse_set,
+.dpy_cursor_define = cocoa_cursor_define,
};
static DisplayChangeListener dcl = {
 .ops = &dcl_ops,
@@ -313,6 +321,13 @@ @interface QemuCocoaView : NSView
 BOOL isFullscreen;
 BOOL isAbsoluteEnabled;
 CFMachPortRef eventsTap;
+NSCursor *guestCursor;
+BOOL cursorHiddenByMe;


Who

[PATCH v3] target/hppa: Fix fid instruction emulation

2022-10-30 Thread Helge Deller
The fid instruction (Floating-Point Identify) puts the FPU model and
revision into the Status Register. Since those values shouldn't be 0,
store values there which a PCX-L2 (for 32-bit) or a PCX-W2 (for 64-bit)
would return. Noticed while trying to install MPE/iX.

Signed-off-by: Helge Deller 
Reviewed-by: Richard Henderson 
---
v3: Removed whole FID comment in insns.decode
v2: Add ULL to integer constants, enhanced commit message.


diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index c7a7e997f9..27341d27b2 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -388,10 +388,7 @@ fmpyfadd_d  101110 rm1:5 rm2:5 ... 0 1 ..0 0 0 neg:1 
t:5ra3=%rc32

 # Floating point class 0

-# FID.  With r = t = 0, which via fcpy puts 0 into fr0.
-# This is machine/revision = 0, which is reserved for simulator.
-fcpy_f  001100 0 0 0 00 0   \
-&fclass01 r=0 t=0
+fid_f   001100 0 0 000 00 00 0

 fcpy_f  001100 . . 010 00 .. .  @f0c_0
 fabs_f  001100 . . 011 00 .. .  @f0c_0
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index d15b9e27c7..981f8ee03d 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3622,6 +3622,17 @@ static void gen_fcpy_f(TCGv_i32 dst, TCGv_env unused, 
TCGv_i32 src)
 tcg_gen_mov_i32(dst, src);
 }

+static bool trans_fid_f(DisasContext *ctx, arg_fid_f *a)
+{
+nullify_over(ctx);
+#if TARGET_REGISTER_BITS == 64
+save_frd(0, tcg_const_i64(0x130800ULL)); /* PA8700 (PCX-W2) */
+#else
+save_frd(0, tcg_const_i64(0x0f0800ULL)); /* PA7300LC (PCX-L2) */
+#endif
+return nullify_end(ctx);
+}
+
 static bool trans_fcpy_f(DisasContext *ctx, arg_fclass01 *a)
 {
 return do_fop_wew(ctx, a->t, a->r, gen_fcpy_f);



Re: [PATCH v2 1/2] vhost-user: Refactor vhost acked features saving

2022-10-30 Thread Hyman Huang




在 2022/10/30 13:14, Hyman Huang 写道:



在 2022/10/29 16:28, Michael S. Tsirkin 写道:

On Sat, Oct 29, 2022 at 01:25:44AM +0800, huang...@chinatelecom.cn wrote:

From: Hyman Huang(黄勇) 

Abstract vhost acked features saving into
vhost_user_save_acked_features, export it as util function.



Thanks for the patch!

This commit log makes it sound like it's just a refactoring
while it's actually a behaviour change.
This log needs to include analysis of why is saving only if features != 0
safe.

Could you include that pls?

Thanks!

Signed-off-by: Hyman Huang(黄勇) 
Signed-off-by: Guoyi Tu 
---
  include/net/vhost-user.h |  2 ++
  net/vhost-user.c | 35 +++
  2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/include/net/vhost-user.h b/include/net/vhost-user.h
index 5bcd8a6..00d4661 100644
--- a/include/net/vhost-user.h
+++ b/include/net/vhost-user.h
@@ -14,5 +14,7 @@
  struct vhost_net;
  struct vhost_net *vhost_user_get_vhost_net(NetClientState *nc);
  uint64_t vhost_user_get_acked_features(NetClientState *nc);
+void vhost_user_save_acked_features(NetClientState *nc,
+    bool cleanup);
  #endif /* VHOST_USER_H */
diff --git a/net/vhost-user.c b/net/vhost-user.c
index b1a0247..c512cc9 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -45,24 +45,31 @@ uint64_t 
vhost_user_get_acked_features(NetClientState *nc)

  return s->acked_features;
  }
-static void vhost_user_stop(int queues, NetClientState *ncs[])
+void vhost_user_save_acked_features(NetClientState *nc, bool cleanup)
  {
  NetVhostUserState *s;
+
+    s = DO_UPCAST(NetVhostUserState, nc, nc);
+    if (s->vhost_net) {
+    uint64_t features = vhost_net_get_acked_features(s->vhost_net);
+    if (features) {
+    s->acked_features = features;
+    }
+
+    if (cleanup) {
+    vhost_net_cleanup(s->vhost_net);
+    }
+    }
+}
+
+static void vhost_user_stop(int queues, NetClientState *ncs[])
+{
  int i;
  for (i = 0; i < queues; i++) {
  assert(ncs[i]->info->type == NET_CLIENT_DRIVER_VHOST_USER);
-    s = DO_UPCAST(NetVhostUserState, nc, ncs[i]);
-
-    if (s->vhost_net) {
-    /* save acked features */
-    uint64_t features = 
vhost_net_get_acked_features(s->vhost_net);

-    if (features) {
-    s->acked_features = features;
-    }
-    vhost_net_cleanup(s->vhost_net);
-    }
+    vhost_user_save_acked_features(ncs[i], true);
  }
  }
@@ -251,11 +258,7 @@ static void chr_closed_bh(void *opaque)
  s = DO_UPCAST(NetVhostUserState, nc, ncs[0]);
  for (i = queues -1; i >= 0; i--) {
-    s = DO_UPCAST(NetVhostUserState, nc, ncs[i]);
-
-    if (s->vhost_net) {
-    s->acked_features = 
vhost_net_get_acked_features(s->vhost_net);

-    }
+    vhost_user_save_acked_features(ncs[i], false);



So this won't do anything if acked features is 0.
When does this have any effect? How about if guest
acked some features, and then reset the device.
Don't we want to reset the features in this case too?

Sorry about that i just notice that Stefano has replied the question 
about "why saving features only if the features aren't 0" 3 weeks ago, 
it seems that the answer is not clear.
When tring the next version, i seems to find the reason of backing up 
acked_features only if the source features aren't 0:


Qemu do not want reset backup negotiated features to 0 and consequently
loss it, let's analyze such process:

1. guest acked virtio-net features
2. Qemu backup it to acked_features in NetVhostUserState
3. vhost slave device unexpected got failed and disconnectted from 
master, Qemu update acked_features in chr_closed_bh and free the 
vhost_dev, acked_features loss.
4. when vhost slave device show up and Qemu start vhost device again but 
failed unexpectedly, vhost_user_stop will called and assign 
acked_features in vhost_dev to NetVhostUserState, which are 0, and the

original negotiated features loss.

So i will need to think about if it is reasonable to refactor vhost 
acked features saving next version.


Thanks,

Yong


IMHO, as i metioned in the link:
https://patchew.org/QEMU/20220926063641.25038-1-huang...@chinatelecom.cn/20220926063641.25038-2-huang...@chinatelecom.cn/

"Indeed, backing up acked_features in the two functions chr_closed_bh()
vhost_user_stop() are kind of different as above, it also seems a little
weried for me.

IMHO, we can always keep the acked_features in NetVhostUserState the
same as acked_features in vhost_dev no matter what features are, since
this is the role that acked_features in NetVhostUserState plays and we
can just focus on the validation of acked_features in vhost_dev if
something goes wrong"

Maybe we could adopt above strategy and saving acked_features no matter 
whether the featuress are 0 or not.


The next version will modify the logic and skip checking features before 
saving, meanwhi

[PATCH] Run docker probe only if docker or podman are available

2022-10-30 Thread Stefan Weil via
The docker probe uses "sudo -n" which can cause an e-mail with a security 
warning
each time when configure is run. Therefore run docker probe only if either 
docker
or podman are available.

That avoids the problematic "sudo -n" on build environments which have neither
docker nor podman installed.

Fixes: c4575b59155e2e00 ("configure: store container engine in config-host.mak")
Signed-off-by: Stefan Weil 
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 81561be7c1..3af99282b7 100755
--- a/configure
+++ b/configure
@@ -1779,7 +1779,7 @@ fi
 # functions to probe cross compilers
 
 container="no"
-if test $use_containers = "yes"; then
+if test $use_containers = "yes" && (has "docker" || has "podman"); then
 case $($python "$source_path"/tests/docker/docker.py probe) in
 *docker) container=docker ;;
 podman) container=podman ;;
-- 
2.30.2




[RFC v4 3/3] virtio-blk: add some trace events for zoned emulation

2022-10-30 Thread Sam Li
Signed-off-by: Sam Li 
---
 hw/block/trace-events |  7 +++
 hw/block/virtio-blk.c | 12 
 2 files changed, 19 insertions(+)

diff --git a/hw/block/trace-events b/hw/block/trace-events
index 2c45a62bd5..f47da6fcd4 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -44,9 +44,16 @@ pflash_write_unknown(const char *name, uint8_t cmd) "%s: 
unknown command 0x%02x"
 # virtio-blk.c
 virtio_blk_req_complete(void *vdev, void *req, int status) "vdev %p req %p 
status %d"
 virtio_blk_rw_complete(void *vdev, void *req, int ret) "vdev %p req %p ret %d"
+virtio_blk_zone_report_complete(void *vdev, void *req, unsigned int nr_zones, 
int ret) "vdev %p req %p nr_zones %d ret %d"
+virtio_blk_zone_mgmt_complete(void *vdev, void *req, int ret) "vdev %p req %p 
ret %d"
+virtio_blk_zone_append_complete(void *vdev, void *req, int64_t sector, int 
ret) "vdev %p req %p, append sector 0x%" PRIx64 " ret %d"
 virtio_blk_handle_write(void *vdev, void *req, uint64_t sector, size_t 
nsectors) "vdev %p req %p sector %"PRIu64" nsectors %zu"
 virtio_blk_handle_read(void *vdev, void *req, uint64_t sector, size_t 
nsectors) "vdev %p req %p sector %"PRIu64" nsectors %zu"
 virtio_blk_submit_multireq(void *vdev, void *mrb, int start, int num_reqs, 
uint64_t offset, size_t size, bool is_write) "vdev %p mrb %p start %d num_reqs 
%d offset %"PRIu64" size %zu is_write %d"
+virtio_blk_handle_zone_report(void *vdev, void *req, int64_t sector, unsigned 
int nr_zones) "vdev %p req %p sector 0x%" PRIx64 " nr_zones %d"
+virtio_blk_handle_zone_mgmt(void *vdev, void *req, uint8_t op, int64_t sector, 
int64_t len) "vdev %p req %p op 0x%x sector 0x%" PRIx64 " len 0x%" PRIx64 ""
+virtio_blk_handle_zone_reset_all(void *vdev, void *req, int64_t sector, 
int64_t len) "vdev %p req %p sector 0x%" PRIx64 " cap 0x%" PRIx64 ""
+virtio_blk_handle_zone_append(void *vdev, void *req, int64_t sector) "vdev %p 
req %p, append sector 0x%" PRIx64 ""
 
 # hd-geometry.c
 hd_geometry_lchs_guess(void *blk, int cyls, int heads, int secs) "blk %p LCHS 
%d %d %d"
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 4f3625840a..e7d85dc049 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -663,6 +663,7 @@ static void virtio_blk_zone_report_complete(void *opaque, 
int ret)
 int64_t nz = data->zone_report_data.nr_zones;
 int8_t err_status = VIRTIO_BLK_S_OK;
 
+trace_virtio_blk_zone_report_complete(vdev, req, nz, ret);
 if (ret) {
 err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
 goto out;
@@ -777,6 +778,8 @@ static int virtio_blk_handle_zone_report(VirtIOBlockReq 
*req)
 nr_zones = (req->in_len - sizeof(struct virtio_blk_inhdr) -
 sizeof(struct virtio_blk_zone_report)) /
sizeof(struct virtio_blk_zone_descriptor);
+trace_virtio_blk_handle_zone_report(vdev, req,
+offset >> BDRV_SECTOR_BITS, nr_zones);
 
 zone_size = sizeof(BlockZoneDescriptor) * nr_zones;
 data = g_malloc(sizeof(ZoneCmdData));
@@ -802,7 +805,9 @@ static void virtio_blk_zone_mgmt_complete(void *opaque, int 
ret)
 ZoneCmdData *data = opaque;
 VirtIOBlockReq *req = data->req;
 VirtIOBlock *s = req->dev;
+VirtIODevice *vdev = VIRTIO_DEVICE(s);
 int8_t err_status = VIRTIO_BLK_S_OK;
+trace_virtio_blk_zone_mgmt_complete(vdev, req,ret);
 
 if (ret) {
 err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
@@ -830,6 +835,8 @@ static int virtio_blk_handle_zone_mgmt(VirtIOBlockReq *req, 
BlockZoneOp op)
 /* Entire drive capacity */
 offset = 0;
 len = capacity;
+trace_virtio_blk_handle_zone_reset_all(vdev, req, 0,
+   bs->total_sectors);
 } else {
 if (bs->bl.zone_size > capacity - offset) {
 /* The zoned device allows the last smaller zone. */
@@ -837,6 +844,9 @@ static int virtio_blk_handle_zone_mgmt(VirtIOBlockReq *req, 
BlockZoneOp op)
 } else {
 len = bs->bl.zone_size;
 }
+trace_virtio_blk_handle_zone_mgmt(vdev, req, op,
+  offset >> BDRV_SECTOR_BITS,
+  len >> BDRV_SECTOR_BITS);
 }
 
 if (!check_zoned_request(s, offset, 0, false, &err_status)) {
@@ -882,6 +892,7 @@ static void virtio_blk_zone_append_complete(void *opaque, 
int ret)
 err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
 goto out;
 }
+trace_virtio_blk_zone_append_complete(vdev, req, append_sector, ret);
 
 out:
 aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
@@ -901,6 +912,7 @@ static int virtio_blk_handle_zone_append(VirtIOBlockReq 
*req,
 int64_t offset = virtio_ldq_p(vdev, &req->out.sector) << BDRV_SECTOR_BITS;
 int64_t len = iov_size(out_iov, niov);
 
+trace_virtio_blk_handle_zone_append(vdev, req, offset >> BDRV_SECTOR_BITS);
 if (!check_zoned_request(s, offset, len, true, &err_status)) {
 

[RFC v4 1/3] include: update virtio_blk headers

2022-10-30 Thread Sam Li
Use scripts/update-linux-headers.sh to update virtio-blk headers
from Dmitry's "virtio-blk:add support for zoned block devices"
Linux patches.

Signed-off-by: Sam Li 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Dmitry Fomichev 
---
 include/standard-headers/linux/virtio_blk.h | 158 ++--
 1 file changed, 142 insertions(+), 16 deletions(-)

diff --git a/include/standard-headers/linux/virtio_blk.h 
b/include/standard-headers/linux/virtio_blk.h
index 2dcc90826a..3744e4da1b 100644
--- a/include/standard-headers/linux/virtio_blk.h
+++ b/include/standard-headers/linux/virtio_blk.h
@@ -25,10 +25,10 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE. */
-#include "standard-headers/linux/types.h"
-#include "standard-headers/linux/virtio_ids.h"
-#include "standard-headers/linux/virtio_config.h"
-#include "standard-headers/linux/virtio_types.h"
+#include 
+#include 
+#include 
+#include 
 
 /* Feature bits */
 #define VIRTIO_BLK_F_SIZE_MAX  1   /* Indicates maximum segment size */
@@ -40,6 +40,8 @@
 #define VIRTIO_BLK_F_MQ12  /* support more than one vq */
 #define VIRTIO_BLK_F_DISCARD   13  /* DISCARD is supported */
 #define VIRTIO_BLK_F_WRITE_ZEROES  14  /* WRITE ZEROES is supported */
+#define VIRTIO_BLK_F_SECURE_ERASE  16 /* Secure Erase is supported */
+#define VIRTIO_BLK_F_ZONED 17  /* Zoned block device */
 
 /* Legacy feature bits */
 #ifndef VIRTIO_BLK_NO_LEGACY
@@ -47,8 +49,10 @@
 #define VIRTIO_BLK_F_SCSI  7   /* Supports scsi command passthru */
 #define VIRTIO_BLK_F_FLUSH 9   /* Flush command supported */
 #define VIRTIO_BLK_F_CONFIG_WCE11  /* Writeback mode available in 
config */
+#ifndef __KERNEL__
 /* Old (deprecated) name for VIRTIO_BLK_F_FLUSH. */
 #define VIRTIO_BLK_F_WCE VIRTIO_BLK_F_FLUSH
+#endif
 #endif /* !VIRTIO_BLK_NO_LEGACY */
 
 #define VIRTIO_BLK_ID_BYTES20  /* ID string length */
@@ -63,8 +67,8 @@ struct virtio_blk_config {
/* geometry of the device (if VIRTIO_BLK_F_GEOMETRY) */
struct virtio_blk_geometry {
__virtio16 cylinders;
-   uint8_t heads;
-   uint8_t sectors;
+   __u8 heads;
+   __u8 sectors;
} geometry;
 
/* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
@@ -72,17 +76,17 @@ struct virtio_blk_config {
 
/* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY  */
/* exponent for physical block per logical block. */
-   uint8_t physical_block_exp;
+   __u8 physical_block_exp;
/* alignment offset in logical blocks. */
-   uint8_t alignment_offset;
+   __u8 alignment_offset;
/* minimum I/O size without performance penalty in logical blocks. */
__virtio16 min_io_size;
/* optimal sustained I/O size in logical blocks. */
__virtio32 opt_io_size;
 
/* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */
-   uint8_t wce;
-   uint8_t unused;
+   __u8 wce;
+   __u8 unused;
 
/* number of vqs, only available when VIRTIO_BLK_F_MQ is set */
__virtio16 num_queues;
@@ -116,10 +120,35 @@ struct virtio_blk_config {
 * Set if a VIRTIO_BLK_T_WRITE_ZEROES request may result in the
 * deallocation of one or more of the sectors.
 */
-   uint8_t write_zeroes_may_unmap;
+   __u8 write_zeroes_may_unmap;
 
-   uint8_t unused1[3];
-} QEMU_PACKED;
+   __u8 unused1[3];
+
+   /* the next 3 entries are guarded by VIRTIO_BLK_F_SECURE_ERASE */
+   /*
+* The maximum secure erase sectors (in 512-byte sectors) for
+* one segment.
+*/
+   __virtio32 max_secure_erase_sectors;
+   /*
+* The maximum number of secure erase segments in a
+* secure erase command.
+*/
+   __virtio32 max_secure_erase_seg;
+   /* Secure erase commands must be aligned to this number of sectors. */
+   __virtio32 secure_erase_sector_alignment;
+
+   /* Zoned block device characteristics (if VIRTIO_BLK_F_ZONED) */
+   struct virtio_blk_zoned_characteristics {
+   __virtio32 zone_sectors;
+   __virtio32 max_open_zones;
+   __virtio32 max_active_zones;
+   __virtio32 max_append_sectors;
+   __virtio32 write_granularity;
+   __u8 model;
+   __u8 unused2[3];
+   } zoned;
+} __attribute__((packed));
 
 /*
  * Command types
@@ -153,6 +182,30 @@ struct virtio_blk_config {
 /* Write zeroes command */
 #define VIRTIO_BLK_T_WRITE_ZEROES  13
 
+/* Secure erase command */
+#define VIRTIO_BLK_T_SECURE_ERASE  14
+
+/* Zone append command */
+#define VIRTIO_BLK_T_ZONE_APPEND15
+
+/* Report zones command */
+#define VIRTIO_BLK_T_ZONE_REPORT16
+
+/* Open zone command */
+#define VIRTIO_BLK_T_ZONE_OPEN  18

[RFC v4 2/3] virtio-blk: add zoned storage emulation for zoned devices

2022-10-30 Thread Sam Li
This patch extends virtio-blk emulation to handle zoned device commands
by calling the new block layer APIs to perform zoned device I/O on
behalf of the guest. It supports Report Zone, four zone oparations (open,
close, finish, reset), and Append Zone.

The VIRTIO_BLK_F_ZONED feature bit will only be set if the host does
support zoned block devices. Regular block devices(conventional zones)
will not be set.

The guest os can use blktests, fio to test those commands on zoned devices.
Furthermore, using zonefs to test zone append write is also supported.

Signed-off-by: Sam Li 
---
 hw/block/virtio-blk-common.c |   2 +
 hw/block/virtio-blk.c| 387 +++
 2 files changed, 389 insertions(+)

diff --git a/hw/block/virtio-blk-common.c b/hw/block/virtio-blk-common.c
index ac52d7c176..e2f8e2f6da 100644
--- a/hw/block/virtio-blk-common.c
+++ b/hw/block/virtio-blk-common.c
@@ -29,6 +29,8 @@ static const VirtIOFeature feature_sizes[] = {
  .end = endof(struct virtio_blk_config, discard_sector_alignment)},
 {.flags = 1ULL << VIRTIO_BLK_F_WRITE_ZEROES,
  .end = endof(struct virtio_blk_config, write_zeroes_may_unmap)},
+{.flags = 1ULL << VIRTIO_BLK_F_ZONED,
+ .end = endof(struct virtio_blk_config, zoned)},
 {}
 };
 
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 8131ec2dbc..4f3625840a 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -26,6 +26,9 @@
 #include "hw/virtio/virtio-blk.h"
 #include "dataplane/virtio-blk.h"
 #include "scsi/constants.h"
+#if defined(CONFIG_BLKZONED)
+#include 
+#endif
 #ifdef __linux__
 # include 
 #endif
@@ -592,6 +595,332 @@ err:
 return err_status;
 }
 
+typedef struct ZoneCmdData {
+VirtIOBlockReq *req;
+union {
+struct {
+unsigned int nr_zones;
+BlockZoneDescriptor *zones;
+} zone_report_data;
+struct {
+int64_t offset;
+} zone_append_data;
+};
+} ZoneCmdData;
+
+/*
+ * check zoned_request: error checking before issuing requests. If all checks
+ * passed, return true.
+ * append: true if only zone append requests issued.
+ */
+static bool check_zoned_request(VirtIOBlock *s, int64_t offset, int64_t len,
+ bool append, uint8_t *status) {
+BlockDriverState *bs = blk_bs(s->blk);
+int index = offset / bs->bl.zone_size;
+
+if (offset < 0 || len < 0 || offset > (bs->total_sectors << 
BDRV_SECTOR_BITS) - len) {
+*status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
+return false;
+}
+
+if (!virtio_has_feature(s->host_features, VIRTIO_BLK_F_ZONED)) {
+*status = VIRTIO_BLK_S_UNSUPP;
+return false;
+}
+
+if (append) {
+if ((offset % bs->bl.write_granularity) != 0) {
+*status = VIRTIO_BLK_S_ZONE_UNALIGNED_WP;
+return false;
+}
+
+if (BDRV_ZT_IS_CONV(bs->bl.wps->wp[index])) {
+*status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
+return false;
+}
+
+if (len / 512 > bs->bl.max_append_sectors) {
+if (bs->bl.max_append_sectors == 0) {
+*status = VIRTIO_BLK_S_UNSUPP;
+} else {
+*status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
+}
+return false;
+}
+}
+return true;
+}
+
+static void virtio_blk_zone_report_complete(void *opaque, int ret)
+{
+ZoneCmdData *data = opaque;
+VirtIOBlockReq *req = data->req;
+VirtIOBlock *s = req->dev;
+VirtIODevice *vdev = VIRTIO_DEVICE(req->dev);
+struct iovec *in_iov = req->elem.in_sg;
+unsigned in_num = req->elem.in_num;
+int64_t zrp_size, n, j = 0;
+int64_t nz = data->zone_report_data.nr_zones;
+int8_t err_status = VIRTIO_BLK_S_OK;
+
+if (ret) {
+err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
+goto out;
+}
+
+struct virtio_blk_zone_report zrp_hdr = (struct virtio_blk_zone_report) {
+.nr_zones = cpu_to_le64(nz),
+};
+zrp_size = sizeof(struct virtio_blk_zone_report)
+   + sizeof(struct virtio_blk_zone_descriptor) * nz;
+n = iov_from_buf(in_iov, in_num, 0, &zrp_hdr, sizeof(zrp_hdr));
+if (n != sizeof(zrp_hdr)) {
+virtio_error(vdev, "Driver provided intput buffer that is too small!");
+err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD;
+goto out;
+}
+
+for (size_t i = sizeof(zrp_hdr); i < zrp_size;
+i += sizeof(struct virtio_blk_zone_descriptor), ++j) {
+struct virtio_blk_zone_descriptor desc =
+(struct virtio_blk_zone_descriptor) {
+.z_start = cpu_to_le64(data->zone_report_data.zones[j].start
+>> BDRV_SECTOR_BITS),
+.z_cap = cpu_to_le64(data->zone_report_data.zones[j].cap
+>> BDRV_SECTOR_BITS),
+.z_wp = cpu_to_le64(data->zone_report_data.zones[j].wp
+>> BDRV_SECTOR_BITS),
+};
+
+switch (data->zone

[RFC v4 0/3] Add zoned storage emulation to virtio-blk driver

2022-10-30 Thread Sam Li
Note: the virtio-blk headers isn't upstream in the kernel yet therefore
marked as an RFC. More information can be found here:
https://patchwork.kernel.org/project/linux-block/cover/20221030043545.974223-1-dmitry.fomic...@wdc.com/

v4:
- change the way writing zone append request result to buffer
- change zone state, zone type value of virtio_blk_zone_descriptor
- add trace events for new zone APIs

v3:
- use qemuio_from_buffer to write status bit [Stefan]
- avoid using req->elem directly [Stefan]
- fix error checkings and memory leak [Stefan]

v2:
- change units of emulated zone op coresponding to block layer APIs
- modify error checking cases [Stefan, Damien]

v1:
- add zoned storage emulation

Sam Li (3):
  include: update virtio_blk headers
  virtio-blk: add zoned storage emulation for zoned devices
  virtio-blk: add some trace events for zoned emulation

 hw/block/trace-events   |   7 +
 hw/block/virtio-blk-common.c|   2 +
 hw/block/virtio-blk.c   | 399 
 include/standard-headers/linux/virtio_blk.h | 158 +++-
 4 files changed, 550 insertions(+), 16 deletions(-)

-- 
2.38.1




Re: [PATCH] ui/cocoa: Support hardware cursor interface

2022-10-30 Thread Elliot Nunn
Akihiko,

Sounds like you've done a lot of work on ui/cocoa, with the goal of
improving the experience with modern Linux guests. My goal is to improve
the experience with antiquated Mac OS 9 guests.

> My patch has been only tested with recent Linux, but it certainly should
> be ensured that it works well for old systems when upstreaming.
> 
> First I'd like to know what display device you use. It looks like
> dpy_mouse_set is used only by ati-vga, vhost-user-gpu, virtio-gpu, and
> vmware.

I was using my own hardware cursor patches to the VGA device, but now I am
using virtio-gpu. My Mac OS 9 driver for virtio-gpu is in progress.

>> 1. In absolute pointing mode, re-enable Cocoa's cursor and let the host
>> OS move it according to user input.
>> 2. Keep the cursor sprite, but move it according to Cocoa's mouse
>> movement events instead of dpy_mouse_set events.
> 
> Also, can you give reasoning while 2 is preferred? 1 would allow to
> exploit the hardware's feature for cursor composition, resulting in
> smoother experience and a bit less power consumption. But there may be
> complications it can cause so I have not decided which one is the better
> yet.

Mainly that it would simplify the code. OTOH, if we expect the guest to
use the hardware cursor facility, then it's only fair that the host does
the same. I'm open to either option. We should probably try both.

>> And I didn't realise that you had added VirGL support to cocoa.m. Well
>> done! Is it on track for release?
>> My patch should be withdrawn from consideration, in favour of a future
>> solution that does not use cursor warping.
> 
> I'm not really pushing my changes hard so it's kind of stale. Perhaps it
> is better to rewrite the cursor composition patch in a way that does not
> depend on the Virgl patch. I'm also aware that the cursor composition
> using Core Graphics is somewhat laggy so it may be better to rewrite it
> using subview, Core Animation, Metal, or something else. But I have not
> done that yet.

Is there some Cocoa-native way of compositing within the window, that
will work with or without a GL surface? Subviews sound appropriate.

Not that I have any influence, but I think your virgl patch is an
excellent contribution and should go upstream.

Thanks again,

Elliot



Re: [PATCH] tcg/tci: fix logic error when registering helpers via FFI

2022-10-30 Thread Peter Maydell
On Sat, 29 Oct 2022 at 01:45, Icenowy Zheng  wrote:
>
> 在 2022-10-29星期六的 06:28 +1100,Richard Henderson写道:
> > Oh my.  I'm surprised any test cases at all worked.
> > Queued to tcg-next, with the declaration of j moved to the loop
> > itself:
> >
> > for (int j = 0; j < nargs; ++j)
>
> Ah I think this is a C99 feature. Is our C standard baseline high
> enough to use it?

Mmm, my instinctive reaction was that our style probably
doesn't permit that. But if you do
  git grep 'for (int'
we already use it quite a bit...

-- PMM



Re: [PATCH] Fix some typos in documentation and comments

2022-10-30 Thread Peter Maydell
On Sat, 29 Oct 2022 at 18:25, Stefan Weil  wrote:
>
> Most of them were found and fixed using codespell.
>
> Signed-off-by: Stefan Weil 
> ---
>
> My focus was fixing typos which are relevant for the generated documentation.
>
> codespell finds many more typos in source code, and adding it to the 
> continuous
> integration checks looks more and more like a good idea.
>
> Stefan
>
>
>  docs/devel/qapi-code-gen.rst| 2 +-
>  docs/devel/testing.rst  | 2 +-
>  docs/system/arm/cpu-features.rst| 2 +-
>  docs/system/loongarch/loongson3.rst | 2 +-
>  docs/tools/virtiofsd.rst| 2 +-
>  include/exec/memory.h   | 2 +-
>  qapi/qom.json   | 2 +-
>  qemu-options.hx | 8 
>  qga/qapi-schema.json| 2 +-
>  tests/qtest/libqtest.h  | 2 +-
>  10 files changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst
> index cd9b544376..c4c04bf755 100644
> --- a/docs/devel/qapi-code-gen.rst
> +++ b/docs/devel/qapi-code-gen.rst
> @@ -1313,7 +1313,7 @@ Removing "unreachable" stuff like events that can't be 
> triggered
>  anymore, optional return or event data members that can't be sent
>  anymore, and return or event data member (enumeration) values that
>  can't be sent anymore makes no difference to clients, except for
> -introspection.  The latter can conceivably confuse clients, so tread
> +introspection.  The latter can conceivably confuse clients, so treat
>  carefully.

No, the current text is correct: "tread carefully" means "be cautious".

> --- a/docs/system/loongarch/loongson3.rst
> +++ b/docs/system/loongarch/loongson3.rst
> @@ -41,7 +41,7 @@ can be accessed by following steps.
>
>$ qemu-system-loongarch64 -machine virt -m 4G -cpu la464-loongarch-cpu \
>-smp 1 -bios QEMU_EFI.fd -kernel vmlinuz.efi -initrd initrd.img \
> -  -append "root=/dev/ram rdinit=/sbin/init consol e=ttyS0,115200" \
> +  -append "root=/dev/ram rdinit=/sbin/init console e=ttyS0,115200" \
>--nographic

This is an error, but the fix is wrong -- the space between 'l' and 'e'
should just be deleted.


> @@ -5248,7 +5248,7 @@ SRST
>  read the colo-compare git log.
>
>  ``-object cryptodev-backend-builtin,id=id[,queues=queues]``
> -Creates a cryptodev backend which executes crypto opreation from
> +Creates a cryptodev backend which executes crypto operation from

Should be "operations"

>  the QEMU cipher APIS. The id parameter is a unique ID that will

This should be "APIs".

The other changes in the patch look good.

thanks
-- PMM



Re: [PATCH V5 2/4] intel-iommu: drop VTDBus

2022-10-30 Thread Yi Liu

On 2022/10/28 14:14, Jason Wang wrote:

We introduce VTDBus structure as an intermediate step for searching
the address space. This works well with SID based matching/lookup. But
when we want to support SID plus PASID based address space lookup,
this intermediate steps turns out to be a burden. So the patch simply
drops the VTDBus structure and use the PCIBus and devfn as the key for
the g_hash_table(). This simplifies the codes and the future PASID
extension.


just a nit.
in this way, all vtd_as'es are in the single hash table. will it become
a bottle-neck for searching? Especially with patch 4/4 in this serial.
sid has 16 bits, pasid has 20 bits, so at most there will be 2^36 entries
in the hash table.


To prevent being slower for past vtd_find_as_from_bus_num() callers, a
vtd_as cache indexed by the bus number is introduced to store the last
recent search result of a vtd_as belongs to a specific bus.

Reviewed-by: Peter Xu 
Signed-off-by: Jason Wang 
---
Changes since V2:
- use PCI_BUILD_BDF() instead of vtd_make_source_id()
- Tweak the comments above vtd_as_hash()
- use PCI_BUS_NUM() instead of open coding
- rename vtd_as to vtd_address_spaces
---
  hw/i386/intel_iommu.c | 234 +-
  include/hw/i386/intel_iommu.h |  11 +-
  2 files changed, 118 insertions(+), 127 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 271de995be..9fe5a222eb 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -61,6 +61,16 @@
  } 
\
  }
  
+/*

+ * PCI bus number (or SID) is not reliable since the device is usaully
+ * initalized before guest can configure the PCI bridge
+ * (SECONDARY_BUS_NUMBER).
+ */
+struct vtd_as_key {
+PCIBus *bus;
+uint8_t devfn;
+};
+
  static void vtd_address_space_refresh_all(IntelIOMMUState *s);
  static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n);
  
@@ -210,6 +220,27 @@ static guint vtd_uint64_hash(gconstpointer v)

  return (guint)*(const uint64_t *)v;
  }
  
+static gboolean vtd_as_equal(gconstpointer v1, gconstpointer v2)

+{
+const struct vtd_as_key *key1 = v1;
+const struct vtd_as_key *key2 = v2;
+
+return (key1->bus == key2->bus) && (key1->devfn == key2->devfn);
+}
+
+/*
+ * Note that we use pointer to PCIBus as the key, so hashing/shifting
+ * based on the pointer value is intended. Note that we deal with
+ * collisions through vtd_as_equal().
+ */
+static guint vtd_as_hash(gconstpointer v)
+{
+const struct vtd_as_key *key = v;
+guint value = (guint)(uintptr_t)key->bus;
+
+return (guint)(value << 8 | key->devfn);
+}
+
  static gboolean vtd_hash_remove_by_domain(gpointer key, gpointer value,
gpointer user_data)
  {
@@ -248,22 +279,14 @@ static gboolean vtd_hash_remove_by_page(gpointer key, 
gpointer value,
  static void vtd_reset_context_cache_locked(IntelIOMMUState *s)
  {
  VTDAddressSpace *vtd_as;
-VTDBus *vtd_bus;
-GHashTableIter bus_it;
-uint32_t devfn_it;
+GHashTableIter as_it;
  
  trace_vtd_context_cache_reset();
  
-g_hash_table_iter_init(&bus_it, s->vtd_as_by_busptr);

+g_hash_table_iter_init(&as_it, s->vtd_address_spaces);
  
-while (g_hash_table_iter_next (&bus_it, NULL, (void**)&vtd_bus)) {

-for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) {
-vtd_as = vtd_bus->dev_as[devfn_it];
-if (!vtd_as) {
-continue;
-}
-vtd_as->context_cache_entry.context_cache_gen = 0;
-}
+while (g_hash_table_iter_next (&as_it, NULL, (void**)&vtd_as)) {
+vtd_as->context_cache_entry.context_cache_gen = 0;
  }
  s->context_cache_gen = 1;
  }
@@ -993,32 +1016,6 @@ static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, 
uint32_t level)
  return slpte & rsvd_mask;
  }
  
-/* Find the VTD address space associated with a given bus number */

-static VTDBus *vtd_find_as_from_bus_num(IntelIOMMUState *s, uint8_t bus_num)
-{
-VTDBus *vtd_bus = s->vtd_as_by_bus_num[bus_num];
-GHashTableIter iter;
-
-if (vtd_bus) {
-return vtd_bus;
-}
-
-/*
- * Iterate over the registered buses to find the one which
- * currently holds this bus number and update the bus_num
- * lookup table.
- */
-g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
-while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
-if (pci_bus_num(vtd_bus->bus) == bus_num) {
-s->vtd_as_by_bus_num[bus_num] = vtd_bus;
-return vtd_bus;
-}
-}
-
-return NULL;
-}
-
  /* Given the @iova, get relevant @slptep. @slpte_level will be the last level
   * of the translation, can be used for deciding the size of large page.
   */
@@ -1632,24 +1629,13 @@ static bool vtd_switch_address_space(VTDAddressSpace 
*as)
  
  static void vtd_switch_address_space_all(IntelIOMMUS

[PATCH v2] Fix some typos in documentation and comments

2022-10-30 Thread Stefan Weil via
Most of them were found and fixed using codespell.

Signed-off-by: Stefan Weil 
---

v2: Fixes from Peter Maydell's comments

My focus was fixing typos which are relevant for the generated documentation.

codespell finds many more typos in source code, and adding it to the continuous
integration checks looks more and more like a good idea.

Stefan


 docs/devel/testing.rst  |  2 +-
 docs/system/arm/cpu-features.rst|  2 +-
 docs/system/loongarch/loongson3.rst |  2 +-
 docs/tools/virtiofsd.rst|  2 +-
 include/exec/memory.h   |  2 +-
 qapi/qom.json   |  2 +-
 qemu-options.hx | 10 +-
 qga/qapi-schema.json|  2 +-
 tests/qtest/libqtest.h  |  2 +-
 9 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index fbb98faabe..e10c47b5a7 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -99,7 +99,7 @@ successfully on various hosts. The following list shows some 
best practices:
 * If your test cases uses the blkdebug feature, use relative path to pass
   the config and image file paths in the command line as Windows absolute
   path contains the delimiter ":" which will confuse the blkdebug parser.
-* Use double quotes in your extra QEMU commmand line in your test cases
+* Use double quotes in your extra QEMU command line in your test cases
   instead of single quotes, as Windows does not drop single quotes when
   passing the command line to QEMU.
 * Windows opens a file in text mode by default, while a POSIX compliant
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index c2c01ec7d2..00c444042f 100644
--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -433,7 +433,7 @@ additional constraints on the set of vector lengths 
supported by SME.
 SME User-mode Default Vector Length Property
 
 
-For qemu-aarch64, the cpu propery ``sme-default-vector-length=N`` is
+For qemu-aarch64, the cpu property ``sme-default-vector-length=N`` is
 defined to mirror the Linux kernel parameter file
 ``/proc/sys/abi/sme_default_vector_length``.  The default length, ``N``,
 is in units of bytes and must be between 16 and 8192.
diff --git a/docs/system/loongarch/loongson3.rst 
b/docs/system/loongarch/loongson3.rst
index 1bdab44e27..68113b6f5e 100644
--- a/docs/system/loongarch/loongson3.rst
+++ b/docs/system/loongarch/loongson3.rst
@@ -41,7 +41,7 @@ can be accessed by following steps.
 
   $ qemu-system-loongarch64 -machine virt -m 4G -cpu la464-loongarch-cpu \
   -smp 1 -bios QEMU_EFI.fd -kernel vmlinuz.efi -initrd initrd.img \
-  -append "root=/dev/ram rdinit=/sbin/init consol e=ttyS0,115200" \
+  -append "root=/dev/ram rdinit=/sbin/init console=ttyS0,115200" \
   --nographic
 
 Note: The running speed may be a little slow, as the performance of our
diff --git a/docs/tools/virtiofsd.rst b/docs/tools/virtiofsd.rst
index 5f5ac9dd56..995a754a7b 100644
--- a/docs/tools/virtiofsd.rst
+++ b/docs/tools/virtiofsd.rst
@@ -232,7 +232,7 @@ e.g.:
 
   ``:ok:server::security.:``
 
-  will pass 'securty.' xattr's in listxattr from the server
+  will pass 'security.' xattr's in listxattr from the server
   and ignore following rules.
 
   ``:ok:all:::``
diff --git a/include/exec/memory.h b/include/exec/memory.h
index bfb1de8eea..a751c111bd 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1970,7 +1970,7 @@ void memory_region_clear_dirty_bitmap(MemoryRegion *mr, 
hwaddr start,
  * querying the same page multiple times, which is especially useful for
  * display updates where the scanlines often are not page aligned.
  *
- * The dirty bitmap region which gets copyed into the snapshot (and
+ * The dirty bitmap region which gets copied into the snapshot (and
  * cleared afterwards) can be larger than requested.  The boundaries
  * are rounded up/down so complete bitmap longs (covering 64 pages on
  * 64bit hosts) can be copied over into the bitmap snapshot.  Which
diff --git a/qapi/qom.json b/qapi/qom.json
index 80dd419b39..216b56a4e6 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -586,7 +586,7 @@
 #
 # @size: size of the memory region in bytes
 #
-# @x-use-canonical-path-for-ramblock-id: if true, the canoncial path is used
+# @x-use-canonical-path-for-ramblock-id: if true, the canonical path is used
 #for ramblock-id. Disable this for 4.0
 #machine types or older to allow
 #migration with newer QEMU versions.
diff --git a/qemu-options.hx b/qemu-options.hx
index eb38e5dc40..1141dc5e58 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1051,7 +1051,7 @@ SRST
 details on the external interface.
 
 ``-device isa-ipmi-kcs,bmc=id[,ioport=val][,irq=val]``
-Add a KCS IPMI interafce on the ISA bus. This also add

  1   2   >