[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [XEN PATCH 5/6] xen/arm: ffa: separate rxtx buffer routines
Hi Jens, > On 25 Mar 2024, at 10:39, Jens Wiklander <jens.wiklander@xxxxxxxxxx> wrote: > > Move rxtx buffer routines into a spearate file for easier navigation in > the source code. > > Add ffa_rxtx_init(), ffa_rxtx_destroy(), and ffa_rxtx_domain_destroy() to > handle the ffa_rxtx internal things on initialization and teardown. > > Signed-off-by: Jens Wiklander <jens.wiklander@xxxxxxxxxx> Reviewed-by: Bertrand Marquis <bertrand.marquis@xxxxxxx> Cheers Bertrand > --- > xen/arch/arm/tee/Makefile | 1 + > xen/arch/arm/tee/ffa.c | 174 +------------------------- > xen/arch/arm/tee/ffa_private.h | 7 ++ > xen/arch/arm/tee/ffa_rxtx.c | 216 +++++++++++++++++++++++++++++++++ > 4 files changed, 229 insertions(+), 169 deletions(-) > create mode 100644 xen/arch/arm/tee/ffa_rxtx.c > > diff --git a/xen/arch/arm/tee/Makefile b/xen/arch/arm/tee/Makefile > index be644fba8055..f0112a2f922d 100644 > --- a/xen/arch/arm/tee/Makefile > +++ b/xen/arch/arm/tee/Makefile > @@ -1,5 +1,6 @@ > obj-$(CONFIG_FFA) += ffa.o > obj-$(CONFIG_FFA) += ffa_shm.o > obj-$(CONFIG_FFA) += ffa_partinfo.o > +obj-$(CONFIG_FFA) += ffa_rxtx.o > obj-y += tee.o > obj-$(CONFIG_OPTEE) += optee.o > diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c > index 7a2803881420..4f7775b8c890 100644 > --- a/xen/arch/arm/tee/ffa.c > +++ b/xen/arch/arm/tee/ffa.c > @@ -65,26 +65,6 @@ > > #include "ffa_private.h" > > -/* > - * Structs below ending with _1_0 are defined in FF-A-1.0-REL and > - * structs ending with _1_1 are defined in FF-A-1.1-REL0. > - */ > - > -/* Endpoint RX/TX descriptor */ > -struct ffa_endpoint_rxtx_descriptor_1_0 { > - uint16_t sender_id; > - uint16_t reserved; > - uint32_t rx_range_count; > - uint32_t tx_range_count; > -}; > - > -struct ffa_endpoint_rxtx_descriptor_1_1 { > - uint16_t sender_id; > - uint16_t reserved; > - uint32_t rx_region_offs; > - uint32_t tx_region_offs; > -}; > - > /* Negotiated FF-A version to use with the SPMC */ > static uint32_t __ro_after_init ffa_version; > > @@ -145,12 +125,6 @@ static bool check_mandatory_feature(uint32_t id) > return !ret; > } > > -static int32_t ffa_rxtx_map(paddr_t tx_addr, paddr_t rx_addr, > - uint32_t page_count) > -{ > - return ffa_simple_call(FFA_RXTX_MAP_64, tx_addr, rx_addr, page_count, 0); > -} > - > static void handle_version(struct cpu_user_regs *regs) > { > struct domain *d = current->domain; > @@ -166,127 +140,6 @@ static void handle_version(struct cpu_user_regs *regs) > ffa_set_regs(regs, vers, 0, 0, 0, 0, 0, 0, 0); > } > > -static uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr, > - register_t rx_addr, uint32_t page_count) > -{ > - uint32_t ret = FFA_RET_INVALID_PARAMETERS; > - struct domain *d = current->domain; > - struct ffa_ctx *ctx = d->arch.tee; > - struct page_info *tx_pg; > - struct page_info *rx_pg; > - p2m_type_t t; > - void *rx; > - void *tx; > - > - if ( !smccc_is_conv_64(fid) ) > - { > - /* > - * Calls using the 32-bit calling convention must ignore the upper > - * 32 bits in the argument registers. > - */ > - tx_addr &= UINT32_MAX; > - rx_addr &= UINT32_MAX; > - } > - > - if ( page_count > FFA_MAX_RXTX_PAGE_COUNT ) > - { > - printk(XENLOG_ERR "ffa: RXTX_MAP: error: %u pages requested (limit > %u)\n", > - page_count, FFA_MAX_RXTX_PAGE_COUNT); > - return FFA_RET_INVALID_PARAMETERS; > - } > - > - /* Already mapped */ > - if ( ctx->rx ) > - return FFA_RET_DENIED; > - > - tx_pg = get_page_from_gfn(d, gfn_x(gaddr_to_gfn(tx_addr)), &t, > P2M_ALLOC); > - if ( !tx_pg ) > - return FFA_RET_INVALID_PARAMETERS; > - > - /* Only normal RW RAM for now */ > - if ( t != p2m_ram_rw ) > - goto err_put_tx_pg; > - > - rx_pg = get_page_from_gfn(d, gfn_x(gaddr_to_gfn(rx_addr)), &t, > P2M_ALLOC); > - if ( !tx_pg ) > - goto err_put_tx_pg; > - > - /* Only normal RW RAM for now */ > - if ( t != p2m_ram_rw ) > - goto err_put_rx_pg; > - > - tx = __map_domain_page_global(tx_pg); > - if ( !tx ) > - goto err_put_rx_pg; > - > - rx = __map_domain_page_global(rx_pg); > - if ( !rx ) > - goto err_unmap_tx; > - > - ctx->rx = rx; > - ctx->tx = tx; > - ctx->rx_pg = rx_pg; > - ctx->tx_pg = tx_pg; > - ctx->page_count = page_count; > - ctx->rx_is_free = true; > - return FFA_RET_OK; > - > -err_unmap_tx: > - unmap_domain_page_global(tx); > -err_put_rx_pg: > - put_page(rx_pg); > -err_put_tx_pg: > - put_page(tx_pg); > - > - return ret; > -} > - > -static void rxtx_unmap(struct ffa_ctx *ctx) > -{ > - unmap_domain_page_global(ctx->rx); > - unmap_domain_page_global(ctx->tx); > - put_page(ctx->rx_pg); > - put_page(ctx->tx_pg); > - ctx->rx = NULL; > - ctx->tx = NULL; > - ctx->rx_pg = NULL; > - ctx->tx_pg = NULL; > - ctx->page_count = 0; > - ctx->rx_is_free = false; > -} > - > -static uint32_t ffa_handle_rxtx_unmap(void) > -{ > - struct domain *d = current->domain; > - struct ffa_ctx *ctx = d->arch.tee; > - > - if ( !ctx->rx ) > - return FFA_RET_INVALID_PARAMETERS; > - > - rxtx_unmap(ctx); > - > - return FFA_RET_OK; > -} > - > -static int32_t ffa_handle_rx_release(void) > -{ > - int32_t ret = FFA_RET_DENIED; > - struct domain *d = current->domain; > - struct ffa_ctx *ctx = d->arch.tee; > - > - if ( !spin_trylock(&ctx->rx_lock) ) > - return FFA_RET_BUSY; > - > - if ( !ctx->page_count || ctx->rx_is_free ) > - goto out; > - ret = FFA_RET_OK; > - ctx->rx_is_free = true; > -out: > - spin_unlock(&ctx->rx_lock); > - > - return ret; > -} > - > static void handle_msg_send_direct_req(struct cpu_user_regs *regs, uint32_t > fid) > { > struct arm_smccc_1_2_regs arg = { .a0 = fid, }; > @@ -522,8 +375,7 @@ static int ffa_domain_teardown(struct domain *d) > if ( !ctx ) > return 0; > > - if ( ctx->rx ) > - rxtx_unmap(ctx); > + ffa_rxtx_domain_destroy(d); > > ffa_domain_teardown_continue(ctx, true /* first_time */); > > @@ -538,7 +390,6 @@ static int ffa_relinquish_resources(struct domain *d) > static bool ffa_probe(void) > { > uint32_t vers; > - int e; > unsigned int major_vers; > unsigned int minor_vers; > > @@ -596,36 +447,21 @@ static bool ffa_probe(void) > !check_mandatory_feature(FFA_MSG_SEND_DIRECT_REQ_32) ) > return false; > > - ffa_rx = alloc_xenheap_pages(get_order_from_pages(FFA_RXTX_PAGE_COUNT), > 0); > - if ( !ffa_rx ) > + if ( !ffa_rxtx_init() ) > return false; > > - ffa_tx = alloc_xenheap_pages(get_order_from_pages(FFA_RXTX_PAGE_COUNT), > 0); > - if ( !ffa_tx ) > - goto err_free_ffa_rx; > - > - e = ffa_rxtx_map(__pa(ffa_tx), __pa(ffa_rx), FFA_RXTX_PAGE_COUNT); > - if ( e ) > - { > - printk(XENLOG_ERR "ffa: Failed to map rxtx: error %d\n", e); > - goto err_free_ffa_tx; > - } > ffa_version = vers; > > if ( !ffa_partinfo_init() ) > - goto err_free_ffa_tx; > + goto err_rxtx_destroy; > > INIT_LIST_HEAD(&ffa_teardown_head); > init_timer(&ffa_teardown_timer, ffa_teardown_timer_callback, NULL, 0); > > return true; > > -err_free_ffa_tx: > - free_xenheap_pages(ffa_tx, 0); > - ffa_tx = NULL; > -err_free_ffa_rx: > - free_xenheap_pages(ffa_rx, 0); > - ffa_rx = NULL; > +err_rxtx_destroy: > + ffa_rxtx_destroy(); > ffa_version = 0; > > return false; > diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h > index 6b32b69cfe90..98236cbf14a3 100644 > --- a/xen/arch/arm/tee/ffa_private.h > +++ b/xen/arch/arm/tee/ffa_private.h > @@ -263,6 +263,13 @@ int32_t ffa_handle_partition_info_get(uint32_t w1, > uint32_t w2, uint32_t w3, > uint32_t w4, uint32_t w5, uint32_t > *count, > uint32_t *fpi_size); > > +bool ffa_rxtx_init(void); > +void ffa_rxtx_destroy(void); > +void ffa_rxtx_domain_destroy(struct domain *d); > +uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr, > + register_t rx_addr, uint32_t page_count); > +uint32_t ffa_handle_rxtx_unmap(void); > +int32_t ffa_handle_rx_release(void); > > static inline uint16_t ffa_get_vm_id(const struct domain *d) > { > diff --git a/xen/arch/arm/tee/ffa_rxtx.c b/xen/arch/arm/tee/ffa_rxtx.c > new file mode 100644 > index 000000000000..661764052e67 > --- /dev/null > +++ b/xen/arch/arm/tee/ffa_rxtx.c > @@ -0,0 +1,216 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Copyright (C) 2024 Linaro Limited > + */ > + > +#include <xen/const.h> > +#include <xen/domain_page.h> > +#include <xen/mm.h> > +#include <xen/sizes.h> > +#include <xen/types.h> > + > +#include <asm/smccc.h> > +#include <asm/regs.h> > + > +#include "ffa_private.h" > + > +/* Endpoint RX/TX descriptor defined in FF-A-1.0-REL */ > +struct ffa_endpoint_rxtx_descriptor_1_0 { > + uint16_t sender_id; > + uint16_t reserved; > + uint32_t rx_range_count; > + uint32_t tx_range_count; > +}; > + > +/* Endpoint RX/TX descriptor defined in FF-A-1.1-REL0 */ > +struct ffa_endpoint_rxtx_descriptor_1_1 { > + uint16_t sender_id; > + uint16_t reserved; > + uint32_t rx_region_offs; > + uint32_t tx_region_offs; > +}; > + > +uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr, > + register_t rx_addr, uint32_t page_count) > +{ > + uint32_t ret = FFA_RET_INVALID_PARAMETERS; > + struct domain *d = current->domain; > + struct ffa_ctx *ctx = d->arch.tee; > + struct page_info *tx_pg; > + struct page_info *rx_pg; > + p2m_type_t t; > + void *rx; > + void *tx; > + > + if ( !smccc_is_conv_64(fid) ) > + { > + /* > + * Calls using the 32-bit calling convention must ignore the upper > + * 32 bits in the argument registers. > + */ > + tx_addr &= UINT32_MAX; > + rx_addr &= UINT32_MAX; > + } > + > + if ( page_count > FFA_MAX_RXTX_PAGE_COUNT ) > + { > + printk(XENLOG_ERR "ffa: RXTX_MAP: error: %u pages requested (limit > %u)\n", > + page_count, FFA_MAX_RXTX_PAGE_COUNT); > + return FFA_RET_INVALID_PARAMETERS; > + } > + > + /* Already mapped */ > + if ( ctx->rx ) > + return FFA_RET_DENIED; > + > + tx_pg = get_page_from_gfn(d, gfn_x(gaddr_to_gfn(tx_addr)), &t, > P2M_ALLOC); > + if ( !tx_pg ) > + return FFA_RET_INVALID_PARAMETERS; > + > + /* Only normal RW RAM for now */ > + if ( t != p2m_ram_rw ) > + goto err_put_tx_pg; > + > + rx_pg = get_page_from_gfn(d, gfn_x(gaddr_to_gfn(rx_addr)), &t, > P2M_ALLOC); > + if ( !tx_pg ) > + goto err_put_tx_pg; > + > + /* Only normal RW RAM for now */ > + if ( t != p2m_ram_rw ) > + goto err_put_rx_pg; > + > + tx = __map_domain_page_global(tx_pg); > + if ( !tx ) > + goto err_put_rx_pg; > + > + rx = __map_domain_page_global(rx_pg); > + if ( !rx ) > + goto err_unmap_tx; > + > + ctx->rx = rx; > + ctx->tx = tx; > + ctx->rx_pg = rx_pg; > + ctx->tx_pg = tx_pg; > + ctx->page_count = page_count; > + ctx->rx_is_free = true; > + return FFA_RET_OK; > + > +err_unmap_tx: > + unmap_domain_page_global(tx); > +err_put_rx_pg: > + put_page(rx_pg); > +err_put_tx_pg: > + put_page(tx_pg); > + > + return ret; > +} > + > +static void rxtx_unmap(struct ffa_ctx *ctx) > +{ > + unmap_domain_page_global(ctx->rx); > + unmap_domain_page_global(ctx->tx); > + put_page(ctx->rx_pg); > + put_page(ctx->tx_pg); > + ctx->rx = NULL; > + ctx->tx = NULL; > + ctx->rx_pg = NULL; > + ctx->tx_pg = NULL; > + ctx->page_count = 0; > + ctx->rx_is_free = false; > +} > + > +uint32_t ffa_handle_rxtx_unmap(void) > +{ > + struct domain *d = current->domain; > + struct ffa_ctx *ctx = d->arch.tee; > + > + if ( !ctx->rx ) > + return FFA_RET_INVALID_PARAMETERS; > + > + rxtx_unmap(ctx); > + > + return FFA_RET_OK; > +} > + > +int32_t ffa_handle_rx_release(void) > +{ > + int32_t ret = FFA_RET_DENIED; > + struct domain *d = current->domain; > + struct ffa_ctx *ctx = d->arch.tee; > + > + if ( !spin_trylock(&ctx->rx_lock) ) > + return FFA_RET_BUSY; > + > + if ( !ctx->page_count || ctx->rx_is_free ) > + goto out; > + ret = FFA_RET_OK; > + ctx->rx_is_free = true; > +out: > + spin_unlock(&ctx->rx_lock); > + > + return ret; > +} > + > +static int32_t ffa_rxtx_map(paddr_t tx_addr, paddr_t rx_addr, > + uint32_t page_count) > +{ > + return ffa_simple_call(FFA_RXTX_MAP_64, tx_addr, rx_addr, page_count, 0); > +} > + > +static int32_t ffa_rxtx_unmap(void) > +{ > + return ffa_simple_call(FFA_RXTX_UNMAP, 0, 0, 0, 0); > +} > + > +void ffa_rxtx_domain_destroy(struct domain *d) > +{ > + struct ffa_ctx *ctx = d->arch.tee; > + > + if ( ctx->rx ) > + rxtx_unmap(ctx); > +} > + > +void ffa_rxtx_destroy(void) > +{ > + bool need_unmap = ffa_tx && ffa_rx; > + > + if ( ffa_tx ) > + { > + free_xenheap_pages(ffa_tx, 0); > + ffa_tx = NULL; > + } > + if ( ffa_rx ) > + { > + free_xenheap_pages(ffa_rx, 0); > + ffa_rx = NULL; > + } > + > + if ( need_unmap ) > + ffa_rxtx_unmap(); > +} > + > +bool ffa_rxtx_init(void) > +{ > + int e; > + > + ffa_rx = alloc_xenheap_pages(get_order_from_pages(FFA_RXTX_PAGE_COUNT), > 0); > + if ( !ffa_rx ) > + return false; > + > + ffa_tx = alloc_xenheap_pages(get_order_from_pages(FFA_RXTX_PAGE_COUNT), > 0); > + if ( !ffa_tx ) > + goto err; > + > + e = ffa_rxtx_map(__pa(ffa_tx), __pa(ffa_rx), FFA_RXTX_PAGE_COUNT); > + if ( e ) > + { > + printk(XENLOG_ERR "ffa: Failed to map rxtx: error %d\n", e); > + goto err; > + } > + return true; > + > +err: > + ffa_rxtx_destroy(); > + > + return false; > +} > -- > 2.34.1 >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |