From mboxrd@z Thu Jan 1 00:00:00 1970 From: Patrik Jakobsson Subject: Re: [PATCH v2 5/5] drm: Add decoding of DRM and KMS ioctls Date: Tue, 30 Jun 2015 09:47:05 +0200 Message-ID: <20150630074705.GA12526@patrik-dev-mach> References: <1434616965-5157-1-git-send-email-patrik.jakobsson@linux.intel.com> <1434616965-5157-6-git-send-email-patrik.jakobsson@linux.intel.com> <20150629193500.6cbc3a35@guiness.lab.lse.epita.fr> Reply-To: strace development list Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Content-Disposition: inline In-Reply-To: <20150629193500.6cbc3a35-krIL5v34lyW+8jMViQwUxmazZaUMDOZU@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: strace-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org To: Gabriel Laskar Cc: intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org, ldv-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org, strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org List-Id: intel-gfx@lists.freedesktop.org On Mon, Jun 29, 2015 at 07:35:00PM +0200, Gabriel Laskar wrote: > On Thu, 18 Jun 2015 10:42:45 +0200 > Patrik Jakobsson wrote: > > > This patch adds many of the DRM and KMS ioctls. The rest can be added as > > needed. > > > > * drm.c: Decode DRM_IOCTL_VERSION > > * drm.c: Decode DRM_IOCTL_GET_UNIQUE > > * drm.c: Decode DRM_IOCTL_GET_MAGIC > > * drm.c: Decode DRM_IOCTL_WAIT_VBLANK > > * drm.c: Decode DRM_IOCTL_MODE_GETRESOURCES > > * drm.c: Decode DRM_IOCTL_MODE_GETCRTC > > * drm.c: Decode DRM_IOCTL_MODE_SETCRTC > > * drm.c: Decode DRM_IOCTL_MODE_CURSOR > > * drm.c: Decode DRM_IOCTL_MODE_CURSOR2 > > * drm.c: Decode DRM_IOCTL_MODE_GETGAMMA > > * drm.c: Decode DRM_IOCTL_MODE_SETGAMMA > > * drm.c: Decode DRM_IOCTL_MODE_GETENCODER > > * drm.c: Decode DRM_IOCTL_MODE_GETCONNECTOR > > * drm.c: Decode DRM_IOCTL_MODE_GETPROPERTY > > * drm.c: Decode DRM_IOCTL_MODE_SETPROPERTY > > * drm.c: Decode DRM_IOCTL_MODE_GETPROPBLOB > > * drm.c: Decode DRM_IOCTL_MODE_GETFB > > * drm.c: Decode DRM_IOCTL_MODE_ADDFB > > * drm.c: Decode DRM_IOCTL_MODE_RMFB > > * drm.c: Decode DRM_IOCTL_MODE_PAGE_FLIP > > * drm.c: Decode DRM_IOCTL_DIRTYFB > > * drm.c: Decode DRM_IOCTL_CREATE_DUMB > > * drm.c: Decode DRM_IOCTL_MAP_DUMB > > * drm.c: Decode DRM_IOCTL_DESTROY_DUMB > > * drm.c: Decode DRM_IOCTL_GEM_CLOSE > > > > Signed-off-by: Patrik Jakobsson > > --- > > drm.c | 510 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 510 insertions(+) > > > > diff --git a/drm.c b/drm.c > > index 8e3f7d1..2e6d763 100644 > > --- a/drm.c > > +++ b/drm.c > > @@ -104,6 +104,463 @@ int drm_decode_number(struct tcb *tcp, unsigned int arg) > > return 0; > > } > > > > +static int drm_version(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_version ver; > > + > > + if (umove(tcp, arg, &ver)) > > + return 0; > > + > > The umove() should be done only on exiting and if the ioctl succeded ? > > Same thing for most of the read only ioctl. > Yes, that could be moved into exiting. Will fix for all "single phase" ioctls. > > + if (exiting(tcp)) { > > + tprintf(", {version_major=%d, version_minor=%d, version_patchlevel=%d, " > > + "name_len=%lu, name=", ver.version_major, > > + ver.version_minor, ver.version_patchlevel, > > + ver.name_len); > > + printstr(tcp, (long)ver.name, ver.name_len); > > + tprintf(", date_len=%lu, date=", ver.date_len); > > + printstr(tcp, (long)ver.date, ver.date_len); > > + tprintf(", desc_len=%lu, desc=", ver.desc_len); > > + printstr(tcp, (long)ver.desc, ver.desc_len); > > + tprints("}"); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_get_unique(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_unique unique; > > + > > + if (umove(tcp, arg, &unique)) > > + return 0; > > + > > + if (exiting(tcp)) { > > + tprintf(", {unique_len=%lu, unique=}", unique.unique_len); > > There is an extra '}' > Oops > > + printstr(tcp, (long)unique.unique, unique.unique_len); > > + tprints("}"); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_get_magic(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_auth auth; > > + > > + if (umove(tcp, arg, &auth)) > > + return 0; > > + > > + if (exiting(tcp)) > > + tprintf(", {magic=%u}", auth.magic); > > + > > + return 1; > > +} > > + > > +static int drm_wait_vblank(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + union drm_wait_vblank vblank; > > + > > + if (umove(tcp, arg, &vblank)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {request={type=%u, sequence=%u, signal=%lu}", > > + vblank.request.type, vblank.request.sequence, > > + vblank.request.signal); > > + } else if (exiting(tcp)) { > > + tprintf(", reply={type=%u, sequence=%u, tval_sec=%ld, tval_usec=%ld}}", > > + vblank.reply.type, vblank.reply.sequence, > > + vblank.reply.tval_sec, vblank.reply.tval_usec); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_resources(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_card_res res; > > + > > + if (umove(tcp, arg, &res)) > > + return 0; > > + > > + if (exiting(tcp)) { > > + tprintf(", {fb_id_ptr=%p, crtc_id_ptr=%p, connector_id_ptr=%p, " > > + "encoder_id_ptr=%p, count_fbs=%u, count_crtcs=%u, " > > + "count_connectors=%u, count_encoders=%u, min_width=%u, " > > + "max_width=%u, min_height=%u, max_height=%u}", > > + (void *)res.fb_id_ptr, (void *)res.crtc_id_ptr, > > + (void *)res.connector_id_ptr, (void *)res.encoder_id_ptr, > > + res.count_fbs, res.count_crtcs, res.count_connectors, > > + res.count_encoders, res.min_width, res.max_width, > > + res.min_height, res.max_height); > > + } > > + > > + return 1; > > +} > > + > > +static void drm_mode_print_modeinfo(struct drm_mode_modeinfo *info) > > +{ > > + tprintf("clock=%u, hdisplay=%hu, hsync_start=%hu, hsync_end=%hu, " > > + "htotal=%hu, hskew=%hu, vdisplay=%hu, vsync_start=%hu, " > > + "vsync_end=%hu, vtotal=%hu, vscan=%hu, vrefresh=%u, " > > + "flags=0x%x, type=%u, name=%s", info->clock, info->hdisplay, > > + info->hsync_start, info->hsync_end, info->htotal, info->hskew, > > + info->vdisplay, info->vsync_start, info->vsync_end, > > + info->vtotal, info->vscan, info->vrefresh, info->flags, > > + info->type, info->name); > > +} > > + > > +static int drm_mode_get_crtc(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_crtc crtc; > > + > > + if (umove(tcp, arg, &crtc)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {crtc_id=%u", crtc.crtc_id); > > + } else if (exiting(tcp)) { > > + tprintf(", set_connectors_ptr=%p, count_connectors=%u, " > > + "fb_id=%u, x=%u, y=%u, gamma_size=%u, mode_valid=%u, " > > + "mode={", (void *)crtc.set_connectors_ptr, > > + crtc.count_connectors, crtc.fb_id, crtc.x, crtc.y, > > + crtc.gamma_size, crtc.mode_valid); > > + > > + drm_mode_print_modeinfo(&crtc.mode); > > + tprintf("}}"); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_set_crtc(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_crtc crtc; > > + > > + if (umove(tcp, arg, &crtc)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {set_connectors_ptr=%p, count_connectors=%u, " > > + "crtc_id=%u, fb_id=%u, x=%u, y=%u, gamma_size=%u, " > > + "mode_valid=%u, mode={", (void *)crtc.set_connectors_ptr, > > + crtc.count_connectors, crtc.crtc_id, crtc.fb_id, crtc.x, > > + crtc.y, crtc.gamma_size, crtc.mode_valid); > > + > > + drm_mode_print_modeinfo(&crtc.mode); > > + tprintf("}}"); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_cursor(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_cursor cursor; > > + > > + if (umove(tcp, arg, &cursor)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {flags=0x%x, crtc_id=%u, x=%d, y=%d, width=%u, " > > + "height=%u, handle=%u}", cursor.flags, cursor.crtc_id, > > + cursor.x, cursor.y, cursor.width, cursor.height, > > + cursor.handle); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_cursor2(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_cursor2 cursor; > > + > > + if (umove(tcp, arg, &cursor)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {flags=0x%x, crtc_id=%u, x=%d, y=%d, width=%u, " > > + "height=%u, handle=%u, hot_x=%d, hot_y=%d}", > > + cursor.flags, cursor.crtc_id, cursor.x, cursor.y, > > + cursor.width, cursor.height, cursor.handle, > > + cursor.hot_x, cursor.hot_y); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_gamma(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_crtc_lut lut; > > + > > + if (umove(tcp, arg, &lut)) > > + return 0; > > + > > + if (entering(tcp)) { > > + /* We don't print the entire table, just the pointers */ > > + tprintf(", {crtc_id=%u, gamma_size=%u, red=%p, green=%p, " > > + "blue=%p}", lut.crtc_id, lut.gamma_size, > > + (void *)lut.red, (void *)lut.green, (void *)lut.blue); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_set_gamma(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_crtc_lut lut; > > + > > + if (umove(tcp, arg, &lut)) > > + return 0; > > + > > + if (entering(tcp)) { > > + /* We don't print the entire table, just the rgb pointers */ > > + tprintf(", {crtc_id=%u, gamma_size=%u, red=%p, green=%p, " > > + "blue=%p}", lut.crtc_id, lut.gamma_size, > > + (void *)lut.red, (void *)lut.green, (void *)lut.blue); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_encoder(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_get_encoder enc; > > + > > + if (umove(tcp, arg, &enc)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {encoder_id=%u", enc.encoder_id); > > + } else if (exiting(tcp)) { > > + /* TODO: Print name of encoder type */ > > + tprintf(", encoder_type=%u, crtc_id=%u, possible_crtcs=0x%x, " > > + "possible_clones=0x%x}", enc.encoder_type, > > + enc.crtc_id, enc.possible_crtcs, enc.possible_clones); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_connector(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_get_connector con; > > + > > + if (umove(tcp, arg, &con)) > > + return 0; > > + > > + /* We could be very verbose here but keep is simple for now */ > > + if (entering(tcp)) { > > + tprintf(", {connector_id=%u", con.connector_id); > > + } else if (exiting(tcp)) { > > + tprintf(", encoders_ptr=%p, modes_ptr=%p, props_ptr=%p, " > > + "prop_values_ptr=%p, count_modes=%u, count_props=%u, " > > + "count_encoders=%u, encoder_id=%u, connector_type=%u, " > > + "connector_type_id=%u, connection=%u, mm_width=%u, " > > + "mm_height=%u, subpixel=%u}", (void *)con.encoders_ptr, > > + (void *)con.modes_ptr, (void *)con.props_ptr, > > + (void *)con.prop_values_ptr, con.count_modes, > > + con.count_props, con.count_encoders, con.encoder_id, > > + con.connector_type, con.connector_type_id, > > + con.connection, con.mm_width, con.mm_height, > > + con.subpixel); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_property(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_get_property prop; > > + > > + if (umove(tcp, arg, &prop)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {prop_id=%u", prop.prop_id); > > + } else if (exiting(tcp)) { > > + tprintf(", values_ptr=%p, enum_blob_ptr=%p, flags=0x%x, " > > + "name=%s, count_values=%u, count_enum_blobs=%u}", > > + (void *)prop.values_ptr, (void *)prop.enum_blob_ptr, > > + prop.flags, prop.name, prop.count_values, > > + prop.count_enum_blobs); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_set_property(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_connector_set_property prop; > > + > > + if (umove(tcp, arg, &prop)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {value=%Lu, prop_id=%u, connector_id=%u}", > > + prop.value, prop.prop_id, prop.connector_id); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_prop_blob(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_get_blob blob; > > + > > + if (umove(tcp, arg, &blob)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {blob_id=%u", blob.blob_id); > > + } else if (exiting(tcp)) { > > + tprintf(", length=%u, data=%p}", blob.length, > > + (void *)blob.data); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_add_fb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_fb_cmd cmd; > > + > > + if (umove(tcp, arg, &cmd)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {width=%u, height=%u, pitch=%u, bpp=%u, depth=%u, " > > + "handle=%u", cmd.width, cmd.height, cmd.pitch, > > + cmd.bpp, cmd.depth, cmd.handle); > > + } else if (exiting(tcp)) { > > + tprintf(", fb_id=%u}", cmd.fb_id); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_fb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_fb_cmd cmd; > > + > > + if (umove(tcp, arg, &cmd)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {fb_id=%u", cmd.fb_id); > > + } else { > > + tprintf(", width=%u, height=%u, pitch=%u, bpp=%u, depth=%u, " > > + "handle=%u}", cmd.width, cmd.height, cmd.pitch, > > + cmd.bpp, cmd.depth, cmd.handle); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_rm_fb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + unsigned int handle; > > + > > + if (umove(tcp, arg, &handle)) > > + return 0; > > + > > + if (entering(tcp)) > > + tprintf(", %u", handle); > > + > > + return 1; > > +} > > + > > +static int drm_mode_page_flip(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_crtc_page_flip flip; > > + > > + if (umove(tcp, arg, &flip)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {crtc_id=%u, fb_id=%u, flags=0x%x, user_data=0x%Lx}", > > + flip.crtc_id, flip.fb_id, flip.flags, flip.user_data); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_dirty_fb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_fb_dirty_cmd cmd; > > + > > + if (umove(tcp, arg, &cmd)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {fb_id=%u, flags=0x%x, color=0x%x, num_clips=%u, " > > + "clips_ptr=%p}", cmd.fb_id, cmd.flags, cmd.color, > > + cmd.num_clips, (void *)cmd.clips_ptr); > > + } > > + > > + return 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, &dumb)) > > + return 0; > > + > > + 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 1; > > +} > > + > > +static int drm_mode_map_dumb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_map_dumb dumb; > > + > > + if (umove(tcp, arg, &dumb)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {handle=%u", dumb.handle); > > + } else if (exiting(tcp)) { > > + tprintf(", offset=%Lu}", dumb.offset); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_destroy_dumb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_destroy_dumb dumb; > > + > > + if (umove(tcp, arg, &dumb)) > > + return 0; > > + > > + if (entering(tcp)) > > + tprintf(", {handle=%u}", dumb.handle); > > + > > + return 1; > > +} > > + > > +static int drm_gem_close(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_gem_close close; > > + > > + if (umove(tcp, arg, &close)) > > + return 0; > > + > > + if (entering(tcp)) > > + tprintf(", {handle=%u}", close.handle); > > + > > + return 1; > > +} > > + > > int drm_ioctl(struct tcb *tcp, const unsigned int code, long arg) > > { > > /* Check for device specific ioctls */ > > @@ -112,6 +569,59 @@ int drm_ioctl(struct tcb *tcp, const unsigned int code, long arg) > > return drm_i915_ioctl(tcp, code, arg); > > } > > > > + switch (code) { > > + case DRM_IOCTL_VERSION: > > + return drm_version(tcp, code, arg); > > + case DRM_IOCTL_GET_UNIQUE: > > + return drm_get_unique(tcp, code, arg); > > + case DRM_IOCTL_GET_MAGIC: > > + return drm_get_magic(tcp, code, arg); > > + case DRM_IOCTL_WAIT_VBLANK: > > + return drm_wait_vblank(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETRESOURCES: > > + return drm_mode_get_resources(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETCRTC: > > + return drm_mode_get_crtc(tcp, code, arg); > > + case DRM_IOCTL_MODE_SETCRTC: > > + return drm_mode_set_crtc(tcp, code, arg); > > + case DRM_IOCTL_MODE_CURSOR: > > + return drm_mode_cursor(tcp, code, arg); > > + case DRM_IOCTL_MODE_CURSOR2: > > + return drm_mode_cursor2(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETGAMMA: > > + return drm_mode_get_gamma(tcp, code, arg); > > + case DRM_IOCTL_MODE_SETGAMMA: > > + return drm_mode_set_gamma(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETENCODER: > > + return drm_mode_get_encoder(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETCONNECTOR: > > + return drm_mode_get_connector(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETPROPERTY: > > + return drm_mode_get_property(tcp, code, arg); > > + case DRM_IOCTL_MODE_SETPROPERTY: > > + return drm_mode_set_property(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETPROPBLOB: > > + return drm_mode_get_prop_blob(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETFB: > > + return drm_mode_get_fb(tcp, code, arg); > > + case DRM_IOCTL_MODE_ADDFB: > > + return drm_mode_add_fb(tcp, code, arg); > > + case DRM_IOCTL_MODE_RMFB: > > + return drm_mode_rm_fb(tcp, code, arg); > > + case DRM_IOCTL_MODE_PAGE_FLIP: > > + return drm_mode_page_flip(tcp, code, arg); > > + case DRM_IOCTL_MODE_DIRTYFB: > > + return drm_mode_dirty_fb(tcp, code, arg); > > + case DRM_IOCTL_MODE_CREATE_DUMB: > > + return drm_mode_create_dumb(tcp, code, arg); > > + case DRM_IOCTL_MODE_MAP_DUMB: > > + return drm_mode_map_dumb(tcp, code, arg); > > + case DRM_IOCTL_MODE_DESTROY_DUMB: > > + return drm_mode_destroy_dumb(tcp, code, arg); > > + case DRM_IOCTL_GEM_CLOSE: > > + return drm_gem_close(tcp, code, arg); > > + } > > + > > /* Free any allocated private data */ > > if (exiting(tcp) && tcp->priv_data != NULL) { > > free(tcp->priv_data); > > > > -- > Gabriel Laskar ------------------------------------------------------------------------------ Don't Limit Your Business. Reach for the Cloud. GigeNET's Cloud Solutions provide you with the tools and support that you need to offload your IT needs and focus on growing your business. Configured For All Businesses. Start Your Cloud Today. https://www.gigenetcloud.com/