summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/kvm/arm_vgic.h2
-rw-r--r--virt/kvm/arm/hyp/vgic-v2-sr.c28
-rw-r--r--virt/kvm/arm/hyp/vgic-v3-sr.c6
-rw-r--r--virt/kvm/arm/vgic/vgic-v2.c1
-rw-r--r--virt/kvm/arm/vgic/vgic-v3.c1
5 files changed, 10 insertions, 28 deletions
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index cdbd142ca7f2..ac98ae46bfb7 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -263,7 +263,6 @@ struct vgic_dist {
263struct vgic_v2_cpu_if { 263struct vgic_v2_cpu_if {
264 u32 vgic_hcr; 264 u32 vgic_hcr;
265 u32 vgic_vmcr; 265 u32 vgic_vmcr;
266 u64 vgic_elrsr; /* Saved only */
267 u32 vgic_apr; 266 u32 vgic_apr;
268 u32 vgic_lr[VGIC_V2_MAX_LRS]; 267 u32 vgic_lr[VGIC_V2_MAX_LRS];
269}; 268};
@@ -272,7 +271,6 @@ struct vgic_v3_cpu_if {
272 u32 vgic_hcr; 271 u32 vgic_hcr;
273 u32 vgic_vmcr; 272 u32 vgic_vmcr;
274 u32 vgic_sre; /* Restored only, change ignored */ 273 u32 vgic_sre; /* Restored only, change ignored */
275 u32 vgic_elrsr; /* Saved only */
276 u32 vgic_ap0r[4]; 274 u32 vgic_ap0r[4];
277 u32 vgic_ap1r[4]; 275 u32 vgic_ap1r[4];
278 u64 vgic_lr[VGIC_V3_MAX_LRS]; 276 u64 vgic_lr[VGIC_V3_MAX_LRS];
diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c
index 4fe6e797e8b3..a91b0d2b9249 100644
--- a/virt/kvm/arm/hyp/vgic-v2-sr.c
+++ b/virt/kvm/arm/hyp/vgic-v2-sr.c
@@ -23,29 +23,19 @@
23#include <asm/kvm_hyp.h> 23#include <asm/kvm_hyp.h>
24#include <asm/kvm_mmu.h> 24#include <asm/kvm_mmu.h>
25 25
26static void __hyp_text save_elrsr(struct kvm_vcpu *vcpu, void __iomem *base)
27{
28 struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
29 int nr_lr = (kern_hyp_va(&kvm_vgic_global_state))->nr_lr;
30 u32 elrsr0, elrsr1;
31
32 elrsr0 = readl_relaxed(base + GICH_ELRSR0);
33 if (unlikely(nr_lr > 32))
34 elrsr1 = readl_relaxed(base + GICH_ELRSR1);
35 else
36 elrsr1 = 0;
37
38 cpu_if->vgic_elrsr = ((u64)elrsr1 << 32) | elrsr0;
39}
40
41static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base) 26static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base)
42{ 27{
43 struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; 28 struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
44 int i;
45 u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs; 29 u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs;
30 u64 elrsr;
31 int i;
32
33 elrsr = readl_relaxed(base + GICH_ELRSR0);
34 if (unlikely(used_lrs > 32))
35 elrsr |= ((u64)readl_relaxed(base + GICH_ELRSR1)) << 32;
46 36
47 for (i = 0; i < used_lrs; i++) { 37 for (i = 0; i < used_lrs; i++) {
48 if (cpu_if->vgic_elrsr & (1UL << i)) 38 if (elrsr & (1UL << i))
49 cpu_if->vgic_lr[i] &= ~GICH_LR_STATE; 39 cpu_if->vgic_lr[i] &= ~GICH_LR_STATE;
50 else 40 else
51 cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4)); 41 cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
@@ -68,13 +58,9 @@ void __hyp_text __vgic_v2_save_state(struct kvm_vcpu *vcpu)
68 58
69 if (used_lrs) { 59 if (used_lrs) {
70 cpu_if->vgic_apr = readl_relaxed(base + GICH_APR); 60 cpu_if->vgic_apr = readl_relaxed(base + GICH_APR);
71
72 save_elrsr(vcpu, base);
73 save_lrs(vcpu, base); 61 save_lrs(vcpu, base);
74
75 writel_relaxed(0, base + GICH_HCR); 62 writel_relaxed(0, base + GICH_HCR);
76 } else { 63 } else {
77 cpu_if->vgic_elrsr = ~0UL;
78 cpu_if->vgic_apr = 0; 64 cpu_if->vgic_apr = 0;
79 } 65 }
80} 66}
diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
index f5c3d6d7019e..9abf2f3c12b5 100644
--- a/virt/kvm/arm/hyp/vgic-v3-sr.c
+++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
@@ -222,15 +222,16 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
222 if (used_lrs) { 222 if (used_lrs) {
223 int i; 223 int i;
224 u32 nr_pre_bits; 224 u32 nr_pre_bits;
225 u32 elrsr;
225 226
226 cpu_if->vgic_elrsr = read_gicreg(ICH_ELSR_EL2); 227 elrsr = read_gicreg(ICH_ELSR_EL2);
227 228
228 write_gicreg(0, ICH_HCR_EL2); 229 write_gicreg(0, ICH_HCR_EL2);
229 val = read_gicreg(ICH_VTR_EL2); 230 val = read_gicreg(ICH_VTR_EL2);
230 nr_pre_bits = vtr_to_nr_pre_bits(val); 231 nr_pre_bits = vtr_to_nr_pre_bits(val);
231 232
232 for (i = 0; i < used_lrs; i++) { 233 for (i = 0; i < used_lrs; i++) {
233 if (cpu_if->vgic_elrsr & (1 << i)) 234 if (elrsr & (1 << i))
234 cpu_if->vgic_lr[i] &= ~ICH_LR_STATE; 235 cpu_if->vgic_lr[i] &= ~ICH_LR_STATE;
235 else 236 else
236 cpu_if->vgic_lr[i] = __gic_v3_get_lr(i); 237 cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
@@ -262,7 +263,6 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
262 cpu_if->its_vpe.its_vm) 263 cpu_if->its_vpe.its_vm)
263 write_gicreg(0, ICH_HCR_EL2); 264 write_gicreg(0, ICH_HCR_EL2);
264 265
265 cpu_if->vgic_elrsr = 0xffff;
266 cpu_if->vgic_ap0r[0] = 0; 266 cpu_if->vgic_ap0r[0] = 0;
267 cpu_if->vgic_ap0r[1] = 0; 267 cpu_if->vgic_ap0r[1] = 0;
268 cpu_if->vgic_ap0r[2] = 0; 268 cpu_if->vgic_ap0r[2] = 0;
diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
index c32d7b93ffd1..bb305d49cfdd 100644
--- a/virt/kvm/arm/vgic/vgic-v2.c
+++ b/virt/kvm/arm/vgic/vgic-v2.c
@@ -265,7 +265,6 @@ void vgic_v2_enable(struct kvm_vcpu *vcpu)
265 * anyway. 265 * anyway.
266 */ 266 */
267 vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0; 267 vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0;
268 vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr = ~0;
269 268
270 /* Get the show on the road... */ 269 /* Get the show on the road... */
271 vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN; 270 vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN;
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index 6b329414e57a..b76e21f3e6bd 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -267,7 +267,6 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu)
267 * anyway. 267 * anyway.
268 */ 268 */
269 vgic_v3->vgic_vmcr = 0; 269 vgic_v3->vgic_vmcr = 0;
270 vgic_v3->vgic_elrsr = ~0;
271 270
272 /* 271 /*
273 * If we are emulating a GICv3, we do it in an non-GICv2-compatible 272 * If we are emulating a GICv3, we do it in an non-GICv2-compatible