#define pr_fmt(fmt) …
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/io-pgtable.h>
#include <linux/kernel.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/dma-mapping.h>
#include <asm/barrier.h>
#include "io-pgtable-arm.h"
#include "iommu-pages.h"
#define ARM_LPAE_MAX_ADDR_BITS …
#define ARM_LPAE_S2_MAX_CONCAT_PAGES …
#define ARM_LPAE_MAX_LEVELS …
#define io_pgtable_to_data(x) …
#define io_pgtable_ops_to_data(x) …
#define ARM_LPAE_LVL_SHIFT(l,d) …
#define ARM_LPAE_GRANULE(d) …
#define ARM_LPAE_PGD_SIZE(d) …
#define ARM_LPAE_PTES_PER_TABLE(d) …
#define ARM_LPAE_PGD_IDX(l,d) …
#define ARM_LPAE_LVL_IDX(a,l,d) …
#define ARM_LPAE_BLOCK_SIZE(l,d) …
#define ARM_LPAE_PTE_TYPE_SHIFT …
#define ARM_LPAE_PTE_TYPE_MASK …
#define ARM_LPAE_PTE_TYPE_BLOCK …
#define ARM_LPAE_PTE_TYPE_TABLE …
#define ARM_LPAE_PTE_TYPE_PAGE …
#define ARM_LPAE_PTE_ADDR_MASK …
#define ARM_LPAE_PTE_NSTABLE …
#define ARM_LPAE_PTE_XN …
#define ARM_LPAE_PTE_DBM …
#define ARM_LPAE_PTE_AF …
#define ARM_LPAE_PTE_SH_NS …
#define ARM_LPAE_PTE_SH_OS …
#define ARM_LPAE_PTE_SH_IS …
#define ARM_LPAE_PTE_NS …
#define ARM_LPAE_PTE_VALID …
#define ARM_LPAE_PTE_ATTR_LO_MASK …
#define ARM_LPAE_PTE_ATTR_HI_MASK …
#define ARM_LPAE_PTE_ATTR_MASK …
#define ARM_LPAE_PTE_SW_SYNC …
#define ARM_LPAE_PTE_AP_UNPRIV …
#define ARM_LPAE_PTE_AP_RDONLY_BIT …
#define ARM_LPAE_PTE_AP_RDONLY …
#define ARM_LPAE_PTE_AP_WR_CLEAN_MASK …
#define ARM_LPAE_PTE_ATTRINDX_SHIFT …
#define ARM_LPAE_PTE_nG …
#define ARM_LPAE_PTE_HAP_FAULT …
#define ARM_LPAE_PTE_HAP_READ …
#define ARM_LPAE_PTE_HAP_WRITE …
#define ARM_LPAE_PTE_MEMATTR_OIWB …
#define ARM_LPAE_PTE_MEMATTR_NC …
#define ARM_LPAE_PTE_MEMATTR_DEV …
#define ARM_LPAE_VTCR_SL0_MASK …
#define ARM_LPAE_TCR_T0SZ_SHIFT …
#define ARM_LPAE_VTCR_PS_SHIFT …
#define ARM_LPAE_VTCR_PS_MASK …
#define ARM_LPAE_MAIR_ATTR_SHIFT(n) …
#define ARM_LPAE_MAIR_ATTR_MASK …
#define ARM_LPAE_MAIR_ATTR_DEVICE …
#define ARM_LPAE_MAIR_ATTR_NC …
#define ARM_LPAE_MAIR_ATTR_INC_OWBRWA …
#define ARM_LPAE_MAIR_ATTR_WBRWA …
#define ARM_LPAE_MAIR_ATTR_IDX_NC …
#define ARM_LPAE_MAIR_ATTR_IDX_CACHE …
#define ARM_LPAE_MAIR_ATTR_IDX_DEV …
#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE …
#define ARM_MALI_LPAE_TTBR_ADRMODE_TABLE …
#define ARM_MALI_LPAE_TTBR_READ_INNER …
#define ARM_MALI_LPAE_TTBR_SHARE_OUTER …
#define ARM_MALI_LPAE_MEMATTR_IMP_DEF …
#define ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC …
#define iopte_deref(pte,d) …
#define iopte_type(pte) …
#define iopte_prot(pte) …
#define iopte_writeable_dirty(pte) …
#define iopte_set_writeable_clean(ptep) …
struct arm_lpae_io_pgtable { … };
arm_lpae_iopte;
static inline bool iopte_leaf(arm_lpae_iopte pte, int lvl,
enum io_pgtable_fmt fmt)
{ … }
static inline bool iopte_table(arm_lpae_iopte pte, int lvl)
{ … }
static arm_lpae_iopte paddr_to_iopte(phys_addr_t paddr,
struct arm_lpae_io_pgtable *data)
{ … }
static phys_addr_t iopte_to_paddr(arm_lpae_iopte pte,
struct arm_lpae_io_pgtable *data)
{ … }
static bool selftest_running = …;
static dma_addr_t __arm_lpae_dma_addr(void *pages)
{ … }
static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
struct io_pgtable_cfg *cfg,
void *cookie)
{ … }
static void __arm_lpae_free_pages(void *pages, size_t size,
struct io_pgtable_cfg *cfg,
void *cookie)
{ … }
static void __arm_lpae_sync_pte(arm_lpae_iopte *ptep, int num_entries,
struct io_pgtable_cfg *cfg)
{ … }
static void __arm_lpae_clear_pte(arm_lpae_iopte *ptep, struct io_pgtable_cfg *cfg)
{ … }
static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
struct iommu_iotlb_gather *gather,
unsigned long iova, size_t size, size_t pgcount,
int lvl, arm_lpae_iopte *ptep);
static void __arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
phys_addr_t paddr, arm_lpae_iopte prot,
int lvl, int num_entries, arm_lpae_iopte *ptep)
{ … }
static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
unsigned long iova, phys_addr_t paddr,
arm_lpae_iopte prot, int lvl, int num_entries,
arm_lpae_iopte *ptep)
{ … }
static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table,
arm_lpae_iopte *ptep,
arm_lpae_iopte curr,
struct arm_lpae_io_pgtable *data)
{ … }
static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
phys_addr_t paddr, size_t size, size_t pgcount,
arm_lpae_iopte prot, int lvl, arm_lpae_iopte *ptep,
gfp_t gfp, size_t *mapped)
{ … }
static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
int prot)
{ … }
static int arm_lpae_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
phys_addr_t paddr, size_t pgsize, size_t pgcount,
int iommu_prot, gfp_t gfp, size_t *mapped)
{ … }
static void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
arm_lpae_iopte *ptep)
{ … }
static void arm_lpae_free_pgtable(struct io_pgtable *iop)
{ … }
static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
struct iommu_iotlb_gather *gather,
unsigned long iova, size_t size,
arm_lpae_iopte blk_pte, int lvl,
arm_lpae_iopte *ptep, size_t pgcount)
{ … }
static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
struct iommu_iotlb_gather *gather,
unsigned long iova, size_t size, size_t pgcount,
int lvl, arm_lpae_iopte *ptep)
{ … }
static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
size_t pgsize, size_t pgcount,
struct iommu_iotlb_gather *gather)
{ … }
static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
unsigned long iova)
{ … }
struct io_pgtable_walk_data { … };
static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
struct io_pgtable_walk_data *walk_data,
arm_lpae_iopte *ptep,
int lvl);
static int io_pgtable_visit_dirty(struct arm_lpae_io_pgtable *data,
struct io_pgtable_walk_data *walk_data,
arm_lpae_iopte *ptep, int lvl)
{ … }
static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
struct io_pgtable_walk_data *walk_data,
arm_lpae_iopte *ptep,
int lvl)
{ … }
static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
unsigned long iova, size_t size,
unsigned long flags,
struct iommu_dirty_bitmap *dirty)
{ … }
static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
{ … }
static struct arm_lpae_io_pgtable *
arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
{ … }
static struct io_pgtable *
arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
{ … }
static struct io_pgtable *
arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
{ … }
static struct io_pgtable *
arm_32_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
{ … }
static struct io_pgtable *
arm_32_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
{ … }
static struct io_pgtable *
arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
{ … }
struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = …;
struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s2_init_fns = …;
struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s1_init_fns = …;
struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s2_init_fns = …;
struct io_pgtable_init_fns io_pgtable_arm_mali_lpae_init_fns = …;
#ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST
static struct io_pgtable_cfg *cfg_cookie __initdata;
static void __init dummy_tlb_flush_all(void *cookie)
{ … }
static void __init dummy_tlb_flush(unsigned long iova, size_t size,
size_t granule, void *cookie)
{ … }
static void __init dummy_tlb_add_page(struct iommu_iotlb_gather *gather,
unsigned long iova, size_t granule,
void *cookie)
{ … }
static const struct iommu_flush_ops dummy_tlb_ops __initconst = …;
static void __init arm_lpae_dump_ops(struct io_pgtable_ops *ops)
{ … }
#define __FAIL(ops, i) …
static int __init arm_lpae_run_tests(struct io_pgtable_cfg *cfg)
{ … }
static int __init arm_lpae_do_selftests(void)
{ … }
subsys_initcall(arm_lpae_do_selftests);
#endif