The emulated controller sets CAP.SSNTF, but it never generates a
notification: PxSNTF is never set by the device model, reads back as
zero and a write to it is ignored.
Linux checks HOST_CAP_SNTF and, when it is set, calls
sata_async_notification() from every port interrupt that has PxIS.SDBS
set. That function reads PxSNTF and writes the value back, so every
NCQ command costs the guest two extra MMIO accesses, i.e. two more
VM exits per I/O. QEMU and VirtualBox do not advertise SSNTF, so a
Linux guest on bhyve takes more exits per command than on them.
Drop AHCI_CAP_SSNTF from CAP. The PxSNTF register handling and its
snapshot stay as they are, so a guest that still touches the register
keeps working. CAP is part of the snapshot, so a guest restored from
a checkpoint taken before this change keeps the old CAP value and
works as before.
Signed-off-by: Wanpeng Qian <wanpengqian@gmail.com>
Sponsored by: keelos.dev