diff --git a/hw/9p.h b/hw/9p.h
new file mode 100644
index 0000000..f0ff45b
--- /dev/null
+++ b/hw/9p.h
@@ -0,0 +1,26 @@
+/*
+ * Virtio 9p
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ *  Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_9P_H
+#define QEMU_9P_H
+
+#include <stdbool.h>
+
+typedef struct V9fsConf
+{
+    char *share_path;
+    /* tag name for the device */
+    char *tag;
+} V9fsConf;
+
+#endif
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index dca6175..4dd6b22 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -22,22 +22,20 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
-static const char *base_path;
-
-static const char *rpath(const char *path)
+static const char *rpath(V9fsState *s, const char *path)
 {
     /* FIXME: so wrong... */
     static char buffer[4096];
-    snprintf(buffer, sizeof(buffer), "%s/%s", base_path, path);
+    snprintf(buffer, sizeof(buffer), "%s/%s", s->fs_root, path);
     return buffer;
 }
 
-static int local_lstat(void *opaque, const char *path, struct stat *stbuf)
+static int local_lstat(V9fsState *s, const char *path, struct stat *stbuf)
 {
-    return lstat(rpath(path), stbuf);
+    return lstat(rpath(s, path), stbuf);
 }
 
-static int local_setuid(void *opaque, uid_t uid)
+static int local_setuid(V9fsState *s, uid_t uid)
 {
     struct passwd *pw;
     gid_t groups[33];
@@ -72,86 +70,86 @@ static int local_setuid(void *opaque, uid_t uid)
     return 0;
 }
 
-static ssize_t local_readlink(void *opaque, const char *path,
-                                char *buf, size_t bufsz)
+static ssize_t local_readlink(V9fsState *s, const char *path,
+			      char *buf, size_t bufsz)
 {
-    return readlink(rpath(path), buf, bufsz);
+    return readlink(rpath(s, path), buf, bufsz);
 }
 
-static int local_close(void *opaque, int fd)
+static int local_close(V9fsState *s, int fd)
 {
     return close(fd);
 }
 
-static int local_closedir(void *opaque, DIR *dir)
+static int local_closedir(V9fsState *s, DIR *dir)
 {
     return closedir(dir);
 }
 
-static int local_open(void *opaque, const char *path, int flags)
+static int local_open(V9fsState *s, const char *path, int flags)
 {
-    return open(rpath(path), flags);
+    return open(rpath(s, path), flags);
 }
 
-static DIR *local_opendir(void *opaque, const char *path)
+static DIR *local_opendir(V9fsState *s, const char *path)
 {
-    return opendir(rpath(path));
+    return opendir(rpath(s, path));
 }
 
-static void local_rewinddir(void *opaque, DIR *dir)
+static void local_rewinddir(V9fsState *s, DIR *dir)
 {
     return rewinddir(dir);
 }
 
-static off_t local_telldir(void *opaque, DIR *dir)
+static off_t local_telldir(V9fsState *s, DIR *dir)
 {
     return telldir(dir);
 }
 
-static struct dirent *local_readdir(void *opaque, DIR *dir)
+static struct dirent *local_readdir(V9fsState *s, DIR *dir)
 {
     return readdir(dir);
 }
 
-static void local_seekdir(void *opaque, DIR *dir, off_t off)
+static void local_seekdir(V9fsState *s, DIR *dir, off_t off)
 {
     return seekdir(dir, off);
 }
 
