Commit 4a4f219e authored by Yi Sun's avatar Yi Sun Committed by Michael S. Tsirkin
Browse files

intel_iommu: add scalable-mode option to make scalable mode work

This patch adds an option to provide flexibility for user to expose
Scalable Mode to guest. User could expose Scalable Mode to guest by
the config as below:

"-device intel-iommu,caching-mode=on,scalable-mode=on"

The Linux iommu driver has supported scalable mode. Please refer below
patch set:

    https://www.spinics.net/lists/kernel/msg2985279.html



Signed-off-by: default avatarLiu, Yi L <yi.l.liu@intel.com>
Signed-off-by: default avatarYi Sun <yi.y.sun@linux.intel.com>
Message-Id: <1551753295-30167-4-git-send-email-yi.y.sun@linux.intel.com>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Reviewed-by: default avatarPeter Xu <peterx@redhat.com>
Reviewed-by: default avatarIgor Mammedov <imammedo@redhat.com>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent c0c1d351
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -1710,6 +1710,9 @@ static void vtd_root_table_setup(IntelIOMMUState *s)
{
    s->root = vtd_get_quad_raw(s, DMAR_RTADDR_REG);
    s->root_extended = s->root & VTD_RTADDR_RTT;
    if (s->scalable_mode) {
        s->root_scalable = s->root & VTD_RTADDR_SMT;
    }
    s->root &= VTD_RTADDR_ADDR_MASK(s->aw_bits);

    trace_vtd_reg_dmar_root(s->root, s->root_extended);
@@ -2419,6 +2422,17 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s)
        }
        break;

    /*
     * TODO: the entity of below two cases will be implemented in future series.
     * To make guest (which integrates scalable mode support patch set in
     * iommu driver) work, just return true is enough so far.
     */
    case VTD_INV_DESC_PC:
        break;

    case VTD_INV_DESC_PIOTLB:
        break;

    case VTD_INV_DESC_WAIT:
        trace_vtd_inv_desc("wait", inv_desc.hi, inv_desc.lo);
        if (!vtd_process_wait_desc(s, &inv_desc)) {
@@ -2983,6 +2997,7 @@ static Property vtd_properties[] = {
    DEFINE_PROP_UINT8("aw-bits", IntelIOMMUState, aw_bits,
                      VTD_HOST_ADDRESS_WIDTH),
    DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE),
    DEFINE_PROP_BOOL("x-scalable-mode", IntelIOMMUState, scalable_mode, FALSE),
    DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true),
    DEFINE_PROP_END_OF_LIST(),
};
@@ -3518,6 +3533,11 @@ static void vtd_init(IntelIOMMUState *s)
        s->cap |= VTD_CAP_CM;
    }

    /* TODO: read cap/ecap from host to decide which cap to be exposed. */
    if (s->scalable_mode) {
        s->ecap |= VTD_ECAP_SMTS | VTD_ECAP_SRS | VTD_ECAP_SLTS;
    }

    vtd_reset_caches(s);

    /* Define registers with default values and bit semantics */
@@ -3629,6 +3649,11 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp)
        return false;
    }

    if (s->scalable_mode && !s->dma_drain) {
        error_setg(errp, "Need to set dma_drain for scalable mode");
        return false;
    }

    return true;
}

+4 −0
Original line number Diff line number Diff line
@@ -190,7 +190,9 @@
#define VTD_ECAP_EIM                (1ULL << 4)
#define VTD_ECAP_PT                 (1ULL << 6)
#define VTD_ECAP_MHMV               (15ULL << 20)
#define VTD_ECAP_SRS                (1ULL << 31)
#define VTD_ECAP_SMTS               (1ULL << 43)
#define VTD_ECAP_SLTS               (1ULL << 46)

/* CAP_REG */
/* (offset >> 4) << 24 */
@@ -345,6 +347,8 @@ typedef union VTDInvDesc VTDInvDesc;
#define VTD_INV_DESC_IEC                0x4 /* Interrupt Entry Cache
                                               Invalidate Descriptor */
#define VTD_INV_DESC_WAIT               0x5 /* Invalidation Wait Descriptor */
#define VTD_INV_DESC_PIOTLB             0x6 /* PASID-IOTLB Invalidate Desc */
#define VTD_INV_DESC_PC                 0x7 /* PASID-cache Invalidate Desc */
#define VTD_INV_DESC_NONE               0   /* Not an Invalidate Descriptor */

/* Masks for Invalidation Wait Descriptor*/
+2 −1
Original line number Diff line number Diff line
@@ -228,6 +228,7 @@ struct IntelIOMMUState {
    uint32_t version;

    bool caching_mode;              /* RO - is cap CM enabled? */
    bool scalable_mode;             /* RO - is Scalable Mode supported? */

    dma_addr_t root;                /* Current root table pointer */
    bool root_extended;             /* Type of root table (extended or not) */