diff options
Diffstat (limited to 'arch/sparc64/kernel/ptrace.c')
| -rw-r--r-- | arch/sparc64/kernel/ptrace.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index 23ad839d113f..774ecbb8a031 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c | |||
| @@ -30,6 +30,8 @@ | |||
| 30 | #include <asm/psrcompat.h> | 30 | #include <asm/psrcompat.h> |
| 31 | #include <asm/visasm.h> | 31 | #include <asm/visasm.h> |
| 32 | #include <asm/spitfire.h> | 32 | #include <asm/spitfire.h> |
| 33 | #include <asm/page.h> | ||
| 34 | #include <asm/cpudata.h> | ||
| 33 | 35 | ||
| 34 | /* Returning from ptrace is a bit tricky because the syscall return | 36 | /* Returning from ptrace is a bit tricky because the syscall return |
| 35 | * low level code assumes any value returned which is negative and | 37 | * low level code assumes any value returned which is negative and |
| @@ -128,20 +130,24 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, | |||
| 128 | * is mapped to in the user's address space, we can skip the | 130 | * is mapped to in the user's address space, we can skip the |
| 129 | * D-cache flush. | 131 | * D-cache flush. |
| 130 | */ | 132 | */ |
| 131 | if ((uaddr ^ kaddr) & (1UL << 13)) { | 133 | if ((uaddr ^ (unsigned long) kaddr) & (1UL << 13)) { |
| 132 | unsigned long start = __pa(kaddr); | 134 | unsigned long start = __pa(kaddr); |
| 133 | unsigned long end = start + len; | 135 | unsigned long end = start + len; |
| 136 | unsigned long dcache_line_size; | ||
| 137 | |||
| 138 | dcache_line_size = local_cpu_data().dcache_line_size; | ||
| 134 | 139 | ||
| 135 | if (tlb_type == spitfire) { | 140 | if (tlb_type == spitfire) { |
| 136 | for (; start < end; start += 32) | 141 | for (; start < end; start += dcache_line_size) |
| 137 | spitfire_put_dcache_tag(va & 0x3fe0, 0x0); | 142 | spitfire_put_dcache_tag(start & 0x3fe0, 0x0); |
| 138 | } else { | 143 | } else { |
| 139 | for (; start < end; start += 32) | 144 | start &= ~(dcache_line_size - 1); |
| 145 | for (; start < end; start += dcache_line_size) | ||
| 140 | __asm__ __volatile__( | 146 | __asm__ __volatile__( |
| 141 | "stxa %%g0, [%0] %1\n\t" | 147 | "stxa %%g0, [%0] %1\n\t" |
| 142 | "membar #Sync" | 148 | "membar #Sync" |
| 143 | : /* no outputs */ | 149 | : /* no outputs */ |
| 144 | : "r" (va), | 150 | : "r" (start), |
| 145 | "i" (ASI_DCACHE_INVALIDATE)); | 151 | "i" (ASI_DCACHE_INVALIDATE)); |
| 146 | } | 152 | } |
| 147 | } | 153 | } |
| @@ -149,8 +155,11 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, | |||
| 149 | if (write && tlb_type == spitfire) { | 155 | if (write && tlb_type == spitfire) { |
| 150 | unsigned long start = (unsigned long) kaddr; | 156 | unsigned long start = (unsigned long) kaddr; |
| 151 | unsigned long end = start + len; | 157 | unsigned long end = start + len; |
| 158 | unsigned long icache_line_size; | ||
| 159 | |||
| 160 | icache_line_size = local_cpu_data().icache_line_size; | ||
| 152 | 161 | ||
| 153 | for (; start < end; start += 32) | 162 | for (; start < end; start += icache_line_size) |
| 154 | flushi(start); | 163 | flushi(start); |
| 155 | } | 164 | } |
| 156 | } | 165 | } |
