Re: [PATCH 5/8] Adds basic CPU hot-(un)plug support for Loongarch

2023-08-09 Thread lixianglai

Hi Igor Mammedov:

On 7/28/23 9:21 PM, Igor Mammedov wrote:

On Thu, 20 Jul 2023 15:15:10 +0800
xianglai li  wrote:


1.Add CPU topology related functions
2.Add CPU hot-plug related hook functions
3.Update the in-place CPU creation process at machine initialization

patch is to large, split it at least on those ^^ 3 parts,
which would do a single distinct thing.
After that it will be easier to review this.



Ok, I'll split this patch further.




Also looking at hw/loongarch/acpi-build.c
you have cpu_index == arch_id == core_id /according to comments/
and they are mixed/used interchangeably. which is confusing
at least. So clean it up first to use arch_id consistently

then a separate patches to introduce socket/core/thread support
with proper documentation/pointers to specs as to how arch_id
should be calculated.

And once that is ready, add hotplug on top of it.



Okay, I'll do it according to your suggestion.



Cc: Xiaojuan Yang 
Cc: Song Gao 
Cc: "Michael S. Tsirkin" 
Cc: Igor Mammedov 
Cc: Ani Sinha 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: Marcel Apfelbaum 
Cc: "Philippe Mathieu-Daudé" 
Cc: Yanan Wang 
Cc: "Daniel P. Berrangé" 
Cc: Peter Xu 
Cc: David Hildenbrand 
Signed-off-by: xianglai li 
---
  hw/loongarch/virt.c | 381 ++--
  include/hw/loongarch/virt.h |  11 +-
  target/loongarch/cpu.h  |   4 +
  3 files changed, 382 insertions(+), 14 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index e19b042ce8..5919389f42 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -46,6 +46,9 @@
  #include "hw/block/flash.h"
  #include "qemu/error-report.h"
  
+static int virt_get_socket_id(const MachineState *ms, int cpu_index);

+static int virt_get_core_id(const MachineState *ms, int cpu_index);
+static int virt_get_thread_id(const MachineState *ms, int cpu_index);
  
  static void virt_flash_create(LoongArchMachineState *lams)

  {
@@ -447,12 +450,12 @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic, 
LoongArchMachineState
  {
  DeviceState *dev;
  MachineState *ms = MACHINE(lams);
-uint32_t event = ACPI_GED_PWR_DOWN_EVT;
+uint32_t event = ACPI_GED_PWR_DOWN_EVT | ACPI_GED_CPU_HOTPLUG_EVT;
  
  if (ms->ram_slots) {

  event |= ACPI_GED_MEM_HOTPLUG_EVT;
  }
-dev = qdev_new(TYPE_ACPI_GED);
+dev = qdev_new(TYPE_ACPI_GED_LOONGARCH);
  qdev_prop_set_uint32(dev, "ged-event", event);
  
  /* ged event */

@@ -461,6 +464,7 @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic, 
LoongArchMachineState
  sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, VIRT_GED_MEM_ADDR);
  /* ged regs used for reset and power down */
  sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, VIRT_GED_REG_ADDR);
+sysbus_mmio_map(SYS_BUS_DEVICE(dev), 3, VIRT_GED_CPUHP_ADDR);
  
  sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,

 qdev_get_gpio_in(pch_pic, VIRT_SCI_IRQ - 
VIRT_GSI_BASE));
@@ -583,6 +587,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
  
  extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);

  sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
+lams->extioi = extioi;
  
  /*

   * The connection of interrupts:
@@ -624,11 +629,11 @@ static void loongarch_irq_init(LoongArchMachineState 
*lams)
  
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
  1));
  /*
-* extioi iocsr memory region
-* only one extioi is added on loongarch virt machine
-* external device interrupt can only be routed to cpu 0-3
-*/
-   if (cpu < EXTIOI_CPUS)
+ * extioi iocsr memory region
+ * only one extioi is added on loongarch virt machine
+ * external device interrupt can only be routed to cpu 0-3
+ */
+if (cpu < EXTIOI_CPUS)
  memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
  sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
  cpu));
@@ -789,7 +794,6 @@ static void loongarch_init(MachineState *machine)
  NodeInfo *numa_info = machine->numa_state->nodes;
  int i;
  hwaddr fdt_base;
-const CPUArchIdList *possible_cpus;
  MachineClass *mc = MACHINE_GET_CLASS(machine);
  CPUState *cpu;
  char *ramName = NULL;
@@ -810,12 +814,40 @@ static void loongarch_init(MachineState *machine)
  create_fdt(lams);
  /* Init CPUs */
  
-possible_cpus = mc->possible_cpu_arch_ids(machine);

-for (i = 0; i < possible_cpus->len; i++) {
-cpu = cpu_create(machine->cpu_type);
+mc->possible_cpu_arch_ids(machine);
+
+for (i = 0; i < machine->smp.cpus; i++) {
+Object *cpuobj;
+cpuobj = object_new(machine->cpu_type);
+
+cpu = CPU(cpuobj);
  cpu->cpu_index = i;

I'd move this to foo_cpu_pre_plug()


I guess I don't need to assign a value to the cpu

Re: [PATCH v4 11/11] target/loongarch: Add loongarch32 cpu la132

2023-08-09 Thread Jiajie Chen



On 2023/8/9 03:26, Richard Henderson wrote:

On 8/7/23 18:54, Jiajie Chen wrote:

+static void loongarch_la464_initfn(Object *obj)
+{
+    LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+    CPULoongArchState *env = &cpu->env;
+
+    loongarch_cpu_initfn_common(env);
+
+    cpu->dtb_compatible = "loongarch,Loongson-3A5000";
+    env->cpucfg[0] = 0x14c010;  /* PRID */
+
+    uint32_t data = env->cpucfg[1];
+    data = FIELD_DP32(data, CPUCFG1, ARCH, 2); /* LA64 */
+    data = FIELD_DP32(data, CPUCFG1, PALEN, 0x2f); /* 48 bits */
+    data = FIELD_DP32(data, CPUCFG1, VALEN, 0x2f); /* 48 bits */
+    data = FIELD_DP32(data, CPUCFG1, RI, 1);
+    data = FIELD_DP32(data, CPUCFG1, EP, 1);
+    data = FIELD_DP32(data, CPUCFG1, RPLV, 1);
+    env->cpucfg[1] = data;
+}
+
+static void loongarch_la132_initfn(Object *obj)
+{
+    LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+    CPULoongArchState *env = &cpu->env;
+
+    loongarch_cpu_initfn_common(env);
+
+    cpu->dtb_compatible = "loongarch,Loongson-1C103";
+
+    uint32_t data = env->cpucfg[1];
+    data = FIELD_DP32(data, CPUCFG1, ARCH, 1); /* LA32 */
+    data = FIELD_DP32(data, CPUCFG1, PALEN, 0x1f); /* 32 bits */
+    data = FIELD_DP32(data, CPUCFG1, VALEN, 0x1f); /* 32 bits */
+    data = FIELD_DP32(data, CPUCFG1, RI, 0);
+    data = FIELD_DP32(data, CPUCFG1, EP, 0);
+    data = FIELD_DP32(data, CPUCFG1, RPLV, 0);
+    env->cpucfg[1] = data;
+}


The use of the loongarch_cpu_initfn_common function is not going to 
scale.

Compare the set of *_initfn in target/arm/tcg/cpu32.c

In general, you want to copy data in bulk from the processor manual, 
so that the reviewer can simply read through the table and see that 
the code is correct, without having to check between multiple 
functions to see that the combination is correct.


For our existing la464, that table is Table 54 in the 3A5000 manual.

Is there a public specification for the la132?  I could not find one 
in https://www.loongson.cn/EN/product/, but perhaps that's just the 
english view.



There seems no, even from the chinese view.





r~




Re: [PATCH v4 1/9] virtio: Add shared memory capability

2023-08-09 Thread Huang Rui
On Wed, Aug 09, 2023 at 10:11:00AM +0800, Gurchetan Singh wrote:
> From: "Dr. David Alan Gilbert" 
> 
> Define a new capability type 'VIRTIO_PCI_CAP_SHARED_MEMORY_CFG' to allow
> defining shared memory regions with sizes and offsets of 2^32 and more.
> Multiple instances of the capability are allowed and distinguished
> by a device-specific 'id'.
> 
> Signed-off-by: Dr. David Alan Gilbert 
> Signed-off-by: Antonio Caggiano 
> Reviewed-by: Gurchetan Singh 
> Signed-off-by: Gurchetan Singh 
> Tested-by: Alyssa Ross 
> Reviewed-by: Akihiko Odaki 

Acked-and-Tested-by: Huang Rui 

> ---
>  hw/virtio/virtio-pci.c | 18 ++
>  include/hw/virtio/virtio-pci.h |  4 
>  2 files changed, 22 insertions(+)
> 
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index edbc0daa18..da8c9ea12d 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -1435,6 +1435,24 @@ static int virtio_pci_add_mem_cap(VirtIOPCIProxy 
> *proxy,
>  return offset;
>  }
>  
> +int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy,
> +   uint8_t bar, uint64_t offset, uint64_t length,
> +   uint8_t id)
> +{
> +struct virtio_pci_cap64 cap = {
> +.cap.cap_len = sizeof cap,
> +.cap.cfg_type = VIRTIO_PCI_CAP_SHARED_MEMORY_CFG,
> +};
> +
> +cap.cap.bar = bar;
> +cap.cap.length = cpu_to_le32(length);
> +cap.length_hi = cpu_to_le32(length >> 32);
> +cap.cap.offset = cpu_to_le32(offset);
> +cap.offset_hi = cpu_to_le32(offset >> 32);
> +cap.cap.id = id;
> +return virtio_pci_add_mem_cap(proxy, &cap.cap);
> +}
> +
>  static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr,
> unsigned size)
>  {
> diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h
> index ab2051b64b..5a3f182f99 100644
> --- a/include/hw/virtio/virtio-pci.h
> +++ b/include/hw/virtio/virtio-pci.h
> @@ -264,4 +264,8 @@ unsigned virtio_pci_optimal_num_queues(unsigned 
> fixed_queues);
>  void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue 
> *vq,
>int n, bool assign,
>bool with_irqfd);
> +
> +int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy, uint8_t bar, uint64_t 
> offset,
> +   uint64_t length, uint8_t id);
> +
>  #endif
> -- 
> 2.41.0.640.ga95def55d0-goog
> 



[PATCH for-8.2] dockerfiles: bump tricore cross compiler container to Debian 11

2023-08-09 Thread Paolo Bonzini
With the release of version 12 on June 10, 2023, Debian 10 is
not supported anymore.  Modify the cross compiler container to
build on a newer version.

Signed-off-by: Paolo Bonzini 
---
 tests/docker/dockerfiles/debian-tricore-cross.docker | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/docker/dockerfiles/debian-tricore-cross.docker 
b/tests/docker/dockerfiles/debian-tricore-cross.docker
index 269bfa8d423..5bd1963fb55 100644
--- a/tests/docker/dockerfiles/debian-tricore-cross.docker
+++ b/tests/docker/dockerfiles/debian-tricore-cross.docker
@@ -9,7 +9,7 @@
 #
 # SPDX-License-Identifier: GPL-2.0-or-later
 #
-FROM docker.io/library/debian:buster-slim
+FROM docker.io/library/debian:11-slim
 
 MAINTAINER Philippe Mathieu-Daudé 
 
-- 
2.41.0




[PATCH for-8.2] configure: fix and complete detection of tricore tools

2023-08-09 Thread Paolo Bonzini
The tricore tools are not detected when they are installed in
the host system, only if they are taken from an external
container.  For this reason the build-tricore-softmmu job
was not running the TCG tests.

In addition the container provides all tools, not just as/ld/gcc,
so there is no need to special case tricore.

Signed-off-by: Paolo Bonzini 
---
 configure | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/configure b/configure
index 133f4e32351..f2bd8858d6c 100755
--- a/configure
+++ b/configure
@@ -1271,6 +1271,7 @@ fi
 : ${cross_prefix_sh4="sh4-linux-gnu-"}
 : ${cross_prefix_sparc64="sparc64-linux-gnu-"}
 : ${cross_prefix_sparc="$cross_prefix_sparc64"}
+: ${cross_prefix_tricore="tricore-"}
 : ${cross_prefix_x86_64="x86_64-linux-gnu-"}
 
 : ${cross_cc_aarch64_be="$cross_cc_aarch64"}
@@ -1458,10 +1459,6 @@ probe_target_compiler() {
   tricore)
 container_image=debian-tricore-cross
 container_cross_prefix=tricore-
-container_cross_as=tricore-as
-container_cross_ld=tricore-ld
-container_cross_cc=tricore-gcc
-break
 ;;
   x86_64)
 container_image=debian-amd64-cross
-- 
2.41.0




[PATCH v5 01/11] target/loongarch: Add function to check current arch

2023-08-09 Thread Jiajie Chen
Add is_la64 function to check if the current cpucfg[1].arch equals to
2(LA64).

Signed-off-by: Jiajie Chen 
Co-authored-by: Richard Henderson 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index fa371ca8ba..5a71d64a04 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -132,6 +132,11 @@ FIELD(CPUCFG1, HP, 24, 1)
 FIELD(CPUCFG1, IOCSR_BRD, 25, 1)
 FIELD(CPUCFG1, MSG_INT, 26, 1)
 
+/* cpucfg[1].arch */
+#define CPUCFG1_ARCH_LA32R   0
+#define CPUCFG1_ARCH_LA321
+#define CPUCFG1_ARCH_LA642
+
 /* cpucfg[2] bits */
 FIELD(CPUCFG2, FP, 0, 1)
 FIELD(CPUCFG2, FP_SP, 1, 1)
@@ -420,6 +425,11 @@ static inline int cpu_mmu_index(CPULoongArchState *env, 
bool ifetch)
 #endif
 }
 
+static inline bool is_la64(CPULoongArchState *env)
+{
+return FIELD_EX32(env->cpucfg[1], CPUCFG1, ARCH) == CPUCFG1_ARCH_LA64;
+}
+
 /*
  * LoongArch CPUs hardware flags.
  */
-- 
2.41.0




[PATCH v5 08/11] target/loongarch: Reject la64-only instructions in la32 mode

2023-08-09 Thread Jiajie Chen
LoongArch64-only instructions are marked with regard to the instruction
manual Table 2. LSX instructions are not marked for now for lack of
public manual.

Signed-off-by: Jiajie Chen 
---
 target/loongarch/insn_trans/trans_arith.c.inc | 30 
 .../loongarch/insn_trans/trans_atomic.c.inc   | 76 +--
 target/loongarch/insn_trans/trans_bit.c.inc   | 28 +++
 .../loongarch/insn_trans/trans_branch.c.inc   |  4 +-
 target/loongarch/insn_trans/trans_extra.c.inc | 16 ++--
 target/loongarch/insn_trans/trans_fmov.c.inc  |  4 +-
 .../loongarch/insn_trans/trans_memory.c.inc   | 68 -
 target/loongarch/insn_trans/trans_shift.c.inc | 14 ++--
 target/loongarch/translate.h  |  7 ++
 9 files changed, 127 insertions(+), 120 deletions(-)

diff --git a/target/loongarch/insn_trans/trans_arith.c.inc 
b/target/loongarch/insn_trans/trans_arith.c.inc
index 43d6cf261d..4c21d8b037 100644
--- a/target/loongarch/insn_trans/trans_arith.c.inc
+++ b/target/loongarch/insn_trans/trans_arith.c.inc
@@ -249,9 +249,9 @@ static bool trans_addu16i_d(DisasContext *ctx, 
arg_addu16i_d *a)
 }
 
 TRANS(add_w, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_add_tl)
-TRANS(add_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_add_tl)
+TRANS_64(add_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_add_tl)
 TRANS(sub_w, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_sub_tl)
-TRANS(sub_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_sub_tl)
+TRANS_64(sub_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_sub_tl)
 TRANS(and, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_and_tl)
 TRANS(or, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_or_tl)
 TRANS(xor, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_xor_tl)
@@ -261,32 +261,32 @@ TRANS(orn, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, 
tcg_gen_orc_tl)
 TRANS(slt, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_slt)
 TRANS(sltu, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sltu)
 TRANS(mul_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, tcg_gen_mul_tl)
-TRANS(mul_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_mul_tl)
+TRANS_64(mul_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_mul_tl)
 TRANS(mulh_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, gen_mulh_w)
 TRANS(mulh_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, gen_mulh_w)
-TRANS(mulh_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_d)
-TRANS(mulh_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_du)
-TRANS(mulw_d_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, tcg_gen_mul_tl)
-TRANS(mulw_d_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, tcg_gen_mul_tl)
+TRANS_64(mulh_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_d)
+TRANS_64(mulh_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_du)
+TRANS_64(mulw_d_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, tcg_gen_mul_tl)
+TRANS_64(mulw_d_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, tcg_gen_mul_tl)
 TRANS(div_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, gen_div_w)
 TRANS(mod_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, gen_rem_w)
 TRANS(div_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_SIGN, gen_div_du)
 TRANS(mod_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_SIGN, gen_rem_du)
-TRANS(div_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_d)
-TRANS(mod_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_d)
-TRANS(div_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_du)
-TRANS(mod_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_du)
+TRANS_64(div_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_d)
+TRANS_64(mod_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_d)
+TRANS_64(div_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_du)
+TRANS_64(mod_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_du)
 TRANS(slti, gen_rri_v, EXT_NONE, EXT_NONE, gen_slt)
 TRANS(sltui, gen_rri_v, EXT_NONE, EXT_NONE, gen_sltu)
 TRANS(addi_w, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_addi_tl)
-TRANS(addi_d, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_addi_tl)
+TRANS_64(addi_d, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_addi_tl)
 TRANS(alsl_w, gen_rrr_sa, EXT_NONE, EXT_SIGN, gen_alsl)
-TRANS(alsl_wu, gen_rrr_sa, EXT_NONE, EXT_ZERO, gen_alsl)
-TRANS(alsl_d, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_alsl)
+TRANS_64(alsl_wu, gen_rrr_sa, EXT_NONE, EXT_ZERO, gen_alsl)
+TRANS_64(alsl_d, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_alsl)
 TRANS(pcaddi, gen_pc, gen_pcaddi)
 TRANS(pcalau12i, gen_pc, gen_pcalau12i)
 TRANS(pcaddu12i, gen_pc, gen_pcaddu12i)
-TRANS(pcaddu18i, gen_pc, gen_pcaddu18i)
+TRANS_64(pcaddu18i, gen_pc, gen_pcaddu18i)
 TRANS(andi, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_andi_tl)
 TRANS(ori, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_ori_tl)
 TRANS(xori, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_xori_tl)
diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc 
b/target/loongarch/insn_trans/trans_atomic.c.inc
index 612709f2a7..c69f31bc78 100644
--- a/target/loongarch/insn_trans/trans_atomic.c.inc
+++ b/target/loongarch/insn_trans/trans_atomic.c.inc
@@ -70,41 +70,41 @@ static bool gen_am(DisasContext *ctx, arg_rrr *a,
 
 TRANS(ll_w, gen_ll, MO_TESL)
 TRANS(sc_

[PATCH v5 00/11] Add la32 & va32 support for loongarch64-softmmu

2023-08-09 Thread Jiajie Chen
This patch series allow qemu-system-loongarch64 to emulate a LoongArch32
machine. A new CPU model (la132) is added for loongarch32, however due
to lack of public documentation, details will need to be added in the
future. Initial GDB support is added.

At the same time, VA32(32-bit virtual address) support is introduced for
LoongArch64.

LA32 support is tested using a small supervisor program at
https://github.com/jiegec/supervisor-la32. VA32 mode under LA64 is not
tested yet.

Changes since v4:

- Code refactor, thanks Richard Henderson for great advice
- Truncate higher 32 bits of PC in VA32 mode
- Revert la132 initfn refactor

Changes since v3:

- Support VA32 mode for LoongArch64
- Check the current arch from CPUCFG.ARCH
- Reject la64-only instructions in la32 mode

Changes since v2:

- Fix typo in previous commit
- Fix VPPN width in TLBEHI/TLBREHI

Changes since v1:

- No longer create a separate qemu-system-loongarch32 executable, but
  allow user to run loongarch32 emulation using qemu-system-loongarch64
- Add loongarch32 cpu support for virt machine

Full changes:

Jiajie Chen (11):
  target/loongarch: Add function to check current arch
  target/loongarch: Add new object class for loongarch32 cpus
  target/loongarch: Add GDB support for loongarch32 mode
  target/loongarch: Support LoongArch32 TLB entry
  target/loongarch: Support LoongArch32 DMW
  target/loongarch: Support LoongArch32 VPPN
  target/loongarch: Add LA64 & VA32 to DisasContext
  target/loongarch: Reject la64-only instructions in la32 mode
  target/loongarch: Truncate high 32 bits of address in VA32 mode
  target/loongarch: Sign extend results in VA32 mode
  target/loongarch: Add loongarch32 cpu la132

 configs/targets/loongarch64-softmmu.mak   |   2 +-
 gdb-xml/loongarch-base32.xml  |  45 
 hw/loongarch/virt.c   |   5 -
 target/loongarch/cpu-csr.h|  22 ++--
 target/loongarch/cpu.c|  74 +++--
 target/loongarch/cpu.h|  33 ++
 target/loongarch/gdbstub.c|  34 --
 target/loongarch/insn_trans/trans_arith.c.inc |  32 +++---
 .../loongarch/insn_trans/trans_atomic.c.inc   |  81 +++---
 target/loongarch/insn_trans/trans_bit.c.inc   |  28 ++---
 .../loongarch/insn_trans/trans_branch.c.inc   |  11 +-
 target/loongarch/insn_trans/trans_extra.c.inc |  16 +--
 .../loongarch/insn_trans/trans_fmemory.c.inc  |  30 ++
 target/loongarch/insn_trans/trans_fmov.c.inc  |   4 +-
 target/loongarch/insn_trans/trans_lsx.c.inc   |  38 ++-
 .../loongarch/insn_trans/trans_memory.c.inc   | 102 --
 target/loongarch/insn_trans/trans_shift.c.inc |  14 +--
 target/loongarch/op_helper.c  |   4 +-
 target/loongarch/tlb_helper.c |  66 +---
 target/loongarch/translate.c  |  43 
 target/loongarch/translate.h  |   9 ++
 21 files changed, 445 insertions(+), 248 deletions(-)
 create mode 100644 gdb-xml/loongarch-base32.xml

-- 
2.41.0




[PATCH v5 02/11] target/loongarch: Add new object class for loongarch32 cpus

2023-08-09 Thread Jiajie Chen
Add object class for future loongarch32 cpus. It is derived from the
loongarch64 object class.

Signed-off-by: Jiajie Chen 
---
 target/loongarch/cpu.c | 19 +++
 target/loongarch/cpu.h |  1 +
 2 files changed, 20 insertions(+)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index ad93ecac92..c6b73444b4 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -732,12 +732,22 @@ static void loongarch_cpu_class_init(ObjectClass *c, void 
*data)
 #endif
 }
 
+static void loongarch32_cpu_class_init(ObjectClass *c, void *data)
+{
+}
+
 #define DEFINE_LOONGARCH_CPU_TYPE(model, initfn) \
 { \
 .parent = TYPE_LOONGARCH_CPU, \
 .instance_init = initfn, \
 .name = LOONGARCH_CPU_TYPE_NAME(model), \
 }
+#define DEFINE_LOONGARCH32_CPU_TYPE(model, initfn) \
+{ \
+.parent = TYPE_LOONGARCH32_CPU, \
+.instance_init = initfn, \
+.name = LOONGARCH_CPU_TYPE_NAME(model), \
+}
 
 static const TypeInfo loongarch_cpu_type_infos[] = {
 {
@@ -750,6 +760,15 @@ static const TypeInfo loongarch_cpu_type_infos[] = {
 .class_size = sizeof(LoongArchCPUClass),
 .class_init = loongarch_cpu_class_init,
 },
+{
+.name = TYPE_LOONGARCH32_CPU,
+.parent = TYPE_LOONGARCH_CPU,
+.instance_size = sizeof(LoongArchCPU),
+
+.abstract = true,
+.class_size = sizeof(LoongArchCPUClass),
+.class_init = loongarch32_cpu_class_init,
+},
 DEFINE_LOONGARCH_CPU_TYPE("la464", loongarch_la464_initfn),
 };
 
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 5a71d64a04..2af4c414b0 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -382,6 +382,7 @@ struct ArchCPU {
 };
 
 #define TYPE_LOONGARCH_CPU "loongarch-cpu"
+#define TYPE_LOONGARCH32_CPU "loongarch32-cpu"
 
 OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass,
 LOONGARCH_CPU)
-- 
2.41.0




[PATCH v5 03/11] target/loongarch: Add GDB support for loongarch32 mode

2023-08-09 Thread Jiajie Chen
GPRs and PC are 32-bit wide in loongarch32 mode.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
---
 configs/targets/loongarch64-softmmu.mak |  2 +-
 gdb-xml/loongarch-base32.xml| 45 +
 target/loongarch/cpu.c  | 10 +-
 target/loongarch/gdbstub.c  | 32 ++
 4 files changed, 80 insertions(+), 9 deletions(-)
 create mode 100644 gdb-xml/loongarch-base32.xml

diff --git a/configs/targets/loongarch64-softmmu.mak 
b/configs/targets/loongarch64-softmmu.mak
index 9abc99056f..f23780fdd8 100644
--- a/configs/targets/loongarch64-softmmu.mak
+++ b/configs/targets/loongarch64-softmmu.mak
@@ -1,5 +1,5 @@
 TARGET_ARCH=loongarch64
 TARGET_BASE_ARCH=loongarch
 TARGET_SUPPORTS_MTTCG=y
-TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml
+TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml 
gdb-xml/loongarch-fpu.xml
 TARGET_NEED_FDT=y
diff --git a/gdb-xml/loongarch-base32.xml b/gdb-xml/loongarch-base32.xml
new file mode 100644
index 00..af47bbd3da
--- /dev/null
+++ b/gdb-xml/loongarch-base32.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index c6b73444b4..30dd70571a 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -694,7 +694,13 @@ static const struct SysemuCPUOps loongarch_sysemu_ops = {
 
 static gchar *loongarch_gdb_arch_name(CPUState *cs)
 {
-return g_strdup("loongarch64");
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+if (is_la64(env)) {
+return g_strdup("loongarch64");
+} else {
+return g_strdup("loongarch32");
+}
 }
 
 static void loongarch_cpu_class_init(ObjectClass *c, void *data)
@@ -734,6 +740,8 @@ static void loongarch_cpu_class_init(ObjectClass *c, void 
*data)
 
 static void loongarch32_cpu_class_init(ObjectClass *c, void *data)
 {
+CPUClass *cc = CPU_CLASS(c);
+cc->gdb_core_xml_file = "loongarch-base32.xml";
 }
 
 #define DEFINE_LOONGARCH_CPU_TYPE(model, initfn) \
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
index 0752fff924..a462e25737 100644
--- a/target/loongarch/gdbstub.c
+++ b/target/loongarch/gdbstub.c
@@ -34,16 +34,25 @@ int loongarch_cpu_gdb_read_register(CPUState *cs, 
GByteArray *mem_buf, int n)
 {
 LoongArchCPU *cpu = LOONGARCH_CPU(cs);
 CPULoongArchState *env = &cpu->env;
+uint64_t val;
 
 if (0 <= n && n < 32) {
-return gdb_get_regl(mem_buf, env->gpr[n]);
+val = env->gpr[n];
 } else if (n == 32) {
 /* orig_a0 */
-return gdb_get_regl(mem_buf, 0);
+val = 0;
 } else if (n == 33) {
-return gdb_get_regl(mem_buf, env->pc);
+val = env->pc;
 } else if (n == 34) {
-return gdb_get_regl(mem_buf, env->CSR_BADV);
+val = env->CSR_BADV;
+}
+
+if (0 <= n && n <= 34) {
+if (is_la64(env)) {
+return gdb_get_reg64(mem_buf, val);
+} else {
+return gdb_get_reg32(mem_buf, val);
+}
 }
 return 0;
 }
@@ -52,15 +61,24 @@ int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 {
 LoongArchCPU *cpu = LOONGARCH_CPU(cs);
 CPULoongArchState *env = &cpu->env;
-target_ulong tmp = ldtul_p(mem_buf);
+target_ulong tmp;
+int read_length;
 int length = 0;
 
+if (is_la64(env)) {
+tmp = ldq_p(mem_buf);
+read_length = 8;
+} else {
+tmp = ldl_p(mem_buf);
+read_length = 4;
+}
+
 if (0 <= n && n < 32) {
 env->gpr[n] = tmp;
-length = sizeof(target_ulong);
+length = read_length;
 } else if (n == 33) {
 env->pc = tmp;
-length = sizeof(target_ulong);
+length = read_length;
 }
 return length;
 }
-- 
2.41.0




[PATCH v5 05/11] target/loongarch: Support LoongArch32 DMW

2023-08-09 Thread Jiajie Chen
LA32 uses a different encoding for CSR.DMW and a new direct mapping
mechanism.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu-csr.h|  7 +++
 target/loongarch/tlb_helper.c | 26 +++---
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index 48ed2e0632..b93f99a9ef 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -188,10 +188,9 @@ FIELD(CSR_DMW, PLV1, 1, 1)
 FIELD(CSR_DMW, PLV2, 2, 1)
 FIELD(CSR_DMW, PLV3, 3, 1)
 FIELD(CSR_DMW, MAT, 4, 2)
-FIELD(CSR_DMW, VSEG, 60, 4)
-
-#define dmw_va2pa(va) \
-(va & MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS))
+FIELD(CSR_DMW_32, PSEG, 25, 3)
+FIELD(CSR_DMW_32, VSEG, 29, 3)
+FIELD(CSR_DMW_64, VSEG, 60, 4)
 
 /* Debug CSRs */
 #define LOONGARCH_CSR_DBG0x500 /* debug config */
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index cef10e2257..1f8e7911c7 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -173,6 +173,18 @@ static int loongarch_map_address(CPULoongArchState *env, 
hwaddr *physical,
 return TLBRET_NOMATCH;
 }
 
+static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va,
+target_ulong dmw)
+{
+if (is_la64(env)) {
+return va & TARGET_VIRT_MASK;
+} else {
+uint32_t pseg = FIELD_EX32(dmw, CSR_DMW_32, PSEG);
+return (va & MAKE_64BIT_MASK(0, R_CSR_DMW_32_VSEG_SHIFT)) | \
+(pseg << R_CSR_DMW_32_VSEG_SHIFT);
+}
+}
+
 static int get_physical_address(CPULoongArchState *env, hwaddr *physical,
 int *prot, target_ulong address,
 MMUAccessType access_type, int mmu_idx)
@@ -192,12 +204,20 @@ static int get_physical_address(CPULoongArchState *env, 
hwaddr *physical,
 }
 
 plv = kernel_mode | (user_mode << R_CSR_DMW_PLV3_SHIFT);
-base_v = address >> R_CSR_DMW_VSEG_SHIFT;
+if (is_la64(env)) {
+base_v = address >> R_CSR_DMW_64_VSEG_SHIFT;
+} else {
+base_v = address >> R_CSR_DMW_32_VSEG_SHIFT;
+}
 /* Check direct map window */
 for (int i = 0; i < 4; i++) {
-base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW, VSEG);
+if (is_la64(env)) {
+base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_64, VSEG);
+} else {
+base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG);
+}
 if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) {
-*physical = dmw_va2pa(address);
+*physical = dmw_va2pa(env, address, env->CSR_DMW[i]);
 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 return TLBRET_MATCH;
 }
-- 
2.41.0




[PATCH v5 06/11] target/loongarch: Support LoongArch32 VPPN

2023-08-09 Thread Jiajie Chen
VPPN of TLBEHI/TLBREHI is limited to 19 bits in LA32.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu-csr.h|  6 --
 target/loongarch/tlb_helper.c | 23 ++-
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index b93f99a9ef..c59d7a9fcb 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -57,7 +57,8 @@ FIELD(CSR_TLBIDX, PS, 24, 6)
 FIELD(CSR_TLBIDX, NE, 31, 1)
 
 #define LOONGARCH_CSR_TLBEHI 0x11 /* TLB EntryHi */
-FIELD(CSR_TLBEHI, VPPN, 13, 35)
+FIELD(CSR_TLBEHI_32, VPPN, 13, 19)
+FIELD(CSR_TLBEHI_64, VPPN, 13, 35)
 
 #define LOONGARCH_CSR_TLBELO00x12 /* TLB EntryLo0 */
 #define LOONGARCH_CSR_TLBELO10x13 /* TLB EntryLo1 */
@@ -164,7 +165,8 @@ FIELD(CSR_TLBRERA, PC, 2, 62)
 #define LOONGARCH_CSR_TLBRELO1   0x8d /* TLB refill entrylo1 */
 #define LOONGARCH_CSR_TLBREHI0x8e /* TLB refill entryhi */
 FIELD(CSR_TLBREHI, PS, 0, 6)
