qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20
@ 2025-05-20 11:04 Paolo Bonzini
  2025-05-20 11:04 ` [PULL 01/35] i386/tcg: Make CPUID_HT and CPUID_EXT3_CMP_LEG supported Paolo Bonzini
                   ` (35 more replies)
  0 siblings, 36 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:04 UTC (permalink / raw)
  To: qemu-devel

The following changes since commit 2af4a82ab2cce3412ffc92cd4c96bd870e33bc8e:

  Merge tag 'pull-riscv-to-apply-20250519' of https://github.com/alistair23/qemu into staging (2025-05-19 14:00:54 -0400)

are available in the Git repository at:

  https://gitlab.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to 220c739903cec99df032219ac94c45b5269a0ab5:

  qom: reverse order of instance_post_init calls (2025-05-20 08:18:53 +0200)

----------------------------------------------------------------
* target/riscv: clean up supported MMU modes, declarative CPU definitions,
  remove .instance_post_init (reviewed by Alistair)
* qom: reverse order of instance_post_init calls
* qapi/misc-target: doc and standard improvements for SGX
* hw/pci-host/gt64120: Fix endianness handling
* i386/hvf: Make CPUID_HT supported
* i386/tcg: Make CPUID_HT and CPUID_EXT3_CMP_LEG supported

----------------------------------------------------------------
Paolo Bonzini (27):
      hw/riscv: acpi: only create RHCT MMU entry for supported types
      target/riscv: assert argument to set_satp_mode_max_supported is valid
      target/riscv: cpu: store max SATP mode as a single integer
      target/riscv: update max_satp_mode based on QOM properties
      target/riscv: remove supported from RISCVSATPMap
      target/riscv: move satp_mode.{map,init} out of CPUConfig
      target/riscv: introduce RISCVCPUDef
      target/riscv: store RISCVCPUDef struct directly in the class
      target/riscv: merge riscv_cpu_class_init with the class_base function
      target/riscv: move RISCVCPUConfig fields to a header file
      target/riscv: include default value in cpu_cfg_fields.h.inc
      target/riscv: add more RISCVCPUDef fields
      target/riscv: convert abstract CPU classes to RISCVCPUDef
      target/riscv: convert profile CPU models to RISCVCPUDef
      target/riscv: convert bare CPU models to RISCVCPUDef
      target/riscv: convert dynamic CPU models to RISCVCPUDef
      target/riscv: convert SiFive E CPU models to RISCVCPUDef
      target/riscv: convert ibex CPU models to RISCVCPUDef
      target/riscv: convert SiFive U models to RISCVCPUDef
      target/riscv: th: make CSR insertion test a bit more intuitive
      target/riscv: generalize custom CSR functionality
      target/riscv: convert THead C906 to RISCVCPUDef
      target/riscv: convert TT Ascalon to RISCVCPUDef
      target/riscv: convert Ventana V1 to RISCVCPUDef
      target/riscv: convert Xiangshan Nanhu to RISCVCPUDef
      target/riscv: remove .instance_post_init
      qom: reverse order of instance_post_init calls

Rakesh Jeyasingh (2):
      hw/pci-host/gt64120: Fix endianness handling
      hw/pci-host: Remove unused pci_host_data_be_ops

Xiaoyao Li (2):
      i386/tcg: Make CPUID_HT and CPUID_EXT3_CMP_LEG supported
      i386/hvf: Make CPUID_HT supported

Zhao Liu (4):
      qapi/misc-target: Rename SGXEPCSection to SgxEpcSection
      qapi/misc-target: Rename SGXInfo to SgxInfo
      qapi/misc-target: Fix the doc related SGXEPCSection
      qapi/misc-target: Fix the doc to distinguish query-sgx and query-sgx-capabilities

 qapi/misc-target.json             |   26 +-
 include/hw/pci-host/dino.h        |    4 -
 include/hw/pci/pci_host.h         |    1 -
 include/qom/object.h              |    3 +-
 target/riscv/cpu-qom.h            |    2 +
 target/riscv/cpu.h                |   42 +-
 target/riscv/cpu_cfg.h            |  178 +------
 target/riscv/cpu_cfg_fields.h.inc |  170 +++++++
 hw/i386/sgx-stub.c                |    4 +-
 hw/i386/sgx.c                     |   32 +-
 hw/pci-host/gt64120.c             |   82 +--
 hw/pci/pci_host.c                 |    6 -
 hw/riscv/boot.c                   |    2 +-
 hw/riscv/virt-acpi-build.c        |   15 +-
 hw/riscv/virt.c                   |    5 +-
 qom/object.c                      |    8 +-
 target/i386/cpu.c                 |    8 +-
 target/i386/hvf/x86_cpuid.c       |    2 +-
 target/riscv/cpu.c                | 1014 +++++++++++++++++--------------------
 target/riscv/csr.c                |   11 +-
 target/riscv/gdbstub.c            |    6 +-
 target/riscv/kvm/kvm-cpu.c        |   27 +-
 target/riscv/machine.c            |    2 +-
 target/riscv/tcg/tcg-cpu.c        |   13 +-
 target/riscv/th_csr.c             |   30 +-
 target/riscv/translate.c          |    2 +-
 26 files changed, 821 insertions(+), 874 deletions(-)
 create mode 100644 target/riscv/cpu_cfg_fields.h.inc
-- 
2.49.0



^ permalink raw reply	[flat|nested] 53+ messages in thread

* [PULL 01/35] i386/tcg: Make CPUID_HT and CPUID_EXT3_CMP_LEG supported
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
@ 2025-05-20 11:04 ` Paolo Bonzini
  2025-05-20 11:04 ` [PULL 02/35] i386/hvf: Make CPUID_HT supported Paolo Bonzini
                   ` (34 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Xiaoyao Li, Ewan Hai

From: Xiaoyao Li <xiaoyao.li@intel.com>

Since commit c6bd2dd63420 ("i386/cpu: Set up CPUID_HT in
x86_cpu_expand_features() instead of cpu_x86_cpuid()") and
commit 99a637a86f55 ("i386/cpu: Set and track CPUID_EXT3_CMP_LEG in
env->features[FEAT_8000_0001_ECX]"), it gets warnings when booting the
VM with vcpus >= 2 and with tcg:

  qemu-system-x86_64: warning: TCG doesn't support requested feature: CPUID.01H:EDX.ht [bit 28]
  qemu-system-x86_64: warning: TCG doesn't support requested feature: CPUID.80000001H:ECX.cmp-legacy [bit 1]

This is because, after the two commits, CPUID_HT and CPUID_EXT3_CMP_LEG
are set in env->features[] when vcpus >=2 (in x86_cpu_expand_features())
later in x86_cpu_filter_features() it will check against the TCG supported
bits. However, current TCG doesn't mark the two bits as supported, hence
the warnings.

Fix it by adding the two bits to the supported bits of TCG since multiple
vcpus are supported by TCG.

Fixes: c6bd2dd63420 ("i386/cpu: Set up CPUID_HT in x86_cpu_expand_features() instead of cpu_x86_cpuid()")
Fixes: 99a637a86f55 ("i386/cpu: Set and track CPUID_EXT3_CMP_LEG in env->features[FEAT_8000_0001_ECX]")
Reported-by: Ewan Hai <ewanhai-oc@zhaoxin.com>
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Link: https://lore.kernel.org/r/20250514031652.838763-2-xiaoyao.li@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ec908d7d360..9689f6374e6 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -776,11 +776,12 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
           CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
           CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
           CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
-          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS | CPUID_DE)
+          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS | CPUID_DE | \
+          CPUID_HT)
           /* partly implemented:
           CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64) */
           /* missing:
-          CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
+          CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_TM, CPUID_PBE */
 
 /*
  * Kernel-only features that can be shown to usermode programs even if
@@ -848,7 +849,8 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
 
 #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
           CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A | \
-          CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_KERNEL_FEATURES)
+          CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_KERNEL_FEATURES | \
+          CPUID_EXT3_CMP_LEG)
 
 #define TCG_EXT4_FEATURES 0
 
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 02/35] i386/hvf: Make CPUID_HT supported
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
  2025-05-20 11:04 ` [PULL 01/35] i386/tcg: Make CPUID_HT and CPUID_EXT3_CMP_LEG supported Paolo Bonzini
@ 2025-05-20 11:04 ` Paolo Bonzini
  2025-05-20 11:04 ` [PULL 03/35] hw/pci-host/gt64120: Fix endianness handling Paolo Bonzini
                   ` (33 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Xiaoyao Li

From: Xiaoyao Li <xiaoyao.li@intel.com>

Since Commit c6bd2dd63420 ("i386/cpu: Set up CPUID_HT in
x86_cpu_expand_features() instead of cpu_x86_cpuid()"), CPUID_HT will be
set in env->features[] in x86_cpu_expand_features() when vcpus >= 2.

Later in x86_cpu_filter_features() it will check against the HVF
supported bits. It will trigger the warning like

    qemu-system-x86_64: warning: host doesn't support requested feature: CPUID.01H:EDX.ht [bit 28]

Add CPUID_HT to HVF supported CPUID bits to fix it.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Link: https://lore.kernel.org/r/20250514031652.838763-3-xiaoyao.li@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/hvf/x86_cpuid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/i386/hvf/x86_cpuid.c b/target/i386/hvf/x86_cpuid.c
index fa131b18c6d..0798a0cbafb 100644
--- a/target/i386/hvf/x86_cpuid.c
+++ b/target/i386/hvf/x86_cpuid.c
@@ -73,7 +73,7 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
              CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC |
              CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
              CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX |
-             CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS;
+             CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS | CPUID_HT;
         ecx &= CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 |
              CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID |
              CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_MOVBE |
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 03/35] hw/pci-host/gt64120: Fix endianness handling
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
  2025-05-20 11:04 ` [PULL 01/35] i386/tcg: Make CPUID_HT and CPUID_EXT3_CMP_LEG supported Paolo Bonzini
  2025-05-20 11:04 ` [PULL 02/35] i386/hvf: Make CPUID_HT supported Paolo Bonzini
@ 2025-05-20 11:04 ` Paolo Bonzini
  2025-05-20 11:04 ` [PULL 04/35] hw/pci-host: Remove unused pci_host_data_be_ops Paolo Bonzini
                   ` (32 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Rakesh Jeyasingh, Thomas Huth

From: Rakesh Jeyasingh <rakeshjb010@gmail.com>

The GT-64120 PCI controller requires special handling where:
1. Host bridge(bus 0 ,device 0) must never be byte-swapped
2. Other devices follow MByteSwap bit in GT_PCI0_CMD

The previous implementation incorrectly  swapped all accesses, breaking
host bridge detection (lspci -d 11ab:4620).

Changes made:
1. Removed gt64120_update_pci_cfgdata_mapping() and moved data_mem initialization
  to gt64120_realize() for cleaner setup
2. Implemented custom read/write handlers that:
   - Preserve host bridge accesses (extract32(config_reg,11,13)==0)
   - apply swapping only for non-bridge devices in big-endian mode

Fixes: 145e2198 ("hw/mips/gt64xxx_pci: Endian-swap using PCI_HOST_BRIDGE MemoryRegionOps")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2826

Signed-off-by: Rakesh Jeyasingh <rakeshjb010@gmail.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Link: https://lore.kernel.org/r/20250429170354.150581-2-rakeshjb010@gmail.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/pci-host/gt64120.c | 82 +++++++++++++++++++++++++------------------
 1 file changed, 48 insertions(+), 34 deletions(-)

diff --git a/hw/pci-host/gt64120.c b/hw/pci-host/gt64120.c
index 56a6ef93b7a..b12a25696c4 100644
--- a/hw/pci-host/gt64120.c
+++ b/hw/pci-host/gt64120.c
@@ -320,38 +320,6 @@ static void gt64120_isd_mapping(GT64120State *s)
     memory_region_transaction_commit();
 }
 
-static void gt64120_update_pci_cfgdata_mapping(GT64120State *s)
-{
-    /* Indexed on MByteSwap bit, see Table 158: PCI_0 Command, Offset: 0xc00 */
-    static const MemoryRegionOps *pci_host_data_ops[] = {
-        &pci_host_data_be_ops, &pci_host_data_le_ops
-    };
-    PCIHostState *phb = PCI_HOST_BRIDGE(s);
-
-    memory_region_transaction_begin();
-
-    /*
-     * The setting of the MByteSwap bit and MWordSwap bit in the PCI Internal
-     * Command Register determines how data transactions from the CPU to/from
-     * PCI are handled along with the setting of the Endianness bit in the CPU
-     * Configuration Register. See:
-     * - Table 16: 32-bit PCI Transaction Endianness
-     * - Table 158: PCI_0 Command, Offset: 0xc00
-     */
-
-    if (memory_region_is_mapped(&phb->data_mem)) {
-        memory_region_del_subregion(&s->ISD_mem, &phb->data_mem);
-        object_unparent(OBJECT(&phb->data_mem));
-    }
-    memory_region_init_io(&phb->data_mem, OBJECT(phb),
-                          pci_host_data_ops[s->regs[GT_PCI0_CMD] & 1],
-                          s, "pci-conf-data", 4);
-    memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGDATA << 2,
-                                        &phb->data_mem, 1);
-
-    memory_region_transaction_commit();
-}
-
 static void gt64120_pci_mapping(GT64120State *s)
 {
     memory_region_transaction_begin();
@@ -645,7 +613,6 @@ static void gt64120_writel(void *opaque, hwaddr addr,
     case GT_PCI0_CMD:
     case GT_PCI1_CMD:
         s->regs[saddr] = val & 0x0401fc0f;
-        gt64120_update_pci_cfgdata_mapping(s);
         break;
     case GT_PCI0_TOR:
     case GT_PCI0_BS_SCS10:
@@ -1024,6 +991,48 @@ static const MemoryRegionOps isd_mem_ops = {
     },
 };
 
+static bool bswap(const GT64120State *s) 
+{
+    PCIHostState *phb = PCI_HOST_BRIDGE(s);
+    /*check for bus == 0 && device == 0, Bits 11:15 = Device , Bits 16:23 = Bus*/
+    bool is_phb_dev0 = extract32(phb->config_reg, 11, 13) == 0;
+    bool le_mode = FIELD_EX32(s->regs[GT_PCI0_CMD], GT_PCI0_CMD, MByteSwap);
+    /* Only swap for non-bridge devices in big-endian mode */
+    return !le_mode && !is_phb_dev0;
+}
+
+static uint64_t gt64120_pci_data_read(void *opaque, hwaddr addr, unsigned size)
+{
+    GT64120State *s = opaque;
+    uint32_t val = pci_host_data_le_ops.read(opaque, addr, size);
+
+    if (bswap(s)) {
+        val = bswap32(val);
+    }
+    return val;
+}
+
+static void gt64120_pci_data_write(void *opaque, hwaddr addr, 
+    uint64_t val, unsigned size)
+{
+    GT64120State *s = opaque;
+
+    if (bswap(s)) {
+        val = bswap32(val); 
+    }
+    pci_host_data_le_ops.write(opaque, addr, val, size);  
+}
+
+static const MemoryRegionOps gt64120_pci_data_ops = {
+    .read = gt64120_pci_data_read,
+    .write = gt64120_pci_data_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
+
 static void gt64120_reset(DeviceState *dev)
 {
     GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev);
@@ -1178,7 +1187,6 @@ static void gt64120_reset(DeviceState *dev)
 
     gt64120_isd_mapping(s);
     gt64120_pci_mapping(s);
-    gt64120_update_pci_cfgdata_mapping(s);
 }
 
 static void gt64120_realize(DeviceState *dev, Error **errp)
@@ -1202,6 +1210,12 @@ static void gt64120_realize(DeviceState *dev, Error **errp)
     memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGADDR << 2,
                                         &phb->conf_mem, 1);
 
+    memory_region_init_io(&phb->data_mem, OBJECT(phb),
+                          &gt64120_pci_data_ops,
+                          s, "pci-conf-data", 4);
+    memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGDATA << 2,
+                                        &phb->data_mem, 1);
+
 
     /*
      * The whole address space decoded by the GT-64120A doesn't generate
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 04/35] hw/pci-host: Remove unused pci_host_data_be_ops
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (2 preceding siblings ...)
  2025-05-20 11:04 ` [PULL 03/35] hw/pci-host/gt64120: Fix endianness handling Paolo Bonzini
@ 2025-05-20 11:04 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 05/35] qapi/misc-target: Rename SGXEPCSection to SgxEpcSection Paolo Bonzini
                   ` (31 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Rakesh Jeyasingh, Philippe Mathieu-Daudé, Thomas Huth

From: Rakesh Jeyasingh <rakeshjb010@gmail.com>

pci_host_data_be_ops became unused after endianness fixes

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Rakesh Jeyasingh <rakeshjb010@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Thomas Huth <thuth@redhat.com>
Link: https://lore.kernel.org/r/20250429170354.150581-3-rakeshjb010@gmail.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/hw/pci-host/dino.h | 4 ----
 include/hw/pci/pci_host.h  | 1 -
 hw/pci/pci_host.c          | 6 ------
 3 files changed, 11 deletions(-)

diff --git a/include/hw/pci-host/dino.h b/include/hw/pci-host/dino.h
index fd7975c7984..5dc8cdf6108 100644
--- a/include/hw/pci-host/dino.h
+++ b/include/hw/pci-host/dino.h
@@ -109,10 +109,6 @@ static const uint32_t reg800_keep_bits[DINO800_REGS] = {
 struct DinoState {
     PCIHostState parent_obj;
 
-    /*
-     * PCI_CONFIG_ADDR is parent_obj.config_reg, via pci_host_conf_be_ops,
-     * so that we can map PCI_CONFIG_DATA to pci_host_data_be_ops.
-     */
     uint32_t config_reg_dino; /* keep original copy, including 2 lowest bits */
 
     uint32_t iar0;
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index e52d8ec2cdc..954dd446fa4 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -68,6 +68,5 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, unsigned len);
 extern const MemoryRegionOps pci_host_conf_le_ops;
 extern const MemoryRegionOps pci_host_conf_be_ops;
 extern const MemoryRegionOps pci_host_data_le_ops;
-extern const MemoryRegionOps pci_host_data_be_ops;
 
 #endif /* PCI_HOST_H */
diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index abe83bbab89..7179d99178b 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -217,12 +217,6 @@ const MemoryRegionOps pci_host_data_le_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-const MemoryRegionOps pci_host_data_be_ops = {
-    .read = pci_host_data_read,
-    .write = pci_host_data_write,
-    .endianness = DEVICE_BIG_ENDIAN,
-};
-
 static bool pci_host_needed(void *opaque)
 {
     PCIHostState *s = opaque;
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 05/35] qapi/misc-target: Rename SGXEPCSection to SgxEpcSection
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (3 preceding siblings ...)
  2025-05-20 11:04 ` [PULL 04/35] hw/pci-host: Remove unused pci_host_data_be_ops Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 06/35] qapi/misc-target: Rename SGXInfo to SgxInfo Paolo Bonzini
                   ` (30 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Zhao Liu

From: Zhao Liu <zhao1.liu@intel.com>

QAPI requires strict PascalCase naming style, i.e., only the first
letter of a single word is allowed to be uppercase, which could help
with readability.

Rename SGXEPCSection to SgxEpcSection.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20250516091130.2374221-2-zhao1.liu@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 qapi/misc-target.json |  6 +++---
 hw/i386/sgx.c         | 18 +++++++++---------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/qapi/misc-target.json b/qapi/misc-target.json
index 42e4a7417dc..a1275d3873a 100644
--- a/qapi/misc-target.json
+++ b/qapi/misc-target.json
@@ -319,7 +319,7 @@
   'if': 'TARGET_ARM' }
 
 ##
-# @SGXEPCSection:
+# @SgxEpcSection:
 #
 # Information about intel SGX EPC section info
 #
@@ -329,7 +329,7 @@
 #
 # Since: 7.0
 ##
-{ 'struct': 'SGXEPCSection',
+{ 'struct': 'SgxEpcSection',
   'data': { 'node': 'int',
             'size': 'uint64'}}
 
@@ -355,7 +355,7 @@
             'sgx1': 'bool',
             'sgx2': 'bool',
             'flc': 'bool',
-            'sections': ['SGXEPCSection']},
+            'sections': ['SgxEpcSection']},
    'if': 'TARGET_I386' }
 
 ##
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
index 5685c4fb802..3c601689eb7 100644
--- a/hw/i386/sgx.c
+++ b/hw/i386/sgx.c
@@ -84,10 +84,10 @@ static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high)
            ((high & MAKE_64BIT_MASK(0, 20)) << 32);
 }
 
-static SGXEPCSectionList *sgx_calc_host_epc_sections(void)
+static SgxEpcSectionList *sgx_calc_host_epc_sections(void)
 {
-    SGXEPCSectionList *head = NULL, **tail = &head;
-    SGXEPCSection *section;
+    SgxEpcSectionList *head = NULL, **tail = &head;
+    SgxEpcSection *section;
     uint32_t i, type;
     uint32_t eax, ebx, ecx, edx;
     uint32_t j = 0;
@@ -104,7 +104,7 @@ static SGXEPCSectionList *sgx_calc_host_epc_sections(void)
             break;
         }
 
-        section = g_new0(SGXEPCSection, 1);
+        section = g_new0(SgxEpcSection, 1);
         section->node = j++;
         section->size = sgx_calc_section_metric(ecx, edx);
         QAPI_LIST_APPEND(tail, section);
@@ -183,17 +183,17 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp)
     return info;
 }
 
-static SGXEPCSectionList *sgx_get_epc_sections_list(void)
+static SgxEpcSectionList *sgx_get_epc_sections_list(void)
 {
     GSList *device_list = sgx_epc_get_device_list();
-    SGXEPCSectionList *head = NULL, **tail = &head;
-    SGXEPCSection *section;
+    SgxEpcSectionList *head = NULL, **tail = &head;
+    SgxEpcSection *section;
 
     for (; device_list; device_list = device_list->next) {
         DeviceState *dev = device_list->data;
         Object *obj = OBJECT(dev);
 
-        section = g_new0(SGXEPCSection, 1);
+        section = g_new0(SgxEpcSection, 1);
         section->node = object_property_get_uint(obj, SGX_EPC_NUMA_NODE_PROP,
                                                  &error_abort);
         section->size = object_property_get_uint(obj, SGX_EPC_SIZE_PROP,
@@ -237,7 +237,7 @@ SGXInfo *qmp_query_sgx(Error **errp)
 void hmp_info_sgx(Monitor *mon, const QDict *qdict)
 {
     Error *err = NULL;
-    SGXEPCSectionList *section_list, *section;
+    SgxEpcSectionList *section_list, *section;
     g_autoptr(SGXInfo) info = qmp_query_sgx(&err);
     uint64_t size = 0;
 
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 06/35] qapi/misc-target: Rename SGXInfo to SgxInfo
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (4 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 05/35] qapi/misc-target: Rename SGXEPCSection to SgxEpcSection Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 07/35] qapi/misc-target: Fix the doc related SGXEPCSection Paolo Bonzini
                   ` (29 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Zhao Liu

From: Zhao Liu <zhao1.liu@intel.com>

QAPI requires strict PascalCase naming style, i.e., only the first
letter of a single word is allowed to be uppercase, which could help
with readability.

Rename SGXInfo to SgxInfo.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20250516091130.2374221-3-zhao1.liu@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 qapi/misc-target.json | 12 ++++++------
 hw/i386/sgx-stub.c    |  4 ++--
 hw/i386/sgx.c         | 14 +++++++-------
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/qapi/misc-target.json b/qapi/misc-target.json
index a1275d3873a..6b3c9d8bd58 100644
--- a/qapi/misc-target.json
+++ b/qapi/misc-target.json
@@ -334,7 +334,7 @@
             'size': 'uint64'}}
 
 ##
-# @SGXInfo:
+# @SgxInfo:
 #
 # Information about intel Safe Guard eXtension (SGX) support
 #
@@ -350,7 +350,7 @@
 #
 # Since: 6.2
 ##
-{ 'struct': 'SGXInfo',
+{ 'struct': 'SgxInfo',
   'data': { 'sgx': 'bool',
             'sgx1': 'bool',
             'sgx2': 'bool',
@@ -363,7 +363,7 @@
 #
 # Returns information about SGX
 #
-# Returns: @SGXInfo
+# Returns: @SgxInfo
 #
 # Since: 6.2
 #
@@ -375,14 +375,14 @@
 #                      "sections": [{"node": 0, "size": 67108864},
 #                      {"node": 1, "size": 29360128}]} }
 ##
-{ 'command': 'query-sgx', 'returns': 'SGXInfo', 'if': 'TARGET_I386' }
+{ 'command': 'query-sgx', 'returns': 'SgxInfo', 'if': 'TARGET_I386' }
 
 ##
 # @query-sgx-capabilities:
 #
 # Returns information from host SGX capabilities
 #
-# Returns: @SGXInfo
+# Returns: @SgxInfo
 #
 # Since: 6.2
 #
@@ -394,7 +394,7 @@
 #                      "section" : [{"node": 0, "size": 67108864},
 #                      {"node": 1, "size": 29360128}]} }
 ##
-{ 'command': 'query-sgx-capabilities', 'returns': 'SGXInfo', 'if': 'TARGET_I386' }
+{ 'command': 'query-sgx-capabilities', 'returns': 'SgxInfo', 'if': 'TARGET_I386' }
 
 
 ##
diff --git a/hw/i386/sgx-stub.c b/hw/i386/sgx-stub.c
index 38ff75e9f37..ccb21a975d7 100644
--- a/hw/i386/sgx-stub.c
+++ b/hw/i386/sgx-stub.c
@@ -10,13 +10,13 @@ void sgx_epc_build_srat(GArray *table_data)
 {
 }
 
-SGXInfo *qmp_query_sgx(Error **errp)
+SgxInfo *qmp_query_sgx(Error **errp)
 {
     error_setg(errp, "SGX support is not compiled in");
     return NULL;
 }
 
-SGXInfo *qmp_query_sgx_capabilities(Error **errp)
+SgxInfo *qmp_query_sgx_capabilities(Error **errp)
 {
     error_setg(errp, "SGX support is not compiled in");
     return NULL;
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
index 3c601689eb7..c80203b438e 100644
--- a/hw/i386/sgx.c
+++ b/hw/i386/sgx.c
@@ -153,9 +153,9 @@ static void sgx_epc_reset(void *opaque)
      }
 }
 
-SGXInfo *qmp_query_sgx_capabilities(Error **errp)
+SgxInfo *qmp_query_sgx_capabilities(Error **errp)
 {
-    SGXInfo *info = NULL;
+    SgxInfo *info = NULL;
     uint32_t eax, ebx, ecx, edx;
     Error *local_err = NULL;
 
@@ -166,7 +166,7 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp)
         return NULL;
     }
 
-    info = g_new0(SGXInfo, 1);
+    info = g_new0(SgxInfo, 1);
     host_cpuid(0x7, 0, &eax, &ebx, &ecx, &edx);
 
     info->sgx = ebx & (1U << 2) ? true : false;
@@ -205,9 +205,9 @@ static SgxEpcSectionList *sgx_get_epc_sections_list(void)
     return head;
 }
 
-SGXInfo *qmp_query_sgx(Error **errp)
+SgxInfo *qmp_query_sgx(Error **errp)
 {
-    SGXInfo *info = NULL;
+    SgxInfo *info = NULL;
     X86MachineState *x86ms;
     PCMachineState *pcms =
         (PCMachineState *)object_dynamic_cast(qdev_get_machine(),
@@ -223,7 +223,7 @@ SGXInfo *qmp_query_sgx(Error **errp)
         return NULL;
     }
 
-    info = g_new0(SGXInfo, 1);
+    info = g_new0(SgxInfo, 1);
 
     info->sgx = true;
     info->sgx1 = true;
@@ -238,7 +238,7 @@ void hmp_info_sgx(Monitor *mon, const QDict *qdict)
 {
     Error *err = NULL;
     SgxEpcSectionList *section_list, *section;
-    g_autoptr(SGXInfo) info = qmp_query_sgx(&err);
+    g_autoptr(SgxInfo) info = qmp_query_sgx(&err);
     uint64_t size = 0;
 
     if (err) {
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 07/35] qapi/misc-target: Fix the doc related SGXEPCSection
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (5 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 06/35] qapi/misc-target: Rename SGXInfo to SgxInfo Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 08/35] qapi/misc-target: Fix the doc to distinguish query-sgx and query-sgx-capabilities Paolo Bonzini
                   ` (28 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Zhao Liu, Markus Armbruster

From: Zhao Liu <zhao1.liu@intel.com>

The "sections" field of SGXInfo is used to gather EPC section
information for both the guest and the host. Therefore, delete the "for
guest" limitation.

Additionally, avoid the abbreviation "info" and use "information"
instead. And for SGXEPCSection, delete the redundant word "info".

Reported-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Link: https://lore.kernel.org/r/20250513143131.2008078-2-zhao1.liu@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 qapi/misc-target.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qapi/misc-target.json b/qapi/misc-target.json
index 6b3c9d8bd58..6814708972d 100644
--- a/qapi/misc-target.json
+++ b/qapi/misc-target.json
@@ -321,7 +321,7 @@
 ##
 # @SgxEpcSection:
 #
-# Information about intel SGX EPC section info
+# Information about intel SGX EPC section
 #
 # @node: the numa node
 #
@@ -346,7 +346,7 @@
 #
 # @flc: true if FLC is supported
 #
-# @sections: The EPC sections info for guest (Since: 7.0)
+# @sections: The EPC sections information (Since: 7.0)
 #
 # Since: 6.2
 ##
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 08/35] qapi/misc-target: Fix the doc to distinguish query-sgx and query-sgx-capabilities
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (6 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 07/35] qapi/misc-target: Fix the doc related SGXEPCSection Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 09/35] hw/riscv: acpi: only create RHCT MMU entry for supported types Paolo Bonzini
                   ` (27 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Zhao Liu, Markus Armbruster

From: Zhao Liu <zhao1.liu@intel.com>

There're 2 QMP commands: query-sgx and query-sgx-capabilities, but
their outputs are very similar and the documentation lacks clear
differentiation.

From the codes, query-sgx is used to gather guest's SGX capabilities
(including SGX related CPUIDs and EPC sections' size, in SGXInfo), and
if guest doesn't have SGX, then QEMU will report the error message.

On the other hand, query-sgx-capabilities is used to gather host's SGX
capabilities (descripted by SGXInfo as well). And if host doesn't
support SGX, then QEMU will also report the error message.

Considering that SGXInfo is already documented and both these 2 commands
have enough error messages (for the exception case in their codes).

Therefore the QAPI documentation for these two commands only needs to
emphasize that one of them applies to the guest and the other to the
host.

Fix their documentation to reflect this difference.

Reported-by: Markus Armbruster <armbru@redhat.com>
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Link: https://lore.kernel.org/r/20250513143131.2008078-3-zhao1.liu@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 qapi/misc-target.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qapi/misc-target.json b/qapi/misc-target.json
index 6814708972d..f7ec695caad 100644
--- a/qapi/misc-target.json
+++ b/qapi/misc-target.json
@@ -361,7 +361,7 @@
 ##
 # @query-sgx:
 #
-# Returns information about SGX
+# Returns information about configured SGX capabilities of guest
 #
 # Returns: @SgxInfo
 #
@@ -380,7 +380,7 @@
 ##
 # @query-sgx-capabilities:
 #
-# Returns information from host SGX capabilities
+# Returns information about SGX capabilities of host
 #
 # Returns: @SgxInfo
 #
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 09/35] hw/riscv: acpi: only create RHCT MMU entry for supported types
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (7 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 08/35] qapi/misc-target: Fix the doc to distinguish query-sgx and query-sgx-capabilities Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 10/35] target/riscv: assert argument to set_satp_mode_max_supported is valid Paolo Bonzini
                   ` (26 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Do not create the RHCT MMU type entry for RV32 CPUs, since it
only has definitions for SV39/SV48/SV57.  Likewise, check that
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.

Acked-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 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 1eef2fb4eb3..e693d529e15 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -288,6 +288,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,
@@ -307,7 +308,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++;
     }
 
@@ -367,7 +369,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 */
@@ -382,7 +385,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.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 10/35] target/riscv: assert argument to set_satp_mode_max_supported is valid
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (8 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 09/35] hw/riscv: acpi: only create RHCT MMU entry for supported types Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 11/35] target/riscv: cpu: store max SATP mode as a single integer Paolo Bonzini
                   ` (25 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

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
SV64 is not a valid VM mode for 32-bit CPUs, SV64 is not a
valid VM mode at all, not yet at least.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 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 d92874baa06..0f7ce5305be 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -444,6 +444,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 */
@@ -1497,7 +1499,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.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 11/35] target/riscv: cpu: store max SATP mode as a single integer
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (9 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 10/35] target/riscv: assert argument to set_satp_mode_max_supported is valid Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 12/35] target/riscv: update max_satp_mode based on QOM properties Paolo Bonzini
                   ` (24 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

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.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 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 cfe371b829d..c8ea5cdc870 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -196,6 +196,7 @@ struct RISCVCPUConfig {
 
     bool short_isa_string;
 
+    int8_t max_satp_mode;
     RISCVSATPMap satp_mode;
 };
 
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0f7ce5305be..32c283a6628 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -446,6 +446,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 */
@@ -1172,16 +1173,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. */
@@ -1210,10 +1208,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;
     }
 
@@ -1473,6 +1471,7 @@ static void riscv_cpu_init(Object *obj)
     cpu->cfg.cbop_blocksize = 64;
     cpu->cfg.cboz_blocksize = 64;
     cpu->env.vext_ver = VEXT_VERSION_1_00_0;
+    cpu->cfg.max_satp_mode = -1;
 }
 
 static void riscv_bare_cpu_init(Object *obj)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 55e00972b79..ab8659f3044 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -816,8 +816,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.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 12/35] target/riscv: update max_satp_mode based on QOM properties
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (10 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 11/35] target/riscv: cpu: store max SATP mode as a single integer Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 13/35] target/riscv: remove supported from RISCVSATPMap Paolo Bonzini
                   ` (23 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Almost all users of cpu->cfg.satp_mode care about the "max" value
satp_mode_max_from_map(cpu->cfg.satp_mode.map).  Convert the QOM
properties back into it.  For TCG, deduce the bitmap of supported modes
from valid_vm[].

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 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 b56d3afa696..3d89a4a83ba 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -930,7 +930,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 e693d529e15..8b5683dbdeb 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -287,7 +287,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;
 
@@ -308,8 +307,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++;
     }
 
@@ -369,20 +367,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 0dcced1b49d..cf280a92e5a 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -237,10 +237,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;
@@ -252,8 +252,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 32c283a6628..48576bff92c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -389,7 +389,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 uint8_t satp_mode_max_from_map(uint32_t map)
 {
     /*
      * 'map = 0' will make us return (31 - 32), which C will
@@ -455,15 +455,13 @@ static void set_satp_mode_default_map(RISCVCPU *cpu)
     /*
      * Bare CPUs do not default to the max available.
      * Users must set a valid satp_mode in the command
-     * line.
+     * line.  Otherwise, leave the existing max_satp_mode
+     * in place.
      */
     if (object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_BARE_CPU) != NULL) {
         warn_report("No satp mode set. Defaulting to 'bare'");
-        cpu->cfg.satp_mode.map = (1 << VM_1_10_MBARE);
-        return;
+        cpu->cfg.max_satp_mode = VM_1_10_MBARE;
     }
-
-    cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported;
 }
 #endif
 
@@ -1175,8 +1173,8 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
     bool rv32 = riscv_cpu_is_32bit(cpu);
     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) {
+    if (cpu->cfg.max_satp_mode == -1) {
+        /* The CPU wants the hypervisor to decide which satp mode to allow */
         return;
     }
 
@@ -1195,14 +1193,14 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
                     (cpu->cfg.satp_mode.supported & (1 << i))) {
                     for (int j = i - 1; j >= 0; --j) {
                         if (cpu->cfg.satp_mode.supported & (1 << j)) {
-                            cpu->cfg.satp_mode.map |= (1 << j);
-                            break;
+                            cpu->cfg.max_satp_mode = j;
+                            return;
                         }
                     }
-                    break;
                 }
             }
         }
+        return;
     }
 
     satp_mode_map_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
@@ -1232,12 +1230,7 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
         }
     }
 
-    /* Finally expand the map so that all valid modes are set */
-    for (int i = satp_mode_map_max - 1; i >= 0; --i) {
-        if (cpu->cfg.satp_mode.supported & (1 << i)) {
-            cpu->cfg.satp_mode.map |= (1 << i);
-        }
-    }
+    cpu->cfg.max_satp_mode = satp_mode_map_max;
 }
 #endif
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 288edeedea4..9843fd21914 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1912,8 +1912,13 @@ static RISCVException read_mstatus(CPURISCVState *env, int csrno,
 
 static bool validate_vm(CPURISCVState *env, target_ulong vm)
 {
-    uint64_t mode_supported = riscv_cpu_cfg(env)->satp_mode.map;
-    return get_field(mode_supported, (1 << vm));
+    bool rv32 = riscv_cpu_mxl(env) == MXL_RV32;
+    RISCVCPU *cpu = env_archcpu(env);
+    int satp_mode_supported_max = cpu->cfg.max_satp_mode;
+    const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
+
+    assert(satp_mode_supported_max >= 0);
+    return vm <= satp_mode_supported_max && valid_vm[vm];
 }
 
 static target_ulong legalize_xatp(CPURISCVState *env, target_ulong old_xatp,
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 13/35] target/riscv: remove supported from RISCVSATPMap
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (11 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 12/35] target/riscv: update max_satp_mode based on QOM properties Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 14/35] target/riscv: move satp_mode.{map, init} out of CPUConfig Paolo Bonzini via
                   ` (22 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

"supported" can be computed on the fly based on the max_satp_mode.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 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 c8ea5cdc870..8b80e03c9ab 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 48576bff92c..0326cd8e563 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -439,14 +439,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 */
@@ -1171,9 +1184,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;
     }
@@ -1190,9 +1204,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;
                         }
@@ -1221,7 +1235,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.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 14/35] target/riscv: move satp_mode.{map, init} out of CPUConfig
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (12 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 13/35] target/riscv: remove supported from RISCVSATPMap Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini via
  2025-05-20 11:05 ` [PULL 15/35] target/riscv: introduce RISCVCPUDef Paolo Bonzini
                   ` (21 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini via @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

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.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 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 3d89a4a83ba..731ea2540cd 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -499,6 +499,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
@@ -515,6 +528,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 8b80e03c9ab..8fa73c8a07d 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;
@@ -195,7 +182,6 @@ struct RISCVCPUConfig {
     bool short_isa_string;
 
     int8_t max_satp_mode;
-    RISCVSATPMap satp_mode;
 };
 
 typedef struct RISCVCPUConfig RISCVCPUConfig;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0326cd8e563..54a996c2927 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1192,8 +1192,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 {
@@ -1203,7 +1203,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)) {
@@ -1217,7 +1217,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) {
@@ -1233,8 +1233,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),
@@ -1322,11 +1322,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);
+    value = satp_modes->map & (1 << satp);
 
     visit_type_bool(v, name, &value, errp);
 }
@@ -1334,7 +1334,7 @@ static void cpu_riscv_get_satp(Object *obj, Visitor *v, const char *name,
 static void cpu_riscv_set_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;
 
@@ -1342,8 +1342,8 @@ static void cpu_riscv_set_satp(Object *obj, Visitor *v, const char *name,
         return;
     }
 
-    satp_map->map = deposit32(satp_map->map, satp, 1, value);
-    satp_map->init |= 1 << satp;
+    satp_modes->map = deposit32(satp_modes->map, satp, 1, value);
+    satp_modes->init |= 1 << satp;
 }
 
 void riscv_add_satp_mode_properties(Object *obj)
@@ -1352,16 +1352,16 @@ void riscv_add_satp_mode_properties(Object *obj)
 
     if (cpu->env.misa_mxl == MXL_RV32) {
         object_property_add(obj, "sv32", "bool", cpu_riscv_get_satp,
-                            cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
+                            cpu_riscv_set_satp, NULL, &cpu->satp_modes);
     } else {
         object_property_add(obj, "sv39", "bool", cpu_riscv_get_satp,
-                            cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
+                            cpu_riscv_set_satp, NULL, &cpu->satp_modes);
         object_property_add(obj, "sv48", "bool", cpu_riscv_get_satp,
-                            cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
+                            cpu_riscv_set_satp, NULL, &cpu->satp_modes);
         object_property_add(obj, "sv57", "bool", cpu_riscv_get_satp,
-                            cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
+                            cpu_riscv_set_satp, NULL, &cpu->satp_modes);
         object_property_add(obj, "sv64", "bool", cpu_riscv_get_satp,
-                            cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
+                            cpu_riscv_set_satp, NULL, &cpu->satp_modes);
     }
 }
 
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 15/35] target/riscv: introduce RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (13 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 14/35] target/riscv: move satp_mode.{map, init} out of CPUConfig Paolo Bonzini via
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 16/35] target/riscv: store RISCVCPUDef struct directly in the class Paolo Bonzini
                   ` (20 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Start putting all the CPU definitions in a struct.  Later this will replace
instance_init functions with declarative code, for now just remove the
ugly cast of class_data.

Reviewed-by: Alistair Francis <alistair23@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.h |  4 ++++
 target/riscv/cpu.c | 27 ++++++++++++++++++---------
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 731ea2540cd..9de3f716ea6 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -538,6 +538,10 @@ struct ArchCPU {
     const GPtrArray *decoders;
 };
 
+typedef struct RISCVCPUDef {
+    RISCVMXL misa_mxl_max;  /* max mxl for this cpu */
+} RISCVCPUDef;
+
 /**
  * RISCVCPUClass:
  * @parent_realize: The parent class' realize handler.
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 54a996c2927..6e92fbb9928 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -3073,8 +3073,9 @@ static void riscv_cpu_common_class_init(ObjectClass *c, const void *data)
 static void riscv_cpu_class_init(ObjectClass *c, const void *data)
 {
     RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
+    const RISCVCPUDef *def = data;
 
-    mcc->misa_mxl_max = (RISCVMXL)GPOINTER_TO_UINT(data);
+    mcc->misa_mxl_max = def->misa_mxl_max;
     riscv_cpu_validate_misa_mxl(mcc);
 }
 
@@ -3170,40 +3171,48 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
 }
 #endif
 
-#define DEFINE_DYNAMIC_CPU(type_name, misa_mxl_max, initfn) \
+#define DEFINE_DYNAMIC_CPU(type_name, misa_mxl_max_, initfn) \
     {                                                       \
         .name = (type_name),                                \
         .parent = TYPE_RISCV_DYNAMIC_CPU,                   \
         .instance_init = (initfn),                          \
         .class_init = riscv_cpu_class_init,                 \
-        .class_data = GUINT_TO_POINTER(misa_mxl_max)        \
+        .class_data = &(const RISCVCPUDef) {                \
+             .misa_mxl_max = (misa_mxl_max_),               \
+        },                                                  \
     }
 
-#define DEFINE_VENDOR_CPU(type_name, misa_mxl_max, initfn)  \
+#define DEFINE_VENDOR_CPU(type_name, misa_mxl_max_, initfn) \
     {                                                       \
         .name = (type_name),                                \
         .parent = TYPE_RISCV_VENDOR_CPU,                    \
         .instance_init = (initfn),                          \
         .class_init = riscv_cpu_class_init,                 \
-        .class_data = GUINT_TO_POINTER(misa_mxl_max)        \
+        .class_data = &(const RISCVCPUDef) {                \
+             .misa_mxl_max = (misa_mxl_max_),               \
+        },                                                  \
     }
 
-#define DEFINE_BARE_CPU(type_name, misa_mxl_max, initfn)    \
+#define DEFINE_BARE_CPU(type_name, misa_mxl_max_, initfn)   \
     {                                                       \
         .name = (type_name),                                \
         .parent = TYPE_RISCV_BARE_CPU,                      \
         .instance_init = (initfn),                          \
         .class_init = riscv_cpu_class_init,                 \
-        .class_data = GUINT_TO_POINTER(misa_mxl_max)        \
+        .class_data = &(const RISCVCPUDef) {                \
+             .misa_mxl_max = (misa_mxl_max_),               \
+        },                                                  \
     }
 
-#define DEFINE_PROFILE_CPU(type_name, misa_mxl_max, initfn) \
+#define DEFINE_PROFILE_CPU(type_name, misa_mxl_max_, initfn) \
     {                                                       \
         .name = (type_name),                                \
         .parent = TYPE_RISCV_BARE_CPU,                      \
         .instance_init = (initfn),                          \
         .class_init = riscv_cpu_class_init,                 \
-        .class_data = GUINT_TO_POINTER(misa_mxl_max)        \
+        .class_data = &(const RISCVCPUDef) {                \
+             .misa_mxl_max = (misa_mxl_max_),               \
+        },                                                  \
     }
 
 static const TypeInfo riscv_cpu_type_infos[] = {
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 16/35] target/riscv: store RISCVCPUDef struct directly in the class
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (14 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 15/35] target/riscv: introduce RISCVCPUDef Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 17/35] target/riscv: merge riscv_cpu_class_init with the class_base function Paolo Bonzini
                   ` (19 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

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.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 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     |  2 +-
 target/riscv/tcg/tcg-cpu.c | 10 +++++-----
 target/riscv/translate.c   |  2 +-
 8 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9de3f716ea6..d2d4db95c17 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -554,7 +554,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 765b9e2b1ab..828a867be39 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 6e92fbb9928..22e3a2211ed 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -356,7 +356,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
@@ -1047,7 +1047,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) {
@@ -1449,7 +1449,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,
@@ -1543,7 +1543,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:
@@ -3070,12 +3070,24 @@ static void riscv_cpu_common_class_init(ObjectClass *c, const void *data)
     device_class_set_props(dc, riscv_cpu_properties);
 }
 
+static void riscv_cpu_class_base_init(ObjectClass *c, const 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, const 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);
 }
 
@@ -3226,6 +3238,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_register_gdb_regs_for_features(CPUState *cs)
                                  ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs),
                                  0);
     }
-    switch (mcc->misa_mxl_max) {
+    switch (mcc->def->misa_mxl_max) {
     case MXL_RV32:
         gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
                                  riscv_gdb_set_virtual,
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 82f97286360..e77f612af35 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -2086,22 +2086,19 @@ static void kvm_cpu_accel_register_types(void)
 }
 type_init(kvm_cpu_accel_register_types);
 
-static void riscv_host_cpu_class_init(ObjectClass *c, const void *data)
-{
-    RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
-
-#if defined(TARGET_RISCV32)
-    mcc->misa_mxl_max = MXL_RV32;
-#elif defined(TARGET_RISCV64)
-    mcc->misa_mxl_max = MXL_RV64;
-#endif
-}
-
 static const TypeInfo riscv_kvm_cpu_type_infos[] = {
     {
         .name = TYPE_RISCV_CPU_HOST,
         .parent = TYPE_RISCV_CPU,
-        .class_init = riscv_host_cpu_class_init,
+#if defined(TARGET_RISCV32)
+        .class_data = &(const RISCVCPUDef) {
+            .misa_mxl_max = MXL_RV32,
+        },
+#elif defined(TARGET_RISCV64)
+        .class_data = &(const RISCVCPUDef) {
+            .misa_mxl_max = MXL_RV64,
+        },
+#endif
     }
 };
 
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index a1f70cc9556..c97e9ce9df1 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -170,7 +170,7 @@ static bool rv128_needed(void *opaque)
 {
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(opaque);
 
-    return mcc->misa_mxl_max == MXL_RV128;
+    return mcc->def->misa_mxl_max == MXL_RV128;
 }
 
 static const VMStateDescription vmstate_rv128 = {
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index ab8659f3044..305912b8dd3 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -691,7 +691,7 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         return;
     }
 
-    if (mcc->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
+    if (mcc->def->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
         error_setg(errp, "Zcf extension is only relevant to RV32");
         return;
     }
@@ -788,7 +788,7 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         return;
     }
 
-    if (mcc->misa_mxl_max == MXL_RV32 && cpu->cfg.ext_svukte) {
+    if (mcc->def->misa_mxl_max == MXL_RV32 && cpu->cfg.ext_svukte) {
         error_setg(errp, "svukte is not supported for RV32");
         return;
     }
@@ -1026,7 +1026,7 @@ static void cpu_enable_zc_implied_rules(RISCVCPU *cpu)
         cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcmp), true);
         cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcmt), true);
 
-        if (riscv_has_ext(env, RVF) && mcc->misa_mxl_max == MXL_RV32) {
+        if (riscv_has_ext(env, RVF) && mcc->def->misa_mxl_max == MXL_RV32) {
             cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcf), true);
         }
     }
