From patchwork Mon Nov 30 22:47:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak M X-Patchwork-Id: 7728371 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id C7031BEEE1 for ; Mon, 30 Nov 2015 17:13:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DAE8F20515 for ; Mon, 30 Nov 2015 17:13:25 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id A4D4F20562 for ; Mon, 30 Nov 2015 17:13:24 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id ECF296E61D; Mon, 30 Nov 2015 09:13:23 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id 37BCE6E61A for ; Mon, 30 Nov 2015 09:13:21 -0800 (PST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 30 Nov 2015 09:13:20 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,365,1444719600"; d="scan'208";a="861391542" Received: from mdeepakubuntudesk01-desktop.iind.intel.com ([10.223.26.119]) by orsmga002.jf.intel.com with ESMTP; 30 Nov 2015 09:13:18 -0800 From: Deepak M To: intel-gfx@lists.freedesktop.org Date: Tue, 1 Dec 2015 04:17:07 +0530 Message-Id: <1448923632-16760-5-git-send-email-m.deepak@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1448923632-16760-1-git-send-email-m.deepak@intel.com> References: <1448923632-16760-1-git-send-email-m.deepak@intel.com> Cc: Deepak M , Jani Nikula Subject: [Intel-gfx] [MIPI SEQ PARSING v3 04/13] drm/i915: Do opregion VBT validation during opregion setup X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-1.2 required=5.0 tests=BAYES_00, DATE_IN_FUTURE_03_06, RCVD_IN_DNSWL_MED,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Signed-off-by: Deepak M Tested-by: Mika Kahola --- 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;