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>
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 @@
 
 	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 @@
 			  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 @@
 
 	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 @@
 	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));