Re: [PATCH 2/2] target/riscv: fixes a bug against `ssamoswap` behavior in M-mode

2025-03-05 Thread Alistair Francis
On Tue, Feb 18, 2025 at 12:57 PM Deepak Gupta  wrote:
>
> Commit f06bfe3dc38c ("target/riscv: implement zicfiss instructions") adds
> `ssamoswap` instruction. `ssamoswap` takes the code-point from existing
> reserved encoding (and not a zimop like other shadow stack instructions).
> If shadow stack is not enabled (via xenvcfg.SSE), then `ssamoswap` must
> result in an illegal instruction exception. However there is a slightly
> modified behavior for M-mode.
>
> Shadow stack are not available in M-mode and all shadow stack instructions
> in M-mode exhibit zimop behavior. However, `ssamoswap` can still succeed
> if MPRV=1 and MPP is non-zero (see section 2.7 of zicfiss specification).
> This patch corrects that behavior for `ssamoswap`.

Section "22.2.3. Shadow Stack Memory Protection " of the latest priv
spec [1] seems to say: "When the effective privilege mode is M, any
memory access by an SSAMOSWAP.W/D
instruction will result in a store/AMO access-fault exception."

1: 
https://github.com/riscv/riscv-isa-manual/releases/tag/riscv-isa-release-9cfaf37-2025-03-06

Alistair

>
> Fixes: f06bfe3dc38c ("target/riscv: implement zicfiss instructions")
>
> Reported-by: Ved Shanbhogue 
> Signed-off-by: Deepak Gupta 
> ---
>  target/riscv/insn_trans/trans_rvzicfiss.c.inc | 13 +++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvzicfiss.c.inc 
> b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
> index e3ebc4977c..ec016cd70f 100644
> --- a/target/riscv/insn_trans/trans_rvzicfiss.c.inc
> +++ b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
> @@ -15,6 +15,13 @@
>   * You should have received a copy of the GNU General Public License along 
> with
>   * this program.  If not, see .
>   */
> +
> + #define REQUIRE_ZICFISS(ctx) do {   \
> +if (!ctx->cfg_ptr->ext_zicfiss) {\
> +return false;\
> +}\
> +} while (0)
> +
>  static bool trans_sspopchk(DisasContext *ctx, arg_sspopchk *a)
>  {
>  if (!ctx->bcfi_enabled) {
> @@ -77,7 +84,8 @@ static bool trans_ssrdp(DisasContext *ctx, arg_ssrdp *a)
>  static bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a)
>  {
>  REQUIRE_A_OR_ZAAMO(ctx);
> -if (!ctx->bcfi_enabled) {
> +REQUIRE_ZICFISS(ctx);
> +if ((ctx->priv != PRV_M) && !ctx->bcfi_enabled) {
>  return false;
>  }
>
> @@ -97,7 +105,8 @@ static bool trans_ssamoswap_d(DisasContext *ctx, 
> arg_amoswap_w *a)
>  {
>  REQUIRE_64BIT(ctx);
>  REQUIRE_A_OR_ZAAMO(ctx);
> -if (!ctx->bcfi_enabled) {
> +REQUIRE_ZICFISS(ctx);
> +if ((ctx->priv != PRV_M) && !ctx->bcfi_enabled) {
>  return false;
>  }
>
> --
> 2.34.1
>
>



[PATCH v7 0/6] Specifying cache topology on ARM

2025-03-05 Thread Alireza Sanaee via
Specifying the cache layout in virtual machines is useful for
applications and operating systems to fetch accurate information about
the cache structure and make appropriate adjustments. Enforcing correct
sharing information can lead to better optimizations. This patch enables
the specification of cache layout through a command line parameter,
building on a patch set by Intel [1,2,3]. It uses this set as a
foundation.  The device tree and ACPI/PPTT table, and device tree are
populated based on user-provided information and CPU topology.

Example:


++++
|Socket 0||Socket 1|
|(L3 Cache)  ||(L3 Cache)  |
++---+++---+
 | |
++++++
|   Cluster 0 ||   Cluster 0 |
|   (L2 Cache)||   (L2 Cache)|
++++++
 | |
+++  ++++++  +++
|   Core 0 | |   Core 1||   Core 0|  |   Core 1|
|   (L1i, L1d) | |   (L1i, L1d)||   (L1i, L1d)|  |   (L1i, L1d)|
+++  ++++++  +++
 |   |   |   |
++  ++  ++  ++
|Thread 0|  |Thread 1|  |Thread 1|  |Thread 0|
++  ++  ++  ++
|Thread 1|  |Thread 0|  |Thread 0|  |Thread 1|
++  ++  ++  ++


The following command will represent the system relying on **ACPI PPTT tables**.

./qemu-system-aarch64 \
 -machine 
virt,smp-cache.0.cache=l1i,smp-cache.0.topology=core,smp-cache.1.cache=l1d,smp-cache.1.topology=core,smp-cache.2.cache=l2,smp-cache.2.topology=cluseter,smp-cache.3.cache=l3,smp-cache.3.topology=socket
 \
 -cpu max \
 -m 2048 \
 -smp sockets=2,clusters=1,cores=2,threads=2 \
 -kernel ./Image.gz \
 -append "console=ttyAMA0 root=/dev/ram rdinit=/init acpi=force" \
 -initrd rootfs.cpio.gz \
 -bios ./edk2-aarch64-code.fd \
 -nographic

The following command will represent the system relying on **the device tree**.

./qemu-system-aarch64 \
 -machine 
virt,smp-cache.0.cache=l1i,smp-cache.0.topology=core,smp-cache.1.cache=l1d,smp-cache.1.topology=core,smp-cache.2.cache=l2,smp-cache.2.topology=cluseter,smp-cache.3.cache=l3,smp-cache.3.topology=socket
 \
 -cpu max \
 -m 2048 \
 -smp sockets=2,clusters=1,cores=2,threads=2 \
 -kernel ./Image.gz \
 -append "console=ttyAMA0 root=/dev/ram rdinit=/init acpi=off" \
 -initrd rootfs.cpio.gz \
 -nographic

Failure cases:
1) There are scenarios where caches exist in systems' registers but
left unspecified by users. In this case qemu returns failure.

2) SMT threads cannot share caches which is not very common. More
discussions here [4].

Currently only three levels of caches are supported to be specified from
the command line. However, increasing the value does not require
significant changes. Further, this patch assumes l2 and l3 unified
caches and does not allow l(2/3)(i/d). The level terminology is
thread/core/cluster/socket right now. Hierarchy assumed in this patch:
Socket level = Cluster level + 1 = Core level + 2 = Thread level + 3;

TODO:
  1) Making the code to work with arbitrary levels
  2) Separated data and instruction cache at L2 and L3.
  3) Additional cache controls.  e.g. size of L3 may not want to just
  match the underlying system, because only some of the associated host
  CPUs may be bound to this VM.

[1] https://lore.kernel.org/kvm/20240908125920.1160236-1-zhao1@intel.com/
[2] 
https://lore.kernel.org/qemu-devel/20241101083331.340178-1-zhao1@intel.com/
[3] 
https://lore.kernel.org/qemu-devel/20250110145115.1574345-1-zhao1@intel.com/
[4] 
https://lore.kernel.org/devicetree-spec/20250203120527.3534-1-alireza.san...@huawei.com/

Change Log:
  v6->v7:
   * Intel stuff got pulled up, so rebase.
   * added some discussions on device tree.

  v5->v6:
   * Minor bug fix.
   * rebase based on new Intel patchset.
 - 
https://lore.kernel.org/qemu-devel/20250110145115.1574345-1-zhao1@intel.com/

  v4->v5:
* Added Reviewed-by tags.
* Applied some comments.

  v3->v4:
* Device tree added.

Depends-on: Building PPTT with root node and identical implementation flag
Depends-on: Msg-id: 20250306023342.508-1-alireza.san...@huawei.com

Alireza Sanaee (6):
  target/arm/tcg: increase cache level for cpu=max
  arm/virt.c: add cache hierarchy to device tree
  bio

[PATCH v7 1/6] target/arm/tcg: increase cache level for cpu=max

2025-03-05 Thread Alireza Sanaee via
This patch addresses cache description in the `aarch64_max_tcg_initfn`
function for cpu=max. It introduces three layers of caches and modifies
the cache description registers accordingly.

Signed-off-by: Alireza Sanaee 
Reviewed-by: Jonathan Cameron 
---
 target/arm/tcg/cpu64.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 29ab0ac79d..1405506594 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -1086,6 +1086,19 @@ void aarch64_max_tcg_initfn(Object *obj)
 uint64_t t;
 uint32_t u;
 
+/*
+ * Expanded cache set
+ */
+cpu->clidr = 0x8200123; /* 4 4 3 in 3 bit fields */
+/* 64KB L1 dcache */
+cpu->ccsidr[0] = make_ccsidr(CCSIDR_FORMAT_LEGACY, 4, 64, 64 * KiB, 7);
+/* 64KB L1 icache */
+cpu->ccsidr[1] = make_ccsidr(CCSIDR_FORMAT_LEGACY, 4, 64, 64 * KiB, 2);
+/* 1MB L2 unified cache */
+cpu->ccsidr[2] = make_ccsidr(CCSIDR_FORMAT_LEGACY, 8, 64, 1 * MiB, 7);
+/* 2MB L3 unified cache */
+cpu->ccsidr[4] = make_ccsidr(CCSIDR_FORMAT_LEGACY, 8, 64, 2 * MiB, 7);
+
 /*
  * Unset ARM_FEATURE_BACKCOMPAT_CNTFRQ, which we would otherwise default
  * to because we started with aarch64_a57_initfn(). A 'max' CPU might
-- 
2.43.0




[PATCH v7 2/6] arm/virt.c: add cache hierarchy to device tree

2025-03-05 Thread Alireza Sanaee via
Specify which layer (core/cluster/socket) caches found at in the CPU
topology. Updating cache topology to device tree (spec v0.4).
Example:

Here, 2 sockets (packages), and 2 clusters, 4 cores and 2 threads
created, in aggregate 2*2*4*2 logical cores. In the smp-cache object,
cores will have l1d and l1i.  However, extending this is not difficult).
The clusters will share a unified l2 level cache, and finally sockets
will share l3. In this patch, threads will share l1 caches by default,
but this can be adjusted if case required.

Currently only three levels of caches are supported.  The patch does not
allow partial declaration of caches. In another word, all caches must be
defined or caches must be skipped.

./qemu-system-aarch64 \
-machine virt,\
 smp-cache.0.cache=l1i,smp-cache.0.topology=core,\
 smp-cache.1.cache=l1d,smp-cache.1.topology=core,\
 smp-cache.2.cache=l2,smp-cache.2.topology=cluster,\
 smp-cache.3.cache=l3,smp-cache.3.topology=socket\
-cpu max \
-m 2048 \
-smp sockets=2,clusters=2,cores=4,threads=1 \
-kernel ./Image.gz \
-append "console=ttyAMA0 root=/dev/ram rdinit=/init acpi=force" \
-initrd rootfs.cpio.gz \
-bios ./edk2-aarch64-code.fd \
-nographic

For instance, following device tree will be generated for a scenario
where we have 2 sockets, 2 clusters, 2 cores and 2 threads, in total 16
PEs. L1i and L1d are private to each thread, and l2 and l3 are shared at
socket level as an example.

Limitation: SMT cores cannot share L1 cache for now. This
problem does not exist in PPTT tables.

Signed-off-by: Alireza Sanaee 
Co-developed-by: Jonathan Cameron 
Signed-off-by: Jonathan Cameron 
---
 hw/arm/virt.c | 350 ++
 hw/cpu/core.c |  92 +++
 include/hw/arm/virt.h |   4 +
 include/hw/cpu/core.h |  26 
 4 files changed, 472 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index ee69081ef4..3fd05f312d 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -237,6 +237,132 @@ static const int a15irqmap[] = {
 [VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
 };
 
+unsigned int virt_get_caches(const VirtMachineState *vms,
+ PPTTCPUCaches *caches)
+{
+ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0)); /* assume homogeneous CPUs */
+bool ccidx = cpu_isar_feature(any_ccidx, armcpu);
+unsigned int num_cache, i;
+int level_instr = 1, level_data = 1;
+
+for (i = 0, num_cache = 0; i < CPU_MAX_CACHES; i++, num_cache++) {
+int type = (armcpu->clidr >> (3 * i)) & 7;
+int bank_index;
+int level;
+PPTTCPUCacheType cache_type;
+
+if (type == 0) {
+break;
+}
+
+switch (type) {
+case 1:
+cache_type = INSTRUCTION;
+level = level_instr;
+break;
+case 2:
+cache_type = DATA;
+level = level_data;
+break;
+case 4:
+cache_type = UNIFIED;
+level = level_instr > level_data ? level_instr : level_data;
+break;
+case 3: /* Split - Do data first */
+cache_type = DATA;
+level = level_data;
+break;
+default:
+error_setg(&error_abort, "Unrecognized cache type");
+return 0;
+}
+/*
+ * ccsidr is indexed using both the level and whether it is
+ * an instruction cache. Unified caches use the same storage
+ * as data caches.
+ */
+bank_index = (i * 2) | ((type == 1) ? 1 : 0);
+if (ccidx) {
+caches[num_cache] = (PPTTCPUCaches) {
+.type =  cache_type,
+.level = level,
+.linesize = 1 << (FIELD_EX64(armcpu->ccsidr[bank_index],
+ CCSIDR_EL1,
+ CCIDX_LINESIZE) + 4),
+.associativity = FIELD_EX64(armcpu->ccsidr[bank_index],
+CCSIDR_EL1,
+CCIDX_ASSOCIATIVITY) + 1,
+.sets = FIELD_EX64(armcpu->ccsidr[bank_index], CCSIDR_EL1,
+   CCIDX_NUMSETS) + 1,
+};
+} else {
+caches[num_cache] = (PPTTCPUCaches) {
+.type =  cache_type,
+.level = level,
+.linesize = 1 << (FIELD_EX64(armcpu->ccsidr[bank_index],
+ CCSIDR_EL1, LINESIZE) + 4),
+.associativity = FIELD_EX64(armcpu->ccsidr[bank_index],
+CCSIDR_EL1,
+ASSOCIATIVITY) + 1,
+.sets = FIELD_EX64(armcpu->ccsidr[bank_index], CCSIDR_EL1,
+   NUMSETS) + 1,
+};
+}
+caches[num_cache].size =

Re: [PATCH v2 1/2] target/riscv: Add scontext CSR handling

2025-03-05 Thread Alistair Francis
On Thu, Mar 6, 2025 at 3:48 PM Alistair Francis  wrote:
>
> On Mon, Mar 3, 2025 at 7:39 PM Florian Lugou
>  wrote:
> >
> > scontext size is 16 bits on RV32 and 32 bits on RV64, as recommended by
> > version 1.0 2025-02-21 of the debug specification.
>
> Section 5.7.8 indicates the register is XLEN bits wide, with data
> being 32-bits wide for both RV32 and RV64.

Note that QEMU supports the ratified 0.13 debug spec [1] (plus
mcontrol6), where scontext.data is XLEN bits wide, so that's what will
need to be done here.

If you want to support the new debug spec that's also fine, but we
need a way to expose that to users and ensure the spec is supported.

1: https://github.com/riscv/riscv-debug-spec/releases/tag/task_group_vote

Alistair

>
> Alistair
>
> >
> > When the Smstateen extension is implemented, accessibility to the
> > scontext CSR is controlled by bit 57 of the [mh]stateen0 CSRs.
> >
> > Signed-off-by: Florian Lugou 
> > ---
> >  target/riscv/cpu.h  |  1 +
> >  target/riscv/cpu_bits.h |  5 +
> >  target/riscv/csr.c  | 36 
> >  target/riscv/debug.c|  1 +
> >  4 files changed, 43 insertions(+)
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 616c3bdc1c..102e8285a6 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -440,6 +440,7 @@ struct CPUArchState {
> >  target_ulong tdata2[RV_MAX_TRIGGERS];
> >  target_ulong tdata3[RV_MAX_TRIGGERS];
> >  target_ulong mcontext;
> > +target_ulong scontext;
> >  struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
> >  struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
> >  QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index a30317c617..e8997f3153 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > @@ -258,6 +258,9 @@
> >  /* VS-Level Control transfer records CSRs */
> >  #define CSR_VSCTRCTL0x24e
> >
> > +/* Supervisor-Level Sdtrig CSRs (debug) */
> > +#define CSR_SCONTEXT0x5a8
> > +
> >  /* Hpervisor CSRs */
> >  #define CSR_HSTATUS 0x600
> >  #define CSR_HEDELEG 0x602
> > @@ -1103,4 +1106,6 @@ typedef enum CTRType {
> >  #define MCONTEXT64 0x1FFFULL
> >  #define MCONTEXT32_HCONTEXT0x007F
> >  #define MCONTEXT64_HCONTEXT0x3FFFULL
> > +#define SCONTEXT32 0x
> > +#define SCONTEXT64 0xULL
> >  #endif
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 0ebcca4597..37b38f24a6 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -3393,6 +3393,10 @@ static RISCVException write_mstateen0(CPURISCVState 
> > *env, int csrno,
> >  wr_mask |= SMSTATEEN0_P1P13;
> >  }
> >
> > +if (riscv_cpu_cfg(env)->debug) {
> > +wr_mask |= SMSTATEEN0_HSCONTXT;
> > +}
> > +
> >  if (riscv_cpu_cfg(env)->ext_smaia || riscv_cpu_cfg(env)->ext_smcsrind) 
> > {
> >  wr_mask |= SMSTATEEN0_SVSLCT;
> >  }
> > @@ -5321,6 +5325,35 @@ static RISCVException write_mcontext(CPURISCVState 
> > *env, int csrno,
> >  return RISCV_EXCP_NONE;
> >  }
> >
> > +static RISCVException read_scontext(CPURISCVState *env, int csrno,
> > +target_ulong *val)
> > +{
> > +RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSCONTXT);
> > +if (ret != RISCV_EXCP_NONE) {
> > +return ret;
> > +}
> > +
> > +*val = env->scontext;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException write_scontext(CPURISCVState *env, int csrno,
> > + target_ulong val)
> > +{
> > +bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
> > +
> > +RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSCONTXT);
> > +if (ret != RISCV_EXCP_NONE) {
> > +return ret;
> > +}
> > +
> > +/* Spec suggest 16-bit for RV32 and 34-bit for RV64 */
> > +target_ulong mask = rv32 ? SCONTEXT32 : SCONTEXT64;
> > +
> > +env->scontext = val & mask;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> >  static RISCVException read_mnscratch(CPURISCVState *env, int csrno,
> >   target_ulong *val)
> >  {
> > @@ -5973,6 +6006,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> >  [CSR_SIEH]   = { "sieh",   aia_smode32, NULL, NULL, rmw_sieh },
> >  [CSR_SIPH]   = { "siph",   aia_smode32, NULL, NULL, rmw_siph },
> >
> > +/* Supervisor-Level Sdtrig CSRs (debug) */
> > +[CSR_SCONTEXT]   = { "scontext", debug, read_scontext, write_scontext 
> > },
> > +
> >  [CSR_HSTATUS] = { "hstatus", hmode,   read_hstatus, 
> > write_hstatus,
> >.min_priv_ver = PRIV_VERSION_1_12_0  
> >   },
> >  [CSR_HEDELEG] = { "hedeleg", hm

[PATCH v7 3/6] bios-tables-test: prepare to change ARM ACPI virt PPTT

2025-03-05 Thread Alireza Sanaee via
Prepare to update `build_pptt` function to add cache description
functionalities, thus add binaries in this patch.

Signed-off-by: Alireza Sanaee 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..ba2a8180e9 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,2 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/aarch64/virt/PPTT.topology",
-- 
2.43.0




[PATCH v7 5/6] tests/qtest/bios-table-test: testing new ARM ACPI PPTT topology

2025-03-05 Thread Alireza Sanaee via
Test new PPTT topolopy with cache representation.

Signed-off-by: Alireza Sanaee 
Reviewed-by: Jonathan Cameron 
---
 tests/qtest/bios-tables-test.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 0a333ec435..6bdc25f4df 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -2142,6 +2142,10 @@ static void test_acpi_aarch64_virt_tcg_topology(void)
 };
 
 test_acpi_one("-cpu cortex-a57 "
+  "-M virt,smp-cache.0.cache=l1i,smp-cache.0.topology=cluster,"
+  "smp-cache.1.cache=l1d,smp-cache.1.topology=cluster,"
+  "smp-cache.2.cache=l2,smp-cache.2.topology=cluster,"
+  "smp-cache.3.cache=l3,smp-cache.3.topology=cluster "
   "-smp sockets=1,clusters=2,cores=2,threads=2", &data);
 free_test_data(&data);
 }
-- 
2.43.0




Re: [PATCH 2/2] target/riscv: fixes a bug against `ssamoswap` behavior in M-mode

2025-03-05 Thread Alistair Francis
On Thu, Mar 6, 2025 at 4:13 PM Deepak Gupta  wrote:
>
> On Thu, Mar 06, 2025 at 03:29:00PM +1000, Alistair Francis wrote:
> >On Tue, Feb 18, 2025 at 12:57 PM Deepak Gupta  wrote:
> >>
> >> Commit f06bfe3dc38c ("target/riscv: implement zicfiss instructions") adds
> >> `ssamoswap` instruction. `ssamoswap` takes the code-point from existing
> >> reserved encoding (and not a zimop like other shadow stack instructions).
> >> If shadow stack is not enabled (via xenvcfg.SSE), then `ssamoswap` must
> >> result in an illegal instruction exception. However there is a slightly
> >> modified behavior for M-mode.
> >>
> >> Shadow stack are not available in M-mode and all shadow stack instructions
> >> in M-mode exhibit zimop behavior. However, `ssamoswap` can still succeed
> >> if MPRV=1 and MPP is non-zero (see section 2.7 of zicfiss specification).
> >> This patch corrects that behavior for `ssamoswap`.
> >
> >Section "22.2.3. Shadow Stack Memory Protection " of the latest priv
> >spec [1] seems to say: "When the effective privilege mode is M, any
> >memory access by an SSAMOSWAP.W/D
> >instruction will result in a store/AMO access-fault exception."
>
> Hmm I didn't look at priv spec. Let me fix this one.

I hope the two don't conflict, that will be a nightmare

Alistair

>
> >
> >1: 
> >https://github.com/riscv/riscv-isa-manual/releases/tag/riscv-isa-release-9cfaf37-2025-03-06
> >
> >Alistair
> >
> >>
> >> Fixes: f06bfe3dc38c ("target/riscv: implement zicfiss instructions")
> >>
> >> Reported-by: Ved Shanbhogue 
> >> Signed-off-by: Deepak Gupta 
> >> ---
> >>  target/riscv/insn_trans/trans_rvzicfiss.c.inc | 13 +++--
> >>  1 file changed, 11 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/target/riscv/insn_trans/trans_rvzicfiss.c.inc 
> >> b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
> >> index e3ebc4977c..ec016cd70f 100644
> >> --- a/target/riscv/insn_trans/trans_rvzicfiss.c.inc
> >> +++ b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
> >> @@ -15,6 +15,13 @@
> >>   * You should have received a copy of the GNU General Public License 
> >> along with
> >>   * this program.  If not, see .
> >>   */
> >> +
> >> + #define REQUIRE_ZICFISS(ctx) do {   \
> >> +if (!ctx->cfg_ptr->ext_zicfiss) {\
> >> +return false;\
> >> +}\
> >> +} while (0)
> >> +
> >>  static bool trans_sspopchk(DisasContext *ctx, arg_sspopchk *a)
> >>  {
> >>  if (!ctx->bcfi_enabled) {
> >> @@ -77,7 +84,8 @@ static bool trans_ssrdp(DisasContext *ctx, arg_ssrdp *a)
> >>  static bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a)
> >>  {
> >>  REQUIRE_A_OR_ZAAMO(ctx);
> >> -if (!ctx->bcfi_enabled) {
> >> +REQUIRE_ZICFISS(ctx);
> >> +if ((ctx->priv != PRV_M) && !ctx->bcfi_enabled) {
> >>  return false;
> >>  }
> >>
> >> @@ -97,7 +105,8 @@ static bool trans_ssamoswap_d(DisasContext *ctx, 
> >> arg_amoswap_w *a)
> >>  {
> >>  REQUIRE_64BIT(ctx);
> >>  REQUIRE_A_OR_ZAAMO(ctx);
> >> -if (!ctx->bcfi_enabled) {
> >> +REQUIRE_ZICFISS(ctx);
> >> +if ((ctx->priv != PRV_M) && !ctx->bcfi_enabled) {
> >>  return false;
> >>  }
> >>
> >> --
> >> 2.34.1
> >>
> >>



Re: [PATCH v2 2/2] target/riscv: Support matching scontext in Sdtrig's textra CSRs

2025-03-05 Thread Alistair Francis
On Mon, Mar 3, 2025 at 7:38 PM Florian Lugou
 wrote:
>
> Support setting textra32.sselect or textra64.sselect to 1 (scontext).
> The trigger will only match if the content of scontext matches the value
> in svalue, after it is masked as configured in sbytemask.

I don't think this matches the 0.13 debug spec [1].

If we want to support the newly ratified 1.0 spec as well we need to
communicate that to users. Ideally we want to support both versions
and let users choose, but it might be ok to just drop 0.13, as I get
the feeling it should not have been ratified.

1: https://github.com/riscv/riscv-debug-spec/releases/tag/task_group_vote

Alistair

>
> Signed-off-by: Florian Lugou 
> ---
>  target/riscv/debug.c | 75 +++-
>  target/riscv/debug.h |  3 ++
>  2 files changed, 57 insertions(+), 21 deletions(-)
>
> diff --git a/target/riscv/debug.c b/target/riscv/debug.c
> index 072593ab12..a64dadf6d6 100644
> --- a/target/riscv/debug.c
> +++ b/target/riscv/debug.c
> @@ -219,8 +219,8 @@ static inline void warn_always_zero_bit(target_ulong val, 
> target_ulong mask,
>
>  static target_ulong textra_validate(CPURISCVState *env, target_ulong tdata3)
>  {
> -target_ulong mhvalue, mhselect;
> -target_ulong mhselect_new;
> +target_ulong mhvalue, mhselect, sbytemask, svalue, sselect;
> +target_ulong mhselect_new, sselect_new;
>  target_ulong textra;
>  const uint32_t mhselect_no_rvh[8] = { 0, 0, 0, 0, 4, 4, 4, 4 };
>
> @@ -228,25 +228,17 @@ static target_ulong textra_validate(CPURISCVState *env, 
> target_ulong tdata3)
>  case MXL_RV32:
>  mhvalue  = get_field(tdata3, TEXTRA32_MHVALUE);
>  mhselect = get_field(tdata3, TEXTRA32_MHSELECT);
> -/* Validate unimplemented (always zero) bits */
> -warn_always_zero_bit(tdata3, (target_ulong)TEXTRA32_SBYTEMASK,
> - "sbytemask");
> -warn_always_zero_bit(tdata3, (target_ulong)TEXTRA32_SVALUE,
> - "svalue");
> -warn_always_zero_bit(tdata3, (target_ulong)TEXTRA32_SSELECT,
> - "sselect");
> +sbytemask  = get_field(tdata3, TEXTRA32_SBYTEMASK);
> +svalue  = get_field(tdata3, TEXTRA32_SVALUE);
> +sselect = get_field(tdata3, TEXTRA32_SSELECT);
>  break;
>  case MXL_RV64:
>  case MXL_RV128:
>  mhvalue  = get_field(tdata3, TEXTRA64_MHVALUE);
>  mhselect = get_field(tdata3, TEXTRA64_MHSELECT);
> -/* Validate unimplemented (always zero) bits */
> -warn_always_zero_bit(tdata3, (target_ulong)TEXTRA64_SBYTEMASK,
> - "sbytemask");
> -warn_always_zero_bit(tdata3, (target_ulong)TEXTRA64_SVALUE,
> - "svalue");
> -warn_always_zero_bit(tdata3, (target_ulong)TEXTRA64_SSELECT,
> - "sselect");
> +sbytemask  = get_field(tdata3, TEXTRA64_SBYTEMASK);
> +svalue  = get_field(tdata3, TEXTRA64_SVALUE);
> +sselect = get_field(tdata3, TEXTRA64_SSELECT);
>  break;
>  default:
>  g_assert_not_reached();
> @@ -258,17 +250,34 @@ static target_ulong textra_validate(CPURISCVState *env, 
> target_ulong tdata3)
>  qemu_log_mask(LOG_UNIMP, "mhselect only supports 0 or 4 for now\n");
>  }
>
> +/* Validate sselect. */
> +switch (sselect) {
> +case SSELECT_IGNORE:
> +case SSELECT_SCONTEXT:
> +sselect_new = sselect;
> +break;
> +default:
> +sselect_new = 0;
> +qemu_log_mask(LOG_UNIMP, "sselect only supports 0 or 1 for now\n");
> +}
> +
>  /* Write legal values into textra */
>  textra = 0;
>  switch (riscv_cpu_mxl(env)) {
>  case MXL_RV32:
> -textra = set_field(textra, TEXTRA32_MHVALUE,  mhvalue);
> -textra = set_field(textra, TEXTRA32_MHSELECT, mhselect_new);
> +textra = set_field(textra, TEXTRA32_MHVALUE,   mhvalue);
> +textra = set_field(textra, TEXTRA32_MHSELECT,  mhselect_new);
> +textra = set_field(textra, TEXTRA32_SBYTEMASK, sbytemask);
> +textra = set_field(textra, TEXTRA32_SVALUE,svalue);
> +textra = set_field(textra, TEXTRA32_SSELECT,   sselect_new);
>  break;
>  case MXL_RV64:
>  case MXL_RV128:
> -textra = set_field(textra, TEXTRA64_MHVALUE,  mhvalue);
> -textra = set_field(textra, TEXTRA64_MHSELECT, mhselect_new);
> +textra = set_field(textra, TEXTRA64_MHVALUE,   mhvalue);
> +textra = set_field(textra, TEXTRA64_MHSELECT,  mhselect_new);
> +textra = set_field(textra, TEXTRA64_SBYTEMASK, sbytemask);
> +textra = set_field(textra, TEXTRA64_SVALUE,svalue);
> +textra = set_field(textra, TEXTRA64_SSELECT,   sselect_new);
>  break;
>  default:
>  g_assert_not_reached();
> @@ -368,7 +377,7 @@ static bool trigger_textra_match(CPURISCVState *env, 
> trigger_type_t type,
>   

[PATCH v6 3/4] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64()

2025-03-05 Thread Akihiko Odaki
DEFINE_PROP_ON_OFF_AUTO_BIT64() corresponds to DEFINE_PROP_ON_OFF_AUTO()
as DEFINE_PROP_BIT64() corresponds to DEFINE_PROP_BOOL(). The difference
is that DEFINE_PROP_ON_OFF_AUTO_BIT64() exposes OnOffAuto instead of
bool.

Signed-off-by: Akihiko Odaki 
---
 include/hw/qdev-properties.h | 18 
 hw/core/qdev-properties.c| 66 +++-
 2 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 
bf27375a3ccdb238ef3327dd85d3d0a1431cbfbf..0d161325e8dc92d0e0e5aa9a1e2dd734f7a55cae
 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -43,11 +43,22 @@ struct PropertyInfo {
 ObjectPropertyRelease *release;
 };
 
+/**
+ * struct OnOffAutoBit64 - OnOffAuto storage with 64 elements.
+ * @on_bits: Bitmap of elements with "on".
+ * @auto_bits: Bitmap of elements with "auto".
+ */
+typedef struct OnOffAutoBit64 {
+uint64_t on_bits;
+uint64_t auto_bits;
+} OnOffAutoBit64;
+
 
 /*** qdev-properties.c ***/
 
 extern const PropertyInfo qdev_prop_bit;
 extern const PropertyInfo qdev_prop_bit64;
+extern const PropertyInfo qdev_prop_on_off_auto_bit64;
 extern const PropertyInfo qdev_prop_bool;
 extern const PropertyInfo qdev_prop_enum;
 extern const PropertyInfo qdev_prop_uint8;
@@ -100,6 +111,13 @@ extern const PropertyInfo qdev_prop_link;
 .set_default = true,  \
 .defval.u  = (bool)_defval)
 
+#define DEFINE_PROP_ON_OFF_AUTO_BIT64(_name, _state, _field, _bit, _defval) \
+DEFINE_PROP(_name, _state, _field, qdev_prop_on_off_auto_bit64, \
+OnOffAutoBit64, \
+.bitnr= (_bit), \
+.set_default = true,\
+.defval.i = (OnOffAuto)_defval)
+
 #define DEFINE_PROP_BOOL(_name, _state, _field, _defval) \
 DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool, \
 .set_default = true, \
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 
3462921841db74456284b91374955b6101f03bbc..54fbcc9fa8d4b66003d9a66b1e6af61684c59ae4
 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -188,7 +188,8 @@ const PropertyInfo qdev_prop_bit = {
 
 static uint64_t qdev_get_prop_mask64(const Property *prop)
 {
-assert(prop->info == &qdev_prop_bit64);
+assert(prop->info == &qdev_prop_bit64 ||
+   prop->info == &qdev_prop_on_off_auto_bit64);
 return 0x1ull << prop->bitnr;
 }
 
@@ -233,6 +234,69 @@ const PropertyInfo qdev_prop_bit64 = {
 .set_default_value = set_default_value_bool,
 };
 
+static void prop_get_on_off_auto_bit64(Object *obj, Visitor *v,
+   const char *name, void *opaque,
+   Error **errp)
+{
+Property *prop = opaque;
+OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop);
+OnOffAuto value;
+uint64_t mask = qdev_get_prop_mask64(prop);
+
+if (p->auto_bits & mask) {
+value = ON_OFF_AUTO_AUTO;
+} else if (p->on_bits & mask) {
+value = ON_OFF_AUTO_ON;
+} else {
+value = ON_OFF_AUTO_OFF;
+}
+
+visit_type_OnOffAuto(v, name, &value, errp);
+}
+
+static void prop_set_on_off_auto_bit64(Object *obj, Visitor *v,
+   const char *name, void *opaque,
+   Error **errp)
+{
+Property *prop = opaque;
+OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop);
+OnOffAuto value;
+uint64_t mask = qdev_get_prop_mask64(prop);
+
+if (!visit_type_OnOffAuto(v, name, &value, errp)) {
+return;
+}
+
+switch (value) {
+case ON_OFF_AUTO_AUTO:
+p->on_bits &= ~mask;
+p->auto_bits |= mask;
+break;
+
+case ON_OFF_AUTO_ON:
+p->on_bits |= mask;
+p->auto_bits &= ~mask;
+break;
+
+case ON_OFF_AUTO_OFF:
+p->on_bits &= ~mask;
+p->auto_bits &= ~mask;
+break;
+
+case ON_OFF_AUTO__MAX:
+g_assert_not_reached();
+}
+}
+
+const PropertyInfo qdev_prop_on_off_auto_bit64 = {
+.name  = "OnOffAuto",
+.description = "on/off/auto",
+.enum_table = &OnOffAuto_lookup,
+.get = prop_get_on_off_auto_bit64,
+.set = prop_set_on_off_auto_bit64,
+.set_default_value = qdev_propinfo_set_default_value_enum,
+};
+
 /* --- bool --- */
 
 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,

-- 
2.48.1




Re: [PATCH] target/riscv: rvv: Fix incorrect vlen comparison in prop_vlen_set

2025-03-05 Thread Michael Tokarev

06.03.2025 09:28, Michael Tokarev wrote:


... how important it is to pick it up for 8.2 and 7.2 series,
where the patch does not apply directly?


Scratch this.  It is applicable for 9.2 only (from the currently
active stable series), b/c it fixes a commit after 8.2

Thanks,

/mjt



[PATCH 3/7] hw/hyperv/vmbus: common compilation unit

2025-03-05 Thread Pierrick Bouvier
Replace TARGET_PAGE.* by runtime calls.

Signed-off-by: Pierrick Bouvier 
---
 hw/hyperv/vmbus.c | 50 +--
 hw/hyperv/meson.build |  2 +-
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c
index 12a7dc43128..109ac319caf 100644
--- a/hw/hyperv/vmbus.c
+++ b/hw/hyperv/vmbus.c
@@ -18,7 +18,7 @@
 #include "hw/hyperv/vmbus.h"
 #include "hw/hyperv/vmbus-bridge.h"
 #include "hw/sysbus.h"
-#include "cpu.h"
+#include "exec/target_page.h"
 #include "trace.h"
 
 enum {
@@ -309,7 +309,7 @@ void vmbus_put_gpadl(VMBusGpadl *gpadl)
 
 uint32_t vmbus_gpadl_len(VMBusGpadl *gpadl)
 {
-return gpadl->num_gfns * TARGET_PAGE_SIZE;
+return gpadl->num_gfns * qemu_target_page_size();
 }
 
 static void gpadl_iter_init(GpadlIter *iter, VMBusGpadl *gpadl,
@@ -323,14 +323,14 @@ static void gpadl_iter_init(GpadlIter *iter, VMBusGpadl 
*gpadl,
 
 static inline void gpadl_iter_cache_unmap(GpadlIter *iter)
 {
-uint32_t map_start_in_page = (uintptr_t)iter->map & ~TARGET_PAGE_MASK;
-uint32_t io_end_in_page = ((iter->last_off - 1) & ~TARGET_PAGE_MASK) + 1;
+uint32_t map_start_in_page = (uintptr_t)iter->map & 
~qemu_target_page_mask();
+uint32_t io_end_in_page = ((iter->last_off - 1) & 
~qemu_target_page_mask()) + 1;
 
 /* mapping is only done to do non-zero amount of i/o */
 assert(iter->last_off > 0);
 assert(map_start_in_page < io_end_in_page);
 
-dma_memory_unmap(iter->as, iter->map, TARGET_PAGE_SIZE - map_start_in_page,
+dma_memory_unmap(iter->as, iter->map, qemu_target_page_size() - 
map_start_in_page,
  iter->dir, io_end_in_page - map_start_in_page);
 }
 
@@ -348,17 +348,17 @@ static ssize_t gpadl_iter_io(GpadlIter *iter, void *buf, 
uint32_t len)
 assert(iter->active);
 
 while (len) {
-uint32_t off_in_page = iter->off & ~TARGET_PAGE_MASK;
-uint32_t pgleft = TARGET_PAGE_SIZE - off_in_page;
+uint32_t off_in_page = iter->off & ~qemu_target_page_mask();
+uint32_t pgleft = qemu_target_page_size() - off_in_page;
 uint32_t cplen = MIN(pgleft, len);
 void *p;
 
 /* try to reuse the cached mapping */
 if (iter->map) {
 uint32_t map_start_in_page =
-(uintptr_t)iter->map & ~TARGET_PAGE_MASK;
-uint32_t off_base = iter->off & ~TARGET_PAGE_MASK;
-uint32_t mapped_base = (iter->last_off - 1) & ~TARGET_PAGE_MASK;
+(uintptr_t)iter->map & ~qemu_target_page_mask();
+uint32_t off_base = iter->off & ~qemu_target_page_mask();
+uint32_t mapped_base = (iter->last_off - 1) & 
~qemu_target_page_mask();
 if (off_base != mapped_base || off_in_page < map_start_in_page) {
 gpadl_iter_cache_unmap(iter);
 iter->map = NULL;
@@ -368,10 +368,10 @@ static ssize_t gpadl_iter_io(GpadlIter *iter, void *buf, 
uint32_t len)
 if (!iter->map) {
 dma_addr_t maddr;
 dma_addr_t mlen = pgleft;
-uint32_t idx = iter->off >> TARGET_PAGE_BITS;
+uint32_t idx = iter->off >> qemu_target_page_bits();
 assert(idx < iter->gpadl->num_gfns);
 
-maddr = (iter->gpadl->gfns[idx] << TARGET_PAGE_BITS) | off_in_page;
+maddr = (iter->gpadl->gfns[idx] << qemu_target_page_bits()) | 
off_in_page;
 
 iter->map = dma_memory_map(iter->as, maddr, &mlen, iter->dir,
MEMTXATTRS_UNSPECIFIED);
@@ -382,7 +382,7 @@ static ssize_t gpadl_iter_io(GpadlIter *iter, void *buf, 
uint32_t len)
 }
 }
 
-p = (void *)(uintptr_t)(((uintptr_t)iter->map & TARGET_PAGE_MASK) |
+p = (void *)(uintptr_t)(((uintptr_t)iter->map & 
qemu_target_page_mask()) |
 off_in_page);
 if (iter->dir == DMA_DIRECTION_FROM_DEVICE) {
 memcpy(p, buf, cplen);
@@ -591,9 +591,9 @@ static void ringbuf_init_common(VMBusRingBufCommon 
*ringbuf, VMBusGpadl *gpadl,
 uint32_t begin, uint32_t end)
 {
 ringbuf->as = as;
-ringbuf->rb_addr = gpadl->gfns[begin] << TARGET_PAGE_BITS;
-ringbuf->base = (begin + 1) << TARGET_PAGE_BITS;
-ringbuf->len = (end - begin - 1) << TARGET_PAGE_BITS;
+ringbuf->rb_addr = gpadl->gfns[begin] << qemu_target_page_bits();
+ringbuf->base = (begin + 1) << qemu_target_page_bits();
+ringbuf->len = (end - begin - 1) << qemu_target_page_bits();
 gpadl_iter_init(&ringbuf->iter, gpadl, as, dir);
 }
 
@@ -734,7 +734,7 @@ static int vmbus_channel_notify_guest(VMBusChannel *chan)
 unsigned long *int_map, mask;
 unsigned idx;
 hwaddr addr = chan->vmbus->int_page_gpa;
-hwaddr len = TARGET_PAGE_SIZE / 2, dirty = 0;
+hwaddr len = qemu_target_page_size() / 2, dirty = 0;
 
 trace_vmbus_channel_notify_guest(chan->id);
 
@@ -743,7 +743,7 @@ static int vmbus_channel_notify_guest(VMBusChannel *cha

[PATCH v2 2/2] target/riscv: fixes a bug against `ssamoswap` behavior in M-mode

2025-03-05 Thread Deepak Gupta
Commit f06bfe3dc38c ("target/riscv: implement zicfiss instructions") adds
`ssamoswap` instruction. `ssamoswap` takes the code-point from existing
reserved encoding (and not a zimop like other shadow stack instructions).
If shadow stack is not enabled (via xenvcfg.SSE) and effective priv is
less than M then `ssamoswap` must result in an illegal instruction
exception. However if effective priv is M, then `ssamoswap` results in
store/AMO access fault. See Section "22.2.3. Shadow Stack Memory
Protection" of priv spec.

Fixes: f06bfe3dc38c ("target/riscv: implement zicfiss instructions")

Reported-by: Ved Shanbhogue 
Signed-off-by: Deepak Gupta 
---
 target/riscv/insn_trans/trans_rvzicfiss.c.inc | 17 +
 1 file changed, 17 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rvzicfiss.c.inc 
b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
index e3ebc4977c..b0096adcd0 100644
--- a/target/riscv/insn_trans/trans_rvzicfiss.c.inc
+++ b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
@@ -15,6 +15,13 @@
  * You should have received a copy of the GNU General Public License along with
  * this program.  If not, see .
  */
+
+#define REQUIRE_ZICFISS(ctx) do {\
+if (!ctx->cfg_ptr->ext_zicfiss) {\
+return false;\
+}\
+} while (0)
+
 static bool trans_sspopchk(DisasContext *ctx, arg_sspopchk *a)
 {
 if (!ctx->bcfi_enabled) {
@@ -77,6 +84,11 @@ static bool trans_ssrdp(DisasContext *ctx, arg_ssrdp *a)
 static bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a)
 {
 REQUIRE_A_OR_ZAAMO(ctx);
+REQUIRE_ZICFISS(ctx);
+if (ctx->priv == PRV_M) {
+generate_exception(ctx, RISCV_EXCP_STORE_AMO_ACCESS_FAULT);
+}
+
 if (!ctx->bcfi_enabled) {
 return false;
 }
@@ -97,6 +109,11 @@ static bool trans_ssamoswap_d(DisasContext *ctx, 
arg_amoswap_w *a)
 {
 REQUIRE_64BIT(ctx);
 REQUIRE_A_OR_ZAAMO(ctx);
+REQUIRE_ZICFISS(ctx);
+if (ctx->priv == PRV_M) {
+generate_exception(ctx, RISCV_EXCP_STORE_AMO_ACCESS_FAULT);
+}
+
 if (!ctx->bcfi_enabled) {
 return false;
 }
-- 
2.34.1




[PATCH 2/7] hw/hyperv/hyperv.h: header cleanup

2025-03-05 Thread Pierrick Bouvier
Signed-off-by: Pierrick Bouvier 
---
 include/hw/hyperv/hyperv.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/hw/hyperv/hyperv.h b/include/hw/hyperv/hyperv.h
index d717b4e13d4..c6f7039447f 100644
--- a/include/hw/hyperv/hyperv.h
+++ b/include/hw/hyperv/hyperv.h
@@ -10,7 +10,9 @@
 #ifndef HW_HYPERV_HYPERV_H
 #define HW_HYPERV_HYPERV_H
 
-#include "cpu-qom.h"
+#include "qemu/osdep.h"
+#include "exec/hwaddr.h"
+#include "hw/core/cpu.h"
 #include "hw/hyperv/hyperv-proto.h"
 
 typedef struct HvSintRoute HvSintRoute;
-- 
2.39.5




Re: [PATCH 30/57] qapi/parser: adjust info location for doc body section

2025-03-05 Thread Markus Armbruster
John Snow  writes:

> On Wed, Mar 5, 2025 at 5:10 AM Markus Armbruster  wrote:
>
>> John Snow  writes:
>>
>> > Instead of using the info object for the doc block as a whole (which
>> > always points to the very first line of the block), update the info
>> > pointer for each call to ensure_untagged_section when the existing
>> > section is otherwise empty. This way, Sphinx error information will
>> > match precisely to where the text actually starts.
>> >
>> > For example, this patch will move the info pointer for the "Hello!"
>> > untagged section ...
>> >
>> >> ##   <-- from here ...
>> >> # Hello! <-- ... to here.
>> >> ##
>> >
>> > Signed-off-by: John Snow 
>>
>> This patch would be easier to accept with a test case where it improves
>> the error location.  I tried to construct one quickly, but failed.  Can
>> you help?
>>
>> Possible substitute: point to a patch later in this series where things
>> become worse without this patch.
>
>
> Maybe we can use the "if build_docs" section of the qapi schema testing to
> run things through Sphinx and harvest the error messages for negative
> cases...? I gotta sit down and figure out how.

Rule of thumb for compilers: every error needs a negative test.  So,
test coverage for transmogrifier errors is certainly wanted, but it's
not a blocker for an initial merge.  We need to make progress, and to
make progress, we need to limit the size of the steps.

> In the meantime, if I unapply my series, then edit block-core to look like
> this:
>
> ##
> # @SnapshotInfo:
> #
> # rST syntax error: *ahh!
> #
>
> (Lines 13-17, error is on line 16)
>
> Building, I get this error:
>
> /home/jsnow/src/qemu/docs/../qapi/block-core.json:14: WARNING: Inline
> emphasis start-string without end-string. [docutils]
> /home/jsnow/src/qemu/docs/../storage-daemon/qapi/../../qapi/block-core.json:14:
> WARNING: Inline emphasis start-string without end-string. [docutils]
>
> Mmm, nope. Not quite.
>
> If I re-push my series and try again with the same edit ...
>
> /home/jsnow/src/qemu/docs/../qapi/block-core.json:14: WARNING: Inline
> emphasis start-string without end-string. [docutils]
> /home/jsnow/src/qemu/docs/../storage-daemon/qapi/../../qapi/block-core.json:14:
> WARNING: Inline emphasis start-string without end-string. [docutils]
> /home/jsnow/src/qemu/docs/../qapi/block-core.json:16: WARNING: Inline
> emphasis start-string without end-string. [docutils]
>
> The two inclusions from the old qapidoc are still wrong, but the inclusion
> through the new transmogrifier is correct.

Reproduced.  To get non-first warnings, you have to configure
--disable-werror.  Observation, not a complaint.

> (I'm going to be honest with you, I don't know why the error location
> didn't change at all for the old qapidoc. I think one of the many error
> location bugs I fixed when writing the new transmogrifier that just never
> got applied to the old system...)

I'm definitely not asking you to find out more :)

> If I undo this fix but keep the rest of my series, I get these errors:
>
> /home/jsnow/src/qemu/docs/../qapi/block-core.json:14: WARNING: Inline
> emphasis start-string without end-string. [docutils]
> /home/jsnow/src/qemu/docs/../storage-daemon/qapi/../../qapi/block-core.json:14:
> WARNING: Inline emphasis start-string without end-string. [docutils]
> /home/jsnow/src/qemu/docs/../qapi/block-core.json:13: WARNING: Inline
> emphasis start-string without end-string. [docutils]
>
> Two are from the old qapidoc, one is from the new one. They're all wrong.

Also reproduced.  Thanks!

Perhaps the patch could be moved closer to where it's needed, or even be
squashed into one the first one that depends it.  Bah, good enough as
is.

Here's my attempt to improve the commit message:

qapi/parser: adjust info location for doc body section

Instead of using the info object for the doc block as a whole (which
always points to the very first line of the block), update the info
pointer for each call to ensure_untagged_section when the existing
section is otherwise empty. This way, Sphinx error information will
match precisely to where the text actually starts.

For example, this patch will move the info pointer for the "Hello!"
untagged section ...

##   <-- from here ...
# Hello! <-- ... to here.
##

This doesn't seem to improve error reporting now.  It will with the
QAPI doc transmogrifier I'm about to add.

If I stick bad rST into qapi/block-core.json like this

 ##
 # @SnapshotInfo:
 #
+# rST syntax error: *ahh!
+#
 # @id: unique snapshot id
 #
 # @name: user chosen name

the existing code's error message will point to the beginning of the
doc comment, which is less than helpful.  The transmogrifier's
message will point to the erroneous line, but to accomplish this, it
needs this patch.

What do you think?




Re: [PATCH v6 00/36] Multifd 🔀 device state transfer support with VFIO consumer

2025-03-05 Thread Avihai Horon



On 05/03/2025 19:45, Cédric Le Goater wrote:

External email: Use caution opening links or attachments


On 3/5/25 10:29, Cédric Le Goater wrote:

Hello,

On 3/4/25 23:03, Maciej S. Szmigiero wrote:

From: "Maciej S. Szmigiero" 

This is an updated v6 patch series of the v5 series located here:
https://lore.kernel.org/qemu-devel/cover.1739994627.git.maciej.szmigi...@oracle.com/ 



What this patch set is about?
Current live migration device state transfer is done via the main 
(single)

migration channel, which reduces performance and severally impacts the
migration downtime for VMs having large device state that needs to be
transferred during the switchover phase.

Example devices that have such large switchover phase device state 
are some

types of VFIO SmartNICs and GPUs.

This patch set allows parallelizing this transfer by using multifd 
channels

for it.
It also introduces new load and save threads per VFIO device for 
decoupling

these operations from the main migration thread.
These threads run on newly introduced generic (non-AIO) thread pools,
instantiated by the core migration core.


I think we are ready to apply 1-33. Avihai, please take a look !


Applied to vfio-next with changes for documentation.

Avihai, I will wait for your input before sending a PR.


Other than the comment I left everything looks fine by me.

Thanks.




Re: [RFC PATCH 10/18] qemu: Introduce legacy_binary_is_big_endian() helper

2025-03-05 Thread Thomas Huth

On 05/03/2025 16.39, Philippe Mathieu-Daudé wrote:

Introduce legacy_binary_endianness() to return the endianness
of a legacy binary, and legacy_binary_is_big_endian() being
equivalent of compile time TARGET_BIG_ENDIAN definition.

Signed-off-by: Philippe Mathieu-Daudé 
---
  include/qemu/legacy_binary_info.h |  8 ++
  legacy_binary_info.c  | 43 +++
  2 files changed, 51 insertions(+)


We already have target_words_bigendian() ... why do we need yet another 
function?


 Thomas




Re: [PATCH 1/2] 9pfs: fix concurrent v9fs_reclaim_fd() calls

2025-03-05 Thread Greg Kurz
Hi Christian !

On Tue, 4 Mar 2025 16:15:57 +0100
Christian Schoenebeck  wrote:

> Even though this function is serialized to be always called from main
> thread, v9fs_reclaim_fd() is dispatching the coroutine to a worker thread
> in between via its v9fs_co_*() calls, hence leading to the situation where
> v9fs_reclaim_fd() is effectively executed multiple times simultaniously,
> which renders its LRU algorithm useless and causes high latency.
> 
> Fix this by adding a simple boolean variable to ensure this function is
> only called once at a time. No synchronization needed for this boolean
> variable as this function is only entered and returned on main thread.
> 
> Fixes: 7a46274529c ('hw/9pfs: Add file descriptor reclaim support')
> Signed-off-by: Christian Schoenebeck 
> ---

Another long long standing bug bites the dust ! Good catch !

Reviewed-by: Greg Kurz 

>  hw/9pfs/9p.c | 10 ++
>  hw/9pfs/9p.h |  1 +
>  2 files changed, 11 insertions(+)
> 
> diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
> index 7cad2bce62..4f9c2dde9c 100644
> --- a/hw/9pfs/9p.c
> +++ b/hw/9pfs/9p.c
> @@ -435,6 +435,12 @@ void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu)
>  GHashTableIter iter;
>  gpointer fid;
>  
> +/* prevent multiple coroutines running this function simultaniously */
> +if (s->reclaiming) {
> +return;
> +}
> +s->reclaiming = true;
> +
>  g_hash_table_iter_init(&iter, s->fids);
>  
>  QSLIST_HEAD(, V9fsFidState) reclaim_list =
> @@ -510,6 +516,8 @@ void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu)
>   */
>  put_fid(pdu, f);
>  }
> +
> +s->reclaiming = false;
>  }
>  
>  /*
> @@ -4324,6 +4332,8 @@ int v9fs_device_realize_common(V9fsState *s, const 
> V9fsTransport *t,
>  s->ctx.fst = &fse->fst;
>  fsdev_throttle_init(s->ctx.fst);
>  
> +s->reclaiming = false;
> +
>  rc = 0;
>  out:
>  if (rc) {
> diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
> index 5e041e1f60..259ad32ed1 100644
> --- a/hw/9pfs/9p.h
> +++ b/hw/9pfs/9p.h
> @@ -362,6 +362,7 @@ struct V9fsState {
>  uint64_t qp_ndevices; /* Amount of entries in qpd_table. */
>  uint16_t qp_affix_next;
>  uint64_t qp_fullpath_next;
> +bool reclaiming;
>  };
>  
>  /* 9p2000.L open flags */



-- 
Greg



Re: [PATCH 31/57] qapi: expand tags to all doc sections

2025-03-05 Thread Markus Armbruster
John Snow  writes:

> On Wed, Mar 5, 2025 at 5:16 AM Markus Armbruster  wrote:
>
>> Replaying review of a previous posting for your convenience...
>>
>> John Snow  writes:
>>
>> > This patch adds an explicit section "kind" to all QAPIDoc
>> > sections. Members/Features are now explicitly marked as such, with the
>> > name now being stored in a dedicated "name" field (which qapidoc.py was
>> > not actually using anyway.)
>>
>> I'm not sure what the parenthesis is trying to convey.
>>
>
> The old qapidoc.py doesn't actually use the name field, so there's nothing
> to adjust for old callers.
>
>
>>
>> Before the patch, we have:
>>
>>   typetag
>> untagged  Section None
>> @foo: ArgSection  'foo'
>> Returns:  Section 'Returns'
>> Errors:   Section 'Errors'
>> Since:Section 'Since'
>> TODO: Section 'TODO'
>>
>> Afterwards, I believe:
>>
>>   type kind name
>> untagged  Section  PLAIN
>> @foo: ArgSection   MEMBER   'foo'   if member or argument
>>   ArgSection   FEATURE  'foo'   if feature
>> Returns:  Section  RETURNS
>> Errors:   Section  ERRORS
>> Since:Section  SINCE
>> TODO: Section  TODO
>>
>> So, .tag is replaced by .kind and .name, member vs. feature vs. other
>> tags is now obvious from .kind alone, i.e. there's no need to account
>> for context or type.
>>
>> Fine print: why do we need to account for type before the patch?
>> Consider @Since: ...
>>
>
> I'm not sure I follow...

Consider

##
# @some-command
#
# @Since: an anti-socially named argument
#
# Since: 10.0
##

Before the patch, both the argument description and the Since section
have tag 'Since'.  The former has type ArgSection, which is a subtype of
Section.  The latter has type Section.  This is how we tell them apart.
There's potential for confusion and misuse of .tag.

After the patch, they have different kinds.

Do you follow now?

>> > The qapi-schema tests are updated to account for the new section names;
>> > mostly "TODO" becomes "Todo" and `None` becomes "Plain".
>> >
>> > Signed-off-by: John Snow 
>> > ---
>> >  docs/sphinx/qapidoc.py |   7 ++-
>> >  scripts/qapi/parser.py | 109 -
>> >  tests/qapi-schema/doc-good.out |  10 +--
>> >  tests/qapi-schema/test-qapi.py |   2 +-
>> >  4 files changed, 90 insertions(+), 38 deletions(-)
>> >
>> > diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py
>> > index 61997fd21af..d622398f1da 100644
>> > --- a/docs/sphinx/qapidoc.py
>> > +++ b/docs/sphinx/qapidoc.py
>> > @@ -35,6 +35,7 @@
>> >  from docutils.statemachine import ViewList
>> >  from qapi.error import QAPIError, QAPISemError
>> >  from qapi.gen import QAPISchemaVisitor
>> > +from qapi.parser import QAPIDoc
>> >  from qapi.schema import QAPISchema
>> >
>> >  from sphinx import addnodes
>> > @@ -258,11 +259,11 @@ def _nodes_for_sections(self, doc):
>> >  """Return list of doctree nodes for additional sections"""
>> >  nodelist = []
>> >  for section in doc.sections:
>> > -if section.tag and section.tag == 'TODO':
>> > +if section.kind == QAPIDoc.Kind.TODO:
>> >  # Hide TODO: sections
>> >  continue
>> >
>> > -if not section.tag:
>> > +if section.kind == QAPIDoc.Kind.PLAIN:
>> >  # Sphinx cannot handle sectionless titles;
>> >  # Instead, just append the results to the prior section.
>> >  container = nodes.container()
>> > @@ -270,7 +271,7 @@ def _nodes_for_sections(self, doc):
>> >  nodelist += container.children
>> >  continue
>> >
>> > -snode = self._make_section(section.tag)
>> > +snode = self._make_section(section.kind.name.title())
>> >  self._parse_text_into_node(dedent(section.text), snode)
>> >  nodelist.append(snode)
>> >  return nodelist
>> > diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
>> > index 36cb64a677a..c3004aa70c6 100644
>> > --- a/scripts/qapi/parser.py
>> > +++ b/scripts/qapi/parser.py
>> > @@ -15,6 +15,7 @@
>> >  # See the COPYING file in the top-level directory.
>> >
>> >  from collections import OrderedDict
>> > +import enum
>> >  import os
>> >  import re
>> >  from typing import (
>> > @@ -575,7 +576,10 @@ def get_doc(self) -> 'QAPIDoc':
>> >  )
>> >  raise QAPIParseError(self, emsg)
>> >
>> > -doc.new_tagged_section(self.info, match.group(1))
>> > +doc.new_tagged_section(
>> > +self.info,
>> > +QAPIDoc.Kind.from_string(match.group(1))
>> > +)
>> >  text = line[match.end():]
>> >  if text:
>> >  do

Re: [PATCH 2/7] target/riscv: Move target-agnostic definitions to 'cpu-qom.h'

2025-03-05 Thread Philippe Mathieu-Daudé

On 9/2/25 08:34, Paolo Bonzini wrote:

On 2/6/25 19:18, Philippe Mathieu-Daudé wrote:

"cpu.h" is target-specific. Definitions which can be used
by hw/ code when building QOM blocks can be in "cpu-qom.h",
which is target-agnostic.

Move the MISA bits (removing the pointless target_ulong cast)
and the IRQ index definitions.


This seems wrong.  Why not move from cpu.h to cpu_bits.h, and include that?


Because of ...



Paolo


Signed-off-by: Philippe Mathieu-Daudé 
---
  target/riscv/cpu-qom.h  | 40 
  target/riscv/cpu.h  | 24 
  target/riscv/cpu_bits.h | 15 ---
  3 files changed, 40 insertions(+), 39 deletions(-)




diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index f97c48a3943..80701bc77fe 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -720,21 +720,6 @@ typedef enum RISCVException {
  #define RISCV_EXCP_INT_FLAG    0x8000
  #define RISCV_EXCP_INT_MASK    0x7fff
-/* Interrupt causes */
-#define IRQ_U_SOFT 0
-#define IRQ_S_SOFT 1
-#define IRQ_VS_SOFT    2
-#define IRQ_M_SOFT 3
-#define IRQ_U_TIMER    4
-#define IRQ_S_TIMER    5
-#define IRQ_VS_TIMER   6
-#define IRQ_M_TIMER    7
-#define IRQ_U_EXT  8
-#define IRQ_S_EXT  9
-#define IRQ_VS_EXT 10
-#define IRQ_M_EXT  11
-#define IRQ_S_GEXT 12
-#define IRQ_PMU_OVF    13
  #define IRQ_LOCAL_MAX  64
  /* -1 is due to bit zero of hgeip and hgeie being ROZ. */
  #define IRQ_LOCAL_GUEST_MAX    (TARGET_LONG_BITS - 1)


... this TARGET_LONG_BITS use in cpu_bits.h.

and:

target/riscv/cpu_bits.h:1070:44: error: attempt to use a poisoned identifier
 1070 | #define CPU_INTERRUPT_RNMI CPU_INTERRUPT_TGT_EXT_0
  |^

But I got your idea and will only move these 2 to "cpu.h".



Re: [PATCH] goldfish_rtc: Fix tick_offset migration

2025-03-05 Thread Alistair Francis
On Thu, Mar 6, 2025 at 4:44 PM Michael Tokarev  wrote:
>
> 06.03.2025 09:35, Michael Tokarev wrote:
>
> >> Migrate the tick_offset directly, adding it as a version-dependent field
> >> to VMState. Keep the old behavior when migrating from previous versions.
> >>
> >> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2033
> >
> > Is this a qemu-stable material?
>
> It is probably not, since this change adds a new field (and version) to the
> migration stream.

That's fine

Alistair

>
> Thanks,
>
> /mjt
>



Re: [PATCH] target/riscv: rvv: Fix unexpected behavior of vector reduction instructions when vl is 0

2025-03-05 Thread Michael Tokarev

24.01.2025 13:14, Max Chou wrote:

According to the Vector Reduction Operations section in the RISC-V "V"
Vector Extension spec,
"If vl=0, no operation is performed and the destination register is not
updated."

The vd should be updated when vl is larger than 0.


Is this a qemu-stable material?

If yes, how far to previous releases it is worth to pick?
(Current older stable series are 7.2 and 8.2).

I currently picked this up for 7.2, 8.2 and 9.2.

Thanks,

/mjt



Re: [PATCH 5/7] target/riscv: update max_satp_mode based on QOM properties

2025-03-05 Thread Alistair Francis
On Wed, Feb 19, 2025 at 2:59 AM Paolo Bonzini  wrote:
>
> Almost all users of cpu->cfg.satp_mode care only about the "max" value
> satp_mode_max_from_map(cpu->cfg.satp_mode.map); convert the QOM
> properties back into it.  For TCG, consult valid_vm[] instead of
> the bitmap of accepted modes.
>
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h |  1 -
>  hw/riscv/virt-acpi-build.c | 14 +-
>  hw/riscv/virt.c|  5 ++---
>  target/riscv/cpu.c | 27 ++-
>  target/riscv/csr.c |  9 +++--
>  5 files changed, 24 insertions(+), 32 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 97713681cbe..f9b223bf8a7 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -911,7 +911,6 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState 
> *cs);
>  target_ulong riscv_new_csr_seed(target_ulong new_value,
>  target_ulong write_mask);
>
> -uint8_t satp_mode_max_from_map(uint32_t map);
>  const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
>
>  /* Implemented in th_csr.c */
> diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
> index 2b374ebacbf..1a92a84207d 100644
> --- a/hw/riscv/virt-acpi-build.c
> +++ b/hw/riscv/virt-acpi-build.c
> @@ -261,7 +261,6 @@ static void build_rhct(GArray *table_data,
>  uint32_t isa_offset, num_rhct_nodes, cmo_offset = 0;
>  RISCVCPU *cpu = &s->soc[0].harts[0];
>  uint32_t mmu_offset = 0;
> -uint8_t satp_mode_max;
>  bool rv32 = riscv_cpu_is_32bit(cpu);
>  g_autofree char *isa = NULL;
>
> @@ -282,8 +281,7 @@ static void build_rhct(GArray *table_data,
>  num_rhct_nodes++;
>  }
>
> -if (!rv32 && cpu->cfg.satp_mode.supported != 0 &&
> -(cpu->cfg.satp_mode.map & ~(1 << VM_1_10_MBARE))) {
> +if (!rv32 && cpu->cfg.max_satp_mode >= VM_1_10_SV39) {
>  num_rhct_nodes++;
>  }
>
> @@ -343,20 +341,18 @@ static void build_rhct(GArray *table_data,
>  }
>
>  /* MMU node structure */
> -if (!rv32 && cpu->cfg.satp_mode.supported != 0 &&
> -(cpu->cfg.satp_mode.map & ~(1 << VM_1_10_MBARE))) {
> -satp_mode_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
> +if (!rv32 && cpu->cfg.max_satp_mode >= VM_1_10_SV39) {
>  mmu_offset = table_data->len - table.table_offset;
>  build_append_int_noprefix(table_data, 2, 2);/* Type */
>  build_append_int_noprefix(table_data, 8, 2);/* Length */
>  build_append_int_noprefix(table_data, 0x1, 2);  /* Revision */
>  build_append_int_noprefix(table_data, 0, 1);/* Reserved */
>  /* MMU Type */
> -if (satp_mode_max == VM_1_10_SV57) {
> +if (cpu->cfg.max_satp_mode == VM_1_10_SV57) {
>  build_append_int_noprefix(table_data, 2, 1);/* Sv57 */
> -} else if (satp_mode_max == VM_1_10_SV48) {
> +} else if (cpu->cfg.max_satp_mode == VM_1_10_SV48) {
>  build_append_int_noprefix(table_data, 1, 1);/* Sv48 */
> -} else if (satp_mode_max == VM_1_10_SV39) {
> +} else if (cpu->cfg.max_satp_mode == VM_1_10_SV39) {
>  build_append_int_noprefix(table_data, 0, 1);/* Sv39 */
>  } else {
>  g_assert_not_reached();
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 241389d72f8..2394fc71df4 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -236,10 +236,10 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, 
> int socket,
>  uint32_t cpu_phandle;
>  MachineState *ms = MACHINE(s);
>  bool is_32_bit = riscv_is_32bit(&s->soc[0]);
> -uint8_t satp_mode_max;
>
>  for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
>  RISCVCPU *cpu_ptr = &s->soc[socket].harts[cpu];
> +int8_t satp_mode_max = cpu_ptr->cfg.max_satp_mode;
>  g_autofree char *cpu_name = NULL;
>  g_autofree char *core_name = NULL;
>  g_autofree char *intc_name = NULL;
> @@ -251,8 +251,7 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int 
> socket,
>  s->soc[socket].hartid_base + cpu);
>  qemu_fdt_add_subnode(ms->fdt, cpu_name);
>
> -if (cpu_ptr->cfg.satp_mode.supported != 0) {
> -satp_mode_max = 
> satp_mode_max_from_map(cpu_ptr->cfg.satp_mode.map);
> +if (satp_mode_max != -1) {
>  sv_name = g_strdup_printf("riscv,%s",
>satp_mode_str(satp_mode_max, 
> is_32_bit));
>  qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type", sv_name);
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 2d06543217a..ce71ee95a52 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -387,7 +387,7 @@ static uint8_t satp_mode_from_str(const char 
> *satp_mode_str)
>  g_assert_not_reached();
>  }
>
> -uint8_t satp_mode_max_from_map(uint32_t map)
> +static uin

Re: [RFC PATCH 01/18] hw/xen/hvm: Fix Aarch64 typo

2025-03-05 Thread Richard Henderson

On 3/5/25 07:39, Philippe Mathieu-Daudé wrote:

There is no TARGET_ARM_64 definition. Luckily enough,
when TARGET_AARCH64 is defined, TARGET_ARM also is.

Fixes: 733766cd373 ("hw/arm: introduce xenpvh machine")
Signed-off-by: Philippe Mathieu-Daudé 
---
  include/hw/xen/arch_hvm.h | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



diff --git a/include/hw/xen/arch_hvm.h b/include/hw/xen/arch_hvm.h
index c7c515220d2..df39c819c8f 100644
--- a/include/hw/xen/arch_hvm.h
+++ b/include/hw/xen/arch_hvm.h
@@ -1,5 +1,5 @@
  #if defined(TARGET_I386) || defined(TARGET_X86_64)
  #include "hw/i386/xen_arch_hvm.h"
-#elif defined(TARGET_ARM) || defined(TARGET_ARM_64)
+#elif defined(TARGET_ARM) || defined(TARGET_AARCH64)
  #include "hw/arm/xen_arch_hvm.h"
  #endif





[PATCH v2 3/5] hw/acpi/aml-build: Build a root node in the PPTT table

2025-03-05 Thread Alireza Sanaee via
From: Yicong Yang 

Currently we build the PPTT starting from the socket node and each
socket will be a separate tree. For a multi-socket system it'll
be hard for the OS to know the whole system is homogeneous or not
(actually we're in the current implementation) since no parent node
to telling the identical implementation informentation. Add a
root node for indicating this.

Signed-off-by: Yicong Yang 
Reviewed-by: Jonathan Cameron 
Signed-off-by: Alireza Sanaee 
---
 hw/acpi/aml-build.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 560cee12a2..3010325ca4 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -2153,12 +2153,25 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, 
MachineState *ms,
 int64_t socket_id = -1, cluster_id = -1, core_id = -1;
 uint32_t socket_offset = 0, cluster_offset = 0, core_offset = 0;
 uint32_t pptt_start = table_data->len;
+uint32_t root_offset;
 int n;
 AcpiTable table = { .sig = "PPTT", .rev = 2,
 .oem_id = oem_id, .oem_table_id = oem_table_id };
 
 acpi_table_begin(&table, table_data);
 
+/*
+ * Build a root node for all the processor nodes. Otherwise when
+ * building a multi-socket system each socket tree are separated
+ * and will be hard for the OS like Linux to know whether the
+ * system is homogeneous.
+ */
+root_offset = table_data->len - pptt_start;
+build_processor_hierarchy_node(table_data,
+(1 << 0) | /* Physical package */
+(1 << 4), /* Identical Implementation */
+0, 0, NULL, 0);
+
 /*
  * This works with the assumption that cpus[n].props.*_id has been
  * sorted from top to down levels in mc->possible_cpu_arch_ids().
@@ -2175,7 +2188,7 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, 
MachineState *ms,
 build_processor_hierarchy_node(table_data,
 (1 << 0) | /* Physical package */
 (1 << 4), /* Identical Implementation */
-0, socket_id, NULL, 0);
+root_offset, socket_id, NULL, 0);
 }
 
 if (mc->smp_props.clusters_supported && mc->smp_props.has_clusters) {
-- 
2.43.0




[PATCH v2 1/5] tests: virt: Allow changes to PPTT test table

2025-03-05 Thread Alireza Sanaee via
From: Yicong Yang 

Allow changes to PPTT test table, preparing for adding identical
implementation flags support and for adding a root node for all
the system.

Signed-off-by: Yicong Yang 
Reviewed-by: Jonathan Cameron 
Signed-off-by: Alireza Sanaee 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..e84d6c6955 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,4 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/aarch64/virt/PPTT",
+"tests/data/acpi/aarch64/virt/PPTT.acpihmatvirt",
+"tests/data/acpi/aarch64/virt/PPTT.topology",
-- 
2.43.0




[PATCH v2 4/5] hw/acpi/aml-build: Update the revision of PPTT table

2025-03-05 Thread Alireza Sanaee via
From: Yicong Yang 

The lastest ACPI spec 6.5 support PPTT revision 3. Update it
by handy. This is compatible with previous revision.

Signed-off-by: Yicong Yang 
Reviewed-by: Jonathan Cameron 
Signed-off-by: Alireza Sanaee 
---
 hw/acpi/aml-build.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 3010325ca4..e5401dfdb1 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -2155,7 +2155,7 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, 
MachineState *ms,
 uint32_t pptt_start = table_data->len;
 uint32_t root_offset;
 int n;
-AcpiTable table = { .sig = "PPTT", .rev = 2,
+AcpiTable table = { .sig = "PPTT", .rev = 3,
 .oem_id = oem_id, .oem_table_id = oem_table_id };
 
 acpi_table_begin(&table, table_data);
-- 
2.43.0




[PATCH v2 5/5] tests: virt: Update expected ACPI tables for virt test

2025-03-05 Thread Alireza Sanaee via
From: Yicong Yang 

Update the ACPI tables according to the acpi aml_build change, also
empty bios-tables-test-allowed-diff.h.

The disassembled differences between actual and expected PPTT shows
below. Only about the root node adding and identification flag set
as expected.
  /*
* Intel ACPI Component Architecture
* AML/ASL+ Disassembler version 20210604 (64-bit version)
* Copyright (c) 2000 - 2021 Intel Corporation
*
  - * Disassembly of tests/data/acpi/aarch64/virt/PPTT, Thu Sep 26 08:54:39 2024
  + * Disassembly of /tmp/aml-QNEIU2, Thu Sep 26 08:54:39 2024
*
* ACPI Data Table [PPTT]
*
* Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
*/

   [000h    4]Signature : "PPTT"[Processor 
Properties Topology Table]
  -[004h 0004   4] Table Length : 004C
  -[008h 0008   1] Revision : 02
  -[009h 0009   1] Checksum : A8
  +[004h 0004   4] Table Length : 0060
  +[008h 0008   1] Revision : 03
  +[009h 0009   1] Checksum : 26
   [00Ah 0010   6]   Oem ID : "BOCHS "
   [010h 0016   8] Oem Table ID : "BXPC"
   [018h 0024   4] Oem Revision : 0001
   [01Ch 0028   4]  Asl Compiler ID : "BXPC"
   [020h 0032   4]Asl Compiler Revision : 0001

   [024h 0036   1]Subtable Type : 00 [Processor Hierarchy Node]
   [025h 0037   1]   Length : 14
   [026h 0038   2] Reserved : 
  -[028h 0040   4]Flags (decoded below) : 0001
  +[028h 0040   4]Flags (decoded below) : 0011
   Physical package : 1
ACPI Processor ID valid : 0
  Processor is a thread : 0
 Node is a leaf : 0
  -Identical Implementation : 0
  +Identical Implementation : 1
   [02Ch 0044   4]   Parent : 
   [030h 0048   4]ACPI Processor ID : 
   [034h 0052   4]  Private Resource Number : 

   [038h 0056   1]Subtable Type : 00 [Processor Hierarchy Node]
   [039h 0057   1]   Length : 14
   [03Ah 0058   2] Reserved : 
  -[03Ch 0060   4]Flags (decoded below) : 000A
  +[03Ch 0060   4]Flags (decoded below) : 0011
  +Physical package : 1
  + ACPI Processor ID valid : 0
  +   Processor is a thread : 0
  +  Node is a leaf : 0
  +Identical Implementation : 1
  +[040h 0064   4]   Parent : 0024
  +[044h 0068   4]ACPI Processor ID : 
  +[048h 0072   4]  Private Resource Number : 
  +
  +[04Ch 0076   1]Subtable Type : 00 [Processor Hierarchy Node]
  +[04Dh 0077   1]   Length : 14
  +[04Eh 0078   2] Reserved : 
  +[050h 0080   4]Flags (decoded below) : 000A
   Physical package : 0
ACPI Processor ID valid : 1
  Processor is a thread : 0
 Node is a leaf : 1
   Identical Implementation : 0
  -[040h 0064   4]   Parent : 0024
  -[044h 0068   4]ACPI Processor ID : 
  -[048h 0072   4]  Private Resource Number : 
  +[054h 0084   4]   Parent : 0038
  +[058h 0088   4]ACPI Processor ID : 
  +[05Ch 0092   4]  Private Resource Number : 

  -Raw Table Data: Length 76 (0x4C)
  +Raw Table Data: Length 96 (0x60)

  -: 50 50 54 54 4C 00 00 00 02 A8 42 4F 43 48 53 20  // PPTTL.BOCHS
  +: 50 50 54 54 60 00 00 00 03 26 42 4F 43 48 53 20  // PPTT`&BOCHS
   0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43  // BXPC
BXPC
  -0020: 01 00 00 00 00 14 00 00 01 00 00 00 00 00 00 00  // 

  -0030: 00 00 00 00 00 00 00 00 00 14 00 00 0A 00 00 00  // 

  -0040: 24 00 00 00 00 00 00 00 00 00 00 00  // $...
  +0020: 01 00 00 00 00 14 00 00 11 00 00 00 00 00 00 00  // 

  +0030: 00 00 00 00 00 00 00 00 00 14 00 00 11 00 00 00  // 

  +0040: 24 00 00 00 00 00 00 00 00 00 00 00 00 14 00 00  // 
$...
  +0050: 0A 00 00 00 38 00 00 00 00 00 00 00 00 00 00 00  // 
8...

Signed-off-by: Yicong Yang 
Reviewed-by: Jonathan Cameron 
Signed-off-by: Alireza Sanaee 
---
 tests/data/acpi/aarch64/virt/PPTT  | Bin 76 -> 96 bytes
 tests/data/acpi/aarch64/virt/PPTT.acpihmatvirt | Bin 156 -> 176 bytes
 tests/data/acpi/aarch64/virt/PPT

Re: [PATCH 6/7] target/riscv: remove supported from RISCVSATPMap

2025-03-05 Thread Alistair Francis
On Wed, Feb 19, 2025 at 2:59 AM Paolo Bonzini  wrote:
>
> "supported" can be computed on the fly based on the max_satp_mode.
>
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu_cfg.h |  4 +---
>  target/riscv/cpu.c | 34 --
>  2 files changed, 25 insertions(+), 13 deletions(-)
>
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index 28d8de978fa..1d7fff8decd 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -29,11 +29,9 @@
>   *
>   * init is a 16-bit bitmap used to make sure the user selected a correct
>   * configuration as per the specification.
> - *
> - * supported is a 16-bit bitmap used to reflect the hw capabilities.
>   */
>  typedef struct {
> -uint16_t map, init, supported;
> +uint16_t map, init;
>  } RISCVSATPMap;
>
>  struct RISCVCPUConfig {
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index ce71ee95a52..86a048b62c5 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -437,14 +437,27 @@ static void set_satp_mode_max_supported(RISCVCPU *cpu,
>  bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
>  const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
>
> -for (int i = 0; i <= satp_mode; ++i) {
> -if (valid_vm[i]) {
> -cpu->cfg.satp_mode.supported |= (1 << i);
> -}
> +assert(valid_vm[satp_mode]);
> +cpu->cfg.max_satp_mode = satp_mode;
> +}
> +
> +static bool get_satp_mode_supported(RISCVCPU *cpu, uint16_t *supported)
> +{
> +bool rv32 = riscv_cpu_is_32bit(cpu);
> +const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
> +int satp_mode = cpu->cfg.max_satp_mode;
> +
> +if (satp_mode == -1) {
> +return false;
>  }
>
> -assert(cpu->cfg.satp_mode.supported & (1 << satp_mode));
> -cpu->cfg.max_satp_mode = satp_mode;
> +*supported = 0;
> +for (int i = 0; i <= satp_mode; ++i) {
> +if (valid_vm[i]) {
> +*supported |= (1 << i);
> +}
> +}
> +return true;
>  }
>
>  /* Set the satp mode to the max supported */
> @@ -1176,9 +1189,10 @@ static void riscv_cpu_disas_set_info(CPUState *s, 
> disassemble_info *info)
>  static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
>  {
>  bool rv32 = riscv_cpu_is_32bit(cpu);
> +uint16_t supported;
>  uint8_t satp_mode_map_max;
>
> -if (cpu->cfg.max_satp_mode == -1) {
> +if (!get_satp_mode_supported(cpu, &supported)) {
>  /* The CPU wants the hypervisor to decide which satp mode to allow */
>  return;
>  }
> @@ -1195,9 +1209,9 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, 
> Error **errp)
>   */
>  for (int i = 1; i < 16; ++i) {
>  if ((cpu->cfg.satp_mode.init & (1 << i)) &&
> -(cpu->cfg.satp_mode.supported & (1 << i))) {
> +supported & (1 << i)) {
>  for (int j = i - 1; j >= 0; --j) {
> -if (cpu->cfg.satp_mode.supported & (1 << j)) {
> +if (supported & (1 << j)) {
>  cpu->cfg.max_satp_mode = j;
>  return;
>  }
> @@ -1226,7 +1240,7 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, 
> Error **errp)
>  for (int i = satp_mode_map_max - 1; i >= 0; --i) {
>  if (!(cpu->cfg.satp_mode.map & (1 << i)) &&
>  (cpu->cfg.satp_mode.init & (1 << i)) &&
> -(cpu->cfg.satp_mode.supported & (1 << i))) {
> +(supported & (1 << i))) {
>  error_setg(errp, "cannot disable %s satp mode if %s "
> "is enabled", satp_mode_str(i, false),
> satp_mode_str(satp_mode_map_max, false));
> --
> 2.48.1
>
>



[PATCH v2 0/5] Building PPTT with root node and identical implementation flag

2025-03-05 Thread Alireza Sanaee via
OS like Linux is using PPTT processor node's identical implementation
flag [1] to infer whether the whole system or a certain CPU cluster is
homogeneous or not [2]. QEMU currently only support building homogeneous
system, set the flag to indicate the fact. Build a root node in PPTT
for indicates the identical implementation which is needed for a
multi-socket system. Update the related PPTT tables as well.

Since we'll update the test PPTT table data, upgrade the revision of PPTT
we build to revision 3 by handy.

[1] ACPI 6.5 Table 5.158: Processor Structure Flags
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/pptt.c?h=v6.11-rc1#n810

Yicong Yang (5):
  tests: virt: Allow changes to PPTT test table
  hw/acpi/aml-build: Set identical implementation flag for PPTT
processor nodes
  hw/acpi/aml-build: Build a root node in the PPTT table
  hw/acpi/aml-build: Update the revision of PPTT table
  tests: virt: Update expected ACPI tables for virt test

 hw/acpi/aml-build.c   |  26 ++
 tests/data/acpi/aarch64/virt/PPTT | Bin 76 -> 96 bytes
 .../data/acpi/aarch64/virt/PPTT.acpihmatvirt  | Bin 156 -> 176 bytes
 tests/data/acpi/aarch64/virt/PPTT.topology| Bin 336 -> 356 bytes
 4 files changed, 21 insertions(+), 5 deletions(-)

-- 
2.43.0




Re: [PATCH 7/7] target/riscv: move satp_mode.{map, init} out of CPUConfig

2025-03-05 Thread Alistair Francis
On Wed, Feb 19, 2025 at 3:00 AM Paolo Bonzini  wrote:
>
> They are used to provide the nice QOM properties for svNN,
> but the canonical source of the CPU configuration is now
> cpu->cfg.max_satp_mode.  Store them in the ArchCPU struct.
>
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h | 14 ++
>  target/riscv/cpu_cfg.h | 14 --
>  target/riscv/cpu.c | 32 
>  3 files changed, 30 insertions(+), 30 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index f9b223bf8a7..df7a05e7d15 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -492,6 +492,19 @@ struct CPUArchState {
>  uint64_t rnmi_excpvec;
>  };
>
> +/*
> + * map is a 16-bit bitmap: the most significant set bit in map is the maximum
> + * satp mode that is supported. It may be chosen by the user and must respect
> + * what qemu implements (valid_1_10_32/64) and what the hw is capable of
> + * (supported bitmap below).
> + *
> + * init is a 16-bit bitmap used to make sure the user selected a correct
> + * configuration as per the specification.
> + */
> +typedef struct {
> +uint16_t map, init;
> +} RISCVSATPModes;
> +
>  /*
>   * RISCVCPU:
>   * @env: #CPURISCVState
> @@ -508,6 +521,7 @@ struct ArchCPU {
>
>  /* Configuration Settings */
>  RISCVCPUConfig cfg;
> +RISCVSATPModes satp_modes;
>
>  QEMUTimer *pmu_timer;
>  /* A bitmask of Available programmable counters */
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index 1d7fff8decd..7b7067d5bee 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -21,19 +21,6 @@
>  #ifndef RISCV_CPU_CFG_H
>  #define RISCV_CPU_CFG_H
>
> -/*
> - * map is a 16-bit bitmap: the most significant set bit in map is the maximum
> - * satp mode that is supported. It may be chosen by the user and must respect
> - * what qemu implements (valid_1_10_32/64) and what the hw is capable of
> - * (supported bitmap below).
> - *
> - * init is a 16-bit bitmap used to make sure the user selected a correct
> - * configuration as per the specification.
> - */
> -typedef struct {
> -uint16_t map, init;
> -} RISCVSATPMap;
> -
>  struct RISCVCPUConfig {
>  bool ext_zba;
>  bool ext_zbb;
> @@ -191,7 +178,6 @@ struct RISCVCPUConfig {
>
>  #ifndef CONFIG_USER_ONLY
>  int8_t max_satp_mode;
> -RISCVSATPMap satp_mode;
>  #endif
>  };
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 86a048b62c5..8ab7fe2e286 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1197,8 +1197,8 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, 
> Error **errp)
>  return;
>  }
>
> -if (cpu->cfg.satp_mode.map == 0) {
> -if (cpu->cfg.satp_mode.init == 0) {
> +if (cpu->satp_modes.map == 0) {
> +if (cpu->satp_modes.init == 0) {
>  /* If unset by the user, we fallback to the default satp mode. */
>  set_satp_mode_default_map(cpu);
>  } else {
> @@ -1208,7 +1208,7 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, 
> Error **errp)
>   * valid_vm_1_10_32/64.
>   */
>  for (int i = 1; i < 16; ++i) {
> -if ((cpu->cfg.satp_mode.init & (1 << i)) &&
> +if ((cpu->satp_modes.init & (1 << i)) &&
>  supported & (1 << i)) {
>  for (int j = i - 1; j >= 0; --j) {
>  if (supported & (1 << j)) {
> @@ -1222,7 +1222,7 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, 
> Error **errp)
>  return;
>  }
>
> -satp_mode_map_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
> +satp_mode_map_max = satp_mode_max_from_map(cpu->satp_modes.map);
>
>  /* Make sure the user asked for a supported configuration (HW and qemu) 
> */
>  if (satp_mode_map_max > cpu->cfg.max_satp_mode) {
> @@ -1238,8 +1238,8 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, 
> Error **errp)
>   */
>  if (!rv32) {
>  for (int i = satp_mode_map_max - 1; i >= 0; --i) {
> -if (!(cpu->cfg.satp_mode.map & (1 << i)) &&
> -(cpu->cfg.satp_mode.init & (1 << i)) &&
> +if (!(cpu->satp_modes.map & (1 << i)) &&
> +(cpu->satp_modes.init & (1 << i)) &&
>  (supported & (1 << i))) {
>  error_setg(errp, "cannot disable %s satp mode if %s "
> "is enabled", satp_mode_str(i, false),
> @@ -1327,11 +1327,11 @@ bool riscv_cpu_accelerator_compatible(RISCVCPU *cpu)
>  static void cpu_riscv_get_satp(Object *obj, Visitor *v, const char *name,
> void *opaque, Error **errp)
>  {
> -RISCVSATPMap *satp_map = opaque;
> +RISCVSATPModes *satp_modes = opaque;
>  uint8_t satp = satp_mode_from_str(name);
>  bool value;
>
> -value = satp_map->map & (1 << satp);
> +  

[PATCH v2 2/5] hw/acpi/aml-build: Set identical implementation flag for PPTT processor nodes

2025-03-05 Thread Alireza Sanaee via
From: Yicong Yang 

Per ACPI 6.5 Table 5.158: Processor Structure Flags, the identical
implementation flag indicates whether all the children processors
of this node share the same identical implementation revision.
Currently Linux support parsing this field [1] and maybe used to
identify the heterogeneous platform. Since qemu only support
homogeneous emulation, set this flag for all the processor node
to indicates the facts when building the PPTT table. Node leaf
is an exception since spec says this flag should be ignored
on leaf nodes by OSPM.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/pptt.c?h=v6.11-rc1#n810

Signed-off-by: Yicong Yang 
Reviewed-by: Jonathan Cameron 
Signed-off-by: Alireza Sanaee 
---
 hw/acpi/aml-build.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index f8f93a9f66..560cee12a2 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -2173,7 +2173,8 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, 
MachineState *ms,
 core_id = -1;
 socket_offset = table_data->len - pptt_start;
 build_processor_hierarchy_node(table_data,
-(1 << 0), /* Physical package */
+(1 << 0) | /* Physical package */
+(1 << 4), /* Identical Implementation */
 0, socket_id, NULL, 0);
 }
 
@@ -2184,7 +2185,8 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, 
MachineState *ms,
 core_id = -1;
 cluster_offset = table_data->len - pptt_start;
 build_processor_hierarchy_node(table_data,
-(0 << 0), /* Not a physical package */
+(0 << 0) | /* Not a physical package */
+(1 << 4), /* Identical Implementation */
 socket_offset, cluster_id, NULL, 0);
 }
 } else {
@@ -2202,7 +2204,8 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, 
MachineState *ms,
 core_id = cpus->cpus[n].props.core_id;
 core_offset = table_data->len - pptt_start;
 build_processor_hierarchy_node(table_data,
-(0 << 0), /* Not a physical package */
+(0 << 0) | /* Not a physical package */
+(1 << 4), /* Identical Implementation */
 cluster_offset, core_id, NULL, 0);
 }
 
-- 
2.43.0




Re: [PATCH 39/57] qapi/source: allow multi-line QAPISourceInfo advancing

2025-03-05 Thread Markus Armbruster
John Snow  writes:

> On Wed, Mar 5, 2025 at 5:35 AM Markus Armbruster  wrote:
>
>> John Snow  writes:
>>
>> > This is for the sake of the new rST generator (the "transmogrifier") so
>> > we can advance multiple lines on occasion while keeping the
>> > generated<-->source mappings accurate.
>> >
>> > next_line now simply takes an optional n parameter which chooses the
>> > number of lines to advance.
>> >
>> > RFC: Here's the exorbitant detail on why I want this:
>> >
>> > This is used mainly when converting section syntax in free-form
>> > documentation to more traditional rST section header syntax, which
>> > does not always line up 1:1 for line counts.
>>
>> Obvious way to resolve the RFC:
>>
>>   The next patch will use this when converting ...
>>
>> >
>> > For example:
>> >
>> > ```
>> >  ##
>> >  # = Section <-- Info is pointing here, "L1"
>> >  #
>> >  # Lorem Ipsum
>> >  ##
>> > ```
>> >
>> > would be transformed to rST as:
>> >
>> > ```
>> > ===<-- L1
>> > Section<-- L1
>> > ===<-- L1
>> ><-- L2
>> > Lorem Ipsum<-- L3
>> > ```
>>
>> Not a demand, just wondering: could we drop our headings syntax and just
>> use rST?
>>
>
> Yes, once we drop the old qapidoc fully, which I am not sure I can do
> before freeze ... So we have some goofy stuff in the meantime.

No need to do it before the freeze.  Trying to do it before might be
self-sabotage ;)

> You suggested before I can rewrite the freeform generator to avoid needing
> this; I wrote the freeform generator to be as close to the old one as I
> could, but we could kerjiggle it if needed.
>
> ... On the other hand, this is a patch for a += n, so... eh.
>
> --js




Re: [PATCH] pci-ids.rst: Add Red Hat pci-id for AMD IOMMU device

2025-03-05 Thread Yan Vugenfirer
On Wed, Mar 5, 2025 at 8:54 AM Michael S. Tsirkin  wrote:

> On Tue, Mar 04, 2025 at 06:37:47PM +, Suravee Suthikulpanit wrote:
> > The QEMU-emulated AMD IOMMU PCI device is implemented based on the AMD
> I/O
> > Virtualization Technology (IOMMU) Specification [1]. The PCI id for this
> > device is platform-specific.
> >
> > Currently, the QEMU-emulated AMD IOMMU device is using AMD vendor id and
> > undefined device id.
>
> undefined?
>
> > Therefore, change the vendor id to Red Hat and request a new
> QEMU-specific
> > device id.
>
> Won't the drivers fail to load then?
>

Windows will not identify the device (it is a dummy device, without driver)
and SVVP certifications will fail as a result.
I suggest using ID that is already present in Windows machine.inf:
VEN_1002&DEV_5A23
VEN_1022&DEV_1419


>
> >
> > [1]
> https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/specifications/48882_IOMMU.pdf
>
> what is this link teaching us? It's a 300 page document. Where to look
> in there?
>
> > Cc: Gerd Hoffmann 
> > Signed-off-by: Suravee Suthikulpanit 
> > ---
> >  docs/specs/pci-ids.rst | 2 ++
> >  hw/i386/amd_iommu.c| 3 ++-
> >  include/hw/pci/pci.h   | 1 +
> >  3 files changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/docs/specs/pci-ids.rst b/docs/specs/pci-ids.rst
> > index 261b0f359f..2416a70a2d 100644
> > --- a/docs/specs/pci-ids.rst
> > +++ b/docs/specs/pci-ids.rst
> > @@ -100,6 +100,8 @@ PCI devices (other than virtio):
> >PCI UFS device (``-device ufs``)
> >  1b36:0014
> >PCI RISC-V IOMMU device
> > +1b36:0015
> > +  PCI AMD IOMMU device (``-device amd-iommu``)
> >
> >  All these devices are documented in :doc:`index`.
> >
> > diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
> > index dda1a5781f..4d8564249c 100644
> > --- a/hw/i386/amd_iommu.c
> > +++ b/hw/i386/amd_iommu.c
> > @@ -1766,7 +1766,8 @@ static void amdvi_pci_class_init(ObjectClass
> *klass, void *data)
> >  DeviceClass *dc = DEVICE_CLASS(klass);
> >  PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> >
> > -k->vendor_id = PCI_VENDOR_ID_AMD;
> > +k->vendor_id = PCI_VENDOR_ID_REDHAT;
> > +k->device_id = PCI_DEVICE_ID_REDHAT_AMD_IOMMU;
> >  k->class_id = 0x0806;
> >  k->realize = amdvi_pci_realize;
> >
> > diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> > index 4002bbeebd..da44e6673d 100644
> > --- a/include/hw/pci/pci.h
> > +++ b/include/hw/pci/pci.h
> > @@ -117,6 +117,7 @@ extern bool pci_available;
> >  #define PCI_DEVICE_ID_REDHAT_ACPI_ERST   0x0012
> >  #define PCI_DEVICE_ID_REDHAT_UFS 0x0013
> >  #define PCI_DEVICE_ID_REDHAT_RISCV_IOMMU 0x0014
> > +#define PCI_DEVICE_ID_REDHAT_AMD_IOMMU   0x0015
> >  #define PCI_DEVICE_ID_REDHAT_QXL 0x0100
> >
> >  #define FMT_PCIBUS  PRIx64
> > --
> > 2.34.1
>
>
>


Re: [PULL v5 09/11] hw/arm: introduce xenpvh machine

2025-03-05 Thread Philippe Mathieu-Daudé

On 6/3/25 01:13, Edgar E. Iglesias wrote:


On Wed, Mar 5, 2025 at 5:22 PM Stefano Stabellini 
mailto:sstabell...@kernel.org>> wrote:


+Edgar

On Wed, 5 Mar 2025, Philippe Mathieu-Daudé wrote:
 > On 16/6/23 01:52, Stefano Stabellini wrote:
 > > From: Vikram Garhwal mailto:vikram.garh...@amd.com>>
 > >
 > > Add a new machine xenpvh which creates a IOREQ server to
register/connect
 > > with
 > > Xen Hypervisor.
 > >
 > > Optional: When CONFIG_TPM is enabled, it also creates a tpm-
tis-device, adds
 > > a
 > > TPM emulator and connects to swtpm running on host machine via
chardev
 > > socket
 > > and support TPM functionalities for a guest domain.
 > >
 > > Extra command line for aarch64 xenpvh QEMU to connect to swtpm:
 > >      -chardev socket,id=chrtpm,path=/tmp/myvtpm2/swtpm-sock \
 > >      -tpmdev emulator,id=tpm0,chardev=chrtpm \
 > >      -machine tpm-base-addr=0x0c00 \
 > >
 > > swtpm implements a TPM software emulator(TPM 1.2 & TPM 2) built
on libtpms
 > > and
 > > provides access to TPM functionality over socket, chardev and CUSE
 > > interface.
 > > Github repo: https://github.com/stefanberger/swtpm 
 > > Example for starting swtpm on host machine:
 > >      mkdir /tmp/vtpm2
 > >      swtpm socket --tpmstate dir=/tmp/vtpm2 \
 > >      --ctrl type=unixio,path=/tmp/vtpm2/swtpm-sock &
 > >
 > > Signed-off-by: Vikram Garhwal mailto:vikram.garh...@amd.com>>
 > > Signed-off-by: Stefano Stabellini mailto:stefano.stabell...@amd.com>>
 > > Reviewed-by: Stefano Stabellini mailto:sstabell...@kernel.org>>
 > > ---
 > >   docs/system/arm/xenpvh.rst    |  34 +++
 > >   docs/system/target-arm.rst    |   1 +
 > >   hw/arm/meson.build            |   2 +
 > >   hw/arm/xen_arm.c              | 181 +
+
 > >   include/hw/arm/xen_arch_hvm.h |   9 ++
 > >   include/hw/xen/arch_hvm.h     |   2 +
 > >   6 files changed, 229 insertions(+)
 > >   create mode 100644 docs/system/arm/xenpvh.rst
 > >   create mode 100644 hw/arm/xen_arm.c
 > >   create mode 100644 include/hw/arm/xen_arch_hvm.h
 >
 >
 > > diff --git a/include/hw/xen/arch_hvm.h b/include/hw/xen/arch_hvm.h
 > > index 26674648d8..c7c515220d 100644
 > > --- a/include/hw/xen/arch_hvm.h
 > > +++ b/include/hw/xen/arch_hvm.h
 > > @@ -1,3 +1,5 @@
 > >   #if defined(TARGET_I386) || defined(TARGET_X86_64)
 > >   #include "hw/i386/xen_arch_hvm.h"
 > > +#elif defined(TARGET_ARM) || defined(TARGET_ARM_64)
 >
 > I suppose this is a typo and you meant TARGET_AARCH64 :)
 > Luckily TARGET_AARCH64 defines TARGET_ARM.

Hi Philippe, it looks like this is an older patch.

Edgar, is this patch still valid?


Hi,

Yes, I think Phil is right, this works by luck and should have been 
TARGET_AARCH64.

Phil, will you send a patch?


On the list:
https://lore.kernel.org/qemu-devel/20250305153929.43687-2-phi...@linaro.org/

But IIUC since there is no vCPU emulated in HVM I wonder why the
32/64-bit distinction matters here.



Re: [PATCH v5 0/2] s390x/pci: relax I/O address translation requirement

2025-03-05 Thread Thomas Huth

On 26/02/2025 22.00, Matthew Rosato wrote:

This series introduces the concept of the relaxed translation requirement
for s390x guests in order to allow bypass of the guest IOMMU for more
efficient PCI passthrough.

With this series, QEMU can indicate to the guest that an IOMMU is not
strictly required for a zPCI device.  This would subsequently allow a
guest linux to use iommu.passthrough=1 and bypass their guest IOMMU for
PCI devices.

When this occurs, QEMU will note the behavior via an intercepted MPCIFC
instruction and will fill the host iommu with mappings of the entire
guest address space in response.

The kernel series [1] that adds the relevant behavior needed to
exploit this new feature from within a s390x linux guest is available
in linux-next via iommu-next.

[1]: 
https://lore.kernel.org/linux-s390/20250212213418.182902-1-mjros...@linux.ibm.com/

Changes for v5:
- Add some review/test tags (had to drop some due to code changes)
- Dynamically allocate iommu->dm_mr, remove direct_map bool

Changes for v4:
- use get_system_memory() instead of ms->ram
- rename rtr_allowed to rtr_avail
- turn off rtr_avail for emulated devices so MPCFIC fence properly
   rejects an attempt at direct mapping (we only advertise via CLP
   for passthrough devices)
- turn off rtr_avail for passthrough ISM devices
- various minor changes

Changes for v3:
- use s390_get_memory_limit
- advertise full aperture for relaxed-translation-capable devices

Changes for v2:
- Add relax-translation property, fence for older machines
- Add a new MPCIFC failure case when direct-mapping requested but
   the relax-translation property is set to off.
- For direct mapping, use a memory alias to handle the SMDA offset and
   then just let vfio handle the pinning of memory.

Matthew Rosato (2):
   s390x/pci: add support for guests that request direct mapping
   s390x/pci: indicate QEMU supports relaxed translation for passthrough

  hw/s390x/s390-pci-bus.c | 39 +++--
  hw/s390x/s390-pci-inst.c| 13 +--
  hw/s390x/s390-pci-vfio.c| 28 ++-
  hw/s390x/s390-virtio-ccw.c  |  5 +
  include/hw/s390x/s390-pci-bus.h |  3 +++
  include/hw/s390x/s390-pci-clp.h |  1 +
  6 files changed, 80 insertions(+), 9 deletions(-)



Series
Acked-by: Thomas Huth 

I'll queue it for my next pull request.

 Thomas




Re: [PATCH 00/57] docs: Add new QAPI transmogrifier

2025-03-05 Thread Markus Armbruster
John Snow  writes:

> On Wed, Mar 5, 2025, 6:31 AM Markus Armbruster  wrote:
>
>> John Snow  writes:
>>
>> > Hi! This series is based on armbru/pull-qapi-2025-02-26.
>> >
>> > This series is a "minimum viable" version of the new QAPI documentation
>> > system. It does the bare minimum under the new framework, saving nice
>> > features for later.
>>
>> Not saved for later: a massive improvement of the generated
>> documentation's looks and usability.  Moreover, I hope the new generator
>> will be easier to maintain than the old one, because its inner workings
>> are closer to how Sphinx expects such things to work.  Fair?
>>
>
> I hope so too, though some of the sphinx version compatibility hacks are
> possibly fairly porcelain. The most egregious of them are for versions
> prior to Sphinx 4.1.
>
> Almost all of the compatibility hacks are factored into compat.py and they
> are all documented with what versions they're there for. Most of the
> ugliest is pre-4.1.

[...]

> It's the stuff in compat.py that was the absolute hardest. You need that
> stuff for this to work on the version ranges it works for, but typing it
> was an extra special torture.

Supporting such a wide range of versions is *expensive*.

Writing compat.py is sunk cost.

Maintaining it is not.  It's fragile hacks, hard to understand even with
deep Sphinx innards expertise, impossible to understand without.  I
figure if we somehow lost your expertise, we'd likely have to drop
support for old Sphinx the moment compat.py breaks.

Just because we can solve certain hard problems doesn't mean we should.
I question the wisdom of supporting such a wide range of Sphinx
versions.




Re: [PATCH 21/57] docs/qapi-domain: add :deprecated: directive option

2025-03-05 Thread Markus Armbruster
John Snow  writes:

> On Wed, Mar 5, 2025, 4:13 AM Markus Armbruster  wrote:

[...]

>> pylint warns:
>>
>> docs/sphinx/qapi_domain.py:279:4: W0237: Parameter 'contentnode' has
>> been renamed to 'content_node' in overriding 'QAPIObject.transform_content'
>> method (arguments-renamed)
>>
>> For what it's worth, @content_node is easier on on my eyes than
>> @contentnode.
>>
>
> Almost certifiably a Sphinx version difference that I simply won't be able
> to accommodate. It comes back clean against 8.x, and does not impact the
> runtime functionality at all.

If that's the case, don't worry about it.

[...]




Re: [RFC v4 0/5] Add packed virtqueue to shadow virtqueue

2025-03-05 Thread Eugenio Perez Martin
On Thu, Mar 6, 2025 at 6:26 AM Sahil Siddiq  wrote:
>
> Hi,
>
> Sorry for the delay in my response. There was a lot to absorb in the
> previous mail and I thought I would spend some more time exploring
> this.
>
> On 2/11/25 1:27 PM, Eugenio Perez Martin wrote:
> > On Mon, Feb 10, 2025 at 5:25 PM Sahil Siddiq  wrote:
> >> On 2/10/25 7:53 PM, Eugenio Perez Martin wrote:
> >>> On Mon, Feb 10, 2025 at 11:58 AM Sahil Siddiq  
> >>> wrote:
>  On 2/6/25 8:47 PM, Sahil Siddiq wrote:
> > On 2/6/25 12:42 PM, Eugenio Perez Martin wrote:
> >> On Thu, Feb 6, 2025 at 6:26 AM Sahil Siddiq  
> >> wrote:
> >>> On 2/4/25 11:45 PM, Eugenio Perez Martin wrote:
>  PS: Please note that you can check packed_vq SVQ implementation
>  already without CVQ, as these features are totally orthogonal :).
> 
> >>>
> >>> Right. Now that I can ping with the ctrl features turned off, I think
> >>> this should take precedence. There's another issue specific to the
> >>> packed virtqueue case. It causes the kernel to crash. I have been
> >>> investigating this and the situation here looks very similar to what's
> >>> explained in Jason Wang's mail [2]. My plan of action is to apply his
> >>> changes in L2's kernel and check if that resolves the problem.
> >>>
> >>> The details of the crash can be found in this mail [3].
> >>>
> >>
> >> If you're testing this series without changes, I think that is caused
> >> by not implementing the packed version of vhost_svq_get_buf.
> >>
> >> https://lists.nongnu.org/archive/html/qemu-devel/2024-12/msg01902.html
> >>
> >
> > Oh, apologies, I think I had misunderstood your response in the linked 
> > mail.
> > Until now, I thought they were unrelated. In that case, I'll implement 
> > the
> > packed version of vhost_svq_get_buf. Hopefully that fixes it :).
> >
> 
>  I noticed one thing while testing some of the changes that I have made.
>  I haven't finished making the relevant changes to all the functions which
>  will have to handle split and packed vq differently. L2's kernel crashes
>  when I launch L0-QEMU with ctrl_vq=on,ctrl_rx=on.
> >>>
> >>> Interesting, is a similar crash than this? (NULL ptr deference on
> >>> virtnet_set_features)?
> >>>
> >>> https://issues.redhat.com/browse/RHEL-391
> >> I am not able to access this bug report (even with a Red Hat account). It
> >> says it may have been deleted or I don't have the permission to view it.
> >>
> >> It's hard to tell if this is the same issue. I don't think it is the same
> >> issue though since I don't see any such indication in the logs. The kernel
> >> throws the following:
> >>
> >> [   23.047503] virtio_net virtio1: output.0:id 0 is not a head!
> >
> > This is a common error when modifying code of the dataplane, it is
> > unlikely to do deep changes and not see this error :). It indicates
> > that your code is marking the descriptor id 0 as used when the guest
> > didn't make it available.
>
> Right, I explored this a little further. I noticed that there were
> a few issues in my implementation with the way packed vqs were being
> handled (apart from the lack of implementation of
> vhost_svq_get_buf_packed). After making the relevant changes and
> implementing vhost_svq_get_buf_packed, I couldn't see this issue
> anymore.
>
> > If this is happening in control virtqueue, I'd check if the code is
> > setting the flags as used in ring[1] when it shouldn't. But my bet is
> > that the rx queue is the wrong one.
>
> The flags were one of the issues. I hadn't initialized "avail_used_flags"
> correctly. Rectifying them seems to have solved this issue. However, I see
> two new issues (described further below).
>
> >> [   49.173243] watchdog: BUG: soft lockup - CPU#1 stuck for 25s! 
> >> [NetworkManager:782]
> >> [   49.174167] Modules linked in: rfkill intel_rapl_msr intel_rapl_common 
> >> intel_uncore_frequency_common intel_pmc_core intel_vsec pmt_telemetry 
> >> pmt_class kvg
> >> [   49.188258] CPU: 1 PID: 782 Comm: NetworkManager Not tainted 
> >> 6.8.7-200.fc39.x86_64 #1
> >> [   49.193196] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 
> >> rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
> >> [   49.193196] RIP: 0010:virtqueue_get_buf+0x0/0x20
> >>
> >
> > Two possibilities about this part:
> > a) You're spending "too long" in the debugger in QEMU. From the kernel
> > POV, the function virtqueue_get_buf is taking too long to complete so
> > it detects it as a lockup. You can check this scenario by not running
> > QEMU under GDB or disabling all breakpoints. You can ignore this
> > message if you don't find the error this way. If you still see the
> > message, goto possibility b.
> >
> > b) The kernel has a bug that makes it softlockup in virtqueue_get_buf.
> > The kernel should not soft lockup even if your changes were malicious
> > :(, so it is something to be fixed. If

Re: [PATCH v2 1/2] target/riscv: Add scontext CSR handling

2025-03-05 Thread Alistair Francis
On Mon, Mar 3, 2025 at 7:39 PM Florian Lugou
 wrote:
>
> scontext size is 16 bits on RV32 and 32 bits on RV64, as recommended by
> version 1.0 2025-02-21 of the debug specification.

Section 5.7.8 indicates the register is XLEN bits wide, with data
being 32-bits wide for both RV32 and RV64.

Alistair

>
> When the Smstateen extension is implemented, accessibility to the
> scontext CSR is controlled by bit 57 of the [mh]stateen0 CSRs.
>
> Signed-off-by: Florian Lugou 
> ---
>  target/riscv/cpu.h  |  1 +
>  target/riscv/cpu_bits.h |  5 +
>  target/riscv/csr.c  | 36 
>  target/riscv/debug.c|  1 +
>  4 files changed, 43 insertions(+)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 616c3bdc1c..102e8285a6 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -440,6 +440,7 @@ struct CPUArchState {
>  target_ulong tdata2[RV_MAX_TRIGGERS];
>  target_ulong tdata3[RV_MAX_TRIGGERS];
>  target_ulong mcontext;
> +target_ulong scontext;
>  struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
>  struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
>  QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index a30317c617..e8997f3153 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -258,6 +258,9 @@
>  /* VS-Level Control transfer records CSRs */
>  #define CSR_VSCTRCTL0x24e
>
> +/* Supervisor-Level Sdtrig CSRs (debug) */
> +#define CSR_SCONTEXT0x5a8
> +
>  /* Hpervisor CSRs */
>  #define CSR_HSTATUS 0x600
>  #define CSR_HEDELEG 0x602
> @@ -1103,4 +1106,6 @@ typedef enum CTRType {
>  #define MCONTEXT64 0x1FFFULL
>  #define MCONTEXT32_HCONTEXT0x007F
>  #define MCONTEXT64_HCONTEXT0x3FFFULL
> +#define SCONTEXT32 0x
> +#define SCONTEXT64 0xULL
>  #endif
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 0ebcca4597..37b38f24a6 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3393,6 +3393,10 @@ static RISCVException write_mstateen0(CPURISCVState 
> *env, int csrno,
>  wr_mask |= SMSTATEEN0_P1P13;
>  }
>
> +if (riscv_cpu_cfg(env)->debug) {
> +wr_mask |= SMSTATEEN0_HSCONTXT;
> +}
> +
>  if (riscv_cpu_cfg(env)->ext_smaia || riscv_cpu_cfg(env)->ext_smcsrind) {
>  wr_mask |= SMSTATEEN0_SVSLCT;
>  }
> @@ -5321,6 +5325,35 @@ static RISCVException write_mcontext(CPURISCVState 
> *env, int csrno,
>  return RISCV_EXCP_NONE;
>  }
>
> +static RISCVException read_scontext(CPURISCVState *env, int csrno,
> +target_ulong *val)
> +{
> +RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSCONTXT);
> +if (ret != RISCV_EXCP_NONE) {
> +return ret;
> +}
> +
> +*val = env->scontext;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_scontext(CPURISCVState *env, int csrno,
> + target_ulong val)
> +{
> +bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
> +
> +RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSCONTXT);
> +if (ret != RISCV_EXCP_NONE) {
> +return ret;
> +}
> +
> +/* Spec suggest 16-bit for RV32 and 34-bit for RV64 */
> +target_ulong mask = rv32 ? SCONTEXT32 : SCONTEXT64;
> +
> +env->scontext = val & mask;
> +return RISCV_EXCP_NONE;
> +}
> +
>  static RISCVException read_mnscratch(CPURISCVState *env, int csrno,
>   target_ulong *val)
>  {
> @@ -5973,6 +6006,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>  [CSR_SIEH]   = { "sieh",   aia_smode32, NULL, NULL, rmw_sieh },
>  [CSR_SIPH]   = { "siph",   aia_smode32, NULL, NULL, rmw_siph },
>
> +/* Supervisor-Level Sdtrig CSRs (debug) */
> +[CSR_SCONTEXT]   = { "scontext", debug, read_scontext, write_scontext },
> +
>  [CSR_HSTATUS] = { "hstatus", hmode,   read_hstatus, 
> write_hstatus,
>.min_priv_ver = PRIV_VERSION_1_12_0
> },
>  [CSR_HEDELEG] = { "hedeleg", hmode,   read_hedeleg, 
> write_hedeleg,
> diff --git a/target/riscv/debug.c b/target/riscv/debug.c
> index 9db4048523..072593ab12 100644
> --- a/target/riscv/debug.c
> +++ b/target/riscv/debug.c
> @@ -1088,4 +1088,5 @@ void riscv_trigger_reset_hold(CPURISCVState *env)
>  }
>
>  env->mcontext = 0;
> +env->scontext = 0;
>  }
> --
> 2.43.0
>
>



Re: [PATCH v2 0/9] vfio/igd: Decoupling quirks with legacy mode

2025-03-05 Thread Cédric Le Goater

Tomita,

On 3/3/25 18:52, Tomita Moeko wrote:

This patchset intends to decouple existing quirks from legacy mode.
Currently all quirks depends on legacy mode (except x-igd-opregion),
which includes following conditions:
* Machine type is i440fx
* IGD device is at guest BDF 00:02.0
* VBIOS in ROM BAR or file
* VGA IO/MMIO ranges are claimed by IGD
* OpRegion
* Same LPC bridge and Host bridge VID/DID/SVID/SSID as host

If one of the condition is not met, the quirks will not be applied.
However, for recent generations, espcially Gen 11+ devices that removed
VBIOS support, not all the conditions are required. For example, on EFI-
based systems, VBIOS ROM is unnecessary, and VGA ranges are not used.

To have better support on newer UEFI-based VMs, this patchset makes the
quirks independent of legacy mode. The BDSM and GGC register quirks are
applied to all supported IGD devices, new x-igd-lpc option for the LPC
bridge / Host bridge ID quirk is introduced for possible Q35 support.
It also prepares for supporting IGD passthrough when it is not primary
display later (kernel change will be merged in 6.15).

To maintain backward compatbility with exising configuration, legacy
mode will automatically be enabled when:
* Machine type is i440fx
* IGD device is at guest BDF 00:02.0
If the legacy mode behavior is unwanted, option x-igd-legacy-mode=off
is provided for users to disable it.

Note that a major difference is that instead of simply continues, legacy
mode will now fail immediately on error, this may break functionality,
but the impact should be low as IGD passthrough is not working, and
there would be no display output if it fails halfway.

The first 2 patches of this patchset was taken from a previous one,
details can be found at:
https://lore.kernel.org/all/20250124191245.12464-1-tomitamo...@gmail.com/

This patchest was mainly tested on Alder Lake UHD770, with Debian 12
(kernel 6.1), Windows 11 (driver 32.0.101.6458) and Intel GOP driver
17.0.1081.

Btw, documentation change would be added after everyone considers the
proposed change is okay.


Changelog:
v2:
* Keep legacy mode for compatbility
* Renamed from "vfio/igd: Remove legacy mode"
Link: https://lore.kernel.org/all/20250224182927.31519-1-tomitamo...@gmail.com/



QEMU 10.0 soft-freeze is next week. I plan to send a PR at the end
of this week.

Thanks,

C.





Re: [PATCH 2/2] target/riscv: fixes a bug against `ssamoswap` behavior in M-mode

2025-03-05 Thread Deepak Gupta

On Thu, Mar 06, 2025 at 04:22:52PM +1000, Alistair Francis wrote:

On Thu, Mar 6, 2025 at 4:13 PM Deepak Gupta  wrote:


On Thu, Mar 06, 2025 at 03:29:00PM +1000, Alistair Francis wrote:
>On Tue, Feb 18, 2025 at 12:57 PM Deepak Gupta  wrote:
>>
>> Commit f06bfe3dc38c ("target/riscv: implement zicfiss instructions") adds
>> `ssamoswap` instruction. `ssamoswap` takes the code-point from existing
>> reserved encoding (and not a zimop like other shadow stack instructions).
>> If shadow stack is not enabled (via xenvcfg.SSE), then `ssamoswap` must
>> result in an illegal instruction exception. However there is a slightly
>> modified behavior for M-mode.
>>
>> Shadow stack are not available in M-mode and all shadow stack instructions
>> in M-mode exhibit zimop behavior. However, `ssamoswap` can still succeed
>> if MPRV=1 and MPP is non-zero (see section 2.7 of zicfiss specification).
>> This patch corrects that behavior for `ssamoswap`.
>
>Section "22.2.3. Shadow Stack Memory Protection " of the latest priv
>spec [1] seems to say: "When the effective privilege mode is M, any
>memory access by an SSAMOSWAP.W/D
>instruction will result in a store/AMO access-fault exception."

Hmm I didn't look at priv spec. Let me fix this one.


I hope the two don't conflict, that will be a nightmare


No they don't conflict. Last "else" block below basically means that
it should be store/AMO access fault because there is no shadow stack page.

"""
if privilege_mode != M && menvcfg.SSE == 0
raise illegal-instruction exception
if S-mode not implemented
raise illegal-instruction exception
else if privilege_mode == U && senvcfg.SSE == 0
raise illegal-instruction exception
else if privilege_mode == VS && henvcfg.SSE == 0
raise virtual instruction exception
else if privilege_mode == VU && senvcfg.SSE == 0
raise virtual instruction exception
else
temp[31:0] = mem[X(rs1)]
X(rd) = SignExtend(temp[31:0])
mem[X(rs1)] = X(rs2)[31:0]
endif
"""


Alistair



>
>1: 
https://github.com/riscv/riscv-isa-manual/releases/tag/riscv-isa-release-9cfaf37-2025-03-06
>
>Alistair
>
>>
>> Fixes: f06bfe3dc38c ("target/riscv: implement zicfiss instructions")
>>
>> Reported-by: Ved Shanbhogue 
>> Signed-off-by: Deepak Gupta 
>> ---
>>  target/riscv/insn_trans/trans_rvzicfiss.c.inc | 13 +++--
>>  1 file changed, 11 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/riscv/insn_trans/trans_rvzicfiss.c.inc 
b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
>> index e3ebc4977c..ec016cd70f 100644
>> --- a/target/riscv/insn_trans/trans_rvzicfiss.c.inc
>> +++ b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
>> @@ -15,6 +15,13 @@
>>   * You should have received a copy of the GNU General Public License along 
with
>>   * this program.  If not, see .
>>   */
>> +
>> + #define REQUIRE_ZICFISS(ctx) do {   \
>> +if (!ctx->cfg_ptr->ext_zicfiss) {\
>> +return false;\
>> +}\
>> +} while (0)
>> +
>>  static bool trans_sspopchk(DisasContext *ctx, arg_sspopchk *a)
>>  {
>>  if (!ctx->bcfi_enabled) {
>> @@ -77,7 +84,8 @@ static bool trans_ssrdp(DisasContext *ctx, arg_ssrdp *a)
>>  static bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a)
>>  {
>>  REQUIRE_A_OR_ZAAMO(ctx);
>> -if (!ctx->bcfi_enabled) {
>> +REQUIRE_ZICFISS(ctx);
>> +if ((ctx->priv != PRV_M) && !ctx->bcfi_enabled) {
>>  return false;
>>  }
>>
>> @@ -97,7 +105,8 @@ static bool trans_ssamoswap_d(DisasContext *ctx, 
arg_amoswap_w *a)
>>  {
>>  REQUIRE_64BIT(ctx);
>>  REQUIRE_A_OR_ZAAMO(ctx);
>> -if (!ctx->bcfi_enabled) {
>> +REQUIRE_ZICFISS(ctx);
>> +if ((ctx->priv != PRV_M) && !ctx->bcfi_enabled) {
>>  return false;
>>  }
>>
>> --
>> 2.34.1
>>
>>




Re: [PATCH 1/2] target/riscv: fix access permission checks for CSR_SSP

2025-03-05 Thread Deepak Gupta

On Thu, Mar 06, 2025 at 04:20:56PM +1000, Alistair Francis wrote:

On Thu, Mar 6, 2025 at 4:12 PM Deepak Gupta  wrote:


On Thu, Mar 06, 2025 at 03:20:55PM +1000, Alistair Francis wrote:
>On Tue, Feb 18, 2025 at 12:56 PM Deepak Gupta  wrote:
>>
>> Commit:8205bc1 ("target/riscv: introduce ssp and enabling controls for
>> zicfiss") introduced CSR_SSP but it mis-interpreted the spec on access
>> to CSR_SSP in M-mode. Gated to CSR_SSP is not gated via `xSSE`. But
>> rather rules clearly specified in section "2.2.4. Shadow Stack Pointer"
>
>Do you mean "22.2.1. Shadow Stack Pointer (ssp) CSR access contr" in
>the priv spec?

No I meant 2.2.4 of zicfiss specification. Section 22.2.1 of priv spec
says same.


I meant that it's now just in the priv spec, the zicfiss spec is no
longer maintained so we should just reference the priv spec


Got it.



Alistair



>
>> of `zicfiss` specification. Thanks to Adam Zabrocki for bringing this
>> to attention.
>
>The thanks should probably be below the line

Sure

>
>>
>> Fixes: 8205bc127a83 ("target/riscv: introduce ssp and enabling controls
>> for zicfiss"
>>
>> Reported-by: Adam Zabrocki 
>> Signed-off-by: Deepak Gupta 
>
>The actual change looks good:
>
>Reviewed-by: Alistair Francis 
>
>Alistair
>
>> ---
>>  target/riscv/csr.c | 5 +
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
>> index afb7544f07..75c661d2a1 100644
>> --- a/target/riscv/csr.c
>> +++ b/target/riscv/csr.c
>> @@ -191,6 +191,11 @@ static RISCVException cfi_ss(CPURISCVState *env, int 
csrno)
>>  return RISCV_EXCP_ILLEGAL_INST;
>>  }
>>
>> +/* If ext implemented, M-mode always have access to SSP CSR */
>> +if (env->priv == PRV_M) {
>> +return RISCV_EXCP_NONE;
>> +}
>> +
>>  /* if bcfi not active for current env, access to csr is illegal */
>>  if (!cpu_get_bcfien(env)) {
>>  #if !defined(CONFIG_USER_ONLY)
>> --
>> 2.34.1
>>
>>




RE: [PATCH v4 17/23] hw/arm/aspeed_ast27x0.c Support AST2700 A1 GIC Interrupt Mapping

2025-03-05 Thread Jamin Lin
Hi Cedric,

> Subject: Re: [PATCH v4 17/23] hw/arm/aspeed_ast27x0.c Support AST2700 A1
> GIC Interrupt Mapping
> 
> On 3/3/25 10:54, Jamin Lin wrote:
> > Currently, these IRQ tables support from GIC 128 - 136 for AST2700 A0.
> > These IRQ tables can be reused for AST2700 A1 from GIC 192 - 197.
> > Updates the interrupt mapping to include support for AST2700 A1 by
> > extending the existing mappings to the new GIC range.
> >
> > Signed-off-by: Jamin Lin 
> > ---
> >   hw/arm/aspeed_ast27x0.c | 82
> ++---
> >   1 file changed, 52 insertions(+), 30 deletions(-)
> >
> > diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
> > 09aad69e3c..eab9674b6c 100644
> > --- a/hw/arm/aspeed_ast27x0.c
> > +++ b/hw/arm/aspeed_ast27x0.c
> > @@ -120,21 +120,27 @@ static const int aspeed_soc_ast2700a0_irqmap[] =
> {
> >   };
> >
> >   /* GICINT 128 */
> > -static const int aspeed_soc_ast2700_gic128_intcmap[] = {
> > +/* GICINT 192 */
> > +static const int ast2700_gic128_gic192_intcmap[] = {
> >   [ASPEED_DEV_LPC]   = 0,
> >   [ASPEED_DEV_IBT]   = 2,
> >   [ASPEED_DEV_KCS]   = 4,
> >   };
> >
> > +/* GICINT 129 */
> > +/* GICINT 193 */
> > +
> >   /* GICINT 130 */
> > -static const int aspeed_soc_ast2700_gic130_intcmap[] = {
> > +/* GICINT 194 */
> > +static const int ast2700_gic130_gic194_intcmap[] = {
> >   [ASPEED_DEV_I2C]= 0,
> >   [ASPEED_DEV_ADC]= 16,
> >   [ASPEED_DEV_GPIO]   = 18,
> >   };
> >
> >   /* GICINT 131 */
> > -static const int aspeed_soc_ast2700_gic131_intcmap[] = {
> > +/* GICINT 195 */
> > +static const int ast2700_gic131_gic195_intcmap[] = {
> >   [ASPEED_DEV_I3C]   = 0,
> >   [ASPEED_DEV_WDT]   = 16,
> >   [ASPEED_DEV_FMC]   = 25,
> > @@ -142,7 +148,8 @@ static const int
> aspeed_soc_ast2700_gic131_intcmap[] = {
> >   };
> >
> >   /* GICINT 132 */
> > -static const int aspeed_soc_ast2700_gic132_intcmap[] = {
> > +/* GICINT 196 */
> > +static const int ast2700_gic132_gic196_intcmap[] = {
> >   [ASPEED_DEV_ETH1]  = 0,
> >   [ASPEED_DEV_ETH2]  = 1,
> >   [ASPEED_DEV_ETH3]  = 2,
> > @@ -161,24 +168,26 @@ static const int
> aspeed_soc_ast2700_gic132_intcmap[] = {
> >   };
> >
> >   /* GICINT 133 */
> > -static const int aspeed_soc_ast2700_gic133_intcmap[] = {
> > +/* GICINT 197 */
> > +static const int ast2700_gic133_gic197_intcmap[] = {
> >   [ASPEED_DEV_SDHCI] = 1,
> >   [ASPEED_DEV_PECI]  = 4,
> >   };
> >
> >   /* GICINT 128 ~ 136 */
> > +/* GICINT 192 ~ 201 */
> >   struct gic_intc_irq_info {
> >   int irq;
> >   const int *ptr;
> >   };
> >
> > -static const struct gic_intc_irq_info aspeed_soc_ast2700_gic_intcmap[] = {
> > -{128,  aspeed_soc_ast2700_gic128_intcmap},
> > +static const struct gic_intc_irq_info ast2700_gic_intcmap[] = {
> > +{128,  ast2700_gic128_gic192_intcmap},
> >   {129,  NULL},
> > -{130,  aspeed_soc_ast2700_gic130_intcmap},
> > -{131,  aspeed_soc_ast2700_gic131_intcmap},
> > -{132,  aspeed_soc_ast2700_gic132_intcmap},
> > -{133,  aspeed_soc_ast2700_gic133_intcmap},
> > +{130,  ast2700_gic130_gic194_intcmap},
> > +{131,  ast2700_gic131_gic195_intcmap},
> > +{132,  ast2700_gic132_gic196_intcmap},
> > +{133,  ast2700_gic133_gic197_intcmap},
> >   {134,  NULL},
> >   {135,  NULL},
> >   {136,  NULL},
> > @@ -190,11 +199,11 @@ static qemu_irq
> aspeed_soc_ast2700_get_irq(AspeedSoCState *s, int dev)
> >   AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
> >   int i;
> >
> > -for (i = 0; i < ARRAY_SIZE(aspeed_soc_ast2700_gic_intcmap); i++) {
> > -if (sc->irqmap[dev] == aspeed_soc_ast2700_gic_intcmap[i].irq) {
> > -assert(aspeed_soc_ast2700_gic_intcmap[i].ptr);
> > +for (i = 0; i < ARRAY_SIZE(ast2700_gic_intcmap); i++) {
> > +if (sc->irqmap[dev] == ast2700_gic_intcmap[i].irq) {
> > +assert(ast2700_gic_intcmap[i].ptr);
> >   return qdev_get_gpio_in(DEVICE(&a->intc.orgates[i]),
> > -aspeed_soc_ast2700_gic_intcmap[i].ptr[dev]);
> > +ast2700_gic_intcmap[i].ptr[dev]);
> >   }
> >   }
> >
> > @@ -208,16 +217,17 @@ static qemu_irq
> aspeed_soc_ast2700_get_irq_index(AspeedSoCState *s, int dev,
> >   AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
> >   int i;
> >
> > -for (i = 0; i < ARRAY_SIZE(aspeed_soc_ast2700_gic_intcmap); i++) {
> > -if (sc->irqmap[dev] == aspeed_soc_ast2700_gic_intcmap[i].irq) {
> > -assert(aspeed_soc_ast2700_gic_intcmap[i].ptr);
> > +for (i = 0; i < ARRAY_SIZE(ast2700_gic_intcmap); i++) {
> > +if (sc->irqmap[dev] == ast2700_gic_intcmap[i].irq) {
> > +assert(ast2700_gic_intcmap[i].ptr);
> >   return qdev_get_gpio_in(DEVICE(&a->intc.orgates[i]),
> > -aspeed_soc_ast2700_gic_intcmap[i].ptr[dev] + index);
> > +ast2700_gic_intcm

Re: [PATCH 02/22] target/riscv: Convert misa_mxl_max using GLib macros

2025-03-05 Thread Alistair Francis
On Fri, Feb 28, 2025 at 8:30 PM Paolo Bonzini  wrote:
>
> From: Philippe Mathieu-Daudé 
>
> Use GLib conversion macros to pass misa_mxl_max as
> riscv_cpu_class_init() class data.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> Reviewed-by: Richard Henderson 
> Link: https://lore.kernel.org/r/20250212213249.45574-8-phi...@linaro.org
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 85dc2fe3bec..f05b72ac873 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -2961,7 +2961,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
> *data)
>  {
>  RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
>
> -mcc->misa_mxl_max = (RISCVMXL)(uintptr_t)data;
> +mcc->misa_mxl_max = (RISCVMXL)GPOINTER_TO_UINT(data);
>  riscv_cpu_validate_misa_mxl(mcc);
>  }
>
> @@ -3063,7 +3063,7 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char 
> *nodename)
>  .parent = TYPE_RISCV_DYNAMIC_CPU,   \
>  .instance_init = (initfn),  \
>  .class_init = riscv_cpu_class_init, \
> -.class_data = (void *)(misa_mxl_max)\
> +.class_data = GUINT_TO_POINTER(misa_mxl_max)\
>  }
>
>  #define DEFINE_VENDOR_CPU(type_name, misa_mxl_max, initfn)  \
> @@ -3072,7 +3072,7 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char 
> *nodename)
>  .parent = TYPE_RISCV_VENDOR_CPU,\
>  .instance_init = (initfn),  \
>  .class_init = riscv_cpu_class_init, \
> -.class_data = (void *)(misa_mxl_max)\
> +.class_data = GUINT_TO_POINTER(misa_mxl_max)\
>  }
>
>  #define DEFINE_BARE_CPU(type_name, misa_mxl_max, initfn)\
> @@ -3081,7 +3081,7 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char 
> *nodename)
>  .parent = TYPE_RISCV_BARE_CPU,  \
>  .instance_init = (initfn),  \
>  .class_init = riscv_cpu_class_init, \
> -.class_data = (void *)(misa_mxl_max)\
> +.class_data = GUINT_TO_POINTER(misa_mxl_max)\
>  }
>
>  #define DEFINE_PROFILE_CPU(type_name, misa_mxl_max, initfn) \
> @@ -3090,7 +3090,7 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char 
> *nodename)
>  .parent = TYPE_RISCV_BARE_CPU,  \
>  .instance_init = (initfn),  \
>  .class_init = riscv_cpu_class_init, \
> -.class_data = (void *)(misa_mxl_max)\
> +.class_data = GUINT_TO_POINTER(misa_mxl_max)\
>  }
>
>  static const TypeInfo riscv_cpu_type_infos[] = {
> --
> 2.48.1
>
>



Re: [PATCH 2/7] target/riscv: env->misa_mxl is a constant

2025-03-05 Thread Alistair Francis
On Wed, Feb 19, 2025 at 3:01 AM Paolo Bonzini  wrote:
>
> There is nothing that overwrites env->misa_mxl, so it is a constant.  Do

The idea is that misa_mxl can change, although that's not supported now.

> not let a corrupted migration stream change the value; changing misa_mxl

Does this actually happen? If the migration data is corrupted won't we
have all sorts of strange issues?

Alistair

> would have a snowball effect on, for example, the valid VM modes.
>
> Signed-off-by: Paolo Bonzini 
> ---
>  target/riscv/machine.c | 13 +
>  1 file changed, 13 insertions(+)
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index d8445244ab2..c3d8e7c4005 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -375,6 +375,18 @@ static const VMStateDescription vmstate_ssp = {
>  }
>  };
>
> +static bool riscv_validate_misa_mxl(void *opaque, int version_id)
> +{
> +RISCVCPU *cpu = RISCV_CPU(opaque);
> +CPURISCVState *env = &cpu->env;
> +RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
> +uint32_t misa_mxl_saved = env->misa_mxl;
> +
> +/* Preserve misa_mxl even if the migration stream corrupted it  */
> +env->misa_mxl = mcc->misa_mxl_max;
> +return misa_mxl_saved == mcc->misa_mxl_max;
> +}
> +
>  const VMStateDescription vmstate_riscv_cpu = {
>  .name = "cpu",
>  .version_id = 10,
> @@ -394,6 +406,7 @@ const VMStateDescription vmstate_riscv_cpu = {
>  VMSTATE_UINTTL(env.priv_ver, RISCVCPU),
>  VMSTATE_UINTTL(env.vext_ver, RISCVCPU),
>  VMSTATE_UINT32(env.misa_mxl, RISCVCPU),
> +VMSTATE_VALIDATE("MXL must match", riscv_validate_misa_mxl),
>  VMSTATE_UINT32(env.misa_ext, RISCVCPU),
>  VMSTATE_UNUSED(4),
>  VMSTATE_UINT32(env.misa_ext_mask, RISCVCPU),
> --
> 2.48.1
>
>



Re: [PATCH v2 10/10] target/i386/kvm: don't stop Intel PMU counters

2025-03-05 Thread Mi, Dapeng


On 3/6/2025 3:00 AM, dongli.zh...@oracle.com wrote:
> Hi Dapeng,
>
> On 3/4/25 11:35 PM, Mi, Dapeng wrote:
>> On 3/3/2025 6:00 AM, Dongli Zhang wrote:
>>> The kvm_put_msrs() sets the MSRs using KVM_SET_MSRS. The x86 KVM processes
>>> these MSRs one by one in a loop, only saving the config and triggering the
>>> KVM_REQ_PMU request. This approach does not immediately stop the event
>>> before updating PMC.
>>>
>>> In additional, PMU MSRs are set only at levels >= KVM_PUT_RESET_STATE,
>>> excluding runtime. Therefore, updating these MSRs without stopping events
>>> should be acceptable.
>> Suppose this works for upcoming mediated vPMU as well? If so, please
>> mention it here. Thanks.
> TBH I am not sure if it works for mediated vPMU. The entire patchset is
> based the current implementation in mainline linux kernel.
>
> Otherwise, it is also required to modify the AMD's implementation ... that
> is, to stop AMD general PMCs or global registers (PerfMonV2).
>
> How about only consider the case without mediated vPMU so far?
>
> 1. For user without PerfMonV2 servers, they only need the patchset to reset
> general PMCs.
>
> 2. For user with PerfMonV2 servers, they need extra patch to reset global
> registers.
>
> 3. For mediated vPMU, we may add extra patch in the future.

I suppose it should be fine for mediated vPMU but I have no bandwidth to
thoroughly test it.

Ok, I think it's fine not to consider mediated vPMU in this patch series,
we can look at it later. Thanks.


>
> Thank you very much!
>
> Dongli Zhang
>
>>
>>> Finally, KVM creates kernel perf events with host mode excluded
>>> (exclude_host = 1). While the events remain active, they don't increment
>>> the counter during QEMU vCPU userspace mode.
>>>
>>> No Fixed tag is going to be added for the commit 0d89436786b0 ("kvm:
>>> migrate vPMU state"), because this isn't a bugfix.
>>>
>>> Signed-off-by: Dongli Zhang 
>>> ---
>>>  target/i386/kvm/kvm.c | 9 -
>>>  1 file changed, 9 deletions(-)
>>>
>>> diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
>>> index c5911baef0..4902694129 100644
>>> --- a/target/i386/kvm/kvm.c
>>> +++ b/target/i386/kvm/kvm.c
>>> @@ -4160,13 +4160,6 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
>>>  }
>>>  
>>>  if (IS_INTEL_CPU(env) && has_pmu_version > 0) {
>>> -if (has_pmu_version > 1) {
>>> -/* Stop the counter.  */
>>> -kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
>>> -kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
>>> -}
>>> -
>>> -/* Set the counter values.  */
>>>  for (i = 0; i < num_pmu_fixed_counters; i++) {
>>>  kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR0 + i,
>>>env->msr_fixed_counters[i]);
>>> @@ -4182,8 +4175,6 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
>>>env->msr_global_status);
>>>  kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
>>>env->msr_global_ovf_ctrl);
>>> -
>>> -/* Now start the PMU.  */
>>>  kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL,
>>>env->msr_fixed_ctr_ctrl);
>>>  kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL,



Re: [PATCH] docs/about/emulation: Fix broken link

2025-03-05 Thread Alistair Francis
On Wed, Mar 5, 2025 at 8:27 PM Santiago Monserrat Campanello
 wrote:
>
> semihosting link to risc-v changed
>
> Signed-off-by: Santiago Monserrat Campanello 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2717

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
> the original one linked it's still accesible on
> https://github.com/riscv-non-isa/riscv-semihosting/blob/0.2/riscv-semihosting-spec.adoc
> ---
>  docs/about/emulation.rst | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/docs/about/emulation.rst b/docs/about/emulation.rst
> index 3bc3579434..a72591ee4d 100644
> --- a/docs/about/emulation.rst
> +++ b/docs/about/emulation.rst
> @@ -171,7 +171,7 @@ for that architecture.
>  - Unified Hosting Interface (MD01069)
>* - RISC-V
>  - System and User-mode
> -- 
> https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc
> +- 
> https://github.com/riscv-non-isa/riscv-semihosting/blob/main/riscv-semihosting.adoc
>* - Xtensa
>  - System
>  - Tensilica ISS SIMCALL
> --
> 2.43.0
>
>



Re: [PATCH 06/22] target/riscv: move RISCVCPUConfig fields to a header file

2025-03-05 Thread Alistair Francis
On Fri, Feb 28, 2025 at 8:31 PM Paolo Bonzini  wrote:
>
> To support merging a subclass's RISCVCPUDef into the superclass, a list
> of all the CPU features is needed.  Put them into a header file that
> can be included multiple times, expanding the macros BOOL_FIELD and
> TYPE_FIELD to different operations.
>
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu_cfg.h| 160 +---
>  target/riscv/cpu_cfg_fields.h.inc | 167 ++
>  2 files changed, 170 insertions(+), 157 deletions(-)
>  create mode 100644 target/riscv/cpu_cfg_fields.h.inc
>
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index 7b7067d5bee..e9bf75730a6 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -22,163 +22,9 @@
>  #define RISCV_CPU_CFG_H
>
>  struct RISCVCPUConfig {
> -bool ext_zba;
> -bool ext_zbb;
> -bool ext_zbc;
> -bool ext_zbkb;
> -bool ext_zbkc;
> -bool ext_zbkx;
> -bool ext_zbs;
> -bool ext_zca;
> -bool ext_zcb;
> -bool ext_zcd;
> -bool ext_zce;
> -bool ext_zcf;
> -bool ext_zcmp;
> -bool ext_zcmt;
> -bool ext_zk;
> -bool ext_zkn;
> -bool ext_zknd;
> -bool ext_zkne;
> -bool ext_zknh;
> -bool ext_zkr;
> -bool ext_zks;
> -bool ext_zksed;
> -bool ext_zksh;
> -bool ext_zkt;
> -bool ext_zifencei;
> -bool ext_zicntr;
> -bool ext_zicsr;
> -bool ext_zicbom;
> -bool ext_zicbop;
> -bool ext_zicboz;
> -bool ext_zicfilp;
> -bool ext_zicfiss;
> -bool ext_zicond;
> -bool ext_zihintntl;
> -bool ext_zihintpause;
> -bool ext_zihpm;
> -bool ext_zimop;
> -bool ext_zcmop;
> -bool ext_ztso;
> -bool ext_smstateen;
> -bool ext_sstc;
> -bool ext_smcdeleg;
> -bool ext_ssccfg;
> -bool ext_smcntrpmf;
> -bool ext_smcsrind;
> -bool ext_sscsrind;
> -bool ext_ssdbltrp;
> -bool ext_smdbltrp;
> -bool ext_svadu;
> -bool ext_svinval;
> -bool ext_svnapot;
> -bool ext_svpbmt;
> -bool ext_svvptc;
> -bool ext_svukte;
> -bool ext_zdinx;
> -bool ext_zaamo;
> -bool ext_zacas;
> -bool ext_zama16b;
> -bool ext_zabha;
> -bool ext_zalrsc;
> -bool ext_zawrs;
> -bool ext_zfa;
> -bool ext_zfbfmin;
> -bool ext_zfh;
> -bool ext_zfhmin;
> -bool ext_zfinx;
> -bool ext_zhinx;
> -bool ext_zhinxmin;
> -bool ext_zve32f;
> -bool ext_zve32x;
> -bool ext_zve64f;
> -bool ext_zve64d;
> -bool ext_zve64x;
> -bool ext_zvbb;
> -bool ext_zvbc;
> -bool ext_zvkb;
> -bool ext_zvkg;
> -bool ext_zvkned;
> -bool ext_zvknha;
> -bool ext_zvknhb;
> -bool ext_zvksed;
> -bool ext_zvksh;
> -bool ext_zvkt;
> -bool ext_zvkn;
> -bool ext_zvknc;
> -bool ext_zvkng;
> -bool ext_zvks;
> -bool ext_zvksc;
> -bool ext_zvksg;
> -bool ext_zmmul;
> -bool ext_zvfbfmin;
> -bool ext_zvfbfwma;
> -bool ext_zvfh;
> -bool ext_zvfhmin;
> -bool ext_smaia;
> -bool ext_ssaia;
> -bool ext_sscofpmf;
> -bool ext_smepmp;
> -bool ext_smrnmi;
> -bool ext_ssnpm;
> -bool ext_smnpm;
> -bool ext_smmpm;
> -bool ext_sspm;
> -bool ext_supm;
> -bool rvv_ta_all_1s;
> -bool rvv_ma_all_1s;
> -bool rvv_vl_half_avl;
> -
> -uint32_t mvendorid;
> -uint64_t marchid;
> -uint64_t mimpid;
> -
> -/* Named features  */
> -bool ext_svade;
> -bool ext_zic64b;
> -bool ext_ssstateen;
> -bool ext_sha;
> -
> -/*
> - * Always 'true' booleans for named features
> - * TCG always implement/can't be user disabled,
> - * based on spec version.
> - */
> -bool has_priv_1_13;
> -bool has_priv_1_12;
> -bool has_priv_1_11;
> -
> -/* Vendor-specific custom extensions */
> -bool ext_xtheadba;
> -bool ext_xtheadbb;
> -bool ext_xtheadbs;
> -bool ext_xtheadcmo;
> -bool ext_xtheadcondmov;
> -bool ext_xtheadfmemidx;
> -bool ext_xtheadfmv;
> -bool ext_xtheadmac;
> -bool ext_xtheadmemidx;
> -bool ext_xtheadmempair;
> -bool ext_xtheadsync;
> -bool ext_XVentanaCondOps;
> -
> -uint32_t pmu_mask;
> -uint16_t vlenb;
> -uint16_t elen;
> -uint16_t cbom_blocksize;
> -uint16_t cbop_blocksize;
> -uint16_t cboz_blocksize;
> -bool mmu;
> -bool pmp;
> -bool debug;
> -bool misa_w;
> -
> -bool short_isa_string;
> -
> -#ifndef CONFIG_USER_ONLY
> -int8_t max_satp_mode;
> -#endif
> +#define BOOL_FIELD(x) bool x;
> +#define TYPED_FIELD(type, x) type x;
> +#include "cpu_cfg_fields.h.inc"
>  };
>
>  typedef struct RISCVCPUConfig RISCVCPUConfig;
> diff --git a/target/riscv/cpu_cfg_fields.h.inc 
> b/target/riscv/cpu_cfg_fields.h.inc
> new file mode 100644
> index 000..a42f298017f
> --- /dev/null
> +++ b/target/riscv/cpu_cfg_fields.h.inc
> @@ -0,0 +1,167 @@
> +/*
> + * Req

Re: [RFC v4 0/5] Add packed virtqueue to shadow virtqueue

2025-03-05 Thread Sahil Siddiq

Hi,

Sorry for the delay in my response. There was a lot to absorb in the
previous mail and I thought I would spend some more time exploring
this.

On 2/11/25 1:27 PM, Eugenio Perez Martin wrote:

On Mon, Feb 10, 2025 at 5:25 PM Sahil Siddiq  wrote:

On 2/10/25 7:53 PM, Eugenio Perez Martin wrote:

On Mon, Feb 10, 2025 at 11:58 AM Sahil Siddiq  wrote:

On 2/6/25 8:47 PM, Sahil Siddiq wrote:

On 2/6/25 12:42 PM, Eugenio Perez Martin wrote:

On Thu, Feb 6, 2025 at 6:26 AM Sahil Siddiq  wrote:

On 2/4/25 11:45 PM, Eugenio Perez Martin wrote:

PS: Please note that you can check packed_vq SVQ implementation
already without CVQ, as these features are totally orthogonal :).



Right. Now that I can ping with the ctrl features turned off, I think
this should take precedence. There's another issue specific to the
packed virtqueue case. It causes the kernel to crash. I have been
investigating this and the situation here looks very similar to what's
explained in Jason Wang's mail [2]. My plan of action is to apply his
changes in L2's kernel and check if that resolves the problem.

The details of the crash can be found in this mail [3].



If you're testing this series without changes, I think that is caused
by not implementing the packed version of vhost_svq_get_buf.

https://lists.nongnu.org/archive/html/qemu-devel/2024-12/msg01902.html



Oh, apologies, I think I had misunderstood your response in the linked mail.
Until now, I thought they were unrelated. In that case, I'll implement the
packed version of vhost_svq_get_buf. Hopefully that fixes it :).



I noticed one thing while testing some of the changes that I have made.
I haven't finished making the relevant changes to all the functions which
will have to handle split and packed vq differently. L2's kernel crashes
when I launch L0-QEMU with ctrl_vq=on,ctrl_rx=on.


Interesting, is a similar crash than this? (NULL ptr deference on
virtnet_set_features)?

https://issues.redhat.com/browse/RHEL-391

I am not able to access this bug report (even with a Red Hat account). It
says it may have been deleted or I don't have the permission to view it.

It's hard to tell if this is the same issue. I don't think it is the same
issue though since I don't see any such indication in the logs. The kernel
throws the following:

[   23.047503] virtio_net virtio1: output.0:id 0 is not a head!


This is a common error when modifying code of the dataplane, it is
unlikely to do deep changes and not see this error :). It indicates
that your code is marking the descriptor id 0 as used when the guest
didn't make it available.


Right, I explored this a little further. I noticed that there were
a few issues in my implementation with the way packed vqs were being
handled (apart from the lack of implementation of
vhost_svq_get_buf_packed). After making the relevant changes and
implementing vhost_svq_get_buf_packed, I couldn't see this issue
anymore.


If this is happening in control virtqueue, I'd check if the code is
setting the flags as used in ring[1] when it shouldn't. But my bet is
that the rx queue is the wrong one.


The flags were one of the issues. I hadn't initialized "avail_used_flags"
correctly. Rectifying them seems to have solved this issue. However, I see
two new issues (described further below).


[   49.173243] watchdog: BUG: soft lockup - CPU#1 stuck for 25s! 
[NetworkManager:782]
[   49.174167] Modules linked in: rfkill intel_rapl_msr intel_rapl_common 
intel_uncore_frequency_common intel_pmc_core intel_vsec pmt_telemetry pmt_class 
kvg
[   49.188258] CPU: 1 PID: 782 Comm: NetworkManager Not tainted 
6.8.7-200.fc39.x86_64 #1
[   49.193196] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 
rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
[   49.193196] RIP: 0010:virtqueue_get_buf+0x0/0x20



Two possibilities about this part:
a) You're spending "too long" in the debugger in QEMU. From the kernel
POV, the function virtqueue_get_buf is taking too long to complete so
it detects it as a lockup. You can check this scenario by not running
QEMU under GDB or disabling all breakpoints. You can ignore this
message if you don't find the error this way. If you still see the
message, goto possibility b.

b) The kernel has a bug that makes it softlockup in virtqueue_get_buf.
The kernel should not soft lockup even if your changes were malicious
:(, so it is something to be fixed. If you have the time, can you test
with the latest upstream kernel?


I wasn't running QEMU under GDB, so there may indeed be an issue in the
kernel. While I don't see a soft lockup at this exact point after making
the above described changes, I do see a soft lockup issue in another part
of virtio-net.

When testing my implementation with the control feature bits turned on,
the kernel throws the following warning while booting.

[9.046478] net eth0: Failed to disable allmulti mode.

This is printed as a dev_warn() in 
drivers/net/virtio_net.c:virtnet_rx_mode_work [1].
The kernel doesn't cont

Re: [PATCH 1/2] target/riscv: fix access permission checks for CSR_SSP

2025-03-05 Thread Deepak Gupta

On Thu, Mar 06, 2025 at 03:20:55PM +1000, Alistair Francis wrote:

On Tue, Feb 18, 2025 at 12:56 PM Deepak Gupta  wrote:


Commit:8205bc1 ("target/riscv: introduce ssp and enabling controls for
zicfiss") introduced CSR_SSP but it mis-interpreted the spec on access
to CSR_SSP in M-mode. Gated to CSR_SSP is not gated via `xSSE`. But
rather rules clearly specified in section "2.2.4. Shadow Stack Pointer"


Do you mean "22.2.1. Shadow Stack Pointer (ssp) CSR access contr" in
the priv spec?


No I meant 2.2.4 of zicfiss specification. Section 22.2.1 of priv spec
says same.




of `zicfiss` specification. Thanks to Adam Zabrocki for bringing this
to attention.


The thanks should probably be below the line


Sure





Fixes: 8205bc127a83 ("target/riscv: introduce ssp and enabling controls
for zicfiss"

Reported-by: Adam Zabrocki 
Signed-off-by: Deepak Gupta 


The actual change looks good:

Reviewed-by: Alistair Francis 

Alistair


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

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index afb7544f07..75c661d2a1 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -191,6 +191,11 @@ static RISCVException cfi_ss(CPURISCVState *env, int csrno)
 return RISCV_EXCP_ILLEGAL_INST;
 }

+/* If ext implemented, M-mode always have access to SSP CSR */
+if (env->priv == PRV_M) {
+return RISCV_EXCP_NONE;
+}
+
 /* if bcfi not active for current env, access to csr is illegal */
 if (!cpu_get_bcfien(env)) {
 #if !defined(CONFIG_USER_ONLY)
--
2.34.1






[PATCH v6 1/4] qapi: Do not consume a value if failed

2025-03-05 Thread Akihiko Odaki
Do not consume a value if interpreting one failed so that we can
reinterpret the value with a different type.

Signed-off-by: Akihiko Odaki 
---
 qapi/qobject-input-visitor.c | 103 +--
 1 file changed, 69 insertions(+), 34 deletions(-)

diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
index 
c52d36997df8d99bc575c553a413df8ebcb60c32..0cc75b3c74e40a24cb1ce764330ae2703e80d7cf
 100644
--- a/qapi/qobject-input-visitor.c
+++ b/qapi/qobject-input-visitor.c
@@ -116,9 +116,8 @@ static const char *full_name(QObjectInputVisitor *qiv, 
const char *name)
 return full_name_nth(qiv, name, 0);
 }
 
-static QObject *qobject_input_try_get_object(QObjectInputVisitor *qiv,
- const char *name,
- bool consume)
+static QObject *qobject_input_try_get_object(const QObjectInputVisitor *qiv,
+ const char *name)
 {
 StackObject *tos;
 QObject *qobj;
@@ -138,34 +137,19 @@ static QObject 
*qobject_input_try_get_object(QObjectInputVisitor *qiv,
 if (qobject_type(qobj) == QTYPE_QDICT) {
 assert(name);
 ret = qdict_get(qobject_to(QDict, qobj), name);
-if (tos->h && consume && ret) {
-bool removed = g_hash_table_remove(tos->h, name);
-assert(removed);
-}
 } else {
 assert(qobject_type(qobj) == QTYPE_QLIST);
 assert(!name);
-if (tos->entry) {
-ret = qlist_entry_obj(tos->entry);
-if (consume) {
-tos->entry = qlist_next(tos->entry);
-}
-} else {
-ret = NULL;
-}
-if (consume) {
-tos->index++;
-}
+ret = tos->entry ? qlist_entry_obj(tos->entry) : NULL;
 }
 
 return ret;
 }
 
 static QObject *qobject_input_get_object(QObjectInputVisitor *qiv,
- const char *name,
- bool consume, Error **errp)
+ const char *name, Error **errp)
 {
-QObject *obj = qobject_input_try_get_object(qiv, name, consume);
+QObject *obj = qobject_input_try_get_object(qiv, name);
 
 if (!obj) {
 error_setg(errp, QERR_MISSING_PARAMETER, full_name(qiv, name));
@@ -173,6 +157,38 @@ static QObject 
*qobject_input_get_object(QObjectInputVisitor *qiv,
 return obj;
 }
 
+static void qobject_input_consume_object(QObjectInputVisitor *qiv,
+ const char *name)
+{
+StackObject *tos;
+QObject *qobj;
+
+if (QSLIST_EMPTY(&qiv->stack)) {
+/* Starting at root, name is ignored. */
+return;
+}
+
+/* We are in a container; find the next element. */
+tos = QSLIST_FIRST(&qiv->stack);
+qobj = tos->obj;
+assert(qobj);
+
+if (qobject_type(qobj) == QTYPE_QDICT) {
+assert(name);
+if (tos->h) {
+bool removed = g_hash_table_remove(tos->h, name);
+assert(removed);
+}
+} else {
+assert(qobject_type(qobj) == QTYPE_QLIST);
+assert(!name);
+if (tos->entry) {
+tos->entry = qlist_next(tos->entry);
+}
+tos->index++;
+}
+}
+
 static const char *qobject_input_get_keyval(QObjectInputVisitor *qiv,
 const char *name,
 Error **errp)
@@ -180,7 +196,7 @@ static const char 
*qobject_input_get_keyval(QObjectInputVisitor *qiv,
 QObject *qobj;
 QString *qstr;
 
-qobj = qobject_input_get_object(qiv, name, true, errp);
+qobj = qobject_input_get_object(qiv, name, errp);
 if (!qobj) {
 return NULL;
 }
@@ -233,6 +249,7 @@ static const QListEntry 
*qobject_input_push(QObjectInputVisitor *qiv,
 tos->index = -1;
 }
 
+qobject_input_consume_object(qiv, name);
 QSLIST_INSERT_HEAD(&qiv->stack, tos, node);
 return tos->entry;
 }
@@ -279,7 +296,7 @@ static bool qobject_input_start_struct(Visitor *v, const 
char *name, void **obj,
size_t size, Error **errp)
 {
 QObjectInputVisitor *qiv = to_qiv(v);
-QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
+QObject *qobj = qobject_input_get_object(qiv, name, errp);
 
 if (obj) {
 *obj = NULL;
@@ -316,7 +333,7 @@ static bool qobject_input_start_list(Visitor *v, const char 
*name,
  Error **errp)
 {
 QObjectInputVisitor *qiv = to_qiv(v);
-QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
+QObject *qobj = qobject_input_get_object(qiv, name, errp);
 const QListEntry *entry;
 
 if (list) {
@@ -382,7 +399,7 @@ static bool qobject_input_start_alternate(Visitor *v, const 
char *name,
   Error **errp)
 {
 QObjectInputVisitor 

[PATCH v6 0/4] virtio: Convert feature properties to OnOffAuto

2025-03-05 Thread Akihiko Odaki
This series was spun off from:
"[PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto"
(https://patchew.org/QEMU/20240714-auto-v3-0-e27401aab...@daynix.com/)

Some features are not always available with vhost. Legacy features are
not available with vp_vdpa in particular. virtio devices used to disable
them when not available even if the corresponding properties were
explicitly set to "on".

QEMU already has OnOffAuto type, which includes the "auto" value to let
it automatically decide the effective value. Convert feature properties
to OnOffAuto and set them "auto" by default to utilize it. This allows
QEMU to report an error if they are set "on" and the corresponding
features are not available.

Signed-off-by: Akihiko Odaki 
---
Changes in v6:
- Rebased.
- Link to v5: 
https://lore.kernel.org/qemu-devel/20250208-virtio-v5-0-4376cb218...@daynix.com

Changes in v5:
- Covered QAPI more than just qdev.
- Expanded the description of patch
  "qapi: Accept bool for OnOffAuto and OnOffSplit".
- Rebased.
- Link to v4: 
https://lore.kernel.org/r/20250108-virtio-v4-0-cbf0aa04c...@daynix.com

Changes in v4:
- Added patch "qapi: Do not consume a value if failed".
- Link to v3: 
https://lore.kernel.org/r/20250104-virtio-v3-0-63ef70e9d...@daynix.com

Changes in v3:
- Rebased.
- Link to v2: 
https://lore.kernel.org/r/20241022-virtio-v2-0-b2394236e...@daynix.com

Changes in v2:
- Expanded the message of patch "qdev-properties: Accept bool for
  OnOffAuto".
- Link to v1: 
https://lore.kernel.org/r/20241014-virtio-v1-0-e9ddf7a81...@daynix.com

---
Akihiko Odaki (4):
  qapi: Do not consume a value if failed
  qapi: Accept bool for OnOffAuto and OnOffSplit
  qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64()
  virtio: Convert feature properties to OnOffAuto

 include/hw/qdev-properties.h |  18 
 include/hw/virtio/virtio.h   |  38 +---
 hw/core/machine.c|   1 +
 hw/core/qdev-properties.c|  83 +-
 hw/virtio/virtio-bus.c   |  14 +-
 hw/virtio/virtio.c   |   4 +-
 qapi/qobject-input-visitor.c | 103 +--
 scripts/qapi/visit.py|  24 ++
 8 files changed, 229 insertions(+), 56 deletions(-)
---
base-commit: b69801dd6b1eb4d107f7c2f643adf0a4e3ec9124
change-id: 20241013-virtio-164ea3f295c3

Best regards,
-- 
Akihiko Odaki 




[PATCH v6 2/4] qapi: Accept bool for OnOffAuto and OnOffSplit

2025-03-05 Thread Akihiko Odaki
bool has representations of "on" and "off" different from
OnOffAuto/OnOffSplit:
- The command line syntax accepts on/yes/true/y and off/no/false/n for
  bool but only on and off for OnOffAuto.
- JSON uses true/false for bool but "on" and "off" for
  OnOffAuto/OnOffSplit.

This inconsistency causes some problems:
- Users need to take the underlying type into consideration to determine
  what literal to specify, increasing cognitive loads for human users
  and complexity for programs invoking QEMU.
- Converting an existing bool property to OnOffAuto/OnOffSplit will
  break compatibility.

Fix these problems by accepting bool literals for OnOffAuto/OnOffSplit.
This change is specific to OnOffAuto/OnOffSplit; types added in the
future may be defined as an alternate of bool and enum to avoid the
mentioned problems in the first place.

Signed-off-by: Akihiko Odaki 
---
 hw/core/qdev-properties.c | 17 -
 scripts/qapi/visit.py | 24 
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 
0b52aad55516099917a4e9b71a920bc3da8a92ec..3462921841db74456284b91374955b6101f03bbc
 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -2,6 +2,7 @@
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
 #include "qapi/qapi-types-misc.h"
+#include "qapi/qapi-visit-common.h"
 #include "qobject/qlist.h"
 #include "qemu/ctype.h"
 #include "qemu/error-report.h"
@@ -493,12 +494,26 @@ const PropertyInfo qdev_prop_string = {
 
 /* --- on/off/auto --- */
 
+static void set_on_off_auto(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+Property *prop = opaque;
+int *ptr = object_field_prop_ptr(obj, prop);
+OnOffAuto value;
+
+if (!visit_type_OnOffAuto(v, name, &value, errp)) {
+return;
+}
+
+*ptr = value;
+}
+
 const PropertyInfo qdev_prop_on_off_auto = {
 .name = "OnOffAuto",
 .description = "on/off/auto",
 .enum_table = &OnOffAuto_lookup,
 .get = qdev_propinfo_get_enum,
-.set = qdev_propinfo_set_enum,
+.set = set_on_off_auto,
 .set_default_value = qdev_propinfo_set_default_value_enum,
 };
 
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index 
36e240967b687db10115ba375da3371898b7d95c..5844b64ad6b49a7b88e286dd35ab28b2755282d0
 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -205,6 +205,29 @@ def gen_visit_list(name: str, element_type: 
QAPISchemaType) -> str:
 
 
 def gen_visit_enum(name: str) -> str:
+if name in ('OnOffAuto', 'OnOffSplit'):
+return mcgen('''
+
+bool visit_type_%(c_name)s(Visitor *v, const char *name,
+ %(c_name)s *obj, Error **errp)
+{
+bool b;
+int i;
+
+if (v->type == VISITOR_INPUT && visit_type_bool(v, name, &b, NULL)) {
+*obj = b ? %(on)s : %(off)s;
+return true;
+}
+
+b = visit_type_enum(v, name, &i, &%(c_name)s_lookup, errp);
+*obj = i;
+
+return b;
+}
+''',
+ c_name=c_name(name),
+ on=c_enum_const(name, 'on'), off=c_enum_const(name, 
'off'))
+
 return mcgen('''
 
 bool visit_type_%(c_name)s(Visitor *v, const char *name,
@@ -355,6 +378,7 @@ def _begin_user_module(self, name: str) -> None:
 self._genc.preamble_add(mcgen('''
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/visitor-impl.h"
 #include "%(visit)s.h"
 #include "%(prefix)sqapi-features.h"
 ''',

-- 
2.48.1




Re: [PATCH 2/2] target/riscv: fixes a bug against `ssamoswap` behavior in M-mode

2025-03-05 Thread Deepak Gupta

On Thu, Mar 06, 2025 at 03:29:00PM +1000, Alistair Francis wrote:

On Tue, Feb 18, 2025 at 12:57 PM Deepak Gupta  wrote:


Commit f06bfe3dc38c ("target/riscv: implement zicfiss instructions") adds
`ssamoswap` instruction. `ssamoswap` takes the code-point from existing
reserved encoding (and not a zimop like other shadow stack instructions).
If shadow stack is not enabled (via xenvcfg.SSE), then `ssamoswap` must
result in an illegal instruction exception. However there is a slightly
modified behavior for M-mode.

Shadow stack are not available in M-mode and all shadow stack instructions
in M-mode exhibit zimop behavior. However, `ssamoswap` can still succeed
if MPRV=1 and MPP is non-zero (see section 2.7 of zicfiss specification).
This patch corrects that behavior for `ssamoswap`.


Section "22.2.3. Shadow Stack Memory Protection " of the latest priv
spec [1] seems to say: "When the effective privilege mode is M, any
memory access by an SSAMOSWAP.W/D
instruction will result in a store/AMO access-fault exception."


Hmm I didn't look at priv spec. Let me fix this one.



1: 
https://github.com/riscv/riscv-isa-manual/releases/tag/riscv-isa-release-9cfaf37-2025-03-06

Alistair



Fixes: f06bfe3dc38c ("target/riscv: implement zicfiss instructions")

Reported-by: Ved Shanbhogue 
Signed-off-by: Deepak Gupta 
---
 target/riscv/insn_trans/trans_rvzicfiss.c.inc | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvzicfiss.c.inc 
b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
index e3ebc4977c..ec016cd70f 100644
--- a/target/riscv/insn_trans/trans_rvzicfiss.c.inc
+++ b/target/riscv/insn_trans/trans_rvzicfiss.c.inc
@@ -15,6 +15,13 @@
  * You should have received a copy of the GNU General Public License along with
  * this program.  If not, see .
  */
+
+ #define REQUIRE_ZICFISS(ctx) do {   \
+if (!ctx->cfg_ptr->ext_zicfiss) {\
+return false;\
+}\
+} while (0)
+
 static bool trans_sspopchk(DisasContext *ctx, arg_sspopchk *a)
 {
 if (!ctx->bcfi_enabled) {
@@ -77,7 +84,8 @@ static bool trans_ssrdp(DisasContext *ctx, arg_ssrdp *a)
 static bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a)
 {
 REQUIRE_A_OR_ZAAMO(ctx);
-if (!ctx->bcfi_enabled) {
+REQUIRE_ZICFISS(ctx);
+if ((ctx->priv != PRV_M) && !ctx->bcfi_enabled) {
 return false;
 }

@@ -97,7 +105,8 @@ static bool trans_ssamoswap_d(DisasContext *ctx, 
arg_amoswap_w *a)
 {
 REQUIRE_64BIT(ctx);
 REQUIRE_A_OR_ZAAMO(ctx);
-if (!ctx->bcfi_enabled) {
+REQUIRE_ZICFISS(ctx);
+if ((ctx->priv != PRV_M) && !ctx->bcfi_enabled) {
 return false;
 }

--
2.34.1






[PATCH v6 4/4] virtio: Convert feature properties to OnOffAuto

2025-03-05 Thread Akihiko Odaki
Some features are not always available with vhost. Legacy features are
not available with vp_vdpa in particular. virtio devices used to disable
them when not available even if the corresponding properties were
explicitly set to "on".

QEMU already has OnOffAuto type, which includes the "auto" value to let
it automatically decide the effective value. Convert feature properties
to OnOffAuto and set them "auto" by default to utilize it. This allows
QEMU to report an error if they are set "on" and the corresponding
features are not available.

Signed-off-by: Akihiko Odaki 
---
 include/hw/virtio/virtio.h | 38 +-
 hw/core/machine.c  |  1 +
 hw/virtio/virtio-bus.c | 14 --
 hw/virtio/virtio.c |  4 +++-
 4 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 
638691028050d2599592d8c7e95c75ac3913fbdd..b854c2cb1d04da0a35165289c28f87e8cb869df6
 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -113,7 +113,8 @@ struct VirtIODevice
 uint16_t queue_sel;
 /**
  * These fields represent a set of VirtIO features at various
- * levels of the stack. @host_features indicates the complete
+ * levels of the stack. @requested_features indicates the feature
+ * set the user requested. @host_features indicates the complete
  * feature set the VirtIO device can offer to the driver.
  * @guest_features indicates which features the VirtIO driver has
  * selected by writing to the feature register. Finally
@@ -121,6 +122,7 @@ struct VirtIODevice
  * backend (e.g. vhost) and could potentially be a subset of the
  * total feature set offered by QEMU.
  */
+OnOffAutoBit64 requested_features;
 uint64_t host_features;
 uint64_t guest_features;
 uint64_t backend_features;
@@ -149,6 +151,7 @@ struct VirtIODevice
 bool started;
 bool start_on_kick; /* when virtio 1.0 feature has not been negotiated */
 bool disable_legacy_check;
+bool force_features_auto;
 bool vhost_started;
 VMChangeStateEntry *vmstate;
 char *bus_name;
@@ -376,22 +379,23 @@ typedef struct VirtIOSCSIConf VirtIOSCSIConf;
 typedef struct VirtIORNGConf VirtIORNGConf;
 
 #define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
-DEFINE_PROP_BIT64("indirect_desc", _state, _field,\
-  VIRTIO_RING_F_INDIRECT_DESC, true), \
-DEFINE_PROP_BIT64("event_idx", _state, _field,\
-  VIRTIO_RING_F_EVENT_IDX, true), \
-DEFINE_PROP_BIT64("notify_on_empty", _state, _field,  \
-  VIRTIO_F_NOTIFY_ON_EMPTY, true), \
-DEFINE_PROP_BIT64("any_layout", _state, _field, \
-  VIRTIO_F_ANY_LAYOUT, true), \
-DEFINE_PROP_BIT64("iommu_platform", _state, _field, \
-  VIRTIO_F_IOMMU_PLATFORM, false), \
-DEFINE_PROP_BIT64("packed", _state, _field, \
-  VIRTIO_F_RING_PACKED, false), \
-DEFINE_PROP_BIT64("queue_reset", _state, _field, \
-  VIRTIO_F_RING_RESET, true), \
-DEFINE_PROP_BIT64("in_order", _state, _field, \
-  VIRTIO_F_IN_ORDER, false)
+DEFINE_PROP_ON_OFF_AUTO_BIT64("indirect_desc", _state, _field, \
+  VIRTIO_RING_F_INDIRECT_DESC, \
+  ON_OFF_AUTO_AUTO), \
+DEFINE_PROP_ON_OFF_AUTO_BIT64("event_idx", _state, _field, \
+  VIRTIO_RING_F_EVENT_IDX, ON_OFF_AUTO_AUTO), \
+DEFINE_PROP_ON_OFF_AUTO_BIT64("notify_on_empty", _state, _field, \
+  VIRTIO_F_NOTIFY_ON_EMPTY, ON_OFF_AUTO_AUTO), 
\
+DEFINE_PROP_ON_OFF_AUTO_BIT64("any_layout", _state, _field, \
+  VIRTIO_F_ANY_LAYOUT, ON_OFF_AUTO_AUTO), \
+DEFINE_PROP_ON_OFF_AUTO_BIT64("iommu_platform", _state, _field, \
+  VIRTIO_F_IOMMU_PLATFORM, ON_OFF_AUTO_OFF), \
+DEFINE_PROP_ON_OFF_AUTO_BIT64("packed", _state, _field, \
+  VIRTIO_F_RING_PACKED, ON_OFF_AUTO_OFF), \
+DEFINE_PROP_ON_OFF_AUTO_BIT64("queue_reset", _state, _field, \
+  VIRTIO_F_RING_RESET, ON_OFF_AUTO_AUTO), \
+DEFINE_PROP_ON_OFF_AUTO_BIT64("in_order", _state, _field, \
+  VIRTIO_F_IN_ORDER, ON_OFF_AUTO_OFF)
 
 hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
 bool virtio_queue_enabled_legacy(VirtIODevice *vdev, int n);
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 
02cff735b3fb8cf0ce8a85ec7f1fb36a98005a24..b25b366bdc715acd5c90af7ac38cfb3ac88f4c5b
 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -43,6 +43,7 @@ GlobalProperty hw_compat_9_2[] = {
 { "virtio-balloon-pci-non-transitional", "vectors", "0" },
 { "virtio-mem-pci", "vectors", "0" },
 { "migration", "multifd-clean-tls-termination"

[PATCH v7 6/6] Update the ACPI tables according to the acpi aml_build change, also empty bios-tables-test-allowed-diff.h.

2025-03-05 Thread Alireza Sanaee via
The disassembled differences between actual and expected PPTT based on
the following cache topology representation:

- l1d and l1i shared at cluster level
- l2 shared at cluster level
- l3 shared at cluster level

/*
 * Intel ACPI Component Architecture
 * AML/ASL+ Disassembler version 20200925 (64-bit version)
 * Copyright (c) 2000 - 2020 Intel Corporation
 *
 * Disassembly of ../../../tests/data/acpi/aarch64/virt/PPTT.topology, Mon Oct  
7 16:57:29 2024
 *
 * ACPI Data Table [PPTT]
 *
 * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
 */

[000h    4]Signature : "PPTT"[Processor Properties 
Topology Table]
[004h 0004   4] Table Length : 021C
[008h 0008   1] Revision : 03
[009h 0009   1] Checksum : 4D
[00Ah 0010   6]   Oem ID : "BOCHS "
[010h 0016   8] Oem Table ID : "BXPC"
[018h 0024   4] Oem Revision : 0001
[01Ch 0028   4]  Asl Compiler ID : "BXPC"
[020h 0032   4]Asl Compiler Revision : 0001

[024h 0036   1]Subtable Type : 00 [Processor Hierarchy Node]
[025h 0037   1]   Length : 14
[026h 0038   2] Reserved : 
[028h 0040   4]Flags (decoded below) : 0011
Physical package : 1
 ACPI Processor ID valid : 0
   Processor is a thread : 0
  Node is a leaf : 0
Identical Implementation : 1
[02Ch 0044   4]   Parent : 
[030h 0048   4]ACPI Processor ID : 
[034h 0052   4]  Private Resource Number : 

[038h 0056   1]Subtable Type : 00 [Processor Hierarchy Node]
[039h 0057   1]   Length : 14
[03Ah 0058   2] Reserved : 
[03Ch 0060   4]Flags (decoded below) : 0011
Physical package : 1
 ACPI Processor ID valid : 0
   Processor is a thread : 0
  Node is a leaf : 0
Identical Implementation : 1
[040h 0064   4]   Parent : 0024
[044h 0068   4]ACPI Processor ID : 
[048h 0072   4]  Private Resource Number : 

[04Ch 0076   1]Subtable Type : 01 [Cache Type]
[04Dh 0077   1]   Length : 1C
[04Eh 0078   2] Reserved : 
[050h 0080   4]Flags (decoded below) : 00FF
  Size valid : 1
Number of Sets valid : 1
 Associativity valid : 1
   Allocation Type valid : 1
Cache Type valid : 1
  Write Policy valid : 1
 Line Size valid : 1
[054h 0084   4]  Next Level of Cache : 
[058h 0088   4] Size : 0020
[05Ch 0092   4]   Number of Sets : 0800
[060h 0096   1]Associativity : 10
[061h 0097   1]   Attributes : 0F
 Allocation Type : 3
  Cache Type : 3
Write Policy : 0
[062h 0098   2]Line Size : 0040

[068h 0104   1]Subtable Type : 01 [Cache Type]
[069h 0105   1]   Length : 1C
[06Ah 0106   2] Reserved : 
[06Ch 0108   4]Flags (decoded below) : 00FF
  Size valid : 1
Number of Sets valid : 1
 Associativity valid : 1
   Allocation Type valid : 1
Cache Type valid : 1
  Write Policy valid : 1
 Line Size valid : 1
[070h 0112   4]  Next Level of Cache : 004C
[074h 0116   4] Size : 8000
[078h 0120   4]   Number of Sets : 0080
[07Ch 0124   1]Associativity : 04
[07Dh 0125   1]   Attributes : 03
 Allocation Type : 3
  Cache Type : 0
Write Policy : 0
[07Eh 0126   2]Line Size : 0040

[084h 0132   1]Subtable Type : 01 [Cache Type]
[085h 0133   1]   Length : 1C
[086h 0134   2] Reserved : 
[088h 0136   4]Flags (decoded below) : 00FF
  Size valid : 1
Number of Sets valid : 1
 Associativity valid : 1
   Allocation Type valid : 1
Cache Type valid : 1
  Write Policy valid : 1

Re: [PATCH v3 0/2] target/riscv: throw debug exception before page fault

2025-03-05 Thread Michael Tokarev

21.01.2025 20:06, Daniel Henrique Barboza wrote:

Hi,

In this new version, in patch 2,  we're using the address 'size' val from
riscv_cpu_tlb_fill() instead of infering it from the CPU XLEN.

No other changes made. Patches based on master.

Changes from v2:
- patch 2:
   - use 'size' instead of infering wp_len using the CPU XLEN
- v2 link: 
https://lore.kernel.org/qemu-riscv/20250120204910.1317013-1-dbarb...@ventanamicro.com/

Daniel Henrique Barboza (2):
   target/riscv/debug.c: use wp size = 4 for 32-bit CPUs
   target/riscv: throw debug exception before page fault


Hi!

Is this a qemu-stable material?

If yes, is it worth to pick it up for older stable series
(currently active series are 7.2 and 8.2)?

Please keep Cc: qemu-stable@ for fixes which should be picked up
for the stable series.

Thanks,

/mjt



Re: [PATCH] goldfish_rtc: Fix tick_offset migration

2025-03-05 Thread Michael Tokarev

15.01.2025 00:21, Rodrigo Dias Correa wrote:

Instead of migrating the raw tick_offset, goldfish_rtc migrates a
recalculated value based on QEMU_CLOCK_VIRTUAL. As QEMU_CLOCK_VIRTUAL
stands still across a save-and-restore cycle, the guest RTC becomes out
of sync with the host RTC when the VM is restored.

As described in the bug description, it looks like this calculation was
copied from pl031 RTC, which had its tick_offset migration fixed by
Commit 032cfe6a79c8 ("pl031: Correctly migrate state when using -rtc
clock=host").

Migrate the tick_offset directly, adding it as a version-dependent field
to VMState. Keep the old behavior when migrating from previous versions.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2033


Is this a qemu-stable material?

If yes, how far to older stable series it is worth to pick?
(Currently active older stable series are 7.2 and 8.2).

Please add Cc: qemu-stable@ for fixes which are supposed to be picked up
for the stable series.

Thanks,

/mjt



Re: [PATCH 4/7] target/riscv: cpu: store max SATP mode as a single integer

2025-03-05 Thread Alistair Francis
On Wed, Feb 19, 2025 at 3:00 AM Paolo Bonzini  wrote:
>
> The maximum available SATP mode implies all the shorter virtual address sizes.
> Store it in RISCVCPUConfig and avoid recomputing it via 
> satp_mode_max_from_map.
>
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu_cfg.h |  1 +
>  target/riscv/cpu.c | 11 +--
>  target/riscv/tcg/tcg-cpu.c |  3 ++-
>  3 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index b410b1e6038..28d8de978fa 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -192,6 +192,7 @@ struct RISCVCPUConfig {
>  bool short_isa_string;
>
>  #ifndef CONFIG_USER_ONLY
> +int8_t max_satp_mode;
>  RISCVSATPMap satp_mode;
>  #endif
>  };
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7950b6447f8..2d06543217a 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -444,6 +444,7 @@ static void set_satp_mode_max_supported(RISCVCPU *cpu,
>  }
>
>  assert(cpu->cfg.satp_mode.supported & (1 << satp_mode));
> +cpu->cfg.max_satp_mode = satp_mode;
>  }
>
>  /* Set the satp mode to the max supported */
> @@ -1177,16 +1178,13 @@ static void riscv_cpu_disas_set_info(CPUState *s, 
> disassemble_info *info)
>  static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
>  {
>  bool rv32 = riscv_cpu_is_32bit(cpu);
> -uint8_t satp_mode_map_max, satp_mode_supported_max;
> +uint8_t satp_mode_map_max;
>
>  /* The CPU wants the OS to decide which satp mode to use */
>  if (cpu->cfg.satp_mode.supported == 0) {
>  return;
>  }
>
> -satp_mode_supported_max =
> -satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
> -
>  if (cpu->cfg.satp_mode.map == 0) {
>  if (cpu->cfg.satp_mode.init == 0) {
>  /* If unset by the user, we fallback to the default satp mode. */
> @@ -1215,10 +1213,10 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU 
> *cpu, Error **errp)
>  satp_mode_map_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
>
>  /* Make sure the user asked for a supported configuration (HW and qemu) 
> */
> -if (satp_mode_map_max > satp_mode_supported_max) {
> +if (satp_mode_map_max > cpu->cfg.max_satp_mode) {
>  error_setg(errp, "satp_mode %s is higher than hw max capability %s",
> satp_mode_str(satp_mode_map_max, rv32),
> -   satp_mode_str(satp_mode_supported_max, rv32));
> +   satp_mode_str(cpu->cfg.max_satp_mode, rv32));
>  return;
>  }
>
> @@ -1477,6 +1475,7 @@ static void riscv_cpu_init(Object *obj)
>  cpu->cfg.cbom_blocksize = 64;
>  cpu->cfg.cbop_blocksize = 64;
>  cpu->cfg.cboz_blocksize = 64;
> +cpu->cfg.max_satp_mode = -1;
>  cpu->env.vext_ver = VEXT_VERSION_1_00_0;
>  }
>
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 0a137281de1..a9f59a67e00 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -693,8 +693,9 @@ static bool riscv_cpu_validate_profile_satp(RISCVCPU *cpu,
>  RISCVCPUProfile *profile,
>  bool send_warn)
>  {
> -int satp_max = satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
> +int satp_max = cpu->cfg.max_satp_mode;
>
> +assert(satp_max >= 0);
>  if (profile->satp_mode > satp_max) {
>  if (send_warn) {
>  bool is_32bit = riscv_cpu_is_32bit(cpu);
> --
> 2.48.1
>
>



Re: [PATCH 1/1] [RISC-V/RVV] Expand the probe_pages helper function to handle probe flags.

2025-03-05 Thread Alistair Francis
On Sat, Feb 22, 2025 at 2:21 AM Paolo Savini  wrote:
>
> This commit expands the probe_pages helper function in
> target/riscv/vector_helper.c to handle also the cases in which we need access 
> to
> the flags raised while probing the memory and the host address.
> This is done in order to provide a unified interface to probe_access and
> probe_access_flags.
> The new version of probe_pages can now act as a regular call to probe_access 
> as
> before and as a call to probe_access_flags. In the latter case the user need 
> to
> pass pointers to flags and host address and a boolean value for nonfault.
> The flags and host address will be set and made available as for a direct call
> to probe_access_flags.
>
> Signed-off-by: Paolo Savini 

Do you mind rebasing this on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next ?

Alistair

> ---
>  target/riscv/vector_helper.c | 57 +++-
>  1 file changed, 37 insertions(+), 20 deletions(-)
>
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 772cff8fbe..c0f1b7994e 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -114,25 +114,42 @@ static inline uint32_t vext_max_elems(uint32_t desc, 
> uint32_t log2_esz)
>   * It will trigger an exception if there is no mapping in TLB
>   * and page table walk can't fill the TLB entry. Then the guest
>   * software can return here after process the exception or never return.
> + *
> + * This function can also be used when direct access to probe_access_flags is
> + * needed in order to access the flags. If a pointer to a flags operand is
> + * provided the function will call probe_access_flags instead, use nonfault
> + * and update host and flags.
>   */
> -static void probe_pages(CPURISCVState *env, target_ulong addr,
> -target_ulong len, uintptr_t ra,
> -MMUAccessType access_type)
> +static void probe_pages(CPURISCVState *env, target_ulong addr, target_ulong 
> len,
> +uintptr_t ra, MMUAccessType access_type, int 
> mmu_index,
> +void **host, int *flags, bool nonfault)
>  {
>  target_ulong pagelen = -(addr | TARGET_PAGE_MASK);
>  target_ulong curlen = MIN(pagelen, len);
> -int mmu_index = riscv_env_mmu_index(env, false);
>
> -probe_access(env, adjust_addr(env, addr), curlen, access_type,
> - mmu_index, ra);
> +if (flags != NULL) {
> +*flags = probe_access_flags(env, adjust_addr(env, addr), curlen,
> +access_type, mmu_index, nonfault, host, 
> ra);
> +} else {
> +probe_access(env, adjust_addr(env, addr), curlen, access_type,
> + mmu_index, ra);
> +}
> +
>  if (len > curlen) {
>  addr += curlen;
>  curlen = len - curlen;
> -probe_access(env, adjust_addr(env, addr), curlen, access_type,
> - mmu_index, ra);
> +if (flags != NULL) {
> +*flags = probe_access_flags(env, adjust_addr(env, addr), curlen,
> +access_type, mmu_index, nonfault,
> +host, ra);
> +} else {
> +probe_access(env, adjust_addr(env, addr), curlen, access_type,
> + mmu_index, ra);
> +}
>  }
>  }
>
> +
>  static inline void vext_set_elem_mask(void *v0, int index,
>uint8_t value)
>  {
> @@ -332,8 +349,8 @@ vext_page_ldst_us(CPURISCVState *env, void *vd, 
> target_ulong addr,
>  MMUAccessType access_type = is_load ? MMU_DATA_LOAD : MMU_DATA_STORE;
>
>  /* Check page permission/pmp/watchpoint/etc. */
> -flags = probe_access_flags(env, adjust_addr(env, addr), size, 
> access_type,
> -   mmu_index, true, &host, ra);
> +probe_pages(env, addr, size, ra, access_type, mmu_index, &host, &flags,
> +true);
>
>  if (flags == 0) {
>  if (nf == 1) {
> @@ -635,7 +652,7 @@ vext_ldff(void *vd, void *v0, target_ulong base, 
> CPURISCVState *env,
>  uint32_t vma = vext_vma(desc);
>  target_ulong addr, addr_probe, addr_i, offset, remain, page_split, elems;
>  int mmu_index = riscv_env_mmu_index(env, false);
> -int flags;
> +int flags, probe_flags;
>  void *host;
>
>  VSTART_CHECK_EARLY_EXIT(env);
> @@ -649,15 +666,15 @@ vext_ldff(void *vd, void *v0, target_ulong base, 
> CPURISCVState *env,
>  }
>
>  /* Check page permission/pmp/watchpoint/etc. */
> -flags = probe_access_flags(env, adjust_addr(env, addr), elems * msize,
> -   MMU_DATA_LOAD, mmu_index, true, &host, ra);
> +probe_pages(env, addr, elems * msize, ra, MMU_DATA_LOAD, mmu_index, 
> &host,
> +&flags, true);
>
>  /* If we are crossing a page check also the second page. */
>  if (env->vl > elems) {
>  addr_probe 

Re: [PATCH 30/57] qapi/parser: adjust info location for doc body section

2025-03-05 Thread John Snow
On Wed, Mar 5, 2025 at 5:10 AM Markus Armbruster  wrote:

> John Snow  writes:
>
> > Instead of using the info object for the doc block as a whole (which
> > always points to the very first line of the block), update the info
> > pointer for each call to ensure_untagged_section when the existing
> > section is otherwise empty. This way, Sphinx error information will
> > match precisely to where the text actually starts.
> >
> > For example, this patch will move the info pointer for the "Hello!"
> > untagged section ...
> >
> >> ##   <-- from here ...
> >> # Hello! <-- ... to here.
> >> ##
> >
> > Signed-off-by: John Snow 
>
> This patch would be easier to accept with a test case where it improves
> the error location.  I tried to construct one quickly, but failed.  Can
> you help?
>
> Possible substitute: point to a patch later in this series where things
> become worse without this patch.


Maybe we can use the "if build_docs" section of the qapi schema testing to
run things through Sphinx and harvest the error messages for negative
cases...? I gotta sit down and figure out how.

In the meantime, if I unapply my series, then edit block-core to look like
this:

##
# @SnapshotInfo:
#
# rST syntax error: *ahh!
#

(Lines 13-17, error is on line 16)

Building, I get this error:

/home/jsnow/src/qemu/docs/../qapi/block-core.json:14: WARNING: Inline
emphasis start-string without end-string. [docutils]
/home/jsnow/src/qemu/docs/../storage-daemon/qapi/../../qapi/block-core.json:14:
WARNING: Inline emphasis start-string without end-string. [docutils]

Mmm, nope. Not quite.

If I re-push my series and try again with the same edit ...

/home/jsnow/src/qemu/docs/../qapi/block-core.json:14: WARNING: Inline
emphasis start-string without end-string. [docutils]
/home/jsnow/src/qemu/docs/../storage-daemon/qapi/../../qapi/block-core.json:14:
WARNING: Inline emphasis start-string without end-string. [docutils]
/home/jsnow/src/qemu/docs/../qapi/block-core.json:16: WARNING: Inline
emphasis start-string without end-string. [docutils]

The two inclusions from the old qapidoc are still wrong, but the inclusion
through the new transmogrifier is correct.

(I'm going to be honest with you, I don't know why the error location
didn't change at all for the old qapidoc. I think one of the many error
location bugs I fixed when writing the new transmogrifier that just never
got applied to the old system...)

If I undo this fix but keep the rest of my series, I get these errors:

/home/jsnow/src/qemu/docs/../qapi/block-core.json:14: WARNING: Inline
emphasis start-string without end-string. [docutils]
/home/jsnow/src/qemu/docs/../storage-daemon/qapi/../../qapi/block-core.json:14:
WARNING: Inline emphasis start-string without end-string. [docutils]
/home/jsnow/src/qemu/docs/../qapi/block-core.json:13: WARNING: Inline
emphasis start-string without end-string. [docutils]

Two are from the old qapidoc, one is from the new one. They're all wrong.

--js


Re: [PATCH v3 0/2] Enhanced VSTART and VL checks for vector instructions

2025-03-05 Thread Alistair Francis
On Wed, Mar 5, 2025 at 9:24 PM Chao Liu  wrote:
>
> Hi,
>
> This patchset fixes some bugs in RVV instructions,
>
> can you pull it in the near future please?
>
> Looking forward to your reply!

@Daniel Henrique Barboza you commented on v2, can you have a look at this?

Alistair

>
> --
> Regards,
> Chao
>
> >
> > Hi, all:
> >
> > In accordance with the review, i improved the commit message of patch and 
> > added
> > the reason for the modification.
> >
> > There was no change in the patch content.
> >
> > PATCH v2 review:
> > https://lore.kernel.org/qemu-devel/61e8f7d8-607a-4d63-b9dd-cfbfc8407...@ventanamicro.com/
> >
> > PATCH v1 review:
> > https://lore.kernel.org/qemu-devel/cakmqykpfyxhk8panovzv3fmwxd79wzsjylwkkoagemt_b2k...@mail.gmail.com/
> >
> > --
> > Regards,
> > Chao
> >
> > Chao Liu (2):
> >   target/riscv: refactor VSTART_CHECK_EARLY_EXIT() to accept vl as a
> > parameter
> >   target/riscv: fix handling of nop for vstart >= vl in some vector
> > instruction
> >
> >  target/riscv/vcrypto_helper.c   | 32 ++---
> >  target/riscv/vector_helper.c| 83 ++---
> >  target/riscv/vector_internals.c |  4 +-
> >  target/riscv/vector_internals.h | 12 ++---
> >  4 files changed, 69 insertions(+), 62 deletions(-)
> >
> > --
> > 2.47.1
> >
> >



Re: [RFC PATCH 1/4] qom: Introduce TypeInfo::registerable() callback

2025-03-05 Thread Richard Henderson

On 3/5/25 08:12, Philippe Mathieu-Daudé wrote:

Introduce theTypeInfo::registerable() callback to allow
runtime decision on whether register a QOM type or not.

Signed-off-by: Philippe Mathieu-Daudé
---
  include/qom/object.h | 1 +
  qom/object.c | 4 
  qom/trace-events | 1 +
  3 files changed, 6 insertions(+)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH] tests/functional: Increase the timeout of the mips64el_replay test

2025-03-05 Thread Stefan Hajnoczi
On Wed, Mar 05, 2025 at 08:43:53AM +0100, Thomas Huth wrote:
> We run the gitlab-CI with the untrusted tests enabled, and
> the test_replay_mips64el_malta_5KEc_cpio subtest is rather slow,
> so this already hit the standard 90 seconds timeout in the CI.
> Increase the timeout for more headroom.
> 
> Reported-by: Stefan Hajnoczi 
> Signed-off-by: Thomas Huth 
> ---
>  tests/functional/meson.build | 1 +
>  1 file changed, 1 insertion(+)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


RE: [PATCH v4 14/23] hw/intc/aspeed: Add Support for Multi-Output IRQ Handling

2025-03-05 Thread Jamin Lin
Hi Cedric, 

> Subject: Re: [PATCH v4 14/23] hw/intc/aspeed: Add Support for Multi-Output
> IRQ Handling
> 
> On 3/3/25 10:54, Jamin Lin wrote:
> > This update introduces support for handling multi-output IRQs in the
> > AST2700 interrupt controller (INTC), specifically for GICINT192_201.
> > GICINT192_201 maps
> > 1:10 to input IRQ 0 and output IRQs 0 to 9. Each status bit
> > corresponds to a specific IRQ.
> >
> > Implemented "aspeed_intc_set_irq_handler_multi_outpins" to handle IRQs
> > with multiple output pins. Introduced
> "aspeed_intc_status_handler_multi_outpins"
> > for managing status registers associated with multi-output IRQs.
> >
> > Added new IRQ definitions for GICINT192_201 in INTC.
> > Adjusted the IRQ array to accommodate 10 input pins and 19 output
> > pins, aligning with the new GICINT192_201 mappings.
> >
> > |--|
> > |INTC  |
> > |inpin[0:0]->outpin[0] |
> > |inpin[0:1]->outpin[1] |
> > |inpin[0:2]->outpin[2] |
> > |inpin[0:3]->outpin[3] |
> > orgates[0]---> |inpin[0:4]->outpin[4] |
> > |inpin[0:5]->outpin[5] |
> > |inpin[0:6]->outpin[6] |
> > |inpin[0:7]->outpin[7] |
> > |inpin[0:8]->outpin[8] |
> > |inpin[0:9]->outpin[9] |
> > |  |
> >   orgates[1]--> |inpin[1]--->outpin[10]|
> >   orgates[2]--> |inpin[2]--->outpin[11]|
> >   orgates[3]--> |inpin[3]--->outpin[12]|
> >   orgates[4]--> |inpin[4]--->outpin[13]|
> >   orgates[5]--> |inpin[5]--->outpin[14]|
> >   orgates[6]--> |inpin[6]--->outpin[15]|
> >   orgates[7]--> |inpin[7]--->outpin[16]|
> >   orgates[8]--> |inpin[8]--->outpin[17]|
> >   orgates[9]--> |inpin[9]--->outpin[18]|
> > |--|
> >
> > Signed-off-by: Jamin Lin 
> > ---
> >   include/hw/intc/aspeed_intc.h |   6 +-
> >   hw/intc/aspeed_intc.c | 144
> ++
> >   hw/intc/trace-events  |   1 +
> >   3 files changed, 133 insertions(+), 18 deletions(-)
> >
> > diff --git a/include/hw/intc/aspeed_intc.h
> > b/include/hw/intc/aspeed_intc.h index 112a01f402..21d9398933 100644
> > --- a/include/hw/intc/aspeed_intc.h
> > +++ b/include/hw/intc/aspeed_intc.h
> > @@ -16,9 +16,9 @@
> >   #define TYPE_ASPEED_2700_INTC TYPE_ASPEED_INTC "-ast2700"
> >   OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass,
> ASPEED_INTC)
> >
> > -#define ASPEED_INTC_NR_REGS (0x808 >> 2) -#define
> > ASPEED_INTC_MAX_INPINS 9 -#define ASPEED_INTC_MAX_OUTPINS 9
> > +#define ASPEED_INTC_NR_REGS (0xB08 >> 2) #define
> > +ASPEED_INTC_MAX_INPINS 10 #define ASPEED_INTC_MAX_OUTPINS 19
> >
> >   typedef struct AspeedINTCIRQ {
> >   int inpin_idx;
> > diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index
> > 99077ec72d..18521d3eb0 100644
> > --- a/hw/intc/aspeed_intc.c
> > +++ b/hw/intc/aspeed_intc.c
> > @@ -39,6 +39,8 @@ REG32(GICINT135_EN, 0x700)
> >   REG32(GICINT135_STATUS, 0x704)
> >   REG32(GICINT136_EN, 0x800)
> >   REG32(GICINT136_STATUS, 0x804)
> > +REG32(GICINT192_201_EN, 0xB00)
> > +REG32(GICINT192_201_STATUS, 0xB04)
> >
> >   static const AspeedINTCIRQ *aspeed_intc_get_irq(AspeedINTCClass *aic,
> >   uint32_t addr)
> @@
> > -117,9 +119,48 @@ static void
> aspeed_intc_set_irq_handler(AspeedINTCState *s,
> >   }
> >   }
> >
> > +static void aspeed_intc_set_irq_handler_multi_outpins(AspeedINTCState *s,
> > + const AspeedINTCIRQ *intc_irq,
> > +uint32_t select) {
> > +const char *name = object_get_typename(OBJECT(s));
> > +int i;
> > +
> > +for (i = 0; i < intc_irq->num_outpins; i++) {
> > +if (select & BIT(i)) {
> > +if (s->mask[intc_irq->inpin_idx] & BIT(i) ||
> > +s->regs[intc_irq->status_addr] & BIT(i)) {
> > +/*
> > + * a. mask bit is not 0 means in ISR mode sources
> interrupt
> > + * routine are executing.
> > + * b. status bit is not 0 means previous source interrupt
> > + * does not be executed, yet.
> > + *
> > + * save source interrupt to pending bit.
> > + */
> > + s->pending[intc_irq->inpin_idx] |= BIT(i);
> > + trace_aspeed_intc_pending_irq(name,
> intc_irq->inpin_idx,
> > +
> s->pending[intc_irq->inpin_idx]);
> > +} else {
> > +/*
> > + * notify firmware which source interrupt are coming
> > + * by setting 

Re: [PATCH] hw/riscv/riscv-iommu: Get target page info using runtime helpers

2025-03-05 Thread Alistair Francis
On Wed, Mar 5, 2025 at 9:20 AM Philippe Mathieu-Daudé  wrote:
>
> Prefer runtime helpers to get target page size / mask / bits
> rather than compile time definitions. This will help to build
> these files once for all RISC-V binaries.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/riscv-iommu-pci.c |  4 +++-
>  hw/riscv/riscv-iommu.c | 29 +++--
>  2 files changed, 18 insertions(+), 15 deletions(-)
>
> diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c
> index 12451869e41..e2b893c5898 100644
> --- a/hw/riscv/riscv-iommu-pci.c
> +++ b/hw/riscv/riscv-iommu-pci.c
> @@ -23,6 +23,7 @@
>  #include "hw/qdev-properties.h"
>  #include "hw/riscv/riscv_hart.h"
>  #include "migration/vmstate.h"
> +#include "exec/target_page.h"
>  #include "qapi/error.h"
>  #include "qemu/error-report.h"
>  #include "qemu/host-utils.h"
> @@ -102,7 +103,8 @@ static void riscv_iommu_pci_realize(PCIDevice *dev, Error 
> **errp)
>  qdev_realize(DEVICE(iommu), NULL, errp);
>
>  memory_region_init(&s->bar0, OBJECT(s), "riscv-iommu-bar0",
> -QEMU_ALIGN_UP(memory_region_size(&iommu->regs_mr), 
> TARGET_PAGE_SIZE));
> +   QEMU_ALIGN_UP(memory_region_size(&iommu->regs_mr),
> + qemu_target_page_size()));
>  memory_region_add_subregion(&s->bar0, 0, &iommu->regs_mr);
>
>  pcie_endpoint_cap_init(dev, 0);
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index e7568ca227a..8bbb33b8b53 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -23,6 +23,7 @@
>  #include "hw/qdev-properties.h"
>  #include "hw/riscv/riscv_hart.h"
>  #include "migration/vmstate.h"
> +#include "exec/target_page.h"
>  #include "qapi/error.h"
>  #include "qemu/timer.h"
>
> @@ -300,14 +301,14 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx,
>  riscv_iommu_msi_check(s, ctx, iotlb->iova)) {
>  iotlb->target_as = &s->trap_as;
>  iotlb->translated_addr = iotlb->iova;
> -iotlb->addr_mask = ~TARGET_PAGE_MASK;
> +iotlb->addr_mask = ~qemu_target_page_mask();
>  return 0;
>  }
>
>  /* Exit early for pass-through mode. */
>  if (!(en_s || en_g)) {
>  iotlb->translated_addr = iotlb->iova;
> -iotlb->addr_mask = ~TARGET_PAGE_MASK;
> +iotlb->addr_mask = ~qemu_target_page_mask();
>  /* Allow R/W in pass-through mode */
>  iotlb->perm = IOMMU_RW;
>  return 0;
> @@ -390,7 +391,7 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx,
>  do {
>  const unsigned widened = (pass && !sc[pass].step) ? 2 : 0;
>  const unsigned va_bits = widened + sc[pass].ptidxbits;
> -const unsigned va_skip = TARGET_PAGE_BITS + sc[pass].ptidxbits *
> +const unsigned va_skip = qemu_target_page_bits() + 
> sc[pass].ptidxbits *
>   (sc[pass].levels - 1 - sc[pass].step);
>  const unsigned idx = (addr >> va_skip) & ((1 << va_bits) - 1);
>  const dma_addr_t pte_addr = base + idx * sc[pass].ptesize;
> @@ -448,7 +449,7 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx,
>  break;/* Reserved leaf PTE flags: PTE_W */
>  } else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
>  break;/* Reserved leaf PTE flags: PTE_W + PTE_X 
> */
> -} else if (ppn & ((1ULL << (va_skip - TARGET_PAGE_BITS)) - 1)) {
> +} else if (ppn & ((1ULL << (va_skip - qemu_target_page_bits())) - 
> 1)) {
>  break;/* Misaligned PPN */
>  } else if ((iotlb->perm & IOMMU_RO) && !(pte & PTE_R)) {
>  break;/* Read access check failed */
> @@ -480,7 +481,7 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx,
>  riscv_iommu_msi_check(s, ctx, base)) {
>  /* Trap MSI writes and return GPA address. */
>  iotlb->target_as = &s->trap_as;
> -iotlb->addr_mask = ~TARGET_PAGE_MASK;
> +iotlb->addr_mask = ~qemu_target_page_mask();
>  return 0;
>  }
>
> @@ -950,7 +951,7 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx)
>   *   device index: [23:16][15:7][6:0]
>   */
>  const int split = depth * 9 + 6 + dc_fmt;
> -addr |= ((ctx->devid >> split) << 3) & ~TARGET_PAGE_MASK;
> +addr |= ((ctx->devid >> split) << 3) & ~qemu_target_page_mask();
>  if (dma_memory_read(s->target_as, addr, &de, sizeof(de),
>  MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
>  return RISCV_IOMMU_FQ_CAUSE_DDT_LOAD_FAULT;
> @@ -968,7 +969,7 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx)

Re: [PATCH] hw/riscv/riscv-iommu: Get target page info using runtime helpers

2025-03-05 Thread Alistair Francis
On Wed, Mar 5, 2025 at 9:20 AM Philippe Mathieu-Daudé  wrote:
>
> Prefer runtime helpers to get target page size / mask / bits
> rather than compile time definitions. This will help to build
> these files once for all RISC-V binaries.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Thanks!

Do you mind rebasing on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next ?

Alistair

> ---
>  hw/riscv/riscv-iommu-pci.c |  4 +++-
>  hw/riscv/riscv-iommu.c | 29 +++--
>  2 files changed, 18 insertions(+), 15 deletions(-)
>
> diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c
> index 12451869e41..e2b893c5898 100644
> --- a/hw/riscv/riscv-iommu-pci.c
> +++ b/hw/riscv/riscv-iommu-pci.c
> @@ -23,6 +23,7 @@
>  #include "hw/qdev-properties.h"
>  #include "hw/riscv/riscv_hart.h"
>  #include "migration/vmstate.h"
> +#include "exec/target_page.h"
>  #include "qapi/error.h"
>  #include "qemu/error-report.h"
>  #include "qemu/host-utils.h"
> @@ -102,7 +103,8 @@ static void riscv_iommu_pci_realize(PCIDevice *dev, Error 
> **errp)
>  qdev_realize(DEVICE(iommu), NULL, errp);
>
>  memory_region_init(&s->bar0, OBJECT(s), "riscv-iommu-bar0",
> -QEMU_ALIGN_UP(memory_region_size(&iommu->regs_mr), 
> TARGET_PAGE_SIZE));
> +   QEMU_ALIGN_UP(memory_region_size(&iommu->regs_mr),
> + qemu_target_page_size()));
>  memory_region_add_subregion(&s->bar0, 0, &iommu->regs_mr);
>
>  pcie_endpoint_cap_init(dev, 0);
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index e7568ca227a..8bbb33b8b53 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -23,6 +23,7 @@
>  #include "hw/qdev-properties.h"
>  #include "hw/riscv/riscv_hart.h"
>  #include "migration/vmstate.h"
> +#include "exec/target_page.h"
>  #include "qapi/error.h"
>  #include "qemu/timer.h"
>
> @@ -300,14 +301,14 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx,
>  riscv_iommu_msi_check(s, ctx, iotlb->iova)) {
>  iotlb->target_as = &s->trap_as;
>  iotlb->translated_addr = iotlb->iova;
> -iotlb->addr_mask = ~TARGET_PAGE_MASK;
> +iotlb->addr_mask = ~qemu_target_page_mask();
>  return 0;
>  }
>
>  /* Exit early for pass-through mode. */
>  if (!(en_s || en_g)) {
>  iotlb->translated_addr = iotlb->iova;
> -iotlb->addr_mask = ~TARGET_PAGE_MASK;
> +iotlb->addr_mask = ~qemu_target_page_mask();
>  /* Allow R/W in pass-through mode */
>  iotlb->perm = IOMMU_RW;
>  return 0;
> @@ -390,7 +391,7 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx,
>  do {
>  const unsigned widened = (pass && !sc[pass].step) ? 2 : 0;
>  const unsigned va_bits = widened + sc[pass].ptidxbits;
> -const unsigned va_skip = TARGET_PAGE_BITS + sc[pass].ptidxbits *
> +const unsigned va_skip = qemu_target_page_bits() + 
> sc[pass].ptidxbits *
>   (sc[pass].levels - 1 - sc[pass].step);
>  const unsigned idx = (addr >> va_skip) & ((1 << va_bits) - 1);
>  const dma_addr_t pte_addr = base + idx * sc[pass].ptesize;
> @@ -448,7 +449,7 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx,
>  break;/* Reserved leaf PTE flags: PTE_W */
>  } else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
>  break;/* Reserved leaf PTE flags: PTE_W + PTE_X 
> */
> -} else if (ppn & ((1ULL << (va_skip - TARGET_PAGE_BITS)) - 1)) {
> +} else if (ppn & ((1ULL << (va_skip - qemu_target_page_bits())) - 
> 1)) {
>  break;/* Misaligned PPN */
>  } else if ((iotlb->perm & IOMMU_RO) && !(pte & PTE_R)) {
>  break;/* Read access check failed */
> @@ -480,7 +481,7 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx,
>  riscv_iommu_msi_check(s, ctx, base)) {
>  /* Trap MSI writes and return GPA address. */
>  iotlb->target_as = &s->trap_as;
> -iotlb->addr_mask = ~TARGET_PAGE_MASK;
> +iotlb->addr_mask = ~qemu_target_page_mask();
>  return 0;
>  }
>
> @@ -950,7 +951,7 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx)
>   *   device index: [23:16][15:7][6:0]
>   */
>  const int split = depth * 9 + 6 + dc_fmt;
> -addr |= ((ctx->devid >> split) << 3) & ~TARGET_PAGE_MASK;
> +addr |= ((ctx->devid >> split) << 3) & ~qemu_target_page_mask();
>  if (dma_memory_read(s->target_as, addr, &de, sizeof(de),
>  MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
>  return RISCV_IOMMU_FQ_CAUSE_DDT_LOAD_FAULT;
> @@ -968,7 +969,7 @@ static int risc

Re: [PATCH 31/57] qapi: expand tags to all doc sections

2025-03-05 Thread John Snow
On Wed, Mar 5, 2025 at 5:16 AM Markus Armbruster  wrote:

> Replaying review of a previous posting for your convenience...
>
> John Snow  writes:
>
> > This patch adds an explicit section "kind" to all QAPIDoc
> > sections. Members/Features are now explicitly marked as such, with the
> > name now being stored in a dedicated "name" field (which qapidoc.py was
> > not actually using anyway.)
>
> I'm not sure what the parenthesis is trying to convey.
>

The old qapidoc.py doesn't actually use the name field, so there's nothing
to adjust for old callers.


>
> Before the patch, we have:
>
>   typetag
> untagged  Section None
> @foo: ArgSection  'foo'
> Returns:  Section 'Returns'
> Errors:   Section 'Errors'
> Since:Section 'Since'
> TODO: Section 'TODO'
>
> Afterwards, I believe:
>
>   type kind name
> untagged  Section  PLAIN
> @foo: ArgSection   MEMBER   'foo'   if member or argument
>   ArgSection   FEATURE  'foo'   if feature
> Returns:  Section  RETURNS
> Errors:   Section  ERRORS
> Since:Section  SINCE
> TODO: Section  TODO
>
> So, .tag is replaced by .kind and .name, member vs. feature vs. other
> tags is now obvious from .kind alone, i.e. there's no need to account
> for context or type.
>
> Fine print: why do we need to account for type before the patch?
> Consider @Since: ...
>

I'm not sure I follow...


>
> > The qapi-schema tests are updated to account for the new section names;
> > mostly "TODO" becomes "Todo" and `None` becomes "Plain".
> >
> > Signed-off-by: John Snow 
> > ---
> >  docs/sphinx/qapidoc.py |   7 ++-
> >  scripts/qapi/parser.py | 109 -
> >  tests/qapi-schema/doc-good.out |  10 +--
> >  tests/qapi-schema/test-qapi.py |   2 +-
> >  4 files changed, 90 insertions(+), 38 deletions(-)
> >
> > diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py
> > index 61997fd21af..d622398f1da 100644
> > --- a/docs/sphinx/qapidoc.py
> > +++ b/docs/sphinx/qapidoc.py
> > @@ -35,6 +35,7 @@
> >  from docutils.statemachine import ViewList
> >  from qapi.error import QAPIError, QAPISemError
> >  from qapi.gen import QAPISchemaVisitor
> > +from qapi.parser import QAPIDoc
> >  from qapi.schema import QAPISchema
> >
> >  from sphinx import addnodes
> > @@ -258,11 +259,11 @@ def _nodes_for_sections(self, doc):
> >  """Return list of doctree nodes for additional sections"""
> >  nodelist = []
> >  for section in doc.sections:
> > -if section.tag and section.tag == 'TODO':
> > +if section.kind == QAPIDoc.Kind.TODO:
> >  # Hide TODO: sections
> >  continue
> >
> > -if not section.tag:
> > +if section.kind == QAPIDoc.Kind.PLAIN:
> >  # Sphinx cannot handle sectionless titles;
> >  # Instead, just append the results to the prior section.
> >  container = nodes.container()
> > @@ -270,7 +271,7 @@ def _nodes_for_sections(self, doc):
> >  nodelist += container.children
> >  continue
> >
> > -snode = self._make_section(section.tag)
> > +snode = self._make_section(section.kind.name.title())
> >  self._parse_text_into_node(dedent(section.text), snode)
> >  nodelist.append(snode)
> >  return nodelist
> > diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
> > index 36cb64a677a..c3004aa70c6 100644
> > --- a/scripts/qapi/parser.py
> > +++ b/scripts/qapi/parser.py
> > @@ -15,6 +15,7 @@
> >  # See the COPYING file in the top-level directory.
> >
> >  from collections import OrderedDict
> > +import enum
> >  import os
> >  import re
> >  from typing import (
> > @@ -575,7 +576,10 @@ def get_doc(self) -> 'QAPIDoc':
> >  )
> >  raise QAPIParseError(self, emsg)
> >
> > -doc.new_tagged_section(self.info, match.group(1))
> > +doc.new_tagged_section(
> > +self.info,
> > +QAPIDoc.Kind.from_string(match.group(1))
> > +)
> >  text = line[match.end():]
> >  if text:
> >  doc.append_line(text)
> > @@ -586,7 +590,7 @@ def get_doc(self) -> 'QAPIDoc':
> >  self,
> >  "unexpected '=' markup in definition
> documentation")
> >  else:
> > -# tag-less paragraph
> > +# plain paragraph(s)
>
> We're parsing a single pargraph here.  The plain section we add it to
> may have any number of paragraphs.  But for me, the comment is about
> what's being parsed.  Mind to drop (s)?
>

Anguish. I can't keep this straight in my head. OK. It wasn't obvious at a
glance where th

Re: [PATCH 1/6] hw/ppc: Implement skeleton code for fadump in PSeries

2025-03-05 Thread Aditya Gupta

Hi Harsh,

Thanks for your reviews.


On 04/03/25 14:31, Harsh Prateek Bora wrote:



On 2/17/25 12:47, Aditya Gupta wrote:

Implement the handler for "ibm,configure-kernel-dump" rtas call in QEMU.

Currently the handler just does basic checks and handles
register/unregister/invalidate requests from kernel.

Fadump will be enabled in a later patch.


Let's use FADump or fadump for consistency.


Sure, will use FADump when starting the line, else fadump ?


Signed-off-by: Aditya Gupta 
---
  hw/ppc/spapr_rtas.c    | 99 ++
  include/hw/ppc/spapr.h | 59 +
  2 files changed, 158 insertions(+)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index df2e837632aa..eebdf13b1552 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -341,6 +341,105 @@ static void 
rtas_ibm_set_system_parameter(PowerPCCPU *cpu,

  rtas_st(rets, 0, ret);
  }
  +struct fadump_metadata fadump_metadata;
+
+/* Papr Section 7.4.9 ibm,configure-kernel-dump RTAS call */
+static __attribute((unused)) void 
rtas_configure_kernel_dump(PowerPCCPU *cpu,


This __attribute shall be avoided if the function can be introduced 
when actually get used.

Will do it that way in v2, without introducing this unused attribute.



+ SpaprMachineState *spapr,
+   uint32_t token, uint32_t nargs,
+   target_ulong args,
+   uint32_t nret, target_ulong rets)
+{
+    struct rtas_fadump_section_header header;
+    target_ulong cmd = rtas_ld(args, 0);
+    target_ulong fdm_addr = rtas_ld(args, 1);
+    target_ulong fdm_size = rtas_ld(args, 2);
+
+    /* Number outputs has to be 1 */
+    if (nret != 1) {
+    qemu_log_mask(LOG_GUEST_ERROR,
+    "FADUMP: ibm,configure-kernel-dump RTAS called with 
nret != 1.\n");


Some of the error cases are using hcall_dprintf below. Let's use same
for consistency. Also, shouldn't this case also return 
RTAS_OUT_PARAM_ERROR ?


Sure, will use qemu_log_mask then.

Thanks for the catch, yes I should have returned PARAM_ERROR, missed it. 
Will do it.





+    return;
+    }
+
+    /* Number inputs has to be 3 */
+    if (nargs != 3) {
+    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);


Log error ?

Will add.



+    return;
+    }
+
+    switch (cmd) {
+    case FADUMP_CMD_REGISTER:
+    if (fadump_metadata.fadump_registered) {
+    /* Fadump already registered */
+    rtas_st(rets, 0, RTAS_OUT_DUMP_ALREADY_REGISTERED);


Log error ?

Will do.



+    return;
+    }
+
+    if (fadump_metadata.fadump_dump_active == 1) {
+    rtas_st(rets, 0, RTAS_OUT_DUMP_ACTIVE);


Log error?

Will add.



+    return;
+    }
+
+    if (fdm_size < sizeof(struct rtas_fadump_section_header)) {
+    qemu_log_mask(LOG_GUEST_ERROR,
+    "FADUMP: Header size is invalid: %lu\n", fdm_size);
+    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+    return;
+    }
+
+    /* XXX: Can we ensure fdm_addr points to a valid RMR-memory 
buffer ? */

+    if (fdm_addr <= 0) {
+    qemu_log_mask(LOG_GUEST_ERROR,
+    "FADUMP: Invalid fdm address: %ld\n", fdm_addr);
+    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+    return;
+    }
+
+    /* Verify that we understand the fadump header version */
+    cpu_physical_memory_read(fdm_addr, &header, sizeof(header));
+    if (header.dump_format_version != 
cpu_to_be32(FADUMP_VERSION)) {

+    qemu_log_mask(LOG_GUEST_ERROR,
+    "FADUMP: Unknown fadump header version: 0x%x\n",
+    header.dump_format_version);
+    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+    return;
+    }
+
+    fadump_metadata.fadump_registered = true;
+    fadump_metadata.fadump_dump_active = false;
+    fadump_metadata.fdm_addr = fdm_addr;
+    break;
+    case FADUMP_CMD_UNREGISTER:
+    if (fadump_metadata.fadump_dump_active == 1) {
+    rtas_st(rets, 0, RTAS_OUT_DUMP_ACTIVE);


Log error?

Will add.



+    return;
+    }
+
+    fadump_metadata.fadump_registered = false;
+    fadump_metadata.fadump_dump_active = false;
+    fadump_metadata.fdm_addr = -1;
+    break;
+    case FADUMP_CMD_INVALIDATE:
+    if (fadump_metadata.fadump_dump_active) {
+    fadump_metadata.fadump_registered = false;
+    fadump_metadata.fadump_dump_active = false;
+    fadump_metadata.fdm_addr = -1;
+    memset(&fadump_metadata.registered_fdm, 0,
+    sizeof(fadump_metadata.registered_fdm));
+    } else {
+    hcall_dprintf("fadump: Nothing to invalidate, no dump 
active.\n");


Isnt this an error case? Should it return status as error or success ?


Not sure. PAPR doesn't specify it any error for this situation. With 
this current code, software can do invalidat

Re: [PATCH v2 3/6] hw/riscv: Make FDT optional for MPFS

2025-03-05 Thread Alistair Francis
On Tue, Feb 25, 2025 at 10:55 AM Sebastian Huber
 wrote:
>
> Real-time kernels such as RTEMS or Zephyr may use a static device tree
> built into the kernel image.  Do not require to use the -dtb option if
> -kernel is used for the microchip-icicle-kit machine.  Issue a warning
> if no device tree is provided by the user since the machine does not
> generate one.
>
> Signed-off-by: Sebastian Huber 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/microchip_pfsoc.c | 56 +++---
>  1 file changed, 28 insertions(+), 28 deletions(-)
>
> diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> index f477d2791e..844dc0545c 100644
> --- a/hw/riscv/microchip_pfsoc.c
> +++ b/hw/riscv/microchip_pfsoc.c
> @@ -516,7 +516,6 @@ static void 
> microchip_icicle_kit_machine_init(MachineState *machine)
>  uint64_t mem_low_size, mem_high_size;
>  hwaddr firmware_load_addr;
>  const char *firmware_name;
> -bool kernel_as_payload = false;
>  target_ulong firmware_end_addr, kernel_start_addr;
>  uint64_t kernel_entry;
>  uint64_t fdt_load_addr;
> @@ -589,25 +588,12 @@ static void 
> microchip_icicle_kit_machine_init(MachineState *machine)
>   *
>   * This ensures backwards compatibility with how we used to expose -bios
>   * to users but allows them to run through direct kernel booting as well.
> - *
> - * When -kernel is used for direct boot, -dtb must be present to provide
> - * a valid device tree for the board, as we don't generate device tree.
>   */
>
> -if (machine->kernel_filename && machine->dtb) {
> -int fdt_size;
> -machine->fdt = load_device_tree(machine->dtb, &fdt_size);
> -if (!machine->fdt) {
> -error_report("load_device_tree() failed");
> -exit(1);
> -}
> -
> +if (machine->kernel_filename) {
>  firmware_name = RISCV64_BIOS_BIN;
>  firmware_load_addr = memmap[MICROCHIP_PFSOC_DRAM_LO].base;
> -kernel_as_payload = true;
> -}
> -
> -if (!kernel_as_payload) {
> +} else {
>  firmware_name = BIOS_FILENAME;
>  firmware_load_addr = RESET_VECTOR;
>  }
> @@ -617,7 +603,7 @@ static void 
> microchip_icicle_kit_machine_init(MachineState *machine)
>   &firmware_load_addr, 
> NULL);
>
>  riscv_boot_info_init(&boot_info, &s->soc.u_cpus);
> -if (kernel_as_payload) {
> +if (machine->kernel_filename) {
>  kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info,
>   firmware_end_addr);
>
> @@ -625,19 +611,33 @@ static void 
> microchip_icicle_kit_machine_init(MachineState *machine)
>true, NULL);
>  kernel_entry = boot_info.image_low_addr;
>
> -/* Compute the fdt load address in dram */
> -hwaddr kernel_ram_base = memmap[MICROCHIP_PFSOC_DRAM_LO].base;
> -hwaddr kernel_ram_size = memmap[MICROCHIP_PFSOC_DRAM_LO].size;
> -
> -if (kernel_entry - kernel_ram_base >= kernel_ram_size) {
> -kernel_ram_base = memmap[MICROCHIP_PFSOC_DRAM_HI].base;
> -kernel_ram_size = mem_high_size;
> +if (machine->dtb) {
> +int fdt_size;
> +machine->fdt = load_device_tree(machine->dtb, &fdt_size);
> +if (!machine->fdt) {
> +error_report("load_device_tree() failed");
> +exit(1);
> +}
> +
> +/* Compute the FDT load address in DRAM */
> +hwaddr kernel_ram_base = memmap[MICROCHIP_PFSOC_DRAM_LO].base;
> +hwaddr kernel_ram_size = memmap[MICROCHIP_PFSOC_DRAM_LO].size;
> +
> +if (kernel_entry - kernel_ram_base >= kernel_ram_size) {
> +kernel_ram_base = memmap[MICROCHIP_PFSOC_DRAM_HI].base;
> +kernel_ram_size = mem_high_size;
> +}
> +
> +fdt_load_addr = riscv_compute_fdt_addr(kernel_ram_base, 
> kernel_ram_size,
> +   machine, &boot_info);
> +riscv_load_fdt(fdt_load_addr, machine->fdt);
> +} else {
> +warn_report_once("The QEMU microchip-icicle-kit machine does not 
> "
> + "generate a device tree, so no device tree is "
> + "being provided to the guest.");
> +fdt_load_addr = 0;
>  }
>
> -fdt_load_addr = riscv_compute_fdt_addr(kernel_ram_base, 
> kernel_ram_size,
> -   machine, &boot_info);
> -riscv_load_fdt(fdt_load_addr, machine->fdt);
> -
>  /* Load the reset vector */
>  riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, 
> firmware_load_addr,
>memmap[MICROCHIP_PFSOC_ENVM_DATA].base,
> --
> 2.43.0
>



Re: [PATCH 3/6] hw/ppc: Preserve memory regions registered for fadump

2025-03-05 Thread Aditya Gupta

On 05/03/25 12:10, Harsh Prateek Bora wrote:




On 2/17/25 12:47, Aditya Gupta wrote:

<...snip...>

+    /* Reset error_flags & bytes_dumped for now */
+    fdm->rgn[i].error_flags = 0;
+    fdm->rgn[i].bytes_dumped = 0;
+
+    if (be32_to_cpu(fdm->rgn[i].request_flag) != 
FADUMP_REQUEST_FLAG) {

+    qemu_log_mask(LOG_UNIMP,
+    "FADUMP: Skipping copying region as not requested\n");
+    continue;
+    }
+
+    switch (data_type) {
+    case FADUMP_CPU_STATE_DATA:
+    /* TODO: Add CPU state data */
+    break;
+    case FADUMP_HPTE_REGION:
+    /* TODO: Add hpte state data */
+    break;
+    case FADUMP_REAL_MODE_REGION:
+    case FADUMP_PARAM_AREA:
+    /* Skip copy if source and destination are same (eg. 
param area) */

+    if (src_addr != dest_addr) {
+    copy_buffer = g_malloc(src_len + 1);
+    if (copy_buffer == NULL) {
+    qemu_log_mask(LOG_GUEST_ERROR,
+    "FADUMP: Failed allocating memory for 
copying reserved memory regions\n");

+    fdm->rgn[i].error_flags =
+ cpu_to_be16(FADUMP_ERROR_LENGTH_EXCEEDS_SOURCE);
+
+    continue;
+    }
+
+    /* Copy the source region to destination */
+    cpu_physical_memory_read(src_addr, copy_buffer, 
src_len);
+    cpu_physical_memory_write(dest_addr, copy_buffer, 
src_len);

+    g_free(copy_buffer);
+    }
+
+    /*
+ * Considering cpu_physical_memory_write would have 
copied the

+ * complete region
+ */
+    fdm->rgn[i].bytes_dumped = cpu_to_be64(src_len);


Is this really valid for FADUMP_PARAM_AREA where we intend to skip copy?

Yes I think it's good to keep it. Because that's an optimisation i did 
to skip the copy if src and dest are same.


But the actual copy depends on the OS passing us the 
"FADUMP_REQUEST_FLAG" in the region's request flag.


If the flag is set, i am expecting the kernel asked us to copy, and 
hence the .bytes_dumped should be same as the number of bytes asked by 
kernel to copy ideally.


If the flag is not set, we return early, so we let the .bytes_dumped be 0.


+
+    break;
+    default:
+    qemu_log_mask(LOG_GUEST_ERROR,
+    "FADUMP: Skipping unknown source data type: %d\n", 
data_type);

+
+    fdm->rgn[i].error_flags =
+    cpu_to_be16(FADUMP_ERROR_INVALID_DATA_TYPE);
+    }
+    }
+
+    return true;
+}
+
  static void trigger_fadump_boot(target_ulong spapr_retcode)
  {
  /*
@@ -353,7 +467,8 @@ static void trigger_fadump_boot(target_ulong 
spapr_retcode)

   */
  pause_all_vcpus();
  -    if (true /* TODO: Preserve memory registered for fadump */) {
+    /* Preserve the memory locations registered for fadump */
+    if (!fadump_preserve_mem()) {


This change can be avoided as suggested in previous patch.

Agreed, will do it in previous patch.



  /* Failed to preserve the registered memory regions */
  rtas_st(spapr_retcode, 0, RTAS_OUT_HW_ERROR);
  diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index efa2f891a8a7..a80704187583 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -776,7 +776,32 @@ void push_sregs_to_kvm_pr(SpaprMachineState 
*spapr);

  #define FADUMP_CMD_UNREGISTER  2
  #define FADUMP_CMD_INVALIDATE  3
  -#define FADUMP_VERSION    1
+#define FADUMP_VERSION 1


This change can be avoided if taken care initially.


Nice, I missed this diff. Will fix it in the patch which introduced this.


Thanks,

- Aditya Gupta



Thanks
Harsh

+
+/*
+ * The Firmware Assisted Dump Memory structure supports a maximum of 
10 sections

+ * in the dump memory structure. Presently, three sections are used for
+ * CPU state data, HPTE & Parameters area, while the remaining seven 
sections

+ * can be used for boot memory regions.
+ */
+#define FADUMP_MAX_SECTIONS    10
+#define RTAS_FADUMP_MAX_BOOT_MEM_REGS  7
+
+/* Firmware provided dump sections */
+#define FADUMP_CPU_STATE_DATA   0x0001
+#define FADUMP_HPTE_REGION  0x0002
+#define FADUMP_REAL_MODE_REGION 0x0011
+
+/* OS defined sections */
+#define FADUMP_PARAM_AREA   0x0100
+
+/* Dump request flag */
+#define FADUMP_REQUEST_FLAG 0x0001
+
+/* Dump status flag */
+#define FADUMP_ERROR_INVALID_DATA_TYPE  0x8000
+#define FADUMP_ERROR_INVALID_SOURCE_ADDR    0x4000
+#define FADUMP_ERROR_LENGTH_EXCEEDS_SOURCE  0x2000
    /*
   * The Firmware Assisted Dump Memory structure supports a maximum 
of 10 sections




Re: [PATCH 01/22] target/riscv: Declare RISCVCPUClass::misa_mxl_max as RISCVMXL

2025-03-05 Thread Alistair Francis
On Fri, Feb 28, 2025 at 8:31 PM Paolo Bonzini  wrote:
>
> From: Philippe Mathieu-Daudé 
>
> Signed-off-by: Philippe Mathieu-Daudé 
> Reviewed-by: Richard Henderson 
> Link: https://lore.kernel.org/r/20250212213249.45574-7-phi...@linaro.org
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h | 2 +-
>  target/riscv/cpu.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index df7a05e7d15..3041a4be5c9 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -543,7 +543,7 @@ struct RISCVCPUClass {
>
>  DeviceRealize parent_realize;
>  ResettablePhases parent_phases;
> -uint32_t misa_mxl_max;  /* max mxl for this cpu */
> +RISCVMXL misa_mxl_max;  /* max mxl for this cpu */
>  };
>
>  static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 244e44ce410..85dc2fe3bec 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -2961,7 +2961,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
> *data)
>  {
>  RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
>
> -mcc->misa_mxl_max = (uint32_t)(uintptr_t)data;
> +mcc->misa_mxl_max = (RISCVMXL)(uintptr_t)data;
>  riscv_cpu_validate_misa_mxl(mcc);
>  }
>
> --
> 2.48.1
>
>



Re: [PATCH] block/qed: fix use-after-free by nullifying timer pointer after free

2025-03-05 Thread Stefan Hajnoczi
On Tue, Mar 04, 2025 at 11:39:10AM +0300, ger...@altlinux.org wrote:
> From: Denis Rastyogin 
> 
> This error was discovered by fuzzing qemu-img.
> 
> In the QED block driver, the need_check_timer timer is freed in
> bdrv_qed_detach_aio_context, but the pointer to the timer is not
> set to NULL. This can lead to a use-after-free scenario
> in bdrv_qed_drain_begin().
> 
> The need_check_timer pointer is set to NULL after freeing the timer.
> Which helps catch this condition when checking in bdrv_qed_drain_begin().
> 
> Closes: https://gitlab.com/qemu-project/qemu/-/issues/2852
> Signed-off-by: Denis Rastyogin 
> ---
>  block/qed.c | 1 +
>  1 file changed, 1 insertion(+)

Thanks, applied to my block tree:
https://gitlab.com/stefanha/qemu/commits/block

Stefan


signature.asc
Description: PGP signature


[PULL 0/1] Block patches

2025-03-05 Thread Stefan Hajnoczi
The following changes since commit 661c2e1ab29cd9c4d268ae3f44712e8d421c0e56:

  scripts/checkpatch: Fix a typo (2025-03-04 09:30:26 +0800)

are available in the Git repository at:

  https://gitlab.com/stefanha/qemu.git tags/block-pull-request

for you to fetch changes up to 2ad638a3d160923ef3dbf87c73944e6e44bdc724:

  block/qed: fix use-after-free by nullifying timer pointer after free 
(2025-03-06 10:19:54 +0800)


Pull request

QED need_check_timer use-after-free fix



Denis Rastyogin (1):
  block/qed: fix use-after-free by nullifying timer pointer after free

 block/qed.c | 1 +
 1 file changed, 1 insertion(+)

-- 
2.48.1




[PULL 1/1] block/qed: fix use-after-free by nullifying timer pointer after free

2025-03-05 Thread Stefan Hajnoczi
From: Denis Rastyogin 

This error was discovered by fuzzing qemu-img.

In the QED block driver, the need_check_timer timer is freed in
bdrv_qed_detach_aio_context, but the pointer to the timer is not
set to NULL. This can lead to a use-after-free scenario
in bdrv_qed_drain_begin().

The need_check_timer pointer is set to NULL after freeing the timer.
Which helps catch this condition when checking in bdrv_qed_drain_begin().

Closes: https://gitlab.com/qemu-project/qemu/-/issues/2852
Signed-off-by: Denis Rastyogin 
Message-ID: <20250304083927.37681-1-ger...@altlinux.org>
Signed-off-by: Stefan Hajnoczi 
---
 block/qed.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/qed.c b/block/qed.c
index 382c9e5335..ac24449ffb 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -353,6 +353,7 @@ static void bdrv_qed_detach_aio_context(BlockDriverState 
*bs)
 
 qed_cancel_need_check_timer(s);
 timer_free(s->need_check_timer);
+s->need_check_timer = NULL;
 }
 
 static void bdrv_qed_attach_aio_context(BlockDriverState *bs,
-- 
2.48.1




Re: [PATCH 4/6] hw/ppc: Implement saving CPU state in Fadump

2025-03-05 Thread Aditya Gupta

On 05/03/25 12:53, Harsh Prateek Bora wrote:




On 2/17/25 12:47, Aditya Gupta wrote:

<...snip...>

+    case FADUMP_CPU_STATE_DATA: {
+    struct rtas_fadump_reg_save_area_header reg_save_hdr;
+    struct rtas_fadump_reg_entry **reg_entries;
+    struct rtas_fadump_reg_entry *curr_reg_entry;
+
+    uint32_t fadump_reg_entries_size;
+    __be32 num_cpus = 0;
+    uint32_t num_regs_per_cpu = 0;
+    CPUState *cpu;
+    CPUPPCState *env;
+    PowerPCCPU *ppc_cpu;
+
+    CPU_FOREACH(cpu) {
+    ++num_cpus;
+    }
+
+    reg_save_hdr.version = cpu_to_be32(1);


PAPR spec mentions version value as 0. Do we need to update ?

Yes, will fix, thanks Harsh.



+    reg_save_hdr.magic_number =
+    cpu_to_be64(fadump_str_to_u64("REGSAVE"));
+
+    /* Reg save area header is immediately followed by num 
cpus */

+    reg_save_hdr.num_cpu_offset =
+    cpu_to_be32(sizeof(struct 
rtas_fadump_reg_save_area_header));

+


Above inits could go into a helper 
fadump_init_reg_save_header(®_save_hdr);
BTW, the PAPR spec also mentions about padding followed by 
num_cpus_offset, see another comment later below.




+    fadump_reg_entries_size = num_cpus *
+  FADUMP_NUM_PER_CPU_REGS *
+  sizeof(struct 
rtas_fadump_reg_entry);

+
+    reg_entries = malloc(fadump_reg_entries_size);


This was declared as double pointer, but being used as a pointer.
Agreed, not needed to keep it as double pointer. My initial plan for 
this variable was different, that's why i was using double pointer 
earlier to point to a list of CPU registers, and each CPU registers 
itself an array. Not needed in current implementation. Will fix it.


+    curr_reg_entry = (struct rtas_fadump_reg_entry 
*)reg_entries;

+
+    /* This must loop num_cpus time */
+    CPU_FOREACH(cpu) {
+    ppc_cpu = POWERPC_CPU(cpu);
+    env = cpu_env(cpu);
+    num_regs_per_cpu = 0;
+
+    curr_reg_entry->reg_id =
+    cpu_to_be64(fadump_str_to_u64("CPUSTRT"));
+    curr_reg_entry->reg_value = ppc_cpu->vcpu_id;
+    ++curr_reg_entry;
+
+#define REG_ENTRY(id, val) \
+    do { \
+    curr_reg_entry->reg_id =   \
+    cpu_to_be64(fadump_str_to_u64(#id)); \
+    curr_reg_entry->reg_value = val;   \
+    ++curr_reg_entry; \
+    ++num_regs_per_cpu; \
+    } while (0)
+
+    REG_ENTRY(ACOP, env->spr[SPR_ACOP]);
+    REG_ENTRY(AMR, env->spr[SPR_AMR]);
+    REG_ENTRY(BESCR, env->spr[SPR_BESCR]);
+    REG_ENTRY(CFAR, env->spr[SPR_CFAR]);
+    REG_ENTRY(CIABR, env->spr[SPR_CIABR]);
+
+    /* Save the condition register */
+    uint64_t cr = 0;
+    cr |= (env->crf[0] & 0xf);
+    cr |= (env->crf[1] & 0xf) << 1;
+    cr |= (env->crf[2] & 0xf) << 2;
+    cr |= (env->crf[3] & 0xf) << 3;
+    cr |= (env->crf[4] & 0xf) << 4;
+    cr |= (env->crf[5] & 0xf) << 5;
+    cr |= (env->crf[6] & 0xf) << 6;
+    cr |= (env->crf[7] & 0xf) << 7;
+    REG_ENTRY(CR, cr);


ppc_get_cr ?

Thanks, will use it.



+
+    REG_ENTRY(CTR, env->spr[SPR_CTR]);
+    REG_ENTRY(CTRL, env->spr[SPR_CTRL]);
+    REG_ENTRY(DABR, env->spr[SPR_DABR]);
+    REG_ENTRY(DABRX, env->spr[SPR_DABRX]);
+    REG_ENTRY(DAR, env->spr[SPR_DAR]);
+    REG_ENTRY(DAWR0, env->spr[SPR_DAWR0]);
+    REG_ENTRY(DAWR1, env->spr[SPR_DAWR1]);
+    REG_ENTRY(DAWRX0, env->spr[SPR_DAWRX0]);
+    REG_ENTRY(DAWRX1, env->spr[SPR_DAWRX1]);
+    REG_ENTRY(DPDES, env->spr[SPR_DPDES]);
+    REG_ENTRY(DSCR, env->spr[SPR_DSCR]);
+    REG_ENTRY(DSISR, env->spr[SPR_DSISR]);
+    REG_ENTRY(EBBHR, env->spr[SPR_EBBHR]);
+    REG_ENTRY(EBBRR, env->spr[SPR_EBBRR]);
+
+    REG_ENTRY(FPSCR, env->fpscr);
+    REG_ENTRY(FSCR, env->spr[SPR_FSCR]);
+
+    /* Save the GPRs */
+    for (int gpr_id = 0; gpr_id < 32; ++gpr_id) {
+    curr_reg_entry->reg_id =
+ cpu_to_be64(fadump_gpr_id_to_u64(gpr_id));
+    curr_reg_entry->reg_value = env->gpr[i];
+    ++curr_reg_entry;
+    ++num_regs_per_cpu;
+    }
+
+    REG_ENTRY(IAMR, env->spr[SPR_IAMR]);
+    REG_ENTRY(IC, env->spr[SPR_IC]);
+    REG_ENTRY(LR, env->spr[SPR_LR]);
+
+    REG_ENTRY(MSR, env->msr);
+  

Re: [PATCH v2 4/6] hw/riscv: Allow direct start of kernel for MPFS

2025-03-05 Thread Alistair Francis
On Tue, Feb 25, 2025 at 10:55 AM Sebastian Huber
 wrote:
>
> Further customize the -bios and -kernel options behaviour for the
> microchip-icicle-kit machine.  If "-bios none -kernel filename" is
> specified, then do not load a firmware and instead only load and start
> the kernel image.
>
> Signed-off-by: Sebastian Huber 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/microchip_pfsoc.c | 57 ++
>  1 file changed, 40 insertions(+), 17 deletions(-)
>
> diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> index 844dc0545c..df902c8667 100644
> --- a/hw/riscv/microchip_pfsoc.c
> +++ b/hw/riscv/microchip_pfsoc.c
> @@ -578,29 +578,45 @@ static void 
> microchip_icicle_kit_machine_init(MachineState *machine)
>  }
>
>  /*
> - * We follow the following table to select which payload we execute.
> + * We follow the following table to select which firmware we use.
>   *
> - *  -bios |-kernel | payload
> - * ---++
> - *  N |  N | HSS
> - *  Y | don't care | HSS
> - *  N |  Y | kernel
> - *
> - * This ensures backwards compatibility with how we used to expose -bios
> - * to users but allows them to run through direct kernel booting as well.
> + * -bios | -kernel| firmware
> + * --++
> + * none  |  N | error
> + * none  |  Y | kernel
> + * NULL, default |  N | BIOS_FILENAME
> + * NULL, default |  Y | RISCV64_BIOS_BIN
> + * other | don't care | other
>   */
> +if (machine->firmware && !strcmp(machine->firmware, "none")) {
> +if (!machine->kernel_filename) {
> +error_report("for -bios none, a kernel is required");
> +exit(1);
> +}
>
> -if (machine->kernel_filename) {
> -firmware_name = RISCV64_BIOS_BIN;
> -firmware_load_addr = memmap[MICROCHIP_PFSOC_DRAM_LO].base;
> +firmware_name = NULL;
> +firmware_load_addr = RESET_VECTOR;
> +} else if (!machine->firmware || !strcmp(machine->firmware, "default")) {
> +if (machine->kernel_filename) {
> +firmware_name = RISCV64_BIOS_BIN;
> +firmware_load_addr = memmap[MICROCHIP_PFSOC_DRAM_LO].base;
> +} else {
> +firmware_name = BIOS_FILENAME;
> +firmware_load_addr = RESET_VECTOR;
> +}
>  } else {
> -firmware_name = BIOS_FILENAME;
> +firmware_name = machine->firmware;
>  firmware_load_addr = RESET_VECTOR;
>  }
>
> -/* Load the firmware */
> -firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
> - &firmware_load_addr, 
> NULL);
> +/* Load the firmware if necessary */
> +if (firmware_name) {
> +const char *filename = riscv_find_firmware(firmware_name, NULL);
> +firmware_end_addr = riscv_load_firmware(filename, 
> &firmware_load_addr,
> +NULL);
> +} else {
> +firmware_end_addr = firmware_load_addr;
> +}
>
>  riscv_boot_info_init(&boot_info, &s->soc.u_cpus);
>  if (machine->kernel_filename) {
> @@ -638,8 +654,15 @@ static void 
> microchip_icicle_kit_machine_init(MachineState *machine)
>  fdt_load_addr = 0;
>  }
>
> +hwaddr start_addr;
> +if (firmware_name) {
> +start_addr = firmware_load_addr;
> +} else {
> +start_addr = kernel_entry;
> +}
> +
>  /* Load the reset vector */
> -riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, 
> firmware_load_addr,
> +riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, start_addr,
>memmap[MICROCHIP_PFSOC_ENVM_DATA].base,
>memmap[MICROCHIP_PFSOC_ENVM_DATA].size,
>kernel_entry, fdt_load_addr);
> --
> 2.43.0
>



Re: [PATCH 2/6] hw/ppc: Trigger Fadump boot if fadump is registered

2025-03-05 Thread Aditya Gupta



On 04/03/25 14:51, Harsh Prateek Bora wrote:



On 2/17/25 12:47, Aditya Gupta wrote:

According to PAPR:

 R1–7.3.30–3. When the platform receives an ibm,os-term RTAS 
call, or

 on a system reset without an ibm,nmi-interlock RTAS call, if the
 platform has a dump structure registered through the
 ibm,configure-kernel-dump call, the platform must process each
 registered kernel dump section as required and, when available,
 present the dump structure information to the operating system
 through the “ibm,kernel-dump” property, updated with status for 
each

 dump section, until the dump has been invalidated through the
 ibm,configure-kernel-dump RTAS call.

If Fadump has been registered, trigger an Fadump boot (memory preserving
boot), if QEMU recieves a 'ibm,os-term' rtas call.

Implementing the fadump boot as:
 * pause all vcpus (will save registers later)
 * preserve memory regions specified by fadump


Although mentioned later, but needs to call out here as not implemented
in this patch. Ideally, all the prep work patches should be introduced
earlier before enabling the trigger.

Got it, will try rearranging the code. Though with current code, the 
trigger won't be called as fadump will not get registered (as of this 
patch the rtas call was not exposed to the kernel, this will likely 
change in v2).

 * do a memory preserving reboot (GUEST_RESET in QEMU doesn't clear
   the memory)

Memory regions registered by fadump will be handled in a later patch.

Signed-off-by: Aditya Gupta 
---
  hw/ppc/spapr_rtas.c | 42 ++
  1 file changed, 42 insertions(+)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index eebdf13b1552..01c82375f03d 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -342,6 +342,43 @@ static void 
rtas_ibm_set_system_parameter(PowerPCCPU *cpu,

  }
    struct fadump_metadata fadump_metadata;
+bool is_next_boot_fadump;
+
+static void trigger_fadump_boot(target_ulong spapr_retcode)
+{
+    /*
+ * In PowerNV, SBE stops all clocks for cores, do similar to it
+ * QEMU's nearest equivalent is 'pause_all_vcpus'
+ * See 'stopClocksS0' in SBE source code for more info on SBE part
+ */
+    pause_all_vcpus();
+
+    if (true /* TODO: Preserve memory registered for fadump */) {
+    /* Failed to preserve the registered memory regions */


Instead of this, it is better to introduce the dummy stub here now 
which can be populated in a later patch. That also helps in avoiding 
code changes in this hunk in future patch.


For eg:

static bool fadump_preserved_mem(void)
{
    return false; /* TBD */
}

...

if (!fadump_preserve_mem()) {
 ...
}


Thanks, makes sense. I will do it this way.


Thanks,

- Aditya Gupta




+    rtas_st(spapr_retcode, 0, RTAS_OUT_HW_ERROR);
+
+    /* Cause a reboot */
+    qemu_system_guest_panicked(NULL);
+    return;
+    }
+
+    /* Mark next boot as fadump boot */
+    is_next_boot_fadump = true;
+
+    /* Reset fadump_registered for next boot */
+    fadump_metadata.fadump_registered = false;
+    fadump_metadata.fadump_dump_active = true;
+
+    /* Then do a guest reset */
+    /*
+ * Requirement:
+ * This guest reset should not clear the memory (which is
+ * the case when this is merged)
+ */
+    qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+
+    rtas_st(spapr_retcode, 0, RTAS_OUT_SUCCESS);
+}
    /* Papr Section 7.4.9 ibm,configure-kernel-dump RTAS call */
  static __attribute((unused)) void 
rtas_configure_kernel_dump(PowerPCCPU *cpu,

@@ -449,6 +486,11 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu,
  target_ulong msgaddr = rtas_ld(args, 0);
  char msg[512];
  +    if (fadump_metadata.fadump_registered) {
+    /* If fadump boot works, control won't come back here */
+    return trigger_fadump_boot(rets);
+    }
+
  cpu_physical_memory_read(msgaddr, msg, sizeof(msg) - 1);
  msg[sizeof(msg) - 1] = 0;




Re: [PATCH v2 5/6] hw/riscv: Configurable MPFS CLINT timebase freq

2025-03-05 Thread Alistair Francis
On Tue, Feb 25, 2025 at 10:55 AM Sebastian Huber
 wrote:
>
> This property enables the setting of the CLINT timebase frequency
> through the command line, for example:
>
>   -machine microchip-icicle-kit,clint-timebase-frequency=1000
>
> Signed-off-by: Sebastian Huber 
> Reviewed-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/microchip_pfsoc.c | 49 +++---
>  include/hw/riscv/microchip_pfsoc.h |  1 +
>  2 files changed, 46 insertions(+), 4 deletions(-)
>
> diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> index df902c8667..9068eed780 100644
> --- a/hw/riscv/microchip_pfsoc.c
> +++ b/hw/riscv/microchip_pfsoc.c
> @@ -39,6 +39,7 @@
>  #include "qemu/units.h"
>  #include "qemu/cutils.h"
>  #include "qapi/error.h"
> +#include "qapi/visitor.h"
>  #include "hw/boards.h"
>  #include "hw/loader.h"
>  #include "hw/sysbus.h"
> @@ -61,9 +62,6 @@
>  #define BIOS_FILENAME   "hss.bin"
>  #define RESET_VECTOR0x2022
>
> -/* CLINT timebase frequency */
> -#define CLINT_TIMEBASE_FREQ 100
> -
>  /* GEM version */
>  #define GEM_REVISION0x0107010c
>
> @@ -193,6 +191,7 @@ static void microchip_pfsoc_soc_instance_init(Object *obj)
>  static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
>  {
>  MachineState *ms = MACHINE(qdev_get_machine());
> +MicrochipIcicleKitState *iks = MICROCHIP_ICICLE_KIT_MACHINE(ms);
>  MicrochipPFSoCState *s = MICROCHIP_PFSOC(dev);
>  const MemMapEntry *memmap = microchip_pfsoc_memmap;
>  MemoryRegion *system_memory = get_system_memory();
> @@ -253,7 +252,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, 
> Error **errp)
>  memmap[MICROCHIP_PFSOC_CLINT].base + RISCV_ACLINT_SWI_SIZE,
>  RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, ms->smp.cpus,
>  RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
> -CLINT_TIMEBASE_FREQ, false);
> +iks->clint_timebase_freq, false);
>
>  /* L2 cache controller */
>  create_unimplemented_device("microchip.pfsoc.l2cc",
> @@ -669,6 +668,40 @@ static void 
> microchip_icicle_kit_machine_init(MachineState *machine)
>  }
>  }
>
> +static void microchip_icicle_kit_set_clint_timebase_freq(Object *obj,
> + Visitor *v,
> + const char *name,
> + void *opaque,
> + Error **errp)
> +{
> +MicrochipIcicleKitState *s = MICROCHIP_ICICLE_KIT_MACHINE(obj);
> +uint32_t value;
> +
> +if (!visit_type_uint32(v, name, &value, errp)) {
> +return;
> +}
> +
> +s->clint_timebase_freq = value;
> +}
> +
> +static void microchip_icicle_kit_get_clint_timebase_freq(Object *obj,
> + Visitor *v,
> + const char *name,
> + void *opaque,
> + Error **errp)
> +{
> +MicrochipIcicleKitState *s = MICROCHIP_ICICLE_KIT_MACHINE(obj);
> +uint32_t value = s->clint_timebase_freq;
> +
> +visit_type_uint32(v, name, &value, errp);
> +}
> +
> +static void microchip_icicle_kit_machine_instance_init(Object *obj)
> +{
> +MicrochipIcicleKitState *m = MICROCHIP_ICICLE_KIT_MACHINE(obj);
> +m->clint_timebase_freq = 100;
> +}
> +
>  static void microchip_icicle_kit_machine_class_init(ObjectClass *oc, void 
> *data)
>  {
>  MachineClass *mc = MACHINE_CLASS(oc);
> @@ -690,12 +723,20 @@ static void 
> microchip_icicle_kit_machine_class_init(ObjectClass *oc, void *data)
>   * See memory_tests() in mss_ddr.c in the HSS source code.
>   */
>  mc->default_ram_size = 1537 * MiB;
> +
> +object_class_property_add(oc, "clint-timebase-frequency", "uint32_t",
> +  microchip_icicle_kit_get_clint_timebase_freq,
> +  microchip_icicle_kit_set_clint_timebase_freq,
> +  NULL, NULL);
> +object_class_property_set_description(oc, "clint-timebase-frequency",
> +  "Set CLINT timebase frequency in Hz.");
>  }
>
>  static const TypeInfo microchip_icicle_kit_machine_typeinfo = {
>  .name   = MACHINE_TYPE_NAME("microchip-icicle-kit"),
>  .parent = TYPE_MACHINE,
>  .class_init = microchip_icicle_kit_machine_class_init,
> +.instance_init = microchip_icicle_kit_machine_instance_init,
>  .instance_size = sizeof(MicrochipIcicleKitState),
>  };
>
> diff --git a/include/hw/riscv/microchip_pfsoc.h 
> b/include/hw/riscv/microchip_pfsoc.h
> index daef086da6..7ca9b976c1 100644
> --- a/include/hw/riscv/microchip_pfsoc.h
> +++ b/include/hw/riscv/microchip_pfsoc.h
> @@ -67,6 +67,7 @@ typedef struct Microch

Re: [PATCH 04/22] target/riscv: store RISCVCPUDef struct directly in the class

2025-03-05 Thread Alistair Francis
On Fri, Feb 28, 2025 at 8:31 PM Paolo Bonzini  wrote:
>
> Prepare for adding more fields to RISCVCPUDef and reading them in
> riscv_cpu_init: instead of storing the misa_mxl_max field in
> RISCVCPUClass, ensure that there's always a valid RISCVCPUDef struct
> and go through it.
>
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h |  2 +-
>  hw/riscv/boot.c|  2 +-
>  target/riscv/cpu.c | 23 ++-
>  target/riscv/gdbstub.c |  6 +++---
>  target/riscv/kvm/kvm-cpu.c | 21 +
>  target/riscv/machine.c |  6 +++---
>  target/riscv/tcg/tcg-cpu.c | 10 +-
>  target/riscv/translate.c   |  2 +-
>  8 files changed, 41 insertions(+), 31 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 743afeb1655..a038122f80c 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -547,7 +547,7 @@ struct RISCVCPUClass {
>
>  DeviceRealize parent_realize;
>  ResettablePhases parent_phases;
> -RISCVMXL misa_mxl_max;  /* max mxl for this cpu */
> +RISCVCPUDef *def;
>  };
>
>  static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
> diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
> index c309441b7d8..13728e137c4 100644
> --- a/hw/riscv/boot.c
> +++ b/hw/riscv/boot.c
> @@ -37,7 +37,7 @@
>  bool riscv_is_32bit(RISCVHartArrayState *harts)
>  {
>  RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(&harts->harts[0]);
> -return mcc->misa_mxl_max == MXL_RV32;
> +return mcc->def->misa_mxl_max == MXL_RV32;
>  }
>
>  /*
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index a71d806e35f..51acce07752 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -354,7 +354,7 @@ void riscv_cpu_set_misa_ext(CPURISCVState *env, uint32_t 
> ext)
>
>  int riscv_cpu_max_xlen(RISCVCPUClass *mcc)
>  {
> -return 16 << mcc->misa_mxl_max;
> +return 16 << mcc->def->misa_mxl_max;
>  }
>
>  #ifndef CONFIG_USER_ONLY
> @@ -1054,7 +1054,7 @@ static void riscv_cpu_reset_hold(Object *obj, ResetType 
> type)
>  mcc->parent_phases.hold(obj, type);
>  }
>  #ifndef CONFIG_USER_ONLY
> -env->misa_mxl = mcc->misa_mxl_max;
> +env->misa_mxl = mcc->def->misa_mxl_max;
>  env->priv = PRV_M;
>  env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
>  if (env->misa_mxl > MXL_RV32) {
> @@ -1447,7 +1447,7 @@ static void riscv_cpu_init(Object *obj)
>  RISCVCPU *cpu = RISCV_CPU(obj);
>  CPURISCVState *env = &cpu->env;
>
> -env->misa_mxl = mcc->misa_mxl_max;
> +env->misa_mxl = mcc->def->misa_mxl_max;
>
>  #ifndef CONFIG_USER_ONLY
>  qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq,
> @@ -1544,7 +1544,7 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPUClass 
> *mcc)
>  CPUClass *cc = CPU_CLASS(mcc);
>
>  /* Validate that MISA_MXL is set properly. */
> -switch (mcc->misa_mxl_max) {
> +switch (mcc->def->misa_mxl_max) {
>  #ifdef TARGET_RISCV64
>  case MXL_RV64:
>  case MXL_RV128:
> @@ -2957,12 +2957,24 @@ static void riscv_cpu_common_class_init(ObjectClass 
> *c, void *data)
>  device_class_set_props(dc, riscv_cpu_properties);
>  }
>
> +static void riscv_cpu_class_base_init(ObjectClass *c, void *data)
> +{
> +RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
> +RISCVCPUClass *pcc = RISCV_CPU_CLASS(object_class_get_parent(c));
> +
> +if (pcc->def) {
> +mcc->def = g_memdup2(pcc->def, sizeof(*pcc->def));
> +} else {
> +mcc->def = g_new0(RISCVCPUDef, 1);
> +}
> +}
> +
>  static void riscv_cpu_class_init(ObjectClass *c, void *data)
>  {
>  RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
>  const RISCVCPUDef *def = data;
>
> -mcc->misa_mxl_max = def->misa_mxl_max;
> +mcc->def->misa_mxl_max = def->misa_mxl_max;
>  riscv_cpu_validate_misa_mxl(mcc);
>  }
>
> @@ -3113,6 +3125,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>  .abstract = true,
>  .class_size = sizeof(RISCVCPUClass),
>  .class_init = riscv_cpu_common_class_init,
> +.class_base_init = riscv_cpu_class_base_init,
>  },
>  {
>  .name = TYPE_RISCV_DYNAMIC_CPU,
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index 18e88f416af..1934f919c01 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -62,7 +62,7 @@ int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray 
> *mem_buf, int n)
>  return 0;
>  }
>
> -switch (mcc->misa_mxl_max) {
> +switch (mcc->def->misa_mxl_max) {
>  case MXL_RV32:
>  return gdb_get_reg32(mem_buf, tmp);
>  case MXL_RV64:
> @@ -82,7 +82,7 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t 
> *mem_buf, int n)
>  int length = 0;
>  target_ulong tmp;
>
> -switch (mcc->misa_mxl_max) {
> +switch (mcc->def->misa_mxl_max) {
>  case MXL_RV32:
>  tmp = (int32_t)ldl_p(mem_buf);
>  length = 4;
> @@ -359,7 +359,7 @@ void riscv_cpu_regi

Re: [PATCH 05/22] target/riscv: merge riscv_cpu_class_init with the class_base function

2025-03-05 Thread Alistair Francis
On Fri, Feb 28, 2025 at 8:33 PM Paolo Bonzini  wrote:
>
> Since all TYPE_RISCV_CPU subclasses support a class_data of type
> RISCVCPUDef, process it even before calling the .class_init function
> for the subclasses.
>
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 21 ++---
>  1 file changed, 10 insertions(+), 11 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 51acce07752..91dd63edc9f 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -2967,15 +2967,18 @@ static void riscv_cpu_class_base_init(ObjectClass *c, 
> void *data)
>  } else {
>  mcc->def = g_new0(RISCVCPUDef, 1);
>  }
> -}
>
> -static void riscv_cpu_class_init(ObjectClass *c, void *data)
> -{
> -RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
> -const RISCVCPUDef *def = data;
> +if (data) {
> +const RISCVCPUDef *def = data;
> +if (def->misa_mxl_max) {
> +assert(def->misa_mxl_max <= MXL_RV128);
> +mcc->def->misa_mxl_max = def->misa_mxl_max;
> +}
> +}
>
> -mcc->def->misa_mxl_max = def->misa_mxl_max;
> -riscv_cpu_validate_misa_mxl(mcc);
> +if (!object_class_is_abstract(c)) {
> +riscv_cpu_validate_misa_mxl(mcc);
> +}
>  }
>
>  static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str,
> @@ -3075,7 +3078,6 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char 
> *nodename)
>  .name = (type_name),\
>  .parent = TYPE_RISCV_DYNAMIC_CPU,   \
>  .instance_init = (initfn),  \
> -.class_init = riscv_cpu_class_init, \
>  .class_data = (void*) &((const RISCVCPUDef) {   \
>   .misa_mxl_max = (misa_mxl_max_),   \
>  }), \
> @@ -3086,7 +3088,6 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char 
> *nodename)
>  .name = (type_name),\
>  .parent = TYPE_RISCV_VENDOR_CPU,\
>  .instance_init = (initfn),  \
> -.class_init = riscv_cpu_class_init, \
>  .class_data = (void*) &((const RISCVCPUDef) {   \
>   .misa_mxl_max = (misa_mxl_max_),   \
>  }), \
> @@ -3097,7 +3098,6 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char 
> *nodename)
>  .name = (type_name),\
>  .parent = TYPE_RISCV_BARE_CPU,  \
>  .instance_init = (initfn),  \
> -.class_init = riscv_cpu_class_init, \
>  .class_data = (void*) &((const RISCVCPUDef) {   \
>   .misa_mxl_max = (misa_mxl_max_),   \
>  }), \
> @@ -3108,7 +3108,6 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char 
> *nodename)
>  .name = (type_name),\
>  .parent = TYPE_RISCV_BARE_CPU,  \
>  .instance_init = (initfn),  \
> -.class_init = riscv_cpu_class_init, \
>  .class_data = (void*) &((const RISCVCPUDef) {   \
>   .misa_mxl_max = (misa_mxl_max_),   \
>  }), \
> --
> 2.48.1
>
>



Re: [PATCH v2 01/14] arm/cpu: Add sysreg definitions in cpu-sysregs.h

2025-03-05 Thread Richard Henderson

On 3/5/25 08:38, Cornelia Huck wrote:

+++ b/target/arm/cpu-sysregs.h
@@ -0,0 +1,131 @@
+#ifndef ARM_CPU_SYSREGS_H
+#define ARM_CPU_SYSREGS_H
+
+/*
+ * Following is similar to the coprocessor regs encodings, but with an argument
+ * ordering that matches the ARM ARM. We also reuse the various CP_REG_ defines
+ * that actually are the same as the equivalent KVM_REG_ values.
+ */
+#define ENCODE_ID_REG(op0, op1, crn, crm, op2)  \
+(((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
+ ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
+ ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
+ ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
+ ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
+
+typedef enum ARMIDRegisterIdx {
+ID_AA64PFR0_EL1_IDX,
+ID_AA64PFR1_EL1_IDX,
+ID_AA64SMFR0_EL1_IDX,
+ID_AA64DFR0_EL1_IDX,
+ID_AA64DFR1_EL1_IDX,
+ID_AA64ISAR0_EL1_IDX,
+ID_AA64ISAR1_EL1_IDX,
+ID_AA64ISAR2_EL1_IDX,
+ID_AA64MMFR0_EL1_IDX,
+ID_AA64MMFR1_EL1_IDX,
+ID_AA64MMFR2_EL1_IDX,
+ID_AA64MMFR3_EL1_IDX,
+ID_PFR0_EL1_IDX,
+ID_PFR1_EL1_IDX,
+ID_DFR0_EL1_IDX,
+ID_MMFR0_EL1_IDX,
+ID_MMFR1_EL1_IDX,
+ID_MMFR2_EL1_IDX,
+ID_MMFR3_EL1_IDX,
+ID_ISAR0_EL1_IDX,
+ID_ISAR1_EL1_IDX,
+ID_ISAR2_EL1_IDX,
+ID_ISAR3_EL1_IDX,
+ID_ISAR4_EL1_IDX,
+ID_ISAR5_EL1_IDX,
+ID_MMFR4_EL1_IDX,
+ID_ISAR6_EL1_IDX,
+MVFR0_EL1_IDX,
+MVFR1_EL1_IDX,
+MVFR2_EL1_IDX,
+ID_PFR2_EL1_IDX,
+ID_DFR1_EL1_IDX,
+ID_MMFR5_EL1_IDX,
+ID_AA64ZFR0_EL1_IDX,
+CTR_EL0_IDX,
+NUM_ID_IDX,
+} ARMIDRegisterIdx;
+
+typedef enum ARMSysRegs {
+SYS_ID_AA64PFR0_EL1 = ENCODE_ID_REG(3, 0, 0, 4, 0),
+SYS_ID_AA64PFR1_EL1 = ENCODE_ID_REG(3, 0, 0, 4, 1),
+SYS_ID_AA64SMFR0_EL1 = ENCODE_ID_REG(3, 0, 0, 4, 5),
+SYS_ID_AA64DFR0_EL1 = ENCODE_ID_REG(3, 0, 0, 5, 0),
+SYS_ID_AA64DFR1_EL1 = ENCODE_ID_REG(3, 0, 0, 5, 1),
+SYS_ID_AA64ISAR0_EL1 = ENCODE_ID_REG(3, 0, 0, 6, 0),
+SYS_ID_AA64ISAR1_EL1 = ENCODE_ID_REG(3, 0, 0, 6, 1),
+SYS_ID_AA64ISAR2_EL1 = ENCODE_ID_REG(3, 0, 0, 6, 2),
+SYS_ID_AA64MMFR0_EL1 = ENCODE_ID_REG(3, 0, 0, 7, 0),
+SYS_ID_AA64MMFR1_EL1 = ENCODE_ID_REG(3, 0, 0, 7, 1),
+SYS_ID_AA64MMFR2_EL1 = ENCODE_ID_REG(3, 0, 0, 7, 2),
+SYS_ID_AA64MMFR3_EL1 = ENCODE_ID_REG(3, 0, 0, 7, 3),
+SYS_ID_PFR0_EL1 = ENCODE_ID_REG(3, 0, 0, 1, 0),
+SYS_ID_PFR1_EL1 = ENCODE_ID_REG(3, 0, 0, 1, 1),
+SYS_ID_DFR0_EL1 = ENCODE_ID_REG(3, 0, 0, 1, 2),
+SYS_ID_MMFR0_EL1 = ENCODE_ID_REG(3, 0, 0, 1, 4),
+SYS_ID_MMFR1_EL1 = ENCODE_ID_REG(3, 0, 0, 1, 5),
+SYS_ID_MMFR2_EL1 = ENCODE_ID_REG(3, 0, 0, 1, 6),
+SYS_ID_MMFR3_EL1 = ENCODE_ID_REG(3, 0, 0, 1, 7),
+SYS_ID_ISAR0_EL1 = ENCODE_ID_REG(3, 0, 0, 2, 0),
+SYS_ID_ISAR1_EL1 = ENCODE_ID_REG(3, 0, 0, 2, 1),
+SYS_ID_ISAR2_EL1 = ENCODE_ID_REG(3, 0, 0, 2, 2),
+SYS_ID_ISAR3_EL1 = ENCODE_ID_REG(3, 0, 0, 2, 3),
+SYS_ID_ISAR4_EL1 = ENCODE_ID_REG(3, 0, 0, 2, 4),
+SYS_ID_ISAR5_EL1 = ENCODE_ID_REG(3, 0, 0, 2, 5),
+SYS_ID_MMFR4_EL1 = ENCODE_ID_REG(3, 0, 0, 2, 6),
+SYS_ID_ISAR6_EL1 = ENCODE_ID_REG(3, 0, 0, 2, 7),
+SYS_MVFR0_EL1 = ENCODE_ID_REG(3, 0, 0, 3, 0),
+SYS_MVFR1_EL1 = ENCODE_ID_REG(3, 0, 0, 3, 1),
+SYS_MVFR2_EL1 = ENCODE_ID_REG(3, 0, 0, 3, 2),
+SYS_ID_PFR2_EL1 = ENCODE_ID_REG(3, 0, 0, 3, 4),
+SYS_ID_DFR1_EL1 = ENCODE_ID_REG(3, 0, 0, 3, 5),
+SYS_ID_MMFR5_EL1 = ENCODE_ID_REG(3, 0, 0, 3, 6),
+SYS_ID_AA64ZFR0_EL1 = ENCODE_ID_REG(3, 0, 0, 4, 4),
+SYS_CTR_EL0 = ENCODE_ID_REG(3, 3, 0, 0, 1),
+} ARMSysRegs;
+
+static const uint32_t id_register_sysreg[NUM_ID_IDX] = {
+[ID_AA64PFR0_EL1_IDX] = SYS_ID_AA64PFR0_EL1,
+[ID_AA64PFR1_EL1_IDX] = SYS_ID_AA64PFR1_EL1,
+[ID_AA64SMFR0_EL1_IDX] = SYS_ID_AA64SMFR0_EL1,
+[ID_AA64DFR0_EL1_IDX] = SYS_ID_AA64DFR0_EL1,
+[ID_AA64DFR1_EL1_IDX] = SYS_ID_AA64DFR1_EL1,
+[ID_AA64ISAR0_EL1_IDX] = SYS_ID_AA64ISAR0_EL1,
+[ID_AA64ISAR1_EL1_IDX] = SYS_ID_AA64ISAR1_EL1,
+[ID_AA64ISAR2_EL1_IDX] = SYS_ID_AA64ISAR2_EL1,
+[ID_AA64MMFR0_EL1_IDX] = SYS_ID_AA64MMFR0_EL1,
+[ID_AA64MMFR1_EL1_IDX] = SYS_ID_AA64MMFR1_EL1,
+[ID_AA64MMFR2_EL1_IDX] = SYS_ID_AA64MMFR2_EL1,
+[ID_AA64MMFR3_EL1_IDX] = SYS_ID_AA64MMFR3_EL1,
+[ID_PFR0_EL1_IDX] = SYS_ID_PFR0_EL1,
+[ID_PFR1_EL1_IDX] = SYS_ID_PFR1_EL1,
+[ID_DFR0_EL1_IDX] = SYS_ID_DFR0_EL1,
+[ID_MMFR0_EL1_IDX] = SYS_ID_MMFR0_EL1,
+[ID_MMFR1_EL1_IDX] = SYS_ID_MMFR1_EL1,
+[ID_MMFR2_EL1_IDX] = SYS_ID_MMFR2_EL1,
+[ID_MMFR3_EL1_IDX] = SYS_ID_MMFR3_EL1,
+[ID_ISAR0_EL1_IDX] = SYS_ID_ISAR0_EL1,
+[ID_ISAR1_EL1_IDX] = SYS_ID_ISAR1_EL1,
+[ID_ISAR2_EL1_IDX] = SYS_ID_ISAR2_EL1,
+[ID_ISAR3_EL1_IDX] = SYS_ID_ISAR3_EL1,
+[ID_ISAR4_EL1_IDX] = SYS_ID_ISAR4_EL1,
+[ID_ISAR5_EL1_IDX] = SYS_ID_ISAR5_EL1,
+[ID_MMFR4_EL1_IDX] = SYS_ID_MMFR4_EL1,
+[ID_ISAR6_EL1_IDX] = SYS_ID_ISAR6_EL1,
+[MVFR0_EL1_IDX] = SYS_MVFR0_EL1,
+[MVFR1_EL1_IDX] = SYS_MVFR1_EL1,

Re: [RFC PATCH 04/18] qemu: Introduce 'qemu/legacy_binary_info.h'

2025-03-05 Thread Richard Henderson

On 3/5/25 07:39, Philippe Mathieu-Daudé wrote:

+void legacy_binary_info_init(const char *argv0)
+{
+g_auto(GStrv) tokens = g_strsplit(argv0, G_DIR_SEPARATOR_S, -1);
+unsigned count = 0;
+const char *binary_name;
+
+while (tokens[count]) {
+count++;
+}
+assert(count > 0);
+binary_name = tokens[count - 1];


This is g_path_get_basename().


+
+for (size_t i = 0; i < ARRAY_SIZE(legacy_binary_infos); i++) {
+if (!strcmp(legacy_binary_infos[i].binary_name, binary_name)) {
+current_index = i;
+return;
+}
+}
+fprintf(stderr, "Missing legacy info for '%s' binary.\n", binary_name);
+abort();
+}


I'm with Paolo that this should not abort here; Error is better.
Even if the caller supplies error_fatal.

When testing for errors before and after a patch, I often rename
the binary, e.g. qemu-system-aarch64-good / qemu-system-aarch64-bad.
Leaving it in the same build directory is required in order to let
it find the uninstalled rom images.

Is there a way we can preserve something akin to this?
Do we need to add the -target command-line option that Pierrick mooted?


r~



Re: [PATCH 3/7] target/riscv: assert argument to set_satp_mode_max_supported is valid

2025-03-05 Thread Alistair Francis
On Wed, Feb 19, 2025 at 2:58 AM Paolo Bonzini  wrote:
>
> Check that the argument to set_satp_mode_max_supported is valid for
> the MXL value of the CPU.  It would be a bug in the CPU definition
> if it weren't.
>
> In fact, there is such a bug in riscv_bare_cpu_init(): not just
> SV32 is not a valid VM mode for 64-bit CPUs, SV64 is not a
> valid VM mode at all, not yet at least.
>
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index cca24b9f1fc..7950b6447f8 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -442,6 +442,8 @@ static void set_satp_mode_max_supported(RISCVCPU *cpu,
>  cpu->cfg.satp_mode.supported |= (1 << i);
>  }
>  }
> +
> +assert(cpu->cfg.satp_mode.supported & (1 << satp_mode));
>  }
>
>  /* Set the satp mode to the max supported */
> @@ -1502,7 +1504,9 @@ static void riscv_bare_cpu_init(Object *obj)
>   * satp_mode manually (see set_satp_mode_default()).
>   */
>  #ifndef CONFIG_USER_ONLY
> -set_satp_mode_max_supported(cpu, VM_1_10_SV64);
> +set_satp_mode_max_supported(RISCV_CPU(obj),
> +riscv_cpu_mxl(&RISCV_CPU(obj)->env) == MXL_RV32 ?
> +VM_1_10_SV32 : VM_1_10_SV57);
>  #endif
>  }
>
> --
> 2.48.1
>
>



Re: [PATCH v2 0/6] Improve Microchip Polarfire SoC customization

2025-03-05 Thread Alistair Francis
On Tue, Feb 25, 2025 at 10:55 AM Sebastian Huber
 wrote:
>
> Booting the microchip-icicle-kit machine using the latest PolarFire SoC
> Hart Software Services (HSS) no longer works since Qemu lacks support
> for several registers (clocks, DRAM controller). Also reading from the
> SDCard does not work currently.
>
> In order to allow tests runs for real-time kernels such as RTEMS and
> Zephyr, improve the boot customization. This patch set enables a direct
> run of kernel executables, for example:
>
> qemu-system-riscv64 -no-reboot -nographic \
>   -serial null -serial mon:stdio \
>   -smp 2 \
>   -bios none \
>   -machine microchip-icicle-kit,clint-timebase-frequency=1000 \
>   -kernel rtos.elf
>
> v2:
>
> * Add documentation update.
>
> * In patch 3, warn if no device tree is specified.
>
> * In patch 4, use riscv_find_firmware() to locate the firmware shipped with 
> Qemu.
>
> Sebastian Huber (6):
>   hw/misc: Add MPFS system reset support
>   hw/riscv: More flexible FDT placement for MPFS
>   hw/riscv: Make FDT optional for MPFS
>   hw/riscv: Allow direct start of kernel for MPFS
>   hw/riscv: Configurable MPFS CLINT timebase freq
>   hw/riscv: microchip_pfsoc: Rework documentation

Thanks!

Applied to riscv-to-apply.next

Alistair

>
>  docs/system/riscv/microchip-icicle-kit.rst | 124 ++---
>  hw/misc/mchp_pfsoc_sysreg.c|   7 +
>  hw/riscv/microchip_pfsoc.c | 151 +++--
>  include/hw/riscv/microchip_pfsoc.h |   1 +
>  4 files changed, 162 insertions(+), 121 deletions(-)
>
> --
> 2.43.0
>



Re: [PATCH 4/7] target/riscv: cpu: store max SATP mode as a single integer

2025-03-05 Thread Alistair Francis
On Wed, Feb 19, 2025 at 3:00 AM Paolo Bonzini  wrote:
>
> The maximum available SATP mode implies all the shorter virtual address sizes.
> Store it in RISCVCPUConfig and avoid recomputing it via 
> satp_mode_max_from_map.
>
> Signed-off-by: Paolo Bonzini 

This fails to build on the latest riscv-to-apply.next
(https://github.com/alistair23/qemu/tree/riscv-to-apply.next)

../target/riscv/cpu.c: In function ‘riscv_cpu_init’:
../target/riscv/cpu.c:1481:13: error: ‘RISCVCPUConfig’ has no member
named ‘max_satp_mode’
 1481 | cpu->cfg.max_satp_mode = -1;
  | ^

Do you mind rebasing?

Alistair

> ---
>  target/riscv/cpu_cfg.h |  1 +
>  target/riscv/cpu.c | 11 +--
>  target/riscv/tcg/tcg-cpu.c |  3 ++-
>  3 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index b410b1e6038..28d8de978fa 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -192,6 +192,7 @@ struct RISCVCPUConfig {
>  bool short_isa_string;
>
>  #ifndef CONFIG_USER_ONLY
> +int8_t max_satp_mode;
>  RISCVSATPMap satp_mode;
>  #endif
>  };
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7950b6447f8..2d06543217a 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -444,6 +444,7 @@ static void set_satp_mode_max_supported(RISCVCPU *cpu,
>  }
>
>  assert(cpu->cfg.satp_mode.supported & (1 << satp_mode));
> +cpu->cfg.max_satp_mode = satp_mode;
>  }
>
>  /* Set the satp mode to the max supported */
> @@ -1177,16 +1178,13 @@ static void riscv_cpu_disas_set_info(CPUState *s, 
> disassemble_info *info)
>  static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
>  {
>  bool rv32 = riscv_cpu_is_32bit(cpu);
> -uint8_t satp_mode_map_max, satp_mode_supported_max;
> +uint8_t satp_mode_map_max;
>
>  /* The CPU wants the OS to decide which satp mode to use */
>  if (cpu->cfg.satp_mode.supported == 0) {
>  return;
>  }
>
> -satp_mode_supported_max =
> -satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
> -
>  if (cpu->cfg.satp_mode.map == 0) {
>  if (cpu->cfg.satp_mode.init == 0) {
>  /* If unset by the user, we fallback to the default satp mode. */
> @@ -1215,10 +1213,10 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU 
> *cpu, Error **errp)
>  satp_mode_map_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
>
>  /* Make sure the user asked for a supported configuration (HW and qemu) 
> */
> -if (satp_mode_map_max > satp_mode_supported_max) {
> +if (satp_mode_map_max > cpu->cfg.max_satp_mode) {
>  error_setg(errp, "satp_mode %s is higher than hw max capability %s",
> satp_mode_str(satp_mode_map_max, rv32),
> -   satp_mode_str(satp_mode_supported_max, rv32));
> +   satp_mode_str(cpu->cfg.max_satp_mode, rv32));
>  return;
>  }
>
> @@ -1477,6 +1475,7 @@ static void riscv_cpu_init(Object *obj)
>  cpu->cfg.cbom_blocksize = 64;
>  cpu->cfg.cbop_blocksize = 64;
>  cpu->cfg.cboz_blocksize = 64;
> +cpu->cfg.max_satp_mode = -1;
>  cpu->env.vext_ver = VEXT_VERSION_1_00_0;
>  }
>
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 0a137281de1..a9f59a67e00 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -693,8 +693,9 @@ static bool riscv_cpu_validate_profile_satp(RISCVCPU *cpu,
>  RISCVCPUProfile *profile,
>  bool send_warn)
>  {
> -int satp_max = satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
> +int satp_max = cpu->cfg.max_satp_mode;
>
> +assert(satp_max >= 0);
>  if (profile->satp_mode > satp_max) {
>  if (send_warn) {
>  bool is_32bit = riscv_cpu_is_32bit(cpu);
> --
> 2.48.1
>
>



Re: [PATCH qemu] target/riscv: Only check ext_zca for 16-bit aligned PC.

2025-03-05 Thread Alistair Francis
On Tue, Feb 25, 2025 at 11:49 AM ~yuming  wrote:
>
> From: Yu-Ming Chang 
>
> Since C always implies Zca, Zca is always enabled when 16-bit
> insructions are supported. we can only check ext_zca to allow
> 16-bit aligned PC addresses.
>
> Signed-off-by: Yu-Ming Chang 

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 5 ++---
>  target/riscv/op_helper.c| 4 ++--
>  target/riscv/translate.c| 2 +-
>  3 files changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
> b/target/riscv/insn_trans/trans_rvi.c.inc
> index 96c218a9d7..e5965201a7 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -106,7 +106,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>  tcg_gen_ext32s_tl(target_pc, target_pc);
>  }
>
> -if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
> +if (!ctx->cfg_ptr->ext_zca) {
>  TCGv t0 = tcg_temp_new();
>
>  misaligned = gen_new_label();
> @@ -236,8 +236,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, 
> TCGCond cond)
>
>  gen_set_label(l); /* branch taken */
>
> -if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca &&
> -(a->imm & 0x3)) {
> +if (!ctx->cfg_ptr->ext_zca && (a->imm & 0x3)) {
>  /* misaligned */
>  TCGv target_pc = tcg_temp_new();
>  gen_pc_plus_diff(target_pc, ctx, a->imm);
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index ce1256f439..68882136d7 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -276,7 +276,7 @@ target_ulong helper_sret(CPURISCVState *env)
>  }
>
>  target_ulong retpc = env->sepc;
> -if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) {
> +if (!env_archcpu(env)->cfg.ext_zca && (retpc & 0x3)) {
>  riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
>  }
>
> @@ -349,7 +349,7 @@ static void check_ret_from_m_mode(CPURISCVState *env, 
> target_ulong retpc,
>  riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
>  }
>
> -if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) {
> +if (!env_archcpu(env)->cfg.ext_zca && (retpc & 0x3)) {
>  riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
>  }
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 698b74f7a8..34eeed50be 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -566,7 +566,7 @@ static void gen_jal(DisasContext *ctx, int rd, 
> target_ulong imm)
>  TCGv succ_pc = dest_gpr(ctx, rd);
>
>  /* check misaligned: */
> -if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
> +if (!ctx->cfg_ptr->ext_zca) {
>  if ((imm & 0x3) != 0) {
>  TCGv target_pc = tcg_temp_new();
>  gen_pc_plus_diff(target_pc, ctx, imm);
> --
> 2.45.3
>



Re: [PATCH 1/7] hw/riscv: acpi: only create RHCT MMU entry for supported types

2025-03-05 Thread Alistair Francis
On Wed, Feb 19, 2025 at 2:58 AM Paolo Bonzini  wrote:
>
> Do not create the RHCT MMU type entry for RV32 CPUs, since it
> only has definitions for SV39/SV48/SV57.  Likewise, check that

I don't have access to the spec, so I'm going to take your word on this

> satp_mode_max_from_map() will actually return a valid value, skipping
> the MMU type entry if all MMU types were disabled on the command line.
>
> Signed-off-by: Paolo Bonzini 

Acked-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/virt-acpi-build.c | 9 ++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
> index 1ad68005085..2b374ebacbf 100644
> --- a/hw/riscv/virt-acpi-build.c
> +++ b/hw/riscv/virt-acpi-build.c
> @@ -262,6 +262,7 @@ static void build_rhct(GArray *table_data,
>  RISCVCPU *cpu = &s->soc[0].harts[0];
>  uint32_t mmu_offset = 0;
>  uint8_t satp_mode_max;
> +bool rv32 = riscv_cpu_is_32bit(cpu);
>  g_autofree char *isa = NULL;
>
>  AcpiTable table = { .sig = "RHCT", .rev = 1, .oem_id = s->oem_id,
> @@ -281,7 +282,8 @@ static void build_rhct(GArray *table_data,
>  num_rhct_nodes++;
>  }
>
> -if (cpu->cfg.satp_mode.supported != 0) {
> +if (!rv32 && cpu->cfg.satp_mode.supported != 0 &&
> +(cpu->cfg.satp_mode.map & ~(1 << VM_1_10_MBARE))) {
>  num_rhct_nodes++;
>  }
>
> @@ -341,7 +343,8 @@ static void build_rhct(GArray *table_data,
>  }
>
>  /* MMU node structure */
> -if (cpu->cfg.satp_mode.supported != 0) {
> +if (!rv32 && cpu->cfg.satp_mode.supported != 0 &&
> +(cpu->cfg.satp_mode.map & ~(1 << VM_1_10_MBARE))) {
>  satp_mode_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
>  mmu_offset = table_data->len - table.table_offset;
>  build_append_int_noprefix(table_data, 2, 2);/* Type */
> @@ -356,7 +359,7 @@ static void build_rhct(GArray *table_data,
>  } else if (satp_mode_max == VM_1_10_SV39) {
>  build_append_int_noprefix(table_data, 0, 1);/* Sv39 */
>  } else {
> -assert(1);
> +g_assert_not_reached();
>  }
>  }
>
> --
> 2.48.1
>
>



Re: [RFC PATCH 02/18] hw/vfio/common: Get target page size using runtime helpers

2025-03-05 Thread Richard Henderson

On 3/5/25 07:39, Philippe Mathieu-Daudé wrote:

Prefer runtime helpers to get target page size.

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/vfio/common.c | 9 ++---
  1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 7a4010ef4ee..d4c9e59173d 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -30,6 +30,7 @@
  #include "exec/address-spaces.h"
  #include "exec/memory.h"
  #include "exec/ram_addr.h"
+#include "exec/target_page.h"
  #include "hw/hw.h"
  #include "qemu/error-report.h"
  #include "qemu/main-loop.h"
@@ -395,10 +396,12 @@ static void 
vfio_register_ram_discard_listener(VFIOContainerBase *bcontainer,
  VFIORamDiscardListener *vrdl;
  
  /* Ignore some corner cases not relevant in practice. */

-g_assert(QEMU_IS_ALIGNED(section->offset_within_region, TARGET_PAGE_SIZE));
+g_assert(QEMU_IS_ALIGNED(section->offset_within_region,
+ qemu_target_page_size()));
  g_assert(QEMU_IS_ALIGNED(section->offset_within_address_space,
- TARGET_PAGE_SIZE));
-g_assert(QEMU_IS_ALIGNED(int128_get64(section->size), TARGET_PAGE_SIZE));
+ qemu_target_page_size()));
+g_assert(QEMU_IS_ALIGNED(int128_get64(section->size),
+ qemu_target_page_size()));


It would be worth storing this in a local variable, I think.

Reviewed-by: Richard Henderson 


r~



Re: [RFC PATCH 03/18] include: Poison TARGET_PHYS_ADDR_SPACE_BITS definition

2025-03-05 Thread Richard Henderson

On 3/5/25 07:39, Philippe Mathieu-Daudé wrote:

Ensure common code never use this target specific definition.

Signed-off-by: Philippe Mathieu-Daudé 
---
  include/exec/poison.h | 1 +
  1 file changed, 1 insertion(+)

diff --git a/include/exec/poison.h b/include/exec/poison.h
index 0c4ad04eb97..0ab7f0da1c7 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -47,6 +47,7 @@
  #pragma GCC poison TARGET_PAGE_MASK
  #pragma GCC poison TARGET_PAGE_BITS
  #pragma GCC poison TARGET_PAGE_ALIGN
+#pragma GCC poison TARGET_PHYS_ADDR_SPACE_BITS
  
  #pragma GCC poison CPU_INTERRUPT_HARD

  #pragma GCC poison CPU_INTERRUPT_EXITTB


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 02/14] arm/kvm: add accessors for storing host features into idregs

2025-03-05 Thread Richard Henderson

On 3/5/25 08:38, Cornelia Huck wrote:

Signed-off-by: Cornelia Huck 
---
  target/arm/cpu-sysregs.h |  3 +++
  target/arm/cpu64.c   | 25 +
  target/arm/kvm.c | 12 
  3 files changed, 40 insertions(+)

diff --git a/target/arm/cpu-sysregs.h b/target/arm/cpu-sysregs.h
index de09ebae91a5..54a4fadbf0c1 100644
--- a/target/arm/cpu-sysregs.h
+++ b/target/arm/cpu-sysregs.h
@@ -128,4 +128,7 @@ static const uint32_t id_register_sysreg[NUM_ID_IDX] = {
  [CTR_EL0_IDX] = SYS_CTR_EL0,
  };
  
+int get_sysreg_idx(ARMSysRegs sysreg);

+uint64_t idregs_sysreg_to_kvm_reg(ARMSysRegs sysreg);
+
  #endif /* ARM_CPU_SYSREGS_H */
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 8188ede5cc8a..9ae78253cb34 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -736,6 +736,31 @@ static void aarch64_a53_initfn(Object *obj)
  define_cortex_a72_a57_a53_cp_reginfo(cpu);
  }
  
+#ifdef CONFIG_KVM

+
+int get_sysreg_idx(ARMSysRegs sysreg)
+{
+int i;
+
+for (i = 0; i < NUM_ID_IDX; i++) {
+if (id_register_sysreg[i] == sysreg) {
+return i;
+}
+}
+return -1;
+}
+
+uint64_t idregs_sysreg_to_kvm_reg(ARMSysRegs sysreg)
+{
+return ARM64_SYS_REG((sysreg & CP_REG_ARM64_SYSREG_OP0_MASK) >> 
CP_REG_ARM64_SYSREG_OP0_SHIFT,
+ (sysreg & CP_REG_ARM64_SYSREG_OP1_MASK) >> 
CP_REG_ARM64_SYSREG_OP1_SHIFT,
+ (sysreg & CP_REG_ARM64_SYSREG_CRN_MASK) >> 
CP_REG_ARM64_SYSREG_CRN_SHIFT,
+ (sysreg & CP_REG_ARM64_SYSREG_CRM_MASK) >> 
CP_REG_ARM64_SYSREG_CRM_SHIFT,
+ (sysreg & CP_REG_ARM64_SYSREG_OP2_MASK) >> 
CP_REG_ARM64_SYSREG_OP2_SHIFT);
+}
+
+#endif


Why are these here, with an ifdef, instead of in kvm.c?

Rather than a loop over an array, you could do

#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \
case SYS_##NAME: return NAME##_IDX;

int get_sysreg_idx(ARMSysRegs sysreg)
{
switch (sysreg) {
#include "cpu-sysregs.h.inc"
}
g_assert_not_reached();
}

#undef DEF


diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index da30bdbb2349..2381c87e4ba1 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -246,6 +246,18 @@ static bool kvm_arm_pauth_supported(void)
  kvm_check_extension(kvm_state, KVM_CAP_ARM_PTRAUTH_GENERIC));
  }
  
+/* read a sysreg value and store it in the idregs */

+static int get_host_cpu_reg(int fd, ARMHostCPUFeatures *ahcf, ARMIDRegisterIdx 
index)
+{
+uint64_t *reg;
+int ret;
+
+reg = &ahcf->isar.idregs[index];
+ret = read_sys_reg64(fd, reg,
+ idregs_sysreg_to_kvm_reg(id_register_sysreg[index]));
+return ret;
+}


Surely this patch doesn't compile by itself,
because this will Werror for the unused function.


r~



Re: [PATCH 39/57] qapi/source: allow multi-line QAPISourceInfo advancing

2025-03-05 Thread John Snow
On Wed, Mar 5, 2025 at 5:35 AM Markus Armbruster  wrote:

> John Snow  writes:
>
> > This is for the sake of the new rST generator (the "transmogrifier") so
> > we can advance multiple lines on occasion while keeping the
> > generated<-->source mappings accurate.
> >
> > next_line now simply takes an optional n parameter which chooses the
> > number of lines to advance.
> >
> > RFC: Here's the exorbitant detail on why I want this:
> >
> > This is used mainly when converting section syntax in free-form
> > documentation to more traditional rST section header syntax, which
> > does not always line up 1:1 for line counts.
>
> Obvious way to resolve the RFC:
>
>   The next patch will use this when converting ...
>
> >
> > For example:
> >
> > ```
> >  ##
> >  # = Section <-- Info is pointing here, "L1"
> >  #
> >  # Lorem Ipsum
> >  ##
> > ```
> >
> > would be transformed to rST as:
> >
> > ```
> > ===<-- L1
> > Section<-- L1
> > ===<-- L1
> ><-- L2
> > Lorem Ipsum<-- L3
> > ```
>
> Not a demand, just wondering: could we drop our headings syntax and just
> use rST?
>

Yes, once we drop the old qapidoc fully, which I am not sure I can do
before freeze ... So we have some goofy stuff in the meantime.
You suggested before I can rewrite the freeform generator to avoid needing
this; I wrote the freeform generator to be as close to the old one as I
could, but we could kerjiggle it if needed.

... On the other hand, this is a patch for a += n, so... eh.

--js


Re: [PATCH qemu] target/riscv: Only check ext_zca for 16-bit aligned PC.

2025-03-05 Thread Alistair Francis
On Tue, Feb 25, 2025 at 11:49 AM ~yuming  wrote:
>
> From: Yu-Ming Chang 
>
> Since C always implies Zca, Zca is always enabled when 16-bit
> insructions are supported. we can only check ext_zca to allow
> 16-bit aligned PC addresses.

Urgh! Sorry about this

Zca is only in priv spec version 1.12 or newer. So although C does
always imply Zca, that's only true for 1.12 priv specs.

This patch as is breaks older CPUs (like the sifive_u).

That's my fault as I told you to use Zca, but unfortunately it doesn't work.

So, the best bet is probably a helper function that checks the priv
spec version then based on that checks either Zca or C. That way
when/if we drop versions before 1.12 we can update the code.

Alistair

>
> Signed-off-by: Yu-Ming Chang 
> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 5 ++---
>  target/riscv/op_helper.c| 4 ++--
>  target/riscv/translate.c| 2 +-
>  3 files changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
> b/target/riscv/insn_trans/trans_rvi.c.inc
> index 96c218a9d7..e5965201a7 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -106,7 +106,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>  tcg_gen_ext32s_tl(target_pc, target_pc);
>  }
>
> -if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
> +if (!ctx->cfg_ptr->ext_zca) {
>  TCGv t0 = tcg_temp_new();
>
>  misaligned = gen_new_label();
> @@ -236,8 +236,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, 
> TCGCond cond)
>
>  gen_set_label(l); /* branch taken */
>
> -if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca &&
> -(a->imm & 0x3)) {
> +if (!ctx->cfg_ptr->ext_zca && (a->imm & 0x3)) {
>  /* misaligned */
>  TCGv target_pc = tcg_temp_new();
>  gen_pc_plus_diff(target_pc, ctx, a->imm);
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index ce1256f439..68882136d7 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -276,7 +276,7 @@ target_ulong helper_sret(CPURISCVState *env)
>  }
>
>  target_ulong retpc = env->sepc;
> -if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) {
> +if (!env_archcpu(env)->cfg.ext_zca && (retpc & 0x3)) {
>  riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
>  }
>
> @@ -349,7 +349,7 @@ static void check_ret_from_m_mode(CPURISCVState *env, 
> target_ulong retpc,
>  riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
>  }
>
> -if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) {
> +if (!env_archcpu(env)->cfg.ext_zca && (retpc & 0x3)) {
>  riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
>  }
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 698b74f7a8..34eeed50be 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -566,7 +566,7 @@ static void gen_jal(DisasContext *ctx, int rd, 
> target_ulong imm)
>  TCGv succ_pc = dest_gpr(ctx, rd);
>
>  /* check misaligned: */
> -if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
> +if (!ctx->cfg_ptr->ext_zca) {
>  if ((imm & 0x3) != 0) {
>  TCGv target_pc = tcg_temp_new();
>  gen_pc_plus_diff(target_pc, ctx, imm);
> --
> 2.45.3
>



Re: [PATCH 1/2] target/riscv: fix access permission checks for CSR_SSP

2025-03-05 Thread Alistair Francis
On Tue, Feb 18, 2025 at 12:56 PM Deepak Gupta  wrote:
>
> Commit:8205bc1 ("target/riscv: introduce ssp and enabling controls for
> zicfiss") introduced CSR_SSP but it mis-interpreted the spec on access
> to CSR_SSP in M-mode. Gated to CSR_SSP is not gated via `xSSE`. But
> rather rules clearly specified in section "2.2.4. Shadow Stack Pointer"

Do you mean "22.2.1. Shadow Stack Pointer (ssp) CSR access contr" in
the priv spec?

> of `zicfiss` specification. Thanks to Adam Zabrocki for bringing this
> to attention.

The thanks should probably be below the line

>
> Fixes: 8205bc127a83 ("target/riscv: introduce ssp and enabling controls
> for zicfiss"
>
> Reported-by: Adam Zabrocki 
> Signed-off-by: Deepak Gupta 

The actual change looks good:

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index afb7544f07..75c661d2a1 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -191,6 +191,11 @@ static RISCVException cfi_ss(CPURISCVState *env, int 
> csrno)
>  return RISCV_EXCP_ILLEGAL_INST;
>  }
>
> +/* If ext implemented, M-mode always have access to SSP CSR */
> +if (env->priv == PRV_M) {
> +return RISCV_EXCP_NONE;
> +}
> +
>  /* if bcfi not active for current env, access to csr is illegal */
>  if (!cpu_get_bcfien(env)) {
>  #if !defined(CONFIG_USER_ONLY)
> --
> 2.34.1
>
>



Re: [PATCH v6 32/36] vfio/migration: Make x-migration-multifd-transfer VFIO property mutable

2025-03-05 Thread Cédric Le Goater

On 3/4/25 23:03, Maciej S. Szmigiero wrote:

From: "Maciej S. Szmigiero" 

DEFINE_PROP_ON_OFF_AUTO() property isn't runtime-mutable so using it
would mean that the source VM would need to decide upfront at startup
time whether it wants to do a multifd device state transfer at some
point.

Source VM can run for a long time before being migrated so it is
desirable to have a fallback mechanism to the old way of transferring
VFIO device state if it turns to be necessary.

This brings this property to the same mutability level as ordinary
migration parameters, which too can be adjusted at the run time.

Signed-off-by: Maciej S. Szmigiero 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/migration-multifd.c |  4 
  hw/vfio/pci.c   | 20 +---
  2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/hw/vfio/migration-multifd.c b/hw/vfio/migration-multifd.c
index aacddc503bb8..233724710b37 100644
--- a/hw/vfio/migration-multifd.c
+++ b/hw/vfio/migration-multifd.c
@@ -485,6 +485,10 @@ bool vfio_multifd_setup(VFIODevice *vbasedev, bool 
alloc_multifd, Error **errp)
  {
  VFIOMigration *migration = vbasedev->migration;
  
+/*

+ * Make a copy of this setting at the start in case it is changed
+ * mid-migration.
+ */
  if (vbasedev->migration_multifd_transfer == ON_OFF_AUTO_AUTO) {
  migration->multifd_transfer = vfio_multifd_transfer_supported();
  } else {
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 6d6f889f59c5..21605bac2fb0 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3353,6 +3353,8 @@ static void vfio_instance_init(Object *obj)
  pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
  }
  
+static PropertyInfo vfio_pci_migration_multifd_transfer_prop;

+
  static const Property vfio_pci_dev_properties[] = {
  DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIOPCIDevice, host),
  DEFINE_PROP_UUID_NODEFAULT("vf-token", VFIOPCIDevice, vf_token),
@@ -3377,9 +3379,10 @@ static const Property vfio_pci_dev_properties[] = {
  VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
  DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
  vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
-DEFINE_PROP_ON_OFF_AUTO("x-migration-multifd-transfer", VFIOPCIDevice,
-vbasedev.migration_multifd_transfer,
-ON_OFF_AUTO_AUTO),
+DEFINE_PROP("x-migration-multifd-transfer", VFIOPCIDevice,
+vbasedev.migration_multifd_transfer,
+vfio_pci_migration_multifd_transfer_prop, OnOffAuto,
+.set_default = true, .defval.i = ON_OFF_AUTO_AUTO),
  DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice,
   vbasedev.migration_events, false),
  DEFINE_PROP_BOOL("x-no-mmap", VFIOPCIDevice, vbasedev.no_mmap, false),
@@ -3480,6 +3483,17 @@ static const TypeInfo vfio_pci_nohotplug_dev_info = {
  
  static void register_vfio_pci_dev_type(void)

  {
+/*
+ * Ordinary ON_OFF_AUTO property isn't runtime-mutable, but source VM can
+ * run for a long time before being migrated so it is desirable to have a
+ * fallback mechanism to the old way of transferring VFIO device state if
+ * it turns to be necessary.
+ * The following makes this type of property have the same mutability level
+ * as ordinary migration parameters.
+ */
+vfio_pci_migration_multifd_transfer_prop = qdev_prop_on_off_auto;
+vfio_pci_migration_multifd_transfer_prop.realized_set_allowed = true;
+
  type_register_static(&vfio_pci_dev_info);
  type_register_static(&vfio_pci_nohotplug_dev_info);
  }






Re: [PATCH v6 15/36] migration/multifd: Make MultiFDSendData a struct

2025-03-05 Thread Cédric Le Goater

Fabiano,

Could you please ack (or not) this patch please ?

Thanks,

C.


On 3/4/25 23:03, Maciej S. Szmigiero wrote:

From: Peter Xu 

The newly introduced device state buffer can be used for either storing
VFIO's read() raw data, but already also possible to store generic device
states.  After noticing that device states may not easily provide a max
buffer size (also the fact that RAM MultiFDPages_t after all also want to
have flexibility on managing offset[] array), it may not be a good idea to
stick with union on MultiFDSendData.. as it won't play well with such
flexibility.

Switch MultiFDSendData to a struct.

It won't consume a lot more space in reality, after all the real buffers
were already dynamically allocated, so it's so far only about the two
structs (pages, device_state) that will be duplicated, but they're small.

With this, we can remove the pretty hard to understand alloc size logic.
Because now we can allocate offset[] together with the SendData, and
properly free it when the SendData is freed.

Signed-off-by: Peter Xu 
[MSS: Make sure to clear possible device state payload before freeing
MultiFDSendData, remove placeholders for other patches not included]
Signed-off-by: Maciej S. Szmigiero 
---
  migration/multifd-device-state.c |  5 -
  migration/multifd-nocomp.c   | 13 ++---
  migration/multifd.c  | 25 +++--
  migration/multifd.h  | 15 +--
  4 files changed, 22 insertions(+), 36 deletions(-)

diff --git a/migration/multifd-device-state.c b/migration/multifd-device-state.c
index e383e75b1a02..64d8ca180167 100644
--- a/migration/multifd-device-state.c
+++ b/migration/multifd-device-state.c
@@ -20,11 +20,6 @@ static struct {
  MultiFDSendData *send_data;
  } *multifd_send_device_state;
  
-size_t multifd_device_state_payload_size(void)

-{
-return sizeof(MultiFDDeviceState_t);
-}
-
  void multifd_device_state_send_setup(void)
  {
  assert(!multifd_send_device_state);
diff --git a/migration/multifd-nocomp.c b/migration/multifd-nocomp.c
index c00804652383..ffe75256c9fb 100644
--- a/migration/multifd-nocomp.c
+++ b/migration/multifd-nocomp.c
@@ -25,15 +25,14 @@
  
  static MultiFDSendData *multifd_ram_send;
  
-size_t multifd_ram_payload_size(void)

+void multifd_ram_payload_alloc(MultiFDPages_t *pages)
  {
-uint32_t n = multifd_ram_page_count();
+pages->offset = g_new0(ram_addr_t, multifd_ram_page_count());
+}
  
-/*

- * We keep an array of page offsets at the end of MultiFDPages_t,
- * add space for it in the allocation.
- */
-return sizeof(MultiFDPages_t) + n * sizeof(ram_addr_t);
+void multifd_ram_payload_free(MultiFDPages_t *pages)
+{
+g_clear_pointer(&pages->offset, g_free);
  }
  
  void multifd_ram_save_setup(void)

diff --git a/migration/multifd.c b/migration/multifd.c
index 3625c9a37c0e..dfb5189f0ea3 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -105,26 +105,12 @@ struct {
  
  MultiFDSendData *multifd_send_data_alloc(void)

  {
-size_t max_payload_size, size_minus_payload;
+MultiFDSendData *new = g_new0(MultiFDSendData, 1);
  
-/*

- * MultiFDPages_t has a flexible array at the end, account for it
- * when allocating MultiFDSendData. Use max() in case other types
- * added to the union in the future are larger than
- * (MultiFDPages_t + flex array).
- */
-max_payload_size = MAX(multifd_ram_payload_size(),
-   multifd_device_state_payload_size());
-max_payload_size = MAX(max_payload_size, sizeof(MultiFDPayload));
+multifd_ram_payload_alloc(&new->u.ram);
+/* Device state allocates its payload on-demand */
  
-/*

- * Account for any holes the compiler might insert. We can't pack
- * the structure because that misaligns the members and triggers
- * Waddress-of-packed-member.
- */
-size_minus_payload = sizeof(MultiFDSendData) - sizeof(MultiFDPayload);
-
-return g_malloc0(size_minus_payload + max_payload_size);
+return new;
  }
  
  void multifd_send_data_clear(MultiFDSendData *data)

@@ -151,8 +137,11 @@ void multifd_send_data_free(MultiFDSendData *data)
  return;
  }
  
+/* This also free's device state payload */

  multifd_send_data_clear(data);
  
+multifd_ram_payload_free(&data->u.ram);

+
  g_free(data);
  }
  
diff --git a/migration/multifd.h b/migration/multifd.h

index aa679d8bbe83..2d337e7b3b52 100644
--- a/migration/multifd.h
+++ b/migration/multifd.h
@@ -115,9 +115,13 @@ typedef struct {
  uint32_t num;
  /* number of normal pages */
  uint32_t normal_num;
+/*
+ * Pointer to the ramblock.  NOTE: it's caller's responsibility to make
+ * sure the pointer is always valid!
+ */
  RAMBlock *block;
-/* offset of each page */
-ram_addr_t offset[];
+/* offset array of each page, managed by multifd */
+ram_addr_t *offset;
  } MultiFDPages_t;
  
  struct MultiFDRecvData {

Re: [PATCH v6 00/36] Multifd 🔀 device state transfer support with VFIO consumer

2025-03-05 Thread Avihai Horon



On 05/03/2025 11:29, Cédric Le Goater wrote:

External email: Use caution opening links or attachments


Hello,

On 3/4/25 23:03, Maciej S. Szmigiero wrote:

From: "Maciej S. Szmigiero" 

This is an updated v6 patch series of the v5 series located here:
https://lore.kernel.org/qemu-devel/cover.1739994627.git.maciej.szmigi...@oracle.com/ 



What this patch set is about?
Current live migration device state transfer is done via the main 
(single)

migration channel, which reduces performance and severally impacts the
migration downtime for VMs having large device state that needs to be
transferred during the switchover phase.

Example devices that have such large switchover phase device state 
are some

types of VFIO SmartNICs and GPUs.

This patch set allows parallelizing this transfer by using multifd 
channels

for it.
It also introduces new load and save threads per VFIO device for 
decoupling

these operations from the main migration thread.
These threads run on newly introduced generic (non-AIO) thread pools,
instantiated by the core migration core.


I think we are ready to apply 1-33. Avihai, please take a look !


Sure, will try to do it by EOW.

When were you planning to apply?



7,15 and 17 still need an Ack from Peter and/or Fabiano though.

34 can be reworked a bit before -rc0.
35 is for QEMU 10.1.
36 needs some massaging. I will do that.

This can go through the vfio tree if everyone agrees.

Thanks,

C.





Changes from v5:
* Add bql_locked() assertion to migration_incoming_state_destroy() 
with a

comment describing why holding BQL there is necessary.

* Add SPDX-License-Identifier to newly added files.

* Move consistency of multfd transfer settings check to the patch adding
x-migration-multifd-transfer property.

* Change packet->idx == UINT32_MAX message to the suggested one.

* Use WITH_QEMU_LOCK_GUARD() in vfio_load_state_buffer().

* Add vfio_load_bufs_thread_{start,end} trace events.

* Invert "ret" value computation logic in vfio_load_bufs_thread() and
   vfio_multifd_save_complete_precopy_thread() - initialize "ret" to 
false
   at definition, remove "ret = false" at every failure/early exit 
block and

   add "ret = true" just before the early exit jump label.

* Make vfio_load_bufs_thread_load_config() return a bool and take an
   "Error **" parameter.

* Make vfio_multifd_setup() (previously called 
vfio_multifd_transfer_setup())
   allocate struct VFIOMultifd if requested by "alloc_multifd" 
parameter.


* Add vfio_multifd_cleanup() call to vfio_save_cleanup() (for 
consistency
   with the load code), with a comment describing that it is 
currently a NOP

   there.

* Move vfio_multifd_cleanup() to migration-multifd.c.

* Move general multifd migration description in 
docs/devel/migration/vfio.rst

   from the top section to new "Multifd" section at the bottom.

* Add comment describing why x-migration-multifd-transfer needs to be
   a custom property above the variable containing that custom 
property type

   in register_vfio_pci_dev_type().

* Add object_class_property_set_description() description for all 3 
newly

   added parameters: x-migration-multifd-transfer,
   x-migration-load-config-after-iter and 
x-migration-max-queued-buffers.


* Split out wiring vfio_multifd_setup() and vfio_multifd_cleanup() into
   general VFIO load/save setup and cleanup methods into a brand new
   patch/commit.

* Squash the patch introducing VFIOStateBuffer(s) into the "received 
buffers
   queuing" commit to fix building the interim code form at the time 
of this

   patch with "-Werror".

* Change device state packet "idstr" field to NULL-terminated and drop
   QEMU_NONSTRING marking from its definition.

* Add vbasedev->name to VFIO error messages to know which device caused
   that error.

* Move BQL lock ordering assert closer to the other lock in the lock 
order

   in vfio_load_state_buffer().

* Drop orphan "QemuThread load_bufs_thread" VFIOMultifd member leftover
   from the days of the version 2 of this patch set.

* Change "guint" into an "unsigned int" where it was present in this
   patch set.

* Use g_autoptr() for QEMUFile also in 
vfio_load_bufs_thread_load_config().


* Call multifd_abort_device_state_save_threads() if a migration error is
   already set in the save path to avoid needlessly waiting for the 
remaining

   threads to do all of their normal work.

* Other minor changes that should not have functional impact, like:
   renamed functions/labels, moved code lines between patches contained
   in this patch set, added review tags, code formatting, rebased on top
   of the latest QEMU git master, etc.



This patch set is targeting QEMU 10.0.

It is also exported as a git tree:
https://gitlab.com/maciejsszmigiero/qemu/-/commits/multifd-device-state-transfer-vfio 





Maciej S. Szmigiero (35):
   migration: Clarify that 

[PATCH qemu 7/8] hw/cxl/cxl-mailbox-utils: Added support for Get Log Capabilities (Opcode 0402h)

2025-03-05 Thread Jonathan Cameron via
From: Arpit Kumar 

CXL spec 3.2 section 8.2.10.5.3 describes Get Log Capabilities.
It provides log capabilities supported by specified log.

Signed-off-by: Arpit Kumar 
Signed-off-by: Jonathan Cameron 
---
 include/hw/cxl/cxl_device.h  | 20 
 include/hw/cxl/cxl_mailbox.h |  5 
 hw/cxl/cxl-mailbox-utils.c   | 45 
 3 files changed, 70 insertions(+)

diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index ed6cd50c67..87a376c982 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -133,6 +133,18 @@ typedef enum {
 CXL_MBOX_MAX = 0x20
 } CXLRetCode;
 
+/* types of logs */
+typedef enum {
+CXL_LOG_COMMAND_EFFECT,
+CXL_LOG_VENDOR_DEBUG,
+CXL_LOG_COMPONENT_STATE_DUMP,
+CXL_LOG_ERROR_CHECK_SCRUB,
+CXL_LOG_MEDIA_TEST_CAPABILITY,
+CXL_LOG_MEDIA_TEST_RESULTS_SHORT,
+CXL_LOG_MEDIA_TEST_RESULTS_LONG,
+MAX_LOG_TYPE
+} CXLLogType;
+
 typedef struct CXLCCI CXLCCI;
 typedef struct cxl_device_state CXLDeviceState;
 struct cxl_cmd;
@@ -163,6 +175,11 @@ typedef struct CXLEventLog {
 QSIMPLEQ_HEAD(, CXLEvent) events;
 } CXLEventLog;
 
+typedef struct CXLLogCapabilities {
+uint32_t param_flags;
+QemuUUID uuid;
+} CXLLogCapabilities;
+
 typedef struct CXLCCI {
 struct cxl_cmd cxl_cmd_set[256][256];
 struct cel_log {
@@ -171,6 +188,9 @@ typedef struct CXLCCI {
 } cel_log[1 << 16];
 size_t cel_size;
 
+/* get log capabilities */
+const CXLLogCapabilities *supported_log_cap;
+
 /* background command handling (times in ms) */
 struct {
 uint16_t opcode;
diff --git a/include/hw/cxl/cxl_mailbox.h b/include/hw/cxl/cxl_mailbox.h
index 9008402d1c..8e1c7c5f15 100644
--- a/include/hw/cxl/cxl_mailbox.h
+++ b/include/hw/cxl/cxl_mailbox.h
@@ -16,4 +16,9 @@
 #define CXL_MBOX_BACKGROUND_OPERATION (1 << 6)
 #define CXL_MBOX_BACKGROUND_OPERATION_ABORT (1 << 7)
 
+#define CXL_LOG_CAP_CLEAR_SUPPORTED (1 << 0)
+#define CXL_LOG_CAP_POPULATE_SUPPORTED (1 << 1)
+#define CXL_LOG_CAP_AUTO_POPULATE_SUPPORTED (1 << 2)
+#define CXL_LOG_CAP_PERSISTENT_COLD_RESET_SUPPORTED (1 << 3)
+
 #endif
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 299f232f26..f35fc4f112 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -81,6 +81,7 @@ enum {
 LOGS= 0x04,
 #define GET_SUPPORTED 0x0
 #define GET_LOG   0x1
+#define GET_LOG_CAPABILITIES   0x2
 FEATURES= 0x05,
 #define GET_SUPPORTED 0x0
 #define GET_FEATURE   0x1
@@ -1068,6 +1069,43 @@ static CXLRetCode cmd_logs_get_log(const struct cxl_cmd 
*cmd,
 return CXL_MBOX_SUCCESS;
 }
 
+static const struct CXLLogCapabilities *find_log_index(QemuUUID *uuid, CXLCCI 
*cci)
+{
+for (int i = CXL_LOG_COMMAND_EFFECT; i < MAX_LOG_TYPE; i++) {
+if (qemu_uuid_is_equal(uuid,
+&cci->supported_log_cap[i].uuid)) {
+return &cci->supported_log_cap[i];
+}
+}
+return NULL;
+}
+
+/* CXL r3.2 Section 8.2.10.5.3: Get Log Capabilities (Opcode 0402h) */
+static CXLRetCode cmd_logs_get_log_capabilities(const struct cxl_cmd *cmd,
+uint8_t *payload_in,
+size_t len_in,
+uint8_t *payload_out,
+size_t *len_out,
+CXLCCI *cci)
+{
+const CXLLogCapabilities *cap;
+struct {
+QemuUUID uuid;
+} QEMU_PACKED QEMU_ALIGNED(8) *get_log_capabilities_in = (void 
*)payload_in;
+
+uint32_t *get_log_capabilities_out = (uint32_t *)payload_out;
+
+cap = find_log_index(&get_log_capabilities_in->uuid, cci);
+if (!cap) {
+return CXL_MBOX_INVALID_LOG;
+}
+
+memcpy(get_log_capabilities_out, &cap->param_flags,
+   sizeof(cap->param_flags));
+*len_out = sizeof(*get_log_capabilities_out);
+return CXL_MBOX_SUCCESS;
+}
+
 /* CXL r3.1 section 8.2.9.6: Features */
 /*
  * Get Supported Features output payload
@@ -3253,6 +3291,8 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
 [LOGS][GET_SUPPORTED] = { "LOGS_GET_SUPPORTED", cmd_logs_get_supported,
   0, 0 },
 [LOGS][GET_LOG] = { "LOGS_GET_LOG", cmd_logs_get_log, 0x18, 0 },
+[LOGS][GET_LOG_CAPABILITIES] = { "LOGS_GET_LOG_CAPABILITIES",
+ cmd_logs_get_log_capabilities, 0x10, 0 },
 [FEATURES][GET_SUPPORTED] = { "FEATURES_GET_SUPPORTED",
   cmd_features_get_supported, 0x8, 0 },
 [FEATURES][GET_FEATURE] = { "FEATURES_GET_FEATURE",
@@ -3512,10 +3552,15 @@ static void cxl_rebuild_cel(CXLCCI *cci)
 }
 }
 
+static const struct CXLLogCapabilities cxl_get_log_cap[MAX_LOG_TYPE] = {
+[CXL_LOG_COMMAND_EFFECT] = { .param_flags = 0, .uuid = cel_uuid },
+};
+
 void cxl_

[PATCH qemu 1/8] hw/cxl: Support aborting background commands

2025-03-05 Thread Jonathan Cameron via
From: Davidlohr Bueso 

As of 3.1 spec, background commands can be canceled with a new
abort command. Implement the support, which is advertised in
the CEL. No ad-hoc context undoing is necessary as all the
command logic of the running bg command is done upon completion.
Arbitrarily, the on-going background cmd will not be aborted if
already at least 85% done;

A mutex is introduced to stabilize mbox request cancel command vs
the timer callback being fired scenarios (as well as reading the
mbox registers). While some operations under critical regions
may be unnecessary (irq notifying, cmd callbacks), this is not
a path where performance is important, so simplicity is preferred.

Tested-by: Ajay Joshi 
Reviewed-by: Ajay Joshi 
Signed-off-by: Davidlohr Bueso 
Signed-off-by: Jonathan Cameron 
---
Modified with changes Davidlohr posted on list.
---
 include/hw/cxl/cxl_device.h  |  4 ++
 include/hw/cxl/cxl_mailbox.h |  1 +
 hw/cxl/cxl-device-utils.c| 14 ---
 hw/cxl/cxl-mailbox-utils.c   | 72 
 hw/mem/cxl_type3.c   |  8 +++-
 5 files changed, 86 insertions(+), 13 deletions(-)

diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 3a0ee7e8e7..d21695507f 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -176,10 +176,12 @@ typedef struct CXLCCI {
 uint16_t opcode;
 uint16_t complete_pct;
 uint16_t ret_code; /* Current value of retcode */
+bool aborted;
 uint64_t starttime;
 /* set by each bg cmd, cleared by the bg_timer when complete */
 uint64_t runtime;
 QEMUTimer *timer;
+QemuMutex lock; /* serializes mbox abort vs timer cb */
 } bg;
 
 /* firmware update */
@@ -201,6 +203,7 @@ typedef struct CXLCCI {
 DeviceState *d;
 /* Pointer to the device hosting the protocol conversion */
 DeviceState *intf;
+bool initialized;
 } CXLCCI;
 
 typedef struct cxl_device_state {
@@ -316,6 +319,7 @@ void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, 
size_t payload_max);
 void cxl_initialize_mailbox_swcci(CXLCCI *cci, DeviceState *intf,
   DeviceState *d, size_t payload_max);
 void cxl_init_cci(CXLCCI *cci, size_t payload_max);
+void cxl_destroy_cci(CXLCCI *cci);
 void cxl_add_cci_commands(CXLCCI *cci, const struct cxl_cmd 
(*cxl_cmd_set)[256],
   size_t payload_max);
 int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
diff --git a/include/hw/cxl/cxl_mailbox.h b/include/hw/cxl/cxl_mailbox.h
index beb048052e..9008402d1c 100644
--- a/include/hw/cxl/cxl_mailbox.h
+++ b/include/hw/cxl/cxl_mailbox.h
@@ -14,5 +14,6 @@
 #define CXL_MBOX_IMMEDIATE_LOG_CHANGE (1 << 4)
 #define CXL_MBOX_SECURITY_STATE_CHANGE (1 << 5)
 #define CXL_MBOX_BACKGROUND_OPERATION (1 << 6)
+#define CXL_MBOX_BACKGROUND_OPERATION_ABORT (1 << 7)
 
 #endif
diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
index 52ad1e4c3f..e150d74457 100644
--- a/hw/cxl/cxl-device-utils.c
+++ b/hw/cxl/cxl-device-utils.c
@@ -95,11 +95,15 @@ static uint64_t mailbox_reg_read(void *opaque, hwaddr 
offset, unsigned size)
 }
 if (offset == A_CXL_DEV_MAILBOX_STS) {
 uint64_t status_reg = cxl_dstate->mbox_reg_state64[offset / size];
-if (cci->bg.complete_pct) {
-status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, BG_OP,
-0);
-cxl_dstate->mbox_reg_state64[offset / size] = status_reg;
-}
+int bgop;
+
+qemu_mutex_lock(&cci->bg.lock);
+bgop = !(cci->bg.complete_pct == 100 || cci->bg.aborted);
+
+status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, BG_OP,
+bgop);
+cxl_dstate->mbox_reg_state64[offset / size] = status_reg;
+qemu_mutex_unlock(&cci->bg.lock);
 }
 return cxl_dstate->mbox_reg_state64[offset / size];
 default:
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 516c01d840..4401f446d9 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -56,6 +56,7 @@ enum {
 INFOSTAT= 0x00,
 #define IS_IDENTIFY   0x1
 #define BACKGROUND_OPERATION_STATUS0x2
+#define BACKGROUND_OPERATION_ABORT 0x5
 EVENTS  = 0x01,
 #define GET_RECORDS   0x0
 #define CLEAR_RECORDS   0x1
@@ -636,6 +637,41 @@ static CXLRetCode cmd_infostat_bg_op_sts(const struct 
cxl_cmd *cmd,
 return CXL_MBOX_SUCCESS;
 }
 
+/*
+ * CXL r3.1 Section 8.2.9.1.5:
+ * Request Abort Background Operation (Opcode 0005h)
+ */
+static CXLRetCode cmd_infostat_bg_op_abort(const struct cxl_cmd *cmd,
+   uint8_t *payload_in,
+   size_t len_in,
+   uint8_t *payload_out,
+ 

  1   2   3   4   >