/*
 * Copyright (C) 2014-2016 Broadcom Corporation
 * Copyright (c) 2017 Red Hat, Inc.
 * Written by Prem Mallappa, Eric Auger
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Author: Prem Mallappa <pmallapp@broadcom.com>
 *
 */

#include "qemu/osdep.h"
#include "trace.h"
#include "exec/target_page.h"
#include "hw/core/cpu.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu/jhash.h"
#include "qemu/module.h"

#include "qemu/error-report.h"
#include "hw/arm/smmu-common.h"
#include "smmu-internal.h"

/* IOTLB Management */

static guint smmu_iotlb_key_hash(gconstpointer v)
{
    SMMUIOTLBKey *key = (SMMUIOTLBKey *)v;
    uint32_t a, b, c;

    /* Jenkins hash */
    a = b = c = JHASH_INITVAL + sizeof(*key);
    a += key->asid + key->vmid + key->level + key->tg;
    b += extract64(key->iova, 0, 32);
    c += extract64(key->iova, 32, 32);

    __jhash_mix(a, b, c);
    __jhash_final(a, b, c);

    return c;
}

static gboolean smmu_iotlb_key_equal(gconstpointer v1, gconstpointer v2)
{
    SMMUIOTLBKey *k1 = (SMMUIOTLBKey *)v1, *k2 = (SMMUIOTLBKey *)v2;

    return (k1->asid == k2->asid) && (k1->iova == k2->iova) &&
           (k1->level == k2->level) && (k1->tg == k2->tg) &&
           (k1->vmid == k2->vmid);
}

SMMUIOTLBKey smmu_get_iotlb_key(int asid, int vmid, uint64_t iova,
                                uint8_t tg, uint8_t level)
{
    SMMUIOTLBKey key = {.asid = asid, .vmid = vmid, .iova = iova,
                        .tg = tg, .level = level};

    return key;
}

static SMMUTLBEntry *smmu_iotlb_lookup_all_levels(SMMUState *bs,
                                                  SMMUTransCfg *cfg,
                                                  SMMUTransTableInfo *tt,
                                                  hwaddr iova)
{
    uint8_t tg = (tt->granule_sz - 10) / 2;
    uint8_t inputsize = 64 - tt->tsz;
    uint8_t stride = tt->granule_sz - 3;
    uint8_t level = 4 - (inputsize - 4) / stride;
    SMMUTLBEntry *entry = NULL;

    while (level <= 3) {
        uint64_t subpage_size = 1ULL << level_shift(level, tt->granule_sz);
        uint64_t mask = subpage_size - 1;
        SMMUIOTLBKey key;

        key = smmu_get_iotlb_key(cfg->asid, cfg->s2cfg.vmid,
                                 iova & ~mask, tg, level);
        entry = g_hash_table_lookup(bs->iotlb, &key);
        if (entry) {
            break;
        }
        level++;
    }
    return entry;
}

/**
 * smmu_iotlb_lookup - Look up for a TLB entry.
 * @bs: SMMU state which includes the TLB instance
 * @cfg: Configuration of the translation
 * @tt: Translation table info (granule and tsz)
 * @iova: IOVA address to lookup
 *
 * returns a valid entry on success, otherwise NULL.
 * In case of nested translation, tt can be updated to include
 * the granule of the found entry as it might different from
 * the IOVA granule.
 */
SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg,
                                SMMUTransTableInfo *tt, hwaddr iova)
{
    SMMUTLBEntry *entry = NULL;

    entry = smmu_iotlb_lookup_all_levels(bs, cfg, tt, iova);
    /*
     * For nested translation also try the s2 granule, as the TLB will insert
     * it if the size of s2 tlb entry was smaller.
     */
    if (!entry && (cfg->stage == SMMU_NESTED) &&
        (cfg->s2cfg.granule_sz != tt->granule_sz)) {
        tt->granule_sz = cfg->s2cfg.granule_sz;
        entry = smmu_iotlb_lookup_all_levels(bs, cfg, tt, iova);
    }

    if (entry) {
        cfg->iotlb_hits++;
        trace_smmu_iotlb_lookup_hit(cfg->asid, cfg->s2cfg.vmid, iova,
                                    cfg->iotlb_hits, cfg->iotlb_misses,
                                    100 * cfg->iotlb_hits /
                                    (cfg->iotlb_hits + cfg->iotlb_misses));
    } else {
        cfg->iotlb_misses++;
        trace_smmu_iotlb_lookup_miss(cfg->asid, cfg->s2cfg.vmid, iova,
                                     cfg->iotlb_hits, cfg->iotlb_misses,
                                     100 * cfg->iotlb_hits /
                                     (cfg->iotlb_hits + cfg->iotlb_misses));
    }
    return entry;
}

void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *new)
{
    SMMUIOTLBKey *key = g_new0(SMMUIOTLBKey, 1);
    uint8_t tg = (new->granule - 10) / 2;

    if (g_hash_table_size(bs->iotlb) >= SMMU_IOTLB_MAX_SIZE) {
        smmu_iotlb_inv_all(bs);
    }

    *key = smmu_get_iotlb_key(cfg->asid, cfg->s2cfg.vmid, new->entry.iova,
                              tg, new->level);
    trace_smmu_iotlb_insert(cfg->asid, cfg->s2cfg.vmid, new->entry.iova,
                            tg, new->level);
    g_hash_table_insert(bs->iotlb, key, new);
}

void smmu_iotlb_inv_all(SMMUState *s)
{
    trace_smmu_iotlb_inv_all();
    g_hash_table_remove_all(s->iotlb);
}

static gboolean smmu_hash_remove_by_asid_vmid(gpointer key, gpointer value,
                                              gpointer user_data)
{
    SMMUIOTLBPageInvInfo *info = (SMMUIOTLBPageInvInfo *)user_data;
    SMMUIOTLBKey *iotlb_key = (SMMUIOTLBKey *)key;

    return (SMMU_IOTLB_ASID(*iotlb_key) == info->asid) &&
           (SMMU_IOTLB_VMID(*iotlb_key) == info->vmid);
}

static gboolean smmu_hash_remove_by_vmid(gpointer key, gpointer value,
                                         gpointer user_data)
{
    int vmid = *(int *)user_data;
    SMMUIOTLBKey *iotlb_key = (SMMUIOTLBKey *)key;

    return SMMU_IOTLB_VMID(*iotlb_key) == vmid;
}

static gboolean smmu_hash_remove_by_vmid_s1(gpointer key, gpointer value,
                                            gpointer user_data)
{
    int vmid = *(int *)user_data;
    SMMUIOTLBKey *iotlb_key = (SMMUIOTLBKey *)key;

    return (SMMU_IOTLB_VMID(*iotlb_key) == vmid) &&
           (SMMU_IOTLB_ASID(*iotlb_key) >= 0);
}

static gboolean smmu_hash_remove_by_asid_vmid_iova(gpointer key, gpointer value,
                                              gpointer user_data)
{
    SMMUTLBEntry *iter = (SMMUTLBEntry *)value;
    IOMMUTLBEntry *entry = &iter->entry;
    SMMUIOTLBPageInvInfo *info = (SMMUIOTLBPageInvInfo *)user_data;
    SMMUIOTLBKey iotlb_key = *(SMMUIOTLBKey *)key;

    if (info->asid >= 0 && info->asid != SMMU_IOTLB_ASID(iotlb_key)) {
        return false;
    }
    if (info->vmid >= 0 && info->vmid != SMMU_IOTLB_VMID(iotlb_key)) {
        return false;
    }
    return ((info->iova & ~entry->addr_mask) == entry->iova) ||
           ((entry->iova & ~info->mask) == info->iova);
}

static gboolean smmu_hash_remove_by_vmid_ipa(gpointer key, gpointer value,
                                             gpointer user_data)
{
    SMMUTLBEntry *iter = (SMMUTLBEntry *)value;
    IOMMUTLBEntry *entry = &iter->entry;
    SMMUIOTLBPageInvInfo *info = (SMMUIOTLBPageInvInfo *)user_data;
    SMMUIOTLBKey iotlb_key = *(SMMUIOTLBKey *)key;

    if (SMMU_IOTLB_ASID(iotlb_key) >= 0) {
        /* This is a stage-1 address. */
        return false;
    }
    if (info->vmid != SMMU_IOTLB_VMID(iotlb_key)) {
        return false;
    }
    return ((info->iova & ~entry->addr_mask) == entry->iova) ||
           ((entry->iova & ~info->mask) == info->iova);
}

