Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging
Pull request
These two .can_receive() are now reviewed. The net subsystem queue for 2.4 is now empty.
# gpg: Signature made Tue Jul 28 13:26:03 2015 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>"
* remotes/stefanha/tags/net-pull-request:
xen: Drop net_rx_ok
hw/net: handle flow control in mcf_fec driver receiver
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/.gitignore b/.gitignore
index aed0e1f..61bc492 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,8 @@
/trace/generated-tcg-tracers.h
/trace/generated-ust-provider.h
/trace/generated-ust.c
+/ui/shader/texture-blit-frag.h
+/ui/shader/texture-blit-vert.h
/libcacard/trace/generated-tracers.c
*-timestamp
/*-softmmu
diff --git a/Makefile b/Makefile
index c9be643..340d9c8 100644
--- a/Makefile
+++ b/Makefile
@@ -135,7 +135,7 @@
else \
mv $@.tmp $@; \
cp -p $@ $@.old; \
- fi, " GEN $@");
+ fi, " GEN $@");
defconfig:
rm -f config-all-devices.mak $(SUBDIR_DEVICES_MAK)
diff --git a/block/sheepdog.c b/block/sheepdog.c
index bd7cbed..9585beb 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -318,6 +318,10 @@
AIOCB_DISCARD_OBJ,
};
+#define AIOCBOverwrapping(x, y) \
+ (!(x->max_affect_data_idx < y->min_affect_data_idx \
+ || y->max_affect_data_idx < x->min_affect_data_idx))
+
struct SheepdogAIOCB {
BlockAIOCB common;
@@ -334,6 +338,11 @@
bool cancelable;
int nr_pending;
+
+ uint32_t min_affect_data_idx;
+ uint32_t max_affect_data_idx;
+
+ QLIST_ENTRY(SheepdogAIOCB) aiocb_siblings;
};
typedef struct BDRVSheepdogState {
@@ -362,8 +371,10 @@
/* Every aio request must be linked to either of these queues. */
QLIST_HEAD(inflight_aio_head, AIOReq) inflight_aio_head;
- QLIST_HEAD(pending_aio_head, AIOReq) pending_aio_head;
QLIST_HEAD(failed_aio_head, AIOReq) failed_aio_head;
+
+ CoQueue overwrapping_queue;
+ QLIST_HEAD(inflight_aiocb_head, SheepdogAIOCB) inflight_aiocb_head;
} BDRVSheepdogState;
static const char * sd_strerror(int err)
@@ -498,13 +509,7 @@
AIOReq *aioreq, *next;
if (sd_acb_cancelable(acb)) {
- /* Remove outstanding requests from pending and failed queues. */
- QLIST_FOREACH_SAFE(aioreq, &s->pending_aio_head, aio_siblings,
- next) {
- if (aioreq->aiocb == acb) {
- free_aio_req(s, aioreq);
- }
- }
+ /* Remove outstanding requests from failed queue. */
QLIST_FOREACH_SAFE(aioreq, &s->failed_aio_head, aio_siblings,
next) {
if (aioreq->aiocb == acb) {
@@ -529,6 +534,10 @@
int64_t sector_num, int nb_sectors)
{
SheepdogAIOCB *acb;
+ uint32_t object_size;
+ BDRVSheepdogState *s = bs->opaque;
+
+ object_size = (UINT32_C(1) << s->inode.block_size_shift);
acb = qemu_aio_get(&sd_aiocb_info, bs, NULL, NULL);
@@ -542,6 +551,11 @@
acb->coroutine = qemu_coroutine_self();
acb->ret = 0;
acb->nr_pending = 0;
+
+ acb->min_affect_data_idx = acb->sector_num * BDRV_SECTOR_SIZE / object_size;
+ acb->max_affect_data_idx = (acb->sector_num * BDRV_SECTOR_SIZE +
+ acb->nb_sectors * BDRV_SECTOR_SIZE) / object_size;
+
return acb;
}
@@ -703,38 +717,6 @@
static int get_sheep_fd(BDRVSheepdogState *s, Error **errp);
static void co_write_request(void *opaque);
-static AIOReq *find_pending_req(BDRVSheepdogState *s, uint64_t oid)
-{
- AIOReq *aio_req;
-
- QLIST_FOREACH(aio_req, &s->pending_aio_head, aio_siblings) {
- if (aio_req->oid == oid) {
- return aio_req;
- }
- }
-
- return NULL;
-}
-
-/*
- * This function searchs pending requests to the object `oid', and
- * sends them.
- */
-static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid)
-{
- AIOReq *aio_req;
- SheepdogAIOCB *acb;
-
- while ((aio_req = find_pending_req(s, oid)) != NULL) {
- acb = aio_req->aiocb;
- /* move aio_req from pending list to inflight one */
- QLIST_REMOVE(aio_req, aio_siblings);
- QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
- add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
- acb->aiocb_type);
- }
-}
-
static coroutine_fn void reconnect_to_sdog(void *opaque)
{
BDRVSheepdogState *s = opaque;
@@ -840,12 +822,6 @@
s->max_dirty_data_idx = MAX(idx, s->max_dirty_data_idx);
s->min_dirty_data_idx = MIN(idx, s->min_dirty_data_idx);
}
- /*
- * Some requests may be blocked because simultaneous
- * create requests are not allowed, so we search the
- * pending requests here.
- */
- send_pending_req(s, aio_req->oid);
}
break;
case AIOCB_READ_UDATA:
@@ -1341,30 +1317,6 @@
return ret;
}
-/* Return true if the specified request is linked to the pending list. */
-static bool check_simultaneous_create(BDRVSheepdogState *s, AIOReq *aio_req)
-{
- AIOReq *areq;
- QLIST_FOREACH(areq, &s->inflight_aio_head, aio_siblings) {
- if (areq != aio_req && areq->oid == aio_req->oid) {
- /*
- * Sheepdog cannot handle simultaneous create requests to the same
- * object, so we cannot send the request until the previous request
- * finishes.
- */
- DPRINTF("simultaneous create to %" PRIx64 "\n", aio_req->oid);
- aio_req->flags = 0;
- aio_req->base_oid = 0;
- aio_req->create = false;
- QLIST_REMOVE(aio_req, aio_siblings);
- QLIST_INSERT_HEAD(&s->pending_aio_head, aio_req, aio_siblings);
- return true;
- }
- }
-
- return false;
-}
-
static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
{
SheepdogAIOCB *acb = aio_req->aiocb;
@@ -1379,10 +1331,6 @@
goto out;
}
- if (check_simultaneous_create(s, aio_req)) {
- return;
- }
-
if (s->inode.data_vdi_id[idx]) {
aio_req->base_oid = vid_to_data_oid(s->inode.data_vdi_id[idx], idx);
aio_req->flags |= SD_FLAG_CMD_COW;
@@ -1458,8 +1406,8 @@
filename = qemu_opt_get(opts, "filename");
QLIST_INIT(&s->inflight_aio_head);
- QLIST_INIT(&s->pending_aio_head);
QLIST_INIT(&s->failed_aio_head);
+ QLIST_INIT(&s->inflight_aiocb_head);
s->fd = -1;
memset(vdi, 0, sizeof(vdi));
@@ -1524,6 +1472,7 @@
bs->total_sectors = s->inode.vdi_size / BDRV_SECTOR_SIZE;
pstrcpy(s->name, sizeof(s->name), vdi);
qemu_co_mutex_init(&s->lock);
+ qemu_co_queue_init(&s->overwrapping_queue);
qemu_opts_del(opts);
g_free(buf);
return 0;
@@ -2195,12 +2144,6 @@
old_oid, done);
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
- if (create) {
- if (check_simultaneous_create(s, aio_req)) {
- goto done;
- }
- }
-
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
acb->aiocb_type);
done:
@@ -2215,6 +2158,20 @@
return 1;
}
+static bool check_overwrapping_aiocb(BDRVSheepdogState *s, SheepdogAIOCB *aiocb)
+{
+ SheepdogAIOCB *cb;
+
+ QLIST_FOREACH(cb, &s->inflight_aiocb_head, aiocb_siblings) {
+ if (AIOCBOverwrapping(aiocb, cb)) {
+ return true;
+ }
+ }
+
+ QLIST_INSERT_HEAD(&s->inflight_aiocb_head, aiocb, aiocb_siblings);
+ return false;
+}
+
static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov)
{
@@ -2234,14 +2191,25 @@
acb->aio_done_func = sd_write_done;
acb->aiocb_type = AIOCB_WRITE_UDATA;
+retry:
+ if (check_overwrapping_aiocb(s, acb)) {
+ qemu_co_queue_wait(&s->overwrapping_queue);
+ goto retry;
+ }
+
ret = sd_co_rw_vector(acb);
if (ret <= 0) {
+ QLIST_REMOVE(acb, aiocb_siblings);
+ qemu_co_queue_restart_all(&s->overwrapping_queue);
qemu_aio_unref(acb);
return ret;
}
qemu_coroutine_yield();
+ QLIST_REMOVE(acb, aiocb_siblings);
+ qemu_co_queue_restart_all(&s->overwrapping_queue);
+
return acb->ret;
}
@@ -2250,19 +2218,30 @@
{
SheepdogAIOCB *acb;
int ret;
+ BDRVSheepdogState *s = bs->opaque;
acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors);
acb->aiocb_type = AIOCB_READ_UDATA;
acb->aio_done_func = sd_finish_aiocb;
+retry:
+ if (check_overwrapping_aiocb(s, acb)) {
+ qemu_co_queue_wait(&s->overwrapping_queue);
+ goto retry;
+ }
+
ret = sd_co_rw_vector(acb);
if (ret <= 0) {
+ QLIST_REMOVE(acb, aiocb_siblings);
+ qemu_co_queue_restart_all(&s->overwrapping_queue);
qemu_aio_unref(acb);
return ret;
}
qemu_coroutine_yield();
+ QLIST_REMOVE(acb, aiocb_siblings);
+ qemu_co_queue_restart_all(&s->overwrapping_queue);
return acb->ret;
}
@@ -2610,14 +2589,25 @@
acb->aiocb_type = AIOCB_DISCARD_OBJ;
acb->aio_done_func = sd_finish_aiocb;
+retry:
+ if (check_overwrapping_aiocb(s, acb)) {
+ qemu_co_queue_wait(&s->overwrapping_queue);
+ goto retry;
+ }
+
ret = sd_co_rw_vector(acb);
if (ret <= 0) {
+ QLIST_REMOVE(acb, aiocb_siblings);
+ qemu_co_queue_restart_all(&s->overwrapping_queue);
qemu_aio_unref(acb);
return ret;
}
qemu_coroutine_yield();
+ QLIST_REMOVE(acb, aiocb_siblings);
+ qemu_co_queue_restart_all(&s->overwrapping_queue);
+
return acb->ret;
}
diff --git a/block/ssh.c b/block/ssh.c
index aebb18c..8d06739 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -563,7 +563,7 @@
/* Open the socket and connect. */
s->sock = inet_connect(s->hostport, errp);
if (s->sock < 0) {
- ret = -errno;
+ ret = -EIO;
goto err;
}
diff --git a/block/vpc.c b/block/vpc.c
index 37572ba..3e385d9 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -168,6 +168,7 @@
uint8_t buf[HEADER_SIZE];
uint32_t checksum;
uint64_t computed_size;
+ uint64_t pagetable_size;
int disk_type = VHD_DYNAMIC;
int ret;
@@ -269,7 +270,17 @@
goto fail;
}
- s->pagetable = qemu_try_blockalign(bs->file, s->max_table_entries * 4);
+ if (s->max_table_entries > SIZE_MAX / 4 ||
+ s->max_table_entries > (int) INT_MAX / 4) {
+ error_setg(errp, "Max Table Entries too large (%" PRId32 ")",
+ s->max_table_entries);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ pagetable_size = (uint64_t) s->max_table_entries * 4;
+
+ s->pagetable = qemu_try_blockalign(bs->file, pagetable_size);
if (s->pagetable == NULL) {
ret = -ENOMEM;
goto fail;
@@ -277,14 +288,13 @@
s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
- ret = bdrv_pread(bs->file, s->bat_offset, s->pagetable,
- s->max_table_entries * 4);
+ ret = bdrv_pread(bs->file, s->bat_offset, s->pagetable, pagetable_size);
if (ret < 0) {
goto fail;
}
s->free_data_block_offset =
- (s->bat_offset + (s->max_table_entries * 4) + 511) & ~511;
+ ROUND_UP(s->bat_offset + pagetable_size, 512);
for (i = 0; i < s->max_table_entries; i++) {
be32_to_cpus(&s->pagetable[i]);
diff --git a/crypto/cipher-builtin.c b/crypto/cipher-builtin.c
index 912c1b9..30f4853 100644
--- a/crypto/cipher-builtin.c
+++ b/crypto/cipher-builtin.c
@@ -117,7 +117,7 @@
uint8_t *outptr = out;
while (len) {
if (len > AES_BLOCK_SIZE) {
- AES_decrypt(inptr, outptr, &ctxt->state.aes.encrypt_key);
+ AES_decrypt(inptr, outptr, &ctxt->state.aes.decrypt_key);
inptr += AES_BLOCK_SIZE;
outptr += AES_BLOCK_SIZE;
len -= AES_BLOCK_SIZE;
@@ -126,15 +126,15 @@
memcpy(tmp1, inptr, len);
/* Fill with 0 to avoid valgrind uninitialized reads */
memset(tmp1 + len, 0, sizeof(tmp1) - len);
- AES_decrypt(tmp1, tmp2, &ctxt->state.aes.encrypt_key);
+ AES_decrypt(tmp1, tmp2, &ctxt->state.aes.decrypt_key);
memcpy(outptr, tmp2, len);
len = 0;
}
}
} else {
AES_cbc_encrypt(in, out, len,
- &ctxt->state.aes.encrypt_key,
- ctxt->state.aes.iv, 1);
+ &ctxt->state.aes.decrypt_key,
+ ctxt->state.aes.iv, 0);
}
return 0;
diff --git a/device_tree.c b/device_tree.c
index d2de580..a9f5f8e 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -241,7 +241,7 @@
/*
* We need to find out if the user gave us special instruction at
- * which phandle id to start allocting phandles.
+ * which phandle id to start allocating phandles.
*/
if (!phandle) {
phandle = machine_phandle_start(current_machine);
diff --git a/gdbstub.c b/gdbstub.c
index 92b2f81..ffe7e6e 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1285,6 +1285,7 @@
ret = GDB_SIGNAL_UNKNOWN;
break;
}
+ gdb_set_stop_cpu(cpu);
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(cpu));
send_packet:
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 3f4c9e7..93a407c 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -21,7 +21,8 @@
#include "virtio-9p-coth.h"
#include "hw/virtio/virtio-access.h"
-static uint64_t virtio_9p_get_features(VirtIODevice *vdev, uint64_t features)
+static uint64_t virtio_9p_get_features(VirtIODevice *vdev, uint64_t features,
+ Error **errp)
{
virtio_add_feature(&features, VIRTIO_9P_MOUNT_TAG);
return features;
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 6ef8af3..f972731 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -14,6 +14,7 @@
#include "hw/virtio/virtio.h"
#include "hw/i386/pc.h"
#include "qemu/error-report.h"
+#include "qemu/iov.h"
#include "qemu/sockets.h"
#include "virtio-9p.h"
#include "fsdev/qemu-fsdev.h"
@@ -3261,16 +3262,26 @@
while ((pdu = alloc_pdu(s)) &&
(len = virtqueue_pop(vq, &pdu->elem)) != 0) {
- uint8_t *ptr;
+ struct {
+ uint32_t size_le;
+ uint8_t id;
+ uint16_t tag_le;
+ } QEMU_PACKED out;
+ int len;
+
pdu->s = s;
BUG_ON(pdu->elem.out_num == 0 || pdu->elem.in_num == 0);
- BUG_ON(pdu->elem.out_sg[0].iov_len < 7);
+ QEMU_BUILD_BUG_ON(sizeof out != 7);
- ptr = pdu->elem.out_sg[0].iov_base;
+ len = iov_to_buf(pdu->elem.out_sg, pdu->elem.out_num, 0,
+ &out, sizeof out);
+ BUG_ON(len != sizeof out);
- pdu->size = le32_to_cpu(*(uint32_t *)ptr);
- pdu->id = ptr[4];
- pdu->tag = le16_to_cpu(*(uint16_t *)(ptr + 5));
+ pdu->size = le32_to_cpu(out.size_le);
+
+ pdu->id = out.id;
+ pdu->tag = le16_to_cpu(out.tag_le);
+
qemu_co_queue_init(&pdu->complete);
submit_pdu(s, pdu);
}
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index f04f6dc..1c7fcfa 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -221,9 +221,9 @@
acpi_pm_tmr_reset(&pm->acpi_regs);
acpi_gpe_reset(&pm->acpi_regs);
+ pm->smi_en = 0;
if (!pm->smm_enabled) {
- /* Mark SMM as already inited to prevent SMM from running. KVM does not
- * support SMM mode. */
+ /* Mark SMM as already inited to prevent SMM from running. */
pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
}
pm->smi_en_wmask = ~0;
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 6aefda4..1556c9c 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -722,7 +722,8 @@
aio_context_release(blk_get_aio_context(s->blk));
}
-static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features)
+static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
+ Error **errp)
{
VirtIOBlock *s = VIRTIO_BLK(vdev);
@@ -730,7 +731,15 @@
virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
- virtio_add_feature(&features, VIRTIO_BLK_F_SCSI);
+ if (__virtio_has_feature(features, VIRTIO_F_VERSION_1)) {
+ if (s->conf.scsi) {
+ error_setg(errp, "Please set scsi=off for virtio-blk devices in order to use virtio 1.0");
+ return 0;
+ }
+ } else {
+ virtio_clear_feature(&features, VIRTIO_F_ANY_LAYOUT);
+ virtio_add_feature(&features, VIRTIO_BLK_F_SCSI);
+ }
if (s->conf.config_wce) {
virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 78c73e5..bc56f5d 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -195,7 +195,8 @@
return 0;
}
- memcpy(elem.in_sg[0].iov_base, buf, len);
+ /* TODO: detect a buffer that's too short, set NEEDS_RESET */
+ iov_from_buf(elem.in_sg, elem.in_num, 0, buf, len);
virtqueue_push(vq, &elem, len);
virtio_notify(VIRTIO_DEVICE(vser), vq);
@@ -499,7 +500,8 @@
}
}
-static uint64_t get_features(VirtIODevice *vdev, uint64_t features)
+static uint64_t get_features(VirtIODevice *vdev, uint64_t features,
+ Error **errp)
{
VirtIOSerial *vser;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 990a26b..a67d927 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -89,7 +89,8 @@
}
}
-static uint64_t virtio_gpu_get_features(VirtIODevice *vdev, uint64_t features)
+static uint64_t virtio_gpu_get_features(VirtIODevice *vdev, uint64_t features,
+ Error **errp)
{
return features;
}
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index aed811a..46eddb8 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1108,8 +1108,8 @@
aml_append(field, aml_named_field("PEPT", 8));
aml_append(dev, field);
- /* device present, functioning, decoding, not shown in UI */
- aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+ /* device present, functioning, decoding, shown in UI */
+ aml_append(dev, aml_name_decl("_STA", aml_int(0xF)));
method = aml_method("RDPT", 0);
aml_append(method, aml_store(aml_name("PEPT"), aml_local(0)));
diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c
index 7f5b8d6..7b25d27 100644
--- a/hw/input/virtio-input.c
+++ b/hw/input/virtio-input.c
@@ -166,7 +166,8 @@
virtio_notify_config(vdev);
}
-static uint64_t virtio_input_get_features(VirtIODevice *vdev, uint64_t f)
+static uint64_t virtio_input_get_features(VirtIODevice *vdev, uint64_t f,
+ Error **errp)
{
return f;
}
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 451ff72..ab607e4 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -643,11 +643,6 @@
static const uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
int i;
- /* Check for runt packet (remember that checksum is not there) */
- if (size < 64 - 4) {
- return (s->regs[SONIC_RCR] & SONIC_RCR_RNT) ? 0 : -1;
- }
-
/* Check promiscuous mode */
if ((s->regs[SONIC_RCR] & SONIC_RCR_PRO) && (buf[0] & 1) == 0) {
return 0;
@@ -836,6 +831,7 @@
dp8393xState *s = DP8393X(dev);
int i, checksum;
uint8_t *prom;
+ Error *local_err = NULL;
address_space_init(&s->as, s->dma_mr, "dp8393x");
memory_region_init_io(&s->mmio, OBJECT(dev), &dp8393x_ops, s,
@@ -848,8 +844,13 @@
s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
- memory_region_init_rom_device(&s->prom, OBJECT(dev), NULL, NULL,
- "dp8393x-prom", SONIC_PROM_SIZE, NULL);
+ memory_region_init_ram(&s->prom, OBJECT(dev),
+ "dp8393x-prom", SONIC_PROM_SIZE, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ memory_region_set_readonly(&s->prom, true);
prom = memory_region_get_ram_ptr(&s->prom);
checksum = 0;
for (i = 0; i < 6; i++) {
@@ -889,6 +890,8 @@
dc->reset = dp8393x_reset;
dc->vmsd = &vmstate_dp8393x;
dc->props = dp8393x_properties;
+ /* Reason: dma_mr property can't be set */
+ dc->cannot_instantiate_with_device_add_yet = true;
}
static const TypeInfo dp8393x_info = {
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 304d3dd..1510839 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -446,7 +446,8 @@
static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue);
-static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features)
+static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
+ Error **errp)
{
VirtIONet *n = VIRTIO_NET(vdev);
NetClientState *nc = qemu_get_queue(n->nic);
@@ -1777,8 +1778,6 @@
}
static Property virtio_net_properties[] = {
- DEFINE_PROP_BIT("any_layout", VirtIONet, host_features,
- VIRTIO_F_ANY_LAYOUT, true),
DEFINE_PROP_BIT("csum", VirtIONet, host_features, VIRTIO_NET_F_CSUM, true),
DEFINE_PROP_BIT("guest_csum", VirtIONet, host_features,
VIRTIO_NET_F_GUEST_CSUM, true),
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 51ba9e0..a04369c 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -2202,8 +2202,15 @@
return 0;
}
+static void megasas_queue_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ return;
+}
+
static const MemoryRegionOps megasas_queue_ops = {
.read = megasas_queue_read,
+ .write = megasas_queue_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.impl = {
.min_access_size = 8,
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 52549f8..a69918b 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -153,7 +153,8 @@
}
static uint64_t vhost_scsi_get_features(VirtIODevice *vdev,
- uint64_t features)
+ uint64_t features,
+ Error **errp)
{
VHostSCSI *s = VHOST_SCSI(vdev);
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index f7d3c7c..811c3da 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -629,7 +629,8 @@
}
static uint64_t virtio_scsi_get_features(VirtIODevice *vdev,
- uint64_t requested_features)
+ uint64_t requested_features,
+ Error **errp)
{
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
@@ -953,8 +954,6 @@
0xFFFF),
DEFINE_PROP_UINT32("cmd_per_lun", VirtIOSCSI, parent_obj.conf.cmd_per_lun,
128),
- DEFINE_PROP_BIT("any_layout", VirtIOSCSI, host_features,
- VIRTIO_F_ANY_LAYOUT, true),
DEFINE_PROP_BIT("hotplug", VirtIOSCSI, host_features,
VIRTIO_SCSI_F_HOTPLUG, true),
DEFINE_PROP_BIT("param_change", VirtIOSCSI, host_features,
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 2990f8d..3577b7a 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -310,7 +310,8 @@
trace_virtio_balloon_set_config(dev->actual, oldactual);
}
-static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f)
+static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
+ Error **errp)
{
VirtIOBalloon *dev = VIRTIO_BALLOON(vdev);
f |= dev->host_features;
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index 3926f7e..febda76 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -54,7 +54,8 @@
/* Get the features of the plugged device. */
assert(vdc->get_features != NULL);
- vdev->host_features = vdc->get_features(vdev, vdev->host_features);
+ vdev->host_features = vdc->get_features(vdev, vdev->host_features,
+ errp);
}
/* Reset the virtio_bus */
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 283401a..c024161 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1095,7 +1095,8 @@
break;
case VIRTIO_PCI_COMMON_DF:
if (proxy->dfselect <= 1) {
- val = vdev->host_features >> (32 * proxy->dfselect);
+ val = (vdev->host_features & ~VIRTIO_LEGACY_FEATURES) >>
+ (32 * proxy->dfselect);
}
break;
case VIRTIO_PCI_COMMON_GFSELECT:
@@ -1413,6 +1414,13 @@
virtio_pci_add_mem_cap(proxy, cap);
}
+static void virtio_pci_modern_region_unmap(VirtIOPCIProxy *proxy,
+ VirtIOPCIRegion *region)
+{
+ memory_region_del_subregion(&proxy->modern_bar,
+ ®ion->mr);
+}
+
/* This is called by virtio-bus just after the device is plugged. */
static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
{
@@ -1519,8 +1527,16 @@
static void virtio_pci_device_unplugged(DeviceState *d)
{
VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
+ bool modern = !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN);
virtio_pci_stop_ioeventfd(proxy);
+
+ if (modern) {
+ virtio_pci_modern_region_unmap(proxy, &proxy->common);
+ virtio_pci_modern_region_unmap(proxy, &proxy->isr);
+ virtio_pci_modern_region_unmap(proxy, &proxy->device);
+ virtio_pci_modern_region_unmap(proxy, &proxy->notify);
+ }
}
static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index 6e5f022..97d1541 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -104,7 +104,7 @@
virtio_rng_process(vrng);
}
-static uint64_t get_features(VirtIODevice *vdev, uint64_t f)
+static uint64_t get_features(VirtIODevice *vdev, uint64_t f, Error **errp)
{
return f;
}
diff --git a/include/hw/compat.h b/include/hw/compat.h
index 4a43466..94c8097 100644
--- a/include/hw/compat.h
+++ b/include/hw/compat.h
@@ -2,7 +2,27 @@
#define HW_COMPAT_H
#define HW_COMPAT_2_3 \
- /* empty */
+ {\
+ .driver = "virtio-blk-pci",\
+ .property = "any_layout",\
+ .value = "off",\
+ },{\
+ .driver = "virtio-balloon-pci",\
+ .property = "any_layout",\
+ .value = "off",\
+ },{\
+ .driver = "virtio-serial-pci",\
+ .property = "any_layout",\
+ .value = "off",\
+ },{\
+ .driver = "virtio-9p-pci",\
+ .property = "any_layout",\
+ .value = "off",\
+ },{\
+ .driver = "virtio-rng-pci",\
+ .property = "any_layout",\
+ .value = "off",\
+ },
#define HW_COMPAT_2_2 \
/* empty */
diff --git a/include/hw/timer/a9gtimer.h b/include/hw/timer/a9gtimer.h
index b88c02a..98d8e0a 100644
--- a/include/hw/timer/a9gtimer.h
+++ b/include/hw/timer/a9gtimer.h
@@ -37,7 +37,7 @@
#define R_CONTROL_TIMER_ENABLE (1 << 0)
#define R_CONTROL_COMP_ENABLE (1 << 1)
#define R_CONTROL_IRQ_ENABLE (1 << 2)
-#define R_CONTROL_AUTO_INCREMENT (1 << 2)
+#define R_CONTROL_AUTO_INCREMENT (1 << 3)
#define R_CONTROL_PRESCALER_SHIFT 8
#define R_CONTROL_PRESCALER_LEN 8
#define R_CONTROL_PRESCALER_MASK (((1 << R_CONTROL_PRESCALER_LEN) - 1) << \
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 473fb75..59f0763 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -25,6 +25,10 @@
/* A guest should never accept this. It implies negotiation is broken. */
#define VIRTIO_F_BAD_FEATURE 30
+#define VIRTIO_LEGACY_FEATURES ((0x1ULL << VIRTIO_F_BAD_FEATURE) | \
+ (0x1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) | \
+ (0x1ULL << VIRTIO_F_ANY_LAYOUT))
+
struct VirtQueue;
static inline hwaddr vring_align(hwaddr addr,
@@ -97,7 +101,9 @@
/* This is what a VirtioDevice must implement */
DeviceRealize realize;
DeviceUnrealize unrealize;
- uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
+ uint64_t (*get_features)(VirtIODevice *vdev,
+ uint64_t requested_features,
+ Error **errp);
uint64_t (*bad_features)(VirtIODevice *vdev);
void (*set_features)(VirtIODevice *vdev, uint64_t val);
int (*validate_features)(VirtIODevice *vdev);
@@ -214,7 +220,9 @@
DEFINE_PROP_BIT64("event_idx", _state, _field, \
VIRTIO_RING_F_EVENT_IDX, true), \
DEFINE_PROP_BIT64("notify_on_empty", _state, _field, \
- VIRTIO_F_NOTIFY_ON_EMPTY, true)
+ VIRTIO_F_NOTIFY_ON_EMPTY, true), \
+ DEFINE_PROP_BIT64("any_layout", _state, _field, \
+ VIRTIO_F_ANY_LAYOUT, true)
hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n);
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index f51ff69..2e5a97d 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -75,9 +75,6 @@
void *opaque);
void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque);
-void register_device_unmigratable(DeviceState *dev, const char *idstr,
- void *opaque);
-
typedef struct VMStateInfo VMStateInfo;
typedef struct VMStateDescription VMStateDescription;
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 237d654..fb3da6c 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -148,13 +148,125 @@
return !strcmp(s, "?") || !strcmp(s, "help");
}
-/* cutils.c */
+/* util/cutils.c */
+/**
+ * pstrcpy:
+ * @buf: buffer to copy string into
+ * @buf_size: size of @buf in bytes
+ * @str: string to copy
+ *
+ * Copy @str into @buf, including the trailing NUL, but do not
+ * write more than @buf_size bytes. The resulting buffer is
+ * always NUL terminated (even if the source string was too long).
+ * If @buf_size is zero or negative then no bytes are copied.
+ *
+ * This function is similar to strncpy(), but avoids two of that
+ * function's problems:
+ * * if @str fits in the buffer, pstrcpy() does not zero-fill the
+ * remaining space at the end of @buf
+ * * if @str is too long, pstrcpy() will copy the first @buf_size-1
+ * bytes and then add a NUL
+ */
void pstrcpy(char *buf, int buf_size, const char *str);
+/**
+ * strpadcpy:
+ * @buf: buffer to copy string into
+ * @buf_size: size of @buf in bytes
+ * @str: string to copy
+ * @pad: character to pad the remainder of @buf with
+ *
+ * Copy @str into @buf (but *not* its trailing NUL!), and then pad the
+ * rest of the buffer with the @pad character. If @str is too large
+ * for the buffer then it is truncated, so that @buf contains the
+ * first @buf_size characters of @str, with no terminator.
+ */
void strpadcpy(char *buf, int buf_size, const char *str, char pad);
+/**
+ * pstrcat:
+ * @buf: buffer containing existing string
+ * @buf_size: size of @buf in bytes
+ * @s: string to concatenate to @buf
+ *
+ * Append a copy of @s to the string already in @buf, but do not
+ * allow the buffer to overflow. If the existing contents of @buf
+ * plus @str would total more than @buf_size bytes, then write
+ * as much of @str as will fit followed by a NUL terminator.
+ *
+ * @buf must already contain a NUL-terminated string, or the
+ * behaviour is undefined.
+ *
+ * Returns: @buf.
+ */
char *pstrcat(char *buf, int buf_size, const char *s);
+/**
+ * strstart:
+ * @str: string to test
+ * @val: prefix string to look for
+ * @ptr: NULL, or pointer to be written to indicate start of
+ * the remainder of the string
+ *
+ * Test whether @str starts with the prefix @val.
+ * If it does (including the degenerate case where @str and @val
+ * are equal) then return true. If @ptr is not NULL then a
+ * pointer to the first character following the prefix is written
+ * to it. If @val is not a prefix of @str then return false (and
+ * @ptr is not written to).
+ *
+ * Returns: true if @str starts with prefix @val, false otherwise.
+ */
int strstart(const char *str, const char *val, const char **ptr);
+/**
+ * stristart:
+ * @str: string to test
+ * @val: prefix string to look for
+ * @ptr: NULL, or pointer to be written to indicate start of
+ * the remainder of the string
+ *
+ * Test whether @str starts with the case-insensitive prefix @val.
+ * This function behaves identically to strstart(), except that the
+ * comparison is made after calling qemu_toupper() on each pair of
+ * characters.
+ *
+ * Returns: true if @str starts with case-insensitive prefix @val,
+ * false otherwise.
+ */
int stristart(const char *str, const char *val, const char **ptr);
+/**
+ * qemu_strnlen:
+ * @s: string
+ * @max_len: maximum number of bytes in @s to scan
+ *
+ * Return the length of the string @s, like strlen(), but do not
+ * examine more than @max_len bytes of the memory pointed to by @s.
+ * If no NUL terminator is found within @max_len bytes, then return
+ * @max_len instead.
+ *
+ * This function has the same behaviour as the POSIX strnlen()
+ * function.
+ *
+ * Returns: length of @s in bytes, or @max_len, whichever is smaller.
+ */
int qemu_strnlen(const char *s, int max_len);
+/**
+ * qemu_strsep:
+ * @input: pointer to string to parse
+ * @delim: string containing delimiter characters to search for
+ *
+ * Locate the first occurrence of any character in @delim within
+ * the string referenced by @input, and replace it with a NUL.
+ * The location of the next character after the delimiter character
+ * is stored into @input.
+ * If the end of the string was reached without finding a delimiter
+ * character, then NULL is stored into @input.
+ * If @input points to a NULL pointer on entry, return NULL.
+ * The return value is always the original value of *@input (and
+ * so now points to a NUL-terminated string corresponding to the
+ * part of the input up to the first delimiter).
+ *
+ * This function has the same behaviour as the BSD strsep() function.
+ *
+ * Returns: the pointer originally in @input.
+ */
char *qemu_strsep(char **input, const char *delim);
time_t mktimegm(struct tm *tm);
int qemu_fls(int i);
diff --git a/memory.c b/memory.c
index 5e5f325..4eb138a 100644
--- a/memory.c
+++ b/memory.c
@@ -859,11 +859,6 @@
qemu_ram_free(mr->ram_addr);
}
-static void memory_region_destructor_alias(MemoryRegion *mr)
-{
- memory_region_unref(mr->alias);
-}
-
static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
{
qemu_ram_free_from_ptr(mr->ram_addr);
@@ -1272,8 +1267,6 @@
uint64_t size)
{
memory_region_init(mr, owner, name, size);
- memory_region_ref(orig);
- mr->destructor = memory_region_destructor_alias;
mr->alias = orig;
mr->alias_offset = offset;
}
diff --git a/qapi-schema.json b/qapi-schema.json
index a0a45f7..4342a08 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -15,7 +15,7 @@
{ 'include': 'qapi/trace.json' }
##
-# LostTickPolicy:
+# @LostTickPolicy:
#
# Policy for handling lost ticks in timer devices.
#
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 8e3204a..04ba19f 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -565,34 +565,30 @@
break;
case EXCP_EXT_INTERRUPT:
cause = 0;
- if (env->CP0_Cause & (1 << CP0Ca_IV))
- offset = 0x200;
+ if (env->CP0_Cause & (1 << CP0Ca_IV)) {
+ uint32_t spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & 0x1f;
- if (env->CP0_Config3 & ((1 << CP0C3_VInt) | (1 << CP0C3_VEIC))) {
- /* Vectored Interrupts. */
- unsigned int spacing;
- unsigned int vector;
- unsigned int pending = (env->CP0_Cause & CP0Ca_IP_mask) >> 8;
+ if ((env->CP0_Status & (1 << CP0St_BEV)) || spacing == 0) {
+ offset = 0x200;
+ } else {
+ uint32_t vector = 0;
+ uint32_t pending = (env->CP0_Cause & CP0Ca_IP_mask) >> CP0Ca_IP;
- pending &= env->CP0_Status >> 8;
- /* Compute the Vector Spacing. */
- spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & ((1 << 6) - 1);
- spacing <<= 5;
-
- if (env->CP0_Config3 & (1 << CP0C3_VInt)) {
- /* For VInt mode, the MIPS computes the vector internally. */
- for (vector = 7; vector > 0; vector--) {
- if (pending & (1 << vector)) {
- /* Found it. */
- break;
+ if (env->CP0_Config3 & (1 << CP0C3_VEIC)) {
+ /* For VEIC mode, the external interrupt controller feeds
+ * the vector through the CP0Cause IP lines. */
+ vector = pending;
+ } else {
+ /* Vectored Interrupts
+ * Mask with Status.IM7-IM0 to get enabled interrupts. */
+ pending &= (env->CP0_Status >> CP0St_IM) & 0xff;
+ /* Find the highest-priority interrupt. */
+ while (pending >>= 1) {
+ vector++;
}
}
- } else {
- /* For VEIC mode, the external interrupt controller feeds the
- vector through the CP0Cause IP lines. */
- vector = pending;
+ offset = 0x200 + (vector * (spacing << 5));
}
- offset = 0x200 + vector * spacing;
}
goto set_EPC;
case EXCP_LTLBL:
diff --git a/target-mips/machine.c b/target-mips/machine.c
index 8fa755c..b15c43a 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -153,6 +153,7 @@
{
r4k_tlb_t *v = pv;
+ uint8_t asid = v->ASID;
uint16_t flags = ((v->EHINV << 15) |
(v->RI1 << 14) |
(v->RI0 << 13) |
@@ -168,7 +169,7 @@
qemu_put_betls(f, &v->VPN);
qemu_put_be32s(f, &v->PageMask);
- qemu_put_8s(f, &v->ASID);
+ qemu_put_8s(f, &asid);
qemu_put_be16s(f, &flags);
qemu_put_be64s(f, &v->PFN[0]);
qemu_put_be64s(f, &v->PFN[1]);
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 9c28631..db4f6b9 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1432,7 +1432,6 @@
void helper_mtc0_intctl(CPUMIPSState *env, target_ulong arg1)
{
- /* vectored interrupts not implemented, no performance counters. */
env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000003e0) | (arg1 & 0x000003e0);
}
@@ -1473,7 +1472,6 @@
void helper_mtc0_ebase(CPUMIPSState *env, target_ulong arg1)
{
- /* vectored interrupts not implemented */
env->CP0_EBase = (env->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
}
diff --git a/tests/Makefile b/tests/Makefile
index 8d26736..7494582 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -487,10 +487,10 @@
# Reports and overall runs
check-report.xml: $(patsubst %,check-report-qtest-%.xml, $(QTEST_TARGETS)) check-report-unit.xml
- $(call quiet-command,$(SRC_PATH)/scripts/gtester-cat $^ > $@, " GEN $@")
+ $(call quiet-command,$(SRC_PATH)/scripts/gtester-cat $^ > $@, " GEN $@")
check-report.html: check-report.xml
- $(call quiet-command,gtester-report $< > $@, " GEN $@")
+ $(call quiet-command,gtester-report $< > $@, " GEN $@")
# Other tests
diff --git a/tests/qemu-iotests/135 b/tests/qemu-iotests/135
new file mode 100755
index 0000000..16bf736
--- /dev/null
+++ b/tests/qemu-iotests/135
@@ -0,0 +1,54 @@
+#!/bin/bash
+#
+# Test VPC open of image with large Max Table Entries value.
+#
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=jcody@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt vpc
+_supported_proto generic
+_supported_os Linux
+
+_use_sample_img afl5.img.bz2
+
+echo
+echo "=== Verify image open and failure ===="
+$QEMU_IMG info "$TEST_IMG" 2>&1| _filter_testdir
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/135.out b/tests/qemu-iotests/135.out
new file mode 100644
index 0000000..793898b
--- /dev/null
+++ b/tests/qemu-iotests/135.out
@@ -0,0 +1,5 @@
+QA output created by 135
+
+=== Verify image open and failure ====
+qemu-img: Could not open 'TEST_DIR/afl5.img': Max Table Entries too large (1073741825)
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 6206765..c430b6c 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -133,3 +133,4 @@
131 rw auto quick
132 rw auto quick
134 rw auto quick
+135 rw auto
diff --git a/tests/qemu-iotests/sample_images/afl5.img.bz2 b/tests/qemu-iotests/sample_images/afl5.img.bz2
new file mode 100644
index 0000000..1614348
--- /dev/null
+++ b/tests/qemu-iotests/sample_images/afl5.img.bz2
Binary files differ
diff --git a/tests/test-crypto-cipher.c b/tests/test-crypto-cipher.c
index f9b1a03..9d38d26 100644
--- a/tests/test-crypto-cipher.c
+++ b/tests/test-crypto-cipher.c
@@ -226,12 +226,10 @@
const QCryptoCipherTestData *data = opaque;
QCryptoCipher *cipher;
- Error *err = NULL;
uint8_t *key, *iv, *ciphertext, *plaintext, *outtext;
size_t nkey, niv, nciphertext, nplaintext;
char *outtexthex;
- g_test_message("foo");
nkey = unhex_string(data->key, &key);
niv = unhex_string(data->iv, &iv);
nciphertext = unhex_string(data->ciphertext, &ciphertext);
@@ -244,28 +242,42 @@
cipher = qcrypto_cipher_new(
data->alg, data->mode,
key, nkey,
- &err);
+ &error_abort);
g_assert(cipher != NULL);
- g_assert(err == NULL);
if (iv) {
g_assert(qcrypto_cipher_setiv(cipher,
iv, niv,
- &err) == 0);
- g_assert(err == NULL);
+ &error_abort) == 0);
}
g_assert(qcrypto_cipher_encrypt(cipher,
plaintext,
outtext,
nplaintext,
- &err) == 0);
- g_assert(err == NULL);
+ &error_abort) == 0);
outtexthex = hex_string(outtext, nciphertext);
g_assert_cmpstr(outtexthex, ==, data->ciphertext);
+ g_free(outtexthex);
+
+ if (iv) {
+ g_assert(qcrypto_cipher_setiv(cipher,
+ iv, niv,
+ &error_abort) == 0);
+ }
+ g_assert(qcrypto_cipher_decrypt(cipher,
+ ciphertext,
+ outtext,
+ nplaintext,
+ &error_abort) == 0);
+
+ outtexthex = hex_string(outtext, nplaintext);
+
+ g_assert_cmpstr(outtexthex, ==, data->plaintext);
+
g_free(outtext);
g_free(outtexthex);
g_free(key);