On Mon, Feb 20, 2017 at 07:56:19PM -0800, ben@skyportsystems.com wrote:
From: Ben Warren ben@skyportsystems.com
Any pointers to BIOS-allocated memory that were written back to QEMU fw_cfg files are replayed when resuming from S3 sleep.
Signed-off-by: Ben Warren ben@skyportsystems.com Reviewed-by: Laszlo Ersek lersek@redhat.com
src/fw/romfile_loader.c | 33 +++++++++++++++++++++++++++++++++ src/fw/romfile_loader.h | 2 ++ src/resume.c | 4 ++++ 3 files changed, 39 insertions(+)
diff --git a/src/fw/romfile_loader.c b/src/fw/romfile_loader.c index 30e7b58..14bc908 100644 --- a/src/fw/romfile_loader.c +++ b/src/fw/romfile_loader.c @@ -4,6 +4,7 @@ #include "string.h" // strcmp #include "romfile.h" // struct romfile_s #include "malloc.h" // Zone*, _malloc +#include "list.h" // struct hlist_node #include "output.h" // warn_* #include "paravirt.h" // qemu_cfg_write_file
@@ -16,6 +17,16 @@ struct romfile_loader_files { struct romfile_loader_file files[]; };
+// Data structures for storing "write pointer" entries for possible replay +struct romfile_wr_pointer_entry {
- u64 pointer;
- u32 offset;
- u16 key;
- u8 ptr_size;
- struct hlist_node node;
+}; +static struct hlist_head romfile_pointer_list;
static struct romfile_loader_file * romfile_loader_find(const char *name, struct romfile_loader_files *files) @@ -29,6 +40,19 @@ romfile_loader_find(const char *name, return NULL; }
+// Replay "write pointer" entries back to QEMU +void romfile_fw_cfg_resume(void) +{
- if (!CONFIG_QEMU)
return;
- struct romfile_wr_pointer_entry *entry;
- hlist_for_each_entry(entry, &romfile_pointer_list, node) {
qemu_cfg_write_file_simple(&entry->pointer, entry->key,
entry->offset, entry->ptr_size);
- }
+}
static void romfile_loader_allocate(struct romfile_loader_entry_s *entry, struct romfile_loader_files *files) { @@ -163,6 +187,15 @@ static void romfile_loader_write_pointer(struct romfile_loader_entry_s *entry, entry->wr_pointer.size) != entry->wr_pointer.size) { goto err; }
- /* Store the info so it can replayed later if necessary */
- struct romfile_wr_pointer_entry *store = malloc_high(sizeof(*store));
- store->pointer = pointer;
I missed this in my earlier review - it's necessary to always check the return of malloc() in seabios. (Writing to NULL changes memory at address 0 which is shared with the 16bit interrupt table.) I fixed it upon commit.
-Kevin