[PATCH v2 06/22] drm/i915/bios: Validate the panel_name table

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx>

In addition to the fp_timing,dvo_timing,panel_pnp_id tables
there also exists a panel_name table. Unlike the others this
is just one offset+table_size even though there are still 16
actual panel_names in the data block.

The panel_name table made its first appearance somewhere
around VBT version 156-163. The exact version is not known.
But we don't need to know that since we can just check whether
the pointers block has enough room for it or not.

Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx>
---
 drivers/gpu/drm/i915/display/intel_bios.c     | 18 +++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_vbt_defs.h |  5 +++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index 925f521f1f84..799c1fe36b23 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -206,7 +206,7 @@ static const struct {
 static bool validate_lfp_data_ptrs(const void *bdb,
 				   const struct bdb_lvds_lfp_data_ptrs *ptrs)
 {
-	int fp_timing_size, dvo_timing_size, panel_pnp_id_size;
+	int fp_timing_size, dvo_timing_size, panel_pnp_id_size, panel_name_size;
 	int data_block_size, lfp_data_size;
 	int i;
 
@@ -221,6 +221,7 @@ static bool validate_lfp_data_ptrs(const void *bdb,
 	fp_timing_size = ptrs->ptr[0].fp_timing.table_size;
 	dvo_timing_size = ptrs->ptr[0].dvo_timing.table_size;
 	panel_pnp_id_size = ptrs->ptr[0].panel_pnp_id.table_size;
+	panel_name_size = ptrs->panel_name.table_size;
 
 	/* fp_timing has variable size */
 	if (fp_timing_size < 32 ||
@@ -228,6 +229,11 @@ static bool validate_lfp_data_ptrs(const void *bdb,
 	    panel_pnp_id_size != sizeof(struct lvds_pnp_id))
 		return false;
 
+	/* panel_name is not present in old VBTs */
+	if (panel_name_size != 0 &&
+	    panel_name_size != sizeof(struct lvds_lfp_panel_name))
+		return false;
+
 	lfp_data_size = ptrs->ptr[1].fp_timing.offset - ptrs->ptr[0].fp_timing.offset;
 	if (16 * lfp_data_size > data_block_size)
 		return false;
@@ -268,6 +274,9 @@ static bool validate_lfp_data_ptrs(const void *bdb,
 			return false;
 	}
 
+	if (ptrs->panel_name.offset + 16 * panel_name_size > data_block_size)
+		return false;
+
 	return true;
 }
 
@@ -291,6 +300,13 @@ static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block)
 		ptrs->ptr[i].panel_pnp_id.offset -= offset;
 	}
 
+	if (ptrs->panel_name.table_size) {
+		if (ptrs->panel_name.offset < offset)
+			return false;
+
+		ptrs->panel_name.offset -= offset;
+	}
+
 	return validate_lfp_data_ptrs(bdb, ptrs);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index d727fcd6cdab..e4a11c3e3f3e 100644
--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -737,6 +737,7 @@ struct lvds_lfp_data_ptr {
 struct bdb_lvds_lfp_data_ptrs {
 	u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
 	struct lvds_lfp_data_ptr ptr[16];
+	struct lvds_lfp_data_ptr_table panel_name; /* 156-163? */
 } __packed;
 
 /*
@@ -778,6 +779,10 @@ struct bdb_lvds_lfp_data {
 	struct lvds_lfp_data_entry data[16];
 } __packed;
 
+struct lvds_lfp_panel_name {
+	u8 name[13];
+} __packed;
+
 /*
  * Block 43 - LFP Backlight Control Data Block
  */
-- 
2.35.1




[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux