* lsi HBA reselection fix (George)

* Small cleanups (Li Qiang)
 * bugfixes for vhost-user-bridge and hostmem (Marc-André)
 * single-thread TCG fix (me)
 * VMX migration blocker (me)
 * target/i386 fix for LOCK (Richard)
 * MAINTAINERS update (Philippe, Thomas)
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQEcBAABAgAGBQJb/nM4AAoJEL/70l94x66DzyAH/A3/r56O6NVGID1ellB7WFI0
 oLznck2k8En23VWd6i1T/F9t+bAhnkUz60+RM0HhswXRQbkxFV4BqLt247AjiYBx
 SBoqvFkgH2N8dNY8jbtMHePQwir9ovZxH2G0O8KUXeEiVv5ecrnay+j5XESJvylF
 Gqs2UjubyWc8ihklmxCfzwIdD/H6ZRTulzHlMRZnHs31m6yrlzKDuZcNORLYOkbq
 FuEmeLYyE6bampIkaUSR3S8yaMK807cCvKZ3u0+eojbBxyf6OGK6wHWazRHnUtyx
 uZmAcGJ45mijiOskLxo5Y7/9iagADG/EpYB3Hg6jx9phTNsro6E6WuXMPDbE5Wc=
 =fXOF
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

* lsi HBA reselection fix (George)
* Small cleanups (Li Qiang)
* bugfixes for vhost-user-bridge and hostmem (Marc-André)
* single-thread TCG fix (me)
* VMX migration blocker (me)
* target/i386 fix for LOCK (Richard)
* MAINTAINERS update (Philippe, Thomas)

# gpg: Signature made Wed 28 Nov 2018 10:51:36 GMT
# gpg:                using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
  hostmem: no need to check for host_memory_backend_mr_inited() in alloc()
  hostmem-memfd: honour share=on/off property
  MAINTAINERS: Add an entry for the Firmware Configuration (fw_cfg) device
  MAINTAINERS: Add some missing entries related to accelerators
  target/i386: Generate #UD when applying LOCK to a register destination
  checkpatch: g_test_message does not need a trailing newline
  vl.c: remove outdated comment
  vhost-user-bridge: fix recvmsg iovlen
  vl: Improve error message when we can't load fw_cfg from file
  vmstate: constify VMStateField
  migration: savevm: consult migration blockers
  lsi: Reselection needed to remove pending commands from queue
  cpus: run work items for all vCPUs if single-threaded
  target/i386: kvm: add VMX migration blocker

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-11-28 11:32:33 +00:00
commit c56606684a
33 changed files with 285 additions and 194 deletions

View File

@ -117,6 +117,7 @@ S: Maintained
F: cpus.c F: cpus.c
F: exec.c F: exec.c
F: accel/tcg/ F: accel/tcg/
F: accel/stubs/tcg-stub.c
F: include/exec/cpu*.h F: include/exec/cpu*.h
F: include/exec/exec-all.h F: include/exec/exec-all.h
F: include/exec/helper*.h F: include/exec/helper*.h
@ -341,7 +342,10 @@ L: kvm@vger.kernel.org
S: Supported S: Supported
F: */kvm.* F: */kvm.*
F: accel/kvm/ F: accel/kvm/
F: accel/stubs/kvm-stub.c
F: include/hw/kvm/
F: include/sysemu/kvm*.h F: include/sysemu/kvm*.h
F: scripts/kvm/kvm_flightrecorder
ARM ARM
M: Peter Maydell <peter.maydell@linaro.org> M: Peter Maydell <peter.maydell@linaro.org>
@ -384,6 +388,7 @@ M: Marcelo Tosatti <mtosatti@redhat.com>
L: kvm@vger.kernel.org L: kvm@vger.kernel.org
S: Supported S: Supported
F: target/i386/kvm.c F: target/i386/kvm.c
F: scripts/kvm/vmxcap
Guest CPU Cores (Xen): Guest CPU Cores (Xen):
---------------------- ----------------------
@ -1559,6 +1564,19 @@ F: hw/display/edid*
F: include/hw/display/edid.h F: include/hw/display/edid.h
F: qemu-edid.c F: qemu-edid.c
Firmware configuration (fw_cfg)
M: Philippe Mathieu-Daudé <philmd@redhat.com>
R: Laszlo Ersek <lersek@redhat.com>
R: Gerd Hoffmann <kraxel@redhat.com>
S: Supported
F: docs/specs/fw_cfg.txt
F: hw/nvram/fw_cfg.c
F: include/hw/nvram/fw_cfg.h
F: include/standard-headers/linux/qemu_fw_cfg.h
F: tests/libqos/fw_cfg.c
F: tests/fw_cfg-test.c
T: git https://github.com/philmd/qemu.git fw_cfg-next
Subsystems Subsystems
---------- ----------
Audio Audio

View File

@ -42,6 +42,9 @@ static void
file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
{ {
HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend); HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
#ifdef CONFIG_POSIX
gchar *path;
#endif
if (!backend->size) { if (!backend->size) {
error_setg(errp, "can't create backend with size 0"); error_setg(errp, "can't create backend with size 0");
@ -54,8 +57,6 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
#ifndef CONFIG_POSIX #ifndef CONFIG_POSIX
error_setg(errp, "-mem-path not supported on this host"); error_setg(errp, "-mem-path not supported on this host");
#else #else
if (!host_memory_backend_mr_inited(backend)) {
gchar *path;
backend->force_prealloc = mem_prealloc; backend->force_prealloc = mem_prealloc;
path = object_get_canonical_path(OBJECT(backend)); path = object_get_canonical_path(OBJECT(backend));
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
@ -65,7 +66,6 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
(fb->is_pmem ? RAM_PMEM : 0), (fb->is_pmem ? RAM_PMEM : 0),
fb->mem_path, errp); fb->mem_path, errp);
g_free(path); g_free(path);
}
#endif #endif
} }

View File

@ -44,10 +44,6 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
return; return;
} }
if (host_memory_backend_mr_inited(backend)) {
return;
}
backend->force_prealloc = mem_prealloc; backend->force_prealloc = mem_prealloc;
fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size, fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
m->hugetlb, m->hugetlbsize, m->seal ? m->hugetlb, m->hugetlbsize, m->seal ?
@ -59,7 +55,8 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
name = object_get_canonical_path(OBJECT(backend)); name = object_get_canonical_path(OBJECT(backend));
memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend),
name, backend->size, true, fd, errp); name, backend->size,
backend->share, fd, errp);
g_free(name); g_free(name);
} }
@ -131,6 +128,7 @@ memfd_backend_instance_init(Object *obj)
/* default to sealed file */ /* default to sealed file */
m->seal = true; m->seal = true;
MEMORY_BACKEND(m)->share = true;
} }
static void static void

10
cpus.c
View File

