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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'riscv-for-linus-5.2-mw2' of git://git.kernel.org/pub/scm/linux/kernel/git/palmer/riscv-linux

Pull RISC-V updates from Palmer Dabbelt:
"This contains an assortment of RISC-V related patches that I'd like to
target for the 5.2 merge window. Most of the patches are cleanups, but
there are a handful of user-visible changes:

- The nosmp and nr_cpus command-line arguments are now supported,
which work like normal.

- The SBI console no longer installs itself as a preferred console,
we rely on standard mechanisms (/chosen, command-line, hueristics)
instead.

- sfence_remove_sfence_vma{,_asid} now pass their arguments along to
the SBI call.

- Modules now support BUG().

- A missing sfence.vma during boot has been added. This bug only
manifests during boot.

- The arch/riscv support for SiFive's L2 cache controller has been
merged, which should un-block the EDAC framework work.

I've only tested this on QEMU again, as I didn't have time to get
things running on the Unleashed. The latest master from this morning
merges in cleanly and passes the tests as well"

* tag 'riscv-for-linus-5.2-mw2' of git://git.kernel.org/pub/scm/linux/kernel/git/palmer/riscv-linux: (31 commits)
riscv: fix locking violation in page fault handler
RISC-V: sifive_l2_cache: Add L2 cache controller driver for SiFive SoCs
RISC-V: Add DT documentation for SiFive L2 Cache Controller
RISC-V: Avoid using invalid intermediate translations
riscv: Support BUG() in kernel module
riscv: Add the support for c.ebreak check in is_valid_bugaddr()
riscv: support trap-based WARN()
riscv: fix sbi_remote_sfence_vma{,_asid}.
riscv: move switch_mm to its own file
riscv: move flush_icache_{all,mm} to cacheflush.c
tty: Don't force RISCV SBI console as preferred console
RISC-V: Access CSRs using CSR numbers
RISC-V: Add interrupt related SCAUSE defines in asm/csr.h
RISC-V: Use tabs to align macro values in asm/csr.h
RISC-V: Fix minor checkpatch issues.
RISC-V: Support nr_cpus command line option.
RISC-V: Implement nosmp commandline option.
RISC-V: Add RISC-V specific arch_match_cpu_phys_id
riscv: vdso: drop unnecessary cc-ldoption
riscv: call pm_power_off from machine_halt / machine_power_off
...

