qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

linux-user: Provide safe_syscall for ppc64

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>

authored by

Richard Henderson and committed by
Riku Voipio
4ba92cd7 c9bc3437

+115
+23
linux-user/host/ppc64/hostdep.h
··· 12 12 #ifndef QEMU_HOSTDEP_H 13 13 #define QEMU_HOSTDEP_H 14 14 15 + /* We have a safe-syscall.inc.S */ 16 + #define HAVE_SAFE_SYSCALL 17 + 18 + #ifndef __ASSEMBLER__ 19 + 20 + /* These are defined by the safe-syscall.inc.S file */ 21 + extern char safe_syscall_start[]; 22 + extern char safe_syscall_end[]; 23 + 24 + /* Adjust the signal context to rewind out of safe-syscall if we're in it */ 25 + static inline void rewind_if_in_safe_syscall(void *puc) 26 + { 27 + struct ucontext *uc = puc; 28 + unsigned long *pcreg = &uc->uc_mcontext.gp_regs[PT_NIP]; 29 + 30 + if (*pcreg > (uintptr_t)safe_syscall_start 31 + && *pcreg < (uintptr_t)safe_syscall_end) { 32 + *pcreg = (uintptr_t)safe_syscall_start; 33 + } 34 + } 35 + 36 + #endif /* __ASSEMBLER__ */ 37 + 15 38 #endif
+92
linux-user/host/ppc64/safe-syscall.inc.S
··· 1 + /* 2 + * safe-syscall.inc.S : host-specific assembly fragment 3 + * to handle signals occurring at the same time as system calls. 4 + * This is intended to be included by linux-user/safe-syscall.S 5 + * 6 + * Written by Richard Henderson <rth@twiddle.net> 7 + * Copyright (C) 2016 Red Hat, Inc. 8 + * 9 + * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 + * See the COPYING file in the top-level directory. 11 + */ 12 + 13 + .global safe_syscall_base 14 + .global safe_syscall_start 15 + .global safe_syscall_end 16 + .type safe_syscall_base, @function 17 + 18 + .text 19 + 20 + /* This is the entry point for making a system call. The calling 21 + * convention here is that of a C varargs function with the 22 + * first argument an 'int *' to the signal_pending flag, the 23 + * second one the system call number (as a 'long'), and all further 24 + * arguments being syscall arguments (also 'long'). 25 + * We return a long which is the syscall's return value, which 26 + * may be negative-errno on failure. Conversion to the 27 + * -1-and-errno-set convention is done by the calling wrapper. 28 + */ 29 + #if _CALL_ELF == 2 30 + safe_syscall_base: 31 + .cfi_startproc 32 + .localentry safe_syscall_base,0 33 + #else 34 + .section ".opd","aw" 35 + .align 3 36 + safe_syscall_base: 37 + .quad .L.safe_syscall_base,.TOC.@tocbase,0 38 + .previous 39 + .L.safe_syscall_base: 40 + .cfi_startproc 41 + #endif 42 + /* We enter with r3 == *signal_pending 43 + * r4 == syscall number 44 + * r5 ... r10 == syscall arguments 45 + * and return the result in r3 46 + * and the syscall instruction needs 47 + * r0 == syscall number 48 + * r3 ... r8 == syscall arguments 49 + * and returns the result in r3 50 + * Shuffle everything around appropriately. 51 + */ 52 + mr 11, 3 /* signal_pending */ 53 + mr 0, 4 /* syscall number */ 54 + mr 3, 5 /* syscall arguments */ 55 + mr 4, 6 56 + mr 5, 7 57 + mr 6, 8 58 + mr 7, 9 59 + mr 8, 10 60 + 61 + /* This next sequence of code works in conjunction with the 62 + * rewind_if_safe_syscall_function(). If a signal is taken 63 + * and the interrupted PC is anywhere between 'safe_syscall_start' 64 + * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'. 65 + * The code sequence must therefore be able to cope with this, and 66 + * the syscall instruction must be the final one in the sequence. 67 + */ 68 + safe_syscall_start: 69 + /* if signal_pending is non-zero, don't do the call */ 70 + lwz 12, 0(11) 71 + cmpwi 0, 12, 0 72 + bne- 0f 73 + sc 74 + safe_syscall_end: 75 + /* code path when we did execute the syscall */ 76 + bnslr+ 77 + 78 + /* syscall failed; return negative errno */ 79 + neg 3, 3 80 + blr 81 + 82 + /* code path when we didn't execute the syscall */ 83 + 0: addi 3, 0, -TARGET_ERESTARTSYS 84 + blr 85 + .cfi_endproc 86 + 87 + #if _CALL_ELF == 2 88 + .size safe_syscall_base, .-safe_syscall_base 89 + #else 90 + .size safe_syscall_base, .-.L.safe_syscall_base 91 + .size .L.safe_syscall_base, .-.L.safe_syscall_base 92 + #endif