aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2016-09-06 09:02:17 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2016-09-08 06:53:00 -0400
commit3272f0d08e4490b792b99cf6034a2bb859bf6c9f (patch)
treefeeacabe06da56fb71a94adce04293bd0a8d18ca /virt
parent21977a4c57cd92c71113e21319302b5a399f9d2d (diff)
arm64: KVM: Inject a vSerror if detecting a bad GICV access at EL2
If, when proxying a GICV access at EL2, we detect that the guest is doing something silly, report an EL1 SError instead ofgnoring the access. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/hyp/vgic-v2-sr.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c
index a052f2056cc0..c8aeb7b91ec8 100644
--- a/virt/kvm/arm/hyp/vgic-v2-sr.c
+++ b/virt/kvm/arm/hyp/vgic-v2-sr.c
@@ -170,7 +170,18 @@ void __hyp_text __vgic_v2_restore_state(struct kvm_vcpu *vcpu)
170} 170}
171 171
172#ifdef CONFIG_ARM64 172#ifdef CONFIG_ARM64
173bool __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu) 173/*
174 * __vgic_v2_perform_cpuif_access -- perform a GICV access on behalf of the
175 * guest.
176 *
177 * @vcpu: the offending vcpu
178 *
179 * Returns:
180 * 1: GICV access successfully performed
181 * 0: Not a GICV access
182 * -1: Illegal GICV access
183 */
184int __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu)
174{ 185{
175 struct kvm *kvm = kern_hyp_va(vcpu->kvm); 186 struct kvm *kvm = kern_hyp_va(vcpu->kvm);
176 struct vgic_dist *vgic = &kvm->arch.vgic; 187 struct vgic_dist *vgic = &kvm->arch.vgic;
@@ -185,15 +196,15 @@ bool __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu)
185 /* If not for GICV, move on */ 196 /* If not for GICV, move on */
186 if (fault_ipa < vgic->vgic_cpu_base || 197 if (fault_ipa < vgic->vgic_cpu_base ||
187 fault_ipa >= (vgic->vgic_cpu_base + KVM_VGIC_V2_CPU_SIZE)) 198 fault_ipa >= (vgic->vgic_cpu_base + KVM_VGIC_V2_CPU_SIZE))
188 return false; 199 return 0;
189 200
190 /* Reject anything but a 32bit access */ 201 /* Reject anything but a 32bit access */
191 if (kvm_vcpu_dabt_get_as(vcpu) != sizeof(u32)) 202 if (kvm_vcpu_dabt_get_as(vcpu) != sizeof(u32))
192 return false; 203 return -1;
193 204
194 /* Not aligned? Don't bother */ 205 /* Not aligned? Don't bother */
195 if (fault_ipa & 3) 206 if (fault_ipa & 3)
196 return false; 207 return -1;
197 208
198 rd = kvm_vcpu_dabt_get_rd(vcpu); 209 rd = kvm_vcpu_dabt_get_rd(vcpu);
199 addr = kern_hyp_va((kern_hyp_va(&kvm_vgic_global_state))->vcpu_base_va); 210 addr = kern_hyp_va((kern_hyp_va(&kvm_vgic_global_state))->vcpu_base_va);
@@ -210,6 +221,6 @@ bool __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu)
210 sizeof(u32))); 221 sizeof(u32)));
211 } 222 }
212 223
213 return true; 224 return 1;
214} 225}
215#endif 226#endif