void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova,
                         uint8_t tg, uint64_t num_pages, uint8_t ttl)
{
    /* if tg is not set we use 4KB range invalidation */
    uint8_t granule = tg ? tg * 2 + 10 : 12;

    if (ttl && (num_pages == 1) && (asid >= 0)) {
        SMMUIOTLBKey key = smmu_get_iotlb_key(asid, vmid, iova, tg, ttl);

        if (g_hash_table_remove(s->iotlb, &key)) {
            return;
        }
        /*
         * if the entry is not found, let's see if it does not
         * belong to a larger IOTLB entry
         */
    }

    SMMUIOTLBPageInvInfo info = {
        .asid = asid, .iova = iova,
        .vmid = vmid,
        .mask = (num_pages * 1 << granule) - 1};

    g_hash_table_foreach_remove(s->iotlb,
                                smmu_hash_remove_by_asid_vmid_iova,
                                &info);
}

/*
 * Similar to smmu_iotlb_inv_iova(), but for Stage-2, ASID is always -1,
 * in Stage-1 invalidation ASID = -1, means don't care.
 */
void smmu_iotlb_inv_ipa(SMMUState *s, int vmid, dma_addr_t ipa, uint8_t tg,
                        uint64_t num_pages, uint8_t ttl)
{
    uint8_t granule = tg ? tg * 2 + 10 : 12;
    int asid = -1;

   if (ttl && (num_pages == 1)) {
        SMMUIOTLBKey key = smmu_get_iotlb_key(asid, vmid, ipa, tg, ttl);

        if (g_hash_table_remove(s->iotlb, &key)) {
            return;
        }
    }

    SMMUIOTLBPageInvInfo info = {
        .iova = ipa,
        .vmid = vmid,
        .mask = (num_pages << granule) - 1};

    g_hash_table_foreach_remove(s->iotlb,
                                smmu_hash_remove_by_vmid_ipa,
                                &info);
}

void smmu_iotlb_inv_asid_vmid(SMMUState *s, int asid, int vmid)
{
    SMMUIOTLBPageInvInfo info = {
        .asid = asid,
        .vmid = vmid,
    };

    trace_smmu_iotlb_inv_asid_vmid(asid, vmid);
    g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_asid_vmid, &info);
}

void smmu_iotlb_inv_vmid(SMMUState *s, int vmid)
{
    trace_smmu_iotlb_inv_vmid(vmid);
    g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_vmid, &vmid);
}

inline void smmu_iotlb_inv_vmid_s1(SMMUState *s, int vmid)
{
    trace_smmu_iotlb_inv_vmid_s1(vmid);
    g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_vmid_s1, &vmid);
}

/* VMSAv8-64 Translation */

/**
 * get_pte - Get the content of a page table entry located at
 * @base_addr[@index]
 */
static int get_pte(dma_addr_t baseaddr, uint32_t index, uint64_t *pte,
                   SMMUPTWEventInfo *info)
{
    int ret;
    dma_addr_t addr = baseaddr + index * sizeof(*pte);

    /* TODO: guarantee 64-bit single-copy atomicity */
    ret = ldq_le_dma(&address_space_memory, addr, pte, MEMTXATTRS_UNSPECIFIED);

    if (ret != MEMTX_OK) {
        info->type = SMMU_PTW_ERR_WALK_EABT;
        info->addr = addr;
        return -EINVAL;
    }
    trace_smmu_get_pte(baseaddr, index, addr, *pte);
    return 0;
}

/* VMSAv8-64 Translation Table Format Descriptor Decoding */

/**
 * get_page_pte_address - returns the L3 descriptor output address,
 * ie. the page frame
 * ARM ARM spec: Figure D4-17 VMSAv8-64 level 3 descriptor format
 */
static inline hwaddr get_page_pte_address(uint64_t pte, int granule_sz)
{
    return PTE_ADDRESS(pte, granule_sz);
}

/**
 * get_table_pte_address - return table descriptor output address,
 * ie. address of next level table
 * ARM ARM Figure D4-16 VMSAv8-64 level0, level1, and level 2 descriptor formats
 */
static inline hwaddr get_table_pte_address(uint64_t pte, int granule_sz)
{
    return PTE_ADDRESS(pte, granule_sz);
}

/**
 * get_block_pte_address - return block descriptor output address and block size
 * ARM ARM Figure D4-16 VMSAv8-64 level0, level1, and level 2 descriptor formats
 */
static inline hwaddr get_block_pte_address(uint64_t pte, int level,
                                           int granule_sz, uint64_t *bsz)
{
    int n = level_shift(level, granule_sz);

    *bsz = 1ULL << n;
    return PTE_ADDRESS(pte, n);
}

SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova)
{
    bool tbi = extract64(iova, 55, 1) ? TBI1(cfg->tbi) : TBI0(cfg->tbi);
    uint8_t tbi_byte = tbi * 8;

    if (cfg->tt[0].tsz &&
        !extract64(iova, 64 - cfg->tt[0].tsz, cfg->tt[0].tsz - tbi_byte)) {
        /* there is a ttbr0 region and we are in it (high bits all zero) */
        return &cfg->tt[0];
    } else if (cfg->tt[1].tsz &&
        sextract64(iova, 64 - cfg->tt[1].tsz, cfg->tt[1].tsz - tbi_byte) == -1) {
        /* there is a ttbr1 region and we are in it (high bits all one) */
        return &cfg->tt[1];
    } else if (!cfg->tt[0].tsz) {
        /* ttbr0 region is "everything not in the ttbr1 region" */
        return &cfg->tt[0];
    } else if (!cfg->tt[1].tsz) {
        /* ttbr1 region is "everything not in the ttbr0 region" */
        return &cfg->tt[1];
    }
    /* in the gap between the two regions, this is a Translation fault */
    return NULL;
}

/* Translate stage-1 table address using stage-2 page table. */
static inline int translate_table_addr_ipa(SMMUState *bs,
                                           dma_addr_t *table_addr,
                                           SMMUTransCfg *cfg,
                                           SMMUPTWEventInfo *info)
{
    dma_addr_t addr = *table_addr;
    SMMUTLBEntry *cached_entry;
    int asid;

    /*
     * The translation table walks performed from TTB0 or TTB1 are always
     * performed in IPA space if stage 2 translations are enabled.
     */
    asid = cfg->asid;
    cfg->stage = SMMU_STAGE_2;
    cfg->asid = -1;
    cached_entry = smmu_translate(bs, cfg, addr, IOMMU_RO, info);
    cfg->asid = asid;
    cfg->stage = SMMU_NESTED;

    if (cached_entry) {
        *table_addr = CACHED_ENTRY_TO_ADDR(cached_entry, addr);
        return 0;
    }

    info->stage = SMMU_STAGE_2;
    info->addr = addr;
    info->is_ipa_descriptor = true;
    return -EINVAL;
}

/**
 * smmu_ptw_64_s1 - VMSAv8-64 Walk of the page tables for a given IOVA
 * @bs: smmu state which includes TLB instance
 * @cfg: translation config
 * @iova: iova to translate
 * @perm: access type
 * @tlbe: SMMUTLBEntry (out)
 * @info: handle to an error info
 *
 * Return 0 on success, < 0 on error. In case of error, @info is filled
 * and tlbe->perm is set to IOMMU_NONE.
 * Upon success, @tlbe is filled with translated_addr and entry
 * permission rights.
 */
