#define GIC_LPI_OFFSET 8192
 
 #define VITS_TYPER_IDBITS 16
+#define VITS_TYPER_DEVBITS 16
 
 /*
  * Finds and returns a collection in the ITS collection table.
         * To avoid memory waste in the guest, we keep the number of IDBits and
         * DevBits low - as least for the time being.
         */
-       reg |= 0x0f << GITS_TYPER_DEVBITS_SHIFT;
+       reg |= GIC_ENCODE_SZ(VITS_TYPER_DEVBITS, 5) << GITS_TYPER_DEVBITS_SHIFT;
        reg |= GIC_ENCODE_SZ(VITS_TYPER_IDBITS, 5) << GITS_TYPER_IDBITS_SHIFT;
        reg |= GIC_ENCODE_SZ(abi->ite_esz, 4) << GITS_TYPER_ITT_ENTRY_SIZE_SHIFT;
 
  * Check whether an ID can be stored into the corresponding guest table.
  * For a direct table this is pretty easy, but gets a bit nasty for
  * indirect tables. We check whether the resulting guest physical address
- * is actually valid (covered by a memslot and guest accessbible).
+ * is actually valid (covered by a memslot and guest accessible).
  * For this we have to read the respective first level entry.
  */
-static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
+static bool vgic_its_check_id(struct vgic_its *its, u64 baser, u32 id)
 {
        int l1_tbl_size = GITS_BASER_NR_PAGES(baser) * SZ_64K;
+       u64 indirect_ptr, type = GITS_BASER_TYPE(baser);
+       int esz = GITS_BASER_ENTRY_SIZE(baser);
        int index;
-       u64 indirect_ptr;
        gfn_t gfn;
-       int esz = GITS_BASER_ENTRY_SIZE(baser);
+
+       switch (type) {
+       case GITS_BASER_TYPE_DEVICE:
+               if (id >= BIT_ULL(VITS_TYPER_DEVBITS))
+                       return false;
+               break;
+       case GITS_BASER_TYPE_COLLECTION:
+               /* as GITS_TYPER.CIL == 0, ITS supports 16-bit collection ID */
+               if (id >= BIT_ULL(16))
+                       return false;
+               break;
+       default:
+               return false;
+       }
 
        if (!(baser & GITS_BASER_INDIRECT)) {
                phys_addr_t addr;