]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - virt/kvm/arm/vgic/vgic-v2.c
UBUNTU: Ubuntu-4.15.0-96.97
[mirror_ubuntu-bionic-kernel.git] / virt / kvm / arm / vgic / vgic-v2.c
index 80897102da26ce51ddb95d01da15c61277c27b66..fa79f9f54c5cece3fef32ca6c5781c5f4f6ff7e4 100644 (file)
@@ -37,6 +37,13 @@ void vgic_v2_init_lrs(void)
                vgic_v2_write_lr(i, 0);
 }
 
+void vgic_v2_set_npie(struct kvm_vcpu *vcpu)
+{
+       struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2;
+
+       cpuif->vgic_hcr |= GICH_HCR_NPIE;
+}
+
 void vgic_v2_set_underflow(struct kvm_vcpu *vcpu)
 {
        struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2;
@@ -64,7 +71,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
        int lr;
        unsigned long flags;
 
-       cpuif->vgic_hcr &= ~GICH_HCR_UIE;
+       cpuif->vgic_hcr &= ~(GICH_HCR_UIE | GICH_HCR_NPIE);
 
        for (lr = 0; lr < vgic_cpu->used_lrs; lr++) {
                u32 val = cpuif->vgic_lr[lr];
@@ -136,7 +143,10 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
                if (vgic_irq_is_sgi(irq->intid)) {
                        u32 src = ffs(irq->source);
 
-                       BUG_ON(!src);
+                       if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n",
+                                          irq->intid))
+                               return;
+
                        val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT;
                        irq->source &= ~(1 << (src - 1));
                        if (irq->source)
@@ -381,7 +391,7 @@ int vgic_v2_probe(const struct gic_kvm_info *info)
        kvm_vgic_global_state.type = VGIC_V2;
        kvm_vgic_global_state.max_gic_vcpus = VGIC_V2_MAX_CPUS;
 
-       kvm_info("vgic-v2@%llx\n", info->vctrl.start);
+       kvm_debug("vgic-v2@%llx\n", info->vctrl.start);
 
        return 0;
 out:
@@ -401,10 +411,19 @@ void vgic_v2_load(struct kvm_vcpu *vcpu)
        writel_relaxed(cpu_if->vgic_vmcr, vgic->vctrl_base + GICH_VMCR);
 }
 
-void vgic_v2_put(struct kvm_vcpu *vcpu)
+void vgic_v2_vmcr_sync(struct kvm_vcpu *vcpu)
 {
        struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
        struct vgic_dist *vgic = &vcpu->kvm->arch.vgic;
 
        cpu_if->vgic_vmcr = readl_relaxed(vgic->vctrl_base + GICH_VMCR);
 }
+
+void vgic_v2_put(struct kvm_vcpu *vcpu)
+{
+       struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
+       struct vgic_dist *vgic = &vcpu->kvm->arch.vgic;
+
+       vgic_v2_vmcr_sync(vcpu);
+       cpu_if->vgic_apr = readl_relaxed(vgic->vctrl_base + GICH_APR);
+}