Re: [Intel-gfx] kernel oops loading i915 after "x86/asm: Pin sensitive CR4 bits" (873d50d58)

2019-07-10 Thread Dmitry V. Levin
Hi,

On Wed, Jul 10, 2019 at 01:44:17PM +0800, Xi Ruoyao wrote:
> Hello,
> 
> When I try to build and run the latest mainline kernel, it Oops loading i915
> module:
> 
> BUG: unable to handle page fault for address: 9edc1598
> #PF: supervisor write access in kernel mode
> #PF: error_code(0x0003) - permissions violation
> PGD 1a20c067 P4D 1a20c067 PUD 1a20d063 PMD 800019e000e1 
> Oops: 0003 [#1] SMP PTI
> 
> The complete log is attached.
> 
> Bisection tells "x86/asm: Pin sensitive CR4 bits" (873d50d58) is the first 
> "bad"
> commit.  I can revert it and also "x86/asm: Pin sensitive CR0 bits" 
> (8dbec27a2)
> to make the kernel "seems to" work.
> 
> I'm not a kernel expert so I can't tell if there is a bug in Kees' patch, or 
> his
> patch exploits a bug in i915 or module loader.

This seems to be a kernel bug introduced after v5.2, see
https://lore.kernel.org/lkml/CAHk-=wjh+h_-fd-gJz=wor42znmqq46qnb90jyfzqmklslf...@mail.gmail.com/


-- 
ldv
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH v4 2/5] drm: Add private data field to trace control block

2016-07-20 Thread Dmitry V. Levin
On Mon, Sep 07, 2015 at 08:23:57PM +0200, Patrik Jakobsson wrote:
> On Mon, Sep 7, 2015 at 6:51 PM, Dmitry V. Levin wrote:
> > On Mon, Aug 31, 2015 at 02:37:07PM +0200, Patrik Jakobsson wrote:
> > [...]
> >> Here's my take on it (I assume it needs some discussion):
> >>
> >> int
> >> set_tcb_priv_data(struct tcb *tcp, void *priv_data)
> >> {
> >>   /* A free callback is required before setting private data and 
> >> private
> >>* data must be set back to NULL before being set again.
> >>*/
> >
> > I think a single function initializing both _priv_data and _free_priv_data
> > would suffice:
> >
> > int
> > set_tcb_priv_data(struct tcb *tcp, void *priv_data,
> >   void (*free_priv_data)(void *))
> > {
> > if (tcp->_priv_data)
> > return -1;
> >
> > tcp->_free_priv_data = free_priv_data;
> > tcp->_priv_data = priv_data;
> >
> > return 0;
> > }
> 
> Sure, and since they always come in a pairs it might be even better. If it 
> turns
> out we need it split up it is easily done later.

JFYI, I've finalized and merged this set_tcb_priv_data interface.


-- 
ldv


pgp4iyIZxJS8j.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 2/5] drm: Add private data field to trace control block

2015-11-23 Thread Dmitry V. Levin
On Mon, Sep 07, 2015 at 08:23:57PM +0200, Patrik Jakobsson wrote:
> On Mon, Sep 7, 2015 at 6:51 PM, Dmitry V. Levin wrote:
> > On Mon, Aug 31, 2015 at 02:37:07PM +0200, Patrik Jakobsson wrote:
> > [...]
> >> Here's my take on it (I assume it needs some discussion):
> >>
> >> int
> >> set_tcb_priv_data(struct tcb *tcp, void *priv_data)
> >> {
> >>   /* A free callback is required before setting private data and 
> >> private
> >>* data must be set back to NULL before being set again.
> >>*/
> >
> > I think a single function initializing both _priv_data and _free_priv_data
> > would suffice:
> >
> > int
> > set_tcb_priv_data(struct tcb *tcp, void *priv_data,
> >   void (*free_priv_data)(void *))
> > {
> > if (tcp->_priv_data)
> > return -1;
> >
> > tcp->_free_priv_data = free_priv_data;
> > tcp->_priv_data = priv_data;
> >
> > return 0;
> > }
> 
> Sure, and since they always come in a pairs it might be even better. If it 
> turns
> out we need it split up it is easily done later.

The discussion seems to be stalled.
Patrik, would you like to prepare a patch?


-- 
ldv


pgpJLCZWgilyc.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 3/5] drm: Add dispatcher and driver identification for DRM

2015-11-23 Thread Dmitry V. Levin
On Fri, Sep 11, 2015 at 12:57:06PM +0200, Patrik Jakobsson wrote:
> On Tue, Sep 08, 2015 at 03:36:25AM +0300, Dmitry V. Levin wrote:
> > On Mon, Aug 24, 2015 at 02:42:48PM +0200, Patrik Jakobsson wrote:
[...]
> > > +static char *drm_get_driver_name(struct tcb *tcp)
> > > +{
> > > + char path[PATH_MAX];
> > > + char link[PATH_MAX];
> > > + int ret;
> > > +
> > > + if (getfdpath(tcp, tcp->u_arg[0], path, PATH_MAX - 1) < 0)
> > > + return NULL;
> > > +
> > > + snprintf(link, PATH_MAX, "/sys/class/drm/%s/device/driver",
> > > +  basename(path));
> > 
> > if (snprintf(link, sizeof(link), ...) >= sizeof(link))
> > return NULL;
> > 
> 
> According to manpage snprintf never returns more than the specified size - 1.

Really?

"The functions snprintf() and vsnprintf() do not write more than size
bytes (including the terminating null byte ('\0')).  If the output was
truncated due to this limit, then the return value is the number of
characters (excluding the terminating null byte) which would have been
written to the final string if enough space had been available.  Thus,
a return value of size or more means that the output was truncated."


-- 
ldv


pgpGbjcYBUQdC.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 4/5] drm: Add decoding of i915 ioctls