@ -1220,17 +1220,21 @@ static void qemu_wait_io_event_common(CPUState *cpu)
process_queued_cpu_work(cpu); process_queued_cpu_work(cpu);
} }
static void qemu_tcg_rr_wait_io_event(CPUState *cpu) static void qemu_tcg_rr_wait_io_event(void)
{ {
CPUState *cpu;
while (all_cpu_threads_idle()) { while (all_cpu_threads_idle()) {
stop_tcg_kick_timer(); stop_tcg_kick_timer();
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); qemu_cond_wait(first_cpu->halt_cond, &qemu_global_mutex);
} }
start_tcg_kick_timer(); start_tcg_kick_timer();
CPU_FOREACH(cpu) {
qemu_wait_io_event_common(cpu); qemu_wait_io_event_common(cpu);
} }
}
static void qemu_wait_io_event(CPUState *cpu) static void qemu_wait_io_event(CPUState *cpu)
{ {
@ -1562,7 +1566,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
qemu_notify_event(); qemu_notify_event();
} }
qemu_tcg_rr_wait_io_event(cpu ? cpu : first_cpu); qemu_tcg_rr_wait_io_event();
deal_with_unplugged_cpus(); deal_with_unplugged_cpus();
} }

View File

@ -1073,7 +1073,7 @@ static const VMStateDescription vmstate_virtio_gpu_scanouts = {
}; };
static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size, static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
VirtIOGPU *g = opaque; VirtIOGPU *g = opaque;
struct virtio_gpu_simple_resource *res; struct virtio_gpu_simple_resource *res;
@ -1101,7 +1101,7 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
} }
static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
VMStateField *field) const VMStateField *field)
{ {
VirtIOGPU *g = opaque; VirtIOGPU *g = opaque;
struct virtio_gpu_simple_resource *res; struct virtio_gpu_simple_resource *res;

View File

@ -376,7 +376,7 @@ static void kvm_s390_release_adapter_routes(S390FLICState *fs,
* reached * reached
*/ */
static int kvm_flic_save(QEMUFile *f, void *opaque, size_t size, static int kvm_flic_save(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
KVMS390FLICState *flic = opaque; KVMS390FLICState *flic = opaque;
int len = FLIC_SAVE_INITIAL_SIZE; int len = FLIC_SAVE_INITIAL_SIZE;
@ -426,7 +426,7 @@ static int kvm_flic_save(QEMUFile *f, void *opaque, size_t size,
* in QEMUFile * in QEMUFile
*/ */
static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size, static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size,
VMStateField *field) const VMStateField *field)
{ {
uint64_t len = 0; uint64_t len = 0;
uint64_t count = 0; uint64_t count = 0;

View File

@ -95,15 +95,15 @@ struct _eeprom_t {
*/ */
static int get_uint16_from_uint8(QEMUFile *f, void *pv, size_t size, static int get_uint16_from_uint8(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
uint16_t *v = pv; uint16_t *v = pv;
*v = qemu_get_ubyte(f); *v = qemu_get_ubyte(f);
return 0; return 0;
} }
static int put_unused(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_unused(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
fprintf(stderr, "uint16_from_uint8 is used only for backwards compatibility.\n"); fprintf(stderr, "uint16_from_uint8 is used only for backwards compatibility.\n");
fprintf(stderr, "Never should be used to write a new state.\n"); fprintf(stderr, "Never should be used to write a new state.\n");

View File

@ -520,15 +520,15 @@ static void fw_cfg_reset(DeviceState *d)
*/ */
static int get_uint32_as_uint16(QEMUFile *f, void *pv, size_t size, static int get_uint32_as_uint16(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
uint32_t *v = pv; uint32_t *v = pv;
*v = qemu_get_be16(f); *v = qemu_get_be16(f);
return 0; return 0;
} }
static int put_unused(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_unused(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
fprintf(stderr, "uint32_as_uint16 is only used for backward compatibility.\n"); fprintf(stderr, "uint32_as_uint16 is only used for backward compatibility.\n");
fprintf(stderr, "This functions shouldn't be called.\n"); fprintf(stderr, "This functions shouldn't be called.\n");

View File

@ -625,7 +625,7 @@ void msix_unset_vector_notifiers(PCIDevice *dev)
} }
static int put_msix_state(QEMUFile *f, void *pv, size_t size, static int put_msix_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
msix_save(pv, f); msix_save(pv, f);
@ -633,7 +633,7 @@ static int put_msix_state(QEMUFile *f, void *pv, size_t size,
} }
static int get_msix_state(QEMUFile *f, void *pv, size_t size, static int get_msix_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
msix_load(pv, f); msix_load(pv, f);
return 0; return 0;

View File

@ -450,7 +450,7 @@ int pci_bus_numa_node(PCIBus *bus)
} }
static int get_pci_config_device(QEMUFile *f, void *pv, size_t size, static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
PCIDevice *s = container_of(pv, PCIDevice, config); PCIDevice *s = container_of(pv, PCIDevice, config);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(s); PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(s);
@ -490,7 +490,7 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
/* just put buffer */ /* just put buffer */
static int put_pci_config_device(QEMUFile *f, void *pv, size_t size, static int put_pci_config_device(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
const uint8_t **v = pv; const uint8_t **v = pv;
assert(size == pci_config_size(container_of(pv, PCIDevice, config))); assert(size == pci_config_size(container_of(pv, PCIDevice, config)));
@ -506,7 +506,7 @@ static VMStateInfo vmstate_info_pci_config = {
}; };
static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size, static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
PCIDevice *s = container_of(pv, PCIDevice, irq_state); PCIDevice *s = container_of(pv, PCIDevice, irq_state);
uint32_t irq_state[PCI_NUM_PINS]; uint32_t irq_state[PCI_NUM_PINS];
@ -528,7 +528,7 @@ static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size,
} }
static int put_pci_irq_state(QEMUFile *f, void *pv, size_t size, static int put_pci_irq_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
int i; int i;
PCIDevice *s = container_of(pv, PCIDevice, irq_state); PCIDevice *s = container_of(pv, PCIDevice, irq_state);

View File

@ -688,8 +688,8 @@ void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
shpc_cap_update_dword(d); shpc_cap_update_dword(d);
} }
static int shpc_save(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int shpc_save(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
PCIDevice *d = container_of(pv, PCIDevice, shpc); PCIDevice *d = container_of(pv, PCIDevice, shpc);
qemu_put_buffer(f, d->shpc->config, SHPC_SIZEOF(d)); qemu_put_buffer(f, d->shpc->config, SHPC_SIZEOF(d));
@ -697,7 +697,8 @@ static int shpc_save(QEMUFile *f, void *pv, size_t size, VMStateField *field,
return 0; return 0;
} }
static int shpc_load(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int shpc_load(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
PCIDevice *d = container_of(pv, PCIDevice, shpc); PCIDevice *d = container_of(pv, PCIDevice, shpc);
int ret = qemu_get_buffer(f, d->shpc->config, SHPC_SIZEOF(d)); int ret = qemu_get_buffer(f, d->shpc->config, SHPC_SIZEOF(d));

View File

@ -298,6 +298,18 @@ static inline int lsi_irq_on_rsl(LSIState *s)
return (s->sien0 & LSI_SIST0_RSL) && (s->scid & LSI_SCID_RRE); return (s->sien0 & LSI_SIST0_RSL) && (s->scid & LSI_SCID_RRE);
} }
static lsi_request *get_pending_req(LSIState *s)
{
lsi_request *p;
QTAILQ_FOREACH(p, &s->queue, next) {
if (p->pending) {
return p;
}
}
return NULL;
}
static void lsi_soft_reset(LSIState *s) static void lsi_soft_reset(LSIState *s)
{ {
trace_lsi_reset(); trace_lsi_reset();
@ -446,7 +458,6 @@ static void lsi_update_irq(LSIState *s)
{ {
int level; int level;
static int last_level; static int last_level;
lsi_request *p;
/* It's unclear whether the DIP/SIP bits should be cleared when the /* It's unclear whether the DIP/SIP bits should be cleared when the
Interrupt Status Registers are cleared or when istat0 is read. Interrupt Status Registers are cleared or when istat0 is read.
@ -476,13 +487,13 @@ static void lsi_update_irq(LSIState *s)
} }
lsi_set_irq(s, level); lsi_set_irq(s, level);
if (!level && lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON)) { if (!s->current && !level && lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON)) {
lsi_request *p;
trace_lsi_update_irq_disconnected(); trace_lsi_update_irq_disconnected();
QTAILQ_FOREACH(p, &s->queue, next) { p = get_pending_req(s);
if (p->pending) { if (p) {
lsi_reselect(s, p); lsi_reselect(s, p);
break;
}
} }
} }
} }
@ -1065,11 +1076,12 @@ static void lsi_wait_reselect(LSIState *s)
trace_lsi_wait_reselect(); trace_lsi_wait_reselect();
QTAILQ_FOREACH(p, &s->queue, next) { if (s->current) {
if (p->pending) { return;
lsi_reselect(s, p);
break;
} }
p = get_pending_req(s);
if (p) {
lsi_reselect(s, p);
} }
if (s->current == NULL) { if (s->current == NULL) {
s->waiting = 1; s->waiting = 1;
@ -1259,6 +1271,18 @@ again:
case 1: /* Disconnect */ case 1: /* Disconnect */
trace_lsi_execute_script_io_disconnect(); trace_lsi_execute_script_io_disconnect();
s->scntl1 &= ~LSI_SCNTL1_CON; s->scntl1 &= ~LSI_SCNTL1_CON;
/* FIXME: this is not entirely correct; the target need not ask
* for reselection until it has to send data, while here we force a
* reselection as soon as the bus is free. The correct flow would
* reselect before lsi_transfer_data and disconnect as soon as
* DMA ends.
*/
if (!s->current) {
lsi_request *p = get_pending_req(s);
if (p) {
lsi_reselect(s, p);
}
}
break; break;
case 2: /* Wait Reselect */ case 2: /* Wait Reselect */
if (!lsi_irq_on_rsl(s)) { if (!lsi_irq_on_rsl(s)) {

View File

@ -1571,7 +1571,7 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun)
/* SCSI request list. For simplicity, pv points to the whole device */ /* SCSI request list. For simplicity, pv points to the whole device */
static int put_scsi_requests(QEMUFile *f, void *pv, size_t size, static int put_scsi_requests(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
SCSIDevice *s = pv; SCSIDevice *s = pv;
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus); SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
@ -1599,7 +1599,7 @@ static int put_scsi_requests(QEMUFile *f, void *pv, size_t size,
} }
static int get_scsi_requests(QEMUFile *f, void *pv, size_t size, static int get_scsi_requests(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
SCSIDevice *s = pv; SCSIDevice *s = pv;
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus); SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);

View File

@ -750,7 +750,7 @@ static int menelaus_rx(I2CSlave *i2c)
*/ */
static int get_int32_as_uint16(QEMUFile *f, void *pv, size_t size, static int get_int32_as_uint16(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
int *v = pv; int *v = pv;
*v = qemu_get_be16(f); *v = qemu_get_be16(f);
@ -758,7 +758,7 @@ static int get_int32_as_uint16(QEMUFile *f, void *pv, size_t size,
} }
static int put_int32_as_uint16(QEMUFile *f, void *pv, size_t size, static int put_int32_as_uint16(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
int *v = pv; int *v = pv;
qemu_put_be16(f, *v); qemu_put_be16(f, *v);

View File

@ -2155,7 +2155,7 @@ static int usbredir_post_load(void *priv, int version_id)
/* For usbredirparser migration */ /* For usbredirparser migration */
static int usbredir_put_parser(QEMUFile *f, void *priv, size_t unused, static int usbredir_put_parser(QEMUFile *f, void *priv, size_t unused,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
USBRedirDevice *dev = priv; USBRedirDevice *dev = priv;
uint8_t *data; uint8_t *data;
@ -2178,7 +2178,7 @@ static int usbredir_put_parser(QEMUFile *f, void *priv, size_t unused,
} }
static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused, static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused,
VMStateField *field) const VMStateField *field)
{ {
USBRedirDevice *dev = priv; USBRedirDevice *dev = priv;
uint8_t *data; uint8_t *data;
@ -2222,7 +2222,7 @@ static const VMStateInfo usbredir_parser_vmstate_info = {
/* For buffered packets (iso/irq) queue migration */ /* For buffered packets (iso/irq) queue migration */
static int usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused, static int usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
struct endp_data *endp = priv; struct endp_data *endp = priv;
USBRedirDevice *dev = endp->dev; USBRedirDevice *dev = endp->dev;
@ -2245,7 +2245,7 @@ static int usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused,
} }
static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused, static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused,
VMStateField *field) const VMStateField *field)
{ {
struct endp_data *endp = priv; struct endp_data *endp = priv;
USBRedirDevice *dev = endp->dev; USBRedirDevice *dev = endp->dev;
@ -2349,7 +2349,7 @@ static const VMStateDescription usbredir_ep_vmstate = {
/* For PacketIdQueue migration */ /* For PacketIdQueue migration */
static int usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused, static int usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
struct PacketIdQueue *q = priv; struct PacketIdQueue *q = priv;
USBRedirDevice *dev = q->dev; USBRedirDevice *dev = q->dev;
@ -2368,7 +2368,7 @@ static int usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused,
} }
static int usbredir_get_packet_id_q(QEMUFile *f, void *priv, size_t unused, static int usbredir_get_packet_id_q(QEMUFile *f, void *priv, size_t unused,
VMStateField *field) const VMStateField *field)
{ {
struct PacketIdQueue *q = priv; struct PacketIdQueue *q = priv;
USBRedirDevice *dev = q->dev; USBRedirDevice *dev = q->dev;

View File

@ -1816,7 +1816,7 @@ static const VMStateDescription vmstate_virtio_ringsize = {
}; };
static int get_extra_state(QEMUFile *f, void *pv, size_t size, static int get_extra_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
VirtIODevice *vdev = pv; VirtIODevice *vdev = pv;
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
@ -1830,7 +1830,7 @@ static int get_extra_state(QEMUFile *f, void *pv, size_t size,
} }
static int put_extra_state(QEMUFile *f, void *pv, size_t size, static int put_extra_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
VirtIODevice *vdev = pv; VirtIODevice *vdev = pv;
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
@ -1979,14 +1979,14 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f)
/* A wrapper for use as a VMState .put function */ /* A wrapper for use as a VMState .put function */
static int virtio_device_put(QEMUFile *f, void *opaque, size_t size, static int virtio_device_put(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
return virtio_save(VIRTIO_DEVICE(opaque), f); return virtio_save(VIRTIO_DEVICE(opaque), f);
} }
/* A wrapper for use as a VMState .get function */ /* A wrapper for use as a VMState .get function */
static int virtio_device_get(QEMUFile *f, void *opaque, size_t size, static int virtio_device_get(QEMUFile *f, void *opaque, size_t size,
VMStateField *field) const VMStateField *field)
{ {
VirtIODevice *vdev = VIRTIO_DEVICE(opaque); VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
DeviceClass *dc = DEVICE_CLASS(VIRTIO_DEVICE_GET_CLASS(vdev)); DeviceClass *dc = DEVICE_CLASS(VIRTIO_DEVICE_GET_CLASS(vdev));

View File

@ -40,8 +40,8 @@ typedef struct VMStateField VMStateField;
*/ */
struct VMStateInfo { struct VMStateInfo {
const char *name; const char *name;
int (*get)(QEMUFile *f, void *pv, size_t size, VMStateField *field); int (*get)(QEMUFile *f, void *pv, size_t size, const VMStateField *field);
int (*put)(QEMUFile *f, void *pv, size_t size, VMStateField *field, int (*put)(QEMUFile *f, void *pv, size_t size, const VMStateField *field,
QJSON *vmdesc); QJSON *vmdesc);
}; };
@ -186,7 +186,7 @@ struct VMStateDescription {
int (*post_load)(void *opaque, int version_id); int (*post_load)(void *opaque, int version_id);
int (*pre_save)(void *opaque); int (*pre_save)(void *opaque);
bool (*needed)(void *opaque); bool (*needed)(void *opaque);
VMStateField *fields; const VMStateField *fields;
const VMStateDescription **subsections; const VMStateDescription **subsections;
}; };

View File

@ -263,15 +263,16 @@ void timer_get(QEMUFile *f, QEMUTimer *ts)
* Not in vmstate.c to not add qemu-timer.c as dependency to vmstate.c * Not in vmstate.c to not add qemu-timer.c as dependency to vmstate.c
*/ */
static int get_timer(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_timer(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
QEMUTimer *v = pv; QEMUTimer *v = pv;
timer_get(f, v); timer_get(f, v);
return 0; return 0;
} }
static int put_timer(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_timer(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
QEMUTimer *v = pv; QEMUTimer *v = pv;
timer_put(f, v); timer_put(f, v);
@ -2455,6 +2456,10 @@ int save_snapshot(const char *name, Error **errp)
struct tm tm; struct tm tm;
AioContext *aio_context; AioContext *aio_context;
if (migration_is_blocked(errp)) {
return false;
}
if (!replay_can_snapshot()) { if (!replay_can_snapshot()) {
error_setg(errp, "Record/replay does not allow making snapshot " error_setg(errp, "Record/replay does not allow making snapshot "
"right now. Try once more later."); "right now. Try once more later.");

View File

@ -22,15 +22,16 @@
/* bool */ /* bool */
static int get_bool(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_bool(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
bool *v = pv; bool *v = pv;
*v = qemu_get_byte(f); *v = qemu_get_byte(f);
return 0; return 0;
} }
static int put_bool(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_bool(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
bool *v = pv; bool *v = pv;
qemu_put_byte(f, *v); qemu_put_byte(f, *v);
@ -45,15 +46,16 @@ const VMStateInfo vmstate_info_bool = {
/* 8 bit int */ /* 8 bit int */
static int get_int8(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_int8(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
int8_t *v = pv; int8_t *v = pv;
qemu_get_s8s(f, v); qemu_get_s8s(f, v);
return 0; return 0;
} }
static int put_int8(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_int8(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
int8_t *v = pv; int8_t *v = pv;
qemu_put_s8s(f, v); qemu_put_s8s(f, v);
@ -68,15 +70,16 @@ const VMStateInfo vmstate_info_int8 = {
/* 16 bit int */ /* 16 bit int */
static int get_int16(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_int16(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
int16_t *v = pv; int16_t *v = pv;
qemu_get_sbe16s(f, v); qemu_get_sbe16s(f, v);
return 0; return 0;
} }
static int put_int16(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_int16(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
int16_t *v = pv; int16_t *v = pv;
qemu_put_sbe16s(f, v); qemu_put_sbe16s(f, v);
@ -91,15 +94,16 @@ const VMStateInfo vmstate_info_int16 = {
/* 32 bit int */ /* 32 bit int */
static int get_int32(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_int32(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
int32_t *v = pv; int32_t *v = pv;
qemu_get_sbe32s(f, v); qemu_get_sbe32s(f, v);
return 0; return 0;
} }
static int put_int32(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_int32(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
int32_t *v = pv; int32_t *v = pv;
qemu_put_sbe32s(f, v); qemu_put_sbe32s(f, v);
@ -116,7 +120,7 @@ const VMStateInfo vmstate_info_int32 = {
in the field */ in the field */
static int get_int32_equal(QEMUFile *f, void *pv, size_t size, static int get_int32_equal(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
int32_t *v = pv; int32_t *v = pv;
int32_t v2; int32_t v2;
@ -142,7 +146,8 @@ const VMStateInfo vmstate_info_int32_equal = {
* and less than or equal to the one in the field. * and less than or equal to the one in the field.
*/ */
static int get_int32_le(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_int32_le(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
int32_t *cur = pv; int32_t *cur = pv;
int32_t loaded; int32_t loaded;
@ -166,15 +171,16 @@ const VMStateInfo vmstate_info_int32_le = {
/* 64 bit int */ /* 64 bit int */
static int get_int64(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_int64(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
int64_t *v = pv; int64_t *v = pv;
qemu_get_sbe64s(f, v); qemu_get_sbe64s(f, v);
return 0; return 0;
} }
static int put_int64(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_int64(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
int64_t *v = pv; int64_t *v = pv;
qemu_put_sbe64s(f, v); qemu_put_sbe64s(f, v);
@ -189,15 +195,16 @@ const VMStateInfo vmstate_info_int64 = {
/* 8 bit unsigned int */ /* 8 bit unsigned int */
static int get_uint8(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_uint8(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
uint8_t *v = pv; uint8_t *v = pv;
qemu_get_8s(f, v); qemu_get_8s(f, v);
return 0; return 0;
} }
static int put_uint8(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_uint8(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
uint8_t *v = pv; uint8_t *v = pv;
qemu_put_8s(f, v); qemu_put_8s(f, v);
@ -212,15 +219,16 @@ const VMStateInfo vmstate_info_uint8 = {
/* 16 bit unsigned int */ /* 16 bit unsigned int */
static int get_uint16(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_uint16(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
uint16_t *v = pv; uint16_t *v = pv;
qemu_get_be16s(f, v); qemu_get_be16s(f, v);
return 0; return 0;
} }
static int put_uint16(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_uint16(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
uint16_t *v = pv; uint16_t *v = pv;
qemu_put_be16s(f, v); qemu_put_be16s(f, v);
@ -235,15 +243,16 @@ const VMStateInfo vmstate_info_uint16 = {
/* 32 bit unsigned int */ /* 32 bit unsigned int */
static int get_uint32(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_uint32(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
uint32_t *v = pv; uint32_t *v = pv;
qemu_get_be32s(f, v); qemu_get_be32s(f, v);
return 0; return 0;
} }
static int put_uint32(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_uint32(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
uint32_t *v = pv; uint32_t *v = pv;
qemu_put_be32s(f, v); qemu_put_be32s(f, v);
@ -260,7 +269,7 @@ const VMStateInfo vmstate_info_uint32 = {
in the field */ in the field */
static int get_uint32_equal(QEMUFile *f, void *pv, size_t size, static int get_uint32_equal(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
uint32_t *v = pv; uint32_t *v = pv;
uint32_t v2; uint32_t v2;
@ -284,15 +293,16 @@ const VMStateInfo vmstate_info_uint32_equal = {
/* 64 bit unsigned int */ /* 64 bit unsigned int */
static int get_uint64(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_uint64(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
uint64_t *v = pv; uint64_t *v = pv;
qemu_get_be64s(f, v); qemu_get_be64s(f, v);
return 0; return 0;
} }
static int put_uint64(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_uint64(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
uint64_t *v = pv; uint64_t *v = pv;
qemu_put_be64s(f, v); qemu_put_be64s(f, v);
@ -305,7 +315,8 @@ const VMStateInfo vmstate_info_uint64 = {
.put = put_uint64, .put = put_uint64,
}; };
static int get_nullptr(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_nullptr(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
if (qemu_get_byte(f) == VMS_NULLPTR_MARKER) { if (qemu_get_byte(f) == VMS_NULLPTR_MARKER) {
@ -316,7 +327,7 @@ static int get_nullptr(QEMUFile *f, void *pv, size_t size, VMStateField *field)
} }
static int put_nullptr(QEMUFile *f, void *pv, size_t size, static int put_nullptr(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
if (pv == NULL) { if (pv == NULL) {
@ -337,7 +348,7 @@ const VMStateInfo vmstate_info_nullptr = {
in the field */ in the field */
static int get_uint64_equal(QEMUFile *f, void *pv, size_t size, static int get_uint64_equal(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
uint64_t *v = pv; uint64_t *v = pv;
uint64_t v2; uint64_t v2;
@ -363,7 +374,7 @@ const VMStateInfo vmstate_info_uint64_equal = {
in the field */ in the field */
static int get_uint8_equal(QEMUFile *f, void *pv, size_t size, static int get_uint8_equal(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
uint8_t *v = pv; uint8_t *v = pv;
uint8_t v2; uint8_t v2;
@ -389,7 +400,7 @@ const VMStateInfo vmstate_info_uint8_equal = {
in the field */ in the field */
static int get_uint16_equal(QEMUFile *f, void *pv, size_t size, static int get_uint16_equal(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
uint16_t *v = pv; uint16_t *v = pv;
uint16_t v2; uint16_t v2;
@ -414,7 +425,7 @@ const VMStateInfo vmstate_info_uint16_equal = {
/* floating point */ /* floating point */
static int get_float64(QEMUFile *f, void *pv, size_t size, static int get_float64(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
float64 *v = pv; float64 *v = pv;
@ -422,8 +433,8 @@ static int get_float64(QEMUFile *f, void *pv, size_t size,
return 0; return 0;
} }
static int put_float64(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_float64(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
uint64_t *v = pv; uint64_t *v = pv;
@ -440,7 +451,7 @@ const VMStateInfo vmstate_info_float64 = {
/* CPU_DoubleU type */ /* CPU_DoubleU type */
static int get_cpudouble(QEMUFile *f, void *pv, size_t size, static int get_cpudouble(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
CPU_DoubleU *v = pv; CPU_DoubleU *v = pv;
qemu_get_be32s(f, &v->l.upper); qemu_get_be32s(f, &v->l.upper);
@ -449,7 +460,7 @@ static int get_cpudouble(QEMUFile *f, void *pv, size_t size,
} }
static int put_cpudouble(QEMUFile *f, void *pv, size_t size, static int put_cpudouble(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
CPU_DoubleU *v = pv; CPU_DoubleU *v = pv;
qemu_put_be32s(f, &v->l.upper); qemu_put_be32s(f, &v->l.upper);
@ -466,15 +477,15 @@ const VMStateInfo vmstate_info_cpudouble = {
/* uint8_t buffers */ /* uint8_t buffers */
static int get_buffer(QEMUFile *f, void *pv, size_t size, static int get_buffer(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
uint8_t *v = pv; uint8_t *v = pv;
qemu_get_buffer(f, v, size); qemu_get_buffer(f, v, size);
return 0; return 0;
} }
static int put_buffer(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_buffer(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
uint8_t *v = pv; uint8_t *v = pv;
qemu_put_buffer(f, v, size); qemu_put_buffer(f, v, size);
@ -491,7 +502,7 @@ const VMStateInfo vmstate_info_buffer = {
not useful anymore */ not useful anymore */
static int get_unused_buffer(QEMUFile *f, void *pv, size_t size, static int get_unused_buffer(QEMUFile *f, void *pv, size_t size,
VMStateField *field) const VMStateField *field)
{ {
uint8_t buf[1024]; uint8_t buf[1024];
int block_len; int block_len;
@ -505,7 +516,7 @@ static int get_unused_buffer(QEMUFile *f, void *pv, size_t size,
} }
static int put_unused_buffer(QEMUFile *f, void *pv, size_t size, static int put_unused_buffer(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
static const uint8_t buf[1024]; static const uint8_t buf[1024];
int block_len; int block_len;
@ -531,7 +542,8 @@ const VMStateInfo vmstate_info_unused_buffer = {
* in fields that don't really exist in the parent but need to be in the * in fields that don't really exist in the parent but need to be in the
* stream. * stream.
*/ */
static int get_tmp(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_tmp(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
int ret; int ret;
const VMStateDescription *vmsd = field->vmsd; const VMStateDescription *vmsd = field->vmsd;
@ -545,8 +557,8 @@ static int get_tmp(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return ret; return ret;
} }
static int put_tmp(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_tmp(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
const VMStateDescription *vmsd = field->vmsd; const VMStateDescription *vmsd = field->vmsd;
void *tmp = g_malloc(size); void *tmp = g_malloc(size);
@ -573,7 +585,8 @@ const VMStateInfo vmstate_info_tmp = {
*/ */
/* This is the number of 64 bit words sent over the wire */ /* This is the number of 64 bit words sent over the wire */
#define BITS_TO_U64S(nr) DIV_ROUND_UP(nr, 64) #define BITS_TO_U64S(nr) DIV_ROUND_UP(nr, 64)
static int get_bitmap(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_bitmap(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
unsigned long *bmp = pv; unsigned long *bmp = pv;
int i, idx = 0; int i, idx = 0;
@ -587,8 +600,8 @@ static int get_bitmap(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return 0; return 0;
} }
static int put_bitmap(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_bitmap(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
unsigned long *bmp = pv; unsigned long *bmp = pv;
int i, idx = 0; int i, idx = 0;
@ -613,7 +626,7 @@ const VMStateInfo vmstate_info_bitmap = {
* meta data about the QTAILQ is encoded in a VMStateField structure * meta data about the QTAILQ is encoded in a VMStateField structure
*/ */
static int get_qtailq(QEMUFile *f, void *pv, size_t unused_size, static int get_qtailq(QEMUFile *f, void *pv, size_t unused_size,
VMStateField *field) const VMStateField *field)
{ {
int ret = 0; int ret = 0;
const VMStateDescription *vmsd = field->vmsd; const VMStateDescription *vmsd = field->vmsd;
@ -652,7 +665,7 @@ static int get_qtailq(QEMUFile *f, void *pv, size_t unused_size,
/* put for QTAILQ */ /* put for QTAILQ */
static int put_qtailq(QEMUFile *f, void *pv, size_t unused_size, static int put_qtailq(QEMUFile *f, void *pv, size_t unused_size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
const VMStateDescription *vmsd = field->vmsd; const VMStateDescription *vmsd = field->vmsd;
/* offset of the QTAILQ entry in a QTAILQ element*/ /* offset of the QTAILQ entry in a QTAILQ element*/

View File

@ -26,7 +26,7 @@ static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque); void *opaque);
static int vmstate_n_elems(void *opaque, VMStateField *field) static int vmstate_n_elems(void *opaque, const VMStateField *field)
{ {
int n_elems = 1; int n_elems = 1;
@ -50,7 +50,7 @@ static int vmstate_n_elems(void *opaque, VMStateField *field)
return n_elems; return n_elems;
} }
static int vmstate_size(void *opaque, VMStateField *field) static int vmstate_size(void *opaque, const VMStateField *field)
{ {
int size = field->size; int size = field->size;
@ -64,7 +64,8 @@ static int vmstate_size(void *opaque, VMStateField *field)
return size; return size;
} }
static void vmstate_handle_alloc(void *ptr, VMStateField *field, void *opaque) static void vmstate_handle_alloc(void *ptr, const VMStateField *field,
void *opaque)
{ {
if (field->flags & VMS_POINTER && field->flags & VMS_ALLOC) { if (field->flags & VMS_POINTER && field->flags & VMS_ALLOC) {
gsize size = vmstate_size(opaque, field); gsize size = vmstate_size(opaque, field);
@ -78,7 +79,7 @@ static void vmstate_handle_alloc(void *ptr, VMStateField *field, void *opaque)
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, int version_id) void *opaque, int version_id)
{ {
VMStateField *field = vmsd->fields; const VMStateField *field = vmsd->fields;
int ret = 0; int ret = 0;
trace_vmstate_load_state(vmsd->name, version_id); trace_vmstate_load_state(vmsd->name, version_id);
@ -171,9 +172,10 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
return ret; return ret;
} }
static int vmfield_name_num(VMStateField *start, VMStateField *search) static int vmfield_name_num(const VMStateField *start,
const VMStateField *search)
{ {
VMStateField *field; const VMStateField *field;
int found = 0; int found = 0;
for (field = start; field->name; field++) { for (field = start; field->name; field++) {
@ -188,9 +190,10 @@ static int vmfield_name_num(VMStateField *start, VMStateField *search)
return -1; return -1;
} }
static bool vmfield_name_is_unique(VMStateField *start, VMStateField *search) static bool vmfield_name_is_unique(const VMStateField *start,
const VMStateField *search)
{ {
VMStateField *field; const VMStateField *field;
int found = 0; int found = 0;
for (field = start; field->name; field++) { for (field = start; field->name; field++) {
@ -206,7 +209,7 @@ static bool vmfield_name_is_unique(VMStateField *start, VMStateField *search)
return true; return true;
} }
static const char *vmfield_get_type_name(VMStateField *field) static const char *vmfield_get_type_name(const VMStateField *field)
{ {
const char *type = "unknown"; const char *type = "unknown";
@ -221,7 +224,7 @@ static const char *vmfield_get_type_name(VMStateField *field)
return type; return type;
} }
static bool vmsd_can_compress(VMStateField *field) static bool vmsd_can_compress(const VMStateField *field)
{ {
if (field->field_exists) { if (field->field_exists) {
/* Dynamically existing fields mess up compression */ /* Dynamically existing fields mess up compression */
@ -229,7 +232,7 @@ static bool vmsd_can_compress(VMStateField *field)
} }
if (field->flags & VMS_STRUCT) { if (field->flags & VMS_STRUCT) {
VMStateField *sfield = field->vmsd->fields; const VMStateField *sfield = field->vmsd->fields;
while (sfield->name) { while (sfield->name) {
if (!vmsd_can_compress(sfield)) { if (!vmsd_can_compress(sfield)) {
/* Child elements can't compress, so can't we */ /* Child elements can't compress, so can't we */
@ -248,7 +251,7 @@ static bool vmsd_can_compress(VMStateField *field)
} }
static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc, static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc,
VMStateField *field, int i, int max) const VMStateField *field, int i, int max)
{ {
char *name, *old_name; char *name, *old_name;
bool is_array = max > 1; bool is_array = max > 1;
@ -287,7 +290,7 @@ static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc,
} }
static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc, static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc,
VMStateField *field, size_t size, int i) const VMStateField *field, size_t size, int i)
{ {
if (!vmdesc) { if (!vmdesc) {
return; return;
@ -323,7 +326,7 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, QJSON *vmdesc, int version_id) void *opaque, QJSON *vmdesc, int version_id)
{ {
int ret = 0; int ret = 0;
VMStateField *field = vmsd->fields; const VMStateField *field = vmsd->fields;
trace_vmstate_save_state_top(vmsd->name); trace_vmstate_save_state_top(vmsd->name);

View File

@ -4025,7 +4025,7 @@ Memory backend objects offer more control than the @option{-m} option that is
traditionally used to define guest RAM. Please refer to traditionally used to define guest RAM. Please refer to
@option{memory-backend-file} for a description of the options. @option{memory-backend-file} for a description of the options.
@item -object memory-backend-memfd,id=@var{id},merge=@var{on|off},dump=@var{on|off},prealloc=@var{on|off},size=@var{size},host-nodes=@var{host-nodes},policy=@var{default|preferred|bind|interleave},seal=@var{on|off},hugetlb=@var{on|off},hugetlbsize=@var{size} @item -object memory-backend-memfd,id=@var{id},merge=@var{on|off},dump=@var{on|off},share=@var{on|off},prealloc=@var{on|off},size=@var{size},host-nodes=@var{host-nodes},policy=@var{default|preferred|bind|interleave},seal=@var{on|off},hugetlb=@var{on|off},hugetlbsize=@var{size}
Creates an anonymous memory file backend object, which allows QEMU to Creates an anonymous memory file backend object, which allows QEMU to
share the memory with an external process (e.g. when using share the memory with an external process (e.g. when using
@ -4047,6 +4047,8 @@ with the @option{seal} option (requires at least Linux 4.16).
Please refer to @option{memory-backend-file} for a description of the Please refer to @option{memory-backend-file} for a description of the
other options. other options.
The @option{share} boolean option is @var{on} by default with memfd.
@item -object rng-random,id=@var{id},filename=@var{/dev/random} @item -object rng-random,id=@var{id},filename=@var{/dev/random}
Creates a random number generator backend which obtains entropy from Creates a random number generator backend which obtains entropy from

View File

@ -2752,7 +2752,8 @@ sub process {
info_vreport| info_vreport|
error_report| error_report|
warn_report| warn_report|
info_report}x; info_report|
g_test_message}x;
if ($rawline =~ /\b(?:$qemu_error_funcs)\s*\(.*\".*\\n/) { if ($rawline =~ /\b(?:$qemu_error_funcs)\s*\(.*\".*\\n/) {
ERROR("Error messages should not contain newlines\n" . $herecurr); ERROR("Error messages should not contain newlines\n" . $herecurr);

View File

@ -5,7 +5,8 @@
#include "hw/boards.h" #include "hw/boards.h"
#include "migration/cpu.h" #include "migration/cpu.h"
static int get_fpcr(QEMUFile *f, void *opaque, size_t size, VMStateField *field) static int get_fpcr(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
{ {
CPUAlphaState *env = opaque; CPUAlphaState *env = opaque;
cpu_alpha_store_fpcr(env, qemu_get_be64(f)); cpu_alpha_store_fpcr(env, qemu_get_be64(f));
@ -13,7 +14,7 @@ static int get_fpcr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
} }
static int put_fpcr(QEMUFile *f, void *opaque, size_t size, static int put_fpcr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
CPUAlphaState *env = opaque; CPUAlphaState *env = opaque;
qemu_put_be64(f, cpu_alpha_load_fpcr(env)); qemu_put_be64(f, cpu_alpha_load_fpcr(env));

View File

@ -18,7 +18,7 @@ static bool vfp_needed(void *opaque)
} }
static int get_fpscr(QEMUFile *f, void *opaque, size_t size, static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field) const VMStateField *field)
{ {
ARMCPU *cpu = opaque; ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env; CPUARMState *env = &cpu->env;
@ -29,7 +29,7 @@ static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
} }
static int put_fpscr(QEMUFile *f, void *opaque, size_t size, static int put_fpscr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
ARMCPU *cpu = opaque; ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env; CPUARMState *env = &cpu->env;
@ -503,7 +503,7 @@ static const VMStateDescription vmstate_m_security = {
}; };
static int get_cpsr(QEMUFile *f, void *opaque, size_t size, static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field) const VMStateField *field)
{ {
ARMCPU *cpu = opaque; ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env; CPUARMState *env = &cpu->env;
@ -559,7 +559,7 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
} }
static int put_cpsr(QEMUFile *f, void *opaque, size_t size, static int put_cpsr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
ARMCPU *cpu = opaque; ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env; CPUARMState *env = &cpu->env;
@ -585,7 +585,7 @@ static const VMStateInfo vmstate_cpsr = {
}; };
static int get_power(QEMUFile *f, void *opaque, size_t size, static int get_power(QEMUFile *f, void *opaque, size_t size,
VMStateField *field) const VMStateField *field)
{ {
ARMCPU *cpu = opaque; ARMCPU *cpu = opaque;
bool powered_off = qemu_get_byte(f); bool powered_off = qemu_get_byte(f);
@ -594,7 +594,7 @@ static int get_power(QEMUFile *f, void *opaque, size_t size,
} }
static int put_power(QEMUFile *f, void *opaque, size_t size, static int put_power(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
ARMCPU *cpu = opaque; ARMCPU *cpu = opaque;

View File

@ -46,7 +46,8 @@
VMSTATE_UINTTR_ARRAY_V(_f, _s, _n, 0) VMSTATE_UINTTR_ARRAY_V(_f, _s, _n, 0)
static int get_psw(QEMUFile *f, void *opaque, size_t size, VMStateField *field) static int get_psw(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
{ {
CPUHPPAState *env = opaque; CPUHPPAState *env = opaque;
cpu_hppa_put_psw(env, qemu_get_betr(f)); cpu_hppa_put_psw(env, qemu_get_betr(f));
@ -54,7 +55,7 @@ static int get_psw(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
} }
static int put_psw(QEMUFile *f, void *opaque, size_t size, static int put_psw(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
CPUHPPAState *env = opaque; CPUHPPAState *env = opaque;
qemu_put_betr(f, cpu_hppa_get_psw(env)); qemu_put_betr(f, cpu_hppa_get_psw(env));
@ -68,7 +69,8 @@ static const VMStateInfo vmstate_psw = {
}; };
/* FIXME: Use the PA2.0 format, which is a superset of the PA1.1 format. */ /* FIXME: Use the PA2.0 format, which is a superset of the PA1.1 format. */
static int get_tlb(QEMUFile *f, void *opaque, size_t size, VMStateField *field) static int get_tlb(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
{ {
hppa_tlb_entry *ent = opaque; hppa_tlb_entry *ent = opaque;
uint32_t val; uint32_t val;
@ -94,7 +96,7 @@ static int get_tlb(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
} }
static int put_tlb(QEMUFile *f, void *opaque, size_t size, static int put_tlb(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
hppa_tlb_entry *ent = opaque; hppa_tlb_entry *ent = opaque;
uint32_t val = 0; uint32_t val = 0;

View File

@ -855,6 +855,7 @@ static int hyperv_init_vcpu(X86CPU *cpu)
} }
static Error *invtsc_mig_blocker; static Error *invtsc_mig_blocker;
static Error *vmx_mig_blocker;
#define KVM_MAX_CPUID_ENTRIES 100 #define KVM_MAX_CPUID_ENTRIES 100
@ -1247,6 +1248,17 @@ int kvm_arch_init_vcpu(CPUState *cs)
!!(c->ecx & CPUID_EXT_SMX); !!(c->ecx & CPUID_EXT_SMX);
} }
if ((env->features[FEAT_1_ECX] & CPUID_EXT_VMX) && !vmx_mig_blocker) {
error_setg(&vmx_mig_blocker,
"Nested VMX virtualization does not support live migration yet");
r = migrate_add_blocker(vmx_mig_blocker, &local_err);
if (local_err) {
error_report_err(local_err);
error_free(vmx_mig_blocker);
return r;
}
}
if (env->mcg_cap & MCG_LMCE_P) { if (env->mcg_cap & MCG_LMCE_P) {
has_msr_mcg_ext_ctl = has_msr_feature_control = true; has_msr_mcg_ext_ctl = has_msr_feature_control = true;
} }
@ -1254,7 +1266,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (!env->user_tsc_khz) { if (!env->user_tsc_khz) {
if ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC) && if ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC) &&
invtsc_mig_blocker == NULL) { invtsc_mig_blocker == NULL) {
/* for migration */
error_setg(&invtsc_mig_blocker, error_setg(&invtsc_mig_blocker,
"State blocked by non-migratable CPU device" "State blocked by non-migratable CPU device"
" (invtsc flag)"); " (invtsc flag)");
@ -1264,8 +1275,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
error_free(invtsc_mig_blocker); error_free(invtsc_mig_blocker);
return r; return r;
} }
/* for savevm */
vmstate_x86_cpu.unmigratable = 1;
} }
} }

View File

@ -1268,10 +1268,30 @@ static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
} }
} }
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
{
gen_update_cc_op(s);
gen_jmp_im(s, cur_eip);
gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
s->base.is_jmp = DISAS_NORETURN;
}
/* Generate #UD for the current instruction. The assumption here is that
the instruction is known, but it isn't allowed in the current cpu mode. */
static void gen_illegal_opcode(DisasContext *s)
{
gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
}
/* if d == OR_TMP0, it means memory operand (address in A0) */ /* if d == OR_TMP0, it means memory operand (address in A0) */
static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d) static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
{ {
if (d != OR_TMP0) { if (d != OR_TMP0) {
if (s1->prefix & PREFIX_LOCK) {
/* Lock prefix when destination is not memory. */
gen_illegal_opcode(s1);
return;
}
gen_op_mov_v_reg(s1, ot, s1->T0, d); gen_op_mov_v_reg(s1, ot, s1->T0, d);
} else if (!(s1->prefix & PREFIX_LOCK)) { } else if (!(s1->prefix & PREFIX_LOCK)) {
gen_op_ld_v(s1, ot, s1->T0, s1->A0); gen_op_ld_v(s1, ot, s1->T0, s1->A0);
@ -2469,21 +2489,6 @@ static void gen_leave(DisasContext *s)
gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1); gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
} }
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
{
gen_update_cc_op(s);
gen_jmp_im(s, cur_eip);
gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
s->base.is_jmp = DISAS_NORETURN;
}
/* Generate #UD for the current instruction. The assumption here is that
the instruction is known, but it isn't allowed in the current cpu mode. */
static void gen_illegal_opcode(DisasContext *s)
{
gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
}
/* Similarly, except that the assumption here is that we don't decode /* Similarly, except that the assumption here is that we don't decode
the instruction at all -- either a missing opcode, an unimplemented the instruction at all -- either a missing opcode, an unimplemented
feature, or just a bogus instruction stream. */ feature, or just a bogus instruction stream. */

View File

@ -20,7 +20,8 @@ static int cpu_post_load(void *opaque, int version_id)
/* FPU state */ /* FPU state */
static int get_fpr(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_fpr(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
int i; int i;
fpr_t *v = pv; fpr_t *v = pv;
@ -31,8 +32,8 @@ static int get_fpr(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return 0; return 0;
} }
static int put_fpr(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_fpr(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
int i; int i;
fpr_t *v = pv; fpr_t *v = pv;
@ -128,7 +129,8 @@ const VMStateDescription vmstate_mvp = {
/* TLB state */ /* TLB state */
static int get_tlb(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_tlb(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
r4k_tlb_t *v = pv; r4k_tlb_t *v = pv;
uint16_t flags; uint16_t flags;
@ -155,8 +157,8 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return 0; return 0;
} }
static int put_tlb(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_tlb(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
r4k_tlb_t *v = pv; r4k_tlb_t *v = pv;

View File

@ -49,7 +49,8 @@ static const VMStateDescription vmstate_cpu_tlb = {
} }
}; };
static int get_sr(QEMUFile *f, void *opaque, size_t size, VMStateField *field) static int get_sr(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
{ {
CPUOpenRISCState *env = opaque; CPUOpenRISCState *env = opaque;
cpu_set_sr(env, qemu_get_be32(f)); cpu_set_sr(env, qemu_get_be32(f));
@ -57,7 +58,7 @@ static int get_sr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
} }
static int put_sr(QEMUFile *f, void *opaque, size_t size, static int put_sr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
CPUOpenRISCState *env = opaque; CPUOpenRISCState *env = opaque;
qemu_put_be32(f, cpu_get_sr(env)); qemu_put_be32(f, cpu_get_sr(env));

View File

@ -110,7 +110,8 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
return 0; return 0;
} }
static int get_avr(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_avr(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
ppc_avr_t *v = pv; ppc_avr_t *v = pv;
@ -120,8 +121,8 @@ static int get_avr(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return 0; return 0;
} }
static int put_avr(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_avr(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
ppc_avr_t *v = pv; ppc_avr_t *v = pv;
@ -452,7 +453,8 @@ static const VMStateDescription vmstate_sr = {
}; };
#ifdef TARGET_PPC64 #ifdef TARGET_PPC64
static int get_slbe(QEMUFile *f, void *pv, size_t size, VMStateField *field) static int get_slbe(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{ {
ppc_slb_t *v = pv; ppc_slb_t *v = pv;
@ -462,8 +464,8 @@ static int get_slbe(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return 0; return 0;
} }
static int put_slbe(QEMUFile *f, void *pv, size_t size, VMStateField *field, static int put_slbe(QEMUFile *f, void *pv, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
ppc_slb_t *v = pv; ppc_slb_t *v = pv;

View File

@ -56,7 +56,8 @@ static const VMStateDescription vmstate_tlb_entry = {
}; };
#endif #endif
static int get_psr(QEMUFile *f, void *opaque, size_t size, VMStateField *field) static int get_psr(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
{ {
SPARCCPU *cpu = opaque; SPARCCPU *cpu = opaque;
CPUSPARCState *env = &cpu->env; CPUSPARCState *env = &cpu->env;
@ -69,8 +70,8 @@ static int get_psr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
return 0; return 0;
} }
static int put_psr(QEMUFile *f, void *opaque, size_t size, VMStateField *field, static int put_psr(QEMUFile *f, void *opaque, size_t size,
QJSON *vmdesc) const VMStateField *field, QJSON *vmdesc)
{ {
SPARCCPU *cpu = opaque; SPARCCPU *cpu = opaque;
CPUSPARCState *env = &cpu->env; CPUSPARCState *env = &cpu->env;

View File

@ -323,7 +323,7 @@ vubr_backend_recv_cb(int sock, void *ctx)
.msg_name = (struct sockaddr *) &vubr->backend_udp_dest, .msg_name = (struct sockaddr *) &vubr->backend_udp_dest,
.msg_namelen = sizeof(struct sockaddr_in), .msg_namelen = sizeof(struct sockaddr_in),
.msg_iov = sg, .msg_iov = sg,
.msg_iovlen = elem->in_num, .msg_iovlen = num,
.msg_flags = MSG_DONTWAIT, .msg_flags = MSG_DONTWAIT,
}; };
do { do {

9
vl.c
View File

@ -1523,9 +1523,6 @@ static int machine_help_func(QemuOpts *opts, MachineState *machine)
return 1; return 1;
} }
/***********************************************************/
/* main execution loop */
struct vm_change_state_entry { struct vm_change_state_entry {
VMChangeStateHandler *cb; VMChangeStateHandler *cb;
void *opaque; void *opaque;
@ -2250,8 +2247,10 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */ size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */
buf = g_memdup(str, size); buf = g_memdup(str, size);
} else { } else {
if (!g_file_get_contents(file, &buf, &size, NULL)) { GError *err = NULL;
error_setg(errp, "can't load %s", file); if (!g_file_get_contents(file, &buf, &size, &err)) {
error_setg(errp, "can't load %s: %s", file, err->message);
g_error_free(err);
return -1; return -1;
} }
} }