hypervisor.c 5.2 KB

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