This allows us to dump messages if the hypervisor failed to start or the
last few messages after the hypervisor was disabled. This needs some
special treatment, as the hypervisor_memory region is unmapped after
failures.

Hook into disable an failure paths and copy the page to a dedicated
variable. Indicate with a boolean flag that data is present.

Signed-off-by: Ralf Ramsauer <[email protected]>
---
 driver/main.c | 40 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/driver/main.c b/driver/main.c
index f98e63c6..807514bc 100644
--- a/driver/main.c
+++ b/driver/main.c
@@ -84,6 +84,16 @@ static int error_code;
 static struct jailhouse_console *console_page;
 static bool console_available;
 
+/* dump_last_console_page will be true in two cases:
+ *   - the jailhouse console page when disabling the hypervisor
+ *   - the jailhouse console page when enabling the hypervisor fails
+ *
+ * In these cases, we must copy the console_page to last_console_page before
+ * the hypervisor_mem region is unmapped.
+ */
+static bool dump_last_console_page;
+static struct jailhouse_console last_console_page;
+
 #ifdef CONFIG_X86
 bool jailhouse_use_vmcall;
 
@@ -298,6 +308,9 @@ static int jailhouse_cmd_enable(struct jailhouse_system 
__user *arg)
        long max_cpus;
        int err;
 
+       /* unset the dump_last_console_page to drop pending content */
+       dump_last_console_page = false;
+
        fw_name = jailhouse_get_fw_name();
        if (!fw_name) {
                pr_err("jailhouse: Missing or unsupported HVM technology\n");
@@ -477,6 +490,10 @@ static int jailhouse_cmd_enable(struct jailhouse_system 
__user *arg)
        return 0;
 
 error_free_cell:
+       if (console_available) {
+               copy_console_page(&last_console_page);
+               dump_last_console_page = true;
+       }
        jailhouse_cell_delete_root();
 
 error_unmap:
@@ -576,6 +593,11 @@ static int jailhouse_cmd_disable(void)
        if (err)
                goto unlock_out;
 
+       if (console_available) {
+               copy_console_page(&last_console_page);
+               dump_last_console_page = true;
+       }
+
        vunmap(hypervisor_mem);
 
        jailhouse_cell_delete_root();
@@ -660,9 +682,21 @@ static ssize_t jailhouse_console_read(struct file *file, 
char __user *out,
 
        /* wait for new data */
        while (1) {
-               ret = jailhouse_console_page_delta(content, user->head, &miss);
-               if ((!ret || ret == -EAGAIN) && file->f_flags & O_NONBLOCK)
-                       goto console_free_out;
+               if (dump_last_console_page) {
+                       ret = jailhouse_console_delta(&last_console_page,
+                                                     content, user->head,
+                                                     &miss);
+                       if (ret == 0) {
+                               dump_last_console_page = false;
+                               goto console_free_out;
+                       }
+               } else {
+                       ret = jailhouse_console_page_delta(content, user->head,
+                                                          &miss);
+                       if ((!ret || ret == -EAGAIN) &&
+                           file->f_flags & O_NONBLOCK)
+                               goto console_free_out;
+               }
 
                if (ret == -EAGAIN)
                        /* Reset the user head, if jailhouse is not enabled. We
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to