diff options
author | leyfoon.tan <leyfoon.tan@starfivetech.com> | 2024-01-17 06:40:24 +0300 |
---|---|---|
committer | leyfoon.tan <leyfoon.tan@starfivetech.com> | 2024-01-17 06:40:24 +0300 |
commit | 47450656d5d697f02885c8705eae604d3baaee3f (patch) | |
tree | 44f9e992f84c7d60f396f7d9e6e124856154187d | |
parent | 7cbc059d3374bda04199750691accd2fa2044e9a (diff) | |
parent | 30387e227506433af5072cebac0727751a7e87e1 (diff) | |
download | linux-47450656d5d697f02885c8705eae604d3baaee3f.tar.xz |
Merge branch 'starfive-6.6.10-dubhe-Add-Dubhe70' into 'starfive-6.6.10-dubhe'
arch: riscv: starfive: Add Dubhe70 support
See merge request starfive-tech/linux!246
-rw-r--r-- | Documentation/devicetree/bindings/riscv/cpus.yaml | 1 | ||||
-rw-r--r-- | arch/riscv/boot/dts/starfive/Makefile | 1 | ||||
-rwxr-xr-x | arch/riscv/boot/dts/starfive/dubhe.dtsi | 10 | ||||
-rw-r--r-- | arch/riscv/boot/dts/starfive/dubhe70.dtsi | 48 | ||||
-rw-r--r-- | arch/riscv/boot/dts/starfive/dubhe70_fpga.dts | 5 | ||||
-rw-r--r-- | arch/riscv/errata/starfive/errata.c | 38 | ||||
-rw-r--r-- | arch/riscv/include/asm/cpufeature.h | 1 | ||||
-rw-r--r-- | arch/riscv/include/asm/csr.h | 18 | ||||
-rw-r--r-- | arch/riscv/include/asm/errata_list.h | 2 | ||||
-rw-r--r-- | arch/riscv/include/asm/hwcap.h | 18 | ||||
-rw-r--r-- | arch/riscv/include/asm/kvm_host.h | 18 | ||||
-rw-r--r-- | arch/riscv/include/uapi/asm/kvm.h | 11 | ||||
-rw-r--r-- | arch/riscv/kernel/cpufeature.c | 12 | ||||
-rw-r--r-- | arch/riscv/kernel/setup.c | 4 | ||||
-rw-r--r-- | arch/riscv/kernel/smpboot.c | 4 | ||||
-rw-r--r-- | arch/riscv/kvm/vcpu.c | 78 | ||||
-rw-r--r-- | arch/riscv/kvm/vcpu_onereg.c | 72 | ||||
-rw-r--r-- | tools/perf/pmu-events/arch/riscv/mapfile.csv | 3 | ||||
-rw-r--r-- | tools/perf/pmu-events/arch/riscv/starfive/dubhe-80/firmware.json | 68 | ||||
-rw-r--r-- | tools/perf/pmu-events/arch/riscv/starfive/dubhe-90/common.json | 172 |
20 files changed, 380 insertions, 204 deletions
diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml index a1c105e2fcf7..6ef8cf448823 100644 --- a/Documentation/devicetree/bindings/riscv/cpus.yaml +++ b/Documentation/devicetree/bindings/riscv/cpus.yaml @@ -47,6 +47,7 @@ properties: - sifive,u74-mc - thead,c906 - thead,c910 + - starfive,dubhe-70 - starfive,dubhe-80 - starfive,dubhe-90 - const: riscv diff --git a/arch/riscv/boot/dts/starfive/Makefile b/arch/riscv/boot/dts/starfive/Makefile index a8a97301e8fa..aab2781fbc76 100644 --- a/arch/riscv/boot/dts/starfive/Makefile +++ b/arch/riscv/boot/dts/starfive/Makefile @@ -14,3 +14,4 @@ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb dtb-$(CONFIG_ARCH_STARFIVE) += dubhe90_fpga.dtb dtb-$(CONFIG_ARCH_STARFIVE) += dubhe90_fpga_dual.dtb dtb-$(CONFIG_ARCH_STARFIVE) += dubhe80_fpga.dtb +dtb-$(CONFIG_ARCH_STARFIVE) += dubhe70_fpga.dtb diff --git a/arch/riscv/boot/dts/starfive/dubhe.dtsi b/arch/riscv/boot/dts/starfive/dubhe.dtsi index 580eea819f4d..5ec30a7d9423 100755 --- a/arch/riscv/boot/dts/starfive/dubhe.dtsi +++ b/arch/riscv/boot/dts/starfive/dubhe.dtsi @@ -17,7 +17,10 @@ mmu-type = "riscv,sv48"; next-level-cache = <&l2_cache>; reg = <0x0>; - riscv,isa = "rv64imafdcbh_sscofpmf"; + riscv,isa = "rv64imafdcbh"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h", + "zicntr", "zicsr", "zifencei", "zihpm", "sscofpmf"; tlb-split; cpu0_intc: interrupt-controller { @@ -33,7 +36,10 @@ mmu-type = "riscv,sv48"; next-level-cache = <&l2_cache>; reg = <0x1>; - riscv,isa = "rv64imafdcbh_sscofpmf"; + riscv,isa = "rv64imafdcbh"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h", + "zicntr", "zicsr", "zifencei", "zihpm", "sscofpmf"; tlb-split; cpu1_intc: interrupt-controller { diff --git a/arch/riscv/boot/dts/starfive/dubhe70.dtsi b/arch/riscv/boot/dts/starfive/dubhe70.dtsi new file mode 100644 index 000000000000..8060e0f2ad5b --- /dev/null +++ b/arch/riscv/boot/dts/starfive/dubhe70.dtsi @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2023 StarFive Technology Co., Ltd. */ + +#include "dubhe.dtsi" + +&cpu0 { + compatible = "starfive,dubhe-70", "riscv"; + riscv,isa = "rv64imafdcbh"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h", "zicbom", + "zicboz", "zicntr", "zicond", "zicsr", "zifencei", + "zihintpause", "zihpm", "svinval", "svnapot", "svpbmt", + "sscofpmf"; + riscv,cbom-block-size = <64>; + riscv,cboz-block-size = <64>; + d-cache-block-size = <64>; + d-cache-sets = <512>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <16>; + i-cache-block-size = <64>; + i-cache-sets = <512>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <24>; +}; + +&cpu1 { + compatible = "starfive,dubhe-70", "riscv"; + riscv,isa = "rv64imafdcbh"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h", "zicbom", + "zicboz", "zicntr", "zicond", "zicsr", "zifencei", + "zihintpause", "zihpm", "svinval", "svnapot", "svpbmt", + "sscofpmf"; + riscv,cbom-block-size = <64>; + riscv,cboz-block-size = <64>; + d-cache-block-size = <64>; + d-cache-sets = <512>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <16>; + i-cache-block-size = <64>; + i-cache-sets = <512>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <24>; +}; diff --git a/arch/riscv/boot/dts/starfive/dubhe70_fpga.dts b/arch/riscv/boot/dts/starfive/dubhe70_fpga.dts new file mode 100644 index 000000000000..a4e9ea608cb8 --- /dev/null +++ b/arch/riscv/boot/dts/starfive/dubhe70_fpga.dts @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2023 StarFive Technology Co., Ltd. */ + +#include "dubhe70.dtsi" +#include "dubhe_fpga_common.dtsi" diff --git a/arch/riscv/errata/starfive/errata.c b/arch/riscv/errata/starfive/errata.c index b7e757207d54..c774ec16d87d 100644 --- a/arch/riscv/errata/starfive/errata.c +++ b/arch/riscv/errata/starfive/errata.c @@ -23,26 +23,45 @@ #define STARFIVE_DUBHE80_MARCHID 0x80000000DB000080UL #define STARFIVE_DUBHE80_MIMPID 0x0000000020230831UL -static bool errata_probe_cmo(unsigned int stage, unsigned long arch_id, - unsigned long impid) +#define STARFIVE_DUBHE70_MARCHID 0x80000000DB000070UL +#define STARFIVE_DUBHE70_MIMPID 0x0000000020240131UL + +DEFINE_STATIC_KEY_FALSE(bypass_envcfg_csr_key); + +static void errata_probe_cmo(unsigned int stage, unsigned long arch_id, + unsigned long impid) { if (!IS_ENABLED(CONFIG_ERRATA_STARFIVE_CMO)) - return false; + return; if (arch_id == STARFIVE_DUBHE90_MARCHID) { if (impid > STARFIVE_DUBHE90_MIMPID) - return false; + return; } if (arch_id == STARFIVE_DUBHE80_MARCHID) { if (impid > STARFIVE_DUBHE80_MIMPID) - return false; + return; } riscv_cbom_block_size = L1_CACHE_BYTES; riscv_noncoherent_supported(); +} + +static void errata_bypass_envcfg_csr(unsigned int stage, unsigned long arch_id, + unsigned long impid) +{ + if (arch_id == STARFIVE_DUBHE90_MARCHID) { + if (impid > STARFIVE_DUBHE90_MIMPID) + return; + } - return true; + if (arch_id == STARFIVE_DUBHE80_MARCHID) { + if (impid > STARFIVE_DUBHE80_MIMPID) + return; + } + + static_branch_enable(&bypass_envcfg_csr_key); } void starfive_errata_patch_func(struct alt_entry *begin, @@ -51,6 +70,11 @@ void starfive_errata_patch_func(struct alt_entry *begin, unsigned long impid, unsigned int stage) { - if (stage == RISCV_ALTERNATIVES_BOOT) + if (archid == STARFIVE_DUBHE70_MARCHID) + return; + + if (stage == RISCV_ALTERNATIVES_BOOT) { errata_probe_cmo(stage, archid, impid); + errata_bypass_envcfg_csr(stage, archid, impid); + } } diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h index d0345bd659c9..13b7d35648a9 100644 --- a/arch/riscv/include/asm/cpufeature.h +++ b/arch/riscv/include/asm/cpufeature.h @@ -31,5 +31,6 @@ DECLARE_PER_CPU(long, misaligned_access_speed); extern struct riscv_isainfo hart_isa[NR_CPUS]; void check_unaligned_access(int cpu); +void riscv_user_isa_enable(void); #endif diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 777cb8299551..306a19a5509c 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -203,6 +203,18 @@ #define ENVCFG_CBIE_INV _AC(0x3, UL) #define ENVCFG_FIOM _AC(0x1, UL) +/* Smstateen bits */ +#define SMSTATEEN0_AIA_IMSIC_SHIFT 58 +#define SMSTATEEN0_AIA_IMSIC (_ULL(1) << SMSTATEEN0_AIA_IMSIC_SHIFT) +#define SMSTATEEN0_AIA_SHIFT 59 +#define SMSTATEEN0_AIA (_ULL(1) << SMSTATEEN0_AIA_SHIFT) +#define SMSTATEEN0_AIA_ISEL_SHIFT 60 +#define SMSTATEEN0_AIA_ISEL (_ULL(1) << SMSTATEEN0_AIA_ISEL_SHIFT) +#define SMSTATEEN0_HSENVCFG_SHIFT 62 +#define SMSTATEEN0_HSENVCFG (_ULL(1) << SMSTATEEN0_HSENVCFG_SHIFT) +#define SMSTATEEN0_SSTATEEN0_SHIFT 63 +#define SMSTATEEN0_SSTATEEN0 (_ULL(1) << SMSTATEEN0_SSTATEEN0_SHIFT) + /* symbolic CSR names: */ #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 @@ -275,6 +287,8 @@ #define CSR_SIE 0x104 #define CSR_STVEC 0x105 #define CSR_SCOUNTEREN 0x106 +#define CSR_SENVCFG 0x10a +#define CSR_SSTATEEN0 0x10c #define CSR_SSCRATCH 0x140 #define CSR_SEPC 0x141 #define CSR_SCAUSE 0x142 @@ -349,6 +363,10 @@ #define CSR_VSIEH 0x214 #define CSR_VSIPH 0x254 +/* Hypervisor stateen CSRs */ +#define CSR_HSTATEEN0 0x60c +#define CSR_HSTATEEN0H 0x61c + #define CSR_MSTATUS 0x300 #define CSR_MISA 0x301 #define CSR_MIDELEG 0x303 diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h index 6267b6407b6e..6bbb4bf643c0 100644 --- a/arch/riscv/include/asm/errata_list.h +++ b/arch/riscv/include/asm/errata_list.h @@ -164,6 +164,8 @@ asm volatile(ALTERNATIVE( \ : "=r" (__ovl) : \ : "memory") +DECLARE_STATIC_KEY_FALSE(bypass_envcfg_csr_key); + #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h index b7b58258f6c7..fe6656af967a 100644 --- a/arch/riscv/include/asm/hwcap.h +++ b/arch/riscv/include/asm/hwcap.h @@ -58,6 +58,8 @@ #define RISCV_ISA_EXT_ZICSR 40 #define RISCV_ISA_EXT_ZIFENCEI 41 #define RISCV_ISA_EXT_ZIHPM 42 +#define RISCV_ISA_EXT_SMSTATEEN 43 +#define RISCV_ISA_EXT_ZICOND 44 #define RISCV_ISA_EXT_MAX 64 @@ -70,6 +72,7 @@ #ifndef __ASSEMBLY__ #include <linux/jump_label.h> +#include <asm/cpufeature.h> unsigned long riscv_get_elf_hwcap(void); @@ -137,6 +140,21 @@ l_yes: return true; } +static __always_inline bool riscv_cpu_has_extension_likely(int cpu, const unsigned long ext) +{ + if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && riscv_has_extension_likely(ext)) + return true; + + return __riscv_isa_extension_available(hart_isa[cpu].isa, ext); +} + +static __always_inline bool riscv_cpu_has_extension_unlikely(int cpu, const unsigned long ext) +{ + if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && riscv_has_extension_unlikely(ext)) + return true; + + return __riscv_isa_extension_available(hart_isa[cpu].isa, ext); +} #endif #endif /* _ASM_RISCV_HWCAP_H */ diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h index 1ebf20dfbaa6..0eefd9c991ae 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -162,6 +162,16 @@ struct kvm_vcpu_csr { unsigned long hvip; unsigned long vsatp; unsigned long scounteren; + unsigned long senvcfg; +}; + +struct kvm_vcpu_config { + u64 henvcfg; + u64 hstateen0; +}; + +struct kvm_vcpu_smstateen_csr { + unsigned long sstateen0; }; struct kvm_vcpu_arch { @@ -183,6 +193,8 @@ struct kvm_vcpu_arch { unsigned long host_sscratch; unsigned long host_stvec; unsigned long host_scounteren; + unsigned long host_senvcfg; + unsigned long host_sstateen0; /* CPU context of Host */ struct kvm_cpu_context host_context; @@ -193,6 +205,9 @@ struct kvm_vcpu_arch { /* CPU CSR context of Guest VCPU */ struct kvm_vcpu_csr guest_csr; + /* CPU Smstateen CSR context of Guest VCPU */ + struct kvm_vcpu_smstateen_csr smstateen_csr; + /* CPU context upon Guest VCPU reset */ struct kvm_cpu_context guest_reset_context; @@ -244,6 +259,9 @@ struct kvm_vcpu_arch { /* Performance monitoring context */ struct kvm_pmu pmu_context; + + /* 'static' configurations which are set only once */ + struct kvm_vcpu_config cfg; }; static inline void kvm_arch_sync_events(struct kvm *kvm) {} diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h index 992c5e407104..917d8cc2489e 100644 --- a/arch/riscv/include/uapi/asm/kvm.h +++ b/arch/riscv/include/uapi/asm/kvm.h @@ -80,6 +80,7 @@ struct kvm_riscv_csr { unsigned long sip; unsigned long satp; unsigned long scounteren; + unsigned long senvcfg; }; /* AIA CSR registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ @@ -93,6 +94,11 @@ struct kvm_riscv_aia_csr { unsigned long iprio2h; }; +/* Smstateen CSR for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ +struct kvm_riscv_smstateen_csr { + unsigned long sstateen0; +}; + /* TIMER registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ struct kvm_riscv_timer { __u64 frequency; @@ -131,6 +137,8 @@ enum KVM_RISCV_ISA_EXT_ID { KVM_RISCV_ISA_EXT_ZICSR, KVM_RISCV_ISA_EXT_ZIFENCEI, KVM_RISCV_ISA_EXT_ZIHPM, + KVM_RISCV_ISA_EXT_SMSTATEEN, + KVM_RISCV_ISA_EXT_ZICOND, KVM_RISCV_ISA_EXT_MAX, }; @@ -178,10 +186,13 @@ enum KVM_RISCV_SBI_EXT_ID { #define KVM_REG_RISCV_CSR (0x03 << KVM_REG_RISCV_TYPE_SHIFT) #define KVM_REG_RISCV_CSR_GENERAL (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT) #define KVM_REG_RISCV_CSR_AIA (0x1 << KVM_REG_RISCV_SUBTYPE_SHIFT) +#define KVM_REG_RISCV_CSR_SMSTATEEN (0x2 << KVM_REG_RISCV_SUBTYPE_SHIFT) #define KVM_REG_RISCV_CSR_REG(name) \ (offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long)) #define KVM_REG_RISCV_CSR_AIA_REG(name) \ (offsetof(struct kvm_riscv_aia_csr, name) / sizeof(unsigned long)) +#define KVM_REG_RISCV_CSR_SMSTATEEN_REG(name) \ + (offsetof(struct kvm_riscv_smstateen_csr, name) / sizeof(unsigned long)) /* Timer registers are mapped as type 4 */ #define KVM_REG_RISCV_TIMER (0x04 << KVM_REG_RISCV_TYPE_SHIFT) diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 1cfbba65d11a..a7ef18dabcd8 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -93,10 +93,10 @@ static bool riscv_isa_extension_check(int id) return true; case RISCV_ISA_EXT_ZICBOZ: if (!riscv_cboz_block_size) { - pr_err("Zicboz detected in ISA string, but no cboz-block-size found\n"); + pr_err("Zicboz detected in ISA string, disabling as no cboz-block-size found\n"); return false; } else if (!is_power_of_2(riscv_cboz_block_size)) { - pr_err("cboz-block-size present, but is not a power-of-2\n"); + pr_err("Zicboz disabled as cboz-block-size present, but is not a power-of-2\n"); return false; } return true; @@ -167,6 +167,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = { __RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM), __RISCV_ISA_EXT_DATA(zicboz, RISCV_ISA_EXT_ZICBOZ), __RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR), + __RISCV_ISA_EXT_DATA(zicond, RISCV_ISA_EXT_ZICOND), __RISCV_ISA_EXT_DATA(zicsr, RISCV_ISA_EXT_ZICSR), __RISCV_ISA_EXT_DATA(zifencei, RISCV_ISA_EXT_ZIFENCEI), __RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE), @@ -175,6 +176,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = { __RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB), __RISCV_ISA_EXT_DATA(zbs, RISCV_ISA_EXT_ZBS), __RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA), + __RISCV_ISA_EXT_DATA(smstateen, RISCV_ISA_EXT_SMSTATEEN), __RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA), __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF), __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC), @@ -653,6 +655,12 @@ static int check_unaligned_access_boot_cpu(void) arch_initcall(check_unaligned_access_boot_cpu); +void riscv_user_isa_enable(void) +{ + if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICBOZ)) + csr_set(CSR_SENVCFG, ENVCFG_CBZE); +} + #ifdef CONFIG_RISCV_ALTERNATIVE /* * Alternative patch sites consider 48 bits when determining when to patch diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index aac853ae4eb7..2a79d4ed2660 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -26,6 +26,7 @@ #include <asm/acpi.h> #include <asm/alternative.h> #include <asm/cacheflush.h> +#include <asm/cpufeature.h> #include <asm/cpu_ops.h> #include <asm/early_ioremap.h> #include <asm/pgtable.h> @@ -301,10 +302,13 @@ void __init setup_arch(char **cmdline_p) riscv_fill_hwcap(); init_rt_signal_env(); apply_boot_alternatives(); + if (IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM) && riscv_isa_extension_available(NULL, ZICBOM)) riscv_noncoherent_supported(); riscv_set_dma_cache_alignment(); + + riscv_user_isa_enable(); } static int __init topology_init(void) diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index 1b8da4e40a4d..d1b0a6fc3adf 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -25,6 +25,8 @@ #include <linux/of.h> #include <linux/sched/task_stack.h> #include <linux/sched/mm.h> + +#include <asm/cpufeature.h> #include <asm/cpu_ops.h> #include <asm/cpufeature.h> #include <asm/irq.h> @@ -253,6 +255,8 @@ asmlinkage __visible void smp_callin(void) elf_hwcap &= ~COMPAT_HWCAP_ISA_V; } + riscv_user_isa_enable(); + /* * Remote TLB flushes are ignored while the CPU is offline, so emit * a local TLB flush right now just in case. diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index 1ac6a8dbe0b8..8fe674a874dd 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -19,6 +19,7 @@ #include <linux/kvm_host.h> #include <asm/csr.h> #include <asm/cacheflush.h> +#include <asm/errata_list.h> #include <asm/kvm_vcpu_vector.h> const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { @@ -471,33 +472,38 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, return -EINVAL; } -/* -static void kvm_riscv_vcpu_update_config(const unsigned long *isa) +static void kvm_riscv_vcpu_setup_config(struct kvm_vcpu *vcpu) { - u64 henvcfg = 0; + const unsigned long *isa = vcpu->arch.isa; + struct kvm_vcpu_config *cfg = &vcpu->arch.cfg; if (riscv_isa_extension_available(isa, SVPBMT)) - henvcfg |= ENVCFG_PBMTE; + cfg->henvcfg |= ENVCFG_PBMTE; if (riscv_isa_extension_available(isa, SSTC)) - henvcfg |= ENVCFG_STCE; + cfg->henvcfg |= ENVCFG_STCE; if (riscv_isa_extension_available(isa, ZICBOM)) - henvcfg |= (ENVCFG_CBIE | ENVCFG_CBCFE); + cfg->henvcfg |= (ENVCFG_CBIE | ENVCFG_CBCFE); if (riscv_isa_extension_available(isa, ZICBOZ)) - henvcfg |= ENVCFG_CBZE; - - csr_write(CSR_HENVCFG, henvcfg); -#ifdef CONFIG_32BIT - csr_write(CSR_HENVCFGH, henvcfg >> 32); -#endif + cfg->henvcfg |= ENVCFG_CBZE; + + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) { + cfg->hstateen0 |= SMSTATEEN0_HSENVCFG; + if (riscv_isa_extension_available(isa, SSAIA)) + cfg->hstateen0 |= SMSTATEEN0_AIA_IMSIC | + SMSTATEEN0_AIA | + SMSTATEEN0_AIA_ISEL; + if (riscv_isa_extension_available(isa, SMSTATEEN)) + cfg->hstateen0 |= SMSTATEEN0_SSTATEEN0; + } } -*/ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + struct kvm_vcpu_config *cfg = &vcpu->arch.cfg; csr_write(CSR_VSSTATUS, csr->vsstatus); csr_write(CSR_VSIE, csr->vsie); @@ -508,9 +514,16 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) csr_write(CSR_VSTVAL, csr->vstval); csr_write(CSR_HVIP, csr->hvip); csr_write(CSR_VSATP, csr->vsatp); - - /* Temporarily commented out while Dubhe is still using Hypervisor ISA v0.6 */ - /* kvm_riscv_vcpu_update_config(vcpu->arch.isa); */ + if (!static_branch_unlikely(&bypass_envcfg_csr_key)) { + csr_write(CSR_HENVCFG, cfg->henvcfg); + if (IS_ENABLED(CONFIG_32BIT)) + csr_write(CSR_HENVCFGH, cfg->henvcfg >> 32); + } + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) { + csr_write(CSR_HSTATEEN0, cfg->hstateen0); + if (IS_ENABLED(CONFIG_32BIT)) + csr_write(CSR_HSTATEEN0H, cfg->hstateen0 >> 32); + } kvm_riscv_gstage_update_hgatp(vcpu); @@ -609,6 +622,34 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu) kvm_riscv_vcpu_aia_update_hvip(vcpu); } +static __always_inline void kvm_riscv_vcpu_swap_in_guest_state(struct kvm_vcpu *vcpu) +{ + struct kvm_vcpu_smstateen_csr *smcsr = &vcpu->arch.smstateen_csr; + struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + struct kvm_vcpu_config *cfg = &vcpu->arch.cfg; + + if (!static_branch_unlikely(&bypass_envcfg_csr_key)) + vcpu->arch.host_senvcfg = csr_swap(CSR_SENVCFG, csr->senvcfg); + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN) && + (cfg->hstateen0 & SMSTATEEN0_SSTATEEN0)) + vcpu->arch.host_sstateen0 = csr_swap(CSR_SSTATEEN0, + smcsr->sstateen0); +} + +static __always_inline void kvm_riscv_vcpu_swap_in_host_state(struct kvm_vcpu *vcpu) +{ + struct kvm_vcpu_smstateen_csr *smcsr = &vcpu->arch.smstateen_csr; + struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + struct kvm_vcpu_config *cfg = &vcpu->arch.cfg; + + if (!static_branch_unlikely(&bypass_envcfg_csr_key)) + csr->senvcfg = csr_swap(CSR_SENVCFG, vcpu->arch.host_senvcfg); + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN) && + (cfg->hstateen0 & SMSTATEEN0_SSTATEEN0)) + smcsr->sstateen0 = csr_swap(CSR_SSTATEEN0, + vcpu->arch.host_sstateen0); +} + /* * Actually run the vCPU, entering an RCU extended quiescent state (EQS) while * the vCPU is running. @@ -618,10 +659,12 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu) */ static void noinstr kvm_riscv_vcpu_enter_exit(struct kvm_vcpu *vcpu) { + kvm_riscv_vcpu_swap_in_guest_state(vcpu); guest_state_enter_irqoff(); __kvm_riscv_switch_to(&vcpu->arch); vcpu->arch.last_exit_cpu = vcpu->cpu; guest_state_exit_irqoff(); + kvm_riscv_vcpu_swap_in_host_state(vcpu); } int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) @@ -630,6 +673,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) struct kvm_cpu_trap trap; struct kvm_run *run = vcpu->run; + if (!vcpu->arch.ran_atleast_once) + kvm_riscv_vcpu_setup_config(vcpu); + /* Mark this VCPU ran at least once */ vcpu->arch.ran_atleast_once = true; diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c index b7e0e03c69b1..c6ebce6126b5 100644 --- a/arch/riscv/kvm/vcpu_onereg.c +++ b/arch/riscv/kvm/vcpu_onereg.c @@ -34,6 +34,7 @@ static const unsigned long kvm_isa_ext_arr[] = { [KVM_RISCV_ISA_EXT_M] = RISCV_ISA_EXT_m, [KVM_RISCV_ISA_EXT_V] = RISCV_ISA_EXT_v, /* Multi letter extensions (alphabetically sorted) */ + KVM_ISA_EXT_ARR(SMSTATEEN), KVM_ISA_EXT_ARR(SSAIA), KVM_ISA_EXT_ARR(SSTC), KVM_ISA_EXT_ARR(SVINVAL), @@ -45,6 +46,7 @@ static const unsigned long kvm_isa_ext_arr[] = { KVM_ISA_EXT_ARR(ZICBOM), KVM_ISA_EXT_ARR(ZICBOZ), KVM_ISA_EXT_ARR(ZICNTR), + KVM_ISA_EXT_ARR(ZICOND), KVM_ISA_EXT_ARR(ZICSR), KVM_ISA_EXT_ARR(ZIFENCEI), KVM_ISA_EXT_ARR(ZIHINTPAUSE), @@ -80,11 +82,11 @@ static bool kvm_riscv_vcpu_isa_enable_allowed(unsigned long ext) static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext) { switch (ext) { + /* Extensions which don't have any mechanism to disable */ case KVM_RISCV_ISA_EXT_A: case KVM_RISCV_ISA_EXT_C: case KVM_RISCV_ISA_EXT_I: case KVM_RISCV_ISA_EXT_M: - case KVM_RISCV_ISA_EXT_SSAIA: case KVM_RISCV_ISA_EXT_SSTC: case KVM_RISCV_ISA_EXT_SVINVAL: case KVM_RISCV_ISA_EXT_SVNAPOT: @@ -92,11 +94,15 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext) case KVM_RISCV_ISA_EXT_ZBB: case KVM_RISCV_ISA_EXT_ZBS: case KVM_RISCV_ISA_EXT_ZICNTR: + case KVM_RISCV_ISA_EXT_ZICOND: case KVM_RISCV_ISA_EXT_ZICSR: case KVM_RISCV_ISA_EXT_ZIFENCEI: case KVM_RISCV_ISA_EXT_ZIHINTPAUSE: case KVM_RISCV_ISA_EXT_ZIHPM: return false; + /* Extensions which can be disabled using Smstateen */ + case KVM_RISCV_ISA_EXT_SSAIA: + return riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN); default: break; } @@ -378,6 +384,34 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu, return 0; } +static inline int kvm_riscv_vcpu_smstateen_set_csr(struct kvm_vcpu *vcpu, + unsigned long reg_num, + unsigned long reg_val) +{ + struct kvm_vcpu_smstateen_csr *csr = &vcpu->arch.smstateen_csr; + + if (reg_num >= sizeof(struct kvm_riscv_smstateen_csr) / + sizeof(unsigned long)) + return -EINVAL; + + ((unsigned long *)csr)[reg_num] = reg_val; + return 0; +} + +static int kvm_riscv_vcpu_smstateen_get_csr(struct kvm_vcpu *vcpu, + unsigned long reg_num, + unsigned long *out_val) +{ + struct kvm_vcpu_smstateen_csr *csr = &vcpu->arch.smstateen_csr; + + if (reg_num >= sizeof(struct kvm_riscv_smstateen_csr) / + sizeof(unsigned long)) + return -EINVAL; + + *out_val = ((unsigned long *)csr)[reg_num]; + return 0; +} + static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) { @@ -401,6 +435,12 @@ static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu, case KVM_REG_RISCV_CSR_AIA: rc = kvm_riscv_vcpu_aia_get_csr(vcpu, reg_num, ®_val); break; + case KVM_REG_RISCV_CSR_SMSTATEEN: + rc = -EINVAL; + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) + rc = kvm_riscv_vcpu_smstateen_get_csr(vcpu, reg_num, + ®_val); + break; default: rc = -ENOENT; break; @@ -440,6 +480,12 @@ static int kvm_riscv_vcpu_set_reg_csr(struct kvm_vcpu *vcpu, case KVM_REG_RISCV_CSR_AIA: rc = kvm_riscv_vcpu_aia_set_csr(vcpu, reg_num, reg_val); break; + case KVM_REG_RISCV_CSR_SMSTATEEN: + rc = -EINVAL; + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) + rc = kvm_riscv_vcpu_smstateen_set_csr(vcpu, reg_num, + reg_val); +break; default: rc = -ENOENT; break; @@ -696,6 +742,8 @@ static inline unsigned long num_csr_regs(const struct kvm_vcpu *vcpu) if (riscv_isa_extension_available(vcpu->arch.isa, SSAIA)) n += sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long); + if (riscv_isa_extension_available(vcpu->arch.isa, SMSTATEEN)) + n += sizeof(struct kvm_riscv_smstateen_csr) / sizeof(unsigned long); return n; } @@ -704,7 +752,7 @@ static int copy_csr_reg_indices(const struct kvm_vcpu *vcpu, u64 __user *uindices) { int n1 = sizeof(struct kvm_riscv_csr) / sizeof(unsigned long); - int n2 = 0; + int n2 = 0, n3 = 0; /* copy general csr regs */ for (int i = 0; i < n1; i++) { @@ -738,7 +786,25 @@ static int copy_csr_reg_indices(const struct kvm_vcpu *vcpu, } } - return n1 + n2; + /* copy Smstateen csr regs */ + if (riscv_isa_extension_available(vcpu->arch.isa, SMSTATEEN)) { + n3 = sizeof(struct kvm_riscv_smstateen_csr) / sizeof(unsigned long); + + for (int i = 0; i < n3; i++) { + u64 size = IS_ENABLED(CONFIG_32BIT) ? + KVM_REG_SIZE_U32 : KVM_REG_SIZE_U64; + u64 reg = KVM_REG_RISCV | size | KVM_REG_RISCV_CSR | + KVM_REG_RISCV_CSR_SMSTATEEN | i; + + if (uindices) { + if (put_user(reg, uindices)) + return -EFAULT; + uindices++; + } + } + } + + return n1 + n2 + n3; } static inline unsigned long num_timer_regs(void) diff --git a/tools/perf/pmu-events/arch/riscv/mapfile.csv b/tools/perf/pmu-events/arch/riscv/mapfile.csv index 3a7ec0293b7f..8310a80a5986 100644 --- a/tools/perf/pmu-events/arch/riscv/mapfile.csv +++ b/tools/perf/pmu-events/arch/riscv/mapfile.csv @@ -15,5 +15,4 @@ # #MVENDORID-MARCHID-MIMPID,Version,Filename,EventType 0x489-0x8000000000000007-0x[[:xdigit:]]+,v1,sifive/u74,core -0x67e80902023,v1,starfive/dubhe-90,core -0x67e80802023,v1,starfive/dubhe-80,core +0x67e-0x80000000db0000[789]0-0x[[:xdigit:]]+,v1,starfive/dubhe-80,core diff --git a/tools/perf/pmu-events/arch/riscv/starfive/dubhe-80/firmware.json b/tools/perf/pmu-events/arch/riscv/starfive/dubhe-80/firmware.json new file mode 100644 index 000000000000..37079ebe9316 --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/starfive/dubhe-80/firmware.json @@ -0,0 +1,68 @@ +[ + { + "ArchStdEvent": "FW_MISALIGNED_LOAD" + }, + { + "ArchStdEvent": "FW_MISALIGNED_STORE" + }, + { + "ArchStdEvent": "FW_ACCESS_LOAD" + }, + { + "ArchStdEvent": "FW_ACCESS_STORE" + }, + { + "ArchStdEvent": "FW_ILLEGAL_INSN" + }, + { + "ArchStdEvent": "FW_SET_TIMER" + }, + { + "ArchStdEvent": "FW_IPI_SENT" + }, + { + "ArchStdEvent": "FW_IPI_RECEIVED" + }, + { + "ArchStdEvent": "FW_FENCE_I_SENT" + }, + { + "ArchStdEvent": "FW_FENCE_I_RECEIVED" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_SENT" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_RECEIVED" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_RECEIVED" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_ASID_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_VMID_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_VMID_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_ASID_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_ASID_RECEIVED" + } +]
\ No newline at end of file diff --git a/tools/perf/pmu-events/arch/riscv/starfive/dubhe-90/common.json b/tools/perf/pmu-events/arch/riscv/starfive/dubhe-90/common.json deleted file mode 100644 index 9026e6653c86..000000000000 --- a/tools/perf/pmu-events/arch/riscv/starfive/dubhe-90/common.json +++ /dev/null @@ -1,172 +0,0 @@ -[ - { - "EventName": "ACCESS_MMU_STLB", - "EventCode": "0x1", - "BriefDescription": "access MMU STLB" - }, - { - "EventName": "MISS_MMU_STLB", - "EventCode": "0x2", - "BriefDescription": "miss MMU STLB" - }, - { - "EventName": "ACCESS_MMU_PTE_C", - "EventCode": "0x3", - "BriefDescription": "access MMU PTE-Cache" - }, - { - "EventName": "MISS_MMU_PTE_C", - "EventCode": "0x4", - "BriefDescription": "miss MMU PTE-Cache" - }, - { - "EventName": "ROB_FLUSH", - "EventCode": "0x5", - "BriefDescription": "ROB flush (all kinds of exceptions)" - }, - { - "EventName": "BTB_PREDICTION_MISS", - "EventCode": "0x6", - "BriefDescription": "BTB prediction miss" - }, - { - "EventName": "ITLB_MISS", - "EventCode": "0x7", - "BriefDescription": "ITLB miss" - }, - { - "EventName": "SYNC_DEL_FETCH_G", - "EventCode": "0x8", - "BriefDescription": "SYNC delivery a fetch-group" - }, - { - "EventName": "ICACHE_MISS", - "EventCode": "0x9", - "BriefDescription": "ICache miss" - }, - { - "EventName": "BPU_BR_RETIRE", - "EventCode": "0xA", - "BriefDescription": "condition branch instruction retire" - }, - { - "EventName": "BPU_BR_MISS", - "EventCode": "0xB", - "BriefDescription": "condition branch instruction miss" - }, - { - "EventName": "RET_INS_RETIRE", - "EventCode": "0xC", - "BriefDescription": "return instruction retire" - }, - { - "EventName": "RET_INS_MISS", - "EventCode": "0xD", - "BriefDescription": "return instruction miss" - }, - { - "EventName": "INDIRECT_JR_MISS", - "EventCode": "0xE", - "BriefDescription": "indirect JR instruction miss (inlcude without target)" - }, - { - "EventName": "IBUF_VAL_ID_NORDY", - "EventCode": "0xF", - "BriefDescription": "IBUF valid while ID not ready" - }, - { - "EventName": "IBUF_NOVAL_ID_RDY", - "EventCode": "0x10", - "BriefDescription": "IBUF not valid while ID ready" - }, - { - "EventName": "REN_INT_PHY_REG_NORDY", - "EventCode": "0x11", - "BriefDescription": "REN integer physical register file is not ready" - }, - { - "EventName": "REN_FP_PHY_REG_NORDY", - "EventCode": "0x12", - "BriefDescription": "REN floating point physical register file is not ready" - }, - { - "EventName": "REN_CP_NORDY", - "EventCode": "0x13", - "BriefDescription": "REN checkpoint is not ready" - }, - { - "EventName": "DEC_VAL_ROB_NORDY", - "EventCode": "0x14", - "BriefDescription": "DEC is valid and ROB is not ready" - }, - { - "EventName": "OOD_FLUSH_LS_DEP", - "EventCode": "0x15", - "BriefDescription": "out of order flush due to load/store dependency" - }, - { - "EventName": "BRU_RET_IJR_INS", - "EventCode": "0x16", - "BriefDescription": "BRU retire an IJR instruction" - }, - { - "EventName": "ACCESS_DTLB", - "EventCode": "0x17", - "BriefDescription": "access DTLB" - }, - { - "EventName": "MISS_DTLB", - "EventCode": "0x18", - "BriefDescription": "miss DTLB" - }, - { - "EventName": "LOAD_INS_DCACHE", - "EventCode": "0x19", - "BriefDescription": "load instruction access DCache" - }, - { - "EventName": "LOAD_INS_MISS_DCACHE", - "EventCode": "0x1A", - "BriefDescription": "load instruction miss DCache" - }, - { - "EventName": "STORE_INS_DCACHE", - "EventCode": "0x1B", - "BriefDescription": "store/amo instruction access DCache" - }, - { - "EventName": "STORE_INS_MISS_DCACHE", - "EventCode": "0x1C", - "BriefDescription": "store/amo instruction miss DCache" - }, - { - "EventName": "LOAD_SCACHE", - "EventCode": "0x1D", - "BriefDescription": "load access SCache" - }, - { - "EventName": "STORE_SCACHE", - "EventCode": "0x1E", - "BriefDescription": "store access SCache" - }, - { - "EventName": "LOAD_MISS_SCACHE", - "EventCode": "0x1F", - "BriefDescription": "load miss SCache" - }, - { - "EventName": "STORE_MISS_SCACHE", - "EventCode": "0x20", - "BriefDescription": "store miss SCache" - }, - { - "EventName": "L2C_PF_REQ", - "EventCode": "0x21", - "BriefDescription": "L2C data-prefetcher request" - }, - { - "EventName": "L2C_PF_HIT", - "EventCode": "0x22", - "BriefDescription": "L2C data-prefetcher hit" - } -]
\ No newline at end of file |