xen_shm_machdep.c revision 1.15 1 1.15 jdolecek /* $NetBSD: xen_shm_machdep.c,v 1.15 2020/04/19 18:47:40 jdolecek Exp $ */
2 1.2 bouyer
3 1.2 bouyer /*
4 1.2 bouyer * Copyright (c) 2006 Manuel Bouyer.
5 1.2 bouyer *
6 1.2 bouyer * Redistribution and use in source and binary forms, with or without
7 1.2 bouyer * modification, are permitted provided that the following conditions
8 1.2 bouyer * are met:
9 1.2 bouyer * 1. Redistributions of source code must retain the above copyright
10 1.2 bouyer * notice, this list of conditions and the following disclaimer.
11 1.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright
12 1.2 bouyer * notice, this list of conditions and the following disclaimer in the
13 1.2 bouyer * documentation and/or other materials provided with the distribution.
14 1.2 bouyer *
15 1.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 1.2 bouyer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 1.2 bouyer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 1.2 bouyer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 1.2 bouyer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 1.2 bouyer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 1.2 bouyer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 1.2 bouyer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 1.2 bouyer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 1.2 bouyer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 1.2 bouyer */
26 1.2 bouyer
27 1.3 bouyer #include <sys/cdefs.h>
28 1.15 jdolecek __KERNEL_RCSID(0, "$NetBSD: xen_shm_machdep.c,v 1.15 2020/04/19 18:47:40 jdolecek Exp $");
29 1.3 bouyer
30 1.2 bouyer #include <sys/types.h>
31 1.2 bouyer #include <sys/param.h>
32 1.2 bouyer #include <sys/systm.h>
33 1.2 bouyer #include <sys/queue.h>
34 1.2 bouyer #include <sys/vmem.h>
35 1.2 bouyer #include <sys/kernel.h>
36 1.2 bouyer #include <uvm/uvm.h>
37 1.2 bouyer
38 1.2 bouyer #include <machine/pmap.h>
39 1.2 bouyer #include <xen/hypervisor.h>
40 1.2 bouyer #include <xen/xen.h>
41 1.2 bouyer #include <xen/evtchn.h>
42 1.2 bouyer #include <xen/xen_shm.h>
43 1.2 bouyer
44 1.2 bouyer /*
45 1.12 maxv * Helper routines for the backend drivers. This implements the necessary
46 1.12 maxv * functions to map a bunch of pages from foreign domains into our kernel VM
47 1.2 bouyer * space, do I/O to it, and unmap it.
48 1.2 bouyer *
49 1.9 jym * At boot time, we grab some kernel VM space that we'll use to map the foreign
50 1.12 maxv * pages. We also maintain a virtual-to-machine mapping table to give back
51 1.2 bouyer * the appropriate address to bus_dma if requested.
52 1.12 maxv *
53 1.2 bouyer * If no more VM space is available, we return an error. The caller can then
54 1.2 bouyer * register a callback which will be called when the required VM space is
55 1.2 bouyer * available.
56 1.2 bouyer */
57 1.2 bouyer
58 1.2 bouyer int
59 1.15 jdolecek xen_shm_map(int nentries, int domid, grant_ref_t *grefp, vaddr_t va,
60 1.2 bouyer grant_handle_t *handlep, int flags)
61 1.2 bouyer {
62 1.12 maxv gnttab_map_grant_ref_t op[XENSHM_MAX_PAGES_PER_REQUEST];
63 1.15 jdolecek int ret, i;
64 1.2 bouyer
65 1.2 bouyer #ifdef DIAGNOSTIC
66 1.2 bouyer if (nentries > XENSHM_MAX_PAGES_PER_REQUEST) {
67 1.12 maxv panic("xen_shm_map: %d entries", nentries);
68 1.2 bouyer }
69 1.2 bouyer #endif
70 1.12 maxv
71 1.2 bouyer for (i = 0; i < nentries; i++) {
72 1.15 jdolecek op[i].host_addr = va + i * PAGE_SIZE;
73 1.2 bouyer op[i].dom = domid;
74 1.2 bouyer op[i].ref = grefp[i];
75 1.2 bouyer op[i].flags = GNTMAP_host_map |
76 1.2 bouyer ((flags & XSHM_RO) ? GNTMAP_readonly : 0);
77 1.2 bouyer }
78 1.12 maxv
79 1.12 maxv ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, op, nentries);
80 1.12 maxv if (__predict_false(ret)) {
81 1.15 jdolecek printf("%s: HYPERVISOR_grant_table_op failed\n", __func__);
82 1.15 jdolecek return EINVAL;
83 1.12 maxv }
84 1.12 maxv
85 1.2 bouyer for (i = 0; i < nentries; i++) {
86 1.15 jdolecek #ifdef DIAGNOSTIC
87 1.2 bouyer if (__predict_false(op[i].status))
88 1.15 jdolecek panic("%s: op[%d] status %d", __func__, i,
89 1.15 jdolecek op[i].status);
90 1.15 jdolecek #endif
91 1.2 bouyer handlep[i] = op[i].handle;
92 1.2 bouyer }
93 1.12 maxv
94 1.2 bouyer return 0;
95 1.2 bouyer }
96 1.2 bouyer
97 1.2 bouyer void
98 1.2 bouyer xen_shm_unmap(vaddr_t va, int nentries, grant_handle_t *handlep)
99 1.2 bouyer {
100 1.2 bouyer gnttab_unmap_grant_ref_t op[XENSHM_MAX_PAGES_PER_REQUEST];
101 1.15 jdolecek int ret, i;
102 1.2 bouyer
103 1.2 bouyer #ifdef DIAGNOSTIC
104 1.2 bouyer if (nentries > XENSHM_MAX_PAGES_PER_REQUEST) {
105 1.12 maxv panic("xen_shm_unmap: %d entries", nentries);
106 1.2 bouyer }
107 1.2 bouyer #endif
108 1.2 bouyer
109 1.2 bouyer for (i = 0; i < nentries; i++) {
110 1.2 bouyer op[i].host_addr = va + i * PAGE_SIZE;
111 1.2 bouyer op[i].dev_bus_addr = 0;
112 1.2 bouyer op[i].handle = handlep[i];
113 1.2 bouyer }
114 1.12 maxv
115 1.2 bouyer ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
116 1.2 bouyer op, nentries);
117 1.12 maxv if (__predict_false(ret)) {
118 1.2 bouyer panic("xen_shm_unmap: unmap failed");
119 1.12 maxv }
120 1.2 bouyer }
121