diff options
author | Sonic Zhang <sonic.zhang@analog.com> | 2010-09-06 06:16:04 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2010-10-22 03:48:59 -0400 |
commit | 99a5b2878b56d24919eb7e646f2d8e02f63a6efc (patch) | |
tree | 5db99463ad9f68e383aa54c9d102f91f5b890091 /arch/blackfin | |
parent | 73775b892ee70bdc0dbd6aeeebb50894d062f9a1 (diff) |
Blackfin: add new cacheflush syscall
Flushing caches sometimes requires anomaly workarounds which require
supervisor-only insns. Normally we don't need to flush caches from
userspace so this isn't a problem, but when gcc generates trampolines
on the stack, we do.
So add a new syscall for gcc to use modeled after the mips version.
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/blackfin/include/asm/cachectl.h | 20 | ||||
-rw-r--r-- | arch/blackfin/include/asm/ptrace.h | 3 | ||||
-rw-r--r-- | arch/blackfin/include/asm/unistd.h | 3 | ||||
-rw-r--r-- | arch/blackfin/kernel/ptrace.c | 4 | ||||
-rw-r--r-- | arch/blackfin/kernel/sys_bfin.c | 15 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 1 |
7 files changed, 44 insertions, 3 deletions
diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild index d9eb29e2555c..9e7c5379d3ff 100644 --- a/arch/blackfin/include/asm/Kbuild +++ b/arch/blackfin/include/asm/Kbuild | |||
@@ -1,4 +1,5 @@ | |||
1 | include include/asm-generic/Kbuild.asm | 1 | include include/asm-generic/Kbuild.asm |
2 | 2 | ||
3 | header-y += bfin_sport.h | 3 | header-y += bfin_sport.h |
4 | header-y += cachectl.h | ||
4 | header-y += fixed_code.h | 5 | header-y += fixed_code.h |
diff --git a/arch/blackfin/include/asm/cachectl.h b/arch/blackfin/include/asm/cachectl.h new file mode 100644 index 000000000000..03255df6c1ea --- /dev/null +++ b/arch/blackfin/include/asm/cachectl.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * based on the mips/cachectl.h | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * Copyright (C) 1994, 1995, 1996 by Ralf Baechle | ||
6 | * | ||
7 | * Licensed under the GPL-2 or later. | ||
8 | */ | ||
9 | |||
10 | #ifndef _ASM_CACHECTL | ||
11 | #define _ASM_CACHECTL | ||
12 | |||
13 | /* | ||
14 | * Options for cacheflush system call | ||
15 | */ | ||
16 | #define ICACHE (1<<0) /* flush instruction cache */ | ||
17 | #define DCACHE (1<<1) /* writeback and flush data cache */ | ||
18 | #define BCACHE (ICACHE|DCACHE) /* flush both caches */ | ||
19 | |||
20 | #endif /* _ASM_CACHECTL */ | ||
diff --git a/arch/blackfin/include/asm/ptrace.h b/arch/blackfin/include/asm/ptrace.h index aaa1c6c2bc19..832d7c009a2c 100644 --- a/arch/blackfin/include/asm/ptrace.h +++ b/arch/blackfin/include/asm/ptrace.h | |||
@@ -113,6 +113,9 @@ extern void user_disable_single_step(struct task_struct *child); | |||
113 | /* common code demands this function */ | 113 | /* common code demands this function */ |
114 | #define ptrace_disable(child) user_disable_single_step(child) | 114 | #define ptrace_disable(child) user_disable_single_step(child) |
115 | 115 | ||
116 | extern int is_user_addr_valid(struct task_struct *child, | ||
117 | unsigned long start, unsigned long len); | ||
118 | |||
116 | /* | 119 | /* |
117 | * Get the address of the live pt_regs for the specified task. | 120 | * Get the address of the live pt_regs for the specified task. |
118 | * These are saved onto the top kernel stack when the process | 121 | * These are saved onto the top kernel stack when the process |
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h index 14fcd254b185..928ae975b87e 100644 --- a/arch/blackfin/include/asm/unistd.h +++ b/arch/blackfin/include/asm/unistd.h | |||
@@ -392,8 +392,9 @@ | |||
392 | #define __NR_fanotify_init 371 | 392 | #define __NR_fanotify_init 371 |
393 | #define __NR_fanotify_mark 372 | 393 | #define __NR_fanotify_mark 372 |
394 | #define __NR_prlimit64 373 | 394 | #define __NR_prlimit64 373 |
395 | #define __NR_cacheflush 374 | ||
395 | 396 | ||
396 | #define __NR_syscall 374 | 397 | #define __NR_syscall 375 |
397 | #define NR_syscalls __NR_syscall | 398 | #define NR_syscalls __NR_syscall |
398 | 399 | ||
399 | /* Old optional stuff no one actually uses */ | 400 | /* Old optional stuff no one actually uses */ |
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index d890c1e35ec6..b35839354130 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c | |||
@@ -114,8 +114,8 @@ put_reg(struct task_struct *task, long regno, unsigned long data) | |||
114 | /* | 114 | /* |
115 | * check that an address falls within the bounds of the target process's memory mappings | 115 | * check that an address falls within the bounds of the target process's memory mappings |
116 | */ | 116 | */ |
117 | static inline int is_user_addr_valid(struct task_struct *child, | 117 | int |
118 | unsigned long start, unsigned long len) | 118 | is_user_addr_valid(struct task_struct *child, unsigned long start, unsigned long len) |
119 | { | 119 | { |
120 | struct vm_area_struct *vma; | 120 | struct vm_area_struct *vma; |
121 | struct sram_list_struct *sraml; | 121 | struct sram_list_struct *sraml; |
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c index bdc1e2f0da32..89448ed7065d 100644 --- a/arch/blackfin/kernel/sys_bfin.c +++ b/arch/blackfin/kernel/sys_bfin.c | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
23 | #include <asm/dma.h> | 23 | #include <asm/dma.h> |
24 | #include <asm/cachectl.h> | ||
25 | #include <asm/ptrace.h> | ||
24 | 26 | ||
25 | asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags) | 27 | asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags) |
26 | { | 28 | { |
@@ -70,3 +72,16 @@ asmlinkage int sys_bfin_spinlock(int *p) | |||
70 | 72 | ||
71 | return ret; | 73 | return ret; |
72 | } | 74 | } |
75 | |||
76 | SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, len, int, op) | ||
77 | { | ||
78 | if (is_user_addr_valid(current, addr, len) != 0) | ||
79 | return -EINVAL; | ||
80 | |||
81 | if (op & DCACHE) | ||
82 | blackfin_dcache_flush_range(addr, addr + len); | ||
83 | if (op & ICACHE) | ||
84 | blackfin_icache_flush_range(addr, addr + len); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 16ea779c3a6f..2ca915ee181f 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -1737,6 +1737,7 @@ ENTRY(_sys_call_table) | |||
1737 | .long _sys_fanotify_init | 1737 | .long _sys_fanotify_init |
1738 | .long _sys_fanotify_mark | 1738 | .long _sys_fanotify_mark |
1739 | .long _sys_prlimit64 | 1739 | .long _sys_prlimit64 |
1740 | .long _sys_cacheflush | ||
1740 | 1741 | ||
1741 | .rept NR_syscalls-(.-_sys_call_table)/4 | 1742 | .rept NR_syscalls-(.-_sys_call_table)/4 |
1742 | .long _sys_ni_syscall | 1743 | .long _sys_ni_syscall |