mirror of
https://github.com/xemu-project/xemu.git
synced 2024-12-04 09:53:32 +00:00
linux-user fixes before 2.7 freeze, fix commit message
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUAV44ovrRIkN7ePJvAAQiuiw//Q6Gpc4jgj4MJeihApuFod4fT1BIJ/pwZ NjnzaXpZQLPfCYd5UNIzKgxHTYnSVgNrffEgaGUpAqV1mwdsku+6iJDpE7ORMdT0 SsdqD514JkpfV9VuX0ZEZvEaX48YnKwavbS3G/5cSmGsoGnPHxZHL8CUmK9DDYrF kAJ7aeZW0n6RlijTzEbPz3hAMOWeNoLh3IOMGvRhr/cZ5K8ggDKMnL6JLrJ4HKCW z6KknG695qqWCTxEkJIrrGr35djpw3qSNRRAxYatQt9VyPjMnnI0lQG9JDYR5AOE abrhVrg6QDXU2T4vNhERLizT1CUG0Vhx3e2R18tF7Yv/R/SnzKm0qajGuIai8LRq typj5LMxI4JgBf3QQb9dyAk4x5cQt28t4ddhcwPQrEttIXtOgDXLUDnclAewSLBt GesxydPIdTPUzQIZYpcbBrhVMhh0obLVeSlgwRm2Kg5y4pE7Ln/ZXeuuPACU9nLg qWYdWc0xyZ6hfPFsqPFqn/ES2pGsJ/LdnY7UJhOlNgMkMNr4PjLHEXmJGQi6fO1L uyHvvwYJ1Gi249u1LInpRt3i6kLyusoIEJ//yWCSZiIJoU7+zm2iOujs+sOy7Mqo DrejTX9Uc3FdMZMJibwH1SioWFdWBsNvzLh0aMq0Udr4lW9FQfnzdYu0V99KcR0a oooHbb0w4N0= =viYB -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20160719-2' into staging linux-user fixes before 2.7 freeze, fix commit message # gpg: Signature made Tue 19 Jul 2016 14:18:54 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-20160719-2: linux-user: AArch64 has sync_file_range, not sync_file_range2 linux-user: Fix type for SIOCATMARK ioctl linux-user: define missing sparc syscalls linux-user: Fix terminal control ioctls linux-user: Add some new blk ioctls linux-user: Handle short lengths in host_to_target_sockaddr() linux-user: Forget about synchronous signal once it is delivered linux-user: Correct type for LOOP_GET_STATUS{,64} ioctls linux-user: Correct type for BLKSSZGET linux-user: Add loop control ioctls linux-user: Check sigsetsize argument to syscalls linux-user: add nested netlink types linux-user: convert sockaddr_ll from host to target linux-user: add fd_trans helper in do_recvfrom() linux-user: fix netlink memory corruption linux-user: fd_trans_*_data() returns the length Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
1ecfb24da9
@ -86,8 +86,7 @@
|
||||
#define TARGET_NR_sync 81
|
||||
#define TARGET_NR_fsync 82
|
||||
#define TARGET_NR_fdatasync 83
|
||||
#define TARGET_NR_sync_file_range2 84
|
||||
/* #define TARGET_NR_sync_file_range 84 */
|
||||
#define TARGET_NR_sync_file_range 84
|
||||
#define TARGET_NR_timerfd_create 85
|
||||
#define TARGET_NR_timerfd_settime 86
|
||||
#define TARGET_NR_timerfd_gettime 87
|
||||
|
@ -76,10 +76,39 @@
|
||||
IOCTL(BLKFLSBUF, 0, TYPE_NULL)
|
||||
IOCTL(BLKRASET, 0, TYPE_INT)
|
||||
IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
|
||||
IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
|
||||
IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL_SPECIAL(BLKPG, IOC_W, do_ioctl_blkpg,
|
||||
MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
|
||||
|
||||
#ifdef BLKDISCARD
|
||||
IOCTL(BLKDISCARD, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2)))
|
||||
#endif
|
||||
#ifdef BLKIOMIN
|
||||
IOCTL(BLKIOMIN, IOC_R, MK_PTR(TYPE_INT))
|
||||
#endif
|
||||
#ifdef BLKIOOPT
|
||||
IOCTL(BLKIOOPT, IOC_R, MK_PTR(TYPE_INT))
|
||||
#endif
|
||||
#ifdef BLKALIGNOFF
|
||||
IOCTL(BLKALIGNOFF, IOC_R, MK_PTR(TYPE_INT))
|
||||
#endif
|
||||
#ifdef BLKPBSZGET
|
||||
IOCTL(BLKPBSZGET, IOC_R, MK_PTR(TYPE_INT))
|
||||
#endif
|
||||
#ifdef BLKDISCARDZEROES
|
||||
IOCTL(BLKDISCARDZEROES, IOC_R, MK_PTR(TYPE_INT))
|
||||
#endif
|
||||
#ifdef BLKSECDISCARD
|
||||
IOCTL(BLKSECDISCARD, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2)))
|
||||
#endif
|
||||
#ifdef BLKROTATIONAL
|
||||
IOCTL(BLKROTATIONAL, IOC_R, MK_PTR(TYPE_SHORT))
|
||||
#endif
|
||||
#ifdef BLKZEROOUT
|
||||
IOCTL(BLKZEROOUT, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2)))
|
||||
#endif
|
||||
|
||||
#ifdef FIBMAP
|
||||
IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
|
||||
#endif
|
||||
@ -91,7 +120,7 @@
|
||||
MK_PTR(MK_STRUCT(STRUCT_fiemap)))
|
||||
#endif
|
||||
|
||||
IOCTL(SIOCATMARK, 0, TYPE_NULL)
|
||||
IOCTL(SIOCATMARK, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
|
||||
IOCTL(SIOCSIFFLAGS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
|
||||
@ -322,11 +351,15 @@
|
||||
IOCTL(LOOP_SET_FD, 0, TYPE_INT)
|
||||
IOCTL(LOOP_CLR_FD, 0, TYPE_INT)
|
||||
IOCTL(LOOP_SET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
|
||||
IOCTL(LOOP_GET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
|
||||
IOCTL(LOOP_GET_STATUS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
|
||||
IOCTL(LOOP_SET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
|
||||
IOCTL(LOOP_GET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
|
||||
IOCTL(LOOP_GET_STATUS64, IOC_R, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
|
||||
IOCTL(LOOP_CHANGE_FD, 0, TYPE_INT)
|
||||
|
||||
IOCTL(LOOP_CTL_ADD, 0, TYPE_INT)
|
||||
IOCTL(LOOP_CTL_REMOVE, 0, TYPE_INT)
|
||||
IOCTL(LOOP_CTL_GET_FREE, 0, TYPE_NULL)
|
||||
|
||||
IOCTL(MTIOCTOP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_mtop)))
|
||||
IOCTL(MTIOCGET, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtget)))
|
||||
IOCTL(MTIOCPOS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtpos)))
|
||||
|
@ -1,4 +1,6 @@
|
||||
/* Copied from 2.6.25 kernel headers to avoid problems on older hosts. */
|
||||
/* Copied from 2.6.25 kernel headers to avoid problems on older hosts,
|
||||
* and subsequently updated to match newer additions to the API.
|
||||
*/
|
||||
|
||||
#ifndef LINUX_LOOP_H
|
||||
#define LINUX_LOOP_H
|
||||
@ -92,5 +94,12 @@ struct loop_info64 {
|
||||
#define LOOP_SET_STATUS64 0x4C04
|
||||
#define LOOP_GET_STATUS64 0x4C05
|
||||
#define LOOP_CHANGE_FD 0x4C06
|
||||
#define LOOP_SET_CAPACITY 0x4C07
|
||||
#define LOOP_SET_DIRECT_IO 0x4C08
|
||||
|
||||
/* /dev/loop-control interface */
|
||||
#define LOOP_CTL_ADD 0x4C80
|
||||
#define LOOP_CTL_REMOVE 0x4C81
|
||||
#define LOOP_CTL_GET_FREE 0x4C82
|
||||
|
||||
#endif
|
||||
|
@ -5826,7 +5826,8 @@ long do_rt_sigreturn(CPUArchState *env)
|
||||
|
||||
#endif
|
||||
|
||||
static void handle_pending_signal(CPUArchState *cpu_env, int sig)
|
||||
static void handle_pending_signal(CPUArchState *cpu_env, int sig,
|
||||
struct emulated_sigtable *k)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(cpu_env);
|
||||
abi_ulong handler;
|
||||
@ -5834,7 +5835,6 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig)
|
||||
target_sigset_t target_old_set;
|
||||
struct target_sigaction *sa;
|
||||
TaskState *ts = cpu->opaque;
|
||||
struct emulated_sigtable *k = &ts->sigtab[sig - 1];
|
||||
|
||||
trace_user_handle_signal(cpu_env, sig);
|
||||
/* dequeue signal */
|
||||
@ -5937,7 +5937,7 @@ void process_pending_signals(CPUArchState *cpu_env)
|
||||
sigact_table[sig - 1]._sa_handler = TARGET_SIG_DFL;
|
||||
}
|
||||
|
||||
handle_pending_signal(cpu_env, sig);
|
||||
handle_pending_signal(cpu_env, sig, &ts->sync_signal);
|
||||
}
|
||||
|
||||
for (sig = 1; sig <= TARGET_NSIG; sig++) {
|
||||
@ -5947,7 +5947,7 @@ void process_pending_signals(CPUArchState *cpu_env)
|
||||
if (ts->sigtab[sig - 1].pending &&
|
||||
(!sigismember(blocked_set,
|
||||
target_to_host_signal_table[sig]))) {
|
||||
handle_pending_signal(cpu_env, sig);
|
||||
handle_pending_signal(cpu_env, sig, &ts->sigtab[sig - 1]);
|
||||
/* Restart scan from the beginning */
|
||||
sig = 1;
|
||||
}
|
||||
|
@ -179,6 +179,9 @@
|
||||
#define TARGET_NR_readahead 205 /* Linux Specific */
|
||||
#define TARGET_NR_socketcall 206 /* Linux Specific */
|
||||
#define TARGET_NR_syslog 207 /* Linux Specific */
|
||||
#define TARGET_NR_lookup_dcookie 208 /* Linux Specific */
|
||||
#define TARGET_NR_fadvise64 209 /* Linux Specific */
|
||||
#define TARGET_NR_fadvise64_64 210 /* Linux Specific */
|
||||
#define TARGET_NR_tgkill 211 /* Linux Specific */
|
||||
#define TARGET_NR_waitpid 212 /* Linux Specific */
|
||||
#define TARGET_NR_swapoff 213 /* Linux Specific */
|
||||
|
@ -100,9 +100,11 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
|
||||
#include <linux/route.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/blkpg.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <linux/netlink.h>
|
||||
#ifdef CONFIG_RTNETLINK
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/if_bridge.h>
|
||||
#endif
|
||||
#include <linux/audit.h>
|
||||
#include "linux_loop.h"
|
||||
@ -1374,15 +1376,26 @@ static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
|
||||
{
|
||||
struct target_sockaddr *target_saddr;
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
|
||||
if (!target_saddr)
|
||||
return -TARGET_EFAULT;
|
||||
memcpy(target_saddr, addr, len);
|
||||
target_saddr->sa_family = tswap16(addr->sa_family);
|
||||
if (addr->sa_family == AF_NETLINK) {
|
||||
if (len >= offsetof(struct target_sockaddr, sa_family) +
|
||||
sizeof(target_saddr->sa_family)) {
|
||||
target_saddr->sa_family = tswap16(addr->sa_family);
|
||||
}
|
||||
if (addr->sa_family == AF_NETLINK && len >= sizeof(struct sockaddr_nl)) {
|
||||
struct sockaddr_nl *target_nl = (struct sockaddr_nl *)target_saddr;
|
||||
target_nl->nl_pid = tswap32(target_nl->nl_pid);
|
||||
target_nl->nl_groups = tswap32(target_nl->nl_groups);
|
||||
} else if (addr->sa_family == AF_PACKET) {
|
||||
struct sockaddr_ll *target_ll = (struct sockaddr_ll *)target_saddr;
|
||||
target_ll->sll_ifindex = tswap32(target_ll->sll_ifindex);
|
||||
target_ll->sll_hatype = tswap16(target_ll->sll_hatype);
|
||||
}
|
||||
unlock_user(target_saddr, target_addr, len);
|
||||
|
||||
@ -1707,6 +1720,33 @@ static abi_long target_to_host_for_each_nlmsg(struct nlmsghdr *nlh,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RTNETLINK
|
||||
static abi_long host_to_target_for_each_nlattr(struct nlattr *nlattr,
|
||||
size_t len, void *context,
|
||||
abi_long (*host_to_target_nlattr)
|
||||
(struct nlattr *,
|
||||
void *context))
|
||||
{
|
||||
unsigned short nla_len;
|
||||
abi_long ret;
|
||||
|
||||
while (len > sizeof(struct nlattr)) {
|
||||
nla_len = nlattr->nla_len;
|
||||
if (nla_len < sizeof(struct nlattr) ||
|
||||
nla_len > len) {
|
||||
break;
|
||||
}
|
||||
ret = host_to_target_nlattr(nlattr, context);
|
||||
nlattr->nla_len = tswap16(nlattr->nla_len);
|
||||
nlattr->nla_type = tswap16(nlattr->nla_type);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
len -= NLA_ALIGN(nla_len);
|
||||
nlattr = (struct nlattr *)(((char *)nlattr) + NLA_ALIGN(nla_len));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static abi_long host_to_target_for_each_rtattr(struct rtattr *rtattr,
|
||||
size_t len,
|
||||
abi_long (*host_to_target_rtattr)
|
||||
@ -1733,12 +1773,292 @@ static abi_long host_to_target_for_each_rtattr(struct rtattr *rtattr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define NLA_DATA(nla) ((void *)((char *)(nla)) + NLA_HDRLEN)
|
||||
|
||||
static abi_long host_to_target_data_bridge_nlattr(struct nlattr *nlattr,
|
||||
void *context)
|
||||
{
|
||||
uint16_t *u16;
|
||||
uint32_t *u32;
|
||||
uint64_t *u64;
|
||||
|
||||
switch (nlattr->nla_type) {
|
||||
/* no data */
|
||||
case IFLA_BR_FDB_FLUSH:
|
||||
break;
|
||||
/* binary */
|
||||
case IFLA_BR_GROUP_ADDR:
|
||||
break;
|
||||
/* uint8_t */
|
||||
case IFLA_BR_VLAN_FILTERING:
|
||||
case IFLA_BR_TOPOLOGY_CHANGE:
|
||||
case IFLA_BR_TOPOLOGY_CHANGE_DETECTED:
|
||||
case IFLA_BR_MCAST_ROUTER:
|
||||
case IFLA_BR_MCAST_SNOOPING:
|
||||
case IFLA_BR_MCAST_QUERY_USE_IFADDR:
|
||||
case IFLA_BR_MCAST_QUERIER:
|
||||
case IFLA_BR_NF_CALL_IPTABLES:
|
||||
case IFLA_BR_NF_CALL_IP6TABLES:
|
||||
case IFLA_BR_NF_CALL_ARPTABLES:
|
||||
break;
|
||||
/* uint16_t */
|
||||
case IFLA_BR_PRIORITY:
|
||||
case IFLA_BR_VLAN_PROTOCOL:
|
||||
case IFLA_BR_GROUP_FWD_MASK:
|
||||
case IFLA_BR_ROOT_PORT:
|
||||
case IFLA_BR_VLAN_DEFAULT_PVID:
|
||||
u16 = NLA_DATA(nlattr);
|
||||
*u16 = tswap16(*u16);
|
||||
break;
|
||||
/* uint32_t */
|
||||
case IFLA_BR_FORWARD_DELAY:
|
||||
case IFLA_BR_HELLO_TIME:
|
||||
case IFLA_BR_MAX_AGE:
|
||||
case IFLA_BR_AGEING_TIME:
|
||||
case IFLA_BR_STP_STATE:
|
||||
case IFLA_BR_ROOT_PATH_COST:
|
||||
case IFLA_BR_MCAST_HASH_ELASTICITY:
|
||||
case IFLA_BR_MCAST_HASH_MAX:
|
||||
case IFLA_BR_MCAST_LAST_MEMBER_CNT:
|
||||
case IFLA_BR_MCAST_STARTUP_QUERY_CNT:
|
||||
u32 = NLA_DATA(nlattr);
|
||||
*u32 = tswap32(*u32);
|
||||
break;
|
||||
/* uint64_t */
|
||||
case IFLA_BR_HELLO_TIMER:
|
||||
case IFLA_BR_TCN_TIMER:
|
||||
case IFLA_BR_GC_TIMER:
|
||||
case IFLA_BR_TOPOLOGY_CHANGE_TIMER:
|
||||
case IFLA_BR_MCAST_LAST_MEMBER_INTVL:
|
||||
case IFLA_BR_MCAST_MEMBERSHIP_INTVL:
|
||||
case IFLA_BR_MCAST_QUERIER_INTVL:
|
||||
case IFLA_BR_MCAST_QUERY_INTVL:
|
||||
case IFLA_BR_MCAST_QUERY_RESPONSE_INTVL:
|
||||
case IFLA_BR_MCAST_STARTUP_QUERY_INTVL:
|
||||
u64 = NLA_DATA(nlattr);
|
||||
*u64 = tswap64(*u64);
|
||||
break;
|
||||
/* ifla_bridge_id: uin8_t[] */
|
||||
case IFLA_BR_ROOT_ID:
|
||||
case IFLA_BR_BRIDGE_ID:
|
||||
break;
|
||||
default:
|
||||
gemu_log("Unknown IFLA_BR type %d\n", nlattr->nla_type);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static abi_long host_to_target_slave_data_bridge_nlattr(struct nlattr *nlattr,
|
||||
void *context)
|
||||
{
|
||||
uint16_t *u16;
|
||||
uint32_t *u32;
|
||||
uint64_t *u64;
|
||||
|
||||
switch (nlattr->nla_type) {
|
||||
/* uint8_t */
|
||||
case IFLA_BRPORT_STATE:
|
||||
case IFLA_BRPORT_MODE:
|
||||
case IFLA_BRPORT_GUARD:
|
||||
case IFLA_BRPORT_PROTECT:
|
||||
case IFLA_BRPORT_FAST_LEAVE:
|
||||
case IFLA_BRPORT_LEARNING:
|
||||
case IFLA_BRPORT_UNICAST_FLOOD:
|
||||
case IFLA_BRPORT_PROXYARP:
|
||||
case IFLA_BRPORT_LEARNING_SYNC:
|
||||
case IFLA_BRPORT_PROXYARP_WIFI:
|
||||
case IFLA_BRPORT_TOPOLOGY_CHANGE_ACK:
|
||||
case IFLA_BRPORT_CONFIG_PENDING:
|
||||
case IFLA_BRPORT_MULTICAST_ROUTER:
|
||||
break;
|
||||
/* uint16_t */
|
||||
case IFLA_BRPORT_PRIORITY:
|
||||
case IFLA_BRPORT_DESIGNATED_PORT:
|
||||
case IFLA_BRPORT_DESIGNATED_COST:
|
||||
case IFLA_BRPORT_ID:
|
||||
case IFLA_BRPORT_NO:
|
||||
u16 = NLA_DATA(nlattr);
|
||||
*u16 = tswap16(*u16);
|
||||
break;
|
||||
/* uin32_t */
|
||||
case IFLA_BRPORT_COST:
|
||||
u32 = NLA_DATA(nlattr);
|
||||
*u32 = tswap32(*u32);
|
||||
break;
|
||||
/* uint64_t */
|
||||
case IFLA_BRPORT_MESSAGE_AGE_TIMER:
|
||||
case IFLA_BRPORT_FORWARD_DELAY_TIMER:
|
||||
case IFLA_BRPORT_HOLD_TIMER:
|
||||
u64 = NLA_DATA(nlattr);
|
||||
*u64 = tswap64(*u64);
|
||||
break;
|
||||
/* ifla_bridge_id: uint8_t[] */
|
||||
case IFLA_BRPORT_ROOT_ID:
|
||||
case IFLA_BRPORT_BRIDGE_ID:
|
||||
break;
|
||||
default:
|
||||
gemu_log("Unknown IFLA_BRPORT type %d\n", nlattr->nla_type);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct linkinfo_context {
|
||||
int len;
|
||||
char *name;
|
||||
int slave_len;
|
||||
char *slave_name;
|
||||
};
|
||||
|
||||
static abi_long host_to_target_data_linkinfo_nlattr(struct nlattr *nlattr,
|
||||
void *context)
|
||||
{
|
||||
struct linkinfo_context *li_context = context;
|
||||
|
||||
switch (nlattr->nla_type) {
|
||||
/* string */
|
||||
case IFLA_INFO_KIND:
|
||||
li_context->name = NLA_DATA(nlattr);
|
||||
li_context->len = nlattr->nla_len - NLA_HDRLEN;
|
||||
break;
|
||||
case IFLA_INFO_SLAVE_KIND:
|
||||
li_context->slave_name = NLA_DATA(nlattr);
|
||||
li_context->slave_len = nlattr->nla_len - NLA_HDRLEN;
|
||||
break;
|
||||
/* stats */
|
||||
case IFLA_INFO_XSTATS:
|
||||
/* FIXME: only used by CAN */
|
||||
break;
|
||||
/* nested */
|
||||
case IFLA_INFO_DATA:
|
||||
if (strncmp(li_context->name, "bridge",
|
||||
li_context->len) == 0) {
|
||||
return host_to_target_for_each_nlattr(NLA_DATA(nlattr),
|
||||
nlattr->nla_len,
|
||||
NULL,
|
||||
host_to_target_data_bridge_nlattr);
|
||||
} else {
|
||||
gemu_log("Unknown IFLA_INFO_KIND %s\n", li_context->name);
|
||||
}
|
||||
break;
|
||||
case IFLA_INFO_SLAVE_DATA:
|
||||
if (strncmp(li_context->slave_name, "bridge",
|
||||
li_context->slave_len) == 0) {
|
||||
return host_to_target_for_each_nlattr(NLA_DATA(nlattr),
|
||||
nlattr->nla_len,
|
||||
NULL,
|
||||
host_to_target_slave_data_bridge_nlattr);
|
||||
} else {
|
||||
gemu_log("Unknown IFLA_INFO_SLAVE_KIND %s\n",
|
||||
li_context->slave_name);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gemu_log("Unknown host IFLA_INFO type: %d\n", nlattr->nla_type);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static abi_long host_to_target_data_inet_nlattr(struct nlattr *nlattr,
|
||||
void *context)
|
||||
{
|
||||
uint32_t *u32;
|
||||
int i;
|
||||
|
||||
switch (nlattr->nla_type) {
|
||||
case IFLA_INET_CONF:
|
||||
u32 = NLA_DATA(nlattr);
|
||||
for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u32);
|
||||
i++) {
|
||||
u32[i] = tswap32(u32[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gemu_log("Unknown host AF_INET type: %d\n", nlattr->nla_type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static abi_long host_to_target_data_inet6_nlattr(struct nlattr *nlattr,
|
||||
void *context)
|
||||
{
|
||||
uint32_t *u32;
|
||||
uint64_t *u64;
|
||||
struct ifla_cacheinfo *ci;
|
||||
int i;
|
||||
|
||||
switch (nlattr->nla_type) {
|
||||
/* binaries */
|
||||
case IFLA_INET6_TOKEN:
|
||||
break;
|
||||
/* uint8_t */
|
||||
case IFLA_INET6_ADDR_GEN_MODE:
|
||||
break;
|
||||
/* uint32_t */
|
||||
case IFLA_INET6_FLAGS:
|
||||
u32 = NLA_DATA(nlattr);
|
||||
*u32 = tswap32(*u32);
|
||||
break;
|
||||
/* uint32_t[] */
|
||||
case IFLA_INET6_CONF:
|
||||
u32 = NLA_DATA(nlattr);
|
||||
for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u32);
|
||||
i++) {
|
||||
u32[i] = tswap32(u32[i]);
|
||||
}
|
||||
break;
|
||||
/* ifla_cacheinfo */
|
||||
case IFLA_INET6_CACHEINFO:
|
||||
ci = NLA_DATA(nlattr);
|
||||
ci->max_reasm_len = tswap32(ci->max_reasm_len);
|
||||
ci->tstamp = tswap32(ci->tstamp);
|
||||
ci->reachable_time = tswap32(ci->reachable_time);
|
||||
ci->retrans_time = tswap32(ci->retrans_time);
|
||||
break;
|
||||
/* uint64_t[] */
|
||||
case IFLA_INET6_STATS:
|
||||
case IFLA_INET6_ICMP6STATS:
|
||||
u64 = NLA_DATA(nlattr);
|
||||
for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u64);
|
||||
i++) {
|
||||
u64[i] = tswap64(u64[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gemu_log("Unknown host AF_INET6 type: %d\n", nlattr->nla_type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static abi_long host_to_target_data_spec_nlattr(struct nlattr *nlattr,
|
||||
void *context)
|
||||
{
|
||||
switch (nlattr->nla_type) {
|
||||
case AF_INET:
|
||||
return host_to_target_for_each_nlattr(NLA_DATA(nlattr), nlattr->nla_len,
|
||||
NULL,
|
||||
host_to_target_data_inet_nlattr);
|
||||
case AF_INET6:
|
||||
return host_to_target_for_each_nlattr(NLA_DATA(nlattr), nlattr->nla_len,
|
||||
NULL,
|
||||
host_to_target_data_inet6_nlattr);
|
||||
default:
|
||||
gemu_log("Unknown host AF_SPEC type: %d\n", nlattr->nla_type);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
|
||||
{
|
||||
uint32_t *u32;
|
||||
struct rtnl_link_stats *st;
|
||||
struct rtnl_link_stats64 *st64;
|
||||
struct rtnl_link_ifmap *map;
|
||||
struct linkinfo_context li_context;
|
||||
|
||||
switch (rtattr->rta_type) {
|
||||
/* binary stream */
|
||||
@ -1846,11 +2166,15 @@ static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
|
||||
map->irq = tswap16(map->irq);
|
||||
break;
|
||||
/* nested */
|
||||
case IFLA_AF_SPEC:
|
||||
case IFLA_LINKINFO:
|
||||
/* FIXME: implement nested type */
|
||||
gemu_log("Unimplemented nested type %d\n", rtattr->rta_type);
|
||||
break;
|
||||
memset(&li_context, 0, sizeof(li_context));
|
||||
return host_to_target_for_each_nlattr(RTA_DATA(rtattr), rtattr->rta_len,
|
||||
&li_context,
|
||||
host_to_target_data_linkinfo_nlattr);
|
||||
case IFLA_AF_SPEC:
|
||||
return host_to_target_for_each_nlattr(RTA_DATA(rtattr), rtattr->rta_len,
|
||||
NULL,
|
||||
host_to_target_data_spec_nlattr);
|
||||
default:
|
||||
gemu_log("Unknown host IFLA type: %d\n", rtattr->rta_type);
|
||||
break;
|
||||
@ -2826,12 +3150,26 @@ static TargetFdTrans target_packet_trans = {
|
||||
#ifdef CONFIG_RTNETLINK
|
||||
static abi_long netlink_route_target_to_host(void *buf, size_t len)
|
||||
{
|
||||
return target_to_host_nlmsg_route(buf, len);
|
||||
abi_long ret;
|
||||
|
||||
ret = target_to_host_nlmsg_route(buf, len);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static abi_long netlink_route_host_to_target(void *buf, size_t len)
|
||||
{
|
||||
return host_to_target_nlmsg_route(buf, len);
|
||||
abi_long ret;
|
||||
|
||||
ret = host_to_target_nlmsg_route(buf, len);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static TargetFdTrans target_netlink_route_trans = {
|
||||
@ -2842,12 +3180,26 @@ static TargetFdTrans target_netlink_route_trans = {
|
||||
|
||||
static abi_long netlink_audit_target_to_host(void *buf, size_t len)
|
||||
{
|
||||
return target_to_host_nlmsg_audit(buf, len);
|
||||
abi_long ret;
|
||||
|
||||
ret = target_to_host_nlmsg_audit(buf, len);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static abi_long netlink_audit_host_to_target(void *buf, size_t len)
|
||||
{
|
||||
return host_to_target_nlmsg_audit(buf, len);
|
||||
abi_long ret;
|
||||
|
||||
ret = host_to_target_nlmsg_audit(buf, len);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static TargetFdTrans target_netlink_audit_trans = {
|
||||
@ -2989,13 +3341,22 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
|
||||
|
||||
if (send) {
|
||||
if (fd_trans_target_to_host_data(fd)) {
|
||||
ret = fd_trans_target_to_host_data(fd)(msg.msg_iov->iov_base,
|
||||
void *host_msg;
|
||||
|
||||
host_msg = g_malloc(msg.msg_iov->iov_len);
|
||||
memcpy(host_msg, msg.msg_iov->iov_base, msg.msg_iov->iov_len);
|
||||
ret = fd_trans_target_to_host_data(fd)(host_msg,
|
||||
msg.msg_iov->iov_len);
|
||||
if (ret >= 0) {
|
||||
msg.msg_iov->iov_base = host_msg;
|
||||
ret = get_errno(safe_sendmsg(fd, &msg, flags));
|
||||
}
|
||||
g_free(host_msg);
|
||||
} else {
|
||||
ret = target_to_host_cmsg(&msg, msgp);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = get_errno(safe_sendmsg(fd, &msg, flags));
|
||||
if (ret == 0) {
|
||||
ret = get_errno(safe_sendmsg(fd, &msg, flags));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = get_errno(safe_recvmsg(fd, &msg, flags));
|
||||
@ -3211,6 +3572,7 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
|
||||
{
|
||||
void *addr;
|
||||
void *host_msg;
|
||||
void *copy_msg = NULL;
|
||||
abi_long ret;
|
||||
|
||||
if ((int)addrlen < 0) {
|
||||
@ -3221,23 +3583,29 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
|
||||
if (!host_msg)
|
||||
return -TARGET_EFAULT;
|
||||
if (fd_trans_target_to_host_data(fd)) {
|
||||
copy_msg = host_msg;
|
||||
host_msg = g_malloc(len);
|
||||
memcpy(host_msg, copy_msg, len);
|
||||
ret = fd_trans_target_to_host_data(fd)(host_msg, len);
|
||||
if (ret < 0) {
|
||||
unlock_user(host_msg, msg, 0);
|
||||
return ret;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (target_addr) {
|
||||
addr = alloca(addrlen+1);
|
||||
ret = target_to_host_sockaddr(fd, addr, target_addr, addrlen);
|
||||
if (ret) {
|
||||
unlock_user(host_msg, msg, 0);
|
||||
return ret;
|
||||
goto fail;
|
||||
}
|
||||
ret = get_errno(safe_sendto(fd, host_msg, len, flags, addr, addrlen));
|
||||
} else {
|
||||
ret = get_errno(safe_sendto(fd, host_msg, len, flags, NULL, 0));
|
||||
}
|
||||
fail:
|
||||
if (copy_msg) {
|
||||
g_free(host_msg);
|
||||
host_msg = copy_msg;
|
||||
}
|
||||
unlock_user(host_msg, msg, 0);
|
||||
return ret;
|
||||
}
|
||||
@ -3272,6 +3640,9 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
|
||||
ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, NULL, 0));
|
||||
}
|
||||
if (!is_error(ret)) {
|
||||
if (fd_trans_host_to_target_data(fd)) {
|
||||
ret = fd_trans_host_to_target_data(fd)(host_msg, ret);
|
||||
}
|
||||
if (target_addr) {
|
||||
host_to_target_sockaddr(target_addr, addr, addrlen);
|
||||
if (put_user_u32(addrlen, target_addrlen)) {
|
||||
@ -7614,7 +7985,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
#if defined(TARGET_ALPHA)
|
||||
struct target_sigaction act, oact, *pact = 0;
|
||||
struct target_rt_sigaction *rt_act;
|
||||
/* ??? arg4 == sizeof(sigset_t). */
|
||||
|
||||
if (arg4 != sizeof(target_sigset_t)) {
|
||||
ret = -TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
if (arg2) {
|
||||
if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
|
||||
goto efault;
|
||||
@ -7638,6 +8013,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
struct target_sigaction *act;
|
||||
struct target_sigaction *oact;
|
||||
|
||||
if (arg4 != sizeof(target_sigset_t)) {
|
||||
ret = -TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
if (arg2) {
|
||||
if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
|
||||
goto efault;
|
||||
@ -7769,6 +8148,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
int how = arg1;
|
||||
sigset_t set, oldset, *set_ptr;
|
||||
|
||||
if (arg4 != sizeof(target_sigset_t)) {
|
||||
ret = -TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (arg2) {
|
||||
switch(how) {
|
||||
case TARGET_SIG_BLOCK:
|
||||
@ -7819,6 +8203,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
case TARGET_NR_rt_sigpending:
|
||||
{
|
||||
sigset_t set;
|
||||
|
||||
/* Yes, this check is >, not != like most. We follow the kernel's
|
||||
* logic and it does it like this because it implements
|
||||
* NR_sigpending through the same code path, and in that case
|
||||
* the old_sigset_t is smaller in size.
|
||||
*/
|
||||
if (arg2 > sizeof(target_sigset_t)) {
|
||||
ret = -TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = get_errno(sigpending(&set));
|
||||
if (!is_error(ret)) {
|
||||
if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
|
||||
@ -7852,6 +8247,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
case TARGET_NR_rt_sigsuspend:
|
||||
{
|
||||
TaskState *ts = cpu->opaque;
|
||||
|
||||
if (arg2 != sizeof(target_sigset_t)) {
|
||||
ret = -TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
|
||||
goto efault;
|
||||
target_to_host_sigset(&ts->sigsuspend_mask, p);
|
||||
@ -7869,6 +8269,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
struct timespec uts, *puts;
|
||||
siginfo_t uinfo;
|
||||
|
||||
if (arg4 != sizeof(target_sigset_t)) {
|
||||
ret = -TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
|
||||
goto efault;
|
||||
target_to_host_sigset(&set, p);
|
||||
@ -9120,6 +9525,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
}
|
||||
|
||||
if (arg4) {
|
||||
if (arg5 != sizeof(target_sigset_t)) {
|
||||
unlock_user(target_pfd, arg1, 0);
|
||||
ret = -TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
|
||||
if (!target_set) {
|
||||
unlock_user(target_pfd, arg1, 0);
|
||||
@ -10939,6 +11350,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
sigset_t _set, *set = &_set;
|
||||
|
||||
if (arg5) {
|
||||
if (arg6 != sizeof(target_sigset_t)) {
|
||||
ret = -TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
target_set = lock_user(VERIFY_READ, arg5,
|
||||
sizeof(target_sigset_t), 1);
|
||||
if (!target_set) {
|
||||
|
@ -985,6 +985,17 @@ struct target_pollfd {
|
||||
#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,abi_ulong)
|
||||
/* return device size in bytes
|
||||
(u64 *arg) */
|
||||
|
||||
#define TARGET_BLKDISCARD TARGET_IO(0x12, 119)
|
||||
#define TARGET_BLKIOMIN TARGET_IO(0x12, 120)
|
||||
#define TARGET_BLKIOOPT TARGET_IO(0x12, 121)
|
||||
#define TARGET_BLKALIGNOFF TARGET_IO(0x12, 122)
|
||||
#define TARGET_BLKPBSZGET TARGET_IO(0x12, 123)
|
||||
#define TARGET_BLKDISCARDZEROES TARGET_IO(0x12, 124)
|
||||
#define TARGET_BLKSECDISCARD TARGET_IO(0x12, 125)
|
||||
#define TARGET_BLKROTATIONAL TARGET_IO(0x12, 126)
|
||||
#define TARGET_BLKZEROOUT TARGET_IO(0x12, 127)
|
||||
|
||||
#define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */
|
||||
#define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */
|
||||
#define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
|
||||
@ -1117,6 +1128,10 @@ struct target_pollfd {
|
||||
#define TARGET_LOOP_GET_STATUS64 0x4C05
|
||||
#define TARGET_LOOP_CHANGE_FD 0x4C06
|
||||
|
||||
#define TARGET_LOOP_CTL_ADD 0x4C80
|
||||
#define TARGET_LOOP_CTL_REMOVE 0x4C81
|
||||
#define TARGET_LOOP_CTL_GET_FREE 0x4C82
|
||||
|
||||
/* fb ioctls */
|
||||
#define TARGET_FBIOGET_VSCREENINFO 0x4600
|
||||
#define TARGET_FBIOPUT_VSCREENINFO 0x4601
|
||||
|
@ -103,10 +103,11 @@ STRUCT(loop_info64,
|
||||
TYPE_ULONGLONG, /* lo_inode */
|
||||
TYPE_ULONGLONG, /* lo_rdevice */
|
||||
TYPE_ULONGLONG, /* lo_offset */
|
||||
TYPE_ULONG, /* lo_number */
|
||||
TYPE_ULONG, /* lo_encrypt_type */
|
||||
TYPE_ULONG, /* lo_encrypt_key_size */
|
||||
TYPE_ULONG, /* lo_flags */
|
||||
TYPE_ULONGLONG, /* lo_sizelimit */
|
||||
TYPE_INT, /* lo_number */
|
||||
TYPE_INT, /* lo_encrypt_type */
|
||||
TYPE_INT, /* lo_encrypt_key_size */
|
||||
TYPE_INT, /* lo_flags */
|
||||
MK_ARRAY(TYPE_CHAR, 64), /* lo_name */
|
||||
MK_ARRAY(TYPE_CHAR, 64), /* lo_crypt_name */
|
||||
MK_ARRAY(TYPE_CHAR, 32), /* lo_encrypt_key */
|
||||
|
@ -209,12 +209,12 @@ struct target_termios {
|
||||
#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
|
||||
#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
|
||||
#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */
|
||||
#define TARGET_TCGETS2 _IOR('T',0x2A, struct termios2)
|
||||
#define TARGET_TCSETS2 _IOW('T',0x2B, struct termios2)
|
||||
#define TARGET_TCSETSW2 _IOW('T',0x2C, struct termios2)
|
||||
#define TARGET_TCSETSF2 _IOW('T',0x2D, struct termios2)
|
||||
#define TARGET_TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
|
||||
#define TARGET_TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
|
||||
#define TARGET_TCGETS2 TARGET_IOR('T',0x2A, struct termios2)
|
||||
#define TARGET_TCSETS2 TARGET_IOW('T',0x2B, struct termios2)
|
||||
#define TARGET_TCSETSW2 TARGET_IOW('T',0x2C, struct termios2)
|
||||
#define TARGET_TCSETSF2 TARGET_IOW('T',0x2D, struct termios2)
|
||||
#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
|
||||
#define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int) /* Lock/unlock Pty */
|
||||
|
||||
#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */
|
||||
#define TARGET_FIOCLEX 0x5451
|
||||
|
Loading…
Reference in New Issue
Block a user