Note: This bug is displayed in read-only format because the product is no longer active in Red Hat Bugzilla.
RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.

Bug 1520352

Summary: [virtio-serial] Virtqueue corruption on vCPU hot-plug
Product: Red Hat Enterprise Linux 7 Reporter: Ladi Prosek <lprosek>
Component: virtio-winAssignee: Amnon Ilan <ailan>
virtio-win sub component: virtio-win-prewhql QA Contact: lijin <lijin>
Status: CLOSED ERRATA Docs Contact:
Severity: unspecified    
Priority: unspecified CC: ailan, ddepaula, jherrman, juzhang, lijin, lmiksik, michen, phou, xiagao
Version: 7.5   
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
When performing a vCPU hot plug on Windows guest virtual machines, the QEMU emulator in some cases terminated unexpectedly. This update fixes a race condition in the virtqueue, which prevents the described problem from occurring.
Story Points: ---
Clone Of: Environment:
Last Closed: 2018-04-10 06:33:41 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Ladi Prosek 2017-12-04 10:47:37 UTC
Description of problem:
Reported by @zyb521 at https://github.com/virtio-win/kvm-guest-drivers-windows/issues/195

"We found that in Windows server 2016, after the hot plug vcpu,qemu process directly exit some times, I'm not sure if it affects other Windows systems."

Version-Release number of selected component (if applicable):
Windows Server 2016 Datacenter
virtio-win 141

How reproducible:
~80% for me with the steps below


Steps to Reproduce:
1. Run QEMU with:

  -chardev socket,host=localhost,port=4467,server,nowait,id=ser \
  -device virtserialport,chardev=ser,name=port1 \

and at least 3G of RAM.

2. Make sure the socket is stuffed with data:
$ nc localhost 4467 </dev/zero

3. Then in the Windows VM simply open the port:

  C:\>copy con \\.\port1
  hello<enter>
And hot-add CPUs:

  (qemu) cpu-add 2
  (qemu) cpu-add 3
  ...


Actual results:
QEMU crashes with either "Looped descriptor" or "Guest moved used index from ... to ..."

Expected results:
QEMU doesn't crash

Comment 2 Ladi Prosek 2017-12-04 10:48:50 UTC
Here's what happening. VIOSerialPortEvtDeviceD0Exit disables interrupts on the read queue but it doesn't stop it. The host side is still sending data. This causes VIOSerialDiscardPortDataLocked, called from VIOSerialPortEvtDeviceD0Exit, to loop extensively and potentially indefinitely. As long as the device has data to send, the loop runs, re-queuing the returned buffers.

Then, when VIOSerialDiscardPortDataLocked convinces itself that it's processed everything, VIOSerialPortEvtDeviceD0Exit proceeds to call VIOSerialDrainQueue which uses virtqueue_detach_unused_buf to essentially un-push already pushed buffers to the queue. Obviously this must not be done on a live queue. The driver is racing here with the device which is still trying to fill buffers and return them to the driver. This is where the QEMU asserts fire.

Comment 5 Peixiu Hou 2017-12-05 07:40:23 UTC
Hi Ladi,

I try to reproduce this bug as comment#0 steps, but didn't reproduce it. Could you help to check my test steps?

Test Steps:
================================================================================
1. boot a guest with cli and install a new win2016 guest:
/usr/libexec/qemu-kvm \
-name win2016 \
-enable-kvm -machine pc,accel=kvm -m 4G -smp 2,maxcpus=8,sockets=8,cores=1,threads=1 -cpu host,hv_time,+kvm_pv_eoi,hv_relaxed,hv_vapic,hv_spinlocks=0x1fff -uuid ea78071a-f6e4-4347-8077-9cb9f7953a84 \
-nodefconfig --nodefaults -boot order=cd,menu=on \
-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=isa_serial0 -device usb-tablet,id=input0 \
-drive file=win2016.raw,if=none,id=drive-ide0-0-1,format=raw,serial=mike_cao,cache=none -device ide-drive,bus=ide.0,unit=1,drive=drive-ide0-0-1,id=ide0-0-1 \
-drive file=/home/images/en_windows_server_2016_x64_dvd_9718492.iso,media=cdrom,id=cdrom,if=none -device ide-drive,drive=cdrom,bootindex=1 \
-netdev tap,id=hostnet0,vhost=on,vhostforce=off \
-device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:83:66:77:88:66,bus=pci.0,addr=0x3,status=on \
-vnc 0.0.0.0:1 -vga std -monitor stdio -qmp tcp:0:4446,server,nowait \
-cdrom /home/virtio-win-prewhql-141.iso \
-device virtio-serial-pci,id=virtio-serial0,max_ports=511 \
-chardev socket,host=localhost,port=4467,server,nowait,id=ser \
-device virtserialport,chardev=ser,name=port1 \

2. Install the virtio-win-prewhql-141 vioser driver.

3. In host:
$ nc localhost 4467 </dev/zero

4. in the Windows VM simply open the port:

  C:\>copy con \\.\port1
  hello<enter>

5. hot-add CPUs:
  (qemu) cpu-add 2
  (qemu) cpu-add 3
  (qemu) cpu-add 4
  (qemu) cpu-add 5
  (qemu) cpu-add 6
  (qemu) cpu-add 7
6. checked the qemu info, no qemu crash
================================================================================

I also tried to test with follow matrix:
1. qemu-kvm-rhev-2.10.0-8.el7  + virtio-win-prewhql-141, not reproduced(tried about 5 times).
2. qemu-kvm-rhev-2.10.0-8.el7  + virtio-win-prewhql-145, not reproduced(tried 1 1 time).
3. qemu-kvm-rhev-2.6.0-29.el7  + virtio-win-prewhql-141, not reproduced(tried about 5 times).
4. qemu-kvm-rhev-2.6.0-29.el7  + virtio-win-prewhql-145, not reproduced(tried 1 time).

Other versions:
kernel-3.10.0-798.el7.x86_64
seabios-1.10.2-5.el7.x86_64


Thanks a lot~
Peixiu

Comment 6 Ladi Prosek 2017-12-05 07:50:20 UTC
Hi Peixiu Hou,

(In reply to Peixiu Hou from comment #5)
> 4. in the Windows VM simply open the port:
> 
>   C:\>copy con \\.\port1
>   hello<enter>

What I meant here is typing hello, or any arbitrary string, and pressing Enter. Without Enter the copy command won't actually open the port the way we want.

If you did press Enter and still couldn't reproduce it, can you please give me access to the repro host?

Thank you!
Ladi

Comment 7 Ladi Prosek 2017-12-05 07:54:11 UTC
Also, do you see the added CPUs in the guest? In Device Manager or even in Task Manager. Every time you do cpu-add, a new CPU should appear.

If not, you'll have to apply the workaround from https://bugzilla.redhat.com/show_bug.cgi?id=1377155#c12

I should have mentioned it before, sorry about that.

Comment 9 Ladi Prosek 2017-12-05 10:55:21 UTC
Thanks! It looks like in your case the corruption is not detected by QEMU but by Windows on D0 re-entry.

Out of curiosity, can you please try again with a modern-only virtio-serial:

-device virtio-serial-pci,...,disable-legacy=on

Thank you,
Ladi

Comment 10 Peixiu Hou 2017-12-05 15:58:36 UTC
(In reply to Ladi Prosek from comment #9)
> Thanks! It looks like in your case the corruption is not detected by QEMU
> but by Windows on D0 re-entry.
> 
> Out of curiosity, can you please try again with a modern-only virtio-serial:
> 
> -device virtio-serial-pci,...,disable-legacy=on
> 
Tried with disable-legacy=on commands:
-device virtio-serial-pci,id=virtio-serial0,max_ports=511,disable-legacy=on \
-chardev socket,host=localhost,port=4467,server,nowait,id=ser \
-device virtserialport,chardev=ser,name=port1 \

1. Also hit BSOD with virtio-win-prewhql-141, qemu report follow error message. comment#8 also hit this error.
(qemu) cpu-add 2
(qemu) qemu-kvm: Guest moved used index from 131 to 129
qemu-kvm: Guest moved used index from 131 to 129

2. Not hit BSOD or qemu crash with virtio-win-prewhql-145.

Best Regard~
Peixiu

> Thank you,
> Ladi

Comment 11 Ladi Prosek 2017-12-06 05:24:06 UTC
Great, thank you. The results you're getting are expected then.

Comment 12 lijin 2017-12-06 05:38:00 UTC
change status to verified according to comment#10 and comment#11

Comment 15 errata-xmlrpc 2018-04-10 06:33:41 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2018:0657