Re: [PATCH v8 2/4] target/riscv: implement Zicboz extension

2023-02-24 Thread liweiwei



On 2023/2/24 21:25, Daniel Henrique Barboza wrote:

From: Christoph Muellner 

The RISC-V base cache management operation (CBO) ISA extension has been
ratified. It defines three extensions: Cache-Block Management, Cache-Block
Prefetch and Cache-Block Zero. More information about the spec can be
found at [1].

Let's start by implementing the Cache-Block Zero extension, Zicboz. It
uses the cbo.zero instruction that, as with all CBO instructions that
will be added later, needs to be implemented in an overlap group with
the LQ instruction due to overlapping patterns.

cbo.zero throws a Illegal Instruction/Virtual Instruction exception
depending on CSR state. This is also the case for the remaining cbo
instructions we're going to add next, so create a check_zicbo_envcfg()
that will be used by all Zicbo[mz] instructions.

[1] 
https://github.com/riscv/riscv-CMOs/blob/master/specifications/cmobase-v1.0.1.pdf

Reviewed-by: Richard Henderson 
Co-developed-by: Philipp Tomsich 
Signed-off-by: Christoph Muellner 
Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Weiwei Li 

Weiwei Li

---
  target/riscv/cpu.c  |  4 ++
  target/riscv/cpu.h  |  2 +
  target/riscv/helper.h   |  3 +
  target/riscv/insn32.decode  | 10 ++-
  target/riscv/insn_trans/trans_rvzicbo.c.inc | 30 +
  target/riscv/op_helper.c| 68 +
  target/riscv/translate.c|  1 +
  7 files changed, 117 insertions(+), 1 deletion(-)
  create mode 100644 target/riscv/insn_trans/trans_rvzicbo.c.inc

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 93b52b826c..7dd37de7f9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -74,6 +74,7 @@ struct isa_ext_data {
  static const struct isa_ext_data isa_edata_arr[] = {
  ISA_EXT_DATA_ENTRY(h, false, PRIV_VERSION_1_12_0, ext_h),
  ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_10_0, ext_v),
+ISA_EXT_DATA_ENTRY(zicboz, true, PRIV_VERSION_1_12_0, ext_icboz),
  ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
  ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
  ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, 
ext_zihintpause),
@@ -1126,6 +1127,9 @@ static Property riscv_cpu_extensions[] = {
  DEFINE_PROP_BOOL("zhinx", RISCVCPU, cfg.ext_zhinx, false),
  DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
  
+DEFINE_PROP_BOOL("zicboz", RISCVCPU, cfg.ext_icboz, true),

+DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
+
  DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
  
  /* Vendor-specific custom extensions */

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7128438d8e..6b4c714d3a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -447,6 +447,7 @@ struct RISCVCPUConfig {
  bool ext_zkt;
  bool ext_ifencei;
  bool ext_icsr;
+bool ext_icboz;
  bool ext_zihintpause;
  bool ext_smstateen;
  bool ext_sstc;
@@ -494,6 +495,7 @@ struct RISCVCPUConfig {
  char *vext_spec;
  uint16_t vlen;
  uint16_t elen;
+uint16_t cboz_blocksize;
  bool mmu;
  bool pmp;
  bool epmp;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 0497370afd..ce165821b8 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -97,6 +97,9 @@ DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl)
  DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
  DEF_HELPER_FLAGS_2(fclass_h, TCG_CALL_NO_RWG_SE, tl, env, i64)
  
+/* Cache-block operations */

+DEF_HELPER_2(cbo_zero, void, env, tl)
+
  /* Special functions */
  DEF_HELPER_2(csrr, tl, env, int)
  DEF_HELPER_3(csrw, void, env, int, tl)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b7e7613ea2..3985bc703f 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -179,7 +179,15 @@ sraw 010 .  . 101 . 0111011 @r
  
  # *** RV128I Base Instruction Set (in addition to RV64I) ***

  ldu     . 111 . 011 @i
-lq      . 010 . 000 @i
+{
+  [
+# *** RV32 Zicboz Standard Extension ***
+cbo_zero   000 00100 . 010 0 000 @sfence_vm
+  ]
+
+  # *** RVI128 lq ***
+  lq      . 010 . 000 @i
+}
  sq      . 100 . 0100011 @s
  addid  .  000 . 1011011 @i
  sllid00 ..  . 001 . 1011011 @sh6
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc 
b/target/riscv/insn_trans/trans_rvzicbo.c.inc
new file mode 100644
index 00..feabc28342
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
@@ -0,0 +1,30 @@
+/*
+ * RISC-V translation routines for the RISC-V CBO Extension.
+ *
+ * Copyright (c) 2021 Philipp Tomsich, philipp.toms...@vrull.eu
+ *
+ * This program is free 

Re: [PATCH 0/4] RISCVCPUConfig related cleanups

2023-02-24 Thread liweiwei



On 2023/2/25 01:45, Daniel Henrique Barboza wrote:

Hi,

These cleanups were suggested by LIU Zhiwei during the review of the
RISCV_FEATURE_* cleanups, currently on version 7 [1].

These are dependent on the patch "[PATCH v7 01/10] target/riscv: introduce
riscv_cpu_cfg()" from [1] because we use the riscv_cpu_cfg() API.


[1] https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg06467.html

Daniel Henrique Barboza (4):
   target/riscv/csr.c: use env_archcpu() in ctr()
   target/riscv/csr.c: simplify mctr()
   target/riscv/csr.c: use riscv_cpu_cfg() to avoid env_cpu() pointers
   target/riscv/csr.c: avoid env_archcpu() usages when reading
 RISCVCPUConfig

  target/riscv/csr.c | 90 +-
  1 file changed, 24 insertions(+), 66 deletions(-)

As  I suggested in another patch, cpu_get_cfg() can also be used in 
vector_helper.c.


Regards,

Weiwei Li




Re: [PATCH 4/4] target/riscv/csr.c: avoid env_archcpu() usages when reading RISCVCPUConfig

2023-02-24 Thread liweiwei



On 2023/2/25 01:45, Daniel Henrique Barboza wrote:

Retrieving the CPU pointer using env_archcpu() just to access cpu->cfg
can be avoided by using riscv_cpu_cfg().

Suggested-by: LIU Zhiwei 
Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Weiwei Li 

Weiwei Li

---
  target/riscv/csr.c | 32 +---
  1 file changed, 9 insertions(+), 23 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 53f1a331f9..ffa2d7b606 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -213,9 +213,7 @@ static RISCVException any32(CPURISCVState *env, int csrno)
  
  static int aia_any(CPURISCVState *env, int csrno)

  {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_smaia) {
+if (!riscv_cpu_cfg(env)->ext_smaia) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -224,9 +222,7 @@ static int aia_any(CPURISCVState *env, int csrno)
  
  static int aia_any32(CPURISCVState *env, int csrno)

  {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_smaia) {
+if (!riscv_cpu_cfg(env)->ext_smaia) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -253,9 +249,7 @@ static int smode32(CPURISCVState *env, int csrno)
  
  static int aia_smode(CPURISCVState *env, int csrno)

  {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_ssaia) {
+if (!riscv_cpu_cfg(env)->ext_ssaia) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -264,9 +258,7 @@ static int aia_smode(CPURISCVState *env, int csrno)
  
  static int aia_smode32(CPURISCVState *env, int csrno)

  {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_ssaia) {
+if (!riscv_cpu_cfg(env)->ext_ssaia) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -380,9 +372,7 @@ static RISCVException pointer_masking(CPURISCVState *env, int csrno)
  
  static int aia_hmode(CPURISCVState *env, int csrno)

  {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_ssaia) {
+if (!riscv_cpu_cfg(env)->ext_ssaia) {
  return RISCV_EXCP_ILLEGAL_INST;
   }
  
@@ -391,9 +381,7 @@ static int aia_hmode(CPURISCVState *env, int csrno)
  
  static int aia_hmode32(CPURISCVState *env, int csrno)

  {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_ssaia) {
+if (!riscv_cpu_cfg(env)->ext_ssaia) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -430,9 +418,7 @@ static RISCVException debug(CPURISCVState *env, int csrno)
  
  static RISCVException seed(CPURISCVState *env, int csrno)

  {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_zkr) {
+if (!riscv_cpu_cfg(env)->ext_zkr) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -555,7 +541,7 @@ static RISCVException read_vl(CPURISCVState *env, int csrno,
  
  static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)

  {
-*val = env_archcpu(env)->cfg.vlen >> 3;
+*val = riscv_cpu_cfg(env)->vlen >> 3;
  return RISCV_EXCP_NONE;
  }
  
@@ -610,7 +596,7 @@ static RISCVException write_vstart(CPURISCVState *env, int csrno,

   * The vstart CSR is defined to have only enough writable bits
   * to hold the largest element index, i.e. lg2(VLEN) bits.
   */
-env->vstart = val & ~(~0ULL << ctzl(env_archcpu(env)->cfg.vlen));
+env->vstart = val & ~(~0ULL << ctzl(riscv_cpu_cfg(env)->vlen));
  return RISCV_EXCP_NONE;
  }
  





Re: [PATCH 3/4] target/riscv/csr.c: use riscv_cpu_cfg() to avoid env_cpu() pointers

2023-02-24 Thread liweiwei



On 2023/2/25 01:45, Daniel Henrique Barboza wrote:

A common trend in this file is to retrieve a RISCVCPU pointer by first
retrieving a CPUState pointer via env_cpu(). The CPU pointer is used
only to access the RISCVCPUConfig object and nothing else.

Let's use riscv_cpu_cfg() to access what we need directly without these
2 pointers.

Suggested-by: LIU Zhiwei 
Signed-off-by: Daniel Henrique Barboza 
---

Reviewed-by: Weiwei Li 

Weiwei Li

  target/riscv/csr.c | 50 +++---
  1 file changed, 12 insertions(+), 38 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0f4aa22a0f..53f1a331f9 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -46,10 +46,8 @@ static RISCVException smstateen_acc_ok(CPURISCVState *env, 
int index,
 uint64_t bit)
  {
  bool virt = riscv_cpu_virt_enabled(env);
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
  
-if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {

+if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
  return RISCV_EXCP_NONE;
  }
  
@@ -81,7 +79,7 @@ static RISCVException fs(CPURISCVState *env, int csrno)

  {
  #if !defined(CONFIG_USER_ONLY)
  if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
-!RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
+!riscv_cpu_cfg(env)->ext_zfinx) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  #endif
@@ -90,11 +88,9 @@ static RISCVException fs(CPURISCVState *env, int csrno)
  
  static RISCVException vs(CPURISCVState *env, int csrno)

  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
  if (env->misa_ext & RVV ||
-cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
+riscv_cpu_cfg(env)->ext_zve32f ||
+riscv_cpu_cfg(env)->ext_zve64f) {
  #if !defined(CONFIG_USER_ONLY)
  if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
  return RISCV_EXCP_ILLEGAL_INST;
@@ -193,10 +189,7 @@ static RISCVException mctr32(CPURISCVState *env, int csrno)
  
  static RISCVException sscofpmf(CPURISCVState *env, int csrno)

  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-if (!cpu->cfg.ext_sscofpmf) {
+if (!riscv_cpu_cfg(env)->ext_sscofpmf) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -319,10 +312,7 @@ static RISCVException umode32(CPURISCVState *env, int csrno)
  
  static RISCVException mstateen(CPURISCVState *env, int csrno)

  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-if (!cpu->cfg.ext_smstateen) {
+if (!riscv_cpu_cfg(env)->ext_smstateen) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -331,10 +321,7 @@ static RISCVException mstateen(CPURISCVState *env, int csrno)
  
  static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)

  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-if (!cpu->cfg.ext_smstateen) {
+if (!riscv_cpu_cfg(env)->ext_smstateen) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -361,10 +348,8 @@ static RISCVException sstateen(CPURISCVState *env, int csrno)

  {
  bool virt = riscv_cpu_virt_enabled(env);
  int index = csrno - CSR_SSTATEEN0;
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
  
-if (!cpu->cfg.ext_smstateen) {

+if (!riscv_cpu_cfg(env)->ext_smstateen) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -916,11 +901,9 @@ static RISCVException read_timeh(CPURISCVState *env, int csrno,
  
  static RISCVException sstc(CPURISCVState *env, int csrno)

  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
  bool hmode_check = false;
  
-if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {

+if (!riscv_cpu_cfg(env)->ext_sstc || !env->rdtime_fn) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -1150,30 +1133,21 @@ static RISCVException write_ignore(CPURISCVState *env, int csrno,

  static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
   target_ulong *val)
  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-*val = cpu->cfg.mvendorid;
+*val = riscv_cpu_cfg(env)->mvendorid;
  return RISCV_EXCP_NONE;
  }
  
  static RISCVException read_marchid(CPURISCVState *env, int csrno,

 target_ulong *val)
  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-*val = cpu->cfg.marchid;
+*val = riscv_cpu_cfg(env)->marchid;
  return RISCV_EXCP_NONE;
  }
  
  static RISCVException read_mimpid(CPURISCVState *env, int csrno,

target_ulong *val)
  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-*val = cpu->cfg.mimpid;
+*val = riscv_cpu_cfg(env)->mimpid;
  return RISCV_EXCP_NONE;
  }
  





Re: [PATCH 2/4] target/riscv/csr.c: simplify mctr()

2023-02-24 Thread liweiwei



On 2023/2/25 01:45, Daniel Henrique Barboza wrote:

Use riscv_cpu_cfg() to retrieve pmu_num.

Signed-off-by: Daniel Henrique Barboza 
---

Reviewed-by: Weiwei Li 

Weiwei Li

  target/riscv/csr.c | 5 ++---
  1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 3692617d13..0f4aa22a0f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -165,8 +165,7 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
  #if !defined(CONFIG_USER_ONLY)
  static RISCVException mctr(CPURISCVState *env, int csrno)
  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+int pmu_num = riscv_cpu_cfg(env)->pmu_num;
  int ctr_index;
  int base_csrno = CSR_MHPMCOUNTER3;
  
@@ -175,7 +174,7 @@ static RISCVException mctr(CPURISCVState *env, int csrno)

  base_csrno += 0x80;
  }
  ctr_index = csrno - base_csrno;
-if (!cpu->cfg.pmu_num || ctr_index >= cpu->cfg.pmu_num) {
+if (!pmu_num || ctr_index >= pmu_num) {
  /* The PMU is not enabled or counter is out of range*/
  return RISCV_EXCP_ILLEGAL_INST;
  }





Re: [PATCH 1/4] target/riscv/csr.c: use env_archcpu() in ctr()

2023-02-24 Thread liweiwei



On 2023/2/25 01:45, Daniel Henrique Barboza wrote:

We don't need to use env_cpu() and CPUState().

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/csr.c | 3 +--
  1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 75a540bfcb..3692617d13 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -108,8 +108,7 @@ static RISCVException vs(CPURISCVState *env, int csrno)
  static RISCVException ctr(CPURISCVState *env, int csrno)
  {
  #if !defined(CONFIG_USER_ONLY)
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  int ctr_index;
  target_ulong ctr_mask;
  int base_csrno = CSR_CYCLE;


This has been done by previous patchset from Bin Meng:

https://lists.nongnu.org/archive/html/qemu-riscv/2023-02/msg00276.html

Regards,

Weiwei Li




[PATCH v3 2/3] hw/arm: Validate cluster and NUMA node boundary

2023-02-24 Thread Gavin Shan
There are two ARM machines where NUMA is aware: 'virt' and 'sbsa-ref'.
Both of them are required to follow cluster-NUMA-node boundary. To
enable the validation to warn about the irregular configuration where
multiple CPUs in one cluster have been associated with different NUMA
nodes.

Signed-off-by: Gavin Shan 
---
 hw/arm/sbsa-ref.c | 2 ++
 hw/arm/virt.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index f778cb6d09..91d38af94c 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -864,6 +864,8 @@ static void sbsa_ref_class_init(ObjectClass *oc, void *data)
 mc->possible_cpu_arch_ids = sbsa_ref_possible_cpu_arch_ids;
 mc->cpu_index_to_instance_props = sbsa_ref_cpu_index_to_props;
 mc->get_default_cpu_node_id = sbsa_ref_get_default_cpu_node_id;
+/* platform instead of architectural choice */
+mc->cpu_cluster_has_numa_boundary = true;
 }
 
 static const TypeInfo sbsa_ref_info = {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index ac626b3bef..b73ac6eabb 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3030,6 +3030,8 @@ static void virt_machine_class_init(ObjectClass *oc, void 
*data)
 mc->smp_props.clusters_supported = true;
 mc->auto_enable_numa_with_memhp = true;
 mc->auto_enable_numa_with_memdev = true;
+/* platform instead of architectural choice */
+mc->cpu_cluster_has_numa_boundary = true;
 mc->default_ram_id = "mach-virt.ram";
 
 object_class_property_add(oc, "acpi", "OnOffAuto",
-- 
2.23.0




[PATCH v3 3/3] hw/riscv: Validate cluster and NUMA node boundary

2023-02-24 Thread Gavin Shan
There are two RISCV machines where NUMA is aware: 'virt' and 'spike'.
Both of them are required to follow cluster-NUMA-node boundary. To
enable the validation to warn about the irregular configuration where
multiple CPUs in one cluster has been associated with multiple NUMA
nodes.

Signed-off-by: Gavin Shan 
---
 hw/riscv/spike.c | 2 ++
 hw/riscv/virt.c  | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index cc3f6dac17..b09b993634 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -357,6 +357,8 @@ static void spike_machine_class_init(ObjectClass *oc, void 
*data)
 mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
 mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
 mc->numa_mem_supported = true;
+/* platform instead of architectural choice */
+mc->cpu_cluster_has_numa_boundary = true;
 mc->default_ram_id = "riscv.spike.ram";
 }
 
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index b81081c70b..e5bb168169 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1636,6 +1636,8 @@ static void virt_machine_class_init(ObjectClass *oc, void 
*data)
 mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
 mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
 mc->numa_mem_supported = true;
+/* platform instead of architectural choice */
+mc->cpu_cluster_has_numa_boundary = true;
 mc->default_ram_id = "riscv_virt_board.ram";
 assert(!mc->get_hotplug_handler);
 mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
-- 
2.23.0




[PATCH v3 0/3] NUMA: Apply cluster-NUMA-node boundary for aarch64 and riscv machines

2023-02-24 Thread Gavin Shan
For arm64 and riscv architecture, the driver (/base/arch_topology.c) is
used to populate the CPU topology in the Linux guest. It's required that
the CPUs in one cluster can't span mutiple NUMA nodes. Otherwise, the Linux
scheduling domain can't be sorted out, as the following warning message
indicates. To avoid the unexpected confusion, this series attempts to
warn about such kind of irregular configurations.

   -smp 6,maxcpus=6,sockets=2,clusters=1,cores=3,threads=1 \
   -numa node,nodeid=0,cpus=0-1,memdev=ram0\
   -numa node,nodeid=1,cpus=2-3,memdev=ram1\
   -numa node,nodeid=2,cpus=4-5,memdev=ram2\

   [ cut here ]
   WARNING: CPU: 0 PID: 1 at kernel/sched/topology.c:2271 
build_sched_domains+0x284/0x910
   Modules linked in:
   CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.14.0-268.el9.aarch64 #1
   pstate: 0045 (nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
   pc : build_sched_domains+0x284/0x910
   lr : build_sched_domains+0x184/0x910
   sp : 8804bd50
   x29: 8804bd50 x28: 0002 x27: 
   x26: 89cf9a80 x25:  x24: 89cbf840
   x23: 80325000 x22: 005df800 x21: 8a4ce508
   x20:  x19: 80324440 x18: 0014
   x17: 388925c0 x16: 5386a066 x15: 9c10cc2e
   x14: 01c0 x13: 0001 x12: 7fffb1a0
   x11: 7fffb180 x10: 8a4ce508 x9 : 0041
   x8 : 8a4ce500 x7 : 8a4cf920 x6 : 0001
   x5 : 0001 x4 : 0007 x3 : 0002
   x2 : 1000 x1 : 8a4cf928 x0 : 0001
   Call trace:
build_sched_domains+0x284/0x910
sched_init_domains+0xac/0xe0
sched_init_smp+0x48/0xc8
kernel_init_freeable+0x140/0x1ac
kernel_init+0x28/0x140
ret_from_fork+0x10/0x20

PATCH[1] Warn about the irregular configuration if required
PATCH[2] Enable the validation for aarch64 machines
PATCH[3] Enable the validation for riscv machines

v2: https://lists.nongnu.org/archive/html/qemu-arm/2023-02/msg01080.html
v1: https://lists.nongnu.org/archive/html/qemu-arm/2023-02/msg00886.html

Changelog
=
v3:
  * Validate cluster-to-NUMA instead of socket-to-NUMA
boundary  (Gavin)
  * Move the switch from MachineState to MachineClass (Philippe)
  * Warning instead of rejecting the irregular configuration  (Daniel)
  * Comments to mention cluster-to-NUMA is platform instead
of architectural choice   (Drew)
  * Drop PATCH[v2 1/4] related to qtests/numa-test(Gavin)
v2:
  * Fix socket-NUMA-node boundary issues in qtests/numa-test  (Gavin)
  * Add helper set_numa_socket_boundary() and validate the
boundary in the generic path  (Philippe)

Gavin Shan (3):
  numa: Validate cluster and NUMA node boundary if required
  hw/arm: Validate cluster and NUMA node boundary
  hw/riscv: Validate cluster and NUMA node boundary

 hw/arm/sbsa-ref.c   |  2 ++
 hw/arm/virt.c   |  2 ++
 hw/core/machine.c   | 42 ++
 hw/riscv/spike.c|  2 ++
 hw/riscv/virt.c |  2 ++
 include/hw/boards.h |  1 +
 6 files changed, 51 insertions(+)

-- 
2.23.0




[PATCH v3 1/3] numa: Validate cluster and NUMA node boundary if required

2023-02-24 Thread Gavin Shan
For some architectures like ARM64, multiple CPUs in one cluster can be
associated with different NUMA nodes, which is irregular configuration
because we shouldn't have this in baremetal environment. The irregular
configuration causes Linux guest to misbehave, as the following warning
messages indicate.

  -smp 6,maxcpus=6,sockets=2,clusters=1,cores=3,threads=1 \
  -numa node,nodeid=0,cpus=0-1,memdev=ram0\
  -numa node,nodeid=1,cpus=2-3,memdev=ram1\
  -numa node,nodeid=2,cpus=4-5,memdev=ram2\

  [ cut here ]
  WARNING: CPU: 0 PID: 1 at kernel/sched/topology.c:2271 
build_sched_domains+0x284/0x910
  Modules linked in:
  CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.14.0-268.el9.aarch64 #1
  pstate: 0045 (nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
  pc : build_sched_domains+0x284/0x910
  lr : build_sched_domains+0x184/0x910
  sp : 8804bd50
  x29: 8804bd50 x28: 0002 x27: 
  x26: 89cf9a80 x25:  x24: 89cbf840
  x23: 80325000 x22: 005df800 x21: 8a4ce508
  x20:  x19: 80324440 x18: 0014
  x17: 388925c0 x16: 5386a066 x15: 9c10cc2e
  x14: 01c0 x13: 0001 x12: 7fffb1a0
  x11: 7fffb180 x10: 8a4ce508 x9 : 0041
  x8 : 8a4ce500 x7 : 8a4cf920 x6 : 0001
  x5 : 0001 x4 : 0007 x3 : 0002
  x2 : 1000 x1 : 8a4cf928 x0 : 0001
  Call trace:
   build_sched_domains+0x284/0x910
   sched_init_domains+0xac/0xe0
   sched_init_smp+0x48/0xc8
   kernel_init_freeable+0x140/0x1ac
   kernel_init+0x28/0x140
   ret_from_fork+0x10/0x20

Improve the situation to warn when multiple CPUs in one cluster have
been associated with different NUMA nodes. However, one NUMA node is
allowed to be associated with different clusters.

Signed-off-by: Gavin Shan 
---
 hw/core/machine.c   | 42 ++
 include/hw/boards.h |  1 +
 2 files changed, 43 insertions(+)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index f29e700ee4..3513df5a86 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1252,6 +1252,45 @@ static void machine_numa_finish_cpu_init(MachineState 
*machine)
 g_string_free(s, true);
 }
 
+static void validate_cpu_cluster_to_numa_boundary(MachineState *ms)
+{
+MachineClass *mc = MACHINE_GET_CLASS(ms);
+NumaState *state = ms->numa_state;
+const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
+const CPUArchId *cpus = possible_cpus->cpus;
+int len = possible_cpus->len, i, j;
+
+if (state->num_nodes <= 1 || len <= 1) {
+return;
+}
+
+/*
+ * The Linux scheduling domain can't be parsed when the multiple CPUs
+ * in one cluster have been associated with different NUMA nodes. However,
+ * it's fine to associate one NUMA node with CPUs in different clusters.
+ */
+for (i = 0; i < len; i++) {
+for (j = i + 1; j < len; j++) {
+if (cpus[i].props.has_socket_id &&
+cpus[i].props.has_cluster_id &&
+cpus[i].props.has_node_id &&
+cpus[j].props.has_socket_id &&
+cpus[j].props.has_cluster_id &&
+cpus[j].props.has_node_id &&
+cpus[i].props.socket_id == cpus[j].props.socket_id &&
+cpus[i].props.cluster_id == cpus[j].props.cluster_id &&
+cpus[i].props.node_id != cpus[j].props.node_id) {
+warn_report("CPU-%d and CPU-%d in socket-%ld-cluster-%ld "
+ "have been associated with node-%ld and node-%ld "
+ "respectively. It can cause OSes like Linux to"
+ "misbehave", i, j, cpus[i].props.socket_id,
+ cpus[i].props.cluster_id, cpus[i].props.node_id,
+ cpus[j].props.node_id);
+}
+}
+}
+}
+
 MemoryRegion *machine_consume_memdev(MachineState *machine,
  HostMemoryBackend *backend)
 {
@@ -1337,6 +1376,9 @@ void machine_run_board_init(MachineState *machine, const 
char *mem_path, Error *
 numa_complete_configuration(machine);
 if (machine->numa_state->num_nodes) {
 machine_numa_finish_cpu_init(machine);
+if (machine_class->cpu_cluster_has_numa_boundary) {
+validate_cpu_cluster_to_numa_boundary(machine);
+}
 }
 }
 
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 6fbbfd56c8..c9793b2789 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -273,6 +273,7 @@ struct MachineClass {
 bool nvdimm_supported;
 bool numa_mem_supported;
 bool auto_enable_numa;
+bool cpu_cluster_has_numa_boundary;
 SMPCompatProps 

[PATCH v2] hw/display/sm501: Add fallbacks to pixman routines

2023-02-24 Thread BALATON Zoltan
Pixman may return false if it does not have a suitable implementation.
Add fallbacks to handle such cases. Also add a property to allow
disabling pixman and always use the fallbacks which is useful for
testing different drawing methods or debugging pixman related issues.

Signed-off-by: BALATON Zoltan 
---
v2: Fix logic for pixman_blt to do what the commit message says, it
was inverted in v1. Reword commit message to clarify the property
is a debug option.

 hw/display/sm501.c | 82 --
 1 file changed, 58 insertions(+), 24 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 58bc9701ee..8c72f3a5b4 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -464,6 +464,7 @@ typedef struct SM501State {
 uint32_t last_width;
 uint32_t last_height;
 bool do_full_update; /* perform a full update next time */
+bool use_pixman;
 I2CBus *i2c_bus;
 
 /* mmio registers */
@@ -691,7 +692,7 @@ static void sm501_2d_operation(SM501State *s)
 unsigned int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF;
 int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0;
 int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt);
-bool overlap = false;
+bool overlap = false, fallback = false;
 
 if ((s->twoD_stretch >> 16) & 0xF) {
 qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n");
@@ -826,7 +827,9 @@ static void sm501_2d_operation(SM501State *s)
 de = db + (width + (height - 1) * dst_pitch) * bypp;
 overlap = (db < se && sb < de);
 }
-if (overlap) {
+if (!s->use_pixman) {
+fallback = true;
+} else if (overlap) {
 /* pixman can't do reverse blit: copy via temporary */
 int tmp_stride = DIV_ROUND_UP(width * bypp, sizeof(uint32_t));
 uint32_t *tmp = tmp_buf;
@@ -834,25 +837,48 @@ static void sm501_2d_operation(SM501State *s)
 if (tmp_stride * sizeof(uint32_t) * height > sizeof(tmp_buf)) {
 tmp = g_malloc(tmp_stride * sizeof(uint32_t) * height);
 }
-pixman_blt((uint32_t *)>local_mem[src_base], tmp,
-   src_pitch * bypp / sizeof(uint32_t),
-   tmp_stride, 8 * bypp, 8 * bypp,
-   src_x, src_y, 0, 0, width, height);
-pixman_blt(tmp, (uint32_t *)>local_mem[dst_base],
-   tmp_stride,
-   dst_pitch * bypp / sizeof(uint32_t),
-   8 * bypp, 8 * bypp,
-   0, 0, dst_x, dst_y, width, height);
+fallback = !pixman_blt((uint32_t *)>local_mem[src_base],
+   tmp,
+   src_pitch * bypp / sizeof(uint32_t),
+   tmp_stride,
+   8 * bypp, 8 * bypp,
+   src_x, src_y, 0, 0, width, height);
+if (!fallback) {
+fallback = !pixman_blt(tmp,
+   (uint32_t *)>local_mem[dst_base],
+   tmp_stride,
+   dst_pitch * bypp / sizeof(uint32_t),
+   8 * bypp, 8 * bypp,
+   0, 0, dst_x, dst_y, width, height);
+}
 if (tmp != tmp_buf) {
 g_free(tmp);
 }
 } else {
-pixman_blt((uint32_t *)>local_mem[src_base],
-   (uint32_t *)>local_mem[dst_base],
-   src_pitch * bypp / sizeof(uint32_t),
-   dst_pitch * bypp / sizeof(uint32_t),
-   8 * bypp, 8 * bypp,
-   src_x, src_y, dst_x, dst_y, width, height);
+fallback = !pixman_blt((uint32_t *)>local_mem[src_base],
+   (uint32_t *)>local_mem[dst_base],
+   src_pitch * bypp / sizeof(uint32_t),
+   dst_pitch * bypp / sizeof(uint32_t),
+   8 * bypp, 8 * bypp, src_x, src_y,
+   dst_x, dst_y, width, height);
+}
+if (fallback) {
+uint8_t *sp = s->local_mem + src_base;
+uint8_t *d = s->local_mem + dst_base;
+unsigned int y, i, j;
+for (y = 0; y < height; y++) {
+if (overlap) { /* overlap also means rtl */
+i = (dst_y + height - 1 - y) * dst_pitch;
+i = (dst_x + i) * bypp;
+j = (src_y + height - 1 - y) * 

Re: [PATCH 0/2] ui/kbd-state: QAPI'fy QKbdModifier

2023-02-24 Thread Akihiko Odaki

On 2023/02/24 20:01, Philippe Mathieu-Daudé wrote:

QAPI seems designed to maintain such enums,
so convert QKbdModifier to be QAPI generated.
Besides, this is how QKeyCode is maintained.


I recognize QkbdModifier as more like an internal detail of displays so 
I'm not convinced it should be converted to QAPI.


The interface of QEMU's input subsystem is so simple: send key up or key 
down events for QKeyCode. The modifiers are not exceptions. However, 
some display backends (cocoa, sdl2, and vnc) are not designed this way, 
and has internal states for modifiers. For such displays, QkbdState 
maintains the states to help them convert their internal key state 
representation to key up/down events of QKeyCode.


QKbdModifier is used by displays only to query these internal states 
QkbdState holds. As such, the definition of QKbdModifier is very 
dependent of the internal working of displays. It is particularly 
designed to match the needs of vnc, and I even wonder if the modifier 
state tracking should be moved away from the common code of QkbdState to 
vnc.


Regards,
Akihiko Odaki



Philippe Mathieu-Daudé (2):
   ui/kbd-state: Rename QKbdModifier enum definitions
   ui/kbd-state: QAPI'fy QKbdModifier

  include/ui/kbd-state.h | 16 
  qapi/ui.json   | 10 ++
  ui/cocoa.m |  2 +-
  ui/kbd-state.c | 14 +++---
  ui/keymaps.c   |  6 +++---
  ui/sdl2-input.c|  2 +-
  ui/vnc.c   | 16 
  7 files changed, 30 insertions(+), 36 deletions(-)





RE: Future of icount discussion for next KVM call?

2023-02-24 Thread Wang, Wei W


> -Original Message-
> From: Wang, Wei W
> Sent: Thursday, February 16, 2023 10:36 PM
> To: quint...@redhat.com; Alex Bennée 
> Cc: Paolo Bonzini ; Pavel Dovgalyuk
> ; qemu-devel@nongnu.org; Richard Henderson
> ; Mark Burton
> ; Bill Mills ; Marco
> Liebel ; Alexandre Iooss ;
> Mahmoud Mandour ; Emilio Cota
> ; kvm-devel ; Philippe Mathieu-
> Daudé 
> Subject: RE: Future of icount discussion for next KVM call?
> 
> On Thursday, February 16, 2023 9:57 PM, Juan Quintela wrote:
> > Just to see what we are having now:
> >
> > - single qemu binary moved to next slot (moved to next week?)
> >   Phillipe proposal
> > - TDX migration: we have the slides, but no code
> >   So I guess we can move it to the following slot, when we have a chance
> >   to look at the code, Wei?
> 
> It's ok to me to continue the discussion on either Feb 21st or March 7th, and 
> I
> plan to finish some update and share the code before end of next week.

KVM code can be read here: https://github.com/intel/tdx/  tdx-mig-wip
QEMU code will be shared soon.


Re: [PATCH v2 0/4] NUMA: Apply socket-NUMA-node boundary for aarch64 and RiscV machines

2023-02-24 Thread Gavin Shan

On 2/25/23 1:20 AM, Igor Mammedov wrote:

On Fri, 24 Feb 2023 21:16:39 +1100
Gavin Shan  wrote:


On 2/24/23 8:26 PM, Daniel Henrique Barboza wrote:

On 2/24/23 04:09, Gavin Shan wrote:

On 2/24/23 12:18 AM, Daniel Henrique Barboza wrote:

On 2/23/23 05:13, Gavin Shan wrote:

For arm64 and RiscV architecture, the driver (/base/arch_topology.c) is
used to populate the CPU topology in the Linux guest. It's required that
the CPUs in one socket can't span mutiple NUMA nodes. Otherwise, the Linux
scheduling domain can't be sorted out, as the following warning message
indicates. To avoid the unexpected confusion, this series attempts to
rejects such kind of insane configurations.

     -smp 6,maxcpus=6,sockets=2,clusters=1,cores=3,threads=1 \
     -numa node,nodeid=0,cpus=0-1,memdev=ram0    \
     -numa node,nodeid=1,cpus=2-3,memdev=ram1    \
     -numa node,nodeid=2,cpus=4-5,memdev=ram2    \



And why is this a QEMU problem? This doesn't hurt ACPI.

Also, this restriction impacts breaks ARM guests in the wild that are running
non-Linux OSes. I don't see why we should impact use cases that has nothing to
do with Linux Kernel feelings about sockets - NUMA nodes exclusivity.
  


With above configuration, CPU-0/1/2 are put into socket-0-cluster-0 while 
CPU-3/4/5
are put into socket-1-cluster-0, meaning CPU-2/3 belong to different socket and
cluster. However, CPU-2/3 are associated with NUMA node-1. In summary, multiple
CPUs in different clusters and sockets have been associated with one NUMA node.

If I'm correct, the configuration isn't sensible in a baremetal environment and
same Linux kernel is supposed to work well for baremetal and virtualized 
machine.
So I think QEMU needs to emulate the topology as much as we can to match with 
the
baremetal environment. It's the reason why I think it's a QEMU problem even it
doesn't hurt ACPI. As I said in the reply to Daniel P. Berrangé 

in another thread, we may need to gurantee that the CPUs in one cluster can't be
split to multiple NUMA nodes, which matches with the baremetal environment, as I
can understand.

Right, the restriction to have socket-NUMA-node or cluster-NUMA-node boundary 
will
definitely break the configurations running in the wild.



What about a warning? If the user attempts to use an exotic NUMA configuration
like the one you mentioned we can print something like:

"Warning: NUMA topologies where a socket belongs to multiple NUMA nodes can cause 
OSes like Linux to misbehave"

This would inform the user what might be going wrong in case Linux is 
crashing/error
out on them and then the user is free to fix their topology (or the kernel). And
at the same time we wouldn't break existing stuff that happens to be working.

   


Yes, I think a warning message is more appropriate, so that users can fix their
irregular configurations and the existing configurations aren't disconnected.
It would be nice to get the agreements from Daniel P. Berrangé and Drew, before
I'm going to change the code and post next revision.


Honestly you (and libvirt as far as I recall) are using legacy options
to assign cpus to numa nodes.
With '-numa node,nodeid=0,cpus=0-1' you can't really be sure what/where
in topology those cpus are.
What you can do is to use '-numa cpu,...' option to assign socket/core/...
to numa node, ex:
 "-numa cpu,node-id=1,socket-id=0 "   or
 "-numa cpu,node-id=0,socket-id=1,core-id=0 "   or
 "-numa cpu,node-id=0,socket-id=1,core-id=1,thread-id=0
to get your desired mapping.

The problem that's so far was stopping the later adoption by libvirt (Michal 
CCed)
is that values used by it are machine specific and to do it properly, for a 
concrete
'-M x -smp ...' at least for the first time qemu should be started with-
  -preconfig option and then user should query possible cpus for those values
and assign them to numa nodes via QMP.



The issue isn't related to the legacy or modern way to configure CPU-to-NUMA 
association.
Note that qtests/numa-test also use the legacy way. For example, the issue can 
be triggered
with the following command lines where the modern configuration is used:

  /home/gavin/sandbox/qemu.main/build/qemu-system-aarch64\
  -accel kvm -machine virt,gic-version=host  \
  -cpu host -smp 6,sockets=2,clusters=1,cores=3,threads=1\
  -m 768M,slots=16,maxmem=64G\
  -object memory-backend-ram,id=mem0,size=256M   \
  -object memory-backend-ram,id=mem1,size=256M   \
  -object memory-backend-ram,id=mem2,size=256M   \
  -numa node,nodeid=0,memdev=mem0\
  -numa node,nodeid=1,memdev=mem1\
  -numa node,nodeid=2,memdev=mem2\
  -numa cpu,node-id=0,socket-id=0,cluster-id=0,core-id=0,thread-id=0 \
  -numa 

Re: [RFC PATCH 10/43] target/loongarch: Implement vaddw/vsubw

2023-02-24 Thread Richard Henderson

On 2/23/23 21:24, gaosong wrote:

     {
     .fniv = gen_vaddwev_s,
     .fno = gen_helper_vaddwev_w_h,
     .opt_opc = vecop_list,
     .vece = MO_32
     },
     {
     .fniv = gen_vaddwev_s,
     .fno = gen_helper_vaddwev_d_w,
     .opt_opc = vecop_list,
     .vece = MO_64
     },


Oh, these two can also include .fni4 and .fni8 integer versions, respectively, for hosts 
without the proper vector support.



r~



Re: [PATCH v2 00/24] hw/ide: QOM/QDev housekeeping

2023-02-24 Thread Philippe Mathieu-Daudé

ping for 3 patches :)

On 20/2/23 10:13, Philippe Mathieu-Daudé wrote:

Missing review: 2, 17, 20

Since v1:
- addressed review comments

John, can I get your formal Ack?

Thanks,

Phil.





[PATCH][RESEND v3 2/3] Add Hyper-V Dynamic Memory Protocol definitions

2023-02-24 Thread Maciej S. Szmigiero
From: "Maciej S. Szmigiero" 

This commit adds Hyper-V Dynamic Memory Protocol definitions, taken
from hv_balloon Linux kernel driver, adapted to the QEMU coding style and
definitions.

Signed-off-by: Maciej S. Szmigiero 
---
 include/hw/hyperv/dynmem-proto.h | 423 +++
 1 file changed, 423 insertions(+)
 create mode 100644 include/hw/hyperv/dynmem-proto.h

diff --git a/include/hw/hyperv/dynmem-proto.h b/include/hw/hyperv/dynmem-proto.h
new file mode 100644
index 00..d0f9090ac4
--- /dev/null
+++ b/include/hw/hyperv/dynmem-proto.h
@@ -0,0 +1,423 @@
+#ifndef HW_HYPERV_DYNMEM_PROTO_H
+#define HW_HYPERV_DYNMEM_PROTO_H
+
+/*
+ * Hyper-V Dynamic Memory Protocol definitions
+ *
+ * Copyright (C) 2020-2023 Oracle and/or its affiliates.
+ *
+ * Based on drivers/hv/hv_balloon.c from Linux kernel:
+ * Copyright (c) 2012, Microsoft Corporation.
+ *
+ * Author: K. Y. Srinivasan 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ *
+ * History:
+ * Initial version 1.0
+ * Changed to 0.1 on 2009/03/25
+ * Changes to 0.2 on 2009/05/14
+ * Changes to 0.3 on 2009/12/03
+ * Changed to 1.0 on 2011/04/05
+ * Changed to 2.0 on 2019/12/10
+ */
+
+#define DYNMEM_MAKE_VERSION(Major, Minor) ((uint32_t)(((Major) << 16) | 
(Minor)))
+#define DYNMEM_MAJOR_VERSION(Version) ((uint32_t)(Version) >> 16)
+#define DYNMEM_MINOR_VERSION(Version) ((uint32_t)(Version) & 0xff)
+
+enum {
+DYNMEM_PROTOCOL_VERSION_1 = DYNMEM_MAKE_VERSION(0, 3),
+DYNMEM_PROTOCOL_VERSION_2 = DYNMEM_MAKE_VERSION(1, 0),
+DYNMEM_PROTOCOL_VERSION_3 = DYNMEM_MAKE_VERSION(2, 0),
+
+DYNMEM_PROTOCOL_VERSION_WIN7 = DYNMEM_PROTOCOL_VERSION_1,
+DYNMEM_PROTOCOL_VERSION_WIN8 = DYNMEM_PROTOCOL_VERSION_2,
+DYNMEM_PROTOCOL_VERSION_WIN10 = DYNMEM_PROTOCOL_VERSION_3,
+
+DYNMEM_PROTOCOL_VERSION_CURRENT = DYNMEM_PROTOCOL_VERSION_WIN10
+};
+
+
+
+/*
+ * Message Types
+ */
+
+enum dm_message_type {
+/*
+ * Version 0.3
+ */
+DM_ERROR = 0,
+DM_VERSION_REQUEST = 1,
+DM_VERSION_RESPONSE = 2,
+DM_CAPABILITIES_REPORT = 3,
+DM_CAPABILITIES_RESPONSE = 4,
+DM_STATUS_REPORT = 5,
+DM_BALLOON_REQUEST = 6,
+DM_BALLOON_RESPONSE = 7,
+DM_UNBALLOON_REQUEST = 8,
+DM_UNBALLOON_RESPONSE = 9,
+DM_MEM_HOT_ADD_REQUEST = 10,
+DM_MEM_HOT_ADD_RESPONSE = 11,
+DM_VERSION_03_MAX = 11,
+/*
+ * Version 1.0.
+ */
+DM_INFO_MESSAGE = 12,
+DM_VERSION_1_MAX = 12,
+
+/*
+ * Version 2.0
+ */
+DM_MEM_HOT_REMOVE_REQUEST = 13,
+DM_MEM_HOT_REMOVE_RESPONSE = 14
+};
+
+
+/*
+ * Structures defining the dynamic memory management
+ * protocol.
+ */
+
+union dm_version {
+struct {
+uint16_t minor_version;
+uint16_t major_version;
+};
+uint32_t version;
+} QEMU_PACKED;
+
+
+union dm_caps {
+struct {
+uint64_t balloon:1;
+uint64_t hot_add:1;
+/*
+ * To support guests that may have alignment
+ * limitations on hot-add, the guest can specify
+ * its alignment requirements; a value of n
+ * represents an alignment of 2^n in mega bytes.
+ */
+uint64_t hot_add_alignment:4;
+uint64_t hot_remove:1;
+uint64_t reservedz:57;
+} cap_bits;
+uint64_t caps;
+} QEMU_PACKED;
+
+union dm_mem_page_range {
+struct  {
+/*
+ * The PFN number of the first page in the range.
+ * 40 bits is the architectural limit of a PFN
+ * number for AMD64.
+ */
+uint64_t start_page:40;
+/*
+ * The number of pages in the range.
+ */
+uint64_t page_cnt:24;
+} finfo;
+uint64_t  page_range;
+} QEMU_PACKED;
+
+
+
+/*
+ * The header for all dynamic memory messages:
+ *
+ * type: Type of the message.
+ * size: Size of the message in bytes; including the header.
+ * trans_id: The guest is responsible for manufacturing this ID.
+ */
+
+struct dm_header {
+uint16_t type;
+uint16_t size;
+uint32_t trans_id;
+} QEMU_PACKED;
+
+/*
+ * A generic message format for dynamic memory.
+ * Specific message formats are defined later in the file.
+ */
+
+struct dm_message {
+struct dm_header hdr;
+uint8_t data[]; /* enclosed message */
+} QEMU_PACKED;
+
+
+/*
+ * Specific message types supporting the dynamic memory protocol.
+ */
+
+/*
+ * Version negotiation message. Sent from the guest to the host.
+ * The guest is free to try different versions until the host
+ * accepts the version.
+ *
+ * dm_version: The protocol version requested.
+ * is_last_attempt: If TRUE, this is the last version guest will request.
+ * reservedz: Reserved field, set to zero.
+ */
+
+struct dm_version_request {
+struct dm_header hdr;
+union dm_version version;
+uint32_t is_last_attempt:1;
+uint32_t reservedz:31;
+} 

[PATCH][RESEND v3 3/3] Add a Hyper-V Dynamic Memory Protocol driver (hv-balloon)

2023-02-24 Thread Maciej S. Szmigiero
From: "Maciej S. Szmigiero" 

This driver is like virtio-balloon on steroids: it allows both changing the
guest memory allocation via ballooning and inserting extra RAM into it by
adding required memory backends and providing them to the driver.

One of advantages of these over ACPI-based PC DIMM hotplug is that such
memory can be hotplugged in much smaller granularity because the ACPI DIMM
slot limit does not apply.

Hot-adding additional memory is done by creating a new memory backend (for
example by executing HMP command
"object_add memory-backend-ram,id=mem1,size=4G"), then executing a new
"hv-balloon-add-memory" QMP command, providing the id of that memory
backend as the "id" parameter.

In contrast with ACPI DIMM hotplug where one can only request to unplug a
whole DIMM stick this driver allows removing memory from guest in single
page (4k) units via ballooning.

After a VM reboot each previously hot-added memory backend gets released.
A "HV_BALLOON_MEMORY_BACKEND_UNUSED" QMP event is emitted in this case so
the software controlling QEMU knows that it either needs to delete that
memory backend (if no longer needed) or re-insert it.

In the future, the guest boot memory size might be changed on reboot
instead, taking into account the effective size that VM had before that
reboot (much like Hyper-V does).

For performance reasons, the guest-released memory is tracked in a few
range trees, as a series of (start, count) ranges.
Each time a new page range is inserted into such tree its neighbors are
checked as candidates for possible merging with it.

Besides performance reasons, the Dynamic Memory protocol itself uses page
ranges as the data structure in its messages, so relevant pages need to be
merged into such ranges anyway.

One has to be careful when tracking the guest-released pages, since the
guest can maliciously report returning pages outside its current address
space, which later clash with the address range of newly added memory.
Similarly, the guest can report freeing the same page twice.

The above design results in much better ballooning performance than when
using virtio-balloon with the same guest: 230 GB / minute with this driver
versus 70 GB / minute with virtio-balloon.

During a ballooning operation most of time is spent waiting for the guest
to come up with newly freed page ranges, processing the received ranges on
the host side (in QEMU and KVM) is nearly instantaneous.

The unballoon operation is also pretty much instantaneous:
thanks to the merging of the ballooned out page ranges 200 GB of memory can
be returned to the guest in about 1 second.
With virtio-balloon this operation takes about 2.5 minutes.

These tests were done against a Windows Server 2019 guest running on a
Xeon E5-2699, after dirtying the whole memory inside guest before each
balloon operation.

Using a range tree instead of a bitmap to track the removed memory also
means that the solution scales well with the guest size: even a 1 TB range
takes just few bytes of memory.

Since the required GTree operations aren't present in every Glib version
a check for them was added to "configure" script, together with new
"--enable-hv-balloon" and "--disable-hv-balloon" arguments.
If these GTree operations are missing in the system's Glib version this
driver will be skipped during QEMU build.

An optional "status-report=on" device parameter requests memory status
events from the guest (typically sent every second), which allow the host
to learn both the guest memory available and the guest memory in use
counts.
They are emitted externally as "HV_BALLOON_STATUS_REPORT" QMP events.

The driver is named hv-balloon since the Linux kernel client driver for
the Dynamic Memory Protocol is named as such and to follow the naming
pattern established by the virtio-balloon driver.
The whole protocol runs over Hyper-V VMBus.

The driver was tested against Windows Server 2012 R2, Windows Server 2016
and Windows Server 2016 guests and obeys the guest alignment requirements
reported to the host via DM_CAPABILITIES_REPORT message.

Signed-off-by: Maciej S. Szmigiero 
---
 Kconfig.host   |3 +
 configure  |   36 +
 hw/hyperv/Kconfig  |5 +
 hw/hyperv/hv-balloon.c | 2185 
 hw/hyperv/meson.build  |1 +
 hw/hyperv/trace-events |   16 +
 meson.build|4 +-
 qapi/machine.json  |   68 ++
 8 files changed, 2317 insertions(+), 1 deletion(-)
 create mode 100644 hw/hyperv/hv-balloon.c

diff --git a/Kconfig.host b/Kconfig.host
index d763d89269..2ee71578f3 100644
--- a/Kconfig.host
+++ b/Kconfig.host
@@ -46,3 +46,6 @@ config FUZZ
 config VFIO_USER_SERVER_ALLOWED
 bool
 imply VFIO_USER_SERVER
+
+config HV_BALLOON_POSSIBLE
+bool
diff --git a/configure b/configure
index cf6db3d551..b534955f58 100755
--- a/configure
+++ b/configure
@@ -283,6 +283,7 @@ bsd_user=""
 pie=""
 coroutine=""
 plugins="$default_feature"
+hv_balloon="$default_feature"
 meson=""
 

[PATCH][RESEND v3 1/3] hapvdimm: add a virtual DIMM device for memory hot-add protocols

2023-02-24 Thread Maciej S. Szmigiero
From: "Maciej S. Szmigiero" 

This device works like a virtual DIMM stick: it allows inserting extra RAM
into the guest at run time and later removing it without having to
duplicate all of the address space management logic of TYPE_MEMORY_DEVICE
in each memory hot-add protocol driver.

This device is not meant to be instantiated or removed by the QEMU user
directly: rather, the protocol driver is supposed to add and remove it as
required.

In fact, its very existence is supposed to be an implementation detail,
transparent to the QEMU user.

To prevent the user from accidentally manually creating an instance of this
device the protocol driver is supposed to place the qdev_device_add*() call
(that is uses to add this device) between hapvdimm_allow_adding() and
hapvdimm_disallow_adding() calls in order to temporary authorize the
operation.

Signed-off-by: Maciej S. Szmigiero 
---
 hw/i386/Kconfig   |   2 +
 hw/i386/pc.c  |   4 +-
 hw/mem/Kconfig|   4 +
 hw/mem/hapvdimm.c | 221 ++
 hw/mem/meson.build|   1 +
 include/hw/mem/hapvdimm.h |  27 +
 6 files changed, 258 insertions(+), 1 deletion(-)
 create mode 100644 hw/mem/hapvdimm.c
 create mode 100644 include/hw/mem/hapvdimm.h

diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index 9fbfe748b5..13f70707ed 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -68,6 +68,7 @@ config I440FX
 imply E1000_PCI
 imply VMPORT
 imply VMMOUSE
+imply HAPVDIMM
 select ACPI_PIIX4
 select PC_PCI
 select PC_ACPI
@@ -95,6 +96,7 @@ config Q35
 imply E1000E_PCI_EXPRESS
 imply VMPORT
 imply VMMOUSE
+imply HAPVDIMM
 select PC_PCI
 select PC_ACPI
 select PCI_EXPRESS_Q35
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index a7a2ededf9..5469d89bcc 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -73,6 +73,7 @@
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/cpu_hotplug.h"
 #include "acpi-build.h"
+#include "hw/mem/hapvdimm.h"
 #include "hw/mem/pc-dimm.h"
 #include "hw/mem/nvdimm.h"
 #include "hw/cxl/cxl.h"
@@ -1609,7 +1610,8 @@ static HotplugHandler 
*pc_get_hotplug_handler(MachineState *machine,
 object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||
 object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI) ||
 object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
-object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE)) {
+object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE) ||
+object_dynamic_cast(OBJECT(dev), TYPE_HAPVDIMM)) {
 return HOTPLUG_HANDLER(machine);
 }
 
diff --git a/hw/mem/Kconfig b/hw/mem/Kconfig
index 73c5ae8ad9..d8c1feafed 100644
--- a/hw/mem/Kconfig
+++ b/hw/mem/Kconfig
@@ -16,3 +16,7 @@ config CXL_MEM_DEVICE
 bool
 default y if CXL
 select MEM_DEVICE
+
+config HAPVDIMM
+bool
+select MEM_DEVICE
diff --git a/hw/mem/hapvdimm.c b/hw/mem/hapvdimm.c
new file mode 100644
index 00..9ae82edb2c
--- /dev/null
+++ b/hw/mem/hapvdimm.c
@@ -0,0 +1,221 @@
+/*
+ * A memory hot-add protocol vDIMM device
+ *
+ * Copyright (C) 2020-2023 Oracle and/or its affiliates.
+ *
+ * Heavily based on pc-dimm.c:
+ * Copyright ProfitBricks GmbH 2012
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "exec/memory.h"
+#include "hw/boards.h"
+#include "hw/mem/hapvdimm.h"
+#include "hw/mem/memory-device.h"
+#include "hw/qdev-core.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qemu/module.h"
+#include "sysemu/hostmem.h"
+#include "trace.h"
+
+typedef struct HAPVDIMMDevice {
+/* private */
+DeviceState parent_obj;
+
+/* public */
+bool ever_realized;
+uint64_t addr;
+uint64_t align;
+uint32_t node;
+HostMemoryBackend *hostmem;
+} HAPVDIMMDevice;
+
+typedef struct HAPVDIMMDeviceClass {
+/* private */
+DeviceClass parent_class;
+} HAPVDIMMDeviceClass;
+
+static bool hapvdimm_adding_allowed;
+static Property hapvdimm_properties[] = {
+DEFINE_PROP_UINT64(HAPVDIMM_ADDR_PROP, HAPVDIMMDevice, addr, 0),
+DEFINE_PROP_UINT64(HAPVDIMM_ALIGN_PROP, HAPVDIMMDevice, align, 0),
+DEFINE_PROP_LINK(HAPVDIMM_MEMDEV_PROP, HAPVDIMMDevice, hostmem,
+ TYPE_MEMORY_BACKEND, HostMemoryBackend *),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+void hapvdimm_allow_adding(void)
+{
+hapvdimm_adding_allowed = true;
+}
+
+void hapvdimm_disallow_adding(void)
+{
+hapvdimm_adding_allowed = false;
+}
+
+static void hapvdimm_get_size(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+ERRP_GUARD();
+uint64_t value;
+
+value = memory_device_get_region_size(MEMORY_DEVICE(obj), errp);
+if (*errp) {
+return;
+}
+
+

[PATCH][RESEND v3 0/3] Hyper-V Dynamic Memory Protocol driver (hv-balloon)

2023-02-24 Thread Maciej S. Szmigiero
From: "Maciej S. Szmigiero" 

This is a rebase/resend of v2 patch series located here:
https://lore.kernel.org/qemu-devel/cover.1672878904.git.maciej.szmigi...@oracle.com/

The only changes from v2 are fixing some conflicts around build files (and
re-testing).

 Kconfig.host |3 +
 configure|   36 +
 hw/hyperv/Kconfig|5 +
 hw/hyperv/hv-balloon.c   | 2185 ++
 hw/hyperv/meson.build|1 +
 hw/hyperv/trace-events   |   16 +
 hw/i386/Kconfig  |2 +
 hw/i386/pc.c |4 +-
 hw/mem/Kconfig   |4 +
 hw/mem/hapvdimm.c|  221 +++
 hw/mem/meson.build   |1 +
 include/hw/hyperv/dynmem-proto.h |  423 ++
 include/hw/mem/hapvdimm.h|   27 +
 meson.build  |4 +-
 qapi/machine.json|   68 +
 15 files changed, 2998 insertions(+), 2 deletions(-)
 create mode 100644 hw/hyperv/hv-balloon.c
 create mode 100644 hw/mem/hapvdimm.c
 create mode 100644 include/hw/hyperv/dynmem-proto.h
 create mode 100644 include/hw/mem/hapvdimm.h




[PATCH] scripts/git.orderfile: Display QAPI script changes before schema ones

2023-02-24 Thread Philippe Mathieu-Daudé
When modifying QAPI scripts and modifying C files along,
it makes sense to display QAPI changes first.

Signed-off-by: Philippe Mathieu-Daudé 
---
Failed example:
https://lore.kernel.org/qemu-devel/20230224155451.20211-3-phi...@linaro.org/
---
 scripts/git.orderfile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/scripts/git.orderfile b/scripts/git.orderfile
index 8edac0380b..70adc1a74a 100644
--- a/scripts/git.orderfile
+++ b/scripts/git.orderfile
@@ -22,6 +22,8 @@ Makefile*
 *.mak
 meson.build
 
+# qapi scripts
+scripts/qapi*
 # qapi schema
 qapi/*.json
 qga/*.json
-- 
2.38.1




Re: [PATCH 0/4] RISCVCPUConfig related cleanups

2023-02-24 Thread Richard Henderson

On 2/24/23 07:45, Daniel Henrique Barboza wrote:

Hi,

These cleanups were suggested by LIU Zhiwei during the review of the
RISCV_FEATURE_* cleanups, currently on version 7 [1].

These are dependent on the patch "[PATCH v7 01/10] target/riscv: introduce
riscv_cpu_cfg()" from [1] because we use the riscv_cpu_cfg() API.


[1] https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg06467.html

Daniel Henrique Barboza (4):
   target/riscv/csr.c: use env_archcpu() in ctr()
   target/riscv/csr.c: simplify mctr()
   target/riscv/csr.c: use riscv_cpu_cfg() to avoid env_cpu() pointers
   target/riscv/csr.c: avoid env_archcpu() usages when reading
 RISCVCPUConfig

  target/riscv/csr.c | 90 +-
  1 file changed, 24 insertions(+), 66 deletions(-)



Reviewed-by: Richard Henderson 

r~



Re: [PULL 00/29] Block layer patches

2023-02-24 Thread Philippe Mathieu-Daudé

Hi,

On 24/2/23 19:50, Peter Maydell wrote:

On Thu, 23 Feb 2023 at 18:51, Kevin Wolf  wrote:


The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8:

   Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into 
staging (2023-02-21 11:28:31 +)

are available in the Git repository at:

   https://repo.or.cz/qemu/kevin.git tags/for-upstream

for you to fetch changes up to 0f385a2420d2c3f8ae7ed65fbe2712027664059e:

   block/rbd: Add support for layered encryption (2023-02-23 19:49:35 +0100)


Block layer patches

- Lock the graph, part 2 (BlockDriver callbacks)
- virtio-scsi: fix SCSIDevice hot unplug with IOThread
- rbd: Add support for layered encryption





Applied, thanks.


Configuring with --extra-cflags=-ggdb, on

C compiler for the host machine: clang (clang 14.0.0 "Apple clang 
version 14.0.0 (clang-1400.0.29.202)")

C linker for the host machine: clang ld64 820.1
Host machine cpu family: aarch64
Host machine cpu: aarch64
...
CFLAGS   : -ggdb -g -O2

I'm getting:

../../block/io.c:182:38: warning: reading variable 'bdrv_aio_preadv' 
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]

drv->bdrv_aio_preadv ||
 ^
../../block/io.c:997:14: warning: reading variable 'bdrv_aio_preadv' 
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]

if (drv->bdrv_aio_preadv) {
 ^
../../block/io.c:1003:20: warning: reading variable 'bdrv_aio_preadv' 
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]

acb = drv->bdrv_aio_preadv(bs, offset, bytes, qiov, flags,
   ^
../../block/io.c:1076:14: warning: reading variable 'bdrv_aio_pwritev' 
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]

if (drv->bdrv_aio_pwritev) {
 ^
../../block/io.c:1082:20: warning: reading variable 'bdrv_aio_pwritev' 
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]

acb = drv->bdrv_aio_pwritev(bs, offset, bytes, qiov, flags,
   ^
../../block/io.c:2899:25: warning: reading variable 'bdrv_aio_flush' 
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]

} else if (bs->drv->bdrv_aio_flush) {
^
../../block/io.c:2905:24: warning: reading variable 'bdrv_aio_flush' 
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]

acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, );
   ^
../../block/io.c:2991:49: warning: reading variable 'bdrv_aio_pdiscard' 
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]

if (!bs->drv->bdrv_co_pdiscard && !bs->drv->bdrv_aio_pdiscard) {
^
../../block/io.c:3058:28: warning: reading variable 'bdrv_aio_pdiscard' 
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]

acb = bs->drv->bdrv_aio_pdiscard(bs, offset, num,
   ^
../../block/io.c:3094:24: warning: reading variable 'bdrv_aio_ioctl' 
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]

if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
   ^
../../block/io.c:3102:20: warning: reading variable 'bdrv_aio_ioctl' 
requires holding mutex 'graph_lock' [-Wthread-safety-analysis]
acb = drv->bdrv_aio_ioctl(bs, req, buf, bdrv_co_io_em_complete, 
);

   ^
11 warnings generated.



Re: [PATCH 0/4] RISCVCPUConfig related cleanups

2023-02-24 Thread Richard Henderson

On 2/24/23 07:45, Daniel Henrique Barboza wrote:

Hi,

These cleanups were suggested by LIU Zhiwei during the review of the
RISCV_FEATURE_* cleanups, currently on version 7 [1].

These are dependent on the patch "[PATCH v7 01/10] target/riscv: introduce
riscv_cpu_cfg()" from [1] because we use the riscv_cpu_cfg() API.


If you add

Based-on: 

to the cover letter, then patchew can stitch the two patch sets together in its git 
repository.



r~



[PATCH 1/2] gitlab/opensbi: Move to docker:stable

2023-02-24 Thread Palmer Dabbelt
The OpenSBI build has been using docker:19.03.1, which appears to be old
enough that v2 of the manifest is no longer supported.  Something has
started serving us those manifests, resulting in errors along the lines
of

$ docker build --cache-from $IMAGE_TAG --tag 
$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $IMAGE_TAG .gitlab-ci.d/opensbi
Step 1/7 : FROM ubuntu:18.04
18.04: Pulling from library/ubuntu
mediaType in manifest should be 
'application/vnd.docker.distribution.manifest.v2+json' not 
'application/vnd.oci.image.manifest.v1+json'

This just moves to docker:stable, as was suggested by the template.

Signed-off-by: Palmer Dabbelt 
---
 .gitlab-ci.d/opensbi.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.d/opensbi.yml b/.gitlab-ci.d/opensbi.yml
index 04ed5a3ea1..9a651465d8 100644
--- a/.gitlab-ci.d/opensbi.yml
+++ b/.gitlab-ci.d/opensbi.yml
@@ -42,9 +42,9 @@
 docker-opensbi:
   extends: .opensbi_job_rules
   stage: containers
-  image: docker:19.03.1
+  image: docker:stable
   services:
-- docker:19.03.1-dind
+- docker:stable-dind
   variables:
 GIT_DEPTH: 3
 IMAGE_TAG: $CI_REGISTRY_IMAGE:opensbi-cross-build
-- 
2.39.1




[PATCH 0/2] Fix the OpenSBI CI job and bump to v1.2

2023-02-24 Thread Palmer Dabbelt
The OpenSBI version bump found a CI failure, which appears to actually
have been related to the Docker version as opposed to the Ubuntu
version -- at least assuming my local CI run
 is accurate
(thanks to Thomas for pointing out how to get those set up).

I've left off the Ubuntu version upgrade because it's triggering some
key-related issues when in apt.  That's probably worth doing, but I
figured it'd be better to send these along now to try and get things
unblocked.  The EDK2 Docker setup looks like it would have the same
issue but I'll also keep that independent.





Re: [PATCH 0/2] block/qcow2: QAPI'fy Qcow2DiscardType

2023-02-24 Thread Richard Henderson

On 2/24/23 05:20, Philippe Mathieu-Daudé wrote:

QAPI seems designed to maintain such enums,
so convert Qcow2DiscardType to be QAPI generated.
Besides, this is how Qcow2CompressionType is maintained.

Philippe Mathieu-Daudé (2):
   block/qcow2: Rename QCOW2_DISCARD_TYPE enum definitions
   block/qcow2: QAPI'fy Qcow2DiscardType


Reviewed-by: Richard Henderson 

r~



Re: [PULL 00/13] testing updates (gitlab, cirrus, docker, avocado, windows)

2023-02-24 Thread Philippe Mathieu-Daudé

On 24/2/23 20:52, Alex Bennée wrote:


Peter Maydell  writes:


On Thu, 23 Feb 2023 at 15:57, Alex Bennée  wrote:


The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8:

   Merge tag 'net-pull-request' of https://github.com/jasowang/qemu
into staging (2023-02-21 11:28:31 +)

are available in the Git repository at:

   https://gitlab.com/stsquad/qemu.git tags/pull-testing-next-230223-1

for you to fetch changes up to e9969376f01180d7bcbee25ae8333983da7eda2c:

   cirrus.yml: Improve the windows_msys2_task (2023-02-23 15:48:23 +)


testing updates:

   - ensure socat available for tests
   - skip socat tests for MacOS
   - properly clean up fifos after use
   - make fp-test less chatty
   - store test artefacts on Cirrus
   - control custom runners with QEMU_CI knobs
   - disable benchmark runs under tsan build
   - update ubuntu 2004 to 2204
   - skip nios2 kernel replay test
   - add tuxrun baselines to avocado
   - binary build of tricore tools
   - export test results on cross builds
   - improve windows builds




So I've been applying pullreqs relying on a combination of the
private-runner CI jobs plus using the free minutes allowance
on my personal gitlab account, and ad-hoc local builds. I'm
a bit reluctant to do that for this one though, because it's
touching all the gitlab config and we won't be able test that
that is OK until we can do a full run with the standard config.
What do you think ?


What is the alternative, waiting 5 days up to March 1st?


This was my run of the tag:

   https://gitlab.com/stsquad/qemu/-/pipelines/787068318/

The FreeBSD failure is the dodgy migration test and the openbsi/edk2
builds fails as 18.04 just went EOL I think. I don't currently have the
s390x runner on my config.



thanks
-- PMM








Re: [PATCH 2/2] qapi: Generate enum count as definition in gen_enum_lookup()

2023-02-24 Thread Richard Henderson

On 2/24/23 05:54, Philippe Mathieu-Daudé wrote:

QAPI's gen_enum() generates QAPI enum values and the number
of this values (as foo__MAX).
The number of entries in an enum type is not part of the
enumerated values, but we generate it as such. See for
example:

   typedef enum OnOffAuto {
   ON_OFF_AUTO_AUTO,
   ON_OFF_AUTO_ON,
   ON_OFF_AUTO_OFF,
   ON_OFF_AUTO__MAX,<-
   } OnOffAuto;

Instead of declaring the enum count as the last enumerated
value, #define it, so it is not part of the enum. The previous
example becomes:

   typedef enum OnOffAuto {
   ON_OFF_AUTO_AUTO,
   ON_OFF_AUTO_ON,
   ON_OFF_AUTO_OFF,
   #define ON_OFF_AUTO__MAX 3   <-
   } OnOffAuto;

Since Clang enables the -Wswitch warning by default [*], remove all
pointless foo__MAX cases in switch statement, in order to avoid:

  audio/audio.c:2231:10: error: case value not in enumerated type 'AudioFormat' 
(aka 'enum AudioFormat') [-Wswitch]
 case AUDIO_FORMAT__MAX:
  ^
  ui/input.c:233:14: error: case value not in enumerated type 'KeyValueKind' 
(aka 'enum KeyValueKind') [-Wswitch]
 case KEY_VALUE_KIND__MAX:
  ^
  ...

[*]https://clang.llvm.org/docs/DiagnosticsReference.html#wswitch
Signed-off-by: Philippe Mathieu-Daudé
---


Yay!

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v5 5/5] dump: Add create_win_dump() stub for non-x86 targets

2023-02-24 Thread Richard Henderson

On 2/23/23 21:38, Philippe Mathieu-Daudé wrote:

-specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files('dump.c'), snappy, 
lzo])
+softmmu_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files('dump.c'), snappy, lzo])


You can remove the when: as well, yes?


r~



Re: [PATCH 5/5] hw/audio/via-ac97: Basic implementation of audio playback

2023-02-24 Thread BALATON Zoltan

On Fri, 24 Feb 2023, Daniel Henrique Barboza wrote:

On 2/24/23 10:05, BALATON Zoltan wrote:
Just for some motivation, this is what we want to make possible for more 
people with QEMU 8.0: https://youtu.be/YY9RExl4VDI


That's neat!



This would need at least my SM502 patches and fixing the IRQ routing in the 
VT8231 (this test was with my series for that, I'll ask testing Bernhard's 
version the same way once I get it and rebase my patches on it). AmigaOS 
can use ES1370 so the via-ac97 patches are not that important now but the 
other patches would be needed. I hope users won't have to wait until 
September to try this.


If you're referring to "hw/display/sm501: Implement more 2D raster 
operations" then it's already

queued in ppc-next.


That one and another I've sent yesterday that adds fallbacks for pixman 
routines.


In fact I believe you can re-send it with this series, 
with my r-b, and whoever

gets to send the PR can send everything at once.


OK I'll collect all the patches in one series and submit it early next 
week. Hopefully we can test over the weekend and address any comments by 
the freeze.


If either Gerd of Phil wants to pick these up I have already acked the 
pegasos2 changes.


If you want me to get this via qemu-ppc bear in mind that I need to send the 
PR March 7th

at the latest.


I'm aware of that, although if we get more CI outage which stops pulls 
maybe we should consider 1-2 week extension, but I'm planning accordingly 
and if there won't be unexpected delays (e.g. new late reviews asking for 
extensive changes) this should be ready a week before the freeze. I think 
we can do one or two more versions/


Regards,
BALATON Zoltan



Re: [PATCH v13 00/60] Xen HVM support under KVM

2023-02-24 Thread David Woodhouse
On Thu, 2023-02-23 at 12:45 +, David Woodhouse wrote:
> Lucky version 13, now with a full set of Reviewed-by: tags from Paul for
> the Xen side. One minor tweak to the return value of the timer op call.
> 
> Now I think we're just looking to Paolo to approve from the KVM side,
> and potentially a last chance for anyone else to give a slightly belated 
> objection (or did I miss something already noted?), and we can merge it?

I got the CI running in gitlab and made a few minor fixes.

https://gitlab.com/dwmw2/qemu/-/pipelines/788353645 looks sane enough;
only a few issues with checkpatch, and those are mostly on the imported
Xen headers.

I won't send v14 just yet, as I'm still trying not to post more than
one a week. I'll probably rebase to master again before posting on
Monday, but it's currently at 
https://git.infradead.org/users/dwmw2/qemu.git/shortlog/refs/heads/xenfv-kvm-14


smime.p7s
Description: S/MIME cryptographic signature


[PATCH 4/7] tests/docker: add USER stanzas to non-lci images

2023-02-24 Thread Alex Bennée
These are flat but not generated by lcitool so we need to manually
update them with the `useradd` stanza.

Signed-off-by: Alex Bennée 
---
 tests/docker/dockerfiles/debian-all-test-cross.docker | 5 +
 tests/docker/dockerfiles/debian-alpha-cross.docker| 5 +
 tests/docker/dockerfiles/debian-hexagon-cross.docker  | 5 +
 tests/docker/dockerfiles/debian-hppa-cross.docker | 5 +
 tests/docker/dockerfiles/debian-loongarch-cross.docker| 5 +
 tests/docker/dockerfiles/debian-m68k-cross.docker | 5 +
 tests/docker/dockerfiles/debian-mips-cross.docker | 5 +
 tests/docker/dockerfiles/debian-mips64-cross.docker   | 5 +
 tests/docker/dockerfiles/debian-native.docker | 5 +
 tests/docker/dockerfiles/debian-powerpc-test-cross.docker | 6 +-
 tests/docker/dockerfiles/debian-riscv64-cross.docker  | 5 +
 tests/docker/dockerfiles/debian-riscv64-test-cross.docker | 5 +
 tests/docker/dockerfiles/debian-sh4-cross.docker  | 5 +
 tests/docker/dockerfiles/debian-sparc64-cross.docker  | 5 +
 tests/docker/dockerfiles/debian-toolchain.docker  | 5 +
 tests/docker/dockerfiles/debian-tricore-cross.docker  | 5 +
 tests/docker/dockerfiles/debian-xtensa-cross.docker   | 5 +
 tests/docker/dockerfiles/fedora-cris-cross.docker | 5 +
 tests/docker/dockerfiles/fedora-i386-cross.docker | 5 +
 tests/docker/dockerfiles/python.docker| 5 +
 20 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/tests/docker/dockerfiles/debian-all-test-cross.docker 
b/tests/docker/dockerfiles/debian-all-test-cross.docker
index 8dc5e1b5de..981e9bdc7b 100644
--- a/tests/docker/dockerfiles/debian-all-test-cross.docker
+++ b/tests/docker/dockerfiles/debian-all-test-cross.docker
@@ -61,3 +61,8 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
 
 ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
 ENV DEF_TARGET_LIST 
aarch64-linux-user,alpha-linux-user,arm-linux-user,hppa-linux-user,i386-linux-user,m68k-linux-user,mips-linux-user,mips64-linux-user,mips64el-linux-user,mipsel-linux-user,ppc-linux-user,ppc64-linux-user,ppc64le-linux-user,riscv64-linux-user,s390x-linux-user,sh4-linux-user,sparc64-linux-user
+# As a final step configure the user (if env is defined)
+ARG USER
+ARG UID
+RUN if [ "${USER}" ]; then \
+  id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
diff --git a/tests/docker/dockerfiles/debian-alpha-cross.docker 
b/tests/docker/dockerfiles/debian-alpha-cross.docker
index 4eeb43c78a..7fa7bf1bde 100644
--- a/tests/docker/dockerfiles/debian-alpha-cross.docker
+++ b/tests/docker/dockerfiles/debian-alpha-cross.docker
@@ -12,3 +12,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
 eatmydata apt-get install --no-install-recommends -y \
 gcc-alpha-linux-gnu \
 libc6.1-dev-alpha-cross
+# As a final step configure the user (if env is defined)
+ARG USER
+ARG UID
+RUN if [ "${USER}" ]; then \
+  id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
diff --git a/tests/docker/dockerfiles/debian-hexagon-cross.docker 
b/tests/docker/dockerfiles/debian-hexagon-cross.docker
index 8a0d748343..5308ccb8fe 100644
--- a/tests/docker/dockerfiles/debian-hexagon-cross.docker
+++ b/tests/docker/dockerfiles/debian-hexagon-cross.docker
@@ -33,3 +33,8 @@ ENV TOOLCHAIN_URL 
https://codelinaro.jfrog.io/artifactory/codelinaro-toolchain-f
 
 RUN curl -#SL "$TOOLCHAIN_URL" | tar -xJC "$TOOLCHAIN_INSTALL"
 ENV PATH $PATH:${TOOLCHAIN_INSTALL}/${TOOLCHAIN_BASENAME}/x86_64-linux-gnu/bin
+# As a final step configure the user (if env is defined)
+ARG USER
+ARG UID
+RUN if [ "${USER}" ]; then \
+  id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
diff --git a/tests/docker/dockerfiles/debian-hppa-cross.docker 
b/tests/docker/dockerfiles/debian-hppa-cross.docker
index af1c8403d8..dd47ffdfa4 100644
--- a/tests/docker/dockerfiles/debian-hppa-cross.docker
+++ b/tests/docker/dockerfiles/debian-hppa-cross.docker
@@ -12,3 +12,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
 eatmydata apt-get install --no-install-recommends -y \
 gcc-hppa-linux-gnu \
 libc6-dev-hppa-cross
+# As a final step configure the user (if env is defined)
+ARG USER
+ARG UID
+RUN if [ "${USER}" ]; then \
+  id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
diff --git a/tests/docker/dockerfiles/debian-loongarch-cross.docker 
b/tests/docker/dockerfiles/debian-loongarch-cross.docker
index a8e8e98909..9d957547b5 100644
--- a/tests/docker/dockerfiles/debian-loongarch-cross.docker
+++ b/tests/docker/dockerfiles/debian-loongarch-cross.docker
@@ -25,3 +25,8 @@ RUN curl -#SL 
https://github.com/loongson/build-tools/releases/download/2022.05.
 
 ENV PATH $PATH:/opt/cross-tools/bin
 ENV LD_LIBRARY_PATH 
/opt/cross-tools/lib:/opt/cross-tools/loongarch64-unknown-linux-gnu/lib:$LD_LIBRARY_PATH
+# As a final step configure the user (if env is 

Re: [PULL 00/13] testing updates (gitlab, cirrus, docker, avocado, windows)

2023-02-24 Thread Alex Bennée


Peter Maydell  writes:

> On Thu, 23 Feb 2023 at 15:57, Alex Bennée  wrote:
>>
>> The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8:
>>
>>   Merge tag 'net-pull-request' of https://github.com/jasowang/qemu
>> into staging (2023-02-21 11:28:31 +)
>>
>> are available in the Git repository at:
>>
>>   https://gitlab.com/stsquad/qemu.git tags/pull-testing-next-230223-1
>>
>> for you to fetch changes up to e9969376f01180d7bcbee25ae8333983da7eda2c:
>>
>>   cirrus.yml: Improve the windows_msys2_task (2023-02-23 15:48:23 +)
>>
>> 
>> testing updates:
>>
>>   - ensure socat available for tests
>>   - skip socat tests for MacOS
>>   - properly clean up fifos after use
>>   - make fp-test less chatty
>>   - store test artefacts on Cirrus
>>   - control custom runners with QEMU_CI knobs
>>   - disable benchmark runs under tsan build
>>   - update ubuntu 2004 to 2204
>>   - skip nios2 kernel replay test
>>   - add tuxrun baselines to avocado
>>   - binary build of tricore tools
>>   - export test results on cross builds
>>   - improve windows builds
>>
>> 
>
> So I've been applying pullreqs relying on a combination of the
> private-runner CI jobs plus using the free minutes allowance
> on my personal gitlab account, and ad-hoc local builds. I'm
> a bit reluctant to do that for this one though, because it's
> touching all the gitlab config and we won't be able test that
> that is OK until we can do a full run with the standard config.
> What do you think ?

This was my run of the tag:

  https://gitlab.com/stsquad/qemu/-/pipelines/787068318/

The FreeBSD failure is the dodgy migration test and the openbsi/edk2
builds fails as 18.04 just went EOL I think. I don't currently have the
s390x runner on my config.

>
> thanks
> -- PMM


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH 3/7] tests/lcitool: append user setting stanza to dockerfiles

2023-02-24 Thread Alex Bennée
For the cross-compilation use-case it is important to add the host
user to the dockerfile so we can map them to the docker environment
when cross-building files.

Signed-off-by: Alex Bennée 
---
 .gitlab-ci.d/cirrus/freebsd-12.vars   |  5 +
 .gitlab-ci.d/cirrus/freebsd-13.vars   |  5 +
 .gitlab-ci.d/cirrus/macos-12.vars |  5 +
 tests/docker/dockerfiles/alpine.docker|  5 +
 tests/docker/dockerfiles/centos8.docker   |  5 +
 tests/docker/dockerfiles/debian-amd64-cross.docker|  5 +
 tests/docker/dockerfiles/debian-amd64.docker  |  5 +
 tests/docker/dockerfiles/debian-arm64-cross.docker|  5 +
 tests/docker/dockerfiles/debian-armel-cross.docker|  5 +
 tests/docker/dockerfiles/debian-armhf-cross.docker|  5 +
 tests/docker/dockerfiles/debian-mips64el-cross.docker |  5 +
 tests/docker/dockerfiles/debian-mipsel-cross.docker   |  5 +
 tests/docker/dockerfiles/debian-ppc64el-cross.docker  |  5 +
 tests/docker/dockerfiles/debian-s390x-cross.docker|  5 +
 tests/docker/dockerfiles/fedora-win32-cross.docker|  5 +
 tests/docker/dockerfiles/fedora-win64-cross.docker|  5 +
 tests/docker/dockerfiles/fedora.docker|  5 +
 tests/docker/dockerfiles/opensuse-leap.docker |  5 +
 tests/docker/dockerfiles/ubuntu2004.docker|  5 +
 tests/docker/dockerfiles/ubuntu2204.docker|  5 +
 tests/lcitool/refresh | 11 ++-
 21 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/.gitlab-ci.d/cirrus/freebsd-12.vars 
b/.gitlab-ci.d/cirrus/freebsd-12.vars
index 44d8a2a511..0bff53be44 100644
--- a/.gitlab-ci.d/cirrus/freebsd-12.vars
+++ b/.gitlab-ci.d/cirrus/freebsd-12.vars
@@ -14,3 +14,8 @@ PIP3='/usr/local/bin/pip-3.8'
 PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache 
cdrkit-genisoimage 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 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 zstd'
 PYPI_PKGS=''
 PYTHON='/usr/local/bin/python3'
+# As a final step configure the user (if env is defined)
+ARG USER
+ARG UID
+RUN if [ "${USER}" ]; then \
+  id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
\ No newline at end of file
diff --git a/.gitlab-ci.d/cirrus/freebsd-13.vars 
b/.gitlab-ci.d/cirrus/freebsd-13.vars
index 7622c849b2..235d08a5ee 100644
--- a/.gitlab-ci.d/cirrus/freebsd-13.vars
+++ b/.gitlab-ci.d/cirrus/freebsd-13.vars
@@ -14,3 +14,8 @@ PIP3='/usr/local/bin/pip-3.8'
 PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache 
cdrkit-genisoimage 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 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 zstd'
 PYPI_PKGS=''
 PYTHON='/usr/local/bin/python3'
+# As a final step configure the user (if env is defined)
+ARG USER
+ARG UID
+RUN if [ "${USER}" ]; then \
+  id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
\ No newline at end of file
diff --git a/.gitlab-ci.d/cirrus/macos-12.vars 
b/.gitlab-ci.d/cirrus/macos-12.vars
index da6aa6469b..599e210707 100644
--- a/.gitlab-ci.d/cirrus/macos-12.vars
+++ b/.gitlab-ci.d/cirrus/macos-12.vars
@@ -14,3 +14,8 @@ 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 ncurses nettle ninja pixman pkg-config python3 
rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol tesseract usbredir 
vde vte3 zlib zstd'
 PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme'
 PYTHON='/opt/homebrew/bin/python3'
+# As a final step configure the user (if env is defined)
+ARG USER
+ARG UID
+RUN if [ "${USER}" ]; then \
+  id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
\ No newline at end of file
diff --git a/tests/docker/dockerfiles/alpine.docker 
b/tests/docker/dockerfiles/alpine.docker
index 56cf14e553..7b82dec8e5 100644
--- a/tests/docker/dockerfiles/alpine.docker
+++ b/tests/docker/dockerfiles/alpine.docker
@@ -124,3 +124,8 @@ ENV LANG "en_US.UTF-8"
 ENV MAKE "/usr/bin/make"
 ENV NINJA "/usr/bin/ninja"
 ENV PYTHON 

Re: [PATCH v2 2/3] qapi: use env var to trigger qapi test output updates

2023-02-24 Thread Eric Blake
On Thu, Feb 23, 2023 at 01:40:26PM +, Daniel P. Berrangé wrote:
> It is possible to pass --update to tests/qapi-schema/test-qapi.py
> to make it update the output files on error. This is inconvient

inconvenient

> to achieve though when test-qapi.py is run indirectly by make/meson.
> 
> Instead simply allow for an env variable to be set:
> 
>  $ QAPI_TEST_UPDATE=1 make check-qapi-schema
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  tests/qapi-schema/test-qapi.py | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
> index 2160cef082..75f2759fd6 100755
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -215,7 +215,8 @@ def main(argv):
>  (dir_name, base_name) = os.path.split(t)
>  dir_name = dir_name or args.dir
>  test_name = os.path.splitext(base_name)[0]
> -status |= test_and_diff(test_name, dir_name, args.update)
> +update = args.update or "QAPI_TEST_UPDATE" in os.environ
> +status |= test_and_diff(test_name, dir_name, update)

Reviewed-by: Eric Blake 

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




Re: [PATCH v2 17/20] vfio/common: Support device dirty page tracking with vIOMMU

2023-02-24 Thread Joao Martins
On 24/02/2023 15:56, Alex Williamson wrote:
> On Fri, 24 Feb 2023 12:53:26 +
> Joao Martins  wrote:
> 
>> On 24/02/2023 11:25, Joao Martins wrote:
>>> On 23/02/2023 23:26, Jason Gunthorpe wrote:  
 On Thu, Feb 23, 2023 at 03:33:09PM -0700, Alex Williamson wrote:  
> On Thu, 23 Feb 2023 16:55:54 -0400
> Jason Gunthorpe  wrote:  
>> On Thu, Feb 23, 2023 at 01:06:33PM -0700, Alex Williamson wrote:
>> Or even better figure out how to get interrupt remapping without IOMMU
>> support :\  
>
> -machine q35,default_bus_bypass_iommu=on,kernel-irqchip=split \
> -device intel-iommu,caching-mode=on,intremap=on  

 Joao?

 If this works lets just block migration if the vIOMMU is turned on..  
>>>
>>> At a first glance, this looked like my regular iommu incantation.
>>>
>>> But reading the code this ::bypass_iommu (new to me) apparently tells that
>>> vIOMMU is bypassed or not for the PCI devices all the way to avoiding
>>> enumerating in the IVRS/DMAR ACPI tables. And I see VFIO double-checks 
>>> whether
>>> PCI device is within the IOMMU address space (or bypassed) prior to DMA 
>>> maps and
>>> such.
>>>
>>> You can see from the other email that all of the other options in my head 
>>> were
>>> either bit inconvenient or risky. I wasn't aware of this option for what is
>>> worth -- much simpler, should work!
>>>  
>>
>> I say *should*, but on a second thought interrupt remapping may still be
>> required to one of these devices that are IOMMU-bypassed. Say to put 
>> affinities
>> to vcpus above 255? I was trying this out with more than 255 vcpus with a 
>> couple
>> VFs and at a first glance these VFs fail to probe (these are CX6 VFs).
>>
>> It is a working setup without the parameter, but now adding a
>> default_bus_bypass_iommu=on fails to init VFs:
>>
>> [   32.412733] mlx5_core :00:02.0: Rate limit: 127 rates are supported,
>> range: 0Mbps to 97656Mbps
>> [   32.416242] mlx5_core :00:02.0: mlx5_load:1204:(pid 3361): Failed to
>> alloc IRQs
>> [   33.227852] mlx5_core :00:02.0: probe_one:1684:(pid 3361): 
>> mlx5_init_one
>> failed with error code -19
>> [   33.242182] mlx5_core :00:03.0: firmware version: 22.31.1660
>> [   33.415876] mlx5_core :00:03.0: Rate limit: 127 rates are supported,
>> range: 0Mbps to 97656Mbps
>> [   33.448016] mlx5_core :00:03.0: mlx5_load:1204:(pid 3361): Failed to
>> alloc IRQs
>> [   34.207532] mlx5_core :00:03.0: probe_one:1684:(pid 3361): 
>> mlx5_init_one
>> failed with error code -19
>>
>> I haven't dived yet into why it fails.
> 
> Hmm, I was thinking this would only affect DMA, but on second thought
> I think the DRHD also describes the interrupt remapping hardware and
> while interrupt remapping is an optional feature of the DRHD, DMA
> remapping is always supported afaict.  I saw IR vectors in
> /proc/interrupts and thought it worked, but indeed an assigned device
> is having trouble getting vectors.
> 

AMD/IVRS might be a little different.

I also tried disabling dma-translation from IOMMU feature as I had mentioned in
another email, and that renders the same result as default_bus_bypass_iommu.

So it's either this KVM pv-op (which is not really interrupt remapping and it's
x86 specific) or full vIOMMU. The PV op[*] has the natural disadvantage of
requiring a compatible guest kernel.

[*] See, KVM_FEATURE_MSI_EXT_DEST_ID.

>>
>>> And avoiding vIOMMU simplifies the whole patchset too, if it's OK to add a 
>>> live
>>> migration blocker if `bypass_iommu` is off for any PCI device.
>>>   
>>
>> Still we could have for starters a live migration blocker until we revisit 
>> the
>> vIOMMU case ... should we deem that the default_bus_bypass_iommu=on or the
>> others I suggested as non-options?
> 
> I'm very uncomfortable presuming a vIOMMU usage model, especially when
> it leads to potentially untracked DMA if our assumptions are violated.

We can track DMA that got dirtied, but it doesn't mean that said DMA is mapped.
I don't think VFIO ties those two in? Like you can ask to track certain ranges,
but if it's in IOMMU then device gets target abort. Start dirty tracking,
doesn't imply that you allow such DMA

with vIOMMU it's just anything that falls outside the IOMMU mapped ranges (or
identity map) get always marked as dirty if it wasn't armed in the device dirty
tracker. It's a best effort basis -- as I don't think supporting vIOMMU has a
ton of options without a more significant compromise. If the vIOMMU is in
passthrough mode, then things work just as if no-vIOMMU is there. Avihai's code
reflects that.

Considering your earlier suggestion that we only start dirty tracking and record
ranges *when*  dirty tracking start operation happens ... then this gets further
simplified. We also have to take into account that we can't have guarantees that
we can change ranges under tracking to be dynamic.

For improving vIOMMU case we either track the MAX_IOVA or we compose an
artifical range based the 

Re: [PATCH v2 00/20] vfio: Add migration pre-copy support and device dirty tracking

2023-02-24 Thread Joao Martins



On 23/02/2023 14:56, Avihai Horon wrote:
> On 22/02/2023 22:55, Alex Williamson wrote:
>> There are various errors running this through the CI on gitlab.
>>
>> This one seems bogus but needs to be resolved regardless:
>>
>> https://gitlab.com/alex.williamson/qemu/-/jobs/3817940731
>> FAILED: libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o
>> 2786s390x-linux-gnu-gcc -m64 -Ilibqemu-aarch64-softmmu.fa.p -I. -I..
>> -Itarget/arm -I../target/arm -Iqapi -Itrace -Iui -Iui/shader
>> -I/usr/include/pixman-1 -I/usr/include/capstone -I/usr/include/glib-2.0
>> -I/usr/lib/s390x-linux-gnu/glib-2.0/include -fdiagnostics-color=auto -Wall
>> -Winvalid-pch -Werror -std=gnu11 -O2 -g -isystem
>> /builds/alex.williamson/qemu/linux-headers -isystem linux-headers -iquote .
>> -iquote /builds/alex.williamson/qemu -iquote
>> /builds/alex.williamson/qemu/include -iquote
>> /builds/alex.williamson/qemu/tcg/s390x -pthread -U_FORTIFY_SOURCE
>> -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
>> -fno-strict-aliasing -fno-common -fwrapv -Wundef -Wwrite-strings
>> -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls
>> -Wold-style-declaration -Wold-style-definition -Wtype-limits 
>> -Wformat-security
>> -Wformat-y2k -Winit-self -Wignored-qualifiers -Wempty-body -Wnested-externs
>> -Wendif-labels -Wexpansion-to-defined -Wimplicit-fallthrough=2
>> -Wmissing-format-attribute -Wno-missing-include-dirs 
>> -Wno-shift-negative-value
>> -Wno-psabi -fstack-protector-strong -fPIE -isystem../linux-headers
>> -isystemlinux-headers -DNEED_CPU_H
>> '-DCONFIG_TARGET="aarch64-softmmu-config-target.h"'
>> '-DCONFIG_DEVICES="aarch64-softmmu-config-devices.h"' -MD -MQ
>> libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o -MF
>> libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o.d -o
>> libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o -c ../hw/vfio/common.c
>> 2787../hw/vfio/common.c: In function ‘vfio_listener_log_global_start’:
>> 2788../hw/vfio/common.c:1772:8: error: ‘ret’ may be used uninitialized in 
>> this
>> function [-Werror=maybe-uninitialized]
>> 2789 1772 | if (ret) {
>> 2790  |    ^
>>
>> 32-bit builds have some actual errors though:
>>
>> https://gitlab.com/alex.williamson/qemu/-/jobs/3817940719
>> FAILED: libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o
>> 2601cc -m32 -Ilibqemu-aarch64-softmmu.fa.p -I. -I.. -Itarget/arm
>> -I../target/arm -Iqapi -Itrace -Iui -Iui/shader -I/usr/include/pixman-1
>> -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/sysprof-4
>> -fdiagnostics-color=auto -Wall -Winvalid-pch -Werror -std=gnu11 -O2 -g
>> -isystem /builds/alex.williamson/qemu/linux-headers -isystem linux-headers
>> -iquote . -iquote /builds/alex.williamson/qemu -iquote
>> /builds/alex.williamson/qemu/include -iquote
>> /builds/alex.williamson/qemu/tcg/i386 -pthread -U_FORTIFY_SOURCE
>> -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
>> -fno-strict-aliasing -fno-common -fwrapv -Wundef -Wwrite-strings
>> -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls
>> -Wold-style-declaration -Wold-style-definition -Wtype-limits 
>> -Wformat-security
>> -Wformat-y2k -Winit-self -Wignored-qualifiers -Wempty-body -Wnested-externs
>> -Wendif-labels -Wexpansion-to-defined -Wimplicit-fallthrough=2
>> -Wmissing-format-attribute -Wno-missing-include-dirs 
>> -Wno-shift-negative-value
>> -Wno-psabi -fstack-protector-strong -fPIE -isystem../linux-headers
>> -isystemlinux-headers -DNEED_CPU_H
>> '-DCONFIG_TARGET="aarch64-softmmu-config-target.h"'
>> '-DCONFIG_DEVICES="aarch64-softmmu-config-devices.h"' -MD -MQ
>> libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o -MF
>> libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o.d -o
>> libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o -c ../hw/vfio/common.c
>> 2602../hw/vfio/common.c: In function
>> 'vfio_device_feature_dma_logging_start_create':
>> 2603../hw/vfio/common.c:1572:27: error: cast from pointer to integer of
>> different size [-Werror=pointer-to-int-cast]
>> 2604 1572 | control->ranges = (uint64_t)ranges;
>> 2605  |   ^
>> 2606../hw/vfio/common.c:1596:23: error: cast from pointer to integer of
>> different size [-Werror=pointer-to-int-cast]
>> 2607 1596 | control->ranges = (uint64_t)ranges;
>> 2608  |   ^
>> 2609../hw/vfio/common.c: In function
>> 'vfio_device_feature_dma_logging_start_destroy':
>> 2610../hw/vfio/common.c:1620:9: error: cast to pointer from integer of
>> different size [-Werror=int-to-pointer-cast]
>> 2611 1620 | (struct vfio_device_feature_dma_logging_range
>> *)control->ranges;
>> 2612  | ^
>> 2613../hw/vfio/common.c: In function 'vfio_device_dma_logging_report':
>> 2614../hw/vfio/common.c:1810:22: error: cast from pointer to integer of
>> different size [-Werror=pointer-to-int-cast]
>> 2615 1810 | report->bitmap = (uint64_t)bitmap;
>> 2616  |  ^
> 
> Sure, I will fix these errors.

Just a thought: 

Re: [RFC PATCH 10/43] target/loongarch: Implement vaddw/vsubw

2023-02-24 Thread Richard Henderson

On 2/23/23 21:24, gaosong wrote:
I was wrong, the instruction is to sign-extend the odd or even elements of the vector 
before the operation, not to sign-extend the result.

E.g
vaddwev_h_b  vd, vj, vk
vd->H[i] = SignExtend(vj->B[2i])  + SignExtend(vk->B[2i]);
vaddwev_w_h  vd, vj, vk
vd->W[i] = SignExtend(vj->H[2i])  + SignExtend(vk->H[2i]);
vaddwev_d_w  vd, vj, vk
vd->Q[i] = SignExtend(vj->W[2i])  + SignExtend(vk->W[2i]);
vaddwev_q_d  vd, vj, vk
vd->Q[i] = SignExtend(vj->D[2i])  + SignExtend(vk->D[2i]);


Ok, good example.


static void gen_vaddwev_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
{
     TCGv_vec t1 = tcg_temp_new_vec_matching(a);
     TCGv_vec t2 = tcg_temp_new_vec_matching(b);

     int halfbits  =  4 << vece;

     /* Sign-extend even elements from a */
     tcg_gen_dupi_vec(vece, t1, MAKE_64BIT_MASK(0, halfbits));
     tcg_gen_and_vec(vece, a, a, t1);


No need to mask off these bits...


     tcg_gen_shli_vec(vece, a, a, halfbits);


... because they shift out here anyway.


     tcg_gen_sari_vec(vece, a, a, halfbits);

     /* Sign-extend even elements from b */
     tcg_gen_dupi_vec(vece, t2, MAKE_64BIT_MASK(0, halfbits));
     tcg_gen_and_vec(vece, b, b, t2);
     tcg_gen_shli_vec(vece, b, b, halfbits);
     tcg_gen_sari_vec(vece,  b, b, halfbits);

     tcg_gen_add_vec(vece, t, a, b);

     tcg_temp_free_vec(t1);
     tcg_temp_free_vec(t2);
}


Otherwise this looks good.


     {
     .fniv = gen_vaddwev_s,
     .fno = gen_helper_vaddwev_q_d,
     .opt_opc = vecop_list,
     .vece = MO_128
     },


There are no 128-bit vector operations; you'll need to do this one differently.

Presumably just load the two 64-bit elements, sign-extend into 128-bits, add with 
tcg_gen_add2_i64, and store the two 64-bit elements as output.  But that won't fit into 
the tcg_gen_gvec_3 interface.



r~



Re: question: QEMU guest with Virtiofs but without virtiofsd

2023-02-24 Thread Ferenc Fejes
Hi Stefan!

On Fri, Feb 24, 2023 at 6:23 PM Stefan Hajnoczi  wrote:
>
> On Fri, 24 Feb 2023 at 11:47, Ferenc Fejes  wrote:
> > I'm using a QEMU VM with a debootstrap rootfs, shared over virtiofs for
> > the guest. My best understanding is that virtiofsd must required even
> > if just using one guest.
>
> Yes, virtiofsd is required even if just one guest is accessing a
> shared directory using a virtiofs device. The virtiofsd daemon is
> responsible for emulating the virtiofs device (QEMU does not do the
> emulation), so that's why it's essential even with just a single
> guest.
>
> > Looking around in the QEMU manpages I got a little bit confused by
> > virtfs parameter. Is it something entirely connected with 9P or it is
> > possible to pass folders to the guest through virtiofs without
> > virtiofsd? Unfortunately none of my trial with the parameters
> > succeeded.
>
> There are two separate VIRTIO devices for sharing files/directories:
> virtiofs and virtio-9p (sometimes called virtfs). It's easy to confuse
> them because "virtiofs" and "virtfs" look similar. They have different
> features and are completely independent of each other. In terms of the
> file system protocol, virtiofs is based on Linux FUSE while virtio-9p
> is based on the 9P protocol.

Thank you for the clarification! No wonder that my commands failed to work.
As a very occasional user of QEMU I those two (and their parameters)
looked very similar to me.

>
> virtiofs uses the --device vhost-user-fs-pci syntax together with a
> virtiofsd process.
>
> virtio-9p uses either the full --device virtio-9p-pci and --fsdev
> syntax or the shortcut --virtfs syntax that combines both these
> options.
>
> > Could someone can give me a confirmation if virtiofsd is must or its
> > optional. Thanks in advance!
>
> If you want to use virtiofs then virtiofsd is required.
>
> If you use virtio-9p then virtiofsd is not needed.
>
> In terms of which one you should use, both are widely used today.
> Unless you have specific requirements, I think you can choose
> whichever one seems most convenient to you.

I think I stick with the virtiofs+virtiofsd. Most QEMU features I need
shipped with 1-2 years old distros and can be installed from repos, so
I dont need to bother with building it.

Thanks again for the detailed explanation!

>
> Stefan

Best,
Ferenc



[PATCH v3 06/15] audio: rename variables in audio_pcm_sw_write()

2023-02-24 Thread Volker Rümelin
The audio_pcm_sw_write() function uses a lot of very unspecific
variable names. Rename them for better readability.

ret => total_in
total => total_out
size => buf_len
hwsamples => hw->mix_buf.size
samples => frames_in_max

Acked-by: Mark Cave-Ayland 
Reviewed-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c | 45 ++---
 1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 8f1c0e77b0..cd10f1ec10 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -706,56 +706,55 @@ static void audio_pcm_sw_resample_out(SWVoiceOut *sw,
 }
 }
 
-static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)
+static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t buf_len)
 {
-size_t hwsamples, samples, live, dead;
-size_t hw_free;
-size_t ret, total;
-
-hwsamples = sw->hw->mix_buf.size;
+HWVoiceOut *hw = sw->hw;
+size_t live, dead, hw_free;
+size_t frames_in_max, total_in, total_out;
 
 live = sw->total_hw_samples_mixed;
-if (audio_bug(__func__, live > hwsamples)) {
-dolog("live=%zu hw->mix_buf.size=%zu\n", live, hwsamples);
+if (audio_bug(__func__, live > hw->mix_buf.size)) {
+dolog("live=%zu hw->mix_buf.size=%zu\n", live, hw->mix_buf.size);
 return 0;
 }
 
-if (live == hwsamples) {
+if (live == hw->mix_buf.size) {
 #ifdef DEBUG_OUT
 dolog ("%s is full %zu\n", sw->name, live);
 #endif
 return 0;
 }
 
-dead = hwsamples - live;
-hw_free = audio_pcm_hw_get_free(sw->hw);
+dead = hw->mix_buf.size - live;
+hw_free = audio_pcm_hw_get_free(hw);
 hw_free = hw_free > live ? hw_free - live : 0;
-samples = ((int64_t)MIN(dead, hw_free) << 32) / sw->ratio;
-samples = MIN(samples, size / sw->info.bytes_per_frame);
-if (samples) {
-sw->conv(sw->resample_buf.buffer, buf, samples);
+frames_in_max = ((int64_t)MIN(dead, hw_free) << 32) / sw->ratio;
+frames_in_max = MIN(frames_in_max, buf_len / sw->info.bytes_per_frame);
+if (frames_in_max) {
+sw->conv(sw->resample_buf.buffer, buf, frames_in_max);
 
 if (!sw->hw->pcm_ops->volume_out) {
-mixeng_volume(sw->resample_buf.buffer, samples, >vol);
+mixeng_volume(sw->resample_buf.buffer, frames_in_max, >vol);
 }
 }
 
-audio_pcm_sw_resample_out(sw, samples, MIN(dead, hw_free), , );
+audio_pcm_sw_resample_out(sw, frames_in_max, MIN(dead, hw_free),
+  _in, _out);
 
-sw->total_hw_samples_mixed += total;
+sw->total_hw_samples_mixed += total_out;
 sw->empty = sw->total_hw_samples_mixed == 0;
 
 #ifdef DEBUG_OUT
 dolog (
-"%s: write size %zu ret %zu total sw %zu\n",
-SW_NAME (sw),
-size / sw->info.bytes_per_frame,
-ret,
+"%s: write size %zu written %zu total mixed %zu\n",
+SW_NAME(sw),
+buf_len / sw->info.bytes_per_frame,
+total_in,
 sw->total_hw_samples_mixed
 );
 #endif
 
-return ret * sw->info.bytes_per_frame;
+return total_in * sw->info.bytes_per_frame;
 }
 
 #ifdef DEBUG_AUDIO
-- 
2.35.3




[PATCH v3 11/15] audio: rename variables in audio_pcm_sw_read()

2023-02-24 Thread Volker Rümelin
The audio_pcm_sw_read() function uses a few very unspecific
variable names. Rename them for better readability.

ret => total_out
total => total_in
size => buf_len
samples => frames_out_max

Acked-by: Mark Cave-Ayland 
Reviewed-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 9e9c03a42e..22c36d6660 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -576,10 +576,10 @@ static void audio_pcm_sw_resample_in(SWVoiceIn *sw,
 }
 }
 
-static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)
+static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t buf_len)
 {
 HWVoiceIn *hw = sw->hw;
-size_t samples, live, ret, swlim, total;
+size_t live, frames_out_max, swlim, total_in, total_out;
 
 live = hw->total_samples_captured - sw->total_hw_samples_acquired;
 if (!live) {
@@ -590,20 +590,20 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, 
size_t size)
 return 0;
 }
 
-samples = size / sw->info.bytes_per_frame;
+frames_out_max = buf_len / sw->info.bytes_per_frame;
 
 swlim = (live * sw->ratio) >> 32;
-swlim = MIN (swlim, samples);
+swlim = MIN(swlim, frames_out_max);
 
-audio_pcm_sw_resample_in(sw, live, swlim, , );
+audio_pcm_sw_resample_in(sw, live, swlim, _in, _out);
 
 if (!hw->pcm_ops->volume_in) {
-mixeng_volume(sw->resample_buf.buffer, ret, >vol);
+mixeng_volume(sw->resample_buf.buffer, total_out, >vol);
 }
+sw->clip(buf, sw->resample_buf.buffer, total_out);
 
-sw->clip(buf, sw->resample_buf.buffer, ret);
-sw->total_hw_samples_acquired += total;
-return ret * sw->info.bytes_per_frame;
+sw->total_hw_samples_acquired += total_in;
+return total_out * sw->info.bytes_per_frame;
 }
 
 /*
-- 
2.35.3




[PATCH v3 05/15] audio: remove sw == NULL check

2023-02-24 Thread Volker Rümelin
All call sites of audio_pcm_sw_write() guarantee that sw is not
NULL. Remove the unnecessary NULL check.

Acked-by: Mark Cave-Ayland 
Reviewed-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 4412b5fad8..8f1c0e77b0 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -712,10 +712,6 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void 
*buf, size_t size)
 size_t hw_free;
 size_t ret, total;
 
-if (!sw) {
-return size;
-}
-
 hwsamples = sw->hw->mix_buf.size;
 
 live = sw->total_hw_samples_mixed;
-- 
2.35.3




[PATCH v3 01/15] audio: change type of mix_buf and conv_buf

2023-02-24 Thread Volker Rümelin
Change the type of mix_buf in struct HWVoiceOut and conv_buf
in struct HWVoiceIn from STSampleBuffer * to STSampleBuffer.
However, a buffer pointer is still needed. For this reason in
struct STSampleBuffer samples[] is changed to *buffer.

This is a preparation for the next patch. The next patch will
add this line, which is not possible with the current struct
STSampleBuffer definition.

+sw->resample_buf.buffer = hw->mix_buf.buffer + rpos2;

There are no functional changes.

Acked-by: Mark Cave-Ayland 
Reviewed-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c  | 106 -
 audio/audio_int.h  |   6 +--
 audio/audio_template.h |  19 
 3 files changed, 67 insertions(+), 64 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 772c3cc320..a0b54e4a2e 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -523,8 +523,8 @@ static size_t audio_pcm_hw_find_min_in (HWVoiceIn *hw)
 static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw)
 {
 size_t live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
-if (audio_bug(__func__, live > hw->conv_buf->size)) {
-dolog("live=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
+if (audio_bug(__func__, live > hw->conv_buf.size)) {
+dolog("live=%zu hw->conv_buf.size=%zu\n", live, hw->conv_buf.size);
 return 0;
 }
 return live;
@@ -533,13 +533,13 @@ static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw)
 static size_t audio_pcm_hw_conv_in(HWVoiceIn *hw, void *pcm_buf, size_t 
samples)
 {
 size_t conv = 0;
-STSampleBuffer *conv_buf = hw->conv_buf;
+STSampleBuffer *conv_buf = >conv_buf;
 
 while (samples) {
 uint8_t *src = advance(pcm_buf, conv * hw->info.bytes_per_frame);
 size_t proc = MIN(samples, conv_buf->size - conv_buf->pos);
 
-hw->conv(conv_buf->samples + conv_buf->pos, src, proc);
+hw->conv(conv_buf->buffer + conv_buf->pos, src, proc);
 conv_buf->pos = (conv_buf->pos + proc) % conv_buf->size;
 samples -= proc;
 conv += proc;
@@ -561,12 +561,12 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, 
size_t size)
 if (!live) {
 return 0;
 }
-if (audio_bug(__func__, live > hw->conv_buf->size)) {
-dolog("live_in=%zu hw->conv_buf->size=%zu\n", live, 
hw->conv_buf->size);
+if (audio_bug(__func__, live > hw->conv_buf.size)) {
+dolog("live_in=%zu hw->conv_buf.size=%zu\n", live, hw->conv_buf.size);
 return 0;
 }
 
-rpos = audio_ring_posb(hw->conv_buf->pos, live, hw->conv_buf->size);
+rpos = audio_ring_posb(hw->conv_buf.pos, live, hw->conv_buf.size);
 
 samples = size / sw->info.bytes_per_frame;
 
@@ -574,11 +574,11 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, 
size_t size)
 swlim = MIN (swlim, samples);
 
 while (swlim) {
-src = hw->conv_buf->samples + rpos;
-if (hw->conv_buf->pos > rpos) {
-isamp = hw->conv_buf->pos - rpos;
+src = hw->conv_buf.buffer + rpos;
+if (hw->conv_buf.pos > rpos) {
+isamp = hw->conv_buf.pos - rpos;
 } else {
-isamp = hw->conv_buf->size - rpos;
+isamp = hw->conv_buf.size - rpos;
 }
 
 if (!isamp) {
@@ -588,7 +588,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, 
size_t size)
 
 st_rate_flow (sw->rate, src, dst, , );
 swlim -= osamp;
-rpos = (rpos + isamp) % hw->conv_buf->size;
+rpos = (rpos + isamp) % hw->conv_buf.size;
 dst += osamp;
 ret += osamp;
 total += isamp;
@@ -636,8 +636,8 @@ static size_t audio_pcm_hw_get_live_out (HWVoiceOut *hw, 
int *nb_live)
 if (nb_live1) {
 size_t live = smin;
 
-if (audio_bug(__func__, live > hw->mix_buf->size)) {
-dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size);
+if (audio_bug(__func__, live > hw->mix_buf.size)) {
+dolog("live=%zu hw->mix_buf.size=%zu\n", live, hw->mix_buf.size);
 return 0;
 }
 return live;
@@ -654,17 +654,17 @@ static size_t audio_pcm_hw_get_free(HWVoiceOut *hw)
 static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, size_t len)
 {
 size_t clipped = 0;
-size_t pos = hw->mix_buf->pos;
+size_t pos = hw->mix_buf.pos;
 
 while (len) {
-st_sample *src = hw->mix_buf->samples + pos;
+st_sample *src = hw->mix_buf.buffer + pos;
 uint8_t *dst = advance(pcm_buf, clipped * hw->info.bytes_per_frame);
-size_t samples_till_end_of_buf = hw->mix_buf->size - pos;
+size_t samples_till_end_of_buf = hw->mix_buf.size - pos;
 size_t samples_to_clip = MIN(len, samples_till_end_of_buf);
 
 hw->clip(dst, src, samples_to_clip);
 
-pos = (pos + samples_to_clip) % hw->mix_buf->size;
+pos = (pos + samples_to_clip) % hw->mix_buf.size;
 len -= 

[PATCH v3 09/15] audio: make playback packet length calculation exact

2023-02-24 Thread Volker Rümelin
Introduce the new function st_rate_frames_in() to calculate the
exact number of audio input frames needed to get a given number
of audio output frames. The exact number of frames depends only
on the difference of opos - ipos and the number of output frames.
When downsampling, this function returns the maximum number of
input frames needed.

This new function replaces the audio_frontend_frames_out() function,
which calculated the average number of input frames rounded down
to the nearest integer. Because audio_frontend_frames_out() also
limited the number of input frames to the size of the resample
buffer, st_rate_frames_in() is not a direct replacement and two
additional MIN() functions are needed. One to prevent resample
buffer overflows and one to limit the available bytes for the audio
frontends.

After this patch the audio packet length calculation for playback is
exact. When upsampling, it's still possible that the audio frontends
can't write the last audio frame. This will be fixed later.

Acked-by: Mark Cave-Ayland 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c  | 43 ++-
 audio/mixeng.c | 39 +++
 audio/mixeng.h |  1 +
 3 files changed, 58 insertions(+), 25 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 556696b095..e18b5e98c5 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -701,8 +701,8 @@ static void audio_pcm_sw_resample_out(SWVoiceOut *sw,
 static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t buf_len)
 {
 HWVoiceOut *hw = sw->hw;
-size_t live, dead, hw_free;
-size_t frames_in_max, total_in, total_out;
+size_t live, dead, hw_free, sw_max, fe_max;
+size_t frames_in_max, frames_out_max, total_in, total_out;
 
 live = sw->total_hw_samples_mixed;
 if (audio_bug(__func__, live > hw->mix_buf.size)) {
@@ -720,17 +720,21 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void 
*buf, size_t buf_len)
 dead = hw->mix_buf.size - live;
 hw_free = audio_pcm_hw_get_free(hw);
 hw_free = hw_free > live ? hw_free - live : 0;
-frames_in_max = ((int64_t)MIN(dead, hw_free) << 32) / sw->ratio;
-frames_in_max = MIN(frames_in_max, buf_len / sw->info.bytes_per_frame);
-if (frames_in_max) {
-sw->conv(sw->resample_buf.buffer, buf, frames_in_max);
+frames_out_max = MIN(dead, hw_free);
+sw_max = st_rate_frames_in(sw->rate, frames_out_max);
+fe_max = MIN(buf_len / sw->info.bytes_per_frame, sw->resample_buf.size);
+frames_in_max = MIN(sw_max, fe_max);
 
-if (!sw->hw->pcm_ops->volume_out) {
-mixeng_volume(sw->resample_buf.buffer, frames_in_max, >vol);
-}
+if (!frames_in_max) {
+return 0;
 }
 
-audio_pcm_sw_resample_out(sw, frames_in_max, MIN(dead, hw_free),
+sw->conv(sw->resample_buf.buffer, buf, frames_in_max);
+if (!sw->hw->pcm_ops->volume_out) {
+mixeng_volume(sw->resample_buf.buffer, frames_in_max, >vol);
+}
+
+audio_pcm_sw_resample_out(sw, frames_in_max, frames_out_max,
   _in, _out);
 
 sw->total_hw_samples_mixed += total_out;
@@ -1000,18 +1004,6 @@ static size_t audio_get_avail (SWVoiceIn *sw)
 return live;
 }
 
-/**
- * audio_frontend_frames_out() - returns the number of frames needed to
- * get frames_out frames after resampling
- *
- * @sw: audio playback frontend
- * @frames_out: number of frames
- */
-static size_t audio_frontend_frames_out(SWVoiceOut *sw, size_t frames_out)
-{
-return ((int64_t)frames_out << 32) / sw->ratio;
-}
-
 static size_t audio_get_free(SWVoiceOut *sw)
 {
 size_t live, dead;
@@ -1031,8 +1023,8 @@ static size_t audio_get_free(SWVoiceOut *sw)
 dead = sw->hw->mix_buf.size - live;
 
 #ifdef DEBUG_OUT
-dolog("%s: get_free live %zu dead %zu frontend frames %zu\n",
-  SW_NAME(sw), live, dead, audio_frontend_frames_out(sw, dead));
+dolog("%s: get_free live %zu dead %zu frontend frames %u\n",
+  SW_NAME(sw), live, dead, st_rate_frames_in(sw->rate, dead));
 #endif
 
 return dead;
@@ -1161,12 +1153,13 @@ static void audio_run_out (AudioState *s)
 size_t free;
 
 if (hw_free > sw->total_hw_samples_mixed) {
-free = audio_frontend_frames_out(sw,
+free = st_rate_frames_in(sw->rate,
 MIN(sw_free, hw_free - sw->total_hw_samples_mixed));
 } else {
 free = 0;
 }
 if (free > 0) {
+free = MIN(free, sw->resample_buf.size);
 sw->callback.fn(sw->callback.opaque,
 free * sw->info.bytes_per_frame);
 }
diff --git a/audio/mixeng.c b/audio/mixeng.c
index fe454e0725..a24c8c45a7 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -440,6 +440,45 @@ void st_rate_stop (void *opaque)
 g_free (opaque);
 }
 
+/**
+ * st_rate_frames_in() - 

[PATCH v3 14/15] audio/audio_template: substitute sw->hw with hw

2023-02-24 Thread Volker Rümelin
Substitute sw->hw with hw in the audio_pcm_sw_alloc_resources_*
functions.

Acked-by: Mark Cave-Ayland 
Reviewed-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio_template.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/audio/audio_template.h b/audio/audio_template.h
index 0d8aab6fad..7e116426c7 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -107,6 +107,7 @@ static void glue (audio_pcm_sw_free_resources_, TYPE) (SW 
*sw)
 
 static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
 {
+HW *hw = sw->hw;
 int samples;
 
 if (!glue(audio_get_pdo_, TYPE)(sw->s->dev)->mixing_engine) {
@@ -125,7 +126,6 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW 
*sw)
 }
 
 if (samples == 0) {
-HW *hw = sw->hw;
 size_t f_fe_min;
 
 /* f_fe_min = ceil(1 [frames] * f_be [Hz] / size_be [frames]) */
@@ -149,9 +149,9 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW 
*sw)
 sw->resample_buf.pos = 0;
 
 #ifdef DAC
-sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
+sw->rate = st_rate_start(sw->info.freq, hw->info.freq);
 #else
-sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
+sw->rate = st_rate_start(hw->info.freq, sw->info.freq);
 #endif
 
 return 0;
-- 
2.35.3




[PATCH v3 13/15] audio: handle leftover audio frame from upsampling

2023-02-24 Thread Volker Rümelin
Upsampling may leave one remaining audio frame in the input
buffer. The emulated audio playback devices are currently
resposible to write this audio frame again in the next write
cycle. Push that task down to audio_pcm_sw_write.

This is another step towards an audio callback interface that
guarantees that when audio frontends are told they can write
n audio frames, they can actually do so.

Acked-by: Mark Cave-Ayland 
Acked-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c  | 34 --
 audio/audio_template.h |  6 ++
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index dad17e59b8..4836ab8ca8 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -731,16 +731,21 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void 
*buf, size_t buf_len)
 hw_free = hw_free > live ? hw_free - live : 0;
 frames_out_max = MIN(dead, hw_free);
 sw_max = st_rate_frames_in(sw->rate, frames_out_max);
-fe_max = MIN(buf_len / sw->info.bytes_per_frame, sw->resample_buf.size);
+fe_max = MIN(buf_len / sw->info.bytes_per_frame + sw->resample_buf.pos,
+ sw->resample_buf.size);
 frames_in_max = MIN(sw_max, fe_max);
 
 if (!frames_in_max) {
 return 0;
 }
 
-sw->conv(sw->resample_buf.buffer, buf, frames_in_max);
-if (!sw->hw->pcm_ops->volume_out) {
-mixeng_volume(sw->resample_buf.buffer, frames_in_max, >vol);
+if (frames_in_max > sw->resample_buf.pos) {
+sw->conv(sw->resample_buf.buffer + sw->resample_buf.pos,
+ buf, frames_in_max - sw->resample_buf.pos);
+if (!sw->hw->pcm_ops->volume_out) {
+mixeng_volume(sw->resample_buf.buffer + sw->resample_buf.pos,
+  frames_in_max - sw->resample_buf.pos, >vol);
+}
 }
 
 audio_pcm_sw_resample_out(sw, frames_in_max, frames_out_max,
@@ -749,6 +754,22 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void 
*buf, size_t buf_len)
 sw->total_hw_samples_mixed += total_out;
 sw->empty = sw->total_hw_samples_mixed == 0;
 
+/*
+ * Upsampling may leave one audio frame in the resample buffer. Decrement
+ * total_in by one if there was a leftover frame from the previous resample
+ * pass in the resample buffer. Increment total_in by one if the current
+ * resample pass left one frame in the resample buffer.
+ */
+if (frames_in_max - total_in == 1) {
+/* copy one leftover audio frame to the beginning of the buffer */
+*sw->resample_buf.buffer = *(sw->resample_buf.buffer + total_in);
+total_in += 1 - sw->resample_buf.pos;
+sw->resample_buf.pos = 1;
+} else if (total_in >= sw->resample_buf.pos) {
+total_in -= sw->resample_buf.pos;
+sw->resample_buf.pos = 0;
+}
+
 #ifdef DEBUG_OUT
 dolog (
 "%s: write size %zu written %zu total mixed %zu\n",
@@ -1155,8 +1176,9 @@ static void audio_run_out (AudioState *s)
 } else {
 free = 0;
 }
-if (free > 0) {
-free = MIN(free, sw->resample_buf.size);
+if (free > sw->resample_buf.pos) {
+free = MIN(free, sw->resample_buf.size)
+   - sw->resample_buf.pos;
 sw->callback.fn(sw->callback.opaque,
 free * sw->info.bytes_per_frame);
 }
diff --git a/audio/audio_template.h b/audio/audio_template.h
index a0b653f52c..0d8aab6fad 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -138,6 +138,12 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW 
*sw)
 return -1;
 }
 
+/*
+ * Allocate one additional audio frame that is needed for upsampling
+ * if the resample buffer size is small. For large buffer sizes take
+ * care of overflows.
+ */
+samples = samples < INT_MAX ? samples + 1 : INT_MAX;
 sw->resample_buf.buffer = g_new0(st_sample, samples);
 sw->resample_buf.size = samples;
 sw->resample_buf.pos = 0;
-- 
2.35.3




[PATCH v3 07/15] audio: don't misuse audio_pcm_sw_write()

2023-02-24 Thread Volker Rümelin
The audio_pcm_sw_write() function is intended to convert a
PCM audio stream to the internal representation, adjust the
volume, and then mix it with the other audio streams with a
possibly changed sample rate in mix_buf. In order for the
audio_capture_mix_and_clear() function to use audio_pcm_sw_write(),
it must bypass the first two tasks of audio_pcm_sw_write().

Since patch "audio: split out the resampling loop in
audio_pcm_sw_write()" this is no longer necessary, because now
the audio_pcm_sw_resample_out() function can be used instead of
audio_pcm_sw_write().

Acked-by: Mark Cave-Ayland 
Acked-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c | 29 ++---
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index cd10f1ec10..44eb7b63b4 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1056,26 +1056,33 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, 
size_t rpos,
 
 for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
 SWVoiceOut *sw = >sw;
-int rpos2 = rpos;
+size_t rpos2 = rpos;
 
 n = samples;
 while (n) {
 size_t till_end_of_hw = hw->mix_buf.size - rpos2;
-size_t to_write = MIN(till_end_of_hw, n);
-size_t bytes = to_write * hw->info.bytes_per_frame;
-size_t written;
+size_t to_read = MIN(till_end_of_hw, n);
+size_t live, frames_in, frames_out;
 
 sw->resample_buf.buffer = hw->mix_buf.buffer + rpos2;
-sw->resample_buf.size = to_write;
-written = audio_pcm_sw_write (sw, NULL, bytes);
-if (written - bytes) {
-dolog("Could not mix %zu bytes into a capture "
+sw->resample_buf.size = to_read;
+live = sw->total_hw_samples_mixed;
+
+audio_pcm_sw_resample_out(sw,
+  to_read, sw->hw->mix_buf.size - live,
+  _in, _out);
+
+sw->total_hw_samples_mixed += frames_out;
+sw->empty = sw->total_hw_samples_mixed == 0;
+
+if (to_read - frames_in) {
+dolog("Could not mix %zu frames into a capture "
   "buffer, mixed %zu\n",
-  bytes, written);
+  to_read, frames_in);
 break;
 }
-n -= to_write;
-rpos2 = (rpos2 + to_write) % hw->mix_buf.size;
+n -= to_read;
+rpos2 = (rpos2 + to_read) % hw->mix_buf.size;
 }
 }
 }
-- 
2.35.3




[PATCH v3 12/15] audio: make recording packet length calculation exact

2023-02-24 Thread Volker Rümelin
Introduce the new function st_rate_frames_out() to calculate the
exact number of audio output frames the resampling code can
generate from a given number of audio input frames. When upsampling,
this function returns the maximum number of output frames.

This new function replaces the audio_frontend_frames_in()
function, which calculated the average number of output frames
rounded down to the nearest integer. The audio_frontend_frames_in()
function was additionally used to limit the number of output frames
to the resample buffer size. In audio_pcm_sw_read() the variable
resample_buf.size replaces the open coded audio_frontend_frames_in()
function. In audio_run_in() an additional MIN() function is
necessary.

After this patch the audio packet length calculation for audio
recording is exact.

Acked-by: Mark Cave-Ayland 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c  | 29 -
 audio/mixeng.c | 41 +
 audio/mixeng.h |  1 +
 3 files changed, 50 insertions(+), 21 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 22c36d6660..dad17e59b8 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -579,7 +579,7 @@ static void audio_pcm_sw_resample_in(SWVoiceIn *sw,
 static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t buf_len)
 {
 HWVoiceIn *hw = sw->hw;
-size_t live, frames_out_max, swlim, total_in, total_out;
+size_t live, frames_out_max, total_in, total_out;
 
 live = hw->total_samples_captured - sw->total_hw_samples_acquired;
 if (!live) {
@@ -590,12 +590,10 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, 
size_t buf_len)
 return 0;
 }
 
-frames_out_max = buf_len / sw->info.bytes_per_frame;
+frames_out_max = MIN(buf_len / sw->info.bytes_per_frame,
+ sw->resample_buf.size);
 
-swlim = (live * sw->ratio) >> 32;
-swlim = MIN(swlim, frames_out_max);
-
-audio_pcm_sw_resample_in(sw, live, swlim, _in, _out);
+audio_pcm_sw_resample_in(sw, live, frames_out_max, _in, _out);
 
 if (!hw->pcm_ops->volume_in) {
 mixeng_volume(sw->resample_buf.buffer, total_out, >vol);
@@ -979,18 +977,6 @@ void AUD_set_active_in (SWVoiceIn *sw, int on)
 }
 }
 
