summaryrefslogtreecommitdiff
path: root/virt/kvm/arm/hyp
diff options
context:
space:
mode:
authorChristoffer Dall <cdall@cs.columbia.edu>2016-03-24 11:21:04 +0100
committerChristoffer Dall <cdall@linaro.org>2017-04-09 07:45:22 -0700
commit328e566479449194979d64685ae6d74c989599bb (patch)
treed8812bef5ccfa0aab49c3af64be5ba495682c76d /virt/kvm/arm/hyp
parent056aad67f836e20568be9b7ca07703a8dea26e0c (diff)
KVM: arm/arm64: vgic: Defer touching GICH_VMCR to vcpu_load/put
We don't have to save/restore the VMCR on every entry to/from the guest, since on GICv2 we can access the control interface from EL1 and on VHE systems with GICv3 we can access the control interface from KVM running in EL2. GICv3 systems without VHE becomes the rare case, which has to save/restore the register on each round trip. Note that userspace accesses may see out-of-date values if the VCPU is running while accessing the VGIC state via the KVM device API, but this is already the case and it is up to userspace to quiesce the CPUs before reading the CPU registers from the GIC for an up-to-date view. Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu> Signed-off-by: Christoffer Dall <cdall@linaro.org>
Diffstat (limited to 'virt/kvm/arm/hyp')
-rw-r--r--virt/kvm/arm/hyp/vgic-v2-sr.c3
-rw-r--r--virt/kvm/arm/hyp/vgic-v3-sr.c14
2 files changed, 10 insertions, 7 deletions
diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c
index c8aeb7b91ec8..d3d3b9b0c2c3 100644
--- a/virt/kvm/arm/hyp/vgic-v2-sr.c
+++ b/virt/kvm/arm/hyp/vgic-v2-sr.c
@@ -114,8 +114,6 @@ void __hyp_text __vgic_v2_save_state(struct kvm_vcpu *vcpu)
if (!base)
return;
- cpu_if->vgic_vmcr = readl_relaxed(base + GICH_VMCR);
-
if (vcpu->arch.vgic_cpu.live_lrs) {
cpu_if->vgic_apr = readl_relaxed(base + GICH_APR);
@@ -165,7 +163,6 @@ void __hyp_text __vgic_v2_restore_state(struct kvm_vcpu *vcpu)
}
}
- writel_relaxed(cpu_if->vgic_vmcr, base + GICH_VMCR);
vcpu->arch.vgic_cpu.live_lrs = live_lrs;
}
diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
index 3947095cc0a1..e51ee7edf953 100644
--- a/virt/kvm/arm/hyp/vgic-v3-sr.c
+++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
@@ -159,8 +159,6 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
if (!cpu_if->vgic_sre)
dsb(st);
- cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2);
-
if (vcpu->arch.vgic_cpu.live_lrs) {
int i;
u32 max_lr_idx, nr_pri_bits;
@@ -261,8 +259,6 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
live_lrs |= (1 << i);
}
- write_gicreg(cpu_if->vgic_vmcr, ICH_VMCR_EL2);
-
if (live_lrs) {
write_gicreg(cpu_if->vgic_hcr, ICH_HCR_EL2);
@@ -326,3 +322,13 @@ u64 __hyp_text __vgic_v3_get_ich_vtr_el2(void)
{
return read_gicreg(ICH_VTR_EL2);
}
+
+u64 __hyp_text __vgic_v3_read_vmcr(void)
+{
+ return read_gicreg(ICH_VMCR_EL2);
+}
+
+void __hyp_text __vgic_v3_write_vmcr(u32 vmcr)
+{
+ write_gicreg(vmcr, ICH_VMCR_EL2);
+}