2015-09-11 Thread Dmitry V. Levin
On Fri, Sep 11, 2015 at 01:31:02PM +0200, Patrik Jakobsson wrote:
> On Tue, Sep 08, 2015 at 04:18:11AM +0300, Dmitry V. Levin wrote:
> > On Mon, Aug 24, 2015 at 02:42:49PM +0200, Patrik Jakobsson wrote:
> > > +static int i915_getparam(struct tcb *tcp, const unsigned int code, long 
> > > arg)
> > > +{
> > > + struct drm_i915_getparam param;
> > > + int value;
> > > +
> > > + if (umove(tcp, arg, ))
> > > + return RVAL_DECODED;
> > > +
> > > + if (entering(tcp)) {
> > > + tprints(", {param=");
> > > + printxval(drm_i915_getparams, param.param, "I915_PARAM_???");
> > > + } else if (exiting(tcp)) {
> > > + if (umove(tcp, (long)param.value, ))
> > > + return RVAL_DECODED;
> > 
> > Since part of param has already been printed, RVAL_DECODED shouldn't be
> > returned here.  For the same reason, RVAL_DECODED shouldn't be returned
> > earlier in this function.
> 
> The usage of RVAL_DECODED is quite confusing. RVAL_DECODED to me should be "We
> decoded this don't do any fallback". How did you intent it to be used?

RVAL_DECODED itself is trivial: by setting this flag parser tells its
caller that decoding is finished on entering and it shouldn't be called on
exiting of this syscall.  Setting this flag on exiting has no effect.

With regards to ioctl parsers, there might be some confusion because they
also have this unusual return code +1 semantics.  In this example, the
problem with "return RVAL_DECODED" statements is that if they happen on
exiting, it means that something has already been printed on entering
already and by returning RVAL_DECODED parser tells its caller to perform
the default action that also prints something.

That is, ioctl parser should return
- on entering:
  + any value (it's ignored) without RVAL_DECODED flag set:
continue processing on exiting;
  + RVAL_DECODED:
skip processing on exiting and tell the caller
to perform default processing on entering;
  + RVAL_DECODED | (1 + RVAL_*):
skip processing on exiting and tell the caller
to skip default processing;
- on exiting:
  + 0 (with or without RVAL_DECODED set, it's ignored anyway):
tell the caller to perform default processing on exiting;
  + 1 + RVAL_* (RVAL_DECODED is ignored):
tell the caller to skip default processing.

> > > + break;
> > > + default:
> > > + tprintf("%d", value);
> > 
> > Likewise.
> > 
> > > + }
> > > + tprints("}");
> > > + }
> > > +
> > > + return RVAL_DECODED | 1;
> > 
> > This shouldn't be returned on entering(tcp).
> 
> If all decoding would be done when entering is finished, wouldn't it make 
> sense
> to allow RVAL_DECODED here? Still don't understand how this is intended to 
> work.

Usally only IOW parsers return codes with RVAL_DECODED set on entering.
IOWR also print something on exiting so they shouldn't normally return
RVAL_DECODED on entering.


-- 
ldv


pgp0fYbXCVwEg.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 5/5] drm: Add decoding of DRM and KMS ioctls

2015-09-11 Thread Dmitry V. Levin
On Fri, Sep 11, 2015 at 01:39:29PM +0200, Patrik Jakobsson wrote:
> On Wed, Sep 09, 2015 at 01:50:40AM +0300, Dmitry V. Levin wrote:
> > On Mon, Aug 24, 2015 at 02:42:50PM +0200, Patrik Jakobsson wrote:
> > > +static int drm_mode_create_dumb(struct tcb *tcp, const unsigned int 
> > > code, long arg)
> > > +{
> > > + struct drm_mode_create_dumb dumb;
> > > +
> > > + if (umove(tcp, arg, ))
> > > + return RVAL_DECODED;
> > > +
> > > + if (entering(tcp)) {
> > > + tprintf(", {width=%u, height=%u, bpp=%u, flags=0x%x",
> > > + dumb.width, dumb.height, dumb.bpp, dumb.flags);
> > > + } else if (exiting(tcp)) {
> > > + tprintf(", handle=%u, pitch=%u, size=%Lu}", dumb.handle,
> > > + dumb.pitch, dumb.size);
> > > + }
> > > +
> > > + return RVAL_DECODED | 1;
> > > +}
> > 
> > This generates a warning (which turns into an error with
> > --enable-gcc-Werror) on x86_64 when using kernel drm headers:
> > 
> > drm.c: In function 'drm_mode_create_dumb':
> > drm.c:521:11: error: format '%Lu' expects argument of type 'long long 
> > unsigned int', but argument 4 has type 'uint64_t {aka long unsigned int}' 
> > [-Werror=format=]
> 
> So this brings us back to whether to include drm kernel headers or not. If
> -Werror is a requirement (which is already broken last time I checked) there

Is it?  Could you cite the error, please?

> will need to be #ifdefs at various places in drm decoding. What would you
> prefer. Both options are fine by me.

This is the only place where definitions differ to the extent that it's visible.
I'd rather cast the argument to unsigned long long.


-- 
ldv


pgpQIVjW9KMtJ.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 5/5] drm: Add decoding of DRM and KMS ioctls

2015-09-11 Thread Dmitry V. Levin
On Fri, Sep 11, 2015 at 02:20:35PM +0200, Patrik Jakobsson wrote:
> On Fri, Sep 11, 2015 at 03:10:05PM +0300, Dmitry V. Levin wrote:
> > On Fri, Sep 11, 2015 at 01:39:29PM +0200, Patrik Jakobsson wrote:
> > > On Wed, Sep 09, 2015 at 01:50:40AM +0300, Dmitry V. Levin wrote:
> > > > On Mon, Aug 24, 2015 at 02:42:50PM +0200, Patrik Jakobsson wrote:
> > > > > +static int drm_mode_create_dumb(struct tcb *tcp, const unsigned int 
> > > > > code, long arg)
> > > > > +{
> > > > > + struct drm_mode_create_dumb dumb;
> > > > > +
> > > > > + if (umove(tcp, arg, ))
> > > > > + return RVAL_DECODED;
> > > > > +
> > > > > + if (entering(tcp)) {
> > > > > + tprintf(", {width=%u, height=%u, bpp=%u, flags=0x%x",
> > > > > + dumb.width, dumb.height, dumb.bpp, dumb.flags);
> > > > > + } else if (exiting(tcp)) {
> > > > > + tprintf(", handle=%u, pitch=%u, size=%Lu}", dumb.handle,
> > > > > + dumb.pitch, dumb.size);
> > > > > + }
> > > > > +
> > > > > + return RVAL_DECODED | 1;
> > > > > +}
> > > > 
> > > > This generates a warning (which turns into an error with
> > > > --enable-gcc-Werror) on x86_64 when using kernel drm headers:
> > > > 
> > > > drm.c: In function 'drm_mode_create_dumb':
> > > > drm.c:521:11: error: format '%Lu' expects argument of type 'long long 
> > > > unsigned int', but argument 4 has type 'uint64_t {aka long unsigned 
> > > > int}' [-Werror=format=]
> > > 
> > > So this brings us back to whether to include drm kernel headers or not. If
> > > -Werror is a requirement (which is already broken last time I checked) 
> > > there
> > 
> > Is it?  Could you cite the error, please?
> 
> It's in aio.c:185 which at a closer look is intentional. Would still break the
> build though. But I'm not arguing that letting warnings slip through (with or
> without -Werror) is ok, just wondering if it justifies what I'm trying to do
> here.

strace is expected to build without compilation warnings assuming that the
compiler and headers are supported.  In fact, I routinely build strace
with --enable-gcc-Werror.  If it doesn't build for you, please report.


-- 
ldv


pgpAg2_5UiTmI.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 4/5] drm: Add decoding of i915 ioctls

