Remove buffer capacity, offset and resize in UAPI

The UAPI no longer supports the buffer capacity, offset and resize
functionality. Instead, the UAPI now only accepts a fixed size given at
the creation of the buffer. This change was made because the features
were not used and made the buffer handling more complicated. The user
knows how big buffers they need for their networks so they don't need
resize support or partial buffer usage support by having separate size
and capacity with an offset.

Without these features, the buffer instance no longer needs any IOCTL
call support so it has been removed. However, to still be able to check
the size of a buffer from its file descriptor, seek support has been
implemented so lseek and similar functions can be used to get the size.

The driver library's clear function that previously only reset the size
and offset values of the buffer will now clear the buffer content
instead.

These are breaking changes so the Linux kernel NPU driver version and
the driver library version have been given major version bumps. All the
tests and other applications affected by these changes have been updated
accordingly.

Change-Id: Ifc34cf04724a95853ad23fd7398dd286f73bcdab
Signed-off-by: Mikael Olsson <mikael.olsson@arm.com>
diff --git a/driver_library/include/ethosu.hpp b/driver_library/include/ethosu.hpp
index 491dc28..47c1868 100644
--- a/driver_library/include/ethosu.hpp
+++ b/driver_library/include/ethosu.hpp
@@ -1,6 +1,5 @@
 /*
  * SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
- *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Licensed under the Apache License, Version 2.0 (the License); you may
@@ -40,12 +39,12 @@
 
 namespace EthosU {
 
-constexpr uint32_t DRIVER_LIBRARY_VERSION_MAJOR = 1;
+constexpr uint32_t DRIVER_LIBRARY_VERSION_MAJOR = 2;
 constexpr uint32_t DRIVER_LIBRARY_VERSION_MINOR = 0;
 constexpr uint32_t DRIVER_LIBRARY_VERSION_PATCH = 0;
 
-constexpr uint32_t MAX_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 1;
-constexpr uint32_t MIN_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 1;
+constexpr uint32_t MAX_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 2;
+constexpr uint32_t MIN_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 2;
 
 class Exception : public std::exception {
 public:
@@ -152,14 +151,11 @@
 
 class Buffer {
 public:
-    Buffer(const Device &device, const size_t capacity);
+    Buffer(const Device &device, const size_t size);
     virtual ~Buffer() noexcept(false);
 
-    size_t capacity() const;
     void clear() const;
     char *data() const;
-    void resize(size_t size, size_t offset = 0) const;
-    size_t offset() const;
     size_t size() const;
 
     int getFd() const;
@@ -167,7 +163,7 @@
 private:
     int fd;
     char *dataPtr;
-    const size_t dataCapacity;
+    const size_t dataSize;
 };
 
 class Network {
diff --git a/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py b/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py
index 216895a..fcea91f 100644
--- a/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py
+++ b/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py
@@ -1,4 +1,4 @@
-# SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
 # SPDX-License-Identifier: Apache-2.0
 import logging
 import time
@@ -49,12 +49,11 @@
         raise RuntimeError("Incorrect number of inputs, expected {}, got {}.".format(number_of_buffers, len(input_data)))
 
     for index, (buffer, data_chunk) in enumerate(zip(buffers, input_data)):
-        cap = buffer.capacity()
-        logging.info("Copying data to a buffer {} of {} with size = {}".format(index + 1, number_of_buffers, cap))
+        size = buffer.size()
+        logging.info("Copying data to a buffer {} of {} with size = {}".format(index + 1, number_of_buffers, size))
 
-        if len(data_chunk) > cap:
-            raise RuntimeError("Buffer expects {} bytes, got {} bytes.".format(cap, len(data_chunk)))
-        buffer.resize(len(data_chunk))
+        if len(data_chunk) > size:
+            raise RuntimeError("Buffer expects {} bytes, got {} bytes.".format(size, len(data_chunk)))
         buffer.from_buffer(data_chunk)
 
 
diff --git a/driver_library/python/src/ethosu_driver/swig/driver.i b/driver_library/python/src/ethosu_driver/swig/driver.i
index 1ff8ded..3e4e384 100644
--- a/driver_library/python/src/ethosu_driver/swig/driver.i
+++ b/driver_library/python/src/ethosu_driver/swig/driver.i
@@ -210,31 +210,22 @@
     Buffer object represents a RW mapping in the virtual address space of the caller.
 
     Created mapping is shareable, updates to the mapping are visible to other processes mapping the same region.
-    Issues ETHOSU_IOCTL_BUFFER_CREATE I/O request to the device with given Maximum capacity.
+    Issues ETHOSU_IOCTL_BUFFER_CREATE I/O request to the device with given size.
 
-    Buffer could be created for a device with given maximum capacity or instantiated directly from
+    Buffer could be created for a device with given size or instantiated directly from
     a file containing binary data.
 
     Examples:
         >>> import ethosu_driver as driver
         >>> # from file:
         >>> buf = driver.Buffer(device, '/path/to/file')
-        >>> # Empty, with maximum capacity:
+        >>> # Empty, with size:
         >>> buf = driver.Buffer(device, 1024)
     ") Buffer;
 %nodefaultctor Buffer;
 class Buffer {
 public:
-    Buffer(const Device &device, const size_t capacity);
-
-    %feature("docstring",
-    "
-    Returns maximum buffer capacity set during initialisation.
-
-    Returns:
-        int: maximum buffer capacity.
-    ") capacity;
-    size_t capacity() const;
+    Buffer(const Device &device, const size_t size);
 
     %feature("docstring",
     "
@@ -255,32 +246,6 @@
 
     %feature("docstring",
     "
-    Sets a size of the memory buffer for the device.
-
-    'offset + size' must not exceed the capacity of the buffer.
-    Does not change the size of the mapped region.
-
-    Issues ETHOSU_IOCTL_BUFFER_SET I/O request with a given size and offset.
-
-    Args:
-        size (int): Device buffer size.
-        offset (int): Offset to where the data starts.
-    ") resize;
-    void resize(size_t size, size_t offset = 0) const;
-
-    %feature("docstring",
-    "
-    Queries device and returns buffer data offset.
-
-    Issues ETHOSU_IOCTL_BUFFER_GET I/O request.
-
-    Returns:
-        int: data offset
-    ") offset;
-    size_t offset() const;
-
-    %feature("docstring",
-    "
     Queries device and returns buffer data size.
 
     Issues ETHOSU_IOCTL_BUFFER_GET I/O request.
@@ -313,7 +278,6 @@
         stream.seekg(0, std::ios_base::beg);
 
         auto buffer = new EthosU::Buffer(device, size);
-        buffer->resize(size);
         stream.read(buffer->data(), size);
 
         return buffer;
@@ -324,7 +288,6 @@
     Fills the buffer from python buffer.
 
     Copies python buffer data to the mapped memory region.
-    Input buffer size must be within `Buffer` maximum capacity.
 
     Args:
         buffer: data to be copied to the mapped memory.
@@ -332,7 +295,6 @@
     ") from_buffer;
     %mutable_buffer(char* buffer, size_t size);
     void from_buffer(char* buffer, size_t size) {
-        self->resize(size);
         char* data = $self->data();
         std::memcpy(data, buffer, size);
     }
diff --git a/driver_library/python/test/test_driver.py b/driver_library/python/test/test_driver.py
index 28d0a29..0dd207f 100644
--- a/driver_library/python/test/test_driver.py
+++ b/driver_library/python/test/test_driver.py
@@ -67,12 +67,6 @@
 
 @pytest.mark.parametrize('device_name', ['ethosu0'])
 @pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_buffer_capacity(network_buffer):
-    assert network_buffer.capacity() > 0
-
-
-@pytest.mark.parametrize('device_name', ['ethosu0'])
-@pytest.mark.parametrize('model_name', ['model.tflite'])
 def test_check_buffer_size(network_buffer):
     assert network_buffer.size() > 0
 
@@ -81,16 +75,8 @@
 @pytest.mark.parametrize('model_name', ['model.tflite'])
 def test_check_buffer_clear(network_buffer):
     network_buffer.clear()
-    assert network_buffer.size() == 0
-
-
-@pytest.mark.parametrize('device_name', ['ethosu0'])
-@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_buffer_resize(network_buffer):
-    offset = 1
-    new_size = network_buffer.capacity() - offset
-    network_buffer.resize(new_size, offset)
-    assert network_buffer.size() == new_size
+    for i in range(network_buffer.size()):
+        assert network_buffer.data()[i] == 0
 
 
 @pytest.mark.parametrize('device_name', ['ethosu0'])
diff --git a/driver_library/python/test/test_driver_utilities.py b/driver_library/python/test/test_driver_utilities.py
index fc8e921..fe44b0e 100644
--- a/driver_library/python/test/test_driver_utilities.py
+++ b/driver_library/python/test/test_driver_utilities.py
@@ -1,5 +1,5 @@
 #
-# SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
 # SPDX-License-Identifier: Apache-2.0
 #
 import pytest
@@ -53,10 +53,8 @@
 def test_allocate_buffers(device):
     buffers = driver.allocate_buffers(device, [128, 256])
     assert len(buffers) == 2
-    assert buffers[0].size() == 0
-    assert buffers[0].capacity() == 128
-    assert buffers[1].size() == 0
-    assert buffers[1].capacity() == 256
+    assert buffers[0].size() == 128
+    assert buffers[1].size() == 256
 
 
 @pytest.mark.parametrize('device_name', ['ethosu0'])
diff --git a/driver_library/src/ethosu.cpp b/driver_library/src/ethosu.cpp
index dcdde8c..3c7dc31 100644
--- a/driver_library/src/ethosu.cpp
+++ b/driver_library/src/ethosu.cpp
@@ -1,6 +1,5 @@
 /*
  * SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
- *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Licensed under the Apache License, Version 2.0 (the License); you may
@@ -279,13 +278,13 @@
  * Buffer
  ****************************************************************************/
 
