lkml.org 
[lkml]   [2015]   [Sep]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.19.y-ckt 053/102] drm/dp/mst: Remove port after removing connector.
    Date
    3.19.8-ckt7 -stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

    commit 4772ff03df8094fd99d28de5fcf5df3a3e9c68bb upstream.

    The port is removed synchronously, but the connector delayed.
    This causes a use after free which can cause a kernel BUG with
    slug_debug=FPZU. This is fixed by freeing the port after the
    connector.

    This fixes a regression introduced with
    6b8eeca65b18ae77e175cc2b6571731f0ee413bf
    "drm/dp/mst: close deadlock in connector destruction."

    Cc: Dave Airlie <airlied@redhat.com>
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
    Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
    Signed-off-by: Jani Nikula <jani.nikula@intel.com>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    drivers/gpu/drm/drm_dp_mst_topology.c | 19 +++++++++++++------
    include/drm/drm_crtc.h | 2 --
    2 files changed, 13 insertions(+), 8 deletions(-)

    diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
    index 8239563..6c0a1b0 100644
    --- a/drivers/gpu/drm/drm_dp_mst_topology.c
    +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
    @@ -869,9 +869,10 @@ static void drm_dp_destroy_port(struct kref *kref)
    from an EDID retrieval */
    if (port->connector) {
    mutex_lock(&mgr->destroy_connector_lock);
    - list_add(&port->connector->destroy_list, &mgr->destroy_connector_list);
    + list_add(&port->next, &mgr->destroy_connector_list);
    mutex_unlock(&mgr->destroy_connector_lock);
    schedule_work(&mgr->destroy_connector_work);
    + return;
    }
    drm_dp_port_teardown_pdt(port, port->pdt);

    @@ -2641,7 +2642,7 @@ static void drm_dp_tx_work(struct work_struct *work)
    static void drm_dp_destroy_connector_work(struct work_struct *work)
    {
    struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, destroy_connector_work);
    - struct drm_connector *connector;
    + struct drm_dp_mst_port *port;

    /*
    * Not a regular list traverse as we have to drop the destroy
    @@ -2650,15 +2651,21 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
    */
    for (;;) {
    mutex_lock(&mgr->destroy_connector_lock);
    - connector = list_first_entry_or_null(&mgr->destroy_connector_list, struct drm_connector, destroy_list);
    - if (!connector) {
    + port = list_first_entry_or_null(&mgr->destroy_connector_list, struct drm_dp_mst_port, next);
    + if (!port) {
    mutex_unlock(&mgr->destroy_connector_lock);
    break;
    }
    - list_del(&connector->destroy_list);
    + list_del(&port->next);
    mutex_unlock(&mgr->destroy_connector_lock);

    - mgr->cbs->destroy_connector(mgr, connector);
    + mgr->cbs->destroy_connector(mgr, port->connector);
    +
    + drm_dp_port_teardown_pdt(port, port->pdt);
    +
    + if (!port->input && port->vcpi.vcpi > 0)
    + drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
    + kfree(port);
    }
    }

    diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
    index 3dab77c..b863298 100644
    --- a/include/drm/drm_crtc.h
    +++ b/include/drm/drm_crtc.h
    @@ -689,8 +689,6 @@ struct drm_connector {
    uint8_t num_h_tile, num_v_tile;
    uint8_t tile_h_loc, tile_v_loc;
    uint16_t tile_h_size, tile_v_size;
    -
    - struct list_head destroy_list;
    };

    /**
    --
    1.9.1


    \
     
     \ /
      Last update: 2015-09-22 20:41    [W:4.063 / U:0.080 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site