diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 3e2b175..aae7082 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -4,4 +4,4 @@ common-obj-y += virtio-bus.o
 common-obj-y += virtio-mmio.o
 
 obj-y += virtio.o virtio-balloon.o 
-obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
+obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o virtio-pstore.o
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index f0677b7..d99a405 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -2414,6 +2414,59 @@ static const TypeInfo virtio_host_pci_info = {
 };
 #endif
 
+/* virtio-pstore-pci */
+
+static void virtio_pstore_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+    VirtIOPstorePCI *vps = VIRTIO_PSTORE_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&vps->vdev);
+    Error *err = NULL;
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+}
+
+static void virtio_pstore_pci_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    k->realize = virtio_pstore_pci_realize;
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_PSTORE;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+}
+
+static void virtio_pstore_pci_instance_init(Object *obj)
+{
+    VirtIOPstorePCI *dev = VIRTIO_PSTORE_PCI(obj);
+
+    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+                                TYPE_VIRTIO_PSTORE);
+    object_property_add_alias(obj, "directory", OBJECT(&dev->vdev),
+                              "directory", &error_abort);
+    object_property_add_alias(obj, "bufsize", OBJECT(&dev->vdev),
+                              "bufsize", &error_abort);
+    object_property_add_alias(obj, "console", OBJECT(&dev->vdev),
+                              "console", &error_abort);
+}
+
+static const TypeInfo virtio_pstore_pci_info = {
+    .name          = TYPE_VIRTIO_PSTORE_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIOPstorePCI),
+    .instance_init = virtio_pstore_pci_instance_init,
+    .class_init    = virtio_pstore_pci_class_init,
+};
+
 /* virtio-pci-bus */
 
 static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
@@ -2483,6 +2536,7 @@ static void virtio_pci_register_types(void)
 #ifdef CONFIG_VHOST_SCSI
     type_register_static(&vhost_scsi_pci_info);
 #endif
+    type_register_static(&virtio_pstore_pci_info);
 }
 
 type_init(virtio_pci_register_types)
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index e4548c2..b4c039f 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -31,6 +31,7 @@
 #ifdef CONFIG_VHOST_SCSI
 #include "hw/virtio/vhost-scsi.h"
 #endif
+#include "hw/virtio/virtio-pstore.h"
 
 typedef struct VirtIOPCIProxy VirtIOPCIProxy;
 typedef struct VirtIOBlkPCI VirtIOBlkPCI;
@@ -44,6 +45,7 @@ typedef struct VirtIOInputPCI VirtIOInputPCI;
 typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI;
 typedef struct VirtIOInputHostPCI VirtIOInputHostPCI;
 typedef struct VirtIOGPUPCI VirtIOGPUPCI;
+typedef struct VirtIOPstorePCI VirtIOPstorePCI;
 
 /* virtio-pci-bus */
 
@@ -311,6 +313,18 @@ struct VirtIOGPUPCI {
     VirtIOGPU vdev;
 };
 
+/*
+ * virtio-pstore-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_PSTORE_PCI "virtio-pstore-pci"
+#define VIRTIO_PSTORE_PCI(obj) \
+        OBJECT_CHECK(VirtIOPstorePCI, (obj), TYPE_VIRTIO_PSTORE_PCI)
+
+struct VirtIOPstorePCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIOPstore vdev;
+};
+
 /* Virtio ABI version, if we increment this, we break the guest driver. */
 #define VIRTIO_PCI_ABI_VERSION          0
 
