Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20160…
Browse files Browse the repository at this point in the history
…527' into staging

linux-user pull request v2 for may 2016

# gpg: Signature made Fri 27 May 2016 12:51:10 BST using RSA key ID DE3C9BC0
# gpg: Good signature from "Riku Voipio <[email protected]>"
# gpg:                 aka "Riku Voipio <[email protected]>"

* remotes/riku/tags/pull-linux-user-20160527: (38 commits)
  linux-user,target-ppc: fix use of MSR_LE
  linux-user/signal.c: Use s390 target space address instead of host space
  linux-user/signal.c: Use target address instead of host address for microblaze restorer
  linux-user/signal.c: Generate opcode data for restorer in setup_rt_frame
  linux-user: arm: Remove ARM_cpsr and similar #defines
  linux-user: Use direct syscalls for setuid(), etc
  linux-user: x86_64: Don't use 16-bit UIDs
  linux-user: Use g_try_malloc() in do_msgrcv()
  linux-user: Handle msgrcv error case correctly
  linux-user: Handle negative values in timespec conversion
  linux-user: Use safe_syscall for futex syscall
  linux-user: Use safe_syscall for pselect, select syscalls
  linux-user: Use safe_syscall for execve syscall
  linux-user: Use safe_syscall for wait system calls
  linux-user: Use safe_syscall for open and openat system calls
  linux-user: Use safe_syscall for read and write system calls
  linux-user: Provide safe_syscall for fixing races between signals and syscalls
  linux-user: Add debug code to exercise restarting system calls
  linux-user: Support for restarting system calls for Microblaze targets
  linux-user: Set r14 on exit from microblaze syscall
  ...

Signed-off-by: Peter Maydell <[email protected]>
  • Loading branch information
pm215 committed May 27, 2016
2 parents 34c99d7 + 49e55cb commit d6550e9
Show file tree
Hide file tree
Showing 31 changed files with 1,539 additions and 972 deletions.
7 changes: 6 additions & 1 deletion Makefile.target
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,12 @@ obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal128.o

ifdef CONFIG_LINUX_USER

QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
# Note that we only add linux-user/host/$ARCH if it exists, and
# that it must come before linux-user/host/generic in the search path.
QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) \
$(patsubst %,-I%,$(wildcard $(SRC_PATH)/linux-user/host/$(ARCH))) \
-I$(SRC_PATH)/linux-user/host/generic \
-I$(SRC_PATH)/linux-user

obj-y += linux-user/
obj-y += gdbstub.o thunk.o user-exec.o
Expand Down
3 changes: 2 additions & 1 deletion linux-user/Makefile.objs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
obj-y = main.o syscall.o strace.o mmap.o signal.o \
elfload.o linuxload.o uaccess.o uname.o
elfload.o linuxload.o uaccess.o uname.o \
safe-syscall.o

obj-$(TARGET_HAS_BFLT) += flatload.o
obj-$(TARGET_I386) += vm86.o
Expand Down
1 change: 1 addition & 0 deletions linux-user/alpha/target_signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static inline abi_ulong get_sp_from_cpustate(CPUAlphaState *state)
return state->ir[IR_SP];
}


/* From <asm/gentrap.h>. */
#define TARGET_GEN_INTOVF -1 /* integer overflow */
#define TARGET_GEN_INTDIV -2 /* integer division by zero */
Expand Down
1 change: 1 addition & 0 deletions linux-user/arm/target_signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ static inline abi_ulong get_sp_from_cpustate(CPUARMState *state)
return state->regs[13];
}


#endif /* TARGET_SIGNAL_H */
20 changes: 1 addition & 19 deletions linux-user/arm/target_syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,11 @@
/* this struct defines the way the registers are stored on the
stack during a system call. */

/* uregs[0..15] are r0 to r15; uregs[16] is CPSR; uregs[17] is ORIG_r0 */
struct target_pt_regs {
abi_long uregs[18];
};

