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