2015-09-09 Thread Dmitry V. Levin
On Tue, Sep 08, 2015 at 04:30:52AM +0300, Dmitry V. Levin wrote:
> On Tue, Sep 08, 2015 at 04:18:11AM +0300, Dmitry V. Levin wrote:
> [...]
> > So the whole function should look smth like this:
> > 
> > static int i915_getparam(struct tcb *tcp, const unsigned int code, long arg)
> > {
> > struct drm_i915_getparam param;
> > 
> > if (entering(tcp)) {
> > if (umove_or_printaddr(tcp, arg, ))
> > return RVAL_DECODED | 1;
> > tprints(", {param=");
> 
> or rather
>   tprints(", ");
>   if (umove_or_printaddr(tcp, arg, ))
>   return RVAL_DECODED | 1;
>   tprints("{param=");

or rather

static int
i915_getparam(struct tcb *tcp, const unsigned int code, const long arg)
{
struct drm_i915_getparam param;
int value;

if (entering(tcp)) {
tprints(", ");
if (umove_or_printaddr(tcp, arg, ))
return RVAL_DECODED | 1;
tprints("{param=");
printxval(drm_i915_getparams, param.param, "I915_PARAM_???");
return 0;
}

if (!umove(tcp, arg, )) {
tprints(", value=");
if (!umove_or_printaddr(tcp, (long) param.value, )) {
switch (param.param) {
case I915_PARAM_CHIPSET_ID:
tprintf("[%#04x]", value);
break;
default:
tprintf("[%d]", value);
}
}
}
tprints("}");
return 1;
}

Note that those structure members that are set by the kernel on exiting
syscall shouldn't normally be printed in case of syserror(tcp).

In case of i915_getparam, no extra check is needed because param.value is
an address supplied by userspace and umove_or_printaddr already performs
all necessary checks, but in other IOWR parsers you might want to use
if (!syserror(tcp) && !umove(tcp, arg, )) {
instead.


-- 
ldv


pgp9B2ipYt45y.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 5/5] drm: Add decoding of DRM and KMS ioctls

2015-09-08 Thread Dmitry V. Levin
On Mon, Aug 24, 2015 at 02:42:50PM +0200, Patrik Jakobsson wrote:
> First batch of drm / kms ioctls.

Several comments in addition to issues similar to 4/5 patch.

> +static int drm_mode_rm_fb(struct tcb *tcp, const unsigned int code, long arg)
> +{
> + unsigned int handle;
> +
> +
> + if (entering(tcp)) {
> + if (umove(tcp, arg, ))
> + return RVAL_DECODED;
> +
> + tprintf(", %u", handle);
> + }
> +
> + return RVAL_DECODED | 1;
> +}

Use printnum_int instead:

tprints(", ");
printnum_int(tcp, arg, "%u");
return RVAL_DECODED | 1;

> +static int drm_mode_create_dumb(struct tcb *tcp, const unsigned int code, 
> long arg)
> +{
> + struct drm_mode_create_dumb dumb;
> +
> + if (umove(tcp, arg, ))
> + return RVAL_DECODED;
> +
> + if (entering(tcp)) {
> + tprintf(", {width=%u, height=%u, bpp=%u, flags=0x%x",
> + dumb.width, dumb.height, dumb.bpp, dumb.flags);
> + } else if (exiting(tcp)) {
> + tprintf(", handle=%u, pitch=%u, size=%Lu}", dumb.handle,
> + dumb.pitch, dumb.size);
> + }
> +
> + return RVAL_DECODED | 1;
> +}

This generates a warning (which turns into an error with
--enable-gcc-Werror) on x86_64 when using kernel drm headers:

drm.c: In function 'drm_mode_create_dumb':
drm.c:521:11: error: format '%Lu' expects argument of type 'long long unsigned 
int', but argument 4 has type 'uint64_t {aka long unsigned int}' 
[-Werror=format=]

> @@ -112,6 +577,84 @@ int drm_ioctl(struct tcb *tcp, const unsigned int code, 
> long arg)
>   if (drm_is_priv(tcp->u_arg[1])) {
>   if (verbose(tcp) && drm_is_driver(tcp, "i915"))
>   ret = drm_i915_ioctl(tcp, code, arg);
> + } else {
> + switch (code) {
> + case DRM_IOCTL_VERSION:
> + ret = drm_version(tcp, code, arg);
> + break;

Looks like the return code can be forwarded without further delays.


-- 
ldv


pgpdCzNMLBccW.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 2/5] drm: Add private data field to trace control block

2015-09-07 Thread Dmitry V. Levin
On Mon, Aug 31, 2015 at 02:37:07PM +0200, Patrik Jakobsson wrote:
[...]
> Here's my take on it (I assume it needs some discussion):
> 
> int
> set_tcb_priv_data(struct tcb *tcp, void *priv_data)
> {
>   /* A free callback is required before setting private data and private
>* data must be set back to NULL before being set again.
>*/

I think a single function initializing both _priv_data and _free_priv_data
would suffice:

int
set_tcb_priv_data(struct tcb *tcp, void *priv_data,
  void (*free_priv_data)(void *))
{
if (tcp->_priv_data)
return -1;

tcp->_free_priv_data = free_priv_data;
tcp->_priv_data = priv_data;

return 0;
}


-- 
ldv


pgpV4AdZ7BOOw.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 4/5] drm: Add decoding of i915 ioctls

2015-09-07 Thread Dmitry V. Levin
On Mon, Aug 24, 2015 at 02:42:49PM +0200, Patrik Jakobsson wrote:
> +static int i915_getparam(struct tcb *tcp, const unsigned int code, long arg)
> +{
> + struct drm_i915_getparam param;
> + int value;
> +
> + if (umove(tcp, arg, ))
> + return RVAL_DECODED;
> +
> + if (entering(tcp)) {
> + tprints(", {param=");
> + printxval(drm_i915_getparams, param.param, "I915_PARAM_???");
> + } else if (exiting(tcp)) {
> + if (umove(tcp, (long)param.value, ))
> + return RVAL_DECODED;

Since part of param has already been printed, RVAL_DECODED shouldn't be
returned here.  For the same reason, RVAL_DECODED shouldn't be returned
earlier in this function.

> + tprints(", value=");
> + switch (param.param) {
> + case I915_PARAM_CHIPSET_ID:
> + tprintf("0x%04x", value);

Since the value has been fetched by address stored in param.value,
it has to be printed in brackets like in printnum_int.

> + break;
> + default:
> + tprintf("%d", value);

Likewise.

> + }
> + tprints("}");
> + }
> +
> + return RVAL_DECODED | 1;

This shouldn't be returned on entering(tcp).

> +}

So the whole function should look smth like this:

static int i915_getparam(struct tcb *tcp, const unsigned int code, long arg)
{
struct drm_i915_getparam param;

if (entering(tcp)) {
if (umove_or_printaddr(tcp, arg, ))
return RVAL_DECODED | 1;
tprints(", {param=");
printxval(drm_i915_getparams, param.param, "I915_PARAM_???");
tprints(", value=");
return 0;
} else {
int value;

if (umove(tcp, arg, )) {
tprints("???");
} else if (!umove_or_printaddr(tcp, (long) param.value, 
)) {
switch (param.param) {
case I915_PARAM_CHIPSET_ID:
tprintf("[%#04x]", value);
break;
default:
tprintf("[%d]", value);
}
}
tprints("}");
return 1;
}
}

Please apply this approach to all DRM_IOWR parsers.

> +
> +static int i915_setparam(struct tcb *tcp, const unsigned int code, long arg)
> +{
> + struct drm_i915_setparam param;
> +
> + if (entering(tcp)) {
> + if (umove(tcp, arg, ))
> + return RVAL_DECODED;

In this and other functions I slightly prefer
if (umove_or_printaddr(tcp, arg, ))
return RVAL_DECODED | 1;
over your variant because umove_or_printaddr() handles NULL address
and !verbose(tcp) case better.


-- 
ldv


pgpGBPm5dnhI6.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 3/5] drm: Add dispatcher and driver identification for DRM

2015-09-07 Thread Dmitry V. Levin
On Mon, Aug 24, 2015 at 02:42:48PM +0200, Patrik Jakobsson wrote:
> * Makefile.am: Add compilation of drm.c.
> * defs.h: Add extern declaration of drm_ioctl when drm headers are found.
> * drm.c: New file.
> * ioctl.c (ioctl_decode): Dispatch drm ioctls when drm headers are found.

* defs.h (drm_decode_number, drm_ioctl): New prototypes.
* drm.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* ioctl.c (ioctl_decode_command_number, ioctl_decode)
[HAVE_DRM_H || HAVE_DRM_DRM_H]: Dispatch drm ioctls.

> --- a/defs.h
> +++ b/defs.h
> @@ -612,6 +612,9 @@ extern const char *sprint_open_modes(int);
>  extern void print_seccomp_filter(struct tcb *tcp, unsigned long);
>  
>  extern int block_ioctl(struct tcb *, const unsigned int, long);
> +#if defined(HAVE_DRM_H) || defined(HAVE_DRM_DRM_H)
> +extern int drm_ioctl(struct tcb *, const unsigned int, long);
> +#endif

I think function these prototypes could be added unconditionally.
Note that v3 version of this patch also declared drm_decode_number().

> --- /dev/null
> +++ b/drm.c
[...]
> +#include "defs.h"
> +
> +#if defined(HAVE_DRM_H) || defined(HAVE_DRM_DRM_H)
> +
> +#ifdef HAVE_DRM_H
> +#include 
> +#else
> +#include 
> +#endif
> +
> +#include 

Let's include  before drm stuff.

> +#define DRM_MAX_NAME_LEN 128
> +
> +inline int drm_is_priv(const unsigned int num)
> +{
> + return (_IOC_NR(num) >= DRM_COMMAND_BASE &&
> + _IOC_NR(num) < DRM_COMMAND_END);
> +}

This function has to be static, and like other static functions,
it has to be added along with its first user, otherwise the project
won't build with --enable-gcc-Werror.

> +static char *drm_get_driver_name(struct tcb *tcp)
> +{
> + char path[PATH_MAX];
> + char link[PATH_MAX];
> + int ret;
> +
> + if (getfdpath(tcp, tcp->u_arg[0], path, PATH_MAX - 1) < 0)
> + return NULL;
> +
> + snprintf(link, PATH_MAX, "/sys/class/drm/%s/device/driver",
> +  basename(path));

if (snprintf(link, sizeof(link), ...) >= sizeof(link))
return NULL;

> +static void drm_free_priv(void *data)
> +{
> + free(data);
> +}

Do we really need a wrapper for free(3)?

> --- a/ioctl.c
> +++ b/ioctl.c
> @@ -248,6 +248,10 @@ ioctl_decode(struct tcb *tcp)
>   case 0x22:
>   return scsi_ioctl(tcp, code, arg);
>  #endif
> +#if defined(HAVE_DRM_H) || defined(HAVE_DRM_DRM_H)
> + case 'd':
> + return drm_ioctl(tcp, code, arg);
> +#endif
>   case 'L':
>   return loop_ioctl(tcp, code, arg);
>   case 'M':

v3 version also patched ioctl_decode_command_number()
to call drm_decode_number().


-- 
ldv


pgpQ1hyYIABO8.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v4 4/5] drm: Add decoding of i915 ioctls

2015-09-07 Thread Dmitry V. Levin
On Tue, Sep 08, 2015 at 04:18:11AM +0300, Dmitry V. Levin wrote:
[...]
> So the whole function should look smth like this:
> 
> static int i915_getparam(struct tcb *tcp, const unsigned int code, long arg)
> {
>   struct drm_i915_getparam param;
> 
>   if (entering(tcp)) {
>   if (umove_or_printaddr(tcp, arg, ))
>   return RVAL_DECODED | 1;
>   tprints(", {param=");

or rather
tprints(", ");
if (umove_or_printaddr(tcp, arg, ))
return RVAL_DECODED | 1;
tprints("{param=");


> In this and other functions I slightly prefer
>   if (umove_or_printaddr(tcp, arg, ))
>   return RVAL_DECODED | 1;
> over your variant because umove_or_printaddr() handles NULL address
> and !verbose(tcp) case better.

And the whole function will look as simple as this:

static int i915_setparam(struct tcb *tcp, const unsigned int code, long arg)
{
struct drm_i915_setparam param;

tprints(", ");
if (!umove_or_printaddr(tcp, arg, )) {
tprints("{param=");
printxval(drm_i915_setparams, param.param, "I915_PARAM_???");
tprintf(", value=%d}", param.value);
}

return RVAL_DECODED | 1;
}

Note the absence of entering(tcp) check because this DRM_IOW parser always
returns a value with RVAL_DECODED flag set.


-- 
ldv


pgpdDdg5mQuUu.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v3 1/5] drm: Add config for detecting libdrm

2015-08-01 Thread Dmitry V. Levin
On Fri, Jul 31, 2015 at 11:09:11AM +0200, Patrik Jakobsson wrote:
 On Thu, Jul 30, 2015 at 10:04:49AM -0400, Mike Frysinger wrote:
  On 30 Jul 2015 15:30, Patrik Jakobsson wrote:
   On Thu, Jul 23, 2015 at 05:48:21AM -0400, Mike Frysinger wrote:
On 01 Jul 2015 14:52, Patrik Jakobsson wrote:
 Use pkg-config to try to find libdrm. If that fails use the standard
 include directory for kernel drm headers in /usr/include/drm.
 
 * configure.ac: Use pkg-config to find libdrm
 
 Signed-off-by: Patrik Jakobsson patrik.jakobs...@linux.intel.com
 ---
  configure.ac | 4 
  1 file changed, 4 insertions(+)
 
 diff --git a/configure.ac b/configure.ac
 index bb8bf46..aa63af7 100644
 --- a/configure.ac
 +++ b/configure.ac
 @@ -844,6 +844,10 @@ fi
  AM_CONDITIONAL([USE_LIBUNWIND], [test x$use_libunwind = xyes])
  AC_MSG_RESULT([$use_libunwind])
  
 +PKG_CHECK_MODULES([libdrm], [libdrm],
 + [CPPFLAGS=$CPPFLAGS $libdrm_CFLAGS],
 + [CPPFLAGS=$CPPFLAGS -I/usr/include/drm])

yikes, no, this is a really really bad idea.  it should read:
PKG_CHECK_MODULES([LIBDRM], [libdrm],
[CPPFLAGS=$CPPFLAGS $LIBDRM_CFLAGS], [:])
   
   I take it you don't want me to fallback on kernel headers and skip
   compiling with drm support if libdrm is not available?
  
  you cannot hardcode any path at all.  if the kernel headers provide all
  of the defines/structs that you need, then just include them directly
  via #include drm/xxx.h.
  -mike
 
 The prefered drm way is to always use the libdrm headers and never the 
 kernel
 headers. I know this is breaking the rules but it's what we got to work with.
 Some distros give you the kernel version and others the libdrm version. The
 kernel version is wrong and libdrm patches this up since we're not allowed to
 break the userspace interface. I think the safest way would be to only compile
 drm support for strace if libdrm is present and ignore the kernel headers.

Unlike most of userspace, strace attempts to show the picture as it's seen
from the kernel perspective.  Sometimes it forces us to use kernel headers
instead of headers provided by libc and other libraries.

If kernel itself uses uapi/drm, it should be safe for strace to use it
as well.  I suppose the check could be written this way:

PKG_CHECK_MODULES([LIBDRM], [libdrm],
  [CPPFLAGS=$CPPFLAGS $LIBDRM_CFLAGS
   AC_CHECK_HEADERS([drm.h i915_drm.h])],
  [AC_CHECK_HEADERS([drm/drm.h drm/i915_drm.h])])
...

#if defined HAVE_DRM_H || defined HAVE_DRM_DRM_H

# ifdef HAVE_DRM_H
#  include drm.h
# else
#  include drm/drm.h
# endif

[rest of drm.c]

#endif /* HAVE_DRM_H || HAVE_DRM_DRM_H */


-- 
ldv


pgpD2LusmvyQ4.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v3 1/5] drm: Add config for detecting libdrm

2015-07-23 Thread Dmitry V. Levin
On Thu, Jul 23, 2015 at 05:48:21AM -0400, Mike Frysinger wrote:
 On 01 Jul 2015 14:52, Patrik Jakobsson wrote:
  Use pkg-config to try to find libdrm. If that fails use the standard
  include directory for kernel drm headers in /usr/include/drm.
  
  * configure.ac: Use pkg-config to find libdrm
  
  Signed-off-by: Patrik Jakobsson patrik.jakobs...@linux.intel.com
  ---
   configure.ac | 4 
   1 file changed, 4 insertions(+)
  
  diff --git a/configure.ac b/configure.ac
  index bb8bf46..aa63af7 100644
  --- a/configure.ac
  +++ b/configure.ac
  @@ -844,6 +844,10 @@ fi
   AM_CONDITIONAL([USE_LIBUNWIND], [test x$use_libunwind = xyes])
   AC_MSG_RESULT([$use_libunwind])
   
  +PKG_CHECK_MODULES([libdrm], [libdrm],
  +   [CPPFLAGS=$CPPFLAGS $libdrm_CFLAGS],
  +   [CPPFLAGS=$CPPFLAGS -I/usr/include/drm])
 
 yikes, no, this is a really really bad idea.  it should read:
 PKG_CHECK_MODULES([LIBDRM], [libdrm],
   [CPPFLAGS=$CPPFLAGS $LIBDRM_CFLAGS], [:])

Why [:] ?  Wouldn't [] suffice?


-- 
ldv


pgpR2DMrJSFVq.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v3 4/5] drm: Add decoding of i915 ioctls

2015-07-10 Thread Dmitry V. Levin
On Fri, Jul 10, 2015 at 02:36:38PM +0200, Patrik Jakobsson wrote:
 On Wed, Jul 08, 2015 at 03:11:36AM +0300, Dmitry V. Levin wrote:
  On Mon, Jul 06, 2015 at 04:40:24PM +0200, Gabriel Laskar wrote:
[...]
   Anyway, SYS_FUNC(ioctl) is a bit complicated, and the handling of the
   fallbacks on failure should be more generic.
  
  What would be useful is a way for on entering parsers to return
  done with decoding information to their callers.
  
  This could be implemented by or'ing return value in the current semantics
  with a flag with done with decoding meaning, e.g. RVAL_DONE.
  
  If an ioctl parser returned RVAL_DONE, this would tell SYS_FUNC(ioctl)
  that the decoding is finished but fallback decoding is needed, while
  RVAL_DONE+1 would mean that the decoding is finished and no fallback
  decoding is needed.
 
 I like that idea but isn't the current return semantics already good enough
 for that? The problem right now is that we ignore the return value from
 ioctl_decode() on entering.

After commit v4.10-104-g204c2bc we no longer ignore the return value from
ioctl_decode() on entering.


-- 
ldv


pgpimtomM5mde.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v3 4/5] drm: Add decoding of i915 ioctls

2015-07-07 Thread Dmitry V. Levin
On Mon, Jul 06, 2015 at 04:40:24PM +0200, Gabriel Laskar wrote:
 On Mon, 6 Jul 2015 12:35:52 +0200, Patrik Jakobsson wrote:
  On Fri, Jul 03, 2015 at 03:36:09AM +0300, Dmitry V. Levin wrote:
   On Wed, Jul 01, 2015 at 02:52:47PM +0200, Patrik Jakobsson wrote:
   [...]
--- a/drm.c
+++ b/drm.c
@@ -35,6 +35,9 @@
 
 #define DRM_MAX_NAME_LEN 128
 
+extern int drm_i915_decode_number(struct tcb *tcp, unsigned int arg);
   
   Please rename arg to code, and ...
   
+extern int drm_i915_ioctl(struct tcb *tcp, const unsigned int code, 
long arg);
   
   ... move both declarations to defs.h to make them visible also
   in the file where these functions are defined.
   
   [...]
+static int i915_setparam(struct tcb *tcp, const unsigned int code, 
long arg)
+{
+   struct drm_i915_setparam param;
+
+   if (entering(tcp)) {
+   if (umove(tcp, arg, param))
+   return 0;
+
+   tprints(, {param=);
+   printxval(drm_i915_setparams, param.param, 
I915_PARAM_???);
+   tprintf(, value=%d}, param.value);
+   }
+
+   return 1;
+}
   
   In this and most of other parsers of _IOC_WRITE ioctls added by this and
   the next patches, any error in parser that leads to return 0 will result
   to disabled arg decoding, including the fallback decoding performed by
   sys_ioctl.
   
   Maybe it's time to deal with this issue in a more generic way.
   
  
  Yes, I'm thinking SYS_FUNC(ioctl) could be improved. But on the other hand 
  how
  likely is it that we fail in umove and what chance do we have to recover 
  from
  that anyway? All I can think of is OOM.
 
 umove() can fail in multiple ways. For example, if the memory is not
 valid in the tracee, umove() will fail.

Yes, this is the most likely cause for umove() to fail,
and the most easily reproducible one, e.g.
ioctl(-1, DRM_IOCTL_VERSION, 42);

 Anyway, SYS_FUNC(ioctl) is a bit complicated, and the handling of the
 fallbacks on failure should be more generic.

What would be useful is a way for on entering parsers to return
done with decoding information to their callers.

This could be implemented by or'ing return value in the current semantics
with a flag with done with decoding meaning, e.g. RVAL_DONE.

If an ioctl parser returned RVAL_DONE, this would tell SYS_FUNC(ioctl)
that the decoding is finished but fallback decoding is needed, while
RVAL_DONE+1 would mean that the decoding is finished and no fallback
decoding is needed.


-- 
ldv


pgpCb97OU3bZW.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v3 2/5] drm: Add private data field to trace control block

2015-07-02 Thread Dmitry V. Levin
On Wed, Jul 01, 2015 at 02:52:45PM +0200, Patrik Jakobsson wrote:
[...]
 --- a/defs.h
 +++ b/defs.h
 @@ -266,6 +266,13 @@ struct tcb {
   int u_error;/* Error code */
   long scno;  /* System call number */
   long u_arg[MAX_ARGS];   /* System call arguments */
 +
 + /*
 +  * Private data for the decoding functions of the syscall. TCB core does
 +  * _not_ handle allocation / deallocation of this data.
 +  */
 + void *priv_data;
 +

This will result to memory leaks if droptcb() is called before the
syscall parser that allocated memory had a chance to deallocate it.
As this data is no longer relevant after leaving trace_syscall_exiting(),
I suggest to perform deallocation directly from trace_syscall_exiting.

This API could be made more flexible by adding another pointer -
the function to be called to deallocate memory, e.g.
struct tcb {
...
void *priv_data;
void (*free_priv_data)(void *);
...
};
...
void
free_priv_data(struct tcb *tcp)
{
if (tcp-priv_data) {
if (tcp-free_priv_data) {
tcp-free_priv_data(tcp-priv_data);
tcp-free_priv_data = NULL;
}
tcp-priv_data = NULL;
}
}
...
droptcb(struct tcb *tcp)
{
...
free_priv_data(tcp);
...
}
...
trace_syscall_exiting(struct tcb *tcp)
{
...
 ret:
free_priv_data(tcp);
...
}

[...]
On Wed, Jul 01, 2015 at 02:52:46PM +0200, Patrik Jakobsson wrote:
 * Makefile.am: Add compilation of drm.c
 * defs.h: Declarations of drm functions
 * drm.c: Utility functions for drm driver detection
 * io.c: Dispatch drm ioctls
 * ioctl.c: Distpatch generic and driver specific ioctls

This is not quite a GNU style changelog entry.  Please have a look at
http://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html
and examples in strace.git history.

[...]
 +#include defs.h
 +
 +#include drm.h
 +#include linux/limits.h

Please include sys/param.h instead of linux/limits.h.

 +#define DRM_MAX_NAME_LEN 128
 +
 +struct drm_ioctl_priv {
 + char name[DRM_MAX_NAME_LEN];
 +};
 +
 +inline int drm_is_priv(const unsigned int num)
 +{
 + return (_IOC_NR(num) = DRM_COMMAND_BASE 
 + _IOC_NR(num)  DRM_COMMAND_END);
 +}
 +
 +static int drm_get_driver_name(struct tcb *tcp, char *name, size_t bufsize)
 +{
 + char path[PATH_MAX];
 + char link[PATH_MAX];
 + int ret;
 +
 + ret = getfdpath(tcp, tcp-u_arg[0], path, PATH_MAX - 1);
 + if (ret  0)
 + return ret;
 +
 + snprintf(link, PATH_MAX, /sys/class/drm/%s/device/driver,
 +  basename(path));
 +
 + ret = readlink(link, path, PATH_MAX - 1);
 + if (ret  0)
 + return ret;
 +
 + path[ret] = '\0';
 + strncpy(name, basename(path), bufsize);
 +
 + return 0;
 +}

I think this is getting too complicated.  This function could just return
strdup(basename(path)) or NULL in case of any error:

static char *
drm_get_driver_name(struct tcb *tcp, const char *name)
{
char path[PATH_MAX];
char link[PATH_MAX];
int ret;

if (getfdpath(tcp, tcp-u_arg[0], path, PATH_MAX - 1)  0)
return NULL;

if (snprintf(link, PATH_MAX, /sys/class/drm/%s/device/driver,
 basename(path)) = PATH_MAX)
return NULL;

ret = readlink(link, path, PATH_MAX - 1);
if (ret  0)
return NULL;

path[ret] = '\0';
return strdup(basename(path));
}

 +
 +int drm_is_driver(struct tcb *tcp, const char *name)
 +{
 + struct drm_ioctl_priv *priv;
 + int ret;
 +
 + /*
 +  * If no private data is allocated we are detecting the driver name for
 +  * the first time and must resolve it.
 +  */
 + if (tcp-priv_data == NULL) {
 + tcp-priv_data = xcalloc(1, sizeof(struct drm_ioctl_priv));

xcalloc shouldn't be used if a potential memory allocation error is not
fatal.  In a parser that performs verbose syscall decoding no memory
allocation error is fatal.

 + priv = tcp-priv_data;
 +
 + ret = drm_get_driver_name(tcp, priv-name, DRM_MAX_NAME_LEN);
 + if (ret)
 + return 0;
 + }
 +
 + priv = tcp-priv_data;
 +
 + return strncmp(name, priv-name, DRM_MAX_NAME_LEN) == 0;

Then with priv_data+free_priv_data interface this would looks smth like
...
if (!tcp-priv_data) {
tcp-priv_data = drm_get_driver_name(tcp, name);
if (tcp-priv_data) {
tcp-free_priv_data = free;
} else {
tcp-priv_data = (void *) ;
tcp-free_priv_data = NULL;
}
}
return !strcmp(name, (char *) tcp-priv_data);

 +}
 +
 +int drm_decode_number(struct tcb *tcp, unsigned int arg)

This is an ioctl request code, let's 

Re: [Intel-gfx] [PATCH v3 4/5] drm: Add decoding of i915 ioctls

2015-07-02 Thread Dmitry V. Levin
On Wed, Jul 01, 2015 at 02:52:47PM +0200, Patrik Jakobsson wrote:
[...]
 --- a/drm.c
 +++ b/drm.c
 @@ -35,6 +35,9 @@
  
  #define DRM_MAX_NAME_LEN 128
  
 +extern int drm_i915_decode_number(struct tcb *tcp, unsigned int arg);

Please rename arg to code, and ...

 +extern int drm_i915_ioctl(struct tcb *tcp, const unsigned int code, long 
 arg);

... move both declarations to defs.h to make them visible also
in the file where these functions are defined.

[...]
 +static int i915_setparam(struct tcb *tcp, const unsigned int code, long arg)
 +{
 + struct drm_i915_setparam param;
 +
 + if (entering(tcp)) {
 + if (umove(tcp, arg, param))
 + return 0;
 +
 + tprints(, {param=);
 + printxval(drm_i915_setparams, param.param, I915_PARAM_???);
 + tprintf(, value=%d}, param.value);
 + }
 +
 + return 1;
 +}

In this and most of other parsers of _IOC_WRITE ioctls added by this and
the next patches, any error in parser that leads to return 0 will result
to disabled arg decoding, including the fallback decoding performed by
sys_ioctl.

Maybe it's time to deal with this issue in a more generic way.


-- 
ldv


pgpe2raSsngWM.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/4] drm: Add dispatcher and driver identification for DRM

2015-06-14 Thread Dmitry V. Levin
On Sun, Jun 14, 2015 at 01:12:45PM +0200, Patrik Jakobsson wrote:
[...]
 How about adding a void *private field to struct tcb. That way any
 syscall can store additional data across the life of the tcb.

We can add a field to struct tcb, but its semantics wrt memory management
should be strictly defined.  For example, who is responsible for memory
deallocation, what droptcb() should do about this field, etc.

In this case, we probably need to store a pointer to a string dynamically
allocated in drm_get_driver_name() (on entering syscall) which is
automatically deallocated later in trace_syscall_exiting() and droptcb().


-- 
ldv


pgprsenA7A0jK.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/4] drm: Add dispatcher and driver identification for DRM

