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.

Reply via email to