Connector states were being allocated in intel_setup_outputs() in a loop
over all connectors. That meant hot-added connectors would have a NULL
state. Since the change to use a struct drm_atomic_state for the legacy
modeset, connector states are necessary for the i915 driver to function
properly, so that would lead to oopses.

Signed-off-by: Ander Conselvan de Oliveira 
<ander.conselvan.de.olive...@intel.com>
---

Hi Nicolas,

Could you please test if this patch solves the issue?

Thanks,
Ander



 drivers/gpu/drm/i915/intel_crt.c     |  2 +-
 drivers/gpu/drm/i915/intel_ddi.c     |  4 +--
 drivers/gpu/drm/i915/intel_display.c | 62 ++++++++++++++++--------------------
 drivers/gpu/drm/i915/intel_dp.c      |  2 +-
 drivers/gpu/drm/i915/intel_dp_mst.c  |  2 +-
 drivers/gpu/drm/i915/intel_drv.h     |  2 ++
 drivers/gpu/drm/i915/intel_dsi.c     |  2 +-
 drivers/gpu/drm/i915/intel_dvo.c     |  2 +-
 drivers/gpu/drm/i915/intel_hdmi.c    |  2 +-
 drivers/gpu/drm/i915/intel_lvds.c    |  6 ++++
 drivers/gpu/drm/i915/intel_sdvo.c    | 22 +++++++++++--
 drivers/gpu/drm/i915/intel_tv.c      |  2 +-
 12 files changed, 64 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index fa5699c..93bb515 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -851,7 +851,7 @@ void intel_crt_init(struct drm_device *dev)
        if (!crt)
                return;
 
-       intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+       intel_connector = intel_connector_alloc();
        if (!intel_connector) {
                kfree(crt);
                return;
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index db35194..2e005e3 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2102,7 +2102,7 @@ intel_ddi_init_dp_connector(struct intel_digital_port 
*intel_dig_port)
        struct intel_connector *connector;
        enum port port = intel_dig_port->port;
 
-       connector = kzalloc(sizeof(*connector), GFP_KERNEL);
+       connector = intel_connector_alloc();
        if (!connector)
                return NULL;
 
@@ -2121,7 +2121,7 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port 
*intel_dig_port)
        struct intel_connector *connector;
        enum port port = intel_dig_port->port;
 
-       connector = kzalloc(sizeof(*connector), GFP_KERNEL);
+       connector = intel_connector_alloc();
        if (!connector)
                return NULL;
 
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 739f61f..afff86f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5666,6 +5666,34 @@ static void intel_connector_check_state(struct 
intel_connector *connector)
        }
 }
 
+int intel_connector_init(struct intel_connector *connector)
+{
+       struct drm_connector_state *connector_state;
+
+       connector_state = kzalloc(sizeof *connector_state, GFP_KERNEL);
+       if (!connector_state)
+               return -ENOMEM;
+
+       connector->base.state = connector_state;
+       return 0;
+}
+
+struct intel_connector *intel_connector_alloc(void)
+{
+       struct intel_connector *connector;
+
+       connector = kzalloc(sizeof *connector, GFP_KERNEL);
+       if (!connector)
+               return NULL;
+
+       if (intel_connector_init(connector) < 0) {
+               kfree(connector);
+               return NULL;
+       }
+
+       return connector;
+}
+
 /* Even simpler default implementation, if there's really no special case to
  * consider. */
 void intel_connector_dpms(struct drm_connector *connector, int mode)