-/**
- * audio_frontend_frames_in() - returns the number of frames the resampling
- * code generates from frames_in frames
- *
- * @sw: audio recording frontend
- * @frames_in: number of frames
- */
-static size_t audio_frontend_frames_in(SWVoiceIn *sw, size_t frames_in)
-{
-return (int64_t)frames_in * sw->ratio >> 32;
-}
-
 static size_t audio_get_avail (SWVoiceIn *sw)
 {
 size_t live;
@@ -1007,9 +993,9 @@ static size_t audio_get_avail (SWVoiceIn *sw)
 }
 
 ldebug (
-"%s: get_avail live %zu frontend frames %zu\n",
+"%s: get_avail live %zu frontend frames %u\n",
 SW_NAME (sw),
-live, audio_frontend_frames_in(sw, live)
+live, st_rate_frames_out(sw->rate, live)
 );
 
 return live;
@@ -1314,8 +1300,9 @@ static void audio_run_in (AudioState *s)
 size_t sw_avail = audio_get_avail(sw);
 size_t avail;
 
-avail = audio_frontend_frames_in(sw, sw_avail);
+avail = st_rate_frames_out(sw->rate, sw_avail);
 if (avail > 0) {
+avail = MIN(avail, sw->resample_buf.size);
 sw->callback.fn(sw->callback.opaque,
 avail * sw->info.bytes_per_frame);
 }