@@ -1035,7 +1035,7 @@ static void cpu_enable_zc_implied_rules(RISCVCPU *cpu)
     if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) {
         cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zca), true);
 
-        if (riscv_has_ext(env, RVF) && mcc->misa_mxl_max == MXL_RV32) {
+        if (riscv_has_ext(env, RVF) && mcc->def->misa_mxl_max == MXL_RV32) {
             cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcf), true);
         }
 
@@ -1161,7 +1161,7 @@ static bool riscv_tcg_cpu_realize(CPUState *cs, Error **errp)
 #ifndef CONFIG_USER_ONLY
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
 
-    if (mcc->misa_mxl_max >= MXL_RV128 && qemu_tcg_mttcg_enabled()) {
+    if (mcc->def->misa_mxl_max >= MXL_RV128 && qemu_tcg_mttcg_enabled()) {
         /* Missing 128-bit aligned atomics */
         error_setg(errp,
                    "128-bit RISC-V currently does not work with Multi "
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0d4f7d601c9..d7a6de02df5 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1276,7 +1276,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s;
     ctx->vstart_eq_zero = FIELD_EX32(tb_flags, TB_FLAGS, VSTART_EQ_ZERO);
     ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
-    ctx->misa_mxl_max = mcc->misa_mxl_max;
+    ctx->misa_mxl_max = mcc->def->misa_mxl_max;
     ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
     ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
     ctx->cs = cs;
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 17/35] target/riscv: merge riscv_cpu_class_init with the class_base function
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (15 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 16/35] target/riscv: store RISCVCPUDef struct directly in the class Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 18/35] target/riscv: move RISCVCPUConfig fields to a header file Paolo Bonzini
                   ` (18 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

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.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 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 22e3a2211ed..334791eebdf 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -3080,15 +3080,18 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
     } else {
         mcc->def = g_new0(RISCVCPUDef, 1);
     }
-}
 
-static void riscv_cpu_class_init(ObjectClass *c, const 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,
@@ -3188,7 +3191,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 = &(const RISCVCPUDef) {                \
              .misa_mxl_max = (misa_mxl_max_),               \
         },                                                  \
@@ -3199,7 +3201,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 = &(const RISCVCPUDef) {                \
              .misa_mxl_max = (misa_mxl_max_),               \
         },                                                  \
@@ -3210,7 +3211,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 = &(const RISCVCPUDef) {                \
              .misa_mxl_max = (misa_mxl_max_),               \
         },                                                  \
@@ -3221,7 +3221,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 = &(const RISCVCPUDef) {                \
              .misa_mxl_max = (misa_mxl_max_),               \
         },                                                  \
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 18/35] target/riscv: move RISCVCPUConfig fields to a header file
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (16 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 17/35] target/riscv: merge riscv_cpu_class_init with the class_base function Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 19/35] target/riscv: include default value in cpu_cfg_fields.h.inc Paolo Bonzini
                   ` (17 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

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.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu_cfg.h            | 163 +---------------------------
 target/riscv/cpu_cfg_fields.h.inc | 170 ++++++++++++++++++++++++++++++
 2 files changed, 173 insertions(+), 160 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 8fa73c8a07d..e9bf75730a6 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -22,166 +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_smctr;
-    bool ext_ssctr;
-    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;
-
-    /* Always enabled for TCG if has_priv_1_11 */
-    bool ext_ziccrse;
-
-    /* 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;
-
-    int8_t max_satp_mode;
+#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 00000000000..cb86bfc5dc3
--- /dev/null
+++ b/target/riscv/cpu_cfg_fields.h.inc
@@ -0,0 +1,170 @@
+/*
+ * Required definitions before including this file:
+ *
+ * #define BOOL_FIELD(x)
+ * #define TYPED_FIELD(type, x)
+ */
+
+BOOL_FIELD(ext_zba)
+BOOL_FIELD(ext_zbb)
+BOOL_FIELD(ext_zbc)
+BOOL_FIELD(ext_zbkb)
+BOOL_FIELD(ext_zbkc)
+BOOL_FIELD(ext_zbkx)
+BOOL_FIELD(ext_zbs)
+BOOL_FIELD(ext_zca)
+BOOL_FIELD(ext_zcb)
+BOOL_FIELD(ext_zcd)
+BOOL_FIELD(ext_zce)
+BOOL_FIELD(ext_zcf)
+BOOL_FIELD(ext_zcmp)
+BOOL_FIELD(ext_zcmt)
+BOOL_FIELD(ext_zk)
+BOOL_FIELD(ext_zkn)
+BOOL_FIELD(ext_zknd)
+BOOL_FIELD(ext_zkne)
+BOOL_FIELD(ext_zknh)
+BOOL_FIELD(ext_zkr)
+BOOL_FIELD(ext_zks)
+BOOL_FIELD(ext_zksed)
+BOOL_FIELD(ext_zksh)
+BOOL_FIELD(ext_zkt)
+BOOL_FIELD(ext_zifencei)
+BOOL_FIELD(ext_zicntr)
+BOOL_FIELD(ext_zicsr)
+BOOL_FIELD(ext_zicbom)
+BOOL_FIELD(ext_zicbop)
+BOOL_FIELD(ext_zicboz)
+BOOL_FIELD(ext_zicfilp)
+BOOL_FIELD(ext_zicfiss)
+BOOL_FIELD(ext_zicond)
+BOOL_FIELD(ext_zihintntl)
+BOOL_FIELD(ext_zihintpause)
+BOOL_FIELD(ext_zihpm)
+BOOL_FIELD(ext_zimop)
+BOOL_FIELD(ext_zcmop)
+BOOL_FIELD(ext_ztso)
+BOOL_FIELD(ext_smstateen)
+BOOL_FIELD(ext_sstc)
+BOOL_FIELD(ext_smcdeleg)
+BOOL_FIELD(ext_ssccfg)
+BOOL_FIELD(ext_smcntrpmf)
+BOOL_FIELD(ext_smcsrind)
+BOOL_FIELD(ext_sscsrind)
+BOOL_FIELD(ext_ssdbltrp)
+BOOL_FIELD(ext_smdbltrp)
+BOOL_FIELD(ext_svadu)
+BOOL_FIELD(ext_svinval)
+BOOL_FIELD(ext_svnapot)
+BOOL_FIELD(ext_svpbmt)
+BOOL_FIELD(ext_svvptc)
+BOOL_FIELD(ext_svukte)
+BOOL_FIELD(ext_zdinx)
+BOOL_FIELD(ext_zaamo)
+BOOL_FIELD(ext_zacas)
+BOOL_FIELD(ext_zama16b)
+BOOL_FIELD(ext_zabha)
+BOOL_FIELD(ext_zalrsc)
+BOOL_FIELD(ext_zawrs)
+BOOL_FIELD(ext_zfa)
+BOOL_FIELD(ext_zfbfmin)
+BOOL_FIELD(ext_zfh)
+BOOL_FIELD(ext_zfhmin)
+BOOL_FIELD(ext_zfinx)
+BOOL_FIELD(ext_zhinx)
+BOOL_FIELD(ext_zhinxmin)
+BOOL_FIELD(ext_zve32f)
+BOOL_FIELD(ext_zve32x)
+BOOL_FIELD(ext_zve64f)
+BOOL_FIELD(ext_zve64d)
+BOOL_FIELD(ext_zve64x)
+BOOL_FIELD(ext_zvbb)
+BOOL_FIELD(ext_zvbc)
+BOOL_FIELD(ext_zvkb)
+BOOL_FIELD(ext_zvkg)
+BOOL_FIELD(ext_zvkned)
+BOOL_FIELD(ext_zvknha)
+BOOL_FIELD(ext_zvknhb)
+BOOL_FIELD(ext_zvksed)
+BOOL_FIELD(ext_zvksh)
+BOOL_FIELD(ext_zvkt)
+BOOL_FIELD(ext_zvkn)
+BOOL_FIELD(ext_zvknc)
+BOOL_FIELD(ext_zvkng)
+BOOL_FIELD(ext_zvks)
+BOOL_FIELD(ext_zvksc)
+BOOL_FIELD(ext_zvksg)
+BOOL_FIELD(ext_zmmul)
+BOOL_FIELD(ext_zvfbfmin)
+BOOL_FIELD(ext_zvfbfwma)
+BOOL_FIELD(ext_zvfh)
+BOOL_FIELD(ext_zvfhmin)
+BOOL_FIELD(ext_smaia)
+BOOL_FIELD(ext_ssaia)
+BOOL_FIELD(ext_smctr)
+BOOL_FIELD(ext_ssctr)
+BOOL_FIELD(ext_sscofpmf)
+BOOL_FIELD(ext_smepmp)
+BOOL_FIELD(ext_smrnmi)
+BOOL_FIELD(ext_ssnpm)
+BOOL_FIELD(ext_smnpm)
+BOOL_FIELD(ext_smmpm)
+BOOL_FIELD(ext_sspm)
+BOOL_FIELD(ext_supm)
+BOOL_FIELD(rvv_ta_all_1s)
+BOOL_FIELD(rvv_ma_all_1s)
+BOOL_FIELD(rvv_vl_half_avl)
+/* Named features  */
+BOOL_FIELD(ext_svade)
+BOOL_FIELD(ext_zic64b)
+BOOL_FIELD(ext_ssstateen)
+BOOL_FIELD(ext_sha)
+
+/*
+ * Always 'true' booleans for named features
+ * TCG always implement/can't be user disabled,
+ * based on spec version.
+ */
+BOOL_FIELD(has_priv_1_13)
+BOOL_FIELD(has_priv_1_12)
+BOOL_FIELD(has_priv_1_11)
+
+/* Always enabled for TCG if has_priv_1_11 */
+BOOL_FIELD(ext_ziccrse)
+
+/* Vendor-specific custom extensions */
+BOOL_FIELD(ext_xtheadba)
+BOOL_FIELD(ext_xtheadbb)
+BOOL_FIELD(ext_xtheadbs)
+BOOL_FIELD(ext_xtheadcmo)
+BOOL_FIELD(ext_xtheadcondmov)
+BOOL_FIELD(ext_xtheadfmemidx)
+BOOL_FIELD(ext_xtheadfmv)
+BOOL_FIELD(ext_xtheadmac)
+BOOL_FIELD(ext_xtheadmemidx)
+BOOL_FIELD(ext_xtheadmempair)
+BOOL_FIELD(ext_xtheadsync)
+BOOL_FIELD(ext_XVentanaCondOps)
+
+BOOL_FIELD(mmu)
+BOOL_FIELD(pmp)
+BOOL_FIELD(debug)
+BOOL_FIELD(misa_w)
+
+BOOL_FIELD(short_isa_string)
+
+TYPED_FIELD(uint32_t, mvendorid)
+TYPED_FIELD(uint64_t, marchid)
+TYPED_FIELD(uint64_t, mimpid)
+
+TYPED_FIELD(uint32_t, pmu_mask)
+TYPED_FIELD(uint16_t, vlenb)
+TYPED_FIELD(uint16_t, elen)
+TYPED_FIELD(uint16_t, cbom_blocksize)
+TYPED_FIELD(uint16_t, cbop_blocksize)
+TYPED_FIELD(uint16_t, cboz_blocksize)
+
+TYPED_FIELD(int8_t, max_satp_mode)
+
+#undef BOOL_FIELD
+#undef TYPED_FIELD
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 19/35] target/riscv: include default value in cpu_cfg_fields.h.inc
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (17 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 18/35] target/riscv: move RISCVCPUConfig fields to a header file Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 20/35] target/riscv: add more RISCVCPUDef fields Paolo Bonzini
                   ` (16 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

In preparation for adding a function to merge two RISCVCPUConfigs
(pulling values from the parent if they are not overridden) annotate
cpu_cfg_fields.h.inc with the default value of the fields.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu_cfg.h            |  2 +-
 target/riscv/cpu_cfg_fields.h.inc | 22 +++++++++++-----------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index e9bf75730a6..aa28dc8d7e6 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -23,7 +23,7 @@
 
 struct RISCVCPUConfig {
 #define BOOL_FIELD(x) bool x;
-#define TYPED_FIELD(type, x) type x;
+#define TYPED_FIELD(type, x, default) type x;
 #include "cpu_cfg_fields.h.inc"
 };
 
diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc
index cb86bfc5dc3..59f134a4192 100644
--- a/target/riscv/cpu_cfg_fields.h.inc
+++ b/target/riscv/cpu_cfg_fields.h.inc
@@ -2,7 +2,7 @@
  * Required definitions before including this file:
  *
  * #define BOOL_FIELD(x)
- * #define TYPED_FIELD(type, x)
+ * #define TYPED_FIELD(type, x, default)
  */
 
 BOOL_FIELD(ext_zba)
@@ -153,18 +153,18 @@ BOOL_FIELD(misa_w)
 
 BOOL_FIELD(short_isa_string)
 
-TYPED_FIELD(uint32_t, mvendorid)
-TYPED_FIELD(uint64_t, marchid)
-TYPED_FIELD(uint64_t, mimpid)
+TYPED_FIELD(uint32_t, mvendorid, 0)
+TYPED_FIELD(uint64_t, marchid, 0)
+TYPED_FIELD(uint64_t, mimpid, 0)
 
-TYPED_FIELD(uint32_t, pmu_mask)
-TYPED_FIELD(uint16_t, vlenb)
-TYPED_FIELD(uint16_t, elen)
-TYPED_FIELD(uint16_t, cbom_blocksize)
-TYPED_FIELD(uint16_t, cbop_blocksize)
-TYPED_FIELD(uint16_t, cboz_blocksize)
+TYPED_FIELD(uint32_t, pmu_mask, 0)
+TYPED_FIELD(uint16_t, vlenb, 0)
+TYPED_FIELD(uint16_t, elen, 0)
+TYPED_FIELD(uint16_t, cbom_blocksize, 0)
+TYPED_FIELD(uint16_t, cbop_blocksize, 0)
+TYPED_FIELD(uint16_t, cboz_blocksize, 0)
 
-TYPED_FIELD(int8_t, max_satp_mode)
+TYPED_FIELD(int8_t, max_satp_mode, -1)
 
 #undef BOOL_FIELD
 #undef TYPED_FIELD
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 20/35] target/riscv: add more RISCVCPUDef fields
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (18 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 19/35] target/riscv: include default value in cpu_cfg_fields.h.inc Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 21/35] target/riscv: convert abstract CPU classes to RISCVCPUDef Paolo Bonzini
                   ` (15 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Allow using RISCVCPUDef to replicate all the logic of custom .instance_init
functions.  To simulate inheritance, merge the child's RISCVCPUDef with
the parent and then finally move it to the CPUState at the end of
TYPE_RISCV_CPU's own instance_init function.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.h         |  4 ++++
 target/riscv/cpu.c         | 42 +++++++++++++++++++++++++++++++++++++-
 target/riscv/kvm/kvm-cpu.c |  6 ++++++
 3 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d2d4db95c17..29b01e9aa86 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -540,6 +540,10 @@ struct ArchCPU {
 
 typedef struct RISCVCPUDef {
     RISCVMXL misa_mxl_max;  /* max mxl for this cpu */
+    uint32_t misa_ext;
+    int priv_spec;
+    int32_t vext_spec;
+    RISCVCPUConfig cfg;
 } RISCVCPUDef;
 
 /**
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 334791eebdf..634216870ed 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -73,6 +73,13 @@ bool riscv_cpu_option_set(const char *optname)
     return g_hash_table_contains(general_user_opts, optname);
 }
 
+static void riscv_cpu_cfg_merge(RISCVCPUConfig *dest, const RISCVCPUConfig *src)
+{
+#define BOOL_FIELD(x) dest->x |= src->x;
+#define TYPED_FIELD(type, x, default_) if (src->x != default_) dest->x = src->x;
+#include "cpu_cfg_fields.h.inc"
+}
+
 #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
     {#_name, _min_ver, CPU_CFG_OFFSET(_prop)}
 
@@ -434,7 +441,7 @@ const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit)
 }
 
 static void set_satp_mode_max_supported(RISCVCPU *cpu,
-                                        uint8_t satp_mode)
+                                        int satp_mode)
 {
     bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
     const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
@@ -1479,6 +1486,16 @@ static void riscv_cpu_init(Object *obj)
     cpu->cfg.cboz_blocksize = 64;
     cpu->env.vext_ver = VEXT_VERSION_1_00_0;
     cpu->cfg.max_satp_mode = -1;
+
+    env->misa_ext_mask = env->misa_ext = mcc->def->misa_ext;
+    riscv_cpu_cfg_merge(&cpu->cfg, &mcc->def->cfg);
+
+    if (mcc->def->priv_spec != RISCV_PROFILE_ATTR_UNUSED) {
+        cpu->env.priv_ver = mcc->def->priv_spec;
+    }
+    if (mcc->def->vext_spec != RISCV_PROFILE_ATTR_UNUSED) {
+        cpu->env.vext_ver = mcc->def->vext_spec;
+    }
 }
 
 static void riscv_bare_cpu_init(Object *obj)
@@ -3087,6 +3104,17 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
             assert(def->misa_mxl_max <= MXL_RV128);
             mcc->def->misa_mxl_max = def->misa_mxl_max;
         }
+        if (def->priv_spec != RISCV_PROFILE_ATTR_UNUSED) {
+            assert(def->priv_spec <= PRIV_VERSION_LATEST);
+            mcc->def->priv_spec = def->priv_spec;
+        }
+        if (def->vext_spec != RISCV_PROFILE_ATTR_UNUSED) {
+            assert(def->vext_spec != 0);
+            mcc->def->vext_spec = def->vext_spec;
+        }
+        mcc->def->misa_ext |= def->misa_ext;
+
+        riscv_cpu_cfg_merge(&mcc->def->cfg, &def->cfg);
     }
 
     if (!object_class_is_abstract(c)) {
@@ -3193,6 +3221,9 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
         .instance_init = (initfn),                          \
         .class_data = &(const RISCVCPUDef) {                \
              .misa_mxl_max = (misa_mxl_max_),               \
+             .priv_spec = RISCV_PROFILE_ATTR_UNUSED,        \
+             .vext_spec = RISCV_PROFILE_ATTR_UNUSED,        \
+             .cfg.max_satp_mode = -1,                       \
         },                                                  \
     }
 
@@ -3203,6 +3234,9 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
         .instance_init = (initfn),                          \
         .class_data = &(const RISCVCPUDef) {                \
              .misa_mxl_max = (misa_mxl_max_),               \
+             .priv_spec = RISCV_PROFILE_ATTR_UNUSED,        \
+             .vext_spec = RISCV_PROFILE_ATTR_UNUSED,        \
+             .cfg.max_satp_mode = -1,                       \
         },                                                  \
     }
 
@@ -3213,6 +3247,9 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
         .instance_init = (initfn),                          \
         .class_data = &(const RISCVCPUDef) {                \
              .misa_mxl_max = (misa_mxl_max_),               \
+             .priv_spec = RISCV_PROFILE_ATTR_UNUSED,        \
+             .vext_spec = RISCV_PROFILE_ATTR_UNUSED,        \
+             .cfg.max_satp_mode = -1,                       \
         },                                                  \
     }
 
@@ -3223,6 +3260,9 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
         .instance_init = (initfn),                          \
         .class_data = &(const RISCVCPUDef) {                \
              .misa_mxl_max = (misa_mxl_max_),               \
+             .priv_spec = RISCV_PROFILE_ATTR_UNUSED,        \
+             .vext_spec = RISCV_PROFILE_ATTR_UNUSED,        \
+             .cfg.max_satp_mode = -1,                       \
         },                                                  \
     }
 
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index e77f612af35..efb41fac53e 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -2093,10 +2093,16 @@ static const TypeInfo riscv_kvm_cpu_type_infos[] = {
 #if defined(TARGET_RISCV32)
         .class_data = &(const RISCVCPUDef) {
             .misa_mxl_max = MXL_RV32,
+            .priv_spec = RISCV_PROFILE_ATTR_UNUSED,
+            .vext_spec = RISCV_PROFILE_ATTR_UNUSED,
+            .cfg.max_satp_mode = -1,
         },
 #elif defined(TARGET_RISCV64)
         .class_data = &(const RISCVCPUDef) {
             .misa_mxl_max = MXL_RV64,
+            .priv_spec = RISCV_PROFILE_ATTR_UNUSED,
+            .vext_spec = RISCV_PROFILE_ATTR_UNUSED,
+            .cfg.max_satp_mode = -1,
         },
 #endif
     }
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 21/35] target/riscv: convert abstract CPU classes to RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (19 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 20/35] target/riscv: add more RISCVCPUDef fields Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 22/35] target/riscv: convert profile CPU models " Paolo Bonzini
                   ` (14 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Start from the top of the hierarchy: dynamic and vendor CPUs are just
markers, whereas bare CPUs can have their instance_init function
replaced by RISCVCPUDef.

The only difference is that the maximum supported SATP mode has to
be specified separately for 32-bit and 64-bit modes.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.h |  1 +
 target/riscv/cpu.c | 93 ++++++++++++++++++++++------------------------
 2 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 29b01e9aa86..f3d70afb866 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -544,6 +544,7 @@ typedef struct RISCVCPUDef {
     int priv_spec;
     int32_t vext_spec;
     RISCVCPUConfig cfg;
+    bool bare;
 } RISCVCPUDef;
 
 /**
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 634216870ed..7dcaf72fc14 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1474,8 +1474,8 @@ static void riscv_cpu_init(Object *obj)
      * for all CPUs. Each accelerator will decide what to do when
      * users disable them.
      */
-    RISCV_CPU(obj)->cfg.ext_zicntr = true;
-    RISCV_CPU(obj)->cfg.ext_zihpm = true;
+    RISCV_CPU(obj)->cfg.ext_zicntr = !mcc->def->bare;
+    RISCV_CPU(obj)->cfg.ext_zihpm = !mcc->def->bare;
 
     /* Default values for non-bool cpu properties */
     cpu->cfg.pmu_mask = MAKE_64BIT_MASK(3, 16);
@@ -1498,36 +1498,6 @@ static void riscv_cpu_init(Object *obj)
     }
 }
 
