Lines Matching full:u

96 static unsigned int evtchn_ring_offset(struct per_user_data *u,  in evtchn_ring_offset()  argument
99 return idx & (u->ring_size - 1); in evtchn_ring_offset()
102 static evtchn_port_t *evtchn_ring_entry(struct per_user_data *u, in evtchn_ring_entry() argument
105 return u->ring + evtchn_ring_offset(u, idx); in evtchn_ring_entry()
108 static int add_evtchn(struct per_user_data *u, struct user_evtchn *evtchn) in add_evtchn() argument
110 struct rb_node **new = &(u->evtchns.rb_node), *parent = NULL; in add_evtchn()
112 u->nr_evtchns++; in add_evtchn()
130 rb_insert_color(&evtchn->node, &u->evtchns); in add_evtchn()
135 static void del_evtchn(struct per_user_data *u, struct user_evtchn *evtchn) in del_evtchn() argument
137 u->nr_evtchns--; in del_evtchn()
138 rb_erase(&evtchn->node, &u->evtchns); in del_evtchn()
142 static struct user_evtchn *find_evtchn(struct per_user_data *u, in find_evtchn() argument
145 struct rb_node *node = u->evtchns.rb_node; in find_evtchn()
165 struct per_user_data *u = evtchn->user; in evtchn_interrupt() local
173 "Interrupt for port %u, but apparently not enabled; per-user %p\n", in evtchn_interrupt()
174 evtchn->port, u); in evtchn_interrupt()
178 spin_lock(&u->ring_prod_lock); in evtchn_interrupt()
180 prod = READ_ONCE(u->ring_prod); in evtchn_interrupt()
181 cons = READ_ONCE(u->ring_cons); in evtchn_interrupt()
183 if ((prod - cons) < u->ring_size) { in evtchn_interrupt()
184 *evtchn_ring_entry(u, prod) = evtchn->port; in evtchn_interrupt()
186 WRITE_ONCE(u->ring_prod, prod + 1); in evtchn_interrupt()
188 wake_up_interruptible(&u->evtchn_wait); in evtchn_interrupt()
189 kill_fasync(&u->evtchn_async_queue, in evtchn_interrupt()
193 u->ring_overflow = 1; in evtchn_interrupt()
195 spin_unlock(&u->ring_prod_lock); in evtchn_interrupt()
205 struct per_user_data *u = file->private_data; in evtchn_read() local
217 mutex_lock(&u->ring_cons_mutex); in evtchn_read()
220 if (u->ring_overflow) in evtchn_read()
223 c = READ_ONCE(u->ring_cons); in evtchn_read()
224 p = READ_ONCE(u->ring_prod); in evtchn_read()
228 mutex_unlock(&u->ring_cons_mutex); in evtchn_read()
233 rc = wait_event_interruptible(u->evtchn_wait, in evtchn_read()
234 READ_ONCE(u->ring_cons) != READ_ONCE(u->ring_prod)); in evtchn_read()
240 if (((c ^ p) & u->ring_size) != 0) { in evtchn_read()
241 bytes1 = (u->ring_size - evtchn_ring_offset(u, c)) * in evtchn_read()
243 bytes2 = evtchn_ring_offset(u, p) * sizeof(evtchn_port_t); in evtchn_read()
259 if (copy_to_user(buf, evtchn_ring_entry(u, c), bytes1) || in evtchn_read()
261 copy_to_user(&buf[bytes1], &u->ring[0], bytes2))) in evtchn_read()
264 WRITE_ONCE(u->ring_cons, c + (bytes1 + bytes2) / sizeof(evtchn_port_t)); in evtchn_read()
268 mutex_unlock(&u->ring_cons_mutex); in evtchn_read()
277 struct per_user_data *u = file->private_data; in evtchn_write() local
296 mutex_lock(&u->bind_mutex); in evtchn_write()
302 evtchn = find_evtchn(u, port); in evtchn_write()
309 mutex_unlock(&u->bind_mutex); in evtchn_write()
318 static int evtchn_resize_ring(struct per_user_data *u) in evtchn_resize_ring() argument
327 if (u->nr_evtchns <= u->ring_size) in evtchn_resize_ring()
330 if (u->ring_size == 0) in evtchn_resize_ring()
333 new_size = 2 * u->ring_size; in evtchn_resize_ring()
339 old_ring = u->ring; in evtchn_resize_ring()
345 mutex_lock(&u->ring_cons_mutex); in evtchn_resize_ring()
346 spin_lock_irq(&u->ring_prod_lock); in evtchn_resize_ring()
359 memcpy(new_ring, old_ring, u->ring_size * sizeof(*u->ring)); in evtchn_resize_ring()
360 memcpy(new_ring + u->ring_size, old_ring, in evtchn_resize_ring()
361 u->ring_size * sizeof(*u->ring)); in evtchn_resize_ring()
363 u->ring = new_ring; in evtchn_resize_ring()
364 u->ring_size = new_size; in evtchn_resize_ring()
366 spin_unlock_irq(&u->ring_prod_lock); in evtchn_resize_ring()
367 mutex_unlock(&u->ring_cons_mutex); in evtchn_resize_ring()
374 static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port, in evtchn_bind_to_user() argument
393 evtchn->user = u; in evtchn_bind_to_user()
397 rc = add_evtchn(u, evtchn); in evtchn_bind_to_user()
401 rc = evtchn_resize_ring(u); in evtchn_bind_to_user()
406 u->name, evtchn); in evtchn_bind_to_user()
418 del_evtchn(u, evtchn); in evtchn_bind_to_user()
422 static void evtchn_unbind_from_user(struct per_user_data *u, in evtchn_unbind_from_user() argument
432 del_evtchn(u, evtchn); in evtchn_unbind_from_user()
439 struct per_user_data *u = file->private_data; in evtchn_ioctl() local
443 mutex_lock(&u->bind_mutex); in evtchn_ioctl()
451 if (u->restrict_domid != UNRESTRICTED_DOMID) in evtchn_ioctl()
465 rc = evtchn_bind_to_user(u, bind_virq.port, false); in evtchn_ioctl()
480 if (u->restrict_domid != UNRESTRICTED_DOMID && in evtchn_ioctl()
481 u->restrict_domid != bind.remote_domain) in evtchn_ioctl()
491 rc = evtchn_bind_to_user(u, bind_interdomain.local_port, false); in evtchn_ioctl()
502 if (u->restrict_domid != UNRESTRICTED_DOMID) in evtchn_ioctl()
516 rc = evtchn_bind_to_user(u, alloc_unbound.port, false); in evtchn_ioctl()
535 evtchn = find_evtchn(u, unbind.port); in evtchn_ioctl()
540 evtchn_unbind_from_user(u, evtchn); in evtchn_ioctl()
554 evtchn = find_evtchn(u, bind.port); in evtchn_ioctl()
558 rc = evtchn_bind_to_user(u, bind.port, true); in evtchn_ioctl()
571 evtchn = find_evtchn(u, notify.port); in evtchn_ioctl()
581 mutex_lock(&u->ring_cons_mutex); in evtchn_ioctl()
582 spin_lock_irq(&u->ring_prod_lock); in evtchn_ioctl()
583 WRITE_ONCE(u->ring_cons, 0); in evtchn_ioctl()
584 WRITE_ONCE(u->ring_prod, 0); in evtchn_ioctl()
585 u->ring_overflow = 0; in evtchn_ioctl()
586 spin_unlock_irq(&u->ring_prod_lock); in evtchn_ioctl()
587 mutex_unlock(&u->ring_cons_mutex); in evtchn_ioctl()
596 if (u->restrict_domid != UNRESTRICTED_DOMID) in evtchn_ioctl()
607 u->restrict_domid = ierd.domid; in evtchn_ioctl()
617 mutex_unlock(&u->bind_mutex); in evtchn_ioctl()
625 struct per_user_data *u = file->private_data; in evtchn_poll() local
627 poll_wait(file, &u->evtchn_wait, wait); in evtchn_poll()
628 if (READ_ONCE(u->ring_cons) != READ_ONCE(u->ring_prod)) in evtchn_poll()
630 if (u->ring_overflow) in evtchn_poll()
637 struct per_user_data *u = filp->private_data; in evtchn_fasync() local
638 return fasync_helper(fd, filp, on, &u->evtchn_async_queue); in evtchn_fasync()
643 struct per_user_data *u; in evtchn_open() local
645 u = kzalloc(sizeof(*u), GFP_KERNEL); in evtchn_open()
646 if (u == NULL) in evtchn_open()
649 u->name = kasprintf(GFP_KERNEL, "evtchn:%s", current->comm); in evtchn_open()
650 if (u->name == NULL) { in evtchn_open()
651 kfree(u); in evtchn_open()
655 init_waitqueue_head(&u->evtchn_wait); in evtchn_open()
657 mutex_init(&u->bind_mutex); in evtchn_open()
658 mutex_init(&u->ring_cons_mutex); in evtchn_open()
659 spin_lock_init(&u->ring_prod_lock); in evtchn_open()
661 u->restrict_domid = UNRESTRICTED_DOMID; in evtchn_open()
663 filp->private_data = u; in evtchn_open()
670 struct per_user_data *u = filp->private_data; in evtchn_release() local
673 while ((node = u->evtchns.rb_node)) { in evtchn_release()
678 evtchn_unbind_from_user(u, evtchn); in evtchn_release()
681 evtchn_free_ring(u->ring); in evtchn_release()
682 kfree(u->name); in evtchn_release()
683 kfree(u); in evtchn_release()