Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/arch/x86/hvm/ioreq.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * hvm/io.c: hardware virtual machine I/O emulation
3
 *
4
 * Copyright (c) 2016 Citrix Systems Inc.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms and conditions of the GNU General Public License,
8
 * version 2, as published by the Free Software Foundation.
9
 *
10
 * This program is distributed in the hope it will be useful, but WITHOUT
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13
 * more details.
14
 *
15
 * You should have received a copy of the GNU General Public License along with
16
 * this program; If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
#include <xen/ctype.h>
20
#include <xen/init.h>
21
#include <xen/lib.h>
22
#include <xen/trace.h>
23
#include <xen/sched.h>
24
#include <xen/irq.h>
25
#include <xen/softirq.h>
26
#include <xen/domain.h>
27
#include <xen/event.h>
28
#include <xen/paging.h>
29
#include <xen/vpci.h>
30
31
#include <asm/hvm/hvm.h>
32
#include <asm/hvm/ioreq.h>
33
#include <asm/hvm/vmx/vmx.h>
34
35
#include <public/hvm/ioreq.h>
36
37
static ioreq_t *get_ioreq(struct hvm_ioreq_server *s, struct vcpu *v)
38
0
{
39
0
    shared_iopage_t *p = s->ioreq.va;
40
0
41
0
    ASSERT((v == current) || !vcpu_runnable(v));
42
0
    ASSERT(p != NULL);
43
0
44
0
    return &p->vcpu_ioreq[v->vcpu_id];
45
0
}
46
47
bool hvm_io_pending(struct vcpu *v)
48
9.75M
{
49
9.75M
    struct domain *d = v->domain;
50
9.75M
    struct hvm_ioreq_server *s;
51
9.75M
52
9.77M
    if ( has_vpci(d) && vpci_process_pending(v) )
53
391
        return true;
54
9.75M
55
9.75M
    list_for_each_entry ( s,
56
9.75M
                          &d->arch.hvm_domain.ioreq_server.list,
57
9.75M
                          list_entry )
58
0
    {
59
0
        struct hvm_ioreq_vcpu *sv;
60
0
61
0
        list_for_each_entry ( sv,
62
0
                              &s->ioreq_vcpu_list,
63
0
                              list_entry )
64
0
        {
65
0
            if ( sv->vcpu == v && sv->pending )
66
0
                return true;
67
0
        }
68
0
    }
69
9.75M
70
9.75M
    return false;
71
9.75M
}
72
73
static void hvm_io_assist(struct hvm_ioreq_vcpu *sv, uint64_t data)
74
0
{
75
0
    struct vcpu *v = sv->vcpu;
76
0
    struct hvm_vcpu_io *vio = &v->arch.hvm_vcpu.hvm_io;
77
0
78
0
    if ( hvm_vcpu_io_need_completion(vio) )
79
0
    {
80
0
        vio->io_req.state = STATE_IORESP_READY;
81
0
        vio->io_req.data = data;
82
0
    }
83
0
    else
84
0
        vio->io_req.state = STATE_IOREQ_NONE;
85
0
86
0
    msix_write_completion(v);
87
0
    vcpu_end_shutdown_deferral(v);
88
0
89
0
    sv->pending = false;
90
0
}
91
92
static bool hvm_wait_for_io(struct hvm_ioreq_vcpu *sv, ioreq_t *p)
93
0
{
94
0
    while ( sv->pending )
95
0
    {
96
0
        unsigned int state = p->state;
97
0
98
0
        rmb();
99
0
        switch ( state )
100
0
        {
101
0
        case STATE_IOREQ_NONE:
102
0
            /*
103
0
             * The only reason we should see this case is when an
104
0
             * emulator is dying and it races with an I/O being
105
0
             * requested.
106
0
             */
107
0
            hvm_io_assist(sv, ~0ul);
108
0
            break;
109
0
        case STATE_IORESP_READY: /* IORESP_READY -> NONE */
110
0
            p->state = STATE_IOREQ_NONE;
111
0
            hvm_io_assist(sv, p->data);
112
0
            break;
113
0
        case STATE_IOREQ_READY:  /* IOREQ_{READY,INPROCESS} -> IORESP_READY */
114
0
        case STATE_IOREQ_INPROCESS:
115
0
            wait_on_xen_event_channel(sv->ioreq_evtchn, p->state != state);
116
0
            break;
117
0
        default:
118
0
            gdprintk(XENLOG_ERR, "Weird HVM iorequest state %u\n", state);
119
0
            sv->pending = false;
120
0
            domain_crash(sv->vcpu->domain);
121
0
            return false; /* bail */
122
0
        }
123
0
    }
124
0
125
0
    return true;
126
0
}
127
128
bool handle_hvm_io_completion(struct vcpu *v)
129
4.60M
{
130
4.60M
    struct domain *d = v->domain;
131
4.60M
    struct hvm_vcpu_io *vio = &v->arch.hvm_vcpu.hvm_io;
132
4.60M
    struct hvm_ioreq_server *s;
133
4.60M
    enum hvm_io_completion io_completion;
134
4.60M
135
4.60M
      list_for_each_entry ( s,
136
4.60M
                          &d->arch.hvm_domain.ioreq_server.list,
137
4.60M
                          list_entry )
138
0
    {
139
0
        struct hvm_ioreq_vcpu *sv;
140
0
141
0
        list_for_each_entry ( sv,
142
0
                              &s->ioreq_vcpu_list,
143
0
                              list_entry )
144
0
        {
145
0
            if ( sv->vcpu == v && sv->pending )
146
0
            {
147
0
                if ( !hvm_wait_for_io(sv, get_ioreq(s, v)) )
148
0
                    return false;
149
0
150
0
                break;
151
0
            }
152
0
        }
153
0
    }
154
4.60M
155
4.60M
    io_completion = vio->io_completion;
156
4.60M
    vio->io_completion = HVMIO_no_completion;
157
4.60M
158
4.60M
    switch ( io_completion )
159
4.60M
    {
160
4.60M
    case HVMIO_no_completion:
161
4.60M
        break;
162
4.60M
163
0
    case HVMIO_mmio_completion:
164
0
        return handle_mmio();
165
4.60M
166
0
    case HVMIO_pio_completion:
167
0
        return handle_pio(vio->io_req.addr, vio->io_req.size,
168
0
                          vio->io_req.dir);
169
4.60M
170
0
    case HVMIO_realmode_completion:
171
0
    {
172
0
        struct hvm_emulate_ctxt ctxt;
173
0
174
0
        hvm_emulate_init_once(&ctxt, NULL, guest_cpu_user_regs());
175
0
        vmx_realmode_emulate_one(&ctxt);
176
0
        hvm_emulate_writeback(&ctxt);
177
0
178
0
        break;
179
4.60M
    }
180
0
    default:
181
0
        ASSERT_UNREACHABLE();
182
0
        break;
183
4.60M
    }
184
4.60M
185
4.63M
    return true;
186
4.60M
}
187
188
static int hvm_alloc_ioreq_gfn(struct domain *d, unsigned long *gfn)
189
0
{
190
0
    unsigned int i;
191
0
    int rc;
192
0
193
0
    rc = -ENOMEM;
194
0
    for ( i = 0; i < sizeof(d->arch.hvm_domain.ioreq_gfn.mask) * 8; i++ )
195
0
    {
196
0
        if ( test_and_clear_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask) )
197
0
        {
198
0
            *gfn = d->arch.hvm_domain.ioreq_gfn.base + i;
199
0
            rc = 0;
200
0
            break;
201
0
        }
202
0
    }