diff --git a/audio/mixeng.c b/audio/mixeng.c
index a24c8c45a7..69f6549224 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -440,6 +440,47 @@ void st_rate_stop (void *opaque)
 g_free (opaque);
 }
 
+/**
+ * st_rate_frames_out() - returns the number of frames the resampling code
+ * generates from frames_in frames
+ *
+ * @opaque: pointer to struct rate
+ * @frames_in: number of frames
+ *
+ * When upsampling, there may be more than one correct result. In this case,
+ * the function returns the maximum number of output frames the resampling
+ * code can generate.
+ */
+uint32_t st_rate_frames_out(void *opaque, uint32_t frames_in)
+{
+struct rate *rate = opaque;
+uint64_t opos_end, opos_delta;
+uint32_t ipos_end;
+uint32_t frames_out;
+
+if (rate->opos_inc == 1ULL << 32) {
+return frames_in;
+}
+
+/* no output frame without at least one input frame */
+if (!frames_in) {
+return 0;
+}
+
+/* last frame read was at rate->ipos - 1 */
+ipos_end = rate->ipos - 1 + frames_in;
+opos_end = (uint64_t)ipos_end << 32;
+
+/* last frame written was at rate->opos - rate->opos_inc */
+if (opos_end + rate->opos_inc <= rate->opos) {
+return 0;
+}
+opos_delta = opos_end - rate->opos + rate->opos_inc;
+frames_out = opos_delta / rate->opos_inc;
+
+return opos_delta % rate->opos_inc ? frames_out : frames_out - 1;
+}
+
 /**
  * st_rate_frames_in() - returns the 

[PATCH v3 15/15] audio: remove sw->ratio

2023-02-24 Thread Volker Rümelin
Simplify the resample buffer size calculation.

For audio playback we have
sw->ratio = ((int64_t)sw->hw->info.freq << 32) / sw->info.freq;
samples = ((int64_t)sw->HWBUF.size << 32) / sw->ratio;

This can be simplified to
samples = muldiv64(sw->HWBUF.size, sw->info.freq, sw->hw->info.freq);

For audio recording we have
sw->ratio = ((int64_t)sw->info.freq << 32) / sw->hw->info.freq;
samples = (int64_t)sw->HWBUF.size * sw->ratio >> 32;

This can be simplified to
samples = muldiv64(sw->HWBUF.size, sw->info.freq, sw->hw->info.freq);

With hw = sw->hw this becomes in both cases
samples = muldiv64(HWBUF.size, sw->info.freq, hw->info.freq);

Now that sw->ratio is no longer needed, remove sw->ratio.

Acked-by: Mark Cave-Ayland 
Reviewed-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c  |  1 -
 audio/audio_int.h  |  2 --
 audio/audio_template.h | 30 +-
 3 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 4836ab8ca8..70b096713c 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -478,7 +478,6 @@ static int audio_attach_capture (HWVoiceOut *hw)
 sw->info = hw->info;
 sw->empty = 1;
 sw->active = hw->enabled;
-sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
 sw->vol = nominal_volume;
 sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
 QLIST_INSERT_HEAD (_cap->sw_head, sw, entries);
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 8b163e1759..d51d63f08d 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -108,7 +108,6 @@ struct SWVoiceOut {
 AudioState *s;
 struct audio_pcm_info info;
 t_sample *conv;
-int64_t ratio;
 STSampleBuffer resample_buf;
 void *rate;
 size_t total_hw_samples_mixed;
@@ -126,7 +125,6 @@ struct SWVoiceIn {
 AudioState *s;
 int active;
 struct audio_pcm_info info;
-int64_t ratio;
 void *rate;
 size_t total_hw_samples_acquired;
 STSampleBuffer resample_buf;
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 7e116426c7..e42326c20d 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -108,32 +108,23 @@ static void glue (audio_pcm_sw_free_resources_, TYPE) (SW 
*sw)
 static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
 {
 HW *hw = sw->hw;
-int samples;
+uint64_t samples;
 
 if (!glue(audio_get_pdo_, TYPE)(sw->s->dev)->mixing_engine) {
 return 0;
 }
 
-#ifdef DAC
-samples = ((int64_t)sw->HWBUF.size << 32) / sw->ratio;
-#else
-samples = (int64_t)sw->HWBUF.size * sw->ratio >> 32;
-#endif
-if (audio_bug(__func__, samples < 0)) {
-dolog("Can not allocate buffer for `%s' (%d samples)\n",
-  SW_NAME(sw), samples);
-return -1;
-}
-
+samples = muldiv64(HWBUF.size, sw->info.freq, hw->info.freq);
 if (samples == 0) {
-size_t f_fe_min;
+uint64_t f_fe_min;
+uint64_t f_be = (uint32_t)hw->info.freq;
 
 /* f_fe_min = ceil(1 [frames] * f_be [Hz] / size_be [frames]) */
