Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/common/grant_table.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 * common/grant_table.c
3
 *
4
 * Mechanism for granting foreign access to page frames, and receiving
5
 * page-ownership transfers.
6
 *
7
 * Copyright (c) 2005-2006 Christopher Clark
8
 * Copyright (c) 2004 K A Fraser
9
 * Copyright (c) 2005 Andrew Warfield
10
 * Modifications by Geoffrey Lefebvre are (c) Intel Research Cambridge
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; If not, see <http://www.gnu.org/licenses/>.
24
 */
25
26
#include <xen/err.h>
27
#include <xen/iocap.h>
28
#include <xen/lib.h>
29
#include <xen/sched.h>
30
#include <xen/mm.h>
31
#include <xen/event.h>
32
#include <xen/trace.h>
33
#include <xen/grant_table.h>
34
#include <xen/guest_access.h>
35
#include <xen/domain_page.h>
36
#include <xen/iommu.h>
37
#include <xen/paging.h>
38
#include <xen/keyhandler.h>
39
#include <xen/vmap.h>
40
#include <xsm/xsm.h>
41
#include <asm/flushtlb.h>
42
43
/* Per-domain grant information. */
44
struct grant_table {
45
    /*
46
     * Lock protecting updates to grant table state (version, active
47
     * entry list, etc.)
48
     */
49
    percpu_rwlock_t       lock;
50
    /* Lock protecting the maptrack limit */
51
    spinlock_t            maptrack_lock;
52
    /*
53
     * The defined versions are 1 and 2.  Set to 0 if we don't know
54
     * what version to use yet.
55
     */
56
    unsigned int          gt_version;
57
    /* Resource limits of the domain. */
58
    unsigned int          max_grant_frames;
59
    unsigned int          max_maptrack_frames;
60
    /* Table size. Number of frames shared with guest */
61
    unsigned int          nr_grant_frames;
62
    /* Number of grant status frames shared with guest (for version 2) */
63
    unsigned int          nr_status_frames;
64
    /* Number of available maptrack entries. */
65
    unsigned int          maptrack_limit;
66
    /* Shared grant table (see include/public/grant_table.h). */
67
    union {
68
        void **shared_raw;
69
        struct grant_entry_v1 **shared_v1;
70
        union grant_entry_v2 **shared_v2;
71
    };
72
    /* State grant table (see include/public/grant_table.h). */
73
    grant_status_t       **status;
74
    /* Active grant table. */
75
    struct active_grant_entry **active;
76
    /* Mapping tracking table per vcpu. */
77
    struct grant_mapping **maptrack;
78
79
    /* Domain to which this struct grant_table belongs. */
80
    const struct domain *domain;
81
82
    struct grant_table_arch arch;
83
};
84
85
#ifndef DEFAULT_MAX_NR_GRANT_FRAMES /* to allow arch to override */
86
/* Default maximum size of a grant table. [POLICY] */
87
#define DEFAULT_MAX_NR_GRANT_FRAMES   64
88
#endif
89
90
static unsigned int __read_mostly max_grant_frames =
91
                                               DEFAULT_MAX_NR_GRANT_FRAMES;
92
integer_runtime_param("gnttab_max_frames", max_grant_frames);
93
94
#define DEFAULT_MAX_MAPTRACK_FRAMES 1024
95
96
static unsigned int __read_mostly max_maptrack_frames =
97
                                               DEFAULT_MAX_MAPTRACK_FRAMES;
98
integer_runtime_param("gnttab_max_maptrack_frames", max_maptrack_frames);
99
100
/*
101
 * Note that the three values below are effectively part of the ABI, even if
102
 * we don't need to make them a formal part of it: A guest suspended for
103
 * migration in the middle of a continuation would fail to work if resumed on
104
 * a hypervisor using different values.
105
 */
106
6
#define GNTTABOP_CONTINUATION_ARG_SHIFT 12
107
6
#define GNTTABOP_CMD_MASK               ((1<<GNTTABOP_CONTINUATION_ARG_SHIFT)-1)
108
3
#define GNTTABOP_ARG_MASK               (~GNTTABOP_CMD_MASK)
109
110
/*
111
 * The first two members of a grant entry are updated as a combined pair.
112
 * The following union allows that to happen in an endian-neutral fashion.
113
 */
114
union grant_combo {
115
    uint32_t word;
116
    struct {
117
        uint16_t flags;
118
        domid_t  domid;
119
    } shorts;
120
};
121
122
/* Used to share code between unmap_grant_ref and unmap_and_replace. */
123
struct gnttab_unmap_common {
124
    /* Input */
125
    uint64_t host_addr;
126
    uint64_t dev_bus_addr;
127
    uint64_t new_addr;
128
    grant_handle_t handle;
129
130
    /* Return */
131
    int16_t status;
132
133
    /* Shared state beteen *_unmap and *_unmap_complete */
134
    uint16_t done;
135
    unsigned long frame;
136
    struct domain *rd;
137
    grant_ref_t ref;
138
};
139
140
/* Number of unmap operations that are done between each tlb flush */
141
#define GNTTAB_UNMAP_BATCH_SIZE 32
142
143
144
#define PIN_FAIL(_lbl, _rc, _f, _a...)          \
145
0
    do {                                        \
146
0
        gdprintk(XENLOG_WARNING, _f, ## _a );   \
147
0
        rc = (_rc);                             \
148
0
        goto _lbl;                              \
149
0
    } while ( 0 )
150
151
/*
152
 * Tracks a mapping of another domain's grant reference. Each domain has a
153
 * table of these, indexes into which are returned as a 'mapping handle'.
154
 */
155
struct grant_mapping {
156
    grant_ref_t ref;        /* grant ref */
157
    uint16_t flags;         /* 0-4: GNTMAP_* ; 5-15: unused */
158
    domid_t  domid;         /* granting domain */
159
    uint32_t vcpu;          /* vcpu which created the grant mapping */
160
    uint32_t pad;           /* round size to a power of 2 */
161
};
162
163
/* Number of grant table frames. Caller must hold d's grant table lock. */
164
static inline unsigned int nr_grant_frames(const struct grant_table *gt)
165
9
{
166
9
    return gt->nr_grant_frames;
167
9
}
168
169
/* Number of status grant table frames. Caller must hold d's gr. table lock.*/
170
static inline unsigned int nr_status_frames(const struct grant_table *gt)
171
0
{
172
0
    return gt->nr_status_frames;
173
0
}
174
175
0
#define MAPTRACK_PER_PAGE (PAGE_SIZE / sizeof(struct grant_mapping))
176
#define maptrack_entry(t, e) \
177
0
    ((t)->maptrack[(e)/MAPTRACK_PER_PAGE][(e)%MAPTRACK_PER_PAGE])
178
179
static inline unsigned int
180
nr_maptrack_frames(struct grant_table *t)
181
0
{
182
0
    return t->maptrack_limit / MAPTRACK_PER_PAGE;
183
0
}
184
185
48
#define MAPTRACK_TAIL (~0u)
186
187
0
#define SHGNT_PER_PAGE_V1 (PAGE_SIZE / sizeof(grant_entry_v1_t))
188
#define shared_entry_v1(t, e) \
189
0
    ((t)->shared_v1[(e)/SHGNT_PER_PAGE_V1][(e)%SHGNT_PER_PAGE_V1])
190
0
#define SHGNT_PER_PAGE_V2 (PAGE_SIZE / sizeof(grant_entry_v2_t))
191
#define shared_entry_v2(t, e) \
192
0
    ((t)->shared_v2[(e)/SHGNT_PER_PAGE_V2][(e)%SHGNT_PER_PAGE_V2])
193
0
#define STGNT_PER_PAGE (PAGE_SIZE / sizeof(grant_status_t))
194
#define status_entry(t, e) \
195
0
    ((t)->status[(e)/STGNT_PER_PAGE][(e)%STGNT_PER_PAGE])
196
static grant_entry_header_t *
197
shared_entry_header(struct grant_table *t, grant_ref_t ref)
198
0
{
199
0
    ASSERT(t->gt_version != 0);
200
0
    if ( t->gt_version == 1 )
201
0
        return (grant_entry_header_t*)&shared_entry_v1(t, ref);
202
0
    else
203
0
        return &shared_entry_v2(t, ref).hdr;
204
0
}
205
206
/* Active grant entry - used for shadowing GTF_permit_access grants. */
207
struct active_grant_entry {
208
    uint32_t      pin;    /* Reference count information:             */
209
                          /* Count of writable host-CPU mappings.     */
210
0
#define GNTPIN_hstw_shift    0
211
0
#define GNTPIN_hstw_inc      (1U << GNTPIN_hstw_shift)
212
0
#define GNTPIN_hstw_mask     (0xFFU << GNTPIN_hstw_shift)
213
                          /* Count of read-only host-CPU mappings.    */
214
0
#define GNTPIN_hstr_shift    8
215
0
#define GNTPIN_hstr_inc      (1U << GNTPIN_hstr_shift)
216
#define GNTPIN_hstr_mask     (0xFFU << GNTPIN_hstr_shift)
217
                          /* Count of writable device-bus mappings.   */
218
0
#define GNTPIN_devw_shift    16
219
0
#define GNTPIN_devw_inc      (1U << GNTPIN_devw_shift)
220
0
#define GNTPIN_devw_mask     (0xFFU << GNTPIN_devw_shift)
221
                          /* Count of read-only device-bus mappings.  */
222
0
#define GNTPIN_devr_shift    24
223
0
#define GNTPIN_devr_inc      (1U << GNTPIN_devr_shift)
224
#define GNTPIN_devr_mask     (0xFFU << GNTPIN_devr_shift)
225
226
    domid_t       domid;  /* Domain being granted access.             */
227
    unsigned int  start:15; /* For sub-page grants, the start offset
228
                               in the page.                           */
229
    bool          is_sub_page:1; /* True if this is a sub-page grant. */
230
    unsigned int  length:16; /* For sub-page grants, the length of the
231
                                grant.                                */
232
    grant_ref_t   trans_gref;
233
    struct domain *trans_domain;
234
    unsigned long frame;  /* Frame being granted.                     */
235
#ifndef NDEBUG
236
    gfn_t         gfn;    /* Guest's idea of the frame being granted. */
237
#endif
238
    spinlock_t    lock;      /* lock to protect access of this entry.
239
                                see docs/misc/grant-tables.txt for
240
                                locking protocol                      */
241
};
242
243
602
#define ACGNT_PER_PAGE (PAGE_SIZE / sizeof(struct active_grant_entry))
244
#define _active_entry(t, e) \
245
0
    ((t)->active[(e)/ACGNT_PER_PAGE][(e)%ACGNT_PER_PAGE])
246
247
static inline void act_set_gfn(struct active_grant_entry *act, gfn_t gfn)
248
0
{
249
0
#ifndef NDEBUG
250
0
    act->gfn = gfn;
251
0
#endif
252
0
}
253
254
static DEFINE_PERCPU_RWLOCK_GLOBAL(grant_rwlock);
255
256
static inline void grant_read_lock(struct grant_table *gt)
257
3
{
258
3
    percpu_read_lock(grant_rwlock, &gt->lock);
259
3
}
260
261
static inline void grant_read_unlock(struct grant_table *gt)
262
3
{
263
3
    percpu_read_unlock(grant_rwlock, &gt->lock);
264
3
}
265
266
static inline void grant_write_lock(struct grant_table *gt)
267
2
{
268
2
    percpu_write_lock(grant_rwlock, &gt->lock);
269
2
}
270
271
static inline void grant_write_unlock(struct grant_table *gt)
272
2
{
273
2
    percpu_write_unlock(grant_rwlock, &gt->lock);
274
2
}
275
276
static inline void gnttab_flush_tlb(const struct domain *d)
277
0
{
278
0
    if ( !paging_mode_external(d) )
279
0
        flush_tlb_mask(d->domain_dirty_cpumask);
280
0
}
281
282
static inline unsigned int
283
num_act_frames_from_sha_frames(const unsigned int num)
284
10
{
285
10
    /*
286
10
     * How many frames are needed for the active grant table,
287
10
     * given the size of the shared grant table?
288
10
     */
289
10
    unsigned int sha_per_page = PAGE_SIZE / sizeof(grant_entry_v1_t);
290
10
291
10
    return DIV_ROUND_UP(num * sha_per_page, ACGNT_PER_PAGE);
292
10
}
293
294
#define max_nr_active_grant_frames(gt) \
295
    num_act_frames_from_sha_frames((gt)->max_grant_frames)
296
297
static inline unsigned int
298
nr_active_grant_frames(struct grant_table *gt)
299
1
{
300
1
    return num_act_frames_from_sha_frames(nr_grant_frames(gt));
301
1
}
302
303
static inline struct active_grant_entry *
304
active_entry_acquire(struct grant_table *t, grant_ref_t e)
305
0
{
306
0
    struct active_grant_entry *act;
307
0
308
0
    /*
309
0
     * The grant table for the active entry should be locked but the
310
0
     * percpu rwlock cannot be checked for read lock without race conditions
311
0
     * or high overhead so we cannot use an ASSERT
312
0
     *
313
0
     *   ASSERT(rw_is_locked(&t->lock));
314
0
     */
315
0
316
0
    act = &_active_entry(t, e);
317
0
    spin_lock(&act->lock);
318
0
319
0
    return act;
320
0
}
321
322
static inline void active_entry_release(struct active_grant_entry *act)
323
0
{
324
0
    spin_unlock(&act->lock);
325
0
}
326
327
#define GRANT_STATUS_PER_PAGE (PAGE_SIZE / sizeof(grant_status_t))
328
#define GRANT_PER_PAGE (PAGE_SIZE / sizeof(grant_entry_v2_t))
329
/* Number of grant table status entries. Caller must hold d's gr. table lock.*/
330
static inline unsigned int grant_to_status_frames(unsigned int grant_frames)
331
1
{
332
1
    return DIV_ROUND_UP(grant_frames * GRANT_PER_PAGE, GRANT_STATUS_PER_PAGE);
333
1
}
334
335
/* Check if the page has been paged out, or needs unsharing.
336
   If rc == GNTST_okay, *page contains the page struct with a ref taken.
337
   Caller must do put_page(*page).
338
   If any error, *page = NULL, *frame = INVALID_MFN, no ref taken. */
339
static int get_paged_frame(unsigned long gfn, unsigned long *frame,
340
                           struct page_info **page, bool readonly,
341
                           struct domain *rd)
342
0
{
343
0
    int rc = GNTST_okay;
344
0
    p2m_type_t p2mt;
345
0
346
0
    *frame = mfn_x(INVALID_MFN);
347
0
    *page = get_page_from_gfn(rd, gfn, &p2mt,
348
0
                              readonly ? P2M_ALLOC : P2M_UNSHARE);
349
0
    if ( !*page )
350
0
    {
351
0
#ifdef P2M_SHARED_TYPES
352
0
        if ( p2m_is_shared(p2mt) )
353
0
            return GNTST_eagain;
354
0
#endif
355
0
#ifdef P2M_PAGES_TYPES
356
        if ( p2m_is_paging(p2mt) )
357
        {
358
            p2m_mem_paging_populate(rd, gfn);
359
            return GNTST_eagain;
360
        }
361
#endif
362
0
        return GNTST_bad_page;
363
0
    }
364
0
365
0
    if ( p2m_is_foreign(p2mt) )
366
0
    {
367
0
        put_page(*page);
368
0
        *page = NULL;
369
0
370
0
        return GNTST_bad_page;
371
0
    }
372
0
373
0
    *frame = page_to_mfn(*page);
374
0
375
0
    return rc;
376
0
}
377
378
static inline void
379
double_gt_lock(struct grant_table *lgt, struct grant_table *rgt)
380
0
{
381
0
    /*
382
0
     * See mapkind() for why the write lock is also required for the
383
0
     * remote domain.
384
0
     */
385
0
    if ( lgt < rgt )
386
0
    {
387
0
        grant_write_lock(lgt);
388
0
        grant_write_lock(rgt);
389
0
    }
390
0
    else
391
0
    {
392
0
        if ( lgt != rgt )
393
0
            grant_write_lock(rgt);
394
0
        grant_write_lock(lgt);
395
0
    }
396
0
}
397
398
static inline void
399
double_gt_unlock(struct grant_table *lgt, struct grant_table *rgt)
400
0
{
401
0
    grant_write_unlock(lgt);
402
0
    if ( lgt != rgt )
403
0
        grant_write_unlock(rgt);
404
0
}
405
406
0
#define INVALID_MAPTRACK_HANDLE UINT_MAX
407
408
static inline grant_handle_t
409
_get_maptrack_handle(struct grant_table *t, struct vcpu *v)
410
0
{
411
0
    unsigned int head, next, prev_head;
412
0
413
0
    spin_lock(&v->maptrack_freelist_lock);
414
0
415
0
    do {
416
0
        /* No maptrack pages allocated for this VCPU yet? */
417
0
        head = read_atomic(&v->maptrack_head);
418
0
        if ( unlikely(head == MAPTRACK_TAIL) )
419
0
        {
420
0
            spin_unlock(&v->maptrack_freelist_lock);
421
0
            return INVALID_MAPTRACK_HANDLE;
422
0
        }
423
0
424
0
        /*
425
0
         * Always keep one entry in the free list to make it easier to
426
0
         * add free entries to the tail.
427
0
         */
428
0
        next = read_atomic(&maptrack_entry(t, head).ref);
429
0
        if ( unlikely(next == MAPTRACK_TAIL) )
430
0
        {
431
0
            spin_unlock(&v->maptrack_freelist_lock);
432
0
            return INVALID_MAPTRACK_HANDLE;
433
0
        }
434
0
435
0
        prev_head = head;
436
0
        head = cmpxchg(&v->maptrack_head, prev_head, next);
437
0
    } while ( head != prev_head );
438
0
439
0
    spin_unlock(&v->maptrack_freelist_lock);
440
0
441
0
    return head;
442
0
}
443
444
/*
445
 * Try to "steal" a free maptrack entry from another VCPU.
446
 *
447
 * A stolen entry is transferred to the thief, so the number of
448
 * entries for each VCPU should tend to the usage pattern.
449
 *
450
 * To avoid having to atomically count the number of free entries on
451
 * each VCPU and to avoid two VCPU repeatedly stealing entries from
452
 * each other, the initial victim VCPU is selected randomly.
453
 */
454
static grant_handle_t steal_maptrack_handle(struct grant_table *t,
455
                                            const struct vcpu *curr)
456
0
{
457
0
    const struct domain *currd = curr->domain;
458
0
    unsigned int first, i;
459
0
460
0
    /* Find an initial victim. */
461
0
    first = i = get_random() % currd->max_vcpus;
462
0
463
0
    do {
464
0
        if ( currd->vcpu[i] )
465
0
        {
466
0
            grant_handle_t handle;
467
0
468
0
            handle = _get_maptrack_handle(t, currd->vcpu[i]);
469
0
            if ( handle != INVALID_MAPTRACK_HANDLE )
470
0
            {
471
0
                maptrack_entry(t, handle).vcpu = curr->vcpu_id;
472
0
                return handle;
473
0
            }
474
0
        }
475
0
476
0
        i++;
477
0
        if ( i == currd->max_vcpus )
478
0
            i = 0;
479
0
    } while ( i != first );
480
0
481
0
    /* No free handles on any VCPU. */
482
0
    return INVALID_MAPTRACK_HANDLE;
483
0
}
484
485
static inline void
486
put_maptrack_handle(
487
    struct grant_table *t, grant_handle_t handle)
488
0
{
489
0
    struct domain *currd = current->domain;
490
0
    struct vcpu *v;
491
0
    unsigned int prev_tail, cur_tail;
492
0
493
0
    /* 1. Set entry to be a tail. */
494
0
    maptrack_entry(t, handle).ref = MAPTRACK_TAIL;
495
0
496
0
    /* 2. Add entry to the tail of the list on the original VCPU. */
497
0
    v = currd->vcpu[maptrack_entry(t, handle).vcpu];
498
0
499
0
    spin_lock(&v->maptrack_freelist_lock);
500
0
501
0
    cur_tail = read_atomic(&v->maptrack_tail);
502
0
    do {
503
0
        prev_tail = cur_tail;
504
0
        cur_tail = cmpxchg(&v->maptrack_tail, prev_tail, handle);
505
0
    } while ( cur_tail != prev_tail );
506
0
507
0
    /* 3. Update the old tail entry to point to the new entry. */
508
0
    write_atomic(&maptrack_entry(t, prev_tail).ref, handle);
509
0
510
0
    spin_unlock(&v->maptrack_freelist_lock);
511
0
}
512
513
static inline grant_handle_t
514
get_maptrack_handle(
515
    struct grant_table *lgt)
516
0
{
517
0
    struct vcpu          *curr = current;
518
0
    unsigned int          i, head;
519
0
    grant_handle_t        handle;
520
0
    struct grant_mapping *new_mt = NULL;
521
0
522
0
    handle = _get_maptrack_handle(lgt, curr);
523
0
    if ( likely(handle != INVALID_MAPTRACK_HANDLE) )
524
0
        return handle;
525
0
526
0
    spin_lock(&lgt->maptrack_lock);
527
0
528
0
    /*
529
0
     * If we've run out of handles and still have frame headroom, try
530
0
     * allocating a new maptrack frame.  If there is no headroom, or we're
531
0
     * out of memory, try stealing an entry from another VCPU (in case the
532
0
     * guest isn't mapping across its VCPUs evenly).
533
0
     */
534
0
    if ( nr_maptrack_frames(lgt) < lgt->max_maptrack_frames )
535
0
        new_mt = alloc_xenheap_page();
536
0
537
0
    if ( !new_mt )
538
0
    {
539
0
        spin_unlock(&lgt->maptrack_lock);
540
0
541
0
        /*
542
0
         * Uninitialized free list? Steal an extra entry for the tail
543
0
         * sentinel.
544
0
         */
545
0
        if ( curr->maptrack_tail == MAPTRACK_TAIL )
546
0
        {
547
0
            handle = steal_maptrack_handle(lgt, curr);
548
0
            if ( handle == INVALID_MAPTRACK_HANDLE )
549
0
                return handle;
550
0
            spin_lock(&curr->maptrack_freelist_lock);
551
0
            maptrack_entry(lgt, handle).ref = MAPTRACK_TAIL;
552
0
            curr->maptrack_tail = handle;
553
0
            if ( curr->maptrack_head == MAPTRACK_TAIL )
554
0
                write_atomic(&curr->maptrack_head, handle);
555
0
            spin_unlock(&curr->maptrack_freelist_lock);
556
0
        }
557
0
        return steal_maptrack_handle(lgt, curr);
558
0
    }
559
0
560
0
    clear_page(new_mt);
561
0
562
0
    /*
563
0
     * Use the first new entry and add the remaining entries to the
564
0
     * head of the free list.
565
0
     */
566
0
    handle = lgt->maptrack_limit;
567
0
568
0
    for ( i = 0; i < MAPTRACK_PER_PAGE; i++ )
569
0
    {
570
0
        BUILD_BUG_ON(sizeof(new_mt->ref) < sizeof(handle));
571
0
        new_mt[i].ref = handle + i + 1;
572
0
        new_mt[i].vcpu = curr->vcpu_id;
573
0
    }
574
0
575
0
    /* Set tail directly if this is the first page for this VCPU. */
576
0
    if ( curr->maptrack_tail == MAPTRACK_TAIL )
577
0
        curr->maptrack_tail = handle + MAPTRACK_PER_PAGE - 1;
578
0
579
0
    lgt->maptrack[nr_maptrack_frames(lgt)] = new_mt;
580
0
    smp_wmb();
581
0
    lgt->maptrack_limit += MAPTRACK_PER_PAGE;
582
0
583
0
    spin_unlock(&lgt->maptrack_lock);
584
0
    spin_lock(&curr->maptrack_freelist_lock);
585
0
586
0
    do {
587
0
        new_mt[i - 1].ref = read_atomic(&curr->maptrack_head);
588
0
        head = cmpxchg(&curr->maptrack_head, new_mt[i - 1].ref, handle + 1);
589
0
    } while ( head != new_mt[i - 1].ref );
590
0
591
0
    spin_unlock(&curr->maptrack_freelist_lock);
592
0
593
0
    return handle;
594
0
}
595
596
/* Number of grant table entries. Caller must hold d's grant table lock. */
597
static unsigned int nr_grant_entries(struct grant_table *gt)
598
0
{
599
0
    switch ( gt->gt_version )
600
0
    {
601
0
#define f2e(nr, ver) (((nr) << PAGE_SHIFT) / sizeof(grant_entry_v##ver##_t))
602
0
    case 1:
603
0
        BUILD_BUG_ON(f2e(INITIAL_NR_GRANT_FRAMES, 1) <
604
0
                     GNTTAB_NR_RESERVED_ENTRIES);
605
0
        return f2e(nr_grant_frames(gt), 1);
606
0
    case 2:
607
0
        BUILD_BUG_ON(f2e(INITIAL_NR_GRANT_FRAMES, 2) <
608
0
                     GNTTAB_NR_RESERVED_ENTRIES);
609
0
        return f2e(nr_grant_frames(gt), 2);
610
0
#undef f2e
611
0
    }
612
0
613
0
    return 0;
614
0
}
615
616
static int _set_status_v1(domid_t  domid,
617
                          int readonly,
618
                          int mapflag,
619
                          grant_entry_header_t *shah,
620
                          struct active_grant_entry *act)
621
0
{
622
0
    int rc = GNTST_okay;
623
0
    union grant_combo scombo, prev_scombo, new_scombo;
624
0
    uint16_t mask = GTF_type_mask;
625
0
626
0
    /*
627
0
     * We bound the number of times we retry CMPXCHG on memory locations that
628
0
     * we share with a guest OS. The reason is that the guest can modify that
629
0
     * location at a higher rate than we can read-modify-CMPXCHG, so the guest
630
0
     * could cause us to livelock. There are a few cases where it is valid for
631
0
     * the guest to race our updates (e.g., to change the GTF_readonly flag),
632
0
     * so we allow a few retries before failing.
633
0
     */
634
0
    int retries = 0;
635
0
636
0
    /* if this is a grant mapping operation we should ensure GTF_sub_page
637
0
       is not set */
638
0
    if ( mapflag )
639
0
        mask |= GTF_sub_page;
640
0
641
0
    scombo.word = *(u32 *)shah;
642
0
643
0
    /*
644
0
     * This loop attempts to set the access (reading/writing) flags
645
0
     * in the grant table entry.  It tries a cmpxchg on the field
646
0
     * up to five times, and then fails under the assumption that
647
0
     * the guest is misbehaving.
648
0
     */
649
0
    for ( ; ; )
650
0
    {
651
0
        /* If not already pinned, check the grant domid and type. */
652
0
        if ( !act->pin &&
653
0
             (((scombo.shorts.flags & mask) !=
654
0
               GTF_permit_access) ||
655
0
              (scombo.shorts.domid != domid)) )
656
0
            PIN_FAIL(done, GNTST_general_error,
657
0
                     "Bad flags (%x) or dom (%d); expected d%d\n",
658
0
                     scombo.shorts.flags, scombo.shorts.domid,
659
0
                     domid);
660
0
661
0
        new_scombo = scombo;
662
0
        new_scombo.shorts.flags |= GTF_reading;
663
0
664
0
        if ( !readonly )
665
0
        {
666
0
            new_scombo.shorts.flags |= GTF_writing;
667
0
            if ( unlikely(scombo.shorts.flags & GTF_readonly) )
668
0
                PIN_FAIL(done, GNTST_general_error,
669
0
                         "Attempt to write-pin a r/o grant entry\n");
670
0
        }
671
0
672
0
        prev_scombo.word = cmpxchg((u32 *)shah,
673
0
                                   scombo.word, new_scombo.word);
674
0
        if ( likely(prev_scombo.word == scombo.word) )
675
0
            break;
676
0
677
0
        if ( retries++ == 4 )
678
0
            PIN_FAIL(done, GNTST_general_error,
679
0
                     "Shared grant entry is unstable\n");
680
0
681
0
        scombo = prev_scombo;
682
0
    }
683
0
684
0
done:
685
0
    return rc;
686
0
}
687
688
static int _set_status_v2(domid_t  domid,
689
                          int readonly,
690
                          int mapflag,
691
                          grant_entry_header_t *shah,
692
                          struct active_grant_entry *act,
693
                          grant_status_t *status)
694
0
{
695
0
    int      rc    = GNTST_okay;
696
0
    union grant_combo scombo;
697
0
    uint16_t flags = shah->flags;
698
0
    domid_t  id    = shah->domid;
699
0
    uint16_t mask  = GTF_type_mask;
700
0
701
0
    /* we read flags and domid in a single memory access.
702
0
       this avoids the need for another memory barrier to
703
0
       ensure access to these fields are not reordered */
704
0
    scombo.word = *(u32 *)shah;
705
0
    barrier(); /* but we still need to stop the compiler from turning
706
0
                  it back into two reads */
707
0
    flags = scombo.shorts.flags;
708
0
    id = scombo.shorts.domid;
709
0
710
0
    /* if this is a grant mapping operation we should ensure GTF_sub_page
711
0
       is not set */
712
0
    if ( mapflag )
713
0
        mask |= GTF_sub_page;
714
0
715
0
    /* If not already pinned, check the grant domid and type. */
716
0
    if ( !act->pin &&
717
0
         ( (((flags & mask) != GTF_permit_access) &&
718
0
            ((flags & mask) != GTF_transitive)) ||
719
0
          (id != domid)) )
720
0
        PIN_FAIL(done, GNTST_general_error,
721
0
                 "Bad flags (%x) or dom (%d); expected d%d, flags %x\n",
722
0
                 flags, id, domid, mask);
723
0
724
0
    if ( readonly )
725
0
    {
726
0
        *status |= GTF_reading;
727
0
    }
728
0
    else
729
0
    {
730
0
        if ( unlikely(flags & GTF_readonly) )
731
0
            PIN_FAIL(done, GNTST_general_error,
732
0
                     "Attempt to write-pin a r/o grant entry\n");
733
0
        *status |= GTF_reading | GTF_writing;
734
0
    }
735
0
736
0
    /* Make sure guest sees status update before checking if flags are
737
0
       still valid */
738
0
    smp_mb();
739
0
740
0
    scombo.word = *(u32 *)shah;
741
0
    barrier();
742
0
    flags = scombo.shorts.flags;
743
0
    id = scombo.shorts.domid;
744
0
745
0
    if ( !act->pin )
746
0
    {
747
0
        if ( (((flags & mask) != GTF_permit_access) &&
748
0
              ((flags & mask) != GTF_transitive)) ||
749
0
             (id != domid) ||
750
0
             (!readonly && (flags & GTF_readonly)) )
751
0
        {
752
0
            gnttab_clear_flag(_GTF_writing, status);
753
0
            gnttab_clear_flag(_GTF_reading, status);
754
0
            PIN_FAIL(done, GNTST_general_error,
755
0
                     "Unstable flags (%x) or dom (%d); expected d%d (r/w: %d)\n",
756
0
                     flags, id, domid, !readonly);
757
0
        }
758
0
    }
759
0
    else
760
0
    {
761
0
        if ( unlikely(flags & GTF_readonly) )
762
0
        {
763
0
            gnttab_clear_flag(_GTF_writing, status);
764
0
            PIN_FAIL(done, GNTST_general_error,
765
0
                     "Unstable grant readonly flag\n");
766
0
        }
767
0
    }
768
0
769
0
done:
770
0
    return rc;
771
0
}
772
773
774
static int _set_status(unsigned gt_version,
775
                       domid_t  domid,
776
                       int readonly,
777
                       int mapflag,
778
                       grant_entry_header_t *shah,
779
                       struct active_grant_entry *act,
780
                       grant_status_t *status)
781
0
{
782
0
783
0
    if ( gt_version == 1 )
784
0
        return _set_status_v1(domid, readonly, mapflag, shah, act);
785
0
    else
786
0
        return _set_status_v2(domid, readonly, mapflag, shah, act, status);
787
0
}
788
789
static int grant_map_exists(const struct domain *ld,
790
                            struct grant_table *rgt,
791
                            unsigned long mfn,
792
                            grant_ref_t *cur_ref)
793
0
{
794
0
    grant_ref_t ref, max_iter;
795
0
796
0
    /*
797
0
     * The remote grant table should be locked but the percpu rwlock
798
0
     * cannot be checked for read lock without race conditions or high
799
0
     * overhead so we cannot use an ASSERT
800
0
     *
801
0
     *   ASSERT(rw_is_locked(&rgt->lock));
802
0
     */
803
0
804
0
    max_iter = min(*cur_ref + (1 << GNTTABOP_CONTINUATION_ARG_SHIFT),
805
0
                   nr_grant_entries(rgt));
806
0
    for ( ref = *cur_ref; ref < max_iter; ref++ )
807
0
    {
808
0
        struct active_grant_entry *act;
809
0
        bool_t exists;
810
0
811
0
        act = active_entry_acquire(rgt, ref);
812
0
813
0
        exists = act->pin
814
0
            && act->domid == ld->domain_id
815
0
            && act->frame == mfn;
816
0
817
0
        active_entry_release(act);
818
0
819
0
        if ( exists )
820
0
            return 0;
821
0
    }
822
0
823
0
    if ( ref < nr_grant_entries(rgt) )
824
0
    {
825
0
        *cur_ref = ref;
826
0
        return 1;
827
0
    }
828
0
829
0
    return -EINVAL;
830
0
}
831
832
0
#define MAPKIND_READ 1
833
0
#define MAPKIND_WRITE 2
834
static unsigned int mapkind(
835
    struct grant_table *lgt, const struct domain *rd, unsigned long mfn)
836
0
{
837
0
    struct grant_mapping *map;
838
0
    grant_handle_t handle, limit = lgt->maptrack_limit;
839
0
    unsigned int kind = 0;
840
0
841
0
    /*
842
0
     * Must have the local domain's grant table write lock when
843
0
     * iterating over its maptrack entries.
844
0
     */
845
0
    ASSERT(percpu_rw_is_write_locked(&lgt->lock));
846
0
    /*
847
0
     * Must have the remote domain's grant table write lock while
848
0
     * counting its active entries.
849
0
     */
850
0
    ASSERT(percpu_rw_is_write_locked(&rd->grant_table->lock));
851
0
852
0
    smp_rmb();
853
0
854
0
    for ( handle = 0; !(kind & MAPKIND_WRITE) && handle < limit; handle++ )
855
0
    {
856
0
        map = &maptrack_entry(lgt, handle);
857
0
        if ( !(map->flags & (GNTMAP_device_map|GNTMAP_host_map)) ||
858
0
             map->domid != rd->domain_id )
859
0
            continue;
860
0
        if ( _active_entry(rd->grant_table, map->ref).frame == mfn )
861
0
            kind |= map->flags & GNTMAP_readonly ?
862
0
                    MAPKIND_READ : MAPKIND_WRITE;
863
0
    }
864
0
865
0
    return kind;
866
0
}
867
868
/*
869
 * Returns 0 if TLB flush / invalidate required by caller.
870
 * va will indicate the address to be invalidated.
871
 *
872
 * addr is _either_ a host virtual address, or the address of the pte to
873
 * update, as indicated by the GNTMAP_contains_pte flag.
874
 */
875
static void
876
map_grant_ref(
877
    struct gnttab_map_grant_ref *op)
878
0
{
879
0
    struct domain *ld, *rd, *owner = NULL;
880
0
    struct grant_table *lgt, *rgt;
881
0
    struct vcpu   *led;
882
0
    grant_handle_t handle;
883
0
    unsigned long  frame = 0;
884
0
    struct page_info *pg = NULL;
885
0
    int            rc = GNTST_okay;
886
0
    u32            old_pin;
887
0
    u32            act_pin;
888
0
    unsigned int   cache_flags, refcnt = 0, typecnt = 0;
889
0
    bool           host_map_created = false;
890
0
    struct active_grant_entry *act = NULL;
891
0
    struct grant_mapping *mt;
892
0
    grant_entry_header_t *shah;
893
0
    uint16_t *status;
894
0
    bool_t need_iommu;
895
0
896
0
    led = current;
897
0
    ld = led->domain;
898
0
899
0
    if ( unlikely((op->flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0) )
900
0
    {
901
0
        gdprintk(XENLOG_INFO, "Bad flags in grant map op: %x\n", op->flags);
902
0
        op->status = GNTST_bad_gntref;
903
0
        return;
904
0
    }
905
0
906
0
    if ( unlikely(paging_mode_external(ld) &&
907
0
                  (op->flags & (GNTMAP_device_map|GNTMAP_application_map|
908
0
                            GNTMAP_contains_pte))) )
909
0
    {
910
0
        gdprintk(XENLOG_INFO, "No device mapping in HVM domain\n");
911
0
        op->status = GNTST_general_error;
912
0
        return;
913
0
    }
914
0
915
0
    if ( unlikely((rd = rcu_lock_domain_by_id(op->dom)) == NULL) )
916
0
    {
917
0
        gdprintk(XENLOG_INFO, "Could not find domain %d\n", op->dom);
918
0
        op->status = GNTST_bad_domain;
919
0
        return;
920
0
    }
921
0
922
0
    rc = xsm_grant_mapref(XSM_HOOK, ld, rd, op->flags);
923
0
    if ( rc )
924
0
    {
925
0
        rcu_unlock_domain(rd);
926
0
        op->status = GNTST_permission_denied;
927
0
        return;
928
0
    }
929
0
930
0
    lgt = ld->grant_table;
931
0
    handle = get_maptrack_handle(lgt);
932
0
    if ( unlikely(handle == INVALID_MAPTRACK_HANDLE) )
933
0
    {
934
0
        rcu_unlock_domain(rd);
935
0
        gdprintk(XENLOG_INFO, "Failed to obtain maptrack handle\n");
936
0
        op->status = GNTST_no_device_space;
937
0
        return;
938
0
    }
939
0
940
0
    rgt = rd->grant_table;
941
0
    grant_read_lock(rgt);
942
0
943
0
    /* Bounds check on the grant ref */
944
0
    if ( unlikely(op->ref >= nr_grant_entries(rgt)))
945
0
        PIN_FAIL(unlock_out, GNTST_bad_gntref, "Bad ref %#x for d%d\n",
946
0
                 op->ref, rgt->domain->domain_id);
947
0
948
0
    act = active_entry_acquire(rgt, op->ref);
949
0
    shah = shared_entry_header(rgt, op->ref);
950
0
    status = rgt->gt_version == 1 ? &shah->flags : &status_entry(rgt, op->ref);
951
0
952
0
    /* If already pinned, check the active domid and avoid refcnt overflow. */
953
0
    if ( act->pin &&
954
0
         ((act->domid != ld->domain_id) ||
955
0
          (act->pin & 0x80808080U) != 0 ||
956
0
          (act->is_sub_page)) )
957
0
        PIN_FAIL(act_release_out, GNTST_general_error,
958
0
                 "Bad domain (%d != %d), or risk of counter overflow %08x, or subpage %d\n",
959
0
                 act->domid, ld->domain_id, act->pin, act->is_sub_page);
960
0
961
0
    if ( !act->pin ||
962
0
         (!(op->flags & GNTMAP_readonly) &&
963
0
          !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask))) )
964
0
    {
965
0
        if ( (rc = _set_status(rgt->gt_version, ld->domain_id,
966
0
                               op->flags & GNTMAP_readonly,
967
0
                               1, shah, act, status) ) != GNTST_okay )
968
0
            goto act_release_out;
969
0
970
0
        if ( !act->pin )
971
0
        {
972
0
            unsigned long gfn = rgt->gt_version == 1 ?
973
0
                                shared_entry_v1(rgt, op->ref).frame :
974
0
                                shared_entry_v2(rgt, op->ref).full_page.frame;
975
0
976
0
            rc = get_paged_frame(gfn, &frame, &pg,
977
0
                                 op->flags & GNTMAP_readonly, rd);
978
0
            if ( rc != GNTST_okay )
979
0
                goto unlock_out_clear;
980
0
            act_set_gfn(act, _gfn(gfn));
981
0
            act->domid = ld->domain_id;
982
0
            act->frame = frame;
983
0
            act->start = 0;
984
0
            act->length = PAGE_SIZE;
985
0
            act->is_sub_page = false;
986
0
            act->trans_domain = rd;
987
0
            act->trans_gref = op->ref;
988
0
        }
989
0
    }
990
0
991
0
    old_pin = act->pin;
992
0
    if ( op->flags & GNTMAP_device_map )
993
0
        act->pin += (op->flags & GNTMAP_readonly) ?
994
0
            GNTPIN_devr_inc : GNTPIN_devw_inc;
995
0
    if ( op->flags & GNTMAP_host_map )
996
0
        act->pin += (op->flags & GNTMAP_readonly) ?
997
0
            GNTPIN_hstr_inc : GNTPIN_hstw_inc;
998
0
999
0
    frame = act->frame;
1000
0
    act_pin = act->pin;
1001
0
1002
0
    cache_flags = (shah->flags & (GTF_PAT | GTF_PWT | GTF_PCD) );
1003
0
1004
0
    active_entry_release(act);
1005
0
    grant_read_unlock(rgt);
1006
0
1007
0
    /* pg may be set, with a refcount included, from get_paged_frame(). */
1008
0
    if ( !pg )
1009
0
    {
1010
0
        pg = mfn_valid(_mfn(frame)) ? mfn_to_page(frame) : NULL;
1011
0
        if ( pg )
1012
0
            owner = page_get_owner_and_reference(pg);
1013
0
    }
1014
0
    else
1015
0
        owner = page_get_owner(pg);
1016
0
1017
0
    if ( owner )
1018
0
        refcnt++;
1019
0
1020
0
    if ( !pg || (owner == dom_io) )
1021
0
    {
1022
0
        /* Only needed the reference to confirm dom_io ownership. */
1023
0
        if ( pg )
1024
0
        {
1025
0
            put_page(pg);
1026
0
            refcnt--;
1027
0
        }
1028
0
1029
0
        if ( paging_mode_external(ld) )
1030
0
        {
1031
0
            gdprintk(XENLOG_WARNING, "HVM guests can't grant map iomem\n");
1032
0
            rc = GNTST_general_error;
1033
0
            goto undo_out;
1034
0
        }
1035
0
1036
0
        if ( !iomem_access_permitted(rd, frame, frame) )
1037
0
        {
1038
0
            gdprintk(XENLOG_WARNING,
1039
0
                     "Iomem mapping not permitted %lx (domain %d)\n",
1040
0
                     frame, rd->domain_id);
1041
0
            rc = GNTST_general_error;
1042
0
            goto undo_out;
1043
0
        }
1044
0
1045
0
        if ( op->flags & GNTMAP_host_map )
1046
0
        {
1047
0
            rc = create_grant_host_mapping(op->host_addr, frame, op->flags,
1048
0
                                           cache_flags);
1049
0
            if ( rc != GNTST_okay )
1050
0
                goto undo_out;
1051
0
1052
0
            host_map_created = true;
1053
0
        }
1054
0
    }
1055
0
    else if ( owner == rd || owner == dom_cow )
1056
0
    {
1057
0
        if ( (op->flags & GNTMAP_device_map) && !(op->flags & GNTMAP_readonly) )
1058
0
        {
1059
0
            if ( (owner == dom_cow) ||
1060
0
                 !get_page_type(pg, PGT_writable_page) )
1061
0
                goto could_not_pin;
1062
0
            typecnt++;
1063
0
        }
1064
0
1065
0
        if ( op->flags & GNTMAP_host_map )
1066
0
        {
1067
0
            /*
1068
0
             * Only need to grab another reference if device_map claimed
1069
0
             * the other one.
1070
0
             */
1071
0
            if ( op->flags & GNTMAP_device_map )
1072
0
            {
1073
0
                if ( !get_page(pg, rd) )
1074
0
                    goto could_not_pin;
1075
0
                refcnt++;
1076
0
            }
1077
0
1078
0
            if ( gnttab_host_mapping_get_page_type(op->flags & GNTMAP_readonly,
1079
0
                                                   ld, rd) )
1080
0
            {
1081
0
                if ( (owner == dom_cow) ||
1082
0
                     !get_page_type(pg, PGT_writable_page) )
1083
0
                    goto could_not_pin;
1084
0
                typecnt++;
1085
0
            }
1086
0
1087
0
            rc = create_grant_host_mapping(op->host_addr, frame, op->flags, 0);
1088
0
            if ( rc != GNTST_okay )
1089
0
                goto undo_out;
1090
0
1091
0
            host_map_created = true;
1092
0
        }
1093
0
    }
1094
0
    else
1095
0
    {
1096
0
    could_not_pin:
1097
0
        if ( !rd->is_dying )
1098
0
            gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n",
1099
0
                     frame);
1100
0
        rc = GNTST_general_error;
1101
0
        goto undo_out;
1102
0
    }
1103
0
1104
0
    need_iommu = gnttab_need_iommu_mapping(ld);
1105
0
    if ( need_iommu )
1106
0
    {
1107
0
        unsigned int kind;
1108
0
        int err = 0;
1109
0
1110
0
        double_gt_lock(lgt, rgt);
1111
0
1112
0
        /* We're not translated, so we know that gmfns and mfns are
1113
0
           the same things, so the IOMMU entry is always 1-to-1. */
1114
0
        kind = mapkind(lgt, rd, frame);
1115
0
        if ( (act_pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) &&
1116
0
             !(old_pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
1117
0
        {
1118
0
            if ( !(kind & MAPKIND_WRITE) )
1119
0
                err = iommu_map_page(ld, frame, frame,
1120
0
                                     IOMMUF_readable|IOMMUF_writable);
1121
0
        }
1122
0
        else if ( act_pin && !old_pin )
1123
0
        {
1124
0
            if ( !kind )
1125
0
                err = iommu_map_page(ld, frame, frame, IOMMUF_readable);
1126
0
        }
1127
0
        if ( err )
1128
0
        {
1129
0
            double_gt_unlock(lgt, rgt);
1130
0
            rc = GNTST_general_error;
1131
0
            goto undo_out;
1132
0
        }
1133
0
    }
1134
0
1135
0
    TRACE_1D(TRC_MEM_PAGE_GRANT_MAP, op->dom);
1136
0
1137
0
    /*
1138
0
     * All maptrack entry users check mt->flags first before using the
1139
0
     * other fields so just ensure the flags field is stored last.
1140
0
     *
1141
0
     * However, if gnttab_need_iommu_mapping() then this would race
1142
0
     * with a concurrent mapcount() call (on an unmap, for example)
1143
0
     * and a lock is required.
1144
0
     */
1145
0
    mt = &maptrack_entry(lgt, handle);
1146
0
    mt->domid = op->dom;
1147
0
    mt->ref   = op->ref;
1148
0
    smp_wmb();
1149
0
    write_atomic(&mt->flags, op->flags);
1150
0
1151
0
    if ( need_iommu )
1152
0
        double_gt_unlock(lgt, rgt);
1153
0
1154
0
    op->dev_bus_addr = (u64)frame << PAGE_SHIFT;
1155
0
    op->handle       = handle;
1156
0
    op->status       = GNTST_okay;
1157
0
1158
0
    rcu_unlock_domain(rd);
1159
0
    return;
1160
0
1161
0
 undo_out:
1162
0
    if ( host_map_created )
1163
0
    {
1164
0
        replace_grant_host_mapping(op->host_addr, frame, 0, op->flags);
1165
0
        gnttab_flush_tlb(ld);
1166
0
    }
1167
0
1168
0
    while ( typecnt-- )
1169
0
        put_page_type(pg);
1170
0
1171
0
    while ( refcnt-- )
1172
0
        put_page(pg);
1173
0
1174
0
    grant_read_lock(rgt);
1175
0
1176
0
    act = active_entry_acquire(rgt, op->ref);
1177
0
1178
0
    if ( op->flags & GNTMAP_device_map )
1179
0
        act->pin -= (op->flags & GNTMAP_readonly) ?
1180
0
            GNTPIN_devr_inc : GNTPIN_devw_inc;
1181
0
    if ( op->flags & GNTMAP_host_map )
1182
0
        act->pin -= (op->flags & GNTMAP_readonly) ?
1183
0
            GNTPIN_hstr_inc : GNTPIN_hstw_inc;
1184
0
1185
0
 unlock_out_clear:
1186
0
    if ( !(op->flags & GNTMAP_readonly) &&
1187
0
         !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
1188
0
        gnttab_clear_flag(_GTF_writing, status);
1189
0
1190
0
    if ( !act->pin )
1191
0
        gnttab_clear_flag(_GTF_reading, status);
1192
0
1193
0
 act_release_out:
1194
0
    active_entry_release(act);
1195
0
1196
0
 unlock_out:
1197
0
    grant_read_unlock(rgt);
1198
0
    op->status = rc;
1199
0
    put_maptrack_handle(lgt, handle);
1200
0
    rcu_unlock_domain(rd);
1201
0
}
1202
1203
static long
1204
gnttab_map_grant_ref(
1205
    XEN_GUEST_HANDLE_PARAM(gnttab_map_grant_ref_t) uop, unsigned int count)
1206
0
{
1207
0
    int i;
1208
0
    struct gnttab_map_grant_ref op;
1209
0
1210
0
    for ( i = 0; i < count; i++ )
1211
0
    {
1212
0
        if ( i && hypercall_preempt_check() )
1213
0
            return i;
1214
0
1215
0
        if ( unlikely(__copy_from_guest_offset(&op, uop, i, 1)) )
1216
0
            return -EFAULT;
1217
0
1218
0
        map_grant_ref(&op);
1219
0
1220
0
        if ( unlikely(__copy_to_guest_offset(uop, i, &op, 1)) )
1221
0
            return -EFAULT;
1222
0
    }
1223
0
1224
0
    return 0;
1225
0
}
1226
1227
static void
1228
unmap_common(
1229
    struct gnttab_unmap_common *op)
1230
0
{
1231
0
    domid_t          dom;
1232
0
    struct domain   *ld, *rd;
1233
0
    struct grant_table *lgt, *rgt;
1234
0
    struct active_grant_entry *act;
1235
0
    s16              rc = 0;
1236
0
    struct grant_mapping *map;
1237
0
    unsigned int flags;
1238
0
    bool put_handle = false;
1239
0
1240
0
    ld = current->domain;
1241
0
    lgt = ld->grant_table;
1242
0
1243
0
    if ( unlikely(op->handle >= lgt->maptrack_limit) )
1244
0
    {
1245
0
        gdprintk(XENLOG_INFO, "Bad d%d handle %#x\n",
1246
0
                 lgt->domain->domain_id, op->handle);
1247
0
        op->status = GNTST_bad_handle;
1248
0
        return;
1249
0
    }
1250
0
1251
0
    smp_rmb();
1252
0
    map = &maptrack_entry(lgt, op->handle);
1253
0
1254
0
    if ( unlikely(!read_atomic(&map->flags)) )
1255
0
    {
1256
0
        gdprintk(XENLOG_INFO, "Zero flags for d%d handle %#x\n",
1257
0
                 lgt->domain->domain_id, op->handle);
1258
0
        op->status = GNTST_bad_handle;
1259
0
        return;
1260
0
    }
1261
0
1262
0
    dom = map->domid;
1263
0
    if ( unlikely((rd = rcu_lock_domain_by_id(dom)) == NULL) )
1264
0
    {
1265
0
        /* This can happen when a grant is implicitly unmapped. */
1266
0
        gdprintk(XENLOG_INFO, "Could not find domain %d\n", dom);
1267
0
        domain_crash(ld); /* naughty... */
1268
0
        return;
1269
0
    }
1270
0
1271
0
    rc = xsm_grant_unmapref(XSM_HOOK, ld, rd);
1272
0
    if ( rc )
1273
0
    {
1274
0
        rcu_unlock_domain(rd);
1275
0
        op->status = GNTST_permission_denied;
1276
0
        return;
1277
0
    }
1278
0
1279
0
    TRACE_1D(TRC_MEM_PAGE_GRANT_UNMAP, dom);
1280
0
1281
0
    rgt = rd->grant_table;
1282
0
1283
0
    grant_read_lock(rgt);
1284
0
1285
0
    if ( rgt->gt_version == 0 )
1286
0
    {
1287
0
        /*
1288
0
         * This ought to be impossible, as such a mapping should not have
1289
0
         * been established (see the nr_grant_entries(rgt) bounds check in
1290
0
         * gnttab_map_grant_ref()). Doing this check only in
1291
0
         * gnttab_unmap_common_complete() - as it used to be done - would,
1292
0
         * however, be too late.
1293
0
         */
1294
0
        rc = GNTST_bad_gntref;
1295
0
        flags = 0;
1296
0
        goto unlock_out;
1297
0
    }
1298
0
1299
0
    op->rd = rd;
1300
0
    op->ref = map->ref;
1301
0
1302
0
    /*
1303
0
     * We can't assume there was no racing unmap for this maptrack entry,
1304
0
     * and hence we can't assume map->ref is valid for rd. While the checks
1305
0
     * below (with the active entry lock held) will reject any such racing
1306
0
     * requests, we still need to make sure we don't attempt to acquire an
1307
0
     * invalid lock.
1308
0
     */
1309
0
    smp_rmb();
1310
0
    if ( unlikely(op->ref >= nr_grant_entries(rgt)) )
1311
0
    {
1312
0
        gdprintk(XENLOG_WARNING, "Unstable d%d handle %#x\n",
1313
0
                 rgt->domain->domain_id, op->handle);
1314
0
        rc = GNTST_bad_handle;
1315
0
        flags = 0;
1316
0
        goto unlock_out;
1317
0
    }
1318
0
1319
0
    act = active_entry_acquire(rgt, op->ref);
1320
0
1321
0
    /*
1322
0
     * Note that we (ab)use the active entry lock here to protect against
1323
0
     * multiple unmaps of the same mapping here. We don't want to hold lgt's
1324
0
     * lock, and we only hold rgt's lock for reading (but the latter wouldn't
1325
0
     * be the right one anyway). Hence the easiest is to rely on a lock we
1326
0
     * hold anyway; see docs/misc/grant-tables.txt's "Locking" section.
1327
0
     */
1328
0
1329
0
    flags = read_atomic(&map->flags);
1330
0
    smp_rmb();
1331
0
    if ( unlikely(!flags) || unlikely(map->domid != dom) ||
1332
0
         unlikely(map->ref != op->ref) )
1333
0
    {
1334
0
        gdprintk(XENLOG_WARNING, "Unstable handle %#x\n", op->handle);
1335
0
        rc = GNTST_bad_handle;
1336
0
        goto act_release_out;
1337
0
    }
1338
0
1339
0
    op->frame = act->frame;
1340
0
1341
0
    if ( op->dev_bus_addr &&
1342
0
         unlikely(op->dev_bus_addr != pfn_to_paddr(act->frame)) )
1343
0
        PIN_FAIL(act_release_out, GNTST_general_error,
1344
0
                 "Bus address doesn't match gntref (%"PRIx64" != %"PRIpaddr")\n",
1345
0
                 op->dev_bus_addr, pfn_to_paddr(act->frame));
1346
0
1347
0
    if ( op->host_addr && (flags & GNTMAP_host_map) )
1348
0
    {
1349
0
        if ( (rc = replace_grant_host_mapping(op->host_addr,
1350
0
                                              op->frame, op->new_addr,
1351
0
                                              flags)) < 0 )
1352
0
            goto act_release_out;
1353
0
1354
0
        map->flags &= ~GNTMAP_host_map;
1355
0
        op->done |= GNTMAP_host_map | (flags & GNTMAP_readonly);
1356
0
    }
1357
0
1358
0
    if ( op->dev_bus_addr && (flags & GNTMAP_device_map) )
1359
0
    {
1360
0
        map->flags &= ~GNTMAP_device_map;
1361
0
        op->done |= GNTMAP_device_map | (flags & GNTMAP_readonly);
1362
0
    }
1363
0
1364
0
    if ( !(map->flags & (GNTMAP_device_map|GNTMAP_host_map)) )
1365
0
    {
1366
0
        map->flags = 0;
1367
0
        put_handle = true;
1368
0
    }
1369
0
1370
0
 act_release_out:
1371
0
    active_entry_release(act);
1372
0
 unlock_out:
1373
0
    grant_read_unlock(rgt);
1374
0
1375
0
    if ( put_handle )
1376
0
        put_maptrack_handle(lgt, op->handle);
1377
0
1378
0
    if ( rc == GNTST_okay && gnttab_need_iommu_mapping(ld) )
1379
0
    {
1380
0
        unsigned int kind;
1381
0
        int err = 0;
1382
0
1383
0
        double_gt_lock(lgt, rgt);
1384
0
1385
0
        kind = mapkind(lgt, rd, op->frame);
1386
0
        if ( !kind )
1387
0
            err = iommu_unmap_page(ld, op->frame);
1388
0
        else if ( !(kind & MAPKIND_WRITE) )
1389
0
            err = iommu_map_page(ld, op->frame, op->frame, IOMMUF_readable);
1390
0
1391
0
        double_gt_unlock(lgt, rgt);
1392
0
1393
0
        if ( err )
1394
0
            rc = GNTST_general_error;
1395
0
    }
1396
0
1397
0
    /* If just unmapped a writable mapping, mark as dirtied */
1398
0
    if ( rc == GNTST_okay && !(flags & GNTMAP_readonly) )
1399
0
         gnttab_mark_dirty(rd, op->frame);
1400
0
1401
0
    op->status = rc;
1402
0
    rcu_unlock_domain(rd);
1403
0
}
1404
1405
static void
1406
unmap_common_complete(struct gnttab_unmap_common *op)
1407
0
{
1408
0
    struct domain *ld, *rd = op->rd;
1409
0
    struct grant_table *rgt;
1410
0
    struct active_grant_entry *act;
1411
0
    grant_entry_header_t *sha;
1412
0
    struct page_info *pg;
1413
0
    uint16_t *status;
1414
0
1415
0
    if ( !op->done )
1416
0
    {
1417
0
        /* unmap_common() didn't do anything - nothing to complete. */
1418
0
        return;
1419
0
    }
1420
0
1421
0
    ld = current->domain;
1422
0
1423
0
    rcu_lock_domain(rd);
1424
0
    rgt = rd->grant_table;
1425
0
1426
0
    grant_read_lock(rgt);
1427
0
1428
0
    act = active_entry_acquire(rgt, op->ref);
1429
0
    sha = shared_entry_header(rgt, op->ref);
1430
0
1431
0
    if ( rgt->gt_version == 1 )
1432
0
        status = &sha->flags;
1433
0
    else
1434
0
        status = &status_entry(rgt, op->ref);
1435
0
1436
0
    pg = mfn_to_page(op->frame);
1437
0
1438
0
    if ( op->done & GNTMAP_device_map )
1439
0
    {
1440
0
        if ( !is_iomem_page(_mfn(act->frame)) )
1441
0
        {
1442
0
            if ( op->done & GNTMAP_readonly )
1443
0
                put_page(pg);
1444
0
            else
1445
0
                put_page_and_type(pg);
1446
0
        }
1447
0
1448
0
        ASSERT(act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask));
1449
0
        if ( op->done & GNTMAP_readonly )
1450
0
            act->pin -= GNTPIN_devr_inc;
1451
0
        else
1452
0
            act->pin -= GNTPIN_devw_inc;
1453
0
    }
1454
0
1455
0
    if ( op->done & GNTMAP_host_map )
1456
0
    {
1457
0
        if ( !is_iomem_page(_mfn(op->frame)) )
1458
0
        {
1459
0
            if ( gnttab_host_mapping_get_page_type(op->done & GNTMAP_readonly,
1460
0
                                                   ld, rd) )
1461
0
                put_page_type(pg);
1462
0
            put_page(pg);
1463
0
        }
1464
0
1465
0
        ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask));
1466
0
        if ( op->done & GNTMAP_readonly )
1467
0
            act->pin -= GNTPIN_hstr_inc;
1468
0
        else
1469
0
            act->pin -= GNTPIN_hstw_inc;
1470
0
    }