203
0
204
0
    return rc;
205
0
}
206
207
static void hvm_free_ioreq_gfn(struct domain *d, unsigned long gfn)
208
0
{
209
0
    unsigned int i = gfn - d->arch.hvm_domain.ioreq_gfn.base;
210
0
211
0
    if ( gfn != gfn_x(INVALID_GFN) )
212
0
        set_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask);
213
0
}
214
215
static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool buf)
216
0
{
217
0
    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
218
0
219
0
    destroy_ring_for_helper(&iorp->va, iorp->page);
220
0
}
221
222
static int hvm_map_ioreq_page(
223
    struct hvm_ioreq_server *s, bool buf, unsigned long gfn)
224
0
{
225
0
    struct domain *d = s->domain;
226
0
    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
227
0
    struct page_info *page;
228
0
    void *va;
229
0
    int rc;
230
0
231
0
    if ( (rc = prepare_ring_for_helper(d, gfn, &page, &va)) )
232
0
        return rc;
233
0
234
0
    if ( (iorp->va != NULL) || d->is_dying )
235
0
    {
236
0
        destroy_ring_for_helper(&va, page);
237
0
        return -EINVAL;
238
0
    }
239
0
240
0
    iorp->va = va;
241
0
    iorp->page = page;
242
0
    iorp->gfn = gfn;
243
0
244
0
    return 0;
245
0
}
246
247
bool is_ioreq_server_page(struct domain *d, const struct page_info *page)
248
0
{
249
0
    const struct hvm_ioreq_server *s;
250
0
    bool found = false;
251
0
252
0
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
253
0
254
0
    list_for_each_entry ( s,
255
0
                          &d->arch.hvm_domain.ioreq_server.list,
256
0
                          list_entry )
257
0
    {
258
0
        if ( (s->ioreq.va && s->ioreq.page == page) ||
259
0
             (s->bufioreq.va && s->bufioreq.page == page) )
260
0
        {
261
0
            found = true;
262
0
            break;
263
0
        }
264
0
    }
265
0
266
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
267
0
268
0
    return found;
269
0
}
270
271
static void hvm_remove_ioreq_gfn(
272
    struct domain *d, struct hvm_ioreq_page *iorp)
273
0
{
274
0
    if ( guest_physmap_remove_page(d, _gfn(iorp->gfn),
275
0
                                   _mfn(page_to_mfn(iorp->page)), 0) )
276
0
        domain_crash(d);
277
0
    clear_page(iorp->va);
278
0
}
279
280
static int hvm_add_ioreq_gfn(
281
    struct domain *d, struct hvm_ioreq_page *iorp)
282
0
{
283
0
    int rc;
284
0
285
0
    clear_page(iorp->va);
286
0
287
0
    rc = guest_physmap_add_page(d, _gfn(iorp->gfn),
288
0
                                _mfn(page_to_mfn(iorp->page)), 0);
289
0
    if ( rc == 0 )
290
0
        paging_mark_dirty(d, _mfn(page_to_mfn(iorp->page)));
291
0
292
0
    return rc;
293
0
}
294
295
static void hvm_update_ioreq_evtchn(struct hvm_ioreq_server *s,
296
                                    struct hvm_ioreq_vcpu *sv)
297
0
{
298
0
    ASSERT(spin_is_locked(&s->lock));
299
0
300
0
    if ( s->ioreq.va != NULL )
301
0
    {
302
0
        ioreq_t *p = get_ioreq(s, sv->vcpu);
303
0
304
0
        p->vp_eport = sv->ioreq_evtchn;
305
0
    }
306
0
}
307
308
static int hvm_ioreq_server_add_vcpu(struct hvm_ioreq_server *s,
309
                                     bool is_default, struct vcpu *v)
310
0
{
311
0
    struct hvm_ioreq_vcpu *sv;
312
0
    int rc;
313
0
314
0
    sv = xzalloc(struct hvm_ioreq_vcpu);
315
0
316
0
    rc = -ENOMEM;
317
0
    if ( !sv )
318
0
        goto fail1;
319
0
320
0
    spin_lock(&s->lock);
321
0
322
0
    rc = alloc_unbound_xen_event_channel(v->domain, v->vcpu_id, s->domid,
323
0
                                         NULL);
324
0
    if ( rc < 0 )
325
0
        goto fail2;
326
0
327
0
    sv->ioreq_evtchn = rc;
328
0
329
0
    if ( v->vcpu_id == 0 && s->bufioreq.va != NULL )
330
0
    {
331
0
        struct domain *d = s->domain;
332
0
333
0
        rc = alloc_unbound_xen_event_channel(v->domain, 0, s->domid, NULL);
334
0
        if ( rc < 0 )
335
0
            goto fail3;
336
0
337
0
        s->bufioreq_evtchn = rc;
338
0
        if ( is_default )
339
0
            d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_EVTCHN] =
340
0
                s->bufioreq_evtchn;
341
0
    }
342
0
343
0
    sv->vcpu = v;
344
0
345
0
    list_add(&sv->list_entry, &s->ioreq_vcpu_list);
346
0
347
0
    if ( s->enabled )
348
0
        hvm_update_ioreq_evtchn(s, sv);
349
0
350
0
    spin_unlock(&s->lock);
351
0
    return 0;
352
0
353
0
 fail3:
354
0
    free_xen_event_channel(v->domain, sv->ioreq_evtchn);
355
0
356
0
 fail2:
357
0
    spin_unlock(&s->lock);
358
0
    xfree(sv);
359
0
360
0
 fail1:
361
0
    return rc;
362
0
}
363
364
static void hvm_ioreq_server_remove_vcpu(struct hvm_ioreq_server *s,
365
                                         struct vcpu *v)
