[PATCH v3] KVM: arm/arm64: Add VGICv3 save/restore API documentation
Christoffer Dall
christoffer.dall at linaro.org
Wed May 18 10:04:13 PDT 2016
On Fri, May 13, 2016 at 04:05:19PM +0100, Marc Zyngier wrote:
> On 13/05/16 15:43, Christoffer Dall wrote:
> > Factor out the GICv3-specific documentation into a separate
> > documentation file. Add description for how to access distributor,
> > redistributor, and CPU interface registers for GICv3 in this new file,
> > and add a group for accesing level triggered IRQ information for GICv3
>
> accessing
>
> > as well.
> >
> > Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
> > ---
> > Changes since v2:
> > - Changed distributor access to be 32-bits in size
> > - Clearly specified data type pointed to by addr field
> > - Specified exception behavior for STATUSR registers
> > - Added group for level-triggered IRQ status info
> > - Removed acks from Marc/Peter as content has changed
> >
> > Documentation/virtual/kvm/devices/arm-vgic-v3.txt | 176 ++++++++++++++++++++++
> > Documentation/virtual/kvm/devices/arm-vgic.txt | 21 +--
> > 2 files changed, 180 insertions(+), 17 deletions(-)
> > create mode 100644 Documentation/virtual/kvm/devices/arm-vgic-v3.txt
> >
> > diff --git a/Documentation/virtual/kvm/devices/arm-vgic-v3.txt b/Documentation/virtual/kvm/devices/arm-vgic-v3.txt
> > new file mode 100644
> > index 0000000..69201e8
> > --- /dev/null
> > +++ b/Documentation/virtual/kvm/devices/arm-vgic-v3.txt
> > @@ -0,0 +1,176 @@
> > +ARM Virtual Generic Interrupt Controller v3 and later (VGICv3)
> > +==============================================================
> > +
> > +
> > +Device types supported:
> > + KVM_DEV_TYPE_ARM_VGIC_V3 ARM Generic Interrupt Controller v3.0
> > +
> > +Only one VGIC instance may be instantiated through this 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. It is not
> > +possible to create both a GICv3 and GICv2 on the same VM.
> > +
> > +Creating a guest GICv3 device requires a host GICv3 as well.
> > +
> > +Groups:
> > + KVM_DEV_ARM_VGIC_GRP_ADDR
> > + Attributes:
> > + 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_DEV_ARM_VGIC_GRP_DIST_REGS
> > + KVM_DEV_ARM_VGIC_GRP_REDIST_REGS
> > + Attributes:
> > + The attr field of kvm_device_attr encodes two values:
> > + bits: | 63 .... 32 | 31 .... 0 |
> > + values: | mpidr | offset |
> > +
> > + All distributor regs are (rw, 32-bit) and kvm_device_attr.addr points to a
> > + __u32 value. 64-bit registers must be accessed by separately accessing the
> > + lower and higher word.
> > +
> > + Writes to read-only registers can be ignored by the kernel.
> > +
> > + KVM_DEV_ARM_VGIC_GRP_DIST_REGS accesses the main distributor registers.
> > + KVM_DEV_ARM_VGIC_GRP_REDIST_REGS accesses the redistributor of the CPU
> > + specified by the mpidr.
> > +
> > + The offset is relative to the "[Re]Distributor base address" as defined
> > + in the GICv3/4 specs. Getting or setting such a register has the same
> > + effect as reading or writing the register on real hardware (except for
> > + GICD_STATUS and GICR_STATUSR, see blow), and the mpidr field is used to
>
> below
>
> > + specify which redistributor is accessed. The mpidr is ignored for the
> > + distributor.
> > +
> > + The mpidr encoding is based on the affinity information in the
> > + architecture defined MPIDR, and the field is encoded as follows:
> > + | 63 .... 56 | 55 .... 48 | 47 .... 40 | 39 .... 32 |
> > + | Aff3 | Aff2 | Aff1 | Aff0 |
> > +
> > + Note that distributor fields are not banked, but return the same value
> > + regardless of the mpidr used to access the register.
> > +
> > + The GICD_STATUSR and GICR_STATUSR registers are architecturally defined such
> > + that a write of a clear bit has no effect, whereas a write with a set bit
> > + clears that value. To allow userspace to freely set the values of these two
> > + registers, setting the attributes with the register offsets for these two
> > + registers simply sets the non-reserved bits to the value written.
> > + Limitations:
> > + - Priorities are not implemented, and registers are RAZ/WI
> > + Errors:
> > + -ENXIO: Getting or setting this register is not yet supported
> > + -EBUSY: One or more VCPUs are running
> > +
> > +
> > + KVM_DEV_ARM_VGIC_CPU_SYSREGS
> > + Attributes:
> > + The attr field of kvm_device_attr encodes two values:
> > + bits: | 63 .... 32 | 31 .... 16 | 15 .... 0 |
> > + values: | mpidr | RES | instr |
> > +
> > + The mpidr field encodes the CPU ID based on the affinity information in the
> > + architecture defined MPIDR, and the field is encoded as follows:
> > + | 63 .... 56 | 55 .... 48 | 47 .... 40 | 39 .... 32 |
> > + | Aff3 | Aff2 | Aff1 | Aff0 |
> > +
> > + The instr field encodes the system register to access based on the fields
> > + defined in the A64 instruction set encoding for system register access
> > + (RES means the bits are reserved for future use and should be zero):
>
> Should we call this field RES0 in order to match the various
> architecture documents?
>
> > +
> > + | 15 ... 14 | 13 ... 11 | 10 ... 7 | 6 ... 3 | 2 ... 0 |
> > + | Op 0 | Op1 | CRn | CRm | Op2 |
> > +
> > + All system regs accessed through this API are (rw, 64-bit) and
> > + kvm_device_attr.addr points to a __u64 value.
> > +
> > + KVM_DEV_ARM_VGIC_CPU_SYSREGS accesses the CPU interface registers for the
> > + CPU specified by the mpidr field.
> > +
> > +
> > + Limitations:
> > + - Priorities are not implemented, and registers are RAZ/WI
>
> Is that still true? We should also document the lack of Group0 support.
>
> > + Errors:
> > + -ENXIO: Getting or setting this register is not yet supported
> > + -EBUSY: VCPU is running
> > + -EINVAL: Invalid mpidr 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.
> > +
> > + kvm_device_attr.addr points to a __u32 value.
> > +
> > + Errors:
> > + -EINVAL: Value set is out of the expected range
> > + -EBUSY: Value has already be set.
> > +
> > +
> > + 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.
> > + 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
> > +
> > +
> > + KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO
> > + Attributes:
> > + The attr field of kvm_device_attr encodes the following values:
> > + bits: | 63 .... 32 | 31 .... 10 | 9 .... 0 |
> > + values: | mpidr | info | vINTID |
> > +
> > + The vINTID specifies which set of IRQs is reported on.
> > +
> > + The info field specifies which information userspace wants to get or set
> > + using this interface. Currently we support two different pieces of
> > + information:
> > +
> > + VGIC_LEVEL_INFO_LINE_LEVEL:
> > + Get/Set the intput level of the IRQ line for a given IRQ.
> > + vINTID must be a multiple of 32.
>
> Is it for a single interrupt, or a set of 32 interrupts? I believe this
> is the latter, so the "for a given IRQ" is a bit misleading ("for a set
> of 32 contiguous interrupts"?).
>
> > +
> > + kvm_device_attr.addr points to a __u32 value which will contain a
> > + bitmap where a set bit means the interrupt level is asserted.
> > +
> > + Bit[n] indicates the status for interrupt vINTID + n.
> > +
> > +
> > + VGIC_LEVEL_INFO_SOFT_PENDING
> > + Get/Set the latch state of a GIVEN level-triggered IRQ as manipulated by
> > + guest writes to GICD_SPENDR.
> > + vINTID must be a multiple of 32.
>
> Same here. Also, can you clear the soft-pending bit through this
> interface? If so, this is not equivalent to a write to GICD_SPENDR.
>
> > +
> > + kvm_device_attr.addr points to a __u32 value which will contain a
> > + bitmap where a set bit means the guest has set the interrupt by writing
> > + to the SPENDR.
> > +
> > + Bit[n] indicates the status for interrupt vINTID + n.
> > +
> > +
> > + SGIs and any interrupt with a higher ID than the number of interrupts
>
> INTID
>
> > + supported, will be RAZ/WI. LPIs are always edge-triggered and are
> > + therefore not supported by this interface.
> > +
> > + PPIs are reported per VCPU as specified in the mpidr field, and SPIs are
> > + reported with the same value regardless of the mpidr specified.
> > +
> > + The mpidr field encodes the CPU ID based on the affinity information in the
> > + architecture defined MPIDR, and the field is encoded as follows:
> > + | 63 .... 56 | 55 .... 48 | 47 .... 40 | 39 .... 32 |
> > + | Aff3 | Aff2 | Aff1 | Aff0 |
> > diff --git a/Documentation/virtual/kvm/devices/arm-vgic.txt b/Documentation/virtual/kvm/devices/arm-vgic.txt
> > index 59541d4..257b854 100644
> > --- a/Documentation/virtual/kvm/devices/arm-vgic.txt
> > +++ b/Documentation/virtual/kvm/devices/arm-vgic.txt
> > @@ -3,16 +3,16 @@ 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
> >
> > 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.
> >
> > -Creating a guest GICv3 device requires a host GICv3 as well.
> > -GICv3 implementations with hardware compatibility support allow a guest GICv2
> > -as well.
> > +GICv3 implementations with hardware compatibility support allow creating a
> > +guest GICv2 through this interface. For information on creating a guest GICv3
> > +device, see arm-vgic-v3.txt. It is not possible to create both a GICv3 and
> > +GICv2 device on the same VM.
> >
> > Groups:
> > KVM_DEV_ARM_VGIC_GRP_ADDR
> > @@ -27,19 +27,6 @@ Groups:
> > 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_DEV_ARM_VGIC_GRP_DIST_REGS
> > Attributes:
> > The attr field of kvm_device_attr encodes two values:
> >
>
Ack on all your points, will consider them on respin.
-Christoffer
More information about the linux-arm-kernel
mailing list