1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun.. include:: <isonum.txt> 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun==================================== 5*4882a593SmuzhiyunPCI Express I/O Virtualization Howto 6*4882a593Smuzhiyun==================================== 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun:Copyright: |copy| 2009 Intel Corporation 9*4882a593Smuzhiyun:Authors: - Yu Zhao <yu.zhao@intel.com> 10*4882a593Smuzhiyun - Donald Dutile <ddutile@redhat.com> 11*4882a593Smuzhiyun 12*4882a593SmuzhiyunOverview 13*4882a593Smuzhiyun======== 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunWhat is SR-IOV 16*4882a593Smuzhiyun-------------- 17*4882a593Smuzhiyun 18*4882a593SmuzhiyunSingle Root I/O Virtualization (SR-IOV) is a PCI Express Extended 19*4882a593Smuzhiyuncapability which makes one physical device appear as multiple virtual 20*4882a593Smuzhiyundevices. The physical device is referred to as Physical Function (PF) 21*4882a593Smuzhiyunwhile the virtual devices are referred to as Virtual Functions (VF). 22*4882a593SmuzhiyunAllocation of the VF can be dynamically controlled by the PF via 23*4882a593Smuzhiyunregisters encapsulated in the capability. By default, this feature is 24*4882a593Smuzhiyunnot enabled and the PF behaves as traditional PCIe device. Once it's 25*4882a593Smuzhiyunturned on, each VF's PCI configuration space can be accessed by its own 26*4882a593SmuzhiyunBus, Device and Function Number (Routing ID). And each VF also has PCI 27*4882a593SmuzhiyunMemory Space, which is used to map its register set. VF device driver 28*4882a593Smuzhiyunoperates on the register set so it can be functional and appear as a 29*4882a593Smuzhiyunreal existing PCI device. 30*4882a593Smuzhiyun 31*4882a593SmuzhiyunUser Guide 32*4882a593Smuzhiyun========== 33*4882a593Smuzhiyun 34*4882a593SmuzhiyunHow can I enable SR-IOV capability 35*4882a593Smuzhiyun---------------------------------- 36*4882a593Smuzhiyun 37*4882a593SmuzhiyunMultiple methods are available for SR-IOV enablement. 38*4882a593SmuzhiyunIn the first method, the device driver (PF driver) will control the 39*4882a593Smuzhiyunenabling and disabling of the capability via API provided by SR-IOV core. 40*4882a593SmuzhiyunIf the hardware has SR-IOV capability, loading its PF driver would 41*4882a593Smuzhiyunenable it and all VFs associated with the PF. Some PF drivers require 42*4882a593Smuzhiyuna module parameter to be set to determine the number of VFs to enable. 43*4882a593SmuzhiyunIn the second method, a write to the sysfs file sriov_numvfs will 44*4882a593Smuzhiyunenable and disable the VFs associated with a PCIe PF. This method 45*4882a593Smuzhiyunenables per-PF, VF enable/disable values versus the first method, 46*4882a593Smuzhiyunwhich applies to all PFs of the same device. Additionally, the 47*4882a593SmuzhiyunPCI SRIOV core support ensures that enable/disable operations are 48*4882a593Smuzhiyunvalid to reduce duplication in multiple drivers for the same 49*4882a593Smuzhiyunchecks, e.g., check numvfs == 0 if enabling VFs, ensure 50*4882a593Smuzhiyunnumvfs <= totalvfs. 51*4882a593SmuzhiyunThe second method is the recommended method for new/future VF devices. 52*4882a593Smuzhiyun 53*4882a593SmuzhiyunHow can I use the Virtual Functions 54*4882a593Smuzhiyun----------------------------------- 55*4882a593Smuzhiyun 56*4882a593SmuzhiyunThe VF is treated as hot-plugged PCI devices in the kernel, so they 57*4882a593Smuzhiyunshould be able to work in the same way as real PCI devices. The VF 58*4882a593Smuzhiyunrequires device driver that is same as a normal PCI device's. 59*4882a593Smuzhiyun 60*4882a593SmuzhiyunDeveloper Guide 61*4882a593Smuzhiyun=============== 62*4882a593Smuzhiyun 63*4882a593SmuzhiyunSR-IOV API 64*4882a593Smuzhiyun---------- 65*4882a593Smuzhiyun 66*4882a593SmuzhiyunTo enable SR-IOV capability: 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun(a) For the first method, in the driver:: 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun'nr_virtfn' is number of VFs to be enabled. 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun(b) For the second method, from sysfs:: 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun echo 'nr_virtfn' > \ 77*4882a593Smuzhiyun /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs 78*4882a593Smuzhiyun 79*4882a593SmuzhiyunTo disable SR-IOV capability: 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun(a) For the first method, in the driver:: 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun void pci_disable_sriov(struct pci_dev *dev); 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun(b) For the second method, from sysfs:: 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun echo 0 > \ 88*4882a593Smuzhiyun /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs 89*4882a593Smuzhiyun 90*4882a593SmuzhiyunTo enable auto probing VFs by a compatible driver on the host, run 91*4882a593Smuzhiyuncommand below before enabling SR-IOV capabilities. This is the 92*4882a593Smuzhiyundefault behavior. 93*4882a593Smuzhiyun:: 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun echo 1 > \ 96*4882a593Smuzhiyun /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe 97*4882a593Smuzhiyun 98*4882a593SmuzhiyunTo disable auto probing VFs by a compatible driver on the host, run 99*4882a593Smuzhiyuncommand below before enabling SR-IOV capabilities. Updating this 100*4882a593Smuzhiyunentry will not affect VFs which are already probed. 101*4882a593Smuzhiyun:: 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun echo 0 > \ 104*4882a593Smuzhiyun /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe 105*4882a593Smuzhiyun 106*4882a593SmuzhiyunUsage example 107*4882a593Smuzhiyun------------- 108*4882a593Smuzhiyun 109*4882a593SmuzhiyunFollowing piece of code illustrates the usage of the SR-IOV API. 110*4882a593Smuzhiyun:: 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun static int dev_probe(struct pci_dev *dev, const struct pci_device_id *id) 113*4882a593Smuzhiyun { 114*4882a593Smuzhiyun pci_enable_sriov(dev, NR_VIRTFN); 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun ... 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun return 0; 119*4882a593Smuzhiyun } 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun static void dev_remove(struct pci_dev *dev) 122*4882a593Smuzhiyun { 123*4882a593Smuzhiyun pci_disable_sriov(dev); 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun ... 126*4882a593Smuzhiyun } 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun static int dev_suspend(struct pci_dev *dev, pm_message_t state) 129*4882a593Smuzhiyun { 130*4882a593Smuzhiyun ... 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun return 0; 133*4882a593Smuzhiyun } 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun static int dev_resume(struct pci_dev *dev) 136*4882a593Smuzhiyun { 137*4882a593Smuzhiyun ... 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun return 0; 140*4882a593Smuzhiyun } 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun static void dev_shutdown(struct pci_dev *dev) 143*4882a593Smuzhiyun { 144*4882a593Smuzhiyun ... 145*4882a593Smuzhiyun } 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun static int dev_sriov_configure(struct pci_dev *dev, int numvfs) 148*4882a593Smuzhiyun { 149*4882a593Smuzhiyun if (numvfs > 0) { 150*4882a593Smuzhiyun ... 151*4882a593Smuzhiyun pci_enable_sriov(dev, numvfs); 152*4882a593Smuzhiyun ... 153*4882a593Smuzhiyun return numvfs; 154*4882a593Smuzhiyun } 155*4882a593Smuzhiyun if (numvfs == 0) { 156*4882a593Smuzhiyun .... 157*4882a593Smuzhiyun pci_disable_sriov(dev); 158*4882a593Smuzhiyun ... 159*4882a593Smuzhiyun return 0; 160*4882a593Smuzhiyun } 161*4882a593Smuzhiyun } 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun static struct pci_driver dev_driver = { 164*4882a593Smuzhiyun .name = "SR-IOV Physical Function driver", 165*4882a593Smuzhiyun .id_table = dev_id_table, 166*4882a593Smuzhiyun .probe = dev_probe, 167*4882a593Smuzhiyun .remove = dev_remove, 168*4882a593Smuzhiyun .suspend = dev_suspend, 169*4882a593Smuzhiyun .resume = dev_resume, 170*4882a593Smuzhiyun .shutdown = dev_shutdown, 171*4882a593Smuzhiyun .sriov_configure = dev_sriov_configure, 172*4882a593Smuzhiyun }; 173