366
0
{
367
0
    struct hvm_ioreq_vcpu *sv;
368
0
369
0
    spin_lock(&s->lock);
370
0
371
0
    list_for_each_entry ( sv,
372
0
                          &s->ioreq_vcpu_list,
373
0
                          list_entry )
374
0
    {
375
0
        if ( sv->vcpu != v )
376
0
            continue;
377
0
378
0
        list_del(&sv->list_entry);
379
0
380
0
        if ( v->vcpu_id == 0 && s->bufioreq.va != NULL )
381
0
            free_xen_event_channel(v->domain, s->bufioreq_evtchn);
382
0
383
0
        free_xen_event_channel(v->domain, sv->ioreq_evtchn);
384
0
385
0
        xfree(sv);
386
0
        break;
387
0
    }
388
0
389
0
    spin_unlock(&s->lock);
390
0
}
391
392
static void hvm_ioreq_server_remove_all_vcpus(struct hvm_ioreq_server *s)
393
0
{
394
0
    struct hvm_ioreq_vcpu *sv, *next;
395
0
396
0
    spin_lock(&s->lock);
397
0
398
0
    list_for_each_entry_safe ( sv,
399
0
                               next,
400
0
                               &s->ioreq_vcpu_list,
401
0
                               list_entry )
402
0
    {
403
0
        struct vcpu *v = sv->vcpu;
404
0
405
0
        list_del(&sv->list_entry);
406
0
407
0
        if ( v->vcpu_id == 0 && s->bufioreq.va != NULL )
408
0
            free_xen_event_channel(v->domain, s->bufioreq_evtchn);
409
0
410
0
        free_xen_event_channel(v->domain, sv->ioreq_evtchn);
411
0
412
0
        xfree(sv);
413
0
    }
414
0
415
0
    spin_unlock(&s->lock);
416
0
}
417
418
static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
419
                                      unsigned long ioreq_gfn,
420
                                      unsigned long bufioreq_gfn)
421
0
{
422
0
    int rc;
423
0
424
0
    rc = hvm_map_ioreq_page(s, false, ioreq_gfn);
425
0
    if ( rc )
426
0
        return rc;
427
0
428
0
    if ( bufioreq_gfn != gfn_x(INVALID_GFN) )
429
0
        rc = hvm_map_ioreq_page(s, true, bufioreq_gfn);
430
0
431
0
    if ( rc )
432
0
        hvm_unmap_ioreq_page(s, false);
433
0
434
0
    return rc;
435
0
}
436
437
static int hvm_ioreq_server_setup_pages(struct hvm_ioreq_server *s,
438
                                        bool is_default,
439
                                        bool handle_bufioreq)
440
0
{
441
0
    struct domain *d = s->domain;
442
0
    unsigned long ioreq_gfn = gfn_x(INVALID_GFN);
443
0
    unsigned long bufioreq_gfn = gfn_x(INVALID_GFN);
444
0
    int rc;
445
0
446
0
    if ( is_default )
447
0
    {
448
0
        /*
449
0
         * The default ioreq server must handle buffered ioreqs, for
450
0
         * backwards compatibility.
451
0
         */
452
0
        ASSERT(handle_bufioreq);
453
0
        return hvm_ioreq_server_map_pages(s,
454
0
                   d->arch.hvm_domain.params[HVM_PARAM_IOREQ_PFN],
455
0
                   d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_PFN]);
456
0
    }
457
0
458
0
    rc = hvm_alloc_ioreq_gfn(d, &ioreq_gfn);
459
0
460
0
    if ( !rc && handle_bufioreq )
461
0
        rc = hvm_alloc_ioreq_gfn(d, &bufioreq_gfn);
462
0
463
0
    if ( !rc )
464
0
        rc = hvm_ioreq_server_map_pages(s, ioreq_gfn, bufioreq_gfn);
465
0
466
0
    if ( rc )
467
0
    {
468
0
        hvm_free_ioreq_gfn(d, ioreq_gfn);
469
0
        hvm_free_ioreq_gfn(d, bufioreq_gfn);
470
0
    }
471
0
472
0
    return rc;
473
0
}
474
475
static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s,
476
                                         bool is_default)
477
0
{
478
0
    struct domain *d = s->domain;
479
0
    bool handle_bufioreq = !!s->bufioreq.va;
480
0
481
0
    if ( handle_bufioreq )
482
0
        hvm_unmap_ioreq_page(s, true);
483
0
484
0
    hvm_unmap_ioreq_page(s, false);
485
0
486
0
    if ( !is_default )
487
0
    {
488
0
        if ( handle_bufioreq )
489
0
            hvm_free_ioreq_gfn(d, s->bufioreq.gfn);
490
0
491
0
        hvm_free_ioreq_gfn(d, s->ioreq.gfn);
492
0
    }
493
0
}
494
495
static void hvm_ioreq_server_free_rangesets(struct hvm_ioreq_server *s,
496
                                            bool is_default)
497
0
{
498
0
    unsigned int i;
499
0
500
0
    if ( is_default )
501
0
        return;
502
0
503
0
    for ( i = 0; i < NR_IO_RANGE_TYPES; i++ )
504
0
        rangeset_destroy(s->range[i]);
505
0
}
506
507
static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s,
508
                                            bool is_default)
509
0
{
510
0
    unsigned int i;
511
0
    int rc;
512
0
513
0
    if ( is_default )
514
0
        goto done;
515
0
516
0
    for ( i = 0; i < NR_IO_RANGE_TYPES; i++ )
517
0
    {
518
0
        char *name;
519
0
520
0
        rc = asprintf(&name, "ioreq_server %d %s", s->id,
521
0
                      (i == XEN_DMOP_IO_RANGE_PORT) ? "port" :
522
0
                      (i == XEN_DMOP_IO_RANGE_MEMORY) ? "memory" :
523
0
                      (i == XEN_DMOP_IO_RANGE_PCI) ? "pci" :
524
0
                      "");
525
0
        if ( rc )
526
0
            goto fail;
527
0
528
0
        s->range[i] = rangeset_new(s->domain, name,
529
0
                                   RANGESETF_prettyprint_hex);
530
0
531
0
        xfree(name);
532
0
533
0
        rc = -ENOMEM;
534
0
        if ( !s->range[i] )
535
0
            goto fail;
536
0
537
0
        rangeset_limit(s->range[i], MAX_NR_IO_RANGES);
538
0
    }
539
0
540
0
 done:
541
0
    return 0;
542
0
543
0
 fail:
544
0
    hvm_ioreq_server_free_rangesets(s, false);
545
0
546
0
    return rc;
547
0
}
548
549
static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s,
550
                                    bool is_default)