1471
0
1472
0
    if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) &&
1473
0
         !(op->done & GNTMAP_readonly) )
1474
0
        gnttab_clear_flag(_GTF_writing, status);
1475
0
1476
0
    if ( act->pin == 0 )
1477
0
        gnttab_clear_flag(_GTF_reading, status);
1478
0
1479
0
    active_entry_release(act);
1480
0
    grant_read_unlock(rgt);
1481
0
1482
0
    rcu_unlock_domain(rd);
1483
0
}
1484
1485
static void
1486
unmap_grant_ref(
1487
    struct gnttab_unmap_grant_ref *op,
1488
    struct gnttab_unmap_common *common)
1489
0
{
1490
0
    common->host_addr = op->host_addr;
1491
0
    common->dev_bus_addr = op->dev_bus_addr;
1492
0
    common->handle = op->handle;
1493
0
1494
0
    /* Intialise these in case common contains old state */
1495
0
    common->done = 0;
1496
0
    common->new_addr = 0;
1497
0
    common->rd = NULL;
1498
0
    common->frame = 0;
1499
0
1500
0
    unmap_common(common);
1501
0
    op->status = common->status;
1502
0
}
1503
1504
1505
static long
1506
gnttab_unmap_grant_ref(
1507
    XEN_GUEST_HANDLE_PARAM(gnttab_unmap_grant_ref_t) uop, unsigned int count)
1508
0
{
1509
0
    int i, c, partial_done, done = 0;
1510
0
    struct gnttab_unmap_grant_ref op;
1511
0
    struct gnttab_unmap_common common[GNTTAB_UNMAP_BATCH_SIZE];
1512
0
1513
0
    while ( count != 0 )
1514
0
    {
1515
0
        c = min(count, (unsigned int)GNTTAB_UNMAP_BATCH_SIZE);
1516
0
        partial_done = 0;
1517
0
1518
0
        for ( i = 0; i < c; i++ )
1519
0
        {
1520
0
            if ( unlikely(__copy_from_guest(&op, uop, 1)) )
1521
0
                goto fault;
1522
0
            unmap_grant_ref(&op, &common[i]);
1523
0
            ++partial_done;
1524
0
            if ( unlikely(__copy_field_to_guest(uop, &op, status)) )
1525
0
                goto fault;
1526
0
            guest_handle_add_offset(uop, 1);
1527
0
        }
1528
0
1529
0
        gnttab_flush_tlb(current->domain);
1530
0
1531
0
        for ( i = 0; i < partial_done; i++ )
1532
0
            unmap_common_complete(&common[i]);
1533
0
1534
0
        count -= c;
1535
0
        done += c;
1536
0
1537
0
        if ( count && hypercall_preempt_check() )
1538
0
            return done;
1539
0
    }
1540
0
1541
0
    return 0;
1542
0
1543
0
fault:
1544
0
    gnttab_flush_tlb(current->domain);
1545
0
1546
0
    for ( i = 0; i < partial_done; i++ )
1547
0
        unmap_common_complete(&common[i]);
1548
0
    return -EFAULT;
1549
0
}
1550
1551
static void
1552
unmap_and_replace(
1553
    struct gnttab_unmap_and_replace *op,
1554
    struct gnttab_unmap_common *common)
1555
0
{
1556
0
    common->host_addr = op->host_addr;
1557
0
    common->new_addr = op->new_addr;
1558
0
    common->handle = op->handle;
1559
0
1560
0
    /* Intialise these in case common contains old state */
1561
0
    common->done = 0;
1562
0
    common->dev_bus_addr = 0;
1563
0
    common->rd = NULL;
1564
0
    common->frame = 0;
1565
0
1566
0
    unmap_common(common);
1567
0
    op->status = common->status;
1568
0
}
1569
1570
static long
1571
gnttab_unmap_and_replace(
1572
    XEN_GUEST_HANDLE_PARAM(gnttab_unmap_and_replace_t) uop, unsigned int count)
1573
0
{
1574
0
    int i, c, partial_done, done = 0;
1575
0
    struct gnttab_unmap_and_replace op;
1576
0
    struct gnttab_unmap_common common[GNTTAB_UNMAP_BATCH_SIZE];
1577
0
1578
0
    while ( count != 0 )
1579
0
    {
1580
0
        c = min(count, (unsigned int)GNTTAB_UNMAP_BATCH_SIZE);
1581
0
        partial_done = 0;
1582
0
1583
0
        for ( i = 0; i < c; i++ )
1584
0
        {
1585
0
            if ( unlikely(__copy_from_guest(&op, uop, 1)) )
1586
0
                goto fault;
1587
0
            unmap_and_replace(&op, &common[i]);
1588
0
            ++partial_done;
1589
0
            if ( unlikely(__copy_field_to_guest(uop, &op, status)) )
1590
0
                goto fault;
1591
0
            guest_handle_add_offset(uop, 1);
1592
0
        }
1593
0
1594
0
        gnttab_flush_tlb(current->domain);
1595
0
1596
0
        for ( i = 0; i < partial_done; i++ )
1597
0
            unmap_common_complete(&common[i]);
1598
0
1599
0
        count -= c;
1600
0
        done += c;
1601
0
1602
0
        if ( count && hypercall_preempt_check() )
1603
0
            return done;
1604
0
    }
1605
0
1606
0
    return 0;
1607
0
1608
0
fault:
1609
0
    gnttab_flush_tlb(current->domain);
1610
0
1611
0
    for ( i = 0; i < partial_done; i++ )
1612
0
        unmap_common_complete(&common[i]);
1613
0
    return -EFAULT;
1614
0
}
1615
1616
static int
1617
gnttab_populate_status_frames(struct domain *d, struct grant_table *gt,
1618
                              unsigned int req_nr_frames)
1619
0
{
1620
0
    unsigned i;
1621
0
    unsigned req_status_frames;
1622
0
1623
0
    req_status_frames = grant_to_status_frames(req_nr_frames);
1624
0
    for ( i = nr_status_frames(gt); i < req_status_frames; i++ )
1625
0
    {
1626
0
        if ( (gt->status[i] = alloc_xenheap_page()) == NULL )
1627
0
            goto status_alloc_failed;
1628
0
        clear_page(gt->status[i]);
1629
0
    }
1630
0
    /* Share the new status frames with the recipient domain */
1631
0
    for ( i = nr_status_frames(gt); i < req_status_frames; i++ )
1632
0
        gnttab_create_status_page(d, gt, i);
1633
0
1634
0
    gt->nr_status_frames = req_status_frames;
1635
0
1636
0
    return 0;
1637
0
1638
0
status_alloc_failed:
1639
0
    for ( i = nr_status_frames(gt); i < req_status_frames; i++ )
1640
0
    {
1641
0
        free_xenheap_page(gt->status[i]);
1642
0
        gt->status[i] = NULL;
1643
0
    }
1644
0
    return -ENOMEM;
1645
0
}
1646
1647
static void
1648
gnttab_unpopulate_status_frames(struct domain *d, struct grant_table *gt)
1649
0
{
1650
0
    int i;
1651
0
1652
0
    for ( i = 0; i < nr_status_frames(gt); i++ )
1653
0
    {
1654
0
        struct page_info *pg = virt_to_page(gt->status[i]);
1655
0
1656
0
        BUG_ON(page_get_owner(pg) != d);
1657
0
        if ( test_and_clear_bit(_PGC_allocated, &pg->count_info) )
1658
0
            put_page(pg);
1659
0
        BUG_ON(pg->count_info & ~PGC_xen_heap);
1660
0
        free_xenheap_page(gt->status[i]);
1661
0
        gt->status[i] = NULL;
1662
0
    }
1663
0
    gt->nr_status_frames = 0;
1664
0
}
1665
1666
/*
1667
 * Grow the grant table. The caller must hold the grant table's
1668
 * write lock before calling this function.
1669
 */
1670
static int
1671
gnttab_grow_table(struct domain *d, unsigned int req_nr_frames)
1672
1
{
1673
1
    struct grant_table *gt = d->grant_table;
1674
1
    unsigned int i, j;
1675
1
1676
1
    if ( unlikely(!gt->active) )
1677
0
    {
1678
0
        gprintk(XENLOG_WARNING, "grant_table_set_limits() call missing\n");
1679
0
        return -ENODEV;
1680
0
    }
1681
1
1682
1
    if ( req_nr_frames < INITIAL_NR_GRANT_FRAMES )
1683
1
        req_nr_frames = INITIAL_NR_GRANT_FRAMES;
1684
1
    ASSERT(req_nr_frames <= gt->max_grant_frames);
1685
1
1686
1
    gdprintk(XENLOG_INFO,
1687
1
            "Expanding d%d grant table from %u to %u frames\n",
1688
1
            d->domain_id, nr_grant_frames(gt), req_nr_frames);
1689
1
1690
1
    /* Active */
1691
1
    for ( i = nr_active_grant_frames(gt);
1692
8
          i < num_act_frames_from_sha_frames(req_nr_frames); i++ )
1693
7
    {
1694
7
        if ( (gt->active[i] = alloc_xenheap_page()) == NULL )
1695
0
            goto active_alloc_failed;
1696
7
        clear_page(gt->active[i]);
1697
602
        for ( j = 0; j < ACGNT_PER_PAGE; j++ )
1698
595
            spin_lock_init(&gt->active[i][j].lock);
1699
7
    }
1700
1
1701
1
    /* Shared */
1702
2
    for ( i = nr_grant_frames(gt); i < req_nr_frames; i++ )
1703
1
    {
1704
1
        if ( (gt->shared_raw[i] = alloc_xenheap_page()) == NULL )
1705
0
            goto shared_alloc_failed;
1706
1
        clear_page(gt->shared_raw[i]);
1707
1
    }
1708
1
1709
1
    /* Status pages - version 2 */
1710
1
    if ( gt->gt_version > 1 )
1711
0
    {
1712
0
        if ( gnttab_populate_status_frames(d, gt, req_nr_frames) )
1713
0
            goto shared_alloc_failed;
1714
0
    }
1715
1
1716
1
    /* Share the new shared frames with the recipient domain */
1717
2
    for ( i = nr_grant_frames(gt); i < req_nr_frames; i++ )
1718
1
        gnttab_create_shared_page(d, gt, i);
1719
1
    gt->nr_grant_frames = req_nr_frames;
1720
1
1721
1
    return 0;
1722
1
1723
0
shared_alloc_failed:
1724
0
    for ( i = nr_grant_frames(gt); i < req_nr_frames; i++ )
1725
0
    {
1726
0
        free_xenheap_page(gt->shared_raw[i]);
1727
0
        gt->shared_raw[i] = NULL;
1728
0
    }
1729
0
active_alloc_failed:
1730
0
    for ( i = nr_active_grant_frames(gt);
1731
0
          i < num_act_frames_from_sha_frames(req_nr_frames); i++ )
1732
0
    {
1733
0
        free_xenheap_page(gt->active[i]);
1734
0
        gt->active[i] = NULL;
1735
0
    }
1736
0
    gdprintk(XENLOG_INFO, "Allocation failure when expanding d%d grant table\n",
1737
0
             d->domain_id);
1738
0
1739
0
    return -ENOMEM;
1740
0
}
1741
1742
static int
1743
grant_table_init(struct domain *d, struct grant_table *gt,
1744
                 unsigned int grant_frames, unsigned int maptrack_frames)
1745
1
{
1746
1
    int ret = -ENOMEM;
1747
1
1748
1
    grant_write_lock(gt);
1749
1
1750
1
    if ( gt->active )
1751
0
    {
1752
0
        ret = -EBUSY;
1753
0
        goto out_no_cleanup;
1754
0
    }
1755
1
1756
1
    gt->max_grant_frames = grant_frames;
1757
1
    gt->max_maptrack_frames = maptrack_frames;
1758
1
1759
1
    /* Active grant table. */
1760
1
    gt->active = xzalloc_array(struct active_grant_entry *,
1761
1
                               max_nr_active_grant_frames(gt));
1762
1
    if ( gt->active == NULL )
1763
0
        goto out;
1764
1
1765
1
    /* Tracking of mapped foreign frames table */
1766
1
    if ( gt->max_maptrack_frames )
1767
1
    {
1768
1
        gt->maptrack = vzalloc(gt->max_maptrack_frames * sizeof(*gt->maptrack));
1769
1
        if ( gt->maptrack == NULL )
1770
0
            goto out;
1771
1
    }
1772
1
1773
1
    /* Shared grant table. */
1774
1
    gt->shared_raw = xzalloc_array(void *, gt->max_grant_frames);
1775
1
    if ( gt->shared_raw == NULL )
1776
0
        goto out;
1777
1
1778
1
    /* Status pages for grant table - for version 2 */
1779
1
    gt->status = xzalloc_array(grant_status_t *,
1780
1
                               grant_to_status_frames(gt->max_grant_frames));
1781
1
    if ( gt->status == NULL )
1782
0
        goto out;
1783
1
1784
1
    ret = gnttab_init_arch(gt);
1785
1
    if ( ret )
1786
0
        goto out;
1787
1
1788
1
    /* gnttab_grow_table() allocates a min number of frames, so 0 is okay. */
1789
1
    ret = gnttab_grow_table(d, 0);
1790
1
1791
1
 out:
1792
1
    if ( ret )
1793
0
    {
1794
0
        gnttab_destroy_arch(gt);
1795
0
        xfree(gt->status);
1796
0
        gt->status = NULL;
1797
0
        xfree(gt->shared_raw);
1798
0
        gt->shared_raw = NULL;
1799
0
        vfree(gt->maptrack);
1800
0
        gt->maptrack = NULL;
1801
0
        xfree(gt->active);
1802
0
        gt->active = NULL;
1803
0
    }
1804
1
1805
1
 out_no_cleanup:
1806
1
    grant_write_unlock(gt);
1807
1
1808
1
    return ret;
1809
1
}
1810
1811
static long
1812
gnttab_setup_table(
1813
    XEN_GUEST_HANDLE_PARAM(gnttab_setup_table_t) uop, unsigned int count,
1814
    unsigned int limit_max)
1815
0
{
1816
0
    struct vcpu *curr = current;
1817
0
    struct gnttab_setup_table op;
1818
0
    struct domain *d = NULL;
1819
0
    struct grant_table *gt;
1820
0
    unsigned int i;
1821
0
1822
0
    if ( count != 1 )
1823
0
        return -EINVAL;
1824
0
1825
0
    if ( unlikely(copy_from_guest(&op, uop, 1)) )
1826
0
        return -EFAULT;
1827
0
1828
0
    if ( !guest_handle_okay(op.frame_list, op.nr_frames) )
1829
0
        return -EFAULT;
1830
0
1831
0
    d = rcu_lock_domain_by_any_id(op.dom);
1832
0
    if ( d == NULL )
1833
0
    {
1834
0
        op.status = GNTST_bad_domain;
1835
0
        goto out;
1836
0
    }
1837
0
1838
0
    if ( xsm_grant_setup(XSM_TARGET, curr->domain, d) )
1839
0
    {
1840
0
        op.status = GNTST_permission_denied;
1841
0
        goto out;
1842
0
    }
1843
0
1844
0
    gt = d->grant_table;
1845
0
    grant_write_lock(gt);
1846
0
1847
0
    if ( unlikely(op.nr_frames > gt->max_grant_frames) )
1848
0
    {
1849
0
        gdprintk(XENLOG_INFO, "d%d is limited to %u grant-table frames\n",
1850
0
                d->domain_id, gt->max_grant_frames);
1851
0
        op.status = GNTST_general_error;
1852
0
        goto unlock;
1853
0
    }
1854
0
    if ( unlikely(limit_max < op.nr_frames) )
1855
0
    {
1856
0
        gdprintk(XENLOG_WARNING, "nr_frames for d%d is too large (%u,%u)\n",
1857
0
                 d->domain_id, op.nr_frames, limit_max);
1858
0
        op.status = GNTST_general_error;
1859
0
        goto unlock;
1860
0
    }
1861
0
1862
0
    if ( gt->gt_version == 0 )
1863
0
        gt->gt_version = 1;
1864
0
1865
0
    if ( (op.nr_frames > nr_grant_frames(gt) ||
1866
0
          ((gt->gt_version > 1) &&
1867
0
           (grant_to_status_frames(op.nr_frames) > nr_status_frames(gt)))) &&
1868
0
         gnttab_grow_table(d, op.nr_frames) )
1869
0
    {
1870
0
        gdprintk(XENLOG_INFO,
1871
0
                 "Expand grant table of d%d to %u failed. Current: %u Max: %u\n",
1872
0
                 d->domain_id, op.nr_frames, nr_grant_frames(gt),
1873
0
                 gt->max_grant_frames);
1874
0
        op.status = GNTST_general_error;
1875
0
        goto unlock;
1876
0
    }
1877
0
1878
0
    op.status = GNTST_okay;
1879
0
    for ( i = 0; i < op.nr_frames; i++ )
1880
0
    {
1881
0
        xen_pfn_t gmfn = gnttab_shared_gmfn(d, gt, i);
1882
0
1883
0
        /* Grant tables cannot be shared */
1884
0
        BUG_ON(SHARED_M2P(gmfn));
1885
0
1886
0
        if ( __copy_to_guest_offset(op.frame_list, i, &gmfn, 1) )
1887
0
            op.status = GNTST_bad_virt_addr;
1888
0
    }
1889
0
1890
0
 unlock:
1891
0
    grant_write_unlock(gt);
1892
0
 out:
1893
0
    if ( d )
1894
0
        rcu_unlock_domain(d);
1895
0
1896
0
    if ( unlikely(__copy_field_to_guest(uop, &op, status)) )
1897
0
        return -EFAULT;
1898
0
1899
0
    return 0;
1900
0
}
1901
1902
static long
1903
gnttab_query_size(
1904
    XEN_GUEST_HANDLE_PARAM(gnttab_query_size_t) uop, unsigned int count)
1905
3
{
1906
3
    struct gnttab_query_size op;
1907
3
    struct domain *d;
1908
3
    struct grant_table *gt;
1909
3
1910
3
    if ( count != 1 )
1911
0
        return -EINVAL;
1912
3
1913
3
    if ( unlikely(copy_from_guest(&op, uop, 1)) )
1914
0
        return -EFAULT;
1915
3
1916
3
    d = rcu_lock_domain_by_any_id(op.dom);
1917
3
    if ( d == NULL )
1918
0
    {
1919
0
        op.status = GNTST_bad_domain;
1920
0
        goto out;
1921
0
    }
1922
3
1923
3
    if ( xsm_grant_query_size(XSM_TARGET, current->domain, d) )
1924
0
    {
1925
0
        op.status = GNTST_permission_denied;
1926
0
        goto out;
1927
0
    }
1928
3
1929
3
    gt = d->grant_table;
1930
3
1931
3
    grant_read_lock(gt);
1932
3
1933
3
    op.nr_frames     = nr_grant_frames(gt);
1934
3
    op.max_nr_frames = gt->max_grant_frames;
1935
3
    op.status        = GNTST_okay;
1936
3
1937
3
    grant_read_unlock(gt);
1938
3
1939
3
 out:
1940
3
    if ( d )
1941
3
        rcu_unlock_domain(d);
1942
3
1943
3
    if ( unlikely(__copy_to_guest(uop, &op, 1)) )
1944
0
        return -EFAULT;
1945
3
1946
3
    return 0;
1947
3
}
1948
1949
/*
1950
 * Check that the given grant reference (rd,ref) allows 'ld' to transfer
1951
 * ownership of a page frame. If so, lock down the grant entry.
1952
 */
1953
static int
1954
gnttab_prepare_for_transfer(
1955
    struct domain *rd, struct domain *ld, grant_ref_t ref)
