 2cf91b9ae6
			
		
	
	
		2cf91b9ae6
		
	
	
	
	
		
			
			Fixes: e34136d93059 "linux-user/ppc: Add vdso" Fixes: 86f04735ac20 "linux-user: Fix brk() to release pages" Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
		
			
				
	
	
		
			240 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			240 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * PowerPC linux replacement vdso.
 | |
|  *
 | |
|  * Copyright 2023 Linaro, Ltd.
 | |
|  *
 | |
|  * SPDX-License-Identifier: GPL-2.0-or-later
 | |
|  */
 | |
| 
 | |
| #include <asm/unistd.h>
 | |
| #include <asm/errno.h>
 | |
| 
 | |
| #ifndef _ARCH_PPC64
 | |
| # define TARGET_ABI32
 | |
| #endif
 | |
| #include "vdso-asmoffset.h"
 | |
| 
 | |
| 
 | |
| 	.text
 | |
| 
 | |
| .macro endf name
 | |
| 	.globl	\name
 | |
| 	.size	\name, .-\name
 | |
| 	/* For PPC64, functions have special linkage; we export pointers. */
 | |
| #ifndef _ARCH_PPC64
 | |
| 	.type	\name, @function
 | |
| #endif
 | |
| .endm
 | |
| 
 | |
| .macro raw_syscall nr
 | |
| 	addi	0, 0, \nr
 | |
| 	sc
 | |
| .endm
 | |
| 
 | |
| .macro vdso_syscall name, nr
 | |
| \name:
 | |
| 	raw_syscall \nr
 | |
| 	blr
 | |
| endf	\name
 | |
| .endm
 | |
| 
 | |
| 	.cfi_startproc
 | |
| 
 | |
| vdso_syscall __kernel_gettimeofday, __NR_gettimeofday
 | |
| vdso_syscall __kernel_clock_gettime, __NR_clock_gettime
 | |
| vdso_syscall __kernel_clock_getres, __NR_clock_getres
 | |
| vdso_syscall __kernel_getcpu, __NR_getcpu
 | |
| vdso_syscall __kernel_time, __NR_time
 | |
| 
 | |
| #ifdef __NR_clock_gettime64
 | |
| vdso_syscall __kernel_clock_gettime64, __NR_clock_gettime64
 | |
| #endif
 | |
| 
 | |
| __kernel_sync_dicache:
 | |
| 	/* qemu does not need to flush caches */
 | |
| 	blr
 | |
| endf	__kernel_sync_dicache
 | |
| 
 | |
| 	.cfi_endproc
 | |
| 
 | |
| /*
 | |
|  * TODO: __kernel_get_tbfreq
 | |
|  * This is probably a constant for QEMU.
 | |
|  */
 | |
| 
 | |
| /*
 | |
|  * Start the unwind info at least one instruction before the signal
 | |
|  * trampoline, because the unwinder will assume we are returning
 | |
|  * after a call site.
 | |
|  */
 | |
| 
 | |
| 	.cfi_startproc simple
 | |
| 	.cfi_signal_frame
 | |
| 
 | |
| #ifdef _ARCH_PPC64
 | |
| # define __kernel_sigtramp_rt  __kernel_sigtramp_rt64
 | |
| # define sizeof_reg	8
 | |
| #else
 | |
| # define __kernel_sigtramp_rt  __kernel_sigtramp_rt32
 | |
| # define sizeof_reg	4
 | |
| #endif
 | |
| #define sizeof_freg	8
 | |
| #define sizeof_vreg	16
 | |
| 
 | |
| 	.cfi_def_cfa	1, SIGNAL_FRAMESIZE + offsetof_rt_sigframe_mcontext
 | |
| 
 | |
| 	/* Return address */
 | |
| 	.cfi_return_column 67
 | |
| 	.cfi_offset	67, 32 * sizeof_reg		/* nip */
 | |
| 
 | |
| 	/* Integer registers */
 | |
| 	.cfi_offset	0, 0 * sizeof_reg
 | |
| 	.cfi_offset	1, 1 * sizeof_reg
 | |
| 	.cfi_offset	2, 2 * sizeof_reg
 | |
| 	.cfi_offset	3, 3 * sizeof_reg
 | |
| 	.cfi_offset	4, 4 * sizeof_reg
 | |
| 	.cfi_offset	5, 5 * sizeof_reg
 | |
| 	.cfi_offset	6, 6 * sizeof_reg
 | |
| 	.cfi_offset	7, 7 * sizeof_reg
 | |
| 	.cfi_offset	8, 8 * sizeof_reg
 | |
| 	.cfi_offset	9, 9 * sizeof_reg
 | |
| 	.cfi_offset	10, 10 * sizeof_reg
 | |
| 	.cfi_offset	11, 11 * sizeof_reg
 | |
| 	.cfi_offset	12, 12 * sizeof_reg
 | |
| 	.cfi_offset	13, 13 * sizeof_reg
 | |
| 	.cfi_offset	14, 14 * sizeof_reg
 | |
| 	.cfi_offset	15, 15 * sizeof_reg
 | |
| 	.cfi_offset	16, 16 * sizeof_reg
 | |
| 	.cfi_offset	17, 17 * sizeof_reg
 | |
| 	.cfi_offset	18, 18 * sizeof_reg
 | |
| 	.cfi_offset	19, 19 * sizeof_reg
 | |
| 	.cfi_offset	20, 20 * sizeof_reg
 | |
| 	.cfi_offset	21, 21 * sizeof_reg
 | |
| 	.cfi_offset	22, 22 * sizeof_reg
 | |
| 	.cfi_offset	23, 23 * sizeof_reg
 | |
| 	.cfi_offset	24, 24 * sizeof_reg
 | |
| 	.cfi_offset	25, 25 * sizeof_reg
 | |
| 	.cfi_offset	26, 26 * sizeof_reg
 | |
| 	.cfi_offset	27, 27 * sizeof_reg
 | |
| 	.cfi_offset	28, 28 * sizeof_reg
 | |
| 	.cfi_offset	29, 29 * sizeof_reg
 | |
| 	.cfi_offset	30, 30 * sizeof_reg
 | |
| 	.cfi_offset	31, 31 * sizeof_reg
 | |
| 	.cfi_offset	65, 36 * sizeof_reg		/* lr */
 | |
| 	.cfi_offset	70, 38 * sizeof_reg		/* ccr */
 | |
| 
 | |
| 	/* Floating point registers */
 | |
| 	.cfi_offset	32, offsetof_mcontext_fregs
 | |
| 	.cfi_offset	33, offsetof_mcontext_fregs + 1 * sizeof_freg
 | |
| 	.cfi_offset	34, offsetof_mcontext_fregs + 2 * sizeof_freg
 | |
| 	.cfi_offset	35, offsetof_mcontext_fregs + 3 * sizeof_freg
 | |
| 	.cfi_offset	36, offsetof_mcontext_fregs + 4 * sizeof_freg
 | |
| 	.cfi_offset	37, offsetof_mcontext_fregs + 5 * sizeof_freg
 | |
| 	.cfi_offset	38, offsetof_mcontext_fregs + 6 * sizeof_freg
 | |
| 	.cfi_offset	39, offsetof_mcontext_fregs + 7 * sizeof_freg
 | |
| 	.cfi_offset	40, offsetof_mcontext_fregs + 8 * sizeof_freg
 | |
| 	.cfi_offset	41, offsetof_mcontext_fregs + 9 * sizeof_freg
 | |
| 	.cfi_offset	42, offsetof_mcontext_fregs + 10 * sizeof_freg
 | |
| 	.cfi_offset	43, offsetof_mcontext_fregs + 11 * sizeof_freg
 | |
| 	.cfi_offset	44, offsetof_mcontext_fregs + 12 * sizeof_freg
 | |
| 	.cfi_offset	45, offsetof_mcontext_fregs + 13 * sizeof_freg
 | |
| 	.cfi_offset	46, offsetof_mcontext_fregs + 14 * sizeof_freg
 | |
| 	.cfi_offset	47, offsetof_mcontext_fregs + 15 * sizeof_freg
 | |
| 	.cfi_offset	48, offsetof_mcontext_fregs + 16 * sizeof_freg
 | |
| 	.cfi_offset	49, offsetof_mcontext_fregs + 17 * sizeof_freg
 | |
| 	.cfi_offset	50, offsetof_mcontext_fregs + 18 * sizeof_freg
 | |
| 	.cfi_offset	51, offsetof_mcontext_fregs + 19 * sizeof_freg
 | |
| 	.cfi_offset	52, offsetof_mcontext_fregs + 20 * sizeof_freg
 | |
| 	.cfi_offset	53, offsetof_mcontext_fregs + 21 * sizeof_freg
 | |
| 	.cfi_offset	54, offsetof_mcontext_fregs + 22 * sizeof_freg
 | |
| 	.cfi_offset	55, offsetof_mcontext_fregs + 23 * sizeof_freg
 | |
| 	.cfi_offset	56, offsetof_mcontext_fregs + 24 * sizeof_freg
 | |
| 	.cfi_offset	57, offsetof_mcontext_fregs + 25 * sizeof_freg
 | |
| 	.cfi_offset	58, offsetof_mcontext_fregs + 26 * sizeof_freg
 | |
| 	.cfi_offset	59, offsetof_mcontext_fregs + 27 * sizeof_freg
 | |
| 	.cfi_offset	60, offsetof_mcontext_fregs + 28 * sizeof_freg
 | |
| 	.cfi_offset	61, offsetof_mcontext_fregs + 29 * sizeof_freg
 | |
| 	.cfi_offset	62, offsetof_mcontext_fregs + 30 * sizeof_freg
 | |
| 	.cfi_offset	63, offsetof_mcontext_fregs + 31 * sizeof_freg
 | |
| 
 | |
| 	/*
 | |
| 	 * Unlike the kernel, unconditionally represent the Altivec/VSX regs.
 | |
| 	 * The space within the stack frame is always available, and most of
 | |
| 	 * our supported processors have them enabled.  The only complication
 | |
| 	 * for PPC64 is the misalignment, so that we have to use indirection.
 | |
| 	 */
 | |
| .macro	save_vreg_ofs reg, ofs
 | |
| #ifdef _ARCH_PPC64
 | |
| 	/*
 | |
| 	 * vreg = *(cfa + offsetof(v_regs)) + ofs
 | |
|          *
 | |
|          * The CFA is input to the expression on the stack, so:
 | |
| 	 * DW_CFA_expression reg, length (7),
 | |
|          *   DW_OP_plus_uconst (0x23), vreg_ptr, DW_OP_deref (0x06),
 | |
| 	 *   DW_OP_plus_uconst (0x23), ofs
 | |
| 	 */
 | |
| 	.cfi_escape 0x10, 77 + \reg, 7, 0x23, (offsetof_mcontext_vregs_ptr & 0x7f) + 0x80, offsetof_mcontext_vregs_ptr >> 7, 0x06, 0x23, (\ofs & 0x7f) | 0x80, \ofs >> 7
 | |
| #else
 | |
| 	.cfi_offset 77 + \reg, offsetof_mcontext_vregs + \ofs
 | |
| #endif
 | |
| .endm
 | |
| 
 | |
| .macro	save_vreg reg
 | |
| 	save_vreg_ofs \reg, (\reg * sizeof_vreg)
 | |
| .endm
 | |
| 
 | |
| 	save_vreg   0
 | |
| 	save_vreg   1
 | |
| 	save_vreg   2
 | |
| 	save_vreg   3
 | |
| 	save_vreg   4
 | |
| 	save_vreg   5
 | |
| 	save_vreg   6
 | |
| 	save_vreg   7
 | |
| 	save_vreg   8
 | |
| 	save_vreg   9
 | |
| 	save_vreg  10
 | |
| 	save_vreg  11
 | |
| 	save_vreg  12
 | |
| 	save_vreg  13
 | |
| 	save_vreg  14
 | |
| 	save_vreg  15
 | |
| 	save_vreg  16
 | |
| 	save_vreg  17
 | |
| 	save_vreg  18
 | |
| 	save_vreg  19
 | |
| 	save_vreg  20
 | |
| 	save_vreg  21
 | |
| 	save_vreg  22
 | |
| 	save_vreg  23
 | |
| 	save_vreg  24
 | |
| 	save_vreg  25
 | |
| 	save_vreg  26
 | |
| 	save_vreg  27
 | |
| 	save_vreg  28
 | |
| 	save_vreg  29
 | |
| 	save_vreg  30
 | |
| 	save_vreg  31
 | |
| 	save_vreg  32
 | |
| 	save_vreg_ofs 33, (32 * sizeof_vreg + 12)
 | |
| 
 | |
| 	nop
 | |
| 
 | |
| __kernel_sigtramp_rt:
 | |
| 	raw_syscall __NR_rt_sigreturn
 | |
| endf	__kernel_sigtramp_rt
 | |
| 
 | |
| #ifndef _ARCH_PPC64
 | |
| 	/*
 | |
| 	 * The non-rt sigreturn has the same layout at a different offset.
 | |
| 	 * Move the CFA and leave all the other descriptions the same.
 | |
| 	 */
 | |
| 	.cfi_def_cfa	1, SIGNAL_FRAMESIZE + offsetof_sigframe_mcontext
 | |
| 	nop
 | |
| __kernel_sigtramp32:
 | |
| 	raw_syscall __NR_sigreturn
 | |
| endf	__kernel_sigtramp32
 | |
| #endif
 | |
| 
 | |
| 	.cfi_endproc
 |