This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: [PATCH] kprobes for s390 architecture
- From: Mike Grundy <grundym at us dot ibm dot com>
- To: Heiko Carstens <heiko dot carstens at de dot ibm dot com>
- Cc: Martin Schwidefsky <schwidefsky at de dot ibm dot com>, Jan Glauber <jan dot glauber at de dot ibm dot com>, linux-kernel at vger dot kernel dot org, systemtap at sources dot redhat dot com
- Date: Fri, 7 Jul 2006 13:23:33 -0400
- Subject: Re: [PATCH] kprobes for s390 architecture
- References: <20060623150344.GL9446@osiris.boeblingen.de.ibm.com> <OF44DB398C.F7A51098-ON88257196.007CD277-88257196.007DC8F0@us.ibm.com> <20060623222106.GA25410@osiris.ibm.com> <20060624113641.GB10403@osiris.ibm.com> <1151421789.5390.65.camel@localhost> <20060628055857.GA9452@osiris.boeblingen.de.ibm.com>
On Wed, Jun 28, 2006 at 07:58:57AM +0200, Heiko Carstens wrote:
> On Tue, Jun 27, 2006 at 05:23:09PM +0200, Martin Schwidefsky wrote:
> > On Sat, 2006-06-24 at 13:36 +0200, Heiko Carstens wrote:
> > > Just do a compare and swap operation on the instruction you want to replace,
> > > then do an smp_call_function() with the wait parameter set to 1 and passing
> > > a pointer to a function that does nothing but return.
> > Not good enough. An instruction can be fetched multiple times for a
> > single execution (see the other mail). So you have a half executed
> > instruction, the cache line is invalidated, a new instruction is written
> > and the cache line is recreated to finished the half executed
> > instruction. That can easiliy happen on millicoded instructions.
>
> Yes, looks like I was too optimistic. Seems like we really have to go for
> stop_machine_run() unless somebody comes up with a better idea...
ok, I tried, but my "better ideas" made things worse. stop_machine_run() wins:
void __kprobes arch_arm_kprobe(struct kprobe *p)
{
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
unsigned long status = kcb->kprobe_status;
struct ins_replace_args args;
args.ptr = p->addr;
args.old = p->opcode;
args.new = BREAKPOINT_INSTRUCTION;
kcb->kprobe_status = KPROBE_SWAP_INST;
stop_machine_run(swap_instruction, &args, NR_CPUS);
kcb->kprobe_status = status;
}
It works, and I guess at this point is the only way to do it. I'll send out a
full patch with this and the other cleanups later.
Mike