Files
linux/drivers/tee/qcomtee/qcomtee_object.h
Linus Torvalds bf4afc53b7 Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
This was done entirely with mindless brute force, using

    git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
        xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'

to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.

Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.

For the same reason the 'flex' versions will be done as a separate
conversion.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21 17:09:51 -08:00

317 lines
10 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef QCOMTEE_OBJECT_H
#define QCOMTEE_OBJECT_H
#include <linux/completion.h>
#include <linux/kref.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
struct qcomtee_object;
/**
* DOC: Overview
*
* qcomtee_object provides object refcounting, ID allocation for objects hosted
* in the kernel, and necessary message marshaling for Qualcomm TEE (QTEE).
*
* To invoke an object in QTEE, the user calls qcomtee_object_do_invoke()
* while passing an instance of &struct qcomtee_object and the requested
* operation + arguments.
*
* After boot, QTEE provides a static object %ROOT_QCOMTEE_OBJECT (type of
* %QCOMTEE_OBJECT_TYPE_ROOT). The root object is invoked to pass the user's
* credentials and obtain other instances of &struct qcomtee_object (type of
* %QCOMTEE_OBJECT_TYPE_TEE) that represent services and TAs in QTEE;
* see &enum qcomtee_object_type.
*
* The objects received from QTEE are refcounted. So the owner of these objects
* can issue qcomtee_object_get() to increase the refcount and pass objects
* to other clients, or issue qcomtee_object_put() to decrease the refcount
* and release the resources in QTEE.
*
* The kernel can host services accessible to QTEE. A driver should embed
* an instance of &struct qcomtee_object in the struct it wants to export to
* QTEE (this is called a callback object). It issues qcomtee_object_user_init()
* to set the dispatch() operation for the callback object and set its type
* to %QCOMTEE_OBJECT_TYPE_CB.
*
* core.c holds an object table for callback objects. An object ID is assigned
* to each callback object, which is an index to the object table. QTEE uses
* these IDs to reference or invoke callback objects.
*
* If QTEE invokes a callback object in the kernel, the dispatch() operation is
* called in the context of the thread that originally called
* qcomtee_object_do_invoke().
*/
/**
* enum qcomtee_object_type - Object types.
* @QCOMTEE_OBJECT_TYPE_TEE: object hosted on QTEE.
* @QCOMTEE_OBJECT_TYPE_CB: object hosted on kernel.
* @QCOMTEE_OBJECT_TYPE_ROOT: 'primordial' object.
* @QCOMTEE_OBJECT_TYPE_NULL: NULL object.
*
* The primordial object is used for bootstrapping the IPC connection between
* the kernel and QTEE. It is invoked by the kernel when it wants to get a
* 'client env'.
*/
enum qcomtee_object_type {
QCOMTEE_OBJECT_TYPE_TEE,
QCOMTEE_OBJECT_TYPE_CB,
QCOMTEE_OBJECT_TYPE_ROOT,
QCOMTEE_OBJECT_TYPE_NULL,
};
/**
* enum qcomtee_arg_type - Type of QTEE argument.
* @QCOMTEE_ARG_TYPE_INV: invalid type.
* @QCOMTEE_ARG_TYPE_OB: output buffer (OB).
* @QCOMTEE_ARG_TYPE_OO: output object (OO).
* @QCOMTEE_ARG_TYPE_IB: input buffer (IB).
* @QCOMTEE_ARG_TYPE_IO: input object (IO).
*
* Use the invalid type to specify the end of the argument array.
*/
enum qcomtee_arg_type {
QCOMTEE_ARG_TYPE_INV = 0,
QCOMTEE_ARG_TYPE_OB,
QCOMTEE_ARG_TYPE_OO,
QCOMTEE_ARG_TYPE_IB,
QCOMTEE_ARG_TYPE_IO,
QCOMTEE_ARG_TYPE_NR,
};
/**
* define QCOMTEE_ARGS_PER_TYPE - Maximum arguments of a specific type.
*
* The QTEE transport protocol limits the maximum number of arguments of
* a specific type (i.e., IB, OB, IO, and OO).
*/
#define QCOMTEE_ARGS_PER_TYPE 16
/* Maximum arguments that can fit in a QTEE message, ignoring the type. */
#define QCOMTEE_ARGS_MAX (QCOMTEE_ARGS_PER_TYPE * (QCOMTEE_ARG_TYPE_NR - 1))
struct qcomtee_buffer {
union {
void *addr;
void __user *uaddr;
};
size_t size;
};
/**
* struct qcomtee_arg - Argument for QTEE object invocation.
* @type: type of argument as &enum qcomtee_arg_type.
* @flags: extra flags.
* @b: address and size if the type of argument is a buffer.
* @o: object instance if the type of argument is an object.
*
* &qcomtee_arg.flags only accepts %QCOMTEE_ARG_FLAGS_UADDR for now, which
* states that &qcomtee_arg.b contains a userspace address in uaddr.
*/
struct qcomtee_arg {
enum qcomtee_arg_type type;
/* 'b.uaddr' holds a __user address. */
#define QCOMTEE_ARG_FLAGS_UADDR BIT(0)
unsigned int flags;
union {
struct qcomtee_buffer b;
struct qcomtee_object *o;
};
};
static inline int qcomtee_args_len(struct qcomtee_arg *args)
{
int i = 0;
while (args[i].type != QCOMTEE_ARG_TYPE_INV)
i++;
return i;
}
/* Context is busy (callback is in progress). */
#define QCOMTEE_OIC_FLAG_BUSY BIT(1)
/* Context needs to notify the current object. */
#define QCOMTEE_OIC_FLAG_NOTIFY BIT(2)
/* Context has shared state with QTEE. */
#define QCOMTEE_OIC_FLAG_SHARED BIT(3)
/**
* struct qcomtee_object_invoke_ctx - QTEE context for object invocation.
* @ctx: TEE context for this invocation.
* @flags: flags for the invocation context.
* @errno: error code for the invocation.
* @object: current object invoked in this callback context.
* @u: array of arguments for the current invocation (+1 for ending arg).
* @in_msg: inbound buffer shared with QTEE.
* @out_msg: outbound buffer shared with QTEE.
* @in_shm: TEE shm allocated for inbound buffer.
* @out_shm: TEE shm allocated for outbound buffer.
* @data: extra data attached to this context.
*/
struct qcomtee_object_invoke_ctx {
struct tee_context *ctx;
unsigned long flags;
int errno;
struct qcomtee_object *object;
struct qcomtee_arg u[QCOMTEE_ARGS_MAX + 1];
struct qcomtee_buffer in_msg;
struct qcomtee_buffer out_msg;
struct tee_shm *in_shm;
struct tee_shm *out_shm;
void *data;
};
static inline struct qcomtee_object_invoke_ctx *
qcomtee_object_invoke_ctx_alloc(struct tee_context *ctx)
{
struct qcomtee_object_invoke_ctx *oic;
oic = kzalloc_obj(*oic);
if (oic)
oic->ctx = ctx;
return oic;
}
/**
* qcomtee_object_do_invoke() - Submit an invocation for an object.
* @oic: context to use for the current invocation.
* @object: object being invoked.
* @op: requested operation on the object.
* @u: array of arguments for the current invocation.
* @result: result returned from QTEE.
*
* The caller is responsible for keeping track of the refcount for each object,
* including @object. On return, the caller loses ownership of all input
* objects of type %QCOMTEE_OBJECT_TYPE_CB.
*
* @object can be of %QCOMTEE_OBJECT_TYPE_ROOT or %QCOMTEE_OBJECT_TYPE_TEE.
*
* Return: On success, returns 0; on failure, returns < 0.
*/
int qcomtee_object_do_invoke(struct qcomtee_object_invoke_ctx *oic,
struct qcomtee_object *object, u32 op,
struct qcomtee_arg *u, int *result);
/**
* struct qcomtee_object_operations - Callback object operations.
* @release: release the object if QTEE is not using it.
* @dispatch: dispatch the operation requested by QTEE.
* @notify: report the status of any pending response submitted by @dispatch.
*/
struct qcomtee_object_operations {
void (*release)(struct qcomtee_object *object);
int (*dispatch)(struct qcomtee_object_invoke_ctx *oic,
struct qcomtee_object *object, u32 op,
struct qcomtee_arg *args);
void (*notify)(struct qcomtee_object_invoke_ctx *oic,
struct qcomtee_object *object, int err);
};
/**
* struct qcomtee_object - QTEE or kernel object.
* @name: object name.
* @refcount: reference counter.
* @object_type: object type as &enum qcomtee_object_type.
* @info: extra information for the object.
* @ops: callback operations for objects of type %QCOMTEE_OBJECT_TYPE_CB.
* @work: work for async operations on the object.
*
* @work is used for releasing objects of %QCOMTEE_OBJECT_TYPE_TEE type.
*/
struct qcomtee_object {
const char *name;
struct kref refcount;
enum qcomtee_object_type object_type;
struct object_info {
unsigned long qtee_id;
/* TEE context for QTEE object async requests. */
struct tee_context *qcomtee_async_ctx;
} info;
struct qcomtee_object_operations *ops;
struct work_struct work;
};
/* Static instances of qcomtee_object objects. */
#define NULL_QCOMTEE_OBJECT ((struct qcomtee_object *)(0))
extern struct qcomtee_object qcomtee_object_root;
#define ROOT_QCOMTEE_OBJECT (&qcomtee_object_root)
static inline enum qcomtee_object_type
typeof_qcomtee_object(struct qcomtee_object *object)
{
if (object == NULL_QCOMTEE_OBJECT)
return QCOMTEE_OBJECT_TYPE_NULL;
return object->object_type;
}
static inline const char *qcomtee_object_name(struct qcomtee_object *object)
{
if (object == NULL_QCOMTEE_OBJECT)
return "null";
if (!object->name)
return "no-name";
return object->name;
}
/**
* qcomtee_object_user_init() - Initialize an object for the user.
* @object: object to initialize.
* @ot: type of object as &enum qcomtee_object_type.
* @ops: instance of callbacks.
* @fmt: name assigned to the object.
*
* Return: On success, returns 0; on failure, returns < 0.
*/
int qcomtee_object_user_init(struct qcomtee_object *object,
enum qcomtee_object_type ot,
struct qcomtee_object_operations *ops,
const char *fmt, ...) __printf(4, 5);
/* Object release is RCU protected. */
int qcomtee_object_get(struct qcomtee_object *object);
void qcomtee_object_put(struct qcomtee_object *object);
#define qcomtee_arg_for_each(i, args) \
for (i = 0; args[i].type != QCOMTEE_ARG_TYPE_INV; i++)
/* Next argument of type @type after index @i. */
int qcomtee_next_arg_type(struct qcomtee_arg *u, int i,
enum qcomtee_arg_type type);
/* Iterate over argument of given type. */
#define qcomtee_arg_for_each_type(i, args, at) \
for (i = qcomtee_next_arg_type(args, 0, at); \
args[i].type != QCOMTEE_ARG_TYPE_INV; \
i = qcomtee_next_arg_type(args, i + 1, at))
#define qcomtee_arg_for_each_input_buffer(i, args) \
qcomtee_arg_for_each_type(i, args, QCOMTEE_ARG_TYPE_IB)
#define qcomtee_arg_for_each_output_buffer(i, args) \
qcomtee_arg_for_each_type(i, args, QCOMTEE_ARG_TYPE_OB)
#define qcomtee_arg_for_each_input_object(i, args) \
qcomtee_arg_for_each_type(i, args, QCOMTEE_ARG_TYPE_IO)
#define qcomtee_arg_for_each_output_object(i, args) \
qcomtee_arg_for_each_type(i, args, QCOMTEE_ARG_TYPE_OO)
struct qcomtee_object *
qcomtee_object_get_client_env(struct qcomtee_object_invoke_ctx *oic);
struct qcomtee_object *
qcomtee_object_get_service(struct qcomtee_object_invoke_ctx *oic,
struct qcomtee_object *client_env, u32 uid);
#endif /* QCOMTEE_OBJECT_H */