aboutsummaryrefslogtreecommitdiff
path: root/virt
diff options
context:
space:
mode:
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/arch_timer.c15
-rw-r--r--virt/kvm/arm/vgic/vgic-v3.c9
2 files changed, 19 insertions, 5 deletions
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 5976609ef27c..43159a238746 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -69,15 +69,17 @@ static void timer_disarm(struct arch_timer_cpu *timer)
static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
{
- struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)dev_id;
/*
+ struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)dev_id;
+
* We disable the timer in the world switch and let it be
* handled by kvm_timer_sync_hwstate(). Getting a timer
* interrupt at this point is a sure sign of some major
* breakage.
- */
pr_warn("Unexpected interrupt %d on vcpu %p\n", irq, vcpu);
+
+ */
return IRQ_HANDLED;
}
@@ -650,10 +652,13 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
/*
* Tell the VGIC that the virtual interrupt is tied to a
* physical interrupt. We do that once per VCPU.
+ * HiSilicon quirk: virtual timer irq map not supported.
*/
- ret = kvm_vgic_map_phys_irq(vcpu, vtimer->irq.irq, phys_irq);
- if (ret)
- return ret;
+ if (!needs_hisi_vtimer_quirk()) {
+ ret = kvm_vgic_map_phys_irq(vcpu, vtimer->irq.irq, phys_irq);
+ if (ret)
+ return ret;
+ }
no_vgic:
timer->enabled = 1;
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index 6fe3f003636a..bc4f7cc6fd05 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -21,6 +21,9 @@
#include "vgic.h"
+DEFINE_STATIC_KEY_FALSE(hisi_vtimer_quirk_enabled);
+EXPORT_SYMBOL_GPL(hisi_vtimer_quirk_enabled);
+
void vgic_v3_set_underflow(struct kvm_vcpu *vcpu)
{
struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3;
@@ -429,6 +432,12 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
kvm_vgic_global_state.can_emulate_gicv2 = false;
kvm_vgic_global_state.ich_vtr_el2 = ich_vtr_el2;
+ /* HiSilicon Quirk: virt timer irqmap not supported */
+ if (info->hisi_vtimer_quirk) {
+ static_branch_enable(&hisi_vtimer_quirk_enabled);
+ pr_info("kvm: Enabling HiSilicon GIC virt timer quirk\n");
+ }
+
if (!info->vcpu.start) {
kvm_info("GICv3: no GICV resource entry\n");
kvm_vgic_global_state.vcpu_base = 0;