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 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 FILE_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  */
29 static inline __attribute__ (( always_inline )) int
30 xengrant_query_size ( struct xen_hypervisor *xen,
31  struct gnttab_query_size *size ) {
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  */
45 static inline __attribute__ (( always_inline )) int
46 xengrant_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  */
61 static inline __attribute__ (( always_inline )) int
62 xengrant_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  */
76 static inline __attribute__ (( always_inline )) unsigned int
77 xengrant_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  */
90 static inline __attribute__ (( always_inline )) struct grant_entry_header *
91 xengrant_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  */
104 static inline __attribute__ (( always_inline )) struct grant_entry_v1 *
105 xengrant_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  */
116 static inline __attribute__ (( always_inline )) union grant_entry_v2 *
117 xengrant_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  */
128 static 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  */
144 static inline __attribute__ (( always_inline )) void
145 xengrant_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  */
173 static inline __attribute__ (( always_inline )) int
174 xengrant_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 );
221  wmb();
222  writew ( ( GTF_permit_access | subflags ), &hdr->flags );
223  wmb();
224 
225  return 0;
226 }
227 
228 extern int xengrant_init ( struct xen_hypervisor *xen );
229 extern int xengrant_alloc ( struct xen_hypervisor *xen, grant_ref_t *refs,
230  unsigned int count );
231 extern void xengrant_free ( struct xen_hypervisor *xen, grant_ref_t *refs,
232  unsigned int count );
233 
234 #endif /* _IPXE_XENGRANT_H */
iPXE I/O API
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
wmb()
uint16_t domid_t
Definition: xen.h:609
void xengrant_free(struct xen_hypervisor *xen, grant_ref_t *refs, unsigned int count)
Free grant references.
Definition: xengrant.c:215
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
uint16_t readw(volatile uint16_t *io_addr)
Read 16-bit word from memory-mapped device.
#define GTF_writing
Definition: grant_table.h:172
v1
Definition: xengrant.h:94
unsigned long long uint64_t
Definition: stdint.h:13
static grant_ref_t domid_t unsigned int physaddr_t addr
Definition: xengrant.h:176
#define PAGE_SIZE
Page size.
Definition: io.h:28
uint32_t grant_ref_t
Definition: grant_table.h:100
A Xen hypervisor.
Definition: xen.h:51
Xen interface.
#define GTF_reading
Definition: grant_table.h:170
unsigned long frame
Definition: xengrant.h:180
#define XENGRANT_FAIL_RATE
Induced failure rate (for testing)
Definition: xengrant.h:20
static struct gnttab_set_version * version
Definition: xengrant.h:47
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
FILE_SECBOOT(PERMITTED)
static __attribute__((always_inline)) int xengrant_query_size(struct xen_hypervisor *xen
Query grant table size.
Definition: xengrant.h:76
void writel(uint32_t data, volatile uint32_t *io_addr)
Write 32-bit dword to memory-mapped device.
static unsigned int count
Number of entries.
Definition: dwmac.h:225
struct grant_entry_v1 * table
Grant table entries.
Definition: xen.h:31
static grant_ref_t domid_t unsigned int subflags
Definition: xengrant.h:174
#define __HYPERVISOR_grant_table_op
Definition: xen.h:97
uint8_t flags
Flags.
Definition: ena.h:18
#define ERANGE
Result too large.
Definition: errno.h:640
static const char grant_ref_t unsigned int struct io_buffer grant_ref_t * refs
Definition: netfront.h:94
static grant_ref_t domid_t domid
Definition: xengrant.h:174
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:32
Definition: grant_table.h:118
unsigned int uint32_t
Definition: stdint.h:12
#define EAGAIN
Resource temporarily unavailable.
Definition: errno.h:319
#define GNTTABOP_query_size
Definition: grant_table.h:296
union grant_entry_v2 * v2
Definition: xengrant.h:179
unsigned long physaddr_t
Definition: stdint.h:20
writew(0, &hdr->flags)
unsigned int shift
Entry size shift (for later version tables)
Definition: xen.h:35
struct xen_grant grant
Grant table.
Definition: xen.h:57
#define DOMID_SELF
Definition: xen.h:568
static struct gnttab_query_size * size
Definition: xengrant.h:31
size_t len
Total grant table length.
Definition: xen.h:33
int xengrant_init(struct xen_hypervisor *xen)
Initialise grant table.
Definition: xengrant.c:71
int xengrant_alloc(struct xen_hypervisor *xen, grant_ref_t *refs, unsigned int count)
Allocate grant references.
Definition: xengrant.c:149
static grant_ref_t ref
Definition: xengrant.h:91
#define GTF_permit_access
Definition: grant_table.h:150
static void xengrant_zero(struct xen_hypervisor *xen, struct grant_entry_header *hdr)
Zero grant table entry.
Definition: xengrant.h:128
void writeq(uint64_t data, volatile uint64_t *io_addr)
Write 64-bit qword to memory-mapped device.
unsigned long int dword
Definition: smc9000.h:40
struct xen_hypervisor * xen
Xen hypervisor.
Definition: xenbus.h:23