vITS support
v2 cover vITS support
This series introduces support for in-kernel GICv3 ITS emulation. It is based on kernel API which is not released yet, therefore i post it as an RFC.
Kernel patches which implement this functionality are:
- [PATCH v2 00/15] KVM: arm64: GICv3 ITS emulation
http://www.spinics.net/lists/arm-kernel/msg430724.html
- [PATCH v3 0/7] KVM: arm/arm64: gsi routing support
http://www.spinics.net/lists/kvm/msg119567.html
v1 => v2:
- Added registers and reset method
- Added unmigratable flag
- Rebased on top of current master, use kvm_arch_fixup_msi_route() now
Pavel Fedin (5):
hw/intc: Implement ITS base class
kernel: Add vGICv3 ITS definitions
kvm_arm: Pass requester ID to MSI routing functions
kvm_arm: Implement support for ITS emulation by KVM arm/virt: Add ITS to the virt board
hw/arm/virt.c | 47 ++++++++-- hw/intc/Makefile.objs | 2 + hw/intc/arm_gicv3_its_common.c | 154 +++++++++++++++++++++++++++++++++ hw/intc/arm_gicv3_its_kvm.c | 88 +++++++++++++++++++ include/hw/intc/arm_gicv3_its_common.h | 72 +++++++++++++++ linux-headers/asm-arm64/kvm.h | 1 + linux-headers/linux/kvm.h | 9 +- target-arm/kvm.c | 6 ++ target-arm/kvm_arm.h | 13 +++ target-arm/machine.c | 16 ++++ 10 files changed, 400 insertions(+), 8 deletions(-) create mode 100644 hw/intc/arm_gicv3_its_common.c create mode 100644 hw/intc/arm_gicv3_its_kvm.c create mode 100644 include/hw/intc/arm_gicv3_its_common.h
Signature · 1 line
2.4.4
RFC PATCH v2 1/5 hw/intc: Implement ITS base class
This is the basic skeleton for both KVM and software-emulated ITS.
--- hw/intc/Makefile.objs | 1 + hw/intc/arm_gicv3_its_common.c | 154 +++++++++++++++++++++++++++++++++ include/hw/intc/arm_gicv3_its_common.h | 72 +++++++++++++++ target-arm/kvm_arm.h | 10 +++ target-arm/machine.c | 16 ++++ 5 files changed, 253 insertions(+) create mode 100644 hw/intc/arm_gicv3_its_common.c create mode 100644 include/hw/intc/arm_gicv3_its_common.h
hw/intc/Makefile.objs +1 -0
@@ -13,6 +13,7 @@ common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o common-obj-$(CONFIG_ARM_GIC) += arm_gic.o common-obj-$(CONFIG_ARM_GIC) += arm_gicv2m.o common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_common.o +common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_its_common.o common-obj-$(CONFIG_OPENPIC) += openpic.o obj-$(CONFIG_APIC) += apic.o apic_common.o
hw/intc/arm_gicv3_its_common.c new file +154 -0
154 lines not on this page · raw message
include/hw/intc/arm_gicv3_its_common.h new file +72 -0
72 lines not on this page · raw message
target-arm/kvm_arm.h +10 -0
@@ -215,4 +215,14 @@ static inline const char *gic_class_name(void)*/ const char *gicv3_class_name (void ); +/** +* its_class_name +* +* Return name of ITS class to use depending on whether KVM acceleration is +* in use, or NULL if the chosen implementation is not available. +* +* Returns: class name to use or NULL +*/ +const char *its_class_name (void ); +#endif
target-arm/machine.c +16 -0
@@ -346,3 +346,19 @@ const char *gicv3_class_name(void)exit (1 ); } + +const char *its_class_name (void ) +{ +if (kvm_irqchip_in_kernel ()) { +#ifdef TARGET_AARCH64 +/* KVM implementation requires this capability */ +if (kvm_direct_msi_enabled ()) { +return "arm-its-kvm" ; + } +#endif +return NULL ; + }else { +/* Software emulation is not implemented yet */ +return NULL ; + } +}
Signature · 1 line
2.4.4
RFC PATCH v2 2/5 kernel: Add vGICv3 ITS definitions
In reply to Pavel FedinThis temporary patch adds kernel API definitions. Use proper header update procedure after these features are released.
--- linux-headers/asm-arm64/kvm.h | 1 + linux-headers/linux/kvm.h | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-)
linux-headers/asm-arm64/kvm.h +1 -0
@@ -87,6 +87,7 @@ struct kvm_regs {/* 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)
linux-headers/linux/kvm.h +7 -2
@@ -843,7 +843,10 @@ struct kvm_irq_routing_msi {__u32 address_lo;__u32 address_hi;__u32 data; -__u32 pad; +union { +__u32 pad; +__u32 devid; + }; };struct kvm_irq_routing_s390_adapter {
@@ -982,12 +985,14 @@ struct kvm_one_reg {__u64 addr; }; +#define KVM_MSI_VALID_DEVID (1U << 0)struct kvm_msi {__u32 address_lo;__u32 address_hi;__u32 data;__u32 flags; -__u8 pad[16 ]; +__u32 devid; +__u8 pad[12 ]; };struct kvm_arm_device_addr {
Signature · 1 line
2.4.4
RFC PATCH v2 3/5 kvm_arm: Pass requester ID to MSI routing functions
In reply to Pavel FedinIntroduce global kvm_arm_msi_use_devid flag and pass device IDs in kvm_arch_fixup_msi_route(). Device IDs are required by the ITS.
--- target-arm/kvm.c | 6 ++++++ target-arm/kvm_arm.h | 3 +++ 2 files changed, 9 insertions(+)
target-arm/kvm.c +6 -0
@@ -23,6 +23,7 @@#include "cpu.h" #include "internals.h" #include "hw/arm/arm.h" +#include "hw/pci/pci.h" #include "exec/memattrs.h" const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
@@ -30,6 +31,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { };static bool cap_has_mp_state; +bool kvm_arm_msi_use_devid =0 ;int kvm_arm_vcpu_init (CPUState *cs) {
@@ -607,6 +609,10 @@ int kvm_arm_vgic_probe(void)int kvm_arch_fixup_msi_route (struct kvm_irq_routing_entry *route,uint64_t address,uint32_t data,PCIDevice *dev) { +if (kvm_arm_msi_use_devid) { + route->flags =KVM_MSI_VALID_DEVID ; + route->u.msi.devid =pci_requester_id (dev); + }return 0 ; }
target-arm/kvm_arm.h +3 -0
@@ -120,6 +120,9 @@ bool write_kvmstate_to_list(ARMCPU *cpu);void kvm_arm_reset_vcpu (ARMCPU *cpu);#ifdef CONFIG_KVM + +extern bool kvm_arm_msi_use_devid; +/** * kvm_arm_create_scratch_host_vcpu: * @cpus_to_try: array of QEMU_KVM_ARM_TARGET_* values (terminated with
Signature · 1 line
2.4.4
RFC PATCH v2 4/5 kvm_arm: Implement support for ITS emulation by KVM
In reply to Pavel FedinThis patch relies on new kernel API which is not released yet.
--- hw/intc/Makefile.objs | 1 + hw/intc/arm_gicv3_its_common.c | 2 +- hw/intc/arm_gicv3_its_kvm.c | 88 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 hw/intc/arm_gicv3_its_kvm.c
hw/intc/Makefile.objs +1 -0
@@ -19,6 +19,7 @@ common-obj-$(CONFIG_OPENPIC) += openpic.o obj-$(CONFIG_APIC) += apic.o apic_common.o obj-$(CONFIG_ARM_GIC_KVM) += arm_gic_kvm.o obj-$(call land,$(CONFIG_ARM_GIC_KVM),$(TARGET_AARCH64)) += arm_gicv3_kvm.o +obj-$(call land,$(CONFIG_ARM_GIC_KVM),$(TARGET_AARCH64)) += arm_gicv3_its_kvm.o obj-$(CONFIG_STELLARIS) += armv7m_nvic.o obj-$(CONFIG_EXYNOS4) += exynos4210_gic.o exynos4210_combiner.o obj-$(CONFIG_GRLIB) += grlib_irqmp.o
hw/intc/arm_gicv3_its_common.c +1 -1
@@ -69,7 +69,7 @@ static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset,if (offset ==0x0040 ) {GICv3ITSState *s =ARM_GICV3_ITS_COMMON (opaque);GICv3ITSCommonClass *c =ARM_GICV3_ITS_COMMON_GET_CLASS (s); -int ret = c->send_msi (s,le32_to_cpu (value), attrs.stream_id); +int ret = c->send_msi (s,le32_to_cpu (value), attrs.requester_id);if (ret) { qemu_log_mask(LOG_GUEST_ERROR,
hw/intc/arm_gicv3_its_kvm.c new file +88 -0
88 lines not on this page · raw message
Signature · 1 line
2.4.4
RFC PATCH v2 5/5 arm/virt: Add ITS to the virt board
In reply to Pavel FedinIf supported by the configuration, ITS will be added automatically.
This patch also renames v2m_phandle to msi_phandle because it's now used by both MSI implementations.
--- hw/arm/virt.c | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-)
hw/arm/virt.c +41 -6
@@ -70,7 +70,7 @@ typedef struct VirtBoardInfo {int fdt_size;uint32_t clock_phandle;uint32_t gic_phandle; -uint32_t v2m_phandle; +uint32_t msi_phandle; } VirtBoardInfo; typedef struct {
@@ -351,9 +351,22 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi) } } +static void fdt_add_its_gic_node (VirtBoardInfo *vbi) +{ + vbi->msi_phandle =qemu_fdt_alloc_phandle (vbi->fdt); +qemu_fdt_add_subnode (vbi->fdt,"/intc/its" ); +qemu_fdt_setprop_string (vbi->fdt,"/intc/its" ,"compatible" , +"arm,gic-v3-its" ); +qemu_fdt_setprop (vbi->fdt,"/intc/its" ,"msi-controller" ,NULL ,0 ); +qemu_fdt_setprop_sized_cells (vbi->fdt,"/intc/its" ,"reg" , +2 , vbi->memmap[VIRT_GIC_ITS ].base, +2 , vbi->memmap[VIRT_GIC_ITS ].size); +qemu_fdt_setprop_cell (vbi->fdt,"/intc/its" ,"phandle" , vbi->msi_phandle); +} +static void fdt_add_v2m_gic_node (VirtBoardInfo *vbi) { - vbi->v2m_phandle =qemu_fdt_alloc_phandle (vbi->fdt); + vbi->msi_phandle =qemu_fdt_alloc_phandle (vbi->fdt);qemu_fdt_add_subnode (vbi->fdt,"/intc/v2m" );qemu_fdt_setprop_string (vbi->fdt,"/intc/v2m" ,"compatible" ,"arm,gic-v2m-frame" );
@@ -361,7 +374,7 @@ static void fdt_add_v2m_gic_node(VirtBoardInfo *vbi)qemu_fdt_setprop_sized_cells (vbi->fdt,"/intc/v2m" ,"reg" ,2 , vbi->memmap[VIRT_GIC_V2M ].base,2 , vbi->memmap[VIRT_GIC_V2M ].size); -qemu_fdt_setprop_cell (vbi->fdt,"/intc/v2m" ,"phandle" , vbi->v2m_phandle); +qemu_fdt_setprop_cell (vbi->fdt,"/intc/v2m" ,"phandle" , vbi->msi_phandle); }static void fdt_add_gic_node (VirtBoardInfo *vbi,int type)
@@ -397,6 +410,26 @@ static void fdt_add_gic_node(VirtBoardInfo *vbi, int type)qemu_fdt_setprop_cell (vbi->fdt,"/intc" ,"phandle" , vbi->gic_phandle); } +static void create_its (VirtBoardInfo *vbi,DeviceState *gicdev) +{ +const char *itsclass =its_class_name (); +DeviceState *dev; + +if (!itsclass) { +/* Do nothing if not supported */ +return ; + } + + dev =qdev_create (NULL , itsclass); + +object_property_set_link (OBJECT (dev),OBJECT (gicdev),"parent-gicv3" , + &error_abort); +qdev_init_nofail (dev); +sysbus_mmio_map (SYS_BUS_DEVICE (dev),0 , vbi->memmap[VIRT_GIC_ITS ].base); + +fdt_add_its_gic_node (vbi); +} +static void create_v2m (VirtBoardInfo *vbi,qemu_irq *pic) {int i;
@@ -480,7 +513,9 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure)fdt_add_gic_node (vbi, type); -if (type ==2 ) { +if (type ==3 ) { +create_its (vbi, gicdev); + }else {create_v2m (vbi, pic); } }
@@ -799,9 +834,9 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,qemu_fdt_setprop_cells (vbi->fdt, nodename,"bus-range" ,0 , nr_pcie_buses -1 ); -if (vbi->v2m_phandle) { +if (vbi->msi_phandle) {qemu_fdt_setprop_cells (vbi->fdt, nodename,"msi-parent" , - vbi->v2m_phandle); + vbi->msi_phandle); } qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
Signature · 1 line
2.4.4