gpu-kms: Handle drmModeGetResources() failing

Avoid dereferencing the NULL return value if it fails. We still create
the MetaGpu, but we treat it as if it has no outputs.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/223

(cherry picked from commit 29cc526e2e)
This commit is contained in:
Iain Lane 2018-08-10 09:46:51 +00:00 committed by Ray Strode
parent 5e56384636
commit 2fb46fd078

View File

@ -62,6 +62,8 @@ struct _MetaGpuKms
int max_buffer_height; int max_buffer_height;
gboolean page_flips_not_supported; gboolean page_flips_not_supported;
gboolean resources_init_failed_before;
}; };
G_DEFINE_QUARK (MetaGpuKmsError, meta_gpu_kms_error) G_DEFINE_QUARK (MetaGpuKmsError, meta_gpu_kms_error)
@ -709,20 +711,34 @@ init_outputs (MetaGpuKms *gpu_kms,
setup_output_clones (gpu); setup_output_clones (gpu);
} }
static void static gboolean
meta_kms_resources_init (MetaKmsResources *resources, meta_kms_resources_init (MetaKmsResources *resources,
int fd) int fd,
GError **error)
{ {
drmModeRes *drm_resources; drmModeRes *drm_resources;
unsigned int i; unsigned int i;
drm_resources = drmModeGetResources (fd); drm_resources = drmModeGetResources (fd);
if (!drm_resources)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"Calling drmModeGetResources() failed");
return FALSE;
}
resources->resources = drm_resources; resources->resources = drm_resources;
resources->n_encoders = (unsigned int) drm_resources->count_encoders; resources->n_encoders = (unsigned int) drm_resources->count_encoders;
resources->encoders = g_new (drmModeEncoder *, resources->n_encoders); resources->encoders = g_new (drmModeEncoder *, resources->n_encoders);
for (i = 0; i < resources->n_encoders; i++) for (i = 0; i < resources->n_encoders; i++)
resources->encoders[i] = drmModeGetEncoder (fd, drm_resources->encoders[i]); resources->encoders[i] = drmModeGetEncoder (fd, drm_resources->encoders[i]);
return TRUE;
} }
static void static void
@ -734,7 +750,7 @@ meta_kms_resources_release (MetaKmsResources *resources)
drmModeFreeEncoder (resources->encoders[i]); drmModeFreeEncoder (resources->encoders[i]);
g_free (resources->encoders); g_free (resources->encoders);
drmModeFreeResources (resources->resources); g_clear_pointer (&resources->resources, drmModeFreeResources);
} }
static gboolean static gboolean
@ -745,8 +761,18 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
MetaMonitorManager *monitor_manager = MetaMonitorManager *monitor_manager =
meta_gpu_get_monitor_manager (gpu); meta_gpu_get_monitor_manager (gpu);
MetaKmsResources resources; MetaKmsResources resources;
g_autoptr (GError) local_error = NULL;
meta_kms_resources_init (&resources, gpu_kms->fd); if (!meta_kms_resources_init (&resources, gpu_kms->fd, &local_error))
{
if (!gpu_kms->resources_init_failed_before)
{
g_warning ("meta_kms_resources_init failed: %s, assuming we have no outputs",
local_error->message);
gpu_kms->resources_init_failed_before = TRUE;
}
return TRUE;
}
gpu_kms->max_buffer_width = resources.resources->max_width; gpu_kms->max_buffer_width = resources.resources->max_width;
gpu_kms->max_buffer_height = resources.resources->max_height; gpu_kms->max_buffer_height = resources.resources->max_height;