Linux-user updates for Qemu 2.11

-----BEGIN PGP SIGNATURE-----
 
 iQJLBAABCAA1FiEE/4IDyMORmK4FgUHvtEiQ3t48m8AFAlnnRv4XHHJpa3Uudm9p
 cGlvQGxpbmFyby5vcmcACgkQtEiQ3t48m8D1hw/8Cu/gXcWzHPxoqU/Bz9lSMS0+
 1UICiGBVNBcrs7QapG+Z4mI4goGcxjFKFEFgHuuvQTb91ONR43jIx4cNryOlu3jS
 9njiHkgY7EeKXf84uPToie9WiXvf2IMI6wKdqJ53htJ8/Y1putbJ2CGf7c8vGIGh
 9WhNGbiQyhpWU3xrEThVptUz+CVOqXxBYVKff0krG7ZSyODhrybPDkp8D020rXa1
 O7oc8pAvwpYWiqpp+iiEU5PXFB7DoLUldefqqZQw+Rgntu6sEU+Rum7ykA2d6jBR
 o0YldbJeU2eq2Kh9EqJHDbTZwevTeul6NEcgd6ZoJkTDhOSDK9mMd6jkkRUHzf+u
 OAlGFFmfdqf9NE5S38XIMRHykwgMtWzQNU2MVLtalkEcadbOy7RnY/lOE/uEACh4
 Ao/GPMDCar7nYR2Ga/P9LXFhR90hbvvvRAB10l7TIgE6/EJJUJs9E0HxC5ktsonv
 gC4tMTejhCwe61Neb0Z9b2gxSkwznJYe9OdTa13CENXMAy3AqPUTsDY91Y80HdpX
 3rE869VSHMIQNuyNecCrUeHyKYkLoB+qGmavtO7m1RNEUeWTPP2WSDMCVKxVT4bg
 ol0UeTOwy0hGm2MUwn3scL+yMEVWjcEyInWDZCCGIvJMxfnwkqAMTO0xZXAIE8n0
 bBHdQ4xVsujMIDmQcO0=
 =9fWY
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20171018' into staging

Linux-user updates for Qemu 2.11

# gpg: Signature made Wed 18 Oct 2017 13:20:14 BST
# gpg:                using RSA key 0xB44890DEDE3C9BC0
# gpg: Good signature from "Riku Voipio <riku.voipio@iki.fi>"
# gpg:                 aka "Riku Voipio <riku.voipio@linaro.org>"
# Primary key fingerprint: FF82 03C8 C391 98AE 0581  41EF B448 90DE DE3C 9BC0

* remotes/riku/tags/pull-linux-user-20171018:
  linux-user: Fix TARGET_MTIOCTOP/MTIOCGET/MTIOCPOS values
  linux-user/main: support dfilter
  linux-user: Fix target FS_IOC_GETFLAGS and FS_IOC_SETFLAGS numbers
  linux-user/sh4: Reduce TARGET_VIRT_ADDR_SPACE_BITS to 31
  linux-user: Tidy and enforce reserved_va initialization
  tcg: Fix off-by-one in assert in page_set_flags
  linux-user: Allow -R values up to 0xffff0000 for 32-bit ARM guests
  linux-user: remove duplicate break in syscall
  target/m68k,linux-user: manage FP registers in ucontext
  linux-user: fix O_TMPFILE handling

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-10-19 14:39:30 +01:00
commit f2a48d696c
11 changed files with 140 additions and 24 deletions

View File

@ -2114,7 +2114,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
guest address space. If this assert fires, it probably indicates guest address space. If this assert fires, it probably indicates
a missing call to h2g_valid. */ a missing call to h2g_valid. */
#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS #if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
assert(end < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS)); assert(end <= ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
#endif #endif
assert(start < end); assert(start < end);
assert_memory_lock(); assert_memory_lock();

View File

@ -19,6 +19,10 @@
#ifndef ARM_TARGET_CPU_H #ifndef ARM_TARGET_CPU_H
#define 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 0xffff0000ul
static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp) static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
{ {
if (newsp) { if (newsp) {

View File

@ -377,7 +377,7 @@ static int validate_guest_space(unsigned long guest_base,
* then there is no way we can allocate it. * then there is no way we can allocate it.
*/ */
if (test_page_addr >= guest_base if (test_page_addr >= guest_base
&& test_page_addr <= (guest_base + guest_size)) { && test_page_addr < (guest_base + guest_size)) {
return -1; return -1;
} }

View File

@ -60,23 +60,38 @@ do { \
} \ } \
} while (0) } while (0)
#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
/* /*
* When running 32-on-64 we should make sure we can fit all of the possible * When running 32-on-64 we should make sure we can fit all of the possible
* guest address space into a contiguous chunk of virtual host memory. * guest address space into a contiguous chunk of virtual host memory.
* *
* This way we will never overlap with our own libraries or binaries or stack * This way we will never overlap with our own libraries or binaries or stack
* or anything else that QEMU maps. * or anything else that QEMU maps.
*
* Many cpus reserve the high bit (or more than one for some 64-bit cpus)
* of the address for the kernel. Some cpus rely on this and user space
* uses the high bit(s) for pointer tagging and the like. For them, we
* must preserve the expected address space.
*/ */
# if defined(TARGET_MIPS) || defined(TARGET_NIOS2) #ifndef MAX_RESERVED_VA
/* # if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
* MIPS only supports 31 bits of virtual address space for user space. # if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
* Nios2 also only supports 31 bits. (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
*/ /* There are a number of places where we assign reserved_va to a variable
unsigned long reserved_va = 0x77000000; of type abi_ulong and expect it to fit. Avoid the last page. */
# define MAX_RESERVED_VA (0xfffffffful & TARGET_PAGE_MASK)
# else
# define MAX_RESERVED_VA (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
# endif
# else # else
unsigned long reserved_va = 0xf7000000; # define MAX_RESERVED_VA 0
# endif # endif
#endif
/* That said, 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
unsigned long reserved_va = MAX_RESERVED_VA;
#else #else
unsigned long reserved_va; unsigned long reserved_va;
#endif #endif
@ -3854,6 +3869,11 @@ static void handle_arg_log(const char *arg)
qemu_set_log(mask); qemu_set_log(mask);
} }
static void handle_arg_dfilter(const char *arg)
{
qemu_set_dfilter_ranges(arg, NULL);
}
static void handle_arg_log_filename(const char *arg) static void handle_arg_log_filename(const char *arg)
{ {
qemu_set_log_filename(arg, &error_fatal); qemu_set_log_filename(arg, &error_fatal);
@ -3978,11 +3998,8 @@ static void handle_arg_reserved_va(const char *arg)
unsigned long unshifted = reserved_va; unsigned long unshifted = reserved_va;
p++; p++;
reserved_va <<= shift; reserved_va <<= shift;
if (((reserved_va >> shift) != unshifted) if (reserved_va >> shift != unshifted
#if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS || (MAX_RESERVED_VA && reserved_va > MAX_RESERVED_VA)) {
|| (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS))
#endif
) {
fprintf(stderr, "Reserved virtual address too big\n"); fprintf(stderr, "Reserved virtual address too big\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -4054,6 +4071,8 @@ static const struct qemu_argument arg_table[] = {
{"d", "QEMU_LOG", true, handle_arg_log, {"d", "QEMU_LOG", true, handle_arg_log,
"item[,...]", "enable logging of specified items " "item[,...]", "enable logging of specified items "
"(use '-d help' for a list of items)"}, "(use '-d help' for a list of items)"},
{"dfilter", "QEMU_DFILTER", true, handle_arg_dfilter,
"range[,...]","filter logging based on address range"},
{"D", "QEMU_LOG_FILENAME", true, handle_arg_log_filename, {"D", "QEMU_LOG_FILENAME", true, handle_arg_log_filename,
"logfile", "write logs to 'logfile' (default stderr)"}, "logfile", "write logs to 'logfile' (default stderr)"},
{"p", "QEMU_PAGESIZE", true, handle_arg_pagesize, {"p", "QEMU_PAGESIZE", true, handle_arg_pagesize,

View File

@ -5704,6 +5704,24 @@ give_sigsegv:
force_sigsegv(sig); force_sigsegv(sig);
} }
static inline void target_rt_save_fpu_state(struct target_ucontext *uc,
CPUM68KState *env)
{
int i;
target_fpregset_t *fpregs = &uc->tuc_mcontext.fpregs;
__put_user(env->fpcr, &fpregs->f_fpcntl[0]);
__put_user(env->fpsr, &fpregs->f_fpcntl[1]);
/* fpiar is not emulated */
for (i = 0; i < 8; i++) {
uint32_t high = env->fregs[i].d.high << 16;
__put_user(high, &fpregs->f_fpregs[i * 3]);
__put_user(env->fregs[i].d.low,
(uint64_t *)&fpregs->f_fpregs[i * 3 + 1]);
}
}
static inline int target_rt_setup_ucontext(struct target_ucontext *uc, static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
CPUM68KState *env) CPUM68KState *env)
{ {
@ -5730,9 +5748,32 @@ static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
__put_user(env->pc, &gregs[16]); __put_user(env->pc, &gregs[16]);
__put_user(sr, &gregs[17]); __put_user(sr, &gregs[17]);
target_rt_save_fpu_state(uc, env);
return 0; return 0;
} }
static inline void target_rt_restore_fpu_state(CPUM68KState *env,
struct target_ucontext *uc)
{
int i;
target_fpregset_t *fpregs = &uc->tuc_mcontext.fpregs;
uint32_t fpcr;
__get_user(fpcr, &fpregs->f_fpcntl[0]);
cpu_m68k_set_fpcr(env, fpcr);
__get_user(env->fpsr, &fpregs->f_fpcntl[1]);
/* fpiar is not emulated */
for (i = 0; i < 8; i++) {
uint32_t high;
__get_user(high, &fpregs->f_fpregs[i * 3]);
env->fregs[i].d.high = high >> 16;
__get_user(env->fregs[i].d.low,
(uint64_t *)&fpregs->f_fpregs[i * 3 + 1]);
}
}
static inline int target_rt_restore_ucontext(CPUM68KState *env, static inline int target_rt_restore_ucontext(CPUM68KState *env,
struct target_ucontext *uc) struct target_ucontext *uc)
{ {
@ -5764,6 +5805,8 @@ static inline int target_rt_restore_ucontext(CPUM68KState *env,
__get_user(temp, &gregs[17]); __get_user(temp, &gregs[17]);
cpu_m68k_set_ccr(env, temp); cpu_m68k_set_ccr(env, temp);
target_rt_restore_fpu_state(env, uc);
return 0; return 0;
badframe: badframe:

View File

@ -837,6 +837,10 @@ UNUSED static struct flags open_flags[] = {
#endif #endif
#ifdef O_PATH #ifdef O_PATH
FLAG_TARGET(O_PATH), FLAG_TARGET(O_PATH),
#endif
#ifdef O_TMPFILE
FLAG_TARGET(O_TMPFILE),
FLAG_TARGET(__O_TMPFILE),
#endif #endif
FLAG_END, FLAG_END,
}; };

View File

@ -342,6 +342,9 @@ static bitmask_transtbl fcntl_flags_tbl[] = {
#endif #endif
#if defined(O_PATH) #if defined(O_PATH)
{ TARGET_O_PATH, TARGET_O_PATH, O_PATH, O_PATH }, { TARGET_O_PATH, TARGET_O_PATH, O_PATH, O_PATH },
#endif
#if defined(O_TMPFILE)
{ TARGET_O_TMPFILE, TARGET_O_TMPFILE, O_TMPFILE, O_TMPFILE },
#endif #endif
/* Don't terminate the list prematurely on 64-bit host+guest. */ /* Don't terminate the list prematurely on 64-bit host+guest. */
#if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0 #if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0

View File

@ -1108,8 +1108,8 @@ struct target_pollfd {
/* Note that the ioctl numbers claim type "long" but the actual type /* Note that the ioctl numbers claim type "long" but the actual type
* used by the kernel is "int". * used by the kernel is "int".
*/ */
#define TARGET_FS_IOC_GETFLAGS TARGET_IOR('f', 1, long) #define TARGET_FS_IOC_GETFLAGS TARGET_IOR('f', 1, abi_long)
#define TARGET_FS_IOC_SETFLAGS TARGET_IOW('f', 2, long) #define TARGET_FS_IOC_SETFLAGS TARGET_IOW('f', 2, abi_long)
#define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap) #define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
@ -2423,7 +2423,7 @@ struct target_statfs64 {
#define TARGET_O_CLOEXEC 010000000 #define TARGET_O_CLOEXEC 010000000
#define TARGET___O_SYNC 000100000 #define TARGET___O_SYNC 000100000
#define TARGET_O_PATH 020000000 #define TARGET_O_PATH 020000000
#elif defined(TARGET_ARM) || defined(TARGET_M68K) #elif defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_AARCH64)
#define TARGET_O_DIRECTORY 040000 /* must be a directory */ #define TARGET_O_DIRECTORY 040000 /* must be a directory */
#define TARGET_O_NOFOLLOW 0100000 /* don't follow links */ #define TARGET_O_NOFOLLOW 0100000 /* don't follow links */
#define TARGET_O_DIRECT 0200000 /* direct disk access hint */ #define TARGET_O_DIRECT 0200000 /* direct disk access hint */
@ -2520,6 +2520,12 @@ struct target_statfs64 {
#ifndef TARGET_O_PATH #ifndef TARGET_O_PATH
#define TARGET_O_PATH 010000000 #define TARGET_O_PATH 010000000
#endif #endif
#ifndef TARGET___O_TMPFILE
#define TARGET___O_TMPFILE 020000000
#endif
#ifndef TARGET_O_TMPFILE
#define TARGET_O_TMPFILE (TARGET___O_TMPFILE | TARGET_O_DIRECTORY)
#endif
#ifndef TARGET_O_NDELAY #ifndef TARGET_O_NDELAY
#define TARGET_O_NDELAY TARGET_O_NONBLOCK #define TARGET_O_NDELAY TARGET_O_NONBLOCK
#endif #endif
@ -2713,9 +2719,34 @@ struct target_f_owner_ex {
#define TARGET_VFAT_IOCTL_READDIR_BOTH TARGET_IORU('r', 1) #define TARGET_VFAT_IOCTL_READDIR_BOTH TARGET_IORU('r', 1)
#define TARGET_VFAT_IOCTL_READDIR_SHORT TARGET_IORU('r', 2) #define TARGET_VFAT_IOCTL_READDIR_SHORT TARGET_IORU('r', 2)
#define TARGET_MTIOCTOP TARGET_IOW('m', 1, struct mtop) struct target_mtop {
#define TARGET_MTIOCGET TARGET_IOR('m', 2, struct mtget) abi_short mt_op;
#define TARGET_MTIOCPOS TARGET_IOR('m', 3, struct mtpos) abi_int mt_count;
};
#if defined(TARGET_SPARC) || defined(TARGET_MIPS)
typedef abi_long target_kernel_daddr_t;
#else
typedef abi_int target_kernel_daddr_t;
#endif
struct target_mtget {
abi_long mt_type;
abi_long mt_resid;
abi_long mt_dsreg;
abi_long mt_gstat;
abi_long mt_erreg;
target_kernel_daddr_t mt_fileno;
target_kernel_daddr_t mt_blkno;
};
struct target_mtpos {
abi_long mt_blkno;
};
#define TARGET_MTIOCTOP TARGET_IOW('m', 1, struct target_mtop)
#define TARGET_MTIOCGET TARGET_IOR('m', 2, struct target_mtget)
#define TARGET_MTIOCPOS TARGET_IOR('m', 3, struct target_mtpos)
struct target_sysinfo { struct target_sysinfo {
abi_long uptime; /* Seconds since boot */ abi_long uptime; /* Seconds since boot */

View File

@ -15,7 +15,11 @@
#else #else
#define TARGET_LONG_BITS 32 #define TARGET_LONG_BITS 32
#define TARGET_PHYS_ADDR_SPACE_BITS 40 #define TARGET_PHYS_ADDR_SPACE_BITS 40
#define TARGET_VIRT_ADDR_SPACE_BITS 32 # ifdef CONFIG_USER_ONLY
# define TARGET_VIRT_ADDR_SPACE_BITS 31
# else
# define TARGET_VIRT_ADDR_SPACE_BITS 32
#endif
#endif #endif
/* Masks used to mark instructions to indicate which ISA level they /* Masks used to mark instructions to indicate which ISA level they

View File

@ -226,7 +226,11 @@ qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu);
void nios2_check_interrupts(CPUNios2State *env); void nios2_check_interrupts(CPUNios2State *env);
#define TARGET_PHYS_ADDR_SPACE_BITS 32 #define TARGET_PHYS_ADDR_SPACE_BITS 32
#define TARGET_VIRT_ADDR_SPACE_BITS 32 #ifdef CONFIG_USER_ONLY
# define TARGET_VIRT_ADDR_SPACE_BITS 31
#else
# define TARGET_VIRT_ADDR_SPACE_BITS 32
#endif
#define cpu_init(cpu_model) cpu_generic_init(TYPE_NIOS2_CPU, cpu_model) #define cpu_init(cpu_model) cpu_generic_init(TYPE_NIOS2_CPU, cpu_model)

View File

@ -45,7 +45,11 @@
#define TARGET_PAGE_BITS 12 /* 4k XXXXX */ #define TARGET_PAGE_BITS 12 /* 4k XXXXX */
#define TARGET_PHYS_ADDR_SPACE_BITS 32 #define TARGET_PHYS_ADDR_SPACE_BITS 32
#define TARGET_VIRT_ADDR_SPACE_BITS 32 #ifdef CONFIG_USER_ONLY
# define TARGET_VIRT_ADDR_SPACE_BITS 31
#else
# define TARGET_VIRT_ADDR_SPACE_BITS 32
#endif
#define SR_MD 30 #define SR_MD 30
#define SR_RB 29 #define SR_RB 29