All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Zhigang Gong" <zhigang.gong@linux.intel.com>
To: 'Francisco Jerez' <currojerez@riseup.net>,
	intel-gfx@lists.freedesktop.org
Cc: 'Brad Volkin' <bradley.d.volkin@intel.com>
Subject: Re: [PATCH 1/3] drm/i915: Fix command parser to validate multiple register access with the same command.
Date: Tue, 2 Jun 2015 17:36:26 +0800	[thread overview]
Message-ID: <000901d09d17$99c5f380$cd51da80$@linux.intel.com> (raw)
In-Reply-To: <1432907055-8268-1-git-send-email-currojerez@riseup.net>

The patchset LGTM and works well with beignet. The 80%+ performance regression issue in darktable also has been fixed
after this patchset applied and enable the atomic in L3 at beignet side. So,

Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>

Thanks,
Zhigang Gong.

> -----Original Message-----
> From: Francisco Jerez [mailto:currojerez@riseup.net]
> Sent: Friday, May 29, 2015 9:44 PM
> To: intel-gfx@lists.freedesktop.org
> Cc: Ville Syrjälä; Zhigang Gong; Brad Volkin
> Subject: [PATCH 1/3] drm/i915: Fix command parser to validate multiple
> register access with the same command.
> 
> Until now the software command checker assumed that commands could read
> or write at most a single register per packet.  This is not necessarily the case,
> MI_LOAD_REGISTER_IMM expects a variable-length list of offset/value pairs
> and writes them in sequence.  The previous code would only check whether
> the first entry was valid, effectively allowing userspace to write unrestricted
> registers of the MMIO space by sending a multi-register write with a legal first
> register, with potential security implications on Gen6 and 7 hardware.
> 
> Fix it by extending the drm_i915_cmd_descriptor table to represent
> multi-register access and making validate_cmd() iterate for all register offsets
> present in the command packet.
> 
> Signed-off-by: Francisco Jerez <currojerez@riseup.net>
> ---
>  drivers/gpu/drm/i915/i915_cmd_parser.c | 74
> ++++++++++++++++++++--------------
>  drivers/gpu/drm/i915/i915_drv.h        |  5 +++
>  2 files changed, 48 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c
> b/drivers/gpu/drm/i915/i915_cmd_parser.c
> index 61ae8ff..c4a5f73 100644
> --- a/drivers/gpu/drm/i915/i915_cmd_parser.c
> +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
> @@ -123,7 +123,7 @@ static const struct drm_i915_cmd_descriptor
> common_cmds[] = {
>  	CMD(  MI_SEMAPHORE_MBOX,                SMI,   !F,  0xFF,
> R  ),
>  	CMD(  MI_STORE_DWORD_INDEX,             SMI,   !F,  0xFF,
> R  ),
>  	CMD(  MI_LOAD_REGISTER_IMM(1),          SMI,   !F,  0xFF,
> W,
> -	      .reg = { .offset = 1, .mask = 0x007FFFFC }               ),
> +	      .reg = { .offset = 1, .mask = 0x007FFFFC, .step = 2 }    ),
>  	CMD(  MI_STORE_REGISTER_MEM(1),         SMI,   !F,  0xFF,
> W | B,
>  	      .reg = { .offset = 1, .mask = 0x007FFFFC },
>  	      .bits = {{
> @@ -939,7 +939,7 @@ bool i915_needs_cmd_parser(struct intel_engine_cs
> *ring)
> 
>  static bool check_cmd(const struct intel_engine_cs *ring,
>  		      const struct drm_i915_cmd_descriptor *desc,
> -		      const u32 *cmd,
> +		      const u32 *cmd, u32 length,
>  		      const bool is_master,
>  		      bool *oacontrol_set)
>  {
> @@ -955,38 +955,49 @@ static bool check_cmd(const struct intel_engine_cs
> *ring,
>  	}
> 
>  	if (desc->flags & CMD_DESC_REGISTER) {
> -		u32 reg_addr = cmd[desc->reg.offset] & desc->reg.mask;
> -
>  		/*
> -		 * OACONTROL requires some special handling for writes. We
> -		 * want to make sure that any batch which enables OA also
> -		 * disables it before the end of the batch. The goal is to
> -		 * prevent one process from snooping on the perf data from
> -		 * another process. To do that, we need to check the value
> -		 * that will be written to the register. Hence, limit
> -		 * OACONTROL writes to only MI_LOAD_REGISTER_IMM
> commands.
> +		 * Get the distance between individual register offset
> +		 * fields if the command can perform more than one
> +		 * access at a time.
>  		 */
> -		if (reg_addr == OACONTROL) {
> -			if (desc->cmd.value == MI_LOAD_REGISTER_MEM) {
> -				DRM_DEBUG_DRIVER("CMD: Rejected LRM to
> OACONTROL\n");
> -				return false;
> +		const u32 step = desc->reg.step ? desc->reg.step : length;
> +		u32 offset;
> +
> +		for (offset = desc->reg.offset; offset < length;
> +		     offset += step) {
> +			const u32 reg_addr = cmd[offset] & desc->reg.mask;
> +
> +			/*
> +			 * OACONTROL requires some special handling for
> +			 * writes. We want to make sure that any batch which
> +			 * enables OA also disables it before the end of the
> +			 * batch. The goal is to prevent one process from
> +			 * snooping on the perf data from another process. To do
> +			 * that, we need to check the value that will be written
> +			 * to the register. Hence, limit OACONTROL writes to
> +			 * only MI_LOAD_REGISTER_IMM commands.
> +			 */
> +			if (reg_addr == OACONTROL) {
> +				if (desc->cmd.value == MI_LOAD_REGISTER_MEM) {
> +					DRM_DEBUG_DRIVER("CMD: Rejected LRM to
> OACONTROL\n");
> +					return false;
> +				}
> +
> +				if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1))
> +					*oacontrol_set = (cmd[offset + 1] != 0);
>  			}
> 
> -			if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1))
> -				*oacontrol_set = (cmd[2] != 0);
> -		}
> -
> -		if (!valid_reg(ring->reg_table,
> -			       ring->reg_count, reg_addr)) {
> -			if (!is_master ||
> -			    !valid_reg(ring->master_reg_table,
> -				       ring->master_reg_count,
> -				       reg_addr)) {
> -				DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in
> command: 0x%08X (ring=%d)\n",
> -						 reg_addr,
> -						 *cmd,
> -						 ring->id);
> -				return false;
> +			if (!valid_reg(ring->reg_table,
> +				       ring->reg_count, reg_addr)) {
> +				if (!is_master ||
> +				    !valid_reg(ring->master_reg_table,
> +					       ring->master_reg_count,
> +					       reg_addr)) {
> +					DRM_DEBUG_DRIVER("CMD: Rejected register
> 0x%08X in command: 0x%08X (ring=%d)\n",
> +							 reg_addr, *cmd,
> +							 ring->id);
> +					return false;
> +				}
>  			}
>  		}
>  	}
> @@ -1110,7 +1121,8 @@ int i915_parse_cmds(struct intel_engine_cs *ring,
>  			break;
>  		}
> 
> -		if (!check_cmd(ring, desc, cmd, is_master, &oacontrol_set)) {
> +		if (!check_cmd(ring, desc, cmd, length, is_master,
> +			       &oacontrol_set)) {
>  			ret = -EINVAL;
>  			break;
>  		}
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 8ae6f7f..3850288 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2228,10 +2228,15 @@ struct drm_i915_cmd_descriptor {
>  	 * Describes where to find a register address in the command to check
>  	 * against the ring's register whitelist. Only valid if flags has the
>  	 * CMD_DESC_REGISTER bit set.
> +	 *
> +	 * A non-zero step value implies that the command may access multiple
> +	 * registers in sequence (e.g. LRI), in that case step gives the
> +	 * distance in dwords between individual offset fields.
>  	 */
>  	struct {
>  		u32 offset;
>  		u32 mask;
> +		u32 step;
>  	} reg;
> 
>  #define MAX_CMD_DESC_BITMASKS 3
> --
> 2.3.5

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

  parent reply	other threads:[~2015-06-02  9:36 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-29 13:44 [PATCH 1/3] drm/i915: Fix command parser to validate multiple register access with the same command Francisco Jerez
2015-05-29 13:44 ` [PATCH 2/3] drm/i915: Extend the parser to check register writes against a mask/value pair Francisco Jerez
2015-05-29 13:44 ` [PATCH 3/3] drm/i915: Add SCRATCH1 and ROW_CHICKEN3 to the register whitelist Francisco Jerez
2015-06-02  9:36 ` Zhigang Gong [this message]
2015-06-02 11:02   ` [PATCH 1/3] drm/i915: Fix command parser to validate multiple register access with the same command Francisco Jerez
2015-06-15 10:35   ` Daniel Vetter
2015-06-15 11:18     ` Francisco Jerez
2015-06-15 11:26       ` Ville Syrjälä
2015-06-15 11:40         ` Daniel Vetter
2015-06-15 12:05           ` Francisco Jerez
2015-08-30 22:19             ` Francisco Jerez
2015-09-01  9:41               ` Daniel Vetter
2015-06-15 13:15           ` Jani Nikula

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='000901d09d17$99c5f380$cd51da80$@linux.intel.com' \
    --to=zhigang.gong@linux.intel.com \
    --cc=bradley.d.volkin@intel.com \
    --cc=currojerez@riseup.net \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.