On 01/24/2017 05:12 PM, Jan Kiszka wrote:
> 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?
Yes, we're calling update_last_console() only in contexts where we
already hold the lock.

We're only reading from jailhouse_console_read() by calling either
jailhouse_console_delta() or jailhouse_console_page_delta(). This short
critical section is protected by the jailhouse_lock as well.

Everything should be fine here.
> 
>> +
>>  #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.
Yep, and again: protected by jailhouse_lock.

  Ralf
> 
>> +            } 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