lkml.org 
[lkml]   [2009]   [Oct]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[20/46] intel-iommu: Cope with broken HP DC7900 BIOS
    2.6.31-stable review patch.  If anyone has any objections, please let us know.

    ------------------
    From: David Woodhouse <David.Woodhouse@intel.com>

    commit 0815565adfe3f4c369110c57d8ffe83caefeed68 upstream.

    Yet another reason why trusting this stuff to the BIOS was a bad idea.
    The HP DC7900 BIOS reports an iommu at an address which just returns all
    ones, when VT-d is disabled in the BIOS.

    Fix up the missing iounmap in the error paths while we're at it.

    Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
    Cc: Arto Jantunen <viiru@debian.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/pci/dmar.c | 22 ++++++++++++++++++----
    1 file changed, 18 insertions(+), 4 deletions(-)

    --- a/drivers/pci/dmar.c
    +++ b/drivers/pci/dmar.c
    @@ -632,20 +632,31 @@ int alloc_iommu(struct dmar_drhd_unit *d
    iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG);
    iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);

    + if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) {
    + /* Promote an attitude of violence to a BIOS engineer today */
    + WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
    + "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
    + drhd->reg_base_addr,
    + dmi_get_system_info(DMI_BIOS_VENDOR),
    + dmi_get_system_info(DMI_BIOS_VERSION),
    + dmi_get_system_info(DMI_PRODUCT_VERSION));
    + goto err_unmap;
    + }
    +
    #ifdef CONFIG_DMAR
    agaw = iommu_calculate_agaw(iommu);
    if (agaw < 0) {
    printk(KERN_ERR
    "Cannot get a valid agaw for iommu (seq_id = %d)\n",
    iommu->seq_id);
    - goto error;
    + goto err_unmap;
    }
    msagaw = iommu_calculate_max_sagaw(iommu);
    if (msagaw < 0) {
    printk(KERN_ERR
    "Cannot get a valid max agaw for iommu (seq_id = %d)\n",
    iommu->seq_id);
    - goto error;
    + goto err_unmap;
    }
    #endif
    iommu->agaw = agaw;
    @@ -665,7 +676,7 @@ int alloc_iommu(struct dmar_drhd_unit *d
    }

    ver = readl(iommu->reg + DMAR_VER_REG);
    - pr_debug("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n",
    + pr_info("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n",
    (unsigned long long)drhd->reg_base_addr,
    DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver),
    (unsigned long long)iommu->cap,
    @@ -675,7 +686,10 @@ int alloc_iommu(struct dmar_drhd_unit *d

    drhd->iommu = iommu;
    return 0;
    -error:
    +
    + err_unmap:
    + iounmap(iommu->reg);
    + error:
    kfree(iommu);
    return -1;
    }



    \
     
     \ /
      Last update: 2009-10-16 19:35    [W:0.022 / U:1.368 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site