Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
This address needs to be 64K aligned.
+ KVM_VGIC_V3_ADDR_TYPE_ITS (rw, 64-bit)
+ Base address in the guest physical address space of the GICv3 ITS
+ control register frame. The ITS allows MSI(-X) interrupts to be
+ injected into guests. This extension is optional, if the kernel
+ does not support the ITS, the call returns -ENODEV.
+ This memory is solely for the guest to access the ITS control
+ registers and does not cover the ITS translation register.
+ Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
+ This address needs to be 64K aligned and the region covers 64 KByte.
KVM_DEV_ARM_VGIC_GRP_DIST_REGS
Attributes:
/* Supported VGICv3 address types */
#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
+#define KVM_VGIC_V3_ADDR_TYPE_ITS 4
#define KVM_VGIC_V3_DIST_SIZE SZ_64K
#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
+#define KVM_VGIC_V3_ITS_SIZE SZ_64K
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
phys_addr_t vgic_redist_base;
};
+ /* The base address of the ITS control register frame */
+ phys_addr_t vgic_its_base;
+
/* Distributor enabled */
u32 enabled;
dist->vgic_dist_base = VGIC_ADDR_UNDEF;
dist->vgic_redist_base = VGIC_ADDR_UNDEF;
+ dist->vgic_its_base = VGIC_ADDR_UNDEF;
kvm->arch.max_vcpus = KVM_MAX_VCPUS;
}
return -ENXIO;
case KVM_VGIC_V3_ADDR_TYPE_DIST:
case KVM_VGIC_V3_ADDR_TYPE_REDIST:
+ case KVM_VGIC_V3_ADDR_TYPE_ITS:
return 0;
}
break;
return ret;
}
+bool vgic_has_its(struct kvm *kvm)
+{
+ struct vgic_dist *dist = &kvm->arch.vgic;
+
+ if (dist->vgic_model != KVM_DEV_TYPE_ARM_VGIC_V3)
+ return false;
+
+ return !IS_VGIC_ADDR_UNDEF(dist->vgic_its_base);
+}
+
static int vgic_nr_shared_irqs(struct vgic_dist *dist)
{
return dist->nr_irqs - VGIC_NR_PRIVATE_IRQS;
block_size = KVM_VGIC_V3_REDIST_SIZE;
alignment = SZ_64K;
break;
+ case KVM_VGIC_V3_ADDR_TYPE_ITS:
+ type_needed = KVM_DEV_TYPE_ARM_VGIC_V3;
+ addr_ptr = &vgic->vgic_its_base;
+ block_size = KVM_VGIC_V3_ITS_SIZE;
+ alignment = SZ_64K;
+ break;
#endif
default:
r = -ENODEV;
int vgic_init(struct kvm *kvm);
void vgic_v2_init_emulation(struct kvm *kvm);
void vgic_v3_init_emulation(struct kvm *kvm);
+bool vgic_has_its(struct kvm *kvm);
#endif