Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/arch/x86/hvm/io.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * io.c: Handling I/O and interrupts.
3
 *
4
 * Copyright (c) 2004, Intel Corporation.
5
 * Copyright (c) 2005, International Business Machines Corporation.
6
 * Copyright (c) 2008, Citrix Systems, Inc.
7
 *
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms and conditions of the GNU General Public License,
10
 * version 2, as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope it will be useful, but WITHOUT
13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15
 * more details.
16
 *
17
 * You should have received a copy of the GNU General Public License along with
18
 * this program; If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include <xen/init.h>
22
#include <xen/mm.h>
23
#include <xen/lib.h>
24
#include <xen/errno.h>
25
#include <xen/trace.h>
26
#include <xen/event.h>
27
#include <xen/hypercall.h>
28
#include <xen/vpci.h>
29
#include <asm/current.h>
30
#include <asm/cpufeature.h>
31
#include <asm/processor.h>
32
#include <asm/msr.h>
33
#include <asm/apic.h>
34
#include <asm/paging.h>
35
#include <asm/shadow.h>
36
#include <asm/p2m.h>
37
#include <asm/hvm/hvm.h>
38
#include <asm/hvm/ioreq.h>
39
#include <asm/hvm/support.h>
40
#include <asm/hvm/vpt.h>
41
#include <asm/hvm/vpic.h>
42
#include <asm/hvm/vlapic.h>
43
#include <asm/hvm/trace.h>
44
#include <asm/hvm/emulate.h>
45
#include <public/sched.h>
46
#include <xen/iocap.h>
47
#include <public/hvm/ioreq.h>
48
49
void send_timeoffset_req(unsigned long timeoff)
50
0
{
51
0
    ioreq_t p = {
52
0
        .type = IOREQ_TYPE_TIMEOFFSET,
53
0
        .size = 8,
54
0
        .count = 1,
55
0
        .dir = IOREQ_WRITE,
56
0
        .data = timeoff,
57
0
        .state = STATE_IOREQ_READY,
58
0
    };
59
0
60
0
    if ( timeoff == 0 )
61
0
        return;
62
0
63
0
    if ( hvm_broadcast_ioreq(&p, true) != 0 )
64
0
        gprintk(XENLOG_ERR, "Unsuccessful timeoffset update\n");
65
0
}
66
67
/* Ask ioemu mapcache to invalidate mappings. */
68
void send_invalidate_req(void)
69
0
{
70
0
    ioreq_t p = {
71
0
        .type = IOREQ_TYPE_INVALIDATE,
72
0
        .size = 4,
73
0
        .dir = IOREQ_WRITE,
74
0
        .data = ~0UL, /* flush all */
75
0
    };
76
0
77
0
    if ( hvm_broadcast_ioreq(&p, false) != 0 )
78
0
        gprintk(XENLOG_ERR, "Unsuccessful map-cache invalidate\n");
79
0
}
80
81
bool hvm_emulate_one_insn(hvm_emulate_validate_t *validate, const char *descr)
82
60.1k
{
83
60.1k
    struct hvm_emulate_ctxt ctxt;
84
60.1k
    struct vcpu *curr = current;
85
60.1k
    struct hvm_vcpu_io *vio = &curr->arch.hvm_vcpu.hvm_io;
86
60.1k
    int rc;
87
60.1k
88
60.1k
    hvm_emulate_init_once(&ctxt, validate, guest_cpu_user_regs());
89
60.1k
90
60.1k
    rc = hvm_emulate_one(&ctxt);
91
60.1k
92
60.1k
    if ( hvm_vcpu_io_need_completion(vio) || vio->mmio_retry )
93
0
        vio->io_completion = HVMIO_mmio_completion;
94
60.1k
    else
95
60.1k
        vio->mmio_access = (struct npfec){};
96
60.1k
97
60.1k
    switch ( rc )
98
60.1k
    {
99
0
    case X86EMUL_UNHANDLEABLE:
100
0
        hvm_dump_emulation_state(XENLOG_G_WARNING, descr, &ctxt, rc);
101
0
        return false;
102
0
103
0
    case X86EMUL_UNRECOGNIZED:
104
0
        hvm_dump_emulation_state(XENLOG_G_WARNING, descr, &ctxt, rc);
105
0
        hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC);
106
0
        break;
107
0
108
0
    case X86EMUL_EXCEPTION:
109
0
        hvm_inject_event(&ctxt.ctxt.event);
110
0
        break;
111
60.1k
    }
