diff options
-rw-r--r-- | hw/net/e1000e_core.c | 9 | ||||
-rw-r--r-- | hw/net/imx_fec.c | 10 | ||||
-rw-r--r-- | linux-user/elfload.c | 22 | ||||
-rw-r--r-- | linux-user/host/s390x/safe-syscall.inc.S | 2 | ||||
-rw-r--r-- | linux-user/ioctls.h | 5 | ||||
-rw-r--r-- | linux-user/m68k/syscall_nr.h | 3 | ||||
-rw-r--r-- | linux-user/mmap.c | 9 | ||||
-rw-r--r-- | linux-user/sh4/syscall_nr.h | 14 | ||||
-rw-r--r-- | linux-user/signal.c | 5 | ||||
-rw-r--r-- | linux-user/strace.c | 2 | ||||
-rw-r--r-- | linux-user/syscall.c | 26 | ||||
-rw-r--r-- | linux-user/syscall_defs.h | 4 | ||||
-rw-r--r-- | linux-user/syscall_types.h | 6 | ||||
-rw-r--r-- | net/colo-compare.c | 19 | ||||
-rw-r--r-- | net/net.c | 6 |
15 files changed, 113 insertions, 29 deletions
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c index 2b11499..28c5be1 100644 --- a/hw/net/e1000e_core.c +++ b/hw/net/e1000e_core.c @@ -806,7 +806,8 @@ typedef struct E1000E_RingInfo_st { static inline bool e1000e_ring_empty(E1000ECore *core, const E1000E_RingInfo *r) { - return core->mac[r->dh] == core->mac[r->dt]; + return core->mac[r->dh] == core->mac[r->dt] || + core->mac[r->dt] >= core->mac[r->dlen] / E1000_RING_DESC_LEN; } static inline uint64_t @@ -1507,6 +1508,7 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt, const E1000E_RingInfo *rxi; size_t ps_hdr_len = 0; bool do_ps = e1000e_do_ps(core, pkt, &ps_hdr_len); + bool is_first = true; rxi = rxr->i; @@ -1514,7 +1516,6 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt, hwaddr ba[MAX_PS_BUFFERS]; e1000e_ba_state bastate = { { 0 } }; bool is_last = false; - bool is_first = true; desc_size = total_size - desc_offset; @@ -1522,6 +1523,10 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt, desc_size = core->rx_desc_buf_size; } + if (e1000e_ring_empty(core, rxi)) { + return; + } + base = e1000e_ring_head_descr(core, rxi); pci_dma_read(d, base, &desc, core->rx_desc_len); diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c index 50c7564..90e6ee3 100644 --- a/hw/net/imx_fec.c +++ b/hw/net/imx_fec.c @@ -55,6 +55,8 @@ } \ } while (0) +#define IMX_MAX_DESC 1024 + static const char *imx_default_reg_name(IMXFECState *s, uint32_t index) { static char tmp[20]; @@ -402,12 +404,12 @@ static void imx_eth_update(IMXFECState *s) static void imx_fec_do_tx(IMXFECState *s) { - int frame_size = 0; + int frame_size = 0, descnt = 0; uint8_t frame[ENET_MAX_FRAME_SIZE]; uint8_t *ptr = frame; uint32_t addr = s->tx_descriptor; - while (1) { + while (descnt++ < IMX_MAX_DESC) { IMXFECBufDesc bd; int len; @@ -453,12 +455,12 @@ static void imx_fec_do_tx(IMXFECState *s) static void imx_enet_do_tx(IMXFECState *s) { - int frame_size = 0; + int frame_size = 0, descnt = 0; uint8_t frame[ENET_MAX_FRAME_SIZE]; uint8_t *ptr = frame; uint32_t addr = s->tx_descriptor; - while (1) { + while (descnt++ < IMX_MAX_DESC) { IMXENETBufDesc bd; int len; diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 8271227..f520d77 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2262,6 +2262,7 @@ static int symcmp(const void *s0, const void *s1) static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) { int i, shnum, nsyms, sym_idx = 0, str_idx = 0; + uint64_t segsz; struct elf_shdr *shdr; char *strings = NULL; struct syminfo *s = NULL; @@ -2293,19 +2294,26 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) goto give_up; } - i = shdr[str_idx].sh_size; - s->disas_strtab = strings = g_try_malloc(i); - if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) { + segsz = shdr[str_idx].sh_size; + s->disas_strtab = strings = g_try_malloc(segsz); + if (!strings || + pread(fd, strings, segsz, shdr[str_idx].sh_offset) != segsz) { goto give_up; } - i = shdr[sym_idx].sh_size; - syms = g_try_malloc(i); - if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) { + segsz = shdr[sym_idx].sh_size; + syms = g_try_malloc(segsz); + if (!syms || pread(fd, syms, segsz, shdr[sym_idx].sh_offset) != segsz) { goto give_up; } - nsyms = i / sizeof(struct elf_sym); + if (segsz / sizeof(struct elf_sym) > INT_MAX) { + /* Implausibly large symbol table: give up rather than ploughing + * on with the number of symbols calculation overflowing + */ + goto give_up; + } + nsyms = segsz / sizeof(struct elf_sym); for (i = 0; i < nsyms; ) { bswap_sym(syms + i); /* Throw away entries which we do not need. */ diff --git a/linux-user/host/s390x/safe-syscall.inc.S b/linux-user/host/s390x/safe-syscall.inc.S index f1b446a..414b44a 100644 --- a/linux-user/host/s390x/safe-syscall.inc.S +++ b/linux-user/host/s390x/safe-syscall.inc.S @@ -72,7 +72,7 @@ safe_syscall_base: */ safe_syscall_start: /* if signal_pending is non-zero, don't do the call */ - lt %r0,0(%r8) + icm %r0,15,0(%r8) jne 2f svc 0 safe_syscall_end: diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 2f6e85b..e6997ff 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -112,6 +112,11 @@ #ifdef FIBMAP IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG)) #endif +#ifdef FICLONE + IOCTL(FICLONE, IOC_W, TYPE_INT) + IOCTL(FICLONERANGE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_file_clone_range))) +#endif + #ifdef FIGETBSZ IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG)) #endif diff --git a/linux-user/m68k/syscall_nr.h b/linux-user/m68k/syscall_nr.h index 4b50fb2..d239551 100644 --- a/linux-user/m68k/syscall_nr.h +++ b/linux-user/m68k/syscall_nr.h @@ -376,3 +376,6 @@ #define TARGET_NR_userfaultfd 373 #define TARGET_NR_membarrier 374 #define TARGET_NR_mlock2 375 +#define TARGET_NR_copy_file_range 376 +#define TARGET_NR_preadv2 377 +#define TARGET_NR_pwritev2 378 diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 61685bf..4888f53 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -193,9 +193,6 @@ static int mmap_frag(abi_ulong real_start, #if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64 # define TASK_UNMAPPED_BASE (1ul << 38) -#elif defined(__CYGWIN__) -/* Cygwin doesn't have a whole lot of address space. */ -# define TASK_UNMAPPED_BASE 0x18000000 #else # define TASK_UNMAPPED_BASE 0x40000000 #endif @@ -429,9 +426,9 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, may need to truncate file maps at EOF and add extra anonymous pages up to the targets page boundary. */ - if ((qemu_real_host_page_size < TARGET_PAGE_SIZE) - && !(flags & MAP_ANONYMOUS)) { - struct stat sb; + if ((qemu_real_host_page_size < qemu_host_page_size) && + !(flags & MAP_ANONYMOUS)) { + struct stat sb; if (fstat (fd, &sb) == -1) goto fail; diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h index e99f735..d6c1e05 100644 --- a/linux-user/sh4/syscall_nr.h +++ b/linux-user/sh4/syscall_nr.h @@ -372,3 +372,17 @@ #define TARGET_NR_process_vm_writev 366 #define TARGET_NR_kcmp 367 #define TARGET_NR_finit_module 368 +#define TARGET_NR_sched_getattr 369 +#define TARGET_NR_sched_setattr 370 +#define TARGET_NR_renameat2 371 +#define TARGET_NR_seccomp 372 +#define TARGET_NR_getrandom 373 +#define TARGET_NR_memfd_create 374 +#define TARGET_NR_bpf 375 +#define TARGET_NR_execveat 376 +#define TARGET_NR_userfaultfd 377 +#define TARGET_NR_membarrier 378 +#define TARGET_NR_mlock2 379 +#define TARGET_NR_copy_file_range 380 +#define TARGET_NR_preadv2 381 +#define TARGET_NR_pwritev2 382 diff --git a/linux-user/signal.c b/linux-user/signal.c index 5064de0..8209539 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -5155,6 +5155,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka, target_ulong rt_sf_addr, newsp = 0; int i, err = 0; #if defined(TARGET_PPC64) + struct target_sigcontext *sc = 0; struct image_info *image = ((TaskState *)thread_cpu->opaque)->info; #endif @@ -5183,6 +5184,10 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka, #if defined(TARGET_PPC64) mctx = &rt_sf->uc.tuc_sigcontext.mcontext; trampptr = &rt_sf->trampoline[0]; + + sc = &rt_sf->uc.tuc_sigcontext; + __put_user(h2g(mctx), &sc->regs); + __put_user(sig, &sc->signal); #else mctx = &rt_sf->uc.tuc_mcontext; trampptr = (uint32_t *)&rt_sf->uc.tuc_mcontext.tramp; diff --git a/linux-user/strace.c b/linux-user/strace.c index 489dbc9..8fb1b6e 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -90,10 +90,8 @@ if( cmd == val ) { \ output_cmd( IPC_STAT ); output_cmd( IPC_INFO ); /* msgctl() commands */ - #ifdef __USER_MISC output_cmd( MSG_STAT ); output_cmd( MSG_INFO ); - #endif /* shmctl() commands */ output_cmd( SHM_LOCK ); output_cmd( SHM_UNLOCK ); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9be8e95..f569f82 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2326,6 +2326,8 @@ static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr) case QEMU_IFLA_GROUP: case QEMU_IFLA_MASTER: case QEMU_IFLA_NUM_VF: + case QEMU_IFLA_GSO_MAX_SEGS: + case QEMU_IFLA_GSO_MAX_SIZE: u32 = RTA_DATA(rtattr); *u32 = tswap32(*u32); break; @@ -11228,7 +11230,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, arg3 = arg4; arg4 = arg5; } - ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4)); + ret = get_errno(readahead(arg1, target_offset64(arg2, arg3) , arg4)); #else ret = get_errno(readahead(arg1, arg2, arg3)); #endif @@ -11561,7 +11563,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef CONFIG_INOTIFY1 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1) case TARGET_NR_inotify_init1: - ret = get_errno(sys_inotify_init1(arg1)); + ret = get_errno(sys_inotify_init1(target_to_host_bitmask(arg1, + fcntl_flags_tbl))); break; #endif #endif @@ -11582,17 +11585,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_mq_open: { struct mq_attr posix_mq_attr; + struct mq_attr *pposix_mq_attr; int host_flags; host_flags = target_to_host_bitmask(arg2, fcntl_flags_tbl); - if (copy_from_user_mq_attr(&posix_mq_attr, arg4) != 0) { - goto efault; + pposix_mq_attr = NULL; + if (arg4) { + if (copy_from_user_mq_attr(&posix_mq_attr, arg4) != 0) { + goto efault; + } + pposix_mq_attr = &posix_mq_attr; } p = lock_user_string(arg1 - 1); if (!p) { goto efault; } - ret = get_errno(mq_open(p, host_flags, arg3, &posix_mq_attr)); + ret = get_errno(mq_open(p, host_flags, arg3, pposix_mq_attr)); unlock_user (p, arg1, 0); } break; @@ -12035,10 +12043,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, timer_t htimer = g_posix_timers[timerid]; struct itimerspec hspec_new = {{0},}, hspec_old = {{0},}; - target_to_host_itimerspec(&hspec_new, arg3); + if (target_to_host_itimerspec(&hspec_new, arg3)) { + goto efault; + } ret = get_errno( timer_settime(htimer, arg2, &hspec_new, &hspec_old)); - host_to_target_itimerspec(arg2, &hspec_old); + if (arg4 && host_to_target_itimerspec(arg4, &hspec_old)) { + goto efault; + } } break; } diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 4442c22..72ca5b1 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -1086,6 +1086,10 @@ struct target_pollfd { #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_FICLONE TARGET_IOW(0x94, 9, int) +#define TARGET_FICLONERANGE TARGET_IOW(0x94, 13, struct file_clone_range) + /* Note that the ioctl numbers claim type "long" but the actual type * used by the kernel is "int". */ diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index 2b8c0c6..24631b0 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -232,6 +232,12 @@ STRUCT(dm_target_versions, STRUCT(dm_target_msg, TYPE_ULONGLONG) /* sector */ +STRUCT(file_clone_range, + TYPE_LONGLONG, /* src_fd */ + TYPE_ULONGLONG, /* src_offset */ + TYPE_ULONGLONG, /* src_length */ + TYPE_ULONGLONG) /* dest_offset */ + STRUCT(fiemap_extent, TYPE_ULONGLONG, /* fe_logical */ TYPE_ULONGLONG, /* fe_physical */ diff --git a/net/colo-compare.c b/net/colo-compare.c index 4962976..162fd6a 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -101,6 +101,15 @@ static int compare_chr_send(CharBackend *out, const uint8_t *buf, uint32_t size); +static gint seq_sorter(Packet *a, Packet *b, gpointer data) +{ + struct tcphdr *atcp, *btcp; + + atcp = (struct tcphdr *)(a->transport_header); + btcp = (struct tcphdr *)(b->transport_header); + return ntohl(atcp->th_seq) - ntohl(btcp->th_seq); +} + /* * Return 0 on success, if return -1 means the pkt * is unsupported(arp and ipv6) and will be sent later @@ -137,6 +146,11 @@ static int packet_enqueue(CompareState *s, int mode) if (g_queue_get_length(&conn->primary_list) <= MAX_QUEUE_SIZE) { g_queue_push_tail(&conn->primary_list, pkt); + if (conn->ip_proto == IPPROTO_TCP) { + g_queue_sort(&conn->primary_list, + (GCompareDataFunc)seq_sorter, + NULL); + } } else { error_report("colo compare primary queue size too big," "drop packet"); @@ -145,6 +159,11 @@ static int packet_enqueue(CompareState *s, int mode) if (g_queue_get_length(&conn->secondary_list) <= MAX_QUEUE_SIZE) { g_queue_push_tail(&conn->secondary_list, pkt); + if (conn->ip_proto == IPPROTO_TCP) { + g_queue_sort(&conn->secondary_list, + (GCompareDataFunc)seq_sorter, + NULL); + } } else { error_report("colo compare secondary queue size too big," "drop packet"); @@ -970,6 +970,7 @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp) const Netdev *netdev; const char *name; NetClientState *peer = NULL; + static bool vlan_warned; if (is_netdev) { netdev = object; @@ -1050,6 +1051,11 @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp) !opts->u.nic.data->has_netdev) { peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL); } + + if (net->has_vlan && !vlan_warned) { + error_report("'vlan' is deprecated. Please use 'netdev' instead."); + vlan_warned = true; + } } if (net_client_init_fun[netdev->type](netdev, name, peer, errp) < 0) { |