[PATCH] tests/qtest/libqos/e1000e: Use IVAR shift definitions

2022-11-04 Thread Akihiko Odaki
There were still some constants defined in e1000_regs.h.

Signed-off-by: Akihiko Odaki 
---
 tests/qtest/libqos/e1000e.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/qtest/libqos/e1000e.c b/tests/qtest/libqos/e1000e.c
index 178d61d04f..21683dd0fb 100644
--- a/tests/qtest/libqos/e1000e.c
+++ b/tests/qtest/libqos/e1000e.c
@@ -30,9 +30,9 @@
 #include "e1000e.h"
 
 #define E1000E_IVAR_TEST_CFG \
-(E1000E_RX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID | \
- ((E1000E_TX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << 8)| \
- ((E1000E_OTHER_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << 16) | \
+(((E1000E_RX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << 
E1000_IVAR_RXQ0_SHIFT) | \
+ ((E1000E_TX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << 
E1000_IVAR_TXQ0_SHIFT) | \
+ ((E1000E_OTHER_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << 
E1000_IVAR_OTHER_SHIFT) | \
  E1000_IVAR_TX_INT_EVERY_WB)
 
 #define E1000E_RING_LEN (0x1000)
-- 
2.38.1




Re: [PATCH v4 1/2] target/loongarch: Adjust the layout of hardware flags bit fields

2022-11-04 Thread Richard Henderson

On 11/5/22 13:10, Rui Wang wrote:

Suggested-by: Richard Henderson
Signed-off-by: Rui Wang
---
  target/loongarch/cpu.h| 27 ---
  .../insn_trans/trans_privileged.c.inc |  4 +--
  target/loongarch/tlb_helper.c |  4 +--
  target/loongarch/translate.c  |  7 -
  target/loongarch/translate.h  |  3 ++-
  5 files changed, 29 insertions(+), 16 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v4 2/2] target/loongarch: Fix emulation of float-point disable exception

2022-11-04 Thread Richard Henderson

On 11/5/22 13:10, Rui Wang wrote:

We need to emulate it to generate a floating point disable exception
when CSR.EUEN.FPE is zero.

Signed-off-by: Rui Wang
---
  target/loongarch/cpu.c|  2 ++
  target/loongarch/cpu.h|  2 ++
  .../loongarch/insn_trans/trans_farith.c.inc   | 30 
  target/loongarch/insn_trans/trans_fcmp.c.inc  | 11 --
  .../loongarch/insn_trans/trans_fmemory.c.inc  | 34 +++
  target/loongarch/insn_trans/trans_fmov.c.inc  | 29 ++--
  6 files changed, 97 insertions(+), 11 deletions(-)


Reviewed-by: Richard Henderson 

r~



[PULL v3 6/7] target/loongarch: Add exception subcode

2022-11-04 Thread Song Gao
We need subcodes to distinguish the same excode cs->exception_indexs,
such as EXCCODE_ADEF/EXCCODE_ADEM.

Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
Message-ID: <20221101073210.3934280-1-gaos...@loongson.cn>
---
 target/loongarch/cpu.c |  7 +++--
 target/loongarch/cpu.h | 58 ++
 2 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 49393d95d8..b28aaed5ba 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -220,7 +220,10 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
 env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA,
   PC, (env->pc >> 2));
 } else {
-env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, cause);
+env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE,
+EXCODE_MCODE(cause));
+env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ESUBCODE,
+EXCODE_SUBCODE(cause));
 env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV,
FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV));
 env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE,
@@ -257,7 +260,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
 env->pc = env->CSR_TLBRENTRY;
 } else {
 env->pc = env->CSR_EENTRY;
-env->pc += cause * vec_size;
+env->pc += EXCODE_MCODE(cause) * vec_size;
 }
 qemu_log_mask(CPU_LOG_INT,
   "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index dce999aaac..dbce176564 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -75,33 +75,37 @@ FIELD(FCSR0, CAUSE, 24, 5)
 #define FP_DIV0   8
 #define FP_INVALID16
 
-#define  EXCCODE_EXTERNAL_INT   64   /* plus external interrupt number */
-#define  EXCCODE_INT 0
-#define  EXCCODE_PIL 1
-#define  EXCCODE_PIS 2
-#define  EXCCODE_PIF 3
-#define  EXCCODE_PME 4
-#define  EXCCODE_PNR 5
-#define  EXCCODE_PNX 6
-#define  EXCCODE_PPI 7
-#define  EXCCODE_ADEF8 /* Different exception subcode */
-#define  EXCCODE_ADEM8
-#define  EXCCODE_ALE 9
-#define  EXCCODE_BCE 10
-#define  EXCCODE_SYS 11
-#define  EXCCODE_BRK 12
-#define  EXCCODE_INE 13
-#define  EXCCODE_IPE 14
-#define  EXCCODE_FPD 15
-#define  EXCCODE_SXD 16
-#define  EXCCODE_ASXD17
-#define  EXCCODE_FPE 18 /* Different exception subcode */
-#define  EXCCODE_VFPE18
-#define  EXCCODE_WPEF19 /* Different exception subcode */
-#define  EXCCODE_WPEM19
-#define  EXCCODE_BTD 20
-#define  EXCCODE_BTE 21
-#define  EXCCODE_DBP 26 /* Reserved subcode used for debug */
+#define EXCODE(code, subcode) ( ((subcode) << 6) | (code) )
+#define EXCODE_MCODE(code)( (code) & 0x3f )
+#define EXCODE_SUBCODE(code)  ( (code) >> 6 )
+
+#define  EXCCODE_EXTERNAL_INT64   /* plus external interrupt number */
+#define  EXCCODE_INT EXCODE(0, 0)
+#define  EXCCODE_PIL EXCODE(1, 0)
+#define  EXCCODE_PIS EXCODE(2, 0)
+#define  EXCCODE_PIF EXCODE(3, 0)
+#define  EXCCODE_PME EXCODE(4, 0)
+#define  EXCCODE_PNR EXCODE(5, 0)
+#define  EXCCODE_PNX EXCODE(6, 0)
+#define  EXCCODE_PPI EXCODE(7, 0)
+#define  EXCCODE_ADEFEXCODE(8, 0) /* Different exception 
subcode */
+#define  EXCCODE_ADEMEXCODE(8, 1)
+#define  EXCCODE_ALE EXCODE(9, 0)
+#define  EXCCODE_BCE EXCODE(10, 0)
+#define  EXCCODE_SYS EXCODE(11, 0)
+#define  EXCCODE_BRK EXCODE(12, 0)
+#define  EXCCODE_INE EXCODE(13, 0)
+#define  EXCCODE_IPE EXCODE(14, 0)
+#define  EXCCODE_FPD EXCODE(15, 0)
+#define  EXCCODE_SXD EXCODE(16, 0)
+#define  EXCCODE_ASXDEXCODE(17, 0)
+#define  EXCCODE_FPE EXCODE(18, 0) /* Different exception 
subcode */
+#define  EXCCODE_VFPEEXCODE(18, 1)
+#define  EXCCODE_WPEFEXCODE(19, 0) /* Different exception 
subcode */
+#define  EXCCODE_WPEMEXCODE(19, 1)
+#define  EXCCODE_BTD EXCODE(20, 0)
+#define  EXCCODE_BTE EXCODE(21, 0)
+#define  EXCCODE_DBP EXCODE(26, 0) /* Reserved subcode used 
for debug */
 
 /* cpucfg[0] bits */
 FIELD(CPUCFG0,

[PULL v3 7/7] target/loongarch: Fix raise_mmu_exception() set wrong exception_index

2022-11-04 Thread Song Gao
When the address is invalid address, We should set exception_index
according to MMUAccessType, and EXCCODE_ADEF need't update badinstr.
Otherwise, The system enters an infinite loop. e.g:
run test.c on system mode
test.c:
#include

void (*func)(int *);

int main()
{
int i = 8;
void *ptr = (void *)0x4000;
func = ptr;
func(&i);
return 0;
}

Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
Message-ID: <20221101073210.3934280-2-gaos...@loongson.cn>
---
 target/loongarch/cpu.c| 1 +
 target/loongarch/tlb_helper.c | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index b28aaed5ba..1512664214 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -177,6 +177,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
 }
 QEMU_FALLTHROUGH;
 case EXCCODE_PIF:
+case EXCCODE_ADEF:
 cause = cs->exception_index;
 update_badinstr = 0;
 break;
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index 610b6d123c..d2f8fb0c60 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -229,7 +229,8 @@ static void raise_mmu_exception(CPULoongArchState *env, 
target_ulong address,
 switch (tlb_error) {
 default:
 case TLBRET_BADADDR:
-cs->exception_index = EXCCODE_ADEM;
+cs->exception_index = access_type == MMU_INST_FETCH
+  ? EXCCODE_ADEF : EXCCODE_ADEM;
 break;
 case TLBRET_NOMATCH:
 /* No TLB match for a mapped address */
@@ -643,7 +644,7 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, 
int size,
 CPULoongArchState *env = &cpu->env;
 hwaddr physical;
 int prot;
-int ret = TLBRET_BADADDR;
+int ret;
 
 /* Data access */
 ret = get_physical_address(env, &physical, &prot, address,
-- 
2.31.1




[PULL v3 2/7] hw/intc: Fix LoongArch extioi coreisr accessing

2022-11-04 Thread Song Gao
From: Xiaojuan Yang 

1. When cpu read or write extioi COREISR reg, it should access
the reg belonged to itself, so the cpu index of 's->coreisr'
is current cpu number. Using MemTxAttrs' requester_id to get
the cpu index.
2. it need not to mask 0x1f when calculate the coreisr array index.

Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
Message-Id: <20221021015307.2570844-3-yangxiaoj...@loongson.cn>
Signed-off-by: Song Gao 
---
 hw/intc/loongarch_extioi.c  | 10 ++
 target/loongarch/iocsr_helper.c | 19 +++
 2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
index 72f4b0cde5..4b8ec3f28a 100644
--- a/hw/intc/loongarch_extioi.c
+++ b/hw/intc/loongarch_extioi.c
@@ -93,8 +93,9 @@ static MemTxResult extioi_readw(void *opaque, hwaddr addr, 
uint64_t *data,
 *data = s->bounce[index];
 break;
 case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
-index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2;
-cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
+index = (offset - EXTIOI_COREISR_START) >> 2;
+/* using attrs to get current cpu index */
+cpu = attrs.requester_id;
 *data = s->coreisr[cpu][index];
 break;
 case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1:
@@ -185,8 +186,9 @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr,
 s->bounce[index] = val;
 break;
 case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
-index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2;
-cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
+index = (offset - EXTIOI_COREISR_START) >> 2;
+/* using attrs to get current cpu index */
+cpu = attrs.requester_id;
 old_data = s->coreisr[cpu][index];
 s->coreisr[cpu][index] = old_data & ~val;
 /* write 1 to clear interrrupt */
diff --git a/target/loongarch/iocsr_helper.c b/target/loongarch/iocsr_helper.c
index 0e9c537dc7..505853e17b 100644
--- a/target/loongarch/iocsr_helper.c
+++ b/target/loongarch/iocsr_helper.c
@@ -14,54 +14,57 @@
 #include "exec/cpu_ldst.h"
 #include "tcg/tcg-ldst.h"
 
+#define GET_MEMTXATTRS(cas) \
+((MemTxAttrs){.requester_id = env_cpu(cas)->cpu_index})
+
 uint64_t helper_iocsrrd_b(CPULoongArchState *env, target_ulong r_addr)
 {
 return address_space_ldub(&env->address_space_iocsr, r_addr,
-  MEMTXATTRS_UNSPECIFIED, NULL);
+  GET_MEMTXATTRS(env), NULL);
 }
 
 uint64_t helper_iocsrrd_h(CPULoongArchState *env, target_ulong r_addr)
 {
 return address_space_lduw(&env->address_space_iocsr, r_addr,
-  MEMTXATTRS_UNSPECIFIED, NULL);
+  GET_MEMTXATTRS(env), NULL);
 }
 
 uint64_t helper_iocsrrd_w(CPULoongArchState *env, target_ulong r_addr)
 {
 return address_space_ldl(&env->address_space_iocsr, r_addr,
- MEMTXATTRS_UNSPECIFIED, NULL);
+ GET_MEMTXATTRS(env), NULL);
 }
 
 uint64_t helper_iocsrrd_d(CPULoongArchState *env, target_ulong r_addr)
 {
 return address_space_ldq(&env->address_space_iocsr, r_addr,
- MEMTXATTRS_UNSPECIFIED, NULL);
+ GET_MEMTXATTRS(env), NULL);
 }
 
 void helper_iocsrwr_b(CPULoongArchState *env, target_ulong w_addr,
   target_ulong val)
 {
 address_space_stb(&env->address_space_iocsr, w_addr,
-  val, MEMTXATTRS_UNSPECIFIED, NULL);
+  val, GET_MEMTXATTRS(env), NULL);
 }
 
 void helper_iocsrwr_h(CPULoongArchState *env, target_ulong w_addr,
   target_ulong val)
 {
 address_space_stw(&env->address_space_iocsr, w_addr,
-  val, MEMTXATTRS_UNSPECIFIED, NULL);
+  val, GET_MEMTXATTRS(env), NULL);
 }
 
 void helper_iocsrwr_w(CPULoongArchState *env, target_ulong w_addr,
   target_ulong val)
 {
 address_space_stl(&env->address_space_iocsr, w_addr,
-  val, MEMTXATTRS_UNSPECIFIED, NULL);
+  val, GET_MEMTXATTRS(env), NULL);
 }
 
 void helper_iocsrwr_d(CPULoongArchState *env, target_ulong w_addr,
   target_ulong val)
 {
 address_space_stq(&env->address_space_iocsr, w_addr,
-  val, MEMTXATTRS_UNSPECIFIED, NULL);
+  val, GET_MEMTXATTRS(env), NULL);
 }
-- 
2.31.1




[PULL v3 3/7] hw/loongarch: Load FDT table into dram memory space

2022-11-04 Thread Song Gao
From: Xiaojuan Yang 

Load FDT table into dram memory space, and the addr is 2 MiB.
Since lowmem region starts from 0, FDT base address is located
at 2 MiB to avoid NULL pointer access.

Signed-off-by: Xiaojuan Yang 
Acked-by: Song Gao 
Message-Id: <20221028014007.2718352-2-yangxiaoj...@loongson.cn>
Signed-off-by: Song Gao 
---
 hw/loongarch/virt.c | 18 +++---
 include/hw/loongarch/virt.h |  3 ---
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 4b595a9ea4..50e9829a94 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -159,7 +159,6 @@ static void fdt_add_pcie_node(const LoongArchMachineState 
*lams)
  1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
  2, base_mmio, 2, size_mmio);
 g_free(nodename);
-qemu_fdt_dumpdtb(ms->fdt, lams->fdt_size);
 }
 
 static void fdt_add_irqchip_node(LoongArchMachineState *lams)
@@ -656,6 +655,7 @@ static void loongarch_init(MachineState *machine)
 MemoryRegion *address_space_mem = get_system_memory();
 LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
 int i;
+hwaddr fdt_base;
 
 if (!cpu_model) {
 cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
@@ -760,12 +760,16 @@ static void loongarch_init(MachineState *machine)
 lams->machine_done.notify = virt_machine_done;
 qemu_add_machine_init_done_notifier(&lams->machine_done);
 fdt_add_pcie_node(lams);
-
-/* load fdt */
-MemoryRegion *fdt_rom = g_new(MemoryRegion, 1);
-memory_region_init_rom(fdt_rom, NULL, "fdt", VIRT_FDT_SIZE, &error_fatal);
-memory_region_add_subregion(get_system_memory(), VIRT_FDT_BASE, fdt_rom);
-rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, VIRT_FDT_BASE);
+/*
+ * Since lowmem region starts from 0, FDT base address is located
+ * at 2 MiB to avoid NULL pointer access.
+ *
+ * Put the FDT into the memory map as a ROM image: this will ensure
+ * the FDT is copied again upon reset, even if addr points into RAM.
+ */
+fdt_base = 2 * MiB;
+qemu_fdt_dumpdtb(machine->fdt, lams->fdt_size);
+rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, fdt_base);
 }
 
 bool loongarch_is_acpi_enabled(LoongArchMachineState *lams)
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 09f1c88ee5..45c383f5a7 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -28,9 +28,6 @@
 #define VIRT_GED_MEM_ADDR   (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN)
 #define VIRT_GED_REG_ADDR   (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)
 
-#define VIRT_FDT_BASE   0x1c40
-#define VIRT_FDT_SIZE   0x10
-
 struct LoongArchMachineState {
 /*< private >*/
 MachineState parent_obj;
-- 
2.31.1




[PULL v3 4/7] hw/loongarch: Improve fdt for LoongArch virt machine

2022-11-04 Thread Song Gao
From: Xiaojuan Yang 

Add new items into LoongArch FDT, including rtc and uart info.

Signed-off-by: Xiaojuan Yang 
Reviewed-by: Song Gao 
Message-Id: <20221028014007.2718352-3-yangxiaoj...@loongson.cn>
Signed-off-by: Song Gao 
---
 hw/loongarch/virt.c| 31 +++
 include/hw/pci-host/ls7a.h |  1 +
 2 files changed, 32 insertions(+)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 50e9829a94..afc1c8ac77 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -42,6 +42,35 @@
 #include "hw/display/ramfb.h"
 #include "hw/mem/pc-dimm.h"
 
+static void fdt_add_rtc_node(LoongArchMachineState *lams)
+{
+char *nodename;
+hwaddr base = VIRT_RTC_REG_BASE;
+hwaddr size = VIRT_RTC_LEN;
+MachineState *ms = MACHINE(lams);
+
+nodename = g_strdup_printf("/rtc@%" PRIx64, base);
+qemu_fdt_add_subnode(ms->fdt, nodename);
+qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", 
"loongson,ls7a-rtc");
+qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 0x0, base, size);
+g_free(nodename);
+}
+
+static void fdt_add_uart_node(LoongArchMachineState *lams)
+{
+char *nodename;
+hwaddr base = VIRT_UART_BASE;
+hwaddr size = VIRT_UART_SIZE;
+MachineState *ms = MACHINE(lams);
+
+nodename = g_strdup_printf("/serial@%" PRIx64, base);
+qemu_fdt_add_subnode(ms->fdt, nodename);
+qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a");
+qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 1);
+g_free(nodename);
+}
+
 static void create_fdt(LoongArchMachineState *lams)
 {
 MachineState *ms = MACHINE(lams);
@@ -422,6 +451,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, 
LoongArchMachineState *
qdev_get_gpio_in(pch_pic,
 VIRT_UART_IRQ - PCH_PIC_IRQ_OFFSET),
115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
+fdt_add_uart_node(lams);
 
 /* Network init */
 for (i = 0; i < nb_nics; i++) {
@@ -442,6 +472,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, 
LoongArchMachineState *
 sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
  qdev_get_gpio_in(pch_pic,
  VIRT_RTC_IRQ - PCH_PIC_IRQ_OFFSET));
+fdt_add_rtc_node(lams);
 
 pm_mem = g_new(MemoryRegion, 1);
 memory_region_init_io(pm_mem, NULL, &loongarch_virt_pm_ops,
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
index 9bd875ca8b..df7fa55a30 100644
--- a/include/hw/pci-host/ls7a.h
+++ b/include/hw/pci-host/ls7a.h
@@ -37,6 +37,7 @@
 #define VIRT_PCI_IRQS48
 #define VIRT_UART_IRQ(PCH_PIC_IRQ_OFFSET + 2)
 #define VIRT_UART_BASE   0x1fe001e0
+#define VIRT_UART_SIZE   0X100
 #define VIRT_RTC_IRQ (PCH_PIC_IRQ_OFFSET + 3)
 #define VIRT_MISC_REG_BASE   (VIRT_PCH_REG_BASE + 0x0008)
 #define VIRT_RTC_REG_BASE(VIRT_MISC_REG_BASE + 0x00050100)
-- 
2.31.1




[PULL v3 1/7] hw/intc: Convert the memops to with_attrs in LoongArch extioi

2022-11-04 Thread Song Gao
From: Xiaojuan Yang 

Converting the MemoryRegionOps read/write handlers to
with_attrs in LoongArch extioi emulation.

Signed-off-by: Xiaojuan Yang 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20221021015307.2570844-2-yangxiaoj...@loongson.cn>
Signed-off-by: Song Gao 
---
 hw/intc/loongarch_extioi.c | 31 +--
 hw/intc/trace-events   |  3 +--
 2 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
index 22803969bc..72f4b0cde5 100644
--- a/hw/intc/loongarch_extioi.c
+++ b/hw/intc/loongarch_extioi.c
@@ -68,44 +68,45 @@ static void extioi_setirq(void *opaque, int irq, int level)
 extioi_update_irq(s, irq, level);
 }
 
-static uint64_t extioi_readw(void *opaque, hwaddr addr, unsigned size)
+static MemTxResult extioi_readw(void *opaque, hwaddr addr, uint64_t *data,
+unsigned size, MemTxAttrs attrs)
 {
 LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
 unsigned long offset = addr & 0x;
-uint32_t index, cpu, ret = 0;
+uint32_t index, cpu;
 
 switch (offset) {
 case EXTIOI_NODETYPE_START ... EXTIOI_NODETYPE_END - 1:
 index = (offset - EXTIOI_NODETYPE_START) >> 2;
-ret = s->nodetype[index];
+*data = s->nodetype[index];
 break;
 case EXTIOI_IPMAP_START ... EXTIOI_IPMAP_END - 1:
 index = (offset - EXTIOI_IPMAP_START) >> 2;
-ret = s->ipmap[index];
+*data = s->ipmap[index];
 break;
 case EXTIOI_ENABLE_START ... EXTIOI_ENABLE_END - 1:
 index = (offset - EXTIOI_ENABLE_START) >> 2;
-ret = s->enable[index];
+*data = s->enable[index];
 break;
 case EXTIOI_BOUNCE_START ... EXTIOI_BOUNCE_END - 1:
 index = (offset - EXTIOI_BOUNCE_START) >> 2;
-ret = s->bounce[index];
+*data = s->bounce[index];
 break;
 case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
 index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2;
 cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
-ret = s->coreisr[cpu][index];
+*data = s->coreisr[cpu][index];
 break;
 case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1:
 index = (offset - EXTIOI_COREMAP_START) >> 2;
-ret = s->coremap[index];
+*data = s->coremap[index];
 break;
 default:
 break;
 }
 
-trace_loongarch_extioi_readw(addr, ret);
-return ret;
+trace_loongarch_extioi_readw(addr, *data);
+return MEMTX_OK;
 }
 
 static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\
@@ -127,8 +128,9 @@ static inline void extioi_enable_irq(LoongArchExtIOI *s, 
int index,\
 }
 }
 
-static void extioi_writew(void *opaque, hwaddr addr,
-  uint64_t val, unsigned size)
+static MemTxResult extioi_writew(void *opaque, hwaddr addr,
+  uint64_t val, unsigned size,
+  MemTxAttrs attrs)
 {
 LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
 int i, cpu, index, old_data, irq;
@@ -231,11 +233,12 @@ static void extioi_writew(void *opaque, hwaddr addr,
 default:
 break;
 }
+return MEMTX_OK;
 }
 
 static const MemoryRegionOps extioi_ops = {
-.read = extioi_readw,
-.write = extioi_writew,
+.read_with_attrs = extioi_readw,
+.write_with_attrs = extioi_writew,
 .impl.min_access_size = 4,
 .impl.max_access_size = 4,
 .valid.min_access_size = 4,
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 0a90c1cdec..6fbc2045e6 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -306,6 +306,5 @@ loongarch_msi_set_irq(int irq_num) "set msi irq %d"
 
 # loongarch_extioi.c
 loongarch_extioi_setirq(int irq, int level) "set extirq irq %d level %d"
-loongarch_extioi_readw(uint64_t addr, uint32_t val) "addr: 0x%"PRIx64 "val: 
0x%x"
+loongarch_extioi_readw(uint64_t addr, uint64_t val) "addr: 0x%"PRIx64 "val: 
0x%" PRIx64
 loongarch_extioi_writew(uint64_t addr, uint64_t val) "addr: 0x%"PRIx64 "val: 
0x%" PRIx64
-
-- 
2.31.1




[PULL v3 0/7] loongarch-to-apply queue

2022-11-04 Thread Song Gao
The following changes since commit ece5f8374d0416a339f0c0a9399faa2c42d4ad6f:

  Merge tag 'linux-user-for-7.2-pull-request' of 
https://gitlab.com/laurent_vivier/qemu into staging (2022-11-03 10:55:05 -0400)

are available in the Git repository at:

  https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20221105

for you to fetch changes up to 6a284614d485f36af6467ce0925df0042aca7a1f:

  target/loongarch: Fix raise_mmu_exception() set wrong exception_index 
(2022-11-05 10:52:19 +0800)


pull-loongarch-20221105

V3:
- According to Richard's latest comments, drop patch 8, 9.

v2:
 - fix win32/win64 complie error;
 - Add Rui Wang' patches.


Song Gao (2):
  target/loongarch: Add exception subcode
  target/loongarch: Fix raise_mmu_exception() set wrong exception_index

Xiaojuan Yang (5):
  hw/intc: Convert the memops to with_attrs in LoongArch extioi
  hw/intc: Fix LoongArch extioi coreisr accessing
  hw/loongarch: Load FDT table into dram memory space
  hw/loongarch: Improve fdt for LoongArch virt machine
  hw/loongarch: Add TPM device for LoongArch virt machine

 hw/intc/loongarch_extioi.c  | 41 -
 hw/intc/trace-events|  3 +--
 hw/loongarch/acpi-build.c   | 51 +++-
 hw/loongarch/virt.c | 53 -
 include/hw/loongarch/virt.h |  3 ---
 include/hw/pci-host/ls7a.h  |  1 +
 target/loongarch/cpu.c  |  8 --
 target/loongarch/cpu.h  | 58 ++---
 target/loongarch/iocsr_helper.c | 19 --
 target/loongarch/tlb_helper.c   |  5 ++--
 10 files changed, 172 insertions(+), 70 deletions(-)




[PULL v3 5/7] hw/loongarch: Add TPM device for LoongArch virt machine

2022-11-04 Thread Song Gao
From: Xiaojuan Yang 

Add TPM device for LoongArch virt machine, including
establish TPM acpi info and add TYPE_TPM_TIS_SYSBUS
to dynamic_sysbus_devices list.

Signed-off-by: Xiaojuan Yang 
Reviewed-by: Song Gao 
Message-Id: <20221028014007.2718352-4-yangxiaoj...@loongson.cn>
Signed-off-by: Song Gao 
---
 hw/loongarch/acpi-build.c | 51 ++-
 hw/loongarch/virt.c   |  4 +++
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 378a6d9d38..68dfb9f88a 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -31,6 +31,9 @@
 
 #include "hw/acpi/generic_event_device.h"
 #include "hw/pci-host/gpex.h"
+#include "sysemu/tpm.h"
+#include "hw/platform-bus.h"
+#include "hw/acpi/aml-build.h"
 
 #define ACPI_BUILD_ALIGN_SIZE 0x1000
 #define ACPI_BUILD_TABLE_SIZE 0x2
@@ -275,6 +278,41 @@ static void build_pci_device_aml(Aml *scope, 
LoongArchMachineState *lams)
 acpi_dsdt_add_gpex(scope, &cfg);
 }
 
+#ifdef CONFIG_TPM
+static void acpi_dsdt_add_tpm(Aml *scope, LoongArchMachineState *vms)
+{
+PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
+hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS;
+SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find());
+MemoryRegion *sbdev_mr;
+hwaddr tpm_base;
+
+if (!sbdev) {
+return;
+}
+
+tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+assert(tpm_base != -1);
+
+tpm_base += pbus_base;
+
+sbdev_mr = sysbus_mmio_get_region(sbdev, 0);
+
+Aml *dev = aml_device("TPM0");
+aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
+aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device")));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs,
+   aml_memory32_fixed(tpm_base,
+  (uint32_t)memory_region_size(sbdev_mr),
+  AML_READ_WRITE));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+#endif
+
 /* build DSDT */
 static void
 build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
@@ -289,7 +327,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
MachineState *machine)
 build_uart_device_aml(dsdt);
 build_pci_device_aml(dsdt, lams);
 build_la_ged_aml(dsdt, machine);
-
+#ifdef CONFIG_TPM
+acpi_dsdt_add_tpm(dsdt, lams);
+#endif
 /* System State Package */
 scope = aml_scope("\\");
 pkg = aml_package(4);
@@ -359,6 +399,15 @@ static void acpi_build(AcpiBuildTables *tables, 
MachineState *machine)
lams->oem_table_id);
 }
 
+#ifdef CONFIG_TPM
+/* TPM info */
+if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) {
+acpi_add_table(table_offsets, tables_blob);
+build_tpm2(tables_blob, tables->linker,
+   tables->tcpalog, lams->oem_id,
+   lams->oem_table_id);
+}
+#endif
 /* Add tables supplied by user (if any) */
 for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
 unsigned len = acpi_table_len(u);
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index afc1c8ac77..5e4c2790bf 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -41,6 +41,7 @@
 #include "hw/platform-bus.h"
 #include "hw/display/ramfb.h"
 #include "hw/mem/pc-dimm.h"
