Xen Test Framework
xenbus.c
Go to the documentation of this file.
1#include <xtf/atomic.h>
2#include <xtf/bitops.h>
3#include <xtf/hypercall.h>
4#include <xtf/lib.h>
5#include <xtf/traps.h>
6#include <xtf/xenbus.h>
7
11
13{
14 if ( port >= (sizeof(shared_info.evtchn_pending) * CHAR_BIT) )
15 panic("evtchn %u out of evtchn_pending[] range\n", port);
16
17 xb_ring = ring;
18 xb_port = port;
19}
20
21/*
22 * Write some raw data into the xenbus ring. Waits for sufficient space to
23 * appear if necessary.
24 */
25static void xenbus_write(const void *data, size_t len)
26{
27 uint32_t part, done = 0;
28
29 while ( len )
30 {
33
34 part = (XENBUS_RING_SIZE - 1) - mask_xenbus_idx(prod - cons);
35
36 /* No space? Kick xenstored and wait for it to consume some data. */
37 if ( !part )
38 {
40
43
44 continue;
45 }
46
47 /* Don't overrun the ring. */
48 part = min(part, XENBUS_RING_SIZE - mask_xenbus_idx(prod));
49
50 /* Don't write more than necessary. */
51 part = min(part, (unsigned int)len);
52
53 memcpy(xb_ring->req + mask_xenbus_idx(prod), data + done, part);
54
55 /* Complete the data read before updating the new producer index. */
56 smp_wmb();
57
58 ACCESS_ONCE(xb_ring->req_prod) = prod + part;
59
60 len -= part;
61 done += part;
62 }
63}
64
65/*
66 * Read some raw data from the xenbus ring. Waits for sufficient data to
67 * appear if necessary.
68 */
69static void xenbus_read(void *data, size_t len)
70{
71 uint32_t part, done = 0;
72
73 while ( len )
74 {
77
78 part = prod - cons;
79
80 /* No data? Kick xenstored and wait for it to produce some data. */
81 if ( !part )
82 {
84
87
88 continue;
89 }
90
91 /* Avoid overrunning the ring. */
92 part = min(part, XENBUS_RING_SIZE - mask_xenbus_idx(cons));
93
94 /* Don't read more than necessary. */
95 part = min(part, (unsigned int)len);
96
97 memcpy(data + done, xb_ring->rsp + mask_xenbus_idx(cons), part);
98
99 /* Complete the data read before updating the new consumer index. */
100 smp_mb();
101
102 ACCESS_ONCE(xb_ring->rsp_cons) = cons + part;
103
104 len -= part;
105 done += part;
106 }
107}
108
110{
111 /*
112 * The XenBus connection is usually set up on behalf of the domain by the
113 * domain builder.
114 *
115 * dom0 is the entity expected to start xenstored (daemon or domain), and
116 * gets no connection details at all. It is supposed to connect late
117 * after starting xenstored.
118 */
119 if ( !xb_port )
120 return -ENODEV;
121
122 /*
123 * Probe whether xb_port is bound. "dom0less" constructs some domains
124 * with an unbound event channel, to be connected later when dom0 starts
125 * xenstored.
126 */
127 struct evtchn_status es = {
128 .dom = DOMID_SELF,
129 .port = xb_port,
130 };
131 int rc = hypercall_evtchn_status(&es);
132
133 if ( rc || es.status != EVTCHN_STATUS_interdomain )
134 return -ENODEV;
135
136 return 0;
137}
138
139const char *xenstore_read(const char *path)
140{
141 struct xenstore_msg_hdr hdr = {
142 .type = XS_READ,
143 .len = strlen(path) + 1, /* Must send the NUL terminator. */
144 };
145
146 /* Write the header and path to read. */
147 xenbus_write(&hdr, sizeof(hdr));
148 xenbus_write(path, hdr.len);
149
150 /* Kick xenstored. */
152
153 /* Read the response header. */
154 xenbus_read(&hdr, sizeof(hdr));
155
156 if ( hdr.type != XS_READ )
157 return NULL;
158
159 if ( hdr.len > XENSTORE_PAYLOAD_MAX )
160 {
161 /*
162 * Xenstored handed back too much data. Drain it safely attempt to
163 * prevent the protocol from stalling.
164 */
165 while ( hdr.len )
166 {
167 unsigned int part = min(hdr.len, XENSTORE_PAYLOAD_MAX + 0u);
168
169 xenbus_read(payload, part);
170
171 hdr.len -= part;
172 }
173
174 return NULL;
175 }
176
177 /* Read the response payload. */
178 xenbus_read(payload, hdr.len);
179
180 /* Safely terminate the reply, just in case xenstored didn't. */
181 payload[hdr.len] = '\0';
182
183 return payload;
184}
185
186/*
187 * Local variables:
188 * mode: C
189 * c-file-style: "BSD"
190 * c-basic-offset: 4
191 * tab-width: 4
192 * indent-tabs-mode: nil
193 * End:
194 */
#define smp_mb()
Definition: barrier.h:33
#define smp_wmb()
Definition: barrier.h:36
static bool test_and_clear_bit(unsigned int bit, volatile void *addr)
Definition: bitops.h:53
#define ENODEV
Definition: errno.h:32
#define EVTCHN_STATUS_interdomain
Definition: event_channel.h:23
uint32_t evtchn_port_t
Definition: event_channel.h:13
static int hypercall_evtchn_send(evtchn_port_t port)
Definition: hypercall.h:229
static long hypercall_poll(evtchn_port_t port)
Definition: hypercall.h:212
static int hypercall_evtchn_status(struct evtchn_status *status)
Definition: hypercall.h:234
Low level bit operations.
#define ACCESS_ONCE(x)
Definition: lib.h:10
#define min(a, b)
Definition: lib.h:28
void panic(const char *fmt,...)
Definition: lib.c:15
#define strlen(s)
Definition: libc.h:18
#define memcpy(d, s, n)
Definition: libc.h:36
#define CHAR_BIT
Definition: limits.h:9
#define NULL
Definition: stddef.h:12
__UINT32_TYPE__ uint32_t
Definition: stdint.h:16
uint32_t status
Definition: event_channel.h:27
unsigned long evtchn_pending[sizeof(unsigned long) *8]
Definition: xen.h:186
char rsp[XENBUS_RING_SIZE]
Definition: xs_wire.h:14
uint32_t req_cons
Definition: xs_wire.h:15
uint32_t req_prod
Definition: xs_wire.h:15
uint32_t rsp_prod
Definition: xs_wire.h:16
char req[XENBUS_RING_SIZE]
Definition: xs_wire.h:13
uint32_t rsp_cons
Definition: xs_wire.h:16
uint32_t len
Definition: xs_wire.h:34
uint32_t type
Definition: xs_wire.h:31
#define DOMID_SELF
Definition: xen.h:70
void init_xenbus(xenbus_interface_t *ring, evtchn_port_t port)
Definition: xenbus.c:12
static xenbus_interface_t * xb_ring
Definition: xenbus.c:8
static void xenbus_write(const void *data, size_t len)
Definition: xenbus.c:25
static void xenbus_read(void *data, size_t len)
Definition: xenbus.c:69
static char payload[XENSTORE_PAYLOAD_MAX+1]
Definition: xenbus.c:10
static evtchn_port_t xb_port
Definition: xenbus.c:9
const char * xenstore_read(const char *path)
Issue a XS_READ operation for key, waiting synchronously for the reply.
Definition: xenbus.c:139
int xenstore_init(void)
Initialise XTF ready for xenstore communication, and determine whether xenstored is listening.
Definition: xenbus.c:109
static uint32_t mask_xenbus_idx(uint32_t idx)
Definition: xs_wire.h:7
#define XENSTORE_PAYLOAD_MAX
Definition: xs_wire.h:69
#define XENBUS_RING_SIZE
Definition: xs_wire.h:6
@ XS_READ
Definition: xs_wire.h:41