mirror of
https://github.com/torvalds/linux.git
synced 2026-04-27 11:02:31 -04:00
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: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Tested-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
132 lines
5.7 KiB
Plaintext
132 lines
5.7 KiB
Plaintext
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 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:
|
|
KVM_VGIC_V2_ADDR_TYPE_DIST (rw, 64-bit)
|
|
Base address in the guest physical address space of the GIC distributor
|
|
register mappings. Only valid for KVM_DEV_TYPE_ARM_VGIC_V2.
|
|
This address needs to be 4K aligned and the region covers 4 KByte.
|
|
|
|
KVM_VGIC_V2_ADDR_TYPE_CPU (rw, 64-bit)
|
|
Base address in the guest physical address space of the GIC virtual cpu
|
|
interface register mappings. Only valid for KVM_DEV_TYPE_ARM_VGIC_V2.
|
|
This address needs to be 4K aligned and the region covers 4 KByte.
|
|
|
|
KVM_VGIC_V3_ADDR_TYPE_DIST (rw, 64-bit)
|
|
Base address in the guest physical address space of the GICv3 distributor
|
|
register mappings. Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
|
|
This address needs to be 64K aligned and the region covers 64 KByte.
|
|
|
|
KVM_VGIC_V3_ADDR_TYPE_REDIST (rw, 64-bit)
|
|
Base address in the guest physical address space of the GICv3
|
|
redistributor register mappings. There are two 64K pages for each
|
|
VCPU and all of the redistributor pages are contiguous.
|
|
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:
|
|
The attr field of kvm_device_attr encodes two values:
|
|
bits: | 63 .... 40 | 39 .. 32 | 31 .... 0 |
|
|
values: | reserved | vcpu_index | offset |
|
|
|
|
All distributor regs are (rw, 32-bit)
|
|
|
|
The offset is relative to the "Distributor base address" as defined in the
|
|
GICv2 specs. Getting or setting such a register has the same effect as
|
|
reading or writing the register on the actual hardware from the cpu whose
|
|
index is specified with the vcpu_index field. Note that most distributor
|
|
fields are not banked, but return the same value regardless of the
|
|
vcpu_index used to access the register.
|
|
Limitations:
|
|
- Priorities are not implemented, and registers are RAZ/WI
|
|
- Currently only implemented for KVM_DEV_TYPE_ARM_VGIC_V2.
|
|
Errors:
|
|
-ENXIO: Getting or setting this register is not yet supported
|
|
-EBUSY: One or more VCPUs are running
|
|
-EINVAL: Invalid vcpu_index supplied
|
|
|
|
KVM_DEV_ARM_VGIC_GRP_CPU_REGS
|
|
Attributes:
|
|
The attr field of kvm_device_attr encodes two values:
|
|
bits: | 63 .... 40 | 39 .. 32 | 31 .... 0 |
|
|
values: | reserved | vcpu_index | offset |
|
|
|
|
All CPU interface regs are (rw, 32-bit)
|
|
|
|
The offset specifies the offset from the "CPU interface base address" as
|
|
defined in the GICv2 specs. Getting or setting such a register has the
|
|
same effect as reading or writing the register on the actual hardware.
|
|
|
|
The Active Priorities Registers APRn are implementation defined, so we set a
|
|
fixed format for our implementation that fits with the model of a "GICv2
|
|
implementation without the security extensions" which we present to the
|
|
guest. This interface always exposes four register APR[0-3] describing the
|
|
maximum possible 128 preemption levels. The semantics of the register
|
|
indicate if any interrupts in a given preemption level are in the active
|
|
state by setting the corresponding bit.
|
|
|
|
Thus, preemption level X has one or more active interrupts if and only if:
|
|
|
|
APRn[X mod 32] == 0b1, where n = X / 32
|
|
|
|
Bits for undefined preemption levels are RAZ/WI.
|
|
|
|
Limitations:
|
|
- Priorities are not implemented, and registers are RAZ/WI
|
|
- Currently only implemented for KVM_DEV_TYPE_ARM_VGIC_V2.
|
|
Errors:
|
|
-ENXIO: Getting or setting this register is not yet supported
|
|
-EBUSY: One or more VCPUs are running
|
|
-EINVAL: Invalid vcpu_index supplied
|
|
|
|
KVM_DEV_ARM_VGIC_GRP_NR_IRQS
|
|
Attributes:
|
|
A value describing the number of interrupts (SGI, PPI and SPI) for
|
|
this GIC instance, ranging from 64 to 1024, in increments of 32.
|
|
|
|
Errors:
|
|
-EINVAL: Value set is out of the expected range
|
|
-EBUSY: Value has already be set, or GIC has already been initialized
|
|
with default values.
|
|
|
|
KVM_DEV_ARM_VGIC_GRP_CTRL
|
|
Attributes:
|
|
KVM_DEV_ARM_VGIC_CTRL_INIT
|
|
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
|
|
-ENODEV: no online VCPU
|
|
-ENOMEM: memory shortage when allocating vgic internal data
|