diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index df4e4a07db3d..4a543e23b9a0 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -444,7 +444,8 @@ static void kvmgt_put_vfio_device(void *vgpu)
 	vfio_device_put(((struct intel_vgpu *)vgpu)->vdev.vfio_device);
 }
 
-static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
+static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev,
+			     unsigned int instances)
 {
 	struct intel_vgpu *vgpu = NULL;
 	struct intel_vgpu_type *type;
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 41eeb57d68a3..4c37826ec9d0 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -106,7 +106,8 @@ static struct attribute_group *mdev_type_groups[] = {
 	NULL,
 };
 
-static int vfio_ccw_mdev_create(struct kobject *kobj, struct mdev_device *mdev)
+static int vfio_ccw_mdev_create(struct kobject *kobj, struct mdev_device *mdev,
+				unsigned int instances)
 {
 	struct vfio_ccw_private *private =
 		dev_get_drvdata(mdev_parent_dev(mdev));
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 0212f0ee8aea..98b0a78e6832 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -104,12 +104,13 @@ static inline void mdev_put_parent(struct mdev_parent *parent)
 }
 
 static int mdev_device_create_ops(struct kobject *kobj,
-				  struct mdev_device *mdev)
+				  struct mdev_device *mdev,
+				  unsigned int instances)
 {
 	struct mdev_parent *parent = mdev->parent;
 	int ret;
 
-	ret = parent->ops->create(kobj, mdev);
+	ret = parent->ops->create(kobj, mdev, instances);
 	if (ret)
 		return ret;
 
@@ -276,7 +277,8 @@ static void mdev_device_release(struct device *dev)
 	kfree(mdev);
 }
 
