~serge-hallyn/ubuntu/raring/libvirt/libvirt-hugepages

« back to all changes in this revision

Viewing changes to .pc/ubuntu/9020-lp545795.patch/src/util/pci.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-05-13 15:44:12 UTC
  • mfrom: (1.2.13)
  • Revision ID: package-import@ubuntu.com-20120513154412-fgmn5sxqdzgnzlx3
Tags: 0.9.12-0ubuntu1
* New upstream version:
  * Synchronize with debian packaging:
    - debian/control: Update build depends.
    - debian/libvirt-bin.postrm: Cleanup /var/log/libvirt
      on purge.
    - Bump standards verson (no changes).
    - debian/patches/Don-t-fail-if-we-can-t-setup-avahi.patch: Added
  * Dropped patches:
    - debian/patches/Debianize-libvirt-guests.patch
    - debian/patches/rewrite-lxc-controller-eof-handling-yet-again
    - debian/patches/ubuntu/libnl13.patch
    - debian/patches/ubuntu/fix-lxc-startup-error.patch
    - debian/patches/ubuntu/fix-bridge-fd.patch
    - debian/patches/ubuntu/skip-labelling-network-disks.patch
    - debian/patches/ubuntu/xen-xend-shutdown-detection.patch
    - debian/patches/ubuntu/xen-config-no-vfb-for-hvm.patch
    - debian/patches/debian/Disable-daemon-start-test.patch
    - debian/patches/debian/Disable-gnulib-s-test-nonplocking-pipe.sh.patch
    - debian/patches/ubuntu/9006-default-config-test-case.patch
    - debian/patches/fix-block-migration.patch
    - debian/patches/ubuntu/9022-qemu-unescape-HMP-commands-before-converting-them-to.patch
    - debian/patches/ubuntu/9023-qemu-change-rbd-auth_supported-separation-character-.patch
    - debian/patches/ubuntu/9024-qemu-allow-snapshotting-of-sheepdog-and-rbd-disks.patch
    - debian/patches/9025-qemu-change-rbd-auth_supported-separation-character-.patch
    - debian/patches/ubuntu/arm-gcc-workaround.patch
  * Rediffed:
    - debian/patches/Allow-libvirt-group-to-access-the-socket.patch
    - debian/patches/Disable-failing-virnetsockettest.patch
    - debian/patches/dnsmasq-as-priv-user
    - debian/patches/9002-better_default_uri_virsh.patch
  * debian/control: Add libnl-route-3-dev ass a build depends.
  * debian/patches/libnl3-build-fix.patch: Fix build with libnl3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2009-2011 Red Hat, Inc.
3
 
 *
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.
8
 
 *
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.
13
 
 *
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
17
 
 *
18
 
 * Authors:
19
 
 *     Mark McLoughlin <markmc@redhat.com>
20
 
 */
21
 
 
22
 
#include <config.h>
23
 
 
24
 
#include "pci.h"
25
 
 
26
 
#include <dirent.h>
27
 
#include <fcntl.h>
28
 
#include <inttypes.h>
29
 
#include <limits.h>
30
 
#include <stdio.h>
31
 
#include <string.h>
32
 
#include <sys/types.h>
33
 
#include <sys/stat.h>
34
 
#include <unistd.h>
35
 
#include <stdlib.h>
36
 
 
37
 
#include "logging.h"
38
 
#include "memory.h"
39
 
#include "command.h"
40
 
#include "virterror_internal.h"
41
 
#include "virfile.h"
42
 
 
43
 
/* avoid compilation breakage on some systems */
44
 
#ifndef MODPROBE
45
 
# define MODPROBE "modprobe"
46
 
#endif
47
 
 
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" */
51
 
 
52
 
#define SRIOV_FOUND 0
53
 
#define SRIOV_NOT_FOUND 1
54
 
#define SRIOV_ERROR -1
55
 
 
56
 
struct _pciDevice {
57
 
    unsigned      domain;
58
 
    unsigned      bus;
59
 
    unsigned      slot;
60
 
    unsigned      function;
61
 
 
62
 
    char          name[PCI_ADDR_LEN]; /* domain:bus:slot.function */
63
 
    char          id[PCI_ID_LEN];     /* product vendor */
64
 
    char          *path;
65
 
    const char    *used_by;           /* The domain which uses the device */
66
 
    int           fd;
67
 
 
68
 
    unsigned      initted;
69
 
    unsigned      pcie_cap_pos;
70
 
    unsigned      pci_pm_cap_pos;
71
 
    unsigned      has_flr : 1;
72
 
    unsigned      has_pm_reset : 1;
73
 
    unsigned      managed : 1;
74
 
 
75
 
    /* used by reattach function */
76
 
    unsigned      unbind_from_stub : 1;
77
 
    unsigned      remove_slot : 1;
78
 
    unsigned      reprobe : 1;
79
 
};
80
 
 
81
 
struct _pciDeviceList {
82
 
    unsigned count;
83
 
    pciDevice **devs;
84
 
};
85
 
 
86
 
 
87
 
/* For virReportOOMError()  and virReportSystemError() */
88
 
#define VIR_FROM_THIS VIR_FROM_NONE
89
 
 
90
 
#define pciReportError(code, ...)                              \
91
 
    virReportErrorHelper(VIR_FROM_NONE, code, __FILE__,        \
92
 
                         __FUNCTION__, __LINE__, __VA_ARGS__)
93
 
 
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
100
 
 */
101
 
 
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
105
 
 
106
 
/* PCI30 6.2.1 */
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
111
 
 
112
 
/* PCI30 6.2.1  Device Identification */
113
 
#define PCI_CLASS_DEVICE        0x0a    /* Device class */
114
 
 
115
 
/* Class Code for bridge; PCI30 D.7  Base Class 06h */
116
 
#define PCI_CLASS_BRIDGE_PCI    0x0604
117
 
 
118
 
/* PCI30 6.2.3  Device Status */
119
 
#define PCI_STATUS              0x06    /* 16 bits */
120
 
#define PCI_STATUS_CAP_LIST    0x10    /* Support Capability List */
121
 
 
122
 
/* PCI30 6.7  Capabilities List */
123
 
#define PCI_CAPABILITY_LIST     0x34    /* Offset of first capability list entry */
124
 
 
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 */
131
 
 
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 */
135
 
 
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 */
143
 
 
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 */
150
 
 
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 */
154
 
 
155
 
#define PCI_EXP_FLAGS           0x2
156
 
#define PCI_EXP_FLAGS_TYPE      0x00f0
157
 
#define PCI_EXP_TYPE_DOWNSTREAM 0x6
158
 
 
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
164
 
 
165
 
#define PCI_EXT_CAP_ID_ACS      0x000d
166
 
#define PCI_EXT_ACS_CTRL        0x06
167
 
 
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 | \
175
 
                                 PCI_EXT_CAP_ACS_UF)
176
 
 
177
 
static int
178
 
pciOpenConfig(pciDevice *dev)
179
 
{
180
 
    int fd;
181
 
 
182
 
    if (dev->fd > 0)
183
 
        return 0;
184
 
 
185
 
    fd = open(dev->path, O_RDWR);
186
 
    if (fd < 0) {
187
 
        char ebuf[1024];
188
 
        VIR_WARN("Failed to open config space file '%s': %s",
189
 
                 dev->path, virStrerror(errno, ebuf, sizeof(ebuf)));
190
 
        return -1;
191
 
    }
192
 
    VIR_DEBUG("%s %s: opened %s", dev->id, dev->name, dev->path);
193
 
    dev->fd = fd;
194
 
    return 0;
195
 
}
196
 
 
197
 
static void
198
 
pciCloseConfig(pciDevice *dev)
199
 
{
200
 
    if (!dev)
201
 
        return;
202
 
 
203
 
    VIR_FORCE_CLOSE(dev->fd);
204
 
}
205
 
 
206
 
static int
207
 
pciRead(pciDevice *dev, unsigned pos, uint8_t *buf, unsigned buflen)
208
 
{
209
 
    memset(buf, 0, buflen);
210
 
 
211
 
    if (pciOpenConfig(dev) < 0)
212
 
        return -1;
213
 
 
214
 
    if (lseek(dev->fd, pos, SEEK_SET) != pos ||
215
 
        saferead(dev->fd, buf, buflen) != buflen) {
216
 
        char ebuf[1024];
217
 
        VIR_WARN("Failed to read from '%s' : %s", dev->path,
218
 
                 virStrerror(errno, ebuf, sizeof(ebuf)));
219
 
        return -1;
220
 
    }
221
 
    return 0;
222
 
}
223
 
 
224
 
static uint8_t
225
 
pciRead8(pciDevice *dev, unsigned pos)
226
 
{
227
 
    uint8_t buf;
228
 
    pciRead(dev, pos, &buf, sizeof(buf));
229
 
    return buf;
230
 
}
231
 
 
232
 
static uint16_t
233
 
pciRead16(pciDevice *dev, unsigned pos)
234
 
{
235
 
    uint8_t buf[2];
236
 
    pciRead(dev, pos, &buf[0], sizeof(buf));
237
 
    return (buf[0] << 0) | (buf[1] << 8);
238
 
}
239
 
 
240
 
