[PATCH v3] virtio-balloon: optimize the virtio-balloon on the ARM platform

2023-03-08 Thread Yangming via
Optimize the virtio-balloon feature on the ARM platform by adding
a variable to keep track of the current hot-plugged pc-dimm size,
instead of traversing the virtual machine's memory modules to count
the current RAM size during the balloon inflation or deflation
process. This variable can be updated only when plugging or unplugging
the device, which will result in an increase of approximately 60%
efficiency of balloon process on the ARM platform.

We tested the total amount of time required for the balloon inflation process 
on ARM:
inflate the balloon to 64GB of a 128GB guest under stress.
Before: 102 seconds
After: 42 seconds

Signed-off-by: Qi Xi 
Signed-off-by: Ming Yang yangmin...@huawei.com
---
 hw/mem/pc-dimm.c   |  7 +++
 hw/virtio/virtio-balloon.c | 33 +
 include/hw/boards.h|  2 ++
 3 files changed, 14 insertions(+), 28 deletions(-)

diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 50ef83215c..37f1f4ccfd 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -81,6 +81,10 @@ void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine)
 
 memory_device_plug(MEMORY_DEVICE(dimm), machine);
 vmstate_register_ram(vmstate_mr, DEVICE(dimm));
+/* count only "real" DIMMs, not NVDIMMs */
+if (!object_dynamic_cast(OBJECT(dimm), TYPE_NVDIMM)) {
+machine->device_memory->dimm_size += memory_region_size(vmstate_mr);
+}
 }
 
 void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine)
@@ -90,6 +94,9 @@ void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine)
 
 memory_device_unplug(MEMORY_DEVICE(dimm), machine);
 vmstate_unregister_ram(vmstate_mr, DEVICE(dimm));
+if (!object_dynamic_cast(OBJECT(dimm), TYPE_NVDIMM)) {
+machine->device_memory->dimm_size -= memory_region_size(vmstate_mr);
+}
 }
 
 static int pc_dimm_slot2bitmap(Object *obj, void *opaque)
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 746f07c4d2..2814a47cb1 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -729,37 +729,14 @@ static void virtio_balloon_get_config(VirtIODevice *vdev, 
uint8_t *config_data)
 memcpy(config_data, &config, virtio_balloon_config_size(dev));
 }
 
-static int build_dimm_list(Object *obj, void *opaque)
-{
-GSList **list = opaque;
-
-if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
-DeviceState *dev = DEVICE(obj);
-if (dev->realized) { /* only realized DIMMs matter */
-*list = g_slist_prepend(*list, dev);
-}
-}
-
-object_child_foreach(obj, build_dimm_list, opaque);
-return 0;
-}
-
 static ram_addr_t get_current_ram_size(void)
 {
-GSList *list = NULL, *item;
-ram_addr_t size = current_machine->ram_size;
-
-build_dimm_list(qdev_get_machine(), &list);
-for (item = list; item; item = g_slist_next(item)) {
-Object *obj = OBJECT(item->data);
-if (!strcmp(object_get_typename(obj), TYPE_PC_DIMM)) {
-size += object_property_get_int(obj, PC_DIMM_SIZE_PROP,
-&error_abort);
-}
+MachineState *machine = MACHINE(qdev_get_machine());
+if (machine->device_memory) {
+return machine->ram_size + machine->device_memory->dimm_size;
+} else {
+return machine->ram_size;
 }
-g_slist_free(list);
-
-return size;
 }
 
 static bool virtio_balloon_page_poison_support(void *opaque)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 6fbbfd56c8..f840f88d54 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -292,10 +292,12 @@ struct MachineClass {
  * @base: address in guest physical address space where the memory
  * address space for memory devices starts
  * @mr: address space container for memory devices
+ * @dimm_size: the sum of plugged DIMMs' sizes
  */
 typedef struct DeviceMemoryState {
 hwaddr base;
 MemoryRegion mr;
+uint64_t dimm_size;
 } DeviceMemoryState;
 
 /**
-- 
2.33.0




Re: [PATCH] target/riscv/csr.c: fix H extension TVM trap

2023-03-08 Thread liweiwei


On 2023/3/8 20:34, chenyi2...@zju.edu.cn wrote:

From: Yi Chen

Trap accesses to hgatp if MSTATUS_TVM is enabled.
Don't trap accesses to vsatp even if MSTATUS_TVM is enabled.

Signed-off-by: Yi Chen
---
  target/riscv/csr.c | 18 ++
  1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index ab56663..09bc780 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2655,7 +2655,7 @@ static RISCVException read_satp(CPURISCVState *env, int 
csrno,
  return RISCV_EXCP_NONE;
  }
  
-if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {

+if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) && 
get_field(env->mstatus, MSTATUS_TVM)) {
  return RISCV_EXCP_ILLEGAL_INST;


This line seems too long (> 80).

And hstatus.VTVM should also be taken into consideration.

Similar to following write_satp.


  } else {
  *val = env->satp;
@@ -2683,7 +2683,7 @@ static RISCVException write_satp(CPURISCVState *env, int 
csrno,
  }
  
  if (vm && mask) {

-if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) && 
get_field(env->mstatus, MSTATUS_TVM)) {
  return RISCV_EXCP_ILLEGAL_INST;
  } else {
  /*
@@ -3047,14 +3047,24 @@ static RISCVException read_hgeip(CPURISCVState *env, 
int csrno,
  static RISCVException read_hgatp(CPURISCVState *env, int csrno,
   target_ulong *val)
  {
-*val = env->hgatp;
+if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+return RISCV_EXCP_ILLEGAL_INST;


This check will do before privilege check in riscv_csrrw_check. So it 
will make VS mode access trigger


ILLEGAL_INST exception, However, it should be VIRTUAL_INST exception in 
this case.


Regards,

Weiwei Li


+} else {
+*val = env->hgatp;
+}
+
  return RISCV_EXCP_NONE;
  }
  
  static RISCVException write_hgatp(CPURISCVState *env, int csrno,

target_ulong val)
  {
-env->hgatp = val;
+if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+return RISCV_EXCP_ILLEGAL_INST;
+} else {
+env->hgatp = val;
+}
+
  return RISCV_EXCP_NONE;
  }
  

Re: [PATCH for-8.1 17/17] target/riscv: rework write_misa()

2023-03-08 Thread LIU Zhiwei



On 2023/3/9 15:27, LIU Zhiwei wrote:


On 2023/3/9 4:19, Daniel Henrique Barboza wrote:

write_misa() must use as much common logic as possible, only specifying
the bits that are exclusive to the CSR write operation and TCG
internals.

Rewrite write_misa() to work as follows:

- supress RVC right after verifying that we're not updating RVG;

- mask the write using misa_ext_mask to avoid enabling unsupported
   extensions;

- emulate the steps done by the cpu init() functions: set cpu->cfg using
   the desired misa value, validate it, and then commit;

- fallback if the validation step fails. We'll need to re-write cpu->cfg
   with the original misa_ext value for the hart.

Let's keep write_misa() as experimental for now until this logic gains
enough mileage.

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/cpu.c |  7 +++---
  target/riscv/cpu.h |  2 ++
  target/riscv/csr.c | 53 +-
  3 files changed, 29 insertions(+), 33 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7be6a86305..4b2be32de3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -281,8 +281,7 @@ static uint32_t 
riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg)

  return ext;
  }
  -static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,
-   uint32_t misa_ext)
+static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg, uint32_t 
misa_ext)

  {
  cfg->ext_i = misa_ext & RVI;
  cfg->ext_e = misa_ext & RVE;
@@ -299,7 +298,7 @@ static void 
riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,

  cfg->ext_g = misa_ext & RVG;
  }
  -static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
+void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
  {
  env->misa_mxl_max = env->misa_mxl = mxl;
  env->misa_ext_mask = env->misa_ext = ext;
@@ -995,7 +994,7 @@ static void 
riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)

   * Check consistency between chosen extensions while setting
   * cpu->cfg accordingly, doing a set_misa() in the end.
   */
-static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error 
**errp)

+void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
  {
  RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
  CPUClass *cc = CPU_CLASS(mcc);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 013a1389d6..d64d0f8dd6 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -591,6 +591,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr 
address, int size,

  bool probe, uintptr_t retaddr);
  char *riscv_isa_string(RISCVCPU *cpu);
  void riscv_cpu_list(void);
+void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext);
+void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
    #define cpu_list riscv_cpu_list
  #define cpu_mmu_index riscv_cpu_mmu_index
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 02a5c2a5ca..2e75c75fcc 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1342,6 +1342,11 @@ static RISCVException read_misa(CPURISCVState 
*env, int csrno,

  static RISCVException write_misa(CPURISCVState *env, int csrno,
   target_ulong val)
  {
+    RISCVCPU *cpu = env_archcpu(env);
+    uint32_t hart_ext_mask = env->misa_ext_mask;
+    uint32_t hart_ext = env->misa_ext;
+    Error *local_err = NULL;
+
  if (!riscv_cpu_cfg(env)->misa_w) {
  /* drop write to misa */
  return RISCV_EXCP_NONE;
@@ -1352,34 +1357,6 @@ static RISCVException write_misa(CPURISCVState 
*env, int csrno,

  return RISCV_EXCP_NONE;
  }
  -    /* 'I' or 'E' must be present */
-    if (!(val & (RVI | RVE))) {
-    /* It is not, drop write to misa */
-    return RISCV_EXCP_NONE;
-    }
-
-    /* 'E' excludes all other extensions */
-    if (val & RVE) {
-    /*
- * when we support 'E' we can do "val = RVE;" however
- * for now we just drop writes if 'E' is present.
- */
-    return RISCV_EXCP_NONE;
-    }
-
-    /*
- * misa.MXL writes are not supported by QEMU.
- * Drop writes to those bits.
- */
-
-    /* Mask extensions that are not supported by this hart */
-    val &= env->misa_ext_mask;
-
-    /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
-    if ((val & RVD) && !(val & RVF)) {
-    val &= ~RVD;
-    }
-
  /*
   * Suppress 'C' if next instruction is not aligned
   * TODO: this should check next_pc
@@ -1388,18 +1365,36 @@ static RISCVException 
write_misa(CPURISCVState *env, int csrno,

  val &= ~RVC;
  }
  +    /* Mask extensions that are not supported by this hart */
+    val &= hart_ext_mask;
+
  /* If nothing changed, do nothing. */
  if (val == env->misa_ext) {
  return RISCV_EXCP_NONE;
  }
  +    /*
+ * Validate the new configuration. Rollback to previous
+ * values if something goes wrong.
+ */
+    set_misa(env, e

Re: [PATCH] use qatzip to acclerate the live migration

2023-03-08 Thread Philippe Mathieu-Daudé

Hi Dennis,

Thank for this patch.

On 8/3/23 01:59, dennis.wu wrote:

qatzip https://github.com/intel/QATzip is a project that
supply the zlib like api with the Intel QAT hardware.
compress and decompress performance with small data block
(4kb page) is low with qatzip API. so we compose multiple
pages into a multi page address structure which is a buffer
list, then we compose these pages together and then call
compress and decompress. we also expand the io_buf_size
since qat is fast have have stress to the IO_BUFF.

If there is no QAT hardware, qatzip will fall back to the
software with proper congfiguration. that mean if host server


Typo "configuration".


have the QAT hardware, while destination server don't have QAT,
the live migration still work well.

To use the qatzip, one parameter is added in both host and
destination side:
(qemu) migrate_set_parameter compress-with-qat 1
if you proper eabled the qatzip, then you can benefit from
the QAT accelleration.


"acceleration".


Since the compress/decompress offloading to the QAT hardware,
no CPU resource neede (only a periodomic polling need some CPU


"needed", "periodic"


resource).

 From the performance, with the same threads scale, with QATzip
(HW), the live migration will have 2~4 time of performance.

plan: so far qatzip API support SVM,but no batch APIs and the
requirement is raised. once the batch APIs ready, the perf expect
to reach close to 10x.

Signed-off-by: dennis.wu 

update


What do you mean by "update" here?

Please prefix the patch subject with 'migration:'.

Please Cc the maintainers, otherwise your patch won't be
reviewed / merged:

$ ./scripts/get_maintainer.pl -f qapi/migration.json
Juan Quintela  (maintainer:Migration)
"Dr. David Alan Gilbert"  (maintainer:Migration)
Eric Blake  (supporter:QAPI Schema)
Markus Armbruster  (supporter:QAPI Schema)
qemu-devel@nongnu.org (open list:All patches CC here)


---
  meson.build   |   3 +-
  migration/migration.c |  22 ++
  migration/migration.h |   1 +
  migration/qemu-file.c |  13 +-
  migration/qemu-file.h |   3 +
  migration/ram.c   | 771 ++
  monitor/hmp-cmds.c|   4 +
  qapi/migration.json   |   8 +-
  8 files changed, 687 insertions(+), 138 deletions(-)

diff --git a/meson.build b/meson.build
index 861de93c4f..2c8ecba936 100644
--- a/meson.build
+++ b/meson.build
@@ -464,6 +464,7 @@ if have_system or have_tools
method: 'pkg-config', kwargs: static_kwargs)
  endif
  zlib = dependency('zlib', required: true, kwargs: static_kwargs)
+qatzip = dependency('qatzip', required: true, method: 'pkg-config', kwargs: 
static_kwargs)


IIUC when using "required: true", all hosts (and non-Intel ones too)
won't be able to build QEMU if libqatzip is not available / installed.

If libqatzip is compatible with pkg-config, you can use "method:
'pkg-config', required: qatzip.found()".
Otherwise better is to provide a generic --enable-qatzip option in
meson_options.txt, then you can use "required: get_option('qatzip')"
here.

See: https://www.qemu.org/docs/master/devel/build-system.html#stage-2-meson


  libaio = not_found
  if not get_option('linux_aio').auto() or have_block
@@ -3058,7 +3059,7 @@ libmigration = static_library('migration', sources: 
migration_files + genh,
name_suffix: 'fa',
build_by_default: false)
  migration = declare_dependency(link_with: libmigration,
-   dependencies: [zlib, qom, io])
+   dependencies: [qatzip, zlib, qom, io])
  softmmu_ss.add(migration)
  
  block_ss = block_ss.apply(config_host, strict: false)

diff --git a/migration/migration.c b/migration/migration.c
index 695f0f2900..4a5c5c532e 100644
--- a/migration/migration.c
+++ b/migration/migration.c




@@ -2421,6 +2431,15 @@ bool migrate_postcopy_blocktime(void)
  return s->enabled_capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
  }
  
+bool migrate_compress_with_qat(void)

+{
+MigrationState *s;
+
+s = migrate_get_current();
+
+return s->parameters.compress_with_qat;
+}




--- a/migration/migration.h
+++ b/migration/migration.h
@@ -388,6 +388,7 @@ bool migrate_use_return_path(void);
  uint64_t ram_get_total_transferred_pages(void);
  
  bool migrate_use_compression(void);

+bool migrate_compress_with_qat(void);
  int migrate_compress_level(void);
  int migrate_compress_threads(void);
  int migrate_compress_wait_thread(void);
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index 1479cddad9..fd6adf04b4 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -22,6 +22,7 @@
   * THE SOFTWARE.
   */
  #include "qemu/osdep.h"
+#include 
  #include 
  #include "qemu/madvise.h"
  #include "qemu/error-report.h"
@@ -31,7 +32,8 @@
  #include "trace.h"
  #include "qapi/error.h"
  
-#define IO_BUF_SIZE 32768

+/* with qat hw, the io buffer size need to expand */


No need to explain what y

Re: [PATCH for-8.1 04/17] target/riscv: add PRIV_VERSION_LATEST macro

2023-03-08 Thread LIU Zhiwei



On 2023/3/9 4:19, Daniel Henrique Barboza wrote:

PRIV_VERSION_LATEST, at this moment assigned to PRIV_VERSION_1_12_0, is
used in all generic CPUs:

- riscv_any_cpu_init()
- rv32_base_cpu_init()
- rv64_base_cpu_init()
- rv128_base_cpu_init()

When a new PRIV version is made available we can just update the LATEST
macro.


IMHO, we should remove the privileged version check in the future. It is 
a combination of many extensions and should not be a constraint as every 
extension has its own name.


Zhiwei



Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/cpu.c | 8 
  target/riscv/cpu.h | 1 +
  2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 964817b9d2..62ef11180f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -338,7 +338,7 @@ static void riscv_any_cpu_init(Object *obj)
  VM_1_10_SV32 : VM_1_10_SV57);
  #endif
  
-env->priv_ver = PRIV_VERSION_1_12_0;

+env->priv_ver = PRIV_VERSION_LATEST;
  register_cpu_props(obj);
  }
  
@@ -350,7 +350,7 @@ static void rv64_base_cpu_init(Object *obj)

  set_misa(env, MXL_RV64, 0);
  register_cpu_props(obj);
  /* Set latest version of privileged specification */
-env->priv_ver = PRIV_VERSION_1_12_0;
+env->priv_ver = PRIV_VERSION_LATEST;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
  #endif
@@ -426,7 +426,7 @@ static void rv128_base_cpu_init(Object *obj)
  set_misa(env, MXL_RV128, 0);
  register_cpu_props(obj);
  /* Set latest version of privileged specification */
-env->priv_ver = PRIV_VERSION_1_12_0;
+env->priv_ver = PRIV_VERSION_LATEST;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
  #endif
@@ -439,7 +439,7 @@ static void rv32_base_cpu_init(Object *obj)
  set_misa(env, MXL_RV32, 0);
  register_cpu_props(obj);
  /* Set latest version of privileged specification */
-env->priv_ver = PRIV_VERSION_1_12_0;
+env->priv_ver = PRIV_VERSION_LATEST;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
  #endif
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 638e47c75a..af2e4b7695 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -89,6 +89,7 @@ enum {
  PRIV_VERSION_1_11_0,
  PRIV_VERSION_1_12_0,
  };
+#define PRIV_VERSION_LATEST PRIV_VERSION_1_12_0
  
  #define VEXT_VERSION_1_00_0 0x0001
  




Re: [PATCH for-8.1 03/17] target/riscv/cpu.c: remove set_priv_version()

2023-03-08 Thread LIU Zhiwei



On 2023/3/9 4:19, Daniel Henrique Barboza wrote:

The setter is doing nothing special. Just set env->priv_ver directly.

IMHO, No better than the older implementation.

Zhiwei



Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/cpu.c | 30 +-
  1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0baed79ec2..964817b9d2 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -240,11 +240,6 @@ static void set_misa(CPURISCVState *env, RISCVMXL mxl, 
uint32_t ext)
  env->misa_ext_mask = env->misa_ext = ext;
  }
  
-static void set_priv_version(CPURISCVState *env, int priv_ver)

-{
-env->priv_ver = priv_ver;
-}
-
  #ifndef CONFIG_USER_ONLY
  static uint8_t satp_mode_from_str(const char *satp_mode_str)
  {
@@ -343,7 +338,7 @@ static void riscv_any_cpu_init(Object *obj)
  VM_1_10_SV32 : VM_1_10_SV57);
  #endif
  
-set_priv_version(env, PRIV_VERSION_1_12_0);

+env->priv_ver = PRIV_VERSION_1_12_0;
  register_cpu_props(obj);
  }
  
@@ -355,7 +350,7 @@ static void rv64_base_cpu_init(Object *obj)

  set_misa(env, MXL_RV64, 0);
  register_cpu_props(obj);
  /* Set latest version of privileged specification */
-set_priv_version(env, PRIV_VERSION_1_12_0);
+env->priv_ver = PRIV_VERSION_1_12_0;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
  #endif
@@ -366,7 +361,7 @@ static void rv64_sifive_u_cpu_init(Object *obj)
  CPURISCVState *env = &RISCV_CPU(obj)->env;
  set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
  register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
  #endif
@@ -379,7 +374,7 @@ static void rv64_sifive_e_cpu_init(Object *obj)
  
  set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);

  register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
  cpu->cfg.mmu = false;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -392,7 +387,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
  RISCVCPU *cpu = RISCV_CPU(obj);
  
  set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);

-set_priv_version(env, PRIV_VERSION_1_11_0);
+env->priv_ver = PRIV_VERSION_1_11_0;
  
  cpu->cfg.ext_g = true;

  cpu->cfg.ext_c = true;
@@ -431,7 +426,7 @@ static void rv128_base_cpu_init(Object *obj)
  set_misa(env, MXL_RV128, 0);
  register_cpu_props(obj);
  /* Set latest version of privileged specification */
-set_priv_version(env, PRIV_VERSION_1_12_0);
+env->priv_ver = PRIV_VERSION_1_12_0;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
  #endif
@@ -444,7 +439,7 @@ static void rv32_base_cpu_init(Object *obj)
  set_misa(env, MXL_RV32, 0);
  register_cpu_props(obj);
  /* Set latest version of privileged specification */
-set_priv_version(env, PRIV_VERSION_1_12_0);
+env->priv_ver = PRIV_VERSION_1_12_0;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
  #endif
@@ -454,8 +449,9 @@ static void rv32_sifive_u_cpu_init(Object *obj)
  {
  CPURISCVState *env = &RISCV_CPU(obj)->env;
  set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+
  register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
  #endif
@@ -468,7 +464,7 @@ static void rv32_sifive_e_cpu_init(Object *obj)
  
  set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);

  register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
  cpu->cfg.mmu = false;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -482,7 +478,7 @@ static void rv32_ibex_cpu_init(Object *obj)
  
  set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);

  register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_11_0);
+env->priv_ver = PRIV_VERSION_1_11_0;
  cpu->cfg.mmu = false;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -497,7 +493,7 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
  
  set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);

  register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
  cpu->cfg.mmu = false;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -1159,7 +1155,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  }
  
  if (priv_version >= 

Re: [PATCH for-8.1 02/17] target/riscv/cpu.c: remove set_vext_version()

2023-03-08 Thread LIU Zhiwei



On 2023/3/9 4:19, Daniel Henrique Barboza wrote:

This setter is doing nothing else but setting env->vext_ver. Assign the
value directly.


IMHO, No better than the older implementation.

Zhiwei



Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/cpu.c | 7 +--
  1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5060a98b6d..0baed79ec2 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -245,11 +245,6 @@ static void set_priv_version(CPURISCVState *env, int 
priv_ver)
  env->priv_ver = priv_ver;
  }
  
-static void set_vext_version(CPURISCVState *env, int vext_ver)

-{
-env->vext_ver = vext_ver;
-}
-
  #ifndef CONFIG_USER_ONLY
  static uint8_t satp_mode_from_str(const char *satp_mode_str)
  {
@@ -839,7 +834,7 @@ static void riscv_cpu_validate_v(CPURISCVState *env, 
RISCVCPUConfig *cfg,
  qemu_log("vector version is not specified, "
   "use the default value v1.0\n");
  }
-set_vext_version(env, vext_version);
+env->vext_ver = vext_version;
  }
  
  /*




Re: [PATCH for-8.1 17/17] target/riscv: rework write_misa()

2023-03-08 Thread LIU Zhiwei



On 2023/3/9 4:19, Daniel Henrique Barboza wrote:

write_misa() must use as much common logic as possible, only specifying
the bits that are exclusive to the CSR write operation and TCG
internals.

Rewrite write_misa() to work as follows:

- supress RVC right after verifying that we're not updating RVG;

- mask the write using misa_ext_mask to avoid enabling unsupported
   extensions;

- emulate the steps done by the cpu init() functions: set cpu->cfg using
   the desired misa value, validate it, and then commit;

- fallback if the validation step fails. We'll need to re-write cpu->cfg
   with the original misa_ext value for the hart.

Let's keep write_misa() as experimental for now until this logic gains
enough mileage.

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/cpu.c |  7 +++---
  target/riscv/cpu.h |  2 ++
  target/riscv/csr.c | 53 +-
  3 files changed, 29 insertions(+), 33 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7be6a86305..4b2be32de3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -281,8 +281,7 @@ static uint32_t 
riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg)
  return ext;
  }
  
-static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,

-   uint32_t misa_ext)
+static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg, uint32_t misa_ext)
  {
  cfg->ext_i = misa_ext & RVI;
  cfg->ext_e = misa_ext & RVE;
@@ -299,7 +298,7 @@ static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,
  cfg->ext_g = misa_ext & RVG;
  }
  
-static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)

+void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
  {
  env->misa_mxl_max = env->misa_mxl = mxl;
  env->misa_ext_mask = env->misa_ext = ext;
@@ -995,7 +994,7 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU 
*cpu)
   * Check consistency between chosen extensions while setting
   * cpu->cfg accordingly, doing a set_misa() in the end.
   */
-static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
+void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
  {
  RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
  CPUClass *cc = CPU_CLASS(mcc);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 013a1389d6..d64d0f8dd6 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -591,6 +591,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
  bool probe, uintptr_t retaddr);
  char *riscv_isa_string(RISCVCPU *cpu);
  void riscv_cpu_list(void);
+void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext);
+void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
  
  #define cpu_list riscv_cpu_list

  #define cpu_mmu_index riscv_cpu_mmu_index
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 02a5c2a5ca..2e75c75fcc 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1342,6 +1342,11 @@ static RISCVException read_misa(CPURISCVState *env, int 
csrno,
  static RISCVException write_misa(CPURISCVState *env, int csrno,
   target_ulong val)
  {
+RISCVCPU *cpu = env_archcpu(env);
+uint32_t hart_ext_mask = env->misa_ext_mask;
+uint32_t hart_ext = env->misa_ext;
+Error *local_err = NULL;
+
  if (!riscv_cpu_cfg(env)->misa_w) {
  /* drop write to misa */
  return RISCV_EXCP_NONE;
@@ -1352,34 +1357,6 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
  return RISCV_EXCP_NONE;
  }
  
-/* 'I' or 'E' must be present */

-if (!(val & (RVI | RVE))) {
-/* It is not, drop write to misa */
-return RISCV_EXCP_NONE;
-}
-
-/* 'E' excludes all other extensions */
-if (val & RVE) {
-/*
- * when we support 'E' we can do "val = RVE;" however
- * for now we just drop writes if 'E' is present.
- */
-return RISCV_EXCP_NONE;
-}
-
-/*
- * misa.MXL writes are not supported by QEMU.
- * Drop writes to those bits.
- */
-
-/* Mask extensions that are not supported by this hart */
-val &= env->misa_ext_mask;
-
-/* 'D' depends on 'F', so clear 'D' if 'F' is not present */
-if ((val & RVD) && !(val & RVF)) {
-val &= ~RVD;
-}
-
  /*
   * Suppress 'C' if next instruction is not aligned
   * TODO: this should check next_pc
@@ -1388,18 +1365,36 @@ static RISCVException write_misa(CPURISCVState *env, 
int csrno,
  val &= ~RVC;
  }
  
+/* Mask extensions that are not supported by this hart */

+val &= hart_ext_mask;
+
  /* If nothing changed, do nothing. */
  if (val == env->misa_ext) {
  return RISCV_EXCP_NONE;
  }
  
+/*

+ * Validate the new configuration. Rollback to previous
+ * values if something goes wrong.
+ */
+set_misa(env, env->misa_mxl, val);
+riscv_cpu_vali

[PATCH 0/4] target/riscv: Some CPURISCVState related cleanup and simplification

2023-03-08 Thread Weiwei Li
The patchset tries to:

- Use riscv_cpu_cfg(env) instead of env_archcpu().cfg.
- Use env_archcpu() to get RISCVCPU pointer from env directly
- Use CPURISCVState as argument directly in riscv_cpu_update_mip and 
riscv_timer_write_timecmp to simplify type conversion
- Remove RISCVCPU argument of riscv_csrrw_check, and get cfg infomation from 
CPURISCVState directly

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-cleanup-upstream

Weiwei Li (4):
  target/riscv: Avoid env_archcpu() when reading RISCVCPUConfig
  target/riscv: Simplify getting RISCVCPU pointer from env
  target/riscv: Simplify type conversion for CPURISCVState
  target/riscv: Simplify arguments for riscv_csrrw_check

 target/riscv/cpu.c |  6 +--
 target/riscv/cpu.h |  3 +-
 target/riscv/cpu_helper.c  | 17 
 target/riscv/csr.c | 87 --
 target/riscv/gdbstub.c |  4 +-
 target/riscv/pmu.c | 14 +++---
 target/riscv/time_helper.c | 15 +++
 target/riscv/time_helper.h |  2 +-
 8 files changed, 57 insertions(+), 91 deletions(-)

-- 
2.25.1




[PATCH 4/4] target/riscv: Simplify arguments for riscv_csrrw_check

2023-03-08 Thread Weiwei Li
Remove RISCVCPU argument, and get cfg infomation from CPURISCVState
directly.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/csr.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 53143f4d9a..80fc15e4d6 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3755,15 +3755,14 @@ static RISCVException rmw_seed(CPURISCVState *env, int 
csrno,
 
 static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
int csrno,
-   bool write_mask,
-   RISCVCPU *cpu)
+   bool write_mask)
 {
 /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
 bool read_only = get_field(csrno, 0xC00) == 3;
 int csr_min_priv = csr_ops[csrno].min_priv_ver;
 
 /* ensure the CSR extension is enabled */
-if (!cpu->cfg.ext_icsr) {
+if (!riscv_cpu_cfg(env)->ext_icsr) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -3859,9 +3858,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-RISCVException ret = riscv_csrrw_check(env, csrno, write_mask, cpu);
+RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
 if (ret != RISCV_EXCP_NONE) {
 return ret;
 }
@@ -3914,9 +3911,8 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int 
csrno,
 Int128 new_value, Int128 write_mask)
 {
 RISCVException ret;
-RISCVCPU *cpu = env_archcpu(env);
 
-ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask), cpu);
+ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
 if (ret != RISCV_EXCP_NONE) {
 return ret;
 }
-- 
2.25.1




[PATCH 1/4] target/riscv: Avoid env_archcpu() when reading RISCVCPUConfig

2023-03-08 Thread Weiwei Li
Use riscv_cpu_cfg(env) instead of env_archcpu().cfg.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/cpu_helper.c |  9 -
 target/riscv/csr.c| 40 ---
 target/riscv/gdbstub.c|  4 ++--
 3 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index f88c503cf4..e677255f87 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -314,7 +314,6 @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env,
 int extirq, unsigned int extirq_def_prio,
 uint64_t pending, uint8_t *iprio)
 {
-RISCVCPU *cpu = env_archcpu(env);
 int irq, best_irq = RISCV_EXCP_NONE;
 unsigned int prio, best_prio = UINT_MAX;
 
@@ -323,7 +322,8 @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env,
 }
 
 irq = ctz64(pending);