1956
0
{
1957
0
    struct grant_table *rgt = rd->grant_table;
1958
0
    grant_entry_header_t *sha;
1959
0
    union grant_combo   scombo, prev_scombo, new_scombo;
1960
0
    int                 retries = 0;
1961
0
1962
0
    grant_read_lock(rgt);
1963
0
1964
0
    if ( unlikely(ref >= nr_grant_entries(rgt)) )
1965
0
    {
1966
0
        gdprintk(XENLOG_INFO,
1967
0
                "Bad grant reference %#x for transfer to d%d\n",
1968
0
                ref, rd->domain_id);
1969
0
        goto fail;
1970
0
    }
1971
0
1972
0
    sha = shared_entry_header(rgt, ref);
1973
0
1974
0
    scombo.word = *(u32 *)&sha->flags;
1975
0
1976
0
    for ( ; ; )
1977
0
    {
1978
0
        if ( unlikely(scombo.shorts.flags != GTF_accept_transfer) ||
1979
0
             unlikely(scombo.shorts.domid != ld->domain_id) )
1980
0
        {
1981
0
            gdprintk(XENLOG_INFO,
1982
0
                     "Bad flags (%x) or dom (%d); expected d%d\n",
1983
0
                     scombo.shorts.flags, scombo.shorts.domid,
1984
0
                     ld->domain_id);
1985
0
            goto fail;
1986
0
        }
1987
0
1988
0
        new_scombo = scombo;
1989
0
        new_scombo.shorts.flags |= GTF_transfer_committed;
1990
0
1991
0
        prev_scombo.word = cmpxchg((u32 *)&sha->flags,
1992
0
                                   scombo.word, new_scombo.word);
1993
0
        if ( likely(prev_scombo.word == scombo.word) )
1994
0
            break;
1995
0
1996
0
        if ( retries++ == 4 )
1997
0
        {
1998
0
            gdprintk(XENLOG_WARNING, "Shared grant entry is unstable\n");
1999
0
            goto fail;
2000
0
        }
2001
0
2002
0
        scombo = prev_scombo;
2003
0
    }
2004
0
2005
0
    grant_read_unlock(rgt);
2006
0
    return 1;
2007
0
2008
0
 fail:
2009
0
    grant_read_unlock(rgt);
2010
0
    return 0;
2011
0
}
2012
2013
static long
2014
gnttab_transfer(
2015
    XEN_GUEST_HANDLE_PARAM(gnttab_transfer_t) uop, unsigned int count)
2016
0
{
2017
0
    struct domain *d = current->domain;
2018
0
    struct domain *e;
2019
0
    struct page_info *page;
2020
0
    int i;
2021
0
    struct gnttab_transfer gop;
2022
0
    unsigned long mfn;
2023
0
    unsigned int max_bitsize;
2024
0
    struct active_grant_entry *act;
2025
0
2026
0
    for ( i = 0; i < count; i++ )
2027
0
    {
2028
0
        bool_t okay;
2029
0
        int rc;
2030
0
2031
0
        if ( i && hypercall_preempt_check() )
2032
0
            return i;
2033
0
2034
0
        /* Read from caller address space. */
2035
0
        if ( unlikely(__copy_from_guest(&gop, uop, 1)) )
2036
0
        {
2037
0
            gdprintk(XENLOG_INFO, "error reading req %d/%u\n",
2038
0
                    i, count);
2039
0
            return -EFAULT;
2040
0
        }
2041
0
2042
0
#ifdef CONFIG_X86
2043
0
        {
2044
0
            p2m_type_t p2mt;
2045
0
2046
0
            mfn = mfn_x(get_gfn_unshare(d, gop.mfn, &p2mt));
2047
0
            if ( p2m_is_shared(p2mt) || !p2m_is_valid(p2mt) )
2048
0
                mfn = mfn_x(INVALID_MFN);
2049
0
        }
2050
0
#else
2051
        mfn = mfn_x(gfn_to_mfn(d, _gfn(gop.mfn)));
2052
#endif
2053
0
2054
0
        /* Check the passed page frame for basic validity. */
2055
0
        if ( unlikely(!mfn_valid(_mfn(mfn))) )
2056
0
        {
2057
0
            put_gfn(d, gop.mfn);
2058
0
            gdprintk(XENLOG_INFO, "out-of-range %lx\n", (unsigned long)gop.mfn);
2059
0
            gop.status = GNTST_bad_page;
2060
0
            goto copyback;
2061
0
        }
2062
0
2063
0
        page = mfn_to_page(mfn);
2064
0
        if ( (rc = steal_page(d, page, 0)) < 0 )
2065
0
        {
2066
0
            put_gfn(d, gop.mfn);
2067
0
            gop.status = rc == -EINVAL ? GNTST_bad_page : GNTST_general_error;
2068
0
            goto copyback;
2069
0
        }
2070
0
2071
0
        rc = guest_physmap_remove_page(d, _gfn(gop.mfn), _mfn(mfn), 0);
2072
0
        gnttab_flush_tlb(d);
2073
0
        if ( rc )
2074
0
        {
2075
0
            gdprintk(XENLOG_INFO, "can't remove GFN %"PRI_xen_pfn" (MFN %lx)\n",
2076
0
                     gop.mfn, mfn);
2077
0
            gop.status = GNTST_general_error;
2078
0
            goto put_gfn_and_copyback;
2079
0
        }
2080
0
2081
0
        /* Find the target domain. */
2082
0
        if ( unlikely((e = rcu_lock_domain_by_id(gop.domid)) == NULL) )
2083
0
        {
2084
0
            gdprintk(XENLOG_INFO, "can't find d%d\n", gop.domid);
2085
0
            gop.status = GNTST_bad_domain;
2086
0
            goto put_gfn_and_copyback;
2087
0
        }
2088
0
2089
0
        if ( xsm_grant_transfer(XSM_HOOK, d, e) )
2090
0
        {
2091
0
            gop.status = GNTST_permission_denied;
2092
0
        unlock_and_copyback:
2093
0
            rcu_unlock_domain(e);
2094
0
        put_gfn_and_copyback:
2095
0
            put_gfn(d, gop.mfn);
2096
0
            page->count_info &= ~(PGC_count_mask|PGC_allocated);
2097
0
            free_domheap_page(page);
2098
0
            goto copyback;
2099
0
        }
2100
0
2101
0
        max_bitsize = domain_clamp_alloc_bitsize(
2102
0
            e, e->grant_table->gt_version > 1 || paging_mode_translate(e)
2103
0
               ? BITS_PER_LONG + PAGE_SHIFT : 32 + PAGE_SHIFT);
2104
0
        if ( max_bitsize < BITS_PER_LONG + PAGE_SHIFT &&
2105
0
             (mfn >> (max_bitsize - PAGE_SHIFT)) )
2106
0
        {
2107
0
            struct page_info *new_page;
2108
0
2109
0
            new_page = alloc_domheap_page(e, MEMF_no_owner |
2110
0
                                             MEMF_bits(max_bitsize));
2111
0
            if ( new_page == NULL )
2112
0
            {
2113
0
                gop.status = GNTST_address_too_big;
2114
0
                goto unlock_and_copyback;
2115
0
            }
2116
0
2117
0
            copy_domain_page(_mfn(page_to_mfn(new_page)), _mfn(mfn));
2118
0
2119
0
            page->count_info &= ~(PGC_count_mask|PGC_allocated);
2120
0
            free_domheap_page(page);
2121
0
            page = new_page;
2122
0
        }
2123
0
2124
0
        spin_lock(&e->page_alloc_lock);
2125
0
2126
0
        /*
2127
0
         * Check that 'e' will accept the page and has reservation
2128
0
         * headroom.  Also, a domain mustn't have PGC_allocated
2129
0
         * pages when it is dying.
2130
0
         */
2131
0
        if ( unlikely(e->is_dying) ||
2132
0
             unlikely(e->tot_pages >= e->max_pages) )
2133
0
        {
2134
0
            spin_unlock(&e->page_alloc_lock);
2135
0
2136
0
            if ( e->is_dying )
2137
0
                gdprintk(XENLOG_INFO, "Transferee d%d is dying\n",
2138
0
                         e->domain_id);
2139
0
            else
2140
0
                gdprintk(XENLOG_INFO,
2141
0
                         "Transferee d%d has no headroom (tot %u, max %u)\n",
2142
0
                         e->domain_id, e->tot_pages, e->max_pages);
2143
0
2144
0
            gop.status = GNTST_general_error;
2145
0
            goto unlock_and_copyback;
2146
0
        }
2147
0
2148
0
        /* Okay, add the page to 'e'. */
2149
0
        if ( unlikely(domain_adjust_tot_pages(e, 1) == 1) )
2150
0
            get_knownalive_domain(e);
2151
0
2152
0
        /*
2153
0
         * We must drop the lock to avoid a possible deadlock in
2154
0
         * gnttab_prepare_for_transfer.  We have reserved a page in e so can
2155
0
         * safely drop the lock and re-aquire it later to add page to the
2156
0
         * pagelist.
2157
0
         */
2158
0
        spin_unlock(&e->page_alloc_lock);
2159
0
        okay = gnttab_prepare_for_transfer(e, d, gop.ref);
2160
0
        spin_lock(&e->page_alloc_lock);
2161
0
2162
0
        if ( unlikely(!okay) || unlikely(e->is_dying) )
2163
0
        {
2164
0
            bool_t drop_dom_ref = !domain_adjust_tot_pages(e, -1);
2165
0
2166
0
            spin_unlock(&e->page_alloc_lock);
2167
0
2168
0
            if ( okay /* i.e. e->is_dying due to the surrounding if() */ )
2169
0
                gdprintk(XENLOG_INFO, "Transferee d%d is now dying\n",
2170
0
                         e->domain_id);
2171
0
2172
0
            if ( drop_dom_ref )
2173
0
                put_domain(e);
2174
0
            gop.status = GNTST_general_error;
2175
0
            goto unlock_and_copyback;
2176
0
        }
2177
0
2178
0
        page_list_add_tail(page, &e->page_list);
2179
0
        page_set_owner(page, e);
2180
0
2181
0
        spin_unlock(&e->page_alloc_lock);
2182
0
        put_gfn(d, gop.mfn);
2183
0
2184
0
        TRACE_1D(TRC_MEM_PAGE_GRANT_TRANSFER, e->domain_id);
2185
0
2186
0
        /* Tell the guest about its new page frame. */
2187
0
        grant_read_lock(e->grant_table);
2188
0
        act = active_entry_acquire(e->grant_table, gop.ref);
2189
0
2190
0
        if ( e->grant_table->gt_version == 1 )
2191
0
        {
2192
0
            grant_entry_v1_t *sha = &shared_entry_v1(e->grant_table, gop.ref);
2193
0
2194
0
            guest_physmap_add_page(e, _gfn(sha->frame), _mfn(mfn), 0);
2195
0
            if ( !paging_mode_translate(e) )
2196
0
                sha->frame = mfn;
2197
0
        }
2198
0
        else
2199
0
        {
2200
0
            grant_entry_v2_t *sha = &shared_entry_v2(e->grant_table, gop.ref);
2201
0
2202
0
            guest_physmap_add_page(e, _gfn(sha->full_page.frame),
2203
0
                                   _mfn(mfn), 0);
2204
0
            if ( !paging_mode_translate(e) )
2205
0
                sha->full_page.frame = mfn;
2206
0
        }
2207
0
        smp_wmb();
2208
0
        shared_entry_header(e->grant_table, gop.ref)->flags |=
2209
0
            GTF_transfer_completed;
2210
0
2211
0
        active_entry_release(act);
2212
0
        grant_read_unlock(e->grant_table);
2213
0
2214
0
        rcu_unlock_domain(e);
2215
0
2216
0
        gop.status = GNTST_okay;
2217
0
2218
0
    copyback:
2219
0
        if ( unlikely(__copy_field_to_guest(uop, &gop, status)) )
2220
0
        {
2221
0
            gdprintk(XENLOG_INFO, "error writing resp %d/%u\n", i, count);
2222
0
            return -EFAULT;
2223
0
        }
2224
0
        guest_handle_add_offset(uop, 1);
2225
0
    }
2226
0
2227
0
    return 0;
2228
0
}
2229
2230
/*
2231
 * Undo acquire_grant_for_copy().  This has no effect on page type and
2232
 * reference counts.
2233
 */
2234
static void
2235
release_grant_for_copy(
2236
    struct domain *rd, grant_ref_t gref, bool readonly)
2237
0
{
2238
0
    struct grant_table *rgt = rd->grant_table;
2239
0
    grant_entry_header_t *sha;
2240
0
    struct active_grant_entry *act;
2241
0
    unsigned long r_frame;
2242
0
    uint16_t *status;
2243
0
    grant_ref_t trans_gref;
2244
0
    struct domain *td;
2245
0
2246
0
    grant_read_lock(rgt);
2247
0
2248
0
    act = active_entry_acquire(rgt, gref);
2249
0
    sha = shared_entry_header(rgt, gref);
2250
0
    r_frame = act->frame;
2251
0
2252
0
    if ( rgt->gt_version == 1 )
2253
0
    {
2254
0
        status = &sha->flags;
2255
0
        td = rd;
2256
0
        trans_gref = gref;
2257
0
    }
2258
0
    else
2259
0
    {
2260
0
        status = &status_entry(rgt, gref);
2261
0
        td = act->trans_domain;
2262
0
        trans_gref = act->trans_gref;
2263
0
    }
2264
0
2265
0
    if ( readonly )
2266
0
    {
2267
0
        act->pin -= GNTPIN_hstr_inc;
2268
0
    }
2269
0
    else
2270
0
    {
2271
0
        gnttab_mark_dirty(rd, r_frame);
2272
0
2273
0
        act->pin -= GNTPIN_hstw_inc;
2274
0
        if ( !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) )
2275
0
            gnttab_clear_flag(_GTF_writing, status);
2276
0
    }
2277
0
2278
0
    if ( !act->pin )
2279
0
        gnttab_clear_flag(_GTF_reading, status);
2280
0
2281
0
    active_entry_release(act);
2282
0
    grant_read_unlock(rgt);
2283
0
2284
0
    if ( td != rd )
2285
0
    {
2286
0
        /*
2287
0
         * Recursive call, but it is bounded (acquire permits only a single
2288
0
         * level of transitivity), so it's okay.
2289
0
         */
2290
0
        release_grant_for_copy(td, trans_gref, readonly);
2291
0
2292
0
        rcu_unlock_domain(td);
2293
0
    }
2294
0
}
2295
2296
/* The status for a grant indicates that we're taking more access than
2297
   the pin requires.  Fix up the status to match the pin.  Called
2298
   under the domain's grant table lock. */
2299
/* Only safe on transitive grants.  Even then, note that we don't
2300
   attempt to drop any pin on the referent grant. */
2301
static void fixup_status_for_copy_pin(const struct active_grant_entry *act,
2302
                                      uint16_t *status)
2303
0
{
2304
0
    if ( !(act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) )
2305
0
        gnttab_clear_flag(_GTF_writing, status);
2306
0
2307
0
    if ( !act->pin )
2308
0
        gnttab_clear_flag(_GTF_reading, status);
2309
0
}
2310
2311
/* Grab a frame number from a grant entry and update the flags and pin
2312
   count as appropriate. If rc == GNTST_okay, note that this *does*
2313
   take one ref count on the target page, stored in *page.
2314
   If there is any error, *page = NULL, no ref taken. */
2315
static int
2316
acquire_grant_for_copy(
2317
    struct domain *rd, grant_ref_t gref, domid_t ldom, bool readonly,
2318
    unsigned long *frame, struct page_info **page,
2319
    uint16_t *page_off, uint16_t *length, bool allow_transitive)
2320
0
{
2321
0
    struct grant_table *rgt = rd->grant_table;
2322
0
    grant_entry_v2_t *sha2;
2323
0
    grant_entry_header_t *shah;
2324
0
    struct active_grant_entry *act;
2325
0
    grant_status_t *status;
2326
0
    uint32_t old_pin;
2327
0
    domid_t trans_domid;
2328
0
    grant_ref_t trans_gref;
2329
0
    struct domain *td;
2330
0
    unsigned long grant_frame;
2331
0
    uint16_t trans_page_off;
2332
0
    uint16_t trans_length;
2333
0
    bool is_sub_page;
2334
0
    s16 rc = GNTST_okay;
2335
0
2336
0
    *page = NULL;
2337
0
2338
0
    grant_read_lock(rgt);
2339
0
2340
0
    if ( unlikely(gref >= nr_grant_entries(rgt)) )
2341
0
        PIN_FAIL(gt_unlock_out, GNTST_bad_gntref,
2342
0
                 "Bad grant reference %#x\n", gref);
2343
0
2344
0
    act = active_entry_acquire(rgt, gref);
2345
0
    shah = shared_entry_header(rgt, gref);
2346
0
    if ( rgt->gt_version == 1 )
2347
0
    {
2348
0
        sha2 = NULL;
2349
0
        status = &shah->flags;
2350
0
    }
2351
0
    else
2352
0
    {
2353
0
        sha2 = &shared_entry_v2(rgt, gref);
2354
0
        status = &status_entry(rgt, gref);
2355
0
    }
2356
0
2357
0
    /* If already pinned, check the active domid and avoid refcnt overflow. */
2358
0
    if ( act->pin && ((act->domid != ldom) || (act->pin & 0x80808080U) != 0) )
2359
0
        PIN_FAIL(unlock_out, GNTST_general_error,
2360
0
                 "Bad domain (%d != %d), or risk of counter overflow %08x\n",
2361
0
                 act->domid, ldom, act->pin);
2362
0
2363
0
    old_pin = act->pin;
2364
0
    if ( sha2 && (shah->flags & GTF_type_mask) == GTF_transitive )
2365
0
    {
2366
0
        if ( (!old_pin || (!readonly &&
2367
0
                           !(old_pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)))) &&
2368
0
             (rc = _set_status_v2(ldom, readonly, 0, shah, act,
2369
0
                                  status)) != GNTST_okay )
2370
0
            goto unlock_out;
2371
0
2372
0
        if ( !allow_transitive )
2373
0
            PIN_FAIL(unlock_out_clear, GNTST_general_error,
2374
0
                     "transitive grant when transitivity not allowed\n");
2375
0
2376
0
        trans_domid = sha2->transitive.trans_domid;
2377
0
        trans_gref = sha2->transitive.gref;
2378
0
        barrier(); /* Stop the compiler from re-loading
2379
0
                      trans_domid from shared memory */
2380
0
        if ( trans_domid == rd->domain_id )
2381
0
            PIN_FAIL(unlock_out_clear, GNTST_general_error,
2382
0
                     "transitive grants cannot be self-referential\n");
2383
0
2384
0
        /*
2385
0
         * We allow the trans_domid == ldom case, which corresponds to a
2386
0
         * grant being issued by one domain, sent to another one, and then
2387
0
         * transitively granted back to the original domain.  Allowing it
2388
0
         * is easy, and means that you don't need to go out of your way to
2389
0
         * avoid it in the guest.
2390
0
         */
2391
0
2392
0
        /* We need to leave the rrd locked during the grant copy. */
2393
0
        td = rcu_lock_domain_by_id(trans_domid);
2394
0
        if ( td == NULL )
2395
0
            PIN_FAIL(unlock_out_clear, GNTST_general_error,
2396
0
                     "transitive grant referenced bad domain %d\n",
2397
0
                     trans_domid);
2398
0
2399
0
        /*
2400
0
         * acquire_grant_for_copy() could take the lock on the
2401
0
         * remote table (if rd == td), so we have to drop the lock
2402
0
         * here and reacquire.
2403
0
         */
2404
0
        active_entry_release(act);
2405
0
        grant_read_unlock(rgt);
2406
0
2407
0
        rc = acquire_grant_for_copy(td, trans_gref, rd->domain_id,
2408
0
                                    readonly, &grant_frame, page,
2409
0
                                    &trans_page_off, &trans_length,
2410
0
                                    false);
2411
0
2412
0
        grant_read_lock(rgt);
2413
0
        act = active_entry_acquire(rgt, gref);
2414
0
2415
0
        if ( rc != GNTST_okay )
2416
0
        {
2417
0
            fixup_status_for_copy_pin(act, status);
2418
0
            rcu_unlock_domain(td);
2419
0
            active_entry_release(act);
2420
0
            grant_read_unlock(rgt);
2421
0
            return rc;
2422
0
        }
2423
0
2424
0
        /*
2425
0
         * We dropped the lock, so we have to check that the grant didn't
2426
0
         * change, and that nobody else tried to pin/unpin it. If anything
2427
0
         * changed, just give up and tell the caller to retry.
2428
0
         */
2429
0
        if ( rgt->gt_version != 2 ||
2430
0
             act->pin != old_pin ||
2431
0
             (old_pin && (act->domid != ldom || act->frame != grant_frame ||
2432
0
                          act->start != trans_page_off ||
2433
0
                          act->length != trans_length ||
2434
0
                          act->trans_domain != td ||
2435
0
                          act->trans_gref != trans_gref ||
2436
0
                          !act->is_sub_page)) )
2437
0
        {
2438
0
            release_grant_for_copy(td, trans_gref, readonly);
2439
0
            fixup_status_for_copy_pin(act, status);
2440
0
            rcu_unlock_domain(td);
2441
0
            active_entry_release(act);
2442
0
            grant_read_unlock(rgt);
2443
0
            put_page(*page);
2444
0
            *page = NULL;
2445
0
            return ERESTART;
2446
0
        }
2447
0
2448
0
        if ( !old_pin )
2449
0
        {
2450
0
            act->domid = ldom;
2451
0
            act->start = trans_page_off;
2452
0
            act->length = trans_length;
2453
0
            act->trans_domain = td;
2454
0
            act->trans_gref = trans_gref;
2455
0
            act->frame = grant_frame;
2456
0
            act_set_gfn(act, INVALID_GFN);
2457
0
            /*
2458
0
             * The actual remote remote grant may or may not be a sub-page,
2459
0
             * but we always treat it as one because that blocks mappings of
2460
0
             * transitive grants.
2461
0
             */
2462
0
            act->is_sub_page = true;
2463
0
        }
2464
0
    }