@@ -13089,7 +13117,6 @@ static void intel_setup_outputs(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_encoder *encoder;
-       struct drm_connector *connector;
        bool dpd_is_edp = false;
 
        intel_lvds_init(dev);
@@ -13225,39 +13252,6 @@ static void intel_setup_outputs(struct drm_device *dev)
        if (SUPPORTS_TV(dev))
                intel_tv_init(dev);
 
-       /*
-        * FIXME:  We don't have full atomic support yet, but we want to be
-        * able to enable/test plane updates via the atomic interface in the
-        * meantime.  However as soon as we flip DRIVER_ATOMIC on, the DRM core
-        * will take some atomic codepaths to lookup properties during
-        * drmModeGetConnector() that unconditionally dereference
-        * connector->state.
-        *
-        * We create a dummy connector state here for each connector to ensure
-        * the DRM core doesn't try to dereference a NULL connector->state.
-        * The actual connector properties will never be updated or contain
-        * useful information, but since we're doing this specifically for
-        * testing/debug of the plane operations (and only when a specific
-        * kernel module option is given), that shouldn't really matter.
-        *
-        * We are also relying on these states to convert the legacy mode set
-        * to use a drm_atomic_state struct. The states are kept consistent
-        * with actual state, so that it is safe to rely on that instead of
-        * the staged config.
-        *
-        * Once atomic support for crtc's + connectors lands, this loop should
-        * be removed since we'll be setting up real connector state, which
-        * will contain Intel-specific properties.
-        */
-       list_for_each_entry(connector,
-                           &dev->mode_config.connector_list,
-                           head) {
-               if (!WARN_ON(connector->state)) {
-                       connector->state = kzalloc(sizeof(*connector->state),
-                                                  GFP_KERNEL);
-               }
-       }
-
        intel_psr_init(dev);
 
        for_each_intel_encoder(dev, encoder) {
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 1b87969..589cd92 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5602,7 +5602,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, 
enum port port)
        if (!intel_dig_port)
                return;
 
-       intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+       intel_connector = intel_connector_alloc();
        if (!intel_connector) {
                kfree(intel_dig_port);
                return;
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c 
b/drivers/gpu/drm/i915/intel_dp_mst.c
index e682015..5561eca 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -413,7 +413,7 @@ static struct drm_connector 
*intel_dp_add_mst_connector(struct drm_dp_mst_topolo
        struct drm_connector *connector;
        int i;
 
-       intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+       intel_connector = intel_connector_alloc();
        if (!intel_connector)
                return NULL;
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 686014b..e07dc4a 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -928,6 +928,8 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc);
 void intel_crtc_control(struct drm_crtc *crtc, bool enable);
 void intel_crtc_update_dpms(struct drm_crtc *crtc);
 void intel_encoder_destroy(struct drm_encoder *encoder);
+int intel_connector_init(struct intel_connector *);
+struct intel_connector *intel_connector_alloc(void);
 void intel_connector_dpms(struct drm_connector *, int mode);
 bool intel_connector_get_hw_state(struct intel_connector *connector);
 void intel_modeset_check_state(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 572251e..5196642 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1007,7 +1007,7 @@ void intel_dsi_init(struct drm_device *dev)
        if (!intel_dsi)
                return;
 
-       intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+       intel_connector = intel_connector_alloc();
        if (!intel_connector) {
                kfree(intel_dsi);
                return;
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index 9a27ec7..7c9f852 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -469,7 +469,7 @@ void intel_dvo_init(struct drm_device *dev)
        if (!intel_dvo)
                return;
 
-       intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+       intel_connector = intel_connector_alloc();
        if (!intel_connector) {
                kfree(intel_dvo);
                return;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index 6d1a436..9d02746 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1752,7 +1752,7 @@ void intel_hdmi_init(struct drm_device *dev, int 
hdmi_reg, enum port port)
        if (!intel_dig_port)
                return;
 
-       intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+       intel_connector = intel_connector_alloc();
        if (!intel_connector) {
                kfree(intel_dig_port);
                return;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c 
b/drivers/gpu/drm/i915/intel_lvds.c
index 314a5d5..4ef031b 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -946,6 +946,12 @@ void intel_lvds_init(struct drm_device *dev)
                return;
        }
 
+       if (!intel_connector_init(&lvds_connector->base)) {
+               kfree(lvds_connector);
+               kfree(lvds_encoder);
+               return;
+       }
+
        lvds_encoder->attached_connector = lvds_connector;
 
        intel_encoder = &lvds_encoder->base;
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c 
b/drivers/gpu/drm/i915/intel_sdvo.c
index b121796..7c9acd8 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2427,6 +2427,22 @@ intel_sdvo_add_hdmi_properties(struct intel_sdvo 
*intel_sdvo,
        }
 }
 
+static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void)
+{
+       struct intel_sdvo_connector *sdvo_connector;
+
+       sdvo_connector = kzalloc(sizeof(*sdvo_connector), GFP_KERNEL);
+       if (!sdvo_connector)
+               return NULL;
+
+       if (!intel_connector_init(&sdvo_connector->base)) {
+               kfree(sdvo_connector);
+               return NULL;
+       }
+
+       return sdvo_connector;
+}
+
 static bool
 intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
 {
@@ -2438,7 +2454,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int 
device)
 
        DRM_DEBUG_KMS("initialising DVI device %d\n", device);
 
-       intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), 
GFP_KERNEL);
+       intel_sdvo_connector = intel_sdvo_connector_alloc();
        if (!intel_sdvo_connector)
                return false;
 
@@ -2492,7 +2508,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int 
type)
 
        DRM_DEBUG_KMS("initialising TV type %d\n", type);
 
-       intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), 
GFP_KERNEL);
+       intel_sdvo_connector = intel_sdvo_connector_alloc();
        if (!intel_sdvo_connector)
                return false;
 
@@ -2571,7 +2587,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int 
device)
 
        DRM_DEBUG_KMS("initialising LVDS device %d\n", device);
 
-       intel_sdvo_connector = kzalloc(sizeof(*intel_sdvo_connector), 
GFP_KERNEL);
+       intel_sdvo_connector = intel_sdvo_connector_alloc();
        if (!intel_sdvo_connector)
                return false;
 
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index bc1d9d7..8b9d325 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1621,7 +1621,7 @@ intel_tv_init(struct drm_device *dev)
                return;
        }
 
-       intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+       intel_connector = intel_connector_alloc();
        if (!intel_connector) {
                kfree(intel_tv);
                return;
-- 
2.1.0

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

Reply via email to