summaryrefslogtreecommitdiffstats
path: root/virt/kvm/arm
diff options
context:
space:
mode:
authorMarc Zyngier2017-10-27 16:28:53 +0200
committerChristoffer Dall2017-11-10 09:45:02 +0100
commitd3d83f7fef9dfa8bf5a279497dcaa3dd690bce2f (patch)
treec13c5b6350df78d55e2f663cd7b8c5f6b0c1c053 /virt/kvm/arm
parentKVM: arm/arm64: GICv4: Prevent a VM using GICv4 from being saved (diff)
downloadkernel-qcow2-linux-d3d83f7fef9dfa8bf5a279497dcaa3dd690bce2f.tar.gz
kernel-qcow2-linux-d3d83f7fef9dfa8bf5a279497dcaa3dd690bce2f.tar.xz
kernel-qcow2-linux-d3d83f7fef9dfa8bf5a279497dcaa3dd690bce2f.zip
KVM: arm/arm64: GICv4: Prevent userspace from changing doorbell affinity
We so far allocate the doorbell interrupts without taking any special measure regarding the affinity of these interrupts. We simply move them around as required when the vcpu gets scheduled on a different CPU. But that's counting without userspace (and the evil irqbalance) that can try and move the VPE interrupt around, causing the ITS code to emit VMOVP commands and remap the doorbell to another redistributor. Worse, this can happen while the vcpu is running, causing all kind of trouble if the VPE is already resident, and we end-up in UNPRED territory. So let's take a definitive action and prevent userspace from messing with us. This is just a matter of adding IRQ_NO_BALANCING to the set of flags we already have, letting the kernel in sole control of the affinity. Acked-by: Christoffer Dall <christoffer.dall@linaro.org> Reviewed-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'virt/kvm/arm')
-rw-r--r--virt/kvm/arm/vgic/vgic-v4.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
index c9cec01008c2..bf874dd01fc0 100644
--- a/virt/kvm/arm/vgic/vgic-v4.c
+++ b/virt/kvm/arm/vgic/vgic-v4.c
@@ -23,6 +23,8 @@
#include "vgic.h"
+#define DB_IRQ_FLAGS (IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY | IRQ_NO_BALANCING)
+
static irqreturn_t vgic_v4_doorbell_handler(int irq, void *info)
{
struct kvm_vcpu *vcpu = info;
@@ -83,7 +85,7 @@ int vgic_v4_init(struct kvm *kvm)
* doorbell could kick us out of the guest too
* early...
*/
- irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY);
+ irq_set_status_flags(irq, DB_IRQ_FLAGS);
ret = request_irq(irq, vgic_v4_doorbell_handler,
0, "vcpu", vcpu);
if (ret) {
@@ -121,7 +123,7 @@ void vgic_v4_teardown(struct kvm *kvm)
struct kvm_vcpu *vcpu = kvm_get_vcpu(kvm, i);
int irq = its_vm->vpes[i]->irq;
- irq_clear_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY);
+ irq_clear_status_flags(irq, DB_IRQ_FLAGS);
free_irq(irq, vcpu);
}