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 |
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 --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,
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(-)