aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
authorAnanth N Mavinakayanahalli <ananth@in.ibm.com>2005-11-07 04:00:14 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 10:53:46 -0500
commit991a51d83a3d9bebfafdd1e692cf310899d60791 (patch)
tree4cc6eaa2a868838e59c7737da9868f2358f2bb19 /arch/sparc64/kernel
parent3516a46042508a495fac13c2e73530d936ebe015 (diff)
[PATCH] Kprobes: Use RCU for (un)register synchronization - arch changes
Changes to the arch kprobes infrastructure to take advantage of the locking changes introduced by usage of RCU for synchronization. All handlers are now run without any locks held, so they have to be re-entrant or provide their own synchronization. Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/kprobes.c14
1 files changed, 2 insertions, 12 deletions
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index b95984154dba..58a815e90373 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -116,15 +116,11 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
116 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 116 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
117 117
118 if (kprobe_running()) { 118 if (kprobe_running()) {
119 /* We *are* holding lock here, so this is safe.
120 * Disarm the probe we just hit, and ignore it.
121 */
122 p = get_kprobe(addr); 119 p = get_kprobe(addr);
123 if (p) { 120 if (p) {
124 if (kcb->kprobe_status == KPROBE_HIT_SS) { 121 if (kcb->kprobe_status == KPROBE_HIT_SS) {
125 regs->tstate = ((regs->tstate & ~TSTATE_PIL) | 122 regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
126 kcb->kprobe_orig_tstate_pil); 123 kcb->kprobe_orig_tstate_pil);
127 unlock_kprobes();
128 goto no_kprobe; 124 goto no_kprobe;
129 } 125 }
130 /* We have reentered the kprobe_handler(), since 126 /* We have reentered the kprobe_handler(), since
@@ -144,14 +140,11 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
144 if (p->break_handler && p->break_handler(p, regs)) 140 if (p->break_handler && p->break_handler(p, regs))
145 goto ss_probe; 141 goto ss_probe;
146 } 142 }
147 /* If it's not ours, can't be delete race, (we hold lock). */
148 goto no_kprobe; 143 goto no_kprobe;
149 } 144 }
150 145
151 lock_kprobes();
152 p = get_kprobe(addr); 146 p = get_kprobe(addr);
153 if (!p) { 147 if (!p) {
154 unlock_kprobes();
155 if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) { 148 if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) {
156 /* 149 /*
157 * The breakpoint instruction was removed right 150 * The breakpoint instruction was removed right
@@ -296,14 +289,12 @@ static inline int post_kprobe_handler(struct pt_regs *regs)
296 goto out; 289 goto out;
297 } 290 }
298 reset_current_kprobe(); 291 reset_current_kprobe();
299 unlock_kprobes();
300out: 292out:
301 preempt_enable_no_resched(); 293 preempt_enable_no_resched();
302 294
303 return 1; 295 return 1;
304} 296}
305 297
306/* Interrupts disabled, kprobe_lock held. */
307static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) 298static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
308{ 299{
309 struct kprobe *cur = kprobe_running(); 300 struct kprobe *cur = kprobe_running();
@@ -316,7 +307,6 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
316 resume_execution(cur, regs, kcb); 307 resume_execution(cur, regs, kcb);
317 308
318 reset_current_kprobe(); 309 reset_current_kprobe();
319 unlock_kprobes();
320 preempt_enable_no_resched(); 310 preempt_enable_no_resched();
321 } 311 }
322 return 0; 312 return 0;
@@ -331,7 +321,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
331 struct die_args *args = (struct die_args *)data; 321 struct die_args *args = (struct die_args *)data;
332 int ret = NOTIFY_DONE; 322 int ret = NOTIFY_DONE;
333 323
334 preempt_disable(); 324 rcu_read_lock();
335 switch (val) { 325 switch (val) {
336 case DIE_DEBUG: 326 case DIE_DEBUG:
337 if (kprobe_handler(args->regs)) 327 if (kprobe_handler(args->regs))
@@ -350,7 +340,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
350 default: 340 default:
351 break; 341 break;
352 } 342 }
353 preempt_enable(); 343 rcu_read_unlock();
354 return ret; 344 return ret;
355} 345}
356 346