xref: /openbmc/linux/arch/x86/include/asm/paravirt.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21965aae3SH. Peter Anvin #ifndef _ASM_X86_PARAVIRT_H
31965aae3SH. Peter Anvin #define _ASM_X86_PARAVIRT_H
4bb898558SAl Viro /* Various instructions on x86 need to be replaced for
5bb898558SAl Viro  * para-virtualization: those hooks are defined here. */
6bb898558SAl Viro 
7239f2e24SThomas Gleixner #include <asm/paravirt_types.h>
8239f2e24SThomas Gleixner 
9bb898558SAl Viro #ifdef CONFIG_PARAVIRT
1054321d94SJeremy Fitzhardinge #include <asm/pgtable_types.h>
11bb898558SAl Viro #include <asm/asm.h>
123010a066SPeter Zijlstra #include <asm/nospec-branch.h>
13bb898558SAl Viro 
14bb898558SAl Viro #ifndef __ASSEMBLY__
15187f1882SPaul Gortmaker #include <linux/bug.h>
16bb898558SAl Viro #include <linux/types.h>
17bb898558SAl Viro #include <linux/cpumask.h>
18a0e2bf7cSJuergen Gross #include <linux/static_call_types.h>
1987b240cbSJosh Poimboeuf #include <asm/frame.h>
20bb898558SAl Viro 
21a0e2bf7cSJuergen Gross u64 dummy_steal_clock(int cpu);
22a0e2bf7cSJuergen Gross u64 dummy_sched_clock(void);
23a0e2bf7cSJuergen Gross 
24a0e2bf7cSJuergen Gross DECLARE_STATIC_CALL(pv_steal_clock, dummy_steal_clock);
25a0e2bf7cSJuergen Gross DECLARE_STATIC_CALL(pv_sched_clock, dummy_sched_clock);
26a0e2bf7cSJuergen Gross 
27a0e2bf7cSJuergen Gross void paravirt_set_sched_clock(u64 (*func)(void));
28a0e2bf7cSJuergen Gross 
paravirt_sched_clock(void)298739c681SPeter Zijlstra static __always_inline u64 paravirt_sched_clock(void)
30fdc0269eSJuergen Gross {
31a0e2bf7cSJuergen Gross 	return static_call(pv_sched_clock)();
32fdc0269eSJuergen Gross }
33fdc0269eSJuergen Gross 
34fdc0269eSJuergen Gross struct static_key;
35fdc0269eSJuergen Gross extern struct static_key paravirt_steal_enabled;
36fdc0269eSJuergen Gross extern struct static_key paravirt_steal_rq_enabled;
37fdc0269eSJuergen Gross 
3889f579ceSYi Wang __visible void __native_queued_spin_unlock(struct qspinlock *lock);
3989f579ceSYi Wang bool pv_is_native_spin_unlock(void);
4089f579ceSYi Wang __visible bool __native_vcpu_is_preempted(long cpu);
4189f579ceSYi Wang bool pv_is_native_vcpu_is_preempted(void);
4289f579ceSYi Wang 
paravirt_steal_clock(int cpu)43fdc0269eSJuergen Gross static inline u64 paravirt_steal_clock(int cpu)
44fdc0269eSJuergen Gross {
45a0e2bf7cSJuergen Gross 	return static_call(pv_steal_clock)(cpu);
46fdc0269eSJuergen Gross }
47fdc0269eSJuergen Gross 
484e629211SJuergen Gross #ifdef CONFIG_PARAVIRT_SPINLOCKS
494e629211SJuergen Gross void __init paravirt_set_cap(void);
504e629211SJuergen Gross #endif
514e629211SJuergen Gross 
52fdc0269eSJuergen Gross /* The paravirtualized I/O functions */
slow_down_io(void)53fdc0269eSJuergen Gross static inline void slow_down_io(void)
54fdc0269eSJuergen Gross {
55eac46b32SPeter Zijlstra 	PVOP_VCALL0(cpu.io_delay);
56fdc0269eSJuergen Gross #ifdef REALLY_SLOW_IO
57eac46b32SPeter Zijlstra 	PVOP_VCALL0(cpu.io_delay);
58eac46b32SPeter Zijlstra 	PVOP_VCALL0(cpu.io_delay);
59eac46b32SPeter Zijlstra 	PVOP_VCALL0(cpu.io_delay);
60fdc0269eSJuergen Gross #endif
61fdc0269eSJuergen Gross }
62fdc0269eSJuergen Gross 
632faf153bSThomas Gleixner void native_flush_tlb_local(void);
64cd30d26cSThomas Gleixner void native_flush_tlb_global(void);
65127ac915SThomas Gleixner void native_flush_tlb_one_user(unsigned long addr);
664ce94eabSNadav Amit void native_flush_tlb_multi(const struct cpumask *cpumask,
6729def599SThomas Gleixner 			     const struct flush_tlb_info *info);
682faf153bSThomas Gleixner 
__flush_tlb_local(void)692faf153bSThomas Gleixner static inline void __flush_tlb_local(void)
70fdc0269eSJuergen Gross {
71fdc0269eSJuergen Gross 	PVOP_VCALL0(mmu.flush_tlb_user);
72fdc0269eSJuergen Gross }
73fdc0269eSJuergen Gross 
__flush_tlb_global(void)74fdc0269eSJuergen Gross static inline void __flush_tlb_global(void)
75fdc0269eSJuergen Gross {
76fdc0269eSJuergen Gross 	PVOP_VCALL0(mmu.flush_tlb_kernel);
77fdc0269eSJuergen Gross }
78fdc0269eSJuergen Gross 
__flush_tlb_one_user(unsigned long addr)79fdc0269eSJuergen Gross static inline void __flush_tlb_one_user(unsigned long addr)
80fdc0269eSJuergen Gross {
81fdc0269eSJuergen Gross 	PVOP_VCALL1(mmu.flush_tlb_one_user, addr);
82fdc0269eSJuergen Gross }
83fdc0269eSJuergen Gross 
__flush_tlb_multi(const struct cpumask * cpumask,const struct flush_tlb_info * info)844ce94eabSNadav Amit static inline void __flush_tlb_multi(const struct cpumask *cpumask,
85fdc0269eSJuergen Gross 				      const struct flush_tlb_info *info)
86fdc0269eSJuergen Gross {
874ce94eabSNadav Amit 	PVOP_VCALL2(mmu.flush_tlb_multi, cpumask, info);
88fdc0269eSJuergen Gross }
89fdc0269eSJuergen Gross 
paravirt_tlb_remove_table(struct mmu_gather * tlb,void * table)90fdc0269eSJuergen Gross static inline void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
91fdc0269eSJuergen Gross {
92fdc0269eSJuergen Gross 	PVOP_VCALL2(mmu.tlb_remove_table, tlb, table);
93fdc0269eSJuergen Gross }
94fdc0269eSJuergen Gross 
paravirt_arch_exit_mmap(struct mm_struct * mm)95fdc0269eSJuergen Gross static inline void paravirt_arch_exit_mmap(struct mm_struct *mm)
96fdc0269eSJuergen Gross {
97fdc0269eSJuergen Gross 	PVOP_VCALL1(mmu.exit_mmap, mm);
98fdc0269eSJuergen Gross }
99fdc0269eSJuergen Gross 
notify_page_enc_status_changed(unsigned long pfn,int npages,bool enc)100064ce6c5SBrijesh Singh static inline void notify_page_enc_status_changed(unsigned long pfn,
101064ce6c5SBrijesh Singh 						  int npages, bool enc)
102064ce6c5SBrijesh Singh {
103064ce6c5SBrijesh Singh 	PVOP_VCALL3(mmu.notify_page_enc_status_changed, pfn, npages, enc);
104064ce6c5SBrijesh Singh }
105064ce6c5SBrijesh Singh 
1069bad5658SJuergen Gross #ifdef CONFIG_PARAVIRT_XXL
load_sp0(unsigned long sp0)107da51da18SAndy Lutomirski static inline void load_sp0(unsigned long sp0)
108bb898558SAl Viro {
1095c83511bSJuergen Gross 	PVOP_VCALL1(cpu.load_sp0, sp0);
110bb898558SAl Viro }
111bb898558SAl Viro 
112bb898558SAl Viro /* The paravirtualized CPUID instruction. */
__cpuid(unsigned int * eax,unsigned int * ebx,unsigned int * ecx,unsigned int * edx)113bb898558SAl Viro static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
114bb898558SAl Viro 			   unsigned int *ecx, unsigned int *edx)
115bb898558SAl Viro {
1165c83511bSJuergen Gross 	PVOP_VCALL4(cpu.cpuid, eax, ebx, ecx, edx);
117bb898558SAl Viro }
118bb898558SAl Viro 
119bb898558SAl Viro /*
120bb898558SAl Viro  * These special macros can be used to get or set a debugging register
121bb898558SAl Viro  */
paravirt_get_debugreg(int reg)122f4afb713SPeter Zijlstra static __always_inline unsigned long paravirt_get_debugreg(int reg)
123bb898558SAl Viro {
1245c83511bSJuergen Gross 	return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg);
125bb898558SAl Viro }
126bb898558SAl Viro #define get_debugreg(var, reg) var = paravirt_get_debugreg(reg)
set_debugreg(unsigned long val,int reg)1277361fac0SPeter Zijlstra static __always_inline void set_debugreg(unsigned long val, int reg)
128bb898558SAl Viro {
1295c83511bSJuergen Gross 	PVOP_VCALL2(cpu.set_debugreg, reg, val);
130bb898558SAl Viro }
131bb898558SAl Viro 
read_cr0(void)132bb898558SAl Viro static inline unsigned long read_cr0(void)
133bb898558SAl Viro {
1345c83511bSJuergen Gross 	return PVOP_CALL0(unsigned long, cpu.read_cr0);
135bb898558SAl Viro }
136bb898558SAl Viro 
write_cr0(unsigned long x)137bb898558SAl Viro static inline void write_cr0(unsigned long x)
138bb898558SAl Viro {
1395c83511bSJuergen Gross 	PVOP_VCALL1(cpu.write_cr0, x);
140bb898558SAl Viro }
141bb898558SAl Viro 
read_cr2(void)1420a53c9acSPeter Zijlstra static __always_inline unsigned long read_cr2(void)
143bb898558SAl Viro {
144fafe5e74SJuergen Gross 	return PVOP_ALT_CALLEE0(unsigned long, mmu.read_cr2,
145fafe5e74SJuergen Gross 				"mov %%cr2, %%rax;",
146fafe5e74SJuergen Gross 				ALT_NOT(X86_FEATURE_XENPV));
147bb898558SAl Viro }
148bb898558SAl Viro 
write_cr2(unsigned long x)149209cfd0cSPeter Zijlstra static __always_inline void write_cr2(unsigned long x)
150bb898558SAl Viro {
1515c83511bSJuergen Gross 	PVOP_VCALL1(mmu.write_cr2, x);
152bb898558SAl Viro }
153bb898558SAl Viro 
__read_cr3(void)1546c690ee1SAndy Lutomirski static inline unsigned long __read_cr3(void)
155bb898558SAl Viro {
156fafe5e74SJuergen Gross 	return PVOP_ALT_CALL0(unsigned long, mmu.read_cr3,
157fafe5e74SJuergen Gross 			      "mov %%cr3, %%rax;", ALT_NOT(X86_FEATURE_XENPV));
158bb898558SAl Viro }
159bb898558SAl Viro 
write_cr3(unsigned long x)160bb898558SAl Viro static inline void write_cr3(unsigned long x)
161bb898558SAl Viro {
162fafe5e74SJuergen Gross 	PVOP_ALT_VCALL1(mmu.write_cr3, x,
163fafe5e74SJuergen Gross 			"mov %%rdi, %%cr3", ALT_NOT(X86_FEATURE_XENPV));
164bb898558SAl Viro }
165bb898558SAl Viro 
__write_cr4(unsigned long x)1661e02ce4cSAndy Lutomirski static inline void __write_cr4(unsigned long x)
167bb898558SAl Viro {
1685c83511bSJuergen Gross 	PVOP_VCALL1(cpu.write_cr4, x);
169bb898558SAl Viro }
170bb898558SAl Viro 
arch_safe_halt(void)17110a09940SPeter Zijlstra static __always_inline void arch_safe_halt(void)
172bb898558SAl Viro {
1735c83511bSJuergen Gross 	PVOP_VCALL0(irq.safe_halt);
174bb898558SAl Viro }
175bb898558SAl Viro 
halt(void)176bb898558SAl Viro static inline void halt(void)
177bb898558SAl Viro {
1785c83511bSJuergen Gross 	PVOP_VCALL0(irq.halt);
179bb898558SAl Viro }
180bb898558SAl Viro 
18110a09940SPeter Zijlstra extern noinstr void pv_native_wbinvd(void);
18210a09940SPeter Zijlstra 
wbinvd(void)18310a09940SPeter Zijlstra static __always_inline void wbinvd(void)
184bb898558SAl Viro {
185fafe5e74SJuergen Gross 	PVOP_ALT_VCALL0(cpu.wbinvd, "wbinvd", ALT_NOT(X86_FEATURE_XENPV));
186bb898558SAl Viro }
187bb898558SAl Viro 
paravirt_read_msr(unsigned msr)188dd2f4a00SAndy Lutomirski static inline u64 paravirt_read_msr(unsigned msr)
189dd2f4a00SAndy Lutomirski {
1905c83511bSJuergen Gross 	return PVOP_CALL1(u64, cpu.read_msr, msr);
191dd2f4a00SAndy Lutomirski }
192dd2f4a00SAndy Lutomirski 
paravirt_write_msr(unsigned msr,unsigned low,unsigned high)193dd2f4a00SAndy Lutomirski static inline void paravirt_write_msr(unsigned msr,
194dd2f4a00SAndy Lutomirski 				      unsigned low, unsigned high)
195dd2f4a00SAndy Lutomirski {
1965c83511bSJuergen Gross 	PVOP_VCALL3(cpu.write_msr, msr, low, high);
197dd2f4a00SAndy Lutomirski }
198dd2f4a00SAndy Lutomirski 
paravirt_read_msr_safe(unsigned msr,int * err)199c2ee03b2SAndy Lutomirski static inline u64 paravirt_read_msr_safe(unsigned msr, int *err)
200bb898558SAl Viro {
2015c83511bSJuergen Gross 	return PVOP_CALL2(u64, cpu.read_msr_safe, msr, err);
202bb898558SAl Viro }
203132ec92fSBorislav Petkov 
paravirt_write_msr_safe(unsigned msr,unsigned low,unsigned high)204c2ee03b2SAndy Lutomirski static inline int paravirt_write_msr_safe(unsigned msr,
205c2ee03b2SAndy Lutomirski 					  unsigned low, unsigned high)
206bb898558SAl Viro {
2075c83511bSJuergen Gross 	return PVOP_CALL3(int, cpu.write_msr_safe, msr, low, high);
208bb898558SAl Viro }
209bb898558SAl Viro 
210bb898558SAl Viro #define rdmsr(msr, val1, val2)			\
211bb898558SAl Viro do {						\
2124985ce15SAndy Lutomirski 	u64 _l = paravirt_read_msr(msr);	\
213bb898558SAl Viro 	val1 = (u32)_l;				\
214bb898558SAl Viro 	val2 = _l >> 32;			\
215bb898558SAl Viro } while (0)
216bb898558SAl Viro 
217bb898558SAl Viro #define wrmsr(msr, val1, val2)			\
218bb898558SAl Viro do {						\
2194985ce15SAndy Lutomirski 	paravirt_write_msr(msr, val1, val2);	\
220bb898558SAl Viro } while (0)
221bb898558SAl Viro 
222bb898558SAl Viro #define rdmsrl(msr, val)			\
223bb898558SAl Viro do {						\
2244985ce15SAndy Lutomirski 	val = paravirt_read_msr(msr);		\
225bb898558SAl Viro } while (0)
226bb898558SAl Viro 
wrmsrl(unsigned msr,u64 val)22747edb651SAndy Lutomirski static inline void wrmsrl(unsigned msr, u64 val)
22847edb651SAndy Lutomirski {
22947edb651SAndy Lutomirski 	wrmsr(msr, (u32)val, (u32)(val>>32));
23047edb651SAndy Lutomirski }
23147edb651SAndy Lutomirski 
232c2ee03b2SAndy Lutomirski #define wrmsr_safe(msr, a, b)	paravirt_write_msr_safe(msr, a, b)
233bb898558SAl Viro 
234bb898558SAl Viro /* rdmsr with exception handling */
235bb898558SAl Viro #define rdmsr_safe(msr, a, b)				\
236bb898558SAl Viro ({							\
237bb898558SAl Viro 	int _err;					\
238c2ee03b2SAndy Lutomirski 	u64 _l = paravirt_read_msr_safe(msr, &_err);	\
239bb898558SAl Viro 	(*a) = (u32)_l;					\
240bb898558SAl Viro 	(*b) = _l >> 32;				\
241bb898558SAl Viro 	_err;						\
242bb898558SAl Viro })
243bb898558SAl Viro 
rdmsrl_safe(unsigned msr,unsigned long long * p)244bb898558SAl Viro static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
245bb898558SAl Viro {
246bb898558SAl Viro 	int err;
247bb898558SAl Viro 
248c2ee03b2SAndy Lutomirski 	*p = paravirt_read_msr_safe(msr, &err);
249bb898558SAl Viro 	return err;
250bb898558SAl Viro }
251177fed1eSBorislav Petkov 
paravirt_read_pmc(int counter)252bb898558SAl Viro static inline unsigned long long paravirt_read_pmc(int counter)
253bb898558SAl Viro {
2545c83511bSJuergen Gross 	return PVOP_CALL1(u64, cpu.read_pmc, counter);
255bb898558SAl Viro }
256bb898558SAl Viro 
257bb898558SAl Viro #define rdpmc(counter, low, high)		\
258bb898558SAl Viro do {						\
259bb898558SAl Viro 	u64 _l = paravirt_read_pmc(counter);	\
260bb898558SAl Viro 	low = (u32)_l;				\
261bb898558SAl Viro 	high = _l >> 32;			\
262bb898558SAl Viro } while (0)
263bb898558SAl Viro 
2641ff4d58aSAndi Kleen #define rdpmcl(counter, val) ((val) = paravirt_read_pmc(counter))
2651ff4d58aSAndi Kleen 
paravirt_alloc_ldt(struct desc_struct * ldt,unsigned entries)266bb898558SAl Viro static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries)
267bb898558SAl Viro {
2685c83511bSJuergen Gross 	PVOP_VCALL2(cpu.alloc_ldt, ldt, entries);
269bb898558SAl Viro }
270bb898558SAl Viro 
paravirt_free_ldt(struct desc_struct * ldt,unsigned entries)271bb898558SAl Viro static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries)
272bb898558SAl Viro {
2735c83511bSJuergen Gross 	PVOP_VCALL2(cpu.free_ldt, ldt, entries);
274bb898558SAl Viro }
275bb898558SAl Viro 
load_TR_desc(void)276bb898558SAl Viro static inline void load_TR_desc(void)
277bb898558SAl Viro {
2785c83511bSJuergen Gross 	PVOP_VCALL0(cpu.load_tr_desc);
279bb898558SAl Viro }
load_gdt(const struct desc_ptr * dtr)280bb898558SAl Viro static inline void load_gdt(const struct desc_ptr *dtr)
281bb898558SAl Viro {
2825c83511bSJuergen Gross 	PVOP_VCALL1(cpu.load_gdt, dtr);
283bb898558SAl Viro }
load_idt(const struct desc_ptr * dtr)284bb898558SAl Viro static inline void load_idt(const struct desc_ptr *dtr)
285bb898558SAl Viro {
2865c83511bSJuergen Gross 	PVOP_VCALL1(cpu.load_idt, dtr);
287bb898558SAl Viro }
set_ldt(const void * addr,unsigned entries)288bb898558SAl Viro static inline void set_ldt(const void *addr, unsigned entries)
289bb898558SAl Viro {
2905c83511bSJuergen Gross 	PVOP_VCALL2(cpu.set_ldt, addr, entries);
291bb898558SAl Viro }
paravirt_store_tr(void)292bb898558SAl Viro static inline unsigned long paravirt_store_tr(void)
293bb898558SAl Viro {
2945c83511bSJuergen Gross 	return PVOP_CALL0(unsigned long, cpu.store_tr);
295bb898558SAl Viro }
2969bad5658SJuergen Gross 
297bb898558SAl Viro #define store_tr(tr)	((tr) = paravirt_store_tr())
load_TLS(struct thread_struct * t,unsigned cpu)298bb898558SAl Viro static inline void load_TLS(struct thread_struct *t, unsigned cpu)
299bb898558SAl Viro {
3005c83511bSJuergen Gross 	PVOP_VCALL2(cpu.load_tls, t, cpu);
301bb898558SAl Viro }
302bb898558SAl Viro 
load_gs_index(unsigned int gs)303bb898558SAl Viro static inline void load_gs_index(unsigned int gs)
304bb898558SAl Viro {
3055c83511bSJuergen Gross 	PVOP_VCALL1(cpu.load_gs_index, gs);
306bb898558SAl Viro }
307bb898558SAl Viro 
write_ldt_entry(struct desc_struct * dt,int entry,const void * desc)308bb898558SAl Viro static inline void write_ldt_entry(struct desc_struct *dt, int entry,
309bb898558SAl Viro 				   const void *desc)
310bb898558SAl Viro {
3115c83511bSJuergen Gross 	PVOP_VCALL3(cpu.write_ldt_entry, dt, entry, desc);
312bb898558SAl Viro }
313bb898558SAl Viro 
write_gdt_entry(struct desc_struct * dt,int entry,void * desc,int type)314bb898558SAl Viro static inline void write_gdt_entry(struct desc_struct *dt, int entry,
315bb898558SAl Viro 				   void *desc, int type)
316bb898558SAl Viro {
3175c83511bSJuergen Gross 	PVOP_VCALL4(cpu.write_gdt_entry, dt, entry, desc, type);
318bb898558SAl Viro }
319bb898558SAl Viro 
write_idt_entry(gate_desc * dt,int entry,const gate_desc * g)320bb898558SAl Viro static inline void write_idt_entry(gate_desc *dt, int entry, const gate_desc *g)
321bb898558SAl Viro {
3225c83511bSJuergen Gross 	PVOP_VCALL3(cpu.write_idt_entry, dt, entry, g);
323bb898558SAl Viro }
324bb898558SAl Viro 
32599bcd4a6SJuergen Gross #ifdef CONFIG_X86_IOPL_IOPERM
tss_invalidate_io_bitmap(void)326cadfad87SAndy Lutomirski static inline void tss_invalidate_io_bitmap(void)
327cadfad87SAndy Lutomirski {
328cadfad87SAndy Lutomirski 	PVOP_VCALL0(cpu.invalidate_io_bitmap);
329cadfad87SAndy Lutomirski }
330cadfad87SAndy Lutomirski 
tss_update_io_bitmap(void)33199bcd4a6SJuergen Gross static inline void tss_update_io_bitmap(void)
33299bcd4a6SJuergen Gross {
33399bcd4a6SJuergen Gross 	PVOP_VCALL0(cpu.update_io_bitmap);
33499bcd4a6SJuergen Gross }
33599bcd4a6SJuergen Gross #endif
33699bcd4a6SJuergen Gross 
paravirt_enter_mmap(struct mm_struct * next)337c9ae1b10SJuergen Gross static inline void paravirt_enter_mmap(struct mm_struct *next)
338bb898558SAl Viro {
339c9ae1b10SJuergen Gross 	PVOP_VCALL1(mmu.enter_mmap, next);
340bb898558SAl Viro }
341bb898558SAl Viro 
paravirt_pgd_alloc(struct mm_struct * mm)342bb898558SAl Viro static inline int paravirt_pgd_alloc(struct mm_struct *mm)
343bb898558SAl Viro {
3445c83511bSJuergen Gross 	return PVOP_CALL1(int, mmu.pgd_alloc, mm);
345bb898558SAl Viro }
346bb898558SAl Viro 
paravirt_pgd_free(struct mm_struct * mm,pgd_t * pgd)347bb898558SAl Viro static inline void paravirt_pgd_free(struct mm_struct *mm, pgd_t *pgd)
348bb898558SAl Viro {
3495c83511bSJuergen Gross 	PVOP_VCALL2(mmu.pgd_free, mm, pgd);
350bb898558SAl Viro }
351bb898558SAl Viro 
paravirt_alloc_pte(struct mm_struct * mm,unsigned long pfn)352bb898558SAl Viro static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned long pfn)
353bb898558SAl Viro {
3545c83511bSJuergen Gross 	PVOP_VCALL2(mmu.alloc_pte, mm, pfn);
355bb898558SAl Viro }
paravirt_release_pte(unsigned long pfn)356bb898558SAl Viro static inline void paravirt_release_pte(unsigned long pfn)
357bb898558SAl Viro {
3585c83511bSJuergen Gross 	PVOP_VCALL1(mmu.release_pte, pfn);
359bb898558SAl Viro }
360bb898558SAl Viro 
paravirt_alloc_pmd(struct mm_struct * mm,unsigned long pfn)361bb898558SAl Viro static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned long pfn)
362bb898558SAl Viro {
3635c83511bSJuergen Gross 	PVOP_VCALL2(mmu.alloc_pmd, mm, pfn);
364bb898558SAl Viro }
365bb898558SAl Viro 
paravirt_release_pmd(unsigned long pfn)366bb898558SAl Viro static inline void paravirt_release_pmd(unsigned long pfn)
367bb898558SAl Viro {
3685c83511bSJuergen Gross 	PVOP_VCALL1(mmu.release_pmd, pfn);
369bb898558SAl Viro }
370bb898558SAl Viro 
paravirt_alloc_pud(struct mm_struct * mm,unsigned long pfn)371bb898558SAl Viro static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned long pfn)
372bb898558SAl Viro {
3735c83511bSJuergen Gross 	PVOP_VCALL2(mmu.alloc_pud, mm, pfn);
374bb898558SAl Viro }
paravirt_release_pud(unsigned long pfn)375bb898558SAl Viro static inline void paravirt_release_pud(unsigned long pfn)
376bb898558SAl Viro {
3775c83511bSJuergen Gross 	PVOP_VCALL1(mmu.release_pud, pfn);
378bb898558SAl Viro }
379bb898558SAl Viro 
paravirt_alloc_p4d(struct mm_struct * mm,unsigned long pfn)380335437fbSKirill A. Shutemov static inline void paravirt_alloc_p4d(struct mm_struct *mm, unsigned long pfn)
381335437fbSKirill A. Shutemov {
3825c83511bSJuergen Gross 	PVOP_VCALL2(mmu.alloc_p4d, mm, pfn);
383335437fbSKirill A. Shutemov }
384335437fbSKirill A. Shutemov 
paravirt_release_p4d(unsigned long pfn)385335437fbSKirill A. Shutemov static inline void paravirt_release_p4d(unsigned long pfn)
386335437fbSKirill A. Shutemov {
3875c83511bSJuergen Gross 	PVOP_VCALL1(mmu.release_p4d, pfn);
388335437fbSKirill A. Shutemov }
389335437fbSKirill A. Shutemov 
__pte(pteval_t val)390bb898558SAl Viro static inline pte_t __pte(pteval_t val)
391bb898558SAl Viro {
392fafe5e74SJuergen Gross 	return (pte_t) { PVOP_ALT_CALLEE1(pteval_t, mmu.make_pte, val,
393fafe5e74SJuergen Gross 					  "mov %%rdi, %%rax",
394fafe5e74SJuergen Gross 					  ALT_NOT(X86_FEATURE_XENPV)) };
395bb898558SAl Viro }
396bb898558SAl Viro 
pte_val(pte_t pte)397bb898558SAl Viro static inline pteval_t pte_val(pte_t pte)
398bb898558SAl Viro {
399fafe5e74SJuergen Gross 	return PVOP_ALT_CALLEE1(pteval_t, mmu.pte_val, pte.pte,
400fafe5e74SJuergen Gross 				"mov %%rdi, %%rax", ALT_NOT(X86_FEATURE_XENPV));
401bb898558SAl Viro }
402bb898558SAl Viro 
__pgd(pgdval_t val)403bb898558SAl Viro static inline pgd_t __pgd(pgdval_t val)
404bb898558SAl Viro {
405fafe5e74SJuergen Gross 	return (pgd_t) { PVOP_ALT_CALLEE1(pgdval_t, mmu.make_pgd, val,
406fafe5e74SJuergen Gross 					  "mov %%rdi, %%rax",
407fafe5e74SJuergen Gross 					  ALT_NOT(X86_FEATURE_XENPV)) };
408bb898558SAl Viro }
409bb898558SAl Viro 
pgd_val(pgd_t pgd)410bb898558SAl Viro static inline pgdval_t pgd_val(pgd_t pgd)
411bb898558SAl Viro {
412fafe5e74SJuergen Gross 	return PVOP_ALT_CALLEE1(pgdval_t, mmu.pgd_val, pgd.pgd,
413fafe5e74SJuergen Gross 				"mov %%rdi, %%rax", ALT_NOT(X86_FEATURE_XENPV));
414bb898558SAl Viro }
415bb898558SAl Viro 
416bb898558SAl Viro #define  __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
ptep_modify_prot_start(struct vm_area_struct * vma,unsigned long addr,pte_t * ptep)4170cbe3e26SAneesh Kumar K.V static inline pte_t ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr,
418bb898558SAl Viro 					   pte_t *ptep)
419bb898558SAl Viro {
420bb898558SAl Viro 	pteval_t ret;
421bb898558SAl Viro 
4220cbe3e26SAneesh Kumar K.V 	ret = PVOP_CALL3(pteval_t, mmu.ptep_modify_prot_start, vma, addr, ptep);
423bb898558SAl Viro 
424bb898558SAl Viro 	return (pte_t) { .pte = ret };
425bb898558SAl Viro }
426bb898558SAl Viro 
ptep_modify_prot_commit(struct vm_area_struct * vma,unsigned long addr,pte_t * ptep,pte_t old_pte,pte_t pte)4270cbe3e26SAneesh Kumar K.V static inline void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr,
42804a86453SAneesh Kumar K.V 					   pte_t *ptep, pte_t old_pte, pte_t pte)
429bb898558SAl Viro {
4300cbe3e26SAneesh Kumar K.V 
4310cabf991SJuergen Gross 	PVOP_VCALL4(mmu.ptep_modify_prot_commit, vma, addr, ptep, pte.pte);
432bb898558SAl Viro }
433bb898558SAl Viro 
set_pte(pte_t * ptep,pte_t pte)434bb898558SAl Viro static inline void set_pte(pte_t *ptep, pte_t pte)
435bb898558SAl Viro {
4365c83511bSJuergen Gross 	PVOP_VCALL2(mmu.set_pte, ptep, pte.pte);
437bb898558SAl Viro }
438bb898558SAl Viro 
set_pmd(pmd_t * pmdp,pmd_t pmd)439bb898558SAl Viro static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
440bb898558SAl Viro {
4410cabf991SJuergen Gross 	PVOP_VCALL2(mmu.set_pmd, pmdp, native_pmd_val(pmd));
442bb898558SAl Viro }
443bb898558SAl Viro 
__pmd(pmdval_t val)444bb898558SAl Viro static inline pmd_t __pmd(pmdval_t val)
445bb898558SAl Viro {
446fafe5e74SJuergen Gross 	return (pmd_t) { PVOP_ALT_CALLEE1(pmdval_t, mmu.make_pmd, val,
447fafe5e74SJuergen Gross 					  "mov %%rdi, %%rax",
448fafe5e74SJuergen Gross 					  ALT_NOT(X86_FEATURE_XENPV)) };
449bb898558SAl Viro }
450bb898558SAl Viro 
pmd_val(pmd_t pmd)451bb898558SAl Viro static inline pmdval_t pmd_val(pmd_t pmd)
452bb898558SAl Viro {
453fafe5e74SJuergen Gross 	return PVOP_ALT_CALLEE1(pmdval_t, mmu.pmd_val, pmd.pmd,
454fafe5e74SJuergen Gross 				"mov %%rdi, %%rax", ALT_NOT(X86_FEATURE_XENPV));
455bb898558SAl Viro }
456bb898558SAl Viro 
set_pud(pud_t * pudp,pud_t pud)457bb898558SAl Viro static inline void set_pud(pud_t *pudp, pud_t pud)
458bb898558SAl Viro {
4590cabf991SJuergen Gross 	PVOP_VCALL2(mmu.set_pud, pudp, native_pud_val(pud));
460bb898558SAl Viro }
4610cabf991SJuergen Gross 
__pud(pudval_t val)462bb898558SAl Viro static inline pud_t __pud(pudval_t val)
463bb898558SAl Viro {
464bb898558SAl Viro 	pudval_t ret;
465bb898558SAl Viro 
466fafe5e74SJuergen Gross 	ret = PVOP_ALT_CALLEE1(pudval_t, mmu.make_pud, val,
467fafe5e74SJuergen Gross 			       "mov %%rdi, %%rax", ALT_NOT(X86_FEATURE_XENPV));
468bb898558SAl Viro 
469bb898558SAl Viro 	return (pud_t) { ret };
470bb898558SAl Viro }
471bb898558SAl Viro 
pud_val(pud_t pud)472bb898558SAl Viro static inline pudval_t pud_val(pud_t pud)
473bb898558SAl Viro {
474fafe5e74SJuergen Gross 	return PVOP_ALT_CALLEE1(pudval_t, mmu.pud_val, pud.pud,
475fafe5e74SJuergen Gross 				"mov %%rdi, %%rax", ALT_NOT(X86_FEATURE_XENPV));
476bb898558SAl Viro }
477bb898558SAl Viro 
pud_clear(pud_t * pudp)478f2a6a705SKirill A. Shutemov static inline void pud_clear(pud_t *pudp)
479f2a6a705SKirill A. Shutemov {
4807c9f80cbSJuergen Gross 	set_pud(pudp, native_make_pud(0));
481f2a6a705SKirill A. Shutemov }
482f2a6a705SKirill A. Shutemov 
set_p4d(p4d_t * p4dp,p4d_t p4d)483f2a6a705SKirill A. Shutemov static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
484f2a6a705SKirill A. Shutemov {
485f2a6a705SKirill A. Shutemov 	p4dval_t val = native_p4d_val(p4d);
486f2a6a705SKirill A. Shutemov 
4875c83511bSJuergen Gross 	PVOP_VCALL2(mmu.set_p4d, p4dp, val);
488f2a6a705SKirill A. Shutemov }
489f2a6a705SKirill A. Shutemov 
490f2a6a705SKirill A. Shutemov #if CONFIG_PGTABLE_LEVELS >= 5
491f2a6a705SKirill A. Shutemov 
__p4d(p4dval_t val)492335437fbSKirill A. Shutemov static inline p4d_t __p4d(p4dval_t val)
493335437fbSKirill A. Shutemov {
494fafe5e74SJuergen Gross 	p4dval_t ret = PVOP_ALT_CALLEE1(p4dval_t, mmu.make_p4d, val,
495fafe5e74SJuergen Gross 					"mov %%rdi, %%rax",
496fafe5e74SJuergen Gross 					ALT_NOT(X86_FEATURE_XENPV));
497335437fbSKirill A. Shutemov 
498335437fbSKirill A. Shutemov 	return (p4d_t) { ret };
499335437fbSKirill A. Shutemov }
500335437fbSKirill A. Shutemov 
p4d_val(p4d_t p4d)501335437fbSKirill A. Shutemov static inline p4dval_t p4d_val(p4d_t p4d)
502335437fbSKirill A. Shutemov {
503fafe5e74SJuergen Gross 	return PVOP_ALT_CALLEE1(p4dval_t, mmu.p4d_val, p4d.p4d,
504fafe5e74SJuergen Gross 				"mov %%rdi, %%rax", ALT_NOT(X86_FEATURE_XENPV));
505335437fbSKirill A. Shutemov }
506f2a6a705SKirill A. Shutemov 
__set_pgd(pgd_t * pgdp,pgd_t pgd)50792e1c5b3SKirill A. Shutemov static inline void __set_pgd(pgd_t *pgdp, pgd_t pgd)
508bb898558SAl Viro {
5095c83511bSJuergen Gross 	PVOP_VCALL2(mmu.set_pgd, pgdp, native_pgd_val(pgd));
510bb898558SAl Viro }
511bb898558SAl Viro 
51292e1c5b3SKirill A. Shutemov #define set_pgd(pgdp, pgdval) do {					\
513ed7588d5SKirill A. Shutemov 	if (pgtable_l5_enabled())						\
51492e1c5b3SKirill A. Shutemov 		__set_pgd(pgdp, pgdval);				\
51592e1c5b3SKirill A. Shutemov 	else								\
51692e1c5b3SKirill A. Shutemov 		set_p4d((p4d_t *)(pgdp), (p4d_t) { (pgdval).pgd });	\
51792e1c5b3SKirill A. Shutemov } while (0)
51892e1c5b3SKirill A. Shutemov 
51992e1c5b3SKirill A. Shutemov #define pgd_clear(pgdp) do {						\
520ed7588d5SKirill A. Shutemov 	if (pgtable_l5_enabled())					\
5217c9f80cbSJuergen Gross 		set_pgd(pgdp, native_make_pgd(0));			\
52292e1c5b3SKirill A. Shutemov } while (0)
523bb898558SAl Viro 
524f2a6a705SKirill A. Shutemov #endif  /* CONFIG_PGTABLE_LEVELS == 5 */
525bb898558SAl Viro 
p4d_clear(p4d_t * p4dp)526335437fbSKirill A. Shutemov static inline void p4d_clear(p4d_t *p4dp)
527335437fbSKirill A. Shutemov {
5287c9f80cbSJuergen Gross 	set_p4d(p4dp, native_make_p4d(0));
529335437fbSKirill A. Shutemov }
530335437fbSKirill A. Shutemov 
set_pte_atomic(pte_t * ptep,pte_t pte)531bb898558SAl Viro static inline void set_pte_atomic(pte_t *ptep, pte_t pte)
532bb898558SAl Viro {
533bb898558SAl Viro 	set_pte(ptep, pte);
534bb898558SAl Viro }
535bb898558SAl Viro 
pte_clear(struct mm_struct * mm,unsigned long addr,pte_t * ptep)536bb898558SAl Viro static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
537bb898558SAl Viro 			     pte_t *ptep)
538bb898558SAl Viro {
5397c9f80cbSJuergen Gross 	set_pte(ptep, native_make_pte(0));
540bb898558SAl Viro }
541bb898558SAl Viro 
pmd_clear(pmd_t * pmdp)542bb898558SAl Viro static inline void pmd_clear(pmd_t *pmdp)
543bb898558SAl Viro {
5447c9f80cbSJuergen Gross 	set_pmd(pmdp, native_make_pmd(0));
545bb898558SAl Viro }
546bb898558SAl Viro 
5477fd7d83dSJeremy Fitzhardinge #define  __HAVE_ARCH_START_CONTEXT_SWITCH
arch_start_context_switch(struct task_struct * prev)548224101edSJeremy Fitzhardinge static inline void arch_start_context_switch(struct task_struct *prev)
549bb898558SAl Viro {
5505c83511bSJuergen Gross 	PVOP_VCALL1(cpu.start_context_switch, prev);
551bb898558SAl Viro }
552bb898558SAl Viro 
arch_end_context_switch(struct task_struct * next)553224101edSJeremy Fitzhardinge static inline void arch_end_context_switch(struct task_struct *next)
554bb898558SAl Viro {
5555c83511bSJuergen Gross 	PVOP_VCALL1(cpu.end_context_switch, next);
556bb898558SAl Viro }
557bb898558SAl Viro 
558bb898558SAl Viro #define  __HAVE_ARCH_ENTER_LAZY_MMU_MODE
arch_enter_lazy_mmu_mode(void)559bb898558SAl Viro static inline void arch_enter_lazy_mmu_mode(void)
560bb898558SAl Viro {
5615c83511bSJuergen Gross 	PVOP_VCALL0(mmu.lazy_mode.enter);
562bb898558SAl Viro }
563bb898558SAl Viro 
arch_leave_lazy_mmu_mode(void)564bb898558SAl Viro static inline void arch_leave_lazy_mmu_mode(void)
565bb898558SAl Viro {
5665c83511bSJuergen Gross 	PVOP_VCALL0(mmu.lazy_mode.leave);
567bb898558SAl Viro }
568bb898558SAl Viro 
arch_flush_lazy_mmu_mode(void)569511ba86eSBoris Ostrovsky static inline void arch_flush_lazy_mmu_mode(void)
570511ba86eSBoris Ostrovsky {
5715c83511bSJuergen Gross 	PVOP_VCALL0(mmu.lazy_mode.flush);
572511ba86eSBoris Ostrovsky }
573bb898558SAl Viro 
__set_fixmap(unsigned idx,phys_addr_t phys,pgprot_t flags)574bb898558SAl Viro static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
5753b3809acSMasami Hiramatsu 				phys_addr_t phys, pgprot_t flags)
576bb898558SAl Viro {
5775c83511bSJuergen Gross 	pv_ops.mmu.set_fixmap(idx, phys, flags);
578bb898558SAl Viro }
579fdc0269eSJuergen Gross #endif
580bb898558SAl Viro 
581b4ecc126SJeremy Fitzhardinge #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS)
582bb898558SAl Viro 
pv_queued_spin_lock_slowpath(struct qspinlock * lock,u32 val)583f233f7f1SPeter Zijlstra (Intel) static __always_inline void pv_queued_spin_lock_slowpath(struct qspinlock *lock,
584f233f7f1SPeter Zijlstra (Intel) 							u32 val)
585f233f7f1SPeter Zijlstra (Intel) {
5865c83511bSJuergen Gross 	PVOP_VCALL2(lock.queued_spin_lock_slowpath, lock, val);
587f233f7f1SPeter Zijlstra (Intel) }
588f233f7f1SPeter Zijlstra (Intel) 
pv_queued_spin_unlock(struct qspinlock * lock)589f233f7f1SPeter Zijlstra (Intel) static __always_inline void pv_queued_spin_unlock(struct qspinlock *lock)
590f233f7f1SPeter Zijlstra (Intel) {
591fafe5e74SJuergen Gross 	PVOP_ALT_VCALLEE1(lock.queued_spin_unlock, lock,
592fafe5e74SJuergen Gross 			  "movb $0, (%%" _ASM_ARG1 ");",
593fafe5e74SJuergen Gross 			  ALT_NOT(X86_FEATURE_PVUNLOCK));
594f233f7f1SPeter Zijlstra (Intel) }
595f233f7f1SPeter Zijlstra (Intel) 
pv_wait(u8 * ptr,u8 val)596f233f7f1SPeter Zijlstra (Intel) static __always_inline void pv_wait(u8 *ptr, u8 val)
597f233f7f1SPeter Zijlstra (Intel) {
5985c83511bSJuergen Gross 	PVOP_VCALL2(lock.wait, ptr, val);
599f233f7f1SPeter Zijlstra (Intel) }
600f233f7f1SPeter Zijlstra (Intel) 
pv_kick(int cpu)601f233f7f1SPeter Zijlstra (Intel) static __always_inline void pv_kick(int cpu)
602f233f7f1SPeter Zijlstra (Intel) {
6035c83511bSJuergen Gross 	PVOP_VCALL1(lock.kick, cpu);
604f233f7f1SPeter Zijlstra (Intel) }
605f233f7f1SPeter Zijlstra (Intel) 
pv_vcpu_is_preempted(long cpu)6066c62985dSWaiman Long static __always_inline bool pv_vcpu_is_preempted(long cpu)
6073cded417SPeter Zijlstra {
608fafe5e74SJuergen Gross 	return PVOP_ALT_CALLEE1(bool, lock.vcpu_is_preempted, cpu,
609fafe5e74SJuergen Gross 				"xor %%" _ASM_AX ", %%" _ASM_AX ";",
610fafe5e74SJuergen Gross 				ALT_NOT(X86_FEATURE_VCPUPREEMPT));
6113cded417SPeter Zijlstra }
6123cded417SPeter Zijlstra 
6135c83511bSJuergen Gross void __raw_callee_save___native_queued_spin_unlock(struct qspinlock *lock);
6145c83511bSJuergen Gross bool __raw_callee_save___native_vcpu_is_preempted(long cpu);
6155c83511bSJuergen Gross 
616f233f7f1SPeter Zijlstra (Intel) #endif /* SMP && PARAVIRT_SPINLOCKS */
617bb898558SAl Viro 
618bb898558SAl Viro #ifdef CONFIG_X86_32
619ecb93d1cSJeremy Fitzhardinge /* save and restore all caller-save registers, except return value */
620e584f559SJeremy Fitzhardinge #define PV_SAVE_ALL_CALLER_REGS		"pushl %ecx;"
621e584f559SJeremy Fitzhardinge #define PV_RESTORE_ALL_CALLER_REGS	"popl  %ecx;"
622bb898558SAl Viro #else
623ecb93d1cSJeremy Fitzhardinge /* save and restore all caller-save registers, except return value */
624ecb93d1cSJeremy Fitzhardinge #define PV_SAVE_ALL_CALLER_REGS						\
625ecb93d1cSJeremy Fitzhardinge 	"push %rcx;"							\
626ecb93d1cSJeremy Fitzhardinge 	"push %rdx;"							\
627ecb93d1cSJeremy Fitzhardinge 	"push %rsi;"							\
628ecb93d1cSJeremy Fitzhardinge 	"push %rdi;"							\
629ecb93d1cSJeremy Fitzhardinge 	"push %r8;"							\
630ecb93d1cSJeremy Fitzhardinge 	"push %r9;"							\
631ecb93d1cSJeremy Fitzhardinge 	"push %r10;"							\
632ecb93d1cSJeremy Fitzhardinge 	"push %r11;"
633ecb93d1cSJeremy Fitzhardinge #define PV_RESTORE_ALL_CALLER_REGS					\
634ecb93d1cSJeremy Fitzhardinge 	"pop %r11;"							\
635ecb93d1cSJeremy Fitzhardinge 	"pop %r10;"							\
636ecb93d1cSJeremy Fitzhardinge 	"pop %r9;"							\
637ecb93d1cSJeremy Fitzhardinge 	"pop %r8;"							\
638ecb93d1cSJeremy Fitzhardinge 	"pop %rdi;"							\
639ecb93d1cSJeremy Fitzhardinge 	"pop %rsi;"							\
640ecb93d1cSJeremy Fitzhardinge 	"pop %rdx;"							\
641ecb93d1cSJeremy Fitzhardinge 	"pop %rcx;"
642bb898558SAl Viro #endif
643bb898558SAl Viro 
644ecb93d1cSJeremy Fitzhardinge /*
645ecb93d1cSJeremy Fitzhardinge  * Generate a thunk around a function which saves all caller-save
646ecb93d1cSJeremy Fitzhardinge  * registers except for the return value.  This allows C functions to
647ecb93d1cSJeremy Fitzhardinge  * be called from assembler code where fewer than normal registers are
648ecb93d1cSJeremy Fitzhardinge  * available.  It may also help code generation around calls from C
649ecb93d1cSJeremy Fitzhardinge  * code if the common case doesn't use many registers.
650ecb93d1cSJeremy Fitzhardinge  *
651ecb93d1cSJeremy Fitzhardinge  * When a callee is wrapped in a thunk, the caller can assume that all
652ecb93d1cSJeremy Fitzhardinge  * arg regs and all scratch registers are preserved across the
653ecb93d1cSJeremy Fitzhardinge  * call. The return value in rax/eax will not be saved, even for void
654ecb93d1cSJeremy Fitzhardinge  * functions.
655ecb93d1cSJeremy Fitzhardinge  */
65687b240cbSJosh Poimboeuf #define PV_THUNK_NAME(func) "__raw_callee_save_" #func
65720125c87SPeter Zijlstra #define __PV_CALLEE_SAVE_REGS_THUNK(func, section)			\
658ecb93d1cSJeremy Fitzhardinge 	extern typeof(func) __raw_callee_save_##func;			\
659ecb93d1cSJeremy Fitzhardinge 									\
66020125c87SPeter Zijlstra 	asm(".pushsection " section ", \"ax\";"				\
66187b240cbSJosh Poimboeuf 	    ".globl " PV_THUNK_NAME(func) ";"				\
66287b240cbSJosh Poimboeuf 	    ".type " PV_THUNK_NAME(func) ", @function;"			\
6631d293758SThomas Gleixner 	    ASM_FUNC_ALIGN						\
66487b240cbSJosh Poimboeuf 	    PV_THUNK_NAME(func) ":"					\
665c3b03791SPeter Zijlstra 	    ASM_ENDBR							\
66687b240cbSJosh Poimboeuf 	    FRAME_BEGIN							\
667ecb93d1cSJeremy Fitzhardinge 	    PV_SAVE_ALL_CALLER_REGS					\
668ecb93d1cSJeremy Fitzhardinge 	    "call " #func ";"						\
669ecb93d1cSJeremy Fitzhardinge 	    PV_RESTORE_ALL_CALLER_REGS					\
67087b240cbSJosh Poimboeuf 	    FRAME_END							\
671b17c2baaSPeter Zijlstra 	    ASM_RET							\
672083db676SJosh Poimboeuf 	    ".size " PV_THUNK_NAME(func) ", .-" PV_THUNK_NAME(func) ";"	\
673ecb93d1cSJeremy Fitzhardinge 	    ".popsection")
674ecb93d1cSJeremy Fitzhardinge 
67520125c87SPeter Zijlstra #define PV_CALLEE_SAVE_REGS_THUNK(func)			\
67620125c87SPeter Zijlstra 	__PV_CALLEE_SAVE_REGS_THUNK(func, ".text")
67720125c87SPeter Zijlstra 
678ecb93d1cSJeremy Fitzhardinge /* Get a reference to a callee-save function */
679ecb93d1cSJeremy Fitzhardinge #define PV_CALLEE_SAVE(func)						\
680ecb93d1cSJeremy Fitzhardinge 	((struct paravirt_callee_save) { __raw_callee_save_##func })
681ecb93d1cSJeremy Fitzhardinge 
682ecb93d1cSJeremy Fitzhardinge /* Promise that "func" already uses the right calling convention */
683ecb93d1cSJeremy Fitzhardinge #define __PV_IS_CALLEE_SAVE(func)			\
684ecb93d1cSJeremy Fitzhardinge 	((struct paravirt_callee_save) { func })
685ecb93d1cSJeremy Fitzhardinge 
6866da63eb2SJuergen Gross #ifdef CONFIG_PARAVIRT_XXL
arch_local_save_flags(void)687e9382440SPeter Zijlstra static __always_inline unsigned long arch_local_save_flags(void)
688bb898558SAl Viro {
689fafe5e74SJuergen Gross 	return PVOP_ALT_CALLEE0(unsigned long, irq.save_fl, "pushf; pop %%rax;",
690fafe5e74SJuergen Gross 				ALT_NOT(X86_FEATURE_XENPV));
691bb898558SAl Viro }
692bb898558SAl Viro 
arch_local_irq_disable(void)693e9382440SPeter Zijlstra static __always_inline void arch_local_irq_disable(void)
694bb898558SAl Viro {
695fafe5e74SJuergen Gross 	PVOP_ALT_VCALLEE0(irq.irq_disable, "cli;", ALT_NOT(X86_FEATURE_XENPV));
696bb898558SAl Viro }
697bb898558SAl Viro 
arch_local_irq_enable(void)698e9382440SPeter Zijlstra static __always_inline void arch_local_irq_enable(void)
699bb898558SAl Viro {
700fafe5e74SJuergen Gross 	PVOP_ALT_VCALLEE0(irq.irq_enable, "sti;", ALT_NOT(X86_FEATURE_XENPV));
701bb898558SAl Viro }
702bb898558SAl Viro 
arch_local_irq_save(void)703e9382440SPeter Zijlstra static __always_inline unsigned long arch_local_irq_save(void)
704bb898558SAl Viro {
705bb898558SAl Viro 	unsigned long f;
706bb898558SAl Viro 
707df9ee292SDavid Howells 	f = arch_local_save_flags();
708df9ee292SDavid Howells 	arch_local_irq_disable();
709bb898558SAl Viro 	return f;
710bb898558SAl Viro }
7116da63eb2SJuergen Gross #endif
712bb898558SAl Viro 
713bb898558SAl Viro 
714bb898558SAl Viro /* Make sure as little as possible of this mess escapes. */
715bb898558SAl Viro #undef PARAVIRT_CALL
716bb898558SAl Viro #undef __PVOP_CALL
717bb898558SAl Viro #undef __PVOP_VCALL
718bb898558SAl Viro #undef PVOP_VCALL0
719bb898558SAl Viro #undef PVOP_CALL0
720bb898558SAl Viro #undef PVOP_VCALL1
721bb898558SAl Viro #undef PVOP_CALL1
722bb898558SAl Viro #undef PVOP_VCALL2
723bb898558SAl Viro #undef PVOP_CALL2
724bb898558SAl Viro #undef PVOP_VCALL3
725bb898558SAl Viro #undef PVOP_CALL3
726bb898558SAl Viro #undef PVOP_VCALL4
727bb898558SAl Viro #undef PVOP_CALL4
728bb898558SAl Viro 
729f1a033ccSJuergen Gross #define DEFINE_PARAVIRT_ASM(func, instr, sec)		\
730f1a033ccSJuergen Gross 	asm (".pushsection " #sec ", \"ax\"\n"		\
731f1a033ccSJuergen Gross 	     ".global " #func "\n\t"			\
732f1a033ccSJuergen Gross 	     ".type " #func ", @function\n\t"		\
733f1a033ccSJuergen Gross 	     ASM_FUNC_ALIGN "\n"			\
734f1a033ccSJuergen Gross 	     #func ":\n\t"				\
735f1a033ccSJuergen Gross 	     ASM_ENDBR					\
736f1a033ccSJuergen Gross 	     instr "\n\t"				\
737f1a033ccSJuergen Gross 	     ASM_RET					\
738f1a033ccSJuergen Gross 	     ".size " #func ", . - " #func "\n\t"	\
739f1a033ccSJuergen Gross 	     ".popsection")
740f1a033ccSJuergen Gross 
7416f30c1acSThomas Gleixner extern void default_banner(void);
742*ce0a1b60SArnd Bergmann void native_pv_lock_init(void) __init;
7436f30c1acSThomas Gleixner 
744bb898558SAl Viro #else  /* __ASSEMBLY__ */
745bb898558SAl Viro 
74627876f38SJuergen Gross #define _PVSITE(ptype, ops, word, algn)		\
747bb898558SAl Viro 771:;						\
748bb898558SAl Viro 	ops;					\
749bb898558SAl Viro 772:;						\
750bb898558SAl Viro 	.pushsection .parainstructions,"a";	\
751bb898558SAl Viro 	 .align	algn;				\
752bb898558SAl Viro 	 word 771b;				\
753bb898558SAl Viro 	 .byte ptype;				\
754bb898558SAl Viro 	 .byte 772b-771b;			\
755f92ff8f5SThomas Gleixner 	 _ASM_ALIGN;				\
756bb898558SAl Viro 	.popsection
757bb898558SAl Viro 
758bb898558SAl Viro 
759bb898558SAl Viro #ifdef CONFIG_X86_64
76033634e42SJuergen Gross #ifdef CONFIG_PARAVIRT_XXL
7619104a18dSJeremy Fitzhardinge 
7625c83511bSJuergen Gross #define PARA_PATCH(off)		((off) / 8)
76327876f38SJuergen Gross #define PARA_SITE(ptype, ops)	_PVSITE(ptype, ops, .quad, 8)
764bb898558SAl Viro #define PARA_INDIRECT(addr)	*addr(%rip)
7659104a18dSJeremy Fitzhardinge 
766e17f8234SBoris Ostrovsky #ifdef CONFIG_DEBUG_ENTRY
767fafe5e74SJuergen Gross .macro PARA_IRQ_save_fl
PARA_PATCH(PV_IRQ_save_fl)768fafe5e74SJuergen Gross 	PARA_SITE(PARA_PATCH(PV_IRQ_save_fl),
769fafe5e74SJuergen Gross 		  ANNOTATE_RETPOLINE_SAFE;
770fafe5e74SJuergen Gross 		  call PARA_INDIRECT(pv_ops+PV_IRQ_save_fl);)
771fafe5e74SJuergen Gross .endm
772fafe5e74SJuergen Gross 
773fafe5e74SJuergen Gross #define SAVE_FLAGS	ALTERNATIVE "PARA_IRQ_save_fl;", "pushf; pop %rax;", \
774fafe5e74SJuergen Gross 				    ALT_NOT(X86_FEATURE_XENPV)
775e17f8234SBoris Ostrovsky #endif
77655aedddbSPeter Zijlstra #endif /* CONFIG_PARAVIRT_XXL */
77755aedddbSPeter Zijlstra #endif	/* CONFIG_X86_64 */
778e17f8234SBoris Ostrovsky 
779bb898558SAl Viro #endif /* __ASSEMBLY__ */
7806f30c1acSThomas Gleixner #else  /* CONFIG_PARAVIRT */
7816f30c1acSThomas Gleixner # define default_banner x86_init_noop
782*ce0a1b60SArnd Bergmann 
783*ce0a1b60SArnd Bergmann #ifndef __ASSEMBLY__
784*ce0a1b60SArnd Bergmann static inline void native_pv_lock_init(void)
785*ce0a1b60SArnd Bergmann {
786*ce0a1b60SArnd Bergmann }
787*ce0a1b60SArnd Bergmann #endif
788fdc0269eSJuergen Gross #endif /* !CONFIG_PARAVIRT */
789fdc0269eSJuergen Gross 
790a1ea1c03SDave Hansen #ifndef __ASSEMBLY__
791fdc0269eSJuergen Gross #ifndef CONFIG_PARAVIRT_XXL
792c9ae1b10SJuergen Gross static inline void paravirt_enter_mmap(struct mm_struct *mm)
793a1ea1c03SDave Hansen {
794a1ea1c03SDave Hansen }
795fdc0269eSJuergen Gross #endif
796a1ea1c03SDave Hansen 
797fdc0269eSJuergen Gross #ifndef CONFIG_PARAVIRT
paravirt_arch_exit_mmap(struct mm_struct * mm)798a1ea1c03SDave Hansen static inline void paravirt_arch_exit_mmap(struct mm_struct *mm)
799a1ea1c03SDave Hansen {
800a1ea1c03SDave Hansen }
801fdc0269eSJuergen Gross #endif
8024e629211SJuergen Gross 
8034e629211SJuergen Gross #ifndef CONFIG_PARAVIRT_SPINLOCKS
paravirt_set_cap(void)8044e629211SJuergen Gross static inline void paravirt_set_cap(void)
8054e629211SJuergen Gross {
8064e629211SJuergen Gross }
8074e629211SJuergen Gross #endif
808a1ea1c03SDave Hansen #endif /* __ASSEMBLY__ */
8091965aae3SH. Peter Anvin #endif /* _ASM_X86_PARAVIRT_H */
810