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

Pull more RISC-V updates from Palmer Dabbelt:

- Support for tuning for systems with fast misaligned accesses.

- Support for SBI-based suspend.

- Support for the new SBI debug console extension.

- The T-Head CMOs now use PA-based flushes.

- Support for enabling the V extension in kernel code.

- Optimized IP checksum routines.

- Various ftrace improvements.

- Support for archrandom, which depends on the Zkr extension.

- The build is no longer broken under NET=n, KUNIT=y for ports that
don't define their own ipv6 checksum.

* tag 'riscv-for-linus-6.8-mw4' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (56 commits)
lib: checksum: Fix build with CONFIG_NET=n
riscv: lib: Check if output in asm goto supported
riscv: Fix build error on rv32 + XIP
riscv: optimize ELF relocation function in riscv
RISC-V: Implement archrandom when Zkr is available
riscv: Optimize hweight API with Zbb extension
riscv: add dependency among Image(.gz), loader(.bin), and vmlinuz.efi
samples: ftrace: Add RISC-V support for SAMPLE_FTRACE_DIRECT[_MULTI]
riscv: ftrace: Add DYNAMIC_FTRACE_WITH_DIRECT_CALLS support
riscv: ftrace: Make function graph use ftrace directly
riscv: select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY
lib/Kconfig.debug: Update AS_HAS_NON_CONST_LEB128 comment and name
riscv: Restrict DWARF5 when building with LLVM to known working versions
riscv: Hoist linker relaxation disabling logic into Kconfig
kunit: Add tests for csum_ipv6_magic and ip_fast_csum
riscv: Add checksum library
riscv: Add checksum header
riscv: Add static key for misaligned accesses
asm-generic: Improve csum_fold
RISC-V: selftests: cbo: Ensure asm operands match constraints
...

