Fourth RISC-V PR for 8.2

This is a few bug fixes for the 8.2 release
 
 * Add Zicboz block size to hwprobe
 * Creat the virt machine FDT before machine init is complete
 * Don't verify ISA compatibility for zicntr and zihpm
 * Fix SiFive E CLINT clock frequency
 * Fix invalid exception on MMU translation stage
 * Fix mxr bit behavior
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEaukCtqfKh31tZZKWr3yVEwxTgBMFAmVdk4sACgkQr3yVEwxT
 gBP6gQ/+NzdRT8Wx/9ynnKs0XwXBwOjQTHDcxCIKLWYrM26c3M+4XEU6IBdg2X1T
 qRv9Xal/pXqvAz8tIunF1fNd0Syom4UezcjvLjzipWwS32+D9KEKhKz89aoQc2SQ
 lnTBYz6lSUNppp3wj68gNAyPpht+5zVwYZDsjeZCRlAS00dcl26Xde8kt9tJW7zy
 tPBvHtJP9AVc+HJdClytEZ79G+EHN5Y4ScoJsVinXSBZs9lIQD+nPmFbxopre6kg
 +RUk56eATIlVMISD5pCYyCr3jTebMqVIFY9xtQxb4R09aLYN6+k13NfsJeIcQgaF
 MbhAGE0WbXEhKyHe4BuVtyz2k+zYtoh6YSE2Czub2pzPAfpKKWiu4Odi7vHlYejw
 Nksn3N7LR3FbhrDst71+EQ28vUuEYfECEFICjzHb+DhxlPxHW9WC4f8ciTUpT57O
 HPWYN7zn5Yw97nGBVuITVO7DfcQcw8MS8HcFEelkeDOephiDKr327SWTL+lp5+P5
 fm7PM4Z92GRvT3Voj4mebVxC62CGqehDotWRvXCvc87m4DfLsmpt0nNeX9q18zw+
 phEZ5Q8AMmEnRzpmoXEzzcDWyJIO6huJFad0imTR6MqvXYxsJYIr+wURDB6POelP
 SfMqdX9cTu8xJ7Hw4gJT9ZgcTlKsTq5LNpGZ/kLPXS6/y7fgC5Y=
 =QK14
 -----END PGP SIGNATURE-----

Merge tag 'pull-riscv-to-apply-20231122' of https://github.com/alistair23/qemu into staging

Fourth RISC-V PR for 8.2

This is a few bug fixes for the 8.2 release

* Add Zicboz block size to hwprobe
* Creat the virt machine FDT before machine init is complete
* Don't verify ISA compatibility for zicntr and zihpm
* Fix SiFive E CLINT clock frequency
* Fix invalid exception on MMU translation stage
* Fix mxr bit behavior

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEaukCtqfKh31tZZKWr3yVEwxTgBMFAmVdk4sACgkQr3yVEwxT
# gBP6gQ/+NzdRT8Wx/9ynnKs0XwXBwOjQTHDcxCIKLWYrM26c3M+4XEU6IBdg2X1T
# qRv9Xal/pXqvAz8tIunF1fNd0Syom4UezcjvLjzipWwS32+D9KEKhKz89aoQc2SQ
# lnTBYz6lSUNppp3wj68gNAyPpht+5zVwYZDsjeZCRlAS00dcl26Xde8kt9tJW7zy
# tPBvHtJP9AVc+HJdClytEZ79G+EHN5Y4ScoJsVinXSBZs9lIQD+nPmFbxopre6kg
# +RUk56eATIlVMISD5pCYyCr3jTebMqVIFY9xtQxb4R09aLYN6+k13NfsJeIcQgaF
# MbhAGE0WbXEhKyHe4BuVtyz2k+zYtoh6YSE2Czub2pzPAfpKKWiu4Odi7vHlYejw
# Nksn3N7LR3FbhrDst71+EQ28vUuEYfECEFICjzHb+DhxlPxHW9WC4f8ciTUpT57O
# HPWYN7zn5Yw97nGBVuITVO7DfcQcw8MS8HcFEelkeDOephiDKr327SWTL+lp5+P5
# fm7PM4Z92GRvT3Voj4mebVxC62CGqehDotWRvXCvc87m4DfLsmpt0nNeX9q18zw+
# phEZ5Q8AMmEnRzpmoXEzzcDWyJIO6huJFad0imTR6MqvXYxsJYIr+wURDB6POelP
# SfMqdX9cTu8xJ7Hw4gJT9ZgcTlKsTq5LNpGZ/kLPXS6/y7fgC5Y=
# =QK14
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 22 Nov 2023 00:37:15 EST
# gpg:                using RSA key 6AE902B6A7CA877D6D659296AF7C95130C538013
# gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6AE9 02B6 A7CA 877D 6D65  9296 AF7C 9513 0C53 8013