2015-06-12 Thread Dmitry V. Levin
On Thu, Jun 11, 2015 at 04:11:49PM +0200, Patrik Jakobsson wrote:
 On Thu, Jun 11, 2015 at 02:26:59AM +0300, Dmitry V. Levin wrote:
  On Wed, Jun 10, 2015 at 01:52:33PM +0200, Patrik Jakobsson wrote:
   On Wed, Jun 10, 2015 at 01:14:20AM +0300, Dmitry V. Levin wrote:
On Tue, Jun 09, 2015 at 01:26:42PM +0200, Patrik Jakobsson wrote:
  [...]
 +#define DRM_MAX_NAME_LEN 128
 +
 +inline int drm_is_priv(const unsigned int num)
 +{
 + return (_IOC_NR(num) = DRM_COMMAND_BASE 
 + _IOC_NR(num)  DRM_COMMAND_END);
 +}
 +
 +static int drm_get_driver_name(struct tcb *tcp, char *name, size_t 
 bufsize)
 +{
 + char path[PATH_MAX];
 + char link[PATH_MAX];
 + int ret;
 +
 + ret = getfdpath(tcp, tcp-u_arg[0], path, PATH_MAX - 1);
 + if (!ret)
 + return ret;
 +
 + snprintf(link, PATH_MAX, /sys/class/drm/%s/device/driver,
 +  basename(path));
 +
 + ret = readlink(link, path, PATH_MAX - 1);
 + if (ret  0)
 + return ret;
 +
 + path[ret] = '\0';
 + strncpy(name, basename(path), bufsize);
 +
 + return 0;
 +}
 +
 +int drm_is_driver(struct tcb *tcp, const char *name)
 +{
 + char drv[DRM_MAX_NAME_LEN];
 + int ret;
 +
 + ret = drm_get_driver_name(tcp, drv, DRM_MAX_NAME_LEN);
 + if (ret)
 + return 0;
 +
 + return strcmp(name, drv) == 0;
 +}