-static void riscv_bare_cpu_init(Object *obj)
-{
-    RISCVCPU *cpu = RISCV_CPU(obj);
-
-    /*
-     * Bare CPUs do not inherit the timer and performance
-     * counters from the parent class (see riscv_cpu_init()
-     * for info on why the parent enables them).
-     *
-     * Users have to explicitly enable these counters for
-     * bare CPUs.
-     */
-    cpu->cfg.ext_zicntr = false;
-    cpu->cfg.ext_zihpm = false;
-
-    /* Set to QEMU's first supported priv version */
-    cpu->env.priv_ver = PRIV_VERSION_1_10_0;
-
-    /*
-     * Support all available satp_mode settings. The default
-     * value will be set to MBARE if the user doesn't set
-     * satp_mode manually (see set_satp_mode_default()).
-     */
-#ifndef CONFIG_USER_ONLY
-    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
-}
-
 typedef struct misa_ext_info {
     const char *name;
     const char *description;
@@ -3100,6 +3070,7 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
 
     if (data) {
         const RISCVCPUDef *def = data;
+        mcc->def->bare |= def->bare;
         if (def->misa_mxl_max) {
             assert(def->misa_mxl_max <= MXL_RV128);
             mcc->def->misa_mxl_max = def->misa_mxl_max;
@@ -3253,6 +3224,19 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
         },                                                  \
     }
 
+#define DEFINE_ABSTRACT_RISCV_CPU(type_name, parent_type_name, ...) \
+    {                                                       \
+        .name = (type_name),                                \
+        .parent = (parent_type_name),                       \
+        .abstract = true,                                   \
+        .class_data = &(const RISCVCPUDef) {                \
+             .priv_spec = RISCV_PROFILE_ATTR_UNUSED,        \
+             .vext_spec = RISCV_PROFILE_ATTR_UNUSED,        \
+             .cfg.max_satp_mode = -1,                       \
+             __VA_ARGS__                                    \
+        },                                                  \
+    }
+
 #define DEFINE_PROFILE_CPU(type_name, misa_mxl_max_, initfn) \
     {                                                       \
         .name = (type_name),                                \
@@ -3279,22 +3263,35 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .class_init = riscv_cpu_common_class_init,
         .class_base_init = riscv_cpu_class_base_init,
     },
-    {
-        .name = TYPE_RISCV_DYNAMIC_CPU,
-        .parent = TYPE_RISCV_CPU,
-        .abstract = true,
-    },
-    {
-        .name = TYPE_RISCV_VENDOR_CPU,
-        .parent = TYPE_RISCV_CPU,
-        .abstract = true,
-    },
-    {
-        .name = TYPE_RISCV_BARE_CPU,
-        .parent = TYPE_RISCV_CPU,
-        .instance_init = riscv_bare_cpu_init,
-        .abstract = true,
-    },
+
+    DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_DYNAMIC_CPU, TYPE_RISCV_CPU),
+    DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_VENDOR_CPU, TYPE_RISCV_CPU),
+    DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_BARE_CPU, TYPE_RISCV_CPU,
+        /*
+         * Bare CPUs do not inherit the timer and performance
+         * counters from the parent class (see riscv_cpu_init()
+         * for info on why the parent enables them).
+         *
+         * Users have to explicitly enable these counters for
+         * bare CPUs.
+         */
+        .bare = true,
+
+        /* Set to QEMU's first supported priv version */
+        .priv_spec = PRIV_VERSION_1_10_0,
+
+        /*
+         * Support all available satp_mode settings. By default
+         * only MBARE will be available if the user doesn't enable
+         * a mode manually (see riscv_cpu_satp_mode_finalize()).
+         */
+#ifdef TARGET_RISCV32
+        .cfg.max_satp_mode = VM_1_10_SV32,
+#else
+        .cfg.max_satp_mode = VM_1_10_SV57,
+#endif
+    ),
+
 #if defined(TARGET_RISCV32)
     DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX,       MXL_RV32,  riscv_max_cpu_init),
 #elif defined(TARGET_RISCV64)
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 22/35] target/riscv: convert profile CPU models to RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (20 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 21/35] target/riscv: convert abstract CPU classes to RISCVCPUDef Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 23/35] target/riscv: convert bare " Paolo Bonzini
                   ` (13 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Profile CPUs reuse the instance_init function for bare CPUs; make them
proper subclasses instead.  Enabling a profile is now done based on the
RISCVCPUDef struct: even though there is room for only one in RISCVCPUDef,
subclasses check that the parent class's profile is enabled through the
parent profile mechanism.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.h |  1 +
 target/riscv/cpu.c | 85 +++++++++++++++++++++++++---------------------
 2 files changed, 48 insertions(+), 38 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f3d70afb866..ed88adef452 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -540,6 +540,7 @@ struct ArchCPU {
 
 typedef struct RISCVCPUDef {
     RISCVMXL misa_mxl_max;  /* max mxl for this cpu */
+    RISCVCPUProfile *profile;
     uint32_t misa_ext;
     int priv_spec;
     int32_t vext_spec;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7dcaf72fc14..54fce767657 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1487,6 +1487,10 @@ static void riscv_cpu_init(Object *obj)
     cpu->env.vext_ver = VEXT_VERSION_1_00_0;
     cpu->cfg.max_satp_mode = -1;
 
+    if (mcc->def->profile) {
+        mcc->def->profile->enabled = true;
+    }
+
     env->misa_ext_mask = env->misa_ext = mcc->def->misa_ext;
     riscv_cpu_cfg_merge(&cpu->cfg, &mcc->def->cfg);
 
@@ -2959,36 +2963,6 @@ static const Property riscv_cpu_properties[] = {
     DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false),
 };
 
-#if defined(TARGET_RISCV64)
-static void rva22u64_profile_cpu_init(Object *obj)
-{
-    rv64i_bare_cpu_init(obj);
-
-    RVA22U64.enabled = true;
-}
-
-static void rva22s64_profile_cpu_init(Object *obj)
-{
-    rv64i_bare_cpu_init(obj);
-
-    RVA22S64.enabled = true;
-}
-
-static void rva23u64_profile_cpu_init(Object *obj)
-{
-    rv64i_bare_cpu_init(obj);
-
-    RVA23U64.enabled = true;
-}
-
-static void rva23s64_profile_cpu_init(Object *obj)
-{
-    rv64i_bare_cpu_init(obj);
-
-    RVA23S64.enabled = true;
-}
-#endif
-
 static const gchar *riscv_gdb_arch_name(CPUState *cs)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
@@ -3057,6 +3031,32 @@ static void riscv_cpu_common_class_init(ObjectClass *c, const void *data)
     device_class_set_props(dc, riscv_cpu_properties);
 }
 
+static bool profile_extends(RISCVCPUProfile *trial, RISCVCPUProfile *parent)
+{
+    RISCVCPUProfile *curr;
+    if (!parent) {
+        return true;
+    }
+
+    curr = trial;
+    while (curr) {
+        if (curr == parent) {
+            return true;
+        }
+        curr = curr->u_parent;
+    }
+
+    curr = trial;
+    while (curr) {
+        if (curr == parent) {
+            return true;
+        }
+        curr = curr->s_parent;
+    }
+
+    return false;
+}
+
 static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
 {
     RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
@@ -3071,6 +3071,11 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
     if (data) {
         const RISCVCPUDef *def = data;
         mcc->def->bare |= def->bare;
+        if (def->profile) {
+            assert(profile_extends(def->profile, mcc->def->profile));
+            assert(mcc->def->bare);
+            mcc->def->profile = def->profile;
+        }
         if (def->misa_mxl_max) {
             assert(def->misa_mxl_max <= MXL_RV128);
             mcc->def->misa_mxl_max = def->misa_mxl_max;
@@ -3237,19 +3242,22 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
         },                                                  \
     }
 
-#define DEFINE_PROFILE_CPU(type_name, misa_mxl_max_, initfn) \
+#define DEFINE_RISCV_CPU(type_name, parent_type_name, ...)  \
     {                                                       \
         .name = (type_name),                                \
-        .parent = TYPE_RISCV_BARE_CPU,                      \
-        .instance_init = (initfn),                          \
+        .parent = (parent_type_name),                       \
         .class_data = &(const RISCVCPUDef) {                \
-             .misa_mxl_max = (misa_mxl_max_),               \
              .priv_spec = RISCV_PROFILE_ATTR_UNUSED,        \
              .vext_spec = RISCV_PROFILE_ATTR_UNUSED,        \
              .cfg.max_satp_mode = -1,                       \
+             __VA_ARGS__                                    \
         },                                                  \
     }
 
+#define DEFINE_PROFILE_CPU(type_name, parent_type_name, profile_)    \
+    DEFINE_RISCV_CPU(type_name, parent_type_name,             \
+        .profile = &(profile_))
+
 static const TypeInfo riscv_cpu_type_infos[] = {
     {
         .name = TYPE_RISCV_CPU,
@@ -3328,10 +3336,11 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 #endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
     DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I,        MXL_RV64,  rv64i_bare_cpu_init),
     DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64E,        MXL_RV64,  rv64e_bare_cpu_init),
-    DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64,  MXL_RV64,  rva22u64_profile_cpu_init),
-    DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22S64,  MXL_RV64,  rva22s64_profile_cpu_init),
-    DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23U64,  MXL_RV64,  rva23u64_profile_cpu_init),
-    DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23S64,  MXL_RV64,  rva23s64_profile_cpu_init),
+
+    DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64,  TYPE_RISCV_CPU_RV64I,  RVA22U64),
+    DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22S64,  TYPE_RISCV_CPU_RV64I,  RVA22S64),
+    DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23U64,  TYPE_RISCV_CPU_RV64I,  RVA23U64),
+    DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23S64,  TYPE_RISCV_CPU_RV64I,  RVA23S64),
 #endif /* TARGET_RISCV64 */
 };
 
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 23/35] target/riscv: convert bare CPU models to RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (21 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 22/35] target/riscv: convert profile CPU models " Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 24/35] target/riscv: convert dynamic " Paolo Bonzini
                   ` (12 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.c | 58 ++++++++++++++--------------------------------
 1 file changed, 17 insertions(+), 41 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 54fce767657..8b82a1b7b33 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -732,18 +732,6 @@ static void rv128_base_cpu_init(Object *obj)
 }
 #endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
 
-static void rv64i_bare_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    riscv_cpu_set_misa_ext(env, RVI);
-}
-
-static void rv64e_bare_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    riscv_cpu_set_misa_ext(env, RVE);
-}
-
 #endif /* !TARGET_RISCV64 */
 
 #if defined(TARGET_RISCV32) || \
@@ -836,18 +824,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
     cpu->cfg.ext_zicsr = true;
     cpu->cfg.pmp = true;
 }
-
-static void rv32i_bare_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    riscv_cpu_set_misa_ext(env, RVI);
-}
-
-static void rv32e_bare_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    riscv_cpu_set_misa_ext(env, RVE);
-}
 #endif
 
 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
@@ -3216,19 +3192,6 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
         },                                                  \
     }
 
-#define DEFINE_BARE_CPU(type_name, misa_mxl_max_, initfn)   \
-    {                                                       \
-        .name = (type_name),                                \
-        .parent = TYPE_RISCV_BARE_CPU,                      \
-        .instance_init = (initfn),                          \
-        .class_data = &(const RISCVCPUDef) {                \
-             .misa_mxl_max = (misa_mxl_max_),               \
-             .priv_spec = RISCV_PROFILE_ATTR_UNUSED,        \
-             .vext_spec = RISCV_PROFILE_ATTR_UNUSED,        \
-             .cfg.max_satp_mode = -1,                       \
-        },                                                  \
-    }
-
 #define DEFINE_ABSTRACT_RISCV_CPU(type_name, parent_type_name, ...) \
     {                                                       \
         .name = (type_name),                                \
@@ -3313,8 +3276,15 @@ static const TypeInfo riscv_cpu_type_infos[] = {
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E31, MXL_RV32,  rv32_sifive_e_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E34, MXL_RV32,  rv32_imafcu_nommu_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U34, MXL_RV32,  rv32_sifive_u_cpu_init),
-    DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV32I,        MXL_RV32,  rv32i_bare_cpu_init),
-    DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV32E,        MXL_RV32,  rv32e_bare_cpu_init),
+
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RV32I, TYPE_RISCV_BARE_CPU,
+        .misa_mxl_max = MXL_RV32,
+        .misa_ext = RVI
+    ),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RV32E, TYPE_RISCV_BARE_CPU,
+        .misa_mxl_max = MXL_RV32,
+        .misa_ext = RVE
+    ),
 #endif
 
 #if (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
@@ -3334,8 +3304,14 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
     DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128,   MXL_RV128, rv128_base_cpu_init),
 #endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
-    DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I,        MXL_RV64,  rv64i_bare_cpu_init),
-    DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64E,        MXL_RV64,  rv64e_bare_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RV64I, TYPE_RISCV_BARE_CPU,
+        .misa_mxl_max = MXL_RV64,
+        .misa_ext = RVI
+    ),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RV64E, TYPE_RISCV_BARE_CPU,
+        .misa_mxl_max = MXL_RV64,
+        .misa_ext = RVE
+    ),
 
     DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64,  TYPE_RISCV_CPU_RV64I,  RVA22U64),
     DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22S64,  TYPE_RISCV_CPU_RV64I,  RVA22S64),
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 24/35] target/riscv: convert dynamic CPU models to RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (22 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 23/35] target/riscv: convert bare " Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 25/35] target/riscv: convert SiFive E " Paolo Bonzini
                   ` (11 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.c | 113 +++++++++++++--------------------------------
 1 file changed, 31 insertions(+), 82 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 8b82a1b7b33..2b26f23bd0a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -485,38 +485,7 @@ static void set_satp_mode_default_map(RISCVCPU *cpu)
 }
 #endif
 
-static void riscv_max_cpu_init(Object *obj)
-{
-    RISCVCPU *cpu = RISCV_CPU(obj);
-    CPURISCVState *env = &cpu->env;
-
-    cpu->cfg.mmu = true;
-    cpu->cfg.pmp = true;
-
-    env->priv_ver = PRIV_VERSION_LATEST;
-#ifndef CONFIG_USER_ONLY
-    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
-}
-
 #if defined(TARGET_RISCV64)
-static void rv64_base_cpu_init(Object *obj)
-{
-    RISCVCPU *cpu = RISCV_CPU(obj);
-    CPURISCVState *env = &cpu->env;
-
-    cpu->cfg.mmu = true;
-    cpu->cfg.pmp = true;
-
-    /* Set latest version of privileged specification */
-    env->priv_ver = PRIV_VERSION_LATEST;
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
-#endif
-}
-
 static void rv64_sifive_u_cpu_init(Object *obj)
 {
     RISCVCPU *cpu = RISCV_CPU(obj);
@@ -717,41 +686,11 @@ static void rv64_xiangshan_nanhu_cpu_init(Object *obj)
 #endif
 }
 
-#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
-static void rv128_base_cpu_init(Object *obj)
-{
-    RISCVCPU *cpu = RISCV_CPU(obj);
-    CPURISCVState *env = &cpu->env;
-
-    cpu->cfg.mmu = true;
-    cpu->cfg.pmp = true;
-
-    /* Set latest version of privileged specification */
-    env->priv_ver = PRIV_VERSION_LATEST;
-    set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
-}
-#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
-
 #endif /* !TARGET_RISCV64 */
 
 #if defined(TARGET_RISCV32) || \
     (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
 
-static void rv32_base_cpu_init(Object *obj)
-{
-    RISCVCPU *cpu = RISCV_CPU(obj);
-    CPURISCVState *env = &cpu->env;
-
-    cpu->cfg.mmu = true;
-    cpu->cfg.pmp = true;
-
-    /* Set latest version of privileged specification */
-    env->priv_ver = PRIV_VERSION_LATEST;
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
-#endif
-}
-
 static void rv32_sifive_u_cpu_init(Object *obj)
 {
     RISCVCPU *cpu = RISCV_CPU(obj);
@@ -3166,19 +3105,6 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
 }
 #endif
 
-#define DEFINE_DYNAMIC_CPU(type_name, misa_mxl_max_, initfn) \
-    {                                                       \
-        .name = (type_name),                                \
-        .parent = TYPE_RISCV_DYNAMIC_CPU,                   \
-        .instance_init = (initfn),                          \
-        .class_data = &(const RISCVCPUDef) {                \
-             .misa_mxl_max = (misa_mxl_max_),               \
-             .priv_spec = RISCV_PROFILE_ATTR_UNUSED,        \
-             .vext_spec = RISCV_PROFILE_ATTR_UNUSED,        \
-             .cfg.max_satp_mode = -1,                       \
-        },                                                  \
-    }
-
 #define DEFINE_VENDOR_CPU(type_name, misa_mxl_max_, initfn) \
     {                                                       \
         .name = (type_name),                                \
@@ -3235,7 +3161,12 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .class_base_init = riscv_cpu_class_base_init,
     },
 
-    DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_DYNAMIC_CPU, TYPE_RISCV_CPU),
+    DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_DYNAMIC_CPU, TYPE_RISCV_CPU,
+        .cfg.mmu = true,
+        .cfg.pmp = true,
+        .priv_spec = PRIV_VERSION_LATEST,
+    ),
+
     DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_VENDOR_CPU, TYPE_RISCV_CPU),
     DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_BARE_CPU, TYPE_RISCV_CPU,
         /*
@@ -3263,15 +3194,23 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 #endif
     ),
 
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_MAX, TYPE_RISCV_DYNAMIC_CPU,
 #if defined(TARGET_RISCV32)
-    DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX,       MXL_RV32,  riscv_max_cpu_init),
+        .misa_mxl_max = MXL_RV32,
+        .cfg.max_satp_mode = VM_1_10_SV32,
 #elif defined(TARGET_RISCV64)
-    DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX,       MXL_RV64,  riscv_max_cpu_init),
+        .misa_mxl_max = MXL_RV64,
+        .cfg.max_satp_mode = VM_1_10_SV57,
 #endif
+    ),
 
 #if defined(TARGET_RISCV32) || \
     (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
-    DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32,    MXL_RV32,  rv32_base_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE32, TYPE_RISCV_DYNAMIC_CPU,
+        .cfg.max_satp_mode = VM_1_10_SV32,
+        .misa_mxl_max = MXL_RV32,
+    ),
+
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_IBEX,       MXL_RV32,  rv32_ibex_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E31, MXL_RV32,  rv32_sifive_e_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E34, MXL_RV32,  rv32_imafcu_nommu_cpu_init),
@@ -3288,11 +3227,18 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 #endif
 
 #if (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
-    DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX32,     MXL_RV32,  riscv_max_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_MAX32, TYPE_RISCV_DYNAMIC_CPU,
+        .cfg.max_satp_mode = VM_1_10_SV32,
+        .misa_mxl_max = MXL_RV32,
+    ),
 #endif
 
 #if defined(TARGET_RISCV64)
-    DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE64,    MXL_RV64,  rv64_base_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE64, TYPE_RISCV_DYNAMIC_CPU,
+        .cfg.max_satp_mode = VM_1_10_SV57,
+        .misa_mxl_max = MXL_RV64,
+    ),
+
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E51, MXL_RV64,  rv64_sifive_e_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U54, MXL_RV64,  rv64_sifive_u_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SHAKTI_C,   MXL_RV64,  rv64_sifive_u_cpu_init),
@@ -3302,8 +3248,11 @@ static const TypeInfo riscv_cpu_type_infos[] = {
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_XIANGSHAN_NANHU,
                                                  MXL_RV64, rv64_xiangshan_nanhu_cpu_init),
 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
-    DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128,   MXL_RV128, rv128_base_cpu_init),
-#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE128, TYPE_RISCV_DYNAMIC_CPU,
+        .cfg.max_satp_mode = VM_1_10_SV57,
+        .misa_mxl_max = MXL_RV128,
+    ),
+#endif /* CONFIG_TCG */
     DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RV64I, TYPE_RISCV_BARE_CPU,
         .misa_mxl_max = MXL_RV64,
         .misa_ext = RVI
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 25/35] target/riscv: convert SiFive E CPU models to RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (23 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 24/35] target/riscv: convert dynamic " Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 26/35] target/riscv: convert ibex " Paolo Bonzini
                   ` (10 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu-qom.h |  1 +
 target/riscv/cpu.c     | 74 ++++++++++++------------------------------
 2 files changed, 21 insertions(+), 54 deletions(-)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 4cfdb74891e..0f9be15e47b 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -44,6 +44,7 @@
 #define TYPE_RISCV_CPU_RVA23S64         RISCV_CPU_TYPE_NAME("rva23s64")
 #define TYPE_RISCV_CPU_IBEX             RISCV_CPU_TYPE_NAME("lowrisc-ibex")
 #define TYPE_RISCV_CPU_SHAKTI_C         RISCV_CPU_TYPE_NAME("shakti-c")
+#define TYPE_RISCV_CPU_SIFIVE_E         RISCV_CPU_TYPE_NAME("sifive-e")
 #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
 #define TYPE_RISCV_CPU_SIFIVE_E34       RISCV_CPU_TYPE_NAME("sifive-e34")
 #define TYPE_RISCV_CPU_SIFIVE_E51       RISCV_CPU_TYPE_NAME("sifive-e51")
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 2b26f23bd0a..17ad8b2ca1f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -503,23 +503,6 @@ static void rv64_sifive_u_cpu_init(Object *obj)
     cpu->cfg.pmp = true;
 }
 
-static void rv64_sifive_e_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    RISCVCPU *cpu = RISCV_CPU(obj);
-
-    riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVC | RVU);
-    env->priv_ver = PRIV_VERSION_1_10_0;
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
-#endif
-
-    /* inherited from parent obj via riscv_cpu_init() */
-    cpu->cfg.ext_zifencei = true;
-    cpu->cfg.ext_zicsr = true;
-    cpu->cfg.pmp = true;
-}
-
 static void rv64_thead_c906_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -708,23 +691,6 @@ static void rv32_sifive_u_cpu_init(Object *obj)
     cpu->cfg.pmp = true;
 }
 
-static void rv32_sifive_e_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    RISCVCPU *cpu = RISCV_CPU(obj);
-
-    riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVC | RVU);
-    env->priv_ver = PRIV_VERSION_1_10_0;
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
-#endif
-
-    /* inherited from parent obj via riscv_cpu_init() */
-    cpu->cfg.ext_zifencei = true;
-    cpu->cfg.ext_zicsr = true;
-    cpu->cfg.pmp = true;
-}
-
 static void rv32_ibex_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -746,23 +712,6 @@ static void rv32_ibex_cpu_init(Object *obj)
     cpu->cfg.ext_zbc = true;
     cpu->cfg.ext_zbs = true;
 }
-
-static void rv32_imafcu_nommu_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    RISCVCPU *cpu = RISCV_CPU(obj);
-
-    riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVF | RVC | RVU);
-    env->priv_ver = PRIV_VERSION_1_10_0;
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
-#endif
-
-    /* inherited from parent obj via riscv_cpu_init() */
-    cpu->cfg.ext_zifencei = true;
-    cpu->cfg.ext_zicsr = true;
-    cpu->cfg.pmp = true;
-}
 #endif
 
 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
@@ -3204,6 +3153,15 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 #endif
     ),
 
+    DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E, TYPE_RISCV_VENDOR_CPU,
+        .misa_ext = RVI | RVM | RVA | RVC | RVU,
+        .priv_spec = PRIV_VERSION_1_10_0,
+        .cfg.max_satp_mode = VM_1_10_MBARE,
+        .cfg.ext_zifencei = true,
+        .cfg.ext_zicsr = true,
+        .cfg.pmp = true
+    ),
+
 #if defined(TARGET_RISCV32) || \
     (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
     DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE32, TYPE_RISCV_DYNAMIC_CPU,
@@ -3212,8 +3170,14 @@ static const TypeInfo riscv_cpu_type_infos[] = {
     ),
 
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_IBEX,       MXL_RV32,  rv32_ibex_cpu_init),
-    DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E31, MXL_RV32,  rv32_sifive_e_cpu_init),
-    DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E34, MXL_RV32,  rv32_imafcu_nommu_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E31, TYPE_RISCV_CPU_SIFIVE_E,
+        .misa_mxl_max = MXL_RV32
+    ),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E34, TYPE_RISCV_CPU_SIFIVE_E,
+        .misa_mxl_max = MXL_RV32,
+        .misa_ext = RVF,  /* IMAFCU */
+    ),
+
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U34, MXL_RV32,  rv32_sifive_u_cpu_init),
 
     DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RV32I, TYPE_RISCV_BARE_CPU,
@@ -3239,7 +3203,9 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .misa_mxl_max = MXL_RV64,
     ),
 
-    DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E51, MXL_RV64,  rv64_sifive_e_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E51, TYPE_RISCV_CPU_SIFIVE_E,
+        .misa_mxl_max = MXL_RV64
+    ),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U54, MXL_RV64,  rv64_sifive_u_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SHAKTI_C,   MXL_RV64,  rv64_sifive_u_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, MXL_RV64,  rv64_thead_c906_cpu_init),
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 26/35] target/riscv: convert ibex CPU models to RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (24 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 25/35] target/riscv: convert SiFive E " Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 27/35] target/riscv: convert SiFive U " Paolo Bonzini
                   ` (9 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.c | 39 ++++++++++++++++-----------------------
 1 file changed, 16 insertions(+), 23 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 17ad8b2ca1f..689c33916e0 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -690,28 +690,6 @@ static void rv32_sifive_u_cpu_init(Object *obj)
     cpu->cfg.mmu = true;
     cpu->cfg.pmp = true;
 }
-
-static void rv32_ibex_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    RISCVCPU *cpu = RISCV_CPU(obj);
-
-    riscv_cpu_set_misa_ext(env, RVI | RVM | RVC | RVU);
-    env->priv_ver = PRIV_VERSION_1_12_0;
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
-#endif
-    /* inherited from parent obj via riscv_cpu_init() */
-    cpu->cfg.ext_zifencei = true;
-    cpu->cfg.ext_zicsr = true;
-    cpu->cfg.pmp = true;
-    cpu->cfg.ext_smepmp = true;
-
-    cpu->cfg.ext_zba = true;
-    cpu->cfg.ext_zbb = true;
-    cpu->cfg.ext_zbc = true;
-    cpu->cfg.ext_zbs = true;
-}
 #endif
 
 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
@@ -3169,7 +3147,22 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .misa_mxl_max = MXL_RV32,
     ),
 
-    DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_IBEX,       MXL_RV32,  rv32_ibex_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_IBEX, TYPE_RISCV_VENDOR_CPU,
+        .misa_mxl_max = MXL_RV32,
+        .misa_ext = RVI | RVM | RVC | RVU,
+        .priv_spec = PRIV_VERSION_1_12_0,
+        .cfg.max_satp_mode = VM_1_10_MBARE,
+        .cfg.ext_zifencei = true,
+        .cfg.ext_zicsr = true,
+        .cfg.pmp = true,
+        .cfg.ext_smepmp = true,
+
+        .cfg.ext_zba = true,
+        .cfg.ext_zbb = true,
+        .cfg.ext_zbc = true,
+        .cfg.ext_zbs = true
+    ),
+
     DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E31, TYPE_RISCV_CPU_SIFIVE_E,
         .misa_mxl_max = MXL_RV32
     ),
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 27/35] target/riscv: convert SiFive U models to RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (25 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 26/35] target/riscv: convert ibex " Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 28/35] target/riscv: th: make CSR insertion test a bit more intuitive Paolo Bonzini
                   ` (8 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu-qom.h |  1 +
 target/riscv/cpu.c     | 79 +++++++++++++++++++-----------------------
 2 files changed, 37 insertions(+), 43 deletions(-)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 0f9be15e47b..1ee05eb393d 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -48,6 +48,7 @@
 #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
 #define TYPE_RISCV_CPU_SIFIVE_E34       RISCV_CPU_TYPE_NAME("sifive-e34")
 #define TYPE_RISCV_CPU_SIFIVE_E51       RISCV_CPU_TYPE_NAME("sifive-e51")
+#define TYPE_RISCV_CPU_SIFIVE_U         RISCV_CPU_TYPE_NAME("sifive-u")
 #define TYPE_RISCV_CPU_SIFIVE_U34       RISCV_CPU_TYPE_NAME("sifive-u34")
 #define TYPE_RISCV_CPU_SIFIVE_U54       RISCV_CPU_TYPE_NAME("sifive-u54")
 #define TYPE_RISCV_CPU_THEAD_C906       RISCV_CPU_TYPE_NAME("thead-c906")
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 689c33916e0..01b028653a3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -440,8 +440,8 @@ const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit)
     g_assert_not_reached();
 }
 
-static void set_satp_mode_max_supported(RISCVCPU *cpu,
-                                        int satp_mode)
+static void __attribute__((unused))
+set_satp_mode_max_supported(RISCVCPU *cpu, int satp_mode)
 {
     bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
     const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
@@ -486,23 +486,6 @@ static void set_satp_mode_default_map(RISCVCPU *cpu)
 #endif
 
 #if defined(TARGET_RISCV64)
-static void rv64_sifive_u_cpu_init(Object *obj)
-{
-    RISCVCPU *cpu = RISCV_CPU(obj);
-    CPURISCVState *env = &cpu->env;
-    riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-    env->priv_ver = PRIV_VERSION_1_10_0;
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
-#endif
-
-    /* inherited from parent obj via riscv_cpu_init() */
-    cpu->cfg.ext_zifencei = true;
-    cpu->cfg.ext_zicsr = true;
-    cpu->cfg.mmu = true;
-    cpu->cfg.pmp = true;
-}
-
 static void rv64_thead_c906_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -671,27 +654,6 @@ static void rv64_xiangshan_nanhu_cpu_init(Object *obj)
 
 #endif /* !TARGET_RISCV64 */
 
-#if defined(TARGET_RISCV32) || \
-    (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
-
-static void rv32_sifive_u_cpu_init(Object *obj)
-{
-    RISCVCPU *cpu = RISCV_CPU(obj);
-    CPURISCVState *env = &cpu->env;
-    riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-    env->priv_ver = PRIV_VERSION_1_10_0;
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
-#endif
-
-    /* inherited from parent obj via riscv_cpu_init() */
-    cpu->cfg.ext_zifencei = true;
-    cpu->cfg.ext_zicsr = true;
-    cpu->cfg.mmu = true;
-    cpu->cfg.pmp = true;
-}
-#endif
-
 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
 {
     ObjectClass *oc;
@@ -2921,6 +2883,17 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
         if (def->misa_mxl_max) {
             assert(def->misa_mxl_max <= MXL_RV128);
             mcc->def->misa_mxl_max = def->misa_mxl_max;
+
+#ifndef CONFIG_USER_ONLY
+            /*
+             * Hack to simplify CPU class hierarchies that include both 32- and
+             * 64-bit models: reduce SV39/48/57/64 to SV32 for 32-bit models.
+             */
+            if (mcc->def->misa_mxl_max == MXL_RV32 &&
+                !valid_vm_1_10_32[mcc->def->cfg.max_satp_mode]) {
+                mcc->def->cfg.max_satp_mode = VM_1_10_SV32;
+            }
+#endif
         }
         if (def->priv_spec != RISCV_PROFILE_ATTR_UNUSED) {
             assert(def->priv_spec <= PRIV_VERSION_LATEST);
@@ -3140,6 +3113,17 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .cfg.pmp = true
     ),
 
+    DEFINE_ABSTRACT_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_U, TYPE_RISCV_VENDOR_CPU,
+        .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU,
+        .priv_spec = PRIV_VERSION_1_10_0,
+
+        .cfg.max_satp_mode = VM_1_10_SV39,
+        .cfg.ext_zifencei = true,
+        .cfg.ext_zicsr = true,
+        .cfg.mmu = true,
+        .cfg.pmp = true
+    ),
+
 #if defined(TARGET_RISCV32) || \
     (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
     DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE32, TYPE_RISCV_DYNAMIC_CPU,
@@ -3171,7 +3155,9 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .misa_ext = RVF,  /* IMAFCU */
     ),
 
-    DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U34, MXL_RV32,  rv32_sifive_u_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_U34, TYPE_RISCV_CPU_SIFIVE_U,
+        .misa_mxl_max = MXL_RV32,
+    ),
 
     DEFINE_RISCV_CPU(TYPE_RISCV_CPU_RV32I, TYPE_RISCV_BARE_CPU,
         .misa_mxl_max = MXL_RV32,
@@ -3199,8 +3185,15 @@ static const TypeInfo riscv_cpu_type_infos[] = {
     DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_E51, TYPE_RISCV_CPU_SIFIVE_E,
         .misa_mxl_max = MXL_RV64
     ),
-    DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U54, MXL_RV64,  rv64_sifive_u_cpu_init),
-    DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SHAKTI_C,   MXL_RV64,  rv64_sifive_u_cpu_init),
+
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SIFIVE_U54, TYPE_RISCV_CPU_SIFIVE_U,
+        .misa_mxl_max = MXL_RV64,
+    ),
+
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_SHAKTI_C, TYPE_RISCV_CPU_SIFIVE_U,
+        .misa_mxl_max = MXL_RV64,
+    ),
+
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, MXL_RV64,  rv64_thead_c906_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_TT_ASCALON, MXL_RV64,  rv64_tt_ascalon_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1,  MXL_RV64,  rv64_veyron_v1_cpu_init),
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 28/35] target/riscv: th: make CSR insertion test a bit more intuitive
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (26 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 27/35] target/riscv: convert SiFive U " Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 29/35] target/riscv: generalize custom CSR functionality Paolo Bonzini
                   ` (7 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

In preparation for generalizing the custom CSR functionality,
make the test return bool instead of int.  Make the insertion_test
optional, too.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/th_csr.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
index 6c970d4e813..969a9fe3c80 100644
--- a/target/riscv/th_csr.c
+++ b/target/riscv/th_csr.c
@@ -29,7 +29,7 @@
 
 typedef struct {
     int csrno;
-    int (*insertion_test)(RISCVCPU *cpu);
+    bool (*insertion_test)(RISCVCPU *cpu);
     riscv_csr_operations csr_ops;
 } riscv_csr;
 
@@ -42,13 +42,9 @@ static RISCVException smode(CPURISCVState *env, int csrno)
     return RISCV_EXCP_ILLEGAL_INST;
 }
 
-static int test_thead_mvendorid(RISCVCPU *cpu)
+static bool test_thead_mvendorid(RISCVCPU *cpu)
 {
-    if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
-        return -1;
-    }
-
-    return 0;
+    return cpu->cfg.mvendorid == THEAD_VENDOR_ID;
 }
 
 static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
@@ -66,13 +62,12 @@ static riscv_csr th_csr_list[] = {
         .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
     }
 };
-
 void th_register_custom_csrs(RISCVCPU *cpu)
 {
     for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
         int csrno = th_csr_list[i].csrno;
         riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
-        if (!th_csr_list[i].insertion_test(cpu)) {
+        if (!th_csr_list[i].insertion_test || th_csr_list[i].insertion_test(cpu)) {
             riscv_set_csr_ops(csrno, csr_ops);
         }
     }
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 29/35] target/riscv: generalize custom CSR functionality
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (27 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 28/35] target/riscv: th: make CSR insertion test a bit more intuitive Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 30/35] target/riscv: convert THead C906 to RISCVCPUDef Paolo Bonzini
                   ` (6 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

While at it, constify it so that the RISCVCSR array in RISCVCPUDef
can also be const.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.h    | 15 ++++++++++++---
 target/riscv/cpu.c    | 25 ++++++++++++++++++++++++-
 target/riscv/csr.c    |  2 +-
 target/riscv/th_csr.c | 21 +++------------------
 4 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ed88adef452..229ade9ed91 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -538,6 +538,8 @@ struct ArchCPU {
     const GPtrArray *decoders;
 };
 
+typedef struct RISCVCSR RISCVCSR;
+
 typedef struct RISCVCPUDef {
     RISCVMXL misa_mxl_max;  /* max mxl for this cpu */
     RISCVCPUProfile *profile;
@@ -546,6 +548,7 @@ typedef struct RISCVCPUDef {
     int32_t vext_spec;
     RISCVCPUConfig cfg;
     bool bare;
+    const RISCVCSR *custom_csrs;
 } RISCVCPUDef;
 
 /**
@@ -893,6 +896,12 @@ typedef struct {
     uint32_t min_priv_ver;
 } riscv_csr_operations;
 
+struct RISCVCSR {
+    int csrno;
+    bool (*insertion_test)(RISCVCPU *cpu);
+    riscv_csr_operations csr_ops;
+};
+
 /* CSR function table constants */
 enum {
     CSR_TABLE_SIZE = 0x1000
@@ -947,7 +956,7 @@ extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
 extern const bool valid_vm_1_10_32[], valid_vm_1_10_64[];
 
 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
-void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
+void riscv_set_csr_ops(int csrno, const riscv_csr_operations *ops);
 
 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
 
@@ -956,8 +965,8 @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
 
 const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
 
-/* Implemented in th_csr.c */
-void th_register_custom_csrs(RISCVCPU *cpu);
+/* In th_csr.c */
+extern const RISCVCSR th_csr_list[];
 
 const char *priv_spec_to_str(int priv_version);
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 01b028653a3..12f4bc41514 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -485,6 +485,19 @@ static void set_satp_mode_default_map(RISCVCPU *cpu)
 }
 #endif
 
+#ifndef CONFIG_USER_ONLY
+static void riscv_register_custom_csrs(RISCVCPU *cpu, const RISCVCSR *csr_list)
+{
+    for (size_t i = 0; csr_list[i].csr_ops.name; i++) {
+        int csrno = csr_list[i].csrno;
+        const riscv_csr_operations *csr_ops = &csr_list[i].csr_ops;
+        if (!csr_list[i].insertion_test || csr_list[i].insertion_test(cpu)) {
+            riscv_set_csr_ops(csrno, csr_ops);
+        }
+    }
+}
+#endif
+
 #if defined(TARGET_RISCV64)
 static void rv64_thead_c906_cpu_init(Object *obj)
 {
@@ -511,7 +524,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
     cpu->cfg.mvendorid = THEAD_VENDOR_ID;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_SV39);
-    th_register_custom_csrs(cpu);
+    riscv_register_custom_csrs(cpu, th_csr_list);
 #endif
 
     /* inherited from parent obj via riscv_cpu_init() */
@@ -1304,6 +1317,11 @@ static void riscv_cpu_init(Object *obj)
     if (mcc->def->vext_spec != RISCV_PROFILE_ATTR_UNUSED) {
         cpu->env.vext_ver = mcc->def->vext_spec;
     }
+#ifndef CONFIG_USER_ONLY
+    if (mcc->def->custom_csrs) {
+        riscv_register_custom_csrs(cpu, mcc->def->custom_csrs);
+    }
+#endif
 }
 
 typedef struct misa_ext_info {
@@ -2906,6 +2924,11 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
         mcc->def->misa_ext |= def->misa_ext;
 
         riscv_cpu_cfg_merge(&mcc->def->cfg, &def->cfg);
+
+        if (def->custom_csrs) {
+            assert(!mcc->def->custom_csrs);
+            mcc->def->custom_csrs = def->custom_csrs;
+        }
     }
 
     if (!object_class_is_abstract(c)) {
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9843fd21914..fb149721691 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -40,7 +40,7 @@ void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
     *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
 }
 
-void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
+void riscv_set_csr_ops(int csrno, const riscv_csr_operations *ops)
 {
     csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
 }
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
index 969a9fe3c80..49eb7bbab5f 100644
--- a/target/riscv/th_csr.c
+++ b/target/riscv/th_csr.c
@@ -27,12 +27,6 @@
 #define TH_SXSTATUS_MAEE        BIT(21)
 #define TH_SXSTATUS_THEADISAEE  BIT(22)
 
-typedef struct {
-    int csrno;
-    bool (*insertion_test)(RISCVCPU *cpu);
-    riscv_csr_operations csr_ops;
-} riscv_csr;
-
 static RISCVException smode(CPURISCVState *env, int csrno)
 {
     if (riscv_has_ext(env, RVS)) {
@@ -55,20 +49,11 @@ static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
     return RISCV_EXCP_NONE;
 }
 
-static riscv_csr th_csr_list[] = {
+const RISCVCSR th_csr_list[] = {
     {
         .csrno = CSR_TH_SXSTATUS,
         .insertion_test = test_thead_mvendorid,
         .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
-    }
+    },
+    { }
 };
-void th_register_custom_csrs(RISCVCPU *cpu)
-{
-    for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
-        int csrno = th_csr_list[i].csrno;
-        riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
-        if (!th_csr_list[i].insertion_test || th_csr_list[i].insertion_test(cpu)) {
-            riscv_set_csr_ops(csrno, csr_ops);
-        }
-    }
-}
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 30/35] target/riscv: convert THead C906 to RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (28 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 29/35] target/riscv: generalize custom CSR functionality Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 31/35] target/riscv: convert TT Ascalon " Paolo Bonzini
                   ` (5 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.c | 61 +++++++++++++++++++++-------------------------
 1 file changed, 28 insertions(+), 33 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 12f4bc41514..5d2ccf647dd 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -499,38 +499,6 @@ static void riscv_register_custom_csrs(RISCVCPU *cpu, const RISCVCSR *csr_list)
 #endif
 
 #if defined(TARGET_RISCV64)
-static void rv64_thead_c906_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    RISCVCPU *cpu = RISCV_CPU(obj);
-
-    riscv_cpu_set_misa_ext(env, RVG | RVC | RVS | RVU);
-    env->priv_ver = PRIV_VERSION_1_11_0;
-
-    cpu->cfg.ext_zfa = true;
-    cpu->cfg.ext_zfh = true;
-    cpu->cfg.mmu = true;
-    cpu->cfg.ext_xtheadba = true;
-    cpu->cfg.ext_xtheadbb = true;
-    cpu->cfg.ext_xtheadbs = true;
-    cpu->cfg.ext_xtheadcmo = true;
-    cpu->cfg.ext_xtheadcondmov = true;
-    cpu->cfg.ext_xtheadfmemidx = true;
-    cpu->cfg.ext_xtheadmac = true;
-    cpu->cfg.ext_xtheadmemidx = true;
-    cpu->cfg.ext_xtheadmempair = true;
-    cpu->cfg.ext_xtheadsync = true;
-
-    cpu->cfg.mvendorid = THEAD_VENDOR_ID;
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(cpu, VM_1_10_SV39);
-    riscv_register_custom_csrs(cpu, th_csr_list);
-#endif
-
-    /* inherited from parent obj via riscv_cpu_init() */
-    cpu->cfg.pmp = true;
-}
-
 static void rv64_veyron_v1_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -3217,7 +3185,34 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .misa_mxl_max = MXL_RV64,
     ),
 
-    DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, MXL_RV64,  rv64_thead_c906_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_THEAD_C906, TYPE_RISCV_VENDOR_CPU,
+        .misa_mxl_max = MXL_RV64,
+        .misa_ext = RVG | RVC | RVS | RVU,
+        .priv_spec = PRIV_VERSION_1_11_0,
+
+        .cfg.ext_zfa = true,
+        .cfg.ext_zfh = true,
+        .cfg.mmu = true,
+        .cfg.ext_xtheadba = true,
+        .cfg.ext_xtheadbb = true,
+        .cfg.ext_xtheadbs = true,
+        .cfg.ext_xtheadcmo = true,
+        .cfg.ext_xtheadcondmov = true,
+        .cfg.ext_xtheadfmemidx = true,
+        .cfg.ext_xtheadmac = true,
+        .cfg.ext_xtheadmemidx = true,
+        .cfg.ext_xtheadmempair = true,
+        .cfg.ext_xtheadsync = true,
+        .cfg.pmp = true,
+
+        .cfg.mvendorid = THEAD_VENDOR_ID,
+
+        .cfg.max_satp_mode = VM_1_10_SV39,
+#ifndef CONFIG_USER_ONLY
+        .custom_csrs = th_csr_list,
+#endif
+    ),
+
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_TT_ASCALON, MXL_RV64,  rv64_tt_ascalon_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1,  MXL_RV64,  rv64_veyron_v1_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_XIANGSHAN_NANHU,
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 31/35] target/riscv: convert TT Ascalon to RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (29 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 30/35] target/riscv: convert THead C906 to RISCVCPUDef Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 32/35] target/riscv: convert Ventana V1 " Paolo Bonzini
                   ` (4 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.c | 127 +++++++++++++++++++++------------------------
 1 file changed, 60 insertions(+), 67 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5d2ccf647dd..48939adaafe 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -539,72 +539,6 @@ static void rv64_veyron_v1_cpu_init(Object *obj)
 #endif
 }
 
-/* Tenstorrent Ascalon */
-static void rv64_tt_ascalon_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    RISCVCPU *cpu = RISCV_CPU(obj);
-
-    riscv_cpu_set_misa_ext(env, RVG | RVC | RVS | RVU | RVH | RVV);
-    env->priv_ver = PRIV_VERSION_1_13_0;
-
-    /* Enable ISA extensions */
-    cpu->cfg.mmu = true;
-    cpu->cfg.vlenb = 256 >> 3;
-    cpu->cfg.elen = 64;
-    cpu->env.vext_ver = VEXT_VERSION_1_00_0;
-    cpu->cfg.rvv_ma_all_1s = true;
-    cpu->cfg.rvv_ta_all_1s = true;
-    cpu->cfg.misa_w = true;
-    cpu->cfg.pmp = true;
-    cpu->cfg.cbom_blocksize = 64;
-    cpu->cfg.cbop_blocksize = 64;
-    cpu->cfg.cboz_blocksize = 64;
-    cpu->cfg.ext_zic64b = true;
-    cpu->cfg.ext_zicbom = true;
-    cpu->cfg.ext_zicbop = true;
-    cpu->cfg.ext_zicboz = true;
-    cpu->cfg.ext_zicntr = true;
-    cpu->cfg.ext_zicond = true;
-    cpu->cfg.ext_zicsr = true;
-    cpu->cfg.ext_zifencei = true;
-    cpu->cfg.ext_zihintntl = true;
-    cpu->cfg.ext_zihintpause = true;
-    cpu->cfg.ext_zihpm = true;
-    cpu->cfg.ext_zimop = true;
-    cpu->cfg.ext_zawrs = true;
-    cpu->cfg.ext_zfa = true;
-    cpu->cfg.ext_zfbfmin = true;
-    cpu->cfg.ext_zfh = true;
-    cpu->cfg.ext_zfhmin = true;
-    cpu->cfg.ext_zcb = true;
-    cpu->cfg.ext_zcmop = true;
-    cpu->cfg.ext_zba = true;
-    cpu->cfg.ext_zbb = true;
-    cpu->cfg.ext_zbs = true;
-    cpu->cfg.ext_zkt = true;
-    cpu->cfg.ext_zvbb = true;
-    cpu->cfg.ext_zvbc = true;
-    cpu->cfg.ext_zvfbfmin = true;
-    cpu->cfg.ext_zvfbfwma = true;
-    cpu->cfg.ext_zvfh = true;
-    cpu->cfg.ext_zvfhmin = true;
-    cpu->cfg.ext_zvkng = true;
-    cpu->cfg.ext_smaia = true;
-    cpu->cfg.ext_smstateen = true;
-    cpu->cfg.ext_ssaia = true;
-    cpu->cfg.ext_sscofpmf = true;
-    cpu->cfg.ext_sstc = true;
-    cpu->cfg.ext_svade = true;
-    cpu->cfg.ext_svinval = true;
-    cpu->cfg.ext_svnapot = true;
-    cpu->cfg.ext_svpbmt = true;
-
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(cpu, VM_1_10_SV57);
-#endif
-}
-
 static void rv64_xiangshan_nanhu_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -3213,7 +3147,66 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 #endif
     ),
 
