On 2017-01-24 17:54, Ralf Ramsauer wrote:
> On 01/24/2017 05:04 PM, Jan Kiszka wrote:
>> On 2017-01-19 21:11, Ralf Ramsauer wrote:
>>> Signed-off-by: Ralf Ramsauer <[email protected]>
>>> ---
>>> Documentation/debug-output.md | 8 +++-
>>> driver/main.c | 97
>>> +++++++++++++++++++++++++++++++++++++++++++
>>> 2 files changed, 104 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/debug-output.md b/Documentation/debug-output.md
>>> index 1c11ca180a..5d0610a154 100644
>>> --- a/Documentation/debug-output.md
>>> +++ b/Documentation/debug-output.md
>>> @@ -89,7 +89,13 @@ Hypervisor Console via sysfs
>>>
>>> If the debug console of root cell has the flag JAILHOUSE_CON2_TYPE_ROOTPAGE
>>> set, the hypervisor console is available through
>>> -/sys/devices/jailhouse/console.
>>> +/sys/devices/jailhouse/console. Continuous reading of the hypervisor
>>> console
>>> +is available through /dev/jailhouse.
>>> +
>>> +Example
>>> +```
>>> +cat /dev/jailhouse
>>> +```
>>>
>>> Inmates
>>> -------
>>> diff --git a/driver/main.c b/driver/main.c
>>> index 2a86842448..4eade5724d 100644
>>> --- a/driver/main.c
>>> +++ b/driver/main.c
>>> @@ -71,6 +71,10 @@ MODULE_FIRMWARE(JAILHOUSE_FW_NAME);
>>> #endif
>>> MODULE_VERSION(JAILHOUSE_VERSION);
>>>
>>> +struct console_userdata {
>>
>> How about "console_state"?
>>
>>> + unsigned int head;
>>> +};
>>> +
>>> DEFINE_MUTEX(jailhouse_lock);
>>> bool jailhouse_enabled;
>>>
>>> @@ -616,11 +620,104 @@ static long jailhouse_ioctl(struct file *file,
>>> unsigned int ioctl,
>>> return err;
>>> }
>>>
>>> +static int jailhouse_console_open(struct inode *inode, struct file *file)
>>> +{
>>> + struct console_userdata *user;
>>> +
>>> + user = kzalloc(sizeof(struct console_userdata), GFP_KERNEL);
>>> + if (!user)
>>> + return -ENOMEM;
>>> +
>>> + file->private_data = user;
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int jailhouse_console_release(struct inode *inode, struct file
>>> *file)
>>> +{
>>> + struct console_userdata *user = file->private_data;
>>> +
>>> + kfree(user);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static ssize_t jailhouse_console_read(struct file *file, char __user *out,
>>> + size_t size, loff_t *off)
>>> +{
>>> + struct console_userdata *user = file->private_data;
>>> + char *content;
>>> + unsigned int miss;
>>> + int ret;
>>> +
>>> + content = kmalloc(sizeof(console_page->content), GFP_KERNEL);
>>> + if (content == NULL)
>>> + return -ENOMEM;
>>> +
>>> + /* wait for new data */
>>> + while (1) {
>>> + if (mutex_lock_interruptible(&jailhouse_lock) != 0) {
>>> + ret = -EINTR;
>>> + goto console_free_out;
>>> + }
>>> +
>>> + ret = jailhouse_console_page_delta(content, user->head, &miss);
>>> +
>>> + mutex_unlock(&jailhouse_lock);
>>> +
>>> + if ((!ret || ret == -EAGAIN) && file->f_flags & O_NONBLOCK)
>>> + goto console_free_out;
>>> +
>>> + if (ret == -EAGAIN)
>>> + /* Reset the user head, if jailhouse is not enabled. We
>>> + * have to do this, as jailhouse might be reenabled and
>>> + * the file handle was kept open in the meanwhile */
>>> + user->head = 0;
>>> + else if (ret < 0)
>>> + goto console_free_out;
>>> + else if (ret)
>>> + break;
>>> +
>>> + schedule_timeout_uninterruptible(HZ / 10);
>>> + if (signal_pending(current)) {
>>> + ret = -EINTR;
>>> + goto console_free_out;
>>> + }
>>> + }
>>> +
>>> + if (miss) {
>>> + /* If we missed anything, warn user. We will dump the actual
>>> + * content in the next call. */
>>> + ret = snprintf(content, sizeof(console_page->content),
>>> + "<NOTE: missing %u byte console log>\n",
>>
>> "missed %u bytes of console log"
> Without brackets and without \n? Didn't you propose brackets?
I just meant to adjust the message text, not the formatting.
>
>>
>>> + miss);
>>> + user->head += miss;
>>> + if (size < ret)
>>> + ret = size;
>>
>> Why is user->head only update by "miss" here? ...
> In this round we're only going to return 'missed %u byte console log' to
> userspace and forward the head to the latest valid position.
>
> Rest of the content is caught in the next round, right afterwards.
> Otherwise we have a significant amount of error checking and rewinding
> and string composition, if we don't want to loose any content.
OK, now I see.
>>
>>> + } else {
>>> + if (size < ret)
>>> + ret = size;
>>> + user->head += ret;
>>
>> ...And shouldn't the last line be pulled out and executed
>> unconditionally? Actually, that would allow to pull the "if size < ret"
>> as well.
> No, in case of misses, we don't want to increase the head by the length
> of the 'missed %u byte console log' string.
>
> "user->head += ret" forwards the head by the amount of bytes that were
> successfully read from the ring buffer and fit into userspace buffer.
>
>
> "user->head += miss" forwards the head to the next valid byte inside the
> ringbuffer, that will be caught in the next round. In this case, ret
> countains the number of bytes that are returned by the function and
> represent the length of the 'missing foo bytes' message.
Makes sense, thanks.
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.