This interface will result to several getfdpath() calls per
ioctl_decode().  If the only purpose of drm_is_driver() is to help 
finding
the most appropriate function, let's create a table of pairs
{driver name, function} and pass this table to a function that will do a
single getfdpath() call, calculate the driver name, and choose the right
function from the table.
   
   Yes I was thinking the same thing but it's a bit tricky. What I need is:
   fd - path - driver name. And fd - path could change between ioctls. It 
   is not
   a likely scenario but it's possible. I could get rid of the extra call in
   drm_decode_number() if I put it back in drm_ioctl as in my RFC. I could 
   also
   optimize path - driver name with a table but I don't know how expensive 
   those
   calls actually are. Not sure what would be the best solution here.
  
  drm_get_driver_name() is quite expensive as it does two readlink syscalls,
  so it should be called at most once per ioctl_decode().
  
  Another method to achieve this is to change drm_get_driver_name() to return
  basename(path) instead of return code, so that drm_ioctl() would call it
  once and pass the result to strcmp calls:
  
  int
  drm_ioctl(struct tcb *tcp, const unsigned int code, long arg)
  {
  if (verbose(tcp)  drm_is_priv(code)) {
  const char *driver = drm_get_driver_name(tcp);
  if (!driver)
  return 0;
  if (!strcmp(driver, i915))
  return drm_i915_ioctl(tcp, code, arg);
  }
  return 0;
  }
 
 I misunderstood you. As you say, we shouldn't do a drm_get_driver_name() more
 than once (no matter how many drm drivers we are looking for) so your 
 suggestion
 above would fix that. I was thinking about how to get rid of the extra call in
 drm_decode_number() (if we could somehow squash them together). But that would
 make things rather ugly. If ok with you we could just have the same approach 
 in
 drm_decode_number() as above and live with the fact that we get two calls to
 drm_get_driver_name() per DRM device specific ioctl. One for 
 drm_decode_number()
 and one for drm_ioctl().

