Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'riscv-for-linus-6.2-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

Pull RISC-V updates from Palmer Dabbelt:

- Support for the T-Head PMU via the perf subsystem

- ftrace support for rv32

- Support for non-volatile memory devices

- Various fixes and cleanups

* tag 'riscv-for-linus-6.2-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (52 commits)
Documentation: RISC-V: patch-acceptance: s/implementor/implementer
Documentation: RISC-V: Mention the UEFI Standards
Documentation: RISC-V: Allow patches for non-standard behavior
Documentation: RISC-V: Fix a typo in patch-acceptance
riscv: Fixup compile error with !MMU
riscv: Fix P4D_SHIFT definition for 3-level page table mode
riscv: Apply a static assert to riscv_isa_ext_id
RISC-V: Add some comments about the shadow and overflow stacks
RISC-V: Align the shadow stack
RISC-V: Ensure Zicbom has a valid block size
RISC-V: Introduce riscv_isa_extension_check
RISC-V: Improve use of isa2hwcap[]
riscv: Don't duplicate _ALTERNATIVE_CFG* macros
riscv: alternatives: Drop the underscores from the assembly macro names
riscv: alternatives: Don't name unused macro parameters
riscv: Don't duplicate __ALTERNATIVE_CFG in __ALTERNATIVE_CFG_2
riscv: mm: call best_map_size many times during linear-mapping
riscv: Move cast inside kernel_mapping_[pv]a_to_[vp]a
riscv: Fix crash during early errata patching
riscv: boot: add zstd support
...

