Hi Viresh.
One small point after on BUSY handling.
It need some time to get how you define which method to use to transfer messages. There might be something to rework in the future to make that a bit more straight forward as you use the "generic send" only once to send the version message so it might be better to open code it directly in there,
On 22 Jul 2025, at 11:46, Viresh Kumar viresh.kumar@linaro.org wrote:
Introduce a virtio-msg bus implementation based on the Arm FF-A (Firmware Framework for Arm) communication interface.
This bus enables virtio-msg transport over secure channels typically used between the normal world OS and a secure OS or hypervisor. It leverages the standardized FF-A interface to exchange messages with a remote backend service.
The implementation integrates with the core virtio-msg transport and uses FF-A service calls to transmit and receive messages.
Optionally, this bus supports attaching a reserved-memory region to constrain DMA-coherent and streaming DMA allocations to a well-defined contiguous area. This memory can be pre-mapped on the remote side, reducing runtime overhead and preventing accidental sharing of unrelated pages due to page-granularity mapping.
To enable reserved memory, the following device tree node should be defined (the node must be named "vmsgffa"):
reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges;
vmsgffa@100000000 { compatible = "restricted-dma-pool"; reg = <0x00000001 0x00000000 0x0 0x00400000>; /* 4 MiB */ }; };
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org
drivers/virtio/Kconfig | 12 +- drivers/virtio/Makefile | 1 + drivers/virtio/virtio_msg_ffa.c | 501 ++++++++++++++++++++++++++++ include/uapi/linux/virtio_msg_ffa.h | 94 ++++++ 4 files changed, 607 insertions(+), 1 deletion(-) create mode 100644 drivers/virtio/virtio_msg_ffa.c create mode 100644 include/uapi/linux/virtio_msg_ffa.h
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index a86025c9e008..683152477e3f 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -176,7 +176,8 @@ config VIRTIO_MSG select VIRTIO help This enables support for Virtio message transport. This option is
- selected by any driver which implements the virtio message bus.
- selected by any driver which implements the virtio message bus, such
- as VIRTIO_MSG_FFA.
config VIRTIO_MSG_USER tristate "Userspace interface for virtio message transport" @@ -186,6 +187,15 @@ config VIRTIO_MSG_USER can be used to read / write messages over virtio-msg transport from userspace.
+config VIRTIO_MSG_FFA
- tristate "FF-A bus driver for virtio message transport"
- depends on ARM_FFA_TRANSPORT
- select VIRTIO_MSG
- help
- This implements a Virtio message bus based on ARM FF-A protocol.
- If unsure, say N.
config VIRTIO_DMA_SHARED_BUFFER tristate depends on DMA_SHARED_BUFFER diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile index 5b664c5f5f25..96ec0a9c4a7a 100644 --- a/drivers/virtio/Makefile +++ b/drivers/virtio/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o virtio_msg_transport-y := virtio_msg.o virtio_msg_transport-$(CONFIG_VIRTIO_MSG_USER) += virtio_msg_user.o obj-$(CONFIG_VIRTIO_MSG) += virtio_msg_transport.o +obj-$(CONFIG_VIRTIO_MSG_FFA) += virtio_msg_ffa.o obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o diff --git a/drivers/virtio/virtio_msg_ffa.c b/drivers/virtio/virtio_msg_ffa.c new file mode 100644 index 000000000000..8c7d43ba2f5a --- /dev/null +++ b/drivers/virtio/virtio_msg_ffa.c @@ -0,0 +1,501 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- FF-A bus implementation for Virtio message transport.
- Copyright (C) 2025 Google LLC and Linaro.
- Viresh Kumar viresh.kumar@linaro.org
- This implements the FF-A (Arm Firmware Framework) bus for Virtio msg
- transport.
- */
+#define pr_fmt(fmt) "virtio-msg-ffa: " fmt
+#include <linux/arm_ffa.h> +#include <linux/err.h> +#include <linux/module.h> +#include <linux/of_reserved_mem.h> +#include <linux/pm.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/virtio.h> +#include <uapi/linux/virtio_msg_ffa.h>
+#include "virtio_msg.h"
+struct virtio_msg_indirect_data {
- struct completion completion;
- struct virtio_msg *response;
+};
+struct virtio_msg_device_data {
- struct virtio_msg_device vmdev;
- struct virtio_msg_indirect_data idata;
+};
+/* Represents FF-A corresponding to a partition */ +struct virtio_msg_ffa_device {
- struct ffa_device *ffa_dev;
- struct reserved_mem *rmem;
- struct virtio_msg_indirect_data idata;
- struct virtio_msg_device_data *vmdevs;
- int (*send)(struct virtio_msg_ffa_device *vmfdev,
- struct virtio_msg *request,
- struct virtio_msg *response,
- struct virtio_msg_indirect_data *idata);
- int vmdev_count;
- u16 msg_size;
+};
+#define to_vmdevdata(_vmdev) \
- container_of(_vmdev, struct virtio_msg_device_data, vmdev)
+#define to_vmfdev(_vmdev) ((struct virtio_msg_ffa_device *)(_vmdev)->bus_data)
+static int vmsg_ffa_send_direct(struct virtio_msg_ffa_device *vmfdev,
- struct virtio_msg *request,
- struct virtio_msg *response,
- struct virtio_msg_indirect_data *idata_unused)
+{
- struct ffa_device *ffa_dev = vmfdev->ffa_dev;
- struct ffa_send_direct_data2 ffa_data;
- int ret;
- memcpy(&ffa_data, request, request->msg_size);
- ret = ffa_dev->ops->msg_ops->sync_send_receive2(ffa_dev, &ffa_data);
- if (ret) {
- dev_dbg(&ffa_dev->dev,
- "Unable to send direct FF-A message: %d\n", ret);
- return ret;
- }
- if (response)
- memcpy(response, &ffa_data, vmfdev->msg_size);
- return 0;
+}
+static int vmsg_ffa_send_indirect(struct virtio_msg_ffa_device *vmfdev,
- struct virtio_msg *request,
- struct virtio_msg *response,
- struct virtio_msg_indirect_data *idata)
+{
- struct ffa_device *ffa_dev = vmfdev->ffa_dev;
- struct device *dev = &ffa_dev->dev;
- int ret;
- /*
- Store the response pointer in idata structure. This will be updated
- by vmsg_ffa_notifier_cb() later.
- */
- idata->response = response;
- ret = ffa_dev->ops->msg_ops->indirect_send(ffa_dev, request,
- request->msg_size);
- if (ret) {
- dev_err(dev, "Failed sending indirect FF-A message: %d\n", ret);
- return ret;
- }
Is the FF-A driver already looping on BUSY case ? If the rx buffer from the receiver is not available you will get a busy back and you will have to retry. Not sure if this should be handled in FF-A driver or in here though.
Cheers Bertrand
- /*
- Always wait for the operation to finish, otherwise we may start
- another operation while the previous one is still ongoing.
- */
- ret = wait_for_completion_interruptible_timeout(&idata->completion, 1000);
- if (ret < 0) {
- dev_err(dev, "Interrupted - waiting for a response: %d\n", ret);
- } else if (!ret) {
- dev_err(dev, "Timed out waiting for a response\n");
- ret = -ETIMEDOUT;
- } else {
- ret = 0;
- }
- return ret;
+}
+static int vmsg_ffa_send(struct virtio_msg_ffa_device *vmfdev,
- struct virtio_msg *request,
- struct virtio_msg *response,
- struct virtio_msg_indirect_data *idata)
+{
- int ret;
- /* Try direct messaging first, fallback to indirect */
- ret = vmsg_ffa_send_direct(vmfdev, request, response, idata);
- if (!ret) {
- vmfdev->send = vmsg_ffa_send_direct;
- return 0;
- }
- /* Fallback to indirect messaging */
- vmfdev->send = vmsg_ffa_send_indirect;
- return vmfdev->send(vmfdev, request, response, idata);
+}
+static struct virtio_msg_device * +find_vmdev(struct virtio_msg_ffa_device *vmfdev, u16 dev_id) +{
- int i;
- /* Find the device corresponding to a dev_id */
- for (i = 0; i < vmfdev->vmdev_count; i++) {
- if (vmfdev->vmdevs[i].vmdev.dev_id == dev_id)
- return &vmfdev->vmdevs[i].vmdev;
- }
- dev_err(&vmfdev->ffa_dev->dev, "Couldn't find matching vmdev: %d\n",
- dev_id);
- return NULL;
+}
+static void vmsg_ffa_notifier_cb(int notify_id, void *cb_data, void *buf) +{
- struct virtio_msg_ffa_device *vmfdev = cb_data;
- struct ffa_device *ffa_dev = vmfdev->ffa_dev;
- struct virtio_msg_indirect_data *idata;
- struct virtio_msg_device *vmdev;
- struct virtio_msg *vmsg = buf;
- /*
- We can either receive a response message (to a previously sent
- request), or an EVENT_USED request message.
- */
- if (vmsg->type & VIRTIO_MSG_TYPE_RESPONSE) {
- if (vmsg->type & VIRTIO_MSG_TYPE_BUS) {
- idata = &vmfdev->idata;
- } else {
- vmdev = find_vmdev(vmfdev, le16_to_cpu(vmsg->dev_id));
- if (!vmdev)
- return;
- idata = &to_vmdevdata(vmdev)->idata;
- }
- if (idata->response)
- memcpy(idata->response, vmsg, vmsg->msg_size);
- complete(&idata->completion);
- return;
- }
- /* Only support EVENT_USED virtio request messages */
- if (vmsg->type & VIRTIO_MSG_TYPE_BUS ||
- vmsg->msg_id != VIRTIO_MSG_EVENT_USED) {
- dev_err(&ffa_dev->dev, "Unsupported message received\n");
- return;
- }
- vmdev = find_vmdev(vmfdev, le16_to_cpu(vmsg->dev_id));
- if (!vmdev)
- return;
- virtio_msg_event(vmdev, vmsg);
+}
+static int vmsg_ffa_notify_setup(struct virtio_msg_ffa_device *vmfdev) +{
- struct ffa_device *ffa_dev = vmfdev->ffa_dev;
- int ret;
- ret = ffa_dev->ops->notifier_ops->fwk_notify_request(ffa_dev,
- &vmsg_ffa_notifier_cb, vmfdev, 0);
- if (ret)
- dev_err(&ffa_dev->dev, "Unable to request notifier: %d\n", ret);
- return ret;
+}
+static void vmsg_ffa_notify_cleanup(struct virtio_msg_ffa_device *vmfdev) +{
- struct ffa_device *ffa_dev = vmfdev->ffa_dev;
- int ret;
- ret = ffa_dev->ops->notifier_ops->fwk_notify_relinquish(ffa_dev, 0);
- if (ret)
- dev_err(&ffa_dev->dev, "Unable to relinquish notifier: %d\n", ret);
+}
+static int vmsg_ffa_bus_get_devices(struct virtio_msg_ffa_device *vmfdev,
- u16 *map, u16 *count)
+{
- u8 req_buf[VIRTIO_MSG_FFA_BUS_MSG_SIZE];
- u8 res_buf[VIRTIO_MSG_FFA_BUS_MSG_SIZE];
- struct virtio_msg *request = (struct virtio_msg *)&req_buf;
- struct virtio_msg *response = (struct virtio_msg *)&res_buf;
- struct bus_get_devices *req_payload = virtio_msg_payload(request);
- struct bus_get_devices_resp *res_payload = virtio_msg_payload(response);
- int ret;
- virtio_msg_prepare(request, VIRTIO_MSG_BUS_GET_DEVICES,
- sizeof(*req_payload));
- req_payload->offset = 0;
- req_payload->num = cpu_to_le16(0xFF);
- ret = vmfdev->send(vmfdev, request, response, &vmfdev->idata);
- if (ret < 0)
- return ret;
- *count = le16_to_cpu(res_payload->num);
- if (!*count)
- return -ENODEV;
- if (res_payload->offset != req_payload->offset)
- return -EINVAL;
- /* Support up to 16 devices for now */
- if (res_payload->next_offset)
- return -EINVAL;
- map[0] = res_payload->devices[0];
- map[1] = res_payload->devices[1];
- return 0;
+}
+static int vmsg_ffa_bus_version(struct virtio_msg_ffa_device *vmfdev) +{
- u8 req_buf[VIRTIO_MSG_FFA_BUS_MSG_SIZE];
- u8 res_buf[VIRTIO_MSG_FFA_BUS_MSG_SIZE];
- struct virtio_msg *request = (struct virtio_msg *)&req_buf;
- struct virtio_msg *response = (struct virtio_msg *)&res_buf;
- struct bus_ffa_version *req_payload = virtio_msg_payload(request);
- struct bus_ffa_version_resp *res_payload = virtio_msg_payload(response);
- u32 features;
- int ret;
- virtio_msg_prepare(request, VIRTIO_MSG_FFA_BUS_VERSION,
- sizeof(*req_payload));
- req_payload->driver_version = cpu_to_le32(VIRTIO_MSG_FFA_BUS_VERSION_1_0);
- req_payload->vmsg_revision = cpu_to_le32(VIRTIO_MSG_REVISION_1);
- req_payload->vmsg_features = cpu_to_le32(VIRTIO_MSG_FEATURES);
- req_payload->features = cpu_to_le32(VIRTIO_MSG_FFA_FEATURE_BOTH_SUPP);
- req_payload->area_num = cpu_to_le16(VIRTIO_MSG_FFA_AREA_ID_MAX);
- ret = vmfdev->send(vmfdev, request, response, &vmfdev->idata);
- if (ret < 0)
- return ret;
- if (le32_to_cpu(res_payload->device_version) != VIRTIO_MSG_FFA_BUS_VERSION_1_0)
- return -EINVAL;
- if (le32_to_cpu(res_payload->vmsg_revision) != VIRTIO_MSG_REVISION_1)
- return -EINVAL;
- if (le32_to_cpu(res_payload->vmsg_features) != VIRTIO_MSG_FEATURES)
- return -EINVAL;
- features = le32_to_cpu(res_payload->features);
- /*
- Direct message must be supported if it already worked.
- Indirect message must be supported if it already worked
- And direct message must not be supported since it didn't work.
- */
- if ((vmfdev->send == vmsg_ffa_send_direct &&
!(features & VIRTIO_MSG_FFA_FEATURE_DIRECT_MSG_SUPP)) ||
- (vmfdev->send == vmsg_ffa_send_indirect &&
(!(features & VIRTIO_MSG_FFA_FEATURE_INDIRECT_MSG_SUPP) ||
(features & VIRTIO_MSG_FFA_FEATURE_DIRECT_MSG_SUPP)))) {
- dev_err(&vmfdev->ffa_dev->dev, "Invalid features\n");
- return -EINVAL;
- }
- return 0;
+}
+static int virtio_msg_ffa_transfer(struct virtio_msg_device *vmdev,
- struct virtio_msg *request,
- struct virtio_msg *response)
+{
- struct virtio_msg_indirect_data *idata = &to_vmdevdata(vmdev)->idata;
- struct virtio_msg_ffa_device *vmfdev = to_vmfdev(vmdev);
- return vmfdev->send(vmfdev, request, response, idata);
+}
+static const char *virtio_msg_ffa_bus_info(struct virtio_msg_device *vmdev,
- u16 *msg_size, u32 *rev)
+{
- struct virtio_msg_ffa_device *vmfdev = to_vmfdev(vmdev);
- *msg_size = vmfdev->msg_size;
- *rev = VIRTIO_MSG_REVISION_1;
- return dev_name(&vmfdev->ffa_dev->dev);
+}
+static struct virtio_msg_ops vmf_ops = {
- .transfer = virtio_msg_ffa_transfer,
- .bus_info = virtio_msg_ffa_bus_info,
+};
+static void remove_vmdevs(struct virtio_msg_ffa_device *vmfdev, int count) +{
- while (count--)
- virtio_msg_unregister(&vmfdev->vmdevs[count].vmdev);
+}
+static int virtio_msg_ffa_probe(struct ffa_device *ffa_dev) +{
- struct virtio_msg_ffa_device *vmfdev;
- struct device *dev = &ffa_dev->dev;
- struct virtio_msg_device *vmdev;
- unsigned long devices = 0;
- int ret, i = 0, bit;
- u16 count;
- vmfdev = devm_kzalloc(dev, sizeof(*vmfdev), GFP_KERNEL);
- if (!vmfdev)
- return -ENOMEM;
- vmfdev->ffa_dev = ffa_dev;
- vmfdev->send = vmsg_ffa_send;
- vmfdev->msg_size = VIRTIO_MSG_FFA_BUS_MSG_SIZE;
- ffa_dev_set_drvdata(ffa_dev, vmfdev);
- init_completion(&vmfdev->idata.completion);
- ret = vmsg_ffa_notify_setup(vmfdev);
- if (ret)
- return ret;
- ret = vmsg_ffa_bus_version(vmfdev);
- if (ret)
- goto notify_cleanup;
- ret = vmsg_ffa_bus_get_devices(vmfdev, (u16 *)&devices, &count);
- if (ret)
- goto notify_cleanup;
- ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
- if (ret)
- dev_warn(dev, "Failed to enable 64-bit or 32-bit DMA\n");
- vmfdev->rmem = of_reserved_mem_lookup_by_name("vmsgffa");
- if (!IS_ERR(vmfdev->rmem)) {
- ret = reserved_mem_device_init(dev, vmfdev->rmem);
- if (ret)
- goto rmem_free;
- } else {
- dev_info(dev, "Continuing without reserved-memory block\n");
- }
- vmfdev->vmdevs = devm_kcalloc(dev, count, sizeof(*vmfdev->vmdevs),
GFP_KERNEL);
- if (!vmfdev->vmdevs) {
- ret = -ENOMEM;
- goto rmem_free;
- }
- vmfdev->vmdev_count = count;
- for_each_set_bit(bit, &devices, sizeof(devices)) {
- init_completion(&vmfdev->vmdevs[i].idata.completion);
- vmdev = &vmfdev->vmdevs[i].vmdev;
- vmdev->dev_id = bit;
- vmdev->ops = &vmf_ops;
- vmdev->vdev.dev.parent = dev;
- vmdev->bus_data = vmfdev;
- ret = virtio_msg_register(vmdev);
- if (ret) {
- dev_err(dev, "Failed to register virtio-msg device (%d)\n", ret);
- goto unregister;
- }
- i++;
- }
- return 0;
+unregister:
- remove_vmdevs(vmfdev, i);
+rmem_free:
- if (!IS_ERR(vmfdev->rmem))
- of_reserved_mem_device_release(dev);
+notify_cleanup:
- vmsg_ffa_notify_cleanup(vmfdev);
- return ret;
+}
+static void virtio_msg_ffa_remove(struct ffa_device *ffa_dev) +{
- struct virtio_msg_ffa_device *vmfdev = ffa_dev->dev.driver_data;
- remove_vmdevs(vmfdev, vmfdev->vmdev_count);
- if (!IS_ERR(vmfdev->rmem))
- of_reserved_mem_device_release(&ffa_dev->dev);
- vmsg_ffa_notify_cleanup(vmfdev);
+}
+static const struct ffa_device_id virtio_msg_ffa_device_ids[] = {
- /* c66028b5-2498-4aa1-9de7-77da6122abf0 */
- { UUID_INIT(0xc66028b5, 0x2498, 0x4aa1,
- 0x9d, 0xe7, 0x77, 0xda, 0x61, 0x22, 0xab, 0xf0) },
- {}
+};
+static int __maybe_unused virtio_msg_ffa_suspend(struct device *dev) +{
- struct virtio_msg_ffa_device *vmfdev = dev_get_drvdata(dev);
- int ret, i, index;
- for (i = 0; i < vmfdev->vmdev_count; i++) {
- index = vmfdev->vmdev_count - i - 1;
- ret = virtio_device_freeze(&vmfdev->vmdevs[index].vmdev.vdev);
- if (ret)
- return ret;
- }
- return 0;
+}
+static int __maybe_unused virtio_msg_ffa_resume(struct device *dev) +{
- struct virtio_msg_ffa_device *vmfdev = dev_get_drvdata(dev);
- int ret, i;
- for (i = 0; i < vmfdev->vmdev_count; i++) {
- ret = virtio_device_restore(&vmfdev->vmdevs[i].vmdev.vdev);
- if (ret)
- return ret;
- }
- return 0;
+}
+static const struct dev_pm_ops virtio_msg_ffa_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(virtio_msg_ffa_suspend, virtio_msg_ffa_resume)
+};
+static struct ffa_driver virtio_msg_ffa_driver = {
- .name = "virtio-msg-ffa",
- .probe = virtio_msg_ffa_probe,
- .remove = virtio_msg_ffa_remove,
- .id_table = virtio_msg_ffa_device_ids,
- .driver = {
- .pm = &virtio_msg_ffa_pm_ops,
- },
+};
+static int virtio_msg_ffa_init(void) +{
- if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT))
- return ffa_register(&virtio_msg_ffa_driver);
- else
- return -EOPNOTSUPP;
+} +module_init(virtio_msg_ffa_init);
+static void virtio_msg_ffa_exit(void) +{
- if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT))
- ffa_unregister(&virtio_msg_ffa_driver);
+} +module_exit(virtio_msg_ffa_exit);
+MODULE_AUTHOR("Viresh Kumar viresh.kumar@linaro.org"); +MODULE_DESCRIPTION("Virtio message FF-A bus driver"); +MODULE_LICENSE("GPL"); diff --git a/include/uapi/linux/virtio_msg_ffa.h b/include/uapi/linux/virtio_msg_ffa.h new file mode 100644 index 000000000000..adcc081b483a --- /dev/null +++ b/include/uapi/linux/virtio_msg_ffa.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/*
- Virtio message FF-A (Arm Firmware Framework) bus header.
- Copyright (C) 2025 Google LLC and Linaro.
- Viresh Kumar viresh.kumar@linaro.org
- */
+#ifndef _LINUX_VIRTIO_MSG_FFA_H +#define _LINUX_VIRTIO_MSG_FFA_H
+#include <linux/types.h>
+/* Message types */ +#define VIRTIO_MSG_FFA_BUS_VERSION 0x80 +#define VIRTIO_MSG_FFA_BUS_AREA_SHARE 0x81 +#define VIRTIO_MSG_FFA_BUS_AREA_UNSHARE 0x82 +#define VIRTIO_MSG_FFA_BUS_RESET 0x83 +#define VIRTIO_MSG_FFA_BUS_EVENT_POLL 0x84 +#define VIRTIO_MSG_FFA_BUS_AREA_RELEASE 0xC0
+#define VIRTIO_MSG_FEATURES 0 +#define VIRTIO_MSG_FFA_BUS_VERSION_1_0 0x1 +#define VIRTIO_MSG_FFA_BUS_MSG_SIZE VIRTIO_MSG_MIN_SIZE
+#define VIRTIO_MSG_FFA_FEATURE_DIRECT_MSG_RX_SUPP (1 << 0) +#define VIRTIO_MSG_FFA_FEATURE_DIRECT_MSG_TX_SUPP (1 << 1) +#define VIRTIO_MSG_FFA_FEATURE_DIRECT_MSG_SUPP \
- (VIRTIO_MSG_FFA_FEATURE_DIRECT_MSG_RX_SUPP | \
- VIRTIO_MSG_FFA_FEATURE_DIRECT_MSG_TX_SUPP)
+#define VIRTIO_MSG_FFA_FEATURE_INDIRECT_MSG_RX_SUPP (1 << 2) +#define VIRTIO_MSG_FFA_FEATURE_INDIRECT_MSG_TX_SUPP (1 << 3) +#define VIRTIO_MSG_FFA_FEATURE_INDIRECT_MSG_SUPP \
- (VIRTIO_MSG_FFA_FEATURE_INDIRECT_MSG_RX_SUPP | \
- VIRTIO_MSG_FFA_FEATURE_INDIRECT_MSG_TX_SUPP)
+#define VIRTIO_MSG_FFA_FEATURE_BOTH_SUPP \
- (VIRTIO_MSG_FFA_FEATURE_DIRECT_MSG_SUPP | \
- VIRTIO_MSG_FFA_FEATURE_INDIRECT_MSG_SUPP)
+#define VIRTIO_MSG_FFA_AREA_ID_MAX 0xFF +#define VIRTIO_MSG_FFA_AREA_ID_OFFSET 56 +#define VIRTIO_MSG_FFA_OFFSET_MASK \
- ((ULL(1) << VIRTIO_MSG_FFA_AREA_ID_OFFSET) - 1)
+#define VIRTIO_MSG_FFA_RESULT_ERROR (1 << 0) +#define VIRTIO_MSG_FFA_RESULT_BUSY (1 << 1)
+/* Message payload format */
+struct bus_ffa_version {
- __le32 driver_version;
- __le32 vmsg_revision;
- __le32 vmsg_features;
- __le32 features;
- __le16 area_num;
+} __attribute__((packed));
+struct bus_ffa_version_resp {
- __le32 device_version;
- __le32 vmsg_revision;
- __le32 vmsg_features;
- __le32 features;
- __le16 area_num;
+} __attribute__((packed));
+struct bus_area_share {
- __le16 area_id;
- __le64 mem_handle;
- __le64 tag;
- __le32 count;
- __le32 attr;
+} __attribute__((packed));
+struct bus_area_share_resp {
- __le16 area_id;
- __le16 result;
+} __attribute__((packed));
+struct bus_area_unshare {
- __le16 area_id;
+} __attribute__((packed));
+struct bus_area_unshare_resp {
- __le16 area_id;
- __le16 result;
+} __attribute__((packed));
+struct bus_area_release {
- __le16 area_id;
+} __attribute__((packed));
+#endif /* _LINUX_VIRTIO_MSG_FFA_H */
2.31.1.272.g89b43f80a514
Virtio-msg mailing list -- virtio-msg@lists.linaro.org To unsubscribe send an email to virtio-msg-leave@lists.linaro.org
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.