#include <linux/spinlock.h>
#include <linux/types.h>
#include <kvm/iodev.h>
+#include <linux/list.h>
#define VGIC_V3_MAX_CPUS 255
#define VGIC_V2_MAX_CPUS 8
struct vgic_irq {
spinlock_t irq_lock; /* Protects the content of the struct */
+ struct list_head lpi_list; /* Used to link all LPIs together */
struct list_head ap_list;
struct kvm_vcpu *vcpu; /* SGIs and PPIs: The VCPU
bool active; /* not used for LPIs */
bool enabled;
bool hw; /* Tied to HW IRQ */
+ struct kref refcount; /* Used for LPIs */
u32 hwintid; /* HW INTID number */
union {
u8 targets; /* GICv2 target VCPUs mask */
};
struct vgic_register_region;
+struct vgic_its;
+
+enum iodev_type {
+ IODEV_CPUIF,
+ IODEV_DIST,
+ IODEV_REDIST,
+ IODEV_ITS
+};
struct vgic_io_device {
gpa_t base_addr;
- struct kvm_vcpu *redist_vcpu;
+ union {
+ struct kvm_vcpu *redist_vcpu;
+ struct vgic_its *its;
+ };
const struct vgic_register_region *regions;
+ enum iodev_type iodev_type;
int nr_regions;
struct kvm_io_device dev;
};
+struct vgic_its {
+ /* The base address of the ITS control register frame */
+ gpa_t vgic_its_base;
+
+ bool enabled;
+ bool initialized;
+ struct vgic_io_device iodev;
+ struct kvm_device *dev;
+
+ /* These registers correspond to GITS_BASER{0,1} */
+ u64 baser_device_table;
+ u64 baser_coll_table;
+
+ /* Protects the command queue */
+ struct mutex cmd_lock;
+ u64 cbaser;
+ u32 creadr;
+ u32 cwriter;
+
+ /* Protects the device and collection lists */
+ struct mutex its_lock;
+ struct list_head device_list;
+ struct list_head collection_list;
+};
+
struct vgic_dist {
bool in_kernel;
bool ready;
/* vGIC model the kernel emulates for the guest (GICv2 or GICv3) */
u32 vgic_model;
+ /* Do injected MSIs require an additional device ID? */
+ bool msis_require_devid;
+
int nr_spis;
/* TODO: Consider moving to global state */
struct vgic_irq *spis;
struct vgic_io_device dist_iodev;
+
+ bool has_its;
+
+ /*
+ * Contains the attributes and gpa of the LPI configuration table.
+ * Since we report GICR_TYPER.CommonLPIAff as 0b00, we can share
+ * one address across all redistributors.
+ * GICv3 spec: 6.1.2 "LPI Configuration tables"
+ */
+ u64 propbaser;
+
+ /* Protects the lpi_list and the count value below. */
+ spinlock_t lpi_list_lock;
+ struct list_head lpi_list_head;
+ int lpi_list_count;
};
struct vgic_v2_cpu_if {
*/
struct vgic_io_device rd_iodev;
struct vgic_io_device sgi_iodev;
+
+ /* Contains the attributes and gpa of the LPI pending tables. */
+ u64 pendbaser;
+
+ bool lpis_enabled;
};
int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write);
return kvm_vgic_global_state.max_gic_vcpus;
}
+int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi);
+
#endif /* __KVM_ARM_VGIC_H */