You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/05/20 13:51:30 UTC

[nuttx] branch master updated: openamp: decoupling the transport layer and virtio device layer

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 1f4b71d576 openamp: decoupling the transport layer and virtio device layer
1f4b71d576 is described below

commit 1f4b71d5760f24a9870959e063ae94a06a2dfa64
Author: wangbowen6 <wa...@xiaomi.com>
AuthorDate: Sat May 20 18:41:15 2023 +0800

    openamp: decoupling the transport layer and virtio device layer
    
    Patch 17:
    virtio: follow virtio 1.2 spec, add more virtio status and device
    
    Patch 18:
    virtio: decoupling the transport layer and virtio device layer
    
    1. Add virtio device api to decouple the transport layer and virtio
       device layer.
    2. Move the vrings info and virtqueue allocation/free  to the
       remoteproc transport layer;
    3. Because 2, modify the rpmsg device also;
    
    Signed-off-by: wangbowen6 <wa...@xiaomi.com>
---
 ...ow-virtio-1.2-spec-add-more-virtio-status.patch |  93 +++
 ...upling-the-transport-layer-and-virtio-dev.patch | 635 +++++++++++++++++++++
 openamp/open-amp.defs                              |   2 +
 3 files changed, 730 insertions(+)

diff --git a/openamp/0017-virtio-follow-virtio-1.2-spec-add-more-virtio-status.patch b/openamp/0017-virtio-follow-virtio-1.2-spec-add-more-virtio-status.patch
new file mode 100644
index 0000000000..bc6eaef94a
--- /dev/null
+++ b/openamp/0017-virtio-follow-virtio-1.2-spec-add-more-virtio-status.patch
@@ -0,0 +1,93 @@
+From 61a7811f09b529341351c19ce1644b7e790daa5f Mon Sep 17 00:00:00 2001
+From: wangbowen6 <wa...@xiaomi.com>
+Date: Tue, 9 May 2023 11:30:09 +0800
+Subject: [PATCH 1/2] virtio: follow virtio 1.2 spec, add more virtio status
+ and device
+
+Signed-off-by: wangbowen6 <wa...@xiaomi.com>
+---
+ lib/include/openamp/virtio.h | 37 ++++++++++++++++++++++++++----------
+ lib/virtio/virtio.c          | 14 ++++++++++++++
+ 2 files changed, 41 insertions(+), 10 deletions(-)
+
+diff --git a/lib/include/openamp/virtio.h open-amp/lib/include/openamp/virtio.h
+index 0303a5b..3001a06 100644
+--- a/lib/include/openamp/virtio.h
++++ open-amp/lib/include/openamp/virtio.h
+@@ -15,21 +15,38 @@ extern "C" {
+ #endif
+ 
+ /* VirtIO device IDs. */
+-#define VIRTIO_ID_NETWORK    0x01UL
+-#define VIRTIO_ID_BLOCK      0x02UL
+-#define VIRTIO_ID_CONSOLE    0x03UL
+-#define VIRTIO_ID_ENTROPY    0x04UL
+-#define VIRTIO_ID_BALLOON    0x05UL
+-#define VIRTIO_ID_IOMEMORY   0x06UL
+-#define VIRTIO_ID_RPMSG      0x07UL /* remote processor messaging */
+-#define VIRTIO_ID_SCSI       0x08UL
+-#define VIRTIO_ID_9P         0x09UL
+-#define VIRTIO_DEV_ANY_ID    (-1)UL
++#define VIRTIO_ID_NETWORK      1UL
++#define VIRTIO_ID_BLOCK        2UL
++#define VIRTIO_ID_CONSOLE      3UL
++#define VIRTIO_ID_ENTROPY      4UL
++#define VIRTIO_ID_BALLOON      5UL
++#define VIRTIO_ID_IOMEMORY     6UL
++#define VIRTIO_ID_RPMSG        7UL /* remote processor messaging */
++#define VIRTIO_ID_SCSI         8UL
++#define VIRTIO_ID_9P           9UL
++#define VIRTIO_ID_RPROC_SERIAL 11UL
++#define VIRTIO_ID_GPU          16UL
++#define VIRTIO_ID_INPUT        18UL
++#define VIRTIO_ID_VSOCK        19UL
++#define VIRTIO_ID_CRYPTO       20UL
++#define VIRTIO_ID_IOMMU        23UL
++#define VIRTIO_ID_MEM          24UL
++#define VIRTIO_ID_SOUND        25UL
++#define VIRTIO_ID_FS           26UL
++#define VIRTIO_ID_PMEM         27UL
++#define VIRTIO_ID_RPMB         28UL
++#define VIRTIO_ID_SCMI         32UL
++#define VIRTIO_ID_I2C_ADAPTER  34UL
++#define VIRTIO_ID_BT           40UL
++#define VIRTIO_ID_GPIO         41UL
++#define VIRTIO_DEV_ANY_ID      -1UL
+ 
+ /* Status byte for guest to report progress. */
++#define VIRTIO_CONFIG_STATUS_RESET     0x00
+ #define VIRTIO_CONFIG_STATUS_ACK       0x01
+ #define VIRTIO_CONFIG_STATUS_DRIVER    0x02
+ #define VIRTIO_CONFIG_STATUS_DRIVER_OK 0x04
++#define VIRTIO_CONFIG_FEATURES_OK      0x08
+ #define VIRTIO_CONFIG_STATUS_NEEDS_RESET 0x40
+ #define VIRTIO_CONFIG_STATUS_FAILED    0x80
+ 
+diff --git a/lib/virtio/virtio.c open-amp/lib/virtio/virtio.c
+index d205784..d25aec3 100644
+--- a/lib/virtio/virtio.c
++++ open-amp/lib/virtio/virtio.c
+@@ -26,6 +26,20 @@ static const struct virtio_ident {
+ 	VIRTIO_ID_IOMEMORY, "IOMemory"}, {
+ 	VIRTIO_ID_SCSI, "SCSI"}, {
+ 	VIRTIO_ID_9P, "9P Transport"}, {
++	VIRTIO_ID_GPU, "GPU"}, {
++	VIRTIO_ID_INPUT, "Input"}, {
++	VIRTIO_ID_VSOCK, "Vsock Transport"}, {
++	VIRTIO_ID_CRYPTO, "Crypto"}, {
++	VIRTIO_ID_IOMMU, "IOMMU"}, {
++	VIRTIO_ID_MEM, "Memory"}, {
++	VIRTIO_ID_SOUND, "Sound"}, {
++	VIRTIO_ID_FS, "File System"}, {
++	VIRTIO_ID_PMEM, "Pmem"}, {
++	VIRTIO_ID_RPMB, "RPMB"}, {
++	VIRTIO_ID_SCMI, "SCMI"}, {
++	VIRTIO_ID_I2C_ADAPTER, "I2C Adapter"}, {
++	VIRTIO_ID_BT, "Bluetooth"}, {
++	VIRTIO_ID_GPIO, "GPIO" }, {
+ 	0, NULL}
+ };
+ 
+-- 
+2.25.1
+
diff --git a/openamp/0018-virtio-decoupling-the-transport-layer-and-virtio-dev.patch b/openamp/0018-virtio-decoupling-the-transport-layer-and-virtio-dev.patch
new file mode 100644
index 0000000000..77068e8eab
--- /dev/null
+++ b/openamp/0018-virtio-decoupling-the-transport-layer-and-virtio-dev.patch
@@ -0,0 +1,635 @@
+From 3ed768a2ce3b35e64c56cd69eb48e4436bdc4c12 Mon Sep 17 00:00:00 2001
+From: wangbowen6 <wa...@xiaomi.com>
+Date: Tue, 9 May 2023 12:53:21 +0800
+Subject: [PATCH 2/2] virtio: decoupling the transport layer and virtio device
+ layer
+
+1. Add virtio device api to decouple the transport layer and virtio
+   device layer.
+2. Move the vrings info and virtqueue allocation/free  to the
+   remoteproc transport layer;
+3. Because 2, modify the rpmsg device also;
+
+Change-Id: Ideb5fc388dd1626ce4ac1efd4c5120863918057b
+Signed-off-by: wangbowen6 <wa...@xiaomi.com>
+---
+ lib/include/openamp/rpmsg_virtio.h |  10 +-
+ lib/include/openamp/virtio.h       | 128 +++++++++++++++++++-
+ lib/remoteproc/remoteproc.c        |  32 -----
+ lib/remoteproc/remoteproc_virtio.c | 188 +++++++++++++++++++++--------
+ lib/rpmsg/rpmsg_virtio.c           |  29 ++++-
+ lib/virtio/virtio.c                |  40 ------
+ 6 files changed, 293 insertions(+), 134 deletions(-)
+
+diff --git a/lib/include/openamp/rpmsg_virtio.h open-amp/lib/include/openamp/rpmsg_virtio.h
+index bdc6cc6..e2d166f 100644
+--- a/lib/include/openamp/rpmsg_virtio.h
++++ open-amp/lib/include/openamp/rpmsg_virtio.h
+@@ -144,8 +144,14 @@ rpmsg_virtio_create_virtqueues(struct rpmsg_virtio_device *rvdev,
+ 			       const char *names[],
+ 			       vq_callback *callbacks)
+ {
+-	return virtio_create_virtqueues(rvdev->vdev, flags, nvqs, names,
+-					callbacks);
++	return rvdev->vdev->func->create_virtqueues(rvdev->vdev, flags, nvqs,
++						    names, callbacks);
++}
++
++static inline void
++rpmsg_virtio_delete_virtqueues(struct rpmsg_virtio_device *rvdev)
++{
++	rvdev->vdev->func->delete_virtqueues(rvdev->vdev);
+ }
+ 
+ static inline int
+diff --git a/lib/include/openamp/virtio.h open-amp/lib/include/openamp/virtio.h
+index 3001a06..fb68c19 100644
+--- a/lib/include/openamp/virtio.h
++++ open-amp/lib/include/openamp/virtio.h
+@@ -161,6 +161,11 @@ void virtio_describe(struct virtio_device *dev, const char *msg,
+  */
+ 
+ struct virtio_dispatch {
++	int (*create_virtqueues)(struct virtio_device *vdev,
++				 unsigned int flags,
++				 unsigned int nvqs, const char *names[],
++				 vq_callback callbacks[]);
++	void (*delete_virtqueues)(struct virtio_device *vdev);
+ 	uint8_t (*get_status)(struct virtio_device *dev);
+ 	void (*set_status)(struct virtio_device *dev, uint8_t status);
+ 	uint32_t (*get_features)(struct virtio_device *dev);
+@@ -182,9 +187,126 @@ struct virtio_dispatch {
+ 	int (*notify_wait)(struct virtio_device *dev, struct virtqueue *vq);
+ };
+ 
+-int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
+-			     unsigned int nvqs, const char *names[],
+-			     vq_callback callbacks[]);
++/**
++ * @brief Create the virtio device virtqueue.
++ *
++ * @param vdev		Pointer to virtio device structure.
++ * @param flags		Create flag.
++ * @param nvqs		The virtqueue number.
++ * @param names		Virtqueue names.
++ * @param callbacks	Virtqueue callback functions.
++ *
++ * @return Pointer to virtio device structure.
++ */
++static inline int virtio_create_virtqueues(struct virtio_device *vdev,
++					   unsigned int flags,
++					   unsigned int nvqs,
++					   const char *names[],
++					   vq_callback callbacks[])
++{
++	return vdev->func->create_virtqueues(vdev, flags, nvqs, names,
++					     callbacks);
++}
++
++/**
++ * @brief Delete the virtio device virtqueue.
++ *
++ * @param vdev	Pointer to virtio device structure.
++ *
++ * @return pointer to virtio device structure.
++ */
++static inline void virtio_delete_virtqueues(struct virtio_device *vdev)
++{
++	return vdev->func->delete_virtqueues(vdev);
++}
++
++/**
++ * @brief Retrieve device status.
++ *
++ * @param dev	Pointer to device structure.
++ *
++ * @return status of the device.
++ */
++static inline uint8_t virtio_get_status(struct virtio_device *vdev)
++{
++	return vdev->func->get_status(vdev);
++}
++
++/**
++ * @brief Set device status.
++ *
++ * @param dev		Pointer to device structure.
++ * @param status	Value to be set as device status.
++ */
++static inline void virtio_set_status(struct virtio_device *vdev,
++				     uint8_t status)
++{
++	vdev->func->set_status(vdev, status);
++}
++
++/**
++ * @brief Retrieve configuration data from the device.
++ *
++ * @param dev		Pointer to device structure.
++ * @param offset	Offset of the data within the configuration area.
++ * @param dst		Address of the buffer that will hold the data.
++ * @param len		Length of the data to be retrieved.
++ */
++static inline void virtio_read_config(struct virtio_device *vdev,
++				      uint32_t offset, void *dst,
++				      int length)
++{
++	vdev->func->read_config(vdev, offset, dst, length);
++}
++
++/**
++ * @brief Write configuration data to the device.
++ *
++ * @param dev		Pointer to device structure.
++ * @param offset	Offset of the data within the configuration area.
++ * @param src		Address of the buffer that holds the data to write.
++ * @param len		Length of the data to be written.
++ */
++static inline void virtio_write_config(struct virtio_device *vdev,
++				       uint32_t offset, void *src,
++				       int length)
++{
++	vdev->func->write_config(vdev, offset, src, length);
++}
++
++/**
++ * @brief Get the virtio device features.
++ *
++ * @param[in] dev	Pointer to device structure.
++ *
++ * @return Features supported by both the driver and the device as a bitfield.
++ */
++static inline uint32_t virtio_get_features(struct virtio_device *vdev)
++{
++	return vdev->func->get_features(vdev);
++}
++
++/**
++ * @brief Set features supported by the VIRTIO driver.
++ *
++ * @param dev		Pointer to device structure.
++ * @param features	Features supported by the driver as a bitfield.
++ */
++static inline void virtio_set_features(struct virtio_device *vdev,
++				       uint32_t features)
++{
++	return vdev->func->set_features(vdev, features);
++}
++
++/**
++ * @brief Reset virtio device.
++ *
++ * @param vdev	Pointer to virtio_device structure.
++ */
++static inline void virtio_reset_device(struct virtio_device *vdev)
++{
++	vdev->func->reset_device(vdev);
++}
+ 
+ #if defined __cplusplus
+ }
+diff --git a/lib/remoteproc/remoteproc.c open-amp/lib/remoteproc/remoteproc.c
+index 001b11b..5a38fe1 100644
+--- a/lib/remoteproc/remoteproc.c
++++ open-amp/lib/remoteproc/remoteproc.c
+@@ -921,7 +921,6 @@ remoteproc_create_virtio(struct remoteproc *rproc,
+ 	struct remoteproc_virtio *rpvdev;
+ 	size_t vdev_rsc_offset;
+ 	unsigned int notifyid;
+-	unsigned int num_vrings, i;
+ 	struct metal_list *node;
+ 
+ #ifdef VIRTIO_DRIVER_ONLY
+@@ -969,39 +968,8 @@ remoteproc_create_virtio(struct remoteproc *rproc,
+ 	rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
+ 	rpvdev->notify_wait = remoteproc_virtio_notify_wait;
+ 	metal_list_add_tail(&rproc->vdevs, &rpvdev->node);
+-	num_vrings = vdev_rsc->num_of_vrings;
+-
+-	/* set the notification id for vrings */
+-	for (i = 0; i < num_vrings; i++) {
+-		struct fw_rsc_vdev_vring *vring_rsc;
+-		metal_phys_addr_t da;
+-		unsigned int num_descs, align;
+-		struct metal_io_region *io;
+-		void *va;
+-		size_t size;
+-		int ret;
+-
+-		vring_rsc = &vdev_rsc->vring[i];
+-		notifyid = vring_rsc->notifyid;
+-		da = vring_rsc->da;
+-		num_descs = vring_rsc->num;
+-		align = vring_rsc->align;
+-		size = vring_size(num_descs, align);
+-		va = remoteproc_mmap(rproc, NULL, &da, size, 0, &io);
+-		if (!va)
+-			goto err1;
+-		ret = rproc_virtio_init_vring(vdev, i, notifyid,
+-					      va, io, num_descs, align);
+-		if (ret)
+-			goto err1;
+-	}
+ 	metal_mutex_release(&rproc->lock);
+ 	return vdev;
+-
+-err1:
+-	remoteproc_remove_virtio(rproc, vdev);
+-	metal_mutex_release(&rproc->lock);
+-	return NULL;
+ }
+ 
+ void remoteproc_remove_virtio(struct remoteproc *rproc,
+diff --git a/lib/remoteproc/remoteproc_virtio.c open-amp/lib/remoteproc/remoteproc_virtio.c
+index 4375c4c..96767c1 100644
+--- a/lib/remoteproc/remoteproc_virtio.c
++++ open-amp/lib/remoteproc/remoteproc_virtio.c
+@@ -16,6 +16,139 @@
+ #include <metal/utilities.h>
+ #include <metal/alloc.h>
+ 
++static void rproc_virtio_delete_virtqueues(struct virtio_device *vdev)
++{
++	struct virtio_vring_info *vring_info;
++	unsigned int i;
++
++	if (vdev->vrings_info != NULL) {
++		for (i = 0; i < vdev->vrings_num; i++) {
++			vring_info = &vdev->vrings_info[i];
++			if (vring_info->vq != NULL) {
++				virtqueue_free(vring_info->vq);
++			}
++		}
++
++		metal_free_memory(vdev->vrings_info);
++	}
++}
++
++static int rproc_virtio_create_virtqueue(struct virtio_device *vdev,
++					 unsigned int flags,
++					 unsigned int i,
++					 const char *name,
++					 vq_callback callback)
++{
++	struct remoteproc_virtio *rpvdev;
++	struct fw_rsc_vdev_vring *vring_rsc;
++	struct fw_rsc_vdev *vdev_rsc;
++	struct remoteproc *rproc;
++	struct virtio_vring_info *vring_info;
++	struct vring_alloc_info *vring_alloc;
++	struct metal_io_region *io;
++	metal_phys_addr_t da;
++	size_t vringsize;
++	void *va;
++	int ret;
++
++	/* Get remoteproc virtio device */
++	rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
++
++	/* Get the remoteproc */
++	rproc = rpvdev->priv;
++
++	/* Get the rsc table */
++	vdev_rsc = rpvdev->vdev_rsc;
++	vring_rsc = &vdev_rsc->vring[i];
++
++	/*
++	 * Initialize the vring information according to the vring resource
++	 * table.
++	 */
++	da = vring_rsc->da;
++	vringsize = vring_size(vring_rsc->num, vring_rsc->align);
++	va = remoteproc_mmap(rproc, NULL, &da, vringsize, 0, &io);
++	if (!va) {
++		return ERROR_VQUEUE_INVLD_PARAM;
++	}
++
++	ret = rproc_virtio_init_vring(vdev, i, vring_rsc->notifyid, va, io,
++				      vring_rsc->num, vring_rsc->align);
++	if (ret) {
++		return ret;
++	}
++
++	/* Get the vring information */
++	vring_info = &vdev->vrings_info[i];
++	vring_alloc = &vring_info->info;
++
++	/* Alloc the virtqueue and init it */
++	vring_info->vq = virtqueue_allocate(vring_alloc->num_descs);
++	if (!vring_info->vq) {
++		return ERROR_NO_MEM;
++	}
++
++#ifndef VIRTIO_DEVICE_ONLY
++	if (vdev->role == VIRTIO_DEV_DRIVER) {
++		size_t offset = metal_io_virt_to_offset(vring_info->io,
++							vring_alloc->vaddr);
++		metal_io_block_set(vring_info->io, offset, 0, vringsize);
++	}
++#endif
++	ret = virtqueue_create(vdev, i, name, vring_alloc, callback,
++			       vdev->func->notify, vring_info->vq);
++	if (ret) {
++		return ret;
++	}
++	return 0;
++}
++
++static int rproc_virtio_create_virtqueues(struct virtio_device *vdev,
++					  unsigned int flags,
++					  unsigned int nvqs,
++					  const char *names[],
++					  vq_callback callbacks[])
++{
++	struct remoteproc_virtio *rpvdev;
++	struct virtio_vring_info *vrings_info;
++	struct fw_rsc_vdev *vdev_rsc;
++	unsigned int i;
++	int ret;
++	(void)flags;
++
++	/* Get remoteproc virtio device, rsc table, remoteproc */
++	rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
++	vdev_rsc = rpvdev->vdev_rsc;
++
++	/* Check vrings number */
++	if (nvqs > vdev_rsc->num_of_vrings)
++		return ERROR_VQUEUE_INVLD_PARAM;
++
++	/* Alloc vrings info for the virtio device */
++	vrings_info = metal_allocate_memory(sizeof(*vrings_info) * nvqs);
++	if (!vrings_info) {
++		return ERROR_NO_MEM;
++	}
++
++	memset(vrings_info, 0, sizeof(*vrings_info) * nvqs);
++	vdev->vrings_info = vrings_info;
++	vdev->vrings_num = nvqs;
++
++	/* set the notification id for vrings */
++	for (i = 0; i < nvqs; i++) {
++		ret = rproc_virtio_create_virtqueue(vdev, flags, i, names[i],
++						    callbacks[i]);
++		if (ret) {
++			goto err;
++		}
++	}
++	return 0;
++
++err:
++	rproc_virtio_delete_virtqueues(vdev);
++	return ret;
++}
++
+ static void rproc_virtio_virtqueue_notify(struct virtqueue *vq)
+ {
+ 	struct remoteproc_virtio *rpvdev;
+@@ -148,7 +281,7 @@ static void rproc_virtio_read_config(struct virtio_device *vdev,
+ 
+ 	rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
+ 	vdev_rsc = rpvdev->vdev_rsc;
+-	config = (char *)(&vdev_rsc->vring[vdev->vrings_num]);
++	config = (char *)(&vdev_rsc->vring[vdev_rsc->num_of_vrings]);
+ 	io = rpvdev->vdev_rsc_io;
+ 
+ 	if (offset + length <= vdev_rsc->config_len)
+@@ -168,7 +301,7 @@ static void rproc_virtio_write_config(struct virtio_device *vdev,
+ 
+ 	rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
+ 	vdev_rsc = rpvdev->vdev_rsc;
+-	config = (char *)(&vdev_rsc->vring[vdev->vrings_num]);
++	config = (char *)(&vdev_rsc->vring[vdev_rsc->num_of_vrings]);
+ 	io = rpvdev->vdev_rsc_io;
+ 
+ 	if (offset + length <= vdev_rsc->config_len) {
+@@ -188,6 +321,8 @@ static void rproc_virtio_reset_device(struct virtio_device *vdev)
+ #endif
+ 
+ static const struct virtio_dispatch remoteproc_virtio_dispatch_funcs = {
++	.create_virtqueues = rproc_virtio_create_virtqueues,
++	.delete_virtqueues = rproc_virtio_delete_virtqueues,
+ 	.get_status = rproc_virtio_get_status,
+ 	.get_features = rproc_virtio_get_features,
+ 	.read_config = rproc_virtio_read_config,
+@@ -215,44 +350,16 @@ rproc_virtio_create_vdev(unsigned int role, unsigned int notifyid,
+ 			 virtio_dev_reset_cb rst_cb)
+ {
+ 	struct remoteproc_virtio *rpvdev;
+-	struct virtio_vring_info *vrings_info;
+ 	struct fw_rsc_vdev *vdev_rsc = rsc;
+ 	struct virtio_device *vdev;
+-	unsigned int num_vrings = vdev_rsc->num_of_vrings;
+-	unsigned int i;
+ 
+ 	rpvdev = metal_allocate_memory(sizeof(*rpvdev));
+ 	if (!rpvdev)
+ 		return NULL;
+-	vrings_info = metal_allocate_memory(sizeof(*vrings_info) * num_vrings);
+-	if (!vrings_info)
+-		goto err0;
+ 	memset(rpvdev, 0, sizeof(*rpvdev));
+-	memset(vrings_info, 0, sizeof(*vrings_info));
+ 	vdev = &rpvdev->vdev;
+-
+-	for (i = 0; i < num_vrings; i++) {
+-		struct virtqueue *vq;
+-#ifndef VIRTIO_DEVICE_ONLY
+-		struct fw_rsc_vdev_vring *vring_rsc;
+-#endif
+-		unsigned int num_extra_desc = 0;
+-
+-#ifndef VIRTIO_DEVICE_ONLY
+-		vring_rsc = &vdev_rsc->vring[i];
+-		if (role == VIRTIO_DEV_DRIVER) {
+-			num_extra_desc = vring_rsc->num;
+-		}
+-#endif
+-		vq = virtqueue_allocate(num_extra_desc);
+-		if (!vq)
+-			goto err1;
+-		vrings_info[i].vq = vq;
+-	}
+-
+ 	rpvdev->notify = notify;
+ 	rpvdev->priv = priv;
+-	vdev->vrings_info = vrings_info;
+ 	/* Assuming the shared memory has been mapped and registered if
+ 	 * necessary
+ 	 */
+@@ -262,7 +369,6 @@ rproc_virtio_create_vdev(unsigned int role, unsigned int notifyid,
+ 	vdev->notifyid = notifyid;
+ 	vdev->role = role;
+ 	vdev->reset_cb = rst_cb;
+-	vdev->vrings_num = num_vrings;
+ 	vdev->func = &remoteproc_virtio_dispatch_funcs;
+ 
+ #ifndef VIRTIO_DEVICE_ONLY
+@@ -274,35 +380,15 @@ rproc_virtio_create_vdev(unsigned int role, unsigned int notifyid,
+ #endif
+ 
+ 	return &rpvdev->vdev;
+-
+-err1:
+-	for (i = 0; i < num_vrings; i++) {
+-		if (vrings_info[i].vq)
+-			metal_free_memory(vrings_info[i].vq);
+-	}
+-	metal_free_memory(vrings_info);
+-err0:
+-	metal_free_memory(rpvdev);
+-	return NULL;
+ }
+ 
+ void rproc_virtio_remove_vdev(struct virtio_device *vdev)
+ {
+ 	struct remoteproc_virtio *rpvdev;
+-	unsigned int i;
+ 
+ 	if (!vdev)
+ 		return;
+ 	rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
+-	for (i = 0; i < vdev->vrings_num; i++) {
+-		struct virtqueue *vq;
+-
+-		vq = vdev->vrings_info[i].vq;
+-		if (vq)
+-			metal_free_memory(vq);
+-	}
+-	if (vdev->vrings_info)
+-		metal_free_memory(vdev->vrings_info);
+ 	metal_free_memory(rpvdev);
+ }
+ 
+diff --git a/lib/rpmsg/rpmsg_virtio.c open-amp/lib/rpmsg/rpmsg_virtio.c
+index 2f38faa..b30eccc 100644
+--- a/lib/rpmsg/rpmsg_virtio.c
++++ open-amp/lib/rpmsg/rpmsg_virtio.c
+@@ -821,8 +821,6 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
+ 		vq_names[1] = "tx_vq";
+ 		callback[0] = rpmsg_virtio_rx_callback;
+ 		callback[1] = rpmsg_virtio_tx_callback;
+-		rvdev->rvq  = vdev->vrings_info[0].vq;
+-		rvdev->svq  = vdev->vrings_info[1].vq;
+ 	}
+ #endif /*!VIRTIO_DEVICE_ONLY*/
+ 
+@@ -833,8 +831,6 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
+ 		vq_names[1] = "rx_vq";
+ 		callback[0] = rpmsg_virtio_tx_callback;
+ 		callback[1] = rpmsg_virtio_rx_callback;
+-		rvdev->rvq  = vdev->vrings_info[1].vq;
+-		rvdev->svq  = vdev->vrings_info[0].vq;
+ 	}
+ #endif /*!VIRTIO_DRIVER_ONLY*/
+ 	rvdev->shbuf_io = shm_io;
+@@ -846,6 +842,21 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
+ 	if (status != RPMSG_SUCCESS)
+ 		return status;
+ 
++	/* Create virtqueue success, assign back the virtqueue */
++#ifndef VIRTIO_DEVICE_ONLY
++	if (role == RPMSG_HOST) {
++		rvdev->rvq  = vdev->vrings_info[0].vq;
++		rvdev->svq  = vdev->vrings_info[1].vq;
++	}
++#endif /*!VIRTIO_DEVICE_ONLY*/
++
++#ifndef VIRTIO_DRIVER_ONLY
++	if (role == RPMSG_REMOTE) {
++		rvdev->rvq  = vdev->vrings_info[1].vq;
++		rvdev->svq  = vdev->vrings_info[0].vq;
++	}
++#endif /*!VIRTIO_DRIVER_ONLY*/
++
+ 	/*
+ 	 * Suppress "tx-complete" interrupts
+ 	 * since send method use busy loop when buffer pool exhaust
+@@ -873,7 +884,8 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
+ 					rvdev->config.r2h_buf_size);
+ 
+ 			if (!buffer) {
+-				return RPMSG_ERR_NO_BUFF;
++				status = RPMSG_ERR_NO_BUFF;
++				goto err;
+ 			}
+ 
+ 			vqbuf.buf = buffer;
+@@ -887,7 +899,7 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
+ 						     buffer);
+ 
+ 			if (status != RPMSG_SUCCESS) {
+-				return status;
++				goto err;
+ 			}
+ 		}
+ 	}
+@@ -912,6 +924,10 @@ int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
+ #endif /*!VIRTIO_DEVICE_ONLY*/
+ 
+ 	return status;
++
++err:
++	rpmsg_virtio_delete_virtqueues(rvdev);
++	return status;
+ }
+ 
+ void rpmsg_deinit_vdev(struct rpmsg_virtio_device *rvdev)
+@@ -931,6 +947,7 @@ void rpmsg_deinit_vdev(struct rpmsg_virtio_device *rvdev)
+ 		rvdev->rvq = 0;
+ 		rvdev->svq = 0;
+ 
++		rpmsg_virtio_delete_virtqueues(rvdev);
+ 		metal_mutex_deinit(&rdev->lock);
+ 	}
+ }
+diff --git a/lib/virtio/virtio.c open-amp/lib/virtio/virtio.c
+index d25aec3..e67e97d 100644
+--- a/lib/virtio/virtio.c
++++ open-amp/lib/virtio/virtio.c
+@@ -96,43 +96,3 @@ void virtio_describe(struct virtio_device *dev, const char *msg,
+ 	/* TODO: Not used currently - keeping it for future use*/
+ 	virtio_feature_name(0, desc);
+ }
+-
+-int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
+-			     unsigned int nvqs, const char *names[],
+-			     vq_callback callbacks[])
+-{
+-	struct virtio_vring_info *vring_info;
+-	struct vring_alloc_info *vring_alloc;
+-	unsigned int num_vrings, i;
+-	int ret;
+-	(void)flags;
+-
+-	num_vrings = vdev->vrings_num;
+-	if (nvqs > num_vrings)
+-		return ERROR_VQUEUE_INVLD_PARAM;
+-	/* Initialize virtqueue for each vring */
+-	for (i = 0; i < nvqs; i++) {
+-		vring_info = &vdev->vrings_info[i];
+-
+-		vring_alloc = &vring_info->info;
+-#ifndef VIRTIO_DEVICE_ONLY
+-		if (vdev->role == VIRTIO_DEV_DRIVER) {
+-			size_t offset;
+-			struct metal_io_region *io = vring_info->io;
+-
+-			offset = metal_io_virt_to_offset(io,
+-							 vring_alloc->vaddr);
+-			metal_io_block_set(io, offset, 0,
+-					   vring_size(vring_alloc->num_descs,
+-						      vring_alloc->align));
+-		}
+-#endif
+-		ret = virtqueue_create(vdev, i, names[i], vring_alloc,
+-				       callbacks[i], vdev->func->notify,
+-				       vring_info->vq);
+-		if (ret)
+-			return ret;
+-	}
+-	return 0;
+-}
+-
+-- 
+2.25.1
+
diff --git a/openamp/open-amp.defs b/openamp/open-amp.defs
index e9430aed72..e7e70fd56f 100644
--- a/openamp/open-amp.defs
+++ b/openamp/open-amp.defs
@@ -51,6 +51,8 @@ open-amp.zip:
 	$(Q) patch -p0 < 0014-rpmsg-add-cache-flash-when-hold-rx-buffer.patch
 	$(Q) patch -p0 < 0015-rpmsg-do-cache_invalidate-when-real-data-returned.patch
 	$(Q) patch -p0 < 0016-openamp-add-new-API-rpmsg_virtio_get_rxbuffer_size.patch
+	$(Q) patch -p0 < 0017-virtio-follow-virtio-1.2-spec-add-more-virtio-status.patch
+	$(Q) patch -p0 < 0018-virtio-decoupling-the-transport-layer-and-virtio-dev.patch