From patchwork Thu Feb 16 19:03:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Gunthorpe X-Patchwork-Id: 728878 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vPQYD0vKTz9s7r for ; Fri, 17 Feb 2017 06:03:44 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=sfs-ml-2.v29.ch3.sourceforge.com) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1ceRL8-0001gM-9L; Thu, 16 Feb 2017 19:03:38 +0000 Received: from sog-mx-1.v43.ch3.sourceforge.com ([172.29.43.191] helo=mx.sourceforge.net) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1ceRL6-0001gG-Uo for tpmdd-devel@lists.sourceforge.net; Thu, 16 Feb 2017 19:03:36 +0000 Received-SPF: pass (sog-mx-1.v43.ch3.sourceforge.com: domain of obsidianresearch.com designates 184.70.90.242 as permitted sender) client-ip=184.70.90.242; envelope-from=jgunthorpe@obsidianresearch.com; helo=quartz.orcorp.ca; Received: from quartz.orcorp.ca ([184.70.90.242]) by sog-mx-1.v43.ch3.sourceforge.com with esmtps (TLSv1:AES128-SHA:128) (Exim 4.76) id 1ceRL5-0005oJ-Sq for tpmdd-devel@lists.sourceforge.net; Thu, 16 Feb 2017 19:03:36 +0000 Received: from [10.0.0.156] (helo=jggl.edm.orcorp.ca) by quartz.orcorp.ca with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1ceRKz-0000hg-ES; Thu, 16 Feb 2017 12:03:29 -0700 Received: from jgg by jggl.edm.orcorp.ca with local (Exim 4.86_2) (envelope-from ) id 1ceRKz-00014J-CG; Thu, 16 Feb 2017 12:03:29 -0700 Date: Thu, 16 Feb 2017 12:03:29 -0700 From: Jason Gunthorpe To: Davide Guerri Message-ID: <20170216190329.GC7257@obsidianresearch.com> References: <20170216180116.GA7145@obsidianresearch.com> <20170216181905.GA7257@obsidianresearch.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) X-Broken-Reverse-DNS: no host name found for IP address 10.0.0.156 X-Spam-Score: -1.6 (-) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1ceRL5-0005oJ-Sq Cc: tpmdd-devel@lists.sourceforge.net Subject: Re: [tpmdd-devel] Intel NUC and fTPM issue on 4.9.2 X-BeenThere: tpmdd-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Tpm Device Driver maintainance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: tpmdd-devel-bounces@lists.sourceforge.net On Thu, Feb 16, 2017 at 06:40:02PM +0000, Davide Guerri wrote: > Sorry I missed 1 line: > > [20417.678952] ACPI resource is [mem 0xfed40000-0xfed4087f flags 0x200] The BIOS is broken.. That range declared in the ACPI is too small Or the cmd_size is too big: > [20417.678990] map request is is [mem 0xfed40080-0xfed40fff flags 0x200] I have no idea which. If we trust the ACPI table then the cmd_size is 2047 bytes If we trust the register then it is 3967.. Try this? ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index a7c870af916c3d..2d16cc4aa0f43b 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -233,6 +233,8 @@ static void __iomem *crb_map_res(struct device *dev, struct crb_priv *priv, .flags = IORESOURCE_MEM, }; + printk("map request is is %pr\n",&new_res); + /* Detect a 64 bit address on a 32 bit system */ if (start != new_res.start) return (void __iomem *) ERR_PTR(-EINVAL); @@ -243,6 +245,26 @@ static void __iomem *crb_map_res(struct device *dev, struct crb_priv *priv, return priv->iobase + (new_res.start - io_res->start); } +/* + * Work around broken BIOSs that return inconsistent values from the ACPI + * region vs the registers. Trust the ACPI region. + */ +static u64 crb_clamp_cmd_size(struct device *dev, struct resource *io_res, + u64 start, u64 size) +{ + if (io_res->start > start || io_res->end < start) + return size; + + if (start + size - 1 <= io_res->end) + return size; + + dev_err(dev, + FW_BUG "ACPI region does not cover the entire command/response buffer. %pr vs %llx %llx\n", + io_res, start, size); + + return io_res->end - start + 1; +} + static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, struct acpi_table_tpm2 *buf) { @@ -267,6 +289,8 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, return -EINVAL; } + printk("ACPI resource is %pr\n",&io_res); + priv->iobase = devm_ioremap_resource(dev, &io_res); if (IS_ERR(priv->iobase)) return PTR_ERR(priv->iobase); @@ -278,14 +302,16 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, cmd_pa = ((u64) ioread32(&priv->cca->cmd_pa_high) << 32) | (u64) ioread32(&priv->cca->cmd_pa_low); - cmd_size = ioread32(&priv->cca->cmd_size); + cmd_size = crb_clamp_cmd_size(dev, &io_res, cmd_pa, + ioread32(&priv->cca->cmd_size)); priv->cmd = crb_map_res(dev, priv, &io_res, cmd_pa, cmd_size); if (IS_ERR(priv->cmd)) return PTR_ERR(priv->cmd); memcpy_fromio(&rsp_pa, &priv->cca->rsp_pa, 8); rsp_pa = le64_to_cpu(rsp_pa); - rsp_size = ioread32(&priv->cca->rsp_size); + rsp_size = crb_clamp_cmd_size(dev, &io_res, rsp_pa, + ioread32(&priv->cca->rsp_size)); if (cmd_pa != rsp_pa) { priv->rsp = crb_map_res(dev, priv, &io_res, rsp_pa, rsp_size);