mmu.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #define pr_fmt(fmt) "Hyper-V: " fmt
  2. #include <linux/hyperv.h>
  3. #include <linux/log2.h>
  4. #include <linux/slab.h>
  5. #include <linux/types.h>
  6. #include <asm/fpu/api.h>
  7. #include <asm/mshyperv.h>
  8. #include <asm/msr.h>
  9. #include <asm/tlbflush.h>
  10. #define CREATE_TRACE_POINTS
  11. #include <asm/trace/hyperv.h>
  12. /* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
  13. struct hv_flush_pcpu {
  14. u64 address_space;
  15. u64 flags;
  16. u64 processor_mask;
  17. u64 gva_list[];
  18. };
  19. /* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */
  20. struct hv_flush_pcpu_ex {
  21. u64 address_space;
  22. u64 flags;
  23. struct hv_vpset hv_vp_set;
  24. u64 gva_list[];
  25. };
  26. /* Each gva in gva_list encodes up to 4096 pages to flush */
  27. #define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE)
  28. /*
  29. * Fills in gva_list starting from offset. Returns the number of items added.
  30. */
  31. static inline int fill_gva_list(u64 gva_list[], int offset,
  32. unsigned long start, unsigned long end)
  33. {
  34. int gva_n = offset;
  35. unsigned long cur = start, diff;
  36. do {
  37. diff = end > cur ? end - cur : 0;
  38. gva_list[gva_n] = cur & PAGE_MASK;
  39. /*
  40. * Lower 12 bits encode the number of additional
  41. * pages to flush (in addition to the 'cur' page).
  42. */
  43. if (diff >= HV_TLB_FLUSH_UNIT)
  44. gva_list[gva_n] |= ~PAGE_MASK;
  45. else if (diff)
  46. gva_list[gva_n] |= (diff - 1) >> PAGE_SHIFT;
  47. cur += HV_TLB_FLUSH_UNIT;
  48. gva_n++;
  49. } while (cur < end);
  50. return gva_n - offset;
  51. }
  52. static void hyperv_flush_tlb_others(const struct cpumask *cpus,
  53. const struct flush_tlb_info *info)
  54. {
  55. int cpu, vcpu, gva_n, max_gvas;
  56. struct hv_flush_pcpu **flush_pcpu;
  57. struct hv_flush_pcpu *flush;
  58. u64 status = U64_MAX;
  59. unsigned long flags;
  60. trace_hyperv_mmu_flush_tlb_others(cpus, info);
  61. if (!hv_hypercall_pg)
  62. goto do_native;
  63. if (cpumask_empty(cpus))
  64. return;
  65. local_irq_save(flags);
  66. flush_pcpu = (struct hv_flush_pcpu **)
  67. this_cpu_ptr(hyperv_pcpu_input_arg);
  68. flush = *flush_pcpu;
  69. if (unlikely(!flush)) {
  70. local_irq_restore(flags);
  71. goto do_native;
  72. }
  73. if (info->mm) {
  74. /*
  75. * AddressSpace argument must match the CR3 with PCID bits
  76. * stripped out.
  77. */
  78. flush->address_space = virt_to_phys(info->mm->pgd);
  79. flush->address_space &= CR3_ADDR_MASK;
  80. flush->flags = 0;
  81. } else {
  82. flush->address_space = 0;
  83. flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES;
  84. }
  85. flush->processor_mask = 0;
  86. if (cpumask_equal(cpus, cpu_present_mask)) {
  87. flush->flags |= HV_FLUSH_ALL_PROCESSORS;
  88. } else {
  89. for_each_cpu(cpu, cpus) {
  90. vcpu = hv_cpu_number_to_vp_number(cpu);
  91. if (vcpu >= 64)
  92. goto do_native;
  93. __set_bit(vcpu, (unsigned long *)
  94. &flush->processor_mask);
  95. }
  96. }
  97. /*
  98. * We can flush not more than max_gvas with one hypercall. Flush the
  99. * whole address space if we were asked to do more.
  100. */
  101. max_gvas = (PAGE_SIZE - sizeof(*flush)) / sizeof(flush->gva_list[0]);
  102. if (info->end == TLB_FLUSH_ALL) {
  103. flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY;
  104. status = hv_do_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE,
  105. flush, NULL);
  106. } else if (info->end &&
  107. ((info->end - info->start)/HV_TLB_FLUSH_UNIT) > max_gvas) {
  108. status = hv_do_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE,
  109. flush, NULL);
  110. } else {
  111. gva_n = fill_gva_list(flush->gva_list, 0,
  112. info->start, info->end);
  113. status = hv_do_rep_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST,
  114. gva_n, 0, flush, NULL);
  115. }
  116. local_irq_restore(flags);
  117. if (!(status & HV_HYPERCALL_RESULT_MASK))
  118. return;
  119. do_native:
  120. native_flush_tlb_others(cpus, info);
  121. }
  122. static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
  123. const struct flush_tlb_info *info)
  124. {
  125. int nr_bank = 0, max_gvas, gva_n;
  126. struct hv_flush_pcpu_ex **flush_pcpu;
  127. struct hv_flush_pcpu_ex *flush;
  128. u64 status = U64_MAX;
  129. unsigned long flags;
  130. trace_hyperv_mmu_flush_tlb_others(cpus, info);
  131. if (!hv_hypercall_pg)
  132. goto do_native;
  133. if (cpumask_empty(cpus))
  134. return;
  135. local_irq_save(flags);
  136. flush_pcpu = (struct hv_flush_pcpu_ex **)
  137. this_cpu_ptr(hyperv_pcpu_input_arg);
  138. flush = *flush_pcpu;
  139. if (unlikely(!flush)) {
  140. local_irq_restore(flags);
  141. goto do_native;
  142. }
  143. if (info->mm) {
  144. /*
  145. * AddressSpace argument must match the CR3 with PCID bits
  146. * stripped out.
  147. */
  148. flush->address_space = virt_to_phys(info->mm->pgd);
  149. flush->address_space &= CR3_ADDR_MASK;
  150. flush->flags = 0;
  151. } else {
  152. flush->address_space = 0;
  153. flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES;
  154. }
  155. flush->hv_vp_set.valid_bank_mask = 0;
  156. if (!cpumask_equal(cpus, cpu_present_mask)) {
  157. flush->hv_vp_set.format = HV_GENERIC_SET_SPARSE_4K;
  158. nr_bank = cpumask_to_vpset(&(flush->hv_vp_set), cpus);
  159. }
  160. if (!nr_bank) {
  161. flush->hv_vp_set.format = HV_GENERIC_SET_ALL;
  162. flush->flags |= HV_FLUSH_ALL_PROCESSORS;
  163. }
  164. /*
  165. * We can flush not more than max_gvas with one hypercall. Flush the
  166. * whole address space if we were asked to do more.
  167. */
  168. max_gvas =
  169. (PAGE_SIZE - sizeof(*flush) - nr_bank *
  170. sizeof(flush->hv_vp_set.bank_contents[0])) /
  171. sizeof(flush->gva_list[0]);
  172. if (info->end == TLB_FLUSH_ALL) {
  173. flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY;
  174. status = hv_do_rep_hypercall(
  175. HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
  176. 0, nr_bank, flush, NULL);
  177. } else if (info->end &&
  178. ((info->end - info->start)/HV_TLB_FLUSH_UNIT) > max_gvas) {
  179. status = hv_do_rep_hypercall(
  180. HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
  181. 0, nr_bank, flush, NULL);
  182. } else {
  183. gva_n = fill_gva_list(flush->gva_list, nr_bank,
  184. info->start, info->end);
  185. status = hv_do_rep_hypercall(
  186. HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX,
  187. gva_n, nr_bank, flush, NULL);
  188. }
  189. local_irq_restore(flags);
  190. if (!(status & HV_HYPERCALL_RESULT_MASK))
  191. return;
  192. do_native:
  193. native_flush_tlb_others(cpus, info);
  194. }
  195. void hyperv_setup_mmu_ops(void)
  196. {
  197. if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
  198. return;
  199. if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) {
  200. pr_info("Using hypercall for remote TLB flush\n");
  201. pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others;
  202. } else {
  203. pr_info("Using ext hypercall for remote TLB flush\n");
  204. pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others_ex;
  205. }
  206. }