On Tue, 2015-12-01 at 04:17 +0530, Deepak M wrote: > Calling the validate_vbt before assiging the opregion vbt blob. > Size of the VBT blob cant be more than 6KB when VBT is present > in mailbox 4. > > Cc: Jani Nikula <jani.nikula@xxxxxxxxx> Tested-by: Mika Kahola <mika.kahola@xxxxxxxxx> > Signed-off-by: Deepak M <m.deepak@xxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_drv.h | 3 +++ > drivers/gpu/drm/i915/intel_bios.c | 43 +++++++++++++++++++---------------- > drivers/gpu/drm/i915/intel_opregion.c | 31 +++++++++++++++++++++++++ > 3 files changed, 57 insertions(+), 20 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 135d32a..8cf8375 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -3324,6 +3324,9 @@ intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state) > } > #endif > > +const struct vbt_header *validate_vbt(const void *_vbt, size_t size, > + const char *source); > + > /* intel_acpi.c */ > #ifdef CONFIG_ACPI > extern void intel_register_dsm_handler(void); > diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c > index 6756a1c..57a77aa 100644 > --- a/drivers/gpu/drm/i915/intel_bios.c > +++ b/drivers/gpu/drm/i915/intel_bios.c > @@ -1237,16 +1237,15 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = { > { } > }; > > -static const struct bdb_header *validate_vbt(const void *base, > +const struct vbt_header *validate_vbt(const void *_vbt, > size_t size, > - const void *_vbt, > const char *source) > { > - size_t offset = _vbt - base; > - const struct vbt_header *vbt = _vbt; > + const struct vbt_header *vbt = (const struct vbt_header *)_vbt; > const struct bdb_header *bdb; > + size_t offset; > > - if (offset + sizeof(struct vbt_header) > size) { > + if (sizeof(struct vbt_header) > size) { > DRM_DEBUG_DRIVER("VBT header incomplete\n"); > return NULL; > } > @@ -1256,26 +1255,26 @@ static const struct bdb_header *validate_vbt(const void *base, > return NULL; > } > > - offset += vbt->bdb_offset; > + offset = vbt->bdb_offset; > if (offset + sizeof(struct bdb_header) > size) { > DRM_DEBUG_DRIVER("BDB header incomplete\n"); > return NULL; > } > > - bdb = base + offset; > + bdb = (const void *)_vbt + offset; > if (offset + bdb->bdb_size > size) { > DRM_DEBUG_DRIVER("BDB incomplete\n"); > return NULL; > } > > DRM_DEBUG_KMS("Using VBT from %s: %20s\n", > - source, vbt->signature); > - return bdb; > + source, vbt->signature); > + return vbt; > } > > -static const struct bdb_header *find_vbt(void __iomem *bios, size_t size) > +static const struct vbt_header *find_vbt(void __iomem *bios, size_t size) > { > - const struct bdb_header *bdb = NULL; > + const struct vbt_header *vbt = NULL; > size_t i; > > /* Scour memory looking for the VBT signature. */ > @@ -1289,12 +1288,12 @@ static const struct bdb_header *find_vbt(void __iomem *bios, size_t size) > */ > void *_bios = (void __force *) bios; > > - bdb = validate_vbt(_bios, size, _bios + i, "PCI ROM"); > + vbt = validate_vbt(_bios + i, size - i, "PCI ROM"); > break; > } > } > > - return bdb; > + return vbt; > } > > /** > @@ -1311,6 +1310,7 @@ intel_parse_bios(struct drm_device *dev) > { > struct drm_i915_private *dev_priv = dev->dev_private; > struct pci_dev *pdev = dev->pdev; > + const struct vbt_header *vbt = NULL; > const struct bdb_header *bdb = NULL; > u8 __iomem *bios = NULL; > > @@ -1319,23 +1319,26 @@ intel_parse_bios(struct drm_device *dev) > > init_vbt_defaults(dev_priv); > > - /* XXX Should this validation be moved to intel_opregion.c? */ > - if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv->opregion.vbt) > - bdb = validate_vbt(dev_priv->opregion.header, OPREGION_SIZE, > - dev_priv->opregion.vbt, "OpRegion"); > + if (!dmi_check_system(intel_no_opregion_vbt) && > + dev_priv->opregion.vbt) { > + vbt = (const struct vbt_header *)dev_priv->opregion.vbt; > + bdb = (const void *)dev_priv->opregion.vbt + vbt->bdb_offset; > + } > > - if (bdb == NULL) { > + if (vbt == NULL) { > size_t size; > > bios = pci_map_rom(pdev, &size); > if (!bios) > return -1; > > - bdb = find_vbt(bios, size); > - if (!bdb) { > + vbt = find_vbt(bios, size); > + if (!vbt) { > pci_unmap_rom(pdev, bios); > return -1; > } > + > + bdb = (const void *)vbt + vbt->bdb_offset; > } > > /* Grab useful general definitions */ > diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c > index 43b7c3b..4a78282 100644 > --- a/drivers/gpu/drm/i915/intel_opregion.c > +++ b/drivers/gpu/drm/i915/intel_opregion.c > @@ -48,6 +48,27 @@ > #define OPREGION_VBT_OFFSET 0x400 > #define OPREGION_ASLE_EXT_OFFSET 0x1C00 > > +#define MAILBOX_4_SIZE 0x1800 > + > +/* > + * Opregion Structure: > + * +-------------------------------+ > + * | Mailbox1 : ACPI | > + * | Offset : 0x100 | > + * +-------------------------------+ > + * | Mailbox2 : SWSCI | > + * | Offset : 0x200 | > + * +-------------------------------+ > + * | Mailbox3 : ASLE | > + * | Offset : 0x300 | > + * +-------------------------------+ > + * | Mailbox4 : VBT | > + * | Offset : 0x400 | > + * +-------------------------------+ > + * | Mailbox5 : ASLE_EXT | > + * | Offset : 0x1C00 | > + * +-------------------------------+ > +*/ > #define OPREGION_SIGNATURE "IntelGraphicsMem" > #define MBOX_ACPI (1<<0) > #define MBOX_SWSCI (1<<1) > @@ -910,6 +931,7 @@ int intel_opregion_setup(struct drm_device *dev) > struct intel_opregion *opregion = &dev_priv->opregion; > u32 asls, mboxes; > char buf[sizeof(OPREGION_SIGNATURE)]; > + const struct vbt_header *vbt = NULL; > int err = 0; > void *base; > > @@ -940,6 +962,15 @@ int intel_opregion_setup(struct drm_device *dev) > err = -EINVAL; > goto err_out; > } > + > + vbt = validate_vbt(base + OPREGION_VBT_OFFSET, > + MAILBOX_4_SIZE, "OpRegion"); > + > + if (vbt == NULL) { > + err = -EINVAL; > + goto err_out; > + } > + > opregion->header = base; > opregion->vbt = base + OPREGION_VBT_OFFSET; > _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx