xref: /openbmc/linux/arch/x86/kernel/paravirt.c (revision d7bfc7d5)
1fd534e9bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2b1df07bdSGlauber de Oliveira Costa /*  Paravirtualization interfaces
3b1df07bdSGlauber de Oliveira Costa     Copyright (C) 2006 Rusty Russell IBM Corporation
4b1df07bdSGlauber de Oliveira Costa 
5b1df07bdSGlauber de Oliveira Costa 
6b1df07bdSGlauber de Oliveira Costa     2007 - x86_64 support added by Glauber de Oliveira Costa, Red Hat Inc
7b1df07bdSGlauber de Oliveira Costa */
8b1df07bdSGlauber de Oliveira Costa 
9b1df07bdSGlauber de Oliveira Costa #include <linux/errno.h>
10186f4360SPaul Gortmaker #include <linux/init.h>
11186f4360SPaul Gortmaker #include <linux/export.h>
12b1df07bdSGlauber de Oliveira Costa #include <linux/efi.h>
13b1df07bdSGlauber de Oliveira Costa #include <linux/bcd.h>
14b1df07bdSGlauber de Oliveira Costa #include <linux/highmem.h>
15376e2424SMasami Hiramatsu #include <linux/kprobes.h>
1665fddcfcSMike Rapoport #include <linux/pgtable.h>
17a0e2bf7cSJuergen Gross #include <linux/static_call.h>
18b1df07bdSGlauber de Oliveira Costa 
19b1df07bdSGlauber de Oliveira Costa #include <asm/bug.h>
20b1df07bdSGlauber de Oliveira Costa #include <asm/paravirt.h>
2150af5eadSPaul Gortmaker #include <asm/debugreg.h>
22b1df07bdSGlauber de Oliveira Costa #include <asm/desc.h>
23b1df07bdSGlauber de Oliveira Costa #include <asm/setup.h>
24b1df07bdSGlauber de Oliveira Costa #include <asm/time.h>
25eba0045fSJeremy Fitzhardinge #include <asm/pgalloc.h>
26b1df07bdSGlauber de Oliveira Costa #include <asm/irq.h>
27b1df07bdSGlauber de Oliveira Costa #include <asm/delay.h>
28b1df07bdSGlauber de Oliveira Costa #include <asm/fixmap.h>
29b1df07bdSGlauber de Oliveira Costa #include <asm/apic.h>
30b1df07bdSGlauber de Oliveira Costa #include <asm/tlbflush.h>
31b1df07bdSGlauber de Oliveira Costa #include <asm/timer.h>
32f05e798aSDavid Howells #include <asm/special_insns.h>
3348a8b97cSPeter Zijlstra #include <asm/tlb.h>
3499bcd4a6SJuergen Gross #include <asm/io_bitmap.h>
35b1df07bdSGlauber de Oliveira Costa 
36fc57a7c6SAndy Lutomirski /*
37fc57a7c6SAndy Lutomirski  * nop stub, which must not clobber anything *including the stack* to
38fc57a7c6SAndy Lutomirski  * avoid confusing the entry prologues.
39fc57a7c6SAndy Lutomirski  */
40fc57a7c6SAndy Lutomirski extern void _paravirt_nop(void);
41fc57a7c6SAndy Lutomirski asm (".pushsection .entry.text, \"ax\"\n"
42fc57a7c6SAndy Lutomirski      ".global _paravirt_nop\n"
43fc57a7c6SAndy Lutomirski      "_paravirt_nop:\n\t"
44fc57a7c6SAndy Lutomirski      "ret\n\t"
45fc57a7c6SAndy Lutomirski      ".size _paravirt_nop, . - _paravirt_nop\n\t"
46fc57a7c6SAndy Lutomirski      ".type _paravirt_nop, @function\n\t"
47fc57a7c6SAndy Lutomirski      ".popsection");
48b1df07bdSGlauber de Oliveira Costa 
496f30c1acSThomas Gleixner void __init default_banner(void)
50b1df07bdSGlauber de Oliveira Costa {
51b1df07bdSGlauber de Oliveira Costa 	printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
52b1df07bdSGlauber de Oliveira Costa 	       pv_info.name);
53b1df07bdSGlauber de Oliveira Costa }
54b1df07bdSGlauber de Oliveira Costa 
55b1df07bdSGlauber de Oliveira Costa /* Undefined instruction for dealing with missing ops pointers. */
56fafe5e74SJuergen Gross static void paravirt_BUG(void)
57fafe5e74SJuergen Gross {
58fafe5e74SJuergen Gross 	BUG();
59fafe5e74SJuergen Gross }
60b1df07bdSGlauber de Oliveira Costa 
61b1df07bdSGlauber de Oliveira Costa struct branch {
62b1df07bdSGlauber de Oliveira Costa 	unsigned char opcode;
63b1df07bdSGlauber de Oliveira Costa 	u32 delta;
64b1df07bdSGlauber de Oliveira Costa } __attribute__((packed));
65b1df07bdSGlauber de Oliveira Costa 
661fc654cfSIngo Molnar static unsigned paravirt_patch_call(void *insn_buff, const void *target,
67abc745f8SJuergen Gross 				    unsigned long addr, unsigned len)
68b1df07bdSGlauber de Oliveira Costa {
6911e86dc7SIngo Molnar 	const int call_len = 5;
701fc654cfSIngo Molnar 	struct branch *b = insn_buff;
7111e86dc7SIngo Molnar 	unsigned long delta = (unsigned long)target - (addr+call_len);
72b1df07bdSGlauber de Oliveira Costa 
7311e86dc7SIngo Molnar 	if (len < call_len) {
7411e86dc7SIngo Molnar 		pr_warn("paravirt: Failed to patch indirect CALL at %ps\n", (void *)addr);
7511e86dc7SIngo Molnar 		/* Kernel might not be viable if patching fails, bail out: */
7611e86dc7SIngo Molnar 		BUG_ON(1);
775800dc5cSPeter Zijlstra 	}
78b1df07bdSGlauber de Oliveira Costa 
79b1df07bdSGlauber de Oliveira Costa 	b->opcode = 0xe8; /* call */
80b1df07bdSGlauber de Oliveira Costa 	b->delta = delta;
8111e86dc7SIngo Molnar 	BUILD_BUG_ON(sizeof(*b) != call_len);
82b1df07bdSGlauber de Oliveira Costa 
8311e86dc7SIngo Molnar 	return call_len;
84b1df07bdSGlauber de Oliveira Costa }
85b1df07bdSGlauber de Oliveira Costa 
869bad5658SJuergen Gross #ifdef CONFIG_PARAVIRT_XXL
877847c7beSJuergen Gross /* identity function, which can be inlined */
887847c7beSJuergen Gross u64 notrace _paravirt_ident_64(u64 x)
897847c7beSJuergen Gross {
907847c7beSJuergen Gross 	return x;
917847c7beSJuergen Gross }
929bad5658SJuergen Gross #endif
93b1df07bdSGlauber de Oliveira Costa 
949043442bSJuergen Gross DEFINE_STATIC_KEY_TRUE(virt_spin_lock_key);
959043442bSJuergen Gross 
969043442bSJuergen Gross void __init native_pv_lock_init(void)
979043442bSJuergen Gross {
9867e87d43SBorislav Petkov 	if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
999043442bSJuergen Gross 		static_branch_disable(&virt_spin_lock_key);
1009043442bSJuergen Gross }
1019043442bSJuergen Gross 
102054ac8adSJuergen Gross unsigned int paravirt_patch(u8 type, void *insn_buff, unsigned long addr,
103054ac8adSJuergen Gross 			    unsigned int len)
1045c83511bSJuergen Gross {
1059043442bSJuergen Gross 	/*
1069043442bSJuergen Gross 	 * Neat trick to map patch type back to the call within the
1079043442bSJuergen Gross 	 * corresponding structure.
1089043442bSJuergen Gross 	 */
1095c83511bSJuergen Gross 	void *opfunc = *((void **)&pv_ops + type);
110b1df07bdSGlauber de Oliveira Costa 	unsigned ret;
111b1df07bdSGlauber de Oliveira Costa 
112b1df07bdSGlauber de Oliveira Costa 	if (opfunc == NULL)
113fafe5e74SJuergen Gross 		/* If there's no function, patch it with paravirt_BUG() */
114fafe5e74SJuergen Gross 		ret = paravirt_patch_call(insn_buff, paravirt_BUG, addr, len);
11541edafdbSJeremy Fitzhardinge 	else if (opfunc == _paravirt_nop)
11679f1d836SBorislav Petkov 		ret = 0;
117b1df07bdSGlauber de Oliveira Costa 	else
118abc745f8SJuergen Gross 		/* Otherwise call the function. */
1191fc654cfSIngo Molnar 		ret = paravirt_patch_call(insn_buff, opfunc, addr, len);
120b1df07bdSGlauber de Oliveira Costa 
121b1df07bdSGlauber de Oliveira Costa 	return ret;
122b1df07bdSGlauber de Oliveira Costa }
123b1df07bdSGlauber de Oliveira Costa 
124c5905afbSIngo Molnar struct static_key paravirt_steal_enabled;
125c5905afbSIngo Molnar struct static_key paravirt_steal_rq_enabled;
1263c404b57SGlauber Costa 
1273c404b57SGlauber Costa static u64 native_steal_clock(int cpu)
1283c404b57SGlauber Costa {
1293c404b57SGlauber Costa 	return 0;
1303c404b57SGlauber Costa }
1313c404b57SGlauber Costa 
132a0e2bf7cSJuergen Gross DEFINE_STATIC_CALL(pv_steal_clock, native_steal_clock);
133a0e2bf7cSJuergen Gross DEFINE_STATIC_CALL(pv_sched_clock, native_sched_clock);
134a0e2bf7cSJuergen Gross 
135a0e2bf7cSJuergen Gross void paravirt_set_sched_clock(u64 (*func)(void))
136a0e2bf7cSJuergen Gross {
137a0e2bf7cSJuergen Gross 	static_call_update(pv_sched_clock, func);
138a0e2bf7cSJuergen Gross }
139a0e2bf7cSJuergen Gross 
140b1df07bdSGlauber de Oliveira Costa /* These are in entry.S */
141b1df07bdSGlauber de Oliveira Costa extern void native_iret(void);
142b1df07bdSGlauber de Oliveira Costa 
143b1df07bdSGlauber de Oliveira Costa static struct resource reserve_ioports = {
144b1df07bdSGlauber de Oliveira Costa 	.start = 0,
145b1df07bdSGlauber de Oliveira Costa 	.end = IO_SPACE_LIMIT,
146b1df07bdSGlauber de Oliveira Costa 	.name = "paravirt-ioport",
147b1df07bdSGlauber de Oliveira Costa 	.flags = IORESOURCE_IO | IORESOURCE_BUSY,
148b1df07bdSGlauber de Oliveira Costa };
149b1df07bdSGlauber de Oliveira Costa 
150b1df07bdSGlauber de Oliveira Costa /*
151b1df07bdSGlauber de Oliveira Costa  * Reserve the whole legacy IO space to prevent any legacy drivers
152b1df07bdSGlauber de Oliveira Costa  * from wasting time probing for their hardware.  This is a fairly
153b1df07bdSGlauber de Oliveira Costa  * brute-force approach to disabling all non-virtual drivers.
154b1df07bdSGlauber de Oliveira Costa  *
155b1df07bdSGlauber de Oliveira Costa  * Note that this must be called very early to have any effect.
156b1df07bdSGlauber de Oliveira Costa  */
157b1df07bdSGlauber de Oliveira Costa int paravirt_disable_iospace(void)
158b1df07bdSGlauber de Oliveira Costa {
159f7743fe6SJeremy Fitzhardinge 	return request_resource(&ioport_resource, &reserve_ioports);
160b1df07bdSGlauber de Oliveira Costa }
161b1df07bdSGlauber de Oliveira Costa 
162b1df07bdSGlauber de Oliveira Costa static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LAZY_NONE;
163b1df07bdSGlauber de Oliveira Costa 
164b1df07bdSGlauber de Oliveira Costa static inline void enter_lazy(enum paravirt_lazy_mode mode)
165b1df07bdSGlauber de Oliveira Costa {
166c6ae41e7SAlex Shi 	BUG_ON(this_cpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
167b1df07bdSGlauber de Oliveira Costa 
168c6ae41e7SAlex Shi 	this_cpu_write(paravirt_lazy_mode, mode);
169b1df07bdSGlauber de Oliveira Costa }
170b1df07bdSGlauber de Oliveira Costa 
171b407fc57SJeremy Fitzhardinge static void leave_lazy(enum paravirt_lazy_mode mode)
172b1df07bdSGlauber de Oliveira Costa {
173c6ae41e7SAlex Shi 	BUG_ON(this_cpu_read(paravirt_lazy_mode) != mode);
174b1df07bdSGlauber de Oliveira Costa 
175c6ae41e7SAlex Shi 	this_cpu_write(paravirt_lazy_mode, PARAVIRT_LAZY_NONE);
176b1df07bdSGlauber de Oliveira Costa }
177b1df07bdSGlauber de Oliveira Costa 
178b1df07bdSGlauber de Oliveira Costa void paravirt_enter_lazy_mmu(void)
179b1df07bdSGlauber de Oliveira Costa {
180b1df07bdSGlauber de Oliveira Costa 	enter_lazy(PARAVIRT_LAZY_MMU);
181b1df07bdSGlauber de Oliveira Costa }
182b1df07bdSGlauber de Oliveira Costa 
183b1df07bdSGlauber de Oliveira Costa void paravirt_leave_lazy_mmu(void)
184b1df07bdSGlauber de Oliveira Costa {
185b407fc57SJeremy Fitzhardinge 	leave_lazy(PARAVIRT_LAZY_MMU);
186b1df07bdSGlauber de Oliveira Costa }
187b1df07bdSGlauber de Oliveira Costa 
188511ba86eSBoris Ostrovsky void paravirt_flush_lazy_mmu(void)
189511ba86eSBoris Ostrovsky {
190511ba86eSBoris Ostrovsky 	preempt_disable();
191511ba86eSBoris Ostrovsky 
192511ba86eSBoris Ostrovsky 	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
193511ba86eSBoris Ostrovsky 		arch_leave_lazy_mmu_mode();
194511ba86eSBoris Ostrovsky 		arch_enter_lazy_mmu_mode();
195511ba86eSBoris Ostrovsky 	}
196511ba86eSBoris Ostrovsky 
197511ba86eSBoris Ostrovsky 	preempt_enable();
198511ba86eSBoris Ostrovsky }
199511ba86eSBoris Ostrovsky 
2009bad5658SJuergen Gross #ifdef CONFIG_PARAVIRT_XXL
201224101edSJeremy Fitzhardinge void paravirt_start_context_switch(struct task_struct *prev)
202b1df07bdSGlauber de Oliveira Costa {
2032829b449SJeremy Fitzhardinge 	BUG_ON(preemptible());
2042829b449SJeremy Fitzhardinge 
205c6ae41e7SAlex Shi 	if (this_cpu_read(paravirt_lazy_mode) == PARAVIRT_LAZY_MMU) {
206b407fc57SJeremy Fitzhardinge 		arch_leave_lazy_mmu_mode();
207224101edSJeremy Fitzhardinge 		set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES);
208b407fc57SJeremy Fitzhardinge 	}
209b1df07bdSGlauber de Oliveira Costa 	enter_lazy(PARAVIRT_LAZY_CPU);
210b1df07bdSGlauber de Oliveira Costa }
211b1df07bdSGlauber de Oliveira Costa 
212224101edSJeremy Fitzhardinge void paravirt_end_context_switch(struct task_struct *next)
213b1df07bdSGlauber de Oliveira Costa {
2142829b449SJeremy Fitzhardinge 	BUG_ON(preemptible());
2152829b449SJeremy Fitzhardinge 
216b407fc57SJeremy Fitzhardinge 	leave_lazy(PARAVIRT_LAZY_CPU);
217b407fc57SJeremy Fitzhardinge 
218224101edSJeremy Fitzhardinge 	if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES))
219b407fc57SJeremy Fitzhardinge 		arch_enter_lazy_mmu_mode();
220b1df07bdSGlauber de Oliveira Costa }
2210a53c9acSPeter Zijlstra 
2220a53c9acSPeter Zijlstra static noinstr unsigned long pv_native_read_cr2(void)
2230a53c9acSPeter Zijlstra {
2240a53c9acSPeter Zijlstra 	return native_read_cr2();
2250a53c9acSPeter Zijlstra }
226209cfd0cSPeter Zijlstra 
227209cfd0cSPeter Zijlstra static noinstr void pv_native_write_cr2(unsigned long val)
228209cfd0cSPeter Zijlstra {
229209cfd0cSPeter Zijlstra 	native_write_cr2(val);
230209cfd0cSPeter Zijlstra }
231f4afb713SPeter Zijlstra 
232f4afb713SPeter Zijlstra static noinstr unsigned long pv_native_get_debugreg(int regno)
233f4afb713SPeter Zijlstra {
234f4afb713SPeter Zijlstra 	return native_get_debugreg(regno);
235f4afb713SPeter Zijlstra }
2367361fac0SPeter Zijlstra 
2377361fac0SPeter Zijlstra static noinstr void pv_native_set_debugreg(int regno, unsigned long val)
2387361fac0SPeter Zijlstra {
2397361fac0SPeter Zijlstra 	native_set_debugreg(regno, val);
2407361fac0SPeter Zijlstra }
241*d7bfc7d5SPeter Zijlstra 
242*d7bfc7d5SPeter Zijlstra static noinstr void pv_native_irq_enable(void)
243*d7bfc7d5SPeter Zijlstra {
244*d7bfc7d5SPeter Zijlstra 	native_irq_enable();
245*d7bfc7d5SPeter Zijlstra }
2469bad5658SJuergen Gross #endif
247b1df07bdSGlauber de Oliveira Costa 
248b1df07bdSGlauber de Oliveira Costa enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
249b1df07bdSGlauber de Oliveira Costa {
250b8bcfe99SJeremy Fitzhardinge 	if (in_interrupt())
251b8bcfe99SJeremy Fitzhardinge 		return PARAVIRT_LAZY_NONE;
252b8bcfe99SJeremy Fitzhardinge 
253c6ae41e7SAlex Shi 	return this_cpu_read(paravirt_lazy_mode);
254b1df07bdSGlauber de Oliveira Costa }
255b1df07bdSGlauber de Oliveira Costa 
256b1df07bdSGlauber de Oliveira Costa struct pv_info pv_info = {
257b1df07bdSGlauber de Oliveira Costa 	.name = "bare hardware",
25840181646SJuergen Gross #ifdef CONFIG_PARAVIRT_XXL
259318f5a2aSAndy Lutomirski 	.extra_user_64bit_cs = __USER_CS,
260318f5a2aSAndy Lutomirski #endif
261b1df07bdSGlauber de Oliveira Costa };
262b1df07bdSGlauber de Oliveira Costa 
26341edafdbSJeremy Fitzhardinge /* 64-bit pagetable entries */
264da5de7c2SJeremy Fitzhardinge #define PTE_IDENT	__PV_IS_CALLEE_SAVE(_paravirt_ident_64)
26541edafdbSJeremy Fitzhardinge 
2665c83511bSJuergen Gross struct paravirt_patch_template pv_ops = {
2675c83511bSJuergen Gross 	/* Cpu ops. */
2689bad5658SJuergen Gross 	.cpu.io_delay		= native_io_delay,
269b1df07bdSGlauber de Oliveira Costa 
2709bad5658SJuergen Gross #ifdef CONFIG_PARAVIRT_XXL
2715c83511bSJuergen Gross 	.cpu.cpuid		= native_cpuid,
272f4afb713SPeter Zijlstra 	.cpu.get_debugreg	= pv_native_get_debugreg,
2737361fac0SPeter Zijlstra 	.cpu.set_debugreg	= pv_native_set_debugreg,
2745c83511bSJuergen Gross 	.cpu.read_cr0		= native_read_cr0,
2755c83511bSJuergen Gross 	.cpu.write_cr0		= native_write_cr0,
2765c83511bSJuergen Gross 	.cpu.write_cr4		= native_write_cr4,
2775c83511bSJuergen Gross 	.cpu.wbinvd		= native_wbinvd,
2785c83511bSJuergen Gross 	.cpu.read_msr		= native_read_msr,
2795c83511bSJuergen Gross 	.cpu.write_msr		= native_write_msr,
2805c83511bSJuergen Gross 	.cpu.read_msr_safe	= native_read_msr_safe,
2815c83511bSJuergen Gross 	.cpu.write_msr_safe	= native_write_msr_safe,
2825c83511bSJuergen Gross 	.cpu.read_pmc		= native_read_pmc,
2835c83511bSJuergen Gross 	.cpu.load_tr_desc	= native_load_tr_desc,
2845c83511bSJuergen Gross 	.cpu.set_ldt		= native_set_ldt,
2855c83511bSJuergen Gross 	.cpu.load_gdt		= native_load_gdt,
2865c83511bSJuergen Gross 	.cpu.load_idt		= native_load_idt,
2875c83511bSJuergen Gross 	.cpu.store_tr		= native_store_tr,
2885c83511bSJuergen Gross 	.cpu.load_tls		= native_load_tls,
2895c83511bSJuergen Gross 	.cpu.load_gs_index	= native_load_gs_index,
2905c83511bSJuergen Gross 	.cpu.write_ldt_entry	= native_write_ldt_entry,
2915c83511bSJuergen Gross 	.cpu.write_gdt_entry	= native_write_gdt_entry,
2925c83511bSJuergen Gross 	.cpu.write_idt_entry	= native_write_idt_entry,
293eba0045fSJeremy Fitzhardinge 
2945c83511bSJuergen Gross 	.cpu.alloc_ldt		= paravirt_nop,
2955c83511bSJuergen Gross 	.cpu.free_ldt		= paravirt_nop,
296b1df07bdSGlauber de Oliveira Costa 
2975c83511bSJuergen Gross 	.cpu.load_sp0		= native_load_sp0,
298b1df07bdSGlauber de Oliveira Costa 
29999bcd4a6SJuergen Gross #ifdef CONFIG_X86_IOPL_IOPERM
300cadfad87SAndy Lutomirski 	.cpu.invalidate_io_bitmap	= native_tss_invalidate_io_bitmap,
30199bcd4a6SJuergen Gross 	.cpu.update_io_bitmap		= native_tss_update_io_bitmap,
30299bcd4a6SJuergen Gross #endif
30399bcd4a6SJuergen Gross 
3045c83511bSJuergen Gross 	.cpu.start_context_switch	= paravirt_nop,
3055c83511bSJuergen Gross 	.cpu.end_context_switch		= paravirt_nop,
3065c83511bSJuergen Gross 
3075c83511bSJuergen Gross 	/* Irq ops. */
3085c83511bSJuergen Gross 	.irq.save_fl		= __PV_IS_CALLEE_SAVE(native_save_fl),
3095c83511bSJuergen Gross 	.irq.irq_disable	= __PV_IS_CALLEE_SAVE(native_irq_disable),
310*d7bfc7d5SPeter Zijlstra 	.irq.irq_enable		= __PV_IS_CALLEE_SAVE(pv_native_irq_enable),
3115c83511bSJuergen Gross 	.irq.safe_halt		= native_safe_halt,
3125c83511bSJuergen Gross 	.irq.halt		= native_halt,
3136da63eb2SJuergen Gross #endif /* CONFIG_PARAVIRT_XXL */
3145c83511bSJuergen Gross 
3155c83511bSJuergen Gross 	/* Mmu ops. */
3162faf153bSThomas Gleixner 	.mmu.flush_tlb_user	= native_flush_tlb_local,
3175c83511bSJuergen Gross 	.mmu.flush_tlb_kernel	= native_flush_tlb_global,
3185c83511bSJuergen Gross 	.mmu.flush_tlb_one_user	= native_flush_tlb_one_user,
3194ce94eabSNadav Amit 	.mmu.flush_tlb_multi	= native_flush_tlb_multi,
3205c83511bSJuergen Gross 	.mmu.tlb_remove_table	=
3215c83511bSJuergen Gross 			(void (*)(struct mmu_gather *, void *))tlb_remove_page,
3225c83511bSJuergen Gross 
323fdc0269eSJuergen Gross 	.mmu.exit_mmap		= paravirt_nop,
324fdc0269eSJuergen Gross 
325fdc0269eSJuergen Gross #ifdef CONFIG_PARAVIRT_XXL
3260a53c9acSPeter Zijlstra 	.mmu.read_cr2		= __PV_IS_CALLEE_SAVE(pv_native_read_cr2),
327209cfd0cSPeter Zijlstra 	.mmu.write_cr2		= pv_native_write_cr2,
328fdc0269eSJuergen Gross 	.mmu.read_cr3		= __native_read_cr3,
329fdc0269eSJuergen Gross 	.mmu.write_cr3		= native_write_cr3,
330fdc0269eSJuergen Gross 
3315c83511bSJuergen Gross 	.mmu.pgd_alloc		= __paravirt_pgd_alloc,
3325c83511bSJuergen Gross 	.mmu.pgd_free		= paravirt_nop,
3335c83511bSJuergen Gross 
3345c83511bSJuergen Gross 	.mmu.alloc_pte		= paravirt_nop,
3355c83511bSJuergen Gross 	.mmu.alloc_pmd		= paravirt_nop,
3365c83511bSJuergen Gross 	.mmu.alloc_pud		= paravirt_nop,
3375c83511bSJuergen Gross 	.mmu.alloc_p4d		= paravirt_nop,
3385c83511bSJuergen Gross 	.mmu.release_pte	= paravirt_nop,
3395c83511bSJuergen Gross 	.mmu.release_pmd	= paravirt_nop,
3405c83511bSJuergen Gross 	.mmu.release_pud	= paravirt_nop,
3415c83511bSJuergen Gross 	.mmu.release_p4d	= paravirt_nop,
3425c83511bSJuergen Gross 
3435c83511bSJuergen Gross 	.mmu.set_pte		= native_set_pte,
3445c83511bSJuergen Gross 	.mmu.set_pmd		= native_set_pmd,
3455c83511bSJuergen Gross 
3465c83511bSJuergen Gross 	.mmu.ptep_modify_prot_start	= __ptep_modify_prot_start,
3475c83511bSJuergen Gross 	.mmu.ptep_modify_prot_commit	= __ptep_modify_prot_commit,
34808b882c6SJeremy Fitzhardinge 
3495c83511bSJuergen Gross 	.mmu.set_pud		= native_set_pud,
350da5de7c2SJeremy Fitzhardinge 
3515c83511bSJuergen Gross 	.mmu.pmd_val		= PTE_IDENT,
3525c83511bSJuergen Gross 	.mmu.make_pmd		= PTE_IDENT,
353f95f2f7bSEduardo Habkost 
3545c83511bSJuergen Gross 	.mmu.pud_val		= PTE_IDENT,
3555c83511bSJuergen Gross 	.mmu.make_pud		= PTE_IDENT,
356da5de7c2SJeremy Fitzhardinge 
3575c83511bSJuergen Gross 	.mmu.set_p4d		= native_set_p4d,
358f2a6a705SKirill A. Shutemov 
359f2a6a705SKirill A. Shutemov #if CONFIG_PGTABLE_LEVELS >= 5
3605c83511bSJuergen Gross 	.mmu.p4d_val		= PTE_IDENT,
3615c83511bSJuergen Gross 	.mmu.make_p4d		= PTE_IDENT,
362335437fbSKirill A. Shutemov 
3635c83511bSJuergen Gross 	.mmu.set_pgd		= native_set_pgd,
364335437fbSKirill A. Shutemov #endif /* CONFIG_PGTABLE_LEVELS >= 5 */
365b1df07bdSGlauber de Oliveira Costa 
3665c83511bSJuergen Gross 	.mmu.pte_val		= PTE_IDENT,
3675c83511bSJuergen Gross 	.mmu.pgd_val		= PTE_IDENT,
368b1df07bdSGlauber de Oliveira Costa 
3695c83511bSJuergen Gross 	.mmu.make_pte		= PTE_IDENT,
3705c83511bSJuergen Gross 	.mmu.make_pgd		= PTE_IDENT,
371b1df07bdSGlauber de Oliveira Costa 
3725c83511bSJuergen Gross 	.mmu.dup_mmap		= paravirt_nop,
3735c83511bSJuergen Gross 	.mmu.activate_mm	= paravirt_nop,
374b1df07bdSGlauber de Oliveira Costa 
3755c83511bSJuergen Gross 	.mmu.lazy_mode = {
376b1df07bdSGlauber de Oliveira Costa 		.enter		= paravirt_nop,
377b1df07bdSGlauber de Oliveira Costa 		.leave		= paravirt_nop,
378511ba86eSBoris Ostrovsky 		.flush		= paravirt_nop,
379b1df07bdSGlauber de Oliveira Costa 	},
380aeaaa59cSJeremy Fitzhardinge 
3815c83511bSJuergen Gross 	.mmu.set_fixmap		= native_set_fixmap,
382fdc0269eSJuergen Gross #endif /* CONFIG_PARAVIRT_XXL */
3835c83511bSJuergen Gross 
3845c83511bSJuergen Gross #if defined(CONFIG_PARAVIRT_SPINLOCKS)
3855c83511bSJuergen Gross 	/* Lock ops. */
3865c83511bSJuergen Gross #ifdef CONFIG_SMP
3875c83511bSJuergen Gross 	.lock.queued_spin_lock_slowpath	= native_queued_spin_lock_slowpath,
3885c83511bSJuergen Gross 	.lock.queued_spin_unlock	=
3895c83511bSJuergen Gross 				PV_CALLEE_SAVE(__native_queued_spin_unlock),
3905c83511bSJuergen Gross 	.lock.wait			= paravirt_nop,
3915c83511bSJuergen Gross 	.lock.kick			= paravirt_nop,
3925c83511bSJuergen Gross 	.lock.vcpu_is_preempted		=
3935c83511bSJuergen Gross 				PV_CALLEE_SAVE(__native_vcpu_is_preempted),
3945c83511bSJuergen Gross #endif /* SMP */
3955c83511bSJuergen Gross #endif
396b1df07bdSGlauber de Oliveira Costa };
397b1df07bdSGlauber de Oliveira Costa 
3989bad5658SJuergen Gross #ifdef CONFIG_PARAVIRT_XXL
3995c83511bSJuergen Gross NOKPROBE_SYMBOL(native_load_idt);
400ae755b5aSJuergen Gross 
401ae755b5aSJuergen Gross void (*paravirt_iret)(void) = native_iret;
4029bad5658SJuergen Gross #endif
4035c83511bSJuergen Gross 
4048af19095SJuergen Gross EXPORT_SYMBOL(pv_ops);
405b1df07bdSGlauber de Oliveira Costa EXPORT_SYMBOL_GPL(pv_info);
406