+632 -318
+51
Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt
··· 1 + SiFive L2 Cache Controller 2 + -------------------------- 3 + The SiFive Level 2 Cache Controller is used to provide access to fast copies 4 + of memory for masters in a Core Complex. The Level 2 Cache Controller also 5 + acts as directory-based coherency manager. 6 + All the properties in ePAPR/DeviceTree specification applies for this platform 7 + 8 + Required Properties: 9 + -------------------- 10 + - compatible: Should be "sifive,fu540-c000-ccache" and "cache" 11 + 12 + - cache-block-size: Specifies the block size in bytes of the cache. 13 + Should be 64 14 + 15 + - cache-level: Should be set to 2 for a level 2 cache 16 + 17 + - cache-sets: Specifies the number of associativity sets of the cache. 18 + Should be 1024 19 + 20 + - cache-size: Specifies the size in bytes of the cache. Should be 2097152 21 + 22 + - cache-unified: Specifies the cache is a unified cache 23 + 24 + - interrupts: Must contain 3 entries (DirError, DataError and DataFail signals) 25 + 26 + - reg: Physical base address and size of L2 cache controller registers map 27 + 28 + Optional Properties: 29 + -------------------- 30 + - next-level-cache: phandle to the next level cache if present. 31 + 32 + - memory-region: reference to the reserved-memory for the L2 Loosely Integrated 33 + Memory region. The reserved memory node should be defined as per the bindings 34 + in reserved-memory.txt 35 + 36 + 37 + Example: 38 + 39 + cache-controller@2010000 { 40 + compatible = "sifive,fu540-c000-ccache", "cache"; 41 + cache-block-size = <64>; 42 + cache-level = <2>; 43 + cache-sets = <1024>; 44 + cache-size = <2097152>; 45 + cache-unified; 46 + interrupt-parent = <&plic0>; 47 + interrupts = <1 2 3>; 48 + reg = <0x0 0x2010000 0x0 0x1000>; 49 + next-level-cache = <&L25 &L40 &L36>; 50 + memory-region = <&l2_lim>; 51 + };
+1 -5
arch/riscv/Kconfig
··· 27 27 select GENERIC_STRNCPY_FROM_USER 28 28 select GENERIC_STRNLEN_USER 29 29 select GENERIC_SMP_IDLE_THREAD 30 - select GENERIC_ATOMIC64 if !64BIT || !RISCV_ISA_A 30 + select GENERIC_ATOMIC64 if !64BIT 31 31 select HAVE_ARCH_AUDITSYSCALL 32 32 select HAVE_MEMBLOCK_NODE_MAP 33 33 select HAVE_DMA_CONTIGUOUS ··· 35 35 select HAVE_PERF_EVENTS 36 36 select HAVE_SYSCALL_TRACEPOINTS 37 37 select IRQ_DOMAIN 38 - select RISCV_ISA_A if SMP 39 38 select SPARSE_IRQ 40 39 select SYSCTL_EXCEPTION_TRACE 41 40 select HAVE_ARCH_TRACEHOOK ··· 193 194 Linux binary. 194 195 195 196 If you don't know what to do here, say Y. 196 - 197 - config RISCV_ISA_A 198 - def_bool y 199 197 200 198 menu "supported PMU type" 201 199 depends on PERF_EVENTS
+2 -3
arch/riscv/Makefile
··· 39 39 KBUILD_CFLAGS += -Wall 40 40 41 41 # ISA string setting 42 - riscv-march-$(CONFIG_ARCH_RV32I) := rv32im 43 - riscv-march-$(CONFIG_ARCH_RV64I) := rv64im 44 - riscv-march-$(CONFIG_RISCV_ISA_A) := $(riscv-march-y)a 42 + riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima 43 + riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima 45 44 riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd 46 45 riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c 47 46 KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
+1
arch/riscv/include/asm/Kbuild
··· 4 4 generic-y += cputime.h 5 5 generic-y += device.h 6 6 generic-y += div64.h 7 + generic-y += extable.h 7 8 generic-y += dma.h 8 9 generic-y += dma-contiguous.h 9 10 generic-y += dma-mapping.h
+24 -11
arch/riscv/include/asm/bug.h
··· 21 21 #include <asm/asm.h> 22 22 23 23 #ifdef CONFIG_GENERIC_BUG 24 - #define __BUG_INSN _AC(0x00100073, UL) /* ebreak */ 24 + #define __INSN_LENGTH_MASK _UL(0x3) 25 + #define __INSN_LENGTH_32 _UL(0x3) 26 + #define __COMPRESSED_INSN_MASK _UL(0xffff) 27 + 28 + #define __BUG_INSN_32 _UL(0x00100073) /* ebreak */ 29 + #define __BUG_INSN_16 _UL(0x9002) /* c.ebreak */ 25 30 26 31 #ifndef __ASSEMBLY__ 27 32 typedef u32 bug_insn_t; ··· 43 38 #define __BUG_ENTRY \ 44 39 __BUG_ENTRY_ADDR "\n\t" \ 45 40 __BUG_ENTRY_FILE "\n\t" \ 46 - RISCV_SHORT " %1" 41 + RISCV_SHORT " %1\n\t" \ 42 + RISCV_SHORT " %2" 47 43 #else 48 44 #define __BUG_ENTRY \ 49 - __BUG_ENTRY_ADDR 45 + __BUG_ENTRY_ADDR "\n\t" \ 46 + RISCV_SHORT " %2" 50 47 #endif 51 48 52 - #define BUG() \ 49 + #define __BUG_FLAGS(flags) \ 53 50 do { \ 54 51 __asm__ __volatile__ ( \ 55 52 "1:\n\t" \ 56 53 "ebreak\n" \ 57 - ".pushsection __bug_table,\"a\"\n\t" \ 54 + ".pushsection __bug_table,\"aw\"\n\t" \ 58 55 "2:\n\t" \ 59 56 __BUG_ENTRY "\n\t" \ 60 - ".org 2b + %2\n\t" \ 57 + ".org 2b + %3\n\t" \ 61 58 ".popsection" \ 62 59 : \ 63 60 : "i" (__FILE__), "i" (__LINE__), \ 64 - "i" (sizeof(struct bug_entry))); \ 65 - unreachable(); \ 61 + "i" (flags), \ 62 + "i" (sizeof(struct bug_entry))); \ 66 63 } while (0) 64 + 67 65 #endif /* !__ASSEMBLY__ */ 68 66 #else /* CONFIG_GENERIC_BUG */ 69 67 #ifndef __ASSEMBLY__ 70 - #define BUG() \ 71 - do { \ 68 + #define __BUG_FLAGS(flags) do { \ 72 69 __asm__ __volatile__ ("ebreak\n"); \ 73 - unreachable(); \ 74 70 } while (0) 75 71 #endif /* !__ASSEMBLY__ */ 76 72 #endif /* CONFIG_GENERIC_BUG */ 73 + 74 + #define BUG() do { \ 75 + __BUG_FLAGS(0); \ 76 + unreachable(); \ 77 + } while (0) 78 + 79 + #define __WARN_FLAGS(flags) __BUG_FLAGS(BUGFLAG_WARNING|(flags)) 77 80 78 81 #define HAVE_ARCH_BUG 79 82
+1 -1
arch/riscv/include/asm/cacheflush.h
··· 47 47 48 48 #else /* CONFIG_SMP */ 49 49 50 - #define flush_icache_all() sbi_remote_fence_i(NULL) 50 + void flush_icache_all(void); 51 51 void flush_icache_mm(struct mm_struct *mm, bool local); 52 52 53 53 #endif /* CONFIG_SMP */
+74 -43
arch/riscv/include/asm/csr.h
··· 14 14 #ifndef _ASM_RISCV_CSR_H 15 15 #define _ASM_RISCV_CSR_H 16 16 17 + #include <asm/asm.h> 17 18 #include <linux/const.h> 18 19 19 20 /* Status register flags */ 20 - #define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */ 21 - #define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */ 22 - #define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */ 23 - #define SR_SUM _AC(0x00040000, UL) /* Supervisor may access User Memory */ 21 + #define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */ 22 + #define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */ 23 + #define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */ 24 + #define SR_SUM _AC(0x00040000, UL) /* Supervisor User Memory Access */ 24 25 25 - #define SR_FS _AC(0x00006000, UL) /* Floating-point Status */ 26 - #define SR_FS_OFF _AC(0x00000000, UL) 27 - #define SR_FS_INITIAL _AC(0x00002000, UL) 28 - #define SR_FS_CLEAN _AC(0x00004000, UL) 29 - #define SR_FS_DIRTY _AC(0x00006000, UL) 26 + #define SR_FS _AC(0x00006000, UL) /* Floating-point Status */ 27 + #define SR_FS_OFF _AC(0x00000000, UL) 28 + #define SR_FS_INITIAL _AC(0x00002000, UL) 29 + #define SR_FS_CLEAN _AC(0x00004000, UL) 30 + #define SR_FS_DIRTY _AC(0x00006000, UL) 30 31 31 - #define SR_XS _AC(0x00018000, UL) /* Extension Status */ 32 - #define SR_XS_OFF _AC(0x00000000, UL) 33 - #define SR_XS_INITIAL _AC(0x00008000, UL) 34 - #define SR_XS_CLEAN _AC(0x00010000, UL) 35 - #define SR_XS_DIRTY _AC(0x00018000, UL) 32 + #define SR_XS _AC(0x00018000, UL) /* Extension Status */ 33 + #define SR_XS_OFF _AC(0x00000000, UL) 34 + #define SR_XS_INITIAL _AC(0x00008000, UL) 35 + #define SR_XS_CLEAN _AC(0x00010000, UL) 36 + #define SR_XS_DIRTY _AC(0x00018000, UL) 36 37 37 38 #ifndef CONFIG_64BIT 38 - #define SR_SD _AC(0x80000000, UL) /* FS/XS dirty */ 39 + #define SR_SD _AC(0x80000000, UL) /* FS/XS dirty */ 39 40 #else 40 - #define SR_SD _AC(0x8000000000000000, UL) /* FS/XS dirty */ 41 + #define SR_SD _AC(0x8000000000000000, UL) /* FS/XS dirty */ 41 42 #endif 42 43 43 44 /* SATP flags */ 44 - #if __riscv_xlen == 32 45 - #define SATP_PPN _AC(0x003FFFFF, UL) 46 - #define SATP_MODE_32 _AC(0x80000000, UL) 47 - #define SATP_MODE SATP_MODE_32 45 + #ifndef CONFIG_64BIT 46 + #define SATP_PPN _AC(0x003FFFFF, UL) 47 + #define SATP_MODE_32 _AC(0x80000000, UL) 48 + #define SATP_MODE SATP_MODE_32 48 49 #else 49 - #define SATP_PPN _AC(0x00000FFFFFFFFFFF, UL) 50 - #define SATP_MODE_39 _AC(0x8000000000000000, UL) 51 - #define SATP_MODE SATP_MODE_39 50 + #define SATP_PPN _AC(0x00000FFFFFFFFFFF, UL) 51 + #define SATP_MODE_39 _AC(0x8000000000000000, UL) 52 + #define SATP_MODE SATP_MODE_39 52 53 #endif 53 54 54 - /* Interrupt Enable and Interrupt Pending flags */ 55 - #define SIE_SSIE _AC(0x00000002, UL) /* Software Interrupt Enable */ 56 - #define SIE_STIE _AC(0x00000020, UL) /* Timer Interrupt Enable */ 57 - #define SIE_SEIE _AC(0x00000200, UL) /* External Interrupt Enable */ 55 + /* SCAUSE */ 56 + #define SCAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1)) 58 57 59 - #define EXC_INST_MISALIGNED 0 60 - #define EXC_INST_ACCESS 1 61 - #define EXC_BREAKPOINT 3 62 - #define EXC_LOAD_ACCESS 5 63 - #define EXC_STORE_ACCESS 7 64 - #define EXC_SYSCALL 8 65 - #define EXC_INST_PAGE_FAULT 12 66 - #define EXC_LOAD_PAGE_FAULT 13 67 - #define EXC_STORE_PAGE_FAULT 15 58 + #define IRQ_U_SOFT 0 59 + #define IRQ_S_SOFT 1 60 + #define IRQ_M_SOFT 3 61 + #define IRQ_U_TIMER 4 62 + #define IRQ_S_TIMER 5 63 + #define IRQ_M_TIMER 7 64 + #define IRQ_U_EXT 8 65 + #define IRQ_S_EXT 9 66 + #define IRQ_M_EXT 11 67 + 68 + #define EXC_INST_MISALIGNED 0 69 + #define EXC_INST_ACCESS 1 70 + #define EXC_BREAKPOINT 3 71 + #define EXC_LOAD_ACCESS 5 72 + #define EXC_STORE_ACCESS 7 73 + #define EXC_SYSCALL 8 74 + #define EXC_INST_PAGE_FAULT 12 75 + #define EXC_LOAD_PAGE_FAULT 13 76 + #define EXC_STORE_PAGE_FAULT 15 77 + 78 + /* SIE (Interrupt Enable) and SIP (Interrupt Pending) flags */ 79 + #define SIE_SSIE (_AC(0x1, UL) << IRQ_S_SOFT) 80 + #define SIE_STIE (_AC(0x1, UL) << IRQ_S_TIMER) 81 + #define SIE_SEIE (_AC(0x1, UL) << IRQ_S_EXT) 82 + 83 + #define CSR_CYCLE 0xc00 84 + #define CSR_TIME 0xc01 85 + #define CSR_INSTRET 0xc02 86 + #define CSR_SSTATUS 0x100 87 + #define CSR_SIE 0x104 88 + #define CSR_STVEC 0x105 89 + #define CSR_SCOUNTEREN 0x106 90 + #define CSR_SSCRATCH 0x140 91 + #define CSR_SEPC 0x141 92 + #define CSR_SCAUSE 0x142 93 + #define CSR_STVAL 0x143 94 + #define CSR_SIP 0x144 95 + #define CSR_SATP 0x180 96 + #define CSR_CYCLEH 0xc80 97 + #define CSR_TIMEH 0xc81 98 + #define CSR_INSTRETH 0xc82 68 99 69 100 #ifndef __ASSEMBLY__ 70 101 71 102 #define csr_swap(csr, val) \ 72 103 ({ \ 73 104 unsigned long __v = (unsigned long)(val); \ 74 - __asm__ __volatile__ ("csrrw %0, " #csr ", %1" \ 105 + __asm__ __volatile__ ("csrrw %0, " __ASM_STR(csr) ", %1"\ 75 106 : "=r" (__v) : "rK" (__v) \ 76 107 : "memory"); \ 77 108 __v; \ ··· 111 80 #define csr_read(csr) \ 112 81 ({ \ 113 82 register unsigned long __v; \ 114 - __asm__ __volatile__ ("csrr %0, " #csr \ 83 + __asm__ __volatile__ ("csrr %0, " __ASM_STR(csr) \ 115 84 : "=r" (__v) : \ 116 85 : "memory"); \ 117 86 __v; \ ··· 120 89 #define csr_write(csr, val) \ 121 90 ({ \ 122 91 unsigned long __v = (unsigned long)(val); \ 123 - __asm__ __volatile__ ("csrw " #csr ", %0" \ 92 + __asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0" \ 124 93 : : "rK" (__v) \ 125 94 : "memory"); \ 126 95 }) ··· 128 97 #define csr_read_set(csr, val) \ 129 98 ({ \ 130 99 unsigned long __v = (unsigned long)(val); \ 131 - __asm__ __volatile__ ("csrrs %0, " #csr ", %1" \ 100 + __asm__ __volatile__ ("csrrs %0, " __ASM_STR(csr) ", %1"\ 132 101 : "=r" (__v) : "rK" (__v) \ 133 102 : "memory"); \ 134 103 __v; \ ··· 137 106 #define csr_set(csr, val) \ 138 107 ({ \ 139 108 unsigned long __v = (unsigned long)(val); \ 140 - __asm__ __volatile__ ("csrs " #csr ", %0" \ 109 + __asm__ __volatile__ ("csrs " __ASM_STR(csr) ", %0" \ 141 110 : : "rK" (__v) \ 142 111 : "memory"); \ 143 112 }) ··· 145 114 #define csr_read_clear(csr, val) \ 146 115 ({ \ 147 116 unsigned long __v = (unsigned long)(val); \ 148 - __asm__ __volatile__ ("csrrc %0, " #csr ", %1" \ 117 + __asm__ __volatile__ ("csrrc %0, " __ASM_STR(csr) ", %1"\ 149 118 : "=r" (__v) : "rK" (__v) \ 150 119 : "memory"); \ 151 120 __v; \ ··· 154 123 #define csr_clear(csr, val) \ 155 124 ({ \ 156 125 unsigned long __v = (unsigned long)(val); \ 157 - __asm__ __volatile__ ("csrc " #csr ", %0" \ 126 + __asm__ __volatile__ ("csrc " __ASM_STR(csr) ", %0" \ 158 127 : : "rK" (__v) \ 159 128 : "memory"); \ 160 129 })
-6
arch/riscv/include/asm/elf.h
··· 27 27 #define ELF_CLASS ELFCLASS32 28 28 #endif 29 29 30 - #if defined(__LITTLE_ENDIAN) 31 30 #define ELF_DATA ELFDATA2LSB 32 - #elif defined(__BIG_ENDIAN) 33 - #define ELF_DATA ELFDATA2MSB 34 - #else 35 - #error "Unknown endianness" 36 - #endif 37 31 38 32 /* 39 33 * This is used to ensure we don't load something for the wrong architecture.
-13
arch/riscv/include/asm/futex.h
··· 7 7 #ifndef _ASM_FUTEX_H 8 8 #define _ASM_FUTEX_H 9 9 10 - #ifndef CONFIG_RISCV_ISA_A 11 - /* 12 - * Use the generic interrupt disabling versions if the A extension 13 - * is not supported. 14 - */ 15 - #ifdef CONFIG_SMP 16 - #error "Can't support generic futex calls without A extension on SMP" 17 - #endif 18 - #include <asm-generic/futex.h> 19 - 20 - #else /* CONFIG_RISCV_ISA_A */ 21 - 22 10 #include <linux/futex.h> 23 11 #include <linux/uaccess.h> 24 12 #include <linux/errno.h> ··· 112 124 return ret; 113 125 } 114 126 115 - #endif /* CONFIG_RISCV_ISA_A */ 116 127 #endif /* _ASM_FUTEX_H */
+5 -5
arch/riscv/include/asm/irqflags.h
··· 21 21 /* read interrupt enabled status */ 22 22 static inline unsigned long arch_local_save_flags(void) 23 23 { 24 - return csr_read(sstatus); 24 + return csr_read(CSR_SSTATUS); 25 25 } 26 26 27 27 /* unconditionally enable interrupts */ 28 28 static inline void arch_local_irq_enable(void) 29 29 { 30 - csr_set(sstatus, SR_SIE); 30 + csr_set(CSR_SSTATUS, SR_SIE); 31 31 } 32 32 33 33 /* unconditionally disable interrupts */ 34 34 static inline void arch_local_irq_disable(void) 35 35 { 36 - csr_clear(sstatus, SR_SIE); 36 + csr_clear(CSR_SSTATUS, SR_SIE); 37 37 } 38 38 39 39 /* get status and disable interrupts */ 40 40 static inline unsigned long arch_local_irq_save(void) 41 41 { 42 - return csr_read_clear(sstatus, SR_SIE); 42 + return csr_read_clear(CSR_SSTATUS, SR_SIE); 43 43 } 44 44 45 45 /* test flags */ ··· 57 57 /* set interrupt enabled status */ 58 58 static inline void arch_local_irq_restore(unsigned long flags) 59 59 { 60 - csr_set(sstatus, flags & SR_SIE); 60 + csr_set(CSR_SSTATUS, flags & SR_SIE); 61 61 } 62 62 63 63 #endif /* _ASM_RISCV_IRQFLAGS_H */
+2 -57
arch/riscv/include/asm/mmu_context.h
··· 20 20 21 21 #include <linux/mm.h> 22 22 #include <linux/sched.h> 23 - #include <asm/tlbflush.h> 24 - #include <asm/cacheflush.h> 25 23 26 24 static inline void enter_lazy_tlb(struct mm_struct *mm, 27 25 struct task_struct *task) ··· 37 39 { 38 40 } 39 41 40 - /* 41 - * When necessary, performs a deferred icache flush for the given MM context, 42 - * on the local CPU. RISC-V has no direct mechanism for instruction cache 43 - * shoot downs, so instead we send an IPI that informs the remote harts they 44 - * need to flush their local instruction caches. To avoid pathologically slow 45 - * behavior in a common case (a bunch of single-hart processes on a many-hart 46 - * machine, ie 'make -j') we avoid the IPIs for harts that are not currently 47 - * executing a MM context and instead schedule a deferred local instruction 48 - * cache flush to be performed before execution resumes on each hart. This 49 - * actually performs that local instruction cache flush, which implicitly only 50 - * refers to the current hart. 51 - */ 52 - static inline void flush_icache_deferred(struct mm_struct *mm) 53 - { 54 - #ifdef CONFIG_SMP 55 - unsigned int cpu = smp_processor_id(); 56 - cpumask_t *mask = &mm->context.icache_stale_mask; 57 - 58 - if (cpumask_test_cpu(cpu, mask)) { 59 - cpumask_clear_cpu(cpu, mask); 60 - /* 61 - * Ensure the remote hart's writes are visible to this hart. 62 - * This pairs with a barrier in flush_icache_mm. 63 - */ 64 - smp_mb(); 65 - local_flush_icache_all(); 66 - } 67 - #endif 68 - } 69 - 70 - static inline void switch_mm(struct mm_struct *prev, 71 - struct mm_struct *next, struct task_struct *task) 72 - { 73 - if (likely(prev != next)) { 74 - /* 75 - * Mark the current MM context as inactive, and the next as 76 - * active. This is at least used by the icache flushing 77 - * routines in order to determine who should 78 - */ 79 - unsigned int cpu = smp_processor_id(); 80 - 81 - cpumask_clear_cpu(cpu, mm_cpumask(prev)); 82 - cpumask_set_cpu(cpu, mm_cpumask(next)); 83 - 84 - /* 85 - * Use the old spbtr name instead of using the current satp 86 - * name to support binutils 2.29 which doesn't know about the 87 - * privileged ISA 1.10 yet. 88 - */ 89 - csr_write(sptbr, virt_to_pfn(next->pgd) | SATP_MODE); 90 - local_flush_tlb_all(); 91 - 92 - flush_icache_deferred(next); 93 - } 94 - } 42 + void switch_mm(struct mm_struct *prev, struct mm_struct *next, 43 + struct task_struct *task); 95 44 96 45 static inline void activate_mm(struct mm_struct *prev, 97 46 struct mm_struct *next)
+6 -15
arch/riscv/include/asm/ptrace.h
··· 70 70 71 71 72 72 /* Helpers for working with the instruction pointer */ 73 - #define GET_IP(regs) ((regs)->sepc) 74 - #define SET_IP(regs, val) (GET_IP(regs) = (val)) 75 - 76 73 static inline unsigned long instruction_pointer(struct pt_regs *regs) 77 74 { 78 - return GET_IP(regs); 75 + return regs->sepc; 79 76 } 80 77 static inline void instruction_pointer_set(struct pt_regs *regs, 81 78 unsigned long val) 82 79 { 83 - SET_IP(regs, val); 80 + regs->sepc = val; 84 81 } 85 82 86 83 #define profile_pc(regs) instruction_pointer(regs) 87 84 88 85 /* Helpers for working with the user stack pointer */ 89 - #define GET_USP(regs) ((regs)->sp) 90 - #define SET_USP(regs, val) (GET_USP(regs) = (val)) 91 - 92 86 static inline unsigned long user_stack_pointer(struct pt_regs *regs) 93 87 { 94 - return GET_USP(regs); 88 + return regs->sp; 95 89 } 96 90 static inline void user_stack_pointer_set(struct pt_regs *regs, 97 91 unsigned long val) 98 92 { 99 - SET_USP(regs, val); 93 + regs->sp = val; 100 94 } 101 95 102 96 /* Helpers for working with the frame pointer */ 103 - #define GET_FP(regs) ((regs)->s0) 104 - #define SET_FP(regs, val) (GET_FP(regs) = (val)) 105 - 106 97 static inline unsigned long frame_pointer(struct pt_regs *regs) 107 98 { 108 - return GET_FP(regs); 99 + return regs->s0; 109 100 } 110 101 static inline void frame_pointer_set(struct pt_regs *regs, 111 102 unsigned long val) 112 103 { 113 - SET_FP(regs, val); 104 + regs->s0 = val; 114 105 } 115 106 116 107 static inline unsigned long regs_return_value(struct pt_regs *regs)
+12 -7
arch/riscv/include/asm/sbi.h
··· 26 26 #define SBI_REMOTE_SFENCE_VMA_ASID 7 27 27 #define SBI_SHUTDOWN 8 28 28 29 - #define SBI_CALL(which, arg0, arg1, arg2) ({ \ 29 + #define SBI_CALL(which, arg0, arg1, arg2, arg3) ({ \ 30 30 register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \ 31 31 register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \ 32 32 register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \ 33 + register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); \ 33 34 register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \ 34 35 asm volatile ("ecall" \ 35 36 : "+r" (a0) \ 36 - : "r" (a1), "r" (a2), "r" (a7) \ 37 + : "r" (a1), "r" (a2), "r" (a3), "r" (a7) \ 37 38 : "memory"); \ 38 39 a0; \ 39 40 }) 40 41 41 42 /* Lazy implementations until SBI is finalized */ 42 - #define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0) 43 - #define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0) 44 - #define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0) 43 + #define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0, 0) 44 + #define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0, 0) 45 + #define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0, 0) 46 + #define SBI_CALL_3(which, arg0, arg1, arg2) \ 47 + SBI_CALL(which, arg0, arg1, arg2, 0) 48 + #define SBI_CALL_4(which, arg0, arg1, arg2, arg3) \ 49 + SBI_CALL(which, arg0, arg1, arg2, arg3) 45 50 46 51 static inline void sbi_console_putchar(int ch) 47 52 { ··· 91 86 unsigned long start, 92 87 unsigned long size) 93 88 { 94 - SBI_CALL_1(SBI_REMOTE_SFENCE_VMA, hart_mask); 89 + SBI_CALL_3(SBI_REMOTE_SFENCE_VMA, hart_mask, start, size); 95 90 } 96 91 97 92 static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, ··· 99 94 unsigned long size, 100 95 unsigned long asid) 101 96 { 102 - SBI_CALL_1(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask); 97 + SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid); 103 98 } 104 99 105 100 #endif
+16
arch/riscv/include/asm/sifive_l2_cache.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * SiFive L2 Cache Controller header file 4 + * 5 + */ 6 + 7 + #ifndef _ASM_RISCV_SIFIVE_L2_CACHE_H 8 + #define _ASM_RISCV_SIFIVE_L2_CACHE_H 9 + 10 + extern int register_sifive_l2_error_notifier(struct notifier_block *nb); 11 + extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb); 12 + 13 + #define SIFIVE_L2_ERR_TYPE_CE 0 14 + #define SIFIVE_L2_ERR_TYPE_UE 1 15 + 16 + #endif /* _ASM_RISCV_SIFIVE_L2_CACHE_H */
+3 -1
arch/riscv/include/asm/thread_info.h
··· 28 28 #include <asm/processor.h> 29 29 #include <asm/csr.h> 30 30 31 - typedef unsigned long mm_segment_t; 31 + typedef struct { 32 + unsigned long seg; 33 + } mm_segment_t; 32 34 33 35 /* 34 36 * low level task data that entry.S needs immediate access to
+9 -19
arch/riscv/include/asm/uaccess.h
··· 23 23 #include <linux/compiler.h> 24 24 #include <linux/thread_info.h> 25 25 #include <asm/byteorder.h> 26 + #include <asm/extable.h> 26 27 #include <asm/asm.h> 27 28 28 29 #define __enable_user_access() \ ··· 39 38 * For historical reasons, these macros are grossly misnamed. 40 39 */ 41 40 42 - #define KERNEL_DS (~0UL) 43 - #define USER_DS (TASK_SIZE) 41 + #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) 42 + 43 + #define KERNEL_DS MAKE_MM_SEG(~0UL) 44 + #define USER_DS MAKE_MM_SEG(TASK_SIZE) 44 45 45 46 #define get_fs() (current_thread_info()->addr_limit) 46 47 ··· 51 48 current_thread_info()->addr_limit = fs; 52 49 } 53 50 54 - #define segment_eq(a, b) ((a) == (b)) 51 + #define segment_eq(a, b) ((a).seg == (b).seg) 55 52 56 - #define user_addr_max() (get_fs()) 53 + #define user_addr_max() (get_fs().seg) 57 54 58 55 59 56 /** ··· 85 82 { 86 83 const mm_segment_t fs = get_fs(); 87 84 88 - return (size <= fs) && (addr <= (fs - size)); 85 + return size <= fs.seg && addr <= fs.seg - size; 89 86 } 90 87 91 88 /* ··· 101 98 * on our cache or tlb entries. 102 99 */ 103 100 104 - struct exception_table_entry { 105 - unsigned long insn, fixup; 106 - }; 107 - 108 - extern int fixup_exception(struct pt_regs *state); 109 - 110 - #if defined(__LITTLE_ENDIAN) 111 - #define __MSW 1 112 101 #define __LSW 0 113 - #elif defined(__BIG_ENDIAN) 114 - #define __MSW 0 115 - #define __LSW 1 116 - #else 117 - #error "Unknown endianness" 118 - #endif 102 + #define __MSW 1 119 103 120 104 /* 121 105 * The "__xxx" versions of the user access functions do not verify the address
-3
arch/riscv/kernel/asm-offsets.c
··· 312 312 - offsetof(struct task_struct, thread.fstate.f[0]) 313 313 ); 314 314 315 - /* The assembler needs access to THREAD_SIZE as well. */ 316 - DEFINE(ASM_THREAD_SIZE, THREAD_SIZE); 317 - 318 315 /* 319 316 * We allocate a pt_regs on the stack when entering the kernel. This 320 317 * ensures the alignment is sane.
+1 -2
arch/riscv/kernel/cpu.c
··· 136 136 static int c_show(struct seq_file *m, void *v) 137 137 { 138 138 unsigned long cpu_id = (unsigned long)v - 1; 139 - struct device_node *node = of_get_cpu_node(cpuid_to_hartid_map(cpu_id), 140 - NULL); 139 + struct device_node *node = of_get_cpu_node(cpu_id, NULL); 141 140 const char *compat, *isa, *mmu; 142 141 143 142 seq_printf(m, "processor\t: %lu\n", cpu_id);
+11 -11
arch/riscv/kernel/entry.S
··· 37 37 * the kernel thread pointer. If we came from the kernel, sscratch 38 38 * will contain 0, and we should continue on the current TP. 39 39 */ 40 - csrrw tp, sscratch, tp 40 + csrrw tp, CSR_SSCRATCH, tp 41 41 bnez tp, _save_context 42 42 43 43 _restore_kernel_tpsp: 44 - csrr tp, sscratch 44 + csrr tp, CSR_SSCRATCH 45 45 REG_S sp, TASK_TI_KERNEL_SP(tp) 46 46 _save_context: 47 47 REG_S sp, TASK_TI_USER_SP(tp) ··· 87 87 li t0, SR_SUM | SR_FS 88 88 89 89 REG_L s0, TASK_TI_USER_SP(tp) 90 - csrrc s1, sstatus, t0 91 - csrr s2, sepc 92 - csrr s3, sbadaddr 93 - csrr s4, scause 94 - csrr s5, sscratch 90 + csrrc s1, CSR_SSTATUS, t0 91 + csrr s2, CSR_SEPC 92 + csrr s3, CSR_STVAL 93 + csrr s4, CSR_SCAUSE 94 + csrr s5, CSR_SSCRATCH 95 95 REG_S s0, PT_SP(sp) 96 96 REG_S s1, PT_SSTATUS(sp) 97 97 REG_S s2, PT_SEPC(sp) ··· 107 107 .macro RESTORE_ALL 108 108 REG_L a0, PT_SSTATUS(sp) 109 109 REG_L a2, PT_SEPC(sp) 110 - csrw sstatus, a0 111 - csrw sepc, a2 110 + csrw CSR_SSTATUS, a0 111 + csrw CSR_SEPC, a2 112 112 113 113 REG_L x1, PT_RA(sp) 114 114 REG_L x3, PT_GP(sp) ··· 155 155 * Set sscratch register to 0, so that if a recursive exception 156 156 * occurs, the exception vector knows it came from the kernel 157 157 */ 158 - csrw sscratch, x0 158 + csrw CSR_SSCRATCH, x0 159 159 160 160 /* Load the global pointer */ 161 161 .option push ··· 248 248 * Save TP into sscratch, so we can find the kernel data structures 249 249 * again. 250 250 */ 251 - csrw sscratch, tp 251 + csrw CSR_SSCRATCH, tp 252 252 253 253 restore_all: 254 254 RESTORE_ALL
+19 -14
arch/riscv/kernel/head.S
··· 23 23 __INIT 24 24 ENTRY(_start) 25 25 /* Mask all interrupts */ 26 - csrw sie, zero 26 + csrw CSR_SIE, zero 27 + csrw CSR_SIP, zero 27 28 28 29 /* Load the global pointer */ 29 30 .option push ··· 69 68 /* Restore C environment */ 70 69 la tp, init_task 71 70 sw zero, TASK_TI_CPU(tp) 72 - 73 - la sp, init_thread_union 74 - li a0, ASM_THREAD_SIZE 75 - add sp, sp, a0 71 + la sp, init_thread_union + THREAD_SIZE 76 72 77 73 /* Start the kernel */ 78 - mv a0, s0 79 - mv a1, s1 74 + mv a0, s1 80 75 call parse_dtb 81 76 tail start_kernel 82 77 ··· 86 89 /* Point stvec to virtual address of intruction after satp write */ 87 90 la a0, 1f 88 91 add a0, a0, a1 89 - csrw stvec, a0 92 + csrw CSR_STVEC, a0 90 93 91 94 /* Compute satp for kernel page tables, but don't load it yet */ 92 95 la a2, swapper_pg_dir ··· 96 99 97 100 /* 98 101 * Load trampoline page directory, which will cause us to trap to 99 - * stvec if VA != PA, or simply fall through if VA == PA 102 + * stvec if VA != PA, or simply fall through if VA == PA. We need a 103 + * full fence here because setup_vm() just wrote these PTEs and we need 104 + * to ensure the new translations are in use. 100 105 */ 101 106 la a0, trampoline_pg_dir 102 107 srl a0, a0, PAGE_SHIFT 103 108 or a0, a0, a1 104 109 sfence.vma 105 - csrw sptbr, a0 110 + csrw CSR_SATP, a0 106 111 .align 2 107 112 1: 108 113 /* Set trap vector to spin forever to help debug */ 109 114 la a0, .Lsecondary_park 110 - csrw stvec, a0 115 + csrw CSR_STVEC, a0 111 116 112 117 /* Reload the global pointer */ 113 118 .option push ··· 117 118 la gp, __global_pointer$ 118 119 .option pop 119 120 120 - /* Switch to kernel page tables */ 121 - csrw sptbr, a2 121 + /* 122 + * Switch to kernel page tables. A full fence is necessary in order to 123 + * avoid using the trampoline translations, which are only correct for 124 + * the first superpage. Fetching the fence is guarnteed to work 125 + * because that first superpage is translated the same way. 126 + */ 127 + csrw CSR_SATP, a2 128 + sfence.vma 122 129 123 130 ret 124 131 ··· 135 130 136 131 /* Set trap vector to spin forever to help debug */ 137 132 la a3, .Lsecondary_park 138 - csrw stvec, a3 133 + csrw CSR_STVEC, a3 139 134 140 135 slli a3, a0, LGREG 141 136 la a1, __cpu_up_stack_pointer
+6 -13
arch/riscv/kernel/irq.c
··· 14 14 /* 15 15 * Possible interrupt causes: 16 16 */ 17 - #define INTERRUPT_CAUSE_SOFTWARE 1 18 - #define INTERRUPT_CAUSE_TIMER 5 19 - #define INTERRUPT_CAUSE_EXTERNAL 9 20 - 21 - /* 22 - * The high order bit of the trap cause register is always set for 23 - * interrupts, which allows us to differentiate them from exceptions 24 - * quickly. The INTERRUPT_CAUSE_* macros don't contain that bit, so we 25 - * need to mask it off. 26 - */ 27 - #define INTERRUPT_CAUSE_FLAG (1UL << (__riscv_xlen - 1)) 17 + #define INTERRUPT_CAUSE_SOFTWARE IRQ_S_SOFT 18 + #define INTERRUPT_CAUSE_TIMER IRQ_S_TIMER 19 + #define INTERRUPT_CAUSE_EXTERNAL IRQ_S_EXT 28 20 29 21 int arch_show_interrupts(struct seq_file *p, int prec) 30 22 { ··· 29 37 struct pt_regs *old_regs = set_irq_regs(regs); 30 38 31 39 irq_enter(); 32 - switch (regs->scause & ~INTERRUPT_CAUSE_FLAG) { 40 + switch (regs->scause & ~SCAUSE_IRQ_FLAG) { 33 41 case INTERRUPT_CAUSE_TIMER: 34 42 riscv_timer_interrupt(); 35 43 break; ··· 46 54 handle_arch_irq(regs); 47 55 break; 48 56 default: 49 - panic("unexpected interrupt cause"); 57 + pr_alert("unexpected interrupt cause 0x%lx", regs->scause); 58 + BUG(); 50 59 } 51 60 irq_exit(); 52 61
+2 -2
arch/riscv/kernel/perf_event.c
··· 185 185 186 186 switch (idx) { 187 187 case RISCV_PMU_CYCLE: 188 - val = csr_read(cycle); 188 + val = csr_read(CSR_CYCLE); 189 189 break; 190 190 case RISCV_PMU_INSTRET: 191 - val = csr_read(instret); 191 + val = csr_read(CSR_INSTRET); 192 192 break; 193 193 default: 194 194 WARN_ON_ONCE(idx < 0 || idx > RISCV_MAX_COUNTERS);
+9 -6
arch/riscv/kernel/reset.c
··· 12 12 */ 13 13 14 14 #include <linux/reboot.h> 15 - #include <linux/export.h> 16 15 #include <asm/sbi.h> 17 16 18 - void (*pm_power_off)(void) = machine_power_off; 19 - EXPORT_SYMBOL(pm_power_off); 17 + static void default_power_off(void) 18 + { 19 + sbi_shutdown(); 20 + while (1); 21 + } 22 + 23 + void (*pm_power_off)(void) = default_power_off; 20 24 21 25 void machine_restart(char *cmd) 22 26 { ··· 30 26 31 27 void machine_halt(void) 32 28 { 33 - machine_power_off(); 29 + pm_power_off(); 34 30 } 35 31 36 32 void machine_power_off(void) 37 33 { 38 - sbi_shutdown(); 39 - while (1); 34 + pm_power_off(); 40 35 }
+4 -2
arch/riscv/kernel/setup.c
··· 52 52 atomic_t hart_lottery; 53 53 unsigned long boot_cpu_hartid; 54 54 55 - void __init parse_dtb(unsigned int hartid, void *dtb) 55 + void __init parse_dtb(phys_addr_t dtb_phys) 56 56 { 57 - if (early_init_dt_scan(__va(dtb))) 57 + void *dtb = __va(dtb_phys); 58 + 59 + if (early_init_dt_scan(dtb)) 58 60 return; 59 61 60 62 pr_err("No DTB passed to the kernel\n");
+6
arch/riscv/kernel/signal.c
··· 234 234 235 235 /* Are we from a system call? */ 236 236 if (regs->scause == EXC_SYSCALL) { 237 + /* Avoid additional syscall restarting via ret_from_exception */ 238 + regs->scause = -1UL; 239 + 237 240 /* If so, check system call restarting.. */ 238 241 switch (regs->a0) { 239 242 case -ERESTART_RESTARTBLOCK: ··· 275 272 276 273 /* Did we come from a system call? */ 277 274 if (regs->scause == EXC_SYSCALL) { 275 + /* Avoid additional syscall restarting via ret_from_exception */ 276 + regs->scause = -1UL; 277 + 278 278 /* Restart the system call - no handlers present */ 279 279 switch (regs->a0) { 280 280 case -ERESTARTNOHAND:
+9 -52
arch/riscv/kernel/smp.c
··· 42 42 43 43 void __init smp_setup_processor_id(void) 44 44 { 45 - cpuid_to_hartid_map(0) = boot_cpu_hartid; 45 + cpuid_to_hartid_map(0) = boot_cpu_hartid; 46 46 } 47 47 48 48 /* A collection of single bit ipi messages. */ ··· 53 53 54 54 int riscv_hartid_to_cpuid(int hartid) 55 55 { 56 - int i = -1; 56 + int i; 57 57 58 58 for (i = 0; i < NR_CPUS; i++) 59 59 if (cpuid_to_hartid_map(i) == hartid) ··· 70 70 for_each_cpu(cpu, in) 71 71 cpumask_set_cpu(cpuid_to_hartid_map(cpu), out); 72 72 } 73 + 74 + bool arch_match_cpu_phys_id(int cpu, u64 phys_id) 75 + { 76 + return phys_id == cpuid_to_hartid_map(cpu); 77 + } 78 + 73 79 /* Unsupported */ 74 80 int setup_profiling_timer(unsigned int multiplier) 75 81 { ··· 95 89 unsigned long *stats = ipi_data[smp_processor_id()].stats; 96 90 97 91 /* Clear pending IPI */ 98 - csr_clear(sip, SIE_SSIE); 92 + csr_clear(CSR_SIP, SIE_SSIE); 99 93 100 94 while (true) { 101 95 unsigned long ops; ··· 205 199 send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE); 206 200 } 207 201 208 - /* 209 - * Performs an icache flush for the given MM context. RISC-V has no direct 210 - * mechanism for instruction cache shoot downs, so instead we send an IPI that 211 - * informs the remote harts they need to flush their local instruction caches. 212 - * To avoid pathologically slow behavior in a common case (a bunch of 213 - * single-hart processes on a many-hart machine, ie 'make -j') we avoid the 214 - * IPIs for harts that are not currently executing a MM context and instead 215 - * schedule a deferred local instruction cache flush to be performed before 216 - * execution resumes on each hart. 217 - */ 218 - void flush_icache_mm(struct mm_struct *mm, bool local) 219 - { 220 - unsigned int cpu; 221 - cpumask_t others, hmask, *mask; 222 - 223 - preempt_disable(); 224 - 225 - /* Mark every hart's icache as needing a flush for this MM. */ 226 - mask = &mm->context.icache_stale_mask; 227 - cpumask_setall(mask); 228 - /* Flush this hart's I$ now, and mark it as flushed. */ 229 - cpu = smp_processor_id(); 230 - cpumask_clear_cpu(cpu, mask); 231 - local_flush_icache_all(); 232 - 233 - /* 234 - * Flush the I$ of other harts concurrently executing, and mark them as 235 - * flushed. 236 - */ 237 - cpumask_andnot(&others, mm_cpumask(mm), cpumask_of(cpu)); 238 - local |= cpumask_empty(&others); 239 - if (mm != current->active_mm || !local) { 240 - cpumask_clear(&hmask); 241 - riscv_cpuid_to_hartid_mask(&others, &hmask); 242 - sbi_remote_fence_i(hmask.bits); 243 - } else { 244 - /* 245 - * It's assumed that at least one strongly ordered operation is 246 - * performed on this hart between setting a hart's cpumask bit 247 - * and scheduling this MM context on that hart. Sending an SBI 248 - * remote message will do this, but in the case where no 249 - * messages are sent we still need to order this hart's writes 250 - * with flush_icache_deferred(). 251 - */ 252 - smp_mb(); 253 - } 254 - 255 - preempt_enable(); 256 - }
+20 -2
arch/riscv/kernel/smpboot.c
··· 47 47 48 48 void __init smp_prepare_cpus(unsigned int max_cpus) 49 49 { 50 + int cpuid; 51 + 52 + /* This covers non-smp usecase mandated by "nosmp" option */ 53 + if (max_cpus == 0) 54 + return; 55 + 56 + for_each_possible_cpu(cpuid) { 57 + if (cpuid == smp_processor_id()) 58 + continue; 59 + set_cpu_present(cpuid, true); 60 + } 50 61 } 51 62 52 63 void __init setup_smp(void) ··· 84 73 } 85 74 86 75 cpuid_to_hartid_map(cpuid) = hart; 87 - set_cpu_possible(cpuid, true); 88 - set_cpu_present(cpuid, true); 89 76 cpuid++; 90 77 } 91 78 92 79 BUG_ON(!found_boot_cpu); 80 + 81 + if (cpuid > nr_cpu_ids) 82 + pr_warn("Total number of cpus [%d] is greater than nr_cpus option value [%d]\n", 83 + cpuid, nr_cpu_ids); 84 + 85 + for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++) { 86 + if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID) 87 + set_cpu_possible(cpuid, true); 88 + } 93 89 } 94 90 95 91 int __cpu_up(unsigned int cpu, struct task_struct *tidle)
+5 -9
arch/riscv/kernel/stacktrace.c
··· 33 33 unsigned long fp, sp, pc; 34 34 35 35 if (regs) { 36 - fp = GET_FP(regs); 37 - sp = GET_USP(regs); 38 - pc = GET_IP(regs); 36 + fp = frame_pointer(regs); 37 + sp = user_stack_pointer(regs); 38 + pc = instruction_pointer(regs); 39 39 } else if (task == NULL || task == current) { 40 40 const register unsigned long current_sp __asm__ ("sp"); 41 41 fp = (unsigned long)__builtin_frame_address(0); ··· 64 64 frame = (struct stackframe *)fp - 1; 65 65 sp = fp; 66 66 fp = frame->fp; 67 - #ifdef HAVE_FUNCTION_GRAPH_RET_ADDR_PTR 68 67 pc = ftrace_graph_ret_addr(current, NULL, frame->ra, 69 68 (unsigned long *)(fp - 8)); 70 - #else 71 - pc = frame->ra - 0x4; 72 - #endif 73 69 } 74 70 } 75 71 ··· 78 82 unsigned long *ksp; 79 83 80 84 if (regs) { 81 - sp = GET_USP(regs); 82 - pc = GET_IP(regs); 85 + sp = user_stack_pointer(regs); 86 + pc = instruction_pointer(regs); 83 87 } else if (task == NULL || task == current) { 84 88 const register unsigned long current_sp __asm__ ("sp"); 85 89 sp = current_sp;
+22 -8
arch/riscv/kernel/traps.c
··· 70 70 && printk_ratelimit()) { 71 71 pr_info("%s[%d]: unhandled signal %d code 0x%x at 0x" REG_FMT, 72 72 tsk->comm, task_pid_nr(tsk), signo, code, addr); 73 - print_vma_addr(KERN_CONT " in ", GET_IP(regs)); 73 + print_vma_addr(KERN_CONT " in ", instruction_pointer(regs)); 74 74 pr_cont("\n"); 75 75 show_regs(regs); 76 76 } ··· 118 118 DO_ERROR_INFO(do_trap_ecall_m, 119 119 SIGILL, ILL_ILLTRP, "environment call from M-mode"); 120 120 121 + #ifdef CONFIG_GENERIC_BUG 122 + static inline unsigned long get_break_insn_length(unsigned long pc) 123 + { 124 + bug_insn_t insn; 125 + 126 + if (probe_kernel_address((bug_insn_t *)pc, insn)) 127 + return 0; 128 + return (((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) ? 4UL : 2UL); 129 + } 130 + #endif /* CONFIG_GENERIC_BUG */ 131 + 121 132 asmlinkage void do_trap_break(struct pt_regs *regs) 122 133 { 123 134 #ifdef CONFIG_GENERIC_BUG ··· 140 129 case BUG_TRAP_TYPE_NONE: 141 130 break; 142 131 case BUG_TRAP_TYPE_WARN: 143 - regs->sepc += sizeof(bug_insn_t); 144 - return; 132 + regs->sepc += get_break_insn_length(regs->sepc); 133 + break; 145 134 case BUG_TRAP_TYPE_BUG: 146 135 die(regs, "Kernel BUG"); 147 136 } ··· 156 145 { 157 146 bug_insn_t insn; 158 147 159 - if (pc < PAGE_OFFSET) 148 + if (pc < VMALLOC_START) 160 149 return 0; 161 150 if (probe_kernel_address((bug_insn_t *)pc, insn)) 162 151 return 0; 163 - return (insn == __BUG_INSN); 152 + if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) 153 + return (insn == __BUG_INSN_32); 154 + else 155 + return ((insn & __COMPRESSED_INSN_MASK) == __BUG_INSN_16); 164 156 } 165 157 #endif /* CONFIG_GENERIC_BUG */ 166 158 ··· 173 159 * Set sup0 scratch register to 0, indicating to exception vector 174 160 * that we are presently executing in the kernel 175 161 */ 176 - csr_write(sscratch, 0); 162 + csr_write(CSR_SSCRATCH, 0); 177 163 /* Set the exception vector address */ 178 - csr_write(stvec, &handle_exception); 164 + csr_write(CSR_STVEC, &handle_exception); 179 165 /* Enable all interrupts */ 180 - csr_write(sie, -1); 166 + csr_write(CSR_SIE, -1); 181 167 }
+1 -1
arch/riscv/kernel/vdso/Makefile
··· 36 36 # these symbols in the kernel code rather than hand-coded addresses. 37 37 38 38 SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ 39 - $(call cc-ldoption, -Wl$(comma)--hash-style=both) 39 + -Wl,--hash-style=both 40 40 $(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE 41 41 $(call if_changed,vdsold) 42 42
+2
arch/riscv/mm/Makefile
··· 9 9 obj-y += extable.o 10 10 obj-y += ioremap.o 11 11 obj-y += cacheflush.o 12 + obj-y += context.o 13 + obj-y += sifive_l2_cache.o
+61
arch/riscv/mm/cacheflush.c
··· 14 14 #include <asm/pgtable.h> 15 15 #include <asm/cacheflush.h> 16 16 17 + #ifdef CONFIG_SMP 18 + 19 + #include <asm/sbi.h> 20 + 21 + void flush_icache_all(void) 22 + { 23 + sbi_remote_fence_i(NULL); 24 + } 25 + 26 + /* 27 + * Performs an icache flush for the given MM context. RISC-V has no direct 28 + * mechanism for instruction cache shoot downs, so instead we send an IPI that 29 + * informs the remote harts they need to flush their local instruction caches. 30 + * To avoid pathologically slow behavior in a common case (a bunch of 31 + * single-hart processes on a many-hart machine, ie 'make -j') we avoid the 32 + * IPIs for harts that are not currently executing a MM context and instead 33 + * schedule a deferred local instruction cache flush to be performed before 34 + * execution resumes on each hart. 35 + */ 36 + void flush_icache_mm(struct mm_struct *mm, bool local) 37 + { 38 + unsigned int cpu; 39 + cpumask_t others, hmask, *mask; 40 + 41 + preempt_disable(); 42 + 43 + /* Mark every hart's icache as needing a flush for this MM. */ 44 + mask = &mm->context.icache_stale_mask; 45 + cpumask_setall(mask); 46 + /* Flush this hart's I$ now, and mark it as flushed. */ 47 + cpu = smp_processor_id(); 48 + cpumask_clear_cpu(cpu, mask); 49 + local_flush_icache_all(); 50 + 51 + /* 52 + * Flush the I$ of other harts concurrently executing, and mark them as 53 + * flushed. 54 + */ 55 + cpumask_andnot(&others, mm_cpumask(mm), cpumask_of(cpu)); 56 + local |= cpumask_empty(&others); 57 + if (mm != current->active_mm || !local) { 58 + cpumask_clear(&hmask); 59 + riscv_cpuid_to_hartid_mask(&others, &hmask); 60 + sbi_remote_fence_i(hmask.bits); 61 + } else { 62 + /* 63 + * It's assumed that at least one strongly ordered operation is 64 + * performed on this hart between setting a hart's cpumask bit 65 + * and scheduling this MM context on that hart. Sending an SBI 66 + * remote message will do this, but in the case where no 67 + * messages are sent we still need to order this hart's writes 68 + * with flush_icache_deferred(). 69 + */ 70 + smp_mb(); 71 + } 72 + 73 + preempt_enable(); 74 + } 75 + 76 + #endif /* CONFIG_SMP */ 77 + 17 78 void flush_icache_pte(pte_t pte) 18 79 { 19 80 struct page *page = pte_page(pte);
+69
arch/riscv/mm/context.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2012 Regents of the University of California 4 + * Copyright (C) 2017 SiFive 5 + */ 6 + 7 + #include <linux/mm.h> 8 + #include <asm/tlbflush.h> 9 + #include <asm/cacheflush.h> 10 + 11 + /* 12 + * When necessary, performs a deferred icache flush for the given MM context, 13 + * on the local CPU. RISC-V has no direct mechanism for instruction cache 14 + * shoot downs, so instead we send an IPI that informs the remote harts they 15 + * need to flush their local instruction caches. To avoid pathologically slow 16 + * behavior in a common case (a bunch of single-hart processes on a many-hart 17 + * machine, ie 'make -j') we avoid the IPIs for harts that are not currently 18 + * executing a MM context and instead schedule a deferred local instruction 19 + * cache flush to be performed before execution resumes on each hart. This 20 + * actually performs that local instruction cache flush, which implicitly only 21 + * refers to the current hart. 22 + */ 23 + static inline void flush_icache_deferred(struct mm_struct *mm) 24 + { 25 + #ifdef CONFIG_SMP 26 + unsigned int cpu = smp_processor_id(); 27 + cpumask_t *mask = &mm->context.icache_stale_mask; 28 + 29 + if (cpumask_test_cpu(cpu, mask)) { 30 + cpumask_clear_cpu(cpu, mask); 31 + /* 32 + * Ensure the remote hart's writes are visible to this hart. 33 + * This pairs with a barrier in flush_icache_mm. 34 + */ 35 + smp_mb(); 36 + local_flush_icache_all(); 37 + } 38 + 39 + #endif 40 + } 41 + 42 + void switch_mm(struct mm_struct *prev, struct mm_struct *next, 43 + struct task_struct *task) 44 + { 45 + unsigned int cpu; 46 + 47 + if (unlikely(prev == next)) 48 + return; 49 + 50 + /* 51 + * Mark the current MM context as inactive, and the next as 52 + * active. This is at least used by the icache flushing 53 + * routines in order to determine who should be flushed. 54 + */ 55 + cpu = smp_processor_id(); 56 + 57 + cpumask_clear_cpu(cpu, mm_cpumask(prev)); 58 + cpumask_set_cpu(cpu, mm_cpumask(next)); 59 + 60 + /* 61 + * Use the old spbtr name instead of using the current satp 62 + * name to support binutils 2.29 which doesn't know about the 63 + * privileged ISA 1.10 yet. 64 + */ 65 + csr_write(sptbr, virt_to_pfn(next->pgd) | SATP_MODE); 66 + local_flush_tlb_all(); 67 + 68 + flush_icache_deferred(next); 69 + }
+3 -6
arch/riscv/mm/fault.c
··· 229 229 pte_t *pte_k; 230 230 int index; 231 231 232 + /* User mode accesses just cause a SIGSEGV */ 232 233 if (user_mode(regs)) 233 - goto bad_area; 234 + return do_trap(regs, SIGSEGV, code, addr, tsk); 234 235 235 236 /* 236 237 * Synchronize this task's top level page-table ··· 240 239 * Do _not_ use "tsk->active_mm->pgd" here. 241 240 * We might be inside an interrupt in the middle 242 241 * of a task switch. 243 - * 244 - * Note: Use the old spbtr name instead of using the current 245 - * satp name to support binutils 2.29 which doesn't know about 246 - * the privileged ISA 1.10 yet. 247 242 */ 248 243 index = pgd_index(addr); 249 - pgd = (pgd_t *)pfn_to_virt(csr_read(sptbr)) + index; 244 + pgd = (pgd_t *)pfn_to_virt(csr_read(CSR_SATP)) + index; 250 245 pgd_k = init_mm.pgd + index; 251 246 252 247 if (!pgd_present(*pgd_k))
+175
arch/riscv/mm/sifive_l2_cache.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * SiFive L2 cache controller Driver 4 + * 5 + * Copyright (C) 2018-2019 SiFive, Inc. 6 + * 7 + */ 8 + #include <linux/debugfs.h> 9 + #include <linux/interrupt.h> 10 + #include <linux/of_irq.h> 11 + #include <linux/of_address.h> 12 + #include <asm/sifive_l2_cache.h> 13 + 14 + #define SIFIVE_L2_DIRECCFIX_LOW 0x100 15 + #define SIFIVE_L2_DIRECCFIX_HIGH 0x104 16 + #define SIFIVE_L2_DIRECCFIX_COUNT 0x108 17 + 18 + #define SIFIVE_L2_DATECCFIX_LOW 0x140 19 + #define SIFIVE_L2_DATECCFIX_HIGH 0x144 20 + #define SIFIVE_L2_DATECCFIX_COUNT 0x148 21 + 22 + #define SIFIVE_L2_DATECCFAIL_LOW 0x160 23 + #define SIFIVE_L2_DATECCFAIL_HIGH 0x164 24 + #define SIFIVE_L2_DATECCFAIL_COUNT 0x168 25 + 26 + #define SIFIVE_L2_CONFIG 0x00 27 + #define SIFIVE_L2_WAYENABLE 0x08 28 + #define SIFIVE_L2_ECCINJECTERR 0x40 29 + 30 + #define SIFIVE_L2_MAX_ECCINTR 3 31 + 32 + static void __iomem *l2_base; 33 + static int g_irq[SIFIVE_L2_MAX_ECCINTR]; 34 + 35 + enum { 36 + DIR_CORR = 0, 37 + DATA_CORR, 38 + DATA_UNCORR, 39 + }; 40 + 41 + #ifdef CONFIG_DEBUG_FS 42 + static struct dentry *sifive_test; 43 + 44 + static ssize_t l2_write(struct file *file, const char __user *data, 45 + size_t count, loff_t *ppos) 46 + { 47 + unsigned int val; 48 + 49 + if (kstrtouint_from_user(data, count, 0, &val)) 50 + return -EINVAL; 51 + if ((val >= 0 && val < 0xFF) || (val >= 0x10000 && val < 0x100FF)) 52 + writel(val, l2_base + SIFIVE_L2_ECCINJECTERR); 53 + else 54 + return -EINVAL; 55 + return count; 56 + } 57 + 58 + static const struct file_operations l2_fops = { 59 + .owner = THIS_MODULE, 60 + .open = simple_open, 61 + .write = l2_write 62 + }; 63 + 64 + static void setup_sifive_debug(void) 65 + { 66 + sifive_test = debugfs_create_dir("sifive_l2_cache", NULL); 67 + 68 + debugfs_create_file("sifive_debug_inject_error", 0200, 69 + sifive_test, NULL, &l2_fops); 70 + } 71 + #endif 72 + 73 + static void l2_config_read(void) 74 + { 75 + u32 regval, val; 76 + 77 + regval = readl(l2_base + SIFIVE_L2_CONFIG); 78 + val = regval & 0xFF; 79 + pr_info("L2CACHE: No. of Banks in the cache: %d\n", val); 80 + val = (regval & 0xFF00) >> 8; 81 + pr_info("L2CACHE: No. of ways per bank: %d\n", val); 82 + val = (regval & 0xFF0000) >> 16; 83 + pr_info("L2CACHE: Sets per bank: %llu\n", (uint64_t)1 << val); 84 + val = (regval & 0xFF000000) >> 24; 85 + pr_info("L2CACHE: Bytes per cache block: %llu\n", (uint64_t)1 << val); 86 + 87 + regval = readl(l2_base + SIFIVE_L2_WAYENABLE); 88 + pr_info("L2CACHE: Index of the largest way enabled: %d\n", regval); 89 + } 90 + 91 + static const struct of_device_id sifive_l2_ids[] = { 92 + { .compatible = "sifive,fu540-c000-ccache" }, 93 + { /* end of table */ }, 94 + }; 95 + 96 + static ATOMIC_NOTIFIER_HEAD(l2_err_chain); 97 + 98 + int register_sifive_l2_error_notifier(struct notifier_block *nb) 99 + { 100 + return atomic_notifier_chain_register(&l2_err_chain, nb); 101 + } 102 + EXPORT_SYMBOL_GPL(register_sifive_l2_error_notifier); 103 + 104 + int unregister_sifive_l2_error_notifier(struct notifier_block *nb) 105 + { 106 + return atomic_notifier_chain_unregister(&l2_err_chain, nb); 107 + } 108 + EXPORT_SYMBOL_GPL(unregister_sifive_l2_error_notifier); 109 + 110 + static irqreturn_t l2_int_handler(int irq, void *device) 111 + { 112 + unsigned int regval, add_h, add_l; 113 + 114 + if (irq == g_irq[DIR_CORR]) { 115 + add_h = readl(l2_base + SIFIVE_L2_DIRECCFIX_HIGH); 116 + add_l = readl(l2_base + SIFIVE_L2_DIRECCFIX_LOW); 117 + pr_err("L2CACHE: DirError @ 0x%08X.%08X\n", add_h, add_l); 118 + regval = readl(l2_base + SIFIVE_L2_DIRECCFIX_COUNT); 119 + atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE, 120 + "DirECCFix"); 121 + } 122 + if (irq == g_irq[DATA_CORR]) { 123 + add_h = readl(l2_base + SIFIVE_L2_DATECCFIX_HIGH); 124 + add_l = readl(l2_base + SIFIVE_L2_DATECCFIX_LOW); 125 + pr_err("L2CACHE: DataError @ 0x%08X.%08X\n", add_h, add_l); 126 + regval = readl(l2_base + SIFIVE_L2_DATECCFIX_COUNT); 127 + atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE, 128 + "DatECCFix"); 129 + } 130 + if (irq == g_irq[DATA_UNCORR]) { 131 + add_h = readl(l2_base + SIFIVE_L2_DATECCFAIL_HIGH); 132 + add_l = readl(l2_base + SIFIVE_L2_DATECCFAIL_LOW); 133 + pr_err("L2CACHE: DataFail @ 0x%08X.%08X\n", add_h, add_l); 134 + regval = readl(l2_base + SIFIVE_L2_DATECCFAIL_COUNT); 135 + atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_UE, 136 + "DatECCFail"); 137 + } 138 + 139 + return IRQ_HANDLED; 140 + } 141 + 142 + int __init sifive_l2_init(void) 143 + { 144 + struct device_node *np; 145 + struct resource res; 146 + int i, rc; 147 + 148 + np = of_find_matching_node(NULL, sifive_l2_ids); 149 + if (!np) 150 + return -ENODEV; 151 + 152 + if (of_address_to_resource(np, 0, &res)) 153 + return -ENODEV; 154 + 155 + l2_base = ioremap(res.start, resource_size(&res)); 156 + if (!l2_base) 157 + return -ENOMEM; 158 + 159 + for (i = 0; i < SIFIVE_L2_MAX_ECCINTR; i++) { 160 + g_irq[i] = irq_of_parse_and_map(np, i); 161 + rc = request_irq(g_irq[i], l2_int_handler, 0, "l2_ecc", NULL); 162 + if (rc) { 163 + pr_err("L2CACHE: Could not request IRQ %d\n", g_irq[i]); 164 + return rc; 165 + } 166 + } 167 + 168 + l2_config_read(); 169 + 170 + #ifdef CONFIG_DEBUG_FS 171 + setup_sifive_debug(); 172 + #endif 173 + return 0; 174 + } 175 + device_initcall(sifive_l2_init);
-1
drivers/tty/hvc/hvc_riscv_sbi.c
··· 53 53 static int __init hvc_sbi_console_init(void) 54 54 { 55 55 hvc_instantiate(0, 0, &hvc_sbi_ops); 56 - add_preferred_console("hvc", 0, NULL); 57 56 58 57 return 0; 59 58 }