hypervisor.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // SPDX-License-Identifier: MIT License
  2. /*
  3. * hypervisor.c
  4. *
  5. * Communication to/from hypervisor.
  6. *
  7. * Copyright (c) 2002-2003, K A Fraser
  8. * Copyright (c) 2005, Grzegorz Milos, gm281@cam.ac.uk,Intel Research Cambridge
  9. * Copyright (c) 2020, EPAM Systems Inc.
  10. */
  11. #include <common.h>
  12. #include <cpu_func.h>
  13. #include <log.h>
  14. #include <memalign.h>
  15. #include <asm/io.h>
  16. #include <asm/armv8/mmu.h>
  17. #include <asm/xen/system.h>
  18. #include <linux/bug.h>
  19. #include <xen/hvm.h>
  20. #include <xen/events.h>
  21. #include <xen/gnttab.h>
  22. #include <xen/xenbus.h>
  23. #include <xen/interface/memory.h>
  24. #define active_evtchns(cpu, sh, idx) \
  25. ((sh)->evtchn_pending[idx] & \
  26. ~(sh)->evtchn_mask[idx])
  27. int in_callback;
  28. /*
  29. * Shared page for communicating with the hypervisor.
  30. * Events flags go here, for example.
  31. */
  32. struct shared_info *HYPERVISOR_shared_info;
  33. static const char *param_name(int op)
  34. {
  35. #define PARAM(x)[HVM_PARAM_##x] = #x
  36. static const char *const names[] = {
  37. PARAM(CALLBACK_IRQ),
  38. PARAM(STORE_PFN),
  39. PARAM(STORE_EVTCHN),
  40. PARAM(PAE_ENABLED),
  41. PARAM(IOREQ_PFN),
  42. PARAM(VPT_ALIGN),
  43. PARAM(CONSOLE_PFN),
  44. PARAM(CONSOLE_EVTCHN),
  45. };
  46. #undef PARAM
  47. if (op >= ARRAY_SIZE(names))
  48. return "unknown";
  49. if (!names[op])
  50. return "reserved";
  51. return names[op];
  52. }
  53. /**
  54. * hvm_get_parameter_maintain_dcache - function to obtain a HVM
  55. * parameter value.
  56. * @idx: HVM parameter index
  57. * @value: Value to fill in
  58. *
  59. * According to Xen on ARM ABI (xen/include/public/arch-arm.h):
  60. * all memory which is shared with other entities in the system
  61. * (including the hypervisor and other guests) must reside in memory
  62. * which is mapped as Normal Inner Write-Back Outer Write-Back
  63. * Inner-Shareable.
  64. *
  65. * Thus, page attributes must be equally set for all the entities
  66. * working with that page.
  67. *
  68. * Before MMU setup the data cache is turned off, so it means that
  69. * manual data cache maintenance is required, because of the
  70. * difference of page attributes.
  71. */
  72. int hvm_get_parameter_maintain_dcache(int idx, uint64_t *value)
  73. {
  74. struct xen_hvm_param xhv;
  75. int ret;
  76. invalidate_dcache_range((unsigned long)&xhv,
  77. (unsigned long)&xhv + sizeof(xhv));
  78. xhv.domid = DOMID_SELF;
  79. xhv.index = idx;
  80. invalidate_dcache_range((unsigned long)&xhv,
  81. (unsigned long)&xhv + sizeof(xhv));
  82. ret = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
  83. if (ret < 0) {
  84. pr_err("Cannot get hvm parameter %s (%d): %d!\n",
  85. param_name(idx), idx, ret);
  86. BUG();
  87. }
  88. invalidate_dcache_range((unsigned long)&xhv,
  89. (unsigned long)&xhv + sizeof(xhv));
  90. *value = xhv.value;
  91. return ret;
  92. }
  93. int hvm_get_parameter(int idx, uint64_t *value)
  94. {
  95. struct xen_hvm_param xhv;
  96. int ret;
  97. xhv.domid = DOMID_SELF;
  98. xhv.index = idx;
  99. ret = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
  100. if (ret < 0) {
  101. pr_err("Cannot get hvm parameter %s (%d): %d!\n",
  102. param_name(idx), idx, ret);
  103. BUG();
  104. }
  105. *value = xhv.value;
  106. return ret;
  107. }
  108. struct shared_info *map_shared_info(void *p)
  109. {
  110. struct xen_add_to_physmap xatp;
  111. HYPERVISOR_shared_info = (struct shared_info *)memalign(PAGE_SIZE,
  112. PAGE_SIZE);
  113. if (!HYPERVISOR_shared_info)
  114. BUG();
  115. xatp.domid = DOMID_SELF;
  116. xatp.idx = 0;
  117. xatp.space = XENMAPSPACE_shared_info;
  118. xatp.gpfn = virt_to_pfn(HYPERVISOR_shared_info);
  119. if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp) != 0)
  120. BUG();
  121. return HYPERVISOR_shared_info;
  122. }
  123. void do_hypervisor_callback(struct pt_regs *regs)
  124. {
  125. unsigned long l1, l2, l1i, l2i;
  126. unsigned int port;
  127. int cpu = 0;
  128. struct shared_info *s = HYPERVISOR_shared_info;
  129. struct vcpu_info *vcpu_info = &s->vcpu_info[cpu];
  130. in_callback = 1;
  131. vcpu_info->evtchn_upcall_pending = 0;
  132. l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
  133. while (l1 != 0) {
  134. l1i = __ffs(l1);
  135. l1 &= ~(1UL << l1i);
  136. while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
  137. l2i = __ffs(l2);
  138. l2 &= ~(1UL << l2i);
  139. port = (l1i * (sizeof(unsigned long) * 8)) + l2i;
  140. do_event(port, regs);
  141. }
  142. }
  143. in_callback = 0;
  144. }
  145. void force_evtchn_callback(void)
  146. {
  147. #ifdef XEN_HAVE_PV_UPCALL_MASK
  148. int save;
  149. #endif
  150. struct vcpu_info *vcpu;
  151. vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()];
  152. #ifdef XEN_HAVE_PV_UPCALL_MASK
  153. save = vcpu->evtchn_upcall_mask;
  154. #endif
  155. while (vcpu->evtchn_upcall_pending) {
  156. #ifdef XEN_HAVE_PV_UPCALL_MASK
  157. vcpu->evtchn_upcall_mask = 1;
  158. #endif
  159. do_hypervisor_callback(NULL);
  160. #ifdef XEN_HAVE_PV_UPCALL_MASK
  161. vcpu->evtchn_upcall_mask = save;
  162. #endif
  163. };
  164. }
  165. void mask_evtchn(uint32_t port)
  166. {
  167. struct shared_info *s = HYPERVISOR_shared_info;
  168. synch_set_bit(port, &s->evtchn_mask[0]);
  169. }
  170. void unmask_evtchn(uint32_t port)
  171. {
  172. struct shared_info *s = HYPERVISOR_shared_info;
  173. struct vcpu_info *vcpu_info = &s->vcpu_info[smp_processor_id()];
  174. synch_clear_bit(port, &s->evtchn_mask[0]);
  175. /*
  176. * Just like a real IO-APIC we 'lose the interrupt edge' if the
  177. * channel is masked.
  178. */
  179. if (synch_test_bit(port, &s->evtchn_pending[0]) &&
  180. !synch_test_and_set_bit(port / (sizeof(unsigned long) * 8),
  181. &vcpu_info->evtchn_pending_sel)) {
  182. vcpu_info->evtchn_upcall_pending = 1;
  183. #ifdef XEN_HAVE_PV_UPCALL_MASK
  184. if (!vcpu_info->evtchn_upcall_mask)
  185. #endif
  186. force_evtchn_callback();
  187. }
  188. }
  189. void clear_evtchn(uint32_t port)
  190. {
  191. struct shared_info *s = HYPERVISOR_shared_info;
  192. synch_clear_bit(port, &s->evtchn_pending[0]);
  193. }
  194. void xen_init(void)
  195. {
  196. debug("%s\n", __func__);
  197. map_shared_info(NULL);
  198. init_events();
  199. init_xenbus();
  200. init_gnttab();
  201. }