-if (!((extirq == IRQ_M_EXT) ? cpu->cfg.ext_smaia : cpu->cfg.ext_ssaia)) {
+if (!((extirq == IRQ_M_EXT) ? riscv_cpu_cfg(env)->ext_smaia :
+  riscv_cpu_cfg(env)->ext_ssaia)) {
 return irq;
 }
 
@@ -765,7 +765,6 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 int mode = mmu_idx & TB_FLAGS_PRIV_MMU_MASK;
 bool use_background = false;
 hwaddr ppn;
-RISCVCPU *cpu = env_archcpu(env);
 int napot_bits = 0;
 target_ulong napot_mask;
 
@@ -946,7 +945,7 @@ restart:
 
 if (riscv_cpu_sxl(env) == MXL_RV32) {
 ppn = pte >> PTE_PPN_SHIFT;
-} else if (pbmte || cpu->cfg.ext_svnapot) {
+} else if (pbmte || riscv_cpu_cfg(env)->ext_svnapot) {
 ppn = (pte & (target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT;
 } else {
 ppn = pte >> PTE_PPN_SHIFT;
@@ -1043,7 +1042,7 @@ restart:
benefit. */
 target_ulong vpn = addr >> PGSHIFT;
 
-if (cpu->cfg.ext_svnapot && (pte & PTE_N)) {
+if (riscv_cpu_cfg(env)->ext_svnapot && (pte & PTE_N)) {
 napot_bits = ctzl(ppn) + 1;
 if ((i != (levels - 1)) || (napot_bits != 4)) {
 return TRANSLATE_FAIL;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index ab566639e5..b453d8e8ca 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -88,9 +88,7 @@ static RISCVException fs(CPURISCVState *env, int csrno)
 
 static RISCVException vs(CPURISCVState *env, int csrno)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (cpu->cfg.ext_zve32f) {
+if (riscv_cpu_cfg(env)->ext_zve32f) {
 #if !defined(CONFIG_USER_ONLY)
 if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -193,9 +191,7 @@ static RISCVException mctr32(CPURISCVState *env, int csrno)
 
 static RISCVException sscofpmf(CPURISCVState *env, int csrno)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_sscofpmf) {
+if (!riscv_cpu_cfg(env)->ext_sscofpmf) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -310,9 +306,7 @@ static RISCVException umode32(CPURISCVState *env, int csrno)
 
 static RISCVException mstateen(CPURISCVState *env, int csrno)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_smstateen) {
+if (!riscv_cpu_cfg(env)->ext_smstateen) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -321,9 +315,7 @@ static RISCVException mstateen(CPURISCVState *env, int 
csrno)
 
 static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-if (!cpu->cfg.ext_smstateen) {
+if (!riscv_cpu_cfg(env)->ext_smstateen) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
@@ -390,10 +382,9 @@ static RISCVException sstateen(CPURISCVState *env, int 
csrno)
 
 static RISCVException sstc(CPURISCVState *env, int csrno)
 {
-RISCVCPU *cpu = env_archcpu(env);
 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;
 }
 
@@ -1170,27 +1161,21 @@ static RISCVException write_ignore(CPURISCVState *env, 
int csrno,
 static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-*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)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-*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)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
-*val = cpu->cfg.mimpid;
+*val = riscv_cpu_

[PATCH 2/4] target/riscv: Simplify getting RISCVCPU pointer from env

2023-03-08 Thread Weiwei Li
Use env_archcpu() to get RISCVCPU pointer from env directly.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/pmu.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index b8e56d2b7b..a200741083 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -223,7 +223,7 @@ bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
 return true;
 }
 
-cpu = RISCV_CPU(env_cpu(env));
+cpu = env_archcpu(env);
 if (!cpu->pmu_event_ctr_map) {
 return false;
 }
@@ -249,7 +249,7 @@ bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env, 
uint32_t target_ctr)
 return true;
 }
 
-cpu = RISCV_CPU(env_cpu(env));
+cpu = env_archcpu(env);
 if (!cpu->pmu_event_ctr_map) {
 return false;
 }
@@ -289,7 +289,7 @@ int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t 
value,
uint32_t ctr_idx)
 {
 uint32_t event_idx;
-RISCVCPU *cpu = RISCV_CPU(env_cpu(env));
+RISCVCPU *cpu = env_archcpu(env);
 
 if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->pmu_event_ctr_map) {
 return -1;
@@ -390,7 +390,7 @@ int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t 
value, uint32_t ctr_idx)
 {
 uint64_t overflow_delta, overflow_at;
 int64_t overflow_ns, overflow_left = 0;
-RISCVCPU *cpu = RISCV_CPU(env_cpu(env));
+RISCVCPU *cpu = env_archcpu(env);
 PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
 
 if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->cfg.ext_sscofpmf) {
-- 
2.25.1




[PATCH 3/4] target/riscv: Simplify type conversion for CPURISCVState

2023-03-08 Thread Weiwei Li
Use CPURISCVState as argument directly in riscv_cpu_update_mip and
riscv_timer_write_timecmp, since type converts from CPURISCVState to
RISCVCPU in many caller of them and then back to CPURISCVState in them.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/cpu.c |  6 +++---
 target/riscv/cpu.h |  3 ++-
 target/riscv/cpu_helper.c  |  8 
 target/riscv/csr.c | 35 +++
 target/riscv/pmu.c |  6 +++---
 target/riscv/time_helper.c | 15 +++
 target/riscv/time_helper.h |  2 +-
 7 files changed, 31 insertions(+), 44 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1e97473af2..16e465a0ab 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1302,7 +1302,7 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int 
level)
 if (kvm_enabled()) {
 kvm_riscv_set_irq(cpu, irq, level);
 } else {
-riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level));
+riscv_cpu_update_mip(env, 1 << irq, BOOL_TO_MASK(level));
 }
  break;
 case IRQ_S_EXT:
@@ -1310,7 +1310,7 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int 
level)
 kvm_riscv_set_irq(cpu, irq, level);
 } else {
 env->external_seip = level;
-riscv_cpu_update_mip(cpu, 1 << irq,
+riscv_cpu_update_mip(env, 1 << irq,
  BOOL_TO_MASK(level | env->software_seip));
 }
 break;
@@ -1336,7 +1336,7 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int 
level)
 }
 
 /* Update mip.SGEIP bit */
-riscv_cpu_update_mip(cpu, MIP_SGEIP,
+riscv_cpu_update_mip(env, MIP_SGEIP,
  BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
 } else {
 g_assert_not_reached();
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 638e47c75a..5adefe4ab5 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -602,7 +602,8 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr 
addr);
 bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
 void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts);
-uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value);
+uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask,
+  uint64_t value);
 #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
 void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *),
  void *arg);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e677255f87..824f0cbd92 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -590,7 +590,7 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool 
enable)
  *
  * To solve this, we check and inject interrupt after setting V=1.
  */
-riscv_cpu_update_mip(env_archcpu(env), 0, 0);
+riscv_cpu_update_mip(env, 0, 0);
 }
 }
 
@@ -610,10 +610,10 @@ int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t 
interrupts)
 }
 }
 
-uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
+uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask,
+  uint64_t value)
 {
-CPURISCVState *env = &cpu->env;
-CPUState *cs = CPU(cpu);
+CPUState *cs = env_cpu(env);
 uint64_t gein, vsgein = 0, vstip = 0, old = env->mip;
 
 if (riscv_cpu_virt_enabled(env)) {
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index b453d8e8ca..53143f4d9a 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -990,15 +990,13 @@ static RISCVException read_vstimecmph(CPURISCVState *env, 
int csrno,
 static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
   target_ulong val)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
 if (riscv_cpu_mxl(env) == MXL_RV32) {
 env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val);
 } else {
 env->vstimecmp = val;
 }
 
-riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
+riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
   env->htimedelta, MIP_VSTIP);
 
 return RISCV_EXCP_NONE;
@@ -1007,10 +1005,8 @@ static RISCVException write_vstimecmp(CPURISCVState 
*env, int csrno,
 static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
target_ulong val)
 {
-RISCVCPU *cpu = env_archcpu(env);
-
 env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val);
-riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
+riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
  

Re: [PATCH for-8.1 14/17] target/riscv/cpu.c: do not allow RVE to be set

2023-03-08 Thread LIU Zhiwei



On 2023/3/9 4:19, Daniel Henrique Barboza wrote:

This restriction is found at the current implementation of write_misa()
in csr.c. Add it in riscv_cpu_validate_set_extensions() as well, while
also removing the checks we're doing considering that I or E can be
enabled.

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/cpu.c | 12 ++--
  1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 49f0fd2c11..7a5d202069 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1045,15 +1045,15 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
  cpu->cfg.ext_ifencei = true;
  }
  