#define ARM_cpsr uregs[16]
#define ARM_pc uregs[15]
#define ARM_lr uregs[14]
#define ARM_sp uregs[13]
#define ARM_ip uregs[12]
#define ARM_fp uregs[11]
#define ARM_r10 uregs[10]
#define ARM_r9 uregs[9]
#define ARM_r8 uregs[8]
#define ARM_r7 uregs[7]
#define ARM_r6 uregs[6]
#define ARM_r5 uregs[5]
#define ARM_r4 uregs[4]
#define ARM_r3 uregs[3]
#define ARM_r2 uregs[2]
#define ARM_r1 uregs[1]
#define ARM_r0 uregs[0]
#define ARM_ORIG_r0 uregs[17]

#define ARM_SYSCALL_BASE 0x900000
#define ARM_THUMB_SYSCALL 0

Expand Down
1 change: 1 addition & 0 deletions linux-user/cris/target_signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ static inline abi_ulong get_sp_from_cpustate(CPUCRISState *state)
return state->regs[14];
}


#endif /* TARGET_SIGNAL_H */
19 changes: 10 additions & 9 deletions linux-user/elfload.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,19 +274,20 @@ static inline void init_thread(struct target_pt_regs *regs,
abi_long stack = infop->start_stack;
memset(regs, 0, sizeof(*regs));

regs->ARM_cpsr = 0x10;
if (infop->entry & 1)
regs->ARM_cpsr |= CPSR_T;
regs->ARM_pc = infop->entry & 0xfffffffe;
regs->ARM_sp = infop->start_stack;
regs->uregs[16] = ARM_CPU_MODE_USR;
if (infop->entry & 1) {
regs->uregs[16] |= CPSR_T;
}
regs->uregs[15] = infop->entry & 0xfffffffe;
regs->uregs[13] = infop->start_stack;
/* FIXME - what to for failure of get_user()? */
get_user_ual(regs->ARM_r2, stack + 8); /* envp */
get_user_ual(regs->ARM_r1, stack + 4); /* envp */
get_user_ual(regs->uregs[2], stack + 8); /* envp */
get_user_ual(regs->uregs[1], stack + 4); /* envp */
/* XXX: it seems that r0 is zeroed after ! */
regs->ARM_r0 = 0;
regs->uregs[0] = 0;
/* For uClinux PIC binaries. */
/* XXX: Linux does this only on ARM with no MMU (do we care ?) */
regs->ARM_r10 = infop->start_data;
regs->uregs[10] = infop->start_data;
}

#define ELF_NREG 18
Expand Down
17 changes: 17 additions & 0 deletions linux-user/errno_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,20 @@
/* for robust mutexes */
#define TARGET_EOWNERDEAD 130 /* Owner died */
#define TARGET_ENOTRECOVERABLE 131 /* State not recoverable */

/* QEMU internal, not visible to the guest. This is returned when a
* system call should be restarted, to tell the main loop that it
* should wind the guest PC backwards so it will re-execute the syscall
* after handling any pending signals. They match with the ones the guest
* kernel uses for the same purpose.
*/
#define TARGET_ERESTARTSYS 512 /* Restart system call (if SA_RESTART) */

/* QEMU internal, not visible to the guest. This is returned by the
* do_sigreturn() code after a successful sigreturn syscall, to indicate
* that it has correctly set the guest registers and so the main loop
* should not touch them. We use the value the guest would use for
* ERESTART_NOINTR (which is kernel internal) to guarantee that we won't
* clash with a valid guest errno now or in the future.
*/
#define TARGET_QEMU_ESIGRETURN 513 /* Return from signal */
20 changes: 20 additions & 0 deletions linux-user/host/generic/hostdep.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* hostdep.h : fallback generic version of header for things
* which are dependent on the host architecture
*
* * Written by Peter Maydell <[email protected]>
*
* Copyright (C) 2016 Linaro Limited
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/

#ifndef QEMU_HOSTDEP_H
#define QEMU_HOSTDEP_H

/* This is the fallback header which is only used if the host
* architecture doesn't provide one in linux-user/host/$ARCH.
*/

#endif
38 changes: 38 additions & 0 deletions linux-user/host/x86_64/hostdep.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* hostdep.h : things which are dependent on the host architecture
*
* * Written by Peter Maydell <[email protected]>
*
* Copyright (C) 2016 Linaro Limited
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/

#ifndef QEMU_HOSTDEP_H
#define QEMU_HOSTDEP_H

/* We have a safe-syscall.inc.S */
#define HAVE_SAFE_SYSCALL

#ifndef __ASSEMBLER__

/* These are defined by the safe-syscall.inc.S file */
extern char safe_syscall_start[];
extern char safe_syscall_end[];

/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc)
{
struct ucontext *uc = puc;
greg_t *pcreg = &uc->uc_mcontext.gregs[REG_RIP];

if (*pcreg > (uintptr_t)safe_syscall_start
&& *pcreg < (uintptr_t)safe_syscall_end) {
*pcreg = (uintptr_t)safe_syscall_start;
}
}

#endif /* __ASSEMBLER__ */

#endif
81 changes: 81 additions & 0 deletions linux-user/host/x86_64/safe-syscall.inc.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* safe-syscall.inc.S : host-specific assembly fragment
* to handle signals occurring at the same time as system calls.
* This is intended to be included by linux-user/safe-syscall.S
*
* Copyright (C) 2015 Timothy Edward Baldwin <[email protected]>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/

.global safe_syscall_base
.global safe_syscall_start
.global safe_syscall_end
.type safe_syscall_base, @function

/* This is the entry point for making a system call. The calling
* convention here is that of a C varargs function with the
* first argument an 'int *' to the signal_pending flag, the
* second one the system call number (as a 'long'), and all further
* arguments being syscall arguments (also 'long').
* We return a long which is the syscall's return value, which
* may be negative-errno on failure. Conversion to the
* -1-and-errno-set convention is done by the calling wrapper.
*/
safe_syscall_base:
/* This saves a frame pointer and aligns the stack for the syscall.
* (It's unclear if the syscall ABI has the same stack alignment
* requirements as the userspace function call ABI, but better safe than
* sorry. Appendix A2 of http://www.x86-64.org/documentation/abi.pdf
* does not list any ABI differences regarding stack alignment.)
*/
push %rbp

/* The syscall calling convention isn't the same as the
* C one:
* we enter with rdi == *signal_pending
* rsi == syscall number
* rdx, rcx, r8, r9, (stack), (stack) == syscall arguments
* and return the result in rax
* and the syscall instruction needs
* rax == syscall number
* rdi, rsi, rdx, r10, r8, r9 == syscall arguments
* and returns the result in rax
* Shuffle everything around appropriately.
* Note that syscall will trash rcx and r11.
*/
mov %rsi, %rax /* syscall number */
mov %rdi, %rbp /* signal_pending pointer */
/* and the syscall arguments */
mov %rdx, %rdi
mov %rcx, %rsi
mov %r8, %rdx
mov %r9, %r10
mov 16(%rsp), %r8
mov 24(%rsp), %r9

/* This next sequence of code works in conjunction with the
* rewind_if_safe_syscall_function(). If a signal is taken
* and the interrupted PC is anywhere between 'safe_syscall_start'
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
* The code sequence must therefore be able to cope with this, and
* the syscall instruction must be the final one in the sequence.
*/
safe_syscall_start:
/* if signal_pending is non-zero, don't do the call */
testl $1, (%rbp)
jnz return_ERESTARTSYS
syscall
safe_syscall_end:
/* code path for having successfully executed the syscall */
pop %rbp
ret

return_ERESTARTSYS:
/* code path when we didn't execute the syscall */
mov $-TARGET_ERESTARTSYS, %rax
pop %rbp
ret

.size safe_syscall_base, .-safe_syscall_base
1 change: 1 addition & 0 deletions linux-user/m68k/target_signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ static inline abi_ulong get_sp_from_cpustate(CPUM68KState *state)
return state->aregs[7];
}


#endif /* TARGET_SIGNAL_H */
Loading

0 comments on commit d6550e9

Please sign in to comment.