lkml.org 
[lkml]   [2018]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.18 092/144] iommu/vt-d: Fix VM domain ID leak
    Date
    3.18-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    [ Upstream commit 46ebb7af7b93792de65e124e1ab8b89a108a41f2 ]

    This continues the attempt to fix commit fb170fb4c548 ("iommu/vt-d:
    Introduce helper functions to make code symmetric for readability").
    The previous attempt in commit 71684406905f ("iommu/vt-d: Detach
    domain *only* from attached iommus") overlooked the fact that
    dmar_domain.iommu_bmp gets cleared for VM domains when devices are
    detached:

    intel_iommu_detach_device
    domain_remove_one_dev_info
    domain_detach_iommu

    The domain is detached from the iommu, but the iommu is still attached
    to the domain, for whatever reason. Thus when we get to domain_exit(),
    we can't rely on iommu_bmp for VM domains to find the active iommus,
    we must check them all. Without that, the corresponding bit in
    intel_iommu.domain_ids doesn't get cleared and repeated VM domain
    creation and destruction will run out of domain IDs. Meanwhile we
    still can't call iommu_detach_domain() on arbitrary non-VM domains or
    we risk clearing in-use domain IDs, as 71684406905f attempted to
    address.

    It's tempting to modify iommu_detach_domain() to test the domain
    iommu_bmp, but the call ordering from domain_remove_one_dev_info()
    prevents it being able to work as fb170fb4c548 seems to have intended.
    Caching of unused VM domains on the iommu object seems to be the root
    of the problem, but this code is far too fragile for that kind of
    rework to be proposed for stable, so we simply revert this chunk to
    its state prior to fb170fb4c548.

    Fixes: fb170fb4c548 ("iommu/vt-d: Introduce helper functions to make
    code symmetric for readability")
    Fixes: 71684406905f ("iommu/vt-d: Detach domain *only* from attached
    iommus")
    Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
    Cc: Jiang Liu <jiang.liu@linux.intel.com>
    Cc: stable@vger.kernel.org # v3.17+
    Signed-off-by: Joerg Roedel <jroedel@suse.de>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/iommu/intel-iommu.c | 9 ++++++---
    1 file changed, 6 insertions(+), 3 deletions(-)

    diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
    index 351da1da814f..2068cb59f7ed 100644
    --- a/drivers/iommu/intel-iommu.c
    +++ b/drivers/iommu/intel-iommu.c
    @@ -1759,8 +1759,9 @@ static int domain_init(struct dmar_domain *domain, int guest_width)

    static void domain_exit(struct dmar_domain *domain)
    {
    + struct dmar_drhd_unit *drhd;
    + struct intel_iommu *iommu;
    struct page *freelist = NULL;
    - int i;

    /* Domain 0 is reserved, so dont process it */
    if (!domain)
    @@ -1780,8 +1781,10 @@ static void domain_exit(struct dmar_domain *domain)

    /* clear attached or cached domains */
    rcu_read_lock();
    - for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus)
    - iommu_detach_domain(domain, g_iommus[i]);
    + for_each_active_iommu(iommu, drhd)
    + if (domain_type_is_vm(domain) ||
    + test_bit(iommu->seq_id, domain->iommu_bmp))
    + iommu_detach_domain(domain, iommu);
    rcu_read_unlock();

    dma_free_pagelist(freelist);
    --
    2.17.1


    \
     
     \ /
      Last update: 2018-11-08 23:42    [W:4.360 / U:0.896 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site