diff options
Diffstat (limited to 'include/asm-x86/paravirt.h')
-rw-r--r-- | include/asm-x86/paravirt.h | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 19726e12051e..f59d370c5df4 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h | |||
@@ -25,15 +25,6 @@ struct tss_struct; | |||
25 | struct mm_struct; | 25 | struct mm_struct; |
26 | struct desc_struct; | 26 | struct desc_struct; |
27 | 27 | ||
28 | /* Lazy mode for batching updates / context switch */ | ||
29 | enum paravirt_lazy_mode { | ||
30 | PARAVIRT_LAZY_NONE = 0, | ||
31 | PARAVIRT_LAZY_MMU = 1, | ||
32 | PARAVIRT_LAZY_CPU = 2, | ||
33 | PARAVIRT_LAZY_FLUSH = 3, | ||
34 | }; | ||
35 | |||
36 | |||
37 | /* general info */ | 28 | /* general info */ |
38 | struct pv_info { | 29 | struct pv_info { |
39 | unsigned int kernel_rpl; | 30 | unsigned int kernel_rpl; |
@@ -64,9 +55,10 @@ struct pv_init_ops { | |||
64 | }; | 55 | }; |
65 | 56 | ||
66 | 57 | ||
67 | struct pv_misc_ops { | 58 | struct pv_lazy_ops { |
68 | /* Set deferred update mode, used for batching operations. */ | 59 | /* Set deferred update mode, used for batching operations. */ |
69 | void (*set_lazy_mode)(enum paravirt_lazy_mode mode); | 60 | void (*enter)(void); |
61 | void (*leave)(void); | ||
70 | }; | 62 | }; |
71 | 63 | ||
72 | struct pv_time_ops { | 64 | struct pv_time_ops { |
@@ -131,6 +123,8 @@ struct pv_cpu_ops { | |||
131 | /* These two are jmp to, not actually called. */ | 123 | /* These two are jmp to, not actually called. */ |
132 | void (*irq_enable_sysexit)(void); | 124 | void (*irq_enable_sysexit)(void); |
133 | void (*iret)(void); | 125 | void (*iret)(void); |
126 | |||
127 | struct pv_lazy_ops lazy_mode; | ||
134 | }; | 128 | }; |
135 | 129 | ||
136 | struct pv_irq_ops { | 130 | struct pv_irq_ops { |
@@ -244,6 +238,8 @@ struct pv_mmu_ops { | |||
244 | #ifdef CONFIG_HIGHPTE | 238 | #ifdef CONFIG_HIGHPTE |
245 | void *(*kmap_atomic_pte)(struct page *page, enum km_type type); | 239 | void *(*kmap_atomic_pte)(struct page *page, enum km_type type); |
246 | #endif | 240 | #endif |
241 | |||
242 | struct pv_lazy_ops lazy_mode; | ||
247 | }; | 243 | }; |
248 | 244 | ||
249 | /* This contains all the paravirt structures: we get a convenient | 245 | /* This contains all the paravirt structures: we get a convenient |
@@ -252,7 +248,6 @@ struct pv_mmu_ops { | |||
252 | struct paravirt_patch_template | 248 | struct paravirt_patch_template |
253 | { | 249 | { |
254 | struct pv_init_ops pv_init_ops; | 250 | struct pv_init_ops pv_init_ops; |
255 | struct pv_misc_ops pv_misc_ops; | ||
256 | struct pv_time_ops pv_time_ops; | 251 | struct pv_time_ops pv_time_ops; |
257 | struct pv_cpu_ops pv_cpu_ops; | 252 | struct pv_cpu_ops pv_cpu_ops; |
258 | struct pv_irq_ops pv_irq_ops; | 253 | struct pv_irq_ops pv_irq_ops; |
@@ -262,7 +257,6 @@ struct paravirt_patch_template | |||
262 | 257 | ||
263 | extern struct pv_info pv_info; | 258 | extern struct pv_info pv_info; |
264 | extern struct pv_init_ops pv_init_ops; | 259 | extern struct pv_init_ops pv_init_ops; |
265 | extern struct pv_misc_ops pv_misc_ops; | ||
266 | extern struct pv_time_ops pv_time_ops; | 260 | extern struct pv_time_ops pv_time_ops; |
267 | extern struct pv_cpu_ops pv_cpu_ops; | 261 | extern struct pv_cpu_ops pv_cpu_ops; |
268 | extern struct pv_irq_ops pv_irq_ops; | 262 | extern struct pv_irq_ops pv_irq_ops; |
@@ -953,37 +947,57 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval) | |||
953 | } | 947 | } |
954 | #endif /* CONFIG_X86_PAE */ | 948 | #endif /* CONFIG_X86_PAE */ |
955 | 949 | ||
950 | /* Lazy mode for batching updates / context switch */ | ||
951 | enum paravirt_lazy_mode { | ||
952 | PARAVIRT_LAZY_NONE, | ||
953 | PARAVIRT_LAZY_MMU, | ||
954 | PARAVIRT_LAZY_CPU, | ||
955 | }; | ||
956 | |||
957 | enum paravirt_lazy_mode paravirt_get_lazy_mode(void); | ||
958 | void paravirt_enter_lazy_cpu(void); | ||
959 | void paravirt_leave_lazy_cpu(void); | ||
960 | void paravirt_enter_lazy_mmu(void); | ||
961 | void paravirt_leave_lazy_mmu(void); | ||
962 | void paravirt_leave_lazy(enum paravirt_lazy_mode mode); | ||
963 | |||
956 | #define __HAVE_ARCH_ENTER_LAZY_CPU_MODE | 964 | #define __HAVE_ARCH_ENTER_LAZY_CPU_MODE |
957 | static inline void arch_enter_lazy_cpu_mode(void) | 965 | static inline void arch_enter_lazy_cpu_mode(void) |
958 | { | 966 | { |
959 | PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_CPU); | 967 | PVOP_VCALL0(pv_cpu_ops.lazy_mode.enter); |
960 | } | 968 | } |
961 | 969 | ||
962 | static inline void arch_leave_lazy_cpu_mode(void) | 970 | static inline void arch_leave_lazy_cpu_mode(void) |
963 | { | 971 | { |
964 | PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_NONE); | 972 | PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave); |
965 | } | 973 | } |
966 | 974 | ||
967 | static inline void arch_flush_lazy_cpu_mode(void) | 975 | static inline void arch_flush_lazy_cpu_mode(void) |
968 | { | 976 | { |
969 | PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_FLUSH); | 977 | if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)) { |
978 | arch_leave_lazy_cpu_mode(); | ||
979 | arch_enter_lazy_cpu_mode(); | ||
980 | } | ||
970 | } | 981 | } |
971 | 982 | ||
972 | 983 | ||
973 | #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE | 984 | #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE |
974 | static inline void arch_enter_lazy_mmu_mode(void) | 985 | static inline void arch_enter_lazy_mmu_mode(void) |
975 | { | 986 | { |
976 | PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_MMU); | 987 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.enter); |
977 | } | 988 | } |
978 | 989 | ||
979 | static inline void arch_leave_lazy_mmu_mode(void) | 990 | static inline void arch_leave_lazy_mmu_mode(void) |
980 | { | 991 | { |
981 | PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_NONE); | 992 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); |
982 | } | 993 | } |
983 | 994 | ||
984 | static inline void arch_flush_lazy_mmu_mode(void) | 995 | static inline void arch_flush_lazy_mmu_mode(void) |
985 | { | 996 | { |
986 | PVOP_VCALL1(pv_misc_ops.set_lazy_mode, PARAVIRT_LAZY_FLUSH); | 997 | if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU)) { |
998 | arch_leave_lazy_mmu_mode(); | ||
999 | arch_enter_lazy_mmu_mode(); | ||
1000 | } | ||
987 | } | 1001 | } |
988 | 1002 | ||
989 | void _paravirt_nop(void); | 1003 | void _paravirt_nop(void); |