static uint32_t
241
 
pciRead32(pciDevice *dev, unsigned pos)
242
 
{
243
 
    uint8_t buf[4];
244
 
    pciRead(dev, pos, &buf[0], sizeof(buf));
245
 
    return (buf[0] << 0) | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
246
 
}
247
 
 
248
 
static int
249
 
pciWrite(pciDevice *dev, unsigned pos, uint8_t *buf, unsigned buflen)
250
 
{
251
 
    if (pciOpenConfig(dev) < 0)
252
 
        return -1;
253
 
 
254
 
    if (lseek(dev->fd, pos, SEEK_SET) != pos ||
255
 
        safewrite(dev->fd, buf, buflen) != buflen) {
256
 
        char ebuf[1024];
257
 
        VIR_WARN("Failed to write to '%s' : %s", dev->path,
258
 
                 virStrerror(errno, ebuf, sizeof(ebuf)));
259
 
        return -1;
260
 
    }
261
 
    return 0;
262
 
}
263
 
 
264
 
static void
265
 
pciWrite16(pciDevice *dev, unsigned pos, uint16_t val)
266
 
{
267
 
    uint8_t buf[2] = { (val >> 0), (val >> 8) };
268
 
    pciWrite(dev, pos, &buf[0], sizeof(buf));
269
 
}
270
 
 
271
 
static void
272
 
pciWrite32(pciDevice *dev, unsigned pos, uint32_t val)
273
 
{
274
 
    uint8_t buf[4] = { (val >> 0), (val >> 8), (val >> 16), (val >> 14) };
275
 
    pciWrite(dev, pos, &buf[0], sizeof(buf));
276
 
}
277
 
 
278
 
typedef int (*pciIterPredicate)(pciDevice *, pciDevice *, void *);
279
 
 
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.
284
 
 */
285
 
static int
286
 
pciIterDevices(pciIterPredicate predicate,
287
 
               pciDevice *dev,
288
 
               pciDevice **matched,
289
 
               void *data)
290
 
{
291
 
    DIR *dir;
292
 
    struct dirent *entry;
293
 
    int ret = 0;
294
 
    int rc;
295
 
 
296
 
    *matched = NULL;
297
 
 
298
 
    VIR_DEBUG("%s %s: iterating over " PCI_SYSFS "devices", dev->id, dev->name);
299
 
 
300
 
    dir = opendir(PCI_SYSFS "devices");
301
 
    if (!dir) {
302
 
        VIR_WARN("Failed to open " PCI_SYSFS "devices");
303
 
        return -1;
304
 
    }
305
 
 
306
 
    while ((entry = readdir(dir))) {
307
 
        unsigned int domain, bus, slot, function;
308
 
        pciDevice *check;
309
 
        char *tmp;
310
 
 
311
 
        /* Ignore '.' and '..' */
312
 
        if (entry->d_name[0] == '.')
313
 
            continue;
314
 
 
315
 
        /* expected format: <domain>:<bus>:<slot>.<function> */
316
 
        if (/* domain */
317
 
            virStrToLong_ui(entry->d_name, &tmp, 16, &domain) < 0 || *tmp != ':' ||
318
 
            /* bus */
319
 
            virStrToLong_ui(tmp + 1, &tmp, 16, &bus) < 0 || *tmp != ':' ||
320
 
            /* slot */
321
 
            virStrToLong_ui(tmp + 1, &tmp, 16, &slot) < 0 || *tmp != '.' ||
322
 
            /* function */
323
 
            virStrToLong_ui(tmp + 1, NULL, 16, &function) < 0) {
324
 
            VIR_WARN("Unusual entry in " PCI_SYSFS "devices: %s", entry->d_name);
325
 
            continue;
326
 
        }
327
 
 
328
 
        check = pciGetDevice(domain, bus, slot, function);
329
 
        if (!check) {
330
 
            ret = -1;
331
 
            break;
332
 
        }
333
 
 
334
 
        rc = predicate(dev, check, data);
335
 
        if (rc < 0) {
336
 
            /* the predicate returned an error, bail */
337
 
            pciFreeDevice(check);
338
 
            ret = -1;
339
 
            break;
340
 
        }
341
 
        else if (rc == 1) {
342
 
            VIR_DEBUG("%s %s: iter matched on %s", dev->id, dev->name, check->name);
343
 
            *matched = check;
344
 
            ret = 1;
345
 
            break;
346
 
        }
347
 
 
348
 
        pciFreeDevice(check);
349
 
    }
350
 
    closedir(dir);
351
 
    return ret;
352
 
}
353
 
 
354
 
static uint8_t
355
 
pciFindCapabilityOffset(pciDevice *dev, unsigned capability)
356
 
{
357
 
    uint16_t status;
358
 
    uint8_t pos;
359
 
 
360
 
    status = pciRead16(dev, PCI_STATUS);
361
 
    if (!(status & PCI_STATUS_CAP_LIST))
362
 
        return 0;
363
 
 
364
 
    pos = pciRead8(dev, PCI_CAPABILITY_LIST);
365
 
 
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
369
 
     *
370
 
     * Note: we're not handling loops or extended
371
 
     * capabilities here.
372
 
     */
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);
378
 
            return pos;
379
 
        }
380
 
 
381
 
        pos = pciRead8(dev, pos + 1);
382
 
    }
383
 
 
384
 
    VIR_DEBUG("%s %s: failed to find cap 0x%.2x", dev->id, dev->name, capability);
385
 
 
386
 
    return 0;
387
 
}
388
 
 
389
 
static unsigned int
390
 
pciFindExtendedCapabilityOffset(pciDevice *dev, unsigned capability)
391
 
{
392
 
    int ttl;
393
 
    unsigned int pos;
394
 
    uint32_t header;
395
 
 
396
 
    /* minimum 8 bytes per capability */
397
 
    ttl = (PCI_EXT_CAP_LIMIT - PCI_EXT_CAP_BASE) / 8;
398
 
    pos = PCI_EXT_CAP_BASE;
399
 
 
400
 
    while (ttl > 0 && pos >= PCI_EXT_CAP_BASE) {
401
 
        header = pciRead32(dev, pos);
402
 
 
403
 
        if ((header & PCI_EXT_CAP_ID_MASK) == capability)
404
 
            return pos;
405
 
 
406
 
        pos = (header >> PCI_EXT_CAP_OFFSET_SHIFT) & PCI_EXT_CAP_OFFSET_MASK;
407
 
        ttl--;
408
 
    }
409
 
 
410
 
    return 0;
411
 
}
412
 
 
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
415
 
 */
416
 
static int
417
 
pciDetectFunctionLevelReset(pciDevice *dev)
418
 
{
419
 
    uint32_t caps;
420
 
    uint8_t pos;
421
 
    char *path;
422
 
    int found;
423
 
 
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.
429
 
     */
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);
434
 
            return 1;
435
 
        }
436
 
    }
437
 
 
438
 
    /* The PCI AF Function Level Reset capability is
439
 
     * the same thing, except for conventional PCI
440
 
     * devices. This is not common yet.
441
 
     */
442
 
    pos = pciFindCapabilityOffset(dev, PCI_CAP_ID_AF);
443
 
    if (pos) {
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);
447
 
            return 1;
448
 
        }
449
 
    }
450
 
 
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
455
 
     */
456
 
 
457
 
    if (virAsprintf(&path, PCI_SYSFS "devices/%s/physfn", dev->name) < 0) {
458
 
        virReportOOMError();
459
 
        return -1;
460
 
    }
461
 
 
462
 
    found = virFileExists(path);
463
 
    VIR_FREE(path);
464
 
    if (found) {
465
 
        VIR_DEBUG("%s %s: buggy device didn't advertise FLR, but is a VF; forcing flr on",
466
 
                  dev->id, dev->name);
467
 
        return 1;
468
 
    }
469
 
 
470
 
    VIR_DEBUG("%s %s: no FLR capability found", dev->id, dev->name);
471
 
 
472
 
    return 0;
473
 
}
474
 
 
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.
478
 
 */
479
 
static unsigned
480
 
pciDetectPowerManagementReset(pciDevice *dev)
481
 
{
482
 
    if (dev->pci_pm_cap_pos) {
483
 
        uint32_t ctl;
484
 
 
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);
489
 
            return 1;
490
 
        }
491
 
    }
492
 
 
493
 
    VIR_DEBUG("%s %s: no PM reset capability found", dev->id, dev->name);
494
 
 
495
 
    return 0;
496
 
}
497
 
 
498
 
/* Any active devices on the same domain/bus ? */
499
 
static int
500
 
pciSharesBusWithActive(pciDevice *dev, pciDevice *check, void *data)
501
 
{
502
 
    pciDeviceList *inactiveDevs = data;
503
 
 
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))
509
 
        return 0;
510
 
 
511
 
    /* same bus, but inactive, i.e. about to be assigned to guest */
512
 
    if (inactiveDevs && pciDeviceListFind(inactiveDevs, check))
513
 
        return 0;
