summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Zyngier <maz@kernel.org>2021-02-28 14:09:59 +0300
committerMarc Zyngier <maz@kernel.org>2021-06-01 12:45:59 +0300
commit669062d2a1aa36661b490683fe17810aa24a9cfb (patch)
tree88e24c9b60a2ab6890ed296fe012faba2a0f33bd
parent74501499d4e0d4ba59ab2bc6be1873716549169d (diff)
downloadlinux-669062d2a1aa36661b490683fe17810aa24a9cfb.tar.xz
KVM: arm64: vgic: Be tolerant to the lack of maintenance interrupt masking
As it turns out, not all the interrupt controllers are able to expose a vGIC maintenance interrupt that can be independently enabled/disabled. And to be fair, it doesn't really matter as all we require is for the interrupt to kick us out of guest mode out way or another. To that effect, add gic_kvm_info.no_maint_irq_mask for an interrupt controller to advertise the lack of masking. Signed-off-by: Marc Zyngier <maz@kernel.org>
-rw-r--r--arch/arm64/kvm/vgic/vgic-init.c8
-rw-r--r--include/linux/irqchip/arm-vgic-info.h2
2 files changed, 9 insertions, 1 deletions
diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index 2fdb65529594..6752d084934d 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -519,12 +519,15 @@ void kvm_vgic_init_cpu_hardware(void)
*/
int kvm_vgic_hyp_init(void)
{
+ bool has_mask;
int ret;
if (!gic_kvm_info)
return -ENODEV;
- if (!gic_kvm_info->maint_irq) {
+ has_mask = !gic_kvm_info->no_maint_irq_mask;
+
+ if (has_mask && !gic_kvm_info->maint_irq) {
kvm_err("No vgic maintenance irq\n");
return -ENXIO;
}
@@ -552,6 +555,9 @@ int kvm_vgic_hyp_init(void)
if (ret)
return ret;
+ if (!has_mask)
+ return 0;
+
ret = request_percpu_irq(kvm_vgic_global_state.maint_irq,
vgic_maintenance_handler,
"vgic", kvm_get_running_vcpus());
diff --git a/include/linux/irqchip/arm-vgic-info.h b/include/linux/irqchip/arm-vgic-info.h
index a25d4da5697d..7c0d08ebb82c 100644
--- a/include/linux/irqchip/arm-vgic-info.h
+++ b/include/linux/irqchip/arm-vgic-info.h
@@ -24,6 +24,8 @@ struct gic_kvm_info {
struct resource vcpu;
/* Interrupt number */
unsigned int maint_irq;
+ /* No interrupt mask, no need to use the above field */
+ bool no_maint_irq_mask;
/* Virtual control interface */
struct resource vctrl;
/* vlpi support */