-    DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_TT_ASCALON, MXL_RV64,  rv64_tt_ascalon_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_TT_ASCALON, TYPE_RISCV_VENDOR_CPU,
+        .misa_mxl_max = MXL_RV64,
+        .misa_ext = RVG | RVC | RVS | RVU | RVH | RVV,
+        .priv_spec = PRIV_VERSION_1_13_0,
+        .vext_spec = VEXT_VERSION_1_00_0,
+
+        /* ISA extensions */
+        .cfg.mmu = true,
+        .cfg.vlenb = 256 >> 3,
+        .cfg.elen = 64,
+        .cfg.rvv_ma_all_1s = true,
+        .cfg.rvv_ta_all_1s = true,
+        .cfg.misa_w = true,
+        .cfg.pmp = true,
+        .cfg.cbom_blocksize = 64,
+        .cfg.cbop_blocksize = 64,
+        .cfg.cboz_blocksize = 64,
+        .cfg.ext_zic64b = true,
+        .cfg.ext_zicbom = true,
+        .cfg.ext_zicbop = true,
+        .cfg.ext_zicboz = true,
+        .cfg.ext_zicntr = true,
+        .cfg.ext_zicond = true,
+        .cfg.ext_zicsr = true,
+        .cfg.ext_zifencei = true,
+        .cfg.ext_zihintntl = true,
+        .cfg.ext_zihintpause = true,
+        .cfg.ext_zihpm = true,
+        .cfg.ext_zimop = true,
+        .cfg.ext_zawrs = true,
+        .cfg.ext_zfa = true,
+        .cfg.ext_zfbfmin = true,
+        .cfg.ext_zfh = true,
+        .cfg.ext_zfhmin = true,
+        .cfg.ext_zcb = true,
+        .cfg.ext_zcmop = true,
+        .cfg.ext_zba = true,
+        .cfg.ext_zbb = true,
+        .cfg.ext_zbs = true,
+        .cfg.ext_zkt = true,
+        .cfg.ext_zvbb = true,
+        .cfg.ext_zvbc = true,
+        .cfg.ext_zvfbfmin = true,
+        .cfg.ext_zvfbfwma = true,
+        .cfg.ext_zvfh = true,
+        .cfg.ext_zvfhmin = true,
+        .cfg.ext_zvkng = true,
+        .cfg.ext_smaia = true,
+        .cfg.ext_smstateen = true,
+        .cfg.ext_ssaia = true,
+        .cfg.ext_sscofpmf = true,
+        .cfg.ext_sstc = true,
+        .cfg.ext_svade = true,
+        .cfg.ext_svinval = true,
+        .cfg.ext_svnapot = true,
+        .cfg.ext_svpbmt = true,
+
+        .cfg.max_satp_mode = VM_1_10_SV57,
+    ),
+
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1,  MXL_RV64,  rv64_veyron_v1_cpu_init),
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_XIANGSHAN_NANHU,
                                                  MXL_RV64, rv64_xiangshan_nanhu_cpu_init),
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 32/35] target/riscv: convert Ventana V1 to RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (30 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 31/35] target/riscv: convert TT Ascalon " Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 33/35] target/riscv: convert Xiangshan Nanhu " Paolo Bonzini
                   ` (3 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.c | 75 ++++++++++++++++++++++------------------------
 1 file changed, 35 insertions(+), 40 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 48939adaafe..000fcc6a1d6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -499,45 +499,6 @@ static void riscv_register_custom_csrs(RISCVCPU *cpu, const RISCVCSR *csr_list)
 #endif
 
 #if defined(TARGET_RISCV64)
-static void rv64_veyron_v1_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    RISCVCPU *cpu = RISCV_CPU(obj);
-
-    riscv_cpu_set_misa_ext(env, RVG | RVC | RVS | RVU | RVH);
-    env->priv_ver = PRIV_VERSION_1_12_0;
-
-    /* Enable ISA extensions */
-    cpu->cfg.mmu = true;
-    cpu->cfg.ext_zifencei = true;
-    cpu->cfg.ext_zicsr = true;
-    cpu->cfg.pmp = true;
-    cpu->cfg.ext_zicbom = true;
-    cpu->cfg.cbom_blocksize = 64;
-    cpu->cfg.cboz_blocksize = 64;
-    cpu->cfg.ext_zicboz = true;
-    cpu->cfg.ext_smaia = true;
-    cpu->cfg.ext_ssaia = true;
-    cpu->cfg.ext_sscofpmf = true;
-    cpu->cfg.ext_sstc = true;
-    cpu->cfg.ext_svinval = true;
-    cpu->cfg.ext_svnapot = true;
-    cpu->cfg.ext_svpbmt = true;
-    cpu->cfg.ext_smstateen = true;
-    cpu->cfg.ext_zba = true;
-    cpu->cfg.ext_zbb = true;
-    cpu->cfg.ext_zbc = true;
-    cpu->cfg.ext_zbs = true;
-    cpu->cfg.ext_XVentanaCondOps = true;
-
-    cpu->cfg.mvendorid = VEYRON_V1_MVENDORID;
-    cpu->cfg.marchid = VEYRON_V1_MARCHID;
-    cpu->cfg.mimpid = VEYRON_V1_MIMPID;
-
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(cpu, VM_1_10_SV48);
-#endif
-}
 
 static void rv64_xiangshan_nanhu_cpu_init(Object *obj)
 {
@@ -3207,7 +3168,41 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .cfg.max_satp_mode = VM_1_10_SV57,
     ),
 
-    DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1,  MXL_RV64,  rv64_veyron_v1_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_VEYRON_V1, TYPE_RISCV_VENDOR_CPU,
+        .misa_mxl_max = MXL_RV64,
+        .misa_ext = RVG | RVC | RVS | RVU | RVH,
+        .priv_spec = PRIV_VERSION_1_12_0,
+
+        /* ISA extensions */
+        .cfg.mmu = true,
+        .cfg.ext_zifencei = true,
+        .cfg.ext_zicsr = true,
+        .cfg.pmp = true,
+        .cfg.ext_zicbom = true,
+        .cfg.cbom_blocksize = 64,
+        .cfg.cboz_blocksize = 64,
+        .cfg.ext_zicboz = true,
+        .cfg.ext_smaia = true,
+        .cfg.ext_ssaia = true,
+        .cfg.ext_sscofpmf = true,
+        .cfg.ext_sstc = true,
+        .cfg.ext_svinval = true,
+        .cfg.ext_svnapot = true,
+        .cfg.ext_svpbmt = true,
+        .cfg.ext_smstateen = true,
+        .cfg.ext_zba = true,
+        .cfg.ext_zbb = true,
+        .cfg.ext_zbc = true,
+        .cfg.ext_zbs = true,
+        .cfg.ext_XVentanaCondOps = true,
+
+        .cfg.mvendorid = VEYRON_V1_MVENDORID,
+        .cfg.marchid = VEYRON_V1_MARCHID,
+        .cfg.mimpid = VEYRON_V1_MIMPID,
+
+        .cfg.max_satp_mode = VM_1_10_SV48,
+    ),
+
     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_XIANGSHAN_NANHU,
                                                  MXL_RV64, rv64_xiangshan_nanhu_cpu_init),
 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 33/35] target/riscv: convert Xiangshan Nanhu to RISCVCPUDef
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (31 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 32/35] target/riscv: convert Ventana V1 " Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 34/35] target/riscv: remove .instance_post_init Paolo Bonzini
                   ` (2 subsequent siblings)
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.c | 80 +++++++++++++---------------------------------
 1 file changed, 23 insertions(+), 57 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 000fcc6a1d6..640aa958fd4 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -440,16 +440,6 @@ const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit)
     g_assert_not_reached();
 }
 
-static void __attribute__((unused))
-set_satp_mode_max_supported(RISCVCPU *cpu, int satp_mode)
-{
-    bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
-    const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
-
-    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);
@@ -498,38 +488,6 @@ static void riscv_register_custom_csrs(RISCVCPU *cpu, const RISCVCSR *csr_list)
 }
 #endif
 
-#if defined(TARGET_RISCV64)
-
-static void rv64_xiangshan_nanhu_cpu_init(Object *obj)
-{
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
-    RISCVCPU *cpu = RISCV_CPU(obj);
-
-    riscv_cpu_set_misa_ext(env, RVG | RVC | RVB | RVS | RVU);
-    env->priv_ver = PRIV_VERSION_1_12_0;
-
-    /* Enable ISA extensions */
-    cpu->cfg.ext_zbc = true;
-    cpu->cfg.ext_zbkb = true;
-    cpu->cfg.ext_zbkc = true;
-    cpu->cfg.ext_zbkx = true;
-    cpu->cfg.ext_zknd = true;
-    cpu->cfg.ext_zkne = true;
-    cpu->cfg.ext_zknh = true;
-    cpu->cfg.ext_zksed = true;
-    cpu->cfg.ext_zksh = true;
-    cpu->cfg.ext_svinval = true;
-
-    cpu->cfg.mmu = true;
-    cpu->cfg.pmp = true;
-
-#ifndef CONFIG_USER_ONLY
-    set_satp_mode_max_supported(cpu, VM_1_10_SV39);
-#endif
-}
-
-#endif /* !TARGET_RISCV64 */
-
 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
 {
     ObjectClass *oc;
@@ -2891,19 +2849,6 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
 }
 #endif
 
-#define DEFINE_VENDOR_CPU(type_name, misa_mxl_max_, initfn) \
-    {                                                       \
-        .name = (type_name),                                \
-        .parent = TYPE_RISCV_VENDOR_CPU,                    \
-        .instance_init = (initfn),                          \
-        .class_data = &(const RISCVCPUDef) {                \
-             .misa_mxl_max = (misa_mxl_max_),               \
-             .priv_spec = RISCV_PROFILE_ATTR_UNUSED,        \
-             .vext_spec = RISCV_PROFILE_ATTR_UNUSED,        \
-             .cfg.max_satp_mode = -1,                       \
-        },                                                  \
-    }
-
 #define DEFINE_ABSTRACT_RISCV_CPU(type_name, parent_type_name, ...) \
     {                                                       \
         .name = (type_name),                                \
@@ -3203,8 +3148,29 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .cfg.max_satp_mode = VM_1_10_SV48,
     ),
 
-    DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_XIANGSHAN_NANHU,
-                                                 MXL_RV64, rv64_xiangshan_nanhu_cpu_init),
+    DEFINE_RISCV_CPU(TYPE_RISCV_CPU_XIANGSHAN_NANHU, TYPE_RISCV_VENDOR_CPU,
+        .misa_mxl_max = MXL_RV64,
+        .misa_ext = RVG | RVC | RVB | RVS | RVU,
+        .priv_spec = PRIV_VERSION_1_12_0,
+
+        /* ISA extensions */
+        .cfg.ext_zbc = true,
+        .cfg.ext_zbkb = true,
+        .cfg.ext_zbkc = true,
+        .cfg.ext_zbkx = true,
+        .cfg.ext_zknd = true,
+        .cfg.ext_zkne = true,
+        .cfg.ext_zknh = true,
+        .cfg.ext_zksed = true,
+        .cfg.ext_zksh = true,
+        .cfg.ext_svinval = true,
+
+        .cfg.mmu = true,
+        .cfg.pmp = true,
+
+        .cfg.max_satp_mode = VM_1_10_SV39,
+    ),
+
 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
     DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE128, TYPE_RISCV_DYNAMIC_CPU,
         .cfg.max_satp_mode = VM_1_10_SV57,
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 34/35] target/riscv: remove .instance_post_init
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (32 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 33/35] target/riscv: convert Xiangshan Nanhu " Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-05-20 11:05 ` [PULL 35/35] qom: reverse order of instance_post_init calls Paolo Bonzini
  2025-05-21 14:06 ` [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Stefan Hajnoczi
  35 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alistair Francis

Unlike other uses of .instance_post_init, accel_cpu_instance_init()
*registers* properties, and therefore must be run before
device_post_init() which sets them to their values from -global.

In order to move all registration of properties to .instance_init,
call accel_cpu_instance_init() at the end of riscv_cpu_init().

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/riscv/cpu.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 640aa958fd4..629ac37501e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1083,11 +1083,6 @@ static bool riscv_cpu_is_dynamic(Object *cpu_obj)
     return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
 }
 
-static void riscv_cpu_post_init(Object *obj)
-{
-    accel_cpu_instance_init(CPU(obj));
-}
-
 static void riscv_cpu_init(Object *obj)
 {
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(obj);
@@ -1143,6 +1138,8 @@ static void riscv_cpu_init(Object *obj)
         riscv_register_custom_csrs(cpu, mcc->def->custom_csrs);
     }
 #endif
+
+    accel_cpu_instance_init(CPU(obj));
 }
 
 typedef struct misa_ext_info {
@@ -2885,7 +2882,6 @@ static const TypeInfo riscv_cpu_type_infos[] = {
         .instance_size = sizeof(RISCVCPU),
         .instance_align = __alignof(RISCVCPU),
         .instance_init = riscv_cpu_init,
-        .instance_post_init = riscv_cpu_post_init,
         .abstract = true,
         .class_size = sizeof(RISCVCPUClass),
         .class_init = riscv_cpu_common_class_init,
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (33 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 34/35] target/riscv: remove .instance_post_init Paolo Bonzini
@ 2025-05-20 11:05 ` Paolo Bonzini
  2025-06-23 16:56   ` [Regression] " Dongli Zhang
  2025-05-21 14:06 ` [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Stefan Hajnoczi
  35 siblings, 1 reply; 53+ messages in thread
From: Paolo Bonzini @ 2025-05-20 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Alistair Francis

Currently, the instance_post_init calls are performed from the leaf
class and all the way up to Object.  This is incorrect because the
leaf class cannot observe property values applied by the superclasses;
for example, a compat property will be set on a device *after*
the class's post_init callback has run.

In particular this makes it impossible for implementations of
accel_cpu_instance_init() to operate based on the actual values of
the properties, though it seems that cxl_dsp_instance_post_init and
rp_instance_post_init might have similar issues.

Follow instead the same order as instance_init, starting with Object
and running the child class's instance_post_init after the parent.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qom/object.h | 3 ++-
 qom/object.c         | 8 ++++----
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 1d5b0337242..26df6137b91 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -445,7 +445,8 @@ struct Object
  *   class will have already been initialized so the type is only responsible
  *   for initializing its own members.
  * @instance_post_init: This function is called to finish initialization of
- *   an object, after all @instance_init functions were called.
+ *   an object, after all @instance_init functions were called, as well as
+ *   @instance_post_init functions for the parent classes.
  * @instance_finalize: This function is called during object destruction.  This
  *   is called before the parent @instance_finalize function has been called.
  *   An object should only free the members that are unique to its type in this
diff --git a/qom/object.c b/qom/object.c
index 7b013f40a0c..1856bb36c74 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -431,13 +431,13 @@ static void object_init_with_type(Object *obj, TypeImpl *ti)
 
 static void object_post_init_with_type(Object *obj, TypeImpl *ti)
 {
-    if (ti->instance_post_init) {
-        ti->instance_post_init(obj);
-    }
-
     if (type_has_parent(ti)) {
         object_post_init_with_type(obj, type_get_parent(ti));
     }
+
+    if (ti->instance_post_init) {
+        ti->instance_post_init(obj);
+    }
 }
 
 bool object_apply_global_props(Object *obj, const GPtrArray *props,
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 53+ messages in thread

* Re: [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20
  2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
                   ` (34 preceding siblings ...)
  2025-05-20 11:05 ` [PULL 35/35] qom: reverse order of instance_post_init calls Paolo Bonzini
@ 2025-05-21 14:06 ` Stefan Hajnoczi
  35 siblings, 0 replies; 53+ messages in thread
From: Stefan Hajnoczi @ 2025-05-21 14:06 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 116 bytes --]

Applied, thanks.

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-05-20 11:05 ` [PULL 35/35] qom: reverse order of instance_post_init calls Paolo Bonzini
@ 2025-06-23 16:56   ` Dongli Zhang
  2025-06-24  8:57     ` Zhao Liu
  0 siblings, 1 reply; 53+ messages in thread
From: Dongli Zhang @ 2025-06-23 16:56 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: Philippe Mathieu-Daudé, Alistair Francis

This commit may broken the "vendor=" configuration.

For instance, the hypervisor CPU vendor is AMD.

I am going to use "-cpu Skylake-Server,vendor=GenuineIntel".


Because of the commit, the vendor is still AMD.

[root@vm ~]# cpuid -1 -l 0x0
CPU:
   vendor_id = "AuthenticAMD"


If I revert this patch, the vendor because the expected Intel.

[root@vm ~]# cpuid -1 -l 0x0
CPU:
   vendor_id = "GenuineIntel"


Thank you very much!

Dongli Zhang

On 5/20/25 4:05 AM, Paolo Bonzini wrote:
> Currently, the instance_post_init calls are performed from the leaf
> class and all the way up to Object.  This is incorrect because the
> leaf class cannot observe property values applied by the superclasses;
> for example, a compat property will be set on a device *after*
> the class's post_init callback has run.
> 
> In particular this makes it impossible for implementations of
> accel_cpu_instance_init() to operate based on the actual values of
> the properties, though it seems that cxl_dsp_instance_post_init and
> rp_instance_post_init might have similar issues.
> 
> Follow instead the same order as instance_init, starting with Object
> and running the child class's instance_post_init after the parent.
> 
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/qom/object.h | 3 ++-
>  qom/object.c         | 8 ++++----
>  2 files changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/include/qom/object.h b/include/qom/object.h
> index 1d5b0337242..26df6137b91 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -445,7 +445,8 @@ struct Object
>   *   class will have already been initialized so the type is only responsible
>   *   for initializing its own members.
>   * @instance_post_init: This function is called to finish initialization of
> - *   an object, after all @instance_init functions were called.
> + *   an object, after all @instance_init functions were called, as well as
> + *   @instance_post_init functions for the parent classes.
>   * @instance_finalize: This function is called during object destruction.  This
>   *   is called before the parent @instance_finalize function has been called.
>   *   An object should only free the members that are unique to its type in this
> diff --git a/qom/object.c b/qom/object.c
> index 7b013f40a0c..1856bb36c74 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -431,13 +431,13 @@ static void object_init_with_type(Object *obj, TypeImpl *ti)
>  
>  static void object_post_init_with_type(Object *obj, TypeImpl *ti)
>  {
> -    if (ti->instance_post_init) {
> -        ti->instance_post_init(obj);
> -    }
> -
>      if (type_has_parent(ti)) {
>          object_post_init_with_type(obj, type_get_parent(ti));
>      }
> +
> +    if (ti->instance_post_init) {
> +        ti->instance_post_init(obj);
> +    }
>  }
>  
>  bool object_apply_global_props(Object *obj, const GPtrArray *props,



^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-06-23 16:56   ` [Regression] " Dongli Zhang
@ 2025-06-24  8:57     ` Zhao Liu
  2025-06-30 15:22       ` Zhao Liu
  0 siblings, 1 reply; 53+ messages in thread
From: Zhao Liu @ 2025-06-24  8:57 UTC (permalink / raw)
  To: Dongli Zhang
  Cc: Paolo Bonzini, qemu-devel, Philippe Mathieu-Daudé,
	Alistair Francis, Like Xu

On Mon, Jun 23, 2025 at 09:56:14AM -0700, Dongli Zhang wrote:
> Date: Mon, 23 Jun 2025 09:56:14 -0700
> From: Dongli Zhang <dongli.zhang@oracle.com>
> Subject: [Regression] Re: [PULL 35/35] qom: reverse order of
>  instance_post_init calls
> 
> This commit may broken the "vendor=" configuration.
> 
> For instance, the hypervisor CPU vendor is AMD.
> 
> I am going to use "-cpu Skylake-Server,vendor=GenuineIntel".
> 
> 
> Because of the commit, the vendor is still AMD.
> 
> [root@vm ~]# cpuid -1 -l 0x0
> CPU:
>    vendor_id = "AuthenticAMD"
> 
> 
> If I revert this patch, the vendor because the expected Intel.
> 
> [root@vm ~]# cpuid -1 -l 0x0
> CPU:
>    vendor_id = "GenuineIntel"
> 
> 
> Thank you very much!

Thank you Dongli!

(+Like)

While testing my cache model series, I also noticed the similar behavior
for KVM. Additionally, Like Xu reported to me that this commit caused
a failure in a KVM unit test case. Your report helped me connect these
two issues I met (though due to my environment issues, I haven't
confirmed yet).

The "vendor" property from cli is registered as the global property in
x86_cpu_parse_featurestr(), and is applied to x86 CPUs in
device_post_init().

With this commit, now KVM will override the "vendor" in
host_cpu_instance_init() (called in x86_cpu_post_initfn()) after
device_post_init(), regardless the previous global "vendor" property.

Back to this commit, I think current order of post_init  makes sense.
Instead, the place of host_cpu_instance_init() doesn't seem quite
right. So, I think this commit might have exposed some drawbacks in the
previous x86 CPU initialization order:

f5cc5a5c1686 ("i386: split cpu accelerators from cpu.c, using AccelCPUClass")
5b8978d80426 ("i386: do not call cpudef-only models functions for max, host, base")




^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-06-24  8:57     ` Zhao Liu
@ 2025-06-30 15:22       ` Zhao Liu
  2025-07-01  6:50         ` Xiaoyao Li
  0 siblings, 1 reply; 53+ messages in thread
From: Zhao Liu @ 2025-06-30 15:22 UTC (permalink / raw)
  To: Paolo Bonzini, Dongli Zhang
  Cc: Thomas Huth, qemu-devel, Philippe Mathieu-Daud�,
	Alistair Francis, Like Xu, Zhao Liu

(cc Thomas for bug reporting on kvm-unit-test...)

On Tue, Jun 24, 2025 at 04:57:21PM +0800, Zhao Liu wrote:
> Date: Tue, 24 Jun 2025 16:57:21 +0800
> From: Zhao Liu <zhao1.liu@intel.com>
> Subject: Re: [Regression] Re: [PULL 35/35] qom: reverse order of
>  instance_post_init calls
> 
> On Mon, Jun 23, 2025 at 09:56:14AM -0700, Dongli Zhang wrote:
> > Date: Mon, 23 Jun 2025 09:56:14 -0700
> > From: Dongli Zhang <dongli.zhang@oracle.com>
> > Subject: [Regression] Re: [PULL 35/35] qom: reverse order of
> >  instance_post_init calls
> > 
> > This commit may broken the "vendor=" configuration.
> > 
> > For instance, the hypervisor CPU vendor is AMD.
> > 
> > I am going to use "-cpu Skylake-Server,vendor=GenuineIntel".
> > 
> > 
> > Because of the commit, the vendor is still AMD.
> > 
> > [root@vm ~]# cpuid -1 -l 0x0
> > CPU:
> >    vendor_id = "AuthenticAMD"
> > 
> > 
> > If I revert this patch, the vendor because the expected Intel.
> > 
> > [root@vm ~]# cpuid -1 -l 0x0
> > CPU:
> >    vendor_id = "GenuineIntel"
> > 
> > 
> > Thank you very much!
> 
> Thank you Dongli!
> 
> (+Like)
> 
> While testing my cache model series, I also noticed the similar behavior
> for KVM. Additionally, Like Xu reported to me that this commit caused
> a failure in a KVM unit test case. Your report helped me connect these
> two issues I met (though due to my environment issues, I haven't
> confirmed yet).

Ok, now I can confirm this commit cause KUT failure:
 * On AMD platform, the "msr.flat" case fails since this case requires
   vendor=GenuineIntel (tested by Like).
 * On Intel platform, the "syscall.flat" case fails because it requires
   vendor=AuthenticAMD (tested by myself).

> The "vendor" property from cli is registered as the global property in
> x86_cpu_parse_featurestr(), and is applied to x86 CPUs in
> device_post_init().
> 
> With this commit, now KVM will override the "vendor" in
> host_cpu_instance_init() (called in x86_cpu_post_initfn()) after
> device_post_init(), regardless the previous global "vendor" property.

This is the root cause for the above failure.

> Back to this commit, I think current order of post_init  makes sense.
> Instead, the place of host_cpu_instance_init() doesn't seem quite
> right. So, I think this commit might have exposed some drawbacks in the
> previous x86 CPU initialization order:
> 
> f5cc5a5c1686 ("i386: split cpu accelerators from cpu.c, using AccelCPUClass")
> 5b8978d80426 ("i386: do not call cpudef-only models functions for max, host, base")

To fix this issue, we need to initialize "vendor" property in the initfn
of max/host/named CPUs instead of current post_initfn.

This will need to split the cpu_instance_init() of x86 kvm (and maybe hvf/tcg)
into 2 hooks:
 * AccelCPUClass.cpu_instance_init() - called in x86 CPUs' initfn.
 * AccelCPUClass.cpu_instance_post_init() - called in x86 CPUs'
   post_initfn.

I just did a POC and this solution works in principle.

But there are very many more details here, including considering more
properties/considering hvf and tcg and so on. It still need to take more
time for me figuring everything out. Once that's done, I'll post a series
to fix this issue.

Thanks,
Zhao



^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-06-30 15:22       ` Zhao Liu
@ 2025-07-01  6:50         ` Xiaoyao Li
  2025-07-02  6:54           ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 53+ messages in thread
From: Xiaoyao Li @ 2025-07-01  6:50 UTC (permalink / raw)
  To: Zhao Liu, Paolo Bonzini, Dongli Zhang
  Cc: Thomas Huth, qemu-devel, Philippe Mathieu-Daud�,
	Alistair Francis, Like Xu

On 6/30/2025 11:22 PM, Zhao Liu wrote:
> (cc Thomas for bug reporting on kvm-unit-test...)
> 
> On Tue, Jun 24, 2025 at 04:57:21PM +0800, Zhao Liu wrote:
>> Date: Tue, 24 Jun 2025 16:57:21 +0800
>> From: Zhao Liu <zhao1.liu@intel.com>
>> Subject: Re: [Regression] Re: [PULL 35/35] qom: reverse order of
>>   instance_post_init calls
>>
>> On Mon, Jun 23, 2025 at 09:56:14AM -0700, Dongli Zhang wrote:
>>> Date: Mon, 23 Jun 2025 09:56:14 -0700
>>> From: Dongli Zhang <dongli.zhang@oracle.com>
>>> Subject: [Regression] Re: [PULL 35/35] qom: reverse order of
>>>   instance_post_init calls
>>>
>>> This commit may broken the "vendor=" configuration.
>>>
>>> For instance, the hypervisor CPU vendor is AMD.
>>>
>>> I am going to use "-cpu Skylake-Server,vendor=GenuineIntel".
>>>
>>>
>>> Because of the commit, the vendor is still AMD.
>>>
>>> [root@vm ~]# cpuid -1 -l 0x0
>>> CPU:
>>>     vendor_id = "AuthenticAMD"
>>>
>>>
>>> If I revert this patch, the vendor because the expected Intel.
>>>
>>> [root@vm ~]# cpuid -1 -l 0x0
>>> CPU:
>>>     vendor_id = "GenuineIntel"
>>>
>>>
>>> Thank you very much!
>>
>> Thank you Dongli!
>>
>> (+Like)
>>
>> While testing my cache model series, I also noticed the similar behavior
>> for KVM. Additionally, Like Xu reported to me that this commit caused
>> a failure in a KVM unit test case. Your report helped me connect these
>> two issues I met (though due to my environment issues, I haven't
>> confirmed yet).
> 
> Ok, now I can confirm this commit cause KUT failure:
>   * On AMD platform, the "msr.flat" case fails since this case requires
>     vendor=GenuineIntel (tested by Like).
>   * On Intel platform, the "syscall.flat" case fails because it requires
>     vendor=AuthenticAMD (tested by myself).
> 
>> The "vendor" property from cli is registered as the global property in
>> x86_cpu_parse_featurestr(), and is applied to x86 CPUs in
>> device_post_init().
>>
>> With this commit, now KVM will override the "vendor" in
>> host_cpu_instance_init() (called in x86_cpu_post_initfn()) after
>> device_post_init(), regardless the previous global "vendor" property.
> 
> This is the root cause for the above failure.
> 
>> Back to this commit, I think current order of post_init  makes sense.
>> Instead, the place of host_cpu_instance_init() doesn't seem quite
>> right. So, I think this commit might have exposed some drawbacks in the
>> previous x86 CPU initialization order:
>>
>> f5cc5a5c1686 ("i386: split cpu accelerators from cpu.c, using AccelCPUClass")
>> 5b8978d80426 ("i386: do not call cpudef-only models functions for max, host, base")
> 
> To fix this issue, we need to initialize "vendor" property in the initfn
> of max/host/named CPUs instead of current post_initfn.
> 
> This will need to split the cpu_instance_init() of x86 kvm (and maybe hvf/tcg)
> into 2 hooks:
>   * AccelCPUClass.cpu_instance_init() - called in x86 CPUs' initfn.
>   * AccelCPUClass.cpu_instance_post_init() - called in x86 CPUs'
>     post_initfn.

Split accel.cpu_instance_init() into cpu's instance_init() and 
post_instance_init() does not seem right way to go.

The reason .post_instance_init() was implemented and put 
accel_cpu_instance_init() in it for x86 cpu was that, we don't want to 
scatter acceletor specific instance_init operation into different 
subclass of x86 cpu (max/host/named cpu model).

I think something like below should be enough.

-----------8<-------------
Author: Xiaoyao Li <xiaoyao.li@intel.com>
Date:   Tue Jul 1 13:33:43 2025 +0800

     i386/cpu: Re-apply the global props as the last step of post_init

     Commit 220c739903ce ("qom: reverse order of instance_post_init calls")
     reverses the order instance_post_init calls, which leads to
     device_post_init() called before x86 cpu specific 
.instance_post_init().

     However, x86 cpu replies on qdev_prop_set_globals() (inside
     device_post_init()) to apply the cpu option like "feature[=foo]" passed
     via '-cpu' as the last step to make the '-cpu' option highest priority.

     After the order change of .instance_post_init(), x86_cpu_post_initfn()
     is called after device_post_init(), and it will change some property
     value even though "-cpu" option specify a different one.

     Re-apply the global props as the last step to ensure "-cpu" option
     always takes highest priority.

     Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 0d35e95430fe..bf290262cbfe 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -9044,6 +9044,12 @@ static void x86_cpu_post_initfn(Object *obj)
              X86_CONFIDENTIAL_GUEST(current_machine->cgs), (CPU(obj)));
      }
  #endif
+
+    /*
+     * Re-apply the "feature[=foo]" from '-cpu' option since they might
+     * be overwritten by above
+     */
+    qdev_prop_set_globals(DEVICE(obj));
  }

  static void x86_cpu_init_default_topo(X86CPU *cpu)




^ permalink raw reply related	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-01  6:50         ` Xiaoyao Li
@ 2025-07-02  6:54           ` Philippe Mathieu-Daudé
  2025-07-02  7:56             ` Zhao Liu
  2025-07-02 12:06             ` Paolo Bonzini
  0 siblings, 2 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-07-02  6:54 UTC (permalink / raw)
  To: Xiaoyao Li, Zhao Liu, Paolo Bonzini, Dongli Zhang
  Cc: Thomas Huth, qemu-devel, Alistair Francis, Like Xu, Igor Mammedov

On 1/7/25 08:50, Xiaoyao Li wrote:
> On 6/30/2025 11:22 PM, Zhao Liu wrote:
>> (cc Thomas for bug reporting on kvm-unit-test...)
>>
>> On Tue, Jun 24, 2025 at 04:57:21PM +0800, Zhao Liu wrote:
>>> Date: Tue, 24 Jun 2025 16:57:21 +0800
>>> From: Zhao Liu <zhao1.liu@intel.com>
>>> Subject: Re: [Regression] Re: [PULL 35/35] qom: reverse order of
>>>   instance_post_init calls
>>>
>>> On Mon, Jun 23, 2025 at 09:56:14AM -0700, Dongli Zhang wrote:
>>>> Date: Mon, 23 Jun 2025 09:56:14 -0700
>>>> From: Dongli Zhang <dongli.zhang@oracle.com>
>>>> Subject: [Regression] Re: [PULL 35/35] qom: reverse order of
>>>>   instance_post_init calls
>>>>
>>>> This commit may broken the "vendor=" configuration.
>>>>
>>>> For instance, the hypervisor CPU vendor is AMD.
>>>>
>>>> I am going to use "-cpu Skylake-Server,vendor=GenuineIntel".
>>>>
>>>>
>>>> Because of the commit, the vendor is still AMD.
>>>>
>>>> [root@vm ~]# cpuid -1 -l 0x0
>>>> CPU:
>>>>     vendor_id = "AuthenticAMD"
>>>>
>>>>
>>>> If I revert this patch, the vendor because the expected Intel.
>>>>
>>>> [root@vm ~]# cpuid -1 -l 0x0
>>>> CPU:
>>>>     vendor_id = "GenuineIntel"
>>>>
>>>>
>>>> Thank you very much!
>>>
>>> Thank you Dongli!
>>>
>>> (+Like)
>>>
>>> While testing my cache model series, I also noticed the similar behavior
>>> for KVM. Additionally, Like Xu reported to me that this commit caused
>>> a failure in a KVM unit test case. Your report helped me connect these
>>> two issues I met (though due to my environment issues, I haven't
>>> confirmed yet).
>>
>> Ok, now I can confirm this commit cause KUT failure:
>>   * On AMD platform, the "msr.flat" case fails since this case requires
>>     vendor=GenuineIntel (tested by Like).
>>   * On Intel platform, the "syscall.flat" case fails because it requires
>>     vendor=AuthenticAMD (tested by myself).
>>
>>> The "vendor" property from cli is registered as the global property in
>>> x86_cpu_parse_featurestr(), and is applied to x86 CPUs in
>>> device_post_init().
>>>
>>> With this commit, now KVM will override the "vendor" in
>>> host_cpu_instance_init() (called in x86_cpu_post_initfn()) after
>>> device_post_init(), regardless the previous global "vendor" property.
>>
>> This is the root cause for the above failure.
>>
>>> Back to this commit, I think current order of post_init  makes sense.
>>> Instead, the place of host_cpu_instance_init() doesn't seem quite
>>> right. So, I think this commit might have exposed some drawbacks in the
>>> previous x86 CPU initialization order:
>>>
>>> f5cc5a5c1686 ("i386: split cpu accelerators from cpu.c, using 
>>> AccelCPUClass")
>>> 5b8978d80426 ("i386: do not call cpudef-only models functions for 
>>> max, host, base")
>>
>> To fix this issue, we need to initialize "vendor" property in the initfn
>> of max/host/named CPUs instead of current post_initfn.
>>
>> This will need to split the cpu_instance_init() of x86 kvm (and maybe 
>> hvf/tcg)
>> into 2 hooks:
>>   * AccelCPUClass.cpu_instance_init() - called in x86 CPUs' initfn.
>>   * AccelCPUClass.cpu_instance_post_init() - called in x86 CPUs'
>>     post_initfn.
> 
> Split accel.cpu_instance_init() into cpu's instance_init() and 
> post_instance_init() does not seem right way to go.

Yeah, please don't. I'm trying to consolidate this code but it takes
(too) long.

> The reason .post_instance_init() was implemented and put 
> accel_cpu_instance_init() in it for x86 cpu was that, we don't want to 
> scatter acceletor specific instance_init operation into different 
> subclass of x86 cpu (max/host/named cpu model).
> 
> I think something like below should be enough.
> 
> -----------8<-------------
> Author: Xiaoyao Li <xiaoyao.li@intel.com>
> Date:   Tue Jul 1 13:33:43 2025 +0800
> 
>      i386/cpu: Re-apply the global props as the last step of post_init
> 
>      Commit 220c739903ce ("qom: reverse order of instance_post_init calls")
>      reverses the order instance_post_init calls, which leads to
>      device_post_init() called before x86 cpu 
> specific .instance_post_init().
> 
>      However, x86 cpu replies on qdev_prop_set_globals() (inside
>      device_post_init()) to apply the cpu option like "feature[=foo]" 
> passed
>      via '-cpu' as the last step to make the '-cpu' option highest 
> priority.
> 
>      After the order change of .instance_post_init(), x86_cpu_post_initfn()
>      is called after device_post_init(), and it will change some property
>      value even though "-cpu" option specify a different one.
> 
>      Re-apply the global props as the last step to ensure "-cpu" option
>      always takes highest priority.
> 
>      Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 0d35e95430fe..bf290262cbfe 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -9044,6 +9044,12 @@ static void x86_cpu_post_initfn(Object *obj)
>               X86_CONFIDENTIAL_GUEST(current_machine->cgs), (CPU(obj)));
>       }
>   #endif
> +
> +    /*
> +     * Re-apply the "feature[=foo]" from '-cpu' option since they might
> +     * be overwritten by above
> +     */
> +    qdev_prop_set_globals(DEVICE(obj));
>   }

This patch LGTM.

Regards,

Phil.


^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-02  6:54           ` Philippe Mathieu-Daudé
@ 2025-07-02  7:56             ` Zhao Liu
  2025-07-02 11:42               ` Xiaoyao Li
  2025-07-02 12:06             ` Paolo Bonzini
  1 sibling, 1 reply; 53+ messages in thread
From: Zhao Liu @ 2025-07-02  7:56 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: Xiaoyao Li, Paolo Bonzini, Dongli Zhang, Thomas Huth, qemu-devel,
	Alistair Francis, Like Xu, Igor Mammedov

> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index 0d35e95430fe..bf290262cbfe 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -9044,6 +9044,12 @@ static void x86_cpu_post_initfn(Object *obj)
> >               X86_CONFIDENTIAL_GUEST(current_machine->cgs), (CPU(obj)));
> >       }
> >   #endif
> > +
> > +    /*
> > +     * Re-apply the "feature[=foo]" from '-cpu' option since they might
> > +     * be overwritten by above
> > +     */
> > +    qdev_prop_set_globals(DEVICE(obj));
> >   }
> 
> This patch LGTM.

This solution will call qdev_prop_set_globals() twice. My concern is
that this masks the problem: previous x86 CPU assumptions about the
order of global property initialization break down...

Per the commit message of Paolo's commit:

"This is incorrect because the leaf class cannot observe property
values applied by the superclasses; for example, a compat property
will be set on a device *after* the class's post_init callback has
run."