-f_fe_min = (hw->info.freq + HWBUF.size - 1) / HWBUF.size;
+f_fe_min = (f_be + HWBUF.size - 1) / HWBUF.size;
 qemu_log_mask(LOG_UNIMP,
   AUDIO_CAP ": The guest selected a " NAME " sample rate"
-  " of %d Hz for %s. Only sample rates >= %zu Hz are"
-  " supported.\n",
+  " of %d Hz for %s. Only sample rates >= %" PRIu64 " Hz"
+  " are supported.\n",
   sw->info.freq, sw->name, f_fe_min);
 return -1;
 }
@@ -141,9 +132,9 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW 
*sw)
 /*
  * Allocate one additional audio frame that is needed for upsampling
  * if the resample buffer size is small. For large buffer sizes take
- * care of overflows.
+ * care of overflows and truncation.
  */
-samples = samples < INT_MAX ? samples + 1 : INT_MAX;
+samples = samples < SIZE_MAX ? samples + 1 : SIZE_MAX;
 sw->resample_buf.buffer = g_new0(st_sample, samples);
 sw->resample_buf.size = samples;
 sw->resample_buf.pos = 0;
@@ -170,11 +161,8 @@ static int glue (audio_pcm_sw_init_, TYPE) (
 sw->hw = hw;
 sw->active = 0;
 #ifdef DAC
-sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
 sw->total_hw_samples_mixed = 0;
 sw->empty = 1;
-#else
-sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
 #endif
 
 if (sw->info.is_float) {
-- 
2.35.3




[PATCH v3 02/15] audio: change type and name of the resample buffer

2023-02-24 Thread Volker Rümelin
Change the type of the resample buffer from struct st_sample *
to STSampleBuffer. Also change the name from buf to resample_buf
for better readability.

The new variables resample_buf.size and resample_buf.pos will be
used after the next patches. There is no functional change.

Acked-by: Mark Cave-Ayland 
Reviewed-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c  | 15 ---
 audio/audio_int.h  |  4 ++--
 audio/audio_template.h | 10 ++
 3 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index a0b54e4a2e..a399147486 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -555,7 +555,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, 
size_t size)
 {
 HWVoiceIn *hw = sw->hw;
 size_t samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
-struct st_sample *src, *dst = sw->buf;
+struct st_sample *src, *dst = sw->resample_buf.buffer;
 
 live = hw->total_samples_captured - sw->total_hw_samples_acquired;
 if (!live) {
@@ -595,10 +595,10 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, 
size_t size)
 }
 
 if (!hw->pcm_ops->volume_in) {
-mixeng_volume (sw->buf, ret, >vol);
+mixeng_volume(sw->resample_buf.buffer, ret, >vol);
 }
 
-sw->clip (buf, sw->buf, ret);
+sw->clip(buf, sw->resample_buf.buffer, ret);
 sw->total_hw_samples_acquired += total;
 return ret * sw->info.bytes_per_frame;
 }
