diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 28d9cf7..6af2fe2 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -591,6 +591,78 @@ static struct virtio_config_ops virtio_pci_config_ops = {
 	.finalize_features = vp_finalize_features,
 };
 
+static struct virtmem *setup_mem(struct virtio_device *vdev, unsigned index)
+{
+	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+	struct virtmem *vmem;
+	u32 size;
+	u32 pfn;
+
+	/* Select the memory region we're interested in */
+    printk(KERN_INFO "selecting mem region %d\n", index);
+	iowrite32(index, vp_dev->ioaddr + VIRTIO_PCI_MEM_SEL);
+
+	/* Read memory region size */
+	size = ioread32(vp_dev->ioaddr + VIRTIO_PCI_MEM_SIZE);
+	if (!size) return ERR_PTR(-ENOENT);
+
+    pfn = ioread32(vp_dev->ioaddr + VIRTIO_PCI_MEM_PFN);
+    printk(KERN_INFO "pfn is %#x\n", pfn);
+
+	/* allocate and fill out our structure the represents an active
+	 * mem_region */
+	vmem = kmalloc(sizeof(struct virtmem), GFP_KERNEL);
+	if (!vmem)
+		return ERR_PTR(-ENOMEM);
+
+    vmem->size = size;
+    vmem->phys_addr = pfn << 12;
+
+	return vmem;
+
+}
+
+/* support for VirtIO shared memory */
+static int vp_map_region(struct virtio_device *vdev, unsigned nmem,
+        struct virtmem ** vmem)
+{
+    int i;
+
+    for (i = 0; i < nmem; ++i) {
+        vmem[i] = setup_mem(vdev, i);
+        printk(KERN_INFO "virtio_pci: vp_map_region (%lu, %lu)\n",
+               vmem[i]->phys_addr, vmem[i]->size);
+
+        /* let's map it here and assign the address to 'map_addr' */
+        vmem[i]->map_addr = ioremap_cache(vmem[i]->phys_addr, vmem[i]->size);
+
+        if (vmem[i]->map_addr == NULL) {
+            printk(KERN_INFO "virtio_pci: vp_map_region (%lu, %lu) failed \n",
+                    vmem[i]->phys_addr, vmem[i]->size);
+            return -ENODEV;
+        }
+    }
+
+    /* TODO: compare length to size? */
+
+    return 0;
+}
+
+static void vp_unmap_region(struct virtio_device *vdev, struct virtmem *vmem)
+{
+
+    vmem->map_addr = 0;
+    vmem->size = 0;
+    iounmap(vmem->phys_addr);
+
+    return;
+}
+
+static struct virtio_device_ops virtio_pci_device_ops = {
+    .map_region = vp_map_region,
+    .unmap_region   = vp_unmap_region,
+};
+
 static void virtio_pci_release_dev(struct device *_d)
 {
 	struct virtio_device *dev = container_of(_d, struct virtio_device, dev);
@@ -630,6 +702,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,
 	vp_dev->vdev.dev.parent = virtio_pci_root;
 	vp_dev->vdev.dev.release = virtio_pci_release_dev;
 	vp_dev->vdev.config = &virtio_pci_config_ops;
+	vp_dev->vdev.device = &virtio_pci_device_ops;
 	vp_dev->pci_dev = pci_dev;
 	INIT_LIST_HEAD(&vp_dev->virtqueues);
 	spin_lock_init(&vp_dev->lock);
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index 057a2e0..2b8ea66 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -26,6 +26,14 @@ struct virtqueue {
 	void *priv;
 };
 
+struct virtmem {
+    struct virtio_device *vdev;
+    u32 size;
+    u64 phys_addr;
+    unsigned char * map_addr;
+    void * priv;
+};
+
 /**
  * virtqueue_ops - operations for virtqueue abstraction layer
  * @add_buf: expose buffer to other end
@@ -88,6 +96,7 @@ struct virtio_device {
 	struct device dev;
 	struct virtio_device_id id;
 	struct virtio_config_ops *config;
+	struct virtio_device_ops *device;
 	struct list_head vqs;
 	/* Note that this is a Linux set_bit-style bitmap. */
 	unsigned long features[1];
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 0093dd7..ff90d3c 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -96,6 +96,13 @@ struct virtio_config_ops {
 	void (*finalize_features)(struct virtio_device *vdev);
 };
 
+struct virtio_device_ops {
+    int (*map_region) (struct virtio_device *vdev,
+                            unsigned nmem, struct virtmem ** vmem);
+    void (*unmap_region)(struct virtio_device *vdev, struct virtmem *vmem);
+    /* we might need query region and other stuff */
+};
+
 /* If driver didn't advertise the feature, it will never appear. */
 void virtio_check_driver_offered_feature(const struct virtio_device *vdev,
 					 unsigned int fbit);
diff --git a/include/linux/virtio_pci.h b/include/linux/virtio_pci.h
index 9a3d7c4..f3362d2 100644
--- a/include/linux/virtio_pci.h
+++ b/include/linux/virtio_pci.h
@@ -49,15 +49,21 @@
 
 /* MSI-X registers: only enabled if MSI-X is enabled. */
 /* A 16-bit vector for configuration changes. */
-#define VIRTIO_MSI_CONFIG_VECTOR        20
+#define VIRTIO_MSI_CONFIG_VECTOR        32
 /* A 16-bit vector for selected queue notifications. */
-#define VIRTIO_MSI_QUEUE_VECTOR         22
+#define VIRTIO_MSI_QUEUE_VECTOR         34
 /* Vector value used to disable MSI for queue */
 #define VIRTIO_MSI_NO_VECTOR            0xffff
 
 /* The remaining space is defined by each driver as the per-driver
  * configuration space */
-#define VIRTIO_PCI_CONFIG(dev)		((dev)->msix_enabled ? 24 : 20)
+#define VIRTIO_PCI_CONFIG(dev)		((dev)->msix_enabled ? 36 : 32)
+
+#define VIRTIO_PCI_MEM_SEL              20
+
+#define VIRTIO_PCI_MEM_SIZE             24
+
+#define VIRTIO_PCI_MEM_PFN              28
 
 /* Virtio ABI version, this must match exactly */
 #define VIRTIO_PCI_ABI_VERSION		0