112
60.1k
113
60.1k
    hvm_emulate_writeback(&ctxt);
114
60.1k
115
60.1k
    return true;
116
60.1k
}
117
118
bool handle_mmio_with_translation(unsigned long gla, unsigned long gpfn,
119
                                  struct npfec access)
120
60.1k
{
121
60.1k
    struct hvm_vcpu_io *vio = &current->arch.hvm_vcpu.hvm_io;
122
60.1k
123
60.1k
    vio->mmio_access = access.gla_valid &&
124
60.1k
                       access.kind == npfec_kind_with_gla
125
60.1k
                       ? access : (struct npfec){};
126
60.1k
    vio->mmio_gla = gla & PAGE_MASK;
127
60.1k
    vio->mmio_gpfn = gpfn;
128
60.1k
    return handle_mmio();
129
60.1k
}
130
131
bool handle_pio(uint16_t port, unsigned int size, int dir)
132
20.1k
{
133
20.1k
    struct vcpu *curr = current;
134
20.1k
    struct hvm_vcpu_io *vio = &curr->arch.hvm_vcpu.hvm_io;
135
20.1k
    unsigned long data;
136
20.1k
    int rc;
137
20.1k
138
20.1k
    ASSERT((size - 1) < 4 && size != 3);
139
20.1k
140
20.1k
    if ( dir == IOREQ_WRITE )
141
58
        data = guest_cpu_user_regs()->eax;
142
20.1k
143
20.1k
    rc = hvmemul_do_pio_buffer(port, size, dir, &data);
144
20.1k
145
20.1k
    if ( hvm_vcpu_io_need_completion(vio) )
146
0
        vio->io_completion = HVMIO_pio_completion;
147
20.1k
148
20.1k
    switch ( rc )
149
20.1k
    {
150
20.1k
    case X86EMUL_OKAY:
151
20.1k
        if ( dir == IOREQ_READ )
152
20.0k
        {
153
20.0k
            if ( size == 4 ) /* Needs zero extension. */
154
20.0k
                guest_cpu_user_regs()->rax = (uint32_t)data;
155
20.0k
            else
156
7
                memcpy(&guest_cpu_user_regs()->rax, &data, size);
157
20.0k
        }
158
20.1k
        break;
159
20.1k
160
0
    case X86EMUL_RETRY:
161
0
        /*
162
0
         * We should not advance RIP/EIP if the domain is shutting down or
163
0
         * if X86EMUL_RETRY has been returned by an internal handler.
164
0
         */
165
0
        if ( curr->domain->is_shutting_down || !hvm_io_pending(curr) )
166
0
            return false;
167
0
        break;
168
0
169
0
    default:
170
0
        gdprintk(XENLOG_ERR, "Weird HVM ioemulation status %d.\n", rc);
171
0
        domain_crash(curr->domain);
172
0
        return false;
173
20.1k
    }
174
20.1k
175
20.1k
    return true;
176
20.1k
}
177
178
static bool_t g2m_portio_accept(const struct hvm_io_handler *handler,
179
                                const ioreq_t *p)
180
20.1k
{
181
20.1k
    struct vcpu *curr = current;
182
20.1k
    const struct hvm_domain *hvm_domain = &curr->domain->arch.hvm_domain;
183
20.1k
    struct hvm_vcpu_io *vio = &curr->arch.hvm_vcpu.hvm_io;
184
20.1k
    struct g2m_ioport *g2m_ioport;
185
20.1k
    unsigned int start, end;
186
20.1k
187
20.1k
    list_for_each_entry( g2m_ioport, &hvm_domain->g2m_ioport_list, list )
188
0
    {
189
0
        start = g2m_ioport->gport;
190
0
        end = start + g2m_ioport->np;
191
0
        if ( (p->addr >= start) && (p->addr + p->size <= end) )
192
0
        {
193
0
            vio->g2m_ioport = g2m_ioport;
194
0
            return 1;
195
0
        }
196
0
    }
197
20.1k
198
20.1k
    return 0;
199
20.1k
}
200
201
static int g2m_portio_read(const struct hvm_io_handler *handler,
202
                           uint64_t addr, uint32_t size, uint64_t *data)
203
0
{
204
0
    struct hvm_vcpu_io *vio = &current->arch.hvm_vcpu.hvm_io;
205
0
    const struct g2m_ioport *g2m_ioport = vio->g2m_ioport;
206
0
    unsigned int mport = (addr - g2m_ioport->gport) + g2m_ioport->mport;
207
0
208
0
    switch ( size )
209
0
    {
210
0
    case 1:
211
0
        *data = inb(mport);
212
0
        break;
213
0
    case 2:
214
0
        *data = inw(mport);
215
0
        break;
216
0
    case 4:
217
0
        *data = inl(mport);
218
0
        break;
219
0
    default:
220
0
        BUG();
221
0
    }
222
0
223
0
    return X86EMUL_OKAY;
224
0
}
225
226
static int g2m_portio_write(const struct hvm_io_handler *handler,
227
                            uint64_t addr, uint32_t size, uint64_t data)
228
0
{
229
0
    struct hvm_vcpu_io *vio = &current->arch.hvm_vcpu.hvm_io;
230
0
    const struct g2m_ioport *g2m_ioport = vio->g2m_ioport;
231
0
    unsigned int mport = (addr - g2m_ioport->gport) + g2m_ioport->mport;
232
0
233
0
    switch ( size )
234
0
    {
235
0
    case 1:
236
0
        outb(data, mport);
237
0
        break;
238
0
    case 2:
239
0
        outw(data, mport);
240
0
        break;
241
0
    case 4:
242
0
        outl(data, mport);
243
0
        break;
244
0
    default:
245
0
        BUG();
246
0
    }
247
0
248
0
    return X86EMUL_OKAY;
249
0
}
250
251
static const struct hvm_io_ops g2m_portio_ops = {
252
    .accept = g2m_portio_accept,
253
    .read = g2m_portio_read,
254
    .write = g2m_portio_write
255
};
256
257
void register_g2m_portio_handler(struct domain *d)
258
1
{
259
1
    struct hvm_io_handler *handler = hvm_next_io_handler(d);
260
1
261
1
    if ( handler == NULL )
262
0
        return;
263
1
264
1
    handler->type = IOREQ_TYPE_PIO;
265
1
    handler->ops = &g2m_portio_ops;
266
1
}
267
268
unsigned int hvm_pci_decode_addr(unsigned int cf8, unsigned int addr,
269
                                 pci_sbdf_t *sbdf)
270
32
{
271
32
    ASSERT(CF8_ENABLED(cf8));
272
32
273
32
    sbdf->bdf = CF8_BDF(cf8);
274
32
    sbdf->seg = 0;
275
32
    /*
276
32
     * NB: the lower 2 bits of the register address are fetched from the
277
32
     * offset into the 0xcfc register when reading/writing to it.
278
32
     */
279
32
    return CF8_ADDR_LO(cf8) | (addr & 3);
280
32
}
281
282
/* Do some sanity checks. */
283
static bool vpci_access_allowed(unsigned int reg, unsigned int len)
284
58.3k
{
285
58.3k
    /* Check access size. */
286
58.3k
    if ( len != 1 && len != 2 && len != 4 && len != 8 )
287
0
        return false;
288
58.3k
289
58.3k
    /* Check that access is size aligned. */
290
58.3k
    if ( (reg & (len - 1)) )
291
1
        return false;
292
58.3k
293
58.3k
    return true;
294
58.3k
}
295
296
/* vPCI config space IO ports handlers (0xcf8/0xcfc). */
297
static bool vpci_portio_accept(const struct hvm_io_handler *handler,
298
                               const ioreq_t *p)