@@ -706,10 +706,10 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void 
*buf, size_t size)
 samples = ((int64_t)MIN(dead, hw_free) << 32) / sw->ratio;
 samples = MIN(samples, size / sw->info.bytes_per_frame);
 if (samples) {
-sw->conv(sw->buf, buf, samples);
+sw->conv(sw->resample_buf.buffer, buf, samples);
 
 if (!sw->hw->pcm_ops->volume_out) {
-mixeng_volume(sw->buf, samples, >vol);
+mixeng_volume(sw->resample_buf.buffer, samples, >vol);
 }
 }
 
@@ -724,7 +724,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, 
size_t size)
 osamp = blck;
 st_rate_flow_mix (
 sw->rate,
-sw->buf + pos,
+sw->resample_buf.buffer + pos,
 sw->hw->mix_buf.buffer + wpos,
 ,
 
@@ -1061,7 +1061,8 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, 
size_t rpos,
 size_t bytes = to_write * hw->info.bytes_per_frame;
 size_t written;
 
-sw->buf = hw->mix_buf.buffer + rpos2;
+sw->resample_buf.buffer = hw->mix_buf.buffer + rpos2;
+sw->resample_buf.size = to_write;
 written = audio_pcm_sw_write (sw, NULL, bytes);
 if (written - bytes) {
 dolog("Could not mix %zu bytes into a capture "
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 061845dcc2..8b163e1759 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -109,7 +109,7 @@ struct SWVoiceOut {
 struct audio_pcm_info info;
 t_sample *conv;
 int64_t ratio;
-struct st_sample *buf;
+STSampleBuffer resample_buf;
 void *rate;
 size_t total_hw_samples_mixed;
 int active;
@@ -129,7 +129,7 @@ struct SWVoiceIn {
 int64_t ratio;
 void *rate;
 size_t total_hw_samples_acquired;
-struct st_sample *buf;
+STSampleBuffer resample_buf;
 f_sample *clip;
 HWVoiceIn *hw;
 char *name;
diff --git a/audio/audio_template.h b/audio/audio_template.h
index dd87170cbd..a0b653f52c 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -95,13 +95,13 @@ static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW 
*hw)
 
 static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
 {
-g_free (sw->buf);
+g_free(sw->resample_buf.buffer);
+sw->resample_buf.buffer = NULL;
+sw->resample_buf.size = 0;
 
 if (sw->rate) {
 st_rate_stop (sw->rate);
 }
-
-sw->buf = NULL;
 sw->rate = NULL;
 }
 
@@ -138,7 +138,9 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW 
*sw)
 return -1;
 }
 
-sw->buf = g_new0(st_sample, samples);
+sw->resample_buf.buffer = g_new0(st_sample, samples);
+sw->resample_buf.size = samples;
+sw->resample_buf.pos = 0;
 
 #ifdef DAC
 sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
-- 
2.35.3




[PATCH v3 10/15] audio: replace the resampling loop in audio_pcm_sw_read()

2023-02-24 Thread Volker Rümelin
Replace the resampling loop in audio_pcm_sw_read() with the new
function audio_pcm_sw_resample_in(). Unlike the old resample
loop the new function will try to consume input frames even if
the output buffer is full. This is necessary when downsampling
to avoid reading less audio frames than calculated in advance.
The loop was unrolled to avoid complicated loop control conditions
in this case.

Acked-by: Mark Cave-Ayland 
Acked-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c | 59 ++-
 1 file changed, 35 insertions(+), 24 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index e18b5e98c5..9e9c03a42e 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -543,11 +543,43 @@ static size_t audio_pcm_hw_conv_in(HWVoiceIn *hw, void 
*pcm_buf, size_t samples)
 /*
  * Soft voice (capture)
  */
+static void audio_pcm_sw_resample_in(SWVoiceIn *sw,
+size_t frames_in_max, size_t frames_out_max,
+size_t *total_in, size_t *total_out)
+{
+HWVoiceIn *hw = sw->hw;
+struct st_sample *src, *dst;
+size_t live, rpos, frames_in, frames_out;
+
+live = hw->total_samples_captured - sw->total_hw_samples_acquired;
+rpos = audio_ring_posb(hw->conv_buf.pos, live, hw->conv_buf.size);
+
+/* resample conv_buf from rpos to end of buffer */
+src = hw->conv_buf.buffer + rpos;
+frames_in = MIN(frames_in_max, hw->conv_buf.size - rpos);
+dst = sw->resample_buf.buffer;
+frames_out = frames_out_max;
+st_rate_flow(sw->rate, src, dst, _in, _out);
+rpos += frames_in;
+*total_in = frames_in;
+*total_out = frames_out;
+
+/* resample conv_buf from start of buffer if there are input frames left */
+if (frames_in_max - frames_in && rpos == hw->conv_buf.size) {
+src = hw->conv_buf.buffer;
+frames_in = frames_in_max - frames_in;
+dst += frames_out;
+frames_out = frames_out_max - frames_out;
+st_rate_flow(sw->rate, src, dst, _in, _out);
+*total_in += frames_in;
+*total_out += frames_out;
+}
+}
+
 static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)
 {
 HWVoiceIn *hw = sw->hw;
-size_t samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
-struct st_sample *src, *dst = sw->resample_buf.buffer;
+size_t samples, live, ret, swlim, total;
 
 live = hw->total_samples_captured - sw->total_hw_samples_acquired;
 if (!live) {
@@ -558,33 +590,12 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, 
size_t size)
 return 0;
 }
 
-rpos = audio_ring_posb(hw->conv_buf.pos, live, hw->conv_buf.size);
-
 samples = size / sw->info.bytes_per_frame;
 
 swlim = (live * sw->ratio) >> 32;
 swlim = MIN (swlim, samples);
 
-while (swlim) {
-src = hw->conv_buf.buffer + rpos;
-if (hw->conv_buf.pos > rpos) {
-isamp = hw->conv_buf.pos - rpos;
-} else {
-isamp = hw->conv_buf.size - rpos;
-}
-
-if (!isamp) {
-break;
-}
-osamp = swlim;
-
-st_rate_flow (sw->rate, src, dst, , );
-swlim -= osamp;
-rpos = (rpos + isamp) % hw->conv_buf.size;
-dst += osamp;
-ret += osamp;
-total += isamp;
-}
+audio_pcm_sw_resample_in(sw, live, swlim, , );
 
 if (!hw->pcm_ops->volume_in) {
 mixeng_volume(sw->resample_buf.buffer, ret, >vol);
-- 
2.35.3




[PATCH v3 08/15] audio: remove unused noop_conv() function

2023-02-24 Thread Volker Rümelin
The function audio_capture_mix_and_clear() no longer uses
audio_pcm_sw_write() to resample audio frames from one internal
buffer to another. For this reason, the noop_conv() function is
now unused. Remove it.

Acked-by: Mark Cave-Ayland 
Reviewed-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 44eb7b63b4..556696b095 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -381,13 +381,6 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info 
*info, void *buf, int len)
 /*
  * Capture
  */
-static void noop_conv (struct st_sample *dst, const void *src, int samples)
-{
-(void) src;
-(void) dst;
-(void) samples;
-}
-
 static CaptureVoiceOut *audio_pcm_capture_find_specific(AudioState *s,
 struct audsettings *as)
 {
@@ -485,7 +478,6 @@ static int audio_attach_capture (HWVoiceOut *hw)
 sw->info = hw->info;
 sw->empty = 1;
 sw->active = hw->enabled;
-sw->conv = noop_conv;
 sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
 sw->vol = nominal_volume;
 sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
-- 
2.35.3




[PATCH v3 03/15] audio: make the resampling code greedy

2023-02-24 Thread Volker Rümelin
Read the maximum possible number of audio frames instead of the
minimum necessary number of frames when the audio stream is
downsampled and the output buffer is limited. This makes the
function symmetrical to upsampling when the input buffer is
limited. The maximum possible number of frames is written here.

With this change it's easier to calculate the exact number of
audio frames the resample function will read or write. These two
functions will be introduced later.

Acked-by: Mark Cave-Ayland 
Acked-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/rate_template.h | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/audio/rate_template.h b/audio/rate_template.h
index b432719ebb..6648f0d2e5 100644
--- a/audio/rate_template.h
+++ b/audio/rate_template.h
@@ -40,8 +40,6 @@ void NAME (void *opaque, struct st_sample *ibuf, struct 
st_sample *obuf,
 int64_t t;
 #endif
 
-ilast = rate->ilast;
-
 istart = ibuf;
 iend = ibuf + *isamp;
 
@@ -59,15 +57,17 @@ void NAME (void *opaque, struct st_sample *ibuf, struct 
st_sample *obuf,
 return;
 }
 
-while (obuf < oend) {
+/* without input samples, there's nothing to do */
+if (ibuf >= iend) {
+*osamp = 0;
+return;
+}
 
-/* Safety catch to make sure we have input samples.  */
-if (ibuf >= iend) {
-break;
-}
+ilast = rate->ilast;
 
-/* read as many input samples so that ipos > opos */
+while (true) {
 
+/* read as many input samples so that ipos > opos */
 while (rate->ipos <= (rate->opos >> 32)) {
 ilast = *ibuf++;
 rate->ipos++;
@@ -78,6 +78,11 @@ void NAME (void *opaque, struct st_sample *ibuf, struct 
st_sample *obuf,
 }
 }
 
+/* make sure that the next output sample can be written */
+if (obuf >= oend) {
+break;
+}
+
 icur = *ibuf;
 
 /* wrap ipos and opos around long before they overflow */
-- 
2.35.3




[PATCH v3 04/15] audio: replace the resampling loop in audio_pcm_sw_write()

2023-02-24 Thread Volker Rümelin
Replace the resampling loop in audio_pcm_sw_write() with the new
function audio_pcm_sw_resample_out(). Unlike the old resample
loop the new function will try to consume input frames even if
the output buffer is full. This is necessary when downsampling
to avoid reading less audio frames than calculated in advance.
The loop was unrolled to avoid complicated loop control conditions
in this case.

Acked-by: Mark Cave-Ayland 
Acked-by: Marc-André Lureau 
Signed-off-by: Volker Rümelin 
---
 audio/audio.c | 63 +--
 1 file changed, 36 insertions(+), 27 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index a399147486..4412b5fad8 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -673,11 +673,44 @@ static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void 
*pcm_buf, size_t len)
 /*
  * Soft voice (playback)
  */
+static void audio_pcm_sw_resample_out(SWVoiceOut *sw,
+size_t frames_in_max, size_t frames_out_max,
+size_t *total_in, size_t *total_out)
+{
+HWVoiceOut *hw = sw->hw;
+struct st_sample *src, *dst;
+size_t live, wpos, frames_in, frames_out;
+
+live = sw->total_hw_samples_mixed;
+wpos = (hw->mix_buf.pos + live) % hw->mix_buf.size;
+
+/* write to mix_buf from wpos to end of buffer */
+src = sw->resample_buf.buffer;
+frames_in = frames_in_max;
+dst = hw->mix_buf.buffer + wpos;
+frames_out = MIN(frames_out_max, hw->mix_buf.size - wpos);
+st_rate_flow_mix(sw->rate, src, dst, _in, _out);
+wpos += frames_out;
+*total_in = frames_in;
+*total_out = frames_out;
+
+/* write to mix_buf from start of buffer if there are input frames left */
+if (frames_in_max - frames_in > 0 && wpos == hw->mix_buf.size) {
+src += frames_in;
+frames_in = frames_in_max - frames_in;
+dst = hw->mix_buf.buffer;
+frames_out = frames_out_max - frames_out;
+st_rate_flow_mix(sw->rate, src, dst, _in, _out);
+*total_in += frames_in;
+*total_out += frames_out;
+}
+}
+
 static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)
 {
-size_t hwsamples, samples, isamp, osamp, wpos, live, dead, left, blck;
+size_t hwsamples, samples, live, dead;
 size_t hw_free;
-size_t ret = 0, pos = 0, total = 0;
+size_t ret, total;
 
 if (!sw) {
 return size;
@@ -698,8 +731,6 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, 
size_t size)
 return 0;
 }
 
-wpos = (sw->hw->mix_buf.pos + live) % hwsamples;
-
 dead = hwsamples - live;
 hw_free = audio_pcm_hw_get_free(sw->hw);
 hw_free = hw_free > live ? hw_free - live : 0;
@@ -713,29 +744,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void 
*buf, size_t size)
 }
 }
 
-while (samples) {
-dead = hwsamples - live;
-left = hwsamples - wpos;
-blck = MIN (dead, left);
-if (!blck) {
-break;
-}
-isamp = samples;
-osamp = blck;
-st_rate_flow_mix (
-sw->rate,
-sw->resample_buf.buffer + pos,
-sw->hw->mix_buf.buffer + wpos,
-,
-
-);
-ret += isamp;
-samples -= isamp;
-pos += isamp;
-live += osamp;
-wpos = (wpos + osamp) % hwsamples;
-total += osamp;
-}
+audio_pcm_sw_resample_out(sw, samples, MIN(dead, hw_free), , );
 
 sw->total_hw_samples_mixed += total;
 sw->empty = sw->total_hw_samples_mixed == 0;
-- 
2.35.3




[PULL 1/8] hw/riscv: handle 32 bit CPUs kernel_entry in riscv_load_kernel()

2023-02-24 Thread Palmer Dabbelt
From: Daniel Henrique Barboza 

Next patch will move all calls to riscv_load_initrd() to
riscv_load_kernel(). Machines that want to load initrd will be able to
do via an extra flag to riscv_load_kernel().

This change will expose a sign-extend behavior that is happening in
load_elf_ram_sym() when running 32 bit guests [1]. This is currently
obscured by the fact that riscv_load_initrd() is using the return of
riscv_load_kernel(), defined as target_ulong, and this return type will
crop the higher 32 bits that would be padded with 1s by the sign
extension when running in 32 bit targets. The changes to be done will
force riscv_load_initrd() to use an uint64_t instead, exposing it to the
padding when dealing with 32 bit CPUs.

There is a discussion about whether load_elf_ram_sym() should or should
not sign extend the value returned by 'lowaddr'. What we can do is to
prevent the behavior change that the next patch will end up doing.
riscv_load_initrd() wasn't dealing with 64 bit kernel entries when
running 32 bit CPUs, and we want to keep it that way.

One way of doing it is to use target_ulong in 'kernel_entry' in
riscv_load_kernel() and rely on the fact that this var will not be sign
extended for 32 bit targets. Another way is to explictly clear the
higher 32 bits when running 32 bit CPUs for all possibilities of
kernel_entry.

We opted for the later. This will allow us to be clear about the design
choices made in the function, while also allowing us to add a small
comment about what load_elf_ram_sym() is doing. With this change, the
consolation patch can do its job without worrying about unintended
behavioral changes.

[1] https://lists.gnu.org/archive/html/qemu-devel/2023-01/msg02281.html

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Message-Id: <20230206140022.2748401-2-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
Signed-off-by: Palmer Dabbelt 
---
 hw/riscv/boot.c| 20 +---
 hw/riscv/microchip_pfsoc.c |  3 ++-
 hw/riscv/opentitan.c   |  3 ++-
 hw/riscv/sifive_e.c|  3 ++-
 hw/riscv/sifive_u.c|  3 ++-
 hw/riscv/spike.c   |  3 ++-
 hw/riscv/virt.c|  3 ++-
 include/hw/riscv/boot.h|  1 +
 8 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index c7e0e50bd8..df6b4a1fba 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -174,6 +174,7 @@ target_ulong riscv_load_firmware(const char 
*firmware_filename,
 }
 
 target_ulong riscv_load_kernel(MachineState *machine,
+   RISCVHartArrayState *harts,
target_ulong kernel_start_addr,
symbol_fn_t sym_cb)
 {
@@ -192,21 +193,34 @@ target_ulong riscv_load_kernel(MachineState *machine,
 if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
  NULL, _load_base, NULL, NULL, 0,
  EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
-return kernel_load_base;
+kernel_entry = kernel_load_base;
+goto out;
 }
 
 if (load_uimage_as(kernel_filename, _entry, NULL, NULL,
NULL, NULL, NULL) > 0) {
-return kernel_entry;
+goto out;
 }
 
 if (load_image_targphys_as(kernel_filename, kernel_start_addr,
current_machine->ram_size, NULL) > 0) {
-return kernel_start_addr;
+kernel_entry = kernel_start_addr;
+goto out;
 }
 
 error_report("could not load kernel '%s'", kernel_filename);
 exit(1);
+
+out:
+/*
+ * For 32 bit CPUs 'kernel_entry' can be sign-extended by
+ * load_elf_ram_sym().
+ */
+if (riscv_is_32bit(harts)) {
+kernel_entry = extract64(kernel_entry, 0, 32);
+}
+
+return kernel_entry;
 }
 
 void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index 2b91e49561..712625d2a4 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -629,7 +629,8 @@ static void microchip_icicle_kit_machine_init(MachineState 
*machine)
 kernel_start_addr = riscv_calc_kernel_start_addr(>soc.u_cpus,
  firmware_end_addr);
 
-kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
+kernel_entry = riscv_load_kernel(machine, >soc.u_cpus,
+ kernel_start_addr, NULL);
 
 if (machine->initrd_filename) {
 riscv_load_initrd(machine, kernel_entry);
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 353f030d80..7fe4fb5628 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -101,7 +101,8 @@ static void opentitan_board_init(MachineState *machine)
 }
 
 if (machine->kernel_filename) {
-riscv_load_kernel(machine, 

Re: [PATCH v5 8/8] hw/mem/cxl_type3: Add CXL RAS Error Injection Support.

2023-02-24 Thread Philippe Mathieu-Daudé

On 23/2/23 15:27, Jonathan Cameron wrote:

On Thu, 23 Feb 2023 08:37:46 +0100
Markus Armbruster  wrote:


Thomas Huth  writes:


On 22/02/2023 19.16, Philippe Mathieu-Daudé wrote:

+Thomas (meson) & Marc-André (conditional QAPI)


+ Markus
  

On 22/2/23 17:49, Jonathan Cameron wrote:


[...]


Doesn't these need

     'if': 'CONFIG_CXL_MEM_DEVICE',

?


If I make this change I get a bunch of

./qapi/qapi-types-cxl.h:18:13: error: attempt to use poisoned 
"CONFIG_CXL_MEM_DEVICE"
  18 | #if defined(CONFIG_CXL_MEM_DEVICE)


Err, I meant the generic CONFIG_CXL, not CONFIG_CXL_MEM_DEVICE.
  

It's a target specific define (I think) as built alongside PCI_EXPRESS
Only CXL_ACPI is specifically included by x86 and arm64 (out of tree)

To be honest though I don't fully understand the QEMU build system so the reason
for the error might be wrong.


You need to restrict to system emulation (the 'have_system' check):


This doesn't help - still have
attempt to used poisoned "CONFIG_CXL"


Not sure how the QAPI generator works, but target specific config switches can only be 
used in target specific json files there, so that's machine-target.json and 
misc-target.json currently, as far as I know. Not sure how the QAPI generator 
distinguishes between common and target specific code, though ... just by the 
"-target" suffix? Maybe Markus or Marc-André can comment on that.


Whenever you use a poisoned macro in a conditional, all the code
generated for this .json file (we call it a "QAPI schema module")
becomes target-dependent.  The QAPI code generator itself is blissfully
unaware of this.

Since target-dependent code needs to be compiled differently, the build
process needs to be know which modules are target-dependent.  We do this
in one of the stupidest ways that could possibly work: a module is
target-dependent if its name ends with "-target".  There are just two
right now: qapi/machine-target.json and qapi/misc-target.json.

The logic resides in qapi/meson.build.  Look for

 if module.endswith('-target')


Thanks for all the pointers.


Questions?


Is it sensible to make the cxl stuff all target dependent and do the following?
I like that we can get rid of the stubs if we do this but I'm sure there are
disadvantages. Only alternative I can currently see is continue to have
stubs and not make the qmp commands conditional on them doing anything useful.


I still don't understand what is the target-dependent part of CXL.

IIUC CXL depends on PCIe which isn't target dependent.



[PATCH v3 00/15] audio: improve callback interface for audio frontends

2023-02-24 Thread Volker Rümelin

Based-on: <0a4007dc-e11c-f16e-0e21-dbc4e60ca...@t-online.de>
([PATCH v2 00/11] audio: more improvements)

The callback interface for emulated audio devices is strange. The 
callback function has an 'avail' parameter that passes the number of 
bytes that can be written or read. Unfortunately, this value sometimes 
is only an imprecise estimate and the callback functions must check the 
actual bytes written or read. For playback devices, this means that they 
either need a ring buffer or have to write the unwritten bytes again the 
next time. For recording devices, things are a bit easier. They only 
need to continue with the actual number of bytes read.


After this patch series, the 'avail' argument for the -audiodev 
out.mixing-engine=on and in.mixing-engine=on cases is exact. Audio 
frontends only need a linear frame buffer and there's a guarantee they 
can write or read 'avail' bytes.


The -audiodev out.mixing-engine=off case is also mostly accurate. Only 
the D-Bus audio backend is still missing a required function. The 
-audiodev in.mixing-engine=off case always passes a much too large 
'avail' value. I haven't worked on this yet, because there was no reason 
for it so far.


The following logs show the improvements. Not only the audio frontends 
can write or read all needed or available bytes. The same is true for 
the audio backends. For playback, the first six lines in the logs are 
expected. Here you can see how quickly the guest fills the empty 
downstream buffers after playback starts.


QEMU was started with -device ich9-intel-hda,addr=0x1b -device 
hda-duplex,audiodev=audio0 -audiodev 
pa,out.frequency=96000,in.frequency=96000,id=audio0


playback guest 44100Hz => host 96000Hz

unpatched version:
hda_audio_output_cb: to write 8188, written 1704
audio_run_out: free 4458, played 926
hda_audio_output_cb: to write 6488, written 2384
audio_run_out: free 3532, played 1297
hda_audio_output_cb: to write 4104, written 2648
audio_run_out: free 2235, played 1441
audio_run_out: free 794, played 793
audio_run_out: free 897, played 896
audio_run_out: free 831, played 829
...
hda_audio_output_cb: could not write 4 bytes
hda_audio_output_cb: to write 1764, written 1760
audio_run_out: free 960, played 958
...

patched version:
hda_audio_output_cb: to write 8192, written 1620
audio_run_out: free 4458, played 880
hda_audio_output_cb: to write 6576, written 2508
audio_run_out: free 3578, played 1365
hda_audio_output_cb: to write 4068, written 2500
audio_run_out: free 2213, played 1360

record host 96000Hz => guest 44100Hz

unpatched version:
audio_run_in: avail 4458, acquired 4454
audio_run_in: avail 1574, acquired 1572
audio_run_in: avail 766, acquired 764
audio_run_in: avail 1052, acquired 1051
audio_run_in: avail 761, acquired 760
audio_run_in: avail 1123, acquired 1121
...
hda_audio_input_cb: could not read 4 bytes
hda_audio_input_cb: to read 1988, read 1984
audio_run_in: avail 1082, acquired 1080
...

patched version:
(no output)

QEMU was started with -device ich9-intel-hda,addr=0x1b -device 
hda-duplex,audiodev=audio0 -audiodev 
pa,out.frequency=32000,in.frequency=32000,id=audio0


playback guest 44100Hz => host 32000Hz

unpatched version:
hda_audio_output_cb: to write 8188, written 1620
audio_run_out: free 1486, played 294
hda_audio_output_cb: to write 6568, written 2512
audio_run_out: free 1192, played 455
hda_audio_output_cb: to write 4060, written 2504
audio_run_out: free 737, played 455
audio_run_out: free 282, played 281
audio_run_out: free 357, played 356
audio_run_out: free 314, played 313
...
hda_audio_output_cb: could not write 4 bytes
hda_audio_output_cb: to write 1416, written 1412
audio_run_out: free 257, played 256
...

patched version:
hda_audio_output_cb: to write 8192, written 1656
audio_run_out: free 1486, played 300
hda_audio_output_cb: to write 6536, written 2516
audio_run_out: free 1186, played 457
hda_audio_output_cb: to write 4020, written 2540
audio_run_out: free 729, played 460

record host 32000Hz => guest 44100Hz

unpatched version:
audio_run_in: avail 1486, acquired 1485
audio_run_in: avail 272, acquired 271
audio_run_in: avail 366, acquired 365
hda_audio_input_cb: could not read 4 bytes
hda_audio_input_cb: to read 1420, read 1416
audio_run_in: avail 258, acquired 257
audio_run_in: avail 375, acquired 374
hda_audio_input_cb: could not read 4 bytes
hda_audio_input_cb: to read 2056, read 2052
audio_run_in: avail 260, acquired 259
...

patched version:
(no output)

This is the debug code for the logs above.

---snip--
> --- a/audio/audio.c    2022-12-13 19:14:31.793153558 +0100
> +++ b/audio/audio.c    2022-12-11 16:24:48.842649711 +0100
> @@ -1228,6 +1228,10 @@ static void audio_run_out (AudioState *s
>  #ifdef DEBUG_OUT
>  dolog("played=%zu\n", played);
>  #endif
> +    if (hw_free - played) {
> +    fprintf(stderr, "%s: free %zu, played %zu\n",
> +    __func__, hw_free, played);
> +    }
>
>  if (played) {
>  

[PULL] Fourth RISC-V PR for QEMU 8.0, Attempt 2

2023-02-24 Thread Palmer Dabbelt
The following changes since commit 417296c8d8588f782018d01a317f88957e9786d6:

  tests/qtest/netdev-socket: Raise connection timeout to 60 seconds (2023-02-09 
11:23:53 +)

are available in the Git repository at:

  g...@github.com:palmer-dabbelt/qemu.git tags/pull-riscv-to-apply-20230224

for you to fetch changes up to 8c89d50c10afdd98da82642ca5e9d7af4f1c18bd:

  target/riscv: Fix vslide1up.vf and vslide1down.vf (2023-02-23 14:21:34 -0800)


Fourth RISC-V PR for QEMU 8.0, Attempt 2

* A triplet of cleanups to the kernel/initrd loader that avoids
  duplication between the various boards.
* Weiwei Li, Daniel Henrique Barboza, and Liu Zhiwei have been added as
  reviewers.  Thanks for the help!
* A fix for PMP matching to avoid incorrectly appling the default
  permissions on PMP permission violations.
* A cleanup to avoid an unnecessary avoid env_archcpu() in
  cpu_get_tb_cpu_state().
* Fixes for the vector slide instructions to avoid truncating 64-bit
  values (such as doubles) on 32-bit targets.


Alistair Francis (1):
  MAINTAINERS: Add some RISC-V reviewers

Daniel Henrique Barboza (4):
  hw/riscv: handle 32 bit CPUs kernel_entry in riscv_load_kernel()
  hw/riscv/boot.c: consolidate all kernel init in riscv_load_kernel()
  hw/riscv/boot.c: make riscv_load_initrd() static
  target/riscv: avoid env_archcpu() in cpu_get_tb_cpu_state()

Frank Chang (1):
  target/riscv: Remove privileged spec version restriction for RVV

Himanshu Chauhan (1):
  target/riscv: Smepmp: Skip applying default rules when address matches

LIU Zhiwei (1):
  target/riscv: Fix vslide1up.vf and vslide1down.vf

 MAINTAINERS  |  3 ++
 hw/riscv/boot.c  | 97 
 hw/riscv/microchip_pfsoc.c   | 12 +-
 hw/riscv/opentitan.c |  4 +-
 hw/riscv/sifive_e.c  |  4 +-
 hw/riscv/sifive_u.c  | 12 +-
 hw/riscv/spike.c | 14 ++-
 hw/riscv/virt.c  | 12 +-
 include/hw/riscv/boot.h  |  3 +-
 target/riscv/cpu.c   |  2 +-
 target/riscv/cpu_helper.c|  2 +-
 target/riscv/csr.c   | 21 --
 target/riscv/pmp.c   |  9 ++--
 target/riscv/vector_helper.c |  4 +-
 14 files changed, 98 insertions(+), 101 deletions(-)
Subject: [PULL] Fourth RISC-V PR for QEMU 8.0, Attempt 2

The following changes since commit 417296c8d8588f782018d01a317f88957e9786d6:

  tests/qtest/netdev-socket: Raise connection timeout to 60 seconds (2023-02-09 
11:23:53 +)

are available in the Git repository at:

  g...@github.com:palmer-dabbelt/qemu.git tags/pull-riscv-to-apply-20230224

for you to fetch changes up to 8c89d50c10afdd98da82642ca5e9d7af4f1c18bd:

  target/riscv: Fix vslide1up.vf and vslide1down.vf (2023-02-23 14:21:34 -0800)


Fourth RISC-V PR for QEMU 8.0, Attempt 2

* A triplet of cleanups to the kernel/initrd loader that avoids
  duplication between the various boards.
* Weiwei Li, Daniel Henrique Barboza, and Liu Zhiwei have been added as
  reviewers.  Thanks for the help!
* A fix for PMP matching to avoid incorrectly appling the default
  permissions on PMP permission violations.
* A cleanup to avoid an unnecessary avoid env_archcpu() in
  cpu_get_tb_cpu_state().
* Fixes for the vector slide instructions to avoid truncating 64-bit
  values (such as doubles) on 32-bit targets.


I've dropped the OpenSBI update from the first attempt.  I'll take a
shot at fixing it given Thomas' instructions, but since Peter said some
PRs may be processed locally I figured it'd be easier to get this out
now -- we'd probably want to pull whatever CI fixes are necessary for
OpenSBI before the bump either way, just to avoid a history breakage, so
I figure this doesn't hurt anything.

If this doesn't process then no big deal on my end, there's some more
stuff floating around.


Alistair Francis (1):
  MAINTAINERS: Add some RISC-V reviewers

Daniel Henrique Barboza (4):
  hw/riscv: handle 32 bit CPUs kernel_entry in riscv_load_kernel()
  hw/riscv/boot.c: consolidate all kernel init in riscv_load_kernel()
  hw/riscv/boot.c: make riscv_load_initrd() static
  target/riscv: avoid env_archcpu() in cpu_get_tb_cpu_state()

Frank Chang (1):
  target/riscv: Remove privileged spec version restriction for RVV

Himanshu Chauhan (1):
  target/riscv: Smepmp: Skip applying default rules when address matches

LIU Zhiwei (1):
  target/riscv: Fix vslide1up.vf and vslide1down.vf

 MAINTAINERS  |  3 ++
 hw/riscv/boot.c  | 97 
 hw/riscv/microchip_pfsoc.c   | 12 +-
 hw/riscv/opentitan.c

[PULL 7/8] target/riscv: avoid env_archcpu() in cpu_get_tb_cpu_state()

2023-02-24 Thread Palmer Dabbelt
From: Daniel Henrique Barboza 

We have a RISCVCPU *cpu pointer available at the start of the function.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Weiwei Li 
Message-ID: <20230210123836.506286-1-dbarb...@ventanamicro.com>
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/cpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index ad8d82662c..3a9472a2ff 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -60,7 +60,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
  * which is not supported by GVEC. So we set vl_eq_vlmax flag to true
  * only when maxsz >= 8 bytes.
  */
-uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
+uint32_t vlmax = vext_get_vlmax(cpu, env->vtype);
 uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
 uint32_t maxsz = vlmax << sew;
 bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
-- 
2.39.0




[PULL 3/8] hw/riscv/boot.c: make riscv_load_initrd() static

2023-02-24 Thread Palmer Dabbelt
From: Daniel Henrique Barboza 

The only remaining caller is riscv_load_kernel_and_initrd() which
belongs to the same file.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20230206140022.2748401-4-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
Signed-off-by: Palmer Dabbelt 
---
 hw/riscv/boot.c | 80 -
 include/hw/riscv/boot.h |  1 -
 2 files changed, 40 insertions(+), 41 deletions(-)

diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 4954bb9d4b..52bf8e67de 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -173,6 +173,46 @@ target_ulong riscv_load_firmware(const char 
*firmware_filename,
 exit(1);
 }
 
+static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
+{
+const char *filename = machine->initrd_filename;
+uint64_t mem_size = machine->ram_size;
+void *fdt = machine->fdt;
+hwaddr start, end;
+ssize_t size;
+
+g_assert(filename != NULL);
+
+/*
+ * We want to put the initrd far enough into RAM that when the
+ * kernel is uncompressed it will not clobber the initrd. However
+ * on boards without much RAM we must ensure that we still leave
+ * enough room for a decent sized initrd, and on boards with large
+ * amounts of RAM we must avoid the initrd being so far up in RAM
+ * that it is outside lowmem and inaccessible to the kernel.
+ * So for boards with less  than 256MB of RAM we put the initrd
+ * halfway into RAM, and for boards with 256MB of RAM or more we put
+ * the initrd at 128MB.
+ */
+start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
+
+size = load_ramdisk(filename, start, mem_size - start);
+if (size == -1) {
+size = load_image_targphys(filename, start, mem_size - start);
+if (size == -1) {
+error_report("could not load ramdisk '%s'", filename);
+exit(1);
+}
+}
+
+/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
+if (fdt) {
+end = start + size;
+qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
+qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
+}
+}
+
 target_ulong riscv_load_kernel(MachineState *machine,
RISCVHartArrayState *harts,
target_ulong kernel_start_addr,
@@ -234,46 +274,6 @@ out:
 return kernel_entry;
 }
 
-void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
-{
-const char *filename = machine->initrd_filename;
-uint64_t mem_size = machine->ram_size;
-void *fdt = machine->fdt;
-hwaddr start, end;
-ssize_t size;
-
-g_assert(filename != NULL);
-
-/*
- * We want to put the initrd far enough into RAM that when the
- * kernel is uncompressed it will not clobber the initrd. However
- * on boards without much RAM we must ensure that we still leave
- * enough room for a decent sized initrd, and on boards with large
- * amounts of RAM we must avoid the initrd being so far up in RAM
- * that it is outside lowmem and inaccessible to the kernel.
- * So for boards with less  than 256MB of RAM we put the initrd
- * halfway into RAM, and for boards with 256MB of RAM or more we put
- * the initrd at 128MB.
- */
-start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
-
-size = load_ramdisk(filename, start, mem_size - start);
-if (size == -1) {
-size = load_image_targphys(filename, start, mem_size - start);
-if (size == -1) {
-error_report("could not load ramdisk '%s'", filename);
-exit(1);
-}
-}
-
-/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
-if (fdt) {
-end = start + size;
-qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
-qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
-}
-}
-
 /*
  * This function makes an assumption that the DRAM interval
  * 'dram_base' + 'dram_size' is contiguous.
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index ea1de8b020..a2e4ae9cb0 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -48,7 +48,6 @@ target_ulong riscv_load_kernel(MachineState *machine,
target_ulong firmware_end_addr,
bool load_initrd,
symbol_fn_t sym_cb);
-void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
 uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size,
 MachineState *ms);
 void riscv_load_fdt(hwaddr fdt_addr, void *fdt);
-- 
2.39.0




[PULL 8/8] target/riscv: Fix vslide1up.vf and vslide1down.vf

2023-02-24 Thread Palmer Dabbelt
From: LIU Zhiwei 

vslide1up_##BITWIDTH is used by the vslide1up.vx and vslide1up.vf. So its
scalar input should be uint64_t to hold the 64 bits float register.And the
same for vslide1down_##BITWIDTH.

This bug is caught when run these instructions on qemu-riscv32.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Reviewed-by: Frank Chang 
Message-ID: <20230213094550.29621-1-zhiwei_...@linux.alibaba.com>
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/vector_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 00de879787..3073c54871 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -5038,7 +5038,7 @@ GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_w, uint32_t, H4)
 GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_d, uint64_t, H8)
 
 #define GEN_VEXT_VSLIE1UP(BITWIDTH, H)  \
-static void vslide1up_##BITWIDTH(void *vd, void *v0, target_ulong s1,   \
+static void vslide1up_##BITWIDTH(void *vd, void *v0, uint64_t s1,   \
  void *vs2, CPURISCVState *env, uint32_t desc)  \
 {   \
 typedef uint##BITWIDTH##_t ETYPE;   \
@@ -5086,7 +5086,7 @@ GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_w, 32)
 GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_d, 64)
 
 #define GEN_VEXT_VSLIDE1DOWN(BITWIDTH, H) \
-static void vslide1down_##BITWIDTH(void *vd, void *v0, target_ulong s1,   \
+static void vslide1down_##BITWIDTH(void *vd, void *v0, uint64_t s1,   \
void *vs2, CPURISCVState *env, uint32_t desc)  \
 { \
 typedef uint##BITWIDTH##_t ETYPE; \
-- 
2.39.0




[PULL 2/8] hw/riscv/boot.c: consolidate all kernel init in riscv_load_kernel()

2023-02-24 Thread Palmer Dabbelt
From: Daniel Henrique Barboza 

The microchip_icicle_kit, sifive_u, spike and virt boards are now doing
the same steps when '-kernel' is used:

- execute load_kernel()
- load init_rd()
- write kernel_cmdline

Let's fold everything inside riscv_load_kernel() to avoid code
repetition. To not change the behavior of boards that aren't calling
riscv_load_init(), add an 'load_initrd' flag to riscv_load_kernel() and
allow these boards to opt out from initrd loading.

Cc: Palmer Dabbelt 
Reviewed-by: Bin Meng 
Reviewed-by: Alistair Francis 
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20230206140022.2748401-3-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
Signed-off-by: Palmer Dabbelt 
---
 hw/riscv/boot.c| 11 +++
 hw/riscv/microchip_pfsoc.c | 11 +--
 hw/riscv/opentitan.c   |  3 ++-
 hw/riscv/sifive_e.c|  3 ++-
 hw/riscv/sifive_u.c| 11 +--
 hw/riscv/spike.c   | 11 +--
 hw/riscv/virt.c| 11 +--
 include/hw/riscv/boot.h|  1 +
 8 files changed, 20 insertions(+), 42 deletions(-)

diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index df6b4a1fba..4954bb9d4b 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -176,10 +176,12 @@ target_ulong riscv_load_firmware(const char 
*firmware_filename,
 target_ulong riscv_load_kernel(MachineState *machine,
RISCVHartArrayState *harts,
target_ulong kernel_start_addr,
+   bool load_initrd,
symbol_fn_t sym_cb)
 {
 const char *kernel_filename = machine->kernel_filename;
 uint64_t kernel_load_base, kernel_entry;
+void *fdt = machine->fdt;
 
 g_assert(kernel_filename != NULL);
 
@@ -220,6 +222,15 @@ out:
 kernel_entry = extract64(kernel_entry, 0, 32);
 }
 
+if (load_initrd && machine->initrd_filename) {
+riscv_load_initrd(machine, kernel_entry);
+}
+
+if (fdt && machine->kernel_cmdline && *machine->kernel_cmdline) {
+qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
+machine->kernel_cmdline);
+}
+
 return kernel_entry;
 }
 
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index 712625d2a4..e81bbd12df 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -630,16 +630,7 @@ static void microchip_icicle_kit_machine_init(MachineState 
*machine)
  firmware_end_addr);
 
 kernel_entry = riscv_load_kernel(machine, >soc.u_cpus,
- kernel_start_addr, NULL);
-
-if (machine->initrd_filename) {
-riscv_load_initrd(machine, kernel_entry);
-}
-
-if (machine->kernel_cmdline && *machine->kernel_cmdline) {
-qemu_fdt_setprop_string(machine->fdt, "/chosen",
-"bootargs", machine->kernel_cmdline);
-}
+ kernel_start_addr, true, NULL);
 
 /* Compute the fdt load address in dram */
 fdt_load_addr = 
riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base,
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 7fe4fb5628..b06944d382 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -102,7 +102,8 @@ static void opentitan_board_init(MachineState *machine)
 
 if (machine->kernel_filename) {
 riscv_load_kernel(machine, >soc.cpus,
-  memmap[IBEX_DEV_RAM].base, NULL);
+  memmap[IBEX_DEV_RAM].base,
+  false, NULL);
 }
 }
 
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 1a7d381514..04939b60c3 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -115,7 +115,8 @@ static void sifive_e_machine_init(MachineState *machine)
 
 if (machine->kernel_filename) {
 riscv_load_kernel(machine, >soc.cpus,
-  memmap[SIFIVE_E_DEV_DTIM].base, NULL);
+  memmap[SIFIVE_E_DEV_DTIM].base,
+  false, NULL);
 }
 }
 
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 71be442a50..ad3bb35b34 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -599,16 +599,7 @@ static void sifive_u_machine_init(MachineState *machine)
  firmware_end_addr);
 
 kernel_entry = riscv_load_kernel(machine, >soc.u_cpus,
- kernel_start_addr, NULL);
-
-if (machine->initrd_filename) {
-riscv_load_initrd(machine, kernel_entry);
-}
-
-if (machine->kernel_cmdline && *machine->kernel_cmdline) {
-qemu_fdt_setprop_string(machine->fdt, "/chosen", "bootargs",
-machine->kernel_cmdline);
-}
+   

