From 9d3019bce39efd32f54d31d4aedef27a31a15c24 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Sun, 14 Jul 2019 15:40:27 +0200 Subject: [PATCH 01/15] linux-user: remove useless variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit filename is only used to open the file if AT_EXECFD is not provided. But exec_path already contains the path of the file to open. Remove filename as it is only used in main.c whereas exec_path is also used in syscall.c. Fixes: d088d664f201 ("linux-user: identify running binary in /proc/self/exe") Signed-off-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Stefano Garzarella Message-Id: <20190714134028.315-1-laurent@vivier.eu> Signed-off-by: Laurent Vivier --- linux-user/main.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 47917bbb20..28f0065b6d 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -49,7 +49,6 @@ char *exec_path; int singlestep; -static const char *filename; static const char *argv0; static int gdbstub_port; static envlist_t *envlist; @@ -586,7 +585,6 @@ static int parse_args(int argc, char **argv) exit(EXIT_FAILURE); } - filename = argv[optind]; exec_path = argv[optind]; return optind; @@ -657,9 +655,9 @@ int main(int argc, char **argv, char **envp) execfd = qemu_getauxval(AT_EXECFD); if (execfd == 0) { - execfd = open(filename, O_RDONLY); + execfd = open(exec_path, O_RDONLY); if (execfd < 0) { - printf("Error while loading %s: %s\n", filename, strerror(errno)); + printf("Error while loading %s: %s\n", exec_path, strerror(errno)); _exit(EXIT_FAILURE); } } @@ -784,10 +782,10 @@ int main(int argc, char **argv, char **envp) cpu->opaque = ts; task_settid(ts); - ret = loader_exec(execfd, filename, target_argv, target_environ, regs, + ret = loader_exec(execfd, exec_path, target_argv, target_environ, regs, info, &bprm); if (ret != 0) { - printf("Error while loading %s: %s\n", filename, strerror(-ret)); + printf("Error while loading %s: %s\n", exec_path, strerror(-ret)); _exit(EXIT_FAILURE); } From 2041df4a050cec1efbba4f87e2bb9c40e7fd6cdf Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 9 Aug 2019 10:11:56 -0700 Subject: [PATCH 02/15] linux-user: Add AT_HWCAP2 for aarch64-linux-user Add the HWCAP2_* bits from kernel version v5.3-rc3. Enable the bits corresponding to ARMv8.5-CondM and ARMv8.5-FRINT. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-Id: <20190809171156.3476-1-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/elfload.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 3365e192eb..43c16a846d 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -607,9 +607,23 @@ enum { ARM_HWCAP_A64_SB = 1 << 29, ARM_HWCAP_A64_PACA = 1 << 30, ARM_HWCAP_A64_PACG = 1UL << 31, + + ARM_HWCAP2_A64_DCPODP = 1 << 0, + ARM_HWCAP2_A64_SVE2 = 1 << 1, + ARM_HWCAP2_A64_SVEAES = 1 << 2, + ARM_HWCAP2_A64_SVEPMULL = 1 << 3, + ARM_HWCAP2_A64_SVEBITPERM = 1 << 4, + ARM_HWCAP2_A64_SVESHA3 = 1 << 5, + ARM_HWCAP2_A64_SVESM4 = 1 << 6, + ARM_HWCAP2_A64_FLAGM2 = 1 << 7, + ARM_HWCAP2_A64_FRINT = 1 << 8, }; -#define ELF_HWCAP get_elf_hwcap() +#define ELF_HWCAP get_elf_hwcap() +#define ELF_HWCAP2 get_elf_hwcap2() + +#define GET_FEATURE_ID(feat, hwcap) \ + do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0) static uint32_t get_elf_hwcap(void) { @@ -621,8 +635,6 @@ static uint32_t get_elf_hwcap(void) hwcaps |= ARM_HWCAP_A64_CPUID; /* probe for the extra features */ -#define GET_FEATURE_ID(feat, hwcap) \ - do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0) GET_FEATURE_ID(aa64_aes, ARM_HWCAP_A64_AES); GET_FEATURE_ID(aa64_pmull, ARM_HWCAP_A64_PMULL); @@ -645,11 +657,22 @@ static uint32_t get_elf_hwcap(void) GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB); GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM); -#undef GET_FEATURE_ID + return hwcaps; +} + +static uint32_t get_elf_hwcap2(void) +{ + ARMCPU *cpu = ARM_CPU(thread_cpu); + uint32_t hwcaps = 0; + + GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2); + GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT); return hwcaps; } +#undef GET_FEATURE_ID + #endif /* not TARGET_AARCH64 */ #endif /* TARGET_ARM */ From 895e2ef521ae0eef2fdfcec8f2108d9ee3303a81 Mon Sep 17 00:00:00 2001 From: Shu-Chun Weng Date: Mon, 19 Aug 2019 11:53:48 -0700 Subject: [PATCH 03/15] linux-user: erroneous fd_trans_unregister call timer_getoverrun returns the "overrun count" for the timer, which is not a file descriptor and thus should not call fd_trans_unregister on it. Signed-off-by: Shu-Chun Weng Reviewed-by: Laurent Vivier Message-Id: <20190819185348.221825-1-scw@google.com> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 1 - 1 file changed, 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 8b41a03901..b42f59a32c 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -11847,7 +11847,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, timer_t htimer = g_posix_timers[timerid]; ret = get_errno(timer_getoverrun(htimer)); } - fd_trans_unregister(ret); return ret; } #endif From 7f4341e84bb867c6e3397a978d3ee131bf8a889b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Fri, 30 Aug 2019 15:36:48 +0100 Subject: [PATCH 04/15] linux-user: fail and report on bad dfilter specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just passing NULL means we end up ignoring the bad dfilter spec instead of reporting it and exiting as we should. Signed-off-by: Alex Bennée Reviewed-by: Laurent Vivier Message-Id: <20190830143648.2967-1-alex.bennee@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/main.c b/linux-user/main.c index 28f0065b6d..c257b063db 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -235,7 +235,7 @@ static void handle_arg_log(const char *arg) static void handle_arg_dfilter(const char *arg) { - qemu_set_dfilter_ranges(arg, NULL); + qemu_set_dfilter_ranges(arg, &error_fatal); } static void handle_arg_log_filename(const char *arg) From 9bdfa4d23f4395dab89a60eb6b05a0308792bd66 Mon Sep 17 00:00:00 2001 From: Shu-Chun Weng Date: Mon, 19 Aug 2019 11:09:47 -0700 Subject: [PATCH 05/15] linux-user: add memfd_create Add support for the memfd_create syscall. If the host does not have the libc wrapper, translate to a direct syscall with NC-macro. Buglink: https://bugs.launchpad.net/qemu/+bug/1734792 Signed-off-by: Shu-Chun Weng Reviewed-by: Laurent Vivier Message-Id: <20190819180947.180725-1-scw@google.com> Signed-off-by: Laurent Vivier --- include/qemu/memfd.h | 4 ++++ linux-user/syscall.c | 12 ++++++++++++ util/memfd.c | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/qemu/memfd.h b/include/qemu/memfd.h index d551c28b68..975b6bdb77 100644 --- a/include/qemu/memfd.h +++ b/include/qemu/memfd.h @@ -32,6 +32,10 @@ #define MFD_HUGE_SHIFT 26 #endif +#if defined CONFIG_LINUX && !defined CONFIG_MEMFD +int memfd_create(const char *name, unsigned int flags); +#endif + int qemu_memfd_create(const char *name, size_t size, bool hugetlb, uint64_t hugetlbsize, unsigned int seals, Error **errp); bool qemu_memfd_alloc_check(void); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index b42f59a32c..6928f654ce 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "qemu/cutils.h" #include "qemu/path.h" +#include "qemu/memfd.h" #include "qemu/queue.h" #include #include @@ -11938,6 +11939,17 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, /* PowerPC specific. */ return do_swapcontext(cpu_env, arg1, arg2, arg3); #endif +#ifdef TARGET_NR_memfd_create + case TARGET_NR_memfd_create: + p = lock_user_string(arg1); + if (!p) { + return -TARGET_EFAULT; + } + ret = get_errno(memfd_create(p, arg2)); + fd_trans_unregister(ret); + unlock_user(p, arg1, 0); + return ret; +#endif default: qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num); diff --git a/util/memfd.c b/util/memfd.c index 00334e5b21..4a3c07e0be 100644 --- a/util/memfd.c +++ b/util/memfd.c @@ -35,7 +35,7 @@ #include #include -static int memfd_create(const char *name, unsigned int flags) +int memfd_create(const char *name, unsigned int flags) { #ifdef __NR_memfd_create return syscall(__NR_memfd_create, name, flags); From 8f67b9c694d01e3468e73d632324cd52a129a38b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 22 Aug 2019 11:59:28 -0700 Subject: [PATCH 06/15] linux-user: Pass CPUState to MAX_RESERVED_VA Turn the scalar macro into a functional macro. Move the creation of the cpu up a bit within main() so that we can pass it to the invocation of MAX_RESERVED_VA. Delay the validation of the -R parameter until MAX_RESERVED_VA is computed. So far no changes to any of the MAX_RESERVED_VA macros to actually use the cpu in any way, but ARM will need it. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-Id: <20190822185929.16891-2-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/arm/target_cpu.h | 2 +- linux-user/main.c | 43 +++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h index 8a3764919a..279ea532d5 100644 --- a/linux-user/arm/target_cpu.h +++ b/linux-user/arm/target_cpu.h @@ -21,7 +21,7 @@ /* We need to be able to map the commpage. See validate_guest_space in linux-user/elfload.c. */ -#define MAX_RESERVED_VA 0xffff0000ul +#define MAX_RESERVED_VA(CPU) 0xffff0000ul static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp) { diff --git a/linux-user/main.c b/linux-user/main.c index c257b063db..24cb24f0bf 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -77,12 +77,12 @@ int have_guest_base; (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32)) /* There are a number of places where we assign reserved_va to a variable of type abi_ulong and expect it to fit. Avoid the last page. */ -# define MAX_RESERVED_VA (0xfffffffful & TARGET_PAGE_MASK) +# define MAX_RESERVED_VA(CPU) (0xfffffffful & TARGET_PAGE_MASK) # else -# define MAX_RESERVED_VA (1ul << TARGET_VIRT_ADDR_SPACE_BITS) +# define MAX_RESERVED_VA(CPU) (1ul << TARGET_VIRT_ADDR_SPACE_BITS) # endif # else -# define MAX_RESERVED_VA 0 +# define MAX_RESERVED_VA(CPU) 0 # endif #endif @@ -356,8 +356,7 @@ static void handle_arg_reserved_va(const char *arg) unsigned long unshifted = reserved_va; p++; reserved_va <<= shift; - if (reserved_va >> shift != unshifted - || (MAX_RESERVED_VA && reserved_va > MAX_RESERVED_VA)) { + if (reserved_va >> shift != unshifted) { fprintf(stderr, "Reserved virtual address too big\n"); exit(EXIT_FAILURE); } @@ -605,6 +604,7 @@ int main(int argc, char **argv, char **envp) int i; int ret; int execfd; + unsigned long max_reserved_va; error_init(argv[0]); module_call_init(MODULE_INIT_TRACE); @@ -670,24 +670,31 @@ int main(int argc, char **argv, char **envp) /* init tcg before creating CPUs and to get qemu_host_page_size */ tcg_exec_init(0); - /* Reserving *too* much vm space via mmap can run into problems - with rlimits, oom due to page table creation, etc. We will still try it, - if directed by the command-line option, but not by default. */ - if (HOST_LONG_BITS == 64 && - TARGET_VIRT_ADDR_SPACE_BITS <= 32 && - reserved_va == 0) { - /* reserved_va must be aligned with the host page size - * as it is used with mmap() - */ - reserved_va = MAX_RESERVED_VA & qemu_host_page_mask; - } - cpu = cpu_create(cpu_type); env = cpu->env_ptr; cpu_reset(cpu); - thread_cpu = cpu; + /* + * Reserving too much vm space via mmap can run into problems + * with rlimits, oom due to page table creation, etc. We will + * still try it, if directed by the command-line option, but + * not by default. + */ + max_reserved_va = MAX_RESERVED_VA(cpu); + if (reserved_va != 0) { + if (max_reserved_va && reserved_va > max_reserved_va) { + fprintf(stderr, "Reserved virtual address too big\n"); + exit(EXIT_FAILURE); + } + } else if (HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32) { + /* + * reserved_va must be aligned with the host page size + * as it is used with mmap() + */ + reserved_va = max_reserved_va & qemu_host_page_mask; + } + if (getenv("QEMU_STRACE")) { do_strace = 1; } From 0b689da375a689efe04ad8381f607d1292471d96 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 22 Aug 2019 11:59:29 -0700 Subject: [PATCH 07/15] linux-user/arm: Adjust MAX_RESERVED_VA for M-profile Limit the virtual address space for M-profile cpus to 2GB, so that we avoid all of the magic addresses in the top half of the M-profile system map. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-Id: <20190822185929.16891-3-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/arm/target_cpu.h | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h index 279ea532d5..3f79356a07 100644 --- a/linux-user/arm/target_cpu.h +++ b/linux-user/arm/target_cpu.h @@ -19,9 +19,27 @@ #ifndef ARM_TARGET_CPU_H #define ARM_TARGET_CPU_H -/* We need to be able to map the commpage. - See validate_guest_space in linux-user/elfload.c. */ -#define MAX_RESERVED_VA(CPU) 0xffff0000ul +static inline unsigned long arm_max_reserved_va(CPUState *cs) +{ + ARMCPU *cpu = ARM_CPU(cs); + + if (arm_feature(&cpu->env, ARM_FEATURE_M)) { + /* + * There are magic return addresses above 0xfe000000, + * and in general a lot of M-profile system stuff in + * the high addresses. Restrict linux-user to the + * cached write-back RAM in the system map. + */ + return 0x80000000ul; + } else { + /* + * We need to be able to map the commpage. + * See validate_guest_space in linux-user/elfload.c. + */ + return 0xffff0000ul; + } +} +#define MAX_RESERVED_VA arm_max_reserved_va static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp) { From dc12567a53c88d7a91b9d71db3775782c7f35c84 Mon Sep 17 00:00:00 2001 From: Josh Kunz Date: Fri, 16 Aug 2019 16:34:22 -0700 Subject: [PATCH 08/15] linux-user: Support gdb 'qOffsets' query for ELF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed to support debugging PIE ELF binaries running under QEMU user mode. Currently, `code_offset` and `data_offset` remain unset for all ELF binaries, so GDB is unable to correctly locate the position of the binary's text and data. The fields `code_offset`, and `data_offset` were originally added way back in 2006 to support debugging of bFMT executables (978efd6aac6), and support was just never added for ELF. Since non-PIE binaries are loaded at exactly the address specified in the binary, GDB does not need to relocate any symbols, so the buggy behavior is not normally observed. http://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qOffsets-packet Buglink: https://bugs.launchpad.net/qemu/+bug/1528239 Signed-off-by: Josh Kunz Reviewed-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20190816233422.16715-1-jkz@google.com> [lv: added link to documentation] Signed-off-by: Laurent Vivier --- linux-user/elfload.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 43c16a846d..f6693e5760 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2403,6 +2403,8 @@ static void load_elf_image(const char *image_name, int image_fd, } info->load_bias = load_bias; + info->code_offset = load_bias; + info->data_offset = load_bias; info->load_addr = load_addr; info->entry = ehdr->e_entry + load_bias; info->start_code = -1; From 130ea8322bd01b27095079632f1946d9a2120870 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 6 Sep 2019 09:57:13 -0700 Subject: [PATCH 09/15] target/xtensa: linux-user: add call0 ABI support Xtensa binaries built for call0 ABI don't rotate register window on function calls and returns. Invocation of signal handlers from the kernel is therefore different in windowed and call0 ABIs. There's currently no way to determine xtensa ELF binary ABI from the binary itself. Add handler for the -xtensa-abi-call0 command line parameter/QEMU_XTENSA_ABI_CALL0 envitonment variable to the qemu-user and record ABI choice. Use it to initialize PS.WOE in xtensa_cpu_reset. Check PS.WOE in setup_rt_frame to determine how a signal should be delivered. Reviewed-by: Laurent Vivier Signed-off-by: Max Filippov Message-Id: <20190906165713.5558-1-jcmvbkbc@gmail.com> Signed-off-by: Laurent Vivier --- linux-user/main.c | 11 +++++++++++ linux-user/xtensa/signal.c | 25 +++++++++++++++++-------- target/xtensa/cpu.c | 24 ++++++++++++++++++++---- target/xtensa/cpu.h | 3 +++ 4 files changed, 51 insertions(+), 12 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 24cb24f0bf..27d9a87bc8 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -391,6 +391,13 @@ static void handle_arg_trace(const char *arg) trace_file = trace_opt_parse(arg); } +#if defined(TARGET_XTENSA) +static void handle_arg_abi_call0(const char *arg) +{ + xtensa_set_abi_call0(); +} +#endif + struct qemu_argument { const char *argv; const char *env; @@ -444,6 +451,10 @@ static const struct qemu_argument arg_table[] = { "", "[[enable=]][,events=][,file=]"}, {"version", "QEMU_VERSION", false, handle_arg_version, "", "display version information and exit"}, +#if defined(TARGET_XTENSA) + {"xtensa-abi-call0", "QEMU_XTENSA_ABI_CALL0", false, handle_arg_abi_call0, + "", "assume CALL0 Xtensa ABI"}, +#endif {NULL, NULL, false, NULL, NULL, NULL} }; diff --git a/linux-user/xtensa/signal.c b/linux-user/xtensa/signal.c index 8d54ef3ae3..590f0313ff 100644 --- a/linux-user/xtensa/signal.c +++ b/linux-user/xtensa/signal.c @@ -134,6 +134,8 @@ void setup_rt_frame(int sig, struct target_sigaction *ka, abi_ulong frame_addr; struct target_rt_sigframe *frame; uint32_t ra; + bool abi_call0; + unsigned base; int i; frame_addr = get_sigframe(ka, env, sizeof(*frame)); @@ -182,20 +184,27 @@ void setup_rt_frame(int sig, struct target_sigaction *ka, __put_user(0x00, &frame->retcode[5]); #endif } - env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT); - if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER)) { - env->sregs[PS] |= PS_WOE | (1 << PS_CALLINC_SHIFT); - } memset(env->regs, 0, sizeof(env->regs)); env->pc = ka->_sa_handler; env->regs[1] = frame_addr; env->sregs[WINDOW_BASE] = 0; env->sregs[WINDOW_START] = 1; - env->regs[4] = (ra & 0x3fffffff) | 0x40000000; - env->regs[6] = sig; - env->regs[7] = frame_addr + offsetof(struct target_rt_sigframe, info); - env->regs[8] = frame_addr + offsetof(struct target_rt_sigframe, uc); + abi_call0 = (env->sregs[PS] & PS_WOE) == 0; + env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT); + + if (abi_call0) { + base = 0; + env->regs[base] = ra; + } else { + env->sregs[PS] |= PS_WOE | (1 << PS_CALLINC_SHIFT); + base = 4; + env->regs[base] = (ra & 0x3fffffff) | 0x40000000; + } + env->regs[base + 2] = sig; + env->regs[base + 3] = frame_addr + offsetof(struct target_rt_sigframe, + info); + env->regs[base + 4] = frame_addr + offsetof(struct target_rt_sigframe, uc); unlock_user_struct(frame, frame_addr, 1); return; diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c index 76db1741a7..c65dcf9dd7 100644 --- a/target/xtensa/cpu.c +++ b/target/xtensa/cpu.c @@ -53,6 +53,20 @@ static bool xtensa_cpu_has_work(CPUState *cs) #endif } +#ifdef CONFIG_USER_ONLY +static bool abi_call0; + +void xtensa_set_abi_call0(void) +{ + abi_call0 = true; +} + +bool xtensa_abi_call0(void) +{ + return abi_call0; +} +#endif + /* CPUClass::reset() */ static void xtensa_cpu_reset(CPUState *s) { @@ -70,10 +84,12 @@ static void xtensa_cpu_reset(CPUState *s) XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10; env->pending_irq_level = 0; #else - env->sregs[PS] = - (xtensa_option_enabled(env->config, - XTENSA_OPTION_WINDOWED_REGISTER) ? PS_WOE : 0) | - PS_UM | (3 << PS_RING_SHIFT); + env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT); + if (xtensa_option_enabled(env->config, + XTENSA_OPTION_WINDOWED_REGISTER) && + !xtensa_abi_call0()) { + env->sregs[PS] |= PS_WOE; + } #endif env->sregs[VECBASE] = env->config->vecbase; env->sregs[IBREAKENABLE] = 0; diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index 0459243e6b..b363ffcf10 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -673,6 +673,9 @@ static inline MemoryRegion *xtensa_get_er_region(CPUXtensaState *env) { return env->system_er; } +#else +void xtensa_set_abi_call0(void); +bool xtensa_abi_call0(void); #endif static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env) From 1cc52740160e6b6762b1fafcd3a9fc0e498e45d0 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 6 Sep 2019 09:57:36 -0700 Subject: [PATCH 10/15] linux-user: drop redundant handling of environment variables QEMU_STRACE and QEMU_RAND_SEED are handled by the parse_args, no need to do it again in main. Signed-off-by: Max Filippov Reviewed-by: Laurent Vivier Message-Id: <20190906165736.5612-1-jcmvbkbc@gmail.com> Signed-off-by: Laurent Vivier --- linux-user/main.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 27d9a87bc8..560d053f72 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -706,13 +706,6 @@ int main(int argc, char **argv, char **envp) reserved_va = max_reserved_va & qemu_host_page_mask; } - if (getenv("QEMU_STRACE")) { - do_strace = 1; - } - - if (seed_optarg == NULL) { - seed_optarg = getenv("QEMU_RAND_SEED"); - } { Error *err = NULL; if (seed_optarg != NULL) { From 92c096f0aabc90380b82b5604e0ee73b38317e5c Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 4 Sep 2019 14:59:22 +0200 Subject: [PATCH 11/15] linux-user: Add support for RNDRESEEDCRNG ioctl RNDRESEEDCRNG is a newer ioctl (added in kernel 4.17), and an "ifdef" guard is used for that reason in this patch. Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Message-Id: <1567601968-26946-3-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 3 +++ linux-user/syscall_defs.h | 1 + 2 files changed, 4 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 3281c97ca2..cd9b6f9a8d 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -246,6 +246,9 @@ IOCTL(RNDADDTOENTCNT, IOC_W, MK_PTR(TYPE_INT)) IOCTL(RNDZAPENTCNT, 0, TYPE_NULL) IOCTL(RNDCLEARPOOL, 0, TYPE_NULL) +#ifdef RNDRESEEDCRNG + IOCTL(RNDRESEEDCRNG, 0, TYPE_NULL) +#endif IOCTL(CDROMPAUSE, 0, TYPE_NULL) IOCTL(CDROMSTART, 0, TYPE_NULL) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 0662270300..19a1d39cbc 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -850,6 +850,7 @@ struct target_pollfd { #define TARGET_RNDADDTOENTCNT TARGET_IOW('R', 0x01, int) #define TARGET_RNDZAPENTCNT TARGET_IO('R', 0x04) #define TARGET_RNDCLEARPOOL TARGET_IO('R', 0x06) +#define TARGET_RNDRESEEDCRNG TARGET_IO('R', 0x07) /* From */ From 4e4b173fa1661537bd94da9f9cea364dcbe6b2f5 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 4 Sep 2019 14:59:23 +0200 Subject: [PATCH 12/15] linux-user: Add support for FIOGETOWN and FIOSETOWN ioctls FIOGETOWN and FIOSETOWN ioctls have platform-specific definitions, hence non-standard definition in QEMU too. Other than that, they both have a single integer argument, and their functionality is emulated in a straightforward way. Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Message-Id: <1567601968-26946-4-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 2 ++ linux-user/syscall_defs.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index cd9b6f9a8d..1830de96e1 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -177,6 +177,8 @@ #endif #endif /* CONFIG_USBFS */ + IOCTL(FIOGETOWN, IOC_R, MK_PTR(TYPE_INT)) + IOCTL(FIOSETOWN, IOC_W, MK_PTR(TYPE_INT)) IOCTL(SIOCATMARK, IOC_R, MK_PTR(TYPE_INT)) IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_int_ifreq))) IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq))) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 19a1d39cbc..498223b777 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -758,10 +758,14 @@ struct target_pollfd { #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4) || \ defined(TARGET_XTENSA) +#define TARGET_FIOGETOWN TARGET_IOR('f', 123, int) +#define TARGET_FIOSETOWN TARGET_IOW('f', 124, int) #define TARGET_SIOCATMARK TARGET_IOR('s', 7, int) #define TARGET_SIOCSPGRP TARGET_IOW('s', 8, pid_t) #define TARGET_SIOCGPGRP TARGET_IOR('s', 9, pid_t) #else +#define TARGET_FIOGETOWN 0x8903 +#define TARGET_FIOSETOWN 0x8901 #define TARGET_SIOCATMARK 0x8905 #define TARGET_SIOCSPGRP 0x8902 #define TARGET_SIOCGPGRP 0x8904 From ab22b4dd749f5769e72eaf4dd368072196ef29af Mon Sep 17 00:00:00 2001 From: Yunqiang Su Date: Wed, 4 Sep 2019 14:59:24 +0200 Subject: [PATCH 13/15] linux-user: Add support for FDFLUSH ioctl FDFLUSH is used for flushing buffers of floppy drives. Support in QEMU is needed because some of Debian packages use this ioctl while running post-build tests. One such example is 'tar' package. Signed-off-by: Yunqiang Su Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Message-Id: <1567601968-26946-5-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 2 ++ linux-user/syscall.c | 1 + linux-user/syscall_defs.h | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 1830de96e1..bc19448042 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -112,6 +112,8 @@ IOCTL(BLKZEROOUT, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2))) #endif + IOCTL(FDFLUSH, 0, TYPE_NULL) + #ifdef FIBMAP IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG)) #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 6928f654ce..e2af3c1494 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -89,6 +89,7 @@ #include #include #include +#include #if defined(CONFIG_FIEMAP) #include #endif diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 498223b777..917202a203 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -888,6 +888,10 @@ struct target_pollfd { #define TARGET_BLKROTATIONAL TARGET_IO(0x12, 126) #define TARGET_BLKZEROOUT TARGET_IO(0x12, 127) +/* From */ + +#define TARGET_FDFLUSH TARGET_IO(2, 0x4b) + #define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */ #define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */ From 7e35fc8b1e59ea5189a6de63a6cab9d06d00d2be Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 4 Sep 2019 14:59:25 +0200 Subject: [PATCH 14/15] linux-user: Add support for FDMSGON and FDMSGOFF ioctls FDMSGON and FDMSGOFF switch informational messages of floppy drives on and off. Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Reviewed-by: Laurent Vivier Message-Id: <1567601968-26946-6-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 2 ++ linux-user/syscall_defs.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index bc19448042..b253469999 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -112,6 +112,8 @@ IOCTL(BLKZEROOUT, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2))) #endif + IOCTL(FDMSGON, 0, TYPE_NULL) + IOCTL(FDMSGOFF, 0, TYPE_NULL) IOCTL(FDFLUSH, 0, TYPE_NULL) #ifdef FIBMAP diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 917202a203..4e33ef396b 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -890,6 +890,8 @@ struct target_pollfd { /* From */ +#define TARGET_FDMSGON TARGET_IO(2, 0x45) +#define TARGET_FDMSGOFF TARGET_IO(2, 0x46) #define TARGET_FDFLUSH TARGET_IO(2, 0x4b) #define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */ From 5eea942900536b76ad13bef35e1d8f276566ae9e Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 4 Sep 2019 14:59:26 +0200 Subject: [PATCH 15/15] linux-user: Add support for FDRESET, FDRAWCMD, FDTWADDLE, and FDEJECT ioctls FDRESET, FDRAWCMD, FDTWADDLE, and FDEJECT ioctls are misc commands for controlling a floppy drive. Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Message-Id: <1567601968-26946-7-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 4 ++++ linux-user/syscall_defs.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index b253469999..c6b9d6ad66 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -115,6 +115,10 @@ IOCTL(FDMSGON, 0, TYPE_NULL) IOCTL(FDMSGOFF, 0, TYPE_NULL) IOCTL(FDFLUSH, 0, TYPE_NULL) + IOCTL(FDRESET, 0, TYPE_NULL) + IOCTL(FDRAWCMD, 0, TYPE_NULL) + IOCTL(FDTWADDLE, 0, TYPE_NULL) + IOCTL(FDEJECT, 0, TYPE_NULL) #ifdef FIBMAP IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG)) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 4e33ef396b..fa69c6ab8d 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -893,6 +893,10 @@ struct target_pollfd { #define TARGET_FDMSGON TARGET_IO(2, 0x45) #define TARGET_FDMSGOFF TARGET_IO(2, 0x46) #define TARGET_FDFLUSH TARGET_IO(2, 0x4b) +#define TARGET_FDRESET TARGET_IO(2, 0x54) +#define TARGET_FDRAWCMD TARGET_IO(2, 0x58) +#define TARGET_FDTWADDLE TARGET_IO(2, 0x59) +#define TARGET_FDEJECT TARGET_IO(2, 0x5a) #define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */ #define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */