2 * linux/fs/9p/trans_xen
6 * Copyright (C) 2017 by Stefano Stabellini <stefano@aporeto.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation; or, when distributed
11 * separately from the Linux kernel or incorporated into other
12 * software packages, subject to the following license:
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this source file (the "Software"), to deal in the Software without
16 * restriction, including without limitation the rights to use, copy, modify,
17 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
18 * and to permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
33 #include <xen/events.h>
34 #include <xen/grant_table.h>
36 #include <xen/xenbus.h>
37 #include <xen/interface/io/9pfs.h>
39 #include <linux/module.h>
40 #include <linux/spinlock.h>
41 #include <linux/rwlock.h>
42 #include <net/9p/9p.h>
43 #include <net/9p/client.h>
44 #include <net/9p/transport.h>
46 #define XEN_9PFS_NUM_RINGS 2
47 #define XEN_9PFS_RING_ORDER 6
48 #define XEN_9PFS_RING_SIZE XEN_FLEX_RING_SIZE(XEN_9PFS_RING_ORDER)
50 struct xen_9pfs_header
{
55 /* uint8_t sdata[]; */
56 } __attribute__((packed
));
58 /* One per ring, more than one per 9pfs share */
59 struct xen_9pfs_dataring
{
60 struct xen_9pfs_front_priv
*priv
;
62 struct xen_9pfs_data_intf
*intf
;
66 /* protect a ring from concurrent accesses */
69 struct xen_9pfs_data data
;
71 struct work_struct work
;
74 /* One per 9pfs share */
75 struct xen_9pfs_front_priv
{
76 struct list_head list
;
77 struct xenbus_device
*dev
;
79 struct p9_client
*client
;
82 struct xen_9pfs_dataring
*rings
;
85 static LIST_HEAD(xen_9pfs_devs
);
86 static DEFINE_RWLOCK(xen_9pfs_lock
);
88 static int p9_xen_cancel(struct p9_client
*client
, struct p9_req_t
*req
)
93 static int p9_xen_create(struct p9_client
*client
, const char *addr
, char *args
)
98 static void p9_xen_close(struct p9_client
*client
)
102 static int p9_xen_request(struct p9_client
*client
, struct p9_req_t
*p9_req
)
107 static void p9_xen_response(struct work_struct
*work
)
111 static irqreturn_t
xen_9pfs_front_event_handler(int irq
, void *r
)
113 struct xen_9pfs_dataring
*ring
= r
;
115 if (!ring
|| !ring
->priv
->client
) {
116 /* ignore spurious interrupt */
120 wake_up_interruptible(&ring
->wq
);
121 schedule_work(&ring
->work
);
126 static struct p9_trans_module p9_xen_trans
= {
128 .maxsize
= 1 << (XEN_9PFS_RING_ORDER
+ XEN_PAGE_SHIFT
),
130 .create
= p9_xen_create
,
131 .close
= p9_xen_close
,
132 .request
= p9_xen_request
,
133 .cancel
= p9_xen_cancel
,
134 .owner
= THIS_MODULE
,
137 static const struct xenbus_device_id xen_9pfs_front_ids
[] = {
142 static void xen_9pfs_front_free(struct xen_9pfs_front_priv
*priv
)
146 write_lock(&xen_9pfs_lock
);
147 list_del(&priv
->list
);
148 write_unlock(&xen_9pfs_lock
);
150 for (i
= 0; i
< priv
->num_rings
; i
++) {
151 if (!priv
->rings
[i
].intf
)
153 if (priv
->rings
[i
].irq
> 0)
154 unbind_from_irqhandler(priv
->rings
[i
].irq
, priv
->dev
);
155 if (priv
->rings
[i
].data
.in
) {
156 for (j
= 0; j
< (1 << XEN_9PFS_RING_ORDER
); j
++) {
159 ref
= priv
->rings
[i
].intf
->ref
[j
];
160 gnttab_end_foreign_access(ref
, 0, 0);
162 free_pages((unsigned long)priv
->rings
[i
].data
.in
,
163 XEN_9PFS_RING_ORDER
-
164 (PAGE_SHIFT
- XEN_PAGE_SHIFT
));
166 gnttab_end_foreign_access(priv
->rings
[i
].ref
, 0, 0);
167 free_page((unsigned long)priv
->rings
[i
].intf
);
174 static int xen_9pfs_front_remove(struct xenbus_device
*dev
)
176 struct xen_9pfs_front_priv
*priv
= dev_get_drvdata(&dev
->dev
);
178 dev_set_drvdata(&dev
->dev
, NULL
);
179 xen_9pfs_front_free(priv
);
183 static int xen_9pfs_front_alloc_dataring(struct xenbus_device
*dev
,
184 struct xen_9pfs_dataring
*ring
)
190 init_waitqueue_head(&ring
->wq
);
191 spin_lock_init(&ring
->lock
);
192 INIT_WORK(&ring
->work
, p9_xen_response
);
194 ring
->intf
= (struct xen_9pfs_data_intf
*)get_zeroed_page(GFP_KERNEL
);
197 ret
= gnttab_grant_foreign_access(dev
->otherend_id
,
198 virt_to_gfn(ring
->intf
), 0);
202 bytes
= (void *)__get_free_pages(GFP_KERNEL
| __GFP_ZERO
,
203 XEN_9PFS_RING_ORDER
- (PAGE_SHIFT
- XEN_PAGE_SHIFT
));
208 for (; i
< (1 << XEN_9PFS_RING_ORDER
); i
++) {
209 ret
= gnttab_grant_foreign_access(
210 dev
->otherend_id
, virt_to_gfn(bytes
) + i
, 0);
213 ring
->intf
->ref
[i
] = ret
;
215 ring
->intf
->ring_order
= XEN_9PFS_RING_ORDER
;
216 ring
->data
.in
= bytes
;
217 ring
->data
.out
= bytes
+ XEN_9PFS_RING_SIZE
;
219 ret
= xenbus_alloc_evtchn(dev
, &ring
->evtchn
);
222 ring
->irq
= bind_evtchn_to_irqhandler(ring
->evtchn
,
223 xen_9pfs_front_event_handler
,
224 0, "xen_9pfs-frontend", ring
);
228 xenbus_free_evtchn(dev
, ring
->evtchn
);
232 for (i
--; i
>= 0; i
--)
233 gnttab_end_foreign_access(ring
->intf
->ref
[i
], 0, 0);
234 free_pages((unsigned long)bytes
,
235 XEN_9PFS_RING_ORDER
-
236 (PAGE_SHIFT
- XEN_PAGE_SHIFT
));
238 gnttab_end_foreign_access(ring
->ref
, 0, 0);
239 free_page((unsigned long)ring
->intf
);
243 static int xen_9pfs_front_probe(struct xenbus_device
*dev
,
244 const struct xenbus_device_id
*id
)
247 struct xenbus_transaction xbt
;
248 struct xen_9pfs_front_priv
*priv
= NULL
;
250 unsigned int max_rings
, max_ring_order
, len
;
252 versions
= xenbus_read(XBT_NIL
, dev
->otherend
, "versions", &len
);
255 if (strcmp(versions
, "1")) {
260 max_rings
= xenbus_read_unsigned(dev
->otherend
, "max-rings", 0);
261 if (max_rings
< XEN_9PFS_NUM_RINGS
)
263 max_ring_order
= xenbus_read_unsigned(dev
->otherend
,
264 "max-ring-page-order", 0);
265 if (max_ring_order
< XEN_9PFS_RING_ORDER
)
268 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
273 priv
->num_rings
= XEN_9PFS_NUM_RINGS
;
274 priv
->rings
= kcalloc(priv
->num_rings
, sizeof(*priv
->rings
),
281 for (i
= 0; i
< priv
->num_rings
; i
++) {
282 priv
->rings
[i
].priv
= priv
;
283 ret
= xen_9pfs_front_alloc_dataring(dev
, &priv
->rings
[i
]);
289 ret
= xenbus_transaction_start(&xbt
);
291 xenbus_dev_fatal(dev
, ret
, "starting transaction");
294 ret
= xenbus_printf(xbt
, dev
->nodename
, "version", "%u", 1);
297 ret
= xenbus_printf(xbt
, dev
->nodename
, "num-rings", "%u",
301 for (i
= 0; i
< priv
->num_rings
; i
++) {
304 BUILD_BUG_ON(XEN_9PFS_NUM_RINGS
> 9);
305 sprintf(str
, "ring-ref%u", i
);
306 ret
= xenbus_printf(xbt
, dev
->nodename
, str
, "%d",
311 sprintf(str
, "event-channel-%u", i
);
312 ret
= xenbus_printf(xbt
, dev
->nodename
, str
, "%u",
313 priv
->rings
[i
].evtchn
);
317 priv
->tag
= xenbus_read(xbt
, dev
->nodename
, "tag", NULL
);
322 ret
= xenbus_transaction_end(xbt
, 0);
326 xenbus_dev_fatal(dev
, ret
, "completing transaction");
330 write_lock(&xen_9pfs_lock
);
331 list_add_tail(&priv
->list
, &xen_9pfs_devs
);
332 write_unlock(&xen_9pfs_lock
);
333 dev_set_drvdata(&dev
->dev
, priv
);
334 xenbus_switch_state(dev
, XenbusStateInitialised
);
339 xenbus_transaction_end(xbt
, 1);
340 xenbus_dev_fatal(dev
, ret
, "writing xenstore");
342 dev_set_drvdata(&dev
->dev
, NULL
);
343 xen_9pfs_front_free(priv
);
347 static int xen_9pfs_front_resume(struct xenbus_device
*dev
)
349 dev_warn(&dev
->dev
, "suspsend/resume unsupported\n");
353 static void xen_9pfs_front_changed(struct xenbus_device
*dev
,
354 enum xenbus_state backend_state
)
356 switch (backend_state
) {
357 case XenbusStateReconfiguring
:
358 case XenbusStateReconfigured
:
359 case XenbusStateInitialising
:
360 case XenbusStateInitialised
:
361 case XenbusStateUnknown
:
364 case XenbusStateInitWait
:
367 case XenbusStateConnected
:
368 xenbus_switch_state(dev
, XenbusStateConnected
);
371 case XenbusStateClosed
:
372 if (dev
->state
== XenbusStateClosed
)
374 /* Missed the backend's CLOSING state -- fallthrough */
375 case XenbusStateClosing
:
376 xenbus_frontend_closed(dev
);
381 static struct xenbus_driver xen_9pfs_front_driver
= {
382 .ids
= xen_9pfs_front_ids
,
383 .probe
= xen_9pfs_front_probe
,
384 .remove
= xen_9pfs_front_remove
,
385 .resume
= xen_9pfs_front_resume
,
386 .otherend_changed
= xen_9pfs_front_changed
,
389 int p9_trans_xen_init(void)
394 pr_info("Initialising Xen transport for 9pfs\n");
396 v9fs_register_trans(&p9_xen_trans
);
397 return xenbus_register_frontend(&xen_9pfs_front_driver
);
399 module_init(p9_trans_xen_init
);
401 void p9_trans_xen_exit(void)
403 v9fs_unregister_trans(&p9_xen_trans
);
404 return xenbus_unregister_driver(&xen_9pfs_front_driver
);
406 module_exit(p9_trans_xen_exit
);