mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 13:30:52 +00:00
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:
commit
b6011bd8a5
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user