[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v7 6/6] xen/arm: ffa: Enable VM to VM without firmware


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Bertrand Marquis <Bertrand.Marquis@xxxxxxx>
  • Date: Fri, 1 Aug 2025 07:10:54 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 4.158.2.129) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=arm.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com])
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ALOs//xUM8fOs/AdT4f1GGnMIeqL+0xTf/QhGePVeE4=; b=Tkf30MOEbxSYP0hWfgucquPEmDBLh2oFGcny+YHwaFXIM6AZjOXFPBwMFqKnz/EZt8bOT9G2f9Ftk5s/UZ5SHrfPwYpQzqkJ1SkGKkvGmS7+NlFc0NAp/JpA3IETc/hVunWtcQHJWisUMtTYVyP7AwgoDZqgfxt271f7bZKRDX21yhmDDxk3uchhPNkF+jphy3EGOXSCnnQLQzbMls2yM9kMemzj6t+fXvyg4X01Rs5JwB/j531c1jkLTPI5onExIv04hk5RmqicgxZehfvOm7SLrxF7Xg0hFBvPcdQOk0stJMGWU/aXh6UlQ0Nb+JSRAHxkUrfyIr2FoKFluAyTzQ==
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ALOs//xUM8fOs/AdT4f1GGnMIeqL+0xTf/QhGePVeE4=; b=aRcEVH+eTDh30/2BCear2LHhVImuJFZ9V+2K/zE7JBvsXGGFFELU8DdU2jyOKEMGM8bsU2Lqd4jKYdT2g9z/AKa5hcseWXE5of8d6LTzUy8RVVNVkIW6lIbYIk+IbefhLAnO15yOjYj2gvG4m9T6rSyXPUAVpyDLShMFx7+aJTCtlw+iutRjZdpm3ZYtqIax2ZYQY7y0/NOqFnHr6aHI8KmqFb0PS8olE8XwPx26h7Nlcl3HonOyId+9rsjgBTyCp5NchReifab1OLVN+wDjBrbFfBucR0S0v5Kcle8S/lqIAt/N9Pzgz0uAbsosIHitxo+moJ78SMEBce8yAedpiw==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=c5kCaFbIMkM5lYLK6rZNBZZATg0cQq4WY6qvshTYKOCY4rN7FnoSAfB0hoLJSlKWzbPB5bjPwGF7Nim0YXvoOWNaWq1kX/gK3ecgnBCOi5X/HM1F/JgSVPdwSquwj8WfBLFns4S+6X1fmzWbD32HNY55d2X/gBkF4NSsOrPeAbWNA67eUkiYdtxSbux3E02K0jYmV7vUyqGtBiFbRG22nLc4MiVhCMkIRkKK+BotGjuyLYQDfKkKrbn3Vft4FASVWm/yJt/5n303Yl3nOBRGhUWuYcB1j5SX0QmR5I0cM8PSgsbXX2rb+5Yy/qDiA9fAtj38Hy8ki55yCscyghoj7Q==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=RnZYnHjZWc+BNQoldV5fVhrQuf6XrR7MkauN2d8X/z2Kg0t6x58abeg5gYr6+zRJdq+4vibz9GRcXRxFJbAnG6AN95B22YipX+Dpv/VjN2vcoxqyztDOiA+d3xqEt4WZ/5Tag9DEgdZWtdkpyYm0aIGGce89yIKCcbYpXJpeo7q9aSE32k2zU6RWw/9UyFWDG9AzCTJrQc/6sTNNlWiP1FSuDs3ULSe1YVDS38kl3HtzK3jQykI3TPp4E4wnQHUFyNec6/9FSzgETco/y2p/dBFmLoJRnL3r24S3edX/FImkSk6bA/jqiyoGkGAlAC1arto6HmfPluZHoQ0yfhCRhw==
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: "jens.wiklander@xxxxxxxxxx" <jens.wiklander@xxxxxxxxxx>, Volodymyr Babchuk <volodymyr_babchuk@xxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>
  • Delivery-date: Fri, 01 Aug 2025 07:11:44 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Thread-index: AQHb9xP7T/VoLAfGvk2gcX5wpv2f7LRNeKMA
  • Thread-topic: [PATCH v7 6/6] xen/arm: ffa: Enable VM to VM without firmware

Hi,

A gentle ping for someone to review this :-)

Thanks
Bertrand

