2
* Copyright (C) 2009-2011 Red Hat, Inc.
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2.1 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
* Mark McLoughlin <markmc@redhat.com>
32
#include <sys/types.h>
40
#include "virterror_internal.h"
43
/* avoid compilation breakage on some systems */
45
# define MODPROBE "modprobe"
48
#define PCI_SYSFS "/sys/bus/pci/"
49
#define PCI_ID_LEN 10 /* "XXXX XXXX" */
50
#define PCI_ADDR_LEN 13 /* "XXXX:XX:XX.X" */
53
#define SRIOV_NOT_FOUND 1
54
#define SRIOV_ERROR -1
62
char name[PCI_ADDR_LEN]; /* domain:bus:slot.function */
63
char id[PCI_ID_LEN]; /* product vendor */
65
const char *used_by; /* The domain which uses the device */
69
unsigned pcie_cap_pos;
70
unsigned pci_pm_cap_pos;
72
unsigned has_pm_reset : 1;
75
/* used by reattach function */
76
unsigned unbind_from_stub : 1;
77
unsigned remove_slot : 1;
81
struct _pciDeviceList {
87
/* For virReportOOMError() and virReportSystemError() */
88
#define VIR_FROM_THIS VIR_FROM_NONE
90
#define pciReportError(code, ...) \
91
virReportErrorHelper(VIR_FROM_NONE, code, __FILE__, \
92
__FUNCTION__, __LINE__, __VA_ARGS__)
94
/* Specifications referenced in comments:
95
* PCI30 - PCI Local Bus Specification 3.0
96
* PCIe20 - PCI Express Base Specification 2.0
97
* BR12 - PCI-to-PCI Bridge Architecture Specification 1.2
98
* PM12 - PCI Bus Power Management Interface Specification 1.2
99
* ECN_AF - Advanced Capabilities for Conventional PCI ECN
102
/* Type 0 config space header length; PCI30 Section 6.1 Configuration Space Organization */
103
#define PCI_CONF_LEN 0x100
104
#define PCI_CONF_HEADER_LEN 0x40
107
#define PCI_HEADER_TYPE 0x0e /* Header type */
108
#define PCI_HEADER_TYPE_BRIDGE 0x1
109
#define PCI_HEADER_TYPE_MASK 0x7f
110
#define PCI_HEADER_TYPE_MULTI 0x80
112
/* PCI30 6.2.1 Device Identification */
113
#define PCI_CLASS_DEVICE 0x0a /* Device class */
115
/* Class Code for bridge; PCI30 D.7 Base Class 06h */
116
#define PCI_CLASS_BRIDGE_PCI 0x0604
118
/* PCI30 6.2.3 Device Status */
119
#define PCI_STATUS 0x06 /* 16 bits */
120
#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
122
/* PCI30 6.7 Capabilities List */
123
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
125
/* PM12 3.2.1 Capability Identifier */
126
#define PCI_CAP_ID_PM 0x01 /* Power Management */
127
/* PCI30 H Capability IDs */
128
#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
129
/* ECN_AF 6.x.1.1 Capability ID for AF */
130
#define PCI_CAP_ID_AF 0x13 /* Advanced Features */
132
/* PCIe20 7.8.3 Device Capabilities Register (Offset 04h) */
133
#define PCI_EXP_DEVCAP 0x4 /* Device capabilities */
134
#define PCI_EXP_DEVCAP_FLR (1<<28) /* Function Level Reset */
136
/* Header type 1 BR12 3.2 PCI-to-PCI Bridge Configuration Space Header Format */
137
#define PCI_PRIMARY_BUS 0x18 /* BR12 3.2.5.2 Primary bus number */
138
#define PCI_SECONDARY_BUS 0x19 /* BR12 3.2.5.3 Secondary bus number */
139
#define PCI_SUBORDINATE_BUS 0x1a /* BR12 3.2.5.4 Highest bus number behind the bridge */
140
#define PCI_BRIDGE_CONTROL 0x3e
141
/* BR12 3.2.5.18 Bridge Control Register */
142
#define PCI_BRIDGE_CTL_RESET 0x40 /* Secondary bus reset */
144
/* PM12 3.2.4 Power Management Control/Status (Offset = 4) */
145
#define PCI_PM_CTRL 4 /* PM control and status register */
146
#define PCI_PM_CTRL_STATE_MASK 0x3 /* Current power state (D0 to D3) */
147
#define PCI_PM_CTRL_STATE_D0 0x0 /* D0 state */
148
#define PCI_PM_CTRL_STATE_D3hot 0x3 /* D3 state */
149
#define PCI_PM_CTRL_NO_SOFT_RESET 0x8 /* No reset for D3hot->D0 */
151
/* ECN_AF 6.x.1 Advanced Features Capability Structure */
152
#define PCI_AF_CAP 0x3 /* Advanced features capabilities */
153
#define PCI_AF_CAP_FLR 0x2 /* Function Level Reset */
155
#define PCI_EXP_FLAGS 0x2
156
#define PCI_EXP_FLAGS_TYPE 0x00f0
157
#define PCI_EXP_TYPE_DOWNSTREAM 0x6
159
#define PCI_EXT_CAP_BASE 0x100
160
#define PCI_EXT_CAP_LIMIT 0x1000
161
#define PCI_EXT_CAP_ID_MASK 0x0000ffff
162
#define PCI_EXT_CAP_OFFSET_SHIFT 20
163
#define PCI_EXT_CAP_OFFSET_MASK 0x00000ffc
165
#define PCI_EXT_CAP_ID_ACS 0x000d
166
#define PCI_EXT_ACS_CTRL 0x06
168
#define PCI_EXT_CAP_ACS_SV 0x01
169
#define PCI_EXT_CAP_ACS_RR 0x04
170
#define PCI_EXT_CAP_ACS_CR 0x08
171
#define PCI_EXT_CAP_ACS_UF 0x10
172
#define PCI_EXT_CAP_ACS_ENABLED (PCI_EXT_CAP_ACS_SV | \
173
PCI_EXT_CAP_ACS_RR | \
174
PCI_EXT_CAP_ACS_CR | \
178
pciOpenConfig(pciDevice *dev)
185
fd = open(dev->path, O_RDWR);
188
VIR_WARN("Failed to open config space file '%s': %s",
189
dev->path, virStrerror(errno, ebuf, sizeof(ebuf)));
192
VIR_DEBUG("%s %s: opened %s", dev->id, dev->name, dev->path);
198
pciCloseConfig(pciDevice *dev)
203
VIR_FORCE_CLOSE(dev->fd);
207
pciRead(pciDevice *dev, unsigned pos, uint8_t *buf, unsigned buflen)
209
memset(buf, 0, buflen);
211
if (pciOpenConfig(dev) < 0)
214
if (lseek(dev->fd, pos, SEEK_SET) != pos ||
215
saferead(dev->fd, buf, buflen) != buflen) {
217
VIR_WARN("Failed to read from '%s' : %s", dev->path,
218
virStrerror(errno, ebuf, sizeof(ebuf)));
225
pciRead8(pciDevice *dev, unsigned pos)
228
pciRead(dev, pos, &buf, sizeof(buf));
233
pciRead16(pciDevice *dev, unsigned pos)
236
pciRead(dev, pos, &buf[0], sizeof(buf));
237
return (buf[0] << 0) | (buf[1] << 8);
241
pciRead32(pciDevice *dev, unsigned pos)
244
pciRead(dev, pos, &buf[0], sizeof(buf));
245
return (buf[0] << 0) | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
249
pciWrite(pciDevice *dev, unsigned pos, uint8_t *buf, unsigned buflen)
251
if (pciOpenConfig(dev) < 0)
254
if (lseek(dev->fd, pos, SEEK_SET) != pos ||
255
safewrite(dev->fd, buf, buflen) != buflen) {
257
VIR_WARN("Failed to write to '%s' : %s", dev->path,
258
virStrerror(errno, ebuf, sizeof(ebuf)));
265
pciWrite16(pciDevice *dev, unsigned pos, uint16_t val)
267
uint8_t buf[2] = { (val >> 0), (val >> 8) };
268
pciWrite(dev, pos, &buf[0], sizeof(buf));
272
pciWrite32(pciDevice *dev, unsigned pos, uint32_t val)
274
uint8_t buf[4] = { (val >> 0), (val >> 8), (val >> 16), (val >> 14) };
275
pciWrite(dev, pos, &buf[0], sizeof(buf));
278
typedef int (*pciIterPredicate)(pciDevice *, pciDevice *, void *);
280
/* Iterate over available PCI devices calling @predicate
281
* to compare each one to @dev.
282
* Return -1 on error since we don't want to assume it is
283
* safe to reset if there is an error.
286
pciIterDevices(pciIterPredicate predicate,
292
struct dirent *entry;
298
VIR_DEBUG("%s %s: iterating over " PCI_SYSFS "devices", dev->id, dev->name);
300
dir = opendir(PCI_SYSFS "devices");
302
VIR_WARN("Failed to open " PCI_SYSFS "devices");
306
while ((entry = readdir(dir))) {
307
unsigned int domain, bus, slot, function;
311
/* Ignore '.' and '..' */
312
if (entry->d_name[0] == '.')
315
/* expected format: <domain>:<bus>:<slot>.<function> */
317
virStrToLong_ui(entry->d_name, &tmp, 16, &domain) < 0 || *tmp != ':' ||
319
virStrToLong_ui(tmp + 1, &tmp, 16, &bus) < 0 || *tmp != ':' ||
321
virStrToLong_ui(tmp + 1, &tmp, 16, &slot) < 0 || *tmp != '.' ||
323
virStrToLong_ui(tmp + 1, NULL, 16, &function) < 0) {
324
VIR_WARN("Unusual entry in " PCI_SYSFS "devices: %s", entry->d_name);
328
check = pciGetDevice(domain, bus, slot, function);
334
rc = predicate(dev, check, data);
336
/* the predicate returned an error, bail */
337
pciFreeDevice(check);
342
VIR_DEBUG("%s %s: iter matched on %s", dev->id, dev->name, check->name);
348
pciFreeDevice(check);
355
pciFindCapabilityOffset(pciDevice *dev, unsigned capability)
360
status = pciRead16(dev, PCI_STATUS);
361
if (!(status & PCI_STATUS_CAP_LIST))
364
pos = pciRead8(dev, PCI_CAPABILITY_LIST);
366
/* Zero indicates last capability, capabilities can't
367
* be in the config space header and 0xff is returned
368
* by the kernel if we don't have access to this region
370
* Note: we're not handling loops or extended
373
while (pos >= PCI_CONF_HEADER_LEN && pos != 0xff) {
374
uint8_t capid = pciRead8(dev, pos);
375
if (capid == capability) {
376
VIR_DEBUG("%s %s: found cap 0x%.2x at 0x%.2x",
377
dev->id, dev->name, capability, pos);
381
pos = pciRead8(dev, pos + 1);
384
VIR_DEBUG("%s %s: failed to find cap 0x%.2x", dev->id, dev->name, capability);
390
pciFindExtendedCapabilityOffset(pciDevice *dev, unsigned capability)
396
/* minimum 8 bytes per capability */
397
ttl = (PCI_EXT_CAP_LIMIT - PCI_EXT_CAP_BASE) / 8;
398
pos = PCI_EXT_CAP_BASE;
400
while (ttl > 0 && pos >= PCI_EXT_CAP_BASE) {
401
header = pciRead32(dev, pos);
403
if ((header & PCI_EXT_CAP_ID_MASK) == capability)
406
pos = (header >> PCI_EXT_CAP_OFFSET_SHIFT) & PCI_EXT_CAP_OFFSET_MASK;
413
/* detects whether this device has FLR. Returns 0 if the device does
414
* not have FLR, 1 if it does, and -1 on error
417
pciDetectFunctionLevelReset(pciDevice *dev)
424
/* The PCIe Function Level Reset capability allows
425
* individual device functions to be reset without
426
* affecting any other functions on the device or
427
* any other devices on the bus. This is only common
428
* on SR-IOV NICs at the moment.
430
if (dev->pcie_cap_pos) {
431
caps = pciRead32(dev, dev->pcie_cap_pos + PCI_EXP_DEVCAP);
432
if (caps & PCI_EXP_DEVCAP_FLR) {
433
VIR_DEBUG("%s %s: detected PCIe FLR capability", dev->id, dev->name);
438
/* The PCI AF Function Level Reset capability is
439
* the same thing, except for conventional PCI
440
* devices. This is not common yet.
442
pos = pciFindCapabilityOffset(dev, PCI_CAP_ID_AF);
444
caps = pciRead16(dev, pos + PCI_AF_CAP);
445
if (caps & PCI_AF_CAP_FLR) {
446
VIR_DEBUG("%s %s: detected PCI FLR capability", dev->id, dev->name);
451
/* there are some buggy devices that do support FLR, but forget to
452
* advertise that fact in their capabilities. However, FLR is *required*
453
* to be present for virtual functions (VFs), so if we see that this
454
* device is a VF, we just assume FLR works
457
if (virAsprintf(&path, PCI_SYSFS "devices/%s/physfn", dev->name) < 0) {
462
found = virFileExists(path);
465
VIR_DEBUG("%s %s: buggy device didn't advertise FLR, but is a VF; forcing flr on",
470
VIR_DEBUG("%s %s: no FLR capability found", dev->id, dev->name);
475
/* Require the device has the PCI Power Management capability
476
* and that a D3hot->D0 transition will results in a full
477
* internal reset, not just a soft reset.
480
pciDetectPowerManagementReset(pciDevice *dev)
482
if (dev->pci_pm_cap_pos) {
485
/* require the NO_SOFT_RESET bit is clear */
486
ctl = pciRead32(dev, dev->pci_pm_cap_pos + PCI_PM_CTRL);
487
if (!(ctl & PCI_PM_CTRL_NO_SOFT_RESET)) {
488
VIR_DEBUG("%s %s: detected PM reset capability", dev->id, dev->name);
493
VIR_DEBUG("%s %s: no PM reset capability found", dev->id, dev->name);
498
/* Any active devices on the same domain/bus ? */
500
pciSharesBusWithActive(pciDevice *dev, pciDevice *check, void *data)
502
pciDeviceList *inactiveDevs = data;
504
/* Different domain, different bus, or simply identical device */
505
if (dev->domain != check->domain ||
506
dev->bus != check->bus ||
507
(dev->slot == check->slot &&
508
dev->function == check->function))
511
/* same bus, but inactive, i.e. about to be assigned to guest */
512
if (inactiveDevs && pciDeviceListFind(inactiveDevs, check))
519
pciBusContainsActiveDevices(pciDevice *dev,
520
pciDeviceList *inactiveDevs)
522
pciDevice *active = NULL;
523
if (pciIterDevices(pciSharesBusWithActive,
524
dev, &active, inactiveDevs) < 0)
529
/* Is @check the parent of @dev ? */
531
pciIsParent(pciDevice *dev, pciDevice *check, void *data)
533
uint16_t device_class;
534
uint8_t header_type, secondary, subordinate;
535
pciDevice **best = data;
537
if (dev->domain != check->domain)
540
/* Is it a bridge? */
541
device_class = pciRead16(check, PCI_CLASS_DEVICE);
542
if (device_class != PCI_CLASS_BRIDGE_PCI)
546
header_type = pciRead8(check, PCI_HEADER_TYPE);
547
if ((header_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE)
550
secondary = pciRead8(check, PCI_SECONDARY_BUS);
551
subordinate = pciRead8(check, PCI_SUBORDINATE_BUS);
553
VIR_DEBUG("%s %s: found parent device %s", dev->id, dev->name, check->name);
555
/* if the secondary bus exactly equals the device's bus, then we found
556
* the direct parent. No further work is necessary
558
if (dev->bus == secondary)
561
/* otherwise, SRIOV allows VFs to be on different busses then their PFs.
562
* In this case, what we need to do is look for the "best" match; i.e.
563
* the most restrictive match that still satisfies all of the conditions.
565
if (dev->bus > secondary && dev->bus <= subordinate) {
567
*best = pciGetDevice(check->domain, check->bus, check->slot,
573
/* OK, we had already recorded a previous "best" match for the
574
* parent. See if the current device is more restrictive than the
575
* best, and if so, make it the new best
577
if (secondary > pciRead8(*best, PCI_SECONDARY_BUS)) {
578
pciFreeDevice(*best);
579
*best = pciGetDevice(check->domain, check->bus, check->slot,
591
pciGetParentDevice(pciDevice *dev, pciDevice **parent)
593
pciDevice *best = NULL;
597
ret = pciIterDevices(pciIsParent, dev, parent, &best);
605
/* Secondary Bus Reset is our sledgehammer - it resets all
606
* devices behind a bus.
609
pciTrySecondaryBusReset(pciDevice *dev,
610
pciDeviceList *inactiveDevs)
612
pciDevice *parent, *conflict;
613
uint8_t config_space[PCI_CONF_LEN];
617
/* For now, we just refuse to do a secondary bus reset
618
* if there are other devices/functions behind the bus.
619
* In future, we could allow it so long as those devices
620
* are not in use by the host or other guests.
622
if ((conflict = pciBusContainsActiveDevices(dev, inactiveDevs))) {
623
pciReportError(VIR_ERR_INTERNAL_ERROR,
624
_("Active %s devices on bus with %s, not doing bus reset"),
625
conflict->name, dev->name);
629
/* Find the parent bus */
630
if (pciGetParentDevice(dev, &parent) < 0)
633
pciReportError(VIR_ERR_INTERNAL_ERROR,
634
_("Failed to find parent device for %s"),
639
VIR_DEBUG("%s %s: doing a secondary bus reset", dev->id, dev->name);
641
/* Save and restore the device's config space; we only do this
642
* for the supplied device since we refuse to do a reset if there
643
* are multiple devices/functions
645
if (pciRead(dev, 0, config_space, PCI_CONF_LEN) < 0) {
646
pciReportError(VIR_ERR_INTERNAL_ERROR,
647
_("Failed to read PCI config space for %s"),
652
/* Read the control register, set the reset flag, wait 200ms,
653
* unset the reset flag and wait 200ms.
655
ctl = pciRead16(dev, PCI_BRIDGE_CONTROL);
657
pciWrite16(parent, PCI_BRIDGE_CONTROL, ctl | PCI_BRIDGE_CTL_RESET);
659
usleep(200 * 1000); /* sleep 200ms */
661
pciWrite16(parent, PCI_BRIDGE_CONTROL, ctl);
663
usleep(200 * 1000); /* sleep 200ms */
665
if (pciWrite(dev, 0, config_space, PCI_CONF_LEN) < 0) {
666
pciReportError(VIR_ERR_INTERNAL_ERROR,
667
_("Failed to restore PCI config space for %s"),
673
pciFreeDevice(parent);
677
/* Power management reset attempts to reset a device using a
678
* D-state transition from D3hot to D0. Note, in detect_pm_reset()
679
* above we require the device supports a full internal reset.
682
pciTryPowerManagementReset(pciDevice *dev)
684
uint8_t config_space[PCI_CONF_LEN];
687
if (!dev->pci_pm_cap_pos)
690
/* Save and restore the device's config space. */
691
if (pciRead(dev, 0, &config_space[0], PCI_CONF_LEN) < 0) {
692
pciReportError(VIR_ERR_INTERNAL_ERROR,
693
_("Failed to read PCI config space for %s"),
698
VIR_DEBUG("%s %s: doing a power management reset", dev->id, dev->name);
700
ctl = pciRead32(dev, dev->pci_pm_cap_pos + PCI_PM_CTRL);
701
ctl &= ~PCI_PM_CTRL_STATE_MASK;
703
pciWrite32(dev, dev->pci_pm_cap_pos + PCI_PM_CTRL, ctl|PCI_PM_CTRL_STATE_D3hot);
705
usleep(10 * 1000); /* sleep 10ms */
707
pciWrite32(dev, dev->pci_pm_cap_pos + PCI_PM_CTRL, ctl|PCI_PM_CTRL_STATE_D0);
709
usleep(10 * 1000); /* sleep 10ms */
711
if (pciWrite(dev, 0, &config_space[0], PCI_CONF_LEN) < 0) {
712
pciReportError(VIR_ERR_INTERNAL_ERROR,
713
_("Failed to restore PCI config space for %s"),
722
pciInitDevice(pciDevice *dev)
726
if (pciOpenConfig(dev) < 0) {
727
virReportSystemError(errno,
728
_("Failed to open config space file '%s'"),
733
dev->pcie_cap_pos = pciFindCapabilityOffset(dev, PCI_CAP_ID_EXP);
734
dev->pci_pm_cap_pos = pciFindCapabilityOffset(dev, PCI_CAP_ID_PM);
735
flr = pciDetectFunctionLevelReset(dev);
739
dev->has_pm_reset = pciDetectPowerManagementReset(dev);
745
pciResetDevice(pciDevice *dev,
746
pciDeviceList *activeDevs,
747
pciDeviceList *inactiveDevs)
751
if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
752
pciReportError(VIR_ERR_INTERNAL_ERROR,
753
_("Not resetting active device %s"), dev->name);
757
if (!dev->initted && pciInitDevice(dev) < 0)
760
/* KVM will perform FLR when starting and stopping
761
* a guest, so there is no need for us to do it here.
766
/* If the device supports PCI power management reset,
767
* that's the next best thing because it only resets
768
* the function, not the whole device.
770
if (dev->has_pm_reset)
771
ret = pciTryPowerManagementReset(dev);
773
/* Bus reset is not an option with the root bus */
774
if (ret < 0 && dev->bus != 0)
775
ret = pciTrySecondaryBusReset(dev, inactiveDevs);
778
virErrorPtr err = virGetLastError();
779
pciReportError(VIR_ERR_INTERNAL_ERROR,
780
_("Unable to reset PCI device %s: %s"),
782
err ? err->message : _("no FLR, PM reset or bus reset available"));
790
pciDriverDir(char **buffer, const char *driver)
794
if (virAsprintf(buffer, PCI_SYSFS "drivers/%s", driver) < 0) {
803
pciDriverFile(char **buffer, const char *driver, const char *file)
807
if (virAsprintf(buffer, PCI_SYSFS "drivers/%s/%s", driver, file) < 0) {
816
pciDeviceFile(char **buffer, const char *device, const char *file)
820
if (virAsprintf(buffer, PCI_SYSFS "devices/%s/%s", device, file) < 0) {
830
pciFindStubDriver(void)
832
char *drvpath = NULL;
836
if (pciDriverDir(&drvpath, "pci-stub") < 0) {
840
if (virFileExists(drvpath)) {
845
if (pciDriverDir(&drvpath, "pciback") < 0) {
849
if (virFileExists(drvpath)) {
857
const char *const stubprobe[] = { MODPROBE, "pci-stub", NULL };
858
const char *const backprobe[] = { MODPROBE, "pciback", NULL };
862
* Probing for pci-stub will succeed regardless of whether
863
* on native or Xen kernels.
864
* On Xen though, we want to prefer pciback, so probe
865
* for that first, because that will only work on Xen
867
if (virRun(backprobe, NULL) < 0 &&
868
virRun(stubprobe, NULL) < 0) {
870
VIR_WARN("failed to load pci-stub or pciback drivers: %s",
871
virStrerror(errno, ebuf, sizeof ebuf));
882
pciUnbindDeviceFromStub(pciDevice *dev, const char *driver)
888
if (pciDriverDir(&drvdir, driver) < 0)
891
if (!dev->unbind_from_stub)
894
/* If the device is bound to stub, unbind it.
896
if (pciDeviceFile(&path, dev->name, "driver") < 0)
899
if (virFileExists(drvdir) && virFileLinkPointsTo(path, drvdir)) {
900
if (pciDriverFile(&path, driver, "unbind") < 0) {
904
if (virFileWriteStr(path, dev->name, 0) < 0) {
905
virReportSystemError(errno,
906
_("Failed to unbind PCI device '%s' from %s"),
911
dev->unbind_from_stub = 0;
914
if (!dev->remove_slot)
917
/* Xen's pciback.ko wants you to use remove_slot on the specific device */
918
if (pciDriverFile(&path, driver, "remove_slot") < 0) {
922
if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) {
923
virReportSystemError(errno,
924
_("Failed to remove slot for PCI device '%s' from %s"),
928
dev->remove_slot = 0;
936
/* Trigger a re-probe of the device is not in the stub's dynamic
937
* ID table. If the stub is available, but 'remove_id' isn't
938
* available, then re-probing would just cause the device to be
939
* re-bound to the stub.
941
if (pciDriverFile(&path, driver, "remove_id") < 0) {
945
if (!virFileExists(drvdir) || virFileExists(path)) {
946
if (virFileWriteStr(PCI_SYSFS "drivers_probe", dev->name, 0) < 0) {
947
virReportSystemError(errno,
948
_("Failed to trigger a re-probe for PCI device '%s'"),
957
/* do not do it again */
958
dev->unbind_from_stub = 0;
959
dev->remove_slot = 0;
970
pciBindDeviceToStub(pciDevice *dev, const char *driver)
977
/* check whether the device is already bound to a driver */
978
if (pciDriverDir(&drvdir, driver) < 0 ||
979
pciDeviceFile(&path, dev->name, "driver") < 0) {
983
if (virFileExists(path)) {
984
if (virFileLinkPointsTo(path, drvdir)) {
985
/* The device is already bound to pci-stub */
992
/* Add the PCI device ID to the stub's dynamic ID table;
993
* this is needed to allow us to bind the device to the stub.
994
* Note: if the device is not currently bound to any driver,
995
* stub will immediately be bound to the device. Also, note
996
* that if a new device with this ID is hotplugged, or if a probe
997
* is triggered for such a device, it will also be immediately
1000
if (pciDriverFile(&path, driver, "new_id") < 0) {
1004
if (virFileWriteStr(path, dev->id, 0) < 0) {
1005
virReportSystemError(errno,
1006
_("Failed to add PCI device ID '%s' to %s"),
1011
/* check whether the device is bound to pci-stub when we write dev->id to
1014
if (pciDriverDir(&drvdir, driver) < 0 ||
1015
pciDeviceFile(&path, dev->name, "driver") < 0) {
1019
if (virFileLinkPointsTo(path, drvdir)) {
1020
dev->unbind_from_stub = 1;
1021
dev->remove_slot = 1;
1025
/* If the device is already bound to a driver, unbind it.
1026
* Note, this will have rather unpleasant side effects if this
1027
* PCI device happens to be IDE controller for the disk hosting
1028
* your root filesystem.
1030
if (pciDeviceFile(&path, dev->name, "driver/unbind") < 0) {
1034
if (virFileExists(path)) {
1035
if (virFileWriteStr(path, dev->name, 0) < 0) {
1036
virReportSystemError(errno,
1037
_("Failed to unbind PCI device '%s'"),
1041
dev->reprobe = reprobe;
1044
/* If the device isn't already bound to pci-stub, try binding it now.
1046
if (pciDriverDir(&drvdir, driver) < 0 ||
1047
pciDeviceFile(&path, dev->name, "driver") < 0) {
1051
if (!virFileLinkPointsTo(path, drvdir)) {
1052
/* Xen's pciback.ko wants you to use new_slot first */
1053
if (pciDriverFile(&path, driver, "new_slot") < 0) {
1057
if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) {
1058
virReportSystemError(errno,
1059
_("Failed to add slot for PCI device '%s' to %s"),
1063
dev->remove_slot = 1;
1065
if (pciDriverFile(&path, driver, "bind") < 0) {
1069
if (virFileWriteStr(path, dev->name, 0) < 0) {
1070
virReportSystemError(errno,
1071
_("Failed to bind PCI device '%s' to %s"),
1075
dev->unbind_from_stub = 1;
1079
/* If 'remove_id' exists, remove the device id from pci-stub's dynamic
1080
* ID table so that 'drivers_probe' works below.
1082
if (pciDriverFile(&path, driver, "remove_id") < 0) {
1083
/* We do not remove PCI ID from pci-stub, and we cannot reprobe it */
1085
VIR_WARN("Could not remove PCI ID '%s' from %s, and the device "
1086
"cannot be probed again.", dev->id, driver);
1092
if (virFileExists(path) && virFileWriteStr(path, dev->id, 0) < 0) {
1093
virReportSystemError(errno,
1094
_("Failed to remove PCI ID '%s' from %s"),
1097
/* remove PCI ID from pci-stub failed, and we cannot reprobe it */
1099
VIR_WARN("Failed to remove PCI ID '%s' from %s, and the device "
1100
"cannot be probed again.", dev->id, driver);
1113
pciUnbindDeviceFromStub(dev, driver);
1120
pciDettachDevice(pciDevice *dev, pciDeviceList *activeDevs)
1122
const char *driver = pciFindStubDriver();
1124
pciReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1125
_("cannot find any PCI stub module"));
1129
if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
1130
pciReportError(VIR_ERR_INTERNAL_ERROR,
1131
_("Not detaching active device %s"), dev->name);
1135
return pciBindDeviceToStub(dev, driver);
1139
pciReAttachDevice(pciDevice *dev, pciDeviceList *activeDevs)
1141
const char *driver = pciFindStubDriver();
1143
pciReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1144
_("cannot find any PCI stub module"));
1148
if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
1149
pciReportError(VIR_ERR_INTERNAL_ERROR,
1150
_("Not reattaching active device %s"), dev->name);
1154
return pciUnbindDeviceFromStub(dev, driver);
1157
/* Certain hypervisors (like qemu/kvm) map the PCI bar(s) on
1158
* the host when doing device passthrough. This can lead to a race
1159
* condition where the hypervisor is still cleaning up the device while
1160
* libvirt is trying to re-attach it to the host device driver. To avoid
1161
* this situation, we look through /proc/iomem, and if the hypervisor is
1162
* still holding onto the bar (denoted by the string in the matcher variable),
1163
* then we can wait around a bit for that to clear up.
1165
* A typical /proc/iomem looks like this (snipped for brevity):
1166
* 00010000-0008efff : System RAM
1167
* 0008f000-0008ffff : reserved
1169
* 00100000-cc9fcfff : System RAM
1170
* 00200000-00483d3b : Kernel code
1171
* 00483d3c-005c88df : Kernel data
1172
* cc9fd000-ccc71fff : ACPI Non-volatile Storage
1174
* d0200000-d02fffff : PCI Bus #05
1175
* d0200000-d021ffff : 0000:05:00.0
1176
* d0200000-d021ffff : e1000e
1177
* d0220000-d023ffff : 0000:05:00.0
1178
* d0220000-d023ffff : e1000e
1180
* f0000000-f0003fff : 0000:00:1b.0
1181
* f0000000-f0003fff : kvm_assigned_device
1183
* Returns 0 if we are clear to continue, and 1 if the hypervisor is still
1184
* holding onto the resource.
1187
pciWaitForDeviceCleanup(pciDevice *dev, const char *matcher)
1192
unsigned long long start, end;
1193
unsigned int domain, bus, slot, function;
1194
int in_matching_device;
1198
fp = fopen("/proc/iomem", "r");
1200
/* If we failed to open iomem, we just basically ignore the error. The
1201
* unbind might succeed anyway, and besides, it's very likely we have
1202
* no way to report the error
1204
VIR_DEBUG("Failed to open /proc/iomem, trying to continue anyway");
1209
in_matching_device = 0;
1211
while (fgets(line, sizeof(line), fp) != 0) {
1212
/* the logic here is a bit confusing. For each line, we look to
1213
* see if it matches the domain:bus:slot.function we were given.
1214
* If this line matches the DBSF, then any subsequent lines indented
1215
* by 2 spaces are the PCI regions for this device. It's also
1216
* possible that none of the PCI regions are currently mapped, in
1217
* which case we have no indented regions. This code handles all
1218
* of these situations
1220
if (in_matching_device && (strspn(line, " ") == (match_depth + 2))) {
1221
/* expected format: <start>-<end> : <suffix> */
1223
virStrToLong_ull(line, &tmp, 16, &start) < 0 || *tmp != '-' ||
1225
virStrToLong_ull(tmp + 1, &tmp, 16, &end) < 0 ||
1226
(tmp = STRSKIP(tmp, " : ")) == NULL)
1229
if (STRPREFIX(tmp, matcher)) {
1235
in_matching_device = 0;
1237
/* expected format: <start>-<end> : <domain>:<bus>:<slot>.<function> */
1239
virStrToLong_ull(line, &tmp, 16, &start) < 0 || *tmp != '-' ||
1241
virStrToLong_ull(tmp + 1, &tmp, 16, &end) < 0 ||
1242
(tmp = STRSKIP(tmp, " : ")) == NULL ||
1244
virStrToLong_ui(tmp, &tmp, 16, &domain) < 0 || *tmp != ':' ||
1246
virStrToLong_ui(tmp + 1, &tmp, 16, &bus) < 0 || *tmp != ':' ||
1248
virStrToLong_ui(tmp + 1, &tmp, 16, &slot) < 0 || *tmp != '.' ||
1250
virStrToLong_ui(tmp + 1, &tmp, 16, &function) < 0 || *tmp != '\n')
1253
if (domain != dev->domain || bus != dev->bus || slot != dev->slot ||
1254
function != dev->function)
1256
in_matching_device = 1;
1257
match_depth = strspn(line, " ");
1261
VIR_FORCE_FCLOSE(fp);
1267
pciReadDeviceID(pciDevice *dev, const char *id_name)
1272
if (pciDeviceFile(&path, dev->name, id_name) < 0) {
1276
/* ID string is '0xNNNN\n' ... i.e. 7 bytes */
1277
if (virFileReadAll(path, 7, &id_str) < 0) {
1284
/* Check for 0x suffix */
1285
if (id_str[0] != '0' || id_str[1] != 'x') {
1290
/* Chop off the newline; we know the string is 7 bytes */
1297
pciGetDevice(unsigned domain,
1303
char *vendor = NULL;
1304
char *product = NULL;
1306
if (VIR_ALLOC(dev) < 0) {
1307
virReportOOMError();
1312
dev->domain = domain;
1315
dev->function = function;
1317
if (snprintf(dev->name, sizeof(dev->name), "%.4x:%.2x:%.2x.%.1x",
1318
dev->domain, dev->bus, dev->slot,
1319
dev->function) >= sizeof(dev->name)) {
1320
pciReportError(VIR_ERR_INTERNAL_ERROR,
1321
_("dev->name buffer overflow: %.4x:%.2x:%.2x.%.1x"),
1322
dev->domain, dev->bus, dev->slot, dev->function);
1325
if (virAsprintf(&dev->path, PCI_SYSFS "devices/%s/config",
1327
virReportOOMError();
1331
if (access(dev->path, F_OK) != 0) {
1332
virReportSystemError(errno,
1333
_("Device %s not found: could not access %s"),
1334
dev->name, dev->path);
1338
vendor = pciReadDeviceID(dev, "vendor");
1339
product = pciReadDeviceID(dev, "device");
1341
if (!vendor || !product) {
1342
pciReportError(VIR_ERR_INTERNAL_ERROR,
1343
_("Failed to read product/vendor ID for %s"),
1348
/* strings contain '0x' prefix */
1349
if (snprintf(dev->id, sizeof(dev->id), "%s %s", &vendor[2],
1350
&product[2]) >= sizeof(dev->id)) {
1351
pciReportError(VIR_ERR_INTERNAL_ERROR,
1352
_("dev->id buffer overflow: %s %s"),
1353
&vendor[2], &product[2]);
1357
VIR_DEBUG("%s %s: initialized", dev->id, dev->name);
1371
pciFreeDevice(pciDevice *dev)
1375
VIR_DEBUG("%s %s: freeing", dev->id, dev->name);
1376
pciCloseConfig(dev);
1377
VIR_FREE(dev->path);
1382
pciDeviceGetName(pciDevice *dev)
1387
void pciDeviceSetManaged(pciDevice *dev, unsigned managed)
1389
dev->managed = !!managed;
1392
unsigned pciDeviceGetManaged(pciDevice *dev)
1394
return dev->managed;
1398
pciDeviceGetUnbindFromStub(pciDevice *dev)
1400
return dev->unbind_from_stub;
1404
pciDeviceSetUnbindFromStub(pciDevice *dev, unsigned unbind)
1406
dev->unbind_from_stub = !!unbind;
1410
pciDeviceGetRemoveSlot(pciDevice *dev)
1412
return dev->remove_slot;
1416
pciDeviceSetRemoveSlot(pciDevice *dev, unsigned remove_slot)
1418
dev->remove_slot = !!remove_slot;
1422
pciDeviceGetReprobe(pciDevice *dev)
1424
return dev->reprobe;
1428
pciDeviceSetReprobe(pciDevice *dev, unsigned reprobe)
1430
dev->reprobe = !!reprobe;
1434
pciDeviceSetUsedBy(pciDevice *dev, const char *name)
1436
dev->used_by = name;
1440
pciDeviceGetUsedBy(pciDevice *dev)
1442
return dev->used_by;
1445
void pciDeviceReAttachInit(pciDevice *pci)
1447
pci->unbind_from_stub = 1;
1448
pci->remove_slot = 1;
1454
pciDeviceListNew(void)
1456
pciDeviceList *list;
1458
if (VIR_ALLOC(list) < 0) {
1459
virReportOOMError();
1467
pciDeviceListFree(pciDeviceList *list)
1474
for (i = 0; i < list->count; i++) {
1475
pciFreeDevice(list->devs[i]);
1476
list->devs[i] = NULL;
1480
VIR_FREE(list->devs);
1485
pciDeviceListAdd(pciDeviceList *list,
1488
if (pciDeviceListFind(list, dev)) {
1489
pciReportError(VIR_ERR_INTERNAL_ERROR,
1490
_("Device %s is already in use"), dev->name);
1494
if (VIR_REALLOC_N(list->devs, list->count+1) < 0) {
1495
virReportOOMError();
1499
list->devs[list->count++] = dev;
1505
pciDeviceListGet(pciDeviceList *list,
1508
if (idx >= list->count)
1513
return list->devs[idx];
1517
pciDeviceListCount(pciDeviceList *list)
1523
pciDeviceListSteal(pciDeviceList *list,
1526
pciDevice *ret = NULL;
1529
for (i = 0; i < list->count; i++) {
1530
if (list->devs[i]->domain != dev->domain ||
1531
list->devs[i]->bus != dev->bus ||
1532
list->devs[i]->slot != dev->slot ||
1533
list->devs[i]->function != dev->function)
1536
ret = list->devs[i];
1538
if (i != --list->count)
1539
memmove(&list->devs[i],
1541
sizeof(*list->devs) * (list->count-i));
1543
if (VIR_REALLOC_N(list->devs, list->count) < 0) {
1553
pciDeviceListDel(pciDeviceList *list,
1556
pciDevice *ret = pciDeviceListSteal(list, dev);
1562
pciDeviceListFind(pciDeviceList *list, pciDevice *dev)
1566
for (i = 0; i < list->count; i++)
1567
if (list->devs[i]->domain == dev->domain &&
1568
list->devs[i]->bus == dev->bus &&
1569
list->devs[i]->slot == dev->slot &&
1570
list->devs[i]->function == dev->function)
1571
return list->devs[i];
1576
int pciDeviceFileIterate(pciDevice *dev,
1577
pciDeviceFileActor actor,
1580
char *pcidir = NULL;
1586
if (virAsprintf(&pcidir, "/sys/bus/pci/devices/%04x:%02x:%02x.%x",
1587
dev->domain, dev->bus, dev->slot, dev->function) < 0) {
1588
virReportOOMError();
1592
if (!(dir = opendir(pcidir))) {
1593
virReportSystemError(errno,
1594
_("cannot open %s"), pcidir);
1598
while ((ent = readdir(dir)) != NULL) {
1599
/* Device assignment requires:
1600
* $PCIDIR/config, $PCIDIR/resource, $PCIDIR/resourceNNN,
1601
* $PCIDIR/rom, $PCIDIR/reset
1603
if (STREQ(ent->d_name, "config") ||
1604
STRPREFIX(ent->d_name, "resource") ||
1605
STREQ(ent->d_name, "rom") ||
1606
STREQ(ent->d_name, "reset")) {
1607
if (virAsprintf(&file, "%s/%s", pcidir, ent->d_name) < 0) {
1608
virReportOOMError();
1611
if ((actor)(dev, file, opaque) < 0)
1629
pciDeviceDownstreamLacksACS(pciDevice *dev)
1635
if (!dev->initted && pciInitDevice(dev) < 0)
1638
pos = dev->pcie_cap_pos;
1639
if (!pos || pciRead16(dev, PCI_CLASS_DEVICE) != PCI_CLASS_BRIDGE_PCI)
1642
flags = pciRead16(dev, pos + PCI_EXP_FLAGS);
1643
if (((flags & PCI_EXP_FLAGS_TYPE) >> 4) != PCI_EXP_TYPE_DOWNSTREAM)
1646
pos = pciFindExtendedCapabilityOffset(dev, PCI_EXT_CAP_ID_ACS);
1648
VIR_DEBUG("%s %s: downstream port lacks ACS", dev->id, dev->name);
1652
ctrl = pciRead16(dev, pos + PCI_EXT_ACS_CTRL);
1653
if ((ctrl & PCI_EXT_CAP_ACS_ENABLED) != PCI_EXT_CAP_ACS_ENABLED) {
1654
VIR_DEBUG("%s %s: downstream port has ACS disabled",
1655
dev->id, dev->name);
1663
pciDeviceIsBehindSwitchLackingACS(pciDevice *dev)
1667
if (pciGetParentDevice(dev, &parent) < 0)
1670
/* if we have no parent, and this is the root bus, ACS doesn't come
1671
* into play since devices on the root bus can't P2P without going
1672
* through the root IOMMU.
1677
pciReportError(VIR_ERR_INTERNAL_ERROR,
1678
_("Failed to find parent device for %s"),
1684
/* XXX we should rather fail when we can't find device's parent and
1685
* stop the loop when we get to root instead of just stopping when no
1686
* parent can be found
1693
acs = pciDeviceDownstreamLacksACS(parent);
1696
pciFreeDevice(parent);
1704
ret = pciGetParentDevice(parent, &parent);
1713
int pciDeviceIsAssignable(pciDevice *dev,
1714
int strict_acs_check)
1718
/* XXX This could be a great place to actually check that a non-managed
1719
* device isn't in use, e.g. by checking that device is either un-bound
1720
* or bound to a stub driver.
1723
ret = pciDeviceIsBehindSwitchLackingACS(dev);
1728
if (!strict_acs_check) {
1729
VIR_DEBUG("%s %s: strict ACS check disabled; device assignment allowed",
1730
dev->id, dev->name);
1732
pciReportError(VIR_ERR_INTERNAL_ERROR,
1733
_("Device %s is behind a switch lacking ACS and "
1734
"cannot be assigned"),
1746
* returns true if equal
1749
pciConfigAddressEqual(struct pci_config_address *bdf1,
1750
struct pci_config_address *bdf2)
1752
return ((bdf1->domain == bdf2->domain) &&
1753
(bdf1->bus == bdf2->bus) &&
1754
(bdf1->slot == bdf2->slot) &&
1755
(bdf1->function == bdf2->function));
1759
logStrToLong_ui(char const *s,
1762
unsigned int *result)
1766
ret = virStrToLong_ui(s, end_ptr, base, result);
1768
VIR_ERROR(_("Failed to convert '%s' to unsigned int"), s);
1770
VIR_DEBUG("Converted '%s' to unsigned int %u", s, *result);
1777
pciParsePciConfigAddress(char *address,
1778
struct pci_config_address *bdf)
1783
if ((address == NULL) || (logStrToLong_ui(address, &p, 16,
1784
&bdf->domain) == -1)) {
1788
if ((p == NULL) || (logStrToLong_ui(p+1, &p, 16,
1789
&bdf->bus) == -1)) {
1793
if ((p == NULL) || (logStrToLong_ui(p+1, &p, 16,
1794
&bdf->slot) == -1)) {
1798
if ((p == NULL) || (logStrToLong_ui(p+1, &p, 16,
1799
&bdf->function) == -1)) {
1810
pciGetPciConfigAddressFromSysfsDeviceLink(const char *device_link,
1811
struct pci_config_address **bdf)
1813
char *config_address = NULL;
1814
char *device_path = NULL;
1818
VIR_DEBUG("Attempting to resolve device path from device link '%s'",
1821
if (!virFileExists(device_link)) {
1822
VIR_DEBUG("sysfs_path '%s' does not exist", device_link);
1826
device_path = canonicalize_file_name (device_link);
1827
if (device_path == NULL) {
1828
memset(errbuf, '\0', sizeof(errbuf));
1829
pciReportError(VIR_ERR_INTERNAL_ERROR,
1830
_("Failed to resolve device link '%s': '%s'"),
1831
device_link, virStrerror(errno, errbuf,
1836
config_address = basename(device_path);
1837
if (VIR_ALLOC(*bdf) != 0) {
1838
virReportOOMError();
1842
if (pciParsePciConfigAddress(config_address, *bdf) != 0) {
1843
pciReportError(VIR_ERR_INTERNAL_ERROR,
1844
_("Failed to parse PCI config address '%s'"),
1850
VIR_DEBUG("pci_config_address %.4x:%.2x:%.2x.%.1x",
1859
VIR_FREE(device_path);
1865
* Returns Physical function given a virtual function
1868
pciGetPhysicalFunction(const char *vf_sysfs_path,
1869
struct pci_config_address **physical_function)
1872
char *device_link = NULL;
1874
VIR_DEBUG("Attempting to get SR IOV physical function for device "
1875
"with sysfs path '%s'", vf_sysfs_path);
1877
if (virBuildPath(&device_link, vf_sysfs_path, "physfn") == -1) {
1878
virReportOOMError();
1881
ret = pciGetPciConfigAddressFromSysfsDeviceLink(device_link,
1885
VIR_FREE(device_link);
1891
* Returns virtual functions of a physical function
1894
pciGetVirtualFunctions(const char *sysfs_path,
1895
struct pci_config_address ***virtual_functions,
1896
unsigned int *num_virtual_functions)
1900
struct dirent *entry = NULL;
1901
char *device_link = NULL;
1904
VIR_DEBUG("Attempting to get SR IOV virtual functions for device"
1905
"with sysfs path '%s'", sysfs_path);
1907
dir = opendir(sysfs_path);
1909
memset(errbuf, '\0', sizeof(errbuf));
1910
pciReportError(VIR_ERR_INTERNAL_ERROR,
1911
_("Failed to open dir '%s': '%s'"),
1912
sysfs_path, virStrerror(errno, errbuf,
1917
*virtual_functions = NULL;
1918
*num_virtual_functions = 0;
1919
while ((entry = readdir(dir))) {
1920
if (STRPREFIX(entry->d_name, "virtfn")) {
1922
if (virBuildPath(&device_link, sysfs_path, entry->d_name) == -1) {
1923
virReportOOMError();
1927
VIR_DEBUG("Number of virtual functions: %d",
1928
*num_virtual_functions);
1929
if (VIR_REALLOC_N(*virtual_functions,
1930
(*num_virtual_functions) + 1) != 0) {
1931
virReportOOMError();
1932
VIR_FREE(device_link);
1936
if (pciGetPciConfigAddressFromSysfsDeviceLink(device_link,
1937
&((*virtual_functions)[*num_virtual_functions])) !=
1939
/* We should not get back SRIOV_NOT_FOUND in this
1940
* case, so if we do, it's an error. */
1941
pciReportError(VIR_ERR_INTERNAL_ERROR,
1942
_("Failed to get SR IOV function from device "
1943
"link '%s'"), device_link);
1944
VIR_FREE(device_link);
1947
(*num_virtual_functions)++;
1949
VIR_FREE(device_link);
1963
* Returns 1 if vf device is a virtual function, 0 if not, -1 on error
1966
pciDeviceIsVirtualFunction(const char *vf_sysfs_device_link)
1968
char *vf_sysfs_physfn_link = NULL;
1971
if (virAsprintf(&vf_sysfs_physfn_link, "%s/physfn",
1972
vf_sysfs_device_link) < 0) {
1973
virReportOOMError();
1977
ret = virFileExists(vf_sysfs_physfn_link);
1979
VIR_FREE(vf_sysfs_physfn_link);
1985
* Returns the sriov virtual function index of vf given its pf
1988
pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
1989
const char *vf_sysfs_device_link,
1993
unsigned int num_virt_fns = 0;
1994
struct pci_config_address *vf_bdf = NULL;
1995
struct pci_config_address **virt_fns = NULL;
1997
if (pciGetPciConfigAddressFromSysfsDeviceLink(vf_sysfs_device_link,
2001
if (pciGetVirtualFunctions(pf_sysfs_device_link, &virt_fns,
2002
&num_virt_fns) < 0) {
2003
pciReportError(VIR_ERR_INTERNAL_ERROR,
2004
_("Error getting physical function's '%s' "
2005
"virtual_functions"), pf_sysfs_device_link);
2009
for (i = 0; i < num_virt_fns; i++) {
2010
if (pciConfigAddressEqual(vf_bdf, virt_fns[i])) {
2019
/* free virtual functions */
2020
for (i = 0; i < num_virt_fns; i++)
2021
VIR_FREE(virt_fns[i]);
2030
* Returns the network device name of a pci device
2033
pciDeviceNetName(char *device_link_sysfs_path, char **netname)
2035
char *pcidev_sysfs_net_path = NULL;
2038
struct dirent *entry = NULL;
2040
if (virBuildPath(&pcidev_sysfs_net_path, device_link_sysfs_path,
2042
virReportOOMError();
2046
dir = opendir(pcidev_sysfs_net_path);
2050
while ((entry = readdir(dir))) {
2051
if (STREQ(entry->d_name, ".") ||
2052
STREQ(entry->d_name, ".."))
2055
/* Assume a single directory entry */
2056
*netname = strdup(entry->d_name);
2058
virReportOOMError();
2067
VIR_FREE(pcidev_sysfs_net_path);
2073
pciGetPhysicalFunction(const char *vf_sysfs_path ATTRIBUTE_UNUSED,
2074
struct pci_config_address **physical_function ATTRIBUTE_UNUSED)
2076
pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciGetPhysicalFunction is not "
2077
"supported on non-linux platforms"));
2082
pciGetVirtualFunctions(const char *sysfs_path ATTRIBUTE_UNUSED,
2083
struct pci_config_address ***virtual_functions ATTRIBUTE_UNUSED,
2084
unsigned int *num_virtual_functions ATTRIBUTE_UNUSED)
2086
pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciGetVirtualFunctions is not "
2087
"supported on non-linux platforms"));
2092
pciDeviceIsVirtualFunction(const char *vf_sysfs_device_link ATTRIBUTE_UNUSED)
2094
pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciDeviceIsVirtualFunction is "
2095
"not supported on non-linux platforms"));
2100
pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link ATTRIBUTE_UNUSED,
2101
const char *vf_sysfs_device_link ATTRIBUTE_UNUSED,
2102
int *vf_index ATTRIBUTE_UNUSED)
2104
pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciGetVirtualFunctionIndex is "
2105
"not supported on non-linux platforms"));
2111
pciDeviceNetName(char *device_link_sysfs_path ATTRIBUTE_UNUSED,
2112
char **netname ATTRIBUTE_UNUSED)
2114
pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciDeviceNetName is not "
2115
"supported on non-linux platforms"));
2118
#endif /* __linux__ */