299
20.1k
{
300
20.0k
    return (p->addr == 0xcf8 && p->size == 4) || (p->addr & ~3) == 0xcfc;
301
20.1k
}
302
303
static int vpci_portio_read(const struct hvm_io_handler *handler,
304
                            uint64_t addr, uint32_t size, uint64_t *data)
305
32
{
306
32
    struct domain *d = current->domain;
307
32
    unsigned int reg;
308
32
    pci_sbdf_t sbdf;
309
32
    uint32_t cf8;
310
32
311
32
    *data = ~(uint64_t)0;
312
32
313
32
    if ( addr == 0xcf8 )
314
0
    {
315
0
        ASSERT(size == 4);
316
0
        *data = d->arch.hvm_domain.pci_cf8;
317
0
        return X86EMUL_OKAY;
318
0
    }
319
32
320
32
    cf8 = ACCESS_ONCE(d->arch.hvm_domain.pci_cf8);
321
32
    if ( !CF8_ENABLED(cf8) )
322
0
        return X86EMUL_UNHANDLEABLE;
323
32
324
32
    reg = hvm_pci_decode_addr(cf8, addr, &sbdf);
325
32
326
32
    if ( !vpci_access_allowed(reg, size) )
327
0
        return X86EMUL_OKAY;
328
32
329
32
    *data = vpci_read(sbdf, reg, size);
330
32
331
32
    return X86EMUL_OKAY;
332
32
}
333
334
static int vpci_portio_write(const struct hvm_io_handler *handler,
335
                             uint64_t addr, uint32_t size, uint64_t data)
336
32
{
337
32
    struct domain *d = current->domain;
338
32
    unsigned int reg;
339
32
    pci_sbdf_t sbdf;
340
32
    uint32_t cf8;
341
32
342
32
    if ( addr == 0xcf8 )
343
32
    {
344
32
        ASSERT(size == 4);
345
32
        d->arch.hvm_domain.pci_cf8 = data;
346
32
        return X86EMUL_OKAY;
347
32
    }
348
32
349
0
    cf8 = ACCESS_ONCE(d->arch.hvm_domain.pci_cf8);
350
0
    if ( !CF8_ENABLED(cf8) )
351
0
        return X86EMUL_UNHANDLEABLE;
352
0
353
0
    reg = hvm_pci_decode_addr(cf8, addr, &sbdf);
354
0
355
0
    if ( !vpci_access_allowed(reg, size) )
356
0
        return X86EMUL_OKAY;
357
0
358
0
    vpci_write(sbdf, reg, size, data);
359
0
360
0
    return X86EMUL_OKAY;
361
0
}
362
363
static const struct hvm_io_ops vpci_portio_ops = {
364
    .accept = vpci_portio_accept,
365
    .read = vpci_portio_read,
366
    .write = vpci_portio_write,
367
};
368
369
void register_vpci_portio_handler(struct domain *d)
370
1
{
371
1
    struct hvm_io_handler *handler;
372
1
373
1
    if ( !has_vpci(d) )
374
0
        return;
375
1
376
1
    handler = hvm_next_io_handler(d);
377
1
    if ( !handler )
378
0
        return;
379
1
380
1
    handler->type = IOREQ_TYPE_PIO;
381
1
    handler->ops = &vpci_portio_ops;
382
1
}
383
384
struct hvm_mmcfg {
385
    struct list_head next;
386
    paddr_t addr;
387
    unsigned int size;
388
    uint16_t segment;
389
    uint8_t start_bus;
390
};
391
392
/* Handlers to trap PCI MMCFG config accesses. */
393
static const struct hvm_mmcfg *vpci_mmcfg_find(const struct domain *d,
394
                                               paddr_t addr)
