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

Merge tag 'csky-for-linus-5.2-rc1' of git://github.com/c-sky/csky-linux

Pull arch/csky updates from Guo Ren:

- Fixup vdsp&fpu issues in kernel

- Add dynamic function tracer

- Use in_syscall & forget_syscall instead of r11_sig

- Reconstruct signal processing

- Support dynamic start physical address

- Fixup wrong update_mmu_cache implementation

- Support vmlinux bootup with MMU off

- Use va_pa_offset instead of phys_offset

- Fixup syscall_trace return processing flow

- Add perf callchain support

- Add perf_arch_fetch_caller_regs support

- Add page fault perf event support

- Add support for perf registers sampling

* tag 'csky-for-linus-5.2-rc1' of git://github.com/c-sky/csky-linux:
csky/syscall_trace: Fixup return processing flow
csky: Fixup compile warning
csky: Add support for perf registers sampling
csky: add page fault perf event support
csky: Use va_pa_offset instead of phys_offset
csky: Support vmlinux bootup with MMU off
csky: Add perf_arch_fetch_caller_regs support
csky: Fixup wrong update_mmu_cache implementation
csky: Support dynamic start physical address
csky: Reconstruct signal processing
csky: Use in_syscall & forget_syscall instead of r11_sig
csky: Add non-uapi asm/ptrace.h namespace
csky: mm/fault.c: Remove duplicate header
csky: remove redundant generic-y
csky: Update syscall_trace_enter/exit implementation
csky: Add perf callchain support
csky/ftrace: Add dynamic function tracer (include graph tracer)
csky: Fixup vdsp&fpu issues in kernel

