events.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
  4. * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
  5. * (C) 2020 - EPAM Systems Inc.
  6. *
  7. * File: events.c [1]
  8. * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
  9. * Changes: Grzegorz Milos (gm281@cam.ac.uk)
  10. *
  11. * Date: Jul 2003, changes Jun 2005
  12. *
  13. * Description: Deals with events received on event channels
  14. *
  15. * [1] - http://xenbits.xen.org/gitweb/?p=mini-os.git;a=summary
  16. */
  17. #include <common.h>
  18. #include <log.h>
  19. #include <asm/io.h>
  20. #include <asm/xen/system.h>
  21. #include <xen/events.h>
  22. #include <xen/hvm.h>
  23. #if IS_ENABLED(CONFIG_XEN_SERIAL)
  24. extern u32 console_evtchn;
  25. #endif /* IS_ENABLED(CONFIG_XEN_SERIAL) */
  26. #define NR_EVS 1024
  27. /**
  28. * struct _ev_action - represents a event handler.
  29. *
  30. * Chaining or sharing is not allowed
  31. */
  32. struct _ev_action {
  33. void (*handler)(evtchn_port_t port, struct pt_regs *regs, void *data);
  34. void *data;
  35. u32 count;
  36. };
  37. static struct _ev_action ev_actions[NR_EVS];
  38. void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data);
  39. static unsigned long bound_ports[NR_EVS / (8 * sizeof(unsigned long))];
  40. void unbind_all_ports(void)
  41. {
  42. int i;
  43. int cpu = 0;
  44. struct shared_info *s = HYPERVISOR_shared_info;
  45. struct vcpu_info *vcpu_info = &s->vcpu_info[cpu];
  46. for (i = 0; i < NR_EVS; i++) {
  47. #if IS_ENABLED(CONFIG_XEN_SERIAL)
  48. if (i == console_evtchn)
  49. continue;
  50. #endif /* IS_ENABLED(CONFIG_XEN_SERIAL) */
  51. if (test_and_clear_bit(i, bound_ports)) {
  52. printf("port %d still bound!\n", i);
  53. unbind_evtchn(i);
  54. }
  55. }
  56. vcpu_info->evtchn_upcall_pending = 0;
  57. vcpu_info->evtchn_pending_sel = 0;
  58. }
  59. int do_event(evtchn_port_t port, struct pt_regs *regs)
  60. {
  61. struct _ev_action *action;
  62. clear_evtchn(port);
  63. if (port >= NR_EVS) {
  64. printk("WARN: do_event(): Port number too large: %d\n", port);
  65. return 1;
  66. }
  67. action = &ev_actions[port];
  68. action->count++;
  69. /* call the handler */
  70. action->handler(port, regs, action->data);
  71. return 1;
  72. }
  73. evtchn_port_t bind_evtchn(evtchn_port_t port,
  74. void (*handler)(evtchn_port_t, struct pt_regs *, void *),
  75. void *data)
  76. {
  77. if (ev_actions[port].handler != default_handler)
  78. printf("WARN: Handler for port %d already registered, replacing\n",
  79. port);
  80. ev_actions[port].data = data;
  81. wmb();
  82. ev_actions[port].handler = handler;
  83. synch_set_bit(port, bound_ports);
  84. return port;
  85. }
  86. /**
  87. * unbind_evtchn() - Unbind event channel for selected port
  88. */
  89. void unbind_evtchn(evtchn_port_t port)
  90. {
  91. struct evtchn_close close;
  92. int rc;
  93. if (ev_actions[port].handler == default_handler)
  94. debug("Default handler for port %d when unbinding\n", port);
  95. mask_evtchn(port);
  96. clear_evtchn(port);
  97. ev_actions[port].handler = default_handler;
  98. wmb();
  99. ev_actions[port].data = NULL;
  100. synch_clear_bit(port, bound_ports);
  101. close.port = port;
  102. rc = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
  103. if (rc)
  104. printf("WARN: close_port %d failed rc=%d. ignored\n", port, rc);
  105. }
  106. void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
  107. {
  108. debug("[Port %d] - event received\n", port);
  109. }
  110. /**
  111. * evtchn_alloc_unbound() - Create a port available to the pal for
  112. * exchanging notifications.
  113. *
  114. * Unfortunate confusion of terminology: the port is unbound as far
  115. * as Xen is concerned, but we automatically bind a handler to it.
  116. *
  117. * Return: The result of the hypervisor call.
  118. */
  119. int evtchn_alloc_unbound(domid_t pal,
  120. void (*handler)(evtchn_port_t, struct pt_regs *, void *),
  121. void *data, evtchn_port_t *port)
  122. {
  123. int rc;
  124. struct evtchn_alloc_unbound op;
  125. op.dom = DOMID_SELF;
  126. op.remote_dom = pal;
  127. rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
  128. if (rc) {
  129. printf("ERROR: alloc_unbound failed with rc=%d", rc);
  130. return rc;
  131. }
  132. if (!handler)
  133. handler = default_handler;
  134. *port = bind_evtchn(op.port, handler, data);
  135. return rc;
  136. }
  137. /**
  138. * eventchn_poll() - Event channel polling function
  139. *
  140. * Check and process any pending events
  141. */
  142. void eventchn_poll(void)
  143. {
  144. do_hypervisor_callback(NULL);
  145. }
  146. /**
  147. * init_events() - Initialize event handler
  148. *
  149. * Initially all events are without a handler and disabled.
  150. */
  151. void init_events(void)
  152. {
  153. int i;
  154. debug("%s\n", __func__);
  155. for (i = 0; i < NR_EVS; i++) {
  156. ev_actions[i].handler = default_handler;
  157. mask_evtchn(i);
  158. }
  159. }
  160. /**
  161. * fini_events() - Close all ports
  162. *
  163. * Mask and clear event channels. Close port using EVTCHNOP_close
  164. * hypercall.
  165. */
  166. void fini_events(void)
  167. {
  168. debug("%s\n", __func__);
  169. /* Dealloc all events */
  170. unbind_all_ports();
  171. }