From: Steve Sistare <steven.sistare@oracle.com>
To: qemu-devel@nongnu.org
Cc: "Juan Quintela" <quintela@redhat.com>,
"Peter Xu" <peterx@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Thomas Huth" <thuth@redhat.com>,
"Daniel P. Berrangé" <berrange@redhat.com>,
"Steve Sistare" <steven.sistare@oracle.com>
Subject: [PATCH V1 3/3] tests/qtest: live migration suspended state
Date: Thu, 15 Jun 2023 13:26:40 -0700 [thread overview]
Message-ID: <1686860800-34667-4-git-send-email-steven.sistare@oracle.com> (raw)
In-Reply-To: <1686860800-34667-1-git-send-email-steven.sistare@oracle.com>
Add a test case to verify that the suspended state is handled correctly in
live migration. The test suspends the src, migrates, then wakes the dest.
Add an option to suspend the src in a-b-bootblock.S, which puts the guest
in S3 state after one round of writing to memory. The option is enabled by
poking a 1 into the suspend_me word in the boot block prior to starting the
src vm. Generate symbol offsets in a-b-bootblock.h so that the suspend_me
offset is known.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
tests/migration/i386/Makefile | 5 ++--
tests/migration/i386/a-b-bootblock.S | 49 +++++++++++++++++++++++++++++++++---
tests/migration/i386/a-b-bootblock.h | 22 ++++++++++------
tests/qtest/migration-helpers.c | 2 +-
tests/qtest/migration-test.c | 31 +++++++++++++++++++++--
5 files changed, 92 insertions(+), 17 deletions(-)
diff --git a/tests/migration/i386/Makefile b/tests/migration/i386/Makefile
index 5c03241..37a72ae 100644
--- a/tests/migration/i386/Makefile
+++ b/tests/migration/i386/Makefile
@@ -4,9 +4,10 @@
.PHONY: all clean
all: a-b-bootblock.h
-a-b-bootblock.h: x86.bootsect
+a-b-bootblock.h: x86.bootsect x86.o
echo "$$__note" > header.tmp
xxd -i $< | sed -e 's/.*int.*//' >> header.tmp
+ nm x86.o | awk '{print "#define SYM_"$$3" 0x"$$1}' >> header.tmp
mv header.tmp $@
x86.bootsect: x86.boot
@@ -16,7 +17,7 @@ x86.boot: x86.o
$(CROSS_PREFIX)objcopy -O binary $< $@
x86.o: a-b-bootblock.S
- $(CROSS_PREFIX)gcc -m32 -march=i486 -c $< -o $@
+ $(CROSS_PREFIX)gcc -I.. -m32 -march=i486 -c $< -o $@
clean:
@rm -rf *.boot *.o *.bootsect
diff --git a/tests/migration/i386/a-b-bootblock.S b/tests/migration/i386/a-b-bootblock.S
index 3d464c7..63d446f 100644
--- a/tests/migration/i386/a-b-bootblock.S
+++ b/tests/migration/i386/a-b-bootblock.S
@@ -9,6 +9,21 @@
#
# Author: dgilbert@redhat.com
+#include "migration-test.h"
+
+#define ACPI_ENABLE 0xf1
+#define ACPI_PORT_SMI_CMD 0xb2
+#define ACPI_PM_BASE 0x600
+#define PM1A_CNT_OFFSET 4
+
+#define ACPI_SCI_ENABLE 0x0001
+#define ACPI_SLEEP_TYPE 0x0400
+#define ACPI_SLEEP_ENABLE 0x2000
+#define SLEEP (ACPI_SCI_ENABLE + ACPI_SLEEP_TYPE + ACPI_SLEEP_ENABLE)
+
+#define LOW_ADDR X86_TEST_MEM_START
+#define HIGH_ADDR X86_TEST_MEM_END
+#define suspended HIGH_ADDR
.code16
.org 0x7c00
@@ -41,12 +56,11 @@ start: # at 0x7c00 ?
# bl keeps a counter so we limit the output speed
mov $0, %bl
mainloop:
- # Start from 1MB
- mov $(1024*1024),%eax
+ mov $LOW_ADDR,%eax
innerloop:
incb (%eax)
add $4096,%eax
- cmp $(100*1024*1024),%eax
+ cmp $HIGH_ADDR,%eax
jl innerloop
inc %bl
@@ -57,7 +71,30 @@ innerloop:
mov $0x3f8,%dx
outb %al,%dx
- jmp mainloop
+ # should this test suspend?
+ mov (suspend_me),%eax
+ cmp $0,%eax
+ je mainloop
+
+ # are we waking after suspend? do not suspend again.
+ mov $suspended,%eax
+ mov (%eax),%eax
+ cmp $1,%eax
+ je mainloop
+
+ # enable acpi
+ mov $ACPI_ENABLE,%al
+ outb %al,$ACPI_PORT_SMI_CMD
+
+ # suspend to ram
+ mov $suspended,%eax
+ movl $1,(%eax)
+ mov $SLEEP,%ax
+ mov $(ACPI_PM_BASE + PM1A_CNT_OFFSET),%dx
+ outw %ax,%dx
+ # not reached. The wakeup causes reset and restart at 0x7c00, and we
+ # do not save and restore registers as a real kernel would do.
+
# GDT magic from old (GPLv2) Grub startup.S
.p2align 2 /* force 4-byte alignment */
@@ -83,6 +120,10 @@ gdtdesc:
.word 0x27 /* limit */
.long gdt /* addr */
+ /* test launcher can poke a 1 here to exercise suspend */
+suspend_me:
+ .int 0
+
/* I'm a bootable disk */
.org 0x7dfe
.byte 0x55
diff --git a/tests/migration/i386/a-b-bootblock.h b/tests/migration/i386/a-b-bootblock.h
index b7b0fce..b39773f 100644
--- a/tests/migration/i386/a-b-bootblock.h
+++ b/tests/migration/i386/a-b-bootblock.h
@@ -4,20 +4,20 @@
* the header and the assembler differences in your patch submission.
*/
unsigned char x86_bootsect[] = {
- 0xfa, 0x0f, 0x01, 0x16, 0x78, 0x7c, 0x66, 0xb8, 0x01, 0x00, 0x00, 0x00,
+ 0xfa, 0x0f, 0x01, 0x16, 0xa4, 0x7c, 0x66, 0xb8, 0x01, 0x00, 0x00, 0x00,
0x0f, 0x22, 0xc0, 0x66, 0xea, 0x20, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x92, 0x0c, 0x02,
0xe6, 0x92, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x8e, 0xd8, 0x66, 0xb8, 0x41,
0x00, 0x66, 0xba, 0xf8, 0x03, 0xee, 0xb3, 0x00, 0xb8, 0x00, 0x00, 0x10,
0x00, 0xfe, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x40,
0x06, 0x7c, 0xf2, 0xfe, 0xc3, 0x80, 0xe3, 0x3f, 0x75, 0xe6, 0x66, 0xb8,
- 0x42, 0x00, 0x66, 0xba, 0xf8, 0x03, 0xee, 0xeb, 0xdb, 0x8d, 0x76, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x9a, 0xcf, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00,
- 0x27, 0x00, 0x60, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x42, 0x00, 0x66, 0xba, 0xf8, 0x03, 0xee, 0xa1, 0xaa, 0x7c, 0x00, 0x00,
+ 0x83, 0xf8, 0x00, 0x74, 0xd3, 0xb8, 0x00, 0x00, 0x40, 0x06, 0x8b, 0x00,
+ 0x83, 0xf8, 0x01, 0x74, 0xc7, 0xb0, 0xf1, 0xe6, 0xb2, 0xb8, 0x00, 0x00,
+ 0x40, 0x06, 0xc7, 0x00, 0x01, 0x00, 0x00, 0x00, 0x66, 0xb8, 0x01, 0x24,
+ 0x66, 0xba, 0x04, 0x06, 0x66, 0xef, 0x66, 0x90, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00, 0x27, 0x00, 0x8c, 0x7c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -49,3 +49,9 @@ unsigned char x86_bootsect[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
};
+#define SYM_gdt 0x00007c8c
+#define SYM_gdtdesc 0x00007ca4
+#define SYM_innerloop 0x00007c3d
+#define SYM_mainloop 0x00007c38
+#define SYM_start 0x00007c00
+#define SYM_suspend_me 0x00007caa
diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c
index be00c52..433d678 100644
--- a/tests/qtest/migration-helpers.c
+++ b/tests/qtest/migration-helpers.c
@@ -28,7 +28,7 @@ bool migrate_watch_for_stop(QTestState *who, const char *name,
{
bool *seen = opaque;
- if (g_str_equal(name, "STOP")) {
+ if (g_str_equal(name, "STOP") || g_str_equal(name, "SUSPEND")) {
*seen = true;
return true;
}
diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index b0c355b..73b07b3 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -121,7 +121,7 @@ static void init_bootfile(const char *bootpath, void *content, size_t len)
/*
* Wait for some output in the serial output file,
* we get an 'A' followed by an endless string of 'B's
- * but on the destination we won't have the A.
+ * but on the destination we won't have the A (unless we enabled suspend/resume)
*/
static void wait_for_serial(const char *side)
{
@@ -507,6 +507,8 @@ typedef struct {
bool use_dirty_ring;
const char *opts_source;
const char *opts_target;
+ /* suspend the src before migrating to dest. */
+ bool suspend;
} MigrateStart;
/*
@@ -617,6 +619,8 @@ static int test_migrate_start(QTestState **from, QTestState **to,
}
}
+ x86_bootsect[SYM_suspend_me - SYM_start] = args->suspend;
+
got_src_stop = false;
got_dst_resume = false;
bootpath = g_strdup_printf("%s/bootsect", tmpfs);
@@ -1475,7 +1479,13 @@ static void test_precopy_common(MigrateCommon *args)
*/
wait_for_migration_complete(to);
- qtest_qmp_assert_success(to, "{ 'execute' : 'cont'}");
+ if (!args->start.suspend) {
+ qtest_qmp_assert_success(to, "{ 'execute' : 'cont'}");
+ }
+ }
+
+ if (args->start.suspend) {
+ qtest_qmp_assert_success(to, "{'execute': 'system_wakeup'}");
}
if (!got_dst_resume) {
@@ -1508,6 +1518,18 @@ static void test_precopy_unix_plain(void)
test_precopy_common(&args);
}
+static void test_precopy_unix_suspend(void)
+{
+ g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
+ MigrateCommon args = {
+ .listen_uri = uri,
+ .connect_uri = uri,
+ .live = true,
+ .start.suspend = true,
+ };
+
+ test_precopy_common(&args);
+}
static void test_precopy_unix_dirty_ring(void)
{
@@ -2682,6 +2704,11 @@ int main(int argc, char **argv)
module_call_init(MODULE_INIT_QOM);
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ qtest_add_func("/migration/precopy/unix/suspend",
+ test_precopy_unix_suspend);
+ }
+
if (has_uffd) {
qtest_add_func("/migration/postcopy/plain", test_postcopy);
qtest_add_func("/migration/postcopy/recovery/plain",
--
1.8.3.1
next prev parent reply other threads:[~2023-06-15 20:27 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-15 20:26 [PATCH V1 0/3] fix migration of suspended runstate Steve Sistare
2023-06-15 20:26 ` [PATCH V1 1/3] vl: start on wakeup request Steve Sistare
2023-06-15 20:26 ` [PATCH V1 2/3] migration: fix suspended runstate Steve Sistare
2023-06-20 21:46 ` Peter Xu
2023-06-21 19:15 ` Steven Sistare
2023-06-21 20:28 ` Peter Xu
2023-06-23 18:25 ` Steven Sistare
2023-06-23 19:56 ` Steven Sistare
2023-06-26 18:27 ` Peter Xu
2023-06-26 19:11 ` Peter Xu
2023-06-30 13:50 ` Steven Sistare
2023-07-26 20:18 ` Peter Xu
2023-08-14 18:53 ` Steven Sistare
2023-08-14 19:37 ` Peter Xu
2023-08-16 17:48 ` Steven Sistare
2023-08-17 18:19 ` Peter Xu
2023-08-24 20:53 ` Steven Sistare
2023-06-15 20:26 ` Steve Sistare [this message]
2023-06-21 16:45 ` [PATCH V1 3/3] tests/qtest: live migration suspended state Peter Xu
2023-06-21 19:39 ` Steven Sistare
2023-06-21 20:00 ` Peter Xu
2023-06-22 21:28 ` Steven Sistare
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1686860800-34667-4-git-send-email-steven.sistare@oracle.com \
--to=steven.sistare@oracle.com \
--cc=berrange@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).