514
 
 
515
 
    return 1;
516
 
}
517
 
 
518
 
static pciDevice *
519
 
pciBusContainsActiveDevices(pciDevice *dev,
520
 
                            pciDeviceList *inactiveDevs)
521
 
{
522
 
    pciDevice *active = NULL;
523
 
    if (pciIterDevices(pciSharesBusWithActive,
524
 
                       dev, &active, inactiveDevs) < 0)
525
 
        return NULL;
526
 
    return active;
527
 
}
528
 
 
529
 
/* Is @check the parent of @dev ? */
530
 
static int
531
 
pciIsParent(pciDevice *dev, pciDevice *check, void *data)
532
 
{
533
 
    uint16_t device_class;
534
 
    uint8_t header_type, secondary, subordinate;
535
 
    pciDevice **best = data;
536
 
 
537
 
    if (dev->domain != check->domain)
538
 
        return 0;
539
 
 
540
 
    /* Is it a bridge? */
541
 
    device_class = pciRead16(check, PCI_CLASS_DEVICE);
542
 
    if (device_class != PCI_CLASS_BRIDGE_PCI)
543
 
        return 0;
544
 
 
545
 
    /* Is it a plane? */
546
 
    header_type = pciRead8(check, PCI_HEADER_TYPE);
547
 
    if ((header_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE)
548
 
        return 0;
549
 
 
550
 
    secondary   = pciRead8(check, PCI_SECONDARY_BUS);
551
 
    subordinate = pciRead8(check, PCI_SUBORDINATE_BUS);
552
 
 
553
 
    VIR_DEBUG("%s %s: found parent device %s", dev->id, dev->name, check->name);
554
 
 
555
 
    /* if the secondary bus exactly equals the device's bus, then we found
556
 
     * the direct parent.  No further work is necessary
557
 
     */
558
 
    if (dev->bus == secondary)
559
 
        return 1;
560
 
 
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.
564
 
     */
565
 
    if (dev->bus > secondary && dev->bus <= subordinate) {
566
 
        if (*best == NULL) {
567
 
            *best = pciGetDevice(check->domain, check->bus, check->slot,
568
 
                                 check->function);
569
 
            if (*best == NULL)
570
 
                return -1;
571
 
        }
572
 
        else {
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
576
 
             */
577
 
            if (secondary > pciRead8(*best, PCI_SECONDARY_BUS)) {
578
 
                pciFreeDevice(*best);
579
 
                *best = pciGetDevice(check->domain, check->bus, check->slot,
580
 
                                     check->function);
581
 
                if (*best == NULL)
582
 
                    return -1;
583
 
            }
584
 
        }
585
 
    }
586
 
 
587
 
    return 0;
588
 
}
589
 
 
590
 
static int
591
 
pciGetParentDevice(pciDevice *dev, pciDevice **parent)
592
 
{
593
 
    pciDevice *best = NULL;
594
 
    int ret;
595
 
 
596
 
    *parent = NULL;
597
 
    ret = pciIterDevices(pciIsParent, dev, parent, &best);
598
 
    if (ret == 1)
599
 
        pciFreeDevice(best);
600
 
    else if (ret == 0)
601
 
        *parent = best;
602
 
    return ret;
603
 
}
604
 
 
605
 
/* Secondary Bus Reset is our sledgehammer - it resets all
606
 
 * devices behind a bus.
607
 
 */
608
 
static int
609
 
pciTrySecondaryBusReset(pciDevice *dev,
610
 
                        pciDeviceList *inactiveDevs)
611
 
{
612
 
    pciDevice *parent, *conflict;
613
 
    uint8_t config_space[PCI_CONF_LEN];
614
 
    uint16_t ctl;
615
 
    int ret = -1;
616
 
 
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.
621
 
     */
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);
626
 
        return -1;
627
 
    }
628
 
 
629
 
    /* Find the parent bus */
630
 
    if (pciGetParentDevice(dev, &parent) < 0)
631
 
        return -1;
632
 
    if (!parent) {
633
 
        pciReportError(VIR_ERR_INTERNAL_ERROR,
634
 
                       _("Failed to find parent device for %s"),
635
 
                       dev->name);
636
 
        return -1;
637
 
    }
638
 
 
639
 
    VIR_DEBUG("%s %s: doing a secondary bus reset", dev->id, dev->name);
640
 
 
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
644
 
     */
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"),
648
 
                       dev->name);
649
 
        goto out;
650
 
    }
651
 
 
652
 
    /* Read the control register, set the reset flag, wait 200ms,
653
 
     * unset the reset flag and wait 200ms.
654
 
     */
655
 
    ctl = pciRead16(dev, PCI_BRIDGE_CONTROL);
656
 
 
657
 
    pciWrite16(parent, PCI_BRIDGE_CONTROL, ctl | PCI_BRIDGE_CTL_RESET);
658
 
 
659
 
    usleep(200 * 1000); /* sleep 200ms */
660
 
 
661
 
    pciWrite16(parent, PCI_BRIDGE_CONTROL, ctl);
662
 
 
663
 
    usleep(200 * 1000); /* sleep 200ms */
664
 
 
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"),
668
 
                       dev->name);
669
 
        goto out;
670
 
    }
671
 
    ret = 0;
672
 
out:
673
 
    pciFreeDevice(parent);
674
 
    return ret;
675
 
}
676
 
 
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.
680
 
 */
681
 
static int
682
 
pciTryPowerManagementReset(pciDevice *dev)
683
 
{
684
 
    uint8_t config_space[PCI_CONF_LEN];
685
 
    uint32_t ctl;
686
 
 
687
 
    if (!dev->pci_pm_cap_pos)
688
 
        return -1;
689
 
 
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"),
694
 
                       dev->name);
695
 
        return -1;
696
 
    }
697
 
 
698
 
    VIR_DEBUG("%s %s: doing a power management reset", dev->id, dev->name);
699
 
 
700
 
    ctl = pciRead32(dev, dev->pci_pm_cap_pos + PCI_PM_CTRL);
701
 
    ctl &= ~PCI_PM_CTRL_STATE_MASK;
702
 
 
703
 
    pciWrite32(dev, dev->pci_pm_cap_pos + PCI_PM_CTRL, ctl|PCI_PM_CTRL_STATE_D3hot);
704
 
 
705
 
    usleep(10 * 1000); /* sleep 10ms */
706
 
 
707
 
    pciWrite32(dev, dev->pci_pm_cap_pos + PCI_PM_CTRL, ctl|PCI_PM_CTRL_STATE_D0);
708
 
 
709
 
    usleep(10 * 1000); /* sleep 10ms */
710
 
 
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"),
714
 
                       dev->name);
715
 
        return -1;
716
 
    }
717
 
 
718
 
    return 0;
719
 
}
720
 
 
721
 
static int
722
 
pciInitDevice(pciDevice *dev)
723
 
{
724
 
    int flr;
725
 
 
726
 
    if (pciOpenConfig(dev) < 0) {
727
 
        virReportSystemError(errno,
728
 
                             _("Failed to open config space file '%s'"),
729
 
                             dev->path);
730
 
        return -1;
731
 
    }
732
 
 
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);
736
 
    if (flr < 0)
737
 
        return flr;
738
 
    dev->has_flr        = flr;
739
 
    dev->has_pm_reset   = pciDetectPowerManagementReset(dev);
740
 
    dev->initted        = 1;
741
 
    return 0;
742
 
}
743
 
 
744
 
int
745
 
pciResetDevice(pciDevice *dev,
746
 
               pciDeviceList *activeDevs,
747
 
               pciDeviceList *inactiveDevs)
748
 
{
749
 
    int ret = -1;
750
 
 
751
 
    if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
752
 
        pciReportError(VIR_ERR_INTERNAL_ERROR,
753
 
                       _("Not resetting active device %s"), dev->name);
754
 
        return -1;
755
 
    }
756
 
 
757
 
    if (!dev->initted && pciInitDevice(dev) < 0)
758
 
        return -1;
759
 
 
760
 
    /* KVM will perform FLR when starting and stopping
761
 
     * a guest, so there is no need for us to do it here.
762
 
     */
763
 
    if (dev->has_flr)
764
 
        return 0;
765
 
 
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.
769
 
     */
770
 
    if (dev->has_pm_reset)
771
 
        ret = pciTryPowerManagementReset(dev);
772
 
 
773
 
    /* Bus reset is not an option with the root bus */
774
 
    if (ret < 0 && dev->bus != 0)
775
 
        ret = pciTrySecondaryBusReset(dev, inactiveDevs);
776
 
 
777
 
    if (ret < 0) {
778
 
        virErrorPtr err = virGetLastError();
779
 
        pciReportError(VIR_ERR_INTERNAL_ERROR,
780
 
                       _("Unable to reset PCI device %s: %s"),
781
 
                       dev->name,
782
 
                       err ? err->message : _("no FLR, PM reset or bus reset available"));
783
 
    }
784
 
 
785
 
    return ret;
786
 
}
787
 
 
788
 
 
789
 
static int
790
 
pciDriverDir(char **buffer, const char *driver)
791
 
