iPXE
xengrant.h
Go to the documentation of this file.
1#ifndef _IPXE_XENGRANT_H
2#define _IPXE_XENGRANT_H
3
4/** @file
5 *
6 * Xen grant tables
7 *
8 */
9
10FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11FILE_SECBOOT ( PERMITTED );
12
13#include <stdint.h>
14#include <stdlib.h>
15#include <ipxe/io.h>
16#include <ipxe/xen.h>
17#include <xen/grant_table.h>
18
19/** Induced failure rate (for testing) */
20#define XENGRANT_FAIL_RATE 0
21
22/**
23 * Query grant table size
24 *
25 * @v xen Xen hypervisor
26 * @v size Table size
27 * @ret xenrc Xen status code
28 */
29static inline __attribute__ (( always_inline )) int
30xengrant_query_size ( struct xen_hypervisor *xen,
32
33 return xen_hypercall_3 ( xen, __HYPERVISOR_grant_table_op,
35 virt_to_phys ( size ), 1 );
36}
37
38/**
39 * Set grant table version
40 *
41 * @v xen Xen hypervisor
42 * @v version Version
43 * @ret xenrc Xen status code
44 */
45static inline __attribute__ (( always_inline )) int
46xengrant_set_version ( struct xen_hypervisor *xen,
47 struct gnttab_set_version *version ) {
48
49 return xen_hypercall_3 ( xen, __HYPERVISOR_grant_table_op,
50 GNTTABOP_set_version,
51 virt_to_phys ( version ), 1 );
52}
53
54/**
55 * Get grant table version
56 *
57 * @v xen Xen hypervisor
58 * @v version Version
59 * @ret xenrc Xen status code
60 */
61static inline __attribute__ (( always_inline )) int
62xengrant_get_version ( struct xen_hypervisor *xen,
63 struct gnttab_get_version *version ) {
64
65 return xen_hypercall_3 ( xen, __HYPERVISOR_grant_table_op,
66 GNTTABOP_get_version,
67 virt_to_phys ( version ), 1 );
68}
69
70/**
71 * Get number of grant table entries
72 *
73 * @v xen Xen hypervisor
74 * @ret entries Number of grant table entries
75 */
76static inline __attribute__ (( always_inline )) unsigned int
77xengrant_entries ( struct xen_hypervisor *xen ) {
78
79 return ( ( xen->grant.len / sizeof ( xen->grant.table[0] ) )
80 >> xen->grant.shift );
81}
82
83/**
84 * Get grant table entry header
85 *
86 * @v xen Xen hypervisor
87 * @v ref Grant reference
88 * @ret hdr Grant table entry header
89 */
90static inline __attribute__ (( always_inline )) struct grant_entry_header *
91xengrant_header ( struct xen_hypervisor *xen, grant_ref_t ref ) {
92 struct grant_entry_v1 *v1;
93
94 v1 = &xen->grant.table[ ref << xen->grant.shift ];
95 return ( container_of ( &v1->flags, struct grant_entry_header, flags ));
96}
97
98/**
99 * Get version 1 grant table entry
100 *
101 * @v hdr Grant table entry header
102 * @ret v1 Version 1 grant table entry
103 */
104static inline __attribute__ (( always_inline )) struct grant_entry_v1 *
105xengrant_v1 ( struct grant_entry_header *hdr ) {
106
107 return ( container_of ( &hdr->flags, struct grant_entry_v1, flags ) );
108}
109
110/**
111 * Get version 2 grant table entry
112 *
113 * @v hdr Grant table entry header
114 * @ret v2 Version 2 grant table entry
115 */
116static inline __attribute__ (( always_inline )) union grant_entry_v2 *
117xengrant_v2 ( struct grant_entry_header *hdr ) {
118
119 return ( container_of ( &hdr->flags, union grant_entry_v2, hdr.flags ));
120}
121
122/**
123 * Zero grant table entry
124 *
125 * @v xen Xen hypervisor
126 * @v hdr Grant table entry header
127 */
128static inline void xengrant_zero ( struct xen_hypervisor *xen,
129 struct grant_entry_header *hdr ) {
130 uint32_t *dword = ( ( uint32_t * ) hdr );
131 unsigned int i = ( ( sizeof ( xen->grant.table[0] ) / sizeof ( *dword ))
132 << xen->grant.shift );
133
134 while ( i-- )
135 writel ( 0, dword++ );
136}
137
138/**
139 * Invalidate access to a page
140 *
141 * @v xen Xen hypervisor
142 * @v ref Grant reference
143 */
144static inline __attribute__ (( always_inline )) void
145xengrant_invalidate ( struct xen_hypervisor *xen, grant_ref_t ref ) {
146 struct grant_entry_header *hdr = xengrant_header ( xen, ref );
147
148 /* Sanity check */
149 assert ( ( readw ( &hdr->flags ) &
150 ( GTF_reading | GTF_writing ) ) == 0 );
151
152 /* This should apparently be done using a cmpxchg instruction.
153 * We omit this: partly in the interests of simplicity, but
154 * mainly since our control flow generally does not permit
155 * failure paths to themselves fail.
156 */
157 writew ( 0, &hdr->flags );
158
159 /* Leave reference marked as in-use (see xengrant_alloc()) */
160 writew ( DOMID_SELF, &hdr->domid );
161}
162
163/**
164 * Permit access to a page
165 *
166 * @v xen Xen hypervisor
167 * @v ref Grant reference
168 * @v domid Domain ID
169 * @v subflags Additional flags
170 * @v addr Physical address within page
171 * @ret rc Return status code
172 */
173static inline __attribute__ (( always_inline )) int
174xengrant_permit_access ( struct xen_hypervisor *xen, grant_ref_t ref,
175 domid_t domid, unsigned int subflags,
177 struct grant_entry_header *hdr = xengrant_header ( xen, ref );
178 struct grant_entry_v1 *v1 = xengrant_v1 ( hdr );
179 union grant_entry_v2 *v2 = xengrant_v2 ( hdr );
180 unsigned long frame = ( addr / PAGE_SIZE );
181
182 /* Fail (for test purposes) if applicable */
183 if ( ( XENGRANT_FAIL_RATE > 0 ) &&
184 ( random() % XENGRANT_FAIL_RATE ) == 0 ) {
185 return -EAGAIN;
186 }
187
188 /* Record frame number. This may fail on a 64-bit system if
189 * we are using v1 grant tables. On a 32-bit system, there is
190 * no way for this code path to fail (with either v1 or v2
191 * grant tables); we allow the compiler to optimise the
192 * failure paths away to save space.
193 */
194 if ( sizeof ( physaddr_t ) == sizeof ( uint64_t ) ) {
195
196 /* 64-bit system */
197 if ( xen->grant.shift ) {
198 /* Version 2 table: no possible failure */
199 writeq ( frame, &v2->full_page.frame );
200 } else {
201 /* Version 1 table: may fail if address above 16TB */
202 if ( frame > 0xffffffffUL )
203 return -ERANGE;
204 writel ( frame, &v1->frame );
205 }
206
207 } else {
208
209 /* 32-bit system */
210 if ( xen->grant.shift ) {
211 /* Version 2 table: no possible failure */
212 writel ( frame, &v2->full_page.frame );
213 } else {
214 /* Version 1 table: no possible failure */
215 writel ( frame, &v1->frame );
216 }
217 }
218
219 /* Record domain ID and flags */
220 writew ( domid, &hdr->domid );
223 wmb();
224
225 return 0;
226}
227
228extern int xengrant_init ( struct xen_hypervisor *xen );
229extern int xengrant_alloc ( struct xen_hypervisor *xen, grant_ref_t *refs,
230 unsigned int count );
231extern void xengrant_free ( struct xen_hypervisor *xen, grant_ref_t *refs,
232 unsigned int count );
233
234#endif /* _IPXE_XENGRANT_H */
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
unsigned int uint32_t
Definition stdint.h:12
unsigned long physaddr_t
Definition stdint.h:20
unsigned long long uint64_t
Definition stdint.h:13
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
u32 version
Driver version.
Definition ath9k_hw.c:1985
uint32_t addr
Buffer address.
Definition dwmac.h:9
uint8_t flags
Flags.
Definition ena.h:7
#define GTF_writing
#define GTF_permit_access
#define GTF_reading
#define grant_entry_v1
uint32_t grant_ref_t
#define GNTTABOP_query_size
uint16_t size
Buffer size.
Definition dwmac.h:3
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ERANGE
Result too large.
Definition errno.h:640
#define EAGAIN
Resource temporarily unavailable.
Definition errno.h:319
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define __attribute__(x)
Definition compiler.h:10
iPXE I/O API
#define PAGE_SIZE
Page size.
Definition io.h:28
#define writeq(data, io_addr)
Definition io.h:273
Xen interface.
uint16_t domid_t
Definition xen.h:622
#define DOMID_SELF
Definition xen.h:581
#define __HYPERVISOR_grant_table_op
Definition xen.h:101
static const char grant_ref_t ref
Definition netfront.h:93
static const char grant_ref_t unsigned int struct io_buffer grant_ref_t * refs
Definition netfront.h:94
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
unsigned long int dword
Definition smc9000.h:40
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
unsigned int shift
Entry size shift (for later version tables)
Definition xen.h:35
size_t len
Total grant table length.
Definition xen.h:33
struct grant_entry_v1 * table
Grant table entries.
Definition xen.h:31
A Xen hypervisor.
Definition xen.h:51
struct xen_grant grant
Grant table.
Definition xen.h:57
#define writel
Definition w89c840.c:160
#define writew
Definition w89c840.c:159
#define readw
Definition w89c840.c:156
wmb()
int xengrant_alloc(struct xen_hypervisor *xen, grant_ref_t *refs, unsigned int count)
Allocate grant references.
Definition xengrant.c:149
static void xengrant_zero(struct xen_hypervisor *xen, struct grant_entry_header *hdr)
Zero grant table entry.
Definition xengrant.h:128
#define XENGRANT_FAIL_RATE
Induced failure rate (for testing)
Definition xengrant.h:20
v1
Definition xengrant.h:94
static grant_ref_t domid_t unsigned int subflags
Definition xengrant.h:175
static grant_ref_t domid_t domid
Definition xengrant.h:175
void xengrant_free(struct xen_hypervisor *xen, grant_ref_t *refs, unsigned int count)
Free grant references.
Definition xengrant.c:215
unsigned long frame
Definition xengrant.h:180
union grant_entry_v2 * v2
Definition xengrant.h:179
int xengrant_init(struct xen_hypervisor *xen)
Initialise grant table.
Definition xengrant.c:71