In order to expose a virtual GICv5 ITS to the guest, KVM needs to emulate the ITS CONFIG_FRAME and its translation-control registers. Replace the placeholder ITS IODEV region with the GICv5 ITS register layout and handlers for the architected MMIO state. Provide read/write emulation for the ITS ID registers, IIDR, AIDR, CR0, CR1, DT_BASER, DT_CFGR, DIDR, EIDR, invalidation registers, READ_EVENT, GEN_EVENT, status registers, and the RAZ/WI MMIO registers that KVM does not implement. Reuse the shared CoreSight identification-register helper so the ITS reports the same component identification values as the IRS. At this stage the translation-triggering registers only record state. Walking the guest's DT/ITT, generating READ_EVENT results, and injecting GEN_EVENT LPIs are added by later commits. Signed-off-by: Sascha Bischoff --- arch/arm64/kvm/vgic/vgic-its-v5.c | 404 +++++++++++++++++++++++++++++- include/kvm/arm_vgic.h | 84 +++++++ 2 files changed, 486 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/vgic/vgic-its-v5.c b/arch/arm64/kvm/vgic/vgic-its-v5.c index f8184b4ae0ccd..fda75314229a5 100644 --- a/arch/arm64/kvm/vgic/vgic-its-v5.c +++ b/arch/arm64/kvm/vgic/vgic-its-v5.c @@ -6,19 +6,280 @@ #include #include +#include #include #include +#include + #include "vgic.h" #include "vgic-mmio.h" +#define VITS_V5_DEVICE_ID_BITS 16 +#define VITS_V5_EVENT_ID_BITS 16 + +static unsigned long vgic_v5_mmio_read_its_misc(struct kvm *kvm, void *dev, + gpa_t addr, unsigned int len) +{ + struct vgic_v5_its *its = dev; + u64 value = 0; + size_t offset = addr & (SZ_64K - 1); + + switch (offset) { + case GICV5_ITS_IDR0: + value = FIELD_PREP(GICV5_ITS_IDR0_ITSID, its->idr0.its_id); + value |= FIELD_PREP(GICV5_ITS_IDR0_SWE, its->idr0.swe); + value |= FIELD_PREP(GICV5_ITS_IDR0_MPAM, its->idr0.mpam); + value |= FIELD_PREP(GICV5_ITS_IDR0_MEC, its->idr0.mec); + value |= FIELD_PREP(GICV5_ITS_IDR0_PA_RANGE, + its->idr0.pa_range); + value |= FIELD_PREP(GICV5_ITS_IDR0_DOM, its->idr0.domain); + break; + case GICV5_ITS_IDR1: + value = FIELD_PREP(GICV5_ITS_IDR1_L2SZ, its->idr1.l2sz); + value |= FIELD_PREP(GICV5_ITS_IDR1_ITT_LEVELS, + its->idr1.itt_levels); + value |= FIELD_PREP(GICV5_ITS_IDR1_DT_LEVELS, + its->idr1.dt_levels); + value |= FIELD_PREP(GICV5_ITS_IDR1_DEVICEID_BITS, + its->idr1.device_id_bits); + break; + case GICV5_ITS_IDR2: + value = FIELD_PREP(GICV5_ITS_IDR2_XDMN_EVENTS, + its->idr2.xdmn_events); + value |= FIELD_PREP(GICV5_ITS_IDR2_EVENTID_BITS, + its->idr2.event_id_bits); + break; + case GICV5_ITS_IIDR: + value = FIELD_PREP(GICV5_ITS_IIDR_PRODUCT_ID, PRODUCT_ID_KVM); + value |= FIELD_PREP(GICV5_ITS_IIDR_VARIANT, 0); + value |= FIELD_PREP(GICV5_ITS_IIDR_REVISION, 0); + value |= FIELD_PREP(GICV5_ITS_IIDR_IMPLEMENTER, + IMPLEMENTER_ARM); + break; + case GICV5_ITS_AIDR: + value = FIELD_PREP(GICV5_ITS_AIDR_COMPONENT, + GICV5_AIDR_COMPONENT_ITS); + value |= FIELD_PREP(GICV5_ITS_AIDR_ARCHMAJORREV, + GICV5_AIDR_ARCH_MAJ_REV_V5); + value |= FIELD_PREP(GICV5_ITS_AIDR_ARCHMINORREV, + GICV5_AIDR_ARCH_MIN_REV_V0); + break; + case GICV5_ITS_CR0: + value = GICV5_ITS_CR0_IDLE; + value |= FIELD_PREP(GICV5_ITS_CR0_ITSEN, its->enabled); + break; + case GICV5_ITS_CR1: + value = FIELD_PREP(GICV5_ITS_CR1_ITT_RA, its->cr1.itt_ra); + value |= FIELD_PREP(GICV5_ITS_CR1_DT_RA, its->cr1.dt_ra); + value |= FIELD_PREP(GICV5_ITS_CR1_IC, its->cr1.ic); + value |= FIELD_PREP(GICV5_ITS_CR1_OC, its->cr1.oc); + value |= FIELD_PREP(GICV5_ITS_CR1_SH, its->cr1.sh); + break; + default: + return 0; + } + + return value; +} + +static void vgic_v5_mmio_write_its_misc(struct kvm *kvm, void *dev, gpa_t addr, + unsigned int len, unsigned long val) +{ + struct vgic_v5_its *its = dev; + size_t offset = addr & (SZ_64K - 1); + + switch (offset) { + case GICV5_ITS_CR0: + its->enabled = FIELD_GET(GICV5_ITS_CR0_ITSEN, val); + return; + case GICV5_ITS_CR1: + its->cr1.sh = FIELD_GET(GICV5_ITS_CR1_SH, val); + its->cr1.oc = FIELD_GET(GICV5_ITS_CR1_OC, val); + its->cr1.ic = FIELD_GET(GICV5_ITS_CR1_IC, val); + its->cr1.dt_ra = FIELD_GET(GICV5_ITS_CR1_DT_RA, val); + its->cr1.itt_ra = FIELD_GET(GICV5_ITS_CR1_ITT_RA, val); + return; + default: + return; + } +} + +static void vgic_v5_write_its_dt_reg(struct vgic_v5_its *its, size_t offset, + unsigned long val) +{ + switch (offset) { + case GICV5_ITS_DT_CFGR: + its->dt_cfgr.device_id_bits = + FIELD_GET(GICV5_ITS_DT_CFGR_DEVICEID_BITS, val); + its->dt_cfgr.l2sz = + FIELD_GET(GICV5_ITS_DT_CFGR_L2SZ, val); + its->dt_cfgr.structure = + FIELD_GET(GICV5_ITS_DT_CFGR_STRUCTURE, val); + return; + case GICV5_ITS_DT_BASER: + its->dt_baser.addr = + FIELD_GET(GICV5_ITS_DT_BASER_ADDR_MASK, val) + << GICV5_ITS_DT_BASER_ADDR_SHIFT; + return; + } +} + +static u64 vgic_v5_read_its_dt_baser(struct vgic_v5_its *its) +{ + return FIELD_PREP(GICV5_ITS_DT_BASER_ADDR_MASK, + its->dt_baser.addr >> GICV5_ITS_DT_BASER_ADDR_SHIFT); +} + +static unsigned long vgic_v5_mmio_read_its_dt_itt(struct kvm *kvm, void *dev, + gpa_t addr, unsigned int len) +{ + struct vgic_v5_its *its = dev; + u64 value = 0; + size_t offset = addr & (SZ_64K - 1); + + switch (offset) { + case GICV5_ITS_DT_CFGR: + value = FIELD_PREP(GICV5_ITS_DT_CFGR_STRUCTURE, + its->dt_cfgr.structure); + value |= FIELD_PREP(GICV5_ITS_DT_CFGR_L2SZ, + its->dt_cfgr.l2sz); + value |= FIELD_PREP(GICV5_ITS_DT_CFGR_DEVICEID_BITS, + its->dt_cfgr.device_id_bits); + break; + case GICV5_ITS_DT_BASER: + case GICV5_ITS_DT_BASER + 4: + value = vgic_v5_read_its_dt_baser(its); + return extract_bytes(value, offset & 4, len); + case GICV5_ITS_DIDR: + case GICV5_ITS_DIDR + 4: + value = FIELD_PREP(GICV5_ITS_DIDR_DEVICEID, + its->didr.device_id); + return extract_bytes(value, offset & 4, len); + case GICV5_ITS_EIDR: + value = FIELD_PREP(GICV5_ITS_EIDR_EVENTID, + its->eidr.event_id); + break; + case GICV5_ITS_STATUSR: + value = GICV5_ITS_STATUSR_IDLE; + break; + case GICV5_ITS_SYNC_STATUSR: + value = GICV5_ITS_SYNC_STATUSR_IDLE; + break; + case GICV5_ITS_READ_EVENT_DATAR: + case GICV5_ITS_READ_EVENT_DATAR + 4: + value = FIELD_PREP(GICV5_ITS_READ_EVENT_DATAR_VIRT, + its->read_event_datar.virt); + value |= FIELD_PREP(GICV5_ITS_READ_EVENT_DATAR_VM_ID, + its->read_event_datar.vm_id); + value |= FIELD_PREP(GICV5_ITS_READ_EVENT_DATAR_VALID, + its->read_event_datar.valid); + value |= FIELD_PREP(GICV5_ITS_READ_EVENT_DATAR_LPI_ID, + its->read_event_datar.lpi_id); + return extract_bytes(value, offset & 4, len); + case GICV5_ITS_GEN_EVENT_EIDR: + value = FIELD_PREP(GICV5_ITS_GEN_EVENT_EIDR_EVENTID, + its->gen_event_eidr.event_id); + break; + case GICV5_ITS_GEN_EVENT_DIDR: + case GICV5_ITS_GEN_EVENT_DIDR + 4: + value = FIELD_PREP(GICV5_ITS_GEN_EVENT_DIDR_DEVICEID, + its->gen_event_didr.device_id); + return extract_bytes(value, offset & 4, len); + case GICV5_ITS_GEN_EVENT_STATUSR: + value = GICV5_ITS_GEN_EVENT_STATUSR_IDLE; + break; + default: + return 0; + } + + return value; +} + +static void vgic_v5_mmio_write_its_dt_itt(struct kvm *kvm, void *dev, + gpa_t addr, unsigned int len, + unsigned long val) +{ + struct vgic_v5_its *its = dev; + size_t offset = addr & (SZ_64K - 1); + + guard(mutex)(&its->its_lock); + + switch (offset) { + case GICV5_ITS_DT_CFGR: + if (!its->enabled) + vgic_v5_write_its_dt_reg(its, offset, val); + return; + case GICV5_ITS_DT_BASER: + case GICV5_ITS_DT_BASER + 4: + if (!its->enabled) { + u64 baser = vgic_v5_read_its_dt_baser(its); + + baser = update_64bit_reg(baser, offset & 4, len, val); + vgic_v5_write_its_dt_reg(its, GICV5_ITS_DT_BASER, + baser); + } + return; + case GICV5_ITS_INV_DEVICER: + its->inv_devicer.l1 = + FIELD_GET(GICV5_ITS_INV_DEVICER_L1, val); + its->inv_devicer.event_id_bits = + FIELD_GET(GICV5_ITS_INV_DEVICER_EVENTID_BITS, val); + its->inv_devicer.i = + FIELD_GET(GICV5_ITS_INV_DEVICER_I, val); + return; + case GICV5_ITS_DIDR: + case GICV5_ITS_DIDR + 4: + if (offset & 4) + return; + its->didr.device_id = FIELD_GET(GICV5_ITS_DIDR_DEVICEID, val); + return; + case GICV5_ITS_EIDR: + its->eidr.event_id = FIELD_GET(GICV5_ITS_EIDR_EVENTID, val); + return; + case GICV5_ITS_INV_EVENTR: + its->inv_eventr.l1 = + FIELD_GET(GICV5_ITS_INV_EVENTR_L1, val); + its->inv_eventr.itt_l2sz = + FIELD_GET(GICV5_ITS_INV_EVENTR_ITT_L2SZ, val); + its->inv_eventr.i = FIELD_GET(GICV5_ITS_INV_EVENTR_I, val); + return; + case GICV5_ITS_SYNCR: + case GICV5_ITS_READ_EVENTR: + return; + case GICV5_ITS_GEN_EVENT_EIDR: + its->gen_event_eidr.event_id = + FIELD_GET(GICV5_ITS_GEN_EVENT_EIDR_EVENTID, val); + return; + case GICV5_ITS_GEN_EVENT_DIDR: + case GICV5_ITS_GEN_EVENT_DIDR + 4: + if (offset & 4) + return; + its->gen_event_didr.device_id = + FIELD_GET(GICV5_ITS_GEN_EVENT_DIDR_DEVICEID, val); + return; + case GICV5_ITS_GEN_EVENTR: + return; + default: + return; + } +} + static unsigned long vgic_v5_mmio_read_its_raz(struct kvm *kvm, void *dev, gpa_t addr, unsigned int len) { return 0; } +static unsigned long vgic_v5_its_coresight_read(struct kvm *kvm, void *dev, + gpa_t addr, unsigned int len) +{ + u32 offset = addr & (SZ_64K - 1); + + return vgic_v5_handle_guest_coresight_idreg_read(offset); +} + static void vgic_v5_mmio_write_its_wi(struct kvm *kvm, void *dev, gpa_t addr, unsigned int len, unsigned long val) { @@ -31,11 +292,148 @@ static void vgic_v5_mmio_write_its_wi(struct kvm *kvm, void *dev, gpa_t addr, } static const struct vgic_register_region vgic_v5_its_registers[] = { - REGISTER_ITS_V5_DESC(0, vgic_v5_mmio_read_its_raz, - vgic_v5_mmio_write_its_wi, KVM_VGIC_V5_ITS_SIZE, + REGISTER_ITS_V5_DESC(GICV5_ITS_IDR0, vgic_v5_mmio_read_its_misc, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_IDR1, vgic_v5_mmio_read_its_misc, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_IDR2, vgic_v5_mmio_read_its_misc, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_IIDR, vgic_v5_mmio_read_its_misc, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_AIDR, vgic_v5_mmio_read_its_misc, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_CR0, vgic_v5_mmio_read_its_misc, + vgic_v5_mmio_write_its_misc, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_CR1, vgic_v5_mmio_read_its_misc, + vgic_v5_mmio_write_its_misc, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_DT_BASER, + vgic_v5_mmio_read_its_dt_itt, + vgic_v5_mmio_write_its_dt_itt, 8, + VGIC_ACCESS_64bit | VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_DT_CFGR, + vgic_v5_mmio_read_its_dt_itt, + vgic_v5_mmio_write_its_dt_itt, 4, + VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_DIDR, vgic_v5_mmio_read_its_dt_itt, + vgic_v5_mmio_write_its_dt_itt, 8, + VGIC_ACCESS_64bit | VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_EIDR, vgic_v5_mmio_read_its_dt_itt, + vgic_v5_mmio_write_its_dt_itt, 4, + VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_INV_EVENTR, vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_dt_itt, 4, + VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_INV_DEVICER, vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_dt_itt, 4, + VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_READ_EVENTR, vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_dt_itt, 4, + VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_READ_EVENT_DATAR, + vgic_v5_mmio_read_its_dt_itt, + vgic_v5_mmio_write_its_wi, 8, + VGIC_ACCESS_64bit | VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_STATUSR, vgic_v5_mmio_read_its_dt_itt, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_SYNCR, vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_dt_itt, 4, + VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_SYNC_STATUSR, + vgic_v5_mmio_read_its_dt_itt, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_GEN_EVENT_DIDR, + vgic_v5_mmio_read_its_dt_itt, + vgic_v5_mmio_write_its_dt_itt, 8, + VGIC_ACCESS_64bit | VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_GEN_EVENT_EIDR, + vgic_v5_mmio_read_its_dt_itt, + vgic_v5_mmio_write_its_dt_itt, 4, + VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_GEN_EVENTR, vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_dt_itt, 4, + VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_GEN_EVENT_STATUSR, + vgic_v5_mmio_read_its_dt_itt, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_MEC_IDR, vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_MEC_MECID_R, vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_MPAM_IDR, vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_MPAM_PARTID_R, + vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_wi, 4, VGIC_ACCESS_32bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_SWERR_STATUSR, vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_wi, 8, VGIC_ACCESS_64bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_SWERR_SYNDROMER0, + vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_wi, 8, VGIC_ACCESS_64bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_SWERR_SYNDROMER1, + vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_wi, 8, + VGIC_ACCESS_64bit), + REGISTER_ITS_V5_DESC(GICV5_ITS_MPAM_PMGR, vgic_v5_mmio_read_its_raz, + vgic_v5_mmio_write_its_wi, 8, VGIC_ACCESS_64bit), + REGISTER_ITS_V5_DESC(GICV5_CORESIGHT_DEVARCH, + vgic_v5_its_coresight_read, + vgic_v5_mmio_write_its_wi, + GICV5_CORESIGHT_IDREGS_SIZE, VGIC_ACCESS_32bit), }; +static void vgic_v5_its_reset(struct vgic_v5_its *its) +{ + u64 mmfr0; + + its->enabled = false; + + mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); + its->idr0.pa_range = cpuid_feature_extract_unsigned_field( + mmfr0, ID_AA64MMFR0_EL1_PARANGE_SHIFT); + its->idr0.domain = GICV5_ITS_IDR0_DOMAIN_NON_SECURE; + its->idr0.mec = 0; + its->idr0.mpam = 0; + its->idr0.swe = 0; + its->idr0.its_id = 0; + + its->idr1.dt_levels = 1; + its->idr1.itt_levels = 1; + its->idr1.l2sz = 0; + its->idr2.xdmn_events = 0; + + its->cr1.sh = 0; + its->cr1.oc = 0; + its->cr1.ic = 0; + its->cr1.dt_ra = false; + its->cr1.itt_ra = false; + + its->idr1.device_id_bits = VITS_V5_DEVICE_ID_BITS; + its->idr2.event_id_bits = VITS_V5_EVENT_ID_BITS; + + its->dt_cfgr.device_id_bits = 0; + its->dt_cfgr.l2sz = 0; + its->dt_cfgr.structure = false; + its->dt_baser.addr = 0; + + its->inv_devicer.l1 = false; + its->inv_devicer.event_id_bits = 0; + its->inv_devicer.i = false; + its->didr.device_id = 0; + its->eidr.event_id = 0; + its->inv_eventr.l1 = false; + its->inv_eventr.itt_l2sz = 0; + its->inv_eventr.i = false; + + its->read_event_datar.lpi_id = 0; + its->read_event_datar.valid = false; + its->read_event_datar.vm_id = 0; + its->read_event_datar.virt = false; + its->gen_event_eidr.event_id = 0; + its->gen_event_didr.device_id = 0; + +} + static int vgic_v5_its_create(struct kvm_device *dev, u32 type) { struct vgic_v5_its *its; @@ -60,6 +458,8 @@ static int vgic_v5_its_create(struct kvm_device *dev, u32 type) its->vgic_v5_its_base = VGIC_ADDR_UNDEF; its->dev = dev; + vgic_v5_its_reset(its); + dev->kvm->arch.vgic.msis_require_devid = true; dev->kvm->arch.vgic.has_its = true; dev->kvm->arch.vgic.its_model = KVM_DEV_TYPE_ARM_VGIC_V5; diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index f3bfeee6104c2..c9eaa7897b57e 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -506,6 +506,90 @@ struct vgic_v5_its { struct vgic_io_device iodev; struct kvm_device *dev; + bool enabled; + + /* ITS state - used for registers etc */ + struct its_idr0 { + u8 domain; + u8 pa_range; + bool mec; + bool mpam; + bool swe; + u16 its_id; + } idr0; + + struct its_idr1 { + u8 device_id_bits; + u8 dt_levels; + u8 itt_levels; + u8 l2sz; + } idr1; + + struct its_idr2 { + u8 event_id_bits; + u8 xdmn_events; + } idr2; + + struct its_iidr { + u16 implementer; + u8 revision; + u8 variant; + u16 product_id; + } iidr; + + struct its_cr1 { + u8 sh; + u8 oc; + u8 ic; + bool dt_ra; + bool itt_ra; + } cr1; + + struct its_dt_cfgr { + u8 device_id_bits; + u8 l2sz; + bool structure; + } dt_cfgr; + + struct its_dt_baser { + u64 addr; + } dt_baser; + + struct its_inv_devicer { + bool l1; + u8 event_id_bits; + bool i; + } inv_devicer; + + struct its_didr { + u32 device_id; + } didr; + + struct its_eidr { + u16 event_id; + } eidr; + + struct its_inv_eventr { + bool l1; + u8 itt_l2sz; + bool i; + } inv_eventr; + + struct its_read_event_datar { + u32 lpi_id; + bool valid; + u16 vm_id; + bool virt; + } read_event_datar; + + struct its_gen_event_eidr { + u16 event_id; + } gen_event_eidr; + + struct its_gen_event_didr { + u32 device_id; + } gen_event_didr; + /* Protects the device in general */ struct mutex its_lock; }; -- 2.34.1