mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-12 11:36:35 +00:00
Merge tag 'drm-intel-fixes-2018-05-29' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
- Fix for potential Spectre vector in the new query uAPI - Fix NULL pointer deref (FDO #106559) - DMI fix to hide LVDS for Radiant P845 (FDO #105468) * tag 'drm-intel-fixes-2018-05-29' of git://anongit.freedesktop.org/drm/drm-intel: drm/i915/query: nospec expects no more than an unsigned long drm/i915/query: Protect tainted function pointer lookup drm/i915/lvds: Move acpi lid notification registration to registration phase drm/i915: Disable LVDS on Radiant P845
This commit is contained in:
commit
801dff41ba
2 changed files with 51 additions and 15 deletions
|
@ -4,6 +4,8 @@
|
|||
* Copyright © 2018 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/nospec.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_query.h"
|
||||
#include <uapi/drm/i915_drm.h>
|
||||
|
@ -100,7 +102,7 @@ int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||
|
||||
for (i = 0; i < args->num_items; i++, user_item_ptr++) {
|
||||
struct drm_i915_query_item item;
|
||||
u64 func_idx;
|
||||
unsigned long func_idx;
|
||||
int ret;
|
||||
|
||||
if (copy_from_user(&item, user_item_ptr, sizeof(item)))
|
||||
|
@ -109,12 +111,17 @@ int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||
if (item.query_id == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (overflows_type(item.query_id - 1, unsigned long))
|
||||
return -EINVAL;
|
||||
|
||||
func_idx = item.query_id - 1;
|
||||
|
||||
if (func_idx < ARRAY_SIZE(i915_query_funcs))
|
||||
ret = i915_query_funcs[func_idx](dev_priv, &item);
|
||||
else
|
||||
ret = -EINVAL;
|
||||
if (func_idx < ARRAY_SIZE(i915_query_funcs)) {
|
||||
func_idx = array_index_nospec(func_idx,
|
||||
ARRAY_SIZE(i915_query_funcs));
|
||||
ret = i915_query_funcs[func_idx](dev_priv, &item);
|
||||
}
|
||||
|
||||
/* Only write the length back to userspace if they differ. */
|
||||
if (ret != item.length && put_user(ret, &user_item_ptr->length))
|
||||
|
|
|
@ -574,6 +574,36 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
|
|||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_lvds_connector_register(struct drm_connector *connector)
|
||||
{
|
||||
struct intel_lvds_connector *lvds = to_lvds_connector(connector);
|
||||
int ret;
|
||||
|
||||
ret = intel_connector_register(connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
lvds->lid_notifier.notifier_call = intel_lid_notify;
|
||||
if (acpi_lid_notifier_register(&lvds->lid_notifier)) {
|
||||
DRM_DEBUG_KMS("lid notifier registration failed\n");
|
||||
lvds->lid_notifier.notifier_call = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
intel_lvds_connector_unregister(struct drm_connector *connector)
|
||||
{
|
||||
struct intel_lvds_connector *lvds = to_lvds_connector(connector);
|
||||
|
||||
if (lvds->lid_notifier.notifier_call)
|
||||
acpi_lid_notifier_unregister(&lvds->lid_notifier);
|
||||
|
||||
intel_connector_unregister(connector);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_lvds_destroy - unregister and free LVDS structures
|
||||
* @connector: connector to free
|
||||
|
@ -586,9 +616,6 @@ static void intel_lvds_destroy(struct drm_connector *connector)
|
|||
struct intel_lvds_connector *lvds_connector =
|
||||
to_lvds_connector(connector);
|
||||
|
||||
if (lvds_connector->lid_notifier.notifier_call)
|
||||
acpi_lid_notifier_unregister(&lvds_connector->lid_notifier);
|
||||
|
||||
if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
|
||||
kfree(lvds_connector->base.edid);
|
||||
|
||||
|
@ -609,8 +636,8 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
|
|||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.atomic_get_property = intel_digital_connector_atomic_get_property,
|
||||
.atomic_set_property = intel_digital_connector_atomic_set_property,
|
||||
.late_register = intel_connector_register,
|
||||
.early_unregister = intel_connector_unregister,
|
||||
.late_register = intel_lvds_connector_register,
|
||||
.early_unregister = intel_lvds_connector_unregister,
|
||||
.destroy = intel_lvds_destroy,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
.atomic_duplicate_state = intel_digital_connector_duplicate_state,
|
||||
|
@ -827,6 +854,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
|
|||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = intel_no_lvds_dmi_callback,
|
||||
.ident = "Radiant P845",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Radiant Systems Inc"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "P845"),
|
||||
},
|
||||
},
|
||||
|
||||
{ } /* terminating entry */
|
||||
};
|
||||
|
@ -1150,12 +1185,6 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
|
|||
|
||||
lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK;
|
||||
|
||||
lvds_connector->lid_notifier.notifier_call = intel_lid_notify;
|
||||
if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) {
|
||||
DRM_DEBUG_KMS("lid notifier registration failed\n");
|
||||
lvds_connector->lid_notifier.notifier_call = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
failed:
|
||||
|
|
Loading…
Reference in a new issue