qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

arm_gicv3_its.c (65140B)


      1 /*
      2  * ITS emulation for a GICv3-based system
      3  *
      4  * Copyright Linaro.org 2021
      5  *
      6  * Authors:
      7  *  Shashi Mallela <shashi.mallela@linaro.org>
      8  *
      9  * This work is licensed under the terms of the GNU GPL, version 2 or (at your
     10  * option) any later version.  See the COPYING file in the top-level directory.
     11  *
     12  */
     13 
     14 #include "qemu/osdep.h"
     15 #include "qemu/log.h"
     16 #include "trace.h"
     17 #include "hw/qdev-properties.h"
     18 #include "hw/intc/arm_gicv3_its_common.h"
     19 #include "gicv3_internal.h"
     20 #include "qom/object.h"
     21 #include "qapi/error.h"
     22 
     23 typedef struct GICv3ITSClass GICv3ITSClass;
     24 /* This is reusing the GICv3ITSState typedef from ARM_GICV3_ITS_COMMON */
     25 DECLARE_OBJ_CHECKERS(GICv3ITSState, GICv3ITSClass,
     26                      ARM_GICV3_ITS, TYPE_ARM_GICV3_ITS)
     27 
     28 struct GICv3ITSClass {
     29     GICv3ITSCommonClass parent_class;
     30     void (*parent_reset)(DeviceState *dev);
     31 };
     32 
     33 /*
     34  * This is an internal enum used to distinguish between LPI triggered
     35  * via command queue and LPI triggered via gits_translater write.
     36  */
     37 typedef enum ItsCmdType {
     38     NONE = 0, /* internal indication for GITS_TRANSLATER write */
     39     CLEAR = 1,
     40     DISCARD = 2,
     41     INTERRUPT = 3,
     42 } ItsCmdType;
     43 
     44 typedef struct DTEntry {
     45     bool valid;
     46     unsigned size;
     47     uint64_t ittaddr;
     48 } DTEntry;
     49 
     50 typedef struct CTEntry {
     51     bool valid;
     52     uint32_t rdbase;
     53 } CTEntry;
     54 
     55 typedef struct ITEntry {
     56     bool valid;
     57     int inttype;
     58     uint32_t intid;
     59     uint32_t doorbell;
     60     uint32_t icid;
     61     uint32_t vpeid;
     62 } ITEntry;
     63 
     64 typedef struct VTEntry {
     65     bool valid;
     66     unsigned vptsize;
     67     uint32_t rdbase;
     68     uint64_t vptaddr;
     69 } VTEntry;
     70 
     71 /*
     72  * The ITS spec permits a range of CONSTRAINED UNPREDICTABLE options
     73  * if a command parameter is not correct. These include both "stall
     74  * processing of the command queue" and "ignore this command, and
     75  * keep processing the queue". In our implementation we choose that
     76  * memory transaction errors reading the command packet provoke a
     77  * stall, but errors in parameters cause us to ignore the command
     78  * and continue processing.
     79  * The process_* functions which handle individual ITS commands all
     80  * return an ItsCmdResult which tells process_cmdq() whether it should
     81  * stall, keep going because of an error, or keep going because the
     82  * command was a success.
     83  */
     84 typedef enum ItsCmdResult {
     85     CMD_STALL = 0,
     86     CMD_CONTINUE = 1,
     87     CMD_CONTINUE_OK = 2,
     88 } ItsCmdResult;
     89 
     90 /* True if the ITS supports the GICv4 virtual LPI feature */
     91 static bool its_feature_virtual(GICv3ITSState *s)
     92 {
     93     return s->typer & R_GITS_TYPER_VIRTUAL_MASK;
     94 }
     95 
     96 static inline bool intid_in_lpi_range(uint32_t id)
     97 {
     98     return id >= GICV3_LPI_INTID_START &&
     99         id < (1 << (GICD_TYPER_IDBITS + 1));
    100 }
    101 
    102 static inline bool valid_doorbell(uint32_t id)
    103 {
    104     /* Doorbell fields may be an LPI, or 1023 to mean "no doorbell" */
    105     return id == INTID_SPURIOUS || intid_in_lpi_range(id);
    106 }
    107 
    108 static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz)
    109 {
    110     uint64_t result = 0;
    111 
    112     switch (page_sz) {
    113     case GITS_PAGE_SIZE_4K:
    114     case GITS_PAGE_SIZE_16K:
    115         result = FIELD_EX64(value, GITS_BASER, PHYADDR) << 12;
    116         break;
    117 
    118     case GITS_PAGE_SIZE_64K:
    119         result = FIELD_EX64(value, GITS_BASER, PHYADDRL_64K) << 16;
    120         result |= FIELD_EX64(value, GITS_BASER, PHYADDRH_64K) << 48;
    121         break;
    122 
    123     default:
    124         break;
    125     }
    126     return result;
    127 }
    128 
    129 static uint64_t table_entry_addr(GICv3ITSState *s, TableDesc *td,
    130                                  uint32_t idx, MemTxResult *res)
    131 {
    132     /*
    133      * Given a TableDesc describing one of the ITS in-guest-memory
    134      * tables and an index into it, return the guest address
    135      * corresponding to that table entry.
    136      * If there was a memory error reading the L1 table of an
    137      * indirect table, *res is set accordingly, and we return -1.
    138      * If the L1 table entry is marked not valid, we return -1 with
    139      * *res set to MEMTX_OK.
    140      *
    141      * The specification defines the format of level 1 entries of a
    142      * 2-level table, but the format of level 2 entries and the format
    143      * of flat-mapped tables is IMPDEF.
    144      */
    145     AddressSpace *as = &s->gicv3->dma_as;
    146     uint32_t l2idx;
    147     uint64_t l2;
    148     uint32_t num_l2_entries;
    149 
    150     *res = MEMTX_OK;
    151 
    152     if (!td->indirect) {
    153         /* Single level table */
    154         return td->base_addr + idx * td->entry_sz;
    155     }
    156 
    157     /* Two level table */
    158     l2idx = idx / (td->page_sz / L1TABLE_ENTRY_SIZE);
    159 
    160     l2 = address_space_ldq_le(as,
    161                               td->base_addr + (l2idx * L1TABLE_ENTRY_SIZE),
    162                               MEMTXATTRS_UNSPECIFIED, res);
    163     if (*res != MEMTX_OK) {
    164         return -1;
    165     }
    166     if (!(l2 & L2_TABLE_VALID_MASK)) {
    167         return -1;
    168     }
    169 
    170     num_l2_entries = td->page_sz / td->entry_sz;
    171     return (l2 & ((1ULL << 51) - 1)) + (idx % num_l2_entries) * td->entry_sz;
    172 }
    173 
    174 /*
    175  * Read the Collection Table entry at index @icid. On success (including
    176  * successfully determining that there is no valid CTE for this index),
    177  * we return MEMTX_OK and populate the CTEntry struct @cte accordingly.
    178  * If there is an error reading memory then we return the error code.
    179  */
    180 static MemTxResult get_cte(GICv3ITSState *s, uint16_t icid, CTEntry *cte)
    181 {
    182     AddressSpace *as = &s->gicv3->dma_as;
    183     MemTxResult res = MEMTX_OK;
    184     uint64_t entry_addr = table_entry_addr(s, &s->ct, icid, &res);
    185     uint64_t cteval;
    186 
    187     if (entry_addr == -1) {
    188         /* No L2 table entry, i.e. no valid CTE, or a memory error */
    189         cte->valid = false;
    190         goto out;
    191     }
    192 
    193     cteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, &res);
    194     if (res != MEMTX_OK) {
    195         goto out;
    196     }
    197     cte->valid = FIELD_EX64(cteval, CTE, VALID);
    198     cte->rdbase = FIELD_EX64(cteval, CTE, RDBASE);
    199 out:
    200     if (res != MEMTX_OK) {
    201         trace_gicv3_its_cte_read_fault(icid);
    202     } else {
    203         trace_gicv3_its_cte_read(icid, cte->valid, cte->rdbase);
    204     }
    205     return res;
    206 }
    207 
    208 /*
    209  * Update the Interrupt Table entry at index @evinted in the table specified
    210  * by the dte @dte. Returns true on success, false if there was a memory
    211  * access error.
    212  */
    213 static bool update_ite(GICv3ITSState *s, uint32_t eventid, const DTEntry *dte,
    214                        const ITEntry *ite)
    215 {
    216     AddressSpace *as = &s->gicv3->dma_as;
    217     MemTxResult res = MEMTX_OK;
    218     hwaddr iteaddr = dte->ittaddr + eventid * ITS_ITT_ENTRY_SIZE;
    219     uint64_t itel = 0;
    220     uint32_t iteh = 0;
    221 
    222     trace_gicv3_its_ite_write(dte->ittaddr, eventid, ite->valid,
    223                               ite->inttype, ite->intid, ite->icid,
    224                               ite->vpeid, ite->doorbell);
    225 
    226     if (ite->valid) {
    227         itel = FIELD_DP64(itel, ITE_L, VALID, 1);
    228         itel = FIELD_DP64(itel, ITE_L, INTTYPE, ite->inttype);
    229         itel = FIELD_DP64(itel, ITE_L, INTID, ite->intid);
    230         itel = FIELD_DP64(itel, ITE_L, ICID, ite->icid);
    231         itel = FIELD_DP64(itel, ITE_L, VPEID, ite->vpeid);
    232         iteh = FIELD_DP32(iteh, ITE_H, DOORBELL, ite->doorbell);
    233     }
    234 
    235     address_space_stq_le(as, iteaddr, itel, MEMTXATTRS_UNSPECIFIED, &res);
    236     if (res != MEMTX_OK) {
    237         return false;
    238     }
    239     address_space_stl_le(as, iteaddr + 8, iteh, MEMTXATTRS_UNSPECIFIED, &res);
    240     return res == MEMTX_OK;
    241 }
    242 
    243 /*
    244  * Read the Interrupt Table entry at index @eventid from the table specified
    245  * by the DTE @dte. On success, we return MEMTX_OK and populate the ITEntry
    246  * struct @ite accordingly. If there is an error reading memory then we return
    247  * the error code.
    248  */
    249 static MemTxResult get_ite(GICv3ITSState *s, uint32_t eventid,
    250                            const DTEntry *dte, ITEntry *ite)
    251 {
    252     AddressSpace *as = &s->gicv3->dma_as;
    253     MemTxResult res = MEMTX_OK;
    254     uint64_t itel;
    255     uint32_t iteh;
    256     hwaddr iteaddr = dte->ittaddr + eventid * ITS_ITT_ENTRY_SIZE;
    257 
    258     itel = address_space_ldq_le(as, iteaddr, MEMTXATTRS_UNSPECIFIED, &res);
    259     if (res != MEMTX_OK) {
    260         trace_gicv3_its_ite_read_fault(dte->ittaddr, eventid);
    261         return res;
    262     }
    263 
    264     iteh = address_space_ldl_le(as, iteaddr + 8, MEMTXATTRS_UNSPECIFIED, &res);
    265     if (res != MEMTX_OK) {
    266         trace_gicv3_its_ite_read_fault(dte->ittaddr, eventid);
    267         return res;
    268     }
    269 
    270     ite->valid = FIELD_EX64(itel, ITE_L, VALID);
    271     ite->inttype = FIELD_EX64(itel, ITE_L, INTTYPE);
    272     ite->intid = FIELD_EX64(itel, ITE_L, INTID);
    273     ite->icid = FIELD_EX64(itel, ITE_L, ICID);
    274     ite->vpeid = FIELD_EX64(itel, ITE_L, VPEID);
    275     ite->doorbell = FIELD_EX64(iteh, ITE_H, DOORBELL);
    276     trace_gicv3_its_ite_read(dte->ittaddr, eventid, ite->valid,
    277                              ite->inttype, ite->intid, ite->icid,
    278                              ite->vpeid, ite->doorbell);
    279     return MEMTX_OK;
    280 }
    281 
    282 /*
    283  * Read the Device Table entry at index @devid. On success (including
    284  * successfully determining that there is no valid DTE for this index),
    285  * we return MEMTX_OK and populate the DTEntry struct accordingly.
    286  * If there is an error reading memory then we return the error code.
    287  */
    288 static MemTxResult get_dte(GICv3ITSState *s, uint32_t devid, DTEntry *dte)
    289 {
    290     MemTxResult res = MEMTX_OK;
    291     AddressSpace *as = &s->gicv3->dma_as;
    292     uint64_t entry_addr = table_entry_addr(s, &s->dt, devid, &res);
    293     uint64_t dteval;
    294 
    295     if (entry_addr == -1) {
    296         /* No L2 table entry, i.e. no valid DTE, or a memory error */
    297         dte->valid = false;
    298         goto out;
    299     }
    300     dteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, &res);
    301     if (res != MEMTX_OK) {
    302         goto out;
    303     }
    304     dte->valid = FIELD_EX64(dteval, DTE, VALID);
    305     dte->size = FIELD_EX64(dteval, DTE, SIZE);
    306     /* DTE word field stores bits [51:8] of the ITT address */
    307     dte->ittaddr = FIELD_EX64(dteval, DTE, ITTADDR) << ITTADDR_SHIFT;
    308 out:
    309     if (res != MEMTX_OK) {
    310         trace_gicv3_its_dte_read_fault(devid);
    311     } else {
    312         trace_gicv3_its_dte_read(devid, dte->valid, dte->size, dte->ittaddr);
    313     }
    314     return res;
    315 }
    316 
    317 /*
    318  * Read the vPE Table entry at index @vpeid. On success (including
    319  * successfully determining that there is no valid entry for this index),
    320  * we return MEMTX_OK and populate the VTEntry struct accordingly.
    321  * If there is an error reading memory then we return the error code.
    322  */
    323 static MemTxResult get_vte(GICv3ITSState *s, uint32_t vpeid, VTEntry *vte)
    324 {
    325     MemTxResult res = MEMTX_OK;
    326     AddressSpace *as = &s->gicv3->dma_as;
    327     uint64_t entry_addr = table_entry_addr(s, &s->vpet, vpeid, &res);
    328     uint64_t vteval;
    329 
    330     if (entry_addr == -1) {
    331         /* No L2 table entry, i.e. no valid VTE, or a memory error */
    332         vte->valid = false;
    333         goto out;
    334     }
    335     vteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, &res);
    336     if (res != MEMTX_OK) {
    337         goto out;
    338     }
    339     vte->valid = FIELD_EX64(vteval, VTE, VALID);
    340     vte->vptsize = FIELD_EX64(vteval, VTE, VPTSIZE);
    341     vte->vptaddr = FIELD_EX64(vteval, VTE, VPTADDR);
    342     vte->rdbase = FIELD_EX64(vteval, VTE, RDBASE);
    343 out:
    344     if (res != MEMTX_OK) {
    345         trace_gicv3_its_vte_read_fault(vpeid);
    346     } else {
    347         trace_gicv3_its_vte_read(vpeid, vte->valid, vte->vptsize,
    348                                  vte->vptaddr, vte->rdbase);
    349     }
    350     return res;
    351 }
    352 
    353 /*
    354  * Given a (DeviceID, EventID), look up the corresponding ITE, including
    355  * checking for the various invalid-value cases. If we find a valid ITE,
    356  * fill in @ite and @dte and return CMD_CONTINUE_OK. Otherwise return
    357  * CMD_STALL or CMD_CONTINUE as appropriate (and the contents of @ite
    358  * should not be relied on).
    359  *
    360  * The string @who is purely for the LOG_GUEST_ERROR messages,
    361  * and should indicate the name of the calling function or similar.
    362  */
    363 static ItsCmdResult lookup_ite(GICv3ITSState *s, const char *who,
    364                                uint32_t devid, uint32_t eventid, ITEntry *ite,
    365                                DTEntry *dte)
    366 {
    367     uint64_t num_eventids;
    368 
    369     if (devid >= s->dt.num_entries) {
    370         qemu_log_mask(LOG_GUEST_ERROR,
    371                       "%s: invalid command attributes: devid %d>=%d",
    372                       who, devid, s->dt.num_entries);
    373         return CMD_CONTINUE;
    374     }
    375 
    376     if (get_dte(s, devid, dte) != MEMTX_OK) {
    377         return CMD_STALL;
    378     }
    379     if (!dte->valid) {
    380         qemu_log_mask(LOG_GUEST_ERROR,
    381                       "%s: invalid command attributes: "
    382                       "invalid dte for %d\n", who, devid);
    383         return CMD_CONTINUE;
    384     }
    385 
    386     num_eventids = 1ULL << (dte->size + 1);
    387     if (eventid >= num_eventids) {
    388         qemu_log_mask(LOG_GUEST_ERROR,
    389                       "%s: invalid command attributes: eventid %d >= %"
    390                       PRId64 "\n", who, eventid, num_eventids);
    391         return CMD_CONTINUE;
    392     }
    393 
    394     if (get_ite(s, eventid, dte, ite) != MEMTX_OK) {
    395         return CMD_STALL;
    396     }
    397 
    398     if (!ite->valid) {
    399         qemu_log_mask(LOG_GUEST_ERROR,
    400                       "%s: invalid command attributes: invalid ITE\n", who);
    401         return CMD_CONTINUE;
    402     }
    403 
    404     return CMD_CONTINUE_OK;
    405 }
    406 
    407 /*
    408  * Given an ICID, look up the corresponding CTE, including checking for various
    409  * invalid-value cases. If we find a valid CTE, fill in @cte and return
    410  * CMD_CONTINUE_OK; otherwise return CMD_STALL or CMD_CONTINUE (and the
    411  * contents of @cte should not be relied on).
    412  *
    413  * The string @who is purely for the LOG_GUEST_ERROR messages,
    414  * and should indicate the name of the calling function or similar.
    415  */
    416 static ItsCmdResult lookup_cte(GICv3ITSState *s, const char *who,
    417                                uint32_t icid, CTEntry *cte)
    418 {
    419     if (icid >= s->ct.num_entries) {
    420         qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid ICID 0x%x\n", who, icid);
    421         return CMD_CONTINUE;
    422     }
    423     if (get_cte(s, icid, cte) != MEMTX_OK) {
    424         return CMD_STALL;
    425     }
    426     if (!cte->valid) {
    427         qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid CTE\n", who);
    428         return CMD_CONTINUE;
    429     }
    430     if (cte->rdbase >= s->gicv3->num_cpu) {
    431         return CMD_CONTINUE;
    432     }
    433     return CMD_CONTINUE_OK;
    434 }
    435 
    436 /*
    437  * Given a VPEID, look up the corresponding VTE, including checking
    438  * for various invalid-value cases. if we find a valid VTE, fill in @vte
    439  * and return CMD_CONTINUE_OK; otherwise return CMD_STALL or CMD_CONTINUE
    440  * (and the contents of @vte should not be relied on).
    441  *
    442  * The string @who is purely for the LOG_GUEST_ERROR messages,
    443  * and should indicate the name of the calling function or similar.
    444  */
    445 static ItsCmdResult lookup_vte(GICv3ITSState *s, const char *who,
    446                                uint32_t vpeid, VTEntry *vte)
    447 {
    448     if (vpeid >= s->vpet.num_entries) {
    449         qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid VPEID 0x%x\n", who, vpeid);
    450         return CMD_CONTINUE;
    451     }
    452 
    453     if (get_vte(s, vpeid, vte) != MEMTX_OK) {
    454         return CMD_STALL;
    455     }
    456     if (!vte->valid) {
    457         qemu_log_mask(LOG_GUEST_ERROR,
    458                       "%s: invalid VTE for VPEID 0x%x\n", who, vpeid);
    459         return CMD_CONTINUE;
    460     }
    461 
    462     if (vte->rdbase >= s->gicv3->num_cpu) {
    463         return CMD_CONTINUE;
    464     }
    465     return CMD_CONTINUE_OK;
    466 }
    467 
    468 static ItsCmdResult process_its_cmd_phys(GICv3ITSState *s, const ITEntry *ite,
    469                                          int irqlevel)
    470 {
    471     CTEntry cte;
    472     ItsCmdResult cmdres;
    473 
    474     cmdres = lookup_cte(s, __func__, ite->icid, &cte);
    475     if (cmdres != CMD_CONTINUE_OK) {
    476         return cmdres;
    477     }
    478     gicv3_redist_process_lpi(&s->gicv3->cpu[cte.rdbase], ite->intid, irqlevel);
    479     return CMD_CONTINUE_OK;
    480 }
    481 
    482 static ItsCmdResult process_its_cmd_virt(GICv3ITSState *s, const ITEntry *ite,
    483                                          int irqlevel)
    484 {
    485     VTEntry vte;
    486     ItsCmdResult cmdres;
    487 
    488     cmdres = lookup_vte(s, __func__, ite->vpeid, &vte);
    489     if (cmdres != CMD_CONTINUE_OK) {
    490         return cmdres;
    491     }
    492 
    493     if (!intid_in_lpi_range(ite->intid) ||
    494         ite->intid >= (1ULL << (vte.vptsize + 1))) {
    495         qemu_log_mask(LOG_GUEST_ERROR, "%s: intid 0x%x out of range\n",
    496                       __func__, ite->intid);
    497         return CMD_CONTINUE;
    498     }
    499 
    500     /*
    501      * For QEMU the actual pending of the vLPI is handled in the
    502      * redistributor code
    503      */
    504     gicv3_redist_process_vlpi(&s->gicv3->cpu[vte.rdbase], ite->intid,
    505                               vte.vptaddr << 16, ite->doorbell, irqlevel);
    506     return CMD_CONTINUE_OK;
    507 }
    508 
    509 /*
    510  * This function handles the processing of following commands based on
    511  * the ItsCmdType parameter passed:-
    512  * 1. triggering of lpi interrupt translation via ITS INT command
    513  * 2. triggering of lpi interrupt translation via gits_translater register
    514  * 3. handling of ITS CLEAR command
    515  * 4. handling of ITS DISCARD command
    516  */
    517 static ItsCmdResult do_process_its_cmd(GICv3ITSState *s, uint32_t devid,
    518                                        uint32_t eventid, ItsCmdType cmd)
    519 {
    520     DTEntry dte;
    521     ITEntry ite;
    522     ItsCmdResult cmdres;
    523     int irqlevel;
    524 
    525     cmdres = lookup_ite(s, __func__, devid, eventid, &ite, &dte);
    526     if (cmdres != CMD_CONTINUE_OK) {
    527         return cmdres;
    528     }
    529 
    530     irqlevel = (cmd == CLEAR || cmd == DISCARD) ? 0 : 1;
    531 
    532     switch (ite.inttype) {
    533     case ITE_INTTYPE_PHYSICAL:
    534         cmdres = process_its_cmd_phys(s, &ite, irqlevel);
    535         break;
    536     case ITE_INTTYPE_VIRTUAL:
    537         if (!its_feature_virtual(s)) {
    538             /* Can't happen unless guest is illegally writing to table memory */
    539             qemu_log_mask(LOG_GUEST_ERROR,
    540                           "%s: invalid type %d in ITE (table corrupted?)\n",
    541                           __func__, ite.inttype);
    542             return CMD_CONTINUE;
    543         }
    544         cmdres = process_its_cmd_virt(s, &ite, irqlevel);
    545         break;
    546     default:
    547         g_assert_not_reached();
    548     }
    549 
    550     if (cmdres == CMD_CONTINUE_OK && cmd == DISCARD) {
    551         ITEntry ite = {};
    552         /* remove mapping from interrupt translation table */
    553         ite.valid = false;
    554         return update_ite(s, eventid, &dte, &ite) ? CMD_CONTINUE_OK : CMD_STALL;
    555     }
    556     return CMD_CONTINUE_OK;
    557 }
    558 
    559 static ItsCmdResult process_its_cmd(GICv3ITSState *s, const uint64_t *cmdpkt,
    560                                     ItsCmdType cmd)
    561 {
    562     uint32_t devid, eventid;
    563 
    564     devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT;
    565     eventid = cmdpkt[1] & EVENTID_MASK;
    566     switch (cmd) {
    567     case INTERRUPT:
    568         trace_gicv3_its_cmd_int(devid, eventid);
    569         break;
    570     case CLEAR:
    571         trace_gicv3_its_cmd_clear(devid, eventid);
    572         break;
    573     case DISCARD:
    574         trace_gicv3_its_cmd_discard(devid, eventid);
    575         break;
    576     default:
    577         g_assert_not_reached();
    578     }
    579     return do_process_its_cmd(s, devid, eventid, cmd);
    580 }
    581 
    582 static ItsCmdResult process_mapti(GICv3ITSState *s, const uint64_t *cmdpkt,
    583                                   bool ignore_pInt)
    584 {
    585     uint32_t devid, eventid;
    586     uint32_t pIntid = 0;
    587     uint64_t num_eventids;
    588     uint16_t icid = 0;
    589     DTEntry dte;
    590     ITEntry ite;
    591 
    592     devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT;
    593     eventid = cmdpkt[1] & EVENTID_MASK;
    594     icid = cmdpkt[2] & ICID_MASK;
    595 
    596     if (ignore_pInt) {
    597         pIntid = eventid;
    598         trace_gicv3_its_cmd_mapi(devid, eventid, icid);
    599     } else {
    600         pIntid = (cmdpkt[1] & pINTID_MASK) >> pINTID_SHIFT;
    601         trace_gicv3_its_cmd_mapti(devid, eventid, icid, pIntid);
    602     }
    603 
    604     if (devid >= s->dt.num_entries) {
    605         qemu_log_mask(LOG_GUEST_ERROR,
    606                       "%s: invalid command attributes: devid %d>=%d",
    607                       __func__, devid, s->dt.num_entries);
    608         return CMD_CONTINUE;
    609     }
    610 
    611     if (get_dte(s, devid, &dte) != MEMTX_OK) {
    612         return CMD_STALL;
    613     }
    614     num_eventids = 1ULL << (dte.size + 1);
    615 
    616     if (icid >= s->ct.num_entries) {
    617         qemu_log_mask(LOG_GUEST_ERROR,
    618                       "%s: invalid ICID 0x%x >= 0x%x\n",
    619                       __func__, icid, s->ct.num_entries);
    620         return CMD_CONTINUE;
    621     }
    622 
    623     if (!dte.valid) {
    624         qemu_log_mask(LOG_GUEST_ERROR,
    625                       "%s: no valid DTE for devid 0x%x\n", __func__, devid);
    626         return CMD_CONTINUE;
    627     }
    628 
    629     if (eventid >= num_eventids) {
    630         qemu_log_mask(LOG_GUEST_ERROR,
    631                       "%s: invalid event ID 0x%x >= 0x%" PRIx64 "\n",
    632                       __func__, eventid, num_eventids);
    633         return CMD_CONTINUE;
    634     }
    635 
    636     if (!intid_in_lpi_range(pIntid)) {
    637         qemu_log_mask(LOG_GUEST_ERROR,
    638                       "%s: invalid interrupt ID 0x%x\n", __func__, pIntid);
    639         return CMD_CONTINUE;
    640     }
    641 
    642     /* add ite entry to interrupt translation table */
    643     ite.valid = true;
    644     ite.inttype = ITE_INTTYPE_PHYSICAL;
    645     ite.intid = pIntid;
    646     ite.icid = icid;
    647     ite.doorbell = INTID_SPURIOUS;
    648     ite.vpeid = 0;
    649     return update_ite(s, eventid, &dte, &ite) ? CMD_CONTINUE_OK : CMD_STALL;
    650 }
    651 
    652 static ItsCmdResult process_vmapti(GICv3ITSState *s, const uint64_t *cmdpkt,
    653                                    bool ignore_vintid)
    654 {
    655     uint32_t devid, eventid, vintid, doorbell, vpeid;
    656     uint32_t num_eventids;
    657     DTEntry dte;
    658     ITEntry ite;
    659 
    660     if (!its_feature_virtual(s)) {
    661         return CMD_CONTINUE;
    662     }
    663 
    664     devid = FIELD_EX64(cmdpkt[0], VMAPTI_0, DEVICEID);
    665     eventid = FIELD_EX64(cmdpkt[1], VMAPTI_1, EVENTID);
    666     vpeid = FIELD_EX64(cmdpkt[1], VMAPTI_1, VPEID);
    667     doorbell = FIELD_EX64(cmdpkt[2], VMAPTI_2, DOORBELL);
    668     if (ignore_vintid) {
    669         vintid = eventid;
    670         trace_gicv3_its_cmd_vmapi(devid, eventid, vpeid, doorbell);
    671     } else {
    672         vintid = FIELD_EX64(cmdpkt[2], VMAPTI_2, VINTID);
    673         trace_gicv3_its_cmd_vmapti(devid, eventid, vpeid, vintid, doorbell);
    674     }
    675 
    676     if (devid >= s->dt.num_entries) {
    677         qemu_log_mask(LOG_GUEST_ERROR,
    678                       "%s: invalid DeviceID 0x%x (must be less than 0x%x)\n",
    679                       __func__, devid, s->dt.num_entries);
    680         return CMD_CONTINUE;
    681     }
    682 
    683     if (get_dte(s, devid, &dte) != MEMTX_OK) {
    684         return CMD_STALL;
    685     }
    686 
    687     if (!dte.valid) {
    688         qemu_log_mask(LOG_GUEST_ERROR,
    689                       "%s: no entry in device table for DeviceID 0x%x\n",
    690                       __func__, devid);
    691         return CMD_CONTINUE;
    692     }
    693 
    694     num_eventids = 1ULL << (dte.size + 1);
    695 
    696     if (eventid >= num_eventids) {
    697         qemu_log_mask(LOG_GUEST_ERROR,
    698                       "%s: EventID 0x%x too large for DeviceID 0x%x "
    699                       "(must be less than 0x%x)\n",
    700                       __func__, eventid, devid, num_eventids);
    701         return CMD_CONTINUE;
    702     }
    703     if (!intid_in_lpi_range(vintid)) {
    704         qemu_log_mask(LOG_GUEST_ERROR,
    705                       "%s: VIntID 0x%x not a valid LPI\n",
    706                       __func__, vintid);
    707         return CMD_CONTINUE;
    708     }
    709     if (!valid_doorbell(doorbell)) {
    710         qemu_log_mask(LOG_GUEST_ERROR,
    711                       "%s: Doorbell %d not 1023 and not a valid LPI\n",
    712                       __func__, doorbell);
    713         return CMD_CONTINUE;
    714     }
    715     if (vpeid >= s->vpet.num_entries) {
    716         qemu_log_mask(LOG_GUEST_ERROR,
    717                       "%s: VPEID 0x%x out of range (must be less than 0x%x)\n",
    718                       __func__, vpeid, s->vpet.num_entries);
    719         return CMD_CONTINUE;
    720     }
    721     /* add ite entry to interrupt translation table */
    722     ite.valid = true;
    723     ite.inttype = ITE_INTTYPE_VIRTUAL;
    724     ite.intid = vintid;
    725     ite.icid = 0;
    726     ite.doorbell = doorbell;
    727     ite.vpeid = vpeid;
    728     return update_ite(s, eventid, &dte, &ite) ? CMD_CONTINUE_OK : CMD_STALL;
    729 }
    730 
    731 /*
    732  * Update the Collection Table entry for @icid to @cte. Returns true
    733  * on success, false if there was a memory access error.
    734  */
    735 static bool update_cte(GICv3ITSState *s, uint16_t icid, const CTEntry *cte)
    736 {
    737     AddressSpace *as = &s->gicv3->dma_as;
    738     uint64_t entry_addr;
    739     uint64_t cteval = 0;
    740     MemTxResult res = MEMTX_OK;
    741 
    742     trace_gicv3_its_cte_write(icid, cte->valid, cte->rdbase);
    743 
    744     if (cte->valid) {
    745         /* add mapping entry to collection table */
    746         cteval = FIELD_DP64(cteval, CTE, VALID, 1);
    747         cteval = FIELD_DP64(cteval, CTE, RDBASE, cte->rdbase);
    748     }
    749 
    750     entry_addr = table_entry_addr(s, &s->ct, icid, &res);
    751     if (res != MEMTX_OK) {
    752         /* memory access error: stall */
    753         return false;
    754     }
    755     if (entry_addr == -1) {
    756         /* No L2 table for this index: discard write and continue */
    757         return true;
    758     }
    759 
    760     address_space_stq_le(as, entry_addr, cteval, MEMTXATTRS_UNSPECIFIED, &res);
    761     return res == MEMTX_OK;
    762 }
    763 
    764 static ItsCmdResult process_mapc(GICv3ITSState *s, const uint64_t *cmdpkt)
    765 {
    766     uint16_t icid;
    767     CTEntry cte;
    768 
    769     icid = cmdpkt[2] & ICID_MASK;
    770     cte.valid = cmdpkt[2] & CMD_FIELD_VALID_MASK;
    771     if (cte.valid) {
    772         cte.rdbase = (cmdpkt[2] & R_MAPC_RDBASE_MASK) >> R_MAPC_RDBASE_SHIFT;
    773         cte.rdbase &= RDBASE_PROCNUM_MASK;
    774     } else {
    775         cte.rdbase = 0;
    776     }
    777     trace_gicv3_its_cmd_mapc(icid, cte.rdbase, cte.valid);
    778 
    779     if (icid >= s->ct.num_entries) {
    780         qemu_log_mask(LOG_GUEST_ERROR, "ITS MAPC: invalid ICID 0x%x\n", icid);
    781         return CMD_CONTINUE;
    782     }
    783     if (cte.valid && cte.rdbase >= s->gicv3->num_cpu) {
    784         qemu_log_mask(LOG_GUEST_ERROR,
    785                       "ITS MAPC: invalid RDBASE %u\n", cte.rdbase);
    786         return CMD_CONTINUE;
    787     }
    788 
    789     return update_cte(s, icid, &cte) ? CMD_CONTINUE_OK : CMD_STALL;
    790 }
    791 
    792 /*
    793  * Update the Device Table entry for @devid to @dte. Returns true
    794  * on success, false if there was a memory access error.
    795  */
    796 static bool update_dte(GICv3ITSState *s, uint32_t devid, const DTEntry *dte)
    797 {
    798     AddressSpace *as = &s->gicv3->dma_as;
    799     uint64_t entry_addr;
    800     uint64_t dteval = 0;
    801     MemTxResult res = MEMTX_OK;
    802 
    803     trace_gicv3_its_dte_write(devid, dte->valid, dte->size, dte->ittaddr);
    804 
    805     if (dte->valid) {
    806         /* add mapping entry to device table */
    807         dteval = FIELD_DP64(dteval, DTE, VALID, 1);
    808         dteval = FIELD_DP64(dteval, DTE, SIZE, dte->size);
    809         dteval = FIELD_DP64(dteval, DTE, ITTADDR, dte->ittaddr);
    810     }
    811 
    812     entry_addr = table_entry_addr(s, &s->dt, devid, &res);
    813     if (res != MEMTX_OK) {
    814         /* memory access error: stall */
    815         return false;
    816     }
    817     if (entry_addr == -1) {
    818         /* No L2 table for this index: discard write and continue */
    819         return true;
    820     }
    821     address_space_stq_le(as, entry_addr, dteval, MEMTXATTRS_UNSPECIFIED, &res);
    822     return res == MEMTX_OK;
    823 }
    824 
    825 static ItsCmdResult process_mapd(GICv3ITSState *s, const uint64_t *cmdpkt)
    826 {
    827     uint32_t devid;
    828     DTEntry dte;
    829 
    830     devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT;
    831     dte.size = cmdpkt[1] & SIZE_MASK;
    832     dte.ittaddr = (cmdpkt[2] & ITTADDR_MASK) >> ITTADDR_SHIFT;
    833     dte.valid = cmdpkt[2] & CMD_FIELD_VALID_MASK;
    834 
    835     trace_gicv3_its_cmd_mapd(devid, dte.size, dte.ittaddr, dte.valid);
    836 
    837     if (devid >= s->dt.num_entries) {
    838         qemu_log_mask(LOG_GUEST_ERROR,
    839                       "ITS MAPD: invalid device ID field 0x%x >= 0x%x\n",
    840                       devid, s->dt.num_entries);
    841         return CMD_CONTINUE;
    842     }
    843 
    844     if (dte.size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS)) {
    845         qemu_log_mask(LOG_GUEST_ERROR,
    846                       "ITS MAPD: invalid size %d\n", dte.size);
    847         return CMD_CONTINUE;
    848     }
    849 
    850     return update_dte(s, devid, &dte) ? CMD_CONTINUE_OK : CMD_STALL;
    851 }
    852 
    853 static ItsCmdResult process_movall(GICv3ITSState *s, const uint64_t *cmdpkt)
    854 {
    855     uint64_t rd1, rd2;
    856 
    857     rd1 = FIELD_EX64(cmdpkt[2], MOVALL_2, RDBASE1);
    858     rd2 = FIELD_EX64(cmdpkt[3], MOVALL_3, RDBASE2);
    859 
    860     trace_gicv3_its_cmd_movall(rd1, rd2);
    861 
    862     if (rd1 >= s->gicv3->num_cpu) {
    863         qemu_log_mask(LOG_GUEST_ERROR,
    864                       "%s: RDBASE1 %" PRId64
    865                       " out of range (must be less than %d)\n",
    866                       __func__, rd1, s->gicv3->num_cpu);
    867         return CMD_CONTINUE;
    868     }
    869     if (rd2 >= s->gicv3->num_cpu) {
    870         qemu_log_mask(LOG_GUEST_ERROR,
    871                       "%s: RDBASE2 %" PRId64
    872                       " out of range (must be less than %d)\n",
    873                       __func__, rd2, s->gicv3->num_cpu);
    874         return CMD_CONTINUE;
    875     }
    876 
    877     if (rd1 == rd2) {
    878         /* Move to same target must succeed as a no-op */
    879         return CMD_CONTINUE_OK;
    880     }
    881 
    882     /* Move all pending LPIs from redistributor 1 to redistributor 2 */
    883     gicv3_redist_movall_lpis(&s->gicv3->cpu[rd1], &s->gicv3->cpu[rd2]);
    884 
    885     return CMD_CONTINUE_OK;
    886 }
    887 
    888 static ItsCmdResult process_movi(GICv3ITSState *s, const uint64_t *cmdpkt)
    889 {
    890     uint32_t devid, eventid;
    891     uint16_t new_icid;
    892     DTEntry dte;
    893     CTEntry old_cte, new_cte;
    894     ITEntry old_ite;
    895     ItsCmdResult cmdres;
    896 
    897     devid = FIELD_EX64(cmdpkt[0], MOVI_0, DEVICEID);
    898     eventid = FIELD_EX64(cmdpkt[1], MOVI_1, EVENTID);
    899     new_icid = FIELD_EX64(cmdpkt[2], MOVI_2, ICID);
    900 
    901     trace_gicv3_its_cmd_movi(devid, eventid, new_icid);
    902 
    903     cmdres = lookup_ite(s, __func__, devid, eventid, &old_ite, &dte);
    904     if (cmdres != CMD_CONTINUE_OK) {
    905         return cmdres;
    906     }
    907 
    908     if (old_ite.inttype != ITE_INTTYPE_PHYSICAL) {
    909         qemu_log_mask(LOG_GUEST_ERROR,
    910                       "%s: invalid command attributes: invalid ITE\n",
    911                       __func__);
    912         return CMD_CONTINUE;
    913     }
    914 
    915     cmdres = lookup_cte(s, __func__, old_ite.icid, &old_cte);
    916     if (cmdres != CMD_CONTINUE_OK) {
    917         return cmdres;
    918     }
    919     cmdres = lookup_cte(s, __func__, new_icid, &new_cte);
    920     if (cmdres != CMD_CONTINUE_OK) {
    921         return cmdres;
    922     }
    923 
    924     if (old_cte.rdbase != new_cte.rdbase) {
    925         /* Move the LPI from the old redistributor to the new one */
    926         gicv3_redist_mov_lpi(&s->gicv3->cpu[old_cte.rdbase],
    927                              &s->gicv3->cpu[new_cte.rdbase],
    928                              old_ite.intid);
    929     }
    930 
    931     /* Update the ICID field in the interrupt translation table entry */
    932     old_ite.icid = new_icid;
    933     return update_ite(s, eventid, &dte, &old_ite) ? CMD_CONTINUE_OK : CMD_STALL;
    934 }
    935 
    936 /*
    937  * Update the vPE Table entry at index @vpeid with the entry @vte.
    938  * Returns true on success, false if there was a memory access error.
    939  */
    940 static bool update_vte(GICv3ITSState *s, uint32_t vpeid, const VTEntry *vte)
    941 {
    942     AddressSpace *as = &s->gicv3->dma_as;
    943     uint64_t entry_addr;
    944     uint64_t vteval = 0;
    945     MemTxResult res = MEMTX_OK;
    946 
    947     trace_gicv3_its_vte_write(vpeid, vte->valid, vte->vptsize, vte->vptaddr,
    948                               vte->rdbase);
    949 
    950     if (vte->valid) {
    951         vteval = FIELD_DP64(vteval, VTE, VALID, 1);
    952         vteval = FIELD_DP64(vteval, VTE, VPTSIZE, vte->vptsize);
    953         vteval = FIELD_DP64(vteval, VTE, VPTADDR, vte->vptaddr);
    954         vteval = FIELD_DP64(vteval, VTE, RDBASE, vte->rdbase);
    955     }
    956 
    957     entry_addr = table_entry_addr(s, &s->vpet, vpeid, &res);
    958     if (res != MEMTX_OK) {
    959         return false;
    960     }
    961     if (entry_addr == -1) {
    962         /* No L2 table for this index: discard write and continue */
    963         return true;
    964     }
    965     address_space_stq_le(as, entry_addr, vteval, MEMTXATTRS_UNSPECIFIED, &res);
    966     return res == MEMTX_OK;
    967 }
    968 
    969 static ItsCmdResult process_vmapp(GICv3ITSState *s, const uint64_t *cmdpkt)
    970 {
    971     VTEntry vte;
    972     uint32_t vpeid;
    973 
    974     if (!its_feature_virtual(s)) {
    975         return CMD_CONTINUE;
    976     }
    977 
    978     vpeid = FIELD_EX64(cmdpkt[1], VMAPP_1, VPEID);
    979     vte.rdbase = FIELD_EX64(cmdpkt[2], VMAPP_2, RDBASE);
    980     vte.valid = FIELD_EX64(cmdpkt[2], VMAPP_2, V);
    981     vte.vptsize = FIELD_EX64(cmdpkt[3], VMAPP_3, VPTSIZE);
    982     vte.vptaddr = FIELD_EX64(cmdpkt[3], VMAPP_3, VPTADDR);
    983 
    984     trace_gicv3_its_cmd_vmapp(vpeid, vte.rdbase, vte.valid,
    985                               vte.vptaddr, vte.vptsize);
    986 
    987     /*
    988      * For GICv4.0 the VPT_size field is only 5 bits, whereas we
    989      * define our field macros to include the full GICv4.1 8 bits.
    990      * The range check on VPT_size will catch the cases where
    991      * the guest set the RES0-in-GICv4.0 bits [7:6].
    992      */
    993     if (vte.vptsize > FIELD_EX64(s->typer, GITS_TYPER, IDBITS)) {
    994         qemu_log_mask(LOG_GUEST_ERROR,
    995                       "%s: invalid VPT_size 0x%x\n", __func__, vte.vptsize);
    996         return CMD_CONTINUE;
    997     }
    998 
    999     if (vte.valid && vte.rdbase >= s->gicv3->num_cpu) {
   1000         qemu_log_mask(LOG_GUEST_ERROR,
   1001                       "%s: invalid rdbase 0x%x\n", __func__, vte.rdbase);
   1002         return CMD_CONTINUE;
   1003     }
   1004 
   1005     if (vpeid >= s->vpet.num_entries) {
   1006         qemu_log_mask(LOG_GUEST_ERROR,
   1007                       "%s: VPEID 0x%x out of range (must be less than 0x%x)\n",
   1008                       __func__, vpeid, s->vpet.num_entries);
   1009         return CMD_CONTINUE;
   1010     }
   1011 
   1012     return update_vte(s, vpeid, &vte) ? CMD_CONTINUE_OK : CMD_STALL;
   1013 }
   1014 
   1015 typedef struct VmovpCallbackData {
   1016     uint64_t rdbase;
   1017     uint32_t vpeid;
   1018     /*
   1019      * Overall command result. If more than one callback finds an
   1020      * error, STALL beats CONTINUE.
   1021      */
   1022     ItsCmdResult result;
   1023 } VmovpCallbackData;
   1024 
   1025 static void vmovp_callback(gpointer data, gpointer opaque)
   1026 {
   1027     /*
   1028      * This function is called to update the VPEID field in a VPE
   1029      * table entry for this ITS. This might be because of a VMOVP
   1030      * command executed on any ITS that is connected to the same GIC
   1031      * as this ITS.  We need to read the VPE table entry for the VPEID
   1032      * and update its RDBASE field.
   1033      */
   1034     GICv3ITSState *s = data;
   1035     VmovpCallbackData *cbdata = opaque;
   1036     VTEntry vte;
   1037     ItsCmdResult cmdres;
   1038 
   1039     cmdres = lookup_vte(s, __func__, cbdata->vpeid, &vte);
   1040     switch (cmdres) {
   1041     case CMD_STALL:
   1042         cbdata->result = CMD_STALL;
   1043         return;
   1044     case CMD_CONTINUE:
   1045         if (cbdata->result != CMD_STALL) {
   1046             cbdata->result = CMD_CONTINUE;
   1047         }
   1048         return;
   1049     case CMD_CONTINUE_OK:
   1050         break;
   1051     }
   1052 
   1053     vte.rdbase = cbdata->rdbase;
   1054     if (!update_vte(s, cbdata->vpeid, &vte)) {
   1055         cbdata->result = CMD_STALL;
   1056     }
   1057 }
   1058 
   1059 static ItsCmdResult process_vmovp(GICv3ITSState *s, const uint64_t *cmdpkt)
   1060 {
   1061     VmovpCallbackData cbdata;
   1062 
   1063     if (!its_feature_virtual(s)) {
   1064         return CMD_CONTINUE;
   1065     }
   1066 
   1067     cbdata.vpeid = FIELD_EX64(cmdpkt[1], VMOVP_1, VPEID);
   1068     cbdata.rdbase = FIELD_EX64(cmdpkt[2], VMOVP_2, RDBASE);
   1069 
   1070     trace_gicv3_its_cmd_vmovp(cbdata.vpeid, cbdata.rdbase);
   1071 
   1072     if (cbdata.rdbase >= s->gicv3->num_cpu) {
   1073         return CMD_CONTINUE;
   1074     }
   1075 
   1076     /*
   1077      * Our ITS implementation reports GITS_TYPER.VMOVP == 1, which means
   1078      * that when the VMOVP command is executed on an ITS to change the
   1079      * VPEID field in a VPE table entry the change must be propagated
   1080      * to all the ITSes connected to the same GIC.
   1081      */
   1082     cbdata.result = CMD_CONTINUE_OK;
   1083     gicv3_foreach_its(s->gicv3, vmovp_callback, &cbdata);
   1084     return cbdata.result;
   1085 }
   1086 
   1087 static ItsCmdResult process_vmovi(GICv3ITSState *s, const uint64_t *cmdpkt)
   1088 {
   1089     uint32_t devid, eventid, vpeid, doorbell;
   1090     bool doorbell_valid;
   1091     DTEntry dte;
   1092     ITEntry ite;
   1093     VTEntry old_vte, new_vte;
   1094     ItsCmdResult cmdres;
   1095 
   1096     if (!its_feature_virtual(s)) {
   1097         return CMD_CONTINUE;
   1098     }
   1099 
   1100     devid = FIELD_EX64(cmdpkt[0], VMOVI_0, DEVICEID);
   1101     eventid = FIELD_EX64(cmdpkt[1], VMOVI_1, EVENTID);
   1102     vpeid = FIELD_EX64(cmdpkt[1], VMOVI_1, VPEID);
   1103     doorbell_valid = FIELD_EX64(cmdpkt[2], VMOVI_2, D);
   1104     doorbell = FIELD_EX64(cmdpkt[2], VMOVI_2, DOORBELL);
   1105 
   1106     trace_gicv3_its_cmd_vmovi(devid, eventid, vpeid, doorbell_valid, doorbell);
   1107 
   1108     if (doorbell_valid && !valid_doorbell(doorbell)) {
   1109         qemu_log_mask(LOG_GUEST_ERROR,
   1110                       "%s: invalid doorbell 0x%x\n", __func__, doorbell);
   1111         return CMD_CONTINUE;
   1112     }
   1113 
   1114     cmdres = lookup_ite(s, __func__, devid, eventid, &ite, &dte);
   1115     if (cmdres != CMD_CONTINUE_OK) {
   1116         return cmdres;
   1117     }
   1118 
   1119     if (ite.inttype != ITE_INTTYPE_VIRTUAL) {
   1120         qemu_log_mask(LOG_GUEST_ERROR, "%s: ITE is not for virtual interrupt\n",
   1121                       __func__);
   1122         return CMD_CONTINUE;
   1123     }
   1124 
   1125     cmdres = lookup_vte(s, __func__, ite.vpeid, &old_vte);
   1126     if (cmdres != CMD_CONTINUE_OK) {
   1127         return cmdres;
   1128     }
   1129     cmdres = lookup_vte(s, __func__, vpeid, &new_vte);
   1130     if (cmdres != CMD_CONTINUE_OK) {
   1131         return cmdres;
   1132     }
   1133 
   1134     if (!intid_in_lpi_range(ite.intid) ||
   1135         ite.intid >= (1ULL << (old_vte.vptsize + 1)) ||
   1136         ite.intid >= (1ULL << (new_vte.vptsize + 1))) {
   1137         qemu_log_mask(LOG_GUEST_ERROR,
   1138                       "%s: ITE intid 0x%x out of range\n",
   1139                       __func__, ite.intid);
   1140         return CMD_CONTINUE;
   1141     }
   1142 
   1143     ite.vpeid = vpeid;
   1144     if (doorbell_valid) {
   1145         ite.doorbell = doorbell;
   1146     }
   1147 
   1148     /*
   1149      * Move the LPI from the old redistributor to the new one. We don't
   1150      * need to do anything if the guest somehow specified the
   1151      * same pending table for source and destination.
   1152      */
   1153     if (old_vte.vptaddr != new_vte.vptaddr) {
   1154         gicv3_redist_mov_vlpi(&s->gicv3->cpu[old_vte.rdbase],
   1155                               old_vte.vptaddr << 16,
   1156                               &s->gicv3->cpu[new_vte.rdbase],
   1157                               new_vte.vptaddr << 16,
   1158                               ite.intid,
   1159                               ite.doorbell);
   1160     }
   1161 
   1162     /* Update the ITE to the new VPEID and possibly doorbell values */
   1163     return update_ite(s, eventid, &dte, &ite) ? CMD_CONTINUE_OK : CMD_STALL;
   1164 }
   1165 
   1166 static ItsCmdResult process_vinvall(GICv3ITSState *s, const uint64_t *cmdpkt)
   1167 {
   1168     VTEntry vte;
   1169     uint32_t vpeid;
   1170     ItsCmdResult cmdres;
   1171 
   1172     if (!its_feature_virtual(s)) {
   1173         return CMD_CONTINUE;
   1174     }
   1175 
   1176     vpeid = FIELD_EX64(cmdpkt[1], VINVALL_1, VPEID);
   1177 
   1178     trace_gicv3_its_cmd_vinvall(vpeid);
   1179 
   1180     cmdres = lookup_vte(s, __func__, vpeid, &vte);
   1181     if (cmdres != CMD_CONTINUE_OK) {
   1182         return cmdres;
   1183     }
   1184 
   1185     gicv3_redist_vinvall(&s->gicv3->cpu[vte.rdbase], vte.vptaddr << 16);
   1186     return CMD_CONTINUE_OK;
   1187 }
   1188 
   1189 static ItsCmdResult process_inv(GICv3ITSState *s, const uint64_t *cmdpkt)
   1190 {
   1191     uint32_t devid, eventid;
   1192     ITEntry ite;
   1193     DTEntry dte;
   1194     CTEntry cte;
   1195     VTEntry vte;
   1196     ItsCmdResult cmdres;
   1197 
   1198     devid = FIELD_EX64(cmdpkt[0], INV_0, DEVICEID);
   1199     eventid = FIELD_EX64(cmdpkt[1], INV_1, EVENTID);
   1200 
   1201     trace_gicv3_its_cmd_inv(devid, eventid);
   1202 
   1203     cmdres = lookup_ite(s, __func__, devid, eventid, &ite, &dte);
   1204     if (cmdres != CMD_CONTINUE_OK) {
   1205         return cmdres;
   1206     }
   1207 
   1208     switch (ite.inttype) {
   1209     case ITE_INTTYPE_PHYSICAL:
   1210         cmdres = lookup_cte(s, __func__, ite.icid, &cte);
   1211         if (cmdres != CMD_CONTINUE_OK) {
   1212             return cmdres;
   1213         }
   1214         gicv3_redist_inv_lpi(&s->gicv3->cpu[cte.rdbase], ite.intid);
   1215         break;
   1216     case ITE_INTTYPE_VIRTUAL:
   1217         if (!its_feature_virtual(s)) {
   1218             /* Can't happen unless guest is illegally writing to table memory */
   1219             qemu_log_mask(LOG_GUEST_ERROR,
   1220                           "%s: invalid type %d in ITE (table corrupted?)\n",
   1221                           __func__, ite.inttype);
   1222             return CMD_CONTINUE;
   1223         }
   1224 
   1225         cmdres = lookup_vte(s, __func__, ite.vpeid, &vte);
   1226         if (cmdres != CMD_CONTINUE_OK) {
   1227             return cmdres;
   1228         }
   1229         if (!intid_in_lpi_range(ite.intid) ||
   1230             ite.intid >= (1ULL << (vte.vptsize + 1))) {
   1231             qemu_log_mask(LOG_GUEST_ERROR, "%s: intid 0x%x out of range\n",
   1232                           __func__, ite.intid);
   1233             return CMD_CONTINUE;
   1234         }
   1235         gicv3_redist_inv_vlpi(&s->gicv3->cpu[vte.rdbase], ite.intid,
   1236                               vte.vptaddr << 16);
   1237         break;
   1238     default:
   1239         g_assert_not_reached();
   1240     }
   1241 
   1242     return CMD_CONTINUE_OK;
   1243 }
   1244 
   1245 /*
   1246  * Current implementation blocks until all
   1247  * commands are processed
   1248  */
   1249 static void process_cmdq(GICv3ITSState *s)
   1250 {
   1251     uint32_t wr_offset = 0;
   1252     uint32_t rd_offset = 0;
   1253     uint32_t cq_offset = 0;
   1254     AddressSpace *as = &s->gicv3->dma_as;
   1255     uint8_t cmd;
   1256     int i;
   1257 
   1258     if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
   1259         return;
   1260     }
   1261 
   1262     wr_offset = FIELD_EX64(s->cwriter, GITS_CWRITER, OFFSET);
   1263 
   1264     if (wr_offset >= s->cq.num_entries) {
   1265         qemu_log_mask(LOG_GUEST_ERROR,
   1266                       "%s: invalid write offset "
   1267                       "%d\n", __func__, wr_offset);
   1268         return;
   1269     }
   1270 
   1271     rd_offset = FIELD_EX64(s->creadr, GITS_CREADR, OFFSET);
   1272 
   1273     if (rd_offset >= s->cq.num_entries) {
   1274         qemu_log_mask(LOG_GUEST_ERROR,
   1275                       "%s: invalid read offset "
   1276                       "%d\n", __func__, rd_offset);
   1277         return;
   1278     }
   1279 
   1280     while (wr_offset != rd_offset) {
   1281         ItsCmdResult result = CMD_CONTINUE_OK;
   1282         void *hostmem;
   1283         hwaddr buflen;
   1284         uint64_t cmdpkt[GITS_CMDQ_ENTRY_WORDS];
   1285 
   1286         cq_offset = (rd_offset * GITS_CMDQ_ENTRY_SIZE);
   1287 
   1288         buflen = GITS_CMDQ_ENTRY_SIZE;
   1289         hostmem = address_space_map(as, s->cq.base_addr + cq_offset,
   1290                                     &buflen, false, MEMTXATTRS_UNSPECIFIED);
   1291         if (!hostmem || buflen != GITS_CMDQ_ENTRY_SIZE) {
   1292             if (hostmem) {
   1293                 address_space_unmap(as, hostmem, buflen, false, 0);
   1294             }
   1295             s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, STALLED, 1);
   1296             qemu_log_mask(LOG_GUEST_ERROR,
   1297                           "%s: could not read command at 0x%" PRIx64 "\n",
   1298                           __func__, s->cq.base_addr + cq_offset);
   1299             break;
   1300         }
   1301         for (i = 0; i < ARRAY_SIZE(cmdpkt); i++) {
   1302             cmdpkt[i] = ldq_le_p(hostmem + i * sizeof(uint64_t));
   1303         }
   1304         address_space_unmap(as, hostmem, buflen, false, 0);
   1305 
   1306         cmd = cmdpkt[0] & CMD_MASK;
   1307 
   1308         trace_gicv3_its_process_command(rd_offset, cmd);
   1309 
   1310         switch (cmd) {
   1311         case GITS_CMD_INT:
   1312             result = process_its_cmd(s, cmdpkt, INTERRUPT);
   1313             break;
   1314         case GITS_CMD_CLEAR:
   1315             result = process_its_cmd(s, cmdpkt, CLEAR);
   1316             break;
   1317         case GITS_CMD_SYNC:
   1318             /*
   1319              * Current implementation makes a blocking synchronous call
   1320              * for every command issued earlier, hence the internal state
   1321              * is already consistent by the time SYNC command is executed.
   1322              * Hence no further processing is required for SYNC command.
   1323              */
   1324             trace_gicv3_its_cmd_sync();
   1325             break;
   1326         case GITS_CMD_VSYNC:
   1327             /*
   1328              * VSYNC also is a nop, because our implementation is always
   1329              * in sync.
   1330              */
   1331             if (!its_feature_virtual(s)) {
   1332                 result = CMD_CONTINUE;
   1333                 break;
   1334             }
   1335             trace_gicv3_its_cmd_vsync();
   1336             break;
   1337         case GITS_CMD_MAPD:
   1338             result = process_mapd(s, cmdpkt);
   1339             break;
   1340         case GITS_CMD_MAPC:
   1341             result = process_mapc(s, cmdpkt);
   1342             break;
   1343         case GITS_CMD_MAPTI:
   1344             result = process_mapti(s, cmdpkt, false);
   1345             break;
   1346         case GITS_CMD_MAPI:
   1347             result = process_mapti(s, cmdpkt, true);
   1348             break;
   1349         case GITS_CMD_DISCARD:
   1350             result = process_its_cmd(s, cmdpkt, DISCARD);
   1351             break;
   1352         case GITS_CMD_INV:
   1353             result = process_inv(s, cmdpkt);
   1354             break;
   1355         case GITS_CMD_INVALL:
   1356             /*
   1357              * Current implementation doesn't cache any ITS tables,
   1358              * but the calculated lpi priority information. We only
   1359              * need to trigger lpi priority re-calculation to be in
   1360              * sync with LPI config table or pending table changes.
   1361              * INVALL operates on a collection specified by ICID so
   1362              * it only affects physical LPIs.
   1363              */
   1364             trace_gicv3_its_cmd_invall();
   1365             for (i = 0; i < s->gicv3->num_cpu; i++) {
   1366                 gicv3_redist_update_lpi(&s->gicv3->cpu[i]);
   1367             }
   1368             break;
   1369         case GITS_CMD_MOVI:
   1370             result = process_movi(s, cmdpkt);
   1371             break;
   1372         case GITS_CMD_MOVALL:
   1373             result = process_movall(s, cmdpkt);
   1374             break;
   1375         case GITS_CMD_VMAPTI:
   1376             result = process_vmapti(s, cmdpkt, false);
   1377             break;
   1378         case GITS_CMD_VMAPI:
   1379             result = process_vmapti(s, cmdpkt, true);
   1380             break;
   1381         case GITS_CMD_VMAPP:
   1382             result = process_vmapp(s, cmdpkt);
   1383             break;
   1384         case GITS_CMD_VMOVP:
   1385             result = process_vmovp(s, cmdpkt);
   1386             break;
   1387         case GITS_CMD_VMOVI:
   1388             result = process_vmovi(s, cmdpkt);
   1389             break;
   1390         case GITS_CMD_VINVALL:
   1391             result = process_vinvall(s, cmdpkt);
   1392             break;
   1393         default:
   1394             trace_gicv3_its_cmd_unknown(cmd);
   1395             break;
   1396         }
   1397         if (result != CMD_STALL) {
   1398             /* CMD_CONTINUE or CMD_CONTINUE_OK */
   1399             rd_offset++;
   1400             rd_offset %= s->cq.num_entries;
   1401             s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, OFFSET, rd_offset);
   1402         } else {
   1403             /* CMD_STALL */
   1404             s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, STALLED, 1);
   1405             qemu_log_mask(LOG_GUEST_ERROR,
   1406                           "%s: 0x%x cmd processing failed, stalling\n",
   1407                           __func__, cmd);
   1408             break;
   1409         }
   1410     }
   1411 }
   1412 
   1413 /*
   1414  * This function extracts the ITS Device and Collection table specific
   1415  * parameters (like base_addr, size etc) from GITS_BASER register.
   1416  * It is called during ITS enable and also during post_load migration
   1417  */
   1418 static void extract_table_params(GICv3ITSState *s)
   1419 {
   1420     uint16_t num_pages = 0;
   1421     uint8_t  page_sz_type;
   1422     uint8_t type;
   1423     uint32_t page_sz = 0;
   1424     uint64_t value;
   1425 
   1426     for (int i = 0; i < 8; i++) {
   1427         TableDesc *td;
   1428         int idbits;
   1429 
   1430         value = s->baser[i];
   1431 
   1432         if (!value) {
   1433             continue;
   1434         }
   1435 
   1436         page_sz_type = FIELD_EX64(value, GITS_BASER, PAGESIZE);
   1437 
   1438         switch (page_sz_type) {
   1439         case 0:
   1440             page_sz = GITS_PAGE_SIZE_4K;
   1441             break;
   1442 
   1443         case 1:
   1444             page_sz = GITS_PAGE_SIZE_16K;
   1445             break;
   1446 
   1447         case 2:
   1448         case 3:
   1449             page_sz = GITS_PAGE_SIZE_64K;
   1450             break;
   1451 
   1452         default:
   1453             g_assert_not_reached();
   1454         }
   1455 
   1456         num_pages = FIELD_EX64(value, GITS_BASER, SIZE) + 1;
   1457 
   1458         type = FIELD_EX64(value, GITS_BASER, TYPE);
   1459 
   1460         switch (type) {
   1461         case GITS_BASER_TYPE_DEVICE:
   1462             td = &s->dt;
   1463             idbits = FIELD_EX64(s->typer, GITS_TYPER, DEVBITS) + 1;
   1464             break;
   1465         case GITS_BASER_TYPE_COLLECTION:
   1466             td = &s->ct;
   1467             if (FIELD_EX64(s->typer, GITS_TYPER, CIL)) {
   1468                 idbits = FIELD_EX64(s->typer, GITS_TYPER, CIDBITS) + 1;
   1469             } else {
   1470                 /* 16-bit CollectionId supported when CIL == 0 */
   1471                 idbits = 16;
   1472             }
   1473             break;
   1474         case GITS_BASER_TYPE_VPE:
   1475             td = &s->vpet;
   1476             /*
   1477              * For QEMU vPEIDs are always 16 bits. (GICv4.1 allows an
   1478              * implementation to implement fewer bits and report this
   1479              * via GICD_TYPER2.)
   1480              */
   1481             idbits = 16;
   1482             break;
   1483         default:
   1484             /*
   1485              * GITS_BASER<n>.TYPE is read-only, so GITS_BASER_RO_MASK
   1486              * ensures we will only see type values corresponding to
   1487              * the values set up in gicv3_its_reset().
   1488              */
   1489             g_assert_not_reached();
   1490         }
   1491 
   1492         memset(td, 0, sizeof(*td));
   1493         /*
   1494          * If GITS_BASER<n>.Valid is 0 for any <n> then we will not process
   1495          * interrupts. (GITS_TYPER.HCC is 0 for this implementation, so we
   1496          * do not have a special case where the GITS_BASER<n>.Valid bit is 0
   1497          * for the register corresponding to the Collection table but we
   1498          * still have to process interrupts using non-memory-backed
   1499          * Collection table entries.)
   1500          * The specification makes it UNPREDICTABLE to enable the ITS without
   1501          * marking each BASER<n> as valid. We choose to handle these as if
   1502          * the table was zero-sized, so commands using the table will fail
   1503          * and interrupts requested via GITS_TRANSLATER writes will be ignored.
   1504          * This happens automatically by leaving the num_entries field at
   1505          * zero, which will be caught by the bounds checks we have before
   1506          * every table lookup anyway.
   1507          */
   1508         if (!FIELD_EX64(value, GITS_BASER, VALID)) {
   1509             continue;
   1510         }
   1511         td->page_sz = page_sz;
   1512         td->indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
   1513         td->entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE) + 1;
   1514         td->base_addr = baser_base_addr(value, page_sz);
   1515         if (!td->indirect) {
   1516             td->num_entries = (num_pages * page_sz) / td->entry_sz;
   1517         } else {
   1518             td->num_entries = (((num_pages * page_sz) /
   1519                                   L1TABLE_ENTRY_SIZE) *
   1520                                  (page_sz / td->entry_sz));
   1521         }
   1522         td->num_entries = MIN(td->num_entries, 1ULL << idbits);
   1523     }
   1524 }
   1525 
   1526 static void extract_cmdq_params(GICv3ITSState *s)
   1527 {
   1528     uint16_t num_pages = 0;
   1529     uint64_t value = s->cbaser;
   1530 
   1531     num_pages = FIELD_EX64(value, GITS_CBASER, SIZE) + 1;
   1532 
   1533     memset(&s->cq, 0 , sizeof(s->cq));
   1534 
   1535     if (FIELD_EX64(value, GITS_CBASER, VALID)) {
   1536         s->cq.num_entries = (num_pages * GITS_PAGE_SIZE_4K) /
   1537                              GITS_CMDQ_ENTRY_SIZE;
   1538         s->cq.base_addr = FIELD_EX64(value, GITS_CBASER, PHYADDR);
   1539         s->cq.base_addr <<= R_GITS_CBASER_PHYADDR_SHIFT;
   1540     }
   1541 }
   1542 
   1543 static MemTxResult gicv3_its_translation_read(void *opaque, hwaddr offset,
   1544                                               uint64_t *data, unsigned size,
   1545                                               MemTxAttrs attrs)
   1546 {
   1547     /*
   1548      * GITS_TRANSLATER is write-only, and all other addresses
   1549      * in the interrupt translation space frame are RES0.
   1550      */
   1551     *data = 0;
   1552     return MEMTX_OK;
   1553 }
   1554 
   1555 static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
   1556                                                uint64_t data, unsigned size,
   1557                                                MemTxAttrs attrs)
   1558 {
   1559     GICv3ITSState *s = (GICv3ITSState *)opaque;
   1560     bool result = true;
   1561 
   1562     trace_gicv3_its_translation_write(offset, data, size, attrs.requester_id);
   1563 
   1564     switch (offset) {
   1565     case GITS_TRANSLATER:
   1566         if (s->ctlr & R_GITS_CTLR_ENABLED_MASK) {
   1567             result = do_process_its_cmd(s, attrs.requester_id, data, NONE);
   1568         }
   1569         break;
   1570     default:
   1571         break;
   1572     }
   1573 
   1574     if (result) {
   1575         return MEMTX_OK;
   1576     } else {
   1577         return MEMTX_ERROR;
   1578     }
   1579 }
   1580 
   1581 static bool its_writel(GICv3ITSState *s, hwaddr offset,
   1582                               uint64_t value, MemTxAttrs attrs)
   1583 {
   1584     bool result = true;
   1585     int index;
   1586 
   1587     switch (offset) {
   1588     case GITS_CTLR:
   1589         if (value & R_GITS_CTLR_ENABLED_MASK) {
   1590             s->ctlr |= R_GITS_CTLR_ENABLED_MASK;
   1591             extract_table_params(s);
   1592             extract_cmdq_params(s);
   1593             process_cmdq(s);
   1594         } else {
   1595             s->ctlr &= ~R_GITS_CTLR_ENABLED_MASK;
   1596         }
   1597         break;
   1598     case GITS_CBASER:
   1599         /*
   1600          * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
   1601          *                 already enabled
   1602          */
   1603         if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
   1604             s->cbaser = deposit64(s->cbaser, 0, 32, value);
   1605             s->creadr = 0;
   1606         }
   1607         break;
   1608     case GITS_CBASER + 4:
   1609         /*
   1610          * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
   1611          *                 already enabled
   1612          */
   1613         if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
   1614             s->cbaser = deposit64(s->cbaser, 32, 32, value);
   1615             s->creadr = 0;
   1616         }
   1617         break;
   1618     case GITS_CWRITER:
   1619         s->cwriter = deposit64(s->cwriter, 0, 32,
   1620                                (value & ~R_GITS_CWRITER_RETRY_MASK));
   1621         if (s->cwriter != s->creadr) {
   1622             process_cmdq(s);
   1623         }
   1624         break;
   1625     case GITS_CWRITER + 4:
   1626         s->cwriter = deposit64(s->cwriter, 32, 32, value);
   1627         break;
   1628     case GITS_CREADR:
   1629         if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) {
   1630             s->creadr = deposit64(s->creadr, 0, 32,
   1631                                   (value & ~R_GITS_CREADR_STALLED_MASK));
   1632         } else {
   1633             /* RO register, ignore the write */
   1634             qemu_log_mask(LOG_GUEST_ERROR,
   1635                           "%s: invalid guest write to RO register at offset "
   1636                           TARGET_FMT_plx "\n", __func__, offset);
   1637         }
   1638         break;
   1639     case GITS_CREADR + 4:
   1640         if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) {
   1641             s->creadr = deposit64(s->creadr, 32, 32, value);
   1642         } else {
   1643             /* RO register, ignore the write */
   1644             qemu_log_mask(LOG_GUEST_ERROR,
   1645                           "%s: invalid guest write to RO register at offset "
   1646                           TARGET_FMT_plx "\n", __func__, offset);
   1647         }
   1648         break;
   1649     case GITS_BASER ... GITS_BASER + 0x3f:
   1650         /*
   1651          * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is
   1652          *                 already enabled
   1653          */
   1654         if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
   1655             index = (offset - GITS_BASER) / 8;
   1656 
   1657             if (s->baser[index] == 0) {
   1658                 /* Unimplemented GITS_BASERn: RAZ/WI */
   1659                 break;
   1660             }
   1661             if (offset & 7) {
   1662                 value <<= 32;
   1663                 value &= ~GITS_BASER_RO_MASK;
   1664                 s->baser[index] &= GITS_BASER_RO_MASK | MAKE_64BIT_MASK(0, 32);
   1665                 s->baser[index] |= value;
   1666             } else {
   1667                 value &= ~GITS_BASER_RO_MASK;
   1668                 s->baser[index] &= GITS_BASER_RO_MASK | MAKE_64BIT_MASK(32, 32);
   1669                 s->baser[index] |= value;
   1670             }
   1671         }
   1672         break;
   1673     case GITS_IIDR:
   1674     case GITS_IDREGS ... GITS_IDREGS + 0x2f:
   1675         /* RO registers, ignore the write */
   1676         qemu_log_mask(LOG_GUEST_ERROR,
   1677                       "%s: invalid guest write to RO register at offset "
   1678                       TARGET_FMT_plx "\n", __func__, offset);
   1679         break;
   1680     default:
   1681         result = false;
   1682         break;
   1683     }
   1684     return result;
   1685 }
   1686 
   1687 static bool its_readl(GICv3ITSState *s, hwaddr offset,
   1688                              uint64_t *data, MemTxAttrs attrs)
   1689 {
   1690     bool result = true;
   1691     int index;
   1692 
   1693     switch (offset) {
   1694     case GITS_CTLR:
   1695         *data = s->ctlr;
   1696         break;
   1697     case GITS_IIDR:
   1698         *data = gicv3_iidr();
   1699         break;
   1700     case GITS_IDREGS ... GITS_IDREGS + 0x2f:
   1701         /* ID registers */
   1702         *data = gicv3_idreg(s->gicv3, offset - GITS_IDREGS, GICV3_PIDR0_ITS);
   1703         break;
   1704     case GITS_TYPER:
   1705         *data = extract64(s->typer, 0, 32);
   1706         break;
   1707     case GITS_TYPER + 4:
   1708         *data = extract64(s->typer, 32, 32);
   1709         break;
   1710     case GITS_CBASER:
   1711         *data = extract64(s->cbaser, 0, 32);
   1712         break;
   1713     case GITS_CBASER + 4:
   1714         *data = extract64(s->cbaser, 32, 32);
   1715         break;
   1716     case GITS_CREADR:
   1717         *data = extract64(s->creadr, 0, 32);
   1718         break;
   1719     case GITS_CREADR + 4:
   1720         *data = extract64(s->creadr, 32, 32);
   1721         break;
   1722     case GITS_CWRITER:
   1723         *data = extract64(s->cwriter, 0, 32);
   1724         break;
   1725     case GITS_CWRITER + 4:
   1726         *data = extract64(s->cwriter, 32, 32);
   1727         break;
   1728     case GITS_BASER ... GITS_BASER + 0x3f:
   1729         index = (offset - GITS_BASER) / 8;
   1730         if (offset & 7) {
   1731             *data = extract64(s->baser[index], 32, 32);
   1732         } else {
   1733             *data = extract64(s->baser[index], 0, 32);
   1734         }
   1735         break;
   1736     default:
   1737         result = false;
   1738         break;
   1739     }
   1740     return result;
   1741 }
   1742 
   1743 static bool its_writell(GICv3ITSState *s, hwaddr offset,
   1744                                uint64_t value, MemTxAttrs attrs)
   1745 {
   1746     bool result = true;
   1747     int index;
   1748 
   1749     switch (offset) {
   1750     case GITS_BASER ... GITS_BASER + 0x3f:
   1751         /*
   1752          * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is
   1753          *                 already enabled
   1754          */
   1755         if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
   1756             index = (offset - GITS_BASER) / 8;
   1757             if (s->baser[index] == 0) {
   1758                 /* Unimplemented GITS_BASERn: RAZ/WI */
   1759                 break;
   1760             }
   1761             s->baser[index] &= GITS_BASER_RO_MASK;
   1762             s->baser[index] |= (value & ~GITS_BASER_RO_MASK);
   1763         }
   1764         break;
   1765     case GITS_CBASER:
   1766         /*
   1767          * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
   1768          *                 already enabled
   1769          */
   1770         if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
   1771             s->cbaser = value;
   1772             s->creadr = 0;
   1773         }
   1774         break;
   1775     case GITS_CWRITER:
   1776         s->cwriter = value & ~R_GITS_CWRITER_RETRY_MASK;
   1777         if (s->cwriter != s->creadr) {
   1778             process_cmdq(s);
   1779         }
   1780         break;
   1781     case GITS_CREADR:
   1782         if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) {
   1783             s->creadr = value & ~R_GITS_CREADR_STALLED_MASK;
   1784         } else {
   1785             /* RO register, ignore the write */
   1786             qemu_log_mask(LOG_GUEST_ERROR,
   1787                           "%s: invalid guest write to RO register at offset "
   1788                           TARGET_FMT_plx "\n", __func__, offset);
   1789         }
   1790         break;
   1791     case GITS_TYPER:
   1792         /* RO registers, ignore the write */
   1793         qemu_log_mask(LOG_GUEST_ERROR,
   1794                       "%s: invalid guest write to RO register at offset "
   1795                       TARGET_FMT_plx "\n", __func__, offset);
   1796         break;
   1797     default:
   1798         result = false;
   1799         break;
   1800     }
   1801     return result;
   1802 }
   1803 
   1804 static bool its_readll(GICv3ITSState *s, hwaddr offset,
   1805                               uint64_t *data, MemTxAttrs attrs)
   1806 {
   1807     bool result = true;
   1808     int index;
   1809 
   1810     switch (offset) {
   1811     case GITS_TYPER:
   1812         *data = s->typer;
   1813         break;
   1814     case GITS_BASER ... GITS_BASER + 0x3f:
   1815         index = (offset - GITS_BASER) / 8;
   1816         *data = s->baser[index];
   1817         break;
   1818     case GITS_CBASER:
   1819         *data = s->cbaser;
   1820         break;
   1821     case GITS_CREADR:
   1822         *data = s->creadr;
   1823         break;
   1824     case GITS_CWRITER:
   1825         *data = s->cwriter;
   1826         break;
   1827     default:
   1828         result = false;
   1829         break;
   1830     }
   1831     return result;
   1832 }
   1833 
   1834 static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
   1835                                   unsigned size, MemTxAttrs attrs)
   1836 {
   1837     GICv3ITSState *s = (GICv3ITSState *)opaque;
   1838     bool result;
   1839 
   1840     switch (size) {
   1841     case 4:
   1842         result = its_readl(s, offset, data, attrs);
   1843         break;
   1844     case 8:
   1845         result = its_readll(s, offset, data, attrs);
   1846         break;
   1847     default:
   1848         result = false;
   1849         break;
   1850     }
   1851 
   1852     if (!result) {
   1853         qemu_log_mask(LOG_GUEST_ERROR,
   1854                       "%s: invalid guest read at offset " TARGET_FMT_plx
   1855                       " size %u\n", __func__, offset, size);
   1856         trace_gicv3_its_badread(offset, size);
   1857         /*
   1858          * The spec requires that reserved registers are RAZ/WI;
   1859          * so use false returns from leaf functions as a way to
   1860          * trigger the guest-error logging but don't return it to
   1861          * the caller, or we'll cause a spurious guest data abort.
   1862          */
   1863         *data = 0;
   1864     } else {
   1865         trace_gicv3_its_read(offset, *data, size);
   1866     }
   1867     return MEMTX_OK;
   1868 }
   1869 
   1870 static MemTxResult gicv3_its_write(void *opaque, hwaddr offset, uint64_t data,
   1871                                    unsigned size, MemTxAttrs attrs)
   1872 {
   1873     GICv3ITSState *s = (GICv3ITSState *)opaque;
   1874     bool result;
   1875 
   1876     switch (size) {
   1877     case 4:
   1878         result = its_writel(s, offset, data, attrs);
   1879         break;
   1880     case 8:
   1881         result = its_writell(s, offset, data, attrs);
   1882         break;
   1883     default:
   1884         result = false;
   1885         break;
   1886     }
   1887 
   1888     if (!result) {
   1889         qemu_log_mask(LOG_GUEST_ERROR,
   1890                       "%s: invalid guest write at offset " TARGET_FMT_plx
   1891                       " size %u\n", __func__, offset, size);
   1892         trace_gicv3_its_badwrite(offset, data, size);
   1893         /*
   1894          * The spec requires that reserved registers are RAZ/WI;
   1895          * so use false returns from leaf functions as a way to
   1896          * trigger the guest-error logging but don't return it to
   1897          * the caller, or we'll cause a spurious guest data abort.
   1898          */
   1899     } else {
   1900         trace_gicv3_its_write(offset, data, size);
   1901     }
   1902     return MEMTX_OK;
   1903 }
   1904 
   1905 static const MemoryRegionOps gicv3_its_control_ops = {
   1906     .read_with_attrs = gicv3_its_read,
   1907     .write_with_attrs = gicv3_its_write,
   1908     .valid.min_access_size = 4,
   1909     .valid.max_access_size = 8,
   1910     .impl.min_access_size = 4,
   1911     .impl.max_access_size = 8,
   1912     .endianness = DEVICE_NATIVE_ENDIAN,
   1913 };
   1914 
   1915 static const MemoryRegionOps gicv3_its_translation_ops = {
   1916     .read_with_attrs = gicv3_its_translation_read,
   1917     .write_with_attrs = gicv3_its_translation_write,
   1918     .valid.min_access_size = 2,
   1919     .valid.max_access_size = 4,
   1920     .impl.min_access_size = 2,
   1921     .impl.max_access_size = 4,
   1922     .endianness = DEVICE_NATIVE_ENDIAN,
   1923 };
   1924 
   1925 static void gicv3_arm_its_realize(DeviceState *dev, Error **errp)
   1926 {
   1927     GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
   1928     int i;
   1929 
   1930     for (i = 0; i < s->gicv3->num_cpu; i++) {
   1931         if (!(s->gicv3->cpu[i].gicr_typer & GICR_TYPER_PLPIS)) {
   1932             error_setg(errp, "Physical LPI not supported by CPU %d", i);
   1933             return;
   1934         }
   1935     }
   1936 
   1937     gicv3_add_its(s->gicv3, dev);
   1938 
   1939     gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops);
   1940 
   1941     /* set the ITS default features supported */
   1942     s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL, 1);
   1943     s->typer = FIELD_DP64(s->typer, GITS_TYPER, ITT_ENTRY_SIZE,
   1944                           ITS_ITT_ENTRY_SIZE - 1);
   1945     s->typer = FIELD_DP64(s->typer, GITS_TYPER, IDBITS, ITS_IDBITS);
   1946     s->typer = FIELD_DP64(s->typer, GITS_TYPER, DEVBITS, ITS_DEVBITS);
   1947     s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIL, 1);
   1948     s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIDBITS, ITS_CIDBITS);
   1949     if (s->gicv3->revision >= 4) {
   1950         /* Our VMOVP handles cross-ITS synchronization itself */
   1951         s->typer = FIELD_DP64(s->typer, GITS_TYPER, VMOVP, 1);
   1952         s->typer = FIELD_DP64(s->typer, GITS_TYPER, VIRTUAL, 1);
   1953     }
   1954 }
   1955 
   1956 static void gicv3_its_reset(DeviceState *dev)
   1957 {
   1958     GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
   1959     GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s);
   1960 
   1961     c->parent_reset(dev);
   1962 
   1963     /* Quiescent bit reset to 1 */
   1964     s->ctlr = FIELD_DP32(s->ctlr, GITS_CTLR, QUIESCENT, 1);
   1965 
   1966     /*
   1967      * setting GITS_BASER0.Type = 0b001 (Device)
   1968      *         GITS_BASER1.Type = 0b100 (Collection Table)
   1969      *         GITS_BASER2.Type = 0b010 (vPE) for GICv4 and later
   1970      *         GITS_BASER<n>.Type,where n = 3 to 7 are 0b00 (Unimplemented)
   1971      *         GITS_BASER<0,1>.Page_Size = 64KB
   1972      * and default translation table entry size to 16 bytes
   1973      */
   1974     s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, TYPE,
   1975                              GITS_BASER_TYPE_DEVICE);
   1976     s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, PAGESIZE,
   1977                              GITS_BASER_PAGESIZE_64K);
   1978     s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, ENTRYSIZE,
   1979                              GITS_DTE_SIZE - 1);
   1980 
   1981     s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, TYPE,
   1982                              GITS_BASER_TYPE_COLLECTION);
   1983     s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, PAGESIZE,
   1984                              GITS_BASER_PAGESIZE_64K);
   1985     s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, ENTRYSIZE,
   1986                              GITS_CTE_SIZE - 1);
   1987 
   1988     if (its_feature_virtual(s)) {
   1989         s->baser[2] = FIELD_DP64(s->baser[2], GITS_BASER, TYPE,
   1990                                  GITS_BASER_TYPE_VPE);
   1991         s->baser[2] = FIELD_DP64(s->baser[2], GITS_BASER, PAGESIZE,
   1992                                  GITS_BASER_PAGESIZE_64K);
   1993         s->baser[2] = FIELD_DP64(s->baser[2], GITS_BASER, ENTRYSIZE,
   1994                                  GITS_VPE_SIZE - 1);
   1995     }
   1996 }
   1997 
   1998 static void gicv3_its_post_load(GICv3ITSState *s)
   1999 {
   2000     if (s->ctlr & R_GITS_CTLR_ENABLED_MASK) {
   2001         extract_table_params(s);
   2002         extract_cmdq_params(s);
   2003     }
   2004 }
   2005 
   2006 static Property gicv3_its_props[] = {
   2007     DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "arm-gicv3",
   2008                      GICv3State *),
   2009     DEFINE_PROP_END_OF_LIST(),
   2010 };
   2011 
   2012 static void gicv3_its_class_init(ObjectClass *klass, void *data)
   2013 {
   2014     DeviceClass *dc = DEVICE_CLASS(klass);
   2015     GICv3ITSClass *ic = ARM_GICV3_ITS_CLASS(klass);
   2016     GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
   2017 
   2018     dc->realize = gicv3_arm_its_realize;
   2019     device_class_set_props(dc, gicv3_its_props);
   2020     device_class_set_parent_reset(dc, gicv3_its_reset, &ic->parent_reset);
   2021     icc->post_load = gicv3_its_post_load;
   2022 }
   2023 
   2024 static const TypeInfo gicv3_its_info = {
   2025     .name = TYPE_ARM_GICV3_ITS,
   2026     .parent = TYPE_ARM_GICV3_ITS_COMMON,
   2027     .instance_size = sizeof(GICv3ITSState),
   2028     .class_init = gicv3_its_class_init,
   2029     .class_size = sizeof(GICv3ITSClass),
   2030 };
   2031 
   2032 static void gicv3_its_register_types(void)
   2033 {
   2034     type_register_static(&gicv3_its_info);
   2035 }
   2036 
   2037 type_init(gicv3_its_register_types)