[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v3 04/10] xen/arm: smmuv3: Move definitions to a header



On Mon, 5 Sep 2022, Rahul Singh wrote:
> From: Jean-Philippe Brucker <jean-philippe@xxxxxxxxxx>
> 
> Backport Linux commit e881e7839fba. Also, move Xen related struct
> definition to header to get it compiled.
> 
> Allow sharing structure definitions with the upcoming SVA support for
> Arm SMMUv3, by moving them to a separate header. We could surgically
> extract only what is needed but keeping all definitions in one place
> looks nicer.
> 
> Signed-off-by: Jean-Philippe Brucker <jean-philippe@xxxxxxxxxx>
> Reviewed-by: Eric Auger <eric.auger@xxxxxxxxxx>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx>
> Link: 
> https://lore.kernel.org/r/20200918101852.582559-8-jean-philippe@xxxxxxxxxx
> Signed-off-by: Will Deacon <will@xxxxxxxxxx>
> Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
> e881e7839fba
> Signed-off-by: Rahul Singh <rahul.singh@xxxxxxx>

Acked-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>


> ---
> Changes in v3:
>  - remove clean backport msg in commit msg
> Changes in v2:
>  - fix commit msg
>  - also move struct definition to header file to sync with Linux patch
> ---
>  xen/drivers/passthrough/arm/smmu-v3.c | 665 +------------------------
>  xen/drivers/passthrough/arm/smmu-v3.h | 674 ++++++++++++++++++++++++++
>  2 files changed, 675 insertions(+), 664 deletions(-)
>  create mode 100644 xen/drivers/passthrough/arm/smmu-v3.h
> 
> diff --git a/xen/drivers/passthrough/arm/smmu-v3.c 
> b/xen/drivers/passthrough/arm/smmu-v3.c
> index e632c75b21..e65b226b85 100644
> --- a/xen/drivers/passthrough/arm/smmu-v3.c
> +++ b/xen/drivers/passthrough/arm/smmu-v3.c
> @@ -90,6 +90,7 @@
>  #include <asm/iommu_fwspec.h>
>  #include <asm/platform.h>
>  
> +#include "smmu-v3.h"
>  
>  #define ARM_SMMU_VTCR_SH_IS          3
>  #define ARM_SMMU_VTCR_RGN_WBWA               1
> @@ -103,22 +104,12 @@
>  #define ARM_SMMU_VTCR_PS_52_BIT              0x6ULL
>  
>  /* Linux compatibility functions. */
> -typedef paddr_t              dma_addr_t;
> -typedef paddr_t              phys_addr_t;
> -typedef unsigned int         gfp_t;
> -
>  #define iomb()               dmb(osh)
>  
>  #define platform_device              device
>  
>  #define GFP_KERNEL           0
>  
> -/* Alias to Xen lock functions */
> -#define mutex spinlock
> -#define mutex_init spin_lock_init
> -#define mutex_lock spin_lock
> -#define mutex_unlock spin_unlock
> -
>  /* Device logger functions */
>  #define dev_name(dev)        dt_node_full_name(dev->of_node)
>  #define dev_dbg(dev, fmt, ...)                       \
> @@ -159,12 +150,6 @@ typedef unsigned int             gfp_t;
>  #define readl_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us)    
> \
>       readx_poll_timeout(readl_relaxed, addr, val, cond, delay_us, timeout_us)
>  
> -#define FIELD_PREP(_mask, _val)                      \
> -     (((typeof(_mask))(_val) << (ffs64(_mask) - 1)) & (_mask))
> -
> -#define FIELD_GET(_mask, _reg)                       \
> -     ((typeof(_mask))(((_reg) & (_mask)) >> (ffs64(_mask) - 1)))
> -
>  /*
>   * Helpers for DMA allocation. Just the function name is reused for
>   * porting code, these allocation are not managed allocations
> @@ -197,27 +182,6 @@ static void *dmam_alloc_coherent(struct device *dev, 
> size_t size,
>       return vaddr;
>  }
>  
> -
> -/* Xen specific code. */
> -struct iommu_domain {
> -     /* Runtime SMMU configuration for this iommu_domain */
> -     atomic_t                ref;
> -     /*
> -      * Used to link iommu_domain contexts for a same domain.
> -      * There is at least one per-SMMU to used by the domain.
> -      */
> -     struct list_head                list;
> -};
> -
> -/* Describes information required for a Xen domain */
> -struct arm_smmu_xen_domain {
> -     spinlock_t              lock;
> -
> -     /* List of iommu domains associated to this domain */
> -     struct list_head        contexts;
> -};
> -
> -
>  /* Keep a list of devices associated with this driver */
>  static DEFINE_SPINLOCK(arm_smmu_devices_lock);
>  static LIST_HEAD(arm_smmu_devices);
> @@ -261,635 +225,8 @@ static int platform_get_irq_byname_optional(struct 
> device *dev,
>  }
>  
>  /* Start of Linux SMMUv3 code */
> -/* MMIO registers */
> -#define ARM_SMMU_IDR0                        0x0
> -#define IDR0_ST_LVL                  GENMASK(28, 27)
> -#define IDR0_ST_LVL_2LVL             1
> -#define IDR0_STALL_MODEL             GENMASK(25, 24)
> -#define IDR0_STALL_MODEL_STALL               0
> -#define IDR0_STALL_MODEL_FORCE               2
> -#define IDR0_TTENDIAN                        GENMASK(22, 21)
> -#define IDR0_TTENDIAN_MIXED          0
> -#define IDR0_TTENDIAN_LE             2
> -#define IDR0_TTENDIAN_BE             3
> -#define IDR0_CD2L                    (1 << 19)
> -#define IDR0_VMID16                  (1 << 18)
> -#define IDR0_PRI                     (1 << 16)
> -#define IDR0_SEV                     (1 << 14)
> -#define IDR0_MSI                     (1 << 13)
> -#define IDR0_ASID16                  (1 << 12)
> -#define IDR0_ATS                     (1 << 10)
> -#define IDR0_HYP                     (1 << 9)
> -#define IDR0_COHACC                  (1 << 4)
> -#define IDR0_TTF                     GENMASK(3, 2)
> -#define IDR0_TTF_AARCH64             2
> -#define IDR0_TTF_AARCH32_64          3
> -#define IDR0_S1P                     (1 << 1)
> -#define IDR0_S2P                     (1 << 0)
> -
> -#define ARM_SMMU_IDR1                        0x4
> -#define IDR1_TABLES_PRESET           (1 << 30)
> -#define IDR1_QUEUES_PRESET           (1 << 29)
> -#define IDR1_REL                     (1 << 28)
> -#define IDR1_CMDQS                   GENMASK(25, 21)
> -#define IDR1_EVTQS                   GENMASK(20, 16)
> -#define IDR1_PRIQS                   GENMASK(15, 11)
> -#define IDR1_SSIDSIZE                        GENMASK(10, 6)
> -#define IDR1_SIDSIZE                 GENMASK(5, 0)
> -
> -#define ARM_SMMU_IDR5                        0x14
> -#define IDR5_STALL_MAX                       GENMASK(31, 16)
> -#define IDR5_GRAN64K                 (1 << 6)
> -#define IDR5_GRAN16K                 (1 << 5)
> -#define IDR5_GRAN4K                  (1 << 4)
> -#define IDR5_OAS                     GENMASK(2, 0)
> -#define IDR5_OAS_32_BIT                      0
> -#define IDR5_OAS_36_BIT                      1
> -#define IDR5_OAS_40_BIT                      2
> -#define IDR5_OAS_42_BIT                      3
> -#define IDR5_OAS_44_BIT                      4
> -#define IDR5_OAS_48_BIT                      5
> -#define IDR5_OAS_52_BIT                      6
> -#define IDR5_VAX                     GENMASK(11, 10)
> -#define IDR5_VAX_52_BIT                      1
> -
> -#define ARM_SMMU_CR0                 0x20
> -#define CR0_ATSCHK                   (1 << 4)
> -#define CR0_CMDQEN                   (1 << 3)
> -#define CR0_EVTQEN                   (1 << 2)
> -#define CR0_PRIQEN                   (1 << 1)
> -#define CR0_SMMUEN                   (1 << 0)
> -
> -#define ARM_SMMU_CR0ACK                      0x24
> -
> -#define ARM_SMMU_CR1                 0x28
> -#define CR1_TABLE_SH                 GENMASK(11, 10)
> -#define CR1_TABLE_OC                 GENMASK(9, 8)
> -#define CR1_TABLE_IC                 GENMASK(7, 6)
> -#define CR1_QUEUE_SH                 GENMASK(5, 4)
> -#define CR1_QUEUE_OC                 GENMASK(3, 2)
> -#define CR1_QUEUE_IC                 GENMASK(1, 0)
> -/* CR1 cacheability fields don't quite follow the usual TCR-style encoding */
> -#define CR1_CACHE_NC                 0
> -#define CR1_CACHE_WB                 1
> -#define CR1_CACHE_WT                 2
> -
> -#define ARM_SMMU_CR2                 0x2c
> -#define CR2_PTM                              (1 << 2)
> -#define CR2_RECINVSID                        (1 << 1)
> -#define CR2_E2H                              (1 << 0)
> -
> -#define ARM_SMMU_GBPA                        0x44
> -#define GBPA_UPDATE                  (1U << 31)
> -#define GBPA_ABORT                   (1 << 20)
> -
> -#define ARM_SMMU_IRQ_CTRL            0x50
> -#define IRQ_CTRL_EVTQ_IRQEN          (1 << 2)
> -#define IRQ_CTRL_PRIQ_IRQEN          (1 << 1)
> -#define IRQ_CTRL_GERROR_IRQEN                (1 << 0)
> -
> -#define ARM_SMMU_IRQ_CTRLACK         0x54
> -
> -#define ARM_SMMU_GERROR                      0x60
> -#define GERROR_SFM_ERR                       (1 << 8)
> -#define GERROR_MSI_GERROR_ABT_ERR    (1 << 7)
> -#define GERROR_MSI_PRIQ_ABT_ERR              (1 << 6)
> -#define GERROR_MSI_EVTQ_ABT_ERR              (1 << 5)
> -#define GERROR_MSI_CMDQ_ABT_ERR              (1 << 4)
> -#define GERROR_PRIQ_ABT_ERR          (1 << 3)
> -#define GERROR_EVTQ_ABT_ERR          (1 << 2)
> -#define GERROR_CMDQ_ERR                      (1 << 0)
> -#define GERROR_ERR_MASK                      0xfd
> -
> -#define ARM_SMMU_GERRORN             0x64
> -
> -#define ARM_SMMU_GERROR_IRQ_CFG0     0x68
> -#define ARM_SMMU_GERROR_IRQ_CFG1     0x70
> -#define ARM_SMMU_GERROR_IRQ_CFG2     0x74
> -
> -#define ARM_SMMU_STRTAB_BASE         0x80
> -#define STRTAB_BASE_RA                       (1UL << 62)
> -#define STRTAB_BASE_ADDR_MASK                GENMASK_ULL(51, 6)
> -
> -#define ARM_SMMU_STRTAB_BASE_CFG     0x88
> -#define STRTAB_BASE_CFG_FMT          GENMASK(17, 16)
> -#define STRTAB_BASE_CFG_FMT_LINEAR   0
> -#define STRTAB_BASE_CFG_FMT_2LVL     1
> -#define STRTAB_BASE_CFG_SPLIT                GENMASK(10, 6)
> -#define STRTAB_BASE_CFG_LOG2SIZE     GENMASK(5, 0)
> -
> -#define ARM_SMMU_CMDQ_BASE           0x90
> -#define ARM_SMMU_CMDQ_PROD           0x98
> -#define ARM_SMMU_CMDQ_CONS           0x9c
> -
> -#define ARM_SMMU_EVTQ_BASE           0xa0
> -#define ARM_SMMU_EVTQ_PROD           0x100a8
> -#define ARM_SMMU_EVTQ_CONS           0x100ac
> -#define ARM_SMMU_EVTQ_IRQ_CFG0               0xb0
> -#define ARM_SMMU_EVTQ_IRQ_CFG1               0xb8
> -#define ARM_SMMU_EVTQ_IRQ_CFG2               0xbc
> -
> -#define ARM_SMMU_PRIQ_BASE           0xc0
> -#define ARM_SMMU_PRIQ_PROD           0x100c8
> -#define ARM_SMMU_PRIQ_CONS           0x100cc
> -#define ARM_SMMU_PRIQ_IRQ_CFG0               0xd0
> -#define ARM_SMMU_PRIQ_IRQ_CFG1               0xd8
> -#define ARM_SMMU_PRIQ_IRQ_CFG2               0xdc
> -
> -#define ARM_SMMU_REG_SZ                      0xe00
> -
> -/* Common MSI config fields */
> -#define MSI_CFG0_ADDR_MASK           GENMASK_ULL(51, 2)
> -#define MSI_CFG2_SH                  GENMASK(5, 4)
> -#define MSI_CFG2_MEMATTR             GENMASK(3, 0)
> -
> -/* Common memory attribute values */
> -#define ARM_SMMU_SH_NSH                      0
> -#define ARM_SMMU_SH_OSH                      2
> -#define ARM_SMMU_SH_ISH                      3
> -#define ARM_SMMU_MEMATTR_DEVICE_nGnRE        0x1
> -#define ARM_SMMU_MEMATTR_OIWB                0xf
> -
> -#define Q_IDX(llq, p)                        ((p) & ((1 << 
> (llq)->max_n_shift) - 1))
> -#define Q_WRP(llq, p)                        ((p) & (1 << 
> (llq)->max_n_shift))
> -#define Q_OVERFLOW_FLAG                      (1U << 31)
> -#define Q_OVF(p)                     ((p) & Q_OVERFLOW_FLAG)
> -#define Q_ENT(q, p)                  ((q)->base +                    \
> -                                      Q_IDX(&((q)->llq), p) *        \
> -                                      (q)->ent_dwords)
> -
> -#define Q_BASE_RWA                   (1UL << 62)
> -#define Q_BASE_ADDR_MASK             GENMASK_ULL(51, 5)
> -#define Q_BASE_LOG2SIZE                      GENMASK(4, 0)
> -
> -/* Ensure DMA allocations are naturally aligned */
> -#ifdef CONFIG_CMA_ALIGNMENT
> -#define Q_MAX_SZ_SHIFT                       (PAGE_SHIFT + 
> CONFIG_CMA_ALIGNMENT)
> -#else
> -#define Q_MAX_SZ_SHIFT                       (PAGE_SHIFT + MAX_ORDER - 1)
> -#endif
> -
> -/*
> - * Stream table.
> - *
> - * Linear: Enough to cover 1 << IDR1.SIDSIZE entries
> - * 2lvl: 128k L1 entries,
> - *       256 lazy entries per table (each table covers a PCI bus)
> - */
> -#define STRTAB_L1_SZ_SHIFT           20
> -#define STRTAB_SPLIT                 8
> -
> -#define STRTAB_L1_DESC_DWORDS                1
> -#define STRTAB_L1_DESC_SPAN          GENMASK_ULL(4, 0)
> -#define STRTAB_L1_DESC_L2PTR_MASK    GENMASK_ULL(51, 6)
> -
> -#define STRTAB_STE_DWORDS            8
> -#define STRTAB_STE_0_V                       (1UL << 0)
> -#define STRTAB_STE_0_CFG             GENMASK_ULL(3, 1)
> -#define STRTAB_STE_0_CFG_ABORT               0
> -#define STRTAB_STE_0_CFG_BYPASS              4
> -#define STRTAB_STE_0_CFG_S1_TRANS    5
> -#define STRTAB_STE_0_CFG_S2_TRANS    6
> -
> -#define STRTAB_STE_0_S1FMT           GENMASK_ULL(5, 4)
> -#define STRTAB_STE_0_S1FMT_LINEAR    0
> -#define STRTAB_STE_0_S1FMT_64K_L2    2
> -#define STRTAB_STE_0_S1CTXPTR_MASK   GENMASK_ULL(51, 6)
> -#define STRTAB_STE_0_S1CDMAX         GENMASK_ULL(63, 59)
> -
> -#define STRTAB_STE_1_S1DSS           GENMASK_ULL(1, 0)
> -#define STRTAB_STE_1_S1DSS_TERMINATE 0x0
> -#define STRTAB_STE_1_S1DSS_BYPASS    0x1
> -#define STRTAB_STE_1_S1DSS_SSID0     0x2
> -
> -#define STRTAB_STE_1_S1C_CACHE_NC    0UL
> -#define STRTAB_STE_1_S1C_CACHE_WBRA  1UL
> -#define STRTAB_STE_1_S1C_CACHE_WT    2UL
> -#define STRTAB_STE_1_S1C_CACHE_WB    3UL
> -#define STRTAB_STE_1_S1CIR           GENMASK_ULL(3, 2)
> -#define STRTAB_STE_1_S1COR           GENMASK_ULL(5, 4)
> -#define STRTAB_STE_1_S1CSH           GENMASK_ULL(7, 6)
> -
> -#define STRTAB_STE_1_S1STALLD                (1UL << 27)
> -
> -#define STRTAB_STE_1_EATS            GENMASK_ULL(29, 28)
> -#define STRTAB_STE_1_EATS_ABT                0UL
> -#define STRTAB_STE_1_EATS_TRANS              1UL
> -#define STRTAB_STE_1_EATS_S1CHK              2UL
> -
> -#define STRTAB_STE_1_STRW            GENMASK_ULL(31, 30)
> -#define STRTAB_STE_1_STRW_NSEL1              0UL
> -#define STRTAB_STE_1_STRW_EL2                2UL
> -
> -#define STRTAB_STE_1_SHCFG           GENMASK_ULL(45, 44)
> -#define STRTAB_STE_1_SHCFG_INCOMING  1UL
> -
> -#define STRTAB_STE_2_S2VMID          GENMASK_ULL(15, 0)
> -#define STRTAB_STE_2_VTCR            GENMASK_ULL(50, 32)
> -#define STRTAB_STE_2_VTCR_S2T0SZ     GENMASK_ULL(5, 0)
> -#define STRTAB_STE_2_VTCR_S2SL0              GENMASK_ULL(7, 6)
> -#define STRTAB_STE_2_VTCR_S2IR0              GENMASK_ULL(9, 8)
> -#define STRTAB_STE_2_VTCR_S2OR0              GENMASK_ULL(11, 10)
> -#define STRTAB_STE_2_VTCR_S2SH0              GENMASK_ULL(13, 12)
> -#define STRTAB_STE_2_VTCR_S2TG               GENMASK_ULL(15, 14)
> -#define STRTAB_STE_2_VTCR_S2PS               GENMASK_ULL(18, 16)
> -#define STRTAB_STE_2_S2AA64          (1UL << 51)
> -#define STRTAB_STE_2_S2ENDI          (1UL << 52)
> -#define STRTAB_STE_2_S2PTW           (1UL << 54)
> -#define STRTAB_STE_2_S2R             (1UL << 58)
> -
> -#define STRTAB_STE_3_S2TTB_MASK              GENMASK_ULL(51, 4)
> -
> -/*
> - * Context descriptors.
> - *
> - * Linear: when less than 1024 SSIDs are supported
> - * 2lvl: at most 1024 L1 entries,
> - *       1024 lazy entries per table.
> - */
> -#define CTXDESC_SPLIT                        10
> -#define CTXDESC_L2_ENTRIES           (1 << CTXDESC_SPLIT)
> -
> -#define CTXDESC_L1_DESC_DWORDS               1
> -#define CTXDESC_L1_DESC_V            (1UL << 0)
> -#define CTXDESC_L1_DESC_L2PTR_MASK   GENMASK_ULL(51, 12)
> -
> -#define CTXDESC_CD_DWORDS            8
> -#define CTXDESC_CD_0_TCR_T0SZ                GENMASK_ULL(5, 0)
> -#define CTXDESC_CD_0_TCR_TG0         GENMASK_ULL(7, 6)
> -#define CTXDESC_CD_0_TCR_IRGN0               GENMASK_ULL(9, 8)
> -#define CTXDESC_CD_0_TCR_ORGN0               GENMASK_ULL(11, 10)
> -#define CTXDESC_CD_0_TCR_SH0         GENMASK_ULL(13, 12)
> -#define CTXDESC_CD_0_TCR_EPD0                (1ULL << 14)
> -#define CTXDESC_CD_0_TCR_EPD1                (1ULL << 30)
> -
> -#define CTXDESC_CD_0_ENDI            (1UL << 15)
> -#define CTXDESC_CD_0_V                       (1UL << 31)
> -
> -#define CTXDESC_CD_0_TCR_IPS         GENMASK_ULL(34, 32)
> -#define CTXDESC_CD_0_TCR_TBI0                (1ULL << 38)
> -
> -#define CTXDESC_CD_0_AA64            (1UL << 41)
> -#define CTXDESC_CD_0_S                       (1UL << 44)
> -#define CTXDESC_CD_0_R                       (1UL << 45)
> -#define CTXDESC_CD_0_A                       (1UL << 46)
> -#define CTXDESC_CD_0_ASET            (1UL << 47)
> -#define CTXDESC_CD_0_ASID            GENMASK_ULL(63, 48)
> -
> -#define CTXDESC_CD_1_TTB0_MASK               GENMASK_ULL(51, 4)
> -
> -/*
> - * When the SMMU only supports linear context descriptor tables, pick a
> - * reasonable size limit (64kB).
> - */
> -#define CTXDESC_LINEAR_CDMAX         ilog2(SZ_64K / (CTXDESC_CD_DWORDS << 3))
> -
> -/* Command queue */
> -#define CMDQ_ENT_SZ_SHIFT            4
> -#define CMDQ_ENT_DWORDS                      ((1 << CMDQ_ENT_SZ_SHIFT) >> 3)
> -#define CMDQ_MAX_SZ_SHIFT            (Q_MAX_SZ_SHIFT - CMDQ_ENT_SZ_SHIFT)
> -
> -#define CMDQ_CONS_ERR                        GENMASK(30, 24)
> -#define CMDQ_ERR_CERROR_NONE_IDX     0
> -#define CMDQ_ERR_CERROR_ILL_IDX              1
> -#define CMDQ_ERR_CERROR_ABT_IDX              2
> -#define CMDQ_ERR_CERROR_ATC_INV_IDX  3
> -
> -#define CMDQ_0_OP                    GENMASK_ULL(7, 0)
> -#define CMDQ_0_SSV                   (1UL << 11)
> -
> -#define CMDQ_PREFETCH_0_SID          GENMASK_ULL(63, 32)
> -#define CMDQ_PREFETCH_1_SIZE         GENMASK_ULL(4, 0)
> -#define CMDQ_PREFETCH_1_ADDR_MASK    GENMASK_ULL(63, 12)
> -
> -#define CMDQ_CFGI_0_SSID             GENMASK_ULL(31, 12)
> -#define CMDQ_CFGI_0_SID                      GENMASK_ULL(63, 32)
> -#define CMDQ_CFGI_1_LEAF             (1UL << 0)
> -#define CMDQ_CFGI_1_RANGE            GENMASK_ULL(4, 0)
> -
> -#define CMDQ_TLBI_0_VMID             GENMASK_ULL(47, 32)
> -#define CMDQ_TLBI_0_ASID             GENMASK_ULL(63, 48)
> -#define CMDQ_TLBI_1_LEAF             (1UL << 0)
> -#define CMDQ_TLBI_1_VA_MASK          GENMASK_ULL(63, 12)
> -#define CMDQ_TLBI_1_IPA_MASK         GENMASK_ULL(51, 12)
> -
> -#define CMDQ_ATC_0_SSID                      GENMASK_ULL(31, 12)
> -#define CMDQ_ATC_0_SID                       GENMASK_ULL(63, 32)
> -#define CMDQ_ATC_0_GLOBAL            (1UL << 9)
> -#define CMDQ_ATC_1_SIZE                      GENMASK_ULL(5, 0)
> -#define CMDQ_ATC_1_ADDR_MASK         GENMASK_ULL(63, 12)
> -
> -#define CMDQ_PRI_0_SSID                      GENMASK_ULL(31, 12)
> -#define CMDQ_PRI_0_SID                       GENMASK_ULL(63, 32)
> -#define CMDQ_PRI_1_GRPID             GENMASK_ULL(8, 0)
> -#define CMDQ_PRI_1_RESP                      GENMASK_ULL(13, 12)
> -
> -#define CMDQ_SYNC_0_CS                       GENMASK_ULL(13, 12)
> -#define CMDQ_SYNC_0_CS_NONE          0
> -#define CMDQ_SYNC_0_CS_IRQ           1
> -#define CMDQ_SYNC_0_CS_SEV           2
> -#define CMDQ_SYNC_0_MSH                      GENMASK_ULL(23, 22)
> -#define CMDQ_SYNC_0_MSIATTR          GENMASK_ULL(27, 24)
> -#define CMDQ_SYNC_0_MSIDATA          GENMASK_ULL(63, 32)
> -#define CMDQ_SYNC_1_MSIADDR_MASK     GENMASK_ULL(51, 2)
> -
> -/* Event queue */
> -#define EVTQ_ENT_SZ_SHIFT            5
> -#define EVTQ_ENT_DWORDS                      ((1 << EVTQ_ENT_SZ_SHIFT) >> 3)
> -#define EVTQ_MAX_SZ_SHIFT            (Q_MAX_SZ_SHIFT - EVTQ_ENT_SZ_SHIFT)
> -
> -#define EVTQ_0_ID                    GENMASK_ULL(7, 0)
> -
> -/* PRI queue */
> -#define PRIQ_ENT_SZ_SHIFT            4
> -#define PRIQ_ENT_DWORDS                      ((1 << PRIQ_ENT_SZ_SHIFT) >> 3)
> -#define PRIQ_MAX_SZ_SHIFT            (Q_MAX_SZ_SHIFT - PRIQ_ENT_SZ_SHIFT)
> -
> -#define PRIQ_0_SID                   GENMASK_ULL(31, 0)
> -#define PRIQ_0_SSID                  GENMASK_ULL(51, 32)
> -#define PRIQ_0_PERM_PRIV             (1UL << 58)
> -#define PRIQ_0_PERM_EXEC             (1UL << 59)
> -#define PRIQ_0_PERM_READ             (1UL << 60)
> -#define PRIQ_0_PERM_WRITE            (1UL << 61)
> -#define PRIQ_0_PRG_LAST                      (1UL << 62)
> -#define PRIQ_0_SSID_V                        (1UL << 63)
> -
> -#define PRIQ_1_PRG_IDX                       GENMASK_ULL(8, 0)
> -#define PRIQ_1_ADDR_MASK             GENMASK_ULL(63, 12)
> -
> -/* High-level queue structures */
> -#define ARM_SMMU_POLL_TIMEOUT_US     100
> -#define ARM_SMMU_CMDQ_SYNC_TIMEOUT_US        1000000 /* 1s! */
> -#define ARM_SMMU_CMDQ_SYNC_SPIN_COUNT        10
> -
>  static bool disable_bypass = 1;
>  
> -enum pri_resp {
> -     PRI_RESP_DENY = 0,
> -     PRI_RESP_FAIL = 1,
> -     PRI_RESP_SUCC = 2,
> -};
> -
> -#ifdef CONFIG_MSI
> -enum arm_smmu_msi_index {
> -     EVTQ_MSI_INDEX,
> -     GERROR_MSI_INDEX,
> -     PRIQ_MSI_INDEX,
> -     ARM_SMMU_MAX_MSIS,
> -};
> -
> -static phys_addr_t arm_smmu_msi_cfg[ARM_SMMU_MAX_MSIS][3] = {
> -     [EVTQ_MSI_INDEX] = {
> -             ARM_SMMU_EVTQ_IRQ_CFG0,
> -             ARM_SMMU_EVTQ_IRQ_CFG1,
> -             ARM_SMMU_EVTQ_IRQ_CFG2,
> -     },
> -     [GERROR_MSI_INDEX] = {
> -             ARM_SMMU_GERROR_IRQ_CFG0,
> -             ARM_SMMU_GERROR_IRQ_CFG1,
> -             ARM_SMMU_GERROR_IRQ_CFG2,
> -     },
> -     [PRIQ_MSI_INDEX] = {
> -             ARM_SMMU_PRIQ_IRQ_CFG0,
> -             ARM_SMMU_PRIQ_IRQ_CFG1,
> -             ARM_SMMU_PRIQ_IRQ_CFG2,
> -     },
> -};
> -#endif /* CONFIG_MSI */
> -
> -struct arm_smmu_cmdq_ent {
> -     /* Common fields */
> -     u8                              opcode;
> -     bool                            substream_valid;
> -
> -     /* Command-specific fields */
> -     union {
> -             #define CMDQ_OP_PREFETCH_CFG    0x1
> -             struct {
> -                     u32                     sid;
> -                     u8                      size;
> -                     u64                     addr;
> -             } prefetch;
> -
> -             #define CMDQ_OP_CFGI_STE        0x3
> -             #define CMDQ_OP_CFGI_ALL        0x4
> -             struct {
> -                     u32                     sid;
> -                     union {
> -                             bool            leaf;
> -                             u8              span;
> -                     };
> -             } cfgi;
> -
> -             #define CMDQ_OP_TLBI_EL2_ALL    0x20
> -             #define CMDQ_OP_TLBI_S12_VMALL  0x28
> -             #define CMDQ_OP_TLBI_S2_IPA     0x2a
> -             #define CMDQ_OP_TLBI_NSNH_ALL   0x30
> -             struct {
> -                     u16                     asid;
> -                     u16                     vmid;
> -                     bool                    leaf;
> -                     u64                     addr;
> -             } tlbi;
> -
> -             #define CMDQ_OP_ATC_INV         0x40
> -             #define ATC_INV_SIZE_ALL        52
> -             struct {
> -                     u32                     sid;
> -                     u32                     ssid;
> -                     u64                     addr;
> -                     u8                      size;
> -                     bool                    global;
> -             } atc;
> -
> -             #define CMDQ_OP_PRI_RESP        0x41
> -             struct {
> -                     u32                     sid;
> -                     u32                     ssid;
> -                     u16                     grpid;
> -                     enum pri_resp           resp;
> -             } pri;
> -
> -             #define CMDQ_OP_CMD_SYNC        0x46
> -             struct {
> -                     u32                     msidata;
> -                     u64                     msiaddr;
> -             } sync;
> -     };
> -};
> -
> -struct arm_smmu_ll_queue {
> -     u32                             prod;
> -     u32                             cons;
> -     u32                             max_n_shift;
> -};
> -
> -struct arm_smmu_queue {
> -     struct arm_smmu_ll_queue        llq;
> -     int                             irq; /* Wired interrupt */
> -
> -     __le64                          *base;
> -     dma_addr_t                      base_dma;
> -     u64                             q_base;
> -
> -     size_t                          ent_dwords;
> -
> -     u32 __iomem                     *prod_reg;
> -     u32 __iomem                     *cons_reg;
> -};
> -
> -struct arm_smmu_cmdq {
> -     struct arm_smmu_queue           q;
> -     spinlock_t                      lock;
> -};
> -
> -struct arm_smmu_evtq {
> -     struct arm_smmu_queue           q;
> -     u32                             max_stalls;
> -};
> -
> -struct arm_smmu_priq {
> -     struct arm_smmu_queue           q;
> -};
> -
> -/* High-level stream table and context descriptor structures */
> -struct arm_smmu_strtab_l1_desc {
> -     u8                              span;
> -
> -     __le64                          *l2ptr;
> -     dma_addr_t                      l2ptr_dma;
> -};
> -
> -struct arm_smmu_s2_cfg {
> -     u16                             vmid;
> -     u64                             vttbr;
> -     u64                             vtcr;
> -};
> -
> -struct arm_smmu_strtab_cfg {
> -     __le64                          *strtab;
> -     dma_addr_t                      strtab_dma;
> -     struct arm_smmu_strtab_l1_desc  *l1_desc;
> -     unsigned int                    num_l1_ents;
> -
> -     u64                             strtab_base;
> -     u32                             strtab_base_cfg;
> -};
> -
> -struct arm_lpae_s2_cfg {
> -     u64                     vttbr;
> -     struct {
> -             u32                     ps:3;
> -             u32                     tg:2;
> -             u32                     sh:2;
> -             u32                     orgn:2;
> -             u32                     irgn:2;
> -             u32                     sl:2;
> -             u32                     tsz:6;
> -     } vtcr;
> -};
> -
> -/* An SMMUv3 instance */
> -struct arm_smmu_device {
> -     struct device                   *dev;
> -     void __iomem                    *base;
> -     void __iomem                    *page1;
> -
> -#define ARM_SMMU_FEAT_2_LVL_STRTAB   (1 << 0)
> -#define ARM_SMMU_FEAT_2_LVL_CDTAB    (1 << 1)
> -#define ARM_SMMU_FEAT_TT_LE          (1 << 2)
> -#define ARM_SMMU_FEAT_TT_BE          (1 << 3)
> -#define ARM_SMMU_FEAT_PRI            (1 << 4)
> -#define ARM_SMMU_FEAT_ATS            (1 << 5)
> -#define ARM_SMMU_FEAT_SEV            (1 << 6)
> -#define ARM_SMMU_FEAT_MSI            (1 << 7)
> -#define ARM_SMMU_FEAT_COHERENCY              (1 << 8)
> -#define ARM_SMMU_FEAT_TRANS_S1               (1 << 9)
> -#define ARM_SMMU_FEAT_TRANS_S2               (1 << 10)
> -#define ARM_SMMU_FEAT_STALLS         (1 << 11)
> -#define ARM_SMMU_FEAT_HYP            (1 << 12)
> -#define ARM_SMMU_FEAT_STALL_FORCE    (1 << 13)
> -#define ARM_SMMU_FEAT_VAX            (1 << 14)
> -     u32                             features;
> -
> -#define ARM_SMMU_OPT_SKIP_PREFETCH   (1 << 0)
> -#define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1)
> -     u32                             options;
> -
> -     struct arm_smmu_cmdq            cmdq;
> -     struct arm_smmu_evtq            evtq;
> -     struct arm_smmu_priq            priq;
> -
> -     int                             gerr_irq;
> -     int                             combined_irq;
> -     u32                             sync_nr;
> -     u8                              prev_cmd_opcode;
> -
> -     unsigned long                   ias; /* IPA */
> -     unsigned long                   oas; /* PA */
> -     unsigned long                   pgsize_bitmap;
> -
> -#define ARM_SMMU_MAX_VMIDS           (1 << 16)
> -     unsigned int                    vmid_bits;
> -     DECLARE_BITMAP(vmid_map, ARM_SMMU_MAX_VMIDS);
> -
> -     unsigned int                    sid_bits;
> -
> -     struct arm_smmu_strtab_cfg      strtab_cfg;
> -
> -     /* Hi16xx adds an extra 32 bits of goodness to its MSI payload */
> -     union {
> -             u32                     sync_count;
> -             u64                     padding;
> -     };
> -
> -     /* Need to keep a list of SMMU devices */
> -     struct list_head                devices;
> -
> -     /* Tasklets for handling evts/faults and pci page request IRQs*/
> -     struct tasklet          evtq_irq_tasklet;
> -     struct tasklet          priq_irq_tasklet;
> -     struct tasklet          combined_irq_tasklet;
> -};
> -
> -/* SMMU private data for each master */
> -struct arm_smmu_master {
> -     struct arm_smmu_device          *smmu;
> -     struct device                   *dev;
> -     struct arm_smmu_domain          *domain;
> -     struct list_head                domain_head;
> -     u32                             *sids;
> -     unsigned int                    num_sids;
> -     bool                            ats_enabled;
> -};
> -
> -/* SMMU private data for an IOMMU domain */
> -enum arm_smmu_domain_stage {
> -     ARM_SMMU_DOMAIN_S1 = 0,
> -     ARM_SMMU_DOMAIN_S2,
> -     ARM_SMMU_DOMAIN_NESTED,
> -     ARM_SMMU_DOMAIN_BYPASS,
> -};
> -
> -struct arm_smmu_domain {
> -     struct arm_smmu_device          *smmu;
> -     struct mutex                    init_mutex; /* Protects smmu pointer */
> -
> -     bool                            non_strict;
> -     atomic_t                        nr_ats_masters;
> -
> -     enum arm_smmu_domain_stage      stage;
> -     struct arm_smmu_s2_cfg  s2_cfg;
> -
> -     /* Xen domain associated with this SMMU domain */
> -     struct domain           *d;
> -
> -     struct iommu_domain             domain;
> -
> -     struct list_head                devices;
> -     spinlock_t                      devices_lock;
> -};
> -
>  struct arm_smmu_option_prop {
>       u32 opt;
>       const char *prop;
> diff --git a/xen/drivers/passthrough/arm/smmu-v3.h 
> b/xen/drivers/passthrough/arm/smmu-v3.h
> new file mode 100644
> index 0000000000..c45d2f16c4
> --- /dev/null
> +++ b/xen/drivers/passthrough/arm/smmu-v3.h
> @@ -0,0 +1,674 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * IOMMU API for ARM architected SMMUv3 implementations.
> + *
> + * Copyright (C) 2022 ARM Limited
> + */
> +
> +#ifndef _ARM_SMMU_V3_H
> +#define _ARM_SMMU_V3_H
> +
> +/* MMIO registers */
> +#define ARM_SMMU_IDR0                        0x0
> +#define IDR0_ST_LVL                  GENMASK(28, 27)
> +#define IDR0_ST_LVL_2LVL             1
> +#define IDR0_STALL_MODEL             GENMASK(25, 24)
> +#define IDR0_STALL_MODEL_STALL               0
> +#define IDR0_STALL_MODEL_FORCE               2
> +#define IDR0_TTENDIAN                        GENMASK(22, 21)
> +#define IDR0_TTENDIAN_MIXED          0
> +#define IDR0_TTENDIAN_LE             2
> +#define IDR0_TTENDIAN_BE             3
> +#define IDR0_CD2L                    (1 << 19)
> +#define IDR0_VMID16                  (1 << 18)
> +#define IDR0_PRI                     (1 << 16)
> +#define IDR0_SEV                     (1 << 14)
> +#define IDR0_MSI                     (1 << 13)
> +#define IDR0_ASID16                  (1 << 12)
> +#define IDR0_ATS                     (1 << 10)
> +#define IDR0_HYP                     (1 << 9)
> +#define IDR0_COHACC                  (1 << 4)
> +#define IDR0_TTF                     GENMASK(3, 2)
> +#define IDR0_TTF_AARCH64             2
> +#define IDR0_TTF_AARCH32_64          3
> +#define IDR0_S1P                     (1 << 1)
> +#define IDR0_S2P                     (1 << 0)
> +
> +#define ARM_SMMU_IDR1                        0x4
> +#define IDR1_TABLES_PRESET           (1 << 30)
> +#define IDR1_QUEUES_PRESET           (1 << 29)
> +#define IDR1_REL                     (1 << 28)
> +#define IDR1_CMDQS                   GENMASK(25, 21)
> +#define IDR1_EVTQS                   GENMASK(20, 16)
> +#define IDR1_PRIQS                   GENMASK(15, 11)
> +#define IDR1_SSIDSIZE                        GENMASK(10, 6)
> +#define IDR1_SIDSIZE                 GENMASK(5, 0)
> +
> +#define ARM_SMMU_IDR5                        0x14
> +#define IDR5_STALL_MAX                       GENMASK(31, 16)
> +#define IDR5_GRAN64K                 (1 << 6)
> +#define IDR5_GRAN16K                 (1 << 5)
> +#define IDR5_GRAN4K                  (1 << 4)
> +#define IDR5_OAS                     GENMASK(2, 0)
> +#define IDR5_OAS_32_BIT                      0
> +#define IDR5_OAS_36_BIT                      1
> +#define IDR5_OAS_40_BIT                      2
> +#define IDR5_OAS_42_BIT                      3
> +#define IDR5_OAS_44_BIT                      4
> +#define IDR5_OAS_48_BIT                      5
> +#define IDR5_OAS_52_BIT                      6
> +#define IDR5_VAX                     GENMASK(11, 10)
> +#define IDR5_VAX_52_BIT                      1
> +
> +#define ARM_SMMU_CR0                 0x20
> +#define CR0_ATSCHK                   (1 << 4)
> +#define CR0_CMDQEN                   (1 << 3)
> +#define CR0_EVTQEN                   (1 << 2)
> +#define CR0_PRIQEN                   (1 << 1)
> +#define CR0_SMMUEN                   (1 << 0)
> +
> +#define ARM_SMMU_CR0ACK                      0x24
> +
> +#define ARM_SMMU_CR1                 0x28
> +#define CR1_TABLE_SH                 GENMASK(11, 10)
> +#define CR1_TABLE_OC                 GENMASK(9, 8)
> +#define CR1_TABLE_IC                 GENMASK(7, 6)
> +#define CR1_QUEUE_SH                 GENMASK(5, 4)
> +#define CR1_QUEUE_OC                 GENMASK(3, 2)
> +#define CR1_QUEUE_IC                 GENMASK(1, 0)
> +/* CR1 cacheability fields don't quite follow the usual TCR-style encoding */
> +#define CR1_CACHE_NC                 0
> +#define CR1_CACHE_WB                 1
> +#define CR1_CACHE_WT                 2
> +
> +#define ARM_SMMU_CR2                 0x2c
> +#define CR2_PTM                              (1 << 2)
> +#define CR2_RECINVSID                        (1 << 1)
> +#define CR2_E2H                              (1 << 0)
> +
> +#define ARM_SMMU_GBPA                        0x44
> +#define GBPA_UPDATE                  (1 << 31)
> +#define GBPA_ABORT                   (1 << 20)
> +
> +#define ARM_SMMU_IRQ_CTRL            0x50
> +#define IRQ_CTRL_EVTQ_IRQEN          (1 << 2)
> +#define IRQ_CTRL_PRIQ_IRQEN          (1 << 1)
> +#define IRQ_CTRL_GERROR_IRQEN                (1 << 0)
> +
> +#define ARM_SMMU_IRQ_CTRLACK         0x54
> +
> +#define ARM_SMMU_GERROR                      0x60
> +#define GERROR_SFM_ERR                       (1 << 8)
> +#define GERROR_MSI_GERROR_ABT_ERR    (1 << 7)
> +#define GERROR_MSI_PRIQ_ABT_ERR              (1 << 6)
> +#define GERROR_MSI_EVTQ_ABT_ERR              (1 << 5)
> +#define GERROR_MSI_CMDQ_ABT_ERR              (1 << 4)
> +#define GERROR_PRIQ_ABT_ERR          (1 << 3)
> +#define GERROR_EVTQ_ABT_ERR          (1 << 2)
> +#define GERROR_CMDQ_ERR                      (1 << 0)
> +#define GERROR_ERR_MASK                      0xfd
> +
> +#define ARM_SMMU_GERRORN             0x64
> +
> +#define ARM_SMMU_GERROR_IRQ_CFG0     0x68
> +#define ARM_SMMU_GERROR_IRQ_CFG1     0x70
> +#define ARM_SMMU_GERROR_IRQ_CFG2     0x74
> +
> +#define ARM_SMMU_STRTAB_BASE         0x80
> +#define STRTAB_BASE_RA                       (1UL << 62)
> +#define STRTAB_BASE_ADDR_MASK                GENMASK_ULL(51, 6)
> +
> +#define ARM_SMMU_STRTAB_BASE_CFG     0x88
> +#define STRTAB_BASE_CFG_FMT          GENMASK(17, 16)
> +#define STRTAB_BASE_CFG_FMT_LINEAR   0
> +#define STRTAB_BASE_CFG_FMT_2LVL     1
> +#define STRTAB_BASE_CFG_SPLIT                GENMASK(10, 6)
> +#define STRTAB_BASE_CFG_LOG2SIZE     GENMASK(5, 0)
> +
> +#define ARM_SMMU_CMDQ_BASE           0x90
> +#define ARM_SMMU_CMDQ_PROD           0x98
> +#define ARM_SMMU_CMDQ_CONS           0x9c
> +
> +#define ARM_SMMU_EVTQ_BASE           0xa0
> +#define ARM_SMMU_EVTQ_PROD           0x100a8
> +#define ARM_SMMU_EVTQ_CONS           0x100ac
> +#define ARM_SMMU_EVTQ_IRQ_CFG0               0xb0
> +#define ARM_SMMU_EVTQ_IRQ_CFG1               0xb8
> +#define ARM_SMMU_EVTQ_IRQ_CFG2               0xbc
> +
> +#define ARM_SMMU_PRIQ_BASE           0xc0
> +#define ARM_SMMU_PRIQ_PROD           0x100c8
> +#define ARM_SMMU_PRIQ_CONS           0x100cc
> +#define ARM_SMMU_PRIQ_IRQ_CFG0               0xd0
> +#define ARM_SMMU_PRIQ_IRQ_CFG1               0xd8
> +#define ARM_SMMU_PRIQ_IRQ_CFG2               0xdc
> +
> +#define ARM_SMMU_REG_SZ                      0xe00
> +
> +/* Common MSI config fields */
> +#define MSI_CFG0_ADDR_MASK           GENMASK_ULL(51, 2)
> +#define MSI_CFG2_SH                  GENMASK(5, 4)
> +#define MSI_CFG2_MEMATTR             GENMASK(3, 0)
> +
> +/* Common memory attribute values */
> +#define ARM_SMMU_SH_NSH                      0
> +#define ARM_SMMU_SH_OSH                      2
> +#define ARM_SMMU_SH_ISH                      3
> +#define ARM_SMMU_MEMATTR_DEVICE_nGnRE        0x1
> +#define ARM_SMMU_MEMATTR_OIWB                0xf
> +
> +#define Q_IDX(llq, p)                        ((p) & ((1 << 
> (llq)->max_n_shift) - 1))
> +#define Q_WRP(llq, p)                        ((p) & (1 << 
> (llq)->max_n_shift))
> +#define Q_OVERFLOW_FLAG                      (1 << 31)
> +#define Q_OVF(p)                     ((p) & Q_OVERFLOW_FLAG)
> +#define Q_ENT(q, p)                  ((q)->base +                    \
> +                                      Q_IDX(&((q)->llq), p) *        \
> +                                      (q)->ent_dwords)
> +
> +#define Q_BASE_RWA                   (1UL << 62)
> +#define Q_BASE_ADDR_MASK             GENMASK_ULL(51, 5)
> +#define Q_BASE_LOG2SIZE                      GENMASK(4, 0)
> +
> +/* Ensure DMA allocations are naturally aligned */
> +#ifdef CONFIG_CMA_ALIGNMENT
> +#define Q_MAX_SZ_SHIFT                       (PAGE_SHIFT + 
> CONFIG_CMA_ALIGNMENT)
> +#else
> +#define Q_MAX_SZ_SHIFT                       (PAGE_SHIFT + MAX_ORDER - 1)
> +#endif
> +
> +/*
> + * Stream table.
> + *
> + * Linear: Enough to cover 1 << IDR1.SIDSIZE entries
> + * 2lvl: 128k L1 entries,
> + *       256 lazy entries per table (each table covers a PCI bus)
> + */
> +#define STRTAB_L1_SZ_SHIFT           20
> +#define STRTAB_SPLIT                 8
> +
> +#define STRTAB_L1_DESC_DWORDS                1
> +#define STRTAB_L1_DESC_SPAN          GENMASK_ULL(4, 0)
> +#define STRTAB_L1_DESC_L2PTR_MASK    GENMASK_ULL(51, 6)
> +
> +#define STRTAB_STE_DWORDS            8
> +#define STRTAB_STE_0_V                       (1UL << 0)
> +#define STRTAB_STE_0_CFG             GENMASK_ULL(3, 1)
> +#define STRTAB_STE_0_CFG_ABORT               0
> +#define STRTAB_STE_0_CFG_BYPASS              4
> +#define STRTAB_STE_0_CFG_S1_TRANS    5
> +#define STRTAB_STE_0_CFG_S2_TRANS    6
> +
> +#define STRTAB_STE_0_S1FMT           GENMASK_ULL(5, 4)
> +#define STRTAB_STE_0_S1FMT_LINEAR    0
> +#define STRTAB_STE_0_S1FMT_64K_L2    2
> +#define STRTAB_STE_0_S1CTXPTR_MASK   GENMASK_ULL(51, 6)
> +#define STRTAB_STE_0_S1CDMAX         GENMASK_ULL(63, 59)
> +
> +#define STRTAB_STE_1_S1DSS           GENMASK_ULL(1, 0)
> +#define STRTAB_STE_1_S1DSS_TERMINATE 0x0
> +#define STRTAB_STE_1_S1DSS_BYPASS    0x1
> +#define STRTAB_STE_1_S1DSS_SSID0     0x2
> +
> +#define STRTAB_STE_1_S1C_CACHE_NC    0UL
> +#define STRTAB_STE_1_S1C_CACHE_WBRA  1UL
> +#define STRTAB_STE_1_S1C_CACHE_WT    2UL
> +#define STRTAB_STE_1_S1C_CACHE_WB    3UL
> +#define STRTAB_STE_1_S1CIR           GENMASK_ULL(3, 2)
> +#define STRTAB_STE_1_S1COR           GENMASK_ULL(5, 4)
> +#define STRTAB_STE_1_S1CSH           GENMASK_ULL(7, 6)
> +
> +#define STRTAB_STE_1_S1STALLD                (1UL << 27)
> +
> +#define STRTAB_STE_1_EATS            GENMASK_ULL(29, 28)
> +#define STRTAB_STE_1_EATS_ABT                0UL
> +#define STRTAB_STE_1_EATS_TRANS              1UL
> +#define STRTAB_STE_1_EATS_S1CHK              2UL
> +
> +#define STRTAB_STE_1_STRW            GENMASK_ULL(31, 30)
> +#define STRTAB_STE_1_STRW_NSEL1              0UL
> +#define STRTAB_STE_1_STRW_EL2                2UL
> +
> +#define STRTAB_STE_1_SHCFG           GENMASK_ULL(45, 44)
> +#define STRTAB_STE_1_SHCFG_INCOMING  1UL
> +
> +#define STRTAB_STE_2_S2VMID          GENMASK_ULL(15, 0)
> +#define STRTAB_STE_2_VTCR            GENMASK_ULL(50, 32)
> +#define STRTAB_STE_2_VTCR_S2T0SZ     GENMASK_ULL(5, 0)
> +#define STRTAB_STE_2_VTCR_S2SL0              GENMASK_ULL(7, 6)
> +#define STRTAB_STE_2_VTCR_S2IR0              GENMASK_ULL(9, 8)
> +#define STRTAB_STE_2_VTCR_S2OR0              GENMASK_ULL(11, 10)
> +#define STRTAB_STE_2_VTCR_S2SH0              GENMASK_ULL(13, 12)
> +#define STRTAB_STE_2_VTCR_S2TG               GENMASK_ULL(15, 14)
> +#define STRTAB_STE_2_VTCR_S2PS               GENMASK_ULL(18, 16)
> +#define STRTAB_STE_2_S2AA64          (1UL << 51)
> +#define STRTAB_STE_2_S2ENDI          (1UL << 52)
> +#define STRTAB_STE_2_S2PTW           (1UL << 54)
> +#define STRTAB_STE_2_S2R             (1UL << 58)
> +
> +#define STRTAB_STE_3_S2TTB_MASK              GENMASK_ULL(51, 4)
> +
> +/*
> + * Context descriptors.
> + *
> + * Linear: when less than 1024 SSIDs are supported
> + * 2lvl: at most 1024 L1 entries,
> + *       1024 lazy entries per table.
> + */
> +#define CTXDESC_SPLIT                        10
> +#define CTXDESC_L2_ENTRIES           (1 << CTXDESC_SPLIT)
> +
> +#define CTXDESC_L1_DESC_DWORDS               1
> +#define CTXDESC_L1_DESC_V            (1UL << 0)
> +#define CTXDESC_L1_DESC_L2PTR_MASK   GENMASK_ULL(51, 12)
> +
> +#define CTXDESC_CD_DWORDS            8
> +#define CTXDESC_CD_0_TCR_T0SZ                GENMASK_ULL(5, 0)
> +#define CTXDESC_CD_0_TCR_TG0         GENMASK_ULL(7, 6)
> +#define CTXDESC_CD_0_TCR_IRGN0               GENMASK_ULL(9, 8)
> +#define CTXDESC_CD_0_TCR_ORGN0               GENMASK_ULL(11, 10)
> +#define CTXDESC_CD_0_TCR_SH0         GENMASK_ULL(13, 12)
> +#define CTXDESC_CD_0_TCR_EPD0                (1ULL << 14)
> +#define CTXDESC_CD_0_TCR_EPD1                (1ULL << 30)
> +
> +#define CTXDESC_CD_0_ENDI            (1UL << 15)
> +#define CTXDESC_CD_0_V                       (1UL << 31)
> +
> +#define CTXDESC_CD_0_TCR_IPS         GENMASK_ULL(34, 32)
> +#define CTXDESC_CD_0_TCR_TBI0                (1ULL << 38)
> +
> +#define CTXDESC_CD_0_AA64            (1UL << 41)
> +#define CTXDESC_CD_0_S                       (1UL << 44)
> +#define CTXDESC_CD_0_R                       (1UL << 45)
> +#define CTXDESC_CD_0_A                       (1UL << 46)
> +#define CTXDESC_CD_0_ASET            (1UL << 47)
> +#define CTXDESC_CD_0_ASID            GENMASK_ULL(63, 48)
> +
> +#define CTXDESC_CD_1_TTB0_MASK               GENMASK_ULL(51, 4)
> +
> +/*
> + * When the SMMU only supports linear context descriptor tables, pick a
> + * reasonable size limit (64kB).
> + */
> +#define CTXDESC_LINEAR_CDMAX         ilog2(SZ_64K / (CTXDESC_CD_DWORDS << 3))
> +
> +/* Command queue */
> +#define CMDQ_ENT_SZ_SHIFT            4
> +#define CMDQ_ENT_DWORDS                      ((1 << CMDQ_ENT_SZ_SHIFT) >> 3)
> +#define CMDQ_MAX_SZ_SHIFT            (Q_MAX_SZ_SHIFT - CMDQ_ENT_SZ_SHIFT)
> +
> +#define CMDQ_CONS_ERR                        GENMASK(30, 24)
> +#define CMDQ_ERR_CERROR_NONE_IDX     0
> +#define CMDQ_ERR_CERROR_ILL_IDX              1
> +#define CMDQ_ERR_CERROR_ABT_IDX              2
> +#define CMDQ_ERR_CERROR_ATC_INV_IDX  3
> +
> +#define CMDQ_0_OP                    GENMASK_ULL(7, 0)
> +#define CMDQ_0_SSV                   (1UL << 11)
> +
> +#define CMDQ_PREFETCH_0_SID          GENMASK_ULL(63, 32)
> +#define CMDQ_PREFETCH_1_SIZE         GENMASK_ULL(4, 0)
> +#define CMDQ_PREFETCH_1_ADDR_MASK    GENMASK_ULL(63, 12)
> +
> +#define CMDQ_CFGI_0_SSID             GENMASK_ULL(31, 12)
> +#define CMDQ_CFGI_0_SID                      GENMASK_ULL(63, 32)
> +#define CMDQ_CFGI_1_LEAF             (1UL << 0)
> +#define CMDQ_CFGI_1_RANGE            GENMASK_ULL(4, 0)
> +
> +#define CMDQ_TLBI_0_VMID             GENMASK_ULL(47, 32)
> +#define CMDQ_TLBI_0_ASID             GENMASK_ULL(63, 48)
> +#define CMDQ_TLBI_1_LEAF             (1UL << 0)
> +#define CMDQ_TLBI_1_VA_MASK          GENMASK_ULL(63, 12)
> +#define CMDQ_TLBI_1_IPA_MASK         GENMASK_ULL(51, 12)
> +
> +#define CMDQ_ATC_0_SSID                      GENMASK_ULL(31, 12)
> +#define CMDQ_ATC_0_SID                       GENMASK_ULL(63, 32)
> +#define CMDQ_ATC_0_GLOBAL            (1UL << 9)
> +#define CMDQ_ATC_1_SIZE                      GENMASK_ULL(5, 0)
> +#define CMDQ_ATC_1_ADDR_MASK         GENMASK_ULL(63, 12)
> +
> +#define CMDQ_PRI_0_SSID                      GENMASK_ULL(31, 12)
> +#define CMDQ_PRI_0_SID                       GENMASK_ULL(63, 32)
> +#define CMDQ_PRI_1_GRPID             GENMASK_ULL(8, 0)
> +#define CMDQ_PRI_1_RESP                      GENMASK_ULL(13, 12)
> +
> +#define CMDQ_SYNC_0_CS                       GENMASK_ULL(13, 12)
> +#define CMDQ_SYNC_0_CS_NONE          0
> +#define CMDQ_SYNC_0_CS_IRQ           1
> +#define CMDQ_SYNC_0_CS_SEV           2
> +#define CMDQ_SYNC_0_MSH                      GENMASK_ULL(23, 22)
> +#define CMDQ_SYNC_0_MSIATTR          GENMASK_ULL(27, 24)
> +#define CMDQ_SYNC_0_MSIDATA          GENMASK_ULL(63, 32)
> +#define CMDQ_SYNC_1_MSIADDR_MASK     GENMASK_ULL(51, 2)
> +
> +/* Event queue */
> +#define EVTQ_ENT_SZ_SHIFT            5
> +#define EVTQ_ENT_DWORDS                      ((1 << EVTQ_ENT_SZ_SHIFT) >> 3)
> +#define EVTQ_MAX_SZ_SHIFT            (Q_MAX_SZ_SHIFT - EVTQ_ENT_SZ_SHIFT)
> +
> +#define EVTQ_0_ID                    GENMASK_ULL(7, 0)
> +
> +/* PRI queue */
> +#define PRIQ_ENT_SZ_SHIFT            4
> +#define PRIQ_ENT_DWORDS                      ((1 << PRIQ_ENT_SZ_SHIFT) >> 3)
> +#define PRIQ_MAX_SZ_SHIFT            (Q_MAX_SZ_SHIFT - PRIQ_ENT_SZ_SHIFT)
> +
> +#define PRIQ_0_SID                   GENMASK_ULL(31, 0)
> +#define PRIQ_0_SSID                  GENMASK_ULL(51, 32)
> +#define PRIQ_0_PERM_PRIV             (1UL << 58)
> +#define PRIQ_0_PERM_EXEC             (1UL << 59)
> +#define PRIQ_0_PERM_READ             (1UL << 60)
> +#define PRIQ_0_PERM_WRITE            (1UL << 61)
> +#define PRIQ_0_PRG_LAST                      (1UL << 62)
> +#define PRIQ_0_SSID_V                        (1UL << 63)
> +
> +#define PRIQ_1_PRG_IDX                       GENMASK_ULL(8, 0)
> +#define PRIQ_1_ADDR_MASK             GENMASK_ULL(63, 12)
> +
> +/* High-level queue structures */
> +#define ARM_SMMU_POLL_TIMEOUT_US     100
> +#define ARM_SMMU_CMDQ_SYNC_TIMEOUT_US        1000000 /* 1s! */
> +#define ARM_SMMU_CMDQ_SYNC_SPIN_COUNT        10
> +
> +#define FIELD_PREP(_mask, _val)                      \
> +     (((typeof(_mask))(_val) << (ffs64(_mask) - 1)) & (_mask))
> +
> +#define FIELD_GET(_mask, _reg)                       \
> +     ((typeof(_mask))(((_reg) & (_mask)) >> (ffs64(_mask) - 1)))
> +
> +/* Linux compatibility functions. */
> +typedef paddr_t              dma_addr_t;
> +typedef paddr_t              phys_addr_t;
> +typedef unsigned int         gfp_t;
> +
> +/* Alias to Xen lock functions */
> +#define mutex spinlock
> +#define mutex_init spin_lock_init
> +#define mutex_lock spin_lock
> +#define mutex_unlock spin_unlock
> +
> +/* SMMU private data for an IOMMU domain */
> +enum arm_smmu_domain_stage {
> +     ARM_SMMU_DOMAIN_S1 = 0,
> +     ARM_SMMU_DOMAIN_S2,
> +     ARM_SMMU_DOMAIN_NESTED,
> +     ARM_SMMU_DOMAIN_BYPASS,
> +};
> +
> +/* Xen specific code. */
> +struct iommu_domain {
> +     /* Runtime SMMU configuration for this iommu_domain */
> +     atomic_t                ref;
> +     /*
> +      * Used to link iommu_domain contexts for a same domain.
> +      * There is at least one per-SMMU to used by the domain.
> +      */
> +     struct list_head                list;
> +};
> +
> +/* Describes information required for a Xen domain */
> +struct arm_smmu_xen_domain {
> +     spinlock_t              lock;
> +
> +     /* List of iommu domains associated to this domain */
> +     struct list_head        contexts;
> +};
> +
> +enum pri_resp {
> +     PRI_RESP_DENY = 0,
> +     PRI_RESP_FAIL = 1,
> +     PRI_RESP_SUCC = 2,
> +};
> +
> +#ifdef CONFIG_MSI
> +enum arm_smmu_msi_index {
> +     EVTQ_MSI_INDEX,
> +     GERROR_MSI_INDEX,
> +     PRIQ_MSI_INDEX,
> +     ARM_SMMU_MAX_MSIS,
> +};
> +
> +static phys_addr_t arm_smmu_msi_cfg[ARM_SMMU_MAX_MSIS][3] = {
> +     [EVTQ_MSI_INDEX] = {
> +             ARM_SMMU_EVTQ_IRQ_CFG0,
> +             ARM_SMMU_EVTQ_IRQ_CFG1,
> +             ARM_SMMU_EVTQ_IRQ_CFG2,
> +     },
> +     [GERROR_MSI_INDEX] = {
> +             ARM_SMMU_GERROR_IRQ_CFG0,
> +             ARM_SMMU_GERROR_IRQ_CFG1,
> +             ARM_SMMU_GERROR_IRQ_CFG2,
> +     },
> +     [PRIQ_MSI_INDEX] = {
> +             ARM_SMMU_PRIQ_IRQ_CFG0,
> +             ARM_SMMU_PRIQ_IRQ_CFG1,
> +             ARM_SMMU_PRIQ_IRQ_CFG2,
> +     },
> +};
> +#endif /* CONFIG_MSI */
> +
> +struct arm_smmu_cmdq_ent {
> +     /* Common fields */
> +     u8                              opcode;
> +     bool                            substream_valid;
> +
> +     /* Command-specific fields */
> +     union {
> +             #define CMDQ_OP_PREFETCH_CFG    0x1
> +             struct {
> +                     u32                     sid;
> +                     u8                      size;
> +                     u64                     addr;
> +             } prefetch;
> +
> +             #define CMDQ_OP_CFGI_STE        0x3
> +             #define CMDQ_OP_CFGI_ALL        0x4
> +             struct {
> +                     u32                     sid;
> +                     union {
> +                             bool            leaf;
> +                             u8              span;
> +                     };
> +             } cfgi;
> +
> +             #define CMDQ_OP_TLBI_EL2_ALL    0x20
> +             #define CMDQ_OP_TLBI_S12_VMALL  0x28
> +             #define CMDQ_OP_TLBI_S2_IPA     0x2a
> +             #define CMDQ_OP_TLBI_NSNH_ALL   0x30
> +             struct {
> +                     u16                     asid;
> +                     u16                     vmid;
> +                     bool                    leaf;
> +                     u64                     addr;
> +             } tlbi;
> +
> +             #define CMDQ_OP_ATC_INV         0x40
> +             #define ATC_INV_SIZE_ALL        52
> +             struct {
> +                     u32                     sid;
> +                     u32                     ssid;
> +                     u64                     addr;
> +                     u8                      size;
> +                     bool                    global;
> +             } atc;
> +
> +             #define CMDQ_OP_PRI_RESP        0x41
> +             struct {
> +                     u32                     sid;
> +                     u32                     ssid;
> +                     u16                     grpid;
> +                     enum pri_resp           resp;
> +             } pri;
> +
> +             #define CMDQ_OP_CMD_SYNC        0x46
> +             struct {
> +                     u32                     msidata;
> +                     u64                     msiaddr;
> +             } sync;
> +     };
> +};
> +
> +struct arm_smmu_ll_queue {
> +     u32                             prod;
> +     u32                             cons;
> +     u32                             max_n_shift;
> +};
> +
> +struct arm_smmu_queue {
> +     struct arm_smmu_ll_queue        llq;
> +     int                             irq; /* Wired interrupt */
> +
> +     __le64                          *base;
> +     dma_addr_t                      base_dma;
> +     u64                             q_base;
> +
> +     size_t                          ent_dwords;
> +
> +     u32 __iomem                     *prod_reg;
> +     u32 __iomem                     *cons_reg;
> +};
> +
> +struct arm_smmu_cmdq {
> +     struct arm_smmu_queue           q;
> +     spinlock_t                      lock;
> +};
> +
> +struct arm_smmu_evtq {
> +     struct arm_smmu_queue           q;
> +     u32                             max_stalls;
> +};
> +
> +struct arm_smmu_priq {
> +     struct arm_smmu_queue           q;
> +};
> +
> +/* High-level stream table and context descriptor structures */
> +struct arm_smmu_strtab_l1_desc {
> +     u8                              span;
> +
> +     __le64                          *l2ptr;
> +     dma_addr_t                      l2ptr_dma;
> +};
> +
> +struct arm_smmu_s2_cfg {
> +     u16                             vmid;
> +     u64                             vttbr;
> +     u64                             vtcr;
> +};
> +
> +struct arm_smmu_strtab_cfg {
> +     __le64                          *strtab;
> +     dma_addr_t                      strtab_dma;
> +     struct arm_smmu_strtab_l1_desc  *l1_desc;
> +     unsigned int                    num_l1_ents;
> +
> +     u64                             strtab_base;
> +     u32                             strtab_base_cfg;
> +};
> +
> +struct arm_lpae_s2_cfg {
> +     u64                     vttbr;
> +     struct {
> +             u32                     ps:3;
> +             u32                     tg:2;
> +             u32                     sh:2;
> +             u32                     orgn:2;
> +             u32                     irgn:2;
> +             u32                     sl:2;
> +             u32                     tsz:6;
> +     } vtcr;
> +};
> +
> +/* An SMMUv3 instance */
> +struct arm_smmu_device {
> +     struct device                   *dev;
> +     void __iomem                    *base;
> +     void __iomem                    *page1;
> +
> +#define ARM_SMMU_FEAT_2_LVL_STRTAB   (1 << 0)
> +#define ARM_SMMU_FEAT_2_LVL_CDTAB    (1 << 1)
> +#define ARM_SMMU_FEAT_TT_LE          (1 << 2)
> +#define ARM_SMMU_FEAT_TT_BE          (1 << 3)
> +#define ARM_SMMU_FEAT_PRI            (1 << 4)
> +#define ARM_SMMU_FEAT_ATS            (1 << 5)
> +#define ARM_SMMU_FEAT_SEV            (1 << 6)
> +#define ARM_SMMU_FEAT_MSI            (1 << 7)
> +#define ARM_SMMU_FEAT_COHERENCY              (1 << 8)
> +#define ARM_SMMU_FEAT_TRANS_S1               (1 << 9)
> +#define ARM_SMMU_FEAT_TRANS_S2               (1 << 10)
> +#define ARM_SMMU_FEAT_STALLS         (1 << 11)
> +#define ARM_SMMU_FEAT_HYP            (1 << 12)
> +#define ARM_SMMU_FEAT_STALL_FORCE    (1 << 13)
> +#define ARM_SMMU_FEAT_VAX            (1 << 14)
> +     u32                             features;
> +
> +#define ARM_SMMU_OPT_SKIP_PREFETCH   (1 << 0)
> +#define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1)
> +     u32                             options;
> +
> +     struct arm_smmu_cmdq            cmdq;
> +     struct arm_smmu_evtq            evtq;
> +     struct arm_smmu_priq            priq;
> +
> +     int                             gerr_irq;
> +     int                             combined_irq;
> +     u32                             sync_nr;
> +     u8                              prev_cmd_opcode;
> +
> +     unsigned long                   ias; /* IPA */
> +     unsigned long                   oas; /* PA */
> +     unsigned long                   pgsize_bitmap;
> +
> +#define ARM_SMMU_MAX_VMIDS           (1 << 16)
> +     unsigned int                    vmid_bits;
> +     DECLARE_BITMAP(vmid_map, ARM_SMMU_MAX_VMIDS);
> +
> +     unsigned int                    sid_bits;
> +
> +     struct arm_smmu_strtab_cfg      strtab_cfg;
> +
> +     /* Hi16xx adds an extra 32 bits of goodness to its MSI payload */
> +     union {
> +             u32                     sync_count;
> +             u64                     padding;
> +     };
> +
> +     /* Need to keep a list of SMMU devices */
> +     struct list_head                devices;
> +
> +     /* Tasklets for handling evts/faults and pci page request IRQs*/
> +     struct tasklet          evtq_irq_tasklet;
> +     struct tasklet          priq_irq_tasklet;
> +     struct tasklet          combined_irq_tasklet;
> +};
> +
> +/* SMMU private data for each master */
> +struct arm_smmu_master {
> +     struct arm_smmu_device          *smmu;
> +     struct device                   *dev;
> +     struct arm_smmu_domain          *domain;
> +     struct list_head                domain_head;
> +     u32                             *sids;
> +     unsigned int                    num_sids;
> +     bool                            ats_enabled;
> +};
> +
> +struct arm_smmu_domain {
> +     struct arm_smmu_device          *smmu;
> +     struct mutex                    init_mutex; /* Protects smmu pointer */
> +
> +     bool                            non_strict;
> +     atomic_t                        nr_ats_masters;
> +
> +     enum arm_smmu_domain_stage      stage;
> +     struct arm_smmu_s2_cfg  s2_cfg;
> +
> +     /* Xen domain associated with this SMMU domain */
> +     struct domain           *d;
> +
> +     struct iommu_domain             domain;
> +
> +     struct list_head                devices;
> +     spinlock_t                      devices_lock;
> +};
> +
> +#endif /* _ARM_SMMU_V3_H */
> -- 
> 2.25.1
> 



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.