aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/paravirt.h
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-02-09 06:16:59 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-09 06:16:59 -0500
commiteca217b36e5d7d4377493d5cedd89105e66a5a72 (patch)
tree71f0ecd5225c3033d509b77a23ad7bc576cf0ab6 /arch/x86/include/asm/paravirt.h
parent54a353a0f845c1dad5fc8183872e750d667838ac (diff)
parente4d0407185cdbdcfd99fc23bde2e5454bbc46329 (diff)
Merge branch 'x86/paravirt' into x86/apic
Conflicts: arch/x86/mach-voyager/voyager_smp.c
Diffstat (limited to 'arch/x86/include/asm/paravirt.h')
-rw-r--r--arch/x86/include/asm/paravirt.h435
1 files changed, 301 insertions, 134 deletions
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 7e674ea80f0d..ff691736f5e9 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -12,21 +12,38 @@
12#define CLBR_EAX (1 << 0) 12#define CLBR_EAX (1 << 0)
13#define CLBR_ECX (1 << 1) 13#define CLBR_ECX (1 << 1)
14#define CLBR_EDX (1 << 2) 14#define CLBR_EDX (1 << 2)
15#define CLBR_EDI (1 << 3)
15 16
16#ifdef CONFIG_X86_64 17#ifdef CONFIG_X86_32
17#define CLBR_RSI (1 << 3) 18/* CLBR_ANY should match all regs platform has. For i386, that's just it */
18#define CLBR_RDI (1 << 4) 19#define CLBR_ANY ((1 << 4) - 1)
20
21#define CLBR_ARG_REGS (CLBR_EAX | CLBR_EDX | CLBR_ECX)
22#define CLBR_RET_REG (CLBR_EAX | CLBR_EDX)
23#define CLBR_SCRATCH (0)
24#else
25#define CLBR_RAX CLBR_EAX
26#define CLBR_RCX CLBR_ECX
27#define CLBR_RDX CLBR_EDX
28#define CLBR_RDI CLBR_EDI
29#define CLBR_RSI (1 << 4)
19#define CLBR_R8 (1 << 5) 30#define CLBR_R8 (1 << 5)
20#define CLBR_R9 (1 << 6) 31#define CLBR_R9 (1 << 6)
21#define CLBR_R10 (1 << 7) 32#define CLBR_R10 (1 << 7)
22#define CLBR_R11 (1 << 8) 33#define CLBR_R11 (1 << 8)
34
23#define CLBR_ANY ((1 << 9) - 1) 35#define CLBR_ANY ((1 << 9) - 1)
36
37#define CLBR_ARG_REGS (CLBR_RDI | CLBR_RSI | CLBR_RDX | \
38 CLBR_RCX | CLBR_R8 | CLBR_R9)
39#define CLBR_RET_REG (CLBR_RAX)
40#define CLBR_SCRATCH (CLBR_R10 | CLBR_R11)
41
24#include <asm/desc_defs.h> 42#include <asm/desc_defs.h>
25#else
26/* CLBR_ANY should match all regs platform has. For i386, that's just it */
27#define CLBR_ANY ((1 << 3) - 1)
28#endif /* X86_64 */ 43#endif /* X86_64 */
29 44
45#define CLBR_CALLEE_SAVE ((CLBR_ARG_REGS | CLBR_SCRATCH) & ~CLBR_RET_REG)
46
30#ifndef __ASSEMBLY__ 47#ifndef __ASSEMBLY__
31#include <linux/types.h> 48#include <linux/types.h>
32#include <linux/cpumask.h> 49#include <linux/cpumask.h>
@@ -40,6 +57,14 @@ struct tss_struct;
40struct mm_struct; 57struct mm_struct;
41struct desc_struct; 58struct desc_struct;
42 59
60/*
61 * Wrapper type for pointers to code which uses the non-standard
62 * calling convention. See PV_CALL_SAVE_REGS_THUNK below.
63 */
64struct paravirt_callee_save {
65 void *func;
66};
67
43/* general info */ 68/* general info */
44struct pv_info { 69struct pv_info {
45 unsigned int kernel_rpl; 70 unsigned int kernel_rpl;
@@ -189,11 +214,15 @@ struct pv_irq_ops {
189 * expected to use X86_EFLAGS_IF; all other bits 214 * expected to use X86_EFLAGS_IF; all other bits
190 * returned from save_fl are undefined, and may be ignored by 215 * returned from save_fl are undefined, and may be ignored by
191 * restore_fl. 216 * restore_fl.
217 *
218 * NOTE: These functions callers expect the callee to preserve
219 * more registers than the standard C calling convention.
192 */ 220 */
193 unsigned long (*save_fl)(void); 221 struct paravirt_callee_save save_fl;
194 void (*restore_fl)(unsigned long); 222 struct paravirt_callee_save restore_fl;
195 void (*irq_disable)(void); 223 struct paravirt_callee_save irq_disable;
196 void (*irq_enable)(void); 224 struct paravirt_callee_save irq_enable;
225
197 void (*safe_halt)(void); 226 void (*safe_halt)(void);
198 void (*halt)(void); 227 void (*halt)(void);
199 228
@@ -279,11 +308,11 @@ struct pv_mmu_ops {
279 void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr, 308 void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr,
280 pte_t *ptep, pte_t pte); 309 pte_t *ptep, pte_t pte);
281 310
282 pteval_t (*pte_val)(pte_t); 311 struct paravirt_callee_save pte_val;
283 pte_t (*make_pte)(pteval_t pte); 312 struct paravirt_callee_save make_pte;
284 313
285 pgdval_t (*pgd_val)(pgd_t); 314 struct paravirt_callee_save pgd_val;
286 pgd_t (*make_pgd)(pgdval_t pgd); 315 struct paravirt_callee_save make_pgd;
287 316
288#if PAGETABLE_LEVELS >= 3 317#if PAGETABLE_LEVELS >= 3
289#ifdef CONFIG_X86_PAE 318#ifdef CONFIG_X86_PAE
@@ -298,12 +327,12 @@ struct pv_mmu_ops {
298 327
299 void (*set_pud)(pud_t *pudp, pud_t pudval); 328 void (*set_pud)(pud_t *pudp, pud_t pudval);
300 329
301 pmdval_t (*pmd_val)(pmd_t); 330 struct paravirt_callee_save pmd_val;
302 pmd_t (*make_pmd)(pmdval_t pmd); 331 struct paravirt_callee_save make_pmd;
303 332
304#if PAGETABLE_LEVELS == 4 333#if PAGETABLE_LEVELS == 4
305 pudval_t (*pud_val)(pud_t); 334 struct paravirt_callee_save pud_val;
306 pud_t (*make_pud)(pudval_t pud); 335 struct paravirt_callee_save make_pud;
307 336
308 void (*set_pgd)(pgd_t *pudp, pgd_t pgdval); 337 void (*set_pgd)(pgd_t *pudp, pgd_t pgdval);
309#endif /* PAGETABLE_LEVELS == 4 */ 338#endif /* PAGETABLE_LEVELS == 4 */
@@ -388,6 +417,8 @@ extern struct pv_lock_ops pv_lock_ops;
388 asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":") 417 asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
389 418
390unsigned paravirt_patch_nop(void); 419unsigned paravirt_patch_nop(void);
420unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len);
421unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len);
391unsigned paravirt_patch_ignore(unsigned len); 422unsigned paravirt_patch_ignore(unsigned len);
392unsigned paravirt_patch_call(void *insnbuf, 423unsigned paravirt_patch_call(void *insnbuf,
393 const void *target, u16 tgt_clobbers, 424 const void *target, u16 tgt_clobbers,
@@ -479,25 +510,45 @@ int paravirt_disable_iospace(void);
479 * makes sure the incoming and outgoing types are always correct. 510 * makes sure the incoming and outgoing types are always correct.
480 */ 511 */
481#ifdef CONFIG_X86_32 512#ifdef CONFIG_X86_32
482#define PVOP_VCALL_ARGS unsigned long __eax, __edx, __ecx 513#define PVOP_VCALL_ARGS \
514 unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx
483#define PVOP_CALL_ARGS PVOP_VCALL_ARGS 515#define PVOP_CALL_ARGS PVOP_VCALL_ARGS
516
517#define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x))
518#define PVOP_CALL_ARG2(x) "d" ((unsigned long)(x))
519#define PVOP_CALL_ARG3(x) "c" ((unsigned long)(x))
520
484#define PVOP_VCALL_CLOBBERS "=a" (__eax), "=d" (__edx), \ 521#define PVOP_VCALL_CLOBBERS "=a" (__eax), "=d" (__edx), \
485 "=c" (__ecx) 522 "=c" (__ecx)
486#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS 523#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS
524
525#define PVOP_VCALLEE_CLOBBERS "=a" (__eax), "=d" (__edx)
526#define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS
527
487#define EXTRA_CLOBBERS 528#define EXTRA_CLOBBERS
488#define VEXTRA_CLOBBERS 529#define VEXTRA_CLOBBERS
489#else 530#else /* CONFIG_X86_64 */
490#define PVOP_VCALL_ARGS unsigned long __edi, __esi, __edx, __ecx 531#define PVOP_VCALL_ARGS \
532 unsigned long __edi = __edi, __esi = __esi, \
533 __edx = __edx, __ecx = __ecx
491#define PVOP_CALL_ARGS PVOP_VCALL_ARGS, __eax 534#define PVOP_CALL_ARGS PVOP_VCALL_ARGS, __eax
535
536#define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x))
537#define PVOP_CALL_ARG2(x) "S" ((unsigned long)(x))
538#define PVOP_CALL_ARG3(x) "d" ((unsigned long)(x))
539#define PVOP_CALL_ARG4(x) "c" ((unsigned long)(x))
540
492#define PVOP_VCALL_CLOBBERS "=D" (__edi), \ 541#define PVOP_VCALL_CLOBBERS "=D" (__edi), \
493 "=S" (__esi), "=d" (__edx), \ 542 "=S" (__esi), "=d" (__edx), \
494 "=c" (__ecx) 543 "=c" (__ecx)
495
496#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax) 544#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax)
497 545
546#define PVOP_VCALLEE_CLOBBERS "=a" (__eax)
547#define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS
548
498#define EXTRA_CLOBBERS , "r8", "r9", "r10", "r11" 549#define EXTRA_CLOBBERS , "r8", "r9", "r10", "r11"
499#define VEXTRA_CLOBBERS , "rax", "r8", "r9", "r10", "r11" 550#define VEXTRA_CLOBBERS , "rax", "r8", "r9", "r10", "r11"
500#endif 551#endif /* CONFIG_X86_32 */
501 552
502#ifdef CONFIG_PARAVIRT_DEBUG 553#ifdef CONFIG_PARAVIRT_DEBUG
503#define PVOP_TEST_NULL(op) BUG_ON(op == NULL) 554#define PVOP_TEST_NULL(op) BUG_ON(op == NULL)
@@ -505,10 +556,11 @@ int paravirt_disable_iospace(void);
505#define PVOP_TEST_NULL(op) ((void)op) 556#define PVOP_TEST_NULL(op) ((void)op)
506#endif 557#endif
507 558
508#define __PVOP_CALL(rettype, op, pre, post, ...) \ 559#define ____PVOP_CALL(rettype, op, clbr, call_clbr, extra_clbr, \
560 pre, post, ...) \
509 ({ \ 561 ({ \
510 rettype __ret; \ 562 rettype __ret; \
511 PVOP_CALL_ARGS; \ 563 PVOP_CALL_ARGS; \
512 PVOP_TEST_NULL(op); \ 564 PVOP_TEST_NULL(op); \
513 /* This is 32-bit specific, but is okay in 64-bit */ \ 565 /* This is 32-bit specific, but is okay in 64-bit */ \
514 /* since this condition will never hold */ \ 566 /* since this condition will never hold */ \
@@ -516,70 +568,113 @@ int paravirt_disable_iospace(void);
516 asm volatile(pre \ 568 asm volatile(pre \
517 paravirt_alt(PARAVIRT_CALL) \ 569 paravirt_alt(PARAVIRT_CALL) \
518 post \ 570 post \
519 : PVOP_CALL_CLOBBERS \ 571 : call_clbr \
520 : paravirt_type(op), \ 572 : paravirt_type(op), \
521 paravirt_clobber(CLBR_ANY), \ 573 paravirt_clobber(clbr), \
522 ##__VA_ARGS__ \ 574 ##__VA_ARGS__ \
523 : "memory", "cc" EXTRA_CLOBBERS); \ 575 : "memory", "cc" extra_clbr); \
524 __ret = (rettype)((((u64)__edx) << 32) | __eax); \ 576 __ret = (rettype)((((u64)__edx) << 32) | __eax); \
525 } else { \ 577 } else { \
526 asm volatile(pre \ 578 asm volatile(pre \
527 paravirt_alt(PARAVIRT_CALL) \ 579 paravirt_alt(PARAVIRT_CALL) \
528 post \ 580 post \
529 : PVOP_CALL_CLOBBERS \ 581 : call_clbr \
530 : paravirt_type(op), \ 582 : paravirt_type(op), \
531 paravirt_clobber(CLBR_ANY), \ 583 paravirt_clobber(clbr), \
532 ##__VA_ARGS__ \ 584 ##__VA_ARGS__ \
533 : "memory", "cc" EXTRA_CLOBBERS); \ 585 : "memory", "cc" extra_clbr); \
534 __ret = (rettype)__eax; \ 586 __ret = (rettype)__eax; \
535 } \ 587 } \
536 __ret; \ 588 __ret; \
537 }) 589 })
538#define __PVOP_VCALL(op, pre, post, ...) \ 590
591#define __PVOP_CALL(rettype, op, pre, post, ...) \
592 ____PVOP_CALL(rettype, op, CLBR_ANY, PVOP_CALL_CLOBBERS, \
593 EXTRA_CLOBBERS, pre, post, ##__VA_ARGS__)
594
595#define __PVOP_CALLEESAVE(rettype, op, pre, post, ...) \
596 ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \
597 PVOP_CALLEE_CLOBBERS, , \
598 pre, post, ##__VA_ARGS__)
599
600
601#define ____PVOP_VCALL(op, clbr, call_clbr, extra_clbr, pre, post, ...) \
539 ({ \ 602 ({ \
540 PVOP_VCALL_ARGS; \ 603 PVOP_VCALL_ARGS; \
541 PVOP_TEST_NULL(op); \ 604 PVOP_TEST_NULL(op); \
542 asm volatile(pre \ 605 asm volatile(pre \
543 paravirt_alt(PARAVIRT_CALL) \ 606 paravirt_alt(PARAVIRT_CALL) \
544 post \ 607 post \
545 : PVOP_VCALL_CLOBBERS \ 608 : call_clbr \
546 : paravirt_type(op), \ 609 : paravirt_type(op), \
547 paravirt_clobber(CLBR_ANY), \ 610 paravirt_clobber(clbr), \
548 ##__VA_ARGS__ \ 611 ##__VA_ARGS__ \
549 : "memory", "cc" VEXTRA_CLOBBERS); \ 612 : "memory", "cc" extra_clbr); \
550 }) 613 })
551 614
615#define __PVOP_VCALL(op, pre, post, ...) \
616 ____PVOP_VCALL(op, CLBR_ANY, PVOP_VCALL_CLOBBERS, \
617 VEXTRA_CLOBBERS, \
618 pre, post, ##__VA_ARGS__)
619
620#define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...) \
621 ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \
622 PVOP_VCALLEE_CLOBBERS, , \
623 pre, post, ##__VA_ARGS__)
624
625
626
552#define PVOP_CALL0(rettype, op) \ 627#define PVOP_CALL0(rettype, op) \
553 __PVOP_CALL(rettype, op, "", "") 628 __PVOP_CALL(rettype, op, "", "")
554#define PVOP_VCALL0(op) \ 629#define PVOP_VCALL0(op) \
555 __PVOP_VCALL(op, "", "") 630 __PVOP_VCALL(op, "", "")
556 631
632#define PVOP_CALLEE0(rettype, op) \
633 __PVOP_CALLEESAVE(rettype, op, "", "")
634#define PVOP_VCALLEE0(op) \
635 __PVOP_VCALLEESAVE(op, "", "")
636
637
557#define PVOP_CALL1(rettype, op, arg1) \ 638#define PVOP_CALL1(rettype, op, arg1) \
558 __PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1))) 639 __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
559#define PVOP_VCALL1(op, arg1) \ 640#define PVOP_VCALL1(op, arg1) \
560 __PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1))) 641 __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1))
642
643#define PVOP_CALLEE1(rettype, op, arg1) \
644 __PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
645#define PVOP_VCALLEE1(op, arg1) \
646 __PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1))
647
561 648
562#define PVOP_CALL2(rettype, op, arg1, arg2) \ 649#define PVOP_CALL2(rettype, op, arg1, arg2) \
563 __PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1)), \ 650 __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \
564 "1" ((unsigned long)(arg2))) 651 PVOP_CALL_ARG2(arg2))
565#define PVOP_VCALL2(op, arg1, arg2) \ 652#define PVOP_VCALL2(op, arg1, arg2) \
566 __PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1)), \ 653 __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1), \
567 "1" ((unsigned long)(arg2))) 654 PVOP_CALL_ARG2(arg2))
655
656#define PVOP_CALLEE2(rettype, op, arg1, arg2) \
657 __PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \
658 PVOP_CALL_ARG2(arg2))
659#define PVOP_VCALLEE2(op, arg1, arg2) \
660 __PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1), \
661 PVOP_CALL_ARG2(arg2))
662
568 663
569#define PVOP_CALL3(rettype, op, arg1, arg2, arg3) \ 664#define PVOP_CALL3(rettype, op, arg1, arg2, arg3) \
570 __PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1)), \ 665 __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \
571 "1"((unsigned long)(arg2)), "2"((unsigned long)(arg3))) 666 PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
572#define PVOP_VCALL3(op, arg1, arg2, arg3) \ 667#define PVOP_VCALL3(op, arg1, arg2, arg3) \
573 __PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1)), \ 668 __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1), \
574 "1"((unsigned long)(arg2)), "2"((unsigned long)(arg3))) 669 PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
575 670
576/* This is the only difference in x86_64. We can make it much simpler */ 671/* This is the only difference in x86_64. We can make it much simpler */
577#ifdef CONFIG_X86_32 672#ifdef CONFIG_X86_32
578#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \ 673#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \
579 __PVOP_CALL(rettype, op, \ 674 __PVOP_CALL(rettype, op, \
580 "push %[_arg4];", "lea 4(%%esp),%%esp;", \ 675 "push %[_arg4];", "lea 4(%%esp),%%esp;", \
581 "0" ((u32)(arg1)), "1" ((u32)(arg2)), \ 676 PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \
582 "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4))) 677 PVOP_CALL_ARG3(arg3), [_arg4] "mr" ((u32)(arg4)))
583#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \ 678#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \
584 __PVOP_VCALL(op, \ 679 __PVOP_VCALL(op, \
585 "push %[_arg4];", "lea 4(%%esp),%%esp;", \ 680 "push %[_arg4];", "lea 4(%%esp),%%esp;", \
@@ -587,13 +682,13 @@ int paravirt_disable_iospace(void);
587 "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4))) 682 "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4)))
588#else 683#else
589#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \ 684#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \
590 __PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1)), \ 685 __PVOP_CALL(rettype, op, "", "", \
591 "1"((unsigned long)(arg2)), "2"((unsigned long)(arg3)), \ 686 PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \
592 "3"((unsigned long)(arg4))) 687 PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
593#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \ 688#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \
594 __PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1)), \ 689 __PVOP_VCALL(op, "", "", \
595 "1"((unsigned long)(arg2)), "2"((unsigned long)(arg3)), \ 690 PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \
596 "3"((unsigned long)(arg4))) 691 PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
597#endif 692#endif
598 693
599static inline int paravirt_enabled(void) 694static inline int paravirt_enabled(void)
@@ -1060,13 +1155,13 @@ static inline pte_t __pte(pteval_t val)
1060 pteval_t ret; 1155 pteval_t ret;
1061 1156
1062 if (sizeof(pteval_t) > sizeof(long)) 1157 if (sizeof(pteval_t) > sizeof(long))
1063 ret = PVOP_CALL2(pteval_t, 1158 ret = PVOP_CALLEE2(pteval_t,
1064 pv_mmu_ops.make_pte, 1159 pv_mmu_ops.make_pte,
1065 val, (u64)val >> 32); 1160 val, (u64)val >> 32);
1066 else 1161 else
1067 ret = PVOP_CALL1(pteval_t, 1162 ret = PVOP_CALLEE1(pteval_t,
1068 pv_mmu_ops.make_pte, 1163 pv_mmu_ops.make_pte,
1069 val); 1164 val);
1070 1165
1071 return (pte_t) { .pte = ret }; 1166 return (pte_t) { .pte = ret };
1072} 1167}
@@ -1076,11 +1171,11 @@ static inline pteval_t pte_val(pte_t pte)
1076 pteval_t ret; 1171 pteval_t ret;
1077 1172
1078 if (sizeof(pteval_t) > sizeof(long)) 1173 if (sizeof(pteval_t) > sizeof(long))
1079 ret = PVOP_CALL2(pteval_t, pv_mmu_ops.pte_val, 1174 ret = PVOP_CALLEE2(pteval_t, pv_mmu_ops.pte_val,
1080 pte.pte, (u64)pte.pte >> 32); 1175 pte.pte, (u64)pte.pte >> 32);
1081 else 1176 else
1082 ret = PVOP_CALL1(pteval_t, pv_mmu_ops.pte_val, 1177 ret = PVOP_CALLEE1(pteval_t, pv_mmu_ops.pte_val,
1083 pte.pte); 1178 pte.pte);
1084 1179
1085 return ret; 1180 return ret;
1086} 1181}
@@ -1090,11 +1185,11 @@ static inline pgd_t __pgd(pgdval_t val)
1090 pgdval_t ret; 1185 pgdval_t ret;
1091 1186
1092 if (sizeof(pgdval_t) > sizeof(long)) 1187 if (sizeof(pgdval_t) > sizeof(long))
1093 ret = PVOP_CALL2(pgdval_t, pv_mmu_ops.make_pgd, 1188 ret = PVOP_CALLEE2(pgdval_t, pv_mmu_ops.make_pgd,
1094 val, (u64)val >> 32); 1189 val, (u64)val >> 32);
1095 else 1190 else
1096 ret = PVOP_CALL1(pgdval_t, pv_mmu_ops.make_pgd, 1191 ret = PVOP_CALLEE1(pgdval_t, pv_mmu_ops.make_pgd,
1097 val); 1192 val);
1098 1193
1099 return (pgd_t) { ret }; 1194 return (pgd_t) { ret };
1100} 1195}
@@ -1104,11 +1199,11 @@ static inline pgdval_t pgd_val(pgd_t pgd)
1104 pgdval_t ret; 1199 pgdval_t ret;
1105 1200
1106 if (sizeof(pgdval_t) > sizeof(long)) 1201 if (sizeof(pgdval_t) > sizeof(long))
1107 ret = PVOP_CALL2(pgdval_t, pv_mmu_ops.pgd_val, 1202 ret = PVOP_CALLEE2(pgdval_t, pv_mmu_ops.pgd_val,
1108 pgd.pgd, (u64)pgd.pgd >> 32); 1203 pgd.pgd, (u64)pgd.pgd >> 32);
1109 else 1204 else
1110 ret = PVOP_CALL1(pgdval_t, pv_mmu_ops.pgd_val, 1205 ret = PVOP_CALLEE1(pgdval_t, pv_mmu_ops.pgd_val,
1111 pgd.pgd); 1206 pgd.pgd);
1112 1207
1113 return ret; 1208 return ret;
1114} 1209}
@@ -1172,11 +1267,11 @@ static inline pmd_t __pmd(pmdval_t val)
1172 pmdval_t ret; 1267 pmdval_t ret;
1173 1268
1174 if (sizeof(pmdval_t) > sizeof(long)) 1269 if (sizeof(pmdval_t) > sizeof(long))
1175 ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.make_pmd, 1270 ret = PVOP_CALLEE2(pmdval_t, pv_mmu_ops.make_pmd,
1176 val, (u64)val >> 32); 1271 val, (u64)val >> 32);
1177 else 1272 else
1178 ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.make_pmd, 1273 ret = PVOP_CALLEE1(pmdval_t, pv_mmu_ops.make_pmd,
1179 val); 1274 val);
1180 1275
1181 return (pmd_t) { ret }; 1276 return (pmd_t) { ret };
1182} 1277}
@@ -1186,11 +1281,11 @@ static inline pmdval_t pmd_val(pmd_t pmd)
1186 pmdval_t ret; 1281 pmdval_t ret;
1187 1282
1188 if (sizeof(pmdval_t) > sizeof(long)) 1283 if (sizeof(pmdval_t) > sizeof(long))
1189 ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.pmd_val, 1284 ret = PVOP_CALLEE2(pmdval_t, pv_mmu_ops.pmd_val,
1190 pmd.pmd, (u64)pmd.pmd >> 32); 1285 pmd.pmd, (u64)pmd.pmd >> 32);
1191 else 1286 else
1192 ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.pmd_val, 1287 ret = PVOP_CALLEE1(pmdval_t, pv_mmu_ops.pmd_val,
1193 pmd.pmd); 1288 pmd.pmd);
1194 1289
1195 return ret; 1290 return ret;
1196} 1291}
@@ -1212,11 +1307,11 @@ static inline pud_t __pud(pudval_t val)
1212 pudval_t ret; 1307 pudval_t ret;
1213 1308
1214 if (sizeof(pudval_t) > sizeof(long)) 1309 if (sizeof(pudval_t) > sizeof(long))
1215 ret = PVOP_CALL2(pudval_t, pv_mmu_ops.make_pud, 1310 ret = PVOP_CALLEE2(pudval_t, pv_mmu_ops.make_pud,
1216 val, (u64)val >> 32); 1311 val, (u64)val >> 32);
1217 else 1312 else
1218 ret = PVOP_CALL1(pudval_t, pv_mmu_ops.make_pud, 1313 ret = PVOP_CALLEE1(pudval_t, pv_mmu_ops.make_pud,
1219 val); 1314 val);
1220 1315
1221 return (pud_t) { ret }; 1316 return (pud_t) { ret };
1222} 1317}
@@ -1226,11 +1321,11 @@ static inline pudval_t pud_val(pud_t pud)
1226 pudval_t ret; 1321 pudval_t ret;
1227 1322
1228 if (sizeof(pudval_t) > sizeof(long)) 1323 if (sizeof(pudval_t) > sizeof(long))
1229 ret = PVOP_CALL2(pudval_t, pv_mmu_ops.pud_val, 1324 ret = PVOP_CALLEE2(pudval_t, pv_mmu_ops.pud_val,
1230 pud.pud, (u64)pud.pud >> 32); 1325 pud.pud, (u64)pud.pud >> 32);
1231 else 1326 else
1232 ret = PVOP_CALL1(pudval_t, pv_mmu_ops.pud_val, 1327 ret = PVOP_CALLEE1(pudval_t, pv_mmu_ops.pud_val,
1233 pud.pud); 1328 pud.pud);
1234 1329
1235 return ret; 1330 return ret;
1236} 1331}
@@ -1371,6 +1466,9 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
1371} 1466}
1372 1467
1373void _paravirt_nop(void); 1468void _paravirt_nop(void);
1469u32 _paravirt_ident_32(u32);
1470u64 _paravirt_ident_64(u64);
1471
1374#define paravirt_nop ((void *)_paravirt_nop) 1472#define paravirt_nop ((void *)_paravirt_nop)
1375 1473
1376#ifdef CONFIG_SMP 1474#ifdef CONFIG_SMP
@@ -1420,12 +1518,37 @@ extern struct paravirt_patch_site __parainstructions[],
1420 __parainstructions_end[]; 1518 __parainstructions_end[];
1421 1519
1422#ifdef CONFIG_X86_32 1520#ifdef CONFIG_X86_32
1423#define PV_SAVE_REGS "pushl %%ecx; pushl %%edx;" 1521#define PV_SAVE_REGS "pushl %ecx; pushl %edx;"
1424#define PV_RESTORE_REGS "popl %%edx; popl %%ecx" 1522#define PV_RESTORE_REGS "popl %edx; popl %ecx;"
1523
1524/* save and restore all caller-save registers, except return value */
1525#define PV_SAVE_ALL_CALLER_REGS "pushl %ecx;"
1526#define PV_RESTORE_ALL_CALLER_REGS "popl %ecx;"
1527
1425#define PV_FLAGS_ARG "0" 1528#define PV_FLAGS_ARG "0"
1426#define PV_EXTRA_CLOBBERS 1529#define PV_EXTRA_CLOBBERS
1427#define PV_VEXTRA_CLOBBERS 1530#define PV_VEXTRA_CLOBBERS
1428#else 1531#else
1532/* save and restore all caller-save registers, except return value */
1533#define PV_SAVE_ALL_CALLER_REGS \
1534 "push %rcx;" \
1535 "push %rdx;" \
1536 "push %rsi;" \
1537 "push %rdi;" \
1538 "push %r8;" \
1539 "push %r9;" \
1540 "push %r10;" \
1541 "push %r11;"
1542#define PV_RESTORE_ALL_CALLER_REGS \
1543 "pop %r11;" \
1544 "pop %r10;" \
1545 "pop %r9;" \
1546 "pop %r8;" \
1547 "pop %rdi;" \
1548 "pop %rsi;" \
1549 "pop %rdx;" \
1550 "pop %rcx;"
1551
1429/* We save some registers, but all of them, that's too much. We clobber all 1552/* We save some registers, but all of them, that's too much. We clobber all
1430 * caller saved registers but the argument parameter */ 1553 * caller saved registers but the argument parameter */
1431#define PV_SAVE_REGS "pushq %%rdi;" 1554#define PV_SAVE_REGS "pushq %%rdi;"
@@ -1435,52 +1558,76 @@ extern struct paravirt_patch_site __parainstructions[],
1435#define PV_FLAGS_ARG "D" 1558#define PV_FLAGS_ARG "D"
1436#endif 1559#endif
1437 1560
1561/*
1562 * Generate a thunk around a function which saves all caller-save
1563 * registers except for the return value. This allows C functions to
1564 * be called from assembler code where fewer than normal registers are
1565 * available. It may also help code generation around calls from C
1566 * code if the common case doesn't use many registers.
1567 *
1568 * When a callee is wrapped in a thunk, the caller can assume that all
1569 * arg regs and all scratch registers are preserved across the
1570 * call. The return value in rax/eax will not be saved, even for void
1571 * functions.
1572 */
1573#define PV_CALLEE_SAVE_REGS_THUNK(func) \
1574 extern typeof(func) __raw_callee_save_##func; \
1575 static void *__##func##__ __used = func; \
1576 \
1577 asm(".pushsection .text;" \
1578 "__raw_callee_save_" #func ": " \
1579 PV_SAVE_ALL_CALLER_REGS \
1580 "call " #func ";" \
1581 PV_RESTORE_ALL_CALLER_REGS \
1582 "ret;" \
1583 ".popsection")
1584
1585/* Get a reference to a callee-save function */
1586#define PV_CALLEE_SAVE(func) \
1587 ((struct paravirt_callee_save) { __raw_callee_save_##func })
1588
1589/* Promise that "func" already uses the right calling convention */
1590#define __PV_IS_CALLEE_SAVE(func) \
1591 ((struct paravirt_callee_save) { func })
1592
1438static inline unsigned long __raw_local_save_flags(void) 1593static inline unsigned long __raw_local_save_flags(void)
1439{ 1594{
1440 unsigned long f; 1595 unsigned long f;
1441 1596
1442 asm volatile(paravirt_alt(PV_SAVE_REGS 1597 asm volatile(paravirt_alt(PARAVIRT_CALL)
1443 PARAVIRT_CALL
1444 PV_RESTORE_REGS)
1445 : "=a"(f) 1598 : "=a"(f)
1446 : paravirt_type(pv_irq_ops.save_fl), 1599 : paravirt_type(pv_irq_ops.save_fl),
1447 paravirt_clobber(CLBR_EAX) 1600 paravirt_clobber(CLBR_EAX)
1448 : "memory", "cc" PV_VEXTRA_CLOBBERS); 1601 : "memory", "cc");
1449 return f; 1602 return f;
1450} 1603}
1451 1604
1452static inline void raw_local_irq_restore(unsigned long f) 1605static inline void raw_local_irq_restore(unsigned long f)
1453{ 1606{
1454 asm volatile(paravirt_alt(PV_SAVE_REGS 1607 asm volatile(paravirt_alt(PARAVIRT_CALL)
1455 PARAVIRT_CALL
1456 PV_RESTORE_REGS)
1457 : "=a"(f) 1608 : "=a"(f)
1458 : PV_FLAGS_ARG(f), 1609 : PV_FLAGS_ARG(f),
1459 paravirt_type(pv_irq_ops.restore_fl), 1610 paravirt_type(pv_irq_ops.restore_fl),
1460 paravirt_clobber(CLBR_EAX) 1611 paravirt_clobber(CLBR_EAX)
1461 : "memory", "cc" PV_EXTRA_CLOBBERS); 1612 : "memory", "cc");
1462} 1613}
1463 1614
1464static inline void raw_local_irq_disable(void) 1615static inline void raw_local_irq_disable(void)
1465{ 1616{
1466 asm volatile(paravirt_alt(PV_SAVE_REGS 1617 asm volatile(paravirt_alt(PARAVIRT_CALL)
1467 PARAVIRT_CALL
1468 PV_RESTORE_REGS)
1469 : 1618 :
1470 : paravirt_type(pv_irq_ops.irq_disable), 1619 : paravirt_type(pv_irq_ops.irq_disable),
1471 paravirt_clobber(CLBR_EAX) 1620 paravirt_clobber(CLBR_EAX)
1472 : "memory", "eax", "cc" PV_EXTRA_CLOBBERS); 1621 : "memory", "eax", "cc");
1473} 1622}
1474 1623
1475static inline void raw_local_irq_enable(void) 1624static inline void raw_local_irq_enable(void)
1476{ 1625{
1477 asm volatile(paravirt_alt(PV_SAVE_REGS 1626 asm volatile(paravirt_alt(PARAVIRT_CALL)
1478 PARAVIRT_CALL
1479 PV_RESTORE_REGS)
1480 : 1627 :
1481 : paravirt_type(pv_irq_ops.irq_enable), 1628 : paravirt_type(pv_irq_ops.irq_enable),
1482 paravirt_clobber(CLBR_EAX) 1629 paravirt_clobber(CLBR_EAX)
1483 : "memory", "eax", "cc" PV_EXTRA_CLOBBERS); 1630 : "memory", "eax", "cc");
1484} 1631}
1485 1632
1486static inline unsigned long __raw_local_irq_save(void) 1633static inline unsigned long __raw_local_irq_save(void)
@@ -1523,33 +1670,49 @@ static inline unsigned long __raw_local_irq_save(void)
1523 .popsection 1670 .popsection
1524 1671
1525 1672
1673#define COND_PUSH(set, mask, reg) \
1674 .if ((~(set)) & mask); push %reg; .endif
1675#define COND_POP(set, mask, reg) \
1676 .if ((~(set)) & mask); pop %reg; .endif
1677
1526#ifdef CONFIG_X86_64 1678#ifdef CONFIG_X86_64
1527#define PV_SAVE_REGS \ 1679
1528 push %rax; \ 1680#define PV_SAVE_REGS(set) \
1529 push %rcx; \ 1681 COND_PUSH(set, CLBR_RAX, rax); \
1530 push %rdx; \ 1682 COND_PUSH(set, CLBR_RCX, rcx); \
1531 push %rsi; \ 1683 COND_PUSH(set, CLBR_RDX, rdx); \
1532 push %rdi; \ 1684 COND_PUSH(set, CLBR_RSI, rsi); \
1533 push %r8; \ 1685 COND_PUSH(set, CLBR_RDI, rdi); \
1534 push %r9; \ 1686 COND_PUSH(set, CLBR_R8, r8); \
1535 push %r10; \ 1687 COND_PUSH(set, CLBR_R9, r9); \
1536 push %r11 1688 COND_PUSH(set, CLBR_R10, r10); \
1537#define PV_RESTORE_REGS \ 1689 COND_PUSH(set, CLBR_R11, r11)
1538 pop %r11; \ 1690#define PV_RESTORE_REGS(set) \
1539 pop %r10; \ 1691 COND_POP(set, CLBR_R11, r11); \
1540 pop %r9; \ 1692 COND_POP(set, CLBR_R10, r10); \
1541 pop %r8; \ 1693 COND_POP(set, CLBR_R9, r9); \
1542 pop %rdi; \ 1694 COND_POP(set, CLBR_R8, r8); \
1543 pop %rsi; \ 1695 COND_POP(set, CLBR_RDI, rdi); \
1544 pop %rdx; \ 1696 COND_POP(set, CLBR_RSI, rsi); \
1545 pop %rcx; \ 1697 COND_POP(set, CLBR_RDX, rdx); \
1546 pop %rax 1698 COND_POP(set, CLBR_RCX, rcx); \
1699 COND_POP(set, CLBR_RAX, rax)
1700
1547#define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 8) 1701#define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 8)
1548#define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8) 1702#define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8)
1549#define PARA_INDIRECT(addr) *addr(%rip) 1703#define PARA_INDIRECT(addr) *addr(%rip)
1550#else 1704#else
1551#define PV_SAVE_REGS pushl %eax; pushl %edi; pushl %ecx; pushl %edx 1705#define PV_SAVE_REGS(set) \
1552#define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax 1706 COND_PUSH(set, CLBR_EAX, eax); \
1707 COND_PUSH(set, CLBR_EDI, edi); \
1708 COND_PUSH(set, CLBR_ECX, ecx); \
1709 COND_PUSH(set, CLBR_EDX, edx)
1710#define PV_RESTORE_REGS(set) \
1711 COND_POP(set, CLBR_EDX, edx); \
1712 COND_POP(set, CLBR_ECX, ecx); \
1713 COND_POP(set, CLBR_EDI, edi); \
1714 COND_POP(set, CLBR_EAX, eax)
1715
1553#define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4) 1716#define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
1554#define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4) 1717#define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
1555#define PARA_INDIRECT(addr) *%cs:addr 1718#define PARA_INDIRECT(addr) *%cs:addr
@@ -1561,15 +1724,15 @@ static inline unsigned long __raw_local_irq_save(void)
1561 1724
1562#define DISABLE_INTERRUPTS(clobbers) \ 1725#define DISABLE_INTERRUPTS(clobbers) \
1563 PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \ 1726 PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
1564 PV_SAVE_REGS; \ 1727 PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \
1565 call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_disable); \ 1728 call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_disable); \
1566 PV_RESTORE_REGS;) \ 1729 PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
1567 1730
1568#define ENABLE_INTERRUPTS(clobbers) \ 1731#define ENABLE_INTERRUPTS(clobbers) \
1569 PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \ 1732 PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \
1570 PV_SAVE_REGS; \ 1733 PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \
1571 call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable); \ 1734 call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable); \
1572 PV_RESTORE_REGS;) 1735 PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
1573 1736
1574#define USERGS_SYSRET32 \ 1737#define USERGS_SYSRET32 \
1575 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret32), \ 1738 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret32), \
@@ -1599,11 +1762,15 @@ static inline unsigned long __raw_local_irq_save(void)
1599 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \ 1762 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \
1600 swapgs) 1763 swapgs)
1601 1764
1765/*
1766 * Note: swapgs is very special, and in practise is either going to be
1767 * implemented with a single "swapgs" instruction or something very
1768 * special. Either way, we don't need to save any registers for
1769 * it.
1770 */
1602#define SWAPGS \ 1771#define SWAPGS \
1603 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \ 1772 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \
1604 PV_SAVE_REGS; \ 1773 call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs) \
1605 call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs); \
1606 PV_RESTORE_REGS \
1607 ) 1774 )
1608 1775
1609#define GET_CR2_INTO_RCX \ 1776#define GET_CR2_INTO_RCX \