{
792
 
    VIR_FREE(*buffer);
793
 
 
794
 
    if (virAsprintf(buffer, PCI_SYSFS "drivers/%s", driver) < 0) {
795
 
        virReportOOMError();
796
 
        return -1;
797
 
    }
798
 
 
799
 
    return 0;
800
 
}
801
 
 
802
 
static int
803
 
pciDriverFile(char **buffer, const char *driver, const char *file)
804
 
{
805
 
    VIR_FREE(*buffer);
806
 
 
807
 
    if (virAsprintf(buffer, PCI_SYSFS "drivers/%s/%s", driver, file) < 0) {
808
 
        virReportOOMError();
809
 
        return -1;
810
 
    }
811
 
 
812
 
    return 0;
813
 
}
814
 
 
815
 
static int
816
 
pciDeviceFile(char **buffer, const char *device, const char *file)
817
 
{
818
 
    VIR_FREE(*buffer);
819
 
 
820
 
    if (virAsprintf(buffer, PCI_SYSFS "devices/%s/%s", device, file) < 0) {
821
 
        virReportOOMError();
822
 
        return -1;
823
 
    }
824
 
 
825
 
    return 0;
826
 
}
827
 
 
828
 
 
829
 
static const char *
830
 
pciFindStubDriver(void)
831
 
{
832
 
    char *drvpath = NULL;
833
 
    int probed = 0;
834
 
 
835
 
recheck:
836
 
    if (pciDriverDir(&drvpath, "pci-stub") < 0) {
837
 
        return NULL;
838
 
    }
839
 
 
840
 
    if (virFileExists(drvpath)) {
841
 
        VIR_FREE(drvpath);
842
 
        return "pci-stub";
843
 
    }
844
 
 
845
 
    if (pciDriverDir(&drvpath, "pciback") < 0) {
846
 
        return NULL;
847
 
    }
848
 
 
849
 
    if (virFileExists(drvpath)) {
850
 
        VIR_FREE(drvpath);
851
 
        return "pciback";
852
 
    }
853
 
 
854
 
    VIR_FREE(drvpath);
855
 
 
856
 
    if (!probed) {
857
 
        const char *const stubprobe[] = { MODPROBE, "pci-stub", NULL };
858
 
        const char *const backprobe[] = { MODPROBE, "pciback", NULL };
859
 
 
860
 
        probed = 1;
861
 
        /*
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
866
 
         */
867
 
        if (virRun(backprobe, NULL) < 0 &&
868
 
            virRun(stubprobe, NULL) < 0) {
869
 
            char ebuf[1024];
870
 
            VIR_WARN("failed to load pci-stub or pciback drivers: %s",
871
 
                     virStrerror(errno, ebuf, sizeof ebuf));
872
 
            return NULL;
873
 
        }
874
 
 
875
 
        goto recheck;
876
 
    }
877
 
 
878
 
    return NULL;
879
 
}
880
 
 
881
 
static int
882
 
pciUnbindDeviceFromStub(pciDevice *dev, const char *driver)
883
 
{
884
 
    int result = -1;
885
 
    char *drvdir = NULL;
886
 
    char *path = NULL;
887
 
 
888
 
    if (pciDriverDir(&drvdir, driver) < 0)
889
 
        goto cleanup;
890
 
 
891
 
    if (!dev->unbind_from_stub)
892
 
        goto remove_slot;
893
 
 
894
 
    /* If the device is bound to stub, unbind it.
895
 
     */
896
 
    if (pciDeviceFile(&path, dev->name, "driver") < 0)
897
 
        goto cleanup;
898
 
 
899
 
    if (virFileExists(drvdir) && virFileLinkPointsTo(path, drvdir)) {
900
 
        if (pciDriverFile(&path, driver, "unbind") < 0) {
901
 
            goto cleanup;
902
 
        }
903
 
 
904
 
        if (virFileWriteStr(path, dev->name, 0) < 0) {
905
 
            virReportSystemError(errno,
906
 
                                 _("Failed to unbind PCI device '%s' from %s"),
907
 
                                 dev->name, driver);
908
 
            goto cleanup;
909
 
        }
910
 
    }
911
 
    dev->unbind_from_stub = 0;
912
 
 
913
 
remove_slot:
914
 
    if (!dev->remove_slot)
915
 
        goto reprobe;
916
 
 
917
 
    /* Xen's pciback.ko wants you to use remove_slot on the specific device */
918
 
    if (pciDriverFile(&path, driver, "remove_slot") < 0) {
919
 
        goto cleanup;
920
 
    }
921
 
 
922
 
    if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) {
923
 
        virReportSystemError(errno,
924
 
                             _("Failed to remove slot for PCI device '%s' from %s"),
925
 
                             dev->name, driver);
926
 
        goto cleanup;
927
 
    }
928
 
    dev->remove_slot = 0;
929
 
 
930
 
reprobe:
931
 
    if (!dev->reprobe) {
932
 
        result = 0;
933
 
        goto cleanup;
934
 
    }
935
 
 
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.
940
 
     */
941
 
    if (pciDriverFile(&path, driver, "remove_id") < 0) {
942
 
        goto cleanup;
943
 
    }
944
 
 
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'"),
949
 
                                 dev->name);
950
 
            goto cleanup;
951
 
        }
952
 
    }
953
 
 
954
 
    result = 0;
955
 
 
956
 
cleanup:
957
 
    /* do not do it again */
958
 
    dev->unbind_from_stub = 0;
959
 
    dev->remove_slot = 0;
960
 
    dev->reprobe = 0;
961
 
 
962
 
    VIR_FREE(drvdir);
963
 
    VIR_FREE(path);
964
 
 
965
 
    return result;
966
 
}
967
 
 
968
 
 
969
 
static int
970
 
pciBindDeviceToStub(pciDevice *dev, const char *driver)
971
 
{
972
 
    int result = -1;
973
 
    char *drvdir = NULL;
974
 
    char *path = NULL;
975
 
    int reprobe = 0;
976
 
 
977
 
    /* check whether the device is already bound to a driver */
978
 
    if (pciDriverDir(&drvdir, driver) < 0 ||
979
 
        pciDeviceFile(&path, dev->name, "driver") < 0) {
980
 
        goto cleanup;
981
 
    }
982
 
 
983
 
    if (virFileExists(path)) {
984
 
        if (virFileLinkPointsTo(path, drvdir)) {
985
 
            /* The device is already bound to pci-stub */
986
 
            result = 0;
987
 
            goto cleanup;
988
 
        }
989
 
        reprobe = 1;
990
 
    }
991
 
 
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
998
 
     * bound by the stub.
999
 
     */
1000
 
    if (pciDriverFile(&path, driver, "new_id") < 0) {
1001
 
        goto cleanup;
1002
 
    }
1003
 
 
1004
 
    if (virFileWriteStr(path, dev->id, 0) < 0) {
1005
 
        virReportSystemError(errno,
1006
 
                             _("Failed to add PCI device ID '%s' to %s"),
1007
 
                             dev->id, driver);
1008
 
        goto cleanup;
1009
 
    }
1010
 
 
1011
 
    /* check whether the device is bound to pci-stub when we write dev->id to
1012
 
     * new_id.
1013
 
     */
1014
 
    if (pciDriverDir(&drvdir, driver) < 0 ||
1015
 
        pciDeviceFile(&path, dev->name, "driver") < 0) {
1016
 
        goto remove_id;
1017
 
    }
1018
 
 
1019
 
    if (virFileLinkPointsTo(path, drvdir)) {
1020
 
        dev->unbind_from_stub = 1;
1021
 
        dev->remove_slot = 1;
1022
 
        goto remove_id;
1023
 
    }
1024
 
 
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.
1029
 
     */
1030
 
    if (pciDeviceFile(&path, dev->name, "driver/unbind") < 0) {
1031
 
        goto cleanup;
1032
 
    }
1033
 
 
1034
 
    if (virFileExists(path)) {
1035
 
        if (virFileWriteStr(path, dev->name, 0) < 0) {
1036
 
            virReportSystemError(errno,
1037
 
                                 _("Failed to unbind PCI device '%s'"),
1038
 
                                 dev->name);
1039
 
            goto cleanup;
1040
 
        }
1041
 
        dev->reprobe = reprobe;
1042
 
    }
1043
 
 
1044
 
    /* If the device isn't already bound to pci-stub, try binding it now.
1045
 
     */
1046
 
    if (pciDriverDir(&drvdir, driver) < 0 ||
1047
 
        pciDeviceFile(&path, dev->name, "driver") < 0) {
1048
 
        goto remove_id;
1049
 
    }
1050
 
 
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) {
1054
 
            goto remove_id;
1055
 
        }
1056
 
 
1057
 
        if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) {
1058
 
            virReportSystemError(errno,
1059
 
                                 _("Failed to add slot for PCI device '%s' to %s"),
1060
 
                                 dev->name, driver);
1061
 
            goto remove_id;
1062
 
        }
1063
 
        dev->remove_slot = 1;
1064
 
 
1065
 
        if (pciDriverFile(&path, driver, "bind") < 0) {
1066
 
            goto remove_id;
1067
 
        }
1068
 
 
1069
 
        if (virFileWriteStr(path, dev->name, 0) < 0) {
1070
 
            virReportSystemError(errno,
1071
 
                                 _("Failed to bind PCI device '%s' to %s"),
1072
 
                                 dev->name, driver);
1073
 
            goto remove_id;
1074
 
        }
1075
 
        dev->unbind_from_stub = 1;
1076
 
    }
1077
 
 
1078
 
remove_id:
1079
 
    /* If 'remove_id' exists, remove the device id from pci-stub's dynamic
1080
 
     * ID table so that 'drivers_probe' works below.
1081
 
     */
1082
 
    if (pciDriverFile(&path, driver, "remove_id") < 0) {
1083
 
        /* We do not remove PCI ID from pci-stub, and we cannot reprobe it */
1084
 
        if (dev->reprobe) {
1085
 
            VIR_WARN("Could not remove PCI ID '%s' from %s, and the device "
1086
 
                     "cannot be probed again.", dev->id, driver);
1087
 
        }
1088
 
        dev->reprobe = 0;
1089
 
        goto cleanup;
1090
 
    }
1091
 
 
1092
 
    if (virFileExists(path) && virFileWriteStr(path, dev->id, 0) < 0) {
1093
 
        virReportSystemError(errno,
1094
 
                             _("Failed to remove PCI ID '%s' from %s"),
1095
 
                             dev->id, driver);
1096
 
 
1097
 
        /* remove PCI ID from pci-stub failed, and we cannot reprobe it */
1098
 
        if (dev->reprobe) {
1099
 
            VIR_WARN("Failed to remove PCI ID '%s' from %s, and the device "
1100
 
                     "cannot be probed again.", dev->id, driver);
1101
 
        }
1102
 
        dev->reprobe = 0;
1103
 
        goto cleanup;
1104
 
    }
1105
 
 
1106
 
    result = 0;
1107
 
 
1108
 
cleanup:
1109
 
    VIR_FREE(drvdir);
1110
 
    VIR_FREE(path);
1111
 
 
1112
 
    if (result < 0) {
1113
 
        pciUnbindDeviceFromStub(dev, driver);
1114
 
    }
1115
 
 
1116
 
    return result;
1117
 
}
1118
 
 
1119
 
int
1120
 
pciDettachDevice(pciDevice *dev, pciDeviceList *activeDevs)
1121
 
{
1122
 
    const char *driver = pciFindStubDriver();
1123
 
    if (!driver) {
1124
 
        pciReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1125
 
                       _("cannot find any PCI stub module"));
1126
 
        return -1;
1127
 
    }
1128
 
 
1129
 
    if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
1130
 
        pciReportError(VIR_ERR_INTERNAL_ERROR,
1131
 
                       _("Not detaching active device %s"), dev->name);
1132
 
        return -1;
1133
 
    }
1134
 
 
1135
 
    return pciBindDeviceToStub(dev, driver);
1136
 
}
1137
 
 
1138
 
int
1139
 
pciReAttachDevice(pciDevice *dev, pciDeviceList *activeDevs)
1140
 
{
1141
 
    const char *driver = pciFindStubDriver();
1142
 
    if (!driver) {
1143
 
        pciReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1144
 
                       _("cannot find any PCI stub module"));
1145
 
        return -1;
1146
 
    }
1147
 
 
1148
 
    if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
1149
 
        pciReportError(VIR_ERR_INTERNAL_ERROR,
1150
 
                       _("Not reattaching active device %s"), dev->name);
1151
 
        return -1;
1152
 
    }
1153
 
 
1154
 
    return pciUnbindDeviceFromStub(dev, driver);
1155
 
}
1156
 
 
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.
1164
 
 *
1165
 
 * A typical /proc/iomem looks like this (snipped for brevity):
1166
 
 * 00010000-0008efff : System RAM
1167
 
 * 0008f000-0008ffff : reserved
1168
 
 * ...
1169
 
 * 00100000-cc9fcfff : System RAM
1170
 
 *   00200000-00483d3b : Kernel code
1171
 
 *   00483d3c-005c88df : Kernel data
1172
 
 * cc9fd000-ccc71fff : ACPI Non-volatile Storage
1173
 
 * ...
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
1179
 
 * ...
1180
 
 * f0000000-f0003fff : 0000:00:1b.0
1181
 
 *   f0000000-f0003fff : kvm_assigned_device
1182
 
 *
1183
 
 * Returns 0 if we are clear to continue, and 1 if the hypervisor is still
1184
 
 * holding onto the resource.
1185
 
 */
1186
 
int
1187
 
pciWaitForDeviceCleanup(pciDevice *dev, const char *matcher)
1188
 
{
1189
 
    FILE *fp;
1190
 
    char line[160];
1191
 
    char *tmp;
1192
 
    unsigned long long start, end;
1193
 
    unsigned int domain, bus, slot, function;
1194
 
    int in_matching_device;
1195
 
    int ret;
1196
 
    size_t match_depth;
1197
 
 
1198
 
    fp = fopen("/proc/iomem", "r");
1199
 
    if (!fp) {
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
1203
 
         */
1204
 
        VIR_DEBUG("Failed to open /proc/iomem, trying to continue anyway");
1205
 
        return 0;
1206
 
    }
1207
 
 
1208
 
    ret = 0;
1209
 
    in_matching_device = 0;
1210
 
    match_depth = 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
1219
 
         */
1220
 
        if (in_matching_device && (strspn(line, " ") == (match_depth + 2))) {
1221
 
            /* expected format: <start>-<end> : <suffix> */
1222
 
            if (/* start */
1223
 
                virStrToLong_ull(line, &tmp, 16, &start) < 0 || *tmp != '-' ||
1224
 
                /* end */
1225
 
                virStrToLong_ull(tmp + 1, &tmp, 16, &end) < 0 ||
1226
 
                (tmp = STRSKIP(tmp, " : ")) == NULL)
1227
 
                continue;
1228
 
 
1229
 
            if (STRPREFIX(tmp, matcher)) {
1230
 
                ret = 1;
1231
 
                break;
1232
 
            }
1233
 
        }
1234
 
        else {
1235
 
            in_matching_device = 0;
1236
 
 
1237
 
            /* expected format: <start>-<end> : <domain>:<bus>:<slot>.<function> */
1238
 
            if (/* start */
1239
 
                virStrToLong_ull(line, &tmp, 16, &start) < 0 || *tmp != '-' ||
1240
 
                /* end */
1241
 
                virStrToLong_ull(tmp + 1, &tmp, 16, &end) < 0 ||
1242
 
                (tmp = STRSKIP(tmp, " : ")) == NULL ||
1243
 
                /* domain */
1244
 
                virStrToLong_ui(tmp, &tmp, 16, &domain) < 0 || *tmp != ':' ||
1245
 
                /* bus */
1246
 
                virStrToLong_ui(tmp + 1, &tmp, 16, &bus) < 0 || *tmp != ':' ||
1247
 
                /* slot */
1248
 
                virStrToLong_ui(tmp + 1, &tmp, 16, &slot) < 0 || *tmp != '.' ||
1249
 
                /* function */
1250
 
                virStrToLong_ui(tmp + 1, &tmp, 16, &function) < 0 || *tmp != '\n')
1251
 
                continue;
1252
 
 
1253
 
            if (domain != dev->domain || bus != dev->bus || slot != dev->slot ||
1254
 
                function != dev->function)
1255
 
                continue;
1256
 
            in_matching_device = 1;
1257
 
            match_depth = strspn(line, " ");
1258
 
        }
1259
 
    }
1260
 
 
1261
 
    VIR_FORCE_FCLOSE(fp);
1262
 
 
1263
 
    return ret;
1264
 
}
1265
 
 
1266
 
static char *
1267
 
pciReadDeviceID(pciDevice *dev, const char *id_name)
1268
 
{
1269
 
    char *path = NULL;
1270
 
    char *id_str;
1271
 
 
1272
 
    if (pciDeviceFile(&path, dev->name, id_name) < 0) {
1273
 
        return NULL;
1274
 
    }
1275
 
 
1276
 
    /* ID string is '0xNNNN\n' ... i.e. 7 bytes */
1277
 
    if (virFileReadAll(path, 7, &id_str) < 0) {
1278
 
        VIR_FREE(path);
1279
 
        return NULL;
1280
 
    }
1281
 
 
1282
 
    VIR_FREE(path);
1283
 
 
1284
 
    /* Check for 0x suffix */
1285
 
    if (id_str[0] != '0' || id_str[1] != 'x') {
1286
 
        VIR_FREE(id_str);
1287
 
        return NULL;
1288
 
    }
1289
 
 
1290
 
    /* Chop off the newline; we know the string is 7 bytes */
1291
 
    id_str[6] = '\0';
1292
 
 
1293
 
    return id_str;
1294
 
}
1295
 
 
1296
 
pciDevice *
1297
 
pciGetDevice(unsigned domain,
1298
 
             unsigned bus,
1299
 
             unsigned slot,
1300
 
             unsigned function)
1301
 
{
1302
 
    pciDevice *dev;
1303
 
    char *vendor = NULL;
1304
 
    char *product = NULL;
1305
 
 
1306
 
    if (VIR_ALLOC(dev) < 0) {
1307
 
        virReportOOMError();
1308
 
        return NULL;
1309
 
    }
1310
 
 
1311
 
    dev->fd       = -1;
1312
 
    dev->domain   = domain;
1313
 
    dev->bus      = bus;
1314
 
    dev->slot     = slot;
1315
 
    dev->function = function;
1316
 
 
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);
1323
 
        goto error;
1324
 
    }
1325
 
    if (virAsprintf(&dev->path, PCI_SYSFS "devices/%s/config",
1326
 
                    dev->name) < 0) {
1327
 
        virReportOOMError();
1328
 
        goto error;
1329
 
    }
1330
 
 
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);
1335
 
        goto error;
1336
 
    }
1337
 
 
1338
 
    vendor  = pciReadDeviceID(dev, "vendor");
1339
 
    product = pciReadDeviceID(dev, "device");
1340
 
 
1341
 
    if (!vendor || !product) {
1342
 
        pciReportError(VIR_ERR_INTERNAL_ERROR,
1343
 
                       _("Failed to read product/vendor ID for %s"),
1344
 
                       dev->name);
1345
 
        goto error;
1346
 
    }
1347
 
 
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]);
1354
 
        goto error;
1355
 
    }
1356
 
 
1357
 
    VIR_DEBUG("%s %s: initialized", dev->id, dev->name);
1358
 
 
1359
 
cleanup:
1360
 
    VIR_FREE(product);
1361
 
    VIR_FREE(vendor);
1362
 
    return dev;
1363
 
 
1364
 
error:
1365
 
    pciFreeDevice(dev);
1366
 
    dev = NULL;
1367
 
    goto cleanup;
1368
 
}
1369
 
 
1370
 
void
1371
 
pciFreeDevice(pciDevice *dev)
1372
 
{
1373
 
    if (!dev)
1374
 
        return;
1375
 
    VIR_DEBUG("%s %s: freeing", dev->id, dev->name);
1376
 
    pciCloseConfig(dev);
1377
 
    VIR_FREE(dev->path);
1378
 
    VIR_FREE(dev);
1379
 
}
1380
 
 
1381
 
const char *
1382
 
pciDeviceGetName(pciDevice *dev)
1383
 
{
1384
 
    return dev->name;
1385
 
}
1386
 
 
1387
 
void pciDeviceSetManaged(pciDevice *dev, unsigned managed)
1388
 
{
1389
 
    dev->managed = !!managed;
1390
 
}
1391
 
 
1392
 
unsigned pciDeviceGetManaged(pciDevice *dev)
1393
 
{
1394
 
    return dev->managed;
1395
 
}
1396
 
 
1397
 
unsigned
1398
 
pciDeviceGetUnbindFromStub(pciDevice *dev)
1399
 
{
1400
 
    return dev->unbind_from_stub;
1401
 
}
1402
 
 
1403
 
void
1404
 
pciDeviceSetUnbindFromStub(pciDevice *dev, unsigned unbind)
1405
 
{
1406
 
    dev->unbind_from_stub = !!unbind;
1407
 
}
1408
 
 
1409
 
unsigned
1410
 
pciDeviceGetRemoveSlot(pciDevice *dev)
1411
 
{
1412
 
    return dev->remove_slot;
1413
 
}
1414
 
 
1415
 
void
1416
 
pciDeviceSetRemoveSlot(pciDevice *dev, unsigned remove_slot)
1417
 
{
1418
 
    dev->remove_slot = !!remove_slot;
1419
 
}
1420
 
 
1421
 
unsigned
1422
 
pciDeviceGetReprobe(pciDevice *dev)
1423
 
{
1424
 
    return dev->reprobe;
1425
 
}
1426
 
 
1427
 
void
1428
 
pciDeviceSetReprobe(pciDevice *dev, unsigned reprobe)
1429
 
{
1430
 
    dev->reprobe = !!reprobe;
1431
 
}
1432
 
 
1433
 
void
1434
 
pciDeviceSetUsedBy(pciDevice *dev, const char *name)
1435
 
{
1436
 
    dev->used_by = name;
1437
 
}
1438
 
 
1439
 
const char *
1440
 
pciDeviceGetUsedBy(pciDevice *dev)
1441
 
{
1442
 
    return dev->used_by;
1443
 
}
1444
 
 
1445
 
void pciDeviceReAttachInit(pciDevice *pci)
1446
 
{
1447
 
    pci->unbind_from_stub = 1;
1448
 
    pci->remove_slot = 1;
1449
 
    pci->reprobe = 1;
1450
 
}
1451
 
 
1452
 
 
1453
 
pciDeviceList *
1454
 
pciDeviceListNew(void)
1455
 
{
1456
 
    pciDeviceList *list;
1457
 
 
1458
 
    if (VIR_ALLOC(list) < 0) {
1459
 
        virReportOOMError();
1460
 
        return NULL;
1461
 
    }
1462
 
 
1463
 
    return list;
1464
 
}
1465
 
 
1466
 
void
1467
 
pciDeviceListFree(pciDeviceList *list)
1468
 
{
1469
 
    int i;
1470
 
 
1471
 
    if (!list)
1472
 
        return;
1473
 
 
1474
 
    for (i = 0; i < list->count; i++) {
1475
 
        pciFreeDevice(list->devs[i]);
1476
 
        list->devs[i] = NULL;
1477
 
    }
1478
 
 
1479
 
    list->count = 0;
1480
 
    VIR_FREE(list->devs);
1481
 
    VIR_FREE(list);
1482
 
}
1483
 
 
1484
 
int
1485
 
pciDeviceListAdd(pciDeviceList *list,
1486
 
                 pciDevice *dev)
1487
 
{
1488
 
    if (pciDeviceListFind(list, dev)) {
1489
 
        pciReportError(VIR_ERR_INTERNAL_ERROR,
1490
 
                       _("Device %s is already in use"), dev->name);
1491
 
        return -1;
1492
 
    }
1493
 
 
1494
 
    if (VIR_REALLOC_N(list->devs, list->count+1) < 0) {
1495
 
        virReportOOMError();
1496
 
        return -1;
1497
 
    }
1498
 
 
1499
 
    list->devs[list->count++] = dev;
1500
 
 
1501
 
    return 0;
1502
 
}
1503
 
 
1504
 
pciDevice *
1505
 
pciDeviceListGet(pciDeviceList *list,
1506
 
                 int idx)
1507
 
{
1508
 
    if (idx >= list->count)
1509
 
        return NULL;
1510
 
    if (idx < 0)
1511
 
        return NULL;
1512
 
 
1513
 
    return list->devs[idx];
1514
 
}
1515
 
 
1516
 
int
1517
 
pciDeviceListCount(pciDeviceList *list)
1518
 
{
1519
 
    return list->count;
1520
 
}
1521
 
 
1522
 
pciDevice *
1523
 
pciDeviceListSteal(pciDeviceList *list,
1524
 
                   pciDevice *dev)
1525
 
{
1526
 
    pciDevice *ret = NULL;
1527
 
    int i;
1528
 
 
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)
1534
 
            continue;
1535
 
 
1536
 
        ret = list->devs[i];
1537
 
 
1538
 
        if (i != --list->count)
1539
 
            memmove(&list->devs[i],
1540
 
                    &list->devs[i+1],
1541
 
                    sizeof(*list->devs) * (list->count-i));
1542
 
 
1543
 
        if (VIR_REALLOC_N(list->devs, list->count) < 0) {
1544
 
            ; /* not fatal */
1545
 
        }
1546
 
 
1547
 
        break;
1548
 
    }
1549
 
    return ret;
1550
 
}
1551
 
 
1552
 
void
1553
 
pciDeviceListDel(pciDeviceList *list,
1554
 
                 pciDevice *dev)
1555
 
{
1556
 
    pciDevice *ret = pciDeviceListSteal(list, dev);
1557
 
    if (ret)
1558
 
        pciFreeDevice(ret);
1559
 
}
1560
 
 
1561
 
pciDevice *
1562
 
pciDeviceListFind(pciDeviceList *list, pciDevice *dev)
1563
 
{
1564
 
    int i;
1565
 
 
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];
1572
 
    return NULL;
1573
 
}
1574
 
 
1575
 
 
1576
 
int pciDeviceFileIterate(pciDevice *dev,
1577
 
                         pciDeviceFileActor actor,
1578
 
                         void *opaque)
1579
 
