How to Pass Through a Physical SATA Disk to KVM Guest for Exclusive Access in Ubuntu


5 views

When you need direct hardware access from a KVM guest, disk passthrough offers superior performance compared to virtualized storage. The host completely relinquishes control of the physical disk to the guest OS.

  • Host system running Ubuntu with KVM/QEMU installed
  • Target SATA disk not currently mounted on host
  • Libvirt permissions to manage raw devices
  • Proper disk identification (use lsblk or ls -l /dev/disk/by-id/)

This is the cleanest approach using libvirt's native capabilities:


<disk type='block' device='disk'>
  <driver name='qemu' type='raw' cache='none' io='native'/>
  <source dev='/dev/disk/by-id/ata-YOUR_DISK_ID'/>
  <target dev='vda' bus='virtio'/>
</disk>

For direct QEMU usage (replace /dev/sdX with your actual disk):


qemu-system-x86_64 \
  -enable-kvm \
  -drive file=/dev/sdX,format=raw,if=virtio,cache=none
  • Permissions: Ensure the QEMU process user (typically libvirt-qemu) has read/write access to the device
  • Disk Identification: Always use by-id paths to avoid device name changes
  • Performance: Use cache=none and io=native for best performance
  • Safety: Never pass through a disk containing the host's root filesystem

Permission denied errors:
Add your disk to the disk group or adjust udev rules:


sudo chown root:disk /dev/sdX
sudo chmod 660 /dev/sdX

Device busy errors:
Ensure no processes are using the disk:


sudo lsof /dev/sdX
sudo fuser -vm /dev/sdX

For advanced SCSI features:


<disk type='block' device='lun'>
  <driver name='qemu' type='raw'/>
  <source dev='/dev/sgX'/>
  <target dev='sda' bus='scsi'/>
</disk>

When you need a KVM guest VM to have direct, exclusive access to a physical SATA disk on the host machine, the most efficient approach is using PCI passthrough or raw disk mapping. This bypasses the host's filesystem layer, giving the guest near-native performance.

This method creates a virtual disk that points directly to the physical device:


sudo virsh edit your_vm_name

Add this disk configuration in the XML:



  
  
  

Replace '/dev/sdX' with your actual disk (e.g., /dev/sdb). Use lsblk to identify the correct disk.

For true native performance, pass through the entire SATA controller:


# Identify the PCI device
lspci -nn | grep SATA

# Unbind from host driver
echo "0000:01:00.0" > /sys/bus/pci/drivers/ahci/unbind

# Add to VM XML configuration

  
    

1. Data Safety: The host system will completely lose access to the disk when passed through

2. Disk Identification: Use ls -l /dev/disk/by-id/ for persistent naming instead of /dev/sdX

3. Performance Tuning: Add io='native' and discard='unmap' to the disk configuration for optimal performance

If you're using LVM, you can pass through entire volume groups: