Merge remote-tracking branch 'mjt/trivial-patches' into staging
# By Christophe Lyon (1) and others
# Via Michael Tokarev
* mjt/trivial-patches:
target-moxie: replace target_phys_addr_t with hwaddr
Rename hexdump to avoid FreeBSD libutil conflict
remove some double-includes
translate: remove redundantly included qemu/timer.h
Remove twice include of qemu-common.h
fix /proc/self/maps output
Message-id: 51977B44.1000302@msgid.tls.msk.ru
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff --git a/VERSION b/VERSION
index 80fd6ef..88eb60e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.4.93
+1.5.50
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index c1e08ec..ff85590 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -1026,6 +1026,21 @@
}
}
+static void assigned_dev_update_msi_msg(PCIDevice *pci_dev)
+{
+ AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
+ uint8_t ctrl_byte = pci_get_byte(pci_dev->config + pci_dev->msi_cap +
+ PCI_MSI_FLAGS);
+
+ if (assigned_dev->assigned_irq_type != ASSIGNED_IRQ_MSI ||
+ !(ctrl_byte & PCI_MSI_FLAGS_ENABLE)) {
+ return;
+ }
+
+ kvm_irqchip_update_msi_route(kvm_state, assigned_dev->msi_virq[0],
+ msi_get_message(pci_dev, 0));
+}
+
static bool assigned_dev_msix_masked(MSIXTableEntry *entry)
{
return (entry->ctrl & cpu_to_le32(0x1)) != 0;
@@ -1201,6 +1216,9 @@
if (range_covers_byte(address, len,
pci_dev->msi_cap + PCI_MSI_FLAGS)) {
assigned_dev_update_msi(pci_dev);
+ } else if (ranges_overlap(address, len, /* 32bit MSI only */
+ pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, 6)) {
+ assigned_dev_update_msi_msg(pci_dev);
}
}
if (assigned_dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) {
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index bf12a10..e1e4f41 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -144,7 +144,7 @@
break;
case IDE_DMA_TRIM:
m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,
- ide_issue_trim, pmac_ide_transfer_cb, s,
+ ide_issue_trim, pmac_ide_transfer_cb, io,
DMA_DIRECTION_TO_DEVICE);
break;
}
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index bed0822..1ea9556 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -359,6 +359,34 @@
return features;
}
+static void virtio_net_apply_guest_offloads(VirtIONet *n)
+{
+ tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)),
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_ECN)),
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)));
+}
+
+static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
+{
+ static const uint64_t guest_offloads_mask =
+ (1ULL << VIRTIO_NET_F_GUEST_CSUM) |
+ (1ULL << VIRTIO_NET_F_GUEST_TSO4) |
+ (1ULL << VIRTIO_NET_F_GUEST_TSO6) |
+ (1ULL << VIRTIO_NET_F_GUEST_ECN) |
+ (1ULL << VIRTIO_NET_F_GUEST_UFO);
+
+ return guest_offloads_mask & features;
+}
+
+static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(n);
+ return virtio_net_guest_offloads_by_features(vdev->guest_features);
+}
+
static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
{
VirtIONet *n = VIRTIO_NET(vdev);
@@ -369,12 +397,9 @@
virtio_net_set_mrg_rx_bufs(n, !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)));
if (n->has_vnet_hdr) {
- tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
- (features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
- (features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
- (features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
- (features >> VIRTIO_NET_F_GUEST_ECN) & 1,
- (features >> VIRTIO_NET_F_GUEST_UFO) & 1);
+ n->curr_guest_offloads =
+ virtio_net_guest_offloads_by_features(features);
+ virtio_net_apply_guest_offloads(n);
}
for (i = 0; i < n->max_queues; i++) {
@@ -420,6 +445,43 @@
return VIRTIO_NET_OK;
}
+static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
+ struct iovec *iov, unsigned int iov_cnt)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(n);
+ uint64_t offloads;
+ size_t s;
+
+ if (!((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features)) {
+ return VIRTIO_NET_ERR;
+ }
+
+ s = iov_to_buf(iov, iov_cnt, 0, &offloads, sizeof(offloads));
+ if (s != sizeof(offloads)) {
+ return VIRTIO_NET_ERR;
+ }
+
+ if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) {
+ uint64_t supported_offloads;
+
+ if (!n->has_vnet_hdr) {
+ return VIRTIO_NET_ERR;
+ }
+
+ supported_offloads = virtio_net_supported_guest_offloads(n);
+ if (offloads & ~supported_offloads) {
+ return VIRTIO_NET_ERR;
+ }
+
+ n->curr_guest_offloads = offloads;
+ virtio_net_apply_guest_offloads(n);
+
+ return VIRTIO_NET_OK;
+ } else {
+ return VIRTIO_NET_ERR;
+ }
+}
+
static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd,
struct iovec *iov, unsigned int iov_cnt)
{
@@ -590,6 +652,8 @@
status = virtio_net_handle_vlan_table(n, ctrl.cmd, iov, iov_cnt);
} else if (ctrl.class == VIRTIO_NET_CTRL_MQ) {
status = virtio_net_handle_mq(n, ctrl.cmd, iov, iov_cnt);
+ } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) {
+ status = virtio_net_handle_offloads(n, ctrl.cmd, iov, iov_cnt);
}
s = iov_from_buf(elem.in_sg, elem.in_num, 0, &status, sizeof(status));
@@ -1110,6 +1174,10 @@
qemu_put_be32(f, n->vqs[i].tx_waiting);
}
}
+
+ if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+ qemu_put_be64(f, n->curr_guest_offloads);
+ }
}
static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
@@ -1167,15 +1235,6 @@
error_report("virtio-net: saved image requires vnet_hdr=on");
return -1;
}
-
- if (n->has_vnet_hdr) {
- tap_set_offload(qemu_get_queue(n->nic)->peer,
- (vdev->guest_features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
- (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
- (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
- (vdev->guest_features >> VIRTIO_NET_F_GUEST_ECN) & 1,
- (vdev->guest_features >> VIRTIO_NET_F_GUEST_UFO) & 1);
- }
}
if (version_id >= 9) {
@@ -1209,6 +1268,16 @@
}
}
+ if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+ n->curr_guest_offloads = qemu_get_be64(f);
+ } else {
+ n->curr_guest_offloads = virtio_net_supported_guest_offloads(n);
+ }
+
+ if (peer_has_vnet_hdr(n)) {
+ virtio_net_apply_guest_offloads(n);
+ }
+
virtio_net_set_queues(n);
/* Find the first multicast entry in the saved MAC filter */
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 1a7e49c..479113b 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -54,7 +54,7 @@
#define JPG_FILE 0
#define BMP_FILE 1
-static char *read_splashfile(char *filename, size_t *file_sizep,
+static char *read_splashfile(char *filename, gsize *file_sizep,
int *file_typep)
{
GError *err = NULL;
@@ -112,7 +112,7 @@
const char *boot_splash_filename = NULL;
char *p;
char *filename, *file_data;
- size_t file_size;
+ gsize file_size;
int file_type;
const char *temp;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 740cf49..663426c 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -216,6 +216,10 @@
.property = "vectors",\
/* DEV_NVECTORS_UNSPECIFIED as a uint32_t string */\
.value = stringify(0xFFFFFFFF),\
+ },{ \
+ .driver = "virtio-net-pci", \
+ .property = "ctrl_guest_offloads", \
+ .value = "off", \
},{\
.driver = "e1000",\
.property = "romfile",\
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index beeead7..b315ac9 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -31,6 +31,8 @@
/* The feature bitmap for virtio net */
#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */
#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */
+#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Control channel offload
+ * configuration support */
#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */
#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */
#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */
@@ -190,6 +192,7 @@
size_t config_size;
char *netclient_name;
char *netclient_type;
+ uint64_t curr_guest_offloads;
} VirtIONet;
#define VIRTIO_NET_CTRL_MAC 1
@@ -229,6 +232,15 @@
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000
+/*
+ * Control network offloads
+ *
+ * Dynamic offloads are available with the
+ * VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature bit.
+ */
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
+ #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
+
#define DEFINE_VIRTIO_NET_FEATURES(_state, _field) \
DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
DEFINE_PROP_BIT("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \
@@ -249,6 +261,7 @@
DEFINE_PROP_BIT("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
DEFINE_PROP_BIT("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true), \
DEFINE_PROP_BIT("ctrl_mac_addr", _state, _field, VIRTIO_NET_F_CTRL_MAC_ADDR, true), \
+ DEFINE_PROP_BIT("ctrl_guest_offloads", _state, _field, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, true), \
DEFINE_PROP_BIT("mq", _state, _field, VIRTIO_NET_F_MQ, false)
#define DEFINE_VIRTIO_NET_PROPERTIES(_state, _field) \
diff --git a/include/qemu-common.h b/include/qemu-common.h
index b9057d1..cb82ef3 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -45,6 +45,7 @@
#if defined(__GLIBC__)
# include <pty.h>
#elif defined CONFIG_BSD
+# include <termios.h>
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
# include <libutil.h>
# else
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 1055507..5da8452 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2528,7 +2528,8 @@
int err = 0;
int i;
- err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
+ err |= __put_user(exception_resume_pc(regs), &sc->sc_pc);
+ regs->hflags &= ~MIPS_HFLAG_BMASK;
__put_user(0, &sc->sc_regs[0]);
for (i = 1; i < 32; ++i) {
@@ -2620,6 +2621,15 @@
return (sp - frame_size) & ~7;
}
+static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
+{
+ if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
+ env->hflags &= ~MIPS_HFLAG_M16;
+ env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
+ env->active_tc.PC &= ~(target_ulong) 1;
+ }
+}
+
# if defined(TARGET_ABI_MIPSO32)
/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
static void setup_frame(int sig, struct target_sigaction * ka,
@@ -2662,6 +2672,7 @@
* since it returns to userland using eret
* we cannot do this here, and we must set PC directly */
regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
+ mips_set_hflags_isa_mode_from_pc(regs);
unlock_user_struct(frame, frame_addr, 1);
return;
@@ -2709,6 +2720,7 @@
#endif
regs->active_tc.PC = regs->CP0_EPC;
+ mips_set_hflags_isa_mode_from_pc(regs);
/* I am not sure this is right, but it seems to work
* maybe a problem with nested signals ? */
regs->CP0_EPC = 0;
@@ -2771,6 +2783,7 @@
* since it returns to userland using eret
* we cannot do this here, and we must set PC directly */
env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
+ mips_set_hflags_isa_mode_from_pc(env);
unlock_user_struct(frame, frame_addr, 1);
return;
@@ -2804,6 +2817,7 @@
goto badframe;
env->active_tc.PC = env->CP0_EPC;
+ mips_set_hflags_isa_mode_from_pc(env);
/* I am not sure this is right, but it seems to work
* maybe a problem with nested signals ? */
env->CP0_EPC = 0;
diff --git a/qapi-schema.json b/qapi-schema.json
index 199744a..664b31f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3210,7 +3210,7 @@
'*telnet' : 'bool' } }
##
-# @ChardevDgram:
+# @ChardevUdp:
#
# Configuration info for datagram socket chardevs.
#
@@ -3219,8 +3219,8 @@
#
# Since: 1.5
##
-{ 'type': 'ChardevDgram', 'data': { 'remote' : 'SocketAddress',
- '*local' : 'SocketAddress' } }
+{ 'type': 'ChardevUdp', 'data': { 'remote' : 'SocketAddress',
+ '*local' : 'SocketAddress' } }
##
# @ChardevMux:
@@ -3286,7 +3286,7 @@
'*rows' : 'int' } }
##
-# @ChardevRingbuf:
+# @ChardevMemory:
#
# Configuration info for memory chardevs
#
@@ -3294,7 +3294,7 @@
#
# Since: 1.5
##
-{ 'type': 'ChardevRingbuf', 'data': { '*size' : 'int' } }
+{ 'type': 'ChardevMemory', 'data': { '*size' : 'int' } }
##
# @ChardevBackend:
@@ -3310,7 +3310,7 @@
'parallel': 'ChardevHostdev',
'pipe' : 'ChardevHostdev',
'socket' : 'ChardevSocket',
- 'dgram' : 'ChardevDgram',
+ 'udp' : 'ChardevUdp',
'pty' : 'ChardevDummy',
'null' : 'ChardevDummy',
'mux' : 'ChardevMux',
@@ -3321,7 +3321,7 @@
'spicevmc' : 'ChardevSpiceChannel',
'spiceport' : 'ChardevSpicePort',
'vc' : 'ChardevVC',
- 'memory' : 'ChardevRingbuf' } }
+ 'memory' : 'ChardevMemory' } }
##
# @ChardevReturn:
diff --git a/qemu-char.c b/qemu-char.c
index 30a2ddf..4f8382e 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2875,8 +2875,8 @@
chr->opaque = NULL;
}
-static CharDriverState *qemu_chr_open_ringbuf(ChardevRingbuf *opts,
- Error **errp)
+static CharDriverState *qemu_chr_open_memory(ChardevMemory *opts,
+ Error **errp)
{
CharDriverState *chr;
RingBufCharDriver *d;
@@ -2888,7 +2888,7 @@
/* The size must be power of 2 */
if (d->size & (d->size - 1)) {
- error_setg(errp, "size of ringbuf chardev must be power of two");
+ error_setg(errp, "size of memory chardev must be power of two");
goto fail;
}
@@ -2920,7 +2920,7 @@
CharDriverState *chr;
const uint8_t *write_data;
int ret;
- size_t write_count;
+ gsize write_count;
chr = qemu_chr_find(device);
if (!chr) {
@@ -3190,12 +3190,12 @@
backend->pipe->device = g_strdup(device);
}
-static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
- Error **errp)
+static void qemu_chr_parse_memory(QemuOpts *opts, ChardevBackend *backend,
+ Error **errp)
{
int val;
- backend->memory = g_new0(ChardevRingbuf, 1);
+ backend->memory = g_new0(ChardevMemory, 1);
val = qemu_opt_get_number(opts, "size", 0);
if (val != 0) {
@@ -3276,6 +3276,7 @@
ChardevReturn *ret = NULL;
const char *id = qemu_opts_id(opts);
const char *bid = NULL;
+ char *filename = g_strdup(qemu_opt_get(opts, "backend"));
if (qemu_opt_get_bool(opts, "mux", 0)) {
bid = g_strdup_printf("%s-base", id);
@@ -3308,6 +3309,7 @@
}
chr = qemu_chr_find(id);
+ chr->filename = filename;
qapi_out:
qapi_free_ChardevBackend(backend);
@@ -3698,12 +3700,12 @@
is_telnet, is_waitconnect, errp);
}
-static CharDriverState *qmp_chardev_open_dgram(ChardevDgram *dgram,
- Error **errp)
+static CharDriverState *qmp_chardev_open_udp(ChardevUdp *udp,
+ Error **errp)
{
int fd;
- fd = socket_dgram(dgram->remote, dgram->local, errp);
+ fd = socket_dgram(udp->remote, udp->local, errp);
if (error_is_set(errp)) {
return NULL;
}
@@ -3739,8 +3741,8 @@
case CHARDEV_BACKEND_KIND_SOCKET:
chr = qmp_chardev_open_socket(backend->socket, errp);
break;
- case CHARDEV_BACKEND_KIND_DGRAM:
- chr = qmp_chardev_open_dgram(backend->dgram, errp);
+ case CHARDEV_BACKEND_KIND_UDP:
+ chr = qmp_chardev_open_udp(backend->udp, errp);
break;
#ifdef HAVE_CHARDEV_TTY
case CHARDEV_BACKEND_KIND_PTY:
@@ -3787,7 +3789,7 @@
chr = vc_init(backend->vc);
break;
case CHARDEV_BACKEND_KIND_MEMORY:
- chr = qemu_chr_open_ringbuf(backend->memory, errp);
+ chr = qemu_chr_open_memory(backend->memory, errp);
break;
default:
error_setg(errp, "unknown chardev backend (%d)", backend->kind);
@@ -3832,7 +3834,7 @@
register_char_driver("socket", qemu_chr_open_socket);
register_char_driver("udp", qemu_chr_open_udp);
register_char_driver_qapi("memory", CHARDEV_BACKEND_KIND_MEMORY,
- qemu_chr_parse_ringbuf);
+ qemu_chr_parse_memory);
register_char_driver_qapi("file", CHARDEV_BACKEND_KIND_FILE,
qemu_chr_parse_file_out);
register_char_driver_qapi("stdio", CHARDEV_BACKEND_KIND_STDIO,
diff --git a/qemu-options.hx b/qemu-options.hx
index fb62b75..fb3961d 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1779,7 +1779,7 @@
"-chardev msmouse,id=id[,mux=on|off]\n"
"-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]\n"
" [,mux=on|off]\n"
- "-chardev ringbuf,id=id[,size=size]\n"
+ "-chardev memory,id=id[,size=size]\n"
"-chardev file,id=id,path=path[,mux=on|off]\n"
"-chardev pipe,id=id,path=path[,mux=on|off]\n"
#ifdef _WIN32
@@ -1817,7 +1817,7 @@
@option{udp},
@option{msmouse},
@option{vc},
-@option{ringbuf},
+@option{memory},
@option{file},
@option{pipe},
@option{console},
@@ -1926,7 +1926,7 @@
@option{cols} and @option{rows} specify that the console be sized to fit a text
console with the given dimensions.
-@item -chardev ringbuf ,id=@var{id} [,size=@var{size}]
+@item -chardev memory ,id=@var{id} [,size=@var{size}]
Create a ring buffer with fixed size @option{size}.
@var{size} must be a power of two, and defaults to @code{64K}).
diff --git a/qom/object.c b/qom/object.c
index ec88231..803b94b 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -442,7 +442,7 @@
int i;
Object *inst;
- for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) {
+ for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
if (obj->class->cast_cache[i] == typename) {
goto out;
}
@@ -458,7 +458,7 @@
assert(obj == inst);
- if (obj == inst) {
+ if (obj && obj == inst) {
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
obj->class->cast_cache[i - 1] = obj->class->cast_cache[i];
}
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index cedf03d..6e761e0 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -668,6 +668,7 @@
hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address,
int rw);
#endif
+target_ulong exception_resume_pc (CPUMIPSState *env);
static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index a55f866..4116de9 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -19,6 +19,7 @@
#include "cpu.h"
#include "helper.h"
+#include "qemu/bitops.h"
/* As the byte ordering doesn't matter, i.e. all columns are treated
identically, these unions can be used directly. */
@@ -53,9 +54,10 @@
env->active_tc.DSPControl |= (target_ulong)flag << position;
}
-static inline void set_DSPControl_carryflag(uint32_t flag, CPUMIPSState *env)
+static inline void set_DSPControl_carryflag(bool flag, CPUMIPSState *env)
{
- env->active_tc.DSPControl |= (target_ulong)flag << 13;
+ env->active_tc.DSPControl &= ~(1 << 13);
+ env->active_tc.DSPControl |= flag << 13;
}
static inline uint32_t get_DSPControl_carryflag(CPUMIPSState *env)
@@ -90,10 +92,10 @@
dspc = env->active_tc.DSPControl;
#ifndef TARGET_MIPS64
dspc = dspc & 0xFFFFFFC0;
- dspc |= pos;
+ dspc |= (pos & 0x3F);
#else
dspc = dspc & 0xFFFFFF80;
- dspc |= pos;
+ dspc |= (pos & 0x7F);
#endif
env->active_tc.DSPControl = dspc;
}
@@ -1266,7 +1268,7 @@
target_ulong helper_addsc(target_ulong rs, target_ulong rt, CPUMIPSState *env)
{
uint64_t temp, tempRs, tempRt;
- int32_t flag;
+ bool flag;
tempRs = (uint64_t)rs & MIPSDSP_LLO;
tempRt = (uint64_t)rt & MIPSDSP_LLO;
@@ -2900,13 +2902,13 @@
return (target_ulong)rd;
}
-#define BIT_INSV(name, posfilter, sizefilter, ret_type) \
+#define BIT_INSV(name, posfilter, ret_type) \
target_ulong helper_##name(CPUMIPSState *env, target_ulong rs, \
target_ulong rt) \
{ \
uint32_t pos, size, msb, lsb; \
- target_ulong filter; \
- target_ulong temp, temprs, temprt; \
+ uint32_t const sizefilter = 0x3F; \
+ target_ulong temp; \
target_ulong dspc; \
\
dspc = env->active_tc.DSPControl; \
@@ -2921,18 +2923,14 @@
return rt; \
} \
\
- filter = ((int64_t)0x01 << size) - 1; \
- filter = filter << pos; \
- temprs = (rs << pos) & filter; \
- temprt = rt & ~filter; \
- temp = temprs | temprt; \
+ temp = deposit64(rt, pos, size, rs); \
\
return (target_long)(ret_type)temp; \
}
-BIT_INSV(insv, 0x1F, 0x3F, int32_t);
+BIT_INSV(insv, 0x1F, int32_t);
#ifdef TARGET_MIPS64
-BIT_INSV(dinsv, 0x7F, 0x3F, target_long);
+BIT_INSV(dinsv, 0x7F, target_long);
#endif
#undef BIT_INSV
@@ -3439,10 +3437,9 @@
if (sub >= -1) {
acc = ((uint64_t)env->active_tc.HI[ac] << 32) |
((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
- temp = (acc >> (start_pos - size)) &
- (((uint32_t)0x01 << (size + 1)) - 1);
+ temp = extract64(acc, start_pos - size, size + 1);
- set_DSPControl_pos(start_pos - (size + 1), env);
+ set_DSPControl_pos(sub, env);
set_DSPControl_efi(0, env);
} else {
set_DSPControl_efi(1, env);
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 3a54acf..36929dd 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -366,8 +366,7 @@
[EXCP_CACHE] = "cache error",
};
-#if !defined(CONFIG_USER_ONLY)
-static target_ulong exception_resume_pc (CPUMIPSState *env)
+target_ulong exception_resume_pc (CPUMIPSState *env)
{
target_ulong bad_pc;
target_ulong isa_mode;
@@ -383,6 +382,7 @@
return bad_pc;
}
+#if !defined(CONFIG_USER_ONLY)
static void set_hflags_for_handler (CPUMIPSState *env)
{
/* Exception handlers are entered in 32-bit mode. */
diff --git a/tests/tcg/mips/mips32-dsp/extpdp.c b/tests/tcg/mips/mips32-dsp/extpdp.c
index 15ba082..79ee16e 100644
--- a/tests/tcg/mips/mips32-dsp/extpdp.c
+++ b/tests/tcg/mips/mips32-dsp/extpdp.c
@@ -42,5 +42,23 @@
efi = (dsp >> 14) & 0x01;
assert(efi == 1);
+
+ ach = 0;
+ acl = 0;
+ dsp = 0;
+ result = 0;
+
+ __asm
+ ("wrdsp %1\n\t"
+ "mthi %2, $ac1\n\t"
+ "mtlo %3, $ac1\n\t"
+ "extpdp %0, $ac1, 0x00\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rt), "+r"(dsp)
+ : "r"(ach), "r"(acl)
+ );
+ assert(dsp == 0x3F);
+ assert(result == rt);
+
return 0;
}
diff --git a/trace-events b/trace-events
index c03b9cb..9c73931 100644
--- a/trace-events
+++ b/trace-events
@@ -34,7 +34,7 @@
qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
qemu_anon_ram_alloc(size_t size, void *ptr) "size %zu ptr %p"
qemu_vfree(void *ptr) "ptr %p"
-qemu_anon_ram_free(void *ptr, size_t size) "size %zu ptr %p"
+qemu_anon_ram_free(void *ptr, size_t size) "ptr %p size %zu"
# hw/virtio.c
virtqueue_fill(void *vq, const void *elem, unsigned int len, unsigned int idx) "vq %p elem %p len %u idx %u"
diff --git a/vl.c b/vl.c
index be0a93c..59dc0b4 100644
--- a/vl.c
+++ b/vl.c
@@ -609,6 +609,7 @@
{ RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED },
+ { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_MAX, RUN_STATE_MAX },
};