diff options
author | Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> | 2010-04-07 04:10:20 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-04-07 04:11:43 -0400 |
commit | 359e4284a3f37aba7fd06d993863de2509d86f54 (patch) | |
tree | c0672b0fd181b28f748b1ebdc87ac2fc01347bed /arch/powerpc/include/asm/ptrace.h | |
parent | a32aaf14513da776556ad9995de8d83cd76ae60a (diff) |
powerpc: Add kprobe-based event tracer
This patch ports the kprobe-based event tracer to powerpc. This patch
is based on x86 port. This brings powerpc on par with x86.
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Acked-by: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/include/asm/ptrace.h')
-rw-r--r-- | arch/powerpc/include/asm/ptrace.h | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index 9e2d84c06b74..5d8be0416227 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h | |||
@@ -89,6 +89,7 @@ struct pt_regs { | |||
89 | 89 | ||
90 | #define instruction_pointer(regs) ((regs)->nip) | 90 | #define instruction_pointer(regs) ((regs)->nip) |
91 | #define user_stack_pointer(regs) ((regs)->gpr[1]) | 91 | #define user_stack_pointer(regs) ((regs)->gpr[1]) |
92 | #define kernel_stack_pointer(regs) ((regs)->gpr[1]) | ||
92 | #define regs_return_value(regs) ((regs)->gpr[3]) | 93 | #define regs_return_value(regs) ((regs)->gpr[3]) |
93 | 94 | ||
94 | #ifdef CONFIG_SMP | 95 | #ifdef CONFIG_SMP |
@@ -141,6 +142,69 @@ do { \ | |||
141 | #define arch_has_block_step() (!cpu_has_feature(CPU_FTR_601)) | 142 | #define arch_has_block_step() (!cpu_has_feature(CPU_FTR_601)) |
142 | #define ARCH_HAS_USER_SINGLE_STEP_INFO | 143 | #define ARCH_HAS_USER_SINGLE_STEP_INFO |
143 | 144 | ||
145 | /* | ||
146 | * kprobe-based event tracer support | ||
147 | */ | ||
148 | |||
149 | #include <linux/stddef.h> | ||
150 | #include <linux/thread_info.h> | ||
151 | extern int regs_query_register_offset(const char *name); | ||
152 | extern const char *regs_query_register_name(unsigned int offset); | ||
153 | #define MAX_REG_OFFSET (offsetof(struct pt_regs, dsisr)) | ||
154 | |||
155 | /** | ||
156 | * regs_get_register() - get register value from its offset | ||
157 | * @regs: pt_regs from which register value is gotten | ||
158 | * @offset: offset number of the register. | ||
159 | * | ||
160 | * regs_get_register returns the value of a register whose offset from @regs. | ||
161 | * The @offset is the offset of the register in struct pt_regs. | ||
162 | * If @offset is bigger than MAX_REG_OFFSET, this returns 0. | ||
163 | */ | ||
164 | static inline unsigned long regs_get_register(struct pt_regs *regs, | ||
165 | unsigned int offset) | ||
166 | { | ||
167 | if (unlikely(offset > MAX_REG_OFFSET)) | ||
168 | return 0; | ||
169 | return *(unsigned long *)((unsigned long)regs + offset); | ||
170 | } | ||
171 | |||
172 | /** | ||
173 | * regs_within_kernel_stack() - check the address in the stack | ||
174 | * @regs: pt_regs which contains kernel stack pointer. | ||
175 | * @addr: address which is checked. | ||
176 | * | ||
177 | * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). | ||
178 | * If @addr is within the kernel stack, it returns true. If not, returns false. | ||
179 | */ | ||
180 | |||
181 | static inline bool regs_within_kernel_stack(struct pt_regs *regs, | ||
182 | unsigned long addr) | ||
183 | { | ||
184 | return ((addr & ~(THREAD_SIZE - 1)) == | ||
185 | (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))); | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * regs_get_kernel_stack_nth() - get Nth entry of the stack | ||
190 | * @regs: pt_regs which contains kernel stack pointer. | ||
191 | * @n: stack entry number. | ||
192 | * | ||
193 | * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which | ||
194 | * is specified by @regs. If the @n th entry is NOT in the kernel stack, | ||
195 | * this returns 0. | ||
196 | */ | ||
197 | static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, | ||
198 | unsigned int n) | ||
199 | { | ||
200 | unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); | ||
201 | addr += n; | ||
202 | if (regs_within_kernel_stack(regs, (unsigned long)addr)) | ||
203 | return *addr; | ||
204 | else | ||
205 | return 0; | ||
206 | } | ||
207 | |||
144 | #endif /* __ASSEMBLY__ */ | 208 | #endif /* __ASSEMBLY__ */ |
145 | 209 | ||
146 | #endif /* __KERNEL__ */ | 210 | #endif /* __KERNEL__ */ |