lkml.org 
[lkml]   [2020]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 48/90] iommu/vt-d: Ignore devices with out-of-spec domain number
    Date
    From: Daniel Drake <drake@endlessm.com>

    commit da72a379b2ec0bad3eb265787f7008bead0b040c upstream.

    VMD subdevices are created with a PCI domain ID of 0x10000 or
    higher.

    These subdevices are also handled like all other PCI devices by
    dmar_pci_bus_notifier().

    However, when dmar_alloc_pci_notify_info() take records of such devices,
    it will truncate the domain ID to a u16 value (in info->seg).
    The device at (e.g.) 10000:00:02.0 is then treated by the DMAR code as if
    it is 0000:00:02.0.

    In the unlucky event that a real device also exists at 0000:00:02.0 and
    also has a device-specific entry in the DMAR table,
    dmar_insert_dev_scope() will crash on:
      BUG_ON(i >= devices_cnt);

    That's basically a sanity check that only one PCI device matches a
    single DMAR entry; in this case we seem to have two matching devices.

    Fix this by ignoring devices that have a domain number higher than
    what can be looked up in the DMAR table.

    This problem was carefully diagnosed by Jian-Hong Pan.

    Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
    Signed-off-by: Daniel Drake <drake@endlessm.com>
    Fixes: 59ce0515cdaf3 ("iommu/vt-d: Update DRHD/RMRR/ATSR device scope caches when PCI hotplug happens")
    Signed-off-by: Joerg Roedel <jroedel@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/iommu/dmar.c | 8 ++++++++
    1 file changed, 8 insertions(+)

    --- a/drivers/iommu/dmar.c
    +++ b/drivers/iommu/dmar.c
    @@ -39,6 +39,7 @@
    #include <linux/dmi.h>
    #include <linux/slab.h>
    #include <linux/iommu.h>
    +#include <linux/limits.h>
    #include <asm/irq_remapping.h>
    #include <asm/iommu_table.h>

    @@ -138,6 +139,13 @@ dmar_alloc_pci_notify_info(struct pci_de

    BUG_ON(dev->is_virtfn);

    + /*
    + * Ignore devices that have a domain number higher than what can
    + * be looked up in DMAR, e.g. VMD subdevices with domain 0x10000
    + */
    + if (pci_domain_nr(dev->bus) > U16_MAX)
    + return NULL;
    +
    /* Only generate path[] for device addition event */
    if (event == BUS_NOTIFY_ADD_DEVICE)
    for (tmp = dev; tmp; tmp = tmp->bus->self)

    \
     
     \ /
      Last update: 2020-03-19 14:36    [W:4.037 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site