On 2017-01-19 21:11, Ralf Ramsauer wrote:
> 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;
Read and writes are synchronized by the jailhouse_lock, right?
> +
> #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;
What if ret is 0, but there would be something to read from the new
console? Or isn't that possible? Hmm, we declare the last_console
invalid on next enable. So enable will be a reset, ok.
> + } else {
> + ret = jailhouse_console_page_delta(content, user->head,
> + &miss);
> + }
>
> mutex_unlock(&jailhouse_lock);
>
>
Jan
--
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.