{
1580
 
    char *pcidir = NULL;
1581
 
    char *file = NULL;
1582
 
    DIR *dir = NULL;
1583
 
    int ret = -1;
1584
 
    struct dirent *ent;
1585
 
 
1586
 
    if (virAsprintf(&pcidir, "/sys/bus/pci/devices/%04x:%02x:%02x.%x",
1587
 
                    dev->domain, dev->bus, dev->slot, dev->function) < 0) {
1588
 
        virReportOOMError();
1589
 
        goto cleanup;
1590
 
    }
1591
 
 
1592
 
    if (!(dir = opendir(pcidir))) {
1593
 
        virReportSystemError(errno,
1594
 
                             _("cannot open %s"), pcidir);
1595
 
        goto cleanup;
1596
 
    }
1597
 
 
1598
 
    while ((ent = readdir(dir)) != NULL) {
1599
 
        /* Device assignment requires:
1600
 
         *   $PCIDIR/config, $PCIDIR/resource, $PCIDIR/resourceNNN,
1601
 
         *   $PCIDIR/rom, $PCIDIR/reset
1602
 
         */
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();
1609
 
                goto cleanup;
1610
 
            }
1611
 
            if ((actor)(dev, file, opaque) < 0)
1612
 
                goto cleanup;
1613
 
 
1614
 
            VIR_FREE(file);
1615
 
        }
1616
 
    }
1617
 
 
1618
 
    ret = 0;
1619
 
 
1620
 
cleanup:
1621
 
    if (dir)
1622
 
        closedir(dir);
1623
 
    VIR_FREE(file);
1624
 
    VIR_FREE(pcidir);
1625
 
    return ret;
1626
 
}
1627
 
 
1628
 
static int
1629
 
pciDeviceDownstreamLacksACS(pciDevice *dev)
1630
 
{
1631
 
    uint16_t flags;
1632
 
    uint16_t ctrl;
1633
 
    unsigned int pos;
1634
 
 
1635
 
    if (!dev->initted && pciInitDevice(dev) < 0)
1636
 
        return -1;
1637
 
 
1638
 
    pos = dev->pcie_cap_pos;
1639
 
    if (!pos || pciRead16(dev, PCI_CLASS_DEVICE) != PCI_CLASS_BRIDGE_PCI)
1640
 
        return 0;
1641
 
 
1642
 
    flags = pciRead16(dev, pos + PCI_EXP_FLAGS);
1643
 
    if (((flags & PCI_EXP_FLAGS_TYPE) >> 4) != PCI_EXP_TYPE_DOWNSTREAM)
1644
 
        return 0;
1645
 
 
1646
 
    pos = pciFindExtendedCapabilityOffset(dev, PCI_EXT_CAP_ID_ACS);
1647
 
    if (!pos) {
1648
 
        VIR_DEBUG("%s %s: downstream port lacks ACS", dev->id, dev->name);
1649
 
        return 1;
1650
 
    }
1651
 
 
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);
1656
 
        return 1;
1657
 
    }
1658
 
 
1659
 
    return 0;
1660
 
}
1661
 
 
1662
 
static int
1663
 
pciDeviceIsBehindSwitchLackingACS(pciDevice *dev)
1664
 
{
1665
 
    pciDevice *parent;
1666
 
 
1667
 
    if (pciGetParentDevice(dev, &parent) < 0)
1668
 
        return -1;
1669
 
    if (!parent) {
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.
1673
 
         */
1674
 
        if (dev->bus == 0)
1675
 
            return 0;
1676
 
        else {
1677
 
            pciReportError(VIR_ERR_INTERNAL_ERROR,
1678
 
                           _("Failed to find parent device for %s"),
1679
 
                           dev->name);
1680
 
            return -1;
1681
 
        }
1682
 
    }
1683
 
 
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
1687
 
     */
1688
 
    do {
1689
 
        pciDevice *tmp;
1690
 
        int acs;
1691
 
        int ret;
1692
 
 
1693
 
        acs = pciDeviceDownstreamLacksACS(parent);
1694
 
 
1695
 
        if (acs) {
1696
 
            pciFreeDevice(parent);
1697
 
            if (acs < 0)
1698
 
                return -1;
1699
 
            else
1700
 
                return 1;
1701
 
        }
1702
 
 
1703
 
        tmp = parent;
1704
 
        ret = pciGetParentDevice(parent, &parent);
1705
 
        pciFreeDevice(tmp);
1706
 
        if (ret < 0)
1707
 
            return -1;
1708
 
    } while (parent);
1709
 
 
1710
 
    return 0;
1711
 
}
1712
 
 
1713
 
int pciDeviceIsAssignable(pciDevice *dev,
1714
 
                          int strict_acs_check)
1715
 
{
1716
 
    int ret;
1717
 
 
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.
1721
 
     */
1722
 
 
1723
 
    ret = pciDeviceIsBehindSwitchLackingACS(dev);
1724
 
    if (ret < 0)
1725
 
        return 0;
1726
 
 
1727
 
    if (ret) {
1728
 
        if (!strict_acs_check) {
1729
 
            VIR_DEBUG("%s %s: strict ACS check disabled; device assignment allowed",
1730
 
                      dev->id, dev->name);
1731
 
        } else {
1732
 
            pciReportError(VIR_ERR_INTERNAL_ERROR,
1733
 
                           _("Device %s is behind a switch lacking ACS and "
1734
 
                             "cannot be assigned"),
1735
 
                           dev->name);
1736
 
            return 0;
1737
 
        }
1738
 
    }
1739
 
 
1740
 
    return 1;
1741
 
}
1742
 
 
1743
 
#ifdef __linux__
1744
 
 
1745
 
/*
1746
 
 * returns true if equal
1747
 
 */
1748
 
static bool
1749
 
pciConfigAddressEqual(struct pci_config_address *bdf1,
1750
 
                      struct pci_config_address *bdf2)
1751
 
{
1752
 
    return ((bdf1->domain == bdf2->domain) &&
1753
 
            (bdf1->bus == bdf2->bus) &&
1754
 
            (bdf1->slot == bdf2->slot) &&
1755
 
            (bdf1->function == bdf2->function));
1756
 
}
1757
 
 
1758
 
static int
1759
 
logStrToLong_ui(char const *s,
1760
 
                char **end_ptr,
1761
 
                int base,
1762
 
                unsigned int *result)
1763
 
{
1764
 
    int ret = 0;
1765
 
 
1766
 
    ret = virStrToLong_ui(s, end_ptr, base, result);
1767
 
    if (ret != 0) {
1768
 
        VIR_ERROR(_("Failed to convert '%s' to unsigned int"), s);
1769
 
    } else {
1770
 
        VIR_DEBUG("Converted '%s' to unsigned int %u", s, *result);
1771
 
    }
1772
 
 
1773
 
    return ret;
1774
 
}
1775
 
 
1776
 
static int
1777
 
pciParsePciConfigAddress(char *address,
1778
 
                         struct pci_config_address *bdf)
1779
 
{
1780
 
    char *p = NULL;
1781
 
    int ret = -1;
1782
 
 
1783
 
    if ((address == NULL) || (logStrToLong_ui(address, &p, 16,
1784
 
                                              &bdf->domain) == -1)) {
1785
 
        goto out;
1786
 
    }
1787
 
 
1788
 
    if ((p == NULL) || (logStrToLong_ui(p+1, &p, 16,
1789
 
                                        &bdf->bus) == -1)) {
1790
 
        goto out;
1791
 
    }
1792
 
 
1793
 
    if ((p == NULL) || (logStrToLong_ui(p+1, &p, 16,
1794
 
                                        &bdf->slot) == -1)) {
1795
 
        goto out;
1796
 
    }
1797
 
 
1798
 
    if ((p == NULL) || (logStrToLong_ui(p+1, &p, 16,
1799
 
                                        &bdf->function) == -1)) {
1800
 
        goto out;
1801
 
    }
1802
 
 
1803
 
    ret = 0;
1804
 
 
1805
 
out:
1806
 
    return ret;
1807
 
}
1808
 
 
1809
 
static int
1810
 
pciGetPciConfigAddressFromSysfsDeviceLink(const char *device_link,
1811
 
                                          struct pci_config_address **bdf)
1812
 
{
1813
 
    char *config_address = NULL;
1814
 
    char *device_path = NULL;
1815
 
    char errbuf[64];
1816
 
    int ret = -1;
1817
 
 
1818
 
    VIR_DEBUG("Attempting to resolve device path from device link '%s'",
1819
 
              device_link);
1820
 
 
1821
 
    if (!virFileExists(device_link)) {
1822
 
        VIR_DEBUG("sysfs_path '%s' does not exist", device_link);
1823
 
        return ret;
1824
 
    }
1825
 
 
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,
1832
 
                       sizeof(errbuf)));
1833
 
        return ret;
1834
 
    }
1835
 
 
1836
 
    config_address = basename(device_path);
1837
 
    if (VIR_ALLOC(*bdf) != 0) {
1838
 
        virReportOOMError();
1839
 
        goto out;
1840
 
    }
1841
 
 
1842
 
    if (pciParsePciConfigAddress(config_address, *bdf) != 0) {
1843
 
        pciReportError(VIR_ERR_INTERNAL_ERROR,
1844
 
                       _("Failed to parse PCI config address '%s'"),
1845
 
                       config_address);
1846
 
        VIR_FREE(*bdf);
1847
 
        goto out;
1848
 
    }
