Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20…
Browse files Browse the repository at this point in the history
…181011a' into staging

Migration pull 2018-10-11

With one bonus HMP fix.

# gpg: Signature made Thu 11 Oct 2018 20:23:12 BST
# gpg:                using RSA key 0516331EBC5BFDE7
# gpg: Good signature from "Dr. David Alan Gilbert (RH2) <dgilbert@redhat.com>"
# Primary key fingerprint: 45F5 C71B 4A0C B7FB 977A  9FA9 0516 331E BC5B FDE7

* remotes/dgilbert/tags/pull-migration-20181011a:
  migration-test: Only generate a single target architecture
  qmp, hmp: make subsystem/system-vendor identities optional
  vhost-user: Don't ask for reply on postcopy mem table set
  vhost-user: Fix userfaultfd leak
  migration: Stop postcopy fault thread before notifying
  tests/migration: Enable the migration test on s390x, too
  tests: Add migration test for aarch64

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Oct 12, 2018
2 parents 75e50c8 + 36bd9e3 commit 05b656d
Show file tree
Hide file tree
Showing 15 changed files with 531 additions and 38 deletions.
6 changes: 4 additions & 2 deletions hmp.c
Expand Up @@ -837,8 +837,10 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)

monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
dev->id->vendor, dev->id->device);
monitor_printf(mon, " PCI subsystem %04" PRIx64 ":%04" PRIx64 "\n",
dev->id->subsystem_vendor, dev->id->subsystem);
if (dev->id->has_subsystem_vendor && dev->id->has_subsystem) {
monitor_printf(mon, " PCI subsystem %04" PRIx64 ":%04" PRIx64 "\n",
dev->id->subsystem_vendor, dev->id->subsystem);
}

if (dev->has_irq) {
monitor_printf(mon, " IRQ %" PRId64 ".\n", dev->irq);
Expand Down
13 changes: 10 additions & 3 deletions hw/pci/pci.c
Expand Up @@ -1737,9 +1737,6 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
info->id = g_new0(PciDeviceId, 1);
info->id->vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
info->id->device = pci_get_word(dev->config + PCI_DEVICE_ID);
info->id->subsystem = pci_get_word(dev->config + PCI_SUBSYSTEM_ID);
info->id->subsystem_vendor =
pci_get_word(dev->config + PCI_SUBSYSTEM_VENDOR_ID);
info->regions = qmp_query_pci_regions(dev);
info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");

Expand All @@ -1752,6 +1749,16 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
if (type == PCI_HEADER_TYPE_BRIDGE) {
info->has_pci_bridge = true;
info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
} else if (type == PCI_HEADER_TYPE_NORMAL) {
info->id->has_subsystem = info->id->has_subsystem_vendor = true;
info->id->subsystem = pci_get_word(dev->config + PCI_SUBSYSTEM_ID);
info->id->subsystem_vendor =
pci_get_word(dev->config + PCI_SUBSYSTEM_VENDOR_ID);
} else if (type == PCI_HEADER_TYPE_CARDBUS) {
info->id->has_subsystem = info->id->has_subsystem_vendor = true;
info->id->subsystem = pci_get_word(dev->config + PCI_CB_SUBSYSTEM_ID);
info->id->subsystem_vendor =
pci_get_word(dev->config + PCI_CB_SUBSYSTEM_VENDOR_ID);
}

return info;
Expand Down
20 changes: 8 additions & 12 deletions hw/virtio/vhost-user.c
Expand Up @@ -374,8 +374,6 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev,
int fds[VHOST_MEMORY_MAX_NREGIONS];
int i, fd;
size_t fd_num = 0;
bool reply_supported = virtio_has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_REPLY_ACK);
VhostUserMsg msg_reply;
int region_i, msg_i;

Expand All @@ -384,10 +382,6 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev,
.hdr.flags = VHOST_USER_VERSION,
};

if (reply_supported) {
msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
}

if (u->region_rb_len < dev->mem->nregions) {
u->region_rb = g_renew(RAMBlock*, u->region_rb, dev->mem->nregions);
u->region_rb_offset = g_renew(ram_addr_t, u->region_rb_offset,
Expand Down Expand Up @@ -503,10 +497,6 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev,
return -1;
}

if (reply_supported) {
return process_message_reply(dev, &msg);
}

return 0;
}

