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>
This commit is contained in:
Родитель
bd94e7aea4
Коммит
d3d83f7fef
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
#include "vgic.h"
|
#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)
|
static irqreturn_t vgic_v4_doorbell_handler(int irq, void *info)
|
||||||
{
|
{
|
||||||
struct kvm_vcpu *vcpu = 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
|
* doorbell could kick us out of the guest too
|
||||||
* early...
|
* 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,
|
ret = request_irq(irq, vgic_v4_doorbell_handler,
|
||||||
0, "vcpu", vcpu);
|
0, "vcpu", vcpu);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -121,7 +123,7 @@ void vgic_v4_teardown(struct kvm *kvm)
|
||||||
struct kvm_vcpu *vcpu = kvm_get_vcpu(kvm, i);
|
struct kvm_vcpu *vcpu = kvm_get_vcpu(kvm, i);
|
||||||
int irq = its_vm->vpes[i]->irq;
|
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);
|
free_irq(irq, vcpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче