Skip to content
View in the app

A better way to browse. Learn more.

Unraid

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

QXL virtual display broken after 7.2.2 -> 7.3.2 upgrade (QEMU 9.2.3 -> 10.2.3), GPU passthrough + QXL combo

Featured Replies

Upgraded a long-running Windows 11 VM's host from Unraid 7.2.2 to 7.3.2 (QEMU went 9.2.3 -> 10.2.3 in that jump). VM has GPU passthrough (a Matrox G550, but I don't think the specific card matters) as a secondary physical display. The emulated QXL device (for Unraid's built-in noVNC console) is the primary monitor. This combo worked fine for over a year with 7.2.2.

Symptom: After the upgrade, the QXL device shows Code 43 ("Windows has stopped this device because it has reported problems") in Device Manager. noVNC shows a black screen.
If I start noVNC with the VM (Start with Console), the WIndows boot animation shows, but freezes as soon as the desktop on the physical monitor initializes.

What I've ruled out:


- VM XML is byte-identical before/after the upgrade (diffed the backup copies) - not a config/drift issue.


- Reinstalling the QXL driver from the current virtio-win-0.1.271.ISO does nothing ("best driver already installed").


- Fully uninstalling the device (driver removal + reboot) makes Windows fall back to the generic Microsoft Basic Display Adapter - which also fails to start, with Code 10: "The driver trying to start is not the same as the driver for the POSTed display adapter." Does this indicate this isn't a QXL driver problem at all? Would the Basic driver be able to initialize the virtual video? It looks like a Windows kernel-level PnP check comparing which PCI device owns the boot/POST framebuffer against whatever's trying to bind a driver to it. Maybe something changed in how QEMU 10.x negotiates that against a GPU-passthrough device sharing the same VM.


- I tried disabling the passthrough GPU's ROM BAR exposure (<rom bar='off'/> on its hostdev, to remove it from VGA/POST arbitration) - no change. QXL/noVNC renders the OVMF boot logo and the Windows boot spinner, then freezes the instant the passthrough GPU takes over as the real display.


Physical monitor via the passthrough GPU works fine as a single primary monitor. It is supposed to be a secondary monitor. I connected another monitor to the second video output of the G550, thinking I could eventually use an EDID emulator on the first port. The second video output will not initialize and the Detect another Monitor function does not find it. I had never used the second port before the upgrade so I don't know if it is related to the QXL/noVNC path or has been broken all along.

Has anyone else hit this specific combination (GPU passthrough + QXL secondary display) breaking across a QEMU 9.x -> 10.x jump? I'm trying to figure out if this is a known QEMU/libvirt regression with a documented fix, or something I need to work around some other way (e.g. swapping QXL for virtio-gpu).
Happy to pull more diagnostics if anyone's seen this before.




<graphics type='vnc' port='5901' autoport='yes' websocket='5701' listen='0.0.0.0' sharePolicy='ignore'>

<listen type='address' address='0.0.0.0'/>

</graphics>

<audio id='1' type='none'/>

<video>

<model type='qxl' ram='131072' vram='65536' vram64='64512' vgamem='65536' heads='1' primary='yes'/>

<alias name='video0'/>

<address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>

</video>

<hostdev mode='subsystem' type='pci' managed='yes'>

<driver name='vfio'/>

<source>

<address domain='0x0000' bus='0x18' slot='0x00' function='0x0'/>

</source>

<alias name='hostdev0'/>

<rom bar='off' file='/mnt/user/isos/vbios/matrox_g550.rom'/>

<address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/>

</hostdev>

<hostdev mode='subsystem' type='pci' managed='yes'>

<driver name='vfio'/>

<source>

<address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>

</source>

<alias name='hostdev1'/>

<address type='pci' domain='0x0000' bus='0x00' slot='0x0e' function='0x0'/>

</hostdev>

  • Community Expert

The boot graphics followed by QXL Code 43 suggest that the failure occurs when Windows initializes its display drivers.

The Basic Display Adapter Code 10 does not conclusively rule out a QXL driver problem. On UEFI systems, Microsoft’s basic driver uses the framebuffer established during boot, so it is not an independent test of QXL.

The unchanged XML is useful evidence. However, the host upgrade also changes the software that interprets it. We need more evidence before identifying this as a specific QEMU regression.

Please provide:

• Tools → Diagnostics, collected after the console fails, with the VM still running.

• The full VM XML and VM log from that startup. These will show the machine version, firmware configuration, and actual QEMU arguments.

• The Windows 11 build and the installed QXL and Matrox driver versions, including provider and date from Device Manager. Please also include the QXL device’s Events details.

• The identity of the second passed-through PCI device in your XML. If you already tried returning to 7.2.2, please say whether that restored QXL.

After collecting that baseline, a useful comparison would be a boot with QXL present and the Matrox temporarily unassigned, with the QXL driver installed. Save the original XML first, shut Windows down cleanly before changing the assignment, and restore it afterward. This would show whether the failure depends on the two adapters being present together.

The Matrox second-port problem remains inconclusive because that port was not tested before the upgrade.

  • Author

Thanks Jorge,

The second PCI device: ASMedia USB 3.1 controller (host 01:00.0), passed through for USB. The GPU is a Matrox G550 PCIe (host 18:00.0, legacy VBIOS dumped and supplied via <rom bar='off' file='/mnt/user/isos/vbios/matrox_g550.rom'/>

One extra data point on the XML: my nightly backup captures the live virsh dumpxml of the running VM. 2026-09-27 (7.2.2) vs 2026-10-01 (7.3.2) differ only in runtime ids/vnet names and a rom bar='off' I added while testing. Same machine type (pc-i440fx-9.1), same resolved QXL sizing (ram=131072 vram=65536 vram64=64512 vgamem=65536). So libvirt resolves it identically; whatever changed is below libvirt.

> Attached: diagnostics taken with the VM running and noVNC black, the VM XML, the VM log (QEMU args), and Windows build/driver/event-log output.

I'm hesitant to delete the Matrox while QXL is broken, which could cause me to be "locked out" of the VM entirely. Let's see what can be learned from this information.

t440-diagnostics-20261007-1708.zip windows11VM-XML.txt windows11VM-QEMU-log.txt

  • Community Expert

Thanks, the diagnostics help. Here is what they show:

- The host side is clean. The VM log has no QEMU warnings, and the syslog has no vfio, IOMMU, AER or BAR errors for the G550 or the ASMedia controller.

- The VM's first start on 7.3.2 still had the ROM BAR enabled, and QXL was already failing then. So the rom bar='off' change did not cause this. You can remove it again if you like.

- The VM had been running since Sep 28 when you collected the diagnostics. They don't include a new start, but for now the log you posted is enough.

The Windows build, driver and event-log output you mentioned did not come through. Only the zip and the two text files are attached. Please post:

- The Windows build (winver).

- Driver provider, version and date for the QXL device and the G550, from Device Manager → Properties → Driver.

- The QXL device's Events tab text.

Also, is the QXL driver installed again, or is the device still on Microsoft Basic Display Adapter after the earlier removal?

Your concern about the QXL-only test is reasonable, but it can't lock you out. The G550 assignment is a host setting, not a guest setting. If the console doesn't work, you shut the VM down from the Unraid GUI and put the saved XML back, and the G550 comes back whatever state Windows is in. Before you test, also check that RDP to the VM works, so you have a second way in. The steps are:

1. Save the current XML.

2. Make sure the QXL driver is installed (not Basic Display).

3. Shut Windows down cleanly.

4. Remove only the G550 hostdev. You can keep the USB controller.

5. Start the VM with the console.

6. Note whether QXL works and what Device Manager shows, then restore the XML.

If QXL works without the G550, the failure needs both adapters together. If it still fails, the G550 is not the cause.

There is also another option. 7.2.2 should still available as the previous version under Update OS. If you can accept a temporary downgrade and the host downtime, booting 7.2.2 with the current Windows install would show directly whether the host update or something on the Windows side changed. This is optional; the QXL-only test comes first.

  • Author

Winver 25H2 26200.8655.
See images below for driver properties.

Reviewing these proposed steps:

1. Save the current XML. (done)

2. Make sure the QXL driver is installed (not Basic Display). (Yes It is)

3. Shut Windows down cleanly. (In the VM from desktop start menu, shut down? Or from the VM control "Stop")

4. Remove only the G550 hostdev. You can keep the USB controller. (By editing the XML while the VM is shut down).

5. Start the VM with the console. (OK, if the same behavior as before, the VNC console shows the boot animation, then freezes before desktop)

6. Note whether QXL works and what Device Manager shows, then restore the XML. (Restoring XML is with VM shut down. If the QXL works and a desktop is available, easy to shut down. If no desktop, No VNC, and no monitor, how to shut down. From VM Control Stop or Force Stop?)

Screenshot 2026-10-08 145249.png

Screenshot 2026-10-08 145215.png

Screenshot 2026-10-08 145209.png

Screenshot 2026-10-08 144849.png

Screenshot 2026-10-08 144836.png

Screenshot 2026-10-08 144729.png

Screenshot 2026-10-08 144722.png

QXL Driver Event View.xml

  • Community Expert

Thanks. 25H2 build 26200.8655 is noted, and it's good that the QXL driver is installed again.

One small thing: the .xml you attached is only the Event Viewer "custom view" definition, not the events themselves. That's fine, they're not needed for this test.

To your questions:

Step 3: Shut down from inside Windows (Start → Shut down). The Stop button in the Unraid VMs page is also a clean shutdown. It sends the same ACPI power-button signal as pressing the power button on a real PC, and Windows shuts down normally. Force Stop is different. It is like pulling the power cord, so don't use it for this step.

Step 4: Yes. With the VM shut down, edit the XML and remove only the G550 <hostdev> block. Keep the ASMedia USB controller.

Step 6: If you have no desktop on the console, there are two clean ways to shut down:

- Connect with RDP and shut down from there. Please check that RDP works before you start the test.

- Click Stop in the Unraid VMs page. Windows receives the power-button request even if it has no working display, and it shuts down normally. Give it a minute or two.

Use Force Stop only if Stop has no effect after several minutes. Then, with the VM off, paste your saved XML back. The G550 returns no matter what state Windows was in.

When you do the test, please report:

- Whether the console reaches the Windows desktop or freezes at the same point as before.

- What Device Manager shows for the QXL device, if you can get in by console or RDP.

If QXL works without the G550, the problem only happens when both adapters are present together, and we can investigate that combination. If QXL still fails without the G550, the G550 is not the cause. Then the next step would be the optional temporary boot of 7.2.2 to compare.

  • Author

Jorge,

The addition of a 2nd CPU to the host T440 server caused the G550 to remove itself since the PCI bus was renumbered. In that process, the VM was run without the G550 with the QXL monitor only. I had Claude describe the details of the process of adjusting to the second CPU. The final condition is the VM is able to boot with both G550 monitors and the QXL some of the time. About 50% of boots still result in failures with BSOD - SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (0x7E) or PAGE_FAULT_IN_NONPAGED_AREA (0x50), which are only recoverable with Force Stop.

Thanks!

Claude report ----
## VM behavior after adding second CPU to host T440 system

JorgeB (on the Unraid forum) asked for a specific test: remove the Matrox G550 passthrough and

restart the VM, to see whether the QXL/virtual-console device initializes cleanly once it has no

passthrough GPU to contend with for boot/POST ownership. That exact test was never run

deliberately - but the Phase 3 CPU2 install (bus renumbering, full mechanism in the "Update

2026-10-14" section right below) put the VM through a sequence of boots that amounts to the same

experiment, plus its reverse (G550 restored), with more boot-by-boot detail than was captured when

this was first logged. Recorded here in full since the data speaks to his question either way.

### Boot 0 - G550 hostdev entirely absent from the XML (never actually started)

During the Phase 3 troubleshooting, an attempt to fix Unraid's Form View tracking (uncheck ->

Update -> re-check -> Update) deleted the Matrox hostdev block from the VM's live domain XML

entirely, rather than just toggling it - confirmed later by pulling the actual live XML and

finding only the ASMedia USB hostdev present. At the same time, Unraid's own safety checks ("VM

Autostart disabled due to vfio-bind error", "Start disabled due to PCI changes") were blocking

Start outright, and ls /var/log/libvirt/qemu/ on the host showed only Debian.log - libvirt had

never even been invoked for this VM, so no boot attempt happened yet, successful or not.

The user declined to force a start in this state to see what would happen, for a sound reason:

**"I have not yet attempted to start the Windows VM - we're just working on getting the hardware

configured... what good would it do to try and run it without the video at all?"** Fair point,

agreed at the time - so this is the one boot in the sequence that did not happen, by

deliberate choice, not a gap in the data.

Passthrough re-enabled for IOMMU Group 5:

Screenshot 2026-10-13 174203.png

### Boot 1 - G550 hostdev present (correct bus 0x19), but non-functional (bar='off' missing)

Once the bus address was corrected and Unraid's PCI-change flags were acknowledged, Start became

available and the VM was booted for the first time since the CPU2 install. At this point the

hostdev was present and bound to the right device - Device Manager showed it at PCI slot 13,

matching the guest-side slot='0x0d', so Windows had it and was binding to the correct device,

just failing to initialize it - because Unraid's own Form-View save had silently stripped the

bar='off' attribute from the hostdev's <rom> line that the pre-Phase-3 working XML had.

Result, reported in real time:

> "VM started fine. The Windows boot 'welcome screen' showed on the QEMU VNC console. The Unraid

> boot logo is on one of the two G550 monitors, frozen. Now the QXL is working and the Matrox is

> code 43."

Screenshot 2026-10-14 085330.png

So: QXL initialized and ran cleanly through to the Windows welcome screen with no issue - it

had no working competing GPU in play (the G550 was present as a device but non-functional), which

is functionally the condition JorgeB's test was trying to isolate. The G550 itself got as far as

painting the Unraid/OVMF boot logo on one physical output, then froze there permanently - no

further output, Code 43 in Device Manager ("Windows has stopped this device because it has

reported problems"). The second G550 output never initialized at all for the duration of this boot.

### Boot 2 - full stop/restart, bar='off' restored via XML View

About ten minutes later, after re-adding <rom bar='off' file='.../matrox_g550.rom'/> (via XML

View this time, not Form View, since Form View has no field for bar and had already been shown

to drop it on save), the VM was stopped and started again - a genuine full restart, not a live

edit:

> "Did it, G550 showing on the physical monitor now, no Code 43."

Clean boot, G550 rendering natively on the physical display, no Code 43. QXL's own state in this

specific boot wasn't separately checked or reported - the focus at the time was confirming the

physical-display fix held, not re-litigating the console. The next full boot cycle that same

evening (after adding a <numatune> memory-pinning block, a separate and unrelated XML change) is

where QXL and both G550 outputs were explicitly confirmed working together, with the most granular

device-handoff sequence captured so far - see "Recurrence, 2026-10-14" further down.

Operational state:

Screenshot 2026-10-16 121446.png

### Reading this against JorgeB's hypothesis

Boot 1 is the closest thing to his requested experiment that has actually happened: with the G550

unable to do anything (Code 43, frozen at its own boot logo), QXL initialized and ran without

issue. That's consistent with - though doesn't by itself prove - his point that something about

having both devices present and racing for boot/POST ownership is the trigger, rather than QXL

being broken on its own. It doesn't settle the harder question still open in this doc: why the

same, unmodified, both-devices-present configuration sometimes boots clean (all three displays,

as in several other boots logged below) and sometimes doesn't (Code 43, Code 10, or an outright

BSOD) - that's the race-condition hypothesis the "Update 2026-10-14" and "Recurrence" sections

below are about, and where his read on QEMU's version-specific POST/VGA-arbitration handling would

be the most useful next input.



  • Community Expert

Adding the second CPU changed several things at once: PCI bus numbers, NUMA layout, the new numatune block, and the ROM BAR setting during the edits. So I'd look at the earlier and current results separately.

Boot 1 is not quite the QXL-only test. The G550 was still assigned, and Windows still loaded its driver and tried to start it (Code 43). It does show that QXL can work on 7.3.2 with the G550 assigned, which is useful. But with failures on about half of boots, one boot can't tell us much either way. The same goes for the ROM BAR setting: one boot with it on and one with it off isn't enough to link it to the result.

The BSODs are the most important thing now. Before the CPU change you had Code 43 on QXL, but no crashes. Please post:

1. The crash details for a couple of the BSODs. In Windows, open Event Viewer → Windows Logs → System, find the Event ID 1001 entries (source BugCheck), and copy their text, which includes the stop code parameters. If you can, also zip and attach the C:\Windows\Minidump folder. The dumps name the driver that crashed, which tells us if it is the QXL driver, the Matrox driver, or something else.

2. New diagnostics (Tools → Diagnostics) collected after a boot that crashed, without rebooting the server first, so the VM log has both good and failed starts.

3. Did any BSOD happen before the second CPU was installed and the numatune block was added? If not, save the XML, remove the numatune block for now, and see if the BSODs stop.

4. Have the Debian VM and the server itself been stable since the CPU install?

Using Force Stop after a BSOD is fine. Windows has already crashed at that point, so there is nothing left to shut down cleanly.

When the crashes are understood, the two comparisons from before are still the ones that answer the original question. Because the problem is intermittent, each one needs several boots, for example five:

- With the G550 hostdev removed from the XML (QXL only).

- On 7.2.2, with the current XML.

One more thing: the AI summary mentions "Update 2026-10-14" and "Recurrence" sections that aren't in your post. Instead of a full write-up, a short line per boot is easier to compare: what changed in the XML, which displays worked, and the Device Manager codes or BSOD stop code.

  • Author

Jorge,
New diagnostics attached.

In the VM Event Viewer → Windows Logs → System, There are no occurrences of Event ID 1001 related to the 2nd CPU addition on October 14th.

The last 1001 bugcheck recorded by Windows was 9/28/2026 3:04:25 PM.

"The computer has rebooted from a bugcheck. The bugcheck was: 0x0000007e (0xffffffffc0000005, 0xfffff8007de73c35, 0xfffffc038d91e558, 0xfffffc038d91dd60). A dump was saved in: C:\WINDOWS\MEMORY.DMP. Report Id: 8a458a27-5a37-429f-b881-76ea501b4b0f."
I have a screenshot of that one 2026-09-28 150454.png. System Thread Exception Not Handled (0x7E)
"C:\Windows\MEMORY.DMP" at 9/28/2026 3:04:25 PM is still available in the VM.

Those were during the VM boot process after the Unraid OS update as described at the start of this thread. But I have seen BSODs occasionally over the past year since creating the VM. Once the VM boots, it works fine, so I try to avoid restarting it unless necessary.

Related to the addition of the 2nd CPU, my October 14th screenshot shows the Page Fault in nonpaged area 0x50 at time 2026-10-14 122805.
At 12:31 the log has Event ID 46 "Crash dump initialization failed!" followed by Event ID 162 "Dump file generation succeded." a few seconds later.
In the VM's minidump, the latest file is 092826-6593-01.dmp.
Is there any way to get better logging of these early in the boot process crashes?

The libvert-qemu-windows11.log available now seems to be from a small window of time from 17:26 to 17:30. Are there other logs available from Unraid or elsewhere?

Screenshot 2026-10-14 122805.png

t440-diagnostics-anon-20261016-1408.zip libvert-qemu-windows11.log

  • Community Expert

Thanks, this helps, and it changes one thing I said before. The 0x7E from Sep 28 and the occasional crashes over the past year mean the BSODs are not new with the second CPU. So the numatune test I suggested is not needed.

The new diagnostics show a clean host. There are no hardware, IOMMU or vfio errors, the VM's CPUs and memory are on the same NUMA node, and the Debian VM has been stable. The 0x50 BSOD at 12:28 matches the VM start you force-stopped at 12:30, so the timing fits.

The Unraid side can't see inside Windows. The VM log in the diagnostics already includes every VM start since the CPU change. It is kept in RAM and starts again with each server reboot. When Windows crashes and restarts by itself, QEMU keeps running, so nothing new appears in that log. The crash dump inside Windows is the useful evidence.

Next steps:

1. Please zip and attach C:\Windows\Minidump\092826-6593-01.dmp. It is small, and it should name the driver that crashed on Sep 28. Don't post MEMORY.DMP. It is very large and can contain personal data. If you'd rather analyze it yourself, open the minidump in WinDbg (free from the Microsoft Store), run !analyze -v, and post the output.

2. To capture the next crashes properly:

- Open System Properties → Advanced → Startup and Recovery.

- Clear "Automatically restart".

- Set "Write debugging information" to "Small memory dump (256 KB)".

- Check that C: has a system-managed page file. The "Crash dump initialization failed" event (ID 46) suggests that the dump setup isn't working right now.

With automatic restart off, the blue screen stays up. Take a photo that includes the "What failed:" line if it appears, and attach the new minidump.

3. Small tidy-up, not related to the crashes: in Tools → System Devices, the old G550 address (18:00.0) is still selected for vfio binding. Unraid skips it, but you can clear it.

When we know which driver crashes, we can see if it is related to the QXL/G550 combination. After that, the QXL-only and 7.2.2 comparisons are still the way to answer the original question.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.