> On 17 Jul 2025, at 14:11, Bertrand Marquis <Bertrand.Marquis@xxxxxxx> wrote:
> 
> When VM to VM support is activated and there is no suitable FF-A support
> in the firmware, enable FF-A support for VMs to allow using it for VM to
> VM communications.
> If there is OP-TEE running in the secure world and using the non FF-A
> communication system, having CONFIG_FFA_VM_TO_VM could be non functional
> (if optee is probed first) or OP-TEE could be non functional (if FF-A is
> probed first) so it is not recommended to activate the configuration
> option for such systems.
> 
> To make buffer full notification work between VMs when there is no
> firmware, rework the notification handling and modify the global flag to
> only be used as check for firmware notification support instead.
> 
> Also split probe function into one for firmware and one for vm to vm to
> make the implementation clearer.
> 
> Signed-off-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
> Reviewed-by: Jens Wiklander <jens.wiklander@xxxxxxxxxx>
> 
> ---
> Changes in v7:
> - add Jens R-b
> Changes in v6:
> - split probe into fw and vm_to_vm probe
> Changes in v5:
> - init ctx list when there is no firmware
> - rework init a bit to prevent duplicates
> - Remove Jens R-b due to changes done
> Changes in v4:
> - Fix Optee to OP-TEE in commit message
> - Add Jens R-b
> Changes in v3:
> - fix typos in commit message
> - add spaces around <<
> - move notification id fix back into buffer full patch
> - fix | position in if
> Changes in v2:
> - replace ifdef with IS_ENABLED when possible
> ---
> xen/arch/arm/tee/ffa.c       |  93 ++++++++++++++++++-------------
> xen/arch/arm/tee/ffa_notif.c | 104 ++++++++++++++++-------------------
> 2 files changed, 104 insertions(+), 93 deletions(-)
> 
> diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c
> index be71eda4869f..df38b4e15b36 100644
> --- a/xen/arch/arm/tee/ffa.c
> +++ b/xen/arch/arm/tee/ffa.c
> @@ -345,8 +345,9 @@ static int ffa_domain_init(struct domain *d)
>     struct ffa_ctx *ctx;
>     int ret;
> 
> -    if ( !ffa_fw_version )
> +    if ( !IS_ENABLED(CONFIG_FFA_VM_TO_VM) && !ffa_fw_version )
>         return -ENODEV;
> +
>     /*
>      * We are using the domain_id + 1 as the FF-A ID for VMs as FF-A ID 0 is
>      * reserved for the hypervisor and we only support secure endpoints using
> @@ -477,38 +478,12 @@ static void ffa_init_secondary(void)
>     ffa_notif_init_interrupt();
> }
> 
> -static bool ffa_probe(void)
> +static bool ffa_probe_fw(void)
> {
>     uint32_t vers;
>     unsigned int major_vers;
>     unsigned int minor_vers;
> 
> -    /*
> -     * FF-A often works in units of 4K pages and currently it's assumed
> -     * that we can map memory using that granularity. See also the comment
> -     * above the FFA_PAGE_SIZE define.
> -     *
> -     * It is possible to support a PAGE_SIZE larger than 4K in Xen, but
> -     * until that is fully handled in this code make sure that we only use
> -     * 4K page sizes.
> -     */
> -    BUILD_BUG_ON(PAGE_SIZE != FFA_PAGE_SIZE);
> -
> -    printk(XENLOG_INFO "ARM FF-A Mediator version %u.%u\n",
> -           FFA_MY_VERSION_MAJOR, FFA_MY_VERSION_MINOR);
> -
> -    if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) )
> -    {
> -        /*
> -         * When FFA VM to VM is enabled, the current implementation does not
> -         * offer any way to limit which VM can communicate with which VM 
> using
> -         * FF-A.
> -         * Signal this in the xen console and taint the system as insecure.
> -         * TODO: Introduce a solution to limit what a VM can do through FFA.
> -         */
> -        printk(XENLOG_ERR "ffa: VM to VM is enabled, system is insecure 
> !!\n");
> -        add_taint(TAINT_MACHINE_INSECURE);
> -    }
>     /*
>      * psci_init_smccc() updates this value with what's reported by EL-3
>      * or secure world.
> @@ -527,11 +502,6 @@ static bool ffa_probe(void)
>         goto err_no_fw;
>     }
> 
> -    /* Some sanity check in case we update the version we support */
> -    BUILD_BUG_ON(FFA_MIN_SPMC_VERSION > FFA_MY_VERSION);
> -    BUILD_BUG_ON(FFA_VERSION_MAJOR(FFA_MIN_SPMC_VERSION) !=
> -                                   FFA_MY_VERSION_MAJOR);
> -
>     major_vers = FFA_VERSION_MAJOR(vers);
>     minor_vers = FFA_VERSION_MINOR(vers);
> 
> @@ -582,10 +552,6 @@ static bool ffa_probe(void)
>         goto err_rxtx_destroy;
> 
>     ffa_notif_init();
> -    INIT_LIST_HEAD(&ffa_teardown_head);
> -    INIT_LIST_HEAD(&ffa_ctx_head);
> -    rwlock_init(&ffa_ctx_list_rwlock);
> -    init_timer(&ffa_teardown_timer, ffa_teardown_timer_callback, NULL, 0);
> 
>     return true;
> 
> @@ -599,6 +565,59 @@ err_no_fw:
>     return false;
> }
> 
> +static bool ffa_probe_vm_to_vm(void)
> +{
> +    if ( !IS_ENABLED(CONFIG_FFA_VM_TO_VM) )
> +        return false;
> +
> +    /*
> +     * When FFA VM to VM is enabled, the current implementation does not
> +     * offer any way to limit which VM can communicate with which VM using
> +     * FF-A.
> +     * Signal this in the xen console and taint the system as insecure.
> +     * TODO: Introduce a solution to limit what a VM can do through FFA.
> +     */
> +    printk(XENLOG_ERR "ffa: VM to VM is enabled, system is insecure !!\n");
> +    add_taint(TAINT_MACHINE_INSECURE);
> +
> +    return true;
> +}
> +
> +static bool ffa_probe(void)
> +{
> +    /*
> +     * FF-A often works in units of 4K pages and currently it's assumed
> +     * that we can map memory using that granularity. See also the comment
> +     * above the FFA_PAGE_SIZE define.
> +     *
> +     * It is possible to support a PAGE_SIZE larger than 4K in Xen, but
> +     * until that is fully handled in this code make sure that we only use
> +     * 4K page sizes.
> +     */
> +    BUILD_BUG_ON(PAGE_SIZE != FFA_PAGE_SIZE);
> +
> +    /* Some sanity check in case we update the version we support */
> +    BUILD_BUG_ON(FFA_MIN_SPMC_VERSION > FFA_MY_VERSION);
> +    BUILD_BUG_ON(FFA_VERSION_MAJOR(FFA_MIN_SPMC_VERSION) !=
> +                                   FFA_MY_VERSION_MAJOR);
> +
> +    printk(XENLOG_INFO "ARM FF-A Mediator version %u.%u\n",
> +           FFA_MY_VERSION_MAJOR, FFA_MY_VERSION_MINOR);
> +
> +    if ( !ffa_probe_fw() && !ffa_probe_vm_to_vm() )
> +        return false;
> +
> +    if ( !ffa_fw_version )
> +        printk(XENLOG_INFO "ARM FF-A only available between VMs\n");
> +
> +    INIT_LIST_HEAD(&ffa_teardown_head);
> +    INIT_LIST_HEAD(&ffa_ctx_head);
> +    rwlock_init(&ffa_ctx_list_rwlock);
> +    init_timer(&ffa_teardown_timer, ffa_teardown_timer_callback, NULL, 0);
> +
> +    return true;
> +}
> +
> static const struct tee_mediator_ops ffa_ops =
> {
>     .probe = ffa_probe,
> diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c
> index f6df2f15bb00..86bef6b3b2ab 100644
> --- a/xen/arch/arm/tee/ffa_notif.c
> +++ b/xen/arch/arm/tee/ffa_notif.c
> @@ -16,7 +16,7 @@
> 
> #include "ffa_private.h"
> 
> -static bool __ro_after_init notif_enabled;
> +static bool __ro_after_init fw_notif_enabled;
> static unsigned int __ro_after_init notif_sri_irq;
> 
> int ffa_handle_notification_bind(struct cpu_user_regs *regs)
> @@ -27,21 +27,17 @@ int ffa_handle_notification_bind(struct cpu_user_regs 
> *regs)
>     uint32_t bitmap_lo = get_user_reg(regs, 3);
>     uint32_t bitmap_hi = get_user_reg(regs, 4);
> 
> -    if ( !notif_enabled )
> -        return FFA_RET_NOT_SUPPORTED;
> -
>     if ( (src_dst & 0xFFFFU) != ffa_get_vm_id(d) )
>         return FFA_RET_INVALID_PARAMETERS;
> 
>     if ( flags )    /* Only global notifications are supported */
>         return FFA_RET_DENIED;
> 
> -    /*
> -     * We only support notifications from SP so no need to check the sender
> -     * endpoint ID, the SPMC will take care of that for us.
> -     */
> -    return ffa_simple_call(FFA_NOTIFICATION_BIND, src_dst, flags, bitmap_lo,
> -                           bitmap_hi);
> +    if ( FFA_ID_IS_SECURE(src_dst >> 16) && fw_notif_enabled )
> +        return ffa_simple_call(FFA_NOTIFICATION_BIND, src_dst, flags,
> +                               bitmap_lo, bitmap_hi);
> +
> +    return FFA_RET_NOT_SUPPORTED;
> }
> 
> int ffa_handle_notification_unbind(struct cpu_user_regs *regs)
> @@ -51,18 +47,14 @@ int ffa_handle_notification_unbind(struct cpu_user_regs 
> *regs)
>     uint32_t bitmap_lo = get_user_reg(regs, 3);
>     uint32_t bitmap_hi = get_user_reg(regs, 4);
> 
> -    if ( !notif_enabled )
> -        return FFA_RET_NOT_SUPPORTED;
> -
>     if ( (src_dst & 0xFFFFU) != ffa_get_vm_id(d) )
>         return FFA_RET_INVALID_PARAMETERS;
> 
> -    /*
> -     * We only support notifications from SP so no need to check the
> -     * destination endpoint ID, the SPMC will take care of that for us.
> -     */
> -    return  ffa_simple_call(FFA_NOTIFICATION_UNBIND, src_dst, 0, bitmap_lo,
> -                            bitmap_hi);
> +    if ( FFA_ID_IS_SECURE(src_dst >> 16) && fw_notif_enabled )
> +        return  ffa_simple_call(FFA_NOTIFICATION_UNBIND, src_dst, 0, 
> bitmap_lo,
> +                                bitmap_hi);
> +
> +    return FFA_RET_NOT_SUPPORTED;
> }
> 
> void ffa_handle_notification_info_get(struct cpu_user_regs *regs)
> @@ -71,7 +63,7 @@ void ffa_handle_notification_info_get(struct cpu_user_regs 
> *regs)
>     struct ffa_ctx *ctx = d->arch.tee;
>     bool notif_pending;
> 
> -    if ( !notif_enabled )
> +    if ( !IS_ENABLED(CONFIG_FFA_VM_TO_VM) && !fw_notif_enabled )
>     {
>         ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED);
>         return;
> @@ -108,7 +100,7 @@ void ffa_handle_notification_get(struct cpu_user_regs 
> *regs)
>     uint32_t w6 = 0;
>     uint32_t w7 = 0;
> 
> -    if ( !notif_enabled )
> +    if ( !IS_ENABLED(CONFIG_FFA_VM_TO_VM) && !fw_notif_enabled )
>     {
>         ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED);
>         return;
> @@ -120,7 +112,8 @@ void ffa_handle_notification_get(struct cpu_user_regs 
> *regs)
>         return;
>     }
> 
> -    if ( flags & ( FFA_NOTIF_FLAG_BITMAP_SP | FFA_NOTIF_FLAG_BITMAP_SPM ) )
> +    if ( fw_notif_enabled && (flags & ( FFA_NOTIF_FLAG_BITMAP_SP |
> +                                        FFA_NOTIF_FLAG_BITMAP_SPM )) )
>     {
>         struct arm_smccc_1_2_regs arg = {
>             .a0 = FFA_NOTIFICATION_GET,
> @@ -177,15 +170,14 @@ int ffa_handle_notification_set(struct cpu_user_regs 
> *regs)
>     uint32_t bitmap_lo = get_user_reg(regs, 3);
>     uint32_t bitmap_hi = get_user_reg(regs, 4);
> 
> -    if ( !notif_enabled )
> -        return FFA_RET_NOT_SUPPORTED;
> -
>     if ( (src_dst >> 16) != ffa_get_vm_id(d) )
>         return FFA_RET_INVALID_PARAMETERS;
> 
> -    /* Let the SPMC check the destination of the notification */
> -    return ffa_simple_call(FFA_NOTIFICATION_SET, src_dst, flags, bitmap_lo,
> -                           bitmap_hi);
> +    if ( FFA_ID_IS_SECURE(src_dst >> 16) && fw_notif_enabled )
> +        return ffa_simple_call(FFA_NOTIFICATION_SET, src_dst, flags, 
> bitmap_lo,
> +                               bitmap_hi);
> +
> +    return FFA_RET_NOT_SUPPORTED;
> }
> 
> #ifdef CONFIG_FFA_VM_TO_VM
> @@ -371,7 +363,7 @@ void ffa_notif_init_interrupt(void)
> {
>     int ret;
> 
> -    if ( notif_enabled && notif_sri_irq < NR_GIC_SGI )
> +    if ( fw_notif_enabled && notif_sri_irq < NR_GIC_SGI )
>     {
>         /*
>          * An error here is unlikely since the primary CPU has already
> @@ -402,41 +394,41 @@ void ffa_notif_init(void)
>     int ret;
> 
>     /* Only enable fw notification if all ABIs we need are supported */
> -    if ( !(ffa_fw_supports_fid(FFA_NOTIFICATION_BITMAP_CREATE) &&
> -           ffa_fw_supports_fid(FFA_NOTIFICATION_BITMAP_DESTROY) &&
> -           ffa_fw_supports_fid(FFA_NOTIFICATION_GET) &&
> -           ffa_fw_supports_fid(FFA_NOTIFICATION_INFO_GET_64)) )
> -        return;
> -
> -    arm_smccc_1_2_smc(&arg, &resp);
> -    if ( resp.a0 != FFA_SUCCESS_32 )
> -        return;
> -
> -    irq = resp.a2;
> -    notif_sri_irq = irq;
> -    if ( irq >= NR_GIC_SGI )
> -        irq_set_type(irq, IRQ_TYPE_EDGE_RISING);
> -    ret = request_irq(irq, 0, notif_irq_handler, "FF-A notif", NULL);
> -    if ( ret )
> +    if ( ffa_fw_supports_fid(FFA_NOTIFICATION_BITMAP_CREATE) &&
> +         ffa_fw_supports_fid(FFA_NOTIFICATION_BITMAP_DESTROY) &&
> +         ffa_fw_supports_fid(FFA_NOTIFICATION_GET) &&
> +         ffa_fw_supports_fid(FFA_NOTIFICATION_INFO_GET_64) )
>     {
> -        printk(XENLOG_ERR "ffa: request_irq irq %u failed: error %d\n",
> -               irq, ret);
> -        return;
> -    }
> +        arm_smccc_1_2_smc(&arg, &resp);
> +        if ( resp.a0 != FFA_SUCCESS_32 )
> +            return;
> 
> -    notif_enabled = true;
> +        irq = resp.a2;
> +        notif_sri_irq = irq;
> +        if ( irq >= NR_GIC_SGI )
> +            irq_set_type(irq, IRQ_TYPE_EDGE_RISING);
> +        ret = request_irq(irq, 0, notif_irq_handler, "FF-A notif", NULL);
> +        if ( ret )
> +        {
> +            printk(XENLOG_ERR "ffa: request_irq irq %u failed: error %d\n",
> +                   irq, ret);
> +            return;
> +        }
> +        fw_notif_enabled = true;
> +    }
> }
> 
> int ffa_notif_domain_init(struct domain *d)
> {
>     int32_t res;
> 
> -    if ( !notif_enabled )
> -        return 0;
> +    if ( fw_notif_enabled )
> +    {
> 
> -    res = ffa_notification_bitmap_create(ffa_get_vm_id(d), d->max_vcpus);
> -    if ( res )
> -        return -ENOMEM;
> +        res = ffa_notification_bitmap_create(ffa_get_vm_id(d), d->max_vcpus);
> +        if ( res )
> +            return -ENOMEM;
> +    }
> 
>     return 0;
> }
> @@ -447,6 +439,6 @@ void ffa_notif_domain_destroy(struct domain *d)
>      * Call bitmap_destroy even if bitmap create failed as the SPMC will
>      * return a DENIED error that we will ignore.
>      */
> -    if ( notif_enabled )
> +    if ( fw_notif_enabled )
>         ffa_notification_bitmap_destroy(ffa_get_vm_id(d));
> }
> -- 
> 2.47.1
> 
> 




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.