diff options
-rw-r--r-- | MAINTAINERS | 20 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | block.c | 6 | ||||
-rwxr-xr-x | configure | 3 | ||||
-rw-r--r-- | coroutine-sigaltstack.c | 2 | ||||
-rw-r--r-- | gdbstub.c | 5 | ||||
-rw-r--r-- | hw/cpu/icc_bus.c | 4 | ||||
-rw-r--r-- | hw/usb/hcd-xhci.c | 9 | ||||
-rw-r--r-- | hw/usb/host-libusb.c | 12 | ||||
-rw-r--r-- | include/block/block.h | 4 | ||||
-rw-r--r-- | include/hw/sysbus.h | 2 | ||||
-rw-r--r-- | include/sysemu/sysemu.h | 1 | ||||
-rw-r--r-- | linux-user/elfload.c | 2 | ||||
-rw-r--r-- | linux-user/syscall.c | 54 | ||||
-rw-r--r-- | linux-user/syscall_defs.h | 5 | ||||
-rw-r--r-- | monitor.c | 6 | ||||
-rw-r--r-- | net/slirp.c | 9 | ||||
-rw-r--r-- | numa.c | 38 | ||||
-rw-r--r-- | pc-bios/petalogix-s3adsp1800.dtb | bin | 8259 -> 8259 bytes | |||
-rw-r--r-- | qapi-schema.json | 9 | ||||
-rw-r--r-- | qemu-doc.texi | 4 | ||||
-rw-r--r-- | qemu-seccomp.c | 6 | ||||
-rw-r--r-- | qmp-commands.hx | 4 | ||||
-rw-r--r-- | target-i386/cpu.c | 6 | ||||
-rw-r--r-- | target-xtensa/cpu.h | 6 | ||||
-rw-r--r-- | target-xtensa/op_helper.c | 6 | ||||
-rw-r--r-- | tests/tcg/xtensa/test_windowed.S | 51 | ||||
-rw-r--r-- | ui/input.c | 15 | ||||
-rw-r--r-- | xen-hvm.c | 3 |
29 files changed, 238 insertions, 56 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index dd02d96624..bcb69e80d2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -880,6 +880,12 @@ S: Maintained F: qobject/ T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp +QEMU Guest Agent +M: Michael Roth <mdroth@linux.vnet.ibm.com> +S: Maintained +F: qga/ +T: git git://github.com/mdroth/qemu.git qga + QOM M: Anthony Liguori <aliguori@amazon.com> M: Andreas Färber <afaerber@suse.de> @@ -920,6 +926,15 @@ M: Blue Swirl <blauwirbel@gmail.com> S: Odd Fixes F: scripts/checkpatch.pl +Migration +M: Juan Quintela <quintela@redhat.com> +S: Maintained +F: include/migration/ +F: migration* +F: savevm.c +F: arch_init.c +F: vmstate.c + Seccomp M: Eduardo Otubo <eduardo.otubo@profitbricks.com> S: Supported @@ -1078,3 +1093,8 @@ M: Chrysostomos Nanakos <cnanakos@grnet.gr> M: Chrysostomos Nanakos <chris@include.gr> S: Maintained F: block/archipelago.c + +Bootdevice +M: Gonglei <arei.gonglei@huawei.com> +S: Maintained +F: bootdevice.c @@ -1 +1 @@ -2.1.90 +2.1.91 @@ -3903,9 +3903,9 @@ typedef struct BdrvCoGetBlockStatusData { } BdrvCoGetBlockStatusData; /* - * Returns true iff the specified sector is present in the disk image. Drivers - * not implementing the functionality are assumed to not support backing files, - * hence all their sectors are reported as allocated. + * Returns the allocation status of the specified sectors. + * Drivers not implementing the functionality are assumed to not support + * backing files, hence all their sectors are reported as allocated. * * If 'sector_num' is beyond the end of the disk image the return value is 0 * and 'pnum' is set to 0. @@ -1823,7 +1823,8 @@ fi # libseccomp check if test "$seccomp" != "no" ; then - if $pkg_config --atleast-version=2.1.0 libseccomp; then + if test "$cpu" = "i386" || test "$cpu" = "x86_64" && + $pkg_config --atleast-version=2.1.1 libseccomp; then libs_softmmu="$libs_softmmu `$pkg_config --libs libseccomp`" QEMU_CFLAGS="$QEMU_CFLAGS `$pkg_config --cflags libseccomp`" seccomp="yes" diff --git a/coroutine-sigaltstack.c b/coroutine-sigaltstack.c index 3de0bb33bd..63519fffc7 100644 --- a/coroutine-sigaltstack.c +++ b/coroutine-sigaltstack.c @@ -155,7 +155,7 @@ Coroutine *qemu_coroutine_new(void) stack_t oss; sigset_t sigs; sigset_t osigs; - jmp_buf old_env; + sigjmp_buf old_env; /* The way to manipulate stack is with the sigaltstack function. We * prepare a stack, with it delivering a signal to ourselves and then @@ -823,7 +823,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) action = *p++; signal = 0; if (action == 'C' || action == 'S') { - signal = strtoul(p, (char **)&p, 16); + signal = gdb_signal_to_target(strtoul(p, (char **)&p, 16)); + if (signal == -1) { + signal = 0; + } } else if (action != 'c' && action != 's') { res = 0; break; diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c index 9575fd6a42..6646ea2b34 100644 --- a/hw/cpu/icc_bus.c +++ b/hw/cpu/icc_bus.c @@ -73,11 +73,11 @@ typedef struct ICCBridgeState { MemoryRegion apic_container; } ICCBridgeState; -#define ICC_BRIGDE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE) +#define ICC_BRIDGE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE) static void icc_bridge_init(Object *obj) { - ICCBridgeState *s = ICC_BRIGDE(obj); + ICCBridgeState *s = ICC_BRIDGE(obj); SysBusDevice *sb = SYS_BUS_DEVICE(obj); qbus_create_inplace(&s->icc_bus, sizeof(s->icc_bus), TYPE_ICC_BUS, diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 2930b72c1d..9a942cfad4 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -2262,6 +2262,9 @@ static USBPort *xhci_lookup_uport(XHCIState *xhci, uint32_t *slot_ctx) int i, pos, port; port = (slot_ctx[1]>>16) & 0xFF; + if (port < 1 || port > xhci->numports) { + return NULL; + } port = xhci->ports[port-1].uport->index+1; pos = snprintf(path, sizeof(path), "%d", port); for (i = 0; i < 5; i++) { @@ -3706,6 +3709,12 @@ static int usb_xhci_post_load(void *opaque, int version_id) xhci_mask64(ldq_le_pci_dma(pci_dev, dcbaap + 8 * slotid)); xhci_dma_read_u32s(xhci, slot->ctx, slot_ctx, sizeof(slot_ctx)); slot->uport = xhci_lookup_uport(xhci, slot_ctx); + if (!slot->uport) { + /* should not happen, but may trigger on guest bugs */ + slot->enabled = 0; + slot->addressed = 0; + continue; + } assert(slot->uport && slot->uport->dev); for (epid = 1; epid <= 31; epid++) { diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index d2d161bc6e..a5f9dab0cd 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -143,6 +143,12 @@ static void usb_host_attach_kernel(USBHostDevice *s); /* ------------------------------------------------------------------------ */ +#ifndef LIBUSB_LOG_LEVEL_WARNING /* older libusb didn't define these */ +#define LIBUSB_LOG_LEVEL_WARNING 2 +#endif + +/* ------------------------------------------------------------------------ */ + #define CONTROL_TIMEOUT 10000 /* 10 sec */ #define BULK_TIMEOUT 0 /* unlimited */ #define INTR_TIMEOUT 0 /* unlimited */ @@ -743,13 +749,13 @@ static void usb_host_speed_compat(USBHostDevice *s) udev->speedmask = (1 << udev->speed); if (udev->speed == USB_SPEED_SUPER && compat_high) { - udev->speedmask |= USB_SPEED_HIGH; + udev->speedmask |= USB_SPEED_MASK_HIGH; } if (udev->speed == USB_SPEED_SUPER && compat_full) { - udev->speedmask |= USB_SPEED_FULL; + udev->speedmask |= USB_SPEED_MASK_FULL; } if (udev->speed == USB_SPEED_HIGH && compat_full) { - udev->speedmask |= USB_SPEED_FULL; + udev->speedmask |= USB_SPEED_MASK_FULL; } } diff --git a/include/block/block.h b/include/block/block.h index 13e453736c..5450610bc1 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -83,7 +83,9 @@ typedef enum { #define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS) #define BDRV_SECTOR_MASK ~(BDRV_SECTOR_SIZE - 1) -/* BDRV_BLOCK_DATA: data is read from bs->file or another file +/* + * Allocation status flags + * BDRV_BLOCK_DATA: data is read from bs->file or another file * BDRV_BLOCK_ZERO: sectors read as zero * BDRV_BLOCK_OFFSET_VALID: sector stored in bs->file as raw data * BDRV_BLOCK_ALLOCATED: the content of the block is determined by this diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h index 6175bf990a..d1f3f000f9 100644 --- a/include/hw/sysbus.h +++ b/include/hw/sysbus.h @@ -10,7 +10,7 @@ #define QDEV_MAX_PIO 32 #define TYPE_SYSTEM_BUS "System" -#define SYSTEM_BUS(obj) OBJECT_CHECK(IDEBus, (obj), TYPE_IDE_BUS) +#define SYSTEM_BUS(obj) OBJECT_CHECK(BusState, (obj), TYPE_SYSTEM_BUS) typedef struct SysBusDevice SysBusDevice; diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 6f9b82b6f3..9fea3bc3af 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -161,6 +161,7 @@ typedef struct node_info { extern NodeInfo numa_info[MAX_NODES]; void set_numa_nodes(void); void set_numa_modes(void); +void query_numa_node_mem(uint64_t node_mem[]); extern QemuOptsList qemu_numa_opts; int numa_init_func(QemuOpts *opts, void *opaque); diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 84123baa58..e2596a4201 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1824,7 +1824,7 @@ static void load_elf_image(const char *image_name, int image_fd, if (a < loaddr) { loaddr = a; } - a += phdr[i].p_memsz; + a = phdr[i].p_vaddr + phdr[i].p_memsz; if (a > hiaddr) { hiaddr = a; } diff --git a/linux-user/syscall.c b/linux-user/syscall.c index a175cc15f8..aaac6a25ce 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5473,6 +5473,27 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, return get_errno(sys_openat(dirfd, path(pathname), flags, mode)); } +#define TIMER_MAGIC 0x0caf0000 +#define TIMER_MAGIC_MASK 0xffff0000 + +/* Convert QEMU provided timer ID back to internal 16bit index format */ +static target_timer_t get_timer_id(abi_long arg) +{ + target_timer_t timerid = arg; + + if ((timerid & TIMER_MAGIC_MASK) != TIMER_MAGIC) { + return -TARGET_EINVAL; + } + + timerid &= 0xffff; + + if (timerid >= ARRAY_SIZE(g_posix_timers)) { + return -TARGET_EINVAL; + } + + return timerid; +} + /* do_syscall() should always have a single exit point at the end so that actions, such as logging of syscall results, can be performed. All errnos that do_syscall() returns must be -TARGET_<errcode>. */ @@ -9579,7 +9600,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, /* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */ struct sigevent host_sevp = { {0}, }, *phost_sevp = NULL; - struct target_timer_t *ptarget_timer; int clkid = arg1; int timer_index = next_free_host_timer(); @@ -9601,11 +9621,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (ret) { phtimer = NULL; } else { - if (!lock_user_struct(VERIFY_WRITE, ptarget_timer, arg3, 1)) { + if (put_user(TIMER_MAGIC | timer_index, arg3, target_timer_t)) { goto efault; } - ptarget_timer->ptr = tswap32(0xcafe0000 | timer_index); - unlock_user_struct(ptarget_timer, arg3, 1); } } break; @@ -9617,9 +9635,11 @@ 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 */ - target_ulong timerid = arg1; + target_timer_t timerid = get_timer_id(arg1); - if (arg3 == 0 || timerid >= ARRAY_SIZE(g_posix_timers)) { + if (timerid < 0) { + ret = timerid; + } else if (arg3 == 0) { ret = -TARGET_EINVAL; } else { timer_t htimer = g_posix_timers[timerid]; @@ -9638,12 +9658,12 @@ 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 */ - target_ulong timerid = arg1; + target_timer_t timerid = get_timer_id(arg1); - if (!arg2) { - return -TARGET_EFAULT; - } else if (timerid >= ARRAY_SIZE(g_posix_timers)) { - ret = -TARGET_EINVAL; + if (timerid < 0) { + ret = timerid; + } else if (!arg2) { + ret = -TARGET_EFAULT; } else { timer_t htimer = g_posix_timers[timerid]; struct itimerspec hspec; @@ -9661,10 +9681,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_timer_getoverrun: { /* args: timer_t timerid */ - target_ulong timerid = arg1; + target_timer_t timerid = get_timer_id(arg1); - if (timerid >= ARRAY_SIZE(g_posix_timers)) { - ret = -TARGET_EINVAL; + if (timerid < 0) { + ret = timerid; } else { timer_t htimer = g_posix_timers[timerid]; ret = get_errno(timer_getoverrun(htimer)); @@ -9677,10 +9697,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_timer_delete: { /* args: timer_t timerid */ - target_ulong timerid = arg1; + target_timer_t timerid = get_timer_id(arg1); - if (timerid >= ARRAY_SIZE(g_posix_timers)) { - ret = -TARGET_EINVAL; + if (timerid < 0) { + ret = timerid; } else { timer_t htimer = g_posix_timers[timerid]; ret = get_errno(timer_delete(htimer)); diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index c9e6323905..ebb3be1196 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -2564,10 +2564,7 @@ struct target_ucred { #endif - -struct target_timer_t { - abi_ulong ptr; -}; +typedef int32_t target_timer_t; #define TARGET_SIGEV_MAX_SIZE 64 @@ -1948,7 +1948,10 @@ static void do_info_numa(Monitor *mon, const QDict *qdict) { int i; CPUState *cpu; + uint64_t *node_mem; + node_mem = g_new0(uint64_t, nb_numa_nodes); + query_numa_node_mem(node_mem); monitor_printf(mon, "%d nodes\n", nb_numa_nodes); for (i = 0; i < nb_numa_nodes; i++) { monitor_printf(mon, "node %d cpus:", i); @@ -1959,8 +1962,9 @@ static void do_info_numa(Monitor *mon, const QDict *qdict) } monitor_printf(mon, "\n"); monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i, - numa_info[i].node_mem >> 20); + node_mem[i] >> 20); } + g_free(node_mem); } #ifdef CONFIG_PROFILER diff --git a/net/slirp.c b/net/slirp.c index 920af30bda..dc89e6b086 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -523,15 +523,21 @@ static int slirp_smb(SlirpState* s, const char *exported_dir, fprintf(f, "[global]\n" "private dir=%s\n" - "socket address=127.0.0.1\n" + "interfaces=127.0.0.1\n" + "bind interfaces only=yes\n" "pid directory=%s\n" "lock directory=%s\n" "state directory=%s\n" + "cache directory=%s\n" "ncalrpc dir=%s/ncalrpc\n" "log file=%s/log.smbd\n" "smb passwd file=%s/smbpasswd\n" "security = user\n" "map to guest = Bad User\n" + "load printers = no\n" + "printing = bsd\n" + "disable spoolss = yes\n" + "usershare max shares = 0\n" "[qemu]\n" "path=%s\n" "read only=no\n" @@ -544,6 +550,7 @@ static int slirp_smb(SlirpState* s, const char *exported_dir, s->smb_dir, s->smb_dir, s->smb_dir, + s->smb_dir, exported_dir, passwd->pw_name ); @@ -35,6 +35,7 @@ #include "hw/boards.h" #include "sysemu/hostmem.h" #include "qmp-commands.h" +#include "hw/mem/pc-dimm.h" QemuOptsList qemu_numa_opts = { .name = "numa", @@ -315,6 +316,43 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, } } +static void numa_stat_memory_devices(uint64_t node_mem[]) +{ + MemoryDeviceInfoList *info_list = NULL; + MemoryDeviceInfoList **prev = &info_list; + MemoryDeviceInfoList *info; + + qmp_pc_dimm_device_list(qdev_get_machine(), &prev); + for (info = info_list; info; info = info->next) { + MemoryDeviceInfo *value = info->value; + + if (value) { + switch (value->kind) { + case MEMORY_DEVICE_INFO_KIND_DIMM: + node_mem[value->dimm->node] += value->dimm->size; + break; + default: + break; + } + } + } + qapi_free_MemoryDeviceInfoList(info_list); +} + +void query_numa_node_mem(uint64_t node_mem[]) +{ + int i; + + if (nb_numa_nodes <= 0) { + return; + } + + numa_stat_memory_devices(node_mem); + for (i = 0; i < nb_numa_nodes; i++) { + node_mem[i] += numa_info[i].node_mem; + } +} + static int query_memdev(Object *obj, void *opaque) { MemdevList **list = opaque; diff --git a/pc-bios/petalogix-s3adsp1800.dtb b/pc-bios/petalogix-s3adsp1800.dtb Binary files differindex 93c5973fd8..8ac80f2f2d 100644 --- a/pc-bios/petalogix-s3adsp1800.dtb +++ b/pc-bios/petalogix-s3adsp1800.dtb diff --git a/qapi-schema.json b/qapi-schema.json index 24379ab3af..d0926d95f6 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3231,6 +3231,11 @@ # # Input event union. # +# @key: Input event of Keyboard +# @btn: Input event of pointer buttons +# @rel: Input event of relative pointer motion +# @abs: Input event of absolute pointer motion +# # Since: 2.0 ## { 'union' : 'InputEvent', @@ -3244,7 +3249,7 @@ # # Send input event(s) to guest. # -# @console: Which console to send event(s) to. +# @console: #optional console to send event(s) to. # # @events: List of InputEvent union. # @@ -3254,7 +3259,7 @@ # ## { 'command': 'input-send-event', - 'data': { 'console':'int', 'events': [ 'InputEvent' ] } } + 'data': { '*console':'int', 'events': [ 'InputEvent' ] } } ## # @NumaOptions diff --git a/qemu-doc.texi b/qemu-doc.texi index 9973090c6c..ad418f851d 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -1631,7 +1631,7 @@ EOF # certtool --generate-certificate \ --load-ca-certificate ca-cert.pem \ --load-ca-privkey ca-key.pem \ - --load-privkey server server-key.pem \ + --load-privkey server-key.pem \ --template server.info \ --outfile server-cert.pem @end example @@ -1654,7 +1654,7 @@ the secure CA private key: country = GB state = London locality = London -organiazation = Name of your organization +organization = Name of your organization cn = client.foo.example.com tls_www_client encryption_key diff --git a/qemu-seccomp.c b/qemu-seccomp.c index 0503764047..af6a375127 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -231,7 +231,11 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = { { SCMP_SYS(shmctl), 240 }, { SCMP_SYS(mlock), 240 }, { SCMP_SYS(munlock), 240 }, - { SCMP_SYS(semctl), 240 } + { SCMP_SYS(semctl), 240 }, + { SCMP_SYS(fallocate), 240 }, + { SCMP_SYS(fadvise64), 240 }, + { SCMP_SYS(inotify_init1), 240 }, + { SCMP_SYS(inotify_add_watch), 240 } }; int seccomp_start(void) diff --git a/qmp-commands.hx b/qmp-commands.hx index 1abd61977b..8812401b67 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3792,7 +3792,7 @@ EQMP { .name = "input-send-event", - .args_type = "console:i,events:q", + .args_type = "console:i?,events:q", .mhandler.cmd_new = qmp_marshal_input_input_send_event, }, @@ -3804,7 +3804,7 @@ Send input event to guest. Arguments: -- "console": console index. +- "console": console index. (json-int, optional) - "events": list of input events. The consoles are visible in the qom tree, under diff --git a/target-i386/cpu.c b/target-i386/cpu.c index fa860de55c..3f13dfe5f5 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -540,8 +540,8 @@ void host_cpuid(uint32_t function, uint32_t count, * otherwise the string is assumed to sized by a terminating nul. * Return lexical ordering of *s1:*s2. */ -static int sstrcmp(const char *s1, const char *e1, const char *s2, - const char *e2) +static int sstrcmp(const char *s1, const char *e1, + const char *s2, const char *e2) { for (;;) { if (!*s1 || !*s2 || *s1 != *s2) @@ -1859,7 +1859,7 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features, * if flags, suppress names undefined in featureset. */ static void listflags(char *buf, int bufsize, uint32_t fbits, - const char **featureset, uint32_t flags) + const char **featureset, uint32_t flags) { const char **p = &featureset[31]; char *q, *b, bit; diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index beb5486fc7..ac463f27fe 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -472,6 +472,12 @@ static inline xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env, env->itlb[wi] + ei; } +static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env) +{ + return env->sregs[WINDOW_START] | + (env->sregs[WINDOW_START] << env->config->nareg / 4); +} + /* MMU modes definitions */ #define MMU_MODE0_SUFFIX _ring0 #define MMU_MODE1_SUFFIX _ring1 diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index dae13866ef..872e5a823b 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -235,6 +235,12 @@ void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm) pc, env->sregs[PS]); HELPER(exception_cause)(env, pc, ILLEGAL_INSTRUCTION_CAUSE); } else { + uint32_t windowstart = xtensa_replicate_windowstart(env) >> + (env->sregs[WINDOW_BASE] + 1); + + if (windowstart & ((1 << callinc) - 1)) { + HELPER(window_check)(env, pc, callinc); + } env->regs[(callinc << 2) | (s & 3)] = env->regs[s] - (imm << 3); rotate_window(env, callinc); env->sregs[WINDOW_START] |= diff --git a/tests/tcg/xtensa/test_windowed.S b/tests/tcg/xtensa/test_windowed.S index 3de6d3763a..d851e8f43c 100644 --- a/tests/tcg/xtensa/test_windowed.S +++ b/tests/tcg/xtensa/test_windowed.S @@ -299,4 +299,55 @@ test entry entry_test 12 test_end +.macro entry_overflow_test window, free, next_window + set_vector window_overflow_4, 0 + set_vector window_overflow_8, 0 + set_vector window_overflow_12, 0 + set_vector window_overflow_\next_window, 10f + + movi a2, \window + movi a2, \free + movi a2, \next_window + reset_window %(1 | ((1 | (1 << ((\next_window) / 4))) << ((\free) / 4))) + reset_ps + movi a2, 0x4000f | ((\window) << 14) + wsr a2, ps + isync + movi a3, 0x12345678 + j 1f + .align 4 +1: + entry a3, 0x5678 + test_fail + .align 4 +10: + rsr a2, epc1 + movi a3, 1b + assert eq, a2, a3 + movi a2, 2f + wsr a2, epc1 + + rsr a2, windowbase + movi a3, (\free) / 4 + assert eq, a2, a3 + rfwo +2: +.endm + +.macro all_entry_overflow_tests + .irp window, 4, 8, 12 + .irp next_window, 4, 8, 12 + .irp free, 4, 8, 12 + .if \free <= \window + entry_overflow_test \window, \free, \next_window + .endif + .endr + .endr + .endr +.endm + +test entry_overflow + all_entry_overflow_tests +test_end + test_suite_end diff --git a/ui/input.c b/ui/input.c index 002831ee72..37ff46fc55 100644 --- a/ui/input.c +++ b/ui/input.c @@ -122,16 +122,19 @@ qemu_input_find_handler(uint32_t mask, QemuConsole *con) return NULL; } -void qmp_input_send_event(int64_t console, InputEventList *events, - Error **errp) +void qmp_input_send_event(bool has_console, int64_t console, + InputEventList *events, Error **errp) { InputEventList *e; QemuConsole *con; - con = qemu_console_lookup_by_index(console); - if (!con) { - error_setg(errp, "console %" PRId64 " not found", console); - return; + con = NULL; + if (has_console) { + con = qemu_console_lookup_by_index(console); + if (!con) { + error_setg(errp, "console %" PRId64 " not found", console); + return; + } } if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { @@ -993,9 +993,8 @@ static void xen_main_loop_prepare(XenIOState *state) static void xen_hvm_change_state_handler(void *opaque, int running, RunState rstate) { - XenIOState *xstate = opaque; if (running) { - xen_main_loop_prepare(xstate); + xen_main_loop_prepare((XenIOState *)opaque); } } |