-FIELD(CSR_TLBREHI, VPPN, 13, 35)
+FIELD(CSR_TLBREHI_32, VPPN, 13, 19)
+FIELD(CSR_TLBREHI_64, VPPN, 13, 35)
 #define LOONGARCH_CSR_TLBRPRMD   0x8f /* TLB refill mode info */
 FIELD(CSR_TLBRPRMD, PPLV, 0, 2)
 FIELD(CSR_TLBRPRMD, PIE, 2, 1)
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index 1f8e7911c7..c8b8b0497f 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -300,8 +300,13 @@ static void raise_mmu_exception(CPULoongArchState *env, 
target_ulong address,
 
 if (tlb_error == TLBRET_NOMATCH) {
 env->CSR_TLBRBADV = address;
-env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN,
-  extract64(address, 13, 35));
+if (is_la64(env)) {
+env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_64,
+VPPN, extract64(address, 13, 35));
+} else {
+env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_32,
+VPPN, extract64(address, 13, 19));
+}
 } else {
 if (!FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
 env->CSR_BADV = address;
@@ -366,12 +371,20 @@ static void fill_tlb_entry(CPULoongArchState *env, int 
index)
 
 if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
 csr_ps = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS);
-csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN);
+if (is_la64(env)) {
+csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_64, VPPN);
+} else {
+csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_32, VPPN);
+}
 lo0 = env->CSR_TLBRELO0;
 lo1 = env->CSR_TLBRELO1;
 } else {
 csr_ps = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
-csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI, VPPN);
+if (is_la64(env)) {
+csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_64, VPPN);
+} else {
+csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_32, VPPN);
+}
 lo0 = env->CSR_TLBELO0;
 lo1 = env->CSR_TLBELO1;
 }
@@ -491,7 +504,7 @@ void helper_tlbfill(CPULoongArchState *env)
 
 if (pagesize == stlb_ps) {
 /* Only write into STLB bits [47:13] */
-address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_VPPN_SHIFT);
+address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT);
 
 /* Choose one set ramdomly */
 set = get_random_tlb(0, 7);
-- 
2.41.0




[PATCH v5 11/11] target/loongarch: Add loongarch32 cpu la132

2023-08-09 Thread Jiajie Chen
Add la132 as a loongarch32 cpu type and allow virt machine to be used
with la132 instead of la464.

Due to lack of public documentation of la132, it is currently a
synthetic loongarch32 cpu model. Details need to be added in the future.

Signed-off-by: Jiajie Chen 
---
 hw/loongarch/virt.c|  5 -
 target/loongarch/cpu.c | 29 +
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index e19b042ce8..af15bf5aaa 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -798,11 +798,6 @@ static void loongarch_init(MachineState *machine)
 cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
 }
 
-if (!strstr(cpu_model, "la464")) {
-error_report("LoongArch/TCG needs cpu type la464");
-exit(1);
-}
-
 if (ram_size < 1 * GiB) {
 error_report("ram_size must be greater than 1G.");
 exit(1);
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index bd980790f2..dd1cd7d7d2 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -439,6 +439,34 @@ static void loongarch_la464_initfn(Object *obj)
 env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
 }
 
+static void loongarch_la132_initfn(Object *obj)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+CPULoongArchState *env = &cpu->env;
+
+int i;
+
+for (i = 0; i < 21; i++) {
+env->cpucfg[i] = 0x0;
+}
+
+cpu->dtb_compatible = "loongarch,Loongson-1C103";
+
+uint32_t data = 0;
+data = FIELD_DP32(data, CPUCFG1, ARCH, 1); /* LA32 */
+data = FIELD_DP32(data, CPUCFG1, PGMMU, 1);
+data = FIELD_DP32(data, CPUCFG1, IOCSR, 1);
+data = FIELD_DP32(data, CPUCFG1, PALEN, 0x1f); /* 32 bits */
+data = FIELD_DP32(data, CPUCFG1, VALEN, 0x1f); /* 32 bits */
+data = FIELD_DP32(data, CPUCFG1, UAL, 1);
+data = FIELD_DP32(data, CPUCFG1, RI, 0);
+data = FIELD_DP32(data, CPUCFG1, EP, 0);
+data = FIELD_DP32(data, CPUCFG1, RPLV, 0);
+data = FIELD_DP32(data, CPUCFG1, HP, 1);
+data = FIELD_DP32(data, CPUCFG1, IOCSR_BRD, 1);
+env->cpucfg[1] = data;
+}
+
 static void loongarch_cpu_list_entry(gpointer data, gpointer user_data)
 {
 const char *typename = object_class_get_name(OBJECT_CLASS(data));
@@ -778,6 +806,7 @@ static const TypeInfo loongarch_cpu_type_infos[] = {
 .class_init = loongarch32_cpu_class_init,
 },
 DEFINE_LOONGARCH_CPU_TYPE("la464", loongarch_la464_initfn),
+DEFINE_LOONGARCH32_CPU_TYPE("la132", loongarch_la132_initfn),
 };
 
 DEFINE_TYPES(loongarch_cpu_type_infos)
-- 
2.41.0




[PATCH v5 07/11] target/loongarch: Add LA64 & VA32 to DisasContext

2023-08-09 Thread Jiajie Chen
Add LA64 and VA32(32-bit Virtual Address) to DisasContext to allow the
translator to reject doubleword instructions in LA32 mode for example.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu.h   | 13 +
 target/loongarch/translate.c |  3 +++
 target/loongarch/translate.h |  2 ++
 3 files changed, 18 insertions(+)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 2af4c414b0..0e02257f91 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -431,6 +431,17 @@ static inline bool is_la64(CPULoongArchState *env)
 return FIELD_EX32(env->cpucfg[1], CPUCFG1, ARCH) == CPUCFG1_ARCH_LA64;
 }
 
+static inline bool is_va32(CPULoongArchState *env)
+{
+/* VA32 if !LA64 or VA32L[1-3] */
+bool va32 = !is_la64(env);
+uint64_t plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
+if (plv >= 1 && (FIELD_EX64(env->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) {
+va32 = true;
+}
+return va32;
+}
+
 /*
  * LoongArch CPUs hardware flags.
  */
@@ -438,6 +449,7 @@ static inline bool is_la64(CPULoongArchState *env)
 #define HW_FLAGS_CRMD_PGR_CSR_CRMD_PG_MASK   /* 0x10 */
 #define HW_FLAGS_EUEN_FPE   0x04
 #define HW_FLAGS_EUEN_SXE   0x08
+#define HW_FLAGS_VA32   0x20
 
 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
 uint64_t *cs_base, uint32_t *flags)
@@ -447,6 +459,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState 
*env, vaddr *pc,
 *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;
 *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE;
+*flags |= is_va32(env) * HW_FLAGS_VA32;
 }
 
 void loongarch_cpu_list(void);
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 3146a2d4ac..ac847745df 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -119,6 +119,9 @@ static void 
loongarch_tr_init_disas_context(DisasContextBase *dcbase,
 ctx->vl = LSX_LEN;
 }
 
+ctx->la64 = is_la64(env);
+ctx->va32 = (ctx->base.tb->flags & HW_FLAGS_VA32) != 0;
+
 ctx->zero = tcg_constant_tl(0);
 }
 
diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 7f60090580..b6fa5df82d 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -33,6 +33,8 @@ typedef struct DisasContext {
 uint16_t plv;
 int vl;   /* Vector length */
 TCGv zero;
+bool la64; /* LoongArch64 mode */
+bool va32; /* 32-bit virtual address */
 } DisasContext;
 
 void generate_exception(DisasContext *ctx, int excp);
-- 
2.41.0




[PATCH v5 04/11] target/loongarch: Support LoongArch32 TLB entry

2023-08-09 Thread Jiajie Chen
The TLB entry of LA32 lacks NR, NX and RPLV and they are hardwired to
zero in LoongArch32.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu-csr.h|  9 +
 target/loongarch/tlb_helper.c | 17 -
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index f8f24032cb..48ed2e0632 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -66,10 +66,11 @@ FIELD(TLBENTRY, D, 1, 1)
 FIELD(TLBENTRY, PLV, 2, 2)
 FIELD(TLBENTRY, MAT, 4, 2)
 FIELD(TLBENTRY, G, 6, 1)
-FIELD(TLBENTRY, PPN, 12, 36)
-FIELD(TLBENTRY, NR, 61, 1)
-FIELD(TLBENTRY, NX, 62, 1)
-FIELD(TLBENTRY, RPLV, 63, 1)
+FIELD(TLBENTRY_32, PPN, 8, 24)
+FIELD(TLBENTRY_64, PPN, 12, 36)
+FIELD(TLBENTRY_64, NR, 61, 1)
+FIELD(TLBENTRY_64, NX, 62, 1)
+FIELD(TLBENTRY_64, RPLV, 63, 1)
 
 #define LOONGARCH_CSR_ASID   0x18 /* Address space identifier */
 FIELD(CSR_ASID, ASID, 0, 10)
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index 6e00190547..cef10e2257 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -48,10 +48,17 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, 
hwaddr *physical,
 tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V);
 tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D);
 tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV);
-tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY, PPN);
-tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY, NX);
-tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY, NR);
-tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY, RPLV);
+if (is_la64(env)) {
+tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN);
+tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX);
+tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR);
+tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV);
+} else {
+tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN);
+tlb_nx = 0;
+tlb_nr = 0;
+tlb_rplv = 0;
+}
 
 /* Check access rights */
 if (!tlb_v) {
@@ -79,7 +86,7 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, 
hwaddr *physical,
  * tlb_entry contains ppn[47:12] while 16KiB ppn is [47:15]
  * need adjust.
  */
-*physical = (tlb_ppn << R_TLBENTRY_PPN_SHIFT) |
+*physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
 (address & MAKE_64BIT_MASK(0, tlb_ps));
 *prot = PAGE_READ;
 if (tlb_d) {
-- 
2.41.0




[PATCH v5 10/11] target/loongarch: Sign extend results in VA32 mode

2023-08-09 Thread Jiajie Chen
In VA32 mode, BL, JIRL and PC* instructions should sign-extend the low
32 bit result to 64 bits.

Signed-off-by: Jiajie Chen 
---
 target/loongarch/insn_trans/trans_arith.c.inc  | 2 +-
 target/loongarch/insn_trans/trans_branch.c.inc | 4 ++--
 target/loongarch/translate.c   | 8 
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/target/loongarch/insn_trans/trans_arith.c.inc 
b/target/loongarch/insn_trans/trans_arith.c.inc
index 4c21d8b037..e3b7979e15 100644
--- a/target/loongarch/insn_trans/trans_arith.c.inc
+++ b/target/loongarch/insn_trans/trans_arith.c.inc
@@ -72,7 +72,7 @@ static bool gen_pc(DisasContext *ctx, arg_r_i *a,
target_ulong (*func)(target_ulong, int))
 {
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
-target_ulong addr = func(ctx->base.pc_next, a->imm);
+target_ulong addr = make_address_pc(ctx, func(ctx->base.pc_next, a->imm));
 
 tcg_gen_movi_tl(dest, addr);
 gen_set_gpr(a->rd, dest, EXT_NONE);
diff --git a/target/loongarch/insn_trans/trans_branch.c.inc 
b/target/loongarch/insn_trans/trans_branch.c.inc
index b63058235d..cf035e44ff 100644
--- a/target/loongarch/insn_trans/trans_branch.c.inc
+++ b/target/loongarch/insn_trans/trans_branch.c.inc
@@ -12,7 +12,7 @@ static bool trans_b(DisasContext *ctx, arg_b *a)
 
 static bool trans_bl(DisasContext *ctx, arg_bl *a)
 {
-tcg_gen_movi_tl(cpu_gpr[1], ctx->base.pc_next + 4);
+tcg_gen_movi_tl(cpu_gpr[1], make_address_pc(ctx, ctx->base.pc_next + 4));
 gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs);
 ctx->base.is_jmp = DISAS_NORETURN;
 return true;
@@ -25,7 +25,7 @@ static bool trans_jirl(DisasContext *ctx, arg_jirl *a)
 
 TCGv addr = make_address_i(ctx, src1, a->imm);
 tcg_gen_mov_tl(cpu_pc, addr);
-tcg_gen_movi_tl(dest, ctx->base.pc_next + 4);
+tcg_gen_movi_tl(dest, make_address_pc(ctx, ctx->base.pc_next + 4));
 gen_set_gpr(a->rd, dest, EXT_NONE);
 tcg_gen_lookup_and_goto_ptr();
 ctx->base.is_jmp = DISAS_NORETURN;
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 689da19ed0..de7c1c5d1f 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -236,6 +236,14 @@ static TCGv make_address_i(DisasContext *ctx, TCGv base, 
target_long ofs)
 return make_address_x(ctx, base, addend);
 }
 
+static uint64_t make_address_pc(DisasContext *ctx, uint64_t addr)
+{
+if (ctx->va32) {
+addr = (int32_t)addr;
+}
+return addr;
+}
+
 #include "decode-insns.c.inc"
 #include "insn_trans/trans_arith.c.inc"
 #include "insn_trans/trans_shift.c.inc"
-- 
2.41.0




[PATCH v5 09/11] target/loongarch: Truncate high 32 bits of address in VA32 mode

2023-08-09 Thread Jiajie Chen
When running in VA32 mode(!LA64 or VA32L[1-3] matching PLV), virtual
address is truncated to 32 bits before address mapping.

Signed-off-by: Jiajie Chen 
Co-authored-by: Richard Henderson 
---
 target/loongarch/cpu.c| 16 
 target/loongarch/cpu.h|  9 +
 target/loongarch/gdbstub.c|  2 +-
 .../loongarch/insn_trans/trans_atomic.c.inc   |  5 ++-
 .../loongarch/insn_trans/trans_branch.c.inc   |  3 +-
 .../loongarch/insn_trans/trans_fmemory.c.inc  | 30 ---
 target/loongarch/insn_trans/trans_lsx.c.inc   | 38 +--
 .../loongarch/insn_trans/trans_memory.c.inc   | 34 +
 target/loongarch/op_helper.c  |  4 +-
 target/loongarch/translate.c  | 32 
 10 files changed, 85 insertions(+), 88 deletions(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 30dd70571a..bd980790f2 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -81,7 +81,7 @@ static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
 LoongArchCPU *cpu = LOONGARCH_CPU(cs);
 CPULoongArchState *env = &cpu->env;
 
-env->pc = value;
+set_pc(env, value);
 }
 
 static vaddr loongarch_cpu_get_pc(CPUState *cs)
@@ -168,7 +168,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
 set_DERA:
 env->CSR_DERA = env->pc;
 env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1);
-env->pc = env->CSR_EENTRY + 0x480;
+set_pc(env, env->CSR_EENTRY + 0x480);
 break;
 case EXCCODE_INT:
 if (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
@@ -249,7 +249,8 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
 
 /* Find the highest-priority interrupt. */
 vector = 31 - clz32(pending);
-env->pc = env->CSR_EENTRY + (EXCCODE_EXTERNAL_INT + vector) * vec_size;
+set_pc(env, env->CSR_EENTRY + \
+   (EXCCODE_EXTERNAL_INT + vector) * vec_size);
 qemu_log_mask(CPU_LOG_INT,
   "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
   " cause %d\n" "A " TARGET_FMT_lx " D "
@@ -260,10 +261,9 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
   env->CSR_ECFG, env->CSR_ESTAT);
 } else {
 if (tlbfill) {
-env->pc = env->CSR_TLBRENTRY;
+set_pc(env, env->CSR_TLBRENTRY);
 } else {
-env->pc = env->CSR_EENTRY;
-env->pc += EXCODE_MCODE(cause) * vec_size;
+set_pc(env, env->CSR_EENTRY + EXCODE_MCODE(cause) * vec_size);
 }
 qemu_log_mask(CPU_LOG_INT,
   "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
@@ -324,7 +324,7 @@ static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
 CPULoongArchState *env = &cpu->env;
 
 tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
-env->pc = tb->pc;
+set_pc(env, tb->pc);
 }
 
 static void loongarch_restore_state_to_opc(CPUState *cs,
@@ -334,7 +334,7 @@ static void loongarch_restore_state_to_opc(CPUState *cs,
 LoongArchCPU *cpu = LOONGARCH_CPU(cs);
 CPULoongArchState *env = &cpu->env;
 
-env->pc = data[0];
+set_pc(env, data[0]);
 }
 #endif /* CONFIG_TCG */
 
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 0e02257f91..9f550793ca 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -442,6 +442,15 @@ static inline bool is_va32(CPULoongArchState *env)
 return va32;
 }
 
+static inline void set_pc(CPULoongArchState *env, uint64_t value)
+{
+if (is_va32(env)) {
+env->pc = (uint32_t)value;
+} else {
+env->pc = value;
+}
+}
+
 /*
  * LoongArch CPUs hardware flags.
  */
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
index a462e25737..e20b20f99b 100644
--- a/target/loongarch/gdbstub.c
+++ b/target/loongarch/gdbstub.c
@@ -77,7 +77,7 @@ int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 env->gpr[n] = tmp;
 length = read_length;
 } else if (n == 33) {
-env->pc = tmp;
+set_pc(env, tmp);
 length = read_length;
 }
 return length;
diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc 
b/target/loongarch/insn_trans/trans_atomic.c.inc
index c69f31bc78..d90312729b 100644
--- a/target/loongarch/insn_trans/trans_atomic.c.inc
+++ b/target/loongarch/insn_trans/trans_atomic.c.inc
@@ -7,9 +7,8 @@ static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop)
 {
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
-TCGv t0 = tcg_temp_new();
+TCGv t0 = make_address_i(ctx, src1, a->imm);
 
-tcg_gen_addi_tl(t0, src1, a->imm);
 tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, mop);
 tcg_gen_st_tl(t0, cpu_env, offsetof(CPULoongArchState, lladdr));
 tcg_gen_st_tl(dest, cpu_env, offsetof(CPULoongArchState, llval));
@@ -62,6 +61,8 @@ static bool gen_am(

Re: [RFC v4 10/11] tests/tcg/multiarch: Add nativecall.c test

2023-08-09 Thread Alex Bennée


Yeqi Fu  writes:

> Introduce a new test for native calls to ensure their functionality.
> The process involves cross-compiling the test cases, building them
> as dynamically linked binaries, and running these binaries which
> necessitates the addition of the appropriate interpreter prefix.
>
> Signed-off-by: Yeqi Fu 
> ---
>  tests/tcg/multiarch/Makefile.target | 17 +
>  tests/tcg/multiarch/native/nativecall.c | 98 +
>  2 files changed, 115 insertions(+)
>  create mode 100644 tests/tcg/multiarch/native/nativecall.c
>
> diff --git a/tests/tcg/multiarch/Makefile.target 
> b/tests/tcg/multiarch/Makefile.target
> index 43bddeaf21..5231df34ba 100644
> --- a/tests/tcg/multiarch/Makefile.target
> +++ b/tests/tcg/multiarch/Makefile.target
> @@ -138,5 +138,22 @@ run-plugin-semiconsole-with-%:
>  TESTS += semihosting semiconsole
>  endif
>  
> +nativecall: native/nativecall.c
> + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(filter-out 
> -static,$(LDFLAGS))
> +
> +ifneq ($(LD_PREFIX),)
> +ifneq ($(wildcard $(LIBNATIVE)),)
> +run-nativecall: nativecall
> + $(call run-test,$<, $(QEMU) -L $(LD_PREFIX) --native-bypass 
> $(LIBNATIVE) $<, "nativecall")
> +else
> +run-nativecall: nativecall
> + $(call skip-test, $<, "no native library found")
> +endif
> +else
> +run-nativecall: nativecall
> + $(call skip-test, $<, "no elf interpreter prefix found")
> +endif
> +EXTRA_RUNS += run-nativecall
> +
>  # Update TESTS
>  TESTS += $(MULTIARCH_TESTS)
> diff --git a/tests/tcg/multiarch/native/nativecall.c 
> b/tests/tcg/multiarch/native/nativecall.c
> new file mode 100644
> index 00..d3f6f49ed0
> --- /dev/null
> +++ b/tests/tcg/multiarch/native/nativecall.c
> @@ -0,0 +1,98 @@
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +void compare_memory(const void *a, const void *b, size_t n)
> +{
> +const unsigned char *p1 = a;
> +const unsigned char *p2 = b;
> +for (size_t i = 0; i < n; i++) {
> +assert(p1[i] == p2[i]);
> +}
> +}
> +
> +void test_memcpy()
> +{
> +char src[] = "Hello, world!";
> +char dest[20];
> +memcpy(dest, src, 13);
> +compare_memory(dest, src, 13);
> +}

As discussed earlier expanding the range of sizes involved will help get
more coverage especially as routines are usually optimised to handle
various alignments and block sizes.

You can also use a --enable-gcov build and check how much coverage of
your new code is hit by the test cases.

> +
> +void test_strncpy()
> +{
> +char src[] = "Hello, world!";
> +char dest[20];
> +strncpy(dest, src, 13);
> +compare_memory(dest, src, 13);
> +}
> +
> +void test_strcpy()
> +{
> +char src[] = "Hello, world!";
> +char dest[20];
> +strcpy(dest, src);
> +compare_memory(dest, src, 13);
> +}
> +
> +void test_strcat()
> +{
> +char src[20] = "Hello, ";
> +char dst[] = "world!";
> +char str[] = "Hello, world!";
> +strcat(src, dest);

copy and paste fail here (dst/dest) means it doesn't compile.

It's always good practice to make sure your tree passes a make check (or
at least check-tcg in the user-mode case) to ensure no silly bugs are
present.

You can also create a gitlab account and take advantage of the CI. See
this run for example:

  https://gitlab.com/stsquad/qemu/-/pipelines/959899240/failures

> +compare_memory(src, str, 13);
> +}
> +
> +void test_memcmp()
> +{
> +char str1[] = "abc";
> +char str2[] = "abc";
> +char str3[] = "def";
> +assert(memcmp(str1, str2, 3) == 0);
> +assert(memcmp(str1, str3, 3) != 0);
> +}
> +
> +void test_strncmp()
> +{
> +char str1[] = "abc";
> +char str2[] = "abc";
> +char str3[] = "def";
> +assert(strncmp(str1, str2, 2) == 0);
> +assert(strncmp(str1, str3, 2) != 0);
> +}
> +
> +void test_strcmp()
> +{
> +char str1[] = "abc";
> +char str2[] = "abc";
> +char str3[] = "def";
> +assert(strcmp(str1, str2) == 0);
> +assert(strcmp(str1, str3) != 0);
> +}
> +
> +void test_memset()
> +{
> +char buffer[10];
> +memset(buffer, 'A', 10);
> +int i;
> +for (i = 0; i < 10; i++) {
> +assert(buffer[i] == 'A');
> +}
> +}
> +
> +int main()
> +{
> +test_memset();
> +test_memcpy();
> +test_strncpy();
> +test_memcmp();
> +test_strncmp();
> +test_strcpy();
> +test_strcmp();
> +test_strcat();
> +
> +return EXIT_SUCCESS;
> +}


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH for-8.2] dockerfiles: bump tricore cross compiler container to Debian 11

2023-08-09 Thread Alex Bennée


Paolo Bonzini  writes:

> With the release of version 12 on June 10, 2023, Debian 10 is
> not supported anymore.  Modify the cross compiler container to
> build on a newer version.
>
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/docker/dockerfiles/debian-tricore-cross.docker | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tests/docker/dockerfiles/debian-tricore-cross.docker
> b/tests/docker/dockerfiles/debian-tricore-cross.docker
> index 269bfa8d423..5bd1963fb55 100644
> --- a/tests/docker/dockerfiles/debian-tricore-cross.docker
> +++ b/tests/docker/dockerfiles/debian-tricore-cross.docker
> @@ -9,7 +9,7 @@
>  #
>  # SPDX-License-Identifier: GPL-2.0-or-later
>  #
> -FROM docker.io/library/debian:buster-slim
> +FROM docker.io/library/debian:11-slim
>  
>  MAINTAINER Philippe Mathieu-Daudé 

Acked-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v2 1/7] tcg/ppc: Untabify tcg-target.c.inc

2023-08-09 Thread Nicholas Piggin
Acked-by: Nicholas Piggin 

