diff mbox series

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

Message ID 20250218165757.554178-6-pbonzini@redhat.com (mailing list archive)
State New
Headers show
Series target/riscv: store max SATP mode as a single integer in RISCVCPUConfig | expand

Commit Message

Paolo Bonzini Feb. 18, 2025, 4:57 p.m. UTC
Almost all users of cpu->cfg.satp_mode care only about the "max" value
satp_mode_max_from_map(cpu->cfg.satp_mode.map); convert the QOM
properties back into it.  For TCG, consult valid_vm[] instead of
the bitmap of accepted modes.

Signed-off-by: Paolo Bonzini <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(-)

Comments

Alistair Francis March 6, 2025, 1:41 a.m. UTC | #1
On Wed, Feb 19, 2025 at 2:59 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> Almost all users of cpu->cfg.satp_mode care only about the "max" value
> satp_mode_max_from_map(cpu->cfg.satp_mode.map); convert the QOM
> properties back into it.  For TCG, consult valid_vm[] instead of
> the bitmap of accepted modes.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

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

Patch

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