blob: 51b44be03f506fdf2d2e5760eee1b81ed19a6d3e [file] [log] [blame]
Vitaly Kuznetsov2ffd9e32017-08-02 18:09:19 +02001#define pr_fmt(fmt) "Hyper-V: " fmt
2
3#include <linux/hyperv.h>
4#include <linux/log2.h>
5#include <linux/slab.h>
6#include <linux/types.h>
7
8#include <asm/fpu/api.h>
9#include <asm/mshyperv.h>
10#include <asm/msr.h>
11#include <asm/tlbflush.h>
12
13/* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
14struct hv_flush_pcpu {
15 u64 address_space;
16 u64 flags;
17 u64 processor_mask;
18 u64 gva_list[];
19};
20
Vitaly Kuznetsov628f54c2017-08-02 18:09:20 +020021/* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */
22struct hv_flush_pcpu_ex {
23 u64 address_space;
24 u64 flags;
25 struct {
26 u64 format;
27 u64 valid_bank_mask;
28 u64 bank_contents[];
29 } hv_vp_set;
30 u64 gva_list[];
31};
32
Vitaly Kuznetsov2ffd9e32017-08-02 18:09:19 +020033/* Each gva in gva_list encodes up to 4096 pages to flush */
34#define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE)
35
36static struct hv_flush_pcpu __percpu *pcpu_flush;
37
Vitaly Kuznetsov628f54c2017-08-02 18:09:20 +020038static struct hv_flush_pcpu_ex __percpu *pcpu_flush_ex;
39
Vitaly Kuznetsov2ffd9e32017-08-02 18:09:19 +020040/*
41 * Fills in gva_list starting from offset. Returns the number of items added.
42 */
43static inline int fill_gva_list(u64 gva_list[], int offset,
44 unsigned long start, unsigned long end)
45{
46 int gva_n = offset;
47 unsigned long cur = start, diff;
48
49 do {
50 diff = end > cur ? end - cur : 0;
51
52 gva_list[gva_n] = cur & PAGE_MASK;
53 /*
54 * Lower 12 bits encode the number of additional
55 * pages to flush (in addition to the 'cur' page).
56 */
57 if (diff >= HV_TLB_FLUSH_UNIT)
58 gva_list[gva_n] |= ~PAGE_MASK;
59 else if (diff)
60 gva_list[gva_n] |= (diff - 1) >> PAGE_SHIFT;
61
62 cur += HV_TLB_FLUSH_UNIT;
63 gva_n++;
64
65 } while (cur < end);
66
67 return gva_n - offset;
68}
69
Vitaly Kuznetsov628f54c2017-08-02 18:09:20 +020070/* Return the number of banks in the resulting vp_set */
71static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush,
72 const struct cpumask *cpus)
73{
74 int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;
75
76 /*
77 * Some banks may end up being empty but this is acceptable.
78 */
79 for_each_cpu(cpu, cpus) {
80 vcpu = hv_cpu_number_to_vp_number(cpu);
81 vcpu_bank = vcpu / 64;
82 vcpu_offset = vcpu % 64;
83
84 /* valid_bank_mask can represent up to 64 banks */
85 if (vcpu_bank >= 64)
86 return 0;
87
88 __set_bit(vcpu_offset, (unsigned long *)
89 &flush->hv_vp_set.bank_contents[vcpu_bank]);
90 if (vcpu_bank >= nr_bank)
91 nr_bank = vcpu_bank + 1;
92 }
93 flush->hv_vp_set.valid_bank_mask = GENMASK_ULL(nr_bank - 1, 0);
94
95 return nr_bank;
96}
97
Vitaly Kuznetsov2ffd9e32017-08-02 18:09:19 +020098static void hyperv_flush_tlb_others(const struct cpumask *cpus,
99 const struct flush_tlb_info *info)
100{
101 int cpu, vcpu, gva_n, max_gvas;
102 struct hv_flush_pcpu *flush;
103 u64 status = U64_MAX;
104 unsigned long flags;
105
106 if (!pcpu_flush || !hv_hypercall_pg)
107 goto do_native;
108
109 if (cpumask_empty(cpus))
110 return;
111
112 local_irq_save(flags);
113
114 flush = this_cpu_ptr(pcpu_flush);
115
116 if (info->mm) {
117 flush->address_space = virt_to_phys(info->mm->pgd);
118 flush->flags = 0;
119 } else {
120 flush->address_space = 0;
121 flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES;
122 }
123
124 flush->processor_mask = 0;
125 if (cpumask_equal(cpus, cpu_present_mask)) {
126 flush->flags |= HV_FLUSH_ALL_PROCESSORS;
127 } else {
128 for_each_cpu(cpu, cpus) {
129 vcpu = hv_cpu_number_to_vp_number(cpu);
130 if (vcpu >= 64)
131 goto do_native;
132
133 __set_bit(vcpu, (unsigned long *)
134 &flush->processor_mask);
135 }
136 }
137
138 /*
139 * We can flush not more than max_gvas with one hypercall. Flush the
140 * whole address space if we were asked to do more.
141 */
142 max_gvas = (PAGE_SIZE - sizeof(*flush)) / sizeof(flush->gva_list[0]);
143
144 if (info->end == TLB_FLUSH_ALL) {
145 flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY;
146 status = hv_do_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE,
147 flush, NULL);
148 } else if (info->end &&
149 ((info->end - info->start)/HV_TLB_FLUSH_UNIT) > max_gvas) {
150 status = hv_do_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE,
151 flush, NULL);
152 } else {
153 gva_n = fill_gva_list(flush->gva_list, 0,
154 info->start, info->end);
155 status = hv_do_rep_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST,
156 gva_n, 0, flush, NULL);
157 }
158
159 local_irq_restore(flags);
160
161 if (!(status & HV_HYPERCALL_RESULT_MASK))
162 return;
163do_native:
164 native_flush_tlb_others(cpus, info);
165}
166
Vitaly Kuznetsov628f54c2017-08-02 18:09:20 +0200167static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
168 const struct flush_tlb_info *info)
169{
170 int nr_bank = 0, max_gvas, gva_n;
171 struct hv_flush_pcpu_ex *flush;
172 u64 status = U64_MAX;
173 unsigned long flags;
174
175 if (!pcpu_flush_ex || !hv_hypercall_pg)
176 goto do_native;
177
178 if (cpumask_empty(cpus))
179 return;
180
181 local_irq_save(flags);
182
183 flush = this_cpu_ptr(pcpu_flush_ex);
184
185 if (info->mm) {
186 flush->address_space = virt_to_phys(info->mm->pgd);
187 flush->flags = 0;
188 } else {
189 flush->address_space = 0;
190 flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES;
191 }
192
193 flush->hv_vp_set.valid_bank_mask = 0;
194
195 if (!cpumask_equal(cpus, cpu_present_mask)) {
196 flush->hv_vp_set.format = HV_GENERIC_SET_SPARCE_4K;
197 nr_bank = cpumask_to_vp_set(flush, cpus);
198 }
199
200 if (!nr_bank) {
201 flush->hv_vp_set.format = HV_GENERIC_SET_ALL;
202 flush->flags |= HV_FLUSH_ALL_PROCESSORS;
203 }
204
205 /*
206 * We can flush not more than max_gvas with one hypercall. Flush the
207 * whole address space if we were asked to do more.
208 */
209 max_gvas =
210 (PAGE_SIZE - sizeof(*flush) - nr_bank *
211 sizeof(flush->hv_vp_set.bank_contents[0])) /
212 sizeof(flush->gva_list[0]);
213
214 if (info->end == TLB_FLUSH_ALL) {
215 flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY;
216 status = hv_do_rep_hypercall(
217 HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
218 0, nr_bank + 2, flush, NULL);
219 } else if (info->end &&
220 ((info->end - info->start)/HV_TLB_FLUSH_UNIT) > max_gvas) {
221 status = hv_do_rep_hypercall(
222 HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
223 0, nr_bank + 2, flush, NULL);
224 } else {
225 gva_n = fill_gva_list(flush->gva_list, nr_bank,
226 info->start, info->end);
227 status = hv_do_rep_hypercall(
228 HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX,
229 gva_n, nr_bank + 2, flush, NULL);
230 }
231
232 local_irq_restore(flags);
233
234 if (!(status & HV_HYPERCALL_RESULT_MASK))
235 return;
236do_native:
237 native_flush_tlb_others(cpus, info);
238}
239
Vitaly Kuznetsov2ffd9e32017-08-02 18:09:19 +0200240void hyperv_setup_mmu_ops(void)
241{
Vitaly Kuznetsov628f54c2017-08-02 18:09:20 +0200242 if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
243 return;
244
245 setup_clear_cpu_cap(X86_FEATURE_PCID);
246
247 if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) {
Vitaly Kuznetsov2ffd9e32017-08-02 18:09:19 +0200248 pr_info("Using hypercall for remote TLB flush\n");
249 pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others;
Vitaly Kuznetsov628f54c2017-08-02 18:09:20 +0200250 } else {
251 pr_info("Using ext hypercall for remote TLB flush\n");
252 pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others_ex;
Vitaly Kuznetsov2ffd9e32017-08-02 18:09:19 +0200253 }
254}
255
256void hyper_alloc_mmu(void)
257{
Vitaly Kuznetsov628f54c2017-08-02 18:09:20 +0200258 if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
259 return;
260
261 if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
Vitaly Kuznetsov2ffd9e32017-08-02 18:09:19 +0200262 pcpu_flush = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
Vitaly Kuznetsov628f54c2017-08-02 18:09:20 +0200263 else
264 pcpu_flush_ex = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
Vitaly Kuznetsov2ffd9e32017-08-02 18:09:19 +0200265}