Expand All @@ -519,8 +509,7 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
size_t fd_num = 0;
bool do_postcopy = u->postcopy_listen && u->postcopy_fd.handler;
bool reply_supported = virtio_has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_REPLY_ACK) &&
!do_postcopy;
VHOST_USER_PROTOCOL_F_REPLY_ACK);

if (do_postcopy) {
/* Postcopy has enough differences that it's best done in it's own
Expand Down Expand Up @@ -1291,6 +1280,7 @@ static int vhost_user_postcopy_end(struct vhost_dev *dev, Error **errp)
return ret;
}
postcopy_unregister_shared_ufd(&u->postcopy_fd);
close(u->postcopy_fd.fd);
u->postcopy_fd.handler = NULL;

trace_vhost_user_postcopy_end_exit();
Expand Down Expand Up @@ -1430,6 +1420,12 @@ static int vhost_user_backend_cleanup(struct vhost_dev *dev)
postcopy_remove_notifier(&u->postcopy_notifier);
u->postcopy_notifier.notify = NULL;
}
u->postcopy_listen = false;
if (u->postcopy_fd.handler) {
postcopy_unregister_shared_ufd(&u->postcopy_fd);
close(u->postcopy_fd.fd);
u->postcopy_fd.handler = NULL;
}
if (u->slave_fd >= 0) {
qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL);
close(u->slave_fd);
Expand Down
11 changes: 6 additions & 5 deletions migration/postcopy-ram.c
Expand Up @@ -533,6 +533,12 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
if (mis->have_fault_thread) {
Error *local_err = NULL;

/* Let the fault thread quit */
atomic_set(&mis->fault_thread_quit, 1);
postcopy_fault_thread_notify(mis);
trace_postcopy_ram_incoming_cleanup_join();
qemu_thread_join(&mis->fault_thread);

if (postcopy_notify(POSTCOPY_NOTIFY_INBOUND_END, &local_err)) {
error_report_err(local_err);
return -1;
Expand All @@ -541,11 +547,6 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
if (qemu_ram_foreach_migratable_block(cleanup_range, mis)) {
return -1;
}
/* Let the fault thread quit */
atomic_set(&mis->fault_thread_quit, 1);
postcopy_fault_thread_notify(mis);
trace_postcopy_ram_incoming_cleanup_join();
qemu_thread_join(&mis->fault_thread);

trace_postcopy_ram_incoming_cleanup_closeuf();
close(mis->userfault_fd);
Expand Down
4 changes: 2 additions & 2 deletions qapi/misc.json
Expand Up @@ -839,8 +839,8 @@
# Since: 2.4
##
{ 'struct': 'PciDeviceId',
'data': {'device': 'int', 'vendor': 'int', 'subsystem': 'int',
'subsystem-vendor': 'int'} }
'data': {'device': 'int', 'vendor': 'int', '*subsystem': 'int',
'*subsystem-vendor': 'int'} }

##
# @PciDeviceInfo:
Expand Down
2 changes: 2 additions & 0 deletions tests/Makefile.include
Expand Up @@ -402,6 +402,7 @@ check-qtest-arm-y += tests/hexloader-test$(EXESUF)
check-qtest-aarch64-y = tests/numa-test$(EXESUF)
check-qtest-aarch64-$(CONFIG_SDHCI) += tests/sdhci-test$(EXESUF)
check-qtest-aarch64-y += tests/boot-serial-test$(EXESUF)
check-qtest-aarch64-y += tests/migration-test$(EXESUF)

check-qtest-microblazeel-y = $(check-qtest-microblaze-y)

Expand All @@ -415,6 +416,7 @@ check-qtest-s390x-$(CONFIG_POSIX) += tests/test-filter-redirector$(EXESUF)
check-qtest-s390x-y += tests/drive_del-test$(EXESUF)
check-qtest-s390x-y += tests/virtio-ccw-test$(EXESUF)
check-qtest-s390x-y += tests/cpu-plug-test$(EXESUF)
check-qtest-s390x-y += tests/migration-test$(EXESUF)

check-qtest-generic-y += tests/machine-none-test$(EXESUF)
check-qtest-generic-y += tests/qom-test$(EXESUF)
Expand Down
51 changes: 47 additions & 4 deletions tests/migration-test.c
Expand Up @@ -86,12 +86,24 @@ static const char *tmpfs;
* repeatedly. It outputs a 'B' at a fixed rate while it's still running.
*/
#include "tests/migration/i386/a-b-bootblock.h"
#include "tests/migration/aarch64/a-b-kernel.h"

static void init_bootfile_x86(const char *bootpath)
static void init_bootfile(const char *bootpath, void *content)
{
FILE *bootfile = fopen(bootpath, "wb");

g_assert_cmpint(fwrite(x86_bootsect, 512, 1, bootfile), ==, 1);
g_assert_cmpint(fwrite(content, 512, 1, bootfile), ==, 1);
fclose(bootfile);
}

#include "tests/migration/s390x/a-b-bios.h"

static void init_bootfile_s390x(const char *bootpath)
{
FILE *bootfile = fopen(bootpath, "wb");
size_t len = sizeof(s390x_elf);

g_assert_cmpint(fwrite(s390x_elf, len, 1, bootfile), ==, 1);
fclose(bootfile);
}

Expand Down Expand Up @@ -428,7 +440,7 @@ static int test_migrate_start(QTestState **from, QTestState **to,
got_stop = false;

if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
init_bootfile_x86(bootpath);
init_bootfile(bootpath, x86_bootsect);
cmd_src = g_strdup_printf("-machine accel=%s -m 150M"
" -name source,debug-threads=on"
" -serial file:%s/src_serial"
Expand All @@ -442,6 +454,19 @@ static int test_migrate_start(QTestState **from, QTestState **to,
accel, tmpfs, bootpath, uri);
start_address = X86_TEST_MEM_START;
end_address = X86_TEST_MEM_END;
} else if (g_str_equal(arch, "s390x")) {
init_bootfile_s390x(bootpath);
cmd_src = g_strdup_printf("-machine accel=%s -m 128M"
" -name source,debug-threads=on"
" -serial file:%s/src_serial -bios %s",
accel, tmpfs, bootpath);
cmd_dst = g_strdup_printf("-machine accel=%s -m 128M"
" -name target,debug-threads=on"
" -serial file:%s/dest_serial -bios %s"
" -incoming %s",
accel, tmpfs, bootpath, uri);
start_address = S390_TEST_MEM_START;
end_address = S390_TEST_MEM_END;
} else if (strcmp(arch, "ppc64") == 0) {
cmd_src = g_strdup_printf("-machine accel=%s -m 256M -nodefaults"
" -name source,debug-threads=on"
Expand All @@ -459,6 +484,24 @@ static int test_migrate_start(QTestState **from, QTestState **to,

start_address = PPC_TEST_MEM_START;
end_address = PPC_TEST_MEM_END;
} else if (strcmp(arch, "aarch64") == 0) {
init_bootfile(bootpath, aarch64_kernel);
cmd_src = g_strdup_printf("-machine virt,accel=%s,gic-version=max "
"-name vmsource,debug-threads=on -cpu max "
"-m 150M -serial file:%s/src_serial "
"-kernel %s ",
accel, tmpfs, bootpath);
cmd_dst = g_strdup_printf("-machine virt,accel=%s,gic-version=max "
"-name vmdest,debug-threads=on -cpu max "
"-m 150M -serial file:%s/dest_serial "
"-kernel %s "
"-incoming %s ",
accel, tmpfs, bootpath, uri);

start_address = ARM_TEST_MEM_START;
end_address = ARM_TEST_MEM_END;

g_assert(sizeof(aarch64_kernel) <= ARM_TEST_MAX_KERNEL_SIZE);
} else {
g_assert_not_reached();
}
Expand Down Expand Up @@ -545,7 +588,7 @@ static void test_deprecated(void)
{
QTestState *from;

from = qtest_start("");
from = qtest_start("-machine none");

deprecated_set_downtime(from, 0.12345);
deprecated_set_speed(from, 12345);
Expand Down
25 changes: 15 additions & 10 deletions tests/migration/Makefile
Expand Up @@ -5,10 +5,23 @@
# See the COPYING file in the top-level directory.
#

TARGET_LIST = i386
TARGET_LIST = i386 aarch64 s390x

SRC_PATH = ../..

.PHONY: help $(TARGET_LIST)
help:
@echo "Create migration guest includes. We generate a binary."
@echo "And then convert that binary to an include file that can be"
@echo "run in a guest."
@echo "Possible operations are:"
@echo
@echo " $(MAKE) clean Remove all intermediate files"
@echo " $(MAKE) target Generate for that target"
@echo " $(MAKE) CROSS_PREFIX=... target"
@echo " Cross-compile than target"
@echo " Possible targets are: $(TARGET_LIST)"

override define __note
/* This file is automatically generated from the assembly file in
* tests/migration/$@. Edit that file and then run "make all"
Expand All @@ -18,16 +31,8 @@ override define __note
endef
export __note

find-arch-cross-cc = $(lastword $(shell grep -h "CROSS_CC_GUEST=" $(wildcard $(SRC_PATH)/$(patsubst i386,*86*,$(1))-softmmu/config-target.mak) /dev/null))
parse-cross-prefix = $(subst gcc,,$(patsubst cc,gcc,$(patsubst CROSS_CC_GUEST="%",%,$(call find-arch-cross-cc,$(1)))))
gen-cross-prefix = $(patsubst %-,CROSS_PREFIX=%-,$(call parse-cross-prefix,$(1)))

.PHONY: all $(TARGET_LIST)

all: $(TARGET_LIST)

$(TARGET_LIST):
$(MAKE) -C $@ $(call gen-cross-prefix,$@)
$(MAKE) CROSS_PREFIX=$(CROSS_PREFIX) -C $@

clean:
for target in $(TARGET_LIST); do \
Expand Down
18 changes: 18 additions & 0 deletions tests/migration/aarch64/Makefile
@@ -0,0 +1,18 @@
# To specify cross compiler prefix, use CROSS_PREFIX=
# $ make CROSS_PREFIX=aarch64-linux-gnu-

.PHONY: all clean
all: a-b-kernel.h

a-b-kernel.h: aarch64.kernel
echo "$$__note" > $@
xxd -i $< | sed -e 's/.*int.*//' >> $@

aarch64.kernel: aarch64.elf
$(CROSS_PREFIX)objcopy -O binary $< $@

aarch64.elf: a-b-kernel.S
$(CROSS_PREFIX)gcc -o $@ -nostdlib -Wl,--build-id=none $<

clean:
$(RM) *.kernel *.elf
75 changes: 75 additions & 0 deletions tests/migration/aarch64/a-b-kernel.S
@@ -0,0 +1,75 @@
#
# Copyright (c) 2018 Red Hat, Inc. and/or its affiliates
#
# Author:
# Wei Huang <wei@redhat.com>
#
# This work is licensed under the terms of the GNU GPL, version 2 or later.
# See the COPYING file in the top-level directory.
#
# Note: Please make sure the compiler compiles the assembly code below with
# pc-relative address. Also the branch instructions should use relative
# addresses only.

#include "../migration-test.h"

.section .text

.globl _start

_start:
/* disable MMU to use phys mem address */
mrs x0, sctlr_el1
bic x0, x0, #(1<<0)
msr sctlr_el1, x0
isb

/* traverse test memory region */
mov x0, #ARM_TEST_MEM_START
mov x1, #ARM_TEST_MEM_END

/* output char 'A' to PL011 */
mov w3, 'A'
mov x2, #ARM_MACH_VIRT_UART
strb w3, [x2]

/* clean up memory */
mov w3, #0
mov x4, x0
clean:
strb w3, [x4]
add x4, x4, #TEST_MEM_PAGE_SIZE
cmp x4, x1
ble clean

/* w5 keeps a counter so we can limit the output speed */
mov w5, #0

/* main body */
mainloop:
mov x4, x0

innerloop:
/* increment the first byte of each page by 1 */
ldrb w3, [x4]
add w3, w3, #1
and w3, w3, #0xff
strb w3, [x4]

/* make sure QEMU user space can see consistent data as MMU is off */
dc civac, x4

add x4, x4, #TEST_MEM_PAGE_SIZE
cmp x4, x1
blt innerloop

add w5, w5, #1
and w5, w5, #0xff
cmp w5, #0
bne mainloop

/* output char 'B' to PL011 */
mov w3, 'B'
strb w3, [x2]

b mainloop

0 comments on commit 05b656d

Please sign in to comment.