| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: xenevt.c,v 1.24 2008/03/01 18:32:48 rmind Exp $ */ | | 1 | /* $NetBSD: xenevt.c,v 1.25 2008/03/22 14:28:10 ad Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2005 Manuel Bouyer. | | 4 | * Copyright (c) 2005 Manuel Bouyer. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * 3. All advertising materials mentioning features or use of this software | | 14 | * 3. All advertising materials mentioning features or use of this software |
| @@ -21,27 +21,27 @@ | | | @@ -21,27 +21,27 @@ |
21 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 21 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
23 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 23 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
24 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 24 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
29 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 29 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | * | | 30 | * |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1.24 2008/03/01 18:32:48 rmind Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1.25 2008/03/22 14:28:10 ad Exp $"); |
35 | | | 35 | |
36 | #include "opt_xen.h" | | 36 | #include "opt_xen.h" |
37 | #include <sys/param.h> | | 37 | #include <sys/param.h> |
38 | #include <sys/kernel.h> | | 38 | #include <sys/kernel.h> |
39 | #include <sys/malloc.h> | | 39 | #include <sys/malloc.h> |
40 | #include <sys/systm.h> | | 40 | #include <sys/systm.h> |
41 | #include <sys/device.h> | | 41 | #include <sys/device.h> |
42 | #include <sys/file.h> | | 42 | #include <sys/file.h> |
43 | #include <sys/filedesc.h> | | 43 | #include <sys/filedesc.h> |
44 | #include <sys/poll.h> | | 44 | #include <sys/poll.h> |
45 | #include <sys/select.h> | | 45 | #include <sys/select.h> |
46 | #include <sys/proc.h> | | 46 | #include <sys/proc.h> |
47 | #include <sys/conf.h> | | 47 | #include <sys/conf.h> |
| @@ -64,29 +64,29 @@ __KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1 | | | @@ -64,29 +64,29 @@ __KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1 |
64 | * Each process with a xenevt device instance open can regiter events it | | 64 | * Each process with a xenevt device instance open can regiter events it |
65 | * wants to receive. It will get pending events by read(), eventually blocking | | 65 | * wants to receive. It will get pending events by read(), eventually blocking |
66 | * until some event is available. Pending events are ack'd by a bitmask | | 66 | * until some event is available. Pending events are ack'd by a bitmask |
67 | * write()en to the device. Some special operations (such as events binding) | | 67 | * write()en to the device. Some special operations (such as events binding) |
68 | * are done though ioctl(). | | 68 | * are done though ioctl(). |
69 | * Processes get a device instance by opening a cloning device. | | 69 | * Processes get a device instance by opening a cloning device. |
70 | */ | | 70 | */ |
71 | | | 71 | |
72 | void xenevtattach(int); | | 72 | void xenevtattach(int); |
73 | static int xenevt_fread(struct file *, off_t *, struct uio *, | | 73 | static int xenevt_fread(struct file *, off_t *, struct uio *, |
74 | kauth_cred_t, int); | | 74 | kauth_cred_t, int); |
75 | static int xenevt_fwrite(struct file *, off_t *, struct uio *, | | 75 | static int xenevt_fwrite(struct file *, off_t *, struct uio *, |
76 | kauth_cred_t, int); | | 76 | kauth_cred_t, int); |
77 | static int xenevt_fioctl(struct file *, u_long, void *, struct lwp *); | | 77 | static int xenevt_fioctl(struct file *, u_long, void *); |
78 | static int xenevt_fpoll(struct file *, int, struct lwp *); | | 78 | static int xenevt_fpoll(struct file *, int); |
79 | static int xenevt_fclose(struct file *, struct lwp *); | | 79 | static int xenevt_fclose(struct file *); |
80 | /* static int xenevt_fkqfilter(struct file *, struct knote *); */ | | 80 | /* static int xenevt_fkqfilter(struct file *, struct knote *); */ |
81 | | | 81 | |
82 | static const struct fileops xenevt_fileops = { | | 82 | static const struct fileops xenevt_fileops = { |
83 | xenevt_fread, | | 83 | xenevt_fread, |
84 | xenevt_fwrite, | | 84 | xenevt_fwrite, |
85 | xenevt_fioctl, | | 85 | xenevt_fioctl, |
86 | fnullop_fcntl, | | 86 | fnullop_fcntl, |
87 | xenevt_fpoll, | | 87 | xenevt_fpoll, |
88 | fbadop_stat, | | 88 | fbadop_stat, |
89 | xenevt_fclose, | | 89 | xenevt_fclose, |
90 | /* xenevt_fkqfilter */ fnullop_kqfilter | | 90 | /* xenevt_fkqfilter */ fnullop_kqfilter |
91 | }; | | 91 | }; |
92 | | | 92 | |
| @@ -291,33 +291,33 @@ xenevt_record(struct xenevt_d *d, evtchn | | | @@ -291,33 +291,33 @@ xenevt_record(struct xenevt_d *d, evtchn |
291 | } | | 291 | } |
292 | | | 292 | |
293 | /* open the xenevt device; this is where we clone */ | | 293 | /* open the xenevt device; this is where we clone */ |
294 | int | | 294 | int |
295 | xenevtopen(dev_t dev, int flags, int mode, struct lwp *l) | | 295 | xenevtopen(dev_t dev, int flags, int mode, struct lwp *l) |
296 | { | | 296 | { |
297 | struct xenevt_d *d; | | 297 | struct xenevt_d *d; |
298 | struct file *fp; | | 298 | struct file *fp; |
299 | int fd, error; | | 299 | int fd, error; |
300 | | | 300 | |
301 | switch(minor(dev)) { | | 301 | switch(minor(dev)) { |
302 | case DEV_EVT: | | 302 | case DEV_EVT: |
303 | /* falloc() will use the descriptor for us. */ | | 303 | /* falloc() will use the descriptor for us. */ |
304 | if ((error = falloc(l, &fp, &fd)) != 0) | | 304 | if ((error = fd_allocfile(&fp, &fd)) != 0) |
305 | return error; | | 305 | return error; |
306 | | | 306 | |
307 | d = malloc(sizeof(*d), M_DEVBUF, M_WAITOK | M_ZERO); | | 307 | d = malloc(sizeof(*d), M_DEVBUF, M_WAITOK | M_ZERO); |
308 | simple_lock_init(&d->lock); | | 308 | simple_lock_init(&d->lock); |
309 | selinit(&d->sel); | | 309 | selinit(&d->sel); |
310 | return fdclone(l, fp, fd, flags, &xenevt_fileops, d); | | 310 | return fd_clone(fp, fd, flags, &xenevt_fileops, d); |
311 | #ifdef XEN3 | | 311 | #ifdef XEN3 |
312 | case DEV_XSD: | | 312 | case DEV_XSD: |
313 | /* no clone for /dev/xsd_kva */ | | 313 | /* no clone for /dev/xsd_kva */ |
314 | return (0); | | 314 | return (0); |
315 | #endif | | 315 | #endif |
316 | default: | | 316 | default: |
317 | break; | | 317 | break; |
318 | } | | 318 | } |
319 | return ENODEV; | | 319 | return ENODEV; |
320 | } | | 320 | } |
321 | | | 321 | |
322 | /* read from device: only for /dev/xsd_kva, xenevt is done though fread */ | | 322 | /* read from device: only for /dev/xsd_kva, xenevt is done though fread */ |
323 | int | | 323 | int |
| @@ -356,27 +356,27 @@ xenevtmmap(dev_t dev, off_t off, int pro | | | @@ -356,27 +356,27 @@ xenevtmmap(dev_t dev, off_t off, int pro |
356 | #ifdef XEN3 | | 356 | #ifdef XEN3 |
357 | if (minor(dev) == DEV_XSD) { | | 357 | if (minor(dev) == DEV_XSD) { |
358 | /* only one page, so off is always 0 */ | | 358 | /* only one page, so off is always 0 */ |
359 | if (off != 0) | | 359 | if (off != 0) |
360 | return -1; | | 360 | return -1; |
361 | return x86_btop( | | 361 | return x86_btop( |
362 | xpmap_mtop(xen_start_info.store_mfn << PAGE_SHIFT)); | | 362 | xpmap_mtop(xen_start_info.store_mfn << PAGE_SHIFT)); |
363 | } | | 363 | } |
364 | #endif | | 364 | #endif |
365 | return -1; | | 365 | return -1; |
366 | } | | 366 | } |
367 | | | 367 | |
368 | static int | | 368 | static int |
369 | xenevt_fclose(struct file *fp, struct lwp *l) | | 369 | xenevt_fclose(struct file *fp) |
370 | { | | 370 | { |
371 | struct xenevt_d *d = fp->f_data; | | 371 | struct xenevt_d *d = fp->f_data; |
372 | int i; | | 372 | int i; |
373 | | | 373 | |
374 | for (i = 0; i < NR_EVENT_CHANNELS; i++ ) { | | 374 | for (i = 0; i < NR_EVENT_CHANNELS; i++ ) { |
375 | if (devevent[i] == d) { | | 375 | if (devevent[i] == d) { |
376 | #ifdef XEN3 | | 376 | #ifdef XEN3 |
377 | evtchn_op_t op = { 0 }; | | 377 | evtchn_op_t op = { 0 }; |
378 | int error; | | 378 | int error; |
379 | #endif | | 379 | #endif |
380 | hypervisor_mask_event(i); | | 380 | hypervisor_mask_event(i); |
381 | devevent[i] = NULL; | | 381 | devevent[i] = NULL; |
382 | #ifdef XEN3 | | 382 | #ifdef XEN3 |
| @@ -492,27 +492,27 @@ xenevt_fwrite(struct file *fp, off_t *of | | | @@ -492,27 +492,27 @@ xenevt_fwrite(struct file *fp, off_t *of |
492 | goto out; | | 492 | goto out; |
493 | for (i = 0; i < nentries; i++) { | | 493 | for (i = 0; i < nentries; i++) { |
494 | if (chans[i] < NR_EVENT_CHANNELS && | | 494 | if (chans[i] < NR_EVENT_CHANNELS && |
495 | devevent[chans[i]] == d) { | | 495 | devevent[chans[i]] == d) { |
496 | hypervisor_unmask_event(chans[i]); | | 496 | hypervisor_unmask_event(chans[i]); |
497 | } | | 497 | } |
498 | } | | 498 | } |
499 | out: | | 499 | out: |
500 | kmem_free(chans, nentries * sizeof(u_int16_t)); | | 500 | kmem_free(chans, nentries * sizeof(u_int16_t)); |
501 | return 0; | | 501 | return 0; |
502 | } | | 502 | } |
503 | | | 503 | |
504 | static int | | 504 | static int |
505 | xenevt_fioctl(struct file *fp, u_long cmd, void *addr, struct lwp *l) | | 505 | xenevt_fioctl(struct file *fp, u_long cmd, void *addr) |
506 | { | | 506 | { |
507 | struct xenevt_d *d = fp->f_data; | | 507 | struct xenevt_d *d = fp->f_data; |
508 | #ifdef XEN3 | | 508 | #ifdef XEN3 |
509 | evtchn_op_t op = { 0 }; | | 509 | evtchn_op_t op = { 0 }; |
510 | int error; | | 510 | int error; |
511 | #else | | 511 | #else |
512 | u_int *arg = addr; | | 512 | u_int *arg = addr; |
513 | #endif | | 513 | #endif |
514 | | | 514 | |
515 | switch(cmd) { | | 515 | switch(cmd) { |
516 | case EVTCHN_RESET: | | 516 | case EVTCHN_RESET: |
517 | #ifdef XEN3 | | 517 | #ifdef XEN3 |
518 | case IOCTL_EVTCHN_RESET: | | 518 | case IOCTL_EVTCHN_RESET: |
| @@ -612,33 +612,33 @@ xenevt_fioctl(struct file *fp, u_long cm | | | @@ -612,33 +612,33 @@ xenevt_fioctl(struct file *fp, u_long cm |
612 | default: | | 612 | default: |
613 | return EINVAL; | | 613 | return EINVAL; |
614 | } | | 614 | } |
615 | return 0; | | 615 | return 0; |
616 | } | | 616 | } |
617 | | | 617 | |
618 | /* | | 618 | /* |
619 | * Support for poll() system call | | 619 | * Support for poll() system call |
620 | * | | 620 | * |
621 | * Return true if the specific operation will not block indefinitely. | | 621 | * Return true if the specific operation will not block indefinitely. |
622 | */ | | 622 | */ |
623 | | | 623 | |
624 | static int | | 624 | static int |
625 | xenevt_fpoll(struct file *fp, int events, struct lwp *l) | | 625 | xenevt_fpoll(struct file *fp, int events) |
626 | { | | 626 | { |
627 | struct xenevt_d *d = fp->f_data; | | 627 | struct xenevt_d *d = fp->f_data; |
628 | int revents = events & (POLLOUT | POLLWRNORM); /* we can always write */ | | 628 | int revents = events & (POLLOUT | POLLWRNORM); /* we can always write */ |
629 | int s; | | 629 | int s; |
630 | | | 630 | |
631 | s = splsoftserial(); | | 631 | s = splsoftserial(); |
632 | simple_lock(&d->lock); | | 632 | simple_lock(&d->lock); |
633 | if (events & (POLLIN | POLLRDNORM)) { | | 633 | if (events & (POLLIN | POLLRDNORM)) { |
634 | if (d->ring_read != d->ring_write) { | | 634 | if (d->ring_read != d->ring_write) { |
635 | revents |= events & (POLLIN | POLLRDNORM); | | 635 | revents |= events & (POLLIN | POLLRDNORM); |
636 | } else { | | 636 | } else { |
637 | /* Record that someone is waiting */ | | 637 | /* Record that someone is waiting */ |
638 | selrecord(l, &d->sel); | | 638 | selrecord(curlwp, &d->sel); |
639 | } | | 639 | } |
640 | } | | 640 | } |
641 | simple_unlock(&d->lock); | | 641 | simple_unlock(&d->lock); |
642 | splx(s); | | 642 | splx(s); |
643 | return (revents); | | 643 | return (revents); |
644 | } | | 644 | } |