This way we would end up with three drm_get_driver_name() calls per ioctl:
twice on entering syscall and once on exiting.  Maybe we could cache
result of the first of these three calls somewhere?


-- 
ldv


pgpK6Q3_uykrE.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 3/4] drm: Add decoding of i915 ioctls

2015-06-12 Thread Dmitry V. Levin
On Thu, Jun 11, 2015 at 03:34:14PM +0200, Patrik Jakobsson wrote:
 On Thu, Jun 11, 2015 at 02:27:12AM +0300, Dmitry V. Levin wrote:
  On Wed, Jun 10, 2015 at 02:45:24PM +0200, Patrik Jakobsson wrote:
   On Wed, Jun 10, 2015 at 01:35:35AM +0300, Dmitry V. Levin wrote:
On Tue, Jun 09, 2015 at 01:26:43PM +0200, Patrik Jakobsson wrote:
  [...]
 +static int i915_setparam(struct tcb *tcp, const unsigned int code, 
 long arg)
 +{
 + struct drm_i915_setparam param;
 +
 + if (exiting(tcp) || umove(tcp, arg, param))
 + return 0;

In this and other ioctl printers that unconditionally return 0 on exit,
wouldn't the caller treat it as an ioctl that hasn't been printed?
   
   Yes, seems like the exiting phase should return 1 if already handled in 
   the
   entering phase. But changing it produces the same output for some reason. 
   Not
   sure what's going on here.
  
  Isn't tcp-u_arg[2] printed twice, the first time decoded,
  and the second time in hex?
 
 My mistake, it does print u_arg[2] in hex as well. Luckily they could all be
 moved to the exiting phase instead. Fixed in v2.

The common rule is to decode as early as possible, consequently, all
syscall arguments that could be decoded on entering syscall should be
decoded on entering rather than on exiting.  All syscall arguments
of _IOW ioctl commands could be fully decoded on entering syscall.


-- 
ldv


pgp2D72UvJixD.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 3/4] drm: Add decoding of i915 ioctls

2015-06-10 Thread Dmitry V. Levin
On Wed, Jun 10, 2015 at 02:45:24PM +0200, Patrik Jakobsson wrote:
 On Wed, Jun 10, 2015 at 01:35:35AM +0300, Dmitry V. Levin wrote:
  On Tue, Jun 09, 2015 at 01:26:43PM +0200, Patrik Jakobsson wrote:
