Index: pipe.c
===================================================================
--- pipe.c	(revision 3555)
+++ pipe.c	(revision 3638)
@@ -729,8 +729,8 @@
 	return 0;
 }
 
-static ssize_t xnpipe_read(struct file *file,
-			   char *buf, size_t count, loff_t *ppos)
+static ssize_t xnpipe_readv(struct file *file, const struct iovec *iovec,
+			    unsigned long nr_segs, loff_t *ppos)
 {
 	struct xnpipe_state *state = file->private_data;
 	int sigpending, err = 0;
@@ -740,9 +740,6 @@
 	ssize_t ret;
 	spl_t s;
 
-	if (!access_ok(VERIFY_WRITE, buf, count))
-		return -EFAULT;
-
 	xnlock_get_irqsave(&nklock, s);
 
 	if (!testbits(state->status, XNPIPE_KERN_CONN)) {
@@ -781,16 +778,26 @@
 	 * entirely.
 	 */
 
-	inbytes = 0;
+	ret = 0;
 
-	for (;;) {
+	for (; nr_segs--; ++iovec)
+	{
+	    char *buf = iovec->iov_base;
+	    size_t count = iovec->iov_len;
+	
+	    if (!access_ok(VERIFY_WRITE, buf, count)) {
+		    err = -EFAULT;
+		    break;
+	    }
+
+	    for (inbytes = 0; inbytes < count; ) {
 		nbytes = xnpipe_m_size(mh) - xnpipe_m_rdoff(mh);
 
 		if (nbytes + inbytes > count)
 			nbytes = count - inbytes;
 
 		if (nbytes == 0)
-			break;
+			goto cleanup;
 
 		xnlock_put_irqrestore(&nklock, s);
 		/* More data could be appended while doing this: */
@@ -802,15 +809,17 @@
 
 		if (err) {
 			err = -EFAULT;
-			break;
+			goto cleanup;
 		}
 
 		inbytes += nbytes;
 		xnpipe_m_rdoff(mh) += nbytes;
+		ret += nbytes;
+	    }
 	}
 
-	state->ionrd -= inbytes;
-	ret = inbytes;
+cleanup:
+	state->ionrd -= ret;
 
 	if (xnpipe_m_size(mh) > xnpipe_m_rdoff(mh))
 		prependq(&state->outq, &mh->link);
@@ -837,6 +846,13 @@
 	return err ? : ret;
 }
 
+static ssize_t xnpipe_read(struct file *file,
+			   char *buf, size_t count, loff_t *ppos)
+{
+	struct iovec iov = { .iov_base = buf, .iov_len = count };
+	return xnpipe_readv(file, &iov, 1, ppos);
+}
+
 static ssize_t xnpipe_write(struct file *file,
 			    const char *buf, size_t count, loff_t *ppos)
 {
@@ -1060,6 +1076,7 @@
 static struct file_operations xnpipe_fops = {
 	.owner = THIS_MODULE,
 	.read = xnpipe_read,
+	.readv = xnpipe_readv,
 	.write = xnpipe_write,
 	.poll = xnpipe_poll,
 	.ioctl = xnpipe_ioctl,