-if (cpu->cfg.ext_i && cpu->cfg.ext_e) {

-error_setg(errp,
-   "I and E extensions are incompatible");
+/* We do not have RV32E support  */
+if (cpu->cfg.ext_e) {
+error_setg(errp, "E extension (RV32E) is not supported");
  return;
  }
  
-if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {

-error_setg(errp,
-   "Either I or E extension must be set");
+/* When RV32E is supported we'll need to check for either I or E */
+if (!cpu->cfg.ext_i) {
+error_setg(errp, "I extension must be set");


We currently have supported the RV64E and RV32E in fact. Although we 
miss some checking when decoding, the current QEMU can run programs 
written for RVE.  So we should not prohibit the RVE here.


Zhiwei


  return;
  }
  




Re: [PATCH] block: add missing coroutine_fn to bdrv_sum_allocated_file_size()

2023-03-08 Thread Philippe Mathieu-Daudé

On 8/3/23 22:14, Stefan Hajnoczi wrote:

Not a coroutine_fn, you say?

   static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
   {
   BdrvChild *child;
   int64_t child_size, sum = 0;

   QLIST_FOREACH(child, &bs->children, next) {
   if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
  BDRV_CHILD_FILTERED))
   {
   child_size = bdrv_co_get_allocated_file_size(child->bs);
^^^

Well what do we have here?!

I rest my case, your honor.

Signed-off-by: Stefan Hajnoczi 
---
  block.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 0dd604d0f6..a79297f99b 100644
--- a/block.c
+++ b/block.c
@@ -5749,7 +5749,7 @@ exit:
   * sums the size of all data-bearing children.  (This excludes backing
   * children.)
   */
-static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
+static int64_t coroutine_fn bdrv_sum_allocated_file_size(BlockDriverState *bs)
  {
  BdrvChild *child;
  int64_t child_size, sum = 0;


Since there is only 1 call site, maybe worth renaming as
bdrv_co_sum_allocated_file_size() in the same patch?



Re: [qemu-web PATCH] Add a blog post about the upcoming KVM Forum 2023

2023-03-08 Thread Cédric Le Goater

Hello Thomas,

one typo below,


On 3/8/23 15:12, Thomas Huth wrote:

Based on the announcement e-mail that Paolo sent to the qemu-devel
mailing list two days ago - let's spread the word via the blog, too!

Signed-off-by: Thomas Huth 
---
  _posts/2023-03-08-kvm-forum-cfp.md | 62 ++
  1 file changed, 62 insertions(+)
  create mode 100644 _posts/2023-03-08-kvm-forum-cfp.md

diff --git a/_posts/2023-03-08-kvm-forum-cfp.md 
b/_posts/2023-03-08-kvm-forum-cfp.md
new file mode 100644
index 000..8daf934
--- /dev/null
+++ b/_posts/2023-03-08-kvm-forum-cfp.md
@@ -0,0 +1,62 @@
+---
+layout: post
+title:  "KVM Forum 2023: Call for presentations"
+date:   2023-03-08 13:45:00 +0100
+categories: [presentations, conferences]
+---
+
+[KVM Forum](https://kvm-forum.qemu.org/2023/) is an annual event that presents
+a rare opportunity for KVM and QEMU developers and users to discuss the state
+of Linux irtualization technology and plan for the challenges ahead. Sessions


irtualization -> virtualization

Thanks,

C.


+include updates on the state of the KVM virtualization stack, planning for the
+future, and many opportunities for attendees to collaborate.
+
+This year's event will be held in Brno, Czech Republic on June 14-15, 2023.
+It will be in-person only and will be held right before the
+[DevConf.CZ](https://www.devconf.info/cz/) open source community conference.
+
+June 14 will be at least partly dedicated to a hackathon or "day of BoFs".
+This will provide time for people to get together and discuss strategic
+decisions, as well as other topics that are best solved within smaller groups.
+
+## Call for presentations
+
+We encourage you to submit presentations via the
+[KVM Forum CfP page](https://kvm-forum.qemu.org/2023/cfp).
+ Suggested topics include:
+
+* Scalability and Optimization
+* Hardening and security
+* Confidential computing
+* Testing
+* KVM and the Linux Kernel:
+  * New Features and Ports
+  * Device Passthrough: VFIO, mdev, vDPA
+  * Network Virtualization
+  * Virtio and vhost
+* Virtual Machine Monitors and Management:
+  * VMM Implementation: APIs, Live Migration, Performance Tuning, etc.
+  * Multi-process VMMs: vhost-user, vfio-user, QEMU Storage Daemon
+  * QEMU without KVM: Hypervisor.framework and other hypervisors
+  * Managing KVM: Libvirt, KubeVirt, Kata Containers
+* Emulation:
+  * New Devices, Boards and Architectures
+  * CPU Emulation and Binary Translation
+
+The deadline for submitting presentations is April 2, 2023 - 11:59 PM PDT.
+Accepted speakers will be notified on April 17, 2023.
+
+## Attending KVM Forum
+
+Admission to KVM Forum and DevConf.CZ is free. However,
+[registration](https://kvm-forum.qemu.org/2023/register/) is required and the
+number of attendees is limited by the space available at the venue.
+
+The DevConf.CZ program will feature technical talks on a variety of topics,
+including cloud and virtualization infrastructure—so make sure to register
+for DevConf.CZ as well if you would like to attend.
+
+Both conferences are committed to fostering an open and welcoming environment
+for everybody. Participants are expected to abide by the
+[Devconf.cz code of conduct](https://www.devconf.info/coc/)
+and [media policy](https://www.devconf.info/media-policy/).





Re: [qemu-web PATCH] Add a blog post about the upcoming KVM Forum 2023

2023-03-08 Thread Paolo Bonzini
Reviewed-by: Paolo Bonzini 

Il mer 8 mar 2023, 15:12 Thomas Huth  ha scritto:

> Based on the announcement e-mail that Paolo sent to the qemu-devel
> mailing list two days ago - let's spread the word via the blog, too!
>
> Signed-off-by: Thomas Huth 
> ---
>  _posts/2023-03-08-kvm-forum-cfp.md | 62 ++
>  1 file changed, 62 insertions(+)
>  create mode 100644 _posts/2023-03-08-kvm-forum-cfp.md
>
> diff --git a/_posts/2023-03-08-kvm-forum-cfp.md
> b/_posts/2023-03-08-kvm-forum-cfp.md
> new file mode 100644
> index 000..8daf934
> --- /dev/null
> +++ b/_posts/2023-03-08-kvm-forum-cfp.md
> @@ -0,0 +1,62 @@
> +---
> +layout: post
> +title:  "KVM Forum 2023: Call for presentations"
> +date:   2023-03-08 13:45:00 +0100
> +categories: [presentations, conferences]
> +---
> +
> +[KVM Forum](https://kvm-forum.qemu.org/2023/) is an annual event that
> presents
> +a rare opportunity for KVM and QEMU developers and users to discuss the
> state
> +of Linux irtualization technology and plan for the challenges ahead.
> Sessions
> +include updates on the state of the KVM virtualization stack, planning
> for the
> +future, and many opportunities for attendees to collaborate.
> +
> +This year's event will be held in Brno, Czech Republic on June 14-15,
> 2023.
> +It will be in-person only and will be held right before the
> +[DevConf.CZ](https://www.devconf.info/cz/) open source community
> conference.
> +
> +June 14 will be at least partly dedicated to a hackathon or "day of BoFs".
> +This will provide time for people to get together and discuss strategic
> +decisions, as well as other topics that are best solved within smaller
> groups.
> +
> +## Call for presentations
> +
> +We encourage you to submit presentations via the
> +[KVM Forum CfP page](https://kvm-forum.qemu.org/2023/cfp).
> + Suggested topics include:
> +
> +* Scalability and Optimization
> +* Hardening and security
> +* Confidential computing
> +* Testing
> +* KVM and the Linux Kernel:
> +  * New Features and Ports
> +  * Device Passthrough: VFIO, mdev, vDPA
> +  * Network Virtualization
> +  * Virtio and vhost
> +* Virtual Machine Monitors and Management:
> +  * VMM Implementation: APIs, Live Migration, Performance Tuning, etc.
> +  * Multi-process VMMs: vhost-user, vfio-user, QEMU Storage Daemon
> +  * QEMU without KVM: Hypervisor.framework and other hypervisors
> +  * Managing KVM: Libvirt, KubeVirt, Kata Containers
> +* Emulation:
> +  * New Devices, Boards and Architectures
> +  * CPU Emulation and Binary Translation
> +
> +The deadline for submitting presentations is April 2, 2023 - 11:59 PM PDT.
> +Accepted speakers will be notified on April 17, 2023.
> +
> +## Attending KVM Forum
> +
> +Admission to KVM Forum and DevConf.CZ is free. However,
> +[registration](https://kvm-forum.qemu.org/2023/register/) is required
> and the
> +number of attendees is limited by the space available at the venue.
> +
> +The DevConf.CZ program will feature technical talks on a variety of
> topics,
> +including cloud and virtualization infrastructure—so make sure to register
> +for DevConf.CZ as well if you would like to attend.
> +
> +Both conferences are committed to fostering an open and welcoming
> environment
> +for everybody. Participants are expected to abide by the
> +[Devconf.cz code of conduct](https://www.devconf.info/coc/)
> +and [media policy](https://www.devconf.info/media-policy/).
> --
> 2.31.1
>
>


Reply: [PATCH v2] virtio-balloon: optimize the virtio-balloon on the ARM platform

2023-03-08 Thread Yangming via
> On 08.03.23 01:42, Michael S. Tsirkin wrote:
> > On Wed, Mar 01, 2023 at 06:38:13AM +, Yangming wrote:
> >> Optimize the virtio-balloon feature on the ARM platform by adding a
> >> variable to keep track of the current hot-plugged pc-dimm size,
> >> instead of traversing the virtual machine's memory modules to count
> >> the current RAM size during the balloon inflation or deflation
> >> process. This variable can be updated only when plugging or
> >> unplugging the device, which will result in an increase of
> >> approximately 60% efficiency of balloon process on the ARM platform.
> >>
> >> We tested the total amount of time required for the balloon inflation
> process on ARM:
> >> inflate the balloon to 64GB of a 128GB guest under stress.
> >> Before: 102 seconds
> >> After: 42 seconds
> >>
> >> Signed-off-by: Qi Xi 
> >> Signed-off-by: Ming Yang yangmin...@huawei.com
> >> ---
> >> Refactor the code by adding comments and removing unnecessary code.
> >>
> >>   hw/mem/pc-dimm.c   |  7 +++
> >>   hw/virtio/virtio-balloon.c | 33 +
> >>   include/hw/boards.h|  2 ++
> >>   3 files changed, 14 insertions(+), 28 deletions(-)
> >>
> >> diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index
> >> 50ef83215c..3f2734a267 100644
> >> --- a/hw/mem/pc-dimm.c
> >> +++ b/hw/mem/pc-dimm.c
> >> @@ -81,6 +81,10 @@ void pc_dimm_plug(PCDIMMDevice *dimm,
> MachineState
> >> *machine)
> >>
> >>   memory_device_plug(MEMORY_DEVICE(dimm), machine);
> >>   vmstate_register_ram(vmstate_mr, DEVICE(dimm));
> >> +/* count only "real" DIMMs, not NVDIMMs */
> >> +if (!object_dynamic_cast(OBJECT(dimm), TYPE_NVDIMM)) {
> >> +machine->device_memory->dimm_size += vmstate_mr->size;
> >> +}
> >>   }
> >>
> >>   void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine)
> >
> > vmstate_mr->size is Int128 you are not supposed to do math on it.
> >
> > And generally poking at this struct is a bad idea.
> >
> > I think memory_region_size will do what you want but not 100% sure.
> > Maybe you need to look at the flatview ...
> 
> Good point, we should use memory_region_size().
> 
> --
> Thanks,
> 
> David / dhildenb

Thanks for the suggestion. The problem will be fixed in the upcoming third 
version by using 'memory_region_size()'.

By the way, we found that the size of the object is aligned with 
'qemu_host_page_size' before allocating the memory (see details in 
'qemu_ram_alloc_internal()' from softmmu/physmem.c). This means that the actual 
allocated memory may differ from the size defined in the Object. As a result, 
in 'get_current_ram_size()', the original method of counting hot-plugged memory 
from the Object may not be accurate. Now, we count the size from the memory 
region, which is a proper way to get the actual size of memory allocated.

Thanks,

XiQi


Re: [PATCH v7 03/10] target/riscv: allow MISA writes as experimental

2023-03-08 Thread LIU Zhiwei



On 2023/2/23 2:51, Daniel Henrique Barboza wrote:

At this moment, and apparently since ever, we have no way of enabling
RISCV_FEATURE_MISA. This means that all the code from write_misa(), all
the nuts and bolts that handles how to properly write this CSR, has
always been a no-op as well because write_misa() will always exit
earlier.

This seems to be benign in the majority of cases. Booting an Ubuntu
'virt' guest and logging all the calls to 'write_misa' shows that no
writes to MISA CSR was attempted. Writing MISA, i.e. enabling/disabling
RISC-V extensions after the machine is powered on, seems to be a niche
use.

After discussions in the mailing list, most notably in [1], we reached
the consensus that this code is not suited to be exposed to users
because it's not well tested, but at the same time removing it is a bit
extreme because we would like to fix it, and it's easier to do so with
the code available to use instead of fetching it from git log.

The approach taken here is to get rid of RISCV_FEATURE_MISA altogether
and use a new experimental flag called x-misa-w. The default value is
false, meaning that we're keeping the existing behavior of doing nothing
if a write_misa() is attempted. As with any existing experimental flag,
x-misa-w is also a temporary flag that we need to remove once we fix
write_misa().

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

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/cpu.c | 6 ++
  target/riscv/cpu.h | 2 +-
  target/riscv/csr.c | 2 +-
  3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 93b52b826c..1d637b1acd 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1210,6 +1210,12 @@ static Property riscv_cpu_properties[] = {
  
  DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),

  DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false),
+
+/*
+ * write_misa() is marked as experimental for now so mark
+ * it with -x and default to 'false'.
+ */
+DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false),


Just a question  I got when I reviewed another patch set:

Why put x-misa-w to riscv_cpu_properties instead of riscv_cpu_extensions?

I think this property should have a fixed value for a named cpu(such as 
sifive_e). Therefore IMHO, putting x-misa-w into riscv_cpu_extensions is 
more proper. At the same time,  the debug, rvv_ta_all_1s,  
rvv_ma_all_1s, resetvec properties should be moved to 
riscv_cpu_extentions. I am not sure why we should give the 
marchid/mipid/mvendorid option for named cpus. Maybe @Frank knows.


Have I missed something?

Zhiwei


  DEFINE_PROP_END_OF_LIST(),
  };
  
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h

index 215423499e..9d3304bcda 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -89,7 +89,6 @@ enum {
  RISCV_FEATURE_MMU,
  RISCV_FEATURE_PMP,
  RISCV_FEATURE_EPMP,
-RISCV_FEATURE_MISA,
  RISCV_FEATURE_DEBUG
  };
  
@@ -498,6 +497,7 @@ struct RISCVCPUConfig {

  bool pmp;
  bool epmp;
  bool debug;
+bool misa_w;
  
  bool short_isa_string;

  };
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e149b453da..3cb8d2ffad 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1329,7 +1329,7 @@ static RISCVException read_misa(CPURISCVState *env, int 
csrno,
  static RISCVException write_misa(CPURISCVState *env, int csrno,
   target_ulong val)
  {
-if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
+if (!riscv_cpu_cfg(env)->misa_w) {
  /* drop write to misa */
  return RISCV_EXCP_NONE;
  }




Re: [PATCH 2/2] target/riscv: Make the "virt" register writable by GDB

2023-03-08 Thread LIU Zhiwei



On 2023/3/9 11:05, Jim Shu wrote:

On Mon, Mar 6, 2023 at 7:26 PM LIU Zhiwei  wrote:


On 2023/3/5 17:42, Jim Shu wrote:

This patch also enables debugger to set current privilege mode to
VU/VS-mode.

Extend previous commit 81d2929c41d32af138f3562f5a7b309f6eac7ca7 to
support H-extension.

Signed-off-by: Jim Shu 
Reviewed-by: Frank Chang 
---
   target/riscv/gdbstub.c | 18 --
   1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 1755fd9d51..a7f234beaf 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -203,15 +203,29 @@ static int riscv_gdb_get_virtual(CPURISCVState *cs, 
GByteArray *buf, int n)

   static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
   {
+#ifdef CONFIG_USER_ONLY
+if (n >= 0 && n <= 1) {
+return sizeof(target_ulong);
+}
+#else
+bool virt;
+
   if (n == 0) {
-#ifndef CONFIG_USER_ONLY
   cs->priv = ldtul_p(mem_buf) & 0x3;
   if (cs->priv == PRV_H) {
   cs->priv = PRV_S;
   }
-#endif
+return sizeof(target_ulong);

We should return according to the misa_mxl_max. And this is a bug before
your commit.

Hi Zhiwei,

After reading other gdbstub.c code, I think it is OK to use
'sizeof(target_ulong)' as virtual register length.


No, you should refer to the riscv_cpu_gdb_read(write)_register.


Its length is 32-bit in RV32 and is 64-bit in RV64/RV128.
Although we don't support MXLEN 32bit  currently on qemu-system-riscv64, 
we should not introduce more code

to make dynamic xlen support complex.

Zhiwei


We don't
need to handle RV128 specially.
Virtual register length is same as CSR length and
'riscv_gdb_set_csr()' also use 'sizeof(target_ulong)'.

Jim Shu


+} else if (n == 1) {
+virt = ldtul_p(mem_buf) & 0x1;
+if ((cs->priv == PRV_M) && (virt == true)) {
+/* M-mode only supports V=0. */
+virt = false;
+}
+riscv_cpu_set_virt_enabled(cs, virt);
   return sizeof(target_ulong);

Same error here. Otherwise,

Reviewed-by: LIU Zhiwei 

Zhiwei


   }
+#endif
   return 0;
   }





Re: [PATCH 2/2] target/riscv: Make the "virt" register writable by GDB

2023-03-08 Thread Jim Shu
On Mon, Mar 6, 2023 at 7:26 PM LIU Zhiwei  wrote:
>
>
> On 2023/3/5 17:42, Jim Shu wrote:
> > This patch also enables debugger to set current privilege mode to
> > VU/VS-mode.
> >
> > Extend previous commit 81d2929c41d32af138f3562f5a7b309f6eac7ca7 to
> > support H-extension.
> >
> > Signed-off-by: Jim Shu 
> > Reviewed-by: Frank Chang 
> > ---
> >   target/riscv/gdbstub.c | 18 --
> >   1 file changed, 16 insertions(+), 2 deletions(-)
> >
> > diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> > index 1755fd9d51..a7f234beaf 100644
> > --- a/target/riscv/gdbstub.c
> > +++ b/target/riscv/gdbstub.c
> > @@ -203,15 +203,29 @@ static int riscv_gdb_get_virtual(CPURISCVState *cs, 
> > GByteArray *buf, int n)
> >
> >   static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int 
> > n)
> >   {
> > +#ifdef CONFIG_USER_ONLY
> > +if (n >= 0 && n <= 1) {
> > +return sizeof(target_ulong);
> > +}
> > +#else
> > +bool virt;
> > +
> >   if (n == 0) {
> > -#ifndef CONFIG_USER_ONLY
> >   cs->priv = ldtul_p(mem_buf) & 0x3;
> >   if (cs->priv == PRV_H) {
> >   cs->priv = PRV_S;
> >   }
> > -#endif
> > +return sizeof(target_ulong);
> We should return according to the misa_mxl_max. And this is a bug before
> your commit.

Hi Zhiwei,

After reading other gdbstub.c code, I think it is OK to use
'sizeof(target_ulong)' as virtual register length.
Its length is 32-bit in RV32 and is 64-bit in RV64/RV128. We don't
need to handle RV128 specially.
Virtual register length is same as CSR length and
'riscv_gdb_set_csr()' also use 'sizeof(target_ulong)'.

Jim Shu

> > +} else if (n == 1) {
> > +virt = ldtul_p(mem_buf) & 0x1;
> > +if ((cs->priv == PRV_M) && (virt == true)) {
> > +/* M-mode only supports V=0. */
> > +virt = false;
> > +}
> > +riscv_cpu_set_virt_enabled(cs, virt);
> >   return sizeof(target_ulong);
> Same error here. Otherwise,
>
> Reviewed-by: LIU Zhiwei 
>
> Zhiwei
>
> >   }
> > +#endif
> >   return 0;
> >   }
> >



Re: [PULL 00/51] Net patches

2023-03-08 Thread Jason Wang
On Wed, Mar 8, 2023 at 8:25 PM Michael S. Tsirkin  wrote:
>
> On Wed, Mar 08, 2023 at 01:21:52PM +0100, Philippe Mathieu-Daudé wrote:
> > On 8/3/23 13:17, Michael S. Tsirkin wrote:
> > > On Wed, Mar 08, 2023 at 08:40:42AM +0100, Philippe Mathieu-Daudé wrote:
> > > > On 8/3/23 07:56, Jason Wang wrote:
> > > > > On Wed, Mar 8, 2023 at 4:43 AM Philippe Mathieu-Daudé 
> > > > >  wrote:
> > > > > >
> > > > > > On 7/3/23 18:01, Peter Maydell wrote:
> > > > > > > On Tue, 7 Mar 2023 at 07:08, Jason Wang  
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > The following changes since commit 
> > > > > > > > 817fd33836e73812df2f1907612b57750fcb9491:
> > > > > > > >
> > > > > > > >  Merge tag 'audio-pull-request' of 
> > > > > > > > https://gitlab.com/marcandre.lureau/qemu into staging 
> > > > > > > > (2023-03-06 14:06:06 +)
> > > > > > > >
> > > > > > > > are available in the git repository at:
> > > > > > > >
> > > > > > > >  https://github.com/jasowang/qemu.git tags/net-pull-request
> > > > > > > >
> > > > > > > > for you to fetch changes up to 
> > > > > > > > c19b566a3898510ec2b3e881b3fb78614b240414:
> > > > > > > >
> > > > > > > >  hw/net/eepro100: Replace DO_UPCAST(EEPRO100State) by 
> > > > > > > > EEPRO100() (2023-03-07 14:55:39 +0800)
> > > > > > > >
> > > > > > > > 
> > > > > >
> > > > > > > build-oss-fuzz failed on something involving fuzzing eepro100:
> > > > > > > https://gitlab.com/qemu-project/qemu/-/jobs/3889073821
> > > > > > Jason, please drop my patches. I'll look at that failure.
> > > >
> > > > Before "hw/net/eepro100: Convert reset handler to DeviceReset",
> > > > e100_pci_reset() is only called once from DeviceRealize _before_
> > > > the device is realized.
> > > >
> > > > After, 1/ it can be called multiple times and 2/ it seems to do
> > > > stuffs that really belong to DeviceRealize (should be called once),
> > > > in particular pci_add_capability().
> > > >
> > > > I *think* it should be illegal to call pci_add_capability() _after_
> > > > a device is realized. Auditing pci_add_capability(), there is only
> > > > one other use before realize: amdvi_sysbus_realize() in
> > > > hw/i386/amd_iommu.c.
> > >
> > > Calling pci_add_capability when VM is running is likely to confuse
> > > guests, yes.
> >
> > Thanks for confirming. Similar pattern: msi_init().
> >
> > While trying to fix that in hw/i386/amd_iommu.c I realized this device
> > isn't in a good shape, almost unmaintained: 2 bugfixes in since 7 years,
> > the other commits are generic API cleanups.

Last time I tried AMD vIOMMU it didn't even boot. We need to check if
anyone can maintain that driver (adding Wei and Peter).

> I'll post the series and
> > we can discuss that there.
>
> Absolutely. A mix of VTD or for that matter virtio iommu and AMD CPUs
> seems to work well enough that most people don't bother.
> I vaguely remember spec review showed some things were hard
> to support correctly with shadowing, but I don't remember
> the detail

Something like caching mode otherwise we need to trap the page table
modification via userfaultfd?

> (and our shadowing with VTD only works because
> it matches what drivers are doing).

I think not, VTD has a caching mode that is designed to be friendly
for virtualization/emulation (mentioned in the spec). But it would be
replaced by hardware accelerated one soon.

Thanks

>
> --
> MST
>




Re: [PATCH] hw/intc/ioapic: Update KVM routes before redelivering IRQ, on RTE update

2023-03-08 Thread Peter Xu
On Mon, Mar 06, 2023 at 05:28:24PM +, David Woodhouse wrote:
> Indeed, I don't think we care about the in-kernel I/OAPIC. I don't
> think we care about the kernel knowing about e.g. "GSI #11" at all. We
> can just deliver it as MSI (for the I/OAPIC) or using KVM_INTERRUPT and
> the interrupt window as we do for the PIC. Which is why I'd happily rip
> that out and let it be delivered via the APIC intercept at 0xfeex.
> 
> The existing code which just keeps IRQ routes updated when they're
> valid is kind of OK, and well-behaved guests can function. But it isn't
> *right* in the case where they aren't valid.
> 
> What *ought* to happen is that the IOMMU should raise a fault at the
> moment the interrupt occurs, if the translation isn't valid. And we
> don't have that at all.

Right, that's definitely not ideal as an emulator.

> 
> As for why I care? I don't really *need* it, as I have everything I
> need for Xen PIRQ support already merged in 
> https://gitlab.com/qemu-project/qemu/-/commit/6096cf7877
> 
> So while the thread at
> https://lore.kernel.org/qemu-devel/aaef9961d210ac1873153bf3cf01d984708744fc.ca...@infradead.org/
> was partly driven by expecting to need this for Xen PIRQ support
> (because in $DAYJOB I did those things in the other order and the PIRQ
> support ended up just being a trivial different translator like the
> IOMMU's IR)... I'd still quite like to fix it up in QEMU anyway, just
> for correctness and fidelity in the faulting cases.
> 
> We can do more efficient invalidation too, rather than blowing away the
> entire routing table every time. Just disconnect the IRQFD for the
> specific interrupts that get invalidated, and let them get fixed up
> again next time they occur.

I'm curious whether there's anything else beside the "correctness of
emulation" reason.

I would think it nice if it existed or trivial to have as what you said.  I
just don't know whether it's as easy, at least so far a new kernel
interface seems still needed, allowing a kernel irq to be paused until
being translated by QEMU from some channel we provide.

So, IMHO it's about whether the reason that "we want to have a complete
emulation of IR" can properly justify the complexity of at least the kernel
interface (I don't worry on the qemu side a lot).  After all, even if it
can completes the emulation, 99.99% of people will not use it. :(

-- 
Peter Xu




Re: [PATCH for-8.1 05/17] target/riscv/cpu.c: add riscv_cpu_validate_priv_spec()

2023-03-08 Thread Richard Henderson

On 3/8/23 12:19, Daniel Henrique Barboza wrote:

+static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)
+{
+CPURISCVState *env = &cpu->env;
+int i, priv_version = -1;
+
+if (cpu->cfg.priv_spec) {
+if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
+priv_version = PRIV_VERSION_1_12_0;
+} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
+priv_version = PRIV_VERSION_1_11_0;
+} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
+priv_version = PRIV_VERSION_1_10_0;
+} else {
+error_setg(errp,
+   "Unsupported privilege spec version '%s'",
+   cpu->cfg.priv_spec);
+return;
+}
+}
+
+if (priv_version >= PRIV_VERSION_1_10_0) {
+env->priv_ver = priv_version;
+}


Merge these two if bodies, as the second condition is completely dependent on 
the first.


r~



Re: [PATCH for-8.1 04/17] target/riscv: add PRIV_VERSION_LATEST macro

2023-03-08 Thread Richard Henderson

On 3/8/23 12:19, Daniel Henrique Barboza wrote:

  PRIV_VERSION_1_11_0,
  PRIV_VERSION_1_12_0,
  };
+#define PRIV_VERSION_LATEST PRIV_VERSION_1_12_0


Any reason not to make this a enumeration value:

  PRIV_VERSION_LATEST = PRIV_VERSION_1_12_0

?

r~



[PATCH v4 3/3] qga: test: Add tests for `all-merge` flag

2023-03-08 Thread Daniel Xu
This commit adds a test to ensure `all-merge` functions as expected.
We also add a negative test to ensure we haven't regressed previous
functionality.

Signed-off-by: Daniel Xu 
---
 tests/unit/test-qga.c | 158 +-
 1 file changed, 141 insertions(+), 17 deletions(-)

diff --git a/tests/unit/test-qga.c b/tests/unit/test-qga.c
index b4e0a14573..fcb84ab81f 100644
--- a/tests/unit/test-qga.c
+++ b/tests/unit/test-qga.c
@@ -755,6 +755,31 @@ static void test_qga_fsfreeze_status(gconstpointer fix)
 g_assert_cmpstr(status, ==, "thawed");
 }
 
+static QDict *wait_for_guest_exec_completion(int fd, int64_t pid)
+{
+QDict *ret = NULL;
+int64_t now;
+bool exited;
+QDict *val;
+
+now = g_get_monotonic_time();
+do {
+ret = qmp_fd(fd,
+ "{'execute': 'guest-exec-status',"
+ " 'arguments': { 'pid': %" PRId64 " } }", pid);
+g_assert_nonnull(ret);
+val = qdict_get_qdict(ret, "return");
+exited = qdict_get_bool(val, "exited");
+if (!exited) {
+qobject_unref(ret);
+}
+} while (!exited &&
+ g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);
+g_assert(exited);
+
+return ret;
+}
+
 static void test_qga_guest_exec(gconstpointer fix)
 {
 const TestFixture *fixture = fix;
@@ -762,9 +787,8 @@ static void test_qga_guest_exec(gconstpointer fix)
 QDict *val;
 const gchar *out;
 g_autofree guchar *decoded = NULL;
-int64_t pid, now, exitcode;
+int64_t pid, exitcode;
 gsize len;
-bool exited;
 
 /* exec 'echo foo bar' */
 ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
@@ -777,23 +801,10 @@ static void test_qga_guest_exec(gconstpointer fix)
 g_assert_cmpint(pid, >, 0);
 qobject_unref(ret);
 
-/* wait for completion */
-now = g_get_monotonic_time();
-do {
-ret = qmp_fd(fixture->fd,
- "{'execute': 'guest-exec-status',"
- " 'arguments': { 'pid': %" PRId64 " } }", pid);
-g_assert_nonnull(ret);
-val = qdict_get_qdict(ret, "return");
-exited = qdict_get_bool(val, "exited");
-if (!exited) {
-qobject_unref(ret);
-}
-} while (!exited &&
- g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);
-g_assert(exited);
+ret = wait_for_guest_exec_completion(fixture->fd, pid);
 
 /* check stdout */
+val = qdict_get_qdict(ret, "return");
 exitcode = qdict_get_int(val, "exitcode");
 g_assert_cmpint(exitcode, ==, 0);
 out = qdict_get_str(val, "out-data");
@@ -802,6 +813,115 @@ static void test_qga_guest_exec(gconstpointer fix)
 g_assert_cmpstr((char *)decoded, ==, "\" test_str \"");
 }
 
+#if defined(G_OS_WIN32)
+static void test_qga_guest_exec_all_no_merge(gconstpointer fix)
+{
+}
+static void test_qga_guest_exec_all_merge(gconstpointer fix)
+{
+const TestFixture *fixture = fix;
+g_autoptr(QDict) ret = NULL;
+QDict *val;
+const gchar *class, *desc;
+g_autofree guchar *decoded = NULL;
+
+/* exec 'echo foo bar' */
+ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
+ " 'path': 'echo',"
+ " 'arg': [ 'execution never reaches here' ],"
+ " 'capture-output': 'all-merge' } }");
+
+g_assert_nonnull(ret);
+val = qdict_get_qdict(ret, "error");
+g_assert_nonnull(val);
+class = qdict_get_str(val, "class");
+desc = qdict_get_str(val, "desc");
+g_assert_cmpstr(class, ==, "GenericError");
+g_assert_cmpint(strlen(desc), >, 0);
+}
+#else
+static void test_qga_guest_exec_all_no_merge(gconstpointer fix)
+{
+const TestFixture *fixture = fix;
+g_autoptr(QDict) ret = NULL;
+QDict *val;
+const gchar *out, *err;
+g_autofree guchar *out_decoded = NULL;
+g_autofree guchar *err_decoded = NULL;
+int64_t pid, exitcode;
+gsize len;
+
+/* exec 'echo foo bar' */
+ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
+ " 'path': '/bin/bash',"
+ " 'arg': [ '-c', 'for i in $(seq 4); do if (( $i %% 2 )); 
then echo stdout; else echo stderr 1>&2; fi; done;' ],"
+ " 'capture-output': 'all' } }");
+g_assert_nonnull(ret);
+qmp_assert_no_error(ret);
+val = qdict_get_qdict(ret, "return");
+pid = qdict_get_int(val, "pid");
+g_assert_cmpint(pid, >, 0);
+qobject_unref(ret);
+
+ret = wait_for_guest_exec_completion(fixture->fd, pid);
+
+val = qdict_get_qdict(ret, "return");
+exitcode = qdict_get_int(val, "exitcode");
+g_assert_cmpint(exitcode, ==, 0);
+
+/* check stdout */
+out = qdict_get_str(val, "out-data");
+out_decoded = g_base64_decode(out, &len);
+g_assert_cmpint(len, ==, 14);
+g_assert_cmpstr((char *)out_decoded, ==, "stdout\nstdout\n");
+
+/* check stderr */
+err = qdict_get_try_str(val, "err

[PATCH v4 1/3] qga: Refactor guest-exec capture-output to take enum

2023-03-08 Thread Daniel Xu
Previously capture-output was an optional boolean flag that either
captured all output or captured none. While this is OK in most cases, it
lacks flexibility for more advanced capture cases, such as wanting to
only capture stdout.

This commits refactors guest-exec qapi to take an enum for capture mode
instead while preserving backwards compatibility.

Suggested-by: Daniel P. Berrangé 
Signed-off-by: Daniel Xu 
---
 qga/commands.c   | 37 ++---
 qga/qapi-schema.json | 32 +++-
 2 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/qga/commands.c b/qga/commands.c
index 172826f8f8..5504fc5b8c 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -379,11 +379,23 @@ close:
 return false;
 }
 
+static GuestExecCaptureOutputMode ga_parse_capture_output(
+GuestExecCaptureOutput *capture_output)
+{
+if (!capture_output)
+return GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE;
+else if (capture_output->type == QTYPE_QBOOL)
+return capture_output->u.flag ? GUEST_EXEC_CAPTURE_OUTPUT_MODE_ALL
+  : GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE;
+else
+return capture_output->u.mode;
+}
+
 GuestExec *qmp_guest_exec(const char *path,
bool has_arg, strList *arg,
bool has_env, strList *env,
const char *input_data,
-   bool has_capture_output, bool capture_output,
+   GuestExecCaptureOutput *capture_output,
Error **errp)
 {
 GPid pid;
@@ -396,7 +408,8 @@ GuestExec *qmp_guest_exec(const char *path,
 gint in_fd, out_fd, err_fd;
 GIOChannel *in_ch, *out_ch, *err_ch;
 GSpawnFlags flags;
-bool has_output = (has_capture_output && capture_output);
+bool has_output = false;
+GuestExecCaptureOutputMode output_mode;
 g_autofree uint8_t *input = NULL;
 size_t ninput = 0;
 
@@ -415,8 +428,26 @@ GuestExec *qmp_guest_exec(const char *path,
 
 flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD |
 G_SPAWN_SEARCH_PATH_FROM_ENVP;
-if (!has_output) {
+
+output_mode = ga_parse_capture_output(capture_output);
+switch (output_mode) {
+case GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE:
 flags |= G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL;
+break;
+case GUEST_EXEC_CAPTURE_OUTPUT_MODE_STDOUT:
+has_output = true;
+flags |= G_SPAWN_STDERR_TO_DEV_NULL;
+break;
+case GUEST_EXEC_CAPTURE_OUTPUT_MODE_STDERR:
+has_output = true;
+flags |= G_SPAWN_STDOUT_TO_DEV_NULL;
+break;
+case GUEST_EXEC_CAPTURE_OUTPUT_MODE_ALL:
+has_output = true;
+break;
+case GUEST_EXEC_CAPTURE_OUTPUT_MODE__MAX:
+/* Silence warning; impossible branch */
+break;
 }
 
 ret = g_spawn_async_with_pipes(NULL, argv, envp, flags,
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 796434ed34..4ef585da5d 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -1200,6 +1200,36 @@
 { 'struct': 'GuestExec',
   'data': { 'pid': 'int'} }
 
+##
+# @GuestExecCaptureOutputMode:
+#
+# An enumeration of guest-exec capture modes.
+#
+# @none: do not capture any output
+# @stdout: only capture stdout
+# @stderr: only capture stderr
+# @all: capture both stdout and stderr
+#
+# Since: 8.0
+##
+ { 'enum': 'GuestExecCaptureOutputMode',
+   'data': [ 'none', 'stdout', 'stderr', 'all' ] }
+
+##
+# @GuestExecCaptureOutput:
+#
+# Controls what guest-exec output gets captures.
+#
+# @flag: captures both stdout and stderr if true. Equivalent
+#to GuestExecCaptureOutputMode::all. (since 2.5)
+# @mode: capture mode; preferred interface
+#
+# Since: 8.0
+##
+ { 'alternate': 'GuestExecCaptureOutput',
+   'data': { 'flag': 'bool',
+ 'mode': 'GuestExecCaptureOutputMode'} }
+
 ##
 # @guest-exec:
 #
@@ -1218,7 +1248,7 @@
 ##
 { 'command': 'guest-exec',
   'data':{ 'path': 'str', '*arg': ['str'], '*env': ['str'],
-   '*input-data': 'str', '*capture-output': 'bool' },
+   '*input-data': 'str', '*capture-output': 
'GuestExecCaptureOutput' },
   'returns': 'GuestExec' }
 
 
-- 
2.39.1




[PATCH v4 2/3] qga: Add `all-merge` variant to GuestExecCaptureOutputMode

2023-03-08 Thread Daniel Xu
Currently, any captured output (via `capture-output`) is segregated into
separate GuestExecStatus fields (`out-data` and `err-data`). This means
that downstream consumers have no way to reassemble the captured data
back into the original stream.

This is relevant for chatty and semi-interactive (ie. read only) CLI
tools.  Such tools may deliberately interleave stdout and stderr for
visual effect. If segregated, the output becomes harder to visually
understand.

This commit adds a new enum variant to the GuestExecCaptureOutputMode
qapi to merge the output streams such that consumers can have a pristine
view of the original command output.

Signed-off-by: Daniel Xu 
---
 qga/commands.c   | 31 +--
 qga/qapi-schema.json |  4 +++-
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/qga/commands.c b/qga/commands.c
index 5504fc5b8c..7d458d0aca 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -270,12 +270,26 @@ static void guest_exec_child_watch(GPid pid, gint status, 
gpointer data)
 g_spawn_close_pid(pid);
 }
 
-/** Reset ignored signals back to default. */
 static void guest_exec_task_setup(gpointer data)
 {
 #if !defined(G_OS_WIN32)
+bool has_merge = *(bool *)data;
 struct sigaction sigact;
 
+if (has_merge) {
+/*
+ * FIXME: When `GLIB_VERSION_MIN_REQUIRED` is bumped to 2.58+, use
+ * g_spawn_async_with_fds() to be portable on windows. The current
+ * logic does not work on windows b/c `GSpawnChildSetupFunc` is run
+ * inside the parent, not the child.
+ */
+if (dup2(STDOUT_FILENO, STDERR_FILENO) != 0) {
+slog("dup2() failed to merge stderr into stdout: %s",
+ strerror(errno));
+}
+}
+
+/* Reset ignored signals back to default. */
 memset(&sigact, 0, sizeof(struct sigaction));
 sigact.sa_handler = SIG_DFL;
 
@@ -409,6 +423,7 @@ GuestExec *qmp_guest_exec(const char *path,
 GIOChannel *in_ch, *out_ch, *err_ch;
 GSpawnFlags flags;
 bool has_output = false;
+bool has_merge = false;
 GuestExecCaptureOutputMode output_mode;
 g_autofree uint8_t *input = NULL;
 size_t ninput = 0;
@@ -445,13 +460,25 @@ GuestExec *qmp_guest_exec(const char *path,
 case GUEST_EXEC_CAPTURE_OUTPUT_MODE_ALL:
 has_output = true;
 break;
+case GUEST_EXEC_CAPTURE_OUTPUT_MODE_ALL_MERGE:
+has_output = true;
+has_merge = true;
+break;
 case GUEST_EXEC_CAPTURE_OUTPUT_MODE__MAX:
 /* Silence warning; impossible branch */
 break;
 }
 
+#if defined(G_OS_WIN32)
+/* FIXME: see comment in guest_exec_task_setup() */
+if (has_merge) {
+error_setg(errp, "all-merge unsupported on windows");
+return NULL;
+}
+#endif
+
 ret = g_spawn_async_with_pipes(NULL, argv, envp, flags,
-guest_exec_task_setup, NULL, &pid, input_data ? &in_fd : NULL,
+guest_exec_task_setup, &has_merge, &pid, input_data ? &in_fd : 
NULL,
 has_output ? &out_fd : NULL, has_output ? &err_fd : NULL, &gerr);
 if (!ret) {
 error_setg(errp, QERR_QGA_COMMAND_FAILED, gerr->message);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 4ef585da5d..d364ab78de 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -1209,11 +1209,13 @@
 # @stdout: only capture stdout
 # @stderr: only capture stderr
 # @all: capture both stdout and stderr
+# @all-merge: capture both stdout and stderr and merge together
+# into stdout. not effective on windows guests.
 #
 # Since: 8.0
 ##
  { 'enum': 'GuestExecCaptureOutputMode',
-   'data': [ 'none', 'stdout', 'stderr', 'all' ] }
+   'data': [ 'none', 'stdout', 'stderr', 'all', 'all-merge' ] }
 
 ##
 # @GuestExecCaptureOutput:
-- 
2.39.1




[PATCH v4 0/3] qga: Support merging output streams in guest-exec

2023-03-08 Thread Daniel Xu
Currently, the captured output (via `capture-output`) is segregated into
separate GuestExecStatus fields (`out-data` and `err-data`). This means
that downstream consumers have no way to reassemble the captured data
back into the original stream.

This is relevant for chatty and semi-interactive (ie. read only) CLI
tools.  Such tools may deliberately interleave stdout and stderr for
visual effect. If segregated, the output becomes harder to visually
understand.

This patchset adds support for merging stderr and stdout output streams
via a backwards compatibile refactor and a new enum variant,
`all-merge`.

---

Changes from v3:
* Split out ASAN fixes into separate patch series
* Refactor `capture-output` flag into an enum
* Avoid using /bin/bash on windows

Changes from v2:
* Error out if `merge-output` on windows guests
* Add FIXMEs for when glib is updated
* Fix memory leaks in qemu-keymap

Changes from v1:
* Drop invalid test fix
* Do not support `merge-output` on windows guests
* Fix a UAF in tests


Daniel Xu (3):
  qga: Refactor guest-exec capture-output to take enum
  qga: Add `all-merge` variant to GuestExecCaptureOutputMode
  qga: test: Add tests for `all-merge` flag

 qga/commands.c|  68 --
 qga/qapi-schema.json  |  34 -
 tests/unit/test-qga.c | 158 +-
 3 files changed, 237 insertions(+), 23 deletions(-)

-- 
2.39.1




Re: [PATCH v2 2/2] tests/tcg/s390x: Add C(G)HRL test

2023-03-08 Thread Richard Henderson

On 3/8/23 13:02, Nina Schoetterl-Glausch wrote:

Test COMPARE HALFWORD RELATIVE LONG instructions.
Test that the bytes following the second operand do not affect the
instruction.
Test the sign extension performed on the second operand.

Signed-off-by: Nina Schoetterl-Glausch
---


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 1/2] target/s390x: Fix emulation of C(G)HRL

2023-03-08 Thread Richard Henderson

On 3/8/23 13:02, Nina Schoetterl-Glausch wrote:

The second operand of COMPARE HALFWORD RELATIVE LONG is a signed
halfword, it does not have the same size as the first operand.

Fixes: a7e836d5eb ("target-s390: Convert COMPARE, COMPARE LOGICAL")
Signed-off-by: Nina Schoetterl-Glausch
---
  target/s390x/tcg/insn-data.h.inc | 4 ++--
  target/s390x/tcg/translate.c | 7 +++
  2 files changed, 9 insertions(+), 2 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2] block: add missing coroutine_fn to bdrv_sum_allocated_file_size()

2023-03-08 Thread Stefan Hajnoczi
v2 is the same as v1. I sent it by accident, sorry :).

Stefan

On Wed, 8 Mar 2023 at 17:18, Stefan Hajnoczi  wrote:
>
> Not a coroutine_fn, you say?
>
>   static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
>   {
>   BdrvChild *child;
>   int64_t child_size, sum = 0;
>
>   QLIST_FOREACH(child, &bs->children, next) {
>   if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
>  BDRV_CHILD_FILTERED))
>   {
>   child_size = bdrv_co_get_allocated_file_size(child->bs);
>^^^
>
> Well what do we have here?!
>
> I rest my case, your honor.
>
> Signed-off-by: Stefan Hajnoczi 
> ---
>  block.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/block.c b/block.c
> index 0dd604d0f6..a79297f99b 100644
> --- a/block.c
> +++ b/block.c
> @@ -5749,7 +5749,7 @@ exit:
>   * sums the size of all data-bearing children.  (This excludes backing
>   * children.)
>   */
> -static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
> +static int64_t coroutine_fn bdrv_sum_allocated_file_size(BlockDriverState 
> *bs)
>  {
>  BdrvChild *child;
>  int64_t child_size, sum = 0;
> --
> 2.39.2
>
>



[PATCH v2] block: add missing coroutine_fn to bdrv_sum_allocated_file_size()

2023-03-08 Thread Stefan Hajnoczi
Not a coroutine_fn, you say?

  static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
  {
  BdrvChild *child;
  int64_t child_size, sum = 0;

  QLIST_FOREACH(child, &bs->children, next) {
  if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
 BDRV_CHILD_FILTERED))
  {
  child_size = bdrv_co_get_allocated_file_size(child->bs);
   ^^^

Well what do we have here?!

I rest my case, your honor.

Signed-off-by: Stefan Hajnoczi 
---
 block.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 0dd604d0f6..a79297f99b 100644
--- a/block.c
+++ b/block.c
@@ -5749,7 +5749,7 @@ exit:
  * sums the size of all data-bearing children.  (This excludes backing
  * children.)
  */
-static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
+static int64_t coroutine_fn bdrv_sum_allocated_file_size(BlockDriverState *bs)
 {
 BdrvChild *child;
 int64_t child_size, sum = 0;
-- 
2.39.2




Emulating a SH2 board?

2023-03-08 Thread Diki Dera
I am looking to emulate a SH2 board, specifically SH7055. I see that there
is already an implementation for SH4, although in places, incomplete from
the comment I saw. Especially interrupts.

Compared to SH4, SH2 is simpler in that it has no MMU, so address 0x1000 is
exactly that. And since SH4 is backwards compatible with SH2, I already
have the necessary translation layer.
My question is probably too broad for which I apologize, but what would it
take to patch out the software MMU and focus more on emulating my board's
devices such as SRAM and CMOS Flash chips as well the functionality
specific to SH7055?


Re: [PATCH v7] audio/pwaudio.c: Add Pipewire audio backend for QEMU

2023-03-08 Thread Volker Rümelin

Am 08.03.23 um 11:39 schrieb Marc-André Lureau:


Volker, Wim, it would be nice if you could review/comment too!

thanks


Hi,

last weekend I replaced pulseaudio with pipewire on my host computer and 
tested the QEMU pipewire backend. It doesn't work well on my computer, 
but with a few changes it becomes usable. I hope to have some time 
tomorrow evening to write down my suggestions and comments.


With best regards,
Volker


--
Marc-André Lureau





[PATCH] block: add missing coroutine_fn to bdrv_sum_allocated_file_size()

2023-03-08 Thread Stefan Hajnoczi
Not a coroutine_fn, you say?

  static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
  {
  BdrvChild *child;
  int64_t child_size, sum = 0;

  QLIST_FOREACH(child, &bs->children, next) {
  if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
 BDRV_CHILD_FILTERED))
  {
  child_size = bdrv_co_get_allocated_file_size(child->bs);
   ^^^

Well what do we have here?!

I rest my case, your honor.

Signed-off-by: Stefan Hajnoczi 
---
 block.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 0dd604d0f6..a79297f99b 100644
--- a/block.c
+++ b/block.c
@@ -5749,7 +5749,7 @@ exit:
  * sums the size of all data-bearing children.  (This excludes backing
  * children.)
  */
-static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
+static int64_t coroutine_fn bdrv_sum_allocated_file_size(BlockDriverState *bs)
 {
 BdrvChild *child;
 int64_t child_size, sum = 0;
-- 
2.39.2




[PATCH v2 1/2] target/s390x: Fix emulation of C(G)HRL

2023-03-08 Thread Nina Schoetterl-Glausch
The second operand of COMPARE HALFWORD RELATIVE LONG is a signed
halfword, it does not have the same size as the first operand.

Fixes: a7e836d5eb ("target-s390: Convert COMPARE, COMPARE LOGICAL")
Signed-off-by: Nina Schoetterl-Glausch 
---
 target/s390x/tcg/insn-data.h.inc | 4 ++--
 target/s390x/tcg/translate.c | 7 +++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/target/s390x/tcg/insn-data.h.inc b/target/s390x/tcg/insn-data.h.inc
index 9d2d35f084..6fe8ca5143 100644
--- a/target/s390x/tcg/insn-data.h.inc
+++ b/target/s390x/tcg/insn-data.h.inc
@@ -199,8 +199,8 @@
 C(0xe55c, CHSI,SIL,   GIE, m1_32s, i2, 0, 0, 0, cmps64)
 C(0xe558, CGHSI,   SIL,   GIE, m1_64, i2, 0, 0, 0, cmps64)
 /* COMPARE HALFWORD RELATIVE LONG */
-C(0xc605, CHRL,RIL_b, GIE, r1_o, mri2_32s, 0, 0, 0, cmps32)
-C(0xc604, CGHRL,   RIL_b, GIE, r1_o, mri2_64, 0, 0, 0, cmps64)
+C(0xc605, CHRL,RIL_b, GIE, r1_o, mri2_16s, 0, 0, 0, cmps32)
+C(0xc604, CGHRL,   RIL_b, GIE, r1_o, mri2_16s, 0, 0, 0, cmps64)
 /* COMPARE HIGH */
 C(0xb9cd, CHHR,RRE,   HW,  r1_sr32, r2_sr32, 0, 0, 0, cmps32)
 C(0xb9dd, CHLR,RRE,   HW,  r1_sr32, r2_o, 0, 0, 0, cmps32)
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index 21a57d5eb2..d324c0b6f2 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -5979,6 +5979,13 @@ static void in2_m2_64a(DisasContext *s, DisasOps *o)
 #define SPEC_in2_m2_64a 0
 #endif
 
+static void in2_mri2_16s(DisasContext *s, DisasOps *o)
+{
+o->in2 = tcg_temp_new_i64();
+tcg_gen_qemu_ld16s(o->in2, gen_ri2(s), get_mem_index(s));
+}
+#define SPEC_in2_mri2_16s 0
+
 static void in2_mri2_16u(DisasContext *s, DisasOps *o)
 {
 o->in2 = tcg_temp_new_i64();
-- 
2.37.2




[PATCH v2 2/2] tests/tcg/s390x: Add C(G)HRL test

2023-03-08 Thread Nina Schoetterl-Glausch
Test COMPARE HALFWORD RELATIVE LONG instructions.
Test that the bytes following the second operand do not affect the
instruction.
Test the sign extension performed on the second operand.

Signed-off-by: Nina Schoetterl-Glausch 
---


I don't know what the coding style is for inline asm.
checkpatch.sh complains about the tabs inside the asm, which I find a
bit surprising given they're inside a string.
IMO emitting tabs makes sense in order to be consistent with gcc output.
I left the tabs in for now, but can remove them.


 tests/tcg/s390x/chrl.c  | 76 +
 tests/tcg/s390x/Makefile.target |  1 +
 2 files changed, 77 insertions(+)
 create mode 100644 tests/tcg/s390x/chrl.c

diff --git a/tests/tcg/s390x/chrl.c b/tests/tcg/s390x/chrl.c
new file mode 100644
index 00..fa33d43c59
--- /dev/null
+++ b/tests/tcg/s390x/chrl.c
@@ -0,0 +1,76 @@
+#include 
+#include 
+#include 
+
+static void test_chrl(void)
+{
+uint32_t program_mask, cc;
+
+asm volatile (
+   ".pushsection .rodata\n"
+"0:.short  1,0x8000\n"
+"  .popsection\n"
+
+"  chrl%[r],0b\n"
+"  ipm %[program_mask]\n"
+: [program_mask] "=r" (program_mask)
+: [r] "r" (1)
+);
+
+cc = program_mask >> 28;
+assert(!cc);
+
+asm volatile (
+   ".pushsection .rodata\n"
+"0:.short  -1,0x8000\n"
+"  .popsection\n"
+
+"  chrl%[r],0b\n"
+"  ipm %[program_mask]\n"
+: [program_mask] "=r" (program_mask)
+: [r] "r" (-1)
+);
+
+cc = program_mask >> 28;
+assert(!cc);
+}
+
+static void test_cghrl(void)
+{
+uint32_t program_mask, cc;
+
+asm volatile (
+   ".pushsection .rodata\n"
+"0:.short  1,0x8000,0,0\n"
+"  .popsection\n"
+
+"  cghrl   %[r],0b\n"
+"  ipm %[program_mask]\n"
+: [program_mask] "=r" (program_mask)
+: [r] "r" (1L)
+);
+
+cc = program_mask >> 28;
+assert(!cc);
+
+asm volatile (
+   ".pushsection .rodata\n"
+"0:.short  -1,0x8000,0,0\n"
+"  .popsection\n"
+
+"  cghrl   %[r],0b\n"
+"  ipm %[program_mask]\n"
+: [program_mask] "=r" (program_mask)
+: [r] "r" (-1L)
+);
+
+cc = program_mask >> 28;
+assert(!cc);
+}
+
+int main(void)
+{
+test_chrl();
+test_cghrl();
+return EXIT_SUCCESS;
+}
diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
index 72ad309b27..a3d3beeffe 100644
--- a/tests/tcg/s390x/Makefile.target
+++ b/tests/tcg/s390x/Makefile.target
@@ -28,6 +28,7 @@ TESTS+=div
 TESTS+=clst
 TESTS+=long-double
 TESTS+=cdsg
+TESTS+=chrl
 
 cdsg: CFLAGS+=-pthread
 cdsg: LDFLAGS+=-pthread
-- 
2.37.2




[PATCH v2 0/2] target/s390x: Fix emulation of C(G)HRL

2023-03-08 Thread Nina Schoetterl-Glausch
The second operand of COMPARE HALFWORD RELATIVE LONG is a signed
halfword, it does not have the same size as the first operand.
Fix this and add a tcg test for c(g)hrl.

Nina Schoetterl-Glausch (2):
  target/s390x: Fix emulation of C(G)HRL
  tests/tcg/s390x: Add C(G)HRL test

 target/s390x/tcg/insn-data.h.inc |  4 +-
 target/s390x/tcg/translate.c |  7 +++
 tests/tcg/s390x/chrl.c   | 76 
 tests/tcg/s390x/Makefile.target  |  1 +
 4 files changed, 86 insertions(+), 2 deletions(-)
 create mode 100644 tests/tcg/s390x/chrl.c

Range-diff against v1:
1:  f463507b25 ! 1:  228a1d9cfb target/s390x: Fix emulation of C(G)HRL
@@ target/s390x/tcg/translate.c: static void in2_m2_64a(DisasContext *s, 
DisasOps *
  
 +static void in2_mri2_16s(DisasContext *s, DisasOps *o)
 +{
-+in2_ri2(s, o);
-+tcg_gen_qemu_ld16s(o->in2, o->in2, get_mem_index(s));
++o->in2 = tcg_temp_new_i64();
++tcg_gen_qemu_ld16s(o->in2, gen_ri2(s), get_mem_index(s));
 +}
 +#define SPEC_in2_mri2_16s 0
 +
  static void in2_mri2_16u(DisasContext *s, DisasOps *o)
  {
- in2_ri2(s, o);
+ o->in2 = tcg_temp_new_i64();
2:  316b53ebd9 = 2:  3b1ca6b682 tests/tcg/s390x: Add C(G)HRL test

base-commit: 817fd33836e73812df2f1907612b57750fcb9491
-- 
2.37.2




Re: [RFC PATCH v1 00/12] *** Add allwinner R40 device support ***

2023-03-08 Thread Niek Linnenbank
Hello Qianfan Zhao,

Thanks for contributing this work to Qemu! With your contribution, we would
get yet another Allwinner SoC supported, making it three in total
(A10/H3/R40). That's great.
My thoughts are that maybe we should try to re-use commonality between
these SoCs where we can. Ofcourse, that may be difficult as the
internals/peripherals of these SoCs often really are different.

Your patches look good already, and I saw patches 02 and 03 are already
merged too. I did a quick regression test with
avocado for cubieboard/orangepi-pc with your patches applied and that went
OK:

$ ARMBIAN_ARTIFACTS_CACHED=yes AVOCADO_ALLOW_LARGE_STORAGE=yes
./build/tests/venv/bin/avocado --show=app,console run -t
machine:orangepi-pc -t machine:cubieboard
tests/avocado/boot_linux_console.py
...
PASS (22.09 s)
RESULTS: PASS 8 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 |
CANCEL 0
JOB TIME   : 169.73 s

For now, I have only two suggestions for you to consider:
1) You could add a new acceptance test for the new bananapi board to
./tests/avocado/boot_linux_console.py.
This helps in your current work to (re)test your code quickly, and after
the code is merged it helps to keep to board working when other changes are
done.
2) If time permits, it may be interesting to document your board for
example in a new file at ./docs/system/arm/bananapi.rst
   If you do this, it will make the board a lot more valuable for other
people to use, since you can add some basic instructions on how to use the
board with qemu there.
   Additionally, it also helps yourself to store this information
somewhere, since it can be easy to forget all the specific
commands/flags/arguments and links to board specific images.

Once you have progressed with your patches beyond the RFC stage, I'll try
to find some time for a more detailed review of your patches.

Kind regards,
Niek Linnenbank

On Thu, Mar 2, 2023 at 12:41 PM  wrote:

> From: qianfan Zhao 
>
> v1: 2023-03-02
>
> The first three patches try fix allwinner i2c driver and I already send
> them
> as a standalone PR and can read it from:
>
>
> https://patchwork.kernel.org/project/qemu-devel/patch/20230220081252.25348-3-qianfangui...@163.com/
>
> Hope that patch can merged first before this.
>
> The next patches will add allwinner R40 device support, including ccu,
> mmc, i2c,
> axp221 pmic, sdram controller, emac and gmac. Now the mainline u-boot and
> kernel can work fine (It doesn't support booting allwinner bsp code and
> there
> are no plans to support it now).
>
> qianfan Zhao (12):
>   hw: allwinner-i2c: Make the trace message more readable
>   hw: allwinner-i2c: Fix TWI_CNTR_INT_FLAG on SUN6i SoCs
>   hw: arm: allwinner-h3: Fix and complete H3 i2c devices
>   hw: arm: Add bananapi M2-Ultra and allwinner-r40 support
>   hw/arm/allwinner-r40: add Clock Control Unit
>   hw: allwinner-r40: Complete uart devices
>   hw: arm: allwinner-r40: Add 5 TWI controllers
>   hw/misc: AXP221 PMU Emulation
>   hw/arm/allwinner-r40: add SDRAM controller device
>   hw: sd: allwinner-sdhost: Add sun50i-a64 SoC support
>   hw: arm: allwinner-r40: Fix the mmc controller's type
>   hw: arm: allwinner-r40: Add emac and gmac support
>
>  configs/devices/arm-softmmu/default.mak |   1 +
>  hw/arm/Kconfig  |  10 +
>  hw/arm/allwinner-h3.c   |  29 +-
>  hw/arm/allwinner-r40.c  | 555 
>  hw/arm/bananapi_m2u.c   | 128 ++
>  hw/arm/meson.build  |   1 +
>  hw/i2c/allwinner-i2c.c  | 136 +-
>  hw/i2c/trace-events |   5 +-
>  hw/misc/Kconfig |   4 +
>  hw/misc/allwinner-r40-ccu.c | 207 +
>  hw/misc/allwinner-r40-dramc.c   | 499 +
>  hw/misc/axp221.c| 196 +
>  hw/misc/meson.build |   3 +
>  hw/misc/trace-events|  19 +
>  hw/sd/allwinner-sdhost.c|  70 ++-
>  include/hw/arm/allwinner-h3.h   |   6 +
>  include/hw/arm/allwinner-r40.h  | 148 +++
>  include/hw/i2c/allwinner-i2c.h  |   6 +
>  include/hw/misc/allwinner-r40-ccu.h |  65 +++
>  include/hw/misc/allwinner-r40-dramc.h   | 108 +
>  include/hw/sd/allwinner-sdhost.h|   9 +
>  21 files changed, 2191 insertions(+), 14 deletions(-)
>  create mode 100644 hw/arm/allwinner-r40.c
>  create mode 100644 hw/arm/bananapi_m2u.c
>  create mode 100644 hw/misc/allwinner-r40-ccu.c
>  create mode 100644 hw/misc/allwinner-r40-dramc.c
>  create mode 100644 hw/misc/axp221.c
>  create mode 100644 include/hw/arm/allwinner-r40.h
>  create mode 100644 include/hw/misc/allwinner-r40-ccu.h
>  create mode 100644 include/hw/misc/allwinner-r40-dramc.h
>
> --
> 2.25.1
>
>

-- 
Niek Linnenbank


[PATCH for-8.1 13/17] target/riscv/cpu.c: split riscv_cpu_validate_priv_spec()

2023-03-08 Thread Daniel Henrique Barboza
This function will validate and change/disable extensions that aren't
compatible with a certain spec version. Since the function is called
at the start of riscv_cpu_validate_set_extensions(), we're disabling
extensions without guaranteeing that they aren't being turned on again
after the validation step.

Create a new riscv_cpu_disable_priv_spec_isa_exts() helper and call it
at the end of riscv_cpu_validate_set_extensions(), right before
re-calculating the misa_ext value with the current config. This will
ensure that we're not re-enabling extensions that should be disabled by
the spec rula by accident.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a564de01df..49f0fd2c11 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -942,7 +942,7 @@ static void riscv_cpu_validate_v(CPURISCVState *env, 
RISCVCPUConfig *cfg,
 static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)
 {
 CPURISCVState *env = &cpu->env;
-int i, priv_version = -1;
+int priv_version = -1;
 
 if (cpu->cfg.priv_spec) {
 if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
@@ -962,6 +962,12 @@ static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, 
Error **errp)
 if (priv_version >= PRIV_VERSION_1_10_0) {
 env->priv_ver = priv_version;
 }
+}
+
+static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
+{
+CPURISCVState *env = &cpu->env;
+int i;
 
 /* Force disable extensions if priv spec version does not match */
 for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
@@ -1183,6 +1189,12 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_zksh = true;
 }
 
+/*
+ * Disable isa extensions based on priv spec after we
+ * validated and set everything we need.
+ */
+riscv_cpu_disable_priv_spec_isa_exts(cpu);
+
 ext = riscv_get_misa_ext_with_cpucfg(&cpu->cfg);
 
 env->misa_ext_mask = env->misa_ext = ext;
-- 
2.39.2




[PATCH for-8.1 08/17] target/riscv/cpu.c: avoid set_misa() in validate_set_extensions()

2023-03-08 Thread Daniel Henrique Barboza
set_misa() will be tuned up to do more than it's already doing and it
will be redundant to what riscv_cpu_validate_set_extensions() does.

Note that we don't ever change env->misa_mlx in this function, so
set_misa() can be replaced by just assigning env->misa_ext and
env->misa_ext_mask to 'ext'.

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

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 499738d2dd..dc6e444219 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1153,7 +1153,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 ext |= RVJ;
 }
 
-set_misa(env, env->misa_mxl, ext);
+env->misa_ext_mask = env->misa_ext = ext;
 }
 
 #ifndef CONFIG_USER_ONLY
-- 
2.39.2




[PATCH for-8.1 05/17] target/riscv/cpu.c: add riscv_cpu_validate_priv_spec()

2023-03-08 Thread Daniel Henrique Barboza
Put all the env->priv_spec related validation into a helper to unclog
riscv_cpu_realize a bit.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 81 ++
 1 file changed, 46 insertions(+), 35 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 62ef11180f..e15f829edc 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -833,6 +833,48 @@ static void riscv_cpu_validate_v(CPURISCVState *env, 
RISCVCPUConfig *cfg,
 env->vext_ver = vext_version;
 }
 
+static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)
+{
+CPURISCVState *env = &cpu->env;
+int i, priv_version = -1;
+
+if (cpu->cfg.priv_spec) {
+if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
+priv_version = PRIV_VERSION_1_12_0;
+} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
+priv_version = PRIV_VERSION_1_11_0;
+} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
+priv_version = PRIV_VERSION_1_10_0;
+} else {
+error_setg(errp,
+   "Unsupported privilege spec version '%s'",
+   cpu->cfg.priv_spec);
+return;
+}
+}
+
+if (priv_version >= PRIV_VERSION_1_10_0) {
+env->priv_ver = priv_version;
+}
+
+/* Force disable extensions if priv spec version does not match */
+for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
+if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&
+(env->priv_ver < isa_edata_arr[i].min_version)) {
+isa_ext_update_enabled(cpu, &isa_edata_arr[i], false);
+#ifndef CONFIG_USER_ONLY
+warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
+" because privilege spec version does not match",
+isa_edata_arr[i].name, env->mhartid);
+#else
+warn_report("disabling %s extension because "
+"privilege spec version does not match",
+isa_edata_arr[i].name);
+#endif
+}
+}
+}
+
 /*
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly, doing a set_misa() in the end.
@@ -1130,7 +1172,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 CPURISCVState *env = &cpu->env;
 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
 CPUClass *cc = CPU_CLASS(mcc);
-int i, priv_version = -1;
 Error *local_err = NULL;
 
 cpu_exec_realizefn(cs, &local_err);
@@ -1139,40 +1180,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-if (cpu->cfg.priv_spec) {
-if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
-priv_version = PRIV_VERSION_1_12_0;
-} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
-priv_version = PRIV_VERSION_1_11_0;
-} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
-priv_version = PRIV_VERSION_1_10_0;
-} else {
-error_setg(errp,
-   "Unsupported privilege spec version '%s'",
-   cpu->cfg.priv_spec);
-return;
-}
-}
-
-if (priv_version >= PRIV_VERSION_1_10_0) {
-env->priv_ver = priv_version;
-}
-
-/* Force disable extensions if priv spec version does not match */
-for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
-if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&
-(env->priv_ver < isa_edata_arr[i].min_version)) {
-isa_ext_update_enabled(cpu, &isa_edata_arr[i], false);
-#ifndef CONFIG_USER_ONLY
-warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
-" because privilege spec version does not match",
-isa_edata_arr[i].name, env->mhartid);
-#else
-warn_report("disabling %s extension because "
-"privilege spec version does not match",
-isa_edata_arr[i].name);
-#endif
-}
+riscv_cpu_validate_priv_spec(cpu, &local_err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
 }
 
 if (cpu->cfg.epmp && !cpu->cfg.pmp) {
-- 
2.39.2




[PATCH for-8.1 04/17] target/riscv: add PRIV_VERSION_LATEST macro

2023-03-08 Thread Daniel Henrique Barboza
PRIV_VERSION_LATEST, at this moment assigned to PRIV_VERSION_1_12_0, is
used in all generic CPUs:

- riscv_any_cpu_init()
- rv32_base_cpu_init()
- rv64_base_cpu_init()
- rv128_base_cpu_init()

When a new PRIV version is made available we can just update the LATEST
macro.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 8 
 target/riscv/cpu.h | 1 +
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 964817b9d2..62ef11180f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -338,7 +338,7 @@ static void riscv_any_cpu_init(Object *obj)
 VM_1_10_SV32 : VM_1_10_SV57);
 #endif
 
-env->priv_ver = PRIV_VERSION_1_12_0;
+env->priv_ver = PRIV_VERSION_LATEST;
 register_cpu_props(obj);
 }
 
@@ -350,7 +350,7 @@ static void rv64_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV64, 0);
 register_cpu_props(obj);
 /* Set latest version of privileged specification */
-env->priv_ver = PRIV_VERSION_1_12_0;
+env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -426,7 +426,7 @@ static void rv128_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV128, 0);
 register_cpu_props(obj);
 /* Set latest version of privileged specification */
-env->priv_ver = PRIV_VERSION_1_12_0;
+env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -439,7 +439,7 @@ static void rv32_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV32, 0);
 register_cpu_props(obj);
 /* Set latest version of privileged specification */
-env->priv_ver = PRIV_VERSION_1_12_0;
+env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 638e47c75a..af2e4b7695 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -89,6 +89,7 @@ enum {
 PRIV_VERSION_1_11_0,
 PRIV_VERSION_1_12_0,
 };
+#define PRIV_VERSION_LATEST PRIV_VERSION_1_12_0
 
 #define VEXT_VERSION_1_00_0 0x0001
 
-- 
2.39.2




[PATCH for-8.1 09/17] target/riscv/cpu.c: set cpu config in set_misa()

2023-03-08 Thread Daniel Henrique Barboza
set_misa() is setting all 'misa' related env states and nothing else.
But other functions, namely riscv_cpu_validate_set_extensions(), uses
the config object to do its job.

This creates a need to set the single letter extensions in the cfg
object to keep both in sync. At this moment this is being done by
register_cpu_props(), forcing every CPU to do a call to this function.

Let's beef up set_misa() and make the function do the sync for us. This
will relieve named CPUs to having to call register_cpu_props(), which
will then be redesigned to a more specialized role next.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 40 
 target/riscv/cpu.h |  4 ++--
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index dc6e444219..08bdf861db 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -236,8 +236,40 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, 
bool async)
 
 static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
 {
+RISCVCPU *cpu;
+
 env->misa_mxl_max = env->misa_mxl = mxl;
 env->misa_ext_mask = env->misa_ext = ext;
+
+/*
+ * ext = 0 will only be a thing during cpu_init() functions
+ * as a way of setting an extension-agnostic CPU. We do
+ * not support clearing misa_ext* and the ext_N flags in
+ * RISCVCPUConfig in regular circunstances.
+ */
+if (ext == 0) {
+return;
+}
+
+/*
+ * We can't use riscv_cpu_cfg() in this case because it is
+ * a read-only inline and we're going to change the values
+ * of cpu->cfg.
+ */
+cpu = env_archcpu(env);
+
+cpu->cfg.ext_i = ext & RVI;
+cpu->cfg.ext_e = ext & RVE;
+cpu->cfg.ext_m = ext & RVM;
+cpu->cfg.ext_a = ext & RVA;
+cpu->cfg.ext_f = ext & RVF;
+cpu->cfg.ext_d = ext & RVD;
+cpu->cfg.ext_v = ext & RVV;
+cpu->cfg.ext_c = ext & RVC;
+cpu->cfg.ext_s = ext & RVS;
+cpu->cfg.ext_u = ext & RVU;
+cpu->cfg.ext_h = ext & RVH;
+cpu->cfg.ext_j = ext & RVJ;
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -340,7 +372,6 @@ static void riscv_any_cpu_init(Object *obj)
 #endif
 
 env->priv_ver = PRIV_VERSION_LATEST;
-register_cpu_props(obj);
 
 /* inherited from parent obj via riscv_cpu_init() */
 cpu->cfg.ext_ifencei = true;
@@ -368,7 +399,6 @@ static void rv64_sifive_u_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 CPURISCVState *env = &cpu->env;
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-register_cpu_props(obj);
 env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
@@ -387,7 +417,6 @@ static void rv64_sifive_e_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
-register_cpu_props(obj);
 env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -472,8 +501,6 @@ static void rv32_sifive_u_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 CPURISCVState *env = &cpu->env;
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-
-register_cpu_props(obj);
 env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
@@ -492,7 +519,6 @@ static void rv32_sifive_e_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
-register_cpu_props(obj);
 env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -510,7 +536,6 @@ static void rv32_ibex_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
-register_cpu_props(obj);
 env->priv_ver = PRIV_VERSION_1_11_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -529,7 +554,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
-register_cpu_props(obj);
 env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index af2e4b7695..f8baedd9c7 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -66,8 +66,8 @@
 #define RV(x) ((target_ulong)1 << (x - 'A'))
 
 /*
- * Consider updating register_cpu_props() when adding
- * new MISA bits here.
+ * Consider updating set_misa() when adding new
+ * MISA bits here.
  */
 #define RVI RV('I')
 #define RVE RV('E') /* E and I are mutually exclusive */
-- 
2.39.2




[PATCH for-8.1 17/17] target/riscv: rework write_misa()

2023-03-08 Thread Daniel Henrique Barboza
write_misa() must use as much common logic as possible, only specifying
the bits that are exclusive to the CSR write operation and TCG
internals.

Rewrite write_misa() to work as follows:

- supress RVC right after verifying that we're not updating RVG;

- mask the write using misa_ext_mask to avoid enabling unsupported
  extensions;

- emulate the steps done by the cpu init() functions: set cpu->cfg using
  the desired misa value, validate it, and then commit;

- fallback if the validation step fails. We'll need to re-write cpu->cfg
  with the original misa_ext value for the hart.

Let's keep write_misa() as experimental for now until this logic gains
enough mileage.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c |  7 +++---
 target/riscv/cpu.h |  2 ++
 target/riscv/csr.c | 53 +-
 3 files changed, 29 insertions(+), 33 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7be6a86305..4b2be32de3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -281,8 +281,7 @@ static uint32_t 
riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg)
 return ext;
 }
 
-static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,
-   uint32_t misa_ext)
+static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg, uint32_t misa_ext)
 {
 cfg->ext_i = misa_ext & RVI;
 cfg->ext_e = misa_ext & RVE;
@@ -299,7 +298,7 @@ static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,
 cfg->ext_g = misa_ext & RVG;
 }
 
