aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.objs1
-rw-r--r--block/curl.c241
-rw-r--r--block/qcow.c2
-rw-r--r--block/vdi.c2
-rw-r--r--block/vhdx.c2
-rw-r--r--block/vmdk.c2
-rw-r--r--block/vpc.c2
-rw-r--r--block/vvfat.c2
-rwxr-xr-xconfigure2
-rw-r--r--contrib/libvhost-user/libvhost-user.c26
-rw-r--r--contrib/libvhost-user/libvhost-user.h6
-rw-r--r--exec.c111
-rw-r--r--hmp.c9
-rw-r--r--hw/9pfs/9p.c2
-rw-r--r--hw/9pfs/xen-9p-backend.c4
-rw-r--r--hw/acpi/aml-build.c27
-rw-r--r--hw/acpi/piix4.c13
-rw-r--r--hw/arm/spitz.c2
-rw-r--r--hw/arm/virt-acpi-build.c26
-rw-r--r--hw/audio/marvell_88w8618.c2
-rw-r--r--hw/audio/pcspk.c2
-rw-r--r--hw/core/or-irq.c2
-rw-r--r--hw/core/qdev.c21
-rw-r--r--hw/core/register.c2
-rw-r--r--hw/core/sysbus.c11
-rw-r--r--hw/display/qxl.c2
-rw-r--r--hw/display/virtio-gpu.c2
-rw-r--r--hw/dma/i8257.c2
-rw-r--r--hw/dma/sparc32_dma.c2
-rw-r--r--hw/gpio/omap_gpio.c4
-rw-r--r--hw/i2c/omap_i2c.c2
-rw-r--r--hw/i2c/smbus_eeprom.c2
-rw-r--r--hw/i2c/smbus_ich9.c2
-rw-r--r--hw/i386/acpi-build.c4
-rw-r--r--hw/i386/amd_iommu.c17
-rw-r--r--hw/i386/intel_iommu.c16
-rw-r--r--hw/i386/pc.c11
-rw-r--r--hw/i386/pc_piix.c16
-rw-r--r--hw/i386/pc_q35.c14
-rw-r--r--hw/i386/xen/xen-mapcache.c15
-rw-r--r--hw/input/vmmouse.c2
-rw-r--r--hw/intc/apic_common.c2
-rw-r--r--hw/intc/arm_gic_kvm.c2
-rw-r--r--hw/intc/arm_gicv3_its_kvm.c2
-rw-r--r--hw/intc/arm_gicv3_kvm.c2
-rw-r--r--hw/intc/etraxfs_pic.c2
-rw-r--r--hw/intc/grlib_irqmp.c2
-rw-r--r--hw/intc/i8259_common.c2
-rw-r--r--hw/intc/nios2_iic.c2
-rw-r--r--hw/intc/omap_intc.c4
-rw-r--r--hw/isa/lpc_ich9.c2
-rw-r--r--hw/isa/piix4.c2
-rw-r--r--hw/isa/vt82c686.c2
-rw-r--r--hw/mips/gt64xxx_pci.c2
-rw-r--r--hw/misc/ivshmem.c2
-rw-r--r--hw/misc/vmport.c2
-rw-r--r--hw/net/dp8393x.c2
-rw-r--r--hw/net/etraxfs_eth.c2
-rw-r--r--hw/net/fsl_etsec/etsec.c2
-rw-r--r--hw/net/lance.c2
-rw-r--r--hw/pci-bridge/dec.c2
-rw-r--r--hw/pci-bridge/pci_bridge_dev.c2
-rw-r--r--hw/pci-bridge/pci_expander_bridge.c2
-rw-r--r--hw/pci-host/apb.c2
-rw-r--r--hw/pci-host/bonito.c2
-rw-r--r--hw/pci-host/gpex.c2
-rw-r--r--hw/pci-host/grackle.c2
-rw-r--r--hw/pci-host/piix.c6
-rw-r--r--hw/pci-host/ppce500.c2
-rw-r--r--hw/pci-host/prep.c2
-rw-r--r--hw/pci-host/q35.c4
-rw-r--r--hw/pci-host/uninorth.c8
-rw-r--r--hw/pci-host/versatile.c2
-rw-r--r--hw/pci-host/xilinx-pcie.c2
-rw-r--r--hw/pci/pci.c1
-rw-r--r--hw/ppc/ppc4xx_pci.c2
-rw-r--r--hw/ppc/spapr_drc.c2
-rw-r--r--hw/ppc/spapr_pci.c2
-rw-r--r--hw/s390x/s390-pci-bus.c1
-rw-r--r--hw/scsi/vhost-scsi.c2
-rw-r--r--hw/sd/milkymist-memcard.c2
-rw-r--r--hw/sd/pl181.c2
-rw-r--r--hw/sh4/sh_pci.c2
-rw-r--r--hw/timer/i8254_common.c2
-rw-r--r--hw/timer/mc146818rtc.c2
-rw-r--r--hw/vfio/amd-xgbe.c2
-rw-r--r--hw/vfio/calxeda-xgmac.c2
-rw-r--r--hw/virtio/vhost-user.c21
-rw-r--r--hw/virtio/vhost.c2
-rw-r--r--hw/virtio/virtio.c4
-rw-r--r--hw/xen/xen_backend.c4
-rw-r--r--include/hw/acpi/acpi-defs.h45
-rw-r--r--include/hw/acpi/aml-build.h3
-rw-r--r--include/hw/compat.h6
-rw-r--r--include/hw/i386/pc.h10
-rw-r--r--include/hw/qdev-core.h9
-rw-r--r--include/hw/qdev-properties.h4
-rw-r--r--include/migration/blocker.h35
-rw-r--r--include/migration/migration.h50
-rw-r--r--include/migration/vmstate.h2
-rw-r--r--include/sysemu/sysemu.h6
-rw-r--r--include/sysemu/xen-mapcache.h5
-rw-r--r--migration/Makefile.objs2
-rw-r--r--migration/migration.c34
-rw-r--r--migration/page_cache.c (renamed from page_cache.c)0
-rw-r--r--migration/page_cache.h (renamed from include/migration/page_cache.h)0
-rw-r--r--migration/postcopy-ram.c18
-rw-r--r--migration/postcopy-ram.h26
-rw-r--r--migration/ram.c35
-rw-r--r--migration/savevm.c61
-rw-r--r--monitor.c2
-rw-r--r--qapi/block-core.json12
-rw-r--r--qdev-monitor.c6
-rw-r--r--qom/cpu.c2
-rw-r--r--replay/replay-snapshot.c8
-rw-r--r--stubs/migr-blocker.c2
-rw-r--r--stubs/vmstate.c5
-rw-r--r--target/i386/cpu.c2
-rw-r--r--target/i386/kvm.c2
-rw-r--r--tests/Makefile.include2
-rw-r--r--tests/bios-tables-test.c4
-rw-r--r--tests/test-x86-cpuid-compat.c111
-rw-r--r--vl.c4
123 files changed, 829 insertions, 454 deletions
diff --git a/Makefile.objs b/Makefile.objs
index 6167e7b17d..2100845ce2 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -49,7 +49,6 @@ common-obj-$(CONFIG_POSIX) += os-posix.o
common-obj-$(CONFIG_LINUX) += fsdev/
common-obj-y += migration/
-common-obj-y += page_cache.o #aio.o
common-obj-$(CONFIG_SPICE) += spice-qemu-char.o
diff --git a/block/curl.c b/block/curl.c
index aa6e8cc0e5..2a244e2439 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -76,15 +76,12 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
#define CURL_TIMEOUT_DEFAULT 5
#define CURL_TIMEOUT_MAX 10000
-#define FIND_RET_NONE 0
-#define FIND_RET_OK 1
-#define FIND_RET_WAIT 2
-
#define CURL_BLOCK_OPT_URL "url"
#define CURL_BLOCK_OPT_READAHEAD "readahead"
#define CURL_BLOCK_OPT_SSLVERIFY "sslverify"
#define CURL_BLOCK_OPT_TIMEOUT "timeout"
#define CURL_BLOCK_OPT_COOKIE "cookie"
+#define CURL_BLOCK_OPT_COOKIE_SECRET "cookie-secret"
#define CURL_BLOCK_OPT_USERNAME "username"
#define CURL_BLOCK_OPT_PASSWORD_SECRET "password-secret"
#define CURL_BLOCK_OPT_PROXY_USERNAME "proxy-username"
@@ -93,14 +90,17 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
struct BDRVCURLState;
typedef struct CURLAIOCB {
- BlockAIOCB common;
+ Coroutine *co;
QEMUIOVector *qiov;
- int64_t sector_num;
- int nb_sectors;
+ uint64_t offset;
+ uint64_t bytes;
+ int ret;
size_t start;
size_t end;
+
+ QSIMPLEQ_ENTRY(CURLAIOCB) next;
} CURLAIOCB;
typedef struct CURLSocket {
@@ -115,7 +115,7 @@ typedef struct CURLState
CURL *curl;
QLIST_HEAD(, CURLSocket) sockets;
char *orig_buf;
- size_t buf_start;
+ uint64_t buf_start;
size_t buf_off;
size_t buf_len;
char range[128];
@@ -126,7 +126,7 @@ typedef struct CURLState
typedef struct BDRVCURLState {
CURLM *multi;
QEMUTimer timer;
- size_t len;
+ uint64_t len;
CURLState states[CURL_NUM_STATES];
char *url;
size_t readahead_size;
@@ -136,6 +136,7 @@ typedef struct BDRVCURLState {
bool accept_range;
AioContext *aio_context;
QemuMutex mutex;
+ QSIMPLEQ_HEAD(, CURLAIOCB) free_state_waitq;
char *username;
char *password;
char *proxyusername;
@@ -147,6 +148,7 @@ static void curl_multi_do(void *arg);
static void curl_multi_read(void *arg);
#ifdef NEED_CURL_TIMER_CALLBACK
+/* Called from curl_multi_do_locked, with s->mutex held. */
static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
{
BDRVCURLState *s = opaque;
@@ -163,6 +165,7 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
}
#endif
+/* Called from curl_multi_do_locked, with s->mutex held. */
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
void *userp, void *sp)
{
@@ -212,6 +215,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
return 0;
}
+/* Called from curl_multi_do_locked, with s->mutex held. */
static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
{
BDRVCURLState *s = opaque;
@@ -226,6 +230,7 @@ static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
return realsize;
}
+/* Called from curl_multi_do_locked, with s->mutex held. */
static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
{
CURLState *s = ((CURLState*)opaque);
@@ -253,7 +258,7 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
continue;
if ((s->buf_off >= acb->end)) {
- size_t request_length = acb->nb_sectors * BDRV_SECTOR_SIZE;
+ size_t request_length = acb->bytes;
qemu_iovec_from_buf(acb->qiov, 0, s->orig_buf + acb->start,
acb->end - acb->start);
@@ -264,9 +269,11 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
request_length - offset);
}
- acb->common.cb(acb->common.opaque, 0);
- qemu_aio_unref(acb);
+ acb->ret = 0;
s->acb[i] = NULL;
+ qemu_mutex_unlock(&s->s->mutex);
+ aio_co_wake(acb->co);
+ qemu_mutex_lock(&s->s->mutex);
}
}
@@ -275,18 +282,19 @@ read_end:
return size * nmemb;
}
-static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
- CURLAIOCB *acb)
+/* Called with s->mutex held. */
+static bool curl_find_buf(BDRVCURLState *s, uint64_t start, uint64_t len,
+ CURLAIOCB *acb)
{
int i;
- size_t end = start + len;
- size_t clamped_end = MIN(end, s->len);
- size_t clamped_len = clamped_end - start;
+ uint64_t end = start + len;
+ uint64_t clamped_end = MIN(end, s->len);
+ uint64_t clamped_len = clamped_end - start;
for (i=0; i<CURL_NUM_STATES; i++) {
CURLState *state = &s->states[i];
- size_t buf_end = (state->buf_start + state->buf_off);
- size_t buf_fend = (state->buf_start + state->buf_len);
+ uint64_t buf_end = (state->buf_start + state->buf_off);
+ uint64_t buf_fend = (state->buf_start + state->buf_len);
if (!state->orig_buf)
continue;
@@ -305,9 +313,8 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
if (clamped_len < len) {
qemu_iovec_memset(acb->qiov, clamped_len, 0, len - clamped_len);
}
- acb->common.cb(acb->common.opaque, 0);
-
- return FIND_RET_OK;
+ acb->ret = 0;
+ return true;
}
// Wait for unfinished chunks
@@ -325,13 +332,13 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
for (j=0; j<CURL_NUM_ACB; j++) {
if (!state->acb[j]) {
state->acb[j] = acb;
- return FIND_RET_WAIT;
+ return true;
}
}
}
}
- return FIND_RET_NONE;
+ return false;
}
/* Called with s->mutex held. */
@@ -376,11 +383,11 @@ static void curl_multi_check_completion(BDRVCURLState *s)
continue;
}
+ acb->ret = -EIO;
+ state->acb[i] = NULL;
qemu_mutex_unlock(&s->mutex);
- acb->common.cb(acb->common.opaque, -EIO);
+ aio_co_wake(acb->co);
qemu_mutex_lock(&s->mutex);
- qemu_aio_unref(acb);
- state->acb[i] = NULL;
}
}
@@ -449,32 +456,28 @@ static void curl_multi_timeout_do(void *arg)
#endif
}
-static CURLState *curl_init_state(BlockDriverState *bs, BDRVCURLState *s)
+/* Called with s->mutex held. */
+static CURLState *curl_find_state(BDRVCURLState *s)
{
CURLState *state = NULL;
- int i, j;
-
- do {
- for (i=0; i<CURL_NUM_STATES; i++) {
- for (j=0; j<CURL_NUM_ACB; j++)
- if (s->states[i].acb[j])
- continue;
- if (s->states[i].in_use)
- continue;
+ int i;
+ for (i = 0; i < CURL_NUM_STATES; i++) {
+ if (!s->states[i].in_use) {
state = &s->states[i];
state->in_use = 1;
break;
}
- if (!state) {
- aio_poll(bdrv_get_aio_context(bs), true);
- }
- } while(!state);
+ }
+ return state;
+}
+static int curl_init_state(BDRVCURLState *s, CURLState *state)
+{
if (!state->curl) {
state->curl = curl_easy_init();
if (!state->curl) {
- return NULL;
+ return -EIO;
}
curl_easy_setopt(state->curl, CURLOPT_URL, s->url);
curl_easy_setopt(state->curl, CURLOPT_SSL_VERIFYPEER,
@@ -527,11 +530,18 @@ static CURLState *curl_init_state(BlockDriverState *bs, BDRVCURLState *s)
QLIST_INIT(&state->sockets);
state->s = s;
- return state;
+ return 0;
}
+/* Called with s->mutex held. */
static void curl_clean_state(CURLState *s)
{
+ CURLAIOCB *next;
+ int j;
+ for (j = 0; j < CURL_NUM_ACB; j++) {
+ assert(!s->acb[j]);
+ }
+
if (s->s->multi)
curl_multi_remove_handle(s->s->multi, s->curl);
@@ -543,6 +553,14 @@ static void curl_clean_state(CURLState *s)
}
s->in_use = 0;
+
+ next = QSIMPLEQ_FIRST(&s->s->free_state_waitq);
+ if (next) {
+ QSIMPLEQ_REMOVE_HEAD(&s->s->free_state_waitq, next);
+ qemu_mutex_unlock(&s->s->mutex);
+ aio_co_wake(next->co);
+ qemu_mutex_lock(&s->s->mutex);
+ }
}
static void curl_parse_filename(const char *filename, QDict *options,
@@ -556,6 +574,7 @@ static void curl_detach_aio_context(BlockDriverState *bs)
BDRVCURLState *s = bs->opaque;
int i;
+ qemu_mutex_lock(&s->mutex);
for (i = 0; i < CURL_NUM_STATES; i++) {
if (s->states[i].in_use) {
curl_clean_state(&s->states[i]);
@@ -571,6 +590,7 @@ static void curl_detach_aio_context(BlockDriverState *bs)
curl_multi_cleanup(s->multi);
s->multi = NULL;
}
+ qemu_mutex_unlock(&s->mutex);
timer_del(&s->timer);
}
@@ -624,6 +644,11 @@ static QemuOptsList runtime_opts = {
.help = "Pass the cookie or list of cookies with each request"
},
{
+ .name = CURL_BLOCK_OPT_COOKIE_SECRET,
+ .type = QEMU_OPT_STRING,
+ .help = "ID of secret used as cookie passed with each request"
+ },
+ {
.name = CURL_BLOCK_OPT_USERNAME,
.type = QEMU_OPT_STRING,
.help = "Username for HTTP auth"
@@ -657,6 +682,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
Error *local_err = NULL;
const char *file;
const char *cookie;
+ const char *cookie_secret;
double d;
const char *secretid;
const char *protocol_delimiter;
@@ -668,6 +694,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
return -EROFS;
}
+ qemu_mutex_init(&s->mutex);
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
@@ -693,7 +720,22 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
s->sslverify = qemu_opt_get_bool(opts, CURL_BLOCK_OPT_SSLVERIFY, true);
cookie = qemu_opt_get(opts, CURL_BLOCK_OPT_COOKIE);
- s->cookie = g_strdup(cookie);
+ cookie_secret = qemu_opt_get(opts, CURL_BLOCK_OPT_COOKIE_SECRET);
+
+ if (cookie && cookie_secret) {
+ error_setg(errp,
+ "curl driver cannot handle both cookie and cookie secret");
+ goto out_noclean;
+ }
+
+ if (cookie_secret) {
+ s->cookie = qcrypto_secret_lookup_as_utf8(cookie_secret, errp);
+ if (!s->cookie) {
+ goto out_noclean;
+ }
+ } else {
+ s->cookie = g_strdup(cookie);
+ }
file = qemu_opt_get(opts, CURL_BLOCK_OPT_URL);
if (file == NULL) {
@@ -736,14 +778,22 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
}
DPRINTF("CURL: Opening %s\n", file);
+ QSIMPLEQ_INIT(&s->free_state_waitq);
s->aio_context = bdrv_get_aio_context(bs);
s->url = g_strdup(file);
- state = curl_init_state(bs, s);
- if (!state)
+ qemu_mutex_lock(&s->mutex);
+ state = curl_find_state(s);
+ qemu_mutex_unlock(&s->mutex);
+ if (!state) {
goto out_noclean;
+ }
// Get file size
+ if (curl_init_state(s, state) < 0) {
+ goto out;
+ }
+
s->accept_range = false;
curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1);
curl_easy_setopt(state->curl, CURLOPT_HEADERFUNCTION,
@@ -771,7 +821,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
}
#endif
- s->len = (size_t)d;
+ s->len = d;
if ((!strncasecmp(s->url, "http://", strlen("http://"))
|| !strncasecmp(s->url, "https://", strlen("https://")))
@@ -780,13 +830,14 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
"Server does not support 'range' (byte ranges).");
goto out;
}
- DPRINTF("CURL: Size = %zd\n", s->len);
+ DPRINTF("CURL: Size = %" PRIu64 "\n", s->len);
+ qemu_mutex_lock(&s->mutex);
curl_clean_state(state);
+ qemu_mutex_unlock(&s->mutex);
curl_easy_cleanup(state->curl);
state->curl = NULL;
- qemu_mutex_init(&s->mutex);
curl_attach_aio_context(bs, bdrv_get_aio_context(bs));
qemu_opts_del(opts);
@@ -797,53 +848,51 @@ out:
curl_easy_cleanup(state->curl);
state->curl = NULL;
out_noclean:
+ qemu_mutex_destroy(&s->mutex);
g_free(s->cookie);
g_free(s->url);
qemu_opts_del(opts);
return -EINVAL;
}
-static const AIOCBInfo curl_aiocb_info = {
- .aiocb_size = sizeof(CURLAIOCB),
-};
-
-
-static void curl_readv_bh_cb(void *p)
+static void curl_setup_preadv(BlockDriverState *bs, CURLAIOCB *acb)
{
CURLState *state;
int running;
- int ret = -EINPROGRESS;
- CURLAIOCB *acb = p;
- BlockDriverState *bs = acb->common.bs;
BDRVCURLState *s = bs->opaque;
- size_t start = acb->sector_num * BDRV_SECTOR_SIZE;
- size_t end;
+ uint64_t start = acb->offset;
+ uint64_t end;
qemu_mutex_lock(&s->mutex);
// In case we have the requested data already (e.g. read-ahead),
// we can just call the callback and be done.
- switch (curl_find_buf(s, start, acb->nb_sectors * BDRV_SECTOR_SIZE, acb)) {
- case FIND_RET_OK:
- qemu_aio_unref(acb);
- // fall through
- case FIND_RET_WAIT:
- goto out;
- default:
- break;
+ if (curl_find_buf(s, start, acb->bytes, acb)) {
+ goto out;
}
// No cache found, so let's start a new request
- state = curl_init_state(acb->common.bs, s);
- if (!state) {
- ret = -EIO;
+ for (;;) {
+ state = curl_find_state(s);
+ if (state) {
+ break;
+ }
+ QSIMPLEQ_INSERT_TAIL(&s->free_state_waitq, acb, next);
+ qemu_mutex_unlock(&s->mutex);
+ qemu_coroutine_yield();
+ qemu_mutex_lock(&s->mutex);
+ }
+
+ if (curl_init_state(s, state) < 0) {
+ curl_clean_state(state);
+ acb->ret = -EIO;
goto out;
}
acb->start = 0;
- acb->end = MIN(acb->nb_sectors * BDRV_SECTOR_SIZE, s->len - start);
+ acb->end = MIN(acb->bytes, s->len - start);
state->buf_off = 0;
g_free(state->orig_buf);
@@ -853,14 +902,14 @@ static void curl_readv_bh_cb(void *p)
state->orig_buf = g_try_malloc(state->buf_len);
if (state->buf_len && state->orig_buf == NULL) {
curl_clean_state(state);
- ret = -ENOMEM;
+ acb->ret = -ENOMEM;
goto out;
}
state->acb[0] = acb;
- snprintf(state->range, 127, "%zd-%zd", start, end);
- DPRINTF("CURL (AIO): Reading %llu at %zd (%s)\n",
- (acb->nb_sectors * BDRV_SECTOR_SIZE), start, state->range);
+ snprintf(state->range, 127, "%" PRIu64 "-%" PRIu64, start, end);
+ DPRINTF("CURL (AIO): Reading %" PRIu64 " at %" PRIu64 " (%s)\n",
+ acb->bytes, start, state->range);
curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range);
curl_multi_add_handle(s->multi, state->curl);
@@ -870,26 +919,24 @@ static void curl_readv_bh_cb(void *p)
out:
qemu_mutex_unlock(&s->mutex);
- if (ret != -EINPROGRESS) {
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_unref(acb);
- }
}
-static BlockAIOCB *curl_aio_readv(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockCompletionFunc *cb, void *opaque)
+static int coroutine_fn curl_co_preadv(BlockDriverState *bs,
+ uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
{
- CURLAIOCB *acb;
-
- acb = qemu_aio_get(&curl_aiocb_info, bs, cb, opaque);
-
- acb->qiov = qiov;
- acb->sector_num = sector_num;
- acb->nb_sectors = nb_sectors;
-
- aio_bh_schedule_oneshot(bdrv_get_aio_context(bs), curl_readv_bh_cb, acb);
- return &acb->common;
+ CURLAIOCB acb = {
+ .co = qemu_coroutine_self(),
+ .ret = -EINPROGRESS,
+ .qiov = qiov,
+ .offset = offset,
+ .bytes = bytes
+ };
+
+ curl_setup_preadv(bs, &acb);
+ while (acb.ret == -EINPROGRESS) {
+ qemu_coroutine_yield();
+ }
+ return acb.ret;
}
static void curl_close(BlockDriverState *bs)
@@ -920,7 +967,7 @@ static BlockDriver bdrv_http = {
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
- .bdrv_aio_readv = curl_aio_readv,
+ .bdrv_co_preadv = curl_co_preadv,
.bdrv_detach_aio_context = curl_detach_aio_context,
.bdrv_attach_aio_context = curl_attach_aio_context,
@@ -936,7 +983,7 @@ static BlockDriver bdrv_https = {
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
- .bdrv_aio_readv = curl_aio_readv,
+ .bdrv_co_preadv = curl_co_preadv,
.bdrv_detach_aio_context = curl_detach_aio_context,
.bdrv_attach_aio_context = curl_attach_aio_context,
@@ -952,7 +999,7 @@ static BlockDriver bdrv_ftp = {
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
- .bdrv_aio_readv = curl_aio_readv,
+ .bdrv_co_preadv = curl_co_preadv,
.bdrv_detach_aio_context = curl_detach_aio_context,
.bdrv_attach_aio_context = curl_attach_aio_context,
@@ -968,7 +1015,7 @@ static BlockDriver bdrv_ftps = {
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
- .bdrv_aio_readv = curl_aio_readv,
+ .bdrv_co_preadv = curl_co_preadv,
.bdrv_detach_aio_context = curl_detach_aio_context,
.bdrv_attach_aio_context = curl_attach_aio_context,
diff --git a/block/qcow.c b/block/qcow.c
index 5d147b962e..95ab123407 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -32,7 +32,7 @@
#include <zlib.h>
#include "qapi/qmp/qerror.h"
#include "crypto/cipher.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
/**************************************************************/
/* QEMU COW block driver with compression and encryption support */
diff --git a/block/vdi.c b/block/vdi.c
index d12d9cdc79..79af47763b 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -55,7 +55,7 @@
#include "sysemu/block-backend.h"
#include "qemu/module.h"
#include "qemu/bswap.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "qemu/coroutine.h"
#include "qemu/cutils.h"
#include "qemu/uuid.h"
diff --git a/block/vhdx.c b/block/vhdx.c
index e8fe3fb5e9..8b270b57c9 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -24,7 +24,7 @@
#include "qemu/crc32c.h"
#include "qemu/bswap.h"
#include "block/vhdx.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "qemu/uuid.h"
/* Options for VHDX creation */
diff --git a/block/vmdk.c b/block/vmdk.c
index c61b9cc8e0..55581b03fe 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -31,7 +31,7 @@
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/bswap.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "qemu/cutils.h"
#include <zlib.h>
diff --git a/block/vpc.c b/block/vpc.c
index ecfee77149..4240ba9d1c 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -28,7 +28,7 @@
#include "block/block_int.h"
#include "sysemu/block-backend.h"
#include "qemu/module.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "qemu/bswap.h"
#include "qemu/uuid.h"
diff --git a/block/vvfat.c b/block/vvfat.c
index 9c82371360..426ca70e35 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -28,7 +28,7 @@
#include "block/block_int.h"
#include "qemu/module.h"
#include "qemu/bswap.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "qapi/qmp/qint.h"
#include "qapi/qmp/qbool.h"
#include "qapi/qmp/qstring.h"
diff --git a/configure b/configure
index 57b5ae600b..139638e922 100755
--- a/configure
+++ b/configure
@@ -2015,7 +2015,7 @@ if test "$xen" != "no" ; then
else
xen_libs="-lxenstore -lxenctrl -lxenguest"
- xen_stable_libs="-lxencall -lxenforeignmemory -lxengnttab -lxenevtchn"
+ xen_stable_libs="-lxenforeignmemory -lxengnttab -lxenevtchn"
# First we test whether Xen headers and libraries are available.
# If no, we are done and there is no Xen support.
diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
index 61e1657e41..9efb9dac0e 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -1031,6 +1031,11 @@ vu_queue_get_avail_bytes(VuDev *dev, VuVirtq *vq, unsigned int *in_bytes,
idx = vq->last_avail_idx;
total_bufs = in_total = out_total = 0;
+ if (unlikely(dev->broken) ||
+ unlikely(!vq->vring.avail)) {
+ goto done;
+ }
+
while ((rc = virtqueue_num_heads(dev, vq, idx)) > 0) {
unsigned int max, num_bufs, indirect = 0;
struct vring_desc *desc;
@@ -1121,11 +1126,16 @@ vu_queue_avail_bytes(VuDev *dev, VuVirtq *vq, unsigned int in_bytes,
/* Fetch avail_idx from VQ memory only when we really need to know if
* guest has added some buffers. */
-int
+bool
vu_queue_empty(VuDev *dev, VuVirtq *vq)
{
+ if (unlikely(dev->broken) ||
+ unlikely(!vq->vring.avail)) {
+ return true;
+ }
+
if (vq->shadow_avail_idx != vq->last_avail_idx) {
- return 0;
+ return false;
}
return vring_avail_idx(vq) == vq->last_avail_idx;
@@ -1174,7 +1184,8 @@ vring_notify(VuDev *dev, VuVirtq *vq)
void
vu_queue_notify(VuDev *dev, VuVirtq *vq)
{
- if (unlikely(dev->broken)) {
+ if (unlikely(dev->broken) ||
+ unlikely(!vq->vring.avail)) {
return;
}
@@ -1291,7 +1302,8 @@ vu_queue_pop(VuDev *dev, VuVirtq *vq, size_t sz)
struct vring_desc *desc;
int rc;
- if (unlikely(dev->broken)) {
+ if (unlikely(dev->broken) ||
+ unlikely(!vq->vring.avail)) {
return NULL;
}
@@ -1445,7 +1457,8 @@ vu_queue_fill(VuDev *dev, VuVirtq *vq,
{
struct vring_used_elem uelem;
- if (unlikely(dev->broken)) {
+ if (unlikely(dev->broken) ||
+ unlikely(!vq->vring.avail)) {
return;
}
@@ -1474,7 +1487,8 @@ vu_queue_flush(VuDev *dev, VuVirtq *vq, unsigned int count)
{
uint16_t old, new;
- if (unlikely(dev->broken)) {
+ if (unlikely(dev->broken) ||
+ unlikely(!vq->vring.avail)) {
return;
}
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
index 156b50e989..af02a31ebe 100644
--- a/contrib/libvhost-user/libvhost-user.h
+++ b/contrib/libvhost-user/libvhost-user.h
@@ -327,13 +327,13 @@ void vu_queue_set_notification(VuDev *dev, VuVirtq *vq, int enable);
bool vu_queue_enabled(VuDev *dev, VuVirtq *vq);
/**
- * vu_queue_enabled:
+ * vu_queue_empty:
* @dev: a VuDev context
* @vq: a VuVirtq queue
*
- * Returns: whether the queue is empty.
+ * Returns: true if the queue is empty or not ready.
*/
-int vu_queue_empty(VuDev *dev, VuVirtq *vq);
+bool vu_queue_empty(VuDev *dev, VuVirtq *vq);
/**
* vu_queue_notify:
diff --git a/exec.c b/exec.c
index 821bef3476..96e3ac98e1 100644
--- a/exec.c
+++ b/exec.c
@@ -465,18 +465,20 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
}
/* Called from RCU critical section */
-IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
- bool is_write)
+static MemoryRegionSection address_space_do_translate(AddressSpace *as,
+ hwaddr addr,
+ hwaddr *xlat,
+ hwaddr *plen,
+ bool is_write,
+ bool is_mmio)
{
- IOMMUTLBEntry iotlb = {0};
+ IOMMUTLBEntry iotlb;
MemoryRegionSection *section;
MemoryRegion *mr;
for (;;) {
AddressSpaceDispatch *d = atomic_rcu_read(&as->dispatch);
- section = address_space_lookup_region(d, addr, false);
- addr = addr - section->offset_within_address_space
- + section->offset_within_region;
+ section = address_space_translate_internal(d, addr, &addr, plen, is_mmio);
mr = section->mr;
if (!mr->iommu_ops) {
@@ -484,55 +486,88 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
}
iotlb = mr->iommu_ops->translate(mr, addr, is_write);
+ addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
+ | (addr & iotlb.addr_mask));
+ *plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
if (!(iotlb.perm & (1 << is_write))) {
- iotlb.target_as = NULL;
- break;
+ goto translate_fail;
}
- addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
- | (addr & iotlb.addr_mask));
as = iotlb.target_as;
}
- return iotlb;
+ *xlat = addr;
+
+ return *section;
+
+translate_fail:
+ return (MemoryRegionSection) { .mr = &io_mem_unassigned };
}
/* Called from RCU critical section */
-MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
- hwaddr *xlat, hwaddr *plen,
- bool is_write)
+IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
+ bool is_write)
{
- IOMMUTLBEntry iotlb;
- MemoryRegionSection *section;
- MemoryRegion *mr;
+ MemoryRegionSection section;
+ hwaddr xlat, plen;
- for (;;) {
- AddressSpaceDispatch *d = atomic_rcu_read(&as->dispatch);
- section = address_space_translate_internal(d, addr, &addr, plen, true);
- mr = section->mr;
+ /* Try to get maximum page mask during translation. */
+ plen = (hwaddr)-1;
- if (!mr->iommu_ops) {
- break;
- }
+ /* This can never be MMIO. */
+ section = address_space_do_translate(as, addr, &xlat, &plen,
+ is_write, false);
- iotlb = mr->iommu_ops->translate(mr, addr, is_write);
- addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
- | (addr & iotlb.addr_mask));
- *plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
- if (!(iotlb.perm & (1 << is_write))) {
- mr = &io_mem_unassigned;
- break;
- }
+ /* Illegal translation */
+ if (section.mr == &io_mem_unassigned) {
+ goto iotlb_fail;
+ }
- as = iotlb.target_as;
+ /* Convert memory region offset into address space offset */
+ xlat += section.offset_within_address_space -
+ section.offset_within_region;
+
+ if (plen == (hwaddr)-1) {
+ /*
+ * We use default page size here. Logically it only happens
+ * for identity mappings.
+ */
+ plen = TARGET_PAGE_SIZE;
}
+ /* Convert to address mask */
+ plen -= 1;
+
+ return (IOMMUTLBEntry) {
+ .target_as = section.address_space,
+ .iova = addr & ~plen,
+ .translated_addr = xlat & ~plen,
+ .addr_mask = plen,
+ /* IOTLBs are for DMAs, and DMA only allows on RAMs. */
+ .perm = IOMMU_RW,
+ };
+
+iotlb_fail:
+ return (IOMMUTLBEntry) {0};
+}
+
+/* Called from RCU critical section */
+MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
+ hwaddr *xlat, hwaddr *plen,
+ bool is_write)
+{
+ MemoryRegion *mr;
+ MemoryRegionSection section;
+
+ /* This can be MMIO, so setup MMIO bit. */
+ section = address_space_do_translate(as, addr, xlat, plen, is_write, true);
+ mr = section.mr;
+
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
*plen = MIN(page, *plen);
}
- *xlat = addr;
return mr;
}
@@ -2106,10 +2141,10 @@ void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
* In that case just map until the end of the page.
*/
if (block->offset == 0) {
- return xen_map_cache(addr, 0, 0);
+ return xen_map_cache(addr, 0, 0, false);
}
- block->host = xen_map_cache(block->offset, block->max_length, 1);
+ block->host = xen_map_cache(block->offset, block->max_length, 1, false);
}
return ramblock_ptr(block, addr);
}
@@ -2139,10 +2174,10 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
* In that case just map the requested area.
*/
if (block->offset == 0) {
- return xen_map_cache(addr, *size, 1);
+ return xen_map_cache(addr, *size, 1, true);
}
- block->host = xen_map_cache(block->offset, block->max_length, 1);
+ block->host = xen_map_cache(block->offset, block->max_length, 1, true);
}
return ramblock_ptr(block, addr);
diff --git a/hmp.c b/hmp.c
index e0ba13cb12..3dceaf809b 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1275,17 +1275,22 @@ void hmp_loadvm(Monitor *mon, const QDict *qdict)
{
int saved_vm_running = runstate_is_running();
const char *name = qdict_get_str(qdict, "name");
+ Error *err = NULL;
vm_stop(RUN_STATE_RESTORE_VM);
- if (load_vmstate(name) == 0 && saved_vm_running) {
+ if (load_vmstate(name, &err) == 0 && saved_vm_running) {
vm_start();
}
+ hmp_handle_error(mon, &err);
}
void hmp_savevm(Monitor *mon, const QDict *qdict)
{
- save_vmstate(qdict_get_try_str(qdict, "name"));
+ Error *err = NULL;
+
+ save_vmstate(qdict_get_try_str(qdict, "name"), &err);
+ hmp_handle_error(mon, &err);
}
void hmp_delvm(Monitor *mon, const QDict *qdict)
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index c80ba67389..ab3e22f231 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -23,7 +23,7 @@
#include "9p-xattr.h"
#include "coth.h"
#include "trace.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
int open_fd_hw;
int total_open_fd;
diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c
index 9c7f41af99..5df97c90fa 100644
--- a/hw/9pfs/xen-9p-backend.c
+++ b/hw/9pfs/xen-9p-backend.c
@@ -332,12 +332,14 @@ static int xen_9pfs_connect(struct XenDevice *xendev)
str = g_strdup_printf("ring-ref%u", i);
if (xenstore_read_fe_int(&xen_9pdev->xendev, str,
&xen_9pdev->rings[i].ref) == -1) {
+ g_free(str);
goto out;
}
g_free(str);
str = g_strdup_printf("event-channel-%u", i);
if (xenstore_read_fe_int(&xen_9pdev->xendev, str,
&xen_9pdev->rings[i].evtchn) == -1) {
+ g_free(str);
goto out;
}
g_free(str);
@@ -378,7 +380,7 @@ static int xen_9pfs_connect(struct XenDevice *xendev)
if (xen_9pdev->rings[i].evtchndev == NULL) {
goto out;
}
- fcntl(xenevtchn_fd(xen_9pdev->rings[i].evtchndev), F_SETFD, FD_CLOEXEC);
+ qemu_set_cloexec(xenevtchn_fd(xen_9pdev->rings[i].evtchndev));
xen_9pdev->rings[i].local_port = xenevtchn_bind_interdomain
(xen_9pdev->rings[i].evtchndev,
xendev->dom,
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index be496c817c..36a6cc450e 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1600,6 +1600,33 @@ build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
(void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
}
+/* Build xsdt table */
+void
+build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
+ const char *oem_id, const char *oem_table_id)
+{
+ int i;
+ unsigned xsdt_entries_offset;
+ AcpiXsdtDescriptorRev2 *xsdt;
+ const unsigned table_data_len = (sizeof(uint64_t) * table_offsets->len);
+ const unsigned xsdt_entry_size = sizeof(xsdt->table_offset_entry[0]);
+ const size_t xsdt_len = sizeof(*xsdt) + table_data_len;
+
+ xsdt = acpi_data_push(table_data, xsdt_len);
+ xsdt_entries_offset = (char *)xsdt->table_offset_entry - table_data->data;
+ for (i = 0; i < table_offsets->len; ++i) {
+ uint64_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
+ uint64_t xsdt_entry_offset = xsdt_entries_offset + xsdt_entry_size * i;
+
+ /* xsdt->table_offset_entry to be filled by Guest linker */
+ bios_linker_loader_add_pointer(linker,
+ ACPI_BUILD_TABLE_FILE, xsdt_entry_offset, xsdt_entry_size,
+ ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
+ }
+ build_header(linker, table_data,
+ (void *)xsdt, "XSDT", xsdt_len, 1, oem_id, oem_table_id);
+}
+
void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
uint64_t len, int node, MemoryAffinityFlags flags)
{
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index a553a7e110..f276967365 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -385,7 +385,10 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
dev, errp);
}
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
- acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, errp);
+ if (!xen_enabled()) {
+ acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
+ errp);
+ }
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
if (s->cpu_hotplug_legacy) {
legacy_acpi_cpu_plug_cb(hotplug_dev, &s->gpe_cpu, dev, errp);
@@ -408,8 +411,10 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug,
dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
- acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
- errp);
+ if (!xen_enabled()) {
+ acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
+ errp);
+ }
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
!s->cpu_hotplug_legacy) {
acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
@@ -700,7 +705,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
* Reason: part of PIIX4 southbridge, needs to be wired up,
* e.g. by mips_malta_init()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->hotpluggable = false;
hc->plug = piix4_device_plug_cb;
hc->unplug_request = piix4_device_unplug_request_cb;
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index fe2d5a764c..324626847c 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -1076,7 +1076,7 @@ static void sl_nand_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_sl_nand_info;
dc->props = sl_nand_properties;
/* Reason: init() method uses drive_get() */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo sl_nand_info = {
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index ce7499c9ca..e5852067f5 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -364,12 +364,12 @@ static void acpi_dsdt_add_power_button(Aml *scope)
/* RSDP */
static GArray *
-build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
+build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset)
{
AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
- unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address);
- unsigned rsdt_pa_offset =
- (char *)&rsdp->rsdt_physical_address - rsdp_table->data;
+ unsigned xsdt_pa_size = sizeof(rsdp->xsdt_physical_address);
+ unsigned xsdt_pa_offset =
+ (char *)&rsdp->xsdt_physical_address - rsdp_table->data;
bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
true /* fseg memory */);
@@ -381,8 +381,8 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
/* Address to be filled by Guest linker */
bios_linker_loader_add_pointer(linker,
- ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size,
- ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset);
+ ACPI_BUILD_RSDP_FILE, xsdt_pa_offset, xsdt_pa_size,
+ ACPI_BUILD_TABLE_FILE, xsdt_tbl_offset);
/* Checksum to be filled by Guest linker */
bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
@@ -654,7 +654,7 @@ static void build_fadt(GArray *table_data, BIOSLinker *linker,
VirtMachineState *vms, unsigned dsdt_tbl_offset)
{
AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
- unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
+ unsigned xdsdt_entry_offset = (char *)&fadt->x_dsdt - table_data->data;
uint16_t bootflags;
switch (vms->psci_conduit) {
@@ -680,7 +680,7 @@ static void build_fadt(GArray *table_data, BIOSLinker *linker,
/* DSDT address to be filled by Guest linker */
bios_linker_loader_add_pointer(linker,
- ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
+ ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->x_dsdt),
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
build_header(linker, table_data,
@@ -743,7 +743,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
{
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
GArray *table_offsets;
- unsigned dsdt, rsdt;
+ unsigned dsdt, xsdt;
GArray *tables_blob = tables->table_data;
table_offsets = g_array_new(false, true /* clear */,
@@ -783,12 +783,12 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
build_iort(tables_blob, tables->linker);
}
- /* RSDT is pointed to by RSDP */
- rsdt = tables_blob->len;
- build_rsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
+ /* XSDT is pointed to by RSDP */
+ xsdt = tables_blob->len;
+ build_xsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
/* RSDP is in FSEG memory, so allocate it separately */
- build_rsdp(tables->rsdp, tables->linker, rsdt);
+ build_rsdp(tables->rsdp, tables->linker, xsdt);
/* Cleanup memory that's no longer used. */
g_array_free(table_offsets, true);
diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c
index 511b004287..4f65f8c199 100644
--- a/hw/audio/marvell_88w8618.c
+++ b/hw/audio/marvell_88w8618.c
@@ -292,7 +292,7 @@ static void mv88w8618_audio_class_init(ObjectClass *klass, void *data)
dc->vmsd = &mv88w8618_audio_vmsd;
dc->props = mv88w8618_audio_properties;
/* Reason: pointer property "wm8750" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo mv88w8618_audio_info = {
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index 798002277b..9b99358d87 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -223,7 +223,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_spk;
dc->props = pcspk_properties;
/* Reason: realize sets global pcspk_state */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo pcspk_info = {
diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c
index 1485d5b285..f9d76c4641 100644
--- a/hw/core/or-irq.c
+++ b/hw/core/or-irq.c
@@ -91,7 +91,7 @@ static void or_irq_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_or_irq;
/* Reason: Needs to be wired up to work, e.g. see stm32f205_soc.c */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo or_irq_type_info = {
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 02b632f6b3..71ff95fd71 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -37,7 +37,7 @@
#include "hw/boards.h"
#include "hw/sysbus.h"
#include "qapi-event.h"
-#include "migration/migration.h"
+#include "migration/vmstate.h"
bool qdev_hotplug = false;
static bool qdev_hot_added = false;
@@ -861,6 +861,20 @@ static bool device_get_realized(Object *obj, Error **errp)
return dev->realized;
}
+static bool check_only_migratable(Object *obj, Error **err)
+{
+ DeviceClass *dc = DEVICE_GET_CLASS(obj);
+
+ if (!vmstate_check_only_migratable(dc->vmsd)) {
+ error_setg(err, "Device %s is not migratable, but "
+ "--only-migratable was specified",
+ object_get_typename(obj));
+ return false;
+ }
+
+ return true;
+}
+
static void device_set_realized(Object *obj, bool value, Error **errp)
{
DeviceState *dev = DEVICE(obj);
@@ -870,7 +884,6 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
Error *local_err = NULL;
bool unattached_parent = false;
static int unattached_count;
- int ret;
if (dev->hotplugged && !dc->hotpluggable) {
error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
@@ -878,8 +891,7 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
}
if (value && !dev->realized) {
- ret = check_migratable(obj, &local_err);
- if (ret < 0) {
+ if (!check_only_migratable(obj, &local_err)) {
goto fail;
}
@@ -1118,6 +1130,7 @@ static void device_class_init(ObjectClass *class, void *data)
* should override it in their class_init()
*/
dc->hotpluggable = true;
+ dc->user_creatable = true;
}
void device_reset(DeviceState *dev)
diff --git a/hw/core/register.c b/hw/core/register.c
index dc335a79a9..da38ef3a54 100644
--- a/hw/core/register.c
+++ b/hw/core/register.c
@@ -288,7 +288,7 @@ static void register_class_init(ObjectClass *oc, void *data)
DeviceClass *dc = DEVICE_CLASS(oc);
/* Reason: needs to be wired up to work */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo register_info = {
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index c0f560b289..5d0887f499 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -326,6 +326,17 @@ static void sysbus_device_class_init(ObjectClass *klass, void *data)
DeviceClass *k = DEVICE_CLASS(klass);
k->init = sysbus_device_init;
k->bus_type = TYPE_SYSTEM_BUS;
+ /*
+ * device_add plugs devices into a suitable bus. For "real" buses,
+ * that actually connects the device. For sysbus, the connections
+ * need to be made separately, and device_add can't do that. The
+ * device would be left unconnected, and will probably not work
+ *
+ * However, a few machines can handle device_add/-device with
+ * a few specific sysbus devices. In those cases, the device
+ * subclass needs to override it and set user_creatable=true.
+ */
+ k->user_creatable = false;
}
static const TypeInfo sysbus_device_type_info = {
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 4d94cecd72..ad09bb98f9 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -26,7 +26,7 @@
#include "qemu/queue.h"
#include "qemu/atomic.h"
#include "sysemu/sysemu.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "trace.h"
#include "qxl.h"
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index cfb5dfa336..58dc0b2737 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -19,7 +19,7 @@
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-gpu.h"
#include "hw/virtio/virtio-bus.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "qemu/log.h"
#include "qapi/error.h"
diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c
index 8bd82e8bc8..bd23e893bf 100644
--- a/hw/dma/i8257.c
+++ b/hw/dma/i8257.c
@@ -601,7 +601,7 @@ static void i8257_class_init(ObjectClass *klass, void *data)
idc->schedule = i8257_dma_schedule;
idc->register_channel = i8257_dma_register_channel;
/* Reason: needs to be wired up by isa_bus_dma() to work */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo i8257_info = {
diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index 9d545e412e..9c6bdc6295 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -305,7 +305,7 @@ static void sparc32_dma_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_dma;
dc->props = sparc32_dma_properties;
/* Reason: pointer property "iommu_opaque" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo sparc32_dma_info = {
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
index dabef4a119..1df394eb12 100644
--- a/hw/gpio/omap_gpio.c
+++ b/hw/gpio/omap_gpio.c
@@ -773,7 +773,7 @@ static void omap_gpio_class_init(ObjectClass *klass, void *data)
dc->reset = omap_gpif_reset;
dc->props = omap_gpio_properties;
/* Reason: pointer property "clk" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo omap_gpio_info = {
@@ -804,7 +804,7 @@ static void omap2_gpio_class_init(ObjectClass *klass, void *data)
dc->reset = omap2_gpif_reset;
dc->props = omap2_gpio_properties;
/* Reason: pointer properties "iclk", "fclk0", ..., "fclk5" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo omap2_gpio_info = {
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
index f7c92ea00c..f6e80bee25 100644
--- a/hw/i2c/omap_i2c.c
+++ b/hw/i2c/omap_i2c.c
@@ -491,7 +491,7 @@ static void omap_i2c_class_init(ObjectClass *klass, void *data)
dc->props = omap_i2c_properties;
dc->reset = omap_i2c_reset;
/* Reason: pointer properties "iclk", "fclk" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->realize = omap_i2c_realize;
}
diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c
index 5b7bd891bc..b13ec0fe7a 100644
--- a/hw/i2c/smbus_eeprom.c
+++ b/hw/i2c/smbus_eeprom.c
@@ -123,7 +123,7 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
sc->read_data = eeprom_read_data;
dc->props = smbus_eeprom_properties;
/* Reason: pointer property "data" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo smbus_eeprom_info = {
diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
index 48fab22625..ea51e09186 100644
--- a/hw/i2c/smbus_ich9.c
+++ b/hw/i2c/smbus_ich9.c
@@ -103,7 +103,7 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data)
* Reason: part of ICH9 southbridge, needs to be wired up by
* pc_q35_init()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index cc0418f327..afcadacd2e 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -341,7 +341,7 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
AcpiFadtDescriptorRev3 *fadt = acpi_data_push(table_data, sizeof(*fadt));
unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
- unsigned xdsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
+ unsigned xdsdt_entry_offset = (char *)&fadt->x_dsdt - table_data->data;
/* FACS address to be filled by Guest linker */
bios_linker_loader_add_pointer(linker,
@@ -354,7 +354,7 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
bios_linker_loader_add_pointer(linker,
- ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->Xdsdt),
+ ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->x_dsdt),
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
build_header(linker, table_data,
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index f86a40aa30..329058dac8 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -21,6 +21,7 @@
*/
#include "qemu/osdep.h"
#include "hw/i386/amd_iommu.h"
+#include "qapi/error.h"
#include "qemu/error-report.h"
#include "trace.h"
@@ -1137,7 +1138,19 @@ static void amdvi_realize(DeviceState *dev, Error **err)
int ret = 0;
AMDVIState *s = AMD_IOMMU_DEVICE(dev);
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
- PCIBus *bus = PC_MACHINE(qdev_get_machine())->bus;
+ MachineState *ms = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ PCMachineState *pcms =
+ PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE));
+ PCIBus *bus;
+
+ if (!pcms) {
+ error_setg(err, "Machine-type '%s' not supported by amd-iommu",
+ mc->name);
+ return;
+ }
+
+ bus = pcms->bus;
s->iotlb = g_hash_table_new_full(amdvi_uint64_hash,
amdvi_uint64_equal, g_free, g_free);
@@ -1186,6 +1199,8 @@ static void amdvi_class_init(ObjectClass *klass, void* data)
dc->vmsd = &vmstate_amdvi;
dc->hotpluggable = false;
dc_class->realize = amdvi_realize;
+ /* Supported by the pc-q35-* machine types */
+ dc->user_creatable = true;
}
static const TypeInfo amdvi = {
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 02f047c8e3..9ba2162cd9 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2969,11 +2969,21 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp)
static void vtd_realize(DeviceState *dev, Error **errp)
{
- PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
- PCIBus *bus = pcms->bus;
+ MachineState *ms = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ PCMachineState *pcms =
+ PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE));
+ PCIBus *bus;
IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev);
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
+ if (!pcms) {
+ error_setg(errp, "Machine-type '%s' not supported by intel-iommu",
+ mc->name);
+ return;
+ }
+
+ bus = pcms->bus;
VTD_DPRINTF(GENERAL, "");
x86_iommu->type = TYPE_INTEL;
@@ -3009,6 +3019,8 @@ static void vtd_class_init(ObjectClass *klass, void *data)
dc->hotpluggable = false;
x86_class->realize = vtd_realize;
x86_class->int_remap = vtd_int_remap;
+ /* Supported by the pc-q35-* machine types */
+ dc->user_creatable = true;
}
static const TypeInfo vtd_info = {
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e36a375683..816bfa872c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -597,7 +597,7 @@ static void port92_class_initfn(ObjectClass *klass, void *data)
* wiring: its A20 output line needs to be wired up by
* port92_init().
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo port92_info = {
@@ -1049,12 +1049,10 @@ static void load_linux(PCMachineState *pcms,
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);
- if (fw_cfg_dma_enabled(fw_cfg)) {
+ option_rom[nb_option_roms].bootindex = 0;
+ option_rom[nb_option_roms].name = "linuxboot.bin";
+ if (pcmc->linuxboot_dma_enabled && fw_cfg_dma_enabled(fw_cfg)) {
option_rom[nb_option_roms].name = "linuxboot_dma.bin";
- option_rom[nb_option_roms].bootindex = 0;
- } else {
- option_rom[nb_option_roms].name = "linuxboot.bin";
- option_rom[nb_option_roms].bootindex = 0;
}
nb_option_roms++;
}
@@ -2351,6 +2349,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
* to be used at the moment, 32K should be enough for a while. */
pcmc->acpi_data_size = 0x20000 + 0x8000;
pcmc->save_tsc_khz = true;
+ pcmc->linuxboot_dma_enabled = true;
mc->get_hotplug_handler = pc_get_hotpug_handler;
mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index d468b963fb..2234bd0461 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -438,7 +438,7 @@ static void pc_i440fx_machine_options(MachineClass *m)
m->default_display = "std";
}
-static void pc_i440fx_2_9_machine_options(MachineClass *m)
+static void pc_i440fx_2_10_machine_options(MachineClass *m)
{
pc_i440fx_machine_options(m);
m->alias = "pc";
@@ -446,14 +446,23 @@ static void pc_i440fx_2_9_machine_options(MachineClass *m)
m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
}
+DEFINE_I440FX_MACHINE(v2_10, "pc-i440fx-2.10", NULL,
+ pc_i440fx_2_10_machine_options);
+
+static void pc_i440fx_2_9_machine_options(MachineClass *m)
+{
+ pc_i440fx_2_10_machine_options(m);
+ m->is_default = 0;
+ m->alias = NULL;
+ SET_MACHINE_COMPAT(m, PC_COMPAT_2_9);
+}
+
DEFINE_I440FX_MACHINE(v2_9, "pc-i440fx-2.9", NULL,
pc_i440fx_2_9_machine_options);
static void pc_i440fx_2_8_machine_options(MachineClass *m)
{
pc_i440fx_2_9_machine_options(m);
- m->is_default = 0;
- m->alias = NULL;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_8);
}
@@ -476,6 +485,7 @@ static void pc_i440fx_2_6_machine_options(MachineClass *m)
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_i440fx_2_7_machine_options(m);
pcmc->legacy_cpu_hotplug = true;
+ pcmc->linuxboot_dma_enabled = false;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
}
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 66303a78cf..f243203844 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -302,20 +302,29 @@ static void pc_q35_machine_options(MachineClass *m)
m->max_cpus = 288;
}
-static void pc_q35_2_9_machine_options(MachineClass *m)
+static void pc_q35_2_10_machine_options(MachineClass *m)
{
pc_q35_machine_options(m);
m->alias = "q35";
m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
}
+DEFINE_Q35_MACHINE(v2_10, "pc-q35-2.10", NULL,
+ pc_q35_2_10_machine_options);
+
+static void pc_q35_2_9_machine_options(MachineClass *m)
+{
+ pc_q35_2_10_machine_options(m);
+ m->alias = NULL;
+ SET_MACHINE_COMPAT(m, PC_COMPAT_2_9);
+}
+
DEFINE_Q35_MACHINE(v2_9, "pc-q35-2.9", NULL,
pc_q35_2_9_machine_options);
static void pc_q35_2_8_machine_options(MachineClass *m)
{
pc_q35_2_9_machine_options(m);
- m->alias = NULL;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_8);
}
@@ -337,6 +346,7 @@ static void pc_q35_2_6_machine_options(MachineClass *m)
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_q35_2_7_machine_options(m);
pcmc->legacy_cpu_hotplug = true;
+ pcmc->linuxboot_dma_enabled = false;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
}
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 31debdfb2c..e60156c04f 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -62,6 +62,7 @@ typedef struct MapCacheRev {
hwaddr paddr_index;
hwaddr size;
QTAILQ_ENTRY(MapCacheRev) next;
+ bool dma;
} MapCacheRev;
typedef struct MapCache {
@@ -202,7 +203,7 @@ static void xen_remap_bucket(MapCacheEntry *entry,
}
static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
- uint8_t lock)
+ uint8_t lock, bool dma)
{
MapCacheEntry *entry, *pentry = NULL;
hwaddr address_index;
@@ -289,6 +290,7 @@ tryagain:
if (lock) {
MapCacheRev *reventry = g_malloc0(sizeof(MapCacheRev));
entry->lock++;
+ reventry->dma = dma;
reventry->vaddr_req = mapcache->last_entry->vaddr_base + address_offset;
reventry->paddr_index = mapcache->last_entry->paddr_index;
reventry->size = entry->size;
@@ -300,12 +302,12 @@ tryagain:
}
uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
- uint8_t lock)
+ uint8_t lock, bool dma)
{
uint8_t *p;
mapcache_lock();
- p = xen_map_cache_unlocked(phys_addr, size, lock);
+ p = xen_map_cache_unlocked(phys_addr, size, lock, dma);
mapcache_unlock();
return p;
}
@@ -426,8 +428,11 @@ void xen_invalidate_map_cache(void)
mapcache_lock();
QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
- DPRINTF("There should be no locked mappings at this time, "
- "but "TARGET_FMT_plx" -> %p is present\n",
+ if (!reventry->dma) {
+ continue;
+ }
+ fprintf(stderr, "Locked DMA mapping while invalidating mapcache!"
+ " "TARGET_FMT_plx" -> %p is present\n",
reventry->paddr_index, reventry->vaddr_req);
}
diff --git a/hw/input/vmmouse.c b/hw/input/vmmouse.c
index 6d15a887c6..4747da9a8d 100644
--- a/hw/input/vmmouse.c
+++ b/hw/input/vmmouse.c
@@ -286,7 +286,7 @@ static void vmmouse_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_vmmouse;
dc->props = vmmouse_properties;
/* Reason: pointer property "ps2_mouse" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo vmmouse_info = {
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index c3829e31b5..1ef56f8d10 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -501,7 +501,7 @@ static void apic_common_class_init(ObjectClass *klass, void *data)
* Reason: APIC and CPU need to be wired up by
* x86_cpu_apic_create()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo apic_common_type = {
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
index ec952ece93..af5cd367e9 100644
--- a/hw/intc/arm_gic_kvm.c
+++ b/hw/intc/arm_gic_kvm.c
@@ -24,7 +24,7 @@
#include "qemu-common.h"
#include "cpu.h"
#include "hw/sysbus.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "sysemu/kvm.h"
#include "kvm_arm.h"
#include "gic_internal.h"
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
index bd4f3aafc6..a0441d6bd1 100644
--- a/hw/intc/arm_gicv3_its_kvm.c
+++ b/hw/intc/arm_gicv3_its_kvm.c
@@ -24,7 +24,7 @@
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "kvm_arm.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#define TYPE_KVM_ARM_ITS "arm-its-kvm"
#define KVM_ARM_ITS(obj) OBJECT_CHECK(GICv3ITSState, (obj), TYPE_KVM_ARM_ITS)
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
index 19aab56072..4ee2baa691 100644
--- a/hw/intc/arm_gicv3_kvm.c
+++ b/hw/intc/arm_gicv3_kvm.c
@@ -28,7 +28,7 @@
#include "kvm_arm.h"
#include "gicv3_internal.h"
#include "vgic_common.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#ifdef DEBUG_GICV3_KVM
#define DPRINTF(fmt, ...) \
diff --git a/hw/intc/etraxfs_pic.c b/hw/intc/etraxfs_pic.c
index 64a6f4b4ba..1bfde2f09e 100644
--- a/hw/intc/etraxfs_pic.c
+++ b/hw/intc/etraxfs_pic.c
@@ -173,7 +173,7 @@ static void etraxfs_pic_class_init(ObjectClass *klass, void *data)
dc->props = etraxfs_pic_properties;
/*
* Note: pointer property "interrupt_vector" may remain null, thus
- * no need for dc->cannot_instantiate_with_device_add_yet = true;
+ * no need for dc->user_creatable = false;
*/
}
diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c
index ac7e63f38b..94659ee256 100644
--- a/hw/intc/grlib_irqmp.c
+++ b/hw/intc/grlib_irqmp.c
@@ -360,7 +360,7 @@ static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
dc->reset = grlib_irqmp_reset;
dc->props = grlib_irqmp_properties;
/* Reason: pointer properties "set_pil_in", "set_pil_in_opaque" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->realize = grlib_irqmp_realize;
}
diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c
index d9a5e8b217..c2fd563b5b 100644
--- a/hw/intc/i8259_common.c
+++ b/hw/intc/i8259_common.c
@@ -144,7 +144,7 @@ static void pic_common_class_init(ObjectClass *klass, void *data)
* wiring of the slave to the master is hard-coded in device model
* code.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo pic_common_type = {
diff --git a/hw/intc/nios2_iic.c b/hw/intc/nios2_iic.c
index 190b6fdbf3..016426f964 100644
--- a/hw/intc/nios2_iic.c
+++ b/hw/intc/nios2_iic.c
@@ -80,7 +80,7 @@ static void altera_iic_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
/* Reason: needs to be wired up, e.g. by nios2_10m50_ghrd_init() */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->realize = altera_iic_realize;
}
diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c
index 877be67971..ccdda89dab 100644
--- a/hw/intc/omap_intc.c
+++ b/hw/intc/omap_intc.c
@@ -401,7 +401,7 @@ static void omap_intc_class_init(ObjectClass *klass, void *data)
dc->reset = omap_inth_reset;
dc->props = omap_intc_properties;
/* Reason: pointer property "clk" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->realize = omap_intc_realize;
}
@@ -656,7 +656,7 @@ static void omap2_intc_class_init(ObjectClass *klass, void *data)
dc->reset = omap_inth_reset;
dc->props = omap2_intc_properties;
/* Reason: pointer property "iclk", "fclk" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->realize = omap2_intc_realize;
}
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index a0866c3856..e2215dcf4d 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -805,7 +805,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
* Reason: part of ICH9 southbridge, needs to be wired up by
* pc_q35_init()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
hc->plug = ich9_pm_device_plug_cb;
hc->unplug_request = ich9_pm_device_unplug_request_cb;
hc->unplug = ich9_pm_device_unplug_cb;
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 5500fcc4d6..f811eba59d 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -123,7 +123,7 @@ static void piix4_class_init(ObjectClass *klass, void *data)
* Reason: part of PIIX4 southbridge, needs to be wired up,
* e.g. by mips_malta_init()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->hotpluggable = false;
}
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 41d5254f8e..50dc83df77 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -494,7 +494,7 @@ static void via_class_init(ObjectClass *klass, void *data)
* Reason: part of VIA VT82C686 southbridge, needs to be wired up,
* e.g. by mips_fulong2e_init()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo via_info = {
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 4811843ab6..e8b2eef688 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -1224,7 +1224,7 @@ static void gt64120_pci_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo gt64120_pci_info = {
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 82ce8378bf..475e36a4c7 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -25,7 +25,7 @@
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
#include "sysemu/kvm.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "qemu/error-report.h"
#include "qemu/event_notifier.h"
#include "qom/object_interfaces.h"
diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
index be40930b8b..165500223f 100644
--- a/hw/misc/vmport.c
+++ b/hw/misc/vmport.c
@@ -163,7 +163,7 @@ static void vmport_class_initfn(ObjectClass *klass, void *data)
dc->realize = vmport_realizefn;
/* Reason: realize sets global port_state */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo vmport_info = {
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index efa33ad40a..b53fcaa8bc 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -934,7 +934,7 @@ static void dp8393x_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_dp8393x;
dc->props = dp8393x_properties;
/* Reason: dma_mr property can't be set */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo dp8393x_info = {
diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c
index efaa49faae..013c8d0a41 100644
--- a/hw/net/etraxfs_eth.c
+++ b/hw/net/etraxfs_eth.c
@@ -630,7 +630,7 @@ static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
k->init = fs_eth_init;
dc->props = etraxfs_eth_properties;
/* Reason: pointer properties "dma_out", "dma_in" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo etraxfs_eth_info = {
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
index aa2b0d5a85..9da1932970 100644
--- a/hw/net/fsl_etsec/etsec.c
+++ b/hw/net/fsl_etsec/etsec.c
@@ -416,6 +416,8 @@ static void etsec_class_init(ObjectClass *klass, void *data)
dc->realize = etsec_realize;
dc->reset = etsec_reset;
dc->props = etsec_properties;
+ /* Supported by ppce500 machine */
+ dc->user_creatable = true;
}
static TypeInfo etsec_info = {
diff --git a/hw/net/lance.c b/hw/net/lance.c
index 573d724bcf..92b0c68274 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -165,7 +165,7 @@ static void lance_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_lance;
dc->props = lance_properties;
/* Reason: pointer property "dma" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo lance_info = {
diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c
index 840c96198a..cca93620ac 100644
--- a/hw/pci-bridge/dec.c
+++ b/hw/pci-bridge/dec.c
@@ -128,7 +128,7 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo dec_21154_pci_host_info = {
diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
index 647ad80155..5dbd933cc1 100644
--- a/hw/pci-bridge/pci_bridge_dev.c
+++ b/hw/pci-bridge/pci_bridge_dev.c
@@ -163,7 +163,7 @@ static Property pci_bridge_dev_properties[] = {
DEFINE_PROP_ON_OFF_AUTO(PCI_BRIDGE_DEV_PROP_MSI, PCIBridgeDev, msi,
ON_OFF_AUTO_AUTO),
DEFINE_PROP_BIT(PCI_BRIDGE_DEV_PROP_SHPC, PCIBridgeDev, flags,
- PCI_BRIDGE_DEV_F_SHPC_REQ, false),
+ PCI_BRIDGE_DEV_F_SHPC_REQ, true),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
index 6ac187fa32..ff59abf208 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -150,7 +150,7 @@ static void pxb_host_class_init(ObjectClass *class, void *data)
dc->fw_name = "pci";
/* Reason: Internal part of the pxb/pxb-pcie device, not usable by itself */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
sbc->explicit_ofw_unit_address = pxb_host_ofw_unit_address;
hc->root_bus_path = pxb_host_root_bus_path;
}
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 653e711121..edc88f4c65 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -810,7 +810,7 @@ static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo pbm_pci_host_info = {
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 1999ece590..85a3bb0dd2 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -825,7 +825,7 @@ static void bonito_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo bonito_info = {
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
index 66055ee5cc..e2629ce70d 100644
--- a/hw/pci-host/gpex.c
+++ b/hw/pci-host/gpex.c
@@ -136,7 +136,7 @@ static void gpex_root_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo gpex_root_info = {
diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
index 2c8acdaaca..2e281f6155 100644
--- a/hw/pci-host/grackle.c
+++ b/hw/pci-host/grackle.c
@@ -134,7 +134,7 @@ static void grackle_pci_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo grackle_pci_info = {
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index bf4221d4bf..2d02de12d9 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -685,7 +685,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void *data)
* Reason: part of PIIX3 southbridge, needs to be wired up by
* pc_piix.c's pc_init1()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo piix3_pci_type_info = {
@@ -739,7 +739,7 @@ static void i440fx_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->hotpluggable = false;
}
@@ -868,7 +868,7 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
dc->fw_name = "pci";
dc->props = i440fx_props;
/* Reason: needs to be wired up by pc_init1 */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo i440fx_pcihost_info = {
diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index e502bc0505..becc0eeb76 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -508,7 +508,7 @@ static void e500_host_bridge_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo e500_host_bridge_info = {
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index 260a119a9e..900a6edfcf 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -364,7 +364,7 @@ static void raven_class_init(ObjectClass *klass, void *data)
* Reason: PCI-facing part of the host bridge, not usable without
* the host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo raven_info = {
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 344f77b10c..cd5c49616e 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -156,7 +156,7 @@ static void q35_host_class_init(ObjectClass *klass, void *data)
dc->realize = q35_host_realize;
dc->props = mch_props;
/* Reason: needs to be wired up by pc_q35_init */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->fw_name = "pci";
}
@@ -549,7 +549,7 @@ static void mch_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo mch_info = {
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index df342ac3cb..6cf5e59f86 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -366,7 +366,7 @@ static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo unin_main_pci_host_info = {
@@ -390,7 +390,7 @@ static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo u3_agp_pci_host_info = {
@@ -414,7 +414,7 @@ static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo unin_agp_pci_host_info = {
@@ -438,7 +438,7 @@ static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo unin_internal_pci_host_info = {
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 27fde46126..aa1fdf75fd 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -479,7 +479,7 @@ static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo versatile_pci_host_info = {
diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c
index 8b71e2d950..a968cea2af 100644
--- a/hw/pci-host/xilinx-pcie.c
+++ b/hw/pci-host/xilinx-pcie.c
@@ -309,7 +309,7 @@ static void xilinx_pcie_root_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo xilinx_pcie_root_info = {
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 259483b1c0..98ccc27533 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1083,6 +1083,7 @@ static void pci_qdev_unrealize(DeviceState *dev, Error **errp)
pc->exit(pci_dev);
}
+ pci_device_deassert_intx(pci_dev);
do_pci_unregister_device(pci_dev);
}
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index dc19682970..6953f8b9ac 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -351,7 +351,7 @@ static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo ppc4xx_host_bridge_info = {
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index a1cdc875b1..9fa5545991 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -675,7 +675,7 @@ static void spapr_dr_connector_class_init(ObjectClass *k, void *data)
/*
* Reason: it crashes FIXME find and document the real reason
*/
- dk->cannot_instantiate_with_device_add_yet = true;
+ dk->user_creatable = false;
}
static const TypeInfo spapr_dr_connector_info = {
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index e7567e2e8f..a7cff32bbf 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1994,6 +1994,8 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
dc->props = spapr_phb_properties;
dc->reset = spapr_phb_reset;
dc->vmsd = &vmstate_spapr_pci;
+ /* Supported by TYPE_SPAPR_MACHINE */
+ dc->user_creatable = true;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
hp->plug = spapr_phb_hot_plug_child;
hp->unplug = spapr_phb_hot_unplug_child;
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index a8a1bab50a..66a6fbeb8c 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -872,7 +872,6 @@ static void s390_pcihost_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
- dc->cannot_instantiate_with_device_add_yet = true;
dc->reset = s390_pcihost_reset;
k->init = s390_pcihost_init;
hc->plug = s390_pcihost_hot_plug;
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 8f53ac3795..cd4ab05233 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -21,7 +21,7 @@
#include "qemu/error-report.h"
#include "qemu/queue.h"
#include "monitor/monitor.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "hw/virtio/vhost-scsi.h"
#include "hw/virtio/vhost.h"
#include "hw/virtio/virtio-scsi.h"
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
index 1f2f0ed44a..4008c81002 100644
--- a/hw/sd/milkymist-memcard.c
+++ b/hw/sd/milkymist-memcard.c
@@ -299,7 +299,7 @@ static void milkymist_memcard_class_init(ObjectClass *klass, void *data)
dc->reset = milkymist_memcard_reset;
dc->vmsd = &vmstate_milkymist_memcard;
/* Reason: init() method uses drive_get_next() */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo milkymist_memcard_info = {
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
index 82c63a4fb5..55c8098ecd 100644
--- a/hw/sd/pl181.c
+++ b/hw/sd/pl181.c
@@ -515,7 +515,7 @@ static void pl181_class_init(ObjectClass *klass, void *data)
k->vmsd = &vmstate_pl181;
k->reset = pl181_reset;
/* Reason: init() method uses drive_get_next() */
- k->cannot_instantiate_with_device_add_yet = true;
+ k->user_creatable = false;
k->realize = pl181_realize;
}
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
index 1747628f3d..38395c082b 100644
--- a/hw/sh4/sh_pci.c
+++ b/hw/sh4/sh_pci.c
@@ -171,7 +171,7 @@ static void sh_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo sh_pci_host_info = {
diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
index e18299a482..976d5200f1 100644
--- a/hw/timer/i8254_common.c
+++ b/hw/timer/i8254_common.c
@@ -287,7 +287,7 @@ static void pit_common_class_init(ObjectClass *klass, void *data)
* wired to the HPET, and because of that, some wiring is always
* done by board code.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo pit_common_type = {
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 4165450250..93de3e1cc5 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -973,7 +973,7 @@ static void rtc_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_rtc;
dc->props = mc146818rtc_properties;
/* Reason: needs to be wired up by rtc_init() */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static void rtc_finalize(Object *obj)
diff --git a/hw/vfio/amd-xgbe.c b/hw/vfio/amd-xgbe.c
index 2c60310cf9..fab196cebf 100644
--- a/hw/vfio/amd-xgbe.c
+++ b/hw/vfio/amd-xgbe.c
@@ -38,6 +38,8 @@ static void vfio_amd_xgbe_class_init(ObjectClass *klass, void *data)
dc->realize = amd_xgbe_realize;
dc->desc = "VFIO AMD XGBE";
dc->vmsd = &vfio_platform_amd_xgbe_vmstate;
+ /* Supported by TYPE_VIRT_MACHINE */
+ dc->user_creatable = true;
}
static const TypeInfo vfio_amd_xgbe_dev_info = {
diff --git a/hw/vfio/calxeda-xgmac.c b/hw/vfio/calxeda-xgmac.c
index bb15d588e5..7bb17af7ad 100644
--- a/hw/vfio/calxeda-xgmac.c
+++ b/hw/vfio/calxeda-xgmac.c
@@ -38,6 +38,8 @@ static void vfio_calxeda_xgmac_class_init(ObjectClass *klass, void *data)
dc->realize = calxeda_xgmac_realize;
dc->desc = "VFIO Calxeda XGMAC";
dc->vmsd = &vfio_platform_calxeda_xgmac_vmstate;
+ /* Supported by TYPE_VIRT_MACHINE */
+ dc->user_creatable = true;
}
static const TypeInfo vfio_calxeda_xgmac_dev_info = {
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 9334a8ae22..32a95a8c69 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -163,22 +163,26 @@ fail:
}
static int process_message_reply(struct vhost_dev *dev,
- VhostUserRequest request)
+ VhostUserMsg msg)
{
- VhostUserMsg msg;
+ VhostUserMsg msg_reply;
- if (vhost_user_read(dev, &msg) < 0) {
+ if ((msg.flags & VHOST_USER_NEED_REPLY_MASK) == 0) {
+ return 0;
+ }
+
+ if (vhost_user_read(dev, &msg_reply) < 0) {
return -1;
}
- if (msg.request != request) {
+ if (msg_reply.request != msg.request) {
error_report("Received unexpected msg type."
"Expected %d received %d",
- request, msg.request);
+ msg.request, msg_reply.request);
return -1;
}
- return msg.payload.u64 ? -1 : 0;
+ return msg_reply.payload.u64 ? -1 : 0;
}
static bool vhost_user_one_time_request(VhostUserRequest request)
@@ -208,6 +212,7 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
* request, we just ignore it.
*/
if (vhost_user_one_time_request(msg->request) && dev->vq_index != 0) {
+ msg->flags &= ~VHOST_USER_NEED_REPLY_MASK;
return 0;
}
@@ -320,7 +325,7 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
}
if (reply_supported) {
- return process_message_reply(dev, msg.request);
+ return process_message_reply(dev, msg);
}
return 0;
@@ -712,7 +717,7 @@ static int vhost_user_net_set_mtu(struct vhost_dev *dev, uint16_t mtu)
/* If reply_ack supported, slave has to ack specified MTU is valid */
if (reply_supported) {
- return process_message_reply(dev, msg.request);
+ return process_message_reply(dev, msg);
}
return 0;
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 0001e60b77..03a46a7429 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -25,7 +25,7 @@
#include "exec/address-spaces.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/virtio-access.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "sysemu/dma.h"
/* enabled until disconnected backend stabilizes */
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 03592c542a..890b4d7eb7 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2451,12 +2451,12 @@ void GCC_FMT_ATTR(2, 3) virtio_error(VirtIODevice *vdev, const char *fmt, ...)
error_vreport(fmt, ap);
va_end(ap);
- vdev->broken = true;
-
if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
virtio_set_status(vdev, vdev->status | VIRTIO_CONFIG_S_NEEDS_RESET);
virtio_notify_config(vdev);
}
+
+ vdev->broken = true;
}
static void virtio_memory_listener_commit(MemoryListener *listener)
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index c85f1637e4..3570f37e56 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -147,7 +147,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
qdev_unplug(DEVICE(xendev), NULL);
return NULL;
}
- fcntl(xenevtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
+ qemu_set_cloexec(xenevtchn_fd(xendev->evtchndev));
if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
xendev->gnttabdev = xengnttab_open(NULL, 0);
@@ -619,6 +619,8 @@ static void xendev_class_init(ObjectClass *klass, void *data)
dc->props = xendev_properties;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ /* xen-backend devices can be plugged/unplugged dynamically */
+ dc->user_creatable = true;
}
static const TypeInfo xendev_type_info = {
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 293ee4524b..72be675dd6 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -81,8 +81,8 @@ typedef struct AcpiRsdpDescriptor AcpiRsdpDescriptor;
uint32_t asl_compiler_revision; /* ASL compiler revision number */
-struct AcpiTableHeader /* ACPI common table header */
-{
+/* ACPI common table header */
+struct AcpiTableHeader {
ACPI_TABLE_HEADER_DEF
} QEMU_PACKED;
typedef struct AcpiTableHeader AcpiTableHeader;
@@ -144,8 +144,8 @@ typedef struct AcpiTableHeader AcpiTableHeader;
/* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */ \
uint16_t arm_boot_flags; \
uint8_t minor_revision; /* FADT Minor Revision (ACPI 5.1) */ \
- uint64_t Xfacs; /* 64-bit physical address of FACS */ \
- uint64_t Xdsdt; /* 64-bit physical address of DSDT */ \
+ uint64_t x_facs; /* 64-bit physical address of FACS */ \
+ uint64_t x_dsdt; /* 64-bit physical address of DSDT */ \
/* 64-bit Extended Power Mgt 1a Event Reg Blk address */ \
struct AcpiGenericAddress xpm1a_event_block; \
/* 64-bit Extended Power Mgt 1b Event Reg Blk address */ \
@@ -224,8 +224,7 @@ typedef struct AcpiSerialPortConsoleRedirection
/*
* ACPI 1.0 Root System Description Table (RSDT)
*/
-struct AcpiRsdtDescriptorRev1
-{
+struct AcpiRsdtDescriptorRev1 {
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
uint32_t table_offset_entry[0]; /* Array of pointers to other */
/* ACPI tables */
@@ -233,10 +232,19 @@ struct AcpiRsdtDescriptorRev1
typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1;
/*
+ * ACPI 2.0 eXtended System Description Table (XSDT)
+ */
+struct AcpiXsdtDescriptorRev2 {
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ uint64_t table_offset_entry[0]; /* Array of pointers to other */
+ /* ACPI tables */
+} QEMU_PACKED;
+typedef struct AcpiXsdtDescriptorRev2 AcpiXsdtDescriptorRev2;
+
+/*
* ACPI 1.0 Firmware ACPI Control Structure (FACS)
*/
-struct AcpiFacsDescriptorRev1
-{
+struct AcpiFacsDescriptorRev1 {
uint32_t signature; /* ACPI Signature */
uint32_t length; /* Length of structure, in bytes */
uint32_t hardware_signature; /* Hardware configuration signature */
@@ -262,8 +270,7 @@ typedef struct AcpiFacsDescriptorRev1 AcpiFacsDescriptorRev1;
/* Master MADT */
-struct AcpiMultipleApicTable
-{
+struct AcpiMultipleApicTable {
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
uint32_t local_apic_address; /* Physical address of local APIC */
uint32_t flags;
@@ -299,8 +306,7 @@ typedef struct AcpiMultipleApicTable AcpiMultipleApicTable;
/* Sub-structures for MADT */
-struct AcpiMadtProcessorApic
-{
+struct AcpiMadtProcessorApic {
ACPI_SUB_HEADER_DEF
uint8_t processor_id; /* ACPI processor id */
uint8_t local_apic_id; /* Processor's local APIC id */
@@ -308,8 +314,7 @@ struct AcpiMadtProcessorApic
} QEMU_PACKED;
typedef struct AcpiMadtProcessorApic AcpiMadtProcessorApic;
-struct AcpiMadtIoApic
-{
+struct AcpiMadtIoApic {
ACPI_SUB_HEADER_DEF
uint8_t io_apic_id; /* I/O APIC ID */
uint8_t reserved; /* Reserved - must be zero */
@@ -462,8 +467,7 @@ typedef struct Acpi20Hpet Acpi20Hpet;
* SRAT (NUMA topology description) table
*/
-struct AcpiSystemResourceAffinityTable
-{
+struct AcpiSystemResourceAffinityTable {
ACPI_TABLE_HEADER_DEF
uint32_t reserved1;
uint32_t reserved2[2];
@@ -475,8 +479,7 @@ typedef struct AcpiSystemResourceAffinityTable AcpiSystemResourceAffinityTable;
#define ACPI_SRAT_PROCESSOR_x2APIC 2
#define ACPI_SRAT_PROCESSOR_GICC 3
-struct AcpiSratProcessorAffinity
-{
+struct AcpiSratProcessorAffinity {
ACPI_SUB_HEADER_DEF
uint8_t proximity_lo;
uint8_t local_apic_id;
@@ -498,8 +501,7 @@ struct AcpiSratProcessorX2ApicAffinity {
} QEMU_PACKED;
typedef struct AcpiSratProcessorX2ApicAffinity AcpiSratProcessorX2ApicAffinity;
-struct AcpiSratMemoryAffinity
-{
+struct AcpiSratMemoryAffinity {
ACPI_SUB_HEADER_DEF
uint32_t proximity;
uint16_t reserved1;
@@ -511,8 +513,7 @@ struct AcpiSratMemoryAffinity
} QEMU_PACKED;
typedef struct AcpiSratMemoryAffinity AcpiSratMemoryAffinity;
-struct AcpiSratProcessorGiccAffinity
-{
+struct AcpiSratProcessorGiccAffinity {
ACPI_SUB_HEADER_DEF
uint32_t proximity;
uint32_t acpi_processor_uid;
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 329a0d0c90..88d0738d76 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -381,6 +381,9 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre);
void
build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
const char *oem_id, const char *oem_table_id);
+void
+build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
+ const char *oem_id, const char *oem_table_id);
int
build_append_named_dword(GArray *array, const char *name_format, ...)
diff --git a/include/hw/compat.h b/include/hw/compat.h
index 846b90eb67..55b176507a 100644
--- a/include/hw/compat.h
+++ b/include/hw/compat.h
@@ -2,7 +2,11 @@
#define HW_COMPAT_H
#define HW_COMPAT_2_9 \
- /* empty */
+ {\
+ .driver = "pci-bridge",\
+ .property = "shpc",\
+ .value = "off",\
+ },
#define HW_COMPAT_2_8 \
{\
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 416aaa56ea..e447f5d8f4 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -151,6 +151,9 @@ struct PCMachineClass {
bool save_tsc_khz;
/* generate legacy CPU hotplug AML */
bool legacy_cpu_hotplug;
+
+ /* use DMA capable linuxboot option rom */
+ bool linuxboot_dma_enabled;
};
#define TYPE_PC_MACHINE "generic-pc-machine"
@@ -379,6 +382,9 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
int e820_get_num_entries(void);
bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
+#define PC_COMPAT_2_9 \
+ HW_COMPAT_2_9 \
+
#define PC_COMPAT_2_8 \
HW_COMPAT_2_8 \
{\
@@ -438,10 +444,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
#define PC_COMPAT_2_6 \
HW_COMPAT_2_6 \
{\
- .driver = "fw_cfg_io",\
- .property = "dma_enabled",\
- .value = "off",\
- },{\
.driver = TYPE_X86_CPU,\
.property = "cpuid-0xb",\
.value = "off",\
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 4bf86b0ad8..e69489ec6c 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -103,16 +103,17 @@ typedef struct DeviceClass {
Property *props;
/*
- * Shall we hide this device model from -device / device_add?
+ * Can this device be instantiated with -device / device_add?
* All devices should support instantiation with device_add, and
* this flag should not exist. But we're not there, yet. Some
* devices fail to instantiate with cryptic error messages.
* Others instantiate, but don't work. Exposing users to such
- * behavior would be cruel; this flag serves to protect them. It
- * should never be set without a comment explaining why it is set.
+ * behavior would be cruel; clearing this flag will protect them.
+ * It should never be cleared without a comment explaining why it
+ * is cleared.
* TODO remove once we're there
*/
- bool cannot_instantiate_with_device_add_yet;
+ bool user_creatable;
bool hotpluggable;
/* callbacks */
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 1d69fa7a8f..d206fc93dd 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -134,12 +134,12 @@ extern PropertyInfo qdev_prop_arraylen;
* device_add, so add code like this:
* |* Reason: pointer property "NAME-OF-YOUR-PROP" *|
* DeviceClass *dc = DEVICE_CLASS(class);
- * dc->cannot_instantiate_with_device_add_yet = true;
+ * dc->user_creatable = false;
*
* - If the property may safely remain null, document it like this:
* |*
* * Note: pointer property "interrupt_vector" may remain null, thus
- * * no need for dc->cannot_instantiate_with_device_add_yet = true;
+ * * no need for dc->user_creatable = false;
* *|
*/
#define DEFINE_PROP_PTR(_n, _s, _f) \
diff --git a/include/migration/blocker.h b/include/migration/blocker.h
new file mode 100644
index 0000000000..acd27018e9
--- /dev/null
+++ b/include/migration/blocker.h
@@ -0,0 +1,35 @@
+/*
+ * QEMU migration blockers
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef MIGRATION_BLOCKER_H
+#define MIGRATION_BLOCKER_H
+
+/**
+ * @migrate_add_blocker - prevent migration from proceeding
+ *
+ * @reason - an error to be returned whenever migration is attempted
+ *
+ * @errp - [out] The reason (if any) we cannot block migration right now.
+ *
+ * @returns - 0 on success, -EBUSY/-EACCES on failure, with errp set.
+ */
+int migrate_add_blocker(Error *reason, Error **errp);
+
+/**
+ * @migrate_del_blocker - remove a blocking error from migration
+ *
+ * @reason - the error blocking migration
+ */
+void migrate_del_blocker(Error *reason);
+
+#endif
diff --git a/include/migration/migration.h b/include/migration/migration.h
index e29cb0144b..49ec5015e5 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -22,7 +22,6 @@
#include "qapi-types.h"
#include "exec/cpu-common.h"
#include "qemu/coroutine_int.h"
-#include "qom/object.h"
#define QEMU_VM_FILE_MAGIC 0x5145564d
#define QEMU_VM_FILE_VERSION_COMPAT 0x00000002
@@ -39,9 +38,6 @@
#define QEMU_VM_COMMAND 0x08
#define QEMU_VM_SECTION_FOOTER 0x7e
-/* for vl.c */
-extern int only_migratable;
-
struct MigrationParams {
bool blk;
bool shared;
@@ -61,28 +57,6 @@ enum mig_rp_message_type {
typedef QLIST_HEAD(, LoadStateEntry) LoadStateEntry_Head;
-/* The current postcopy state is read/set by postcopy_state_get/set
- * which update it atomically.
- * The state is updated as postcopy messages are received, and
- * in general only one thread should be writing to the state at any one
- * time, initially the main thread and then the listen thread;
- * Corner cases are where either thread finishes early and/or errors.
- * The state is checked as messages are received to ensure that
- * the source is sending us messages in the correct order.
- * The state is also used by the RAM reception code to know if it
- * has to place pages atomically, and the cleanup code at the end of
- * the main thread to know if it has to delay cleanup until the end
- * of postcopy.
- */
-typedef enum {
- POSTCOPY_INCOMING_NONE = 0, /* Initial state - no postcopy */
- POSTCOPY_INCOMING_ADVISE,
- POSTCOPY_INCOMING_DISCARD,
- POSTCOPY_INCOMING_LISTENING,
- POSTCOPY_INCOMING_RUNNING,
- POSTCOPY_INCOMING_END
-} PostcopyState;
-
/* State for the incoming migration */
struct MigrationIncomingState {
QEMUFile *from_src_file;
@@ -275,26 +249,6 @@ int ram_discard_range(const char *block_name, uint64_t start, size_t length);
int ram_postcopy_incoming_init(MigrationIncomingState *mis);
void ram_postcopy_migrated_memory_release(MigrationState *ms);
-/**
- * @migrate_add_blocker - prevent migration from proceeding
- *
- * @reason - an error to be returned whenever migration is attempted
- *
- * @errp - [out] The reason (if any) we cannot block migration right now.
- *
- * @returns - 0 on success, -EBUSY/-EACCES on failure, with errp set.
- */
-int migrate_add_blocker(Error *reason, Error **errp);
-
-/**
- * @migrate_del_blocker - remove a blocking error from migration
- *
- * @reason - the error blocking migration
- */
-void migrate_del_blocker(Error *reason);
-
-int check_migratable(Object *obj, Error **err);
-
bool migrate_release_ram(void);
bool migrate_postcopy_ram(void);
bool migrate_zero_blocks(void);
@@ -357,8 +311,4 @@ void global_state_store_running(void);
void migration_page_queue_free(void);
int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len);
uint64_t ram_pagesize_summary(void);
-
-PostcopyState postcopy_state_get(void);
-/* Set the state and return the old state */
-PostcopyState postcopy_state_set(PostcopyState new_state);
#endif
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index f4bf3f1b4e..848965963a 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -1067,4 +1067,6 @@ int64_t self_announce_delay(int round)
void dump_vmstate_json_to_file(FILE *out_fp);
+bool vmstate_check_only_migratable(const VMStateDescription *vmsd);
+
#endif
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index be9e22c955..83c1ceb33e 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -15,7 +15,7 @@
/* vl.c */
extern const char *bios_name;
-
+extern int only_migratable;
extern const char *qemu_name;
extern QemuUUID qemu_uuid;
extern bool qemu_uuid_set;
@@ -75,8 +75,8 @@ void qemu_remove_exit_notifier(Notifier *notify);
void qemu_add_machine_init_done_notifier(Notifier *notify);
void qemu_remove_machine_init_done_notifier(Notifier *notify);
-int save_vmstate(const char *name);
-int load_vmstate(const char *name);
+int save_vmstate(const char *name, Error **errp);
+int load_vmstate(const char *name, Error **errp);
void qemu_announce_self(void);
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index b8c93b9bce..01daaad00c 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -17,7 +17,7 @@ typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr start_addr,
void xen_map_cache_init(phys_offset_to_gaddr_t f,
void *opaque);
uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
- uint8_t lock);
+ uint8_t lock, bool dma);
ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
void xen_invalidate_map_cache_entry(uint8_t *buffer);
void xen_invalidate_map_cache(void);
@@ -31,7 +31,8 @@ static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
static inline uint8_t *xen_map_cache(hwaddr phys_addr,
hwaddr size,
- uint8_t lock)
+ uint8_t lock,
+ bool dma)
{
abort();
}
diff --git a/migration/Makefile.objs b/migration/Makefile.objs
index 480dd493a9..c1920b6fc0 100644
--- a/migration/Makefile.objs
+++ b/migration/Makefile.objs
@@ -1,7 +1,7 @@
common-obj-y += migration.o socket.o fd.o exec.o
common-obj-y += tls.o
common-obj-y += colo-comm.o colo.o colo-failover.o
-common-obj-y += vmstate.o
+common-obj-y += vmstate.o page_cache.o
common-obj-y += qemu-file.o
common-obj-y += qemu-file-channel.o
common-obj-y += xbzrle.o postcopy-ram.o
diff --git a/migration/migration.c b/migration/migration.c
index a5ade23e24..0304c013f3 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -17,6 +17,7 @@
#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
+#include "migration/blocker.h"
#include "migration/migration.h"
#include "migration/qemu-file.h"
#include "sysemu/sysemu.h"
@@ -77,13 +78,6 @@ static NotifierList migration_state_notifiers =
static bool deferred_incoming;
-/*
- * Current state of incoming postcopy; note this is not part of
- * MigrationIncomingState since it's state is used during cleanup
- * at the end as MIS is being freed.
- */
-static PostcopyState incoming_postcopy_state;
-
/* When we add fault tolerance, we could have several
migrations at once. For now we don't need to add
dynamic creation of migration */
@@ -1149,21 +1143,6 @@ void migrate_del_blocker(Error *reason)
migration_blockers = g_slist_remove(migration_blockers, reason);
}
-int check_migratable(Object *obj, Error **err)
-{
- DeviceClass *dc = DEVICE_GET_CLASS(obj);
- if (only_migratable && dc->vmsd) {
- if (dc->vmsd->unmigratable) {
- error_setg(err, "Device %s is not migratable, but "
- "--only-migratable was specified",
- object_get_typename(obj));
- return -1;
- }
- }
-
- return 0;
-}
-
void qmp_migrate_incoming(const char *uri, Error **errp)
{
Error *local_err = NULL;
@@ -2097,14 +2076,3 @@ void migrate_fd_connect(MigrationState *s)
s->migration_thread_running = true;
}
-PostcopyState postcopy_state_get(void)
-{
- return atomic_mb_read(&incoming_postcopy_state);
-}
-
-/* Set the state and return the old state */
-PostcopyState postcopy_state_set(PostcopyState new_state)
-{
- return atomic_xchg(&incoming_postcopy_state, new_state);
-}
-
diff --git a/page_cache.c b/migration/page_cache.c
index 5f8578736e..5f8578736e 100644
--- a/page_cache.c
+++ b/migration/page_cache.c
diff --git a/include/migration/page_cache.h b/migration/page_cache.h
index 10ed53274c..10ed53274c 100644
--- a/include/migration/page_cache.h
+++ b/migration/page_cache.h
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index cdadaf6578..a0489f6542 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -784,3 +784,21 @@ void postcopy_discard_send_finish(MigrationState *ms, PostcopyDiscardState *pds)
g_free(pds);
}
+
+/*
+ * Current state of incoming postcopy; note this is not part of
+ * MigrationIncomingState since it's state is used during cleanup
+ * at the end as MIS is being freed.
+ */
+static PostcopyState incoming_postcopy_state;
+
+PostcopyState postcopy_state_get(void)
+{
+ return atomic_mb_read(&incoming_postcopy_state);
+}
+
+/* Set the state and return the old state */
+PostcopyState postcopy_state_set(PostcopyState new_state)
+{
+ return atomic_xchg(&incoming_postcopy_state, new_state);
+}
diff --git a/migration/postcopy-ram.h b/migration/postcopy-ram.h
index 4c25f03be2..52d51e8007 100644
--- a/migration/postcopy-ram.h
+++ b/migration/postcopy-ram.h
@@ -81,6 +81,28 @@ int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from,
int postcopy_place_page_zero(MigrationIncomingState *mis, void *host,
size_t pagesize);
+/* The current postcopy state is read/set by postcopy_state_get/set
+ * which update it atomically.
+ * The state is updated as postcopy messages are received, and
+ * in general only one thread should be writing to the state at any one
+ * time, initially the main thread and then the listen thread;
+ * Corner cases are where either thread finishes early and/or errors.
+ * The state is checked as messages are received to ensure that
+ * the source is sending us messages in the correct order.
+ * The state is also used by the RAM reception code to know if it
+ * has to place pages atomically, and the cleanup code at the end of
+ * the main thread to know if it has to delay cleanup until the end
+ * of postcopy.
+ */
+typedef enum {
+ POSTCOPY_INCOMING_NONE = 0, /* Initial state - no postcopy */
+ POSTCOPY_INCOMING_ADVISE,
+ POSTCOPY_INCOMING_DISCARD,
+ POSTCOPY_INCOMING_LISTENING,
+ POSTCOPY_INCOMING_RUNNING,
+ POSTCOPY_INCOMING_END
+} PostcopyState;
+
/*
* Allocate a page of memory that can be mapped at a later point in time
* using postcopy_place_page
@@ -88,4 +110,8 @@ int postcopy_place_page_zero(MigrationIncomingState *mis, void *host,
*/
void *postcopy_get_tmp_page(MigrationIncomingState *mis);
+PostcopyState postcopy_state_get(void);
+/* Set the state and return the old state */
+PostcopyState postcopy_state_set(PostcopyState new_state);
+
#endif
diff --git a/migration/ram.c b/migration/ram.c
index d88afeaddd..f59fdd41a4 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -48,8 +48,14 @@
/***********************************************************/
/* ram save/restore */
+/* RAM_SAVE_FLAG_ZERO used to be named RAM_SAVE_FLAG_COMPRESS, it
+ * worked for pages that where filled with the same char. We switched
+ * it to only search for the zero value. And to avoid confusion with
+ * RAM_SSAVE_FLAG_COMPRESS_PAGE just rename it.
+ */
+
#define RAM_SAVE_FLAG_FULL 0x01 /* Obsolete, not used anymore */
-#define RAM_SAVE_FLAG_COMPRESS 0x02
+#define RAM_SAVE_FLAG_ZERO 0x02
#define RAM_SAVE_FLAG_MEM_SIZE 0x04
#define RAM_SAVE_FLAG_PAGE 0x08
#define RAM_SAVE_FLAG_EOS 0x10
@@ -436,20 +442,21 @@ void migrate_compress_threads_create(void)
* @offset: offset inside the block for the page
* in the lower bits, it contains flags
*/
-static size_t save_page_header(RAMState *rs, RAMBlock *block, ram_addr_t offset)
+static size_t save_page_header(RAMState *rs, QEMUFile *f, RAMBlock *block,
+ ram_addr_t offset)
{
size_t size, len;
if (block == rs->last_sent_block) {
offset |= RAM_SAVE_FLAG_CONTINUE;
}
- qemu_put_be64(rs->f, offset);
+ qemu_put_be64(f, offset);
size = 8;
if (!(offset & RAM_SAVE_FLAG_CONTINUE)) {
len = strlen(block->idstr);
- qemu_put_byte(rs->f, len);
- qemu_put_buffer(rs->f, (uint8_t *)block->idstr, len);
+ qemu_put_byte(f, len);
+ qemu_put_buffer(f, (uint8_t *)block->idstr, len);
size += 1 + len;
rs->last_sent_block = block;
}
@@ -571,7 +578,7 @@ static int save_xbzrle_page(RAMState *rs, uint8_t **current_data,
}
/* Send XBZRLE based compressed page */
- bytes_xbzrle = save_page_header(rs, block,
+ bytes_xbzrle = save_page_header(rs, rs->f, block,
offset | RAM_SAVE_FLAG_XBZRLE);
qemu_put_byte(rs->f, ENCODING_FLAG_XBZRLE);
qemu_put_be16(rs->f, encoded_len);
@@ -745,7 +752,7 @@ static int save_zero_page(RAMState *rs, RAMBlock *block, ram_addr_t offset,
if (is_zero_range(p, TARGET_PAGE_SIZE)) {
rs->zero_pages++;
rs->bytes_transferred +=
- save_page_header(rs, block, offset | RAM_SAVE_FLAG_COMPRESS);
+ save_page_header(rs, rs->f, block, offset | RAM_SAVE_FLAG_ZERO);
qemu_put_byte(rs->f, 0);
rs->bytes_transferred += 1;
pages = 1;
@@ -834,7 +841,7 @@ static int ram_save_page(RAMState *rs, PageSearchStatus *pss, bool last_stage)
/* XBZRLE overflow or normal page */
if (pages == -1) {
- rs->bytes_transferred += save_page_header(rs, block,
+ rs->bytes_transferred += save_page_header(rs, rs->f, block,
offset | RAM_SAVE_FLAG_PAGE);
if (send_async) {
qemu_put_buffer_async(rs->f, p, TARGET_PAGE_SIZE,
@@ -860,7 +867,7 @@ static int do_compress_ram_page(QEMUFile *f, RAMBlock *block,
int bytes_sent, blen;
uint8_t *p = block->host + (offset & TARGET_PAGE_MASK);
- bytes_sent = save_page_header(rs, block, offset |
+ bytes_sent = save_page_header(rs, f, block, offset |
RAM_SAVE_FLAG_COMPRESS_PAGE);
blen = qemu_put_compression_data(f, p, TARGET_PAGE_SIZE,
migrate_compress_level());
@@ -991,7 +998,7 @@ static int ram_save_compressed_page(RAMState *rs, PageSearchStatus *pss,
pages = save_zero_page(rs, block, offset, p);
if (pages == -1) {
/* Make sure the first page is sent out before other pages */
- bytes_xmit = save_page_header(rs, block, offset |
+ bytes_xmit = save_page_header(rs, rs->f, block, offset |
RAM_SAVE_FLAG_COMPRESS_PAGE);
blen = qemu_put_compression_data(rs->f, p, TARGET_PAGE_SIZE,
migrate_compress_level());
@@ -2406,7 +2413,7 @@ static int ram_load_postcopy(QEMUFile *f)
trace_ram_load_postcopy_loop((uint64_t)addr, flags);
place_needed = false;
- if (flags & (RAM_SAVE_FLAG_COMPRESS | RAM_SAVE_FLAG_PAGE)) {
+ if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE)) {
block = ram_block_from_stream(f, flags);
host = host_from_ram_block_offset(block, addr);
@@ -2453,7 +2460,7 @@ static int ram_load_postcopy(QEMUFile *f)
last_host = host;
switch (flags & ~RAM_SAVE_FLAG_CONTINUE) {
- case RAM_SAVE_FLAG_COMPRESS:
+ case RAM_SAVE_FLAG_ZERO:
ch = qemu_get_byte(f);
memset(page_buffer, ch, TARGET_PAGE_SIZE);
if (ch) {
@@ -2542,7 +2549,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
flags = addr & ~TARGET_PAGE_MASK;
addr &= TARGET_PAGE_MASK;
- if (flags & (RAM_SAVE_FLAG_COMPRESS | RAM_SAVE_FLAG_PAGE |
+ if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) {
RAMBlock *block = ram_block_from_stream(f, flags);
@@ -2604,7 +2611,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
}
break;
- case RAM_SAVE_FLAG_COMPRESS:
+ case RAM_SAVE_FLAG_ZERO:
ch = qemu_get_byte(f);
ram_handle_compressed(host, ch, TARGET_PAGE_SIZE);
break;
diff --git a/migration/savevm.c b/migration/savevm.c
index 7f66d58a7e..f5e81948e6 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2069,7 +2069,7 @@ int qemu_loadvm_state(QEMUFile *f)
return ret;
}
-int save_vmstate(const char *name)
+int save_vmstate(const char *name, Error **errp)
{
BlockDriverState *bs, *bs1;
QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
@@ -2079,29 +2079,27 @@ int save_vmstate(const char *name)
uint64_t vm_state_size;
qemu_timeval tv;
struct tm tm;
- Error *local_err = NULL;
AioContext *aio_context;
if (!bdrv_all_can_snapshot(&bs)) {
- error_report("Device '%s' is writable but does not support snapshots",
- bdrv_get_device_name(bs));
+ error_setg(errp, "Device '%s' is writable but does not support "
+ "snapshots", bdrv_get_device_name(bs));
return ret;
}
/* Delete old snapshots of the same name */
if (name) {
- ret = bdrv_all_delete_snapshot(name, &bs1, &local_err);
+ ret = bdrv_all_delete_snapshot(name, &bs1, errp);
if (ret < 0) {
- error_reportf_err(local_err,
- "Error while deleting snapshot on device '%s': ",
- bdrv_get_device_name(bs1));
+ error_prepend(errp, "Error while deleting snapshot on device "
+ "'%s': ", bdrv_get_device_name(bs1));
return ret;
}
}
bs = bdrv_all_find_vmstate_bs();
if (bs == NULL) {
- error_report("No block device can accept snapshots");
+ error_setg(errp, "No block device can accept snapshots");
return ret;
}
aio_context = bdrv_get_aio_context(bs);
@@ -2110,7 +2108,7 @@ int save_vmstate(const char *name)
ret = global_state_store();
if (ret) {
- error_report("Error saving global state");
+ error_setg(errp, "Error saving global state");
return ret;
}
vm_stop(RUN_STATE_SAVE_VM);
@@ -2142,21 +2140,20 @@ int save_vmstate(const char *name)
/* save the VM state */
f = qemu_fopen_bdrv(bs, 1);
if (!f) {
- error_report("Could not open VM state file");
+ error_setg(errp, "Could not open VM state file");
goto the_end;
}
- ret = qemu_savevm_state(f, &local_err);
+ ret = qemu_savevm_state(f, errp);
vm_state_size = qemu_ftell(f);
qemu_fclose(f);
if (ret < 0) {
- error_report_err(local_err);
goto the_end;
}
ret = bdrv_all_create_snapshot(sn, bs, vm_state_size, &bs);
if (ret < 0) {
- error_report("Error while creating snapshot on '%s'",
- bdrv_get_device_name(bs));
+ error_setg(errp, "Error while creating snapshot on '%s'",
+ bdrv_get_device_name(bs));
goto the_end;
}
@@ -2229,7 +2226,7 @@ void qmp_xen_load_devices_state(const char *filename, Error **errp)
migration_incoming_state_destroy();
}
-int load_vmstate(const char *name)
+int load_vmstate(const char *name, Error **errp)
{
BlockDriverState *bs, *bs_vm_state;
QEMUSnapshotInfo sn;
@@ -2239,20 +2236,22 @@ int load_vmstate(const char *name)
MigrationIncomingState *mis = migration_incoming_get_current();
if (!bdrv_all_can_snapshot(&bs)) {
- error_report("Device '%s' is writable but does not support snapshots",
- bdrv_get_device_name(bs));
+ error_setg(errp,
+ "Device '%s' is writable but does not support snapshots",
+ bdrv_get_device_name(bs));
return -ENOTSUP;
}
ret = bdrv_all_find_snapshot(name, &bs);
if (ret < 0) {
- error_report("Device '%s' does not have the requested snapshot '%s'",
- bdrv_get_device_name(bs), name);
+ error_setg(errp,
+ "Device '%s' does not have the requested snapshot '%s'",
+ bdrv_get_device_name(bs), name);
return ret;
}
bs_vm_state = bdrv_all_find_vmstate_bs();
if (!bs_vm_state) {
- error_report("No block device supports snapshots");
+ error_setg(errp, "No block device supports snapshots");
return -ENOTSUP;
}
aio_context = bdrv_get_aio_context(bs_vm_state);
@@ -2264,8 +2263,8 @@ int load_vmstate(const char *name)
if (ret < 0) {
return ret;
} else if (sn.vm_state_size == 0) {
- error_report("This is a disk-only snapshot. Revert to it offline "
- "using qemu-img.");
+ error_setg(errp, "This is a disk-only snapshot. Revert to it "
+ " offline using qemu-img");
return -EINVAL;
}
@@ -2274,7 +2273,7 @@ int load_vmstate(const char *name)
ret = bdrv_all_goto_snapshot(name, &bs);
if (ret < 0) {
- error_report("Error %d while activating snapshot '%s' on '%s'",
+ error_setg(errp, "Error %d while activating snapshot '%s' on '%s'",
ret, name, bdrv_get_device_name(bs));
return ret;
}
@@ -2282,7 +2281,7 @@ int load_vmstate(const char *name)
/* restore the VM state */
f = qemu_fopen_bdrv(bs_vm_state, 0);
if (!f) {
- error_report("Could not open VM state file");
+ error_setg(errp, "Could not open VM state file");
return -EINVAL;
}
@@ -2296,7 +2295,7 @@ int load_vmstate(const char *name)
migration_incoming_state_destroy();
if (ret < 0) {
- error_report("Error %d while loading VM state", ret);
+ error_setg(errp, "Error %d while loading VM state", ret);
return ret;
}
@@ -2318,3 +2317,13 @@ void vmstate_register_ram_global(MemoryRegion *mr)
{
vmstate_register_ram(mr, NULL);
}
+
+bool vmstate_check_only_migratable(const VMStateDescription *vmsd)
+{
+ /* check needed if --only-migratable is specified */
+ if (!only_migratable) {
+ return true;
+ }
+
+ return !(vmsd && vmsd->unmigratable);
+}
diff --git a/monitor.c b/monitor.c
index 078cba5c86..afbacfe1cb 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3254,7 +3254,7 @@ void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
TYPE_DEVICE);
name = object_class_get_name(OBJECT_CLASS(dc));
- if (!dc->cannot_instantiate_with_device_add_yet
+ if (dc->user_creatable
&& !strncmp(name, str, len)) {
readline_add_completion(rs, name);
}
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 6b974b952f..ea0b3e8b13 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2813,11 +2813,15 @@
# "name1=content1; name2=content2;" as explained by
# CURLOPT_COOKIE(3). Defaults to no cookies.
#
+# @cookie-secret: ID of a QCryptoSecret object providing the cookie data in a
+# secure way. See @cookie for the format. (since 2.10)
+#
# Since: 2.9
##
{ 'struct': 'BlockdevOptionsCurlHttp',
'base': 'BlockdevOptionsCurlBase',
- 'data': { '*cookie': 'str' } }
+ 'data': { '*cookie': 'str',
+ '*cookie-secret': 'str'} }
##
# @BlockdevOptionsCurlHttps:
@@ -2832,12 +2836,16 @@
# @sslverify: Whether to verify the SSL certificate's validity (defaults to
# true)
#
+# @cookie-secret: ID of a QCryptoSecret object providing the cookie data in a
+# secure way. See @cookie for the format. (since 2.10)
+#
# Since: 2.9
##
{ 'struct': 'BlockdevOptionsCurlHttps',
'base': 'BlockdevOptionsCurlBase',
'data': { '*cookie': 'str',
- '*sslverify': 'bool' } }
+ '*sslverify': 'bool',
+ '*cookie-secret': 'str'} }
##
# @BlockdevOptionsCurlFtp:
diff --git a/qdev-monitor.c b/qdev-monitor.c
index e61d596ef7..3ecbf0bd25 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -114,7 +114,7 @@ static void qdev_print_devinfo(DeviceClass *dc)
if (dc->desc) {
error_printf(", desc \"%s\"", dc->desc);
}
- if (dc->cannot_instantiate_with_device_add_yet) {
+ if (!dc->user_creatable) {
error_printf(", no-user");
}
error_printf("\n");
@@ -156,7 +156,7 @@ static void qdev_print_devinfos(bool show_no_user)
? !test_bit(i, dc->categories)
: !bitmap_empty(dc->categories, DEVICE_CATEGORY_MAX))
|| (!show_no_user
- && dc->cannot_instantiate_with_device_add_yet)) {
+ && !dc->user_creatable)) {
continue;
}
if (!cat_printed) {
@@ -241,7 +241,7 @@ static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
}
dc = DEVICE_CLASS(oc);
- if (dc->cannot_instantiate_with_device_add_yet ||
+ if (!dc->user_creatable ||
(qdev_hotplug && !dc->hotpluggable)) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
"pluggable device type");
diff --git a/qom/cpu.c b/qom/cpu.c
index f9111a02ba..50698767dd 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -453,7 +453,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
* Reason: CPUs still need special care by board code: wiring up
* IRQs, adding reset handlers, halting non-first CPUs, ...
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo cpu_type_info = {
diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c
index 8cced4604f..c75cd38ece 100644
--- a/replay/replay-snapshot.c
+++ b/replay/replay-snapshot.c
@@ -62,14 +62,18 @@ void replay_vmstate_register(void)
void replay_vmstate_init(void)
{
+ Error *err = NULL;
+
if (replay_snapshot) {
if (replay_mode == REPLAY_MODE_RECORD) {
- if (save_vmstate(replay_snapshot) != 0) {
+ if (save_vmstate(replay_snapshot, &err) != 0) {
+ error_report_err(err);
error_report("Could not create snapshot for icount record");
exit(1);
}
} else if (replay_mode == REPLAY_MODE_PLAY) {
- if (load_vmstate(replay_snapshot) != 0) {
+ if (load_vmstate(replay_snapshot, &err) != 0) {
+ error_report_err(err);
error_report("Could not load snapshot for icount replay");
exit(1);
}
diff --git a/stubs/migr-blocker.c b/stubs/migr-blocker.c
index a5ba18f53d..2b64ac9560 100644
--- a/stubs/migr-blocker.c
+++ b/stubs/migr-blocker.c
@@ -1,6 +1,6 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
int migrate_add_blocker(Error *reason, Error **errp)
{
diff --git a/stubs/vmstate.c b/stubs/vmstate.c
index 6d52f29bb2..6399474e49 100644
--- a/stubs/vmstate.c
+++ b/stubs/vmstate.c
@@ -1,7 +1,6 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "migration/vmstate.h"
-#include "migration/migration.h"
const VMStateDescription vmstate_dummy = {};
@@ -21,7 +20,7 @@ void vmstate_unregister(DeviceState *dev,
{
}
-int check_migratable(Object *obj, Error **err)
+bool vmstate_check_only_migratable(const VMStateDescription *vmsd)
{
- return 0;
+ return true;
}
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5e768404a1..a41d595c23 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4075,7 +4075,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->cpu_exec_enter = x86_cpu_exec_enter;
cc->cpu_exec_exit = x86_cpu_exec_exit;
- dc->cannot_instantiate_with_device_add_yet = false;
+ dc->user_creatable = true;
}
static const TypeInfo x86_cpu_type_info = {
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 55865dbee0..011d4a55b1 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -43,7 +43,7 @@
#include "standard-headers/asm-x86/hyperv.h"
#include "hw/pci/pci.h"
#include "hw/pci/msi.h"
-#include "migration/migration.h"
+#include "migration/blocker.h"
#include "exec/memattrs.h"
#include "trace.h"
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 16ff8f399f..4277597e93 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -554,7 +554,7 @@ tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y)
tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
-tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/xbzrle.o page_cache.o $(test-util-obj-y)
+tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/xbzrle.o migration/page_cache.o $(test-util-obj-y)
tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o
tests/test-int128$(EXESUF): tests/test-int128.o
tests/rcutorture$(EXESUF): tests/rcutorture.o $(test-util-obj-y)
diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
index 4e5c65a022..63da978f0b 100644
--- a/tests/bios-tables-test.c
+++ b/tests/bios-tables-test.c
@@ -175,8 +175,8 @@ static void test_acpi_fadt_table(test_data *data)
ACPI_READ_FIELD(fadt_table->reset_value, addr);
ACPI_READ_FIELD(fadt_table->arm_boot_flags, addr);
ACPI_READ_FIELD(fadt_table->minor_revision, addr);
- ACPI_READ_FIELD(fadt_table->Xfacs, addr);
- ACPI_READ_FIELD(fadt_table->Xdsdt, addr);
+ ACPI_READ_FIELD(fadt_table->x_facs, addr);
+ ACPI_READ_FIELD(fadt_table->x_dsdt, addr);
ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm1a_event_block, addr);
ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm1b_event_block, addr);
ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm1a_control_block, addr);
diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c
index 79a2e69a28..6c71e46391 100644
--- a/tests/test-x86-cpuid-compat.c
+++ b/tests/test-x86-cpuid-compat.c
@@ -1,6 +1,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qint.h"
#include "qapi/qmp/qbool.h"
@@ -78,6 +79,90 @@ static void add_cpuid_test(const char *name, const char *cmdline,
qtest_add_data_func(name, args, test_cpuid_prop);
}
+
+/* Parameters to a add_feature_test() test case */
+typedef struct FeatureTestArgs {
+ /* cmdline to start QEMU */
+ const char *cmdline;
+ /*
+ * cpuid-input-eax and cpuid-input-ecx values to look for,
+ * in "feature-words" and "filtered-features" properties.
+ */
+ uint32_t in_eax, in_ecx;
+ /* The register name to look for, in the X86CPUFeatureWordInfo array */
+ const char *reg;
+ /* The bit to check in X86CPUFeatureWordInfo.features */
+ int bitnr;
+ /* The expected value for the bit in (X86CPUFeatureWordInfo.features) */
+ bool expected_value;
+} FeatureTestArgs;
+
+/* Get the value for a feature word in a X86CPUFeatureWordInfo list */
+static uint32_t get_feature_word(QList *features, uint32_t eax, uint32_t ecx,
+ const char *reg)
+{
+ const QListEntry *e;
+
+ for (e = qlist_first(features); e; e = qlist_next(e)) {
+ QDict *w = qobject_to_qdict(qlist_entry_obj(e));
+ const char *rreg = qdict_get_str(w, "cpuid-register");
+ uint32_t reax = qdict_get_int(w, "cpuid-input-eax");
+ bool has_ecx = qdict_haskey(w, "cpuid-input-ecx");
+ uint32_t recx = 0;
+
+ if (has_ecx) {
+ recx = qdict_get_int(w, "cpuid-input-ecx");
+ }
+ if (eax == reax && (!has_ecx || ecx == recx) && !strcmp(rreg, reg)) {
+ return qint_get_int(qobject_to_qint(qdict_get(w, "features")));
+ }
+ }
+ return 0;
+}
+
+static void test_feature_flag(const void *data)
+{
+ const FeatureTestArgs *args = data;
+ char *path;
+ QList *present, *filtered;
+ uint32_t value;
+
+ qtest_start(args->cmdline);
+ path = get_cpu0_qom_path();
+ present = qobject_to_qlist(qom_get(path, "feature-words"));
+ filtered = qobject_to_qlist(qom_get(path, "filtered-features"));
+ value = get_feature_word(present, args->in_eax, args->in_ecx, args->reg);
+ value |= get_feature_word(filtered, args->in_eax, args->in_ecx, args->reg);
+ qtest_end();
+
+ g_assert(!!(value & (1U << args->bitnr)) == args->expected_value);
+
+ QDECREF(present);
+ QDECREF(filtered);
+ g_free(path);
+}
+
+/*
+ * Add test case to ensure that a given feature flag is set in
+ * either "feature-words" or "filtered-features", when running QEMU
+ * using cmdline
+ */
+static FeatureTestArgs *add_feature_test(const char *name, const char *cmdline,
+ uint32_t eax, uint32_t ecx,
+ const char *reg, int bitnr,
+ bool expected_value)
+{
+ FeatureTestArgs *args = g_new0(FeatureTestArgs, 1);
+ args->cmdline = cmdline;
+ args->in_eax = eax;
+ args->in_ecx = ecx;
+ args->reg = reg;
+ args->bitnr = bitnr;
+ args->expected_value = expected_value;
+ qtest_add_data_func(name, args, test_feature_flag);
+ return args;
+}
+
#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS
static void test_plus_minus_subprocess(void)
{
@@ -229,5 +314,31 @@ int main(int argc, char **argv)
"-machine pc-i440fx-2.7 -cpu 486,+xstore",
"xlevel2", 0);
+ /* Test feature parsing */
+ add_feature_test("x86/cpuid/features/plus",
+ "-cpu 486,+arat",
+ 6, 0, "EAX", 2, true);
+ add_feature_test("x86/cpuid/features/minus",
+ "-cpu pentium,-mmx",
+ 1, 0, "EDX", 23, false);
+ add_feature_test("x86/cpuid/features/on",
+ "-cpu 486,arat=on",
+ 6, 0, "EAX", 2, true);
+ add_feature_test("x86/cpuid/features/off",
+ "-cpu pentium,mmx=off",
+ 1, 0, "EDX", 23, false);
+ add_feature_test("x86/cpuid/features/max-plus-invtsc",
+ "-cpu max,+invtsc",
+ 0x80000007, 0, "EDX", 8, true);
+ add_feature_test("x86/cpuid/features/max-invtsc-on",
+ "-cpu max,invtsc=on",
+ 0x80000007, 0, "EDX", 8, true);
+ add_feature_test("x86/cpuid/features/max-minus-mmx",
+ "-cpu max,-mmx",
+ 1, 0, "EDX", 23, false);
+ add_feature_test("x86/cpuid/features/max-invtsc-on,mmx=off",
+ "-cpu max,mmx=off",
+ 1, 0, "EDX", 23, false);
+
return g_test_run();
}
diff --git a/vl.c b/vl.c
index 5c9b40eb1c..1512df6e9e 100644
--- a/vl.c
+++ b/vl.c
@@ -4701,7 +4701,9 @@ int main(int argc, char **argv, char **envp)
if (replay_mode != REPLAY_MODE_NONE) {
replay_vmstate_init();
} else if (loadvm) {
- if (load_vmstate(loadvm) < 0) {
+ Error *local_err = NULL;
+ if (load_vmstate(loadvm, &local_err) < 0) {
+ error_report_err(local_err);
autostart = 0;
}
}