fche changed the topic of #systemtap to: http://sourceware.org/systemtap; email systemtap@sourceware.org if answers here not timely, conversations may be logged
hpt has joined #systemtap
sapatel__ has joined #systemtap
sapatel_ has quit [Ping timeout: 272 seconds]
_whitelogger has joined #systemtap
orivej has quit [Ping timeout: 245 seconds]
mjw has joined #systemtap
mjw has quit [Quit: Leaving]
sscox has quit [Ping timeout: 252 seconds]
hpt has quit [Ping timeout: 245 seconds]
mjw has joined #systemtap
gromero has joined #systemtap
orivej has joined #systemtap
<gromero> fche: Hi. I would like to have the floating-point registers available on Power for probes in userspace. Basically CONTEXT->uregs (which rely on struct pt_regs, i.e. thread_struct->regs) is used to get the register values, however floating-point values resides in thread_struct->fp_state and not in thread_struct->regs. Do you know how what's the correct way to implement it on systemtap?
<fche> gromero, hi
<gromero> btw, the fp registers are also available in userspace in the signal handler through ucontext_t->uc_mcontext
<gromero> fche: hi!
wcohen has quit [Ping timeout: 245 seconds]
<fche> gromero, new tapset functions, or extended ones like register("name") could be one way
<fche> is there a dwarf register# for them, when userspace code passes fp values that way?
<gromero> fche: I believe in register("name") would be nice, that's what I'm looking for.
<gromero> ABI says the following about register #s:
<gromero> DWARF | Register Number | Register Name | Width (Bytes)
<gromero> Reg | 32 - 63 | f0 - f31 | 8
<fche> ok, then it should be possible to have both register() and @uregister(#) work for those
<fche> see powerpc/registers.stp -- it does assume pt_regs, e.g. in _stp_get_register_by_offset
<gromero> exactly
sscox has joined #systemtap
<gromero> but pt_regs has not information about fp
<gromero> afaics
<fche> yes. so one'd have to extend some of those tapset functions to understand two register banks
<fche> register(name) could stay untouched
<fche> _reg_offsets could contain some magic value (bitmask field?) to indicate a non-pt-regs location for the register
<gromero> but regs is used to get the values, by regs = (CONTEXT->user_mode_p ? CONTEXT->uregs : CONTEXT->kregs);
<gromero> uregs and kregs are actually taken from thread_struct->regs, i.e. from pt_regs
<fche> yes, hat function (_stp_get_register_by_offset) would have to look for the distinguished offset parameter, and if present, search in the other thread info struct
<fche> and reject on !CONTEXT->user_mode_p etc.
<fche> so, the suggestion is: put fp registers into _reg_offsets[] but with magic offset numbers (dunno, add 0x10000)
<gromero> but that would require to extend the context members in ./runtime/common_probe_context.h ?
<fche> then have _stp_get_register_by_offset(..) recognize those offset offsets
<fche> extend the context-> to take a copy of the userspace fp_state? probably not, but can do if really needed. chances are the stap tapset function (which is embedded-C in this case) can access current->fp_state probably.
<gromero> extend the context-> to take a copy of the userspace fp_state? correct, that what I was thinking of. I was basically unsure if I'm able to access current->fp_state directly, but I see, if current->fp_state can be used directly in _stp_get_register_by_offset() it looks straightforward.
<gromero> I'll give it a try :)
<fche> yeah. just be careful to add any runtime tests - dunno for example if current->fp_state is always guaranteed to actually be set
<gromero> on power fp_state will only be set if the process when off the CPU at least once (for a context switch, syscall, etc, for instance) and if FP facility is being used, i.e. if the process executed at least an instruction using a FP register. Would the be a problem?
<gromero> *the process went off the CPU at least once
<fche> not being very familiar with powerpc behaviour here, I'd say -- add checks to the tapset function to look for validity
<gromero> ah, ok I see
<gromero> where should I add the runtime tests ?
<fche> because embedded-C is unprotected C, and you don't want someone crashing your kernel just because they ran a probe on an integer-only process that hasn't scheduled off the cpu at least once
<gromero> I see. I'll do that.
<fche> looking forward to the patch!
<gromero> fche: sure! ;)
tromey has joined #systemtap
lindi- has quit [Ping timeout: 252 seconds]
lindi- has joined #systemtap
tromey has quit [Ping timeout: 258 seconds]
wcohen has joined #systemtap
<gromero> fche: does stap relies on ptrace syscall to get the pt_regs for uregs and kregs?
<gromero> I'm not quite sure peeking current->fp_state.fpr member is the correct thing to do for reading the fp register for uprobes...
<gromero> on ptrace() it's possible to pass the register name for PT_KEEPUSER and get the fp values
<fche> ptrace syscall is totally irrelevant to systemtap
<gromero> kernel will take care to determine if it must read from regs (pt_regs) or from fp_state based on that 'addr' passed to ptrace()
<gromero> quite similar to what I'm trying to do
<gromero> oh I see
<fche> we're talking about kernel-side runtime, so we may have to replicate that effort in our runtime code (unless it happens to be packaged in such a way that we can call into it from within the kernel)
<fche> (that's unlikely)
<gromero> I see
tromey has joined #systemtap
sapatel_ has joined #systemtap
sapatel__ has quit [Ping timeout: 246 seconds]
irker340 has joined #systemtap
<irker340> systemtap: sapatel systemtap.git:refs/heads/sapatel/pr23285 * release-4.1-42-ga9282dc / bpf-translate.cxx: partially working thread and named pipe mechanism http://tinyurl.com/y3wlmqls
<gromero> fche: well, still no luck on getting fpr values correctly. it looks like that current->thread.fp_state.fpr[32][2] member are all zeroed when probe code is executed, i.e. after uprobe_notify_resume, returning from the trap exception
<gromero> so much that even using printk() in _stp_get_register_by_offset I can get them, using something like:
<gromero> + for (i1 = 0; i1 < 32; i1++)
<gromero> + for (i2 = 0; i2 < 2; i2++)
<gromero> + printk("fpr[%d][%d] = %llx\n", i1, i2, current->thread.fp_state.fpr[i1][i2]);
<gromero> odd
<gromero> since, gpr, nip and all pt_regs members are correctly set at the point .. .
<gromero> lower fpr fpr[x][0] is supposed to be zero tho, since fp is only 64-bit and a represented and 128-bit entities for convenience as the can refer to to vsx0-31 (which are 128-bit)
<gromero> *in _stp_get_register_by_offset I *can't* get them
yog_ has quit [Ping timeout: 248 seconds]
khaled has joined #systemtap
orivej has quit [Ping timeout: 248 seconds]
khaled has quit [Remote host closed the connection]
khaled has joined #systemtap
khaled has quit [Quit: Konversation terminated!]
irker340 has quit [Quit: transmission timeout]
wcohen has quit [Ping timeout: 272 seconds]
sscox has quit [Ping timeout: 258 seconds]
wcohen has joined #systemtap
tromey has quit [Quit: ERC (IRC client for Emacs 26.1)]
<gromero> what's the root cause usually for "registration error (rc -22)" ?
<gromero> probe fails to attach on a kernel function, but I would like to know if there is a simply way to find out why exactly. ..
<gromero> ah, it's blacklisted : (
<fche> should add some such possibilities to the error::pass5 man page
<fche> gromero, re. the fp regs, you're sure this is for a target program that uses those fp regs ?
mjw has quit [Quit: Leaving]
<fche> would be worth checking out the powerpc arch bits in the kernel. it's possible (likely?) that the kernel doesn't even bother save those fpregs into that struct unless necessary (about to context-switch to some other fp-busy program), and otherwise just leave them in the cpu regs
<gromero> fche: yes, I guess it uses fp regs, I crafted it with some inline asm and gdb tells me it's effective
<fche> and where did you set the probe to interrupt that task ?
<gromero> yes, your hypothesis is pretty good and I'm actually trying to confirm that, but I'm having a hard time ...
<fche> setting up some stap probes inside those parts of the kernel that deal with the fp regs may help
<fche> i.e., use stap to trace the fp reg manipulations
<gromero> for the probe I have:
<gromero> probe process("/home/gromero/x").function("a_func").return {
<gromero> printf("%0lx\n", register("r3"));
<gromero> printf("%0lx\n", register("f0"));
<gromero> }
<gromero> f0 will hit the crafted code in _stp_get_register_by_offset that uses current->thread.fp_state.fpr[i1][i2]
<gromero> x.c is:
<gromero> void a_func(int i)
<gromero> {
<gromero> printf("%d\n", i);
<gromero> asm volatile ("li 3, 0xbee;"
<gromero> "mtvsrd 0, 3;"
<gromero> "mtvsrd 32,3;"
<gromero> "fctid 1, 0;");
<gromero> }
<gromero> int main()
<gromero> {
<gromero> a_func(0xf);
<gromero> }
<gromero> vs0 is actually f0
<gromero> but I also tested vs32 and other values
<gromero> > setting up some stap probes inside those parts of the kernel that deal with the fp regs may help
<gromero> that's where I am now
<gromero> but it's not being easy to find a function I can trust for that purpose
<gromero> what if trap exception won't save fp in the fp_state struct I'm wondering ...
<gromero> I'm inclined to say fp are not saved on the exception alone, only if a context switch happens
<gromero> let me try to add some loops after messing with vs0 to see if I get a context-switch
<fche> would check for those parts of arch/powerpc/* that mention MSR_FP
<gromero> okay
<fche> save_fpu() relevant symbol
<fche> flush_all_to_thread() <-- our pal
<gromero> I tried giveup_all already btw
<fche> called how?
<gromero> wait, I found fpr struct set after returning from save_fpu() o/
<gromero> interesting !
<gromero> set with `0xbee` as expected
<gromero> let me see the trace
<gromero> fp_state.fpr[0]=0x0000000000000bee0000000000000000
<gromero> vr_state.vr[0] =0x00000000000000000000000000000000
<gromero> Returning from: 0xc00000000000f4f8 : save_fpu+0x0/0x2ac [kernel]
<gromero> 0xc000000000020b64 : giveup_all+0xe4/0x110 [kernel]
<gromero> Returning to : 0xc000000000020468 : __giveup_fpu+0x28/0x80 [kernel]
<gromero> 0xc000000000020b64 : giveup_all+0xe4/0x110 [kernel] (inexact)
<gromero> 0xc000000000021aa8 : __switch_to+0x108/0x460 [kernel] (inexact)
<gromero> 0xc000000000144664 : do_task_dead+0x64/0x70 [kernel] (inexact)
<gromero> 0xc000000000107848 : do_exit+0x818/0xd50 [kernel] (inexact)
<gromero> 0xc000000000107e50 : do_group_exit+0x60/0x110 [kernel] (inexact)
<gromero> 0xc000000000107f24 : sys_exit_group+0x24/0x30 [kernel] (inexact)
<gromero> 0xc00000000000bde4 : system_call+0x5c/0x70 [kernel] (inexact)
<gromero> but on the same process "x", after that hit, other hits to save_fpu() return 0 in fpr[0]
<gromero> that's unexpected, since I would expect that fp_state would be in sync to what's found in the register in userspace ...
<gromero> until the end of the process f0=0xbee
<fche> right but the kernel might not save the register state back to the task_struct every time
<fche> s/might/will/
<fche> unless that giveup_all() or equivalent is done every time you want to read the ->Fp_regs
<gromero> okay, I'll confirm that with the kernel folks tomorrow, but if it holds true, how should we proceed ?
<gromero> we basically can't trust fp_state context at will : /
<fche> we need to arrange to call giveup_all() or equivalent when/if the fpregs are being sought
orivej has joined #systemtap
<fche> this may be possible from within the stap tapset function that realizes the user is asking for fpregs
<gromero> I see. I think it's feasible and won't harm the process state too
<gromero> stap probe will always be executed when leaving kernel space to userspace
<gromero> from ret_from_except_lite()
<gromero> calling do_notify_resume()
<gromero> that will check if uprobe is in use IIRC
<gromero> okay, I'll give it a try
<gromero> I'm going off for today
<gromero> thanks a lot for all the help!
<fche> np
sapatel_ has quit [Remote host closed the connection]