On Tue Aug 8, 2023 at 1:02 PM AEST, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 
> ---
>  tcg/ppc/tcg-target.c.inc | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
> index 511e14b180..642d0fd128 100644
> --- a/tcg/ppc/tcg-target.c.inc
> +++ b/tcg/ppc/tcg-target.c.inc
> @@ -221,7 +221,7 @@ static inline bool in_range_b(tcg_target_long target)
>  }
>  
>  static uint32_t reloc_pc24_val(const tcg_insn_unit *pc,
> -const tcg_insn_unit *target)
> +   const tcg_insn_unit *target)
>  {
>  ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
>  tcg_debug_assert(in_range_b(disp));
> @@ -241,7 +241,7 @@ static bool reloc_pc24(tcg_insn_unit *src_rw, const 
> tcg_insn_unit *target)
>  }
>  
>  static uint16_t reloc_pc14_val(const tcg_insn_unit *pc,
> -const tcg_insn_unit *target)
> +   const tcg_insn_unit *target)
>  {
>  ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
>  tcg_debug_assert(disp == (int16_t) disp);
> @@ -3587,7 +3587,7 @@ static void expand_vec_mul(TCGType type, unsigned vece, 
> TCGv_vec v0,
>tcgv_vec_arg(t1), tcgv_vec_arg(t2));
>  vec_gen_3(INDEX_op_ppc_pkum_vec, type, vece, tcgv_vec_arg(v0),
>tcgv_vec_arg(v0), tcgv_vec_arg(t1));
> - break;
> +break;
>  
>  case MO_32:
>  tcg_debug_assert(!have_isa_2_07);




Re: [PATCH] block-migration: Ensure we don't crash during migration cleanup

2023-08-09 Thread Claudio Fontana
On 8/8/23 19:08, Stefan Hajnoczi wrote:
> On Mon, Jul 31, 2023 at 05:33:38PM -0300, Fabiano Rosas wrote:
>> We can fail the blk_insert_bs() at init_blk_migration(), leaving the
>> BlkMigDevState without a dirty_bitmap and BlockDriverState. Account
>> for the possibly missing elements when doing cleanup.
>>
>> Fix the following crashes:
>>
>> Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
>> 0x55ec83ef in bdrv_release_dirty_bitmap (bitmap=0x0) at 
>> ../block/dirty-bitmap.c:359
>> 359 BlockDriverState *bs = bitmap->bs;
>>  #0  0x55ec83ef in bdrv_release_dirty_bitmap (bitmap=0x0) at 
>> ../block/dirty-bitmap.c:359
>>  #1  0x55bba331 in unset_dirty_tracking () at 
>> ../migration/block.c:371
>>  #2  0x55bbad98 in block_migration_cleanup_bmds () at 
>> ../migration/block.c:681
>>
>> Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
>> 0x55e971ff in bdrv_op_unblock (bs=0x0, 
>> op=BLOCK_OP_TYPE_BACKUP_SOURCE, reason=0x0) at ../block.c:7073
>> 7073QLIST_FOREACH_SAFE(blocker, &bs->op_blockers[op], list, next) {
>>  #0  0x55e971ff in bdrv_op_unblock (bs=0x0, 
>> op=BLOCK_OP_TYPE_BACKUP_SOURCE, reason=0x0) at ../block.c:7073
>>  #1  0x55e9734a in bdrv_op_unblock_all (bs=0x0, reason=0x0) at 
>> ../block.c:7095
>>  #2  0x55bbae13 in block_migration_cleanup_bmds () at 
>> ../migration/block.c:690
>>
>> Signed-off-by: Fabiano Rosas 
>> ---
>>  migration/block.c | 11 +--
>>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> Sorry, I missed this patch!
> 
> If this needs to be in QEMU 8.1 (-rc3 is being tagged today), please
> reply and provide a justification. At this point only security fixes and
> showstoppers will be merged. Thanks!
> 
> Applied to my block-next tree for QEMU 8.2:
> https://gitlab.com/stefanha/qemu/commits/block-next
> 
> Stefan

Thanks, and in my personal view I think it's ok for 8.2, IIUC it happens during 
the migration to file work which is not in 8.1 anyway,
Fabiano correct me here if I am wrong,

Ciao,

Claudio



Re: [PATCH v2 2/7] tcg/ppc: Use PADDI in tcg_out_movi

2023-08-09 Thread Nicholas Piggin
On Tue Aug 8, 2023 at 1:02 PM AEST, Richard Henderson wrote:
> PADDI can load 34-bit immediates and 34-bit pc-relative addresses.
>

Reviewed-by: Nicholas Piggin 

> Reviewed-by: Jordan Niethe 
> Signed-off-by: Richard Henderson 
> ---
>  tcg/ppc/tcg-target.c.inc | 51 
>  1 file changed, 51 insertions(+)
>
> diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
> index 642d0fd128..2141c0bc78 100644
> --- a/tcg/ppc/tcg-target.c.inc
> +++ b/tcg/ppc/tcg-target.c.inc
> @@ -707,6 +707,38 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int 
> type,
>  return true;
>  }
>  
> +/* Ensure that the prefixed instruction does not cross a 64-byte boundary. */
> +static bool tcg_out_need_prefix_align(TCGContext *s)
> +{
> +return ((uintptr_t)s->code_ptr & 0x3f) == 0x3c;
> +}
> +
> +static void tcg_out_prefix_align(TCGContext *s)
> +{
> +if (tcg_out_need_prefix_align(s)) {
> +tcg_out32(s, NOP);
> +}
> +}
> +
> +static ptrdiff_t tcg_pcrel_diff_for_prefix(TCGContext *s, const void *target)
> +{
> +return tcg_pcrel_diff(s, target) - (tcg_out_need_prefix_align(s) ? 4 : 
> 0);
> +}
> +
> +/* Output Type 10 Prefix - Modified Load/Store Form (MLS:D) */
> +static void tcg_out_mls_d(TCGContext *s, tcg_insn_unit opc, unsigned rt,
> +  unsigned ra, tcg_target_long imm, bool r)
> +{
> +tcg_insn_unit p, i;
> +
> +p = OPCD(1) | (2 << 24) | (r << 20) | ((imm >> 16) & 0x3);
> +i = opc | TAI(rt, ra, imm);
> +
> +tcg_out_prefix_align(s);
> +tcg_out32(s, p);
> +tcg_out32(s, i);
> +}
> +
>  static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
>   TCGReg base, tcg_target_long offset);
>  
> @@ -992,6 +1024,25 @@ static void tcg_out_movi_int(TCGContext *s, TCGType 
> type, TCGReg ret,
>  return;
>  }
>  
> +/*
> + * Load values up to 34 bits, and pc-relative addresses,
> + * with one prefixed insn.
> + */
> +if (have_isa_3_10) {
> +if (arg == sextract64(arg, 0, 34)) {
> +/* pli ret,value = paddi ret,0,value,0 */
> +tcg_out_mls_d(s, ADDI, ret, 0, arg, 0);
> +return;
> +}
> +
> +tmp = tcg_pcrel_diff_for_prefix(s, (void *)arg);
> +if (tmp == sextract64(tmp, 0, 34)) {
> +/* pla ret,value = paddi ret,0,value,1 */
> +tcg_out_mls_d(s, ADDI, ret, 0, tmp, 1);
> +return;
> +}
> +}
> +
>  /* Load 32-bit immediates with two insns.  Note that we've already
> eliminated bare ADDIS, so we know both insns are required.  */
>  if (TCG_TARGET_REG_BITS == 32 || arg == (int32_t)arg) {




Re: [PATCH] vfio/pci: hide ROM BAR on SFC9220 10/40G Ethernet Controller PF

2023-08-09 Thread Laszlo Ersek
On 8/8/23 17:40, Alex Williamson wrote:
> On Tue,  8 Aug 2023 16:59:16 +0200
> Laszlo Ersek  wrote:
> 
>> The Solarflare Communications SFC9220 NIC's physical function (PF) appears
>> to expose an expansion ROM with the following characteristics:
>>
>> (1) Single-image ROM, with only a legacy BIOS image (no UEFI driver).
>> Alex's rom-parser utility dumps it like this:
>>
>>> Valid ROM signature found @0h, PCIR offset 20h
>>> PCIR: type 0 (x86 PC-AT), vendor: 1924, device: 0a03, class: 02
>>> PCIR: revision 3, vendor revision: 1
>>> Last image  
>>
>> (2) The BIOS image crashes when booted on i440fx.
>>
>> (3) The BIOS image prints the following messages on q35:
>>
>>> Solarflare Boot Manager (v5.2.2.1006)
>>> Solarflare Communications 2008-2019
>>> gPXE (http://etherboot.org) - [...] PCI[...] PnP PMM[...]  
>>
>> So it appears like a modified derivative of old gPXE.
>>
>> Alex surmised in advance that the BIOS image could be accessing
>> host-physical addresses rather than guest-phys ones, leading to the crash
>> on i440fx.
> 
> ROMs sometimes take shortcuts around the standard interfaces to the
> device and can therefore hit gaps in the virtualization, which is why
> that's suspect to me.  However if it works on q35 but not 440fx it
> might be more that we're not matching a PCI topology expectation of the
> ROM.  Was it only tested on 440fx attached to the root bus or does it
> also fail if the PF is attached downstream of a PCI-to-PCI bridge?

I don't know; I'll need to test both of these setups then.

> 
>> Don't expose the option ROM BAR to the VM by default. While this prevents
>> netbooting the VM off the PF on q35/SeaBIOS (a relatively rare scenario),
>> it does not make any difference for UEFI, and at least the VM doesn't
>> crash during boot on i440fx/SeaBIOS (a relatively frequent scenario).
>> Users can restore the original behavior via the QEMU cmdline and the
>> libvirt domain XML.
>>
>> (In two years, we've not seen any customer interest in this bug, hence
>> there's no incentive to investigate (2).)
>>
>> Cc: Alex Williamson  (supporter:VFIO)
>> Cc: "Cédric Le Goater"  (supporter:VFIO)
>> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1975776
>> Signed-off-by: Laszlo Ersek 
>> ---
>>  hw/vfio/pci-quirks.c | 4 
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
>> index f4ff83680572..270eb16b91fa 100644
>> --- a/hw/vfio/pci-quirks.c
>> +++ b/hw/vfio/pci-quirks.c
>> @@ -45,6 +45,10 @@ static const struct {
>>  uint32_t device;
>>  } rom_denylist[] = {
>>  { 0x14e4, 0x168e }, /* Broadcom BCM 57810 */
>> +{ 0x1924, 0x0a03 }, /* Solarflare Communications
>> + * SFC9220 10/40G Ethernet Controller
>> + * 
>> https://bugzilla.redhat.com/show_bug.cgi?id=1975776
> 
> Unfortunately this is not a public bz so there's not much point in
> referencing it in public code or commit log :-\  Thanks,

The BZ is not public because it was originally (mis-)filed for the RH
kernel, and those BZs are private by default. I'd corrected the BZ
component yesterday, but didn't realize I should relax the BZ's
visibility. I'll do that now. (That's the right thing to do regardless
of whether this patch gets in or not.)

Thanks!
Laszlo

> 
> Alex
> 
>> + */
>>  };
>>  
>>  bool vfio_opt_rom_in_denylist(VFIOPCIDevice *vdev)
> 




Re: [PATCH 2/2] linux-user: Use ARRAY_SIZE with bitmask_transtbl

2023-08-09 Thread Alex Bennée


Richard Henderson  writes:

> Rather than using a zero tuple to end the table, use a macro
> to apply ARRAY_SIZE and pass that on to the convert functions.
>
> This fixes two bugs in which the conversion functions required
> that both the target and host masks be non-zero in order to
> continue, rather than require both target and host masks be
> zero in order to terminate.
>
> This affected mmap_flags_tbl when the host does not support
> all of the flags we wish to convert (e.g. MAP_UNINITIALIZED).
> Mapping these flags to zero is good enough, and matches how
> the kernel ignores bits that are unknown.
>
> Fixes: 4b840f96 ("linux-user: Populate more bits in mmap_flags_tbl")
> Signed-off-by: Richard Henderson 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH 1/2] linux-user: Split out do_mmap

2023-08-09 Thread Alex Bennée


Richard Henderson  writes:

> New function that rejects unsupported map types and flags.
> In 4b840f96 we should not have accepted MAP_SHARED_VALIDATE
> without actually validating the rest of the flags.
>
> Fixes: 4b840f96 ("linux-user: Populate more bits in mmap_flags_tbl")
> Signed-off-by: Richard Henderson 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v1 1/3] softmmu/physmem: fallback to opening guest RAM file as readonly in a MAP_PRIVATE mapping

2023-08-09 Thread David Hildenbrand

Hi Peter!


-fd = file_ram_open(mem_path, memory_region_name(mr), readonly, &created,
-   errp);
+fd = file_ram_open(mem_path, memory_region_name(mr), readonly, &created);
+if (fd == -EACCES && !(ram_flags & RAM_SHARED) && !readonly) {
+/*
+ * We can have a writable MAP_PRIVATE mapping of a readonly file.
+ * However, some operations like ftruncate() or fallocate() might fail
+ * later, let's warn the user.
+ */
+fd = file_ram_open(mem_path, memory_region_name(mr), true, &created);
+if (fd >= 0) {
+warn_report("backing store %s for guest RAM (MAP_PRIVATE) opened"
+" readonly because the file is not writable", 
mem_path);


I can understand the use case, but this will be slightly unwanted,
especially the user doesn't yet have a way to predict when will it happen.


Users can set the file permissions accordingly I guess. If they don't 
want the file to never ever be modified via QEMU, set it R/O.




Meanwhile this changes the behavior, is it a concern that someone may want
to rely on current behavior of failing?


The scenario would be that someone passes a readonly file to "-mem-path" 
or "-object memory-backend-file,share=off,readonly=off", with the 
expectation that it would currently fail.


If it now doesn't fail (and we warn instead), what would happen is:
* In file_ram_alloc() we won't even try ftruncate(), because the file
  already had a size > 0. So ftruncate() is not a concern as I now
  realize.
* fallocate might fail later. AFAIKS, that only applies to
  ram_block_discard_range().
 -> virtio-mem performs an initial ram_block_discard_range() check and
fails gracefully early.
 -> virtio-ballooon ignores any errors
 -> ram_discard_range() in migration code fails early for postcopy in
init_range() and loadvm_postcopy_ram_handle_discard(), handling it
gracefully.

So mostly nothing "bad" would happen, it might just be undesirable, and 
we properly warn.


Most importantly, we won't be corrupting/touching the original file in 
any case, because it is R/O.


If we really want to be careful, we could clue that behavior to compat 
machines. I'm not really sure yet if we really have to go down that path.


Any other alternatives? I'd like to avoid new flags where not really 
required.




To think from a higher level of current use case, the ideal solution seems
to me that if the ram file can be put on a file system that supports CoW
itself (like btrfs), we can snapshot that ram file and make it RW for the
qemu instance. Then here it'll be able to open the file.  We'll be able to
keep the interface working as before, meanwhile it'll work with fallocate
or truncations too I assume.

Would that be better instead of changing QEMU?


As I recently learned, using file-backed VMs (on real ssd/disks, not 
shmem/hugetlb) is usually undesired, because the dirtied pages will 
constantly get rewritten to disk by background writeback threads, 
eventually resulting in bad performance and SSD wear.


So while using a COW filesystem sounds cleaner in theory, it's not 
applicable in practice -- unless one disables any background writeback, 
which has different side effects because it cannot be configured on a 
per-file basis.


So for VM templating, it makes sense to capture the guest RAM and store 
it in a file, to then use a COW (MAP_PRIVATE) mapping. Using a read-only 
file makes perfect sense in that scenario IMHO.


[I'm curious at what point a filesystem will actually break COW. if it's 
wired up to the writenotify infrastructure, it would happen when 
actually writing to a page, not at mmap time. I know that filesystems 
use writenotify for lazy allocation of disk blocks on file holes, maybe 
they also do that for lazy allocation of disk blocks on COW]


Thanks!

--
Cheers,

David / dhildenb




Re: [PATCH 4/7] spapr: Fix record-replay machine reset consuming too many events

2023-08-09 Thread Nicholas Piggin
On Tue Aug 8, 2023 at 1:52 PM AEST, Pavel Dovgalyuk wrote:
> On 08.08.2023 06:09, Nicholas Piggin wrote:
> > On Sun Aug 6, 2023 at 9:46 PM AEST, Nicholas Piggin wrote:
> >> On Fri Aug 4, 2023 at 6:50 PM AEST, Pavel Dovgalyuk wrote:
> >>> BTW, there is a function qemu_register_reset_nosnapshotload that can be
> >>> used in similar cases.
> >>> Can you just use it without changing the code of the reset handler?
> >>
> >> I didn't know that, thanks for pointing it out. I'll take a closer look
> >> at it before reposting.
> > 
> > Seems a bit tricky because the device tree has to be rebuilt at reset
> > time (including snapshot load), but it uses the random number. So
>
> It seems strange to me, that loading the existing configuration has to 
> randomize the device tree.

Building the device tree requires a random number for one of the
properties.

Other architectures that don't have this "cas" firmware call that
changes the device tree and so requires it is rebuilt at machine
reset time just build the device tree once at machine creation time
I believe.

So spapr is already weird in that way. We could go the way that
other archs have and just save that random number once at
creation and then reuse it for each reset. I thought that was not
so good because for a normal reset I think it is better to get a
new random number each time, no?

So I think it's natural enough to take a new random number for a
regular reset, but keep the existing one for a snapshot reset. I
could be misunderstanding something though.

Thanks,
Nick

>
> > having a second nosnapshotload reset function might not be called in
> > the correct order, I think?  For now I will keep it as is.
>
> Ok, let's wait for other reviewers.
>
>
> Pavel Dovgalyuk




[PATCH 1/9] python: mkvenv: tweak the matching of --diagnose to depspecs

2023-08-09 Thread Paolo Bonzini
Move the matching between the "absent" array and dep_specs[0] inside
the loop, preparing for the possibility of having multiple canaries
among the installed packages.

Signed-off-by: Paolo Bonzini 
---
 python/scripts/mkvenv.py | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/python/scripts/mkvenv.py b/python/scripts/mkvenv.py
index a47f1eaf5d6..399659b22f1 100644
--- a/python/scripts/mkvenv.py
+++ b/python/scripts/mkvenv.py
@@ -806,6 +806,7 @@ def _do_ensure(
 """
 absent = []
 present = []
+canary = None
 for spec in dep_specs:
 matcher = distlib.version.LegacyMatcher(spec)
 ver = _get_version(matcher.name)
@@ -817,6 +818,8 @@ def _do_ensure(
 or not matcher.match(distlib.version.LegacyVersion(ver))
 ):
 absent.append(spec)
+if spec == dep_specs[0]:
+canary = prog
 else:
 logger.info("found %s %s", matcher.name, ver)
 present.append(matcher.name)
@@ -839,7 +842,7 @@ def _do_ensure(
 absent[0],
 online,
 wheels_dir,
-prog if absent[0] == dep_specs[0] else None,
+canary,
 )
 
 return None
-- 
2.41.0




[PATCH 2/9] python: mkvenv: introduce TOML-like representation of dependencies

2023-08-09 Thread Paolo Bonzini
We would like to place all Python dependencies in the same file, so that
we can add more information without having long and complex command lines.
The plan is to have a TOML file with one entry per package, for example

  [avocado]
  avocado-framework = {
accepted = "(>=88.1, <93.0)",
installed = "88.1",
canary = "avocado"
  }

Each TOML section will thus be a dictionary of dictionaries.  Modify
mkvenv.py's workhorse function, _do_ensure, to already operate on such
a data structure.  The "ensure" subcommand is modified to separate the
depspec into a name and a version part, and use the result (plus the
--diagnose argument) to build a dictionary for each command line argument.

Signed-off-by: Paolo Bonzini 
---
 python/scripts/mkvenv.py | 77 +++-
 1 file changed, 61 insertions(+), 16 deletions(-)

diff --git a/python/scripts/mkvenv.py b/python/scripts/mkvenv.py
index 399659b22f1..96f506d7e22 100644
--- a/python/scripts/mkvenv.py
+++ b/python/scripts/mkvenv.py
@@ -46,6 +46,9 @@
 
 """
 
+# The duplication between importlib and pkg_resources does not help
+# pylint: disable=too-many-lines
+
 # Copyright (C) 2022-2023 Red Hat, Inc.
 #
 # Authors:
@@ -69,6 +72,7 @@
 from types import SimpleNamespace
 from typing import (
 Any,
+Dict,
 Iterator,
 Optional,
 Sequence,
@@ -786,43 +790,67 @@ def pip_install(
 )
 
 
+def _make_version_constraint(info: Dict[str, str], install: bool) -> str:
+"""
+Construct the version constraint part of a PEP 508 dependency
+specification (for example '>=0.61.5') from the accepted and
+installed keys of the provided dictionary.
+
+:param info: A dictionary corresponding to a TOML key-value list.
+:param install: True generates install constraints, False generates
+presence constraints
+"""
+if install and "installed" in info:
+return "==" + info["installed"]
+
+dep_spec = info.get("accepted", "")
+dep_spec = dep_spec.strip()
+# Double check that they didn't just use a version number
+if dep_spec and dep_spec[0] not in "!~><=(":
+raise Ouch(
+"invalid dependency specifier " + dep_spec + " in dependency file"
+)
+
+return dep_spec
+
+
 def _do_ensure(
-dep_specs: Sequence[str],
+group: Dict[str, Dict[str, str]],
 online: bool = False,
 wheels_dir: Optional[Union[str, Path]] = None,
-prog: Optional[str] = None,
 ) -> Optional[Tuple[str, bool]]:
 """
-Use pip to ensure we have the package specified by @dep_specs.
+Use pip to ensure we have the packages specified in @group.
 
-If the package is already installed, do nothing. If online and
+If the packages are already installed, do nothing. If online and
 wheels_dir are both provided, prefer packages found in wheels_dir
 first before connecting to PyPI.
 
-:param dep_specs:
-PEP 508 dependency specifications. e.g. ['meson>=0.61.5'].
+:param group: A dictionary of dictionaries, corresponding to a
+section in a pythondeps.toml file.
 :param online: If True, fall back to PyPI.
 :param wheels_dir: If specified, search this path for packages.
 """
 absent = []
 present = []
 canary = None
-for spec in dep_specs:
-matcher = distlib.version.LegacyMatcher(spec)
-ver = _get_version(matcher.name)
+for name, info in group.items():
+constraint = _make_version_constraint(info, False)
+matcher = distlib.version.LegacyMatcher(name + constraint)
+ver = _get_version(name)
 if (
 ver is None
 # Always pass installed package to pip, so that they can be
 # updated if the requested version changes
-or not _is_system_package(matcher.name)
+or not _is_system_package(name)
 or not matcher.match(distlib.version.LegacyVersion(ver))
 ):
-absent.append(spec)
-if spec == dep_specs[0]:
-canary = prog
+absent.append(name + _make_version_constraint(info, True))
+if len(absent) == 1:
+canary = info.get("canary", None)
 else:
-logger.info("found %s %s", matcher.name, ver)
-present.append(matcher.name)
+logger.info("found %s %s", name, ver)
+present.append(name)
 
 if present:
 generate_console_scripts(present)
@@ -875,7 +903,24 @@ def ensure(
 if not HAVE_DISTLIB:
 raise Ouch("a usable distlib could not be found, please install it")
 
-result = _do_ensure(dep_specs, online, wheels_dir, prog)
+# Convert the depspecs to a dictionary, as if they came
+# from a section in a pythondeps.toml file
+group: Dict[str, Dict[str, str]] = {}
+for spec in dep_specs:
+name = distlib.version.LegacyMatcher(spec).name
+group[name] = {}
+
+spec = spec.strip()
+pos = len(name)
+ver =

[PATCH 4/9] lcitool: bump libvirt-ci submodule and regenerate

2023-08-09 Thread Paolo Bonzini
This brings in a newer version of the pipewire mapping, so rename it.

Python 3.9 and 3.10 do not seem to work in OpenSUSE LEAP 15.5 (weird,
because 3.9 persisted from 15.3 to 15.4) so bump the Python runtime
version to 3.11.

Signed-off-by: Paolo Bonzini 
---
 .../dockerfiles/debian-amd64-cross.docker |  2 +-
 .../dockerfiles/debian-arm64-cross.docker |  2 +-
 .../dockerfiles/debian-armel-cross.docker |  2 +-
 .../dockerfiles/debian-armhf-cross.docker |  2 +-
 .../dockerfiles/debian-mips64el-cross.docker  |  2 +-
 .../dockerfiles/debian-mipsel-cross.docker|  2 +-
 .../dockerfiles/debian-ppc64el-cross.docker   |  2 +-
 .../dockerfiles/debian-riscv64-cross.docker   |  2 +-
 .../dockerfiles/debian-s390x-cross.docker |  2 +-
 .../dockerfiles/fedora-win32-cross.docker |  2 +-
 .../dockerfiles/fedora-win64-cross.docker |  2 +-
 tests/docker/dockerfiles/opensuse-leap.docker | 22 +--
 tests/lcitool/libvirt-ci  |  2 +-
 tests/lcitool/mappings.yml| 12 +-
 tests/lcitool/projects/qemu.yml   |  2 +-
 tests/lcitool/targets/opensuse-leap-15.yml|  4 ++--
 16 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/tests/docker/dockerfiles/debian-amd64-cross.docker 
b/tests/docker/dockerfiles/debian-amd64-cross.docker
index b7bdc012431..b9871f9c8c7 100644
--- a/tests/docker/dockerfiles/debian-amd64-cross.docker
+++ b/tests/docker/dockerfiles/debian-amd64-cross.docker
@@ -1,6 +1,6 @@
 # THIS FILE WAS AUTO-GENERATED
 #
-#  $ lcitool dockerfile --layers all --cross x86_64 debian-11 qemu
+#  $ lcitool dockerfile --layers all --cross-arch x86_64 debian-11 qemu
 #
 # https://gitlab.com/libvirt/libvirt-ci
 
diff --git a/tests/docker/dockerfiles/debian-arm64-cross.docker 
b/tests/docker/dockerfiles/debian-arm64-cross.docker
index 68165c2f23e..3504c771a76 100644
--- a/tests/docker/dockerfiles/debian-arm64-cross.docker
+++ b/tests/docker/dockerfiles/debian-arm64-cross.docker
@@ -1,6 +1,6 @@
 # THIS FILE WAS AUTO-GENERATED
 #
-#  $ lcitool dockerfile --layers all --cross aarch64 debian-11 qemu
+#  $ lcitool dockerfile --layers all --cross-arch aarch64 debian-11 qemu
 #
 # https://gitlab.com/libvirt/libvirt-ci
 
diff --git a/tests/docker/dockerfiles/debian-armel-cross.docker 
b/tests/docker/dockerfiles/debian-armel-cross.docker
index 2fb65308c7a..6d11c9510fd 100644
--- a/tests/docker/dockerfiles/debian-armel-cross.docker
+++ b/tests/docker/dockerfiles/debian-armel-cross.docker
@@ -1,6 +1,6 @@
 # THIS FILE WAS AUTO-GENERATED
 #
-#  $ lcitool dockerfile --layers all --cross armv6l debian-11 qemu
+#  $ lcitool dockerfile --layers all --cross-arch armv6l debian-11 qemu
 #
 # https://gitlab.com/libvirt/libvirt-ci
 
diff --git a/tests/docker/dockerfiles/debian-armhf-cross.docker 
b/tests/docker/dockerfiles/debian-armhf-cross.docker
index df77ccb57bd..37ae575cf7e 100644
--- a/tests/docker/dockerfiles/debian-armhf-cross.docker
+++ b/tests/docker/dockerfiles/debian-armhf-cross.docker
@@ -1,6 +1,6 @@
 # THIS FILE WAS AUTO-GENERATED
 #
-#  $ lcitool dockerfile --layers all --cross armv7l debian-11 qemu
+#  $ lcitool dockerfile --layers all --cross-arch armv7l debian-11 qemu
 #
 # https://gitlab.com/libvirt/libvirt-ci
 
diff --git a/tests/docker/dockerfiles/debian-mips64el-cross.docker 
b/tests/docker/dockerfiles/debian-mips64el-cross.docker
index 63a3d7aa3b9..26ed730165a 100644
--- a/tests/docker/dockerfiles/debian-mips64el-cross.docker
+++ b/tests/docker/dockerfiles/debian-mips64el-cross.docker
@@ -1,6 +1,6 @@
 # THIS FILE WAS AUTO-GENERATED
 #
-#  $ lcitool dockerfile --layers all --cross mips64el debian-11 qemu
+#  $ lcitool dockerfile --layers all --cross-arch mips64el debian-11 qemu
 #
 # https://gitlab.com/libvirt/libvirt-ci
 
diff --git a/tests/docker/dockerfiles/debian-mipsel-cross.docker 
b/tests/docker/dockerfiles/debian-mipsel-cross.docker
index ac87bbb0956..ade2f37ed1d 100644
--- a/tests/docker/dockerfiles/debian-mipsel-cross.docker
+++ b/tests/docker/dockerfiles/debian-mipsel-cross.docker
@@ -1,6 +1,6 @@
 # THIS FILE WAS AUTO-GENERATED
 #
-#  $ lcitool dockerfile --layers all --cross mipsel debian-11 qemu
+#  $ lcitool dockerfile --layers all --cross-arch mipsel debian-11 qemu
 #
 # https://gitlab.com/libvirt/libvirt-ci
 
diff --git a/tests/docker/dockerfiles/debian-ppc64el-cross.docker 
b/tests/docker/dockerfiles/debian-ppc64el-cross.docker
index def11f16933..08dcffa0a85 100644
--- a/tests/docker/dockerfiles/debian-ppc64el-cross.docker
+++ b/tests/docker/dockerfiles/debian-ppc64el-cross.docker
@@ -1,6 +1,6 @@
 # THIS FILE WAS AUTO-GENERATED
 #
-#  $ lcitool dockerfile --layers all --cross ppc64le debian-11 qemu
+#  $ lcitool dockerfile --layers all --cross-arch ppc64le debian-11 qemu
 #
 # https://gitlab.com/libvirt/libvirt-ci
 
diff --git a/tests/docker/dockerfiles/debian-riscv64-cross.docker 
b/tests/docker/dockerfiles/debian-riscv64-cross.docker
index a2d879ee1fd..a26637ec4fb 100644
--- a/tests/docker/dockerfile

[PATCH 8/9] Revert "tests: Use separate virtual environment for avocado"

2023-08-09 Thread Paolo Bonzini
This reverts commit e8e4298feadae7924cf7600bb3bcc5b0a8d7cbe9.

ensuregroup allows to specify both the acceptable versions of avocado,
and a locked version to be used when avocado is not installed as a system
pacakge.  This lets us install avocado in pyvenv/ using "mkvenv.py" and
reuse the distro package on Fedora and CentOS Stream (the only distros
where it's available).

ensuregroup's usage of "(>=..., <=...)" constraints when evaluating
the distro package, and "==" constraints when installing it from PyPI,
makes it possible to avoid conflicts between the known-good version and
a package plugins included in the distro.

This is because package plugins have "==" constraints on the version
that is included in the distro, and, using "pip install avocado==88.1"
on a venv that includes system packages will result in an error:

   avocado-framework-plugin-varianter-yaml-to-mux 98.0 requires 
avocado-framework==98.0, but you have avocado-framework 88.1 which is 
incompatible.
   avocado-framework-plugin-result-html 98.0 requires avocado-framework==98.0, 
but you have avocado-framework 88.1 which is incompatible.

But at the same time, if the venv does not include a system distribution
of avocado then we can install a known-good version and stick to LTS
releases.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1663
Signed-off-by: Paolo Bonzini 
---
 .gitlab-ci.d/buildtest.yml|  6 +++---
 docs/devel/acpi-bits.rst  |  6 +++---
 docs/devel/testing.rst| 14 +++---
 python/scripts/mkvenv.py  | 13 +
 pythondeps.toml   |  7 +++
 .../org.centos/stream/8/x86_64/test-avocado   |  4 ++--
 scripts/device-crash-test |  2 +-
 tests/Makefile.include| 19 ---
 tests/requirements.txt|  6 --
 tests/vm/Makefile.include |  2 +-
 10 files changed, 37 insertions(+), 42 deletions(-)
 delete mode 100644 tests/requirements.txt

diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
index 77dc83a6be0..aee91015077 100644
--- a/.gitlab-ci.d/buildtest.yml
+++ b/.gitlab-ci.d/buildtest.yml
@@ -103,7 +103,7 @@ crash-test-debian:
   script:
 - cd build
 - make NINJA=":" check-venv
-- tests/venv/bin/python3 scripts/device-crash-test -q --tcg-only 
./qemu-system-i386
+- pyvenv/bin/python3 scripts/device-crash-test -q --tcg-only 
./qemu-system-i386
 
 build-system-fedora:
   extends:
@@ -146,8 +146,8 @@ crash-test-fedora:
   script:
 - cd build
 - make NINJA=":" check-venv
-- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-ppc
-- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-riscv32
+- pyvenv/bin/python3 scripts/device-crash-test -q ./qemu-system-ppc
+- pyvenv/bin/python3 scripts/device-crash-test -q ./qemu-system-riscv32
 
 build-system-centos:
   extends:
diff --git a/docs/devel/acpi-bits.rst b/docs/devel/acpi-bits.rst
index 22e2580200c..9677b0098f4 100644
--- a/docs/devel/acpi-bits.rst
+++ b/docs/devel/acpi-bits.rst
@@ -61,19 +61,19 @@ Under ``tests/avocado/`` as the root we have:
::
 
  $ make check-venv (needed only the first time to create the venv)
- $ ./tests/venv/bin/avocado run -t acpi tests/avocado
+ $ ./pyvenv/bin/avocado run -t acpi tests/avocado
 
The above will run all acpi avocado tests including this one.
In order to run the individual tests, perform the following:
::
 
- $ ./tests/venv/bin/avocado run tests/avocado/acpi-bits.py --tap -
+ $ ./pyvenv/bin/avocado run tests/avocado/acpi-bits.py --tap -
 
The above will produce output in tap format. You can omit "--tap -" in the
end and it will produce output like the following:
::
 
-  $ ./tests/venv/bin/avocado run tests/avocado/acpi-bits.py
+  $ ./pyvenv/bin/avocado run tests/avocado/acpi-bits.py
   Fetching asset from 
tests/avocado/acpi-bits.py:AcpiBitsTest.test_acpi_smbios_bits
   JOB ID : eab225724da7b64c012c65705dc2fa14ab1defef
   JOB LOG: 
/home/anisinha/avocado/job-results/job-2022-10-10T17.58-eab2257/job.log
diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index b6ad21bed1c..5d1fc0aa95f 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -894,9 +894,9 @@ You can run the avocado tests simply by executing:
 
   make check-avocado
 
-This involves the automatic creation of Python virtual environment
-within the build tree (at ``tests/venv``) which will have all the
-right dependencies, and will save tests results also within the
+This involves the automatic installation, from PyPI, of all the
+necessary avocado-framework dependencies into the QEMU venv within the
+build tree (at ``./pyvenv``). Test results are also saved within the
 build tree (at ``tests/results``).
 
 Note: the build environment must be using a Python 3 stack, and have
@

[PATCH 0/9] Use known good releases when installing in pyvenv

2023-08-09 Thread Paolo Bonzini
This series introduce a new installation command for mkvenv.py that
retrieves the packages to be installed from a TOML file. This allows
being more flexible in using the system version of a package, while at
the same time using a known-good version when installing the package.
This is important for packages that sometimes have backwards-incompatible
changes or that depend on specific versions of their dependencies.

For example, in the case of sphinx we can always use the last version
that supports older versions of Python and especially docutils (Ubuntu
20.04 for example would not support sphinx 6.0), and in the case of
Avocado we can avoid installing a package that conflicts with any
plugins already existing in the system package path.  This in turn
enables using the same virtual environment for both the build and
qemu-iotests.  John has patches for this.

For the configuration file, TOML was chosen because it was more human
readable and easier to edit than JSON.  A parser is available in the
Python 3.11 standard library; for older versions, the API-compatible
replacement tomli is very small (12k).  I am introducing it as a vendored
.whl file because it is not installed by default in most distros (unlike
pip and setuptools which were introduced in 8.0) and because Debian
11 only has it in bullseye-backports.  However, if preferred the patch
"python: use vendored tomli" can be dropped.  In that case, tomli will
have to be installed from either PyPI or bullseye-backports.

While tomli is bundled with pip, this is only true of recent versions
of pip.  Of all the supported OSes pretty much only FreeBSD has a recent
enough version of pip while staying on Python <3.11.  So we cannot use
the same trick that is in place for distlib.

In order to pick the tomli mapping, lcitool is updated to a recent
version.  As a side effect this updates from LEAP 15.4 to 15.5.

Paolo


Paolo Bonzini (9):
  python: mkvenv: tweak the matching of --diagnose to depspecs
  python: mkvenv: introduce TOML-like representation of dependencies
  python: mkvenv: add ensuregroup command
  lcitool: bump libvirt-ci submodule and regenerate
  configure: never use PyPI for Meson
  python: use vendored tomli
  configure: switch to ensuregroup
  Revert "tests: Use separate virtual environment for avocado"
  tests/docker: add python3-tomli dependency to containers

 .gitlab-ci.d/buildtest.yml|   6 +-
 .gitlab-ci.d/cirrus/freebsd-13.vars   |   2 +-
 .gitlab-ci.d/cirrus/macos-12.vars |   2 +-
 configure |  22 +-
 docs/devel/acpi-bits.rst  |   6 +-
 docs/devel/testing.rst|  14 +-
 python/scripts/mkvenv.py  | 201 --
 python/scripts/vendor.py  |   5 +-
 python/setup.cfg  |   9 +
 python/wheels/tomli-2.0.1-py3-none-any.whl| Bin 0 -> 12757 bytes
 pythondeps.toml   |  32 +++
 .../org.centos/stream/8/x86_64/test-avocado   |   4 +-
 scripts/device-crash-test |   2 +-
 tests/Makefile.include|  19 +-
 tests/docker/dockerfiles/centos8.docker   |   3 +-
 .../dockerfiles/debian-all-test-cross.docker  |   7 +-
 .../dockerfiles/debian-amd64-cross.docker |   6 +-
 tests/docker/dockerfiles/debian-amd64.docker  |   4 +
 .../dockerfiles/debian-arm64-cross.docker |   6 +-
 .../dockerfiles/debian-armel-cross.docker |   6 +-
 .../dockerfiles/debian-armhf-cross.docker |   6 +-
 .../dockerfiles/debian-hexagon-cross.docker   |   6 +-
 .../dockerfiles/debian-mips64el-cross.docker  |   6 +-
 .../dockerfiles/debian-mipsel-cross.docker|   6 +-
 .../dockerfiles/debian-ppc64el-cross.docker   |   6 +-
 .../dockerfiles/debian-riscv64-cross.docker   |   2 +-
 .../dockerfiles/debian-s390x-cross.docker |   6 +-
 .../dockerfiles/debian-tricore-cross.docker   |   2 +
 .../dockerfiles/fedora-i386-cross.docker  |   1 +
 .../dockerfiles/fedora-win32-cross.docker |   2 +-
 .../dockerfiles/fedora-win64-cross.docker |   2 +-
 tests/docker/dockerfiles/opensuse-leap.docker |  23 +-
 tests/docker/dockerfiles/ubuntu2004.docker|   4 +-
 tests/docker/dockerfiles/ubuntu2204.docker|   1 +
 tests/lcitool/libvirt-ci  |   2 +-
 tests/lcitool/mappings.yml|  27 ++-
 tests/lcitool/projects/qemu.yml   |   3 +-
 tests/lcitool/targets/opensuse-leap-15.yml|   4 +-
 tests/requirements.txt|   6 -
 tests/vm/Makefile.include |   2 +-
 tests/vm/generated/freebsd.json   |   1 +
 41 files changed, 371 insertions(+), 103 deletions(-)
 create mode 100644 python/wheels/tomli-2.0.1-py3-none-any.whl
 create mode 100644 pythondeps.toml
 delete mode 100644 tests/requirements.txt

-- 
2.41.0




[PATCH 6/9] python: use vendored tomli

2023-08-09 Thread Paolo Bonzini
Debian only introduced tomli in the bookworm release.  Use a
vendored wheel to avoid requiring a package that is only in
bullseye-backports and is also absent in Ubuntu 20.04.

While at it, fix an issue in the vendor.py scripts which does
not add a newline after each package and hash.

Signed-off-by: Paolo Bonzini 
---
 configure  |   6 ++
 python/scripts/vendor.py   |   5 -
 python/wheels/tomli-2.0.1-py3-none-any.whl | Bin 0 -> 12757 bytes
 3 files changed, 10 insertions(+), 1 deletion(-)
 create mode 100644 python/wheels/tomli-2.0.1-py3-none-any.whl

diff --git a/configure b/configure
index f13f0662b98..347153702c1 100755
--- a/configure
+++ b/configure
@@ -1018,6 +1018,12 @@ fi
 python="$python -B"
 mkvenv="$python ${source_path}/python/scripts/mkvenv.py"
 
+# Finish preparing the virtual environment using vendored .whl files
+
+if $python -c 'import sys; sys.exit(sys.version_info >= (3,11))'; then
+$mkvenv ensure --dir "${source_path}/python/wheels" \
+'tomli>=1.2.0' || exit 1
+fi
 if ! $mkvenv ensure \
  --dir "${source_path}/python/wheels" \
  --diagnose "meson" \
diff --git a/python/scripts/vendor.py b/python/scripts/vendor.py
index 34486a51f44..76274871170 100755
--- a/python/scripts/vendor.py
+++ b/python/scripts/vendor.py
@@ -43,13 +43,16 @@ def main() -> int:
 packages = {
 "meson==0.63.3":
 "d677b809c4895dcbaac9bf6c43703fcb3609a4b24c6057c78f828590049cf43a",
+
+"tomli==2.0.1":
+"939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
 }
 
 vendor_dir = Path(__file__, "..", "..", "wheels").resolve()
 
 with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8") as file:
 for dep_spec, checksum in packages.items():
-file.write(f"{dep_spec} --hash=sha256:{checksum}")
+print(f"{dep_spec} --hash=sha256:{checksum}", file=file)
 file.flush()
 
 cli_args = [
diff --git a/python/wheels/tomli-2.0.1-py3-none-any.whl 
b/python/wheels/tomli-2.0.1-py3-none-any.whl
new file mode 100644
index 
..29670b98d16e2bc770d4fea718582e1dc0dd8aca
GIT binary patch
literal 12757
zcmZ{K19T?cvi6(2v8{=1TN67I+qN;W?TKyMwlT47dy-6?{B!QT=Y02k_dnfhuU_4&
zpQrb(uBz4bbjeEt!O#Ez02H7}RYJMAoa`MF1OSNoGm!sWb+)sywqVfHv#_;r*3+Z6
zch`}hi0BtU>O7{2a9ah3PcNtq)hCA71L7L+!5ht;=`*8pC+Iw0f6veEbjEa6aZ!t{
z-7eZr5K1xTPCr1$E}2eui*cb3n04x0V575s9eHtd3AnP2al@G=Ow7|XTHLl>i@Uu~
zQ2;lqTW6Tfh`@q@wZc7Dx~3&*V^rA36cr>aDz~D#4UVmCEh*IfIByKl8D&D${Pjy<~={mz=uH0
z;OKxG#BXMAx=t8hwKuh0k+D=iu>QdmGLYQ_>$QTHK(gPU>jK%Hve4f5qUJ)GmUw5^
zilT(pi7l$g-h5`|Q5ZK@Iy|sLApdVx1nrKoh{6B>EYtx2q`$0aZ{X-;;`qmiL%gew
z>k{$TZxNPH{>B-G()C>|lj^cyTE!*UBx4BSTcyxf1Z1UB>@D~ux!JK>x35$}xoWyMldsqH<45+0P?zA!=C
zrmO~iH3qtRxp@te>kbb1y{B()f+NS~wt=ylY5e5Z@z!@|J%+wpvA{KvWSnT=G#FS9
zx`qzx-jZob`TJmBX$^<>dw!!_f*H6^ke
z+osYFw-rsfaF|qDyxGvI*_|vQ^>NGWh1~?hFJ~V(sT=WuCT4KQ^}VQrwHrE4@PeNa
zJ@3x2Uu>Q?ylKO2yADm5HTL2^D}yv6kP9_iN{F03?unuwnodf2mgb1uY)iSNRll9v
zXZ+n&d*q&2W6FEl)Eim{s+XBAt(HCe9O@hsU^(M;|h~dZgYrt!2
zm7oomE|;Ut2;g?~{N3WDXo5e3_L<}k1wsCeS5kjtK)m@r-yOb8gRns_Fw#8rG
zE=5nBoH$F!&665^%LM5GYn_l5||zSlb;T
zPfBsV-1?-Wb_u-H@@SvC@GGa&q2iPKgvZp;{OlgV^!`OwS1b&0`>$x3p7%)<*zJbL
zyFg7sq;WO;yuv~w%=ZDnrcdhcRqW|CsuNskql<)quW*4wBz1ujWy0xCtXouY
zkK9448_4P&GU{B`4KWU*h^L;JB-;dc)>&p*u-T?wANcCm&Yl;-C!57t)h7*LhkX*z
zoeYgBmWEI$_|=^}SH)Wa9m97qe53&sL>yT1`skfRvP6JgCO8P=41{4CBmzI6jst^K
z8J8wzB2qYS^xfcbK>RBi^(N_+FWM0`hgMTxE
zL|v$y=eVB49Qew9_W|LUFanUp!|!%7OaPh1&wro~!kV1zhD)C}-H0T!6uu^I?f^p|7ZDsKSgrTwNWJir;O)LV=?7bwZ~3-lAZrNHYo2k`4GU27
z`X04*5_Afhs%sN%;1Mmi0JX!e(AWEMbULIE@+6>(esH%$x}Jb(~vJWJ7@Qf{$44
z7e~`MjMB^Qul>&``bN2BBtbO&yYN&p;~W+Q)6}oI*a(bF=-i0mR1#y5_sE>#Sikl~
zgsA#kaDi~Ytf$zBvbkx!qnNJ+kr-bt=U1Q5>Qf?T7lSO?4Bigg1<{PF*CpLsb7x@a
zf|0%Z_q(M-4E05Ho@`*^va_Y>ir^La2nE}xYHb~4UHl2hi&x<9ifsjhIC8A^1NA*P
zae)d_0s_E`6^YE?dc<1pES|*%EB&&SHi+apoIDWuUbTU=qSOU|``o5SZlVu@|F)XX
zFOYuW0pw-mOX2&3RFpBMCTF5f>al_lZRZ$LMLv0Uict{f9(-I}S(|zTk8K4*Fghfu
zMW_@-9w6RFTX%*o4>EYs)IxqqPs}o9lvVF4i3j`^rG+hy$vB|#0>T<&#Gua^`S?$Q
z-M%0Oy?aos(hIu
zNyBgOO4B$lGAspX1-ABRdI1n)kREccqQQ%*&@pl4jt`vs3Pfr{utt-{gI7;tWIh8RC+#@megPSS`mU#fH7)V&_Opu`m;3Y82H>SSO@
zXwpwC!!D5^Bz`DbM1(GADdp+uudt_;GAk#5N0@?!sSyrGdTsU5^GW%1JUpST1Qx((
z=QqK@q*Z~C<*OjoQ-*Ufp0x%D4g2-iV(UQ&Xf_9#5#p3+EwO>w1<@vU&DYLpLNnIp
zR8%VpfUUZFuqV_z3Yp&lWOTmr$vt$c9Wr%EkV}pj>+7q7dr$(Eq`-{f=f0tv
z5TPhWfmG`}P=W_sTY4i>yd^?lZo!DC{wA~3p}x(pBLYmC#K3c{;ykf9Wx7}+XNhYd
z!8GJk*-1VHc!UF-81|bQ8I+m7@0-ihnjwAvt(7tYYvArt1@9%Sdpy3ue)|f-JdYe^
zVrx~anRs*l63W}}f0EvAi`<|TProaOq;QZe7m!O3Z#Gh?)e<$9i}Voaj9=I@;y*g=
zzzB(Q(74XIHs@v8$By_yK1a4nV2%P_|I<(N;5n7>E0yzLXc>OIfOJhHj<93{N0f;Z
zm1VoE(ZmCJ1CHsE8tIS;n<@brB(3*@GKj9!L!m2Pz1it#IG()=hYT@Q-U9gYfg=9(
z*0KhumaYq#jrr*mrP)u&8WZf0j6q(m7ilOV{eGC0nm^7sOxLlQO-Lom7y=uM4FCaaPhQVi1j8TY21d4uA-&zcAjg)WTa8$
zCbQG1WXx1bYxTQ{W@V{wy-ih>sw&T-;~v(O=RF!)JqqA;plP>jili1riMuqviFPv&
zbXddoJQZxbkT
z`^BTGlo-#6cq3B!Xa(4ic(TU#Ke|lib)r5#zXt0vhL$H##s?qMHJq$uiWUtq@_1C{
zNbouNw>boNqv4ff&!M6)Q$!5LPUJ&WBt5irMSS0)b%{ink)g-$V(%?|

[PATCH 9/9] tests/docker: add python3-tomli dependency to containers

2023-08-09 Thread Paolo Bonzini
Instead of having CI pick tomli from the vendored wheel at configure
time, place it in the containers.

Signed-off-by: Paolo Bonzini 
---
 .gitlab-ci.d/cirrus/freebsd-13.vars   |  2 +-
 .gitlab-ci.d/cirrus/macos-12.vars |  2 +-
 tests/docker/dockerfiles/centos8.docker   |  3 ++-
 .../dockerfiles/debian-all-test-cross.docker  |  7 ++-
 .../docker/dockerfiles/debian-amd64-cross.docker  |  4 
 tests/docker/dockerfiles/debian-amd64.docker  |  4 
 .../docker/dockerfiles/debian-arm64-cross.docker  |  4 
 .../docker/dockerfiles/debian-armel-cross.docker  |  4 
 .../docker/dockerfiles/debian-armhf-cross.docker  |  4 
 .../dockerfiles/debian-hexagon-cross.docker   |  6 +-
 .../dockerfiles/debian-mips64el-cross.docker  |  4 
 .../docker/dockerfiles/debian-mipsel-cross.docker |  4 
 .../dockerfiles/debian-ppc64el-cross.docker   |  4 
 .../docker/dockerfiles/debian-s390x-cross.docker  |  4 
 .../dockerfiles/debian-tricore-cross.docker   |  2 ++
 tests/docker/dockerfiles/fedora-i386-cross.docker |  1 +
 tests/docker/dockerfiles/opensuse-leap.docker |  3 ++-
 tests/docker/dockerfiles/ubuntu2004.docker|  4 +++-
 tests/docker/dockerfiles/ubuntu2204.docker|  1 +
 tests/lcitool/mappings.yml| 15 +++
 tests/lcitool/projects/qemu.yml   |  1 +
 tests/vm/generated/freebsd.json   |  1 +
 22 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/.gitlab-ci.d/cirrus/freebsd-13.vars 
b/.gitlab-ci.d/cirrus/freebsd-13.vars
index facb649f5bd..3785afca36d 100644
--- a/.gitlab-ci.d/cirrus/freebsd-13.vars
+++ b/.gitlab-ci.d/cirrus/freebsd-13.vars
@@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
 NINJA='/usr/local/bin/ninja'
 PACKAGING_COMMAND='pkg'
 PIP3='/usr/local/bin/pip-3.8'
-PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cmocka ctags curl 
cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls 
gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp 
libspice-server libssh libtasn1 llvm lzo2 meson mtools ncurses nettle ninja 
opencv pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx 
py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio 
socat spice-protocol tesseract usbredir virglrenderer vte3 xorriso zstd'
+PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cmocka ctags curl 
cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls 
gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp 
libspice-server libssh libtasn1 llvm lzo2 meson mtools ncurses nettle ninja 
opencv pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx 
py39-sphinx_rtd_theme py39-tomli py39-yaml python3 rpm2cpio sdl2 sdl2_image 
snappy sndio socat spice-protocol tesseract usbredir virglrenderer vte3 xorriso 
zstd'
 PYPI_PKGS=''
 PYTHON='/usr/local/bin/python3'
diff --git a/.gitlab-ci.d/cirrus/macos-12.vars 
b/.gitlab-ci.d/cirrus/macos-12.vars
index ceb294e1539..80eadaab296 100644
--- a/.gitlab-ci.d/cirrus/macos-12.vars
+++ b/.gitlab-ci.d/cirrus/macos-12.vars
@@ -12,5 +12,5 @@ NINJA='/opt/homebrew/bin/ninja'
 PACKAGING_COMMAND='brew'
 PIP3='/opt/homebrew/bin/pip3'
 PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc 
flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c 
libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 
libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config 
python3 rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol tesseract 
usbredir vde vte3 xorriso zlib zstd'
-PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme'
+PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli'
 PYTHON='/opt/homebrew/bin/python3'
diff --git a/tests/docker/dockerfiles/centos8.docker 
b/tests/docker/dockerfiles/centos8.docker
index da7dc818fb6..fc1830966f4 100644
--- a/tests/docker/dockerfiles/centos8.docker
+++ b/tests/docker/dockerfiles/centos8.docker
@@ -133,7 +133,8 @@ RUN /usr/bin/pip3.8 install \
 meson==0.63.2 \
 pillow \
 sphinx \
-sphinx-rtd-theme
+sphinx-rtd-theme \
+tomli
 
 ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
 ENV LANG "en_US.UTF-8"
diff --git a/tests/docker/dockerfiles/debian-all-test-cross.docker 
b/tests/docker/dockerfiles/debian-all-test-cross.docker
index f9f401544a0..54e957d5e74 100644
--- a/tests/docker/dockerfiles/debian-all-test-cross.docker
+++ b/tests/docker/dockerfiles/debian-all-test-cross.docker
@@ -58,7 +58,12 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
 libc6-dev-sh4-cross \
 gcc-sparc64-linux-gnu \
 libc6-dev-sparc64-cross \
-python3-venv
+python3-pip \
+python3-setuptools \
+python3-venv \
+   

[PATCH 3/9] python: mkvenv: add ensuregroup command

2023-08-09 Thread Paolo Bonzini
Introduce a new subcommand that retrieves the packages to be installed
from a TOML file. This allows being more flexible in using the system
version of a package, while at the same time using a known-good version
when installing the package.  This is important for packages that
sometimes have backwards-incompatible changes or that depend on
specific versions of their dependencies.

Compared to JSON, TOML is more human readable and easier to edit.  A
parser is available in 3.11 but also available as a small (12k) package
for older versions, tomli.  While tomli is bundled with pip, this is only
true of recent versions of pip.  Of all the supported OSes pretty much
only FreeBSD has a recent enough version of pip while staying on Python
<3.11.  So we cannot use the same trick that is in place for distlib.

Signed-off-by: Paolo Bonzini 
---
 python/scripts/mkvenv.py | 126 ++-
 python/setup.cfg |   9 +++
 pythondeps.toml  |  17 ++
 3 files changed, 151 insertions(+), 1 deletion(-)
 create mode 100644 pythondeps.toml

diff --git a/python/scripts/mkvenv.py b/python/scripts/mkvenv.py
index 96f506d7e22..02bcd9a8c92 100644
--- a/python/scripts/mkvenv.py
+++ b/python/scripts/mkvenv.py
@@ -14,6 +14,8 @@
 post_init
   post-venv initialization
 ensureEnsure that the specified package is installed.
+ensuregroup
+  Ensure that the specified package group is installed.
 
 --
 
@@ -44,6 +46,19 @@
   --onlineInstall packages from PyPI, if necessary.
   --dir DIR   Path to vendored packages where we may install from.
 
+--
+
+usage: mkvenv ensuregroup [-h] [--online] [--dir DIR] file group...
+
+positional arguments:
+  filepointer to a TOML file
+  group   section name in the TOML file
+
+options:
+  -h, --help  show this help message and exit
+  --onlineInstall packages from PyPI, if necessary.
+  --dir DIR   Path to vendored packages where we may install from.
+
 """
 
 # The duplication between importlib and pkg_resources does not help
@@ -99,6 +114,18 @@
 except ImportError:
 HAVE_DISTLIB = False
 
+# Try to load tomllib, with a fallback to tomli.
+# HAVE_TOMLLIB is checked below, just-in-time, so that mkvenv does not fail
+# outside the venv or before a potential call to ensurepip in checkpip().
+HAVE_TOMLLIB = True
+try:
+import tomllib
+except ImportError:
+try:
+import tomli as tomllib
+except ImportError:
+HAVE_TOMLLIB = False
+
 # Do not add any mandatory dependencies from outside the stdlib:
 # This script *must* be usable standalone!
 
@@ -837,6 +864,7 @@ def _do_ensure(
 for name, info in group.items():
 constraint = _make_version_constraint(info, False)
 matcher = distlib.version.LegacyMatcher(name + constraint)
+print(f"mkvenv: checking for {matcher}", file=sys.stderr)
 ver = _get_version(name)
 if (
 ver is None
@@ -898,7 +926,6 @@ def ensure(
 be presented to the user. e.g., 'sphinx-build' can be used as a
 bellwether for the presence of 'sphinx'.
 """
-print(f"mkvenv: checking for {', '.join(dep_specs)}", file=sys.stderr)
 
 if not HAVE_DISTLIB:
 raise Ouch("a usable distlib could not be found, please install it")
@@ -928,6 +955,64 @@ def ensure(
 raise SystemExit(f"\n{result[0]}\n\n")
 
 
+def _parse_groups(file: str) -> Dict[str, Dict[str, Any]]:
+if not HAVE_TOMLLIB:
+if sys.version_info < (3, 11):
+raise Ouch("found no usable tomli, please install it")
+
+raise Ouch(
+"Python >=3.11 does not have tomllib... what have you done!?"
+)
+
+try:
+# Use loads() to support both tomli v1.2.x (Ubuntu 22.04,
+# Debian bullseye-backports) and v2.0.x
+with open(file, "r", encoding="ascii") as depfile:
+contents = depfile.read()
+return tomllib.loads(contents)  # type: ignore
+except tomllib.TOMLDecodeError as exc:
+raise Ouch(f"parsing {file} failed: {exc}") from exc
+
+
+def ensure_group(
+file: str,
+groups: Sequence[str],
+online: bool = False,
+wheels_dir: Optional[Union[str, Path]] = None,
+) -> None:
+"""
+Use pip to ensure we have the package specified by @dep_specs.
+
+If the package is already installed, do nothing. If online and
+wheels_dir are both provided, prefer packages found in wheels_dir
+first before connecting to PyPI.
+
+:param dep_specs:
+PEP 508 dependency specifications. e.g. ['meson>=0.61.5'].
+:param online: If True, fall back to PyPI.
+:param wheels_dir: If specified, search this path for packages.
+"""
+
+if not HAVE_DISTLIB:
+raise Ouch("found no usable distlib, please install it")
+
+parsed_deps = _parse_groups(file)
+
+to_install: Dict[str, Dict[str,

[PATCH 5/9] configure: never use PyPI for Meson

2023-08-09 Thread Paolo Bonzini
Since there is a vendored copy, there is no point in choosing online
operation.

Signed-off-by: Paolo Bonzini 
---
 configure | 6 --
 1 file changed, 6 deletions(-)

diff --git a/configure b/configure
index f2bd8858d6c..f13f0662b98 100755
--- a/configure
+++ b/configure
@@ -1018,13 +1018,7 @@ fi
 python="$python -B"
 mkvenv="$python ${source_path}/python/scripts/mkvenv.py"
 
-mkvenv_flags=""
-if test "$download" = "enabled" ; then
-mkvenv_flags="--online"
-fi
-
 if ! $mkvenv ensure \
- $mkvenv_flags \
  --dir "${source_path}/python/wheels" \
  --diagnose "meson" \
  "meson>=0.63.0" ;
-- 
2.41.0




[PATCH 7/9] configure: switch to ensuregroup

2023-08-09 Thread Paolo Bonzini
Using the new ensuregroup command, the desired versions of meson and
sphinx can be placed in pythondeps.toml rather than configure.

The meson.install entry in pythondeps.toml matches the version that is
found in python/wheels.  This ensures that mkvenv.py uses the bundled
wheel even if PyPI is enabled; thus not introducing warnings or errors
from versions that are more recent than the one used in CI.

The sphinx entries match what is shipped in Fedora 38.  It's the
last release that has support for older versions of Python (sphinx 6.0
requires Python 3.8) and especially docutils (of which sphinx 6.0 requires
version 0.18).  This is important because Ubuntu 20.04 has docutils 0.14
and Debian 11 has docutils 0.16.

"mkvenv.py ensure" is only used to bootstrap tomli.

Signed-off-by: Paolo Bonzini 
---
 configure   | 14 --
 pythondeps.toml |  8 
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/configure b/configure
index 347153702c1..e4d42d640e4 100755
--- a/configure
+++ b/configure
@@ -1024,13 +1024,8 @@ if $python -c 'import sys; sys.exit(sys.version_info >= 
(3,11))'; then
 $mkvenv ensure --dir "${source_path}/python/wheels" \
 'tomli>=1.2.0' || exit 1
 fi
-if ! $mkvenv ensure \
- --dir "${source_path}/python/wheels" \
- --diagnose "meson" \
- "meson>=0.63.0" ;
-then
-exit 1
-fi
+$mkvenv ensuregroup --dir "${source_path}/python/wheels" \
+ "${source_path}/pythondeps.toml" meson || exit 1
 
 # At this point, we expect Meson to be installed and available.
 # We expect mkvenv or pip to have created pyvenv/bin/meson for us.
@@ -1047,10 +1042,9 @@ if test "$download" = "enabled" -a "$docs" = "enabled" ; 
then
 fi
 
 if test "$docs" != "disabled" ; then
-if ! $mkvenv ensure \
+if ! $mkvenv ensuregroup \
  $mkvenv_flags \
- --diagnose "sphinx-build" \
- "sphinx>=1.6.0" "sphinx-rtd-theme>=0.5.0";
+ "${source_path}/pythondeps.toml" docs;
 then
 if test "$docs" = "enabled" ; then
 exit 1
diff --git a/pythondeps.toml b/pythondeps.toml
index 362f63ff2c9..6be31dba301 100644
--- a/pythondeps.toml
+++ b/pythondeps.toml
@@ -15,3 +15,11 @@
 #   precise error diagnostics to the user.  For example,
 #   'sphinx-build' can be used as a bellwether for the
 #   presence of 'sphinx' in the system.
+
+[meson]
+# The install key should match the version in python/wheels/
+meson = { accepted = ">=0.63.0", installed = "0.63.3", canary = "meson" }
+
+[docs]
+sphinx = { accepted = ">=1.6", installed = "5.3.0", canary = "sphinx-build" }
+sphinx_rtd_theme = { accepted = ">=0.5", installed = "1.1.1" }
-- 
2.41.0




[PATCH] hw/ppc/e500: fix broken snapshot replay

2023-08-09 Thread Maksim Kostin
ppce500_reset_device_tree is registered for system reset, but after
c4b075318eb1 this function rerandomizes rng-seed via
qemu_guest_getrandom_nofail. And when loading a snapshot, it tries to read
EVENT_RANDOM that doesn't exist, so we have an error:

  qemu-system-ppc: Missing random event in the replay log

To fix this, use qemu_register_reset_nosnapshotload instead of
qemu_register_reset.

Reported-by: Vitaly Cheptsov 
Fixes: c4b075318eb1 ("hw/ppc: pass random seed to fdt ")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1634
Signed-off-by: Maksim Kostin 
---
 hw/ppc/e500.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 67793a86f1..d5b6820d1d 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -712,7 +712,7 @@ static int ppce500_prep_device_tree(PPCE500MachineState 
*machine,
 p->kernel_base = kernel_base;
 p->kernel_size = kernel_size;
 
-qemu_register_reset(ppce500_reset_device_tree, p);
+qemu_register_reset_nosnapshotload(ppce500_reset_device_tree, p);
 p->notifier.notify = ppce500_init_notify;
 qemu_add_machine_init_done_notifier(&p->notifier);
 
-- 
2.34.1




[PATCH v2] target/i386: Avoid cpu number overflow in legacy topology

2023-08-09 Thread Qian Wen
The legacy topology enumerated by CPUID.1.EBX[23:16] is defined in SDM
Vol2:

Bits 23-16: Maximum number of addressable IDs for logical processors in
this physical package.

When launching the VM with -smp 256, the value written to EBX[23:16] is
0 because of data overflow. If the guest only supports legacy topology,
without V2 Extended Topology enumerated by CPUID.0x1f or Extended
Topology enumerated by CPUID.0x0b to support over 255 CPUs, the return
of the kernel invoking cpu_smt_allowed() is false and AP's bring-up will
fail. Then only CPU 0 is online, and others are offline.

To avoid this issue caused by overflow, limit the max value written to
EBX[23:16] to 255.

Signed-off-by: Qian Wen 
---
Changes v1 -> v2:
 - Revise the commit message and comment to more clearer.
 - Rebased to v8.1.0-rc2.
---
 target/i386/cpu.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 97ad229d8b..6e1d88fbd7 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6008,6 +6008,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 uint32_t die_offset;
 uint32_t limit;
 uint32_t signature[3];
+uint32_t threads_per_socket;
 X86CPUTopoInfo topo_info;
 
 topo_info.dies_per_pkg = env->nr_dies;
@@ -6049,8 +6050,19 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 *ecx |= CPUID_EXT_OSXSAVE;
 }
 *edx = env->features[FEAT_1_EDX];
-if (cs->nr_cores * cs->nr_threads > 1) {
-*ebx |= (cs->nr_cores * cs->nr_threads) << 16;
+/*
+ * Only bits [23:16] represent the maximum number of addressable
+ * IDs for logical processors in this physical package.
+ * When thread_per_socket > 255, it will 1) overwrite bits[31:24]
+ * which is apic_id, 2) bits [23:16] get truncated.
+ */
+threads_per_socket = cs->nr_cores * cs->nr_threads;
+if (threads_per_socket > 255) {
+threads_per_socket = 255;
+}
+
+if (threads_per_socket > 1) {
+*ebx |= threads_per_socket << 16;
 *edx |= CPUID_HT;
 }
 if (!cpu->enable_pmu) {
-- 
2.25.1




[PATCH] hw/pci-host: Allow extended config space access for Designware PCIe host

2023-08-09 Thread Jason Chien
In pcie_bus_realize(), a root bus is realized as a PCIe bus and a non-root
bus is realized as a PCIe bus if its parent bus is a PCIe bus. However,
the child bus "dw-pcie" is realized before the parent bus "pcie" which is
the root PCIe bus. Thus, the extended configuration space is not accessible
on "dw-pcie". The issue can be resolved by adding the
PCI_BUS_EXTENDED_CONFIG_SPACE flag to "pcie" before "dw-pcie" is realized.

Signed-off-by: Jason Chien 
---
 hw/pci-host/designware.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index 9e183caa48..388d252ee2 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -694,6 +694,7 @@ static void designware_pcie_host_realize(DeviceState *dev, 
Error **errp)
  &s->pci.io,
  0, 4,
  TYPE_PCIE_BUS);
+pci->bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
 
 memory_region_init(&s->pci.address_space_root,
OBJECT(s),
-- 
2.17.1




Re: [PATCH 0/2] hw/nvme: two fixes

2023-08-09 Thread Jesper Devantier
On Tue, Aug 08, 2023 at 05:16:12PM +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> Fix two potential accesses to null pointers.
> 
> Klaus Jensen (2):
>   hw/nvme: fix null pointer access in directive receive
>   hw/nvme: fix null pointer access in ruh update
> 
>  hw/nvme/ctrl.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> -- 
> 2.41.0
> 
> 

Reviewed-by: Jesper Wendel Devantier 


Re: [PATCH for-8.1] tests/tcg: Disable filename test for info proc mappings

2023-08-09 Thread Ilya Leoshkevich
On Tue, 2023-08-08 at 16:49 -0700, Richard Henderson wrote:
> This test fails when host page size != guest page size,
> because qemu may not be able to directly map the file.
> 
> Fixes: a6341482695 ("tests/tcg: Add a test for info proc mappings")
> Signed-off-by: Richard Henderson 
> ---
>  tests/tcg/multiarch/gdbstub/test-proc-mappings.py | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/tcg/multiarch/gdbstub/test-proc-mappings.py
> b/tests/tcg/multiarch/gdbstub/test-proc-mappings.py
> index 7b596ac21b..5e3e5a2fb7 100644
> --- a/tests/tcg/multiarch/gdbstub/test-proc-mappings.py
> +++ b/tests/tcg/multiarch/gdbstub/test-proc-mappings.py
> @@ -33,7 +33,8 @@ def run_test():
>  return
>  raise
>  report(isinstance(mappings, str), "Fetched the mappings from the
> inferior")
> -    report("/sha1" in mappings, "Found the test binary name in the
> mappings")
> +    # Broken with host page size > guest page size
> +    # report("/sha1" in mappings, "Found the test binary name in the
> mappings")
>  
>  
>  def main():

I'll try to find a way to check host/guest page sizes in Python for
8.2. I think it's fine to disable the check for 8.1.

Acked-by: Ilya Leoshkevich 



Re: [PATCH v2 3/7] tcg/ppc: Use prefixed instructions in tcg_out_mem_long

2023-08-09 Thread Nicholas Piggin
On Tue Aug 8, 2023 at 1:02 PM AEST, Richard Henderson wrote:
> When the offset is out of range of the non-prefixed insn, but
> fits the 34-bit immediate of the prefixed insn, use that.
>

The switch will fall through in some cases (at least opi == 0).
Should it have a default: break; to make that obvious?

Reviewed-by: Nicholas Piggin 

> Reviewed-by: Jordan Niethe 
> Signed-off-by: Richard Henderson 
> ---
>  tcg/ppc/tcg-target.c.inc | 66 
>  1 file changed, 66 insertions(+)
>
> diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
> index 2141c0bc78..61ae9d8ab7 100644
> --- a/tcg/ppc/tcg-target.c.inc
> +++ b/tcg/ppc/tcg-target.c.inc
> @@ -323,6 +323,15 @@ static bool tcg_target_const_match(int64_t val, TCGType 
> type, int ct)
>  #define STDX   XO31(149)
>  #define STQXO62(  2)
>  
> +#define PLWA   OPCD( 41)
> +#define PLDOPCD( 57)
> +#define PLXSD  OPCD( 42)
> +#define PLXV   OPCD(25 * 2 + 1)  /* force tx=1 */
> +
> +#define PSTD   OPCD( 61)
> +#define PSTXSD OPCD( 46)
> +#define PSTXV  OPCD(27 * 2 + 1)  /* force sx=1 */
> +
>  #define ADDIC  OPCD( 12)
>  #define ADDI   OPCD( 14)
>  #define ADDIS  OPCD( 15)
> @@ -725,6 +734,20 @@ static ptrdiff_t tcg_pcrel_diff_for_prefix(TCGContext 
> *s, const void *target)
>  return tcg_pcrel_diff(s, target) - (tcg_out_need_prefix_align(s) ? 4 : 
> 0);
>  }
>  
> +/* Output Type 00 Prefix - 8-Byte Load/Store Form (8LS:D) */
> +static void tcg_out_8ls_d(TCGContext *s, tcg_insn_unit opc, unsigned rt,
> +  unsigned ra, tcg_target_long imm, bool r)
> +{
> +tcg_insn_unit p, i;
> +
> +p = OPCD(1) | (r << 20) | ((imm >> 16) & 0x3);
> +i = opc | TAI(rt, ra, imm);
> +
> +tcg_out_prefix_align(s);
> +tcg_out32(s, p);
> +tcg_out32(s, i);
> +}
> +
>  /* Output Type 10 Prefix - Modified Load/Store Form (MLS:D) */
>  static void tcg_out_mls_d(TCGContext *s, tcg_insn_unit opc, unsigned rt,
>unsigned ra, tcg_target_long imm, bool r)
> @@ -1368,6 +1391,49 @@ static void tcg_out_mem_long(TCGContext *s, int opi, 
> int opx, TCGReg rt,
>  break;
>  }
>  
> +/* For unaligned or large offsets, use the prefixed form. */
> +if (have_isa_3_10
> +&& (offset != (int16_t)offset || (offset & align))
> +&& offset == sextract64(offset, 0, 34)) {
> +/*
> + * Note that the MLS:D insns retain their un-prefixed opcode,
> + * while the 8LS:D insns use a different opcode space.
> + */
> +switch (opi) {
> +case LBZ:
> +case LHZ:
> +case LHA:
> +case LWZ:
> +case STB:
> +case STH:
> +case STW:
> +case ADDI:
> +tcg_out_mls_d(s, opi, rt, base, offset, 0);
> +return;
> +case LWA:
> +tcg_out_8ls_d(s, PLWA, rt, base, offset, 0);
> +return;
> +case LD:
> +tcg_out_8ls_d(s, PLD, rt, base, offset, 0);
> +return;
> +case STD:
> +tcg_out_8ls_d(s, PSTD, rt, base, offset, 0);
> +return;
> +case LXSD:
> +tcg_out_8ls_d(s, PLXSD, rt & 31, base, offset, 0);
> +return;
> +case STXSD:
> +tcg_out_8ls_d(s, PSTXSD, rt & 31, base, offset, 0);
> +return;
> +case LXV:
> +tcg_out_8ls_d(s, PLXV, rt & 31, base, offset, 0);
> +return;
> +case STXV:
> +tcg_out_8ls_d(s, PSTXV, rt & 31, base, offset, 0);
> +return;
> +}
> +}
> +
>  /* For unaligned, or very large offsets, use the indexed form.  */
>  if (offset & align || offset != (int32_t)offset || opi == 0) {
>  if (rs == base) {




Re: [PATCH v2] target/i386: Avoid cpu number overflow in legacy topology

2023-08-09 Thread Igor Mammedov
On Wed,  9 Aug 2023 18:27:32 +0800
Qian Wen  wrote:

> The legacy topology enumerated by CPUID.1.EBX[23:16] is defined in SDM
> Vol2:
> 
> Bits 23-16: Maximum number of addressable IDs for logical processors in
> this physical package.
> 
> When launching the VM with -smp 256, the value written to EBX[23:16] is
> 0 because of data overflow. If the guest only supports legacy topology,
> without V2 Extended Topology enumerated by CPUID.0x1f or Extended
> Topology enumerated by CPUID.0x0b to support over 255 CPUs, the return
> of the kernel invoking cpu_smt_allowed() is false and AP's bring-up will
> fail. Then only CPU 0 is online, and others are offline.
> 
> To avoid this issue caused by overflow, limit the max value written to
> EBX[23:16] to 255.

what happens on real hw or in lack of thereof what SDM says about this
value when there is more than 255 threads?.


> Signed-off-by: Qian Wen 
> ---
> Changes v1 -> v2:
>  - Revise the commit message and comment to more clearer.
>  - Rebased to v8.1.0-rc2.
> ---
>  target/i386/cpu.c | 16 ++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 97ad229d8b..6e1d88fbd7 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -6008,6 +6008,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>  uint32_t die_offset;
>  uint32_t limit;
>  uint32_t signature[3];
> +uint32_t threads_per_socket;
>  X86CPUTopoInfo topo_info;
>  
>  topo_info.dies_per_pkg = env->nr_dies;
> @@ -6049,8 +6050,19 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>  *ecx |= CPUID_EXT_OSXSAVE;
>  }
>  *edx = env->features[FEAT_1_EDX];
> -if (cs->nr_cores * cs->nr_threads > 1) {
> -*ebx |= (cs->nr_cores * cs->nr_threads) << 16;
> +/*
> + * Only bits [23:16] represent the maximum number of addressable
> + * IDs for logical processors in this physical package.
> + * When thread_per_socket > 255, it will 1) overwrite bits[31:24]
> + * which is apic_id, 2) bits [23:16] get truncated.
> + */
> +threads_per_socket = cs->nr_cores * cs->nr_threads;
> +if (threads_per_socket > 255) {
> +threads_per_socket = 255;
> +}
> +
> +if (threads_per_socket > 1) {
> +*ebx |= threads_per_socket << 16;
>  *edx |= CPUID_HT;
>  }
>  if (!cpu->enable_pmu) {




Re: [PATCH v2 4/7] tcg/ppc: Use PLD in tcg_out_movi for constant pool

2023-08-09 Thread Nicholas Piggin
On Tue Aug 8, 2023 at 1:02 PM AEST, Richard Henderson wrote:
> The prefixed instruction has a pc-relative form to use here.

I don't understand this code very well but going by existing
relocs it looks okay.

Reviewed-by: Nicholas Piggin 

>
> Signed-off-by: Richard Henderson 
> ---
>  tcg/ppc/tcg-target.c.inc | 24 
>  1 file changed, 24 insertions(+)
>
> diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
> index 61ae9d8ab7..b3b2e9874d 100644
> --- a/tcg/ppc/tcg-target.c.inc
> +++ b/tcg/ppc/tcg-target.c.inc
> @@ -101,6 +101,10 @@
>  #define ALL_GENERAL_REGS  0xu
>  #define ALL_VECTOR_REGS   0xull
>  
> +#ifndef R_PPC64_PCREL34
> +#define R_PPC64_PCREL34  132
> +#endif
> +
>  #define have_isel  (cpuinfo & CPUINFO_ISEL)
>  
>  #ifndef CONFIG_SOFTMMU
> @@ -260,6 +264,19 @@ static bool reloc_pc14(tcg_insn_unit *src_rw, const 
> tcg_insn_unit *target)
>  return false;
>  }
>  
> +static bool reloc_pc34(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
> +{
> +const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
> +ptrdiff_t disp = tcg_ptr_byte_diff(target, src_rx);
> +
> +if (disp == sextract64(disp, 0, 34)) {
> +src_rw[0] = (src_rw[0] & ~0x3) | ((disp >> 16) & 0x3);
> +src_rw[1] = (src_rw[1] & ~0x) | (disp & 0x);
> +return true;
> +}
> +return false;
> +}
> +
>  /* test if a constant matches the constraint */
>  static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
>  {
> @@ -684,6 +701,8 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
>  return reloc_pc14(code_ptr, target);
>  case R_PPC_REL24:
>  return reloc_pc24(code_ptr, target);
> +case R_PPC64_PCREL34:
> +return reloc_pc34(code_ptr, target);
>  case R_PPC_ADDR16:
>  /*
>   * We are (slightly) abusing this relocation type.  In particular,
> @@ -,6 +1130,11 @@ static void tcg_out_movi_int(TCGContext *s, TCGType 
> type, TCGReg ret,
>  }
>  
>  /* Use the constant pool, if possible.  */
> +if (have_isa_3_10) {
> +tcg_out_8ls_d(s, PLD, ret, 0, 0, 1);
> +new_pool_label(s, arg, R_PPC64_PCREL34, s->code_ptr - 2, 0);
> +return;
> +}
>  if (!in_prologue && USE_REG_TB) {
>  new_pool_label(s, arg, R_PPC_ADDR16, s->code_ptr,
> tcg_tbrel_diff(s, NULL));




Re: [PATCH v2 6/7] tcg/ppc: Disable USE_REG_TB for Power v3.1

2023-08-09 Thread Nicholas Piggin
On Tue Aug 8, 2023 at 1:02 PM AEST, Richard Henderson wrote:
> With Power v3.1, we have pc-relative addressing and so
> do not require a register holding the current TB.
>

Acked-by: Nicholas Piggin 

> Signed-off-by: Richard Henderson 
> ---
>  tcg/ppc/tcg-target.c.inc | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
> index 01ca5c9f39..63fe4ef995 100644
> --- a/tcg/ppc/tcg-target.c.inc
> +++ b/tcg/ppc/tcg-target.c.inc
> @@ -83,7 +83,7 @@
>  #define TCG_VEC_TMP2TCG_REG_V1
>  
>  #define TCG_REG_TB TCG_REG_R31
> -#define USE_REG_TB (TCG_TARGET_REG_BITS == 64)
> +#define USE_REG_TB (TCG_TARGET_REG_BITS == 64 && !have_isa_3_10)
>  
>  /* Shorthand for size of a pointer.  Avoid promotion to unsigned.  */
>  #define SZP  ((int)sizeof(void *))




Re: [PATCH v2 7/7] tcg/ppc: Use prefixed instructions for tcg_out_goto_tb

2023-08-09 Thread Nicholas Piggin
On Tue Aug 8, 2023 at 1:02 PM AEST, Richard Henderson wrote:
> When a direct branch is out of range, we can load the destination for
> the indirect branch using PLA (for 16GB worth of buffer) and PLD from
> the TranslationBlock for everything larger.
>
> This means the patch affects exactly one instruction: B (plus filler),
> PLA or PLD.  Which means we can update and execute the patch atomically.
>

Aside from changelog that Jordan pointed out,

Reviewed-by: Nicholas Piggin 

> Signed-off-by: Richard Henderson 
> ---
>  tcg/ppc/tcg-target.c.inc | 31 +++
>  1 file changed, 19 insertions(+), 12 deletions(-)
>
> diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
> index 63fe4ef995..b686a68247 100644
> --- a/tcg/ppc/tcg-target.c.inc
> +++ b/tcg/ppc/tcg-target.c.inc
> @@ -2646,31 +2646,38 @@ static void tcg_out_goto_tb(TCGContext *s, int which)
>  uintptr_t ptr = get_jmp_target_addr(s, which);
>  
>  if (USE_REG_TB) {
> +/*
> + * With REG_TB, we must always use indirect branching,
> + * so that the branch destination and TCG_REG_TB match.
> + */
>  ptrdiff_t offset = tcg_tbrel_diff(s, (void *)ptr);
>  tcg_out_mem_long(s, LD, LDX, TCG_REG_TB, TCG_REG_TB, offset);
> -
> -/* TODO: Use direct branches when possible. */
> -set_jmp_insn_offset(s, which);
>  tcg_out32(s, MTSPR | RS(TCG_REG_TB) | CTR);
> -
>  tcg_out32(s, BCCTR | BO_ALWAYS);
>  
>  /* For the unlinked case, need to reset TCG_REG_TB.  */
>  set_jmp_reset_offset(s, which);
>  tcg_out_mem_long(s, ADDI, ADD, TCG_REG_TB, TCG_REG_TB,
>   -tcg_current_code_size(s));
> -} else {
> -/* Direct branch will be patched by tb_target_set_jmp_target. */
> -set_jmp_insn_offset(s, which);
> -tcg_out32(s, NOP);
> +return;
> +}
>  
> -/* When branch is out of range, fall through to indirect. */
> +/* Direct branch will be patched by tb_target_set_jmp_target. */
> +set_jmp_insn_offset(s, which);
> +tcg_out32(s, NOP);
> +
> +/* When branch is out of range, fall through to indirect. */
> +if (have_isa_3_10) {
> +ptrdiff_t offset = tcg_pcrel_diff_for_prefix(s, (void *)ptr);
> +tcg_out_8ls_d(s, PLD, TCG_REG_TMP1, 0, offset, 1);
> +} else {
>  tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, ptr - (int16_t)ptr);
>  tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_REG_TMP1, 
> (int16_t)ptr);
> -tcg_out32(s, MTSPR | RS(TCG_REG_TMP1) | CTR);
> -tcg_out32(s, BCCTR | BO_ALWAYS);
> -set_jmp_reset_offset(s, which);
>  }
> +
> +tcg_out32(s, MTSPR | RS(TCG_REG_TMP1) | CTR);
> +tcg_out32(s, BCCTR | BO_ALWAYS);
> +set_jmp_reset_offset(s, which);
>  }
>  
>  void tb_target_set_jmp_target(const TranslationBlock *tb, int n,




Re: [PATCH] vfio/pci: hide ROM BAR on SFC9220 10/40G Ethernet Controller PF

2023-08-09 Thread Laszlo Ersek
On 8/8/23 17:40, Alex Williamson wrote:
> On Tue,  8 Aug 2023 16:59:16 +0200
> Laszlo Ersek  wrote:
> 
>> The Solarflare Communications SFC9220 NIC's physical function (PF) appears
>> to expose an expansion ROM with the following characteristics:
>>
>> (1) Single-image ROM, with only a legacy BIOS image (no UEFI driver).
>> Alex's rom-parser utility dumps it like this:
>>
>>> Valid ROM signature found @0h, PCIR offset 20h
>>> PCIR: type 0 (x86 PC-AT), vendor: 1924, device: 0a03, class: 02
>>> PCIR: revision 3, vendor revision: 1
>>> Last image  
>>
>> (2) The BIOS image crashes when booted on i440fx.
>>
>> (3) The BIOS image prints the following messages on q35:
>>
>>> Solarflare Boot Manager (v5.2.2.1006)
>>> Solarflare Communications 2008-2019
>>> gPXE (http://etherboot.org) - [...] PCI[...] PnP PMM[...]  
>>
>> So it appears like a modified derivative of old gPXE.
>>
>> Alex surmised in advance that the BIOS image could be accessing
>> host-physical addresses rather than guest-phys ones, leading to the crash
>> on i440fx.
> 
> ROMs sometimes take shortcuts around the standard interfaces to the
> device and can therefore hit gaps in the virtualization, which is why
> that's suspect to me.  However if it works on q35 but not 440fx it
> might be more that we're not matching a PCI topology expectation of the
> ROM.  Was it only tested on 440fx attached to the root bus or does it
> also fail if the PF is attached downstream of a PCI-to-PCI bridge?

Turns out the oprom wants the NIC to have PCI device number 0,
regardless of the bus number, and regardless of the bus's location in
the PCI topology.

Please drop this patch; I've documented the workaround in the BZ for now
(which I've also opened up to the public).

We should probably find a more visible place for the documentation, though.

Thanks for pointing me in the right direction!
Laszlo

> 
>> Don't expose the option ROM BAR to the VM by default. While this prevents
>> netbooting the VM off the PF on q35/SeaBIOS (a relatively rare scenario),
>> it does not make any difference for UEFI, and at least the VM doesn't
>> crash during boot on i440fx/SeaBIOS (a relatively frequent scenario).
>> Users can restore the original behavior via the QEMU cmdline and the
>> libvirt domain XML.
>>
>> (In two years, we've not seen any customer interest in this bug, hence
>> there's no incentive to investigate (2).)
>>
>> Cc: Alex Williamson  (supporter:VFIO)
>> Cc: "Cédric Le Goater"  (supporter:VFIO)
>> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1975776
>> Signed-off-by: Laszlo Ersek 
>> ---
>>  hw/vfio/pci-quirks.c | 4 
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
>> index f4ff83680572..270eb16b91fa 100644
>> --- a/hw/vfio/pci-quirks.c
>> +++ b/hw/vfio/pci-quirks.c
>> @@ -45,6 +45,10 @@ static const struct {
>>  uint32_t device;
>>  } rom_denylist[] = {
>>  { 0x14e4, 0x168e }, /* Broadcom BCM 57810 */
>> +{ 0x1924, 0x0a03 }, /* Solarflare Communications
>> + * SFC9220 10/40G Ethernet Controller
>> + * 
>> https://bugzilla.redhat.com/show_bug.cgi?id=1975776
> 
> Unfortunately this is not a public bz so there's not much point in
> referencing it in public code or commit log :-\  Thanks,
> 
> Alex
> 
>> + */
>>  };
>>  
>>  bool vfio_opt_rom_in_denylist(VFIOPCIDevice *vdev)
> 




Re: [RFC v1 0/3] Initial support for SPDM

2023-08-09 Thread Jonathan Cameron via
On Tue,  8 Aug 2023 11:51:21 -0400
Alistair Francis  wrote:

> The Security Protocol and Data Model (SPDM) Specification defines
> messages, data objects, and sequences for performing message exchanges
> over a variety of transport and physical media.
>  - 
> https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.3.0.pdf
> 
> This series is a very initial start on adding SPDM support to QEMU.
> 
> This series uses libspdm [1] which is a reference implementation of
> SPDM.
> 
> The series starts by adding support for building and linking with
> libspdm. It then progresses to handling SPDM requests in the NVMe device
> over the PCIe DOE protocol.
> 
> This is a very early attempt. The code quality is not super high, the C
> code hasn't been tested at all. This is really just an RFC to see if
> QEMU will accept linking with libspdm.
> 
> So, the main question is, how do people feel about linking with libspdm
> to support SPDM?
> 
> 1: https://github.com/DMTF/libspdm

Hi Alastair,

For reference / background we've had SPDM support for CXL emulated devices
in our staging tree for quite a while - it's not upstream because of
exactly this question (+ no one had upstreaming this as a high priority
as out of tree was fine for developing the kernel stack - it's well
isolated in the code so there was little cost in rebasing this feature)
- and because libspdm is packaged by almost no one. There were problems
building it with external crypto libraries etc.

Looks like you have had a lot more success than I ever did in getting that
to work. I tried a few times in the past and ended up sticking with
the Avery design folks approach of a socket connection to spdm-emu
Given you cc'd them I'm guessing you came across that work which is what
we used for testing the kernel code Lukas is working on currently.

https://lore.kernel.org/qemu-devel/20210629132520.0...@huawei.com/

https://gitlab.com/jic23/qemu/-/commit/9864fb29979e55c1e37c20edf00907d9524036e8

So I think we have 2 choices here.
1) Do what you have done and build the library as you are doing.
 - Can fix a version - so don't care if they change the ABI etc other
   than needing to move the version QEMU uses forwards when we need
   to for new features.
 - Cert management is going to add a lot of complexity into QEMU.
   I've not looked at how much infrastructure we can reuse from elsewhere.
   Maybe this is a solved problem.

2) Keep the SPDM emulation external.
 - I'm not sure the socket protocol used by spdm-emu is fixed in stone
   as people tend to change both ends.
 - Cert management and protocol options etc are already available.

Personally I prefer the control option 1 gives us, even if it's a lot more
code.  Option 2 also rather limits our ability to do anything with
the encrypted data as well. It's fine if the aim is just verification
of simple flows, but if we need to inject particular measurements etc
it doesn't really work.

Jonathan



> 
> Alistair Francis (3):
>   subprojects: libspdm: Initial support
>   hw: nvme: ctrl: Initial support for DOE
>   hw: nvme: ctrl: Process SPDM requests
> 
>  meson.build   | 78 +++
>  hw/nvme/nvme.h|  4 ++
>  include/hw/pci/pcie_doe.h |  1 +
>  hw/nvme/ctrl.c| 35 
>  .gitmodules   |  3 ++
>  meson_options.txt |  3 ++
>  scripts/meson-buildoptions.sh |  3 ++
>  subprojects/.gitignore|  1 +
>  subprojects/libspdm.wrap  |  5 +++
>  9 files changed, 133 insertions(+)
>  create mode 100644 subprojects/libspdm.wrap
> 




[PATCH v3 1/6] target/arm/ptw: Load stage-2 tables from realm physical space

2023-08-09 Thread Jean-Philippe Brucker
In realm state, stage-2 translation tables are fetched from the realm
physical address space (R_PGRQD).

Signed-off-by: Jean-Philippe Brucker 
Reviewed-by: Peter Maydell 
---
 target/arm/ptw.c | 26 ++
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index d1de934702..063adbd84a 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -157,22 +157,32 @@ static ARMMMUIdx ptw_idx_for_stage_2(CPUARMState *env, 
ARMMMUIdx stage2idx)
 
 /*
  * We're OK to check the current state of the CPU here because
- * (1) we always invalidate all TLBs when the SCR_EL3.NS bit changes
+ * (1) we always invalidate all TLBs when the SCR_EL3.NS or SCR_EL3.NSE bit
+ * changes.
  * (2) there's no way to do a lookup that cares about Stage 2 for a
  * different security state to the current one for AArch64, and AArch32
  * never has a secure EL2. (AArch32 ATS12NSO[UP][RW] allow EL3 to do
  * an NS stage 1+2 lookup while the NS bit is 0.)
  */
-if (!arm_is_secure_below_el3(env) || !arm_el_is_aa64(env, 3)) {
+if (!arm_el_is_aa64(env, 3)) {
 return ARMMMUIdx_Phys_NS;
 }
-if (stage2idx == ARMMMUIdx_Stage2_S) {
-s2walk_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
-} else {
-s2walk_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
-}
-return s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
 
+switch (arm_security_space_below_el3(env)) {
+case ARMSS_NonSecure:
+return ARMMMUIdx_Phys_NS;
+case ARMSS_Realm:
+return ARMMMUIdx_Phys_Realm;
+case ARMSS_Secure:
+if (stage2idx == ARMMMUIdx_Stage2_S) {
+s2walk_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
+} else {
+s2walk_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
+}
+return s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
+default:
+g_assert_not_reached();
+}
 }
 
 static bool regime_translation_big_endian(CPUARMState *env, ARMMMUIdx mmu_idx)
-- 
2.41.0




[PATCH v3 4/6] target/arm: Pass security space rather than flag for AT instructions

2023-08-09 Thread Jean-Philippe Brucker
At the moment we only handle Secure and Nonsecure security spaces for
the AT instructions. Add support for Realm and Root.

For AArch64, arm_security_space() gives the desired space. ARM DDI0487J
says (R_NYXTL):

  If EL3 is implemented, then when an address translation instruction
  that applies to an Exception level lower than EL3 is executed, the
  Effective value of SCR_EL3.{NSE, NS} determines the target Security
  state that the instruction applies to.

For AArch32, some instructions can access NonSecure space from Secure,
so we still need to pass the state explicitly to do_ats_write().

Signed-off-by: Jean-Philippe Brucker 
Reviewed-by: Peter Maydell 
---
 target/arm/internals.h | 18 +-
 target/arm/helper.c| 27 ---
 target/arm/ptw.c   | 12 ++--
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index fc90c364f7..cf13bb94f5 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1217,24 +1217,24 @@ bool get_phys_addr(CPUARMState *env, target_ulong 
address,
 __attribute__((nonnull));
 
 /**
- * get_phys_addr_with_secure_nogpc: get the physical address for a virtual
- *  address
+ * get_phys_addr_with_space_nogpc: get the physical address for a virtual
+ * address
  * @env: CPUARMState
  * @address: virtual address to get physical address for
  * @access_type: 0 for read, 1 for write, 2 for execute
  * @mmu_idx: MMU index indicating required translation regime
- * @is_secure: security state for the access
+ * @space: security space for the access
  * @result: set on translation success.
  * @fi: set to fault info if the translation fails
  *
- * Similar to get_phys_addr, but use the given security regime and don't 
perform
+ * Similar to get_phys_addr, but use the given security space and don't perform
  * a Granule Protection Check on the resulting address.
  */
-bool get_phys_addr_with_secure_nogpc(CPUARMState *env, target_ulong address,
- MMUAccessType access_type,
- ARMMMUIdx mmu_idx, bool is_secure,
- GetPhysAddrResult *result,
- ARMMMUFaultInfo *fi)
+bool get_phys_addr_with_space_nogpc(CPUARMState *env, target_ulong address,
+MMUAccessType access_type,
+ARMMMUIdx mmu_idx, ARMSecuritySpace space,
+GetPhysAddrResult *result,
+ARMMMUFaultInfo *fi)
 __attribute__((nonnull));
 
 bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 427de6bd2a..fbb03c364b 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3357,7 +3357,7 @@ static int par_el1_shareability(GetPhysAddrResult *res)
 
 static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
  MMUAccessType access_type, ARMMMUIdx mmu_idx,
- bool is_secure)
+ ARMSecuritySpace ss)
 {
 bool ret;
 uint64_t par64;
@@ -3369,8 +3369,8 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t 
value,
  * I_MXTJT: Granule protection checks are not performed on the final 
address
  * of a successful translation.
  */
-ret = get_phys_addr_with_secure_nogpc(env, value, access_type, mmu_idx,
-  is_secure, &res, &fi);
+ret = get_phys_addr_with_space_nogpc(env, value, access_type, mmu_idx, ss,
+ &res, &fi);
 
 /*
  * ATS operations only do S1 or S1+S2 translations, so we never
@@ -3535,7 +3535,7 @@ static void ats_write(CPUARMState *env, const 
ARMCPRegInfo *ri, uint64_t value)
 uint64_t par64;
 ARMMMUIdx mmu_idx;
 int el = arm_current_el(env);
-bool secure = arm_is_secure_below_el3(env);
+ARMSecuritySpace ss = arm_security_space(env);
 
 switch (ri->opc2 & 6) {
 case 0:
@@ -3543,10 +3543,9 @@ static void ats_write(CPUARMState *env, const 
ARMCPRegInfo *ri, uint64_t value)
 switch (el) {
 case 3:
 mmu_idx = ARMMMUIdx_E3;
-secure = true;
 break;
 case 2:
-g_assert(!secure);  /* ARMv8.4-SecEL2 is 64-bit only */
+g_assert(ss != ARMSS_Secure);  /* ARMv8.4-SecEL2 is 64-bit only */
 /* fall through */
 case 1:
 if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
@@ -3564,10 +3563,9 @@ static void ats_write(CPUARMState *env, const 
ARMCPRegInfo *ri, uint64_t value)
 switch (el) {
 case 3:
 mmu_idx = ARMMMUIdx_E10_0;
-secure = true;
 break;
 case 2:
-g_assert(!secure);  /* ARMv8.4-SecEL2 is 64-bit only

[PATCH v3 3/6] target/arm: Skip granule protection checks for AT instructions

2023-08-09 Thread Jean-Philippe Brucker
GPC checks are not performed on the output address for AT instructions,
as stated by ARM DDI 0487J in D8.12.2:

  When populating PAR_EL1 with the result of an address translation
  instruction, granule protection checks are not performed on the final
  output address of a successful translation.

Rename get_phys_addr_with_secure(), since it's only used to handle AT
instructions.

Signed-off-by: Jean-Philippe Brucker 
Reviewed-by: Peter Maydell 
---
 target/arm/internals.h | 25 ++---
 target/arm/helper.c|  8 ++--
 target/arm/ptw.c   | 11 ++-
 3 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 0f01bc32a8..fc90c364f7 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1190,12 +1190,11 @@ typedef struct GetPhysAddrResult {
 } GetPhysAddrResult;
 
 /**
- * get_phys_addr_with_secure: get the physical address for a virtual address
+ * get_phys_addr: get the physical address for a virtual address
  * @env: CPUARMState
  * @address: virtual address to get physical address for
  * @access_type: 0 for read, 1 for write, 2 for execute
  * @mmu_idx: MMU index indicating required translation regime
- * @is_secure: security state for the access
  * @result: set on translation success.
  * @fi: set to fault info if the translation fails
  *
@@ -1212,26 +1211,30 @@ typedef struct GetPhysAddrResult {
  *  * for PSMAv5 based systems we don't bother to return a full FSR format
  *value.
  */
-bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
-   MMUAccessType access_type,
-   ARMMMUIdx mmu_idx, bool is_secure,
-   GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
+bool get_phys_addr(CPUARMState *env, target_ulong address,
+   MMUAccessType access_type, ARMMMUIdx mmu_idx,
+   GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
 __attribute__((nonnull));
 
 /**
- * get_phys_addr: get the physical address for a virtual address
+ * get_phys_addr_with_secure_nogpc: get the physical address for a virtual
+ *  address
  * @env: CPUARMState
  * @address: virtual address to get physical address for
  * @access_type: 0 for read, 1 for write, 2 for execute
  * @mmu_idx: MMU index indicating required translation regime
+ * @is_secure: security state for the access
  * @result: set on translation success.
  * @fi: set to fault info if the translation fails
  *
- * Similarly, but use the security regime of @mmu_idx.
+ * Similar to get_phys_addr, but use the given security regime and don't 
perform
+ * a Granule Protection Check on the resulting address.
  */
-bool get_phys_addr(CPUARMState *env, target_ulong address,
-   MMUAccessType access_type, ARMMMUIdx mmu_idx,
-   GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
+bool get_phys_addr_with_secure_nogpc(CPUARMState *env, target_ulong address,
+ MMUAccessType access_type,
+ ARMMMUIdx mmu_idx, bool is_secure,
+ GetPhysAddrResult *result,
+ ARMMMUFaultInfo *fi)
 __attribute__((nonnull));
 
 bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
diff --git a/target/arm/helper.c b/target/arm/helper.c
index a4c2c1bde5..427de6bd2a 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3365,8 +3365,12 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t 
value,
 ARMMMUFaultInfo fi = {};
 GetPhysAddrResult res = {};
 
-ret = get_phys_addr_with_secure(env, value, access_type, mmu_idx,
-is_secure, &res, &fi);
+/*
+ * I_MXTJT: Granule protection checks are not performed on the final 
address
+ * of a successful translation.
+ */
+ret = get_phys_addr_with_secure_nogpc(env, value, access_type, mmu_idx,
+  is_secure, &res, &fi);
 
 /*
  * ATS operations only do S1 or S1+S2 translations, so we never
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 063adbd84a..33179f3471 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -3418,16 +3418,17 @@ static bool get_phys_addr_gpc(CPUARMState *env, 
S1Translate *ptw,
 return false;
 }
 
-bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
-   MMUAccessType access_type, ARMMMUIdx mmu_idx,
-   bool is_secure, GetPhysAddrResult *result,
-   ARMMMUFaultInfo *fi)
+bool get_phys_addr_with_secure_nogpc(CPUARMState *env, target_ulong address,
+ MMUAccessType access_type,
+ ARMMMUIdx mmu_idx, bool is_secure,
+ GetPhysAddrResult *result,
+   

[PATCH v3 6/6] target/arm/helper: Implement CNTHCTL_EL2.CNT[VP]MASK

2023-08-09 Thread Jean-Philippe Brucker
When FEAT_RME is implemented, these bits override the value of
CNT[VP]_CTL_EL0.IMASK in Realm and Root state. Move the IRQ state update
into a new gt_update_irq() function and test those bits every time we
recompute the IRQ state.

Since we're removing the IRQ state from some trace events, add a new
trace event for gt_update_irq().

Signed-off-by: Jean-Philippe Brucker 
---
 target/arm/cpu.h|  4 +++
 target/arm/cpu.c|  4 +++
 target/arm/helper.c | 65 ++---
 target/arm/trace-events |  7 +++--
 4 files changed, 66 insertions(+), 14 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index bcd65a63ca..855a76ae81 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1115,6 +1115,7 @@ struct ArchCPU {
 };
 
 unsigned int gt_cntfrq_period_ns(ARMCPU *cpu);
+void gt_rme_post_el_change(ARMCPU *cpu, void *opaque);
 
 void arm_cpu_post_init(Object *obj);
 
@@ -1743,6 +1744,9 @@ static inline void xpsr_write(CPUARMState *env, uint32_t 
val, uint32_t mask)
 #define HSTR_TTEE (1 << 16)
 #define HSTR_TJDBX (1 << 17)
 
+#define CNTHCTL_CNTVMASK  (1 << 18)
+#define CNTHCTL_CNTPMASK  (1 << 19)
+
 /* Return the current FPSCR value.  */
 uint32_t vfp_get_fpscr(CPUARMState *env);
 void vfp_set_fpscr(CPUARMState *env, uint32_t val);
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 93c28d50e5..7df1f7600b 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2169,6 +2169,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
 set_feature(env, ARM_FEATURE_VBAR);
 }
 
+if (cpu_isar_feature(aa64_rme, cpu)) {
+arm_register_el_change_hook(cpu, >_rme_post_el_change, 0);
+}
+
 register_cp_regs_for_features(cpu);
 arm_cpu_register_gdb_regs_for_features(cpu);
 
diff --git a/target/arm/helper.c b/target/arm/helper.c
index dbfe9f2f5e..86ce6a52bb 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -2608,6 +2608,39 @@ static uint64_t gt_get_countervalue(CPUARMState *env)
 return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / gt_cntfrq_period_ns(cpu);
 }
 
+static void gt_update_irq(ARMCPU *cpu, int timeridx)
+{
+CPUARMState *env = &cpu->env;
+uint64_t cnthctl = env->cp15.cnthctl_el2;
+ARMSecuritySpace ss = arm_security_space(env);
+/* ISTATUS && !IMASK */
+int irqstate = (env->cp15.c14_timer[timeridx].ctl & 6) == 4;
+
+/*
+ * If bit CNTHCTL_EL2.CNT[VP]MASK is set, it overrides IMASK.
+ * It is RES0 in Secure and NonSecure state.
+ */
+if ((ss == ARMSS_Root || ss == ARMSS_Realm) &&
+((timeridx == GTIMER_VIRT && (cnthctl & CNTHCTL_CNTVMASK)) ||
+ (timeridx == GTIMER_PHYS && (cnthctl & CNTHCTL_CNTPMASK {
+irqstate = 0;
+}
+
+qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
+trace_arm_gt_update_irq(timeridx, irqstate);
+}
+
+void gt_rme_post_el_change(ARMCPU *cpu, void *ignored)
+{
+/*
+ * Changing security state between Root and Secure/NonSecure, which may
+ * happen when switching EL, can change the effective value of CNTHCTL_EL2
+ * mask bits. Update the IRQ state accordingly.
+ */
+gt_update_irq(cpu, GTIMER_VIRT);
+gt_update_irq(cpu, GTIMER_PHYS);
+}
+
 static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
 {
 ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
@@ -2623,13 +2656,9 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
 /* Note that this must be unsigned 64 bit arithmetic: */
 int istatus = count - offset >= gt->cval;
 uint64_t nexttick;
-int irqstate;
 
 gt->ctl = deposit32(gt->ctl, 2, 1, istatus);
 
-irqstate = (istatus && !(gt->ctl & 2));
-qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
-
 if (istatus) {
 /* Next transition is when count rolls back over to zero */
 nexttick = UINT64_MAX;
@@ -2648,14 +2677,14 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
 } else {
 timer_mod(cpu->gt_timer[timeridx], nexttick);
 }
-trace_arm_gt_recalc(timeridx, irqstate, nexttick);
+trace_arm_gt_recalc(timeridx, nexttick);
 } else {
 /* Timer disabled: ISTATUS and timer output always clear */
 gt->ctl &= ~4;
-qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0);
 timer_del(cpu->gt_timer[timeridx]);
 trace_arm_gt_recalc_disabled(timeridx);
 }
+gt_update_irq(cpu, timeridx);
 }
 
 static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -2759,10 +2788,8 @@ static void gt_ctl_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
  * IMASK toggled: don't need to recalculate,
  * just set the interrupt line based on ISTATUS
  */
-int irqstate = (oldval & 4) && !(value & 2);
-
-trace_arm_gt_imask_toggle(timeridx, irqstate);
-qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
+trace_arm_gt_imask_toggle(timeridx);

[PATCH v3 0/6] target/arm: Fixes for RME

2023-08-09 Thread Jean-Philippe Brucker
A few patches to fix RME support and allow booting a realm guest, based
on "[PATCH v2 00/15] target/arm/ptw: Cleanups and a few bugfixes"
https://lore.kernel.org/all/20230807141514.19075-1-peter.mayd...@linaro.org/

Since v2:

* Updated the comment in patch 5. I also removed the check for FEAT_RME,
  because as pointed out in "target/arm: Catch illegal-exception-return
  from EL3 with bad NSE/NS", the SCR_NSE bit can only be set with
  FEAT_RME enabled. Because of this additional change, I didn't add the
  Reviewed-by.

* Added an EL-change hook to patch 6, to update the timer IRQ
  when changing the security state. I was wondering whether the
  el_change function should filter security state changes, since we only
  need to update IRQ state when switching between Root and
  Secure/NonSecure. But with a small syscall benchmark exercising
  EL0-EL1 switch with FEAT_RME enabled, I couldn't see any difference
  with and without the el_change hook, so I kept it simple.

* Also added the .raw_write callback for CNTHCTL_EL2.

v2: 
https://lore.kernel.org/all/20230802170157.401491-1-jean-phili...@linaro.org/

Jean-Philippe Brucker (6):
  target/arm/ptw: Load stage-2 tables from realm physical space
  target/arm/helper: Fix tlbmask and tlbbits for TLBI VAE2*
  target/arm: Skip granule protection checks for AT instructions
  target/arm: Pass security space rather than flag for AT instructions
  target/arm/helper: Check SCR_EL3.{NSE,NS} encoding for AT instructions
  target/arm/helper: Implement CNTHCTL_EL2.CNT[VP]MASK

 target/arm/cpu.h|   4 +
 target/arm/internals.h  |  25 +++---
 target/arm/cpu.c|   4 +
 target/arm/helper.c | 184 ++--
 target/arm/ptw.c|  39 ++---
 target/arm/trace-events |   7 +-
 6 files changed, 188 insertions(+), 75 deletions(-)

-- 
2.41.0




[PATCH v3 2/6] target/arm/helper: Fix tlbmask and tlbbits for TLBI VAE2*

2023-08-09 Thread Jean-Philippe Brucker
When HCR_EL2.E2H is enabled, TLB entries are formed using the EL2&0
translation regime, instead of the EL2 translation regime. The TLB VAE2*
instructions invalidate the regime that corresponds to the current value
of HCR_EL2.E2H.

At the moment we only invalidate the EL2 translation regime. This causes
problems with RMM, which issues TLBI VAE2IS instructions with
HCR_EL2.E2H enabled. Update vae2_tlbmask() to take HCR_EL2.E2H into
account.

Add vae2_tlbbits() as well, since the top-byte-ignore configuration is
different between the EL2&0 and EL2 regime.

Signed-off-by: Jean-Philippe Brucker 
Reviewed-by: Peter Maydell 
---
 target/arm/helper.c | 50 -
 1 file changed, 40 insertions(+), 10 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2959d27543..a4c2c1bde5 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4663,6 +4663,21 @@ static int vae1_tlbmask(CPUARMState *env)
 return mask;
 }
 
+static int vae2_tlbmask(CPUARMState *env)
+{
+uint64_t hcr = arm_hcr_el2_eff(env);
+uint16_t mask;
+
+if (hcr & HCR_E2H) {
+mask = ARMMMUIdxBit_E20_2 |
+   ARMMMUIdxBit_E20_2_PAN |
+   ARMMMUIdxBit_E20_0;
+} else {
+mask = ARMMMUIdxBit_E2;
+}
+return mask;
+}
+
 /* Return 56 if TBI is enabled, 64 otherwise. */
 static int tlbbits_for_regime(CPUARMState *env, ARMMMUIdx mmu_idx,
   uint64_t addr)
@@ -4689,6 +4704,25 @@ static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
 return tlbbits_for_regime(env, mmu_idx, addr);
 }
 
+static int vae2_tlbbits(CPUARMState *env, uint64_t addr)
+{
+uint64_t hcr = arm_hcr_el2_eff(env);
+ARMMMUIdx mmu_idx;
+
+/*
+ * Only the regime of the mmu_idx below is significant.
+ * Regime EL2&0 has two ranges with separate TBI configuration, while EL2
+ * only has one.
+ */
+if (hcr & HCR_E2H) {
+mmu_idx = ARMMMUIdx_E20_2;
+} else {
+mmu_idx = ARMMMUIdx_E2;
+}
+
+return tlbbits_for_regime(env, mmu_idx, addr);
+}
+
 static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
   uint64_t value)
 {
@@ -4781,10 +4815,11 @@ static void tlbi_aa64_vae2_write(CPUARMState *env, 
const ARMCPRegInfo *ri,
  * flush-last-level-only.
  */
 CPUState *cs = env_cpu(env);
-int mask = e2_tlbmask(env);
+int mask = vae2_tlbmask(env);
 uint64_t pageaddr = sextract64(value << 12, 0, 56);
+int bits = vae2_tlbbits(env, pageaddr);
 
-tlb_flush_page_by_mmuidx(cs, pageaddr, mask);
+tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits);
 }
 
 static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -4838,11 +4873,11 @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, 
const ARMCPRegInfo *ri,
uint64_t value)
 {
 CPUState *cs = env_cpu(env);
+int mask = vae2_tlbmask(env);
 uint64_t pageaddr = sextract64(value << 12, 0, 56);
-int bits = tlbbits_for_regime(env, ARMMMUIdx_E2, pageaddr);
+int bits = vae2_tlbbits(env, pageaddr);
 
-tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
-  ARMMMUIdxBit_E2, bits);
+tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
 }
 
 static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -5014,11 +5049,6 @@ static void tlbi_aa64_rvae1is_write(CPUARMState *env,
 do_rvae_write(env, value, vae1_tlbmask(env), true);
 }
 
-static int vae2_tlbmask(CPUARMState *env)
-{
-return ARMMMUIdxBit_E2;
-}
-
 static void tlbi_aa64_rvae2_write(CPUARMState *env,
   const ARMCPRegInfo *ri,
   uint64_t value)
-- 
2.41.0




[PATCH v3 5/6] target/arm/helper: Check SCR_EL3.{NSE, NS} encoding for AT instructions

2023-08-09 Thread Jean-Philippe Brucker
The AT instruction is UNDEFINED if the {NSE,NS} configuration is
invalid. Add a function to check this on all AT instructions that apply
to an EL lower than 3.

Suggested-by: Peter Maydell 
Signed-off-by: Jean-Philippe Brucker 
---
 target/arm/helper.c | 38 +++---
 1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index fbb03c364b..dbfe9f2f5e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3616,6 +3616,22 @@ static void ats1h_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 #endif /* CONFIG_TCG */
 }
 
+static CPAccessResult at_e012_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+/*
+ * R_NYXTL: instruction is UNDEFINED if it applies to an Exception level
+ * lower than EL3 and the combination SCR_EL3.{NSE,NS} is reserved. This 
can
+ * only happen when executing at EL3 because that combination also causes 
an
+ * illegal exception return. We don't need to check FEAT_RME either, 
because
+ * scr_write() ensures that the NSE bit is not set otherwise.
+ */
+if ((env->cp15.scr_el3 & (SCR_NSE | SCR_NS)) == SCR_NSE) {
+return CP_ACCESS_TRAP;
+}
+return CP_ACCESS_OK;
+}
+
 static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
  bool isread)
 {
@@ -3623,7 +3639,7 @@ static CPAccessResult at_s1e2_access(CPUARMState *env, 
const ARMCPRegInfo *ri,
 !(env->cp15.scr_el3 & (SCR_NS | SCR_EEL2))) {
 return CP_ACCESS_TRAP;
 }
-return CP_ACCESS_OK;
+return at_e012_access(env, ri, isread);
 }
 
 static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -5505,38 +5521,38 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
   .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0,
   .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
   .fgt = FGT_ATS1E1R,
-  .writefn = ats_write64 },
+  .accessfn = at_e012_access, .writefn = ats_write64 },
 { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
   .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1,
   .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
   .fgt = FGT_ATS1E1W,
-  .writefn = ats_write64 },
+  .accessfn = at_e012_access, .writefn = ats_write64 },
 { .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64,
   .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2,
   .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
   .fgt = FGT_ATS1E0R,
-  .writefn = ats_write64 },
+  .accessfn = at_e012_access, .writefn = ats_write64 },
 { .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64,
   .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3,
   .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
   .fgt = FGT_ATS1E0W,
-  .writefn = ats_write64 },
+  .accessfn = at_e012_access, .writefn = ats_write64 },
 { .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64,
   .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4,
   .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
-  .writefn = ats_write64 },
+  .accessfn = at_e012_access, .writefn = ats_write64 },
 { .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64,
   .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5,
   .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
-  .writefn = ats_write64 },
+  .accessfn = at_e012_access, .writefn = ats_write64 },
 { .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64,
   .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6,
   .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
-  .writefn = ats_write64 },
+  .accessfn = at_e012_access, .writefn = ats_write64 },
 { .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64,
   .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7,
   .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
-  .writefn = ats_write64 },
+  .accessfn = at_e012_access, .writefn = ats_write64 },
 /* AT S1E2* are elsewhere as they UNDEF from EL3 if EL2 is not present */
 { .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64,
   .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0,
@@ -8078,12 +8094,12 @@ static const ARMCPRegInfo ats1e1_reginfo[] = {
   .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
   .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
   .fgt = FGT_ATS1E1RP,
-  .writefn = ats_write64 },
+  .accessfn = at_e012_access, .writefn = ats_write64 },
 { .name = "AT_S1E1WP", .state = ARM_CP_STATE_AA64,
   .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
   .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
   .fgt = FGT_ATS1E1WP,
-  .writefn = ats_write64 },
+  .accessfn = at_e012_access, .writefn = ats_write64 },
 };
 
 static const ARMCPRegInfo ats1cp_reginfo[] = {
-- 
2.41.0




Re: [RFC v4 01/11] build: Implement logic for sharing cross-building config files

2023-08-09 Thread Manos Pitsidianakis
This patch needs a detailed commit message, since it's not obvious why 
these changes are made at all. It'd also be helpful for reviewing.


General style comment for shell scripts: Always put curly braces around 
variables even if they are unnecessary. a $source_path could become 
$source_pathPREFIX in the future and instead of ${source_path} it would 
expand to ${source_pathPREFIX}.


On Tue, 08 Aug 2023 16:17, Yeqi Fu  wrote:

+tcg_tests_targets=
+for target in $target_list; do
+  case $target in
+*-softmmu)
+  test -f "$source_path/tests/tcg/$arch/Makefile.softmmu-target" || 
continue
+  ;;
+  esac

+  if test -f cross-build/$target/config-target.mak; then


targets will never have spaces but I'd still double quote ${target} for 
consistency and style




+  mkdir -p "tests/tcg/$target"
+  ln -srf cross-build/$target/config-target.mak 
tests/tcg/$target/config-target.mak
+  ln -sf $source_path/tests/tcg/Makefile.target tests/tcg/$target/Makefile


This ln definitely needs double quoting.


  echo "run-tcg-tests-$target: $qemu\$(EXESUF)" >> Makefile.prereqs
  tcg_tests_targets="$tcg_tests_targets $target"
  fi
--
2.34.1






Re: [RFC v4 11/11] docs/user: Add doc for native library calls

2023-08-09 Thread Manos Pitsidianakis

On Tue, 08 Aug 2023 16:17, Yeqi Fu  wrote:

+arm and aarch64
+---
+HLT is an invalid instruction for userspace and usefully has 16
+bits of spare immeadiate data which we can stuff data in.


s/immeadiate/immediate

With that fix, you can add

Reviewed-by: Emmanouil Pitsidianakis 



Re: [PATCH v2 10/19] target/ppc: Migrate DECR SPR

2023-08-09 Thread Cédric Le Goater

Hello Nick,

On 8/8/23 06:19, Nicholas Piggin wrote:

TCG does not maintain the DEC reigster in the SPR array, so it does get
migrated. TCG also needs to re-start the decrementer timer on the
destination machine.

Load and store the decrementer into the SPR when migrating. This works
for the level-triggered (book3s) decrementer, and should be compatible
with existing KVM machines that do keep the DEC value there.

This fixes lost decrementer interrupt on migration that can cause
hangs, as well as other problems including record-replay bugs.

Signed-off-by: Nicholas Piggin 
---
  target/ppc/machine.c | 14 ++
  1 file changed, 14 insertions(+)

diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index 8234e35d69..8a190c4853 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -209,6 +209,14 @@ static int cpu_pre_save(void *opaque)
  /* Used to retain migration compatibility for pre 6.0 for 601 machines. */
  env->hflags_compat_nmsr = 0;
  
+if (tcg_enabled()) {

+/*
+ * TCG does not maintain the DECR spr (unlike KVM) so have to save
+ * it here.
+ */
+env->spr[SPR_DECR] = cpu_ppc_load_decr(env);
+}
+
  return 0;
  }
  
@@ -319,6 +327,12 @@ static int cpu_post_load(void *opaque, int version_id)

  ppc_update_ciabr(env);
  ppc_update_daw0(env);
  #endif
+/*
+ * TCG needs to re-start the decrementer timer and/or raise the
+ * interrupt. This works for level-triggered decrementer. Edge
+ * triggered types (including HDEC) would need to carry more state.
+ */
+cpu_ppc_store_decr(env, env->spr[SPR_DECR]);
  pmu_mmcr01_updated(env);
  }



This doesn't apply. I am missing some patch ?

Thanks,

C.




RE: [PATCH] Fix SEGFAULT on getting physical address of MMIO region.

2023-08-09 Thread Mikhail Tyutin
> On 8/2/23 06:08, Mikhail Tyutin wrote:
> > The fix is to clear TLB_INVALID_MASK bit in tlb_addr, as it happens in 
> > other places e.g.
> > load_helper().
> >
> > Signed-off-by: Dmitriy Solovev 
> > Signed-off-by: Mikhail Tyutin 
> > ---
> >   accel/tcg/cputlb.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> The other places in load_helper happen only directly after tlb_fill has 
> succeeded.  Here
> you have no such guarantee.
> 
> I think perhaps the save_iotlb_data() call should be applied to loads as 
> well, and then
> tlb_plugin_lookup simplified.
> 

Hello Richard,

We performed testing on more scenarios and noticed that patch when 
save_iotlb_data() call is added to io_readx
(https://patchew.org/QEMU/20230804110903.19968-1-m.tyu...@yadro.com/). It 
doesn't work for addresses
in OCRAM region. Those accessed bypass io_writex/io_readx function and 
therefore don’t invoke save_iotlb_data().
So we observe the wrong value of cpu->saved_iotlb for it.

Would not be better to get back to initial v1 approach when we clean 
TLB_INVALID_MASK flag in
tlb_plugin_lookup()? It works well for those regions.
(https://patchew.org/QEMU/bf8ae2fd-158a-57b6-6270-2e56b6506...@yadro.com)


Re: [PATCH v2] target/i386: Avoid cpu number overflow in legacy topology

2023-08-09 Thread Wen, Qian
On 8/9/2023 7:14 PM, Igor Mammedov wrote:
> On Wed,  9 Aug 2023 18:27:32 +0800
> Qian Wen  wrote:
>
>> The legacy topology enumerated by CPUID.1.EBX[23:16] is defined in SDM
>> Vol2:
>>
>> Bits 23-16: Maximum number of addressable IDs for logical processors in
>> this physical package.
>>
>> When launching the VM with -smp 256, the value written to EBX[23:16] is
>> 0 because of data overflow. If the guest only supports legacy topology,
>> without V2 Extended Topology enumerated by CPUID.0x1f or Extended
>> Topology enumerated by CPUID.0x0b to support over 255 CPUs, the return
>> of the kernel invoking cpu_smt_allowed() is false and AP's bring-up will
>> fail. Then only CPU 0 is online, and others are offline.
>>
>> To avoid this issue caused by overflow, limit the max value written to
>> EBX[23:16] to 255.
> what happens on real hw or in lack of thereof what SDM says about this
> value when there is more than 255 threads?.
>

Current SDM doesn't specify what the value should be when APIC IDs per package 
exceeds 255. So we asked the internal HW architect, the response is that 
EBX[23:16] will report 255 instead of being truncated to a smaller value.

Thanks,
Qian

>> Signed-off-by: Qian Wen 
>> ---
>> Changes v1 -> v2:
>>  - Revise the commit message and comment to more clearer.
>>  - Rebased to v8.1.0-rc2.
>> ---
>>  target/i386/cpu.c | 16 ++--
>>  1 file changed, 14 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
>> index 97ad229d8b..6e1d88fbd7 100644
>> --- a/target/i386/cpu.c
>> +++ b/target/i386/cpu.c
>> @@ -6008,6 +6008,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
>> uint32_t count,
>>  uint32_t die_offset;
>>  uint32_t limit;
>>  uint32_t signature[3];
>> +uint32_t threads_per_socket;
>>  X86CPUTopoInfo topo_info;
>>  
>>  topo_info.dies_per_pkg = env->nr_dies;
>> @@ -6049,8 +6050,19 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
>> uint32_t count,
>>  *ecx |= CPUID_EXT_OSXSAVE;
>>  }
>>  *edx = env->features[FEAT_1_EDX];
>> -if (cs->nr_cores * cs->nr_threads > 1) {
>> -*ebx |= (cs->nr_cores * cs->nr_threads) << 16;
>> +/*
>> + * Only bits [23:16] represent the maximum number of addressable
>> + * IDs for logical processors in this physical package.
>> + * When thread_per_socket > 255, it will 1) overwrite bits[31:24]
>> + * which is apic_id, 2) bits [23:16] get truncated.
>> + */
>> +threads_per_socket = cs->nr_cores * cs->nr_threads;
>> +if (threads_per_socket > 255) {
>> +threads_per_socket = 255;
>> +}
>> +
>> +if (threads_per_socket > 1) {
>> +*ebx |= threads_per_socket << 16;
>>  *edx |= CPUID_HT;
>>  }
>>  if (!cpu->enable_pmu) {

[PULL 0/2] hw/nvme: more fixes

2023-08-09 Thread Klaus Jensen
From: Klaus Jensen 

Hi,

The following changes since commit a8fc5165aab02f328ccd148aafec1e59fd1426eb:

  Merge tag 'nvme-next-pull-request' of https://gitlab.com/birkelund/qemu into 
staging (2023-08-08 16:39:20 -0700)

are available in the Git repository at:

  https://gitlab.com/birkelund/qemu.git tags/nvme-fixes-pull-request

for you to fetch changes up to 3439ba9c5da943d96f7a3c86e0a7eb2ff48de41c:

  hw/nvme: fix null pointer access in ruh update (2023-08-09 15:32:32 +0200)


hw/nvme: fixes
-BEGIN PGP SIGNATURE-

iQEzBAABCgAdFiEEUigzqnXi3OaiR2bATeGvMW1PDekFAmTTlmcACgkQTeGvMW1P
DemjjggAnhEvaJ4fgS9rsvtxCwtzLNc405xMpNxh6rPaxa+sL3RXPIrW6vWG13+W
VcHw8DI8EV4DzAFP919ZmTUq9/boRbgxx84bStlILUPHWol8+eGYVVfT75wFKszx
d4Vi3nyPSGlrxieSrosARqimcUDtFtDGGAxjvEcKgzhkcU3a8DVYAOmx/hdlWJJQ
KSk4h/E1pKItFbvv+w9yszsbToeZN65oIy7kQtFgx0JOULyWvEYSVygotw/AruF3
FPQ0nrJuZ115w3cJWDszznVJ6+3EcWbD3luQc3zE1FOPp76EkAOkcnPh1XbBJrE2
2BsCX/XnXcZT7BWSJbEzGXLsHjqsPg==
=Zy0+
-END PGP SIGNATURE-



Klaus Jensen (2):
  hw/nvme: fix null pointer access in directive receive
  hw/nvme: fix null pointer access in ruh update

 hw/nvme/ctrl.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

-- 
2.41.0




Re: [PATCH v2 2/3] hw/smbios: Fix thread count in type4

2023-08-09 Thread Igor Mammedov
On Mon, 7 Aug 2023 22:31:35 +0800
Zhao Liu  wrote:

> Hi Igor,
> 
> On Mon, Aug 07, 2023 at 12:11:29PM +0200, Igor Mammedov wrote:
> > Date: Mon, 7 Aug 2023 12:11:29 +0200
> > From: Igor Mammedov 
> > Subject: Re: [PATCH v2 2/3] hw/smbios: Fix thread count in type4
> > X-Mailer: Claws Mail 4.1.1 (GTK 3.24.38; x86_64-redhat-linux-gnu)
> > 
> > On Mon, 7 Aug 2023 13:06:47 +0300
> > Michael Tokarev  wrote:
> >   
> > > 07.08.2023 12:56, Igor Mammedov wrote:  
> > > > On Sat, 5 Aug 2023 09:00:41 +0300
> > > > Michael Tokarev  wrote:  
> > [...]  
> > > The whole thing - provided the preparational patch a1d027be95
> > > "machine: Add helpers to get cores/threads per socket" is also
> > > picked up - applies cleanly and in a stright-forward way to 8.0
> > > and even to 7.2, and passes the usual qemu testsuite. Sure thing
> > > since the issues weren't noticed before, the testsuite does not
> > > cover this area.  It'd be nice to have some verifier to check if
> > > the whole thing actually works after applying the patchset.  
> > 
> > Zhao Liu,
> > can you help us out with adding test cases to cover the code
> > you are touching?  
> 
> Yes, sure.
> 
> Just double check, I should add these 2 test cases:
> 1. in "bios-tables-test.c" to test smbios type4 topology related things, and
> 2. also in "test-smp-parse.c" to test our new topology helpers.
> 
> Do I understand correctly?

yep, I'd do both.
Also looking at test cases I don't see any test cases that
check topo end-to-end path (at least for x86). I mean
checking related CPUID values.
One possible place to it without writing testcase from scratch
could be test-x86-cpuid-compat.c.
Where I'd add test cases for some CPUID leaves at certain topo
configurations (values to check could be hardcoded magic numbers
as long as they are properly documented/reference specs) .

> 
> -Zhao
> 
> > 
> > [...]
> >   
> 




[PULL 2/2] hw/nvme: fix null pointer access in ruh update

2023-08-09 Thread Klaus Jensen
From: Klaus Jensen 

The Reclaim Unit Update operation in I/O Management Receive does not
verify the presence of a configured endurance group prior to accessing
it.

Fix this.

Cc: qemu-sta...@nongnu.org
Fixes: 73064edfb864 ("hw/nvme: flexible data placement emulation")
Reviewed-by: Jesper Wendel Devantier 
Signed-off-by: Klaus Jensen 
---
 hw/nvme/ctrl.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index e5b5c7034d2b..539d27355313 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -4361,7 +4361,13 @@ static uint16_t nvme_io_mgmt_send_ruh_update(NvmeCtrl 
*n, NvmeRequest *req)
 uint32_t npid = (cdw10 >> 1) + 1;
 unsigned int i = 0;
 g_autofree uint16_t *pids = NULL;
-uint32_t maxnpid = n->subsys->endgrp.fdp.nrg * n->subsys->endgrp.fdp.nruh;
+uint32_t maxnpid;
+
+if (!ns->endgrp || !ns->endgrp->fdp.enabled) {
+return NVME_FDP_DISABLED | NVME_DNR;
+}
+
+maxnpid = n->subsys->endgrp.fdp.nrg * n->subsys->endgrp.fdp.nruh;
 
 if (unlikely(npid >= MIN(NVME_FDP_MAXPIDS, maxnpid))) {
 return NVME_INVALID_FIELD | NVME_DNR;
-- 
2.41.0




[PULL 1/2] hw/nvme: fix null pointer access in directive receive

2023-08-09 Thread Klaus Jensen
From: Klaus Jensen 

nvme_directive_receive() does not check if an endurance group has been
configured (set) prior to testing if flexible data placement is enabled
or not.

Fix this.

Cc: qemu-sta...@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1815
Fixes: 73064edfb864 ("hw/nvme: flexible data placement emulation")
Reviewed-by: Jesper Wendel Devantier 
Signed-off-by: Klaus Jensen 
---
 hw/nvme/ctrl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index d217ae91b506..e5b5c7034d2b 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -6900,7 +6900,7 @@ static uint16_t nvme_directive_receive(NvmeCtrl *n, 
NvmeRequest *req)
 case NVME_DIRECTIVE_IDENTIFY:
 switch (doper) {
 case NVME_DIRECTIVE_RETURN_PARAMS:
-if (ns->endgrp->fdp.enabled) {
+if (ns->endgrp && ns->endgrp->fdp.enabled) {
 id.supported |= 1 << NVME_DIRECTIVE_DATA_PLACEMENT;
 id.enabled |= 1 << NVME_DIRECTIVE_DATA_PLACEMENT;
 id.persistent |= 1 << NVME_DIRECTIVE_DATA_PLACEMENT;
-- 
2.41.0




Re: [PATCH v2] target/i386: Avoid cpu number overflow in legacy topology

2023-08-09 Thread Igor Mammedov
On Wed, 9 Aug 2023 21:20:48 +0800
"Wen, Qian"  wrote:

> On 8/9/2023 7:14 PM, Igor Mammedov wrote:
> > On Wed,  9 Aug 2023 18:27:32 +0800
> > Qian Wen  wrote:
> >  
> >> The legacy topology enumerated by CPUID.1.EBX[23:16] is defined in SDM
> >> Vol2:
> >>
> >> Bits 23-16: Maximum number of addressable IDs for logical processors in
> >> this physical package.
> >>
> >> When launching the VM with -smp 256, the value written to EBX[23:16] is
> >> 0 because of data overflow. If the guest only supports legacy topology,
> >> without V2 Extended Topology enumerated by CPUID.0x1f or Extended
> >> Topology enumerated by CPUID.0x0b to support over 255 CPUs, the return
> >> of the kernel invoking cpu_smt_allowed() is false and AP's bring-up will
> >> fail. Then only CPU 0 is online, and others are offline.
> >>
> >> To avoid this issue caused by overflow, limit the max value written to
> >> EBX[23:16] to 255.  
> > what happens on real hw or in lack of thereof what SDM says about this
> > value when there is more than 255 threads?.
> >  
> 
> Current SDM doesn't specify what the value should be when APIC IDs per 
> package exceeds 255. So we asked the internal HW architect, the response is 
> that EBX[23:16] will report 255 instead of being truncated to a smaller value.

then mention it in commit log so one wouldn't wonder where the value came from.

> 
> Thanks,
> Qian
> 
> >> Signed-off-by: Qian Wen 
> >> ---
> >> Changes v1 -> v2:
> >>  - Revise the commit message and comment to more clearer.
> >>  - Rebased to v8.1.0-rc2.
> >> ---
> >>  target/i386/cpu.c | 16 ++--
> >>  1 file changed, 14 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> >> index 97ad229d8b..6e1d88fbd7 100644
> >> --- a/target/i386/cpu.c
> >> +++ b/target/i386/cpu.c
> >> @@ -6008,6 +6008,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> >> uint32_t count,
> >>  uint32_t die_offset;
> >>  uint32_t limit;
> >>  uint32_t signature[3];
> >> +uint32_t threads_per_socket;
> >>  X86CPUTopoInfo topo_info;
> >>  
> >>  topo_info.dies_per_pkg = env->nr_dies;
> >> @@ -6049,8 +6050,19 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t 
> >> index, uint32_t count,
> >>  *ecx |= CPUID_EXT_OSXSAVE;
> >>  }
> >>  *edx = env->features[FEAT_1_EDX];
> >> -if (cs->nr_cores * cs->nr_threads > 1) {
> >> -*ebx |= (cs->nr_cores * cs->nr_threads) << 16;
> >> +/*
> >> + * Only bits [23:16] represent the maximum number of addressable
> >> + * IDs for logical processors in this physical package.
> >> + * When thread_per_socket > 255, it will 1) overwrite bits[31:24]
> >> + * which is apic_id, 2) bits [23:16] get truncated.
> >> + */
> >> +threads_per_socket = cs->nr_cores * cs->nr_threads;
> >> +if (threads_per_socket > 255) {
> >> +threads_per_socket = 255;
> >> +}
> >> +
> >> +if (threads_per_socket > 1) {

> >> +*ebx |= threads_per_socket << 16;
  ^
more robust would be mask out non-relevant fields at rhs 

also perhaps double check if we could do induce similar overflow
tweaking other -smp properties (todo for another patch[es] if there are such 
places).

> >>  *edx |= CPUID_HT;
> >>  }
> >>  if (!cpu->enable_pmu) {  




Re: [PATCH for-8.2] configure: fix and complete detection of tricore tools

2023-08-09 Thread Bastian Koppelmann
On Wed, Aug 09, 2023 at 10:29:44AM +0200, Paolo Bonzini wrote:
> The tricore tools are not detected when they are installed in
> the host system, only if they are taken from an external
> container.  For this reason the build-tricore-softmmu job
> was not running the TCG tests.
> 
> In addition the container provides all tools, not just as/ld/gcc,
> so there is no need to special case tricore.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  configure | 5 +
>  1 file changed, 1 insertion(+), 4 deletions(-)

I think it would be better to skip debian-11 and use 12 instead.

Cheers,
Bastian



Re: [PATCH for-8.2] configure: fix and complete detection of tricore tools

2023-08-09 Thread Bastian Koppelmann
On Wed, Aug 09, 2023 at 03:49:01PM +0200, Bastian Koppelmann wrote:
> On Wed, Aug 09, 2023 at 10:29:44AM +0200, Paolo Bonzini wrote:
> > The tricore tools are not detected when they are installed in
> > the host system, only if they are taken from an external
> > container.  For this reason the build-tricore-softmmu job
> > was not running the TCG tests.
> > 
> > In addition the container provides all tools, not just as/ld/gcc,
> > so there is no need to special case tricore.
> > 
> > Signed-off-by: Paolo Bonzini 
> > ---
> >  configure | 5 +
> >  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> I think it would be better to skip debian-11 and use 12 instead.

Whoops I mixed it up with the other patch. For this one you can have

Reviewed-by: Bastian Koppelmann 

Cheers,
Bastian

> 
> Cheers,
> Bastian



Re: [PATCH for-8.2] dockerfiles: bump tricore cross compiler container to Debian 11

2023-08-09 Thread Bastian Koppelmann
On Wed, Aug 09, 2023 at 10:29:45AM +0200, Paolo Bonzini wrote:
> With the release of version 12 on June 10, 2023, Debian 10 is
> not supported anymore.  Modify the cross compiler container to
> build on a newer version.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/docker/dockerfiles/debian-tricore-cross.docker | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tests/docker/dockerfiles/debian-tricore-cross.docker 
> b/tests/docker/dockerfiles/debian-tricore-cross.docker
> index 269bfa8d423..5bd1963fb55 100644
> --- a/tests/docker/dockerfiles/debian-tricore-cross.docker
> +++ b/tests/docker/dockerfiles/debian-tricore-cross.docker
> @@ -9,7 +9,7 @@
>  #
>  # SPDX-License-Identifier: GPL-2.0-or-later
>  #
> -FROM docker.io/library/debian:buster-slim
> +FROM docker.io/library/debian:11-slim

I think it would be better to skip debian-11 and use 12 instead.

Cheers,
Bastian



Re: [PATCH v2] migration/calc-dirty-rate: millisecond-granularity period

2023-08-09 Thread gudkov . andrei--- via
On Sun, Aug 06, 2023 at 02:31:43PM +0800, Yong Huang wrote:
> On Sat, Aug 5, 2023 at 2:05 AM Markus Armbruster  wrote:
> 
> > Andrei Gudkov  writes:
> >
> > > Introduces alternative argument calc-time-ms, which is the
> > > the same as calc-time but accepts millisecond value.
> > > Millisecond granularity allows to make predictions whether
> > > migration will succeed or not. To do this, calculate dirty
> > > rate with calc-time-ms set to max allowed downtime, convert
> > > measured rate into volume of dirtied memory, and divide by
> > > network throughput. If the value is lower than max allowed
> > > downtime, then migration will converge.
> > >
> > > Measurement results for single thread randomly writing to
> > > a 1/4/24GiB memory region:
> > >
> > > +--+---+
> > > | calc-time-ms |dirty rate MiB/s   |
> > > |  ++---+--+
> > > |  | theoretical| page-sampling | dirty-bitmap |
> > > |  | (at 3M wr/sec) |   |  |
> > > +--++---+--+
> > > | 1GiB |
> > > +--++---+--+
> > > |  100 |   6996 |  7100 | 3192 |
> > > |  200 |   4606 |  4660 | 2655 |
> > > |  300 |   3305 |  3280 | 2371 |
> > > |  400 |   2534 |  2525 | 2154 |
> > > |  500 |   2041 |  2044 | 1871 |
> > > |  750 |   1365 |  1341 | 1358 |
> > > | 1000 |   1024 |  1052 | 1025 |
> > > | 1500 |683 |   678 |  684 |
> > > | 2000 |512 |   507 |  513 |
> > > +--++---+--+
> > > | 4GiB |
> > > +--++---+--+
> > > |  100 |  10232 |  8880 | 4070 |
> > > |  200 |   8954 |  8049 | 3195 |
> > > |  300 |   7889 |  7193 | 2881 |
> > > |  400 |   6996 |  6530 | 2700 |
> > > |  500 |   6245 |  5772 | 2312 |
> > > |  750 |   4829 |  4586 | 2465 |
> > > | 1000 |   3865 |  3780 | 2178 |
> > > | 1500 |   2694 |  2633 | 2004 |
> > > | 2000 |   2041 |  2031 | 1789 |
> > > +--++---+--+
> > > | 24GiB|
> > > +--++---+--+
> > > |  100 |  11495 |  8640 | 5597 |
> > > |  200 |  11226 |  8616 | 3527 |
> > > |  300 |  10965 |  8386 | 2355 |
> > > |  400 |  10713 |  8370 | 2179 |
> > > |  500 |  10469 |  8196 | 2098 |
> > > |  750 |   9890 |  7885 | 2556 |
> > > | 1000 |   9354 |  7506 | 2084 |
> > > | 1500 |   8397 |  6944 | 2075 |
> > > | 2000 |   7574 |  6402 | 2062 |
> > > +--++---+--+
> > >
> > > Theoretical values are computed according to the following formula:
> > > size * (1 - (1-(4096/size))^(time*wps)) / (time * 2^20),
> > > where size is in bytes, time is in seconds, and wps is number of
> > > writes per second.
> > >
> > > Signed-off-by: Andrei Gudkov 
> > > ---
> > >  qapi/migration.json   | 14 ++--
> > >  migration/dirtyrate.h | 12 ---
> > >  migration/dirtyrate.c | 81 +--
> > >  3 files changed, 67 insertions(+), 40 deletions(-)
> > >
> > > diff --git a/qapi/migration.json b/qapi/migration.json
> > > index 8843e74b59..82493d6a57 100644
> > > --- a/qapi/migration.json
> > > +++ b/qapi/migration.json
> > > @@ -1849,7 +1849,11 @@
> > >  # @start-time: start time in units of second for calculation
> > >  #
> > >  # @calc-time: time period for which dirty page rate was measured
> > > -# (in seconds)
> > > +# (rounded down to seconds).
> > > +#
> > > +# @calc-time-ms: actual time period for which dirty page rate was
> > > +# measured (in milliseconds).  Value may be larger than requested
> > > +# time period due to measurement overhead.
> > >  #
> > >  # @sample-pages: number of sampled pages per GiB of guest memory.
> > >  # Valid only in page-sam

Re: [PATCH for-8.2] dockerfiles: bump tricore cross compiler container to Debian 11

2023-08-09 Thread Paolo Bonzini
On Wed, Aug 9, 2023 at 3:53 PM Bastian Koppelmann
 wrote:
> > diff --git a/tests/docker/dockerfiles/debian-tricore-cross.docker 
> > b/tests/docker/dockerfiles/debian-tricore-cross.docker
> > index 269bfa8d423..5bd1963fb55 100644
> > --- a/tests/docker/dockerfiles/debian-tricore-cross.docker
> > +++ b/tests/docker/dockerfiles/debian-tricore-cross.docker
> > @@ -9,7 +9,7 @@
> >  #
> >  # SPDX-License-Identifier: GPL-2.0-or-later
> >  #
> > -FROM docker.io/library/debian:buster-slim
> > +FROM docker.io/library/debian:11-slim
>
> I think it would be better to skip debian-11 and use 12 instead.

I picked 11 in order to keep the container in sync with the
lcitool-generated dockerfiles. Once we switch lcitool from 11 to
12, it is easier to see what the changes are and replicate them in
debian-tricore-cross and friends.

lcitool support for Debian 12 has already landed, but usually we
try to keep the containers on the oldest supported release of a
distro, and that is currently Debian 11.

Paolo




Re: [PATCH] Fix SEGFAULT on getting physical address of MMIO region.

2023-08-09 Thread Richard Henderson

On 8/9/23 06:17, Mikhail Tyutin wrote:

Would not be better to get back to initial v1 approach when we clean 
TLB_INVALID_MASK flag in
tlb_plugin_lookup()? It works well for those regions.


You're just as likely to get invalid data.


r~



Re: [PATCH v5 02/11] target/loongarch: Add new object class for loongarch32 cpus

2023-08-09 Thread Richard Henderson

On 8/9/23 01:26, Jiajie Chen wrote:

Add object class for future loongarch32 cpus. It is derived from the
loongarch64 object class.

Signed-off-by: Jiajie Chen
---
  target/loongarch/cpu.c | 19 +++
  target/loongarch/cpu.h |  1 +
  2 files changed, 20 insertions(+)


Reviewed-by: Richard Henderson 

r~



Re: [RFC v4 01/11] build: Implement logic for sharing cross-building config files

2023-08-09 Thread Alex Bennée


Yeqi Fu  writes:

> Signed-off-by: Yeqi Fu 
> ---
>  configure | 57 +--
>  1 file changed, 34 insertions(+), 23 deletions(-)
>
> diff --git a/configure b/configure
> index 2b41c49c0d..a076583141 100755
> --- a/configure
> +++ b/configure
> @@ -1751,56 +1751,67 @@ if test "$ccache_cpp2" = "yes"; then
>echo "export CCACHE_CPP2=y" >> $config_host_mak
>  fi
>  
> -# tests/tcg configuration
> -(config_host_mak=tests/tcg/config-host.mak
> -mkdir -p tests/tcg
> -echo "# Automatically generated by configure - do not modify" > 
> $config_host_mak
> -echo "SRC_PATH=$source_path" >> $config_host_mak
> -echo "HOST_CC=$host_cc" >> $config_host_mak
> +# Prepare the config files for cross building.
> +# This process generates 'cross-build//config-target.mak' files.
> +# These files are then symlinked to the directories that need them which
> +# including the TCG tests (tests/tcg/) and the libnative library
> +# for linux-user (common/native//).
> +mkdir -p cross-build
>  
> -# versioned checked in the main config_host.mak above
> -if test -n "$gdb_bin"; then
> -echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
> -fi
> -if test "$plugins" = "yes" ; then
> -echo "CONFIG_PLUGIN=y" >> $config_host_mak
> -fi

I think there is a merge conflict here because a bunch of the
config-host.mak output has been squashed. This disabled plugins and gdb
testing.

> -
> -tcg_tests_targets=
>  for target in $target_list; do
>arch=${target%%-*}
> -
>case $target in
>  xtensa*-linux-user)
> -  # the toolchain is not complete with headers, only build softmmu tests
> +  # the toolchain for tests/tcg is not complete with headers
>continue
>;;
>  *-softmmu)
> -  test -f "$source_path/tests/tcg/$arch/Makefile.softmmu-target" || 
> continue

We still want to skip linking tests/tcg/foo-softmmu/config-target.mak
when there are no softmmu tests to build (only a few targets currently
have softmmu tests). I think this is triggering failures like:

  ➜  make run-tcg-tests-m68k-softmmu V=1
  make -C tests/tcg/m68k-softmmu 
  make[1]: Entering directory 
'/home/alex/lsrc/qemu.git/builds/all/tests/tcg/m68k-softmmu'
  make[1]: Nothing to be done for 'all'.
  make[1]: Leaving directory 
'/home/alex/lsrc/qemu.git/builds/all/tests/tcg/m68k-softmmu'
  make -C tests/tcg/m68k-softmmu  SPEED=quick run
  make[1]: Entering directory 
'/home/alex/lsrc/qemu.git/builds/all/tests/tcg/m68k-softmmu'
  make[1]: *** No rule to make target 'hello', needed by 
'run-plugin-hello-with-libbb.so'.  Stop.
  make[1]: Leaving directory 
'/home/alex/lsrc/qemu.git/builds/all/tests/tcg/m68k-softmmu'
  make: *** [/home/alex/lsrc/qemu.git/tests/Makefile.include:56: 
run-tcg-tests-m68k-softmmu] Erro

>qemu="qemu-system-$arch"
>;;
>  *-linux-user|*-bsd-user)
>qemu="qemu-$arch"
>;;
>esac
> -
>if probe_target_compiler $target || test -n "$container_image"; then
>test -n "$container_image" && build_static=y
> -  mkdir -p "tests/tcg/$target"
> -  config_target_mak=tests/tcg/$target/config-target.mak
> -  ln -sf "$source_path/tests/tcg/Makefile.target" 
> "tests/tcg/$target/Makefile"
> +  mkdir -p "cross-build/$target"
> +  config_target_mak=cross-build/$target/config-target.mak
>echo "# Automatically generated by configure - do not modify" > 
> "$config_target_mak"
>echo "TARGET_NAME=$arch" >> "$config_target_mak"
>echo "TARGET=$target" >> "$config_target_mak"
> -  write_target_makefile "build-tcg-tests-$target" >> "$config_target_mak"
> +  write_target_makefile "$target" >> "$config_target_mak"
>echo "BUILD_STATIC=$build_static" >> "$config_target_mak"
>echo "QEMU=$PWD/$qemu" >> "$config_target_mak"
>  
> +  # get the interpreter prefix and the path of libnative required for 
> native call tests
> +  if [ -d "/usr/$(echo "$target_cc" | sed 's/-gcc//')" ]; then
> +  echo "LD_PREFIX=/usr/$(echo "$target_cc" | sed 's/-gcc//')" >> 
> "$config_target_mak"
> +  fi
> +

We should only emit LD_PREFIX for -user targets.

># will GDB work with these binaries?
>if test "${gdb_arches#*$arch}" != "$gdb_arches"; then
>echo "HOST_GDB_SUPPORTS_ARCH=y" >> "$config_target_mak"
>fi
> +  fi
> +done
> +
> +# tests/tcg configuration
> +(mkdir -p tests/tcg
> +# create a symlink to the config-host.mak file in the tests/tcg
> +ln -srf $config_host_mak tests/tcg/config-host.mak
> +
> +tcg_tests_targets=
> +for target in $target_list; do
> +  case $target in
> +*-softmmu)
> +  test -f "$source_path/tests/tcg/$arch/Makefile.softmmu-target" || 
> continue
> +  ;;
> +  esac
>  
> +  if test -f cross-build/$target/config-target.mak; then
> +  mkdir -p "tests/tcg/$target"
> +  ln -srf cross-build/$target/config-target.mak 
> tests/tcg/$target/config-target.mak
> +  ln -sf $source_path/tests/tcg/Makefile.target 
> tests/tc

Re: [PATCH for-8.2 2/3] pnv/lpc: Hook up xscom region for P9/P10

2023-08-09 Thread Frederic Barrat

Hello Joel,

So we're re-using the same xscom ops as on P8. A quick look at the 
definition of those 4 registers on P8 (0xb0020) and on P9/P10 
(0x00090040) seem to show they are not the same though. Am i missing 
something?


  Fred


On 08/08/2023 10:34, Joel Stanley wrote:

 From P9 on the LPC bus is memory mapped. However the xscom access still
is possible, so add it too.

Signed-off-by: Joel Stanley 
---
  include/hw/ppc/pnv_xscom.h | 6 ++
  hw/ppc/pnv.c   | 4 
  hw/ppc/pnv_lpc.c   | 6 ++
  3 files changed, 16 insertions(+)

diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 9bc64635471e..42601bdf419d 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -96,6 +96,9 @@ struct PnvXScomInterfaceClass {
  #define PNV9_XSCOM_SBE_CTRL_BASE  0x00050008
  #define PNV9_XSCOM_SBE_CTRL_SIZE  0x1
  
+#define PNV9_XSCOM_LPC_BASE   0x00090040

+#define PNV9_XSCOM_LPC_SIZE   PNV_XSCOM_LPC_SIZE
+
  #define PNV9_XSCOM_SBE_MBOX_BASE  0x000D0050
  #define PNV9_XSCOM_SBE_MBOX_SIZE  0x16
  
@@ -155,6 +158,9 @@ struct PnvXScomInterfaceClass {

  #define PNV10_XSCOM_SBE_CTRL_BASE  PNV9_XSCOM_SBE_CTRL_BASE
  #define PNV10_XSCOM_SBE_CTRL_SIZE  PNV9_XSCOM_SBE_CTRL_SIZE
  
+#define PNV10_XSCOM_LPC_BASE   PNV9_XSCOM_LPC_BASE

+#define PNV10_XSCOM_LPC_SIZE   PNV9_XSCOM_LPC_SIZE
+
  #define PNV10_XSCOM_SBE_MBOX_BASE  PNV9_XSCOM_SBE_MBOX_BASE
  #define PNV10_XSCOM_SBE_MBOX_SIZE  PNV9_XSCOM_SBE_MBOX_SIZE
  
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c

index afdaa25c2b26..a5db655b41b6 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1566,6 +1566,8 @@ static void pnv_chip_power9_realize(DeviceState *dev, 
Error **errp)
  }
  memory_region_add_subregion(get_system_memory(), PNV9_LPCM_BASE(chip),
  &chip9->lpc.mmio_regs);
+pnv_xscom_add_subregion(chip, PNV9_XSCOM_LPC_BASE,
+&chip9->lpc.xscom_regs);
  
  chip->fw_mr = &chip9->lpc.isa_fw;

  chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
@@ -1785,6 +1787,8 @@ static void pnv_chip_power10_realize(DeviceState *dev, 
Error **errp)
  }
  memory_region_add_subregion(get_system_memory(), PNV10_LPCM_BASE(chip),
  &chip10->lpc.mmio_regs);
+pnv_xscom_add_subregion(chip, PNV10_XSCOM_LPC_BASE,
+&chip10->lpc.xscom_regs);
  
  chip->fw_mr = &chip10->lpc.isa_fw;

  chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index caf5e10a5f96..6c6a3134087f 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -666,6 +666,12 @@ static void pnv_lpc_power9_realize(DeviceState *dev, Error 
**errp)
  /* P9 uses a MMIO region */
  memory_region_init_io(&lpc->mmio_regs, OBJECT(lpc), &pnv_lpc_mmio_ops,
lpc, "lpcm", PNV9_LPCM_SIZE);
+
+/* but the XSCOM region still exists */
+pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(lpc),
+  &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
+  PNV_XSCOM_LPC_SIZE);
+
  }
  
  static void pnv_lpc_power9_class_init(ObjectClass *klass, void *data)




Re: [PATCH v5 08/11] target/loongarch: Reject la64-only instructions in la32 mode

2023-08-09 Thread Richard Henderson

On 8/9/23 01:26, Jiajie Chen wrote:

LoongArch64-only instructions are marked with regard to the instruction
manual Table 2. LSX instructions are not marked for now for lack of
public manual.


I would expect LSX not to be affected by CPUCFG.1.ARCH, but only by 
CPUCFG.2.LSX.

Note that there appears to be a bug with respect to LSX, in that CPUCFG.2.LSX is not 
checked.  The manual is not clear, but I would expect CPUCFG.2.LSX == 0 to trigger an 
illegal instruction exception before the check for EUEN.SXE == 0 to trigger an instruction 
disable exception.  Also, are bit in EUEN allowed to be set to non-zero values when the 
corresponding expansion is not present?


But that is not a problem with this patch, so:

Reviewed-by: Richard Henderson 


r~



Re: [PATCH v2] migration/calc-dirty-rate: millisecond-granularity period

2023-08-09 Thread gudkov . andrei--- via
On Sun, Aug 06, 2023 at 02:16:34PM +0800, Yong Huang wrote:
> On Fri, Aug 4, 2023 at 11:03 PM Andrei Gudkov 
> wrote:
> 
> > Introduces alternative argument calc-time-ms, which is the
> > the same as calc-time but accepts millisecond value.
> > Millisecond granularity allows to make predictions whether
> > migration will succeed or not. To do this, calculate dirty
> > rate with calc-time-ms set to max allowed downtime, convert
> > measured rate into volume of dirtied memory, and divide by
> > network throughput. If the value is lower than max allowed
> >
> Not for the patch, I'm just curious about how the predication
> decides the network throughput, I mean QEMU predicts
> if migration will converge based on how fast it sends the data,
> not the actual bandwidth of the interface, which one the
> prediction uses?
> 
Currently I use network nominal bandwidth, e.g. 1gbps. It would
be nice, of course, to use measured throughput since it can take
into account network headers overhead (as Wang Lei previously
mentioned), compression, etc., but it looks too complicated to
implement outside of migration process.

> > downtime, then migration will converge.
> >
> > Measurement results for single thread randomly writing to
> > a 1/4/24GiB memory region:
> >
> > +--+---+
> > | calc-time-ms |dirty rate MiB/s   |
> > |  ++---+--+
> > |  | theoretical| page-sampling | dirty-bitmap |
> > |  | (at 3M wr/sec) |   |  |
> > +--++---+--+
> > | 1GiB |
> > +--++---+--+
> > |  100 |   6996 |  7100 | 3192 |
> > |  200 |   4606 |  4660 | 2655 |
> > |  300 |   3305 |  3280 | 2371 |
> > |  400 |   2534 |  2525 | 2154 |
> > |  500 |   2041 |  2044 | 1871 |
> > |  750 |   1365 |  1341 | 1358 |
> > | 1000 |   1024 |  1052 | 1025 |
> > | 1500 |683 |   678 |  684 |
> > | 2000 |512 |   507 |  513 |
> > +--++---+--+
> > | 4GiB |
> > +--++---+--+
> > |  100 |  10232 |  8880 | 4070 |
> > |  200 |   8954 |  8049 | 3195 |
> > |  300 |   7889 |  7193 | 2881 |
> > |  400 |   6996 |  6530 | 2700 |
> > |  500 |   6245 |  5772 | 2312 |
> > |  750 |   4829 |  4586 | 2465 |
> > | 1000 |   3865 |  3780 | 2178 |
> > | 1500 |   2694 |  2633 | 2004 |
> > | 2000 |   2041 |  2031 | 1789 |
> > +--++---+--+
> > | 24GiB|
> > +--++---+--+
> > |  100 |  11495 |  8640 | 5597 |
> > |  200 |  11226 |  8616 | 3527 |
> > |  300 |  10965 |  8386 | 2355 |
> > |  400 |  10713 |  8370 | 2179 |
> > |  500 |  10469 |  8196 | 2098 |
> > |  750 |   9890 |  7885 | 2556 |
> > | 1000 |   9354 |  7506 | 2084 |
> > | 1500 |   8397 |  6944 | 2075 |
> > | 2000 |   7574 |  6402 | 2062 |
> > +--++---+--+
> >
> > Theoretical values are computed according to the following formula:
> > size * (1 - (1-(4096/size))^(time*wps)) / (time * 2^20),
> > where size is in bytes, time is in seconds, and wps is number of
> > writes per second.
> >
> > Signed-off-by: Andrei Gudkov 
> > ---
> >  qapi/migration.json   | 14 ++--
> >  migration/dirtyrate.h | 12 ---
> >  migration/dirtyrate.c | 81 +--
> >  3 files changed, 67 insertions(+), 40 deletions(-)
> >
> > [...]
> 
> > diff --git a/qapi/migration.json b/qapi/migration.json
> > index 8843e74b59..82493d6a57 100644
> > --- a/qapi/migration.json
> > +++ b/qapi/migration.json
> > @@ -1849,7 +1849,11 @@
> >  # @start-time: start time in units of second for calculation
> >  #
> >  # @calc-time: time period for which dirty page rate was measured

Re: [PATCH v5 09/11] target/loongarch: Truncate high 32 bits of address in VA32 mode

2023-08-09 Thread Richard Henderson

On 8/9/23 01:26, Jiajie Chen wrote:

When running in VA32 mode(!LA64 or VA32L[1-3] matching PLV), virtual
address is truncated to 32 bits before address mapping.

Signed-off-by: Jiajie Chen
Co-authored-by: Richard Henderson
---
  target/loongarch/cpu.c| 16 
  target/loongarch/cpu.h|  9 +
  target/loongarch/gdbstub.c|  2 +-
  .../loongarch/insn_trans/trans_atomic.c.inc   |  5 ++-
  .../loongarch/insn_trans/trans_branch.c.inc   |  3 +-
  .../loongarch/insn_trans/trans_fmemory.c.inc  | 30 ---
  target/loongarch/insn_trans/trans_lsx.c.inc   | 38 +--
  .../loongarch/insn_trans/trans_memory.c.inc   | 34 +
  target/loongarch/op_helper.c  |  4 +-
  target/loongarch/translate.c  | 32 
  10 files changed, 85 insertions(+), 88 deletions(-)


Much better, thanks.

Reviewed-by: Richard Henderson 


r~



Re: [PATCH v5 10/11] target/loongarch: Sign extend results in VA32 mode

2023-08-09 Thread Richard Henderson

On 8/9/23 01:26, Jiajie Chen wrote:

In VA32 mode, BL, JIRL and PC* instructions should sign-extend the low
32 bit result to 64 bits.

Signed-off-by: Jiajie Chen
---
  target/loongarch/insn_trans/trans_arith.c.inc  | 2 +-
  target/loongarch/insn_trans/trans_branch.c.inc | 4 ++--
  target/loongarch/translate.c   | 8 
  3 files changed, 11 insertions(+), 3 deletions(-)


Reviewed-by: Richard Henderson 


r~



Fix interval_tree_iter_first() to check root node value

2023-08-09 Thread Helge Deller
Fix a crash in qemu-user when running

cat /proc/self/maps

in a chroot, where /proc isn't mounted.

The problem was introduced by commit 3ce3dd8ca965 ("util/selfmap:
Rewrite using qemu/interval-tree.h") where in open_self_maps_1() the
function read_self_maps() is called and which returns NULL if it can't
read the hosts /proc/self/maps file. Afterwards that NULL is fed into
interval_tree_iter_first() which doesn't check if the root node is NULL.

Fix it by adding a check if root is NULL and return NULL in that case.

Signed-off-by: Helge Deller 
Fixes: 3ce3dd8ca965 ("util/selfmap: Rewrite using qemu/interval-tree.h")

diff --git a/util/interval-tree.c b/util/interval-tree.c
index f2866aa7d3..53465182e6 100644
--- a/util/interval-tree.c
+++ b/util/interval-tree.c
@@ -797,7 +797,7 @@ IntervalTreeNode *interval_tree_iter_first(IntervalTreeRoot 
*root,
 {
 IntervalTreeNode *node, *leftmost;

-if (!root->rb_root.rb_node) {
+if (!root || !root->rb_root.rb_node) {
 return NULL;
 }




Re: [PATCH v5 11/11] target/loongarch: Add loongarch32 cpu la132

2023-08-09 Thread Richard Henderson

On 8/9/23 01:26, Jiajie Chen wrote:

Add la132 as a loongarch32 cpu type and allow virt machine to be used
with la132 instead of la464.

Due to lack of public documentation of la132, it is currently a
synthetic loongarch32 cpu model. Details need to be added in the future.

Signed-off-by: Jiajie Chen
---
  hw/loongarch/virt.c|  5 -
  target/loongarch/cpu.c | 29 +
  2 files changed, 29 insertions(+), 5 deletions(-)


Acked-by: Richard Henderson 


r~



Re: [PATCH v1 1/3] softmmu/physmem: fallback to opening guest RAM file as readonly in a MAP_PRIVATE mapping

2023-08-09 Thread Peter Xu
On Wed, Aug 09, 2023 at 11:20:11AM +0200, David Hildenbrand wrote:
> Hi Peter!

Hi, David,

> 
> > > -fd = file_ram_open(mem_path, memory_region_name(mr), readonly, 
> > > &created,
> > > -   errp);
> > > +fd = file_ram_open(mem_path, memory_region_name(mr), readonly, 
> > > &created);
> > > +if (fd == -EACCES && !(ram_flags & RAM_SHARED) && !readonly) {
> > > +/*
> > > + * We can have a writable MAP_PRIVATE mapping of a readonly file.
> > > + * However, some operations like ftruncate() or fallocate() 
> > > might fail
> > > + * later, let's warn the user.
> > > + */
> > > +fd = file_ram_open(mem_path, memory_region_name(mr), true, 
> > > &created);
> > > +if (fd >= 0) {
> > > +warn_report("backing store %s for guest RAM (MAP_PRIVATE) 
> > > opened"
> > > +" readonly because the file is not writable", 
> > > mem_path);
> > 
> > I can understand the use case, but this will be slightly unwanted,
> > especially the user doesn't yet have a way to predict when will it happen.
> 
> Users can set the file permissions accordingly I guess. If they don't want
> the file to never ever be modified via QEMU, set it R/O.
> 
> > 
> > Meanwhile this changes the behavior, is it a concern that someone may want
> > to rely on current behavior of failing?
> 
> The scenario would be that someone passes a readonly file to "-mem-path" or
> "-object memory-backend-file,share=off,readonly=off", with the expectation
> that it would currently fail.
> 
> If it now doesn't fail (and we warn instead), what would happen is:
> * In file_ram_alloc() we won't even try ftruncate(), because the file
>   already had a size > 0. So ftruncate() is not a concern as I now
>   realize.
> * fallocate might fail later. AFAIKS, that only applies to
>   ram_block_discard_range().
>  -> virtio-mem performs an initial ram_block_discard_range() check and
> fails gracefully early.
>  -> virtio-ballooon ignores any errors
>  -> ram_discard_range() in migration code fails early for postcopy in
> init_range() and loadvm_postcopy_ram_handle_discard(), handling it
> gracefully.
> 
> So mostly nothing "bad" would happen, it might just be undesirable, and we
> properly warn.

Indeed, all of them can fail gracefully, while balloon one is harmless.
Definitely good news.

> 
> Most importantly, we won't be corrupting/touching the original file in any
> case, because it is R/O.
> 
> If we really want to be careful, we could clue that behavior to compat
> machines. I'm not really sure yet if we really have to go down that path.
> 
> Any other alternatives? I'd like to avoid new flags where not really
> required.

I was just thinking of a new flag. :) So have you already discussed that
possibility and decided that not a good idea?

The root issue to me here is we actually have two resources (memory map of
the process, and the file) but we only have one way to describe the
permissions upon the two objects.  I'd think it makes a lot more sense if a
new flag is added, when there's a need to differentiate the two.

Consider if you see a bunch of qemu instances with:

  -mem-path $RAM_FILE

On the same host, which can be as weird as it could be to me.. At least
'-mem-path' looks still like a way to exclusively own a ram file for an
instance. I hesitate the new fallback can confuse people too, while that's
so far not the major use case.

Nobody may really rely on any existing behavior of the failure, but
changing existing behavior is just always not wanted.  The guideline here
to me is: whether we want existing "-mem-path XXX" users to start using the
fallback in general?  If it's "no", then maybe it implies a new flag is
better?

> 
> > 
> > To think from a higher level of current use case, the ideal solution seems
> > to me that if the ram file can be put on a file system that supports CoW
> > itself (like btrfs), we can snapshot that ram file and make it RW for the
> > qemu instance. Then here it'll be able to open the file.  We'll be able to
> > keep the interface working as before, meanwhile it'll work with fallocate
> > or truncations too I assume.
> > 
> > Would that be better instead of changing QEMU?
> 
> As I recently learned, using file-backed VMs (on real ssd/disks, not
> shmem/hugetlb) is usually undesired, because the dirtied pages will
> constantly get rewritten to disk by background writeback threads, eventually
> resulting in bad performance and SSD wear.
> 
> So while using a COW filesystem sounds cleaner in theory, it's not
> applicable in practice -- unless one disables any background writeback,
> which has different side effects because it cannot be configured on a
> per-file basis.
> 
> So for VM templating, it makes sense to capture the guest RAM and store it
> in a file, to then use a COW (MAP_PRIVATE) mapping. Using a read-only file
> makes perfect sense in that scenario IMHO.

Valid point.

> 
> [I'm curious at wha

Re: Fix interval_tree_iter_first() to check root node value

2023-08-09 Thread Richard Henderson

On 8/9/23 08:11, Helge Deller wrote:

Fix a crash in qemu-user when running

 cat /proc/self/maps

in a chroot, where /proc isn't mounted.

The problem was introduced by commit 3ce3dd8ca965 ("util/selfmap:
Rewrite using qemu/interval-tree.h") where in open_self_maps_1() the
function read_self_maps() is called and which returns NULL if it can't
read the hosts /proc/self/maps file. Afterwards that NULL is fed into
interval_tree_iter_first() which doesn't check if the root node is NULL.

Fix it by adding a check if root is NULL and return NULL in that case.

Signed-off-by: Helge Deller 
Fixes: 3ce3dd8ca965 ("util/selfmap: Rewrite using qemu/interval-tree.h")

diff --git a/util/interval-tree.c b/util/interval-tree.c
index f2866aa7d3..53465182e6 100644
--- a/util/interval-tree.c
+++ b/util/interval-tree.c
@@ -797,7 +797,7 @@ IntervalTreeNode *interval_tree_iter_first(IntervalTreeRoot 
*root,
  {
  IntervalTreeNode *node, *leftmost;

-if (!root->rb_root.rb_node) {
+if (!root || !root->rb_root.rb_node) {



I guess this is good enough for 8.1.  Before the conversion to interval-tree we would also 
emit nothing.


I've already done a rewrite for 8.2, and I noticed this problem.  There I emit what 
mapping information that I have, which is everything except for the device+path data.


Reviewed-by: Richard Henderson 


r~



Re: [RFC v4 02/11] build: Implement libnative library and the build machinery for libnative

2023-08-09 Thread Alex Bennée


Yeqi Fu  writes:

> This commit implements a shared library, where native functions are
> rewritten as special instructions. At runtime, user programs load
> the shared library, and special instructions are executed when
> native functions are called.
>
> Signed-off-by: Yeqi Fu 
> ---
>  Makefile|  2 +
>  common-user/native/Makefile.include |  9 
>  common-user/native/Makefile.target  | 22 ++
>  common-user/native/libnative.c  | 67 +
>  configure   | 39 +
>  include/native/libnative.h  |  8 
>  6 files changed, 147 insertions(+)
>  create mode 100644 common-user/native/Makefile.include
>  create mode 100644 common-user/native/Makefile.target
>  create mode 100644 common-user/native/libnative.c
>  create mode 100644 include/native/libnative.h
>
> diff --git a/Makefile b/Makefile
> index 5d48dfac18..6f6147b40f 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -182,6 +182,8 @@ SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory --quiet)
>  
>  include $(SRC_PATH)/tests/Makefile.include
>  
> +include $(SRC_PATH)/common-user/native/Makefile.include
> +
>  all: recurse-all
>  
>  ROMS_RULES=$(foreach t, all clean distclean, $(addsuffix /$(t), $(ROMS)))
> diff --git a/common-user/native/Makefile.include 
> b/common-user/native/Makefile.include
> new file mode 100644
> index 00..40d20bcd4c
> --- /dev/null
> +++ b/common-user/native/Makefile.include
> @@ -0,0 +1,9 @@
> +.PHONY: build-native
> +build-native: $(NATIVE_TARGETS:%=build-native-library-%)
> +$(NATIVE_TARGETS:%=build-native-library-%): build-native-library-%:
> + $(call quiet-command, \
> + $(MAKE) -C common-user/native/$* $(SUBDIR_MAKEFLAGS), \
> + "BUILD","$* native library")
> +# endif
> +
> +all: build-native
> diff --git a/common-user/native/Makefile.target 
> b/common-user/native/Makefile.target
> new file mode 100644
> index 00..0c1241b368
> --- /dev/null
> +++ b/common-user/native/Makefile.target
> @@ -0,0 +1,22 @@
> +# -*- Mode: makefile -*-
> +#
> +# Library for native calls
> +#
> +
> +all:
> +-include ../../config-host.mak

This is sensitive to the out of tree build structure the user chooses. For
example:

  ➜  pwd
  /home/alex/lsrc/qemu.git/builds/user/common-user/native/aarch64-linux-user
  🕙16:20:08 alex@zen:common-user/native/aarch64-linux-user  on  
review/native-lib-calls-v4 [$!?] 
  ➜  make libnative.so
  make: *** No rule to make target '/common-user/native/libnative.c', needed by 
'libnative.so'.  Stop.
  🕙16:20:13 alex@zen:common-user/native/aarch64-linux-user  on  
review/native-lib-calls-v4 [$!?] [🔴 USAGE] 
  ✗  

I think this can be solved the same way as we do for tests/tcg by
symlinking the config-host.mak into place and referring to it directly
or adjusting the include to ../../../config-host.mak because the top of
the build tree has a symlinked copy as well.


> +-include config-target.mak
> +
> +CFLAGS+=-O1 -fPIC -shared -fno-stack-protector -I$(SRC_PATH)/include 
> -D$(TARGET_NAME)
> +LDFLAGS+=
> +
> +SRC = $(SRC_PATH)/common-user/native/libnative.c
> +LIBNATIVE = libnative.so
> +
> +all: $(LIBNATIVE)
> +
> +$(LIBNATIVE): $(SRC)
> + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(EXTRA_NATIVE_CALL_FLAGS) $< -o $@ 
> $(LDFLAGS)
> +
> +clean:
> + rm -f $(LIBNATIVE)
> diff --git a/common-user/native/libnative.c b/common-user/native/libnative.c
> new file mode 100644
> index 00..662ae6fbfe
> --- /dev/null
> +++ b/common-user/native/libnative.c
> @@ -0,0 +1,67 @@
> +#include 
> +#include 
> +#include 
> +
> +#include "native/libnative.h"
> +
> +#define WRAP_NATIVE() \
> +do {  \
> +__asm__ volatile(__CALL_EXPR : : : "memory"); \
> +} while (0)
> +
> +#if defined(i386) || defined(x86_64)
> +/*
> + * An unused instruction is utilized to mark a native call.
> + */
> +#define __CALL_EXPR ".byte 0x0f, 0xff;"
> +#endif
> +
> +#if defined(arm) || defined(aarch64)
> +/*
> + * HLT is an invalid instruction for userspace and usefully has 16
> + * bits of spare immeadiate data which we can stuff data in.
> + */
> +#define __CALL_EXPR "hlt 0x;"
> +#endif
> +
> +#if defined(mips) || defined(mips64)
> +/*
> + * The syscall instruction contains 20 unused bits, which are typically
> + * set to 0. These bits can be used to store non-zero data,
> + * distinguishing them from a regular syscall instruction.
> + */
> +#define __CALL_EXPR "syscall 0x;"
> +#endif
> +
> +void *memcpy(void *dest, const void *src, size_t n)
> +{
> +WRAP_NATIVE();
> +}
> +int memcmp(const void *s1, const void *s2, size_t n)
> +{
> +WRAP_NATIVE();
> +}
> +void *memset(void *s, int c, size_t n)
> +{
> +WRAP_NATIVE();
> +}
> +char *strncpy(char *dest, const char *src, size_t n)
> +{
> +WRAP_NATIVE();
> +}
> +int strncmp(const char *s1, const char *s2, size_t n)
> +{
> +WRAP_NATIVE();
> +}
> +char *strcpy

Re: [RFC PATCH 15/19] kvm: handle KVM_EXIT_MEMORY_FAULT

2023-08-09 Thread Xu Yilun
On 2023-07-31 at 12:21:57 -0400, Xiaoyao Li wrote:
> From: Chao Peng 
> 
> Currently only KVM_MEMORY_EXIT_FLAG_PRIVATE in flags is valid when
> KVM_EXIT_MEMORY_FAULT happens. It indicates userspace needs to do
> the memory conversion on the RAMBlock to turn the memory into desired
> attribute, i.e., private/shared.
> 
> Note, KVM_EXIT_MEMORY_FAULT makes sense only when the RAMBlock has
> gmem memory backend.
> 
> Signed-off-by: Chao Peng 
> Signed-off-by: Xiaoyao Li 
> ---
>  accel/kvm/kvm-all.c | 52 +
>  1 file changed, 52 insertions(+)
> 
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index f9b5050b8885..72d50b923bf2 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -3040,6 +3040,48 @@ static void kvm_eat_signals(CPUState *cpu)
>  } while (sigismember(&chkset, SIG_IPI));
>  }
>  
> +static int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private)
> +{
> +MemoryRegionSection section;
> +void *addr;
> +RAMBlock *rb;
> +ram_addr_t offset;
> +int ret = -1;
> +
> +section = memory_region_find(get_system_memory(), start, size);
> +if (!section.mr) {
> +return ret;
> +}
> +
> +if (memory_region_can_be_private(section.mr)) {
> +if (to_private) {
> +ret = kvm_set_memory_attributes_private(start, size);
> +} else {
> +ret = kvm_set_memory_attributes_shared(start, size);
> +}
> +
> +if (ret) {
> +return ret;

Should we unref the memory region before return?

Thanks,
Yilun

> +}
> +
> +addr = memory_region_get_ram_ptr(section.mr) +
> +   section.offset_within_region;
> +rb = qemu_ram_block_from_host(addr, false, &offset);
> +/*
> + * With KVM_SET_MEMORY_ATTRIBUTES by kvm_set_memory_attributes(),
> + * operation on underlying file descriptor is only for releasing
> + * unnecessary pages.
> + */
> +ram_block_convert_range(rb, offset, size, to_private);
> +} else {
> +warn_report("Convert non guest-memfd backed memory region 
> (0x%"HWADDR_PRIx" ,+ 0x%"HWADDR_PRIx") to %s",
> +start, size, to_private ? "private" : "shared");
> +}
> +
> +memory_region_unref(section.mr);
> +return ret;
> +}



Re: [RFC v4 01/11] build: Implement logic for sharing cross-building config files

2023-08-09 Thread Alex Bennée


Alex Bennée  writes:

> Yeqi Fu  writes:
>
>> Signed-off-by: Yeqi Fu 
>> ---
>>  configure | 57 +--
>>  1 file changed, 34 insertions(+), 23 deletions(-)
>>
>> diff --git a/configure b/configure
>> index 2b41c49c0d..a076583141 100755
>> --- a/configure
>> +++ b/configure
>> @@ -1751,56 +1751,67 @@ if test "$ccache_cpp2" = "yes"; then
>>echo "export CCACHE_CPP2=y" >> $config_host_mak
>>  fi
>>  
>> -# tests/tcg configuration
>> -(config_host_mak=tests/tcg/config-host.mak
>> -mkdir -p tests/tcg
>> -echo "# Automatically generated by configure - do not modify" > 
>> $config_host_mak
>> -echo "SRC_PATH=$source_path" >> $config_host_mak
>> -echo "HOST_CC=$host_cc" >> $config_host_mak
>> +# Prepare the config files for cross building.
>> +# This process generates 'cross-build//config-target.mak' files.
>> +# These files are then symlinked to the directories that need them which
>> +# including the TCG tests (tests/tcg/) and the libnative library
>> +# for linux-user (common/native//).
>> +mkdir -p cross-build
>>  
>> -# versioned checked in the main config_host.mak above
>> -if test -n "$gdb_bin"; then
>> -echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
>> -fi
>> -if test "$plugins" = "yes" ; then
>> -echo "CONFIG_PLUGIN=y" >> $config_host_mak
>> -fi
>
> I think there is a merge conflict here because a bunch of the
> config-host.mak output has been squashed. This disabled plugins and gdb
> testing.

Ahh I see now this was intentional because we symlink however it was
lost in the noise of the diff. As Manos pointed out detailing the
movement in the commit message aids reviewers in tracing what has
changed.

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v2] migration/calc-dirty-rate: millisecond-granularity period

2023-08-09 Thread Peter Xu
On Wed, Aug 09, 2023 at 06:02:52PM +0300, gudkov.and...@huawei.com wrote:
> > Not for the patch, I'm just curious about how the predication
> > decides the network throughput, I mean QEMU predicts
> > if migration will converge based on how fast it sends the data,
> > not the actual bandwidth of the interface, which one the
> > prediction uses?
> > 
> Currently I use network nominal bandwidth, e.g. 1gbps. It would
> be nice, of course, to use measured throughput since it can take
> into account network headers overhead (as Wang Lei previously
> mentioned), compression, etc., but it looks too complicated to
> implement outside of migration process.

Using line speed is definitely wise, but qemu may be stupid enough to do
wrong calculations and when it happens migration may not switchover..

See this:

https://lore.kernel.org/r/20230803155344.11450-3-pet...@redhat.com

Probably should be used together with your ways of prediction to be even
more accurate on some workloads where mbps reports insane numbers.

Thanks,

-- 
Peter Xu




[PATCH QEMU] docs/migration: Add the dirty limit section

2023-08-09 Thread ~hyman
From: Hyman Huang(黄勇) 

The dirty limit feature has been introduced since the 8.1
QEMU release but has not reflected in the document, add a
section for that.

Signed-off-by: Hyman Huang(黄勇) 
---
 docs/devel/migration.rst | 70 
 1 file changed, 70 insertions(+)

diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index c3e1400c0c..4cc83adc8e 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -588,6 +588,76 @@ path.
  Return path  - opened by main thread, written by main thread AND postcopy
  thread (protected by rp_mutex)
 
+Dirty limit
+=
+The dirty limit, short for dirty page rate upper limit, is a new capability
+introduced in the 8.1 QEMU release that uses a new algorithm based on the KVM
+dirty ring to throttle down the guest during live migration.
+
+The algorithm framework is as follows:
+
+::
+
+  ---
+  main   --> throttle thread > PREPARE(1) <
+  thread  \|  |
+   \   |  |
+\  V  |
+ -\CALCULATE(2)   |
+   \   |  |
+\  |  |
+ \ V  |
+  \SET PENALTY(3) -
+   -\  |
+ \ |
+  \V
+   -> virtual CPU thread ---> ACCEPT PENALTY(4)
+  ---
+When the qmp command qmp_set_vcpu_dirty_limit is called for the first time,
+the QEMU main thread starts the throttle thread. The throttle thread, once
+launched, executes the loop, which consists of three steps:
+
+  - PREPARE (1)
+
+ The entire work of PREPARE (1) is prepared for the second stage,
+ CALCULATE(2), as the name implies. It involves preparing the dirty
+ page rate value and the corresponding upper limit of the VM:
+ The dirty page rate is calculated via the KVM dirty ring mechanism,
+ which tells QEMU how many dirty pages a virtual CPU has had since the
+ last KVM_EXIT_DIRTY_RING_RULL exception; The dirty page rate upper
+ limit is specified by caller, therefore fetch it directly.
+
+  - CALCULATE (2)
+
+ Calculate a suitable sleep period for each virtual CPU, which will be
+ used to determine the penalty for the target virtual CPU. The
+ computation must be done carefully in order to reduce the dirty page
+ rate progressively down to the upper limit without oscillation. To
+ achieve this, two strategies are provided: the first is to add or
+ subtract sleep time based on the ratio of the current dirty page rate
+ to the limit, which is used when the current dirty page rate is far
+ from the limit; the second is to add or subtract a fixed time when
+ the current dirty page rate is close to the limit.
+
+  - SET PENALTY (3)
+
+ Set the sleep time for each virtual CPU that should be penalized based
+ on the results of the calculation supplied by step CALCULATE (2).
+
+After completing the three above stages, the throttle thread loops back
+to step PREPARE (1) until the dirty limit is reached.
+
+On the other hand, each virtual CPU thread reads the sleep duration and
+sleeps in the path of the KVM_EXIT_DIRTY_RING_RULL exception handler, that
+is ACCEPT PENALTY (4). Virtual CPUs tied with writing processes will
+obviously exit to the path and get penalized, whereas virtual CPUs involved
+with read processes will not.
+
+In summary, thanks to the KVM dirty ring technology, the dirty limit
+algorithm will restrict virtual CPUs as needed to keep their dirty page
+rate inside the limit. This leads to more steady reading performance during
+live migration and can aid in improving large guest responsiveness.
+
 Postcopy
 
 
-- 
2.38.5



Re: [RFC v4 04/11] linux-user: Implement native-bypass option support

2023-08-09 Thread Richard Henderson

On 8/8/23 07:17, Yeqi Fu wrote:

+#define native_bypass_enabled() native_lib_path ? true : false


Need parenthesis for the expression, and possibly better as

(native_lib_path != NULL)

rather than ternary expression.


+#if defined(CONFIG_NATIVE_CALL)
+/* Set the library for native bypass  */
+if (native_lib_path) {
+if (g_file_test(native_lib_path, G_FILE_TEST_EXISTS)) {


G_FILE_TEST_EXISTS may be a directory.
Better with G_FILE_TEST_IS_REGULAR, I guess?


r~



Re: [RFC v4 03/11] linux-user: Implement envlist_appendenv and add tests for envlist

2023-08-09 Thread Richard Henderson

On 8/8/23 07:17, Yeqi Fu wrote:

Signed-off-by: Yeqi Fu 
---
  include/qemu/envlist.h| 13 ++
  tests/unit/meson.build|  1 +
  tests/unit/test-envlist.c | 94 +++
  util/envlist.c| 71 -
  4 files changed, 169 insertions(+), 10 deletions(-)
  create mode 100644 tests/unit/test-envlist.c

diff --git a/include/qemu/envlist.h b/include/qemu/envlist.h
index 6006dfae44..9eb1459e79 100644
--- a/include/qemu/envlist.h
+++ b/include/qemu/envlist.h
@@ -1,12 +1,25 @@
  #ifndef ENVLIST_H
  #define ENVLIST_H
  
+#include "qemu/queue.h"

+
+struct envlist_entry {
+const char *ev_var;/* actual env value */
+QLIST_ENTRY(envlist_entry) ev_link;
+};
+
+struct envlist {
+QLIST_HEAD(, envlist_entry) el_entries; /* actual entries */
+size_t el_count;/* number of entries */
+};
+


Why are you exposing the structures?


+static void envlist_parse_set_unset_test(void)
+{
+envlist_t *testenvlist;
+const char *env = "TEST1=123,TEST2=456";
+
+testenvlist = envlist_create();
+g_assert(envlist_parse_set(testenvlist, env) == 0);
+g_assert(testenvlist->el_count == 2);
+g_assert(envlist_parse_unset(testenvlist, "TEST1,TEST2") == 0);
+g_assert(testenvlist->el_count == 0);


If it's just for the count, then add an envlist_length() function.


r~



Re: [RFC v4 03/11] linux-user: Implement envlist_appendenv and add tests for envlist

2023-08-09 Thread Alex Bennée


Yeqi Fu  writes:

> Signed-off-by: Yeqi Fu 
> ---
>  include/qemu/envlist.h| 13 ++
>  tests/unit/meson.build|  1 +
>  tests/unit/test-envlist.c | 94 +++
>  util/envlist.c| 71 -
>  4 files changed, 169 insertions(+), 10 deletions(-)
>  create mode 100644 tests/unit/test-envlist.c

Thanks for adding the unit test.
>  
> +/*
> + * Appends environment value to envlist. If the environment
> + * variable already exists, the new value is appended to the
> + * existing one.
> + *
> + * Returns 0 in success, errno otherwise.
> + */
> +int
> +envlist_appendenv(envlist_t *envlist, const char *env, const char *separator)
> +{
> +struct envlist_entry *entry = NULL;
> +const char *eq_sign;
> +size_t envname_len;
> +
> +if ((envlist == NULL) || (env == NULL) || (separator == NULL)) {
> +return -EINVAL;
> +}
> +
> +/* find out first equals sign in given env */
> +eq_sign = strchr(env, '=');
> +if (eq_sign == NULL) {
> +return -EINVAL;
> +}
> +
> +if (strchr(eq_sign + 1, '=') != NULL) {
> +return -EINVAL;
> +}
> +
> +envname_len = eq_sign - env + 1;
> +
> +/*
> + * If there already exists variable with given name,
> + * we append the new value to the existing one.
> + */
> +for (entry = envlist->el_entries.lh_first; entry != NULL;
> +entry = entry->ev_link.le_next) {
> +if (strncmp(entry->ev_var, env, envname_len) == 0) {
> +break;
> +}
> +}
> +
> +if (entry != NULL) {
> +char *new_env_value = NULL;
> +size_t new_env_len = strlen(entry->ev_var) + strlen(eq_sign)
> ++ strlen(separator) + 1;
> +new_env_value = g_malloc(new_env_len);
> +strcpy(new_env_value, entry->ev_var);
> +strcat(new_env_value, separator);
> +strcat(new_env_value, eq_sign + 1);
> +g_free((char *)entry->ev_var);
> +entry->ev_var = new_env_value;

You could probably avoid messing about with strlens if you used the
handy glib functions:

if (entry != NULL) {
GString *new_val = g_string_new(entry->ev_var);
g_string_append(new_val, separator);
g_string_append(new_val, eq_sign + 1);
g_free(entry->ev_var);
entry->ev_var = g_string_free(new_val, false);
} else {

Also the fact you needed to cast entry->ev_var to g_free() should have
pointed out that now we can change env entries we need to drop the const
from the char *ev_var; definition in envlist_entry.

Otherwise with those fixes:

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [RFC v4 04/11] linux-user: Implement native-bypass option support

2023-08-09 Thread Alex Bennée


Yeqi Fu  writes:

> This commit implements the -native-bypass support in linux-user. The
> native_calls_enabled() function can be true only when the
> '-native-bypass' option is given.
>
> Signed-off-by: Yeqi Fu 
> ---
>  include/native/native.h |  9 +
>  linux-user/main.c   | 38 ++
>  2 files changed, 47 insertions(+)
>  create mode 100644 include/native/native.h
>
> diff --git a/include/native/native.h b/include/native/native.h
> new file mode 100644
> index 00..62951fafb1
> --- /dev/null
> +++ b/include/native/native.h
> @@ -0,0 +1,9 @@
> +/*
> + * Check if the native bypass feature is enabled.
> + */
> +#if defined(CONFIG_USER_ONLY) && defined(CONFIG_NATIVE_CALL)
> +extern char *native_lib_path;
> +#define native_bypass_enabled() native_lib_path ? true : false
> +#else
> +#define native_bypass_enabled() false
> +#endif
> diff --git a/linux-user/main.c b/linux-user/main.c
> index dba67ffa36..86ea0191f7 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -60,6 +60,11 @@
>  #include "semihosting/semihost.h"
>  #endif
>  
> +#if defined(CONFIG_NATIVE_CALL)
> +#include "native/native.h"
> +char *native_lib_path;
> +#endif
> +
>  #ifndef AT_FLAGS_PRESERVE_ARGV0
>  #define AT_FLAGS_PRESERVE_ARGV0_BIT 0
>  #define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
> @@ -293,6 +298,17 @@ static void handle_arg_set_env(const char *arg)
>  free(r);
>  }
>  
> +#if defined(CONFIG_NATIVE_CALL)
> +static void handle_arg_native_bypass(const char *arg)
> +{
> +if (access(arg, F_OK) != 0) {
> +fprintf(stderr, "native library %s does not exist\n", arg);
> +exit(EXIT_FAILURE);
> +}
> +native_lib_path = strdup(arg);

Although we never free this the coding style states:

  Because of the memory management rules, you must use g_strdup/g_strndup
  instead of plain strdup/strndup.

We do still have a few legacy strdup's to eliminate from the code base
though.

> +}
> +#endif
> +
>  static void handle_arg_unset_env(const char *arg)
>  {
>  char *r, *p, *token;
> @@ -522,6 +538,10 @@ static const struct qemu_argument arg_table[] = {
>   "",   "Generate a /tmp/perf-${pid}.map file for perf"},
>  {"jitdump","QEMU_JITDUMP", false, handle_arg_jitdump,
>   "",   "Generate a jit-${pid}.dump file for perf"},
> +#if defined(CONFIG_NATIVE_CALL)
> +{"native-bypass", "QEMU_NATIVE_BYPASS", true, handle_arg_native_bypass,
> + "",   "native bypass for library calls in user mode only."},
> +#endif

You can drop " in user mode only" because this help text will only show
up on linux-user binaries with support for native bypass.

Otherwise:

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: Fix interval_tree_iter_first() to check root node value

2023-08-09 Thread Helge Deller

On 8/9/23 17:23, Richard Henderson wrote:

On 8/9/23 08:11, Helge Deller wrote:

Fix a crash in qemu-user when running

 cat /proc/self/maps

in a chroot, where /proc isn't mounted.

The problem was introduced by commit 3ce3dd8ca965 ("util/selfmap:
Rewrite using qemu/interval-tree.h") where in open_self_maps_1() the
function read_self_maps() is called and which returns NULL if it can't
read the hosts /proc/self/maps file. Afterwards that NULL is fed into
interval_tree_iter_first() which doesn't check if the root node is NULL.

Fix it by adding a check if root is NULL and return NULL in that case.

Signed-off-by: Helge Deller 
Fixes: 3ce3dd8ca965 ("util/selfmap: Rewrite using qemu/interval-tree.h")

diff --git a/util/interval-tree.c b/util/interval-tree.c
index f2866aa7d3..53465182e6 100644
--- a/util/interval-tree.c
+++ b/util/interval-tree.c
@@ -797,7 +797,7 @@ IntervalTreeNode *interval_tree_iter_first(IntervalTreeRoot 
*root,
  {
  IntervalTreeNode *node, *leftmost;

-    if (!root->rb_root.rb_node) {
+    if (!root || !root->rb_root.rb_node) {



I guess this is good enough for 8.1.  Before the conversion to interval-tree we 
would also emit nothing.


Yes and yes.


I've already done a rewrite for 8.2, and I noticed this problem.
There I emit what mapping information that I have, which is
everything except for the device+path data.


nice.


Reviewed-by: Richard Henderson 


Shall I send a pull request?
If so, is it OK that I include this patch in the pull-request as well?
  linux-user: Fix openat() emulation to correctly detect accesses to /proc
  https://lists.nongnu.org/archive/html/qemu-devel/2023-08/msg00165.html
which already has been R-b: Daniel P. Berrangé

Helge



Re: [RFC v4 03/11] linux-user: Implement envlist_appendenv and add tests for envlist

2023-08-09 Thread Richard Henderson

On 8/8/23 07:17, Yeqi Fu wrote:

+char *new_env_value = NULL;
+size_t new_env_len = strlen(entry->ev_var) + strlen(eq_sign)
++ strlen(separator) + 1;
+new_env_value = g_malloc(new_env_len);
+strcpy(new_env_value, entry->ev_var);
+strcat(new_env_value, separator);
+strcat(new_env_value, eq_sign + 1);


This is

new_env_value = g_strconcat(entry->ev_var, separator, eq_sign + 1, 
NULL);


r~



Re: [RFC v4 02/11] build: Implement libnative library and the build machinery for libnative

2023-08-09 Thread Richard Henderson

On 8/8/23 07:17, Yeqi Fu wrote:

+#if defined(i386) || defined(x86_64)
+/*
+ * An unused instruction is utilized to mark a native call.
+ */
+#define __CALL_EXPR ".byte 0x0f, 0xff;"
+#endif


This is 2 of the 3 (or more) bytes of the UD0 instruction.
At minimum you should include a third byte for the modrm.

For example,

0F FF C0ud0 %eax, %eax

If you want to encode more data, or simply magic numbers, you can use

0F FF 80
78 56 34 12 ud0 0x12345678(%eax), %eax

or with modrm + sib bytes,

0F FF 84 00
78 56 34 12 ud0 0x12345678(%eax, %eax, 0), %eax

So you have up to 32 (displacement) + 3 * 3 (registers) + 2 (shift) = 43 bits that you can 
vary while staying within the encoding of UD0.


You can even have the assembler help encode a displacement to associated data:

.text
0:  ud0 label-0b(%eax), %eax
.rodata
label:  .byte   some stuff


r~



Re: [RFC v4 05/11] linux-user/elfload: Add support for parsing symbols of native libraries.

2023-08-09 Thread Richard Henderson

On 8/8/23 07:17, Yeqi Fu wrote:

This commit addresses the need to parse symbols of native libraries.
The base address of a shared library is determined by the dynamic
linker. To simplify the process, we focus on the last three digits,
which reside within the same page and remain unaffected by the base
address.

Signed-off-by: Yeqi Fu
---
  linux-user/elfload.c | 85 +---
  1 file changed, 80 insertions(+), 5 deletions(-)


I'm not keen on this.  I would much prefer the native library to be self-contained and not 
rely on symbols in this fashion.



r~



Re: Fix interval_tree_iter_first() to check root node value

2023-08-09 Thread Richard Henderson

On 8/9/23 08:53, Helge Deller wrote:

On 8/9/23 17:23, Richard Henderson wrote:

On 8/9/23 08:11, Helge Deller wrote:

Fix a crash in qemu-user when running

 cat /proc/self/maps

in a chroot, where /proc isn't mounted.

The problem was introduced by commit 3ce3dd8ca965 ("util/selfmap:
Rewrite using qemu/interval-tree.h") where in open_self_maps_1() the
function read_self_maps() is called and which returns NULL if it can't
read the hosts /proc/self/maps file. Afterwards that NULL is fed into
interval_tree_iter_first() which doesn't check if the root node is NULL.

Fix it by adding a check if root is NULL and return NULL in that case.

Signed-off-by: Helge Deller 
Fixes: 3ce3dd8ca965 ("util/selfmap: Rewrite using qemu/interval-tree.h")

diff --git a/util/interval-tree.c b/util/interval-tree.c
index f2866aa7d3..53465182e6 100644
--- a/util/interval-tree.c
+++ b/util/interval-tree.c
@@ -797,7 +797,7 @@ IntervalTreeNode *interval_tree_iter_first(IntervalTreeRoot 
*root,
  {
  IntervalTreeNode *node, *leftmost;

-    if (!root->rb_root.rb_node) {
+    if (!root || !root->rb_root.rb_node) {



I guess this is good enough for 8.1.  Before the conversion to interval-tree we would 
also emit nothing.


Yes and yes.


I've already done a rewrite for 8.2, and I noticed this problem.
There I emit what mapping information that I have, which is
everything except for the device+path data.


nice.


Reviewed-by: Richard Henderson 


Shall I send a pull request?
If so, is it OK that I include this patch in the pull-request as well?
   linux-user: Fix openat() emulation to correctly detect accesses to /proc
   https://lists.nongnu.org/archive/html/qemu-devel/2023-08/msg00165.html
which already has been R-b: Daniel P. Berrangé


I can pick them both up -- I have other linux-user patches to send.


r~




Re: [RFC v4 07/11] target/i386: Add support for native library calls

2023-08-09 Thread Richard Henderson

On 8/8/23 07:17, Yeqi Fu wrote:

This commit introduces support for native library calls on the
i386 target. When special instructions reserved for native calls
are encountered, the code now performs address translation and
generates the corresponding native call.

Signed-off-by: Yeqi Fu 
---
  configs/targets/i386-linux-user.mak   |  1 +
  configs/targets/x86_64-linux-user.mak |  1 +
  target/i386/tcg/translate.c   | 27 +++
  3 files changed, 29 insertions(+)

diff --git a/configs/targets/i386-linux-user.mak 
b/configs/targets/i386-linux-user.mak
index 5b2546a430..2d8bca8f93 100644
--- a/configs/targets/i386-linux-user.mak
+++ b/configs/targets/i386-linux-user.mak
@@ -2,3 +2,4 @@ TARGET_ARCH=i386
  TARGET_SYSTBL_ABI=i386
  TARGET_SYSTBL=syscall_32.tbl
  TARGET_XML_FILES= gdb-xml/i386-32bit.xml
+CONFIG_NATIVE_CALL=y
diff --git a/configs/targets/x86_64-linux-user.mak 
b/configs/targets/x86_64-linux-user.mak
index 9ceefbb615..a53b017454 100644
--- a/configs/targets/x86_64-linux-user.mak
+++ b/configs/targets/x86_64-linux-user.mak
@@ -3,3 +3,4 @@ TARGET_BASE_ARCH=i386
  TARGET_SYSTBL_ABI=common,64
  TARGET_SYSTBL=syscall_64.tbl
  TARGET_XML_FILES= gdb-xml/i386-64bit.xml
+CONFIG_NATIVE_CALL=y
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 90c7b32f36..28bf4477fb 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -33,6 +33,7 @@
  #include "helper-tcg.h"
  
  #include "exec/log.h"

+#include "native/native.h"
  
  #define HELPER_H "helper.h"

  #include "exec/helper-info.c.inc"
@@ -6810,6 +6811,32 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
  case 0x1d0 ... 0x1fe:
  disas_insn_new(s, cpu, b);
  break;
+case 0x1ff:
+if (native_bypass_enabled()) {
+TCGv ret = tcg_temp_new();
+TCGv arg1 = tcg_temp_new();
+TCGv arg2 = tcg_temp_new();
+TCGv arg3 = tcg_temp_new();
+const char *fun_name = lookup_symbol((s->base.pc_next) & 0xfff);


I'm not keen on this lookup_symbol interface.
I would much rather there be some data encoded in the native.so.



+uintptr_t ra = GETPC();
+uint32_t a1 = cpu_ldl_data_ra(env, env->regs[R_ESP] + 4, ra);
+uint32_t a2 = cpu_ldl_data_ra(env, env->regs[R_ESP] + 8, ra);
+uint32_t a3 = cpu_ldl_data_ra(env, env->regs[R_ESP] + 12, ra);
+tcg_gen_movi_tl(arg1, a1);
+tcg_gen_movi_tl(arg2, a2);
+tcg_gen_movi_tl(arg3, a3);


This is wrong.  You are performing the stack load at translation time, but it must be done 
at execution time.  You need


tcg_gen_addi_tl(arg1, cpu_regs[R_ESP], 4);  /* arg1 = esp + 4 */
gen_op_ld_v(s, MO_UL, arg1, arg1);  /* arg1 = *arg1 */

etc.


r~



Re: [PATCH for-8.2] dockerfiles: bump tricore cross compiler container to Debian 11

2023-08-09 Thread Bastian Koppelmann
On Wed, Aug 09, 2023 at 04:33:37PM +0200, Paolo Bonzini wrote:
> On Wed, Aug 9, 2023 at 3:53 PM Bastian Koppelmann
>  wrote:
> > > diff --git a/tests/docker/dockerfiles/debian-tricore-cross.docker 
> > > b/tests/docker/dockerfiles/debian-tricore-cross.docker
> > > index 269bfa8d423..5bd1963fb55 100644
> > > --- a/tests/docker/dockerfiles/debian-tricore-cross.docker
> > > +++ b/tests/docker/dockerfiles/debian-tricore-cross.docker
> > > @@ -9,7 +9,7 @@
> > >  #
> > >  # SPDX-License-Identifier: GPL-2.0-or-later
> > >  #
> > > -FROM docker.io/library/debian:buster-slim
> > > +FROM docker.io/library/debian:11-slim
> >
> > I think it would be better to skip debian-11 and use 12 instead.
> 
> I picked 11 in order to keep the container in sync with the
> lcitool-generated dockerfiles. Once we switch lcitool from 11 to
> 12, it is easier to see what the changes are and replicate them in
> debian-tricore-cross and friends.
> 
> lcitool support for Debian 12 has already landed, but usually we
> try to keep the containers on the oldest supported release of a
> distro, and that is currently Debian 11.

Thanks for the explanation.

Acked-by: Bastian Koppelmann 

Cheers,
Bastian



Re: [RFC v1 0/3] Initial support for SPDM

2023-08-09 Thread Alistair Francis
On Wed, Aug 9, 2023 at 8:11 AM Jonathan Cameron
 wrote:
>
> On Tue,  8 Aug 2023 11:51:21 -0400
> Alistair Francis  wrote:
>
> > The Security Protocol and Data Model (SPDM) Specification defines
> > messages, data objects, and sequences for performing message exchanges
> > over a variety of transport and physical media.
> >  - 
> > https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.3.0.pdf
> >
> > This series is a very initial start on adding SPDM support to QEMU.
> >
> > This series uses libspdm [1] which is a reference implementation of
> > SPDM.
> >
> > The series starts by adding support for building and linking with
> > libspdm. It then progresses to handling SPDM requests in the NVMe device
> > over the PCIe DOE protocol.
> >
> > This is a very early attempt. The code quality is not super high, the C
> > code hasn't been tested at all. This is really just an RFC to see if
> > QEMU will accept linking with libspdm.
> >
> > So, the main question is, how do people feel about linking with libspdm
> > to support SPDM?
> >
> > 1: https://github.com/DMTF/libspdm
>
> Hi Alastair,
>
> For reference / background we've had SPDM support for CXL emulated devices
> in our staging tree for quite a while - it's not upstream because of
> exactly this question (+ no one had upstreaming this as a high priority
> as out of tree was fine for developing the kernel stack - it's well
> isolated in the code so there was little cost in rebasing this feature)
> - and because libspdm is packaged by almost no one. There were problems
> building it with external crypto libraries etc.

Thanks for pointing that out! I didn't realise there was existing QEMU
work. I'm glad others are looking into it

Building with libspdm is difficult. Even this series does have weird
issues with openssl's crypto library. I have been working towards
packaging libspdm into buildroot, which has helped cleanup libspdm to
be more user friendly. libspdm 3.0 for example is now a lot easier to
build/package, but I expect to continue to improve things.

There will need to be more improvements to libspdm before this series
could be merged.

>
> Looks like you have had a lot more success than I ever did in getting that
> to work. I tried a few times in the past and ended up sticking with
> the Avery design folks approach of a socket connection to spdm-emu
> Given you cc'd them I'm guessing you came across that work which is what
> we used for testing the kernel code Lukas is working on currently.
>
> https://lore.kernel.org/qemu-devel/20210629132520.0...@huawei.com/
>
> https://gitlab.com/jic23/qemu/-/commit/9864fb29979e55c1e37c20edf00907d9524036e8

Thanks for that!

In the past the QEMU community has refused to accept upstream changes
that expose QEMU internals via sockets. So I suspect linking with
libspdm will be a more upstreamable approach.

On top of that requiring user to run an external socket application is clunky.

>
> So I think we have 2 choices here.
> 1) Do what you have done and build the library as you are doing.
>  - Can fix a version - so don't care if they change the ABI etc other
>than needing to move the version QEMU uses forwards when we need
>to for new features.

I agree

>  - Cert management is going to add a lot of complexity into QEMU.
>I've not looked at how much infrastructure we can reuse from elsewhere.
>Maybe this is a solved problem.

Could we not just point to a cert when running QEMU?

>
> 2) Keep the SPDM emulation external.
>  - I'm not sure the socket protocol used by spdm-emu is fixed in stone
>as people tend to change both ends.
>  - Cert management and protocol options etc are already available.

I suspect this will never get upstream though. My aim is to get
something upstream, so this is probably a no go (unless someone jumps
in and says this is ok).

>
> Personally I prefer the control option 1 gives us, even if it's a lot more
> code.  Option 2 also rather limits our ability to do anything with
> the encrypted data as well. It's fine if the aim is just verification
> of simple flows, but if we need to inject particular measurements etc
> it doesn't really work.

I like option 1 as well :)

I don't envisage QEMU supporting extremely complex flows. I was more
aiming for a certificate and some measurement data and maybe a
manifest. My hope was basic SPDM support, not a complete test suite.

Alistair

>
> Jonathan
>
>
>
> >
> > Alistair Francis (3):
> >   subprojects: libspdm: Initial support
> >   hw: nvme: ctrl: Initial support for DOE
> >   hw: nvme: ctrl: Process SPDM requests
> >
> >  meson.build   | 78 +++
> >  hw/nvme/nvme.h|  4 ++
> >  include/hw/pci/pcie_doe.h |  1 +
> >  hw/nvme/ctrl.c| 35 
> >  .gitmodules   |  3 ++
> >  meson_options.txt |  3 ++
> >  scripts/meson-buildoptions.sh |  3 ++
> >  subprojects/.gitignore|  1 +
> >  subpro

  1   2   >