551
0
{
552
0
    struct domain *d = s->domain;
553
0
    struct hvm_ioreq_vcpu *sv;
554
0
    bool handle_bufioreq = !!s->bufioreq.va;
555
0
556
0
    spin_lock(&s->lock);
557
0
558
0
    if ( s->enabled )
559
0
        goto done;
560
0
561
0
    if ( !is_default )
562
0
    {
563
0
        hvm_remove_ioreq_gfn(d, &s->ioreq);
564
0
565
0
        if ( handle_bufioreq )
566
0
            hvm_remove_ioreq_gfn(d, &s->bufioreq);
567
0
    }
568
0
569
0
    s->enabled = true;
570
0
571
0
    list_for_each_entry ( sv,
572
0
                          &s->ioreq_vcpu_list,
573
0
                          list_entry )
574
0
        hvm_update_ioreq_evtchn(s, sv);
575
0
576
0
  done:
577
0
    spin_unlock(&s->lock);
578
0
}
579
580
static void hvm_ioreq_server_disable(struct hvm_ioreq_server *s,
581
                                     bool is_default)
582
0
{
583
0
    struct domain *d = s->domain;
584
0
    bool handle_bufioreq = !!s->bufioreq.va;
585
0
586
0
    spin_lock(&s->lock);
587
0
588
0
    if ( !s->enabled )
589
0
        goto done;
590
0
591
0
    if ( !is_default )
592
0
    {
593
0
        if ( handle_bufioreq )
594
0
            hvm_add_ioreq_gfn(d, &s->bufioreq);
595
0
596
0
        hvm_add_ioreq_gfn(d, &s->ioreq);
597
0
    }
598
0
599
0
    s->enabled = false;
600
0
601
0
 done:
602
0
    spin_unlock(&s->lock);
603
0
}
604
605
static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
606
                                 struct domain *d, domid_t domid,
607
                                 bool is_default, int bufioreq_handling,
608
                                 ioservid_t id)
609
0
{
610
0
    struct vcpu *v;
611
0
    int rc;
612
0
613
0
    s->id = id;
614
0
    s->domain = d;
615
0
    s->domid = domid;
616
0
617
0
    spin_lock_init(&s->lock);
618
0
    INIT_LIST_HEAD(&s->ioreq_vcpu_list);
619
0
    spin_lock_init(&s->bufioreq_lock);
620
0
621
0
    rc = hvm_ioreq_server_alloc_rangesets(s, is_default);
622
0
    if ( rc )
623
0
        return rc;
624
0
625
0
    if ( bufioreq_handling == HVM_IOREQSRV_BUFIOREQ_ATOMIC )
626
0
        s->bufioreq_atomic = true;
627
0
628
0
    rc = hvm_ioreq_server_setup_pages(
629
0
             s, is_default, bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF);
630
0
    if ( rc )
631
0
        goto fail_map;
632
0
633
0
    for_each_vcpu ( d, v )
634
0
    {
635
0
        rc = hvm_ioreq_server_add_vcpu(s, is_default, v);
636
0
        if ( rc )
637
0
            goto fail_add;
638
0
    }
639
0
640
0
    return 0;
641
0
642
0
 fail_add:
643
0
    hvm_ioreq_server_remove_all_vcpus(s);
644
0
    hvm_ioreq_server_unmap_pages(s, is_default);
645
0
646
0
 fail_map:
647
0
    hvm_ioreq_server_free_rangesets(s, is_default);
648
0
649
0
    return rc;
650
0
}
651
652
static void hvm_ioreq_server_deinit(struct hvm_ioreq_server *s,
653
                                    bool is_default)
654
0
{
655
0
    ASSERT(!s->enabled);
656
0
    hvm_ioreq_server_remove_all_vcpus(s);
657
0
    hvm_ioreq_server_unmap_pages(s, is_default);
658
0
    hvm_ioreq_server_free_rangesets(s, is_default);
659
0
}
660
661
static ioservid_t next_ioservid(struct domain *d)
662
0
{
663
0
    struct hvm_ioreq_server *s;
664
0
    ioservid_t id;
665
0
666
0
    ASSERT(spin_is_locked(&d->arch.hvm_domain.ioreq_server.lock));
667
0
668
0
    id = d->arch.hvm_domain.ioreq_server.id;
669
0
670
0
 again:
671
0
    id++;
672
0
673
0
    /* Check for uniqueness */
674
0
    list_for_each_entry ( s,
675
0
                          &d->arch.hvm_domain.ioreq_server.list,
676
0
                          list_entry )
677
0
    {
678
0
        if ( id == s->id )
679
0
            goto again;
680
0
    }
681
0
682
0
    d->arch.hvm_domain.ioreq_server.id = id;
683
0
684
0
    return id;
685
0
}
686
687
int hvm_create_ioreq_server(struct domain *d, domid_t domid,
688
                            bool is_default, int bufioreq_handling,
689
                            ioservid_t *id)
690
0
{
691
0
    struct hvm_ioreq_server *s;
692
0
    int rc;
693
0
694
0
    if ( bufioreq_handling > HVM_IOREQSRV_BUFIOREQ_ATOMIC )
695
0
        return -EINVAL;
696
0
697
0
    rc = -ENOMEM;
698
0
    s = xzalloc(struct hvm_ioreq_server);
699
0
    if ( !s )
700
0
        goto fail1;
701
0
702
0
    domain_pause(d);
703
0
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
704
0
705
0
    rc = -EEXIST;
706
0
    if ( is_default && d->arch.hvm_domain.default_ioreq_server != NULL )
707
0
        goto fail2;
708
0
709
0
    rc = hvm_ioreq_server_init(s, d, domid, is_default, bufioreq_handling,
710
0
                               next_ioservid(d));
711
0
    if ( rc )
712
0
        goto fail3;
713
0
714
0
    list_add(&s->list_entry,
715
0
             &d->arch.hvm_domain.ioreq_server.list);
716
0
717
0
    if ( is_default )
718
0
    {
719
0
        d->arch.hvm_domain.default_ioreq_server = s;
720
0
        hvm_ioreq_server_enable(s, true);
721
0
    }
722
0
723
0
    if ( id )
724
0
        *id = s->id;
725
0
726
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
727
0
    domain_unpause(d);
728
0
729
0
    return 0;
730
0
731
0
 fail3:
732
0
 fail2:
733
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
734
0
    domain_unpause(d);
735
0
736
0
    xfree(s);
737
0
 fail1:
738
0
    return rc;
739
0
}
740
741
int hvm_destroy_ioreq_server(struct domain *d, ioservid_t id)
742
0
{
743
0
    struct hvm_ioreq_server *s;
744
0
    int rc;
745
0
746
0
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
747
0
748
0
    rc = -ENOENT;
749
0
    list_for_each_entry ( s,
750
0
                          &d->arch.hvm_domain.ioreq_server.list,
751
0
                          list_entry )
752
0
    {
753
0
        if ( s == d->arch.hvm_domain.default_ioreq_server )
754
0
            continue;
755
0
756
0
        if ( s->id != id )
757
0
            continue;
758
0
759
0
        domain_pause(d);
760
0
761
0
        p2m_set_ioreq_server(d, 0, s);
762
0
763
0
        hvm_ioreq_server_disable(s, false);
764
0
765
0
        list_del(&s->list_entry);
766
0
767
0
        hvm_ioreq_server_deinit(s, false);
768
0
769
0
        domain_unpause(d);
770
0
771
0
        xfree(s);
772
0
773
0
        rc = 0;
774
0
        break;
775
0
    }
776
0
777
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
778
0
779
0
    return rc;
780
0
}
781
782
int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
783
                              unsigned long *ioreq_gfn,
784
                              unsigned long *bufioreq_gfn,
785
                              evtchn_port_t *bufioreq_port)
786
0
{
787
0
    struct hvm_ioreq_server *s;
788
0
    int rc;
789
0
790
0
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
791
0
792
0
    rc = -ENOENT;
793
0
    list_for_each_entry ( s,
794
0
                          &d->arch.hvm_domain.ioreq_server.list,
795
0
                          list_entry )
796
0
    {
797
0
        if ( s == d->arch.hvm_domain.default_ioreq_server )
798
0
            continue;
799
0
800
0
        if ( s->id != id )
801
0
            continue;
802
0
803
0
        *ioreq_gfn = s->ioreq.gfn;
804
0
805
0
        if ( s->bufioreq.va != NULL )
806
0
        {
807
0
            *bufioreq_gfn = s->bufioreq.gfn;
808
0
            *bufioreq_port = s->bufioreq_evtchn;
809
0
        }
810
0
811
0
        rc = 0;
812
0
        break;
813
0
    }
814
0
815
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
816
0
817
0
    return rc;
818
0
}
819
820
int hvm_map_io_range_to_ioreq_server(struct domain *d, ioservid_t id,
821
                                     uint32_t type, uint64_t start,
822
                                     uint64_t end)
823
0
{
824
0
    struct hvm_ioreq_server *s;
825
0
    int rc;
826
0
827
0
    if ( start > end )
828
0
        return -EINVAL;
829
0
830
0
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
831
0
832
0
    rc = -ENOENT;
833
0
    list_for_each_entry ( s,
834
0
                          &d->arch.hvm_domain.ioreq_server.list,
835
0
                          list_entry )
836
0
    {
837
0
        if ( s == d->arch.hvm_domain.default_ioreq_server )
838
0
            continue;
839
0
840
0
        if ( s->id == id )
841
0
        {
842
0
            struct rangeset *r;
843
0
844
0
            switch ( type )
845
0
            {
846
0
            case XEN_DMOP_IO_RANGE_PORT:
847
0
            case XEN_DMOP_IO_RANGE_MEMORY:
848
0
            case XEN_DMOP_IO_RANGE_PCI:
849
0
                r = s->range[type];
850
0
                break;
851
0
852
0
            default:
853
0
                r = NULL;
854
0
                break;
855
0
            }
856
0
857
0
            rc = -EINVAL;
858
0
            if ( !r )
859
0
                break;
860
0
861
0
            rc = -EEXIST;
862
0
            if ( rangeset_overlaps_range(r, start, end) )
863
0
                break;
864
0
865
0
            rc = rangeset_add_range(r, start, end);
866
0
            break;
867
0
        }
868
0
    }
869
0
870
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
871
0
872
0
    return rc;
873
0
}
874
875
int hvm_unmap_io_range_from_ioreq_server(struct domain *d, ioservid_t id,
876
                                         uint32_t type, uint64_t start,
877
                                         uint64_t end)
878
0
{
879
0
    struct hvm_ioreq_server *s;
880
0
    int rc;
881
0
882
0
    if ( start > end )
883
0
        return -EINVAL;
884
0
885
0
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
886
0
887
0
    rc = -ENOENT;
888
0
    list_for_each_entry ( s,
889
0
                          &d->arch.hvm_domain.ioreq_server.list,
890
0
                          list_entry )
891
0
    {
892
0
        if ( s == d->arch.hvm_domain.default_ioreq_server )
893
0
            continue;
894
0
895
0
        if ( s->id == id )
896
0
        {
897
0
            struct rangeset *r;
898
0
899
0
            switch ( type )
900
0
            {
901
0
            case XEN_DMOP_IO_RANGE_PORT:
902
0
            case XEN_DMOP_IO_RANGE_MEMORY:
903
0
            case XEN_DMOP_IO_RANGE_PCI:
904
0
                r = s->range[type];
905
0
                break;
906
0
907
0
            default:
908
0
                r = NULL;
909
0
                break;
910
0
            }
911
0
912
0
            rc = -EINVAL;
913
0
            if ( !r )
914
0
                break;
915
0
916
0
            rc = -ENOENT;
917
0
            if ( !rangeset_contains_range(r, start, end) )
918
0
                break;
919
0
920
0
            rc = rangeset_remove_range(r, start, end);
921
0
            break;
922
0
        }
923
0
    }
924
0
925
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
926
0
927
0
    return rc;
928
0
}
929
930
/*
931
 * Map or unmap an ioreq server to specific memory type. For now, only
932
 * HVMMEM_ioreq_server is supported, and in the future new types can be
933
 * introduced, e.g. HVMMEM_ioreq_serverX mapped to ioreq server X. And
934
 * currently, only write operations are to be forwarded to an ioreq server.
935
 * Support for the emulation of read operations can be added when an ioreq
936
 * server has such requirement in the future.
937
 */
938
int hvm_map_mem_type_to_ioreq_server(struct domain *d, ioservid_t id,
939
                                     uint32_t type, uint32_t flags)
940
0
{
941
0
    struct hvm_ioreq_server *s;
942
0
    int rc;
943
0
944
0
    if ( type != HVMMEM_ioreq_server )
945
0
        return -EINVAL;
946
0
947
0
    if ( flags & ~XEN_DMOP_IOREQ_MEM_ACCESS_WRITE )
948
0
        return -EINVAL;
949
0
950
0
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
951
0
952
0
    rc = -ENOENT;
953
0
    list_for_each_entry ( s,
954
0
                          &d->arch.hvm_domain.ioreq_server.list,
955
0
                          list_entry )
956
0
    {
957
0
        if ( s == d->arch.hvm_domain.default_ioreq_server )
958
0
            continue;
959
0
960
0
        if ( s->id == id )
961
0
        {
962
0
            rc = p2m_set_ioreq_server(d, flags, s);
963
0
            break;
964
0
        }
965
0
    }
966
0
967
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
968
0
969
0
    if ( rc == 0 && flags == 0 )
970
0
    {
971
0
        struct p2m_domain *p2m = p2m_get_hostp2m(d);
972
0
973
0
        if ( read_atomic(&p2m->ioreq.entry_count) )
974
0
            p2m_change_entry_type_global(d, p2m_ioreq_server, p2m_ram_rw);
975
0
    }
976
0
977
0
    return rc;
978
0
}
979
980
int hvm_set_ioreq_server_state(struct domain *d, ioservid_t id,
981
                               bool enabled)
982
0
{
983
0
    struct list_head *entry;
984
0
    int rc;
985
0
986
0
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
987
0
988
0
    rc = -ENOENT;
989
0
    list_for_each ( entry,
990
0
                    &d->arch.hvm_domain.ioreq_server.list )
991
0
    {
992
0
        struct hvm_ioreq_server *s = list_entry(entry,
993
0
                                                struct hvm_ioreq_server,
994
0
                                                list_entry);
995
0
996
0
        if ( s == d->arch.hvm_domain.default_ioreq_server )
997
0
            continue;
998
0
999
0
        if ( s->id != id )
1000
0
            continue;
1001
0
1002
0
        domain_pause(d);
1003
0
1004
0
        if ( enabled )
1005
0
            hvm_ioreq_server_enable(s, false);
1006
0
        else
1007
0
            hvm_ioreq_server_disable(s, false);
1008
0
1009
0
        domain_unpause(d);
1010
0
1011
0
        rc = 0;
1012
0
        break;
1013
0
    }
1014
0
1015
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
1016
0
    return rc;
1017
0
}
1018
1019
int hvm_all_ioreq_servers_add_vcpu(struct domain *d, struct vcpu *v)
1020
12
{
1021
12
    struct hvm_ioreq_server *s;
1022
12
    int rc;
1023
12
1024
12
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
1025
12
1026
12
    list_for_each_entry ( s,
1027
12
                          &d->arch.hvm_domain.ioreq_server.list,
1028
12
                          list_entry )
1029
0
    {
1030
0
        bool is_default = (s == d->arch.hvm_domain.default_ioreq_server);
1031
0
1032
0
        rc = hvm_ioreq_server_add_vcpu(s, is_default, v);
1033
0
        if ( rc )
1034
0
            goto fail;
1035
0
    }
1036
12
1037
12
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
1038
12
1039
12
    return 0;
1040
12
1041
0
 fail:
1042
0
    list_for_each_entry ( s,
1043
0
                          &d->arch.hvm_domain.ioreq_server.list,
1044
0
                          list_entry )
1045
0
        hvm_ioreq_server_remove_vcpu(s, v);
1046
0
1047
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
1048
0
1049
0
    return rc;
1050
12
}
1051
1052
void hvm_all_ioreq_servers_remove_vcpu(struct domain *d, struct vcpu *v)
1053
0
{
1054
0
    struct hvm_ioreq_server *s;
1055
0
1056
0
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
1057
0
1058
0
    list_for_each_entry ( s,
1059
0
                          &d->arch.hvm_domain.ioreq_server.list,
1060
0
                          list_entry )
1061
0
        hvm_ioreq_server_remove_vcpu(s, v);
1062
0
1063
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
1064
0
}
1065
1066
void hvm_destroy_all_ioreq_servers(struct domain *d)
1067
0
{
1068
0
    struct hvm_ioreq_server *s, *next;
1069
0
1070
0
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
1071
0
1072
0
    /* No need to domain_pause() as the domain is being torn down */
1073
0
1074
0
    list_for_each_entry_safe ( s,
1075
0
                               next,
1076
0
                               &d->arch.hvm_domain.ioreq_server.list,
1077
0
                               list_entry )
1078
0
    {
1079
0
        bool is_default = (s == d->arch.hvm_domain.default_ioreq_server);
1080
0
1081
0
        hvm_ioreq_server_disable(s, is_default);
1082
0
1083
0
        if ( is_default )
1084
0
            d->arch.hvm_domain.default_ioreq_server = NULL;
1085
0
1086
0
        list_del(&s->list_entry);
1087
0
1088
0
        hvm_ioreq_server_deinit(s, is_default);
1089
0
1090
0
        xfree(s);
1091
0
    }
1092
0
1093
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
1094
0
}
1095
1096
static int hvm_replace_event_channel(struct vcpu *v, domid_t remote_domid,
1097
                                     evtchn_port_t *p_port)
1098
0
{
1099
0
    int old_port, new_port;
1100
0
1101
0
    new_port = alloc_unbound_xen_event_channel(v->domain, v->vcpu_id,
1102
0
                                               remote_domid, NULL);
1103
0
    if ( new_port < 0 )
1104
0
        return new_port;
1105
0
1106
0
    /* xchg() ensures that only we call free_xen_event_channel(). */
1107
0
    old_port = xchg(p_port, new_port);
1108
0
    free_xen_event_channel(v->domain, old_port);
1109
0
    return 0;
1110
0
}
1111
1112
int hvm_set_dm_domain(struct domain *d, domid_t domid)
1113
0
{
1114
0
    struct hvm_ioreq_server *s;
1115
0
    int rc = 0;
1116
0
1117
0
    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
1118
0
1119
0
    /*
1120
0
     * Lack of ioreq server is not a failure. HVM_PARAM_DM_DOMAIN will
1121
0
     * still be set and thus, when the server is created, it will have
1122
0
     * the correct domid.
1123
0
     */
1124
0
    s = d->arch.hvm_domain.default_ioreq_server;
1125
0
    if ( !s )
1126
0
        goto done;
1127
0
1128
0
    domain_pause(d);
1129
0
    spin_lock(&s->lock);
1130
0
1131
0
    if ( s->domid != domid )
1132
0
    {
1133
0
        struct hvm_ioreq_vcpu *sv;
1134
0
1135
0
        list_for_each_entry ( sv,
1136
0
                              &s->ioreq_vcpu_list,
1137
0
                              list_entry )
1138
0
        {
1139
0
            struct vcpu *v = sv->vcpu;
1140
0
1141
0
            if ( v->vcpu_id == 0 )
1142
0
            {
1143
0
                rc = hvm_replace_event_channel(v, domid,
1144
0
                                               &s->bufioreq_evtchn);
1145
0
                if ( rc )
1146
0
                    break;
1147
0
1148
0
                d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_EVTCHN] =
1149
0
                    s->bufioreq_evtchn;
1150
0
            }
1151
0
1152
0
            rc = hvm_replace_event_channel(v, domid, &sv->ioreq_evtchn);
1153
0
            if ( rc )
1154
0
                break;
1155
0
1156
0
            hvm_update_ioreq_evtchn(s, sv);
1157
0
        }
1158
0
1159
0
        s->domid = domid;
1160
0
    }
