aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VERSION2
-rw-r--r--block/gluster.c3
-rw-r--r--block/io.c58
-rw-r--r--block/iscsi.c4
-rw-r--r--block/nbd-client.c4
-rw-r--r--block/qcow2.c6
-rw-r--r--block/sheepdog.c5
-rwxr-xr-xconfigure2
-rw-r--r--hw/char/spapr_vty.c2
-rw-r--r--hw/pci-host/uninorth.c4
-rw-r--r--hw/ppc/spapr.c76
-rw-r--r--hw/ppc/spapr_ovec.c12
-rw-r--r--hw/ppc/spapr_pci.c35
-rw-r--r--hw/scsi/esp.c2
-rw-r--r--hw/usb/xen-usb.c23
-rw-r--r--hw/xen/xen_backend.c66
-rw-r--r--hw/xen/xen_pvdev.c4
-rw-r--r--include/exec/cpu_ldst.h2
-rw-r--r--include/hw/pci-host/spapr.h6
-rw-r--r--include/hw/ppc/spapr_ovec.h4
-rw-r--r--include/hw/xen/xen_backend.h8
-rw-r--r--include/hw/xen/xen_pvdev.h1
-rw-r--r--include/migration/cpu.h4
-rw-r--r--include/monitor/qdev.h1
-rw-r--r--pc-bios/bios-256k.binbin262144 -> 262144 bytes
-rw-r--r--pc-bios/bios.binbin131072 -> 131072 bytes
-rw-r--r--pc-bios/vgabios-cirrus.binbin38400 -> 38400 bytes
-rw-r--r--pc-bios/vgabios-qxl.binbin38912 -> 38912 bytes
-rw-r--r--pc-bios/vgabios-stdvga.binbin38912 -> 38912 bytes
-rw-r--r--pc-bios/vgabios-virtio.binbin38912 -> 38912 bytes
-rw-r--r--pc-bios/vgabios-vmware.binbin38912 -> 38912 bytes
-rw-r--r--pc-bios/vgabios.binbin38400 -> 38400 bytes
-rw-r--r--qdev-monitor.c36
m---------roms/seabios0
-rw-r--r--target-ppc/cpu.h7
-rw-r--r--target-ppc/helper_regs.h11
-rw-r--r--target-ppc/int_helper.c4
-rw-r--r--target-ppc/machine.c39
-rw-r--r--target-ppc/translate_init.c6
-rw-r--r--tests/postcopy-test.c12
-rw-r--r--util/oslib-posix.c1
-rw-r--r--xen-common.c6
-rw-r--r--xen-hvm.c20
43 files changed, 383 insertions, 93 deletions
diff --git a/VERSION b/VERSION
index 5f79f46a0e..96219e0d7b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.7.90
+2.7.91
diff --git a/block/gluster.c b/block/gluster.c
index 0ce15f7adc..891c13b7ce 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -239,12 +239,13 @@ static glfs_t *glfs_find_preopened(const char *volume)
static void glfs_clear_preopened(glfs_t *fs)
{
ListElement *entry = NULL;
+ ListElement *next;
if (fs == NULL) {
return;
}
- QLIST_FOREACH(entry, &glfs_list, list) {
+ QLIST_FOREACH_SAFE(entry, &glfs_list, list, next) {
if (entry->saved.fs == fs) {
if (--entry->saved.ref) {
return;
diff --git a/block/io.c b/block/io.c
index aa532a5c1f..4f005623f7 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1214,6 +1214,8 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, INT_MAX);
int alignment = MAX(bs->bl.pwrite_zeroes_alignment,
bs->bl.request_alignment);
+ int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
+ MAX_WRITE_ZEROES_BOUNCE_BUFFER);
assert(alignment % bs->bl.request_alignment == 0);
head = offset % alignment;
@@ -1229,9 +1231,12 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
* boundaries.
*/
if (head) {
- /* Make a small request up to the first aligned sector. */
- num = MIN(count, alignment - head);
- head = 0;
+ /* Make a small request up to the first aligned sector. For
+ * convenience, limit this request to max_transfer even if
+ * we don't need to fall back to writes. */
+ num = MIN(MIN(count, max_transfer), alignment - head);
+ head = (head + num) % alignment;
+ assert(num < max_write_zeroes);
} else if (tail && num > alignment) {
/* Shorten the request to the last aligned sector. */
num -= tail;
@@ -1257,8 +1262,6 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
if (ret == -ENOTSUP) {
/* Fall back to bounce buffer if write zeroes is unsupported */
- int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
- MAX_WRITE_ZEROES_BOUNCE_BUFFER);
BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;
if ((flags & BDRV_REQ_FUA) &&
@@ -2421,7 +2424,7 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
{
BdrvTrackedRequest req;
int max_pdiscard, ret;
- int head, align;
+ int head, tail, align;
if (!bs->drv) {
return -ENOMEDIUM;
@@ -2444,19 +2447,15 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
return 0;
}
- /* Discard is advisory, so ignore any unaligned head or tail */
+ /* Discard is advisory, but some devices track and coalesce
+ * unaligned requests, so we must pass everything down rather than
+ * round here. Still, most devices will just silently ignore
+ * unaligned requests (by returning -ENOTSUP), so we must fragment
+ * the request accordingly. */
align = MAX(bs->bl.pdiscard_alignment, bs->bl.request_alignment);
assert(align % bs->bl.request_alignment == 0);
head = offset % align;
- if (head) {
- head = MIN(count, align - head);
- count -= head;
- offset += head;
- }
- count = QEMU_ALIGN_DOWN(count, align);
- if (!count) {
- return 0;
- }
+ tail = (offset + count) % align;
bdrv_inc_in_flight(bs);
tracked_request_begin(&req, bs, offset, count, BDRV_TRACKED_DISCARD);
@@ -2468,11 +2467,34 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
max_pdiscard = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_pdiscard, INT_MAX),
align);
- assert(max_pdiscard);
+ assert(max_pdiscard >= bs->bl.request_alignment);
while (count > 0) {
int ret;
- int num = MIN(count, max_pdiscard);
+ int num = count;
+
+ if (head) {
+ /* Make small requests to get to alignment boundaries. */
+ num = MIN(count, align - head);
+ if (!QEMU_IS_ALIGNED(num, bs->bl.request_alignment)) {
+ num %= bs->bl.request_alignment;
+ }
+ head = (head + num) % align;
+ assert(num < max_pdiscard);
+ } else if (tail) {
+ if (num > align) {
+ /* Shorten the request to the last aligned cluster. */
+ num -= tail;
+ } else if (!QEMU_IS_ALIGNED(tail, bs->bl.request_alignment) &&
+ tail > bs->bl.request_alignment) {
+ tail %= bs->bl.request_alignment;
+ num -= tail;
+ }
+ }
+ /* limit request size */
+ if (num > max_pdiscard) {
+ num = max_pdiscard;
+ }
if (bs->drv->bdrv_co_pdiscard) {
ret = bs->drv->bdrv_co_pdiscard(bs, offset, num);
diff --git a/block/iscsi.c b/block/iscsi.c
index 71bd523df5..0960929d57 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1083,7 +1083,9 @@ coroutine_fn iscsi_co_pdiscard(BlockDriverState *bs, int64_t offset, int count)
struct IscsiTask iTask;
struct unmap_list list;
- assert(is_byte_request_lun_aligned(offset, count, iscsilun));
+ if (!is_byte_request_lun_aligned(offset, count, iscsilun)) {
+ return -ENOTSUP;
+ }
if (!iscsilun->lbp.lbpu) {
/* UNMAP is not supported by the target */
diff --git a/block/nbd-client.c b/block/nbd-client.c
index 2a302de674..3779c6c999 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -415,6 +415,10 @@ int nbd_client_init(BlockDriverState *bs,
}
if (client->nbdflags & NBD_FLAG_SEND_FUA) {
bs->supported_write_flags = BDRV_REQ_FUA;
+ bs->supported_zero_flags |= BDRV_REQ_FUA;
+ }
+ if (client->nbdflags & NBD_FLAG_SEND_WRITE_ZEROES) {
+ bs->supported_zero_flags |= BDRV_REQ_MAY_UNMAP;
}
qemu_co_mutex_init(&client->send_mutex);
diff --git a/block/qcow2.c b/block/qcow2.c
index 6d5689a23c..7cfcd8412c 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1206,6 +1206,7 @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.request_alignment = BDRV_SECTOR_SIZE;
}
bs->bl.pwrite_zeroes_alignment = s->cluster_size;
+ bs->bl.pdiscard_alignment = s->cluster_size;
}
static int qcow2_set_key(BlockDriverState *bs, const char *key)
@@ -2490,6 +2491,11 @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
int ret;
BDRVQcow2State *s = bs->opaque;
+ if (!QEMU_IS_ALIGNED(offset | count, s->cluster_size)) {
+ assert(count < s->cluster_size);
+ return -ENOTSUP;
+ }
+
qemu_co_mutex_lock(&s->lock);
ret = qcow2_discard_clusters(bs, offset, count >> BDRV_SECTOR_BITS,
QCOW2_DISCARD_REQUEST, false);
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 1fb917343a..4c9af89180 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -2829,8 +2829,9 @@ static coroutine_fn int sd_co_pdiscard(BlockDriverState *bs, int64_t offset,
iov.iov_len = sizeof(zero);
discard_iov.iov = &iov;
discard_iov.niov = 1;
- assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
- assert((count & (BDRV_SECTOR_SIZE - 1)) == 0);
+ if (!QEMU_IS_ALIGNED(offset | count, BDRV_SECTOR_SIZE)) {
+ return -ENOTSUP;
+ }
acb = sd_aio_setup(bs, &discard_iov, offset >> BDRV_SECTOR_BITS,
count >> BDRV_SECTOR_BITS);
acb->aiocb_type = AIOCB_DISCARD_OBJ;
diff --git a/configure b/configure
index 7d2a34e036..5e66828e64 100755
--- a/configure
+++ b/configure
@@ -582,6 +582,8 @@ FreeBSD)
audio_possible_drivers="oss sdl pa"
# needed for kinfo_getvmmap(3) in libutil.h
LIBS="-lutil $LIBS"
+ # needed for kinfo_getproc
+ libs_qga="-lutil $libs_qga"
netmap="" # enable netmap autodetect
HOST_VARIANT_DIR="freebsd"
;;
diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 06b9b3917f..7c22b8bd0e 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -25,7 +25,7 @@ static int vty_can_receive(void *opaque)
{
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(opaque);
- return (dev->in - dev->out) < VTERM_BUFSIZE;
+ return VTERM_BUFSIZE - (dev->in - dev->out);
}
static void vty_receive(void *opaque, const uint8_t *buf, int size)
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index 7aac4d67a4..df342ac3cb 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -62,9 +62,7 @@ typedef struct UNINState {
static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
{
- int devfn = pci_dev->devfn & 0x00FFFFFF;
-
- return (((devfn >> 11) & 0x1F) + irq_num) & 3;
+ return (irq_num + (pci_dev->devfn >> 3)) & 3;
}
static void pci_unin_set_irq(void *opaque, int irq_num, int level)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 0cbab24c91..c3269c7f50 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1267,6 +1267,68 @@ static bool version_before_3(void *opaque, int version_id)
return version_id < 3;
}
+static bool spapr_ov5_cas_needed(void *opaque)
+{
+ sPAPRMachineState *spapr = opaque;
+ sPAPROptionVector *ov5_mask = spapr_ovec_new();
+ sPAPROptionVector *ov5_legacy = spapr_ovec_new();
+ sPAPROptionVector *ov5_removed = spapr_ovec_new();
+ bool cas_needed;
+
+ /* Prior to the introduction of sPAPROptionVector, we had two option
+ * vectors we dealt with: OV5_FORM1_AFFINITY, and OV5_DRCONF_MEMORY.
+ * Both of these options encode machine topology into the device-tree
+ * in such a way that the now-booted OS should still be able to interact
+ * appropriately with QEMU regardless of what options were actually
+ * negotiatied on the source side.
+ *
+ * As such, we can avoid migrating the CAS-negotiated options if these
+ * are the only options available on the current machine/platform.
+ * Since these are the only options available for pseries-2.7 and
+ * earlier, this allows us to maintain old->new/new->old migration
+ * compatibility.
+ *
+ * For QEMU 2.8+, there are additional CAS-negotiatable options available
+ * via default pseries-2.8 machines and explicit command-line parameters.
+ * Some of these options, like OV5_HP_EVT, *do* require QEMU to be aware
+ * of the actual CAS-negotiated values to continue working properly. For
+ * example, availability of memory unplug depends on knowing whether
+ * OV5_HP_EVT was negotiated via CAS.
+ *
+ * Thus, for any cases where the set of available CAS-negotiatable
+ * options extends beyond OV5_FORM1_AFFINITY and OV5_DRCONF_MEMORY, we
+ * include the CAS-negotiated options in the migration stream.
+ */
+ spapr_ovec_set(ov5_mask, OV5_FORM1_AFFINITY);
+ spapr_ovec_set(ov5_mask, OV5_DRCONF_MEMORY);
+
+ /* spapr_ovec_diff returns true if bits were removed. we avoid using
+ * the mask itself since in the future it's possible "legacy" bits may be
+ * removed via machine options, which could generate a false positive
+ * that breaks migration.
+ */
+ spapr_ovec_intersect(ov5_legacy, spapr->ov5, ov5_mask);
+ cas_needed = spapr_ovec_diff(ov5_removed, spapr->ov5, ov5_legacy);
+
+ spapr_ovec_cleanup(ov5_mask);
+ spapr_ovec_cleanup(ov5_legacy);
+ spapr_ovec_cleanup(ov5_removed);
+
+ return cas_needed;
+}
+
+static const VMStateDescription vmstate_spapr_ov5_cas = {
+ .name = "spapr_option_vector_ov5_cas",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = spapr_ov5_cas_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_STRUCT_POINTER_V(ov5_cas, sPAPRMachineState, 1,
+ vmstate_spapr_ovec, sPAPROptionVector),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
static const VMStateDescription vmstate_spapr = {
.name = "spapr",
.version_id = 3,
@@ -1282,6 +1344,10 @@ static const VMStateDescription vmstate_spapr = {
VMSTATE_PPC_TIMEBASE_V(tb, sPAPRMachineState, 2),
VMSTATE_END_OF_LIST()
},
+ .subsections = (const VMStateDescription*[]) {
+ &vmstate_spapr_ov5_cas,
+ NULL
+ }
};
static int htab_save_setup(QEMUFile *f, void *opaque)
@@ -2701,6 +2767,16 @@ DEFINE_SPAPR_MACHINE(2_8, "2.8", true);
.driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \
.property = "mem64_win_size", \
.value = "0", \
+ }, \
+ { \
+ .driver = TYPE_POWERPC_CPU, \
+ .property = "pre-2.8-migration", \
+ .value = "on", \
+ }, \
+ { \
+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \
+ .property = "pre-2.8-migration", \
+ .value = "on", \
},
static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
diff --git a/hw/ppc/spapr_ovec.c b/hw/ppc/spapr_ovec.c
index c2a0d18577..3eb1d5976f 100644
--- a/hw/ppc/spapr_ovec.c
+++ b/hw/ppc/spapr_ovec.c
@@ -37,6 +37,17 @@
*/
struct sPAPROptionVector {
unsigned long *bitmap;
+ int32_t bitmap_size; /* only used for migration */
+};
+
+const VMStateDescription vmstate_spapr_ovec = {
+ .name = "spapr_option_vector",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_BITMAP(bitmap, sPAPROptionVector, 1, bitmap_size),
+ VMSTATE_END_OF_LIST()
+ }
};
sPAPROptionVector *spapr_ovec_new(void)
@@ -45,6 +56,7 @@ sPAPROptionVector *spapr_ovec_new(void)
ov = g_new0(sPAPROptionVector, 1);
ov->bitmap = bitmap_new(OV_MAXBITS);
+ ov->bitmap_size = OV_MAXBITS;
return ov;
}
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index f9661b7d1a..fd6fc1d953 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1590,6 +1590,8 @@ static Property spapr_phb_properties[] = {
DEFINE_PROP_UINT64("pgsz", sPAPRPHBState, page_size_mask,
(1ULL << 12) | (1ULL << 16)),
DEFINE_PROP_UINT32("numa_node", sPAPRPHBState, numa_node, -1),
+ DEFINE_PROP_BOOL("pre-2.8-migration", sPAPRPHBState,
+ pre_2_8_migration, false),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1636,6 +1638,20 @@ static void spapr_pci_pre_save(void *opaque)
sphb->msi_devs[i].key = *(uint32_t *) key;
sphb->msi_devs[i].value = *(spapr_pci_msi *) value;
}
+
+ if (sphb->pre_2_8_migration) {
+ sphb->mig_liobn = sphb->dma_liobn[0];
+ sphb->mig_mem_win_addr = sphb->mem_win_addr;
+ sphb->mig_mem_win_size = sphb->mem_win_size;
+ sphb->mig_io_win_addr = sphb->io_win_addr;
+ sphb->mig_io_win_size = sphb->io_win_size;
+
+ if ((sphb->mem64_win_size != 0)
+ && (sphb->mem64_win_addr
+ == (sphb->mem_win_addr + sphb->mem_win_size))) {
+ sphb->mig_mem_win_size += sphb->mem64_win_size;
+ }
+ }
}
static int spapr_pci_post_load(void *opaque, int version_id)
@@ -1658,25 +1674,26 @@ static int spapr_pci_post_load(void *opaque, int version_id)
return 0;
}
-static bool version_before_3(void *opaque, int version_id)
+static bool pre_2_8_migration(void *opaque, int version_id)
{
- return version_id < 3;
+ sPAPRPHBState *sphb = opaque;
+
+ return sphb->pre_2_8_migration;
}
static const VMStateDescription vmstate_spapr_pci = {
.name = "spapr_pci",
- .version_id = 3,
+ .version_id = 2,
.minimum_version_id = 2,
.pre_save = spapr_pci_pre_save,
.post_load = spapr_pci_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT64_EQUAL(buid, sPAPRPHBState),
- VMSTATE_UNUSED_TEST(version_before_3,
- sizeof(uint32_t) /* dma_liobn[0] */
- + sizeof(uint64_t) /* mem_win_addr */
- + sizeof(uint64_t) /* mem_win_size */
- + sizeof(uint64_t) /* io_win_addr */
- + sizeof(uint64_t) /* io_win_size */),
+ VMSTATE_UINT32_TEST(mig_liobn, sPAPRPHBState, pre_2_8_migration),
+ VMSTATE_UINT64_TEST(mig_mem_win_addr, sPAPRPHBState, pre_2_8_migration),
+ VMSTATE_UINT64_TEST(mig_mem_win_size, sPAPRPHBState, pre_2_8_migration),
+ VMSTATE_UINT64_TEST(mig_io_win_addr, sPAPRPHBState, pre_2_8_migration),
+ VMSTATE_UINT64_TEST(mig_io_win_size, sPAPRPHBState, pre_2_8_migration),
VMSTATE_STRUCT_ARRAY(lsi_table, sPAPRPHBState, PCI_NUM_PINS, 0,
vmstate_spapr_pci_lsi, struct spapr_pci_lsi),
VMSTATE_INT32(msi_devs_num, sPAPRPHBState),
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 1f2f2d33dd..5a5a4e946a 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -406,11 +406,9 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
/* Data out. */
qemu_log_mask(LOG_UNIMP, "esp: PIO data read not implemented\n");
s->rregs[ESP_FIFO] = 0;
- esp_raise_irq(s);
} else if (s->ti_rptr < s->ti_wptr) {
s->ti_size--;
s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
- esp_raise_irq(s);
}
if (s->ti_rptr == s->ti_wptr) {
s->ti_rptr = 0;
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
index 1b3c2fb3c7..8e676e6c96 100644
--- a/hw/usb/xen-usb.c
+++ b/hw/usb/xen-usb.c
@@ -712,15 +712,10 @@ static void usbback_portid_detach(struct usbback_info *usbif, unsigned port)
static void usbback_portid_remove(struct usbback_info *usbif, unsigned port)
{
- USBPort *p;
-
if (!usbif->ports[port - 1].dev) {
return;
}
- p = &(usbif->ports[port - 1].port);
- snprintf(p->path, sizeof(p->path), "%d", 99);
-
object_unparent(OBJECT(usbif->ports[port - 1].dev));
usbif->ports[port - 1].dev = NULL;
usbback_portid_detach(usbif, port);
@@ -733,10 +728,10 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
{
unsigned speed;
char *portname;
- USBPort *p;
Error *local_err = NULL;
QDict *qdict;
QemuOpts *opts;
+ char *tmp;
if (usbif->ports[port - 1].dev) {
return;
@@ -749,11 +744,16 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
return;
}
portname++;
- p = &(usbif->ports[port - 1].port);
- snprintf(p->path, sizeof(p->path), "%s", portname);
qdict = qdict_new();
qdict_put(qdict, "driver", qstring_from_str("usb-host"));
+ tmp = g_strdup_printf("%s.0", usbif->xendev.qdev.id);
+ qdict_put(qdict, "bus", qstring_from_str(tmp));
+ g_free(tmp);
+ tmp = g_strdup_printf("%s-%u", usbif->xendev.qdev.id, port);
+ qdict_put(qdict, "id", qstring_from_str(tmp));
+ g_free(tmp);
+ qdict_put(qdict, "port", qint_from_int(port));
qdict_put(qdict, "hostbus", qint_from_int(atoi(busid)));
qdict_put(qdict, "hostport", qstring_from_str(portname));
opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
@@ -765,7 +765,6 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
goto err;
}
QDECREF(qdict);
- snprintf(p->path, sizeof(p->path), "%d", port);
speed = usbif->ports[port - 1].dev->speed;
switch (speed) {
case USB_SPEED_LOW:
@@ -799,7 +798,6 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
err:
QDECREF(qdict);
- snprintf(p->path, sizeof(p->path), "%d", 99);
xen_pv_printf(&usbif->xendev, 0, "device %s could not be opened\n", busid);
}
@@ -1012,13 +1010,13 @@ static void usbback_alloc(struct XenDevice *xendev)
usbif = container_of(xendev, struct usbback_info, xendev);
- usb_bus_new(&usbif->bus, sizeof(usbif->bus), &xen_usb_bus_ops, xen_sysdev);
+ usb_bus_new(&usbif->bus, sizeof(usbif->bus), &xen_usb_bus_ops,
+ DEVICE(&xendev->qdev));
for (i = 0; i < USBBACK_MAXPORTS; i++) {
p = &(usbif->ports[i].port);
usb_register_port(&usbif->bus, p, usbif, i, &xen_usb_port_ops,
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL |
USB_SPEED_MASK_HIGH);
- snprintf(p->path, sizeof(p->path), "%d", 99);
}
QTAILQ_INIT(&usbif->req_free_q);
@@ -1066,7 +1064,6 @@ static int usbback_free(struct XenDevice *xendev)
}
usb_bus_release(&usbif->bus);
- object_unparent(OBJECT(&usbif->bus));
TR_BUS(xendev, "finished\n");
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index 41ba5c585a..d1190041ae 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -27,16 +27,18 @@
#include "hw/hw.h"
#include "hw/sysbus.h"
+#include "hw/boards.h"
#include "sysemu/char.h"
#include "qemu/log.h"
+#include "qapi/error.h"
#include "hw/xen/xen_backend.h"
#include "hw/xen/xen_pvdev.h"
+#include "monitor/qdev.h"
#include <xen/grant_table.h>
-#define TYPE_XENSYSDEV "xensysdev"
-
DeviceState *xen_sysdev;
+BusState *xen_sysbus;
/* ------------------------------------------------------------- */
@@ -121,6 +123,12 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
/* init new xendev */
xendev = g_malloc0(ops->size);
+ object_initialize(&xendev->qdev, ops->size, TYPE_XENBACKEND);
+ qdev_set_parent_bus(&xendev->qdev, xen_sysbus);
+ qdev_set_id(&xendev->qdev, g_strdup_printf("xen-%s-%d", type, dev));
+ qdev_init_nofail(&xendev->qdev);
+ object_unref(OBJECT(&xendev->qdev));
+
xendev->type = type;
xendev->dom = dom;
xendev->dev = dev;
@@ -528,6 +536,8 @@ int xen_be_init(void)
xen_sysdev = qdev_create(NULL, TYPE_XENSYSDEV);
qdev_init_nofail(xen_sysdev);
+ xen_sysbus = qbus_create(TYPE_XENSYSBUS, DEVICE(xen_sysdev), "xen-sysbus");
+ qbus_set_bus_hotplug_handler(xen_sysbus, &error_abort);
return 0;
@@ -539,6 +549,15 @@ err:
return -1;
}
+static void xen_set_dynamic_sysbus(void)
+{
+ Object *machine = qdev_get_machine();
+ ObjectClass *oc = object_get_class(machine);
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->has_dynamic_sysbus = true;
+}
+
int xen_be_register(const char *type, struct XenDevOps *ops)
{
char path[50];
@@ -560,6 +579,8 @@ int xen_be_register(const char *type, struct XenDevOps *ops)
void xen_be_register_common(void)
{
+ xen_set_dynamic_sysbus();
+
xen_be_register("console", &xen_console_ops);
xen_be_register("vkbd", &xen_kbdmouse_ops);
xen_be_register("qdisk", &xen_blkdev_ops);
@@ -586,6 +607,42 @@ int xen_be_bind_evtchn(struct XenDevice *xendev)
}
+static Property xendev_properties[] = {
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xendev_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->props = xendev_properties;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static const TypeInfo xendev_type_info = {
+ .name = TYPE_XENBACKEND,
+ .parent = TYPE_XENSYSDEV,
+ .class_init = xendev_class_init,
+ .instance_size = sizeof(struct XenDevice),
+};
+
+static void xen_sysbus_class_init(ObjectClass *klass, void *data)
+{
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
+
+ hc->unplug = qdev_simple_device_unplug_cb;
+}
+
+static const TypeInfo xensysbus_info = {
+ .name = TYPE_XENSYSBUS,
+ .parent = TYPE_BUS,
+ .class_init = xen_sysbus_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
+};
+
static int xen_sysdev_init(SysBusDevice *dev)
{
return 0;
@@ -602,6 +659,7 @@ static void xen_sysdev_class_init(ObjectClass *klass, void *data)
k->init = xen_sysdev_init;
dc->props = xen_sysdev_properties;
+ dc->bus_type = TYPE_XENSYSBUS;
}
static const TypeInfo xensysdev_info = {
@@ -613,7 +671,9 @@ static const TypeInfo xensysdev_info = {
static void xenbe_register_types(void)
{
+ type_register_static(&xensysbus_info);
type_register_static(&xensysdev_info);
+ type_register_static(&xendev_type_info);
}
-type_init(xenbe_register_types);
+type_init(xenbe_register_types)
diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c
index 5212bc6d9e..aed783e844 100644
--- a/hw/xen/xen_pvdev.c
+++ b/hw/xen/xen_pvdev.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
+#include "hw/qdev-core.h"
#include "hw/xen/xen_backend.h"
#include "hw/xen/xen_pvdev.h"
@@ -307,7 +308,8 @@ void xen_pv_del_xendev(struct XenDevice *xendev)
}
QTAILQ_REMOVE(&xendevs, xendev, next);
- g_free(xendev);
+
+ qdev_unplug(&xendev->qdev, NULL);
}
void xen_pv_insert_xendev(struct XenDevice *xendev)
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index b573df53b0..6eb5fe80dc 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -401,7 +401,7 @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, target_ulong addr,
int access_type, int mmu_idx)
{
#if defined(CONFIG_USER_ONLY)
- return g2h(vaddr);
+ return g2h(addr);
#else
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
CPUTLBEntry *tlbentry = &env->tlb_table[mmu_idx][index];
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index b92c1b59f1..092294ed5a 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -79,6 +79,12 @@ struct sPAPRPHBState {
uint64_t dma64_win_addr;
uint32_t numa_node;
+
+ /* Fields for migration compatibility hacks */
+ bool pre_2_8_migration;
+ uint32_t mig_liobn;
+ hwaddr mig_mem_win_addr, mig_mem_win_size;
+ hwaddr mig_io_win_addr, mig_io_win_size;
};
#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL
diff --git a/include/hw/ppc/spapr_ovec.h b/include/hw/ppc/spapr_ovec.h
index 6a06da32e6..355a34411f 100644
--- a/include/hw/ppc/spapr_ovec.h
+++ b/include/hw/ppc/spapr_ovec.h
@@ -37,6 +37,7 @@
#define _SPAPR_OVEC_H
#include "cpu.h"
+#include "migration/vmstate.h"
typedef struct sPAPROptionVector sPAPROptionVector;
@@ -64,4 +65,7 @@ sPAPROptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector);
int spapr_ovec_populate_dt(void *fdt, int fdt_offset,
sPAPROptionVector *ov, const char *name);
+/* migration */
+extern const VMStateDescription vmstate_spapr_ovec;
+
#endif /* !defined (_SPAPR_OVEC_H) */
diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen_backend.h
index cbda40ee53..4f4799a610 100644
--- a/include/hw/xen/xen_backend.h
+++ b/include/hw/xen/xen_backend.h
@@ -6,12 +6,20 @@
#include "sysemu/sysemu.h"
#include "net/net.h"
+#define TYPE_XENSYSDEV "xen-sysdev"
+#define TYPE_XENSYSBUS "xen-sysbus"
+#define TYPE_XENBACKEND "xen-backend"
+
+#define XENBACKEND_DEVICE(obj) \
+ OBJECT_CHECK(XenDevice, (obj), TYPE_XENBACKEND)
+
/* variables */
extern xc_interface *xen_xc;
extern xenforeignmemory_handle *xen_fmem;
extern struct xs_handle *xenstore;
extern const char *xen_protocol;
extern DeviceState *xen_sysdev;
+extern BusState *xen_sysbus;
int xenstore_mkdir(char *path, int p);
int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val);
diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h
index 083f0a9cc7..d473e9b34d 100644
--- a/include/hw/xen/xen_pvdev.h
+++ b/include/hw/xen/xen_pvdev.h
@@ -29,6 +29,7 @@ struct XenDevOps {
};
struct XenDevice {
+ DeviceState qdev;
const char *type;
int dom;
int dev;
diff --git a/include/migration/cpu.h b/include/migration/cpu.h
index f3abbab650..f3d5dfcf61 100644
--- a/include/migration/cpu.h
+++ b/include/migration/cpu.h
@@ -18,6 +18,8 @@
VMSTATE_UINT64_EQUAL_V(_f, _s, _v)
#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v) \
VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v)
+#define VMSTATE_UINTTL_TEST(_f, _s, _t) \
+ VMSTATE_UINT64_TEST(_f, _s, _t)
#define vmstate_info_uinttl vmstate_info_uint64
#else
#define qemu_put_betl qemu_put_be32
@@ -35,6 +37,8 @@
VMSTATE_UINT32_EQUAL_V(_f, _s, _v)
#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v) \
VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v)
+#define VMSTATE_UINTTL_TEST(_f, _s, _t) \
+ VMSTATE_UINT32_TEST(_f, _s, _t)
#define vmstate_info_uinttl vmstate_info_uint32
#endif
diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h
index 8e504bc66b..0ff3331284 100644
--- a/include/monitor/qdev.h
+++ b/include/monitor/qdev.h
@@ -12,5 +12,6 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp);
int qdev_device_help(QemuOpts *opts);
DeviceState *qdev_device_add(QemuOpts *opts, Error **errp);
+void qdev_set_id(DeviceState *dev, const char *id);
#endif
diff --git a/pc-bios/bios-256k.bin b/pc-bios/bios-256k.bin
index 8dc4838a9b..229b5af986 100644
--- a/pc-bios/bios-256k.bin
+++ b/pc-bios/bios-256k.bin
Binary files differ
diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin
index 0b16c546ec..9a9b0f0106 100644
--- a/pc-bios/bios.bin
+++ b/pc-bios/bios.bin
Binary files differ
diff --git a/pc-bios/vgabios-cirrus.bin b/pc-bios/vgabios-cirrus.bin
index 67389ca75b..9dadce2345 100644
--- a/pc-bios/vgabios-cirrus.bin
+++ b/pc-bios/vgabios-cirrus.bin
Binary files differ
diff --git a/pc-bios/vgabios-qxl.bin b/pc-bios/vgabios-qxl.bin
index 9d3d9b4031..a89725c81c 100644
--- a/pc-bios/vgabios-qxl.bin
+++ b/pc-bios/vgabios-qxl.bin
Binary files differ
diff --git a/pc-bios/vgabios-stdvga.bin b/pc-bios/vgabios-stdvga.bin
index 6fc42b1289..ea041412a2 100644
--- a/pc-bios/vgabios-stdvga.bin
+++ b/pc-bios/vgabios-stdvga.bin
Binary files differ
diff --git a/pc-bios/vgabios-virtio.bin b/pc-bios/vgabios-virtio.bin
index b2e6e5a235..71e22fc868 100644
--- a/pc-bios/vgabios-virtio.bin
+++ b/pc-bios/vgabios-virtio.bin
Binary files differ
diff --git a/pc-bios/vgabios-vmware.bin b/pc-bios/vgabios-vmware.bin
index eccd87b458..ad239cbfe8 100644
--- a/pc-bios/vgabios-vmware.bin
+++ b/pc-bios/vgabios-vmware.bin
Binary files differ
diff --git a/pc-bios/vgabios.bin b/pc-bios/vgabios.bin
index 450230ab42..9947c2c26f 100644
--- a/pc-bios/vgabios.bin
+++ b/pc-bios/vgabios.bin
Binary files differ
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 4f78ecb091..c73410c02e 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -539,10 +539,28 @@ static BusState *qbus_find(const char *path, Error **errp)
return bus;
}
+void qdev_set_id(DeviceState *dev, const char *id)
+{
+ if (id) {
+ dev->id = id;
+ }
+
+ if (dev->id) {
+ object_property_add_child(qdev_get_peripheral(), dev->id,
+ OBJECT(dev), NULL);
+ } else {
+ static int anon_count;
+ gchar *name = g_strdup_printf("device[%d]", anon_count++);
+ object_property_add_child(qdev_get_peripheral_anon(), name,
+ OBJECT(dev), NULL);
+ g_free(name);
+ }
+}
+
DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
{
DeviceClass *dc;
- const char *driver, *path, *id;
+ const char *driver, *path;
DeviceState *dev;
BusState *bus = NULL;
Error *err = NULL;
@@ -591,21 +609,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
qdev_set_parent_bus(dev, bus);
}
- id = qemu_opts_id(opts);
- if (id) {
- dev->id = id;
- }
-
- if (dev->id) {
- object_property_add_child(qdev_get_peripheral(), dev->id,
- OBJECT(dev), NULL);
- } else {
- static int anon_count;
- gchar *name = g_strdup_printf("device[%d]", anon_count++);
- object_property_add_child(qdev_get_peripheral_anon(), name,
- OBJECT(dev), NULL);
- g_free(name);
- }
+ qdev_set_id(dev, qemu_opts_id(opts));
/* set properties */
if (qemu_opt_foreach(opts, set_property, dev, &err)) {
diff --git a/roms/seabios b/roms/seabios
-Subproject d7adf6044a4c772b497e97272adf97426b34a24
+Subproject 8891697e3f7d84355420573efd98e94f1473676
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 1c90adb5d7..2a50c43689 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1166,6 +1166,13 @@ struct PowerPCCPU {
int cpu_dt_id;
uint32_t max_compat;
uint32_t cpu_version;
+
+ /* Fields related to migration compatibility hacks */
+ bool pre_2_8_migration;
+ target_ulong mig_msr_mask;
+ uint64_t mig_insns_flags;
+ uint64_t mig_insns_flags2;
+ uint32_t mig_nb_BATs;
};
static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
index bb9ce60436..62138163a5 100644
--- a/target-ppc/helper_regs.h
+++ b/target-ppc/helper_regs.h
@@ -131,11 +131,14 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
}
/* If PR=1 then EE, IR and DR must be 1
*
- * Note: We only enforce this on 64-bit processors. It appears that
- * 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS
- * exploits it.
+ * Note: We only enforce this on 64-bit server processors.
+ * It appears that:
+ * - 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS
+ * exploits it.
+ * - 64-bit embedded implementations do not need any operation to be
+ * performed when PR is set.
*/
- if ((env->insns_flags & PPC_64B) && ((value >> MSR_PR) & 1)) {
+ if ((env->insns_flags & PPC_SEGMENT_64B) && ((value >> MSR_PR) & 1)) {
value |= (1 << MSR_EE) | (1 << MSR_DR) | (1 << MSR_IR);
}
#endif
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 9ac204a393..2d57c9a1c2 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -2572,7 +2572,7 @@ static int bcd_cmp_zero(ppc_avr_t *bcd)
static uint16_t get_national_digit(ppc_avr_t *reg, int n)
{
#if defined(HOST_WORDS_BIGENDIAN)
- return reg->u16[8 - n];
+ return reg->u16[7 - n];
#else
return reg->u16[n];
#endif
@@ -2581,7 +2581,7 @@ static uint16_t get_national_digit(ppc_avr_t *reg, int n)
static void set_national_digit(ppc_avr_t *reg, uint8_t val, int n)
{
#if defined(HOST_WORDS_BIGENDIAN)
- reg->u16[8 - n] = val;
+ reg->u16[7 - n] = val;
#else
reg->u16[n] = val;
#endif
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index e43cb6c39d..18c16d2512 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -135,11 +135,33 @@ static const VMStateInfo vmstate_info_avr = {
#define VMSTATE_AVR_ARRAY(_f, _s, _n) \
VMSTATE_AVR_ARRAY_V(_f, _s, _n, 0)
+static bool cpu_pre_2_8_migration(void *opaque, int version_id)
+{
+ PowerPCCPU *cpu = opaque;
+
+ return cpu->pre_2_8_migration;
+}
+
static void cpu_pre_save(void *opaque)
{
PowerPCCPU *cpu = opaque;
CPUPPCState *env = &cpu->env;
int i;
+ uint64_t insns_compat_mask =
+ PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB
+ | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES
+ | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES
+ | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT
+ | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ
+ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC
+ | PPC_64B | PPC_64BX | PPC_ALTIVEC
+ | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD;
+ uint64_t insns_compat_mask2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX
+ | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206
+ | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206
+ | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207
+ | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207
+ | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM;
env->spr[SPR_LR] = env->lr;
env->spr[SPR_CTR] = env->ctr;
@@ -161,6 +183,14 @@ static void cpu_pre_save(void *opaque)
env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4];
env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4];
}
+
+ /* Hacks for migration compatibility between 2.6, 2.7 & 2.8 */
+ if (cpu->pre_2_8_migration) {
+ cpu->mig_msr_mask = env->msr_mask;
+ cpu->mig_insns_flags = env->insns_flags & insns_compat_mask;
+ cpu->mig_insns_flags2 = env->insns_flags2 & insns_compat_mask2;
+ cpu->mig_nb_BATs = env->nb_BATs;
+ }
}
static int cpu_post_load(void *opaque, int version_id)
@@ -561,10 +591,11 @@ const VMStateDescription vmstate_ppc_cpu = {
/* FIXME: access_type? */
/* Sanity checking */
- VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
- VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
- VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
- VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
+ VMSTATE_UINTTL_TEST(mig_msr_mask, PowerPCCPU, cpu_pre_2_8_migration),
+ VMSTATE_UINT64_TEST(mig_insns_flags, PowerPCCPU, cpu_pre_2_8_migration),
+ VMSTATE_UINT64_TEST(mig_insns_flags2, PowerPCCPU,
+ cpu_pre_2_8_migration),
+ VMSTATE_UINT32_TEST(mig_nb_BATs, PowerPCCPU, cpu_pre_2_8_migration),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription*[]) {
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 208fa1ea53..626e03186c 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -10520,6 +10520,11 @@ static gchar *ppc_gdb_arch_name(CPUState *cs)
#endif
}
+static Property ppc_cpu_properties[] = {
+ DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void ppc_cpu_class_init(ObjectClass *oc, void *data)
{
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
@@ -10532,6 +10537,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
dc->realize = ppc_cpu_realizefn;
dc->unrealize = ppc_cpu_unrealizefn;
+ dc->props = ppc_cpu_properties;
pcc->parent_reset = cc->reset;
cc->reset = ppc_cpu_reset;
diff --git a/tests/postcopy-test.c b/tests/postcopy-test.c
index d6613c5fa4..dafe8beba4 100644
--- a/tests/postcopy-test.c
+++ b/tests/postcopy-test.c
@@ -380,17 +380,21 @@ static void test_migrate(void)
" -incoming %s",
tmpfs, bootpath, uri);
} else if (strcmp(arch, "ppc64") == 0) {
+ const char *accel;
+
+ /* On ppc64, the test only works with kvm-hv, but not with kvm-pr */
+ accel = access("/sys/module/kvm_hv", F_OK) ? "tcg" : "kvm:tcg";
init_bootfile_ppc(bootpath);
- cmd_src = g_strdup_printf("-machine accel=kvm:tcg -m 256M"
+ cmd_src = g_strdup_printf("-machine accel=%s -m 256M"
" -name pcsource,debug-threads=on"
" -serial file:%s/src_serial"
" -drive file=%s,if=pflash,format=raw",
- tmpfs, bootpath);
- cmd_dst = g_strdup_printf("-machine accel=kvm:tcg -m 256M"
+ accel, tmpfs, bootpath);
+ cmd_dst = g_strdup_printf("-machine accel=%s -m 256M"
" -name pcdest,debug-threads=on"
" -serial file:%s/dest_serial"
" -incoming %s",
- tmpfs, uri);
+ accel, tmpfs, uri);
} else {
g_assert_not_reached();
}
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 67c65893a4..f63146407f 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -45,6 +45,7 @@
#ifdef __FreeBSD__
#include <sys/sysctl.h>
+#include <sys/user.h>
#include <libutil.h>
#endif
diff --git a/xen-common.c b/xen-common.c
index bacf962841..909976071c 100644
--- a/xen-common.c
+++ b/xen-common.c
@@ -9,7 +9,6 @@
*/
#include "qemu/osdep.h"
-#include "hw/i386/pc.h"
#include "hw/xen/xen_backend.h"
#include "qmp-commands.h"
#include "sysemu/char.h"
@@ -115,11 +114,6 @@ static void xen_change_state_handler(void *opaque, int running,
static int xen_init(MachineState *ms)
{
- PCMachineState *pcms = PC_MACHINE(ms);
-
- /* Disable ACPI build because Xen handles it */
- pcms->acpi_build_enabled = false;
-
xen_xc = xc_interface_open(0, 0, 0);
if (xen_xc == NULL) {
xen_pv_printf(NULL, 0, "can't open xen interface\n");
diff --git a/xen-hvm.c b/xen-hvm.c
index 2f348edf86..99b8ee8a4f 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -810,6 +810,10 @@ static void cpu_ioreq_pio(ioreq_t *req)
trace_cpu_ioreq_pio(req, req->dir, req->df, req->data_is_ptr, req->addr,
req->data, req->count, req->size);
+ if (req->size > sizeof(uint32_t)) {
+ hw_error("PIO: bad size (%u)", req->size);
+ }
+
if (req->dir == IOREQ_READ) {
if (!req->data_is_ptr) {
req->data = do_inp(req->addr, req->size);
@@ -846,6 +850,10 @@ static void cpu_ioreq_move(ioreq_t *req)
trace_cpu_ioreq_move(req, req->dir, req->df, req->data_is_ptr, req->addr,
req->data, req->count, req->size);
+ if (req->size > sizeof(req->data)) {
+ hw_error("MMIO: bad size (%u)", req->size);
+ }
+
if (!req->data_is_ptr) {
if (req->dir == IOREQ_READ) {
for (i = 0; i < req->count; i++) {
@@ -1010,11 +1018,13 @@ static int handle_buffered_iopage(XenIOState *state)
req.df = 1;
req.type = buf_req->type;
req.data_is_ptr = 0;
+ xen_rmb();
qw = (req.size == 8);
if (qw) {
buf_req = &buf_page->buf_ioreq[(rdptr + 1) %
IOREQ_BUFFER_SLOT_NUM];
req.data |= ((uint64_t)buf_req->data) << 32;
+ xen_rmb();
}
handle_ioreq(state, &req);
@@ -1045,7 +1055,11 @@ static void cpu_handle_ioreq(void *opaque)
handle_buffered_iopage(state);
if (req) {
- handle_ioreq(state, req);
+ ioreq_t copy = *req;
+
+ xen_rmb();
+ handle_ioreq(state, &copy);
+ req->data = copy.data;
if (req->state != STATE_IOREQ_INPROCESS) {
fprintf(stderr, "Badness in I/O request ... not in service?!: "
@@ -1316,6 +1330,10 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
}
xen_be_register_common();
xen_read_physmap(state);
+
+ /* Disable ACPI build because Xen handles it */
+ pcms->acpi_build_enabled = false;
+
return;
err: