Skip to content

Commit

Permalink
virtio: console: Prepare for writing to userspace buffers
Browse files Browse the repository at this point in the history
When ports get advertised as char devices, the buffers will come from
userspace. Equip the fill_readbuf function with the ability to write
to userspace buffers.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
Amit Shah authored and Rusty Russell committed Feb 24, 2010
1 parent 17634ba commit b766cee
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions drivers/char/virtio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,8 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count)
* Give out the data that's requested from the buffer that we have
* queued up.
*/
static ssize_t fill_readbuf(struct port *port, char *out_buf, size_t out_count)
static ssize_t fill_readbuf(struct port *port, char *out_buf, size_t out_count,
bool to_user)
{
struct port_buffer *buf;
unsigned long flags;
Expand All @@ -367,12 +368,18 @@ static ssize_t fill_readbuf(struct port *port, char *out_buf, size_t out_count)
return 0;

buf = port->inbuf;
if (out_count > buf->len - buf->offset)
out_count = buf->len - buf->offset;
out_count = min(out_count, buf->len - buf->offset);

memcpy(out_buf, buf->buf + buf->offset, out_count);
if (to_user) {
ssize_t ret;

ret = copy_to_user(out_buf, buf->buf + buf->offset, out_count);
if (ret)
return -EFAULT;
} else {
memcpy(out_buf, buf->buf + buf->offset, out_count);
}

/* Return the number of bytes actually copied */
buf->offset += out_count;

if (buf->offset == buf->len) {
Expand All @@ -388,6 +395,7 @@ static ssize_t fill_readbuf(struct port *port, char *out_buf, size_t out_count)

spin_unlock_irqrestore(&port->inbuf_lock, flags);
}
/* Return the number of bytes actually copied */
return out_count;
}

Expand Down Expand Up @@ -431,7 +439,7 @@ static int get_chars(u32 vtermno, char *buf, int count)
/* If we don't have an input queue yet, we can't get input. */
BUG_ON(!port->in_vq);

return fill_readbuf(port, buf, count);
return fill_readbuf(port, buf, count, false);
}

static void resize_console(struct port *port)
Expand Down

0 comments on commit b766cee

Please sign in to comment.