]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
KVM: arm64: vgic-v3: Enable trapping of Group-1 system registers
authorMarc Zyngier <marc.zyngier@arm.com>
Fri, 9 Jun 2017 11:49:40 +0000 (12:49 +0100)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Wed, 9 Aug 2017 14:47:56 +0000 (16:47 +0200)
BugLink: https://bugs.launchpad.net/bugs/1673564
In order to be able to trap Group-1 GICv3 system registers, we need to
set ICH_HCR_EL2.TALL1 before entering the guest. This is conditionally
done after having restored the guest's state, and cleared on exit.

Tested-by: Alexander Graf <agraf@suse.de>
Acked-by: David Daney <david.daney@cavium.com>
Acked-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
(backported from commit 9c7bfc288c71068ab323b802dba2eb87fd08b127)
[ dannf: Context adjustments ]
Signed-off-by: dann frazier <dann.frazier@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
include/linux/irqchip/arm-gic-v3.h
virt/kvm/arm/hyp/vgic-v3-sr.c
virt/kvm/arm/vgic/vgic-v3.c

index cad34dc03ad5fffac33ce8bd0fe333eb4e40f3c8..5048db2b819b8945b8b2c59a6ed7fc96b2522a86 100644 (file)
 
 #define ICH_HCR_EN                     (1 << 0)
 #define ICH_HCR_UIE                    (1 << 1)
+#define ICH_HCR_TALL1                  (1 << 12)
 #define ICH_HCR_EOIcount_SHIFT         27
 #define ICH_HCR_EOIcount_MASK          (0x1f << ICH_HCR_EOIcount_SHIFT)
 
index 7fbbf82959c22e4d7705513d53908620f0ddb133..36272a12c19d03afd8a549a6019ed73800ce64df 100644 (file)
@@ -294,6 +294,9 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
 
                vcpu->arch.vgic_cpu.live_lrs = 0;
        } else {
+               if (static_branch_unlikely(&vgic_v3_cpuif_trap))
+                       write_gicreg(0, ICH_HCR_EL2);
+
                cpu_if->vgic_misr  = 0;
                cpu_if->vgic_eisr  = 0;
                cpu_if->vgic_elrsr = 0xffff;
@@ -378,6 +381,14 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
 
                        __gic_v3_set_lr(cpu_if->vgic_lr[i], i);
                }
+       } else {
+               /*
+                * If we need to trap system registers, we must write
+                * ICH_HCR_EL2 anyway, even if no interrupts are being
+                * injected,
+                */
+               if (static_branch_unlikely(&vgic_v3_cpuif_trap))
+                       write_gicreg(cpu_if->vgic_hcr, ICH_HCR_EL2);
        }
 
        /*
index e614a7cb29f09c3c8ab62e8bf17f745f157d1858..1be077a866b76e4a98fed2d11a688c593a21ea37 100644 (file)
@@ -60,6 +60,8 @@ void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu)
        cpuif->vgic_hcr &= ~ICH_HCR_UIE;
 }
 
+static bool group1_trap;
+
 void vgic_v3_set_underflow(struct kvm_vcpu *vcpu)
 {
        struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3;
@@ -226,6 +228,8 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu)
 
        /* Get the show on the road... */
        vgic_v3->vgic_hcr = ICH_HCR_EN;
+       if (group1_trap)
+               vgic_v3->vgic_hcr |= ICH_HCR_TALL1;
 }
 
 /* check for overlapping regions and for regions crossing the end of memory */