395
596k
{
396
596k
    const struct hvm_mmcfg *mmcfg;
397
596k
398
596k
    list_for_each_entry ( mmcfg, &d->arch.hvm_domain.mmcfg_regions, next )
399
596k
        if ( addr >= mmcfg->addr && addr < mmcfg->addr + mmcfg->size )
400
229k
            return mmcfg;
401
596k
402
366k
    return NULL;
403
596k
}
404
405
static unsigned int vpci_mmcfg_decode_addr(const struct hvm_mmcfg *mmcfg,
406
                                           paddr_t addr, pci_sbdf_t *sbdf)
407
58.3k
{
408
58.3k
    addr -= mmcfg->addr;
409
58.3k
    sbdf->bdf = MMCFG_BDF(addr);
410
58.3k
    sbdf->bus += mmcfg->start_bus;
411
58.3k
    sbdf->seg = mmcfg->segment;
412
58.3k
413
58.3k
    return addr & (PCI_CFG_SPACE_EXP_SIZE - 1);
414
58.3k
}
415
416
static int vpci_mmcfg_accept(struct vcpu *v, unsigned long addr)
417
535k
{
418
535k
    struct domain *d = v->domain;
419
535k
    bool found;
420
535k
421
535k
    read_lock(&d->arch.hvm_domain.mmcfg_lock);
422
535k
    found = vpci_mmcfg_find(d, addr);
423
535k
    read_unlock(&d->arch.hvm_domain.mmcfg_lock);
424
535k
425
535k
    return found;
426
535k
}
427
428
static int vpci_mmcfg_read(struct vcpu *v, unsigned long addr,
429
                           unsigned int len, unsigned long *data)
430
55.8k
{
431
55.8k
    struct domain *d = v->domain;
432
55.8k
    const struct hvm_mmcfg *mmcfg;
433
55.8k
    unsigned int reg;
434
55.8k
    pci_sbdf_t sbdf;
435
55.8k
436
55.8k
    *data = ~0ul;
437
55.8k
438
55.8k
    read_lock(&d->arch.hvm_domain.mmcfg_lock);
439
55.8k
    mmcfg = vpci_mmcfg_find(d, addr);
440
55.8k
    if ( !mmcfg )
441
0
    {
442
0
        read_unlock(&d->arch.hvm_domain.mmcfg_lock);
443
0
        return X86EMUL_RETRY;
444
0
    }
445
55.8k
446
55.8k
    reg = vpci_mmcfg_decode_addr(mmcfg, addr, &sbdf);
447
55.8k
    read_unlock(&d->arch.hvm_domain.mmcfg_lock);
448
55.8k
449
55.8k
    if ( !vpci_access_allowed(reg, len) ||
450
55.8k
         (reg + len) > PCI_CFG_SPACE_EXP_SIZE )
451
1
        return X86EMUL_OKAY;
452
55.8k
453
55.8k
    /*
454
55.8k
     * According to the PCIe 3.1A specification:
455
55.8k
     *  - Configuration Reads and Writes must usually be DWORD or smaller
456
55.8k
     *    in size.
457
55.8k
     *  - Because Root Complex implementations are not required to support
458
55.8k
     *    accesses to a RCRB that cross DW boundaries [...] software
459
55.8k
     *    should take care not to cause the generation of such accesses
460
55.8k
     *    when accessing a RCRB unless the Root Complex will support the
461
55.8k
     *    access.
462
55.8k
     *  Xen however supports 8byte accesses by splitting them into two
463
55.8k
     *  4byte accesses.
464
55.8k
     */
465
55.8k
    *data = vpci_read(sbdf, reg, min(4u, len));
466
55.8k
    if ( len == 8 )
467
0
        *data |= (uint64_t)vpci_read(sbdf, reg + 4, 4) << 32;
468
55.8k
469
55.8k
    return X86EMUL_OKAY;
470
55.8k
}
471
472
static int vpci_mmcfg_write(struct vcpu *v, unsigned long addr,
473
                            unsigned int len, unsigned long data)
474
2.50k
{
475
2.50k
    struct domain *d = v->domain;
476
2.50k
    const struct hvm_mmcfg *mmcfg;
477
2.50k
    unsigned int reg;
478
2.50k
    pci_sbdf_t sbdf;
479
2.50k
480
2.50k
    read_lock(&d->arch.hvm_domain.mmcfg_lock);
481
2.50k
    mmcfg = vpci_mmcfg_find(d, addr);
482
2.50k
    if ( !mmcfg )
483
0
    {
484
0
        read_unlock(&d->arch.hvm_domain.mmcfg_lock);
485
0
        return X86EMUL_RETRY;
486
0
    }
487
2.50k
488
2.50k
    reg = vpci_mmcfg_decode_addr(mmcfg, addr, &sbdf);
489
2.50k
    read_unlock(&d->arch.hvm_domain.mmcfg_lock);
490
2.50k
491
2.50k
    if ( !vpci_access_allowed(reg, len) ||
492
2.50k
         (reg + len) > PCI_CFG_SPACE_EXP_SIZE )
493
0
        return X86EMUL_OKAY;
494
2.50k
495
2.50k
    vpci_write(sbdf, reg, min(4u, len), data);
496
2.50k
    if ( len == 8 )
497
0
        vpci_write(sbdf, reg + 4, 4, data >> 32);
498
2.50k
499
2.50k
    return X86EMUL_OKAY;
500
2.50k
}
501
502
static const struct hvm_mmio_ops vpci_mmcfg_ops = {
503
    .check = vpci_mmcfg_accept,
504
    .read = vpci_mmcfg_read,
505
    .write = vpci_mmcfg_write,
506
};
507
508
int register_vpci_mmcfg_handler(struct domain *d, paddr_t addr,
509
                                unsigned int start_bus, unsigned int end_bus,
510
                                unsigned int seg)
511
1
{
512
1
    struct hvm_mmcfg *mmcfg, *new = xmalloc(struct hvm_mmcfg);
513
1
514
1
    ASSERT(is_hardware_domain(d));
515
1
516
1
    if ( !new )
517
0
        return -ENOMEM;
518
1
519
1
    new->addr = addr + (start_bus << 20);
520
1
    new->start_bus = start_bus;
521
1
    new->segment = seg;
522
1
    new->size = (end_bus - start_bus + 1) << 20;;
523
1
524
1
    write_lock(&d->arch.hvm_domain.mmcfg_lock);
525
1
    list_for_each_entry ( mmcfg, &d->arch.hvm_domain.mmcfg_regions, next )
526
0
        if ( new->addr < mmcfg->addr + mmcfg->size &&
527
0
             mmcfg->addr < new->addr + new->size )
528
0
        {
529
0
            int ret = -EEXIST;
530
0
531
0
            if ( new->addr == mmcfg->addr &&
532
0
                 new->start_bus == mmcfg->start_bus &&
533
0
                 new->segment == mmcfg->segment &&
534
0
                 new->size == mmcfg->size )
535
0
                ret = 0;
536
0
            write_unlock(&d->arch.hvm_domain.mmcfg_lock);
537
0
            xfree(new);
538
0
            return ret;
539
0
        }
540
1
541
1
    if ( list_empty(&d->arch.hvm_domain.mmcfg_regions) )
542
1
        register_mmio_handler(d, &vpci_mmcfg_ops);
543
1
544
1
    list_add(&new->next, &d->arch.hvm_domain.mmcfg_regions);
545
1
    write_unlock(&d->arch.hvm_domain.mmcfg_lock);
546
1
547
1
    return 0;
548
1
}
549
550
void destroy_vpci_mmcfg(struct list_head *domain_mmcfg)
551
0
{
552
0
    while ( !list_empty(domain_mmcfg) )
553
0
    {
554
0
        struct hvm_mmcfg *mmcfg = list_first_entry(domain_mmcfg,
555
0
                                                   struct hvm_mmcfg, next);
556
0
557
0
        list_del(&mmcfg->next);
558
0
        xfree(mmcfg);
559
0
    }
560
0
}
561
562
/*
563
 * Local variables:
564
 * mode: C
565
 * c-file-style: "BSD"
566
 * c-basic-offset: 4
567
 * tab-width: 4
568
 * indent-tabs-mode: nil
569
 * End:
570
 */