Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/drivers/vpci/header.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Generic functionality for handling accesses to the PCI header from the
3
 * configuration space.
4
 *
5
 * Copyright (C) 2017 Citrix Systems R&D
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms and conditions of the GNU General Public
9
 * License, version 2, as published by the Free Software Foundation.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public
17
 * License along with this program; If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
#include <xen/sched.h>
21
#include <xen/vpci.h>
22
#include <xen/p2m-common.h>
23
#include <xen/softirq.h>
24
25
#include <asm/event.h>
26
27
#define MAPPABLE_BAR(x)                                                 \
28
39.2k
    ((x)->type == VPCI_BAR_MEM32 || (x)->type == VPCI_BAR_MEM64_LO ||   \
29
33.8k
     (x)->type == VPCI_BAR_ROM)
30
31
struct map_data {
32
    struct domain *d;
33
    bool map;
34
};
35
36
static int map_range(unsigned long s, unsigned long e, void *data,
37
                     unsigned long *c)
38
709
{
39
709
    const struct map_data *map = data;
40
709
    int rc;
41
709
42
709
    for ( ; ; )
43
8.13k
    {
44
8.13k
        unsigned long size = e - s + 1;
45
8.13k
46
8.13k
        /*
47
8.13k
         * ARM TODOs:
48
8.13k
         * - On ARM whether the memory is prefetchable or not should be passed
49
8.13k
         *   to map_mmio_regions in order to decide which memory attributes
50
8.13k
         *   should be used.
51
8.13k
         *
52
8.13k
         * - {un}map_mmio_regions doesn't support preemption, hence the bodge
53
8.13k
         *   below in order to limit the amount of mappings to 64 pages for
54
8.13k
         *   each function call.
55
8.13k
         */
56
8.13k
57
8.13k
#ifdef CONFIG_ARM
58
        size = min(64ul, size);
59
#endif
60
8.13k
61
4.62k
        rc = (map->map ? map_mmio_regions : unmap_mmio_regions)
62
8.13k
             (map->d, _gfn(s), size, _mfn(s));
63
8.13k
        if ( rc == 0 )
64
318
        {
65
318
            *c += size;
66
318
#ifdef CONFIG_ARM
67
            rc = -ERESTART;
68
#endif
69
318
            break;
70
318
        }
71
7.82k
        if ( rc < 0 )
72
0
        {
73
0
            printk(XENLOG_G_WARNING
74
0
                   "Failed to identity %smap [%" PRI_gfn ", %" PRI_gfn ") for d%d: %d\n",
75
0
                   map ? "" : "un", s, e, map->d->domain_id, rc);
76
0
            break;
77
0
        }
78
7.82k
        ASSERT(rc < size);
79
7.82k
        *c += rc;
80
7.82k
        s += rc;
81
7.82k
        if ( general_preempt_check() )
82
1.47k
        {
83
1.47k
            if ( !is_idle_vcpu(current) )
84
391
                return -ERESTART;
85
1.47k
86
1.08k
            process_pending_softirqs();
87
1.08k
        }
88
7.82k
    }
89
709
90
318
    return rc;
91
709
}
92
93
static void modify_decoding(const struct pci_dev *pdev, bool map, bool rom)
94
225
{
95
225
    struct vpci_header *header = &pdev->vpci->header;
96
225
    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
97
225
    unsigned int i;
98
225
99
1.80k
    for ( i = 0; i < ARRAY_SIZE(header->bars); i++ )
100
1.57k
    {
101
1.57k
        if ( rom && header->bars[i].type == VPCI_BAR_ROM )
102
0
        {
103
0
            unsigned int rom_pos = (i == 6) ? PCI_ROM_ADDRESS
104
0
                                            : PCI_ROM_ADDRESS1;
105
0
            uint32_t val = pci_conf_read32(pdev->seg, pdev->bus, slot, func,
106
0
                                           rom_pos);
107
0
108
0
            header->bars[i].enabled = header->bars[i].rom_enabled = map;
109
0
110
0
            val &= ~PCI_ROM_ADDRESS_ENABLE;
111
0
            val |= map ? PCI_ROM_ADDRESS_ENABLE : 0;
112
0
            pci_conf_write32(pdev->seg, pdev->bus, slot, func, rom_pos, val);
113
0
            break;
114
0
        }
115
1.57k
        if ( !rom && (header->bars[i].type != VPCI_BAR_ROM ||
116
7
                      header->bars[i].rom_enabled) )
117
1.56k
            header->bars[i].enabled = map;
118
1.57k
    }
119
225
120
225
    if ( !rom )
121
225
    {
122
225
        uint16_t cmd = pci_conf_read16(pdev->seg, pdev->bus, slot,
123
225
                                       func, PCI_COMMAND);
124
225
125
225
        cmd &= ~PCI_COMMAND_MEMORY;
126
123
        cmd |= map ? PCI_COMMAND_MEMORY : 0;
127
225
        pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
128
225
                         cmd);
129
225
    }
130
225
}
131
132
bool vpci_process_pending(struct vcpu *v)
133
9.70M
{
134
9.70M
    while ( v->vpci.mem )
135
589
    {
136
589
        struct map_data data = {
137
589
            .d = v->domain,
138
589
            .map = v->vpci.map,
139
589
        };
140
589
141
589
        switch ( rangeset_consume_ranges(v->vpci.mem, map_range, &data) )
142
589
        {
143
391
        case -ERESTART:
144
391
            return true;
145
198
        case 0:
146
198
            if ( v->vpci.map )
147
96
            {
148
96
                spin_lock(&v->vpci.pdev->vpci->lock);
149
96
                modify_decoding(v->vpci.pdev, v->vpci.map, v->vpci.rom);
150
96
                spin_unlock(&v->vpci.pdev->vpci->lock);
151
96
            }
152
198
            /* fallthrough. */
153
198
        case -ENOMEM:
154
198
            /*
155
198
             * Other errors are ignored, hopping that at least some regions
156
198
             * will be mapped and that would be enough for the device to
157
198
             * function. Note that in the unmap case the memory decoding or
158
198
             * ROM enable bit have already been toggled off before attempting
159
198
             * to perform the p2m unmap.
160
198
             */
161
198
            rangeset_destroy(v->vpci.mem);
162
198
            v->vpci.mem = NULL;
163
198
            break;
164
589
        }
165
589
    }
166
9.70M
167
9.70M
    return false;
168
9.70M
}
169
170
static void maybe_defer_map(struct domain *d, const struct pci_dev *pdev,
171
                            struct rangeset *mem, bool map, bool rom)
172
225
{
173
225
    struct vcpu *curr = current;
174
225
175
225
    if ( is_idle_vcpu(curr) )
176
27
    {
177
27
        struct map_data data = { .d = d, .map = true };
178
27
179
27
        /*
180
27
         * Only used for domain construction in order to map the BARs
181
27
         * of devices with memory decoding enabled.
182
27
         */
183
27
        ASSERT(map && !rom);
184
27
        rangeset_consume_ranges(mem, map_range, &data);
185
27
        modify_decoding(pdev, true, false);
186
27
        rangeset_destroy(mem);
187
27
    }
188
225
    else
189
198
    {
190
198
        /*
191
198
         * NB: when deferring the {un}map the state of the device should not be
192
198
         * trusted. For example the enable bit is toggled after the device is
193
198
         * mapped. This can lead to parallel mapping operations being started
194
198
         * for the same device if the domain is not well-behaved.
195
198
         *
196
198
         * In any case, the worse that can happen are errors from the {un}map
197
198
         * operations, which will lead to the devices not working properly.
198
198
         */
199
198
        ASSERT(curr->domain == d);
200
198
        curr->vpci.pdev = pdev;
201
198
        curr->vpci.mem = mem;
202
198
        curr->vpci.map = map;
203
198
        curr->vpci.rom = rom;
204
198
    }
205
225
}
206
207
static void modify_bars(const struct pci_dev *pdev, bool map, bool rom)
208
225
{
209
225
    struct vpci_header *header = &pdev->vpci->header;
210
225
    struct rangeset *mem = rangeset_new(NULL, NULL, 0);
211
225
    const struct pci_dev *tmp;
212
225
    const struct vpci_msix *msix = pdev->vpci->msix;
213
225
    unsigned int i;
214
225
    int rc;
215
225
216
225
    if ( !map )
217
102
        modify_decoding(pdev, false, rom);
218
225
219
225
    if ( !mem )
220
0
        return;
221
225
222
225
    /*
223
225
     * Create a rangeset that represents the current device BARs memory region
224
225
     * and compare it against all the currently active BAR memory regions. If
225
225
     * an overlap is found, subtract it from the region to be
226
225
     * mapped/unmapped.
227
225
     *
228
225
     * NB: the rangeset uses inclusive frame numbers.
229
225
     */
230
225
231
225
    /*
232
225
     * First fill the rangeset with all the BARs of this device or with the ROM
233
225
     * BAR only, depending on whether the guest is toggling the memory decode
234
225
     * bit of the command register, or the enable bit of the ROM BAR register.
235
225
     */
236
1.80k
    for ( i = 0; i < ARRAY_SIZE(header->bars); i++ )
237
1.57k
    {
238
1.57k
        const struct vpci_bar *bar = &header->bars[i];
239
1.57k
240
1.57k
        if ( !MAPPABLE_BAR(bar) ||
241
1.29k
             rom ? bar->type != VPCI_BAR_ROM
242
281
                 : (bar->type == VPCI_BAR_ROM && !bar->rom_enabled) )
243
1.30k
            continue;
244
1.57k
245
274
        rc = rangeset_add_range(mem, PFN_DOWN(bar->addr),
246
274
                                PFN_DOWN(bar->addr + bar->size - 1));
247
274
        if ( rc )
248
0
        {
249
0
            printk(XENLOG_G_WARNING
250
0
                   "Failed to add [%" PRI_gfn ", %" PRI_gfn "): %d\n",
251
0
                   PFN_DOWN(bar->addr), PFN_DOWN(bar->addr + bar->size - 1),
252
0
                   rc);
253
0
            rangeset_destroy(mem);
254
0
            return;
255
0
        }
256
274
    }
257
225
258
225
    /* Remove any MSIX regions if present. */
259
335
    for ( i = 0; msix && i < ARRAY_SIZE(msix->tables); i++ )
260
110
    {
261
110
        paddr_t start = VMSIX_TABLE_ADDR(pdev->vpci, i);
262
110
263
110
        rc = rangeset_remove_range(mem, PFN_DOWN(start), PFN_DOWN(start +
264
110
                                   VMSIX_TABLE_SIZE(pdev->vpci, i) - 1));
265
110
        if ( rc )
266
0
        {
267
0
            rangeset_destroy(mem);
268
0
            return;
269
0
        }
270
110
    }
271
225
272
225
    /*
273
225
     * Check for overlaps with other BARs. Note that only BARs that are
274
225
     * currently mapped (enabled) are checked for overlaps.
275
225
     */
276
225
    list_for_each_entry(tmp, &pdev->domain->arch.pdev_list, domain_list)
277
111k
        for ( i = 0; i < ARRAY_SIZE(tmp->vpci->header.bars); i++ )
278
97.5k
        {
279
97.5k
            const struct vpci_bar *bar = &tmp->vpci->header.bars[i];
280
97.5k
            unsigned long start = PFN_DOWN(bar->addr);
281
97.5k
            unsigned long end = PFN_DOWN(bar->addr + bar->size - 1);
282
97.5k
283
97.5k
            if ( !bar->enabled || !MAPPABLE_BAR(bar) ||
284
5.12k
                 !rangeset_overlaps_range(mem, start, end) )
285
97.5k
                continue;
286
97.5k
287
0
            rc = rangeset_remove_range(mem, start, end);
288
0
            if ( rc )
289
0
            {
290
0
                printk(XENLOG_G_WARNING
291
0
                       "Failed to remove [%" PRI_gfn ", %" PRI_gfn "): %d\n",
292
0
                       start, end, rc);
293
0
                rangeset_destroy(mem);
294
0
                return;
295
0
            }
296
0
        }
297
225
298
225
    maybe_defer_map(pdev->domain, pdev, mem, map, rom);
299
225
}
300
301
static void cmd_write(const struct pci_dev *pdev, unsigned int reg,
302
                      uint32_t cmd, void *data)
303
903
{
304
903
    uint8_t seg = pdev->seg, bus = pdev->bus;
305
903
    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
306
903
    uint16_t current_cmd = pci_conf_read16(seg, bus, slot, func, reg);
307
903
308
903
    /*
309
903
     * Let Dom0 play with all the bits directly except for the memory
310
903
     * decoding one.
311
903
     */
312
903
    if ( (cmd ^ current_cmd) & PCI_COMMAND_MEMORY )
313
198
        modify_bars(pdev, cmd & PCI_COMMAND_MEMORY, false);
314
903
    else
315
705
        pci_conf_write16(seg, bus, slot, func, reg, cmd);
316
903
}
317
318
static void bar_write(const struct pci_dev *pdev, unsigned int reg,
319
                      uint32_t val, void *data)
320
99
{
321
99
    struct vpci_bar *bar = data;
322
99
    uint8_t seg = pdev->seg, bus = pdev->bus;
323
99
    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
324
99
    bool hi = false;
325
99
326
99
    if ( pci_conf_read16(seg, bus, slot, func, PCI_COMMAND) &
327
99
         PCI_COMMAND_MEMORY )
328
33
    {
329
33
        gprintk(XENLOG_WARNING,
330
33
                "%04x:%02x:%02x.%u: ignored BAR %lu write with memory decoding enabled\n",
331
33
                seg, bus, slot, func, (pdev->vpci->header.bars - bar) / 4);
332
33
        return;
333
33
    }
334
99
335
66
    if ( bar->type == VPCI_BAR_MEM64_HI )
336
14
    {
337
14
        ASSERT(reg > PCI_BASE_ADDRESS_0);
338
14
        bar--;
339
14
        hi = true;
340
14
    }
341
66
    else
342
52
        val &= PCI_BASE_ADDRESS_MEM_MASK;
343
66
344
66
    /*
345
66
     * Update the cached address, so that when memory decoding is enabled
346
66
     * Xen can map the BAR into the guest p2m.
347
66
     */
348
52
    bar->addr &= ~(0xffffffffull << (hi ? 32 : 0));
349
52
    bar->addr |= (uint64_t)val << (hi ? 32 : 0);
350
66
351
66
    /* Make sure Xen writes back the same value for the BAR RO bits. */
352
66
    if ( !hi )
353
52
    {
354
38
        val |= bar->type == VPCI_BAR_MEM32 ? PCI_BASE_ADDRESS_MEM_TYPE_32
355
14
                                           : PCI_BASE_ADDRESS_MEM_TYPE_64;
356
50
        val |= bar->prefetchable ? PCI_BASE_ADDRESS_MEM_PREFETCH : 0;
357
52
    }
358
66
359
66
    pci_conf_write32(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
360
66
                     PCI_FUNC(pdev->devfn), reg, val);
361
66
}
362
363
static void rom_write(const struct pci_dev *pdev, unsigned int reg,
364
                      uint32_t val, void *data)
365
0
{
366
0
    struct vpci_bar *rom = data;
367
0
    uint8_t seg = pdev->seg, bus = pdev->bus;
368
0
    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
369
0
    uint16_t cmd = pci_conf_read16(seg, bus, slot, func, PCI_COMMAND);
370
0
    bool new_enabled = val & PCI_ROM_ADDRESS_ENABLE;
371
0
372
0
    if ( (cmd & PCI_COMMAND_MEMORY) && rom->rom_enabled && new_enabled )
373
0
    {
374
0
        gprintk(XENLOG_WARNING,
375
0
                "%04x:%02x:%02x.%u: ignored ROM BAR write with memory decoding enabled\n",
376
0
                seg, bus, slot, func);
377
0
        return;
378
0
    }
379
0
380
0
    if ( !rom->rom_enabled )
381
0
        rom->addr = val & PCI_ROM_ADDRESS_MASK;
382
0
383
0
    /* Check if ROM BAR should be mapped/unmapped. */
384
0
    if ( (cmd & PCI_COMMAND_MEMORY) && rom->rom_enabled != new_enabled )
385
0
        modify_bars(pdev, new_enabled, true);
386
0
    else
387
0
    {
388
0
        rom->rom_enabled = new_enabled;
389
0
        pci_conf_write32(pdev->seg, pdev->bus, slot, func, reg, val);
390
0
    }
391
0
392
0
    if ( !new_enabled )
393
0
        rom->addr = val & PCI_ROM_ADDRESS_MASK;
394
0
}
395
396
static int init_bars(struct pci_dev *pdev)
397
68
{
398
68
    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
399
68
    uint16_t cmd;
400
68
    uint64_t addr, size;
401
68
    unsigned int i, num_bars, rom_reg;
402
68
    struct vpci_header *header = &pdev->vpci->header;
403
68
    struct vpci_bar *bars = header->bars;
404
68
    pci_sbdf_t sbdf = {
405
68
        .seg = pdev->seg,
406
68
        .bus = pdev->bus,
407
68
        .dev = slot,
408
68
        .func = func,
409
68
    };
410
68
    int rc;
411
68
412
68
    switch ( pci_conf_read8(pdev->seg, pdev->bus, slot, func, PCI_HEADER_TYPE)
413
68
             & 0x7f )
414
68
    {
415
58
    case PCI_HEADER_TYPE_NORMAL:
416
58
        num_bars = 6;
417
58
        rom_reg = PCI_ROM_ADDRESS;
418
58
        break;
419
10
    case PCI_HEADER_TYPE_BRIDGE:
420
10
        num_bars = 2;
421
10
        rom_reg = PCI_ROM_ADDRESS1;
422
10
        break;
423
0
    default:
424
0
        return -EOPNOTSUPP;
425
68
    }
426
68
427
68
    /* Setup a handler for the command register. */
428
68
    rc = vpci_add_register(pdev->vpci, vpci_hw_read16, cmd_write, PCI_COMMAND,
429
68
                           2, header);
430
68
    if ( rc )
431
0
        return rc;
432
68
433
68
    /* Disable memory decoding before sizing. */
434
68
    cmd = pci_conf_read16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND);
435
68
    if ( cmd & PCI_COMMAND_MEMORY )
436
27
        pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
437
27
                         cmd & ~PCI_COMMAND_MEMORY);
438
68
439
436
    for ( i = 0; i < num_bars; i++ )
440
368
    {
441
368
        uint8_t reg = PCI_BASE_ADDRESS_0 + i * 4;
442
368
        uint32_t val;
443
368
444
368
        if ( i && bars[i - 1].type == VPCI_BAR_MEM64_LO )
445
7
        {
446
7
            bars[i].type = VPCI_BAR_MEM64_HI;
447
7
            rc = vpci_add_register(pdev->vpci, vpci_hw_read32, bar_write, reg,
448
7
                                   4, &bars[i]);
449
7
            if ( rc )
450
0
            {
451
0
                pci_conf_write16(pdev->seg, pdev->bus, slot, func,
452
0
                                 PCI_COMMAND, cmd);
453
0
                return rc;
454
0
            }
455
7
456
7
            continue;
457
7
        }
458
368
459
361
        val = pci_conf_read32(pdev->seg, pdev->bus, slot, func, reg);
460
361
        if ( (val & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO )
461
18
        {
462
18
            bars[i].type = VPCI_BAR_IO;
463
18
            continue;
464
18
        }
465
343
        if ( (val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
466
343
             PCI_BASE_ADDRESS_MEM_TYPE_64 )
467
7
            bars[i].type = VPCI_BAR_MEM64_LO;
468
343
        else
469
336
            bars[i].type = VPCI_BAR_MEM32;
470
343
471
343
        rc = pci_size_mem_bar(sbdf, reg, &addr, &size,
472
275
                              (i == num_bars - 1) ? PCI_BAR_LAST : 0);
473
343
        if ( rc < 0 )
474
0
        {
475
0
            pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
476
0
                             cmd);
477
0
            return rc;
478
0
        }
479
343
480
343
        if ( size == 0 )
481
317
        {
482
317
            bars[i].type = VPCI_BAR_EMPTY;
483
317
            continue;
484
317
        }
485
343
486
26
        bars[i].addr = addr;
487
26
        bars[i].size = size;
488
26
        bars[i].prefetchable = val & PCI_BASE_ADDRESS_MEM_PREFETCH;
489
26
490
26
        rc = vpci_add_register(pdev->vpci, vpci_hw_read32, bar_write, reg, 4,
491
26
                               &bars[i]);
492
26
        if ( rc )
493
0
        {
494
0
            pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
495
0
                             cmd);
496
0
            return rc;
497
0
        }
498
26
    }
499
68
500
68
    /* Check expansion ROM. */
501
68
    rc = pci_size_mem_bar(sbdf, rom_reg, &addr, &size, PCI_BAR_ROM);
502
68
    if ( rc > 0 && size )
503
1
    {
504
1
        struct vpci_bar *rom = &header->bars[num_bars];
505
1
506
1
        rom->type = VPCI_BAR_ROM;
507
1
        rom->size = size;
508
1
        rom->addr = addr;
509
1
        rom->rom_enabled = pci_conf_read32(pdev->seg, pdev->bus, slot, func,
510
1
                                           rom_reg) & PCI_ROM_ADDRESS_ENABLE;
511
1
512
1
        rc = vpci_add_register(pdev->vpci, vpci_hw_read32, rom_write, rom_reg,
513
1
                               4, rom);
514
1
        if ( rc )
515
0
            rom->type = VPCI_BAR_EMPTY;
516
1
    }
517
68
518
68
    if ( cmd & PCI_COMMAND_MEMORY )
519
27
        modify_bars(pdev, true, false);
520
68
521
68
    return 0;
522
68
}
523
REGISTER_VPCI_INIT(init_bars, VPCI_PRIORITY_MIDDLE);
524
525
/*
526
 * Local variables:
527
 * mode: C
528
 * c-file-style: "BSD"
529
 * c-basic-offset: 4
530
 * tab-width: 4
531
 * indent-tabs-mode: nil
532
 * End:
533
 */