mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'riku/linux-user-for-upstream' into staging
* riku/linux-user-for-upstream: (21 commits) linux-user: Handle compressed ISA encodings when processing MIPS exceptions linux-user: Unlock mmap_lock when resuming guest from page_unprotect linux-user: Reset copied CPUs in cpu_copy() always linux-user: Fix epoll on ARM hosts linux-user: fix segmentation fault passing with h2g(x) != x linux-user: Fix pipe syscall return for SPARC linux-user: Fix target_stat and target_stat64 for OpenRISC linux-user: Avoid conditional cpu_reset() configure: Make NPTL non-optional linux-user: Enable NPTL for x86-64 linux-user: Add i386 TLS setter linux-user: Clean up handling of clone() argument order linux-user: Add missing 'break' in i386 get_thread_area syscall linux-user: Enable NPTL for m68k linux-user: Enable NPTL for SPARC targets linux-user: Enable NPTL for OpenRISC linux-user: Move includes of target-specific headers to end of qemu.h configure: Enable threading for unicore32-linux-user configure: Enable threading on all ppc and mips linux-user targets configure: Don't say target_nptl="no" if there is no linux-user target ... Conflicts: linux-user/main.c Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
@@ -155,7 +155,6 @@ curl=""
|
||||
curses=""
|
||||
docs=""
|
||||
fdt=""
|
||||
nptl=""
|
||||
pixman=""
|
||||
sdl=""
|
||||
virtfs=""
|
||||
@@ -856,10 +855,6 @@ for opt do
|
||||
;;
|
||||
--enable-fdt) fdt="yes"
|
||||
;;
|
||||
--disable-nptl) nptl="no"
|
||||
;;
|
||||
--enable-nptl) nptl="yes"
|
||||
;;
|
||||
--enable-mixemu) mixemu="yes"
|
||||
;;
|
||||
--disable-linux-aio) linux_aio="no"
|
||||
@@ -1103,8 +1098,6 @@ echo " --enable-kvm enable KVM acceleration support"
|
||||
echo " --disable-rdma disable RDMA-based migration support"
|
||||
echo " --enable-rdma enable RDMA-based migration support"
|
||||
echo " --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)"
|
||||
echo " --disable-nptl disable usermode NPTL support"
|
||||
echo " --enable-nptl enable usermode NPTL support"
|
||||
echo " --enable-system enable all system emulation targets"
|
||||
echo " --disable-system disable all system emulation targets"
|
||||
echo " --enable-user enable supported user emulation targets"
|
||||
@@ -1439,7 +1432,7 @@ fi
|
||||
##########################################
|
||||
# NPTL probe
|
||||
|
||||
if test "$nptl" != "no" ; then
|
||||
if test "$linux_user" = "yes"; then
|
||||
cat > $TMPC <<EOF
|
||||
#include <sched.h>
|
||||
#include <linux/futex.h>
|
||||
@@ -1450,14 +1443,8 @@ int main(void) {
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
if compile_object ; then
|
||||
nptl=yes
|
||||
else
|
||||
if test "$nptl" = "yes" ; then
|
||||
feature_not_found "nptl"
|
||||
fi
|
||||
nptl=no
|
||||
if ! compile_object ; then
|
||||
feature_not_found "nptl"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -3581,7 +3568,6 @@ echo "bluez support $bluez"
|
||||
echo "Documentation $docs"
|
||||
[ ! -z "$uname_release" ] && \
|
||||
echo "uname -r $uname_release"
|
||||
echo "NPTL support $nptl"
|
||||
echo "GUEST_BASE $guest_base"
|
||||
echo "PIE $pie"
|
||||
echo "vde support $vde"
|
||||
@@ -4216,7 +4202,6 @@ mkdir -p $target_dir
|
||||
echo "# Automatically generated by configure - do not modify" > $config_target_mak
|
||||
|
||||
bflt="no"
|
||||
target_nptl="no"
|
||||
interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_name/g"`
|
||||
gdb_xml_files=""
|
||||
|
||||
@@ -4231,16 +4216,13 @@ case "$target_name" in
|
||||
TARGET_BASE_ARCH=i386
|
||||
;;
|
||||
alpha)
|
||||
target_nptl="yes"
|
||||
;;
|
||||
arm|armeb)
|
||||
TARGET_ARCH=arm
|
||||
bflt="yes"
|
||||
target_nptl="yes"
|
||||
gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
|
||||
;;
|
||||
cris)
|
||||
target_nptl="yes"
|
||||
;;
|
||||
lm32)
|
||||
;;
|
||||
@@ -4251,12 +4233,10 @@ case "$target_name" in
|
||||
microblaze|microblazeel)
|
||||
TARGET_ARCH=microblaze
|
||||
bflt="yes"
|
||||
target_nptl="yes"
|
||||
;;
|
||||
mips|mipsel)
|
||||
TARGET_ARCH=mips
|
||||
echo "TARGET_ABI_MIPSO32=y" >> $config_target_mak
|
||||
target_nptl="yes"
|
||||
;;
|
||||
mipsn32|mipsn32el)
|
||||
TARGET_ARCH=mips64
|
||||
@@ -4277,13 +4257,11 @@ case "$target_name" in
|
||||
;;
|
||||
ppc)
|
||||
gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
|
||||
target_nptl="yes"
|
||||
;;
|
||||
ppcemb)
|
||||
TARGET_BASE_ARCH=ppc
|
||||
TARGET_ABI_DIR=ppc
|
||||
gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
|
||||
target_nptl="yes"
|
||||
;;
|
||||
ppc64)
|
||||
TARGET_BASE_ARCH=ppc
|
||||
@@ -4300,7 +4278,6 @@ case "$target_name" in
|
||||
sh4|sh4eb)
|
||||
TARGET_ARCH=sh4
|
||||
bflt="yes"
|
||||
target_nptl="yes"
|
||||
;;
|
||||
sparc)
|
||||
;;
|
||||
@@ -4314,7 +4291,6 @@ case "$target_name" in
|
||||
echo "TARGET_ABI32=y" >> $config_target_mak
|
||||
;;
|
||||
s390x)
|
||||
target_nptl="yes"
|
||||
;;
|
||||
unicore32)
|
||||
;;
|
||||
@@ -4396,10 +4372,6 @@ fi
|
||||
if test "$target_user_only" = "yes" -a "$bflt" = "yes"; then
|
||||
echo "TARGET_HAS_BFLT=y" >> $config_target_mak
|
||||
fi
|
||||
if test "$target_user_only" = "yes" \
|
||||
-a "$nptl" = "yes" -a "$target_nptl" = "yes"; then
|
||||
echo "CONFIG_USE_NPTL=y" >> $config_target_mak
|
||||
fi
|
||||
if test "$target_user_only" = "yes" -a "$guest_base" = "yes"; then
|
||||
echo "CONFIG_USE_GUEST_BASE=y" >> $config_target_mak
|
||||
fi
|
||||
|
||||
@@ -646,6 +646,10 @@ CPUArchState *cpu_copy(CPUArchState *env)
|
||||
CPUWatchpoint *wp;
|
||||
#endif
|
||||
|
||||
/* Reset non arch specific state */
|
||||
cpu_reset(ENV_GET_CPU(new_env));
|
||||
|
||||
/* Copy arch specific state into the new CPU */
|
||||
memcpy(new_env, env, sizeof(CPUArchState));
|
||||
|
||||
/* Clone all break/watchpoints.
|
||||
|
||||
@@ -210,11 +210,15 @@ extern unsigned long reserved_va;
|
||||
})
|
||||
#endif
|
||||
|
||||
#define h2g(x) ({ \
|
||||
#define h2g_nocheck(x) ({ \
|
||||
unsigned long __ret = (unsigned long)(x) - GUEST_BASE; \
|
||||
(abi_ulong)__ret; \
|
||||
})
|
||||
|
||||
#define h2g(x) ({ \
|
||||
/* Check if given address fits target address space */ \
|
||||
assert(h2g_valid(x)); \
|
||||
(abi_ulong)__ret; \
|
||||
h2g_nocheck(x); \
|
||||
})
|
||||
|
||||
#define saddr(x) g2h(x)
|
||||
|
||||
@@ -32,7 +32,7 @@ void gdb_register_coprocessor(CPUState *cpu,
|
||||
|
||||
static inline int cpu_index(CPUState *cpu)
|
||||
{
|
||||
#if defined(CONFIG_USER_ONLY) && defined(CONFIG_USE_NPTL)
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
return cpu->host_tid;
|
||||
#else
|
||||
return cpu->cpu_index + 1;
|
||||
|
||||
@@ -40,3 +40,5 @@ struct target_pt_regs {
|
||||
#else
|
||||
#define UNAME_MACHINE "armv5tel"
|
||||
#endif
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
||||
@@ -38,4 +38,6 @@ struct target_pt_regs {
|
||||
unsigned long eda;
|
||||
};
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS2
|
||||
|
||||
#endif
|
||||
|
||||
@@ -144,3 +144,5 @@ struct target_vm86plus_struct {
|
||||
};
|
||||
|
||||
#define UNAME_MACHINE "i686"
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
||||
@@ -28,6 +28,21 @@ static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp)
|
||||
env->regs[R_EAX] = 0;
|
||||
}
|
||||
|
||||
/* TODO: need to implement cpu_set_tls() */
|
||||
#if defined(TARGET_ABI32)
|
||||
abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr);
|
||||
|
||||
#endif
|
||||
static inline void cpu_set_tls(CPUX86State *env, target_ulong newtls)
|
||||
{
|
||||
do_set_thread_area(env, newtls);
|
||||
cpu_x86_load_seg(env, R_GS, env->segs[R_GS].selector);
|
||||
}
|
||||
#else
|
||||
abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr);
|
||||
|
||||
static inline void cpu_set_tls(CPUX86State *env, target_ulong newtls)
|
||||
{
|
||||
do_arch_prctl(env, TARGET_ARCH_SET_FS, newtls);
|
||||
}
|
||||
#endif /* defined(TARGET_ABI32) */
|
||||
|
||||
#endif /* !defined(TARGET_CPU_H) */
|
||||
|
||||
@@ -29,6 +29,10 @@ static inline void cpu_clone_regs(CPUM68KState *env, target_ulong newsp)
|
||||
env->dregs[0] = 0;
|
||||
}
|
||||
|
||||
/* TODO: need to implement cpu_set_tls() */
|
||||
static inline void cpu_set_tls(CPUM68KState *env, target_ulong newtls)
|
||||
{
|
||||
TaskState *ts = env->opaque;
|
||||
ts->tp_value = newtls;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+44
-49
@@ -92,7 +92,6 @@ int cpu_get_pic_interrupt(CPUX86State *env)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
/***********************************************************/
|
||||
/* Helper routines for implementing atomic operations. */
|
||||
|
||||
@@ -207,43 +206,6 @@ void cpu_list_unlock(void)
|
||||
{
|
||||
pthread_mutex_unlock(&cpu_list_mutex);
|
||||
}
|
||||
#else /* if !CONFIG_USE_NPTL */
|
||||
/* These are no-ops because we are not threadsafe. */
|
||||
static inline void cpu_exec_start(CPUState *cpu)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void cpu_exec_end(CPUState *cpu)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void start_exclusive(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void end_exclusive(void)
|
||||
{
|
||||
}
|
||||
|
||||
void fork_start(void)
|
||||
{
|
||||
}
|
||||
|
||||
void fork_end(int child)
|
||||
{
|
||||
if (child) {
|
||||
gdbserver_fork((CPUArchState *)thread_cpu->env_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_list_lock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void cpu_list_unlock(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TARGET_I386
|
||||
@@ -2349,7 +2311,31 @@ done_syscall:
|
||||
abi_ulong trap_instr;
|
||||
unsigned int code;
|
||||
|
||||
ret = get_user_ual(trap_instr, env->active_tc.PC);
|
||||
if (env->hflags & MIPS_HFLAG_M16) {
|
||||
if (env->insn_flags & ASE_MICROMIPS) {
|
||||
/* microMIPS mode */
|
||||
abi_ulong instr[2];
|
||||
|
||||
ret = get_user_u16(instr[0], env->active_tc.PC) ||
|
||||
get_user_u16(instr[1], env->active_tc.PC + 2);
|
||||
|
||||
trap_instr = (instr[0] << 16) | instr[1];
|
||||
} else {
|
||||
/* MIPS16e mode */
|
||||
ret = get_user_u16(trap_instr, env->active_tc.PC);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
code = (trap_instr >> 6) & 0x3f;
|
||||
if (do_break(env, &info, code) != 0) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = get_user_ual(trap_instr, env->active_tc.PC);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
@@ -2373,14 +2359,30 @@ done_syscall:
|
||||
abi_ulong trap_instr;
|
||||
unsigned int code = 0;
|
||||
|
||||
ret = get_user_ual(trap_instr, env->active_tc.PC);
|
||||
if (env->hflags & MIPS_HFLAG_M16) {
|
||||
/* microMIPS mode */
|
||||
abi_ulong instr[2];
|
||||
|
||||
ret = get_user_u16(instr[0], env->active_tc.PC) ||
|
||||
get_user_u16(instr[1], env->active_tc.PC + 2);
|
||||
|
||||
trap_instr = (instr[0] << 16) | instr[1];
|
||||
} else {
|
||||
ret = get_user_ual(trap_instr, env->active_tc.PC);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* The immediate versions don't provide a code. */
|
||||
if (!(trap_instr & 0xFC000000)) {
|
||||
code = ((trap_instr >> 6) & ((1 << 10) - 1));
|
||||
if (env->hflags & MIPS_HFLAG_M16) {
|
||||
/* microMIPS mode */
|
||||
code = ((trap_instr >> 12) & ((1 << 4) - 1));
|
||||
} else {
|
||||
code = ((trap_instr >> 6) & ((1 << 10) - 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (do_break(env, &info, code) != 0) {
|
||||
@@ -3157,12 +3159,7 @@ THREAD CPUState *thread_cpu;
|
||||
void task_settid(TaskState *ts)
|
||||
{
|
||||
if (ts->ts_tid == 0) {
|
||||
#ifdef CONFIG_USE_NPTL
|
||||
ts->ts_tid = (pid_t)syscall(SYS_gettid);
|
||||
#else
|
||||
/* when no threads are used, tid becomes pid */
|
||||
ts->ts_tid = getpid();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3640,9 +3637,7 @@ int main(int argc, char **argv, char **envp)
|
||||
exit(1);
|
||||
}
|
||||
cpu = ENV_GET_CPU(env);
|
||||
#if defined(TARGET_SPARC) || defined(TARGET_PPC)
|
||||
cpu_reset(cpu);
|
||||
#endif
|
||||
cpu_reset(ENV_GET_CPU(env));
|
||||
|
||||
thread_cpu = cpu;
|
||||
|
||||
|
||||
@@ -48,4 +48,6 @@ struct target_pt_regs {
|
||||
uint32_t kernel_mode;
|
||||
};
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -225,3 +225,5 @@ struct target_pt_regs {
|
||||
#define TARGET_QEMU_ESIGRETURN 255
|
||||
|
||||
#define UNAME_MACHINE "mips"
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
||||
@@ -222,3 +222,5 @@ struct target_pt_regs {
|
||||
#define TARGET_QEMU_ESIGRETURN 255
|
||||
|
||||
#define UNAME_MACHINE "mips64"
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
|
||||
//#define DEBUG_MMAP
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static __thread int mmap_lock_count;
|
||||
|
||||
@@ -66,16 +65,6 @@ void mmap_fork_end(int child)
|
||||
else
|
||||
pthread_mutex_unlock(&mmap_mutex);
|
||||
}
|
||||
#else
|
||||
/* We aren't threadsafe to start with, so no need to worry about locking. */
|
||||
void mmap_lock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void mmap_unlock(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* NOTE: all the constants are the HOST ones, but addresses are target. */
|
||||
int target_mprotect(abi_ulong start, abi_ulong len, int prot)
|
||||
|
||||
@@ -25,9 +25,14 @@ static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
|
||||
if (newsp) {
|
||||
env->gpr[1] = newsp;
|
||||
}
|
||||
env->gpr[2] = 0;
|
||||
env->gpr[11] = 0;
|
||||
}
|
||||
|
||||
/* TODO: need to implement cpu_set_tls() */
|
||||
static inline void cpu_set_tls(CPUOpenRISCState *env, target_ulong newtls)
|
||||
{
|
||||
/* Linux kernel 3.10 does not pay any attention to CLONE_SETTLS
|
||||
* in copy_thread(), so QEMU need not do so either.
|
||||
*/
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -62,3 +62,5 @@ struct target_revectored_struct {
|
||||
#else
|
||||
#define UNAME_MACHINE "ppc"
|
||||
#endif
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
||||
+8
-12
@@ -16,16 +16,10 @@
|
||||
#include "exec/user/thunk.h"
|
||||
#include "syscall_defs.h"
|
||||
#include "syscall.h"
|
||||
#include "target_cpu.h"
|
||||
#include "target_signal.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/queue.h"
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
#define THREAD __thread
|
||||
#else
|
||||
#define THREAD
|
||||
#endif
|
||||
|
||||
/* This struct is used to hold certain information about the image.
|
||||
* Basically, it replicates in user space what would be certain
|
||||
@@ -118,11 +112,10 @@ typedef struct TaskState {
|
||||
uint32_t v86flags;
|
||||
uint32_t v86mask;
|
||||
#endif
|
||||
#ifdef CONFIG_USE_NPTL
|
||||
abi_ulong child_tidptr;
|
||||
#endif
|
||||
#ifdef TARGET_M68K
|
||||
int sim_syscalls;
|
||||
abi_ulong tp_value;
|
||||
#endif
|
||||
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
|
||||
/* Extra fields for semihosted binaries. */
|
||||
@@ -269,10 +262,8 @@ void mmap_unlock(void);
|
||||
abi_ulong mmap_find_vma(abi_ulong, abi_ulong);
|
||||
void cpu_list_lock(void);
|
||||
void cpu_list_unlock(void);
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
void mmap_fork_start(void);
|
||||
void mmap_fork_end(int child);
|
||||
#endif
|
||||
|
||||
/* main.c */
|
||||
extern unsigned long guest_stack_size;
|
||||
@@ -450,8 +441,13 @@ static inline void *lock_user_string(abi_ulong guest_addr)
|
||||
#define unlock_user_struct(host_ptr, guest_addr, copy) \
|
||||
unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
/* Include target-specific struct and function definitions;
|
||||
* they may need access to the target-independent structures
|
||||
* above, so include them last.
|
||||
*/
|
||||
#include "target_cpu.h"
|
||||
#include "target_signal.h"
|
||||
|
||||
#endif /* QEMU_H */
|
||||
|
||||
@@ -21,3 +21,5 @@ struct target_pt_regs {
|
||||
};
|
||||
|
||||
#define UNAME_MACHINE "s390x"
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
||||
@@ -7,3 +7,10 @@ struct target_pt_regs {
|
||||
};
|
||||
|
||||
#define UNAME_MACHINE "sun4"
|
||||
|
||||
/* SPARC kernels don't define this in their Kconfig, but they have the
|
||||
* same ABI as if they did, implemented by sparc-specific code which fishes
|
||||
* directly in the u_regs() struct for half the parameters in sparc_do_fork()
|
||||
* and copy_thread().
|
||||
*/
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
||||
@@ -25,12 +25,20 @@ static inline void cpu_clone_regs(CPUSPARCState *env, target_ulong newsp)
|
||||
if (newsp) {
|
||||
env->regwptr[22] = newsp;
|
||||
}
|
||||
/* syscall return for clone child: 0, and clear CF since
|
||||
* this counts as a success return value.
|
||||
*/
|
||||
env->regwptr[0] = 0;
|
||||
/* FIXME: Do we also need to clear CF? */
|
||||
/* XXXXX */
|
||||
printf("HELPME: %s:%d\n", __FILE__, __LINE__);
|
||||
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
|
||||
env->xcc &= ~PSR_CARRY;
|
||||
#else
|
||||
env->psr &= ~PSR_CARRY;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* TODO: need to implement cpu_set_tls() */
|
||||
static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls)
|
||||
{
|
||||
env->gregs[7] = newtls;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user