Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : #ifndef _ASM_X86_PARAVIRT_H
3 : : #define _ASM_X86_PARAVIRT_H
4 : : /* Various instructions on x86 need to be replaced for
5 : : * para-virtualization: those hooks are defined here. */
6 : :
7 : : #ifdef CONFIG_PARAVIRT
8 : : #include <asm/pgtable_types.h>
9 : : #include <asm/asm.h>
10 : : #include <asm/nospec-branch.h>
11 : :
12 : : #include <asm/paravirt_types.h>
13 : :
14 : : #ifndef __ASSEMBLY__
15 : : #include <linux/bug.h>
16 : : #include <linux/types.h>
17 : : #include <linux/cpumask.h>
18 : : #include <asm/frame.h>
19 : :
20 : 1915749 : static inline unsigned long long paravirt_sched_clock(void)
21 : : {
22 : 1915749 : return PVOP_CALL0(unsigned long long, time.sched_clock);
23 : : }
24 : :
25 : : struct static_key;
26 : : extern struct static_key paravirt_steal_enabled;
27 : : extern struct static_key paravirt_steal_rq_enabled;
28 : :
29 : : __visible void __native_queued_spin_unlock(struct qspinlock *lock);
30 : : bool pv_is_native_spin_unlock(void);
31 : : __visible bool __native_vcpu_is_preempted(long cpu);
32 : : bool pv_is_native_vcpu_is_preempted(void);
33 : :
34 : 91088 : static inline u64 paravirt_steal_clock(int cpu)
35 : : {
36 : 91088 : return PVOP_CALL1(u64, time.steal_clock, cpu);
37 : : }
38 : :
39 : : /* The paravirtualized I/O functions */
40 : 5340 : static inline void slow_down_io(void)
41 : : {
42 : 5340 : pv_ops.cpu.io_delay();
43 : : #ifdef REALLY_SLOW_IO
44 : : pv_ops.cpu.io_delay();
45 : : pv_ops.cpu.io_delay();
46 : : pv_ops.cpu.io_delay();
47 : : #endif
48 : : }
49 : :
50 : 319069 : static inline void __flush_tlb(void)
51 : : {
52 : 319069 : PVOP_VCALL0(mmu.flush_tlb_user);
53 : 319069 : }
54 : :
55 : 2224 : static inline void __flush_tlb_global(void)
56 : : {
57 : 2224 : PVOP_VCALL0(mmu.flush_tlb_kernel);
58 : 2224 : }
59 : :
60 : 5634354 : static inline void __flush_tlb_one_user(unsigned long addr)
61 : : {
62 : 5634354 : PVOP_VCALL1(mmu.flush_tlb_one_user, addr);
63 : : }
64 : :
65 : 0 : static inline void flush_tlb_others(const struct cpumask *cpumask,
66 : : const struct flush_tlb_info *info)
67 : : {
68 : 0 : PVOP_VCALL2(mmu.flush_tlb_others, cpumask, info);
69 : 0 : }
70 : :
71 : 4029243 : static inline void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
72 : : {
73 : 4029243 : PVOP_VCALL2(mmu.tlb_remove_table, tlb, table);
74 : : }
75 : :
76 : 49020 : static inline void paravirt_arch_exit_mmap(struct mm_struct *mm)
77 : : {
78 : 49020 : PVOP_VCALL1(mmu.exit_mmap, mm);
79 : : }
80 : :
81 : : #ifdef CONFIG_PARAVIRT_XXL
82 : : static inline void load_sp0(unsigned long sp0)
83 : : {
84 : : PVOP_VCALL1(cpu.load_sp0, sp0);
85 : : }
86 : :
87 : : /* The paravirtualized CPUID instruction. */
88 : : static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
89 : : unsigned int *ecx, unsigned int *edx)
90 : : {
91 : : PVOP_VCALL4(cpu.cpuid, eax, ebx, ecx, edx);
92 : : }
93 : :
94 : : /*
95 : : * These special macros can be used to get or set a debugging register
96 : : */
97 : : static inline unsigned long paravirt_get_debugreg(int reg)
98 : : {
99 : : return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg);
100 : : }
101 : : #define get_debugreg(var, reg) var = paravirt_get_debugreg(reg)
102 : : static inline void set_debugreg(unsigned long val, int reg)
103 : : {
104 : : PVOP_VCALL2(cpu.set_debugreg, reg, val);
105 : : }
106 : :
107 : : static inline unsigned long read_cr0(void)
108 : : {
109 : : return PVOP_CALL0(unsigned long, cpu.read_cr0);
110 : : }
111 : :
112 : : static inline void write_cr0(unsigned long x)
113 : : {
114 : : PVOP_VCALL1(cpu.write_cr0, x);
115 : : }
116 : :
117 : : static inline unsigned long read_cr2(void)
118 : : {
119 : : return PVOP_CALLEE0(unsigned long, mmu.read_cr2);
120 : : }
121 : :
122 : : static inline void write_cr2(unsigned long x)
123 : : {
124 : : PVOP_VCALL1(mmu.write_cr2, x);
125 : : }
126 : :
127 : : static inline unsigned long __read_cr3(void)
128 : : {
129 : : return PVOP_CALL0(unsigned long, mmu.read_cr3);
130 : : }
131 : :
132 : : static inline void write_cr3(unsigned long x)
133 : : {
134 : : PVOP_VCALL1(mmu.write_cr3, x);
135 : : }
136 : :
137 : : static inline void __write_cr4(unsigned long x)
138 : : {
139 : : PVOP_VCALL1(cpu.write_cr4, x);
140 : : }
141 : :
142 : : static inline void arch_safe_halt(void)
143 : : {
144 : : PVOP_VCALL0(irq.safe_halt);
145 : : }
146 : :
147 : : static inline void halt(void)
148 : : {
149 : : PVOP_VCALL0(irq.halt);
150 : : }
151 : :
152 : : static inline void wbinvd(void)
153 : : {
154 : : PVOP_VCALL0(cpu.wbinvd);
155 : : }
156 : :
157 : : #define get_kernel_rpl() (pv_info.kernel_rpl)
158 : :
159 : : static inline u64 paravirt_read_msr(unsigned msr)
160 : : {
161 : : return PVOP_CALL1(u64, cpu.read_msr, msr);
162 : : }
163 : :
164 : : static inline void paravirt_write_msr(unsigned msr,
165 : : unsigned low, unsigned high)
166 : : {
167 : : PVOP_VCALL3(cpu.write_msr, msr, low, high);
168 : : }
169 : :
170 : : static inline u64 paravirt_read_msr_safe(unsigned msr, int *err)
171 : : {
172 : : return PVOP_CALL2(u64, cpu.read_msr_safe, msr, err);
173 : : }
174 : :
175 : : static inline int paravirt_write_msr_safe(unsigned msr,
176 : : unsigned low, unsigned high)
177 : : {
178 : : return PVOP_CALL3(int, cpu.write_msr_safe, msr, low, high);
179 : : }
180 : :
181 : : #define rdmsr(msr, val1, val2) \
182 : : do { \
183 : : u64 _l = paravirt_read_msr(msr); \
184 : : val1 = (u32)_l; \
185 : : val2 = _l >> 32; \
186 : : } while (0)
187 : :
188 : : #define wrmsr(msr, val1, val2) \
189 : : do { \
190 : : paravirt_write_msr(msr, val1, val2); \
191 : : } while (0)
192 : :
193 : : #define rdmsrl(msr, val) \
194 : : do { \
195 : : val = paravirt_read_msr(msr); \
196 : : } while (0)
197 : :
198 : : static inline void wrmsrl(unsigned msr, u64 val)
199 : : {
200 : : wrmsr(msr, (u32)val, (u32)(val>>32));
201 : : }
202 : :
203 : : #define wrmsr_safe(msr, a, b) paravirt_write_msr_safe(msr, a, b)
204 : :
205 : : /* rdmsr with exception handling */
206 : : #define rdmsr_safe(msr, a, b) \
207 : : ({ \
208 : : int _err; \
209 : : u64 _l = paravirt_read_msr_safe(msr, &_err); \
210 : : (*a) = (u32)_l; \
211 : : (*b) = _l >> 32; \
212 : : _err; \
213 : : })
214 : :
215 : : static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
216 : : {
217 : : int err;
218 : :
219 : : *p = paravirt_read_msr_safe(msr, &err);
220 : : return err;
221 : : }
222 : :
223 : : static inline unsigned long long paravirt_read_pmc(int counter)
224 : : {
225 : : return PVOP_CALL1(u64, cpu.read_pmc, counter);
226 : : }
227 : :
228 : : #define rdpmc(counter, low, high) \
229 : : do { \
230 : : u64 _l = paravirt_read_pmc(counter); \
231 : : low = (u32)_l; \
232 : : high = _l >> 32; \
233 : : } while (0)
234 : :
235 : : #define rdpmcl(counter, val) ((val) = paravirt_read_pmc(counter))
236 : :
237 : : static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries)
238 : : {
239 : : PVOP_VCALL2(cpu.alloc_ldt, ldt, entries);
240 : : }
241 : :
242 : : static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries)
243 : : {
244 : : PVOP_VCALL2(cpu.free_ldt, ldt, entries);
245 : : }
246 : :
247 : : static inline void load_TR_desc(void)
248 : : {
249 : : PVOP_VCALL0(cpu.load_tr_desc);
250 : : }
251 : : static inline void load_gdt(const struct desc_ptr *dtr)
252 : : {
253 : : PVOP_VCALL1(cpu.load_gdt, dtr);
254 : : }
255 : : static inline void load_idt(const struct desc_ptr *dtr)
256 : : {
257 : : PVOP_VCALL1(cpu.load_idt, dtr);
258 : : }
259 : : static inline void set_ldt(const void *addr, unsigned entries)
260 : : {
261 : : PVOP_VCALL2(cpu.set_ldt, addr, entries);
262 : : }
263 : : static inline unsigned long paravirt_store_tr(void)
264 : : {
265 : : return PVOP_CALL0(unsigned long, cpu.store_tr);
266 : : }
267 : :
268 : : #define store_tr(tr) ((tr) = paravirt_store_tr())
269 : : static inline void load_TLS(struct thread_struct *t, unsigned cpu)
270 : : {
271 : : PVOP_VCALL2(cpu.load_tls, t, cpu);
272 : : }
273 : :
274 : : #ifdef CONFIG_X86_64
275 : : static inline void load_gs_index(unsigned int gs)
276 : : {
277 : : PVOP_VCALL1(cpu.load_gs_index, gs);
278 : : }
279 : : #endif
280 : :
281 : : static inline void write_ldt_entry(struct desc_struct *dt, int entry,
282 : : const void *desc)
283 : : {
284 : : PVOP_VCALL3(cpu.write_ldt_entry, dt, entry, desc);
285 : : }
286 : :
287 : : static inline void write_gdt_entry(struct desc_struct *dt, int entry,
288 : : void *desc, int type)
289 : : {
290 : : PVOP_VCALL4(cpu.write_gdt_entry, dt, entry, desc, type);
291 : : }
292 : :
293 : : static inline void write_idt_entry(gate_desc *dt, int entry, const gate_desc *g)
294 : : {
295 : : PVOP_VCALL3(cpu.write_idt_entry, dt, entry, g);
296 : : }
297 : :
298 : : #ifdef CONFIG_X86_IOPL_IOPERM
299 : : static inline void tss_update_io_bitmap(void)
300 : : {
301 : : PVOP_VCALL0(cpu.update_io_bitmap);
302 : : }
303 : : #endif
304 : :
305 : : static inline void paravirt_activate_mm(struct mm_struct *prev,
306 : : struct mm_struct *next)
307 : : {
308 : : PVOP_VCALL2(mmu.activate_mm, prev, next);
309 : : }
310 : :
311 : : static inline void paravirt_arch_dup_mmap(struct mm_struct *oldmm,
312 : : struct mm_struct *mm)
313 : : {
314 : : PVOP_VCALL2(mmu.dup_mmap, oldmm, mm);
315 : : }
316 : :
317 : : static inline int paravirt_pgd_alloc(struct mm_struct *mm)
318 : : {
319 : : return PVOP_CALL1(int, mmu.pgd_alloc, mm);
320 : : }
321 : :
322 : : static inline void paravirt_pgd_free(struct mm_struct *mm, pgd_t *pgd)
323 : : {
324 : : PVOP_VCALL2(mmu.pgd_free, mm, pgd);
325 : : }
326 : :
327 : : static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned long pfn)
328 : : {
329 : : PVOP_VCALL2(mmu.alloc_pte, mm, pfn);
330 : : }
331 : : static inline void paravirt_release_pte(unsigned long pfn)
332 : : {
333 : : PVOP_VCALL1(mmu.release_pte, pfn);
334 : : }
335 : :
336 : : static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned long pfn)
337 : : {
338 : : PVOP_VCALL2(mmu.alloc_pmd, mm, pfn);
339 : : }
340 : :
341 : : static inline void paravirt_release_pmd(unsigned long pfn)
342 : : {
343 : : PVOP_VCALL1(mmu.release_pmd, pfn);
344 : : }
345 : :
346 : : static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned long pfn)
347 : : {
348 : : PVOP_VCALL2(mmu.alloc_pud, mm, pfn);
349 : : }
350 : : static inline void paravirt_release_pud(unsigned long pfn)
351 : : {
352 : : PVOP_VCALL1(mmu.release_pud, pfn);
353 : : }
354 : :
355 : : static inline void paravirt_alloc_p4d(struct mm_struct *mm, unsigned long pfn)
356 : : {
357 : : PVOP_VCALL2(mmu.alloc_p4d, mm, pfn);
358 : : }
359 : :
360 : : static inline void paravirt_release_p4d(unsigned long pfn)
361 : : {
362 : : PVOP_VCALL1(mmu.release_p4d, pfn);
363 : : }
364 : :
365 : : static inline pte_t __pte(pteval_t val)
366 : : {
367 : : pteval_t ret;
368 : :
369 : : if (sizeof(pteval_t) > sizeof(long))
370 : : ret = PVOP_CALLEE2(pteval_t, mmu.make_pte, val, (u64)val >> 32);
371 : : else
372 : : ret = PVOP_CALLEE1(pteval_t, mmu.make_pte, val);
373 : :
374 : : return (pte_t) { .pte = ret };
375 : : }
376 : :
377 : : static inline pteval_t pte_val(pte_t pte)
378 : : {
379 : : pteval_t ret;
380 : :
381 : : if (sizeof(pteval_t) > sizeof(long))
382 : : ret = PVOP_CALLEE2(pteval_t, mmu.pte_val,
383 : : pte.pte, (u64)pte.pte >> 32);
384 : : else
385 : : ret = PVOP_CALLEE1(pteval_t, mmu.pte_val, pte.pte);
386 : :
387 : : return ret;
388 : : }
389 : :
390 : : static inline pgd_t __pgd(pgdval_t val)
391 : : {
392 : : pgdval_t ret;
393 : :
394 : : if (sizeof(pgdval_t) > sizeof(long))
395 : : ret = PVOP_CALLEE2(pgdval_t, mmu.make_pgd, val, (u64)val >> 32);
396 : : else
397 : : ret = PVOP_CALLEE1(pgdval_t, mmu.make_pgd, val);
398 : :
399 : : return (pgd_t) { ret };
400 : : }
401 : :
402 : : static inline pgdval_t pgd_val(pgd_t pgd)
403 : : {
404 : : pgdval_t ret;
405 : :
406 : : if (sizeof(pgdval_t) > sizeof(long))
407 : : ret = PVOP_CALLEE2(pgdval_t, mmu.pgd_val,
408 : : pgd.pgd, (u64)pgd.pgd >> 32);
409 : : else
410 : : ret = PVOP_CALLEE1(pgdval_t, mmu.pgd_val, pgd.pgd);
411 : :
412 : : return ret;
413 : : }
414 : :
415 : : #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
416 : : static inline pte_t ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr,
417 : : pte_t *ptep)
418 : : {
419 : : pteval_t ret;
420 : :
421 : : ret = PVOP_CALL3(pteval_t, mmu.ptep_modify_prot_start, vma, addr, ptep);
422 : :
423 : : return (pte_t) { .pte = ret };
424 : : }
425 : :
426 : : static inline void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr,
427 : : pte_t *ptep, pte_t old_pte, pte_t pte)
428 : : {
429 : :
430 : : if (sizeof(pteval_t) > sizeof(long))
431 : : /* 5 arg words */
432 : : pv_ops.mmu.ptep_modify_prot_commit(vma, addr, ptep, pte);
433 : : else
434 : : PVOP_VCALL4(mmu.ptep_modify_prot_commit,
435 : : vma, addr, ptep, pte.pte);
436 : : }
437 : :
438 : : static inline void set_pte(pte_t *ptep, pte_t pte)
439 : : {
440 : : if (sizeof(pteval_t) > sizeof(long))
441 : : PVOP_VCALL3(mmu.set_pte, ptep, pte.pte, (u64)pte.pte >> 32);
442 : : else
443 : : PVOP_VCALL2(mmu.set_pte, ptep, pte.pte);
444 : : }
445 : :
446 : : static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
447 : : pte_t *ptep, pte_t pte)
448 : : {
449 : : if (sizeof(pteval_t) > sizeof(long))
450 : : /* 5 arg words */
451 : : pv_ops.mmu.set_pte_at(mm, addr, ptep, pte);
452 : : else
453 : : PVOP_VCALL4(mmu.set_pte_at, mm, addr, ptep, pte.pte);
454 : : }
455 : :
456 : : static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
457 : : {
458 : : pmdval_t val = native_pmd_val(pmd);
459 : :
460 : : if (sizeof(pmdval_t) > sizeof(long))
461 : : PVOP_VCALL3(mmu.set_pmd, pmdp, val, (u64)val >> 32);
462 : : else
463 : : PVOP_VCALL2(mmu.set_pmd, pmdp, val);
464 : : }
465 : :
466 : : #if CONFIG_PGTABLE_LEVELS >= 3
467 : : static inline pmd_t __pmd(pmdval_t val)
468 : : {
469 : : pmdval_t ret;
470 : :
471 : : if (sizeof(pmdval_t) > sizeof(long))
472 : : ret = PVOP_CALLEE2(pmdval_t, mmu.make_pmd, val, (u64)val >> 32);
473 : : else
474 : : ret = PVOP_CALLEE1(pmdval_t, mmu.make_pmd, val);
475 : :
476 : : return (pmd_t) { ret };
477 : : }
478 : :
479 : : static inline pmdval_t pmd_val(pmd_t pmd)
480 : : {
481 : : pmdval_t ret;
482 : :
483 : : if (sizeof(pmdval_t) > sizeof(long))
484 : : ret = PVOP_CALLEE2(pmdval_t, mmu.pmd_val,
485 : : pmd.pmd, (u64)pmd.pmd >> 32);
486 : : else
487 : : ret = PVOP_CALLEE1(pmdval_t, mmu.pmd_val, pmd.pmd);
488 : :
489 : : return ret;
490 : : }
491 : :
492 : : static inline void set_pud(pud_t *pudp, pud_t pud)
493 : : {
494 : : pudval_t val = native_pud_val(pud);
495 : :
496 : : if (sizeof(pudval_t) > sizeof(long))
497 : : PVOP_VCALL3(mmu.set_pud, pudp, val, (u64)val >> 32);
498 : : else
499 : : PVOP_VCALL2(mmu.set_pud, pudp, val);
500 : : }
501 : : #if CONFIG_PGTABLE_LEVELS >= 4
502 : : static inline pud_t __pud(pudval_t val)
503 : : {
504 : : pudval_t ret;
505 : :
506 : : ret = PVOP_CALLEE1(pudval_t, mmu.make_pud, val);
507 : :
508 : : return (pud_t) { ret };
509 : : }
510 : :
511 : : static inline pudval_t pud_val(pud_t pud)
512 : : {
513 : : return PVOP_CALLEE1(pudval_t, mmu.pud_val, pud.pud);
514 : : }
515 : :
516 : : static inline void pud_clear(pud_t *pudp)
517 : : {
518 : : set_pud(pudp, __pud(0));
519 : : }
520 : :
521 : : static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
522 : : {
523 : : p4dval_t val = native_p4d_val(p4d);
524 : :
525 : : PVOP_VCALL2(mmu.set_p4d, p4dp, val);
526 : : }
527 : :
528 : : #if CONFIG_PGTABLE_LEVELS >= 5
529 : :
530 : : static inline p4d_t __p4d(p4dval_t val)
531 : : {
532 : : p4dval_t ret = PVOP_CALLEE1(p4dval_t, mmu.make_p4d, val);
533 : :
534 : : return (p4d_t) { ret };
535 : : }
536 : :
537 : : static inline p4dval_t p4d_val(p4d_t p4d)
538 : : {
539 : : return PVOP_CALLEE1(p4dval_t, mmu.p4d_val, p4d.p4d);
540 : : }
541 : :
542 : : static inline void __set_pgd(pgd_t *pgdp, pgd_t pgd)
543 : : {
544 : : PVOP_VCALL2(mmu.set_pgd, pgdp, native_pgd_val(pgd));
545 : : }
546 : :
547 : : #define set_pgd(pgdp, pgdval) do { \
548 : : if (pgtable_l5_enabled()) \
549 : : __set_pgd(pgdp, pgdval); \
550 : : else \
551 : : set_p4d((p4d_t *)(pgdp), (p4d_t) { (pgdval).pgd }); \
552 : : } while (0)
553 : :
554 : : #define pgd_clear(pgdp) do { \
555 : : if (pgtable_l5_enabled()) \
556 : : set_pgd(pgdp, __pgd(0)); \
557 : : } while (0)
558 : :
559 : : #endif /* CONFIG_PGTABLE_LEVELS == 5 */
560 : :
561 : : static inline void p4d_clear(p4d_t *p4dp)
562 : : {
563 : : set_p4d(p4dp, __p4d(0));
564 : : }
565 : :
566 : : #endif /* CONFIG_PGTABLE_LEVELS == 4 */
567 : :
568 : : #endif /* CONFIG_PGTABLE_LEVELS >= 3 */
569 : :
570 : : #ifdef CONFIG_X86_PAE
571 : : /* Special-case pte-setting operations for PAE, which can't update a
572 : : 64-bit pte atomically */
573 : : static inline void set_pte_atomic(pte_t *ptep, pte_t pte)
574 : : {
575 : : PVOP_VCALL3(mmu.set_pte_atomic, ptep, pte.pte, pte.pte >> 32);
576 : : }
577 : :
578 : : static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
579 : : pte_t *ptep)
580 : : {
581 : : PVOP_VCALL3(mmu.pte_clear, mm, addr, ptep);
582 : : }
583 : :
584 : : static inline void pmd_clear(pmd_t *pmdp)
585 : : {
586 : : PVOP_VCALL1(mmu.pmd_clear, pmdp);
587 : : }
588 : : #else /* !CONFIG_X86_PAE */
589 : : static inline void set_pte_atomic(pte_t *ptep, pte_t pte)
590 : : {
591 : : set_pte(ptep, pte);
592 : : }
593 : :
594 : : static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
595 : : pte_t *ptep)
596 : : {
597 : : set_pte_at(mm, addr, ptep, __pte(0));
598 : : }
599 : :
600 : : static inline void pmd_clear(pmd_t *pmdp)
601 : : {
602 : : set_pmd(pmdp, __pmd(0));
603 : : }
604 : : #endif /* CONFIG_X86_PAE */
605 : :
606 : : #define __HAVE_ARCH_START_CONTEXT_SWITCH
607 : : static inline void arch_start_context_switch(struct task_struct *prev)
608 : : {
609 : : PVOP_VCALL1(cpu.start_context_switch, prev);
610 : : }
611 : :
612 : : static inline void arch_end_context_switch(struct task_struct *next)
613 : : {
614 : : PVOP_VCALL1(cpu.end_context_switch, next);
615 : : }
616 : :
617 : : #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
618 : : static inline void arch_enter_lazy_mmu_mode(void)
619 : : {
620 : : PVOP_VCALL0(mmu.lazy_mode.enter);
621 : : }
622 : :
623 : : static inline void arch_leave_lazy_mmu_mode(void)
624 : : {
625 : : PVOP_VCALL0(mmu.lazy_mode.leave);
626 : : }
627 : :
628 : : static inline void arch_flush_lazy_mmu_mode(void)
629 : : {
630 : : PVOP_VCALL0(mmu.lazy_mode.flush);
631 : : }
632 : :
633 : : static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
634 : : phys_addr_t phys, pgprot_t flags)
635 : : {
636 : : pv_ops.mmu.set_fixmap(idx, phys, flags);
637 : : }
638 : : #endif
639 : :
640 : : #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS)
641 : :
642 : : static __always_inline void pv_queued_spin_lock_slowpath(struct qspinlock *lock,
643 : : u32 val)
644 : : {
645 : : PVOP_VCALL2(lock.queued_spin_lock_slowpath, lock, val);
646 : : }
647 : :
648 : : static __always_inline void pv_queued_spin_unlock(struct qspinlock *lock)
649 : : {
650 : : PVOP_VCALLEE1(lock.queued_spin_unlock, lock);
651 : : }
652 : :
653 : : static __always_inline void pv_wait(u8 *ptr, u8 val)
654 : : {
655 : : PVOP_VCALL2(lock.wait, ptr, val);
656 : : }
657 : :
658 : : static __always_inline void pv_kick(int cpu)
659 : : {
660 : : PVOP_VCALL1(lock.kick, cpu);
661 : : }
662 : :
663 : : static __always_inline bool pv_vcpu_is_preempted(long cpu)
664 : : {
665 : : return PVOP_CALLEE1(bool, lock.vcpu_is_preempted, cpu);
666 : : }
667 : :
668 : : void __raw_callee_save___native_queued_spin_unlock(struct qspinlock *lock);
669 : : bool __raw_callee_save___native_vcpu_is_preempted(long cpu);
670 : :
671 : : #endif /* SMP && PARAVIRT_SPINLOCKS */
672 : :
673 : : #ifdef CONFIG_X86_32
674 : : #define PV_SAVE_REGS "pushl %ecx; pushl %edx;"
675 : : #define PV_RESTORE_REGS "popl %edx; popl %ecx;"
676 : :
677 : : /* save and restore all caller-save registers, except return value */
678 : : #define PV_SAVE_ALL_CALLER_REGS "pushl %ecx;"
679 : : #define PV_RESTORE_ALL_CALLER_REGS "popl %ecx;"
680 : :
681 : : #define PV_FLAGS_ARG "0"
682 : : #define PV_EXTRA_CLOBBERS
683 : : #define PV_VEXTRA_CLOBBERS
684 : : #else
685 : : /* save and restore all caller-save registers, except return value */
686 : : #define PV_SAVE_ALL_CALLER_REGS \
687 : : "push %rcx;" \
688 : : "push %rdx;" \
689 : : "push %rsi;" \
690 : : "push %rdi;" \
691 : : "push %r8;" \
692 : : "push %r9;" \
693 : : "push %r10;" \
694 : : "push %r11;"
695 : : #define PV_RESTORE_ALL_CALLER_REGS \
696 : : "pop %r11;" \
697 : : "pop %r10;" \
698 : : "pop %r9;" \
699 : : "pop %r8;" \
700 : : "pop %rdi;" \
701 : : "pop %rsi;" \
702 : : "pop %rdx;" \
703 : : "pop %rcx;"
704 : :
705 : : /* We save some registers, but all of them, that's too much. We clobber all
706 : : * caller saved registers but the argument parameter */
707 : : #define PV_SAVE_REGS "pushq %%rdi;"
708 : : #define PV_RESTORE_REGS "popq %%rdi;"
709 : : #define PV_EXTRA_CLOBBERS EXTRA_CLOBBERS, "rcx" , "rdx", "rsi"
710 : : #define PV_VEXTRA_CLOBBERS EXTRA_CLOBBERS, "rdi", "rcx" , "rdx", "rsi"
711 : : #define PV_FLAGS_ARG "D"
712 : : #endif
713 : :
714 : : /*
715 : : * Generate a thunk around a function which saves all caller-save
716 : : * registers except for the return value. This allows C functions to
717 : : * be called from assembler code where fewer than normal registers are
718 : : * available. It may also help code generation around calls from C
719 : : * code if the common case doesn't use many registers.
720 : : *
721 : : * When a callee is wrapped in a thunk, the caller can assume that all
722 : : * arg regs and all scratch registers are preserved across the
723 : : * call. The return value in rax/eax will not be saved, even for void
724 : : * functions.
725 : : */
726 : : #define PV_THUNK_NAME(func) "__raw_callee_save_" #func
727 : : #define PV_CALLEE_SAVE_REGS_THUNK(func) \
728 : : extern typeof(func) __raw_callee_save_##func; \
729 : : \
730 : : asm(".pushsection .text;" \
731 : : ".globl " PV_THUNK_NAME(func) ";" \
732 : : ".type " PV_THUNK_NAME(func) ", @function;" \
733 : : PV_THUNK_NAME(func) ":" \
734 : : FRAME_BEGIN \
735 : : PV_SAVE_ALL_CALLER_REGS \
736 : : "call " #func ";" \
737 : : PV_RESTORE_ALL_CALLER_REGS \
738 : : FRAME_END \
739 : : "ret;" \
740 : : ".size " PV_THUNK_NAME(func) ", .-" PV_THUNK_NAME(func) ";" \
741 : : ".popsection")
742 : :
743 : : /* Get a reference to a callee-save function */
744 : : #define PV_CALLEE_SAVE(func) \
745 : : ((struct paravirt_callee_save) { __raw_callee_save_##func })
746 : :
747 : : /* Promise that "func" already uses the right calling convention */
748 : : #define __PV_IS_CALLEE_SAVE(func) \
749 : : ((struct paravirt_callee_save) { func })
750 : :
751 : : #ifdef CONFIG_PARAVIRT_XXL
752 : : static inline notrace unsigned long arch_local_save_flags(void)
753 : : {
754 : : return PVOP_CALLEE0(unsigned long, irq.save_fl);
755 : : }
756 : :
757 : : static inline notrace void arch_local_irq_restore(unsigned long f)
758 : : {
759 : : PVOP_VCALLEE1(irq.restore_fl, f);
760 : : }
761 : :
762 : : static inline notrace void arch_local_irq_disable(void)
763 : : {
764 : : PVOP_VCALLEE0(irq.irq_disable);
765 : : }
766 : :
767 : : static inline notrace void arch_local_irq_enable(void)
768 : : {
769 : : PVOP_VCALLEE0(irq.irq_enable);
770 : : }
771 : :
772 : : static inline notrace unsigned long arch_local_irq_save(void)
773 : : {
774 : : unsigned long f;
775 : :
776 : : f = arch_local_save_flags();
777 : : arch_local_irq_disable();
778 : : return f;
779 : : }
780 : : #endif
781 : :
782 : :
783 : : /* Make sure as little as possible of this mess escapes. */
784 : : #undef PARAVIRT_CALL
785 : : #undef __PVOP_CALL
786 : : #undef __PVOP_VCALL
787 : : #undef PVOP_VCALL0
788 : : #undef PVOP_CALL0
789 : : #undef PVOP_VCALL1
790 : : #undef PVOP_CALL1
791 : : #undef PVOP_VCALL2
792 : : #undef PVOP_CALL2
793 : : #undef PVOP_VCALL3
794 : : #undef PVOP_CALL3
795 : : #undef PVOP_VCALL4
796 : : #undef PVOP_CALL4
797 : :
798 : : extern void default_banner(void);
799 : :
800 : : #else /* __ASSEMBLY__ */
801 : :
802 : : #define _PVSITE(ptype, ops, word, algn) \
803 : : 771:; \
804 : : ops; \
805 : : 772:; \
806 : : .pushsection .parainstructions,"a"; \
807 : : .align algn; \
808 : : word 771b; \
809 : : .byte ptype; \
810 : : .byte 772b-771b; \
811 : : .popsection
812 : :
813 : :
814 : : #define COND_PUSH(set, mask, reg) \
815 : : .if ((~(set)) & mask); push %reg; .endif
816 : : #define COND_POP(set, mask, reg) \
817 : : .if ((~(set)) & mask); pop %reg; .endif
818 : :
819 : : #ifdef CONFIG_X86_64
820 : :
821 : : #define PV_SAVE_REGS(set) \
822 : : COND_PUSH(set, CLBR_RAX, rax); \
823 : : COND_PUSH(set, CLBR_RCX, rcx); \
824 : : COND_PUSH(set, CLBR_RDX, rdx); \
825 : : COND_PUSH(set, CLBR_RSI, rsi); \
826 : : COND_PUSH(set, CLBR_RDI, rdi); \
827 : : COND_PUSH(set, CLBR_R8, r8); \
828 : : COND_PUSH(set, CLBR_R9, r9); \
829 : : COND_PUSH(set, CLBR_R10, r10); \
830 : : COND_PUSH(set, CLBR_R11, r11)
831 : : #define PV_RESTORE_REGS(set) \
832 : : COND_POP(set, CLBR_R11, r11); \
833 : : COND_POP(set, CLBR_R10, r10); \
834 : : COND_POP(set, CLBR_R9, r9); \
835 : : COND_POP(set, CLBR_R8, r8); \
836 : : COND_POP(set, CLBR_RDI, rdi); \
837 : : COND_POP(set, CLBR_RSI, rsi); \
838 : : COND_POP(set, CLBR_RDX, rdx); \
839 : : COND_POP(set, CLBR_RCX, rcx); \
840 : : COND_POP(set, CLBR_RAX, rax)
841 : :
842 : : #define PARA_PATCH(off) ((off) / 8)
843 : : #define PARA_SITE(ptype, ops) _PVSITE(ptype, ops, .quad, 8)
844 : : #define PARA_INDIRECT(addr) *addr(%rip)
845 : : #else
846 : : #define PV_SAVE_REGS(set) \
847 : : COND_PUSH(set, CLBR_EAX, eax); \
848 : : COND_PUSH(set, CLBR_EDI, edi); \
849 : : COND_PUSH(set, CLBR_ECX, ecx); \
850 : : COND_PUSH(set, CLBR_EDX, edx)
851 : : #define PV_RESTORE_REGS(set) \
852 : : COND_POP(set, CLBR_EDX, edx); \
853 : : COND_POP(set, CLBR_ECX, ecx); \
854 : : COND_POP(set, CLBR_EDI, edi); \
855 : : COND_POP(set, CLBR_EAX, eax)
856 : :
857 : : #define PARA_PATCH(off) ((off) / 4)
858 : : #define PARA_SITE(ptype, ops) _PVSITE(ptype, ops, .long, 4)
859 : : #define PARA_INDIRECT(addr) *%cs:addr
860 : : #endif
861 : :
862 : : #ifdef CONFIG_PARAVIRT_XXL
863 : : #define INTERRUPT_RETURN \
864 : : PARA_SITE(PARA_PATCH(PV_CPU_iret), \
865 : : ANNOTATE_RETPOLINE_SAFE; \
866 : : jmp PARA_INDIRECT(pv_ops+PV_CPU_iret);)
867 : :
868 : : #define DISABLE_INTERRUPTS(clobbers) \
869 : : PARA_SITE(PARA_PATCH(PV_IRQ_irq_disable), \
870 : : PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \
871 : : ANNOTATE_RETPOLINE_SAFE; \
872 : : call PARA_INDIRECT(pv_ops+PV_IRQ_irq_disable); \
873 : : PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
874 : :
875 : : #define ENABLE_INTERRUPTS(clobbers) \
876 : : PARA_SITE(PARA_PATCH(PV_IRQ_irq_enable), \
877 : : PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \
878 : : ANNOTATE_RETPOLINE_SAFE; \
879 : : call PARA_INDIRECT(pv_ops+PV_IRQ_irq_enable); \
880 : : PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
881 : : #endif
882 : :
883 : : #ifdef CONFIG_X86_64
884 : : #ifdef CONFIG_PARAVIRT_XXL
885 : : /*
886 : : * If swapgs is used while the userspace stack is still current,
887 : : * there's no way to call a pvop. The PV replacement *must* be
888 : : * inlined, or the swapgs instruction must be trapped and emulated.
889 : : */
890 : : #define SWAPGS_UNSAFE_STACK \
891 : : PARA_SITE(PARA_PATCH(PV_CPU_swapgs), swapgs)
892 : :
893 : : /*
894 : : * Note: swapgs is very special, and in practise is either going to be
895 : : * implemented with a single "swapgs" instruction or something very
896 : : * special. Either way, we don't need to save any registers for
897 : : * it.
898 : : */
899 : : #define SWAPGS \
900 : : PARA_SITE(PARA_PATCH(PV_CPU_swapgs), \
901 : : ANNOTATE_RETPOLINE_SAFE; \
902 : : call PARA_INDIRECT(pv_ops+PV_CPU_swapgs); \
903 : : )
904 : :
905 : : #define USERGS_SYSRET64 \
906 : : PARA_SITE(PARA_PATCH(PV_CPU_usergs_sysret64), \
907 : : ANNOTATE_RETPOLINE_SAFE; \
908 : : jmp PARA_INDIRECT(pv_ops+PV_CPU_usergs_sysret64);)
909 : :
910 : : #ifdef CONFIG_DEBUG_ENTRY
911 : : #define SAVE_FLAGS(clobbers) \
912 : : PARA_SITE(PARA_PATCH(PV_IRQ_save_fl), \
913 : : PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \
914 : : ANNOTATE_RETPOLINE_SAFE; \
915 : : call PARA_INDIRECT(pv_ops+PV_IRQ_save_fl); \
916 : : PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
917 : : #endif
918 : : #endif /* CONFIG_PARAVIRT_XXL */
919 : : #endif /* CONFIG_X86_64 */
920 : :
921 : : #ifdef CONFIG_PARAVIRT_XXL
922 : :
923 : : #define GET_CR2_INTO_AX \
924 : : PARA_SITE(PARA_PATCH(PV_MMU_read_cr2), \
925 : : ANNOTATE_RETPOLINE_SAFE; \
926 : : call PARA_INDIRECT(pv_ops+PV_MMU_read_cr2); \
927 : : )
928 : :
929 : : #endif /* CONFIG_PARAVIRT_XXL */
930 : :
931 : :
932 : : #endif /* __ASSEMBLY__ */
933 : : #else /* CONFIG_PARAVIRT */
934 : : # define default_banner x86_init_noop
935 : : #endif /* !CONFIG_PARAVIRT */
936 : :
937 : : #ifndef __ASSEMBLY__
938 : : #ifndef CONFIG_PARAVIRT_XXL
939 : 10956 : static inline void paravirt_arch_dup_mmap(struct mm_struct *oldmm,
940 : : struct mm_struct *mm)
941 : : {
942 : 10956 : }
943 : : #endif
944 : :
945 : : #ifndef CONFIG_PARAVIRT
946 : : static inline void paravirt_arch_exit_mmap(struct mm_struct *mm)
947 : : {
948 : : }
949 : : #endif
950 : : #endif /* __ASSEMBLY__ */
951 : : #endif /* _ASM_X86_PARAVIRT_H */
|