On 2017-01-16 17:07, Ralf Ramsauer wrote:
> Signed-off-by: Ralf Ramsauer <[email protected]>
> ---
>  Documentation/debug-output.md |  8 +++-
>  driver/main.c                 | 89 
> +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 96 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/debug-output.md b/Documentation/debug-output.md
> index 1c11ca18..5d0610a1 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 8a4b929f..f98e63c6 100644
> --- a/driver/main.c
> +++ b/driver/main.c
> @@ -69,6 +69,10 @@ MODULE_FIRMWARE(JAILHOUSE_FW_NAME);
>  #endif
>  MODULE_VERSION(JAILHOUSE_VERSION);
>  
> +struct console_userdata {
> +     unsigned int head;
> +};
> +
>  DEFINE_MUTEX(jailhouse_lock);
>  bool jailhouse_enabled;
>  
> @@ -621,11 +625,96 @@ 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;
> +
> +     file->private_data = NULL;

Unneeded - this instance will die if you return an error, and otherwise
you overwrite it.

> +     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;
> +     if (user)

Unneeded (but add a blank line) - kfree(NULL) is allowed.

> +             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) {
> +             ret = jailhouse_console_page_delta(content, user->head, &miss);
> +             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(HZ / 10);
> +             set_current_state(TASK_UNINTERRUPTIBLE);

Wrong ordering: first set yourself uninterruptible, then schedule. Or
just used schedule_timeout_interruptible, that does this for you.

> +             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",

Should better be in some <> or [] because the note may be added to a
previous output without a line-break.

> +                            miss);
> +             user->head += miss;
> +             if (size < ret)
> +                     ret = size;
> +     } else {
> +             if (size < ret)
> +                     ret = size;
> +             user->head += ret;
> +     }
> +
> +     if (copy_to_user(out, content, ret))
> +             ret = -EFAULT;
> +
> +console_free_out:
> +     set_current_state(TASK_RUNNING);
> +     kfree(content);
> +     return ret;
> +}
> +
> +
>  static const struct file_operations jailhouse_fops = {
>       .owner = THIS_MODULE,
>       .unlocked_ioctl = jailhouse_ioctl,
>       .compat_ioctl = jailhouse_ioctl,
>       .llseek = noop_llseek,
> +     .open = jailhouse_console_open,
> +     .release = jailhouse_console_release,
> +     .read = jailhouse_console_read,
>  };
>  
>  static struct miscdevice jailhouse_misc_dev = {
> 

Jan

-- 
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux

-- 
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