+619 -256
+29
Documentation/admin-guide/kdump/vmcoreinfo.rst
··· 595 595 ----- 596 596 597 597 Indicates whether the crashed kernel enabled SH extended mode. 598 + 599 + RISCV64 600 + ======= 601 + 602 + VA_BITS 603 + ------- 604 + 605 + The maximum number of bits for virtual addresses. Used to compute the 606 + virtual memory ranges. 607 + 608 + PAGE_OFFSET 609 + ----------- 610 + 611 + Indicates the virtual kernel start address of the direct-mapped RAM region. 612 + 613 + phys_ram_base 614 + ------------- 615 + 616 + Indicates the start physical RAM address. 617 + 618 + MODULES_VADDR|MODULES_END|VMALLOC_START|VMALLOC_END|VMEMMAP_START|VMEMMAP_END|KERNEL_LINK_ADDR 619 + ---------------------------------------------------------------------------------------------- 620 + 621 + Used to get the correct ranges: 622 + 623 + * MODULES_VADDR ~ MODULES_END : Kernel module space. 624 + * VMALLOC_START ~ VMALLOC_END : vmalloc() / ioremap() space. 625 + * VMEMMAP_START ~ VMEMMAP_END : vmemmap space, used for struct page array. 626 + * KERNEL_LINK_ADDR : start address of Kernel link and BPF
+1 -1
Documentation/features/vm/huge-vmap/arch-support.txt
··· 21 21 | openrisc: | TODO | 22 22 | parisc: | TODO | 23 23 | powerpc: | ok | 24 - | riscv: | TODO | 24 + | riscv: | ok | 25 25 | s390: | TODO | 26 26 | sh: | TODO | 27 27 | sparc: | TODO |
+14 -8
Documentation/riscv/patch-acceptance.rst
··· 20 20 ------------------------- 21 21 We'll only accept patches for new modules or extensions if the 22 22 specifications for those modules or extensions are listed as being 23 - "Frozen" or "Ratified" by the RISC-V Foundation. (Developers may, of 24 - course, maintain their own Linux kernel trees that contain code for 25 - any draft extensions that they wish.) 23 + unlikely to be incompatibly changed in the future. For 24 + specifications from the RISC-V foundation this means "Frozen" or 25 + "Ratified", for the UEFI forum specifications this means a published 26 + ECR. (Developers may, of course, maintain their own Linux kernel trees 27 + that contain code for any draft extensions that they wish.) 26 28 27 - Additionally, the RISC-V specification allows implementors to create 29 + Additionally, the RISC-V specification allows implementers to create 28 30 their own custom extensions. These custom extensions aren't required 29 31 to go through any review or ratification process by the RISC-V 30 32 Foundation. To avoid the maintenance complexity and potential 31 33 performance impact of adding kernel code for implementor-specific 32 - RISC-V extensions, we'll only to accept patches for extensions that 33 - have been officially frozen or ratified by the RISC-V Foundation. 34 - (Implementors, may, of course, maintain their own Linux kernel trees 35 - containing code for any custom extensions that they wish.) 34 + RISC-V extensions, we'll only consider patches for extensions that either: 35 + 36 + - Have been officially frozen or ratified by the RISC-V Foundation, or 37 + - Have been implemented in hardware that is widely available, per standard 38 + Linux practice. 39 + 40 + (Implementers, may, of course, maintain their own Linux kernel trees containing 41 + code for any custom extensions that they wish.)
+13 -6
arch/riscv/Kconfig
··· 25 25 select ARCH_HAS_GIGANTIC_PAGE 26 26 select ARCH_HAS_KCOV 27 27 select ARCH_HAS_MMIOWB 28 + select ARCH_HAS_PMEM_API 28 29 select ARCH_HAS_PTE_SPECIAL 29 30 select ARCH_HAS_SET_DIRECT_MAP if MMU 30 31 select ARCH_HAS_SET_MEMORY if MMU ··· 73 72 select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO 74 73 select HARDIRQS_SW_RESEND 75 74 select HAVE_ARCH_AUDITSYSCALL 75 + select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP 76 + select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT && !XIP_KERNEL 76 77 select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL 77 78 select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL 78 79 select HAVE_ARCH_KASAN if MMU && 64BIT ··· 102 99 select HAVE_KPROBES if !XIP_KERNEL 103 100 select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL 104 101 select HAVE_KRETPROBES if !XIP_KERNEL 102 + select HAVE_RETHOOK if !XIP_KERNEL 105 103 select HAVE_MOVE_PMD 106 104 select HAVE_MOVE_PUD 107 105 select HAVE_PCI ··· 127 123 select PCI_MSI if PCI 128 124 select RISCV_INTC 129 125 select RISCV_TIMER if RISCV_SBI 126 + select SIFIVE_PLIC 130 127 select SPARSE_IRQ 131 128 select SYSCTL_EXCEPTION_TRACE 132 129 select THREAD_INFO_IN_TASK 133 130 select TRACE_IRQFLAGS_SUPPORT 134 131 select UACCESS_MEMCPY if !MMU 135 132 select ZONE_DMA32 if 64BIT 133 + select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && $(cc-option,-fpatchable-function-entry=8) 134 + select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE 135 + select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL 136 + select HAVE_FUNCTION_GRAPH_TRACER 137 + select HAVE_FUNCTION_TRACER if !XIP_KERNEL 136 138 137 139 config ARCH_MMAP_RND_BITS_MIN 138 140 default 18 if 64BIT ··· 284 274 bool "RV64I" 285 275 select 64BIT 286 276 select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 287 - select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && $(cc-option,-fpatchable-function-entry=8) 288 - select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE 289 - select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL 290 - select HAVE_FUNCTION_GRAPH_TRACER 291 - select HAVE_FUNCTION_TRACER if !XIP_KERNEL 292 277 select SWIOTLB if MMU 293 278 294 279 endchoice ··· 507 502 select KEXEC_CORE 508 503 select KEXEC_ELF 509 504 select HAVE_IMA_KEXEC if IMA 510 - depends on 64BIT 505 + depends on 64BIT && MMU 511 506 help 512 507 This is new version of kexec system call. This system call is 513 508 file based and takes file descriptors as system call argument ··· 695 690 menu "CPU Power Management" 696 691 697 692 source "drivers/cpuidle/Kconfig" 693 + 694 + source "drivers/cpufreq/Kconfig" 698 695 699 696 endmenu # "CPU Power Management" 700 697
+13
arch/riscv/Kconfig.erratas
··· 66 66 67 67 If you don't know what to do here, say "Y". 68 68 69 + config ERRATA_THEAD_PMU 70 + bool "Apply T-Head PMU errata" 71 + depends on ERRATA_THEAD && RISCV_PMU_SBI 72 + default y 73 + help 74 + The T-Head C9xx cores implement a PMU overflow extension very 75 + similar to the core SSCOFPMF extension. 76 + 77 + This will apply the overflow errata to handle the non-standard 78 + behaviour via the regular SBI PMU driver and interface. 79 + 80 + If you don't know what to do here, say "Y". 81 + 69 82 endmenu # "CPU errata selection"
-5
arch/riscv/Kconfig.socs
··· 3 3 config SOC_MICROCHIP_POLARFIRE 4 4 bool "Microchip PolarFire SoCs" 5 5 select MCHP_CLK_MPFS 6 - select SIFIVE_PLIC 7 6 help 8 7 This enables support for Microchip PolarFire SoC platforms. 9 8 ··· 17 18 select SERIAL_SIFIVE_CONSOLE if TTY 18 19 select CLK_SIFIVE 19 20 select CLK_SIFIVE_PRCI 20 - select SIFIVE_PLIC 21 21 select ERRATA_SIFIVE if !XIP_KERNEL 22 22 help 23 23 This enables support for SiFive SoC platform hardware. ··· 25 27 bool "StarFive SoCs" 26 28 select PINCTRL 27 29 select RESET_CONTROLLER 28 - select SIFIVE_PLIC 29 30 help 30 31 This enables support for StarFive SoC platform hardware. 31 32 ··· 36 39 select POWER_RESET_SYSCON_POWEROFF 37 40 select GOLDFISH 38 41 select RTC_DRV_GOLDFISH if RTC_CLASS 39 - select SIFIVE_PLIC 40 42 select PM_GENERIC_DOMAINS if PM 41 43 select PM_GENERIC_DOMAINS_OF if PM && OF 42 44 select RISCV_SBI_CPUIDLE if CPU_IDLE && RISCV_SBI ··· 48 52 select CLINT_TIMER if RISCV_M_MODE 49 53 select SERIAL_SIFIVE if TTY 50 54 select SERIAL_SIFIVE_CONSOLE if TTY 51 - select SIFIVE_PLIC 52 55 select ARCH_HAS_RESET_CONTROLLER 53 56 select PINCTRL 54 57 select COMMON_CLK
+3
arch/riscv/boot/Makefile
··· 56 56 $(obj)/Image.lzo: $(obj)/Image FORCE 57 57 $(call if_changed,lzo) 58 58 59 + $(obj)/Image.zst: $(obj)/Image FORCE 60 + $(call if_changed,zstd) 61 + 59 62 $(obj)/loader.bin: $(obj)/loader FORCE 60 63 $(call if_changed,objcopy) 61 64
+3
arch/riscv/configs/defconfig
··· 39 39 CONFIG_JUMP_LABEL=y 40 40 CONFIG_MODULES=y 41 41 CONFIG_MODULE_UNLOAD=y 42 + CONFIG_SPARSEMEM_MANUAL=y 42 43 CONFIG_BLK_DEV_THROTTLING=y 43 44 CONFIG_NET=y 44 45 CONFIG_PACKET=y ··· 124 123 CONFIG_INPUT_MOUSEDEV=y 125 124 CONFIG_SERIAL_8250=y 126 125 CONFIG_SERIAL_8250_CONSOLE=y 126 + CONFIG_SERIAL_8250_DW=y 127 127 CONFIG_SERIAL_OF_PLATFORM=y 128 128 CONFIG_SERIAL_SH_SCI=y 129 129 CONFIG_VIRTIO_CONSOLE=y ··· 164 162 CONFIG_RPMSG_CTRL=y 165 163 CONFIG_RPMSG_VIRTIO=y 166 164 CONFIG_ARCH_R9A07G043=y 165 + CONFIG_LIBNVDIMM=y 167 166 CONFIG_EXT4_FS=y 168 167 CONFIG_EXT4_FS_POSIX_ACL=y 169 168 CONFIG_EXT4_FS_SECURITY=y
+19
arch/riscv/errata/thead/errata.c
··· 47 47 return true; 48 48 } 49 49 50 + static bool errata_probe_pmu(unsigned int stage, 51 + unsigned long arch_id, unsigned long impid) 52 + { 53 + if (!IS_ENABLED(CONFIG_ERRATA_THEAD_PMU)) 54 + return false; 55 + 56 + /* target-c9xx cores report arch_id and impid as 0 */ 57 + if (arch_id != 0 || impid != 0) 58 + return false; 59 + 60 + if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) 61 + return false; 62 + 63 + return true; 64 + } 65 + 50 66 static u32 thead_errata_probe(unsigned int stage, 51 67 unsigned long archid, unsigned long impid) 52 68 { ··· 73 57 74 58 if (errata_probe_cmo(stage, archid, impid)) 75 59 cpu_req_errata |= BIT(ERRATA_THEAD_CMO); 60 + 61 + if (errata_probe_pmu(stage, archid, impid)) 62 + cpu_req_errata |= BIT(ERRATA_THEAD_PMU); 76 63 77 64 return cpu_req_errata; 78 65 }
+30 -69
arch/riscv/include/asm/alternative-macros.h
··· 33 33 .endif 34 34 .endm 35 35 36 - .macro __ALTERNATIVE_CFG old_c, new_c, vendor_id, errata_id, enable 36 + .macro ALTERNATIVE_CFG old_c, new_c, vendor_id, errata_id, enable 37 37 886 : 38 38 .option push 39 39 .option norvc ··· 44 44 ALT_NEW_CONTENT \vendor_id, \errata_id, \enable, \new_c 45 45 .endm 46 46 47 - #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ 48 - __ALTERNATIVE_CFG old_c, new_c, vendor_id, errata_id, IS_ENABLED(CONFIG_k) 49 - 50 - .macro __ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, errata_id_1, enable_1, \ 51 - new_c_2, vendor_id_2, errata_id_2, enable_2 52 - 886 : 53 - .option push 54 - .option norvc 55 - .option norelax 56 - \old_c 57 - .option pop 58 - 887 : 59 - ALT_NEW_CONTENT \vendor_id_1, \errata_id_1, \enable_1, \new_c_1 47 + .macro ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, errata_id_1, enable_1, \ 48 + new_c_2, vendor_id_2, errata_id_2, enable_2 49 + ALTERNATIVE_CFG \old_c, \new_c_1, \vendor_id_1, \errata_id_1, \enable_1 60 50 ALT_NEW_CONTENT \vendor_id_2, \errata_id_2, \enable_2, \new_c_2 61 51 .endm 62 52 63 - #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ 64 - CONFIG_k_1, \ 65 - new_c_2, vendor_id_2, errata_id_2, \ 66 - CONFIG_k_2) \ 67 - __ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, errata_id_1, \ 68 - IS_ENABLED(CONFIG_k_1), \ 69 - new_c_2, vendor_id_2, errata_id_2, \ 70 - IS_ENABLED(CONFIG_k_2) 53 + #define __ALTERNATIVE_CFG(...) ALTERNATIVE_CFG __VA_ARGS__ 54 + #define __ALTERNATIVE_CFG_2(...) ALTERNATIVE_CFG_2 __VA_ARGS__ 71 55 72 56 #else /* !__ASSEMBLY__ */ 73 57 ··· 93 109 "887 :\n" \ 94 110 ALT_NEW_CONTENT(vendor_id, errata_id, enable, new_c) 95 111 112 + #define __ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, enable_1, \ 113 + new_c_2, vendor_id_2, errata_id_2, enable_2) \ 114 + __ALTERNATIVE_CFG(old_c, new_c_1, vendor_id_1, errata_id_1, enable_1) \ 115 + ALT_NEW_CONTENT(vendor_id_2, errata_id_2, enable_2, new_c_2) 116 + 117 + #endif /* __ASSEMBLY__ */ 118 + 96 119 #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ 97 120 __ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, IS_ENABLED(CONFIG_k)) 98 121 99 - #define __ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ 100 - enable_1, \ 101 - new_c_2, vendor_id_2, errata_id_2, \ 102 - enable_2) \ 103 - "886 :\n" \ 104 - ".option push\n" \ 105 - ".option norvc\n" \ 106 - ".option norelax\n" \ 107 - old_c "\n" \ 108 - ".option pop\n" \ 109 - "887 :\n" \ 110 - ALT_NEW_CONTENT(vendor_id_1, errata_id_1, enable_1, new_c_1) \ 111 - ALT_NEW_CONTENT(vendor_id_2, errata_id_2, enable_2, new_c_2) 112 - 113 - #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ 114 - CONFIG_k_1, \ 115 - new_c_2, vendor_id_2, errata_id_2, \ 116 - CONFIG_k_2) \ 117 - __ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ 118 - IS_ENABLED(CONFIG_k_1), \ 119 - new_c_2, vendor_id_2, errata_id_2, \ 120 - IS_ENABLED(CONFIG_k_2)) 121 - 122 - #endif /* __ASSEMBLY__ */ 122 + #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, CONFIG_k_1, \ 123 + new_c_2, vendor_id_2, errata_id_2, CONFIG_k_2) \ 124 + __ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, IS_ENABLED(CONFIG_k_1), \ 125 + new_c_2, vendor_id_2, errata_id_2, IS_ENABLED(CONFIG_k_2)) 123 126 124 127 #else /* CONFIG_RISCV_ALTERNATIVE */ 125 128 #ifdef __ASSEMBLY__ 126 129 127 - .macro __ALTERNATIVE_CFG old_c 130 + .macro ALTERNATIVE_CFG old_c 128 131 \old_c 129 132 .endm 130 133 131 - #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ 132 - __ALTERNATIVE_CFG old_c 134 + #define _ALTERNATIVE_CFG(old_c, ...) \ 135 + ALTERNATIVE_CFG old_c 133 136 134 - #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ 135 - CONFIG_k_1, \ 136 - new_c_2, vendor_id_2, errata_id_2, \ 137 - CONFIG_k_2) \ 138 - __ALTERNATIVE_CFG old_c 137 + #define _ALTERNATIVE_CFG_2(old_c, ...) \ 138 + ALTERNATIVE_CFG old_c 139 139 140 140 #else /* !__ASSEMBLY__ */ 141 141 142 - #define __ALTERNATIVE_CFG(old_c) \ 142 + #define __ALTERNATIVE_CFG(old_c) \ 143 143 old_c "\n" 144 144 145 - #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ 145 + #define _ALTERNATIVE_CFG(old_c, ...) \ 146 146 __ALTERNATIVE_CFG(old_c) 147 147 148 - #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, \ 149 - CONFIG_k_1, \ 150 - new_c_2, vendor_id_2, errata_id_2, \ 151 - CONFIG_k_2) \ 152 - __ALTERNATIVE_CFG(old_c) 148 + #define _ALTERNATIVE_CFG_2(old_c, ...) \ 149 + __ALTERNATIVE_CFG(old_c) 153 150 154 151 #endif /* __ASSEMBLY__ */ 155 152 #endif /* CONFIG_RISCV_ALTERNATIVE */ ··· 158 193 * on the following sample code and then replace ALTERNATIVE() with 159 194 * ALTERNATIVE_2() to append its customized content. 160 195 */ 161 - #define ALTERNATIVE_2(old_content, new_content_1, vendor_id_1, \ 162 - errata_id_1, CONFIG_k_1, \ 163 - new_content_2, vendor_id_2, \ 164 - errata_id_2, CONFIG_k_2) \ 165 - _ALTERNATIVE_CFG_2(old_content, new_content_1, vendor_id_1, \ 166 - errata_id_1, CONFIG_k_1, \ 167 - new_content_2, vendor_id_2, \ 168 - errata_id_2, CONFIG_k_2) 196 + #define ALTERNATIVE_2(old_content, new_content_1, vendor_id_1, errata_id_1, CONFIG_k_1, \ 197 + new_content_2, vendor_id_2, errata_id_2, CONFIG_k_2) \ 198 + _ALTERNATIVE_CFG_2(old_content, new_content_1, vendor_id_1, errata_id_1, CONFIG_k_1, \ 199 + new_content_2, vendor_id_2, errata_id_2, CONFIG_k_2) 169 200 170 201 #endif
+7
arch/riscv/include/asm/cacheflush.h
··· 17 17 18 18 static inline void flush_dcache_page(struct page *page) 19 19 { 20 + /* 21 + * HugeTLB pages are always fully mapped and only head page will be 22 + * set PG_dcache_clean (see comments in flush_icache_pte()). 23 + */ 24 + if (PageHuge(page)) 25 + page = compound_head(page); 26 + 20 27 if (test_bit(PG_dcache_clean, &page->flags)) 21 28 clear_bit(PG_dcache_clean, &page->flags); 22 29 }
+15 -1
arch/riscv/include/asm/errata_list.h
··· 6 6 #define ASM_ERRATA_LIST_H 7 7 8 8 #include <asm/alternative.h> 9 + #include <asm/csr.h> 9 10 #include <asm/vendorid_list.h> 10 11 11 12 #ifdef CONFIG_ERRATA_SIFIVE ··· 18 17 #ifdef CONFIG_ERRATA_THEAD 19 18 #define ERRATA_THEAD_PBMT 0 20 19 #define ERRATA_THEAD_CMO 1 21 - #define ERRATA_THEAD_NUMBER 2 20 + #define ERRATA_THEAD_PMU 2 21 + #define ERRATA_THEAD_NUMBER 3 22 22 #endif 23 23 24 24 #define CPUFEATURE_SVPBMT 0 ··· 143 141 "r"((unsigned long)(_start) & ~((_cachesize) - 1UL)), \ 144 142 "r"((unsigned long)(_start) + (_size)) \ 145 143 : "a0") 144 + 145 + #define THEAD_C9XX_RV_IRQ_PMU 17 146 + #define THEAD_C9XX_CSR_SCOUNTEROF 0x5c5 147 + 148 + #define ALT_SBI_PMU_OVERFLOW(__ovl) \ 149 + asm volatile(ALTERNATIVE( \ 150 + "csrr %0, " __stringify(CSR_SSCOUNTOVF), \ 151 + "csrr %0, " __stringify(THEAD_C9XX_CSR_SCOUNTEROF), \ 152 + THEAD_VENDOR_ID, ERRATA_THEAD_PMU, \ 153 + CONFIG_ERRATA_THEAD_PMU) \ 154 + : "=r" (__ovl) : \ 155 + : "memory") 146 156 147 157 #endif /* __ASSEMBLY__ */ 148 158
+6
arch/riscv/include/asm/hugetlb.h
··· 5 5 #include <asm-generic/hugetlb.h> 6 6 #include <asm/page.h> 7 7 8 + static inline void arch_clear_hugepage_flags(struct page *page) 9 + { 10 + clear_bit(PG_dcache_clean, &page->flags); 11 + } 12 + #define arch_clear_hugepage_flags arch_clear_hugepage_flags 13 + 8 14 #endif /* _ASM_RISCV_HUGETLB_H */
+2 -1
arch/riscv/include/asm/hwcap.h
··· 59 59 RISCV_ISA_EXT_ZIHINTPAUSE, 60 60 RISCV_ISA_EXT_SSTC, 61 61 RISCV_ISA_EXT_SVINVAL, 62 - RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX, 62 + RISCV_ISA_EXT_ID_MAX 63 63 }; 64 + static_assert(RISCV_ISA_EXT_ID_MAX <= RISCV_ISA_EXT_MAX); 64 65 65 66 /* 66 67 * This enum represents the logical ID for each RISC-V ISA extension static
+5
arch/riscv/include/asm/io.h
··· 135 135 136 136 #include <asm-generic/io.h> 137 137 138 + #ifdef CONFIG_MMU 139 + #define arch_memremap_wb(addr, size) \ 140 + ((__force void *)ioremap_prot((addr), (size), _PAGE_KERNEL)) 141 + #endif 142 + 138 143 #endif /* _ASM_RISCV_IO_H */
+5
arch/riscv/include/asm/kexec.h
··· 39 39 #define ARCH_HAS_KIMAGE_ARCH 40 40 41 41 struct kimage_arch { 42 + void *fdt; /* For CONFIG_KEXEC_FILE */ 42 43 unsigned long fdt_addr; 43 44 }; 44 45 ··· 63 62 const Elf_Shdr *relsec, 64 63 const Elf_Shdr *symtab); 65 64 #define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add 65 + 66 + struct kimage; 67 + int arch_kimage_file_post_load_cleanup(struct kimage *image); 68 + #define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup 66 69 #endif 67 70 68 71 #endif
-2
arch/riscv/include/asm/kprobes.h
··· 40 40 int kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr); 41 41 bool kprobe_breakpoint_handler(struct pt_regs *regs); 42 42 bool kprobe_single_step_handler(struct pt_regs *regs); 43 - void __kretprobe_trampoline(void); 44 - void __kprobes *trampoline_probe_handler(struct pt_regs *regs); 45 43 46 44 #endif /* CONFIG_KPROBES */ 47 45 #endif /* _ASM_RISCV_KPROBES_H */
+2
arch/riscv/include/asm/mmu.h
··· 19 19 #ifdef CONFIG_SMP 20 20 /* A local icache flush is needed before user execution can resume. */ 21 21 cpumask_t icache_stale_mask; 22 + /* A local tlb flush is needed before user execution can resume. */ 23 + cpumask_t tlb_stale_mask; 22 24 #endif 23 25 } mm_context_t; 24 26
+9 -9
arch/riscv/include/asm/page.h
··· 123 123 ((x) >= PAGE_OFFSET && (!IS_ENABLED(CONFIG_64BIT) || (x) < PAGE_OFFSET + KERN_VIRT_SIZE)) 124 124 125 125 #define linear_mapping_pa_to_va(x) ((void *)((unsigned long)(x) + kernel_map.va_pa_offset)) 126 - #define kernel_mapping_pa_to_va(y) ({ \ 127 - unsigned long _y = y; \ 128 - (IS_ENABLED(CONFIG_XIP_KERNEL) && _y < phys_ram_base) ? \ 129 - (void *)((unsigned long)(_y) + kernel_map.va_kernel_xip_pa_offset) : \ 130 - (void *)((unsigned long)(_y) + kernel_map.va_kernel_pa_offset + XIP_OFFSET); \ 126 + #define kernel_mapping_pa_to_va(y) ({ \ 127 + unsigned long _y = (unsigned long)(y); \ 128 + (IS_ENABLED(CONFIG_XIP_KERNEL) && _y < phys_ram_base) ? \ 129 + (void *)(_y + kernel_map.va_kernel_xip_pa_offset) : \ 130 + (void *)(_y + kernel_map.va_kernel_pa_offset + XIP_OFFSET); \ 131 131 }) 132 132 #define __pa_to_va_nodebug(x) linear_mapping_pa_to_va(x) 133 133 134 134 #define linear_mapping_va_to_pa(x) ((unsigned long)(x) - kernel_map.va_pa_offset) 135 135 #define kernel_mapping_va_to_pa(y) ({ \ 136 - unsigned long _y = y; \ 137 - (IS_ENABLED(CONFIG_XIP_KERNEL) && _y < kernel_map.virt_addr + XIP_OFFSET) ? \ 138 - ((unsigned long)(_y) - kernel_map.va_kernel_xip_pa_offset) : \ 139 - ((unsigned long)(_y) - kernel_map.va_kernel_pa_offset - XIP_OFFSET); \ 136 + unsigned long _y = (unsigned long)(y); \ 137 + (IS_ENABLED(CONFIG_XIP_KERNEL) && _y < kernel_map.virt_addr + XIP_OFFSET) ? \ 138 + (_y - kernel_map.va_kernel_xip_pa_offset) : \ 139 + (_y - kernel_map.va_kernel_pa_offset - XIP_OFFSET); \ 140 140 }) 141 141 142 142 #define __va_to_pa_nodebug(x) ({ \
+5 -1
arch/riscv/include/asm/pgtable-64.h
··· 25 25 #define PGDIR_MASK (~(PGDIR_SIZE - 1)) 26 26 27 27 /* p4d is folded into pgd in case of 4-level page table */ 28 - #define P4D_SHIFT 39 28 + #define P4D_SHIFT_L3 30 29 + #define P4D_SHIFT_L4 39 30 + #define P4D_SHIFT_L5 39 31 + #define P4D_SHIFT (pgtable_l5_enabled ? P4D_SHIFT_L5 : \ 32 + (pgtable_l4_enabled ? P4D_SHIFT_L4 : P4D_SHIFT_L3)) 29 33 #define P4D_SIZE (_AC(1, UL) << P4D_SHIFT) 30 34 #define P4D_MASK (~(P4D_SIZE - 1)) 31 35
+4 -1
arch/riscv/include/asm/pgtable.h
··· 415 415 * Relying on flush_tlb_fix_spurious_fault would suffice, but 416 416 * the extra traps reduce performance. So, eagerly SFENCE.VMA. 417 417 */ 418 - local_flush_tlb_page(address); 418 + flush_tlb_page(vma, address); 419 419 } 420 + 421 + #define __HAVE_ARCH_UPDATE_MMU_TLB 422 + #define update_mmu_tlb update_mmu_cache 420 423 421 424 static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, 422 425 unsigned long address, pmd_t *pmdp)
+5
arch/riscv/include/asm/sbi.h
··· 327 327 static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1; } 328 328 static inline void sbi_init(void) {} 329 329 #endif /* CONFIG_RISCV_SBI */ 330 + 331 + unsigned long riscv_cached_mvendorid(unsigned int cpu_id); 332 + unsigned long riscv_cached_marchid(unsigned int cpu_id); 333 + unsigned long riscv_cached_mimpid(unsigned int cpu_id); 334 + 330 335 #endif /* _ASM_RISCV_SBI_H */
+18
arch/riscv/include/asm/tlbflush.h
··· 22 22 { 23 23 ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory")); 24 24 } 25 + 26 + static inline void local_flush_tlb_all_asid(unsigned long asid) 27 + { 28 + __asm__ __volatile__ ("sfence.vma x0, %0" 29 + : 30 + : "r" (asid) 31 + : "memory"); 32 + } 33 + 34 + static inline void local_flush_tlb_page_asid(unsigned long addr, 35 + unsigned long asid) 36 + { 37 + __asm__ __volatile__ ("sfence.vma %0, %1" 38 + : 39 + : "r" (addr), "r" (asid) 40 + : "memory"); 41 + } 42 + 25 43 #else /* CONFIG_MMU */ 26 44 #define local_flush_tlb_all() do { } while (0) 27 45 #define local_flush_tlb_page(addr) do { } while (0)
+1 -1
arch/riscv/include/asm/vdso.h
··· 10 10 11 11 /* 12 12 * All systems with an MMU have a VDSO, but systems without an MMU don't 13 - * support shared libraries and therefor don't have one. 13 + * support shared libraries and therefore don't have one. 14 14 */ 15 15 #ifdef CONFIG_MMU 16 16
+18
arch/riscv/include/asm/vmalloc.h
··· 1 1 #ifndef _ASM_RISCV_VMALLOC_H 2 2 #define _ASM_RISCV_VMALLOC_H 3 3 4 + #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP 5 + 6 + #define IOREMAP_MAX_ORDER (PUD_SHIFT) 7 + 8 + #define arch_vmap_pud_supported arch_vmap_pud_supported 9 + static inline bool arch_vmap_pud_supported(pgprot_t prot) 10 + { 11 + return true; 12 + } 13 + 14 + #define arch_vmap_pmd_supported arch_vmap_pmd_supported 15 + static inline bool arch_vmap_pmd_supported(pgprot_t prot) 16 + { 17 + return true; 18 + } 19 + 20 + #endif 21 + 4 22 #endif /* _ASM_RISCV_VMALLOC_H */
+8 -4
arch/riscv/include/uapi/asm/ucontext.h
··· 15 15 struct ucontext *uc_link; 16 16 stack_t uc_stack; 17 17 sigset_t uc_sigmask; 18 - /* There's some padding here to allow sigset_t to be expanded in the 18 + /* 19 + * There's some padding here to allow sigset_t to be expanded in the 19 20 * future. Though this is unlikely, other architectures put uc_sigmask 20 21 * at the end of this structure and explicitly state it can be 21 - * expanded, so we didn't want to box ourselves in here. */ 22 + * expanded, so we didn't want to box ourselves in here. 23 + */ 22 24 __u8 __unused[1024 / 8 - sizeof(sigset_t)]; 23 - /* We can't put uc_sigmask at the end of this structure because we need 25 + /* 26 + * We can't put uc_sigmask at the end of this structure because we need 24 27 * to be able to expand sigcontext in the future. For example, the 25 28 * vector ISA extension will almost certainly add ISA state. We want 26 29 * to ensure all user-visible ISA state can be saved and restored via a 27 30 * ucontext, so we're putting this at the end in order to allow for 28 31 * infinite extensibility. Since we know this will be extended and we 29 32 * assume sigset_t won't be extended an extreme amount, we're 30 - * prioritizing this. */ 33 + * prioritizing this. 34 + */ 31 35 struct sigcontext uc_mcontext; 32 36 }; 33 37
+1
arch/riscv/kernel/Makefile
··· 81 81 obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o 82 82 obj-$(CONFIG_KEXEC_FILE) += elf_kexec.o machine_kexec_file.o 83 83 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 84 + obj-$(CONFIG_CRASH_CORE) += crash_core.o 84 85 85 86 obj-$(CONFIG_JUMP_LABEL) += jump_label.o 86 87
+27 -3
arch/riscv/kernel/cpu.c
··· 70 70 return -1; 71 71 } 72 72 73 - #ifdef CONFIG_PROC_FS 74 - 75 73 struct riscv_cpuinfo { 76 74 unsigned long mvendorid; 77 75 unsigned long marchid; 78 76 unsigned long mimpid; 79 77 }; 80 78 static DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); 79 + 80 + unsigned long riscv_cached_mvendorid(unsigned int cpu_id) 81 + { 82 + struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); 83 + 84 + return ci->mvendorid; 85 + } 86 + EXPORT_SYMBOL(riscv_cached_mvendorid); 87 + 88 + unsigned long riscv_cached_marchid(unsigned int cpu_id) 89 + { 90 + struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); 91 + 92 + return ci->marchid; 93 + } 94 + EXPORT_SYMBOL(riscv_cached_marchid); 95 + 96 + unsigned long riscv_cached_mimpid(unsigned int cpu_id) 97 + { 98 + struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id); 99 + 100 + return ci->mimpid; 101 + } 102 + EXPORT_SYMBOL(riscv_cached_mimpid); 81 103 82 104 static int riscv_cpuinfo_starting(unsigned int cpu) 83 105 { ··· 135 113 136 114 return 0; 137 115 } 138 - device_initcall(riscv_cpuinfo_init); 116 + arch_initcall(riscv_cpuinfo_init); 117 + 118 + #ifdef CONFIG_PROC_FS 139 119 140 120 #define __RISCV_ISA_EXT_DATA(UPROP, EXTID) \ 141 121 { \
+33 -10
arch/riscv/kernel/cpufeature.c
··· 9 9 #include <linux/bitmap.h> 10 10 #include <linux/ctype.h> 11 11 #include <linux/libfdt.h> 12 + #include <linux/log2.h> 12 13 #include <linux/module.h> 13 14 #include <linux/of.h> 14 15 #include <asm/alternative.h> ··· 69 68 } 70 69 EXPORT_SYMBOL_GPL(__riscv_isa_extension_available); 71 70 71 + static bool riscv_isa_extension_check(int id) 72 + { 73 + switch (id) { 74 + case RISCV_ISA_EXT_ZICBOM: 75 + if (!riscv_cbom_block_size) { 76 + pr_err("Zicbom detected in ISA string, but no cbom-block-size found\n"); 77 + return false; 78 + } else if (!is_power_of_2(riscv_cbom_block_size)) { 79 + pr_err("cbom-block-size present, but is not a power-of-2\n"); 80 + return false; 81 + } 82 + return true; 83 + } 84 + 85 + return true; 86 + } 87 + 72 88 void __init riscv_fill_hwcap(void) 73 89 { 74 90 struct device_node *node; 75 91 const char *isa; 76 92 char print_str[NUM_ALPHA_EXTS + 1]; 77 93 int i, j, rc; 78 - static unsigned long isa2hwcap[256] = {0}; 94 + unsigned long isa2hwcap[26] = {0}; 79 95 unsigned long hartid; 80 96 81 - isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I; 82 - isa2hwcap['m'] = isa2hwcap['M'] = COMPAT_HWCAP_ISA_M; 83 - isa2hwcap['a'] = isa2hwcap['A'] = COMPAT_HWCAP_ISA_A; 84 - isa2hwcap['f'] = isa2hwcap['F'] = COMPAT_HWCAP_ISA_F; 85 - isa2hwcap['d'] = isa2hwcap['D'] = COMPAT_HWCAP_ISA_D; 86 - isa2hwcap['c'] = isa2hwcap['C'] = COMPAT_HWCAP_ISA_C; 97 + isa2hwcap['i' - 'a'] = COMPAT_HWCAP_ISA_I; 98 + isa2hwcap['m' - 'a'] = COMPAT_HWCAP_ISA_M; 99 + isa2hwcap['a' - 'a'] = COMPAT_HWCAP_ISA_A; 100 + isa2hwcap['f' - 'a'] = COMPAT_HWCAP_ISA_F; 101 + isa2hwcap['d' - 'a'] = COMPAT_HWCAP_ISA_D; 102 + isa2hwcap['c' - 'a'] = COMPAT_HWCAP_ISA_C; 87 103 88 104 elf_hwcap = 0; 89 105 ··· 207 189 #define SET_ISA_EXT_MAP(name, bit) \ 208 190 do { \ 209 191 if ((ext_end - ext == sizeof(name) - 1) && \ 210 - !memcmp(ext, name, sizeof(name) - 1)) \ 192 + !memcmp(ext, name, sizeof(name) - 1) && \ 193 + riscv_isa_extension_check(bit)) \ 211 194 set_bit(bit, this_isa); \ 212 195 } while (false) \ 213 196 214 197 if (unlikely(ext_err)) 215 198 continue; 216 199 if (!ext_long) { 217 - this_hwcap |= isa2hwcap[(unsigned char)(*ext)]; 218 - set_bit(*ext - 'a', this_isa); 200 + int nr = *ext - 'a'; 201 + 202 + if (riscv_isa_extension_check(nr)) { 203 + this_hwcap |= isa2hwcap[nr]; 204 + set_bit(nr, this_isa); 205 + } 219 206 } else { 220 207 SET_ISA_EXT_MAP("sscofpmf", RISCV_ISA_EXT_SSCOFPMF); 221 208 SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT);
+21
arch/riscv/kernel/crash_core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #include <linux/crash_core.h> 4 + #include <linux/pagemap.h> 5 + 6 + void arch_crash_save_vmcoreinfo(void) 7 + { 8 + VMCOREINFO_NUMBER(VA_BITS); 9 + VMCOREINFO_NUMBER(phys_ram_base); 10 + 11 + vmcoreinfo_append_str("NUMBER(PAGE_OFFSET)=0x%lx\n", PAGE_OFFSET); 12 + vmcoreinfo_append_str("NUMBER(VMALLOC_START)=0x%lx\n", VMALLOC_START); 13 + vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%lx\n", VMALLOC_END); 14 + vmcoreinfo_append_str("NUMBER(VMEMMAP_START)=0x%lx\n", VMEMMAP_START); 15 + vmcoreinfo_append_str("NUMBER(VMEMMAP_END)=0x%lx\n", VMEMMAP_END); 16 + #ifdef CONFIG_64BIT 17 + vmcoreinfo_append_str("NUMBER(MODULES_VADDR)=0x%lx\n", MODULES_VADDR); 18 + vmcoreinfo_append_str("NUMBER(MODULES_END)=0x%lx\n", MODULES_END); 19 + #endif 20 + vmcoreinfo_append_str("NUMBER(KERNEL_LINK_ADDR)=0x%lx\n", KERNEL_LINK_ADDR); 21 + }
+14
arch/riscv/kernel/elf_kexec.c
··· 21 21 #include <linux/memblock.h> 22 22 #include <asm/setup.h> 23 23 24 + int arch_kimage_file_post_load_cleanup(struct kimage *image) 25 + { 26 + kvfree(image->arch.fdt); 27 + image->arch.fdt = NULL; 28 + 29 + vfree(image->elf_headers); 30 + image->elf_headers = NULL; 31 + image->elf_headers_sz = 0; 32 + 33 + return kexec_image_post_load_cleanup_default(image); 34 + } 35 + 24 36 static int riscv_kexec_elf_load(struct kimage *image, struct elfhdr *ehdr, 25 37 struct kexec_elf_info *elf_info, unsigned long old_pbase, 26 38 unsigned long new_pbase) ··· 310 298 pr_err("Error add DTB kbuf ret=%d\n", ret); 311 299 goto out_free_fdt; 312 300 } 301 + /* Cache the fdt buffer address for memory cleanup */ 302 + image->arch.fdt = fdt; 313 303 pr_notice("Loaded device tree at 0x%lx\n", kbuf.mem); 314 304 goto out; 315 305
+7 -14
arch/riscv/kernel/entry.S
··· 248 248 andi t0, t0, _TIF_SYSCALL_WORK 249 249 bnez t0, handle_syscall_trace_exit 250 250 251 - ret_from_exception: 251 + SYM_CODE_START_NOALIGN(ret_from_exception) 252 252 REG_L s0, PT_STATUS(sp) 253 253 csrc CSR_STATUS, SR_IE 254 254 #ifdef CONFIG_TRACE_IRQFLAGS ··· 262 262 andi s0, s0, SR_SPP 263 263 #endif 264 264 bnez s0, resume_kernel 265 + SYM_CODE_END(ret_from_exception) 265 266 266 - resume_userspace: 267 267 /* Interrupts must be disabled here so flags are checked atomically */ 268 268 REG_L s0, TASK_TI_FLAGS(tp) /* current_thread_info->flags */ 269 269 andi s1, s0, _TIF_WORK_MASK 270 - bnez s1, work_pending 271 - 270 + bnez s1, resume_userspace_slow 271 + resume_userspace: 272 272 #ifdef CONFIG_CONTEXT_TRACKING_USER 273 273 call user_enter_callable 274 274 #endif ··· 368 368 j restore_all 369 369 #endif 370 370 371 - work_pending: 371 + resume_userspace_slow: 372 372 /* Enter slow path for supplementary processing */ 373 - la ra, ret_from_exception 374 - andi s1, s0, _TIF_NEED_RESCHED 375 - bnez s1, work_resched 376 - work_notifysig: 377 - /* Handle pending signals and notify-resume requests */ 378 - csrs CSR_STATUS, SR_IE /* Enable interrupts for do_notify_resume() */ 379 373 move a0, sp /* pt_regs */ 380 374 move a1, s0 /* current_thread_info->flags */ 381 - tail do_notify_resume 382 - work_resched: 383 - tail schedule 375 + call do_work_pending 376 + j resume_userspace 384 377 385 378 /* Slow paths for ptrace. */ 386 379 handle_syscall_trace_enter:
+23 -21
arch/riscv/kernel/mcount.S
··· 15 15 16 16 .macro SAVE_ABI_STATE 17 17 addi sp, sp, -16 18 - sd s0, 0(sp) 19 - sd ra, 8(sp) 18 + REG_S s0, 0*SZREG(sp) 19 + REG_S ra, 1*SZREG(sp) 20 20 addi s0, sp, 16 21 21 .endm 22 22 ··· 25 25 * register if a0 was not saved. 26 26 */ 27 27 .macro SAVE_RET_ABI_STATE 28 - addi sp, sp, -32 29 - sd s0, 16(sp) 30 - sd ra, 24(sp) 31 - sd a0, 8(sp) 32 - addi s0, sp, 32 28 + addi sp, sp, -4*SZREG 29 + REG_S s0, 2*SZREG(sp) 30 + REG_S ra, 3*SZREG(sp) 31 + REG_S a0, 1*SZREG(sp) 32 + REG_S a1, 0*SZREG(sp) 33 + addi s0, sp, 4*SZREG 33 34 .endm 34 35 35 36 .macro RESTORE_ABI_STATE 36 - ld ra, 8(sp) 37 - ld s0, 0(sp) 37 + REG_L ra, 1*SZREG(sp) 38 + REG_L s0, 0*SZREG(sp) 38 39 addi sp, sp, 16 39 40 .endm 40 41 41 42 .macro RESTORE_RET_ABI_STATE 42 - ld ra, 24(sp) 43 - ld s0, 16(sp) 44 - ld a0, 8(sp) 45 - addi sp, sp, 32 43 + REG_L ra, 3*SZREG(sp) 44 + REG_L s0, 2*SZREG(sp) 45 + REG_L a0, 1*SZREG(sp) 46 + REG_L a1, 0*SZREG(sp) 47 + addi sp, sp, 4*SZREG 46 48 .endm 47 49 48 50 ENTRY(ftrace_stub) ··· 73 71 mv a0, t6 74 72 #endif 75 73 call ftrace_return_to_handler 76 - mv a1, a0 74 + mv a2, a0 77 75 RESTORE_RET_ABI_STATE 78 - jalr a1 76 + jalr a2 79 77 ENDPROC(return_to_handler) 80 78 #endif 81 79 ··· 84 82 la t4, ftrace_stub 85 83 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 86 84 la t0, ftrace_graph_return 87 - ld t1, 0(t0) 85 + REG_L t1, 0(t0) 88 86 bne t1, t4, do_ftrace_graph_caller 89 87 90 88 la t3, ftrace_graph_entry 91 - ld t2, 0(t3) 89 + REG_L t2, 0(t3) 92 90 la t6, ftrace_graph_entry_stub 93 91 bne t2, t6, do_ftrace_graph_caller 94 92 #endif 95 93 la t3, ftrace_trace_function 96 - ld t5, 0(t3) 94 + REG_L t5, 0(t3) 97 95 bne t5, t4, do_trace 98 96 ret 99 97 ··· 103 101 * prepare_to_return(&ra_to_caller_of_caller, ra_to_caller) 104 102 */ 105 103 do_ftrace_graph_caller: 106 - addi a0, s0, -8 104 + addi a0, s0, -SZREG 107 105 mv a1, ra 108 106 #ifdef HAVE_FUNCTION_GRAPH_FP_TEST 109 - ld a2, -16(s0) 107 + REG_L a2, -2*SZREG(s0) 110 108 #endif 111 109 SAVE_ABI_STATE 112 110 call prepare_ftrace_return ··· 119 117 * (*ftrace_trace_function)(ra_to_caller, ra_to_caller_of_caller) 120 118 */ 121 119 do_trace: 122 - ld a1, -8(s0) 120 + REG_L a1, -SZREG(s0) 123 121 mv a0, ra 124 122 125 123 SAVE_ABI_STATE
+1 -1
arch/riscv/kernel/probes/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o simulate-insn.o 3 - obj-$(CONFIG_KPROBES) += kprobes_trampoline.o 3 + obj-$(CONFIG_RETHOOK) += rethook.o rethook_trampoline.o 4 4 obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o 5 5 obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o simulate-insn.o 6 6 CFLAGS_REMOVE_simulate-insn.o = $(CC_FLAGS_FTRACE)
-13
arch/riscv/kernel/probes/kprobes.c
··· 345 345 return ret; 346 346 } 347 347 348 - void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) 349 - { 350 - return (void *)kretprobe_trampoline_handler(regs, NULL); 351 - } 352 - 353 - void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, 354 - struct pt_regs *regs) 355 - { 356 - ri->ret_addr = (kprobe_opcode_t *)regs->ra; 357 - ri->fp = NULL; 358 - regs->ra = (unsigned long) &__kretprobe_trampoline; 359 - } 360 - 361 348 int __kprobes arch_trampoline_kprobe(struct kprobe *p) 362 349 { 363 350 return 0;
+3 -3
arch/riscv/kernel/probes/kprobes_trampoline.S arch/riscv/kernel/probes/rethook_trampoline.S
··· 75 75 REG_L x31, PT_T6(sp) 76 76 .endm 77 77 78 - ENTRY(__kretprobe_trampoline) 78 + ENTRY(arch_rethook_trampoline) 79 79 addi sp, sp, -(PT_SIZE_ON_STACK) 80 80 save_all_base_regs 81 81 82 82 move a0, sp /* pt_regs */ 83 83 84 - call trampoline_probe_handler 84 + call arch_rethook_trampoline_callback 85 85 86 86 /* use the result as the return-address */ 87 87 move ra, a0 ··· 90 90 addi sp, sp, PT_SIZE_ON_STACK 91 91 92 92 ret 93 - ENDPROC(__kretprobe_trampoline) 93 + ENDPROC(arch_rethook_trampoline)
+27
arch/riscv/kernel/probes/rethook.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Generic return hook for riscv. 4 + */ 5 + 6 + #include <linux/kprobes.h> 7 + #include <linux/rethook.h> 8 + #include "rethook.h" 9 + 10 + /* This is called from arch_rethook_trampoline() */ 11 + unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) 12 + { 13 + return rethook_trampoline_handler(regs, regs->s0); 14 + } 15 + 16 + NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); 17 + 18 + void arch_rethook_prepare(struct rethook_node *rhn, struct pt_regs *regs, bool mcount) 19 + { 20 + rhn->ret_addr = regs->ra; 21 + rhn->frame = regs->s0; 22 + 23 + /* replace return addr with trampoline */ 24 + regs->ra = (unsigned long)arch_rethook_trampoline; 25 + } 26 + 27 + NOKPROBE_SYMBOL(arch_rethook_prepare);
+8
arch/riscv/kernel/probes/rethook.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + #ifndef __RISCV_RETHOOK_H 3 + #define __RISCV_RETHOOK_H 4 + 5 + unsigned long arch_rethook_trampoline_callback(struct pt_regs *regs); 6 + void arch_rethook_prepare(struct rethook_node *rhn, struct pt_regs *regs, bool mcount); 7 + 8 + #endif
+21 -13
arch/riscv/kernel/signal.c
··· 313 313 } 314 314 315 315 /* 316 - * notification of userspace execution resumption 317 - * - triggered by the _TIF_WORK_MASK flags 316 + * Handle any pending work on the resume-to-userspace path, as indicated by 317 + * _TIF_WORK_MASK. Entered from assembly with IRQs off. 318 318 */ 319 - asmlinkage __visible void do_notify_resume(struct pt_regs *regs, 320 - unsigned long thread_info_flags) 319 + asmlinkage __visible void do_work_pending(struct pt_regs *regs, 320 + unsigned long thread_info_flags) 321 321 { 322 - if (thread_info_flags & _TIF_UPROBE) 323 - uprobe_notify_resume(regs); 324 - 325 - /* Handle pending signal delivery */ 326 - if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) 327 - do_signal(regs); 328 - 329 - if (thread_info_flags & _TIF_NOTIFY_RESUME) 330 - resume_user_mode_work(regs); 322 + do { 323 + if (thread_info_flags & _TIF_NEED_RESCHED) { 324 + schedule(); 325 + } else { 326 + local_irq_enable(); 327 + if (thread_info_flags & _TIF_UPROBE) 328 + uprobe_notify_resume(regs); 329 + /* Handle pending signal delivery */ 330 + if (thread_info_flags & (_TIF_SIGPENDING | 331 + _TIF_NOTIFY_SIGNAL)) 332 + do_signal(regs); 333 + if (thread_info_flags & _TIF_NOTIFY_RESUME) 334 + resume_user_mode_work(regs); 335 + } 336 + local_irq_disable(); 337 + thread_info_flags = read_thread_flags(); 338 + } while (thread_info_flags & _TIF_WORK_MASK); 331 339 }
+10 -1
arch/riscv/kernel/stacktrace.c
··· 16 16 17 17 #ifdef CONFIG_FRAME_POINTER 18 18 19 + extern asmlinkage void ret_from_exception(void); 20 + 19 21 void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, 20 22 bool (*fn)(void *, unsigned long), void *arg) 21 23 { ··· 60 58 } else { 61 59 fp = frame->fp; 62 60 pc = ftrace_graph_ret_addr(current, NULL, frame->ra, 63 - (unsigned long *)(fp - 8)); 61 + &frame->ra); 62 + if (pc == (unsigned long)ret_from_exception) { 63 + if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc))) 64 + break; 65 + 66 + pc = ((struct pt_regs *)sp)->epc; 67 + fp = ((struct pt_regs *)sp)->s0; 68 + } 64 69 } 65 70 66 71 }
+14 -8
arch/riscv/kernel/traps.c
··· 208 208 #endif /* CONFIG_GENERIC_BUG */ 209 209 210 210 #ifdef CONFIG_VMAP_STACK 211 + /* 212 + * Extra stack space that allows us to provide panic messages when the kernel 213 + * has overflowed its stack. 214 + */ 211 215 static DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], 212 216 overflow_stack)__aligned(16); 213 217 /* 214 - * shadow stack, handled_ kernel_ stack_ overflow(in kernel/entry.S) is used 215 - * to get per-cpu overflow stack(get_overflow_stack). 218 + * A temporary stack for use by handle_kernel_stack_overflow. This is used so 219 + * we can call into C code to get the per-hart overflow stack. Usage of this 220 + * stack must be protected by spin_shadow_stack. 216 221 */ 217 - long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)]; 218 - asmlinkage unsigned long get_overflow_stack(void) 219 - { 220 - return (unsigned long)this_cpu_ptr(overflow_stack) + 221 - OVERFLOW_STACK_SIZE; 222 - } 222 + long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)] __aligned(16); 223 223 224 224 /* 225 225 * A pseudo spinlock to protect the shadow stack from being used by multiple ··· 229 229 * checking a proper spinlock gives us doesn't matter. 230 230 */ 231 231 unsigned long spin_shadow_stack; 232 + 233 + asmlinkage unsigned long get_overflow_stack(void) 234 + { 235 + return (unsigned long)this_cpu_ptr(overflow_stack) + 236 + OVERFLOW_STACK_SIZE; 237 + } 232 238 233 239 asmlinkage void handle_bad_stack(struct pt_regs *regs) 234 240 {
+2
arch/riscv/mm/Makefile
··· 13 13 obj-$(CONFIG_MMU) += fault.o pageattr.o 14 14 obj-y += cacheflush.o 15 15 obj-y += context.o 16 + obj-y += pgtable.o 17 + obj-y += pmem.o 16 18 17 19 ifeq ($(CONFIG_MMU),y) 18 20 obj-$(CONFIG_SMP) += tlbflush.o
+7
arch/riscv/mm/cacheflush.c
··· 83 83 { 84 84 struct page *page = pte_page(pte); 85 85 86 + /* 87 + * HugeTLB pages are always fully mapped, so only setting head page's 88 + * PG_dcache_clean flag is enough. 89 + */ 90 + if (PageHuge(page)) 91 + page = compound_head(page); 92 + 86 93 if (!test_and_set_bit(PG_dcache_clean, &page->flags)) 87 94 flush_icache_all(); 88 95 }
+10
arch/riscv/mm/context.c
··· 196 196 197 197 if (need_flush_tlb) 198 198 local_flush_tlb_all(); 199 + #ifdef CONFIG_SMP 200 + else { 201 + cpumask_t *mask = &mm->context.tlb_stale_mask; 202 + 203 + if (cpumask_test_cpu(cpu, mask)) { 204 + cpumask_clear_cpu(cpu, mask); 205 + local_flush_tlb_all_asid(cntx & asid_mask); 206 + } 207 + } 208 + #endif 199 209 } 200 210 201 211 static void set_mm_noasid(struct mm_struct *mm)
+13 -12
arch/riscv/mm/init.c
··· 672 672 static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size) 673 673 { 674 674 /* Upgrade to PMD_SIZE mappings whenever possible */ 675 - if ((base & (PMD_SIZE - 1)) || (size & (PMD_SIZE - 1))) 676 - return PAGE_SIZE; 675 + base &= PMD_SIZE - 1; 676 + if (!base && size >= PMD_SIZE) 677 + return PMD_SIZE; 677 678 678 - return PMD_SIZE; 679 + return PAGE_SIZE; 679 680 } 680 681 681 682 #ifdef CONFIG_XIP_KERNEL ··· 927 926 */ 928 927 static void __init pt_ops_set_fixmap(void) 929 928 { 930 - pt_ops.alloc_pte = kernel_mapping_pa_to_va((uintptr_t)alloc_pte_fixmap); 931 - pt_ops.get_pte_virt = kernel_mapping_pa_to_va((uintptr_t)get_pte_virt_fixmap); 929 + pt_ops.alloc_pte = kernel_mapping_pa_to_va(alloc_pte_fixmap); 930 + pt_ops.get_pte_virt = kernel_mapping_pa_to_va(get_pte_virt_fixmap); 932 931 #ifndef __PAGETABLE_PMD_FOLDED 933 - pt_ops.alloc_pmd = kernel_mapping_pa_to_va((uintptr_t)alloc_pmd_fixmap); 934 - pt_ops.get_pmd_virt = kernel_mapping_pa_to_va((uintptr_t)get_pmd_virt_fixmap); 935 - pt_ops.alloc_pud = kernel_mapping_pa_to_va((uintptr_t)alloc_pud_fixmap); 936 - pt_ops.get_pud_virt = kernel_mapping_pa_to_va((uintptr_t)get_pud_virt_fixmap); 937 - pt_ops.alloc_p4d = kernel_mapping_pa_to_va((uintptr_t)alloc_p4d_fixmap); 938 - pt_ops.get_p4d_virt = kernel_mapping_pa_to_va((uintptr_t)get_p4d_virt_fixmap); 932 + pt_ops.alloc_pmd = kernel_mapping_pa_to_va(alloc_pmd_fixmap); 933 + pt_ops.get_pmd_virt = kernel_mapping_pa_to_va(get_pmd_virt_fixmap); 934 + pt_ops.alloc_pud = kernel_mapping_pa_to_va(alloc_pud_fixmap); 935 + pt_ops.get_pud_virt = kernel_mapping_pa_to_va(get_pud_virt_fixmap); 936 + pt_ops.alloc_p4d = kernel_mapping_pa_to_va(alloc_p4d_fixmap); 937 + pt_ops.get_p4d_virt = kernel_mapping_pa_to_va(get_p4d_virt_fixmap); 939 938 #endif 940 939 } 941 940 ··· 1111 1110 if (end >= __pa(PAGE_OFFSET) + memory_limit) 1112 1111 end = __pa(PAGE_OFFSET) + memory_limit; 1113 1112 1114 - map_size = best_map_size(start, end - start); 1115 1113 for (pa = start; pa < end; pa += map_size) { 1116 1114 va = (uintptr_t)__va(pa); 1115 + map_size = best_map_size(pa, end - pa); 1117 1116 1118 1117 create_pgd_mapping(swapper_pg_dir, va, pa, map_size, 1119 1118 pgprot_from_va(va));
+83
arch/riscv/mm/pgtable.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <asm/pgalloc.h> 4 + #include <linux/gfp.h> 5 + #include <linux/kernel.h> 6 + #include <linux/pgtable.h> 7 + 8 + #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP 9 + int p4d_set_huge(p4d_t *p4d, phys_addr_t addr, pgprot_t prot) 10 + { 11 + return 0; 12 + } 13 + 14 + void p4d_clear_huge(p4d_t *p4d) 15 + { 16 + } 17 + 18 + int pud_set_huge(pud_t *pud, phys_addr_t phys, pgprot_t prot) 19 + { 20 + pud_t new_pud = pfn_pud(__phys_to_pfn(phys), prot); 21 + 22 + set_pud(pud, new_pud); 23 + return 1; 24 + } 25 + 26 + int pud_clear_huge(pud_t *pud) 27 + { 28 + if (!pud_leaf(READ_ONCE(*pud))) 29 + return 0; 30 + pud_clear(pud); 31 + return 1; 32 + } 33 + 34 + int pud_free_pmd_page(pud_t *pud, unsigned long addr) 35 + { 36 + pmd_t *pmd = pud_pgtable(*pud); 37 + int i; 38 + 39 + pud_clear(pud); 40 + 41 + flush_tlb_kernel_range(addr, addr + PUD_SIZE); 42 + 43 + for (i = 0; i < PTRS_PER_PMD; i++) { 44 + if (!pmd_none(pmd[i])) { 45 + pte_t *pte = (pte_t *)pmd_page_vaddr(pmd[i]); 46 + 47 + pte_free_kernel(NULL, pte); 48 + } 49 + } 50 + 51 + pmd_free(NULL, pmd); 52 + 53 + return 1; 54 + } 55 + 56 + int pmd_set_huge(pmd_t *pmd, phys_addr_t phys, pgprot_t prot) 57 + { 58 + pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), prot); 59 + 60 + set_pmd(pmd, new_pmd); 61 + return 1; 62 + } 63 + 64 + int pmd_clear_huge(pmd_t *pmd) 65 + { 66 + if (!pmd_leaf(READ_ONCE(*pmd))) 67 + return 0; 68 + pmd_clear(pmd); 69 + return 1; 70 + } 71 + 72 + int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) 73 + { 74 + pte_t *pte = (pte_t *)pmd_page_vaddr(*pmd); 75 + 76 + pmd_clear(pmd); 77 + 78 + flush_tlb_kernel_range(addr, addr + PMD_SIZE); 79 + pte_free_kernel(NULL, pte); 80 + return 1; 81 + } 82 + 83 + #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */
+1 -1
arch/riscv/mm/physaddr.c
··· 22 22 phys_addr_t __phys_addr_symbol(unsigned long x) 23 23 { 24 24 unsigned long kernel_start = kernel_map.virt_addr; 25 - unsigned long kernel_end = (unsigned long)_end; 25 + unsigned long kernel_end = kernel_start + kernel_map.size; 26 26 27 27 /* 28 28 * Boundary checking aginst the kernel image mapping.
+21
arch/riscv/mm/pmem.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2022 Ventana Micro Systems Inc. 4 + */ 5 + 6 + #include <linux/export.h> 7 + #include <linux/libnvdimm.h> 8 + 9 + #include <asm/cacheflush.h> 10 + 11 + void arch_wb_cache_pmem(void *addr, size_t size) 12 + { 13 + ALT_CMO_OP(clean, addr, size, riscv_cbom_block_size); 14 + } 15 + EXPORT_SYMBOL_GPL(arch_wb_cache_pmem); 16 + 17 + void arch_invalidate_pmem(void *addr, size_t size) 18 + { 19 + ALT_CMO_OP(inval, addr, size, riscv_cbom_block_size); 20 + } 21 + EXPORT_SYMBOL_GPL(arch_invalidate_pmem);
+11 -17
arch/riscv/mm/tlbflush.c
··· 5 5 #include <linux/sched.h> 6 6 #include <asm/sbi.h> 7 7 #include <asm/mmu_context.h> 8 - 9 - static inline void local_flush_tlb_all_asid(unsigned long asid) 10 - { 11 - __asm__ __volatile__ ("sfence.vma x0, %0" 12 - : 13 - : "r" (asid) 14 - : "memory"); 15 - } 16 - 17 - static inline void local_flush_tlb_page_asid(unsigned long addr, 18 - unsigned long asid) 19 - { 20 - __asm__ __volatile__ ("sfence.vma %0, %1" 21 - : 22 - : "r" (addr), "r" (asid) 23 - : "memory"); 24 - } 8 + #include <asm/tlbflush.h> 25 9 26 10 void flush_tlb_all(void) 27 11 { ··· 15 31 static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start, 16 32 unsigned long size, unsigned long stride) 17 33 { 34 + struct cpumask *pmask = &mm->context.tlb_stale_mask; 18 35 struct cpumask *cmask = mm_cpumask(mm); 19 36 unsigned int cpuid; 20 37 bool broadcast; ··· 28 43 broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids; 29 44 if (static_branch_unlikely(&use_asid_allocator)) { 30 45 unsigned long asid = atomic_long_read(&mm->context.id); 46 + 47 + /* 48 + * TLB will be immediately flushed on harts concurrently 49 + * executing this MM context. TLB flush on other harts 50 + * is deferred until this MM context migrates there. 51 + */ 52 + cpumask_setall(pmask); 53 + cpumask_clear_cpu(cpuid, pmask); 54 + cpumask_andnot(pmask, pmask, cmask); 31 55 32 56 if (broadcast) { 33 57 sbi_remote_sfence_vma_asid(cmask, start, size, asid);
+2 -19
drivers/irqchip/Kconfig
··· 538 538 different processors within the SoC. 539 539 540 540 config RISCV_INTC 541 - bool "RISC-V Local Interrupt Controller" 541 + bool 542 542 depends on RISCV 543 - default y 544 - help 545 - This enables support for the per-HART local interrupt controller 546 - found in standard RISC-V systems. The per-HART local interrupt 547 - controller handles timer interrupts, software interrupts, and 548 - hardware interrupts. Without a per-HART local interrupt controller, 549 - a RISC-V system will be unable to handle any interrupts. 550 - 551 - If you don't know what to do here, say Y. 552 543 553 544 config SIFIVE_PLIC 554 - bool "SiFive Platform-Level Interrupt Controller" 545 + bool 555 546 depends on RISCV 556 547 select IRQ_DOMAIN_HIERARCHY 557 548 select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP 558 - help 559 - This enables support for the PLIC chip found in SiFive (and 560 - potentially other) RISC-V systems. The PLIC controls devices 561 - interrupts and connects them to each core's local interrupt 562 - controller. Aside from timer and software interrupts, all other 563 - interrupt sources are subordinate to the PLIC. 564 - 565 - If you don't know what to do here, say Y. 566 549 567 550 config EXYNOS_IRQ_COMBINER 568 551 bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
+24 -10
drivers/perf/riscv_pmu_sbi.c
··· 20 20 #include <linux/cpu_pm.h> 21 21 #include <linux/sched/clock.h> 22 22 23 + #include <asm/errata_list.h> 23 24 #include <asm/sbi.h> 24 25 #include <asm/hwcap.h> 25 26 ··· 48 47 * per_cpu in case of harts with different pmu counters 49 48 */ 50 49 static union sbi_pmu_ctr_info *pmu_ctr_list; 50 + static bool riscv_pmu_use_irq; 51 + static unsigned int riscv_pmu_irq_num; 51 52 static unsigned int riscv_pmu_irq; 52 53 53 54 struct sbi_pmu_event_data { ··· 583 580 fidx = find_first_bit(cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS); 584 581 event = cpu_hw_evt->events[fidx]; 585 582 if (!event) { 586 - csr_clear(CSR_SIP, SIP_LCOFIP); 583 + csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num)); 587 584 return IRQ_NONE; 588 585 } 589 586 ··· 591 588 pmu_sbi_stop_hw_ctrs(pmu); 592 589 593 590 /* Overflow status register should only be read after counter are stopped */ 594 - overflow = csr_read(CSR_SSCOUNTOVF); 591 + ALT_SBI_PMU_OVERFLOW(overflow); 595 592 596 593 /* 597 594 * Overflow interrupt pending bit should only be cleared after stopping 598 595 * all the counters to avoid any race condition. 599 596 */ 600 - csr_clear(CSR_SIP, SIP_LCOFIP); 597 + csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num)); 601 598 602 599 /* No overflow bit is set */ 603 600 if (!overflow) ··· 664 661 /* Stop all the counters so that they can be enabled from perf */ 665 662 pmu_sbi_stop_all(pmu); 666 663 667 - if (riscv_isa_extension_available(NULL, SSCOFPMF)) { 664 + if (riscv_pmu_use_irq) { 668 665 cpu_hw_evt->irq = riscv_pmu_irq; 669 - csr_clear(CSR_IP, BIT(RV_IRQ_PMU)); 670 - csr_set(CSR_IE, BIT(RV_IRQ_PMU)); 666 + csr_clear(CSR_IP, BIT(riscv_pmu_irq_num)); 667 + csr_set(CSR_IE, BIT(riscv_pmu_irq_num)); 671 668 enable_percpu_irq(riscv_pmu_irq, IRQ_TYPE_NONE); 672 669 } 673 670 ··· 676 673 677 674 static int pmu_sbi_dying_cpu(unsigned int cpu, struct hlist_node *node) 678 675 { 679 - if (riscv_isa_extension_available(NULL, SSCOFPMF)) { 676 + if (riscv_pmu_use_irq) { 680 677 disable_percpu_irq(riscv_pmu_irq); 681 - csr_clear(CSR_IE, BIT(RV_IRQ_PMU)); 678 + csr_clear(CSR_IE, BIT(riscv_pmu_irq_num)); 682 679 } 683 680 684 681 /* Disable all counters access for user mode now */ ··· 694 691 struct device_node *cpu, *child; 695 692 struct irq_domain *domain = NULL; 696 693 697 - if (!riscv_isa_extension_available(NULL, SSCOFPMF)) 694 + if (riscv_isa_extension_available(NULL, SSCOFPMF)) { 695 + riscv_pmu_irq_num = RV_IRQ_PMU; 696 + riscv_pmu_use_irq = true; 697 + } else if (IS_ENABLED(CONFIG_ERRATA_THEAD_PMU) && 698 + riscv_cached_mvendorid(0) == THEAD_VENDOR_ID && 699 + riscv_cached_marchid(0) == 0 && 700 + riscv_cached_mimpid(0) == 0) { 701 + riscv_pmu_irq_num = THEAD_C9XX_RV_IRQ_PMU; 702 + riscv_pmu_use_irq = true; 703 + } 704 + 705 + if (!riscv_pmu_use_irq) 698 706 return -EOPNOTSUPP; 699 707 700 708 for_each_of_cpu_node(cpu) { ··· 727 713 return -ENODEV; 728 714 } 729 715 730 - riscv_pmu_irq = irq_create_mapping(domain, RV_IRQ_PMU); 716 + riscv_pmu_irq = irq_create_mapping(domain, riscv_pmu_irq_num); 731 717 if (!riscv_pmu_irq) { 732 718 pr_err("Failed to map PMU interrupt for node\n"); 733 719 return -ENODEV;
-1
scripts/head-object-list.txt
··· 38 38 arch/powerpc/kernel/fpu.o 39 39 arch/powerpc/kernel/vector.o 40 40 arch/powerpc/kernel/prom_init.o 41 - arch/riscv/kernel/head.o 42 41 arch/s390/kernel/head64.o 43 42 arch/sh/kernel/head_32.o 44 43 arch/sparc/kernel/head_32.o