diff options
-rw-r--r-- | drivers/xen/xenbus/xenbus_comms.c | 6 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_comms.h | 1 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_dev_backend.c | 51 | ||||
-rw-r--r-- | include/xen/grant_table.h | 2 | ||||
-rw-r--r-- | include/xen/xenbus_dev.h | 3 |
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 | |||
238 | void 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 | ||
36 | int xs_init(void); | 36 | int xs_init(void); |
37 | int xb_init_comms(void); | 37 | int xb_init_comms(void); |
38 | void xb_deinit_comms(void); | ||
38 | 39 | ||
39 | /* Low level routines. */ | 40 | /* Low level routines. */ |
40 | int xb_write(const void *data, unsigned len); | 41 | int 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 | ||
29 | static 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 | |||
25 | static long xenbus_backend_ioctl(struct file *file, unsigned int cmd, unsigned long data) | 73 | static 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__ */ |