aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMikael Olsson <mikael.olsson@arm.com>2023-10-30 11:10:56 +0100
committerMikael Olsson <mikael.olsson@arm.com>2023-11-06 09:36:00 +0100
commitc081e5954cd92165b139488e76bdfef1402acee6 (patch)
tree32bc237c124e21f12287150cba040c87c8e8b7e3 /kernel
parent9c999fdd40c0bf2ae420f6f3bfe013dc6baa73c1 (diff)
downloadethos-u-linux-driver-stack-c081e5954cd92165b139488e76bdfef1402acee6.tar.gz
Change create network UAPI to take a user buffer
To not allow the buffer for a network instance to be changed after creation, the create network UAPI will now take the network model data as a user buffer. The content of the user buffer is copied into an internally allocated DMA buffer that cannot be accessed by the user. This breaks the current API so the Linux kernel NPU driver version and the driver library version have been given major version bumps. All the tests, documentation and other applications affected by the changes have been updated accordingly. Change-Id: I25c785d75a24794c3db632e4abe5cfbb1c7ac190 Signed-off-by: Mikael Olsson <mikael.olsson@arm.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/ethosu_device.c3
-rw-r--r--kernel/ethosu_inference.c4
-rw-r--r--kernel/ethosu_mailbox.c14
-rw-r--r--kernel/ethosu_mailbox.h14
-rw-r--r--kernel/ethosu_network.c46
-rw-r--r--kernel/ethosu_network.h7
-rw-r--r--kernel/ethosu_network_info.c4
-rw-r--r--kernel/uapi/ethosu.h18
8 files changed, 61 insertions, 49 deletions
diff --git a/kernel/ethosu_device.c b/kernel/ethosu_device.c
index 73ddb2e..6e2351d 100644
--- a/kernel/ethosu_device.c
+++ b/kernel/ethosu_device.c
@@ -312,8 +312,7 @@ static long ethosu_ioctl(struct file *file,
return ret;
dev_dbg(dev,
- "Device ioctl: Network create. type=%u, fd/index=%u",
- uapi.type, uapi.fd);
+ "Device ioctl: Network create. type=%u\n", uapi.type);
ret = ethosu_network_create(dev, &edev->mailbox, &uapi);
diff --git a/kernel/ethosu_inference.c b/kernel/ethosu_inference.c
index b985e75..57529f9 100644
--- a/kernel/ethosu_inference.c
+++ b/kernel/ethosu_inference.c
@@ -98,9 +98,7 @@ static int ethosu_inference_send(struct ethosu_inference *inf)
ret = ethosu_mailbox_inference(inf->mailbox, &inf->msg,
inf->ifm_count, inf->ifm,
inf->ofm_count, inf->ofm,
- inf->net->buf,
- inf->net->index,
- inf->pmu_event_config,
+ inf->net, inf->pmu_event_config,
ETHOSU_PMU_EVENT_MAX,
inf->pmu_cycle_counter_enable);
if (ret) {
diff --git a/kernel/ethosu_mailbox.c b/kernel/ethosu_mailbox.c
index 9b9cd18..005e83e 100644
--- a/kernel/ethosu_mailbox.c
+++ b/kernel/ethosu_mailbox.c
@@ -239,8 +239,7 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
struct ethosu_buffer **ifm,
uint32_t ofm_count,
struct ethosu_buffer **ofm,
- struct ethosu_buffer *network,
- uint32_t network_index,
+ struct ethosu_network *network,
uint8_t *pmu_event_config,
uint8_t pmu_event_config_count,
uint8_t pmu_cycle_counter_enable)
@@ -279,13 +278,13 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
for (i = 0; i < ETHOSU_CORE_PMU_MAX; i++)
inf_req->pmu_event_config[i] = pmu_event_config[i];
- if (network != NULL) {
+ if (network->dma_mem != NULL) {
inf_req->network.type = ETHOSU_CORE_NETWORK_BUFFER;
ethosu_core_buffer_dma_mem_set(network->dma_mem,
&inf_req->network.buffer);
} else {
inf_req->network.type = ETHOSU_CORE_NETWORK_INDEX;
- inf_req->network.index = network_index;
+ inf_req->network.index = network->index;
}
return ethosu_send_locked(mbox, &rpmsg,
@@ -294,8 +293,7 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
int ethosu_mailbox_network_info_request(struct ethosu_mailbox *mbox,
struct ethosu_mailbox_msg *msg,
- struct ethosu_buffer *network,
- uint32_t network_index)
+ struct ethosu_network *network)
{
struct ethosu_core_rpmsg rpmsg = {
.header = {
@@ -308,13 +306,13 @@ int ethosu_mailbox_network_info_request(struct ethosu_mailbox *mbox,
msg->type = rpmsg.header.type;
- if (network != NULL) {
+ if (network->dma_mem != NULL) {
info_req->network.type = ETHOSU_CORE_NETWORK_BUFFER;
ethosu_core_buffer_dma_mem_set(network->dma_mem,
&info_req->network.buffer);
} else {
info_req->network.type = ETHOSU_CORE_NETWORK_INDEX;
- info_req->network.index = network_index;
+ info_req->network.index = network->index;
}
return ethosu_send_locked(mbox, &rpmsg,
diff --git a/kernel/ethosu_mailbox.h b/kernel/ethosu_mailbox.h
index c4c71a9..ab19613 100644
--- a/kernel/ethosu_mailbox.h
+++ b/kernel/ethosu_mailbox.h
@@ -1,5 +1,6 @@
/*
- * Copyright 2020-2023 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-License-Identifier: GPL-2.0-only
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -14,8 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
- *
- * SPDX-License-Identifier: GPL-2.0-only
*/
#ifndef ETHOSU_MAILBOX_H
@@ -37,9 +36,10 @@
struct device;
struct ethosu_buffer;
-struct ethosu_device;
struct ethosu_core_msg;
struct ethosu_core_queue;
+struct ethosu_device;
+struct ethosu_network;
struct resource;
typedef void (*ethosu_mailbox_cb)(void *user_arg);
@@ -168,8 +168,7 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
struct ethosu_buffer **ifm,
uint32_t ofm_count,
struct ethosu_buffer **ofm,
- struct ethosu_buffer *network,
- uint32_t network_index,
+ struct ethosu_network *network,
uint8_t *pmu_event_config,
uint8_t pmu_event_config_count,
uint8_t pmu_cycle_counter_enable);
@@ -181,8 +180,7 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
*/
int ethosu_mailbox_network_info_request(struct ethosu_mailbox *mbox,
struct ethosu_mailbox_msg *msg,
- struct ethosu_buffer *network,
- uint32_t network_index);
+ struct ethosu_network *network);
/**
* ethosu_mailbox_cancel_inference() - Send inference cancellation
diff --git a/kernel/ethosu_network.c b/kernel/ethosu_network.c
index f7871de..58d5c77 100644
--- a/kernel/ethosu_network.c
+++ b/kernel/ethosu_network.c
@@ -23,8 +23,8 @@
#include "ethosu_network.h"
-#include "ethosu_buffer.h"
#include "ethosu_device.h"
+#include "ethosu_dma_mem.h"
#include "ethosu_inference.h"
#include "ethosu_network_info.h"
#include "uapi/ethosu.h"
@@ -70,8 +70,8 @@ static void ethosu_network_destroy(struct kref *kref)
dev_dbg(dev, "Network destroy. net=0x%pK\n", net);
- if (net->buf != NULL)
- ethosu_buffer_put(net->buf);
+ if (net->dma_mem != NULL)
+ ethosu_dma_mem_free(&net->dma_mem);
memset(net, 0, sizeof(*net));
devm_kfree(dev, net);
@@ -151,7 +151,8 @@ int ethosu_network_create(struct device *dev,
struct ethosu_uapi_network_create *uapi)
{
struct ethosu_network *net;
- int ret = -ENOMEM;
+ const void __user *data;
+ int ret;
net = devm_kzalloc(dev, sizeof(*net), GFP_KERNEL);
if (!net)
@@ -159,17 +160,34 @@ int ethosu_network_create(struct device *dev,
net->dev = dev;
net->mailbox = mailbox;
- net->buf = NULL;
kref_init(&net->kref);
switch (uapi->type) {
- case ETHOSU_UAPI_NETWORK_BUFFER:
- net->buf = ethosu_buffer_get_from_fd(uapi->fd);
- if (IS_ERR(net->buf)) {
- ret = PTR_ERR(net->buf);
+ case ETHOSU_UAPI_NETWORK_USER_BUFFER:
+ if (!uapi->network.data_ptr) {
+ dev_err(dev, "Invalid network data ptr\n");
+ ret = -EINVAL;
goto free_net;
}
+ if (!uapi->network.size) {
+ dev_err(dev, "Invalid network data size\n");
+ ret = -EINVAL;
+ goto free_net;
+ }
+
+ net->dma_mem = ethosu_dma_mem_alloc(dev, uapi->network.size);
+ if (IS_ERR(net->dma_mem)) {
+ ret = PTR_ERR(net->dma_mem);
+ goto free_net;
+ }
+
+ data = u64_to_user_ptr(uapi->network.data_ptr);
+ ret = copy_from_user(net->dma_mem->cpu_addr, data,
+ uapi->network.size);
+ if (ret)
+ goto free_dma_mem;
+
break;
case ETHOSU_UAPI_NETWORK_INDEX:
net->index = uapi->index;
@@ -182,20 +200,20 @@ int ethosu_network_create(struct device *dev,
ret = anon_inode_getfd("ethosu-network", &ethosu_network_fops, net,
O_RDWR | O_CLOEXEC);
if (ret < 0)
- goto put_buf;
+ goto free_dma_mem;
net->file = fget(ret);
fput(net->file);
dev_dbg(dev,
"Network create. file=0x%pK, fd=%d, net=0x%pK, buf=0x%pK, index=%u",
- net->file, ret, net, net->buf, net->index);
+ net->file, ret, net, net->dma_mem, net->index);
return ret;
-put_buf:
- if (net->buf != NULL)
- ethosu_buffer_put(net->buf);
+free_dma_mem:
+ if (net->dma_mem != NULL)
+ ethosu_dma_mem_free(&net->dma_mem);
free_net:
memset(net, 0, sizeof(*net));
diff --git a/kernel/ethosu_network.h b/kernel/ethosu_network.h
index e0d41b1..5484bac 100644
--- a/kernel/ethosu_network.h
+++ b/kernel/ethosu_network.h
@@ -1,5 +1,6 @@
/*
- * Copyright 2020,2022-2023 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2020,2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-License-Identifier: GPL-2.0-only
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -14,8 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
- *
- * SPDX-License-Identifier: GPL-2.0-only
*/
#ifndef ETHOSU_NETWORK_H
@@ -42,7 +41,7 @@ struct ethosu_network {
struct ethosu_mailbox *mailbox;
struct file *file;
struct kref kref;
- struct ethosu_buffer *buf;
+ struct ethosu_dma_mem *dma_mem;
uint32_t index;
};
diff --git a/kernel/ethosu_network_info.c b/kernel/ethosu_network_info.c
index feabcae..011a0b4 100644
--- a/kernel/ethosu_network_info.c
+++ b/kernel/ethosu_network_info.c
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
- *
*/
/****************************************************************************
@@ -39,8 +38,7 @@ static inline int ethosu_network_info_send(struct ethosu_network_info *info,
/* Send network info request to firmware */
return ethosu_mailbox_network_info_request(mailbox,
&info->msg,
- info->net->buf,
- info->net->index);
+ info->net);
}
static void ethosu_network_info_fail(struct ethosu_mailbox_msg *msg)
diff --git a/kernel/uapi/ethosu.h b/kernel/uapi/ethosu.h
index 4e4d180..35eaf60 100644
--- a/kernel/uapi/ethosu.h
+++ b/kernel/uapi/ethosu.h
@@ -67,7 +67,7 @@ namespace EthosU {
#define ETHOSU_PMU_EVENT_MAX 8
/* Kernel driver version */
-#define ETHOSU_KERNEL_DRIVER_VERSION_MAJOR 2
+#define ETHOSU_KERNEL_DRIVER_VERSION_MAJOR 3
#define ETHOSU_KERNEL_DRIVER_VERSION_MINOR 0
#define ETHOSU_KERNEL_DRIVER_VERSION_PATCH 0
@@ -109,13 +109,14 @@ struct ethosu_uapi_buffer_create {
/**
* enum ethosu_uapi_network_type - Network buffer type.
- * @ETHOSU_UAPI_NETWORK_BUFFER: Network is stored in a buffer handle.
- * @ETHOSU_UAPI_NETWORK_INDEX: Network is built into firmware and referenced by
- * index.
+ * @ETHOSU_UAPI_NETWORK_USER_BUFFER: Network data is provided in a user
+ * buffer.
+ * @ETHOSU_UAPI_NETWORK_INDEX: Network is built into firmware and
+ * referenced by index.
*/
enum ethosu_uapi_network_type {
- ETHOSU_UAPI_NETWORK_BUFFER = 1,
- ETHOSU_UAPI_NETWORK_INDEX
+ ETHOSU_UAPI_NETWORK_USER_BUFFER = 1,
+ ETHOSU_UAPI_NETWORK_INDEX,
};
/**
@@ -127,7 +128,10 @@ enum ethosu_uapi_network_type {
struct ethosu_uapi_network_create {
uint32_t type;
union {
- __u32 fd;
+ struct {
+ __u64 data_ptr;
+ __u32 size;
+ } network;
__u32 index;
};
};