| From caf1ff26e1aa178133df68ac3d40815fed2187d9 Mon Sep 17 00:00:00 2001 |
| From: Xiubo Li <lixiubo@cmss.chinamobile.com> |
| Date: Wed, 15 Jun 2016 18:00:33 +0800 |
| Subject: kvm: Fix irq route entries exceeding KVM_MAX_IRQ_ROUTES |
| |
| From: Xiubo Li <lixiubo@cmss.chinamobile.com> |
| |
| commit caf1ff26e1aa178133df68ac3d40815fed2187d9 upstream. |
| |
| These days, we experienced one guest crash with 8 cores and 3 disks, |
| with qemu error logs as bellow: |
| |
| qemu-system-x86_64: /build/qemu-2.0.0/kvm-all.c:984: |
| kvm_irqchip_commit_routes: Assertion `ret == 0' failed. |
| |
| And then we found one patch(bdf026317d) in qemu tree, which said |
| could fix this bug. |
| |
| Execute the following script will reproduce the BUG quickly: |
| |
| irq_affinity.sh |
| ======================================================================== |
| |
| vda_irq_num=25 |
| vdb_irq_num=27 |
| while [ 1 ] |
| do |
| for irq in {1,2,4,8,10,20,40,80} |
| do |
| echo $irq > /proc/irq/$vda_irq_num/smp_affinity |
| echo $irq > /proc/irq/$vdb_irq_num/smp_affinity |
| dd if=/dev/vda of=/dev/zero bs=4K count=100 iflag=direct |
| dd if=/dev/vdb of=/dev/zero bs=4K count=100 iflag=direct |
| done |
| done |
| ======================================================================== |
| |
| The following qemu log is added in the qemu code and is displayed when |
| this bug reproduced: |
| |
| kvm_irqchip_commit_routes: max gsi: 1008, nr_allocated_irq_routes: 1024, |
| irq_routes->nr: 1024, gsi_count: 1024. |
| |
| That's to say when irq_routes->nr == 1024, there are 1024 routing entries, |
| but in the kernel code when routes->nr >= 1024, will just return -EINVAL; |
| |
| The nr is the number of the routing entries which is in of |
| [1 ~ KVM_MAX_IRQ_ROUTES], not the index in [0 ~ KVM_MAX_IRQ_ROUTES - 1]. |
| |
| This patch fix the BUG above. |
| |
| Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com> |
| Signed-off-by: Wei Tang <tangwei@cmss.chinamobile.com> |
| Signed-off-by: Zhang Zhuoyu <zhangzhuoyu@cmss.chinamobile.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| virt/kvm/kvm_main.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/virt/kvm/kvm_main.c |
| +++ b/virt/kvm/kvm_main.c |
| @@ -2861,7 +2861,7 @@ static long kvm_vm_ioctl(struct file *fi |
| if (copy_from_user(&routing, argp, sizeof(routing))) |
| goto out; |
| r = -EINVAL; |
| - if (routing.nr >= KVM_MAX_IRQ_ROUTES) |
| + if (routing.nr > KVM_MAX_IRQ_ROUTES) |
| goto out; |
| if (routing.flags) |
| goto out; |