요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
==============================================================
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 host, or a GICv5 host with
support for FEAT_GCIE_LEGACY.
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_VGIC_V3_ADDR_TYPE_REDIST_REGION (rw, 64-bit)
The attribute data pointed to by kvm_device_attr.addr is a __u64 value::
bits: | 63 .... 52 | 51 .... 16 | 15 - 12 |11 - 0
values: | count | base | flags | index
- index encodes the unique redistributor region index
- flags: reserved for future use, currently 0
- base field encodes bits [51:16] of the guest physical base address
of the first redistributor in the region.
- count encodes the number of redistributors in the region. Must be
greater than 0.
There are two 64K pages for each redistributor in the region and
redistributors are laid out contiguously within the region. Regions
are filled with redistributors in the index order. The sum of all
region count fields must be greater than or equal to the number of
VCPUs. Redistributor regions must be registered in the incremental
index order, starting from index 0.
The characteristics of a specific redistributor region can be read
by presetting the index field in the attr data.
Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
It is invalid to mix calls with KVM_VGIC_V3_ADDR_TYPE_REDIST and
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION attributes.
Note that to obtain reproducible results (the same VCPU being associated
with the same redistributor across a save/restore operation), VCPU creation
order, redistributor region creation order as well as the respective
interleaves of VCPU and region creation MUST be preserved. Any change in
either ordering may result in a different vcpu_id/redistributor association,
resulting in a VM that will fail to run at restore time.
Errors:
======= =============================================================
-E2BIG Address outside of addressable IPA range
-EINVAL Incorrectly aligned address, bad redistributor region
count/index, mixed redistributor region attribute usage
-EEXIST Address already configured
-ENOENT Attempt to read the characteristics of a non existing
redistributor region
-ENXIO The group or attribute is unknown/unsupported for this device
or hardware support is missing.
-EFAULT Invalid user pointer for attr->addr.
-EBUSY Attempt to write a register that is read-only after
initialization
======= =============================================================
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 are 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 the
following registers: GICD_STATUSR, GICR_STATUSR, GICD_ISPENDR,
GICR_ISPENDR0, GICD_ICPENDR, and GICR_ICPENDR0. These registers behave
differently when accessed via this interface compared to their
architecturally defined behavior to allow software a full view of the
VGIC's internal state.
The mpidr field is used to 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.
Userspace is allowed to write the following register fields prior to
initialization of the VGIC:
* GICD_IIDR.Revision
* GICD_TYPER2.nASSGIcap
GICD_IIDR.Revision is updated when the KVM implementation is changed in a
way directly observable by the guest or userspace. Userspace should read
GICD_IIDR from KVM and write back the read value to confirm its expected
behavior is aligned with the KVM implementation. Userspace should set
GICD_IIDR before setting any other registers to ensure the expected
behavior.
GICD_TYPER2.nASSGIcap allows userspace to control the support of SGIs
without an active state. At VGIC creation the field resets to the
maximum capability of the system. Userspace is expected to read the field
to determine the supported value(s) before writing to the field.
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.
Accesses (reads and writes) to the GICD_ISPENDR register region and
GICR_ISPENDR0 registers get/set the value of the latched pending state for
the interrupts.
This is identical to the value returned by a guest read from ISPENDR for an
edge triggered interrupt, but may differ for level triggered interrupts.
For edge triggered interrupts, once an interrupt becomes pending (whether
because of an edge detected on the input line or because of a guest write
to ISPENDR) this state is "latched", and only cleared when either the
interrupt is activated or when the guest writes to ICPENDR. A level
triggered interrupt may be pending either because the level input is held
high by a device, or because of a guest write to the ISPENDR register. Only
ISPENDR writes are latched; if the device lowers the line level then the
interrupt is no longer pending unless the guest also wrote to ISPENDR, and
conversely writes to ICPENDR or activations of the interrupt do not clear
the pending status if the line level is still being held high. (These
rules are documented in the GICv3 specification descriptions of the ICPENDR
and ISPENDR registers.) For a level triggered interrupt the value accessed
here is that of the latch which is set by ISPENDR and cleared by ICPENDR or
interrupt activation, whereas the value returned by a guest read from
ISPENDR is the logical OR of the latch value and the input line level.
Raw access to the latch state is provided to userspace so that it can save
and restore the entire GIC internal state (which is defined by the
combination of the current input line level and the latch state, and cannot
be deduced from purely the line level and the value of the ISPENDR
registers).
Accesses to GICD_ICPENDR register region and GICR_ICPENDR0 registers have
RAZ/WI semantics, meaning that reads always return 0 and writes are always
ignored.
Errors:
====== =====================================================
-ENXIO Getting or setting this register is not yet supported
-EBUSY One or more VCPUs are running
====== =====================================================
KVM_DEV_ARM_VGIC_GRP_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)::
| 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_GRP_CPU_SYSREGS accesses the CPU interface registers for the
CPU specified by the mpidr field.
The available registers are:
=============== ====================================================
ICC_PMR_EL1
ICC_BPR0_EL1
ICC_AP0R0_EL1
ICC_AP0R1_EL1 when the host implements at least 6 bits of priority
ICC_AP0R2_EL1 when the host implements 7 bits of priority
ICC_AP0R3_EL1 when the host implements 7 bits of priority
ICC_AP1R0_EL1
ICC_AP1R1_EL1 when the host implements at least 6 bits of priority
ICC_AP1R2_EL1 when the host implements 7 bits of priority
ICC_AP1R3_EL1 when the host implements 7 bits of priority
ICC_BPR1_EL1
ICC_CTLR_EL1
ICC_SRE_EL1
ICC_IGRPEN0_EL1
ICC_IGRPEN1_EL1
=============== ====================================================
When EL2 is available for the guest, these registers are also available:
============= ====================================================
ICH_AP0R0_EL2
ICH_AP0R1_EL2 when the host implements at least 6 bits of priority
ICH_AP0R2_EL2 when the host implements 7 bits of priority
ICH_AP0R3_EL2 when the host implements 7 bits of priority
ICH_AP1R0_EL2
ICH_AP1R1_EL2 when the host implements at least 6 bits of priority
ICH_AP1R2_EL2 when the host implements 7 bits of priority
ICH_AP1R3_EL2 when the host implements 7 bits of priority
ICH_HCR_EL2
ICC_SRE_EL2
ICH_VTR_EL2
ICH_VMCR_EL2
ICH_LR0_EL2
ICH_LR1_EL2
ICH_LR2_EL2
ICH_LR3_EL2
ICH_LR4_EL2
ICH_LR5_EL2
ICH_LR6_EL2
ICH_LR7_EL2
ICH_LR8_EL2
ICH_LR9_EL2
ICH_LR10_EL2
ICH_LR11_EL2
ICH_LR12_EL2
ICH_LR13_EL2
ICH_LR14_EL2
ICH_LR15_EL2
============= ====================================================
CPU interface registers are only described using the AArch64
encoding.
Errors:
======= =================================================
-ENXIO Getting or setting this register is not supported
-EBUSY VCPU is running
-EINVAL Invalid mpidr or register value 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. Must be called after all VCPUs have been created.
KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES
save all LPI pending bits into guest RAM pending tables.
The first kB of the pending table is not altered by this operation.
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
-EFAULT Invalid guest ram access
-EBUSY One or more VCPUS are running
======= ========================================================
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 the following info values:
VGIC_LEVEL_INFO_LINE_LEVEL:
Get/Set the input level of the IRQ line for a set of 32 contiguously
numbered interrupts.
vINTID must be a multiple of 32.
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.
SGIs and any interrupt with a higher ID than the number of interrupts
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 |
Errors:
======= =============================================
-EINVAL vINTID is not multiple of 32 or info field is
not VGIC_LEVEL_INFO_LINE_LEVEL
======= =============================================
KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ
Attributes:
The attr field of kvm_device_attr encodes the following values:
bits: | 31 .... 5 | 4 .... 0 |
values: | RES0 | vINTID |
The vINTID specifies which interrupt is generated when the vGIC
must generate a maintenance interrupt. This must be a PPI.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
VGICv3 device와 address region
1-86`KVM_DEV_TYPE_ARM_VGIC_V3`는 guest GICv3.0 interrupt controller를 생성합니다. VM에는 이 API로 VGIC 하나만 만들 수 있고 GICv2와 GICv3를 동시에 만들 수 없습니다. Userspace emulated device는 CPU가 아니라 VGIC에 interrupt를 주입해야 합니다.
Guest GICv3는 host GICv3 또는 `FEAT_GCIE_LEGACY`를 지원하는 GICv5 host가 필요합니다.
`KVM_DEV_ARM_VGIC_GRP_ADDR`에서 guest physical MMIO layout을 정합니다.
`kvm_device_attr.addr`가 가리키는 값의 field layout입니다.
Region 내부 redistributor는 각각 128KiB이며 연속 배치됩니다. Region은 index 0부터 증가 순서로 등록하고 모든 count 합은 vCPU 수 이상이어야 합니다. 읽을 때는 조회할 index를 attr data에 미리 설정합니다.
단일 `REDIST` 방식과 `REDIST_REGION` 방식을 섞을 수 없습니다. Save/restore에서 동일 vCPU가 동일 redistributor에 연결되려면 vCPU 생성 순서, region 생성 순서, 두 생성 과정의 interleave까지 보존해야 합니다.
Address·region 구성 오류입니다.
.. SPDX-License-Identifier: GPL-2.0
==============================================================
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 host, or a GICv5 host with
support for FEAT_GCIE_LEGACY.
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_VGIC_V3_ADDR_TYPE_REDIST_REGION (rw, 64-bit)
The attribute data pointed to by kvm_device_attr.addr is a __u64 value::
bits: | 63 .... 52 | 51 .... 16 | 15 - 12 |11 - 0
values: | count | base | flags | index
- index encodes the unique redistributor region index
- flags: reserved for future use, currently 0
- base field encodes bits [51:16] of the guest physical base address
of the first redistributor in the region.
- count encodes the number of redistributors in the region. Must be
greater than 0.
There are two 64K pages for each redistributor in the region and
redistributors are laid out contiguously within the region. Regions
are filled with redistributors in the index order. The sum of all
region count fields must be greater than or equal to the number of
VCPUs. Redistributor regions must be registered in the incremental
index order, starting from index 0.
The characteristics of a specific redistributor region can be read
by presetting the index field in the attr data.
Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
It is invalid to mix calls with KVM_VGIC_V3_ADDR_TYPE_REDIST and
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION attributes.
Note that to obtain reproducible results (the same VCPU being associated
with the same redistributor across a save/restore operation), VCPU creation
order, redistributor region creation order as well as the respective
interleaves of VCPU and region creation MUST be preserved. Any change in
either ordering may result in a different vcpu_id/redistributor association,
resulting in a VM that will fail to run at restore time.
Errors:
======= =============================================================
-E2BIG Address outside of addressable IPA range
-EINVAL Incorrectly aligned address, bad redistributor region
count/index, mixed redistributor region attribute usage
-EEXIST Address already configured
-ENOENT Attempt to read the characteristics of a non existing
redistributor region
-ENXIO The group or attribute is unknown/unsupported for this device
or hardware support is missing.
-EFAULT Invalid user pointer for attr->addr.
-EBUSY Attempt to write a register that is read-only after
initialization
======= =============================================================
Distributor·redistributor register state
87-192`KVM_DEV_ARM_VGIC_GRP_DIST_REGS`와 `...REDIST_REGS`의 `attr`은 상위 32-bit MPIDR와 하위 32-bit register offset을 encode합니다. Distributor register는 모두 read/write 32-bit이며 64-bit register는 lower·higher word를 별도로 access합니다.
MPIDR는 Aff3, Aff2, Aff1, Aff0을 각각 bit 63:56, 55:48, 47:40, 39:32에 배치합니다. Redistributor group은 이 MPIDR로 CPU를 선택하지만 distributor access에서는 무시되며 non-banked distributor field는 어떤 MPIDR로도 같은 값을 반환합니다.
대부분 real hardware와 같은 read/write 효과를 갖지만 migration state를 완전히 보이기 위해 `GICD_STATUSR`, `GICR_STATUSR`, pending set·clear register는 예외 semantics를 사용합니다. Read-only register write는 원칙적으로 무시합니다.
VGIC initialization 전에는 `GICD_IIDR.Revision`과 `GICD_TYPER2.nASSGIcap`을 userspace가 기록할 수 있습니다. IIDR Revision은 guest나 userspace가 직접 관찰할 수 있는 KVM 구현 변경 때 갱신됩니다.
Userspace는 KVM의 `GICD_IIDR` 값을 읽어 그대로 다시 써 기대하는 behavior revision을 확인하고, 다른 register보다 먼저 설정해야 합니다. `nASSGIcap`은 active state 없는 SGI 지원을 제어하며 생성 시 system 최대 capability로 reset되므로 지원값을 먼저 읽어야 합니다.
STATUSR attribute write는 architecture의 write-one-to-clear 대신 non-reserved bit 전체를 주어진 값으로 직접 설정해 userspace가 state를 자유롭게 복원하게 합니다.
`GICD_ISPENDR`와 `GICR_ISPENDR0` attribute access는 interrupt의 latched pending state를 직접 get/set합니다. Edge-triggered interrupt에서는 guest ISPENDR read와 같지만 level-triggered interrupt에서는 input line level과 분리된 latch만 나타냅니다.
Level interrupt의 전체 pending state는 line과 software latch의 조합입니다.
Line level과 guest ISPENDR 값만으로는 internal latch를 추론할 수 없으므로 userspace에 raw latch access를 제공합니다. `GICD_ICPENDR`와 `GICR_ICPENDR0` attribute access는 RAZ/WI여서 read는 항상 0, write는 무시됩니다.
지원하지 않는 register get/set은 `-ENXIO`, vCPU 실행 중 access는 `-EBUSY`입니다.
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 are 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 the
following registers: GICD_STATUSR, GICR_STATUSR, GICD_ISPENDR,
GICR_ISPENDR0, GICD_ICPENDR, and GICR_ICPENDR0. These registers behave
differently when accessed via this interface compared to their
architecturally defined behavior to allow software a full view of the
VGIC's internal state.
The mpidr field is used to 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.
Userspace is allowed to write the following register fields prior to
initialization of the VGIC:
* GICD_IIDR.Revision
* GICD_TYPER2.nASSGIcap
GICD_IIDR.Revision is updated when the KVM implementation is changed in a
way directly observable by the guest or userspace. Userspace should read
GICD_IIDR from KVM and write back the read value to confirm its expected
behavior is aligned with the KVM implementation. Userspace should set
GICD_IIDR before setting any other registers to ensure the expected
behavior.
GICD_TYPER2.nASSGIcap allows userspace to control the support of SGIs
without an active state. At VGIC creation the field resets to the
maximum capability of the system. Userspace is expected to read the field
to determine the supported value(s) before writing to the field.
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.
Accesses (reads and writes) to the GICD_ISPENDR register region and
GICR_ISPENDR0 registers get/set the value of the latched pending state for
the interrupts.
This is identical to the value returned by a guest read from ISPENDR for an
edge triggered interrupt, but may differ for level triggered interrupts.
For edge triggered interrupts, once an interrupt becomes pending (whether
because of an edge detected on the input line or because of a guest write
to ISPENDR) this state is "latched", and only cleared when either the
interrupt is activated or when the guest writes to ICPENDR. A level
triggered interrupt may be pending either because the level input is held
high by a device, or because of a guest write to the ISPENDR register. Only
ISPENDR writes are latched; if the device lowers the line level then the
interrupt is no longer pending unless the guest also wrote to ISPENDR, and
conversely writes to ICPENDR or activations of the interrupt do not clear
the pending status if the line level is still being held high. (These
rules are documented in the GICv3 specification descriptions of the ICPENDR
and ISPENDR registers.) For a level triggered interrupt the value accessed
here is that of the latch which is set by ISPENDR and cleared by ICPENDR or
interrupt activation, whereas the value returned by a guest read from
ISPENDR is the logical OR of the latch value and the input line level.
Raw access to the latch state is provided to userspace so that it can save
and restore the entire GIC internal state (which is defined by the
combination of the current input line level and the latch state, and cannot
be deduced from purely the line level and the value of the ISPENDR
registers).
Accesses to GICD_ICPENDR register region and GICR_ICPENDR0 registers have
RAZ/WI semantics, meaning that reads always return 0 and writes are always
ignored.
Errors:
====== =====================================================
-ENXIO Getting or setting this register is not yet supported
-EBUSY One or more VCPUs are running
====== =====================================================
CPU interface system register
193-284`KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS` attr은 MPIDR 32-bit, reserved 16-bit, A64 system-register instruction encoding 16-bit를 담습니다. Reserved bit는 0이어야 하고 `addr`는 read/write `__u64`를 가리킵니다.
하위 16-bit instr field 구성입니다.
Group은 MPIDR가 가리키는 CPU의 interface register를 access합니다. `ICC_PMR_EL1`, BPR, AP0R·AP1R, CTLR, SRE, IGRPEN register가 기본이며 host priority bit 수에 따라 추가 APR가 제공됩니다.
Host가 구현한 priority 폭이 register availability를 결정합니다.
Guest에 EL2가 있으면 `ICH_AP0R*`, `ICH_AP1R*`, `ICH_HCR_EL2`, `ICC_SRE_EL2`, `ICH_VTR_EL2`, `ICH_VMCR_EL2`와 `ICH_LR0_EL2`부터 `ICH_LR15_EL2`도 access할 수 있습니다. CPU interface register는 AArch64 encoding만 사용합니다.
CPU interface state access 오류입니다.
KVM_DEV_ARM_VGIC_GRP_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)::
| 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_GRP_CPU_SYSREGS accesses the CPU interface registers for the
CPU specified by the mpidr field.
The available registers are:
=============== ====================================================
ICC_PMR_EL1
ICC_BPR0_EL1
ICC_AP0R0_EL1
ICC_AP0R1_EL1 when the host implements at least 6 bits of priority
ICC_AP0R2_EL1 when the host implements 7 bits of priority
ICC_AP0R3_EL1 when the host implements 7 bits of priority
ICC_AP1R0_EL1
ICC_AP1R1_EL1 when the host implements at least 6 bits of priority
ICC_AP1R2_EL1 when the host implements 7 bits of priority
ICC_AP1R3_EL1 when the host implements 7 bits of priority
ICC_BPR1_EL1
ICC_CTLR_EL1
ICC_SRE_EL1
ICC_IGRPEN0_EL1
ICC_IGRPEN1_EL1
=============== ====================================================
When EL2 is available for the guest, these registers are also available:
============= ====================================================
ICH_AP0R0_EL2
ICH_AP0R1_EL2 when the host implements at least 6 bits of priority
ICH_AP0R2_EL2 when the host implements 7 bits of priority
ICH_AP0R3_EL2 when the host implements 7 bits of priority
ICH_AP1R0_EL2
ICH_AP1R1_EL2 when the host implements at least 6 bits of priority
ICH_AP1R2_EL2 when the host implements 7 bits of priority
ICH_AP1R3_EL2 when the host implements 7 bits of priority
ICH_HCR_EL2
ICC_SRE_EL2
ICH_VTR_EL2
ICH_VMCR_EL2
ICH_LR0_EL2
ICH_LR1_EL2
ICH_LR2_EL2
ICH_LR3_EL2
ICH_LR4_EL2
ICH_LR5_EL2
ICH_LR6_EL2
ICH_LR7_EL2
ICH_LR8_EL2
ICH_LR9_EL2
ICH_LR10_EL2
ICH_LR11_EL2
ICH_LR12_EL2
ICH_LR13_EL2
ICH_LR14_EL2
ICH_LR15_EL2
============= ====================================================
CPU interface registers are only described using the AArch64
encoding.
Errors:
======= =================================================
-ENXIO Getting or setting this register is not supported
-EBUSY VCPU is running
-EINVAL Invalid mpidr or register value supplied
======= =================================================
Interrupt 수와 control operation
285-323`KVM_DEV_ARM_VGIC_GRP_NR_IRQS`는 SGI, PPI, SPI를 합친 interrupt 수를 `__u32`로 설정합니다. 범위는 64부터 1024까지이고 32 단위로 증가해야 합니다. 범위 밖 값은 `-EINVAL`, 이미 설정한 값은 `-EBUSY`입니다.
`KVM_DEV_ARM_VGIC_CTRL_INIT`은 모든 vCPU를 만든 뒤 VGIC를 initialize합니다. 추가 parameter는 없습니다. `KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES`는 모든 LPI pending bit를 guest RAM pending table에 저장하지만 table의 첫 1KiB는 변경하지 않습니다.
Initialize·pending-table save가 실패하는 조건입니다.
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. Must be called after all VCPUs have been created.
KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES
save all LPI pending bits into guest RAM pending tables.
The first kB of the pending table is not altered by this operation.
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
-EFAULT Invalid guest ram access
-EBUSY One or more VCPUS are running
======= ========================================================
IRQ line level과 maintenance interrupt
324-376`KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO` attr은 MPIDR, info field, 10-bit vINTID를 encode합니다. 현재 `VGIC_LEVEL_INFO_LINE_LEVEL`만 지원하며 32개 연속 interrupt의 input line level을 `__u32` bitmap으로 get/set합니다.
vINTID는 32의 배수여야 하고 bit N은 interrupt `vINTID+N`의 asserted 상태를 뜻합니다. SGI와 구현 범위를 넘는 ID는 RAZ/WI입니다. LPI는 항상 edge-triggered이므로 이 interface에서 지원하지 않습니다.
PPI는 MPIDR로 지정한 vCPU별 값을 보고하고 SPI는 MPIDR와 무관하게 같은 값을 보고합니다. 잘못된 vINTID alignment나 info 값은 `-EINVAL`입니다.
64-bit attribute encoding입니다.
`KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ` attr의 하위 5-bit vINTID는 vGIC maintenance interrupt로 생성할 PPI를 지정하고 bit 31:5는 RES0입니다.
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 the following info values:
VGIC_LEVEL_INFO_LINE_LEVEL:
Get/Set the input level of the IRQ line for a set of 32 contiguously
numbered interrupts.
vINTID must be a multiple of 32.
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.
SGIs and any interrupt with a higher ID than the number of interrupts
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 |
Errors:
======= =============================================
-EINVAL vINTID is not multiple of 32 or info field is
not VGIC_LEVEL_INFO_LINE_LEVEL
======= =============================================
KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ
Attributes:
The attr field of kvm_device_attr encodes the following values:
bits: | 31 .... 5 | 4 .... 0 |
values: | RES0 | vINTID |
The vINTID specifies which interrupt is generated when the vGIC
must generate a maintenance interrupt. This must be a PPI.
요약·해설
arm-vgic-v3.rst:1-376VGICv3 distributor·redistributor·CPU interface state, pending latch, IRQ count와 line-level device ABI입니다.
Register, attribute, bit field, error code와 source path는 원문 표기를 유지했습니다.