+895 -507
+6 -1
arch/csky/Kconfig
··· 29 29 select GENERIC_SCHED_CLOCK 30 30 select GENERIC_SMP_IDLE_THREAD 31 31 select HAVE_ARCH_TRACEHOOK 32 + select HAVE_ARCH_AUDITSYSCALL 33 + select HAVE_DYNAMIC_FTRACE 32 34 select HAVE_FUNCTION_TRACER 33 35 select HAVE_FUNCTION_GRAPH_TRACER 36 + select HAVE_FTRACE_MCOUNT_RECORD 34 37 select HAVE_KERNEL_GZIP 35 38 select HAVE_KERNEL_LZO 36 39 select HAVE_KERNEL_LZMA 37 40 select HAVE_PERF_EVENTS 38 - select HAVE_C_RECORDMCOUNT 41 + select HAVE_PERF_REGS 42 + select HAVE_PERF_USER_STACK_DUMP 39 43 select HAVE_DMA_API_DEBUG 40 44 select HAVE_DMA_CONTIGUOUS 45 + select HAVE_SYSCALL_TRACEPOINTS 41 46 select MAY_HAVE_SPARSE_IRQ 42 47 select MODULES_USE_ELF_RELA if MODULES 43 48 select OF
+1 -1
arch/csky/Makefile
··· 36 36 37 37 ifneq ($(CSKYABI),) 38 38 MCPU_STR = $(CPUTYPE)$(FPUEXT)$(VDSPEXT)$(TEEEXT) 39 - KBUILD_CFLAGS += -mcpu=$(MCPU_STR) 39 + KBUILD_CFLAGS += -mcpu=$(CPUTYPE) -Wa,-mcpu=$(MCPU_STR) 40 40 KBUILD_CFLAGS += -DCSKYCPU_DEF_NAME=\"$(MCPU_STR)\" 41 41 KBUILD_CFLAGS += -msoft-float -mdiv 42 42 KBUILD_CFLAGS += -fno-tree-vectorize
+22 -2
arch/csky/abiv1/inc/abi/ckmmu.h
··· 40 40 cpwcr("cpcr4", value); 41 41 } 42 42 43 + static inline unsigned long read_mmu_msa0(void) 44 + { 45 + return cprcr("cpcr30"); 46 + } 47 + 48 + static inline void write_mmu_msa0(unsigned long value) 49 + { 50 + cpwcr("cpcr30", value); 51 + } 52 + 53 + static inline unsigned long read_mmu_msa1(void) 54 + { 55 + return cprcr("cpcr31"); 56 + } 57 + 58 + static inline void write_mmu_msa1(unsigned long value) 59 + { 60 + cpwcr("cpcr31", value); 61 + } 62 + 43 63 /* 44 64 * TLB operations. 45 65 */ ··· 85 65 86 66 static inline void setup_pgd(unsigned long pgd, bool kernel) 87 67 { 88 - cpwcr("cpcr29", pgd); 68 + cpwcr("cpcr29", pgd | BIT(0)); 89 69 } 90 70 91 71 static inline unsigned long get_pgd(void) 92 72 { 93 - return cprcr("cpcr29"); 73 + return cprcr("cpcr29") & ~BIT(0); 94 74 } 95 75 #endif /* __ASM_CSKY_CKMMUV1_H */
+29 -12
arch/csky/abiv1/inc/abi/entry.h
··· 16 16 #define LSAVE_A4 40 17 17 #define LSAVE_A5 44 18 18 19 - #define EPC_INCREASE 2 20 - #define EPC_KEEP 0 21 - 22 19 .macro USPTOKSP 23 20 mtcr sp, ss1 24 21 mfcr sp, ss0 ··· 24 27 .macro KSPTOUSP 25 28 mtcr sp, ss0 26 29 mfcr sp, ss1 27 - .endm 28 - 29 - .macro INCTRAP rx 30 - addi \rx, EPC_INCREASE 31 30 .endm 32 31 33 32 .macro SAVE_ALL epc_inc ··· 143 150 cpwcr \rx, cpcr8 144 151 .endm 145 152 146 - .macro SETUP_MMU rx 147 - lrw \rx, PHYS_OFFSET | 0xe 148 - cpwcr \rx, cpcr30 149 - lrw \rx, (PHYS_OFFSET + 0x20000000) | 0xe 150 - cpwcr \rx, cpcr31 153 + .macro SETUP_MMU 154 + /* Init psr and enable ee */ 155 + lrw r6, DEFAULT_PSR_VALUE 156 + mtcr r6, psr 157 + psrset ee 158 + 159 + /* Select MMU as co-processor */ 160 + cpseti cp15 161 + 162 + /* 163 + * cpcr30 format: 164 + * 31 - 29 | 28 - 4 | 3 | 2 | 1 | 0 165 + * BA Reserved C D V 166 + */ 167 + cprcr r6, cpcr30 168 + lsri r6, 28 169 + lsli r6, 28 170 + addi r6, 0xe 171 + cpwcr r6, cpcr30 172 + 173 + lsri r6, 28 174 + addi r6, 2 175 + lsli r6, 28 176 + addi r6, 0xe 177 + cpwcr r6, cpcr31 151 178 .endm 152 179 180 + .macro ANDI_R3 rx, imm 181 + lsri \rx, 3 182 + andi \rx, (\imm >> 3) 183 + .endm 153 184 #endif /* __ASM_CSKY_ENTRY_H */
+3 -2
arch/csky/abiv1/inc/abi/regdef.h
··· 5 5 #define __ASM_CSKY_REGDEF_H 6 6 7 7 #define syscallid r1 8 - #define r11_sig r11 9 - 10 8 #define regs_syscallid(regs) regs->regs[9] 9 + #define regs_fp(regs) regs->regs[2] 11 10 12 11 /* 13 12 * PSR format: ··· 21 22 #define DEFAULT_PSR_VALUE 0x8f000000 22 23 23 24 #define SYSTRACE_SAVENUM 2 25 + 26 + #define TRAP0_SIZE 2 24 27 25 28 #endif /* __ASM_CSKY_REGDEF_H */
+2 -11
arch/csky/abiv2/cacheflush.c
··· 34 34 { 35 35 unsigned long addr, pfn; 36 36 struct page *page; 37 - void *va; 38 - 39 - if (!(vma->vm_flags & VM_EXEC)) 40 - return; 41 37 42 38 pfn = pte_pfn(*pte); 43 39 if (unlikely(!pfn_valid(pfn))) ··· 43 47 if (page == ZERO_PAGE(0)) 44 48 return; 45 49 46 - va = page_address(page); 47 - addr = (unsigned long) va; 48 - 49 - if (va == NULL && PageHighMem(page)) 50 - addr = (unsigned long) kmap_atomic(page); 50 + addr = (unsigned long) kmap_atomic(page); 51 51 52 52 cache_wbinv_range(addr, addr + PAGE_SIZE); 53 53 54 - if (va == NULL && PageHighMem(page)) 55 - kunmap_atomic((void *) addr); 54 + kunmap_atomic((void *) addr); 56 55 }
+26 -8
arch/csky/abiv2/inc/abi/ckmmu.h
··· 42 42 mtcr("cr<4, 15>", value); 43 43 } 44 44 45 + static inline unsigned long read_mmu_msa0(void) 46 + { 47 + return mfcr("cr<30, 15>"); 48 + } 49 + 50 + static inline void write_mmu_msa0(unsigned long value) 51 + { 52 + mtcr("cr<30, 15>", value); 53 + } 54 + 55 + static inline unsigned long read_mmu_msa1(void) 56 + { 57 + return mfcr("cr<31, 15>"); 58 + } 59 + 60 + static inline void write_mmu_msa1(unsigned long value) 61 + { 62 + mtcr("cr<31, 15>", value); 63 + } 64 + 45 65 /* 46 66 * TLB operations. 47 67 */ ··· 90 70 mtcr("cr<8, 15>", 0x02000000); 91 71 } 92 72 93 - /* setup hardrefil pgd */ 94 - static inline unsigned long get_pgd(void) 95 - { 96 - return mfcr("cr<29, 15>"); 97 - } 98 - 99 73 static inline void setup_pgd(unsigned long pgd, bool kernel) 100 74 { 101 75 if (kernel) 102 - mtcr("cr<28, 15>", pgd); 76 + mtcr("cr<28, 15>", pgd | BIT(0)); 103 77 else 104 - mtcr("cr<29, 15>", pgd); 78 + mtcr("cr<29, 15>", pgd | BIT(0)); 105 79 } 106 80 81 + static inline unsigned long get_pgd(void) 82 + { 83 + return mfcr("cr<29, 15>") & ~BIT(0); 84 + } 107 85 #endif /* __ASM_CSKY_CKMMUV2_H */
+75 -12
arch/csky/abiv2/inc/abi/entry.h
··· 14 14 #define LSAVE_A2 32 15 15 #define LSAVE_A3 36 16 16 17 - #define EPC_INCREASE 4 18 - #define EPC_KEEP 0 19 - 20 17 #define KSPTOUSP 21 18 #define USPTOKSP 22 19 23 20 #define usp cr<14, 1> 24 - 25 - .macro INCTRAP rx 26 - addi \rx, EPC_INCREASE 27 - .endm 28 21 29 22 .macro SAVE_ALL epc_inc 30 23 subi sp, 152 ··· 162 169 mtcr \rx, cr<8, 15> 163 170 .endm 164 171 165 - .macro SETUP_MMU rx 166 - lrw \rx, PHYS_OFFSET | 0xe 167 - mtcr \rx, cr<30, 15> 168 - lrw \rx, (PHYS_OFFSET + 0x20000000) | 0xe 169 - mtcr \rx, cr<31, 15> 172 + .macro SETUP_MMU 173 + /* Init psr and enable ee */ 174 + lrw r6, DEFAULT_PSR_VALUE 175 + mtcr r6, psr 176 + psrset ee 177 + 178 + /* Invalid I/Dcache BTB BHT */ 179 + movi r6, 7 180 + lsli r6, 16 181 + addi r6, (1<<4) | 3 182 + mtcr r6, cr17 183 + 184 + /* Invalid all TLB */ 185 + bgeni r6, 26 186 + mtcr r6, cr<8, 15> /* Set MCIR */ 187 + 188 + /* Check MMU on/off */ 189 + mfcr r6, cr18 190 + btsti r6, 0 191 + bt 1f 192 + 193 + /* MMU off: setup mapping tlb entry */ 194 + movi r6, 0 195 + mtcr r6, cr<6, 15> /* Set MPR with 4K page size */ 196 + 197 + grs r6, 1f /* Get current pa by PC */ 198 + bmaski r7, (PAGE_SHIFT + 1) /* r7 = 0x1fff */ 199 + andn r6, r7 200 + mtcr r6, cr<4, 15> /* Set MEH */ 201 + 202 + mov r8, r6 203 + movi r7, 0x00000006 204 + or r8, r7 205 + mtcr r8, cr<2, 15> /* Set MEL0 */ 206 + movi r7, 0x00001006 207 + or r8, r7 208 + mtcr r8, cr<3, 15> /* Set MEL1 */ 209 + 210 + bgeni r8, 28 211 + mtcr r8, cr<8, 15> /* Set MCIR to write TLB */ 212 + 213 + br 2f 214 + 1: 215 + /* 216 + * MMU on: use origin MSA value from bootloader 217 + * 218 + * cr<30/31, 15> MSA register format: 219 + * 31 - 29 | 28 - 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 220 + * BA Reserved SH WA B SO SEC C D V 221 + */ 222 + mfcr r6, cr<30, 15> /* Get MSA0 */ 223 + 2: 224 + lsri r6, 28 225 + lsli r6, 28 226 + addi r6, 0x1ce 227 + mtcr r6, cr<30, 15> /* Set MSA0 */ 228 + 229 + lsri r6, 28 230 + addi r6, 2 231 + lsli r6, 28 232 + addi r6, 0x1ce 233 + mtcr r6, cr<31, 15> /* Set MSA1 */ 234 + 235 + /* enable MMU */ 236 + mfcr r6, cr18 237 + bseti r6, 0 238 + mtcr r6, cr18 239 + 240 + jmpi 3f /* jump to va */ 241 + 3: 242 + .endm 243 + 244 + .macro ANDI_R3 rx, imm 245 + lsri \rx, 3 246 + andi \rx, (\imm >> 3) 170 247 .endm 171 248 #endif /* __ASM_CSKY_ENTRY_H */
+3 -2
arch/csky/abiv2/inc/abi/regdef.h
··· 5 5 #define __ASM_CSKY_REGDEF_H 6 6 7 7 #define syscallid r7 8 - #define r11_sig r11 9 - 10 8 #define regs_syscallid(regs) regs->regs[3] 9 + #define regs_fp(regs) regs->regs[4] 11 10 12 11 /* 13 12 * PSR format: ··· 21 22 #define DEFAULT_PSR_VALUE 0x80000200 22 23 23 24 #define SYSTRACE_SAVENUM 5 25 + 26 + #define TRAP0_SIZE 4 24 27 25 28 #endif /* __ASM_CSKY_REGDEF_H */
+37 -2
arch/csky/abiv2/mcount.S
··· 61 61 addi sp, 16 62 62 .endm 63 63 64 + .macro nop32_stub 65 + nop32 66 + nop32 67 + nop32 68 + .endm 69 + 64 70 ENTRY(ftrace_stub) 65 71 jmp lr 66 72 END(ftrace_stub) 67 73 74 + #ifndef CONFIG_DYNAMIC_FTRACE 68 75 ENTRY(_mcount) 69 76 mcount_enter 70 77 ··· 83 76 bf skip_ftrace 84 77 85 78 mov a0, lr 86 - subi a0, MCOUNT_INSN_SIZE 79 + subi a0, 4 87 80 ldw a1, (sp, 24) 88 81 89 82 jsr r26 ··· 108 101 mcount_exit 109 102 #endif 110 103 END(_mcount) 104 + #else /* CONFIG_DYNAMIC_FTRACE */ 105 + ENTRY(_mcount) 106 + mov t1, lr 107 + ldw lr, (sp, 0) 108 + addi sp, 4 109 + jmp t1 110 + ENDPROC(_mcount) 111 + 112 + ENTRY(ftrace_caller) 113 + mcount_enter 114 + 115 + ldw a0, (sp, 16) 116 + subi a0, 4 117 + ldw a1, (sp, 24) 118 + 119 + nop 120 + GLOBAL(ftrace_call) 121 + nop32_stub 122 + 123 + #ifdef CONFIG_FUNCTION_GRAPH_TRACER 124 + nop 125 + GLOBAL(ftrace_graph_call) 126 + nop32_stub 127 + #endif 128 + 129 + mcount_exit 130 + ENDPROC(ftrace_caller) 131 + #endif /* CONFIG_DYNAMIC_FTRACE */ 111 132 112 133 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 113 134 ENTRY(ftrace_graph_caller) 114 135 mov a0, sp 115 136 addi a0, 24 116 137 ldw a1, (sp, 16) 117 - subi a1, MCOUNT_INSN_SIZE 138 + subi a1, 4 118 139 mov a2, r8 119 140 lrw r26, prepare_ftrace_return 120 141 jsr r26
+1 -5
arch/csky/abiv2/memmove.S
··· 35 35 .L_len_larger_16bytes: 36 36 subi r1, 16 37 37 subi r0, 16 38 - #if defined(__CSKY_VDSPV2__) 39 - vldx.8 vr0, (r1), r19 40 - PRE_BNEZAD (r18) 41 - vstx.8 vr0, (r0), r19 42 - #elif defined(__CK860__) 38 + #if defined(__CK860__) 43 39 ldw r3, (r1, 12) 44 40 stw r3, (r0, 12) 45 41 ldw r3, (r1, 8)
-1
arch/csky/include/asm/Kbuild
··· 12 12 generic-y += emergency-restart.h 13 13 generic-y += exec.h 14 14 generic-y += fb.h 15 - generic-y += ftrace.h 16 15 generic-y += futex.h 17 16 generic-y += gpio.h 18 17 generic-y += hardirq.h
+17 -1
arch/csky/include/asm/ftrace.h
··· 4 4 #ifndef __ASM_CSKY_FTRACE_H 5 5 #define __ASM_CSKY_FTRACE_H 6 6 7 - #define MCOUNT_INSN_SIZE 4 7 + #define MCOUNT_INSN_SIZE 14 8 8 9 9 #define HAVE_FUNCTION_GRAPH_FP_TEST 10 10 11 11 #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR 12 12 13 + #define MCOUNT_ADDR ((unsigned long)_mcount) 14 + 15 + #ifndef __ASSEMBLY__ 16 + 17 + extern void _mcount(unsigned long); 18 + 19 + extern void ftrace_graph_call(void); 20 + 21 + static inline unsigned long ftrace_call_adjust(unsigned long addr) 22 + { 23 + return addr; 24 + } 25 + 26 + struct dyn_arch_ftrace { 27 + }; 28 + #endif /* !__ASSEMBLY__ */ 13 29 #endif /* __ASM_CSKY_FTRACE_H */
+2 -15
arch/csky/include/asm/mmu_context.h
··· 14 14 #include <linux/sched.h> 15 15 #include <abi/ckmmu.h> 16 16 17 - static inline void tlbmiss_handler_setup_pgd(unsigned long pgd, bool kernel) 18 - { 19 - pgd -= PAGE_OFFSET; 20 - pgd += PHYS_OFFSET; 21 - pgd |= 1; 22 - setup_pgd(pgd, kernel); 23 - } 24 - 25 17 #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ 26 - tlbmiss_handler_setup_pgd((unsigned long)pgd, 0) 18 + setup_pgd(__pa(pgd), false) 27 19 #define TLBMISS_HANDLER_SETUP_PGD_KERNEL(pgd) \ 28 - tlbmiss_handler_setup_pgd((unsigned long)pgd, 1) 29 - 30 - static inline unsigned long tlb_get_pgd(void) 31 - { 32 - return ((get_pgd() - PHYS_OFFSET) & ~1) + PAGE_OFFSET; 33 - } 20 + setup_pgd(__pa(pgd), true) 34 21 35 22 #define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) 36 23 #define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK)
+16 -23
arch/csky/include/asm/page.h
··· 8 8 #include <linux/const.h> 9 9 10 10 /* 11 - * PAGE_SHIFT determines the page size 11 + * PAGE_SHIFT determines the page size: 4KB 12 12 */ 13 13 #define PAGE_SHIFT 12 14 14 #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) ··· 17 17 #define THREAD_MASK (~(THREAD_SIZE - 1)) 18 18 #define THREAD_SHIFT (PAGE_SHIFT + 1) 19 19 20 + 20 21 /* 21 - * NOTE: virtual isn't really correct, actually it should be the offset into the 22 - * memory node, but we have no highmem, so that works for now. 23 - * TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots 24 - * of the shifts unnecessary. 22 + * For C-SKY "User-space:Kernel-space" is "2GB:2GB" fixed by hardware and there 23 + * are two segment registers (MSA0 + MSA1) to mapping 512MB + 512MB physical 24 + * address region. We use them mapping kernel 1GB direct-map address area and 25 + * for more than 1GB of memory we use highmem. 25 26 */ 27 + #define PAGE_OFFSET 0x80000000 28 + #define SSEG_SIZE 0x20000000 29 + #define LOWMEM_LIMIT (SSEG_SIZE * 2) 30 + 31 + #define PHYS_OFFSET_OFFSET (CONFIG_RAM_BASE & (SSEG_SIZE - 1)) 26 32 27 33 #ifndef __ASSEMBLY__ 28 34 ··· 56 50 57 51 struct vm_area_struct; 58 52 59 - /* 60 - * These are used to make use of C type-checking.. 61 - */ 62 53 typedef struct { unsigned long pte_low; } pte_t; 63 54 #define pte_val(x) ((x).pte_low) 64 55 ··· 72 69 #define __pgd(x) ((pgd_t) { (x) }) 73 70 #define __pgprot(x) ((pgprot_t) { (x) }) 74 71 75 - #endif /* !__ASSEMBLY__ */ 72 + extern unsigned long va_pa_offset; 76 73 77 - #define PHYS_OFFSET (CONFIG_RAM_BASE & ~(LOWMEM_LIMIT - 1)) 78 - #define PHYS_OFFSET_OFFSET (CONFIG_RAM_BASE & (LOWMEM_LIMIT - 1)) 79 - #define ARCH_PFN_OFFSET PFN_DOWN(CONFIG_RAM_BASE) 74 + #define ARCH_PFN_OFFSET PFN_DOWN(va_pa_offset + PHYS_OFFSET_OFFSET) 80 75 81 - #define PAGE_OFFSET 0x80000000 82 - #define LOWMEM_LIMIT 0x40000000 76 + #define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + va_pa_offset) 77 + #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - va_pa_offset)) 83 78 84 - #define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) 85 - #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - \ 86 - PHYS_OFFSET)) 87 79 #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) 88 80 89 81 #define MAP_NR(x) PFN_DOWN((unsigned long)(x) - PAGE_OFFSET - \ ··· 88 90 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ 89 91 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 90 92 91 - /* 92 - * main RAM and kernel working space are coincident at 0x80000000, but to make 93 - * life more interesting, there's also an uncached virtual shadow at 0xb0000000 94 - * - these mappings are fixed in the MMU 95 - */ 96 - 97 93 #define pfn_to_kaddr(x) __va(PFN_PHYS(x)) 98 94 99 95 #include <asm-generic/memory_model.h> 100 96 #include <asm-generic/getorder.h> 101 97 98 + #endif /* !__ASSEMBLY__ */ 102 99 #endif /* __ASM_CSKY_PAGE_H */
+8
arch/csky/include/asm/perf_event.h
··· 4 4 #ifndef __ASM_CSKY_PERF_EVENT_H 5 5 #define __ASM_CSKY_PERF_EVENT_H 6 6 7 + #include <abi/regdef.h> 8 + 9 + #define perf_arch_fetch_caller_regs(regs, __ip) { \ 10 + (regs)->pc = (__ip); \ 11 + regs_fp(regs) = (unsigned long) __builtin_frame_address(0); \ 12 + asm volatile("mov %0, sp\n":"=r"((regs)->usp)); \ 13 + } 14 + 7 15 #endif /* __ASM_PERF_EVENT_ELF_H */
+41
arch/csky/include/asm/ptrace.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3 + 4 + #ifndef __ASM_CSKY_PTRACE_H 5 + #define __ASM_CSKY_PTRACE_H 6 + 7 + #include <uapi/asm/ptrace.h> 8 + #include <asm/traps.h> 9 + #include <linux/types.h> 10 + 11 + #ifndef __ASSEMBLY__ 12 + 13 + #define PS_S 0x80000000 /* Supervisor Mode */ 14 + 15 + #define arch_has_single_step() (1) 16 + #define current_pt_regs() \ 17 + ({ (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1; }) 18 + 19 + #define user_stack_pointer(regs) ((regs)->usp) 20 + 21 + #define user_mode(regs) (!((regs)->sr & PS_S)) 22 + #define instruction_pointer(regs) ((regs)->pc) 23 + #define profile_pc(regs) instruction_pointer(regs) 24 + 25 + static inline bool in_syscall(struct pt_regs const *regs) 26 + { 27 + return ((regs->sr >> 16) & 0xff) == VEC_TRAP0; 28 + } 29 + 30 + static inline void forget_syscall(struct pt_regs *regs) 31 + { 32 + regs->sr &= ~(0xff << 16); 33 + } 34 + 35 + static inline unsigned long regs_return_value(struct pt_regs *regs) 36 + { 37 + return regs->a0; 38 + } 39 + 40 + #endif /* __ASSEMBLY__ */ 41 + #endif /* __ASM_CSKY_PTRACE_H */
+9
arch/csky/include/asm/syscall.h
··· 8 8 #include <abi/regdef.h> 9 9 #include <uapi/linux/audit.h> 10 10 11 + extern void *sys_call_table[]; 12 + 11 13 static inline int 12 14 syscall_get_nr(struct task_struct *task, struct pt_regs *regs) 13 15 { 14 16 return regs_syscallid(regs); 17 + } 18 + 19 + static inline void 20 + syscall_set_nr(struct task_struct *task, struct pt_regs *regs, 21 + int sysno) 22 + { 23 + regs_syscallid(regs) = sysno; 15 24 } 16 25 17 26 static inline void
+12 -15
arch/csky/include/asm/thread_info.h
··· 51 51 52 52 #endif /* !__ASSEMBLY__ */ 53 53 54 - /* entry.S relies on these definitions! 55 - * bits 0-5 are tested at every exception exit 56 - */ 57 54 #define TIF_SIGPENDING 0 /* signal pending */ 58 55 #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ 59 56 #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ 60 - #define TIF_SYSCALL_TRACE 5 /* syscall trace active */ 61 - #define TIF_DELAYED_TRACE 14 /* single step a syscall */ 57 + #define TIF_SYSCALL_TRACE 3 /* syscall trace active */ 58 + #define TIF_SYSCALL_TRACEPOINT 4 /* syscall tracepoint instrumentation */ 59 + #define TIF_SYSCALL_AUDIT 5 /* syscall auditing */ 62 60 #define TIF_POLLING_NRFLAG 16 /* poll_idle() is TIF_NEED_RESCHED */ 63 61 #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ 64 - #define TIF_FREEZE 19 /* thread is freezing for suspend */ 65 62 #define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */ 66 63 #define TIF_SECCOMP 21 /* secure computing */ 67 64 68 - #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 69 - #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) 70 - #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 71 - #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 72 - #define _TIF_DELAYED_TRACE (1 << TIF_DELAYED_TRACE) 73 - #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) 65 + #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 66 + #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) 67 + #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 68 + #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 69 + #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) 70 + #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) 71 + #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) 74 72 #define _TIF_MEMDIE (1 << TIF_MEMDIE) 75 - #define _TIF_FREEZE (1 << TIF_FREEZE) 76 - #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) 77 - #define _TIF_SECCOMP (1 << TIF_SECCOMP) 73 + #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) 74 + #define _TIF_SECCOMP (1 << TIF_SECCOMP) 78 75 79 76 #endif /* _ASM_CSKY_THREAD_INFO_H */
+2
arch/csky/include/asm/unistd.h
··· 2 2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3 3 4 4 #include <uapi/asm/unistd.h> 5 + 6 + #define NR_syscalls (__NR_syscalls)
+51
arch/csky/include/uapi/asm/perf_regs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + // Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. 3 + 4 + #ifndef _ASM_CSKY_PERF_REGS_H 5 + #define _ASM_CSKY_PERF_REGS_H 6 + 7 + /* Index of struct pt_regs */ 8 + enum perf_event_csky_regs { 9 + PERF_REG_CSKY_TLS, 10 + PERF_REG_CSKY_LR, 11 + PERF_REG_CSKY_PC, 12 + PERF_REG_CSKY_SR, 13 + PERF_REG_CSKY_SP, 14 + PERF_REG_CSKY_ORIG_A0, 15 + PERF_REG_CSKY_A0, 16 + PERF_REG_CSKY_A1, 17 + PERF_REG_CSKY_A2, 18 + PERF_REG_CSKY_A3, 19 + PERF_REG_CSKY_REGS0, 20 + PERF_REG_CSKY_REGS1, 21 + PERF_REG_CSKY_REGS2, 22 + PERF_REG_CSKY_REGS3, 23 + PERF_REG_CSKY_REGS4, 24 + PERF_REG_CSKY_REGS5, 25 + PERF_REG_CSKY_REGS6, 26 + PERF_REG_CSKY_REGS7, 27 + PERF_REG_CSKY_REGS8, 28 + PERF_REG_CSKY_REGS9, 29 + #if defined(__CSKYABIV2__) 30 + PERF_REG_CSKY_EXREGS0, 31 + PERF_REG_CSKY_EXREGS1, 32 + PERF_REG_CSKY_EXREGS2, 33 + PERF_REG_CSKY_EXREGS3, 34 + PERF_REG_CSKY_EXREGS4, 35 + PERF_REG_CSKY_EXREGS5, 36 + PERF_REG_CSKY_EXREGS6, 37 + PERF_REG_CSKY_EXREGS7, 38 + PERF_REG_CSKY_EXREGS8, 39 + PERF_REG_CSKY_EXREGS9, 40 + PERF_REG_CSKY_EXREGS10, 41 + PERF_REG_CSKY_EXREGS11, 42 + PERF_REG_CSKY_EXREGS12, 43 + PERF_REG_CSKY_EXREGS13, 44 + PERF_REG_CSKY_EXREGS14, 45 + PERF_REG_CSKY_HI, 46 + PERF_REG_CSKY_LO, 47 + PERF_REG_CSKY_DCSR, 48 + #endif 49 + PERF_REG_CSKY_MAX, 50 + }; 51 + #endif /* _ASM_CSKY_PERF_REGS_H */
-15
arch/csky/include/uapi/asm/ptrace.h
··· 48 48 unsigned long reserved; 49 49 }; 50 50 51 - #ifdef __KERNEL__ 52 - 53 - #define PS_S 0x80000000 /* Supervisor Mode */ 54 - 55 - #define arch_has_single_step() (1) 56 - #define current_pt_regs() \ 57 - ({ (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1; }) 58 - 59 - #define user_stack_pointer(regs) ((regs)->usp) 60 - 61 - #define user_mode(regs) (!((regs)->sr & PS_S)) 62 - #define instruction_pointer(regs) ((regs)->pc) 63 - #define profile_pc(regs) instruction_pointer(regs) 64 - 65 - #endif /* __KERNEL__ */ 66 51 #endif /* __ASSEMBLY__ */ 67 52 #endif /* _CSKY_PTRACE_H */
+2
arch/csky/kernel/Makefile
··· 9 9 obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o 10 10 obj-$(CONFIG_STACKTRACE) += stacktrace.o 11 11 obj-$(CONFIG_CSKY_PMU_V1) += perf_event.o 12 + obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o 13 + obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o 12 14 13 15 ifdef CONFIG_FUNCTION_TRACER 14 16 CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
+4 -22
arch/csky/kernel/atomic.S
··· 12 12 * If *ptr != oldval && return 1, 13 13 * else *ptr = newval return 0. 14 14 */ 15 - #ifdef CONFIG_CPU_HAS_LDSTEX 16 15 ENTRY(csky_cmpxchg) 17 16 USPTOKSP 18 17 mfcr a3, epc 19 - INCTRAP a3 18 + addi a3, TRAP0_SIZE 20 19 21 20 subi sp, 8 22 21 stw a3, (sp, 0) ··· 23 24 stw a3, (sp, 4) 24 25 25 26 psrset ee 27 + #ifdef CONFIG_CPU_HAS_LDSTEX 26 28 1: 27 29 ldex a3, (a2) 28 30 cmpne a0, a3 ··· 33 33 bez a3, 1b 34 34 2: 35 35 sync.is 36 - mvc a0 37 - ldw a3, (sp, 0) 38 - mtcr a3, epc 39 - ldw a3, (sp, 4) 40 - mtcr a3, epsr 41 - addi sp, 8 42 - KSPTOUSP 43 - rte 44 - END(csky_cmpxchg) 45 36 #else 46 - ENTRY(csky_cmpxchg) 47 - USPTOKSP 48 - mfcr a3, epc 49 - INCTRAP a3 50 - 51 - subi sp, 8 52 - stw a3, (sp, 0) 53 - mfcr a3, epsr 54 - stw a3, (sp, 4) 55 - 56 - psrset ee 57 37 1: 58 38 ldw a3, (a2) 59 39 cmpne a0, a3 ··· 41 61 2: 42 62 stw a1, (a2) 43 63 3: 64 + #endif 44 65 mvc a0 45 66 ldw a3, (sp, 0) 46 67 mtcr a3, epc ··· 52 71 rte 53 72 END(csky_cmpxchg) 54 73 74 + #ifndef CONFIG_CPU_HAS_LDSTEX 55 75 /* 56 76 * Called from tlbmodified exception 57 77 */
+31 -46
arch/csky/kernel/entry.S
··· 40 40 WR_MCIR a2 41 41 #endif 42 42 bclri r6, 0 43 - lrw a2, PHYS_OFFSET 43 + lrw a2, va_pa_offset 44 + ld.w a2, (a2, 0) 44 45 subu r6, a2 45 46 bseti r6, 31 46 47 ··· 51 50 addu r6, a2 52 51 ldw r6, (r6) 53 52 54 - lrw a2, PHYS_OFFSET 53 + lrw a2, va_pa_offset 54 + ld.w a2, (a2, 0) 55 55 subu r6, a2 56 56 bseti r6, 31 57 57 ··· 93 91 mfcr a3, ss2 94 92 mfcr r6, ss3 95 93 mfcr a2, ss4 96 - SAVE_ALL EPC_KEEP 94 + SAVE_ALL 0 97 95 .endm 98 96 .macro tlbop_end is_write 99 97 RD_MEH a2 ··· 101 99 mov a0, sp 102 100 movi a1, \is_write 103 101 jbsr do_page_fault 104 - movi r11_sig, 0 /* r11 = 0, Not a syscall. */ 105 102 jmpi ret_from_exception 106 103 .endm 107 104 ··· 119 118 tlbop_end 1 120 119 121 120 ENTRY(csky_systemcall) 122 - SAVE_ALL EPC_INCREASE 121 + SAVE_ALL TRAP0_SIZE 123 122 124 123 psrset ee, ie 125 124 ··· 137 136 bmaski r10, THREAD_SHIFT 138 137 andn r9, r10 139 138 ldw r8, (r9, TINFO_FLAGS) 140 - btsti r8, TIF_SYSCALL_TRACE 141 - bt 1f 139 + ANDI_R3 r8, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT) 140 + cmpnei r8, 0 141 + bt csky_syscall_trace 142 142 #if defined(__CSKYABIV2__) 143 143 subi sp, 8 144 144 stw r5, (sp, 0x4) ··· 152 150 stw a0, (sp, LSAVE_A0) /* Save return value */ 153 151 jmpi ret_from_exception 154 152 155 - 1: 156 - movi a0, 0 /* enter system call */ 157 - mov a1, sp /* sp = pt_regs pointer */ 158 - jbsr syscall_trace 153 + csky_syscall_trace: 154 + mov a0, sp /* sp = pt_regs pointer */ 155 + jbsr syscall_trace_enter 159 156 /* Prepare args before do system call */ 160 157 ldw a0, (sp, LSAVE_A0) 161 158 ldw a1, (sp, LSAVE_A1) ··· 174 173 #endif 175 174 stw a0, (sp, LSAVE_A0) /* Save return value */ 176 175 177 - movi a0, 1 /* leave system call */ 178 - mov a1, sp /* right now, sp --> pt_regs */ 179 - jbsr syscall_trace 176 + mov a0, sp /* right now, sp --> pt_regs */ 177 + jbsr syscall_trace_exit 180 178 br ret_from_exception 181 179 182 180 ENTRY(ret_from_kernel_thread) ··· 190 190 bmaski r10, THREAD_SHIFT 191 191 andn r9, r10 192 192 ldw r8, (r9, TINFO_FLAGS) 193 - movi r11_sig, 1 194 - btsti r8, TIF_SYSCALL_TRACE 195 - bf 3f 196 - movi a0, 1 197 - mov a1, sp /* sp = pt_regs pointer */ 198 - jbsr syscall_trace 199 - 3: 200 - jbsr ret_from_exception 193 + ANDI_R3 r8, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT) 194 + cmpnei r8, 0 195 + bf ret_from_exception 196 + mov a0, sp /* sp = pt_regs pointer */ 197 + jbsr syscall_trace_exit 201 198 202 199 ret_from_exception: 203 200 ld syscallid, (sp, LSAVE_PSR) ··· 209 212 bmaski r10, THREAD_SHIFT 210 213 andn r9, r10 211 214 212 - resume_userspace: 213 215 ldw r8, (r9, TINFO_FLAGS) 214 216 andi r8, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED) 215 217 cmpnei r8, 0 216 218 bt exit_work 217 - 1: RESTORE_ALL 219 + 1: 220 + RESTORE_ALL 218 221 219 222 exit_work: 223 + lrw syscallid, ret_from_exception 224 + mov lr, syscallid 225 + 220 226 btsti r8, TIF_NEED_RESCHED 221 227 bt work_resched 222 - /* If thread_info->flag is empty, RESTORE_ALL */ 223 - cmpnei r8, 0 224 - bf 1b 225 - mov a1, sp 226 - mov a0, r8 227 - mov a2, r11_sig /* syscall? */ 228 - btsti r8, TIF_SIGPENDING /* delivering a signal? */ 229 - /* prevent further restarts(set r11 = 0) */ 230 - clrt r11_sig 231 - jbsr do_notify_resume /* do signals */ 232 - br resume_userspace 228 + 229 + mov a0, sp 230 + mov a1, r8 231 + jmpi do_notify_resume 233 232 234 233 work_resched: 235 - lrw syscallid, ret_from_exception 236 - mov r15, syscallid /* Return address in link */ 237 234 jmpi schedule 238 235 239 - ENTRY(sys_rt_sigreturn) 240 - movi r11_sig, 0 241 - jmpi do_rt_sigreturn 242 - 243 236 ENTRY(csky_trap) 244 - SAVE_ALL EPC_KEEP 237 + SAVE_ALL 0 245 238 psrset ee 246 - movi r11_sig, 0 /* r11 = 0, Not a syscall. */ 247 239 mov a0, sp /* Push Stack pointer arg */ 248 240 jbsr trap_c /* Call C-level trap handler */ 249 241 jmpi ret_from_exception ··· 247 261 248 262 /* increase epc for continue */ 249 263 mfcr a0, epc 250 - INCTRAP a0 264 + addi a0, TRAP0_SIZE 251 265 mtcr a0, epc 252 266 253 267 /* get current task thread_info with kernel 8K stack */ ··· 264 278 rte 265 279 266 280 ENTRY(csky_irq) 267 - SAVE_ALL EPC_KEEP 281 + SAVE_ALL 0 268 282 psrset ee 269 - movi r11_sig, 0 /* r11 = 0, Not a syscall. */ 270 283 271 284 #ifdef CONFIG_PREEMPT 272 285 mov r9, sp /* Get current stack pointer */
+146 -2
arch/csky/kernel/ftrace.c
··· 3 3 4 4 #include <linux/ftrace.h> 5 5 #include <linux/uaccess.h> 6 + #include <asm/cacheflush.h> 7 + 8 + #ifdef CONFIG_DYNAMIC_FTRACE 9 + 10 + #define NOP 0x4000 11 + #define NOP32_HI 0xc400 12 + #define NOP32_LO 0x4820 13 + #define PUSH_LR 0x14d0 14 + #define MOVIH_LINK 0xea3a 15 + #define ORI_LINK 0xef5a 16 + #define JSR_LINK 0xe8fa 17 + #define BSR_LINK 0xe000 18 + 19 + /* 20 + * Gcc-csky with -pg will insert stub in function prologue: 21 + * push lr 22 + * jbsr _mcount 23 + * nop32 24 + * nop32 25 + * 26 + * If the (callee - current_pc) is less then 64MB, we'll use bsr: 27 + * push lr 28 + * bsr _mcount 29 + * nop32 30 + * nop32 31 + * else we'll use (movih + ori + jsr): 32 + * push lr 33 + * movih r26, ... 34 + * ori r26, ... 35 + * jsr r26 36 + * 37 + * (r26 is our reserved link-reg) 38 + * 39 + */ 40 + static inline void make_jbsr(unsigned long callee, unsigned long pc, 41 + uint16_t *call, bool nolr) 42 + { 43 + long offset; 44 + 45 + call[0] = nolr ? NOP : PUSH_LR; 46 + 47 + offset = (long) callee - (long) pc; 48 + 49 + if (unlikely(offset < -67108864 || offset > 67108864)) { 50 + call[1] = MOVIH_LINK; 51 + call[2] = callee >> 16; 52 + call[3] = ORI_LINK; 53 + call[4] = callee & 0xffff; 54 + call[5] = JSR_LINK; 55 + call[6] = 0; 56 + } else { 57 + offset = offset >> 1; 58 + 59 + call[1] = BSR_LINK | 60 + ((uint16_t)((unsigned long) offset >> 16) & 0x3ff); 61 + call[2] = (uint16_t)((unsigned long) offset & 0xffff); 62 + call[3] = call[5] = NOP32_HI; 63 + call[4] = call[6] = NOP32_LO; 64 + } 65 + } 66 + 67 + static uint16_t nops[7] = {NOP, NOP32_HI, NOP32_LO, NOP32_HI, NOP32_LO, 68 + NOP32_HI, NOP32_LO}; 69 + static int ftrace_check_current_nop(unsigned long hook) 70 + { 71 + uint16_t olds[7]; 72 + unsigned long hook_pos = hook - 2; 73 + 74 + if (probe_kernel_read((void *)olds, (void *)hook_pos, sizeof(nops))) 75 + return -EFAULT; 76 + 77 + if (memcmp((void *)nops, (void *)olds, sizeof(nops))) { 78 + pr_err("%p: nop but get (%04x %04x %04x %04x %04x %04x %04x)\n", 79 + (void *)hook_pos, 80 + olds[0], olds[1], olds[2], olds[3], olds[4], olds[5], 81 + olds[6]); 82 + 83 + return -EINVAL; 84 + } 85 + 86 + return 0; 87 + } 88 + 89 + static int ftrace_modify_code(unsigned long hook, unsigned long target, 90 + bool enable, bool nolr) 91 + { 92 + uint16_t call[7]; 93 + 94 + unsigned long hook_pos = hook - 2; 95 + int ret = 0; 96 + 97 + make_jbsr(target, hook, call, nolr); 98 + 99 + ret = probe_kernel_write((void *)hook_pos, enable ? call : nops, 100 + sizeof(nops)); 101 + if (ret) 102 + return -EPERM; 103 + 104 + flush_icache_range(hook_pos, hook_pos + MCOUNT_INSN_SIZE); 105 + 106 + return 0; 107 + } 108 + 109 + int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) 110 + { 111 + int ret = ftrace_check_current_nop(rec->ip); 112 + 113 + if (ret) 114 + return ret; 115 + 116 + return ftrace_modify_code(rec->ip, addr, true, false); 117 + } 118 + 119 + int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, 120 + unsigned long addr) 121 + { 122 + return ftrace_modify_code(rec->ip, addr, false, false); 123 + } 124 + 125 + int ftrace_update_ftrace_func(ftrace_func_t func) 126 + { 127 + int ret = ftrace_modify_code((unsigned long)&ftrace_call, 128 + (unsigned long)func, true, true); 129 + return ret; 130 + } 131 + 132 + int __init ftrace_dyn_arch_init(void) 133 + { 134 + return 0; 135 + } 136 + #endif /* CONFIG_DYNAMIC_FTRACE */ 6 137 7 138 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 8 139 void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, ··· 174 43 *(unsigned long *)frame_pointer = return_hooker; 175 44 } 176 45 } 177 - #endif 46 + 47 + #ifdef CONFIG_DYNAMIC_FTRACE 48 + int ftrace_enable_ftrace_graph_caller(void) 49 + { 50 + return ftrace_modify_code((unsigned long)&ftrace_graph_call, 51 + (unsigned long)&ftrace_graph_caller, true, true); 52 + } 53 + 54 + int ftrace_disable_ftrace_graph_caller(void) 55 + { 56 + return ftrace_modify_code((unsigned long)&ftrace_graph_call, 57 + (unsigned long)&ftrace_graph_caller, false, true); 58 + } 59 + #endif /* CONFIG_DYNAMIC_FTRACE */ 60 + #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 178 61 179 62 /* _mcount is defined in abi's mcount.S */ 180 - extern void _mcount(void); 181 63 EXPORT_SYMBOL(_mcount);
+7 -53
arch/csky/kernel/head.S
··· 7 7 8 8 __HEAD 9 9 ENTRY(_start) 10 - /* set super user mode */ 11 - lrw a3, DEFAULT_PSR_VALUE 12 - mtcr a3, psr 13 - psrset ee 14 - 15 - SETUP_MMU a3 10 + SETUP_MMU 16 11 17 12 /* set stack point */ 18 - lrw a3, init_thread_union + THREAD_SIZE 19 - mov sp, a3 13 + lrw r6, init_thread_union + THREAD_SIZE 14 + mov sp, r6 20 15 21 16 jmpi csky_start 22 17 END(_start) ··· 19 24 #ifdef CONFIG_SMP 20 25 .align 10 21 26 ENTRY(_start_smp_secondary) 22 - /* Invalid I/Dcache BTB BHT */ 23 - movi a3, 7 24 - lsli a3, 16 25 - addi a3, (1<<4) | 3 26 - mtcr a3, cr17 27 - 28 - tlbi.alls 29 - 30 - /* setup PAGEMASK */ 31 - movi a3, 0 32 - mtcr a3, cr<6, 15> 33 - 34 - /* setup MEL0/MEL1 */ 35 - grs a0, _start_smp_pc 36 - _start_smp_pc: 37 - bmaski a1, 13 38 - andn a0, a1 39 - movi a1, 0x00000006 40 - movi a2, 0x00001006 41 - or a1, a0 42 - or a2, a0 43 - mtcr a1, cr<2, 15> 44 - mtcr a2, cr<3, 15> 45 - 46 - /* setup MEH */ 47 - mtcr a0, cr<4, 15> 48 - 49 - /* write TLB */ 50 - bgeni a3, 28 51 - mtcr a3, cr<8, 15> 52 - 53 - SETUP_MMU a3 54 - 55 - /* enable MMU */ 56 - movi a3, 1 57 - mtcr a3, cr18 58 - 59 - jmpi _goto_mmu_on 60 - _goto_mmu_on: 61 - lrw a3, DEFAULT_PSR_VALUE 62 - mtcr a3, psr 63 - psrset ee 27 + SETUP_MMU 64 28 65 29 /* set stack point */ 66 - lrw a3, secondary_stack 67 - ld.w a3, (a3, 0) 68 - mov sp, a3 30 + lrw r6, secondary_stack 31 + ld.w r6, (r6, 0) 32 + mov sp, r6 69 33 70 34 jmpi csky_start_secondary 71 35 END(_start_smp_secondary)
+119
arch/csky/kernel/perf_callchain.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. 3 + 4 + #include <linux/perf_event.h> 5 + #include <linux/uaccess.h> 6 + 7 + /* Kernel callchain */ 8 + struct stackframe { 9 + unsigned long fp; 10 + unsigned long lr; 11 + }; 12 + 13 + static int unwind_frame_kernel(struct stackframe *frame) 14 + { 15 + if (kstack_end((void *)frame->fp)) 16 + return -EPERM; 17 + if (frame->fp & 0x3 || frame->fp < TASK_SIZE) 18 + return -EPERM; 19 + 20 + *frame = *(struct stackframe *)frame->fp; 21 + if (__kernel_text_address(frame->lr)) { 22 + int graph = 0; 23 + 24 + frame->lr = ftrace_graph_ret_addr(NULL, &graph, frame->lr, 25 + NULL); 26 + } 27 + return 0; 28 + } 29 + 30 + static void notrace walk_stackframe(struct stackframe *fr, 31 + struct perf_callchain_entry_ctx *entry) 32 + { 33 + do { 34 + perf_callchain_store(entry, fr->lr); 35 + } while (unwind_frame_kernel(fr) >= 0); 36 + } 37 + 38 + /* 39 + * Get the return address for a single stackframe and return a pointer to the 40 + * next frame tail. 41 + */ 42 + static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry, 43 + unsigned long fp, unsigned long reg_lr) 44 + { 45 + struct stackframe buftail; 46 + unsigned long lr = 0; 47 + unsigned long *user_frame_tail = (unsigned long *)fp; 48 + 49 + /* Check accessibility of one struct frame_tail beyond */ 50 + if (!access_ok(user_frame_tail, sizeof(buftail))) 51 + return 0; 52 + if (__copy_from_user_inatomic(&buftail, user_frame_tail, 53 + sizeof(buftail))) 54 + return 0; 55 + 56 + if (reg_lr != 0) 57 + lr = reg_lr; 58 + else 59 + lr = buftail.lr; 60 + 61 + fp = buftail.fp; 62 + perf_callchain_store(entry, lr); 63 + 64 + return fp; 65 + } 66 + 67 + /* 68 + * This will be called when the target is in user mode 69 + * This function will only be called when we use 70 + * "PERF_SAMPLE_CALLCHAIN" in 71 + * kernel/events/core.c:perf_prepare_sample() 72 + * 73 + * How to trigger perf_callchain_[user/kernel] : 74 + * $ perf record -e cpu-clock --call-graph fp ./program 75 + * $ perf report --call-graph 76 + * 77 + * On C-SKY platform, the program being sampled and the C library 78 + * need to be compiled with * -mbacktrace, otherwise the user 79 + * stack will not contain function frame. 80 + */ 81 + void perf_callchain_user(struct perf_callchain_entry_ctx *entry, 82 + struct pt_regs *regs) 83 + { 84 + unsigned long fp = 0; 85 + 86 + /* C-SKY does not support virtualization. */ 87 + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) 88 + return; 89 + 90 + fp = regs->regs[4]; 91 + perf_callchain_store(entry, regs->pc); 92 + 93 + /* 94 + * While backtrace from leaf function, lr is normally 95 + * not saved inside frame on C-SKY, so get lr from pt_regs 96 + * at the sample point. However, lr value can be incorrect if 97 + * lr is used as temp register 98 + */ 99 + fp = user_backtrace(entry, fp, regs->lr); 100 + 101 + while (fp && !(fp & 0x3) && entry->nr < entry->max_stack) 102 + fp = user_backtrace(entry, fp, 0); 103 + } 104 + 105 + void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, 106 + struct pt_regs *regs) 107 + { 108 + struct stackframe fr; 109 + 110 + /* C-SKY does not support virtualization. */ 111 + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { 112 + pr_warn("C-SKY does not support perf in guest mode!"); 113 + return; 114 + } 115 + 116 + fr.fp = regs->regs[4]; 117 + fr.lr = regs->lr; 118 + walk_stackframe(&fr, entry); 119 + }
+40
arch/csky/kernel/perf_regs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. 3 + 4 + #include <linux/errno.h> 5 + #include <linux/kernel.h> 6 + #include <linux/perf_event.h> 7 + #include <linux/bug.h> 8 + #include <asm/perf_regs.h> 9 + #include <asm/ptrace.h> 10 + 11 + u64 perf_reg_value(struct pt_regs *regs, int idx) 12 + { 13 + if (WARN_ON_ONCE((u32)idx >= PERF_REG_CSKY_MAX)) 14 + return 0; 15 + 16 + return (u64)*((u32 *)regs + idx); 17 + } 18 + 19 + #define REG_RESERVED (~((1ULL << PERF_REG_CSKY_MAX) - 1)) 20 + 21 + int perf_reg_validate(u64 mask) 22 + { 23 + if (!mask || mask & REG_RESERVED) 24 + return -EINVAL; 25 + 26 + return 0; 27 + } 28 + 29 + u64 perf_reg_abi(struct task_struct *task) 30 + { 31 + return PERF_SAMPLE_REGS_ABI_32; 32 + } 33 + 34 + void perf_get_regs_user(struct perf_regs *regs_user, 35 + struct pt_regs *regs, 36 + struct pt_regs *regs_user_copy) 37 + { 38 + regs_user->regs = task_pt_regs(current); 39 + regs_user->abi = perf_reg_abi(current); 40 + }
+22 -25
arch/csky/kernel/ptrace.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3 3 4 + #include <linux/audit.h> 4 5 #include <linux/elf.h> 5 6 #include <linux/errno.h> 6 7 #include <linux/kernel.h> ··· 12 11 #include <linux/sched/task_stack.h> 13 12 #include <linux/signal.h> 14 13 #include <linux/smp.h> 14 + #include <linux/tracehook.h> 15 15 #include <linux/uaccess.h> 16 16 #include <linux/user.h> 17 17 ··· 23 21 #include <asm/asm-offsets.h> 24 22 25 23 #include <abi/regdef.h> 24 + 25 + #define CREATE_TRACE_POINTS 26 + #include <trace/events/syscalls.h> 26 27 27 28 /* sets the trace bits. */ 28 29 #define TRACE_MODE_SI (1 << 14) ··· 212 207 return ret; 213 208 } 214 209 215 - /* 216 - * If process's system calls is traces, do some corresponding handles in this 217 - * function before entering system call function and after exiting system call 218 - * function. 219 - */ 220 - asmlinkage void syscall_trace(int why, struct pt_regs *regs) 210 + asmlinkage void syscall_trace_enter(struct pt_regs *regs) 221 211 { 222 - long saved_why; 223 - /* 224 - * Save saved_why, why is used to denote syscall entry/exit; 225 - * why = 0:entry, why = 1: exit 226 - */ 227 - saved_why = regs->regs[SYSTRACE_SAVENUM]; 228 - regs->regs[SYSTRACE_SAVENUM] = why; 212 + if (test_thread_flag(TIF_SYSCALL_TRACE)) 213 + if (tracehook_report_syscall_entry(regs)) 214 + syscall_set_nr(current, regs, -1); 229 215 230 - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 231 - ? 0x80 : 0)); 216 + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) 217 + trace_sys_enter(regs, syscall_get_nr(current, regs)); 232 218 233 - /* 234 - * this isn't the same as continuing with a signal, but it will do 235 - * for normal use. strace only continues with a signal if the 236 - * stopping signal is not SIGTRAP. -brl 237 - */ 238 - if (current->exit_code) { 239 - send_sig(current->exit_code, current, 1); 240 - current->exit_code = 0; 241 - } 219 + audit_syscall_entry(regs_syscallid(regs), regs->a0, regs->a1, regs->a2, regs->a3); 220 + } 242 221 243 - regs->regs[SYSTRACE_SAVENUM] = saved_why; 222 + asmlinkage void syscall_trace_exit(struct pt_regs *regs) 223 + { 224 + audit_syscall_exit(regs); 225 + 226 + if (test_thread_flag(TIF_SYSCALL_TRACE)) 227 + tracehook_report_syscall_exit(regs, 0); 228 + 229 + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) 230 + trace_sys_exit(regs, syscall_get_return_value(current, regs)); 244 231 } 245 232 246 233 extern void show_stack(struct task_struct *task, unsigned long *stack);
+9 -3
arch/csky/kernel/setup.c
··· 142 142 #endif 143 143 } 144 144 145 - asmlinkage __visible void __init csky_start(unsigned int unused, void *param) 145 + unsigned long va_pa_offset; 146 + EXPORT_SYMBOL(va_pa_offset); 147 + 148 + asmlinkage __visible void __init csky_start(unsigned int unused, 149 + void *dtb_start) 146 150 { 147 151 /* Clean up bss section */ 148 152 memset(__bss_start, 0, __bss_stop - __bss_start); 149 153 154 + va_pa_offset = read_mmu_msa0() & ~(SSEG_SIZE - 1); 155 + 150 156 pre_trap_init(); 151 157 pre_mmu_init(); 152 158 153 - if (param == NULL) 159 + if (dtb_start == NULL) 154 160 early_init_dt_scan(__dtb_start); 155 161 else 156 - early_init_dt_scan(param); 162 + early_init_dt_scan(dtb_start); 157 163 158 164 start_kernel(); 159 165
+138 -224
arch/csky/kernel/signal.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 - // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3 2 4 - #include <linux/sched.h> 5 - #include <linux/mm.h> 6 - #include <linux/kernel.h> 7 3 #include <linux/signal.h> 8 - #include <linux/syscalls.h> 9 - #include <linux/errno.h> 10 - #include <linux/wait.h> 11 - #include <linux/ptrace.h> 12 - #include <linux/unistd.h> 13 - #include <linux/stddef.h> 14 - #include <linux/highuid.h> 15 - #include <linux/personality.h> 16 - #include <linux/tty.h> 17 - #include <linux/binfmts.h> 18 - #include <linux/tracehook.h> 19 - #include <linux/freezer.h> 20 4 #include <linux/uaccess.h> 5 + #include <linux/syscalls.h> 6 + #include <linux/tracehook.h> 21 7 22 - #include <asm/setup.h> 23 - #include <asm/pgtable.h> 24 8 #include <asm/traps.h> 25 9 #include <asm/ucontext.h> 26 10 #include <asm/vdso.h> ··· 13 29 14 30 #ifdef CONFIG_CPU_HAS_FPU 15 31 #include <abi/fpu.h> 16 - 17 - static int restore_fpu_state(struct sigcontext *sc) 32 + static int restore_fpu_state(struct sigcontext __user *sc) 18 33 { 19 34 int err = 0; 20 35 struct user_fp user_fp; 21 36 22 - err = copy_from_user(&user_fp, &sc->sc_user_fp, sizeof(user_fp)); 37 + err = __copy_from_user(&user_fp, &sc->sc_user_fp, sizeof(user_fp)); 23 38 24 39 restore_from_user_fp(&user_fp); 25 40 26 41 return err; 27 42 } 28 43 29 - static int save_fpu_state(struct sigcontext *sc) 44 + static int save_fpu_state(struct sigcontext __user *sc) 30 45 { 31 46 struct user_fp user_fp; 32 47 33 48 save_to_user_fp(&user_fp); 34 49 35 - return copy_to_user(&sc->sc_user_fp, &user_fp, sizeof(user_fp)); 50 + return __copy_to_user(&sc->sc_user_fp, &user_fp, sizeof(user_fp)); 36 51 } 37 52 #else 38 - static inline int restore_fpu_state(struct sigcontext *sc) { return 0; } 39 - static inline int save_fpu_state(struct sigcontext *sc) { return 0; } 53 + #define restore_fpu_state(sigcontext) (0) 54 + #define save_fpu_state(sigcontext) (0) 40 55 #endif 41 56 42 57 struct rt_sigframe { 43 - int sig; 44 - struct siginfo *pinfo; 45 - void *puc; 46 58 struct siginfo info; 47 59 struct ucontext uc; 48 60 }; 49 61 50 - static int 51 - restore_sigframe(struct pt_regs *regs, 52 - struct sigcontext *sc, int *pr2) 62 + static long restore_sigcontext(struct pt_regs *regs, 63 + struct sigcontext __user *sc) 53 64 { 54 65 int err = 0; 55 66 56 - /* Always make any pending restarted system calls return -EINTR */ 57 - current_thread_info()->task->restart_block.fn = do_no_restart_syscall; 67 + /* sc_pt_regs is structured the same as the start of pt_regs */ 68 + err |= __copy_from_user(regs, &sc->sc_pt_regs, sizeof(struct pt_regs)); 58 69 59 - err |= copy_from_user(regs, &sc->sc_pt_regs, sizeof(struct pt_regs)); 60 - 70 + /* Restore the floating-point state. */ 61 71 err |= restore_fpu_state(sc); 62 72 63 - *pr2 = regs->a0; 64 73 return err; 65 74 } 66 75 67 - asmlinkage int 68 - do_rt_sigreturn(void) 76 + SYSCALL_DEFINE0(rt_sigreturn) 69 77 { 70 - sigset_t set; 71 - int a0; 72 78 struct pt_regs *regs = current_pt_regs(); 73 - struct rt_sigframe *frame = (struct rt_sigframe *)(regs->usp); 79 + struct rt_sigframe __user *frame; 80 + struct task_struct *task; 81 + sigset_t set; 82 + 83 + /* Always make any pending restarted system calls return -EINTR */ 84 + current->restart_block.fn = do_no_restart_syscall; 85 + 86 + frame = (struct rt_sigframe __user *)regs->usp; 74 87 75 88 if (!access_ok(frame, sizeof(*frame))) 76 89 goto badframe; 90 + 77 91 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 78 92 goto badframe; 79 93 80 - sigdelsetmask(&set, (sigmask(SIGKILL) | sigmask(SIGSTOP))); 81 - spin_lock_irq(&current->sighand->siglock); 82 - current->blocked = set; 83 - recalc_sigpending(); 84 - spin_unlock_irq(&current->sighand->siglock); 94 + set_current_blocked(&set); 85 95 86 - if (restore_sigframe(regs, &frame->uc.uc_mcontext, &a0)) 96 + if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 87 97 goto badframe; 88 98 89 - return a0; 99 + if (restore_altstack(&frame->uc.uc_stack)) 100 + goto badframe; 101 + 102 + return regs->a0; 90 103 91 104 badframe: 92 - force_sig(SIGSEGV, current); 105 + task = current; 106 + force_sig(SIGSEGV, task); 93 107 return 0; 94 108 } 95 109 96 - static int setup_sigframe(struct sigcontext *sc, struct pt_regs *regs) 110 + static int setup_sigcontext(struct rt_sigframe __user *frame, 111 + struct pt_regs *regs) 97 112 { 113 + struct sigcontext __user *sc = &frame->uc.uc_mcontext; 98 114 int err = 0; 99 115 100 - err |= copy_to_user(&sc->sc_pt_regs, regs, sizeof(struct pt_regs)); 116 + err |= __copy_to_user(&sc->sc_pt_regs, regs, sizeof(struct pt_regs)); 101 117 err |= save_fpu_state(sc); 102 118 103 119 return err; 104 120 } 105 121 106 - static inline void * 107 - get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 122 + static inline void __user *get_sigframe(struct ksignal *ksig, 123 + struct pt_regs *regs, size_t framesize) 108 124 { 109 - unsigned long usp; 125 + unsigned long sp; 126 + /* Default to using normal stack */ 127 + sp = regs->usp; 110 128 111 - /* Default to using normal stack. */ 112 - usp = regs->usp; 129 + /* 130 + * If we are on the alternate signal stack and would overflow it, don't. 131 + * Return an always-bogus address instead so we will die with SIGSEGV. 132 + */ 133 + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) 134 + return (void __user __force *)(-1UL); 113 135 114 - /* This is the X/Open sanctioned signal stack switching. */ 115 - if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(usp)) { 116 - if (!on_sig_stack(usp)) 117 - usp = current->sas_ss_sp + current->sas_ss_size; 118 - } 119 - return (void *)((usp - frame_size) & -8UL); 136 + /* This is the X/Open sanctioned signal stack switching. */ 137 + sp = sigsp(sp, ksig) - framesize; 138 + 139 + /* Align the stack frame. */ 140 + sp &= -8UL; 141 + 142 + return (void __user *)sp; 120 143 } 121 144 122 145 static int ··· 131 140 { 132 141 struct rt_sigframe *frame; 133 142 int err = 0; 134 - 135 143 struct csky_vdso *vdso = current->mm->context.vdso; 136 144 137 - frame = get_sigframe(&ksig->ka, regs, sizeof(*frame)); 138 - if (!frame) 139 - return 1; 145 + frame = get_sigframe(ksig, regs, sizeof(*frame)); 146 + if (!access_ok(frame, sizeof(*frame))) 147 + return -EFAULT; 140 148 141 - err |= __put_user(ksig->sig, &frame->sig); 142 - err |= __put_user(&frame->info, &frame->pinfo); 143 - err |= __put_user(&frame->uc, &frame->puc); 144 149 err |= copy_siginfo_to_user(&frame->info, &ksig->info); 145 150 146 - /* Create the ucontext. */ 151 + /* Create the ucontext. */ 147 152 err |= __put_user(0, &frame->uc.uc_flags); 148 - err |= __put_user(0, &frame->uc.uc_link); 149 - err |= __put_user((void *)current->sas_ss_sp, 150 - &frame->uc.uc_stack.ss_sp); 151 - err |= __put_user(sas_ss_flags(regs->usp), 152 - &frame->uc.uc_stack.ss_flags); 153 - err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 154 - err |= setup_sigframe(&frame->uc.uc_mcontext, regs); 155 - err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 156 - 153 + err |= __put_user(NULL, &frame->uc.uc_link); 154 + err |= __save_altstack(&frame->uc.uc_stack, regs->usp); 155 + err |= setup_sigcontext(frame, regs); 156 + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 157 157 if (err) 158 - goto give_sigsegv; 158 + return -EFAULT; 159 159 160 - /* Set up registers for signal handler */ 161 - regs->usp = (unsigned long)frame; 162 - regs->pc = (unsigned long)ksig->ka.sa.sa_handler; 163 - regs->lr = (unsigned long)vdso->rt_signal_retcode; 164 - 165 - adjust_stack: 166 - regs->a0 = ksig->sig; /* first arg is signo */ 167 - regs->a1 = (unsigned long)(&(frame->info)); 168 - regs->a2 = (unsigned long)(&(frame->uc)); 169 - return err; 170 - 171 - give_sigsegv: 172 - if (ksig->sig == SIGSEGV) 173 - ksig->ka.sa.sa_handler = SIG_DFL; 174 - force_sig(SIGSEGV, current); 175 - goto adjust_stack; 176 - } 177 - 178 - /* 179 - * OK, we're invoking a handler 180 - */ 181 - static int 182 - handle_signal(struct ksignal *ksig, struct pt_regs *regs) 183 - { 184 - int ret; 185 - sigset_t *oldset = sigmask_to_save(); 160 + /* Set up to return from userspace. */ 161 + regs->lr = (unsigned long)(vdso->rt_signal_retcode); 186 162 187 163 /* 188 - * set up the stack frame, regardless of SA_SIGINFO, 189 - * and pass info anyway. 164 + * Set up registers for signal handler. 165 + * Registers that we don't modify keep the value they had from 166 + * user-space at the time we took the signal. 167 + * We always pass siginfo and mcontext, regardless of SA_SIGINFO, 168 + * since some things rely on this (e.g. glibc's debug/segfault.c). 190 169 */ 191 - ret = setup_rt_frame(ksig, oldset, regs); 192 - 193 - if (ret != 0) { 194 - force_sigsegv(ksig->sig, current); 195 - return ret; 196 - } 197 - 198 - /* Block the signal if we were successful. */ 199 - spin_lock_irq(&current->sighand->siglock); 200 - sigorsets(&current->blocked, &current->blocked, &ksig->ka.sa.sa_mask); 201 - if (!(ksig->ka.sa.sa_flags & SA_NODEFER)) 202 - sigaddset(&current->blocked, ksig->sig); 203 - recalc_sigpending(); 204 - spin_unlock_irq(&current->sighand->siglock); 170 + regs->pc = (unsigned long)ksig->ka.sa.sa_handler; 171 + regs->usp = (unsigned long)frame; 172 + regs->a0 = ksig->sig; /* a0: signal number */ 173 + regs->a1 = (unsigned long)(&(frame->info)); /* a1: siginfo pointer */ 174 + regs->a2 = (unsigned long)(&(frame->uc)); /* a2: ucontext pointer */ 205 175 206 176 return 0; 207 177 } 208 178 209 - /* 210 - * Note that 'init' is a special process: it doesn't get signals it doesn't 211 - * want to handle. Thus you cannot kill init even with a SIGKILL even by 212 - * mistake. 213 - * 214 - * Note that we go through the signals twice: once to check the signals 215 - * that the kernel can handle, and then we build all the user-level signal 216 - * handling stack-frames in one go after that. 217 - */ 218 - static void do_signal(struct pt_regs *regs, int syscall) 179 + static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) 219 180 { 220 - unsigned int retval = 0, continue_addr = 0, restart_addr = 0; 181 + sigset_t *oldset = sigmask_to_save(); 182 + int ret; 183 + 184 + /* Are we from a system call? */ 185 + if (in_syscall(regs)) { 186 + /* Avoid additional syscall restarting via ret_from_exception */ 187 + forget_syscall(regs); 188 + 189 + /* If so, check system call restarting.. */ 190 + switch (regs->a0) { 191 + case -ERESTART_RESTARTBLOCK: 192 + case -ERESTARTNOHAND: 193 + regs->a0 = -EINTR; 194 + break; 195 + 196 + case -ERESTARTSYS: 197 + if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { 198 + regs->a0 = -EINTR; 199 + break; 200 + } 201 + /* fallthrough */ 202 + case -ERESTARTNOINTR: 203 + regs->a0 = regs->orig_a0; 204 + regs->pc -= TRAP0_SIZE; 205 + break; 206 + } 207 + } 208 + 209 + /* Set up the stack frame */ 210 + ret = setup_rt_frame(ksig, oldset, regs); 211 + 212 + signal_setup_done(ret, ksig, 0); 213 + } 214 + 215 + static void do_signal(struct pt_regs *regs) 216 + { 221 217 struct ksignal ksig; 222 218 223 - /* 224 - * We want the common case to go fast, which 225 - * is why we may in certain cases get here from 226 - * kernel mode. Just return without doing anything 227 - * if so. 228 - */ 229 - if (!user_mode(regs)) 219 + if (get_signal(&ksig)) { 220 + /* Actually deliver the signal */ 221 + handle_signal(&ksig, regs); 230 222 return; 223 + } 231 224 232 - /* 233 - * If we were from a system call, check for system call restarting... 234 - */ 235 - if (syscall) { 236 - continue_addr = regs->pc; 237 - #if defined(__CSKYABIV2__) 238 - restart_addr = continue_addr - 4; 239 - #else 240 - restart_addr = continue_addr - 2; 241 - #endif 242 - retval = regs->a0; 225 + /* Did we come from a system call? */ 226 + if (in_syscall(regs)) { 227 + /* Avoid additional syscall restarting via ret_from_exception */ 228 + forget_syscall(regs); 243 229 244 - /* 245 - * Prepare for system call restart. We do this here so that a 246 - * debugger will see the already changed. 247 - */ 248 - switch (retval) { 230 + /* Restart the system call - no handlers present */ 231 + switch (regs->a0) { 249 232 case -ERESTARTNOHAND: 250 233 case -ERESTARTSYS: 251 234 case -ERESTARTNOINTR: 252 235 regs->a0 = regs->orig_a0; 253 - regs->pc = restart_addr; 236 + regs->pc -= TRAP0_SIZE; 254 237 break; 255 238 case -ERESTART_RESTARTBLOCK: 256 - regs->a0 = -EINTR; 239 + regs->a0 = regs->orig_a0; 240 + regs_syscallid(regs) = __NR_restart_syscall; 241 + regs->pc -= TRAP0_SIZE; 257 242 break; 258 243 } 259 244 } 260 245 261 - if (try_to_freeze()) 262 - goto no_signal; 263 - 264 246 /* 265 - * Get the signal to deliver. When running under ptrace, at this 266 - * point the debugger may change all our registers ... 247 + * If there is no signal to deliver, we just put the saved 248 + * sigmask back. 267 249 */ 268 - if (get_signal(&ksig)) { 269 - /* 270 - * Depending on the signal settings we may need to revert the 271 - * decision to restart the system call. But skip this if a 272 - * debugger has chosen to restart at a different PC. 273 - */ 274 - if (regs->pc == restart_addr) { 275 - if (retval == -ERESTARTNOHAND || 276 - (retval == -ERESTARTSYS && 277 - !(ksig.ka.sa.sa_flags & SA_RESTART))) { 278 - regs->a0 = -EINTR; 279 - regs->pc = continue_addr; 280 - } 281 - } 282 - 283 - /* Whee! Actually deliver the signal. */ 284 - if (handle_signal(&ksig, regs) == 0) { 285 - /* 286 - * A signal was successfully delivered; the saved 287 - * sigmask will have been stored in the signal frame, 288 - * and will be restored by sigreturn, so we can simply 289 - * clear the TIF_RESTORE_SIGMASK flag. 290 - */ 291 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 292 - clear_thread_flag(TIF_RESTORE_SIGMASK); 293 - } 294 - return; 295 - } 296 - 297 - no_signal: 298 - if (syscall) { 299 - /* 300 - * Handle restarting a different system call. As above, 301 - * if a debugger has chosen to restart at a different PC, 302 - * ignore the restart. 303 - */ 304 - if (retval == -ERESTART_RESTARTBLOCK 305 - && regs->pc == continue_addr) { 306 - #if defined(__CSKYABIV2__) 307 - regs->regs[3] = __NR_restart_syscall; 308 - regs->pc -= 4; 309 - #else 310 - regs->regs[9] = __NR_restart_syscall; 311 - regs->pc -= 2; 312 - #endif 313 - } 314 - 315 - /* 316 - * If there's no signal to deliver, we just put the saved 317 - * sigmask back. 318 - */ 319 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 320 - clear_thread_flag(TIF_RESTORE_SIGMASK); 321 - sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 322 - } 323 - } 250 + restore_saved_sigmask(); 324 251 } 325 252 326 - asmlinkage void 327 - do_notify_resume(unsigned int thread_flags, struct pt_regs *regs, int syscall) 253 + /* 254 + * notification of userspace execution resumption 255 + * - triggered by the _TIF_WORK_MASK flags 256 + */ 257 + asmlinkage void do_notify_resume(struct pt_regs *regs, 258 + unsigned long thread_info_flags) 328 259 { 329 - if (thread_flags & _TIF_SIGPENDING) 330 - do_signal(regs, syscall); 260 + /* Handle pending signal delivery */ 261 + if (thread_info_flags & _TIF_SIGPENDING) 262 + do_signal(regs); 331 263 332 - if (thread_flags & _TIF_NOTIFY_RESUME) { 264 + if (thread_info_flags & _TIF_NOTIFY_RESUME) { 333 265 clear_thread_flag(TIF_NOTIFY_RESUME); 334 266 tracehook_notify_resume(regs); 335 267 }
+11 -4
arch/csky/mm/fault.c
··· 15 15 #include <linux/smp.h> 16 16 #include <linux/version.h> 17 17 #include <linux/vt_kern.h> 18 - #include <linux/kernel.h> 19 18 #include <linux/extable.h> 20 19 #include <linux/uaccess.h> 20 + #include <linux/perf_event.h> 21 21 22 22 #include <asm/hardirq.h> 23 23 #include <asm/mmu_context.h> ··· 82 82 83 83 unsigned long pgd_base; 84 84 85 - pgd_base = tlb_get_pgd(); 85 + pgd_base = (unsigned long)__va(get_pgd()); 86 86 pgd = (pgd_t *)pgd_base + offset; 87 87 pgd_k = init_mm.pgd + offset; 88 88 ··· 107 107 return; 108 108 } 109 109 #endif 110 + 111 + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); 110 112 /* 111 113 * If we're in an interrupt or have no user 112 114 * context, we must not take the fault.. ··· 156 154 goto bad_area; 157 155 BUG(); 158 156 } 159 - if (fault & VM_FAULT_MAJOR) 157 + if (fault & VM_FAULT_MAJOR) { 160 158 tsk->maj_flt++; 161 - else 159 + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, 160 + address); 161 + } else { 162 162 tsk->min_flt++; 163 + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, 164 + address); 165 + } 163 166 164 167 up_read(&mm->mmap_sem); 165 168 return;
+3
scripts/recordmcount.pl
··· 397 397 } elsif ($arch eq "nds32") { 398 398 $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_NDS32_HI20_RELA\\s+_mcount\$"; 399 399 $alignment = 2; 400 + } elsif ($arch eq "csky") { 401 + $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_CKCORE_PCREL_JSR_IMM26BY2\\s+_mcount\$"; 402 + $alignment = 2; 400 403 } else { 401 404 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; 402 405 }