+2678 -215
+7 -2
Documentation/devicetree/bindings/riscv/cpus.yaml
··· 63 64 mmu-type: 65 description: 66 - Identifies the MMU address translation mode used on this 67 - hart. These values originate from the RISC-V Privileged 68 Specification document, available from 69 https://riscv.org/specifications/ 70 $ref: /schemas/types.yaml#/definitions/string ··· 79 $ref: /schemas/types.yaml#/definitions/uint32 80 description: 81 The blocksize in bytes for the Zicbom cache operations. 82 83 riscv,cboz-block-size: 84 $ref: /schemas/types.yaml#/definitions/uint32
··· 63 64 mmu-type: 65 description: 66 + Identifies the largest MMU address translation mode supported by 67 + this hart. These values originate from the RISC-V Privileged 68 Specification document, available from 69 https://riscv.org/specifications/ 70 $ref: /schemas/types.yaml#/definitions/string ··· 79 $ref: /schemas/types.yaml#/definitions/uint32 80 description: 81 The blocksize in bytes for the Zicbom cache operations. 82 + 83 + riscv,cbop-block-size: 84 + $ref: /schemas/types.yaml#/definitions/uint32 85 + description: 86 + The blocksize in bytes for the Zicbop cache operations. 87 88 riscv,cboz-block-size: 89 $ref: /schemas/types.yaml#/definitions/uint32
+1 -1
Documentation/devicetree/bindings/riscv/extensions.yaml
··· 48 insensitive, letters in the riscv,isa string must be all 49 lowercase. 50 $ref: /schemas/types.yaml#/definitions/string 51 - pattern: ^rv(?:64|32)imaf?d?q?c?b?k?j?p?v?h?(?:[hsxz](?:[a-z])+)?(?:_[hsxz](?:[a-z])+)*$ 52 deprecated: true 53 54 riscv,isa-base:
··· 48 insensitive, letters in the riscv,isa string must be all 49 lowercase. 50 $ref: /schemas/types.yaml#/definitions/string 51 + pattern: ^rv(?:64|32)imaf?d?q?c?b?k?j?p?v?h?(?:[hsxz](?:[0-9a-z])+)?(?:_[hsxz](?:[0-9a-z])+)*$ 52 deprecated: true 53 54 riscv,isa-base:
+1 -1
Documentation/features/vm/TLB/arch-support.txt
··· 20 | openrisc: | .. | 21 | parisc: | TODO | 22 | powerpc: | TODO | 23 - | riscv: | TODO | 24 | s390: | TODO | 25 | sh: | TODO | 26 | sparc: | TODO |
··· 20 | openrisc: | .. | 21 | parisc: | TODO | 22 | powerpc: | TODO | 23 + | riscv: | ok | 24 | s390: | TODO | 25 | sh: | TODO | 26 | sparc: | TODO |
+56 -1
arch/riscv/Kconfig
··· 53 select ARCH_USE_MEMTEST 54 select ARCH_USE_QUEUED_RWLOCKS 55 select ARCH_USES_CFI_TRAPS if CFI_CLANG 56 select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU 57 select ARCH_WANT_FRAME_POINTERS 58 select ARCH_WANT_GENERAL_HUGETLB if !RISCV_ISA_SVNAPOT ··· 67 select CLINT_TIMER if !MMU 68 select CLONE_BACKWARDS 69 select COMMON_CLK 70 - select CPU_PM if CPU_IDLE || HIBERNATION 71 select EDAC_SUPPORT 72 select FRAME_POINTER if PERF_EVENTS || (FUNCTION_TRACER && !DYNAMIC_FTRACE) 73 select GENERIC_ARCH_TOPOLOGY 74 select GENERIC_ATOMIC64 if !64BIT 75 select GENERIC_CLOCKEVENTS_BROADCAST if SMP ··· 117 select HAVE_DEBUG_KMEMLEAK 118 select HAVE_DMA_CONTIGUOUS if MMU 119 select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE) 120 select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE 121 select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL 122 select HAVE_FUNCTION_GRAPH_TRACER ··· 145 select HAVE_REGS_AND_STACK_ACCESS_API 146 select HAVE_RETHOOK if !XIP_KERNEL 147 select HAVE_RSEQ 148 select HAVE_STACKPROTECTOR 149 select HAVE_SYSCALL_TRACEPOINTS 150 select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU ··· 187 def_bool $(cc-option,-fsanitize=shadow-call-stack) 188 # https://github.com/riscv-non-isa/riscv-elf-psabi-doc/commit/a484e843e6eeb51f0cb7b8819e50da6d2444d769 189 depends on $(ld-option,--no-relax-gp) 190 191 config ARCH_MMAP_RND_BITS_MIN 192 default 18 if 64BIT ··· 548 549 If you don't know what to do here, say Y. 550 551 config TOOLCHAIN_HAS_ZBB 552 bool 553 default y ··· 695 Say Y here if you want the kernel to embed support for misaligned 696 load/store for both kernel and userspace. When disable, misaligned 697 accesses will generate SIGBUS in userspace and panic in kernel. 698 699 endmenu # "Platform type" 700
··· 53 select ARCH_USE_MEMTEST 54 select ARCH_USE_QUEUED_RWLOCKS 55 select ARCH_USES_CFI_TRAPS if CFI_CLANG 56 + select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH if SMP && MMU 57 select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU 58 select ARCH_WANT_FRAME_POINTERS 59 select ARCH_WANT_GENERAL_HUGETLB if !RISCV_ISA_SVNAPOT ··· 66 select CLINT_TIMER if !MMU 67 select CLONE_BACKWARDS 68 select COMMON_CLK 69 + select CPU_PM if CPU_IDLE || HIBERNATION || SUSPEND 70 select EDAC_SUPPORT 71 select FRAME_POINTER if PERF_EVENTS || (FUNCTION_TRACER && !DYNAMIC_FTRACE) 72 + select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY if DYNAMIC_FTRACE 73 select GENERIC_ARCH_TOPOLOGY 74 select GENERIC_ATOMIC64 if !64BIT 75 select GENERIC_CLOCKEVENTS_BROADCAST if SMP ··· 115 select HAVE_DEBUG_KMEMLEAK 116 select HAVE_DMA_CONTIGUOUS if MMU 117 select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE) 118 + select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS 119 select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE 120 select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL 121 select HAVE_FUNCTION_GRAPH_TRACER ··· 142 select HAVE_REGS_AND_STACK_ACCESS_API 143 select HAVE_RETHOOK if !XIP_KERNEL 144 select HAVE_RSEQ 145 + select HAVE_SAMPLE_FTRACE_DIRECT 146 + select HAVE_SAMPLE_FTRACE_DIRECT_MULTI 147 select HAVE_STACKPROTECTOR 148 select HAVE_SYSCALL_TRACEPOINTS 149 select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU ··· 182 def_bool $(cc-option,-fsanitize=shadow-call-stack) 183 # https://github.com/riscv-non-isa/riscv-elf-psabi-doc/commit/a484e843e6eeb51f0cb7b8819e50da6d2444d769 184 depends on $(ld-option,--no-relax-gp) 185 + 186 + config RISCV_USE_LINKER_RELAXATION 187 + def_bool y 188 + # https://github.com/llvm/llvm-project/commit/6611d58f5bbcbec77262d392e2923e1d680f6985 189 + depends on !LD_IS_LLD || LLD_VERSION >= 150000 190 + 191 + # https://github.com/llvm/llvm-project/commit/bbc0f99f3bc96f1db16f649fc21dd18e5b0918f6 192 + config ARCH_HAS_BROKEN_DWARF5 193 + def_bool y 194 + depends on RISCV_USE_LINKER_RELAXATION 195 + # https://github.com/llvm/llvm-project/commit/1df5ea29b43690b6622db2cad7b745607ca4de6a 196 + depends on AS_IS_LLVM && AS_VERSION < 180000 197 + # https://github.com/llvm/llvm-project/commit/7ffabb61a5569444b5ac9322e22e5471cc5e4a77 198 + depends on LD_IS_LLD && LLD_VERSION < 180000 199 200 config ARCH_MMAP_RND_BITS_MIN 201 default 18 if 64BIT ··· 529 530 If you don't know what to do here, say Y. 531 532 + config RISCV_ISA_V_UCOPY_THRESHOLD 533 + int "Threshold size for vectorized user copies" 534 + depends on RISCV_ISA_V 535 + default 768 536 + help 537 + Prefer using vectorized copy_to_user()/copy_from_user() when the 538 + workload size exceeds this value. 539 + 540 + config RISCV_ISA_V_PREEMPTIVE 541 + bool "Run kernel-mode Vector with kernel preemption" 542 + depends on PREEMPTION 543 + depends on RISCV_ISA_V 544 + default y 545 + help 546 + Usually, in-kernel SIMD routines are run with preemption disabled. 547 + Functions which envoke long running SIMD thus must yield core's 548 + vector unit to prevent blocking other tasks for too long. 549 + 550 + This config allows kernel to run SIMD without explicitly disable 551 + preemption. Enabling this config will result in higher memory 552 + consumption due to the allocation of per-task's kernel Vector context. 553 + 554 config TOOLCHAIN_HAS_ZBB 555 bool 556 default y ··· 654 Say Y here if you want the kernel to embed support for misaligned 655 load/store for both kernel and userspace. When disable, misaligned 656 accesses will generate SIGBUS in userspace and panic in kernel. 657 + 658 + config RISCV_EFFICIENT_UNALIGNED_ACCESS 659 + bool "Assume the CPU supports fast unaligned memory accesses" 660 + depends on NONPORTABLE 661 + select DCACHE_WORD_ACCESS if MMU 662 + select HAVE_EFFICIENT_UNALIGNED_ACCESS 663 + help 664 + Say Y here if you want the kernel to assume that the CPU supports 665 + efficient unaligned memory accesses. When enabled, this option 666 + improves the performance of the kernel on such CPUs. However, the 667 + kernel will run much more slowly, or will not be able to run at all, 668 + on CPUs that do not support efficient unaligned memory accesses. 669 + 670 + If unsure what to do here, say N. 671 672 endmenu # "Platform type" 673
+1
arch/riscv/Kconfig.errata
··· 98 depends on ERRATA_THEAD && MMU 99 select DMA_DIRECT_REMAP 100 select RISCV_DMA_NONCOHERENT 101 default y 102 help 103 This will apply the cache management errata to handle the
··· 98 depends on ERRATA_THEAD && MMU 99 select DMA_DIRECT_REMAP 100 select RISCV_DMA_NONCOHERENT 101 + select RISCV_NONSTANDARD_CACHE_OPS 102 default y 103 help 104 This will apply the cache management errata to handle the
+5 -3
arch/riscv/Makefile
··· 43 KBUILD_LDFLAGS += -melf32lriscv 44 endif 45 46 - ifeq ($(CONFIG_LD_IS_LLD),y) 47 - ifeq ($(call test-lt, $(CONFIG_LLD_VERSION), 150000),y) 48 KBUILD_CFLAGS += -mno-relax 49 KBUILD_AFLAGS += -mno-relax 50 ifndef CONFIG_AS_IS_LLVM 51 KBUILD_CFLAGS += -Wa,-mno-relax 52 KBUILD_AFLAGS += -Wa,-mno-relax 53 - endif 54 endif 55 endif 56 ··· 106 # unaligned accesses. While unaligned accesses are explicitly allowed in the 107 # RISC-V ISA, they're emulated by machine mode traps on all extant 108 # architectures. It's faster to have GCC emit only aligned accesses. 109 KBUILD_CFLAGS += $(call cc-option,-mstrict-align) 110 111 ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) 112 prepare: stack_protector_prepare ··· 163 164 all: $(notdir $(KBUILD_IMAGE)) 165 166 $(BOOT_TARGETS): vmlinux 167 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ 168 @$(kecho) ' Kernel: $(boot)/$@ is ready'
··· 43 KBUILD_LDFLAGS += -melf32lriscv 44 endif 45 46 + ifndef CONFIG_RISCV_USE_LINKER_RELAXATION 47 KBUILD_CFLAGS += -mno-relax 48 KBUILD_AFLAGS += -mno-relax 49 ifndef CONFIG_AS_IS_LLVM 50 KBUILD_CFLAGS += -Wa,-mno-relax 51 KBUILD_AFLAGS += -Wa,-mno-relax 52 endif 53 endif 54 ··· 108 # unaligned accesses. While unaligned accesses are explicitly allowed in the 109 # RISC-V ISA, they're emulated by machine mode traps on all extant 110 # architectures. It's faster to have GCC emit only aligned accesses. 111 + ifneq ($(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS),y) 112 KBUILD_CFLAGS += $(call cc-option,-mstrict-align) 113 + endif 114 115 ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) 116 prepare: stack_protector_prepare ··· 163 164 all: $(notdir $(KBUILD_IMAGE)) 165 166 + loader.bin: loader 167 + Image.gz loader vmlinuz.efi: Image 168 $(BOOT_TARGETS): vmlinux 169 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ 170 @$(kecho) ' Kernel: $(boot)/$@ is ready'
+1
arch/riscv/configs/defconfig
··· 149 CONFIG_SERIAL_8250_DW=y 150 CONFIG_SERIAL_OF_PLATFORM=y 151 CONFIG_SERIAL_SH_SCI=y 152 CONFIG_VIRTIO_CONSOLE=y 153 CONFIG_HW_RANDOM=y 154 CONFIG_HW_RANDOM_VIRTIO=y
··· 149 CONFIG_SERIAL_8250_DW=y 150 CONFIG_SERIAL_OF_PLATFORM=y 151 CONFIG_SERIAL_SH_SCI=y 152 + CONFIG_SERIAL_EARLYCON_RISCV_SBI=y 153 CONFIG_VIRTIO_CONSOLE=y 154 CONFIG_HW_RANDOM=y 155 CONFIG_HW_RANDOM_VIRTIO=y
+67 -2
arch/riscv/errata/thead/errata.c
··· 12 #include <asm/alternative.h> 13 #include <asm/cacheflush.h> 14 #include <asm/cpufeature.h> 15 #include <asm/errata_list.h> 16 #include <asm/hwprobe.h> 17 #include <asm/patch.h> 18 #include <asm/vendorid_list.h> 19 ··· 35 return false; 36 } 37 38 static bool errata_probe_cmo(unsigned int stage, 39 unsigned long arch_id, unsigned long impid) 40 { ··· 113 if (stage == RISCV_ALTERNATIVES_BOOT) { 114 riscv_cbom_block_size = L1_CACHE_BYTES; 115 riscv_noncoherent_supported(); 116 } 117 118 return true; ··· 143 if (errata_probe_pbmt(stage, archid, impid)) 144 cpu_req_errata |= BIT(ERRATA_THEAD_PBMT); 145 146 - if (errata_probe_cmo(stage, archid, impid)) 147 - cpu_req_errata |= BIT(ERRATA_THEAD_CMO); 148 149 if (errata_probe_pmu(stage, archid, impid)) 150 cpu_req_errata |= BIT(ERRATA_THEAD_PMU);
··· 12 #include <asm/alternative.h> 13 #include <asm/cacheflush.h> 14 #include <asm/cpufeature.h> 15 + #include <asm/dma-noncoherent.h> 16 #include <asm/errata_list.h> 17 #include <asm/hwprobe.h> 18 + #include <asm/io.h> 19 #include <asm/patch.h> 20 #include <asm/vendorid_list.h> 21 ··· 33 return false; 34 } 35 36 + /* 37 + * th.dcache.ipa rs1 (invalidate, physical address) 38 + * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 39 + * 0000001 01010 rs1 000 00000 0001011 40 + * th.dcache.iva rs1 (invalidate, virtual address) 41 + * 0000001 00110 rs1 000 00000 0001011 42 + * 43 + * th.dcache.cpa rs1 (clean, physical address) 44 + * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 45 + * 0000001 01001 rs1 000 00000 0001011 46 + * th.dcache.cva rs1 (clean, virtual address) 47 + * 0000001 00101 rs1 000 00000 0001011 48 + * 49 + * th.dcache.cipa rs1 (clean then invalidate, physical address) 50 + * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 51 + * 0000001 01011 rs1 000 00000 0001011 52 + * th.dcache.civa rs1 (clean then invalidate, virtual address) 53 + * 0000001 00111 rs1 000 00000 0001011 54 + * 55 + * th.sync.s (make sure all cache operations finished) 56 + * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 57 + * 0000000 11001 00000 000 00000 0001011 58 + */ 59 + #define THEAD_INVAL_A0 ".long 0x02a5000b" 60 + #define THEAD_CLEAN_A0 ".long 0x0295000b" 61 + #define THEAD_FLUSH_A0 ".long 0x02b5000b" 62 + #define THEAD_SYNC_S ".long 0x0190000b" 63 + 64 + #define THEAD_CMO_OP(_op, _start, _size, _cachesize) \ 65 + asm volatile("mv a0, %1\n\t" \ 66 + "j 2f\n\t" \ 67 + "3:\n\t" \ 68 + THEAD_##_op##_A0 "\n\t" \ 69 + "add a0, a0, %0\n\t" \ 70 + "2:\n\t" \ 71 + "bltu a0, %2, 3b\n\t" \ 72 + THEAD_SYNC_S \ 73 + : : "r"(_cachesize), \ 74 + "r"((unsigned long)(_start) & ~((_cachesize) - 1UL)), \ 75 + "r"((unsigned long)(_start) + (_size)) \ 76 + : "a0") 77 + 78 + static void thead_errata_cache_inv(phys_addr_t paddr, size_t size) 79 + { 80 + THEAD_CMO_OP(INVAL, paddr, size, riscv_cbom_block_size); 81 + } 82 + 83 + static void thead_errata_cache_wback(phys_addr_t paddr, size_t size) 84 + { 85 + THEAD_CMO_OP(CLEAN, paddr, size, riscv_cbom_block_size); 86 + } 87 + 88 + static void thead_errata_cache_wback_inv(phys_addr_t paddr, size_t size) 89 + { 90 + THEAD_CMO_OP(FLUSH, paddr, size, riscv_cbom_block_size); 91 + } 92 + 93 + static const struct riscv_nonstd_cache_ops thead_errata_cmo_ops = { 94 + .wback = &thead_errata_cache_wback, 95 + .inv = &thead_errata_cache_inv, 96 + .wback_inv = &thead_errata_cache_wback_inv, 97 + }; 98 + 99 static bool errata_probe_cmo(unsigned int stage, 100 unsigned long arch_id, unsigned long impid) 101 { ··· 48 if (stage == RISCV_ALTERNATIVES_BOOT) { 49 riscv_cbom_block_size = L1_CACHE_BYTES; 50 riscv_noncoherent_supported(); 51 + riscv_noncoherent_register_cache_ops(&thead_errata_cmo_ops); 52 } 53 54 return true; ··· 77 if (errata_probe_pbmt(stage, archid, impid)) 78 cpu_req_errata |= BIT(ERRATA_THEAD_PBMT); 79 80 + errata_probe_cmo(stage, archid, impid); 81 82 if (errata_probe_pmu(stage, archid, impid)) 83 cpu_req_errata |= BIT(ERRATA_THEAD_PMU);
+78
arch/riscv/include/asm/arch_hweight.h
···
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Based on arch/x86/include/asm/arch_hweight.h 4 + */ 5 + 6 + #ifndef _ASM_RISCV_HWEIGHT_H 7 + #define _ASM_RISCV_HWEIGHT_H 8 + 9 + #include <asm/alternative-macros.h> 10 + #include <asm/hwcap.h> 11 + 12 + #if (BITS_PER_LONG == 64) 13 + #define CPOPW "cpopw " 14 + #elif (BITS_PER_LONG == 32) 15 + #define CPOPW "cpop " 16 + #else 17 + #error "Unexpected BITS_PER_LONG" 18 + #endif 19 + 20 + static __always_inline unsigned int __arch_hweight32(unsigned int w) 21 + { 22 + #ifdef CONFIG_RISCV_ISA_ZBB 23 + asm_volatile_goto(ALTERNATIVE("j %l[legacy]", "nop", 0, 24 + RISCV_ISA_EXT_ZBB, 1) 25 + : : : : legacy); 26 + 27 + asm (".option push\n" 28 + ".option arch,+zbb\n" 29 + CPOPW "%0, %0\n" 30 + ".option pop\n" 31 + : "+r" (w) : :); 32 + 33 + return w; 34 + 35 + legacy: 36 + #endif 37 + return __sw_hweight32(w); 38 + } 39 + 40 + static inline unsigned int __arch_hweight16(unsigned int w) 41 + { 42 + return __arch_hweight32(w & 0xffff); 43 + } 44 + 45 + static inline unsigned int __arch_hweight8(unsigned int w) 46 + { 47 + return __arch_hweight32(w & 0xff); 48 + } 49 + 50 + #if BITS_PER_LONG == 64 51 + static __always_inline unsigned long __arch_hweight64(__u64 w) 52 + { 53 + # ifdef CONFIG_RISCV_ISA_ZBB 54 + asm_volatile_goto(ALTERNATIVE("j %l[legacy]", "nop", 0, 55 + RISCV_ISA_EXT_ZBB, 1) 56 + : : : : legacy); 57 + 58 + asm (".option push\n" 59 + ".option arch,+zbb\n" 60 + "cpop %0, %0\n" 61 + ".option pop\n" 62 + : "+r" (w) : :); 63 + 64 + return w; 65 + 66 + legacy: 67 + # endif 68 + return __sw_hweight64(w); 69 + } 70 + #else /* BITS_PER_LONG == 64 */ 71 + static inline unsigned long __arch_hweight64(__u64 w) 72 + { 73 + return __arch_hweight32((u32)w) + 74 + __arch_hweight32((u32)(w >> 32)); 75 + } 76 + #endif /* !(BITS_PER_LONG == 64) */ 77 + 78 + #endif /* _ASM_RISCV_HWEIGHT_H */
+72
arch/riscv/include/asm/archrandom.h
···
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Kernel interface for the RISCV arch_random_* functions 4 + * 5 + * Copyright (c) 2023 Rivos Inc. 6 + * 7 + */ 8 + 9 + #ifndef ASM_RISCV_ARCHRANDOM_H 10 + #define ASM_RISCV_ARCHRANDOM_H 11 + 12 + #include <asm/csr.h> 13 + #include <asm/processor.h> 14 + 15 + #define SEED_RETRY_LOOPS 100 16 + 17 + static inline bool __must_check csr_seed_long(unsigned long *v) 18 + { 19 + unsigned int retry = SEED_RETRY_LOOPS, valid_seeds = 0; 20 + const int needed_seeds = sizeof(long) / sizeof(u16); 21 + u16 *entropy = (u16 *)v; 22 + 23 + do { 24 + /* 25 + * The SEED CSR must be accessed with a read-write instruction. 26 + */ 27 + unsigned long csr_seed = csr_swap(CSR_SEED, 0); 28 + unsigned long opst = csr_seed & SEED_OPST_MASK; 29 + 30 + switch (opst) { 31 + case SEED_OPST_ES16: 32 + entropy[valid_seeds++] = csr_seed & SEED_ENTROPY_MASK; 33 + if (valid_seeds == needed_seeds) 34 + return true; 35 + break; 36 + 37 + case SEED_OPST_DEAD: 38 + pr_err_once("archrandom: Unrecoverable error\n"); 39 + return false; 40 + 41 + case SEED_OPST_BIST: 42 + case SEED_OPST_WAIT: 43 + default: 44 + cpu_relax(); 45 + continue; 46 + } 47 + } while (--retry); 48 + 49 + return false; 50 + } 51 + 52 + static inline size_t __must_check arch_get_random_longs(unsigned long *v, size_t max_longs) 53 + { 54 + return 0; 55 + } 56 + 57 + static inline size_t __must_check arch_get_random_seed_longs(unsigned long *v, size_t max_longs) 58 + { 59 + if (!max_longs) 60 + return 0; 61 + 62 + /* 63 + * If Zkr is supported and csr_seed_long succeeds, we return one long 64 + * worth of entropy. 65 + */ 66 + if (riscv_has_extension_likely(RISCV_ISA_EXT_ZKR) && csr_seed_long(v)) 67 + return 1; 68 + 69 + return 0; 70 + } 71 + 72 + #endif /* ASM_RISCV_ARCHRANDOM_H */
+15
arch/riscv/include/asm/asm-extable.h
··· 6 #define EX_TYPE_FIXUP 1 7 #define EX_TYPE_BPF 2 8 #define EX_TYPE_UACCESS_ERR_ZERO 3 9 10 #ifdef CONFIG_MMU 11 ··· 48 #define EX_DATA_REG_ZERO_SHIFT 5 49 #define EX_DATA_REG_ZERO GENMASK(9, 5) 50 51 #define EX_DATA_REG(reg, gpr) \ 52 "((.L__gpr_num_" #gpr ") << " __stringify(EX_DATA_REG_##reg##_SHIFT) ")" 53 ··· 67 68 #define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err) \ 69 _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero) 70 71 #endif /* __ASSEMBLY__ */ 72
··· 6 #define EX_TYPE_FIXUP 1 7 #define EX_TYPE_BPF 2 8 #define EX_TYPE_UACCESS_ERR_ZERO 3 9 + #define EX_TYPE_LOAD_UNALIGNED_ZEROPAD 4 10 11 #ifdef CONFIG_MMU 12 ··· 47 #define EX_DATA_REG_ZERO_SHIFT 5 48 #define EX_DATA_REG_ZERO GENMASK(9, 5) 49 50 + #define EX_DATA_REG_DATA_SHIFT 0 51 + #define EX_DATA_REG_DATA GENMASK(4, 0) 52 + #define EX_DATA_REG_ADDR_SHIFT 5 53 + #define EX_DATA_REG_ADDR GENMASK(9, 5) 54 + 55 #define EX_DATA_REG(reg, gpr) \ 56 "((.L__gpr_num_" #gpr ") << " __stringify(EX_DATA_REG_##reg##_SHIFT) ")" 57 ··· 61 62 #define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err) \ 63 _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero) 64 + 65 + #define _ASM_EXTABLE_LOAD_UNALIGNED_ZEROPAD(insn, fixup, data, addr) \ 66 + __DEFINE_ASM_GPR_NUMS \ 67 + __ASM_EXTABLE_RAW(#insn, #fixup, \ 68 + __stringify(EX_TYPE_LOAD_UNALIGNED_ZEROPAD), \ 69 + "(" \ 70 + EX_DATA_REG(DATA, data) " | " \ 71 + EX_DATA_REG(ADDR, addr) \ 72 + ")") 73 74 #endif /* __ASSEMBLY__ */ 75
+27
arch/riscv/include/asm/asm-prototypes.h
··· 9 long long __ashrti3(long long a, int b); 10 long long __ashlti3(long long a, int b); 11 12 13 #define DECLARE_DO_ERROR_INFO(name) asmlinkage void name(struct pt_regs *regs) 14
··· 9 long long __ashrti3(long long a, int b); 10 long long __ashlti3(long long a, int b); 11 12 + #ifdef CONFIG_RISCV_ISA_V 13 + 14 + #ifdef CONFIG_MMU 15 + asmlinkage int enter_vector_usercopy(void *dst, void *src, size_t n); 16 + #endif /* CONFIG_MMU */ 17 + 18 + void xor_regs_2_(unsigned long bytes, unsigned long *__restrict p1, 19 + const unsigned long *__restrict p2); 20 + void xor_regs_3_(unsigned long bytes, unsigned long *__restrict p1, 21 + const unsigned long *__restrict p2, 22 + const unsigned long *__restrict p3); 23 + void xor_regs_4_(unsigned long bytes, unsigned long *__restrict p1, 24 + const unsigned long *__restrict p2, 25 + const unsigned long *__restrict p3, 26 + const unsigned long *__restrict p4); 27 + void xor_regs_5_(unsigned long bytes, unsigned long *__restrict p1, 28 + const unsigned long *__restrict p2, 29 + const unsigned long *__restrict p3, 30 + const unsigned long *__restrict p4, 31 + const unsigned long *__restrict p5); 32 + 33 + #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE 34 + asmlinkage void riscv_v_context_nesting_start(struct pt_regs *regs); 35 + asmlinkage void riscv_v_context_nesting_end(struct pt_regs *regs); 36 + #endif /* CONFIG_RISCV_ISA_V_PREEMPTIVE */ 37 + 38 + #endif /* CONFIG_RISCV_ISA_V */ 39 40 #define DECLARE_DO_ERROR_INFO(name) asmlinkage void name(struct pt_regs *regs) 41
+3 -1
arch/riscv/include/asm/bitops.h
··· 271 #include <asm-generic/bitops/fls64.h> 272 #include <asm-generic/bitops/sched.h> 273 274 - #include <asm-generic/bitops/hweight.h> 275 276 #if (BITS_PER_LONG == 64) 277 #define __AMO(op) "amo" #op ".d"
··· 271 #include <asm-generic/bitops/fls64.h> 272 #include <asm-generic/bitops/sched.h> 273 274 + #include <asm/arch_hweight.h> 275 + 276 + #include <asm-generic/bitops/const_hweight.h> 277 278 #if (BITS_PER_LONG == 64) 279 #define __AMO(op) "amo" #op ".d"
+93
arch/riscv/include/asm/checksum.h
···
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Checksum routines 4 + * 5 + * Copyright (C) 2023 Rivos Inc. 6 + */ 7 + #ifndef __ASM_RISCV_CHECKSUM_H 8 + #define __ASM_RISCV_CHECKSUM_H 9 + 10 + #include <linux/in6.h> 11 + #include <linux/uaccess.h> 12 + 13 + #define ip_fast_csum ip_fast_csum 14 + 15 + extern unsigned int do_csum(const unsigned char *buff, int len); 16 + #define do_csum do_csum 17 + 18 + /* Default version is sufficient for 32 bit */ 19 + #ifndef CONFIG_32BIT 20 + #define _HAVE_ARCH_IPV6_CSUM 21 + __sum16 csum_ipv6_magic(const struct in6_addr *saddr, 22 + const struct in6_addr *daddr, 23 + __u32 len, __u8 proto, __wsum sum); 24 + #endif 25 + 26 + /* Define riscv versions of functions before importing asm-generic/checksum.h */ 27 + #include <asm-generic/checksum.h> 28 + 29 + /** 30 + * Quickly compute an IP checksum with the assumption that IPv4 headers will 31 + * always be in multiples of 32-bits, and have an ihl of at least 5. 32 + * 33 + * @ihl: the number of 32 bit segments and must be greater than or equal to 5. 34 + * @iph: assumed to be word aligned given that NET_IP_ALIGN is set to 2 on 35 + * riscv, defining IP headers to be aligned. 36 + */ 37 + static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) 38 + { 39 + unsigned long csum = 0; 40 + int pos = 0; 41 + 42 + do { 43 + csum += ((const unsigned int *)iph)[pos]; 44 + if (IS_ENABLED(CONFIG_32BIT)) 45 + csum += csum < ((const unsigned int *)iph)[pos]; 46 + } while (++pos < ihl); 47 + 48 + /* 49 + * ZBB only saves three instructions on 32-bit and five on 64-bit so not 50 + * worth checking if supported without Alternatives. 51 + */ 52 + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && 53 + IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) { 54 + unsigned long fold_temp; 55 + 56 + asm_volatile_goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, 57 + RISCV_ISA_EXT_ZBB, 1) 58 + : 59 + : 60 + : 61 + : no_zbb); 62 + 63 + if (IS_ENABLED(CONFIG_32BIT)) { 64 + asm(".option push \n\ 65 + .option arch,+zbb \n\ 66 + not %[fold_temp], %[csum] \n\ 67 + rori %[csum], %[csum], 16 \n\ 68 + sub %[csum], %[fold_temp], %[csum] \n\ 69 + .option pop" 70 + : [csum] "+r" (csum), [fold_temp] "=&r" (fold_temp)); 71 + } else { 72 + asm(".option push \n\ 73 + .option arch,+zbb \n\ 74 + rori %[fold_temp], %[csum], 32 \n\ 75 + add %[csum], %[fold_temp], %[csum] \n\ 76 + srli %[csum], %[csum], 32 \n\ 77 + not %[fold_temp], %[csum] \n\ 78 + roriw %[csum], %[csum], 16 \n\ 79 + subw %[csum], %[fold_temp], %[csum] \n\ 80 + .option pop" 81 + : [csum] "+r" (csum), [fold_temp] "=&r" (fold_temp)); 82 + } 83 + return (__force __sum16)(csum >> 16); 84 + } 85 + no_zbb: 86 + #ifndef CONFIG_32BIT 87 + csum += ror64(csum, 32); 88 + csum >>= 32; 89 + #endif 90 + return csum_fold((__force __wsum)csum); 91 + } 92 + 93 + #endif /* __ASM_RISCV_CHECKSUM_H */
+2
arch/riscv/include/asm/cpufeature.h
··· 135 return __riscv_isa_extension_available(hart_isa[cpu].isa, ext); 136 } 137 138 #endif
··· 135 return __riscv_isa_extension_available(hart_isa[cpu].isa, ext); 136 } 137 138 + DECLARE_STATIC_KEY_FALSE(fast_misaligned_access_speed_key); 139 + 140 #endif
+9
arch/riscv/include/asm/csr.h
··· 411 #define CSR_VTYPE 0xc21 412 #define CSR_VLENB 0xc22 413 414 #ifdef CONFIG_RISCV_M_MODE 415 # define CSR_STATUS CSR_MSTATUS 416 # define CSR_IE CSR_MIE
··· 411 #define CSR_VTYPE 0xc21 412 #define CSR_VLENB 0xc22 413 414 + /* Scalar Crypto Extension - Entropy */ 415 + #define CSR_SEED 0x015 416 + #define SEED_OPST_MASK _AC(0xC0000000, UL) 417 + #define SEED_OPST_BIST _AC(0x00000000, UL) 418 + #define SEED_OPST_WAIT _AC(0x40000000, UL) 419 + #define SEED_OPST_ES16 _AC(0x80000000, UL) 420 + #define SEED_OPST_DEAD _AC(0xC0000000, UL) 421 + #define SEED_ENTROPY_MASK _AC(0xFFFF, UL) 422 + 423 #ifdef CONFIG_RISCV_M_MODE 424 # define CSR_STATUS CSR_MSTATUS 425 # define CSR_IE CSR_MIE
+17
arch/riscv/include/asm/entry-common.h
··· 4 #define _ASM_RISCV_ENTRY_COMMON_H 5 6 #include <asm/stacktrace.h> 7 8 void handle_page_fault(struct pt_regs *regs); 9 void handle_break(struct pt_regs *regs);
··· 4 #define _ASM_RISCV_ENTRY_COMMON_H 5 6 #include <asm/stacktrace.h> 7 + #include <asm/thread_info.h> 8 + #include <asm/vector.h> 9 + 10 + static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs, 11 + unsigned long ti_work) 12 + { 13 + if (ti_work & _TIF_RISCV_V_DEFER_RESTORE) { 14 + clear_thread_flag(TIF_RISCV_V_DEFER_RESTORE); 15 + /* 16 + * We are already called with irq disabled, so go without 17 + * keeping track of riscv_v_flags. 18 + */ 19 + riscv_v_vstate_restore(&current->thread.vstate, regs); 20 + } 21 + } 22 + 23 + #define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare 24 25 void handle_page_fault(struct pt_regs *regs); 26 void handle_break(struct pt_regs *regs);
+6 -44
arch/riscv/include/asm/errata_list.h
··· 24 25 #ifdef CONFIG_ERRATA_THEAD 26 #define ERRATA_THEAD_PBMT 0 27 - #define ERRATA_THEAD_CMO 1 28 - #define ERRATA_THEAD_PMU 2 29 - #define ERRATA_THEAD_NUMBER 3 30 #endif 31 32 #ifdef __ASSEMBLY__ ··· 93 #define ALT_THEAD_PMA(_val) 94 #endif 95 96 - /* 97 - * th.dcache.ipa rs1 (invalidate, physical address) 98 - * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 99 - * 0000001 01010 rs1 000 00000 0001011 100 - * th.dache.iva rs1 (invalida, virtual address) 101 - * 0000001 00110 rs1 000 00000 0001011 102 - * 103 - * th.dcache.cpa rs1 (clean, physical address) 104 - * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 105 - * 0000001 01001 rs1 000 00000 0001011 106 - * th.dcache.cva rs1 (clean, virtual address) 107 - * 0000001 00101 rs1 000 00000 0001011 108 - * 109 - * th.dcache.cipa rs1 (clean then invalidate, physical address) 110 - * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 111 - * 0000001 01011 rs1 000 00000 0001011 112 - * th.dcache.civa rs1 (... virtual address) 113 - * 0000001 00111 rs1 000 00000 0001011 114 - * 115 - * th.sync.s (make sure all cache operations finished) 116 - * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 117 - * 0000000 11001 00000 000 00000 0001011 118 - */ 119 - #define THEAD_INVAL_A0 ".long 0x0265000b" 120 - #define THEAD_CLEAN_A0 ".long 0x0255000b" 121 - #define THEAD_FLUSH_A0 ".long 0x0275000b" 122 - #define THEAD_SYNC_S ".long 0x0190000b" 123 - 124 #define ALT_CMO_OP(_op, _start, _size, _cachesize) \ 125 - asm volatile(ALTERNATIVE_2( \ 126 - __nops(6), \ 127 "mv a0, %1\n\t" \ 128 "j 2f\n\t" \ 129 "3:\n\t" \ 130 CBO_##_op(a0) \ 131 "add a0, a0, %0\n\t" \ 132 "2:\n\t" \ 133 - "bltu a0, %2, 3b\n\t" \ 134 - "nop", 0, RISCV_ISA_EXT_ZICBOM, CONFIG_RISCV_ISA_ZICBOM, \ 135 - "mv a0, %1\n\t" \ 136 - "j 2f\n\t" \ 137 - "3:\n\t" \ 138 - THEAD_##_op##_A0 "\n\t" \ 139 - "add a0, a0, %0\n\t" \ 140 - "2:\n\t" \ 141 - "bltu a0, %2, 3b\n\t" \ 142 - THEAD_SYNC_S, THEAD_VENDOR_ID, \ 143 - ERRATA_THEAD_CMO, CONFIG_ERRATA_THEAD_CMO) \ 144 : : "r"(_cachesize), \ 145 "r"((unsigned long)(_start) & ~((_cachesize) - 1UL)), \ 146 "r"((unsigned long)(_start) + (_size)) \
··· 24 25 #ifdef CONFIG_ERRATA_THEAD 26 #define ERRATA_THEAD_PBMT 0 27 + #define ERRATA_THEAD_PMU 1 28 + #define ERRATA_THEAD_NUMBER 2 29 #endif 30 31 #ifdef __ASSEMBLY__ ··· 94 #define ALT_THEAD_PMA(_val) 95 #endif 96 97 #define ALT_CMO_OP(_op, _start, _size, _cachesize) \ 98 + asm volatile(ALTERNATIVE( \ 99 + __nops(5), \ 100 "mv a0, %1\n\t" \ 101 "j 2f\n\t" \ 102 "3:\n\t" \ 103 CBO_##_op(a0) \ 104 "add a0, a0, %0\n\t" \ 105 "2:\n\t" \ 106 + "bltu a0, %2, 3b\n\t", \ 107 + 0, RISCV_ISA_EXT_ZICBOM, CONFIG_RISCV_ISA_ZICBOM) \ 108 : : "r"(_cachesize), \ 109 "r"((unsigned long)(_start) & ~((_cachesize) - 1UL)), \ 110 "r"((unsigned long)(_start) + (_size)) \
+17 -1
arch/riscv/include/asm/ftrace.h
··· 128 struct dyn_ftrace; 129 int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec); 130 #define ftrace_init_nop ftrace_init_nop 131 - #endif 132 133 #endif /* CONFIG_DYNAMIC_FTRACE */ 134
··· 128 struct dyn_ftrace; 129 int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec); 130 #define ftrace_init_nop ftrace_init_nop 131 + 132 + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 133 + struct ftrace_ops; 134 + struct ftrace_regs; 135 + void ftrace_graph_func(unsigned long ip, unsigned long parent_ip, 136 + struct ftrace_ops *op, struct ftrace_regs *fregs); 137 + #define ftrace_graph_func ftrace_graph_func 138 + 139 + static inline void __arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr) 140 + { 141 + regs->t1 = addr; 142 + } 143 + #define arch_ftrace_set_direct_caller(fregs, addr) \ 144 + __arch_ftrace_set_direct_caller(&(fregs)->regs, addr) 145 + #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ 146 + 147 + #endif /* __ASSEMBLY__ */ 148 149 #endif /* CONFIG_DYNAMIC_FTRACE */ 150
+1 -1
arch/riscv/include/asm/pgtable.h
··· 865 #define TASK_SIZE_MIN (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2) 866 867 #ifdef CONFIG_COMPAT 868 - #define TASK_SIZE_32 (_AC(0x80000000, UL) - PAGE_SIZE) 869 #define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \ 870 TASK_SIZE_32 : TASK_SIZE_64) 871 #else
··· 865 #define TASK_SIZE_MIN (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2) 866 867 #ifdef CONFIG_COMPAT 868 + #define TASK_SIZE_32 (_AC(0x80000000, UL)) 869 #define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \ 870 TASK_SIZE_32 : TASK_SIZE_64) 871 #else
+41 -2
arch/riscv/include/asm/processor.h
··· 16 17 #ifdef CONFIG_64BIT 18 #define DEFAULT_MAP_WINDOW (UL(1) << (MMAP_VA_BITS - 1)) 19 - #define STACK_TOP_MAX TASK_SIZE_64 20 21 #define arch_get_mmap_end(addr, len, flags) \ 22 ({ \ ··· 73 struct task_struct; 74 struct pt_regs; 75 76 /* CPU-specific state of a task */ 77 struct thread_struct { 78 /* Callee-saved registers */ ··· 118 unsigned long s[12]; /* s[0]: frame pointer */ 119 struct __riscv_d_ext_state fstate; 120 unsigned long bad_cause; 121 - unsigned long vstate_ctrl; 122 struct __riscv_v_ext_state vstate; 123 unsigned long align_ctl; 124 }; 125 126 /* Whitelist the fstate from the task_struct for hardened usercopy */
··· 16 17 #ifdef CONFIG_64BIT 18 #define DEFAULT_MAP_WINDOW (UL(1) << (MMAP_VA_BITS - 1)) 19 + #define STACK_TOP_MAX TASK_SIZE 20 21 #define arch_get_mmap_end(addr, len, flags) \ 22 ({ \ ··· 73 struct task_struct; 74 struct pt_regs; 75 76 + /* 77 + * We use a flag to track in-kernel Vector context. Currently the flag has the 78 + * following meaning: 79 + * 80 + * - bit 0: indicates whether the in-kernel Vector context is active. The 81 + * activation of this state disables the preemption. On a non-RT kernel, it 82 + * also disable bh. 83 + * - bits 8: is used for tracking preemptible kernel-mode Vector, when 84 + * RISCV_ISA_V_PREEMPTIVE is enabled. Calling kernel_vector_begin() does not 85 + * disable the preemption if the thread's kernel_vstate.datap is allocated. 86 + * Instead, the kernel set this bit field. Then the trap entry/exit code 87 + * knows if we are entering/exiting the context that owns preempt_v. 88 + * - 0: the task is not using preempt_v 89 + * - 1: the task is actively using preempt_v. But whether does the task own 90 + * the preempt_v context is decided by bits in RISCV_V_CTX_DEPTH_MASK. 91 + * - bit 16-23 are RISCV_V_CTX_DEPTH_MASK, used by context tracking routine 92 + * when preempt_v starts: 93 + * - 0: the task is actively using, and own preempt_v context. 94 + * - non-zero: the task was using preempt_v, but then took a trap within. 95 + * Thus, the task does not own preempt_v. Any use of Vector will have to 96 + * save preempt_v, if dirty, and fallback to non-preemptible kernel-mode 97 + * Vector. 98 + * - bit 30: The in-kernel preempt_v context is saved, and requries to be 99 + * restored when returning to the context that owns the preempt_v. 100 + * - bit 31: The in-kernel preempt_v context is dirty, as signaled by the 101 + * trap entry code. Any context switches out-of current task need to save 102 + * it to the task's in-kernel V context. Also, any traps nesting on-top-of 103 + * preempt_v requesting to use V needs a save. 104 + */ 105 + #define RISCV_V_CTX_DEPTH_MASK 0x00ff0000 106 + 107 + #define RISCV_V_CTX_UNIT_DEPTH 0x00010000 108 + #define RISCV_KERNEL_MODE_V 0x00000001 109 + #define RISCV_PREEMPT_V 0x00000100 110 + #define RISCV_PREEMPT_V_DIRTY 0x80000000 111 + #define RISCV_PREEMPT_V_NEED_RESTORE 0x40000000 112 + 113 /* CPU-specific state of a task */ 114 struct thread_struct { 115 /* Callee-saved registers */ ··· 81 unsigned long s[12]; /* s[0]: frame pointer */ 82 struct __riscv_d_ext_state fstate; 83 unsigned long bad_cause; 84 + u32 riscv_v_flags; 85 + u32 vstate_ctrl; 86 struct __riscv_v_ext_state vstate; 87 unsigned long align_ctl; 88 + struct __riscv_v_ext_state kernel_vstate; 89 }; 90 91 /* Whitelist the fstate from the task_struct for hardened usercopy */
+19
arch/riscv/include/asm/sbi.h
··· 29 SBI_EXT_RFENCE = 0x52464E43, 30 SBI_EXT_HSM = 0x48534D, 31 SBI_EXT_SRST = 0x53525354, 32 SBI_EXT_PMU = 0x504D55, 33 SBI_EXT_DBCN = 0x4442434E, 34 SBI_EXT_STA = 0x535441, ··· 114 enum sbi_srst_reset_reason { 115 SBI_SRST_RESET_REASON_NONE = 0, 116 SBI_SRST_RESET_REASON_SYS_FAILURE, 117 }; 118 119 enum sbi_ext_pmu_fid { ··· 297 unsigned long arg3, unsigned long arg4, 298 unsigned long arg5); 299 300 void sbi_console_putchar(int ch); 301 int sbi_console_getchar(void); 302 long sbi_get_mvendorid(void); 303 long sbi_get_marchid(void); 304 long sbi_get_mimpid(void); ··· 360 } 361 362 int sbi_err_map_linux_errno(int err); 363 #else /* CONFIG_RISCV_SBI */ 364 static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1; } 365 static inline void sbi_init(void) {}
··· 29 SBI_EXT_RFENCE = 0x52464E43, 30 SBI_EXT_HSM = 0x48534D, 31 SBI_EXT_SRST = 0x53525354, 32 + SBI_EXT_SUSP = 0x53555350, 33 SBI_EXT_PMU = 0x504D55, 34 SBI_EXT_DBCN = 0x4442434E, 35 SBI_EXT_STA = 0x535441, ··· 113 enum sbi_srst_reset_reason { 114 SBI_SRST_RESET_REASON_NONE = 0, 115 SBI_SRST_RESET_REASON_SYS_FAILURE, 116 + }; 117 + 118 + enum sbi_ext_susp_fid { 119 + SBI_EXT_SUSP_SYSTEM_SUSPEND = 0, 120 + }; 121 + 122 + enum sbi_ext_susp_sleep_type { 123 + SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM = 0, 124 }; 125 126 enum sbi_ext_pmu_fid { ··· 288 unsigned long arg3, unsigned long arg4, 289 unsigned long arg5); 290 291 + #ifdef CONFIG_RISCV_SBI_V01 292 void sbi_console_putchar(int ch); 293 int sbi_console_getchar(void); 294 + #else 295 + static inline void sbi_console_putchar(int ch) { } 296 + static inline int sbi_console_getchar(void) { return -ENOENT; } 297 + #endif 298 long sbi_get_mvendorid(void); 299 long sbi_get_marchid(void); 300 long sbi_get_mimpid(void); ··· 346 } 347 348 int sbi_err_map_linux_errno(int err); 349 + 350 + extern bool sbi_debug_console_available; 351 + int sbi_debug_console_write(const char *bytes, unsigned int num_bytes); 352 + int sbi_debug_console_read(char *bytes, unsigned int num_bytes); 353 + 354 #else /* CONFIG_RISCV_SBI */ 355 static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1; } 356 static inline void sbi_init(void) {}
+64
arch/riscv/include/asm/simd.h
···
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org> 4 + * Copyright (C) 2023 SiFive 5 + */ 6 + 7 + #ifndef __ASM_SIMD_H 8 + #define __ASM_SIMD_H 9 + 10 + #include <linux/compiler.h> 11 + #include <linux/irqflags.h> 12 + #include <linux/percpu.h> 13 + #include <linux/preempt.h> 14 + #include <linux/types.h> 15 + #include <linux/thread_info.h> 16 + 17 + #include <asm/vector.h> 18 + 19 + #ifdef CONFIG_RISCV_ISA_V 20 + /* 21 + * may_use_simd - whether it is allowable at this time to issue vector 22 + * instructions or access the vector register file 23 + * 24 + * Callers must not assume that the result remains true beyond the next 25 + * preempt_enable() or return from softirq context. 26 + */ 27 + static __must_check inline bool may_use_simd(void) 28 + { 29 + /* 30 + * RISCV_KERNEL_MODE_V is only set while preemption is disabled, 31 + * and is clear whenever preemption is enabled. 32 + */ 33 + if (in_hardirq() || in_nmi()) 34 + return false; 35 + 36 + /* 37 + * Nesting is acheived in preempt_v by spreading the control for 38 + * preemptible and non-preemptible kernel-mode Vector into two fields. 39 + * Always try to match with prempt_v if kernel V-context exists. Then, 40 + * fallback to check non preempt_v if nesting happens, or if the config 41 + * is not set. 42 + */ 43 + if (IS_ENABLED(CONFIG_RISCV_ISA_V_PREEMPTIVE) && current->thread.kernel_vstate.datap) { 44 + if (!riscv_preempt_v_started(current)) 45 + return true; 46 + } 47 + /* 48 + * Non-preemptible kernel-mode Vector temporarily disables bh. So we 49 + * must not return true on irq_disabled(). Otherwise we would fail the 50 + * lockdep check calling local_bh_enable() 51 + */ 52 + return !irqs_disabled() && !(riscv_v_flags() & RISCV_KERNEL_MODE_V); 53 + } 54 + 55 + #else /* ! CONFIG_RISCV_ISA_V */ 56 + 57 + static __must_check inline bool may_use_simd(void) 58 + { 59 + return false; 60 + } 61 + 62 + #endif /* ! CONFIG_RISCV_ISA_V */ 63 + 64 + #endif
+1 -2
arch/riscv/include/asm/switch_to.h
··· 53 struct pt_regs *regs; 54 55 regs = task_pt_regs(prev); 56 - if (unlikely(regs->status & SR_SD)) 57 - fstate_save(prev, regs); 58 fstate_restore(next, task_pt_regs(next)); 59 } 60
··· 53 struct pt_regs *regs; 54 55 regs = task_pt_regs(prev); 56 + fstate_save(prev, regs); 57 fstate_restore(next, task_pt_regs(next)); 58 } 59
+2
arch/riscv/include/asm/thread_info.h
··· 102 #define TIF_NOTIFY_SIGNAL 9 /* signal notifications exist */ 103 #define TIF_UPROBE 10 /* uprobe breakpoint or singlestep */ 104 #define TIF_32BIT 11 /* compat-mode 32bit process */ 105 106 #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) 107 #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 108 #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 109 #define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) 110 #define _TIF_UPROBE (1 << TIF_UPROBE) 111 112 #define _TIF_WORK_MASK \ 113 (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NEED_RESCHED | \
··· 102 #define TIF_NOTIFY_SIGNAL 9 /* signal notifications exist */ 103 #define TIF_UPROBE 10 /* uprobe breakpoint or singlestep */ 104 #define TIF_32BIT 11 /* compat-mode 32bit process */ 105 + #define TIF_RISCV_V_DEFER_RESTORE 12 /* restore Vector before returing to user */ 106 107 #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) 108 #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 109 #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 110 #define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) 111 #define _TIF_UPROBE (1 << TIF_UPROBE) 112 + #define _TIF_RISCV_V_DEFER_RESTORE (1 << TIF_RISCV_V_DEFER_RESTORE) 113 114 #define _TIF_WORK_MASK \ 115 (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+15
arch/riscv/include/asm/tlbbatch.h
···
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (C) 2023 Rivos Inc. 4 + */ 5 + 6 + #ifndef _ASM_RISCV_TLBBATCH_H 7 + #define _ASM_RISCV_TLBBATCH_H 8 + 9 + #include <linux/cpumask.h> 10 + 11 + struct arch_tlbflush_unmap_batch { 12 + struct cpumask cpumask; 13 + }; 14 + 15 + #endif /* _ASM_RISCV_TLBBATCH_H */
+8
arch/riscv/include/asm/tlbflush.h
··· 47 void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, 48 unsigned long end); 49 #endif 50 #else /* CONFIG_SMP && CONFIG_MMU */ 51 52 #define flush_tlb_all() local_flush_tlb_all()
··· 47 void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, 48 unsigned long end); 49 #endif 50 + 51 + bool arch_tlbbatch_should_defer(struct mm_struct *mm); 52 + void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *batch, 53 + struct mm_struct *mm, 54 + unsigned long uaddr); 55 + void arch_flush_tlb_batched_pending(struct mm_struct *mm); 56 + void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch); 57 + 58 #else /* CONFIG_SMP && CONFIG_MMU */ 59 60 #define flush_tlb_all() local_flush_tlb_all()
+79 -11
arch/riscv/include/asm/vector.h
··· 22 extern unsigned long riscv_v_vsize; 23 int riscv_v_setup_vsize(void); 24 bool riscv_v_first_use_handler(struct pt_regs *regs); 25 26 static __always_inline bool has_vector(void) 27 { ··· 174 __riscv_v_vstate_dirty(regs); 175 } 176 177 - static inline void riscv_v_vstate_save(struct task_struct *task, 178 struct pt_regs *regs) 179 { 180 if ((regs->status & SR_VS) == SR_VS_DIRTY) { 181 - struct __riscv_v_ext_state *vstate = &task->thread.vstate; 182 - 183 __riscv_v_vstate_save(vstate, vstate->datap); 184 __riscv_v_vstate_clean(regs); 185 } 186 } 187 188 - static inline void riscv_v_vstate_restore(struct task_struct *task, 189 struct pt_regs *regs) 190 { 191 if ((regs->status & SR_VS) != SR_VS_OFF) { 192 - struct __riscv_v_ext_state *vstate = &task->thread.vstate; 193 - 194 __riscv_v_vstate_restore(vstate, vstate->datap); 195 __riscv_v_vstate_clean(regs); 196 } 197 } 198 199 static inline void __switch_to_vector(struct task_struct *prev, 200 struct task_struct *next) 201 { 202 struct pt_regs *regs; 203 204 - regs = task_pt_regs(prev); 205 - riscv_v_vstate_save(prev, regs); 206 - riscv_v_vstate_restore(next, task_pt_regs(next)); 207 } 208 209 void riscv_v_vstate_ctrl_init(struct task_struct *tsk); ··· 273 static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; } 274 #define riscv_v_vsize (0) 275 #define riscv_v_vstate_discard(regs) do {} while (0) 276 - #define riscv_v_vstate_save(task, regs) do {} while (0) 277 - #define riscv_v_vstate_restore(task, regs) do {} while (0) 278 #define __switch_to_vector(__prev, __next) do {} while (0) 279 #define riscv_v_vstate_off(regs) do {} while (0) 280 #define riscv_v_vstate_on(regs) do {} while (0) 281 282 #endif /* CONFIG_RISCV_ISA_V */ 283
··· 22 extern unsigned long riscv_v_vsize; 23 int riscv_v_setup_vsize(void); 24 bool riscv_v_first_use_handler(struct pt_regs *regs); 25 + void kernel_vector_begin(void); 26 + void kernel_vector_end(void); 27 + void get_cpu_vector_context(void); 28 + void put_cpu_vector_context(void); 29 + void riscv_v_thread_free(struct task_struct *tsk); 30 + void __init riscv_v_setup_ctx_cache(void); 31 + void riscv_v_thread_alloc(struct task_struct *tsk); 32 + 33 + static inline u32 riscv_v_flags(void) 34 + { 35 + return READ_ONCE(current->thread.riscv_v_flags); 36 + } 37 38 static __always_inline bool has_vector(void) 39 { ··· 162 __riscv_v_vstate_dirty(regs); 163 } 164 165 + static inline void riscv_v_vstate_save(struct __riscv_v_ext_state *vstate, 166 struct pt_regs *regs) 167 { 168 if ((regs->status & SR_VS) == SR_VS_DIRTY) { 169 __riscv_v_vstate_save(vstate, vstate->datap); 170 __riscv_v_vstate_clean(regs); 171 } 172 } 173 174 + static inline void riscv_v_vstate_restore(struct __riscv_v_ext_state *vstate, 175 struct pt_regs *regs) 176 { 177 if ((regs->status & SR_VS) != SR_VS_OFF) { 178 __riscv_v_vstate_restore(vstate, vstate->datap); 179 __riscv_v_vstate_clean(regs); 180 } 181 } 182 + 183 + static inline void riscv_v_vstate_set_restore(struct task_struct *task, 184 + struct pt_regs *regs) 185 + { 186 + if ((regs->status & SR_VS) != SR_VS_OFF) { 187 + set_tsk_thread_flag(task, TIF_RISCV_V_DEFER_RESTORE); 188 + riscv_v_vstate_on(regs); 189 + } 190 + } 191 + 192 + #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE 193 + static inline bool riscv_preempt_v_dirty(struct task_struct *task) 194 + { 195 + return !!(task->thread.riscv_v_flags & RISCV_PREEMPT_V_DIRTY); 196 + } 197 + 198 + static inline bool riscv_preempt_v_restore(struct task_struct *task) 199 + { 200 + return !!(task->thread.riscv_v_flags & RISCV_PREEMPT_V_NEED_RESTORE); 201 + } 202 + 203 + static inline void riscv_preempt_v_clear_dirty(struct task_struct *task) 204 + { 205 + barrier(); 206 + task->thread.riscv_v_flags &= ~RISCV_PREEMPT_V_DIRTY; 207 + } 208 + 209 + static inline void riscv_preempt_v_set_restore(struct task_struct *task) 210 + { 211 + barrier(); 212 + task->thread.riscv_v_flags |= RISCV_PREEMPT_V_NEED_RESTORE; 213 + } 214 + 215 + static inline bool riscv_preempt_v_started(struct task_struct *task) 216 + { 217 + return !!(task->thread.riscv_v_flags & RISCV_PREEMPT_V); 218 + } 219 + 220 + #else /* !CONFIG_RISCV_ISA_V_PREEMPTIVE */ 221 + static inline bool riscv_preempt_v_dirty(struct task_struct *task) { return false; } 222 + static inline bool riscv_preempt_v_restore(struct task_struct *task) { return false; } 223 + static inline bool riscv_preempt_v_started(struct task_struct *task) { return false; } 224 + #define riscv_preempt_v_clear_dirty(tsk) do {} while (0) 225 + #define riscv_preempt_v_set_restore(tsk) do {} while (0) 226 + #endif /* CONFIG_RISCV_ISA_V_PREEMPTIVE */ 227 228 static inline void __switch_to_vector(struct task_struct *prev, 229 struct task_struct *next) 230 { 231 struct pt_regs *regs; 232 233 + if (riscv_preempt_v_started(prev)) { 234 + if (riscv_preempt_v_dirty(prev)) { 235 + __riscv_v_vstate_save(&prev->thread.kernel_vstate, 236 + prev->thread.kernel_vstate.datap); 237 + riscv_preempt_v_clear_dirty(prev); 238 + } 239 + } else { 240 + regs = task_pt_regs(prev); 241 + riscv_v_vstate_save(&prev->thread.vstate, regs); 242 + } 243 + 244 + if (riscv_preempt_v_started(next)) 245 + riscv_preempt_v_set_restore(next); 246 + else 247 + riscv_v_vstate_set_restore(next, task_pt_regs(next)); 248 } 249 250 void riscv_v_vstate_ctrl_init(struct task_struct *tsk); ··· 208 static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; } 209 #define riscv_v_vsize (0) 210 #define riscv_v_vstate_discard(regs) do {} while (0) 211 + #define riscv_v_vstate_save(vstate, regs) do {} while (0) 212 + #define riscv_v_vstate_restore(vstate, regs) do {} while (0) 213 #define __switch_to_vector(__prev, __next) do {} while (0) 214 #define riscv_v_vstate_off(regs) do {} while (0) 215 #define riscv_v_vstate_on(regs) do {} while (0) 216 + #define riscv_v_thread_free(tsk) do {} while (0) 217 + #define riscv_v_setup_ctx_cache() do {} while (0) 218 + #define riscv_v_thread_alloc(tsk) do {} while (0) 219 220 #endif /* CONFIG_RISCV_ISA_V */ 221
+27
arch/riscv/include/asm/word-at-a-time.h
··· 9 #define _ASM_RISCV_WORD_AT_A_TIME_H 10 11 12 #include <linux/kernel.h> 13 14 struct word_at_a_time { ··· 45 46 /* The mask we created is directly usable as a bytemask */ 47 #define zero_bytemask(mask) (mask) 48 49 #endif /* _ASM_RISCV_WORD_AT_A_TIME_H */
··· 9 #define _ASM_RISCV_WORD_AT_A_TIME_H 10 11 12 + #include <asm/asm-extable.h> 13 #include <linux/kernel.h> 14 15 struct word_at_a_time { ··· 44 45 /* The mask we created is directly usable as a bytemask */ 46 #define zero_bytemask(mask) (mask) 47 + 48 + #ifdef CONFIG_DCACHE_WORD_ACCESS 49 + 50 + /* 51 + * Load an unaligned word from kernel space. 52 + * 53 + * In the (very unlikely) case of the word being a page-crosser 54 + * and the next page not being mapped, take the exception and 55 + * return zeroes in the non-existing part. 56 + */ 57 + static inline unsigned long load_unaligned_zeropad(const void *addr) 58 + { 59 + unsigned long ret; 60 + 61 + /* Load word from unaligned pointer addr */ 62 + asm( 63 + "1: " REG_L " %0, %2\n" 64 + "2:\n" 65 + _ASM_EXTABLE_LOAD_UNALIGNED_ZEROPAD(1b, 2b, %0, %1) 66 + : "=&r" (ret) 67 + : "r" (addr), "m" (*(unsigned long *)addr)); 68 + 69 + return ret; 70 + } 71 + 72 + #endif /* CONFIG_DCACHE_WORD_ACCESS */ 73 74 #endif /* _ASM_RISCV_WORD_AT_A_TIME_H */
+68
arch/riscv/include/asm/xor.h
···
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* 3 + * Copyright (C) 2021 SiFive 4 + */ 5 + 6 + #include <linux/hardirq.h> 7 + #include <asm-generic/xor.h> 8 + #ifdef CONFIG_RISCV_ISA_V 9 + #include <asm/vector.h> 10 + #include <asm/switch_to.h> 11 + #include <asm/asm-prototypes.h> 12 + 13 + static void xor_vector_2(unsigned long bytes, unsigned long *__restrict p1, 14 + const unsigned long *__restrict p2) 15 + { 16 + kernel_vector_begin(); 17 + xor_regs_2_(bytes, p1, p2); 18 + kernel_vector_end(); 19 + } 20 + 21 + static void xor_vector_3(unsigned long bytes, unsigned long *__restrict p1, 22 + const unsigned long *__restrict p2, 23 + const unsigned long *__restrict p3) 24 + { 25 + kernel_vector_begin(); 26 + xor_regs_3_(bytes, p1, p2, p3); 27 + kernel_vector_end(); 28 + } 29 + 30 + static void xor_vector_4(unsigned long bytes, unsigned long *__restrict p1, 31 + const unsigned long *__restrict p2, 32 + const unsigned long *__restrict p3, 33 + const unsigned long *__restrict p4) 34 + { 35 + kernel_vector_begin(); 36 + xor_regs_4_(bytes, p1, p2, p3, p4); 37 + kernel_vector_end(); 38 + } 39 + 40 + static void xor_vector_5(unsigned long bytes, unsigned long *__restrict p1, 41 + const unsigned long *__restrict p2, 42 + const unsigned long *__restrict p3, 43 + const unsigned long *__restrict p4, 44 + const unsigned long *__restrict p5) 45 + { 46 + kernel_vector_begin(); 47 + xor_regs_5_(bytes, p1, p2, p3, p4, p5); 48 + kernel_vector_end(); 49 + } 50 + 51 + static struct xor_block_template xor_block_rvv = { 52 + .name = "rvv", 53 + .do_2 = xor_vector_2, 54 + .do_3 = xor_vector_3, 55 + .do_4 = xor_vector_4, 56 + .do_5 = xor_vector_5 57 + }; 58 + 59 + #undef XOR_TRY_TEMPLATES 60 + #define XOR_TRY_TEMPLATES \ 61 + do { \ 62 + xor_speed(&xor_block_8regs); \ 63 + xor_speed(&xor_block_32regs); \ 64 + if (has_vector()) { \ 65 + xor_speed(&xor_block_rvv);\ 66 + } \ 67 + } while (0) 68 + #endif
+1
arch/riscv/kernel/Makefile
··· 64 obj-$(CONFIG_RISCV_MISALIGNED) += traps_misaligned.o 65 obj-$(CONFIG_FPU) += fpu.o 66 obj-$(CONFIG_RISCV_ISA_V) += vector.o 67 obj-$(CONFIG_SMP) += smpboot.o 68 obj-$(CONFIG_SMP) += smp.o 69 obj-$(CONFIG_SMP) += cpu_ops.o
··· 64 obj-$(CONFIG_RISCV_MISALIGNED) += traps_misaligned.o 65 obj-$(CONFIG_FPU) += fpu.o 66 obj-$(CONFIG_RISCV_ISA_V) += vector.o 67 + obj-$(CONFIG_RISCV_ISA_V) += kernel_mode_vector.o 68 obj-$(CONFIG_SMP) += smpboot.o 69 obj-$(CONFIG_SMP) += smp.o 70 obj-$(CONFIG_SMP) += cpu_ops.o
+87 -3
arch/riscv/kernel/cpufeature.c
··· 8 9 #include <linux/acpi.h> 10 #include <linux/bitmap.h> 11 #include <linux/cpuhotplug.h> 12 #include <linux/ctype.h> 13 #include <linux/log2.h> 14 #include <linux/memory.h> 15 #include <linux/module.h> ··· 45 46 /* Performance information */ 47 DEFINE_PER_CPU(long, misaligned_access_speed); 48 49 /** 50 * riscv_isa_extension_base() - Get base extension word ··· 788 (speed == RISCV_HWPROBE_MISALIGNED_FAST) ? "fast" : "slow"); 789 790 per_cpu(misaligned_access_speed, cpu) = speed; 791 return 0; 792 } 793 ··· 810 check_unaligned_access(pages[cpu]); 811 } 812 813 static int riscv_online_cpu(unsigned int cpu) 814 { 815 static struct page *buf; 816 817 /* We are already set since the last check */ 818 if (per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_UNKNOWN) 819 - return 0; 820 821 buf = alloc_pages(GFP_KERNEL, MISALIGNED_BUFFER_ORDER); 822 if (!buf) { ··· 882 883 check_unaligned_access(buf); 884 __free_pages(buf, MISALIGNED_BUFFER_ORDER); 885 return 0; 886 } 887 ··· 927 /* Check core 0. */ 928 smp_call_on_cpu(0, check_unaligned_access, bufs[0], true); 929 930 - /* Setup hotplug callback for any new CPUs that come online. */ 931 cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "riscv:online", 932 - riscv_online_cpu, NULL); 933 934 out: 935 unaligned_emulation_finish();
··· 8 9 #include <linux/acpi.h> 10 #include <linux/bitmap.h> 11 + #include <linux/cpu.h> 12 #include <linux/cpuhotplug.h> 13 #include <linux/ctype.h> 14 + #include <linux/jump_label.h> 15 #include <linux/log2.h> 16 #include <linux/memory.h> 17 #include <linux/module.h> ··· 43 44 /* Performance information */ 45 DEFINE_PER_CPU(long, misaligned_access_speed); 46 + 47 + static cpumask_t fast_misaligned_access; 48 49 /** 50 * riscv_isa_extension_base() - Get base extension word ··· 784 (speed == RISCV_HWPROBE_MISALIGNED_FAST) ? "fast" : "slow"); 785 786 per_cpu(misaligned_access_speed, cpu) = speed; 787 + 788 + /* 789 + * Set the value of fast_misaligned_access of a CPU. These operations 790 + * are atomic to avoid race conditions. 791 + */ 792 + if (speed == RISCV_HWPROBE_MISALIGNED_FAST) 793 + cpumask_set_cpu(cpu, &fast_misaligned_access); 794 + else 795 + cpumask_clear_cpu(cpu, &fast_misaligned_access); 796 + 797 return 0; 798 } 799 ··· 796 check_unaligned_access(pages[cpu]); 797 } 798 799 + DEFINE_STATIC_KEY_FALSE(fast_misaligned_access_speed_key); 800 + 801 + static void modify_unaligned_access_branches(cpumask_t *mask, int weight) 802 + { 803 + if (cpumask_weight(mask) == weight) 804 + static_branch_enable_cpuslocked(&fast_misaligned_access_speed_key); 805 + else 806 + static_branch_disable_cpuslocked(&fast_misaligned_access_speed_key); 807 + } 808 + 809 + static void set_unaligned_access_static_branches_except_cpu(int cpu) 810 + { 811 + /* 812 + * Same as set_unaligned_access_static_branches, except excludes the 813 + * given CPU from the result. When a CPU is hotplugged into an offline 814 + * state, this function is called before the CPU is set to offline in 815 + * the cpumask, and thus the CPU needs to be explicitly excluded. 816 + */ 817 + 818 + cpumask_t fast_except_me; 819 + 820 + cpumask_and(&fast_except_me, &fast_misaligned_access, cpu_online_mask); 821 + cpumask_clear_cpu(cpu, &fast_except_me); 822 + 823 + modify_unaligned_access_branches(&fast_except_me, num_online_cpus() - 1); 824 + } 825 + 826 + static void set_unaligned_access_static_branches(void) 827 + { 828 + /* 829 + * This will be called after check_unaligned_access_all_cpus so the 830 + * result of unaligned access speed for all CPUs will be available. 831 + * 832 + * To avoid the number of online cpus changing between reading 833 + * cpu_online_mask and calling num_online_cpus, cpus_read_lock must be 834 + * held before calling this function. 835 + */ 836 + 837 + cpumask_t fast_and_online; 838 + 839 + cpumask_and(&fast_and_online, &fast_misaligned_access, cpu_online_mask); 840 + 841 + modify_unaligned_access_branches(&fast_and_online, num_online_cpus()); 842 + } 843 + 844 + static int lock_and_set_unaligned_access_static_branch(void) 845 + { 846 + cpus_read_lock(); 847 + set_unaligned_access_static_branches(); 848 + cpus_read_unlock(); 849 + 850 + return 0; 851 + } 852 + 853 + arch_initcall_sync(lock_and_set_unaligned_access_static_branch); 854 + 855 static int riscv_online_cpu(unsigned int cpu) 856 { 857 static struct page *buf; 858 859 /* We are already set since the last check */ 860 if (per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_UNKNOWN) 861 + goto exit; 862 863 buf = alloc_pages(GFP_KERNEL, MISALIGNED_BUFFER_ORDER); 864 if (!buf) { ··· 812 813 check_unaligned_access(buf); 814 __free_pages(buf, MISALIGNED_BUFFER_ORDER); 815 + 816 + exit: 817 + set_unaligned_access_static_branches(); 818 + 819 + return 0; 820 + } 821 + 822 + static int riscv_offline_cpu(unsigned int cpu) 823 + { 824 + set_unaligned_access_static_branches_except_cpu(cpu); 825 + 826 return 0; 827 } 828 ··· 846 /* Check core 0. */ 847 smp_call_on_cpu(0, check_unaligned_access, bufs[0], true); 848 849 + /* 850 + * Setup hotplug callbacks for any new CPUs that come online or go 851 + * offline. 852 + */ 853 cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "riscv:online", 854 + riscv_online_cpu, riscv_offline_cpu); 855 856 out: 857 unaligned_emulation_finish();
+8
arch/riscv/kernel/entry.S
··· 83 /* Load the kernel shadow call stack pointer if coming from userspace */ 84 scs_load_current_if_task_changed s5 85 86 move a0, sp /* pt_regs */ 87 la ra, ret_from_exception 88 ··· 142 */ 143 csrw CSR_SCRATCH, tp 144 1: 145 REG_L a0, PT_STATUS(sp) 146 /* 147 * The current load reservation is effectively part of the processor's
··· 83 /* Load the kernel shadow call stack pointer if coming from userspace */ 84 scs_load_current_if_task_changed s5 85 86 + #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE 87 + move a0, sp 88 + call riscv_v_context_nesting_start 89 + #endif 90 move a0, sp /* pt_regs */ 91 la ra, ret_from_exception 92 ··· 138 */ 139 csrw CSR_SCRATCH, tp 140 1: 141 + #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE 142 + move a0, sp 143 + call riscv_v_context_nesting_end 144 + #endif 145 REG_L a0, PT_STATUS(sp) 146 /* 147 * The current load reservation is effectively part of the processor's
+13 -17
arch/riscv/kernel/ftrace.c
··· 178 } 179 180 #ifdef CONFIG_DYNAMIC_FTRACE 181 extern void ftrace_graph_call(void); 182 - extern void ftrace_graph_regs_call(void); 183 int ftrace_enable_ftrace_graph_caller(void) 184 { 185 - int ret; 186 - 187 - ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, 188 - (unsigned long)&prepare_ftrace_return, true, true); 189 - if (ret) 190 - return ret; 191 - 192 - return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, 193 (unsigned long)&prepare_ftrace_return, true, true); 194 } 195 196 int ftrace_disable_ftrace_graph_caller(void) 197 { 198 - int ret; 199 - 200 - ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, 201 - (unsigned long)&prepare_ftrace_return, false, true); 202 - if (ret) 203 - return ret; 204 - 205 - return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, 206 (unsigned long)&prepare_ftrace_return, false, true); 207 } 208 #endif /* CONFIG_DYNAMIC_FTRACE */ 209 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
··· 178 } 179 180 #ifdef CONFIG_DYNAMIC_FTRACE 181 + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 182 + void ftrace_graph_func(unsigned long ip, unsigned long parent_ip, 183 + struct ftrace_ops *op, struct ftrace_regs *fregs) 184 + { 185 + struct pt_regs *regs = arch_ftrace_get_regs(fregs); 186 + unsigned long *parent = (unsigned long *)&regs->ra; 187 + 188 + prepare_ftrace_return(parent, ip, frame_pointer(regs)); 189 + } 190 + #else /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ 191 extern void ftrace_graph_call(void); 192 int ftrace_enable_ftrace_graph_caller(void) 193 { 194 + return __ftrace_modify_call((unsigned long)&ftrace_graph_call, 195 (unsigned long)&prepare_ftrace_return, true, true); 196 } 197 198 int ftrace_disable_ftrace_graph_caller(void) 199 { 200 + return __ftrace_modify_call((unsigned long)&ftrace_graph_call, 201 (unsigned long)&prepare_ftrace_return, false, true); 202 } 203 + #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ 204 #endif /* CONFIG_DYNAMIC_FTRACE */ 205 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+247
arch/riscv/kernel/kernel_mode_vector.c
···
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (C) 2012 ARM Ltd. 4 + * Author: Catalin Marinas <catalin.marinas@arm.com> 5 + * Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org> 6 + * Copyright (C) 2021 SiFive 7 + */ 8 + #include <linux/compiler.h> 9 + #include <linux/irqflags.h> 10 + #include <linux/percpu.h> 11 + #include <linux/preempt.h> 12 + #include <linux/types.h> 13 + 14 + #include <asm/vector.h> 15 + #include <asm/switch_to.h> 16 + #include <asm/simd.h> 17 + #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE 18 + #include <asm/asm-prototypes.h> 19 + #endif 20 + 21 + static inline void riscv_v_flags_set(u32 flags) 22 + { 23 + WRITE_ONCE(current->thread.riscv_v_flags, flags); 24 + } 25 + 26 + static inline void riscv_v_start(u32 flags) 27 + { 28 + int orig; 29 + 30 + orig = riscv_v_flags(); 31 + BUG_ON((orig & flags) != 0); 32 + riscv_v_flags_set(orig | flags); 33 + barrier(); 34 + } 35 + 36 + static inline void riscv_v_stop(u32 flags) 37 + { 38 + int orig; 39 + 40 + barrier(); 41 + orig = riscv_v_flags(); 42 + BUG_ON((orig & flags) == 0); 43 + riscv_v_flags_set(orig & ~flags); 44 + } 45 + 46 + /* 47 + * Claim ownership of the CPU vector context for use by the calling context. 48 + * 49 + * The caller may freely manipulate the vector context metadata until 50 + * put_cpu_vector_context() is called. 51 + */ 52 + void get_cpu_vector_context(void) 53 + { 54 + /* 55 + * disable softirqs so it is impossible for softirqs to nest 56 + * get_cpu_vector_context() when kernel is actively using Vector. 57 + */ 58 + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) 59 + local_bh_disable(); 60 + else 61 + preempt_disable(); 62 + 63 + riscv_v_start(RISCV_KERNEL_MODE_V); 64 + } 65 + 66 + /* 67 + * Release the CPU vector context. 68 + * 69 + * Must be called from a context in which get_cpu_vector_context() was 70 + * previously called, with no call to put_cpu_vector_context() in the 71 + * meantime. 72 + */ 73 + void put_cpu_vector_context(void) 74 + { 75 + riscv_v_stop(RISCV_KERNEL_MODE_V); 76 + 77 + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) 78 + local_bh_enable(); 79 + else 80 + preempt_enable(); 81 + } 82 + 83 + #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE 84 + static __always_inline u32 *riscv_v_flags_ptr(void) 85 + { 86 + return &current->thread.riscv_v_flags; 87 + } 88 + 89 + static inline void riscv_preempt_v_set_dirty(void) 90 + { 91 + *riscv_v_flags_ptr() |= RISCV_PREEMPT_V_DIRTY; 92 + } 93 + 94 + static inline void riscv_preempt_v_reset_flags(void) 95 + { 96 + *riscv_v_flags_ptr() &= ~(RISCV_PREEMPT_V_DIRTY | RISCV_PREEMPT_V_NEED_RESTORE); 97 + } 98 + 99 + static inline void riscv_v_ctx_depth_inc(void) 100 + { 101 + *riscv_v_flags_ptr() += RISCV_V_CTX_UNIT_DEPTH; 102 + } 103 + 104 + static inline void riscv_v_ctx_depth_dec(void) 105 + { 106 + *riscv_v_flags_ptr() -= RISCV_V_CTX_UNIT_DEPTH; 107 + } 108 + 109 + static inline u32 riscv_v_ctx_get_depth(void) 110 + { 111 + return *riscv_v_flags_ptr() & RISCV_V_CTX_DEPTH_MASK; 112 + } 113 + 114 + static int riscv_v_stop_kernel_context(void) 115 + { 116 + if (riscv_v_ctx_get_depth() != 0 || !riscv_preempt_v_started(current)) 117 + return 1; 118 + 119 + riscv_preempt_v_clear_dirty(current); 120 + riscv_v_stop(RISCV_PREEMPT_V); 121 + return 0; 122 + } 123 + 124 + static int riscv_v_start_kernel_context(bool *is_nested) 125 + { 126 + struct __riscv_v_ext_state *kvstate, *uvstate; 127 + 128 + kvstate = &current->thread.kernel_vstate; 129 + if (!kvstate->datap) 130 + return -ENOENT; 131 + 132 + if (riscv_preempt_v_started(current)) { 133 + WARN_ON(riscv_v_ctx_get_depth() == 0); 134 + *is_nested = true; 135 + get_cpu_vector_context(); 136 + if (riscv_preempt_v_dirty(current)) { 137 + __riscv_v_vstate_save(kvstate, kvstate->datap); 138 + riscv_preempt_v_clear_dirty(current); 139 + } 140 + riscv_preempt_v_set_restore(current); 141 + return 0; 142 + } 143 + 144 + /* Transfer the ownership of V from user to kernel, then save */ 145 + riscv_v_start(RISCV_PREEMPT_V | RISCV_PREEMPT_V_DIRTY); 146 + if ((task_pt_regs(current)->status & SR_VS) == SR_VS_DIRTY) { 147 + uvstate = &current->thread.vstate; 148 + __riscv_v_vstate_save(uvstate, uvstate->datap); 149 + } 150 + riscv_preempt_v_clear_dirty(current); 151 + return 0; 152 + } 153 + 154 + /* low-level V context handling code, called with irq disabled */ 155 + asmlinkage void riscv_v_context_nesting_start(struct pt_regs *regs) 156 + { 157 + int depth; 158 + 159 + if (!riscv_preempt_v_started(current)) 160 + return; 161 + 162 + depth = riscv_v_ctx_get_depth(); 163 + if (depth == 0 && (regs->status & SR_VS) == SR_VS_DIRTY) 164 + riscv_preempt_v_set_dirty(); 165 + 166 + riscv_v_ctx_depth_inc(); 167 + } 168 + 169 + asmlinkage void riscv_v_context_nesting_end(struct pt_regs *regs) 170 + { 171 + struct __riscv_v_ext_state *vstate = &current->thread.kernel_vstate; 172 + u32 depth; 173 + 174 + WARN_ON(!irqs_disabled()); 175 + 176 + if (!riscv_preempt_v_started(current)) 177 + return; 178 + 179 + riscv_v_ctx_depth_dec(); 180 + depth = riscv_v_ctx_get_depth(); 181 + if (depth == 0) { 182 + if (riscv_preempt_v_restore(current)) { 183 + __riscv_v_vstate_restore(vstate, vstate->datap); 184 + __riscv_v_vstate_clean(regs); 185 + riscv_preempt_v_reset_flags(); 186 + } 187 + } 188 + } 189 + #else 190 + #define riscv_v_start_kernel_context(nested) (-ENOENT) 191 + #define riscv_v_stop_kernel_context() (-ENOENT) 192 + #endif /* CONFIG_RISCV_ISA_V_PREEMPTIVE */ 193 + 194 + /* 195 + * kernel_vector_begin(): obtain the CPU vector registers for use by the calling 196 + * context 197 + * 198 + * Must not be called unless may_use_simd() returns true. 199 + * Task context in the vector registers is saved back to memory as necessary. 200 + * 201 + * A matching call to kernel_vector_end() must be made before returning from the 202 + * calling context. 203 + * 204 + * The caller may freely use the vector registers until kernel_vector_end() is 205 + * called. 206 + */ 207 + void kernel_vector_begin(void) 208 + { 209 + bool nested = false; 210 + 211 + if (WARN_ON(!has_vector())) 212 + return; 213 + 214 + BUG_ON(!may_use_simd()); 215 + 216 + if (riscv_v_start_kernel_context(&nested)) { 217 + get_cpu_vector_context(); 218 + riscv_v_vstate_save(&current->thread.vstate, task_pt_regs(current)); 219 + } 220 + 221 + if (!nested) 222 + riscv_v_vstate_set_restore(current, task_pt_regs(current)); 223 + 224 + riscv_v_enable(); 225 + } 226 + EXPORT_SYMBOL_GPL(kernel_vector_begin); 227 + 228 + /* 229 + * kernel_vector_end(): give the CPU vector registers back to the current task 230 + * 231 + * Must be called from a context in which kernel_vector_begin() was previously 232 + * called, with no call to kernel_vector_end() in the meantime. 233 + * 234 + * The caller must not use the vector registers after this function is called, 235 + * unless kernel_vector_begin() is called again in the meantime. 236 + */ 237 + void kernel_vector_end(void) 238 + { 239 + if (WARN_ON(!has_vector())) 240 + return; 241 + 242 + riscv_v_disable(); 243 + 244 + if (riscv_v_stop_kernel_context()) 245 + put_cpu_vector_context(); 246 + } 247 + EXPORT_SYMBOL_GPL(kernel_vector_end);
+162 -38
arch/riscv/kernel/mcount-dyn.S
··· 57 .endm 58 59 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 60 - .macro SAVE_ALL 61 addi sp, sp, -PT_SIZE_ON_STACK 62 63 - REG_S t0, PT_EPC(sp) 64 - REG_S x1, PT_RA(sp) 65 - REG_S x2, PT_SP(sp) 66 - REG_S x3, PT_GP(sp) 67 - REG_S x4, PT_TP(sp) 68 - REG_S x5, PT_T0(sp) 69 - save_from_x6_to_x31 70 .endm 71 72 - .macro RESTORE_ALL 73 - REG_L x1, PT_RA(sp) 74 - REG_L x2, PT_SP(sp) 75 - REG_L x3, PT_GP(sp) 76 - REG_L x4, PT_TP(sp) 77 - /* Restore t0 with PT_EPC */ 78 - REG_L x5, PT_EPC(sp) 79 - restore_from_x6_to_x31 80 81 addi sp, sp, PT_SIZE_ON_STACK 82 .endm 83 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ 84 85 SYM_FUNC_START(ftrace_caller) 86 SAVE_ABI 87 ··· 224 call ftrace_stub 225 #endif 226 RESTORE_ABI 227 - jr t0 228 SYM_FUNC_END(ftrace_caller) 229 230 - #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 231 SYM_FUNC_START(ftrace_regs_caller) 232 - SAVE_ALL 233 - 234 - addi a0, t0, -FENTRY_RA_OFFSET 235 - la a1, function_trace_op 236 - REG_L a2, 0(a1) 237 - mv a1, ra 238 - mv a3, sp 239 240 SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL) 241 call ftrace_stub 242 243 - #ifdef CONFIG_FUNCTION_GRAPH_TRACER 244 - addi a0, sp, PT_RA 245 - REG_L a1, PT_EPC(sp) 246 - addi a1, a1, -FENTRY_RA_OFFSET 247 - #ifdef HAVE_FUNCTION_GRAPH_FP_TEST 248 - mv a2, s0 249 - #endif 250 - SYM_INNER_LABEL(ftrace_graph_regs_call, SYM_L_GLOBAL) 251 - call ftrace_stub 252 - #endif 253 - 254 - RESTORE_ALL 255 - jr t0 256 SYM_FUNC_END(ftrace_regs_caller) 257 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
··· 57 .endm 58 59 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 60 + 61 + /** 62 + * SAVE_ABI_REGS - save regs against the pt_regs struct 63 + * 64 + * @all: tell if saving all the regs 65 + * 66 + * If all is set, all the regs will be saved, otherwise only ABI 67 + * related regs (a0-a7,epc,ra and optional s0) will be saved. 68 + * 69 + * After the stack is established, 70 + * 71 + * 0(sp) stores the PC of the traced function which can be accessed 72 + * by &(fregs)->regs->epc in tracing function. Note that the real 73 + * function entry address should be computed with -FENTRY_RA_OFFSET. 74 + * 75 + * 8(sp) stores the function return address (i.e. parent IP) that 76 + * can be accessed by &(fregs)->regs->ra in tracing function. 77 + * 78 + * The other regs are saved at the respective localtion and accessed 79 + * by the respective pt_regs member. 80 + * 81 + * Here is the layout of stack for your reference. 82 + * 83 + * PT_SIZE_ON_STACK -> +++++++++ 84 + * + ..... + 85 + * + t3-t6 + 86 + * + s2-s11+ 87 + * + a0-a7 + --++++-> ftrace_caller saved 88 + * + s1 + + 89 + * + s0 + --+ 90 + * + t0-t2 + + 91 + * + tp + + 92 + * + gp + + 93 + * + sp + + 94 + * + ra + --+ // parent IP 95 + * sp -> + epc + --+ // PC 96 + * +++++++++ 97 + **/ 98 + .macro SAVE_ABI_REGS, all=0 99 addi sp, sp, -PT_SIZE_ON_STACK 100 101 + REG_S t0, PT_EPC(sp) 102 + REG_S x1, PT_RA(sp) 103 + 104 + // save the ABI regs 105 + 106 + REG_S x10, PT_A0(sp) 107 + REG_S x11, PT_A1(sp) 108 + REG_S x12, PT_A2(sp) 109 + REG_S x13, PT_A3(sp) 110 + REG_S x14, PT_A4(sp) 111 + REG_S x15, PT_A5(sp) 112 + REG_S x16, PT_A6(sp) 113 + REG_S x17, PT_A7(sp) 114 + 115 + // save the leftover regs 116 + 117 + .if \all == 1 118 + REG_S x2, PT_SP(sp) 119 + REG_S x3, PT_GP(sp) 120 + REG_S x4, PT_TP(sp) 121 + REG_S x5, PT_T0(sp) 122 + REG_S x6, PT_T1(sp) 123 + REG_S x7, PT_T2(sp) 124 + REG_S x8, PT_S0(sp) 125 + REG_S x9, PT_S1(sp) 126 + REG_S x18, PT_S2(sp) 127 + REG_S x19, PT_S3(sp) 128 + REG_S x20, PT_S4(sp) 129 + REG_S x21, PT_S5(sp) 130 + REG_S x22, PT_S6(sp) 131 + REG_S x23, PT_S7(sp) 132 + REG_S x24, PT_S8(sp) 133 + REG_S x25, PT_S9(sp) 134 + REG_S x26, PT_S10(sp) 135 + REG_S x27, PT_S11(sp) 136 + REG_S x28, PT_T3(sp) 137 + REG_S x29, PT_T4(sp) 138 + REG_S x30, PT_T5(sp) 139 + REG_S x31, PT_T6(sp) 140 + 141 + // save s0 if FP_TEST defined 142 + 143 + .else 144 + #ifdef HAVE_FUNCTION_GRAPH_FP_TEST 145 + REG_S x8, PT_S0(sp) 146 + #endif 147 + .endif 148 .endm 149 150 + .macro RESTORE_ABI_REGS, all=0 151 + REG_L t0, PT_EPC(sp) 152 + REG_L x1, PT_RA(sp) 153 + REG_L x10, PT_A0(sp) 154 + REG_L x11, PT_A1(sp) 155 + REG_L x12, PT_A2(sp) 156 + REG_L x13, PT_A3(sp) 157 + REG_L x14, PT_A4(sp) 158 + REG_L x15, PT_A5(sp) 159 + REG_L x16, PT_A6(sp) 160 + REG_L x17, PT_A7(sp) 161 162 + .if \all == 1 163 + REG_L x2, PT_SP(sp) 164 + REG_L x3, PT_GP(sp) 165 + REG_L x4, PT_TP(sp) 166 + REG_L x6, PT_T1(sp) 167 + REG_L x7, PT_T2(sp) 168 + REG_L x8, PT_S0(sp) 169 + REG_L x9, PT_S1(sp) 170 + REG_L x18, PT_S2(sp) 171 + REG_L x19, PT_S3(sp) 172 + REG_L x20, PT_S4(sp) 173 + REG_L x21, PT_S5(sp) 174 + REG_L x22, PT_S6(sp) 175 + REG_L x23, PT_S7(sp) 176 + REG_L x24, PT_S8(sp) 177 + REG_L x25, PT_S9(sp) 178 + REG_L x26, PT_S10(sp) 179 + REG_L x27, PT_S11(sp) 180 + REG_L x28, PT_T3(sp) 181 + REG_L x29, PT_T4(sp) 182 + REG_L x30, PT_T5(sp) 183 + REG_L x31, PT_T6(sp) 184 + 185 + .else 186 + #ifdef HAVE_FUNCTION_GRAPH_FP_TEST 187 + REG_L x8, PT_S0(sp) 188 + #endif 189 + .endif 190 addi sp, sp, PT_SIZE_ON_STACK 191 .endm 192 + 193 + .macro PREPARE_ARGS 194 + addi a0, t0, -FENTRY_RA_OFFSET 195 + la a1, function_trace_op 196 + REG_L a2, 0(a1) 197 + mv a1, ra 198 + mv a3, sp 199 + .endm 200 + 201 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ 202 203 + #ifndef CONFIG_DYNAMIC_FTRACE_WITH_REGS 204 SYM_FUNC_START(ftrace_caller) 205 SAVE_ABI 206 ··· 105 call ftrace_stub 106 #endif 107 RESTORE_ABI 108 + jr t0 109 SYM_FUNC_END(ftrace_caller) 110 111 + #else /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ 112 SYM_FUNC_START(ftrace_regs_caller) 113 + mv t1, zero 114 + SAVE_ABI_REGS 1 115 + PREPARE_ARGS 116 117 SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL) 118 call ftrace_stub 119 120 + RESTORE_ABI_REGS 1 121 + bnez t1, .Ldirect 122 + jr t0 123 + .Ldirect: 124 + jr t1 125 SYM_FUNC_END(ftrace_regs_caller) 126 + 127 + SYM_FUNC_START(ftrace_caller) 128 + SAVE_ABI_REGS 0 129 + PREPARE_ARGS 130 + 131 + SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) 132 + call ftrace_stub 133 + 134 + RESTORE_ABI_REGS 0 135 + jr t0 136 + SYM_FUNC_END(ftrace_caller) 137 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ 138 + 139 + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS 140 + SYM_CODE_START(ftrace_stub_direct_tramp) 141 + jr t0 142 + SYM_CODE_END(ftrace_stub_direct_tramp) 143 + #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
+25 -9
arch/riscv/kernel/module.c
··· 723 724 if (!bucket) { 725 kfree(entry); 726 - kfree(rel_head); 727 kfree(rel_head->rel_entry); 728 return -ENOMEM; 729 } 730 ··· 747 { 748 /* Can safely assume that bits is not greater than sizeof(long) */ 749 unsigned long hashtable_size = roundup_pow_of_two(num_relocations); 750 unsigned int hashtable_bits = ilog2(hashtable_size); 751 752 /* ··· 764 hashtable_size <<= should_double_size; 765 766 *relocation_hashtable = kmalloc_array(hashtable_size, 767 - sizeof(*relocation_hashtable), 768 GFP_KERNEL); 769 if (!*relocation_hashtable) 770 - return -ENOMEM; 771 772 __hash_init(*relocation_hashtable, hashtable_size); 773 ··· 783 Elf_Sym *sym; 784 void *location; 785 unsigned int i, type; 786 Elf_Addr v; 787 int res; 788 unsigned int num_relocations = sechdrs[relsec].sh_size / sizeof(*rel); ··· 794 hashtable_bits = initialize_relocation_hashtable(num_relocations, 795 &relocation_hashtable); 796 797 - if (hashtable_bits < 0) 798 - return hashtable_bits; 799 800 INIT_LIST_HEAD(&used_buckets_list); 801 ··· 834 v = sym->st_value + rel[i].r_addend; 835 836 if (type == R_RISCV_PCREL_LO12_I || type == R_RISCV_PCREL_LO12_S) { 837 - unsigned int j; 838 839 - for (j = 0; j < sechdrs[relsec].sh_size / sizeof(*rel); j++) { 840 unsigned long hi20_loc = 841 sechdrs[sechdrs[relsec].sh_info].sh_addr 842 + rel[j].r_offset; ··· 866 hi20 = (offset + 0x800) & 0xfffff000; 867 lo12 = offset - hi20; 868 v = lo12; 869 870 break; 871 } 872 - } 873 - if (j == sechdrs[relsec].sh_size / sizeof(*rel)) { 874 pr_err( 875 "%s: Can not find HI20 relocation information\n", 876 me->name); 877 return -EINVAL; 878 } 879 } 880 881 if (reloc_handlers[type].accumulate_handler)
··· 723 724 if (!bucket) { 725 kfree(entry); 726 kfree(rel_head->rel_entry); 727 + kfree(rel_head); 728 return -ENOMEM; 729 } 730 ··· 747 { 748 /* Can safely assume that bits is not greater than sizeof(long) */ 749 unsigned long hashtable_size = roundup_pow_of_two(num_relocations); 750 + /* 751 + * When hashtable_size == 1, hashtable_bits == 0. 752 + * This is valid because the hashing algorithm returns 0 in this case. 753 + */ 754 unsigned int hashtable_bits = ilog2(hashtable_size); 755 756 /* ··· 760 hashtable_size <<= should_double_size; 761 762 *relocation_hashtable = kmalloc_array(hashtable_size, 763 + sizeof(**relocation_hashtable), 764 GFP_KERNEL); 765 if (!*relocation_hashtable) 766 + return 0; 767 768 __hash_init(*relocation_hashtable, hashtable_size); 769 ··· 779 Elf_Sym *sym; 780 void *location; 781 unsigned int i, type; 782 + unsigned int j_idx = 0; 783 Elf_Addr v; 784 int res; 785 unsigned int num_relocations = sechdrs[relsec].sh_size / sizeof(*rel); ··· 789 hashtable_bits = initialize_relocation_hashtable(num_relocations, 790 &relocation_hashtable); 791 792 + if (!relocation_hashtable) 793 + return -ENOMEM; 794 795 INIT_LIST_HEAD(&used_buckets_list); 796 ··· 829 v = sym->st_value + rel[i].r_addend; 830 831 if (type == R_RISCV_PCREL_LO12_I || type == R_RISCV_PCREL_LO12_S) { 832 + unsigned int j = j_idx; 833 + bool found = false; 834 835 + do { 836 unsigned long hi20_loc = 837 sechdrs[sechdrs[relsec].sh_info].sh_addr 838 + rel[j].r_offset; ··· 860 hi20 = (offset + 0x800) & 0xfffff000; 861 lo12 = offset - hi20; 862 v = lo12; 863 + found = true; 864 865 break; 866 } 867 + 868 + j++; 869 + if (j > sechdrs[relsec].sh_size / sizeof(*rel)) 870 + j = 0; 871 + 872 + } while (j_idx != j); 873 + 874 + if (!found) { 875 pr_err( 876 "%s: Can not find HI20 relocation information\n", 877 me->name); 878 return -EINVAL; 879 } 880 + 881 + /* Record the previous j-loop end index */ 882 + j_idx = j; 883 } 884 885 if (reloc_handlers[type].accumulate_handler)
+1 -2
arch/riscv/kernel/pi/cmdline_early.c
··· 38 if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) || 39 IS_ENABLED(CONFIG_CMDLINE_FORCE) || 40 fdt_cmdline_size == 0 /* CONFIG_CMDLINE_FALLBACK */) { 41 - strncat(early_cmdline, CONFIG_CMDLINE, 42 - COMMAND_LINE_SIZE - fdt_cmdline_size); 43 } 44 45 return early_cmdline;
··· 38 if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) || 39 IS_ENABLED(CONFIG_CMDLINE_FORCE) || 40 fdt_cmdline_size == 0 /* CONFIG_CMDLINE_FALLBACK */) { 41 + strlcat(early_cmdline, CONFIG_CMDLINE, COMMAND_LINE_SIZE); 42 } 43 44 return early_cmdline;
+12 -1
arch/riscv/kernel/process.c
··· 171 riscv_v_vstate_off(task_pt_regs(current)); 172 kfree(current->thread.vstate.datap); 173 memset(&current->thread.vstate, 0, sizeof(struct __riscv_v_ext_state)); 174 #endif 175 } 176 ··· 179 { 180 /* Free the vector context of datap. */ 181 if (has_vector()) 182 - kfree(tsk->thread.vstate.datap); 183 } 184 185 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) ··· 188 *dst = *src; 189 /* clear entire V context, including datap for a new task */ 190 memset(&dst->thread.vstate, 0, sizeof(struct __riscv_v_ext_state)); 191 192 return 0; 193 } ··· 224 childregs->a0 = 0; /* Return value of fork() */ 225 p->thread.s[0] = 0; 226 } 227 p->thread.ra = (unsigned long)ret_from_fork; 228 p->thread.sp = (unsigned long)childregs; /* kernel sp */ 229 return 0; 230 }
··· 171 riscv_v_vstate_off(task_pt_regs(current)); 172 kfree(current->thread.vstate.datap); 173 memset(&current->thread.vstate, 0, sizeof(struct __riscv_v_ext_state)); 174 + clear_tsk_thread_flag(current, TIF_RISCV_V_DEFER_RESTORE); 175 #endif 176 } 177 ··· 178 { 179 /* Free the vector context of datap. */ 180 if (has_vector()) 181 + riscv_v_thread_free(tsk); 182 } 183 184 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) ··· 187 *dst = *src; 188 /* clear entire V context, including datap for a new task */ 189 memset(&dst->thread.vstate, 0, sizeof(struct __riscv_v_ext_state)); 190 + memset(&dst->thread.kernel_vstate, 0, sizeof(struct __riscv_v_ext_state)); 191 + clear_tsk_thread_flag(dst, TIF_RISCV_V_DEFER_RESTORE); 192 193 return 0; 194 } ··· 221 childregs->a0 = 0; /* Return value of fork() */ 222 p->thread.s[0] = 0; 223 } 224 + p->thread.riscv_v_flags = 0; 225 + if (has_vector()) 226 + riscv_v_thread_alloc(p); 227 p->thread.ra = (unsigned long)ret_from_fork; 228 p->thread.sp = (unsigned long)childregs; /* kernel sp */ 229 return 0; 230 + } 231 + 232 + void __init arch_task_cache_init(void) 233 + { 234 + riscv_v_setup_ctx_cache(); 235 }
+5 -2
arch/riscv/kernel/ptrace.c
··· 99 * Ensure the vector registers have been saved to the memory before 100 * copying them to membuf. 101 */ 102 - if (target == current) 103 - riscv_v_vstate_save(current, task_pt_regs(current)); 104 105 ptrace_vstate.vstart = vstate->vstart; 106 ptrace_vstate.vl = vstate->vl;
··· 99 * Ensure the vector registers have been saved to the memory before 100 * copying them to membuf. 101 */ 102 + if (target == current) { 103 + get_cpu_vector_context(); 104 + riscv_v_vstate_save(&current->thread.vstate, task_pt_regs(current)); 105 + put_cpu_vector_context(); 106 + } 107 108 ptrace_vstate.vstart = vstate->vstart; 109 ptrace_vstate.vl = vstate->vl;
+66
arch/riscv/kernel/sbi.c
··· 7 8 #include <linux/bits.h> 9 #include <linux/init.h> 10 #include <linux/pm.h> 11 #include <linux/reboot.h> 12 #include <asm/sbi.h> ··· 572 } 573 EXPORT_SYMBOL_GPL(sbi_get_mimpid); 574 575 void __init sbi_init(void) 576 { 577 int ret; ··· 672 sbi_srst_reboot_nb.notifier_call = sbi_srst_reboot; 673 sbi_srst_reboot_nb.priority = 192; 674 register_restart_handler(&sbi_srst_reboot_nb); 675 } 676 } else { 677 __sbi_set_timer = __sbi_set_timer_v01;
··· 7 8 #include <linux/bits.h> 9 #include <linux/init.h> 10 + #include <linux/mm.h> 11 #include <linux/pm.h> 12 #include <linux/reboot.h> 13 #include <asm/sbi.h> ··· 571 } 572 EXPORT_SYMBOL_GPL(sbi_get_mimpid); 573 574 + bool sbi_debug_console_available; 575 + 576 + int sbi_debug_console_write(const char *bytes, unsigned int num_bytes) 577 + { 578 + phys_addr_t base_addr; 579 + struct sbiret ret; 580 + 581 + if (!sbi_debug_console_available) 582 + return -EOPNOTSUPP; 583 + 584 + if (is_vmalloc_addr(bytes)) 585 + base_addr = page_to_phys(vmalloc_to_page(bytes)) + 586 + offset_in_page(bytes); 587 + else 588 + base_addr = __pa(bytes); 589 + if (PAGE_SIZE < (offset_in_page(bytes) + num_bytes)) 590 + num_bytes = PAGE_SIZE - offset_in_page(bytes); 591 + 592 + if (IS_ENABLED(CONFIG_32BIT)) 593 + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, 594 + num_bytes, lower_32_bits(base_addr), 595 + upper_32_bits(base_addr), 0, 0, 0); 596 + else 597 + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, 598 + num_bytes, base_addr, 0, 0, 0, 0); 599 + 600 + if (ret.error == SBI_ERR_FAILURE) 601 + return -EIO; 602 + return ret.error ? sbi_err_map_linux_errno(ret.error) : ret.value; 603 + } 604 + 605 + int sbi_debug_console_read(char *bytes, unsigned int num_bytes) 606 + { 607 + phys_addr_t base_addr; 608 + struct sbiret ret; 609 + 610 + if (!sbi_debug_console_available) 611 + return -EOPNOTSUPP; 612 + 613 + if (is_vmalloc_addr(bytes)) 614 + base_addr = page_to_phys(vmalloc_to_page(bytes)) + 615 + offset_in_page(bytes); 616 + else 617 + base_addr = __pa(bytes); 618 + if (PAGE_SIZE < (offset_in_page(bytes) + num_bytes)) 619 + num_bytes = PAGE_SIZE - offset_in_page(bytes); 620 + 621 + if (IS_ENABLED(CONFIG_32BIT)) 622 + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ, 623 + num_bytes, lower_32_bits(base_addr), 624 + upper_32_bits(base_addr), 0, 0, 0); 625 + else 626 + ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ, 627 + num_bytes, base_addr, 0, 0, 0, 0); 628 + 629 + if (ret.error == SBI_ERR_FAILURE) 630 + return -EIO; 631 + return ret.error ? sbi_err_map_linux_errno(ret.error) : ret.value; 632 + } 633 + 634 void __init sbi_init(void) 635 { 636 int ret; ··· 611 sbi_srst_reboot_nb.notifier_call = sbi_srst_reboot; 612 sbi_srst_reboot_nb.priority = 192; 613 register_restart_handler(&sbi_srst_reboot_nb); 614 + } 615 + if ((sbi_spec_version >= sbi_mk_version(2, 0)) && 616 + (sbi_probe_extension(SBI_EXT_DBCN) > 0)) { 617 + pr_info("SBI DBCN extension detected\n"); 618 + sbi_debug_console_available = true; 619 } 620 } else { 621 __sbi_set_timer = __sbi_set_timer_v01;
+5 -2
arch/riscv/kernel/signal.c
··· 86 /* datap is designed to be 16 byte aligned for better performance */ 87 WARN_ON(unlikely(!IS_ALIGNED((unsigned long)datap, 16))); 88 89 - riscv_v_vstate_save(current, regs); 90 /* Copy everything of vstate but datap. */ 91 err = __copy_to_user(&state->v_state, &current->thread.vstate, 92 offsetof(struct __riscv_v_ext_state, datap)); ··· 137 if (unlikely(err)) 138 return err; 139 140 - riscv_v_vstate_restore(current, regs); 141 142 return err; 143 }
··· 86 /* datap is designed to be 16 byte aligned for better performance */ 87 WARN_ON(unlikely(!IS_ALIGNED((unsigned long)datap, 16))); 88 89 + get_cpu_vector_context(); 90 + riscv_v_vstate_save(&current->thread.vstate, regs); 91 + put_cpu_vector_context(); 92 + 93 /* Copy everything of vstate but datap. */ 94 err = __copy_to_user(&state->v_state, &current->thread.vstate, 95 offsetof(struct __riscv_v_ext_state, datap)); ··· 134 if (unlikely(err)) 135 return err; 136 137 + riscv_v_vstate_set_restore(current, regs); 138 139 return err; 140 }
+44
arch/riscv/kernel/suspend.c
··· 4 * Copyright (c) 2022 Ventana Micro Systems Inc. 5 */ 6 7 #include <linux/ftrace.h> 8 #include <asm/csr.h> 9 #include <asm/suspend.h> 10 11 void suspend_save_csrs(struct suspend_context *context) ··· 89 90 return rc; 91 }
··· 4 * Copyright (c) 2022 Ventana Micro Systems Inc. 5 */ 6 7 + #define pr_fmt(fmt) "suspend: " fmt 8 + 9 #include <linux/ftrace.h> 10 + #include <linux/suspend.h> 11 #include <asm/csr.h> 12 + #include <asm/sbi.h> 13 #include <asm/suspend.h> 14 15 void suspend_save_csrs(struct suspend_context *context) ··· 85 86 return rc; 87 } 88 + 89 + #ifdef CONFIG_RISCV_SBI 90 + static int sbi_system_suspend(unsigned long sleep_type, 91 + unsigned long resume_addr, 92 + unsigned long opaque) 93 + { 94 + struct sbiret ret; 95 + 96 + ret = sbi_ecall(SBI_EXT_SUSP, SBI_EXT_SUSP_SYSTEM_SUSPEND, 97 + sleep_type, resume_addr, opaque, 0, 0, 0); 98 + if (ret.error) 99 + return sbi_err_map_linux_errno(ret.error); 100 + 101 + return ret.value; 102 + } 103 + 104 + static int sbi_system_suspend_enter(suspend_state_t state) 105 + { 106 + return cpu_suspend(SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM, sbi_system_suspend); 107 + } 108 + 109 + static const struct platform_suspend_ops sbi_system_suspend_ops = { 110 + .valid = suspend_valid_only_mem, 111 + .enter = sbi_system_suspend_enter, 112 + }; 113 + 114 + static int __init sbi_system_suspend_init(void) 115 + { 116 + if (sbi_spec_version >= sbi_mk_version(2, 0) && 117 + sbi_probe_extension(SBI_EXT_SUSP) > 0) { 118 + pr_info("SBI SUSP extension detected\n"); 119 + if (IS_ENABLED(CONFIG_SUSPEND)) 120 + suspend_set_ops(&sbi_system_suspend_ops); 121 + } 122 + 123 + return 0; 124 + } 125 + 126 + arch_initcall(sbi_system_suspend_init); 127 + #endif /* CONFIG_RISCV_SBI */
+45 -8
arch/riscv/kernel/vector.c
··· 21 #include <asm/bug.h> 22 23 static bool riscv_v_implicit_uacc = IS_ENABLED(CONFIG_RISCV_ISA_V_DEFAULT_ENABLE); 24 25 unsigned long riscv_v_vsize __read_mostly; 26 EXPORT_SYMBOL_GPL(riscv_v_vsize); ··· 49 } 50 51 return 0; 52 } 53 54 static bool insn_is_vector(u32 insn_buf) ··· 99 return false; 100 } 101 102 - static int riscv_v_thread_zalloc(void) 103 { 104 void *datap; 105 106 - datap = kzalloc(riscv_v_vsize, GFP_KERNEL); 107 if (!datap) 108 return -ENOMEM; 109 110 - current->thread.vstate.datap = datap; 111 - memset(&current->thread.vstate, 0, offsetof(struct __riscv_v_ext_state, 112 - datap)); 113 return 0; 114 } 115 116 #define VSTATE_CTRL_GET_CUR(x) ((x) & PR_RISCV_V_VSTATE_CTRL_CUR_MASK) ··· 158 ctrl |= VSTATE_CTRL_MAKE_NEXT(nxt); 159 if (inherit) 160 ctrl |= PR_RISCV_V_VSTATE_CTRL_INHERIT; 161 - tsk->thread.vstate_ctrl = ctrl; 162 } 163 164 bool riscv_v_vstate_ctrl_user_allowed(void) ··· 199 * context where VS has been off. So, try to allocate the user's V 200 * context and resume execution. 201 */ 202 - if (riscv_v_thread_zalloc()) { 203 force_sig(SIGBUS); 204 return true; 205 } 206 riscv_v_vstate_on(regs); 207 - riscv_v_vstate_restore(current, regs); 208 return true; 209 } 210
··· 21 #include <asm/bug.h> 22 23 static bool riscv_v_implicit_uacc = IS_ENABLED(CONFIG_RISCV_ISA_V_DEFAULT_ENABLE); 24 + static struct kmem_cache *riscv_v_user_cachep; 25 + #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE 26 + static struct kmem_cache *riscv_v_kernel_cachep; 27 + #endif 28 29 unsigned long riscv_v_vsize __read_mostly; 30 EXPORT_SYMBOL_GPL(riscv_v_vsize); ··· 45 } 46 47 return 0; 48 + } 49 + 50 + void __init riscv_v_setup_ctx_cache(void) 51 + { 52 + if (!has_vector()) 53 + return; 54 + 55 + riscv_v_user_cachep = kmem_cache_create_usercopy("riscv_vector_ctx", 56 + riscv_v_vsize, 16, SLAB_PANIC, 57 + 0, riscv_v_vsize, NULL); 58 + #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE 59 + riscv_v_kernel_cachep = kmem_cache_create("riscv_vector_kctx", 60 + riscv_v_vsize, 16, 61 + SLAB_PANIC, NULL); 62 + #endif 63 } 64 65 static bool insn_is_vector(u32 insn_buf) ··· 80 return false; 81 } 82 83 + static int riscv_v_thread_zalloc(struct kmem_cache *cache, 84 + struct __riscv_v_ext_state *ctx) 85 { 86 void *datap; 87 88 + datap = kmem_cache_zalloc(cache, GFP_KERNEL); 89 if (!datap) 90 return -ENOMEM; 91 92 + ctx->datap = datap; 93 + memset(ctx, 0, offsetof(struct __riscv_v_ext_state, datap)); 94 return 0; 95 + } 96 + 97 + void riscv_v_thread_alloc(struct task_struct *tsk) 98 + { 99 + #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE 100 + riscv_v_thread_zalloc(riscv_v_kernel_cachep, &tsk->thread.kernel_vstate); 101 + #endif 102 + } 103 + 104 + void riscv_v_thread_free(struct task_struct *tsk) 105 + { 106 + if (tsk->thread.vstate.datap) 107 + kmem_cache_free(riscv_v_user_cachep, tsk->thread.vstate.datap); 108 + #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE 109 + if (tsk->thread.kernel_vstate.datap) 110 + kmem_cache_free(riscv_v_kernel_cachep, tsk->thread.kernel_vstate.datap); 111 + #endif 112 } 113 114 #define VSTATE_CTRL_GET_CUR(x) ((x) & PR_RISCV_V_VSTATE_CTRL_CUR_MASK) ··· 122 ctrl |= VSTATE_CTRL_MAKE_NEXT(nxt); 123 if (inherit) 124 ctrl |= PR_RISCV_V_VSTATE_CTRL_INHERIT; 125 + tsk->thread.vstate_ctrl &= ~PR_RISCV_V_VSTATE_CTRL_MASK; 126 + tsk->thread.vstate_ctrl |= ctrl; 127 } 128 129 bool riscv_v_vstate_ctrl_user_allowed(void) ··· 162 * context where VS has been off. So, try to allocate the user's V 163 * context and resume execution. 164 */ 165 + if (riscv_v_thread_zalloc(riscv_v_user_cachep, &current->thread.vstate)) { 166 force_sig(SIGBUS); 167 return true; 168 } 169 riscv_v_vstate_on(regs); 170 + riscv_v_vstate_set_restore(current, regs); 171 return true; 172 } 173
+6
arch/riscv/lib/Makefile
··· 6 lib-y += strcmp.o 7 lib-y += strlen.o 8 lib-y += strncmp.o 9 lib-$(CONFIG_MMU) += uaccess.o 10 lib-$(CONFIG_64BIT) += tishift.o 11 lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o 12 13 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
··· 6 lib-y += strcmp.o 7 lib-y += strlen.o 8 lib-y += strncmp.o 9 + lib-y += csum.o 10 + ifeq ($(CONFIG_MMU), y) 11 + lib-$(CONFIG_RISCV_ISA_V) += uaccess_vector.o 12 + endif 13 lib-$(CONFIG_MMU) += uaccess.o 14 lib-$(CONFIG_64BIT) += tishift.o 15 lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o 16 17 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o 18 + lib-$(CONFIG_RISCV_ISA_V) += xor.o 19 + lib-$(CONFIG_RISCV_ISA_V) += riscv_v_helpers.o
+328
arch/riscv/lib/csum.c
···
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Checksum library 4 + * 5 + * Influenced by arch/arm64/lib/csum.c 6 + * Copyright (C) 2023 Rivos Inc. 7 + */ 8 + #include <linux/bitops.h> 9 + #include <linux/compiler.h> 10 + #include <linux/jump_label.h> 11 + #include <linux/kasan-checks.h> 12 + #include <linux/kernel.h> 13 + 14 + #include <asm/cpufeature.h> 15 + 16 + #include <net/checksum.h> 17 + 18 + /* Default version is sufficient for 32 bit */ 19 + #ifndef CONFIG_32BIT 20 + __sum16 csum_ipv6_magic(const struct in6_addr *saddr, 21 + const struct in6_addr *daddr, 22 + __u32 len, __u8 proto, __wsum csum) 23 + { 24 + unsigned int ulen, uproto; 25 + unsigned long sum = (__force unsigned long)csum; 26 + 27 + sum += (__force unsigned long)saddr->s6_addr32[0]; 28 + sum += (__force unsigned long)saddr->s6_addr32[1]; 29 + sum += (__force unsigned long)saddr->s6_addr32[2]; 30 + sum += (__force unsigned long)saddr->s6_addr32[3]; 31 + 32 + sum += (__force unsigned long)daddr->s6_addr32[0]; 33 + sum += (__force unsigned long)daddr->s6_addr32[1]; 34 + sum += (__force unsigned long)daddr->s6_addr32[2]; 35 + sum += (__force unsigned long)daddr->s6_addr32[3]; 36 + 37 + ulen = (__force unsigned int)htonl((unsigned int)len); 38 + sum += ulen; 39 + 40 + uproto = (__force unsigned int)htonl(proto); 41 + sum += uproto; 42 + 43 + /* 44 + * Zbb support saves 4 instructions, so not worth checking without 45 + * alternatives if supported 46 + */ 47 + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && 48 + IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) { 49 + unsigned long fold_temp; 50 + 51 + /* 52 + * Zbb is likely available when the kernel is compiled with Zbb 53 + * support, so nop when Zbb is available and jump when Zbb is 54 + * not available. 55 + */ 56 + asm_volatile_goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, 57 + RISCV_ISA_EXT_ZBB, 1) 58 + : 59 + : 60 + : 61 + : no_zbb); 62 + asm(".option push \n\ 63 + .option arch,+zbb \n\ 64 + rori %[fold_temp], %[sum], 32 \n\ 65 + add %[sum], %[fold_temp], %[sum] \n\ 66 + srli %[sum], %[sum], 32 \n\ 67 + not %[fold_temp], %[sum] \n\ 68 + roriw %[sum], %[sum], 16 \n\ 69 + subw %[sum], %[fold_temp], %[sum] \n\ 70 + .option pop" 71 + : [sum] "+r" (sum), [fold_temp] "=&r" (fold_temp)); 72 + return (__force __sum16)(sum >> 16); 73 + } 74 + no_zbb: 75 + sum += ror64(sum, 32); 76 + sum >>= 32; 77 + return csum_fold((__force __wsum)sum); 78 + } 79 + EXPORT_SYMBOL(csum_ipv6_magic); 80 + #endif /* !CONFIG_32BIT */ 81 + 82 + #ifdef CONFIG_32BIT 83 + #define OFFSET_MASK 3 84 + #elif CONFIG_64BIT 85 + #define OFFSET_MASK 7 86 + #endif 87 + 88 + static inline __no_sanitize_address unsigned long 89 + do_csum_common(const unsigned long *ptr, const unsigned long *end, 90 + unsigned long data) 91 + { 92 + unsigned int shift; 93 + unsigned long csum = 0, carry = 0; 94 + 95 + /* 96 + * Do 32-bit reads on RV32 and 64-bit reads otherwise. This should be 97 + * faster than doing 32-bit reads on architectures that support larger 98 + * reads. 99 + */ 100 + while (ptr < end) { 101 + csum += data; 102 + carry += csum < data; 103 + data = *(ptr++); 104 + } 105 + 106 + /* 107 + * Perform alignment (and over-read) bytes on the tail if any bytes 108 + * leftover. 109 + */ 110 + shift = ((long)ptr - (long)end) * 8; 111 + #ifdef __LITTLE_ENDIAN 112 + data = (data << shift) >> shift; 113 + #else 114 + data = (data >> shift) << shift; 115 + #endif 116 + csum += data; 117 + carry += csum < data; 118 + csum += carry; 119 + csum += csum < carry; 120 + 121 + return csum; 122 + } 123 + 124 + /* 125 + * Algorithm accounts for buff being misaligned. 126 + * If buff is not aligned, will over-read bytes but not use the bytes that it 127 + * shouldn't. The same thing will occur on the tail-end of the read. 128 + */ 129 + static inline __no_sanitize_address unsigned int 130 + do_csum_with_alignment(const unsigned char *buff, int len) 131 + { 132 + unsigned int offset, shift; 133 + unsigned long csum, data; 134 + const unsigned long *ptr, *end; 135 + 136 + /* 137 + * Align address to closest word (double word on rv64) that comes before 138 + * buff. This should always be in the same page and cache line. 139 + * Directly call KASAN with the alignment we will be using. 140 + */ 141 + offset = (unsigned long)buff & OFFSET_MASK; 142 + kasan_check_read(buff, len); 143 + ptr = (const unsigned long *)(buff - offset); 144 + 145 + /* 146 + * Clear the most significant bytes that were over-read if buff was not 147 + * aligned. 148 + */ 149 + shift = offset * 8; 150 + data = *(ptr++); 151 + #ifdef __LITTLE_ENDIAN 152 + data = (data >> shift) << shift; 153 + #else 154 + data = (data << shift) >> shift; 155 + #endif 156 + end = (const unsigned long *)(buff + len); 157 + csum = do_csum_common(ptr, end, data); 158 + 159 + #ifdef CC_HAS_ASM_GOTO_TIED_OUTPUT 160 + /* 161 + * Zbb support saves 6 instructions, so not worth checking without 162 + * alternatives if supported 163 + */ 164 + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && 165 + IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) { 166 + unsigned long fold_temp; 167 + 168 + /* 169 + * Zbb is likely available when the kernel is compiled with Zbb 170 + * support, so nop when Zbb is available and jump when Zbb is 171 + * not available. 172 + */ 173 + asm_volatile_goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, 174 + RISCV_ISA_EXT_ZBB, 1) 175 + : 176 + : 177 + : 178 + : no_zbb); 179 + 180 + #ifdef CONFIG_32BIT 181 + asm_volatile_goto(".option push \n\ 182 + .option arch,+zbb \n\ 183 + rori %[fold_temp], %[csum], 16 \n\ 184 + andi %[offset], %[offset], 1 \n\ 185 + add %[csum], %[fold_temp], %[csum] \n\ 186 + beq %[offset], zero, %l[end] \n\ 187 + rev8 %[csum], %[csum] \n\ 188 + .option pop" 189 + : [csum] "+r" (csum), [fold_temp] "=&r" (fold_temp) 190 + : [offset] "r" (offset) 191 + : 192 + : end); 193 + 194 + return (unsigned short)csum; 195 + #else /* !CONFIG_32BIT */ 196 + asm_volatile_goto(".option push \n\ 197 + .option arch,+zbb \n\ 198 + rori %[fold_temp], %[csum], 32 \n\ 199 + add %[csum], %[fold_temp], %[csum] \n\ 200 + srli %[csum], %[csum], 32 \n\ 201 + roriw %[fold_temp], %[csum], 16 \n\ 202 + addw %[csum], %[fold_temp], %[csum] \n\ 203 + andi %[offset], %[offset], 1 \n\ 204 + beq %[offset], zero, %l[end] \n\ 205 + rev8 %[csum], %[csum] \n\ 206 + .option pop" 207 + : [csum] "+r" (csum), [fold_temp] "=&r" (fold_temp) 208 + : [offset] "r" (offset) 209 + : 210 + : end); 211 + 212 + return (csum << 16) >> 48; 213 + #endif /* !CONFIG_32BIT */ 214 + end: 215 + return csum >> 16; 216 + } 217 + no_zbb: 218 + #endif /* CC_HAS_ASM_GOTO_TIED_OUTPUT */ 219 + #ifndef CONFIG_32BIT 220 + csum += ror64(csum, 32); 221 + csum >>= 32; 222 + #endif 223 + csum = (u32)csum + ror32((u32)csum, 16); 224 + if (offset & 1) 225 + return (u16)swab32(csum); 226 + return csum >> 16; 227 + } 228 + 229 + /* 230 + * Does not perform alignment, should only be used if machine has fast 231 + * misaligned accesses, or when buff is known to be aligned. 232 + */ 233 + static inline __no_sanitize_address unsigned int 234 + do_csum_no_alignment(const unsigned char *buff, int len) 235 + { 236 + unsigned long csum, data; 237 + const unsigned long *ptr, *end; 238 + 239 + ptr = (const unsigned long *)(buff); 240 + data = *(ptr++); 241 + 242 + kasan_check_read(buff, len); 243 + 244 + end = (const unsigned long *)(buff + len); 245 + csum = do_csum_common(ptr, end, data); 246 + 247 + /* 248 + * Zbb support saves 6 instructions, so not worth checking without 249 + * alternatives if supported 250 + */ 251 + if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && 252 + IS_ENABLED(CONFIG_RISCV_ALTERNATIVE)) { 253 + unsigned long fold_temp; 254 + 255 + /* 256 + * Zbb is likely available when the kernel is compiled with Zbb 257 + * support, so nop when Zbb is available and jump when Zbb is 258 + * not available. 259 + */ 260 + asm_volatile_goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0, 261 + RISCV_ISA_EXT_ZBB, 1) 262 + : 263 + : 264 + : 265 + : no_zbb); 266 + 267 + #ifdef CONFIG_32BIT 268 + asm (".option push \n\ 269 + .option arch,+zbb \n\ 270 + rori %[fold_temp], %[csum], 16 \n\ 271 + add %[csum], %[fold_temp], %[csum] \n\ 272 + .option pop" 273 + : [csum] "+r" (csum), [fold_temp] "=&r" (fold_temp) 274 + : 275 + : ); 276 + 277 + #else /* !CONFIG_32BIT */ 278 + asm (".option push \n\ 279 + .option arch,+zbb \n\ 280 + rori %[fold_temp], %[csum], 32 \n\ 281 + add %[csum], %[fold_temp], %[csum] \n\ 282 + srli %[csum], %[csum], 32 \n\ 283 + roriw %[fold_temp], %[csum], 16 \n\ 284 + addw %[csum], %[fold_temp], %[csum] \n\ 285 + .option pop" 286 + : [csum] "+r" (csum), [fold_temp] "=&r" (fold_temp) 287 + : 288 + : ); 289 + #endif /* !CONFIG_32BIT */ 290 + return csum >> 16; 291 + } 292 + no_zbb: 293 + #ifndef CONFIG_32BIT 294 + csum += ror64(csum, 32); 295 + csum >>= 32; 296 + #endif 297 + csum = (u32)csum + ror32((u32)csum, 16); 298 + return csum >> 16; 299 + } 300 + 301 + /* 302 + * Perform a checksum on an arbitrary memory address. 303 + * Will do a light-weight address alignment if buff is misaligned, unless 304 + * cpu supports fast misaligned accesses. 305 + */ 306 + unsigned int do_csum(const unsigned char *buff, int len) 307 + { 308 + if (unlikely(len <= 0)) 309 + return 0; 310 + 311 + /* 312 + * Significant performance gains can be seen by not doing alignment 313 + * on machines with fast misaligned accesses. 314 + * 315 + * There is some duplicate code between the "with_alignment" and 316 + * "no_alignment" implmentations, but the overlap is too awkward to be 317 + * able to fit in one function without introducing multiple static 318 + * branches. The largest chunk of overlap was delegated into the 319 + * do_csum_common function. 320 + */ 321 + if (static_branch_likely(&fast_misaligned_access_speed_key)) 322 + return do_csum_no_alignment(buff, len); 323 + 324 + if (((unsigned long)buff & OFFSET_MASK) == 0) 325 + return do_csum_no_alignment(buff, len); 326 + 327 + return do_csum_with_alignment(buff, len); 328 + }
+45
arch/riscv/lib/riscv_v_helpers.c
···
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (C) 2023 SiFive 4 + * Author: Andy Chiu <andy.chiu@sifive.com> 5 + */ 6 + #include <linux/linkage.h> 7 + #include <asm/asm.h> 8 + 9 + #include <asm/vector.h> 10 + #include <asm/simd.h> 11 + 12 + #ifdef CONFIG_MMU 13 + #include <asm/asm-prototypes.h> 14 + #endif 15 + 16 + #ifdef CONFIG_MMU 17 + size_t riscv_v_usercopy_threshold = CONFIG_RISCV_ISA_V_UCOPY_THRESHOLD; 18 + int __asm_vector_usercopy(void *dst, void *src, size_t n); 19 + int fallback_scalar_usercopy(void *dst, void *src, size_t n); 20 + asmlinkage int enter_vector_usercopy(void *dst, void *src, size_t n) 21 + { 22 + size_t remain, copied; 23 + 24 + /* skip has_vector() check because it has been done by the asm */ 25 + if (!may_use_simd()) 26 + goto fallback; 27 + 28 + kernel_vector_begin(); 29 + remain = __asm_vector_usercopy(dst, src, n); 30 + kernel_vector_end(); 31 + 32 + if (remain) { 33 + copied = n - remain; 34 + dst += copied; 35 + src += copied; 36 + n = remain; 37 + goto fallback; 38 + } 39 + 40 + return remain; 41 + 42 + fallback: 43 + return fallback_scalar_usercopy(dst, src, n); 44 + } 45 + #endif
+10
arch/riscv/lib/uaccess.S
··· 3 #include <asm/asm.h> 4 #include <asm/asm-extable.h> 5 #include <asm/csr.h> 6 7 .macro fixup op reg addr lbl 8 100: ··· 13 .endm 14 15 SYM_FUNC_START(__asm_copy_to_user) 16 17 /* Enable access to user memory */ 18 li t6, SR_SUM ··· 190 sub a0, t5, a0 191 ret 192 SYM_FUNC_END(__asm_copy_to_user) 193 EXPORT_SYMBOL(__asm_copy_to_user) 194 SYM_FUNC_ALIAS(__asm_copy_from_user, __asm_copy_to_user) 195 EXPORT_SYMBOL(__asm_copy_from_user)
··· 3 #include <asm/asm.h> 4 #include <asm/asm-extable.h> 5 #include <asm/csr.h> 6 + #include <asm/hwcap.h> 7 + #include <asm/alternative-macros.h> 8 9 .macro fixup op reg addr lbl 10 100: ··· 11 .endm 12 13 SYM_FUNC_START(__asm_copy_to_user) 14 + #ifdef CONFIG_RISCV_ISA_V 15 + ALTERNATIVE("j fallback_scalar_usercopy", "nop", 0, RISCV_ISA_EXT_v, CONFIG_RISCV_ISA_V) 16 + REG_L t0, riscv_v_usercopy_threshold 17 + bltu a2, t0, fallback_scalar_usercopy 18 + tail enter_vector_usercopy 19 + #endif 20 + SYM_FUNC_START(fallback_scalar_usercopy) 21 22 /* Enable access to user memory */ 23 li t6, SR_SUM ··· 181 sub a0, t5, a0 182 ret 183 SYM_FUNC_END(__asm_copy_to_user) 184 + SYM_FUNC_END(fallback_scalar_usercopy) 185 EXPORT_SYMBOL(__asm_copy_to_user) 186 SYM_FUNC_ALIAS(__asm_copy_from_user, __asm_copy_to_user) 187 EXPORT_SYMBOL(__asm_copy_from_user)
+53
arch/riscv/lib/uaccess_vector.S
···
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #include <linux/linkage.h> 4 + #include <asm-generic/export.h> 5 + #include <asm/asm.h> 6 + #include <asm/asm-extable.h> 7 + #include <asm/csr.h> 8 + 9 + #define pDst a0 10 + #define pSrc a1 11 + #define iNum a2 12 + 13 + #define iVL a3 14 + 15 + #define ELEM_LMUL_SETTING m8 16 + #define vData v0 17 + 18 + .macro fixup op reg addr lbl 19 + 100: 20 + \op \reg, \addr 21 + _asm_extable 100b, \lbl 22 + .endm 23 + 24 + SYM_FUNC_START(__asm_vector_usercopy) 25 + /* Enable access to user memory */ 26 + li t6, SR_SUM 27 + csrs CSR_STATUS, t6 28 + 29 + loop: 30 + vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma 31 + fixup vle8.v vData, (pSrc), 10f 32 + sub iNum, iNum, iVL 33 + add pSrc, pSrc, iVL 34 + fixup vse8.v vData, (pDst), 11f 35 + add pDst, pDst, iVL 36 + bnez iNum, loop 37 + 38 + /* Exception fixup for vector load is shared with normal exit */ 39 + 10: 40 + /* Disable access to user memory */ 41 + csrc CSR_STATUS, t6 42 + mv a0, iNum 43 + ret 44 + 45 + /* Exception fixup code for vector store. */ 46 + 11: 47 + /* Undo the subtraction after vle8.v */ 48 + add iNum, iNum, iVL 49 + /* Make sure the scalar fallback skip already processed bytes */ 50 + csrr t2, CSR_VSTART 51 + sub iNum, iNum, t2 52 + j 10b 53 + SYM_FUNC_END(__asm_vector_usercopy)
+81
arch/riscv/lib/xor.S
···
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* 3 + * Copyright (C) 2021 SiFive 4 + */ 5 + #include <linux/linkage.h> 6 + #include <linux/export.h> 7 + #include <asm/asm.h> 8 + 9 + SYM_FUNC_START(xor_regs_2_) 10 + vsetvli a3, a0, e8, m8, ta, ma 11 + vle8.v v0, (a1) 12 + vle8.v v8, (a2) 13 + sub a0, a0, a3 14 + vxor.vv v16, v0, v8 15 + add a2, a2, a3 16 + vse8.v v16, (a1) 17 + add a1, a1, a3 18 + bnez a0, xor_regs_2_ 19 + ret 20 + SYM_FUNC_END(xor_regs_2_) 21 + EXPORT_SYMBOL(xor_regs_2_) 22 + 23 + SYM_FUNC_START(xor_regs_3_) 24 + vsetvli a4, a0, e8, m8, ta, ma 25 + vle8.v v0, (a1) 26 + vle8.v v8, (a2) 27 + sub a0, a0, a4 28 + vxor.vv v0, v0, v8 29 + vle8.v v16, (a3) 30 + add a2, a2, a4 31 + vxor.vv v16, v0, v16 32 + add a3, a3, a4 33 + vse8.v v16, (a1) 34 + add a1, a1, a4 35 + bnez a0, xor_regs_3_ 36 + ret 37 + SYM_FUNC_END(xor_regs_3_) 38 + EXPORT_SYMBOL(xor_regs_3_) 39 + 40 + SYM_FUNC_START(xor_regs_4_) 41 + vsetvli a5, a0, e8, m8, ta, ma 42 + vle8.v v0, (a1) 43 + vle8.v v8, (a2) 44 + sub a0, a0, a5 45 + vxor.vv v0, v0, v8 46 + vle8.v v16, (a3) 47 + add a2, a2, a5 48 + vxor.vv v0, v0, v16 49 + vle8.v v24, (a4) 50 + add a3, a3, a5 51 + vxor.vv v16, v0, v24 52 + add a4, a4, a5 53 + vse8.v v16, (a1) 54 + add a1, a1, a5 55 + bnez a0, xor_regs_4_ 56 + ret 57 + SYM_FUNC_END(xor_regs_4_) 58 + EXPORT_SYMBOL(xor_regs_4_) 59 + 60 + SYM_FUNC_START(xor_regs_5_) 61 + vsetvli a6, a0, e8, m8, ta, ma 62 + vle8.v v0, (a1) 63 + vle8.v v8, (a2) 64 + sub a0, a0, a6 65 + vxor.vv v0, v0, v8 66 + vle8.v v16, (a3) 67 + add a2, a2, a6 68 + vxor.vv v0, v0, v16 69 + vle8.v v24, (a4) 70 + add a3, a3, a6 71 + vxor.vv v0, v0, v24 72 + vle8.v v8, (a5) 73 + add a4, a4, a6 74 + vxor.vv v16, v0, v8 75 + add a5, a5, a6 76 + vse8.v v16, (a1) 77 + add a1, a1, a6 78 + bnez a0, xor_regs_5_ 79 + ret 80 + SYM_FUNC_END(xor_regs_5_) 81 + EXPORT_SYMBOL(xor_regs_5_)
+31
arch/riscv/mm/extable.c
··· 27 return true; 28 } 29 30 static inline void regs_set_gpr(struct pt_regs *regs, unsigned int offset, 31 unsigned long val) 32 { ··· 58 return true; 59 } 60 61 bool fixup_exception(struct pt_regs *regs) 62 { 63 const struct exception_table_entry *ex; ··· 94 return ex_handler_bpf(ex, regs); 95 case EX_TYPE_UACCESS_ERR_ZERO: 96 return ex_handler_uaccess_err_zero(ex, regs); 97 } 98 99 BUG();
··· 27 return true; 28 } 29 30 + static inline unsigned long regs_get_gpr(struct pt_regs *regs, unsigned int offset) 31 + { 32 + if (unlikely(!offset || offset > MAX_REG_OFFSET)) 33 + return 0; 34 + 35 + return *(unsigned long *)((unsigned long)regs + offset); 36 + } 37 + 38 static inline void regs_set_gpr(struct pt_regs *regs, unsigned int offset, 39 unsigned long val) 40 { ··· 50 return true; 51 } 52 53 + static bool 54 + ex_handler_load_unaligned_zeropad(const struct exception_table_entry *ex, 55 + struct pt_regs *regs) 56 + { 57 + int reg_data = FIELD_GET(EX_DATA_REG_DATA, ex->data); 58 + int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->data); 59 + unsigned long data, addr, offset; 60 + 61 + addr = regs_get_gpr(regs, reg_addr * sizeof(unsigned long)); 62 + 63 + offset = addr & 0x7UL; 64 + addr &= ~0x7UL; 65 + 66 + data = *(unsigned long *)addr >> (offset * 8); 67 + 68 + regs_set_gpr(regs, reg_data * sizeof(unsigned long), data); 69 + 70 + regs->epc = get_ex_fixup(ex); 71 + return true; 72 + } 73 + 74 bool fixup_exception(struct pt_regs *regs) 75 { 76 const struct exception_table_entry *ex; ··· 65 return ex_handler_bpf(ex, regs); 66 case EX_TYPE_UACCESS_ERR_ZERO: 67 return ex_handler_uaccess_err_zero(ex, regs); 68 + case EX_TYPE_LOAD_UNALIGNED_ZEROPAD: 69 + return ex_handler_load_unaligned_zeropad(ex, regs); 70 } 71 72 BUG();
+24 -1
arch/riscv/mm/init.c
··· 1060 kernel_map.virt_addr = KERNEL_LINK_ADDR + kernel_map.virt_offset; 1061 1062 #ifdef CONFIG_XIP_KERNEL 1063 kernel_map.page_offset = PAGE_OFFSET_L3; 1064 kernel_map.xiprom = (uintptr_t)CONFIG_XIP_PHYS_ADDR; 1065 kernel_map.xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom); 1066 ··· 1391 } 1392 1393 #ifdef CONFIG_SPARSEMEM_VMEMMAP 1394 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, 1395 struct vmem_altmap *altmap) 1396 { 1397 - return vmemmap_populate_basepages(start, end, node, NULL); 1398 } 1399 #endif 1400
··· 1060 kernel_map.virt_addr = KERNEL_LINK_ADDR + kernel_map.virt_offset; 1061 1062 #ifdef CONFIG_XIP_KERNEL 1063 + #ifdef CONFIG_64BIT 1064 kernel_map.page_offset = PAGE_OFFSET_L3; 1065 + #else 1066 + kernel_map.page_offset = _AC(CONFIG_PAGE_OFFSET, UL); 1067 + #endif 1068 kernel_map.xiprom = (uintptr_t)CONFIG_XIP_PHYS_ADDR; 1069 kernel_map.xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom); 1070 ··· 1387 } 1388 1389 #ifdef CONFIG_SPARSEMEM_VMEMMAP 1390 + void __meminit vmemmap_set_pmd(pmd_t *pmd, void *p, int node, 1391 + unsigned long addr, unsigned long next) 1392 + { 1393 + pmd_set_huge(pmd, virt_to_phys(p), PAGE_KERNEL); 1394 + } 1395 + 1396 + int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node, 1397 + unsigned long addr, unsigned long next) 1398 + { 1399 + vmemmap_verify((pte_t *)pmdp, node, addr, next); 1400 + return 1; 1401 + } 1402 + 1403 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, 1404 struct vmem_altmap *altmap) 1405 { 1406 + /* 1407 + * Note that SPARSEMEM_VMEMMAP is only selected for rv64 and that we 1408 + * can't use hugepage mappings for 2-level page table because in case of 1409 + * memory hotplug, we are not able to update all the page tables with 1410 + * the new PMDs. 1411 + */ 1412 + return vmemmap_populate_hugepages(start, end, node, NULL); 1413 } 1414 #endif 1415
+49 -20
arch/riscv/mm/tlbflush.c
··· 98 local_flush_tlb_range_asid(d->start, d->size, d->stride, d->asid); 99 } 100 101 - static void __flush_tlb_range(struct mm_struct *mm, unsigned long start, 102 - unsigned long size, unsigned long stride) 103 { 104 struct flush_tlb_range_data ftd; 105 - const struct cpumask *cmask; 106 - unsigned long asid = FLUSH_TLB_NO_ASID; 107 bool broadcast; 108 109 - if (mm) { 110 - unsigned int cpuid; 111 112 - cmask = mm_cpumask(mm); 113 - if (cpumask_empty(cmask)) 114 - return; 115 116 cpuid = get_cpu(); 117 /* check if the tlbflush needs to be sent to other CPUs */ 118 broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids; 119 - 120 - if (static_branch_unlikely(&use_asid_allocator)) 121 - asid = atomic_long_read(&mm->context.id) & asid_mask; 122 } else { 123 - cmask = cpu_online_mask; 124 broadcast = true; 125 } 126 ··· 134 local_flush_tlb_range_asid(start, size, stride, asid); 135 } 136 137 - if (mm) 138 put_cpu(); 139 } 140 141 void flush_tlb_mm(struct mm_struct *mm) 142 { 143 - __flush_tlb_range(mm, 0, FLUSH_TLB_MAX_SIZE, PAGE_SIZE); 144 } 145 146 void flush_tlb_mm_range(struct mm_struct *mm, 147 unsigned long start, unsigned long end, 148 unsigned int page_size) 149 { 150 - __flush_tlb_range(mm, start, end - start, page_size); 151 } 152 153 void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) 154 { 155 - __flush_tlb_range(vma->vm_mm, addr, PAGE_SIZE, PAGE_SIZE); 156 } 157 158 void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, ··· 193 } 194 } 195 196 - __flush_tlb_range(vma->vm_mm, start, end - start, stride_size); 197 } 198 199 void flush_tlb_kernel_range(unsigned long start, unsigned long end) 200 { 201 - __flush_tlb_range(NULL, start, end - start, PAGE_SIZE); 202 } 203 204 #ifdef CONFIG_TRANSPARENT_HUGEPAGE 205 void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, 206 unsigned long end) 207 { 208 - __flush_tlb_range(vma->vm_mm, start, end - start, PMD_SIZE); 209 } 210 #endif
··· 98 local_flush_tlb_range_asid(d->start, d->size, d->stride, d->asid); 99 } 100 101 + static void __flush_tlb_range(struct cpumask *cmask, unsigned long asid, 102 + unsigned long start, unsigned long size, 103 + unsigned long stride) 104 { 105 struct flush_tlb_range_data ftd; 106 bool broadcast; 107 108 + if (cpumask_empty(cmask)) 109 + return; 110 111 + if (cmask != cpu_online_mask) { 112 + unsigned int cpuid; 113 114 cpuid = get_cpu(); 115 /* check if the tlbflush needs to be sent to other CPUs */ 116 broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids; 117 } else { 118 broadcast = true; 119 } 120 ··· 140 local_flush_tlb_range_asid(start, size, stride, asid); 141 } 142 143 + if (cmask != cpu_online_mask) 144 put_cpu(); 145 + } 146 + 147 + static inline unsigned long get_mm_asid(struct mm_struct *mm) 148 + { 149 + return static_branch_unlikely(&use_asid_allocator) ? 150 + atomic_long_read(&mm->context.id) & asid_mask : FLUSH_TLB_NO_ASID; 151 } 152 153 void flush_tlb_mm(struct mm_struct *mm) 154 { 155 + __flush_tlb_range(mm_cpumask(mm), get_mm_asid(mm), 156 + 0, FLUSH_TLB_MAX_SIZE, PAGE_SIZE); 157 } 158 159 void flush_tlb_mm_range(struct mm_struct *mm, 160 unsigned long start, unsigned long end, 161 unsigned int page_size) 162 { 163 + __flush_tlb_range(mm_cpumask(mm), get_mm_asid(mm), 164 + start, end - start, page_size); 165 } 166 167 void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) 168 { 169 + __flush_tlb_range(mm_cpumask(vma->vm_mm), get_mm_asid(vma->vm_mm), 170 + addr, PAGE_SIZE, PAGE_SIZE); 171 } 172 173 void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, ··· 190 } 191 } 192 193 + __flush_tlb_range(mm_cpumask(vma->vm_mm), get_mm_asid(vma->vm_mm), 194 + start, end - start, stride_size); 195 } 196 197 void flush_tlb_kernel_range(unsigned long start, unsigned long end) 198 { 199 + __flush_tlb_range((struct cpumask *)cpu_online_mask, FLUSH_TLB_NO_ASID, 200 + start, end - start, PAGE_SIZE); 201 } 202 203 #ifdef CONFIG_TRANSPARENT_HUGEPAGE 204 void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, 205 unsigned long end) 206 { 207 + __flush_tlb_range(mm_cpumask(vma->vm_mm), get_mm_asid(vma->vm_mm), 208 + start, end - start, PMD_SIZE); 209 } 210 #endif 211 + 212 + bool arch_tlbbatch_should_defer(struct mm_struct *mm) 213 + { 214 + return true; 215 + } 216 + 217 + void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *batch, 218 + struct mm_struct *mm, 219 + unsigned long uaddr) 220 + { 221 + cpumask_or(&batch->cpumask, &batch->cpumask, mm_cpumask(mm)); 222 + } 223 + 224 + void arch_flush_tlb_batched_pending(struct mm_struct *mm) 225 + { 226 + flush_tlb_mm(mm); 227 + } 228 + 229 + void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch) 230 + { 231 + __flush_tlb_range(&batch->cpumask, FLUSH_TLB_NO_ASID, 0, 232 + FLUSH_TLB_MAX_SIZE, PAGE_SIZE); 233 + }
+1 -1
drivers/tty/hvc/Kconfig
··· 108 109 config HVC_RISCV_SBI 110 bool "RISC-V SBI console support" 111 - depends on RISCV_SBI_V01 112 select HVC_DRIVER 113 help 114 This enables support for console output via RISC-V SBI calls, which
··· 108 109 config HVC_RISCV_SBI 110 bool "RISC-V SBI console support" 111 + depends on RISCV_SBI 112 select HVC_DRIVER 113 help 114 This enables support for console output via RISC-V SBI calls, which
+31 -8
drivers/tty/hvc/hvc_riscv_sbi.c
··· 40 return i; 41 } 42 43 - static const struct hv_ops hvc_sbi_ops = { 44 .get_chars = hvc_sbi_tty_get, 45 .put_chars = hvc_sbi_tty_put, 46 }; 47 48 static int __init hvc_sbi_init(void) 49 { 50 - return PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_ops, 16)); 51 - } 52 - device_initcall(hvc_sbi_init); 53 54 - static int __init hvc_sbi_console_init(void) 55 - { 56 - hvc_instantiate(0, 0, &hvc_sbi_ops); 57 58 return 0; 59 } 60 - console_initcall(hvc_sbi_console_init);
··· 40 return i; 41 } 42 43 + static const struct hv_ops hvc_sbi_v01_ops = { 44 .get_chars = hvc_sbi_tty_get, 45 .put_chars = hvc_sbi_tty_put, 46 }; 47 48 + static ssize_t hvc_sbi_dbcn_tty_put(uint32_t vtermno, const u8 *buf, size_t count) 49 + { 50 + return sbi_debug_console_write(buf, count); 51 + } 52 + 53 + static ssize_t hvc_sbi_dbcn_tty_get(uint32_t vtermno, u8 *buf, size_t count) 54 + { 55 + return sbi_debug_console_read(buf, count); 56 + } 57 + 58 + static const struct hv_ops hvc_sbi_dbcn_ops = { 59 + .put_chars = hvc_sbi_dbcn_tty_put, 60 + .get_chars = hvc_sbi_dbcn_tty_get, 61 + }; 62 + 63 static int __init hvc_sbi_init(void) 64 { 65 + int err; 66 67 + if (sbi_debug_console_available) { 68 + err = PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_dbcn_ops, 256)); 69 + if (err) 70 + return err; 71 + hvc_instantiate(0, 0, &hvc_sbi_dbcn_ops); 72 + } else if (IS_ENABLED(CONFIG_RISCV_SBI_V01)) { 73 + err = PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_v01_ops, 256)); 74 + if (err) 75 + return err; 76 + hvc_instantiate(0, 0, &hvc_sbi_v01_ops); 77 + } else { 78 + return -ENODEV; 79 + } 80 81 return 0; 82 } 83 + device_initcall(hvc_sbi_init);
+1 -1
drivers/tty/serial/Kconfig
··· 87 88 config SERIAL_EARLYCON_RISCV_SBI 89 bool "Early console using RISC-V SBI" 90 - depends on RISCV_SBI_V01 91 select SERIAL_CORE 92 select SERIAL_CORE_CONSOLE 93 select SERIAL_EARLYCON
··· 87 88 config SERIAL_EARLYCON_RISCV_SBI 89 bool "Early console using RISC-V SBI" 90 + depends on RISCV_SBI 91 select SERIAL_CORE 92 select SERIAL_CORE_CONSOLE 93 select SERIAL_EARLYCON
+24 -3
drivers/tty/serial/earlycon-riscv-sbi.c
··· 15 sbi_console_putchar(c); 16 } 17 18 - static void sbi_console_write(struct console *con, 19 - const char *s, unsigned n) 20 { 21 struct earlycon_device *dev = con->data; 22 uart_console_write(&dev->port, s, n, sbi_putc); 23 } 24 25 static int __init early_sbi_setup(struct earlycon_device *device, 26 const char *opt) 27 { 28 - device->con->write = sbi_console_write; 29 return 0; 30 } 31 EARLYCON_DECLARE(sbi, early_sbi_setup);
··· 15 sbi_console_putchar(c); 16 } 17 18 + static void sbi_0_1_console_write(struct console *con, 19 + const char *s, unsigned int n) 20 { 21 struct earlycon_device *dev = con->data; 22 uart_console_write(&dev->port, s, n, sbi_putc); 23 } 24 25 + static void sbi_dbcn_console_write(struct console *con, 26 + const char *s, unsigned int n) 27 + { 28 + int ret; 29 + 30 + while (n) { 31 + ret = sbi_debug_console_write(s, n); 32 + if (ret < 0) 33 + break; 34 + 35 + s += ret; 36 + n -= ret; 37 + } 38 + } 39 + 40 static int __init early_sbi_setup(struct earlycon_device *device, 41 const char *opt) 42 { 43 + if (sbi_debug_console_available) 44 + device->con->write = sbi_dbcn_console_write; 45 + else if (IS_ENABLED(CONFIG_RISCV_SBI_V01)) 46 + device->con->write = sbi_0_1_console_write; 47 + else 48 + return -ENODEV; 49 + 50 return 0; 51 } 52 EARLYCON_DECLARE(sbi, early_sbi_setup);
+3 -3
include/asm-generic/checksum.h
··· 2 #ifndef __ASM_GENERIC_CHECKSUM_H 3 #define __ASM_GENERIC_CHECKSUM_H 4 5 /* 6 * computes the checksum of a memory block at buff, length len, 7 * and adds in "sum" (32-bit) ··· 33 static inline __sum16 csum_fold(__wsum csum) 34 { 35 u32 sum = (__force u32)csum; 36 - sum = (sum & 0xffff) + (sum >> 16); 37 - sum = (sum & 0xffff) + (sum >> 16); 38 - return (__force __sum16)~sum; 39 } 40 #endif 41
··· 2 #ifndef __ASM_GENERIC_CHECKSUM_H 3 #define __ASM_GENERIC_CHECKSUM_H 4 5 + #include <linux/bitops.h> 6 + 7 /* 8 * computes the checksum of a memory block at buff, length len, 9 * and adds in "sum" (32-bit) ··· 31 static inline __sum16 csum_fold(__wsum csum) 32 { 33 u32 sum = (__force u32)csum; 34 + return (__force __sum16)((~sum - ror32(sum, 16)) >> 16); 35 } 36 #endif 37
+7 -5
lib/Kconfig.debug
··· 231 in the "Debug information" choice below, indicating that debug 232 information will be generated for build targets. 233 234 - # Clang is known to generate .{s,u}leb128 with symbol deltas with DWARF5, which 235 - # some targets may not support: https://sourceware.org/bugzilla/show_bug.cgi?id=27215 236 - config AS_HAS_NON_CONST_LEB128 237 def_bool $(as-instr,.uleb128 .Lexpr_end4 - .Lexpr_start3\n.Lexpr_start3:\n.Lexpr_end4:) 238 239 choice ··· 259 config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT 260 bool "Rely on the toolchain's implicit default DWARF version" 261 select DEBUG_INFO 262 - depends on !CC_IS_CLANG || AS_IS_LLVM || CLANG_VERSION < 140000 || (AS_IS_GNU && AS_VERSION >= 23502 && AS_HAS_NON_CONST_LEB128) 263 help 264 The implicit default version of DWARF debug info produced by a 265 toolchain changes over time. ··· 283 config DEBUG_INFO_DWARF5 284 bool "Generate DWARF Version 5 debuginfo" 285 select DEBUG_INFO 286 - depends on !CC_IS_CLANG || AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502 && AS_HAS_NON_CONST_LEB128) 287 help 288 Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc 289 5.0+ accepts the -gdwarf-5 flag but only had partial support for some
··· 231 in the "Debug information" choice below, indicating that debug 232 information will be generated for build targets. 233 234 + # Clang generates .uleb128 with label differences for DWARF v5, a feature that 235 + # older binutils ports do not support when utilizing RISC-V style linker 236 + # relaxation: https://sourceware.org/bugzilla/show_bug.cgi?id=27215 237 + config AS_HAS_NON_CONST_ULEB128 238 def_bool $(as-instr,.uleb128 .Lexpr_end4 - .Lexpr_start3\n.Lexpr_start3:\n.Lexpr_end4:) 239 240 choice ··· 258 config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT 259 bool "Rely on the toolchain's implicit default DWARF version" 260 select DEBUG_INFO 261 + depends on !CC_IS_CLANG || AS_IS_LLVM || CLANG_VERSION < 140000 || (AS_IS_GNU && AS_VERSION >= 23502 && AS_HAS_NON_CONST_ULEB128) 262 help 263 The implicit default version of DWARF debug info produced by a 264 toolchain changes over time. ··· 282 config DEBUG_INFO_DWARF5 283 bool "Generate DWARF Version 5 debuginfo" 284 select DEBUG_INFO 285 + depends on !ARCH_HAS_BROKEN_DWARF5 286 + depends on !CC_IS_CLANG || AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502 && AS_HAS_NON_CONST_ULEB128) 287 help 288 Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc 289 5.0+ accepts the -gdwarf-5 flag but only had partial support for some
+285 -1
lib/checksum_kunit.c
··· 1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 - * Test cases csum_partial and csum_fold 4 */ 5 6 #include <kunit/test.h> 7 #include <asm/checksum.h> 8 9 #define MAX_LEN 512 10 #define MAX_ALIGN 64 11 #define TEST_BUFLEN (MAX_LEN + MAX_ALIGN) 12 13 /* Values for a little endian CPU. Byte swap each half on big endian CPU. */ 14 static const u32 random_init_sum = 0x2847aab; ··· 215 0xffff0000, 0xfffffffb, 216 }; 217 218 static u8 tmp_buf[TEST_BUFLEN]; 219 220 #define full_csum(buff, len, sum) csum_fold(csum_partial(buff, len, sum)) ··· 575 } 576 } 577 578 static struct kunit_case __refdata checksum_test_cases[] = { 579 KUNIT_CASE(test_csum_fixed_random_inputs), 580 KUNIT_CASE(test_csum_all_carry_inputs), 581 KUNIT_CASE(test_csum_no_carry_inputs), 582 {} 583 }; 584
··· 1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 + * Test cases csum_partial, csum_fold, ip_fast_csum, csum_ipv6_magic 4 */ 5 6 #include <kunit/test.h> 7 #include <asm/checksum.h> 8 + #include <net/ip6_checksum.h> 9 10 #define MAX_LEN 512 11 #define MAX_ALIGN 64 12 #define TEST_BUFLEN (MAX_LEN + MAX_ALIGN) 13 + 14 + #define IPv4_MIN_WORDS 5 15 + #define IPv4_MAX_WORDS 15 16 + #define NUM_IPv6_TESTS 200 17 + #define NUM_IP_FAST_CSUM_TESTS 181 18 19 /* Values for a little endian CPU. Byte swap each half on big endian CPU. */ 20 static const u32 random_init_sum = 0x2847aab; ··· 209 0xffff0000, 0xfffffffb, 210 }; 211 212 + static const __sum16 expected_csum_ipv6_magic[] = { 213 + 0x18d4, 0x3085, 0x2e4b, 0xd9f4, 0xbdc8, 0x78f, 0x1034, 0x8422, 0x6fc0, 214 + 0xd2f6, 0xbeb5, 0x9d3, 0x7e2a, 0x312e, 0x778e, 0xc1bb, 0x7cf2, 0x9d1e, 215 + 0xca21, 0xf3ff, 0x7569, 0xb02e, 0xca86, 0x7e76, 0x4539, 0x45e3, 0xf28d, 216 + 0xdf81, 0x8fd5, 0x3b5d, 0x8324, 0xf471, 0x83be, 0x1daf, 0x8c46, 0xe682, 217 + 0xd1fb, 0x6b2e, 0xe687, 0x2a33, 0x4833, 0x2d67, 0x660f, 0x2e79, 0xd65e, 218 + 0x6b62, 0x6672, 0x5dbd, 0x8680, 0xbaa5, 0x2229, 0x2125, 0x2d01, 0x1cc0, 219 + 0x6d36, 0x33c0, 0xee36, 0xd832, 0x9820, 0x8a31, 0x53c5, 0x2e2, 0xdb0e, 220 + 0x49ed, 0x17a7, 0x77a0, 0xd72e, 0x3d72, 0x7dc8, 0x5b17, 0xf55d, 0xa4d9, 221 + 0x1446, 0x5d56, 0x6b2e, 0x69a5, 0xadb6, 0xff2a, 0x92e, 0xe044, 0x3402, 222 + 0xbb60, 0xec7f, 0xe7e6, 0x1986, 0x32f4, 0x8f8, 0x5e00, 0x47c6, 0x3059, 223 + 0x3969, 0xe957, 0x4388, 0x2854, 0x3334, 0xea71, 0xa6de, 0x33f9, 0x83fc, 224 + 0x37b4, 0x5531, 0x3404, 0x1010, 0xed30, 0x610a, 0xc95, 0x9aed, 0x6ff, 225 + 0x5136, 0x2741, 0x660e, 0x8b80, 0xf71, 0xa263, 0x88af, 0x7a73, 0x3c37, 226 + 0x1908, 0x6db5, 0x2e92, 0x1cd2, 0x70c8, 0xee16, 0xe80, 0xcd55, 0x6e6, 227 + 0x6434, 0x127, 0x655d, 0x2ea0, 0xb4f4, 0xdc20, 0x5671, 0xe462, 0xe52b, 228 + 0xdb44, 0x3589, 0xc48f, 0xe60b, 0xd2d2, 0x66ad, 0x498, 0x436, 0xb917, 229 + 0xf0ca, 0x1a6e, 0x1cb7, 0xbf61, 0x2870, 0xc7e8, 0x5b30, 0xe4a5, 0x168, 230 + 0xadfc, 0xd035, 0xe690, 0xe283, 0xfb27, 0xe4ad, 0xb1a5, 0xf2d5, 0xc4b6, 231 + 0x8a30, 0xd7d5, 0x7df9, 0x91d5, 0x63ed, 0x2d21, 0x312b, 0xab19, 0xa632, 232 + 0x8d2e, 0xef06, 0x57b9, 0xc373, 0xbd1f, 0xa41f, 0x8444, 0x9975, 0x90cb, 233 + 0xc49c, 0xe965, 0x4eff, 0x5a, 0xef6d, 0xe81a, 0xe260, 0x853a, 0xff7a, 234 + 0x99aa, 0xb06b, 0xee19, 0xcc2c, 0xf34c, 0x7c49, 0xdac3, 0xa71e, 0xc988, 235 + 0x3845, 0x1014 236 + }; 237 + 238 + static const __sum16 expected_fast_csum[] = { 239 + 0xda83, 0x45da, 0x4f46, 0x4e4f, 0x34e, 0xe902, 0xa5e9, 0x87a5, 0x7187, 240 + 0x5671, 0xf556, 0x6df5, 0x816d, 0x8f81, 0xbb8f, 0xfbba, 0x5afb, 0xbe5a, 241 + 0xedbe, 0xabee, 0x6aac, 0xe6b, 0xea0d, 0x67ea, 0x7e68, 0x8a7e, 0x6f8a, 242 + 0x3a70, 0x9f3a, 0xe89e, 0x75e8, 0x7976, 0xfa79, 0x2cfa, 0x3c2c, 0x463c, 243 + 0x7146, 0x7a71, 0x547a, 0xfd53, 0x99fc, 0xb699, 0x92b6, 0xdb91, 0xe8da, 244 + 0x5fe9, 0x1e60, 0xae1d, 0x39ae, 0xf439, 0xa1f4, 0xdda1, 0xede, 0x790f, 245 + 0x579, 0x1206, 0x9012, 0x2490, 0xd224, 0x5cd2, 0xa65d, 0xca7, 0x220d, 246 + 0xf922, 0xbf9, 0x920b, 0x1b92, 0x361c, 0x2e36, 0x4d2e, 0x24d, 0x2, 247 + 0xcfff, 0x90cf, 0xa591, 0x93a5, 0x7993, 0x9579, 0xc894, 0x50c8, 0x5f50, 248 + 0xd55e, 0xcad5, 0xf3c9, 0x8f4, 0x4409, 0x5043, 0x5b50, 0x55b, 0x2205, 249 + 0x1e22, 0x801e, 0x3780, 0xe137, 0x7ee0, 0xf67d, 0x3cf6, 0xa53c, 0x2ea5, 250 + 0x472e, 0x5147, 0xcf51, 0x1bcf, 0x951c, 0x1e95, 0xc71e, 0xe4c7, 0xc3e4, 251 + 0x3dc3, 0xee3d, 0xa4ed, 0xf9a4, 0xcbf8, 0x75cb, 0xb375, 0x50b4, 0x3551, 252 + 0xf835, 0x19f8, 0x8c1a, 0x538c, 0xad52, 0xa3ac, 0xb0a3, 0x5cb0, 0x6c5c, 253 + 0x5b6c, 0xc05a, 0x92c0, 0x4792, 0xbe47, 0x53be, 0x1554, 0x5715, 0x4b57, 254 + 0xe54a, 0x20e5, 0x21, 0xd500, 0xa1d4, 0xa8a1, 0x57a9, 0xca57, 0x5ca, 255 + 0x1c06, 0x4f1c, 0xe24e, 0xd9e2, 0xf0d9, 0x4af1, 0x474b, 0x8146, 0xe81, 256 + 0xfd0e, 0x84fd, 0x7c85, 0xba7c, 0x17ba, 0x4a17, 0x964a, 0xf595, 0xff5, 257 + 0x5310, 0x3253, 0x6432, 0x4263, 0x2242, 0xe121, 0x32e1, 0xf632, 0xc5f5, 258 + 0x21c6, 0x7d22, 0x8e7c, 0x418e, 0x5641, 0x3156, 0x7c31, 0x737c, 0x373, 259 + 0x2503, 0xc22a, 0x3c2, 0x4a04, 0x8549, 0x5285, 0xa352, 0xe8a3, 0x6fe8, 260 + 0x1a6f, 0x211a, 0xe021, 0x38e0, 0x7638, 0xf575, 0x9df5, 0x169e, 0xf116, 261 + 0x23f1, 0xcd23, 0xece, 0x660f, 0x4866, 0x6a48, 0x716a, 0xee71, 0xa2ee, 262 + 0xb8a2, 0x61b9, 0xa361, 0xf7a2, 0x26f7, 0x1127, 0x6611, 0xe065, 0x36e0, 263 + 0x1837, 0x3018, 0x1c30, 0x721b, 0x3e71, 0xe43d, 0x99e4, 0x9e9a, 0xb79d, 264 + 0xa9b7, 0xcaa, 0xeb0c, 0x4eb, 0x1305, 0x8813, 0xb687, 0xa9b6, 0xfba9, 265 + 0xd7fb, 0xccd8, 0x2ecd, 0x652f, 0xae65, 0x3fae, 0x3a40, 0x563a, 0x7556, 266 + 0x2776, 0x1228, 0xef12, 0xf9ee, 0xcef9, 0x56cf, 0xa956, 0x24a9, 0xba24, 267 + 0x5fba, 0x665f, 0xf465, 0x8ff4, 0x6d8f, 0x346d, 0x5f34, 0x385f, 0xd137, 268 + 0xb8d0, 0xacb8, 0x55ac, 0x7455, 0xe874, 0x89e8, 0xd189, 0xa0d1, 0xb2a0, 269 + 0xb8b2, 0x36b8, 0x5636, 0xd355, 0x8d3, 0x1908, 0x2118, 0xc21, 0x990c, 270 + 0x8b99, 0x158c, 0x7815, 0x9e78, 0x6f9e, 0x4470, 0x1d44, 0x341d, 0x2634, 271 + 0x3f26, 0x793e, 0xc79, 0xcc0b, 0x26cc, 0xd126, 0x1fd1, 0xb41f, 0xb6b4, 272 + 0x22b7, 0xa122, 0xa1, 0x7f01, 0x837e, 0x3b83, 0xaf3b, 0x6fae, 0x916f, 273 + 0xb490, 0xffb3, 0xceff, 0x50cf, 0x7550, 0x7275, 0x1272, 0x2613, 0xaa26, 274 + 0xd5aa, 0x7d5, 0x9607, 0x96, 0xb100, 0xf8b0, 0x4bf8, 0xdd4c, 0xeddd, 275 + 0x98ed, 0x2599, 0x9325, 0xeb92, 0x8feb, 0xcc8f, 0x2acd, 0x392b, 0x3b39, 276 + 0xcb3b, 0x6acb, 0xd46a, 0xb8d4, 0x6ab8, 0x106a, 0x2f10, 0x892f, 0x789, 277 + 0xc806, 0x45c8, 0x7445, 0x3c74, 0x3a3c, 0xcf39, 0xd7ce, 0x58d8, 0x6e58, 278 + 0x336e, 0x1034, 0xee10, 0xe9ed, 0xc2e9, 0x3fc2, 0xd53e, 0xd2d4, 0xead2, 279 + 0x8fea, 0x2190, 0x1162, 0xbe11, 0x8cbe, 0x6d8c, 0xfb6c, 0x6dfb, 0xd36e, 280 + 0x3ad3, 0xf3a, 0x870e, 0xc287, 0x53c3, 0xc54, 0x5b0c, 0x7d5a, 0x797d, 281 + 0xec79, 0x5dec, 0x4d5e, 0x184e, 0xd618, 0x60d6, 0xb360, 0x98b3, 0xf298, 282 + 0xb1f2, 0x69b1, 0xf969, 0xef9, 0xab0e, 0x21ab, 0xe321, 0x24e3, 0x8224, 283 + 0x5481, 0x5954, 0x7a59, 0xff7a, 0x7dff, 0x1a7d, 0xa51a, 0x46a5, 0x6b47, 284 + 0xe6b, 0x830e, 0xa083, 0xff9f, 0xd0ff, 0xffd0, 0xe6ff, 0x7de7, 0xc67d, 285 + 0xd0c6, 0x61d1, 0x3a62, 0xc3b, 0x150c, 0x1715, 0x4517, 0x5345, 0x3954, 286 + 0xdd39, 0xdadd, 0x32db, 0x6a33, 0xd169, 0x86d1, 0xb687, 0x3fb6, 0x883f, 287 + 0xa487, 0x39a4, 0x2139, 0xbe20, 0xffbe, 0xedfe, 0x8ded, 0x368e, 0xc335, 288 + 0x51c3, 0x9851, 0xf297, 0xd6f2, 0xb9d6, 0x95ba, 0x2096, 0xea1f, 0x76e9, 289 + 0x4e76, 0xe04d, 0xd0df, 0x80d0, 0xa280, 0xfca2, 0x75fc, 0xef75, 0x32ef, 290 + 0x6833, 0xdf68, 0xc4df, 0x76c4, 0xb77, 0xb10a, 0xbfb1, 0x58bf, 0x5258, 291 + 0x4d52, 0x6c4d, 0x7e6c, 0xb67e, 0xccb5, 0x8ccc, 0xbe8c, 0xc8bd, 0x9ac8, 292 + 0xa99b, 0x52a9, 0x2f53, 0xc30, 0x3e0c, 0xb83d, 0x83b7, 0x5383, 0x7e53, 293 + 0x4f7e, 0xe24e, 0xb3e1, 0x8db3, 0x618e, 0xc861, 0xfcc8, 0x34fc, 0x9b35, 294 + 0xaa9b, 0xb1aa, 0x5eb1, 0x395e, 0x8639, 0xd486, 0x8bd4, 0x558b, 0x2156, 295 + 0xf721, 0x4ef6, 0x14f, 0x7301, 0xdd72, 0x49de, 0x894a, 0x9889, 0x8898, 296 + 0x7788, 0x7b77, 0x637b, 0xb963, 0xabb9, 0x7cab, 0xc87b, 0x21c8, 0xcb21, 297 + 0xdfca, 0xbfdf, 0xf2bf, 0x6af2, 0x626b, 0xb261, 0x3cb2, 0xc63c, 0xc9c6, 298 + 0xc9c9, 0xb4c9, 0xf9b4, 0x91f9, 0x4091, 0x3a40, 0xcc39, 0xd1cb, 0x7ed1, 299 + 0x537f, 0x6753, 0xa167, 0xba49, 0x88ba, 0x7789, 0x3877, 0xf037, 0xd3ef, 300 + 0xb5d4, 0x55b6, 0xa555, 0xeca4, 0xa1ec, 0xb6a2, 0x7b7, 0x9507, 0xfd94, 301 + 0x82fd, 0x5c83, 0x765c, 0x9676, 0x3f97, 0xda3f, 0x6fda, 0x646f, 0x3064, 302 + 0x5e30, 0x655e, 0x6465, 0xcb64, 0xcdca, 0x4ccd, 0x3f4c, 0x243f, 0x6f24, 303 + 0x656f, 0x6065, 0x3560, 0x3b36, 0xac3b, 0x4aac, 0x714a, 0x7e71, 0xda7e, 304 + 0x7fda, 0xda7f, 0x6fda, 0xff6f, 0xc6ff, 0xedc6, 0xd4ed, 0x70d5, 0xeb70, 305 + 0xa3eb, 0x80a3, 0xca80, 0x3fcb, 0x2540, 0xf825, 0x7ef8, 0xf87e, 0x73f8, 306 + 0xb474, 0xb4b4, 0x92b5, 0x9293, 0x93, 0x3500, 0x7134, 0x9071, 0xfa8f, 307 + 0x51fa, 0x1452, 0xba13, 0x7ab9, 0x957a, 0x8a95, 0x6e8a, 0x6d6e, 0x7c6d, 308 + 0x447c, 0x9744, 0x4597, 0x8945, 0xef88, 0x8fee, 0x3190, 0x4831, 0x8447, 309 + 0xa183, 0x1da1, 0xd41d, 0x2dd4, 0x4f2e, 0xc94e, 0xcbc9, 0xc9cb, 0x9ec9, 310 + 0x319e, 0xd531, 0x20d5, 0x4021, 0xb23f, 0x29b2, 0xd828, 0xecd8, 0x5ded, 311 + 0xfc5d, 0x4dfc, 0xd24d, 0x6bd2, 0x5f6b, 0xb35e, 0x7fb3, 0xee7e, 0x56ee, 312 + 0xa657, 0x68a6, 0x8768, 0x7787, 0xb077, 0x4cb1, 0x764c, 0xb175, 0x7b1, 313 + 0x3d07, 0x603d, 0x3560, 0x3e35, 0xb03d, 0xd6b0, 0xc8d6, 0xd8c8, 0x8bd8, 314 + 0x3e8c, 0x303f, 0xd530, 0xf1d4, 0x42f1, 0xca42, 0xddca, 0x41dd, 0x3141, 315 + 0x132, 0xe901, 0x8e9, 0xbe09, 0xe0bd, 0x2ce0, 0x862d, 0x3986, 0x9139, 316 + 0x6d91, 0x6a6d, 0x8d6a, 0x1b8d, 0xac1b, 0xedab, 0x54ed, 0xc054, 0xcebf, 317 + 0xc1ce, 0x5c2, 0x3805, 0x6038, 0x5960, 0xd359, 0xdd3, 0xbe0d, 0xafbd, 318 + 0x6daf, 0x206d, 0x2c20, 0x862c, 0x8e86, 0xec8d, 0xa2ec, 0xa3a2, 0x51a3, 319 + 0x8051, 0xfd7f, 0x91fd, 0xa292, 0xaf14, 0xeeae, 0x59ef, 0x535a, 0x8653, 320 + 0x3986, 0x9539, 0xb895, 0xa0b8, 0x26a0, 0x2227, 0xc022, 0x77c0, 0xad77, 321 + 0x46ad, 0xaa46, 0x60aa, 0x8560, 0x4785, 0xd747, 0x45d7, 0x2346, 0x5f23, 322 + 0x25f, 0x1d02, 0x71d, 0x8206, 0xc82, 0x180c, 0x3018, 0x4b30, 0x4b, 323 + 0x3001, 0x1230, 0x2d12, 0x8c2d, 0x148d, 0x4015, 0x5f3f, 0x3d5f, 0x6b3d, 324 + 0x396b, 0x473a, 0xf746, 0x44f7, 0x8945, 0x3489, 0xcb34, 0x84ca, 0xd984, 325 + 0xf0d9, 0xbcf0, 0x63bd, 0x3264, 0xf332, 0x45f3, 0x7346, 0x5673, 0xb056, 326 + 0xd3b0, 0x4ad4, 0x184b, 0x7d18, 0x6c7d, 0xbb6c, 0xfeba, 0xe0fe, 0x10e1, 327 + 0x5410, 0x2954, 0x9f28, 0x3a9f, 0x5a3a, 0xdb59, 0xbdc, 0xb40b, 0x1ab4, 328 + 0x131b, 0x5d12, 0x6d5c, 0xe16c, 0xb0e0, 0x89b0, 0xba88, 0xbb, 0x3c01, 329 + 0xe13b, 0x6fe1, 0x446f, 0xa344, 0x81a3, 0xfe81, 0xc7fd, 0x38c8, 0xb38, 330 + 0x1a0b, 0x6d19, 0xf36c, 0x47f3, 0x6d48, 0xb76d, 0xd3b7, 0xd8d2, 0x52d9, 331 + 0x4b53, 0xa54a, 0x34a5, 0xc534, 0x9bc4, 0xed9b, 0xbeed, 0x3ebe, 0x233e, 332 + 0x9f22, 0x4a9f, 0x774b, 0x4577, 0xa545, 0x64a5, 0xb65, 0x870b, 0x487, 333 + 0x9204, 0x5f91, 0xd55f, 0x35d5, 0x1a35, 0x71a, 0x7a07, 0x4e7a, 0xfc4e, 334 + 0x1efc, 0x481f, 0x7448, 0xde74, 0xa7dd, 0x1ea7, 0xaa1e, 0xcfaa, 0xfbcf, 335 + 0xedfb, 0x6eee, 0x386f, 0x4538, 0x6e45, 0xd96d, 0x11d9, 0x7912, 0x4b79, 336 + 0x494b, 0x6049, 0xac5f, 0x65ac, 0x1366, 0x5913, 0xe458, 0x7ae4, 0x387a, 337 + 0x3c38, 0xb03c, 0x76b0, 0x9376, 0xe193, 0x42e1, 0x7742, 0x6476, 0x3564, 338 + 0x3c35, 0x6a3c, 0xcc69, 0x94cc, 0x5d95, 0xe5e, 0xee0d, 0x4ced, 0xce4c, 339 + 0x52ce, 0xaa52, 0xdaaa, 0xe4da, 0x1de5, 0x4530, 0x5445, 0x3954, 0xb639, 340 + 0x81b6, 0x7381, 0x1574, 0xc215, 0x10c2, 0x3f10, 0x6b3f, 0xe76b, 0x7be7, 341 + 0xbc7b, 0xf7bb, 0x41f7, 0xcc41, 0x38cc, 0x4239, 0xa942, 0x4a9, 0xc504, 342 + 0x7cc4, 0x437c, 0x6743, 0xea67, 0x8dea, 0xe88d, 0xd8e8, 0xdcd8, 0x17dd, 343 + 0x5718, 0x958, 0xa609, 0x41a5, 0x5842, 0x159, 0x9f01, 0x269f, 0x5a26, 344 + 0x405a, 0xc340, 0xb4c3, 0xd4b4, 0xf4d3, 0xf1f4, 0x39f2, 0xe439, 0x67e4, 345 + 0x4168, 0xa441, 0xdda3, 0xdedd, 0x9df, 0xab0a, 0xa5ab, 0x9a6, 0xba09, 346 + 0x9ab9, 0xad9a, 0x5ae, 0xe205, 0xece2, 0xecec, 0x14ed, 0xd614, 0x6bd5, 347 + 0x916c, 0x3391, 0x6f33, 0x206f, 0x8020, 0x780, 0x7207, 0x2472, 0x8a23, 348 + 0xb689, 0x3ab6, 0xf739, 0x97f6, 0xb097, 0xa4b0, 0xe6a4, 0x88e6, 0x2789, 349 + 0xb28, 0x350b, 0x1f35, 0x431e, 0x1043, 0xc30f, 0x79c3, 0x379, 0x5703, 350 + 0x3256, 0x4732, 0x7247, 0x9d72, 0x489d, 0xd348, 0xa4d3, 0x7ca4, 0xbf7b, 351 + 0x45c0, 0x7b45, 0x337b, 0x4034, 0x843f, 0xd083, 0x35d0, 0x6335, 0x4d63, 352 + 0xe14c, 0xcce0, 0xfecc, 0x35ff, 0x5636, 0xf856, 0xeef8, 0x2def, 0xfc2d, 353 + 0x4fc, 0x6e04, 0xb66d, 0x78b6, 0xbb78, 0x3dbb, 0x9a3d, 0x839a, 0x9283, 354 + 0x593, 0xd504, 0x23d5, 0x5424, 0xd054, 0x61d0, 0xdb61, 0x17db, 0x1f18, 355 + 0x381f, 0x9e37, 0x679e, 0x1d68, 0x381d, 0x8038, 0x917f, 0x491, 0xbb04, 356 + 0x23bb, 0x4124, 0xd41, 0xa30c, 0x8ba3, 0x8b8b, 0xc68b, 0xd2c6, 0xebd2, 357 + 0x93eb, 0xbd93, 0x99bd, 0x1a99, 0xea19, 0x58ea, 0xcf58, 0x73cf, 0x1073, 358 + 0x9e10, 0x139e, 0xea13, 0xcde9, 0x3ecd, 0x883f, 0xf89, 0x180f, 0x2a18, 359 + 0x212a, 0xce20, 0x73ce, 0xf373, 0x60f3, 0xad60, 0x4093, 0x8e40, 0xb98e, 360 + 0xbfb9, 0xf1bf, 0x8bf1, 0x5e8c, 0xe95e, 0x14e9, 0x4e14, 0x1c4e, 0x7f1c, 361 + 0xe77e, 0x6fe7, 0xf26f, 0x13f2, 0x8b13, 0xda8a, 0x5fda, 0xea5f, 0x4eea, 362 + 0xa84f, 0x88a8, 0x1f88, 0x2820, 0x9728, 0x5a97, 0x3f5b, 0xb23f, 0x70b2, 363 + 0x2c70, 0x232d, 0xf623, 0x4f6, 0x905, 0x7509, 0xd675, 0x28d7, 0x9428, 364 + 0x3794, 0xf036, 0x2bf0, 0xba2c, 0xedb9, 0xd7ed, 0x59d8, 0xed59, 0x4ed, 365 + 0xe304, 0x18e3, 0x5c19, 0x3d5c, 0x753d, 0x6d75, 0x956d, 0x7f95, 0xc47f, 366 + 0x83c4, 0xa84, 0x2e0a, 0x5f2e, 0xb95f, 0x77b9, 0x6d78, 0xf46d, 0x1bf4, 367 + 0xed1b, 0xd6ed, 0xe0d6, 0x5e1, 0x3905, 0x5638, 0xa355, 0x99a2, 0xbe99, 368 + 0xb4bd, 0x85b4, 0x2e86, 0x542e, 0x6654, 0xd765, 0x73d7, 0x3a74, 0x383a, 369 + 0x2638, 0x7826, 0x7677, 0x9a76, 0x7e99, 0x2e7e, 0xea2d, 0xa6ea, 0x8a7, 370 + 0x109, 0x3300, 0xad32, 0x5fad, 0x465f, 0x2f46, 0xc62f, 0xd4c5, 0xad5, 371 + 0xcb0a, 0x4cb, 0xb004, 0x7baf, 0xe47b, 0x92e4, 0x8e92, 0x638e, 0x1763, 372 + 0xc17, 0xf20b, 0x1ff2, 0x8920, 0x5889, 0xcb58, 0xf8cb, 0xcaf8, 0x84cb, 373 + 0x9f84, 0x8a9f, 0x918a, 0x4991, 0x8249, 0xff81, 0x46ff, 0x5046, 0x5f50, 374 + 0x725f, 0xf772, 0x8ef7, 0xe08f, 0xc1e0, 0x1fc2, 0x9e1f, 0x8b9d, 0x108b, 375 + 0x411, 0x2b04, 0xb02a, 0x1fb0, 0x1020, 0x7a0f, 0x587a, 0x8958, 0xb188, 376 + 0xb1b1, 0x49b2, 0xb949, 0x7ab9, 0x917a, 0xfc91, 0xe6fc, 0x47e7, 0xbc47, 377 + 0x8fbb, 0xea8e, 0x34ea, 0x2635, 0x1726, 0x9616, 0xc196, 0xa6c1, 0xf3a6, 378 + 0x11f3, 0x4811, 0x3e48, 0xeb3e, 0xf7ea, 0x1bf8, 0xdb1c, 0x8adb, 0xe18a, 379 + 0x42e1, 0x9d42, 0x5d9c, 0x6e5d, 0x286e, 0x4928, 0x9a49, 0xb09c, 0xa6b0, 380 + 0x2a7, 0xe702, 0xf5e6, 0x9af5, 0xf9b, 0x810f, 0x8080, 0x180, 0x1702, 381 + 0x5117, 0xa650, 0x11a6, 0x1011, 0x550f, 0xd554, 0xbdd5, 0x6bbe, 0xc66b, 382 + 0xfc7, 0x5510, 0x5555, 0x7655, 0x177, 0x2b02, 0x6f2a, 0xb70, 0x9f0b, 383 + 0xcf9e, 0xf3cf, 0x3ff4, 0xcb40, 0x8ecb, 0x768e, 0x5277, 0x8652, 0x9186, 384 + 0x9991, 0x5099, 0xd350, 0x93d3, 0x6d94, 0xe6d, 0x530e, 0x3153, 0xa531, 385 + 0x64a5, 0x7964, 0x7c79, 0x467c, 0x1746, 0x3017, 0x3730, 0x538, 0x5, 386 + 0x1e00, 0x5b1e, 0x955a, 0xae95, 0x3eaf, 0xff3e, 0xf8ff, 0xb2f9, 0xa1b3, 387 + 0xb2a1, 0x5b2, 0xad05, 0x7cac, 0x2d7c, 0xd32c, 0x80d2, 0x7280, 0x8d72, 388 + 0x1b8e, 0x831b, 0xac82, 0xfdac, 0xa7fd, 0x15a8, 0xd614, 0xe0d5, 0x7be0, 389 + 0xb37b, 0x61b3, 0x9661, 0x9d95, 0xc79d, 0x83c7, 0xd883, 0xead7, 0xceb, 390 + 0xf60c, 0xa9f5, 0x19a9, 0xa019, 0x8f9f, 0xd48f, 0x3ad5, 0x853a, 0x985, 391 + 0x5309, 0x6f52, 0x1370, 0x6e13, 0xa96d, 0x98a9, 0x5198, 0x9f51, 0xb69f, 392 + 0xa1b6, 0x2ea1, 0x672e, 0x2067, 0x6520, 0xaf65, 0x6eaf, 0x7e6f, 0xee7e, 393 + 0x17ef, 0xa917, 0xcea8, 0x9ace, 0xff99, 0x5dff, 0xdf5d, 0x38df, 0xa39, 394 + 0x1c0b, 0xe01b, 0x46e0, 0xcb46, 0x90cb, 0xba90, 0x4bb, 0x9104, 0x9d90, 395 + 0xc89c, 0xf6c8, 0x6cf6, 0x886c, 0x1789, 0xbd17, 0x70bc, 0x7e71, 0x17e, 396 + 0x1f01, 0xa01f, 0xbaa0, 0x14bb, 0xfc14, 0x7afb, 0xa07a, 0x3da0, 0xbf3d, 397 + 0x48bf, 0x8c48, 0x968b, 0x9d96, 0xfd9d, 0x96fd, 0x9796, 0x6b97, 0xd16b, 398 + 0xf4d1, 0x3bf4, 0x253c, 0x9125, 0x6691, 0xc166, 0x34c1, 0x5735, 0x1a57, 399 + 0xdc19, 0x77db, 0x8577, 0x4a85, 0x824a, 0x9182, 0x7f91, 0xfd7f, 0xb4c3, 400 + 0xb5b4, 0xb3b5, 0x7eb3, 0x617e, 0x4e61, 0xa4f, 0x530a, 0x3f52, 0xa33e, 401 + 0x34a3, 0x9234, 0xf091, 0xf4f0, 0x1bf5, 0x311b, 0x9631, 0x6a96, 0x386b, 402 + 0x1d39, 0xe91d, 0xe8e9, 0x69e8, 0x426a, 0xee42, 0x89ee, 0x368a, 0x2837, 403 + 0x7428, 0x5974, 0x6159, 0x1d62, 0x7b1d, 0xf77a, 0x7bf7, 0x6b7c, 0x696c, 404 + 0xf969, 0x4cf9, 0x714c, 0x4e71, 0x6b4e, 0x256c, 0x6e25, 0xe96d, 0x94e9, 405 + 0x8f94, 0x3e8f, 0x343e, 0x4634, 0xb646, 0x97b5, 0x8997, 0xe8a, 0x900e, 406 + 0x8090, 0xfd80, 0xa0fd, 0x16a1, 0xf416, 0xebf4, 0x95ec, 0x1196, 0x8911, 407 + 0x3d89, 0xda3c, 0x9fd9, 0xd79f, 0x4bd7, 0x214c, 0x3021, 0x4f30, 0x994e, 408 + 0x5c99, 0x6f5d, 0x326f, 0xab31, 0x6aab, 0xe969, 0x90e9, 0x1190, 0xff10, 409 + 0xa2fe, 0xe0a2, 0x66e1, 0x4067, 0x9e3f, 0x2d9e, 0x712d, 0x8170, 0xd180, 410 + 0xffd1, 0x25ff, 0x3826, 0x2538, 0x5f24, 0xc45e, 0x1cc4, 0xdf1c, 0x93df, 411 + 0xc793, 0x80c7, 0x2380, 0xd223, 0x7ed2, 0xfc7e, 0x22fd, 0x7422, 0x1474, 412 + 0xb714, 0x7db6, 0x857d, 0xa85, 0xa60a, 0x88a6, 0x4289, 0x7842, 0xc278, 413 + 0xf7c2, 0xcdf7, 0x84cd, 0xae84, 0x8cae, 0xb98c, 0x1aba, 0x4d1a, 0x884c, 414 + 0x4688, 0xcc46, 0xd8cb, 0x2bd9, 0xbe2b, 0xa2be, 0x72a2, 0xf772, 0xd2f6, 415 + 0x75d2, 0xc075, 0xa3c0, 0x63a3, 0xae63, 0x8fae, 0x2a90, 0x5f2a, 0xef5f, 416 + 0x5cef, 0xa05c, 0x89a0, 0x5e89, 0x6b5e, 0x736b, 0x773, 0x9d07, 0xe99c, 417 + 0x27ea, 0x2028, 0xc20, 0x980b, 0x4797, 0x2848, 0x9828, 0xc197, 0x48c2, 418 + 0x2449, 0x7024, 0x570, 0x3e05, 0xd3e, 0xf60c, 0xbbf5, 0x69bb, 0x3f6a, 419 + 0x740, 0xf006, 0xe0ef, 0xbbe0, 0xadbb, 0x56ad, 0xcf56, 0xbfce, 0xa9bf, 420 + 0x205b, 0x6920, 0xae69, 0x50ae, 0x2050, 0xf01f, 0x27f0, 0x9427, 0x8993, 421 + 0x8689, 0x4087, 0x6e40, 0xb16e, 0xa1b1, 0xe8a1, 0x87e8, 0x6f88, 0xfe6f, 422 + 0x4cfe, 0xe94d, 0xd5e9, 0x47d6, 0x3148, 0x5f31, 0xc35f, 0x13c4, 0xa413, 423 + 0x5a5, 0x2405, 0xc223, 0x66c2, 0x3667, 0x5e37, 0x5f5e, 0x2f5f, 0x8c2f, 424 + 0xe48c, 0xd0e4, 0x4d1, 0xd104, 0xe4d0, 0xcee4, 0xfcf, 0x480f, 0xa447, 425 + 0x5ea4, 0xff5e, 0xbefe, 0x8dbe, 0x1d8e, 0x411d, 0x1841, 0x6918, 0x5469, 426 + 0x1155, 0xc611, 0xaac6, 0x37ab, 0x2f37, 0xca2e, 0x87ca, 0xbd87, 0xabbd, 427 + 0xb3ab, 0xcb4, 0xce0c, 0xfccd, 0xa5fd, 0x72a5, 0xf072, 0x83f0, 0xfe83, 428 + 0x97fd, 0xc997, 0xb0c9, 0xadb0, 0xe6ac, 0x88e6, 0x1088, 0xbe10, 0x16be, 429 + 0xa916, 0xa3a8, 0x46a3, 0x5447, 0xe953, 0x84e8, 0x2085, 0xa11f, 0xfa1, 430 + 0xdd0f, 0xbedc, 0x5abe, 0x805a, 0xc97f, 0x6dc9, 0x826d, 0x4a82, 0x934a, 431 + 0x5293, 0xd852, 0xd3d8, 0xadd3, 0xf4ad, 0xf3f4, 0xfcf3, 0xfefc, 0xcafe, 432 + 0xb7ca, 0x3cb8, 0xa13c, 0x18a1, 0x1418, 0xea13, 0x91ea, 0xf891, 0x53f8, 433 + 0xa254, 0xe9a2, 0x87ea, 0x4188, 0x1c41, 0xdc1b, 0xf5db, 0xcaf5, 0x45ca, 434 + 0x6d45, 0x396d, 0xde39, 0x90dd, 0x1e91, 0x1e, 0x7b00, 0x6a7b, 0xa46a, 435 + 0xc9a3, 0x9bc9, 0x389b, 0x1139, 0x5211, 0x1f52, 0xeb1f, 0xabeb, 0x48ab, 436 + 0x9348, 0xb392, 0x17b3, 0x1618, 0x5b16, 0x175b, 0xdc17, 0xdedb, 0x1cdf, 437 + 0xeb1c, 0xd1ea, 0x4ad2, 0xd4b, 0xc20c, 0x24c2, 0x7b25, 0x137b, 0x8b13, 438 + 0x618b, 0xa061, 0xff9f, 0xfffe, 0x72ff, 0xf572, 0xe2f5, 0xcfe2, 0xd2cf, 439 + 0x75d3, 0x6a76, 0xc469, 0x1ec4, 0xfc1d, 0x59fb, 0x455a, 0x7a45, 0xa479, 440 + 0xb7a4 441 + }; 442 + 443 static u8 tmp_buf[TEST_BUFLEN]; 444 445 #define full_csum(buff, len, sum) csum_fold(csum_partial(buff, len, sum)) ··· 338 } 339 } 340 341 + static void test_ip_fast_csum(struct kunit *test) 342 + { 343 + __sum16 csum_result, expected; 344 + 345 + for (int len = IPv4_MIN_WORDS; len < IPv4_MAX_WORDS; len++) { 346 + for (int index = 0; index < NUM_IP_FAST_CSUM_TESTS; index++) { 347 + csum_result = ip_fast_csum(random_buf + index, len); 348 + expected = 349 + expected_fast_csum[(len - IPv4_MIN_WORDS) * 350 + NUM_IP_FAST_CSUM_TESTS + 351 + index]; 352 + CHECK_EQ(expected, csum_result); 353 + } 354 + } 355 + } 356 + 357 + static void test_csum_ipv6_magic(struct kunit *test) 358 + { 359 + #if defined(CONFIG_NET) 360 + const struct in6_addr *saddr; 361 + const struct in6_addr *daddr; 362 + unsigned int len; 363 + unsigned char proto; 364 + unsigned int csum; 365 + 366 + const int daddr_offset = sizeof(struct in6_addr); 367 + const int len_offset = sizeof(struct in6_addr) + sizeof(struct in6_addr); 368 + const int proto_offset = sizeof(struct in6_addr) + sizeof(struct in6_addr) + 369 + sizeof(int); 370 + const int csum_offset = sizeof(struct in6_addr) + sizeof(struct in6_addr) + 371 + sizeof(int) + sizeof(char); 372 + 373 + for (int i = 0; i < NUM_IPv6_TESTS; i++) { 374 + saddr = (const struct in6_addr *)(random_buf + i); 375 + daddr = (const struct in6_addr *)(random_buf + i + 376 + daddr_offset); 377 + len = *(unsigned int *)(random_buf + i + len_offset); 378 + proto = *(random_buf + i + proto_offset); 379 + csum = *(unsigned int *)(random_buf + i + csum_offset); 380 + CHECK_EQ(expected_csum_ipv6_magic[i], 381 + csum_ipv6_magic(saddr, daddr, len, proto, csum)); 382 + } 383 + #endif /* !CONFIG_NET */ 384 + } 385 + 386 static struct kunit_case __refdata checksum_test_cases[] = { 387 KUNIT_CASE(test_csum_fixed_random_inputs), 388 KUNIT_CASE(test_csum_all_carry_inputs), 389 KUNIT_CASE(test_csum_no_carry_inputs), 390 + KUNIT_CASE(test_ip_fast_csum), 391 + KUNIT_CASE(test_csum_ipv6_magic), 392 {} 393 }; 394
+35
samples/ftrace/ftrace-direct-modify.c
··· 24 25 static unsigned long my_ip = (unsigned long)schedule; 26 27 #ifdef CONFIG_X86_64 28 29 #include <asm/ibt.h>
··· 24 25 static unsigned long my_ip = (unsigned long)schedule; 26 27 + #ifdef CONFIG_RISCV 28 + #include <asm/asm.h> 29 + 30 + asm ( 31 + " .pushsection .text, \"ax\", @progbits\n" 32 + " .type my_tramp1, @function\n" 33 + " .globl my_tramp1\n" 34 + " my_tramp1:\n" 35 + " addi sp,sp,-2*"SZREG"\n" 36 + " "REG_S" t0,0*"SZREG"(sp)\n" 37 + " "REG_S" ra,1*"SZREG"(sp)\n" 38 + " call my_direct_func1\n" 39 + " "REG_L" t0,0*"SZREG"(sp)\n" 40 + " "REG_L" ra,1*"SZREG"(sp)\n" 41 + " addi sp,sp,2*"SZREG"\n" 42 + " jr t0\n" 43 + " .size my_tramp1, .-my_tramp1\n" 44 + " .type my_tramp2, @function\n" 45 + " .globl my_tramp2\n" 46 + 47 + " my_tramp2:\n" 48 + " addi sp,sp,-2*"SZREG"\n" 49 + " "REG_S" t0,0*"SZREG"(sp)\n" 50 + " "REG_S" ra,1*"SZREG"(sp)\n" 51 + " call my_direct_func2\n" 52 + " "REG_L" t0,0*"SZREG"(sp)\n" 53 + " "REG_L" ra,1*"SZREG"(sp)\n" 54 + " addi sp,sp,2*"SZREG"\n" 55 + " jr t0\n" 56 + " .size my_tramp2, .-my_tramp2\n" 57 + " .popsection\n" 58 + ); 59 + 60 + #endif /* CONFIG_RISCV */ 61 + 62 #ifdef CONFIG_X86_64 63 64 #include <asm/ibt.h>
+41
samples/ftrace/ftrace-direct-multi-modify.c
··· 22 extern void my_tramp1(void *); 23 extern void my_tramp2(void *); 24 25 #ifdef CONFIG_X86_64 26 27 #include <asm/ibt.h>
··· 22 extern void my_tramp1(void *); 23 extern void my_tramp2(void *); 24 25 + #ifdef CONFIG_RISCV 26 + #include <asm/asm.h> 27 + 28 + asm ( 29 + " .pushsection .text, \"ax\", @progbits\n" 30 + " .type my_tramp1, @function\n" 31 + " .globl my_tramp1\n" 32 + " my_tramp1:\n" 33 + " addi sp,sp,-3*"SZREG"\n" 34 + " "REG_S" a0,0*"SZREG"(sp)\n" 35 + " "REG_S" t0,1*"SZREG"(sp)\n" 36 + " "REG_S" ra,2*"SZREG"(sp)\n" 37 + " mv a0,t0\n" 38 + " call my_direct_func1\n" 39 + " "REG_L" a0,0*"SZREG"(sp)\n" 40 + " "REG_L" t0,1*"SZREG"(sp)\n" 41 + " "REG_L" ra,2*"SZREG"(sp)\n" 42 + " addi sp,sp,3*"SZREG"\n" 43 + " jr t0\n" 44 + " .size my_tramp1, .-my_tramp1\n" 45 + 46 + " .type my_tramp2, @function\n" 47 + " .globl my_tramp2\n" 48 + " my_tramp2:\n" 49 + " addi sp,sp,-3*"SZREG"\n" 50 + " "REG_S" a0,0*"SZREG"(sp)\n" 51 + " "REG_S" t0,1*"SZREG"(sp)\n" 52 + " "REG_S" ra,2*"SZREG"(sp)\n" 53 + " mv a0,t0\n" 54 + " call my_direct_func2\n" 55 + " "REG_L" a0,0*"SZREG"(sp)\n" 56 + " "REG_L" t0,1*"SZREG"(sp)\n" 57 + " "REG_L" ra,2*"SZREG"(sp)\n" 58 + " addi sp,sp,3*"SZREG"\n" 59 + " jr t0\n" 60 + " .size my_tramp2, .-my_tramp2\n" 61 + " .popsection\n" 62 + ); 63 + 64 + #endif /* CONFIG_RISCV */ 65 + 66 #ifdef CONFIG_X86_64 67 68 #include <asm/ibt.h>
+25
samples/ftrace/ftrace-direct-multi.c
··· 17 18 extern void my_tramp(void *); 19 20 #ifdef CONFIG_X86_64 21 22 #include <asm/ibt.h>
··· 17 18 extern void my_tramp(void *); 19 20 + #ifdef CONFIG_RISCV 21 + #include <asm/asm.h> 22 + 23 + asm ( 24 + " .pushsection .text, \"ax\", @progbits\n" 25 + " .type my_tramp, @function\n" 26 + " .globl my_tramp\n" 27 + " my_tramp:\n" 28 + " addi sp,sp,-3*"SZREG"\n" 29 + " "REG_S" a0,0*"SZREG"(sp)\n" 30 + " "REG_S" t0,1*"SZREG"(sp)\n" 31 + " "REG_S" ra,2*"SZREG"(sp)\n" 32 + " mv a0,t0\n" 33 + " call my_direct_func\n" 34 + " "REG_L" a0,0*"SZREG"(sp)\n" 35 + " "REG_L" t0,1*"SZREG"(sp)\n" 36 + " "REG_L" ra,2*"SZREG"(sp)\n" 37 + " addi sp,sp,3*"SZREG"\n" 38 + " jr t0\n" 39 + " .size my_tramp, .-my_tramp\n" 40 + " .popsection\n" 41 + ); 42 + 43 + #endif /* CONFIG_RISCV */ 44 + 45 #ifdef CONFIG_X86_64 46 47 #include <asm/ibt.h>
+28
samples/ftrace/ftrace-direct-too.c
··· 19 20 extern void my_tramp(void *); 21 22 #ifdef CONFIG_X86_64 23 24 #include <asm/ibt.h>
··· 19 20 extern void my_tramp(void *); 21 22 + #ifdef CONFIG_RISCV 23 + #include <asm/asm.h> 24 + 25 + asm ( 26 + " .pushsection .text, \"ax\", @progbits\n" 27 + " .type my_tramp, @function\n" 28 + " .globl my_tramp\n" 29 + " my_tramp:\n" 30 + " addi sp,sp,-5*"SZREG"\n" 31 + " "REG_S" a0,0*"SZREG"(sp)\n" 32 + " "REG_S" a1,1*"SZREG"(sp)\n" 33 + " "REG_S" a2,2*"SZREG"(sp)\n" 34 + " "REG_S" t0,3*"SZREG"(sp)\n" 35 + " "REG_S" ra,4*"SZREG"(sp)\n" 36 + " call my_direct_func\n" 37 + " "REG_L" a0,0*"SZREG"(sp)\n" 38 + " "REG_L" a1,1*"SZREG"(sp)\n" 39 + " "REG_L" a2,2*"SZREG"(sp)\n" 40 + " "REG_L" t0,3*"SZREG"(sp)\n" 41 + " "REG_L" ra,4*"SZREG"(sp)\n" 42 + " addi sp,sp,5*"SZREG"\n" 43 + " jr t0\n" 44 + " .size my_tramp, .-my_tramp\n" 45 + " .popsection\n" 46 + ); 47 + 48 + #endif /* CONFIG_RISCV */ 49 + 50 #ifdef CONFIG_X86_64 51 52 #include <asm/ibt.h>
+24
samples/ftrace/ftrace-direct.c
··· 16 17 extern void my_tramp(void *); 18 19 #ifdef CONFIG_X86_64 20 21 #include <asm/ibt.h>
··· 16 17 extern void my_tramp(void *); 18 19 + #ifdef CONFIG_RISCV 20 + #include <asm/asm.h> 21 + 22 + asm ( 23 + " .pushsection .text, \"ax\", @progbits\n" 24 + " .type my_tramp, @function\n" 25 + " .globl my_tramp\n" 26 + " my_tramp:\n" 27 + " addi sp,sp,-3*"SZREG"\n" 28 + " "REG_S" a0,0*"SZREG"(sp)\n" 29 + " "REG_S" t0,1*"SZREG"(sp)\n" 30 + " "REG_S" ra,2*"SZREG"(sp)\n" 31 + " call my_direct_func\n" 32 + " "REG_L" a0,0*"SZREG"(sp)\n" 33 + " "REG_L" t0,1*"SZREG"(sp)\n" 34 + " "REG_L" ra,2*"SZREG"(sp)\n" 35 + " addi sp,sp,3*"SZREG"\n" 36 + " jr t0\n" 37 + " .size my_tramp, .-my_tramp\n" 38 + " .popsection\n" 39 + ); 40 + 41 + #endif /* CONFIG_RISCV */ 42 + 43 #ifdef CONFIG_X86_64 44 45 #include <asm/ibt.h>
+11 -13
tools/testing/selftests/riscv/hwprobe/cbo.c
··· 36 regs[0] += 4; 37 } 38 39 - static void cbo_insn(char *base, int fn) 40 - { 41 - uint32_t insn = MK_CBO(fn); 42 - 43 - asm volatile( 44 - "mv a0, %0\n" 45 - "li a1, %1\n" 46 - ".4byte %2\n" 47 - : : "r" (base), "i" (fn), "i" (insn) : "a0", "a1", "memory"); 48 - } 49 50 static void cbo_inval(char *base) { cbo_insn(base, 0); } 51 static void cbo_clean(char *base) { cbo_insn(base, 1); } ··· 95 block_size = pair.value; 96 ksft_test_result(rc == 0 && pair.key == RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE && 97 is_power_of_2(block_size), "Zicboz block size\n"); 98 - ksft_print_msg("Zicboz block size: %ld\n", block_size); 99 100 illegal_insn = false; 101 cbo_zero(&mem[block_size]); ··· 119 for (j = 0; j < block_size; ++j) { 120 if (mem[i * block_size + j] != expected) { 121 ksft_test_result_fail("cbo.zero check\n"); 122 - ksft_print_msg("cbo.zero check: mem[%d] != 0x%x\n", 123 i * block_size + j, expected); 124 return; 125 } ··· 199 pair.key = RISCV_HWPROBE_KEY_IMA_EXT_0; 200 rc = riscv_hwprobe(&pair, 1, sizeof(cpu_set_t), (unsigned long *)&cpus, 0); 201 if (rc < 0) 202 - ksft_exit_fail_msg("hwprobe() failed with %d\n", rc); 203 assert(rc == 0 && pair.key == RISCV_HWPROBE_KEY_IMA_EXT_0); 204 205 if (pair.value & RISCV_HWPROBE_EXT_ZICBOZ) {
··· 36 regs[0] += 4; 37 } 38 39 + #define cbo_insn(base, fn) \ 40 + ({ \ 41 + asm volatile( \ 42 + "mv a0, %0\n" \ 43 + "li a1, %1\n" \ 44 + ".4byte %2\n" \ 45 + : : "r" (base), "i" (fn), "i" (MK_CBO(fn)) : "a0", "a1", "memory"); \ 46 + }) 47 48 static void cbo_inval(char *base) { cbo_insn(base, 0); } 49 static void cbo_clean(char *base) { cbo_insn(base, 1); } ··· 97 block_size = pair.value; 98 ksft_test_result(rc == 0 && pair.key == RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE && 99 is_power_of_2(block_size), "Zicboz block size\n"); 100 + ksft_print_msg("Zicboz block size: %llu\n", block_size); 101 102 illegal_insn = false; 103 cbo_zero(&mem[block_size]); ··· 121 for (j = 0; j < block_size; ++j) { 122 if (mem[i * block_size + j] != expected) { 123 ksft_test_result_fail("cbo.zero check\n"); 124 + ksft_print_msg("cbo.zero check: mem[%llu] != 0x%x\n", 125 i * block_size + j, expected); 126 return; 127 } ··· 201 pair.key = RISCV_HWPROBE_KEY_IMA_EXT_0; 202 rc = riscv_hwprobe(&pair, 1, sizeof(cpu_set_t), (unsigned long *)&cpus, 0); 203 if (rc < 0) 204 + ksft_exit_fail_msg("hwprobe() failed with %ld\n", rc); 205 assert(rc == 0 && pair.key == RISCV_HWPROBE_KEY_IMA_EXT_0); 206 207 if (pair.value & RISCV_HWPROBE_EXT_ZICBOZ) {
+2 -2
tools/testing/selftests/riscv/hwprobe/hwprobe.c
··· 29 /* Fail if the kernel claims not to recognize a base key. */ 30 if ((i < 4) && (pairs[i].key != i)) 31 ksft_exit_fail_msg("Failed to recognize base key: key != i, " 32 - "key=%ld, i=%ld\n", pairs[i].key, i); 33 34 if (pairs[i].key != RISCV_HWPROBE_KEY_BASE_BEHAVIOR) 35 continue; ··· 37 if (pairs[i].value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA) 38 continue; 39 40 - ksft_exit_fail_msg("Unexpected pair: (%ld, %ld)\n", pairs[i].key, pairs[i].value); 41 } 42 43 out = riscv_hwprobe(pairs, 8, 0, 0, 0);
··· 29 /* Fail if the kernel claims not to recognize a base key. */ 30 if ((i < 4) && (pairs[i].key != i)) 31 ksft_exit_fail_msg("Failed to recognize base key: key != i, " 32 + "key=%lld, i=%ld\n", pairs[i].key, i); 33 34 if (pairs[i].key != RISCV_HWPROBE_KEY_BASE_BEHAVIOR) 35 continue; ··· 37 if (pairs[i].value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA) 38 continue; 39 40 + ksft_exit_fail_msg("Unexpected pair: (%lld, %llu)\n", pairs[i].key, pairs[i].value); 41 } 42 43 out = riscv_hwprobe(pairs, 8, 0, 0, 0);
+3
tools/testing/selftests/riscv/mm/mmap_test.h
··· 18 int *on_56_addr; 19 }; 20 21 static inline void do_mmaps(struct addresses *mmap_addresses) 22 { 23 /* ··· 52 mmap_addresses->on_56_addr = 53 mmap(on_56_bits, 5 * sizeof(int), prot, flags, 0, 0); 54 } 55 56 static inline int memory_layout(void) 57 {
··· 18 int *on_56_addr; 19 }; 20 21 + // Only works on 64 bit 22 + #if __riscv_xlen == 64 23 static inline void do_mmaps(struct addresses *mmap_addresses) 24 { 25 /* ··· 50 mmap_addresses->on_56_addr = 51 mmap(on_56_bits, 5 * sizeof(int), prot, flags, 0, 0); 52 } 53 + #endif /* __riscv_xlen == 64 */ 54 55 static inline int memory_layout(void) 56 {
+1 -1
tools/testing/selftests/riscv/vector/v_initval_nolibc.c
··· 27 28 datap = malloc(MAX_VSIZE); 29 if (!datap) { 30 - ksft_test_result_fail("fail to allocate memory for size = %lu\n", MAX_VSIZE); 31 exit(-1); 32 } 33
··· 27 28 datap = malloc(MAX_VSIZE); 29 if (!datap) { 30 + ksft_test_result_fail("fail to allocate memory for size = %d\n", MAX_VSIZE); 31 exit(-1); 32 } 33
+3
tools/testing/selftests/riscv/vector/vstate_exec_nolibc.c
··· 1 // SPDX-License-Identifier: GPL-2.0-only 2 #define THIS_PROGRAM "./vstate_exec_nolibc" 3 4 int main(int argc, char **argv)
··· 1 // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #include <linux/wait.h> 4 + 5 #define THIS_PROGRAM "./vstate_exec_nolibc" 6 7 int main(int argc, char **argv)
+2 -2
tools/testing/selftests/riscv/vector/vstate_prctl.c
··· 60 } 61 rc = launch_test(inherit); 62 if (rc != expected) { 63 - ksft_test_result_fail("Test failed, check %d != %d\n", rc, 64 expected); 65 return -2; 66 } ··· 79 pair.key = RISCV_HWPROBE_KEY_IMA_EXT_0; 80 rc = riscv_hwprobe(&pair, 1, 0, NULL, 0); 81 if (rc < 0) { 82 - ksft_test_result_fail("hwprobe() failed with %d\n", rc); 83 return -1; 84 } 85
··· 60 } 61 rc = launch_test(inherit); 62 if (rc != expected) { 63 + ksft_test_result_fail("Test failed, check %d != %ld\n", rc, 64 expected); 65 return -2; 66 } ··· 79 pair.key = RISCV_HWPROBE_KEY_IMA_EXT_0; 80 rc = riscv_hwprobe(&pair, 1, 0, NULL, 0); 81 if (rc < 0) { 82 + ksft_test_result_fail("hwprobe() failed with %ld\n", rc); 83 return -1; 84 } 85