Discussion:
[DTrace internals]
Shrikanth R K
2010-07-20 05:59:58 UTC
Permalink
I see the the instruction DIF_OP_LDUW (when observed with the option verbose in script) is getting replaced with a DIF_OP_RLDUW. Maybe this is intentional, but with DIF_OP_RLDUW the check 'dtrace_canstore' fails giving 'CPU_DTRACE_KPRIV' fault for whatever variables I query.

* Is this intentional replacement?
* If yes, then my args[0] variables are all outside the range being checked in dtrace_canstore which gets called when dtrace_dif_emulate sees DIF_OP_RLDUW?
** This is FreeBSD cross compiler environment...

Here is the script
#pragma D option verbose
BEGIN
{
}
fbt::kernel_nudge_client:entry
{
trace(args[0]->client_num);
}
---------------------------------------------------------------------------------------
root%dtrace -s fbt_test.d

DIFO 0x0x80b1280 returns D type (integer) (size 4)
OFF OPCODE INSTRUCTION
00: 25000001 setx DT_INTEGER[0], %r1 ! 0x0
01: 28000101 ldga DT_VAR(0), %r1, %r1
02: 25000102 setx DT_INTEGER[1], %r2 ! 0x20
03: 04010201 sll %r1, %r2, %r1
04: 05010201 srl %r1, %r2, %r1
05: 25000202 setx DT_INTEGER[2], %r2 ! 0xc
06: 07010201 add %r1, %r2, %r1
07: 21010001 lduw [%r1], %r1 <== LDUW here
08: 23000001 ret %r1
dtrace: script 'fbt_test.d' matched 2 probes
CPU ID FUNCTION:NAME
0 1 :BEGIN
---------------------------------------------------------------------------------------
But when the probe is hit, I compare what DIFO is present in kernel space

(kgdb) p /x text[7]
$12 = 0x4c010001

whereas the instruction 07 in the above dump is 0x21010001
'4c' says it is a "rlduw" instruction.

The problem is the args[0]->client_num address is showing up as [0xc45b3d2c]
and the check in dtrace_canstore shows all ranges for 'dtms_scratch_base',
'dtvs_dynvars.dtds_base' are above the "0xc45b3d2c". Hence dtrace_canstore returns 0
and CPU_DTRACE_KPRIV gets returned.

(kgdb) fr
#3 0xc4ff9863 in dtrace_dif_emulate...
(kgdb) p /x 0xc45b3d2c <== &args[0]->client_num
$19 = 0xc45b3d2c
(kgdb) p /x mstate->dtms_scratch_base
$20 = 0xc5cc0008
(kgdb) p /x mstate->dtms_scratch_size
$21 = 0xbffff8
(kgdb) p /x vstate->dtvs_dynvars.dtds_base
$22 = 0xc74c0000
(kgdb) p /x vstate->dtvs_dynvars.dtds_size
$23 = 0x100000
--------------------------------------------------------------------------------------------
Here is o/p for
root%dtrace -l -f kernel_nudge_client -v

ID PROVIDER MODULE FUNCTION NAME
58 fbt kernel kernel_nudge_client entry

Probe Description Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: Unknown

Argument Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: ISA

Argument Types
args[0]: kernel_client *
args[1]: int

--
Shrikanth R K
--
This message posted from opensolaris.org
Adam Leventhal
2010-08-13 19:09:11 UTC
Permalink
Post by Shrikanth R K
I see the the instruction DIF_OP_LDUW (when observed with the option verbose in script) is getting replaced with a DIF_OP_RLDUW. Maybe this is intentional, but with DIF_OP_RLDUW the check 'dtrace_canstore' fails giving 'CPU_DTRACE_KPRIV' fault for whatever variables I query.
We do this for unprivileged consumers:

http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/dtrace/dtrace.c#dtrace_difo_validate

look for 'checkload'
Post by Shrikanth R K
* Is this intentional replacement?
* If yes, then my args[0] variables are all outside the range being checked in dtrace_canstore which gets called when dtrace_dif_emulate sees DIF_OP_RLDUW?
** This is FreeBSD cross compiler environment...
It sounds like you're running into an idiosyncrasy of the FreeBSD DTrace port.

Adam
Post by Shrikanth R K
Here is the script
#pragma D option verbose
BEGIN
{
}
fbt::kernel_nudge_client:entry
{
trace(args[0]->client_num);
}
---------------------------------------------------------------------------------------
root%dtrace -s fbt_test.d
DIFO 0x0x80b1280 returns D type (integer) (size 4)
OFF OPCODE INSTRUCTION
00: 25000001 setx DT_INTEGER[0], %r1 ! 0x0
01: 28000101 ldga DT_VAR(0), %r1, %r1
02: 25000102 setx DT_INTEGER[1], %r2 ! 0x20
03: 04010201 sll %r1, %r2, %r1
04: 05010201 srl %r1, %r2, %r1
05: 25000202 setx DT_INTEGER[2], %r2 ! 0xc
06: 07010201 add %r1, %r2, %r1
07: 21010001 lduw [%r1], %r1 <== LDUW here
08: 23000001 ret %r1
dtrace: script 'fbt_test.d' matched 2 probes
CPU ID FUNCTION:NAME
0 1 :BEGIN
---------------------------------------------------------------------------------------
But when the probe is hit, I compare what DIFO is present in kernel space
(kgdb) p /x text[7]
$12 = 0x4c010001
whereas the instruction 07 in the above dump is 0x21010001
'4c' says it is a "rlduw" instruction.
The problem is the args[0]->client_num address is showing up as [0xc45b3d2c]
and the check in dtrace_canstore shows all ranges for 'dtms_scratch_base',
'dtvs_dynvars.dtds_base' are above the "0xc45b3d2c". Hence dtrace_canstore returns 0
and CPU_DTRACE_KPRIV gets returned.
(kgdb) fr
#3 0xc4ff9863 in dtrace_dif_emulate...
(kgdb) p /x 0xc45b3d2c <== &args[0]->client_num
$19 = 0xc45b3d2c
(kgdb) p /x mstate->dtms_scratch_base
$20 = 0xc5cc0008
(kgdb) p /x mstate->dtms_scratch_size
$21 = 0xbffff8
(kgdb) p /x vstate->dtvs_dynvars.dtds_base
$22 = 0xc74c0000
(kgdb) p /x vstate->dtvs_dynvars.dtds_size
$23 = 0x100000
--------------------------------------------------------------------------------------------
Here is o/p for
root%dtrace -l -f kernel_nudge_client -v
ID PROVIDER MODULE FUNCTION NAME
58 fbt kernel kernel_nudge_client entry
Probe Description Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: Unknown
Argument Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: ISA
Argument Types
args[0]: kernel_client *
args[1]: int
--
Shrikanth R K
--
This message posted from opensolaris.org
_______________________________________________
dtrace-discuss mailing list
--
Adam Leventhal, Fishworks http://blogs.sun.com/ahl
Loading...