-static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
+void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
 {
 env->misa_mxl_max = env->misa_mxl = mxl;
 env->misa_ext_mask = env->misa_ext = ext;
@@ -995,7 +994,7 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU 
*cpu)
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly, doing a set_misa() in the end.
  */
-static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
+void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
 {
 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
 CPUClass *cc = CPU_CLASS(mcc);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 013a1389d6..d64d0f8dd6 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -591,6 +591,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 bool probe, uintptr_t retaddr);
 char *riscv_isa_string(RISCVCPU *cpu);
 void riscv_cpu_list(void);
+void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext);
+void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
 
 #define cpu_list riscv_cpu_list
 #define cpu_mmu_index riscv_cpu_mmu_index
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 02a5c2a5ca..2e75c75fcc 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1342,6 +1342,11 @@ static RISCVException read_misa(CPURISCVState *env, int 
csrno,
 static RISCVException write_misa(CPURISCVState *env, int csrno,
  target_ulong val)
 {
+RISCVCPU *cpu = env_archcpu(env);
+uint32_t hart_ext_mask = env->misa_ext_mask;
+uint32_t hart_ext = env->misa_ext;
+Error *local_err = NULL;
+
 if (!riscv_cpu_cfg(env)->misa_w) {
 /* drop write to misa */
 return RISCV_EXCP_NONE;
@@ -1352,34 +1357,6 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
-/* 'I' or 'E' must be present */
-if (!(val & (RVI | RVE))) {
-/* It is not, drop write to misa */
-return RISCV_EXCP_NONE;
-}
-
-/* 'E' excludes all other extensions */
-if (val & RVE) {
-/*
- * when we support 'E' we can do "val = RVE;" however
- * for now we just drop writes if 'E' is present.
- */
-return RISCV_EXCP_NONE;
-}
-
-/*
- * misa.MXL writes are not supported by QEMU.
- * Drop writes to those bits.
- */
-
-/* Mask extensions that are not supported by this hart */
-val &= env->misa_ext_mask;
-
-/* 'D' depends on 'F', so clear 'D' if 'F' is not present */
-if ((val & RVD) && !(val & RVF)) {
-val &= ~RVD;
-}
-
 /*
  * Suppress 'C' if next instruction is not aligned
  * TODO: this should check next_pc
@@ -1388,18 +1365,36 @@ static RISCVException write_misa(CPURISCVState *env, 
int csrno,
 val &= ~RVC;
 }
 
+/* Mask extensions that are not supported by this hart */
+val &= hart_ext_mask;
+
 /* If nothing changed, do nothing. */
 if (val == env->misa_ext) {
 return RISCV_EXCP_NONE;
 }
 
+/*
+ * Validate the new configuration. Rollback to previous
+ * values if something goes wrong.
+ */
+set_misa(env, env->misa_mxl, val);
+riscv_cpu_validate_set_extensions(cpu, &local_err);
+if (local_err) {
+set_misa(env, env->misa_mxl, hart_ext);
+

[PATCH for-8.1 07/17] target/riscv/cpu.c: remove cfg setup from riscv_cpu_init()

2023-03-08 Thread Daniel Henrique Barboza
We have 4 config settings being done in riscv_cpu_init(): ext_ifencei,
ext_icsr, mmu and pmp. This is also the constructor of the "riscv-cpu"
device, which happens to be the parent device of every RISC-V cpu.

The result is that these 4 configs are being set every time, and every
other CPU should always account for them. CPUs such as sifive_e need to
disable settings that aren't enabled simply because the parent class
happens to be enabling it.

Moving all configurations from the parent class to each CPU will
centralize the config of each CPU into its own init(), which is clearer
than having to account to whatever happens to be set in the parent
device. These settings are also being set in register_cpu_props() when
no 'misa_ext' is set, so for these CPUs we don't need changes. Named
CPUs will receive all cfgs that the parent were setting into their
init().

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 60 --
 1 file changed, 48 insertions(+), 12 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e2cd55320c..499738d2dd 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -325,7 +325,8 @@ static void set_satp_mode_default_map(RISCVCPU *cpu)
 
 static void riscv_any_cpu_init(Object *obj)
 {
-CPURISCVState *env = &RISCV_CPU(obj)->env;
+RISCVCPU *cpu = RISCV_CPU(obj);
+CPURISCVState *env = &cpu->env;
 #if defined(TARGET_RISCV32)
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
 #elif defined(TARGET_RISCV64)
@@ -340,6 +341,12 @@ static void riscv_any_cpu_init(Object *obj)
 
 env->priv_ver = PRIV_VERSION_LATEST;
 register_cpu_props(obj);
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.ext_ifencei = true;
+cpu->cfg.ext_icsr = true;
+cpu->cfg.mmu = true;
+cpu->cfg.pmp = true;
 }
 
 #if defined(TARGET_RISCV64)
@@ -358,13 +365,20 @@ static void rv64_base_cpu_init(Object *obj)
 
 static void rv64_sifive_u_cpu_init(Object *obj)
 {
-CPURISCVState *env = &RISCV_CPU(obj)->env;
+RISCVCPU *cpu = RISCV_CPU(obj);
+CPURISCVState *env = &cpu->env;
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
 register_cpu_props(obj);
 env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
 #endif
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.ext_ifencei = true;
+cpu->cfg.ext_icsr = true;
+cpu->cfg.mmu = true;
+cpu->cfg.pmp = true;
 }
 
 static void rv64_sifive_e_cpu_init(Object *obj)
@@ -375,10 +389,14 @@ static void rv64_sifive_e_cpu_init(Object *obj)
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
 register_cpu_props(obj);
 env->priv_ver = PRIV_VERSION_1_10_0;
-cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
 #endif
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.ext_ifencei = true;
+cpu->cfg.ext_icsr = true;
+cpu->cfg.pmp = true;
 }
 
 static void rv64_thead_c906_cpu_init(Object *obj)
@@ -411,6 +429,10 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_SV39);
 #endif
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.ext_ifencei = true;
+cpu->cfg.pmp = true;
 }
 
 static void rv128_base_cpu_init(Object *obj)
@@ -447,7 +469,8 @@ static void rv32_base_cpu_init(Object *obj)
 
 static void rv32_sifive_u_cpu_init(Object *obj)
 {
-CPURISCVState *env = &RISCV_CPU(obj)->env;
+RISCVCPU *cpu = RISCV_CPU(obj);
+CPURISCVState *env = &cpu->env;
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
 
 register_cpu_props(obj);
@@ -455,6 +478,12 @@ static void rv32_sifive_u_cpu_init(Object *obj)
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.ext_ifencei = true;
+cpu->cfg.ext_icsr = true;
+cpu->cfg.mmu = true;
+cpu->cfg.pmp = true;
 }
 
 static void rv32_sifive_e_cpu_init(Object *obj)
@@ -465,10 +494,14 @@ static void rv32_sifive_e_cpu_init(Object *obj)
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
 register_cpu_props(obj);
 env->priv_ver = PRIV_VERSION_1_10_0;
-cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
 #endif
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.ext_ifencei = true;
+cpu->cfg.ext_icsr = true;
+cpu->cfg.pmp = true;
 }
 
 static void rv32_ibex_cpu_init(Object *obj)
@@ -479,11 +512,15 @@ static void rv32_ibex_cpu_init(Object *obj)
 set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
 register_cpu_props(obj);
 env->priv_ver = PRIV_VERSION_1_11_0;
-cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mo

[PATCH for-8.1 15/17] target/riscv: add RVG

2023-03-08 Thread Daniel Henrique Barboza
The 'G' bit in misa_ext is a virtual extension that enables a set of
extensions (i, m, a, f, d, icsr and ifencei). We'll want to avoid
setting it for write_misa(). Add it so we can gate write_misa() properly
against it.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 4 
 target/riscv/cpu.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7a5d202069..7be6a86305 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -274,6 +274,9 @@ static uint32_t 
riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg)
 if (cfg->ext_j) {
 ext |= RVJ;
 }
+if (cfg->ext_g) {
+ext |= RVG;
+}
 
 return ext;
 }
@@ -293,6 +296,7 @@ static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,
 cfg->ext_u = misa_ext & RVU;
 cfg->ext_h = misa_ext & RVH;
 cfg->ext_j = misa_ext & RVJ;
+cfg->ext_g = misa_ext & RVG;
 }
 
 static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 529d8044c4..013a1389d6 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -82,6 +82,7 @@
 #define RVU RV('U')
 #define RVH RV('H')
 #define RVJ RV('J')
+#define RVG RV('G')
 
 
 /* Privileged specification version */
-- 
2.39.2




[PATCH for-8.1 06/17] target/riscv: move realize() validations to riscv_cpu_validate_set_extensions()

2023-03-08 Thread Daniel Henrique Barboza
Center all validations that are scattered in riscv_cpu_realize() in the
same function.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 74 ++
 1 file changed, 35 insertions(+), 39 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e15f829edc..e2cd55320c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -881,9 +881,43 @@ static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, 
Error **errp)
  */
 static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
 {
+RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
+CPUClass *cc = CPU_CLASS(mcc);
 CPURISCVState *env = &cpu->env;
+Error *local_err = NULL;
 uint32_t ext = 0;
 
+riscv_cpu_validate_priv_spec(cpu, &local_err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
+
+if (cpu->cfg.epmp && !cpu->cfg.pmp) {
+/*
+ * Enhanced PMP should only be available
+ * on harts with PMP support
+ */
+error_setg(errp, "Invalid configuration: EPMP requires PMP support");
+return;
+}
+
+/* Validate that MISA_MXL is set properly. */
+switch (env->misa_mxl_max) {
+#ifdef TARGET_RISCV64
+case MXL_RV64:
+case MXL_RV128:
+cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
+break;
+#endif
+case MXL_RV32:
+cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
+break;
+default:
+g_assert_not_reached();
+}
+assert(env->misa_mxl_max == env->misa_mxl);
+
 /* Do some ISA extension error checking */
 if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
 cpu->cfg.ext_a && cpu->cfg.ext_f &&
@@ -1066,8 +1100,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 ext |= RVH;
 }
 if (cpu->cfg.ext_v) {
-Error *local_err = NULL;
-
 riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
 if (local_err != NULL) {
 error_propagate(errp, local_err);
@@ -1169,9 +1201,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 {
 CPUState *cs = CPU(dev);
 RISCVCPU *cpu = RISCV_CPU(dev);
-CPURISCVState *env = &cpu->env;
 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
-CPUClass *cc = CPU_CLASS(mcc);
 Error *local_err = NULL;
 
 cpu_exec_realizefn(cs, &local_err);
@@ -1180,51 +1210,17 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-riscv_cpu_validate_priv_spec(cpu, &local_err);
+riscv_cpu_validate_set_extensions(cpu, &local_err);
 if (local_err != NULL) {
 error_propagate(errp, local_err);
 return;
 }
 
-if (cpu->cfg.epmp && !cpu->cfg.pmp) {
-/*
- * Enhanced PMP should only be available
- * on harts with PMP support
- */
-error_setg(errp, "Invalid configuration: EPMP requires PMP support");
-return;
-}
-
-
 #ifndef CONFIG_USER_ONLY
 if (cpu->cfg.ext_sstc) {
 riscv_timer_init(cpu);
 }
-#endif /* CONFIG_USER_ONLY */
-
-/* Validate that MISA_MXL is set properly. */
-switch (env->misa_mxl_max) {
-#ifdef TARGET_RISCV64
-case MXL_RV64:
-case MXL_RV128:
-cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
-break;
-#endif
-case MXL_RV32:
-cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
-break;
-default:
-g_assert_not_reached();
-}
-assert(env->misa_mxl_max == env->misa_mxl);
 
-riscv_cpu_validate_set_extensions(cpu, &local_err);
-if (local_err != NULL) {
-error_propagate(errp, local_err);
-return;
-}
-
-#ifndef CONFIG_USER_ONLY
 if (cpu->cfg.pmu_num) {
 if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
 cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
-- 
2.39.2




[PATCH for-8.1 11/17] target/riscv/cpu.c: move riscv_cpu_validate_v() up

2023-03-08 Thread Daniel Henrique Barboza
riscv_cpu_validate_set_extensions() will play a future role in
write_misa(). First we need to ensure that this function is validating
first and setting cfg values later. At this moment this is not the case
of the RVV validation.

Move RVV validation up. Leave the 'ext |= RVV' where it is - next patch
has plans for it.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4988fd4d4b..48838471b8 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -,6 +,14 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 }
 }
 
+if (cpu->cfg.ext_v) {
+riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
+}
+
 if (cpu->cfg.ext_zk) {
 cpu->cfg.ext_zkn = true;
 cpu->cfg.ext_zkr = true;
@@ -1165,12 +1173,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 ext |= RVH;
 }
 if (cpu->cfg.ext_v) {
-riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
-if (local_err != NULL) {
-error_propagate(errp, local_err);
-return;
-}
-
 ext |= RVV;
 }
 if (cpu->cfg.ext_j) {
-- 
2.39.2




[PATCH for-8.1 03/17] target/riscv/cpu.c: remove set_priv_version()

2023-03-08 Thread Daniel Henrique Barboza
The setter is doing nothing special. Just set env->priv_ver directly.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 30 +-
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0baed79ec2..964817b9d2 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -240,11 +240,6 @@ static void set_misa(CPURISCVState *env, RISCVMXL mxl, 
uint32_t ext)
 env->misa_ext_mask = env->misa_ext = ext;
 }
 
-static void set_priv_version(CPURISCVState *env, int priv_ver)
-{
-env->priv_ver = priv_ver;
-}
-
 #ifndef CONFIG_USER_ONLY
 static uint8_t satp_mode_from_str(const char *satp_mode_str)
 {
@@ -343,7 +338,7 @@ static void riscv_any_cpu_init(Object *obj)
 VM_1_10_SV32 : VM_1_10_SV57);
 #endif
 
-set_priv_version(env, PRIV_VERSION_1_12_0);
+env->priv_ver = PRIV_VERSION_1_12_0;
 register_cpu_props(obj);
 }
 
@@ -355,7 +350,7 @@ static void rv64_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV64, 0);
 register_cpu_props(obj);
 /* Set latest version of privileged specification */
-set_priv_version(env, PRIV_VERSION_1_12_0);
+env->priv_ver = PRIV_VERSION_1_12_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -366,7 +361,7 @@ static void rv64_sifive_u_cpu_init(Object *obj)
 CPURISCVState *env = &RISCV_CPU(obj)->env;
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
 register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
 #endif
@@ -379,7 +374,7 @@ static void rv64_sifive_e_cpu_init(Object *obj)
 
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
 register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
 cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -392,7 +387,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-set_priv_version(env, PRIV_VERSION_1_11_0);
+env->priv_ver = PRIV_VERSION_1_11_0;
 
 cpu->cfg.ext_g = true;
 cpu->cfg.ext_c = true;
@@ -431,7 +426,7 @@ static void rv128_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV128, 0);
 register_cpu_props(obj);
 /* Set latest version of privileged specification */
-set_priv_version(env, PRIV_VERSION_1_12_0);
+env->priv_ver = PRIV_VERSION_1_12_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -444,7 +439,7 @@ static void rv32_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV32, 0);
 register_cpu_props(obj);
 /* Set latest version of privileged specification */
-set_priv_version(env, PRIV_VERSION_1_12_0);
+env->priv_ver = PRIV_VERSION_1_12_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
@@ -454,8 +449,9 @@ static void rv32_sifive_u_cpu_init(Object *obj)
 {
 CPURISCVState *env = &RISCV_CPU(obj)->env;
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+
 register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
@@ -468,7 +464,7 @@ static void rv32_sifive_e_cpu_init(Object *obj)
 
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
 register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
 cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -482,7 +478,7 @@ static void rv32_ibex_cpu_init(Object *obj)
 
 set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
 register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_11_0);
+env->priv_ver = PRIV_VERSION_1_11_0;
 cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -497,7 +493,7 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
 
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
 register_cpu_props(obj);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
 cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -1159,7 +1155,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 
 if (priv_version >= PRIV_VERSION_1_10_0) {
-set_priv_version(env, priv_version);
+env->priv_ver = priv_version;
 }
 
 /* Force disable extensions if priv spec version does not match */
-- 
2.39.

[PATCH for-8.1 02/17] target/riscv/cpu.c: remove set_vext_version()

2023-03-08 Thread Daniel Henrique Barboza
This setter is doing nothing else but setting env->vext_ver. Assign the
value directly.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5060a98b6d..0baed79ec2 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -245,11 +245,6 @@ static void set_priv_version(CPURISCVState *env, int 
priv_ver)
 env->priv_ver = priv_ver;
 }
 
-static void set_vext_version(CPURISCVState *env, int vext_ver)
-{
-env->vext_ver = vext_ver;
-}
-
 #ifndef CONFIG_USER_ONLY
 static uint8_t satp_mode_from_str(const char *satp_mode_str)
 {
@@ -839,7 +834,7 @@ static void riscv_cpu_validate_v(CPURISCVState *env, 
RISCVCPUConfig *cfg,
 qemu_log("vector version is not specified, "
  "use the default value v1.0\n");
 }
-set_vext_version(env, vext_version);
+env->vext_ver = vext_version;
 }
 
 /*
-- 
2.39.2




[PATCH for-8.1 16/17] target/riscv: do not allow RVG in write_misa()

2023-03-08 Thread Daniel Henrique Barboza
We're getting ready to use riscv_cpu_validate_set_extensions() to unify
the handling of write_misa() with the rest of the code base. But first
we need to deal with RVG.

The 'G' virtual extension enables a set of extensions in the CPU. At
this moment, this is done at the start of our validation step in
riscv_cpu_validate_set_extensions(). This means that enabling G will
enable other extensions in the CPU before resuming the validation.

This also means that, in case a write_misa() validation fails, we're
going to set cpu->cfg attributes that are unrelated to misa_ext bits
(icsr and ifencei). These would be 2 extra states that we would need to
store to fallback from a validation failure.

Since write_misa() is still on experimental state let's make our lives
easier for now and disable RVG updates.

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

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index ab566639e5..02a5c2a5ca 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1347,6 +1347,11 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
+/* Changing 'G' state is unsupported */
+if (val & RVG) {
+return RISCV_EXCP_NONE;
+}
+
 /* 'I' or 'E' must be present */
 if (!(val & (RVI | RVE))) {
 /* It is not, drop write to misa */
-- 
2.39.2




[PATCH for-8.1 12/17] target/riscv: put env->misa_ext <-> cpu->cfg code into helpers

2023-03-08 Thread Daniel Henrique Barboza
The extremely tedious code that sets cpu->cfg based on misa_ext, and
vice-versa, is scattered around riscv_cpu_validate_set_extensions() and
set_misa().

Introduce helpers to do this work, cleaning up the logic of both
functions a bit. While we're at it, add a note in cpu.h informing that
any future change in MISA RV* bits should also be reflected in the
helpers as well.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 120 -
 target/riscv/cpu.h |   3 +-
 2 files changed, 65 insertions(+), 58 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 48838471b8..a564de01df 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -234,10 +234,69 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, 
bool async)
 }
 }
 
