Message ID | 20241101142017.79311-4-abdellatif.elkhlifi@arm.com |
---|---|
State | Needs Review / ACK |
Delegated to: | Tom Rini |
Headers | show |
Series | arm_ffa: Add FFA_MEM_SHARE and FFA_MEM_RECLAIM support | expand |
[...] > } > > +/** > + * ffa_memory_reclaim_hdlr() - FFA_MEM_RECLAIM handler function > + * @dev: The FF-A bus device > + * @g_handle: The memory region globally unique Handle > + * @flags: Zero memory and time slicing flags > + * > + * Implement FFA_MEM_RECLAIM FF-A function > + * to restore exclusive access to a memory region back to its Owner. > + * > + * Return: > + * > + * 0 on success. Otherwise, failure > + */ > +int ffa_memory_reclaim_hdlr(struct udevice *dev, u64 g_handle, u32 flags) > +{ > + ffa_value_t res; > + int ffa_errno; > + > + invoke_ffa_fn((ffa_value_t){ > + .a0 = FFA_SMC_32(FFA_MEM_RECLAIM), > + .a1 = HANDLE_LOW(g_handle), .a2 = HANDLE_HIGH(g_handle), > + .a3 = flags, > + }, > + &res > + ); > + > + if (res.a0 != FFA_SMC_32(FFA_SUCCESS)) { > + ffa_errno = res.a2; > + ffa_print_error_log(FFA_MEM_RECLAIM, ffa_errno); > + return ffa_to_std_errno(ffa_errno); > + } > + > + return 0; > +} Is there a reason you have to define both ffa_memory_reclaim_hdlr() and ffa_memory_reclaim()? Can't you just move the checks of ffa_memory_reclaim() to ffa_memory_reclaim_hdlr()? > + > /* FF-A driver operations (used by clients for communicating with FF-A)*/ > > /** > @@ -1214,6 +1261,29 @@ int ffa_memory_share(struct udevice *dev, struct ffa_mem_ops_args *args) > return ops->memory_share(dev, args); > } > > +/** > + * ffa_memory_reclaim() - FFA_MEM_RECLAIM driver operation > + * @dev: The FF-A bus device > + * @g_handle: The memory region globally unique Handle > + * @flags: Zero memory and time slicing flags > + * > + * Driver operation for FFA_MEM_RECLAIM. > + * Please see ffa_memory_reclaim_hdlr() description for more details. > + * > + * Return: > + * > + * 0 on success. Otherwise, failure > + */ > +int ffa_memory_reclaim(struct udevice *dev, u64 g_handle, u32 flags) > +{ > + struct ffa_bus_ops *ops = ffa_get_ops(dev); > + > + if (!ops || !ops->memory_reclaim) > + return -ENOSYS; > + > + return ops->memory_reclaim(dev, g_handle, flags); > +} > + > /** > * ffa_do_probe() - probing FF-A framework > * @dev: the FF-A bus device (arm_ffa) > diff --git a/drivers/firmware/arm-ffa/arm-ffa.c b/drivers/firmware/arm-ffa/arm-ffa.c > index c4211c953ef..b7e751e3821 100644 > --- a/drivers/firmware/arm-ffa/arm-ffa.c > +++ b/drivers/firmware/arm-ffa/arm-ffa.c > @@ -85,6 +85,7 @@ static const struct ffa_bus_ops ffa_ops = { > .sync_send_receive = ffa_msg_send_direct_req_hdlr, > .rxtx_unmap = ffa_unmap_rxtx_buffers_hdlr, > .memory_share = ffa_memory_share_hdlr, > + .memory_reclaim = ffa_memory_reclaim_hdlr, > }; > [...] Thanks /Ilias
Hi Ilias, > > +/** > > + * ffa_memory_reclaim_hdlr() - FFA_MEM_RECLAIM handler function > > + * @dev: The FF-A bus device > > + * @g_handle: The memory region globally unique Handle > > + * @flags: Zero memory and time slicing flags > > + * > > + * Implement FFA_MEM_RECLAIM FF-A function > > + * to restore exclusive access to a memory region back to its Owner. > > + * > > + * Return: > > + * > > + * 0 on success. Otherwise, failure > > + */ > > +int ffa_memory_reclaim_hdlr(struct udevice *dev, u64 g_handle, u32 flags) > > +{ > > + ffa_value_t res; > > + int ffa_errno; > > + > > + invoke_ffa_fn((ffa_value_t){ > > + .a0 = FFA_SMC_32(FFA_MEM_RECLAIM), > > + .a1 = HANDLE_LOW(g_handle), .a2 = HANDLE_HIGH(g_handle), > > + .a3 = flags, > > + }, > > + &res > > + ); > > + > > + if (res.a0 != FFA_SMC_32(FFA_SUCCESS)) { > > + ffa_errno = res.a2; > > + ffa_print_error_log(FFA_MEM_RECLAIM, ffa_errno); > > + return ffa_to_std_errno(ffa_errno); > > + } > > + > > + return 0; > > +} > > Is there a reason you have to define both ffa_memory_reclaim_hdlr() and ffa_memory_reclaim()? > Can't you just move the checks of ffa_memory_reclaim() to > ffa_memory_reclaim_hdlr()? Yes, ffa_memory_reclaim() is the FF-A bus operation which is called by upper layers (clients). ffa_memory_reclaim_hdlr() is the low level handler called by the operation. The handler is set by the driver (e.g: Arm driver, sandbox driver) in the driver's ops structure [5]. So, the driver can set the handler and define its own if needed. The client doesn't know which handler to use. It just calls the driver operation. This design was followed in the other ABIs already merged. For example [1][2][3][4]. [1]: ffa_rxtx_unmap() operation: drivers/firmware/arm-ffa/arm-ffa-uclass.c#L999 [2]: ffa_unmap_rxtx_buffers_hdlr() handler: drivers/firmware/arm-ffa/arm-ffa-uclass.c#L999 [3]: rxtx_unmap ops callback in sandbox driver: drivers/firmware/arm-ffa/sandbox_ffa.c#L93 [4]: rxtx_unmap ops callback in Arm driver: drivers/firmware/arm-ffa/arm-ffa.c#L86 [5]: Arm's driver ops structure: drivers/firmware/arm-ffa/arm-ffa.c#L83 > > + > > /* FF-A driver operations (used by clients for communicating with FF-A)*/ > > ... > > +/** > > + * ffa_memory_reclaim() - FFA_MEM_RECLAIM driver operation > > + * @dev: The FF-A bus device > > + * @g_handle: The memory region globally unique Handle > > + * @flags: Zero memory and time slicing flags > > + * > > + * Driver operation for FFA_MEM_RECLAIM. > > + * Please see ffa_memory_reclaim_hdlr() description for more details. > > + * > > + * Return: > > + * > > + * 0 on success. Otherwise, failure > > + */ > > +int ffa_memory_reclaim(struct udevice *dev, u64 g_handle, u32 flags) > > +{ > > + struct ffa_bus_ops *ops = ffa_get_ops(dev); > > + > > + if (!ops || !ops->memory_reclaim) > > + return -ENOSYS; > > + > > + return ops->memory_reclaim(dev, g_handle, flags); > > +} Cheers, Abdellatif
diff --git a/doc/arch/arm64.ffa.rst b/doc/arch/arm64.ffa.rst index 3eec735d741..d2c4fb49f79 100644 --- a/doc/arch/arm64.ffa.rst +++ b/doc/arch/arm64.ffa.rst @@ -186,6 +186,7 @@ The following features are provided: - FFA_MSG_SEND_DIRECT_REQ - FFA_MSG_SEND_DIRECT_RESP - FFA_MEM_SHARE + - FFA_MEM_RECLAIM - Support for the 64-bit version of the following ABIs: @@ -205,6 +206,7 @@ The following features are provided: - ffa_sync_send_receive - ffa_rxtx_unmap - ffa_memory_share + - ffa_memory_reclaim - FF-A bus discovery makes sure FF-A framework is responsive and compatible with the driver diff --git a/drivers/firmware/arm-ffa/arm-ffa-uclass.c b/drivers/firmware/arm-ffa/arm-ffa-uclass.c index 8ff666c3757..5eae28386ae 100644 --- a/drivers/firmware/arm-ffa/arm-ffa-uclass.c +++ b/drivers/firmware/arm-ffa/arm-ffa-uclass.c @@ -109,6 +109,18 @@ static struct ffa_abi_errmap err_msg_map[FFA_ERRMAP_COUNT] = { "DENIED: Memory region ownership, permission, access or attributes error", }, }, + [FFA_ID_TO_ERRMAP_ID(FFA_MEM_RECLAIM)] = { + { + [ABORTED] = + "ABORTED: ABI invocation failure", + [INVALID_PARAMETERS] = + "INVALID_PARAMETERS: Invalid handle or flags", + [NO_MEMORY] = + "NO_MEMORY: Failure to create the Owner's mapping", + [DENIED] = + "DENIED: Memory region state issue", + }, + }, }; /** @@ -1115,6 +1127,41 @@ int ffa_memory_share_hdlr(struct udevice *dev, struct ffa_mem_ops_args *args) return ffa_memory_ops(dev, FFA_MEM_SHARE, args); } +/** + * ffa_memory_reclaim_hdlr() - FFA_MEM_RECLAIM handler function + * @dev: The FF-A bus device + * @g_handle: The memory region globally unique Handle + * @flags: Zero memory and time slicing flags + * + * Implement FFA_MEM_RECLAIM FF-A function + * to restore exclusive access to a memory region back to its Owner. + * + * Return: + * + * 0 on success. Otherwise, failure + */ +int ffa_memory_reclaim_hdlr(struct udevice *dev, u64 g_handle, u32 flags) +{ + ffa_value_t res; + int ffa_errno; + + invoke_ffa_fn((ffa_value_t){ + .a0 = FFA_SMC_32(FFA_MEM_RECLAIM), + .a1 = HANDLE_LOW(g_handle), .a2 = HANDLE_HIGH(g_handle), + .a3 = flags, + }, + &res + ); + + if (res.a0 != FFA_SMC_32(FFA_SUCCESS)) { + ffa_errno = res.a2; + ffa_print_error_log(FFA_MEM_RECLAIM, ffa_errno); + return ffa_to_std_errno(ffa_errno); + } + + return 0; +} + /* FF-A driver operations (used by clients for communicating with FF-A)*/ /** @@ -1214,6 +1261,29 @@ int ffa_memory_share(struct udevice *dev, struct ffa_mem_ops_args *args) return ops->memory_share(dev, args); } +/** + * ffa_memory_reclaim() - FFA_MEM_RECLAIM driver operation + * @dev: The FF-A bus device + * @g_handle: The memory region globally unique Handle + * @flags: Zero memory and time slicing flags + * + * Driver operation for FFA_MEM_RECLAIM. + * Please see ffa_memory_reclaim_hdlr() description for more details. + * + * Return: + * + * 0 on success. Otherwise, failure + */ +int ffa_memory_reclaim(struct udevice *dev, u64 g_handle, u32 flags) +{ + struct ffa_bus_ops *ops = ffa_get_ops(dev); + + if (!ops || !ops->memory_reclaim) + return -ENOSYS; + + return ops->memory_reclaim(dev, g_handle, flags); +} + /** * ffa_do_probe() - probing FF-A framework * @dev: the FF-A bus device (arm_ffa) diff --git a/drivers/firmware/arm-ffa/arm-ffa.c b/drivers/firmware/arm-ffa/arm-ffa.c index c4211c953ef..b7e751e3821 100644 --- a/drivers/firmware/arm-ffa/arm-ffa.c +++ b/drivers/firmware/arm-ffa/arm-ffa.c @@ -85,6 +85,7 @@ static const struct ffa_bus_ops ffa_ops = { .sync_send_receive = ffa_msg_send_direct_req_hdlr, .rxtx_unmap = ffa_unmap_rxtx_buffers_hdlr, .memory_share = ffa_memory_share_hdlr, + .memory_reclaim = ffa_memory_reclaim_hdlr, }; /* Registering the FF-A driver as an SMCCC feature driver */ diff --git a/include/arm_ffa.h b/include/arm_ffa.h index ce4a3d7f440..965139b166a 100644 --- a/include/arm_ffa.h +++ b/include/arm_ffa.h @@ -147,8 +147,9 @@ struct ffa_mem_ops_args { * struct ffa_bus_ops - Operations for FF-A * @partition_info_get: callback for the FFA_PARTITION_INFO_GET * @sync_send_receive: callback for the FFA_MSG_SEND_DIRECT_REQ - * @rxtx_unmap: callback for the FFA_RXTX_UNMAP + * @rxtx_unmap: callback for the FFA_RXTX_UNMAP * @memory_share: callback for the FFA_MEM_SHARE + * @memory_reclaim: callback for the FFA_MEM_RECLAIM * * The data structure providing all the operations supported by the driver. * This structure is EFI runtime resident. @@ -161,6 +162,7 @@ struct ffa_bus_ops { bool is_smc64); int (*rxtx_unmap)(struct udevice *dev); int (*memory_share)(struct udevice *dev, struct ffa_mem_ops_args *args); + int (*memory_reclaim)(struct udevice *dev, u64 g_handle, u32 flags); }; #define ffa_get_ops(dev) ((struct ffa_bus_ops *)(dev)->driver->ops) @@ -280,6 +282,27 @@ int ffa_memory_share(struct udevice *dev, struct ffa_mem_ops_args *args); */ int ffa_memory_share_hdlr(struct udevice *dev, struct ffa_mem_ops_args *args); +/** + * ffa_memory_reclaim() - FFA_MEM_RECLAIM driver operation + * Please see ffa_memory_reclaim_hdlr() description for more details. + */ +int ffa_memory_reclaim(struct udevice *dev, u64 g_handle, u32 flags); + +/** + * ffa_memory_reclaim_hdlr() - FFA_MEM_RECLAIM handler function + * @dev: The FF-A bus device + * @g_handle: The memory region globally unique Handle + * @flags: Zero memory and time slicing flags + * + * Implement FFA_MEM_RECLAIM FF-A function + * to restore exclusive access to a memory region back to its Owner. + * + * Return: + * + * 0 on success. Otherwise, failure + */ +int ffa_memory_reclaim_hdlr(struct udevice *dev, u64 g_handle, u32 flags); + struct ffa_priv; /** diff --git a/include/arm_ffa_priv.h b/include/arm_ffa_priv.h index 02e2cd89937..09205f40907 100644 --- a/include/arm_ffa_priv.h +++ b/include/arm_ffa_priv.h @@ -133,10 +133,11 @@ enum ffa_abis { FFA_MSG_SEND_DIRECT_REQ = 0x6f, FFA_MSG_SEND_DIRECT_RESP = 0x70, FFA_MEM_SHARE = 0x73, + FFA_MEM_RECLAIM = 0x77, /* To be updated when adding new FFA IDs */ FFA_FIRST_ID = FFA_ERROR, /* Lowest number ID */ - FFA_LAST_ID = FFA_MEM_SHARE, /* Highest number ID */ + FFA_LAST_ID = FFA_MEM_RECLAIM, /* Highest number ID */ }; enum ffa_abi_errcode {