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;
+ 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.
--
2.7.4
_______________________________________________
SeaBIOS mailing list
SeaBIOS@seabios.org
https://www.coreboot.org/mailman/listinfo/seabios
On Mon, 20 Feb 2017 19:56:19 -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> Reviewed-by: Igor Mammedov <imammedo@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; > + 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. _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://www.coreboot.org/mailman/listinfo/seabios
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 _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://www.coreboot.org/mailman/listinfo/seabios
© 2016 - 2025 Red Hat, Inc.