-static ssize_t local_readv(void *opaque, int fd, const struct iovec *iov,
+static ssize_t local_readv(V9fsState *s, int fd, const struct iovec *iov,
 			   int iovcnt)
 {
     return readv(fd, iov, iovcnt);
 }
 
-static off_t local_lseek(void *opaque, int fd, off_t offset, int whence)
+static off_t local_lseek(V9fsState *s, int fd, off_t offset, int whence)
 {
     return lseek(fd, offset, whence);
 }
 
-static ssize_t local_writev(void *opaque, int fd, const struct iovec *iov,
+static ssize_t local_writev(V9fsState *s, int fd, const struct iovec *iov,
 			    int iovcnt)
 {
     return writev(fd, iov, iovcnt);
 }
 
-static int local_chmod(void *opaque, const char *path, mode_t mode)
+static int local_chmod(V9fsState *s, const char *path, mode_t mode)
 {
-    return chmod(rpath(path), mode);
+    return chmod(rpath(s, path), mode);
 }
 
-static int local_mknod(void *opaque, const char *path, mode_t mode, dev_t dev)
+static int local_mknod(V9fsState *s, const char *path, mode_t mode, dev_t dev)
 {
-    return mknod(rpath(path), mode, dev);
+    return mknod(rpath(s, path), mode, dev);
 }
 
-static int local_mksock(void *opaque, const char *path)
+static int local_mksock(V9fsState *s2, const char *path)
 {
     struct sockaddr_un addr;
     int s;
 
     addr.sun_family = AF_UNIX;
-    snprintf(addr.sun_path, 108, "%s", rpath(path));
+    snprintf(addr.sun_path, 108, "%s", rpath(s2, path));
 
     s = socket(PF_UNIX, SOCK_STREAM, 0);
     if (s == -1)
@@ -166,36 +164,36 @@ static int local_mksock(void *opaque, const char *path)
     return 0;
 }
 
-static int local_mkdir(void *opaque, const char *path, mode_t mode)
+static int local_mkdir(V9fsState *s, const char *path, mode_t mode)
 {
-    return mkdir(rpath(path), mode);
+    return mkdir(rpath(s, path), mode);
 }
 
-static int local_fstat(void *opaque, int fd, struct stat *stbuf)
+static int local_fstat(V9fsState *s, int fd, struct stat *stbuf)
 {
     return fstat(fd, stbuf);
 }
 
-static int local_open2(void *opaque, const char *path, int flags, mode_t mode)
+static int local_open2(V9fsState *s, const char *path, int flags, mode_t mode)
 {
-    return open(rpath(path), flags, mode);
+    return open(rpath(s, path), flags, mode);
 }
 
-static int local_symlink(void *opaque, const char *oldpath,
+static int local_symlink(V9fsState *s, const char *oldpath,
 			 const char *newpath)
 {
-    return symlink(oldpath, rpath(newpath));
+    return symlink(oldpath, rpath(s, newpath));
 }
 
-static int local_link(void *opaque, const char *oldpath, const char *newpath)
+static int local_link(V9fsState *s, const char *oldpath, const char *newpath)
 {
-    char *tmp = qemu_strdup(rpath(oldpath));
+    char *tmp = qemu_strdup(rpath(s, oldpath));
     int err, serrno = 0;
 
     if (tmp == NULL)
 	return -ENOMEM;
 
-    err = link(tmp, rpath(newpath));
+    err = link(tmp, rpath(s, newpath));
     if (err == -1)
 	serrno = errno;
 
@@ -207,22 +205,22 @@ static int local_link(void *opaque, const char *oldpath, const char *newpath)
     return err;
 }
 
-static int local_truncate(void *opaque, const char *path, off_t size)
+static int local_truncate(V9fsState *s, const char *path, off_t size)
 {
-    return truncate(rpath(path), size);
+    return truncate(rpath(s, path), size);
 }
 
-static int local_rename(void *opaque, const char *oldpath,
+static int local_rename(V9fsState *s, const char *oldpath,
 			const char *newpath)
 {
     char *tmp;
     int err;
 
-    tmp = qemu_strdup(rpath(oldpath));
+    tmp = qemu_strdup(rpath(s, oldpath));
     if (tmp == NULL)
 	return -1;
 
-    err = rename(tmp, rpath(newpath));
+    err = rename(tmp, rpath(s, newpath));
     if (err == -1) {
 	int serrno = errno;
 	qemu_free(tmp);
@@ -234,20 +232,20 @@ static int local_rename(void *opaque, const char *oldpath,
 
 }
 
-static int local_chown(void *opaque, const char *path, uid_t uid, gid_t gid)
+static int local_chown(V9fsState *s, const char *path, uid_t uid, gid_t gid)
 {
-    return chown(rpath(path), uid, gid);
+    return chown(rpath(s, path), uid, gid);
 }
 
-static int local_utime(void *opaque, const char *path,
+static int local_utime(V9fsState *s, const char *path,
 		       const struct utimbuf *buf)
 {
-    return utime(rpath(path), buf);
+    return utime(rpath(s, path), buf);
 }
 
-static int local_remove(void *opaque, const char *path)
+static int local_remove(V9fsState *s, const char *path)
 {
-    return remove(rpath(path));
+    return remove(rpath(s, path));
 }
 
 
@@ -283,6 +281,5 @@ static V9fsPosixFileOperations ops = {
 
 V9fsPosixFileOperations *virtio_9p_init_local(const char *path)
 {
-    base_path = path;
-    return &ops;
+return &ops;
 }
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 1dbb982..e095916 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -15,78 +15,8 @@
 #include "pc.h"
 #include "qemu_socket.h"
 #include "virtio-9p.h"
-
 #include <assert.h>
 
-/* from Linux's linux/virtio_9p.h */
-
-/* The ID for virtio console */
-#define VIRTIO_ID_9P	9
-/* Maximum number of virtio channels per partition (1 for now) */
-#define MAX_9P_CHAN	1
-
-#define MAX_REQ		128
-
-#define BUG_ON(cond) assert(!(cond))
-
-typedef struct V9fsFidState V9fsFidState;
-
-typedef struct V9fsString
-{
-    int16_t size;
-    char *data;
-} V9fsString;
-
-typedef struct V9fsQID
-{
-    int8_t type;
-    int32_t version;
-    int64_t path;
-} V9fsQID;
-
-typedef struct V9fsStat
-{
-    int16_t size;
-    int16_t type;
-    int32_t dev;
-    V9fsQID qid;
-    int32_t mode;
-    int32_t atime;
-    int32_t mtime;
-    int64_t length;
-    V9fsString name;
-    V9fsString uid;
-    V9fsString gid;
-    V9fsString muid;
-    /* 9p2000.u */
-    V9fsString extension;
-    int32_t n_uid;
-    int32_t n_gid;
-    int32_t n_muid;
-} V9fsStat;
-
-struct V9fsFidState
-{
-    int32_t fid;
-    V9fsString path;
-    int fd;
-    DIR *dir;
-    uid_t uid;
-    V9fsFidState *next;
-};
-
-typedef struct V9fsState
-{
-    VirtIODevice vdev;
-    VirtQueue *vq;
-    V9fsPDU pdus[MAX_REQ];
-    V9fsPDU *free_pdu;
-    V9fsFidState *fid_list;
-    V9fsPosixFileOperations *ops;
-    char *root;
-    uid_t uid;
-} V9fsState;
-
 int dotu = 1;
 int debug_9p_pdu = 1;
 
@@ -94,12 +24,12 @@ extern void pprint_pdu(V9fsPDU *pdu);
 
 static int posix_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
 {
-    return s->ops->lstat(s->ops->opaque, path->data, stbuf);
+    return s->ops->lstat(s, path->data, stbuf);
 }
 
 static int posix_setuid(V9fsState *s, uid_t uid)
 {
-    return s->ops->setuid(s->ops->opaque, uid);
+    return s->ops->setuid(s, uid);
 }
 
 static ssize_t posix_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
@@ -108,7 +38,7 @@ static ssize_t posix_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
 
     buf->data = qemu_malloc(1024);
 
-    len = s->ops->readlink(s->ops->opaque, path->data, buf->data, 1024 - 1);
+    len = s->ops->readlink(s, path->data, buf->data, 1024 - 1);
     if (len > -1) {
         buf->size = len;
         buf->data[len] = 0;
@@ -119,127 +49,127 @@ static ssize_t posix_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
 
 static int posix_close(V9fsState *s, int fd)
 {
-    return s->ops->close(s->ops->opaque, fd);
+    return s->ops->close(s, fd);
 }
 
 static int posix_closedir(V9fsState *s, DIR *dir)
 {
-    return s->ops->closedir(s->ops->opaque, dir);
+    return s->ops->closedir(s, dir);
 }
 
 static int posix_open(V9fsState *s, V9fsString *path, int flags)
 {
-    return s->ops->open(s->ops->opaque, path->data, flags);
+    return s->ops->open(s, path->data, flags);
 }
 
 static DIR *posix_opendir(V9fsState *s, V9fsString *path)
 {
-    return s->ops->opendir(s->ops->opaque, path->data);
+    return s->ops->opendir(s, path->data);
 }
 
 static void posix_rewinddir(V9fsState *s, DIR *dir)
 {
-    return s->ops->rewinddir(s->ops->opaque, dir);
+    return s->ops->rewinddir(s, dir);
 }
 
 static off_t posix_telldir(V9fsState *s, DIR *dir)
 {
-    return s->ops->telldir(s->ops->opaque, dir);
+    return s->ops->telldir(s, dir);
 }
 
 static struct dirent *posix_readdir(V9fsState *s, DIR *dir)
 {
-    return s->ops->readdir(s->ops->opaque, dir);
+    return s->ops->readdir(s, dir);
 }
 
 static void posix_seekdir(V9fsState *s, DIR *dir, off_t off)
 {
-    return s->ops->seekdir(s->ops->opaque, dir, off);
+    return s->ops->seekdir(s, dir, off);
 }
 
 static int posix_readv(V9fsState *s, int fd, const struct iovec *iov,
 		       int iovcnt)
 {
-    return s->ops->readv(s->ops->opaque, fd, iov, iovcnt);
+    return s->ops->readv(s, fd, iov, iovcnt);
 }
 
 static off_t posix_lseek(V9fsState *s, int fd, off_t offset, int whence)
 {
-    return s->ops->lseek(s->ops->opaque, fd, offset, whence);
+    return s->ops->lseek(s, fd, offset, whence);
 }
 
 static int posix_writev(V9fsState *s, int fd, const struct iovec *iov,
                        int iovcnt)
 {
-    return s->ops->writev(s->ops->opaque, fd, iov, iovcnt);
+    return s->ops->writev(s, fd, iov, iovcnt);
 }
 
 static int posix_chmod(V9fsState *s, V9fsString *path, mode_t mode)
 {
-    return s->ops->chmod(s->ops->opaque, path->data, mode);
+    return s->ops->chmod(s, path->data, mode);
 }
 
 static int posix_mknod(V9fsState *s, V9fsString *path, mode_t mode, dev_t dev)
 {
-    return s->ops->mknod(s->ops->opaque, path->data, mode, dev);
+    return s->ops->mknod(s, path->data, mode, dev);
 }
 
 static int posix_mksock(V9fsState *s, V9fsString *path)
 {
-    return s->ops->mksock(s->ops->opaque, path->data);
+    return s->ops->mksock(s, path->data);
 }
 
 static int posix_mkdir(V9fsState *s, V9fsString *path, mode_t mode)
 {
-    return s->ops->mkdir(s->ops->opaque, path->data, mode);
+    return s->ops->mkdir(s, path->data, mode);
 }
 
 static int posix_fstat(V9fsState *s, int fd, struct stat *stbuf)
 {
-    return s->ops->fstat(s->ops->opaque, fd, stbuf);
+    return s->ops->fstat(s, fd, stbuf);
 }
 
 static int posix_open2(V9fsState *s, V9fsString *path, int flags, mode_t mode)
 {
-    return s->ops->open2(s->ops->opaque, path->data, flags, mode);
+    return s->ops->open2(s, path->data, flags, mode);
 }
 
 static int posix_symlink(V9fsState *s, V9fsString *oldpath,
 			 V9fsString *newpath)
 {
-    return s->ops->symlink(s->ops->opaque, oldpath->data, newpath->data);
+    return s->ops->symlink(s, oldpath->data, newpath->data);
 }
 
 static int posix_link(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
 {
-    return s->ops->link(s->ops->opaque, oldpath->data, newpath->data);
+    return s->ops->link(s, oldpath->data, newpath->data);
 }
 
 static int posix_truncate(V9fsState *s, V9fsString *path, off_t size)
 {
-    return s->ops->truncate(s->ops->opaque, path->data, size);
+    return s->ops->truncate(s, path->data, size);
 }
 
 static int posix_rename(V9fsState *s, V9fsString *oldpath,
 			V9fsString *newpath)
 {
-    return s->ops->rename(s->ops->opaque, oldpath->data, newpath->data);
+    return s->ops->rename(s, oldpath->data, newpath->data);
 }
 
 static int posix_chown(V9fsState *s, V9fsString *path, uid_t uid, gid_t gid)
 {
-    return s->ops->chown(s->ops->opaque, path->data, uid, gid);
+    return s->ops->chown(s, path->data, uid, gid);
 }
 
 static int posix_utime(V9fsState *s, V9fsString *path,
 		       const struct utimbuf *buf)
 {
-    return s->ops->utime(s->ops->opaque, path->data, buf);
+    return s->ops->utime(s, path->data, buf);
 }
 
 static int posix_remove(V9fsState *s, V9fsString *path)
 {
-    return s->ops->remove(s->ops->opaque, path->data);
+    return s->ops->remove(s, path->data);
 }
 
 static void v9fs_string_init(V9fsString *str)
@@ -785,7 +715,7 @@ static void v9fs_attach(V9fsState *s, V9fsPDU *pdu)
 
     fidp->uid = n_uname;
 
-    v9fs_string_sprintf(&fidp->path, "%s", s->root);
+    v9fs_string_sprintf(&fidp->path, "%s", "/");
     fid_to_qid(s, fidp, &qid);
 
     offset += pdu_marshal(pdu, offset, "Q", &qid);
@@ -2045,17 +1975,58 @@ static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
 
 static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
 {
+    features |= 1 << VIRTIO_9P_MOUNT_TAG;
     return features;
 }
 
-VirtIODevice *virtio_9p_init(DeviceState *dev, const char *path)
+static V9fsState *to_virtio_9p(VirtIODevice *vdev)
+{
+    return (V9fsState *)vdev;
+}
+
+static void virtio_9p_set_config(VirtIODevice *vdev, const uint8_t *config)
+{
+    uint16_t tag_len;
+    struct virtio_9p_config *cfg;
+    V9fsState *s = to_virtio_9p(vdev);
+
+    memcpy(&tag_len, config, sizeof(tag_len));
+    cfg = qemu_mallocz(sizeof(struct virtio_9p_config) + tag_len);
+
+    memcpy(cfg, config, s->config_size);
+    memcpy(&s->tag_len, &cfg->tag_len, sizeof(uint16_t));
+    /* free the old config details */
+    qemu_free(s->tag);
+    s->tag = qemu_malloc(tag_len);
+    memcpy(s->tag, cfg->tag, cfg->tag_len);
+    qemu_free(cfg);
+}
+
+static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
 {
+    struct virtio_9p_config *cfg;
+    V9fsState *s = to_virtio_9p(vdev);
+
+    cfg = qemu_mallocz(sizeof(struct virtio_9p_config) +
+			    s->tag_len);
+    memcpy(&cfg->tag_len, &s->tag_len, sizeof(uint16_t));
+    memcpy(cfg->tag, s->tag, s->tag_len);
+    memcpy(config, cfg, s->config_size);
+    qemu_free(cfg);
+}
+
+VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
+ {
     V9fsState *s;
-    int i;
+    int i, len;
+    struct stat stat;
+
 
     s = (V9fsState *)virtio_common_init("virtio-9p",
-                                        VIRTIO_ID_9P,
-                                        0, sizeof(V9fsState));
+                                    VIRTIO_ID_9P,
+                                    sizeof(struct virtio_9p_config)+
+                                    MAX_TAG_LEN,
+                                    sizeof(V9fsState));
 
     /* initialize pdu allocator */
     s->free_pdu = &s->pdus[0];
@@ -2066,12 +2037,37 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, const char *path)
     s->vq = virtio_add_queue(&s->vdev, MAX_REQ, handle_9p_output);
     BUG_ON(s->vq == NULL);
 
-    s->root = strdup("/");
-    BUG_ON(s->root == NULL);
+    if (!conf->share_path || !conf->tag) {
+	    /* we haven't specified a mount_tag */
+	    fprintf(stderr, "Virtio-9p devices need share_path "
+		    "and mount_tag arguments\n");
+	    exit(1);
+    }
+    if (lstat(conf->share_path, &stat)) {
+	    fprintf(stderr, "share path %s does not exist\n", conf->share_path);
+	    exit(1);
+    } else if (!S_ISDIR(stat.st_mode)) {
+	    fprintf(stderr, "share path %s is not a directory \n", conf->share_path);
+	    exit(1);
+    }
+    s->fs_root = qemu_strdup(conf->share_path);
+    len = strlen(conf->tag);
+    if (len > MAX_TAG_LEN)
+	    len = MAX_TAG_LEN;
+    /* s->tag is non-NULL terminated string */
+    s->tag = qemu_malloc(len);
+    memcpy(s->tag, conf->tag, len);
+    s->tag_len = len;
+    BUG_ON(s->fs_root == NULL);
     s->uid = -1;
 
-    s->ops = virtio_9p_init_local(path);
+    s->ops = virtio_9p_init_local(conf->share_path);
     s->vdev.get_features = virtio_9p_get_features;
+    s->config_size = sizeof(struct virtio_9p_config) +
+			s->tag_len;
+    s->vdev.get_config = virtio_9p_get_config;
+    s->vdev.set_config = virtio_9p_set_config;
+
 
     return &s->vdev;
 }
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 8e15bf0..3fc88a4 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -6,6 +6,10 @@
 #include <sys/time.h>
 #include <utime.h>
 
+/* The feature bitmap for virtio 9P */
+/* The mount point is specified in a config variable */
+#define VIRTIO_9P_MOUNT_TAG 0
+
 enum {
     P9_TVERSION = 100,
     P9_RVERSION,
@@ -66,35 +70,118 @@ struct V9fsPDU
     V9fsPDU *next;
 };
 
+/* FIXME
+ * 1) change user needs to set groups and stuff
+ */
+
+/* from Linux's linux/virtio_9p.h */
+
+/* The ID for virtio console */
+#define VIRTIO_ID_9P	9
+#define MAX_REQ		128
+#define MAX_TAG_LEN	32
+
+#define BUG_ON(cond) assert(!(cond))
+
+typedef struct V9fsFidState V9fsFidState;
+
+typedef struct V9fsString
+{
+    int16_t size;
+    char *data;
+} V9fsString;
+
+typedef struct V9fsQID
+{
+    int8_t type;
+    int32_t version;
+    int64_t path;
+} V9fsQID;
+
+typedef struct V9fsStat
+{
+    int16_t size;
+    int16_t type;
+    int32_t dev;
+    V9fsQID qid;
+    int32_t mode;
+    int32_t atime;
+    int32_t mtime;
+    int64_t length;
+    V9fsString name;
+    V9fsString uid;
+    V9fsString gid;
+    V9fsString muid;
+    /* 9p2000.u */
+    V9fsString extension;
+    int32_t n_uid;
+    int32_t n_gid;
+    int32_t n_muid;
+} V9fsStat;
+
+struct V9fsFidState
+{
+    int32_t fid;
+    V9fsString path;
+    int fd;
+    DIR *dir;
+    uid_t uid;
+    V9fsFidState *next;
+};
+
+struct V9fsPosixFileOpertions ;
+typedef struct V9fsState
+{
+    VirtIODevice vdev;
+    VirtQueue *vq;
+    V9fsPDU pdus[MAX_REQ];
+    V9fsPDU *free_pdu;
+    V9fsFidState *fid_list;
+    struct V9fsPosixFileOpertions *ops;
+    char *fs_root;
+    uid_t uid;
+    uint16_t tag_len;
+    uint8_t *tag;
+    size_t config_size;
+} V9fsState;
+
+struct virtio_9p_config
+{
+    /* number of characters in tag */
+    uint16_t tag_len;
+    /* Variable size tag name */
+    uint8_t tag[0];
+} __attribute__((packed));
+
 typedef struct V9fsPosixFileOpertions
 {
-    int (*lstat)(void *, const char *, struct stat *);
-    ssize_t (*readlink)(void *, const char *, char *, size_t);
-    int (*chmod)(void *, const char *, mode_t);
-    int (*chown)(void *, const char *, uid_t, gid_t);
-    int (*mknod)(void *, const char *, mode_t, dev_t);
-    int (*mksock)(void *, const char *);
-    int (*utime)(void *, const char *, const struct utimbuf *);
-    int (*remove)(void *, const char *);
-    int (*symlink)(void *, const char *, const char *);
-    int (*link)(void *, const char *, const char *);
-    int (*setuid)(void *, uid_t);
-    int (*close)(void *, int);
-    int (*closedir)(void *, DIR *);
-    DIR *(*opendir)(void *, const char *);
-    int (*open)(void *, const char *, int);
-    int (*open2)(void *, const char *, int, mode_t);
-    void (*rewinddir)(void *, DIR *);
-    off_t (*telldir)(void *, DIR *);
-    struct dirent *(*readdir)(void *, DIR *);
-    void (*seekdir)(void *, DIR *, off_t);
-    ssize_t (*readv)(void *, int, const struct iovec *, int);
-    ssize_t (*writev)(void *, int, const struct iovec *, int);
-    off_t (*lseek)(void *, int, off_t, int);
-    int (*mkdir)(void *, const char *, mode_t);
-    int (*fstat)(void *, int, struct stat *);
-    int (*rename)(void *, const char *, const char *);
-    int (*truncate)(void *, const char *, off_t);
+    int (*lstat)(V9fsState *, const char *, struct stat *);
+    ssize_t (*readlink)(V9fsState *, const char *, char *, size_t);
+    int (*chmod)(V9fsState *, const char *, mode_t);
+    int (*chown)(V9fsState *, const char *, uid_t, gid_t);
+    int (*mknod)(V9fsState *, const char *, mode_t, dev_t);
+    int (*mksock)(V9fsState *, const char *);
+    int (*utime)(V9fsState *, const char *, const struct utimbuf *);
+    int (*remove)(V9fsState *, const char *);
+    int (*symlink)(V9fsState *, const char *, const char *);
+    int (*link)(V9fsState *, const char *, const char *);
+    int (*setuid)(V9fsState *, uid_t);
+    int (*close)(V9fsState *, int);
+    int (*closedir)(V9fsState *, DIR *);
+    DIR *(*opendir)(V9fsState *, const char *);
+    int (*open)(V9fsState *, const char *, int);
+    int (*open2)(V9fsState *, const char *, int, mode_t);
+    void (*rewinddir)(V9fsState *, DIR *);
+    off_t (*telldir)(V9fsState *, DIR *);
+    struct dirent *(*readdir)(V9fsState *, DIR *);
+    void (*seekdir)(V9fsState *, DIR *, off_t);
+    ssize_t (*readv)(V9fsState *, int, const struct iovec *, int);
+    ssize_t (*writev)(V9fsState *, int, const struct iovec *, int);
+    off_t (*lseek)(V9fsState *, int, off_t, int);
+    int (*mkdir)(V9fsState *, const char *, mode_t);
+    int (*fstat)(V9fsState *, int, struct stat *);
+    int (*rename)(V9fsState *, const char *, const char *);
+    int (*truncate)(V9fsState *, const char *, off_t);
     void *opaque;
 } V9fsPosixFileOperations;
 
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 85879fb..73e7df7 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -86,7 +86,6 @@
 #define wmb() do { } while (0)
 
 /* PCI bindings.  */
-
 typedef struct {
     PCIDevice pci_dev;
     VirtIODevice *vdev;
@@ -96,7 +95,7 @@ typedef struct {
     BlockConf block;
     NICConf nic;
     uint32_t host_features;
-    char *share_path;
+    V9fsConf fsconf;
     /* Max. number of ports we can have for a the virtio-serial device */
     uint32_t max_virtserial_ports;
 } VirtIOPCIProxy;
@@ -558,7 +557,7 @@ static int virtio_9p_init_pci(PCIDevice *pci_dev)
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
     VirtIODevice *vdev;
 
-    vdev = virtio_9p_init(&pci_dev->qdev, proxy->share_path);
+    vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf);
     virtio_init_pci(proxy, vdev,
 		    PCI_VENDOR_ID_REDHAT_QUMRANET,
 		    0x1009,
@@ -627,7 +626,8 @@ static PCIDeviceInfo virtio_info[] = {
         .init      = virtio_9p_init_pci,
         .qdev.props = (Property[]) {
             DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-            DEFINE_PROP_STRING("share_path", VirtIOPCIProxy, share_path),
+            DEFINE_PROP_STRING("share_path", VirtIOPCIProxy, fsconf.share_path),
+            DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
             DEFINE_PROP_END_OF_LIST(),
         },
     },{
diff --git a/hw/virtio.h b/hw/virtio.h
index 4032a96..c11a380 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -19,6 +19,7 @@
 #include "qdev.h"
 #include "sysemu.h"
 #include "block_int.h"
+#include "9p.h"
 
 /* from Linux's linux/virtio_config.h */
 
@@ -174,7 +175,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf);
 VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf);
 VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports);
 VirtIODevice *virtio_balloon_init(DeviceState *dev);
-VirtIODevice *virtio_9p_init(DeviceState *dev, const char *path);
+VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
 
 void virtio_net_exit(VirtIODevice *vdev);
 
