aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Warren <ben@skyportsystems.com>2017-02-20 19:56:19 -0800
committerGerd Hoffmann <kraxel@redhat.com>2017-02-24 15:01:20 +0100
commit5f4c7b13cdf9c450eb55645f4362ea58fa61b79b (patch)
tree1058baa5db03e2728f5ff908b49f6949fb6f61c9
parentc45ca702322e6ffa030aca54ca131b264b5cec85 (diff)
downloadseabios-5f4c7b13cdf9c450eb55645f4362ea58fa61b79b.zip
seabios-5f4c7b13cdf9c450eb55645f4362ea58fa61b79b.tar.gz
seabios-5f4c7b13cdf9c450eb55645f4362ea58fa61b79b.tar.bz2
QEMU fw_cfg: Write fw_cfg back on S3 resumerel-1.10.2
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> Reviewed-by: Igor Mammedov <imammedo@redhat.com> Signed-off-by: Kevin O'Connor <kevin@koconnor.net> (cherry picked from commit 8f598a4641f98cf503653f80c779793d91c95a84)
-rw-r--r--src/fw/romfile_loader.c37
-rw-r--r--src/fw/romfile_loader.h2
-rw-r--r--src/resume.c4
3 files changed, 43 insertions, 0 deletions
diff --git a/src/fw/romfile_loader.c b/src/fw/romfile_loader.c
index 30e7b58..18476e2 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,19 @@ 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));
+ if (!store) {
+ warn_noalloc();
+ return;
+ }
+ store->pointer = pointer;
+ store->key = qemu_get_romfile_key(dest_file);
+ store->offset = dst_offset;
+ store->ptr_size = entry->wr_pointer.size;
+ hlist_add_head(&store->node, &romfile_pointer_list);
+
return;
err:
warn_internalerror();
diff --git a/src/fw/romfile_loader.h b/src/fw/romfile_loader.h
index 4dc50ab..fcd4ab2 100644
--- a/src/fw/romfile_loader.h
+++ b/src/fw/romfile_loader.h
@@ -86,4 +86,6 @@ enum {
int romfile_loader_execute(const char *name);
+void romfile_fw_cfg_resume(void);
+
#endif
diff --git a/src/resume.c b/src/resume.c
index e67cfce..99fa34f 100644
--- a/src/resume.c
+++ b/src/resume.c
@@ -17,6 +17,7 @@
#include "string.h" // memset
#include "util.h" // dma_setup
#include "tcgbios.h" // tpm_s3_resume
+#include "fw/romfile_loader.h" // romfile_fw_cfg_resume
// Handler for post calls that look like a resume.
void VISIBLE16
@@ -105,6 +106,9 @@ s3_resume(void)
tpm_s3_resume();
s3_resume_vga();
+ /* Replay any fw_cfg entries that go back to the host */
+ romfile_fw_cfg_resume();
+
make_bios_readonly();
// Invoke the resume vector.