static int smmu_ptw_64_s1(SMMUState *bs, SMMUTransCfg *cfg,
                          dma_addr_t iova, IOMMUAccessFlags perm,
                          SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
{
    dma_addr_t baseaddr, indexmask;
    SMMUStage stage = cfg->stage;
    SMMUTransTableInfo *tt = select_tt(cfg, iova);
    uint8_t level, granule_sz, inputsize, stride;

    if (!tt || tt->disabled) {
        info->type = SMMU_PTW_ERR_TRANSLATION;
        goto error;
    }

    granule_sz = tt->granule_sz;
    stride = VMSA_STRIDE(granule_sz);
    inputsize = 64 - tt->tsz;
    level = 4 - (inputsize - 4) / stride;
    indexmask = VMSA_IDXMSK(inputsize, stride, level);

    baseaddr = extract64(tt->ttb, 0, cfg->oas);
    baseaddr &= ~indexmask;

    while (level < VMSA_LEVELS) {
        uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
        uint64_t mask = subpage_size - 1;
        uint32_t offset = iova_level_offset(iova, inputsize, level, granule_sz);
        uint64_t pte, gpa;
        dma_addr_t pte_addr = baseaddr + offset * sizeof(pte);
        uint8_t ap;

        if (get_pte(baseaddr, offset, &pte, info)) {
                goto error;
        }
        trace_smmu_ptw_level(stage, level, iova, subpage_size,
                             baseaddr, offset, pte);

        if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) {
            trace_smmu_ptw_invalid_pte(stage, level, baseaddr,
                                       pte_addr, offset, pte);
            break;
        }

        if (is_table_pte(pte, level)) {
            ap = PTE_APTABLE(pte);

            if (is_permission_fault(ap, perm) && !tt->had) {
                info->type = SMMU_PTW_ERR_PERMISSION;
                goto error;
            }
            baseaddr = get_table_pte_address(pte, granule_sz);
            if (cfg->stage == SMMU_NESTED) {
                if (translate_table_addr_ipa(bs, &baseaddr, cfg, info)) {
                    goto error;
                }
            }
            level++;
            continue;
        } else if (is_page_pte(pte, level)) {
            gpa = get_page_pte_address(pte, granule_sz);
            trace_smmu_ptw_page_pte(stage, level, iova,
                                    baseaddr, pte_addr, pte, gpa);
        } else {
            uint64_t block_size;

            gpa = get_block_pte_address(pte, level, granule_sz,
                                        &block_size);
            trace_smmu_ptw_block_pte(stage, level, baseaddr,
                                     pte_addr, pte, iova, gpa,
                                     block_size >> 20);
        }

        /*
         * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
         * are 0 we take an Access flag fault. (5.4. Context Descriptor)
         * An Access flag fault takes priority over a Permission fault.
         */
        if (!PTE_AF(pte) && !cfg->affd) {
            info->type = SMMU_PTW_ERR_ACCESS;
            goto error;
        }

        ap = PTE_AP(pte);
        if (is_permission_fault(ap, perm)) {
            info->type = SMMU_PTW_ERR_PERMISSION;
            goto error;
        }

        /*
         * The address output from the translation causes a stage 1 Address
         * Size fault if it exceeds the range of the effective IPA size for
         * the given CD.
         */
        if (gpa >= (1ULL << cfg->oas)) {
            info->type = SMMU_PTW_ERR_ADDR_SIZE;
            goto error;
        }

        tlbe->entry.translated_addr = gpa;
        tlbe->entry.iova = iova & ~mask;
        tlbe->entry.addr_mask = mask;
        tlbe->parent_perm = PTE_AP_TO_PERM(ap);
        tlbe->entry.perm = tlbe->parent_perm;
        tlbe->level = level;
        tlbe->granule = granule_sz;
        return 0;
    }
    info->type = SMMU_PTW_ERR_TRANSLATION;

error:
    info->stage = SMMU_STAGE_1;
    tlbe->entry.perm = IOMMU_NONE;
    return -EINVAL;
}

/**
 * smmu_ptw_64_s2 - VMSAv8-64 Walk of the page tables for a given ipa
 * for stage-2.
 * @cfg: translation config
 * @ipa: ipa to translate
 * @perm: access type
 * @tlbe: SMMUTLBEntry (out)
 * @info: handle to an error info
 *
 * Return 0 on success, < 0 on error. In case of error, @info is filled
 * and tlbe->perm is set to IOMMU_NONE.
 * Upon success, @tlbe is filled with translated_addr and entry
 * permission rights.
 */