1161
0
1162
0
    spin_unlock(&s->lock);
1163
0
    domain_unpause(d);
1164
0
1165
0
 done:
1166
0
    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
1167
0
    return rc;
1168
0
}
1169
1170
struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
1171
                                                 ioreq_t *p)
1172
20.0k
{
1173
20.0k
    struct hvm_ioreq_server *s;
1174
20.0k
    uint32_t cf8;
1175
20.0k
    uint8_t type;
1176
20.0k
    uint64_t addr;
1177
20.0k
1178
20.0k
    if ( list_empty(&d->arch.hvm_domain.ioreq_server.list) )
1179
20.0k
        return NULL;
1180
20.0k
1181
0
    if ( p->type != IOREQ_TYPE_COPY && p->type != IOREQ_TYPE_PIO )
1182
0
        return d->arch.hvm_domain.default_ioreq_server;
1183
0
1184
0
    cf8 = d->arch.hvm_domain.pci_cf8;
1185
0
1186
0
    if ( p->type == IOREQ_TYPE_PIO &&
1187
0
         (p->addr & ~3) == 0xcfc &&
1188
0
         CF8_ENABLED(cf8) )
1189
0
    {
1190
0
        uint32_t x86_fam;
1191
0
        pci_sbdf_t sbdf;
1192
0
        unsigned int reg;
1193
0
1194
0
        reg = hvm_pci_decode_addr(cf8, p->addr, &sbdf);
1195
0
1196
0
        /* PCI config data cycle */
1197
0
        type = XEN_DMOP_IO_RANGE_PCI;
1198
0
        addr = ((uint64_t)sbdf.sbdf << 32) | reg;
1199
0
        /* AMD extended configuration space access? */
1200
0
        if ( CF8_ADDR_HI(cf8) &&
1201
0
             d->arch.cpuid->x86_vendor == X86_VENDOR_AMD &&
1202
0
             (x86_fam = get_cpu_family(
1203
0
                 d->arch.cpuid->basic.raw_fms, NULL, NULL)) > 0x10 &&
1204
0
             x86_fam <= 0x17 )
1205
0
        {
1206
0
            uint64_t msr_val;
1207
0
1208
0
            if ( !rdmsr_safe(MSR_AMD64_NB_CFG, msr_val) &&
1209
0
                 (msr_val & (1ULL << AMD64_NB_CFG_CF8_EXT_ENABLE_BIT)) )
1210
0
                addr |= CF8_ADDR_HI(cf8);
1211
0
        }
1212
0
    }
1213
0
    else
1214
0
    {
1215
0
        type = (p->type == IOREQ_TYPE_PIO) ?
1216
0
                XEN_DMOP_IO_RANGE_PORT : XEN_DMOP_IO_RANGE_MEMORY;
1217
0
        addr = p->addr;
1218
0
    }
1219
0
1220
0
    list_for_each_entry ( s,
1221
0
                          &d->arch.hvm_domain.ioreq_server.list,
1222
0
                          list_entry )
1223
0
    {
1224
0
        struct rangeset *r;
1225
0
1226
0
        if ( s == d->arch.hvm_domain.default_ioreq_server )
1227
0
            continue;
1228
0
1229
0
        if ( !s->enabled )
1230
0
            continue;
1231
0
1232
0
        r = s->range[type];
1233
0
1234
0
        switch ( type )
1235
0
        {
1236
0
            unsigned long end;
1237
0
1238
0
        case XEN_DMOP_IO_RANGE_PORT:
1239
0
            end = addr + p->size - 1;
1240
0
            if ( rangeset_contains_range(r, addr, end) )
1241
0
                return s;
1242
0
1243
0
            break;
1244
0
        case XEN_DMOP_IO_RANGE_MEMORY:
1245
0
            end = addr + (p->size * p->count) - 1;
1246
0
            if ( rangeset_contains_range(r, addr, end) )
1247
0
                return s;
1248
0
1249
0
            break;
1250
0
        case XEN_DMOP_IO_RANGE_PCI:
1251
0
            if ( rangeset_contains_singleton(r, addr >> 32) )
1252
0
            {
1253
0
                p->type = IOREQ_TYPE_PCI_CONFIG;
1254
0
                p->addr = addr;
1255
0
                return s;
1256
0
            }
1257
0
1258
0
            break;
1259
0
        }
1260
0
    }
1261
0
1262
0
    return d->arch.hvm_domain.default_ioreq_server;
1263
0
}
1264
1265
static int hvm_send_buffered_ioreq(struct hvm_ioreq_server *s, ioreq_t *p)
1266
0
{
1267
0
    struct domain *d = current->domain;
1268
0
    struct hvm_ioreq_page *iorp;
1269
0
    buffered_iopage_t *pg;
1270
0
    buf_ioreq_t bp = { .data = p->data,
1271
0
                       .addr = p->addr,
1272
0
                       .type = p->type,
1273
0
                       .dir = p->dir };
1274
0
    /* Timeoffset sends 64b data, but no address. Use two consecutive slots. */
1275
0
    int qw = 0;
1276
0
1277
0
    /* Ensure buffered_iopage fits in a page */
1278
0
    BUILD_BUG_ON(sizeof(buffered_iopage_t) > PAGE_SIZE);
1279
0
1280
0
    iorp = &s->bufioreq;
1281
0
    pg = iorp->va;
1282
0
1283
0
    if ( !pg )
1284
0
        return X86EMUL_UNHANDLEABLE;
1285
0
1286
0
    /*
1287
0
     * Return 0 for the cases we can't deal with:
1288
0
     *  - 'addr' is only a 20-bit field, so we cannot address beyond 1MB
1289
0
     *  - we cannot buffer accesses to guest memory buffers, as the guest
1290
0
     *    may expect the memory buffer to be synchronously accessed
1291
0
     *  - the count field is usually used with data_is_ptr and since we don't
1292
0
     *    support data_is_ptr we do not waste space for the count field either
1293
0
     */
1294
0
    if ( (p->addr > 0xffffful) || p->data_is_ptr || (p->count != 1) )
1295
0
        return 0;
1296
0
1297
0
    switch ( p->size )
1298
0
    {
1299
0
    case 1:
1300
0
        bp.size = 0;
1301
0
        break;
1302
0
    case 2:
1303
0
        bp.size = 1;
1304
0
        break;
1305
0
    case 4:
1306
0
        bp.size = 2;
1307
0
        break;
1308
0
    case 8:
1309
0
        bp.size = 3;
1310
0
        qw = 1;
1311
0
        break;
1312
0
    default:
1313
0
        gdprintk(XENLOG_WARNING, "unexpected ioreq size: %u\n", p->size);
1314
0
        return X86EMUL_UNHANDLEABLE;
1315
0
    }
1316
0
1317
0
    spin_lock(&s->bufioreq_lock);
1318
0
1319
0
    if ( (pg->ptrs.write_pointer - pg->ptrs.read_pointer) >=
1320
0
         (IOREQ_BUFFER_SLOT_NUM - qw) )
1321
0
    {
1322
0
        /* The queue is full: send the iopacket through the normal path. */
1323
0
        spin_unlock(&s->bufioreq_lock);
1324
0
        return X86EMUL_UNHANDLEABLE;
1325
0
    }
1326
0
1327
0
    pg->buf_ioreq[pg->ptrs.write_pointer % IOREQ_BUFFER_SLOT_NUM] = bp;
1328
0
1329
0
    if ( qw )
1330
0
    {
1331
0
        bp.data = p->data >> 32;
1332
0
        pg->buf_ioreq[(pg->ptrs.write_pointer+1) % IOREQ_BUFFER_SLOT_NUM] = bp;
1333
0
    }
1334
0
1335
0
    /* Make the ioreq_t visible /before/ write_pointer. */
1336
0
    wmb();
1337
0
    pg->ptrs.write_pointer += qw ? 2 : 1;
1338
0
1339
0
    /* Canonicalize read/write pointers to prevent their overflow. */
1340
0
    while ( s->bufioreq_atomic && qw++ < IOREQ_BUFFER_SLOT_NUM &&
1341
0
            pg->ptrs.read_pointer >= IOREQ_BUFFER_SLOT_NUM )
1342
0
    {
1343
0
        union bufioreq_pointers old = pg->ptrs, new;
1344
0
        unsigned int n = old.read_pointer / IOREQ_BUFFER_SLOT_NUM;
1345
0
1346
0
        new.read_pointer = old.read_pointer - n * IOREQ_BUFFER_SLOT_NUM;
1347
0
        new.write_pointer = old.write_pointer - n * IOREQ_BUFFER_SLOT_NUM;
1348
0
        cmpxchg(&pg->ptrs.full, old.full, new.full);
1349
0
    }
1350
0
1351
0
    notify_via_xen_event_channel(d, s->bufioreq_evtchn);
1352
0
    spin_unlock(&s->bufioreq_lock);
1353
0
1354
0
    return X86EMUL_OKAY;
1355
0
}
1356
1357
int hvm_send_ioreq(struct hvm_ioreq_server *s, ioreq_t *proto_p,
1358
                   bool buffered)
