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.