-static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
+static uint32_t riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg)
 {
-RISCVCPU *cpu;
+uint32_t ext = 0;
 
+if (cfg->ext_i) {
+ext |= RVI;
+}
+if (cfg->ext_e) {
+ext |= RVE;
+}
+if (cfg->ext_m) {
+ext |= RVM;
+}
+if (cfg->ext_a) {
+ext |= RVA;
+}
+if (cfg->ext_f) {
+ext |= RVF;
+}
+if (cfg->ext_d) {
+ext |= RVD;
+}
+if (cfg->ext_c) {
+ext |= RVC;
+}
+if (cfg->ext_s) {
+ext |= RVS;
+}
+if (cfg->ext_u) {
+ext |= RVU;
+}
+if (cfg->ext_h) {
+ext |= RVH;
+}
+if (cfg->ext_v) {
+ext |= RVV;
+}
+if (cfg->ext_j) {
+ext |= RVJ;
+}
+
+return ext;
+}
+
+static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,
+   uint32_t misa_ext)
+{
+cfg->ext_i = misa_ext & RVI;
+cfg->ext_e = misa_ext & RVE;
+cfg->ext_m = misa_ext & RVM;
+cfg->ext_a = misa_ext & RVA;
+cfg->ext_f = misa_ext & RVF;
+cfg->ext_d = misa_ext & RVD;
+cfg->ext_v = misa_ext & RVV;
+cfg->ext_c = misa_ext & RVC;
+cfg->ext_s = misa_ext & RVS;
+cfg->ext_u = misa_ext & RVU;
+cfg->ext_h = misa_ext & RVH;
+cfg->ext_j = misa_ext & RVJ;
+}
+
+static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
+{
 env->misa_mxl_max = env->misa_mxl = mxl;
 env->misa_ext_mask = env->misa_ext = ext;
 
@@ -251,25 +310,7 @@ static void set_misa(CPURISCVState *env, RISCVMXL mxl, 
uint32_t ext)
 return;
 }
 
-/*
- * We can't use riscv_cpu_cfg() in this case because it is
- * a read-only inline and we're going to change the values
- * of cpu->cfg.
- */
-cpu = env_archcpu(env);
-
-cpu->cfg.ext_i = ext & RVI;
-cpu->cfg.ext_e = ext & RVE;
-cpu->cfg.ext_m = ext & RVM;
-cpu->cfg.ext_a = ext & RVA;
-cpu->cfg.ext_f = ext & RVF;
-cpu->cfg.ext_d = ext & RVD;
-cpu->cfg.ext_v = ext & RVV;
-cpu->cfg.ext_c = ext & RVC;
-cpu->cfg.ext_s = ext & RVS;
-cpu->cfg.ext_u = ext & RVU;
-cpu->cfg.ext_h = ext & RVH;
-cpu->cfg.ext_j = ext & RVJ;
+riscv_set_cpucfg_with_misa(&env_archcpu(env)->cfg, ext);
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -1142,42 +1183,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_zksh = true;
 }
 
-if (cpu->cfg.ext_i) {
-ext |= RVI;
-}
-if (cpu->cfg.ext_e) {
-ext |= RVE;
-}
-if (cpu->cfg.ext_m) {
-ext |= RVM;
-}
-if (cpu->cfg.ext_a) {
-ext |= RVA;
-}
-if (cpu->cfg.ext_f) {
-ext |= RVF;
-}
-if (cpu->cfg.ext_d) {
-ext |= RVD;
-}
-if (cpu->cfg.ext_c) {
-ext |= RVC;
-}
-if (cpu->cfg.ext_s) {
-ext |= RVS;
-}
-if (cpu->cfg.ext_u) {
-ext |= RVU;
-}
-if (cpu->cfg.ext_h) {
-ext |= RVH;
-}
-if (cpu->cfg.ext_v) {
-ext |= RVV;
-}
-if (cpu->cfg.ext_j) {
-ext |= RVJ;
-}
+ext = riscv_get_misa_ext_with_cpucfg(&cpu->cfg);
 
 env->misa_ext_mask = env->misa_ext = ext;
 }
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f8baedd9c7..529d8044c4 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -66,7 +66,8 @@
 #define RV(x) ((target_ulong)1 << (x - 'A'))
 
 /*
- * Consider updating set_misa() when adding new
+ * Consider updating riscv_get_misa_ext_with_cpucfg()
+ * and riscv_set_cpucfg_with_misa() when adding new
  * MISA bits here.
  */
 #define RVI RV('I')
-- 
2.39.2




[PATCH for-8.1 14/17] target/riscv/cpu.c: do not allow RVE to be set

2023-03-08 Thread Daniel Henrique Barboza
This restriction is found at the current implementation of write_misa()
in csr.c. Add it in riscv_cpu_validate_set_extensions() as well, while
also removing the checks we're doing considering that I or E can be
enabled.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 49f0fd2c11..7a5d202069 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1045,15 +1045,15 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_ifencei = true;
 }
 
-if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
-error_setg(errp,
-   "I and E extensions are incompatible");
+/* We do not have RV32E support  */
+if (cpu->cfg.ext_e) {
+error_setg(errp, "E extension (RV32E) is not supported");
 return;
 }
 
-if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {
-error_setg(errp,
-   "Either I or E extension must be set");
+/* When RV32E is supported we'll need to check for either I or E */
+if (!cpu->cfg.ext_i) {
+error_setg(errp, "I extension must be set");
 return;
 }
 
-- 
2.39.2




[PATCH for-8.1 00/17] centralize CPU extensions logic

2023-03-08 Thread Daniel Henrique Barboza
Hi,

During the review of a series that did some work in the RISCV_FEATURES*
enum, Liu Zhiwei commented on how we could centralize the all the
extension validation code and integrate it with write_misa() [1].

This does at least part of what was suggested. The idea is that, ATM, we
have too many places setting cpu->cfg and the validation logic is
scattered around (e.g. there are some contraints in write_misa() that
should be applicable elsewhere). This series is an attempt to centralize
things a bit.

The main accomplishments of this series are:

- the parent device riscv-cpu no longer sets any cpu->cfg attribute. This
  was forcing init() functions to disable extensions that it wouldn't
  use just because the parent device was enabling it;

- all validations are centered in validate_set_extensions(), with
  pontual exceptions in write_misa() that has exclusive contraints;

- set_misa() now writes cpu->cfg. No need to have one function to set
  env->misa_ext and then another to set cpu->cfg;

- register_cpu_props() now only exposes user-facing props;

- all validations from validate_set_extensions() are done at the start
  of the function. Validate first, set extensions after;

- RVE is now forbidden in all validations, not just in write_misa();

- RVG is now forbidden in write_misa();

- write_misa now uses set_misa() and validate_set_extensions().



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

Daniel Henrique Barboza (17):
  target/riscv/cpu.c: add riscv_cpu_validate_v()
  target/riscv/cpu.c: remove set_vext_version()
  target/riscv/cpu.c: remove set_priv_version()
  target/riscv: add PRIV_VERSION_LATEST macro
  target/riscv/cpu.c: add riscv_cpu_validate_priv_spec()
  target/riscv: move realize() validations to
riscv_cpu_validate_set_extensions()
  target/riscv/cpu.c: remove cfg setup from riscv_cpu_init()
  target/riscv/cpu.c: avoid set_misa() in validate_set_extensions()
  target/riscv/cpu.c: set cpu config in set_misa()
  target/riscv/cpu.c: redesign register_cpu_props()
  target/riscv/cpu.c: move riscv_cpu_validate_v() up
  target/riscv: put env->misa_ext <-> cpu->cfg code into helpers
  target/riscv/cpu.c: split riscv_cpu_validate_priv_spec()
  target/riscv/cpu.c: do not allow RVE to be set
  target/riscv: add RVG
  target/riscv: do not allow RVG in write_misa()
  target/riscv: rework write_misa()

 target/riscv/cpu.c | 516 +
 target/riscv/cpu.h |   9 +-
 target/riscv/csr.c |  52 ++---
 3 files changed, 323 insertions(+), 254 deletions(-)

-- 
2.39.2




[PATCH for-8.1 01/17] target/riscv/cpu.c: add riscv_cpu_validate_v()

2023-03-08 Thread Daniel Henrique Barboza
The code that validates ext_v in riscv_cpu_validate_set_extensions() is
not properly indented - we're missing an extra indent level right after
the first check that uses cfg->elen.

In the end the 'v' verification is a bit too large in comparison with
the others, and can be put in a separated function to enhance the
readability of riscv_cpu_validate_set_extensions().

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 83 ++
 1 file changed, 47 insertions(+), 36 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1e97473af2..5060a98b6d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -802,6 +802,46 @@ static void riscv_cpu_disas_set_info(CPUState *s, 
disassemble_info *info)
 }
 }
 
+static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
+ Error **errp)
+{
+int vext_version = VEXT_VERSION_1_00_0;
+
+if (!is_power_of_2(cfg->vlen)) {
+error_setg(errp, "Vector extension VLEN must be power of 2");
+return;
+}
+if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) {
+error_setg(errp,
+   "Vector extension implementation only supports VLEN "
+   "in the range [128, %d]", RV_VLEN_MAX);
+return;
+}
+if (!is_power_of_2(cfg->elen)) {
+error_setg(errp, "Vector extension ELEN must be power of 2");
+return;
+}
+if (cfg->elen > 64 || cfg->elen < 8) {
+error_setg(errp,
+   "Vector extension implementation only supports ELEN "
+   "in the range [8, 64]");
+return;
+}
+if (cfg->vext_spec) {
+if (!g_strcmp0(cfg->vext_spec, "v1.0")) {
+vext_version = VEXT_VERSION_1_00_0;
+} else {
+error_setg(errp, "Unsupported vector spec version '%s'",
+   cfg->vext_spec);
+return;
+}
+} else {
+qemu_log("vector version is not specified, "
+ "use the default value v1.0\n");
+}
+set_vext_version(env, vext_version);
+}
+
 /*
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly, doing a set_misa() in the end.
@@ -993,44 +1033,15 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 ext |= RVH;
 }
 if (cpu->cfg.ext_v) {
-int vext_version = VEXT_VERSION_1_00_0;
-ext |= RVV;
-if (!is_power_of_2(cpu->cfg.vlen)) {
-error_setg(errp,
-   "Vector extension VLEN must be power of 2");
-return;
-}
-if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) {
-error_setg(errp,
-   "Vector extension implementation only supports VLEN "
-   "in the range [128, %d]", RV_VLEN_MAX);
-return;
-}
-if (!is_power_of_2(cpu->cfg.elen)) {
-error_setg(errp,
-   "Vector extension ELEN must be power of 2");
-return;
-}
-if (cpu->cfg.elen > 64 || cpu->cfg.elen < 8) {
-error_setg(errp,
-   "Vector extension implementation only supports ELEN "
-   "in the range [8, 64]");
+Error *local_err = NULL;
+
+riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
 return;
 }
-if (cpu->cfg.vext_spec) {
-if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) {
-vext_version = VEXT_VERSION_1_00_0;
-} else {
-error_setg(errp,
-   "Unsupported vector spec version '%s'",
-   cpu->cfg.vext_spec);
-return;
-}
-} else {
-qemu_log("vector version is not specified, "
- "use the default value v1.0\n");
-}
-set_vext_version(env, vext_version);
+
+ext |= RVV;
 }
 if (cpu->cfg.ext_j) {
 ext |= RVJ;
-- 
2.39.2




[PATCH for-8.1 10/17] target/riscv/cpu.c: redesign register_cpu_props()

2023-03-08 Thread Daniel Henrique Barboza
Now that the function is a no-op if 'env.misa_ext != 0', and no one that
are setting misa_ext != 0 is calling it because set_misa() is setting
the cpu cfg accordingly, remove the now deprecated code and rename the
function to register_generic_cpu_props().

This function is now doing exactly what the name says: it is creating
user-facing properties to allow changes in the CPU cfg via the QEMU
command line, setting default values if no user input is provided.

Note that there's the possibility of a CPU to set a certain misa value
and, at the same, also want user-facing flags and defaults from this
function. This is not the case since commit 26b2bc58599c ("target/riscv:
Don't expose the CPU properties on names CPUs"), but given that this is
also a possibility, clarify in the function that using this function
will overwrite existing values in cpu->cfg.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 48 ++
 1 file changed, 10 insertions(+), 38 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 08bdf861db..4988fd4d4b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -221,7 +221,7 @@ static const char * const riscv_intr_names[] = {
 "reserved"
 };
 
-static void register_cpu_props(Object *obj);
+static void register_generic_cpu_props(Object *obj);
 
 const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
 {
@@ -386,7 +386,7 @@ static void rv64_base_cpu_init(Object *obj)
 CPURISCVState *env = &RISCV_CPU(obj)->env;
 /* We set this in the realise function */
 set_misa(env, MXL_RV64, 0);
-register_cpu_props(obj);
+register_generic_cpu_props(obj);
 /* Set latest version of privileged specification */
 env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
@@ -475,7 +475,7 @@ static void rv128_base_cpu_init(Object *obj)
 CPURISCVState *env = &RISCV_CPU(obj)->env;
 /* We set this in the realise function */
 set_misa(env, MXL_RV128, 0);
-register_cpu_props(obj);
+register_generic_cpu_props(obj);
 /* Set latest version of privileged specification */
 env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
@@ -488,7 +488,7 @@ static void rv32_base_cpu_init(Object *obj)
 CPURISCVState *env = &RISCV_CPU(obj)->env;
 /* We set this in the realise function */
 set_misa(env, MXL_RV32, 0);
-register_cpu_props(obj);
+register_generic_cpu_props(obj);
 /* Set latest version of privileged specification */
 env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
@@ -575,7 +575,7 @@ static void riscv_host_cpu_init(Object *obj)
 #elif defined(TARGET_RISCV64)
 set_misa(env, MXL_RV64, 0);
 #endif
-register_cpu_props(obj);
+register_generic_cpu_props(obj);
 }
 #endif
 
@@ -1529,44 +1529,16 @@ static Property riscv_cpu_extensions[] = {
 };
 
 /*
- * Register CPU props based on env.misa_ext. If a non-zero
- * value was set, register only the required cpu->cfg.ext_*
- * properties and leave. env.misa_ext = 0 means that we want
- * all the default properties to be registered.
+ * Register generic CPU props with user-facing flags declared
+ * in riscv_cpu_extensions[].
+ *
+ * Note that this will overwrite existing values in cpu->cfg.
  */
-static void register_cpu_props(Object *obj)
+static void register_generic_cpu_props(Object *obj)
 {
-RISCVCPU *cpu = RISCV_CPU(obj);
-uint32_t misa_ext = cpu->env.misa_ext;
 Property *prop;
 DeviceState *dev = DEVICE(obj);
 
-/*
- * If misa_ext is not zero, set cfg properties now to
- * allow them to be read during riscv_cpu_realize()
- * later on.
- */
-if (cpu->env.misa_ext != 0) {
-cpu->cfg.ext_i = misa_ext & RVI;
-cpu->cfg.ext_e = misa_ext & RVE;
-cpu->cfg.ext_m = misa_ext & RVM;
-cpu->cfg.ext_a = misa_ext & RVA;
-cpu->cfg.ext_f = misa_ext & RVF;
-cpu->cfg.ext_d = misa_ext & RVD;
-cpu->cfg.ext_v = misa_ext & RVV;
-cpu->cfg.ext_c = misa_ext & RVC;
-cpu->cfg.ext_s = misa_ext & RVS;
-cpu->cfg.ext_u = misa_ext & RVU;
-cpu->cfg.ext_h = misa_ext & RVH;
-cpu->cfg.ext_j = misa_ext & RVJ;
-
-/*
- * We don't want to set the default riscv_cpu_extensions
- * in this case.
- */
-return;
-}
-
 for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
 qdev_property_add_static(dev, prop);
 }
-- 
2.39.2




[PULL 5/5] qga/win/vss: requester_freeze changes

2023-03-08 Thread Konstantin Kostiuk
From: Kfir Manor 

Change requester_freeze so that the VSS backup type queried from the registry

Signed-off-by: Kfir Manor 
Reviewed-by: Konstantin Kostiuk 
Signed-off-by: Konstantin Kostiuk 
---
 qga/vss-win32/requester.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp
index e06d516675..3e998af4a8 100644
--- a/qga/vss-win32/requester.cpp
+++ b/qga/vss-win32/requester.cpp
@@ -285,6 +285,7 @@ void requester_freeze(int *num_vols, void *mountpoints, 
ErrorSet *errset)
 DWORD wait_status;
 int num_fixed_drives = 0, i;
 int num_mount_points = 0;
+VSS_BACKUP_TYPE vss_bt = get_vss_backup_type();
 
 if (vss_ctx.pVssbc) { /* already frozen */
 *num_vols = 0;
@@ -332,7 +333,7 @@ void requester_freeze(int *num_vols, void *mountpoints, 
ErrorSet *errset)
 goto out;
 }
 
-hr = vss_ctx.pVssbc->SetBackupState(true, true, VSS_BT_FULL, false);
+hr = vss_ctx.pVssbc->SetBackupState(true, true, vss_bt, false);
 if (FAILED(hr)) {
 err_set(errset, hr, "failed to set backup state");
 goto out;
-- 
2.25.1




[PULL 2/5] qga/win32: Use rundll for VSS installation

2023-03-08 Thread Konstantin Kostiuk
The custom action uses cmd.exe to run VSS Service installation
and removal which causes an interactive command shell to spawn.
This shell can be used to execute any commands as a SYSTEM user.
Even if call qemu-ga.exe directly the interactive command shell
will be spawned as qemu-ga.exe is a console application and used
by users from the console as well as a service.

As VSS Service runs from DLL which contains the installer and
uninstaller code, it can be run directly by rundll32.exe without
any interactive command shell.

Add specific entry points for rundll which is just a wrapper
for COMRegister/COMUnregister functions with proper arguments.

resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2167423
fixes: CVE-2023-0664 (part 2 of 2)

Signed-off-by: Konstantin Kostiuk 
Reviewed-by: Yan Vugenfirer 
Reported-by: Brian Wiltse 
---
 qga/installer/qemu-ga.wxs | 10 +-
 qga/vss-win32/install.cpp |  9 +
 qga/vss-win32/qga-vss.def |  2 ++
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/qga/installer/qemu-ga.wxs b/qga/installer/qemu-ga.wxs
index feb629ec47..46ae9e7a13 100644
--- a/qga/installer/qemu-ga.wxs
+++ b/qga/installer/qemu-ga.wxs
@@ -127,22 +127,22 @@
   
 
 
-
+
 
 
 
 
 
 
diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp
index b57508fbe0..68662a6dfc 100644
--- a/qga/vss-win32/install.cpp
+++ b/qga/vss-win32/install.cpp
@@ -357,6 +357,15 @@ out:
 return hr;
 }
 
