diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2017-06-08 09:04:38 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2017-06-08 09:04:38 -0400 |
commit | 38a4f43d5698daec601f4c5652ec287e594faf84 (patch) | |
tree | 0fd3fc91b5c95114de064dc8324dc99e00baedd2 | |
parent | d4912215d1031e4fb3d1038d2e1857218dba0d0a (diff) | |
parent | 33b5c38852b29736f3b472dd095c9a18ec22746f (diff) |
Merge tag 'kvm-arm-for-v4.12-rc5-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/ARM Fixes for v4.12-rc5 - Take 2
Changes include:
- Fix an issue with migrating GICv2 VMs on GICv3 systems.
- Squashed a bug for gicv3 when figuring out preemption levels.
- Fix a potential null pointer derefence in KVM happening under memory
pressure.
- Maintain RES1 bits in the SCTLR_EL2 to make sure KVM works on new
architecture revisions.
- Allow unaligned accesses at EL2/HYP
-rw-r--r-- | arch/arm/kvm/init.S | 5 | ||||
-rw-r--r-- | arch/arm64/include/asm/sysreg.h | 4 | ||||
-rw-r--r-- | arch/arm64/kvm/hyp-init.S | 11 | ||||
-rw-r--r-- | arch/arm64/kvm/vgic-sys-reg-v3.c | 10 | ||||
-rw-r--r-- | include/linux/irqchip/arm-gic-v3.h | 4 | ||||
-rw-r--r-- | include/linux/irqchip/arm-gic.h | 28 | ||||
-rw-r--r-- | virt/kvm/arm/hyp/vgic-v3-sr.c | 2 | ||||
-rw-r--r-- | virt/kvm/arm/mmu.c | 3 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-mmio-v2.c | 16 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-v2.c | 28 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-v3.c | 47 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic.h | 12 |
12 files changed, 131 insertions, 39 deletions
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S index 570ed4a9c261..5386528665b5 100644 --- a/arch/arm/kvm/init.S +++ b/arch/arm/kvm/init.S | |||
@@ -104,7 +104,6 @@ __do_hyp_init: | |||
104 | @ - Write permission implies XN: disabled | 104 | @ - Write permission implies XN: disabled |
105 | @ - Instruction cache: enabled | 105 | @ - Instruction cache: enabled |
106 | @ - Data/Unified cache: enabled | 106 | @ - Data/Unified cache: enabled |
107 | @ - Memory alignment checks: enabled | ||
108 | @ - MMU: enabled (this code must be run from an identity mapping) | 107 | @ - MMU: enabled (this code must be run from an identity mapping) |
109 | mrc p15, 4, r0, c1, c0, 0 @ HSCR | 108 | mrc p15, 4, r0, c1, c0, 0 @ HSCR |
110 | ldr r2, =HSCTLR_MASK | 109 | ldr r2, =HSCTLR_MASK |
@@ -112,8 +111,8 @@ __do_hyp_init: | |||
112 | mrc p15, 0, r1, c1, c0, 0 @ SCTLR | 111 | mrc p15, 0, r1, c1, c0, 0 @ SCTLR |
113 | ldr r2, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C) | 112 | ldr r2, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C) |
114 | and r1, r1, r2 | 113 | and r1, r1, r2 |
115 | ARM( ldr r2, =(HSCTLR_M | HSCTLR_A) ) | 114 | ARM( ldr r2, =(HSCTLR_M) ) |
116 | THUMB( ldr r2, =(HSCTLR_M | HSCTLR_A | HSCTLR_TE) ) | 115 | THUMB( ldr r2, =(HSCTLR_M | HSCTLR_TE) ) |
117 | orr r1, r1, r2 | 116 | orr r1, r1, r2 |
118 | orr r0, r0, r1 | 117 | orr r0, r0, r1 |
119 | mcr p15, 4, r0, c1, c0, 0 @ HSCR | 118 | mcr p15, 4, r0, c1, c0, 0 @ HSCR |
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 15c142ce991c..b4d13d9267ff 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h | |||
@@ -286,6 +286,10 @@ | |||
286 | #define SCTLR_ELx_A (1 << 1) | 286 | #define SCTLR_ELx_A (1 << 1) |
287 | #define SCTLR_ELx_M 1 | 287 | #define SCTLR_ELx_M 1 |
288 | 288 | ||
289 | #define SCTLR_EL2_RES1 ((1 << 4) | (1 << 5) | (1 << 11) | (1 << 16) | \ | ||
290 | (1 << 16) | (1 << 18) | (1 << 22) | (1 << 23) | \ | ||
291 | (1 << 28) | (1 << 29)) | ||
292 | |||
289 | #define SCTLR_ELx_FLAGS (SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \ | 293 | #define SCTLR_ELx_FLAGS (SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \ |
290 | SCTLR_ELx_SA | SCTLR_ELx_I) | 294 | SCTLR_ELx_SA | SCTLR_ELx_I) |
291 | 295 | ||
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S index 839425c24b1c..3f9615582377 100644 --- a/arch/arm64/kvm/hyp-init.S +++ b/arch/arm64/kvm/hyp-init.S | |||
@@ -106,10 +106,13 @@ __do_hyp_init: | |||
106 | tlbi alle2 | 106 | tlbi alle2 |
107 | dsb sy | 107 | dsb sy |
108 | 108 | ||
109 | mrs x4, sctlr_el2 | 109 | /* |
110 | and x4, x4, #SCTLR_ELx_EE // preserve endianness of EL2 | 110 | * Preserve all the RES1 bits while setting the default flags, |
111 | ldr x5, =SCTLR_ELx_FLAGS | 111 | * as well as the EE bit on BE. Drop the A flag since the compiler |
112 | orr x4, x4, x5 | 112 | * is allowed to generate unaligned accesses. |
113 | */ | ||
114 | ldr x4, =(SCTLR_EL2_RES1 | (SCTLR_ELx_FLAGS & ~SCTLR_ELx_A)) | ||
115 | CPU_BE( orr x4, x4, #SCTLR_ELx_EE) | ||
113 | msr sctlr_el2, x4 | 116 | msr sctlr_el2, x4 |
114 | isb | 117 | isb |
115 | 118 | ||
diff --git a/arch/arm64/kvm/vgic-sys-reg-v3.c b/arch/arm64/kvm/vgic-sys-reg-v3.c index 79f37e37d367..6260b69e5622 100644 --- a/arch/arm64/kvm/vgic-sys-reg-v3.c +++ b/arch/arm64/kvm/vgic-sys-reg-v3.c | |||
@@ -65,8 +65,8 @@ static bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, | |||
65 | * Here set VMCR.CTLR in ICC_CTLR_EL1 layout. | 65 | * Here set VMCR.CTLR in ICC_CTLR_EL1 layout. |
66 | * The vgic_set_vmcr() will convert to ICH_VMCR layout. | 66 | * The vgic_set_vmcr() will convert to ICH_VMCR layout. |
67 | */ | 67 | */ |
68 | vmcr.ctlr = val & ICC_CTLR_EL1_CBPR_MASK; | 68 | vmcr.cbpr = (val & ICC_CTLR_EL1_CBPR_MASK) >> ICC_CTLR_EL1_CBPR_SHIFT; |
69 | vmcr.ctlr |= val & ICC_CTLR_EL1_EOImode_MASK; | 69 | vmcr.eoim = (val & ICC_CTLR_EL1_EOImode_MASK) >> ICC_CTLR_EL1_EOImode_SHIFT; |
70 | vgic_set_vmcr(vcpu, &vmcr); | 70 | vgic_set_vmcr(vcpu, &vmcr); |
71 | } else { | 71 | } else { |
72 | val = 0; | 72 | val = 0; |
@@ -83,8 +83,8 @@ static bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, | |||
83 | * The VMCR.CTLR value is in ICC_CTLR_EL1 layout. | 83 | * The VMCR.CTLR value is in ICC_CTLR_EL1 layout. |
84 | * Extract it directly using ICC_CTLR_EL1 reg definitions. | 84 | * Extract it directly using ICC_CTLR_EL1 reg definitions. |
85 | */ | 85 | */ |
86 | val |= vmcr.ctlr & ICC_CTLR_EL1_CBPR_MASK; | 86 | val |= (vmcr.cbpr << ICC_CTLR_EL1_CBPR_SHIFT) & ICC_CTLR_EL1_CBPR_MASK; |
87 | val |= vmcr.ctlr & ICC_CTLR_EL1_EOImode_MASK; | 87 | val |= (vmcr.eoim << ICC_CTLR_EL1_EOImode_SHIFT) & ICC_CTLR_EL1_EOImode_MASK; |
88 | 88 | ||
89 | p->regval = val; | 89 | p->regval = val; |
90 | } | 90 | } |
@@ -135,7 +135,7 @@ static bool access_gic_bpr1(struct kvm_vcpu *vcpu, struct sys_reg_params *p, | |||
135 | p->regval = 0; | 135 | p->regval = 0; |
136 | 136 | ||
137 | vgic_get_vmcr(vcpu, &vmcr); | 137 | vgic_get_vmcr(vcpu, &vmcr); |
138 | if (!((vmcr.ctlr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT)) { | 138 | if (!vmcr.cbpr) { |
139 | if (p->is_write) { | 139 | if (p->is_write) { |
140 | vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >> | 140 | vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >> |
141 | ICC_BPR1_EL1_SHIFT; | 141 | ICC_BPR1_EL1_SHIFT; |
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index fffb91202bc9..1fa293a37f4a 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h | |||
@@ -417,6 +417,10 @@ | |||
417 | #define ICH_HCR_EN (1 << 0) | 417 | #define ICH_HCR_EN (1 << 0) |
418 | #define ICH_HCR_UIE (1 << 1) | 418 | #define ICH_HCR_UIE (1 << 1) |
419 | 419 | ||
420 | #define ICH_VMCR_ACK_CTL_SHIFT 2 | ||
421 | #define ICH_VMCR_ACK_CTL_MASK (1 << ICH_VMCR_ACK_CTL_SHIFT) | ||
422 | #define ICH_VMCR_FIQ_EN_SHIFT 3 | ||
423 | #define ICH_VMCR_FIQ_EN_MASK (1 << ICH_VMCR_FIQ_EN_SHIFT) | ||
420 | #define ICH_VMCR_CBPR_SHIFT 4 | 424 | #define ICH_VMCR_CBPR_SHIFT 4 |
421 | #define ICH_VMCR_CBPR_MASK (1 << ICH_VMCR_CBPR_SHIFT) | 425 | #define ICH_VMCR_CBPR_MASK (1 << ICH_VMCR_CBPR_SHIFT) |
422 | #define ICH_VMCR_EOIM_SHIFT 9 | 426 | #define ICH_VMCR_EOIM_SHIFT 9 |
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index dc30f3d057eb..d3453ee072fc 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h | |||
@@ -25,7 +25,18 @@ | |||
25 | #define GICC_ENABLE 0x1 | 25 | #define GICC_ENABLE 0x1 |
26 | #define GICC_INT_PRI_THRESHOLD 0xf0 | 26 | #define GICC_INT_PRI_THRESHOLD 0xf0 |
27 | 27 | ||
28 | #define GIC_CPU_CTRL_EOImodeNS (1 << 9) | 28 | #define GIC_CPU_CTRL_EnableGrp0_SHIFT 0 |
29 | #define GIC_CPU_CTRL_EnableGrp0 (1 << GIC_CPU_CTRL_EnableGrp0_SHIFT) | ||
30 | #define GIC_CPU_CTRL_EnableGrp1_SHIFT 1 | ||
31 | #define GIC_CPU_CTRL_EnableGrp1 (1 << GIC_CPU_CTRL_EnableGrp1_SHIFT) | ||
32 | #define GIC_CPU_CTRL_AckCtl_SHIFT 2 | ||
33 | #define GIC_CPU_CTRL_AckCtl (1 << GIC_CPU_CTRL_AckCtl_SHIFT) | ||
34 | #define GIC_CPU_CTRL_FIQEn_SHIFT 3 | ||
35 | #define GIC_CPU_CTRL_FIQEn (1 << GIC_CPU_CTRL_FIQEn_SHIFT) | ||
36 | #define GIC_CPU_CTRL_CBPR_SHIFT 4 | ||
37 | #define GIC_CPU_CTRL_CBPR (1 << GIC_CPU_CTRL_CBPR_SHIFT) | ||
38 | #define GIC_CPU_CTRL_EOImodeNS_SHIFT 9 | ||
39 | #define GIC_CPU_CTRL_EOImodeNS (1 << GIC_CPU_CTRL_EOImodeNS_SHIFT) | ||
29 | 40 | ||
30 | #define GICC_IAR_INT_ID_MASK 0x3ff | 41 | #define GICC_IAR_INT_ID_MASK 0x3ff |
31 | #define GICC_INT_SPURIOUS 1023 | 42 | #define GICC_INT_SPURIOUS 1023 |
@@ -84,8 +95,19 @@ | |||
84 | #define GICH_LR_EOI (1 << 19) | 95 | #define GICH_LR_EOI (1 << 19) |
85 | #define GICH_LR_HW (1 << 31) | 96 | #define GICH_LR_HW (1 << 31) |
86 | 97 | ||
87 | #define GICH_VMCR_CTRL_SHIFT 0 | 98 | #define GICH_VMCR_ENABLE_GRP0_SHIFT 0 |
88 | #define GICH_VMCR_CTRL_MASK (0x21f << GICH_VMCR_CTRL_SHIFT) | 99 | #define GICH_VMCR_ENABLE_GRP0_MASK (1 << GICH_VMCR_ENABLE_GRP0_SHIFT) |
100 | #define GICH_VMCR_ENABLE_GRP1_SHIFT 1 | ||
101 | #define GICH_VMCR_ENABLE_GRP1_MASK (1 << GICH_VMCR_ENABLE_GRP1_SHIFT) | ||
102 | #define GICH_VMCR_ACK_CTL_SHIFT 2 | ||
103 | #define GICH_VMCR_ACK_CTL_MASK (1 << GICH_VMCR_ACK_CTL_SHIFT) | ||
104 | #define GICH_VMCR_FIQ_EN_SHIFT 3 | ||
105 | #define GICH_VMCR_FIQ_EN_MASK (1 << GICH_VMCR_FIQ_EN_SHIFT) | ||
106 | #define GICH_VMCR_CBPR_SHIFT 4 | ||
107 | #define GICH_VMCR_CBPR_MASK (1 << GICH_VMCR_CBPR_SHIFT) | ||
108 | #define GICH_VMCR_EOI_MODE_SHIFT 9 | ||
109 | #define GICH_VMCR_EOI_MODE_MASK (1 << GICH_VMCR_EOI_MODE_SHIFT) | ||
110 | |||
89 | #define GICH_VMCR_PRIMASK_SHIFT 27 | 111 | #define GICH_VMCR_PRIMASK_SHIFT 27 |
90 | #define GICH_VMCR_PRIMASK_MASK (0x1f << GICH_VMCR_PRIMASK_SHIFT) | 112 | #define GICH_VMCR_PRIMASK_MASK (0x1f << GICH_VMCR_PRIMASK_SHIFT) |
91 | #define GICH_VMCR_BINPOINT_SHIFT 21 | 113 | #define GICH_VMCR_BINPOINT_SHIFT 21 |
diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c index 32c3295929b0..87940364570b 100644 --- a/virt/kvm/arm/hyp/vgic-v3-sr.c +++ b/virt/kvm/arm/hyp/vgic-v3-sr.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <asm/kvm_hyp.h> | 22 | #include <asm/kvm_hyp.h> |
23 | 23 | ||
24 | #define vtr_to_max_lr_idx(v) ((v) & 0xf) | 24 | #define vtr_to_max_lr_idx(v) ((v) & 0xf) |
25 | #define vtr_to_nr_pre_bits(v) (((u32)(v) >> 26) + 1) | 25 | #define vtr_to_nr_pre_bits(v) ((((u32)(v) >> 26) & 7) + 1) |
26 | 26 | ||
27 | static u64 __hyp_text __gic_v3_get_lr(unsigned int lr) | 27 | static u64 __hyp_text __gic_v3_get_lr(unsigned int lr) |
28 | { | 28 | { |
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c index a2d63247d1bb..e2e5effba2a9 100644 --- a/virt/kvm/arm/mmu.c +++ b/virt/kvm/arm/mmu.c | |||
@@ -879,6 +879,9 @@ static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache | |||
879 | pmd_t *pmd; | 879 | pmd_t *pmd; |
880 | 880 | ||
881 | pud = stage2_get_pud(kvm, cache, addr); | 881 | pud = stage2_get_pud(kvm, cache, addr); |
882 | if (!pud) | ||
883 | return NULL; | ||
884 | |||
882 | if (stage2_pud_none(*pud)) { | 885 | if (stage2_pud_none(*pud)) { |
883 | if (!cache) | 886 | if (!cache) |
884 | return NULL; | 887 | return NULL; |
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c index 0a4283ed9aa7..63e0bbdcddcc 100644 --- a/virt/kvm/arm/vgic/vgic-mmio-v2.c +++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c | |||
@@ -226,7 +226,13 @@ static unsigned long vgic_mmio_read_vcpuif(struct kvm_vcpu *vcpu, | |||
226 | 226 | ||
227 | switch (addr & 0xff) { | 227 | switch (addr & 0xff) { |
228 | case GIC_CPU_CTRL: | 228 | case GIC_CPU_CTRL: |
229 | val = vmcr.ctlr; | 229 | val = vmcr.grpen0 << GIC_CPU_CTRL_EnableGrp0_SHIFT; |
230 | val |= vmcr.grpen1 << GIC_CPU_CTRL_EnableGrp1_SHIFT; | ||
231 | val |= vmcr.ackctl << GIC_CPU_CTRL_AckCtl_SHIFT; | ||
232 | val |= vmcr.fiqen << GIC_CPU_CTRL_FIQEn_SHIFT; | ||
233 | val |= vmcr.cbpr << GIC_CPU_CTRL_CBPR_SHIFT; | ||
234 | val |= vmcr.eoim << GIC_CPU_CTRL_EOImodeNS_SHIFT; | ||
235 | |||
230 | break; | 236 | break; |
231 | case GIC_CPU_PRIMASK: | 237 | case GIC_CPU_PRIMASK: |
232 | /* | 238 | /* |
@@ -267,7 +273,13 @@ static void vgic_mmio_write_vcpuif(struct kvm_vcpu *vcpu, | |||
267 | 273 | ||
268 | switch (addr & 0xff) { | 274 | switch (addr & 0xff) { |
269 | case GIC_CPU_CTRL: | 275 | case GIC_CPU_CTRL: |
270 | vmcr.ctlr = val; | 276 | vmcr.grpen0 = !!(val & GIC_CPU_CTRL_EnableGrp0); |
277 | vmcr.grpen1 = !!(val & GIC_CPU_CTRL_EnableGrp1); | ||
278 | vmcr.ackctl = !!(val & GIC_CPU_CTRL_AckCtl); | ||
279 | vmcr.fiqen = !!(val & GIC_CPU_CTRL_FIQEn); | ||
280 | vmcr.cbpr = !!(val & GIC_CPU_CTRL_CBPR); | ||
281 | vmcr.eoim = !!(val & GIC_CPU_CTRL_EOImodeNS); | ||
282 | |||
271 | break; | 283 | break; |
272 | case GIC_CPU_PRIMASK: | 284 | case GIC_CPU_PRIMASK: |
273 | /* | 285 | /* |
diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c index 504b4bd0d651..e4187e52bb26 100644 --- a/virt/kvm/arm/vgic/vgic-v2.c +++ b/virt/kvm/arm/vgic/vgic-v2.c | |||
@@ -177,7 +177,18 @@ void vgic_v2_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) | |||
177 | struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; | 177 | struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; |
178 | u32 vmcr; | 178 | u32 vmcr; |
179 | 179 | ||
180 | vmcr = (vmcrp->ctlr << GICH_VMCR_CTRL_SHIFT) & GICH_VMCR_CTRL_MASK; | 180 | vmcr = (vmcrp->grpen0 << GICH_VMCR_ENABLE_GRP0_SHIFT) & |
181 | GICH_VMCR_ENABLE_GRP0_MASK; | ||
182 | vmcr |= (vmcrp->grpen1 << GICH_VMCR_ENABLE_GRP1_SHIFT) & | ||
183 | GICH_VMCR_ENABLE_GRP1_MASK; | ||
184 | vmcr |= (vmcrp->ackctl << GICH_VMCR_ACK_CTL_SHIFT) & | ||
185 | GICH_VMCR_ACK_CTL_MASK; | ||
186 | vmcr |= (vmcrp->fiqen << GICH_VMCR_FIQ_EN_SHIFT) & | ||
187 | GICH_VMCR_FIQ_EN_MASK; | ||
188 | vmcr |= (vmcrp->cbpr << GICH_VMCR_CBPR_SHIFT) & | ||
189 | GICH_VMCR_CBPR_MASK; | ||
190 | vmcr |= (vmcrp->eoim << GICH_VMCR_EOI_MODE_SHIFT) & | ||
191 | GICH_VMCR_EOI_MODE_MASK; | ||
181 | vmcr |= (vmcrp->abpr << GICH_VMCR_ALIAS_BINPOINT_SHIFT) & | 192 | vmcr |= (vmcrp->abpr << GICH_VMCR_ALIAS_BINPOINT_SHIFT) & |
182 | GICH_VMCR_ALIAS_BINPOINT_MASK; | 193 | GICH_VMCR_ALIAS_BINPOINT_MASK; |
183 | vmcr |= (vmcrp->bpr << GICH_VMCR_BINPOINT_SHIFT) & | 194 | vmcr |= (vmcrp->bpr << GICH_VMCR_BINPOINT_SHIFT) & |
@@ -195,8 +206,19 @@ void vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) | |||
195 | 206 | ||
196 | vmcr = cpu_if->vgic_vmcr; | 207 | vmcr = cpu_if->vgic_vmcr; |
197 | 208 | ||
198 | vmcrp->ctlr = (vmcr & GICH_VMCR_CTRL_MASK) >> | 209 | vmcrp->grpen0 = (vmcr & GICH_VMCR_ENABLE_GRP0_MASK) >> |
199 | GICH_VMCR_CTRL_SHIFT; | 210 | GICH_VMCR_ENABLE_GRP0_SHIFT; |
211 | vmcrp->grpen1 = (vmcr & GICH_VMCR_ENABLE_GRP1_MASK) >> | ||
212 | GICH_VMCR_ENABLE_GRP1_SHIFT; | ||
213 | vmcrp->ackctl = (vmcr & GICH_VMCR_ACK_CTL_MASK) >> | ||
214 | GICH_VMCR_ACK_CTL_SHIFT; | ||
215 | vmcrp->fiqen = (vmcr & GICH_VMCR_FIQ_EN_MASK) >> | ||
216 | GICH_VMCR_FIQ_EN_SHIFT; | ||
217 | vmcrp->cbpr = (vmcr & GICH_VMCR_CBPR_MASK) >> | ||
218 | GICH_VMCR_CBPR_SHIFT; | ||
219 | vmcrp->eoim = (vmcr & GICH_VMCR_EOI_MODE_MASK) >> | ||
220 | GICH_VMCR_EOI_MODE_SHIFT; | ||
221 | |||
200 | vmcrp->abpr = (vmcr & GICH_VMCR_ALIAS_BINPOINT_MASK) >> | 222 | vmcrp->abpr = (vmcr & GICH_VMCR_ALIAS_BINPOINT_MASK) >> |
201 | GICH_VMCR_ALIAS_BINPOINT_SHIFT; | 223 | GICH_VMCR_ALIAS_BINPOINT_SHIFT; |
202 | vmcrp->bpr = (vmcr & GICH_VMCR_BINPOINT_MASK) >> | 224 | vmcrp->bpr = (vmcr & GICH_VMCR_BINPOINT_MASK) >> |
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c index 6fe3f003636a..030248e669f6 100644 --- a/virt/kvm/arm/vgic/vgic-v3.c +++ b/virt/kvm/arm/vgic/vgic-v3.c | |||
@@ -159,15 +159,24 @@ void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr) | |||
159 | void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) | 159 | void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) |
160 | { | 160 | { |
161 | struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; | 161 | struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; |
162 | u32 model = vcpu->kvm->arch.vgic.vgic_model; | ||
162 | u32 vmcr; | 163 | u32 vmcr; |
163 | 164 | ||
164 | /* | 165 | if (model == KVM_DEV_TYPE_ARM_VGIC_V2) { |
165 | * Ignore the FIQen bit, because GIC emulation always implies | 166 | vmcr = (vmcrp->ackctl << ICH_VMCR_ACK_CTL_SHIFT) & |
166 | * SRE=1 which means the vFIQEn bit is also RES1. | 167 | ICH_VMCR_ACK_CTL_MASK; |
167 | */ | 168 | vmcr |= (vmcrp->fiqen << ICH_VMCR_FIQ_EN_SHIFT) & |
168 | vmcr = ((vmcrp->ctlr >> ICC_CTLR_EL1_EOImode_SHIFT) << | 169 | ICH_VMCR_FIQ_EN_MASK; |
169 | ICH_VMCR_EOIM_SHIFT) & ICH_VMCR_EOIM_MASK; | 170 | } else { |
170 | vmcr |= (vmcrp->ctlr << ICH_VMCR_CBPR_SHIFT) & ICH_VMCR_CBPR_MASK; | 171 | /* |
172 | * When emulating GICv3 on GICv3 with SRE=1 on the | ||
173 | * VFIQEn bit is RES1 and the VAckCtl bit is RES0. | ||
174 | */ | ||
175 | vmcr = ICH_VMCR_FIQ_EN_MASK; | ||
176 | } | ||
177 | |||
178 | vmcr |= (vmcrp->cbpr << ICH_VMCR_CBPR_SHIFT) & ICH_VMCR_CBPR_MASK; | ||
179 | vmcr |= (vmcrp->eoim << ICH_VMCR_EOIM_SHIFT) & ICH_VMCR_EOIM_MASK; | ||
171 | vmcr |= (vmcrp->abpr << ICH_VMCR_BPR1_SHIFT) & ICH_VMCR_BPR1_MASK; | 180 | vmcr |= (vmcrp->abpr << ICH_VMCR_BPR1_SHIFT) & ICH_VMCR_BPR1_MASK; |
172 | vmcr |= (vmcrp->bpr << ICH_VMCR_BPR0_SHIFT) & ICH_VMCR_BPR0_MASK; | 181 | vmcr |= (vmcrp->bpr << ICH_VMCR_BPR0_SHIFT) & ICH_VMCR_BPR0_MASK; |
173 | vmcr |= (vmcrp->pmr << ICH_VMCR_PMR_SHIFT) & ICH_VMCR_PMR_MASK; | 182 | vmcr |= (vmcrp->pmr << ICH_VMCR_PMR_SHIFT) & ICH_VMCR_PMR_MASK; |
@@ -180,17 +189,27 @@ void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) | |||
180 | void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) | 189 | void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) |
181 | { | 190 | { |
182 | struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; | 191 | struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; |
192 | u32 model = vcpu->kvm->arch.vgic.vgic_model; | ||
183 | u32 vmcr; | 193 | u32 vmcr; |
184 | 194 | ||
185 | vmcr = cpu_if->vgic_vmcr; | 195 | vmcr = cpu_if->vgic_vmcr; |
186 | 196 | ||
187 | /* | 197 | if (model == KVM_DEV_TYPE_ARM_VGIC_V2) { |
188 | * Ignore the FIQen bit, because GIC emulation always implies | 198 | vmcrp->ackctl = (vmcr & ICH_VMCR_ACK_CTL_MASK) >> |
189 | * SRE=1 which means the vFIQEn bit is also RES1. | 199 | ICH_VMCR_ACK_CTL_SHIFT; |
190 | */ | 200 | vmcrp->fiqen = (vmcr & ICH_VMCR_FIQ_EN_MASK) >> |
191 | vmcrp->ctlr = ((vmcr >> ICH_VMCR_EOIM_SHIFT) << | 201 | ICH_VMCR_FIQ_EN_SHIFT; |
192 | ICC_CTLR_EL1_EOImode_SHIFT) & ICC_CTLR_EL1_EOImode_MASK; | 202 | } else { |
193 | vmcrp->ctlr |= (vmcr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT; | 203 | /* |
204 | * When emulating GICv3 on GICv3 with SRE=1 on the | ||
205 | * VFIQEn bit is RES1 and the VAckCtl bit is RES0. | ||
206 | */ | ||
207 | vmcrp->fiqen = 1; | ||
208 | vmcrp->ackctl = 0; | ||
209 | } | ||
210 | |||
211 | vmcrp->cbpr = (vmcr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT; | ||
212 | vmcrp->eoim = (vmcr & ICH_VMCR_EOIM_MASK) >> ICH_VMCR_EOIM_SHIFT; | ||
194 | vmcrp->abpr = (vmcr & ICH_VMCR_BPR1_MASK) >> ICH_VMCR_BPR1_SHIFT; | 213 | vmcrp->abpr = (vmcr & ICH_VMCR_BPR1_MASK) >> ICH_VMCR_BPR1_SHIFT; |
195 | vmcrp->bpr = (vmcr & ICH_VMCR_BPR0_MASK) >> ICH_VMCR_BPR0_SHIFT; | 214 | vmcrp->bpr = (vmcr & ICH_VMCR_BPR0_MASK) >> ICH_VMCR_BPR0_SHIFT; |
196 | vmcrp->pmr = (vmcr & ICH_VMCR_PMR_MASK) >> ICH_VMCR_PMR_SHIFT; | 215 | vmcrp->pmr = (vmcr & ICH_VMCR_PMR_MASK) >> ICH_VMCR_PMR_SHIFT; |
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h index da83e4caa272..bba7fa22a7f7 100644 --- a/virt/kvm/arm/vgic/vgic.h +++ b/virt/kvm/arm/vgic/vgic.h | |||
@@ -111,14 +111,18 @@ static inline bool irq_is_pending(struct vgic_irq *irq) | |||
111 | * registers regardless of the hardware backed GIC used. | 111 | * registers regardless of the hardware backed GIC used. |
112 | */ | 112 | */ |
113 | struct vgic_vmcr { | 113 | struct vgic_vmcr { |
114 | u32 ctlr; | 114 | u32 grpen0; |
115 | u32 grpen1; | ||
116 | |||
117 | u32 ackctl; | ||
118 | u32 fiqen; | ||
119 | u32 cbpr; | ||
120 | u32 eoim; | ||
121 | |||
115 | u32 abpr; | 122 | u32 abpr; |
116 | u32 bpr; | 123 | u32 bpr; |
117 | u32 pmr; /* Priority mask field in the GICC_PMR and | 124 | u32 pmr; /* Priority mask field in the GICC_PMR and |
118 | * ICC_PMR_EL1 priority field format */ | 125 | * ICC_PMR_EL1 priority field format */ |
119 | /* Below member variable are valid only for GICv3 */ | ||
120 | u32 grpen0; | ||
121 | u32 grpen1; | ||
122 | }; | 126 | }; |
123 | 127 | ||
124 | struct vgic_reg_attr { | 128 | struct vgic_reg_attr { |