1849
 
 
1850
 
    VIR_DEBUG("pci_config_address %.4x:%.2x:%.2x.%.1x",
1851
 
              (*bdf)->domain,
1852
 
              (*bdf)->bus,
1853
 
              (*bdf)->slot,
1854
 
              (*bdf)->function);
1855
 
 
1856
 
    ret = 0;
1857
 
 
1858
 
out:
1859
 
    VIR_FREE(device_path);
1860
 
 
1861
 
    return ret;
1862
 
}
1863
 
 
1864
 
/*
1865
 
 * Returns Physical function given a virtual function
1866
 
 */
1867
 
int
1868
 
pciGetPhysicalFunction(const char *vf_sysfs_path,
1869
 
                       struct pci_config_address **physical_function)
1870
 
{
1871
 
    int ret = -1;
1872
 
    char *device_link = NULL;
1873
 
 
1874
 
    VIR_DEBUG("Attempting to get SR IOV physical function for device "
1875
 
              "with sysfs path '%s'", vf_sysfs_path);
1876
 
 
1877
 
    if (virBuildPath(&device_link, vf_sysfs_path, "physfn") == -1) {
1878
 
        virReportOOMError();
1879
 
        return ret;
1880
 
    } else {
1881
 
        ret = pciGetPciConfigAddressFromSysfsDeviceLink(device_link,
1882
 
                                                        physical_function);
1883
 
    }
1884
 
 
1885
 
    VIR_FREE(device_link);
1886
 
 
1887
 
    return ret;
1888
 
}
1889
 
 
1890
 
/*
1891
 
 * Returns virtual functions of a physical function
1892
 
 */
1893
 
int
1894
 
pciGetVirtualFunctions(const char *sysfs_path,
1895
 
                       struct pci_config_address ***virtual_functions,
1896
 
                       unsigned int *num_virtual_functions)
1897
 
{
1898
 
    int ret = -1;
1899
 
    DIR *dir = NULL;
1900
 
    struct dirent *entry = NULL;
1901
 
    char *device_link = NULL;
1902
 
    char errbuf[64];
1903
 
 
1904
 
    VIR_DEBUG("Attempting to get SR IOV virtual functions for device"
1905
 
              "with sysfs path '%s'", sysfs_path);
1906
 
 
1907
 
    dir = opendir(sysfs_path);
1908
 
    if (dir == NULL) {
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,
1913
 
                       sizeof(errbuf)));
1914
 
        return ret;
1915
 
    }
1916
 
 
1917
 
    *virtual_functions = NULL;
1918
 
    *num_virtual_functions = 0;
1919
 
    while ((entry = readdir(dir))) {
1920
 
        if (STRPREFIX(entry->d_name, "virtfn")) {
1921
 
 
1922
 
            if (virBuildPath(&device_link, sysfs_path, entry->d_name) == -1) {
1923
 
                virReportOOMError();
1924
 
                goto out;
1925
 
            }
1926
 
 
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);
1933
 
                goto out;
1934
 
            }
1935
 
 
1936
 
            if (pciGetPciConfigAddressFromSysfsDeviceLink(device_link,
1937
 
                &((*virtual_functions)[*num_virtual_functions])) !=
1938
 
                SRIOV_FOUND) {
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);
1945
 
                goto out;
1946
 
            } else {
1947
 
                (*num_virtual_functions)++;
1948
 
            }
1949
 
            VIR_FREE(device_link);
1950
 
        }
1951
 
    }
1952
 
 
1953
 
    ret = 0;
1954
 
 
1955
 
out:
1956
 
    if (dir)
1957
 
        closedir(dir);
1958
 
 
1959
 
    return ret;
1960
 
}
1961
 
 
1962
 
/*
1963
 
 * Returns 1 if vf device is a virtual function, 0 if not, -1 on error
1964
 
 */
1965
 
int
1966
 
pciDeviceIsVirtualFunction(const char *vf_sysfs_device_link)
1967
 
{
1968
 
    char *vf_sysfs_physfn_link = NULL;
1969
 
    int ret = -1;
1970
 
 
1971
 
    if (virAsprintf(&vf_sysfs_physfn_link, "%s/physfn",
1972
 
        vf_sysfs_device_link) < 0) {
1973
 
        virReportOOMError();
1974
 
        return ret;
1975
 
    }
1976
 
 
1977
 
    ret = virFileExists(vf_sysfs_physfn_link);
1978
 
 
1979
 
    VIR_FREE(vf_sysfs_physfn_link);
1980
 
 
1981
 
    return ret;
1982
 
}
1983
 
 
1984
 
/*
1985
 
 * Returns the sriov virtual function index of vf given its pf
1986
 
 */
1987
 
int
1988
 
pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
1989
 
                           const char *vf_sysfs_device_link,
1990
 
                           int *vf_index)
1991
 
{
1992
 
    int ret = -1, i;
1993
 
    unsigned int num_virt_fns = 0;
1994
 
    struct pci_config_address *vf_bdf = NULL;
1995
 
    struct pci_config_address **virt_fns = NULL;
1996
 
 
1997
 
    if (pciGetPciConfigAddressFromSysfsDeviceLink(vf_sysfs_device_link,
1998
 
        &vf_bdf) < 0)
1999
 
        return ret;
2000
 
 
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);
2006
 
        goto out;
2007
 
    }
2008
 
 
2009
 
    for (i = 0; i < num_virt_fns; i++) {
2010
 
         if (pciConfigAddressEqual(vf_bdf, virt_fns[i])) {
2011
 
             *vf_index = i;
2012
 
             ret = 0;
2013
 
             break;
2014
 
         }
2015
 
    }
2016
 
 
2017
 
out:
2018
 
 
2019
 
    /* free virtual functions */
2020
 
    for (i = 0; i < num_virt_fns; i++)
2021
 
         VIR_FREE(virt_fns[i]);
2022
 
 
2023
 
    VIR_FREE(virt_fns);
2024
 
    VIR_FREE(vf_bdf);
2025
 
 
2026
 
    return ret;
2027
 
}
2028
 
 
2029
 
/*
2030
 
 * Returns the network device name of a pci device
2031
 
 */
2032
 
int
2033
 
pciDeviceNetName(char *device_link_sysfs_path, char **netname)
2034
 
{
2035
 
     char *pcidev_sysfs_net_path = NULL;
2036
 
     int ret = -1;
2037
 
     DIR *dir = NULL;
2038
 
     struct dirent *entry = NULL;
2039
 
 
2040
 
     if (virBuildPath(&pcidev_sysfs_net_path, device_link_sysfs_path,
2041
 
         "net") == -1) {
2042
 
         virReportOOMError();
2043
 
         return -1;
2044
 
     }
2045
 
 
2046
 
     dir = opendir(pcidev_sysfs_net_path);
2047
 
     if (dir == NULL)
2048
 
         goto out;
2049
 
 
2050
 
     while ((entry = readdir(dir))) {
2051
 
            if (STREQ(entry->d_name, ".") ||
2052
 
                STREQ(entry->d_name, ".."))
2053
 
                continue;
2054
 
 
2055
 
            /* Assume a single directory entry */
2056
 
            *netname = strdup(entry->d_name);
2057
 
            if (!*netname)
2058
 
                virReportOOMError();
2059
 
            else
2060
 
                ret = 0;
2061
 
            break;
2062
 
     }
2063
 
 
2064
 
     closedir(dir);
2065
 
 
2066
 
out:
2067
 
     VIR_FREE(pcidev_sysfs_net_path);
2068
 
 
2069
 
     return ret;
2070
 
}
2071
 
#else
2072
 
int
2073
 
pciGetPhysicalFunction(const char *vf_sysfs_path ATTRIBUTE_UNUSED,
2074
 
              struct pci_config_address **physical_function ATTRIBUTE_UNUSED)
2075
 
{
2076
 
    pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciGetPhysicalFunction is not "
2077
 
                   "supported on non-linux platforms"));
2078
 
    return -1;
2079
 
}
2080
 
 
2081
 
int
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)
2085
 
{
2086
 
    pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciGetVirtualFunctions is not "
2087
 
                   "supported on non-linux platforms"));
2088
 
    return -1;
2089
 
}
2090
 
 
2091
 
int
2092
 
pciDeviceIsVirtualFunction(const char *vf_sysfs_device_link ATTRIBUTE_UNUSED)
2093
 
{
2094
 
    pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciDeviceIsVirtualFunction is "
2095
 
                   "not supported on non-linux platforms"));
2096
 
    return -1;
2097
 
}
2098
 
 
2099
 
int
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)
2103
 
{
2104
 
    pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciGetVirtualFunctionIndex is "
2105
 
                   "not supported on non-linux platforms"));
2106
 
    return -1;
2107
 
 
2108
 
}
2109
 
 
2110
 
int
2111
 
pciDeviceNetName(char *device_link_sysfs_path ATTRIBUTE_UNUSED,
2112
 
                 char **netname ATTRIBUTE_UNUSED)
2113
 
{
2114
 
    pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciDeviceNetName is not "
2115
 
                   "supported on non-linux platforms"));
2116
 
    return -1;
2117
 
}
2118
 
#endif /* __linux__ */