[...]
   +static int i915_setparam(struct tcb *tcp, const unsigned int code, long 
   arg)
   +{
   + struct drm_i915_setparam param;
   +
   + if (exiting(tcp) || umove(tcp, arg, param))
   + return 0;
  
  In this and other ioctl printers that unconditionally return 0 on exit,
  wouldn't the caller treat it as an ioctl that hasn't been printed?
 
 Yes, seems like the exiting phase should return 1 if already handled in the
 entering phase. But changing it produces the same output for some reason. Not
 sure what's going on here.

Isn't tcp-u_arg[2] printed twice, the first time decoded,
and the second time in hex?


-- 
ldv


pgpEIy0KojEQe.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/4] drm: Add dispatcher and driver identification for DRM

2015-06-10 Thread Dmitry V. Levin
On Wed, Jun 10, 2015 at 01:52:33PM +0200, Patrik Jakobsson wrote:
 On Wed, Jun 10, 2015 at 01:14:20AM +0300, Dmitry V. Levin wrote:
  On Tue, Jun 09, 2015 at 01:26:42PM +0200, Patrik Jakobsson wrote:
[...]
   +#define DRM_MAX_NAME_LEN 128
   +
   +inline int drm_is_priv(const unsigned int num)
   +{
   + return (_IOC_NR(num) = DRM_COMMAND_BASE 
   + _IOC_NR(num)  DRM_COMMAND_END);
   +}
   +
   +static int drm_get_driver_name(struct tcb *tcp, char *name, size_t 
   bufsize)
   +{
   + char path[PATH_MAX];
   + char link[PATH_MAX];
   + int ret;
   +
   + ret = getfdpath(tcp, tcp-u_arg[0], path, PATH_MAX - 1);
   + if (!ret)
   + return ret;
   +
   + snprintf(link, PATH_MAX, /sys/class/drm/%s/device/driver,
   +  basename(path));
   +
   + ret = readlink(link, path, PATH_MAX - 1);
   + if (ret  0)
   + return ret;
   +
   + path[ret] = '\0';
   + strncpy(name, basename(path), bufsize);
   +
   + return 0;
   +}
   +
   +int drm_is_driver(struct tcb *tcp, const char *name)
   +{
   + char drv[DRM_MAX_NAME_LEN];
   + int ret;
   +
   + ret = drm_get_driver_name(tcp, drv, DRM_MAX_NAME_LEN);
   + if (ret)
   + return 0;
   +
   + return strcmp(name, drv) == 0;
   +}
  
  This interface will result to several getfdpath() calls per
  ioctl_decode().  If the only purpose of drm_is_driver() is to help finding
  the most appropriate function, let's create a table of pairs
  {driver name, function} and pass this table to a function that will do a
  single getfdpath() call, calculate the driver name, and choose the right
  function from the table.
 
 Yes I was thinking the same thing but it's a bit tricky. What I need is:
 fd - path - driver name. And fd - path could change between ioctls. It is 
 not
 a likely scenario but it's possible. I could get rid of the extra call in
 drm_decode_number() if I put it back in drm_ioctl as in my RFC. I could also
 optimize path - driver name with a table but I don't know how expensive those
 calls actually are. Not sure what would be the best solution here.

drm_get_driver_name() is quite expensive as it does two readlink syscalls,
so it should be called at most once per ioctl_decode().

Another method to achieve this is to change drm_get_driver_name() to return
basename(path) instead of return code, so that drm_ioctl() would call it
once and pass the result to strcmp calls:

int
drm_ioctl(struct tcb *tcp, const unsigned int code, long arg)
{
if (verbose(tcp)  drm_is_priv(code)) {
const char *driver = drm_get_driver_name(tcp);
if (!driver)
return 0;
if (!strcmp(driver, i915))
return drm_i915_ioctl(tcp, code, arg);
}
return 0;
}


-- 
ldv


pgpy4jMxtLaWP.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 3/4] drm: Add decoding of i915 ioctls

2015-06-09 Thread Dmitry V. Levin
On Tue, Jun 09, 2015 at 01:26:43PM +0200, Patrik Jakobsson wrote:
[...]
 +static int i915_getparam(struct tcb *tcp, const unsigned int code, long arg)
 +{
 + struct drm_i915_getparam param;
 + int value;
 +
 + if (entering(tcp) || umove(tcp, arg, param))
 + return 0;
 + if (umove(tcp, (long)param.value, value))
 + return 0;
 +
 + tprintf(, {param=);

We use tprints to print regular strings.

 +static int i915_setparam(struct tcb *tcp, const unsigned int code, long arg)
 +{
 + struct drm_i915_setparam param;
 +
 + if (exiting(tcp) || umove(tcp, arg, param))
 + return 0;

In this and other ioctl printers that unconditionally return 0 on exit,
wouldn't the caller treat it as an ioctl that hasn't been printed?


-- 
ldv


pgp5rnp2hAveW.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/4] drm: Add decoding of DRM and KMS ioctls

2015-06-09 Thread Dmitry V. Levin
On Tue, Jun 09, 2015 at 01:26:44PM +0200, Patrik Jakobsson wrote:
[...]
 +static int drm_version(struct tcb *tcp, const unsigned int code, long arg)
 +{
 + struct drm_version ver;
 + char *name, *date, *desc;
 + int ret;
 +
 + if (entering(tcp) || umove(tcp, arg, ver))
 + return 0;
 +
 + name = calloc(ver.name_len + 1, 1);
 + if (!name)
 + return 0;
 + ret = umovestr(tcp, (long)ver.name, ver.name_len, name);
 + if (ret  0)
 + goto free_name;

No need to allocate (arbitrary sized chunk of) memory just to fetch
a string that has to be printed.  There is a function called printstr()
to print such strings in a properly quoted form.


-- 
ldv


pgp0kBBLAKjpZ.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/4] drm: Add decoding of DRM and KMS ioctls

2015-06-09 Thread Dmitry V. Levin
On Tue, Jun 09, 2015 at 04:38:40PM +0200, Gabriel Laskar wrote:
 On Tue, 9 Jun 2015 16:29:31 +0200
 Patrik Jakobsson patrik.jakobs...@linux.intel.com wrote:
 
  On Tue, Jun 09, 2015 at 03:51:08PM +0200, Gabriel Laskar wrote:
   On Tue,  9 Jun 2015 13:26:44 +0200
   Patrik Jakobsson patrik.jakobs...@linux.intel.com wrote:
   
This patch adds many of the DRM and KMS ioctls. The rest can be added as
needed.

Signed-off-by: Patrik Jakobsson patrik.jakobs...@linux.intel.com
---
 drm.c | 519 
++
 1 file changed, 519 insertions(+)

diff --git a/drm.c b/drm.c
index fa98fb7..e550c34 100644
--- a/drm.c
+++ b/drm.c
@@ -82,6 +82,468 @@ int drm_is_driver(struct tcb *tcp, const char *name)
return strcmp(name, drv) == 0;
 }
 
+static int drm_version(struct tcb *tcp, const unsigned int code, long 
arg)
+{
+   struct drm_version ver;
+   char *name, *date, *desc;
+   int ret;
+
+   if (entering(tcp) || umove(tcp, arg, ver))
+   return 0;
+
+   name = calloc(ver.name_len + 1, 1);
   
   We have some wrappers for that now, you can call xcalloc(), but it will
   die if this does not work. Your version have the advantage of not kill
   strace, and just not decode the argument.
   
  
  If ok I'll keep it as calloc? As you say, dying here is not really 
  neccessary.
 
 Yeah, that was mostly me thinking out loud. Imho, I would keep the
 calloc(), but I don't know what Dmitry will prefer. Maybe for
 consistency, it should be better to have an xcalloc().

The general rule is to call xcalloc() if die_out_of_memory() is the best
way to handle the OOM condition.  strace should neither attempt to
allocate arbitrary large chunks of memory specified by user input
nor die when such allocation requests fail.


-- 
ldv


pgpT0lLEITVSL.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/4] drm: Add dispatcher and driver identification for DRM

2015-06-09 Thread Dmitry V. Levin
On Tue, Jun 09, 2015 at 01:26:42PM +0200, Patrik Jakobsson wrote:
[...]
 +static int drm_get_driver_name(struct tcb *tcp, char *name, size_t bufsize)
 +{
 + char path[PATH_MAX];
 + char link[PATH_MAX];
 + int ret;
 +
 + ret = getfdpath(tcp, tcp-u_arg[0], path, PATH_MAX - 1);
 + if (!ret)
 + return ret;

The return code of getfdpath() is essentially the return code of
readlink(), so the check should be the same as after readlink() below.

 +
 + snprintf(link, PATH_MAX, /sys/class/drm/%s/device/driver,
 +  basename(path));
 +
 + ret = readlink(link, path, PATH_MAX - 1);
 + if (ret  0)
 + return ret;
 +
 + path[ret] = '\0';
 + strncpy(name, basename(path), bufsize);
 +
 + return 0;
 +}

-- 
ldv


pgptJdMY46ej4.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/4] drm: Add dispatcher and driver identification for DRM