X86 CPUs have the issue (e.g., "vendor" doesn't work) now because
they - as leaf class, don't care about the property values of
superclass - the DeviceState. If a property is just for initialization,
like "vendor", it should be placed in the instance_init() instead of
instance_post_init().

In addition, if other places handle it similarly, the device's
post_init seems pointless. :-(

Thanks,
Zhao



^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-02  7:56             ` Zhao Liu
@ 2025-07-02 11:42               ` Xiaoyao Li
  2025-07-02 12:12                 ` Paolo Bonzini
  0 siblings, 1 reply; 53+ messages in thread
From: Xiaoyao Li @ 2025-07-02 11:42 UTC (permalink / raw)
  To: Zhao Liu, Philippe Mathieu-Daudé
  Cc: Paolo Bonzini, Dongli Zhang, Thomas Huth, qemu-devel,
	Alistair Francis, Like Xu, Igor Mammedov

On 7/2/2025 3:56 PM, Zhao Liu wrote:
>>> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
>>> index 0d35e95430fe..bf290262cbfe 100644
>>> --- a/target/i386/cpu.c
>>> +++ b/target/i386/cpu.c
>>> @@ -9044,6 +9044,12 @@ static void x86_cpu_post_initfn(Object *obj)
>>>                X86_CONFIDENTIAL_GUEST(current_machine->cgs), (CPU(obj)));
>>>        }
>>>    #endif
>>> +
>>> +    /*
>>> +     * Re-apply the "feature[=foo]" from '-cpu' option since they might
>>> +     * be overwritten by above
>>> +     */
>>> +    qdev_prop_set_globals(DEVICE(obj));
>>>    }
>>
>> This patch LGTM.
> 
> This solution will call qdev_prop_set_globals() twice. My concern is
> that this masks the problem: previous x86 CPU assumptions about the
> order of global property initialization break down...
> 
> Per the commit message of Paolo's commit:
> 
> "This is incorrect because the leaf class cannot observe property
> values applied by the superclasses; for example, a compat property
> will be set on a device *after* the class's post_init callback has
> run."

After checking the history of why .post_instance_init() was introduced 
in the first place: 8231c2dd2203 ("qom: Introduce instance_post_init 
hook"). It turns out to be used for qdev_prop_set_globals(), to ensure 
global properties being applied after all sub-device specific 
instance_init() were called. And I think the order from child to parent 
was defined purposely.

And the reverse of Paolo's patch breaks the usage of "-global" than it 
won't take effect if the sub-device changes the property in its 
post_instance_init() callback.

Back to Paolo's example of "a compat property will be set on a device 
*after* the class's post_init callback has run". I think the behavior of 
compat property is applied after the class's post_init callback is also 
what we want. If reversing the order, then compat prop can be 
overwritten by subclass's post_init callback, and doesn't it fail the 
purpose of compat prop?

So I think we might revert this patch, and document clearly the reverse 
order of .post_instance_init() callback.

> X86 CPUs have the issue (e.g., "vendor" doesn't work) now because
> they - as leaf class, don't care about the property values of
> superclass - the DeviceState. If a property is just for initialization,
> like "vendor", it should be placed in the instance_init() instead of
> instance_post_init().
> 
> In addition, if other places handle it similarly, the device's
> post_init seems pointless. :-(
> 
> Thanks,
> Zhao
> 



^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-02  6:54           ` Philippe Mathieu-Daudé
  2025-07-02  7:56             ` Zhao Liu
@ 2025-07-02 12:06             ` Paolo Bonzini
  1 sibling, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-07-02 12:06 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: Xiaoyao Li, Zhao Liu, Dongli Zhang, Thomas Huth, qemu-devel,
	Alistair Francis, Like Xu, Igor Mammedov

[-- Attachment #1: Type: text/plain, Size: 3572 bytes --]

Il mer 2 lug 2025, 02:54 Philippe Mathieu-Daudé <philmd@linaro.org> ha
scritto:

> >>> Back to this commit, I think current order of post_init  makes sense.
> >>> Instead, the place of host_cpu_instance_init() doesn't seem quite
> >>> right. So, I think this commit might have exposed some drawbacks in the
> >>> previous x86 CPU initialization order:
> >>>
> >>> f5cc5a5c1686 ("i386: split cpu accelerators from cpu.c, using
> >>> AccelCPUClass")
> >>> 5b8978d80426 ("i386: do not call cpudef-only models functions for
> >>> max, host, base")
> >>
> >> To fix this issue, we need to initialize "vendor" property in the initfn
> >> of max/host/named CPUs instead of current post_initfn.
> >>
> >> This will need to split the cpu_instance_init() of x86 kvm (and maybe
> >> hvf/tcg)
> >> into 2 hooks:
> >>   * AccelCPUClass.cpu_instance_init() - called in x86 CPUs' initfn.
> >>   * AccelCPUClass.cpu_instance_post_init() - called in x86 CPUs'
> >>     post_initfn.
> >
> > Split accel.cpu_instance_init() into cpu's instance_init() and
> > post_instance_init() does not seem right way to go.
>
> Yeah, please don't. I'm trying to consolidate this code but it takes
> (too) long.
>

Unfortunately I agree with Zhao. The globals, being user provided, must
come after the AccelCPUClass initialization.

My hope is that it's possible to avoid a split and move everything earlier
as in target-riscv/. I will take a look next week if Zhao doesn't beat me,
and/or discuss with him.

Paolo


> > The reason .post_instance_init() was implemented and put
> > accel_cpu_instance_init() in it for x86 cpu was that, we don't want to
> > scatter acceletor specific instance_init operation into different
> > subclass of x86 cpu (max/host/named cpu model).
> >
> > I think something like below should be enough.
> >
> > -----------8<-------------
> > Author: Xiaoyao Li <xiaoyao.li@intel.com>
> > Date:   Tue Jul 1 13:33:43 2025 +0800
> >
> >      i386/cpu: Re-apply the global props as the last step of post_init
> >
> >      Commit 220c739903ce ("qom: reverse order of instance_post_init
> calls")
> >      reverses the order instance_post_init calls, which leads to
> >      device_post_init() called before x86 cpu
> > specific .instance_post_init().
> >
> >      However, x86 cpu replies on qdev_prop_set_globals() (inside
> >      device_post_init()) to apply the cpu option like "feature[=foo]"
> > passed
> >      via '-cpu' as the last step to make the '-cpu' option highest
> > priority.
> >
> >      After the order change of .instance_post_init(),
> x86_cpu_post_initfn()
> >      is called after device_post_init(), and it will change some property
> >      value even though "-cpu" option specify a different one.
> >
> >      Re-apply the global props as the last step to ensure "-cpu" option
> >      always takes highest priority.
> >
> >      Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
> >
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index 0d35e95430fe..bf290262cbfe 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -9044,6 +9044,12 @@ static void x86_cpu_post_initfn(Object *obj)
> >               X86_CONFIDENTIAL_GUEST(current_machine->cgs), (CPU(obj)));
> >       }
> >   #endif
> > +
> > +    /*
> > +     * Re-apply the "feature[=foo]" from '-cpu' option since they might
> > +     * be overwritten by above
> > +     */
> > +    qdev_prop_set_globals(DEVICE(obj));
> >   }
>
> This patch LGTM.
>
> Regards,
>
> Phil.
>
>

[-- Attachment #2: Type: text/html, Size: 5125 bytes --]

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-02 11:42               ` Xiaoyao Li
@ 2025-07-02 12:12                 ` Paolo Bonzini
  2025-07-02 13:24                   ` Xiaoyao Li
  0 siblings, 1 reply; 53+ messages in thread
From: Paolo Bonzini @ 2025-07-02 12:12 UTC (permalink / raw)
  To: Xiaoyao Li
  Cc: Zhao Liu, Philippe Mathieu-Daudé, Dongli Zhang, Thomas Huth,
	qemu-devel, Alistair Francis, Like Xu, Igor Mammedov

[-- Attachment #1: Type: text/plain, Size: 1692 bytes --]

Il mer 2 lug 2025, 07:42 Xiaoyao Li <xiaoyao.li@intel.com> ha scritto:

> Back to Paolo's example of "a compat property will be set on a device
> *after* the class's post_init callback has run". I think the behavior of
> compat property is applied after the class's post_init callback is also
> what we want. If reversing the order, then compat prop can be
> overwritten by subclass's post_init callback, and doesn't it fail the
> purpose of compat prop?
>

I wrote the patch because of a latent issue with TDX. The issue was roughly
that a compat property was overwriting the TDX-specific modifications to
CPUID. I think this case shows that you *do* want the subclass to overwrite
the compat property—of course the subclass code must be aware that compat
properties exist and limit changes appropriately.

In general I don't see how the reverse order makes sense: the subclass
knows what the superclass does, so it can do the right thing if it runs
last; but the superclass cannot know what all of its subclasses do in
post_init, so it makes less sense to run it last.

Paolo


> So I think we might revert this patch, and document clearly the reverse
> order of .post_instance_init() callback.
>
> > X86 CPUs have the issue (e.g., "vendor" doesn't work) now because
> > they - as leaf class, don't care about the property values of
> > superclass - the DeviceState. If a property is just for initialization,
> > like "vendor", it should be placed in the instance_init() instead of
> > instance_post_init().
> >
> > In addition, if other places handle it similarly, the device's
> > post_init seems pointless. :-(
> >
> > Thanks,
> > Zhao
> >
>
>

[-- Attachment #2: Type: text/html, Size: 2523 bytes --]

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-02 12:12                 ` Paolo Bonzini
@ 2025-07-02 13:24                   ` Xiaoyao Li
  2025-07-02 18:54                     ` Paolo Bonzini
  0 siblings, 1 reply; 53+ messages in thread
From: Xiaoyao Li @ 2025-07-02 13:24 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Zhao Liu, Philippe Mathieu-Daudé, Dongli Zhang, Thomas Huth,
	qemu-devel, Alistair Francis, Like Xu, Igor Mammedov

On 7/2/2025 8:12 PM, Paolo Bonzini wrote:
> Il mer 2 lug 2025, 07:42 Xiaoyao Li <xiaoyao.li@intel.com> ha scritto:
> 
>> Back to Paolo's example of "a compat property will be set on a device
>> *after* the class's post_init callback has run". I think the behavior of
>> compat property is applied after the class's post_init callback is also
>> what we want. If reversing the order, then compat prop can be
>> overwritten by subclass's post_init callback, and doesn't it fail the
>> purpose of compat prop?
>>
> 
> I wrote the patch because of a latent issue with TDX. The issue was roughly
> that a compat property was overwriting the TDX-specific modifications to
> CPUID. I think this case shows that you *do* want the subclass to overwrite
> the compat property—of course the subclass code must be aware that compat
> properties exist and limit changes appropriately.

IIRC that's on rhel QEMU which ports the TDX code before it's merged 
upstream. Now TDX is upstreamed, it works with upstream compat property 
and I think future new compat property won't affect TDX or anything, 
since it's compat property and it's to guarantee the existing behavior 
when introducing new behavior?

> In general I don't see how the reverse order makes sense: the subclass
> knows what the superclass does, so it can do the right thing if it runs
> last; but the superclass cannot know what all of its subclasses do in
> post_init, so it makes less sense to run it last.

I agree in general the parent to child order makes more sense, 
especially when we treat .instance_init() as the phase 1 init and 
.post_instance_init() as the phase 2 init.

But the original purpose of introducing .post_instance_init() was to 
ensure qdev_prop_set_globals() is called at last for Device. Reverse the 
order breaks this purpose.

It seems not good option like the reversed order from child to parent 
that can achieve it by just putting the last step in top parent's.

I'm looking forward to seeing a better solution.

> Paolo
> 
> 
>> So I think we might revert this patch, and document clearly the reverse
>> order of .post_instance_init() callback.
>>
>>> X86 CPUs have the issue (e.g., "vendor" doesn't work) now because
>>> they - as leaf class, don't care about the property values of
>>> superclass - the DeviceState. If a property is just for initialization,
>>> like "vendor", it should be placed in the instance_init() instead of
>>> instance_post_init().
>>>
>>> In addition, if other places handle it similarly, the device's
>>> post_init seems pointless. :-(
>>>
>>> Thanks,
>>> Zhao
>>>
>>
>>
> 



^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-02 13:24                   ` Xiaoyao Li
@ 2025-07-02 18:54                     ` Paolo Bonzini
  2025-07-03  1:03                       ` Xiaoyao Li
  0 siblings, 1 reply; 53+ messages in thread
From: Paolo Bonzini @ 2025-07-02 18:54 UTC (permalink / raw)
  To: Xiaoyao Li
  Cc: Zhao Liu, Philippe Mathieu-Daudé, Dongli Zhang, Thomas Huth,
	qemu-devel, Alistair Francis, Like Xu, Igor Mammedov

[-- Attachment #1: Type: text/plain, Size: 2286 bytes --]

Il mer 2 lug 2025, 09:25 Xiaoyao Li <xiaoyao.li@intel.com> ha scritto:

> IIRC that's on rhel QEMU which ports the TDX code before it's merged
> upstream. Now TDX is upstreamed, it works with upstream compat property
> and I think future new compat property won't affect TDX or anything,
> since it's compat property and it's to guarantee the existing behavior
> when introducing new behavior?
>

It's a compat property that is only added by RHEL-specific machine types.
But the bug is not specific to RHEL, it just happens that no upstream
machine type has compat properties that overlap with TDX adjustments of
CPUID.

> In general I don't see how the reverse order makes sense: the subclass
> > knows what the superclass does, so it can do the right thing if it runs
> > last; but the superclass cannot know what all of its subclasses do in
> > post_init, so it makes less sense to run it last.
>
> I agree in general the parent to child order makes more sense,
> especially when we treat .instance_init() as the phase 1 init and
> .post_instance_init() as the phase 2 init.
>
> But the original purpose of introducing .post_instance_init() was to
> ensure qdev_prop_set_globals() is called at last for Device. Reverse the
> order breaks this purpose.
>

Not "last", but "after instance_init". Anything that happens in the child
class's instance_post_init can be moved at the end of instance_init, just
like the refactoring that I did for risc-v.

Paolo

It seems not good option like the reversed order from child to parent
> that can achieve it by just putting the last step in top parent's.
>
> I'm looking forward to seeing a better solution.
>
> > Paolo
> >
> >
> >> So I think we might revert this patch, and document clearly the reverse
> >> order of .post_instance_init() callback.
> >>
> >>> X86 CPUs have the issue (e.g., "vendor" doesn't work) now because
> >>> they - as leaf class, don't care about the property values of
> >>> superclass - the DeviceState. If a property is just for initialization,
> >>> like "vendor", it should be placed in the instance_init() instead of
> >>> instance_post_init().
> >>>
> >>> In addition, if other places handle it similarly, the device's
> >>> post_init seems pointless. :-(
> >>>
> >>> Thanks,
> >>> Zhao
> >>>
> >>
> >>
> >
>
>

[-- Attachment #2: Type: text/html, Size: 3611 bytes --]

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-02 18:54                     ` Paolo Bonzini
@ 2025-07-03  1:03                       ` Xiaoyao Li
  2025-07-03  3:08                         ` Zhao Liu
  0 siblings, 1 reply; 53+ messages in thread
From: Xiaoyao Li @ 2025-07-03  1:03 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Zhao Liu, Philippe Mathieu-Daudé, Dongli Zhang, Thomas Huth,
	qemu-devel, Alistair Francis, Like Xu, Igor Mammedov

On 7/3/2025 2:54 AM, Paolo Bonzini wrote:
> Il mer 2 lug 2025, 09:25 Xiaoyao Li <xiaoyao.li@intel.com> ha scritto:
> 
>> IIRC that's on rhel QEMU which ports the TDX code before it's merged
>> upstream. Now TDX is upstreamed, it works with upstream compat property
>> and I think future new compat property won't affect TDX or anything,
>> since it's compat property and it's to guarantee the existing behavior
>> when introducing new behavior?
>>
> 
> It's a compat property that is only added by RHEL-specific machine types.
> But the bug is not specific to RHEL, it just happens that no upstream
> machine type has compat properties that overlap with TDX adjustments of
> CPUID.
> 
>> In general I don't see how the reverse order makes sense: the subclass
>>> knows what the superclass does, so it can do the right thing if it runs
>>> last; but the superclass cannot know what all of its subclasses do in
>>> post_init, so it makes less sense to run it last.
>>
>> I agree in general the parent to child order makes more sense,
>> especially when we treat .instance_init() as the phase 1 init and
>> .post_instance_init() as the phase 2 init.
>>
>> But the original purpose of introducing .post_instance_init() was to
>> ensure qdev_prop_set_globals() is called at last for Device. Reverse the
>> order breaks this purpose.
>>
> 
> Not "last", but "after instance_init". Anything that happens in the child
> class's instance_post_init can be moved at the end of instance_init, just
> like the refactoring that I did for risc-v.

Move into the end of instance_init() can surely work. But it requires to 
split the code in instance_post_init() to different child's 
instance_init() or making sure the code in instance_post_init() is 
called at the end of each lowest child class.

Besides, it also leads to a rule that child of Device's 
.post_instance_init() needs to be careful about changing the property or 
anything that might affect the property, because it might break the 
usage of global properties.

This can surely work. But to me, it seems to make code worse not better.




^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-03  1:03                       ` Xiaoyao Li
@ 2025-07-03  3:08                         ` Zhao Liu
  2025-07-03  3:36                           ` Xiaoyao Li
  0 siblings, 1 reply; 53+ messages in thread
From: Zhao Liu @ 2025-07-03  3:08 UTC (permalink / raw)
  To: Xiaoyao Li
  Cc: Paolo Bonzini, Philippe Mathieu-Daudé, Dongli Zhang,
	Thomas Huth, qemu-devel, Alistair Francis, Like Xu, Igor Mammedov

On Thu, Jul 03, 2025 at 09:03:10AM +0800, Xiaoyao Li wrote:
> Date: Thu, 3 Jul 2025 09:03:10 +0800
> From: Xiaoyao Li <xiaoyao.li@intel.com>
> Subject: Re: [Regression] Re: [PULL 35/35] qom: reverse order of
>  instance_post_init calls
> 
> On 7/3/2025 2:54 AM, Paolo Bonzini wrote:
> > Il mer 2 lug 2025, 09:25 Xiaoyao Li <xiaoyao.li@intel.com> ha scritto:
> > 
> > > IIRC that's on rhel QEMU which ports the TDX code before it's merged
> > > upstream. Now TDX is upstreamed, it works with upstream compat property
> > > and I think future new compat property won't affect TDX or anything,
> > > since it's compat property and it's to guarantee the existing behavior
> > > when introducing new behavior?
> > > 
> > 
> > It's a compat property that is only added by RHEL-specific machine types.
> > But the bug is not specific to RHEL, it just happens that no upstream
> > machine type has compat properties that overlap with TDX adjustments of
> > CPUID.
> > 
> > > In general I don't see how the reverse order makes sense: the subclass
> > > > knows what the superclass does, so it can do the right thing if it runs
> > > > last; but the superclass cannot know what all of its subclasses do in
> > > > post_init, so it makes less sense to run it last.
> > > 
> > > I agree in general the parent to child order makes more sense,
> > > especially when we treat .instance_init() as the phase 1 init and
> > > .post_instance_init() as the phase 2 init.
> > > 
> > > But the original purpose of introducing .post_instance_init() was to
> > > ensure qdev_prop_set_globals() is called at last for Device. Reverse the
> > > order breaks this purpose.
> > > 
> > 
> > Not "last", but "after instance_init". Anything that happens in the child
> > class's instance_post_init can be moved at the end of instance_init, just
> > like the refactoring that I did for risc-v.
> 
> Move into the end of instance_init() can surely work. But it requires to
> split the code in instance_post_init() to different child's instance_init()
> or making sure the code in instance_post_init() is called at the end of each
> lowest child class.

Initially, when I proposed the split approach, it wasn't about
splitting for the sake of splitting, nor for the sake of "work".

A more granular split is just a means, and the goal is to place things
at different stages in the most appropriate locations.

> Besides, it also leads to a rule that child of Device's
> .post_instance_init() needs to be careful about changing the property or
> anything that might affect the property,

I believe that's how things should be. instance_post_init() provides an
opportunity to tweak properties. The order of instance_post_init()
reflects the dependency relationships for property adjustments. As I
mentioned earlier, if a property doesn't need to consider other factors
and is simply being initialized, instance_init() is the most appropriate
place for it.

> because it might break the usage of global properties.

Breaking global properties is just one example. Essentially, properties
like "vendor" don't adhere well to the semantics of QOM.

> This can surely work. But to me, it seems to make code worse not better.

IMO, it's not the split that makes things worse, but rather the improper
use of instance_post_init() that makes everything about the x86 CPU
fragile. Ideally, QOM/qdev should focus on their own abstraction order,
while the leaf-class should do the right thing in the right place, which
is the most solid situation.



^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-03  3:08                         ` Zhao Liu
@ 2025-07-03  3:36                           ` Xiaoyao Li
  2025-07-03  4:51                             ` Paolo Bonzini
  0 siblings, 1 reply; 53+ messages in thread
From: Xiaoyao Li @ 2025-07-03  3:36 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Philippe Mathieu-Daudé, Dongli Zhang,
	Thomas Huth, qemu-devel, Alistair Francis, Like Xu, Igor Mammedov

On 7/3/2025 11:08 AM, Zhao Liu wrote:
> On Thu, Jul 03, 2025 at 09:03:10AM +0800, Xiaoyao Li wrote:
>> Date: Thu, 3 Jul 2025 09:03:10 +0800
>> From: Xiaoyao Li <xiaoyao.li@intel.com>
>> Subject: Re: [Regression] Re: [PULL 35/35] qom: reverse order of
>>   instance_post_init calls
>>
>> On 7/3/2025 2:54 AM, Paolo Bonzini wrote:
>>> Il mer 2 lug 2025, 09:25 Xiaoyao Li <xiaoyao.li@intel.com> ha scritto:
>>>
>>>> IIRC that's on rhel QEMU which ports the TDX code before it's merged
>>>> upstream. Now TDX is upstreamed, it works with upstream compat property
>>>> and I think future new compat property won't affect TDX or anything,
>>>> since it's compat property and it's to guarantee the existing behavior
>>>> when introducing new behavior?
>>>>
>>>
>>> It's a compat property that is only added by RHEL-specific machine types.
>>> But the bug is not specific to RHEL, it just happens that no upstream
>>> machine type has compat properties that overlap with TDX adjustments of
>>> CPUID.
>>>
>>>> In general I don't see how the reverse order makes sense: the subclass
>>>>> knows what the superclass does, so it can do the right thing if it runs
>>>>> last; but the superclass cannot know what all of its subclasses do in
>>>>> post_init, so it makes less sense to run it last.
>>>>
>>>> I agree in general the parent to child order makes more sense,
>>>> especially when we treat .instance_init() as the phase 1 init and
>>>> .post_instance_init() as the phase 2 init.
>>>>
>>>> But the original purpose of introducing .post_instance_init() was to
>>>> ensure qdev_prop_set_globals() is called at last for Device. Reverse the
>>>> order breaks this purpose.
>>>>
>>>
>>> Not "last", but "after instance_init". Anything that happens in the child
>>> class's instance_post_init can be moved at the end of instance_init, just
>>> like the refactoring that I did for risc-v.
>>
>> Move into the end of instance_init() can surely work. But it requires to
>> split the code in instance_post_init() to different child's instance_init()
>> or making sure the code in instance_post_init() is called at the end of each
>> lowest child class.
> 
> Initially, when I proposed the split approach, it wasn't about
> splitting for the sake of splitting, nor for the sake of "work".
> 
> A more granular split is just a means, and the goal is to place things
> at different stages in the most appropriate locations.
> 
>> Besides, it also leads to a rule that child of Device's
>> .post_instance_init() needs to be careful about changing the property or
>> anything that might affect the property,
> 
> I believe that's how things should be. instance_post_init() provides an
> opportunity to tweak properties. The order of instance_post_init()
> reflects the dependency relationships for property adjustments. As I
> mentioned earlier, if a property doesn't need to consider other factors
> and is simply being initialized, instance_init() is the most appropriate
> place for it.

The reason why accelerator's instance_init() was moved to post_init, was 
just it needs to consider other factors. Please see commit 4db4385a7ab6 
("i386: run accel_cpu_instance_init as post_init")

accelerator needs to do different tweak for "max/host", "xcc->model".

Of course we can split it and put specific handling at the end of each 
sub-class's instance_init(), like below:

- in TYPE_X86_CPU instance_init()
	
	if (accelerator_kvm) {
		kvm_instance_init_common_for_x86_cpu();
	}

- in "base" instance_init()

	if (accelerator_kvm) {
		kvm_instance_init_for_base();
	}

- in "max" instance_init()

	if (accelerator_kvm) {
		kvm_instance_init_for_max();
	}

- in "host" instance_init()

	if (accelerator_kvm) {
		kvm_instance_init_for_host();
	}

- in "named cpu model" instance_init()

	if (xcc->model)	{
		kvm_instance_init_for_xcc_model();
	}

Contrast to the current implementation in post_init()

	if (accelerator_kvm) {
		kvm_instance_init_common_for_x86_cpu();

		if (base)
			...
		if (max)
			...
		if (host)
			...
		if (xcc->model)
			...
	}

The reality for the former might be simpler since "base" doesn't have 
instance_init(), and "max/host" are same to KVM as "cpu->max_features"

But I still like the latter.




^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-03  3:36                           ` Xiaoyao Li
@ 2025-07-03  4:51                             ` Paolo Bonzini
  2025-07-07 15:41                               ` Paolo Bonzini
  0 siblings, 1 reply; 53+ messages in thread
From: Paolo Bonzini @ 2025-07-03  4:51 UTC (permalink / raw)
  To: Xiaoyao Li
  Cc: Zhao Liu, Philippe Mathieu-Daudé, Dongli Zhang, Thomas Huth,
	qemu-devel, Alistair Francis, Like Xu, Igor Mammedov

[-- Attachment #1: Type: text/plain, Size: 2699 bytes --]

Il mer 2 lug 2025, 23:36 Xiaoyao Li <xiaoyao.li@intel.com> ha scritto:

> The reason why accelerator's instance_init() was moved to post_init, was
> just it needs to consider other factors. Please see commit 4db4385a7ab6
> ("i386: run accel_cpu_instance_init as post_init")
>

You're right and this can be a problem with the simple split that Zhao
proposed. But the root cause is that post_init is confusing many kinds of
defaults (the KVM vendor case, globals which are different for compat
properties and -global and which CPUs also abuse to implement -cpu by the
way, max_features handling, maybe more; all of which have different
priorities).

TDX added checks on top, and instance_post_init worked when applying class
defaults but not for checks. But as mentioned in the commit message for
this patch, cxl_dsp_instance_post_init and
rp_instance_post_init have similar issues so reverting is also incorrect.

Maybe DeviceClass needs another callback that is called before Device's own
instance_post_init. The accelerator could use it.

Or maybe, more long term, instance_post_init could be replaced by a set of
Notifiers that are registered by instance_init and that have a priority
(FIXUP_CLASS_DEFAULTS, APPLY_GLOBAL_DEFAULTS, and a third for TDX).

Paolo

accelerator needs to do different tweak for "max/host", "xcc->model".
>
> Of course we can split it and put specific handling at the end of each
> sub-class's instance_init(), like below:
>
> - in TYPE_X86_CPU instance_init()
>
>         if (accelerator_kvm) {
>                 kvm_instance_init_common_for_x86_cpu();
>         }
>
> - in "base" instance_init()
>
>         if (accelerator_kvm) {
>                 kvm_instance_init_for_base();
>         }
>
> - in "max" instance_init()
>
>         if (accelerator_kvm) {
>                 kvm_instance_init_for_max();
>         }
>
> - in "host" instance_init()
>
>         if (accelerator_kvm) {
>                 kvm_instance_init_for_host();
>         }
>
> - in "named cpu model" instance_init()
>
>         if (xcc->model) {
>                 kvm_instance_init_for_xcc_model();
>         }
>
> Contrast to the current implementation in post_init()
>
>         if (accelerator_kvm) {
>                 kvm_instance_init_common_for_x86_cpu();
>
>                 if (base)
>                         ...
>                 if (max)
>                         ...
>                 if (host)
>                         ...
>                 if (xcc->model)
>                         ...
>         }
>
> The reality for the former might be simpler since "base" doesn't have
> instance_init(), and "max/host" are same to KVM as "cpu->max_features"
>
> But I still like the latter.
>
>
>

[-- Attachment #2: Type: text/html, Size: 4042 bytes --]

^ permalink raw reply	[flat|nested] 53+ messages in thread

* Re: [Regression] Re: [PULL 35/35] qom: reverse order of instance_post_init calls
  2025-07-03  4:51                             ` Paolo Bonzini
@ 2025-07-07 15:41                               ` Paolo Bonzini
  0 siblings, 0 replies; 53+ messages in thread
From: Paolo Bonzini @ 2025-07-07 15:41 UTC (permalink / raw)
  To: Xiaoyao Li
  Cc: Zhao Liu, Philippe Mathieu-Daudé, Dongli Zhang, Thomas Huth,
	qemu-devel, Alistair Francis, Like Xu, Igor Mammedov

[-- Attachment #1: Type: text/plain, Size: 3194 bytes --]

Il gio 3 lug 2025, 06:51 Paolo Bonzini <pbonzini@redhat.com> ha scritto:

>
>
> Il mer 2 lug 2025, 23:36 Xiaoyao Li <xiaoyao.li@intel.com> ha scritto:
>
>> The reason why accelerator's instance_init() was moved to post_init, was
>> just it needs to consider other factors. Please see commit 4db4385a7ab6
>> ("i386: run accel_cpu_instance_init as post_init")
>>
>
> You're right and this can be a problem with the simple split that Zhao
> proposed. But the root cause is that post_init is confusing many kinds of
> defaults (the KVM vendor case, globals which are different for compat
> properties and -global and which CPUs also abuse to implement -cpu by the
> way, max_features handling, maybe more; all of which have different
> priorities).
>

I checked and it seems to me that all of the accelerator-specific
initialization should be doable in instance_init (which risc-v already
does), the only problem is the max_features field. But max_features is
*not* a qdev property so it can be moved to the class side.

I will try to send patches tomorrow.

Paolo


TDX added checks on top, and instance_post_init worked when applying class
> defaults but not for checks. But as mentioned in the commit message for
> this patch, cxl_dsp_instance_post_init and
> rp_instance_post_init have similar issues so reverting is also incorrect.
>
> Maybe DeviceClass needs another callback that is called before Device's
> own instance_post_init. The accelerator could use it.
>
> Or maybe, more long term, instance_post_init could be replaced by a set of
> Notifiers that are registered by instance_init and that have a priority
> (FIXUP_CLASS_DEFAULTS, APPLY_GLOBAL_DEFAULTS, and a third for TDX).
>
> Paolo
>
> accelerator needs to do different tweak for "max/host", "xcc->model".
>>
>> Of course we can split it and put specific handling at the end of each
>> sub-class's instance_init(), like below:
>>
>> - in TYPE_X86_CPU instance_init()
>>
>>         if (accelerator_kvm) {
>>                 kvm_instance_init_common_for_x86_cpu();
>>         }
>>
>> - in "base" instance_init()
>>
>>         if (accelerator_kvm) {
>>                 kvm_instance_init_for_base();
>>         }
>>
>> - in "max" instance_init()
>>
>>         if (accelerator_kvm) {
>>                 kvm_instance_init_for_max();
>>         }
>>
>> - in "host" instance_init()
>>
>>         if (accelerator_kvm) {
>>                 kvm_instance_init_for_host();
>>         }
>>
>> - in "named cpu model" instance_init()
>>
>>         if (xcc->model) {
>>                 kvm_instance_init_for_xcc_model();
>>         }
>>
>> Contrast to the current implementation in post_init()
>>
>>         if (accelerator_kvm) {
>>                 kvm_instance_init_common_for_x86_cpu();
>>
>>                 if (base)
>>                         ...
>>                 if (max)
>>                         ...
>>                 if (host)
>>                         ...
>>                 if (xcc->model)
>>                         ...
>>         }
>>
>> The reality for the former might be simpler since "base" doesn't have
>> instance_init(), and "max/host" are same to KVM as "cpu->max_features"
>>
>> But I still like the latter.
>>
>>
>>

[-- Attachment #2: Type: text/html, Size: 5157 bytes --]

^ permalink raw reply	[flat|nested] 53+ messages in thread

end of thread, other threads:[~2025-07-07 16:03 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-20 11:04 [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Paolo Bonzini
2025-05-20 11:04 ` [PULL 01/35] i386/tcg: Make CPUID_HT and CPUID_EXT3_CMP_LEG supported Paolo Bonzini
2025-05-20 11:04 ` [PULL 02/35] i386/hvf: Make CPUID_HT supported Paolo Bonzini
2025-05-20 11:04 ` [PULL 03/35] hw/pci-host/gt64120: Fix endianness handling Paolo Bonzini
2025-05-20 11:04 ` [PULL 04/35] hw/pci-host: Remove unused pci_host_data_be_ops Paolo Bonzini
2025-05-20 11:05 ` [PULL 05/35] qapi/misc-target: Rename SGXEPCSection to SgxEpcSection Paolo Bonzini
2025-05-20 11:05 ` [PULL 06/35] qapi/misc-target: Rename SGXInfo to SgxInfo Paolo Bonzini
2025-05-20 11:05 ` [PULL 07/35] qapi/misc-target: Fix the doc related SGXEPCSection Paolo Bonzini
2025-05-20 11:05 ` [PULL 08/35] qapi/misc-target: Fix the doc to distinguish query-sgx and query-sgx-capabilities Paolo Bonzini
2025-05-20 11:05 ` [PULL 09/35] hw/riscv: acpi: only create RHCT MMU entry for supported types Paolo Bonzini
2025-05-20 11:05 ` [PULL 10/35] target/riscv: assert argument to set_satp_mode_max_supported is valid Paolo Bonzini
2025-05-20 11:05 ` [PULL 11/35] target/riscv: cpu: store max SATP mode as a single integer Paolo Bonzini
2025-05-20 11:05 ` [PULL 12/35] target/riscv: update max_satp_mode based on QOM properties Paolo Bonzini
2025-05-20 11:05 ` [PULL 13/35] target/riscv: remove supported from RISCVSATPMap Paolo Bonzini
2025-05-20 11:05 ` [PULL 14/35] target/riscv: move satp_mode.{map, init} out of CPUConfig Paolo Bonzini via
2025-05-20 11:05 ` [PULL 15/35] target/riscv: introduce RISCVCPUDef Paolo Bonzini
2025-05-20 11:05 ` [PULL 16/35] target/riscv: store RISCVCPUDef struct directly in the class Paolo Bonzini
2025-05-20 11:05 ` [PULL 17/35] target/riscv: merge riscv_cpu_class_init with the class_base function Paolo Bonzini
2025-05-20 11:05 ` [PULL 18/35] target/riscv: move RISCVCPUConfig fields to a header file Paolo Bonzini
2025-05-20 11:05 ` [PULL 19/35] target/riscv: include default value in cpu_cfg_fields.h.inc Paolo Bonzini
2025-05-20 11:05 ` [PULL 20/35] target/riscv: add more RISCVCPUDef fields Paolo Bonzini
2025-05-20 11:05 ` [PULL 21/35] target/riscv: convert abstract CPU classes to RISCVCPUDef Paolo Bonzini
2025-05-20 11:05 ` [PULL 22/35] target/riscv: convert profile CPU models " Paolo Bonzini
2025-05-20 11:05 ` [PULL 23/35] target/riscv: convert bare " Paolo Bonzini
2025-05-20 11:05 ` [PULL 24/35] target/riscv: convert dynamic " Paolo Bonzini
2025-05-20 11:05 ` [PULL 25/35] target/riscv: convert SiFive E " Paolo Bonzini
2025-05-20 11:05 ` [PULL 26/35] target/riscv: convert ibex " Paolo Bonzini
2025-05-20 11:05 ` [PULL 27/35] target/riscv: convert SiFive U " Paolo Bonzini
2025-05-20 11:05 ` [PULL 28/35] target/riscv: th: make CSR insertion test a bit more intuitive Paolo Bonzini
2025-05-20 11:05 ` [PULL 29/35] target/riscv: generalize custom CSR functionality Paolo Bonzini
2025-05-20 11:05 ` [PULL 30/35] target/riscv: convert THead C906 to RISCVCPUDef Paolo Bonzini
2025-05-20 11:05 ` [PULL 31/35] target/riscv: convert TT Ascalon " Paolo Bonzini
2025-05-20 11:05 ` [PULL 32/35] target/riscv: convert Ventana V1 " Paolo Bonzini
2025-05-20 11:05 ` [PULL 33/35] target/riscv: convert Xiangshan Nanhu " Paolo Bonzini
2025-05-20 11:05 ` [PULL 34/35] target/riscv: remove .instance_post_init Paolo Bonzini
2025-05-20 11:05 ` [PULL 35/35] qom: reverse order of instance_post_init calls Paolo Bonzini
2025-06-23 16:56   ` [Regression] " Dongli Zhang
2025-06-24  8:57     ` Zhao Liu
2025-06-30 15:22       ` Zhao Liu
2025-07-01  6:50         ` Xiaoyao Li
2025-07-02  6:54           ` Philippe Mathieu-Daudé
2025-07-02  7:56             ` Zhao Liu
2025-07-02 11:42               ` Xiaoyao Li
2025-07-02 12:12                 ` Paolo Bonzini
2025-07-02 13:24                   ` Xiaoyao Li
2025-07-02 18:54                     ` Paolo Bonzini
2025-07-03  1:03                       ` Xiaoyao Li
2025-07-03  3:08                         ` Zhao Liu
2025-07-03  3:36                           ` Xiaoyao Li
2025-07-03  4:51                             ` Paolo Bonzini
2025-07-07 15:41                               ` Paolo Bonzini
2025-07-02 12:06             ` Paolo Bonzini
2025-05-21 14:06 ` [PULL 00/35] RISCV, i386, endianness fixes for 2025-05-20 Stefan Hajnoczi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).