When passing through a physical SSD device to a Windows 7 guest in QEMU/KVM, you might notice that TRIM commands from the guest OS aren't being properly propagated to the host's physical SSD. This leads to suboptimal performance over time as the SSD's garbage collection can't work efficiently.
The discard=on
parameter in QEMU primarily works with image files (qcow2, raw files, etc.) rather than physical devices. When using:
-drive file=/dev/disk/by-id/wwn-0x5002538d4002d61f,if=none,id=drive-scsi0-0-0-0,format=raw,discard=on
-device virtio-scsi-pci,id=scsi0
-device scsi-hd,bus=scsi0.0,drive=drive-scsi0-0-0-0
The discard setting gets ignored for physical devices because QEMU can't safely assume control over the entire block device's unused space.
Here are three approaches to achieve proper TRIM functionality:
1. Using virtio-blk Instead of SCSI
Virtio-blk generally has better TRIM support:
-blockdev node-name=drive0,driver=raw,file.driver=host_device,file.filename=/dev/disk/by-id/wwn-0x5002538d4002d61f,discard=unmap
-device virtio-blk-pci,drive=drive0,scsi=off
This configuration enables UNMAP (SCSI equivalent of TRIM) passthrough.
2. Creating a Partition-Loopback Setup
For more control, you can create a partition on the SSD and pass it through:
# On host:
sudo sgdisk -n 0:0:0 -t 0:0700 /dev/disk/by-id/wwn-0x5002538d4002d61f
# QEMU command:
-drive file=/dev/disk/by-id/wwn-0x5002538d4002d61f-part1,if=none,id=drive0,format=raw,discard=on
-device virtio-blk-pci,drive=drive0
3. Virtio-SCSI with Explicit Discard Settings
For SCSI passthrough (required for some Windows versions), modify your existing config:
-drive file=/dev/disk/by-id/wwn-0x5002538d4002d61f,if=none,id=drive-scsi0-0-0-0,format=raw,cache=none,aio=native,discard=unmap
-device virtio-scsi-pci,id=scsi0
-device scsi-hd,bus=scsi0.0,drive=drive-scsi0-0-0-0,discard_granularity=512
In your Windows 7 guest:
- Run
fsutil behavior query DisableDeleteNotify
- should return 0 - Run
defrag /L /V C:
to verify TRIM operations
On the Linux host, check kernel messages after TRIM operations:
sudo dmesg | grep -i trim
sudo dmesg | grep -i discard
For best performance with physical SSD passthrough:
- Always use
cache=none
andaio=native
- Consider
discard_granularity=4096
if your SSD uses 4K blocks - Disable host-side filesystem caching with
direct=on
if supported
When passing through a physical SSD to a QEMU/KVM virtual machine, you might notice that TRIM commands issued by the guest OS (Windows/Linux) aren't reaching the underlying hardware. This occurs because the default configuration doesn't properly handle SCSI UNMAP (for virtio-scsi) or DISCARD commands for direct physical device passthrough.
The typical approach using:
-drive file=/dev/disk/by-id/wwn-0x5002538d4002d61f,if=none,id=drive-scsi0-0-0-0,format=raw,discard=on \
-device virtio-scsi-pci,id=scsi0 \
-device scsi-hd,bus=scsi0.0,drive=drive-scsi0-0-0-0
only enables discard at the virtual device layer, not physical passthrough.
For proper TRIM passthrough, you need to:
- Use virtio-blk instead of virtio-scsi for better discard support
- Enable both discard and detect-zeroes options
- Configure proper cache settings
Here's the optimized configuration:
-blockdev node-name=drive0,driver=host_device,filename=/dev/disk/by-id/wwn-0x5002538d4002d61f,cache.direct=on,discard=unmap,detect-zeroes=unmap \
-device virtio-blk-pci,drive=drive0,scsi=off
- cache.direct=on: Bypasses host page cache for direct I/O
- discard=unmap: Passes TRIM commands to physical device
- detect-zeroes=unmap: Converts zero writes to UNMAP commands
- scsi=off: Forces virtio-blk mode for better compatibility
After implementing this configuration:
fsutil behavior query DisableDeleteNotify
Should return 0 (TRIM enabled). For Linux guests:
sudo fstrim -v /
Should show trimmed blocks. Monitor your SSD's SMART data to confirm TRIM is working:
smartctl -a /dev/disk/by-id/wwn-0x5002538d4002d61f | grep -i trim
For NVMe SSDs, consider direct PCIe passthrough for best performance:
-device vfio-pci,host=01:00.0
This gives the guest native NVMe access including all TRIM functionality.
The virtio-blk approach typically shows:
- 15-20% better random write performance with TRIM
- More consistent latency under heavy workloads
- Better SSD longevity through proper garbage collection
For production systems, combine this with:
-object iothread,id=iothread0 \
-device virtio-blk-pci,iothread=iothread0,...