static int smmu_ptw_64_s2(SMMUTransCfg *cfg,
                          dma_addr_t ipa, IOMMUAccessFlags perm,
                          SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
{
    const SMMUStage stage = SMMU_STAGE_2;
    int granule_sz = cfg->s2cfg.granule_sz;
    /* ARM DDI0487I.a: Table D8-7. */
    int inputsize = 64 - cfg->s2cfg.tsz;
    int level = get_start_level(cfg->s2cfg.sl0, granule_sz);
    int stride = VMSA_STRIDE(granule_sz);
    int idx = pgd_concat_idx(level, granule_sz, ipa);
    /*
     * Get the ttb from concatenated structure.
     * The offset is the idx * size of each ttb(number of ptes * (sizeof(pte))
     */
    uint64_t baseaddr = extract64(cfg->s2cfg.vttb, 0, cfg->s2cfg.eff_ps) +
                                  (1 << stride) * idx * sizeof(uint64_t);
    dma_addr_t indexmask = VMSA_IDXMSK(inputsize, stride, level);

    baseaddr &= ~indexmask;

    /*
     * On input, a stage 2 Translation fault occurs if the IPA is outside the
     * range configured by the relevant S2T0SZ field of the STE.
     */
    if (ipa >= (1ULL << inputsize)) {
        info->type = SMMU_PTW_ERR_TRANSLATION;
        goto error_ipa;
    }

    while (level < VMSA_LEVELS) {
        uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
        uint64_t mask = subpage_size - 1;
        uint32_t offset = iova_level_offset(ipa, inputsize, level, granule_sz);
        uint64_t pte, gpa;
        dma_addr_t pte_addr = baseaddr + offset * sizeof(pte);
        uint8_t s2ap;

        if (get_pte(baseaddr, offset, &pte, info)) {
                goto error;
        }
        trace_smmu_ptw_level(stage, level, ipa, subpage_size,
                             baseaddr, offset, pte);
        if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) {
            trace_smmu_ptw_invalid_pte(stage, level, baseaddr,
                                       pte_addr, offset, pte);
            break;
        }

        if (is_table_pte(pte, level)) {
            baseaddr = get_table_pte_address(pte, granule_sz);
            level++;
            continue;
        } else if (is_page_pte(pte, level)) {
            gpa = get_page_pte_address(pte, granule_sz);
            trace_smmu_ptw_page_pte(stage, level, ipa,
                                    baseaddr, pte_addr, pte, gpa);
        } else {
            uint64_t block_size;

            gpa = get_block_pte_address(pte, level, granule_sz,
                                        &block_size);
            trace_smmu_ptw_block_pte(stage, level, baseaddr,
                                     pte_addr, pte, ipa, gpa,
                                     block_size >> 20);
        }

        /*
         * If S2AFFD and PTE.AF are 0 => fault. (5.2. Stream Table Entry)
         * An Access fault takes priority over a Permission fault.
         */
        if (!PTE_AF(pte) && !cfg->s2cfg.affd) {
            info->type = SMMU_PTW_ERR_ACCESS;
            goto error_ipa;
        }

        s2ap = PTE_AP(pte);
        if (is_permission_fault_s2(s2ap, perm)) {
            info->type = SMMU_PTW_ERR_PERMISSION;
            goto error_ipa;
        }

        /*
         * The address output from the translation causes a stage 2 Address
         * Size fault if it exceeds the effective PA output range.
         */
        if (gpa >= (1ULL << cfg->s2cfg.eff_ps)) {
            info->type = SMMU_PTW_ERR_ADDR_SIZE;
            goto error_ipa;
        }

        tlbe->entry.translated_addr = gpa;
        tlbe->entry.iova = ipa & ~mask;
        tlbe->entry.addr_mask = mask;
        tlbe->parent_perm = s2ap;
        tlbe->entry.perm = tlbe->parent_perm;
        tlbe->level = level;
        tlbe->granule = granule_sz;
        return 0;
    }
    info->type = SMMU_PTW_ERR_TRANSLATION;

error_ipa:
    info->addr = ipa;
error:
    info->stage = SMMU_STAGE_2;
    tlbe->entry.perm = IOMMU_NONE;
    return -EINVAL;
}

/*
 * combine S1 and S2 TLB entries into a single entry.
 * As a result the S1 entry is overridden with combined data.
 */
static void combine_tlb(SMMUTLBEntry *tlbe, SMMUTLBEntry *tlbe_s2,
                        dma_addr_t iova, SMMUTransCfg *cfg)
{
    if (tlbe_s2->entry.addr_mask < tlbe->entry.addr_mask) {
        tlbe->entry.addr_mask = tlbe_s2->entry.addr_mask;
        tlbe->granule = tlbe_s2->granule;
        tlbe->level = tlbe_s2->level;
    }

    tlbe->entry.translated_addr = CACHED_ENTRY_TO_ADDR(tlbe_s2,
                                    tlbe->entry.translated_addr);

    tlbe->entry.iova = iova & ~tlbe->entry.addr_mask;
    /* parent_perm has s2 perm while perm keeps s1 perm. */
    tlbe->parent_perm = tlbe_s2->entry.perm;
    return;
}

/**
 * smmu_ptw - Walk the page tables for an IOVA, according to @cfg
 *
 * @bs: smmu state which includes TLB instance
 * @cfg: translation configuration
 * @iova: iova to translate
 * @perm: tentative access type
 * @tlbe: returned entry
 * @info: ptw event handle
 *
 * return 0 on success
 */
int smmu_ptw(SMMUState *bs, SMMUTransCfg *cfg, dma_addr_t iova,
             IOMMUAccessFlags perm, SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
{
    int ret;
    SMMUTLBEntry tlbe_s2;
    dma_addr_t ipa;

    if (cfg->stage == SMMU_STAGE_1) {
        return smmu_ptw_64_s1(bs, cfg, iova, perm, tlbe, info);
    } else if (cfg->stage == SMMU_STAGE_2) {
        /*
         * If bypassing stage 1(or unimplemented), the input address is passed
         * directly to stage 2 as IPA. If the input address of a transaction
         * exceeds the size of the IAS, a stage 1 Address Size fault occurs.
         * For AA64, IAS = OAS according to (IHI 0070.E.a) "3.4 Address sizes"
         */
        if (iova >= (1ULL << cfg->oas)) {
            info->type = SMMU_PTW_ERR_ADDR_SIZE;
            info->stage = SMMU_STAGE_1;
            tlbe->entry.perm = IOMMU_NONE;
            return -EINVAL;
        }

        return smmu_ptw_64_s2(cfg, iova, perm, tlbe, info);
    }

    /* SMMU_NESTED. */
    ret = smmu_ptw_64_s1(bs, cfg, iova, perm, tlbe, info);
    if (ret) {
        return ret;
    }

    ipa = CACHED_ENTRY_TO_ADDR(tlbe, iova);
    ret = smmu_ptw_64_s2(cfg, ipa, perm, &tlbe_s2, info);
    if (ret) {
        return ret;
    }

    combine_tlb(tlbe, &tlbe_s2, iova, cfg);
    return 0;
}

SMMUTLBEntry *smmu_translate(SMMUState *bs, SMMUTransCfg *cfg, dma_addr_t addr,
                             IOMMUAccessFlags flag, SMMUPTWEventInfo *info)
{
    SMMUTLBEntry *cached_entry = NULL;
    SMMUTransTableInfo *tt;
    int status;

    /*
     * Combined attributes used for TLB lookup, holds the attributes for
     * the input stage.
     */
    SMMUTransTableInfo tt_combined;

    if (cfg->stage == SMMU_STAGE_2) {
        /* Stage2. */
        tt_combined.granule_sz = cfg->s2cfg.granule_sz;
        tt_combined.tsz = cfg->s2cfg.tsz;
    } else {
        /* Select stage1 translation table. */
        tt = select_tt(cfg, addr);
        if (!tt) {
            info->type = SMMU_PTW_ERR_TRANSLATION;
            info->stage = SMMU_STAGE_1;
            return NULL;
        }
        tt_combined.granule_sz = tt->granule_sz;
        tt_combined.tsz = tt->tsz;
    }

    cached_entry = smmu_iotlb_lookup(bs, cfg, &tt_combined, addr);
    if (cached_entry) {
        if ((flag & IOMMU_WO) && !(cached_entry->entry.perm &
            cached_entry->parent_perm & IOMMU_WO)) {
            info->type = SMMU_PTW_ERR_PERMISSION;
            info->stage = !(cached_entry->entry.perm & IOMMU_WO) ?
                          SMMU_STAGE_1 :
                          SMMU_STAGE_2;
            return NULL;
        }
        return cached_entry;
    }

    cached_entry = g_new0(SMMUTLBEntry, 1);
    status = smmu_ptw(bs, cfg, addr, flag, cached_entry, info);
    if (status) {
            g_free(cached_entry);
            return NULL;
    }
    smmu_iotlb_insert(bs, cfg, cached_entry);
    return cached_entry;
}

/**
 * The bus number is used for lookup when SID based invalidation occurs.
 * In that case we lazily populate the SMMUPciBus array from the bus hash
 * table. At the time the SMMUPciBus is created (smmu_find_add_as), the bus
 * numbers may not be always initialized yet.
 */
SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num)
{
    SMMUPciBus *smmu_pci_bus = s->smmu_pcibus_by_bus_num[bus_num];
    GHashTableIter iter;

    if (smmu_pci_bus) {
        return smmu_pci_bus;
    }

    g_hash_table_iter_init(&iter, s->smmu_pcibus_by_busptr);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&smmu_pci_bus)) {
        if (pci_bus_num(smmu_pci_bus->bus) == bus_num) {
            s->smmu_pcibus_by_bus_num[bus_num] = smmu_pci_bus;
            return smmu_pci_bus;
        }
    }

    return NULL;
}