-int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
+int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid,
+		       unsigned int instances)
 {
 	int ret;
 	struct mdev_device *mdev, *tmp;
@@ -316,6 +318,7 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
 	mdev->dev.bus     = &mdev_bus_type;
 	mdev->dev.release = mdev_device_release;
 	dev_set_name(&mdev->dev, "%pUl", uuid.b);
+	mdev->type_instances = instances;
 
 	ret = device_register(&mdev->dev);
 	if (ret) {
@@ -323,7 +326,7 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
 		goto mdev_fail;
 	}
 
-	ret = mdev_device_create_ops(kobj, mdev);
+	ret = mdev_device_create_ops(kobj, mdev, instances);
 	if (ret)
 		goto create_fail;
 
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index b5819b7d7ef7..aa0b4b64c503 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -33,6 +33,7 @@ struct mdev_device {
 	struct kref ref;
 	struct list_head next;
 	struct kobject *type_kobj;
+	unsigned int type_instances;
 	bool active;
 };
 
@@ -52,13 +53,16 @@ struct mdev_type {
 #define to_mdev_type(_kobj)		\
 	container_of(_kobj, struct mdev_type, kobj)
 
+#define MDEV_CREATE_OPT_LEN 32
+
 int  parent_create_sysfs_files(struct mdev_parent *parent);
 void parent_remove_sysfs_files(struct mdev_parent *parent);
 
 int  mdev_create_sysfs_files(struct device *dev, struct mdev_type *type);
 void mdev_remove_sysfs_files(struct device *dev, struct mdev_type *type);
 
-int  mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid);
+int  mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid,
+			unsigned int instances);
 int  mdev_device_remove(struct device *dev, bool force_remove);
 
 #endif /* MDEV_PRIVATE_H */
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 249472f05509..5a417a20e774 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -54,11 +54,15 @@ static const struct sysfs_ops mdev_type_sysfs_ops = {
 static ssize_t create_store(struct kobject *kobj, struct device *dev,
 			    const char *buf, size_t count)
 {
-	char *str;
+	char *str, *opt = NULL;
 	uuid_le uuid;
 	int ret;
+	unsigned int instances = 1;
 
-	if ((count < UUID_STRING_LEN) || (count > UUID_STRING_LEN + 1))
+	if (count < UUID_STRING_LEN)
+		return -EINVAL;
+
+	if (count > UUID_STRING_LEN + 1 + MDEV_CREATE_OPT_LEN)
 		return -EINVAL;
 
 	str = kstrndup(buf, count, GFP_KERNEL);
@@ -66,13 +70,31 @@ static ssize_t create_store(struct kobject *kobj, struct device *dev,
 		return -ENOMEM;
 
 	ret = uuid_le_to_bin(str, &uuid);
-	kfree(str);
-	if (ret)
+	if (ret) {
+		kfree(str);
 		return ret;
+	}
 
-	ret = mdev_device_create(kobj, dev, uuid);
-	if (ret)
+	if (count > UUID_STRING_LEN + 1) {
+		opt = str + UUID_STRING_LEN;
+		if (*opt++ != ',' ||
+		    strncmp(opt, "instances=", 10)) {
+			kfree(str);
+			return -EINVAL;
+		}
+		opt += 10;
+		if (kstrtouint(opt, 10, &instances)) {
+			kfree(str);
+			return -EINVAL;
+		}
+	}
+
+	ret = mdev_device_create(kobj, dev, uuid, instances);
+	if (ret) {
+		kfree(str);
 		return ret;
+	}
+	kfree(str);
 
 	return count;
 }
@@ -246,10 +268,18 @@ static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
+static ssize_t instances_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct mdev_device *mdev = to_mdev_device(dev);
+	return sprintf(buf, "%u\n", mdev->type_instances);
+}
+
 static DEVICE_ATTR_WO(remove);
+static DEVICE_ATTR_RO(instances);
 
 static const struct attribute *mdev_device_attrs[] = {
 	&dev_attr_remove.attr,
+	&dev_attr_instances.attr,
 	NULL,
 };
 
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index b6e048e1045f..12d42aa30f81 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -70,7 +70,8 @@ struct mdev_parent_ops {
 	const struct attribute_group **mdev_attr_groups;
 	struct attribute_group **supported_type_groups;
 
-	int     (*create)(struct kobject *kobj, struct mdev_device *mdev);
+	int     (*create)(struct kobject *kobj, struct mdev_device *mdev,
+			  unsigned int instances);
 	int     (*remove)(struct mdev_device *mdev);
 	int     (*open)(struct mdev_device *mdev);
 	void    (*release)(struct mdev_device *mdev);
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 2960e26c6ea4..8b2a9e98c587 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -432,7 +432,8 @@ static int mbochs_reset(struct mdev_device *mdev)
 	return 0;
 }
 
-static int mbochs_create(struct kobject *kobj, struct mdev_device *mdev)
+static int mbochs_create(struct kobject *kobj, struct mdev_device *mdev,
+			 unsigned int instances)
 {
 	const struct mbochs_type *type = mbochs_find_type(kobj);
 	struct device *dev = mdev_dev(mdev);
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index 96e7969c473a..0ec48ea5225a 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -226,7 +226,8 @@ static int mdpy_reset(struct mdev_device *mdev)
 	return 0;
 }
 
-static int mdpy_create(struct kobject *kobj, struct mdev_device *mdev)
+static int mdpy_create(struct kobject *kobj, struct mdev_device *mdev,
+		       unsigned int instances)
 {
 	const struct mdpy_type *type = mdpy_find_type(kobj);
 	struct device *dev = mdev_dev(mdev);
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 7abb79d8313d..ff2eaffa1155 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -727,7 +727,8 @@ static ssize_t mdev_access(struct mdev_device *mdev, char *buf, size_t count,
 	return ret;
 }
 
-int mtty_create(struct kobject *kobj, struct mdev_device *mdev)
+int mtty_create(struct kobject *kobj, struct mdev_device *mdev,
+		unsigned int instances)
 {
 	struct mdev_state *mdev_state;
 	char name[MTTY_STRING_LEN];