[PULL 6/8] target/riscv: Smepmp: Skip applying default rules when address matches

2023-02-24 Thread Palmer Dabbelt
From: Himanshu Chauhan 

When MSECCFG.MML is set, after checking the address range in PMP if the
asked permissions are not same as programmed in PMP, the default
permissions are applied. This should only be the case when there
is no matching address is found.

This patch skips applying default rules when matching address range
is found. It returns the index of the match PMP entry.

Fixes: 824cac681c3 (target/riscv: Fix PMP propagation for tlb)
Signed-off-by: Himanshu Chauhan 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Message-Id: <20230209055206.229392-1-hchau...@ventanamicro.com>
Signed-off-by: Alistair Francis 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/pmp.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index d1126a6066..4bc4113531 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -441,9 +441,12 @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 }
 }
 
-if ((privs & *allowed_privs) == privs) {
-ret = i;
-}
+/*
+ * If matching address range was found, the protection bits
+ * defined with PMP must be used. We shouldn't fallback on
+ * finding default privileges.
+ */
+ret = i;
 break;
 }
 }
-- 
2.39.0




[PULL 4/8] target/riscv: Remove privileged spec version restriction for RVV

2023-02-24 Thread Palmer Dabbelt
From: Frank Chang 

The RVV specification does not require that the core needs to support
the privileged specification v1.12.0 to support RVV, and there is no
dependency from ISA level.

This commit removes the restriction from both RVV CSRs and extension CPU
ISA string.

Signed-off-by: Frank Chang 
Reviewed-by: Bin Meng 
Reviewed-by: LIU Zhiwei 
Acked-by: Alistair Francis 
Message-Id: <20230208063209.27279-1-frank.ch...@sifive.com>
Signed-off-by: Alistair Francis 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/cpu.c |  2 +-
 target/riscv/csr.c | 21 +++--
 2 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0dd2f0c753..93b52b826c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -73,7 +73,7 @@ struct isa_ext_data {
  */
 static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(h, false, PRIV_VERSION_1_12_0, ext_h),
-ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_12_0, ext_v),
+ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_10_0, ext_v),
 ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
 ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
 ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, 
ext_zihintpause),
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index fa17d7770c..1b0a0c1693 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3980,20 +3980,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_FRM]  = { "frm",  fs, read_frm, write_frm},
 [CSR_FCSR] = { "fcsr", fs, read_fcsr,write_fcsr   },
 /* Vector CSRs */
-[CSR_VSTART]   = { "vstart",   vs, read_vstart,  write_vstart,
-   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_VXSAT]= { "vxsat",vs, read_vxsat,   write_vxsat,
-   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_VXRM] = { "vxrm", vs, read_vxrm,write_vxrm,
-   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_VCSR] = { "vcsr", vs, read_vcsr,write_vcsr,
-   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_VL]   = { "vl",   vs, read_vl,
-   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_VTYPE]= { "vtype",vs, read_vtype,
-   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_VLENB]= { "vlenb",vs, read_vlenb,
-   .min_priv_ver = PRIV_VERSION_1_12_0},
+[CSR_VSTART]   = { "vstart",   vs, read_vstart,  write_vstart },
+[CSR_VXSAT]= { "vxsat",vs, read_vxsat,   write_vxsat  },
+[CSR_VXRM] = { "vxrm", vs, read_vxrm,write_vxrm   },
+[CSR_VCSR] = { "vcsr", vs, read_vcsr,write_vcsr   },
+[CSR_VL]   = { "vl",   vs, read_vl},
+[CSR_VTYPE]= { "vtype",vs, read_vtype },
+[CSR_VLENB]= { "vlenb",vs, read_vlenb },
 /* User Timers and Counters */
 [CSR_CYCLE]= { "cycle",ctr,read_hpmcounter  },
 [CSR_INSTRET]  = { "instret",  ctr,read_hpmcounter  },
-- 
2.39.0




[PULL 5/8] MAINTAINERS: Add some RISC-V reviewers

2023-02-24 Thread Palmer Dabbelt
From: Alistair Francis 

This patch adds some active RISC-V members as reviewers to the
MAINTAINERS file.

Signed-off-by: Alistair Francis 
Acked-by: LIU Zhiwei 
Acked-by: Weiwei Li 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Frank Chang 
Message-Id: <20230209003308.738237-1-alistair.fran...@opensource.wdc.com>
Signed-off-by: Palmer Dabbelt 
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 96e25f62ac..847bc7f131 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -287,6 +287,9 @@ RISC-V TCG CPUs
 M: Palmer Dabbelt 
 M: Alistair Francis 
 M: Bin Meng 
+R: Weiwei Li 
+R: Daniel Henrique Barboza 
+R: Liu Zhiwei 
 L: qemu-ri...@nongnu.org
 S: Supported
 F: target/riscv/
-- 
2.39.0




Re: [PULL 0/9] Fourth RISC-V PR for QEMU 8.0

2023-02-24 Thread Palmer Dabbelt

On Fri, 24 Feb 2023 10:52:34 PST (-0800), Peter Maydell wrote:

On Fri, 24 Feb 2023 at 06:56, Thomas Huth  wrote:


  Hi!

On 23/02/2023 23.49, Palmer Dabbelt wrote:
> Nobody's replied, so I'm inclined to just drop the OpenSBI bump and re-send
> the PR.  At least that way we can avoid getting blocked on the CI issues.
> There's some more in flight so there'll probably be a 5th round before the
> freeze either way, at least this way the stuff that works can avoid getting
> blocked.

Please note that pull requests are currently not processed
anyway ('til March 1st), see:

  
https://lore.kernel.org/qemu-devel/cafeaca83u_enxdj3gjka-xv6eljgjpr_9frdkaqm3qacyhr...@mail.gmail.com/


I've been able to do some pullreq processing with a combination
of the private CI runners, my personal gitlab account's CI minute
allowance, and local ad-hoc jobs. So probably best not to wait
til March 1st before sending.


Ok, I'm just going to send a v2 with the OpenSBI bump removed.  No big 
deal if it doesn't get merged, there's more to do in RISC-V land either 
way.


I'll also poke aroun with the CI some and try to see if I can get local 
stuff working to debug the OpenSBI issue.


Thanks!



Re: [PULL 00/13] testing updates (gitlab, cirrus, docker, avocado, windows)

2023-02-24 Thread Peter Maydell
On Thu, 23 Feb 2023 at 15:57, Alex Bennée  wrote:
>
> The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8:
>
>   Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into 
> staging (2023-02-21 11:28:31 +)
>
> are available in the Git repository at:
>
>   https://gitlab.com/stsquad/qemu.git tags/pull-testing-next-230223-1
>
> for you to fetch changes up to e9969376f01180d7bcbee25ae8333983da7eda2c:
>
>   cirrus.yml: Improve the windows_msys2_task (2023-02-23 15:48:23 +)
>
> 
> testing updates:
>
>   - ensure socat available for tests
>   - skip socat tests for MacOS
>   - properly clean up fifos after use
>   - make fp-test less chatty
>   - store test artefacts on Cirrus
>   - control custom runners with QEMU_CI knobs
>   - disable benchmark runs under tsan build
>   - update ubuntu 2004 to 2204
>   - skip nios2 kernel replay test
>   - add tuxrun baselines to avocado
>   - binary build of tricore tools
>   - export test results on cross builds
>   - improve windows builds
>
> 

So I've been applying pullreqs relying on a combination of the
private-runner CI jobs plus using the free minutes allowance
on my personal gitlab account, and ad-hoc local builds. I'm
a bit reluctant to do that for this one though, because it's
touching all the gitlab config and we won't be able test that
that is OK until we can do a full run with the standard config.
What do you think ?

thanks
-- PMM



Re: [PULL 0/9] Fourth RISC-V PR for QEMU 8.0

2023-02-24 Thread Peter Maydell
On Fri, 24 Feb 2023 at 06:56, Thomas Huth  wrote:
>
>   Hi!
>
> On 23/02/2023 23.49, Palmer Dabbelt wrote:
> > Nobody's replied, so I'm inclined to just drop the OpenSBI bump and re-send
> > the PR.  At least that way we can avoid getting blocked on the CI issues.
> > There's some more in flight so there'll probably be a 5th round before the
> > freeze either way, at least this way the stuff that works can avoid getting
> > blocked.
>
> Please note that pull requests are currently not processed
> anyway ('til March 1st), see:
>
>   
> https://lore.kernel.org/qemu-devel/cafeaca83u_enxdj3gjka-xv6eljgjpr_9frdkaqm3qacyhr...@mail.gmail.com/

I've been able to do some pullreq processing with a combination
of the private CI runners, my personal gitlab account's CI minute
allowance, and local ad-hoc jobs. So probably best not to wait
til March 1st before sending.

thanks
-- PMM



Re: [PULL 00/12] Error reporting patches patches for 2023-02-23

2023-02-24 Thread Peter Maydell
On Thu, 23 Feb 2023 at 13:46, Markus Armbruster  wrote:
>
> The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8:
>
>   Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into 
> staging (2023-02-21 11:28:31 +)
>
> are available in the Git repository at:
>
>   https://repo.or.cz/qemu/armbru.git tags/pull-error-2023-02-23
>
> for you to fetch changes up to 1178710247017ee4f570b16a186ee48c250a18d1:
>
>   rocker: Tweak stubbed out monitor commands' error messages (2023-02-23 
> 14:10:17 +0100)
>
> 
> Error reporting patches patches for 2023-02-23
>


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/8.0
for any user-visible changes.

-- PMM



Re: [PULL 00/29] Block layer patches

2023-02-24 Thread Peter Maydell
On Thu, 23 Feb 2023 at 18:51, Kevin Wolf  wrote:
>
> The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8:
>
>   Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into 
> staging (2023-02-21 11:28:31 +)
>
> are available in the Git repository at:
>
>   https://repo.or.cz/qemu/kevin.git tags/for-upstream
>
> for you to fetch changes up to 0f385a2420d2c3f8ae7ed65fbe2712027664059e:
>
>   block/rbd: Add support for layered encryption (2023-02-23 19:49:35 +0100)
>
> 
> Block layer patches
>
> - Lock the graph, part 2 (BlockDriver callbacks)
> - virtio-scsi: fix SCSIDevice hot unplug with IOThread
> - rbd: Add support for layered encryption
>
> 


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/8.0
for any user-visible changes.

-- PMM



Re: [RFC QEMU] docs: vhost-user: Add custom memory mapping support

2023-02-24 Thread Alex Bennée


Viresh Kumar  writes:

> The current model of memory mapping at the back-end works fine with
> Qemu, where a standard call to mmap() for the respective file
> descriptor, passed from front-end, is generally all we need to do before
> the front-end can start accessing the guest memory.
>
> There are other complex cases though, where we need more information at
> the backend and need to do more than just an mmap() call. For example,
> Xen, a type-1 hypervisor, currently supports memory mapping via two
> different methods, foreign-mapping (via /dev/privcmd) and grant-dev (via
> /dev/gntdev). In both these cases, the back-end needs to call mmap()
> followed by an ioctl() (or vice-versa), and need to pass extra
> information via the ioctl(), like the Xen domain-id of the guest whose
> memory we are trying to map.
>
> Add a new protocol feature, 'VHOST_USER_PROTOCOL_F_CUSTOM_MMAP', which
> lets the back-end know about the additional memory mapping requirements.
> When this feature is negotiated, the front-end can send the
> 'VHOST_USER_CUSTOM_MMAP' message type to provide the additional
> information to the back-end.
>
> Signed-off-by: Viresh Kumar 
> ---
>  docs/interop/vhost-user.rst | 32 
>  1 file changed, 32 insertions(+)
>
> diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
> index 3f18ab424eb0..f2b1d705593a 100644
> --- a/docs/interop/vhost-user.rst
> +++ b/docs/interop/vhost-user.rst
> @@ -258,6 +258,23 @@ Inflight description
>  
>  :queue size: a 16-bit size of virtqueues
>  
> +Custom mmap description
> +^^^
> +
> ++---+---+
> +| flags | value |
> ++---+---+
> +
> +:flags: 64-bit bit field
> +
> +- Bit 0 is Xen foreign memory access flag - needs Xen foreign memory mapping.
> +- Bit 1 is Xen grant memory access flag - needs Xen grant memory mapping.
> +
> +:value: a 64-bit hypervisor specific value.
> +
> +- For Xen foreign or grant memory access, this is set with guest's xen domain
> +  id.
> +
>  C structure
>  ---
>  
> @@ -867,6 +884,7 @@ Protocol features
>#define VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS 14
>#define VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS  15
>#define VHOST_USER_PROTOCOL_F_STATUS   16
> +  #define VHOST_USER_PROTOCOL_F_CUSTOM_MMAP  17
>  
>  Front-end message types
>  ---
> @@ -1422,6 +1440,20 @@ Front-end message types
>query the back-end for its device status as defined in the Virtio
>specification.
>  
> +``VHOST_USER_CUSTOM_MMAP``
> +  :id: 41
> +  :equivalent ioctl: N/A
> +  :request payload: Custom mmap description
> +  :reply payload: N/A
> +
> +  When the ``VHOST_USER_PROTOCOL_F_CUSTOM_MMAP`` protocol feature has been
> +  successfully negotiated, this message is submitted by the front-end to
> +  notify the back-end of the special memory mapping requirements, that the
> +  back-end needs to take care of, while mapping any memory regions sent
> +  over by the front-end. The front-end must send this message before
> +  any memory-regions are sent to the back-end via 
> ``VHOST_USER_SET_MEM_TABLE``
> +  or ``VHOST_USER_ADD_MEM_REG`` message types.
> +
>  
>  Back-end message types
>  --

This looks good enough for me. We will see how it works in prototype.

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH 6/7] tests/docker: use direct RUNC call to run test jobs

2023-02-24 Thread Alex Bennée
If we build them without the script we can certainly run them without
it.

Signed-off-by: Alex Bennée 
---
 tests/docker/Makefile.include | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include
index 9e73ff5cf3..cee1b34703 100644
--- a/tests/docker/Makefile.include
+++ b/tests/docker/Makefile.include
@@ -223,8 +223,9 @@ docker-run: docker-qemu-src
$(IMAGE) --executable $(EXECUTABLE),\
"  COPYING $(EXECUTABLE) to $(IMAGE)"))
$(call quiet-command,   \
-   $(DOCKER_SCRIPT) run\
-   $(if $(NOUSER),,--run-as-current-user)  \
+   $(RUNC) run \
+   --rm\
+   $(if $(NOUSER),,-u $(UID))  \
--security-opt seccomp=unconfined   \
$(if $(DEBUG),-ti,) \
$(if $(NETWORK),$(if $(subst 
$(NETWORK),,1),--net=$(NETWORK)),--net=none) \
-- 
2.39.1




[PATCH 5/7] tests/docker: use direct RUNC call to build containers

2023-02-24 Thread Alex Bennée
We don't really need stuff from docker.py to do the build as we have
everything we need with a direct call. We do rely on the dockerfiles
being able to tweak the UID/name mapping as the last step.

Signed-off-by: Alex Bennée 
---
 tests/docker/Makefile.include | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include
index bfb0dcac21..9e73ff5cf3 100644
--- a/tests/docker/Makefile.include
+++ b/tests/docker/Makefile.include
@@ -7,6 +7,8 @@ SPACE := $(NULL) #
 COMMA := ,
 
 HOST_ARCH = $(if $(ARCH),$(ARCH),$(shell uname -m))
+USER = $(if $(NOUSER),,$(shell id -un))
+UID = $(if $(NOUSER),,$(shell id -u))
 
 DOCKER_FILES_DIR := $(SRC_PATH)/tests/docker/dockerfiles
 ifeq ($(HOST_ARCH),x86_64)
@@ -14,6 +16,7 @@ DOCKER_DEFAULT_REGISTRY := 
registry.gitlab.com/qemu-project/qemu
 endif
 DOCKER_REGISTRY := $(if $(REGISTRY),$(REGISTRY),$(DOCKER_DEFAULT_REGISTRY))
 
+RUNC ?= docker
 ENGINE ?= auto
 DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py --engine $(ENGINE)
 
@@ -35,15 +38,16 @@ docker-qemu-src: $(DOCKER_SRC_COPY)
 
 # General rule for building docker images.
 docker-image-%: $(DOCKER_FILES_DIR)/%.docker
-   $(call quiet-command,\
-   $(DOCKER_SCRIPT) build -t qemu/$* -f $< \
-   $(if $V,,--quiet) \
-   $(if $(NOCACHE),--no-cache, \
-   $(if $(DOCKER_REGISTRY),--registry $(DOCKER_REGISTRY))) 
\
-   $(if $(NOUSER),,--add-current-user) \
-   $(if $(EXTRA_FILES),--extra-files $(EXTRA_FILES))\
-   $(if $(EXECUTABLE),--include-executable=$(EXECUTABLE)),\
-   "BUILD","$*")
+ $(call quiet-command, \
+   $(RUNC) build   \
+   $(if $V,,--quiet)   \
+   $(if $(NOCACHE),--no-cache, \
+   $(if $(DOCKER_REGISTRY),--cache-from 
$(DOCKER_REGISTRY)/qemu/$*)) \
+   $(if $(NOUSER),,\
+   --build-arg USER=$(USER)\
+   --build-arg UID=$(UID)) \
+   -t qemu/$* - < $<,  \
+   "BUILD", $1)
 
 # Special rule for debootstraped binfmt linux-user images
 docker-binfmt-image-debian-%: $(DOCKER_FILES_DIR)/debian-bootstrap.docker
-- 
2.39.1




[PATCH 2/7] tests/dockerfiles: unify debian-toolchain references

2023-02-24 Thread Alex Bennée
We use the debian release number elsewhere so fix it for consistency
along with the broken comment.

Signed-off-by: Alex Bennée 
---
 tests/docker/dockerfiles/debian-toolchain.docker | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/docker/dockerfiles/debian-toolchain.docker 
b/tests/docker/dockerfiles/debian-toolchain.docker
index 6c73408b34..dc9545857f 100644
--- a/tests/docker/dockerfiles/debian-toolchain.docker
+++ b/tests/docker/dockerfiles/debian-toolchain.docker
@@ -30,7 +30,7 @@ ADD build-toolchain.sh /root/build-toolchain.sh
 RUN cd /root && ./build-toolchain.sh
 
 # Throw away the extra toolchain build deps, the downloaded source,
-# and the build trees by restoring the original debian10 image,
+# and the build trees by restoring the original image,
 # then copying the built toolchain from stage 0.
-FROM docker.io/library/debian:bullseye-slim
+FROM docker.io/library/debian:11-slim
 COPY --from=0 /usr/local /usr/local
-- 
2.39.1




[PATCH 7/7] tests/gitlab: use kaniko to build images

2023-02-24 Thread Alex Bennée
Apparently the docker-in-docker approach has some flaws including
needing privileged mode to run and being quite slow. An alternative
approach is to use Google's kaniko tool. It also works across
different gitlab executors.

Following the gitlab example code we drop all the direct docker calls
and usage of the script and make a direct call to kaniko and hope the
images are cacheable by others.

Signed-off-by: Alex Bennée 
---
 .gitlab-ci.d/container-template.yml | 23 +--
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/.gitlab-ci.d/container-template.yml 
b/.gitlab-ci.d/container-template.yml
index c434b9c8f3..c2d7950df8 100644
--- a/.gitlab-ci.d/container-template.yml
+++ b/.gitlab-ci.d/container-template.yml
@@ -1,22 +1,17 @@
 .container_job_template:
   extends: .base_job_template
-  image: docker:stable
+  image:
+name: gcr.io/kaniko-project/executor:v1.9.0-debug
+entrypoint: [""]
   stage: containers
-  services:
-- docker:dind
   before_script:
 - export TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
-- export COMMON_TAG="$CI_REGISTRY/qemu-project/qemu/$NAME:latest"
-- apk add python3
-- docker info
-- docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" -p 
"$CI_REGISTRY_PASSWORD"
+- export COMMON_TAG="$CI_REGISTRY/qemu-project/qemu/qemu/$NAME:latest"
   script:
 - echo "TAG:$TAG"
 - echo "COMMON_TAG:$COMMON_TAG"
-- ./tests/docker/docker.py --engine docker build
-  -t "qemu/$NAME" -f "tests/docker/dockerfiles/$NAME.docker"
-  -r $CI_REGISTRY/qemu-project/qemu
-- docker tag "qemu/$NAME" "$TAG"
-- docker push "$TAG"
-  after_script:
-- docker logout
+- /kaniko/executor
+  --reproducible
+  --context "${CI_PROJECT_DIR}"
+  --dockerfile 
"${CI_PROJECT_DIR}/tests/docker/dockerfiles/$NAME.docker"
+  --destination "${TAG}"
-- 
2.39.1




[PATCH 1/7] configure: expose the direct container command

2023-02-24 Thread Alex Bennée
In the process of migrating away from using docker.py to build our
containers we need to expose the command to the build environment. The
script is still a useful way to probe which command works though.

Signed-off-by: Alex Bennée 
---
 configure | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/configure b/configure
index cf6db3d551..b6a1cebad9 100755
--- a/configure
+++ b/configure
@@ -1744,6 +1744,7 @@ fi
 # functions to probe cross compilers
 
 container="no"
+runc=""
 if test $use_containers = "yes" && (has "docker" || has "podman"); then
 case $($python "$source_path"/tests/docker/docker.py probe) in
 *docker) container=docker ;;
