diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2018-09-28 21:04:00 +0300 |
---|---|---|
committer | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2018-12-11 00:37:53 +0300 |
commit | cb8ce7111117e16a87f3f55c014ccd1f19f81016 (patch) | |
tree | 234918241b8b45bda9e9250927698e47ba8c0063 /drivers/gpu/drm/drm_dp_mst_topology.c | |
parent | c978ae9bde582e82a04c63a4071701691dd8b35c (diff) | |
download | linux-cb8ce7111117e16a87f3f55c014ccd1f19f81016.tar.xz |
drm/dp/mst: Validate REMOTE_I2C_READ harder
Make sure i2c msgs we're asked to transfer conform to the
requirements of REMOTE_I2C_READ. We were only checking that the
last message is a read, but we must also check that the preceding
messages are all writes. Also check that the length of each
message isn't too long.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180928180403.22499-2-ville.syrjala@linux.intel.com
Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Diffstat (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c')
-rw-r--r-- | drivers/gpu/drm/drm_dp_mst_topology.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 229ad6026314..f0cbd5fad8fc 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3250,6 +3250,23 @@ void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr) } EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy); +static bool remote_i2c_read_ok(const struct i2c_msg msgs[], int num) +{ + int i; + + if (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS) + return false; + + for (i = 0; i < num - 1; i++) { + if (msgs[i].flags & I2C_M_RD || + msgs[i].len > 0xff) + return false; + } + + return msgs[num - 1].flags & I2C_M_RD && + msgs[num - 1].len <= 0xff; +} + /* I2C device */ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) @@ -3259,7 +3276,6 @@ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs struct drm_dp_mst_branch *mstb; struct drm_dp_mst_topology_mgr *mgr = port->mgr; unsigned int i; - bool reading = false; struct drm_dp_sideband_msg_req_body msg; struct drm_dp_sideband_msg_tx *txmsg = NULL; int ret; @@ -3268,12 +3284,7 @@ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs if (!mstb) return -EREMOTEIO; - /* construct i2c msg */ - /* see if last msg is a read */ - if (msgs[num - 1].flags & I2C_M_RD) - reading = true; - - if (!reading || (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS)) { + if (!remote_i2c_read_ok(msgs, num)) { DRM_DEBUG_KMS("Unsupported I2C transaction for MST device\n"); ret = -EIO; goto out; |