aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-02-18 11:09:15 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2025-05-20 08:04:19 +0200
commit211c7f9bb817ca7bb7855535da4db5ca80a8aa1d (patch)
tree73cfe0cf59ed7d9f133d9d01607f23d395785ec3
parent357ce8171a9c7581ba02475874c8c28ed5220d9e (diff)
downloadqemu-211c7f9bb817ca7bb7855535da4db5ca80a8aa1d.zip
qemu-211c7f9bb817ca7bb7855535da4db5ca80a8aa1d.tar.gz
qemu-211c7f9bb817ca7bb7855535da4db5ca80a8aa1d.tar.bz2
target/riscv: update max_satp_mode based on QOM properties
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>
-rw-r--r--hw/riscv/virt-acpi-build.c14
-rw-r--r--hw/riscv/virt.c5
-rw-r--r--target/riscv/cpu.c27
-rw-r--r--target/riscv/cpu.h1
-rw-r--r--target/riscv/csr.c9
5 files changed, 24 insertions, 32 deletions
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index e693d52..8b5683d 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 0dcced1..cf280a9 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 32c283a..48576bf 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/cpu.h b/target/riscv/cpu.h
index b56d3af..3d89a4a 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/target/riscv/csr.c b/target/riscv/csr.c
index 288edee..9843fd2 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,