diff --git a/hw/virtio/virtio-pstore.c b/hw/virtio/virtio-pstore.c
new file mode 100644
index 0000000..2ca7786
--- /dev/null
+++ b/hw/virtio/virtio-pstore.c
@@ -0,0 +1,477 @@
+/*
+ * Virtio Pstore Device
+ *
+ * Copyright (C) 2016  LG Electronics
+ *
+ * Authors:
+ *  Namhyung Kim  <namhyung@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <stdio.h>
+
+#include "qemu/osdep.h"
+#include "qemu/iov.h"
+#include "qemu-common.h"
+#include "qemu/cutils.h"
+#include "qemu/error-report.h"
+#include "sysemu/kvm.h"
+#include "qapi/visitor.h"
+#include "qapi-event.h"
+#include "trace.h"
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/virtio-access.h"
+#include "hw/virtio/virtio-pstore.h"
+
+
+static void virtio_pstore_to_filename(VirtIOPstore *s, char *buf, size_t sz,
+                                      struct virtio_pstore_req *req)
+{
+    const char *basename;
+    unsigned long long id = 0;
+    unsigned int flags = le32_to_cpu(req->flags);
+
+    switch (le16_to_cpu(req->type)) {
+    case VIRTIO_PSTORE_TYPE_DMESG:
+        basename = "dmesg";
+        id = s->id++;
+        break;
+    case VIRTIO_PSTORE_TYPE_CONSOLE:
+        basename = "console";
+        if (s->console_id) {
+            id = s->console_id;
+        } else {
+            id = s->console_id = s->id++;
+        }
+        break;
+    default:
+        basename = "unknown";
+        break;
+    }
+
+    snprintf(buf, sz, "%s/%s-%llu%s", s->directory, basename, id,
+             flags & VIRTIO_PSTORE_FL_COMPRESSED ? ".enc.z" : "");
+}
+
+static void virtio_pstore_from_filename(VirtIOPstore *s, char *name,
+                                        char *buf, size_t sz,
+                                        struct virtio_pstore_fileinfo *info)
+{
+    snprintf(buf, sz, "%s/%s", s->directory, name);
+
+    if (g_str_has_prefix(name, "dmesg-")) {
+        info->type = VIRTIO_PSTORE_TYPE_DMESG;
+        name += strlen("dmesg-");
+    } else if (g_str_has_prefix(name, "console-")) {
+        info->type = VIRTIO_PSTORE_TYPE_CONSOLE;
+        name += strlen("console-");
+    } else if (g_str_has_prefix(name, "unknown-")) {
+        info->type = VIRTIO_PSTORE_TYPE_UNKNOWN;
+        name += strlen("unknown-");
+    }
+
+    qemu_strtoull(name, NULL, 0, &info->id);
+
+    info->flags = 0;
+    if (g_str_has_suffix(name, ".enc.z")) {
+        info->flags |= VIRTIO_PSTORE_FL_COMPRESSED;
+    }
+}
+
+static ssize_t virtio_pstore_do_open(VirtIOPstore *s)
+{
+    s->dirp = opendir(s->directory);
+    if (s->dirp == NULL) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static ssize_t virtio_pstore_do_read(VirtIOPstore *s, struct iovec *in_sg,
+                                     unsigned int in_num,
+                                     struct virtio_pstore_res *res)
+{
+    char path[PATH_MAX];
+    int fd;
+    ssize_t len;
+    struct stat stbuf;
+    struct dirent *dent;
+    int sg_num = in_num;
+    struct iovec sg[sg_num];
+    struct virtio_pstore_fileinfo info;
+    size_t offset = sizeof(*res) + sizeof(info);
+
+    if (s->dirp == NULL) {
+        return -1;
+    }
+
+    dent = readdir(s->dirp);
+    while (dent) {
+        if (dent->d_name[0] != '.') {
+            break;
+        }
+        dent = readdir(s->dirp);
+    }
+
+    if (dent == NULL) {
+        return 0;
+    }
+
+    /* skip res and fileinfo */
+    sg_num = iov_copy(sg, sg_num, in_sg, in_num, offset,
+                      iov_size(in_sg, in_num) - offset);
+
+    virtio_pstore_from_filename(s, dent->d_name, path, sizeof(path), &info);
+    fd = open(path, O_RDONLY);
+    if (fd < 0) {
+        error_report("cannot open %s", path);
+        return -1;
+    }
+
+    if (fstat(fd, &stbuf) < 0) {
+        len = -1;
+        goto out;
+    }
+
+    len = readv(fd, sg, sg_num);
+    if (len < 0) {
+        if (errno == EAGAIN) {
+            len = 0;
+        }
+        goto out;
+    }
+
+    info.id        = cpu_to_le64(info.id);
+    info.type      = cpu_to_le16(info.type);
+    info.flags     = cpu_to_le32(info.flags);
+    info.len       = cpu_to_le32(len);
+    info.time_sec  = cpu_to_le64(stbuf.st_ctim.tv_sec);
+    info.time_nsec = cpu_to_le32(stbuf.st_ctim.tv_nsec);
+
+    iov_from_buf(in_sg, in_num, sizeof(*res), &info, sizeof(info));
+    len += sizeof(info);
+
+ out:
+    close(fd);
+    return len;
+}
+
+static ssize_t virtio_pstore_do_write(VirtIOPstore *s, struct iovec *out_sg,
+                                      unsigned int out_num,
+                                      struct virtio_pstore_req *req)
+{
+    char path[PATH_MAX];
+    int fd;
+    ssize_t len;
+    unsigned short type;
+    int flags = O_WRONLY | O_CREAT;
+
+    /* we already consume the req */
+    iov_discard_front(&out_sg, &out_num, sizeof(*req));
+
+    virtio_pstore_to_filename(s, path, sizeof(path), req);
+
+    type = le16_to_cpu(req->type);
+
+    if (type == VIRTIO_PSTORE_TYPE_DMESG) {
+        flags |= O_TRUNC;
+    } else if (type == VIRTIO_PSTORE_TYPE_CONSOLE) {
+        flags |= O_APPEND;
+    }
+
+    fd = open(path, flags, 0644);
+    if (fd < 0) {
+        error_report("cannot open %s", path);
+        return -1;
+    }
+    len = writev(fd, out_sg, out_num);
+    close(fd);
+
+    return len;
+}
+
+static ssize_t virtio_pstore_do_close(VirtIOPstore *s)
+{
+    if (s->dirp == NULL) {
+        return 0;
+    }
+
+    closedir(s->dirp);
+    s->dirp = NULL;
+
+    return 0;
+}
+
+static ssize_t virtio_pstore_do_erase(VirtIOPstore *s,
+                                      struct virtio_pstore_req *req)
+{
+    char path[PATH_MAX];
+
+    virtio_pstore_to_filename(s, path, sizeof(path), req);
+
+    return unlink(path);
+}
+
+static void virtio_pstore_handle_io(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOPstore *s = VIRTIO_PSTORE(vdev);
+    VirtQueueElement *elem;
+    struct virtio_pstore_req req;
+    struct virtio_pstore_res res;
+    ssize_t len = 0;
+    int ret;
+
+    for (;;) {
+        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+        if (!elem) {
+            return;
+        }
+
+        if (elem->out_num < 1 || elem->in_num < 1) {
+            error_report("request or response buffer is missing");
+            exit(1);
+        }
+
+        len = iov_to_buf(elem->out_sg, elem->out_num, 0, &req, sizeof(req));
+        if (len != (ssize_t)sizeof(req)) {
+            error_report("invalid request size: %ld", (long)len);
+            exit(1);
+        }
+        res.cmd  = req.cmd;
+        res.type = req.type;
+
+        switch (le16_to_cpu(req.cmd)) {
+        case VIRTIO_PSTORE_CMD_OPEN:
+            ret = virtio_pstore_do_open(s);
+            break;
+        case VIRTIO_PSTORE_CMD_READ:
+            ret = virtio_pstore_do_read(s, elem->in_sg, elem->in_num, &res);
+            if (ret > 0) {
+                len = ret;
+                ret = 0;
+            }
+            break;
+        case VIRTIO_PSTORE_CMD_WRITE:
+            ret = virtio_pstore_do_write(s, elem->out_sg, elem->out_num, &req);
+            break;
+        case VIRTIO_PSTORE_CMD_CLOSE:
+            ret = virtio_pstore_do_close(s);
+            break;
+        case VIRTIO_PSTORE_CMD_ERASE:
+            ret = virtio_pstore_do_erase(s, &req);
+            break;
+        default:
+            ret = -1;
+            break;
+        }
+
+        res.ret  = ret;
+
+        iov_from_buf(elem->in_sg, elem->in_num, 0, &res, sizeof(res));
+        virtqueue_push(vq, elem, sizeof(res) + len);
+
+        virtio_notify(vdev, vq);
+        g_free(elem);
+
+        if (ret < 0) {
+            return;
+        }
+    }
+}
+
+static void virtio_pstore_device_realize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VirtIOPstore *s = VIRTIO_PSTORE(dev);
+
+    virtio_init(vdev, "virtio-pstore", VIRTIO_ID_PSTORE,
+                sizeof(struct virtio_pstore_config));
+
+    s->id = 1;
+    s->console_id = 0;
+
+    s->vq[0] = virtio_add_queue(vdev, 128, virtio_pstore_handle_io);
+    s->vq[1] = virtio_add_queue(vdev, 128, virtio_pstore_handle_io);
+}
+
+static void virtio_pstore_device_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+
+    virtio_cleanup(vdev);
+}
+
+static void virtio_pstore_get_config(VirtIODevice *vdev, uint8_t *config_data)
+{
+    VirtIOPstore *dev = VIRTIO_PSTORE(vdev);
+    struct virtio_pstore_config config;
+
+    config.bufsize = cpu_to_le32(dev->bufsize);
+    if (dev->console) {
+        config.flags |= cpu_to_le32(VIRTIO_PSTORE_CONFIG_FL_CONSOLE);
+    }
+
+    memcpy(config_data, &config, sizeof(struct virtio_pstore_config));
+}
+
+static void virtio_pstore_set_config(VirtIODevice *vdev,
+                                     const uint8_t *config_data)
+{
+    VirtIOPstore *dev = VIRTIO_PSTORE(vdev);
+    struct virtio_pstore_config config;
+
+    memcpy(&config, config_data, sizeof(struct virtio_pstore_config));
+
+    dev->bufsize = le32_to_cpu(config.bufsize);
+}
+
+static uint64_t get_features(VirtIODevice *vdev, uint64_t f, Error **errp)
+{
+    return f;
+}
+
+static void pstore_get_directory(Object *obj, Visitor *v,
+                                 const char *name, void *opaque,
+                                 Error **errp)
+{
+    VirtIOPstore *s = opaque;
+
+    visit_type_str(v, name, &s->directory, errp);
+}
+
+static void pstore_set_directory(Object *obj, Visitor *v,
+                                 const char *name, void *opaque,
+                                 Error **errp)
+{
+    VirtIOPstore *s = opaque;
+    Error *local_err = NULL;
+    char *value;
+
+    visit_type_str(v, name, &value, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    g_free(s->directory);
+    s->directory = value;
+}
+
+static void pstore_release_directory(Object *obj, const char *name,
+                                     void *opaque)
+{
+    VirtIOPstore *s = opaque;
+
+    g_free(s->directory);
+    s->directory = NULL;
+}
+
+static void pstore_get_bufsize(Object *obj, Visitor *v,
+                               const char *name, void *opaque,
+                               Error **errp)
+{
+    VirtIOPstore *s = opaque;
+    uint64_t value = s->bufsize;
+
+    visit_type_size(v, name, &value, errp);
+}
+
+static void pstore_set_bufsize(Object *obj, Visitor *v,
+                               const char *name, void *opaque,
+                               Error **errp)
+{
+    VirtIOPstore *s = opaque;
+    Error *error = NULL;
+    uint64_t value;
+
+    visit_type_size(v, name, &value, &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+
+    if (value < 4096) {
+        error_report("Warning: too small buffer size: %"PRIu64, value);
+    }
+
+    s->bufsize = value;
+}
+
+static void pstore_get_console(Object *obj, Visitor *v,
+                               const char *name, void *opaque,
+                               Error **errp)
+{
+    VirtIOPstore *s = opaque;
+    bool value = s->console;
+
+    visit_type_bool(v, name, &value, errp);
+}
+
+static void pstore_set_console(Object *obj, Visitor *v,
+                               const char *name, void *opaque,
+                               Error **errp)
+{
+    VirtIOPstore *s = opaque;
+    Error *error = NULL;
+    bool value;
+
+    visit_type_bool(v, name, &value, &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+
+    s->console = value;
+}
+
+static Property virtio_pstore_properties[] = {
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_pstore_instance_init(Object *obj)
+{
+    VirtIOPstore *s = VIRTIO_PSTORE(obj);
+
+    object_property_add(obj, "directory", "str",
+                        pstore_get_directory, pstore_set_directory,
+                        pstore_release_directory, s, NULL);
+    object_property_add(obj, "bufsize", "size",
+                        pstore_get_bufsize, pstore_set_bufsize, NULL, s, NULL);
+    object_property_add(obj, "console", "bool",
+                        pstore_get_console, pstore_set_console, NULL, s, NULL);
+}
+
+static void virtio_pstore_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+
+    dc->props = virtio_pstore_properties;
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+    vdc->realize = virtio_pstore_device_realize;
+    vdc->unrealize = virtio_pstore_device_unrealize;
+    vdc->get_config = virtio_pstore_get_config;
+    vdc->set_config = virtio_pstore_set_config;
+    vdc->get_features = get_features;
+}
+
+static const TypeInfo virtio_pstore_info = {
+    .name = TYPE_VIRTIO_PSTORE,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIOPstore),
+    .instance_init = virtio_pstore_instance_init,
+    .class_init = virtio_pstore_class_init,
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_pstore_info);
+}
+
+type_init(virtio_register_types)
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 74d797d..000e1e9 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -79,6 +79,7 @@
 #define PCI_DEVICE_ID_VIRTIO_SCSI        0x1004
 #define PCI_DEVICE_ID_VIRTIO_RNG         0x1005
 #define PCI_DEVICE_ID_VIRTIO_9P          0x1009
+#define PCI_DEVICE_ID_VIRTIO_PSTORE      0x100a
 
 #define PCI_VENDOR_ID_REDHAT             0x1b36
 #define PCI_DEVICE_ID_REDHAT_BRIDGE      0x0001
diff --git a/include/hw/virtio/virtio-pstore.h b/include/hw/virtio/virtio-pstore.h
new file mode 100644
index 0000000..d188a48
--- /dev/null
+++ b/include/hw/virtio/virtio-pstore.h
@@ -0,0 +1,34 @@
+/*
+ * Virtio Pstore Support
+ *
+ * Authors:
+ *  Namhyung Kim      <namhyung@gmail.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_VIRTIO_PSTORE_H
+#define _QEMU_VIRTIO_PSTORE_H
+
+#include "standard-headers/linux/virtio_pstore.h"
+#include "hw/virtio/virtio.h"
+#include "hw/pci/pci.h"
+
+#define TYPE_VIRTIO_PSTORE "virtio-pstore-device"
+#define VIRTIO_PSTORE(obj) \
+        OBJECT_CHECK(VirtIOPstore, (obj), TYPE_VIRTIO_PSTORE)
+
+typedef struct VirtIOPstore {
+    VirtIODevice    parent_obj;
+    VirtQueue      *vq[2];
+    char           *directory;
+    uint64_t        id;
+    uint64_t        console_id;
+    DIR            *dirp;
+    uint64_t        bufsize;
+    bool            console;
+} VirtIOPstore;
+
+#endif
diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
index 77925f5..c72a9ab 100644
--- a/include/standard-headers/linux/virtio_ids.h
+++ b/include/standard-headers/linux/virtio_ids.h
@@ -41,5 +41,6 @@
 #define VIRTIO_ID_CAIF	       12 /* Virtio caif */
 #define VIRTIO_ID_GPU          16 /* virtio GPU */
 #define VIRTIO_ID_INPUT        18 /* virtio input */
+#define VIRTIO_ID_PSTORE       22 /* virtio pstore */
 
 #endif /* _LINUX_VIRTIO_IDS_H */
diff --git a/include/standard-headers/linux/virtio_pstore.h b/include/standard-headers/linux/virtio_pstore.h
new file mode 100644
index 0000000..b893d15
--- /dev/null
+++ b/include/standard-headers/linux/virtio_pstore.h
@@ -0,0 +1,80 @@
+#ifndef _LINUX_VIRTIO_PSTORE_H
+#define _LINUX_VIRTIO_PSTORE_H
+/* This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
+#include "standard-headers/linux/types.h"
+#include "standard-headers/linux/virtio_types.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_config.h"
+
+#define VIRTIO_PSTORE_CMD_NULL   0
+#define VIRTIO_PSTORE_CMD_OPEN   1
+#define VIRTIO_PSTORE_CMD_READ   2
+#define VIRTIO_PSTORE_CMD_WRITE  3
+#define VIRTIO_PSTORE_CMD_ERASE  4
+#define VIRTIO_PSTORE_CMD_CLOSE  5
+
+#define VIRTIO_PSTORE_TYPE_UNKNOWN  0
+#define VIRTIO_PSTORE_TYPE_DMESG    1
+#define VIRTIO_PSTORE_TYPE_CONSOLE  2
+
+#define VIRTIO_PSTORE_FL_COMPRESSED  1
+
+#define VIRTIO_PSTORE_CONFIG_FL_CONSOLE  (1 << 0)
+
+struct virtio_pstore_req {
+    __virtio16 cmd;
+    __virtio16 type;
+    __virtio32 flags;
+    __virtio64 id;
+    __virtio32 count;
+    __virtio32 reserved;
+};
+
+struct virtio_pstore_res {
+    __virtio16 cmd;
+    __virtio16 type;
+    __virtio32 ret;
+};
+
+struct virtio_pstore_fileinfo {
+    __virtio64 id;
+    __virtio32 count;
+    __virtio16 type;
+    __virtio16 unused;
+    __virtio32 flags;
+    __virtio32 len;
+    __virtio64 time_sec;
+    __virtio32 time_nsec;
+    __virtio32 reserved;
+};
+
+struct virtio_pstore_config {
+    __virtio32 bufsize;
+    __virtio32 flags;
+};
+
+#endif /* _LINUX_VIRTIO_PSTORE_H */
diff --git a/qdev-monitor.c b/qdev-monitor.c
index e19617f..e1df5a9 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -73,6 +73,7 @@ static const QDevAlias qdev_alias_table[] = {
     { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
     { "virtio-tablet-ccw", "virtio-tablet", QEMU_ARCH_S390X },
     { "virtio-tablet-pci", "virtio-tablet", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
+    { "virtio-pstore-pci", "virtio-pstore" },
     { }
 };
 