+#include "sysemu/tpm.h"
 
 static void fdt_add_rtc_node(LoongArchMachineState *lams)
 {
@@ -960,6 +961,9 @@ static void loongarch_class_init(ObjectClass *oc, void 
*data)
 object_class_property_set_description(oc, "acpi",
 "Enable ACPI");
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
+#ifdef CONFIG_TPM
+machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
+#endif
 }
 
 static const TypeInfo loongarch_machine_types[] = {
-- 
2.31.1




[PULL v3 0/7] loongarch-to-apply queue

2022-11-04 Thread Song Gao
The following changes since commit ece5f8374d0416a339f0c0a9399faa2c42d4ad6f:

  Merge tag 'linux-user-for-7.2-pull-request' of 
https://gitlab.com/laurent_vivier/qemu into staging (2022-11-03 10:55:05 -0400)

are available in the Git repository at:

  https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20221105

for you to fetch changes up to 6a284614d485f36af6467ce0925df0042aca7a1f:

  target/loongarch: Fix raise_mmu_exception() set wrong exception_index 
(2022-11-05 10:52:19 +0800)


pull-loongarch-20221105

V3:
- According to Richard's latest comments, drop patch 8, 9.

v2:
 - fix win32/win64 complie error;
 - Add Rui Wang' patches.


Song Gao (2):
  target/loongarch: Add exception subcode
  target/loongarch: Fix raise_mmu_exception() set wrong exception_index

Xiaojuan Yang (5):
  hw/intc: Convert the memops to with_attrs in LoongArch extioi
  hw/intc: Fix LoongArch extioi coreisr accessing
  hw/loongarch: Load FDT table into dram memory space
  hw/loongarch: Improve fdt for LoongArch virt machine
  hw/loongarch: Add TPM device for LoongArch virt machine

 hw/intc/loongarch_extioi.c  | 41 -
 hw/intc/trace-events|  3 +--
 hw/loongarch/acpi-build.c   | 51 +++-
 hw/loongarch/virt.c | 53 -
 include/hw/loongarch/virt.h |  3 ---
 include/hw/pci-host/ls7a.h  |  1 +
 target/loongarch/cpu.c  |  8 --
 target/loongarch/cpu.h  | 58 ++---
 target/loongarch/iocsr_helper.c | 19 --
 target/loongarch/tlb_helper.c   |  5 ++--
 10 files changed, 172 insertions(+), 70 deletions(-)




RE: [PATCH] gdb-xml: Fix size of EFER register on i386 architecture when debugged by GDB

2022-11-04 Thread 伊藤 太清
Thanks for the reply. Below are details about the patch.

1. A bug

GDB cannot print the x87 FPU registers correctly when the GDB is debugging
an OS working on qemu-system-i386.

1.1 My host environment

Ubuntu 22.04.1 LTS

1.2 Reproduction of the bug

The following 3 files are needed to reproduce the bug.

* test_os.s
* test_os.ld
* Makefile

And the following 2 tools, too.

* build-essential
* gdb

The contents of the above files are below.

-- Begin of test_os.s --

.code16
.text
main:
fninit  # Initialize the FPU
fld1# Push 1.0
fldl2t  # Push log 2 10
fldl2e # Push log 2 e
fldpi   # Push pi
fldlg2 # Push log 10 2
fldln2 # Push log e 2
fldz # Push 0.0
loop:
hlt
jmp loop

-- End of test_os.s --

-- Begin of test_os.ld --

OUTPUT_FORMAT("binary");

BASE = 0x7c00;

SECTIONS
{
. = BASE;
.text :
{
   test_os.o(.text)
}
. = BASE;
. += 0x0200;
. -= 0x0002;
.boot_sector_sign :
{
   BYTE(0x55);
   BYTE(0xaa);
}
/DISCARD/ :
{
   *(.eh_frame)
   *(.note.gnu.property)
}
}

-- End of test_os.ld --

-- Begin of Makefile --

TEST_OS_NAME = test_o
TEST_OS_NAME = test_os
TEST_OS_ASM = $(TEST_OS_NAME).s
TEST_OS_IMG = $(TEST_OS_NAME).img
TEST_OS_LNK = $(TEST_OS_NAME).ld
TEST_OS_MAP = $(TEST_OS_NAME).map
TEST_OS_OBJ = $(TEST_OS_NAME).o

all: $(TEST_OS_IMG)

test: $(TEST_OS_IMG)
(qemu-system-i386 -boot order=a \
-drive file=$<,format=raw,if=floppy \
-S -gdb tcp::2159 -vnc localhost:0 &) && \
gdb

$(TEST_OS_IMG): $(TEST_OS_OBJ) $(TEST_OS_LNK)
ld $< -Map $(TEST_OS_MAP) -o $@ -T $(word 2, $^)

$(TEST_OS_OBJ): $(TEST_OS_ASM)
gcc $^ -c -nostdlib -o $@ -Wall -Wextra

-- End of Makefile --

Put these files on a same directory. "test_os.s" is source code of tiny OS
to run on QEMU. The OS consists only a boot sector. It initialize x87 FPU
and pushes some floating point values onto x87 FPU stack. "test_os.ld" is
its linker script. And you can make "test_os.img", a raw image of the OS.
Now, there are all things to reproduce the bug. You can "make test" to let
QEMU run the OS and wait for GDB, then GDB will start. Below is "result 1"
reproducing the bug.

-- Begin of result 1 --

$ make test
(gdb) target remote localhost:2159
(gdb) break *0x7c00
(gdb) continue
(gdb) x/10i $eip
=> 0x7c00:  fninit
   0x7c02:  fld1
   0x7c04:  fldl2t
   0x7c06:  fldl2e
   0x7c08:  fldpi
   0x7c0a:  fldlg2
   0x7c0c:  fldln2
   0x7c0e:  fldz
   0x7c10:  hlt
   0x7c11:  jmp0x7c10
(gdb) break *0x7c10
(gdb) continue
(gdb) info float
  R7: Valid   0x037f3fff8000 +9.18460266999444e-4934 Denormal
  R6: Valid   0x4000d49a784b +2.56521115372749819e-4937  Denormal
  R5: Valid   0xcd1b8afe3fffb8aa3b29 -1.960870532096122377e+1010
  R4: Valid   0x5c17f0bc4000c90fdaa2 +1.914514747773691148e+2165
  R3: Valid   0x2168c2353ffd9a209a84 +6.533729021523866343e-2358
  R2: Valid   0xfbcff7993ffeb17217f7 -4.548119628708025252e+4609
  R1: Valid   0xd1cf79ac Unsupported
=>R0: Valid   0x +0

Status Word: 0x
   TOP: 0
Control Word:0x0800
   PC: Single Precision (24-bits)
   RC: Round up
Tag Word:0x
Instruction Pointer: 0x00:0x
Operand Pointer: 0x00:0x
Opcode:  0x

-- End of result 1 --

First, in GDB interface, connect localhost:2159 where QEMU is waiting for
GDB. Second, Proceed to 0x7c00 and confirm there are intentional
instructions. Finally, Proceed to 0x7c10 and confirm contents of the x87
FPU registers. There are values different from what the OS pushed in
registers from "R0" to "R7", the x87 FPU stack. Furthermore, the control
word seems to be wrong. The first instruction "fninit" in the OS makes the
control word 0x037f but it is 0x0800 in the above result.

2. Cause

There is a cause in exchanging 'g' packet between QEMU and GDB. This packet
sends registers of machine emulated by QEMU to GDB. And its format is
defined in "qemu/gdb-xml/i386-32bit.xml". Size of EFER register is defined
in two places, line 113 and 129.

-- qemu/gdb-xml/i386-32bit.xml line 113 --

  

--

The above line says size of EFER is 8 bytes.

-- qemu/gdb-xml/i386-32bit.xml line 129 --

  

--

The above line says size of EFER is 3

[PATCH v4 0/2] target/loongarch: Fix emulation of float-point disable exception

2022-11-04 Thread Rui Wang
v4:
 - Separate hardware flags to mmu index and plv.
 - Fix return value of check fpe.

Rui Wang (2):
  target/loongarch: Adjust the layout of hardware flags bit fields
  target/loongarch: Fix emulation of float-point disable exception

 target/loongarch/cpu.c|  2 ++
 target/loongarch/cpu.h| 29 ++--
 .../loongarch/insn_trans/trans_farith.c.inc   | 30 
 target/loongarch/insn_trans/trans_fcmp.c.inc  | 11 --
 .../loongarch/insn_trans/trans_fmemory.c.inc  | 34 +++
 target/loongarch/insn_trans/trans_fmov.c.inc  | 29 ++--
 .../insn_trans/trans_privileged.c.inc |  4 +--
 target/loongarch/tlb_helper.c |  4 +--
 target/loongarch/translate.c  |  7 +++-
 target/loongarch/translate.h  |  3 +-
 10 files changed, 126 insertions(+), 27 deletions(-)

-- 
2.38.1




[PATCH v4 1/2] target/loongarch: Adjust the layout of hardware flags bit fields

2022-11-04 Thread Rui Wang
Suggested-by: Richard Henderson 
Signed-off-by: Rui Wang 
---
 target/loongarch/cpu.h| 27 ---
 .../insn_trans/trans_privileged.c.inc |  4 +--
 target/loongarch/tlb_helper.c |  4 +--
 target/loongarch/translate.c  |  7 -
 target/loongarch/translate.h  |  3 ++-
 5 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index dbce176564..026cd6bb52 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -14,6 +14,7 @@
 #include "qemu/timer.h"
 #include "exec/memory.h"
 #include "hw/sysbus.h"
+#include "cpu-csr.h"
 
 #define IOCSRF_TEMP 0
 #define IOCSRF_NODECNT  1
@@ -373,24 +374,30 @@ struct LoongArchCPUClass {
  * 0 for kernel mode, 3 for user mode.
  * Define an extra index for DA(direct addressing) mode.
  */
-#define MMU_KERNEL_IDX   0
-#define MMU_USER_IDX 3
-#define MMU_DA_IDX   4
+#define MMU_PLV_KERNEL   0
+#define MMU_PLV_USER 3
+#define MMU_IDX_KERNEL   MMU_PLV_KERNEL
+#define MMU_IDX_USER MMU_PLV_USER
+#define MMU_IDX_DA   4
 
 static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
-return MMU_USER_IDX;
+return MMU_IDX_USER;
 #else
-uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
-
-if (!pg) {
-return MMU_DA_IDX;
+if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) {
+return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
 }
-return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
+return MMU_IDX_DA;
 #endif
 }
 
+/*
+ * LoongArch CPUs hardware flags.
+ */
+#define HW_FLAGS_PLV_MASK   R_CSR_CRMD_PLV_MASK  /* 0x03 */
+#define HW_FLAGS_CRMD_PGR_CSR_CRMD_PG_MASK   /* 0x10 */
+
 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
 target_ulong *pc,
 target_ulong *cs_base,
@@ -398,7 +405,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState 
*env,
 {
 *pc = env->pc;
 *cs_base = 0;
-*flags = cpu_mmu_index(env, false);
+*flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
 }
 
 void loongarch_cpu_list(void);
diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc 
b/target/loongarch/insn_trans/trans_privileged.c.inc
index 9c4dcbfcfb..40f82becb0 100644
--- a/target/loongarch/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/insn_trans/trans_privileged.c.inc
@@ -159,7 +159,7 @@ static const CSRInfo csr_info[] = {
 
 static bool check_plv(DisasContext *ctx)
 {
-if (ctx->base.tb->flags == MMU_USER_IDX) {
+if (ctx->plv == MMU_PLV_USER) {
 generate_exception(ctx, EXCCODE_IPE);
 return true;
 }
@@ -335,7 +335,7 @@ TRANS(iocsrwr_d, gen_iocsrwr, gen_helper_iocsrwr_d)
 
 static void check_mmu_idx(DisasContext *ctx)
 {
-if (ctx->mem_idx != MMU_DA_IDX) {
+if (ctx->mem_idx != MMU_IDX_DA) {
 tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
 ctx->base.is_jmp = DISAS_EXIT;
 }
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index d2f8fb0c60..c6d1de50fe 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -170,8 +170,8 @@ static int get_physical_address(CPULoongArchState *env, 
hwaddr *physical,
 int *prot, target_ulong address,
 MMUAccessType access_type, int mmu_idx)
 {
-int user_mode = mmu_idx == MMU_USER_IDX;
-int kernel_mode = mmu_idx == MMU_KERNEL_IDX;
+int user_mode = mmu_idx == MMU_IDX_USER;
+int kernel_mode = mmu_idx == MMU_IDX_KERNEL;
 uint32_t plv, base_c, base_v;
 int64_t addr_high;
 uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA);
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 6091772349..38ced69803 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -75,7 +75,12 @@ static void loongarch_tr_init_disas_context(DisasContextBase 
*dcbase,
 DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
-ctx->mem_idx = ctx->base.tb->flags;
+ctx->plv = ctx->base.tb->flags & HW_FLAGS_PLV_MASK;
+if (ctx->base.tb->flags & HW_FLAGS_CRMD_PG) {
+ctx->mem_idx = ctx->plv;
+} else {
+ctx->mem_idx = MMU_IDX_DA;
+}
 
 /* Bound the number of insns to execute to those left on the page.  */
 bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 9cc12512d1..6d2e382e8b 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -29,7 +29,8 @@ typedef struct DisasContext {
 DisasContextBase base;
 target_ulong page_start;
 uint32_t opcode;
-int mem_idx;
+uint16_t mem_idx;
+uint16_t plv;
 TCGv zero;
 /* Sp

[PATCH v4 2/2] target/loongarch: Fix emulation of float-point disable exception

2022-11-04 Thread Rui Wang
We need to emulate it to generate a floating point disable exception
when CSR.EUEN.FPE is zero.

Signed-off-by: Rui Wang 
---
 target/loongarch/cpu.c|  2 ++
 target/loongarch/cpu.h|  2 ++
 .../loongarch/insn_trans/trans_farith.c.inc   | 30 
 target/loongarch/insn_trans/trans_fcmp.c.inc  | 11 --
 .../loongarch/insn_trans/trans_fmemory.c.inc  | 34 +++
 target/loongarch/insn_trans/trans_fmov.c.inc  | 29 ++--
 6 files changed, 97 insertions(+), 11 deletions(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 1512664214..46b04cbdad 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -48,6 +48,7 @@ static const char * const excp_names[] = {
 [EXCCODE_BRK] = "Break",
 [EXCCODE_INE] = "Instruction Non-Existent",
 [EXCCODE_IPE] = "Instruction privilege error",
+[EXCCODE_FPD] = "Floating Point Disabled",
 [EXCCODE_FPE] = "Floating Point Exception",
 [EXCCODE_DBP] = "Debug breakpoint",
 [EXCCODE_BCE] = "Bound Check Exception",
@@ -185,6 +186,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
 case EXCCODE_BRK:
 case EXCCODE_INE:
 case EXCCODE_IPE:
+case EXCCODE_FPD:
 case EXCCODE_FPE:
 case EXCCODE_BCE:
 env->CSR_BADV = env->pc;
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 026cd6bb52..e15c633b0b 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -397,6 +397,7 @@ static inline int cpu_mmu_index(CPULoongArchState *env, 
bool ifetch)
  */
 #define HW_FLAGS_PLV_MASK   R_CSR_CRMD_PLV_MASK  /* 0x03 */
 #define HW_FLAGS_CRMD_PGR_CSR_CRMD_PG_MASK   /* 0x10 */
+#define HW_FLAGS_EUEN_FPE   0x04
 
 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
 target_ulong *pc,
@@ -406,6 +407,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState 
*env,
 *pc = env->pc;
 *cs_base = 0;
 *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
+*flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE;
 }
 
 void loongarch_cpu_list(void);
diff --git a/target/loongarch/insn_trans/trans_farith.c.inc 
b/target/loongarch/insn_trans/trans_farith.c.inc
index 7bb3f41aee..7081fbb89b 100644
--- a/target/loongarch/insn_trans/trans_farith.c.inc
+++ b/target/loongarch/insn_trans/trans_farith.c.inc
@@ -3,9 +3,22 @@
  * Copyright (c) 2021 Loongson Technology Corporation Limited
  */
 
+#ifndef CONFIG_USER_ONLY
+#define CHECK_FPE do { \
+if ((ctx->base.tb->flags & HW_FLAGS_EUEN_FPE) == 0) { \
+generate_exception(ctx, EXCCODE_FPD); \
+return true; \
+} \
+} while (0)
+#else
+#define CHECK_FPE
+#endif
+
 static bool gen_fff(DisasContext *ctx, arg_fff *a,
 void (*func)(TCGv, TCGv_env, TCGv, TCGv))
 {
+CHECK_FPE;
+
 func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk]);
 return true;
 }
@@ -13,6 +26,8 @@ static bool gen_fff(DisasContext *ctx, arg_fff *a,
 static bool gen_ff(DisasContext *ctx, arg_ff *a,
void (*func)(TCGv, TCGv_env, TCGv))
 {
+CHECK_FPE;
+
 func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj]);
 return true;
 }
@@ -22,6 +37,9 @@ static bool gen_muladd(DisasContext *ctx, arg_ *a,
int flag)
 {
 TCGv_i32 tflag = tcg_constant_i32(flag);
+
+CHECK_FPE;
+
 func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj],
  cpu_fpr[a->fk], cpu_fpr[a->fa], tflag);
 return true;
@@ -29,18 +47,24 @@ static bool gen_muladd(DisasContext *ctx, arg_ *a,
 
 static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a)
 {
+CHECK_FPE;
+
 tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 31);
 return true;
 }
 
 static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a)
 {
+CHECK_FPE;
+
 tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 63);
 return true;
 }
 
 static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a)
 {
+CHECK_FPE;
+
 tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 31));
 gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
 return true;
@@ -48,12 +72,16 @@ static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a)
 
 static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a)
 {
+CHECK_FPE;
+
 tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 63));
 return true;
 }
 
 static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a)
 {
+CHECK_FPE;
+
 tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x8000);
 gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
 return true;
@@ -61,6 +89,8 @@ static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a)
 
 static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a)
 {
+CHECK_FPE;
+
 tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x8000LL);
 return true;
 }
diff --git a/t

Re: [PATCH v3 11/11] Hexagon (target/hexagon) Use direct block chaining for tight loops

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

Direct block chaining is documented here
https://qemu.readthedocs.io/en/latest/devel/tcg.html#direct-block-chaining

Hexagon inner loops end with the endloop0 instruction
To go back to the beginning of the loop, this instructions writes to PC
from register SA0 (start address 0).  To use direct block chaining, we
have to assign PC with a constant value.  So, we specialize the code
generation when the start of the translation block is equal to SA0.

When this is the case, we defer the compare/branch from endloop0 to
gen_end_tb.  When this is done, we can assign the start address of the TB
to PC.

Signed-off-by: Taylor Simpson 
---
  target/hexagon/cpu.h   | 17 
  target/hexagon/gen_tcg.h   |  3 ++
  target/hexagon/translate.h |  1 +
  target/hexagon/genptr.c| 57 ++
  target/hexagon/translate.c | 34 +++
  5 files changed, 107 insertions(+), 5 deletions(-)

diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index ff8c26272d..5260e0f127 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -152,16 +152,23 @@ struct ArchCPU {
  
  #include "cpu_bits.h"
  
+typedef union {

+uint32_t i;
+struct {
+bool is_tight_loop:1;
+};
+} HexStateFlags;


I don't see this as an improvement on manual flags handling, as it makes the flags value 
be dependent on host bit-field ordering.  This makes it more difficult to compare traces 
across hosts.


Otherwise,
Reviewed-by: Richard Henderson 


r~



Re: [PATCH v3 10/11] Hexagon (target/hexagon) Use direct block chaining for direct jump/branch

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

Direct block chaining is documented here
https://qemu.readthedocs.io/en/latest/devel/tcg.html#direct-block-chaining

Recall that Hexagon allows packets with multiple jumps where only the first
one with a true predicate will actually jump.  So, we can only use direct
block chaining when the packet contains a single PC-relative jump.


Not quite accurate.

Only the first two direct branches can use direct block chaining.  Other exits from the 
translation block could use indirect block chaining (tcg_gen_lookup_and_goto_ptr).  You 
just have to remember which is taken.


That said, this is certainly an improvement.


+if (ctx->pkt->pkt_has_multi_cof) {
+gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), pred);
+} else {
+/* Defer this jump to the end of the TB */
+g_assert(ctx->branch_cond == NULL);
+ctx->has_single_direct_branch = true;
+if (pred != NULL) {
+ctx->branch_cond = tcg_temp_local_new();
+tcg_gen_mov_tl(ctx->branch_cond, pred);
+}
+ctx->branch_dest = dest;


Perhaps re-use hex_branch_taken as branch_cond?

Anyway,
Reviewed-by: Richard Henderson 


r~



[PATCH] LockGuards: replace manual lock()/unlock() calls to WITH_QEMU_LOCK_GUARD()

2022-11-04 Thread nyoro . gachu
From: Samker 

LockGuards are preferred to manual lock()/unlock() calls. Lock guards
help prevent common bugs when locks are not released in error code
paths. This patch
replaces calls to manual lock()/unlock() with the much preferred
WITH_QEMU_LOCK_GUARD()

Signed-off-by: M N Gachu 
---
 softmmu/physmem.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index d9578ccfd4..fb00596777 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -24,6 +24,7 @@
 #include "qemu/cutils.h"
 #include "qemu/cacheflush.h"
 #include "qemu/madvise.h"
+#include "qemu/lockable.h"
 
 #ifdef CONFIG_TCG
 #include "hw/core/tcg-cpu-ops.h"
@@ -3114,13 +3115,12 @@ void cpu_register_map_client(QEMUBH *bh)
 {
 MapClient *client = g_malloc(sizeof(*client));
 
-qemu_mutex_lock(&map_client_list_lock);
+WITH_QEMU_LOCK_GUARD(&map_client_list_lock);
 client->bh = bh;
 QLIST_INSERT_HEAD(&map_client_list, client, link);
 if (!qatomic_read(&bounce.in_use)) {
 cpu_notify_map_clients_locked();
 }
-qemu_mutex_unlock(&map_client_list_lock);
 }
 
 void cpu_exec_init_all(void)
@@ -3143,7 +3143,7 @@ void cpu_unregister_map_client(QEMUBH *bh)
 {
 MapClient *client;
 
-qemu_mutex_lock(&map_client_list_lock);
+WITH_QEMU_LOCK_GUARD(&map_client_list_lock);
 QLIST_FOREACH(client, &map_client_list, link) {
 if (client->bh == bh) {
 cpu_unregister_map_client_do(client);
-- 
2.25.1




Re: [PATCH v3 09/11] Hexagon (target/hexagon) Add overrides for various forms of jump

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

+static void gen_cmp_jumpnv(DisasContext *ctx,
+   TCGCond cond, TCGv val, TCGv src, int pc_off)
+{
+TCGv pred = tcg_temp_new();
+tcg_gen_setcond_tl(cond, pred, val, src);
+gen_cond_jump(ctx, pred, pc_off);


This, in particular could benefit from the complete branch condition being passed down, 
rather than setcond here then brcond based on the result.


But it's still an improvement, so,
Reviewed-by: Richard Henderson 


r~



Re: [PATCH v3 07/11] Hexagon (target/hexagon) Add overrides for direct call instructions

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

+static void gen_write_new_pc_addr(DisasContext *ctx, TCGv addr, TCGv pred)
+{
+TCGLabel *pred_false = NULL;
+if (pred != NULL) {
+pred_false = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, pred, 0, pred_false);
+}


It would be nice to pass down the entire branch condition.  Trivial for usage within this 
patch, but more complex for others.


r~



Re: [PATCH v3 07/11] Hexagon (target/hexagon) Add overrides for direct call instructions

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

+tcg_gen_andi_tl(lsb, pred, 1);
+if (!sense) {
+tcg_gen_xori_tl(lsb, lsb, 1);
+}
+gen_write_new_pc_pcrel(ctx, pc_off, lsb);
+tcg_gen_brcondi_tl(TCG_COND_EQ, lsb, 0, skip);


Better to change the branch condition than invert the lsb.


r~



Re: [PATCH v3 08/11] Hexagon (target/hexagon) Add overrides for compound compare and jump

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

Signed-off-by: Taylor Simpson
---
  target/hexagon/gen_tcg.h | 177 +++
  target/hexagon/genptr.c  |  72 
  2 files changed, 249 insertions(+)


Acked-by: Richard Henderson 

r~



Re: [PATCH v3 07/11] Hexagon (target/hexagon) Add overrides for direct call instructions

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

Add overrides for
 J2_call
 J2_callt
 J2_callf

Signed-off-by: Taylor Simpson
---
  target/hexagon/gen_tcg.h |  8 ++
  target/hexagon/genptr.c  | 55 
  2 files changed, 63 insertions(+)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v3 06/11] Hexagon (target/hexagon) Remove next_PC from runtime state

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

The imported files don't properly mark all CONDEXEC instructions, so
we add some logic to hex_common.py to add the attribute.

Signed-off-by: Taylor Simpson
---
  target/hexagon/cpu.h|  1 -
  target/hexagon/gen_tcg.h|  6 ++
  target/hexagon/macros.h |  2 +-
  target/hexagon/translate.h  |  2 +-
  target/hexagon/op_helper.c  |  6 +++---
  target/hexagon/translate.c  | 29 +++--
  target/hexagon/gen_helper_funcs.py  |  4 
  target/hexagon/gen_helper_protos.py |  3 +++
  target/hexagon/gen_tcg_funcs.py |  3 +++
  target/hexagon/hex_common.py| 20 
  10 files changed, 64 insertions(+), 12 deletions(-)


Acked-by: Richard Henderson 

r~



Re: [PATCH v3 05/11] Hexagon (target/hexagon) Remove PC from the runtime state

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

Add pc field to Packet structure
For helpers that need PC, pass an extra argument
Remove slot arg from conditional jump helpers
On a trap0, copy pkt->pc into hex_gpr[HEX_REG_PC]

Signed-off-by: Taylor Simpson
---
  target/hexagon/gen_tcg.h| 7 +++
  target/hexagon/insn.h   | 1 +
  target/hexagon/macros.h | 2 +-
  target/hexagon/translate.c  | 9 +
  target/hexagon/gen_helper_funcs.py  | 4 
  target/hexagon/gen_helper_protos.py | 3 +++
  target/hexagon/gen_tcg_funcs.py | 3 +++
  target/hexagon/hex_common.py| 6 +-
  8 files changed, 25 insertions(+), 10 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v3 04/11] Hexagon (target/hexagon) Only use branch_taken when packet has multi cof

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

When a packet has more than one change-of-flow instruction, only the first
one to branch is considered.  We use the branch_taken variable to keep
track of this.

However, when there is a single cof instruction, we don't need the same
amount of bookkeeping.

We add the pkt_has_multi_cof member to the Packet structure, and pass this
information to the needed functions.

When there is a generated helper function with cof, the generator will
pass this pkt_has_multi_cof as a runtime value.

Signed-off-by: Taylor Simpson
---
  target/hexagon/insn.h   |  1 +
  target/hexagon/macros.h |  2 +-
  target/hexagon/decode.c | 15 +--
  target/hexagon/op_helper.c  | 24 +++-
  target/hexagon/translate.c  |  4 +++-
  target/hexagon/gen_helper_funcs.py  |  5 -
  target/hexagon/gen_helper_protos.py |  8 ++--
  target/hexagon/gen_tcg_funcs.py |  5 +
  target/hexagon/hex_common.py|  3 +++
  9 files changed, 51 insertions(+), 16 deletions(-)


Acked-by: Richard Henderson 

r~



Re: [PATCH v3 03/11] Hexagon (target/hexagon) Add overrides for S2_asr_r_r_sat/S2_asl_r_r_sat

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

+static void gen_set_usr_field(int field, TCGv val)
+{
+tcg_gen_deposit_tl(hex_new_value[HEX_REG_USR], hex_new_value[HEX_REG_USR],
+   val,
+   reg_field_info[field].offset,
+   reg_field_info[field].width);
+}


If you plan to use this for something else, fine, but since you're never clearing USR_OVF, 
it would be better to use tcg_gen_ori_tl.




+static void gen_sat_i64(TCGv_i64 dst, TCGv_i64 src, uint32_t bits)
+{
+TCGLabel *label = gen_new_label();
+
+tcg_gen_sextract_i64(dst, src, 0, bits);
+tcg_gen_brcond_i64(TCG_COND_EQ, dst, src, label);
+{
+TCGv_i64 min = tcg_constant_i64(-(1LL << (bits - 1)));
+TCGv_i64 max = tcg_constant_i64((1LL << (bits - 1)) - 1);
+tcg_gen_movcond_i64(TCG_COND_LT, dst, src, tcg_constant_i64(0),
+min, max);
+gen_set_usr_fieldi(USR_OVF, 1);
+}
+gen_set_label(label);
+}


This could be done branchless:

   tcg_gen_smax_i64(dst, src, min);
   tcg_gen_smin_i64(dst, dst, max);

   tcg_gen_setcond_i64(TCG_COND_NE, o_64, dst, src);
   tcg_gen_trunc_i64_tl(o_tl, o_64);
   tcg_gen_shli_tl(o_tl, reg_field_info[USE_OVF].offset);
   tcg_gen_or_tl(hex_new_value[HEX_REG_USR], hex_new_value[HEX_REG_USR], o_tl);



+static void gen_satval(TCGv_i64 dest, TCGv_i64 source, uint32_t bits)
+{
+TCGv_i64 min = tcg_constant_i64(-(1LL << (bits - 1)));
+TCGv_i64 max = tcg_constant_i64((1LL << (bits - 1)) - 1);
+
+gen_set_usr_fieldi(USR_OVF, 1);
+tcg_gen_movcond_i64(TCG_COND_LT, dest, source, tcg_constant_i64(0),
+min, max);
+}


Likewise.


+/* Shift left with saturation */
+static void gen_shl_sat(TCGv RdV, TCGv RsV, TCGv shift_amt)
+{
+/*
+ * int64_t A = (fCAST4_8s(RsV) << shift_amt;
+ * if (((int32_t)((fSAT(A)) ^ ((int32_t)(RsV < 0) {
+ * RdV = fSATVALN(32, ((int32_t)(RsV)))
+ * } else if (((RsV) > 0) && ((A) == 0)) {
+ * RdV = fSATVALN(32, (RsV));
+ * } else {
+ * RdV = fSAT(A);
+ * }
+ */


A little bit tricky to follow, but is this overflow condition to be the same as

x_32 = rsv << shift_amt;
y_32 = x_32 >> shift_amt;
overflow = x_32 != y_32;

i.e. overflow if we've lost bits that are not copies of the sign bit (and thus restored by 
the arithmetic right shift)?



+tcg_gen_ext_i32_i64(RsV_i64, RsV);
+tcg_gen_ext_i32_i64(shift_amt_i64, shift_amt);
+tcg_gen_shl_i64(A, RsV_i64, shift_amt_i64);
+
+/* Check for saturation */
+gen_sat_i64(A_sat_i64, A, 32);


Setting USR_OVF here...


+tcg_gen_extrl_i64_i32(A_sat, A_sat_i64);
+tcg_gen_xor_tl(tmp, A_sat, RsV);
+tcg_gen_brcondi_tl(TCG_COND_GE, tmp, 0, label1);
+gen_satval(RdV_i64, RsV_i64, 32);


... and also here.  Is this also computing the same saturation value that you 
did above?



+tcg_gen_extrl_i64_i32(RdV, RdV_i64);
+tcg_gen_br(done);
+
+gen_set_label(label1);
+tcg_gen_brcondi_tl(TCG_COND_LE, RsV, 0, label2);
+tcg_gen_brcondi_i64(TCG_COND_NE, A, 0, label2);
+gen_satval(RdV_i64, RsV_i64, 32);


and again?


+tcg_gen_extrl_i64_i32(RdV, RdV_i64);
+tcg_gen_br(done);
+
+gen_set_label(label2);
+tcg_gen_mov_tl(RdV, A_sat);
+
+gen_set_label(done);
+
+tcg_temp_free_i64(RsV_i64);
+tcg_temp_free_i64(shift_amt_i64);
+tcg_temp_free_i64(A);
+tcg_temp_free_i64(A_sat_i64);
+tcg_temp_free(A_sat);
+tcg_temp_free_i64(RdV_i64);
+tcg_temp_free(tmp);
+}
+
+static void gen_sar(TCGv RdV, TCGv RsV, TCGv shift_amt)
+{
+/*
+ * if (shift_amt < 32) {
+ * RdV = sar(RsV, shift_amt);
+ * } else {
+ * if (RsV > 0) {
+ * RdV = 0;
+ * } else {
+ * RdV = ~0;
+ * }
+ * }
+ */
+TCGLabel *shift_ge_32 = gen_new_label();
+TCGLabel *done = gen_new_label();
+
+tcg_gen_brcondi_tl(TCG_COND_GE, shift_amt, 32, shift_ge_32);
+tcg_gen_sar_tl(RdV, RsV, shift_amt);
+tcg_gen_br(done);
+
+gen_set_label(shift_ge_32);
+tcg_gen_movcond_tl(TCG_COND_LT, RdV, RsV, tcg_constant_tl(0),
+   tcg_constant_tl(~0), tcg_constant_tl(0));


This is better done as

shift = min(shift, 31);
rdv = rsv >> shift;

without branches.


r~



Re: [PATCH v3 02/11] Hexagon (target/hexagon) Fix predicated assignment to .tmp and .cur

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

Here are example instructions with a predicated .tmp/.cur assignment
 if (p1) v12.tmp = vmem(r7 + #0)
 if (p0) v12.cur = vmem(r9 + #0)
The .tmp/.cur indicates that references to v12 in the same packet
take the result of the load.  However, when the predicate is false,
the value at the start of the packet should be used.  After the packet
commits, the .tmp value is dropped, but the .cur value is maintained.

To fix this bug, we preload the original value from the HVX register
into the temporary used for the result.

Test cases added to tests/tcg/hexagon/hvx_misc.c

Co-authored-by: Matheus Tavares Bernardino
Signed-off-by: Matheus Tavares Bernardino
Signed-off-by: Taylor Simpson
---
  target/hexagon/translate.h  |  6 +++
  tests/tcg/hexagon/hvx_misc.c| 72 +
  target/hexagon/gen_tcg_funcs.py | 12 ++
  3 files changed, 90 insertions(+)


Acked-by: Richard Henderson 

r~



Re: [PATCH v3 01/11] Hexagon (target/hexagon) Add pkt and insn to DisasContext

2022-11-04 Thread Richard Henderson

On 11/5/22 06:26, Taylor Simpson wrote:

This enables us to reduce the number of parameters to many functions
In particular, the generated functions previously took all 3 as arguments

Not only does this simplify the code, it improves the translation time

Signed-off-by: Taylor Simpson
---
  target/hexagon/gen_tcg_hvx.h|   6 +-
  target/hexagon/insn.h   |   7 +-
  target/hexagon/macros.h |  10 +--
  target/hexagon/mmvec/macros.h   |   4 +-
  target/hexagon/translate.h  |   9 ++-
  target/hexagon/genptr.c |   6 +-
  target/hexagon/translate.c  | 120 +---
  target/hexagon/gen_tcg_funcs.py |  15 ++--
  8 files changed, 89 insertions(+), 88 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 0/2] util/log: Make the per-thread flag immutable

2022-11-04 Thread Richard Henderson

On 11/4/22 23:00, Greg Kurz wrote:

While working on the "util/log: Always send errors to logfile when daemonized"
series [1], I've encountered some issues with the per-thread flag. They stem
from the code not being designed to allow the per-thread flag to be enabled
or disabled more than once, but nothing is done to prevent that from
happening. This results in unexpected results like the creation of a log
file with a `%d` in its name or confusing errors when using the `log`
command in the monitor.

I'm posting fixes separately now in case it makes sense to merge them during
soft freeze. If so, I'll open an issue as explained in this recent mail [2].

[1] https://patchew.org/QEMU/20221019151651.334334-1-gr...@kaod.org/
[2] https://lists.nongnu.org/archive/html/qemu-devel/2022-11/msg00137.html

Date: Wed, 19 Oct 2022 17:16:49 +0200
Message-ID: <20221019151651.334334-1-gr...@kaod.org>

Greg Kurz (2):
   util/log: Make the per-thread flag immutable
   util/log: Ignore per-thread flag if global file already there

  util/log.c | 9 +
  1 file changed, 9 insertions(+)



Series:
Reviewed-by: Richard Henderson 


r~



Re: [PATCH v9 4/8] KVM: Use gfn instead of hva for mmu_notifier_retry

2022-11-04 Thread Sean Christopherson
On Fri, Nov 04, 2022, Chao Peng wrote:
> On Thu, Oct 27, 2022 at 11:29:14AM +0100, Fuad Tabba wrote:
> > Hi,
> > 
> > On Tue, Oct 25, 2022 at 4:19 PM Chao Peng  
> > wrote:
> > >
> > > Currently in mmu_notifier validate path, hva range is recorded and then
> > > checked against in the mmu_notifier_retry_hva() of the page fault path.
> > > However, for the to be introduced private memory, a page fault may not
> > > have a hva associated, checking gfn(gpa) makes more sense.
> > >
> > > For existing non private memory case, gfn is expected to continue to
> > > work. The only downside is when aliasing multiple gfns to a single hva,
> > > the current algorithm of checking multiple ranges could result in a much
> > > larger range being rejected. Such aliasing should be uncommon, so the
> > > impact is expected small.
> > >
> > > It also fixes a bug in kvm_zap_gfn_range() which has already been using
> > 
> > nit: Now it's kvm_unmap_gfn_range().
> 
> Forgot to mention: the bug is still with kvm_zap_gfn_range(). It calls
> kvm_mmu_invalidate_begin/end with a gfn range but before this series
> kvm_mmu_invalidate_begin/end actually accept a hva range. Note it's
> unrelated to whether we use kvm_zap_gfn_range() or kvm_unmap_gfn_range()
> in the following patch (patch 05).

Grr, in the future, if you find an existing bug, please send a patch.  At the
very least, report the bug.  The APICv case that this was added for could very
well be broken because of this, and the resulting failures would be an absolute
nightmare to debug.

Compile tested only...

--
From: Sean Christopherson 
Date: Fri, 4 Nov 2022 22:20:33 +
Subject: [PATCH] KVM: x86/mmu: Block all page faults during
 kvm_zap_gfn_range()

When zapping a GFN range, pass 0 => ALL_ONES for the to-be-invalidated
range to effectively block all page faults while the zap is in-progress.
The invalidation helpers take a host virtual address, whereas zapping a
GFN obviously provides a guest physical address and with the wrong unit
of measurement (frame vs. byte).

Alternatively, KVM could walk all memslots to get the associated HVAs,
but thanks to SMM, that would require multiple lookups.  And practically
speaking, kvm_zap_gfn_range() usage is quite rare and not a hot path,
e.g. MTRR and CR0.CD are almost guaranteed to be done only on vCPU0
during boot, and APICv inhibits are similarly infrequent operations.

Fixes: edb298c663fc ("KVM: x86/mmu: bump mmu notifier count in 
kvm_zap_gfn_range")
Cc: sta...@vger.kernel.org
Cc: Maxim Levitsky 
Signed-off-by: Sean Christopherson 
---
 arch/x86/kvm/mmu/mmu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 6f81539061d6..1ccb769f62af 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -6056,7 +6056,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, 
gfn_t gfn_end)
 
write_lock(&kvm->mmu_lock);
 
-   kvm_mmu_invalidate_begin(kvm, gfn_start, gfn_end);
+   kvm_mmu_invalidate_begin(kvm, 0, -1ul);
 
flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end);
 
@@ -6070,7 +6070,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, 
gfn_t gfn_end)
kvm_flush_remote_tlbs_with_address(kvm, gfn_start,
   gfn_end - gfn_start);
 
-   kvm_mmu_invalidate_end(kvm, gfn_start, gfn_end);
+   kvm_mmu_invalidate_end(kvm, 0, -1ul);
 
write_unlock(&kvm->mmu_lock);
 }

base-commit: c12879206e47730ff5ab255bbf625b28ade4028f
-- 




Re: [PATCH 12/26] target/s390x: Move masking of psw.addr to cpu_get_tb_cpu_state

2022-11-04 Thread Richard Henderson

On 11/4/22 00:42, Ilya Leoshkevich wrote:

On Wed, Oct 05, 2022 at 08:44:07PM -0700, Richard Henderson wrote:

Masking after the fact in s390x_tr_init_disas_context
provides incorrect information to tb_lookup.

Signed-off-by: Richard Henderson 
---
  target/s390x/cpu.h   | 13 +++--
  target/s390x/tcg/translate.c |  6 --
  2 files changed, 7 insertions(+), 12 deletions(-)


How can we end up in a situation where this matters? E.g. if we are in
64-bit mode and execute

 0xa12345678: sam31

we will get a specification exception, and cpu_get_tb_cpu_state() will
not run. And for valid 31-bit addresses masking should be a no-op.


Ah, true.  I was mislead by the presence of the code in s390x_tr_init_disas_context. 
Perhaps a tcg_debug_assert or just a comment?



r~



Re: [PATCH v3 2/2] target/loongarch: Fix emulation of float-point disable exception

2022-11-04 Thread Richard Henderson

On 11/4/22 15:05, Rui Wang wrote:

+#ifndef CONFIG_USER_ONLY
+#define CHECK_FPE do { \
+if ((ctx->base.tb->flags & HW_FLAGS_EUEN_FPE) == 0) { \
+generate_exception(ctx, EXCCODE_FPD); \
+return false; \
+} \
+} while (0)
+#else
+#define CHECK_FPE
+#endif
+
  static bool gen_fff(DisasContext *ctx, arg_fff *a,
  void (*func)(TCGv, TCGv_env, TCGv, TCGv))
  {
+CHECK_FPE;


Oh, sorry, I just realized this is not quite correct: CHECK_FPE should return 
true, not false.

Returning false indicates that the instruction has not been matched, and the decoder 
should continue searching.  If we reach the end of the search space, we raise EXCCODE_INE. 
But here we have successfully matched the instruction, and have found that the register 
bank is disabled and should raise EXCCODE_FPD.


The difference will in practice not be visible, because the code that will be emitted to 
raise EXCCODE_INE will not be reached, because control flow will have already raised 
EXCCODE_FPD, but it would be better to not emit the dead code.



r~



Re: [PATCH v3 1/2] target/loongarch: Adjust the layout of hardware flags bit fields

2022-11-04 Thread Richard Henderson

On 11/4/22 15:05, Rui Wang wrote:

  static bool check_plv(DisasContext *ctx)
  {
-if (ctx->base.tb->flags == MMU_USER_IDX) {
+if (ctx->mem_idx == MMU_USER_IDX) {


Not quite.  This needs to check HW_FLAGS_PLV_MASK, not the mem_idx.  That was the intent 
of keeping them separate in HW_FLAGS.



r~



Re: [PATCH] target/arm: Two fixes for secure ptw

2022-11-04 Thread Richard Henderson

On 11/4/22 21:58, Peter Maydell wrote:

OK. Do we ever do anything with the attrs for a phys tlb lookup
except use them internally for details of the stage 2 tlb walk ?
I guess they get used for the memory transaction to do the walk.
That matches the old code that just had a local MemTxAttrs in
arm_ldq_ptw() to do the walk which therefore implicitly got
user == false.


Exactly.

I can't think of any reason .user would be apply outside of the stage1 lookup, which is 
what records the setting for any future mmio.



r~



Re: [PATCH v9 5/8] KVM: Register/unregister the guest private memory regions

2022-11-04 Thread Sean Christopherson
Paolo, any thoughts before I lead things further astray?

On Fri, Nov 04, 2022, Chao Peng wrote:
> On Thu, Nov 03, 2022 at 11:04:53PM +, Sean Christopherson wrote:
> > On Tue, Oct 25, 2022, Chao Peng wrote:
> > > @@ -4708,6 +4802,24 @@ static long kvm_vm_ioctl(struct file *filp,
> > >   r = kvm_vm_ioctl_set_memory_region(kvm, &mem);
> > >   break;
> > >   }
> > > +#ifdef CONFIG_KVM_GENERIC_PRIVATE_MEM
> > > + case KVM_MEMORY_ENCRYPT_REG_REGION:
> > > + case KVM_MEMORY_ENCRYPT_UNREG_REGION: {
> > 
> > I'm having second thoughts about usurping 
> > KVM_MEMORY_ENCRYPT_(UN)REG_REGION.  Aside
> > from the fact that restricted/protected memory may not be encrypted, there 
> > are
> > other potential use cases for per-page memory attributes[*], e.g. to make 
> > memory
> > read-only (or no-exec, or exec-only, etc...) without having to modify 
> > memslots.
> > 
> > Any paravirt use case where the attributes of a page are effectively 
> > dictated by
> > the guest is going to run into the exact same performance problems with 
> > memslots,
> > which isn't suprising in hindsight since shared vs. private is really just 
> > an
> > attribute, albeit with extra special semantics.
> > 
> > And if we go with a brand new ioctl(), maybe someday in the very distant 
> > future
> > we can deprecate and delete KVM_MEMORY_ENCRYPT_(UN)REG_REGION.
> > 
> > Switching to a new ioctl() should be a minor change, i.e. shouldn't throw 
> > too big
> > of a wrench into things.
> > 
> > Something like:
> > 
> >   KVM_SET_MEMORY_ATTRIBUTES
> > 
> >   struct kvm_memory_attributes {
> > __u64 address;
> > __u64 size;
> > __u64 flags;

Oh, this is half-baked.  I lost track of which flags were which.  What I 
intended
was a separate, initially-unused flags, e.g.

 struct kvm_memory_attributes {
__u64 address;
__u64 size;
__u64 attributes;
__u64 flags;
  }

so that KVM can tweak behavior and/or extend the effective size of the struct.

> I like the idea of adding a new ioctl(). But putting all attributes into
> a flags in uAPI sounds not good to me, e.g. forcing userspace to set all
> attributes in one call can cause pain for userspace, probably for KVM
> implementation as well. For private<->shared memory conversion, we
> actually only care the KVM_MEM_ATTR_SHARED or KVM_MEM_ATTR_PRIVATE bit,

Not necessarily, e.g. I can see pKVM wanting to convert from RW+PRIVATE => 
RO+SHARED
or even RW+PRIVATE => NONE+SHARED so that the guest can't write/access the 
memory
while it's accessible from the host.

And if this does extend beyond shared/private, dropping from RWX=>R, i.e. 
dropping
WX permissions, would also be a common operation.

Hmm, typing that out makes me think that if we do end up supporting other 
"attributes",
i.e. protections, we should go straight to full RWX protections instead of doing
things piecemeal, i.e. add individual protections instead of combinations like
NO_EXEC and READ_ONLY.  The protections would have to be inverted for backwards
compatibility, but that's easy enough to handle.  The semantics could be like
protection keys, which also have inverted persmissions, where the final 
protections
are the combination of memslot+attributes, i.e. a read-only memslot couldn't be 
made
writable via attributes.

E.g. userspace could do "NO_READ | NO_WRITE | NO_EXEC" to temporarily block 
access
to memory without needing to delete the memslot.  KVM would need to disallow
unsupported combinations, e.g. disallowed effective protections would be:

  - W or WX [unless there's an arch that supports write-only memory]
  - R or RW [until KVM plumbs through support for no-exec, or it's unsupported 
in hardware]
  - X   [until KVM plumbs through support for exec-only, or it's 
unsupported in hardware]

Anyways, that's all future work...

> but we force userspace to set other irrelevant bits as well if use this
> API.

They aren't irrelevant though, as the memory attributes are all describing the
allowed protections for a given page.  If there's a use case where userspace 
"can't"
keep track of the attributes for whatever reason, then userspace could do a RMW
to set/clear attributes.  Alternatively, the ioctl() could take an "operation" 
and
support WRITE/OR/AND to allow setting/clearing individual flags, e.g. tweak the
above to be: 
 
 struct kvm_memory_attributes {
__u64 address;
__u64 size;
__u64 attributes;
__u32 operation;
__u32 flags;
  }

> I looked at kvm_device_attr, sounds we can do similar:

The device attributes deal with isolated, arbitrary values, whereas memory 
attributes
are flags, i.e. devices are 1:1 whereas memory is 1:MANY.  There is no "unset" 
for
device attributes, because they aren't flags.  Device attributes vs. memory 
attributes
really are two very different things that just happen to use a common name.

If it helped clarify things without creating naming problems, we could even use
PROTECTIONS instead of ATT

[PATCH 2/3] hvf: implement guest debugging on Apple Silicon hosts

2022-11-04 Thread francesco . cagnin
From: Francesco Cagnin 

Support is added for single-stepping, software breakpoints, hardware
breakpoints and watchpoints. The code has been structured like the KVM
counterpart (and many parts are basically identical).

Guests can be debugged through the gdbstub.

Signed-off-by: Francesco Cagnin 
---
 accel/hvf/hvf-accel-ops.c | 124 
 accel/hvf/hvf-all.c   |  24 +
 cpu.c |   3 +
 include/sysemu/hvf.h  |  29 ++
 include/sysemu/hvf_int.h  |   1 +
 target/arm/hvf/hvf.c  | 194 +-
 6 files changed, 374 insertions(+), 1 deletion(-)

diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index 24913ca9c4..5ff5778d55 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -52,6 +52,7 @@
 #include "qemu/main-loop.h"
 #include "exec/address-spaces.h"
 #include "exec/exec-all.h"
+#include "exec/gdbstub.h"
 #include "sysemu/cpus.h"
 #include "sysemu/hvf.h"
 #include "sysemu/hvf_int.h"
@@ -340,12 +341,18 @@ static int hvf_accel_init(MachineState *ms)
 return hvf_arch_init();
 }
 
+static int hvf_gdbstub_sstep_flags(void)
+{
+return SSTEP_ENABLE;
+}
+
 static void hvf_accel_class_init(ObjectClass *oc, void *data)
 {
 AccelClass *ac = ACCEL_CLASS(oc);
 ac->name = "HVF";
 ac->init_machine = hvf_accel_init;
 ac->allowed = &hvf_allowed;
+ac->gdbstub_supported_sstep_flags = hvf_gdbstub_sstep_flags;
 }
 
 static const TypeInfo hvf_accel_type = {
@@ -462,6 +469,118 @@ static void hvf_start_vcpu_thread(CPUState *cpu)
cpu, QEMU_THREAD_JOINABLE);
 }
 
+static bool hvf_supports_guest_debug(void)
+{
+#ifdef TARGET_AARCH64
+return true;
+#else
+return false;
+#endif
+}
+
+static int hvf_insert_breakpoint(CPUState *cpu, int type, hwaddr addr, hwaddr 
len)
+{
+struct hvf_sw_breakpoint *bp;
+int err;
+
+if (type == GDB_BREAKPOINT_SW) {
+bp = hvf_find_sw_breakpoint(cpu, addr);
+if (bp) {
+bp->use_count++;
+return 0;
+}
+
+bp = g_new(struct hvf_sw_breakpoint, 1);
+bp->pc = addr;
+bp->use_count = 1;
+err = hvf_arch_insert_sw_breakpoint(cpu, bp);
+if (err) {
+g_free(bp);
+return err;
+}
+
+QTAILQ_INSERT_HEAD(&hvf_state->hvf_sw_breakpoints, bp, entry);
+} else {
+err = hvf_arch_insert_hw_breakpoint(addr, len, type);
+if (err) {
+return err;
+}
+}
+
+CPU_FOREACH(cpu) {
+err = hvf_update_guest_debug(cpu);
+if (err) {
+return err;
+}
+}
+return 0;
+}
+
+static int hvf_remove_breakpoint(CPUState *cpu, int type, hwaddr addr, hwaddr 
len)
+{
+struct hvf_sw_breakpoint *bp;
+int err;
+
+if (type == GDB_BREAKPOINT_SW) {
+bp = hvf_find_sw_breakpoint(cpu, addr);
+if (!bp) {
+return -ENOENT;
+}
+
+if (bp->use_count > 1) {
+bp->use_count--;
+return 0;
+}
+
+err = hvf_arch_remove_sw_breakpoint(cpu, bp);
+if (err) {
+return err;
+}
+
+QTAILQ_REMOVE(&hvf_state->hvf_sw_breakpoints, bp, entry);
+g_free(bp);
+} else {
+err = hvf_arch_remove_hw_breakpoint(addr, len, type);
+if (err) {
+return err;
+}
+}
+
+CPU_FOREACH(cpu) {
+err = hvf_update_guest_debug(cpu);
+if (err) {
+return err;
+}
+}
+return 0;
+}
+
+static void hvf_remove_all_breakpoints(CPUState *cpu)
+{
+struct hvf_sw_breakpoint *bp, *next;
+HVFState *s = hvf_state;
+CPUState *tmpcpu;
+
+QTAILQ_FOREACH_SAFE(bp, &s->hvf_sw_breakpoints, entry, next) {
+if (hvf_arch_remove_sw_breakpoint(cpu, bp) != 0) {
+/* Try harder to find a CPU that currently sees the breakpoint. */
+CPU_FOREACH(tmpcpu)
+{
+if (hvf_arch_remove_sw_breakpoint(tmpcpu, bp) == 0) {
+break;
+}
+}
+}
+QTAILQ_REMOVE(&s->hvf_sw_breakpoints, bp, entry);
+g_free(bp);
+}
+hvf_arch_remove_all_hw_breakpoints();
+
+CPU_FOREACH(cpu) {
+hvf_update_guest_debug(cpu);
+}
+}
+
 static void hvf_accel_ops_class_init(ObjectClass *oc, void *data)
 {
 AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
@@ -473,6 +592,11 @@ static void hvf_accel_ops_class_init(ObjectClass *oc, void 
*data)
 ops->synchronize_post_init = hvf_cpu_synchronize_post_init;
 ops->synchronize_state = hvf_cpu_synchronize_state;
 ops->synchronize_pre_loadvm = hvf_cpu_synchronize_pre_loadvm;
+
+ops->supports_guest_debug = hvf_supports_guest_debug;
+ops->insert_breakpoint = hvf_insert_breakpoint;
+ops->remove_breakpoint = hvf_remove_breakpoint;
+ops->remove_all_breakpoints = hvf_remove_all_breakpoints;
 };
 static const TypeInfo hvf_accel_ops_type = {
 

[PATCH 3/3] hvf: handle writes of MDSCR_EL1 and DBG*_EL1

2022-11-04 Thread francesco . cagnin
From: Francesco Cagnin 

This proved to be required when debugging the Linux kernel's initial
code, as the Hypervisor framework was triggering 'EC_SYSTEMREGISTERTRAP'
VM exits after enabling trap exceptions with
'hv_vcpu_set_trap_debug_exceptions()'.

Signed-off-by: Francesco Cagnin 
---
 target/arm/hvf/hvf.c | 140 +++
 1 file changed, 140 insertions(+)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 211b296500..dbc3605f6d 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -97,6 +97,71 @@ static void hvf_arm_init_debug(CPUState *cpu)
 #define SYSREG_PMCEID1_EL0SYSREG(3, 3, 9, 12, 7)
 #define SYSREG_PMCCNTR_EL0SYSREG(3, 3, 9, 13, 0)
 #define SYSREG_PMCCFILTR_EL0  SYSREG(3, 3, 14, 15, 7)
+#define SYSREG_MDSCR_EL1  SYSREG(2, 0, 0, 2, 2)
+#define SYSREG_DBGBVR0_EL1SYSREG(2, 0, 0, 0, 4)
+#define SYSREG_DBGBCR0_EL1SYSREG(2, 0, 0, 0, 5)
+#define SYSREG_DBGWVR0_EL1SYSREG(2, 0, 0, 0, 6)
+#define SYSREG_DBGWCR0_EL1SYSREG(2, 0, 0, 0, 7)
+#define SYSREG_DBGBVR1_EL1SYSREG(2, 0, 0, 1, 4)
+#define SYSREG_DBGBCR1_EL1SYSREG(2, 0, 0, 1, 5)
+#define SYSREG_DBGWVR1_EL1SYSREG(2, 0, 0, 1, 6)
+#define SYSREG_DBGWCR1_EL1SYSREG(2, 0, 0, 1, 7)
+#define SYSREG_DBGBVR2_EL1SYSREG(2, 0, 0, 2, 4)
+#define SYSREG_DBGBCR2_EL1SYSREG(2, 0, 0, 2, 5)
+#define SYSREG_DBGWVR2_EL1SYSREG(2, 0, 0, 2, 6)
+#define SYSREG_DBGWCR2_EL1SYSREG(2, 0, 0, 2, 7)
+#define SYSREG_DBGBVR3_EL1SYSREG(2, 0, 0, 3, 4)
+#define SYSREG_DBGBCR3_EL1SYSREG(2, 0, 0, 3, 5)
+#define SYSREG_DBGWVR3_EL1SYSREG(2, 0, 0, 3, 6)
+#define SYSREG_DBGWCR3_EL1SYSREG(2, 0, 0, 3, 7)
+#define SYSREG_DBGBVR4_EL1SYSREG(2, 0, 0, 4, 4)
+#define SYSREG_DBGBCR4_EL1SYSREG(2, 0, 0, 4, 5)
+#define SYSREG_DBGWVR4_EL1SYSREG(2, 0, 0, 4, 6)
+#define SYSREG_DBGWCR4_EL1SYSREG(2, 0, 0, 4, 7)
+#define SYSREG_DBGBVR5_EL1SYSREG(2, 0, 0, 5, 4)
+#define SYSREG_DBGBCR5_EL1SYSREG(2, 0, 0, 5, 5)
+#define SYSREG_DBGWVR5_EL1SYSREG(2, 0, 0, 5, 6)
+#define SYSREG_DBGWCR5_EL1SYSREG(2, 0, 0, 5, 7)
+#define SYSREG_DBGBVR6_EL1SYSREG(2, 0, 0, 6, 4)
+#define SYSREG_DBGBCR6_EL1SYSREG(2, 0, 0, 6, 5)
+#define SYSREG_DBGWVR6_EL1SYSREG(2, 0, 0, 6, 6)
+#define SYSREG_DBGWCR6_EL1SYSREG(2, 0, 0, 6, 7)
+#define SYSREG_DBGBVR7_EL1SYSREG(2, 0, 0, 7, 4)
+#define SYSREG_DBGBCR7_EL1SYSREG(2, 0, 0, 7, 5)
+#define SYSREG_DBGWVR7_EL1SYSREG(2, 0, 0, 7, 6)
+#define SYSREG_DBGWCR7_EL1SYSREG(2, 0, 0, 7, 7)
+#define SYSREG_DBGBVR8_EL1SYSREG(2, 0, 0, 8, 4)
+#define SYSREG_DBGBCR8_EL1SYSREG(2, 0, 0, 8, 5)
+#define SYSREG_DBGWVR8_EL1SYSREG(2, 0, 0, 8, 6)
+#define SYSREG_DBGWCR8_EL1SYSREG(2, 0, 0, 8, 7)
+#define SYSREG_DBGBVR9_EL1SYSREG(2, 0, 0, 9, 4)
+#define SYSREG_DBGBCR9_EL1SYSREG(2, 0, 0, 9, 5)
+#define SYSREG_DBGWVR9_EL1SYSREG(2, 0, 0, 9, 6)
+#define SYSREG_DBGWCR9_EL1SYSREG(2, 0, 0, 9, 7)
+#define SYSREG_DBGBVR10_EL1   SYSREG(2, 0, 0, 10, 4)
+#define SYSREG_DBGBCR10_EL1   SYSREG(2, 0, 0, 10, 5)
+#define SYSREG_DBGWVR10_EL1   SYSREG(2, 0, 0, 10, 6)
+#define SYSREG_DBGWCR10_EL1   SYSREG(2, 0, 0, 10, 7)
+#define SYSREG_DBGBVR11_EL1   SYSREG(2, 0, 0, 11, 4)
+#define SYSREG_DBGBCR11_EL1   SYSREG(2, 0, 0, 11, 5)
+#define SYSREG_DBGWVR11_EL1   SYSREG(2, 0, 0, 11, 6)
+#define SYSREG_DBGWCR11_EL1   SYSREG(2, 0, 0, 11, 7)
+#define SYSREG_DBGBVR12_EL1   SYSREG(2, 0, 0, 12, 4)
+#define SYSREG_DBGBCR12_EL1   SYSREG(2, 0, 0, 12, 5)
+#define SYSREG_DBGWVR12_EL1   SYSREG(2, 0, 0, 12, 6)
+#define SYSREG_DBGWCR12_EL1   SYSREG(2, 0, 0, 12, 7)
+#define SYSREG_DBGBVR13_EL1   SYSREG(2, 0, 0, 13, 4)
+#define SYSREG_DBGBCR13_EL1   SYSREG(2, 0, 0, 13, 5)
+#define SYSREG_DBGWVR13_EL1   SYSREG(2, 0, 0, 13, 6)
+#define SYSREG_DBGWCR13_EL1   SYSREG(2, 0, 0, 13, 7)
+#define SYSREG_DBGBVR14_EL1   SYSREG(2, 0, 0, 14, 4)
+#define SYSREG_DBGBCR14_EL1   SYSREG(2, 0, 0, 14, 5)
+#define SYSREG_DBGWVR14_EL1   SYSREG(2, 0, 0, 14, 6)
+#define SYSREG_DBGWCR14_EL1   SYSREG(2, 0, 0, 14, 7)
+#define SYSREG_DBGBVR15_EL1   SYSREG(2, 0, 0, 15, 4)
+#define SYSREG_DBGBCR15_EL1   SYSREG(2, 0, 0, 15, 5)
+#define SYSREG_DBGWVR15_EL1   SYSREG(2, 0, 0, 15, 6)
+#define SYSREG_DBGWCR15_EL1   SYSREG(2, 0, 0, 15, 7)
 
 #define WFX_IS_WFE (1 << 0)
 
@@ -1041,6 +1106,81 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, 
uint64_t val)
 case SYSREG_OSDLR_EL1:
 /* Dummy register */
 break;
+case SYSREG_MDSCR_EL1:
+env->cp15.mdscr_el1 = val;
+break;
+case SYSREG_DBGBVR0_EL1:
+case SYSREG_DBGBVR1_EL1:
+case SYSREG_DBGBVR2_EL1:
+case SYSREG_DBGBVR3_EL1:
+case SYSREG_DBGBVR4_EL1:
+case SYSREG_DBGBVR5_EL1:
+case SYSREG_DBGBVR6_EL1:
+case SYSREG_DBGBVR7_EL1:
+case SYSREG_DBGBVR8_EL1:
+case SYSREG_DBGBVR9_EL1:
+case SYSREG_DBGBVR10_EL1:
+case SYSREG_DBGBVR11_EL1:
+case SYSREG_DBGBVR12_EL1:
+case SYSREG_DBGBVR13_EL1:
+case SYSREG_DBGBVR14_EL1:
+case SYSREG_DBGB

[PATCH 1/3] arm: move KVM breakpoints helpers

2022-11-04 Thread francesco . cagnin
From: Francesco Cagnin 

These helpers will be also used for HVF. Aside from reformatting a
couple of comments for 'checkpatch.pl', this is just code motion.

Signed-off-by: Francesco Cagnin 
---
 target/arm/debug_helper.c | 241 +
 target/arm/internals.h|  50 +++
 target/arm/kvm64.c| 276 --
 3 files changed, 291 insertions(+), 276 deletions(-)

diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
index c21739242c..2f29dd7e9b 100644
--- a/target/arm/debug_helper.c
+++ b/target/arm/debug_helper.c
@@ -12,6 +12,7 @@
 #include "cpregs.h"
 #include "exec/exec-all.h"
 #include "exec/helper-proto.h"
+#include "exec/gdbstub.h"
 
 
 /* Return the Exception Level targeted by debug exceptions. */
@@ -1134,3 +1135,243 @@ vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr 
addr, int len)
 }
 
 #endif
+
+/* Maximum and current break/watch point counts */
+int max_hw_bps, max_hw_wps;
+GArray *hw_breakpoints, *hw_watchpoints;
+
+/**
+ * insert_hw_breakpoint()
+ * @addr: address of breakpoint
+ *
+ * See ARM ARM D2.9.1 for details but here we are only going to create
+ * simple un-linked breakpoints (i.e. we don't chain breakpoints
+ * together to match address and context or vmid). The hardware is
+ * capable of fancier matching but that will require exposing that
+ * fanciness to GDB's interface
+ *
+ * DBGBCR_EL1, Debug Breakpoint Control Registers
+ *
+ *  31  24 23  20 19   16 15 14  13  12   9 8   5 43 2   1  0
+ * +--+--+---+-++--+-+--+-+---+
+ * | RES0 |  BT  |  LBN  | SSC | HMC| RES0 | BAS | RES0 | PMC | E |
+ * +--+--+---+-++--+-+--+-+---+
+ *
+ * BT: Breakpoint type (0 = unlinked address match)
+ * LBN: Linked BP number (0 = unused)
+ * SSC/HMC/PMC: Security, Higher and Priv access control (Table D-12)
+ * BAS: Byte Address Select (RES1 for AArch64)
+ * E: Enable bit
+ *
+ * DBGBVR_EL1, Debug Breakpoint Value Registers
+ *
+ *  63  53 52   49 48   2  1 0
+ * +--+---+--+-+
+ * | RESS | VA[52:49] | VA[48:2] | 0 0 |
+ * +--+---+--+-+
+ *
+ * Depending on the addressing mode bits the top bits of the register
+ * are a sign extension of the highest applicable VA bit. Some
+ * versions of GDB don't do it correctly so we ensure they are correct
+ * here so future PC comparisons will work properly.
+ */
+
+int insert_hw_breakpoint(target_ulong addr)
+{
+HWBreakpoint brk = {
+.bcr = 0x1, /* BCR E=1, enable */
+.bvr = sextract64(addr, 0, 53)
+};
+
+if (cur_hw_bps >= max_hw_bps) {
+return -ENOBUFS;
+}
+
+brk.bcr = deposit32(brk.bcr, 1, 2, 0x3);   /* PMC = 11 */
+brk.bcr = deposit32(brk.bcr, 5, 4, 0xf);   /* BAS = RES1 */
+
+g_array_append_val(hw_breakpoints, brk);
+
+return 0;
+}
+
+/**
+ * delete_hw_breakpoint()
+ * @pc: address of breakpoint
+ *
+ * Delete a breakpoint and shuffle any above down
+ */
+
+int delete_hw_breakpoint(target_ulong pc)
+{
+int i;
+for (i = 0; i < hw_breakpoints->len; i++) {
+HWBreakpoint *brk = get_hw_bp(i);
+if (brk->bvr == pc) {
+g_array_remove_index(hw_breakpoints, i);
+return 0;
+}
+}
+return -ENOENT;
+}
+
+/**
+ * insert_hw_watchpoint()
+ * @addr: address of watch point
+ * @len: size of area
+ * @type: type of watch point
+ *
+ * See ARM ARM D2.10. As with the breakpoints we can do some advanced
+ * stuff if we want to. The watch points can be linked with the break
+ * points above to make them context aware. However for simplicity
+ * currently we only deal with simple read/write watch points.
+ *
+ * D7.3.11 DBGWCR_EL1, Debug Watchpoint Control Registers
+ *
+ *  31  29 28   24 23  21  20  19 16 15 14  13   12  5 4   3 2   1  0
+ * +--+---+--++-+-+-+-+-+-+---+
+ * | RES0 |  MASK | RES0 | WT | LBN | SSC | HMC | BAS | LSC | PAC | E |
+ * +--+---+--++-+-+-+-+-+-+---+
+ *
+ * MASK: num bits addr mask (0=none,01/10=res,11=3 bits (8 bytes))
+ * WT: 0 - unlinked, 1 - linked (not currently used)
+ * LBN: Linked BP number (not currently used)
+ * SSC/HMC/PAC: Security, Higher and Priv access control (Table D2-11)
+ * BAS: Byte Address Select
+ * LSC: Load/Store control (01: load, 10: store, 11: both)
+ * E: Enable
+ *
+ * The bottom 2 bits of the value register are masked. Therefore to
+ * break on any sizes smaller than an unaligned word you need to set
+ * MASK=0, BAS=bit per byte in question. For larger regions (^2) you
+ * need to ensure you mask the address as required and set BAS=0xff
+ */
+
+int insert_hw_watchpoint(target_ulong addr,
+target_ulong len, int type)
+{
+HWWatchpoint wp = {
+.wcr = R_DBGWCR_E_MASK, /* E=1, enable */
+.wvr = addr & (~0x7ULL),
+.details = { .vaddr = 

[PATCH 0/3] Add gdbstub support to HVF

2022-11-04 Thread francesco . cagnin
From: Francesco Cagnin 

Hello,

This patch series aims to add gdbstub support to HVF (the 'QEMU
accelerator on macOS that employs Hypervisor.framework') on Apple
Silicon hosts.

The proposed implementation, structured like the KVM counterpart,
handles single-stepping, software breakpoints, hardware breakpoints and
hardware watchpoints on single-core guests (i.e. '-smp 1'). (If
possible, I'd like to receive guidance on how to add proper support for
multi-core guests.)

The patch has been most recently tested working on macOS Ventura 13.0
hosts and Linux kernel 5.19 guests with the test script
'tests/guest-debug/test-gdbstub.py' (slightly updated to make it work
with Linux kernels compiled on macOS).

If deemed useful, I can also submit an analogous patch targeting Intel
hosts.

Francesco Cagnin (3):
  arm: move KVM breakpoints helpers
  hvf: implement guest debugging on Apple Silicon hosts
  hvf: handle writes of MDSCR_EL1 and DBG*_EL1

 accel/hvf/hvf-accel-ops.c | 124 ++
 accel/hvf/hvf-all.c   |  24 +++
 cpu.c |   3 +
 include/sysemu/hvf.h  |  29 
 include/sysemu/hvf_int.h  |   1 +
 target/arm/debug_helper.c | 241 +++
 target/arm/hvf/hvf.c  | 334 +-
 target/arm/internals.h|  50 ++
 target/arm/kvm64.c| 276 ---
 9 files changed, 805 insertions(+), 277 deletions(-)

-- 
2.38.1




Re: [PATCH v3 09/30] nbd/server: Clean up abuse of BlockExportOptionsNbd member @arg

2022-11-04 Thread Eric Blake
On Fri, Nov 04, 2022 at 05:06:51PM +0100, Markus Armbruster wrote:
> block-export-add argument @name defaults to the value of argument
> @node-name.
> 
> nbd_export_create() implements this by copying @node_name to @name.
> It leaves @has_node_name false, violating the "has_node_name ==
> !!node_name" invariant.  Unclean.  Falls apart when we elide
> @has_node_name (next commit): then QAPI frees the same value twice,
> once for @node_name and once @name.  iotest 307 duly explodes.
> 
> Goes back to commit c62d24e906 "blockdev-nbd: Boxed argument type for
> nbd-server-add" (v5.0.0).  Got moved from qmp_nbd_server_add() to
> nbd_export_create() (commit 56ee86261e), then copied back (commit
> b6076afcab).  Commit 8675cbd68b "nbd: Utilize QAPI_CLONE for type
> conversion" (v5.2.0) cleaned up the copy in qmp_nbd_server_add()
> noting
> 
> Second, our assignment to arg->name is fishy: the generated QAPI code
> for qapi_free_NbdServerAddOptions does not visit arg->name if
> arg->has_name is false, but if it DID visit it, we would have
> introduced a double-free situation when arg is finally freed.
> 
> Exactly.  However, the copy in nbd_export_create() remained dirty.
> 
> Clean it up.  Since the value stored in member @name is not actually
> used outside this function, use a local variable instead of modifying
> the QAPI object.
> 
> Signed-off-by: Markus Armbruster 
> Cc: Eric Blake 
> Cc: Vladimir Sementsov-Ogievskiy 
> Cc: qemu-bl...@nongnu.org
> ---
>  nbd/server.c | 15 ++-
>  1 file changed, 6 insertions(+), 9 deletions(-)
>

Reviewed-by: Eric Blake 

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




Re: [PATCH v3 08/30] blockdev: Clean up abuse of DriveBackup member format

2022-11-04 Thread Eric Blake
On Fri, Nov 04, 2022 at 05:06:50PM +0100, Markus Armbruster wrote:
> drive-backup argument @format defaults to the format of the source
> unless @mode is "existing".
> 
> drive_backup_prepare() implements this by copying the source's
> @format_name to DriveBackup member @format.  It leaves @has_format
> false, violating the "has_format == !!format" invariant.  Unclean.
> Falls apart when we elide @has_format (commit after next): then QAPI
> passes @format, which is a string constant, to g_free().  iotest 056
> duly explodes.
> 
> Clean it up.  Since the value stored in member @format is not actually
> used outside this function, use a local variable instead of modifying
> the QAPI object.
> 
> Signed-off-by: Markus Armbruster 
> Cc: Kevin Wolf 
> Cc: Hanna Reitz 
> Cc: qemu-bl...@nongnu.org
> ---
>  blockdev.c | 17 +
>  1 file changed, 9 insertions(+), 8 deletions(-)
>

Reviewed-by: Eric Blake 

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




[PATCH v3 02/11] Hexagon (target/hexagon) Fix predicated assignment to .tmp and .cur

2022-11-04 Thread Taylor Simpson
Here are example instructions with a predicated .tmp/.cur assignment
if (p1) v12.tmp = vmem(r7 + #0)
if (p0) v12.cur = vmem(r9 + #0)
The .tmp/.cur indicates that references to v12 in the same packet
take the result of the load.  However, when the predicate is false,
the value at the start of the packet should be used.  After the packet
commits, the .tmp value is dropped, but the .cur value is maintained.

To fix this bug, we preload the original value from the HVX register
into the temporary used for the result.

Test cases added to tests/tcg/hexagon/hvx_misc.c

Co-authored-by: Matheus Tavares Bernardino 
Signed-off-by: Matheus Tavares Bernardino 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/translate.h  |  6 +++
 tests/tcg/hexagon/hvx_misc.c| 72 +
 target/hexagon/gen_tcg_funcs.py | 12 ++
 3 files changed, 90 insertions(+)

diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 115e29b84f..b8fcf615e8 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -86,6 +86,12 @@ static inline bool is_preloaded(DisasContext *ctx, int num)
 return test_bit(num, ctx->regs_written);
 }
 
+static inline bool is_vreg_preloaded(DisasContext *ctx, int num)
+{
+return test_bit(num, ctx->vregs_updated) ||
+   test_bit(num, ctx->vregs_updated_tmp);
+}
+
 intptr_t ctx_future_vreg_off(DisasContext *ctx, int regnum,
  int num, bool alloc_ok);
 intptr_t ctx_tmp_vreg_off(DisasContext *ctx, int regnum,
diff --git a/tests/tcg/hexagon/hvx_misc.c b/tests/tcg/hexagon/hvx_misc.c
index 6e2c9ab3cd..53d5c9b44f 100644
--- a/tests/tcg/hexagon/hvx_misc.c
+++ b/tests/tcg/hexagon/hvx_misc.c
@@ -541,6 +541,75 @@ static void test_vshuff(void)
 check_output_b(__LINE__, 1);
 }
 
+static void test_load_tmp_predicated(void)
+{
+void *p0 = buffer0;
+void *p1 = buffer1;
+void *pout = output;
+bool pred = true;
+
+for (int i = 0; i < BUFSIZE; i++) {
+/*
+ * Load into v12 as .tmp with a predicate
+ * When the predicate is true, we get the vector from buffer1[i]
+ * When the predicate is false, we get a vector of all 1's
+ * Regardless of the predicate, the next packet should have
+ * a vector of all 1's
+ */
+asm("v3 = vmem(%0 + #0)\n\t"
+"r1 = #1\n\t"
+"v12 = vsplat(r1)\n\t"
+"p1 = !cmp.eq(%3, #0)\n\t"
+"{\n\t"
+"if (p1) v12.tmp = vmem(%1 + #0)\n\t"
+"v4.w = vadd(v12.w, v3.w)\n\t"
+"}\n\t"
+"v4.w = vadd(v4.w, v12.w)\n\t"
+"vmem(%2 + #0) = v4\n\t"
+: : "r"(p0), "r"(p1), "r"(pout), "r"(pred)
+: "r1", "p1", "v12", "v3", "v4", "v6", "memory");
+p0 += sizeof(MMVector);
+p1 += sizeof(MMVector);
+pout += sizeof(MMVector);
+
+for (int j = 0; j < MAX_VEC_SIZE_BYTES / 4; j++) {
+expect[i].w[j] =
+pred ? buffer0[i].w[j] + buffer1[i].w[j] + 1
+ : buffer0[i].w[j] + 2;
+}
+pred = !pred;
+}
+
+check_output_w(__LINE__, BUFSIZE);
+}
+
+static void test_load_cur_predicated(void)
+{
+bool pred = true;
+for (int i = 0; i < BUFSIZE; i++) {
+asm volatile("p0 = !cmp.eq(%3, #0)\n\t"
+ "v3 = vmem(%0+#0)\n\t"
+ /*
+  * Preload v4 to make sure that the assignment from the
+  * packet below is not being ignored when pred is false.
+  */
+ "r0 = #0x01237654\n\t"
+ "v4 = vsplat(r0)\n\t"
+ "{\n\t"
+ "if (p0) v3.cur = vmem(%1+#0)\n\t"
+ "v4 = v3\n\t"
+ "}\n\t"
+ "vmem(%2+#0) = v4\n\t"
+ :
+ : "r"(&buffer0[i]), "r"(&buffer1[i]),
+   "r"(&output[i]), "r"(pred)
+ : "r0", "p0", "v3", "v4", "memory");
+expect[i] = pred ? buffer1[i] : buffer0[i];
+pred = !pred;
+}
+check_output_w(__LINE__, BUFSIZE);
+}
+
 int main()
 {
 init_buffers();
@@ -578,6 +647,9 @@ int main()
 
 test_vshuff();
 
+test_load_tmp_predicated();
+test_load_cur_predicated();
+
 puts(err ? "FAIL" : "PASS");
 return err ? 1 : 0;
 }
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index 02a6565685..ca5fde91cc 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -173,6 +173,18 @@ def genptr_decl(f, tag, regtype, regid, regno):
 f.write("ctx_future_vreg_off(ctx, %s%sN," % \
 (regtype, regid))
 f.write(" 1, true);\n");
+if 'A_CONDEXEC' in hex_common.attribdict[tag]:
+f.write("if (!is_vreg_preloaded(ctx, %s)) {\n" % (regN))
+  

[PATCH v3 09/11] Hexagon (target/hexagon) Add overrides for various forms of jump

2022-11-04 Thread Taylor Simpson
Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h | 189 +++
 target/hexagon/genptr.c  |  45 ++
 2 files changed, 234 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 8b311d16e0..93afa01156 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -797,6 +797,195 @@
 #define fGEN_TCG_J4_tstbit0_fp1_jump_t(SHORTCODE) \
 gen_cmpnd_tstbit0_jmp(ctx, 1, false, RsV, riV)
 
+#define fGEN_TCG_J2_jump(SHORTCODE) \
+gen_jump(ctx, riV)
+#define fGEN_TCG_J2_jumpr(SHORTCODE) \
+gen_jumpr(ctx, RsV)
+#define fGEN_TCG_J4_jumpseti(SHORTCODE) \
+do { \
+tcg_gen_movi_tl(RdV, UiV); \
+gen_jump(ctx, riV); \
+} while (0)
+
+#define fGEN_TCG_cond_jump(COND) \
+do { \
+TCGv LSB = tcg_temp_new(); \
+COND; \
+gen_cond_jump(ctx, LSB, riV); \
+tcg_temp_free(LSB); \
+} while (0)
+
+#define fGEN_TCG_J2_jumpt(SHORTCODE) \
+fGEN_TCG_cond_jump(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumptpt(SHORTCODE) \
+fGEN_TCG_cond_jump(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumpf(SHORTCODE) \
+fGEN_TCG_cond_jump(fLSBOLDNOT(PuV))
+#define fGEN_TCG_J2_jumpfpt(SHORTCODE) \
+fGEN_TCG_cond_jump(fLSBOLDNOT(PuV))
+#define fGEN_TCG_J2_jumptnew(SHORTCODE) \
+gen_cond_jump(ctx, PuN, riV)
+#define fGEN_TCG_J2_jumptnewpt(SHORTCODE) \
+gen_cond_jump(ctx, PuN, riV)
+#define fGEN_TCG_J2_jumpfnewpt(SHORTCODE) \
+fGEN_TCG_cond_jump(fLSBNEWNOT(PuN))
+#define fGEN_TCG_J2_jumpfnew(SHORTCODE) \
+fGEN_TCG_cond_jump(fLSBNEWNOT(PuN))
+#define fGEN_TCG_J2_jumprz(SHORTCODE) \
+fGEN_TCG_cond_jump(tcg_gen_setcondi_tl(TCG_COND_NE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprzpt(SHORTCODE) \
+fGEN_TCG_cond_jump(tcg_gen_setcondi_tl(TCG_COND_NE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprnz(SHORTCODE) \
+fGEN_TCG_cond_jump(tcg_gen_setcondi_tl(TCG_COND_EQ, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprnzpt(SHORTCODE) \
+fGEN_TCG_cond_jump(tcg_gen_setcondi_tl(TCG_COND_EQ, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprgtez(SHORTCODE) \
+fGEN_TCG_cond_jump(tcg_gen_setcondi_tl(TCG_COND_GE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprgtezpt(SHORTCODE) \
+fGEN_TCG_cond_jump(tcg_gen_setcondi_tl(TCG_COND_GE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprltez(SHORTCODE) \
+fGEN_TCG_cond_jump(tcg_gen_setcondi_tl(TCG_COND_LE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprltezpt(SHORTCODE) \
+fGEN_TCG_cond_jump(tcg_gen_setcondi_tl(TCG_COND_LE, LSB, RsV, 0))
+
+#define fGEN_TCG_cond_jumpr(COND) \
+do { \
+TCGv LSB = tcg_temp_new(); \
+COND; \
+gen_cond_jumpr(ctx, LSB, RsV); \
+tcg_temp_free(LSB); \
+} while (0)
+
+#define fGEN_TCG_J2_jumprt(SHORTCODE) \
+fGEN_TCG_cond_jumpr(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumprtpt(SHORTCODE) \
+fGEN_TCG_cond_jumpr(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumprf(SHORTCODE) \
+fGEN_TCG_cond_jumpr(fLSBOLDNOT(PuV))
+#define fGEN_TCG_J2_jumprfpt(SHORTCODE) \
+fGEN_TCG_cond_jumpr(fLSBOLDNOT(PuV))
+#define fGEN_TCG_J2_jumprtnew(SHORTCODE) \
+fGEN_TCG_cond_jumpr(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumprtnewpt(SHORTCODE) \
+fGEN_TCG_cond_jumpr(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumprfnew(SHORTCODE) \
+fGEN_TCG_cond_jumpr(fLSBNEWNOT(PuN))
+#define fGEN_TCG_J2_jumprfnewpt(SHORTCODE) \
+fGEN_TCG_cond_jumpr(fLSBNEWNOT(PuN))
+#define fGEN_TCG_J2_jumprfnewpt(SHORTCODE) \
+fGEN_TCG_cond_jumpr(fLSBNEWNOT(PuN))
+
+/*
+ * New value compare & jump instructions
+ * if ([!]COND(r0.new, r1) jump:t address
+ * if ([!]COND(r0.new, #7) jump:t address
+ */
+#define fGEN_TCG_J4_cmpgt_t_jumpnv_t(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_GT, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_t_jumpnv_nt(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_GT, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_f_jumpnv_t(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_LE, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_f_jumpnv_nt(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_LE, NsN, RtV, riV)
+
+#define fGEN_TCG_J4_cmpeq_t_jumpnv_t(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_EQ, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_t_jumpnv_nt(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_EQ, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_f_jumpnv_t(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_NE, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_f_jumpnv_nt(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_NE, NsN, RtV, riV)
+
+#define fGEN_TCG_J4_cmplt_t_jumpnv_t(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_LT, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmplt_t_jumpnv_nt(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_LT, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmplt_f_jumpnv_t(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_GE, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmplt_f_jumpnv_nt(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_GE, NsN, RtV, riV)
+
+#define fGEN_TCG_J4_cmpeqi_t_jumpnv_t(SHORTCODE) \
+gen_cmpi_jumpnv(ctx, TCG_COND_EQ, NsN, UiV, riV)
+#define fGEN_TCG_J4_cmpeq

[PATCH v3 04/11] Hexagon (target/hexagon) Only use branch_taken when packet has multi cof

2022-11-04 Thread Taylor Simpson
When a packet has more than one change-of-flow instruction, only the first
one to branch is considered.  We use the branch_taken variable to keep
track of this.

However, when there is a single cof instruction, we don't need the same
amount of bookkeeping.

We add the pkt_has_multi_cof member to the Packet structure, and pass this
information to the needed functions.

When there is a generated helper function with cof, the generator will
pass this pkt_has_multi_cof as a runtime value.

Signed-off-by: Taylor Simpson 
---
 target/hexagon/insn.h   |  1 +
 target/hexagon/macros.h |  2 +-
 target/hexagon/decode.c | 15 +--
 target/hexagon/op_helper.c  | 24 +++-
 target/hexagon/translate.c  |  4 +++-
 target/hexagon/gen_helper_funcs.py  |  5 -
 target/hexagon/gen_helper_protos.py |  8 ++--
 target/hexagon/gen_tcg_funcs.py |  5 +
 target/hexagon/hex_common.py|  3 +++
 9 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h
index cb92586802..775c4c183d 100644
--- a/target/hexagon/insn.h
+++ b/target/hexagon/insn.h
@@ -57,6 +57,7 @@ struct Packet {
 
 /* Pre-decodes about COF */
 bool pkt_has_cof;  /* Has any change-of-flow */
+bool pkt_has_multi_cof;/* Has more than one change-of-flow */
 bool pkt_has_endloop;
 
 bool pkt_has_dczeroa;
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 93ee4739a1..8fd8123cec 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -407,7 +407,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int 
shift)
 
 #define fCHECK_PCALIGN(A)
 
-#define fWRITE_NPC(A) write_new_pc(env, A)
+#define fWRITE_NPC(A) write_new_pc(env, pkt_has_multi_cof != 0, A)
 
 #define fBRANCH(LOC, TYPE)  fWRITE_NPC(LOC)
 #define fJUMPR(REGNO, TARGET, TYPE) fBRANCH(TARGET, COF_TYPE_JUMPR)
diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index 6b73b5c60c..041c8de751 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -388,6 +388,7 @@ static void decode_set_insn_attr_fields(Packet *pkt)
 uint16_t opcode;
 
 pkt->pkt_has_cof = false;
+pkt->pkt_has_multi_cof = false;
 pkt->pkt_has_endloop = false;
 pkt->pkt_has_dczeroa = false;
 
@@ -412,13 +413,23 @@ static void decode_set_insn_attr_fields(Packet *pkt)
 }
 }
 
-pkt->pkt_has_cof |= decode_opcode_can_jump(opcode);
+if (decode_opcode_can_jump(opcode)) {
+if (pkt->pkt_has_cof) {
+pkt->pkt_has_multi_cof = true;
+}
+pkt->pkt_has_cof = true;
+}
 
 pkt->insn[i].is_endloop = decode_opcode_ends_loop(opcode);
 
 pkt->pkt_has_endloop |= pkt->insn[i].is_endloop;
 
-pkt->pkt_has_cof |= pkt->pkt_has_endloop;
+if (pkt->pkt_has_endloop) {
+if (pkt->pkt_has_cof) {
+pkt->pkt_has_multi_cof = true;
+}
+pkt->pkt_has_cof = true;
+}
 }
 }
 
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 085afc3274..84391e25eb 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -104,20 +104,26 @@ static void log_store64(CPUHexagonState *env, 
target_ulong addr,
 env->mem_log_stores[slot].data64 = val;
 }
 
-static void write_new_pc(CPUHexagonState *env, target_ulong addr)
+static void write_new_pc(CPUHexagonState *env, bool pkt_has_multi_cof,
+ target_ulong addr)
 {
 HEX_DEBUG_LOG("write_new_pc(0x" TARGET_FMT_lx ")\n", addr);
 
-/*
- * If more than one branch is taken in a packet, only the first one
- * is actually done.
- */
-if (env->branch_taken) {
-HEX_DEBUG_LOG("INFO: multiple branches taken in same packet, "
-  "ignoring the second one\n");
+if (pkt_has_multi_cof) {
+/*
+ * If more than one branch is taken in a packet, only the first one
+ * is actually done.
+ */
+if (env->branch_taken) {
+HEX_DEBUG_LOG("INFO: multiple branches taken in same packet, "
+  "ignoring the second one\n");
+} else {
+fCHECK_PCALIGN(addr);
+env->next_PC = addr;
+env->branch_taken = 1;
+}
 } else {
 fCHECK_PCALIGN(addr);
-env->branch_taken = 1;
 env->next_PC = addr;
 }
 }
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 0940d0f2c1..1d872d72b6 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -248,7 +248,9 @@ static void gen_start_packet(DisasContext *ctx)
 tcg_gen_movi_tl(hex_slot_cancelled, 0);
 }
 if (pkt->pkt_has_cof) {
-tcg_gen_movi_tl(hex_branch_taken, 0);
+if (pkt->pkt_has_multi_cof) {
+tcg_gen_movi_tl(hex_branch_taken, 0);
+}
 tcg_gen_movi

[PATCH v3 01/11] Hexagon (target/hexagon) Add pkt and insn to DisasContext

2022-11-04 Thread Taylor Simpson
This enables us to reduce the number of parameters to many functions
In particular, the generated functions previously took all 3 as arguments

Not only does this simplify the code, it improves the translation time

Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg_hvx.h|   6 +-
 target/hexagon/insn.h   |   7 +-
 target/hexagon/macros.h |  10 +--
 target/hexagon/mmvec/macros.h   |   4 +-
 target/hexagon/translate.h  |   9 ++-
 target/hexagon/genptr.c |   6 +-
 target/hexagon/translate.c  | 120 +---
 target/hexagon/gen_tcg_funcs.py |  15 ++--
 8 files changed, 89 insertions(+), 88 deletions(-)

diff --git a/target/hexagon/gen_tcg_hvx.h b/target/hexagon/gen_tcg_hvx.h
index cdcc9382bb..083f4d92c6 100644
--- a/target/hexagon/gen_tcg_hvx.h
+++ b/target/hexagon/gen_tcg_hvx.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -697,7 +697,7 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 #define fGEN_TCG_NEWVAL_VEC_STORE(GET_EA, INC) \
 do { \
 GET_EA; \
-gen_vreg_store(ctx, insn, pkt, EA, OsN_off, insn->slot, true); \
+gen_vreg_store(ctx, EA, OsN_off, insn->slot, true); \
 INC; \
 } while (0)
 
@@ -736,7 +736,7 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 PRED; \
 tcg_gen_brcondi_tl(TCG_COND_EQ, LSB, 0, false_label); \
 tcg_temp_free(LSB); \
-gen_vreg_store(ctx, insn, pkt, EA, SRCOFF, insn->slot, ALIGN); \
+gen_vreg_store(ctx, EA, SRCOFF, insn->slot, ALIGN); \
 INC; \
 tcg_gen_br(end_label); \
 gen_set_label(false_label); \
diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h
index aa26389147..cb92586802 100644
--- a/target/hexagon/insn.h
+++ b/target/hexagon/insn.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -28,10 +28,7 @@ struct Instruction;
 struct Packet;
 struct DisasContext;
 
-typedef void (*SemanticInsn)(CPUHexagonState *env,
- struct DisasContext *ctx,
- struct Instruction *insn,
- struct Packet *pkt);
+typedef void (*SemanticInsn)(struct DisasContext *ctx);
 
 struct Instruction {
 SemanticInsn generate;/* pointer to genptr routine */
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index c8805bdaeb..93ee4739a1 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -94,9 +94,9 @@
  */
 #define CHECK_NOSHUF(VA, SIZE) \
 do { \
-if (insn->slot == 0 && pkt->pkt_has_store_s1) { \
+if (insn->slot == 0 && ctx->pkt->pkt_has_store_s1) { \
 probe_noshuf_load(VA, SIZE, ctx->mem_idx); \
-process_store(ctx, pkt, 1); \
+process_store(ctx, 1); \
 } \
 } while (0)
 
@@ -105,12 +105,12 @@
 TCGLabel *label = gen_new_label(); \
 tcg_gen_brcondi_tl(TCG_COND_EQ, PRED, 0, label); \
 GET_EA; \
-if (insn->slot == 0 && pkt->pkt_has_store_s1) { \
+if (insn->slot == 0 && ctx->pkt->pkt_has_store_s1) { \
 probe_noshuf_load(EA, SIZE, ctx->mem_idx); \
 } \
 gen_set_label(label); \
-if (insn->slot == 0 && pkt->pkt_has_store_s1) { \
-process_store(ctx, pkt, 1); \
+if (insn->slot == 0 && ctx->pkt->pkt_has_store_s1) { \
+process_store(ctx, 1); \
 } \
 } while (0)
 
diff --git a/target/hexagon/mmvec/macros.h b/target/hexagon/mmvec/macros.h
index 8345753580..8c864e8c68 100644
--- a/target/hexagon/mmvec/macros.h
+++ b/target/hexagon/mmvec/macros.h
@@ -288,7 +288,7 @@
 #endif
 #ifdef QEMU_GENERATE
 #define fSTOREMMV(EA, SRC) \
-gen_vreg_store(ctx, insn, pkt, EA, SRC##_off, insn->slot, true)
+gen_vreg_store(ctx, EA, SRC##_off, insn->slot, true)
 #endif
 #ifdef QEMU_GENERATE
 #define fSTOREMMVQ(EA, SRC, MASK) \
@@ -300,7 +300,7 @@
 #endif
 #ifdef QEMU_GENERATE
 #define fSTOREMMVU(EA, SRC) \
-gen_vreg_store(ctx, insn, pkt, EA, SRC##_off, insn->slot, false)
+gen_vreg_store(ctx, EA, SRC##_off, insn->slot, false)
 #endif
 #define fVFOREACH(WIDTH, VAR) for (VAR = 0; VAR < fVELEM(WIDTH); VAR++)
 #define fVARRAY_ELEMENT_ACCESS(ARRAY, TYPE, INDEX) \
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index a245172827..115e29b84f 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -1,5 +1,5 @@
 /*
- *  C

[PATCH v3 11/11] Hexagon (target/hexagon) Use direct block chaining for tight loops

2022-11-04 Thread Taylor Simpson
Direct block chaining is documented here
https://qemu.readthedocs.io/en/latest/devel/tcg.html#direct-block-chaining

Hexagon inner loops end with the endloop0 instruction
To go back to the beginning of the loop, this instructions writes to PC
from register SA0 (start address 0).  To use direct block chaining, we
have to assign PC with a constant value.  So, we specialize the code
generation when the start of the translation block is equal to SA0.

When this is the case, we defer the compare/branch from endloop0 to
gen_end_tb.  When this is done, we can assign the start address of the TB
to PC.

Signed-off-by: Taylor Simpson 
---
 target/hexagon/cpu.h   | 17 
 target/hexagon/gen_tcg.h   |  3 ++
 target/hexagon/translate.h |  1 +
 target/hexagon/genptr.c| 57 ++
 target/hexagon/translate.c | 34 +++
 5 files changed, 107 insertions(+), 5 deletions(-)

diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index ff8c26272d..5260e0f127 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -152,16 +152,23 @@ struct ArchCPU {
 
 #include "cpu_bits.h"
 
+typedef union {
+uint32_t i;
+struct {
+bool is_tight_loop:1;
+};
+} HexStateFlags;
+
 static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, target_ulong *pc,
 target_ulong *cs_base, uint32_t *flags)
 {
+HexStateFlags hex_flags = { 0 };
 *pc = env->gpr[HEX_REG_PC];
 *cs_base = 0;
-#ifdef CONFIG_USER_ONLY
-*flags = 0;
-#else
-#error System mode not supported on Hexagon yet
-#endif
+if (*pc == env->gpr[HEX_REG_SA0]) {
+hex_flags.is_tight_loop = true;
+}
+*flags = hex_flags.i;
 }
 
 static inline int cpu_mmu_index(CPUHexagonState *env, bool ifetch)
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 93afa01156..0f0c027523 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -620,6 +620,9 @@
 #define fGEN_TCG_J2_callf(SHORTCODE) \
 gen_cond_call(ctx, PuV, false, riV)
 
+#define fGEN_TCG_J2_endloop0(SHORTCODE) \
+gen_endloop0(ctx)
+
 /*
  * Compound compare and jump instructions
  * Here is a primer to understand the tag names
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 0841e8418e..7fc066c19a 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -60,6 +60,7 @@ typedef struct DisasContext {
 bool has_single_direct_branch;
 TCGv branch_cond;
 target_ulong branch_dest;
+bool is_tight_loop;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 235ea9d210..74b7b3ac5d 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -635,6 +635,63 @@ static void gen_cond_call(DisasContext *ctx, TCGv pred, 
bool sense, int pc_off)
 gen_set_label(skip);
 }
 
+static void gen_endloop0(DisasContext *ctx)
+{
+TCGv lpcfg = tcg_temp_local_new();
+
+GET_USR_FIELD(USR_LPCFG, lpcfg);
+
+/*
+ *if (lpcfg == 1) {
+ *hex_new_pred_value[3] = 0xff;
+ *hex_pred_written |= 1 << 3;
+ *}
+ */
+TCGLabel *label1 = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_NE, lpcfg, 1, label1);
+{
+tcg_gen_movi_tl(hex_new_pred_value[3], 0xff);
+tcg_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << 3);
+}
+gen_set_label(label1);
+
+/*
+ *if (lpcfg) {
+ *SET_USR_FIELD(USR_LPCFG, lpcfg - 1);
+ *}
+ */
+TCGLabel *label2 = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, lpcfg, 0, label2);
+{
+tcg_gen_subi_tl(lpcfg, lpcfg, 1);
+SET_USR_FIELD(USR_LPCFG, lpcfg);
+}
+gen_set_label(label2);
+
+/*
+ * If we're in a tight loop, we'll do this at the end of the TB to take
+ * advantage of direct block chaining.
+ */
+if (!ctx->is_tight_loop) {
+/*
+ *if (hex_gpr[HEX_REG_LC0] > 1) {
+ *PC = hex_gpr[HEX_REG_SA0];
+ *hex_new_value[HEX_REG_LC0] = hex_gpr[HEX_REG_LC0] - 1;
+ *}
+ */
+TCGLabel *label3 = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_LEU, hex_gpr[HEX_REG_LC0], 1, label3);
+{
+gen_jumpr(ctx, hex_gpr[HEX_REG_SA0]);
+tcg_gen_subi_tl(hex_new_value[HEX_REG_LC0],
+hex_gpr[HEX_REG_LC0], 1);
+}
+gen_set_label(label3);
+}
+
+tcg_temp_free(lpcfg);
+}
+
 static void gen_cmp_jumpnv(DisasContext *ctx,
TCGCond cond, TCGv val, TCGv src, int pc_off)
 {
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 8c007c6f07..731ec85707 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -135,6 +135,8 @@ static void gen_goto_tb(DisasContext *ctx, int idx, 
target_ulong dest)
 
 static void gen_end_tb(DisasC

[PATCH v3 10/11] Hexagon (target/hexagon) Use direct block chaining for direct jump/branch

2022-11-04 Thread Taylor Simpson
Direct block chaining is documented here
https://qemu.readthedocs.io/en/latest/devel/tcg.html#direct-block-chaining

Recall that Hexagon allows packets with multiple jumps where only the first
one with a true predicate will actually jump.  So, we can only use direct
block chaining when the packet contains a single PC-relative jump.  We add
the following to DisasContext in order to perform direct block chaining at
the end of packet commit (in gen_end_tb)
has_single_direct_branch
Indicates that we can use direct block chaining
branch_cond
The condition under which the branch is taken
branch_dest
The destination of the branch

Signed-off-by: Taylor Simpson 
---
 target/hexagon/translate.h |  3 +++
 target/hexagon/genptr.c| 13 -
 target/hexagon/translate.c | 39 +-
 3 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 96509a4da7..0841e8418e 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -57,6 +57,9 @@ typedef struct DisasContext {
 bool qreg_is_predicated[NUM_QREGS];
 int qreg_log_idx;
 bool pre_commit;
+bool has_single_direct_branch;
+TCGv branch_cond;
+target_ulong branch_dest;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 81c2ae464d..235ea9d210 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -482,7 +482,18 @@ static void gen_write_new_pc_addr(DisasContext *ctx, TCGv 
addr, TCGv pred)
 static void gen_write_new_pc_pcrel(DisasContext *ctx, int pc_off, TCGv pred)
 {
 target_ulong dest = ctx->pkt->pc + pc_off;
-gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), pred);
+if (ctx->pkt->pkt_has_multi_cof) {
+gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), pred);
+} else {
+/* Defer this jump to the end of the TB */
+g_assert(ctx->branch_cond == NULL);
+ctx->has_single_direct_branch = true;
+if (pred != NULL) {
+ctx->branch_cond = tcg_temp_local_new();
+tcg_gen_mov_tl(ctx->branch_cond, pred);
+}
+ctx->branch_dest = dest;
+}
 }
 
 static void gen_set_usr_field(int field, TCGv val)
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index fa6415936c..8c007c6f07 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -116,10 +116,44 @@ static void gen_exec_counters(DisasContext *ctx)
 hex_gpr[HEX_REG_QEMU_HVX_CNT], ctx->num_hvx_insns);
 }
 
+static bool use_goto_tb(DisasContext *ctx, target_ulong dest)
+{
+return translator_use_goto_tb(&ctx->base, dest);
+}
+
+static void gen_goto_tb(DisasContext *ctx, int idx, target_ulong dest)
+{
+if (use_goto_tb(ctx, dest)) {
+tcg_gen_goto_tb(idx);
+tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], dest);
+tcg_gen_exit_tb(ctx->base.tb, idx);
+} else {
+tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], dest);
+tcg_gen_lookup_and_goto_ptr();
+}
+}
+
 static void gen_end_tb(DisasContext *ctx)
 {
 gen_exec_counters(ctx);
-tcg_gen_exit_tb(NULL, 0);
+
+if (ctx->has_single_direct_branch) {
+if (ctx->branch_cond != NULL) {
+TCGLabel *skip = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, ctx->branch_cond, 0, skip);
+gen_goto_tb(ctx, 0, ctx->branch_dest);
+gen_set_label(skip);
+gen_goto_tb(ctx, 1, ctx->next_PC);
+tcg_temp_free(ctx->branch_cond);
+ctx->branch_cond = NULL;
+} else {
+gen_goto_tb(ctx, 0, ctx->branch_dest);
+}
+} else {
+tcg_gen_lookup_and_goto_ptr();
+}
+
+g_assert(ctx->branch_cond == NULL);
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
@@ -811,6 +845,9 @@ static void hexagon_tr_init_disas_context(DisasContextBase 
*dcbase,
 
 static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu)
 {
+DisasContext *ctx = container_of(db, DisasContext, base);
+ctx->has_single_direct_branch = false;
+ctx->branch_cond = NULL;
 }
 
 static void hexagon_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
-- 
2.17.1



[PATCH v3 06/11] Hexagon (target/hexagon) Remove next_PC from runtime state

2022-11-04 Thread Taylor Simpson
The imported files don't properly mark all CONDEXEC instructions, so
we add some logic to hex_common.py to add the attribute.

Signed-off-by: Taylor Simpson 
---
 target/hexagon/cpu.h|  1 -
 target/hexagon/gen_tcg.h|  6 ++
 target/hexagon/macros.h |  2 +-
 target/hexagon/translate.h  |  2 +-
 target/hexagon/op_helper.c  |  6 +++---
 target/hexagon/translate.c  | 29 +++--
 target/hexagon/gen_helper_funcs.py  |  4 
 target/hexagon/gen_helper_protos.py |  3 +++
 target/hexagon/gen_tcg_funcs.py |  3 +++
 target/hexagon/hex_common.py| 20 
 10 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 2a65a57bab..ff8c26272d 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -78,7 +78,6 @@ typedef struct CPUArchState {
 target_ulong gpr[TOTAL_PER_THREAD_REGS];
 target_ulong pred[NUM_PREGS];
 target_ulong branch_taken;
-target_ulong next_PC;
 
 /* For comparing with LLDB on target - see adjust_stack_ptrs function */
 target_ulong last_pc_dumped;
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index d38db72ce9..df279ab43b 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -612,6 +612,12 @@
 tcg_temp_free(tmp); \
 } while (0)
 
+#define fGEN_TCG_J2_pause(SHORTCODE) \
+do { \
+uiV = uiV; \
+tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->next_PC); \
+} while (0)
+
 /* r0 = asr(r1, r2):sat */
 #define fGEN_TCG_S2_asr_r_r_sat(SHORTCODE) \
 gen_asr_r_r_sat(RdV, RsV, RtV)
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 6e7a6a156a..903503540e 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -400,7 +400,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int 
shift)
 #endif
 #define fREAD_PC() (PC)
 
-#define fREAD_NPC() (env->next_PC & (0xfffe))
+#define fREAD_NPC() (next_PC & (0xfffe))
 
 #define fREAD_P0() (READ_PREG(0))
 #define fREAD_P3() (READ_PREG(3))
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index b8fcf615e8..96509a4da7 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -30,6 +30,7 @@ typedef struct DisasContext {
 DisasContextBase base;
 Packet *pkt;
 Insn *insn;
+uint32_t next_PC;
 uint32_t mem_idx;
 uint32_t num_packets;
 uint32_t num_insns;
@@ -134,7 +135,6 @@ static inline void ctx_log_qreg_write(DisasContext *ctx,
 
 extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
 extern TCGv hex_pred[NUM_PREGS];
-extern TCGv hex_next_PC;
 extern TCGv hex_this_PC;
 extern TCGv hex_slot_cancelled;
 extern TCGv hex_branch_taken;
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 84391e25eb..aad0195eb6 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -119,12 +119,12 @@ static void write_new_pc(CPUHexagonState *env, bool 
pkt_has_multi_cof,
   "ignoring the second one\n");
 } else {
 fCHECK_PCALIGN(addr);
-env->next_PC = addr;
+env->gpr[HEX_REG_PC] = addr;
 env->branch_taken = 1;
 }
 } else {
 fCHECK_PCALIGN(addr);
-env->next_PC = addr;
+env->gpr[HEX_REG_PC] = addr;
 }
 }
 
@@ -299,7 +299,7 @@ void HELPER(debug_commit_end)(CPUHexagonState *env, int 
has_st0, int has_st1)
 }
 }
 
-HEX_DEBUG_LOG("Next PC = " TARGET_FMT_lx "\n", env->next_PC);
+HEX_DEBUG_LOG("Next PC = " TARGET_FMT_lx "\n", env->gpr[HEX_REG_PC]);
 HEX_DEBUG_LOG("Exec counters: pkt = " TARGET_FMT_lx
   ", insn = " TARGET_FMT_lx
   ", hvx = " TARGET_FMT_lx "\n",
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 9efc6c88aa..fa6415936c 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -31,7 +31,6 @@
 
 TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
 TCGv hex_pred[NUM_PREGS];
-TCGv hex_next_PC;
 TCGv hex_this_PC;
 TCGv hex_slot_cancelled;
 TCGv hex_branch_taken;
@@ -120,7 +119,6 @@ static void gen_exec_counters(DisasContext *ctx)
 static void gen_end_tb(DisasContext *ctx)
 {
 gen_exec_counters(ctx);
-tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC);
 tcg_gen_exit_tb(NULL, 0);
 ctx->base.is_jmp = DISAS_NORETURN;
 }
@@ -128,7 +126,7 @@ static void gen_end_tb(DisasContext *ctx)
 static void gen_exception_end_tb(DisasContext *ctx, int excp)
 {
 gen_exec_counters(ctx);
-tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC);
+tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->next_PC);
 gen_exception_raw(excp);
 ctx->base.is_jmp = DISAS_NORETURN;
 
@@ -204,6 +202,24 @@ static bool need_pred_written(Packet *pkt)
 return check_for_attrib(pkt, A_WRITES_PRED_REG);
 }
 
+static bool need_next_PC(DisasContext *ctx)
+{
+Packet *pkt = ctx->pkt;
+
+/* Check for condition

[PATCH v3 08/11] Hexagon (target/hexagon) Add overrides for compound compare and jump

2022-11-04 Thread Taylor Simpson
Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h | 177 +++
 target/hexagon/genptr.c  |  72 
 2 files changed, 249 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index fe0a5e9c13..8b311d16e0 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -620,6 +620,183 @@
 #define fGEN_TCG_J2_callf(SHORTCODE) \
 gen_cond_call(ctx, PuV, false, riV)
 
+/*
+ * Compound compare and jump instructions
+ * Here is a primer to understand the tag names
+ *
+ * Comparison
+ *  cmpeqi   compare equal to an immediate
+ *  cmpgti   compare greater than an immediate
+ *  cmpgtiu  compare greater than an unsigned immediate
+ *  cmpeqn1  compare equal to negative 1
+ *  cmpgtn1  compare greater than negative 1
+ *  cmpeqcompare equal (two registers)
+ *  cmpgtu   compare greater than unsigned (two registers)
+ *  tstbit0  test bit zero
+ *
+ * Condition
+ *  tp0  p0 is true p0 = cmp.eq(r0,#5); if (p0.new) jump:nt address
+ *  fp0  p0 is falsep0 = cmp.eq(r0,#5); if (!p0.new) jump:nt 
address
+ *  tp1  p1 is true p1 = cmp.eq(r0,#5); if (p1.new) jump:nt address
+ *  fp1  p1 is falsep1 = cmp.eq(r0,#5); if (!p1.new) jump:nt 
address
+ *
+ * Prediction (not modelled in qemu)
+ *  _nt  not taken
+ *  _t   taken
+ */
+#define fGEN_TCG_J4_cmpeq_tp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_EQ, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_tp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_EQ, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_fp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_EQ, false, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_fp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_EQ, false, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_tp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_EQ, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_tp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_EQ, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_fp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_EQ, false, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_fp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_EQ, false, RsV, RtV, riV)
+
+#define fGEN_TCG_J4_cmpgt_tp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_GT, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_tp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_GT, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_fp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_GT, false, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_fp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_GT, false, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_tp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_GT, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_tp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_GT, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_fp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_GT, false, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_fp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_GT, false, RsV, RtV, riV)
+
+#define fGEN_TCG_J4_cmpgtu_tp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_GTU, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_tp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_GTU, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_fp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_GTU, false, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_fp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 0, TCG_COND_GTU, false, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_tp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_GTU, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_tp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_GTU, true, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_fp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_GTU, false, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_fp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp(ctx, 1, TCG_COND_GTU, false, RsV, RtV, riV)
+
+#define fGEN_TCG_J4_cmpeqi_tp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmpi_jmp(ctx, 0, TCG_COND_EQ, true, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_tp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmpi_jmp(ctx, 0, TCG_COND_EQ, true, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_fp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmpi_jmp(ctx, 0, TCG_COND_EQ, false, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_fp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmpi_jmp(ctx, 0, TCG_COND_EQ, false, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_tp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmpi_jmp(ctx, 1, TCG_COND_EQ, true, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_tp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmpi_jmp(ctx, 1, TCG_COND_EQ, true, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_fp1_ju

[PATCH v3 07/11] Hexagon (target/hexagon) Add overrides for direct call instructions

2022-11-04 Thread Taylor Simpson
Add overrides for
J2_call
J2_callt
J2_callf

Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h |  8 ++
 target/hexagon/genptr.c  | 55 
 2 files changed, 63 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index df279ab43b..fe0a5e9c13 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -612,6 +612,14 @@
 tcg_temp_free(tmp); \
 } while (0)
 
+#define fGEN_TCG_J2_call(SHORTCODE) \
+gen_call(ctx, riV)
+
+#define fGEN_TCG_J2_callt(SHORTCODE) \
+gen_cond_call(ctx, PuV, true, riV)
+#define fGEN_TCG_J2_callf(SHORTCODE) \
+gen_cond_call(ctx, PuV, false, riV)
+
 #define fGEN_TCG_J2_pause(SHORTCODE) \
 do { \
 uiV = uiV; \
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index c14263ae95..88e6898027 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -456,6 +456,35 @@ static TCGv gen_8bitsof(TCGv result, TCGv value)
 return result;
 }
 
+static void gen_write_new_pc_addr(DisasContext *ctx, TCGv addr, TCGv pred)
+{
+TCGLabel *pred_false = NULL;
+if (pred != NULL) {
+pred_false = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, pred, 0, pred_false);
+}
+
+if (ctx->pkt->pkt_has_multi_cof) {
+/* If there are multiple branches in a packet, ignore the second one */
+tcg_gen_movcond_tl(TCG_COND_NE, hex_gpr[HEX_REG_PC],
+   hex_branch_taken, tcg_constant_tl(0),
+   hex_gpr[HEX_REG_PC], addr);
+tcg_gen_movi_tl(hex_branch_taken, 1);
+} else {
+tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], addr);
+}
+
+if (pred != NULL) {
+gen_set_label(pred_false);
+}
+}
+
+static void gen_write_new_pc_pcrel(DisasContext *ctx, int pc_off, TCGv pred)
+{
+target_ulong dest = ctx->pkt->pc + pc_off;
+gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), pred);
+}
+
 static void gen_set_usr_field(int field, TCGv val)
 {
 tcg_gen_deposit_tl(hex_new_value[HEX_REG_USR], hex_new_value[HEX_REG_USR],
@@ -470,6 +499,32 @@ static void gen_set_usr_fieldi(int field, int x)
 gen_set_usr_field(field, val);
 }
 
+static void gen_call(DisasContext *ctx, int pc_off)
+{
+TCGv next_PC =
+tcg_constant_tl(ctx->pkt->pc + ctx->pkt->encod_pkt_size_in_bytes);
+gen_log_reg_write(HEX_REG_LR, next_PC);
+gen_write_new_pc_pcrel(ctx, pc_off, NULL);
+}
+
+static void gen_cond_call(DisasContext *ctx, TCGv pred, bool sense, int pc_off)
+{
+TCGv next_PC;
+TCGv lsb = tcg_temp_local_new();
+TCGLabel *skip = gen_new_label();
+tcg_gen_andi_tl(lsb, pred, 1);
+if (!sense) {
+tcg_gen_xori_tl(lsb, lsb, 1);
+}
+gen_write_new_pc_pcrel(ctx, pc_off, lsb);
+tcg_gen_brcondi_tl(TCG_COND_EQ, lsb, 0, skip);
+tcg_temp_free(lsb);
+next_PC =
+tcg_constant_tl(ctx->pkt->pc + ctx->pkt->encod_pkt_size_in_bytes);
+gen_log_reg_write(HEX_REG_LR, next_PC);
+gen_set_label(skip);
+}
+
 static void gen_sat_i64(TCGv_i64 dst, TCGv_i64 src, uint32_t bits)
 {
 TCGLabel *label = gen_new_label();
-- 
2.17.1



[PATCH v3 03/11] Hexagon (target/hexagon) Add overrides for S2_asr_r_r_sat/S2_asl_r_r_sat

2022-11-04 Thread Taylor Simpson
These instructions will not be generated by idef-parser, so we override
them manually.

Test cases added to tests/tcg/hexagon/usr.c

Co-authored-by: Matheus Tavares Bernardino 
Signed-off-by: Matheus Tavares Bernardino 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h |  10 ++-
 target/hexagon/genptr.c  | 173 +++
 tests/tcg/hexagon/usr.c  |  30 +--
 3 files changed, 206 insertions(+), 7 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 50634ac459..b5fe22a07a 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -612,6 +612,14 @@
 tcg_temp_free(tmp); \
 } while (0)
 
+/* r0 = asr(r1, r2):sat */
+#define fGEN_TCG_S2_asr_r_r_sat(SHORTCODE) \
+gen_asr_r_r_sat(RdV, RsV, RtV)
+
+/* r0 = asl(r1, r2):sat */
+#define fGEN_TCG_S2_asl_r_r_sat(SHORTCODE) \
+gen_asl_r_r_sat(RdV, RsV, RtV)
+
 /* Floating point */
 #define fGEN_TCG_F2_conv_sf2df(SHORTCODE) \
 gen_helper_conv_sf2df(RddV, cpu_env, RsV)
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 85416dd530..c14263ae95 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -456,6 +456,179 @@ static TCGv gen_8bitsof(TCGv result, TCGv value)
 return result;
 }
 
+static void gen_set_usr_field(int field, TCGv val)
+{
+tcg_gen_deposit_tl(hex_new_value[HEX_REG_USR], hex_new_value[HEX_REG_USR],
+   val,
+   reg_field_info[field].offset,
+   reg_field_info[field].width);
+}
+
+static void gen_set_usr_fieldi(int field, int x)
+{
+TCGv val = tcg_constant_tl(x);
+gen_set_usr_field(field, val);
+}
+
+static void gen_sat_i64(TCGv_i64 dst, TCGv_i64 src, uint32_t bits)
+{
+TCGLabel *label = gen_new_label();
+
+tcg_gen_sextract_i64(dst, src, 0, bits);
+tcg_gen_brcond_i64(TCG_COND_EQ, dst, src, label);
+{
+TCGv_i64 min = tcg_constant_i64(-(1LL << (bits - 1)));
+TCGv_i64 max = tcg_constant_i64((1LL << (bits - 1)) - 1);
+tcg_gen_movcond_i64(TCG_COND_LT, dst, src, tcg_constant_i64(0),
+min, max);
+gen_set_usr_fieldi(USR_OVF, 1);
+}
+gen_set_label(label);
+}
+
+static void gen_satval(TCGv_i64 dest, TCGv_i64 source, uint32_t bits)
+{
+TCGv_i64 min = tcg_constant_i64(-(1LL << (bits - 1)));
+TCGv_i64 max = tcg_constant_i64((1LL << (bits - 1)) - 1);
+
+gen_set_usr_fieldi(USR_OVF, 1);
+tcg_gen_movcond_i64(TCG_COND_LT, dest, source, tcg_constant_i64(0),
+min, max);
+}
+
+/* Shift left with saturation */
+static void gen_shl_sat(TCGv RdV, TCGv RsV, TCGv shift_amt)
+{
+/*
+ * int64_t A = (fCAST4_8s(RsV) << shift_amt;
+ * if (((int32_t)((fSAT(A)) ^ ((int32_t)(RsV < 0) {
+ * RdV = fSATVALN(32, ((int32_t)(RsV)))
+ * } else if (((RsV) > 0) && ((A) == 0)) {
+ * RdV = fSATVALN(32, (RsV));
+ * } else {
+ * RdV = fSAT(A);
+ * }
+ */
+TCGv_i64 RsV_i64 = tcg_temp_local_new_i64();
+TCGv_i64 shift_amt_i64 = tcg_temp_local_new_i64();
+TCGv_i64 A = tcg_temp_local_new_i64();
+TCGv_i64 A_sat_i64 = tcg_temp_local_new_i64();
+TCGv A_sat = tcg_temp_local_new();
+TCGv_i64 RdV_i64 = tcg_temp_local_new_i64();
+TCGv tmp = tcg_temp_new();
+TCGLabel *label1 = gen_new_label();
+TCGLabel *label2 = gen_new_label();
+TCGLabel *done = gen_new_label();
+
+tcg_gen_ext_i32_i64(RsV_i64, RsV);
+tcg_gen_ext_i32_i64(shift_amt_i64, shift_amt);
+tcg_gen_shl_i64(A, RsV_i64, shift_amt_i64);
+
+/* Check for saturation */
+gen_sat_i64(A_sat_i64, A, 32);
+tcg_gen_extrl_i64_i32(A_sat, A_sat_i64);
+tcg_gen_xor_tl(tmp, A_sat, RsV);
+tcg_gen_brcondi_tl(TCG_COND_GE, tmp, 0, label1);
+gen_satval(RdV_i64, RsV_i64, 32);
+tcg_gen_extrl_i64_i32(RdV, RdV_i64);
+tcg_gen_br(done);
+
+gen_set_label(label1);
+tcg_gen_brcondi_tl(TCG_COND_LE, RsV, 0, label2);
+tcg_gen_brcondi_i64(TCG_COND_NE, A, 0, label2);
+gen_satval(RdV_i64, RsV_i64, 32);
+tcg_gen_extrl_i64_i32(RdV, RdV_i64);
+tcg_gen_br(done);
+
+gen_set_label(label2);
+tcg_gen_mov_tl(RdV, A_sat);
+
+gen_set_label(done);
+
+tcg_temp_free_i64(RsV_i64);
+tcg_temp_free_i64(shift_amt_i64);
+tcg_temp_free_i64(A);
+tcg_temp_free_i64(A_sat_i64);
+tcg_temp_free(A_sat);
+tcg_temp_free_i64(RdV_i64);
+tcg_temp_free(tmp);
+}
+
+static void gen_sar(TCGv RdV, TCGv RsV, TCGv shift_amt)
+{
+/*
+ * if (shift_amt < 32) {
+ * RdV = sar(RsV, shift_amt);
+ * } else {
+ * if (RsV > 0) {
+ * RdV =

[PATCH v3 00/11] Hexagon (target/hexagon) performance and bug fixes

2022-11-04 Thread Taylor Simpson
1)
Performance improvement
Add pkt and insn to DisasContext
Many functions need information from all 3 structures, so merge
them together.

2)
Bug fix
Fix predicated assignment to .tmp and .cur


3)
Performance improvement
Add overrides for S2_asr_r_r_sat/S2_asl_r_r_sat
These functions will not be handled by idef-parser

4-11)
The final 8 patches improve change-of-flow handling.

Currently, we set the PC to a new address before exiting a TB.  The
ultimate goal is to use direct block chaining.  However, several steps
are needed along the way.

4)
When a packet has more than one change-of-flow (COF) instruction, only
the first one taken is considered.  The runtime bookkeeping is only
needed when there is more than one COF instruction in a packet.

5, 6)
Remove PC and next_PC from the runtime state and always use a
translation-time constant.  Note that next_PC is used by call instructions
to set LR and by conditional COF instructions to set the fall-through
address.

7, 8, 9)
Add helper overrides for COF instructions.  In particular, we must
distinguish those that use a PC-relative address for the destination.
These are candidates for direct block chaining later.

10)
Use direct block chaining for packets that have a single PC-relative
COF instruction.  Instead of generating the code while processing the
instruction, we record the effect in DisasContext and generate the code
during gen_end_tb.

11)
Use direct block chaining for tight loops.  We look for TBs that end
with an endloop0 that will branch back to the TB start address.


 Changes in V3 
Merge previously emailed patches into single series
Merge functions that check if vreg is preloaded

 Changes in V2 
Update test case to use both true and false predicates
Add fix for .cur
Simplify test in need_pkt_has_multi_cof
Address feedback from Matheus Tavares Bernardino 
Rearrange new-value-jump overrides
Simplify gen_write_new_pc_addr



Taylor Simpson (11):
  Hexagon (target/hexagon) Add pkt and insn to DisasContext
  Hexagon (target/hexagon) Fix predicated assignment to .tmp and .cur
  Hexagon (target/hexagon) Add overrides for
S2_asr_r_r_sat/S2_asl_r_r_sat
  Hexagon (target/hexagon) Only use branch_taken when packet has multi
cof
  Hexagon (target/hexagon) Remove PC from the runtime state
  Hexagon (target/hexagon) Remove next_PC from runtime state
  Hexagon (target/hexagon) Add overrides for direct call instructions
  Hexagon (target/hexagon) Add overrides for compound compare and jump
  Hexagon (target/hexagon) Add overrides for various forms of jump
  Hexagon (target/hexagon) Use direct block chaining for direct
jump/branch
  Hexagon (target/hexagon) Use direct block chaining for tight loops

 target/hexagon/cpu.h|  18 +-
 target/hexagon/gen_tcg.h| 400 +-
 target/hexagon/gen_tcg_hvx.h|   6 +-
 target/hexagon/insn.h   |   9 +-
 target/hexagon/macros.h |  16 +-
 target/hexagon/mmvec/macros.h   |   4 +-
 target/hexagon/translate.h  |  21 +-
 target/hexagon/decode.c |  15 +-
 target/hexagon/genptr.c | 419 +++-
 target/hexagon/op_helper.c  |  28 +-
 target/hexagon/translate.c  | 235 +++-
 tests/tcg/hexagon/hvx_misc.c|  72 +
 tests/tcg/hexagon/usr.c |  30 +-
 target/hexagon/gen_helper_funcs.py  |  13 +-
 target/hexagon/gen_helper_protos.py |  14 +-
 target/hexagon/gen_tcg_funcs.py |  38 ++-
 target/hexagon/hex_common.py|  29 +-
 17 files changed, 1229 insertions(+), 138 deletions(-)

-- 
2.17.1



[PATCH v3 05/11] Hexagon (target/hexagon) Remove PC from the runtime state

2022-11-04 Thread Taylor Simpson
Add pc field to Packet structure
For helpers that need PC, pass an extra argument
Remove slot arg from conditional jump helpers
On a trap0, copy pkt->pc into hex_gpr[HEX_REG_PC]

Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h| 7 +++
 target/hexagon/insn.h   | 1 +
 target/hexagon/macros.h | 2 +-
 target/hexagon/translate.c  | 9 +
 target/hexagon/gen_helper_funcs.py  | 4 
 target/hexagon/gen_helper_protos.py | 3 +++
 target/hexagon/gen_tcg_funcs.py | 3 +++
 target/hexagon/hex_common.py| 6 +-
 8 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index b5fe22a07a..d38db72ce9 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -750,4 +750,11 @@
 RsV = RsV; \
 } while (0)
 
+#define fGEN_TCG_J2_trap0(SHORTCODE) \
+do { \
+uiV = uiV; \
+tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->pkt->pc); \
+TCGv excp = tcg_constant_tl(HEX_EXCP_TRAP0); \
+gen_helper_raise_exception(cpu_env, excp); \
+} while (0)
 #endif
diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h
index 775c4c183d..3e7a22c91e 100644
--- a/target/hexagon/insn.h
+++ b/target/hexagon/insn.h
@@ -54,6 +54,7 @@ typedef struct Instruction Insn;
 struct Packet {
 uint16_t num_insns;
 uint16_t encod_pkt_size_in_bytes;
+uint32_t pc;
 
 /* Pre-decodes about COF */
 bool pkt_has_cof;  /* Has any change-of-flow */
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 8fd8123cec..6e7a6a156a 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -398,7 +398,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int 
shift)
 #else
 #define fREAD_GP() READ_REG(HEX_REG_GP)
 #endif
-#define fREAD_PC() (READ_REG(HEX_REG_PC))
+#define fREAD_PC() (PC)
 
 #define fREAD_NPC() (env->next_PC & (0xfffe))
 
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 1d872d72b6..9efc6c88aa 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -194,11 +194,6 @@ static bool check_for_attrib(Packet *pkt, int attrib)
 return false;
 }
 
-static bool need_pc(Packet *pkt)
-{
-return check_for_attrib(pkt, A_IMPLICIT_READS_PC);
-}
-
 static bool need_slot_cancelled(Packet *pkt)
 {
 return check_for_attrib(pkt, A_CONDEXEC);
@@ -241,9 +236,6 @@ static void gen_start_packet(DisasContext *ctx)
 }
 
 /* Initialize the runtime state for packet semantics */
-if (need_pc(pkt)) {
-tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->base.pc_next);
-}
 if (need_slot_cancelled(pkt)) {
 tcg_gen_movi_tl(hex_slot_cancelled, 0);
 }
@@ -772,6 +764,7 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 }
 
 if (decode_packet(nwords, words, &pkt, false) > 0) {
+pkt.pc = ctx->base.pc_next;
 HEX_DEBUG_PRINT_PKT(&pkt);
 ctx->pkt = &pkt;
 gen_start_packet(ctx);
diff --git a/target/hexagon/gen_helper_funcs.py 
b/target/hexagon/gen_helper_funcs.py
index c4fc609b31..024f70d166 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -241,6 +241,10 @@ def gen_helper_function(f, tag, tagregs, tagimms):
 if (hex_common.need_pkt_has_multi_cof(tag)):
 f.write(", uint32_t pkt_has_multi_cof")
 
+if hex_common.need_PC(tag):
+if i > 0: f.write(", ")
+f.write("target_ulong PC")
+i += 1
 if hex_common.need_slot(tag):
 if i > 0: f.write(", ")
 f.write("uint32_t slot")
diff --git a/target/hexagon/gen_helper_protos.py 
b/target/hexagon/gen_helper_protos.py
index 8c6b36d8d8..00c48dff7c 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -85,6 +85,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
 if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += 1
 if hex_common.need_part1(tag): def_helper_size += 1
 if hex_common.need_slot(tag): def_helper_size += 1
+if hex_common.need_PC(tag): def_helper_size += 1
 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag))
 ## The return type is void
 f.write(', void' )
@@ -93,6 +94,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
 if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += 1
 if hex_common.need_part1(tag): def_helper_size += 1
 if hex_common.need_slot(tag): def_helper_size += 1
+if hex_common.need_PC(tag): def_helper_size += 1
 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag))
 
 ## Generate the qemu DEF_HELPER type for each result
@@ -131,6 +133,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
 ## Add the arguments for the instruction pkt_has_multi_cof, slot and
 ## p

Intermittent hang on x86 replay avocado test?

2022-11-04 Thread Peter Maydell
On my machine this avocado test:

./build/all/tests/venv/bin/avocado run
./build/all/tests/avocado/replay_kernel.py:ReplayKernelNormal.test_x86_64_pc

seems to hang intermittently (maybe 1 time in 3?).

Does anybody else see this? Looking at the avocado logs suggests
the record part runs fine but the replay part hangs very early
in the kernel bootup. (Or possibly Avocado has got confused and
isn't logging all the output.)

I couldn't trigger it outside avocado.

thanks
-- PMM



Re: [PATCH] tests/qtest/ac97-test: add up-/downsampling tests

2022-11-04 Thread Thomas Huth

On 04/11/2022 18.56, Philippe Mathieu-Daudé wrote:

On 4/11/22 18:33, Thomas Huth wrote:

On 26/10/2022 21.34, Volker Rümelin wrote:

Am 25.10.22 um 09:44 schrieb Marc-André Lureau:

Hi

On Tue, Oct 25, 2022 at 12:31 AM Volker Rümelin wrote:

Am 24.10.22 um 10:13 schrieb Marc-André Lureau:

Hi

On Mon, Oct 24, 2022 at 9:28 AM Volker Rümelin
wrote:

 Test if the audio subsystem can handle extreme up- and down-
 sampling ratios like 44100/1 and 1/44100. For some time these
 used to trigger QEMU aborts. The test was taken from
 https://gitlab.com/qemu-project/qemu/-/issues/71  where it was
 used to demonstrate a very different issue.

 Suggested-by: Marc-André Lureau
 Signed-off-by: Volker Rümelin


Thanks for working on this

It seems to show something different though:
"
A bug was just triggered in audio_calloc
Save all your work and restart without audio
I am sorry
"

AUD_open_out() is called with audsettings: {freq = 1, nchannels = 2,
fmt = AUDIO_FORMAT_S16, endianness = 0}

And that's it. Any idea?

Hi,

the scary message is expected and doesn't mean this qos-test failed.
This is the currently not so silent 'the audio subsystem should (...)
silently give up' case.

Ok, but it's not silent. According to the AC97 spec, "if the value
written to the register is supported that value will be echoed back
when read, otherwise the closest (higher in case of a tie) sample rate
supported is returned". We should probably pick a low sample rate,
like 8000 (see Table 32 in spec 2.1) for anything below it.


Hi,

I don't think we should limit the lowest sample rate to 8000 Hz. The 
sample rates in AC97 revision 2.1 Table 32 are sample rates the codec 
should support at minimum. We are free to support the whole 1-65535 Hz 
sample rate range.


FWIW, a minimum sample rate of 1 Hz also does not make much sense. You 
cannot hear that frequency anymore... so it does not really make that much 
sense to support such low frequencies here. Just my 0.02 €.


Still useful when using a sound card as signal generator, i.e.:
https://www.allaboutcircuits.com/technical-articles/how-to-use-your-computer-as-an-arbitrary-waveform-generator/ 


I dare to say that you can reproduce low frequency wave forms with higher 
sample rates, too. In the example on that page, the author also reproduces a 
signal with the rate of 441 Hz with a sample rate of 22050 Hz, so I do not 
really see your point here why lower sample rates should still be useful here.


 Thomas





Re: [PATCH] tests/qtest/ac97-test: add up-/downsampling tests

2022-11-04 Thread Philippe Mathieu-Daudé

On 4/11/22 18:33, Thomas Huth wrote:

On 26/10/2022 21.34, Volker Rümelin wrote:

Am 25.10.22 um 09:44 schrieb Marc-André Lureau:

Hi

On Tue, Oct 25, 2022 at 12:31 AM Volker Rümelin  
wrote:

Am 24.10.22 um 10:13 schrieb Marc-André Lureau:

Hi

On Mon, Oct 24, 2022 at 9:28 AM Volker Rümelin
wrote:

 Test if the audio subsystem can handle extreme up- and down-
 sampling ratios like 44100/1 and 1/44100. For some time these
 used to trigger QEMU aborts. The test was taken from
 https://gitlab.com/qemu-project/qemu/-/issues/71  where it was
 used to demonstrate a very different issue.

 Suggested-by: Marc-André Lureau
 Signed-off-by: Volker Rümelin


Thanks for working on this

It seems to show something different though:
"
A bug was just triggered in audio_calloc
Save all your work and restart without audio
I am sorry
"

AUD_open_out() is called with audsettings: {freq = 1, nchannels = 2,
fmt = AUDIO_FORMAT_S16, endianness = 0}

And that's it. Any idea?

Hi,

the scary message is expected and doesn't mean this qos-test failed.
This is the currently not so silent 'the audio subsystem should (...)
silently give up' case.

Ok, but it's not silent. According to the AC97 spec, "if the value
written to the register is supported that value will be echoed back
when read, otherwise the closest (higher in case of a tie) sample rate
supported is returned". We should probably pick a low sample rate,
like 8000 (see Table 32 in spec 2.1) for anything below it.


Hi,

I don't think we should limit the lowest sample rate to 8000 Hz. The 
sample rates in AC97 revision 2.1 Table 32 are sample rates the codec 
should support at minimum. We are free to support the whole 1-65535 Hz 
sample rate range.


FWIW, a minimum sample rate of 1 Hz also does not make much sense. You 
cannot hear that frequency anymore... so it does not really make that 
much sense to support such low frequencies here. Just my 0.02 €.


Still useful when using a sound card as signal generator, i.e.:
https://www.allaboutcircuits.com/technical-articles/how-to-use-your-computer-as-an-arbitrary-waveform-generator/




Re: [PATCH] tests/qtest/e1000e-test: Use e1000_regs.h

2022-11-04 Thread Thomas Huth

On 03/11/2022 10.54, Akihiko Odaki wrote:

The register definitions in tests/qtest/e1000e-test.c had names
different from hw/net/e1000_regs.h, which made it hard to understand
what test codes corresponds to the implementation. Use
hw/net/e1000_regs.h from tests/qtest/libqos/e1000e.c to remove
these duplications.

Signed-off-by: Akihiko Odaki 
---
  tests/qtest/e1000e-test.c | 66 ++-
  1 file changed, 10 insertions(+), 56 deletions(-)

diff --git a/tests/qtest/e1000e-test.c b/tests/qtest/e1000e-test.c
index c98779c7c0..9e7cb1eb2d 100644
--- a/tests/qtest/e1000e-test.c
+++ b/tests/qtest/e1000e-test.c
@@ -33,34 +33,11 @@
  #include "qemu/bitops.h"
  #include "libqos/malloc.h"


 Hi!

Thank you for your patches! Just a very small nit: That "libqos/malloc.h" 
was still old context, the file is called "libqos/libqos-malloc.h" now - 
please make sure to send patches based on the latest git master branch. 
Anyway, it was trivial to fix up, so I've queued your patch now (together 
with your three other patches) to my testing-next branch:


 https://gitlab.com/thuth/qemu/-/commits/testing-next

 Thomas




Re: [RFC PATCH] virtio: re-order vm_running and use_started checks

2022-11-04 Thread Michael S. Tsirkin
On Fri, Nov 04, 2022 at 05:58:17PM +0100, Christian Borntraeger wrote:
> Am 04.11.22 um 17:51 schrieb Christian Borntraeger:
> > 
> > 
> > Am 04.11.22 um 17:14 schrieb Michael S. Tsirkin:
> > > On Fri, Nov 04, 2022 at 04:59:35PM +0100, Christian Borntraeger wrote:
> > > > 
> > > > 
> > > > Am 04.11.22 um 16:56 schrieb Michael S. Tsirkin:
> > > > > On Fri, Oct 14, 2022 at 02:21:08PM +0100, Alex Bennée wrote:
> > > > > > During migration the virtio device state can be restored before we
> > > > > > restart the VM. As no devices can be running while the VM is paused 
> > > > > > it
> > > > > > makes sense to bail out early in that case.
> > > > > > 
> > > > > > This returns the order introduced in:
> > > > > > 
> > > > > >    9f6bcfd99f (hw/virtio: move vm_running check to 
> > > > > > virtio_device_started)
> > > > > > 
> > > > > > to what virtio-sock was doing longhand.
> > > > > > 
> > > > > > Signed-off-by: Alex Bennée 
> > > > > > Cc: Christian Borntraeger 
> > > > > 
> > > > > 
> > > > > What happens now:
> > > > > 
> > > > > with this applied I get:
> > > > > 
> > > > > https://gitlab.com/mitsirkin/qemu/-/pipelines/685829158/failures
> > > > > 
> > > > > ― ✀  
> > > > > ―
> > > > > stderr:
> > > > > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > > > > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid 
> > > > > argument (22)
> > > > > qemu-system-arm: Failed to set msg fds.
> > > > > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid 
> > > > > argument (22)
> > > > > qemu-system-arm: -chardev 
> > > > > socket,id=chr-reconnect,path=/tmp/vhost-test-QLKXU1/reconnect.sock,server=on:
> > > > >  info: QEMU waiting for connection on: 
> > > > > disconnected:unix:/tmp/vhost-test-QLKXU1/reconnect.sock,server=on
> > > > > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > > > > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid 
> > > > > argument (22)
> > > > > qemu-system-arm: Failed to set msg fds.
> > > > > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid 
> > > > > argument (22)
> > > > > qemu-system-arm: -chardev 
> > > > > socket,id=chr-connect-fail,path=/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on:
> > > > >  info: QEMU waiting for connection on: 
> > > > > disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
> > > > > qemu-system-arm: -netdev 
> > > > > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: Failed to 
> > > > > read msg header. Read 0 instead of 12. Original request 1.
> > > > > qemu-system-arm: -netdev 
> > > > > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: 
> > > > > vhost_backend_init failed: Protocol error
> > > > > qemu-system-arm: -netdev 
> > > > > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: failed to 
> > > > > init vhost_net for queue 0
> > > > > qemu-system-arm: -netdev 
> > > > > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: info: QEMU 
> > > > > waiting for connection on: 
> > > > > disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
> > > > > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > > > > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid 
> > > > > argument (22)
> > > > > qemu-system-arm: Failed to set msg fds.
> > > > > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid 
> > > > > argument (22)
> > > > > qemu-system-arm: -chardev 
> > > > > socket,id=chr-flags-mismatch,path=/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on:
> > > > >  info: QEMU waiting for connection on: 
> > > > > disconnected:unix:/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on
> > > > > qemu-system-arm: Failed to write msg. Wrote -1 instead of 52.
> > > > > qemu-system-arm: vhost_set_mem_table failed: Invalid argument (22)
> > > > > qemu-system-arm: unable to start vhost net: 22: falling back on 
> > > > > userspace virtio
> > > > > vhost lacks feature mask 0x4000 for backend
> > > > > qemu-system-arm: failed to init vhost_net for queue 0
> > > > > qemu-system-arm: Failed to set msg fds.
> > > > > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid 
> > > > > argument (22)
> > > > > qemu-system-arm: Failed to set msg fds.
> > > > > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid 
> > > > > argument (22)
> > > > > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > > > > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid 
> > > > > argument (22)
> > > > > qemu-system-arm: Failed to set msg fds.
> > > > > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid 
> > > > > argument (22)
> > > > > qemu-system-arm: Failed to set msg fds.
> > > > > qemu-system-arm: vhost VQ 2 ring restore failed: -22: Invalid 
> > > > > argument (22)
> > > > > qemu-system-arm: Failed to set msg fds.
> > > > > qemu-system-arm: vhost VQ 3 ring restore failed: -22: Invalid 
> > > > > 

Re: [PATCH for-8.0 8/9] qdev: Remove qdev_reset_all() and qbus_reset_all()

2022-11-04 Thread Philippe Mathieu-Daudé

On 4/11/22 17:15, Peter Maydell wrote:

Remove the qdev_reset_all() and qbus_reset_all() functions, now we
have moved all the callers over to the new device_cold_reset() and
bus_cold_reset() functions.

Signed-off-by: Peter Maydell 
---
  include/hw/qdev-core.h | 26 
  hw/core/qdev.c | 54 --
  hw/core/trace-events   |  4 
  3 files changed, 84 deletions(-)



diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 0806d8fcaaa..3b0f04c5c6d 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c



-static int qbus_reset_one(BusState *bus, void *opaque)
-{
-BusClass *bc = BUS_GET_CLASS(bus);
-trace_qbus_reset(bus, object_get_typename(OBJECT(bus)));
-if (bc->reset) {
-bc->reset(bus);
-}
-return 0;
-}



diff --git a/hw/core/trace-events b/hw/core/trace-events
index 9b3ecce3b2f..d6ab5c74b90 100644
--- a/hw/core/trace-events
+++ b/hw/core/trace-events
@@ -3,11 +3,7 @@ loader_write_rom(const char *name, uint64_t gpa, uint64_t size, 
bool isrom) "%s:
  
  # qdev.c

  qdev_reset(void *obj, const char *objtype) "obj=%p(%s)"
-qdev_reset_all(void *obj, const char *objtype) "obj=%p(%s)"
-qdev_reset_tree(void *obj, const char *objtype) "obj=%p(%s)"
  qbus_reset(void *obj, const char *objtype) "obj=%p(%s)"


We can also remove the "qbus_reset" event.

Reviewed-by: Philippe Mathieu-Daudé 


-qbus_reset_all(void *obj, const char *objtype) "obj=%p(%s)"
-qbus_reset_tree(void *obj, const char *objtype) "obj=%p(%s)"
  qdev_update_parent_bus(void *obj, const char *objtype, void *oldp, const char 
*oldptype, void *newp, const char *newptype) "obj=%p(%s) old_parent=%p(%s) 
new_parent=%p(%s)"
  
  # resettable.c





Re: [RFC PATCH] virtio: re-order vm_running and use_started checks

2022-11-04 Thread Michael S. Tsirkin
On Fri, Nov 04, 2022 at 04:31:08PM +, Alex Bennée wrote:
> 
> "Michael S. Tsirkin"  writes:
> 
> > On Fri, Oct 14, 2022 at 02:21:08PM +0100, Alex Bennée wrote:
> >> During migration the virtio device state can be restored before we
> >> restart the VM. As no devices can be running while the VM is paused it
> >> makes sense to bail out early in that case.
> >> 
> >> This returns the order introduced in:
> >> 
> >>  9f6bcfd99f (hw/virtio: move vm_running check to virtio_device_started)
> >> 
> >> to what virtio-sock was doing longhand.
> >> 
> >> Signed-off-by: Alex Bennée 
> >> Cc: Christian Borntraeger 
> >
> >
> > What happens now:
> >
> > with this applied I get:
> >
> > https://gitlab.com/mitsirkin/qemu/-/pipelines/685829158/failures
> >
> > ― ✀  
> > ―
> > stderr:
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: -chardev
> > socket,id=chr-reconnect,path=/tmp/vhost-test-QLKXU1/reconnect.sock,server=on:
> > info: QEMU waiting for connection on:
> > disconnected:unix:/tmp/vhost-test-QLKXU1/reconnect.sock,server=on
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: -chardev
> > socket,id=chr-connect-fail,path=/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on:
> > info: QEMU waiting for connection on:
> > disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
> > qemu-system-arm: -netdev
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: Failed to
> > read msg header. Read 0 instead of 12. Original request 1.
> > qemu-system-arm: -netdev
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on:
> > vhost_backend_init failed: Protocol error
> > qemu-system-arm: -netdev
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: failed to
> > init vhost_net for queue 0
> > qemu-system-arm: -netdev
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: info: QEMU
> > waiting for connection on:
> > disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: -chardev
> > socket,id=chr-flags-mismatch,path=/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on:
> > info: QEMU waiting for connection on:
> > disconnected:unix:/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 52.
> > qemu-system-arm: vhost_set_mem_table failed: Invalid argument (22)
> > qemu-system-arm: unable to start vhost net: 22: falling back on userspace 
> > virtio
> > vhost lacks feature mask 0x4000 for backend
> > qemu-system-arm: failed to init vhost_net for queue 0
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 2 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 3 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost_set_vring_call failed: Invalid argume

Re: Use of unshare(CLONE_FS) in virtiofsd

2022-11-04 Thread Florian Weimer
* Vivek Goyal:

>>  The usual
>> recommendation for emulating it is to use openat with O_PATH, and then
>> use getxattr on the virtual /proc/self/fd path.  This needs an
>> additional system call (openat, getxattr, close instead of fchdir,
>> getxattr),
>
> openat(O_PATH) + getxattr(/proc/self/fd) + close() sounds reasonable
> too. Not sure why did we not take that path. May be due to that extra
> syscall or something else.

Thanks.

>> but it avoids the unshare(CLONE_FS) call behind libc's back.
>
> Hmm.., did not know that libc does not like threads calling
> unshare(CLONE_FS). Not sure why that is a problem.

Here's a corner case: We plan to add chroot detection to NSS module
loading (so that we do not load NSS modules after chroot), as a form of
security hardening.  If the application calls unshare(CLONE_FS) and then
chroot, which NSS modules are loaded depends on which threads call NSS
functions.

One could argue that chdir/chroot are problematic, not
unshare(CLONE_FS). 8-)

> BTW, we need separate umask per thread as well. During file creation 
> we might be switching to umask provide in fuse protocol message
> and then switch back. Given multiple therads might be doing this
> creation in parallel, so we ofcourse need this to be per thread
> property.

That's a good point.  That's not something that can be worked around
with *at functions.

> So if your patches for pthread_create() with per thread filesystem
> attributes finally goes upstream, I guess we should be able to
> make use of it and drop unshare(CLONE_FS).

Thank you for the feedback.

Florian




Re: [PATCH for-8.0 9/9] hw: Remove device_legacy_reset()

2022-11-04 Thread Philippe Mathieu-Daudé

On 4/11/22 17:15, Peter Maydell wrote:

The device_legacy_reset() function is now not used anywhere, so we
can remove the implementation.

Signed-off-by: Peter Maydell 
---
  include/hw/qdev-core.h |  9 -
  hw/core/qdev.c | 10 --
  2 files changed, 19 deletions(-)



-void device_legacy_reset(DeviceState *dev)
-{
-DeviceClass *klass = DEVICE_GET_CLASS(dev);
-
-trace_qdev_reset(dev, object_get_typename(OBJECT(dev)));


We can remove the "qdev_reset" entry in hw/core/trace-events.

Reviewed-by: Philippe Mathieu-Daudé 


-if (klass->reset) {
-klass->reset(dev);
-}
-}




Re: [PATCH for-8.0 7/9] Replace use of qdev_reset_all() with device_cold_reset()

2022-11-04 Thread Paul Durrant

On 04/11/2022 16:15, Peter Maydell wrote:

The legacy function qdev_reset_all() performs a recursive reset,
starting from a qdev.  However, it does not permit any of the devices
in the tree to use three-phase reset, because device reset goes
through the device_legacy_reset() function that only calls the single
DeviceClass::reset method.

Switch to using the device_cold_reset() function instead.  This also
performs a recursive reset, where first the children are reset and
then finally the parent, but it uses the new (...in 2020...)
Resettable mechanism, which supports both the old style single-reset
method and also the new 3-phase reset handling.

This commit changes the five remaining uses of this function.

Commit created with:
  sed -i -e 's/qdev_reset_all/device_cold_reset/g' hw/i386/xen/xen_platform.c 
hw/input/adb.c hw/remote/vfio-user-obj.c hw/s390x/s390-virtio-ccw.c 
hw/usb/dev-uas.c

Signed-off-by: Peter Maydell 
---
  hw/i386/xen/xen_platform.c | 2 +-


Reviewed-by: Paul Durrant 


  hw/input/adb.c | 2 +-
  hw/remote/vfio-user-obj.c  | 2 +-
  hw/s390x/s390-virtio-ccw.c | 2 +-
  hw/usb/dev-uas.c   | 2 +-
  5 files changed, 5 insertions(+), 5 deletions(-)





Re: [PATCH for-8.0 5/9] pci: Use device_cold_reset() and bus_cold_reset()

2022-11-04 Thread Philippe Mathieu-Daudé

On 4/11/22 17:15, Peter Maydell wrote:

In the PCI subsystem we currently use the legacy function
qdev_reset_all() and qbus_reset_all().  These perform a recursive
reset, starting from either a qbus or a qdev.  However they do not
permit any of the devices in the tree to use three-phase reset,
because device reset goes through the device_legacy_reset() function
that only calls the single DeviceClass::reset method.

Switch to using the device_cold_reset() and bus_cold_reset()
functions.  These also perform a recursive reset, where first the
children are reset and then finally the parent, but they use the new
(...in 2020...) Resettable mechanism, which supports both the old
style single-reset method and also the new 3-phase reset handling.

This should be a no-behaviour-change commit which just reduces the
use of a deprecated API.

Commit created with:
  sed -i -e 
's/qdev_reset_all/device_cold_reset/g;s/qbus_reset_all/bus_cold_reset/g' 
hw/pci/*.c

Signed-off-by: Peter Maydell 
---
  hw/pci/pci.c| 6 +++---
  hw/pci/pci_bridge.c | 2 +-
  2 files changed, 4 insertions(+), 4 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




[PATCH v5 2/5] linux-user/strace: Extract print_execve_argv() from print_execve()

2022-11-04 Thread Philippe Mathieu-Daudé
From: Drew DeVault 

In order to add print_execveat() which re-use common code from
print_execve(), extract print_execve_argv() from it.

Signed-off-by: Drew DeVault 
Message-Id: <20221104081015.706009-1-...@cmpwn.com>
[PMD: Split of bigger patch, filled description, fixed style]
Signed-off-by: Philippe Mathieu-Daudé 
---
 linux-user/strace.c | 71 +
 1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 25c47f0316..3d11d2f759 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -616,38 +616,6 @@ print_semctl(CPUArchState *cpu_env, const struct 
syscallname *name,
 }
 #endif
 
-static void
-print_execve(CPUArchState *cpu_env, const struct syscallname *name,
- abi_long arg1, abi_long arg2, abi_long arg3,
- abi_long arg4, abi_long arg5, abi_long arg6)
-{
-abi_ulong arg_ptr_addr;
-char *s;
-
-if (!(s = lock_user_string(arg1)))
-return;
-qemu_log("%s(\"%s\",{", name->name, s);
-unlock_user(s, arg1, 0);
-
-for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) {
-abi_ulong *arg_ptr, arg_addr;
-
-arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
-if (!arg_ptr)
-return;
-arg_addr = tswapal(*arg_ptr);
-unlock_user(arg_ptr, arg_ptr_addr, 0);
-if (!arg_addr)
-break;
-if ((s = lock_user_string(arg_addr))) {
-qemu_log("\"%s\",", s);
-unlock_user(s, arg_addr, 0);
-}
-}
-
-qemu_log("NULL})");
-}
-
 #ifdef TARGET_NR_ipc
 static void
 print_ipc(CPUArchState *cpu_env, const struct syscallname *name,
@@ -1969,6 +1937,45 @@ print_execv(CPUArchState *cpu_env, const struct 
syscallname *name,
 }
 #endif
 
+static void
+print_execve_argv(abi_long argv, int last)
+{
+abi_ulong arg_ptr_addr;
+char *s;
+
+qemu_log("{");
+for (arg_ptr_addr = argv; ; arg_ptr_addr += sizeof(abi_ulong)) {
+abi_ulong *arg_ptr, arg_addr;
+
+arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
+if (!arg_ptr) {
+return;
+}
+arg_addr = tswapal(*arg_ptr);
+unlock_user(arg_ptr, arg_ptr_addr, 0);
+if (!arg_addr) {
+break;
+}
+s = lock_user_string(arg_addr);
+if (s) {
+qemu_log("\"%s\",", s);
+unlock_user(s, arg_addr, 0);
+}
+}
+qemu_log("NULL}%s", get_comma(last));
+}
+
+static void
+print_execve(CPUArchState *cpu_env, const struct syscallname *name,
+ abi_long arg1, abi_long arg2, abi_long arg3,
+ abi_long arg4, abi_long arg5, abi_long arg6)
+{
+print_syscall_prologue(name);
+print_string(arg1, 0);
+print_execve_argv(arg2, 1);
+print_syscall_epilogue(name);
+}
+
 #if defined(TARGET_NR_faccessat) || defined(TARGET_NR_faccessat2)
 static void
 print_faccessat(CPUArchState *cpu_env, const struct syscallname *name,
-- 
2.38.1




[PATCH v5 4/5] linux-user/syscall: Extract do_execve() from do_syscall1()

2022-11-04 Thread Philippe Mathieu-Daudé
From: Drew DeVault 

execve() is a particular case of execveat(). In order
to add do_execveat(), first factor do_execve() out.

Signed-off-by: Drew DeVault 
Message-Id: <20221104081015.706009-1-...@cmpwn.com>
[PMD: Split of bigger patch, filled description, fixed style]
Signed-off-by: Philippe Mathieu-Daudé 
---
 linux-user/syscall.c | 211 +++
 1 file changed, 114 insertions(+), 97 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 24b25759be..c3ac6bb4d2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8357,6 +8357,119 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, 
const char *pathname, int
 return safe_openat(dirfd, path(pathname), flags, mode);
 }
 
+static int do_execve(CPUArchState *cpu_env,
+   abi_long pathname, abi_long guest_argp,
+   abi_long guest_envp)
+{
+int ret;
+char **argp, **envp;
+int argc, envc;
+abi_ulong gp;
+abi_ulong addr;
+char **q;
+void *p;
+
+argc = 0;
+
+for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
+if (get_user_ual(addr, gp)) {
+return -TARGET_EFAULT;
+}
+if (!addr) {
+break;
+}
+argc++;
+}
+envc = 0;
+for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
+if (get_user_ual(addr, gp)) {
+return -TARGET_EFAULT;
+}
+if (!addr) {
+break;
+}
+envc++;
+}
+
+argp = g_new0(char *, argc + 1);
+envp = g_new0(char *, envc + 1);
+
+for (gp = guest_argp, q = argp; gp; gp += sizeof(abi_ulong), q++) {
+if (get_user_ual(addr, gp)) {
+goto execve_efault;
+}
+if (!addr) {
+break;
+}
+*q = lock_user_string(addr);
+if (!*q) {
+goto execve_efault;
+}
+}
+*q = NULL;
+
+for (gp = guest_envp, q = envp; gp; gp += sizeof(abi_ulong), q++) {
+if (get_user_ual(addr, gp)) {
+goto execve_efault;
+}
+if (!addr) {
+break;
+}
+*q = lock_user_string(addr);
+if (!*q) {
+goto execve_efault;
+}
+}
+*q = NULL;
+
+/*
+ * Although execve() is not an interruptible syscall it is
+ * a special case where we must use the safe_syscall wrapper:
+ * if we allow a signal to happen before we make the host
+ * syscall then we will 'lose' it, because at the point of
+ * execve the process leaves QEMU's control. So we use the
+ * safe syscall wrapper to ensure that we either take the
+ * signal as a guest signal, or else it does not happen
+ * before the execve completes and makes it the other
+ * program's problem.
+ */
+p = lock_user_string(pathname);
+if (!p) {
+goto execve_efault;
+}
+
+if (is_proc_myself(p, "exe")) {
+ret = get_errno(safe_execve(exec_path, argp, envp));
+} else {
+ret = get_errno(safe_execve(p, argp, envp));
+}
+
+unlock_user(p, pathname, 0);
+
+goto execve_end;
+
+execve_efault:
+ret = -TARGET_EFAULT;
+
+execve_end:
+for (gp = guest_argp, q = argp; *q; gp += sizeof(abi_ulong), q++) {
+if (get_user_ual(addr, gp) || !addr) {
+break;
+}
+unlock_user(*q, addr, 0);
+}
+for (gp = guest_envp, q = envp; *q; gp += sizeof(abi_ulong), q++) {
+if (get_user_ual(addr, gp) || !addr) {
+break;
+}
+unlock_user(*q, addr, 0);
+}
+
+g_free(argp);
+g_free(envp);
+return ret;
+}
+
 #define TIMER_MAGIC 0x0caf
 #define TIMER_MAGIC_MASK 0x
 
