[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 2/4] migration/ram: Fix for ARM/ARM64 page size
From: |
Christian Pinto |
Subject: |
[Qemu-devel] [RFC PATCH 2/4] migration/ram: Fix for ARM/ARM64 page size |
Date: |
Thu, 9 Mar 2017 12:34:35 +0100 |
Architecture such as ARM use a page size of 1KB, while write protection
is done at the granularity of host pages (generally 4KB).
All addresses must always be aligned to the size of a host page.
Signed-off-by: Christian Pinto <address@hidden>
Signed-off-by: Baptiste Reynal <address@hidden>
---
migration/postcopy-ram.c | 6 +++---
migration/ram.c | 18 ++++++++++++++----
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 9c45f1059f..97382067b3 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -373,7 +373,7 @@ int postcopy_ram_prepare_discard(MigrationIncomingState
*mis)
return 0;
}
-int ram_set_pages_wp(uint64_t page_addr,
+int ram_set_pages_wp(ram_addr_t page_addr,
uint64_t size,
bool remove,
int uffd)
@@ -556,10 +556,10 @@ static void *postcopy_ram_fault_thread(void *opaque)
* will be an deadlock error.
*/
if (migration_in_setup(ms)) {
- uint64_t host = msg.arg.pagefault.address;
+ ram_addr_t host = msg.arg.pagefault.address;
host &= ~(hostpagesize - 1);
- ret = ram_set_pages_wp(host, getpagesize(), true,
+ ret = ram_set_pages_wp(host, hostpagesize, true,
us->userfault_fd);
if (ret < 0) {
error_report("Remove page's write-protect failed");
diff --git a/migration/ram.c b/migration/ram.c
index 3417c56f29..7a3b1c7ed3 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1383,14 +1383,24 @@ static int ram_find_and_save_block(QEMUFile *f, bool
last_stage,
/* For snapshot, we will remove the page write-protect here */
if (migration_in_snapshot(ms)) {
int ret;
- uint64_t host_addr = (uint64_t)(pss.block->host + pss.offset);
-
+ /*
+ * Some architectures in QEMU use a smaller memory page size
+ * with respect to the host page size. ARM as an example
+ * uses 1K memory pages, while Linux supports pages of minimum
+ * size of 4K.
+ * Userfault write protection works at the level of a host page
+ * and thus one full host page has to be protected/unprotected
+ * every time.
+ */
+ ram_addr_t host_addr = (ram_addr_t)(pss.block->host +
+ pss.offset) & (~(qemu_host_page_size - 1));
ret = ram_set_pages_wp(host_addr, getpagesize(), true,
ms->userfault_state.userfault_fd);
if (ret < 0) {
error_report("Failed to remove the write-protect for page:"
- "%"PRIx64 " length: %d, block: %s", host_addr,
- getpagesize(), pss.block->idstr);
+ "%"PRIx64 " length: %d, offset: %"PRIx64
+ ", block: %s", host_addr, getpagesize(),
+ pss.offset, pss.block->idstr);
}
}
}
--
2.11.0