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 /* Nothing to initialise. Report the presence of the xenbus ring. */
112 return xb_port ? 0 : -ENODEV;
113}
114
115const char *xenstore_read(const char *path)
116{
117 struct xenstore_msg_hdr hdr = {
118 .type = XS_READ,
119 .len = strlen(path) + 1, /* Must send the NUL terminator. */
120 };
121
122 /* Write the header and path to read. */
123 xenbus_write(&hdr, sizeof(hdr));
124 xenbus_write(path, hdr.len);
125
126 /* Kick xenstored. */
128
129 /* Read the response header. */
130 xenbus_read(&hdr, sizeof(hdr));
131
132 if ( hdr.type != XS_READ )
133 return NULL;
134
135 if ( hdr.len > XENSTORE_PAYLOAD_MAX )
136 {
137 /*
138 * Xenstored handed back too much data. Drain it safely attempt to
139 * prevent the protocol from stalling.
140 */
141 while ( hdr.len )
142 {
143 unsigned int part = min(hdr.len, XENSTORE_PAYLOAD_MAX + 0u);
144
145 xenbus_read(payload, part);
146
147 hdr.len -= part;
148 }
149
150 return NULL;
151 }
152
153 /* Read the response payload. */
154 xenbus_read(payload, hdr.len);
155
156 /* Safely terminate the reply, just in case xenstored didn't. */
157 payload[hdr.len] = '\0';
158
159 return payload;
160}
161
162/*
163 * Local variables:
164 * mode: C
165 * c-file-style: "BSD"
166 * c-basic-offset: 4
167 * tab-width: 4
168 * indent-tabs-mode: nil
169 * End:
170 */
#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
uint32_t evtchn_port_t
Definition: event_channel.h:11
static int hypercall_evtchn_send(evtchn_port_t port)
Definition: hypercall.h:223
static long hypercall_poll(evtchn_port_t port)
Definition: hypercall.h:211
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
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
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:115
int xenstore_init(void)
Initialise XTF ready for xenstore communication.
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