Lines Matching full:u
95 static unsigned int evtchn_ring_offset(struct per_user_data *u, in evtchn_ring_offset() argument
98 return idx & (u->ring_size - 1); in evtchn_ring_offset()
101 static evtchn_port_t *evtchn_ring_entry(struct per_user_data *u, in evtchn_ring_entry() argument
104 return u->ring + evtchn_ring_offset(u, idx); in evtchn_ring_entry()
107 static int add_evtchn(struct per_user_data *u, struct user_evtchn *evtchn) in add_evtchn() argument
109 struct rb_node **new = &(u->evtchns.rb_node), *parent = NULL; in add_evtchn()
111 u->nr_evtchns++; in add_evtchn()
129 rb_insert_color(&evtchn->node, &u->evtchns); in add_evtchn()
134 static void del_evtchn(struct per_user_data *u, struct user_evtchn *evtchn) in del_evtchn() argument
136 u->nr_evtchns--; in del_evtchn()
137 rb_erase(&evtchn->node, &u->evtchns); in del_evtchn()
141 static struct user_evtchn *find_evtchn(struct per_user_data *u, in find_evtchn() argument
144 struct rb_node *node = u->evtchns.rb_node; in find_evtchn()
164 struct per_user_data *u = evtchn->user; in evtchn_interrupt() local
168 "Interrupt for port %u, but apparently not enabled; per-user %p\n", in evtchn_interrupt()
169 evtchn->port, u); in evtchn_interrupt()
173 spin_lock(&u->ring_prod_lock); in evtchn_interrupt()
175 prod = READ_ONCE(u->ring_prod); in evtchn_interrupt()
176 cons = READ_ONCE(u->ring_cons); in evtchn_interrupt()
178 if ((prod - cons) < u->ring_size) { in evtchn_interrupt()
179 *evtchn_ring_entry(u, prod) = evtchn->port; in evtchn_interrupt()
181 WRITE_ONCE(u->ring_prod, prod + 1); in evtchn_interrupt()
183 wake_up_interruptible(&u->evtchn_wait); in evtchn_interrupt()
184 kill_fasync(&u->evtchn_async_queue, in evtchn_interrupt()
188 u->ring_overflow = 1; in evtchn_interrupt()
190 spin_unlock(&u->ring_prod_lock); in evtchn_interrupt()
200 struct per_user_data *u = file->private_data; in evtchn_read() local
212 mutex_lock(&u->ring_cons_mutex); in evtchn_read()
215 if (u->ring_overflow) in evtchn_read()
218 c = READ_ONCE(u->ring_cons); in evtchn_read()
219 p = READ_ONCE(u->ring_prod); in evtchn_read()
223 mutex_unlock(&u->ring_cons_mutex); in evtchn_read()
228 rc = wait_event_interruptible(u->evtchn_wait, in evtchn_read()
229 READ_ONCE(u->ring_cons) != READ_ONCE(u->ring_prod)); in evtchn_read()
235 if (((c ^ p) & u->ring_size) != 0) { in evtchn_read()
236 bytes1 = (u->ring_size - evtchn_ring_offset(u, c)) * in evtchn_read()
238 bytes2 = evtchn_ring_offset(u, p) * sizeof(evtchn_port_t); in evtchn_read()
254 if (copy_to_user(buf, evtchn_ring_entry(u, c), bytes1) || in evtchn_read()
256 copy_to_user(&buf[bytes1], &u->ring[0], bytes2))) in evtchn_read()
259 WRITE_ONCE(u->ring_cons, c + (bytes1 + bytes2) / sizeof(evtchn_port_t)); in evtchn_read()
263 mutex_unlock(&u->ring_cons_mutex); in evtchn_read()
272 struct per_user_data *u = file->private_data; in evtchn_write() local
291 mutex_lock(&u->bind_mutex); in evtchn_write()
297 evtchn = find_evtchn(u, port); in evtchn_write()
304 mutex_unlock(&u->bind_mutex); in evtchn_write()
313 static int evtchn_resize_ring(struct per_user_data *u) in evtchn_resize_ring() argument
322 if (u->nr_evtchns <= u->ring_size) in evtchn_resize_ring()
325 if (u->ring_size == 0) in evtchn_resize_ring()
328 new_size = 2 * u->ring_size; in evtchn_resize_ring()
334 old_ring = u->ring; in evtchn_resize_ring()
340 mutex_lock(&u->ring_cons_mutex); in evtchn_resize_ring()
341 spin_lock_irq(&u->ring_prod_lock); in evtchn_resize_ring()
354 memcpy(new_ring, old_ring, u->ring_size * sizeof(*u->ring)); in evtchn_resize_ring()
355 memcpy(new_ring + u->ring_size, old_ring, in evtchn_resize_ring()
356 u->ring_size * sizeof(*u->ring)); in evtchn_resize_ring()
358 u->ring = new_ring; in evtchn_resize_ring()
359 u->ring_size = new_size; in evtchn_resize_ring()
361 spin_unlock_irq(&u->ring_prod_lock); in evtchn_resize_ring()
362 mutex_unlock(&u->ring_cons_mutex); in evtchn_resize_ring()
369 static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port, in evtchn_bind_to_user() argument
388 evtchn->user = u; in evtchn_bind_to_user()
392 rc = add_evtchn(u, evtchn); in evtchn_bind_to_user()
396 rc = evtchn_resize_ring(u); in evtchn_bind_to_user()
401 u->name, evtchn); in evtchn_bind_to_user()
413 del_evtchn(u, evtchn); in evtchn_bind_to_user()
417 static void evtchn_unbind_from_user(struct per_user_data *u, in evtchn_unbind_from_user() argument
426 del_evtchn(u, evtchn); in evtchn_unbind_from_user()
433 struct per_user_data *u = file->private_data; in evtchn_ioctl() local
437 mutex_lock(&u->bind_mutex); in evtchn_ioctl()
445 if (u->restrict_domid != UNRESTRICTED_DOMID) in evtchn_ioctl()
459 rc = evtchn_bind_to_user(u, bind_virq.port, false); in evtchn_ioctl()
474 if (u->restrict_domid != UNRESTRICTED_DOMID && in evtchn_ioctl()
475 u->restrict_domid != bind.remote_domain) in evtchn_ioctl()
485 rc = evtchn_bind_to_user(u, bind_interdomain.local_port, false); in evtchn_ioctl()
496 if (u->restrict_domid != UNRESTRICTED_DOMID) in evtchn_ioctl()
510 rc = evtchn_bind_to_user(u, alloc_unbound.port, false); in evtchn_ioctl()
529 evtchn = find_evtchn(u, unbind.port); in evtchn_ioctl()
534 evtchn_unbind_from_user(u, evtchn); in evtchn_ioctl()
548 evtchn = find_evtchn(u, bind.port); in evtchn_ioctl()
552 rc = evtchn_bind_to_user(u, bind.port, true); in evtchn_ioctl()
565 evtchn = find_evtchn(u, notify.port); in evtchn_ioctl()
575 mutex_lock(&u->ring_cons_mutex); in evtchn_ioctl()
576 spin_lock_irq(&u->ring_prod_lock); in evtchn_ioctl()
577 WRITE_ONCE(u->ring_cons, 0); in evtchn_ioctl()
578 WRITE_ONCE(u->ring_prod, 0); in evtchn_ioctl()
579 u->ring_overflow = 0; in evtchn_ioctl()
580 spin_unlock_irq(&u->ring_prod_lock); in evtchn_ioctl()
581 mutex_unlock(&u->ring_cons_mutex); in evtchn_ioctl()
590 if (u->restrict_domid != UNRESTRICTED_DOMID) in evtchn_ioctl()
601 u->restrict_domid = ierd.domid; in evtchn_ioctl()
611 mutex_unlock(&u->bind_mutex); in evtchn_ioctl()
619 struct per_user_data *u = file->private_data; in evtchn_poll() local
621 poll_wait(file, &u->evtchn_wait, wait); in evtchn_poll()
622 if (READ_ONCE(u->ring_cons) != READ_ONCE(u->ring_prod)) in evtchn_poll()
624 if (u->ring_overflow) in evtchn_poll()
631 struct per_user_data *u = filp->private_data; in evtchn_fasync() local
632 return fasync_helper(fd, filp, on, &u->evtchn_async_queue); in evtchn_fasync()
637 struct per_user_data *u; in evtchn_open() local
639 u = kzalloc(sizeof(*u), GFP_KERNEL); in evtchn_open()
640 if (u == NULL) in evtchn_open()
643 u->name = kasprintf(GFP_KERNEL, "evtchn:%s", current->comm); in evtchn_open()
644 if (u->name == NULL) { in evtchn_open()
645 kfree(u); in evtchn_open()
649 init_waitqueue_head(&u->evtchn_wait); in evtchn_open()
651 mutex_init(&u->bind_mutex); in evtchn_open()
652 mutex_init(&u->ring_cons_mutex); in evtchn_open()
653 spin_lock_init(&u->ring_prod_lock); in evtchn_open()
655 u->restrict_domid = UNRESTRICTED_DOMID; in evtchn_open()
657 filp->private_data = u; in evtchn_open()
664 struct per_user_data *u = filp->private_data; in evtchn_release() local
667 while ((node = u->evtchns.rb_node)) { in evtchn_release()
672 evtchn_unbind_from_user(u, evtchn); in evtchn_release()
675 evtchn_free_ring(u->ring); in evtchn_release()
676 kfree(u->name); in evtchn_release()
677 kfree(u); in evtchn_release()