drm/i915/bios: range check LFP Data Block panel_type2

While the panel_type from LFP Data Block is range checked, panel_type2
is not. Add a few helpers for range checking, and use them to not only
check panel_type2, but also improve clarity and correctness in the panel
type selection.

Discovered using AI-assisted static analysis confirmed by Intel Product
Security.

v2:
- Fix commit message typo (Michał)
- Add is_panel_type_pnp() (Ville)

Reported-by: Martin Hodo <martin.hodo@intel.com>
Fixes: 6434cf6300 ("drm/i915/bios: calculate panel type as per child device index in VBT")
Cc: stable@vger.kernel.org # v6.0+
Cc: Animesh Manna <animesh.manna@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Reviewed-by: Michał Grzelak <michal.grzelak@intel.com> # v1
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20260626140155.1389655-1-jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
This commit is contained in:
Jani Nikula
2026-06-26 17:01:55 +03:00
parent 1765cf59f5
commit c9ebe5d2f2

View File

@@ -623,6 +623,21 @@ get_lfp_data_tail(const struct bdb_lfp_data *data,
return NULL;
}
static bool is_panel_type_valid(int panel_type)
{
return panel_type >= 0 && panel_type < 16;
}
static bool is_panel_type_pnp(int panel_type)
{
return panel_type == 0xff;
}
static bool is_panel_type_valid_or_pnp(int panel_type)
{
return is_panel_type_valid(panel_type) || is_panel_type_pnp(panel_type);
}
static int opregion_get_panel_type(struct intel_display *display,
const struct intel_bios_encoder_data *devdata,
const struct drm_edid *drm_edid, bool use_fallback)
@@ -640,15 +655,21 @@ static int vbt_get_panel_type(struct intel_display *display,
if (!lfp_options)
return -1;
if (lfp_options->panel_type > 0xf &&
lfp_options->panel_type != 0xff) {
if (!is_panel_type_valid_or_pnp(lfp_options->panel_type)) {
drm_dbg_kms(display->drm, "Invalid VBT panel type 0x%x\n",
lfp_options->panel_type);
return -1;
}
if (devdata && devdata->child.handle == DEVICE_HANDLE_LFP2)
if (devdata && devdata->child.handle == DEVICE_HANDLE_LFP2) {
if (!is_panel_type_valid_or_pnp(lfp_options->panel_type2)) {
drm_dbg_kms(display->drm, "Invalid VBT panel type 2 0x%x\n",
lfp_options->panel_type2);
return -1;
}
return lfp_options->panel_type2;
}
drm_WARN_ON(display->drm,
devdata && devdata->child.handle != DEVICE_HANDLE_LFP1);
@@ -762,13 +783,12 @@ static int get_panel_type(struct intel_display *display,
panel_types[i].name, panel_types[i].panel_type);
}
if (panel_types[PANEL_TYPE_OPREGION].panel_type >= 0)
if (is_panel_type_valid(panel_types[PANEL_TYPE_OPREGION].panel_type))
i = PANEL_TYPE_OPREGION;
else if (panel_types[PANEL_TYPE_VBT].panel_type == 0xff &&
panel_types[PANEL_TYPE_PNPID].panel_type >= 0)
else if (is_panel_type_pnp(panel_types[PANEL_TYPE_VBT].panel_type) &&
is_panel_type_valid(panel_types[PANEL_TYPE_PNPID].panel_type))
i = PANEL_TYPE_PNPID;
else if (panel_types[PANEL_TYPE_VBT].panel_type != 0xff &&
panel_types[PANEL_TYPE_VBT].panel_type >= 0)
else if (is_panel_type_valid(panel_types[PANEL_TYPE_VBT].panel_type))
i = PANEL_TYPE_VBT;
else
i = PANEL_TYPE_FALLBACK;