aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/xen/xenbus/xenbus_comms.c6
-rw-r--r--drivers/xen/xenbus/xenbus_comms.h1
-rw-r--r--drivers/xen/xenbus/xenbus_dev_backend.c51
-rw-r--r--include/xen/grant_table.h2
-rw-r--r--include/xen/xenbus_dev.h3
5 files changed, 63 insertions, 0 deletions
diff --git a/drivers/xen/xenbus/xenbus_comms.c b/drivers/xen/xenbus/xenbus_comms.c
index 2eff7a6aaa20..52fe7ad07666 100644
--- a/drivers/xen/xenbus/xenbus_comms.c
+++ b/drivers/xen/xenbus/xenbus_comms.c
@@ -234,3 +234,9 @@ int xb_init_comms(void)
234 234
235 return 0; 235 return 0;
236} 236}
237
238void xb_deinit_comms(void)
239{
240 unbind_from_irqhandler(xenbus_irq, &xb_waitq);
241 xenbus_irq = 0;
242}
diff --git a/drivers/xen/xenbus/xenbus_comms.h b/drivers/xen/xenbus/xenbus_comms.h
index 6e42800fa499..c8abd3b8a6c4 100644
--- a/drivers/xen/xenbus/xenbus_comms.h
+++ b/drivers/xen/xenbus/xenbus_comms.h
@@ -35,6 +35,7 @@
35 35
36int xs_init(void); 36int xs_init(void);
37int xb_init_comms(void); 37int xb_init_comms(void);
38void xb_deinit_comms(void);
38 39
39/* Low level routines. */ 40/* Low level routines. */
40int xb_write(const void *data, unsigned len); 41int xb_write(const void *data, unsigned len);
diff --git a/drivers/xen/xenbus/xenbus_dev_backend.c b/drivers/xen/xenbus/xenbus_dev_backend.c
index 3d3be78c1093..be738c43104b 100644
--- a/drivers/xen/xenbus/xenbus_dev_backend.c
+++ b/drivers/xen/xenbus/xenbus_dev_backend.c
@@ -8,7 +8,11 @@
8 8
9#include <xen/xen.h> 9#include <xen/xen.h>
10#include <xen/page.h> 10#include <xen/page.h>
11#include <xen/xenbus.h>
11#include <xen/xenbus_dev.h> 12#include <xen/xenbus_dev.h>
13#include <xen/grant_table.h>
14#include <xen/events.h>
15#include <asm/xen/hypervisor.h>
12 16
13#include "xenbus_comms.h" 17#include "xenbus_comms.h"
14 18
@@ -22,6 +26,50 @@ static int xenbus_backend_open(struct inode *inode, struct file *filp)
22 return nonseekable_open(inode, filp); 26 return nonseekable_open(inode, filp);
23} 27}
24 28
29static long xenbus_alloc(domid_t domid)
30{
31 struct evtchn_alloc_unbound arg;
32 int err = -EEXIST;
33
34 xs_suspend();
35
36 /* If xenstored_ready is nonzero, that means we have already talked to
37 * xenstore and set up watches. These watches will be restored by
38 * xs_resume, but that requires communication over the port established
39 * below that is not visible to anyone until the ioctl returns.
40 *
41 * This can be resolved by splitting the ioctl into two parts
42 * (postponing the resume until xenstored is active) but this is
43 * unnecessarily complex for the intended use where xenstored is only
44 * started once - so return -EEXIST if it's already running.
45 */
46 if (xenstored_ready)
47 goto out_err;
48
49 gnttab_grant_foreign_access_ref(GNTTAB_RESERVED_XENSTORE, domid,
50 virt_to_mfn(xen_store_interface), 0 /* writable */);
51
52 arg.dom = DOMID_SELF;
53 arg.remote_dom = domid;
54
55 err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &arg);
56 if (err)
57 goto out_err;
58
59 if (xen_store_evtchn > 0)
60 xb_deinit_comms();
61
62 xen_store_evtchn = arg.port;
63
64 xs_resume();
65
66 return arg.port;
67
68 out_err:
69 xs_suspend_cancel();
70 return err;
71}
72
25static long xenbus_backend_ioctl(struct file *file, unsigned int cmd, unsigned long data) 73static long xenbus_backend_ioctl(struct file *file, unsigned int cmd, unsigned long data)
26{ 74{
27 if (!capable(CAP_SYS_ADMIN)) 75 if (!capable(CAP_SYS_ADMIN))
@@ -33,6 +81,9 @@ static long xenbus_backend_ioctl(struct file *file, unsigned int cmd, unsigned l
33 return xen_store_evtchn; 81 return xen_store_evtchn;
34 return -ENODEV; 82 return -ENODEV;
35 83
84 case IOCTL_XENBUS_BACKEND_SETUP:
85 return xenbus_alloc(data);
86
36 default: 87 default:
37 return -ENOTTY; 88 return -ENOTTY;
38 } 89 }
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index 15f8a00ff003..11e27c3af3cb 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -46,6 +46,8 @@
46 46
47#include <xen/features.h> 47#include <xen/features.h>
48 48
49#define GNTTAB_RESERVED_XENSTORE 1
50
49/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */ 51/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
50#define NR_GRANT_FRAMES 4 52#define NR_GRANT_FRAMES 4
51 53
diff --git a/include/xen/xenbus_dev.h b/include/xen/xenbus_dev.h
index ac5f0fe47ed9..bbee8c6a349d 100644
--- a/include/xen/xenbus_dev.h
+++ b/include/xen/xenbus_dev.h
@@ -38,4 +38,7 @@
38#define IOCTL_XENBUS_BACKEND_EVTCHN \ 38#define IOCTL_XENBUS_BACKEND_EVTCHN \
39 _IOC(_IOC_NONE, 'B', 0, 0) 39 _IOC(_IOC_NONE, 'B', 0, 0)
40 40
41#define IOCTL_XENBUS_BACKEND_SETUP \
42 _IOC(_IOC_NONE, 'B', 1, 0)
43
41#endif /* __LINUX_XEN_XENBUS_DEV_H__ */ 44#endif /* __LINUX_XEN_XENBUS_DEV_H__ */