@@ -8867,103 +8980,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 return ret;
 #endif
 case TARGET_NR_execve:
-{
-char **argp, **envp;
-int argc, envc;
-abi_ulong gp;
-abi_ulong guest_argp;
-abi_ulong guest_envp;
-abi_ulong addr;
-char **q;
-
-argc = 0;
-guest_argp = arg2;
-for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
-if (get_user_ual(addr, gp))
-return -TARGET_EFAULT;
-if (!addr)
-break;
-argc++;
-}
-envc = 0;
-guest_envp = arg3;
-for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
-if (get_user_ual(addr, gp))
-return -TARGET_EFAULT;
-if (!addr)
-break;
-envc++;
-}
-
-argp = g_new0(char *, argc + 1);
-envp = g_new0(char *, envc + 1);
-
-for (gp = guest_argp, q = argp; gp;
-  gp += sizeof(abi_ulong), q++) {
-if (get_user_ual(addr, gp))
-goto execve_efau

[PATCH v5 5/5] linux-user/syscall: Implement execveat()

2022-11-04 Thread Philippe Mathieu-Daudé
From: Drew DeVault 

References: https://gitlab.com/qemu-project/qemu/-/issues/1007
Signed-off-by: Drew DeVault 
Reviewed-by: Laurent Vivier 
Message-Id: <20221104081015.706009-1-...@cmpwn.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 linux-user/syscall.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c3ac6bb4d2..c267db9542 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -696,7 +696,8 @@ safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, 
options, \
 #endif
 safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
   int, options, struct rusage *, rusage)