+STDAPI_(void) CALLBACK DLLCOMRegister(HWND, HINSTANCE, LPSTR, int)
+{
+COMRegister();
+}
+
+STDAPI_(void) CALLBACK DLLCOMUnregister(HWND, HINSTANCE, LPSTR, int)
+{
+COMUnregister();
+}
 
 static BOOL CreateRegistryKey(LPCTSTR key, LPCTSTR value, LPCTSTR data)
 {
diff --git a/qga/vss-win32/qga-vss.def b/qga/vss-win32/qga-vss.def
index 927782c31b..ee97a81427 100644
--- a/qga/vss-win32/qga-vss.def
+++ b/qga/vss-win32/qga-vss.def
@@ -1,6 +1,8 @@
 LIBRARY  "QGA-PROVIDER.DLL"
 
 EXPORTS
+   DLLCOMRegister
+   DLLCOMUnregister
COMRegister PRIVATE
COMUnregister   PRIVATE
DllCanUnloadNow PRIVATE
-- 
2.25.1




[PULL 3/5] qga/win/installer: add VssOption to installer

2023-03-08 Thread Konstantin Kostiuk
From: Kfir Manor 

Adds registry value VssOption with value 1 to QEMU Guest Agent VSS Provider 
service registry key

Signed-off-by: Kfir Manor 
Reviewed-by: Konstantin Kostiuk 
Signed-off-by: Konstantin Kostiuk 
---
 qga/installer/qemu-ga.wxs | 4 
 1 file changed, 4 insertions(+)

diff --git a/qga/installer/qemu-ga.wxs b/qga/installer/qemu-ga.wxs
index 46ae9e7a13..df572adb4a 100644
--- a/qga/installer/qemu-ga.wxs
+++ b/qga/installer/qemu-ga.wxs
@@ -122,6 +122,10 @@
   
   
 
+
+  
+
   
 
   
-- 
2.25.1




[PULL 4/5] qga/win/vss: query VSS backup type

2023-03-08 Thread Konstantin Kostiuk
From: Kfir Manor 

Query VSS backup type number (DWORD) from QEMU Guest Agent VSS Provider 
registry key registry value VssOption

Translate the VSS backup type number (DWORD) into its VSS backup type 
(VSS_BACKUP_TYPE)

Returns the queried VSS backup type if the program encounters unexpected 
behaviors or values return default VSS backup type VSS_BT_FULL instead

Signed-off-by: Kfir Manor 
Reviewed-by: Konstantin Kostiuk 
Signed-off-by: Konstantin Kostiuk 
---
 qga/vss-win32/requester.cpp | 38 +
 qga/vss-win32/vss-handles.h |  3 +++
 2 files changed, 41 insertions(+)

diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp
index b371affeab..e06d516675 100644
--- a/qga/vss-win32/requester.cpp
+++ b/qga/vss-win32/requester.cpp
@@ -23,6 +23,8 @@
 /* Call QueryStatus every 10 ms while waiting for frozen event */
 #define VSS_TIMEOUT_EVENT_MSEC 10
 
+#define DEFAULT_VSS_BACKUP_TYPE VSS_BT_FULL
+
 #define err_set(e, err, fmt, ...)   \
 ((e)->error_setg_win32_wrapper((e)->errp, __FILE__, __LINE__, __func__, \
err, fmt, ## __VA_ARGS__))
@@ -234,6 +236,42 @@ out:
 }
 }
 
+DWORD get_reg_dword_value(HKEY baseKey, LPCSTR subKey, LPCSTR valueName,
+  DWORD defaultData)
+{
+DWORD regGetValueError;
+DWORD dwordData;
+DWORD dataSize = sizeof(DWORD);
+
+regGetValueError = RegGetValue(baseKey, subKey, valueName, RRF_RT_DWORD,
+   NULL, &dwordData, &dataSize);
+if (regGetValueError  != ERROR_SUCCESS) {
+return defaultData;
+}
+return dwordData;
+}
+
+bool is_valid_vss_backup_type(VSS_BACKUP_TYPE vssBT)
+{
+return (vssBT > VSS_BT_UNDEFINED && vssBT < VSS_BT_OTHER);
+}
+
+VSS_BACKUP_TYPE get_vss_backup_type(
+VSS_BACKUP_TYPE defaultVssBT = DEFAULT_VSS_BACKUP_TYPE)
+{
+VSS_BACKUP_TYPE vssBackupType;
+
+vssBackupType = static_cast(
+get_reg_dword_value(HKEY_LOCAL_MACHINE,
+QGA_PROVIDER_REGISTRY_ADDRESS,
+"VssOption",
+defaultVssBT));
+if (!is_valid_vss_backup_type(vssBackupType)) {
+return defaultVssBT;
+}
+return vssBackupType;
+}
+
 void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset)
 {
 COMPointer pAsync;
diff --git a/qga/vss-win32/vss-handles.h b/qga/vss-win32/vss-handles.h
index 0f8a741ad2..1a7d842129 100644
--- a/qga/vss-win32/vss-handles.h
+++ b/qga/vss-win32/vss-handles.h
@@ -6,6 +6,9 @@
 #define QGA_PROVIDER_NAME "QEMU Guest Agent VSS Provider"
 #define QGA_PROVIDER_LNAME L(QGA_PROVIDER_NAME)
 #define QGA_PROVIDER_VERSION L(QEMU_VERSION)
+#define QGA_PROVIDER_REGISTRY_ADDRESS "SYSTEM\\CurrentControlSet"\
+  "\\Services"\
+  "\\" QGA_PROVIDER_NAME
 
 #define EVENT_NAME_FROZEN  "Global\\QGAVSSEvent-frozen"
 #define EVENT_NAME_THAW"Global\\QGAVSSEvent-thaw"
-- 
2.25.1




[PULL 1/5] qga/win32: Remove change action from MSI installer

2023-03-08 Thread Konstantin Kostiuk
Remove the 'change' button from "Programs and Features" because it does
not checks if a user is an admin or not. The installer has no components
to choose from and always installs everything. So the 'change' button is
not obviously needed but can create a security issue.

resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2167423
fixes: CVE-2023-0664 (part 1 of 2)

Signed-off-by: Konstantin Kostiuk 
Reviewed-by: Yan Vugenfirer 
Reported-by: Brian Wiltse 
---
 qga/installer/qemu-ga.wxs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/qga/installer/qemu-ga.wxs b/qga/installer/qemu-ga.wxs
index 51340f7ecc..feb629ec47 100644
--- a/qga/installer/qemu-ga.wxs
+++ b/qga/installer/qemu-ga.wxs
@@ -31,6 +31,7 @@
   />
 
 1
+
 
-- 
2.25.1




[PULL 0/5] QGA Misc patches

2023-03-08 Thread Konstantin Kostiuk
The following changes since commit 9832009d9dd2386664c15cc70f6e6bfe062be8bd:

  Merge tag 'pull-riscv-to-apply-20230306' of 
https://gitlab.com/palmer-dabbelt/qemu into staging (2023-03-07 12:53:00 +)

are available in the Git repository at:

  g...@github.com:kostyanf14/qemu.git tags/qga-pull-2023-03-08

for you to fetch changes up to 0961f929c66ceb5e9e95756bfe418b9ef34510eb:

  qga/win/vss: requester_freeze changes (2023-03-08 18:26:50 +0200)


qga-pull-2023-03-08


Kfir Manor (3):
  qga/win/installer: add VssOption to installer
  qga/win/vss: query VSS backup type
  qga/win/vss: requester_freeze changes

Konstantin Kostiuk (2):
  qga/win32: Remove change action from MSI installer
  qga/win32: Use rundll for VSS installation

 qga/installer/qemu-ga.wxs   | 15 ++-
 qga/vss-win32/install.cpp   |  9 +
 qga/vss-win32/qga-vss.def   |  2 ++
 qga/vss-win32/requester.cpp | 41 -
 qga/vss-win32/vss-handles.h |  3 +++
 5 files changed, 64 insertions(+), 6 deletions(-)


--
2.25.1




Re: [PATCH] target/riscv/csr.c: fix H extension TVM trap

2023-03-08 Thread Daniel Henrique Barboza




On 3/8/23 09:34, chenyi2...@zju.edu.cn wrote:

From: Yi Chen 

Trap accesses to hgatp if MSTATUS_TVM is enabled.
Don't trap accesses to vsatp even if MSTATUS_TVM is enabled.

Signed-off-by: Yi Chen 
---
  target/riscv/csr.c | 18 ++
  1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index ab56663..09bc780 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2655,7 +2655,7 @@ static RISCVException read_satp(CPURISCVState *env, int 
csrno,
  return RISCV_EXCP_NONE;
  }
  
-if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {

+if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) && 
get_field(env->mstatus, MSTATUS_TVM)) {


The commit message mentions 'vsatp' but this patch is changing satp callbacks.

Any reason to not change read_vsatp() and write_vsatp() instead?



  return RISCV_EXCP_ILLEGAL_INST;
  } else {
  *val = env->satp;
@@ -2683,7 +2683,7 @@ static RISCVException write_satp(CPURISCVState *env, int 
csrno,
  }
  
  if (vm && mask) {

-if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) && 
get_field(env->mstatus, MSTATUS_TVM)) {
  return RISCV_EXCP_ILLEGAL_INST;
  } else {
  /*
@@ -3047,14 +3047,24 @@ static RISCVException read_hgeip(CPURISCVState *env, 
int csrno,
  static RISCVException read_hgatp(CPURISCVState *env, int csrno,
   target_ulong *val)
  {
-*val = env->hgatp;
+if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+return RISCV_EXCP_ILLEGAL_INST;


The end of the first paragraph of ISA 8.2.10 goes as follows:


When mstatus.TVM=1, attempts to read or write hgatp while executing
in HS-mode will raise an illegal instruction exception.


I believe you need to check for HS-mode, not just PRV_S. riscv_csrrw_check() in
target/riscv/csr.c checks for HS-mode as follows:

if (riscv_has_ext(env, RVH) && env->priv == PRV_S &&
!riscv_cpu_virt_enabled(env)) {

Same goes for write_hgatp() below.


+} else {
+*val = env->hgatp;
+}
+


You can discard the 'else' since you're doing a return in the if:

if (...) {
return RISCV_EXCP_ILLEGAL_INST;
}

*val = env->hgatp;



  return RISCV_EXCP_NONE;
  }
  
  static RISCVException write_hgatp(CPURISCVState *env, int csrno,

target_ulong val)
  {
-env->hgatp = val;
+if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+return RISCV_EXCP_ILLEGAL_INST;
+} else {
+env->hgatp = val;
+}


No need for else here either:

if (...) {
return RISCV_EXCP_ILLEGAL_INST;
}

env->hgatp = val;



Thanks,


Daniel


+
  return RISCV_EXCP_NONE;
  }
  




RE: [PULL 00/17] Hexagon (target/hexagon) updates

2023-03-08 Thread Taylor Simpson
Just checking if this is on the radar to be merged ...


> -Original Message-
> From: Taylor Simpson 
> Sent: Monday, March 6, 2023 10:34 PM
> To: qemu-devel@nongnu.org
> Cc: Taylor Simpson ; richard.hender...@linaro.org;
> phi...@linaro.org; peter.mayd...@linaro.org; Brian Cain
> ; Matheus Bernardino (QUIC)
> ; stefa...@redhat.com; a...@rev.ng;
> a...@rev.ng
> Subject: [PULL 00/17] Hexagon (target/hexagon) updates
> 
> The following changes since commit
> f003dd8d81f7d88f4b1f8802309eaa76f6eb223a:
> 
>   Merge tag 'pull-tcg-20230305' of https://gitlab.com/rth7680/qemu into
> staging (2023-03-06 10:20:04 +)
> 
> are available in the Git repository at:
> 
>   https://github.com/quic/qemu tags/pull-hex-20230306
> 
> for you to fetch changes up to
> c2b33d0be998bf539953f1dad0aa0d1cc8d9d069:
> 
>   Hexagon (target/hexagon) Improve code gen for predicated HVX
> instructions (2023-03-06 20:47:12 -0800)
> 
> 
> Hexagon (target/hexagon) updates
> 
> 
> Anton Johansson (1):
>   target/hexagon/idef-parser: Remove unused code paths
> 
> Richard Henderson (1):
>   target/hexagon/idef-parser: Elide mov in gen_pred_assign
> 
> Taylor Simpson (15):
>   Hexagon (target/hexagon) Restore --disable-hexagon-idef-parser build
>   Hexagon (target/hexagon) Add overrides for jumpr31 instructions
>   Hexagon (target/hexagon) Add overrides for callr
>   Hexagon (target/hexagon) Add overrides for endloop1/endloop01
>   Hexagon (target/hexagon) Add overrides for dealloc-return instructions
>   Hexagon (target/hexagon) Analyze packet before generating TCG
>   Hexagon (target/hexagon) Don't set pkt_has_store_s1 when not needed
>   Hexagon (target/hexagon) Analyze packet for HVX
>   Hexagon (tests/tcg/hexagon) Update preg_alias.c
>   Hexagon (tests/tcg/hexagon) Remove __builtin from scatter_gather
>   Hexagon (tests/tcg/hexagon) Enable HVX tests
>   Hexagon (target/hexagon) Change subtract from zero to change sign
>   Hexagon (target/hexagon) Remove gen_log_predicated_reg_write[_pair]
>   Hexagon (target/hexagon) Reduce manipulation of slot_cancelled
>   Hexagon (target/hexagon) Improve code gen for predicated HVX
> instructions
> 
>  target/hexagon/cpu.h|   5 +-
>  target/hexagon/gen_tcg.h|  90 -
>  target/hexagon/gen_tcg_hvx.h|  17 +-
>  target/hexagon/idef-parser/idef-parser.h|   1 -
>  target/hexagon/macros.h |  29 +-
>  target/hexagon/op_helper.h  |   3 +-
>  target/hexagon/translate.h  |  86 +++--
>  target/hexagon/attribs_def.h.inc|   1 +
>  target/hexagon/genptr.c | 296 ++--
>  target/hexagon/idef-parser/parser-helpers.c |  19 +-
>  target/hexagon/op_helper.c  |  60 ++--
>  target/hexagon/translate.c  | 288 +---
>  tests/tcg/hexagon/fpstuff.c |  31 +-
>  tests/tcg/hexagon/preg_alias.c  |  10 +-
>  tests/tcg/hexagon/scatter_gather.c  | 513 +++
> -
>  target/hexagon/README   |  31 +-
>  target/hexagon/gen_analyze_funcs.py | 252 ++
>  target/hexagon/gen_helper_funcs.py  |  19 +-
>  target/hexagon/gen_helper_protos.py |  12 +-
>  target/hexagon/gen_tcg_funcs.py | 152 +++--
>  target/hexagon/hex_common.py|  10 +-
>  target/hexagon/idef-parser/idef-parser.lex  |  31 +-
>  target/hexagon/idef-parser/idef-parser.y|  49 +--
>  target/hexagon/idef-parser/macros.inc   |   9 -
>  target/hexagon/meson.build  |  11 +-
>  tests/tcg/hexagon/Makefile.target   |  13 +-
>  26 files changed, 1209 insertions(+), 829 deletions(-)  create mode 100755
> target/hexagon/gen_analyze_funcs.py


[PATCH 36/47] virtio-rng-pci: fix migration compat for vectors

2023-03-08 Thread Michael Tokarev
From: "Dr. David Alan Gilbert" 

Fixup the migration compatibility for existing machine types
so that they do not enable msi-x.

Symptom:

(qemu) qemu: get_pci_config_device: Bad config data: i=0x34 read: 84 device: 98 
cmask: ff wmask: 0 w1cmask:0
qemu: Failed to load PCIDevice:config
qemu: Failed to load virtio-rng:virtio
qemu: error while loading state for instance 0x0 of device 
':00:03.0/virtio-rng'
qemu: load of migration failed: Invalid argument

Note: This fix will break migration from 7.2->7.2-fixed with this patch

bz: https://bugzilla.redhat.com/show_bug.cgi?id=2155749
Fixes: 9ea02e8f1 ("virtio-rng-pci: Allow setting nvectors, so we can use MSI-X")

Signed-off-by: Dr. David Alan Gilbert 
Message-Id: <20230109105809.163975-1-dgilb...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Reviewed-by: Thomas Huth 
Acked-by: David Daney 
Fixes: 9ea02e8f1 ("virtio-rng-pci: Allow setting nvectors, so we can use MSI-X")
Signed-off-by: Dr. David Alan Gilbert 
Reviewed-by: Philippe Mathieu-Daudé 
(cherry picked from commit bad9c5a5166fd5e3a892b7b0477cf2f4bd3a959a)
Signed-off-by: Michael Tokarev 
---
 hw/core/machine.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 8d34caa31d..77a0a131d1 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -42,6 +42,7 @@
 
 GlobalProperty hw_compat_7_1[] = {
 { "virtio-device", "queue_reset", "false" },
+{ "virtio-rng-pci", "vectors", "0" },
 };
 const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1);
 
-- 
2.30.2




Re: [PATCH v2 2/3] tests/avocado: Add Fedora 34 distro, including kernel/initrd checksums

2023-03-08 Thread David Woodhouse
On Wed, 2023-03-08 at 17:42 +, Alex Bennée wrote:
> 
> David Woodhouse  writes:
> 
> > From: David Woodhouse 
> > 
> > The kernel in Fedora 31 doesn't support 'xen_no_vector_callback' on
> > its command line, so add a slightly newer version as a prelude to
> > enabling avocado tests for Xen guests.
> 
> Why slightly newer rather than current release?
> 
> Our existing Fedora guest builds cause all sorts of timeout issues
> running under TCG and seem particularly heavyweight considering the
> coverage we manage to get.

Yeah, I spent a happy afternoon playing with this; I think you may have
observed some of it on IRC. Although I kept some of the naughtier words
to my side of the keyboard. From memory...

I tried Fedora 37 and eventually got that to *boot* (hint:
rootflags=subvol=root) although it concerned me that it wasn't yet at
the URL containing /archive/ so I wondered if adding it at its current
URL might not work in the long term. And then cloudinit didn't seem to
work on it (the finalize step failed in the guest IIRC).

I tried Fedora 36 and cloudinit *did* work there, and it was in
basically the same /pub/archive/fedora/ location so all that made me
happier... but 'dnf install xen-runtime' didn't work, which I was using
in my tests at that point to install the `xenstore-ls` binary. And in
fact dnf didn't seem to find *anything* useful at all in the
repositories which were configured in the Fedora Cloud 36 image.

So I tried Fedora 34, which is the first to have the
'xen_no_vector_callback' option that I'd added in the 5.12 kernel.
And when that worked, I declared all the above to be "Someone Else's
Problem".

The fact that it didn't boot with `-smp 4` was clearly *my* problem,
but the code was already merged upstream at that point, so fixing what
turned out to be the I/OAPIC migration bug ended up being my top
priority. 

Now, I've dropped the dnf invocation because now the second PR has 
been submitted I've switched it to use xen-disk anyway, and that's a
good enough exercise for both xenstore and event channel interrupts.

So it probably *could* move to Fedora 36, and the fact that the intel-
iommu test wouldn't work on Fedora 36 could remain Someone Else's
Problem. :)

Please advise.


smime.p7s
Description: S/MIME cryptographic signature


Re: [PATCH v2 3/3] tests/avocado: Test Xen guest support under KVM

2023-03-08 Thread David Woodhouse
On Wed, 2023-03-08 at 17:45 +, Alex Bennée wrote:
> 
> David Woodhouse  writes:
> 
> > From: David Woodhouse 
> > 
> > Exercise guests with a few different modes for interrupt delivery. In
> > particular we want to cover:
> > 
> >  • Xen event channel delivery via GSI to the I/O APIC
> >  • Xen event channel delivery via GSI to the i8259 PIC
> >  • MSIs routed to PIRQ event channels
> >  • GSIs routed to PIRQ event channels
> > 
> > As well as some variants of normal non-Xen stuff like MSI to vAPIC and
> > PCI INTx going to the I/O APIC and PIC, which ought to still work even
> > in Xen mode.
> > 
> > Signed-off-by: David Woodhouse 
> > ---
> >  tests/avocado/xen_guest.py | 147 +
> >  1 file changed, 147 insertions(+)
> >  create mode 100644 tests/avocado/xen_guest.py
> > 
> > diff --git a/tests/avocado/xen_guest.py b/tests/avocado/xen_guest.py
> > new file mode 100644
> > index 00..c50b52958f
> > --- /dev/null
> > +++ b/tests/avocado/xen_guest.py
> > @@ -0,0 +1,147 @@
> > +# Xen guest functional tests
> > +#
> 
> Perhaps to avoid confusion we should call the file kvm_xen_guests.py and
> make it clearer in the comment this is the mode we are talking about.
> c.f. the boot_xen.py tests which boot Xen (under TCG emulation) as a
> proper hypervisor.

Ack. I'll change it.

> > +# Copyright © 2021 Red Hat, Inc.
> > +# Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
> > +#
> > +# Author:
> > +#  David Woodhouse 
> > +#
> > +# This work is licensed under the terms of the GNU GPL, version 2 or
> > +# later.  See the COPYING file in the top-level directory.
> > +import os
> > +
> > +from avocado import skipIf
> > +from avocado_qemu import LinuxTest
> > +
> > +@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
> 
> This just means we will never have CI coverage. In theory when running
> on the GitLab shared runners the test should skip anyway when it can't
> find /dev/kvm and hopefully can run on our custom runners when it can
> see /dev/kvm.
> 

That one was just cargo-culted from the Intel IOMMU test which I
started from. Happy to drop that if it's redundant.




smime.p7s
Description: S/MIME cryptographic signature


Re: [PULL 14/20] hw/ppc/pegasos2: Fix PCI interrupt routing

2023-03-08 Thread BALATON Zoltan

On Wed, 8 Mar 2023, BALATON Zoltan wrote:

On Wed, 8 Mar 2023, Philippe Mathieu-Daudé wrote:

Hi Zoltan,

On 8/3/23 00:47, Philippe Mathieu-Daudé wrote:

From: BALATON Zoltan 

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.


IIUC the schematic, only tje INTA and INTB lines (AGP IRQs) are
bidirectional and shared between NB/SB.

INTC and INTC are SB output to NB input.


I'll check the schematics again when I have time later but what we know for 
sure is that guests expect PCI interrupts to raise ISA IRQ9 which is mapped 
by the VT8231 ISA function 0c55-0x57 registers. The PCI buses are otherwise 
handled by the north bridge. So how can the VIA PINT pins be outputs? Where 
do the signals from the PCI cards go into VT8231 otherwise? Also the VT8231 
datasheet on page 10 says PINTA-D pins are inputs so I can't understand your 
reasoning above.


I think this may be an error in some schematic pages or nore likely 
something we don't undestand about the drawing as both Sheet 2 with 
MV64361 and Sheet 18 with VT8231 show the interrupts as inputs (which also 
matches the VT8231 datasheet). Other sheets with individual PCI slots show 
these interrupt lines as outputs as expected. Only sheet 13 shows INTA and 
B as bidirectional and INTC and D as output but maybe only because that 
sheet also shows the PCI slots from which the lines are output and the 
VT8231 in which they are inputs so together for this sheet they are both 
input and output but for the chips they are input only and for the slots 
they are output only. The main sheet also has these directions maybe 
because it shows links to the sheet that has the slots from where the IRQs 
are coming and also links to the AGP port where only INTA and B are 
connected so for these they are inputs for sheet 13. So this shows that 
AGP interrupts are also inputs to Sheet 13 whereas other PCI INTC and D 
are only outputs from this sheet because they are routed to the VT8231 
sheet within sheet 13 so at higher level they don't appear as both the 
outputs and inputs of INTC and D are on Sheet 13.


So I think what we have here is correct and matches the schematics where 
PCI interrupts come from slots, they are connected to VT8231 on Sheet 13 
but INTA and B can also come from AGP which is on sheet 4 so these are 
also input to sheet 13, finally all of these are output towards sheet 2 
with MV64361 that's why the top level sheet has confusing bidirectional 
arrows but if you look at the chips the lines are input there and output 
at the slots which is only what makes sense anyway.


What is it that bothers you and Mark about this that you both want to 
change it to something else and what makes you think this can't be right?


Regards,
BALATON Zoltan


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

Signed-off-by: BALATON Zoltan 
Reviewed-by: Daniel Henrique Barboza 
Tested-by: Rene Engel 
Message-Id: 
<520ff9e6eeef600ee14a4116c0c7b11940cc499c.1678188711.git.bala...@eik.bme.hu>

Signed-off-by: Philippe Mathieu-Daudé 
---
  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 298564f1f5..19e8031a3f 100644
--- a/hw/pci-host/mv64361.c
+++ b/hw/pci-host/mv64361.c
@@ -873,10 +873,6 @@ static void mv64361_realize(DeviceState *dev, Error 
**errp)

  }
  sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->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 7cc375df05..f1650be5ee 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -73,6 +73,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;
@@ -95,6 +97,15 @@ static void pegasos2_cpu_reset(void *opaque)
  }
  }
  +static void pegasos2_pci_irq(void *opaque, int n, int level

Re: [PATCH v2 8/9] async: update documentation of the memory barriers

2023-03-08 Thread Richard Henderson

On 3/8/23 10:08, Paolo Bonzini wrote:

On 3/8/23 17:47, Richard Henderson wrote:

The case that I was imagining for smp_mb__before_rmw() is something like this:

 wake_me = true;
 smp_mb__before_rmw();
 if (qatomic_xchg(&can_sleep, true)) { ... }

where you really need a full barrier.


What is different about this that doesn't apply to the remove-head case we've been 
talking about?


For remove-head, nothing is going to change the BH_PENDING flag while the code runs.  This 
would be an okay transformation of the code, at both the compiler and the processor level:


   // first part of atomic_fetch_and
   old_flags = LDAXR of bh->flags

   // QSLIST_REMOVE_HEAD ends up between load and store of
   // atomic_fetch_and
   all the loads and stores for remove-head

   // second part of atomic_fetch_and
   new_flags = old_flags & ~(BH_PENDING|BH_SCHEDULED|BH_IDLE);
   (successful) STLXR of new_flags into bh->flags


Instead in the case above, I was thinking you would get a missed wakeup without the 
barriers.  Here is the full pseudocode:


   // this store can move below the load of can_sleep
   qatomic_set(&wake_me, true);
   if (qatomic_xchg(&can_sleep, true)) sleep;

   // this store can move below the load of wake_me
   qatomic_set(&can_sleep, false);
   if (qatomic_xchg(&wake_me, false)) wake them;

The buggy case is where the threads observe can_sleep = true, wake_me = false, i.e. the 
original value of the variables.


Oh, I see, buggy in a larger context.

Reviewed-by: Richard Henderson 


r~



Re: [PATCH] Fix build without CONFIG_XEN_EMU

2023-03-08 Thread Woodhouse, David
On Wed, 2023-03-08 at 08:05 -0500, mreza...@redhat.com wrote:
> From: Miroslav Rezanina 
> 
> Upstream commit ddf0fd9ae1 "hw/xen: Support HVM_PARAM_CALLBACK_TYPE_GSI 
> callback"
> added kvm_xen_maybe_deassert_callback usage to target/i386/kvm/kvm.c file 
> without
> conditional preprocessing check. This breaks any build not using 
> CONFIG_XEN_EMU.
> 
> Protect call by conditional preprocessing to allow build without 
> CONFIG_XEN_EMU.
> 
> Signed-off-by: Miroslav Rezanina 

Reviewed-by: David Woodhouse 

I'll add a build target with that config locally to keep me honest.



smime.p7s
Description: S/MIME cryptographic signature



Amazon Development Centre (London) Ltd. Registered in England and Wales with 
registration number 04543232 with its registered office at 1 Principal Place, 
Worship Street, London EC2A 2FA, United Kingdom.




Re: [PATCH v2 8/9] async: update documentation of the memory barriers

2023-03-08 Thread Paolo Bonzini

On 3/8/23 17:47, Richard Henderson wrote:
The case that I was imagining for smp_mb__before_rmw() is something 
like this:


 wake_me = true;
 smp_mb__before_rmw();
 if (qatomic_xchg(&can_sleep, true)) { ... }

where you really need a full barrier.


What is different about this that doesn't apply to the remove-head case 
we've been talking about?


For remove-head, nothing is going to change the BH_PENDING flag while 
the code runs.  This would be an okay transformation of the code, at 
both the compiler and the processor level:


  // first part of atomic_fetch_and
  old_flags = LDAXR of bh->flags

  // QSLIST_REMOVE_HEAD ends up between load and store of
  // atomic_fetch_and
  all the loads and stores for remove-head

  // second part of atomic_fetch_and
  new_flags = old_flags & ~(BH_PENDING|BH_SCHEDULED|BH_IDLE);
  (successful) STLXR of new_flags into bh->flags


Instead in the case above, I was thinking you would get a missed wakeup 
without the barriers.  Here is the full pseudocode:


  // this store can move below the load of can_sleep
  qatomic_set(&wake_me, true);
  if (qatomic_xchg(&can_sleep, true)) sleep;

  // this store can move below the load of wake_me
  qatomic_set(&can_sleep, false);
  if (qatomic_xchg(&wake_me, false)) wake them;

The buggy case is where the threads observe can_sleep = true, wake_me = 
false, i.e. the original value of the variables.  Let's look at it with 
CPPMEM.


Like before, the CPPMEM test must use CAS and .readsvalue() to hack 
around the lack of "if"s.  Two .readsvalue() clauses represent the buggy 
case, so we are all good if there is *no* consistent executions.


Unfortunately, it fails:

  // 2 consistent (i.e. buggy) executions
  int main() {
atomic_int w = 0;
atomic_int s = 1;
{{{
  { w.store(1, mo_relaxed);
// the buggy case is the one in which the threads read the
// original value of w and s.  So here the CAS writes a
// dummy value different from both 0 and 1
cas_strong_explicit(&s, 0, 99, mo_seq_cst, mo_seq_cst);
s.load(mo_relaxed).readsvalue(1); }
|||
  { s.store(0, mo_relaxed);
// same as above
cas_strong_explicit(&w, 1, 99, mo_seq_cst, mo_seq_cst);
w.load(mo_relaxed).readsvalue(0); }
}}}
  }

It works with barriers, which models the extra smp_mb__before_rmw():

  // no consistent executions (i.e. it works)
  int main() {
atomic_int w = 0;
atomic_int s = 1;
{{{
  { w.store(1, mo_relaxed);
atomic_thread_fence(mo_seq_cst);
cas_strong_explicit(&s, 0, 99, mo_relaxed, mo_relaxed);
s.load(mo_relaxed).readsvalue(1); }
|||
  { s.store(0, mo_relaxed);
atomic_thread_fence(mo_seq_cst);
cas_strong_explicit(&w, 1, 99, mo_relaxed, mo_relaxed);
w.load(mo_relaxed).readsvalue(0); }
}}}
  }

I think I agree with you that _in practice_ it's going to work at the 
processor level; the pseudo-assembly would be


  r1 = LDAXR(can_sleep);
   r2 = LDAXR(wake_me);
   STR(can_sleep, false);
   STLXR(wake_me, false); // successful
  STR(wake_me, true);
  STLXR(can_sleep, true); // successful (?)
  if r1 == 0 { ... }
   if r2 != 0 { ... }

and I can't think of a way in which both store-exclusives (or xchg, or 
cmpxchg) would succeed.  So perhaps smp_mb__before_rmw() could indeed be 
a signal_fence().  But that's quite scary even for the standards of this 
discussion...


Paolo




Re: Deadlock with ide_issue_trim and draining

2023-03-08 Thread Hanna Czenczek

On 07.03.23 14:44, Hanna Czenczek wrote:

On 07.03.23 13:22, Fiona Ebner wrote:

Hi,
I am suspecting that commit 7e5cdb345f ("ide: Increment BB in-flight
counter for TRIM BH") introduced an issue in combination with draining.

 From a debug session on a costumer's machine I gathered the following
information:
* The QEMU process hangs in aio_poll called during draining and doesn't
progress.
* The in_flight counter for the BlockDriverState is 0 and for the
BlockBackend it is 1.
* There is a blk_aio_pdiscard_entry request in the BlockBackend's
queued_requests.
* The drive is attached via ahci.

I suspect that something like the following happened:

1. ide_issue_trim is called, and increments the in_flight counter.
2. ide_issue_trim_cb calls blk_aio_pdiscard.
3. somebody else starts draining.
4. ide_issue_trim_cb is called as the completion callback for
blk_aio_pdiscard.
5. ide_issue_trim_cb issues yet another blk_aio_pdiscard request.
6. The request is added to the wait queue via blk_wait_while_drained,
because draining has been started.
7. Nobody ever decrements the in_flight counter and draining can't 
finish.


Sounds about right.


The issue occurs very rarely and is difficult to reproduce, but with the
help of GDB, I'm able to do it rather reliably:
1. Use GDB to break on blk_aio_pdiscard.
2. Run mkfs.ext4 on a huge disk in the guest.
3. Issue a drive-backup QMP command after landing on the breakpoint.
4. Continue a few times in GDB.
5. After that I can observe the same situation as described above.

I'd be happy about suggestions for how to fix it. Unfortunately, I don't
see a clear-cut way at the moment. The only idea I have right now is to
change the code to issue all discard requests at the same time, but I
fear there might pitfalls with that?


The point of 7e5cdb345f was that we need any in-flight count to 
accompany a set s->bus->dma->aiocb.  While blk_aio_pdiscard() is 
happening, we don’t necessarily need another count.  But we do need it 
while there is no blk_aio_pdiscard().


ide_issue_trim_cb() returns in two cases (and, recursively through its 
callers, leaves s->bus->dma->aiocb set):

1. After calling blk_aio_pdiscard(), which will keep an in-flight count,
2. After calling replay_bh_schedule_event() (i.e. qemu_bh_schedule()), 
which does not keep an in-flight count.


Perhaps we just need to move the blk_inc_in_flight() above the 
replay_bh_schedule_event() call?


While writing the commit message for this, I noticed it isn’t quite 
right: ide_cancel_dma_sync() drains s->blk only once, so once the 
in-flight counter goes to 0, s->blk is considered drained and 
ide_cancel_dma_sync() will go on to assert that s->bus->dma->aiocb is 
now NULL.  However, if we do have a blk_aio_pdiscard() in flight, the 
drain will wait only for that one to complete, not for the whole trim 
operation to complete, i.e. the next discard or ide_trim_bh_cb() will be 
scheduled, but neither will necessarily be run before blk_drain() returns.


I’ve attached a reproducer that issues two trim requests.  Before 
7e5cdb345f, it makes qemu crash because the assertion fails (one or two 
of the blk_aio_pdiscard()s is drained, but the trim isn’t settled yet).  
After 7e5cdb345f, qemu hangs because of what you describe (the second 
blk_aio_pdiscard() is enqueued, so the drain can’t make progress, 
resulting in a deadlock).  With my proposed fix, qemu crashes again.


(Reproducer is run like this:
$ qemu-system-x86_64 -drive if=ide,file=/tmp/test.bin,format=raw
)

What comes to my mind is either what you’ve proposed initially (issuing 
all discards simultaneously), or to still use my proposed fix, but also 
have ide_cancel_dma_sync() run blk_drain() in a loop until 
s->bus->dma->aiocb becomes NULL.  (Kind of like my original patch 
(https://lists.nongnu.org/archive/html/qemu-block/2022-01/msg00024.html), 
only that we can still use blk_drain() instead of aio_poll() because we 
increment the in-flight counter while the completion BH is scheduled.)


Hanna

test.bin
Description: Binary data
format binary
use16

org 0x7c00

DMA_BUF = 0x7e00

cld

xor ax, ax
mov ds, ax
mov es, ax

; clear DMA buffer
mov di, DMA_BUF
xor ax, ax
mov cx, 256
repnz stosw

; two TRIM requests (both are the same: one sector, starting at sector index 1)
mov di, DMA_BUF
mov dword [di+ 0], 0x0001
mov dword [di+ 4], 0x0001
mov dword [di+ 8], 0x0001
mov dword [di+12], 0x0001

; find IDE PCI device
mov ax, 0xb102
mov dx, 0x8086
mov cx, 0x7010
xor si, si
int 0x1a

; bx has PCI address
pushbx

; enable BM+MEM+IO

mov di, 0x04 ; command/status
mov ax, 0xb10a ; read config dword
int 0x1a

pop bx
pushbx

or  cl, 0x7 ; BM+MEM+IO
mov di, 0x04
mov ax, 0xb10d ; write config dword
int 0x1a

pop bx
pushbx

; read BAR4 (DMA I/O space)

mov di, 0x20 ; bar4
mov ax, 0xb10a
int 0x1a

and cx, 0xfffc ; DMA I/O base
pushcx

mov

Re: [PATCH v2 3/3] tests/avocado: Test Xen guest support under KVM

2023-03-08 Thread Alex Bennée


David Woodhouse  writes:

> From: David Woodhouse 
>
> Exercise guests with a few different modes for interrupt delivery. In
> particular we want to cover:
>
>  • Xen event channel delivery via GSI to the I/O APIC
>  • Xen event channel delivery via GSI to the i8259 PIC
>  • MSIs routed to PIRQ event channels
>  • GSIs routed to PIRQ event channels
>
> As well as some variants of normal non-Xen stuff like MSI to vAPIC and
> PCI INTx going to the I/O APIC and PIC, which ought to still work even
> in Xen mode.
>
> Signed-off-by: David Woodhouse 
> ---
>  tests/avocado/xen_guest.py | 147 +
>  1 file changed, 147 insertions(+)
>  create mode 100644 tests/avocado/xen_guest.py
>
> diff --git a/tests/avocado/xen_guest.py b/tests/avocado/xen_guest.py
> new file mode 100644
> index 00..c50b52958f
> --- /dev/null
> +++ b/tests/avocado/xen_guest.py
> @@ -0,0 +1,147 @@
> +# Xen guest functional tests
> +#

Perhaps to avoid confusion we should call the file kvm_xen_guests.py and
make it clearer in the comment this is the mode we are talking about.
c.f. the boot_xen.py tests which boot Xen (under TCG emulation) as a
proper hypervisor.

> +# Copyright © 2021 Red Hat, Inc.
> +# Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
> +#
> +# Author:
> +#  David Woodhouse 
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2 or
> +# later.  See the COPYING file in the top-level directory.
> +import os
> +
> +from avocado import skipIf
> +from avocado_qemu import LinuxTest
> +
> +@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')

This just means we will never have CI coverage. In theory when running
on the GitLab shared runners the test should skip anyway when it can't
find /dev/kvm and hopefully can run on our custom runners when it can
see /dev/kvm.

> +class XenGuest(LinuxTest):
> +"""
> +:avocado: tags=arch:x86_64
> +:avocado: tags=distro:fedora
> +:avocado: tags=distro_version:34
> +:avocado: tags=machine:q35
> +:avocado: tags=accel:kvm
> +:avocado: tags=xen_guest
> +"""
> +
> +kernel_path = None
> +initrd_path = None
> +kernel_params = None
> +
> +def set_up_boot(self):
> +path = self.download_boot()
> +self.vm.add_args('-drive', 'file=%s,if=none,id=drv0' % path)
> +self.vm.add_args('-device', 'xen-disk,drive=drv0,vdev=xvda')
> +
> +def setUp(self):
> +super(XenGuest, self).setUp(None, 'virtio-net-pci')
> +
> +def common_vm_setup(self, custom_kernel=None):
> +self.require_accelerator("kvm")
> +self.vm.add_args("-accel", 
> "kvm,xen-version=0x4000a,kernel-irqchip=split")
> +self.vm.add_args("-smp", "4")
> +
> +if custom_kernel is None:
> +return
> +
> +kernel_url = self.distro.pxeboot_url + 'vmlinuz'
> +initrd_url = self.distro.pxeboot_url + 'initrd.img'
> +self.kernel_path = self.fetch_asset(kernel_url, algorithm='sha256',
> +
> asset_hash=self.distro.kernel_hash)
> +self.initrd_path = self.fetch_asset(initrd_url, algorithm='sha256',
> +
> asset_hash=self.distro.initrd_hash)
> +
> +def run_and_check(self):
> +if self.kernel_path:
> +self.vm.add_args('-kernel', self.kernel_path,
> + '-append', self.kernel_params,
> + '-initrd', self.initrd_path)
> +self.launch_and_wait()
> +self.ssh_command('cat /proc/cmdline')
> +self.ssh_command('dmesg | grep -e "Grant table initialized"')
> +
> +def test_xen_guest(self):
> +"""
> +:avocado: tags=xen_guest
> +"""
> +
> +self.common_vm_setup(True)
> +
> +self.kernel_params = (self.distro.default_kernel_params +
> +  ' xen_emul_unplug=ide-disks')
> +self.run_and_check()
> +self.ssh_command('grep xen-pirq.*msi /proc/interrupts')
> +
> +def test_xen_guest_nomsi(self):
> +"""
> +:avocado: tags=xen_guest_nomsi
> +"""
> +
> +self.common_vm_setup(True)
> +
> +self.kernel_params = (self.distro.default_kernel_params +
> +  ' xen_emul_unplug=ide-disks pci=nomsi')
> +self.run_and_check()
> +self.ssh_command('grep xen-pirq.* /proc/interrupts')
> +
> +def test_xen_guest_noapic_nomsi(self):
> +"""
> +:avocado: tags=xen_guest_noapic_nomsi
> +"""
> +
> +self.common_vm_setup(True)
> +
> +self.kernel_params = (self.distro.default_kernel_params +
> +  ' xen_emul_unplug=ide-disks noapic pci=nomsi')
> +self.run_and_check()
> +self.ssh_command('grep xen-pirq /proc/interrupts')
> +
> +def test_xen_guest_vapic(self):
> +"""
> +:avocado: tags=xen_guest_vapic
> +"""
> +
> +self.c

Re: [PATCH v2 2/3] tests/avocado: Add Fedora 34 distro, including kernel/initrd checksums

2023-03-08 Thread Alex Bennée


David Woodhouse  writes:

> From: David Woodhouse 
>
> The kernel in Fedora 31 doesn't support 'xen_no_vector_callback' on
> its command line, so add a slightly newer version as a prelude to
> enabling avocado tests for Xen guests.

Why slightly newer rather than current release?

Our existing Fedora guest builds cause all sorts of timeout issues
running under TCG and seem particularly heavyweight considering the
coverage we manage to get.

>
> Signed-off-by: David Woodhouse 
> ---
>  tests/avocado/avocado_qemu/__init__.py | 27 ++
>  1 file changed, 27 insertions(+)
>
> diff --git a/tests/avocado/avocado_qemu/__init__.py 
> b/tests/avocado/avocado_qemu/__init__.py
> index a313e88c07..49e414e267 100644
> --- a/tests/avocado/avocado_qemu/__init__.py
> +++ b/tests/avocado/avocado_qemu/__init__.py
> @@ -485,6 +485,23 @@ class LinuxDistro:
>' console=tty0'),
>   },
>  },
> +'34': {
> +'x86_64':
> +{'checksum': ('b9b621b26725ba95442d9a56cbaa0547'
> +  '84e0779a9522ec6eafff07c6e6f717ea'),
> + 'pxeboot_url': ('https://archives.fedoraproject.org/'
> + 'pub/archive/fedora/linux/releases/34/'
> + 'Everything/x86_64/os/images/pxeboot/'),
> + 'kernel_hash': ('085fc6e47f2e3a271b591f3e56739ca9'
> + '4c16718837a5f431ab95468e1e95f9eb'),
> + 'initrd_hash': ('d6cd2e03e8188eed6c896fd65ff05f81'
> + '2c4c1c8777d630b5909e9a1a4627e337'),
> + 'kernel_params': ('root=UUID=386769a3-cfa5-47c8-8797-'
> +   'd5ec58c9cb6c ro no_timer_check '
> +   'net.ifnames=0 console=tty1 '
> +   'console=ttyS0,115200n8'),
> +},
> +},
>  }
>  }
>  
> @@ -513,6 +530,16 @@ def pxeboot_url(self):
>  """Gets the repository url where pxeboot files can be found"""
>  return self._info.get('pxeboot_url', None)
>  
> +@property
> +def kernel_hash(self):
> +"""Gets checksum of the pxeboot kernel image"""
> +return self._info.get('kernel_hash', None)
> +
> +@property
> +def initrd_hash(self):
> +"""Gets checksum of the pxeboot initrd image"""
> +return self._info.get('initrd_hash', None)
> +
>  @property
>  def default_kernel_params(self):
>  """Gets the default kernel parameters"""


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH 1/6] block: don't acquire AioContext lock in bdrv_drain_all()

2023-03-08 Thread Kevin Wolf
Am 08.03.2023 um 15:26 hat Stefan Hajnoczi geschrieben:
> On Wed, Mar 08, 2023 at 09:48:17AM +0100, Kevin Wolf wrote:
> > Am 07.03.2023 um 20:20 hat Stefan Hajnoczi geschrieben:
> > > On Tue, Mar 07, 2023 at 06:17:22PM +0100, Kevin Wolf wrote:
> > > > Am 01.03.2023 um 21:57 hat Stefan Hajnoczi geschrieben:
> > > > > There is no need for the AioContext lock in bdrv_drain_all() because
> > > > > nothing in AIO_WAIT_WHILE() needs the lock and the condition is 
> > > > > atomic.
> > > > > 
> > > > > Note that the NULL AioContext argument to AIO_WAIT_WHILE() is odd. In
> > > > > the future it can be removed.
> > > > 
> > > > It can be removed for all callers that run in the main loop context. For
> > > > code running in an iothread, it's still important to pass a non-NULL
> > > > context. This makes me doubt that the ctx parameter can really be
> > > > removed without changing more.
> > > > 
> > > > Is your plan to remove the if from AIO_WAIT_WHILE_INTERNAL(), too, and
> > > > to poll qemu_get_current_aio_context() instead of ctx_ or the main
> > > > context?
> > > 
> > > This is what I'd like once everything has been converted to
> > > AIO_WAIT_WHILE_UNLOCKED() - and at this point we might as well call it
> > > AIO_WAIT_WHILE() again:
> > > 
> > >   #define AIO_WAIT_WHILE(cond) ({\
> > >   bool waited_ = false;  \
> > >   AioWait *wait_ = &global_aio_wait; \
> > >   /* Increment wait_->num_waiters before evaluating cond. */ \
> > >   qatomic_inc(&wait_->num_waiters);  \
> > >   /* Paired with smp_mb in aio_wait_kick(). */   \
> > >   smp_mb();  \
> > >   while ((cond)) {   \
> > >   aio_poll(qemu_get_current_aio_context(), true);\
> > >   waited_ = true;\
> > >   }  \
> > >   qatomic_dec(&wait_->num_waiters);  \
> > >   waited_; })
> > 
> > Ok, yes, this is what I tried to describe above.
> > 
> > > However, I just realized this only works in the main loop thread because
> > > that's where aio_wait_kick() notifications are received. An IOThread
> > > running AIO_WAIT_WHILE() won't be woken when another thread (including
> > > the main loop thread) calls aio_wait_kick().
> > 
> > Which is of course a limitation we already have today. You can wait for
> > things in your own iothread, or for all threads from the main loop.
> > 
> > However, in the future multiqueue world, the first case probably becomes
> > pretty much useless because even for the same node, you could get
> > activity in any thread.
> > 
> > So essentially AIO_WAIT_WHILE() becomes GLOBAL_STATE_CODE(). Which is
> > probably a good idea anyway, but I'm not entirely sure how many places
> > we currently have where it's called from an iothread. I know the drain
> > in mirror_run(), but Emanuele already had a patch in his queue where
> > bdrv_co_yield_to_drain() schedules drain in the main context, so if that
> > works, mirror_run() would be solved.
> > 
> > https://gitlab.com/eesposit/qemu/-/commit/63562351aca4fb05d5711eb410feb96e64b5d4ad
> > 
> > > I would propose introducing a QemuCond for each condition that we wait
> > > on, but QemuCond lacks event loop integration. The current thread would
> > > be unable to run aio_poll() while also waiting on a QemuCond.
> > > 
> > > Life outside coroutines is hard, man! I need to think about this more.
> > > Luckily this problem doesn't block this patch series.
> > 
> > I hope that we don't really need all of this if we can limit running
> > synchronous code to the main loop.
> 
> Great idea, I think you're right.
> 
> I'll audit the code to find the IOThread AIO_WAIT_WHILE() callers and
> maybe a future patch series can work on that.
> 
> > > > > There is an assertion in
> > > > > AIO_WAIT_WHILE() that checks that we're in the main loop AioContext 
> > > > > and
> > > > > we would lose that check by dropping the argument. However, that was a
> > > > > precursor to the GLOBAL_STATE_CODE()/IO_CODE() macros and is now a
> > > > > duplicate check. So I think we won't lose much by dropping it, but 
> > > > > let's
> > > > > do a few more AIO_WAIT_WHILE_UNLOCKED() coversions of this sort to
> > > > > confirm this is the case.
> > > > > 
> > > > > Signed-off-by: Stefan Hajnoczi 
> > > > 
> > > > Yes, it seems that we don't lose much, except maybe some consistency in
> > > > the intermediate state. The commit message could state a bit more
> > > > directly what we gain, though. Since you mention removing the parameter
> > > > as a future possibility, I assume that's the goal with it, but I
> > > > wouldn't be sure just from reading the commit message.
> > > 
> > > AIO_WAIT_WH