-Buffer::Buffer(const Device &device, const size_t capacity) : fd(-1), dataPtr(nullptr), dataCapacity(capacity) {
-    ethosu_uapi_buffer_create uapi = {static_cast<uint32_t>(dataCapacity)};
+Buffer::Buffer(const Device &device, const size_t size) : fd(-1), dataPtr(nullptr), dataSize(size) {
+    ethosu_uapi_buffer_create uapi = {static_cast<uint32_t>(dataSize)};
     fd                             = device.ioctl(ETHOSU_IOCTL_BUFFER_CREATE, static_cast<void *>(&uapi));
 
     void *d;
     try {
-        d = emmap(nullptr, dataCapacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+        d = emmap(nullptr, dataSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
     } catch (std::exception &e) {
         try {
             eclose(fd);
@@ -295,13 +294,13 @@
 
     dataPtr = reinterpret_cast<char *>(d);
 
-    Log(Severity::Info) << "Buffer(" << &device << ", " << dec << capacity << "), this=" << this << ", fd=" << fd
+    Log(Severity::Info) << "Buffer(" << &device << ", " << dec << size << "), this=" << this << ", fd=" << fd
                         << ", dataPtr=" << static_cast<void *>(dataPtr) << endl;
 }
 
 Buffer::~Buffer() noexcept(false) {
     try {
-        emunmap(dataPtr, dataCapacity);
+        emunmap(dataPtr, dataSize);
     } catch (std::exception &e) {
         try {
             eclose(fd);
@@ -314,35 +313,16 @@
     Log(Severity::Info) << "~Buffer(). this=" << this << endl;
 }
 
-size_t Buffer::capacity() const {
-    return dataCapacity;
-}
-
 void Buffer::clear() const {
-    resize(0, 0);
+    memset(dataPtr, 0, dataSize);
 }
 
 char *Buffer::data() const {
-    return dataPtr + offset();
-}
-
-void Buffer::resize(size_t size, size_t offset) const {
-    ethosu_uapi_buffer uapi;
-    uapi.offset = offset;
-    uapi.size   = size;
-    eioctl(fd, ETHOSU_IOCTL_BUFFER_SET, static_cast<void *>(&uapi));
-}
-
-size_t Buffer::offset() const {
-    ethosu_uapi_buffer uapi;
-    eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi));
-    return uapi.offset;
+    return dataPtr;
 }
 
 size_t Buffer::size() const {
-    ethosu_uapi_buffer uapi;
-    eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi));
-    return uapi.size;
+    return dataSize;
 }
 
 int Buffer::getFd() const {
diff --git a/kernel/ethosu_buffer.c b/kernel/ethosu_buffer.c
index 07c8033..bf7d745 100644
--- a/kernel/ethosu_buffer.c
+++ b/kernel/ethosu_buffer.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.
- *
  */
 
 /****************************************************************************
@@ -45,17 +44,14 @@
 static int ethosu_buffer_mmap(struct file *file,
 			      struct vm_area_struct *vma);
 
-static long ethosu_buffer_ioctl(struct file *file,
-				unsigned int cmd,
-				unsigned long arg);
+static loff_t ethosu_buffer_llseek(struct file *file,
+				   loff_t offset,
+				   int whence);
 
 static const struct file_operations ethosu_buffer_fops = {
-	.release        = &ethosu_buffer_release,
-	.mmap           = &ethosu_buffer_mmap,
-	.unlocked_ioctl = &ethosu_buffer_ioctl,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl   = &ethosu_buffer_ioctl,
-#endif
+	.release = &ethosu_buffer_release,
+	.mmap    = &ethosu_buffer_mmap,
+	.llseek  = &ethosu_buffer_llseek,
 };
 
 /****************************************************************************
@@ -75,8 +71,8 @@
 
 	dev_dbg(dev, "Buffer destroy. buf=0x%pK", buf);
 
-	memset(buf->cpu_addr, 0, buf->capacity);
-	dma_free_coherent(dev, buf->capacity, buf->cpu_addr,
+	memset(buf->cpu_addr, 0, buf->size);
+	dma_free_coherent(dev, buf->size, buf->cpu_addr,
 			  buf->dma_addr);
 
 	memset(buf, 0, sizeof(*buf));
@@ -108,78 +104,43 @@
 		file, buf);
 
 	ret = dma_mmap_coherent(dev, vma, buf->cpu_addr,
-				buf->dma_addr, buf->capacity);
+				buf->dma_addr, buf->size);
 
 	return ret;
 }
 
-static long ethosu_buffer_ioctl(struct file *file,
-				unsigned int cmd,
-				unsigned long arg)
+static loff_t ethosu_buffer_llseek(struct file *file,
+				   loff_t offset,
+				   int whence)
 {
 	struct ethosu_buffer *buf = file->private_data;
-	struct device *dev = buf->dev;
-	void __user *udata = (void __user *)arg;
-	int ret;
 
-	ret = device_lock_interruptible(dev);
-	if (ret)
-		return ret;
+	if (offset != 0)
+		return -EINVAL;
 
-	switch (cmd) {
-	case ETHOSU_IOCTL_BUFFER_SET: {
-		struct ethosu_uapi_buffer uapi;
-
-		if (copy_from_user(&uapi, udata, sizeof(uapi))) {
-			ret = -EFAULT;
-			break;
-		}
-
-		dev_dbg(dev,
-			"Buffer ioctl: Buffer set. size=%u, offset=%u\n",
-			uapi.size, uapi.offset);
-
-		ret = ethosu_buffer_resize(buf, uapi.size, uapi.offset);
-		break;
+	/*
+	 * SEEK_END and SEEK_SET is supported with a zero offset to allow buffer
+	 * size discovery using seek functions e.g.
+	 * size = lseek(buf_fd, 0, SEEK_END);
+	 * lseek(buf_fd, 0, SEEK_SET);
+	 */
+	switch (whence) {
+	case SEEK_END:
+		return buf->size;
+	case SEEK_SET:
+		return 0;
+	default:
+		return -EINVAL;
 	}
-	case ETHOSU_IOCTL_BUFFER_GET: {
-		struct ethosu_uapi_buffer uapi = { 0 };
-
-		uapi.size = buf->size;
-		uapi.offset = buf->offset;
-
-		dev_dbg(dev,
-			"Buffer ioctl: Buffer get. size=%u, offset=%u\n",
-			uapi.size, uapi.offset);
-
-		if (copy_to_user(udata, &uapi, sizeof(uapi))) {
-			ret = -EFAULT;
-			break;
-		}
-
-		ret = 0;
-		break;
-	}
-	default: {
-		dev_err(dev, "Invalid ioctl. cmd=%u, arg=%lu",
-			cmd, arg);
-		ret = -ENOIOCTLCMD;
-		break;
-	}
-	}
-
-	device_unlock(dev);
-
-	return ret;
 }
 
 int ethosu_buffer_create(struct device *dev,
-			 size_t capacity)
+			 size_t size)
 {
 	struct ethosu_buffer *buf;
 	int ret = -ENOMEM;
 
-	if (!capacity)
+	if (!size)
 		return -EINVAL;
 
 	buf = devm_kzalloc(dev, sizeof(*buf), GFP_KERNEL);
@@ -187,13 +148,11 @@
 		return -ENOMEM;
 
 	buf->dev = dev;
-	buf->capacity = capacity;
-	buf->offset = 0;
-	buf->size = 0;
+	buf->size = size;
 	kref_init(&buf->kref);
 
-	buf->cpu_addr = dma_alloc_coherent(dev, capacity,
-					   &buf->dma_addr, GFP_KERNEL);
+	buf->cpu_addr = dma_alloc_coherent(dev, size, &buf->dma_addr,
+					   GFP_KERNEL);
 	if (!buf->cpu_addr)
 		goto free_buf;
 
@@ -203,17 +162,19 @@
 		goto free_dma;
 
 	buf->file = fget(ret);
+	buf->file->f_mode |= FMODE_LSEEK;
+
 	fput(buf->file);
 
 	dev_dbg(dev,
-		"Buffer create. file=0x%pK, fd=%d, buf=0x%pK, capacity=%zu, cpu_addr=0x%pK, dma_addr=0x%llx, phys_addr=0x%llx\n",
-		buf->file, ret, buf, capacity, buf->cpu_addr, buf->dma_addr,
+		"Buffer create. file=0x%pK, fd=%d, buf=0x%pK, size=%zu, cpu_addr=0x%pK, dma_addr=0x%llx, phys_addr=0x%llx\n",
+		buf->file, ret, buf, size, buf->cpu_addr, buf->dma_addr,
 		virt_to_phys(buf->cpu_addr));
 
 	return ret;
 
 free_dma:
-	dma_free_coherent(dev, buf->capacity, buf->cpu_addr,
+	dma_free_coherent(dev, buf->size, buf->cpu_addr,
 			  buf->dma_addr);
 
 free_buf:
@@ -254,16 +215,3 @@
 {
 	kref_put(&buf->kref, ethosu_buffer_destroy);
 }
-
-int ethosu_buffer_resize(struct ethosu_buffer *buf,
-			 size_t size,
-			 size_t offset)
-{
-	if ((size + offset) > buf->capacity)
-		return -EINVAL;
-
-	buf->size = size;
-	buf->offset = offset;
-
-	return 0;
-}
diff --git a/kernel/ethosu_buffer.h b/kernel/ethosu_buffer.h
index bc5958c..1829fbe 100644
--- a/kernel/ethosu_buffer.h
+++ b/kernel/ethosu_buffer.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_BUFFER_H
@@ -40,21 +39,14 @@
  * @dev:		Device
  * @file:		File
  * @kref:		Reference counting
- * @capacity:		Maximum capacity of the buffer
- * @offset:		Offset to first byte of buffer
- * @size:		Size of the data in the buffer
+ * @size:		Size of the buffer
  * @cpu_addr:		Kernel mapped address
  * @dma_addr:		DMA address
- * @dma_addr_orig:	Original DMA address before range mapping
- *
- * 'offset + size' must not be larger than 'capacity'.
  */
 struct ethosu_buffer {
 	struct device *dev;
 	struct file   *file;
 	struct kref   kref;
-	size_t        capacity;
-	size_t        offset;
 	size_t        size;
 	void          *cpu_addr;
 	dma_addr_t    dma_addr;
@@ -72,7 +64,7 @@
  * Return: fd on success, else error code.
  */
 int ethosu_buffer_create(struct device *dev,
-			 size_t capacity);
+			 size_t size);
 
 /**
  * ethosu_buffer_get_from_fd() - Get buffer handle from fd
@@ -93,13 +85,4 @@
  */
 void ethosu_buffer_put(struct ethosu_buffer *buf);
 
-/**
- * ethosu_buffer_resize() - Resize and validate buffer
- *
- * Return: 0 on success, else error code.
- */
-int ethosu_buffer_resize(struct ethosu_buffer *buf,
-			 size_t size,
-			 size_t offset);
-
 #endif /* ETHOSU_BUFFER_H */
diff --git a/kernel/ethosu_device.c b/kernel/ethosu_device.c
index 8e21512..73ddb2e 100644
--- a/kernel/ethosu_device.c
+++ b/kernel/ethosu_device.c
@@ -290,10 +290,10 @@
 			return ret;
 
 		dev_dbg(dev,
-			"Device ioctl: Buffer create. capacity=%u",
-			uapi.capacity);
+			"Device ioctl: Buffer create. size=%u",
+			uapi.size);
 
-		ret = ethosu_buffer_create(dev, uapi.capacity);
+		ret = ethosu_buffer_create(dev, uapi.size);
 
 		device_unlock(dev);
 
diff --git a/kernel/ethosu_inference.c b/kernel/ethosu_inference.c
index 5c57074..b985e75 100644
--- a/kernel/ethosu_inference.c
+++ b/kernel/ethosu_inference.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.
- *
  */
 
 /****************************************************************************
@@ -426,7 +425,6 @@
 	struct device *dev = mailbox->dev;
 	struct ethosu_mailbox_msg *msg;
 	struct ethosu_inference *inf;
-	int ret;
 	int i;
 
 	msg = ethosu_mailbox_find(mailbox, msg_id,
@@ -442,27 +440,14 @@
 	inf = container_of(msg, typeof(*inf), msg);
 
 	if (rsp->status == ETHOSU_CORE_STATUS_OK &&
-	    inf->ofm_count <= ETHOSU_CORE_BUFFER_MAX) {
-		uint32_t i;
-
+	    inf->ofm_count <= ETHOSU_CORE_BUFFER_MAX)
 		inf->status = ETHOSU_UAPI_STATUS_OK;
-
-		for (i = 0; i < inf->ofm_count; i++) {
-			struct ethosu_buffer *ofm = inf->ofm[i];
-
-			ret = ethosu_buffer_resize(
-				ofm, ofm->size + rsp->ofm_size[i],
-				ofm->offset);
-			if (ret)
-				inf->status = ETHOSU_UAPI_STATUS_ERROR;
-		}
-	} else if (rsp->status == ETHOSU_CORE_STATUS_REJECTED) {
+	else if (rsp->status == ETHOSU_CORE_STATUS_REJECTED)
 		inf->status = ETHOSU_UAPI_STATUS_REJECTED;
-	} else if (rsp->status == ETHOSU_CORE_STATUS_ABORTED) {
+	else if (rsp->status == ETHOSU_CORE_STATUS_ABORTED)
 		inf->status = ETHOSU_UAPI_STATUS_ABORTED;
-	} else {
+	else
 		inf->status = ETHOSU_UAPI_STATUS_ERROR;
-	}
 
 	if (inf->status == ETHOSU_UAPI_STATUS_OK) {
 		for (i = 0; i < ETHOSU_CORE_PMU_MAX; i++) {
diff --git a/kernel/ethosu_mailbox.c b/kernel/ethosu_mailbox.c
index 5cc2465..e499860 100644
--- a/kernel/ethosu_mailbox.c
+++ b/kernel/ethosu_mailbox.c
@@ -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
  */
 
 /****************************************************************************
@@ -125,17 +124,10 @@
 static void ethosu_core_set_size(struct ethosu_buffer *buf,
 				 struct ethosu_core_buffer *cbuf)
 {
-	cbuf->ptr = (uint32_t)buf->dma_addr + buf->offset;
+	cbuf->ptr = (uint32_t)buf->dma_addr;
 	cbuf->size = (uint32_t)buf->size;
 }
 
-static void ethosu_core_set_capacity(struct ethosu_buffer *buf,
-				     struct ethosu_core_buffer *cbuf)
-{
-	cbuf->ptr = (uint32_t)buf->dma_addr + buf->offset + buf->size;
-	cbuf->size = (uint32_t)buf->capacity - buf->offset - buf->size;
-}
-
 int ethosu_mailbox_register(struct ethosu_mailbox *mbox,
 			    struct ethosu_mailbox_msg *msg)
 {
@@ -278,7 +270,7 @@
 		ethosu_core_set_size(ifm[i], &inf_req->ifm[i]);
 
 	for (i = 0; i < ofm_count; i++)
-		ethosu_core_set_capacity(ofm[i], &inf_req->ofm[i]);
+		ethosu_core_set_size(ofm[i], &inf_req->ofm[i]);
 
 	for (i = 0; i < ETHOSU_CORE_PMU_MAX; i++)
 		inf_req->pmu_event_config[i] = pmu_event_config[i];
diff --git a/kernel/uapi/ethosu.h b/kernel/uapi/ethosu.h
index 69f8d3a..4e4d180 100644
--- a/kernel/uapi/ethosu.h
+++ b/kernel/uapi/ethosu.h
@@ -49,10 +49,6 @@
 						   struct ethosu_uapi_kernel_driver_version)
 #define ETHOSU_IOCTL_BUFFER_CREATE      ETHOSU_IOR(0x10, \
 						   struct ethosu_uapi_buffer_create)
-#define ETHOSU_IOCTL_BUFFER_SET         ETHOSU_IOR(0x11, \
-						   struct ethosu_uapi_buffer)
-#define ETHOSU_IOCTL_BUFFER_GET         ETHOSU_IOW(0x12, \
-						   struct ethosu_uapi_buffer)
 #define ETHOSU_IOCTL_NETWORK_CREATE     ETHOSU_IOR(0x20, \
 						   struct ethosu_uapi_network_create)
 #define ETHOSU_IOCTL_NETWORK_INFO       ETHOSU_IOR(0x21, \
@@ -71,7 +67,7 @@
 #define ETHOSU_PMU_EVENT_MAX             8
 
 /* Kernel driver version */
-#define ETHOSU_KERNEL_DRIVER_VERSION_MAJOR 1
+#define ETHOSU_KERNEL_DRIVER_VERSION_MAJOR 2
 #define ETHOSU_KERNEL_DRIVER_VERSION_MINOR 0
 #define ETHOSU_KERNEL_DRIVER_VERSION_PATCH 0
 
@@ -105,21 +101,9 @@
 
 /**
  * struct ethosu_uapi_buffer_create - Create buffer request
- * @capacity:	Maximum capacity of the buffer
+ * @size:	Size of the requested buffer
  */
 struct ethosu_uapi_buffer_create {
-	__u32 capacity;
-};
-
-/**
- * struct ethosu_uapi_buffer - Buffer descriptor
- * @offset:	Offset to where the data starts
- * @size:	Size of the data
- *
- * 'offset + size' must not exceed the capacity of the buffer.
- */
-struct ethosu_uapi_buffer {
-	__u32 offset;
 	__u32 size;
 };
 
diff --git a/tests/cancel_inference_test.cpp b/tests/cancel_inference_test.cpp
index 36514f4..846a29f 100644
--- a/tests/cancel_inference_test.cpp
+++ b/tests/cancel_inference_test.cpp
@@ -1,6 +1,5 @@
 /*
- * Copyright (c) 2022 Arm Limited.
- *
+ * SPDX-FileCopyrightText: Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
  * SPDX-License-Identifier: Apache-2.0
  *
  * Licensed under the Apache License, Version 2.0 (the License); you may
@@ -42,7 +41,6 @@
 void testCancelInference(const Device &device) {
     try {
         auto networkBuffer = std::make_shared<Buffer>(device, sizeof(networkModelData));
-        networkBuffer->resize(sizeof(networkModelData));
         std::memcpy(networkBuffer->data(), networkModelData, sizeof(networkModelData));
         auto network = std::make_shared<Network>(device, networkBuffer);
 
@@ -50,7 +48,6 @@
         std::vector<std::shared_ptr<Buffer>> outputBuffers;
 
         auto inputBuffer = std::make_shared<Buffer>(device, sizeof(inputData));
-        inputBuffer->resize(sizeof(inputData));
         std::memcpy(inputBuffer->data(), inputData, sizeof(inputData));
 
         inputBuffers.push_back(inputBuffer);
@@ -83,7 +80,6 @@
 void testRejectInference(const Device &device) {
     try {
         auto networkBuffer = std::make_shared<Buffer>(device, sizeof(networkModelData));
-        networkBuffer->resize(sizeof(networkModelData));
         std::memcpy(networkBuffer->data(), networkModelData, sizeof(networkModelData));
         auto network = std::make_shared<Network>(device, networkBuffer);
 
@@ -91,7 +87,6 @@
         std::vector<std::shared_ptr<Buffer>> outputBuffers;
 
         auto inputBuffer = std::make_shared<Buffer>(device, sizeof(inputData));
-        inputBuffer->resize(sizeof(inputData));
         std::memcpy(inputBuffer->data(), inputData, sizeof(inputData));
 
         inputBuffers.push_back(inputBuffer);
diff --git a/tests/run_inference_test.cpp b/tests/run_inference_test.cpp
index 6075d7a..6b17ac2 100644
--- a/tests/run_inference_test.cpp
+++ b/tests/run_inference_test.cpp
@@ -19,6 +19,7 @@
 #include <uapi/ethosu.h>
 
 #include <cstring>
+#include <errno.h>
 #include <iostream>
 #include <list>
 #include <memory>
@@ -69,6 +70,36 @@
     TEST_ASSERT(capabilities.hwId.architecture > SemanticVersion());
 }
 
+void testBufferSeek(const Device &device) {
+    try {
+        Buffer buf{device, 1024};
+
+        // SEEK_END should return the size of the buffer
+        TEST_ASSERT(lseek(buf.getFd(), 0, SEEK_END) == 1024);
+
+        // SEEK_SET is supported when moving the file pointer to the start
+        TEST_ASSERT(lseek(buf.getFd(), 0, SEEK_SET) == 0);
+
+        // SEEK_CUR is not supported
+        errno = 0;
+        TEST_ASSERT(lseek(buf.getFd(), 0, SEEK_CUR) == -1);
+        TEST_ASSERT(errno == EINVAL);
+
+        // Non-zero offset is not supported
+        errno = 0;
+        TEST_ASSERT(lseek(buf.getFd(), 1, SEEK_CUR) == -1);
+        TEST_ASSERT(errno == EINVAL);
+
+        errno = 0;
+        TEST_ASSERT(lseek(buf.getFd(), 2, SEEK_END) == -1);
+        TEST_ASSERT(errno == EINVAL);
+
+        errno = 0;
+        TEST_ASSERT(lseek(buf.getFd(), 3, SEEK_SET) == -1);
+        TEST_ASSERT(errno == EINVAL);
+    } catch (std::exception &e) { throw TestFailureException("Buffer seek test: ", e.what()); }
+}
+
 void testNetworkInfoNotExistentIndex(const Device &device) {
     try {
         Network(device, 0);
@@ -81,7 +112,6 @@
 void testNetworkInfoBuffer(const Device &device) {
     try {
         std::shared_ptr<Buffer> buffer = std::make_shared<Buffer>(device, sizeof(networkModelData));
-        buffer->resize(sizeof(networkModelData));
         std::memcpy(buffer->data(), networkModelData, sizeof(networkModelData));
         Network network(device, buffer);
 
@@ -93,7 +123,6 @@
 void testNetworkInfoUnparsableBuffer(const Device &device) {
     try {
         auto buffer = std::make_shared<Buffer>(device, sizeof(networkModelData) / 4);
-        buffer->resize(sizeof(networkModelData) / 4);
         std::memcpy(buffer->data(), networkModelData + sizeof(networkModelData) / 4, sizeof(networkModelData) / 4);
 
         try {
@@ -122,7 +151,6 @@
 void testRunInferenceBuffer(const Device &device) {
     try {
         auto networkBuffer = std::make_shared<Buffer>(device, sizeof(networkModelData));
-        networkBuffer->resize(sizeof(networkModelData));
         std::memcpy(networkBuffer->data(), networkModelData, sizeof(networkModelData));
         auto network = std::make_shared<Network>(device, networkBuffer);
 
@@ -130,7 +158,6 @@
         std::vector<std::shared_ptr<Buffer>> outputBuffers;
 
         auto inputBuffer = std::make_shared<Buffer>(device, sizeof(inputData));
-        inputBuffer->resize(sizeof(inputData));
         std::memcpy(inputBuffer->data(), inputData, sizeof(inputData));
 
         inputBuffers.push_back(inputBuffer);
@@ -168,6 +195,7 @@
         testPing(device);
         testDriverVersion(device);
         testCapabilties(device);
+        testBufferSeek(device);
         testNetworkInvalidType(device);
         testNetworkInfoNotExistentIndex(device);
         testNetworkInfoBuffer(device);
diff --git a/utils/inference_runner/inference_runner.cpp b/utils/inference_runner/inference_runner.cpp
index 569fda6..c7a18b0 100644
--- a/utils/inference_runner/inference_runner.cpp
+++ b/utils/inference_runner/inference_runner.cpp
@@ -1,6 +1,5 @@
 /*
- * Copyright (c) 2020-2023 Arm Limited. All rights reserved.
- *
+ * SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
  * SPDX-License-Identifier: Apache-2.0
  *
  * Licensed under the Apache License, Version 2.0 (the License); you may
@@ -69,7 +68,6 @@
     stream.seekg(0, ios_base::beg);
 
     shared_ptr<Buffer> buffer = make_shared<Buffer>(device, size);
-    buffer->resize(size);
     stream.read(buffer->data(), size);
 
     return buffer;
@@ -102,7 +100,6 @@
     vector<shared_ptr<Buffer>> ifm;
     for (auto size : network->getIfmDims()) {
         shared_ptr<Buffer> buffer = make_shared<Buffer>(device, size);
-        buffer->resize(size);
         stream.read(buffer->data(), size);
 
         if (!stream) {