Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55aedddb authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Thomas Gleixner
Browse files

x86/paravirt: Make read_cr2() CALLEE_SAVE



The one paravirt read_cr2() implementation (Xen) is actually quite trivial
and doesn't need to clobber anything other than the return register.

Making read_cr2() CALLEE_SAVE avoids all the PUSH/POP nonsense and allows
more convenient use from assembly.

Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Reviewed-by: default avatarJuergen Gross <jgross@suse.com>
Cc: bp@alien8.de
Cc: rostedt@goodmis.org
Cc: luto@kernel.org
Cc: torvalds@linux-foundation.org
Cc: hpa@zytor.com
Cc: dave.hansen@linux.intel.com
Cc: zhe.he@windriver.com
Cc: joel@joelfernandes.org
Cc: devel@etsukata.com
Link: https://lkml.kernel.org/r/20190711114335.887392493@infradead.org
parent 406de552
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -343,3 +343,9 @@ For 32-bit we have the following conventions - kernel is built with
.Lafter_call_\@:
#endif
.endm

#ifdef CONFIG_PARAVIRT_XXL
#define GET_CR2_INTO(reg) GET_CR2_INTO_AX ; _ASM_MOV %_ASM_AX, reg
#else
#define GET_CR2_INTO(reg) _ASM_MOV %cr2, reg
#endif
+13 −9
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ static inline void write_cr0(unsigned long x)

static inline unsigned long read_cr2(void)
{
	return PVOP_CALL0(unsigned long, mmu.read_cr2);
	return PVOP_CALLEE0(unsigned long, mmu.read_cr2);
}

static inline void write_cr2(unsigned long x)
@@ -909,13 +909,7 @@ extern void default_banner(void);
		  ANNOTATE_RETPOLINE_SAFE;				\
		  call PARA_INDIRECT(pv_ops+PV_CPU_swapgs);		\
		 )
#endif

#define GET_CR2_INTO_RAX				\
	ANNOTATE_RETPOLINE_SAFE;				\
	call PARA_INDIRECT(pv_ops+PV_MMU_read_cr2);

#ifdef CONFIG_PARAVIRT_XXL
#define USERGS_SYSRET64							\
	PARA_SITE(PARA_PATCH(PV_CPU_usergs_sysret64),			\
		  ANNOTATE_RETPOLINE_SAFE;				\
@@ -929,9 +923,19 @@ extern void default_banner(void);
		  call PARA_INDIRECT(pv_ops+PV_IRQ_save_fl);	    \
		  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
#endif
#endif
#endif /* CONFIG_PARAVIRT_XXL */
#endif	/* CONFIG_X86_64 */

#ifdef CONFIG_PARAVIRT_XXL

#define GET_CR2_INTO_AX							\
	PARA_SITE(PARA_PATCH(PV_MMU_read_cr2),				\
		  ANNOTATE_RETPOLINE_SAFE;				\
		  call PARA_INDIRECT(pv_ops+PV_MMU_read_cr2);		\
		 )

#endif /* CONFIG_PARAVIRT_XXL */

#endif	/* CONFIG_X86_32 */

#endif /* __ASSEMBLY__ */
#else  /* CONFIG_PARAVIRT */
+1 −1
Original line number Diff line number Diff line
@@ -220,7 +220,7 @@ struct pv_mmu_ops {
	void (*exit_mmap)(struct mm_struct *mm);

#ifdef CONFIG_PARAVIRT_XXL
	unsigned long (*read_cr2)(void);
	struct paravirt_callee_save read_cr2;
	void (*write_cr2)(unsigned long);

	unsigned long (*read_cr3)(void);
+1 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ static void __used common(void)
	BLANK();
	OFFSET(XEN_vcpu_info_mask, vcpu_info, evtchn_upcall_mask);
	OFFSET(XEN_vcpu_info_pending, vcpu_info, evtchn_upcall_pending);
	OFFSET(XEN_vcpu_info_arch_cr2, vcpu_info, arch.cr2);
#endif

	BLANK();
+1 −3
Original line number Diff line number Diff line
@@ -29,9 +29,7 @@
#ifdef CONFIG_PARAVIRT_XXL
#include <asm/asm-offsets.h>
#include <asm/paravirt.h>
#define GET_CR2_INTO(reg) GET_CR2_INTO_RAX ; movq %rax, reg
#else
#define GET_CR2_INTO(reg) movq %cr2, reg
#define INTERRUPT_RETURN iretq
#endif

@@ -323,7 +321,7 @@ early_idt_handler_common:

	cmpq $14,%rsi		/* Page fault? */
	jnz 10f
	GET_CR2_INTO(%rdi)	/* Can clobber any volatile register if pv */
	GET_CR2_INTO(%rdi)	/* can clobber %rax if pv */
	call early_make_pgtable
	andl %eax,%eax
	jz 20f			/* All good */
Loading