Re: [PATCH v2 02/25] target/arm: Handle FPROUNDING_ODD in arm_rmode_to_sf

2023-03-08 Thread Philippe Mathieu-Daudé

On 7/3/23 19:34, Richard Henderson wrote:

While this enumerator has been present since the first commit,
it isn't ever used.  The first actual use of round-to-odd came
with SVE, which currently uses float_round_to_odd instead of
the arm-specific enumerator.

Amusingly, the comment about unhandled TIEAWAY has been
out of date since the initial commit of translate-a64.c.

Signed-off-by: Richard Henderson 
---
Cc: qemu-...@nongnu.org
---
  target/arm/vfp_helper.c | 6 ++
  1 file changed, 2 insertions(+), 4 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH v5 1/4] linux-aio: use LinuxAioState from the running thread

2023-03-08 Thread Stefan Hajnoczi
On Wed, Mar 08, 2023 at 12:42:11PM +0100, Kevin Wolf wrote:
> Am 07.03.2023 um 15:18 hat Stefan Hajnoczi geschrieben:
> > On Tue, Mar 07, 2023 at 09:48:51AM +0100, Kevin Wolf wrote:
> > > Am 01.03.2023 um 17:16 hat Stefan Hajnoczi geschrieben:
> > > > On Fri, Feb 03, 2023 at 08:17:28AM -0500, Emanuele Giuseppe Esposito 
> > > > wrote:
> > > > > Remove usage of aio_context_acquire by always submitting asynchronous
> > > > > AIO to the current thread's LinuxAioState.
> > > > > 
> > > > > In order to prevent mistakes from the caller side, avoid passing 
> > > > > LinuxAioState
> > > > > in laio_io_{plug/unplug} and laio_co_submit, and document the 
> > > > > functions
> > > > > to make clear that they work in the current thread's AioContext.
> > > > > 
> > > > > Signed-off-by: Emanuele Giuseppe Esposito 
> > > > > ---
> > > > >  include/block/aio.h   |  4 
> > > > >  include/block/raw-aio.h   | 18 --
> > > > >  include/sysemu/block-backend-io.h |  6 ++
> > > > >  block/file-posix.c| 10 +++---
> > > > >  block/linux-aio.c | 29 +
> > > > >  5 files changed, 38 insertions(+), 29 deletions(-)
> > > > > 
> > > > > diff --git a/include/block/aio.h b/include/block/aio.h
> > > > > index 8fba6a3584..b6b396cfcb 100644
> > > > > --- a/include/block/aio.h
> > > > > +++ b/include/block/aio.h
> > > > > @@ -208,10 +208,6 @@ struct AioContext {
> > > > >  struct ThreadPool *thread_pool;
> > > > >  
> > > > >  #ifdef CONFIG_LINUX_AIO
> > > > > -/*
> > > > > - * State for native Linux AIO.  Uses aio_context_acquire/release 
> > > > > for
> > > > > - * locking.
> > > > > - */
> > > > >  struct LinuxAioState *linux_aio;
> > > > >  #endif
> > > > >  #ifdef CONFIG_LINUX_IO_URING
> > > > > diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h
> > > > > index f8cda9df91..db614472e6 100644
> > > > > --- a/include/block/raw-aio.h
> > > > > +++ b/include/block/raw-aio.h
> > > > > @@ -49,14 +49,20 @@
> > > > >  typedef struct LinuxAioState LinuxAioState;
> > > > >  LinuxAioState *laio_init(Error **errp);
> > > > >  void laio_cleanup(LinuxAioState *s);
> > > > > -int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState 
> > > > > *s, int fd,
> > > > > -uint64_t offset, QEMUIOVector *qiov, 
> > > > > int type,
> > > > > -uint64_t dev_max_batch);
> > > > > +
> > > > > +/* laio_co_submit: submit I/O requests in the thread's current 
> > > > > AioContext. */
> > > > > +int coroutine_fn laio_co_submit(int fd, uint64_t offset, 
> > > > > QEMUIOVector *qiov,
> > > > > +int type, uint64_t dev_max_batch);
> > > > > +
> > > > >  void laio_detach_aio_context(LinuxAioState *s, AioContext 
> > > > > *old_context);
> > > > >  void laio_attach_aio_context(LinuxAioState *s, AioContext 
> > > > > *new_context);
> > > > > -void laio_io_plug(BlockDriverState *bs, LinuxAioState *s);
> > > > > -void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s,
> > > > > -uint64_t dev_max_batch);
> > > > > +
> > > > > +/*
> > > > > + * laio_io_plug/unplug work in the thread's current AioContext, 
> > > > > therefore the
> > > > > + * caller must ensure that they are paired in the same IOThread.
> > > > > + */
> > > > > +void laio_io_plug(void);
> > > > > +void laio_io_unplug(uint64_t dev_max_batch);
> > > > >  #endif
> > > > >  /* io_uring.c - Linux io_uring implementation */
> > > > >  #ifdef CONFIG_LINUX_IO_URING
> > > > > diff --git a/include/sysemu/block-backend-io.h 
> > > > > b/include/sysemu/block-backend-io.h
> > > > > index 031a27ba10..d41698ccc5 100644
> > > > > --- a/include/sysemu/block-backend-io.h
> > > > > +++ b/include/sysemu/block-backend-io.h
> > > > > @@ -74,8 +74,14 @@ void blk_iostatus_set_err(BlockBackend *blk, int 
> > > > > error);
> > > > >  int blk_get_max_iov(BlockBackend *blk);
> > > > >  int blk_get_max_hw_iov(BlockBackend *blk);
> > > > >  
> > > > > +/*
> > > > > + * blk_io_plug/unplug are thread-local operations. This means that 
> > > > > multiple
> > > > > + * IOThreads can simultaneously call plug/unplug, but the caller 
> > > > > must ensure
> > > > > + * that each unplug() is called in the same IOThread of the matching 
> > > > > plug().
> > > > > + */
> > > > >  void blk_io_plug(BlockBackend *blk);
> > > > >  void blk_io_unplug(BlockBackend *blk);
> > > > > +
> > > > >  AioContext *blk_get_aio_context(BlockBackend *blk);
> > > > >  BlockAcctStats *blk_get_stats(BlockBackend *blk);
> > > > >  void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
> > > > > diff --git a/block/file-posix.c b/block/file-posix.c
> > > > > index fa227d9d14..fa99d1c25a 100644
> > > > > --- a/block/file-posix.c
> > > > > +++ b/block/file-posix.c
> > > > > @@ -2095,10 +2095,8 @@ static int coroutine_fn 
> > > > > raw_co_prw(BlockDriverState *bs, uint64_t offset,
> > > > >  #endif

[PATCH 30/47] Revert "x86: use typedef for SetupData struct"

2023-03-08 Thread Michael Tokarev
From: "Michael S. Tsirkin" 

This reverts commit eebb38a5633a77f5fa79d6486d5b2fcf8fbe3c07.

Fixes: eebb38a563 ("x86: use typedef for SetupData struct")
Signed-off-by: Michael S. Tsirkin 
Tested-by: Nathan Chancellor 
Tested-by: Dov Murik 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Reviewed-by: Daniel P. Berrangé 
(cherry picked from commit ea96a784773259d469f3f2465f09e04eabb80a66)
Signed-off-by: Michael Tokarev 
---
 hw/i386/x86.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 32f37ab7c2..76b12108b4 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -657,12 +657,12 @@ DeviceState *ioapic_init_secondary(GSIState *gsi_state)
 return dev;
 }
 
-typedef struct SetupData {
+struct setup_data {
 uint64_t next;
 uint32_t type;
 uint32_t len;
 uint8_t data[];
-} __attribute__((packed)) SetupData;
+} __attribute__((packed));
 
 
 /*
@@ -803,7 +803,7 @@ void x86_load_linux(X86MachineState *x86ms,
 FILE *f;
 char *vmode;
 MachineState *machine = MACHINE(x86ms);
-SetupData *setup_data;
+struct setup_data *setup_data;
 const char *kernel_filename = machine->kernel_filename;
 const char *initrd_filename = machine->initrd_filename;
 const char *dtb_filename = machine->dtb;
@@ -1086,11 +1086,11 @@ void x86_load_linux(X86MachineState *x86ms,
 }
 
 setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
-kernel_size = setup_data_offset + sizeof(SetupData) + dtb_size;
+kernel_size = setup_data_offset + sizeof(struct setup_data) + dtb_size;
 kernel = g_realloc(kernel, kernel_size);
 
 
-setup_data = (SetupData *)(kernel + setup_data_offset);
+setup_data = (struct setup_data *)(kernel + setup_data_offset);
 setup_data->next = cpu_to_le64(first_setup_data);
 first_setup_data = prot_addr + setup_data_offset;
 setup_data->type = cpu_to_le32(SETUP_DTB);
@@ -1101,9 +1101,9 @@ void x86_load_linux(X86MachineState *x86ms,
 
 if (!legacy_no_rng_seed) {
 setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
-kernel_size = setup_data_offset + sizeof(SetupData) + RNG_SEED_LENGTH;
+kernel_size = setup_data_offset + sizeof(struct setup_data) + 
RNG_SEED_LENGTH;
 kernel = g_realloc(kernel, kernel_size);
-setup_data = (SetupData *)(kernel + setup_data_offset);
+setup_data = (struct setup_data *)(kernel + setup_data_offset);
 setup_data->next = cpu_to_le64(first_setup_data);
 first_setup_data = prot_addr + setup_data_offset;
 setup_data->type = cpu_to_le32(SETUP_RNG_SEED);
-- 
2.30.2




[PATCH 22/47] target/i386: Fix C flag for BLSI, BLSMSK, BLSR

2023-03-08 Thread Michael Tokarev
From: Richard Henderson 

We forgot to set cc_src, which is used for computing C.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1370
Signed-off-by: Richard Henderson 
Message-Id: <20230114180601.2993644-1-richard.hender...@linaro.org>
Cc: qemu-sta...@nongnu.org
Fixes: 1d0b926150e5 ("target/i386: move scalar 0F 38 and 0F 3A instruction to 
new decoder", 2022-10-18)
Signed-off-by: Paolo Bonzini 
(cherry picked from commit 99282098dc74c2055bde5652bde6cf0067d0c370)
Signed-off-by: Michael Tokarev 
---
 target/i386/tcg/emit.c.inc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index 99f6ba6e19..4d7702c106 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -,6 +,7 @@ static void gen_BLSI(DisasContext *s, CPUX86State *env, 
X86DecodedInsn *decode)
 {
 MemOp ot = decode->op[0].ot;
 
+tcg_gen_mov_tl(cpu_cc_src, s->T0);
 tcg_gen_neg_tl(s->T1, s->T0);
 tcg_gen_and_tl(s->T0, s->T0, s->T1);
 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
@@ -1121,6 +1122,7 @@ static void gen_BLSMSK(DisasContext *s, CPUX86State *env, 
X86DecodedInsn *decode
 {
 MemOp ot = decode->op[0].ot;
 
+tcg_gen_mov_tl(cpu_cc_src, s->T0);
 tcg_gen_subi_tl(s->T1, s->T0, 1);
 tcg_gen_xor_tl(s->T0, s->T0, s->T1);
 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
@@ -1131,6 +1133,7 @@ static void gen_BLSR(DisasContext *s, CPUX86State *env, 
X86DecodedInsn *decode)
 {
 MemOp ot = decode->op[0].ot;
 
+tcg_gen_mov_tl(cpu_cc_src, s->T0);
 tcg_gen_subi_tl(s->T1, s->T0, 1);
 tcg_gen_and_tl(s->T0, s->T0, s->T1);
 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
-- 
2.30.2




[RFC PATCH 00/47] Patch Round-up for stable 7.2.1

2023-03-08 Thread Michael Tokarev
Hello!

This is my first attempt to perform a stable qemu release.
Doing it in a way similar to how Michael Roth did it before :)
But since this is my first attempt, this is an RFC for now.

The following new patches are queued for QEMU stable v7.2.1:

  https://gitlab.com/mjt0k/qemu/-/commits/stable-7.2-staging/

Please respond here or CC qemu-sta...@nongnu.org on any additional patches
you think should (or shouldn't) be included in the release.

About some of the patches.

I picked up a few more than minimally necessary so that some of the CI
tests are fixed. These are the curl forward compat change, two changes
for tests/, and also "build-sys: fix crlf-ending C code" (fixes build
failure on msys-win32). The same failures exists on 7.2.0 now, while
the proposed 7.2.1 passes all tests I've tried so far (will try avocado
tests too once additional hdd will arrive).

Two patches ("vdpa: stop all svq on device deletion" and "Revert "hw/i386:
pass RNG seed via setup_data entry"") required conflict resolution when
cherry-picking.

2 virtio-rng-pci migration fixes makes certain v7.2.0 VMs non-migratable
to v7.2.1.

---

Akihiko Odaki (4):
  vhost-user-gpio: Configure vhost_dev when connecting
  vhost-user-i2c: Back up vqs before cleaning up vhost_dev
  vhost-user-rng: Back up vqs before cleaning up vhost_dev
  hw/timer/hpet: Fix expiration time overflow

Alex Bennée (2):
  target/arm: fix handling of HLT semihosting in system mode
  tests/tcg: fix unused variable in linux-test

Anton Johansson (1):
  block: Handle curl 7.55.0, 7.85.0 version changes

Carlos López (2):
  vhost: avoid a potential use of an uninitialized variable in
vhost_svq_poll()
  libvhost-user: check for NULL when allocating a virtqueue element

Chenyi Qiang (2):
  virtio-mem: Fix the bitmap index of the section offset
  virtio-mem: Fix the iterator variable in a vmem->rdl_list loop

David Hildenbrand (2):
  migration/ram: Fix error handling in ram_write_tracking_start()
  migration/ram: Fix populate_read_range()

Dr. David Alan Gilbert (2):
  virtio-rng-pci: fix migration compat for vectors
  virtio-rng-pci: fix transitional migration compat for vectors

Eugenio Pérez (1):
  vdpa: stop all svq on device deletion

Evgeny Iakovlev (1):
  target/arm: allow writes to SCR_EL3.HXEn bit when FEAT_HCX is enabled

Guenter Roeck (1):
  target/sh4: Mask restore of env->flags from tb->flags

Jason Wang (3):
  vhost: fix vq dirty bitmap syncing when vIOMMU is enabled
  intel-iommu: fail MAP notifier without caching mode
  intel-iommu: fail DEVIOTLB_UNMAP without dt mode

Julia Suvorova (1):
  hw/smbios: fix field corruption in type 4 table

Kevin Wolf (1):
  qcow2: Fix theoretical corruption in store_bitmap() error path

Klaus Jensen (2):
  hw/nvme: fix missing endian conversions for doorbell buffers
  hw/nvme: fix missing cq eventidx update

Laszlo Ersek (1):
  acpi: cpuhp: fix guest-visible maximum access size to the legacy reg
block

Marc-André Lureau (1):
  build-sys: fix crlf-ending C code

Michael S. Tsirkin (6):
  Revert "x86: do not re-randomize RNG seed on snapshot load"
  Revert "x86: re-initialize RNG seed when selecting kernel"
  Revert "x86: reinitialize RNG seed on system reboot"
  Revert "x86: use typedef for SetupData struct"
  Revert "x86: return modified setup_data only if read as memory, not as
file"
  Revert "hw/i386: pass RNG seed via setup_data entry"

Paolo Bonzini (4):
  meson: accept relative symlinks in "meson introspect --installed" data
  configure: fix GLIB_VERSION for cross-compilation
  target/i386: fix ADOX followed by ADCX
  block/iscsi: fix double-free on BUSY or similar statuses

Richard Henderson (8):
  target/riscv: Set pc_succ_insn for !rvc illegal insn
  target/arm: Fix sve_probe_page
  target/arm: Fix in_debug path in S1_ptw_translate
  target/arm: Fix physical address resolution for Stage2
  tests/tcg/i386: Introduce and use reg_t consistently
  target/i386: Fix BEXTR instruction
  target/i386: Fix C flag for BLSI, BLSMSK, BLSR
  target/i386: Fix BZHI instruction

Stefan Hajnoczi (1):
  block: fix detect-zeroes= with BDRV_REQ_REGISTERED_BUF

Yajun Wu (1):
  chardev/char-socket: set s->listener = NULL in char_socket_finalize

 block/curl.c  |  44 -
 block/io.c|   3 +
 block/iscsi.c |   1 +
 block/qcow2-bitmap.c  |   5 +-
 chardev/char-socket.c |   1 +
 configure |   2 +-
 hw/acpi/cpu_hotplug.c |   3 +
 hw/core/machine.c |   3 +
 hw/i386/intel_iommu.c |  15 ++
 hw/i386/microvm.c |   2 +-
 hw/i386/pc.c  |   4 +-
 hw/i386/pc_piix.c |   2 -
 hw/i386/pc_q35.c  |   2 -
 hw/i386/x86.c |  88 ++--

[PATCH 01/47] target/sh4: Mask restore of env->flags from tb->flags

2023-03-08 Thread Michael Tokarev
From: Guenter Roeck 

The values in env->flags are a subset of tb->flags.
Restore only the bits that belong.

Cc: qemu-sta...@nongnu.org
Fixes: ab419fd8a035 ("target/sh4: Fix TB_FLAG_UNALIGN")
Signed-off-by: Guenter Roeck 
Message-ID: <20221212011345.ga2235...@roeck-us.net>
[rth: Reduce to only the the superh_cpu_synchronize_from_tb change]
Signed-off-by: Richard Henderson 
(cherry picked from commit bc2331635ce18ff068d2bb1e493bc546e1f786e1)
Signed-off-by: Michael Tokarev 
---
 target/sh4/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 453268392b..827cee25af 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -47,7 +47,7 @@ static void superh_cpu_synchronize_from_tb(CPUState *cs,
 SuperHCPU *cpu = SUPERH_CPU(cs);
 
 cpu->env.pc = tb_pc(tb);
-cpu->env.flags = tb->flags;
+cpu->env.flags = tb->flags & TB_FLAG_ENVFLAGS_MASK;
 }
 
 static void superh_restore_state_to_opc(CPUState *cs,
-- 
2.30.2




[PATCH 08/47] acpi: cpuhp: fix guest-visible maximum access size to the legacy reg block

2023-03-08 Thread Michael Tokarev
From: Laszlo Ersek 

The modern ACPI CPU hotplug interface was introduced in the following
series (aa1dd39ca307..679dd1a957df), released in v2.7.0:

  1  abd49bc2ed2f docs: update ACPI CPU hotplug spec with new protocol
  2  16bcab97eb9f pc: piix4/ich9: add 'cpu-hotplug-legacy' property
  3  5e1b5d93887b acpi: cpuhp: add CPU devices AML with _STA method
  4  ac35f13ba8f8 pc: acpi: introduce AcpiDeviceIfClass.madt_cpu hook
  5  d2238cb6781d acpi: cpuhp: implement hot-add parts of CPU hotplug
  interface
  6  8872c25a26cc acpi: cpuhp: implement hot-remove parts of CPU hotplug
  interface
  7  76623d00ae57 acpi: cpuhp: add cpu._OST handling
  8  679dd1a957df pc: use new CPU hotplug interface since 2.7 machine type

Before patch#1, "docs/specs/acpi_cpu_hotplug.txt" only specified 1-byte
accesses for the hotplug register block.  Patch#1 preserved the same
restriction for the legacy register block, but:

- it specified DWORD accesses for some of the modern registers,

- in particular, the switch from the legacy block to the modern block
  would require a DWORD write to the *legacy* block.

The latter functionality was then implemented in cpu_status_write()
[hw/acpi/cpu_hotplug.c], in patch#8.

Unfortunately, all DWORD accesses depended on a dormant bug: the one
introduced in earlier commit a014ed07bd5a ("memory: accept mismatching
sizes in memory_region_access_valid", 2013-05-29); first released in
v1.6.0.  Due to commit a014ed07bd5a, the DWORD accesses to the *legacy*
CPU hotplug register block would work in spite of the above series *not*
relaxing "valid.max_access_size = 1" in "hw/acpi/cpu_hotplug.c":

> static const MemoryRegionOps AcpiCpuHotplug_ops = {
> .read = cpu_status_read,
> .write = cpu_status_write,
> .endianness = DEVICE_LITTLE_ENDIAN,
> .valid = {
> .min_access_size = 1,
> .max_access_size = 1,
> },
> };

Later, in commits e6d0c3ce6895 ("acpi: cpuhp: introduce 'Command data 2'
field", 2020-01-22) and ae340aa3d256 ("acpi: cpuhp: spec: add typical
usecases", 2020-01-22), first released in v5.0.0, the modern CPU hotplug
interface (including the documentation) was extended with another DWORD
*read* access, namely to the "Command data 2" register, which would be
important for the guest to confirm whether it managed to switch the
register block from legacy to modern.

This functionality too silently depended on the bug from commit
a014ed07bd5a.

In commit 5d971f9e6725 ('memory: Revert "memory: accept mismatching sizes
in memory_region_access_valid"', 2020-06-26), first released in v5.1.0,
the bug from commit a014ed07bd5a was fixed (the commit was reverted).
That swiftly exposed the bug in "AcpiCpuHotplug_ops", still present from
the v2.7.0 series quoted at the top -- namely the fact that
"valid.max_access_size = 1" didn't match what the guest was supposed to
do, according to the spec ("docs/specs/acpi_cpu_hotplug.txt").

The symptom is that the "modern interface negotiation protocol"
described in commit ae340aa3d256:

> +  Use following steps to detect and enable modern CPU hotplug interface:
> +1. Store 0x0 to the 'CPU selector' register,
> +   attempting to switch to modern mode
> +2. Store 0x0 to the 'CPU selector' register,
> +   to ensure valid selector value
> +3. Store 0x0 to the 'Command field' register,
> +4. Read the 'Command data 2' register.
> +   If read value is 0x0, the modern interface is enabled.
> +   Otherwise legacy or no CPU hotplug interface available

falls apart for the guest: steps 1 and 2 are lost, because they are DWORD
writes; so no switching happens.  Step 3 (a single-byte write) is not
lost, but it has no effect; see the condition in cpu_status_write() in
patch#8.  And step 4 *misleads* the guest into thinking that the switch
worked: the DWORD read is lost again -- it returns zero to the guest
without ever reaching the device model, so the guest never learns the
switch didn't work.

This means that guest behavior centered on the "Command data 2" register
worked *only* in the v5.0.0 release; it got effectively regressed in
v5.1.0.

To make things *even more* complicated, the breakage was (and remains, as
of today) visible with TCG acceleration only.  Commit 5d971f9e6725 makes
no difference with KVM acceleration -- the DWORD accesses still work,
despite "valid.max_access_size = 1".

As commit 5d971f9e6725 suggests, fix the problem by raising
"valid.max_access_size" to 4 -- the spec now clearly instructs the guest
to perform DWORD accesses to the legacy register block too, for enabling
(and verifying!) the modern block.  In order to keep compatibility for the
device model implementation though, set "impl.max_access_size = 1", so
that wide accesses be split before they reach the legacy read/write
handlers, like they always have been on KVM, and like they were on TCG
before 5d971f9e6725 (v5.1.0).

Tested with:

- OVMF IA32 + qemu-system-i386, C

[PATCH 46/47] tests/tcg: fix unused variable in linux-test

2023-03-08 Thread Michael Tokarev
From: Alex Bennée 

The latest hexagon compiler picks up that we never consume wcount.
Given the name of the #define that rcount checks against is WCOUNT_MAX
I figured the check just got missed.

Signed-off-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221221090411.1995037-5-alex.ben...@linaro.org>
(cherry picked from commit 2bc6c79417b89c3306b724577e775f03fe61fb2e)
Signed-off-by: Michael Tokarev 
---
 tests/tcg/multiarch/linux/linux-test.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tests/tcg/multiarch/linux/linux-test.c 
b/tests/tcg/multiarch/linux/linux-test.c
index 5a2a4f2258..64f57cb287 100644
--- a/tests/tcg/multiarch/linux/linux-test.c
+++ b/tests/tcg/multiarch/linux/linux-test.c
@@ -354,13 +354,17 @@ static void test_pipe(void)
 if (FD_ISSET(fds[0], &rfds)) {
 chk_error(read(fds[0], &ch, 1));
 rcount++;
-if (rcount >= WCOUNT_MAX)
+if (rcount >= WCOUNT_MAX) {
 break;
+}
 }
 if (FD_ISSET(fds[1], &wfds)) {
 ch = 'a';
 chk_error(write(fds[1], &ch, 1));
 wcount++;
+if (wcount >= WCOUNT_MAX) {
+break;
+}
 }
 }
 }
-- 
2.30.2




[PATCH 31/47] Revert "x86: return modified setup_data only if read as memory, not as file"

2023-03-08 Thread Michael Tokarev
From: "Michael S. Tsirkin" 

This reverts commit e935b735085dfa61d8e6d276b6f9e7687796a3c7.

Fixes: e935b73508 ("x86: return modified setup_data only if read as memory, not 
as file")
Signed-off-by: Michael S. Tsirkin 
Tested-by: Nathan Chancellor 
Tested-by: Dov Murik 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Reviewed-by: Daniel P. Berrangé 
(cherry picked from commit ae80d81cfa865cbe443543679e013e7fa5fcd12c)
Signed-off-by: Michael Tokarev 
---
 hw/i386/x86.c | 46 +--
 hw/nvram/fw_cfg.c | 12 +-
 include/hw/nvram/fw_cfg.h | 22 ---
 3 files changed, 16 insertions(+), 64 deletions(-)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 76b12108b4..4831193c86 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -37,7 +37,6 @@
 #include "sysemu/whpx.h"
 #include "sysemu/numa.h"
 #include "sysemu/replay.h"
-#include "sysemu/reset.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/cpu-timers.h"
 #include "sysemu/xen.h"
@@ -769,24 +768,6 @@ static bool load_elfboot(const char *kernel_filename,
 return true;
 }
 
-typedef struct SetupDataFixup {
-void *pos;
-hwaddr orig_val, new_val;
-uint32_t addr;
-} SetupDataFixup;
-
-static void fixup_setup_data(void *opaque)
-{
-SetupDataFixup *fixup = opaque;
-stq_p(fixup->pos, fixup->new_val);
-}
-
-static void reset_setup_data(void *opaque)
-{
-SetupDataFixup *fixup = opaque;
-stq_p(fixup->pos, fixup->orig_val);
-}
-
 void x86_load_linux(X86MachineState *x86ms,
 FWCfgState *fw_cfg,
 int acpi_data_size,
@@ -,11 +1092,8 @@ void x86_load_linux(X86MachineState *x86ms,
 qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH);
 }
 
-fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
-fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
-fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
-sev_load_ctx.kernel_data = (char *)kernel;
-sev_load_ctx.kernel_size = kernel_size;
+/* Offset 0x250 is a pointer to the first setup_data link. */
+stq_p(header + 0x250, first_setup_data);
 
 /*
  * If we're starting an encrypted VM, it will be OVMF based, which uses the
@@ -1125,20 +1103,16 @@ void x86_load_linux(X86MachineState *x86ms,
  * file the user passed in.
  */
 if (!sev_enabled()) {
-SetupDataFixup *fixup = g_malloc(sizeof(*fixup));
-
 memcpy(setup, header, MIN(sizeof(header), setup_size));
-/* Offset 0x250 is a pointer to the first setup_data link. */
-fixup->pos = setup + 0x250;
-fixup->orig_val = ldq_p(fixup->pos);
-fixup->new_val = first_setup_data;
-fixup->addr = cpu_to_le32(real_addr);
-fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_SETUP_ADDR, fixup_setup_data, 
NULL,
-  fixup, &fixup->addr, sizeof(fixup->addr), 
true);
-qemu_register_reset(reset_setup_data, fixup);
-} else {
-fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
 }
+
+fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
+fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
+fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
+sev_load_ctx.kernel_data = (char *)kernel;
+sev_load_ctx.kernel_size = kernel_size;
+
+fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
 fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
 fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);
 sev_load_ctx.setup_data = (char *)setup;
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 6edf5ea3e9..371a45dfe2 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -693,12 +693,12 @@ static const VMStateDescription vmstate_fw_cfg = {
 }
 };
 