@@ -1752,6 +1753,7 @@ if test $use_containers = "yes" && (has "docker" || has 
"podman"); then
 esac
 if test "$container" != "no"; then
 docker_py="$python $source_path/tests/docker/docker.py --engine 
$container"
+runc=$($python "$source_path"/tests/docker/docker.py probe)
 fi
 fi
 
@@ -2351,6 +2353,7 @@ fi
 
 if test "$container" != no; then
 echo "ENGINE=$container" >> $config_host_mak
+echo "RUNC=$runc" >> $config_host_mak
 fi
 echo "ROMS=$roms" >> $config_host_mak
 echo "MAKE=$make" >> $config_host_mak
-- 
2.39.1




[PATCH 0/7] testing/next: docker.py removal and kaniko updates

2023-02-24 Thread Alex Bennée
This series attempts to remove our dependence on the docker.py script
and build things directly with the appropriate tool. I've been
noodling around with how we build images on gitlab to see if they can
cache better because the normal case should be we don't need to
rebuild everything if the upstream distro hasn't updated its package
list.

Anyway what do people think?

Alex Bennée (7):
  configure: expose the direct container command
  tests/dockerfiles: unify debian-toolchain references
  tests/lcitool: append user setting stanza to dockerfiles
  tests/docker: add USER stanzas to non-lci images
  tests/docker: use direct RUNC call to build containers
  tests/docker: use direct RUNC call to run test jobs
  tests/gitlab: use kaniko to build images

 configure |  3 +++
 .gitlab-ci.d/cirrus/freebsd-12.vars   |  5 
 .gitlab-ci.d/cirrus/freebsd-13.vars   |  5 
 .gitlab-ci.d/cirrus/macos-12.vars |  5 
 .gitlab-ci.d/container-template.yml   | 23 +++-
 tests/docker/Makefile.include | 27 +++
 tests/docker/dockerfiles/alpine.docker|  5 
 tests/docker/dockerfiles/centos8.docker   |  5 
 .../dockerfiles/debian-all-test-cross.docker  |  5 
 .../dockerfiles/debian-alpha-cross.docker |  5 
 .../dockerfiles/debian-amd64-cross.docker |  5 
 tests/docker/dockerfiles/debian-amd64.docker  |  5 
 .../dockerfiles/debian-arm64-cross.docker |  5 
 .../dockerfiles/debian-armel-cross.docker |  5 
 .../dockerfiles/debian-armhf-cross.docker |  5 
 .../dockerfiles/debian-hexagon-cross.docker   |  5 
 .../dockerfiles/debian-hppa-cross.docker  |  5 
 .../dockerfiles/debian-loongarch-cross.docker |  5 
 .../dockerfiles/debian-m68k-cross.docker  |  5 
 .../dockerfiles/debian-mips-cross.docker  |  5 
 .../dockerfiles/debian-mips64-cross.docker|  5 
 .../dockerfiles/debian-mips64el-cross.docker  |  5 
 .../dockerfiles/debian-mipsel-cross.docker|  5 
 tests/docker/dockerfiles/debian-native.docker |  5 
 .../debian-powerpc-test-cross.docker  |  6 -
 .../dockerfiles/debian-ppc64el-cross.docker   |  5 
 .../dockerfiles/debian-riscv64-cross.docker   |  5 
 .../debian-riscv64-test-cross.docker  |  5 
 .../dockerfiles/debian-s390x-cross.docker |  5 
 .../dockerfiles/debian-sh4-cross.docker   |  5 
 .../dockerfiles/debian-sparc64-cross.docker   |  5 
 .../dockerfiles/debian-toolchain.docker   |  9 +--
 .../dockerfiles/debian-tricore-cross.docker   |  5 
 .../dockerfiles/debian-xtensa-cross.docker|  5 
 .../dockerfiles/fedora-cris-cross.docker  |  5 
 .../dockerfiles/fedora-i386-cross.docker  |  5 
 .../dockerfiles/fedora-win32-cross.docker |  5 
 .../dockerfiles/fedora-win64-cross.docker |  5 
 tests/docker/dockerfiles/fedora.docker|  5 
 tests/docker/dockerfiles/opensuse-leap.docker |  5 
 tests/docker/dockerfiles/python.docker|  5 
 tests/docker/dockerfiles/ubuntu2004.docker|  5 
 tests/docker/dockerfiles/ubuntu2204.docker|  5 
 tests/lcitool/refresh | 11 +++-
 44 files changed, 240 insertions(+), 29 deletions(-)

-- 
2.39.1




Re: [PATCH v3 1/6] configure: Look for auxiliary Python installations

2023-02-24 Thread Eric Blake
On Tue, Feb 21, 2023 at 12:03:44PM +0100, Paolo Bonzini wrote:
> > 
> > This configure loop will prefer, in order:
> > 
> > 1. Whatever is specified in $PYTHON
> > 2. python3
> > 3. python (Which is usually 2.x, but might be 3.x on some platforms.)
> > 4. python3.11 down through python3.6
> > 
> > +
> >   python=
> > +first_python=
> >   explicit_python=no
> > -for binary in "${PYTHON-python3}" python
> > +# Check for $PYTHON, python3, python, then explicitly-versioned 
> > interpreters.
> > +for binary in "${PYTHON-python3}" ${PYTHON:+python3} python \
> > +  python3.11 python3.10 python3.9 \
> > +  python3.8 python3.7 python3.6
> 
> I think if PYTHON is set we shouldn't look at anything else.

Now that you mention that, it does sound more like what autoconf does
(if the user specified something, honor it; otherwise, find the best
match in a list of candidates).

> 
> Paolo
> 
> >   do
> >   if has "$binary"
> >   then
> >   python=$(command -v "$binary")
> > -break
> > +if test -z "$first_python"; then
> > +   first_python=$python
> > +fi
> > +if check_py_version "$python"; then
> > +# This one is good.
> > +first_python=
> > +break
> > +fi

One easy way to do that is add this here:

 if test -n "$PYTHON"; then break; fi

> >   fi
> >   done
> > +# If first_python is set, we didn't find a suitable binary.
> > +# Use this one for possible future error messages.
> > +if test -n "$first_python"; then
> > +python="$first_python"
> > +fi

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




[PATCH 2/4] target/riscv/csr.c: simplify mctr()

2023-02-24 Thread Daniel Henrique Barboza
Use riscv_cpu_cfg() to retrieve pmu_num.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/csr.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 3692617d13..0f4aa22a0f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -165,8 +165,7 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
 #if !defined(CONFIG_USER_ONLY)
 static RISCVException mctr(CPURISCVState *env, int csrno)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+int pmu_num = riscv_cpu_cfg(env)->pmu_num;
 int ctr_index;
 int base_csrno = CSR_MHPMCOUNTER3;
 
@@ -175,7 +174,7 @@ static RISCVException mctr(CPURISCVState *env, int csrno)
 base_csrno += 0x80;
 }
 ctr_index = csrno - base_csrno;
-if (!cpu->cfg.pmu_num || ctr_index >= cpu->cfg.pmu_num) {
+if (!pmu_num || ctr_index >= pmu_num) {
 /* The PMU is not enabled or counter is out of range*/
 return RISCV_EXCP_ILLEGAL_INST;
 }
-- 
2.39.2




[PATCH 3/4] target/riscv/csr.c: use riscv_cpu_cfg() to avoid env_cpu() pointers

2023-02-24 Thread Daniel Henrique Barboza
A common trend in this file is to retrieve a RISCVCPU pointer by first
retrieving a CPUState pointer via env_cpu(). The CPU pointer is used
only to access the RISCVCPUConfig object and nothing else.

Let's use riscv_cpu_cfg() to access what we need directly without these
2 pointers.

Suggested-by: LIU Zhiwei 
Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/csr.c | 50 +++---
 1 file changed, 12 insertions(+), 38 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0f4aa22a0f..53f1a331f9 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -46,10 +46,8 @@ static RISCVException smstateen_acc_ok(CPURISCVState *env, 
int index,
uint64_t bit)
 {
 bool virt = riscv_cpu_virt_enabled(env);
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
 
-if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
+if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
 return RISCV_EXCP_NONE;
 }
 
@@ -81,7 +79,7 @@ static RISCVException fs(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
 if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
-!RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
+!riscv_cpu_cfg(env)->ext_zfinx) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 #endif
@@ -90,11 +88,9 @@ static RISCVException fs(CPURISCVState *env, int csrno)
 
 static RISCVException vs(CPURISCVState *env, int csrno)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
 if (env->misa_ext & RVV ||
-cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
+riscv_cpu_cfg(env)->ext_zve32f ||
+riscv_cpu_cfg(env)->ext_zve64f) {
 #if !defined(CONFIG_USER_ONLY)
 if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -193,10 +189,7 @@ static RISCVException mctr32(CPURISCVState *env, int csrno)
 
 static RISCVException sscofpmf(CPURISCVState *env, int csrno)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-if (!cpu->cfg.ext_sscofpmf) {
+if (!riscv_cpu_cfg(env)->ext_sscofpmf) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -319,10 +312,7 @@ static RISCVException umode32(CPURISCVState *env, int 
csrno)
 
 static RISCVException mstateen(CPURISCVState *env, int csrno)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-if (!cpu->cfg.ext_smstateen) {
+if (!riscv_cpu_cfg(env)->ext_smstateen) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -331,10 +321,7 @@ static RISCVException mstateen(CPURISCVState *env, int 
csrno)
 
 static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-if (!cpu->cfg.ext_smstateen) {
+if (!riscv_cpu_cfg(env)->ext_smstateen) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -361,10 +348,8 @@ static RISCVException sstateen(CPURISCVState *env, int 
csrno)
 {
 bool virt = riscv_cpu_virt_enabled(env);
 int index = csrno - CSR_SSTATEEN0;
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
 
-if (!cpu->cfg.ext_smstateen) {
+if (!riscv_cpu_cfg(env)->ext_smstateen) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -916,11 +901,9 @@ static RISCVException read_timeh(CPURISCVState *env, int 
csrno,
 
 static RISCVException sstc(CPURISCVState *env, int csrno)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
 bool hmode_check = false;
 
-if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
+if (!riscv_cpu_cfg(env)->ext_sstc || !env->rdtime_fn) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -1150,30 +1133,21 @@ static RISCVException write_ignore(CPURISCVState *env, 
int csrno,
 static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-*val = cpu->cfg.mvendorid;
+*val = riscv_cpu_cfg(env)->mvendorid;
 return RISCV_EXCP_NONE;
 }
 
 static RISCVException read_marchid(CPURISCVState *env, int csrno,
target_ulong *val)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-*val = cpu->cfg.marchid;
+*val = riscv_cpu_cfg(env)->marchid;
 return RISCV_EXCP_NONE;
 }
 
 static RISCVException read_mimpid(CPURISCVState *env, int csrno,
   target_ulong *val)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
-
-*val = cpu->cfg.mimpid;
+*val = riscv_cpu_cfg(env)->mimpid;
 return RISCV_EXCP_NONE;
 }
 
-- 
2.39.2




[PATCH 0/4] RISCVCPUConfig related cleanups

2023-02-24 Thread Daniel Henrique Barboza
Hi,

These cleanups were suggested by LIU Zhiwei during the review of the
RISCV_FEATURE_* cleanups, currently on version 7 [1].

These are dependent on the patch "[PATCH v7 01/10] target/riscv: introduce
riscv_cpu_cfg()" from [1] because we use the riscv_cpu_cfg() API.


[1] https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg06467.html

Daniel Henrique Barboza (4):
  target/riscv/csr.c: use env_archcpu() in ctr()
  target/riscv/csr.c: simplify mctr()
  target/riscv/csr.c: use riscv_cpu_cfg() to avoid env_cpu() pointers
  target/riscv/csr.c: avoid env_archcpu() usages when reading
RISCVCPUConfig

 target/riscv/csr.c | 90 +-
 1 file changed, 24 insertions(+), 66 deletions(-)

-- 
2.39.2




[PATCH 4/4] target/riscv/csr.c: avoid env_archcpu() usages when reading RISCVCPUConfig

2023-02-24 Thread Daniel Henrique Barboza
Retrieving the CPU pointer using env_archcpu() just to access cpu->cfg
can be avoided by using riscv_cpu_cfg().

Suggested-by: LIU Zhiwei 
Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/csr.c | 32 +---
 1 file changed, 9 insertions(+), 23 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 53f1a331f9..ffa2d7b606 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -213,9 +213,7 @@ static RISCVException any32(CPURISCVState *env, int csrno)
 
 static int aia_any(CPURISCVState *env, int csrno)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_smaia) {
+if (!riscv_cpu_cfg(env)->ext_smaia) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -224,9 +222,7 @@ static int aia_any(CPURISCVState *env, int csrno)
 
 static int aia_any32(CPURISCVState *env, int csrno)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_smaia) {
+if (!riscv_cpu_cfg(env)->ext_smaia) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -253,9 +249,7 @@ static int smode32(CPURISCVState *env, int csrno)
 
 static int aia_smode(CPURISCVState *env, int csrno)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_ssaia) {
+if (!riscv_cpu_cfg(env)->ext_ssaia) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -264,9 +258,7 @@ static int aia_smode(CPURISCVState *env, int csrno)
 
 static int aia_smode32(CPURISCVState *env, int csrno)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_ssaia) {
+if (!riscv_cpu_cfg(env)->ext_ssaia) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -380,9 +372,7 @@ static RISCVException pointer_masking(CPURISCVState *env, 
int csrno)
 
 static int aia_hmode(CPURISCVState *env, int csrno)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_ssaia) {
+if (!riscv_cpu_cfg(env)->ext_ssaia) {
 return RISCV_EXCP_ILLEGAL_INST;
  }
 
@@ -391,9 +381,7 @@ static int aia_hmode(CPURISCVState *env, int csrno)
 
 static int aia_hmode32(CPURISCVState *env, int csrno)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_ssaia) {
+if (!riscv_cpu_cfg(env)->ext_ssaia) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -430,9 +418,7 @@ static RISCVException debug(CPURISCVState *env, int csrno)
 
 static RISCVException seed(CPURISCVState *env, int csrno)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_zkr) {
+if (!riscv_cpu_cfg(env)->ext_zkr) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -555,7 +541,7 @@ static RISCVException read_vl(CPURISCVState *env, int csrno,
 
 static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
 {
-*val = env_archcpu(env)->cfg.vlen >> 3;
+*val = riscv_cpu_cfg(env)->vlen >> 3;
 return RISCV_EXCP_NONE;
 }
 
@@ -610,7 +596,7 @@ static RISCVException write_vstart(CPURISCVState *env, int 
csrno,
  * The vstart CSR is defined to have only enough writable bits
  * to hold the largest element index, i.e. lg2(VLEN) bits.
  */
-env->vstart = val & ~(~0ULL << ctzl(env_archcpu(env)->cfg.vlen));
+env->vstart = val & ~(~0ULL << ctzl(riscv_cpu_cfg(env)->vlen));
 return RISCV_EXCP_NONE;
 }
 
-- 
2.39.2




[PATCH 1/4] target/riscv/csr.c: use env_archcpu() in ctr()

2023-02-24 Thread Daniel Henrique Barboza
We don't need to use env_cpu() and CPUState().

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/csr.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 75a540bfcb..3692617d13 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -108,8 +108,7 @@ static RISCVException vs(CPURISCVState *env, int csrno)
 static RISCVException ctr(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 int ctr_index;
 target_ulong ctr_mask;
 int base_csrno = CSR_CYCLE;
-- 
2.39.2




Re: [PATCH v5 8/8] hw/mem/cxl_type3: Add CXL RAS Error Injection Support.

2023-02-24 Thread Jonathan Cameron via
On Thu, 23 Feb 2023 14:27:48 +
Jonathan Cameron  wrote:

> On Thu, 23 Feb 2023 08:37:46 +0100
> Markus Armbruster  wrote:
> 
> > Thomas Huth  writes:
> >   
> > > On 22/02/2023 19.16, Philippe Mathieu-Daudé wrote:
> > >> +Thomas (meson) & Marc-André (conditional QAPI)
> > >
> > > + Markus
> > >
> > >> On 22/2/23 17:49, Jonathan Cameron wrote:
> > 
> > [...]
> >   
> > >> Doesn't these need
> > >>
> > >>     'if': 'CONFIG_CXL_MEM_DEVICE',
> > >>
> > >> ?
> > >
> > > If I make this change I get a bunch of
> > >
> > > ./qapi/qapi-types-cxl.h:18:13: error: attempt to use poisoned 
> > > "CONFIG_CXL_MEM_DEVICE"
> > >  18 | #if defined(CONFIG_CXL_MEM_DEVICE)
> > 
> >  Err, I meant the generic CONFIG_CXL, not CONFIG_CXL_MEM_DEVICE.
> > 
> > > It's a target specific define (I think) as built alongside PCI_EXPRESS
> > > Only CXL_ACPI is specifically included by x86 and arm64 (out of tree)
> > >
> > > To be honest though I don't fully understand the QEMU build system so 
> > > the reason
> > > for the error might be wrong.
> > 
> >  You need to restrict to system emulation (the 'have_system' check):
> > >>>
> > >>> This doesn't help - still have
> > >>> attempt to used poisoned "CONFIG_CXL"
> > >
> > > Not sure how the QAPI generator works, but target specific config 
> > > switches can only be used in target specific json files there, so that's 
> > > machine-target.json and misc-target.json currently, as far as I know. Not 
> > > sure how the QAPI generator distinguishes between common and target 
> > > specific code, though ... just by the "-target" suffix? Maybe Markus or 
> > > Marc-André can comment on that.
> > 
> > Whenever you use a poisoned macro in a conditional, all the code
> > generated for this .json file (we call it a "QAPI schema module")
> > becomes target-dependent.  The QAPI code generator itself is blissfully
> > unaware of this.
> > 
> > Since target-dependent code needs to be compiled differently, the build
> > process needs to be know which modules are target-dependent.  We do this
> > in one of the stupidest ways that could possibly work: a module is
> > target-dependent if its name ends with "-target".  There are just two
> > right now: qapi/machine-target.json and qapi/misc-target.json.
> > 
> > The logic resides in qapi/meson.build.  Look for
> > 
> > if module.endswith('-target')  
> 
> Thanks for all the pointers.
> > 
> > Questions?  
> 
> Is it sensible to make the cxl stuff all target dependent and do the 
> following?
> I like that we can get rid of the stubs if we do this but I'm sure there are
> disadvantages. Only alternative I can currently see is continue to have
> stubs and not make the qmp commands conditional on them doing anything useful.
> 
> Note this is on top of my tree so involves more changes - I'll push it down
> into the relevant series.

I got too focused on getting it to build, and failed to realize that the below
change results in the new commands not being available anywhere. Oops.

Anyhow, my current conclusion is there isn't an easy way to make these 
conditional
so we should just keep the stubs for non CXL supporting builds.

If I'm wrong on that, let me know.

Thanks,

Jonathan

> 
> From 551122103cf1f5bb4de8ee005482c72532181439 Mon Sep 17 00:00:00 2001
> From: Jonathan Cameron 
> Date: Thu, 23 Feb 2023 14:22:53 +
> Subject: [PATCH] hw/cxl: Make CXL compilation target specific
> 
> ---
>  hw/cxl/cxl-host-stubs.c| 15 
>  hw/cxl/meson.build |  6 +---
>  hw/mem/cxl_type3.c |  3 +-
>  hw/mem/cxl_type3_stubs.c   | 58 --
>  hw/mem/meson.build |  8 ++---
>  qapi/{cxl.json => cxl-target.json} | 37 +--
>  qapi/meson.build   |  2 +-
>  qapi/qapi-schema.json  |  2 +-
>  8 files changed, 35 insertions(+), 96 deletions(-)
> 
> diff --git a/hw/cxl/cxl-host-stubs.c b/hw/cxl/cxl-host-stubs.c
> deleted file mode 100644
> index cae4afcdde..00
> --- a/hw/cxl/cxl-host-stubs.c
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -/*
> - * CXL host parameter parsing routine stubs
> - *
> - * Copyright (c) 2022 Huawei
> - */
> -#include "qemu/osdep.h"
> -#include "qapi/error.h"
> -#include "hw/cxl/cxl.h"
> -#include "hw/cxl/cxl_host.h"
> -
> -void cxl_fmws_link_targets(CXLState *stat, Error **errp) {};
> -void cxl_machine_init(Object *obj, CXLState *state) {};
> -void cxl_hook_up_pxb_registers(PCIBus *bus, CXLState *state, Error **errp) 
> {};
> -
> -const MemoryRegionOps cfmws_ops;
> diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build
> index 99ee564ce8..99eeb84268 100644
> --- a/hw/cxl/meson.build
> +++ b/hw/cxl/meson.build
> @@ -1,4 +1,4 @@
> -softmmu_ss.add(when: 'CONFIG_CXL',
> +specific_ss.add(when: 'CONFIG_CXL',
> if_true: files(
> 

Re: question: QEMU guest with Virtiofs but without virtiofsd

2023-02-24 Thread Stefan Hajnoczi
On Fri, 24 Feb 2023 at 11:47, Ferenc Fejes  wrote:
> I'm using a QEMU VM with a debootstrap rootfs, shared over virtiofs for
> the guest. My best understanding is that virtiofsd must required even
> if just using one guest.

Yes, virtiofsd is required even if just one guest is accessing a
shared directory using a virtiofs device. The virtiofsd daemon is
responsible for emulating the virtiofs device (QEMU does not do the
emulation), so that's why it's essential even with just a single
guest.

> Looking around in the QEMU manpages I got a little bit confused by
> virtfs parameter. Is it something entirely connected with 9P or it is
> possible to pass folders to the guest through virtiofs without
> virtiofsd? Unfortunately none of my trial with the parameters
> succeeded.

There are two separate VIRTIO devices for sharing files/directories:
virtiofs and virtio-9p (sometimes called virtfs). It's easy to confuse
them because "virtiofs" and "virtfs" look similar. They have different
features and are completely independent of each other. In terms of the
file system protocol, virtiofs is based on Linux FUSE while virtio-9p
is based on the 9P protocol.

virtiofs uses the --device vhost-user-fs-pci syntax together with a
virtiofsd process.

virtio-9p uses either the full --device virtio-9p-pci and --fsdev
syntax or the shortcut --virtfs syntax that combines both these
options.

> Could someone can give me a confirmation if virtiofsd is must or its
> optional. Thanks in advance!

If you want to use virtiofs then virtiofsd is required.

If you use virtio-9p then virtiofsd is not needed.

In terms of which one you should use, both are widely used today.
Unless you have specific requirements, I think you can choose
whichever one seems most convenient to you.

Stefan



Re: [PATCH v16 08/11] qapi/s390x/cpu topology: set-cpu-topology monitor command

2023-02-24 Thread Nina Schoetterl-Glausch
On Wed, 2023-02-22 at 15:21 +0100, Pierre Morel wrote:
> The modification of the CPU attributes are done through a monitor
> command.
> 
> It allows to move the core inside the topology tree to optimize
> the cache usage in the case the host's hypervisor previously
> moved the CPU.
> 
> The same command allows to modify the CPU attributes modifiers
> like polarization entitlement and the dedicated attribute to notify
> the guest if the host admin modified scheduling or dedication of a vCPU.
> 
> With this knowledge the guest has the possibility to optimize the
> usage of the vCPUs.
> 
> The command has a feature unstable for the moment.
> 
> Signed-off-by: Pierre Morel 
> ---
>  qapi/machine-target.json |  35 +
>  include/monitor/hmp.h|   1 +
>  hw/s390x/cpu-topology.c  | 154 +++
>  hmp-commands.hx  |  17 +
>  4 files changed, 207 insertions(+)
> 
> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
> index a52cc32f09..baa9d273cf 100644
> --- a/qapi/machine-target.json
> +++ b/qapi/machine-target.json
> @@ -354,3 +354,38 @@
>  { 'enum': 'CpuS390Polarization',
>'prefix': 'S390_CPU_POLARIZATION',
>'data': [ 'horizontal', 'vertical' ] }
> +
> +##
> +# @set-cpu-topology:
> +#
> +# @core-id: the vCPU ID to be moved
> +# @socket-id: optional destination socket where to move the vCPU
> +# @book-id: optional destination book where to move the vCPU
> +# @drawer-id: optional destination drawer where to move the vCPU
> +# @entitlement: optional entitlement
> +# @dedicated: optional, if the vCPU is dedicated to a real CPU
> +#
> +# Features:
> +# @unstable: This command may still be modified.
> +#
> +# Modifies the topology by moving the CPU inside the topology
> +# tree or by changing a modifier attribute of a CPU.
> +# Default value for optional parameter is the current value
> +# used by the CPU.
> +#
> +# Returns: Nothing on success, the reason on failure.
> +#
> +# Since: 8.0
> +##
> +{ 'command': 'set-cpu-topology',
> +  'data': {
> +  'core-id': 'uint16',
> +  '*socket-id': 'uint16',
> +  '*book-id': 'uint16',
> +  '*drawer-id': 'uint16',
> +  '*entitlement': 'str',

How about you add a machine-common.json and define CpuS390Entitlement there,
and then include it from both machine.json and machine-target.json?

Then you can declare it as CpuS390Entitlement and don't need to do the parsing
manually.

You could also put it in common.json, but that seems a bit too generic.

Anyone have objections?

> +  '*dedicated': 'bool'
> +  },
> +  'features': [ 'unstable' ],
> +  'if': { 'all': [ 'TARGET_S390X' ] }
> +}
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index 2220f14fc9..4e65e6d08e 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -178,5 +178,6 @@ void hmp_ioport_read(Monitor *mon, const QDict *qdict);
>  void hmp_ioport_write(Monitor *mon, const QDict *qdict);
>  void hmp_boot_set(Monitor *mon, const QDict *qdict);
>  void hmp_info_mtree(Monitor *mon, const QDict *qdict);
> +void hmp_set_cpu_topology(Monitor *mon, const QDict *qdict);
>  
>  #endif
> diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c
> index ed5fc75381..3a7eb441a3 100644
> --- a/hw/s390x/cpu-topology.c
> +++ b/hw/s390x/cpu-topology.c
> @@ -19,6 +19,12 @@
>  #include "hw/s390x/s390-virtio-ccw.h"
>  #include "hw/s390x/cpu-topology.h"
>  #include "qapi/qapi-types-machine-target.h"
> +#include "qapi/qapi-types-machine.h"
> +#include "qapi/qapi-commands-machine-target.h"
> +#include "qapi/qmp/qdict.h"
> +#include "monitor/hmp.h"
> +#include "monitor/monitor.h"
> +
>  /*
>   * s390_topology is used to keep the topology information.
>   * .cores_per_socket: tracks information on the count of cores
> @@ -310,6 +316,26 @@ static void s390_topology_add_core_to_socket(S390CPU 
> *cpu, int drawer_id,
>  }
>  }
>  
> +/**
> + * s390_topology_need_report
> + * @cpu: Current cpu
> + * @drawer_id: future drawer ID
> + * @book_id: future book ID
> + * @socket_id: future socket ID
> + *
> + * A modified topology change report is needed if the
> + */
> +static int s390_topology_need_report(S390CPU *cpu, int drawer_id,
> +   int book_id, int socket_id,
> +   uint16_t entitlement, bool dedicated)
> +{
> +return cpu->env.drawer_id != drawer_id ||
> +   cpu->env.book_id != book_id ||
> +   cpu->env.socket_id != socket_id ||
> +   cpu->env.entitlement != entitlement ||
> +   cpu->env.dedicated != dedicated;
> +}
> +
>  /**
>   * s390_update_cpu_props:
>   * @ms: the machine state
> @@ -376,3 +402,131 @@ void s390_topology_setup_cpu(MachineState *ms, S390CPU 
> *cpu, Error **errp)
>  /* topology tree is reflected in props */
>  s390_update_cpu_props(ms, cpu);
>  }
> +
> +/*
> + * qmp and hmp implementations
> + */
> +
> +#define TOPOLOGY_SET(n) do {\
> +  

Re: [PATCH 5/5] hw/audio/via-ac97: Basic implementation of audio playback

2023-02-24 Thread Daniel Henrique Barboza




On 2/24/23 10:05, BALATON Zoltan wrote:

Just for some motivation, this is what we want to make possible for more people 
with QEMU 8.0: https://youtu.be/YY9RExl4VDI


That's neat!



This would need at least my SM502 patches and fixing the IRQ routing in the 
VT8231 (this test was with my series for that, I'll ask testing Bernhard's 
version the same way once I get it and rebase my patches on it). AmigaOS can 
use ES1370 so the via-ac97 patches are not that important now but the other 
patches would be needed. I hope users won't have to wait until September to try 
this.


If you're referring to "hw/display/sm501: Implement more 2D raster operations" 
then it's already
queued in ppc-next. In fact I believe you can re-send it with this series, with 
my r-b, and whoever
gets to send the PR can send everything at once.

If either Gerd of Phil wants to pick these up I have already acked the pegasos2 
changes.

If you want me to get this via qemu-ppc bear in mind that I need to send the PR 
March 7th
at the latest.


Thanks,


Daniel



While AmigaOS runs on sam460ex now, that versiion is much slower due to the 
limited PPC440 that doesn't have AltiVec and also due to some issues on the 
real platform it has to do more synchronisation which slows it down. The 
pegasos2 version runs much better and has a better chance to get it to work 
with KVM on PPC host so this would be a big improvement even if there would be 
more bugs to fix in upcoming releases but we'll never find those unless people 
can start using it and report them. More people are interested but less are 
able to compile and test from git repos and depend on binary distros instead.

Regards,
BALATON Zoltan




Re: [PATCH 3/5] hw/ppc/pegasos2: Fix PCI interrupt routing

2023-02-24 Thread Daniel Henrique Barboza




On 2/21/23 15:44, BALATON Zoltan wrote:

According to the PegasosII schematics the PCI interrupt lines are
connected to both the gpp pins of the Mv64361 north bridge and the
PINT pins of the VT8231 south bridge so guests can get interrupts from
either of these. So far we only had the MV64361 connections which
worked for on board devices but for additional PCI devices (such as
network or sound card added with -device) guest OSes expect interrupt
from the ISA IRQ 9 where the firmware routes these PCI interrupts in
VT8231 ISA bridge. After the previous patches we can now model this
and also remove the board specific connection from mv64361. Also
configure routing of these lines when using Virtual Open Firmware to
match board firmware for guests that expect this.

This fixes PCI interrupts on pegasos2 under Linux, MorphOS and AmigaOS.

Signed-off-by: BALATON Zoltan 
---


Reviewed-by: Daniel Henrique Barboza 


  hw/pci-host/mv64361.c |  4 
  hw/ppc/pegasos2.c | 26 +-
  2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
index f43f33fbd9..3d9132f989 100644
--- a/hw/pci-host/mv64361.c
+++ b/hw/pci-host/mv64361.c
@@ -874,10 +874,6 @@ static void mv64361_realize(DeviceState *dev, Error **errp)
  }
  sysbus_init_irq(SYS_BUS_DEVICE(dev), >cpu_irq);
  qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
-/* FIXME: PCI IRQ connections may be board specific */
-for (i = 0; i < PCI_NUM_PINS; i++) {
-s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
-}
  }
  
  static void mv64361_reset(DeviceState *dev)

diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index a9563f4fb2..4e1476673b 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -74,6 +74,8 @@ struct Pegasos2MachineState {
  MachineState parent_obj;
  PowerPCCPU *cpu;
  DeviceState *mv;
+qemu_irq mv_pirq[PCI_NUM_PINS];
+qemu_irq via_pirq[PCI_NUM_PINS];
  Vof *vof;
  void *fdt_blob;
  uint64_t kernel_addr;
@@ -96,6 +98,15 @@ static void pegasos2_cpu_reset(void *opaque)
  }
  }
  
+static void pegasos2_pci_irq(void *opaque, int n, int level)

+{
+Pegasos2MachineState *pm = opaque;
+
+/* PCI interrupt lines are connected to both MV64361 and VT8231 */
+qemu_set_irq(pm->mv_pirq[n], level);
+qemu_set_irq(pm->via_pirq[n], level);
+}
+
  static void pegasos2_init(MachineState *machine)
  {
  Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
@@ -107,7 +118,7 @@ static void pegasos2_init(MachineState *machine)
  I2CBus *i2c_bus;
  const char *fwname = machine->firmware ?: PROM_FILENAME;
  char *filename;
-int sz;
+int i, sz;
  uint8_t *spd_data;
  
  /* init CPU */

@@ -157,11 +168,18 @@ static void pegasos2_init(MachineState *machine)
  /* Marvell Discovery II system controller */
  pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
qdev_get_gpio_in(DEVICE(pm->cpu), 
PPC6xx_INPUT_INT)));
+for (i = 0; i < PCI_NUM_PINS; i++) {
+pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i);
+}
  pci_bus = mv64361_get_pci_bus(pm->mv, 1);
+pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);
  
  /* VIA VT8231 South Bridge (multifunction PCI device) */

  via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
   true, TYPE_VT8231_ISA));
+for (i = 0; i < PCI_NUM_PINS; i++) {
+pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
+}
  object_property_add_alias(OBJECT(machine), "rtc-time",
object_resolve_path_component(via, "rtc"),
"date");
@@ -268,6 +286,12 @@ static void pegasos2_machine_reset(MachineState *machine, 
ShutdownCause reason)
PCI_INTERRUPT_LINE, 2, 0x9);
  pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
0x50, 1, 0x2);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x55, 1, 0x90);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x56, 1, 0x99);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x57, 1, 0x90);
  
  pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 1) << 8) |