* tag 'pull-riscv-to-apply-20231122' of https://github.com/alistair23/qemu:
  target/riscv/cpu_helper.c: Fix mxr bit behavior
  target/riscv/cpu_helper.c: Invalid exception on MMU translation stage
  riscv: Fix SiFive E CLINT clock frequency
  target/riscv: don't verify ISA compatibility for zicntr and zihpm
  hw/riscv/virt.c: do create_fdt() earlier, add finalize_fdt()
  linux-user/riscv: Add Zicboz block size to hwprobe

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2023-11-22 09:39:23 -05:00
commit b93c4313f2
5 changed files with 85 additions and 57 deletions

View File

@ -225,7 +225,7 @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
RISCV_ACLINT_SWI_SIZE,
RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, ms->smp.cpus,
RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, false);
SIFIVE_E_LFCLK_DEFAULT_FREQ, false);
sifive_e_prci_create(memmap[SIFIVE_E_DEV_PRCI].base);
/* AON */

View File

@ -962,7 +962,6 @@ static void create_fdt_uart(RISCVVirtState *s, const MemMapEntry *memmap,
qemu_fdt_setprop_cells(ms->fdt, name, "interrupts", UART0_IRQ, 0x4);
}
qemu_fdt_add_subnode(ms->fdt, "/chosen");
qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", name);
g_free(name);
}
@ -1023,11 +1022,29 @@ static void create_fdt_fw_cfg(RISCVVirtState *s, const MemMapEntry *memmap)
g_free(nodename);
}
static void finalize_fdt(RISCVVirtState *s)
{
uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1;
create_fdt_sockets(s, virt_memmap, &phandle, &irq_mmio_phandle,
&irq_pcie_phandle, &irq_virtio_phandle,
&msi_pcie_phandle);
create_fdt_virtio(s, virt_memmap, irq_virtio_phandle);
create_fdt_pcie(s, virt_memmap, irq_pcie_phandle, msi_pcie_phandle);
create_fdt_reset(s, virt_memmap, &phandle);
create_fdt_uart(s, virt_memmap, irq_mmio_phandle);
create_fdt_rtc(s, virt_memmap, irq_mmio_phandle);
}
static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap)
{
MachineState *ms = MACHINE(s);
uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1;
uint8_t rng_seed[32];
ms->fdt = create_device_tree(&s->fdt_size);
@ -1047,28 +1064,16 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap)
qemu_fdt_setprop_cell(ms->fdt, "/soc", "#size-cells", 0x2);
qemu_fdt_setprop_cell(ms->fdt, "/soc", "#address-cells", 0x2);
create_fdt_sockets(s, memmap, &phandle, &irq_mmio_phandle,
&irq_pcie_phandle, &irq_virtio_phandle,
&msi_pcie_phandle);
create_fdt_virtio(s, memmap, irq_virtio_phandle);
create_fdt_pcie(s, memmap, irq_pcie_phandle, msi_pcie_phandle);
create_fdt_reset(s, memmap, &phandle);
create_fdt_uart(s, memmap, irq_mmio_phandle);
create_fdt_rtc(s, memmap, irq_mmio_phandle);
create_fdt_flash(s, memmap);
create_fdt_fw_cfg(s, memmap);
create_fdt_pmu(s);
qemu_fdt_add_subnode(ms->fdt, "/chosen");
/* Pass seed to RNG */
qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
qemu_fdt_setprop(ms->fdt, "/chosen", "rng-seed",
rng_seed, sizeof(rng_seed));
create_fdt_flash(s, memmap);
create_fdt_fw_cfg(s, memmap);
create_fdt_pmu(s);
}
static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
@ -1257,15 +1262,12 @@ static void virt_machine_done(Notifier *notifier, void *data)
uint64_t kernel_entry = 0;
BlockBackend *pflash_blk0;
/* load/create device tree */
if (machine->dtb) {
machine->fdt = load_device_tree(machine->dtb, &s->fdt_size);
if (!machine->fdt) {
error_report("load_device_tree() failed");
exit(1);
}
} else {
create_fdt(s, memmap);
/*
* An user provided dtb must include everything, including
* dynamic sysbus devices. Our FDT needs to be finalized.
*/
if (machine->dtb == NULL) {
finalize_fdt(s);
}
/*
@ -1541,6 +1543,17 @@ static void virt_machine_init(MachineState *machine)
}
virt_flash_map(s, system_memory);
/* load/create device tree */
if (machine->dtb) {
machine->fdt = load_device_tree(machine->dtb, &s->fdt_size);
if (!machine->fdt) {
error_report("load_device_tree() failed");
exit(1);
}
} else {
create_fdt(s, memmap);
}
s->machine_done.notify = virt_machine_done;
qemu_add_machine_init_done_notifier(&s->machine_done);
}

