Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1085fdc6 authored by Andre Przywara's avatar Andre Przywara Committed by Marc Zyngier
Browse files

KVM: arm64: vgic-its: Introduce new KVM ITS device



Introduce a new KVM device that represents an ARM Interrupt Translation
Service (ITS) controller. Since there can be multiple of this per guest,
we can't piggy back on the existing GICv3 distributor device, but create
a new type of KVM device.
On the KVM_CREATE_DEVICE ioctl we allocate and initialize the ITS data
structure and store the pointer in the kvm_device data.
Upon an explicit init ioctl from userland (after having setup the MMIO
address) we register the handlers with the kvm_io_bus framework.
Any reference to an ITS thus has to go via this interface.

Signed-off-by: default avatarAndre Przywara <andre.przywara@arm.com>
Reviewed-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Tested-by: default avatarEric Auger <eric.auger@redhat.com>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent 59c5ab40
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -4,16 +4,22 @@ ARM Virtual Generic Interrupt Controller (VGIC)
Device types supported:
  KVM_DEV_TYPE_ARM_VGIC_V2     ARM Generic Interrupt Controller v2.0
  KVM_DEV_TYPE_ARM_VGIC_V3     ARM Generic Interrupt Controller v3.0
  KVM_DEV_TYPE_ARM_VGIC_ITS    ARM Interrupt Translation Service Controller

Only one VGIC instance may be instantiated through either this API or the
legacy KVM_CREATE_IRQCHIP api.  The created VGIC will act as the VM interrupt
controller, requiring emulated user-space devices to inject interrupts to the
VGIC instead of directly to CPUs.
Only one VGIC instance of the V2/V3 types above may be instantiated through
either this API or the legacy KVM_CREATE_IRQCHIP api.  The created VGIC will
act as the VM interrupt controller, requiring emulated user-space devices to
inject interrupts to the VGIC instead of directly to CPUs.

Creating a guest GICv3 device requires a host GICv3 as well.
GICv3 implementations with hardware compatibility support allow a guest GICv2
as well.

Creating a virtual ITS controller requires a host GICv3 (but does not depend
on having physical ITS controllers).
There can be multiple ITS controllers per guest, each of them has to have
a separate, non-overlapping MMIO region.

Groups:
  KVM_DEV_ARM_VGIC_GRP_ADDR
  Attributes:
@@ -39,6 +45,13 @@ Groups:
      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.
      Only valid for KVM_DEV_TYPE_ARM_VGIC_ITS.
      This address needs to be 64K aligned and the region covers 128K.

  KVM_DEV_ARM_VGIC_GRP_DIST_REGS
  Attributes:
@@ -109,8 +122,8 @@ Groups:
  KVM_DEV_ARM_VGIC_GRP_CTRL
  Attributes:
    KVM_DEV_ARM_VGIC_CTRL_INIT
      request the initialization of the VGIC, no additional parameter in
      kvm_device_attr.addr.
      request the initialization of the VGIC or ITS, no additional parameter
      in kvm_device_attr.addr.
  Errors:
    -ENXIO: VGIC not properly configured as required prior to calling
     this attribute
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/kvm_host.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
+2 −0
Original line number Diff line number Diff line
@@ -87,9 +87,11 @@ 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_ITS_ADDR_TYPE		4

#define KVM_VGIC_V3_DIST_SIZE		SZ_64K
#define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
#define KVM_VGIC_V3_ITS_SIZE		(2 * 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 */
+3 −0
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ struct vgic_its {
	gpa_t			vgic_its_base;

	bool			enabled;
	bool			initialized;
	struct vgic_io_device	iodev;
};

@@ -167,6 +168,8 @@ struct vgic_dist {

	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
+2 −0
Original line number Diff line number Diff line
@@ -1077,6 +1077,8 @@ enum kvm_device_type {
#define KVM_DEV_TYPE_FLIC		KVM_DEV_TYPE_FLIC
	KVM_DEV_TYPE_ARM_VGIC_V3,
#define KVM_DEV_TYPE_ARM_VGIC_V3	KVM_DEV_TYPE_ARM_VGIC_V3
	KVM_DEV_TYPE_ARM_VGIC_ITS,
#define KVM_DEV_TYPE_ARM_VGIC_ITS	KVM_DEV_TYPE_ARM_VGIC_ITS
	KVM_DEV_TYPE_MAX,
};

Loading