aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/virt/kvm/arm/vgic/vgic-mmio-v2.c
diff options
context:
space:
mode:
authorChristoffer Dall <christoffer.dall@arm.com>2018-07-16 15:06:25 +0200
committerMarc Zyngier <marc.zyngier@arm.com>2018-07-21 16:02:29 +0100
commitd53c2c29ae0dfac1e062939afeaeaa1a45cc47a3 (patch)
tree539c32e02b61bb9e16d84fe75e01a7a37429d2df /virt/kvm/arm/vgic/vgic-mmio-v2.c
parentKVM: arm/arm64: vgic: Return error on incompatible uaccess GICD_IIDR writes (diff)
downloadwireguard-linux-d53c2c29ae0dfac1e062939afeaeaa1a45cc47a3.tar.xz
wireguard-linux-d53c2c29ae0dfac1e062939afeaeaa1a45cc47a3.zip
KVM: arm/arm64: vgic: Allow configuration of interrupt groups
Implement the required MMIO accessors for GICv2 and GICv3 for the IGROUPR distributor and redistributor registers. This can allow guests to change behavior compared to running on previous versions of KVM, but only to align with the architecture and hardware implementations. This also allows userspace to configure the interrupts groups for GICv3. We don't allow userspace to write the groups on GICv2 just yet, because that would result in GICv2 guests not receiving interrupts after migrating from an older kernel that exposes GICv2 interrupts as group 1. Reviewed-by: Andrew Jones <drjones@redhat.com> Signed-off-by: Christoffer Dall <christoffer.dall@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt/kvm/arm/vgic/vgic-mmio-v2.c')
-rw-r--r--virt/kvm/arm/vgic/vgic-mmio-v2.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c
index 4f0f2c4165ec..ee164f831401 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v2.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c
@@ -26,6 +26,8 @@
* The Revision field in the IIDR have the following meanings:
*
* Revision 1: Report GICv2 interrupts as group 0 instead of group 1
+ * Revision 2: Interrupt groups are guest-configurable and signaled using
+ * their configured groups.
*/
static unsigned long vgic_mmio_read_v2_misc(struct kvm_vcpu *vcpu,
@@ -89,6 +91,14 @@ static int vgic_mmio_uaccess_write_v2_misc(struct kvm_vcpu *vcpu,
return 0;
}
+static int vgic_mmio_uaccess_write_v2_group(struct kvm_vcpu *vcpu,
+ gpa_t addr, unsigned int len,
+ unsigned long val)
+{
+ /* Ignore writes from userspace */
+ return 0;
+}
+
static void vgic_mmio_write_sgir(struct kvm_vcpu *source_vcpu,
gpa_t addr, unsigned int len,
unsigned long val)
@@ -386,7 +396,8 @@ static const struct vgic_register_region vgic_v2_dist_registers[] = {
NULL, vgic_mmio_uaccess_write_v2_misc,
12, VGIC_ACCESS_32bit),
REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_IGROUP,
- vgic_mmio_read_raz, vgic_mmio_write_wi, NULL, NULL, 1,
+ vgic_mmio_read_group, vgic_mmio_write_group,
+ NULL, vgic_mmio_uaccess_write_v2_group, 1,
VGIC_ACCESS_32bit),
REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ENABLE_SET,
vgic_mmio_read_enable, vgic_mmio_write_senable, NULL, NULL, 1,