View File

@ -8808,6 +8808,8 @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
struct riscv_hwprobe {
abi_llong key;
abi_ullong value;
@ -8860,6 +8862,10 @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env,
case RISCV_HWPROBE_KEY_CPUPERF_0:
__put_user(RISCV_HWPROBE_MISALIGNED_FAST, &pair->value);
break;
case RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE:
value = cfg->ext_zicboz ? cfg->cboz_blocksize : 0;
__put_user(value, &pair->value);
break;
default:
__put_user(-1, &pair->key);
break;

View File

@ -1032,13 +1032,29 @@ restart:
prot |= PAGE_WRITE;
}
if (pte & PTE_X) {
bool mxr;
bool mxr = false;
if (first_stage == true) {
/*
* Use mstatus for first stage or for the second stage without
* virt_enabled (MPRV+MPV)
*/
if (first_stage || !env->virt_enabled) {
mxr = get_field(env->mstatus, MSTATUS_MXR);
} else {
mxr = get_field(env->vsstatus, MSTATUS_MXR);
}
/* MPRV+MPV case, check VSSTATUS */
if (first_stage && two_stage && !env->virt_enabled) {
mxr |= get_field(env->vsstatus, MSTATUS_MXR);
}
/*
* Setting MXR at HS-level overrides both VS-stage and G-stage
* execute-only permissions
*/
if (env->virt_enabled) {
mxr |= get_field(env->mstatus_hs, MSTATUS_MXR);
}
if (mxr) {
prot |= PAGE_READ;
}
@ -1143,47 +1159,31 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
bool two_stage_indirect)
{
CPUState *cs = env_cpu(env);
int page_fault_exceptions, vm;
uint64_t stap_mode;
if (riscv_cpu_mxl(env) == MXL_RV32) {
stap_mode = SATP32_MODE;
} else {
stap_mode = SATP64_MODE;
}
if (first_stage) {
vm = get_field(env->satp, stap_mode);
} else {
vm = get_field(env->hgatp, stap_mode);
}
page_fault_exceptions = vm != VM_1_10_MBARE && !pmp_violation;
switch (access_type) {
case MMU_INST_FETCH:
if (env->virt_enabled && !first_stage) {
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
} else {
cs->exception_index = page_fault_exceptions ?
RISCV_EXCP_INST_PAGE_FAULT : RISCV_EXCP_INST_ACCESS_FAULT;
cs->exception_index = pmp_violation ?
RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
}
break;
case MMU_DATA_LOAD:
if (two_stage && !first_stage) {
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
} else {
cs->exception_index = page_fault_exceptions ?
RISCV_EXCP_LOAD_PAGE_FAULT : RISCV_EXCP_LOAD_ACCESS_FAULT;
cs->exception_index = pmp_violation ?
RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
}
break;
case MMU_DATA_STORE:
if (two_stage && !first_stage) {
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
} else {
cs->exception_index = page_fault_exceptions ?
RISCV_EXCP_STORE_PAGE_FAULT :
RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
cs->exception_index = pmp_violation ?
RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
RISCV_EXCP_STORE_PAGE_FAULT;
}
break;
default:

View File

@ -250,6 +250,15 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
for (edata = isa_edata_arr; edata && edata->name; edata++) {
if (isa_ext_is_enabled(cpu, edata->ext_enable_offset) &&
(env->priv_ver < edata->min_version)) {
/*
* These two extensions are always enabled as they were supported
* by QEMU before they were added as extensions in the ISA.
*/
if (!strcmp(edata->name, "zicntr") ||
!strcmp(edata->name, "zihpm")) {
continue;
}
isa_ext_update_enabled(cpu, edata->ext_enable_offset, false);
#ifndef CONFIG_USER_ONLY
warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx