diff options
Diffstat (limited to 'include/asm-x86/paravirt.h')
-rw-r--r-- | include/asm-x86/paravirt.h | 229 |
1 files changed, 196 insertions, 33 deletions
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 0f13b945e240..695ce9383f52 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h | |||
@@ -84,7 +84,7 @@ struct pv_time_ops { | |||
84 | int (*set_wallclock)(unsigned long); | 84 | int (*set_wallclock)(unsigned long); |
85 | 85 | ||
86 | unsigned long long (*sched_clock)(void); | 86 | unsigned long long (*sched_clock)(void); |
87 | unsigned long (*get_cpu_khz)(void); | 87 | unsigned long (*get_tsc_khz)(void); |
88 | }; | 88 | }; |
89 | 89 | ||
90 | struct pv_cpu_ops { | 90 | struct pv_cpu_ops { |
@@ -115,6 +115,9 @@ struct pv_cpu_ops { | |||
115 | void (*set_ldt)(const void *desc, unsigned entries); | 115 | void (*set_ldt)(const void *desc, unsigned entries); |
116 | unsigned long (*store_tr)(void); | 116 | unsigned long (*store_tr)(void); |
117 | void (*load_tls)(struct thread_struct *t, unsigned int cpu); | 117 | void (*load_tls)(struct thread_struct *t, unsigned int cpu); |
118 | #ifdef CONFIG_X86_64 | ||
119 | void (*load_gs_index)(unsigned int idx); | ||
120 | #endif | ||
118 | void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum, | 121 | void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum, |
119 | const void *desc); | 122 | const void *desc); |
120 | void (*write_gdt_entry)(struct desc_struct *, | 123 | void (*write_gdt_entry)(struct desc_struct *, |
@@ -141,8 +144,32 @@ struct pv_cpu_ops { | |||
141 | u64 (*read_pmc)(int counter); | 144 | u64 (*read_pmc)(int counter); |
142 | unsigned long long (*read_tscp)(unsigned int *aux); | 145 | unsigned long long (*read_tscp)(unsigned int *aux); |
143 | 146 | ||
144 | /* These two are jmp to, not actually called. */ | 147 | /* |
145 | void (*irq_enable_syscall_ret)(void); | 148 | * Atomically enable interrupts and return to userspace. This |
149 | * is only ever used to return to 32-bit processes; in a | ||
150 | * 64-bit kernel, it's used for 32-on-64 compat processes, but | ||
151 | * never native 64-bit processes. (Jump, not call.) | ||
152 | */ | ||
153 | void (*irq_enable_sysexit)(void); | ||
154 | |||
155 | /* | ||
156 | * Switch to usermode gs and return to 64-bit usermode using | ||
157 | * sysret. Only used in 64-bit kernels to return to 64-bit | ||
158 | * processes. Usermode register state, including %rsp, must | ||
159 | * already be restored. | ||
160 | */ | ||
161 | void (*usergs_sysret64)(void); | ||
162 | |||
163 | /* | ||
164 | * Switch to usermode gs and return to 32-bit usermode using | ||
165 | * sysret. Used to return to 32-on-64 compat processes. | ||
166 | * Other usermode register state, including %esp, must already | ||
167 | * be restored. | ||
168 | */ | ||
169 | void (*usergs_sysret32)(void); | ||
170 | |||
171 | /* Normal iret. Jump to this with the standard iret stack | ||
172 | frame set up. */ | ||
146 | void (*iret)(void); | 173 | void (*iret)(void); |
147 | 174 | ||
148 | void (*swapgs)(void); | 175 | void (*swapgs)(void); |
@@ -165,6 +192,10 @@ struct pv_irq_ops { | |||
165 | void (*irq_enable)(void); | 192 | void (*irq_enable)(void); |
166 | void (*safe_halt)(void); | 193 | void (*safe_halt)(void); |
167 | void (*halt)(void); | 194 | void (*halt)(void); |
195 | |||
196 | #ifdef CONFIG_X86_64 | ||
197 | void (*adjust_exception_frame)(void); | ||
198 | #endif | ||
168 | }; | 199 | }; |
169 | 200 | ||
170 | struct pv_apic_ops { | 201 | struct pv_apic_ops { |
@@ -174,7 +205,6 @@ struct pv_apic_ops { | |||
174 | * these shouldn't be in this interface. | 205 | * these shouldn't be in this interface. |
175 | */ | 206 | */ |
176 | void (*apic_write)(unsigned long reg, u32 v); | 207 | void (*apic_write)(unsigned long reg, u32 v); |
177 | void (*apic_write_atomic)(unsigned long reg, u32 v); | ||
178 | u32 (*apic_read)(unsigned long reg); | 208 | u32 (*apic_read)(unsigned long reg); |
179 | void (*setup_boot_clock)(void); | 209 | void (*setup_boot_clock)(void); |
180 | void (*setup_secondary_clock)(void); | 210 | void (*setup_secondary_clock)(void); |
@@ -219,7 +249,14 @@ struct pv_mmu_ops { | |||
219 | void (*flush_tlb_others)(const cpumask_t *cpus, struct mm_struct *mm, | 249 | void (*flush_tlb_others)(const cpumask_t *cpus, struct mm_struct *mm, |
220 | unsigned long va); | 250 | unsigned long va); |
221 | 251 | ||
222 | /* Hooks for allocating/releasing pagetable pages */ | 252 | /* Hooks for allocating and freeing a pagetable top-level */ |
253 | int (*pgd_alloc)(struct mm_struct *mm); | ||
254 | void (*pgd_free)(struct mm_struct *mm, pgd_t *pgd); | ||
255 | |||
256 | /* | ||
257 | * Hooks for allocating/releasing pagetable pages when they're | ||
258 | * attached to a pagetable | ||
259 | */ | ||
223 | void (*alloc_pte)(struct mm_struct *mm, u32 pfn); | 260 | void (*alloc_pte)(struct mm_struct *mm, u32 pfn); |
224 | void (*alloc_pmd)(struct mm_struct *mm, u32 pfn); | 261 | void (*alloc_pmd)(struct mm_struct *mm, u32 pfn); |
225 | void (*alloc_pmd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count); | 262 | void (*alloc_pmd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count); |
@@ -238,7 +275,13 @@ struct pv_mmu_ops { | |||
238 | void (*pte_update_defer)(struct mm_struct *mm, | 275 | void (*pte_update_defer)(struct mm_struct *mm, |
239 | unsigned long addr, pte_t *ptep); | 276 | unsigned long addr, pte_t *ptep); |
240 | 277 | ||
278 | pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr, | ||
279 | pte_t *ptep); | ||
280 | void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr, | ||
281 | pte_t *ptep, pte_t pte); | ||
282 | |||
241 | pteval_t (*pte_val)(pte_t); | 283 | pteval_t (*pte_val)(pte_t); |
284 | pteval_t (*pte_flags)(pte_t); | ||
242 | pte_t (*make_pte)(pteval_t pte); | 285 | pte_t (*make_pte)(pteval_t pte); |
243 | 286 | ||
244 | pgdval_t (*pgd_val)(pgd_t); | 287 | pgdval_t (*pgd_val)(pgd_t); |
@@ -273,6 +316,13 @@ struct pv_mmu_ops { | |||
273 | #endif | 316 | #endif |
274 | 317 | ||
275 | struct pv_lazy_ops lazy_mode; | 318 | struct pv_lazy_ops lazy_mode; |
319 | |||
320 | /* dom0 ops */ | ||
321 | |||
322 | /* Sometimes the physical address is a pfn, and sometimes its | ||
323 | an mfn. We can tell which is which from the index. */ | ||
324 | void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx, | ||
325 | unsigned long phys, pgprot_t flags); | ||
276 | }; | 326 | }; |
277 | 327 | ||
278 | /* This contains all the paravirt structures: we get a convenient | 328 | /* This contains all the paravirt structures: we get a convenient |
@@ -439,10 +489,17 @@ int paravirt_disable_iospace(void); | |||
439 | #define VEXTRA_CLOBBERS , "rax", "r8", "r9", "r10", "r11" | 489 | #define VEXTRA_CLOBBERS , "rax", "r8", "r9", "r10", "r11" |
440 | #endif | 490 | #endif |
441 | 491 | ||
492 | #ifdef CONFIG_PARAVIRT_DEBUG | ||
493 | #define PVOP_TEST_NULL(op) BUG_ON(op == NULL) | ||
494 | #else | ||
495 | #define PVOP_TEST_NULL(op) ((void)op) | ||
496 | #endif | ||
497 | |||
442 | #define __PVOP_CALL(rettype, op, pre, post, ...) \ | 498 | #define __PVOP_CALL(rettype, op, pre, post, ...) \ |
443 | ({ \ | 499 | ({ \ |
444 | rettype __ret; \ | 500 | rettype __ret; \ |
445 | PVOP_CALL_ARGS; \ | 501 | PVOP_CALL_ARGS; \ |
502 | PVOP_TEST_NULL(op); \ | ||
446 | /* This is 32-bit specific, but is okay in 64-bit */ \ | 503 | /* This is 32-bit specific, but is okay in 64-bit */ \ |
447 | /* since this condition will never hold */ \ | 504 | /* since this condition will never hold */ \ |
448 | if (sizeof(rettype) > sizeof(unsigned long)) { \ | 505 | if (sizeof(rettype) > sizeof(unsigned long)) { \ |
@@ -471,6 +528,7 @@ int paravirt_disable_iospace(void); | |||
471 | #define __PVOP_VCALL(op, pre, post, ...) \ | 528 | #define __PVOP_VCALL(op, pre, post, ...) \ |
472 | ({ \ | 529 | ({ \ |
473 | PVOP_VCALL_ARGS; \ | 530 | PVOP_VCALL_ARGS; \ |
531 | PVOP_TEST_NULL(op); \ | ||
474 | asm volatile(pre \ | 532 | asm volatile(pre \ |
475 | paravirt_alt(PARAVIRT_CALL) \ | 533 | paravirt_alt(PARAVIRT_CALL) \ |
476 | post \ | 534 | post \ |
@@ -720,7 +778,7 @@ static inline unsigned long long paravirt_sched_clock(void) | |||
720 | { | 778 | { |
721 | return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock); | 779 | return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock); |
722 | } | 780 | } |
723 | #define calculate_cpu_khz() (pv_time_ops.get_cpu_khz()) | 781 | #define calibrate_tsc() (pv_time_ops.get_tsc_khz()) |
724 | 782 | ||
725 | static inline unsigned long long paravirt_read_pmc(int counter) | 783 | static inline unsigned long long paravirt_read_pmc(int counter) |
726 | { | 784 | { |
@@ -789,6 +847,13 @@ static inline void load_TLS(struct thread_struct *t, unsigned cpu) | |||
789 | PVOP_VCALL2(pv_cpu_ops.load_tls, t, cpu); | 847 | PVOP_VCALL2(pv_cpu_ops.load_tls, t, cpu); |
790 | } | 848 | } |
791 | 849 | ||
850 | #ifdef CONFIG_X86_64 | ||
851 | static inline void load_gs_index(unsigned int gs) | ||
852 | { | ||
853 | PVOP_VCALL1(pv_cpu_ops.load_gs_index, gs); | ||
854 | } | ||
855 | #endif | ||
856 | |||
792 | static inline void write_ldt_entry(struct desc_struct *dt, int entry, | 857 | static inline void write_ldt_entry(struct desc_struct *dt, int entry, |
793 | const void *desc) | 858 | const void *desc) |
794 | { | 859 | { |
@@ -830,11 +895,6 @@ static inline void apic_write(unsigned long reg, u32 v) | |||
830 | PVOP_VCALL2(pv_apic_ops.apic_write, reg, v); | 895 | PVOP_VCALL2(pv_apic_ops.apic_write, reg, v); |
831 | } | 896 | } |
832 | 897 | ||
833 | static inline void apic_write_atomic(unsigned long reg, u32 v) | ||
834 | { | ||
835 | PVOP_VCALL2(pv_apic_ops.apic_write_atomic, reg, v); | ||
836 | } | ||
837 | |||
838 | static inline u32 apic_read(unsigned long reg) | 898 | static inline u32 apic_read(unsigned long reg) |
839 | { | 899 | { |
840 | return PVOP_CALL1(unsigned long, pv_apic_ops.apic_read, reg); | 900 | return PVOP_CALL1(unsigned long, pv_apic_ops.apic_read, reg); |
@@ -912,6 +972,16 @@ static inline void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, | |||
912 | PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, &cpumask, mm, va); | 972 | PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, &cpumask, mm, va); |
913 | } | 973 | } |
914 | 974 | ||
975 | static inline int paravirt_pgd_alloc(struct mm_struct *mm) | ||
976 | { | ||
977 | return PVOP_CALL1(int, pv_mmu_ops.pgd_alloc, mm); | ||
978 | } | ||
979 | |||
980 | static inline void paravirt_pgd_free(struct mm_struct *mm, pgd_t *pgd) | ||
981 | { | ||
982 | PVOP_VCALL2(pv_mmu_ops.pgd_free, mm, pgd); | ||
983 | } | ||
984 | |||
915 | static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned pfn) | 985 | static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned pfn) |
916 | { | 986 | { |
917 | PVOP_VCALL2(pv_mmu_ops.alloc_pte, mm, pfn); | 987 | PVOP_VCALL2(pv_mmu_ops.alloc_pte, mm, pfn); |
@@ -996,6 +1066,20 @@ static inline pteval_t pte_val(pte_t pte) | |||
996 | return ret; | 1066 | return ret; |
997 | } | 1067 | } |
998 | 1068 | ||
1069 | static inline pteval_t pte_flags(pte_t pte) | ||
1070 | { | ||
1071 | pteval_t ret; | ||
1072 | |||
1073 | if (sizeof(pteval_t) > sizeof(long)) | ||
1074 | ret = PVOP_CALL2(pteval_t, pv_mmu_ops.pte_flags, | ||
1075 | pte.pte, (u64)pte.pte >> 32); | ||
1076 | else | ||
1077 | ret = PVOP_CALL1(pteval_t, pv_mmu_ops.pte_flags, | ||
1078 | pte.pte); | ||
1079 | |||
1080 | return ret; | ||
1081 | } | ||
1082 | |||
999 | static inline pgd_t __pgd(pgdval_t val) | 1083 | static inline pgd_t __pgd(pgdval_t val) |
1000 | { | 1084 | { |
1001 | pgdval_t ret; | 1085 | pgdval_t ret; |
@@ -1024,6 +1108,29 @@ static inline pgdval_t pgd_val(pgd_t pgd) | |||
1024 | return ret; | 1108 | return ret; |
1025 | } | 1109 | } |
1026 | 1110 | ||
1111 | #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION | ||
1112 | static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, | ||
1113 | pte_t *ptep) | ||
1114 | { | ||
1115 | pteval_t ret; | ||
1116 | |||
1117 | ret = PVOP_CALL3(pteval_t, pv_mmu_ops.ptep_modify_prot_start, | ||
1118 | mm, addr, ptep); | ||
1119 | |||
1120 | return (pte_t) { .pte = ret }; | ||
1121 | } | ||
1122 | |||
1123 | static inline void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, | ||
1124 | pte_t *ptep, pte_t pte) | ||
1125 | { | ||
1126 | if (sizeof(pteval_t) > sizeof(long)) | ||
1127 | /* 5 arg words */ | ||
1128 | pv_mmu_ops.ptep_modify_prot_commit(mm, addr, ptep, pte); | ||
1129 | else | ||
1130 | PVOP_VCALL4(pv_mmu_ops.ptep_modify_prot_commit, | ||
1131 | mm, addr, ptep, pte.pte); | ||
1132 | } | ||
1133 | |||
1027 | static inline void set_pte(pte_t *ptep, pte_t pte) | 1134 | static inline void set_pte(pte_t *ptep, pte_t pte) |
1028 | { | 1135 | { |
1029 | if (sizeof(pteval_t) > sizeof(long)) | 1136 | if (sizeof(pteval_t) > sizeof(long)) |
@@ -1252,6 +1359,12 @@ static inline void arch_flush_lazy_mmu_mode(void) | |||
1252 | } | 1359 | } |
1253 | } | 1360 | } |
1254 | 1361 | ||
1362 | static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, | ||
1363 | unsigned long phys, pgprot_t flags) | ||
1364 | { | ||
1365 | pv_mmu_ops.set_fixmap(idx, phys, flags); | ||
1366 | } | ||
1367 | |||
1255 | void _paravirt_nop(void); | 1368 | void _paravirt_nop(void); |
1256 | #define paravirt_nop ((void *)_paravirt_nop) | 1369 | #define paravirt_nop ((void *)_paravirt_nop) |
1257 | 1370 | ||
@@ -1277,8 +1390,8 @@ extern struct paravirt_patch_site __parainstructions[], | |||
1277 | * caller saved registers but the argument parameter */ | 1390 | * caller saved registers but the argument parameter */ |
1278 | #define PV_SAVE_REGS "pushq %%rdi;" | 1391 | #define PV_SAVE_REGS "pushq %%rdi;" |
1279 | #define PV_RESTORE_REGS "popq %%rdi;" | 1392 | #define PV_RESTORE_REGS "popq %%rdi;" |
1280 | #define PV_EXTRA_CLOBBERS EXTRA_CLOBBERS, "rcx" , "rdx" | 1393 | #define PV_EXTRA_CLOBBERS EXTRA_CLOBBERS, "rcx" , "rdx", "rsi" |
1281 | #define PV_VEXTRA_CLOBBERS EXTRA_CLOBBERS, "rdi", "rcx" , "rdx" | 1394 | #define PV_VEXTRA_CLOBBERS EXTRA_CLOBBERS, "rdi", "rcx" , "rdx", "rsi" |
1282 | #define PV_FLAGS_ARG "D" | 1395 | #define PV_FLAGS_ARG "D" |
1283 | #endif | 1396 | #endif |
1284 | 1397 | ||
@@ -1370,58 +1483,108 @@ static inline unsigned long __raw_local_irq_save(void) | |||
1370 | 1483 | ||
1371 | 1484 | ||
1372 | #ifdef CONFIG_X86_64 | 1485 | #ifdef CONFIG_X86_64 |
1373 | #define PV_SAVE_REGS pushq %rax; pushq %rdi; pushq %rcx; pushq %rdx | 1486 | #define PV_SAVE_REGS \ |
1374 | #define PV_RESTORE_REGS popq %rdx; popq %rcx; popq %rdi; popq %rax | 1487 | push %rax; \ |
1488 | push %rcx; \ | ||
1489 | push %rdx; \ | ||
1490 | push %rsi; \ | ||
1491 | push %rdi; \ | ||
1492 | push %r8; \ | ||
1493 | push %r9; \ | ||
1494 | push %r10; \ | ||
1495 | push %r11 | ||
1496 | #define PV_RESTORE_REGS \ | ||
1497 | pop %r11; \ | ||
1498 | pop %r10; \ | ||
1499 | pop %r9; \ | ||
1500 | pop %r8; \ | ||
1501 | pop %rdi; \ | ||
1502 | pop %rsi; \ | ||
1503 | pop %rdx; \ | ||
1504 | pop %rcx; \ | ||
1505 | pop %rax | ||
1375 | #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 8) | 1506 | #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 8) |
1376 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8) | 1507 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8) |
1508 | #define PARA_INDIRECT(addr) *addr(%rip) | ||
1377 | #else | 1509 | #else |
1378 | #define PV_SAVE_REGS pushl %eax; pushl %edi; pushl %ecx; pushl %edx | 1510 | #define PV_SAVE_REGS pushl %eax; pushl %edi; pushl %ecx; pushl %edx |
1379 | #define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax | 1511 | #define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax |
1380 | #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4) | 1512 | #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4) |
1381 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4) | 1513 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4) |
1514 | #define PARA_INDIRECT(addr) *%cs:addr | ||
1382 | #endif | 1515 | #endif |
1383 | 1516 | ||
1384 | #define INTERRUPT_RETURN \ | 1517 | #define INTERRUPT_RETURN \ |
1385 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \ | 1518 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \ |
1386 | jmp *%cs:pv_cpu_ops+PV_CPU_iret) | 1519 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret)) |
1387 | 1520 | ||
1388 | #define DISABLE_INTERRUPTS(clobbers) \ | 1521 | #define DISABLE_INTERRUPTS(clobbers) \ |
1389 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \ | 1522 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \ |
1390 | PV_SAVE_REGS; \ | 1523 | PV_SAVE_REGS; \ |
1391 | call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \ | 1524 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_disable); \ |
1392 | PV_RESTORE_REGS;) \ | 1525 | PV_RESTORE_REGS;) \ |
1393 | 1526 | ||
1394 | #define ENABLE_INTERRUPTS(clobbers) \ | 1527 | #define ENABLE_INTERRUPTS(clobbers) \ |
1395 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \ | 1528 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \ |
1396 | PV_SAVE_REGS; \ | 1529 | PV_SAVE_REGS; \ |
1397 | call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \ | 1530 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable); \ |
1398 | PV_RESTORE_REGS;) | 1531 | PV_RESTORE_REGS;) |
1399 | 1532 | ||
1400 | #define ENABLE_INTERRUPTS_SYSCALL_RET \ | 1533 | #define USERGS_SYSRET32 \ |
1401 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\ | 1534 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret32), \ |
1402 | CLBR_NONE, \ | 1535 | CLBR_NONE, \ |
1403 | jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret) | 1536 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret32)) |
1404 | |||
1405 | 1537 | ||
1406 | #ifdef CONFIG_X86_32 | 1538 | #ifdef CONFIG_X86_32 |
1407 | #define GET_CR0_INTO_EAX \ | 1539 | #define GET_CR0_INTO_EAX \ |
1408 | push %ecx; push %edx; \ | 1540 | push %ecx; push %edx; \ |
1409 | call *pv_cpu_ops+PV_CPU_read_cr0; \ | 1541 | call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \ |
1410 | pop %edx; pop %ecx | 1542 | pop %edx; pop %ecx |
1411 | #else | 1543 | |
1544 | #define ENABLE_INTERRUPTS_SYSEXIT \ | ||
1545 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), \ | ||
1546 | CLBR_NONE, \ | ||
1547 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit)) | ||
1548 | |||
1549 | |||
1550 | #else /* !CONFIG_X86_32 */ | ||
1551 | |||
1552 | /* | ||
1553 | * If swapgs is used while the userspace stack is still current, | ||
1554 | * there's no way to call a pvop. The PV replacement *must* be | ||
1555 | * inlined, or the swapgs instruction must be trapped and emulated. | ||
1556 | */ | ||
1557 | #define SWAPGS_UNSAFE_STACK \ | ||
1558 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \ | ||
1559 | swapgs) | ||
1560 | |||
1412 | #define SWAPGS \ | 1561 | #define SWAPGS \ |
1413 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \ | 1562 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \ |
1414 | PV_SAVE_REGS; \ | 1563 | PV_SAVE_REGS; \ |
1415 | call *pv_cpu_ops+PV_CPU_swapgs; \ | 1564 | call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs); \ |
1416 | PV_RESTORE_REGS \ | 1565 | PV_RESTORE_REGS \ |
1417 | ) | 1566 | ) |
1418 | 1567 | ||
1419 | #define GET_CR2_INTO_RCX \ | 1568 | #define GET_CR2_INTO_RCX \ |
1420 | call *pv_mmu_ops+PV_MMU_read_cr2; \ | 1569 | call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2); \ |
1421 | movq %rax, %rcx; \ | 1570 | movq %rax, %rcx; \ |
1422 | xorq %rax, %rax; | 1571 | xorq %rax, %rax; |
1423 | 1572 | ||
1424 | #endif | 1573 | #define PARAVIRT_ADJUST_EXCEPTION_FRAME \ |
1574 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \ | ||
1575 | CLBR_NONE, \ | ||
1576 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_adjust_exception_frame)) | ||
1577 | |||
1578 | #define USERGS_SYSRET64 \ | ||
1579 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64), \ | ||
1580 | CLBR_NONE, \ | ||
1581 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64)) | ||
1582 | |||
1583 | #define ENABLE_INTERRUPTS_SYSEXIT32 \ | ||
1584 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), \ | ||
1585 | CLBR_NONE, \ | ||
1586 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit)) | ||
1587 | #endif /* CONFIG_X86_32 */ | ||
1425 | 1588 | ||
1426 | #endif /* __ASSEMBLY__ */ | 1589 | #endif /* __ASSEMBLY__ */ |
1427 | #endif /* CONFIG_PARAVIRT */ | 1590 | #endif /* CONFIG_PARAVIRT */ |