2465
0
    else if ( !old_pin ||
2466
0
              (!readonly && !(old_pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask))) )
2467
0
    {
2468
0
        if ( (rc = _set_status(rgt->gt_version, ldom,
2469
0
                               readonly, 0, shah, act,
2470
0
                               status) ) != GNTST_okay )
2471
0
             goto unlock_out;
2472
0
2473
0
        td = rd;
2474
0
        trans_gref = gref;
2475
0
        if ( !sha2 )
2476
0
        {
2477
0
            unsigned long gfn = shared_entry_v1(rgt, gref).frame;
2478
0
2479
0
            rc = get_paged_frame(gfn, &grant_frame, page, readonly, rd);
2480
0
            if ( rc != GNTST_okay )
2481
0
                goto unlock_out_clear;
2482
0
            act_set_gfn(act, _gfn(gfn));
2483
0
            is_sub_page = false;
2484
0
            trans_page_off = 0;
2485
0
            trans_length = PAGE_SIZE;
2486
0
        }
2487
0
        else if ( !(sha2->hdr.flags & GTF_sub_page) )
2488
0
        {
2489
0
            rc = get_paged_frame(sha2->full_page.frame, &grant_frame, page,
2490
0
                                 readonly, rd);
2491
0
            if ( rc != GNTST_okay )
2492
0
                goto unlock_out_clear;
2493
0
            act_set_gfn(act, _gfn(sha2->full_page.frame));
2494
0
            is_sub_page = false;
2495
0
            trans_page_off = 0;
2496
0
            trans_length = PAGE_SIZE;
2497
0
        }
2498
0
        else
2499
0
        {
2500
0
            rc = get_paged_frame(sha2->sub_page.frame, &grant_frame, page,
2501
0
                                 readonly, rd);
2502
0
            if ( rc != GNTST_okay )
2503
0
                goto unlock_out_clear;
2504
0
            act_set_gfn(act, _gfn(sha2->sub_page.frame));
2505
0
            is_sub_page = true;
2506
0
            trans_page_off = sha2->sub_page.page_off;
2507
0
            trans_length = sha2->sub_page.length;
2508
0
        }
2509
0
2510
0
        if ( !act->pin )
2511
0
        {
2512
0
            act->domid = ldom;
2513
0
            act->is_sub_page = is_sub_page;
2514
0
            act->start = trans_page_off;
2515
0
            act->length = trans_length;
2516
0
            act->trans_domain = td;
2517
0
            act->trans_gref = trans_gref;
2518
0
            act->frame = grant_frame;
2519
0
        }
2520
0
    }
2521
0
    else
2522
0
    {
2523
0
        ASSERT(mfn_valid(_mfn(act->frame)));
2524
0
        *page = mfn_to_page(act->frame);
2525
0
        td = page_get_owner_and_reference(*page);
2526
0
        /*
2527
0
         * act->pin being non-zero should guarantee the page to have a
2528
0
         * non-zero refcount and hence a valid owner.
2529
0
         */
2530
0
        ASSERT(td);
2531
0
    }
2532
0
2533
0
    act->pin += readonly ? GNTPIN_hstr_inc : GNTPIN_hstw_inc;
2534
0
2535
0
    *page_off = act->start;
2536
0
    *length = act->length;
2537
0
    *frame = act->frame;
2538
0
2539
0
    active_entry_release(act);
2540
0
    grant_read_unlock(rgt);
2541
0
    return rc;
2542
0
2543
0
 unlock_out_clear:
2544
0
    if ( !(readonly) &&
2545
0
         !(act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) )
2546
0
        gnttab_clear_flag(_GTF_writing, status);
2547
0
2548
0
    if ( !act->pin )
2549
0
        gnttab_clear_flag(_GTF_reading, status);
2550
0
2551
0
 unlock_out:
2552
0
    active_entry_release(act);
2553
0
2554
0
 gt_unlock_out:
2555
0
    grant_read_unlock(rgt);
2556
0
2557
0
    return rc;
2558
0
}
2559
2560
struct gnttab_copy_buf {
2561
    /* Guest provided. */
2562
    struct gnttab_copy_ptr ptr;
2563
    uint16_t len;
2564
2565
    /* Mapped etc. */
2566
    struct domain *domain;
2567
    unsigned long frame;
2568
    struct page_info *page;
2569
    void *virt;
2570
    bool_t read_only;
2571
    bool_t have_grant;
2572
    bool_t have_type;
2573
};
2574
2575
static int gnttab_copy_lock_domain(domid_t domid, bool is_gref,
2576
                                   struct gnttab_copy_buf *buf)
2577
0
{
2578
0
    /* Only DOMID_SELF may reference via frame. */
2579
0
    if ( domid != DOMID_SELF && !is_gref )
2580
0
        return GNTST_permission_denied;
2581
0
2582
0
    buf->domain = rcu_lock_domain_by_any_id(domid);
2583
0
2584
0
    if ( !buf->domain )
2585
0
        return GNTST_bad_domain;
2586
0
2587
0
    buf->ptr.domid = domid;
2588
0
2589
0
    return GNTST_okay;
2590
0
}
2591
2592
static void gnttab_copy_unlock_domains(struct gnttab_copy_buf *src,
2593
                                       struct gnttab_copy_buf *dest)
2594
0
{
2595
0
    if ( src->domain )
2596
0
    {
2597
0
        rcu_unlock_domain(src->domain);
2598
0
        src->domain = NULL;
2599
0
    }
2600
0
    if ( dest->domain )
2601
0
    {
2602
0
        rcu_unlock_domain(dest->domain);
2603
0
        dest->domain = NULL;
2604
0
    }
2605
0
}
2606
2607
static int gnttab_copy_lock_domains(const struct gnttab_copy *op,
2608
                                    struct gnttab_copy_buf *src,
2609
                                    struct gnttab_copy_buf *dest)
2610
0
{
2611
0
    int rc;
2612
0
2613
0
    rc = gnttab_copy_lock_domain(op->source.domid,
2614
0
                                 op->flags & GNTCOPY_source_gref, src);
2615
0
    if ( rc < 0 )
2616
0
        goto error;
2617
0
    rc = gnttab_copy_lock_domain(op->dest.domid,
2618
0
                                 op->flags & GNTCOPY_dest_gref, dest);
2619
0
    if ( rc < 0 )
2620
0
        goto error;
2621
0
2622
0
    rc = xsm_grant_copy(XSM_HOOK, src->domain, dest->domain);
2623
0
    if ( rc < 0 )
2624
0
    {
2625
0
        rc = GNTST_permission_denied;
2626
0
        goto error;
2627
0
    }
2628
0
    return 0;
2629
0
2630
0
 error:
2631
0
    gnttab_copy_unlock_domains(src, dest);
2632
0
    return rc;
2633
0
}
2634
2635
static void gnttab_copy_release_buf(struct gnttab_copy_buf *buf)
2636
0
{
2637
0
    if ( buf->virt )
2638
0
    {
2639
0
        unmap_domain_page(buf->virt);
2640
0
        buf->virt = NULL;
2641
0
    }
2642
0
    if ( buf->have_type )
2643
0
    {
2644
0
        put_page_type(buf->page);
2645
0
        buf->have_type = 0;
2646
0
    }
2647
0
    if ( buf->page )
2648
0
    {
2649
0
        put_page(buf->page);
2650
0
        buf->page = NULL;
2651
0
    }
2652
0
    if ( buf->have_grant )
2653
0
    {
2654
0
        release_grant_for_copy(buf->domain, buf->ptr.u.ref, buf->read_only);
2655
0
        buf->have_grant = 0;
2656
0
    }
2657
0
}
2658
2659
static int gnttab_copy_claim_buf(const struct gnttab_copy *op,
2660
                                 const struct gnttab_copy_ptr *ptr,
2661
                                 struct gnttab_copy_buf *buf,
2662
                                 unsigned int gref_flag)
2663
0
{
2664
0
    int rc;
2665
0
2666
0
    buf->read_only = gref_flag == GNTCOPY_source_gref;
2667
0
2668
0
    if ( op->flags & gref_flag )
2669
0
    {
2670
0
        rc = acquire_grant_for_copy(buf->domain, ptr->u.ref,
2671
0
                                    current->domain->domain_id,
2672
0
                                    buf->read_only,
2673
0
                                    &buf->frame, &buf->page,
2674
0
                                    &buf->ptr.offset, &buf->len, true);
2675
0
        if ( rc != GNTST_okay )
2676
0
            goto out;
2677
0
        buf->ptr.u.ref = ptr->u.ref;
2678
0
        buf->have_grant = 1;
2679
0
    }
2680
0
    else
2681
0
    {
2682
0
        rc = get_paged_frame(ptr->u.gmfn, &buf->frame, &buf->page,
2683
0
                             buf->read_only, buf->domain);
2684
0
        if ( rc != GNTST_okay )
2685
0
            PIN_FAIL(out, rc,
2686
0
                     "source frame %"PRI_xen_pfn" invalid\n", ptr->u.gmfn);
2687
0
2688
0
        buf->ptr.u.gmfn = ptr->u.gmfn;
2689
0
        buf->ptr.offset = 0;
2690
0
        buf->len = PAGE_SIZE;
2691
0
    }
2692
0
2693
0
    if ( !buf->read_only )
2694
0
    {
2695
0
        if ( !get_page_type(buf->page, PGT_writable_page) )
2696
0
        {
2697
0
            if ( !buf->domain->is_dying )
2698
0
                gdprintk(XENLOG_WARNING, "Could not get writable frame %lx\n",
2699
0
                         buf->frame);
2700
0
            rc = GNTST_general_error;
2701
0
            goto out;
2702
0
        }
2703
0
        buf->have_type = 1;
2704
0
    }
2705
0
2706
0
    buf->virt = map_domain_page(_mfn(buf->frame));
2707
0
    rc = GNTST_okay;
2708
0
2709
0
 out:
2710
0
    return rc;
2711
0
}
2712
2713
static bool_t gnttab_copy_buf_valid(const struct gnttab_copy_ptr *p,
2714
                                    const struct gnttab_copy_buf *b,
2715
                                    bool_t has_gref)
2716
0
{
2717
0
    if ( !b->virt )
2718
0
        return 0;
2719
0
    if ( has_gref )
2720
0
        return b->have_grant && p->u.ref == b->ptr.u.ref;
2721
0
    return p->u.gmfn == b->ptr.u.gmfn;
2722
0
}
2723
2724
static int gnttab_copy_buf(const struct gnttab_copy *op,
2725
                           struct gnttab_copy_buf *dest,
2726
                           const struct gnttab_copy_buf *src)
2727
0
{
2728
0
    int rc;
2729
0
2730
0
    if ( ((op->source.offset + op->len) > PAGE_SIZE) ||
2731
0
         ((op->dest.offset + op->len) > PAGE_SIZE) )
2732
0
        PIN_FAIL(out, GNTST_bad_copy_arg, "copy beyond page area\n");
2733
0
2734
0
    if ( op->source.offset < src->ptr.offset ||
2735
0
         op->source.offset + op->len > src->ptr.offset + src->len )
2736
0
        PIN_FAIL(out, GNTST_general_error,
2737
0
                 "copy source out of bounds: %d < %d || %d > %d\n",
2738
0
                 op->source.offset, src->ptr.offset,
2739
0
                 op->len, src->len);
2740
0
2741
0
    if ( op->dest.offset < dest->ptr.offset ||
2742
0
         op->dest.offset + op->len > dest->ptr.offset + dest->len )
2743
0
        PIN_FAIL(out, GNTST_general_error,
2744
0
                 "copy dest out of bounds: %d < %d || %d > %d\n",
2745
0
                 op->dest.offset, dest->ptr.offset,
2746
0
                 op->len, dest->len);
2747
0
2748
0
    memcpy(dest->virt + op->dest.offset, src->virt + op->source.offset,
2749
0
           op->len);
2750
0
    gnttab_mark_dirty(dest->domain, dest->frame);
2751
0
    rc = GNTST_okay;
2752
0
 out:
2753
0
    return rc;
2754
0
}
2755
2756
static int gnttab_copy_one(const struct gnttab_copy *op,
2757
                           struct gnttab_copy_buf *dest,
2758
                           struct gnttab_copy_buf *src)
2759
0
{
2760
0
    int rc;
2761
0
2762
0
    if ( !src->domain || op->source.domid != src->ptr.domid ||
2763
0
         !dest->domain || op->dest.domid != dest->ptr.domid )
2764
0
    {
2765
0
        gnttab_copy_release_buf(src);
2766
0
        gnttab_copy_release_buf(dest);
2767
0
        gnttab_copy_unlock_domains(src, dest);
2768
0
2769
0
        rc = gnttab_copy_lock_domains(op, src, dest);
2770
0
        if ( rc < 0 )
2771
0
            goto out;
2772
0
    }
2773
0
2774
0
    /* Different source? */
2775
0
    if ( !gnttab_copy_buf_valid(&op->source, src,
2776
0
                                op->flags & GNTCOPY_source_gref) )
2777
0
    {
2778
0
        gnttab_copy_release_buf(src);
2779
0
        rc = gnttab_copy_claim_buf(op, &op->source, src, GNTCOPY_source_gref);
2780
0
        if ( rc )
2781
0
            goto out;
2782
0
    }
2783
0
2784
0
    /* Different dest? */
2785
0
    if ( !gnttab_copy_buf_valid(&op->dest, dest,
2786
0
                                op->flags & GNTCOPY_dest_gref) )
2787
0
    {
2788
0
        gnttab_copy_release_buf(dest);
2789
0
        rc = gnttab_copy_claim_buf(op, &op->dest, dest, GNTCOPY_dest_gref);
2790
0
        if ( rc )
2791
0
            goto out;
2792
0
    }
2793
0
2794
0
    rc = gnttab_copy_buf(op, dest, src);
2795
0
 out:
2796
0
    return rc;
2797
0
}
2798
2799
/*
2800
 * gnttab_copy(), other than the various other helpers of
2801
 * do_grant_table_op(), returns (besides possible error indicators)
2802
 * "count - i" rather than "i" to ensure that even if no progress
2803
 * was made at all (perhaps due to gnttab_copy_one() returning a
2804
 * positive value) a non-zero value is being handed back (zero needs
2805
 * to be avoided, as that means "success, all done").
2806
 */
2807
static long gnttab_copy(
2808
    XEN_GUEST_HANDLE_PARAM(gnttab_copy_t) uop, unsigned int count)
2809
0
{
2810
0
    unsigned int i;
2811
0
    struct gnttab_copy op;
2812
0
    struct gnttab_copy_buf src = {};
2813
0
    struct gnttab_copy_buf dest = {};
2814
0
    long rc = 0;
2815
0
2816
0
    for ( i = 0; i < count; i++ )
2817
0
    {
2818
0
        if ( i && hypercall_preempt_check() )
2819
0
        {
2820
0
            rc = count - i;
2821
0
            break;
2822
0
        }
2823
0
2824
0
        if ( unlikely(__copy_from_guest(&op, uop, 1)) )
2825
0
        {
2826
0
            rc = -EFAULT;
2827
0
            break;
2828
0
        }
2829
0
2830
0
        rc = gnttab_copy_one(&op, &dest, &src);
2831
0
        if ( rc > 0 )
2832
0
        {
2833
0
            rc = count - i;
2834
0
            break;
2835
0
        }
2836
0
        if ( rc != GNTST_okay )
2837
0
        {
2838
0
            gnttab_copy_release_buf(&src);
2839
0
            gnttab_copy_release_buf(&dest);
2840
0
        }
2841
0
2842
0
        op.status = rc;
2843
0
        rc = 0;
2844
0
        if ( unlikely(__copy_field_to_guest(uop, &op, status)) )
2845
0
        {
2846
0
            rc = -EFAULT;
2847
0
            break;
2848
0
        }
2849
0
        guest_handle_add_offset(uop, 1);
2850
0
    }
2851
0
2852
0
    gnttab_copy_release_buf(&src);
2853
0
    gnttab_copy_release_buf(&dest);
2854
0
    gnttab_copy_unlock_domains(&src, &dest);
2855
0
2856
0
    return rc;
2857
0
}
2858
2859
static long
2860
gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set_version_t) uop)
2861
0
{
2862
0
    gnttab_set_version_t op;
2863
0
    struct domain *currd = current->domain;
2864
0
    struct grant_table *gt = currd->grant_table;
2865
0
    grant_entry_v1_t reserved_entries[GNTTAB_NR_RESERVED_ENTRIES];
2866
0
    int res;
2867
0
    unsigned int i;
2868
0
2869
0
    if ( copy_from_guest(&op, uop, 1) )
2870
0
        return -EFAULT;
2871
0
2872
0
    res = -EINVAL;
2873
0
    if ( op.version != 1 && op.version != 2 )
2874
0
        goto out;
2875
0
2876
0
    res = 0;
2877
0
    if ( gt->gt_version == op.version )
2878
0
        goto out;
2879
0
2880
0
    grant_write_lock(gt);
2881
0
    /*
2882
0
     * Make sure that the grant table isn't currently in use when we
2883
0
     * change the version number, except for the first 8 entries which
2884
0
     * are allowed to be in use (xenstore/xenconsole keeps them mapped).
2885
0
     * (You need to change the version number for e.g. kexec.)
2886
0
     */
2887
0
    for ( i = GNTTAB_NR_RESERVED_ENTRIES; i < nr_grant_entries(gt); i++ )
2888
0
    {
2889
0
        if ( read_atomic(&_active_entry(gt, i).pin) != 0 )
2890
0
        {
2891
0
            gdprintk(XENLOG_WARNING,
2892
0
                     "tried to change grant table version from %u to %u, but some grant entries still in use\n",
2893
0
                     gt->gt_version, op.version);
2894
0
            res = -EBUSY;
2895
0
            goto out_unlock;
2896
0
        }
2897
0
    }
2898
0
2899
0
    switch ( gt->gt_version )
2900
0
    {
2901
0
    case 0:
2902
0
        if ( op.version == 2 )
2903
0
        {
2904
0
    case 1:
2905
0
            /* XXX: We could maybe shrink the active grant table here. */
2906
0
            res = gnttab_populate_status_frames(currd, gt, nr_grant_frames(gt));
2907
0
            if ( res < 0)
2908
0
                goto out_unlock;
2909
0
        }
2910
0
        break;
2911
0
    case 2:
2912
0
        for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES; i++ )
2913
0
        {
2914
0
            switch ( shared_entry_v2(gt, i).hdr.flags & GTF_type_mask )
2915
0
            {
2916
0
            case GTF_permit_access:
2917
0
                 if ( !(shared_entry_v2(gt, i).full_page.frame >> 32) )
2918
0
                     break;
2919
0
                 /* fall through */
2920
0
            case GTF_transitive:
2921
0
                gdprintk(XENLOG_WARNING,
2922
0
                         "tried to change grant table version to 1 with non-representable entries\n");
2923
0
                res = -ERANGE;
2924
0
                goto out_unlock;
2925
0
            }
2926
0
        }
2927
0
        break;
2928
0
    }
2929
0
2930
0
    /* Preserve the first 8 entries (toolstack reserved grants). */
2931
0
    switch ( gt->gt_version )
2932
0
    {
2933
0
    case 1:
2934
0
        memcpy(reserved_entries, &shared_entry_v1(gt, 0),
2935
0
               sizeof(reserved_entries));
2936
0
        break;
2937
0
    case 2:
2938
0
        for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES; i++ )
2939
0
        {
2940
0
            unsigned int flags = shared_entry_v2(gt, i).hdr.flags;
2941
0
2942
0
            switch ( flags & GTF_type_mask )
2943
0
            {
2944
0
            case GTF_permit_access:
2945
0
                reserved_entries[i].flags = flags | status_entry(gt, i);
2946
0
                reserved_entries[i].domid = shared_entry_v2(gt, i).hdr.domid;
2947
0
                reserved_entries[i].frame = shared_entry_v2(gt, i).full_page.frame;
2948
0
                break;
2949
0
            default:
2950
0
                gdprintk(XENLOG_INFO,
2951
0
                         "bad flags %#x in grant %#x when switching version\n",
2952
0
                         flags, i);
2953
0
                /* fall through */
2954
0
            case GTF_invalid:
2955
0
                memset(&reserved_entries[i], 0, sizeof(reserved_entries[i]));
2956
0
                break;
2957
0
            }
2958
0
        }
2959
0
        break;
2960
0
    }
2961
0
2962
0
    if ( op.version < 2 && gt->gt_version == 2 )
2963
0
        gnttab_unpopulate_status_frames(currd, gt);
2964
0
2965
0
    /* Make sure there's no crud left over from the old version. */
2966
0
    for ( i = 0; i < nr_grant_frames(gt); i++ )
2967
0
        clear_page(gt->shared_raw[i]);
2968
0
2969
0
    /* Restore the first 8 entries (toolstack reserved grants). */
2970
0
    if ( gt->gt_version )
2971
0
    {
2972
0
        switch ( op.version )
2973
0
        {
2974
0
        case 1:
2975
0
            memcpy(&shared_entry_v1(gt, 0), reserved_entries, sizeof(reserved_entries));
2976
0
            break;
2977
0
        case 2:
2978
0
            for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES; i++ )
2979
0
            {
2980
0
                status_entry(gt, i) =
2981
0
                    reserved_entries[i].flags & (GTF_reading | GTF_writing);
2982
0
                shared_entry_v2(gt, i).hdr.flags =
2983
0
                    reserved_entries[i].flags & ~(GTF_reading | GTF_writing);
2984
0
                shared_entry_v2(gt, i).hdr.domid =
2985
0
                    reserved_entries[i].domid;
2986
0
                shared_entry_v2(gt, i).full_page.frame =
2987
0
                    reserved_entries[i].frame;
2988
0
            }
2989
0
            break;
2990
0
        }
2991
0
    }
2992
0
2993
0
    gt->gt_version = op.version;
2994
0
2995
0
 out_unlock:
2996
0
    grant_write_unlock(gt);
2997
0
2998
0
 out:
2999
0
    op.version = gt->gt_version;
3000
0
3001
0
    if ( __copy_to_guest(uop, &op, 1) )
3002
0
        res = -EFAULT;
3003
0
3004
0
    return res;
3005
0
}
3006
3007
static long
3008
gnttab_get_status_frames(XEN_GUEST_HANDLE_PARAM(gnttab_get_status_frames_t) uop,
3009
                         unsigned int count, unsigned int limit_max)
3010
0
{
3011
0
    gnttab_get_status_frames_t op;
3012
0
    struct domain *d;
3013
0
    struct grant_table *gt;
3014
0
    uint64_t       gmfn;
3015
0
    int i;
3016
0
    int rc;
3017
0
3018
0
    if ( count != 1 )
3019
0
        return -EINVAL;
3020
0
3021
0
    if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
3022
0
    {
3023
0
        gdprintk(XENLOG_INFO,
3024
0
                 "Fault while reading gnttab_get_status_frames_t\n");
3025
0
        return -EFAULT;
3026
0
    }
3027
0
3028
0
    d = rcu_lock_domain_by_any_id(op.dom);
3029
0
    if ( d == NULL )
3030
0
    {
3031
0
        op.status = GNTST_bad_domain;
3032
0
        goto out1;
3033
0
    }
3034
0
    rc = xsm_grant_setup(XSM_TARGET, current->domain, d);
3035
0
    if ( rc )
3036
0
    {
3037
0
        op.status = GNTST_permission_denied;
3038
0
        goto out2;
3039
0
    }
3040
0
3041
0
    gt = d->grant_table;
3042
0
3043
0
    op.status = GNTST_okay;
3044
0
3045
0
    grant_read_lock(gt);
3046
0
3047
0
    if ( unlikely(op.nr_frames > nr_status_frames(gt)) )
3048
0
    {
3049
0
        gdprintk(XENLOG_INFO, "Requested addresses of d%d for %u grant "
3050
0
                 "status frames, but has only %u\n",
3051
0
                 d->domain_id, op.nr_frames, nr_status_frames(gt));
3052
0
        op.status = GNTST_general_error;
3053
0
        goto unlock;
3054
0
    }
3055
0
3056
0
    if ( unlikely(limit_max < grant_to_status_frames(op.nr_frames)) )
3057
0
    {
3058
0
        gdprintk(XENLOG_WARNING,
3059
0
                 "grant_to_status_frames(%u) for d%d is too large (%u,%u)\n",
3060
0
                 op.nr_frames, d->domain_id,
3061
0
                 grant_to_status_frames(op.nr_frames), limit_max);
3062
0
        op.status = GNTST_general_error;
3063
0
        goto unlock;
3064
0
    }
3065
0
3066
0
    for ( i = 0; i < op.nr_frames; i++ )
3067
0
    {
3068
0
        gmfn = gnttab_status_gmfn(d, gt, i);
3069
0
        if ( copy_to_guest_offset(op.frame_list, i, &gmfn, 1) )
3070
0
            op.status = GNTST_bad_virt_addr;
3071
0
    }
3072
0
3073
0
 unlock:
3074
0
    grant_read_unlock(gt);
3075
0
 out2:
3076
0
    rcu_unlock_domain(d);
3077
0
 out1:
3078
0
    if ( unlikely(__copy_field_to_guest(uop, &op, status)) )
3079
0
        return -EFAULT;
3080
0
3081
0
    return 0;
3082
0
}
3083
3084
static long
3085
gnttab_get_version(XEN_GUEST_HANDLE_PARAM(gnttab_get_version_t) uop)
3086
0
{
3087
0
    gnttab_get_version_t op;
3088
0
    struct domain *d;
3089
0
    int rc;
3090
0
3091
0
    if ( copy_from_guest(&op, uop, 1) )
3092
0
        return -EFAULT;
3093
0
3094
0
    d = rcu_lock_domain_by_any_id(op.dom);
3095
0
    if ( d == NULL )
3096
0
        return -ESRCH;
3097
0
3098
0
    rc = xsm_grant_query_size(XSM_TARGET, current->domain, d);
3099
0
    if ( rc )
3100
0
    {
3101
0
        rcu_unlock_domain(d);
3102
0
        return rc;
3103
0
    }
3104
0
3105
0
    op.version = d->grant_table->gt_version;
3106
0
3107
0
    rcu_unlock_domain(d);
3108
0
3109
0
    if ( __copy_field_to_guest(uop, &op, version) )
3110
0
        return -EFAULT;
3111
0
3112
0
    return 0;
3113
0
}
3114
3115
static s16
3116
swap_grant_ref(grant_ref_t ref_a, grant_ref_t ref_b)
3117
0
{
3118
0
    struct domain *d = rcu_lock_current_domain();
3119
0
    struct grant_table *gt = d->grant_table;
3120
0
    struct active_grant_entry *act_a = NULL;
3121
0
    struct active_grant_entry *act_b = NULL;
3122
0
    s16 rc = GNTST_okay;
3123
0
3124
0
    grant_write_lock(gt);
3125
0
3126
0
    /* Bounds check on the grant refs */
3127
0
    if ( unlikely(ref_a >= nr_grant_entries(d->grant_table)))
3128
0
        PIN_FAIL(out, GNTST_bad_gntref, "Bad ref-a %#x\n", ref_a);
3129
0
    if ( unlikely(ref_b >= nr_grant_entries(d->grant_table)))
3130
0
        PIN_FAIL(out, GNTST_bad_gntref, "Bad ref-b %#x\n", ref_b);
3131
0
3132
0
    /* Swapping the same ref is a no-op. */
3133
0
    if ( ref_a == ref_b )
3134
0
        goto out;
3135
0
3136
0
    act_a = active_entry_acquire(gt, ref_a);
3137
0
    if ( act_a->pin )
3138
0
        PIN_FAIL(out, GNTST_eagain, "ref a %#x busy\n", ref_a);
3139
0
3140
0
    act_b = active_entry_acquire(gt, ref_b);
3141
0
    if ( act_b->pin )
3142
0
        PIN_FAIL(out, GNTST_eagain, "ref b %#x busy\n", ref_b);
3143
0
3144
0
    if ( gt->gt_version == 1 )
3145
0
    {
3146
0
        grant_entry_v1_t shared;
3147
0
3148
0
        shared = shared_entry_v1(gt, ref_a);
3149
0
        shared_entry_v1(gt, ref_a) = shared_entry_v1(gt, ref_b);
3150
0
        shared_entry_v1(gt, ref_b) = shared;
3151
0
    }
3152
0
    else
3153
0
    {
3154
0
        grant_entry_v2_t shared;
3155
0
        grant_status_t status;
3156
0
3157
0
        shared = shared_entry_v2(gt, ref_a);
3158
0
        status = status_entry(gt, ref_a);
3159
0
3160
0
        shared_entry_v2(gt, ref_a) = shared_entry_v2(gt, ref_b);
3161
0
        status_entry(gt, ref_a) = status_entry(gt, ref_b);
3162
0
3163
0
        shared_entry_v2(gt, ref_b) = shared;
3164
0
        status_entry(gt, ref_b) = status;
3165
0
    }
3166
0
3167
0
out:
3168
0
    if ( act_b != NULL )
3169
0
        active_entry_release(act_b);
3170
0
    if ( act_a != NULL )
3171
0
        active_entry_release(act_a);
3172
0
    grant_write_unlock(gt);
3173
0
3174
0
    rcu_unlock_domain(d);
3175
0
3176
0
    return rc;
3177
0
}
3178
3179
static long
3180
gnttab_swap_grant_ref(XEN_GUEST_HANDLE_PARAM(gnttab_swap_grant_ref_t) uop,
3181
                      unsigned int count)
3182
0
{
3183
0
    int i;
3184
0
    gnttab_swap_grant_ref_t op;
3185
0
3186
0
    for ( i = 0; i < count; i++ )
3187
0
    {
3188
0
        if ( i && hypercall_preempt_check() )
3189
0
            return i;
3190
0
        if ( unlikely(__copy_from_guest(&op, uop, 1)) )
3191
0
            return -EFAULT;
3192
0
        op.status = swap_grant_ref(op.ref_a, op.ref_b);
3193
0
        if ( unlikely(__copy_field_to_guest(uop, &op, status)) )
3194
0
            return -EFAULT;
3195
0
        guest_handle_add_offset(uop, 1);
3196
0
    }
3197
0
    return 0;
3198
0
}
3199
3200
static int cache_flush(gnttab_cache_flush_t *cflush, grant_ref_t *cur_ref)
3201
0
{
3202
0
    struct domain *d, *owner;
3203
0
    struct page_info *page;
3204
0
    unsigned long mfn;
3205
0
    void *v;
3206
0
    int ret;
3207
0
3208
0
    if ( (cflush->offset >= PAGE_SIZE) ||
3209
0
         (cflush->length > PAGE_SIZE) ||
3210
0
         (cflush->offset + cflush->length > PAGE_SIZE) )
3211
0
        return -EINVAL;
3212
0
3213
0
    if ( cflush->length == 0 || cflush->op == 0 )
3214
0
        return 0;
3215
0
3216
0
    /* currently unimplemented */
3217
0
    if ( cflush->op & GNTTAB_CACHE_SOURCE_GREF )
3218
0
        return -EOPNOTSUPP;
3219
0
3220
0
    if ( cflush->op & ~(GNTTAB_CACHE_INVAL|GNTTAB_CACHE_CLEAN) )
3221
0
        return -EINVAL;
3222
0
3223
0
    d = rcu_lock_current_domain();
3224
0
    mfn = cflush->a.dev_bus_addr >> PAGE_SHIFT;
3225
0
3226
0
    if ( !mfn_valid(_mfn(mfn)) )
3227
0
    {
3228
0
        rcu_unlock_domain(d);
3229
0
        return -EINVAL;
3230
0
    }
3231
0
3232
0
    page = mfn_to_page(mfn);
3233
0
    owner = page_get_owner_and_reference(page);
3234
0
    if ( !owner || !owner->grant_table )
3235
0
    {
3236
0
        rcu_unlock_domain(d);
3237
0
        return -EPERM;
3238
0
    }
3239
0
3240
0
    if ( d != owner )
3241
0
    {
3242
0
        grant_read_lock(owner->grant_table);
3243
0
3244
0
        ret = grant_map_exists(d, owner->grant_table, mfn, cur_ref);
3245
0
        if ( ret != 0 )
3246
0
        {
3247
0
            grant_read_unlock(owner->grant_table);
3248
0
            rcu_unlock_domain(d);
3249
0
            put_page(page);
3250
0
            return ret;
3251
0
        }
3252
0
    }
3253
0
3254
0
    v = map_domain_page(_mfn(mfn));
3255
0
    v += cflush->offset;
3256
0
3257
0
    if ( (cflush->op & GNTTAB_CACHE_INVAL) && (cflush->op & GNTTAB_CACHE_CLEAN) )
3258
0
        ret = clean_and_invalidate_dcache_va_range(v, cflush->length);
3259
0
    else if ( cflush->op & GNTTAB_CACHE_INVAL )
3260
0
        ret = invalidate_dcache_va_range(v, cflush->length);
3261
0
    else if ( cflush->op & GNTTAB_CACHE_CLEAN )
3262
0
        ret = clean_dcache_va_range(v, cflush->length);
3263
0
    else
3264
0
        ret = 0;
3265
0
3266
0
    if ( d != owner )
3267
0
        grant_read_unlock(owner->grant_table);
3268
0
    unmap_domain_page(v);
3269
0
    put_page(page);
3270
0
3271
0
    return ret;
3272
0
}
3273
3274
static long
3275
gnttab_cache_flush(XEN_GUEST_HANDLE_PARAM(gnttab_cache_flush_t) uop,
3276
                      grant_ref_t *cur_ref,
3277
                      unsigned int count)
3278
0
{
3279
0
    unsigned int i;
3280
0
    gnttab_cache_flush_t op;
3281
0
3282
0
    for ( i = 0; i < count; i++ )
3283
0
    {
3284
0
        if ( i && hypercall_preempt_check() )
3285
0
            return i;
3286
0
        if ( unlikely(__copy_from_guest(&op, uop, 1)) )
3287
0
            return -EFAULT;
3288
0
        for ( ; ; )
3289
0
        {
3290
0
            int ret = cache_flush(&op, cur_ref);
3291
0
3292
0
            if ( ret < 0 )
3293
0
                return ret;
3294
0
            if ( ret == 0 )
3295
0
                break;
3296
0
            if ( hypercall_preempt_check() )
3297
0
                return i;
3298
0
        }
3299
0
        *cur_ref = 0;
3300
0
        guest_handle_add_offset(uop, 1);
3301
0
    }
3302
0
    return 0;
3303
0
}
3304
3305
long
3306
do_grant_table_op(
3307
    unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) uop, unsigned int count)
