KVM: arm/arm64: vgic: Keep track of implementation revision
authorChristoffer Dall <christoffer.dall@arm.com>
Mon, 16 Jul 2018 13:06:19 +0000 (15:06 +0200)
committerMarc Zyngier <marc.zyngier@arm.com>
Sat, 21 Jul 2018 15:02:21 +0000 (16:02 +0100)
As we are about to tweak implementation aspects of the VGIC emulation,
while still preserving some level of backwards compatibility support,
add a field to keep track of the implementation revision field which is
reported to the VM and to userspace.

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>
include/kvm/arm_vgic.h
virt/kvm/arm/vgic/vgic-init.c
virt/kvm/arm/vgic/vgic-mmio-v2.c
virt/kvm/arm/vgic/vgic-mmio-v3.c

index cfdd2484cc4263375fbb3ba527a75db2789bbb36..7e64c463ab4de377ebaa9aefd827f47e7f09b1dc 100644 (file)
@@ -217,6 +217,9 @@ struct vgic_dist {
        /* vGIC model the kernel emulates for the guest (GICv2 or GICv3) */
        u32                     vgic_model;
 
+       /* Implementation revision as reported in the GICD_IIDR */
+       u32                     implementation_rev;
+
        /* Do injected MSIs require an additional device ID? */
        bool                    msis_require_devid;
 
index b714179137414ddb96819f9dd7d5eb80e912a59d..8b6fc45c42feae8f8eb212705b20350e0bcae7d3 100644 (file)
@@ -298,6 +298,7 @@ int vgic_init(struct kvm *kvm)
 
        vgic_debug_init(kvm);
 
+       dist->implementation_rev = 0;
        dist->initialized = true;
 
 out:
index af44e569373a7e1a18a7faee80959e617f7d57d2..f0c5351805b667bca541f81d5a5911e5ef5fccb8 100644 (file)
 static unsigned long vgic_mmio_read_v2_misc(struct kvm_vcpu *vcpu,
                                            gpa_t addr, unsigned int len)
 {
+       struct vgic_dist *vgic = &vcpu->kvm->arch.vgic;
        u32 value;
 
        switch (addr & 0x0c) {
        case GIC_DIST_CTRL:
-               value = vcpu->kvm->arch.vgic.enabled ? GICD_ENABLE : 0;
+               value = vgic->enabled ? GICD_ENABLE : 0;
                break;
        case GIC_DIST_CTR:
-               value = vcpu->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
+               value = vgic->nr_spis + VGIC_NR_PRIVATE_IRQS;
                value = (value >> 5) - 1;
                value |= (atomic_read(&vcpu->kvm->online_vcpus) - 1) << 5;
                break;
        case GIC_DIST_IIDR:
                value = (PRODUCT_ID_KVM << GICD_IIDR_PRODUCT_ID_SHIFT) |
+                       (vgic->implementation_rev << GICD_IIDR_REVISION_SHIFT) |
                        (IMPLEMENTER_ARM << GICD_IIDR_IMPLEMENTER_SHIFT);
                break;
        default:
index c03f42409b989a5fdb3343b2c47734c84ce80ff6..ebe10a015bfba346f08d5e575e274259560a8b65 100644 (file)
@@ -62,16 +62,17 @@ bool vgic_supports_direct_msis(struct kvm *kvm)
 static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
                                            gpa_t addr, unsigned int len)
 {
+       struct vgic_dist *vgic = &vcpu->kvm->arch.vgic;
        u32 value = 0;
 
        switch (addr & 0x0c) {
        case GICD_CTLR:
-               if (vcpu->kvm->arch.vgic.enabled)
+               if (vgic->enabled)
                        value |= GICD_CTLR_ENABLE_SS_G1;
                value |= GICD_CTLR_ARE_NS | GICD_CTLR_DS;
                break;
        case GICD_TYPER:
-               value = vcpu->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
+               value = vgic->nr_spis + VGIC_NR_PRIVATE_IRQS;
                value = (value >> 5) - 1;
                if (vgic_has_its(vcpu->kvm)) {
                        value |= (INTERRUPT_ID_BITS_ITS - 1) << 19;
@@ -82,6 +83,7 @@ static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
                break;
        case GICD_IIDR:
                value = (PRODUCT_ID_KVM << GICD_IIDR_PRODUCT_ID_SHIFT) |
+                       (vgic->implementation_rev << GICD_IIDR_REVISION_SHIFT) |
                        (IMPLEMENTER_ARM << GICD_IIDR_IMPLEMENTER_SHIFT);
                break;
        default: