|
@@ -227,6 +227,7 @@ static struct its_ite *find_ite(struct vgic_its *its, u32 device_id,
|
|
#define GIC_LPI_OFFSET 8192
|
|
#define GIC_LPI_OFFSET 8192
|
|
|
|
|
|
#define VITS_TYPER_IDBITS 16
|
|
#define VITS_TYPER_IDBITS 16
|
|
|
|
+#define VITS_TYPER_DEVBITS 16
|
|
|
|
|
|
/*
|
|
/*
|
|
* Finds and returns a collection in the ITS collection table.
|
|
* Finds and returns a collection in the ITS collection table.
|
|
@@ -427,7 +428,7 @@ static unsigned long vgic_mmio_read_its_typer(struct kvm *kvm,
|
|
* To avoid memory waste in the guest, we keep the number of IDBits and
|
|
* To avoid memory waste in the guest, we keep the number of IDBits and
|
|
* DevBits low - as least for the time being.
|
|
* 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(VITS_TYPER_IDBITS, 5) << GITS_TYPER_IDBITS_SHIFT;
|
|
reg |= GIC_ENCODE_SZ(abi->ite_esz, 4) << GITS_TYPER_ITT_ENTRY_SIZE_SHIFT;
|
|
reg |= GIC_ENCODE_SZ(abi->ite_esz, 4) << GITS_TYPER_ITT_ENTRY_SIZE_SHIFT;
|
|
|
|
|
|
@@ -672,16 +673,30 @@ static int vgic_its_cmd_handle_movi(struct kvm *kvm, struct vgic_its *its,
|
|
* Check whether an ID can be stored into the corresponding guest table.
|
|
* 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
|
|
* For a direct table this is pretty easy, but gets a bit nasty for
|
|
* indirect tables. We check whether the resulting guest physical address
|
|
* 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.
|
|
* 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;
|
|
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;
|
|
int index;
|
|
- u64 indirect_ptr;
|
|
|
|
gfn_t gfn;
|
|
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)) {
|
|
if (!(baser & GITS_BASER_INDIRECT)) {
|
|
phys_addr_t addr;
|
|
phys_addr_t addr;
|