-void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
-   FWCfgCallback select_cb,
-   FWCfgWriteCallback write_cb,
-   void *callback_opaque,
-   void *data, size_t len,
-   bool read_only)
+static void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
+  FWCfgCallback select_cb,
+  FWCfgWriteCallback write_cb,
+  void *callback_opaque,
+  void *data, size_t len,
+  bool read_only)
 {
 int arch = !!(key & FW_CFG_ARCH_LOCAL);
 
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index 2e503904dc..c1f81a5f13 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -117,28 +117,6 @@ struct FWCfgMemState {
  */
 void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);
 
-/**
- * fw_cfg_add_bytes_callback:
- * @s: fw_cfg device being modified
- * @key: selector key value

[PATCH 18/47] qcow2: Fix theoretical corruption in store_bitmap() error path

2023-03-08 Thread Michael Tokarev
From: Kevin Wolf 

In order to write the bitmap table to the image file, it is converted to
big endian. If the write fails, it is passed to clear_bitmap_table() to
free all of the clusters it had allocated before. However, if we don't
convert it back to native endianness first, we'll free things at a wrong
offset.

In practical terms, the offsets will be so high that we won't actually
free any allocated clusters, but just run into an error, but in theory
this can cause image corruption.

Cc: qemu-sta...@nongnu.org
Signed-off-by: Kevin Wolf 
Message-Id: <20230112191454.169353-2-kw...@redhat.com>
Reviewed-by: Hanna Czenczek 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Kevin Wolf 
(cherry picked from commit b03dd9613bcf8fe948581b2b3585510cb525c382)
Signed-off-by: Michael Tokarev 
---
 block/qcow2-bitmap.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index bcad567c0c..3dff99ba06 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -115,7 +115,7 @@ static int update_header_sync(BlockDriverState *bs)
 return bdrv_flush(bs->file->bs);
 }
 
-static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
+static inline void bitmap_table_bswap_be(uint64_t *bitmap_table, size_t size)
 {
 size_t i;
 
@@ -1401,9 +1401,10 @@ static int store_bitmap(BlockDriverState *bs, 
Qcow2Bitmap *bm, Error **errp)
 goto fail;
 }
 
-bitmap_table_to_be(tb, tb_size);
+bitmap_table_bswap_be(tb, tb_size);
 ret = bdrv_pwrite(bs->file, tb_offset, tb_size * sizeof(tb[0]), tb, 0);
 if (ret < 0) {
+bitmap_table_bswap_be(tb, tb_size);
 error_setg_errno(errp, -ret, "Failed to write bitmap '%s' to file",
  bm_name);
 goto fail;
-- 
2.30.2




[PATCH 07/47] target/riscv: Set pc_succ_insn for !rvc illegal insn

2023-03-08 Thread Michael Tokarev
From: Richard Henderson 

Failure to set pc_succ_insn may result in a TB covering zero bytes,
which triggers an assert within the code generator.

Cc: qemu-sta...@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1224
Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221203175744.151365-1-richard.hender...@linaro.org>
[ Changes by AF:
 - Add missing run-plugin-test-noc-% line
]
Signed-off-by: Alistair Francis 
(cherry picked from commit ec2918b467228e7634f1dd5f35033ad3021b6ef7)
Signed-off-by: Michael Tokarev 
---
 target/riscv/translate.c  | 12 
 tests/tcg/Makefile.target |  2 ++
 tests/tcg/riscv64/Makefile.target |  6 ++
 tests/tcg/riscv64/test-noc.S  | 32 +++
 4 files changed, 44 insertions(+), 8 deletions(-)
 create mode 100644 tests/tcg/riscv64/test-noc.S

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index db123da5ec..1ed4bb5ec3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1064,14 +1064,10 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 
 /* Check for compressed insn */
 if (insn_len(opcode) == 2) {
-if (!has_ext(ctx, RVC)) {
-gen_exception_illegal(ctx);
-} else {
-ctx->opcode = opcode;
-ctx->pc_succ_insn = ctx->base.pc_next + 2;
-if (decode_insn16(ctx, opcode)) {
-return;
-}
+ctx->opcode = opcode;
+ctx->pc_succ_insn = ctx->base.pc_next + 2;
+if (has_ext(ctx, RVC) && decode_insn16(ctx, opcode)) {
+return;
 }
 } else {
 uint32_t opcode32 = opcode;
diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target
index 75257f2b29..14bc013181 100644
--- a/tests/tcg/Makefile.target
+++ b/tests/tcg/Makefile.target
@@ -117,6 +117,8 @@ endif
 
 %: %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
+%: %.S
+   $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
 else
 # For softmmu targets we include a different Makefile fragement as the
 # build options for bare programs are usually pretty different. They
diff --git a/tests/tcg/riscv64/Makefile.target 
b/tests/tcg/riscv64/Makefile.target
index b5b89dfb0e..cc3ed65ffd 100644
--- a/tests/tcg/riscv64/Makefile.target
+++ b/tests/tcg/riscv64/Makefile.target
@@ -4,3 +4,9 @@
 VPATH += $(SRC_PATH)/tests/tcg/riscv64
 TESTS += test-div
 TESTS += noexec
+
+# Disable compressed instructions for test-noc
+TESTS += test-noc
+test-noc: LDFLAGS = -nostdlib -static
+run-test-noc: QEMU_OPTS += -cpu rv64,c=false
+run-plugin-test-noc-%: QEMU_OPTS += -cpu rv64,c=false
diff --git a/tests/tcg/riscv64/test-noc.S b/tests/tcg/riscv64/test-noc.S
new file mode 100644
index 00..e29d60c8b3
--- /dev/null
+++ b/tests/tcg/riscv64/test-noc.S
@@ -0,0 +1,32 @@
+#include 
+
+   .text
+   .globl _start
+_start:
+   .option norvc
+   li  a0, 4   /* SIGILL */
+   la  a1, sa
+   li  a2, 0
+   li  a3, 8
+   li  a7, __NR_rt_sigaction
+   scall
+
+   .option rvc
+   li  a0, 1
+   j   exit
+   .option norvc
+
+pass:
+   li  a0, 0
+exit:
+   li  a7, __NR_exit
+   scall
+
+   .data
+   /* struct kernel_sigaction sa = { .sa_handler = pass }; */
+   .type   sa, @object
+   .size   sa, 32
+sa:
+   .dword  pass
+   .zero   24
+
-- 
2.30.2




[PATCH 09/47] hw/nvme: fix missing endian conversions for doorbell buffers

2023-03-08 Thread Michael Tokarev
From: Klaus Jensen 

The eventidx and doorbell value are not handling endianness correctly.
Fix this.

Fixes: 3f7fe8de3d49 ("hw/nvme: Implement shadow doorbell buffer support")
Cc: qemu-sta...@nongnu.org
Reported-by: Guenter Roeck 
Reviewed-by: Keith Busch 
Signed-off-by: Klaus Jensen 
(cherry picked from commit 2fda0726e5149e032acfa5fe442db56cd6433c4c)
Signed-off-by: Michael Tokarev 
Conflicts: hw/nvme/ctrl.c
---
 hw/nvme/ctrl.c | 22 --
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index ac3885ce50..83f5e58e8d 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -1333,8 +1333,12 @@ static inline void nvme_blk_write(BlockBackend *blk, 
int64_t offset,
 
 static void nvme_update_cq_head(NvmeCQueue *cq)
 {
-pci_dma_read(&cq->ctrl->parent_obj, cq->db_addr, &cq->head,
-sizeof(cq->head));
+uint32_t v;
+
+pci_dma_read(&cq->ctrl->parent_obj, cq->db_addr, &v, sizeof(v));
+
+cq->head = le32_to_cpu(v);
+
 trace_pci_nvme_shadow_doorbell_cq(cq->cqid, cq->head);
 }
 
@@ -6221,15 +6225,21 @@ static uint16_t nvme_admin_cmd(NvmeCtrl *n, NvmeRequest 
*req)
 
 static void nvme_update_sq_eventidx(const NvmeSQueue *sq)
 {
-pci_dma_write(&sq->ctrl->parent_obj, sq->ei_addr, &sq->tail,
-  sizeof(sq->tail));
+uint32_t v = cpu_to_le32(sq->tail);
+
+pci_dma_write(&sq->ctrl->parent_obj, sq->ei_addr, &v, sizeof(v));
+
 trace_pci_nvme_eventidx_sq(sq->sqid, sq->tail);
 }
 
 static void nvme_update_sq_tail(NvmeSQueue *sq)
 {
-pci_dma_read(&sq->ctrl->parent_obj, sq->db_addr, &sq->tail,
- sizeof(sq->tail));
+uint32_t v;
+
+pci_dma_read(&sq->ctrl->parent_obj, sq->db_addr, &v, sizeof(v));
+
+sq->tail = le32_to_cpu(v);
+
 trace_pci_nvme_shadow_doorbell_sq(sq->sqid, sq->tail);
 }
 
-- 
2.30.2




[PATCH 37/47] virtio-rng-pci: fix transitional migration compat for vectors

2023-03-08 Thread Michael Tokarev
From: "Dr. David Alan Gilbert" 

In bad9c5a516 ("virtio-rng-pci: fix migration compat for vectors") I
fixed the virtio-rng-pci migration compatibility, but it was discovered
that we also need to fix the other aliases of the device for the
transitional cases.

Fixes: 9ea02e8f1 ('virtio-rng-pci: Allow setting nvectors, so we can use MSI-X')
bz: https://bugzilla.redhat.com/show_bug.cgi?id=2162569
Signed-off-by: Dr. David Alan Gilbert 
Message-Id: <20230207174944.138255-1-dgilb...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
(cherry picked from commit 62bdb8871512076841f4464f7e26efdc7783f78d)
Signed-off-by: Michael Tokarev 
---
 hw/core/machine.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 77a0a131d1..035d078a74 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -43,6 +43,8 @@
 GlobalProperty hw_compat_7_1[] = {
 { "virtio-device", "queue_reset", "false" },
 { "virtio-rng-pci", "vectors", "0" },
+{ "virtio-rng-pci-transitional", "vectors", "0" },
+{ "virtio-rng-pci-non-transitional", "vectors", "0" },
 };
 const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1);
 
-- 
2.30.2




[PATCH 43/47] intel-iommu: fail MAP notifier without caching mode

2023-03-08 Thread Michael Tokarev
From: Jason Wang 

Without caching mode, MAP notifier won't work correctly since guest
won't send IOTLB update event when it establishes new mappings in the
I/O page tables. Let's fail the IOMMU notifiers early instead of
misbehaving silently.

Reviewed-by: Eric Auger 
Tested-by: Viktor Prutyanov 
Signed-off-by: Jason Wang 
Message-Id: <20230223065924.42503-2-jasow...@redhat.com>
Reviewed-by: Peter Xu 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
(cherry picked from commit b8d78277c091f26fdd64f239bc8bb7e55d74cecf)
Signed-off-by: Michael Tokarev 
---
 hw/i386/intel_iommu.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index a08ee85edf..9143376677 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -3186,6 +3186,13 @@ static int 
vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
  "Snoop Control with vhost or VFIO is not supported");
 return -ENOTSUP;
 }
+if (!s->caching_mode && (new & IOMMU_NOTIFIER_MAP)) {
+error_setg_errno(errp, ENOTSUP,
+ "device %02x.%02x.%x requires caching mode",
+ pci_bus_num(vtd_as->bus), PCI_SLOT(vtd_as->devfn),
+ PCI_FUNC(vtd_as->devfn));
+return -ENOTSUP;
+}
 
 /* Update per-address-space notifier flags */
 vtd_as->notifier_flags = new;
-- 
2.30.2




[PATCH 23/47] target/i386: fix ADOX followed by ADCX

2023-03-08 Thread Michael Tokarev
From: Paolo Bonzini 

When ADCX is followed by ADOX or vice versa, the second instruction's
carry comes from EFLAGS and the condition codes use the CC_OP_ADCOX
operation.  Retrieving the carry from EFLAGS is handled by this bit
of gen_ADCOX:

tcg_gen_extract_tl(carry_in, cpu_cc_src,
ctz32(cc_op == CC_OP_ADCX ? CC_C : CC_O), 1);

Unfortunately, in this case cc_op has been overwritten by the previous
"if" statement to CC_OP_ADCOX.  This works by chance when the first
instruction is ADCX; however, if the first instruction is ADOX,
ADCX will incorrectly take its carry from OF instead of CF.

Fix by moving the computation of the new cc_op at the end of the function.
The included exhaustive test case fails without this patch and passes
afterwards.

Because ADCX/ADOX need not be invoked through the VEX prefix, this
regression bisects to commit 16fc5726a6e2 ("target/i386: reimplement
0x0f 0x38, add AVX", 2022-10-18).  However, the mistake happened a
little earlier, when BMI instructions were rewritten using the new
decoder framework.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1471
Reported-by: Paul Jolly 
Fixes: 1d0b926150e5 ("target/i386: move scalar 0F 38 and 0F 3A instruction to 
new decoder", 2022-10-18)
Cc: qemu-sta...@nongnu.org
Signed-off-by: Paolo Bonzini 
(cherry picked from commit 60c7dd22e1383754d5f150bc9f7c2785c662a7b6)
Signed-off-by: Michael Tokarev 
---
 target/i386/tcg/emit.c.inc   | 20 +
 tests/tcg/i386/Makefile.target   |  6 ++-
 tests/tcg/i386/test-i386-adcox.c | 75 
 3 files changed, 91 insertions(+), 10 deletions(-)
 create mode 100644 tests/tcg/i386/test-i386-adcox.c

diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index 4d7702c106..0d7c6e80ae 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -1015,6 +1015,7 @@ VSIB_AVX(VPGATHERQ, vpgatherq)
 
 static void gen_ADCOX(DisasContext *s, CPUX86State *env, MemOp ot, int cc_op)
 {
+int opposite_cc_op;
 TCGv carry_in = NULL;
 TCGv carry_out = (cc_op == CC_OP_ADCX ? cpu_cc_dst : cpu_cc_src2);
 TCGv zero;
@@ -1022,14 +1023,8 @@ static void gen_ADCOX(DisasContext *s, CPUX86State *env, 
MemOp ot, int cc_op)
 if (cc_op == s->cc_op || s->cc_op == CC_OP_ADCOX) {
 /* Re-use the carry-out from a previous round.  */
 carry_in = carry_out;
-cc_op = s->cc_op;
-} else if (s->cc_op == CC_OP_ADCX || s->cc_op == CC_OP_ADOX) {
-/* Merge with the carry-out from the opposite instruction.  */
-cc_op = CC_OP_ADCOX;
-}
-
-/* If we don't have a carry-in, get it out of EFLAGS.  */
-if (!carry_in) {
+} else {
+/* We don't have a carry-in, get it out of EFLAGS.  */
 if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
 gen_compute_eflags(s);
 }
@@ -1053,7 +1048,14 @@ static void gen_ADCOX(DisasContext *s, CPUX86State *env, 
MemOp ot, int cc_op)
 tcg_gen_add2_tl(s->T0, carry_out, s->T0, carry_out, s->T1, zero);
 break;
 }
-set_cc_op(s, cc_op);
+
+opposite_cc_op = cc_op == CC_OP_ADCX ? CC_OP_ADOX : CC_OP_ADCX;
+if (s->cc_op == CC_OP_ADCOX || s->cc_op == opposite_cc_op) {
+/* Merge with the carry-out from the opposite instruction.  */
+set_cc_op(s, CC_OP_ADCOX);
+} else {
+set_cc_op(s, cc_op);
+}
 }
 
 static void gen_ADCX(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
diff --git a/tests/tcg/i386/Makefile.target b/tests/tcg/i386/Makefile.target
index 81831cafbc..bafd8c2180 100644
--- a/tests/tcg/i386/Makefile.target
+++ b/tests/tcg/i386/Makefile.target
@@ -14,7 +14,7 @@ config-cc.mak: Makefile
 I386_SRCS=$(notdir $(wildcard $(I386_SRC)/*.c))
 ALL_X86_TESTS=$(I386_SRCS:.c=)
 SKIP_I386_TESTS=test-i386-ssse3 test-avx test-3dnow test-mmx
-X86_64_TESTS:=$(filter test-i386-bmi2 $(SKIP_I386_TESTS), $(ALL_X86_TESTS))
+X86_64_TESTS:=$(filter test-i386-adcox test-i386-bmi2 $(SKIP_I386_TESTS), 
$(ALL_X86_TESTS))
 
 test-i386-sse-exceptions: CFLAGS += -msse4.1 -mfpmath=sse
 run-test-i386-sse-exceptions: QEMU_OPTS += -cpu max
@@ -28,6 +28,10 @@ test-i386-bmi2: CFLAGS=-O2
 run-test-i386-bmi2: QEMU_OPTS += -cpu max
 run-plugin-test-i386-bmi2-%: QEMU_OPTS += -cpu max
 
+test-i386-adcox: CFLAGS=-O2
+run-test-i386-adcox: QEMU_OPTS += -cpu max
+run-plugin-test-i386-adcox-%: QEMU_OPTS += -cpu max
+
 #
 # hello-i386 is a barebones app
 #
diff --git a/tests/tcg/i386/test-i386-adcox.c b/tests/tcg/i386/test-i386-adcox.c
new file mode 100644
index 00..16169efff8
--- /dev/null
+++ b/tests/tcg/i386/test-i386-adcox.c
@@ -0,0 +1,75 @@
+/* See if various BMI2 instructions give expected results */
+#include 
+#include 
+#include 
+
+#define CC_C 1
+#define CC_O (1 << 11)
+
+#ifdef __x86_64__
+#define REG uint64_t
+#else
+#define REG uint32_t
+#endif
+
+void test_adox_adcx(uint32_t in_c, uint32_t in_o, REG adcx_operand, REG 
adox_operand)
+{
+REG flags;
+

[PATCH 42/47] chardev/char-socket: set s->listener = NULL in char_socket_finalize

2023-03-08 Thread Michael Tokarev
From: Yajun Wu 

After live migration with virtio block device, qemu crash at:

#0  0x55914f46f795 in object_dynamic_cast_assert 
(obj=0x559151b7b090, typename=0x55914f80fbc4 "qio-channel", file=0x55914f80fb90 
"/images/testvfe/sw/qemu.gerrit/include/io/channel.h", line=30, 
func=0x55914f80fcb8 <__func__.17257> "QIO_CHANNEL") at ../qom/object.c:872
#1  0x55914f480d68 in QIO_CHANNEL (obj=0x559151b7b090) at 
/images/testvfe/sw/qemu.gerrit/include/io/channel.h:29
#2  0x55914f4812f8 in qio_net_listener_set_client_func_full 
(listener=0x559151b7a720, func=0x55914f580b97 , 
data=0x5591519f4ea0, notify=0x0, context=0x0) at ../io/net-listener.c:166
#3  0x55914f580059 in tcp_chr_update_read_handler 
(chr=0x5591519f4ea0) at ../chardev/char-socket.c:637
#4  0x55914f583dca in qemu_chr_be_update_read_handlers 
(s=0x5591519f4ea0, context=0x0) at ../chardev/char.c:226
#5  0x55914f57b7c9 in qemu_chr_fe_set_handlers_full 
(b=0x559152bf23a0, fd_can_read=0x0, fd_read=0x0, fd_event=0x0, be_change=0x0, 
opaque=0x0, context=0x0, set_open=false, sync_state=true) at 
../chardev/char-fe.c:279
#6  0x55914f57b86d in qemu_chr_fe_set_handlers (b=0x559152bf23a0, 
fd_can_read=0x0, fd_read=0x0, fd_event=0x0, be_change=0x0, opaque=0x0, 
context=0x0, set_open=false) at ../chardev/char-fe.c:304
#7  0x55914f378caf in vhost_user_async_close (d=0x559152bf21a0, 
chardev=0x559152bf23a0, vhost=0x559152bf2420, cb=0x55914f2fb8c1 
) at ../hw/virtio/vhost-user.c:2725
#8  0x55914f2fba40 in vhost_user_blk_event (opaque=0x559152bf21a0, 
event=CHR_EVENT_CLOSED) at ../hw/block/vhost-user-blk.c:395
#9  0x55914f58388c in chr_be_event (s=0x5591519f4ea0, 
event=CHR_EVENT_CLOSED) at ../chardev/char.c:61
#10 0x55914f583905 in qemu_chr_be_event (s=0x5591519f4ea0, 
event=CHR_EVENT_CLOSED) at ../chardev/char.c:81
#11 0x55914f581275 in char_socket_finalize (obj=0x5591519f4ea0) at 
../chardev/char-socket.c:1083
#12 0x55914f46f073 in object_deinit (obj=0x5591519f4ea0, 
type=0x5591519055c0) at ../qom/object.c:680
#13 0x55914f46f0e5 in object_finalize (data=0x5591519f4ea0) at 
../qom/object.c:694
#14 0x55914f46ff06 in object_unref (objptr=0x5591519f4ea0) at 
../qom/object.c:1202
#15 0x55914f4715a4 in object_finalize_child_property 
(obj=0x559151b76c50, name=0x559151b7b250 "char3", opaque=0x5591519f4ea0) at 
../qom/object.c:1747
#16 0x55914f46ee86 in object_property_del_all (obj=0x559151b76c50) 
at ../qom/object.c:632
#17 0x55914f46f0d2 in object_finalize (data=0x559151b76c50) at 
../qom/object.c:693
#18 0x55914f46ff06 in object_unref (objptr=0x559151b76c50) at 
../qom/object.c:1202
#19 0x55914f4715a4 in object_finalize_child_property 
(obj=0x559151b6b560, name=0x559151b76630 "chardevs", opaque=0x559151b76c50) at 
../qom/object.c:1747
#20 0x55914f46ef67 in object_property_del_child 
(obj=0x559151b6b560, child=0x559151b76c50) at ../qom/object.c:654
#21 0x55914f46f042 in object_unparent (obj=0x559151b76c50) at 
../qom/object.c:673
#22 0x55914f58632a in qemu_chr_cleanup () at ../chardev/char.c:1189
#23 0x55914f16c66c in qemu_cleanup () at ../softmmu/runstate.c:830
#24 0x55914eee7b9e in qemu_default_main () at ../softmmu/main.c:38
#25 0x55914eee7bcc in main (argc=86, argv=0x7ffc97cb8d88) at 
../softmmu/main.c:48

In char_socket_finalize after s->listener freed, event callback function
vhost_user_blk_event will be called to handle CHR_EVENT_CLOSED.
vhost_user_blk_event is calling qio_net_listener_set_client_func_full which
is still using s->listener.

Setting s->listener = NULL after object_unref(OBJECT(s->listener)) can
solve this issue.

Signed-off-by: Yajun Wu 
Acked-by: Jiri Pirko 
Message-Id: <20230214021430.3638579-1-yaj...@nvidia.com>
Reviewed-by: Marc-André Lureau 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
(cherry picked from commit b8a7f51f59e28d5a8e0c07ed3919cc9695560ed2)
Signed-off-by: Michael Tokarev 
---
 chardev/char-socket.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 879564aa8a..b00efb1482 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1065,6 +1065,7 @@ static void char_socket_finalize(Object *obj)
 qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
   NULL, chr->gcontext);
 object_unref(OBJECT(s->listener));
+s->listener = NULL;
 }
 if (s->tls_creds) {
 object_unref(OBJECT(s->tls_creds));
-- 
2.30.2




[PATCH 15/47] target/arm: Fix physical address resolution for Stage2

2023-03-08 Thread Michael Tokarev
From: Richard Henderson 

Conversion to probe_access_full missed applying the page offset.

Cc: qemu-sta...@nongnu.org
Reported-by: Sid Manning 
Signed-off-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-id: 20230126233134.103193-1-richard.hender...@linaro.org
Fixes: f3639a64f602 ("target/arm: Use softmmu tlbs for page table walking")
Signed-off-by: Richard Henderson 
Signed-off-by: Peter Maydell 
(cherry picked from commit 9d2617ac7d3139d870ba14204aedd74395990192)
Signed-off-by: Michael Tokarev 
---
 target/arm/ptw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index bb22271a1d..0b16068557 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -266,7 +266,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate 
*ptw,
 if (unlikely(flags & TLB_INVALID_MASK)) {
 goto fail;
 }
-ptw->out_phys = full->phys_addr;
+ptw->out_phys = full->phys_addr | (addr & ~TARGET_PAGE_MASK);
 ptw->out_rw = full->prot & PAGE_WRITE;
 pte_attrs = full->pte_attrs;
 pte_secure = full->attrs.secure;
-- 
2.30.2




[PATCH 03/47] virtio-mem: Fix the bitmap index of the section offset

2023-03-08 Thread Michael Tokarev
From: Chenyi Qiang 

vmem->bitmap indexes the memory region of the virtio-mem backend at a
granularity of block_size. To calculate the index of target section offset,
the block_size should be divided instead of the bitmap_size.

Fixes: 2044969f0b ("virtio-mem: Implement RamDiscardManager interface")
Signed-off-by: Chenyi Qiang 
Message-Id: <20221216062231.11181-1-chenyi.qi...@intel.com>
Reviewed-by: David Hildenbrand 
Reviewed-by: Michael S. Tsirkin 
Cc: qemu-sta...@nongnu.org
Signed-off-by: David Hildenbrand 
(cherry picked from commit b11cf32e07a2f7ff0d171b89497381a04c9d07e0)
Signed-off-by: Michael Tokarev 
---
 hw/virtio/virtio-mem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index ed170def48..e19ee817fe 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -235,7 +235,7 @@ static int virtio_mem_for_each_plugged_section(const 
VirtIOMEM *vmem,
 uint64_t offset, size;
 int ret = 0;
 
-first_bit = s->offset_within_region / vmem->bitmap_size;
+first_bit = s->offset_within_region / vmem->block_size;
 first_bit = find_next_bit(vmem->bitmap, vmem->bitmap_size, first_bit);
 while (first_bit < vmem->bitmap_size) {
 MemoryRegionSection tmp = *s;
@@ -267,7 +267,7 @@ static int virtio_mem_for_each_unplugged_section(const 
VirtIOMEM *vmem,
 uint64_t offset, size;
 int ret = 0;
 
-first_bit = s->offset_within_region / vmem->bitmap_size;
+first_bit = s->offset_within_region / vmem->block_size;
 first_bit = find_next_zero_bit(vmem->bitmap, vmem->bitmap_size, first_bit);
 while (first_bit < vmem->bitmap_size) {
 MemoryRegionSection tmp = *s;
-- 
2.30.2




[PATCH 10/47] hw/nvme: fix missing cq eventidx update

2023-03-08 Thread Michael Tokarev
From: Klaus Jensen 

Prior to reading the shadow doorbell cq head, we have to update the
eventidx. Otherwise, we risk that the driver will skip an mmio doorbell
write. This happens on riscv64, as reported by Guenter.

Adding the missing update to the cq eventidx fixes the issue.

Fixes: 3f7fe8de3d49 ("hw/nvme: Implement shadow doorbell buffer support")
Cc: qemu-sta...@nongnu.org
Cc: qemu-ri...@nongnu.org
Reported-by: Guenter Roeck 
Reviewed-by: Keith Busch 
Signed-off-by: Klaus Jensen 
(cherry picked from commit fa5db2aa168bdc0f15c269b6212ef47632fab8ba)
Signed-off-by: Michael Tokarev 
---
 hw/nvme/ctrl.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 83f5e58e8d..366b973a9e 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -1331,6 +1331,15 @@ static inline void nvme_blk_write(BlockBackend *blk, 
int64_t offset,
 }
 }
 
+static void nvme_update_cq_eventidx(const NvmeCQueue *cq)
+{
+uint32_t v = cpu_to_le32(cq->head);
+
+//not in 7.2: trace_pci_nvme_update_cq_eventidx(cq->cqid, cq->head);
+
+pci_dma_write(PCI_DEVICE(cq->ctrl), cq->ei_addr, &v, sizeof(v));
+}
+
 static void nvme_update_cq_head(NvmeCQueue *cq)
 {
 uint32_t v;
@@ -1355,6 +1364,7 @@ static void nvme_post_cqes(void *opaque)
 hwaddr addr;
 
 if (n->dbbuf_enabled) {
+nvme_update_cq_eventidx(cq);
 nvme_update_cq_head(cq);
 }
 
-- 
2.30.2




[PATCH 44/47] intel-iommu: fail DEVIOTLB_UNMAP without dt mode

2023-03-08 Thread Michael Tokarev
From: Jason Wang 

Without dt mode, device IOTLB notifier won't work since guest won't
send device IOTLB invalidation descriptor in this case. Let's fail
early instead of misbehaving silently.

Reviewed-by: Laurent Vivier 
Tested-by: Laurent Vivier 
Tested-by: Viktor Prutyanov 
Buglink: https://bugzilla.redhat.com/2156876
Signed-off-by: Jason Wang 
Message-Id: <20230223065924.42503-3-jasow...@redhat.com>
Reviewed-by: Peter Xu 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
(cherry picked from commit 09adb0e021207b60a0c51a68939b4539d98d3ef3)
Signed-off-by: Michael Tokarev 
---
 hw/i386/intel_iommu.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 9143376677..d025ef2873 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -3179,6 +3179,7 @@ static int 
vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
 {
 VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
 IntelIOMMUState *s = vtd_as->iommu_state;
+X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
 
 /* TODO: add support for VFIO and vhost users */
 if (s->snoop_control) {
@@ -3193,6 +3194,13 @@ static int 
vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
  PCI_FUNC(vtd_as->devfn));
 return -ENOTSUP;
 }
+if (!x86_iommu->dt_supported && (new & IOMMU_NOTIFIER_DEVIOTLB_UNMAP)) {
+error_setg_errno(errp, ENOTSUP,
+ "device %02x.%02x.%x requires device IOTLB mode",
+ pci_bus_num(vtd_as->bus), PCI_SLOT(vtd_as->devfn),
+ PCI_FUNC(vtd_as->devfn));
+return -ENOTSUP;
+}
 
 /* Update per-address-space notifier flags */
 vtd_as->notifier_flags = new;
-- 
2.30.2




[PATCH 06/47] meson: accept relative symlinks in "meson introspect --installed" data

2023-03-08 Thread Michael Tokarev
From: Paolo Bonzini 

When installing shared libraries, as is the case for libvfio-user.so,
Meson will include relative symbolic links in the output of
"meson introspect --installed":

  {
"libvfio-user.so": "/usr/local/lib64/libvfio-user.so",
...
  }

In the case of scripts/symlink-install-tree.py, this will
be a symbolic link to a symbolic link but, in any case, there is
no issue in creating it.

Cc: qemu-sta...@nongnu.org
Signed-off-by: Paolo Bonzini 
(cherry picked from commit f32eb0021a85efaca97f69b0e9201737562a8e4f)
Signed-off-by: Michael Tokarev 
---
 scripts/symlink-install-tree.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/scripts/symlink-install-tree.py b/scripts/symlink-install-tree.py
index a5bf0b0d6d..67cb86dd52 100644
--- a/scripts/symlink-install-tree.py
+++ b/scripts/symlink-install-tree.py
@@ -17,7 +17,6 @@ def destdir_join(d1: str, d2: str) -> str:
 out = subprocess.run([*introspect.split(' '), '--installed'],
  stdout=subprocess.PIPE, check=True).stdout
 for source, dest in json.loads(out).items():
-assert os.path.isabs(source)
 bundle_dest = destdir_join('qemu-bundle', dest)
 path = os.path.dirname(bundle_dest)
 try:
-- 
2.30.2




[PATCH 17/47] migration/ram: Fix populate_read_range()

2023-03-08 Thread Michael Tokarev
From: David Hildenbrand 

Unfortunately, commit f7b9dcfbcf44 broke populate_read_range(): the loop
end condition is very wrong, resulting in that function not populating the
full range. Lets' fix that.

Fixes: f7b9dcfbcf44 ("migration/ram: Factor out populating pages readable in 
ram_block_populate_pages()")
Cc: qemu-sta...@nongnu.org
Reviewed-by: Peter Xu 
Reviewed-by: Juan Quintela 
Signed-off-by: David Hildenbrand 
Signed-off-by: Juan Quintela 
(cherry picked from commit 5f19a4491941fdc5c5b50ce4ade6e0f591b4)
Signed-off-by: Michael Tokarev 
---
 migration/ram.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/migration/ram.c b/migration/ram.c
index 8062713c75..f25ebd9620 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1765,13 +1765,15 @@ out:
 static inline void populate_read_range(RAMBlock *block, ram_addr_t offset,
ram_addr_t size)
 {
+const ram_addr_t end = offset + size;
+
 /*
  * We read one byte of each page; this will preallocate page tables if
  * required and populate the shared zeropage on MAP_PRIVATE anonymous 
memory
  * where no page was populated yet. This might require adaption when
  * supporting other mappings, like shmem.
  */
-for (; offset < size; offset += block->page_size) {
+for (; offset < end; offset += block->page_size) {
 char tmp = *((char *)block->host + offset);
 
 /* Don't optimize the read out */
-- 
2.30.2




[PATCH 04/47] virtio-mem: Fix the iterator variable in a vmem->rdl_list loop

2023-03-08 Thread Michael Tokarev
From: Chenyi Qiang 

It should be the variable rdl2 to revert the already-notified listeners.

Fixes: 2044969f0b ("virtio-mem: Implement RamDiscardManager interface")
Signed-off-by: Chenyi Qiang 
Message-Id: <20221228090312.17276-1-chenyi.qi...@intel.com>
Cc: qemu-sta...@nongnu.org
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: David Hildenbrand 
(cherry picked from commit 29f1b328e3b767cba2661920a8470738469b9e36)
Signed-off-by: Michael Tokarev 
---
 hw/virtio/virtio-mem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index e19ee817fe..56db586c89 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -341,7 +341,7 @@ static int virtio_mem_notify_plug(VirtIOMEM *vmem, uint64_t 
offset,
 if (ret) {
 /* Notify all already-notified listeners. */
 QLIST_FOREACH(rdl2, &vmem->rdl_list, next) {
-MemoryRegionSection tmp = *rdl->section;
+MemoryRegionSection tmp = *rdl2->section;
 
 if (rdl2 == rdl) {
 break;
-- 
2.30.2




  1   2   3   >