PCI_INTERRUPT_LINE, 2, 0x109);




Re: [PATCH] hw/display/sm501: Implement more 2D raster operations

2023-02-24 Thread Daniel Henrique Barboza




On 2/16/23 11:40, BALATON Zoltan wrote:

Add simple implementation for two raster operations that are used by
AmigaOS which fixes graphics problems in some progtams using these.

Signed-off-by: BALATON Zoltan 
---


Reviewed-by: Daniel Henrique Barboza 


And queued in ppc-next. Thanks,


Daniel


For definitions of these see:
https://learn.microsoft.com/en-us/windows/win32/gdi/ternary-raster-operations

  hw/display/sm501.c | 30 +-
  1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index e1d0591d36..58bc9701ee 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -753,7 +753,7 @@ static void sm501_2d_operation(SM501State *s)
  }
  
  if ((rop_mode && rop == 0x5) || (!rop_mode && rop == 0x55)) {

-/* Invert dest, is there a way to do this with pixman? */
+/* DSTINVERT, is there a way to do this with pixman? */
  unsigned int x, y, i;
  uint8_t *d = s->local_mem + dst_base;
  
@@ -763,6 +763,34 @@ static void sm501_2d_operation(SM501State *s)

  stn_he_p([i], bypp, ~ldn_he_p([i], bypp));
  }
  }
+} else if (!rop_mode && rop == 0x99) {
+/* DSxn, is there a way to do this with pixman? */
+unsigned int x, y, i, j;
+uint8_t *sp = s->local_mem + src_base;
+uint8_t *d = s->local_mem + dst_base;
+
+for (y = 0; y < height; y++) {
+i = (dst_x + (dst_y + y) * dst_pitch) * bypp;
+j = (src_x + (src_y + y) * src_pitch) * bypp;
+for (x = 0; x < width; x++, i += bypp, j += bypp) {
+stn_he_p([i], bypp,
+ ~(ldn_he_p([j], bypp) ^ ldn_he_p([i], 
bypp)));
+}
+}
+} else if (!rop_mode && rop == 0xee) {
+/* SRCPAINT, is there a way to do this with pixman? */
+unsigned int x, y, i, j;
+uint8_t *sp = s->local_mem + src_base;
+uint8_t *d = s->local_mem + dst_base;
+
+for (y = 0; y < height; y++) {
+i = (dst_x + (dst_y + y) * dst_pitch) * bypp;
+j = (src_x + (src_y + y) * src_pitch) * bypp;
+for (x = 0; x < width; x++, i += bypp, j += bypp) {
+stn_he_p([i], bypp,
+ ldn_he_p([j], bypp) | ldn_he_p([i], bypp));
+}
+}
  } else {
  /* Do copy src for unimplemented ops, better than unpainted area 
*/
  if ((rop_mode && (rop != 0xc || rop2_source_is_pattern)) ||




[PATCH 06/33] x86: pcihp: fix missing PCNT callchain when intermediate root-port has 'hotplug=off' set

2023-02-24 Thread Igor Mammedov
Beside BSEL numbers change (due to 2 extra root-ports in q35/miltibridge test),
following change is expected:

   Scope (\_SB.PCI0)
   {
  ...
  +Scope (S50)
  +{
  +Scope (S00)
  +{
  +Method (PCNT, 0, NotSerialized)
  +{
  +BNUM = Zero
  +DVNT (PCIU, One)
  +DVNT (PCID, 0x03)
  +}
  +}
  +
  +Method (PCNT, 0, NotSerialized)
  +{
  +^S00.PCNT
  +}
  +}
  ...
   Method (PCNT, 0, NotSerialized)
   {
  +^S50.PCNT ()
   ^S13.PCNT ()
   ^S12.PCNT ()
   ^S11.PCNT ()

I practice [1] hasn't broke anything since on hardware side we unset
hotplug_handler on such intermediate port => hotplug behind it has
not been properly wired and as result not worked.

1)
Fixes: ddab4d3fae4e8 ("pcihp: compose PCNT callchain right before its user 
_GPE._E01")
Signed-off-by: Igor Mammedov 
---
 hw/i386/acpi-build.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index b67dcbbb37..c0674ae2d1 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -516,16 +516,24 @@ static bool build_append_notfication_callback(Aml 
*parent_scope,
 PCIBus *sec;
 QObject *bsel;
 int nr_notifiers = 0;
+GQueue *pcnt_bus_list = g_queue_new();
 
 QLIST_FOREACH(sec, >child, sibling) {
 Aml *br_scope = aml_scope("S%.02X", sec->parent_dev->devfn);
-if (pci_bus_is_root(sec) ||
-!object_property_find(OBJECT(sec), ACPI_PCIHP_PROP_BSEL)) {
+if (pci_bus_is_root(sec)) {
 continue;
 }
 nr_notifiers = nr_notifiers +
build_append_notfication_callback(br_scope, sec);
-aml_append(parent_scope, br_scope);
+/*
+ * add new child scope to parent
+ * and keep track of bus that have PCNT,
+ * bus list is used later to call children PCNTs from this level PCNT
+ */
+if (nr_notifiers) {
+g_queue_push_tail(pcnt_bus_list, sec);
+aml_append(parent_scope, br_scope);
+}
 }
 
 /*
@@ -549,17 +557,13 @@ static bool build_append_notfication_callback(Aml 
*parent_scope,
 }
 
 /* Notify about child bus events in any case */
-QLIST_FOREACH(sec, >child, sibling) {
-if (pci_bus_is_root(sec) ||
-!object_property_find(OBJECT(sec), ACPI_PCIHP_PROP_BSEL)) {
-continue;
-}
-
+while ((sec = g_queue_pop_head(pcnt_bus_list))) {
 aml_append(method, aml_name("^S%.02X.PCNT", sec->parent_dev->devfn));
 }
 
 aml_append(parent_scope, method);
 qobject_unref(bsel);
+g_queue_free(pcnt_bus_list);
 return !!nr_notifiers;
 }
 
-- 
2.39.1




[PATCH 12/33] tests: acpi: whitelist DSDT blobs before isolating PCI _DSM func 0 prolog

2023-02-24 Thread Igor Mammedov
Signed-off-by: Igor Mammedov 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 35 +
 1 file changed, 35 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..7e7745db39 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,36 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/pc/DSDT",
+"tests/data/acpi/pc/DSDT.acpierst",
+"tests/data/acpi/pc/DSDT.acpihmat",
+"tests/data/acpi/pc/DSDT.bridge",
+"tests/data/acpi/pc/DSDT.cphp",
+"tests/data/acpi/pc/DSDT.dimmpxm",
+"tests/data/acpi/pc/DSDT.hpbridge",
+"tests/data/acpi/pc/DSDT.ipmikcs",
+"tests/data/acpi/pc/DSDT.memhp",
+"tests/data/acpi/pc/DSDT.nohpet",
+"tests/data/acpi/pc/DSDT.numamem",
+"tests/data/acpi/pc/DSDT.roothp",
+"tests/data/acpi/q35/DSDT",
+"tests/data/acpi/q35/DSDT.acpierst",
+"tests/data/acpi/q35/DSDT.acpihmat",
+"tests/data/acpi/q35/DSDT.acpihmat-noinitiator",
+"tests/data/acpi/q35/DSDT.applesmc",
+"tests/data/acpi/q35/DSDT.bridge",
+"tests/data/acpi/q35/DSDT.core-count2",
+"tests/data/acpi/q35/DSDT.cphp",
+"tests/data/acpi/q35/DSDT.cxl",
+"tests/data/acpi/q35/DSDT.dimmpxm",
+"tests/data/acpi/q35/DSDT.ipmibt",
+"tests/data/acpi/q35/DSDT.ipmismbus",
+"tests/data/acpi/q35/DSDT.ivrs",
+"tests/data/acpi/q35/DSDT.memhp",
+"tests/data/acpi/q35/DSDT.mmio64",
+"tests/data/acpi/q35/DSDT.multi-bridge",
+"tests/data/acpi/q35/DSDT.nohpet",
+"tests/data/acpi/q35/DSDT.numamem",
+"tests/data/acpi/q35/DSDT.pvpanic-isa",
+"tests/data/acpi/q35/DSDT.tis.tpm12",
+"tests/data/acpi/q35/DSDT.tis.tpm2",
+"tests/data/acpi/q35/DSDT.viot",
+"tests/data/acpi/q35/DSDT.xapic",
-- 
2.39.1




[PATCH 10/33] pcihp: piix4: do not redirect hotplug controller to piix4 when ACPI hotplug is disabled

2023-02-24 Thread Igor Mammedov
commit [1] added ability to disable ACPI PCI hotplug
on hostbridge but forgot to take into account that it
should disable all ACPI hotplug machinery in case both
hostbridge and bridge hotplug are disabled.

Commit [2] tried to fix that, however it forgot to
remove hotplug_handler override which hands hotplug
control over to piix4 hotplug controller
(uninitialized after [2]).

As result at the time bridge is plugged in, its default
(SHPC) hotplug handler is replaced by piix4 one in
  acpi_pcihp_device_plug_cb()
...
if (!s->legacy_piix &&
   ...
   qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev));

which is acting on uninitialized s->legacy_piix value
(0 by default) that was supposed to be initialized by
acpi_pcihp_init(), that is no longer called due to
following condition being false:

  piix4_acpi_system_hot_add_init()
if (s->use_acpi_hotplug_bridge || s->use_acpi_root_pci_hotplug) {

and the bridge ends up with piix4 as hotplug handler
instead of shpc one.

Followup hotplug on that bridge as result yields
piix4 specific error:

  Error: Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set

1) 3d7e78aa777 (Introduce a new flag for i440fx to disable PCI hotplug on the 
root bus)
2) df4008c9c59 (piix4: don't reserve hw resources when hotplug is off globally)

Fixes: df4008c9c59 (piix4: don't reserve hw resources when hotplug is off 
globally)
Signed-off-by: Igor Mammedov 
---
 hw/acpi/piix4.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index eac2125abd..8fc422829a 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -492,7 +492,6 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
 
 piix4_acpi_system_hot_add_init(pci_address_space_io(dev),
pci_get_bus(dev), s);
-qbus_set_hotplug_handler(BUS(pci_get_bus(dev)), OBJECT(s));
 
 piix4_pm_add_properties(s);
 }
@@ -564,6 +563,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 if (s->use_acpi_hotplug_bridge || s->use_acpi_root_pci_hotplug) {
 acpi_pcihp_init(OBJECT(s), >acpi_pci_hotplug, bus, parent,
 s->use_acpi_hotplug_bridge, ACPI_PCIHP_ADDR_PIIX4);
+qbus_set_hotplug_handler(BUS(pci_get_bus(PCI_DEVICE(s))), OBJECT(s));
 }
 
 s->cpu_hotplug_legacy = true;
-- 
2.39.1




Re: [PATCH] hw/mips/gt64xxx_pci: Don't endian-swap GT_PCI0_CFGADDR

2023-02-24 Thread Nathan Chancellor
On Thu, Feb 23, 2023 at 04:19:58PM +, Jiaxun Yang wrote:
> 145e2198d749 ("hw/mips/gt64xxx_pci: Endian-swap using PCI_HOST_BRIDGE
> MemoryRegionOps") converted CFGADDR/CFGDATA registers to use PCI_HOST_BRIDGE's
> accessor facility and enabled byte swap for both CFGADDR/CFGDATA register.
> 
> However CFGADDR as a ISD internal register is not controled by MByteSwap
> bit, it follows endian of all other ISD register, which means it ties to
> little endian.
> 
> Move mapping of CFGADDR out of gt64120_update_pci_cfgdata_mapping to disable
> endian-swapping.
> 
> This should fix some recent reports about poweroff hang.
> 
> Fixes: 145e2198d749 ("hw/mips/gt64xxx_pci: Endian-swap using PCI_HOST_BRIDGE 
> MemoryRegionOps")
> Signed-off-by: Jiaxun Yang 

Thanks for the fix!

Tested-by: Nathan Chancellor 

> ---
>  hw/pci-host/gt64120.c | 18 ++
>  1 file changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/hw/pci-host/gt64120.c b/hw/pci-host/gt64120.c
> index f226d0342039..82c15edb4698 100644
> --- a/hw/pci-host/gt64120.c
> +++ b/hw/pci-host/gt64120.c
> @@ -321,9 +321,6 @@ static void gt64120_isd_mapping(GT64120State *s)
>  static void gt64120_update_pci_cfgdata_mapping(GT64120State *s)
>  {
>  /* Indexed on MByteSwap bit, see Table 158: PCI_0 Command, Offset: 0xc00 
> */
> -static const MemoryRegionOps *pci_host_conf_ops[] = {
> -_host_conf_be_ops, _host_conf_le_ops
> -};
>  static const MemoryRegionOps *pci_host_data_ops[] = {
>  _host_data_be_ops, _host_data_le_ops
>  };
> @@ -339,15 +336,6 @@ static void 
> gt64120_update_pci_cfgdata_mapping(GT64120State *s)
>   * - Table 16: 32-bit PCI Transaction Endianess
>   * - Table 158: PCI_0 Command, Offset: 0xc00
>   */
> -if (memory_region_is_mapped(>conf_mem)) {
> -memory_region_del_subregion(>ISD_mem, >conf_mem);
> -object_unparent(OBJECT(>conf_mem));
> -}
> -memory_region_init_io(>conf_mem, OBJECT(phb),
> -  pci_host_conf_ops[s->regs[GT_PCI0_CMD] & 1],
> -  s, "pci-conf-idx", 4);
> -memory_region_add_subregion_overlap(>ISD_mem, GT_PCI0_CFGADDR << 2,
> ->conf_mem, 1);
>  
>  if (memory_region_is_mapped(>data_mem)) {
>  memory_region_del_subregion(>ISD_mem, >data_mem);
> @@ -1208,6 +1196,12 @@ static void gt64120_realize(DeviceState *dev, Error 
> **errp)
>  PCI_DEVFN(18, 0), TYPE_PCI_BUS);
>  
>  pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
> +memory_region_init_io(>conf_mem, OBJECT(phb),
> +  _host_conf_le_ops,
> +  s, "pci-conf-idx", 4);
> +memory_region_add_subregion_overlap(>ISD_mem, GT_PCI0_CFGADDR << 2,
> +>conf_mem, 1);
> +
>  
>  /*
>   * The whole address space decoded by the GT-64120A doesn't generate
> -- 
> 2.37.1 (Apple Git-137.1)
> 
> 



question: QEMU guest with Virtiofs but without virtiofsd

2023-02-24 Thread Ferenc Fejes
Hi!

I'm using a QEMU VM with a debootstrap rootfs, shared over virtiofs for
the guest. My best understanding is that virtiofsd must required even
if just using one guest.

Looking around in the QEMU manpages I got a little bit confused by
virtfs parameter. Is it something entirely connected with 9P or it is
possible to pass folders to the guest through virtiofs without
virtiofsd? Unfortunately none of my trial with the parameters
succeeded.

Could someone can give me a confirmation if virtiofsd is must or its
optional. Thanks in advance!

Best,
Ferenc



[PATCH 32/33] pcihp: move fields enabling hotplug into AcpiPciHpState

2023-02-24 Thread Igor Mammedov
... instead of duplicating them in piix4 and lpc and then
trying to pass them to pcihp routines as arguments.
it simplifies call sites and places pcihp specific in
its own structure.

Signed-off-by: Igor Mammedov 
---
 include/hw/acpi/pcihp.h |  8 
 include/hw/acpi/piix4.h |  2 --
 hw/acpi/acpi-pci-hotplug-stub.c |  5 ++---
 hw/acpi/ich9.c  | 15 +++
 hw/acpi/pcihp.c | 16 
 hw/acpi/piix4.c | 23 +--
 6 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index cd18ebdcdc..04c98511a4 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -49,14 +49,14 @@ typedef struct AcpiPciHpState {
 uint32_t acpi_index;
 PCIBus *root;
 MemoryRegion io;
-bool legacy_piix;
 uint16_t io_base;
 uint16_t io_len;
+bool use_acpi_hotplug_bridge;
+bool use_acpi_root_pci_hotplug;
 } AcpiPciHpState;
 
 void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
- MemoryRegion *address_space_io, bool bridges_enabled,
- uint16_t io_base);
+ MemoryRegion *address_space_io, uint16_t io_base);
 
 void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
@@ -69,7 +69,7 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler 
*hotplug_dev,
  Error **errp);
 
 /* Called on reset */
-void acpi_pcihp_reset(AcpiPciHpState *s, bool acpihp_root_off);
+void acpi_pcihp_reset(AcpiPciHpState *s);
 
 void build_append_pcihp_slots(Aml *parent_scope, PCIBus *bus);
 
diff --git a/include/hw/acpi/piix4.h b/include/hw/acpi/piix4.h
index be1f8ea80e..eb1c122d80 100644
--- a/include/hw/acpi/piix4.h
+++ b/include/hw/acpi/piix4.h
@@ -57,8 +57,6 @@ struct PIIX4PMState {
 Notifier powerdown_notifier;
 
 AcpiPciHpState acpi_pci_hotplug;
-bool use_acpi_hotplug_bridge;
-bool use_acpi_root_pci_hotplug;
 bool not_migrate_acpi_index;
 
 uint8_t disable_s3;
diff --git a/hw/acpi/acpi-pci-hotplug-stub.c b/hw/acpi/acpi-pci-hotplug-stub.c
index a43f6dafc9..d1794399f7 100644
--- a/hw/acpi/acpi-pci-hotplug-stub.c
+++ b/hw/acpi/acpi-pci-hotplug-stub.c
@@ -5,8 +5,7 @@
 const VMStateDescription vmstate_acpi_pcihp_pci_status;
 
 void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
- MemoryRegion *address_space_io, bool bridges_enabled,
- uint16_t io_base)
+ MemoryRegion *address_space_io, uint16_t io_base)
 {
 return;
 }
@@ -36,7 +35,7 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 return;
 }
 
-void acpi_pcihp_reset(AcpiPciHpState *s, bool acpihp_root_off)
+void acpi_pcihp_reset(AcpiPciHpState *s)
 {
 return;
 }
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index a93c470e9d..34a58fc07c 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -218,7 +218,7 @@ static bool vmstate_test_use_pcihp(void *opaque)
 {
 ICH9LPCPMRegs *s = opaque;
 
-return s->use_acpi_hotplug_bridge;
+return s->acpi_pci_hotplug.use_acpi_hotplug_bridge;
 }
 
 static const VMStateDescription vmstate_pcihp_state = {
@@ -277,8 +277,8 @@ static void pm_reset(void *opaque)
 }
 pm->smi_en_wmask = ~0;
 
-if (pm->use_acpi_hotplug_bridge) {
-acpi_pcihp_reset(>acpi_pci_hotplug, true);
+if (pm->acpi_pci_hotplug.use_acpi_hotplug_bridge) {
+acpi_pcihp_reset(>acpi_pci_hotplug);
 }
 
 acpi_update_sci(>acpi_regs, pm->irq);
@@ -320,12 +320,11 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 acpi_pm_tco_init(>tco_regs, >io);
 }
 
-if (pm->use_acpi_hotplug_bridge) {
+if (pm->acpi_pci_hotplug.use_acpi_hotplug_bridge) {
 acpi_pcihp_init(OBJECT(lpc_pci),
 >acpi_pci_hotplug,
 pci_get_bus(lpc_pci),
 pci_address_space_io(lpc_pci),
-true,
 ACPI_PCIHP_ADDR_ICH9);
 
 qbus_set_hotplug_handler(BUS(pci_get_bus(lpc_pci)),
@@ -407,14 +406,14 @@ static bool ich9_pm_get_acpi_pci_hotplug(Object *obj, 
Error **errp)
 {
 ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
 
-return s->pm.use_acpi_hotplug_bridge;
+return s->pm.acpi_pci_hotplug.use_acpi_hotplug_bridge;
 }
 
 static void ich9_pm_set_acpi_pci_hotplug(Object *obj, bool value, Error **errp)
 {
 ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
 
-s->pm.use_acpi_hotplug_bridge = value;
+s->pm.acpi_pci_hotplug.use_acpi_hotplug_bridge = value;
 }
 
 static bool ich9_pm_get_keep_pci_slot_hpc(Object *obj, Error **errp)
@@ -439,7 +438,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 pm->disable_s3 = 0;
 pm->disable_s4 = 0;
 pm->s4_val = 2;
-pm->use_acpi_hotplug_bridge = true;
+

[PATCH 28/33] pci: move acpi-index uniqueness check to generic PCI device code

2023-02-24 Thread Igor Mammedov
acpi-index is now working with non-hotpluggable buses
(pci/q35 machine hostbridge), it can be used even if
ACPI PCI hotplug is disabled and as result acpi-index
uniqueness check will be omitted (since the check is
done by ACPI PCI hotplug handler, which isn't wired
when ACPI PCI hotplug is disabled).
Move check and related code to generic PCIDevice so it
would be independent of ACPI PCI hotplug.

Signed-off-by: Igor Mammedov 
---
PS: this also one step closer to enabling acpi-index
support for microvm and virt/arm machines.
---
 hw/acpi/pcihp.c | 56 
 hw/pci/pci.c| 57 +
 2 files changed, 57 insertions(+), 56 deletions(-)

diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 5dc7377411..adf45e8443 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -54,21 +54,6 @@ typedef struct AcpiPciHpFind {
 PCIBus *bus;
 } AcpiPciHpFind;
 
-static gint g_cmp_uint32(gconstpointer a, gconstpointer b, gpointer user_data)
-{
-return a - b;
-}
-
-static GSequence *pci_acpi_index_list(void)
-{
-static GSequence *used_acpi_index_list;
-
-if (!used_acpi_index_list) {
-used_acpi_index_list = g_sequence_new(NULL);
-}
-return used_acpi_index_list;
-}
-
 static int acpi_pcihp_get_bsel(PCIBus *bus)
 {
 Error *local_err = NULL;
@@ -300,8 +285,6 @@ void acpi_pcihp_reset(AcpiPciHpState *s, bool 
acpihp_root_off)
 acpi_pcihp_update(s);
 }
 
-#define ONBOARD_INDEX_MAX (16 * 1024 - 1)
-
 void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
 {
@@ -314,34 +297,6 @@ void acpi_pcihp_device_pre_plug_cb(HotplugHandler 
*hotplug_dev,
ACPI_PCIHP_PROP_BSEL "' set");
 return;
 }
-
-/*
- * capped by systemd (see: udev-builtin-net_id.c)
- * as it's the only known user honor it to avoid users
- * misconfigure QEMU and then wonder why acpi-index doesn't work
- */
-if (pdev->acpi_index > ONBOARD_INDEX_MAX) {
-error_setg(errp, "acpi-index should be less or equal to %u",
-   ONBOARD_INDEX_MAX);
-return;
-}
-
-/*
- * make sure that acpi-index is unique across all present PCI devices
- */
-if (pdev->acpi_index) {
-GSequence *used_indexes = pci_acpi_index_list();
-
-if (g_sequence_lookup(used_indexes, GINT_TO_POINTER(pdev->acpi_index),
-  g_cmp_uint32, NULL)) {
-error_setg(errp, "a PCI device with acpi-index = %" PRIu32
-   " already exist", pdev->acpi_index);
-return;
-}
-g_sequence_insert_sorted(used_indexes,
- GINT_TO_POINTER(pdev->acpi_index),
- g_cmp_uint32, NULL);
-}
 }
 
 void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
@@ -401,17 +356,6 @@ void acpi_pcihp_device_unplug_cb(HotplugHandler 
*hotplug_dev, AcpiPciHpState *s,
 trace_acpi_pci_unplug(PCI_SLOT(pdev->devfn),
   acpi_pcihp_get_bsel(pci_get_bus(pdev)));
 
-/*
- * clean up acpi-index so it could reused by another device
- */
-if (pdev->acpi_index) {
-GSequence *used_indexes = pci_acpi_index_list();
-
-g_sequence_remove(g_sequence_lookup(used_indexes,
-  GINT_TO_POINTER(pdev->acpi_index),
-  g_cmp_uint32, NULL));
-}
-
 qdev_unrealize(dev);
 }
 
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index cc51f98593..d9be0cfca6 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -92,6 +92,21 @@ static const VMStateDescription vmstate_pcibus = {
 }
 };
 
+static gint g_cmp_uint32(gconstpointer a, gconstpointer b, gpointer user_data)
+{
+return a - b;
+}
+
+static GSequence *pci_acpi_index_list(void)
+{
+static GSequence *used_acpi_index_list;
+
+if (!used_acpi_index_list) {
+used_acpi_index_list = g_sequence_new(NULL);
+}
+return used_acpi_index_list;
+}
+
 static void pci_init_bus_master(PCIDevice *pci_dev)
 {
 AddressSpace *dma_as = pci_device_iommu_address_space(pci_dev);
@@ -1225,6 +1240,17 @@ static void pci_qdev_unrealize(DeviceState *dev)
 do_pci_unregister_device(pci_dev);
 
 pci_dev->msi_trigger = NULL;
+
+/*
+ * clean up acpi-index so it could reused by another device
+ */
+if (pci_dev->acpi_index) {
+GSequence *used_indexes = pci_acpi_index_list();
+
+g_sequence_remove(g_sequence_lookup(used_indexes,
+  GINT_TO_POINTER(pci_dev->acpi_index),
+  g_cmp_uint32, NULL));
+}
 }
 
 void pci_register_bar(PCIDevice *pci_dev, int region_num,
@@ -1980,6 +2006,8 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, 
uint8_t devfn)
 return bus->devices[devfn];
 }
 
+#define ONBOARD_INDEX_MAX (16 * 1024 - 1)
+
 static void pci_qdev_realize(DeviceState 

[PATCH 29/33] acpi: pci: drop BSEL usage when deciding that device isn't hotpluggable

2023-02-24 Thread Igor Mammedov
previous commit ("pci: fix 'hotplugglable' property behavior") fixed
pcie root port's 'hotpluggable' property to behave consistently.

So we don't need a BSEL crutch anymore to see of device is not
hotpluggable, drop it from 'generic' PCI slots description handling.

BSEL is still used to decide if hotplug part should be called
but that will be moved out of generic code to hotplug one by
followup patches.

Signed-off-by: Igor Mammedov 
---
 hw/i386/acpi-build.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 7b982b6072..6b51b7401d 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -590,7 +590,7 @@ void build_append_pci_bus_devices(Aml *parent_scope, PCIBus 
*bus)
 
 call_dev_aml_func(DEVICE(bus->devices[devfn]), dev);
 /* add _DSM if device has acpi-index set */
-if (pdev->acpi_index && !bsel &&
+if (pdev->acpi_index &&
 !object_property_get_bool(OBJECT(pdev), "hotpluggable",
   _abort)) {
 aml_append(dev, aml_pci_static_endpoint_dsm(pdev));
-- 
2.39.1




[PATCH 30/33] acpi: pci: move BSEL into build_append_pcihp_slots()

2023-02-24 Thread Igor Mammedov
Generic PCI enumeration code doesn't really need access to
BSEL value, it is only used as means to decide if hotplug
enumerator should be called.

Use stateless object_property_find() to do that, and move
the rest of BSEL handling into build_append_pcihp_slots()
where it belongs.

This cleans up generic code a bit from hotplug stuff
and follow up patch will remove remaining call to
build_append_pcihp_slots() from generic code, making
it possible to use without ACPI PCI hotplug dependencies.

Signed-off-by: Igor Mammedov 
---
 hw/i386/acpi-build.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 6b51b7401d..d068b0507e 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -519,12 +519,14 @@ static bool is_devfn_ignored_hotplug(const int devfn, 
const PCIBus *bus)
 return false;
 }
 
-static void build_append_pcihp_slots(Aml *parent_scope, PCIBus *bus,
- QObject *bsel)
+static void build_append_pcihp_slots(Aml *parent_scope, PCIBus *bus)
 {
 int devfn;
 Aml *dev, *notify_method = NULL, *method;
+QObject *bsel = object_property_get_qobject(OBJECT(bus),
+ACPI_PCIHP_PROP_BSEL, NULL);
 uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
+qobject_unref(bsel);
 
 aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
 notify_method = aml_method("DVNT", 2, AML_NOTSERIALIZED);
@@ -569,12 +571,9 @@ static void build_append_pcihp_slots(Aml *parent_scope, 
PCIBus *bus,
 
 void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
 {
-QObject *bsel;
 int devfn;
 Aml *dev;
 
-bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, 
NULL);
-
 for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
 /* ACPI spec: 1.0b: Table 6-2 _ADR Object Bus Types, PCI type */
 int adr = PCI_SLOT(devfn) << 16 | PCI_FUNC(devfn);
@@ -600,11 +599,9 @@ void build_append_pci_bus_devices(Aml *parent_scope, 
PCIBus *bus)
 aml_append(parent_scope, dev);
 }
 
-if (bsel) {
-build_append_pcihp_slots(parent_scope, bus, bsel);
+if (object_property_find(OBJECT(bus), ACPI_PCIHP_PROP_BSEL)) {
+build_append_pcihp_slots(parent_scope, bus);
 }
-
-qobject_unref(bsel);
 }
 
 static bool build_append_notfication_callback(Aml *parent_scope,
-- 
2.39.1




[PATCH 03/33] tests: acpi: update expected blobs

2023-02-24 Thread Igor Mammedov
expected changes:
Basically adds devices present on root bus in form:
  Device (SXX)
  {
 Name (_ADR, 0x)  // _ADR: Address
  }

On top of that For q35.noacpihp, all ACPI PCI hotplug
AML is removed and _OSC get native hotplug enabled:

   CreateDWordField (Arg3, 0x04, CDW2)
   CreateDWordField (Arg3, 0x08, CDW3)
   Local0 = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
  -Local0 &= 0x1E
  +Local0 &= 0x1F
   If ((Arg1 != One))
   {
   CDW1 |= 0x08
Signed-off-by: Igor Mammedov 
---
 tests/qtest/bios-tables-test-allowed-diff.h |   2 --
 tests/data/acpi/pc/DSDT.hpbrroot| Bin 3081 -> 3115 bytes
 tests/data/acpi/q35/DSDT.noacpihp   | Bin 8252 -> 7932 bytes
 3 files changed, 2 deletions(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index b2c5312871..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,3 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/pc/DSDT.hpbrroot",
-"tests/data/acpi/q35/DSDT.noacpihp",
diff --git a/tests/data/acpi/pc/DSDT.hpbrroot b/tests/data/acpi/pc/DSDT.hpbrroot
index 
a71ed4fbaa14be655c28a5e03e50157b4476e480..d77752960285a5afa6d0c0a04e400842f6acd2ed
 100644
GIT binary patch
delta 100
zcmeB_SS`Wj66_M9_;DlGJx(rXm6-Tor+5Kx<;|Zse=<548N_qMJGuk`Rj@Eb
YH}MA>S-=HY!2-qz6>JazgbH>B01xpO0

delta 66
zcmZ22(J8^@66_Mf$-}_Fcyc4xJx(r1rI`3+5KR#m%2Me=^D$TEuh2JGuk`RWLI|
NH}MA>8NdZt7ywGL58eO(

diff --git a/tests/data/acpi/q35/DSDT.noacpihp 
b/tests/data/acpi/q35/DSDT.noacpihp
index 
d68c472b460e4609a64ea67de3c4cebfca76164d..f35338db30a44638cc3a55d2870e0e377af4246f
 100644
GIT binary patch
delta 160
zcmdnv@W+@xe~<
z0!|8(r^?wU^9LJR#B;8NdZtAOZ*#tY86SgbFr@073;jSil6K
Lf@AYVxj04uw-F~b

delta 485
zcmexkyT^gcCDVuVVj)AP$0<6$dFLLkhnl<(+5VJ?9S<|m&9n^yTw
z6o2I_dDz)^Nx}m5shM0%OA-n|mNa+dFfjN7Nk)bwpq|>vNeq*dc>V(cLv12sVr^n2
zBNsbEVnJd@0s{k3uj=G1F7^T;Rwf2spgnLCAO;j9K~!xHVN{c1@)g}~72V{;
z65tUK#1Ze|>B1Y}7hvFMV8*}^9}40*dn$P3mlWibrYjVs7U!21C8rhx<$^;Txwtvv
zor8h}dAYdU84vIr;9-=Q+$odE^Cozjb`K(;E8t+a1~*TcQr6%
F000aMj?@4E

-- 
2.39.1




  1   2   3   >