mmu.c 5.7 KB

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