2015-06-09 Thread Dmitry V. Levin
On Tue, Jun 09, 2015 at 01:26:42PM +0200, Patrik Jakobsson wrote:
[...]
 --- a/Makefile.am
 +++ b/Makefile.am
 @@ -121,6 +121,7 @@ strace_SOURCES =  \
   utime.c \
   utimes.c\
   v4l2.c  \
 + drm.c   \
   vsprintf.c  \
   wait.c  \
   xattr.c

Starting with v4.7-166-g7ae73a9, we keep strace_SOURCES list sorted.

 --- /dev/null
 +++ b/drm.c
[...]
 +#include defs.h
 +
 +#include sys/types.h
 +#include unistd.h
 +#include string.h
 +#include linux/limits.h
 +#include stdint.h
 +#include sys/ioctl.h
 +#include linux/types.h
 +#include drm.h

No need to include header files already included by defs.h.
Most likely no need to include linux/limits.h or linux/types.h.

 +#define DRM_MAX_NAME_LEN 128
 +
 +inline int drm_is_priv(const unsigned int num)
 +{
 + return (_IOC_NR(num) = DRM_COMMAND_BASE 
 + _IOC_NR(num)  DRM_COMMAND_END);
 +}
 +
 +static int drm_get_driver_name(struct tcb *tcp, char *name, size_t bufsize)
 +{
 + char path[PATH_MAX];
 + char link[PATH_MAX];
 + int ret;
 +
 + ret = getfdpath(tcp, tcp-u_arg[0], path, PATH_MAX - 1);
 + if (!ret)
 + return ret;
 +
 + snprintf(link, PATH_MAX, /sys/class/drm/%s/device/driver,
 +  basename(path));
 +
 + ret = readlink(link, path, PATH_MAX - 1);
 + if (ret  0)
 + return ret;
 +
 + path[ret] = '\0';
 + strncpy(name, basename(path), bufsize);
 +
 + return 0;
 +}
 +
 +int drm_is_driver(struct tcb *tcp, const char *name)
 +{
 + char drv[DRM_MAX_NAME_LEN];
 + int ret;
 +
 + ret = drm_get_driver_name(tcp, drv, DRM_MAX_NAME_LEN);
 + if (ret)
 + return 0;
 +
 + return strcmp(name, drv) == 0;
 +}

This interface will result to several getfdpath() calls per
ioctl_decode().  If the only purpose of drm_is_driver() is to help finding
the most appropriate function, let's create a table of pairs
{driver name, function} and pass this table to a function that will do a
single getfdpath() call, calculate the driver name, and choose the right
function from the table.

[...]
 @@ -284,6 +294,7 @@ ioctl_decode(struct tcb *tcp, unsigned int code, long arg)
   *   d   sys/des.h   (possible overlap)
   *   d   vax/dkio.h  (possible overlap)
   *   d   vaxuba/rxreg.h  (possible overlap)
 + *   d  drm/drm.h
   *   f   sys/filio.h
   *   g   sunwindow/win_ioctl.h   -no overlap-
   *   g   sunwindowdev/winioctl.c !no manifest constant! -no 
 overlap-

This is a history, no need to patch it.


-- 
ldv


pgpR95kJajcmt.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [RFC 0/2] strace/drm: Add i915 ioctls to strace

2015-05-13 Thread Dmitry V. Levin
On Tue, May 12, 2015 at 07:37:59PM +0200, Gabriel Laskar wrote:
 On Tue, 12 May 2015 14:35:28 +0200, Patrik Jakobsson wrote:
  On Mon, May 11, 2015 at 08:08:19PM +0200, Gabriel Laskar wrote:
   On Mon, 11 May 2015 15:54:24 +0200, Patrik Jakobsson wrote:
On Mon, May 11, 2015 at 12:50:36PM +0200, Gabriel Laskar wrote:
 On Wed,  6 May 2015 16:48:01 +0200, Patrik Jakobsson wrote:
 
  This patch set aims to make strace more useful when tracing i915 
  ioctls.
  The ioctl type is first checked for being drm and then the driver
  backing the opened device is identified by looking at sysfs. Other
  drivers than i915 can easily be added.
  
  Only a subset of the i915 ioctls are included. I will extend this 
  patch
  set if the approach looks ok. The generic drm ioctls are also 
  missing.
  
  Give it a spin with:
  strace -e trace=ioctl -p `pidof X`
  
  Patrik Jakobsson (2):
strace/drm: Print extended info for drm and i915 ioctls
strace/drm: Print args for most common i915 ioctls
  
   Makefile.am|   2 +
   defs.h |   2 +
   drm.c  | 104 +
   drm_i915.c | 278 
  +
   ioctl.c|   5 +
   xlat/drm_i915_getparams.in |  28 +
   xlat/drm_i915_ioctls.in|  51 +
   xlat/drm_i915_setparams.in |   4 +
   8 files changed, 474 insertions(+)
   create mode 100644 drm.c
   create mode 100644 drm_i915.c
   create mode 100644 xlat/drm_i915_getparams.in
   create mode 100644 xlat/drm_i915_ioctls.in
   create mode 100644 xlat/drm_i915_setparams.in
  
 
 This is a great start! We need this kind of decoding. Do you plan to
 add also the generic drm ioctl decoding?

Thanks for the review. Yes, my plan is to add generic drm ioctls as 
well.

 
 Some issues though:
 
 * The way you avoid the ioctl request decoding is quite hard to 
 follow,
   but it seems that you don't have much of a choice, except that in
   drm_ioctl(), the code from SYS_FUNC(ioctl) is duplicated. It seems 
 it
   needs some work here, to allow a simpler code path. Maybe this would
   be clearer if the decoding/drm_get_driver_name, etc… was in
   ioctl_decode_command_number(). Also, with the actual code, if you 
 are
   on i915 with an invalid ioctl number, it will be printed as
   I915_IOCTL_??? and not _IOC(...) (see below for an example.) 
 This
   will also add an inconsistent result depending whether /sys is
   mounted or not.

Yes, moving it to ioctl_decode_command_number() makes sense. I'll do 
that.
And I'll make the output consistent and skip the I915_IOCTL_???. It 
comes with
the drawback of possibly duplicated entries when doing the lookup even 
though we
know we're talking to i915, but it is still nicer than _???.
   
   If you call all the request decoding code from
   ioctl_decode_command_number() you will still be able to determine if
   you are on i915, and write the correct request, but the fallback code
   will be no longer duplicated. You will have to call xlookup() instead of
   printxval(), in order to be able to know when the decoding fail though.
  
  Unfortunately I cannot check for i915 in _decode_command_number since I 
  don't
  have the full tcb context (cannot figure out the path, etc.). That's 
  probably
  why I had to duplicate the decoding in the first place. The only other 
  solution
  I see is to detect i915 early and store it globally somewhere but that is 
  rather
  nasty. Not sure how to do this in a better way. What am I missing?
 
 Oh yes, I see. We can add tcb context to ioctl_decode_command_number(),
 it should not be a problem. We didn't have the need for it for the
 moment, that's all.
 
 Dmitry? What do you think of this?

I had no chance to have a look at the code, but anyway, passing
tcb context down to ioctl_decode_command_number() shouldn't be a problem
at all.


-- 
ldv
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx