linux-user pull for 2.2

Clearest linux-user patches sent to the list since august,
 Apart from Mikhails patch, the rest are quite trivial.
 
 v2: check for CONFIG_TIMERFD only after it has been defined
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIVAwUAVDLomrRIkN7ePJvAAQgtXQ//Tw/Mkt9TyihjyVlH4Surl/Zt4Z3WkJU0
 /OLfSFXlKatflFfkmIiluPwXiPFfTLnn6mDTDRHU5fDlfHW41t5CPVpg/yM610La
 azRMRc6xZZdphdxrwhYd3SgU1hIihsyRnptpbCUSMYXGUFo7/xW1rPPgABCmqo4Q
 wZmayyhpIQkYqqf5ExbTSLEuI9r0xsLOWI4M1p1DkqlSq56dA/RvUq6lcd65bZlz
 nyvAMEiMzkOoVoQgt7o4gou0TlT+8mf1hpcYMIfz5hc0hcNkwnWGJsKloSGi9j57
 Ym0zSZ44t1WVXZ7ygbDgXdP3t2XpeyTj7l4yaDqrZ54oL4viI9X0039X4FwlZ24k
 EXO+IPgpyUOSHLmiEV6vwEP1xOOe5QaPXmuFq591i3tbp1jFq+ul70V6rr+880xy
 K16O5FiTgUVJ2SwPBWGnF1kHoGTI/UCBnFCI2N1x0g/j4AJiK2xVkQkwtfmolIgS
 A1KwO0oUQhv9gZ36vTEdyyLy2WAs1PkKxL5XRGxV/A1l8p7/pyrr9LMKI42ibdh6
 WsHP5blkgy11W97ujX5at+Is3sjB41xKOZV7STcKDy27LEeUvVPF2lw2keItnLQi
 HyzO0AaXZzmT7RmjWKDuF5RbsSWTQuT2jws5u+3fgGmILYOD77dsgevarLg9tamb
 Us6CQ7DvvfA=
 =rZir
 -----END PGP SIGNATURE-----

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

linux-user pull for 2.2

Clearest linux-user patches sent to the list since august,
Apart from Mikhails patch, the rest are quite trivial.

v2: check for CONFIG_TIMERFD only after it has been defined

# gpg: Signature made Mon 06 Oct 2014 20:08:10 BST using RSA key ID DE3C9BC0
# gpg: Good signature from "Riku Voipio <riku.voipio@iki.fi>"
# gpg:                 aka "Riku Voipio <riku.voipio@linaro.org>"

* remotes/riku/tags/pull-linux-user-20141006-2:
  translate-all.c: memory walker initial address miscalculation
  linux-user: don't include timerfd if not needed
  linux-user: Simplify timerid checks on g_posix_timers range
  linux-user: Convert blkpg to use a special subop handler
  linux-user: Enable epoll_pwait syscall for ARM

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-10-07 10:41:48 +01:00
commit b6011bd8a5
7 changed files with 104 additions and 45 deletions

View file

@ -232,8 +232,8 @@ extern uintptr_t qemu_host_page_mask;
#if defined(CONFIG_USER_ONLY)
void page_dump(FILE *f);
typedef int (*walk_memory_regions_fn)(void *, abi_ulong,
abi_ulong, unsigned long);
typedef int (*walk_memory_regions_fn)(void *, target_ulong,
target_ulong, unsigned long);
int walk_memory_regions(void *, walk_memory_regions_fn);
int page_get_flags(target_ulong address);

View file

@ -350,7 +350,7 @@
#define TARGET_NR_vmsplice (343)
#define TARGET_NR_move_pages (344)
#define TARGET_NR_getcpu (345)
/* 346 for epoll_pwait */
#define TARGET_NR_epoll_pwait (346)
#define TARGET_NR_kexec_load (347)
#define TARGET_NR_utimensat (348)
#define TARGET_NR_signalfd (349)

View file

@ -2355,9 +2355,9 @@ struct elf_note_info {
};
struct vm_area_struct {
abi_ulong vma_start; /* start vaddr of memory region */
abi_ulong vma_end; /* end vaddr of memory region */
abi_ulong vma_flags; /* protection etc. flags for the region */
target_ulong vma_start; /* start vaddr of memory region */
target_ulong vma_end; /* end vaddr of memory region */
abi_ulong vma_flags; /* protection etc. flags for the region */
QTAILQ_ENTRY(vm_area_struct) vma_link;
};
@ -2368,13 +2368,13 @@ struct mm_struct {
static struct mm_struct *vma_init(void);
static void vma_delete(struct mm_struct *);
static int vma_add_mapping(struct mm_struct *, abi_ulong,
abi_ulong, abi_ulong);
static int vma_add_mapping(struct mm_struct *, target_ulong,
target_ulong, abi_ulong);
static int vma_get_mapping_count(const struct mm_struct *);
static struct vm_area_struct *vma_first(const struct mm_struct *);
static struct vm_area_struct *vma_next(struct vm_area_struct *);
static abi_ulong vma_dump_size(const struct vm_area_struct *);
static int vma_walker(void *priv, abi_ulong start, abi_ulong end,
static int vma_walker(void *priv, target_ulong start, target_ulong end,
unsigned long flags);
static void fill_elf_header(struct elfhdr *, int, uint16_t, uint32_t);
@ -2466,8 +2466,8 @@ static void vma_delete(struct mm_struct *mm)
g_free(mm);
}
static int vma_add_mapping(struct mm_struct *mm, abi_ulong start,
abi_ulong end, abi_ulong flags)
static int vma_add_mapping(struct mm_struct *mm, target_ulong start,
target_ulong end, abi_ulong flags)
{
struct vm_area_struct *vma;
@ -2535,7 +2535,7 @@ static abi_ulong vma_dump_size(const struct vm_area_struct *vma)
return (vma->vma_end - vma->vma_start);
}
static int vma_walker(void *priv, abi_ulong start, abi_ulong end,
static int vma_walker(void *priv, target_ulong start, target_ulong end,
unsigned long flags)
{
struct mm_struct *mm = (struct mm_struct *)priv;

View file

@ -78,7 +78,8 @@
IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
IOCTL(BLKPG, IOC_W, MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
IOCTL_SPECIAL(BLKPG, IOC_W, do_ioctl_blkpg,
MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
#ifdef FIBMAP
IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
#endif

View file

@ -58,7 +58,6 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/statfs.h>
#include <sys/timerfd.h>
#include <utime.h>
#include <sys/sysinfo.h>
//#include <sys/user.h>
@ -67,6 +66,9 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <linux/wireless.h>
#include <linux/icmp.h>
#include "qemu-common.h"
#ifdef CONFIG_TIMERFD
#include <sys/timerfd.h>
#endif
#ifdef TARGET_GPROF
#include <sys/gmon.h>
#endif
@ -3696,6 +3698,59 @@ out:
return ret;
}
static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
abi_long cmd, abi_long arg)
{
void *argptr;
int target_size;
const argtype *arg_type = ie->arg_type;
const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) };
abi_long ret;
struct blkpg_ioctl_arg *host_blkpg = (void*)buf_temp;
struct blkpg_partition host_part;
/* Read and convert blkpg */
arg_type++;
target_size = thunk_type_size(arg_type, 0);
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
if (!argptr) {
ret = -TARGET_EFAULT;
goto out;
}
thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
unlock_user(argptr, arg, 0);
switch (host_blkpg->op) {
case BLKPG_ADD_PARTITION:
case BLKPG_DEL_PARTITION:
/* payload is struct blkpg_partition */
break;
default:
/* Unknown opcode */
ret = -TARGET_EINVAL;
goto out;
}
/* Read and convert blkpg->data */
arg = (abi_long)(uintptr_t)host_blkpg->data;
target_size = thunk_type_size(part_arg_type, 0);
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
if (!argptr) {
ret = -TARGET_EFAULT;
goto out;
}
thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST);
unlock_user(argptr, arg, 0);
/* Swizzle the data pointer to our local copy and call! */
host_blkpg->data = &host_part;
ret = get_errno(ioctl(fd, ie->host_cmd, host_blkpg));
out:
return ret;
}
static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
int fd, abi_long cmd, abi_long arg)
{
@ -9562,11 +9617,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
{
/* args: timer_t timerid, int flags, const struct itimerspec *new_value,
* struct itimerspec * old_value */
arg1 &= 0xffff;
if (arg3 == 0 || arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
target_ulong timerid = arg1;
if (arg3 == 0 || timerid >= ARRAY_SIZE(g_posix_timers)) {
ret = -TARGET_EINVAL;
} else {
timer_t htimer = g_posix_timers[arg1];
timer_t htimer = g_posix_timers[timerid];
struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
target_to_host_itimerspec(&hspec_new, arg3);
@ -9582,13 +9638,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_timer_gettime:
{
/* args: timer_t timerid, struct itimerspec *curr_value */
arg1 &= 0xffff;
target_ulong timerid = arg1;
if (!arg2) {
return -TARGET_EFAULT;
} else if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
} else if (timerid >= ARRAY_SIZE(g_posix_timers)) {
ret = -TARGET_EINVAL;
} else {
timer_t htimer = g_posix_timers[arg1];
timer_t htimer = g_posix_timers[timerid];
struct itimerspec hspec;
ret = get_errno(timer_gettime(htimer, &hspec));
@ -9604,11 +9661,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_timer_getoverrun:
{
/* args: timer_t timerid */
arg1 &= 0xffff;
if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
target_ulong timerid = arg1;
if (timerid >= ARRAY_SIZE(g_posix_timers)) {
ret = -TARGET_EINVAL;
} else {
timer_t htimer = g_posix_timers[arg1];
timer_t htimer = g_posix_timers[timerid];
ret = get_errno(timer_getoverrun(htimer));
}
break;
@ -9619,13 +9677,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_timer_delete:
{
/* args: timer_t timerid */
arg1 &= 0xffff;
if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
target_ulong timerid = arg1;
if (timerid >= ARRAY_SIZE(g_posix_timers)) {
ret = -TARGET_EINVAL;
} else {
timer_t htimer = g_posix_timers[arg1];
timer_t htimer = g_posix_timers[timerid];
ret = get_errno(timer_delete(htimer));
g_posix_timers[arg1] = 0;
g_posix_timers[timerid] = 0;
}
break;
}

View file

@ -252,4 +252,4 @@ STRUCT(blkpg_ioctl_arg,
TYPE_INT, /* op */
TYPE_INT, /* flags */
TYPE_INT, /* datalen */
MK_PTR(MK_STRUCT(STRUCT_blkpg_partition))) /* data */
TYPE_PTRVOID) /* data */

View file

@ -1660,30 +1660,30 @@ void cpu_interrupt(CPUState *cpu, int mask)
struct walk_memory_regions_data {
walk_memory_regions_fn fn;
void *priv;
uintptr_t start;
target_ulong start;
int prot;
};
static int walk_memory_regions_end(struct walk_memory_regions_data *data,
abi_ulong end, int new_prot)
target_ulong end, int new_prot)
{
if (data->start != -1ul) {
if (data->start != -1u) {
int rc = data->fn(data->priv, data->start, end, data->prot);
if (rc != 0) {
return rc;
}
}
data->start = (new_prot ? end : -1ul);
data->start = (new_prot ? end : -1u);
data->prot = new_prot;
return 0;
}
static int walk_memory_regions_1(struct walk_memory_regions_data *data,
abi_ulong base, int level, void **lp)
target_ulong base, int level, void **lp)
{
abi_ulong pa;
target_ulong pa;
int i, rc;
if (*lp == NULL) {
@ -1708,7 +1708,7 @@ static int walk_memory_regions_1(struct walk_memory_regions_data *data,
void **pp = *lp;
for (i = 0; i < V_L2_SIZE; ++i) {
pa = base | ((abi_ulong)i <<
pa = base | ((target_ulong)i <<
(TARGET_PAGE_BITS + V_L2_BITS * level));
rc = walk_memory_regions_1(data, pa, level - 1, pp + i);
if (rc != 0) {
@ -1727,13 +1727,12 @@ int walk_memory_regions(void *priv, walk_memory_regions_fn fn)
data.fn = fn;
data.priv = priv;
data.start = -1ul;
data.start = -1u;
data.prot = 0;
for (i = 0; i < V_L1_SIZE; i++) {
int rc = walk_memory_regions_1(&data, (abi_ulong)i << V_L1_SHIFT,
int rc = walk_memory_regions_1(&data, (target_ulong)i << (V_L1_SHIFT + TARGET_PAGE_BITS),
V_L1_SHIFT / V_L2_BITS - 1, l1_map + i);
if (rc != 0) {
return rc;
}
@ -1742,13 +1741,13 @@ int walk_memory_regions(void *priv, walk_memory_regions_fn fn)
return walk_memory_regions_end(&data, 0, 0);
}
static int dump_region(void *priv, abi_ulong start,
abi_ulong end, unsigned long prot)
static int dump_region(void *priv, target_ulong start,
target_ulong end, unsigned long prot)
{
FILE *f = (FILE *)priv;
(void) fprintf(f, TARGET_ABI_FMT_lx"-"TARGET_ABI_FMT_lx
" "TARGET_ABI_FMT_lx" %c%c%c\n",
(void) fprintf(f, TARGET_FMT_lx"-"TARGET_FMT_lx
" "TARGET_FMT_lx" %c%c%c\n",
start, end, end - start,
((prot & PAGE_READ) ? 'r' : '-'),
((prot & PAGE_WRITE) ? 'w' : '-'),
@ -1760,7 +1759,7 @@ static int dump_region(void *priv, abi_ulong start,
/* dump memory mappings */
void page_dump(FILE *f)
{
const int length = sizeof(abi_ulong) * 2;
const int length = sizeof(target_ulong) * 2;
(void) fprintf(f, "%-*s %-*s %-*s %s\n",
length, "start", length, "end", length, "size", "prot");
walk_memory_regions(f, dump_region);
@ -1788,7 +1787,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
guest address space. If this assert fires, it probably indicates
a missing call to h2g_valid. */
#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
assert(end < ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
assert(end < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
#endif
assert(start < end);
@ -1825,7 +1824,7 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
guest address space. If this assert fires, it probably indicates
a missing call to h2g_valid. */
#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
assert(start < ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
assert(start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
#endif
if (len == 0) {