-safe_syscall3(int, execve, const char *, filename, char **, argv, char **, 
envp)
+safe_syscall5(int, execveat, int, dirfd, const char *, filename,
+  char **, argv, char **, envp, int, flags)
 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
 defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
 safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, 
\
@@ -8357,9 +8358,9 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, 
const char *pathname, int
 return safe_openat(dirfd, path(pathname), flags, mode);
 }
 
-static int do_execve(CPUArchState *cpu_env,
+static int do_execveat(CPUArchState *cpu_env, int dirfd,
abi_long pathname, abi_long guest_argp,
-   abi_long guest_envp)
+   abi_long guest_envp, int flags)
 {
 int ret;
 char **argp, **envp;
@@ -8439,9 +8440,9 @@ static int do_execve(CPUArchState *cpu_env,
 }
 
 if (is_proc_myself(p, "exe")) {
-ret = get_errno(safe_execve(exec_path, argp, envp));
+ret = get_errno(safe_execveat(dirfd, exec_path, argp, envp, flags));
 } else {
-ret = get_errno(safe_execve(p, argp, envp));
+ret = get_errno(safe_execveat(dirfd, p, argp, envp, flags));
 }
 
 unlock_user(p, pathname, 0);
@@ -8979,8 +8980,10 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 unlock_user(p, arg2, 0);
 return ret;
 #endif
+case TARGET_NR_execveat:
+return do_execveat(cpu_env, arg1, arg2, arg3, arg4, arg5);
 case TARGET_NR_execve:
-return do_execve(cpu_env, arg1, arg2, arg3);
+return do_execveat(cpu_env, AT_FDCWD, arg1, arg2, arg3, 0);
 case TARGET_NR_chdir:
 if (!(p = lock_user_string(arg1)))
 return -TARGET_EFAULT;
-- 
2.38.1




[PATCH v5 1/5] linux-user/strace: Constify struct flags

2022-11-04 Thread Philippe Mathieu-Daudé
print_flags() takes a const pointer.

Signed-off-by: Philippe Mathieu-Daudé 
---
 linux-user/strace.c | 40 
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 9ae5a812cd..25c47f0316 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -945,7 +945,7 @@ print_syscall_ret_ioctl(CPUArchState *cpu_env, const struct 
syscallname *name,
 }
 #endif
 
-UNUSED static struct flags access_flags[] = {
+UNUSED static const struct flags access_flags[] = {
 FLAG_GENERIC(F_OK),
 FLAG_GENERIC(R_OK),
 FLAG_GENERIC(W_OK),
@@ -953,7 +953,7 @@ UNUSED static struct flags access_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags at_file_flags[] = {
+UNUSED static const struct flags at_file_flags[] = {
 #ifdef AT_EACCESS
 FLAG_GENERIC(AT_EACCESS),
 #endif
@@ -963,14 +963,14 @@ UNUSED static struct flags at_file_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags unlinkat_flags[] = {
+UNUSED static const struct flags unlinkat_flags[] = {
 #ifdef AT_REMOVEDIR
 FLAG_GENERIC(AT_REMOVEDIR),
 #endif
 FLAG_END,
 };
 
-UNUSED static struct flags mode_flags[] = {
+UNUSED static const struct flags mode_flags[] = {
 FLAG_GENERIC(S_IFSOCK),
 FLAG_GENERIC(S_IFLNK),
 FLAG_GENERIC(S_IFREG),
@@ -981,14 +981,14 @@ UNUSED static struct flags mode_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags open_access_flags[] = {
+UNUSED static const struct flags open_access_flags[] = {
 FLAG_TARGET(O_RDONLY),
 FLAG_TARGET(O_WRONLY),
 FLAG_TARGET(O_RDWR),
 FLAG_END,
 };
 
-UNUSED static struct flags open_flags[] = {
+UNUSED static const struct flags open_flags[] = {
 FLAG_TARGET(O_APPEND),
 FLAG_TARGET(O_CREAT),
 FLAG_TARGET(O_DIRECTORY),
@@ -1019,7 +1019,7 @@ UNUSED static struct flags open_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags mount_flags[] = {
+UNUSED static const struct flags mount_flags[] = {
 #ifdef MS_BIND
 FLAG_GENERIC(MS_BIND),
 #endif
@@ -1044,7 +1044,7 @@ UNUSED static struct flags mount_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags umount2_flags[] = {
+UNUSED static const struct flags umount2_flags[] = {
 #ifdef MNT_FORCE
 FLAG_GENERIC(MNT_FORCE),
 #endif
@@ -1057,7 +1057,7 @@ UNUSED static struct flags umount2_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags mmap_prot_flags[] = {
+UNUSED static const struct flags mmap_prot_flags[] = {
 FLAG_GENERIC(PROT_NONE),
 FLAG_GENERIC(PROT_EXEC),
 FLAG_GENERIC(PROT_READ),
@@ -1068,7 +1068,7 @@ UNUSED static struct flags mmap_prot_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags mmap_flags[] = {
+UNUSED static const struct flags mmap_flags[] = {
 FLAG_TARGET(MAP_SHARED),
 FLAG_TARGET(MAP_PRIVATE),
 FLAG_TARGET(MAP_ANONYMOUS),
@@ -1092,7 +1092,7 @@ UNUSED static struct flags mmap_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags clone_flags[] = {
+UNUSED static const struct flags clone_flags[] = {
 FLAG_GENERIC(CLONE_VM),
 FLAG_GENERIC(CLONE_FS),
 FLAG_GENERIC(CLONE_FILES),
@@ -1136,7 +1136,7 @@ UNUSED static struct flags clone_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags msg_flags[] = {
+UNUSED static const struct flags msg_flags[] = {
 /* send */
 FLAG_GENERIC(MSG_CONFIRM),
 FLAG_GENERIC(MSG_DONTROUTE),
@@ -1156,7 +1156,7 @@ UNUSED static struct flags msg_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags statx_flags[] = {
+UNUSED static const struct flags statx_flags[] = {
 #ifdef AT_EMPTY_PATH
 FLAG_GENERIC(AT_EMPTY_PATH),
 #endif
@@ -1178,7 +1178,7 @@ UNUSED static struct flags statx_flags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags statx_mask[] = {
+UNUSED static const struct flags statx_mask[] = {
 /* This must come first, because it includes everything.  */
 #ifdef STATX_ALL
 FLAG_GENERIC(STATX_ALL),
@@ -1226,7 +1226,7 @@ UNUSED static struct flags statx_mask[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags falloc_flags[] = {
+UNUSED static const struct flags falloc_flags[] = {
 FLAG_GENERIC(FALLOC_FL_KEEP_SIZE),
 FLAG_GENERIC(FALLOC_FL_PUNCH_HOLE),
 #ifdef FALLOC_FL_NO_HIDE_STALE
@@ -1246,7 +1246,7 @@ UNUSED static struct flags falloc_flags[] = {
 #endif
 };
 
-UNUSED static struct flags termios_iflags[] = {
+UNUSED static const struct flags termios_iflags[] = {
 FLAG_TARGET(IGNBRK),
 FLAG_TARGET(BRKINT),
 FLAG_TARGET(IGNPAR),
@@ -1265,7 +1265,7 @@ UNUSED static struct flags termios_iflags[] = {
 FLAG_END,
 };
 
-UNUSED static struct flags termios_oflags[] = {
+UNUSED static const struct flags termios_oflags[] = {
 FLAG_TARGET(OPOST),
 FLAG_TARGET(OLCUC),
 FLAG_TARGET(ONLCR),
@@ -1349,7 +1349,7 @@ UNUSED static struct enums termios_cflags_CSIZE[] = {
 ENUM_END,
 };
 
-UNUSED static struct flags termios_cflags[] = {
+UNUSED static const struct flags termios_cflags[] = {
 FLAG_TARG

[PATCH v5 3/5] linux-user/strace: Add output for execveat() syscall

2022-11-04 Thread Philippe Mathieu-Daudé
From: Drew DeVault 

Signed-off-by: Drew DeVault 
Message-Id: <20221104081015.706009-1-...@cmpwn.com>
Suggested-by: Helge Deller 
[PMD: Split of bigger patch]
Signed-off-by: Philippe Mathieu-Daudé 
---
 linux-user/strace.c| 23 +++
 linux-user/strace.list |  2 +-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 3d11d2f759..7bccb4f0c0 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1104,6 +1104,16 @@ UNUSED static const struct flags clone_flags[] = {
 FLAG_END,
 };
 
+UNUSED static const struct flags execveat_flags[] = {
+#ifdef AT_EMPTY_PATH
+FLAG_GENERIC(AT_EMPTY_PATH),
+#endif
+#ifdef AT_SYMLINK_NOFOLLOW
+FLAG_GENERIC(AT_SYMLINK_NOFOLLOW),
+#endif
+FLAG_END,
+};
+
 UNUSED static const struct flags msg_flags[] = {
 /* send */
 FLAG_GENERIC(MSG_CONFIRM),
@@ -1976,6 +1986,19 @@ print_execve(CPUArchState *cpu_env, const struct 
syscallname *name,
 print_syscall_epilogue(name);
 }
 
+static void
+print_execveat(CPUArchState *cpu_env, const struct syscallname *name,
+   abi_long arg1, abi_long arg2, abi_long arg3,
+   abi_long arg4, abi_long arg5, abi_long arg6)
+{
+print_syscall_prologue(name);
+print_at_dirfd(arg1, 0);
+print_string(arg2, 0);
+print_execve_argv(arg3, 0);
+print_flags(execveat_flags, arg5, 1);
+print_syscall_epilogue(name);
+}
+
 #if defined(TARGET_NR_faccessat) || defined(TARGET_NR_faccessat2)
 static void
 print_faccessat(CPUArchState *cpu_env, const struct syscallname *name,
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 3a898e2532..bb21c05414 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -164,7 +164,7 @@
 { TARGET_NR_execve, "execve" , NULL, print_execve, NULL },
 #endif
 #ifdef TARGET_NR_execveat
-{ TARGET_NR_execveat, "execveat" , NULL, NULL, NULL },
+{ TARGET_NR_execveat, "execveat" , NULL, print_execveat, NULL },
 #endif
 #ifdef TARGET_NR_exec_with_loader
 { TARGET_NR_exec_with_loader, "exec_with_loader" , NULL, NULL, NULL },
-- 
2.38.1




[PATCH v5 0/5] linux-user: implement execveat

2022-11-04 Thread Philippe Mathieu-Daudé
As I was reviewing this patch from Drew:
https://lore.kernel.org/qemu-devel/20221104081015.706009-1-...@cmpwn.com/
and it was too big for my review standards, I split it into smaller
steps. Since the result can help the other reviewers, post it.

Since v4:
- Constify struct flags
- Split Drew's patch in 4

Drew DeVault (4):
  linux-user/strace: Extract print_execve_argv() from print_execve()
  linux-user/strace: Add output for execveat() syscall
  linux-user/syscall: Extract do_execve() from do_syscall1()
  linux-user/syscall: Implement execveat()

Philippe Mathieu-Daudé (1):
  linux-user/strace: Constify struct flags

 linux-user/strace.c| 134 +++--
 linux-user/strace.list |   2 +-
 linux-user/syscall.c   | 216 ++---
 3 files changed, 201 insertions(+), 151 deletions(-)

-- 
2.38.1




Re: [PATCH] tests/qtest/ac97-test: add up-/downsampling tests

2022-11-04 Thread Thomas Huth

On 26/10/2022 21.34, Volker Rümelin wrote:

Am 25.10.22 um 09:44 schrieb Marc-André Lureau:

Hi

On Tue, Oct 25, 2022 at 12:31 AM Volker Rümelin  wrote:

Am 24.10.22 um 10:13 schrieb Marc-André Lureau:

Hi

On Mon, Oct 24, 2022 at 9:28 AM Volker Rümelin
wrote:

 Test if the audio subsystem can handle extreme up- and down-
 sampling ratios like 44100/1 and 1/44100. For some time these
 used to trigger QEMU aborts. The test was taken from
 https://gitlab.com/qemu-project/qemu/-/issues/71  where it was
 used to demonstrate a very different issue.

 Suggested-by: Marc-André Lureau
 Signed-off-by: Volker Rümelin


Thanks for working on this

It seems to show something different though:
"
A bug was just triggered in audio_calloc
Save all your work and restart without audio
I am sorry
"

AUD_open_out() is called with audsettings: {freq = 1, nchannels = 2,
fmt = AUDIO_FORMAT_S16, endianness = 0}

And that's it. Any idea?

Hi,

the scary message is expected and doesn't mean this qos-test failed.
This is the currently not so silent 'the audio subsystem should (...)
silently give up' case.

Ok, but it's not silent. According to the AC97 spec, "if the value
written to the register is supported that value will be echoed back
when read, otherwise the closest (higher in case of a tie) sample rate
supported is returned". We should probably pick a low sample rate,
like 8000 (see Table 32 in spec 2.1) for anything below it.


Hi,

I don't think we should limit the lowest sample rate to 8000 Hz. The sample 
rates in AC97 revision 2.1 Table 32 are sample rates the codec should 
support at minimum. We are free to support the whole 1-65535 Hz sample rate 
range.


FWIW, a minimum sample rate of 1 Hz also does not make much sense. You 
cannot hear that frequency anymore... so it does not really make that much 
sense to support such low frequencies here. Just my 0.02 €.


This is a convenient way to test edge cases. If you think the 
audio_bug message is an issue, I'll improve the error handling in AUD_open_* 
first and then resend this qos test.


I agree with Marc-André - the error message looks confusing when running the 
test. Maybe you could simply fence it with qtest_enable() at least?



The noaudio backend uses a mixing-engine buffer size of 1024 audio
frames and AUD_open_* tries to allocate memory for 1024/44100 = 0.0232
audio frames for the resample buffer in audio_pcm_sw_alloc_resources_*.
This allocation fails and produces the scary message. The error is
handled correctly and AUD_open_* returns NULL. AUD_read and AUD_write
return early if this pointer is NULL and the audio frontend callback
functions will also not be called because the audio_frontend_frames_*
functions return 0 in this case.

Thanks, it'd be nice to have such a description in the commit message.


I'll improve the commit message of patch version 2.


A v2 would be appreciated!

 Thanks,
  Thomas




Re: [RFC PATCH] virtio: re-order vm_running and use_started checks

2022-11-04 Thread Christian Borntraeger

Am 04.11.22 um 17:51 schrieb Christian Borntraeger:



Am 04.11.22 um 17:14 schrieb Michael S. Tsirkin:

On Fri, Nov 04, 2022 at 04:59:35PM +0100, Christian Borntraeger wrote:



Am 04.11.22 um 16:56 schrieb Michael S. Tsirkin:

On Fri, Oct 14, 2022 at 02:21:08PM +0100, Alex Bennée wrote:

During migration the virtio device state can be restored before we
restart the VM. As no devices can be running while the VM is paused it
makes sense to bail out early in that case.

This returns the order introduced in:

   9f6bcfd99f (hw/virtio: move vm_running check to virtio_device_started)

to what virtio-sock was doing longhand.

Signed-off-by: Alex Bennée 
Cc: Christian Borntraeger 



What happens now:

with this applied I get:

https://gitlab.com/mitsirkin/qemu/-/pipelines/685829158/failures

― ✀  ―
stderr:
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: -chardev 
socket,id=chr-reconnect,path=/tmp/vhost-test-QLKXU1/reconnect.sock,server=on: 
info: QEMU waiting for connection on: 
disconnected:unix:/tmp/vhost-test-QLKXU1/reconnect.sock,server=on
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: -chardev 
socket,id=chr-connect-fail,path=/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on:
 info: QEMU waiting for connection on: 
disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
qemu-system-arm: -netdev 
vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: Failed to read msg 
header. Read 0 instead of 12. Original request 1.
qemu-system-arm: -netdev 
vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: vhost_backend_init 
failed: Protocol error
qemu-system-arm: -netdev 
vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: failed to init 
vhost_net for queue 0
qemu-system-arm: -netdev 
vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: info: QEMU waiting 
for connection on: 
disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: -chardev 
socket,id=chr-flags-mismatch,path=/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on:
 info: QEMU waiting for connection on: 
disconnected:unix:/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on
qemu-system-arm: Failed to write msg. Wrote -1 instead of 52.
qemu-system-arm: vhost_set_mem_table failed: Invalid argument (22)
qemu-system-arm: unable to start vhost net: 22: falling back on userspace virtio
vhost lacks feature mask 0x4000 for backend
qemu-system-arm: failed to init vhost_net for queue 0
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 2 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 3 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost_set_vring_call failed: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost_set_vring_call failed: Invalid argument (22)
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -

Re: [RFC PATCH] virtio: re-order vm_running and use_started checks

2022-11-04 Thread Christian Borntraeger




Am 04.11.22 um 17:14 schrieb Michael S. Tsirkin:

On Fri, Nov 04, 2022 at 04:59:35PM +0100, Christian Borntraeger wrote:



Am 04.11.22 um 16:56 schrieb Michael S. Tsirkin:

On Fri, Oct 14, 2022 at 02:21:08PM +0100, Alex Bennée wrote:

During migration the virtio device state can be restored before we
restart the VM. As no devices can be running while the VM is paused it
makes sense to bail out early in that case.

This returns the order introduced in:

   9f6bcfd99f (hw/virtio: move vm_running check to virtio_device_started)

to what virtio-sock was doing longhand.

Signed-off-by: Alex Bennée 
Cc: Christian Borntraeger 



What happens now:

with this applied I get:

https://gitlab.com/mitsirkin/qemu/-/pipelines/685829158/failures

― ✀  ―
stderr:
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: -chardev 
socket,id=chr-reconnect,path=/tmp/vhost-test-QLKXU1/reconnect.sock,server=on: 
info: QEMU waiting for connection on: 
disconnected:unix:/tmp/vhost-test-QLKXU1/reconnect.sock,server=on
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: -chardev 
socket,id=chr-connect-fail,path=/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on:
 info: QEMU waiting for connection on: 
disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
qemu-system-arm: -netdev 
vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: Failed to read msg 
header. Read 0 instead of 12. Original request 1.
qemu-system-arm: -netdev 
vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: vhost_backend_init 
failed: Protocol error
qemu-system-arm: -netdev 
vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: failed to init 
vhost_net for queue 0
qemu-system-arm: -netdev 
vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: info: QEMU waiting 
for connection on: 
disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: -chardev 
socket,id=chr-flags-mismatch,path=/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on:
 info: QEMU waiting for connection on: 
disconnected:unix:/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on
qemu-system-arm: Failed to write msg. Wrote -1 instead of 52.
qemu-system-arm: vhost_set_mem_table failed: Invalid argument (22)
qemu-system-arm: unable to start vhost net: 22: falling back on userspace virtio
vhost lacks feature mask 0x4000 for backend
qemu-system-arm: failed to init vhost_net for queue 0
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 2 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 3 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost_set_vring_call failed: Invalid argument (22)
qemu-system-arm: Failed to set msg fds.
qemu-system-arm: vhost_set_vring_call failed: Invalid argument (22)
qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
qemu-system-arm: vhost VQ 0 ring restore failed: -5: Input/output error (5)
qemu-system-arm: ../hw/vir

Re: [PULL 68/86] hw/ide/piix: Ignore writes of hardwired PCI command register bits

2022-11-04 Thread Michael S. Tsirkin
On Mon, Oct 31, 2022 at 08:53:57AM -0400, Michael S. Tsirkin wrote:
> From: Lev Kujawski 
> 
> One method to enable PCI bus mastering for IDE controllers, often used
> by x86 firmware, is to write 0x7 to the PCI command register.  Neither
> the PIIX 3/4 specifications nor actual PIIX 3 hardware (a Tyan S1686D
> system) permit setting the Memory Space Enable (MSE) bit, thus the
> command register would be left in an unspecified state without this
> patch.
> 
> * hw/core/machine.c
>   Facilitate migration by not masking writes to the PIIX 3/4 PCICMD
>   register for machine states of QEMU versions prior to 7.2.
> * hw/ide/piix.c
>   a) Add a reference to the PIIX 4 data sheet.
>   b) Mask the MSE bit using the QEMU PCI device wmask field.
>   c) Define a new boolean property, x-filter-pcicmd, to control
>  whether the write mask is enabled and enable it by default
>  for both the PIIX 3 and PIIX 4 IDE controllers.
> * include/hw/ide/pci.h
>   Add the boolean filter_pcicmd field to the PCIIDEState structure,
>   because the PIIX IDE controllers do not define their own state.
> * tests/qtest/ide-test.c
>   Use the command_disabled field of the QPCIDevice testing model to
>   indicate that PCI_COMMAND_MEMORY is hardwired within PIIX 3/4 IDE
>   controllers.
> 
> Signed-off-by: Lev Kujawski 
> Message-Id: <20221024094621.512806-3-lku...@mailbox.org>
> Reviewed-by: Michael S. Tsirkin 
> Signed-off-by: Michael S. Tsirkin 


Caused test asserts reported by Stefan. Dropped for now,
pls figure the issue out and resubmit. Thanks!
> ---
>  include/hw/ide/pci.h   |  1 +
>  hw/core/machine.c  |  2 ++
>  hw/ide/piix.c  | 24 
>  tests/qtest/ide-test.c |  1 +
>  4 files changed, 28 insertions(+)
> 
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index d8384e1c42..5424b00a9e 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -53,6 +53,7 @@ struct PCIIDEState {
>  MemoryRegion bmdma_bar;
>  MemoryRegion cmd_bar[2];
>  MemoryRegion data_bar[2];
> +bool filter_pcicmd; /* used only for piix3/4 */
>  };
>  
>  static inline IDEState *bmdma_active_if(BMDMAState *bmdma)
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 907fa78ff0..65fdfe2fed 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -42,6 +42,8 @@
>  
>  GlobalProperty hw_compat_7_1[] = {
>  { "virtio-device", "queue_reset", "false" },
> +{ "piix3-ide", "x-filter-pcicmd", "false" },
> +{ "piix4-ide", "x-filter-pcicmd", "false" },
>  };
>  const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1);
>  
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index de1f4f0efb..a3af32e126 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -25,6 +25,8 @@
>   * References:
>   *  [1] 82371FB (PIIX) AND 82371SB (PIIX3) PCI ISA IDE XCELERATOR,
>   *  290550-002, Intel Corporation, April 1997.
> + *  [2] 82371AB PCI-TO-ISA / IDE XCELERATOR (PIIX4), 290562-001,
> + *  Intel Corporation, April 1997.
>   */
>  
>  #include "qemu/osdep.h"
> @@ -160,6 +162,21 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error 
> **errp)
>  uint8_t *pci_conf = dev->config;
>  int rc;
>  
> +/*
> + * Mask all IDE PCI command register bits except for Bus Master
> + * Function Enable (bit 2) and I/O Space Enable (bit 0), as the
> + * remainder are hardwired to 0 [1, p.48] [2, p.89-90].
> + *
> + * NOTE: According to the PIIX3 datasheet [1], the Memory Space
> + * Enable (MSE, bit 1) is hardwired to 1, but this is contradicted
> + * by actual PIIX3 hardware, the datasheet itself (viz., Default
> + * Value: h), and the PIIX4 datasheet [2].
> + */
> +if (d->filter_pcicmd) {
> +pci_set_word(dev->wmask + PCI_COMMAND,
> + PCI_COMMAND_MASTER | PCI_COMMAND_IO);
> +}
> +
>  pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
>  
>  bmdma_setup_bar(d);
> @@ -185,6 +202,11 @@ static void pci_piix_ide_exitfn(PCIDevice *dev)
>  }
>  }
>  
> +static Property pci_piix_ide_properties[] = {
> +DEFINE_PROP_BOOL("x-filter-pcicmd", PCIIDEState, filter_pcicmd, TRUE),
> +DEFINE_PROP_END_OF_LIST(),
> +};
> +
>  /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
>  static void piix3_ide_class_init(ObjectClass *klass, void *data)
>  {
> @@ -198,6 +220,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void 
> *data)
>  k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
>  k->class_id = PCI_CLASS_STORAGE_IDE;
>  set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> +device_class_set_props(dc, pci_piix_ide_properties);
>  dc->hotpluggable = false;
>  }
>  
> @@ -220,6 +243,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void 
> *data)
>  k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
>  k->class_id = PCI_CLASS_STORAGE_IDE;
>  set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> +device_class_set_props(dc, pci_piix_ide_properties);
> 

Re: [RFC PATCH] virtio: re-order vm_running and use_started checks

2022-11-04 Thread Alex Bennée


"Michael S. Tsirkin"  writes:

> On Fri, Oct 14, 2022 at 02:21:08PM +0100, Alex Bennée wrote:
>> During migration the virtio device state can be restored before we
>> restart the VM. As no devices can be running while the VM is paused it
>> makes sense to bail out early in that case.
>> 
>> This returns the order introduced in:
>> 
>>  9f6bcfd99f (hw/virtio: move vm_running check to virtio_device_started)
>> 
>> to what virtio-sock was doing longhand.
>> 
>> Signed-off-by: Alex Bennée 
>> Cc: Christian Borntraeger 
>
>
> What happens now:
>
> with this applied I get:
>
> https://gitlab.com/mitsirkin/qemu/-/pipelines/685829158/failures
>
> ― ✀  ―
> stderr:
> qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: -chardev
> socket,id=chr-reconnect,path=/tmp/vhost-test-QLKXU1/reconnect.sock,server=on:
> info: QEMU waiting for connection on:
> disconnected:unix:/tmp/vhost-test-QLKXU1/reconnect.sock,server=on
> qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: -chardev
> socket,id=chr-connect-fail,path=/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on:
> info: QEMU waiting for connection on:
> disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
> qemu-system-arm: -netdev
> vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: Failed to
> read msg header. Read 0 instead of 12. Original request 1.
> qemu-system-arm: -netdev
> vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on:
> vhost_backend_init failed: Protocol error
> qemu-system-arm: -netdev
> vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: failed to
> init vhost_net for queue 0
> qemu-system-arm: -netdev
> vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: info: QEMU
> waiting for connection on:
> disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
> qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: -chardev
> socket,id=chr-flags-mismatch,path=/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on:
> info: QEMU waiting for connection on:
> disconnected:unix:/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on
> qemu-system-arm: Failed to write msg. Wrote -1 instead of 52.
> qemu-system-arm: vhost_set_mem_table failed: Invalid argument (22)
> qemu-system-arm: unable to start vhost net: 22: falling back on userspace 
> virtio
> vhost lacks feature mask 0x4000 for backend
> qemu-system-arm: failed to init vhost_net for queue 0
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 2 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 3 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost_set_vring_call failed: Invalid argument (22)
> qemu-system-arm: Failed to set msg fds.
> qemu-system-arm: vhost_set_vring_call failed: Invalid argument (22)
> qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> qemu-system-arm: vhost VQ 0 ring restore failed: -5: Input/output err

[PATCH for-8.0 3/9] hw/audio/intel-hda: Drop unnecessary prototype

2022-11-04 Thread Peter Maydell
The only use of intel_hda_reset() is after its definition, so we
don't need to separately declare its prototype at the top of the
file; drop the unnecessary line.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Peter Maydell 
---
 hw/audio/intel-hda.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 38cfa20262e..b9ed231fe84 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -220,8 +220,6 @@ struct IntelHDAReg {
 void   (*rhandler)(IntelHDAState *d, const IntelHDAReg *reg);
 };
 
-static void intel_hda_reset(DeviceState *dev);
-
 /* - */
 
 static hwaddr intel_hda_addr(uint32_t lbase, uint32_t ubase)
-- 
2.25.1




[PATCH for-8.0 1/9] hw/s390x/s390-pci-inst.c: Use device_cold_reset() to reset PCI devices

2022-11-04 Thread Peter Maydell
The semantic difference between the deprecated device_legacy_reset()
function and the newer device_cold_reset() function is that the new
function resets both the device itself and any qbuses it owns,
whereas the legacy function resets just the device itself and nothing
else.

In s390-pci-inst.c we use device_legacy_reset() to reset an
S390PCIBusDevice.  This device doesn't have any child qbuses, so the
functions do the same thing and we can stop using the deprecated one.

Reviewed-by: Matthew Rosato 
Signed-off-by: Peter Maydell 
---
 hw/s390x/s390-pci-inst.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 20a9bcc7afb..16f5a3e81b4 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -272,7 +272,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
 stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP);
 goto out;
 }
-device_legacy_reset(DEVICE(pbdev));
+device_cold_reset(DEVICE(pbdev));
 pbdev->fh &= ~FH_MASK_ENABLE;
 pbdev->state = ZPCI_FS_DISABLED;
 stl_p(&ressetpci->fh, pbdev->fh);
-- 
2.25.1




[PATCH for-8.0 4/9] hw/usb/hcd-xhci: Reset the XHCIState with device_cold_reset()

2022-11-04 Thread Peter Maydell
Currently the hcd-xhci-pci and hcd-xhci-sysbus devices, which are
mostly wrappers around the TYPE_XHCI device, which is a direct
subclass of TYPE_DEVICE.  Since TYPE_DEVICE devices are not on any
qbus and do not get automatically reset, the wrapper devices both
reset the TYPE_XHCI device in their own reset functions.  However,
they do this using device_legacy_reset(), which will reset the device
itself but not any bus it has.

Switch to device_cold_reset(), which avoids using a deprecated
function and also propagates reset along any child buses.

Signed-off-by: Peter Maydell 
---
It's possible this might result in USB devices on the bus getting
reset more than once (once via the descent-along-qbus and once when
xhci_reset() etc manually reset each port), but in my testing with
gdb I couldn't get that to happen.  It should be harmless anyway.
---
 hw/usb/hcd-xhci-pci.c| 2 +-
 hw/usb/hcd-xhci-sysbus.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c
index e934b1a5b1f..643d4643e4d 100644
--- a/hw/usb/hcd-xhci-pci.c
+++ b/hw/usb/hcd-xhci-pci.c
@@ -85,7 +85,7 @@ static void xhci_pci_reset(DeviceState *dev)
 {
 XHCIPciState *s = XHCI_PCI(dev);
 
-device_legacy_reset(DEVICE(&s->xhci));
+device_cold_reset(DEVICE(&s->xhci));
 }
 
 static int xhci_pci_vmstate_post_load(void *opaque, int version_id)
diff --git a/hw/usb/hcd-xhci-sysbus.c b/hw/usb/hcd-xhci-sysbus.c
index a14e4381960..faf57b47975 100644
--- a/hw/usb/hcd-xhci-sysbus.c
+++ b/hw/usb/hcd-xhci-sysbus.c
@@ -29,7 +29,7 @@ void xhci_sysbus_reset(DeviceState *dev)
 {
 XHCISysbusState *s = XHCI_SYSBUS(dev);
 
-device_legacy_reset(DEVICE(&s->xhci));
+device_cold_reset(DEVICE(&s->xhci));
 }
 
 static void xhci_sysbus_realize(DeviceState *dev, Error **errp)
-- 
2.25.1




[PATCH for-8.0 9/9] hw: Remove device_legacy_reset()

2022-11-04 Thread Peter Maydell
The device_legacy_reset() function is now not used anywhere, so we
can remove the implementation.

Signed-off-by: Peter Maydell 
---
 include/hw/qdev-core.h |  9 -
 hw/core/qdev.c | 10 --
 2 files changed, 19 deletions(-)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index c7eda169d78..35fddb19a64 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -776,15 +776,6 @@ BusState *sysbus_get_default(void);
 char *qdev_get_fw_dev_path(DeviceState *dev);
 char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev);
 
-/**
- * device_legacy_reset:
- *
- * Reset a single device (by calling the reset method).
- * Note: This function is deprecated and will be removed when it becomes 
unused.
- * Please use device_cold_reset() now.
- */
-void device_legacy_reset(DeviceState *dev);
-
 void device_class_set_props(DeviceClass *dc, Property *props);
 
 /**
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 3b0f04c5c6d..2743191efe7 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -857,16 +857,6 @@ void device_class_set_parent_unrealize(DeviceClass *dc,
 dc->unrealize = dev_unrealize;
 }
 
-void device_legacy_reset(DeviceState *dev)
-{
-DeviceClass *klass = DEVICE_GET_CLASS(dev);
-
-trace_qdev_reset(dev, object_get_typename(OBJECT(dev)));
-if (klass->reset) {
-klass->reset(dev);
-}
-}
-
 Object *qdev_get_machine(void)
 {
 static Object *dev;
-- 
2.25.1




Re: [PULL 04/10] libvhost-user: Fix wrong type of argument to formatting function (reported by LGTM)

2022-11-04 Thread Laurent Vivier

Hi Stefan,

Le 03/11/2022 à 17:17, Laurent Vivier a écrit :

From: Stefan Weil 

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Stefan Weil 
Message-Id: <20220422070144.1043697-2...@weilnetz.de>
Signed-off-by: Laurent Vivier 
---
  subprojects/libvhost-user/libvhost-user.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/subprojects/libvhost-user/libvhost-user.c 
b/subprojects/libvhost-user/libvhost-user.c
index ffed4729a3dc..d9a6e3e5560f 100644
--- a/subprojects/libvhost-user/libvhost-user.c
+++ b/subprojects/libvhost-user/libvhost-user.c
@@ -651,7 +651,7 @@ generate_faults(VuDev *dev) {
  
  if (ioctl(dev->postcopy_ufd, UFFDIO_REGISTER, ®_struct)) {

  vu_panic(dev, "%s: Failed to userfault region %d "
-  "@%p + size:%zx offset: %zx: (ufd=%d)%s\n",
+  "@%" PRIx64 " + size:%zx offset: %zx: (ufd=%d)%s\n",
   __func__, i,
   dev_region->mmap_addr,
   dev_region->size, dev_region->mmap_offset,


They all need PRIx64:

typedef struct VuDevRegion {
/* Guest Physical address. */
uint64_t gpa;
/* Memory region size. */
uint64_t size;
/* QEMU virtual address (userspace). */
uint64_t qva;
/* Starting offset in our mmaped space. */
uint64_t mmap_offset;
/* Start address of mmaped space. */
uint64_t mmap_addr;
} VuDevRegion;

Could you fix your patch?

Thanks,
Laurent



[PATCH for-8.0 5/9] pci: Use device_cold_reset() and bus_cold_reset()

2022-11-04 Thread Peter Maydell
In the PCI subsystem we currently use the legacy function
qdev_reset_all() and qbus_reset_all().  These perform a recursive
reset, starting from either a qbus or a qdev.  However they do not
permit any of the devices in the tree to use three-phase reset,
because device reset goes through the device_legacy_reset() function
that only calls the single DeviceClass::reset method.

Switch to using the device_cold_reset() and bus_cold_reset()
functions.  These also perform a recursive reset, where first the
children are reset and then finally the parent, but they use the new
(...in 2020...) Resettable mechanism, which supports both the old
style single-reset method and also the new 3-phase reset handling.

This should be a no-behaviour-change commit which just reduces the
use of a deprecated API.

Commit created with:
 sed -i -e 
's/qdev_reset_all/device_cold_reset/g;s/qbus_reset_all/bus_cold_reset/g' 
hw/pci/*.c

Signed-off-by: Peter Maydell 
---
 hw/pci/pci.c| 6 +++---
 hw/pci/pci_bridge.c | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 2f450f6a728..9d819cbe3b3 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -378,14 +378,14 @@ static void pci_do_device_reset(PCIDevice *dev)
  */
 void pci_device_reset(PCIDevice *dev)
 {
-qdev_reset_all(&dev->qdev);
+device_cold_reset(&dev->qdev);
 pci_do_device_reset(dev);
 }
 
 /*
  * Trigger pci bus reset under a given bus.
- * Called via qbus_reset_all on RST# assert, after the devices
- * have been reset qdev_reset_all-ed already.
+ * Called via bus_cold_reset on RST# assert, after the devices
+ * have been reset device_cold_reset-ed already.
  */
 static void pcibus_reset(BusState *qbus)
 {
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index da34c8ebcd1..b2b180edd61 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -275,7 +275,7 @@ void pci_bridge_write_config(PCIDevice *d,
 newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
 if (~oldctl & newctl & PCI_BRIDGE_CTL_BUS_RESET) {
 /* Trigger hot reset on 0->1 transition. */
-qbus_reset_all(BUS(&s->sec_bus));
+bus_cold_reset(BUS(&s->sec_bus));
 }
 }
 
-- 
2.25.1




[PATCH for-8.0 7/9] Replace use of qdev_reset_all() with device_cold_reset()

2022-11-04 Thread Peter Maydell
The legacy function qdev_reset_all() performs a recursive reset,
starting from a qdev.  However, it does not permit any of the devices
in the tree to use three-phase reset, because device reset goes
through the device_legacy_reset() function that only calls the single
DeviceClass::reset method.

Switch to using the device_cold_reset() function instead.  This also
performs a recursive reset, where first the children are reset and
then finally the parent, but it uses the new (...in 2020...)
Resettable mechanism, which supports both the old style single-reset
method and also the new 3-phase reset handling.

This commit changes the five remaining uses of this function.

Commit created with:
 sed -i -e 's/qdev_reset_all/device_cold_reset/g' hw/i386/xen/xen_platform.c 
hw/input/adb.c hw/remote/vfio-user-obj.c hw/s390x/s390-virtio-ccw.c 
hw/usb/dev-uas.c

Signed-off-by: Peter Maydell 
---
 hw/i386/xen/xen_platform.c | 2 +-
 hw/input/adb.c | 2 +-
 hw/remote/vfio-user-obj.c  | 2 +-
 hw/s390x/s390-virtio-ccw.c | 2 +-
 hw/usb/dev-uas.c   | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index a64265cca07..7db0d94ec28 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -177,7 +177,7 @@ static void pci_xen_ide_unplug(DeviceState *dev, bool aux)
 blk_unref(blk);
 }
 }
-qdev_reset_all(dev);
+device_cold_reset(dev);
 }
 
 static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque)
diff --git a/hw/input/adb.c b/hw/input/adb.c
index 84331b9fce6..214ae6f42b3 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -43,7 +43,7 @@ static const char *adb_commands[] = {
 
 static void adb_device_reset(ADBDevice *d)
 {
-qdev_reset_all(DEVICE(d));
+device_cold_reset(DEVICE(d));
 }
 
 static int do_adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf,
diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c
index c6cc53acf2d..6ff14e0b9c0 100644
--- a/hw/remote/vfio-user-obj.c
+++ b/hw/remote/vfio-user-obj.c
@@ -685,7 +685,7 @@ static int vfu_object_device_reset(vfu_ctx_t *vfu_ctx, 
vfu_reset_type_t type)
 return 0;
 }
 
-qdev_reset_all(DEVICE(o->pci_dev));
+device_cold_reset(DEVICE(o->pci_dev));
 
 return 0;
 }
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 806de32034c..13a9ca62800 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -110,7 +110,7 @@ static void subsystem_reset(void)
 for (i = 0; i < ARRAY_SIZE(reset_dev_types); i++) {
 dev = DEVICE(object_resolve_path_type("", reset_dev_types[i], NULL));
 if (dev) {
-qdev_reset_all(dev);
+device_cold_reset(dev);
 }
 }
 }
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 5192b062d6f..88f99c05d53 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -791,7 +791,7 @@ static void usb_uas_task(UASDevice *uas, uas_iu *iu)
 
 case UAS_TMF_LOGICAL_UNIT_RESET:
 trace_usb_uas_tmf_logical_unit_reset(uas->dev.addr, tag, lun);
-qdev_reset_all(&dev->qdev);
+device_cold_reset(&dev->qdev);
 usb_uas_queue_response(uas, tag, UAS_RC_TMF_COMPLETE);
 break;
 
-- 
2.25.1




[PATCH for-8.0 0/9] reset: Remove some deprecated APIs

2022-11-04 Thread Peter Maydell
This patchset removes the remaining uses of some deprecated
reset-related APIs:
 * device_legacy_reset() -- replaced with device_cold_reset()
   (conversions require some thought)
 * qdev_reset_all() -- replaced with device_cold_reset()
   (mechanical no-behaviour-change conversion)
 * qbus_reset_all() -- replaced with bus_cold_reset()
   (mechanical no-behaviour-change conversion)

The first four patches have been on the list already; the
first three have been reviewed.

Mostly just tested with 'make check' and 'make check-avocado'.

This is of course all for-8.0 material, but I figured I
might as well push it out on list for review, especially
since I have some followup stuff that depends on this.

thanks
-- PMM

Peter Maydell (9):
  hw/s390x/s390-pci-inst.c: Use device_cold_reset() to reset PCI devices
  hw/audio/intel-hda: don't reset codecs twice
  hw/audio/intel-hda: Drop unnecessary prototype
  hw/usb/hcd-xhci: Reset the XHCIState with device_cold_reset()
  pci: Use device_cold_reset() and bus_cold_reset()
  hw/hyperv/vmbus: Use device_cold_reset() and bus_cold_reset()
  Replace use of qdev_reset_all() with device_cold_reset()
  qdev: Remove qdev_reset_all() and qbus_reset_all()
  hw: Remove device_legacy_reset()

 include/hw/qdev-core.h | 35 -
 hw/audio/intel-hda.c   |  6 +---
 hw/core/qdev.c | 64 --
 hw/hyperv/vmbus.c  |  4 +--
 hw/i386/xen/xen_platform.c |  2 +-
 hw/input/adb.c |  2 +-
 hw/pci/pci.c   |  6 ++--
 hw/pci/pci_bridge.c|  2 +-
 hw/remote/vfio-user-obj.c  |  2 +-
 hw/s390x/s390-pci-inst.c   |  2 +-
 hw/s390x/s390-virtio-ccw.c |  2 +-
 hw/usb/dev-uas.c   |  2 +-
 hw/usb/hcd-xhci-pci.c  |  2 +-
 hw/usb/hcd-xhci-sysbus.c   |  2 +-
 hw/core/trace-events   |  4 ---
 15 files changed, 15 insertions(+), 122 deletions(-)

-- 
2.25.1




[PATCH for-8.0 8/9] qdev: Remove qdev_reset_all() and qbus_reset_all()

2022-11-04 Thread Peter Maydell
Remove the qdev_reset_all() and qbus_reset_all() functions, now we
have moved all the callers over to the new device_cold_reset() and
bus_cold_reset() functions.

Signed-off-by: Peter Maydell 
---
 include/hw/qdev-core.h | 26 
 hw/core/qdev.c | 54 --
 hw/core/trace-events   |  4 
 3 files changed, 84 deletions(-)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 785dd5a56ef..c7eda169d78 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -743,32 +743,6 @@ int qdev_walk_children(DeviceState *dev,
qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
void *opaque);
 
-/**
- * @qdev_reset_all:
- * Reset @dev. See @qbus_reset_all() for more details.
- *
- * Note: This function is deprecated and will be removed when it becomes 
unused.
- * Please use device_cold_reset() now.
- */
-void qdev_reset_all(DeviceState *dev);
-void qdev_reset_all_fn(void *opaque);
-
-/**
- * @qbus_reset_all:
- * @bus: Bus to be reset.
- *
- * Reset @bus and perform a bus-level ("hard") reset of all devices connected
- * to it, including recursive processing of all buses below @bus itself.  A
- * hard reset means that qbus_reset_all will reset all state of the device.
- * For PCI devices, for example, this will include the base address registers
- * or configuration space.
- *
- * Note: This function is deprecated and will be removed when it becomes 
unused.
- * Please use bus_cold_reset() now.
- */
-void qbus_reset_all(BusState *bus);
-void qbus_reset_all_fn(void *opaque);
-
 /**
  * device_cold_reset:
  * Reset device @dev and perform a recursive processing using the resettable
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 0806d8fcaaa..3b0f04c5c6d 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -237,60 +237,6 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int 
alias_id,
 dev->alias_required_for_version = required_for_version;
 }
 
-static int qdev_prereset(DeviceState *dev, void *opaque)
-{
-trace_qdev_reset_tree(dev, object_get_typename(OBJECT(dev)));
-return 0;
-}
-
-static int qbus_prereset(BusState *bus, void *opaque)
-{
-trace_qbus_reset_tree(bus, object_get_typename(OBJECT(bus)));
-return 0;
-}
-
-static int qdev_reset_one(DeviceState *dev, void *opaque)
-{
-device_legacy_reset(dev);
-
-return 0;
-}
-
-static int qbus_reset_one(BusState *bus, void *opaque)
-{
-BusClass *bc = BUS_GET_CLASS(bus);
-trace_qbus_reset(bus, object_get_typename(OBJECT(bus)));
-if (bc->reset) {
-bc->reset(bus);
-}
-return 0;
-}
-
-void qdev_reset_all(DeviceState *dev)
-{
-trace_qdev_reset_all(dev, object_get_typename(OBJECT(dev)));
-qdev_walk_children(dev, qdev_prereset, qbus_prereset,
-   qdev_reset_one, qbus_reset_one, NULL);
-}
-
-void qdev_reset_all_fn(void *opaque)
-{
-qdev_reset_all(DEVICE(opaque));
-}
-
-void qbus_reset_all(BusState *bus)
-{
-trace_qbus_reset_all(bus, object_get_typename(OBJECT(bus)));
-qbus_walk_children(bus, qdev_prereset, qbus_prereset,
-   qdev_reset_one, qbus_reset_one, NULL);
-}
-
-void qbus_reset_all_fn(void *opaque)
-{
-BusState *bus = opaque;
-qbus_reset_all(bus);
-}
-
 void device_cold_reset(DeviceState *dev)
 {
 resettable_reset(OBJECT(dev), RESET_TYPE_COLD);
diff --git a/hw/core/trace-events b/hw/core/trace-events
index 9b3ecce3b2f..d6ab5c74b90 100644
--- a/hw/core/trace-events
+++ b/hw/core/trace-events
@@ -3,11 +3,7 @@ loader_write_rom(const char *name, uint64_t gpa, uint64_t 
size, bool isrom) "%s:
 
 # qdev.c
 qdev_reset(void *obj, const char *objtype) "obj=%p(%s)"
-qdev_reset_all(void *obj, const char *objtype) "obj=%p(%s)"
-qdev_reset_tree(void *obj, const char *objtype) "obj=%p(%s)"
 qbus_reset(void *obj, const char *objtype) "obj=%p(%s)"
-qbus_reset_all(void *obj, const char *objtype) "obj=%p(%s)"
-qbus_reset_tree(void *obj, const char *objtype) "obj=%p(%s)"
 qdev_update_parent_bus(void *obj, const char *objtype, void *oldp, const char 
*oldptype, void *newp, const char *newptype) "obj=%p(%s) old_parent=%p(%s) 
new_parent=%p(%s)"
 
 # resettable.c
-- 
2.25.1




[PATCH for-8.0 2/9] hw/audio/intel-hda: don't reset codecs twice

2022-11-04 Thread Peter Maydell
Currently the intel-hda device has a reset method which manually
resets all the codecs by calling device_legacy_reset() on them.  This
means they get reset twice, once because child devices on a qbus get
reset before the parent device's reset method is called, and then
again because we're manually resetting them.

Drop the manual reset call, and ensure that codecs are still reset
when the guest does a reset via ICH6_GCTL_RESET by using
device_cold_reset() (which resets all the devices on the qbus as well
as the device itself) instead of a direct call to the reset function.

This is a slight ordering change because the (only) codec reset now
happens before the controller registers etc are reset, rather than
once before and then once after, but the codec reset function
hda_audio_reset() doesn't care.

This lets us drop a use of device_legacy_reset(), which is
deprecated.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Peter Maydell 
---
 hw/audio/intel-hda.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index f38117057b9..38cfa20262e 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -516,7 +516,7 @@ static void intel_hda_notify_codecs(IntelHDAState *d, 
uint32_t stream, bool runn
 static void intel_hda_set_g_ctl(IntelHDAState *d, const IntelHDAReg *reg, 
uint32_t old)
 {
 if ((d->g_ctl & ICH6_GCTL_RESET) == 0) {
-intel_hda_reset(DEVICE(d));
+device_cold_reset(DEVICE(d));
 }
 }
 
@@ -1083,11 +1083,9 @@ static void intel_hda_reset(DeviceState *dev)
 intel_hda_regs_reset(d);
 d->wall_base_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
-/* reset codecs */
 QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) {
 DeviceState *qdev = kid->child;
 cdev = HDA_CODEC_DEVICE(qdev);
-device_legacy_reset(DEVICE(cdev));
 d->state_sts |= (1 << cdev->cad);
 }
 intel_hda_update_irq(d);
-- 
2.25.1




[PATCH for-8.0 6/9] hw/hyperv/vmbus: Use device_cold_reset() and bus_cold_reset()

2022-11-04 Thread Peter Maydell
In the vmbus code we currently use the legacy functions
qdev_reset_all() and qbus_reset_all().  These perform a recursive
reset, starting from either a qbus or a qdev.  However they do not
permit any of the devices in the tree to use three-phase reset,
because device reset goes through the device_legacy_reset() function
that only calls the single DeviceClass::reset method.

Switch to using the device_cold_reset() and bus_cold_reset()
functions.  These also perform a recursive reset, where first the
children are reset and then finally the parent, but they use the new
(...in 2020...) Resettable mechanism, which supports both the old
style single-reset method and also the new 3-phase reset handling.

This should be a no-behaviour-change commit which just reduces the
use of a deprecated API.

Commit created with:
  sed -i -e 
's/qdev_reset_all/device_cold_reset/g;s/qbus_reset_all/bus_cold_reset/g' 
hw/hyperv/*.c

Signed-off-by: Peter Maydell 
---
 hw/hyperv/vmbus.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c
index 30bc04e1c4c..f345f310b0f 100644
--- a/hw/hyperv/vmbus.c
+++ b/hw/hyperv/vmbus.c
@@ -1578,7 +1578,7 @@ static bool vmbus_initialized(VMBus *vmbus)
 
 static void vmbus_reset_all(VMBus *vmbus)
 {
-qbus_reset_all(BUS(vmbus));
+bus_cold_reset(BUS(vmbus));
 }
 
 static void post_msg(VMBus *vmbus, void *msgdata, uint32_t msglen)
@@ -2035,7 +2035,7 @@ static void vdev_reset_on_close(VMBusDevice *vdev)
 }
 
 /* all channels closed -- reset device */
-qdev_reset_all(DEVICE(vdev));
+device_cold_reset(DEVICE(vdev));
 }
 
 static void handle_close_channel(VMBus *vmbus, vmbus_message_close_channel 
*msg,
-- 
2.25.1




Re: [PATCH v3 00/30] qapi: Elide redundant has_FOO in generated C

2022-11-04 Thread Markus Armbruster
Markus Armbruster  writes:

> In QAPI, absent optional members are distinct from any present value.
> We thus represent an optional schema member FOO as two C members: a
> FOO with the member's type, and a bool has_FOO.  Likewise for function
> arguments.
>
> However, the has_FOO is actually redundant for a pointer-valued FOO,
> which can be null only when has_FOO is false, i.e. has_FOO == !!FOO.
> Except for arrays, where we a null FOO can also be a present empty
> array.
>
> The redundant has_FOO are a nuisance to work with.  Improve the
> generator to elide them.
>
> PATCH 01+02 are trivial documentation cleanups.
>
> PATCH 03 tweaks an example in documentation so it'll show the change.
>
> PATCH 04 improves the code generator, but nerfs the change for the
> schema modules where handwritten code needs to be updated.
>
> PATCH 05-07,10-29 un-nerf in reviewable chunks.  Their commit messages
> refer back to PATCH 04 for an explanation of the transformation.
> Please read that first.  Note that these patches combine the
> mechanical transformation with obvious, local follow-up
> simplifications.  If you want them separate for easier review, let me
> know.
>
> PATCH 08+09 clean up in preparation for PATCH 10.
>
> PATCH 28 drops the nerfing code.

PATCH 30, of course.




Re: [RFC PATCH] virtio: re-order vm_running and use_started checks

2022-11-04 Thread Michael S. Tsirkin
On Fri, Nov 04, 2022 at 04:59:35PM +0100, Christian Borntraeger wrote:
> 
> 
> Am 04.11.22 um 16:56 schrieb Michael S. Tsirkin:
> > On Fri, Oct 14, 2022 at 02:21:08PM +0100, Alex Bennée wrote:
> > > During migration the virtio device state can be restored before we
> > > restart the VM. As no devices can be running while the VM is paused it
> > > makes sense to bail out early in that case.
> > > 
> > > This returns the order introduced in:
> > > 
> > >   9f6bcfd99f (hw/virtio: move vm_running check to virtio_device_started)
> > > 
> > > to what virtio-sock was doing longhand.
> > > 
> > > Signed-off-by: Alex Bennée 
> > > Cc: Christian Borntraeger 
> > 
> > 
> > What happens now:
> > 
> > with this applied I get:
> > 
> > https://gitlab.com/mitsirkin/qemu/-/pipelines/685829158/failures
> > 
> > ― ✀  
> > ―
> > stderr:
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: -chardev 
> > socket,id=chr-reconnect,path=/tmp/vhost-test-QLKXU1/reconnect.sock,server=on:
> >  info: QEMU waiting for connection on: 
> > disconnected:unix:/tmp/vhost-test-QLKXU1/reconnect.sock,server=on
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: -chardev 
> > socket,id=chr-connect-fail,path=/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on:
> >  info: QEMU waiting for connection on: 
> > disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
> > qemu-system-arm: -netdev 
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: Failed to read 
> > msg header. Read 0 instead of 12. Original request 1.
> > qemu-system-arm: -netdev 
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: 
> > vhost_backend_init failed: Protocol error
> > qemu-system-arm: -netdev 
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: failed to init 
> > vhost_net for queue 0
> > qemu-system-arm: -netdev 
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: info: QEMU 
> > waiting for connection on: 
> > disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: -chardev 
> > socket,id=chr-flags-mismatch,path=/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on:
> >  info: QEMU waiting for connection on: 
> > disconnected:unix:/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 52.
> > qemu-system-arm: vhost_set_mem_table failed: Invalid argument (22)
> > qemu-system-arm: unable to start vhost net: 22: falling back on userspace 
> > virtio
> > vhost lacks feature mask 0x4000 for backend
> > qemu-system-arm: failed to init vhost_net for queue 0
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 2 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 3 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.

Re: [RFC PATCH] virtio: re-order vm_running and use_started checks

2022-11-04 Thread Michael S. Tsirkin
On Fri, Nov 04, 2022 at 04:59:35PM +0100, Christian Borntraeger wrote:
> 
> 
> Am 04.11.22 um 16:56 schrieb Michael S. Tsirkin:
> > On Fri, Oct 14, 2022 at 02:21:08PM +0100, Alex Bennée wrote:
> > > During migration the virtio device state can be restored before we
> > > restart the VM. As no devices can be running while the VM is paused it
> > > makes sense to bail out early in that case.
> > > 
> > > This returns the order introduced in:
> > > 
> > >   9f6bcfd99f (hw/virtio: move vm_running check to virtio_device_started)
> > > 
> > > to what virtio-sock was doing longhand.
> > > 
> > > Signed-off-by: Alex Bennée 
> > > Cc: Christian Borntraeger 
> > 
> > 
> > What happens now:
> > 
> > with this applied I get:
> > 
> > https://gitlab.com/mitsirkin/qemu/-/pipelines/685829158/failures
> > 
> > ― ✀  
> > ―
> > stderr:
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: -chardev 
> > socket,id=chr-reconnect,path=/tmp/vhost-test-QLKXU1/reconnect.sock,server=on:
> >  info: QEMU waiting for connection on: 
> > disconnected:unix:/tmp/vhost-test-QLKXU1/reconnect.sock,server=on
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: -chardev 
> > socket,id=chr-connect-fail,path=/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on:
> >  info: QEMU waiting for connection on: 
> > disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
> > qemu-system-arm: -netdev 
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: Failed to read 
> > msg header. Read 0 instead of 12. Original request 1.
> > qemu-system-arm: -netdev 
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: 
> > vhost_backend_init failed: Protocol error
> > qemu-system-arm: -netdev 
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: failed to init 
> > vhost_net for queue 0
> > qemu-system-arm: -netdev 
> > vhost-user,id=hs0,chardev=chr-connect-fail,vhostforce=on: info: QEMU 
> > waiting for connection on: 
> > disconnected:unix:/tmp/vhost-test-L9Q6U1/connect-fail.sock,server=on
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: -chardev 
> > socket,id=chr-flags-mismatch,path=/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on:
> >  info: QEMU waiting for connection on: 
> > disconnected:unix:/tmp/vhost-test-3MO5U1/flags-mismatch.sock,server=on
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 52.
> > qemu-system-arm: vhost_set_mem_table failed: Invalid argument (22)
> > qemu-system-arm: unable to start vhost net: 22: falling back on userspace 
> > virtio
> > vhost lacks feature mask 0x4000 for backend
> > qemu-system-arm: failed to init vhost_net for queue 0
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 2 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 3 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to write msg. Wrote -1 instead of 20.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.
> > qemu-system-arm: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> > qemu-system-arm: Failed to set msg fds.

[PULL 0/1] VFIO fix for v7.2-rc0

2022-11-04 Thread Alex Williamson
The following changes since commit ece5f8374d0416a339f0c0a9399faa2c42d4ad6f:

  Merge tag 'linux-user-for-7.2-pull-request' of 
https://gitlab.com/laurent_vivier/qemu into staging (2022-11-03 10:55:05 -0400)

are available in the Git repository at:

  https://gitlab.com/alex.williamson/qemu.git tags/vfio-fixes-v7.2-rc0.0

for you to fetch changes up to 2461e752199ca457bf0973b6c8a77dc30585809c:

  vfio/migration: Fix wrong enum usage (2022-11-03 15:57:31 -0600)


VFIO fixes for v7.2-rc0

 * Correct initial migration device state using correct v1
   protocol enum (Avihai Horon)


Avihai Horon (1):
  vfio/migration: Fix wrong enum usage

 hw/vfio/migration.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)




[PATCH v3 08/30] blockdev: Clean up abuse of DriveBackup member format

2022-11-04 Thread Markus Armbruster
drive-backup argument @format defaults to the format of the source
unless @mode is "existing".

drive_backup_prepare() implements this by copying the source's
@format_name to DriveBackup member @format.  It leaves @has_format
false, violating the "has_format == !!format" invariant.  Unclean.
Falls apart when we elide @has_format (commit after next): then QAPI
passes @format, which is a string constant, to g_free().  iotest 056
duly explodes.

Clean it up.  Since the value stored in member @format is not actually
used outside this function, use a local variable instead of modifying
the QAPI object.

Signed-off-by: Markus Armbruster 
Cc: Kevin Wolf 
Cc: Hanna Reitz 
Cc: qemu-bl...@nongnu.org
---
 blockdev.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 3f1dec6242..d6550e0dc8 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1686,6 +1686,7 @@ static void drive_backup_prepare(BlkActionState *common, 
Error **errp)
 BlockDriverState *source = NULL;
 AioContext *aio_context;
 AioContext *old_context;
+const char *format;
 QDict *options;
 Error *local_err = NULL;
 int flags;
@@ -1717,9 +1718,9 @@ static void drive_backup_prepare(BlkActionState *common, 
Error **errp)
 /* Paired with .clean() */
 bdrv_drained_begin(bs);
 
-if (!backup->has_format) {
-backup->format = backup->mode == NEW_IMAGE_MODE_EXISTING ?
- NULL : (char *) bs->drv->format_name;
+format = backup->format;
+if (!format && backup->mode != NEW_IMAGE_MODE_EXISTING) {
+format = bs->drv->format_name;
 }
 
 /* Early check to avoid creating target */
@@ -1758,19 +1759,19 @@ static void drive_backup_prepare(BlkActionState 
*common, Error **errp)
 }
 
 if (backup->mode != NEW_IMAGE_MODE_EXISTING) {
-assert(backup->format);
+assert(format);
 if (source) {
 /* Implicit filters should not appear in the filename */
 BlockDriverState *explicit_backing =
 bdrv_skip_implicit_filters(source);
 
 bdrv_refresh_filename(explicit_backing);
-bdrv_img_create(backup->target, backup->format,
+bdrv_img_create(backup->target, format,
 explicit_backing->filename,
 explicit_backing->drv->format_name, NULL,
 size, flags, false, &local_err);
 } else {
-bdrv_img_create(backup->target, backup->format, NULL, NULL, NULL,
+bdrv_img_create(backup->target, format, NULL, NULL, NULL,
 size, flags, false, &local_err);
 }
 }
@@ -1783,8 +1784,8 @@ static void drive_backup_prepare(BlkActionState *common, 
Error **errp)
 options = qdict_new();
 qdict_put_str(options, "discard", "unmap");
 qdict_put_str(options, "detect-zeroes", "unmap");
-if (backup->format) {
-qdict_put_str(options, "driver", backup->format);
+if (format) {
+qdict_put_str(options, "driver", format);
 }
 
 target_bs = bdrv_open(backup->target, NULL, options, flags, errp);
-- 
2.37.3




[PATCH v3 23/30] qapi run-state: Elide redundant has_FOO in generated C

2022-11-04 Thread Markus Armbruster
The has_FOO for pointer-valued FOO are redundant, except for arrays.
They are also a nuisance to work with.  Recent commit "qapi: Start to
elide redundant has_FOO in generated C" provided the means to elide
them step by step.  This is the step for qapi/run-state.json.

Said commit explains the transformation in more detail.  The invariant
violations mentioned there do not occur here.

Drop a superfluous conditional around
qapi_free_GuestPanicInformation() while there.

Cc: Paolo Bonzini 
Signed-off-by: Markus Armbruster 
Reviewed-by: Philippe Mathieu-Daudé 
---
 softmmu/runstate.c | 18 +-
 scripts/qapi/schema.py |  1 -
 2 files changed, 5 insertions(+), 14 deletions(-)

diff --git a/softmmu/runstate.c b/softmmu/runstate.c
index 3dd83d5e5d..cab9f6fc07 100644
--- a/softmmu/runstate.c
+++ b/softmmu/runstate.c
@@ -484,18 +484,15 @@ void qemu_system_guest_panicked(GuestPanicInformation 
*info)
  */
 if (panic_action == PANIC_ACTION_PAUSE
 || (panic_action == PANIC_ACTION_SHUTDOWN && shutdown_action == 
SHUTDOWN_ACTION_PAUSE)) {
-qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE,
-!!info, info);
+qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, info);
 vm_stop(RUN_STATE_GUEST_PANICKED);
 } else if (panic_action == PANIC_ACTION_SHUTDOWN ||
panic_action == PANIC_ACTION_EXIT_FAILURE) {
-qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
-   !!info, info);
+qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF, info);
 vm_stop(RUN_STATE_GUEST_PANICKED);
 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
 } else {
-qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_RUN,
-!!info, info);
+qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_RUN, info);
 }
 
 if (info) {
@@ -522,13 +519,8 @@ void qemu_system_guest_panicked(GuestPanicInformation 
*info)
 void qemu_system_guest_crashloaded(GuestPanicInformation *info)
 {
 qemu_log_mask(LOG_GUEST_ERROR, "Guest crash loaded");
-
-qapi_event_send_guest_crashloaded(GUEST_PANIC_ACTION_RUN,
-   !!info, info);
-
-if (info) {
-qapi_free_GuestPanicInformation(info);
-}
+qapi_event_send_guest_crashloaded(GUEST_PANIC_ACTION_RUN, info);
+qapi_free_GuestPanicInformation(info);
 }
 
 void qemu_system_reset_request(ShutdownCause reason)
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index 1b3195bc87..f405ab7f49 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -759,7 +759,6 @@ def need_has(self):
 assert self.type
 # Temporary hack to support dropping the has_FOO in reviewable chunks
 opt_out = [
-'qapi/run-state.json',
 'qapi/stats.json',
 'qapi/tpm.json',
 'qapi/transaction.json',
-- 
2.37.3




[PATCH v3 22/30] qapi rocker: Elide redundant has_FOO in generated C

2022-11-04 Thread Markus Armbruster
The has_FOO for pointer-valued FOO are redundant, except for arrays.
They are also a nuisance to work with.  Recent commit "qapi: Start to
elide redundant has_FOO in generated C" provided the means to elide
them step by step.  This is the step for qapi/rocker.json.

Said commit explains the transformation in more detail.  The invariant
violations mentioned there do not occur here.

Cc: Jiri Pirko 
Signed-off-by: Markus Armbruster 
---
 hw/net/rocker/rocker_of_dpa.c | 13 ++---
 monitor/hmp-cmds.c| 22 +++---
 scripts/qapi/schema.py|  1 -
 3 files changed, 13 insertions(+), 23 deletions(-)

diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
index b3b8c5bb6d..dfe4754469 100644
--- a/hw/net/rocker/rocker_of_dpa.c
+++ b/hw/net/rocker/rocker_of_dpa.c
@@ -2348,23 +2348,19 @@ static void of_dpa_flow_fill(void *cookie, void *value, 
void *user_data)
 
 if (memcmp(key->eth.src.a, zero_mac.a, ETH_ALEN) ||
 memcmp(mask->eth.src.a, zero_mac.a, ETH_ALEN)) {
-nkey->has_eth_src = true;
 nkey->eth_src = qemu_mac_strdup_printf(key->eth.src.a);
 }
 
-if (nkey->has_eth_src && memcmp(mask->eth.src.a, ff_mac.a, ETH_ALEN)) {
-nmask->has_eth_src = true;
+if (nkey->eth_src && memcmp(mask->eth.src.a, ff_mac.a, ETH_ALEN)) {
 nmask->eth_src = qemu_mac_strdup_printf(mask->eth.src.a);
 }
 
 if (memcmp(key->eth.dst.a, zero_mac.a, ETH_ALEN) ||
 memcmp(mask->eth.dst.a, zero_mac.a, ETH_ALEN)) {
-nkey->has_eth_dst = true;
 nkey->eth_dst = qemu_mac_strdup_printf(key->eth.dst.a);
 }
 
-if (nkey->has_eth_dst && memcmp(mask->eth.dst.a, ff_mac.a, ETH_ALEN)) {
-nmask->has_eth_dst = true;
+if (nkey->eth_dst && memcmp(mask->eth.dst.a, ff_mac.a, ETH_ALEN)) {
 nmask->eth_dst = qemu_mac_strdup_printf(mask->eth.dst.a);
 }
 
@@ -2400,7 +2396,6 @@ static void of_dpa_flow_fill(void *cookie, void *value, 
void *user_data)
 if (key->ipv4.addr.dst || mask->ipv4.addr.dst) {
 char *dst = inet_ntoa(*(struct in_addr *)&key->ipv4.addr.dst);
 int dst_len = of_dpa_mask2prefix(mask->ipv4.addr.dst);
-nkey->has_ip_dst = true;
 nkey->ip_dst = g_strdup_printf("%s/%d", dst, dst_len);
 }
 break;
@@ -2501,12 +2496,10 @@ static void of_dpa_group_fill(void *key, void *value, 
void *user_data)
 ngroup->set_vlan_id = ntohs(group->l2_rewrite.vlan_id);
 }
 if (memcmp(group->l2_rewrite.src_mac.a, zero_mac.a, ETH_ALEN)) {
-ngroup->has_set_eth_src = true;
 ngroup->set_eth_src =
 qemu_mac_strdup_printf(group->l2_rewrite.src_mac.a);
 }
 if (memcmp(group->l2_rewrite.dst_mac.a, zero_mac.a, ETH_ALEN)) {
-ngroup->has_set_eth_dst = true;
 ngroup->set_eth_dst =
 qemu_mac_strdup_printf(group->l2_rewrite.dst_mac.a);
 }
@@ -2532,12 +2525,10 @@ static void of_dpa_group_fill(void *key, void *value, 
void *user_data)
 ngroup->set_vlan_id = ntohs(group->l3_unicast.vlan_id);
 }
 if (memcmp(group->l3_unicast.src_mac.a, zero_mac.a, ETH_ALEN)) {
-ngroup->has_set_eth_src = true;
 ngroup->set_eth_src =
 qemu_mac_strdup_printf(group->l3_unicast.src_mac.a);
 }
 if (memcmp(group->l3_unicast.dst_mac.a, zero_mac.a, ETH_ALEN)) {
-ngroup->has_set_eth_dst = true;
 ngroup->set_eth_dst =
 qemu_mac_strdup_printf(group->l3_unicast.dst_mac.a);
 }
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index ae5ebe765a..a41f94a34a 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -2010,35 +2010,35 @@ void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict 
*qdict)
 }
 }
 
-if (key->has_eth_src) {
+if (key->eth_src) {
 if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) &&
-(mask->has_eth_src) &&
+mask->eth_src &&
 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
 monitor_printf(mon, " src ");
 } else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) &&
-(mask->has_eth_src) &&
+mask->eth_src &&
 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
 monitor_printf(mon, " src ");
 } else {
 monitor_printf(mon, " src %s", key->eth_src);
-if (mask->has_eth_src) {
+if (mask->eth_src) {
 monitor_printf(mon, "(%s)", mask->eth_src);
 }
 }
 }
 
-if (key->has_eth_dst) {
+if (key->eth_dst) {
 if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) &&
-(mask->has_eth_dst) &&
+mask->eth_dst &&
 (strcmp(mas

[PATCH v3 02/30] qapi: Tidy up whitespace in generated code

2022-11-04 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Daniel P. Berrangé 
---
 docs/devel/qapi-code-gen.rst | 1 -
 scripts/qapi/commands.py | 7 +++
 scripts/qapi/events.py   | 1 -
 3 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst
index 997313fce7..b56ea4546d 100644
--- a/docs/devel/qapi-code-gen.rst
+++ b/docs/devel/qapi-code-gen.rst
@@ -1664,7 +1664,6 @@ Example::
 $ cat qapi-generated/example-qapi-commands.c
 [Uninteresting stuff omitted...]
 
-
 static void qmp_marshal_output_UserDefOne(UserDefOne *ret_in,
 QObject **ret_out, Error **errp)
 {
diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index 38ca38a7b9..cf68aaf0bf 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -83,7 +83,7 @@ def gen_call(name: str,
 
 trace_qmp_enter_%(name)s(req_json->str);
 }
-''',
+''',
  upper=upper, name=name)
 
 ret += mcgen('''
@@ -124,13 +124,13 @@ def gen_call(name: str,
 
 trace_qmp_exit_%(name)s(ret_json->str, true);
 }
-''',
+''',
  upper=upper, name=name)
 else:
 ret += mcgen('''
 
 trace_qmp_exit_%(name)s("{}", true);
-''',
+''',
  name=name)
 
 return ret
@@ -316,7 +316,6 @@ def _begin_user_module(self, name: str) -> None:
 #include "qapi/error.h"
 #include "%(visit)s.h"
 #include "%(commands)s.h"
-
 ''',
  commands=commands, visit=visit))
 
diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
index 27b44c49f5..e762d53d19 100644
--- a/scripts/qapi/events.py
+++ b/scripts/qapi/events.py
@@ -196,7 +196,6 @@ def _begin_user_module(self, name: str) -> None:
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp-event.h"
-
 ''',
  events=events, visit=visit,
  prefix=self._prefix))
-- 
2.37.3




[PATCH v3 11/30] qapi chardev: Elide redundant has_FOO in generated C

2022-11-04 Thread Markus Armbruster
The has_FOO for pointer-valued FOO are redundant, except for arrays.
They are also a nuisance to work with.  Recent commit "qapi: Start to
elide redundant has_FOO in generated C" provided the means to elide
them step by step.  This is the step for qapi/char.json.

Said commit explains the transformation in more detail.  The invariant
violations mentioned there do not occur here.

Cc: Marc-André Lureau 
Cc: Paolo Bonzini 
Signed-off-by: Markus Armbruster 
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Philippe Mathieu-Daudé 
---
 chardev/char-file.c|  4 ++--
 chardev/char-socket.c  | 10 --
 chardev/char-udp.c |  1 -
 chardev/char.c |  6 +-
 tests/unit/test-char.c |  1 -
 scripts/qapi/schema.py |  1 -
 6 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/chardev/char-file.c b/chardev/char-file.c
index 2fd80707e5..3a7b9caf6f 100644
--- a/chardev/char-file.c
+++ b/chardev/char-file.c
@@ -45,7 +45,7 @@ static void qmp_chardev_open_file(Chardev *chr,
 DWORD accessmode;
 DWORD flags;
 
-if (file->has_in) {
+if (file->in) {
 error_setg(errp, "input file not supported");
 return;
 }
@@ -83,7 +83,7 @@ static void qmp_chardev_open_file(Chardev *chr,
 return;
 }
 
-if (file->has_in) {
+if (file->in) {
 flags = O_RDONLY;
 in = qmp_chardev_open_file_source(file->in, flags, errp);
 if (in < 0) {
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 879564aa8a..29ffe5075e 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1251,7 +1251,7 @@ static bool qmp_chardev_validate_socket(ChardevSocket 
*sock,
"'fd' address type");
 return false;
 }
-if (sock->has_tls_creds &&
+if (sock->tls_creds &&
 !(sock->has_server && sock->server)) {
 error_setg(errp,
"'tls_creds' option is incompatible with "
@@ -1261,7 +1261,7 @@ static bool qmp_chardev_validate_socket(ChardevSocket 
*sock,
 break;
 
 case SOCKET_ADDRESS_TYPE_UNIX:
-if (sock->has_tls_creds) {
+if (sock->tls_creds) {
 error_setg(errp,
"'tls_creds' option is incompatible with "
"'unix' address type");
@@ -1273,7 +1273,7 @@ static bool qmp_chardev_validate_socket(ChardevSocket 
*sock,
 break;
 
 case SOCKET_ADDRESS_TYPE_VSOCK:
-if (sock->has_tls_creds) {
+if (sock->tls_creds) {
 error_setg(errp,
"'tls_creds' option is incompatible with "
"'vsock' address type");
@@ -1284,7 +1284,7 @@ static bool qmp_chardev_validate_socket(ChardevSocket 
*sock,
 break;
 }
 
-if (sock->has_tls_authz && !sock->has_tls_creds) {
+if (sock->tls_authz && !sock->tls_creds) {
 error_setg(errp, "'tls_authz' option requires 'tls_creds' option");
 return false;
 }
@@ -1465,9 +1465,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, 
ChardevBackend *backend,
 sock->wait = qemu_opt_get_bool(opts, "wait", true);
 sock->has_reconnect = qemu_opt_find(opts, "reconnect");
 sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0);
-sock->has_tls_creds = qemu_opt_get(opts, "tls-creds");
 sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
-sock->has_tls_authz = qemu_opt_get(opts, "tls-authz");
 sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));
 
 addr = g_new0(SocketAddressLegacy, 1);
diff --git a/chardev/char-udp.c b/chardev/char-udp.c
index 6756e69924..3d9a2d5e77 100644
--- a/chardev/char-udp.c
+++ b/chardev/char-udp.c
@@ -178,7 +178,6 @@ static void qemu_chr_parse_udp(QemuOpts *opts, 
ChardevBackend *backend,
 udp->remote = addr;
 
 if (has_local) {
-udp->has_local = true;
 addr = g_new0(SocketAddressLegacy, 1);
 addr->type = SOCKET_ADDRESS_TYPE_INET;
 addr->u.inet.data = g_new(InetSocketAddress, 1);
diff --git a/chardev/char.c b/chardev/char.c
index b005df3ccf..4c5de16402 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -240,7 +240,7 @@ static void qemu_char_open(Chardev *chr, ChardevBackend 
*backend,
 /* Any ChardevCommon member would work */
 ChardevCommon *common = backend ? backend->u.null.data : NULL;
 
-if (common && common->has_logfile) {
+if (common && common->logfile) {
 int flags = O_WRONLY;
 if (common->has_logappend &&
 common->logappend) {
@@ -496,9 +496,7 @@ void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon 
*backend)
 {
 const char *logfile = qemu_opt_get(opts, "logfile");
 
-backend->has_logfile = logfile != NULL;
 backend->logfile = g_strdup(logfile);
-
 backend->has_logappend = true;
 backend->logappend = qemu_opt_get_bool(opts, "logappend", false);
 }
@@ -1057,7 +1055,6 @@ ChardevReturn *qmp_chardev_add(const char *id, 
ChardevBackend *backend,
 ret = g_new

[PATCH v3 10/30] qapi block: Elide redundant has_FOO in generated C

2022-11-04 Thread Markus Armbruster
The has_FOO for pointer-valued FOO are redundant, except for arrays.
They are also a nuisance to work with.  Recent commit "qapi: Start to
elide redundant has_FOO in generated C" provided the means to elide
them step by step.  This is the step for qapi/block*.json.

Said commit explains the transformation in more detail.

There is one instance of the invariant violation mentioned there:
qcow2_signal_corruption() passes false, "" when node_name is an empty
string.  Take care to pass NULL then.

The previous two commits cleaned up two more.

Additionally, helper bdrv_latency_histogram_stats() loses its output
parameters and returns a value instead.

Cc: Kevin Wolf 
Cc: Hanna Reitz 
Cc: qemu-bl...@nongnu.org
Signed-off-by: Markus Armbruster 
---
 block/block-backend.c  |   2 +-
 block/copy-before-write.c  |   2 +-
 block/dirty-bitmap.c   |   1 -
 block/export/export.c  |   2 +-
 block/export/vduse-blk.c   |   3 +-
 block/gluster.c|   3 -
 block/monitor/block-hmp-cmds.c |  48 --
 block/qapi-sysemu.c|  73 +--
 block/qapi.c   |  62 +
 block/qcow.c   |  10 +-
 block/qcow2.c  |  18 ++--
 block/qed.c|   2 +-
 block/quorum.c |   2 +-
 block/rbd.c|  15 +--
 block/ssh.c|   2 +-
 blockdev-nbd.c |   9 +-
 blockdev.c | 164 +
 blockjob.c |   2 -
 monitor/hmp-cmds.c |   3 +-
 qemu-img.c |  13 ++-
 qemu-nbd.c |   2 -
 scripts/qapi/schema.py |   3 -
 22 files changed, 167 insertions(+), 274 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index c0c7d56c8d..4c9aaec14a 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1859,7 +1859,7 @@ static void send_qmp_error_event(BlockBackend *blk,
 BlockDriverState *bs = blk_bs(blk);
 
 optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE;
-qapi_event_send_block_io_error(blk_name(blk), !!bs,
+qapi_event_send_block_io_error(blk_name(blk),
bs ? bdrv_get_node_name(bs) : NULL, optype,
action, blk_iostatus_is_enabled(blk),
error == ENOSPC, strerror(error));
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index 4abaa7339e..b28ae25ec1 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -432,7 +432,7 @@ static int cbw_open(BlockDriverState *bs, QDict *options, 
int flags,
 return -EINVAL;
 }
 
-if (opts->has_bitmap) {
+if (opts->bitmap) {
 bitmap = block_dirty_bitmap_lookup(opts->bitmap->node,
opts->bitmap->name, NULL, errp);
 if (!bitmap) {
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index bf3dc0512a..9c39550698 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -541,7 +541,6 @@ BlockDirtyInfoList 
*bdrv_query_dirty_bitmaps(BlockDriverState *bs)
 
 info->count = bdrv_get_dirty_count(bm);
 info->granularity = bdrv_dirty_bitmap_granularity(bm);
-info->has_name = !!bm->name;
 info->name = g_strdup(bm->name);
 info->recording = bdrv_dirty_bitmap_recording(bm);
 info->busy = bdrv_dirty_bitmap_busy(bm);
diff --git a/block/export/export.c b/block/export/export.c
index 7cc0c25c1c..28a91c9c42 100644
--- a/block/export/export.c
+++ b/block/export/export.c
@@ -114,7 +114,7 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error 
**errp)
 ctx = bdrv_get_aio_context(bs);
 aio_context_acquire(ctx);
 
-if (export->has_iothread) {
+if (export->iothread) {
 IOThread *iothread;
 AioContext *new_ctx;
 Error **set_context_errp;
diff --git a/block/export/vduse-blk.c b/block/export/vduse-blk.c
index f101c24c3f..350d6fdaf0 100644
--- a/block/export/vduse-blk.c
+++ b/block/export/vduse-blk.c
@@ -265,8 +265,7 @@ static int vduse_blk_exp_create(BlockExport *exp, 
BlockExportOptions *opts,
 }
 vblk_exp->num_queues = num_queues;
 vblk_exp->handler.blk = exp->blk;
-vblk_exp->handler.serial = g_strdup(vblk_opts->has_serial ?
-vblk_opts->serial : "");
+vblk_exp->handler.serial = g_strdup(vblk_opts->serial ?: "");
 vblk_exp->handler.logical_block_size = logical_block_size;
 vblk_exp->handler.writable = opts->writable;
 
diff --git a/block/gluster.c b/block/gluster.c
index 7c90f7ba4b..7efc296399 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -830,7 +830,6 @@ static int qemu_gluster_open(BlockDriverState *bs,  QDict 
*options,
 s->logfile = g_strdup(logfile ? logfile : GLUSTER_LOGFILE_DEFAULT);
 
 gconf->logfile = g_strdup(s->logfile);
-gconf->has_logfile = true;
 
 s-

[PULL 1/1] vfio/migration: Fix wrong enum usage

2022-11-04 Thread Alex Williamson
From: Avihai Horon 

vfio_migration_init() initializes VFIOMigration->device_state using enum
of VFIO migration protocol v2. Current implemented protocol is v1 so v1
enum should be used. Fix it.

Fixes: 429c72800654 ("vfio/migration: Fix incorrect initialization value for 
parameters in VFIOMigration")
Signed-off-by: Avihai Horon 
Reviewed-by: Zhang Chen 
Link: https://lore.kernel.org/r/20221016085752.32740-1-avih...@nvidia.com
Signed-off-by: Alex Williamson 
---
 hw/vfio/migration.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 3de4252111ee..c74453e0b5e0 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -806,7 +806,7 @@ static int vfio_migration_init(VFIODevice *vbasedev,
 }
 
 vbasedev->migration = g_new0(VFIOMigration, 1);
-vbasedev->migration->device_state = VFIO_DEVICE_STATE_RUNNING;
+vbasedev->migration->device_state = VFIO_DEVICE_STATE_V1_RUNNING;
 vbasedev->migration->vm_running = runstate_is_running();
 
 ret = vfio_region_setup(obj, vbasedev, &vbasedev->migration->region,





[PATCH v3 29/30] qapi qga: Elide redundant has_FOO in generated C

2022-11-04 Thread Markus Armbruster
The has_FOO for pointer-valued FOO are redundant, except for arrays.
They are also a nuisance to work with.  Recent commit "qapi: Start to
elide redundant has_FOO in generated C" provided the means to elide
them step by step.  This is the step for qga/qapi-schema.json.

Said commit explains the transformation in more detail.  The invariant
violations mentioned there do not occur here.

Cc: Michael Roth 
Cc: Konstantin Kostiuk 
Signed-off-by: Markus Armbruster 
---
 qga/commands-posix.c   | 32 
 qga/commands-win32.c   | 40 +++-
 qga/commands.c | 11 ---
 scripts/qapi/schema.py |  3 +--
 4 files changed, 20 insertions(+), 66 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 32493d6383..1a28326ec7 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -71,7 +71,7 @@ static void ga_wait_child(pid_t pid, int *status, Error 
**errp)
 g_assert(rpid == pid);
 }
 
-void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp)
+void qmp_guest_shutdown(const char *mode, Error **errp)
 {
 const char *shutdown_flag;
 Error *local_err = NULL;
@@ -93,7 +93,7 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, 
Error **errp)
 #endif
 
 slog("guest-shutdown called, mode: %s", mode);
-if (!has_mode || strcmp(mode, "powerdown") == 0) {
+if (!mode || strcmp(mode, "powerdown") == 0) {
 shutdown_flag = powerdown_flag;
 } else if (strcmp(mode, "halt") == 0) {
 shutdown_flag = halt_flag;
@@ -404,14 +404,14 @@ end:
 return f;
 }
 
-int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode,
+int64_t qmp_guest_file_open(const char *path, const char *mode,
 Error **errp)
 {
 FILE *fh;
 Error *local_err = NULL;
 int64_t handle;
 
-if (!has_mode) {
+if (!mode) {
 mode = "r";
 }
 slog("guest-file-open called, filepath: %s, mode: %s", path, mode);
@@ -1037,7 +1037,6 @@ static bool build_guest_fsinfo_for_ccw_dev(char const 
*syspath,
 return false;
 }
 
-disk->has_ccw_address = true;
 disk->ccw_address = g_new0(GuestCCWAddress, 1);
 disk->ccw_address->cssid = cssid;
 disk->ccw_address->ssid = ssid;
@@ -1084,12 +1083,10 @@ static void build_guest_fsinfo_for_real_device(char 
const *syspath,
 devnode = udev_device_get_devnode(udevice);
 if (devnode != NULL) {
 disk->dev = g_strdup(devnode);
-disk->has_dev = true;
 }
 serial = udev_device_get_property_value(udevice, "ID_SERIAL");
 if (serial != NULL && *serial != 0) {
 disk->serial = g_strdup(serial);
-disk->has_serial = true;
 }
 }
 
@@ -1108,7 +1105,7 @@ static void build_guest_fsinfo_for_real_device(char const 
*syspath,
 has_hwinf = false;
 }
 
-if (has_hwinf || disk->has_dev || disk->has_serial) {
+if (has_hwinf || disk->dev || disk->serial) {
 QAPI_LIST_PREPEND(fs->disk, disk);
 } else {
 qapi_free_GuestDiskAddress(disk);
@@ -1411,7 +1408,6 @@ static void get_nvme_smart(GuestDiskInfo *disk)
 return;
 }
 
-disk->has_smart = true;
 disk->smart = g_new0(GuestDiskSmart, 1);
 disk->smart->type = GUEST_DISK_BUS_TYPE_NVME;
 
@@ -1449,7 +1445,7 @@ static void get_nvme_smart(GuestDiskInfo *disk)
 
 static void get_disk_smart(GuestDiskInfo *disk)
 {
-if (disk->has_address
+if (disk->address
 && (disk->address->bus_type == GUEST_DISK_BUS_TYPE_NVME)) {
 get_nvme_smart(disk);
 }
@@ -1502,7 +1498,6 @@ GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
 disk->name = dev_name;
 disk->partition = false;
 disk->alias = get_alias_for_syspath(disk_dir);
-disk->has_alias = (disk->alias != NULL);
 QAPI_LIST_PREPEND(ret, disk);
 
 /* Get address for non-virtual devices */
@@ -1522,8 +1517,6 @@ GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
 error_get_pretty(local_err));
 error_free(local_err);
 local_err = NULL;
-} else if (disk->address != NULL) {
-disk->has_address = true;
 }
 }
 
@@ -1641,7 +1634,6 @@ qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error 
**errp)
 if (fd == -1) {
 result->error = g_strdup_printf("failed to open: %s",
 strerror(errno));
-result->has_error = true;
 continue;
 }
 
@@ -1656,7 +1648,6 @@ qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error 
**errp)
 r.minlen = has_minimum ? minimum : 0;
 ret = ioctl(fd, FITRIM, &r);
 if (ret == -1) {
-result->has_error = true;
 if (errno == ENOTTY || errno == EOPNOTSUPP) {
 result->error = g_strdup("trim not supported");
 } else {
@@ 

  1   2   3   >