When the MMU is disabled (CONFIG_ARCH_USE_MMU=n) the
data passed back and forth with the TEE needs to be
synced from/to the cache, otherwise we get random data
in either world.
Fix this by cleaning before a call and invalidating after.
This has to be done both on the optee msg arg, and the shm
buffers therein. Cleaning and invalidating the page list
used to describe non-contiguous shm buffers did not seem
mandatory in my tests, but common sense says that it should
be, so we do that too.
This fix does not apply to the optee msg arg of the socket
transport (optee_socket.c), as that one _should_ be handled
by the socket send/recv methods. It does apply to all shm
buffers though, regardless of transport.
Signed-off-by: George Poulios <gpoulios@census-labs.com>
This patch is a rework of the NuttX file descriptor implementation. The
goal is two-fold:
1. Improve POSIX compliance. The old implementation tied file description
to inode only, not the file struct. POSIX however dictates otherwise.
2. Fix a bug with descriptor duplication (dup2() and dup3()). There is
an existing race condition with this POSIX API that currently results
in a kernel side crash.
The crash occurs when a partially open / closed file descriptor is
duplicated. The reason for the crash is that even if the descriptor is
closed, the file might still be in use by the kernel (due to e.g. ongoing
write to file). The open file data is changed by file_dup3() and this
causes a crash in the device / drivers themselves as they lose access to
the inode and private data.
The fix is done by separating struct file into file and file descriptor
structs. The file struct can live on even if the descriptor is closed,
fixing the crash. This also fixes the POSIX issue, as two descriptors
can now point to the same file.
Signed-off-by: Ville Juven <ville.juven@unikie.com>
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
So far the NuttX implementation of OP-TEE has been using
registered memory references to pass non-registered memory
to OP-TEE OS, passing the physical address of the memory
in what is normally used as a 'cookie'. This was compatible
with the Openvela framework, but no other OP-TEE OS.
Fix this by passing temporary memory instead with the standard
non-contiguous (OPTEE_MSG_ATTR_NONCONTIG) flag.
Signed-off-by: George Poulios <gpoulios@census-labs.com>
This is mostly to handle the case that the user calls
close() before calling close() on the shm. In that case
optee_close() frees the shm and then optee_shm_close()
operates on an invalid reference. Fix that.
Signed-off-by: George Poulios <gpoulios@census-labs.com>
This is no longer (exactly) the linked list entry that it
used to be, but rather an associated pointer in an idr tree
entry. Plain 'optee_shm' is more concise, and more appropriate.
Changes also reg_pair_to_uintptr() to reg_pair_to_ptr() for
better readability in invocations.
Signed-off-by: George Poulios <gpoulios@census-labs.com>
Previous implementation was not compatible with GlobalPlatform
API in the following ways:
- Registered mem IDs would begin from negatives when it should
have been greater than or equal to 0
- Register IOCTL would return 0 on success, when it should have
been returning a file descriptor.
- Register IOCTL would expect the user-space client to specify
TEE_SHM_* flags dictating its behaviour when in fact, libteec
never specifies flags.
This commit fixes all those issues. It uses nuttx/idr.h instead
of a linked list, and it uses `file_allocate` to provide file
descriptors for registered shared memory. Upon close(fd), the
memory is de-registered and freed accordingly. It also updates
the documentation accordingly.
Signed-off-by: George Poulios <gpoulios@census-labs.com>
Some calls to `optee_is_valid_range()` would return
-EINVAL and some would return -EACCESS. Change all to
-EFAULT (Bad Address) which is more appropriate.
Signed-off-by: George Poulios <gpoulios@census-labs.com>
So far NuttX has supported OP-TEE interfacing over
local and RPMsg sockets. This commit introduces support
for direct invocation of OP-TEE through arm SMCs. The
SMC transport is enabled through CONFIG_DEV_OPTEE_SMC.
This SMC implementation has been tested only with arm64,
OP-TEE rev 4.4.
Note that it does not support reverse direction RPCs,
i.e. from the Secure World to the Normal World to
something like optee supplicant. A basic RPC handling
skeleton is provided with implementation for some
basic functions (alloc/free mem, and foreign interrupts)
but no supplicant command handling.
(+one minor change s/parm/param in arch/arm64/include/syscall
to satisfy the spellchecker during PR)
Signed-off-by: George Poulios <gpoulios@census-labs.com>
Adds support for SHM_REGISTER IOCTL. Registration can
be requested both against the driver (for automatic cleanup)
and against the secure OS (for sharing).
Introduces also `optee_{msg,free}_alloc()` to allocate
aligned memory for message arguments depending on the
`alignment` specified in the driver's private data. For
alignment greater than word size, memory is allocated on the
heap, otherwise it's allocated on the stack (similar to the
previous implementation but using `alloca()` instead).
Signed-off-by: George Poulios <gpoulios@census-labs.com>
Besides a few checks for NULL IOCTL argument values, this
commits introduces also a check to ensure that user specified
memory (mainly IOCTL arguments) indeed belongs to the user.
This is applicable only with `CONFIG_ARCH_ADDRENV`.
Signed-off-by: George Poulios <gpoulios@census-labs.com>
Prepares the ground for introducing new transports to
the OP-TEE driver. "transports" as in alternatives to
RPMsg and local network.
Signed-off-by: George Poulios <gpoulios@census-labs.com>
examples:
There are two threads involved: thread A with a priority of 100 and
thread B with a priority of 101. Here's how they interact:
When thread A releases a semaphore, thread B is scheduled to execute
some code and may reacquire the semaphore. If no other tasks are ready,
thread A will be scheduled to run.
This continuous process can lead to a busy loop.
Thread A: Thread B:
while (nxsem_get_value(&priv->wait, &semcount) >= 0 && <---
semcount <= 0) | 2)context switch
{ 1)contex switch |
nxsem_post(&priv->wait); -------------> run some code and nxsem_wait again
}
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
misc/rpmsgblk_server.c:135:16: warning: format '%d' expects argument of type 'int', but argument 3 has type 'int32_t' {aka 'long int'} [-Wformat=]
135 | ferr("block device open failed, ret=%d\n", msg->header.result);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
| |
| int32_t {aka long int}
misc/rpmsgblk_server.c:135:48: note: format string is defined here
135 | ferr("block device open failed, ret=%d\n", msg->header.result);
| ~^
| |
| int
| %ld
misc/rpmsgblk_server.c: In function 'rpmsgblk_close_handler':
misc/rpmsgblk_server.c:170:16: warning: format '%d' expects argument of type 'int', but argument 3 has type 'int32_t' {aka 'long int'} [-Wformat=]
170 | ferr("block device close failed, ret=%d\n", msg->header.result);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
| |
| int32_t {aka long int}
misc/rpmsgblk_server.c:170:49: note: format string is defined here
170 | ferr("block device close failed, ret=%d\n", msg->header.result);
| ~^
| |
| int
| %ld
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
This forces the bch layer to read the sector from the physical device
instead of using the cached values. It is necessary to call when the
device is updated from the different source than bch, for example
erased by the MTD ioctl command.
It also has to invalidate readahead buffer from FTL if option
CONFIG_DRVR_READAHEAD is set.
Signed-off-by: Michal Lenc <michallenc@seznam.cz>
* Make readv/writev implementations update struct uio
This can simplify partial result handling.
* change the error number on the overflow from EOVERFLOW to EINVAL
to match NetBSD
* add a commented out uio_offset field. I used "#if 0" here as
C comments can't nest.
* add a few helper functions
Note on uio_copyfrom/uio_copyto:
although i'm not quite happy with the "offset" functionality,
it's necessary to simplify the adaptation of some drivers like
drivers/serial/serial.c, which (ab)uses the user-supplied buffer
as a line-buffer.
/dev/zero is a very commonly used config, for example use
/dev/zero to test the filesystem, mtd or block devices performance.
So let's default enable it when not enable DEFAULT_SMALL
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
when client read and poll wait buffer from server side and server side may
poll notify more than one times, then rpmsgdev in client side will call
"rpmsgdev_poll_setup(priv, 0, false);" twice which will cause crash in
vela rpmsgdev_server.c
Signed-off-by: rongyichang <rongyichang@xiaomi.com>
the msg count is not changed while iov len is increased.
which may cause the buffer reply by server is bigger than
msg count
Signed-off-by: rongyichang <rongyichang@xiaomi.com>
Most tools used for compliance and SBOM generation use SPDX identifiers
This change brings us a step closer to an easy SBOM generation.
Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
This patch fixed userspace headers conflict. Architecture-related definition and API should not be exposed to users.
Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
currently, nuttx implements readv/writev on the top of read/write.
while it might work for the simplest cases, it's broken by design.
for example, it's impossible to make it work correctly for files
which need to preserve data boundaries without allocating a single
contiguous buffer. (udp socket, some character devices, etc)
this change is a start of the migration to a better design.
that is, implement read/write on the top of readv/writev.
to avoid a single huge change, following things will NOT be done in
this commit:
* fix actual bugs caused by the original readv-based-on-read design.
(cf. https://github.com/apache/nuttx/pull/12674)
* adapt filesystems/drivers to actually benefit from the new interface.
(except a few trivial examples)
* eventually retire the old interface.
* retire read/write syscalls. implement them in libc instead.
* pread/pwrite/preadv/pwritev (except the introduction of struct uio,
which is a preparation to back these variations with the new
interface.)
A use-after-free problem occurs when there are multiple remotes in the list `g_rpmsg` and the matching remote is not the last item in the list.
Log
# Export the device "/dev/LOCAL_DEV" to remote "REMOTE_CPU"
ap> testdev -d 2 -c "REMOTE_CPU" -l "/dev/LOCAL_DEV"
[ap] kasan_report: kasan detected a read access error, address at 0x3c3d4740,size is 4, return address: 0x2c33620f
[ap] kasan_show_memory: Shadow bytes around the buggy address:
[ap] kasan_show_memory: 0x3c3d46f0: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
[ap] kasan_show_memory: 0x3c3d4700: aa aa aa aa cc cc cc cc cc cc cc cc cc cc cc cc
[ap] kasan_show_memory: 0x3c3d4710: 40 47 3d 3c ed 61 33 2c 00 00 00 00 00 00 00 00
[ap] kasan_show_memory: 0x3c3d4720: 00 00 00 00 00 00 00 00 00 00 00 00 cc cc cc cc
[ap] kasan_show_memory: 0x3c3d4730: 55 55 55 55 38 00 00 00 02 2c 00 00 cc cc cc cc
[ap] kasan_show_memory: 0x3c3d4740:[00 00 00 00]66 e0 42 3c cc cc cc cc cc cc cc cc
[ap] kasan_show_memory: 0x3c3d4750: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
[ap] kasan_show_memory: 0x3c3d4760: aa aa aa aa 38 00 00 00 01 2c 00 00 cc cc cc cc
[ap] kasan_show_memory: 0x3c3d4770: 50 57 44 3d 2f 00 cc cc cc cc cc cc cc cc cc cc
[ap] kasan_show_memory: 0x3c3d4780: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
[ap] dump_assert_info: Current Version: NuttX ****** ***** *** 12.3.0 **********-***** *** ** 2024 **:**:** arm
[ap] dump_assert_info: Assertion failed panic: at file: kasan/hook.c:187 task: testdev process: testdev 0x2ca20495
$ addr2line -fe nuttx/nuttx 0x2c33620f
rpmsgdev_server_created
/workspace/nuttx/drivers/misc/rpmsgdev_server.c:529
# Line 529 => strcmp()
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Rpmsg dev server always open the real char device with nonblock mode,
so let client try to read/wrtie the read device every read/write
operation.
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
misc/rpmsgblk.c:616:29: warning: implicit declaration of function ‘rpmsg_virtio_get_buffer_size’; did you mean ‘rpmsg_get_rx_buffer_size’? [-Wimplicit-function-declaration]
616 | if (MAX(msglen, rsplen) > rpmsg_virtio_get_buffer_size(priv->ept.rdev))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| rpmsg_get_rx_buffer_size
Signed-off-by: Yongrong Wang <wangyongrong@xiaomi.com>
x86_64 uses 4-5G virtual addresses, we need to convert them into physical addresses and pass them to qemu, otherwise qemu will fail to map
Signed-off-by: liwenxiang1 <liwenxiang1@xiaomi.com>