static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
{
    SMMUState *s = opaque;
    SMMUPciBus *sbus = g_hash_table_lookup(s->smmu_pcibus_by_busptr, bus);
    SMMUDevice *sdev;
    static unsigned int index;

    if (!sbus) {
        sbus = g_malloc0(sizeof(SMMUPciBus) +
                         sizeof(SMMUDevice *) * SMMU_PCI_DEVFN_MAX);
        sbus->bus = bus;
        g_hash_table_insert(s->smmu_pcibus_by_busptr, bus, sbus);
    }

    sdev = sbus->pbdev[devfn];
    if (!sdev) {
        char *name = g_strdup_printf("%s-%d-%d", s->mrtypename, devfn, index++);

        sdev = sbus->pbdev[devfn] = g_new0(SMMUDevice, 1);

        sdev->smmu = s;
        sdev->bus = bus;
        sdev->devfn = devfn;

        memory_region_init_iommu(&sdev->iommu, sizeof(sdev->iommu),
                                 s->mrtypename,
                                 OBJECT(s), name, UINT64_MAX);
        address_space_init(&sdev->as,
                           MEMORY_REGION(&sdev->iommu), name);
        trace_smmu_add_mr(name);
        g_free(name);
    }

    return &sdev->as;
}

static const PCIIOMMUOps smmu_ops = {
    .get_address_space = smmu_find_add_as,
};

SMMUDevice *smmu_find_sdev(SMMUState *s, uint32_t sid)
{
    uint8_t bus_n, devfn;
    SMMUPciBus *smmu_bus;

    bus_n = PCI_BUS_NUM(sid);
    smmu_bus = smmu_find_smmu_pcibus(s, bus_n);
    if (smmu_bus) {
        devfn = SMMU_PCI_DEVFN(sid);
        return smmu_bus->pbdev[devfn];
    }
    return NULL;
}

/* Unmap all notifiers attached to @mr */
static void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
{
    IOMMUNotifier *n;

    trace_smmu_inv_notifiers_mr(mr->parent_obj.name);
    IOMMU_NOTIFIER_FOREACH(n, mr) {
        memory_region_unmap_iommu_notifier_range(n);
    }
}

/* Unmap all notifiers of all mr's */
void smmu_inv_notifiers_all(SMMUState *s)
{
    SMMUDevice *sdev;

    QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
        smmu_inv_notifiers_mr(&sdev->iommu);
    }
}

static void smmu_base_realize(DeviceState *dev, Error **errp)
{
    SMMUState *s = ARM_SMMU(dev);
    SMMUBaseClass *sbc = ARM_SMMU_GET_CLASS(dev);
    Error *local_err = NULL;

    sbc->parent_realize(dev, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
    s->configs = g_hash_table_new_full(NULL, NULL, NULL, g_free);
    s->iotlb = g_hash_table_new_full(smmu_iotlb_key_hash, smmu_iotlb_key_equal,
                                     g_free, g_free);
    s->smmu_pcibus_by_busptr = g_hash_table_new(NULL, NULL);

    if (s->primary_bus) {
        pci_setup_iommu(s->primary_bus, &smmu_ops, s);
    } else {
        error_setg(errp, "SMMU is not attached to any PCI bus!");
    }
}

static void smmu_base_reset_hold(Object *obj, ResetType type)
{
    SMMUState *s = ARM_SMMU(obj);

    memset(s->smmu_pcibus_by_bus_num, 0, sizeof(s->smmu_pcibus_by_bus_num));

    g_hash_table_remove_all(s->configs);
    g_hash_table_remove_all(s->iotlb);
}

static Property smmu_dev_properties[] = {
    DEFINE_PROP_UINT8("bus_num", SMMUState, bus_num, 0),
    DEFINE_PROP_LINK("primary-bus", SMMUState, primary_bus,
                     TYPE_PCI_BUS, PCIBus *),
    DEFINE_PROP_END_OF_LIST(),
};

static void smmu_base_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ResettableClass *rc = RESETTABLE_CLASS(klass);
    SMMUBaseClass *sbc = ARM_SMMU_CLASS(klass);

    device_class_set_props(dc, smmu_dev_properties);
    device_class_set_parent_realize(dc, smmu_base_realize,
                                    &sbc->parent_realize);
    rc->phases.hold = smmu_base_reset_hold;
}

static const TypeInfo smmu_base_info = {
    .name          = TYPE_ARM_SMMU,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(SMMUState),
    .class_data    = NULL,
    .class_size    = sizeof(SMMUBaseClass),
    .class_init    = smmu_base_class_init,
    .abstract      = true,
};

static void smmu_base_register_types(void)
{
    type_register_static(&smmu_base_info);
}

type_init(smmu_base_register_types)