1359
0
{
1360
0
    struct vcpu *curr = current;
1361
0
    struct domain *d = curr->domain;
1362
0
    struct hvm_ioreq_vcpu *sv;
1363
0
1364
0
    ASSERT(s);
1365
0
1366
0
    if ( buffered )
1367
0
        return hvm_send_buffered_ioreq(s, proto_p);
1368
0
1369
0
    if ( unlikely(!vcpu_start_shutdown_deferral(curr)) )
1370
0
        return X86EMUL_RETRY;
1371
0
1372
0
    list_for_each_entry ( sv,
1373
0
                          &s->ioreq_vcpu_list,
1374
0
                          list_entry )
1375
0
    {
1376
0
        if ( sv->vcpu == curr )
1377
0
        {
1378
0
            evtchn_port_t port = sv->ioreq_evtchn;
1379
0
            ioreq_t *p = get_ioreq(s, curr);
1380
0
1381
0
            if ( unlikely(p->state != STATE_IOREQ_NONE) )
1382
0
            {
1383
0
                gprintk(XENLOG_ERR, "device model set bad IO state %d\n",
1384
0
                        p->state);
1385
0
                break;
1386
0
            }
1387
0
1388
0
            if ( unlikely(p->vp_eport != port) )
1389
0
            {
1390
0
                gprintk(XENLOG_ERR, "device model set bad event channel %d\n",
1391
0
                        p->vp_eport);
1392
0
                break;
1393
0
            }
1394
0
1395
0
            proto_p->state = STATE_IOREQ_NONE;
1396
0
            proto_p->vp_eport = port;
1397
0
            *p = *proto_p;
1398
0
1399
0
            prepare_wait_on_xen_event_channel(port);
1400
0
1401
0
            /*
1402
0
             * Following happens /after/ blocking and setting up ioreq
1403
0
             * contents. prepare_wait_on_xen_event_channel() is an implicit
1404
0
             * barrier.
1405
0
             */
1406
0
            p->state = STATE_IOREQ_READY;
1407
0
            notify_via_xen_event_channel(d, port);
1408
0
1409
0
            sv->pending = true;
1410
0
            return X86EMUL_RETRY;
1411
0
        }
1412
0
    }
1413
0
1414
0
    return X86EMUL_UNHANDLEABLE;
1415
0
}
1416
1417
unsigned int hvm_broadcast_ioreq(ioreq_t *p, bool buffered)
1418
0
{
1419
0
    struct domain *d = current->domain;
1420
0
    struct hvm_ioreq_server *s;
1421
0
    unsigned int failed = 0;
1422
0
1423
0
    list_for_each_entry ( s,
1424
0
                          &d->arch.hvm_domain.ioreq_server.list,
1425
0
                          list_entry )
1426
0
        if ( hvm_send_ioreq(s, p, buffered) == X86EMUL_UNHANDLEABLE )
1427
0
            failed++;
1428
0
1429
0
    return failed;
1430
0
}
1431
1432
static int hvm_access_cf8(
1433
    int dir, unsigned int port, unsigned int bytes, uint32_t *val)
1434
0
{
1435
0
    struct domain *d = current->domain;
1436
0
1437
0
    if ( dir == IOREQ_WRITE && bytes == 4 )
1438
0
        d->arch.hvm_domain.pci_cf8 = *val;
1439
0
1440
0
    /* We always need to fall through to the catch all emulator */
1441
0
    return X86EMUL_UNHANDLEABLE;
1442
0
}
1443
1444
void hvm_ioreq_init(struct domain *d)
1445
1
{
1446
1
    spin_lock_init(&d->arch.hvm_domain.ioreq_server.lock);
1447
1
    INIT_LIST_HEAD(&d->arch.hvm_domain.ioreq_server.list);
1448
1
1449
1
    register_portio_handler(d, 0xcf8, 4, hvm_access_cf8);
1450
1
}
1451
1452
/*
1453
 * Local variables:
1454
 * mode: C
1455
 * c-file-style: "BSD"
1456
 * c-basic-offset: 4
1457
 * tab-width: 4
1458
 * indent-tabs-mode: nil
1459
 * End:
1460
 */