Yes.
I tried to crop the 2 sizes manually and it worked.
I tested a couple of user space commands and it seems to be working.

Later I will try with your patch.

Thanks!



Sent from my iPhone
> On 16 Feb 2017, at 19:03, Jason Gunthorpe <jguntho...@obsidianresearch.com> 
> wrote:
> 
>> 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?
> 
> 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);

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
tpmdd-devel mailing list
tpmdd-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

Reply via email to