Bug fixes.

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQEcBAABAgAGBQJbTgXfAAoJEL/70l94x66DTbYH/3NutBAkNZKX7EImj/d0I1O8
 nERMVH1R70KBcugdsjhaBfTRoATDXdrBng4MBqloIK9dEMT3g6D4TFZJLU+WAjOc
 8sItx0BrUR7Sl8SnAvWNFoqVtvVancFiLnu11DsFGM0l8mJHRlZSkQZ0Fd0FL2W/
 OPnW7t6F7B2bc1VlPfSs093FVCoD3S+lJmbj64dwNrn8+fOX918V6gSaYQe92aIY
 pSbJjkRDx2iULmzMY8QH4OQiHgnd/Pijj+D628DMrUc0iW1Rsw5V2Yq7SMY6zoa8
 MoI/YDwX6eRMU2mq74BrKlULZrpmQn+6ZCdZTvXzLwc2zpKD4puO4FuMBOA7yx4=
 =GcxI
 -----END PGP SIGNATURE-----

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

Bug fixes.

# gpg: Signature made Tue 17 Jul 2018 16:06:07 BST
# 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:
  Document command line options with single dash
  opts: remove redundant check for NULL parameter
  i386: only parse the initrd_filename once for multiboot modules
  i386: fix regression parsing multiboot initrd modules
  virtio-scsi: fix hotplug ->reset() vs event race
  qdev: add HotplugHandler->post_plug() callback
  hw/char/serial: retry write if EAGAIN
  PC Chipset: Improve serial divisor calculation
  vhost-user-test: added proper TestServer *dest initialization in test_migrate()
  hyperv: ensure VP index equal to QEMU cpu_index
  hyperv: rename vcpu_id to vp_index
  accel: Fix typo and grammar in comment
  dump: add kernel_gs_base to QEMU CPU state

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-07-17 17:06:32 +01:00
commit 59b5552f02
18 changed files with 184 additions and 62 deletions

View file

@ -1795,7 +1795,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
tb->jmp_dest[0] = (uintptr_t)NULL;
tb->jmp_dest[1] = (uintptr_t)NULL;
/* init original jump addresses wich has been set during tcg_gen_code() */
/* init original jump addresses which have been set during tcg_gen_code() */
if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) {
tb_reset_jump(tb, 0);
}

View file

@ -150,13 +150,10 @@ static void serial_update_irq(SerialState *s)
static void serial_update_parameters(SerialState *s)
{
int speed, parity, data_bits, stop_bits, frame_size;
float speed;
int parity, data_bits, stop_bits, frame_size;
QEMUSerialSetParams ssp;
if (s->divider == 0 || s->divider > s->baudbase) {
return;
}
/* Start bit. */
frame_size = 1;
if (s->lcr & 0x08) {
@ -169,14 +166,16 @@ static void serial_update_parameters(SerialState *s)
} else {
parity = 'N';
}
if (s->lcr & 0x04)
if (s->lcr & 0x04) {
stop_bits = 2;
else
} else {
stop_bits = 1;
}
data_bits = (s->lcr & 0x03) + 5;
frame_size += data_bits + stop_bits;
speed = s->baudbase / s->divider;
/* Zero divisor should give about 3500 baud */
speed = (s->divider == 0) ? 3500 : (float) s->baudbase / s->divider;
ssp.speed = speed;
ssp.parity = parity;
ssp.data_bits = data_bits;
@ -184,7 +183,7 @@ static void serial_update_parameters(SerialState *s)
s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size;
qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
DPRINTF("speed=%d parity=%c data=%d stop=%d\n",
DPRINTF("speed=%.2f parity=%c data=%d stop=%d\n",
speed, parity, data_bits, stop_bits);
}
@ -261,15 +260,20 @@ static void serial_xmit(SerialState *s)
if (s->mcr & UART_MCR_LOOP) {
/* in loopback mode, say that we just received a char */
serial_receive1(s, &s->tsr, 1);
} else if (qemu_chr_fe_write(&s->chr, &s->tsr, 1) == 0 &&
s->tsr_retry < MAX_XMIT_RETRY) {
assert(s->watch_tag == 0);
s->watch_tag =
qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
serial_watch_cb, s);
if (s->watch_tag > 0) {
s->tsr_retry++;
return;
} else {
int rc = qemu_chr_fe_write(&s->chr, &s->tsr, 1);
if ((rc == 0 ||
(rc == -1 && errno == EAGAIN)) &&
s->tsr_retry < MAX_XMIT_RETRY) {
assert(s->watch_tag == 0);
s->watch_tag =
qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
serial_watch_cb, s);
if (s->watch_tag > 0) {
s->tsr_retry++;
return;
}
}
}
s->tsr_retry = 0;
@ -341,7 +345,11 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
default:
case 0:
if (s->lcr & UART_LCR_DLAB) {
s->divider = (s->divider & 0xff00) | val;
if (size == 2) {
s->divider = (s->divider & 0xff00) | val;
} else if (size == 4) {
s->divider = val;
}
serial_update_parameters(s);
} else {
s->thr = (uint8_t) val;

View file

@ -35,6 +35,16 @@ void hotplug_handler_plug(HotplugHandler *plug_handler,
}
}
void hotplug_handler_post_plug(HotplugHandler *plug_handler,
DeviceState *plugged_dev)
{
HotplugHandlerClass *hdc = HOTPLUG_HANDLER_GET_CLASS(plug_handler);
if (hdc->post_plug) {
hdc->post_plug(plug_handler, plugged_dev);
}
}
void hotplug_handler_unplug_request(HotplugHandler *plug_handler,
DeviceState *plugged_dev,
Error **errp)

View file

@ -867,6 +867,10 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
device_reset(dev);
}
dev->pending_deleted_event = false;
if (hotplug_ctrl) {
hotplug_handler_post_plug(hotplug_ctrl, dev);
}
} else if (!value && dev->realized) {
Error **local_errp = NULL;
QLIST_FOREACH(bus, &dev->child_bus, sibling) {

View file

@ -161,6 +161,7 @@ int load_multiboot(FWCfgState *fw_cfg,
uint8_t bootinfo[MBI_SIZE];
uint8_t *mb_bootinfo_data;
uint32_t cmdline_len;
GList *mods = NULL;
/* Ok, let's see if it is a multiboot image.
The header is 12x32bit long, so the latest entry may be 8192 - 48. */
@ -291,16 +292,16 @@ int load_multiboot(FWCfgState *fw_cfg,
cmdline_len = strlen(kernel_filename) + 1;
cmdline_len += strlen(kernel_cmdline) + 1;
if (initrd_filename) {
const char *r = get_opt_value(initrd_filename, NULL);
cmdline_len += strlen(r) + 1;
mbs.mb_mods_avail = 1;
while (1) {
const char *r = initrd_filename;
cmdline_len += strlen(initrd_filename) + 1;
while (*r) {
char *value;
r = get_opt_value(r, &value);
mbs.mb_mods_avail++;
r = get_opt_value(r, NULL);
if (!*r) {
break;
mods = g_list_append(mods, value);
if (*r) {
r++;
}
r++;
}
}
@ -315,20 +316,16 @@ int load_multiboot(FWCfgState *fw_cfg,
mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE;
mbs.offset_bootloader = mbs.offset_cmdlines + cmdline_len;
if (initrd_filename) {
const char *next_initrd;
char not_last;
char *one_file = NULL;
if (mods) {
GList *tmpl = mods;
mbs.offset_mods = mbs.mb_buf_size;
do {
while (tmpl) {
char *next_space;
int mb_mod_length;
uint32_t offs = mbs.mb_buf_size;
char *one_file = tmpl->data;
next_initrd = get_opt_value(initrd_filename, &one_file);
not_last = *next_initrd;
/* if a space comes after the module filename, treat everything
after that as parameters */
hwaddr c = mb_add_cmdline(&mbs, one_file);
@ -353,10 +350,10 @@ int load_multiboot(FWCfgState *fw_cfg,
mb_debug("mod_start: %p\nmod_end: %p\n cmdline: "TARGET_FMT_plx,
(char *)mbs.mb_buf + offs,
(char *)mbs.mb_buf + offs + mb_mod_length, c);
initrd_filename = next_initrd+1;
g_free(one_file);
one_file = NULL;
} while (not_last);
tmpl = tmpl->next;
}
g_list_free(mods);
}
/* Commandline support */

View file

@ -1999,6 +1999,11 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
}
cpu->thread_id = topo.smt_id;
if (cpu->hyperv_vpindex && !kvm_hv_vpindex_settable()) {
error_setg(errp, "kernel doesn't allow setting HyperV VP_INDEX");
return;
}
cs = CPU(cpu);
cs->cpu_index = idx;

View file

@ -57,7 +57,7 @@ static void free_sint_route_index(HypervTestDev *dev, int i)
dev->sint_route[i] = NULL;
}
static int find_sint_route_index(HypervTestDev *dev, uint32_t vcpu_id,
static int find_sint_route_index(HypervTestDev *dev, uint32_t vp_index,
uint32_t sint)
{
HvSintRoute *sint_route;
@ -65,7 +65,7 @@ static int find_sint_route_index(HypervTestDev *dev, uint32_t vcpu_id,
for (i = 0; i < ARRAY_SIZE(dev->sint_route); i++) {
sint_route = dev->sint_route[i];
if (sint_route && sint_route->vcpu_id == vcpu_id &&
if (sint_route && sint_route->vp_index == vp_index &&
sint_route->sint == sint) {
return i;
}
@ -74,7 +74,7 @@ static int find_sint_route_index(HypervTestDev *dev, uint32_t vcpu_id,
}
static void hv_synic_test_dev_control(HypervTestDev *dev, uint32_t ctl,
uint32_t vcpu_id, uint32_t sint)
uint32_t vp_index, uint32_t sint)
{
int i;
HvSintRoute *sint_route;
@ -83,19 +83,19 @@ static void hv_synic_test_dev_control(HypervTestDev *dev, uint32_t ctl,
case HV_TEST_DEV_SINT_ROUTE_CREATE:
i = alloc_sint_route_index(dev);
assert(i >= 0);
sint_route = kvm_hv_sint_route_create(vcpu_id, sint, NULL);
sint_route = kvm_hv_sint_route_create(vp_index, sint, NULL);
assert(sint_route);
dev->sint_route[i] = sint_route;
break;
case HV_TEST_DEV_SINT_ROUTE_DESTROY:
i = find_sint_route_index(dev, vcpu_id, sint);
i = find_sint_route_index(dev, vp_index, sint);
assert(i >= 0);
sint_route = dev->sint_route[i];
kvm_hv_sint_route_destroy(sint_route);
free_sint_route_index(dev, i);
break;
case HV_TEST_DEV_SINT_ROUTE_SET_SINT:
i = find_sint_route_index(dev, vcpu_id, sint);
i = find_sint_route_index(dev, vp_index, sint);
assert(i >= 0);
sint_route = dev->sint_route[i];
kvm_hv_sint_route_set_sint(sint_route);
@ -117,8 +117,8 @@ static void hv_test_dev_control(void *opaque, hwaddr addr, uint64_t data,
case HV_TEST_DEV_SINT_ROUTE_DESTROY:
case HV_TEST_DEV_SINT_ROUTE_SET_SINT: {
uint8_t sint = data & 0xFF;
uint8_t vcpu_id = (data >> 8ULL) & 0xFF;
hv_synic_test_dev_control(dev, ctl, vcpu_id, sint);
uint8_t vp_index = (data >> 8ULL) & 0xFF;
hv_synic_test_dev_control(dev, ctl, vp_index, sint);
break;
}
default:

View file

@ -797,8 +797,16 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
virtio_scsi_acquire(s);
blk_set_aio_context(sd->conf.blk, s->ctx);
virtio_scsi_release(s);
}
}
/* Announce the new device after it has been plugged */
static void virtio_scsi_post_hotplug(HotplugHandler *hotplug_dev,
DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev);
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
SCSIDevice *sd = SCSI_DEVICE(dev);
if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
virtio_scsi_acquire(s);
@ -968,6 +976,7 @@ static void virtio_scsi_class_init(ObjectClass *klass, void *data)
vdc->start_ioeventfd = virtio_scsi_dataplane_start;
vdc->stop_ioeventfd = virtio_scsi_dataplane_stop;
hc->plug = virtio_scsi_hotplug;
hc->post_plug = virtio_scsi_post_hotplug;
hc->unplug = virtio_scsi_hotunplug;
}

View file

@ -47,6 +47,8 @@ typedef void (*hotplug_fn)(HotplugHandler *plug_handler,
* @parent: Opaque parent interface.
* @pre_plug: pre plug callback called at start of device.realize(true)
* @plug: plug callback called at end of device.realize(true).
* @post_plug: post plug callback called after device.realize(true) and device
* reset
* @unplug_request: unplug request callback.
* Used as a means to initiate device unplug for devices that
* require asynchronous unplug handling.
@ -61,6 +63,7 @@ typedef struct HotplugHandlerClass {
/* <public> */
hotplug_fn pre_plug;
hotplug_fn plug;
void (*post_plug)(HotplugHandler *plug_handler, DeviceState *plugged_dev);
hotplug_fn unplug_request;
hotplug_fn unplug;
} HotplugHandlerClass;
@ -83,6 +86,14 @@ void hotplug_handler_pre_plug(HotplugHandler *plug_handler,
DeviceState *plugged_dev,
Error **errp);
/**
* hotplug_handler_post_plug:
*
* Call #HotplugHandlerClass.post_plug callback of @plug_handler.
*/
void hotplug_handler_post_plug(HotplugHandler *plug_handler,
DeviceState *plugged_dev);
/**
* hotplug_handler_unplug_request:
*

View file

@ -471,7 +471,7 @@ STEXI
@item -balloon virtio[,addr=@var{addr}]
@findex -balloon
Enable virtio balloon device, optionally with PCI address @var{addr}. This
option is deprecated, use @option{--device virtio-balloon} instead.
option is deprecated, use @option{-device virtio-balloon} instead.
ETEXI
DEF("device", HAS_ARG, QEMU_OPTION_device,
@ -2005,7 +2005,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
"-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
" configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
DEF("nic", HAS_ARG, QEMU_OPTION_nic,
"--nic [tap|bridge|"
"-nic [tap|bridge|"
#ifdef CONFIG_SLIRP
"user|"
#endif
@ -2024,7 +2024,7 @@ DEF("nic", HAS_ARG, QEMU_OPTION_nic,
"socket][,option][,...][mac=macaddr]\n"
" initialize an on-board / default host NIC (using MAC address\n"
" macaddr) and connect it to the given host network backend\n"
"--nic none use it alone to have zero network devices (the default is to\n"
"-nic none use it alone to have zero network devices (the default is to\n"
" provided a 'user' network connection)\n",
QEMU_ARCH_ALL)
DEF("net", HAS_ARG, QEMU_OPTION_net,
@ -3339,7 +3339,7 @@ mlocking qemu and guest memory can be enabled via @option{mlock=on}
ETEXI
DEF("overcommit", HAS_ARG, QEMU_OPTION_overcommit,
"--overcommit [mem-lock=on|off][cpu-pm=on|off]\n"
"-overcommit [mem-lock=on|off][cpu-pm=on|off]\n"
" run qemu with overcommit hints\n"
" mem-lock=on|off controls memory lock support (default: off)\n"
" cpu-pm=on|off controls cpu power management (default: off)\n",

View file

@ -258,6 +258,12 @@ struct QEMUCPUState {
QEMUCPUSegment cs, ds, es, fs, gs, ss;
QEMUCPUSegment ldt, tr, gdt, idt;
uint64_t cr[5];
/*
* Fields below are optional and are being added at the end without
* changing the version. External tools may identify their presence
* by checking 'size' field.
*/
uint64_t kernel_gs_base;
};
typedef struct QEMUCPUState QEMUCPUState;
@ -315,6 +321,10 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUX86State *env)
s->cr[2] = env->cr[2];
s->cr[3] = env->cr[3];
s->cr[4] = env->cr[4];
#ifdef TARGET_X86_64
s->kernel_gs_base = env->kernelgsbase;
#endif
}
static inline int cpu_write_qemu_note(WriteCoreDumpFunction f,

View file

@ -16,6 +16,16 @@
#include "hyperv.h"
#include "hyperv-proto.h"
uint32_t hyperv_vp_index(X86CPU *cpu)
{
return CPU(cpu)->cpu_index;
}
X86CPU *hyperv_find_vcpu(uint32_t vp_index)
{
return X86_CPU(qemu_get_cpu(vp_index));
}
int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit)
{
CPUX86State *env = &cpu->env;
@ -72,7 +82,7 @@ static void kvm_hv_sint_ack_handler(EventNotifier *notifier)
}
}
HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint,
HvSintRoute *kvm_hv_sint_route_create(uint32_t vp_index, uint32_t sint,
HvSintAckClb sint_ack_clb)
{
HvSintRoute *sint_route;
@ -92,7 +102,7 @@ HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint,
event_notifier_set_handler(&sint_route->sint_ack_notifier,
kvm_hv_sint_ack_handler);
gsi = kvm_irqchip_add_hv_sint_route(kvm_state, vcpu_id, sint);
gsi = kvm_irqchip_add_hv_sint_route(kvm_state, vp_index, sint);
if (gsi < 0) {
goto err_gsi;
}
@ -105,7 +115,7 @@ HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint,
}
sint_route->gsi = gsi;
sint_route->sint_ack_clb = sint_ack_clb;
sint_route->vcpu_id = vcpu_id;
sint_route->vp_index = vp_index;
sint_route->sint = sint;
return sint_route;

View file

@ -23,7 +23,7 @@ typedef void (*HvSintAckClb)(HvSintRoute *sint_route);
struct HvSintRoute {
uint32_t sint;
uint32_t vcpu_id;
uint32_t vp_index;
int gsi;
EventNotifier sint_set_notifier;
EventNotifier sint_ack_notifier;
@ -32,11 +32,14 @@ struct HvSintRoute {
int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit);
HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint,
HvSintRoute *kvm_hv_sint_route_create(uint32_t vp_index, uint32_t sint,
HvSintAckClb sint_ack_clb);
void kvm_hv_sint_route_destroy(HvSintRoute *sint_route);
int kvm_hv_sint_route_set_sint(HvSintRoute *sint_route);
uint32_t hyperv_vp_index(X86CPU *cpu);
X86CPU *hyperv_find_vcpu(uint32_t vp_index);
#endif

View file

@ -40,3 +40,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
abort();
}
#endif
bool kvm_hv_vpindex_settable(void)
{
return false;
}

View file

@ -85,6 +85,7 @@ static bool has_msr_hv_hypercall;
static bool has_msr_hv_crash;
static bool has_msr_hv_reset;
static bool has_msr_hv_vpindex;
static bool hv_vpindex_settable;
static bool has_msr_hv_runtime;
static bool has_msr_hv_synic;
static bool has_msr_hv_stimer;
@ -162,6 +163,11 @@ bool kvm_enable_x2apic(void)
has_x2apic_api);
}
bool kvm_hv_vpindex_settable(void)
{
return hv_vpindex_settable;
}
static int kvm_get_tsc(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
@ -745,6 +751,37 @@ static int hyperv_handle_properties(CPUState *cs)
return 0;
}
static int hyperv_init_vcpu(X86CPU *cpu)
{
if (cpu->hyperv_vpindex && !hv_vpindex_settable) {
/*
* the kernel doesn't support setting vp_index; assert that its value
* is in sync
*/
int ret;
struct {
struct kvm_msrs info;
struct kvm_msr_entry entries[1];
} msr_data = {
.info.nmsrs = 1,
.entries[0].index = HV_X64_MSR_VP_INDEX,
};
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, &msr_data);
if (ret < 0) {
return ret;
}
assert(ret == 1);
if (msr_data.entries[0].data != hyperv_vp_index(cpu)) {
error_report("kernel's vp_index != QEMU's vp_index");
return -ENXIO;
}
}
return 0;
}
static Error *invtsc_mig_blocker;
#define KVM_MAX_CPUID_ENTRIES 100
@ -1160,6 +1197,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
has_msr_tsc_aux = false;
}
r = hyperv_init_vcpu(cpu);
if (r) {
goto fail;
}
return 0;
fail:
@ -1351,6 +1393,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
has_pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2);
#endif
hv_vpindex_settable = kvm_check_extension(s, KVM_CAP_HYPERV_VP_INDEX);
ret = kvm_get_supported_msrs(s);
if (ret < 0) {
return ret;
@ -1900,6 +1944,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
if (has_msr_hv_runtime) {
kvm_msr_entry_add(cpu, HV_X64_MSR_VP_RUNTIME, env->msr_hv_runtime);
}
if (cpu->hyperv_vpindex && hv_vpindex_settable) {
kvm_msr_entry_add(cpu, HV_X64_MSR_VP_INDEX, hyperv_vp_index(cpu));
}
if (cpu->hyperv_synic) {
int j;

View file

@ -63,4 +63,6 @@ void kvm_put_apicbase(X86CPU *cpu, uint64_t value);
bool kvm_enable_x2apic(void);
bool kvm_has_x2apic_api(void);
bool kvm_hv_vpindex_settable(void);
#endif

View file

@ -537,6 +537,7 @@ static gboolean _test_server_free(TestServer *server)
g_free(server->mig_path);
g_free(server->chr_name);
g_assert(server->bus);
qpci_free_pc(server->bus);
g_free(server);
@ -684,6 +685,7 @@ static void test_migrate(void)
g_free(cmd);
init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC);
init_virtio_dev(dest, 1u << VIRTIO_NET_F_MAC);
wait_for_fds(s);
size = get_log_size(s);
g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8));
@ -739,6 +741,7 @@ static void test_migrate(void)
read_guest_mem_server(dest);
uninit_virtio_dev(s);
uninit_virtio_dev(dest);
g_source_destroy(source);
g_source_unref(source);

View file

@ -82,11 +82,9 @@ const char *get_opt_value(const char *p, char **value)
if (*offset != '\0' && *(offset + 1) == ',') {
length++;
}
if (value) {
*value = g_renew(char, *value, capacity + length + 1);
strncpy(*value + capacity, p, length);
(*value)[capacity + length] = '\0';
}
*value = g_renew(char, *value, capacity + length + 1);
strncpy(*value + capacity, p, length);
(*value)[capacity + length] = '\0';
capacity += length;
if (*offset == '\0' ||
*(offset + 1) != ',') {