3308
3
{
3309
3
    long rc;
3310
3
    unsigned int opaque_in = cmd & GNTTABOP_ARG_MASK, opaque_out = 0;
3311
3
3312
3
    if ( (int)count < 0 )
3313
0
        return -EINVAL;
3314
3
3315
3
    if ( (cmd &= GNTTABOP_CMD_MASK) != GNTTABOP_cache_flush && opaque_in )
3316
0
        return -EINVAL;
3317
3
3318
3
    rc = -EFAULT;
3319
3
    switch ( cmd )
3320
3
    {
3321
0
    case GNTTABOP_map_grant_ref:
3322
0
    {
3323
0
        XEN_GUEST_HANDLE_PARAM(gnttab_map_grant_ref_t) map =
3324
0
            guest_handle_cast(uop, gnttab_map_grant_ref_t);
3325
0
3326
0
        if ( unlikely(!guest_handle_okay(map, count)) )
3327
0
            goto out;
3328
0
        rc = gnttab_map_grant_ref(map, count);
3329
0
        if ( rc > 0 )
3330
0
        {
3331
0
            guest_handle_add_offset(map, rc);
3332
0
            uop = guest_handle_cast(map, void);
3333
0
        }
3334
0
        break;
3335
0
    }
3336
0
3337
0
    case GNTTABOP_unmap_grant_ref:
3338
0
    {
3339
0
        XEN_GUEST_HANDLE_PARAM(gnttab_unmap_grant_ref_t) unmap =
3340
0
            guest_handle_cast(uop, gnttab_unmap_grant_ref_t);
3341
0
3342
0
        if ( unlikely(!guest_handle_okay(unmap, count)) )
3343
0
            goto out;
3344
0
        rc = gnttab_unmap_grant_ref(unmap, count);
3345
0
        if ( rc > 0 )
3346
0
        {
3347
0
            guest_handle_add_offset(unmap, rc);
3348
0
            uop = guest_handle_cast(unmap, void);
3349
0
        }
3350
0
        break;
3351
0
    }
3352
0
3353
0
    case GNTTABOP_unmap_and_replace:
3354
0
    {
3355
0
        XEN_GUEST_HANDLE_PARAM(gnttab_unmap_and_replace_t) unmap =
3356
0
            guest_handle_cast(uop, gnttab_unmap_and_replace_t);
3357
0
3358
0
        if ( unlikely(!guest_handle_okay(unmap, count)) )
3359
0
            goto out;
3360
0
        rc = -ENOSYS;
3361
0
        if ( unlikely(!replace_grant_supported()) )
3362
0
            goto out;
3363
0
        rc = gnttab_unmap_and_replace(unmap, count);
3364
0
        if ( rc > 0 )
3365
0
        {
3366
0
            guest_handle_add_offset(unmap, rc);
3367
0
            uop = guest_handle_cast(unmap, void);
3368
0
        }
3369
0
        break;
3370
0
    }
3371
0
3372
0
    case GNTTABOP_setup_table:
3373
0
        rc = gnttab_setup_table(
3374
0
            guest_handle_cast(uop, gnttab_setup_table_t), count, UINT_MAX);
3375
0
        ASSERT(rc <= 0);
3376
0
        break;
3377
0
3378
0
    case GNTTABOP_transfer:
3379
0
    {
3380
0
        XEN_GUEST_HANDLE_PARAM(gnttab_transfer_t) transfer =
3381
0
            guest_handle_cast(uop, gnttab_transfer_t);
3382
0
3383
0
        if ( unlikely(!guest_handle_okay(transfer, count)) )
3384
0
            goto out;
3385
0
        rc = gnttab_transfer(transfer, count);
3386
0
        if ( rc > 0 )
3387
0
        {
3388
0
            guest_handle_add_offset(transfer, rc);
3389
0
            uop = guest_handle_cast(transfer, void);
3390
0
        }
3391
0
        break;
3392
0
    }
3393
0
3394
0
    case GNTTABOP_copy:
3395
0
    {
3396
0
        XEN_GUEST_HANDLE_PARAM(gnttab_copy_t) copy =
3397
0
            guest_handle_cast(uop, gnttab_copy_t);
3398
0
3399
0
        if ( unlikely(!guest_handle_okay(copy, count)) )
3400
0
            goto out;
3401
0
        rc = gnttab_copy(copy, count);
3402
0
        if ( rc > 0 )
3403
0
        {
3404
0
            rc = count - rc;
3405
0
            guest_handle_add_offset(copy, rc);
3406
0
            uop = guest_handle_cast(copy, void);
3407
0
        }
3408
0
        break;
3409
0
    }
3410
0
3411
3
    case GNTTABOP_query_size:
3412
3
        rc = gnttab_query_size(
3413
3
            guest_handle_cast(uop, gnttab_query_size_t), count);
3414
3
        ASSERT(rc <= 0);
3415
3
        break;
3416
0
3417
0
    case GNTTABOP_set_version:
3418
0
        rc = gnttab_set_version(guest_handle_cast(uop, gnttab_set_version_t));
3419
0
        break;
3420
0
3421
0
    case GNTTABOP_get_status_frames:
3422
0
        rc = gnttab_get_status_frames(
3423
0
            guest_handle_cast(uop, gnttab_get_status_frames_t), count,
3424
0
                              UINT_MAX);
3425
0
        break;
3426
0
3427
0
    case GNTTABOP_get_version:
3428
0
        rc = gnttab_get_version(guest_handle_cast(uop, gnttab_get_version_t));
3429
0
        break;
3430
0
3431
0
    case GNTTABOP_swap_grant_ref:
3432
0
    {
3433
0
        XEN_GUEST_HANDLE_PARAM(gnttab_swap_grant_ref_t) swap =
3434
0
            guest_handle_cast(uop, gnttab_swap_grant_ref_t);
3435
0
3436
0
        if ( unlikely(!guest_handle_okay(swap, count)) )
3437
0
            goto out;
3438
0
        rc = gnttab_swap_grant_ref(swap, count);
3439
0
        if ( rc > 0 )
3440
0
        {
3441
0
            guest_handle_add_offset(swap, rc);
3442
0
            uop = guest_handle_cast(swap, void);
3443
0
        }
3444
0
        break;
3445
0
    }
3446
0
3447
0
    case GNTTABOP_cache_flush:
3448
0
    {
3449
0
        XEN_GUEST_HANDLE_PARAM(gnttab_cache_flush_t) cflush =
3450
0
            guest_handle_cast(uop, gnttab_cache_flush_t);
3451
0
3452
0
        if ( unlikely(!guest_handle_okay(cflush, count)) )
3453
0
            goto out;
3454
0
        rc = gnttab_cache_flush(cflush, &opaque_in, count);
3455
0
        if ( rc > 0 )
3456
0
        {
3457
0
            guest_handle_add_offset(cflush, rc);
3458
0
            uop = guest_handle_cast(cflush, void);
3459
0
        }
3460
0
        opaque_out = opaque_in;
3461
0
        break;
3462
0
    }
3463
0
3464
0
    default:
3465
0
        rc = -ENOSYS;
3466
0
        break;
3467
3
    }
3468
3
3469
3
  out:
3470
3
    if ( rc > 0 || opaque_out != 0 )
3471
0
    {
3472
0
        ASSERT(rc < count);
3473
0
        ASSERT((opaque_out & GNTTABOP_CMD_MASK) == 0);
3474
0
        rc = hypercall_create_continuation(__HYPERVISOR_grant_table_op, "ihi",
3475
0
                                           opaque_out | cmd, uop, count - rc);
3476
0
    }
3477
3
3478
3
    return rc;
3479
3
}
3480
3481
#ifdef CONFIG_COMPAT
3482
#include "compat/grant_table.c"
3483
#endif
3484
3485
int
3486
grant_table_create(
3487
    struct domain *d)
3488
1
{
3489
1
    struct grant_table *t;
3490
1
    int ret = 0;
3491
1
3492
1
    if ( (t = xzalloc(struct grant_table)) == NULL )
3493
0
        return -ENOMEM;
3494
1
3495
1
    /* Simple stuff. */
3496
1
    percpu_rwlock_resource_init(&t->lock, grant_rwlock);
3497
1
    spin_lock_init(&t->maptrack_lock);
3498
1
3499
1
    /* Okay, install the structure. */
3500
1
    t->domain = d;
3501
1
    d->grant_table = t;
3502
1
3503
1
    if ( d->domain_id == 0 )
3504
1
    {
3505
1
        ret = grant_table_init(d, t, gnttab_dom0_frames(), max_maptrack_frames);
3506
1
    }
3507
1
3508
1
    return ret;
3509
1
}
3510
3511
void
3512
gnttab_release_mappings(
3513
    struct domain *d)
3514
0
{
3515
0
    struct grant_table   *gt = d->grant_table, *rgt;
3516
0
    struct grant_mapping *map;
3517
0
    grant_ref_t           ref;
3518
0
    grant_handle_t        handle;
3519
0
    struct domain        *rd;
3520
0
    struct active_grant_entry *act;
3521
0
    grant_entry_header_t *sha;
3522
0
    uint16_t             *status;
3523
0
    struct page_info     *pg;
3524
0
3525
0
    BUG_ON(!d->is_dying);
3526
0
3527
0
    for ( handle = 0; handle < gt->maptrack_limit; handle++ )
3528
0
    {
3529
0
        map = &maptrack_entry(gt, handle);
3530
0
        if ( !(map->flags & (GNTMAP_device_map|GNTMAP_host_map)) )
3531
0
            continue;
3532
0
3533
0
        ref = map->ref;
3534
0
3535
0
        gdprintk(XENLOG_INFO, "Grant release %#x ref %#x flags %#x d%d\n",
3536
0
                 handle, ref, map->flags, map->domid);
3537
0
3538
0
        rd = rcu_lock_domain_by_id(map->domid);
3539
0
        if ( rd == NULL )
3540
0
        {
3541
0
            /* Nothing to clear up... */
3542
0
            map->flags = 0;
3543
0
            continue;
3544
0
        }
3545
0
3546
0
        rgt = rd->grant_table;
3547
0
        grant_read_lock(rgt);
3548
0
3549
0
        act = active_entry_acquire(rgt, ref);
3550
0
        sha = shared_entry_header(rgt, ref);
3551
0
        if ( rgt->gt_version == 1 )
3552
0
            status = &sha->flags;
3553
0
        else
3554
0
            status = &status_entry(rgt, ref);
3555
0
3556
0
        pg = mfn_to_page(act->frame);
3557
0
3558
0
        if ( map->flags & GNTMAP_readonly )
3559
0
        {
3560
0
            if ( map->flags & GNTMAP_device_map )
3561
0
            {
3562
0
                BUG_ON(!(act->pin & GNTPIN_devr_mask));
3563
0
                act->pin -= GNTPIN_devr_inc;
3564
0
                if ( !is_iomem_page(_mfn(act->frame)) )
3565
0
                    put_page(pg);
3566
0
            }
3567
0
3568
0
            if ( map->flags & GNTMAP_host_map )
3569
0
            {
3570
0
                BUG_ON(!(act->pin & GNTPIN_hstr_mask));
3571
0
                act->pin -= GNTPIN_hstr_inc;
3572
0
                if ( gnttab_release_host_mappings(d) &&
3573
0
                     !is_iomem_page(_mfn(act->frame)) )
3574
0
                    put_page(pg);
3575
0
            }
3576
0
        }
3577
0
        else
3578
0
        {
3579
0
            if ( map->flags & GNTMAP_device_map )
3580
0
            {
3581
0
                BUG_ON(!(act->pin & GNTPIN_devw_mask));
3582
0
                act->pin -= GNTPIN_devw_inc;
3583
0
                if ( !is_iomem_page(_mfn(act->frame)) )
3584
0
                    put_page_and_type(pg);
3585
0
            }
3586
0
3587
0
            if ( map->flags & GNTMAP_host_map )
3588
0
            {
3589
0
                BUG_ON(!(act->pin & GNTPIN_hstw_mask));
3590
0
                act->pin -= GNTPIN_hstw_inc;
3591
0
                if ( gnttab_release_host_mappings(d) &&
3592
0
                     !is_iomem_page(_mfn(act->frame)) )
3593
0
                {
3594
0
                    if ( gnttab_host_mapping_get_page_type((map->flags &
3595
0
                                                            GNTMAP_readonly),
3596
0
                                                           d, rd) )
3597
0
                        put_page_type(pg);
3598
0
                    put_page(pg);
3599
0
                }
3600
0
            }
3601
0
3602
0
            if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
3603
0
                gnttab_clear_flag(_GTF_writing, status);
3604
0
        }
3605
0
3606
0
        if ( act->pin == 0 )
3607
0
            gnttab_clear_flag(_GTF_reading, status);
3608
0
3609
0
        active_entry_release(act);
3610
0
        grant_read_unlock(rgt);
3611
0
3612
0
        rcu_unlock_domain(rd);
3613
0
3614
0
        map->flags = 0;
3615
0
    }
3616
0
}
3617
3618
void grant_table_warn_active_grants(struct domain *d)
3619
0
{
3620
0
    struct grant_table *gt = d->grant_table;
3621
0
    struct active_grant_entry *act;
3622
0
    grant_ref_t ref;
3623
0
    unsigned int nr_active = 0;
3624
0
3625
0
#define WARN_GRANT_MAX 10
3626
0
3627
0
    grant_read_lock(gt);
3628
0
3629
0
    for ( ref = 0; ref != nr_grant_entries(gt); ref++ )
3630
0
    {
3631
0
        act = active_entry_acquire(gt, ref);
3632
0
        if ( !act->pin )
3633
0
        {
3634
0
            active_entry_release(act);
3635
0
            continue;
3636
0
        }
3637
0
3638
0
        nr_active++;
3639
0
        if ( nr_active <= WARN_GRANT_MAX )
3640
0
            printk(XENLOG_G_DEBUG "d%d has active grant %x ("
3641
0
#ifndef NDEBUG
3642
0
                   "GFN %lx, "
3643
0
#endif
3644
0
                   "MFN: %lx)\n",
3645
0
                   d->domain_id, ref,
3646
0
#ifndef NDEBUG
3647
0
                   gfn_x(act->gfn),
3648
0
#endif
3649
0
                   act->frame);
3650
0
        active_entry_release(act);
3651
0
    }
3652
0
3653
0
    if ( nr_active > WARN_GRANT_MAX )
3654
0
        printk(XENLOG_G_DEBUG "d%d has too many (%d) active grants to report\n",
3655
0
               d->domain_id, nr_active);
3656
0
3657
0
    grant_read_unlock(gt);
3658
0
3659
0
#undef WARN_GRANT_MAX
3660
0
}
3661
3662
void
3663
grant_table_destroy(
3664
    struct domain *d)
3665
0
{
3666
0
    struct grant_table *t = d->grant_table;
3667
0
    int i;
3668
0
3669
0
    if ( t == NULL )
3670
0
        return;
3671
0
3672
0
    gnttab_destroy_arch(t);
3673
0
3674
0
    for ( i = 0; i < nr_grant_frames(t); i++ )
3675
0
        free_xenheap_page(t->shared_raw[i]);
3676
0
    xfree(t->shared_raw);
3677
0
3678
0
    for ( i = 0; i < nr_maptrack_frames(t); i++ )
3679
0
        free_xenheap_page(t->maptrack[i]);
3680
0
    vfree(t->maptrack);
3681
0
3682
0
    for ( i = 0; i < nr_active_grant_frames(t); i++ )
3683
0
        free_xenheap_page(t->active[i]);
3684
0
    xfree(t->active);
3685
0
3686
0
    for ( i = 0; i < nr_status_frames(t); i++ )
3687
0
        free_xenheap_page(t->status[i]);
3688
0
    xfree(t->status);
3689
0
3690
0
    xfree(t);
3691
0
    d->grant_table = NULL;
3692
0
}
3693
3694
void grant_table_init_vcpu(struct vcpu *v)
3695
24
{
3696
24
    spin_lock_init(&v->maptrack_freelist_lock);
3697
24
    v->maptrack_head = MAPTRACK_TAIL;
3698
24
    v->maptrack_tail = MAPTRACK_TAIL;
3699
24
}
3700
3701
int grant_table_set_limits(struct domain *d, unsigned int grant_frames,
3702
                           unsigned int maptrack_frames)
3703
0
{
3704
0
    struct grant_table *gt = d->grant_table;
3705
0
3706
0
    if ( grant_frames < INITIAL_NR_GRANT_FRAMES ||
3707
0
         grant_frames > max_grant_frames ||
3708
0
         maptrack_frames > max_maptrack_frames )
3709
0
        return -EINVAL;
3710
0
    if ( !gt )
3711
0
        return -ENOENT;
3712
0
3713
0
    /* Set limits. */
3714
0
    return grant_table_init(d, gt, grant_frames, maptrack_frames);
3715
0
}
3716
3717
#ifdef CONFIG_HAS_MEM_SHARING
3718
int mem_sharing_gref_to_gfn(struct grant_table *gt, grant_ref_t ref,
3719
                            gfn_t *gfn, uint16_t *status)
3720
0
{
3721
0
    int rc = 0;
3722
0
    uint16_t flags = 0;
3723
0
3724
0
    grant_read_lock(gt);
3725
0
3726
0
    if ( gt->gt_version < 1 )
3727
0
        rc = -EINVAL;
3728
0
    else if ( ref >= nr_grant_entries(gt) )
3729
0
        rc = -ENOENT;
3730
0
    else if ( gt->gt_version == 1 )
3731
0
    {
3732
0
        const grant_entry_v1_t *sha1 = &shared_entry_v1(gt, ref);
3733
0
3734
0
        flags = sha1->flags;
3735
0
        *gfn = _gfn(sha1->frame);
3736
0
    }
3737
0
    else
3738
0
    {
3739
0
        const grant_entry_v2_t *sha2 = &shared_entry_v2(gt, ref);
3740
0
3741
0
        flags = sha2->hdr.flags;
3742
0
        if ( flags & GTF_sub_page )
3743
0
           *gfn = _gfn(sha2->sub_page.frame);
3744
0
        else
3745
0
           *gfn = _gfn(sha2->full_page.frame);
3746
0
    }
3747
0
3748
0
    if ( !rc && (flags & GTF_type_mask) != GTF_permit_access )
3749
0
        rc = -ENXIO;
3750
0
    else if ( !rc && status )
3751
0
    {
3752
0
        if ( gt->gt_version == 1 )
3753
0
            *status = flags;
3754
0
        else
3755
0
            *status = status_entry(gt, ref);
3756
0
    }
3757
0
3758
0
    grant_read_unlock(gt);
3759
0
3760
0
    return rc;
3761
0
}
3762
#endif
3763
3764
int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn,
3765
                     mfn_t *mfn)
3766
1
{
3767
1
    int rc = 0;
3768
1
    struct grant_table *gt = d->grant_table;
3769
1
3770
1
    grant_write_lock(gt);
3771
1
3772
1
    if ( gt->gt_version == 0 )
3773
1
        gt->gt_version = 1;
3774
1
3775
1
    if ( gt->gt_version == 2 &&
3776
0
         (idx & XENMAPIDX_grant_table_status) )
3777
0
    {
3778
0
        idx &= ~XENMAPIDX_grant_table_status;
3779
0
        if ( idx < nr_status_frames(gt) )
3780
0
            *mfn = _mfn(virt_to_mfn(gt->status[idx]));
3781
0
        else
3782
0
            rc = -EINVAL;
3783
0
    }
3784
1
    else
3785
1
    {
3786
1
        if ( (idx >= nr_grant_frames(gt)) && (idx < gt->max_grant_frames) )
3787
0
            gnttab_grow_table(d, idx + 1);
3788
1
3789
1
        if ( idx < nr_grant_frames(gt) )
3790
1
            *mfn = _mfn(virt_to_mfn(gt->shared_raw[idx]));
3791
1
        else
3792
0
            rc = -EINVAL;
3793
1
    }
3794
1
3795
1
    if ( !rc )
3796
1
        gnttab_set_frame_gfn(gt, idx, gfn);
3797
1
3798
1
    grant_write_unlock(gt);
3799
1
3800
1
    return rc;
3801
1
}
3802
3803
static void gnttab_usage_print(struct domain *rd)
3804
0
{
3805
0
    int first = 1;
3806
0
    grant_ref_t ref;
3807
0
    struct grant_table *gt = rd->grant_table;
3808
0
3809
0
    printk("      -------- active --------       -------- shared --------\n");
3810
0
    printk("[ref] localdom mfn      pin          localdom gmfn     flags\n");
3811
0
3812
0
    grant_read_lock(gt);
3813
0
3814
0
    printk("grant-table for remote d%d (v%u)\n"
3815
0
           "  %u frames (%u max), %u maptrack frames (%u max)\n",
3816
0
           rd->domain_id, gt->gt_version,
3817
0
           nr_grant_frames(gt), gt->max_grant_frames,
3818
0
           nr_maptrack_frames(gt), gt->max_maptrack_frames);
3819
0
3820
0
    for ( ref = 0; ref != nr_grant_entries(gt); ref++ )
3821
0
    {
3822
0
        struct active_grant_entry *act;
3823
0
        struct grant_entry_header *sha;
3824
0
        uint16_t status;
3825
0
        uint64_t frame;
3826
0
3827
0
        act = active_entry_acquire(gt, ref);
3828
0
        if ( !act->pin )
3829
0
        {
3830
0
            active_entry_release(act);
3831
0
            continue;
3832
0
        }
3833
0
3834
0
        sha = shared_entry_header(gt, ref);
3835
0
3836
0
        if ( gt->gt_version == 1 )
3837
0
        {
3838
0
            status = sha->flags;
3839
0
            frame = shared_entry_v1(gt, ref).frame;
3840
0
        }
3841
0
        else
3842
0
        {
3843
0
            frame = shared_entry_v2(gt, ref).full_page.frame;
3844
0
            status = status_entry(gt, ref);
3845
0
        }
3846
0
3847
0
        first = 0;
3848
0
3849
0
        /*      [0xXXX]  ddddd 0xXXXXXX 0xXXXXXXXX      ddddd 0xXXXXXX 0xXX */
3850
0
        printk("[0x%03x]  %5d 0x%06lx 0x%08x      %5d 0x%06"PRIx64" 0x%02x\n",
3851
0
               ref, act->domid, act->frame, act->pin,
3852
0
               sha->domid, frame, status);
3853
0
        active_entry_release(act);
3854
0
    }
3855
0
3856
0
    grant_read_unlock(gt);
3857
0
3858
0
    if ( first )
3859
0
        printk("no active grant table entries\n");
3860
0
}
3861
3862
static void gnttab_usage_print_all(unsigned char key)
3863
0
{
3864
0
    struct domain *d;
3865
0
    printk("%s [ key '%c' pressed\n", __func__, key);
3866
0
    for_each_domain ( d )
3867
0
        gnttab_usage_print(d);
3868
0
    printk("%s ] done\n", __func__);
3869
0
}
3870
3871
static int __init gnttab_usage_init(void)
3872
1
{
3873
1
    register_keyhandler('g', gnttab_usage_print_all,
3874
1
                        "print grant table usage", 1);
3875
1
    return 0;
3876
1
}
3877
__initcall(gnttab_usage_init);
3878
3879
unsigned int __init gnttab_dom0_frames(void)
3880
1
{
3881
1
    return min(max_grant_frames, gnttab_dom0_max());
3882
1
}
3883
3884
/*
3885
 * Local variables:
3886
 * mode: C
3887
 * c-file-style: "BSD"
3888
 * c-basic-offset: 4
3889
 * tab-width: 4
3890
 * indent-tabs-mode: nil
3891
 * End:
3892
 */