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 | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/driver/main.c b/driver/main.c index 4eade5724d..439ff9b1b2 100644 --- a/driver/main.c +++ b/driver/main.c @@ -73,6 +73,7 @@ MODULE_VERSION(JAILHOUSE_VERSION); struct console_userdata { unsigned int head; + unsigned int last_console_id; }; DEFINE_MUTEX(jailhouse_lock); @@ -86,6 +87,24 @@ static int error_code; static struct jailhouse_console* volatile console_page; static bool console_available; +/* last_console contains three members: + * - valid: indicates if content in the page member is present + * - id: hint for the consumer if it already consumed the content + * - page: actual content + * + * Those members are updated in following cases: + * - on disabling the hypervisor to print last messages + * - on failures when enabling the hypervisor + * + * We need this structure, as in those cases the hypervisor memory gets + * unmapped. + */ +static struct { + bool valid; + unsigned int id; + struct jailhouse_console page; +} last_console; + #ifdef CONFIG_X86 bool jailhouse_use_vmcall; @@ -116,6 +135,16 @@ static void copy_console_page(struct jailhouse_console *dst) } while (console_page->tail != tail || console_page->lock); } +static inline void update_last_console(void) +{ + if (!console_available) + return; + + copy_console_page(&last_console.page); + last_console.id++; + last_console.valid = true; +} + static long get_max_cpus(u32 cpu_set_size, const struct jailhouse_system __user *system_config) { @@ -371,6 +400,7 @@ static int jailhouse_cmd_enable(struct jailhouse_system __user *arg) console_page = (struct jailhouse_console*) (hypervisor_mem + header->console_page); + last_console.valid = false; /* Copy hypervisor's binary image at beginning of the memory region * and clear the rest to zero. */ @@ -472,6 +502,7 @@ static int jailhouse_cmd_enable(struct jailhouse_system __user *arg) return 0; error_free_cell: + update_last_console(); jailhouse_cell_delete_root(); error_unmap: @@ -571,6 +602,8 @@ static int jailhouse_cmd_disable(void) if (err) goto unlock_out; + update_last_console(); + vunmap(hypervisor_mem); jailhouse_cell_delete_root(); @@ -661,7 +694,18 @@ static ssize_t jailhouse_console_read(struct file *file, char __user *out, goto console_free_out; } - ret = jailhouse_console_page_delta(content, user->head, &miss); + if (last_console.id != user->last_console_id && + last_console.valid) { + ret = jailhouse_console_delta(&last_console.page, + content, user->head, + &miss); + if (!ret) + user->last_console_id = + last_console.id; + } else { + ret = jailhouse_console_page_delta(content, user->head, + &miss); + } mutex_unlock(&jailhouse_lock); -- 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.
