|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5 6/6] xen/arm: ffa: Enable VM to VM without firmware
Hi Jens,
> On 22 May 2025, at 14:00, Jens Wiklander <jens.wiklander@xxxxxxxxxx> wrote:
>
> Hi Bertrand,
>
> On Thu, May 22, 2025 at 11:11 AM Bertrand Marquis
> <Bertrand.Marquis@xxxxxxx> wrote:
>>
>> Hi Jens,
>>
>>> On 22 May 2025, at 10:30, Jens Wiklander <jens.wiklander@xxxxxxxxxx> wrote:
>>>
>>> Hi,
>>>
>>> On Thu, May 22, 2025 at 10:18 AM Bertrand Marquis
>>> <Bertrand.Marquis@xxxxxxx> wrote:
>>>>
>>>> Hi Jens,
>>>>
>>>>> On 22 May 2025, at 10:00, Jens Wiklander <jens.wiklander@xxxxxxxxxx>
>>>>> wrote:
>>>>>
>>>>> Hi Bertrand,
>>>>>
>>>>> On Wed, Apr 16, 2025 at 9:40 AM 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.
>>>>>>
>>>>>> Signed-off-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
>>>>>> ---
>>>>>> 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 | 24 ++++++--
>>>>>> xen/arch/arm/tee/ffa_notif.c | 104 ++++++++++++++++-------------------
>>>>>> 2 files changed, 67 insertions(+), 61 deletions(-)
>>>>>>
>>>>>> diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c
>>>>>> index c1c4c0957091..b86c88cefa8c 100644
>>>>>> --- a/xen/arch/arm/tee/ffa.c
>>>>>> +++ b/xen/arch/arm/tee/ffa.c
>>>>>> @@ -342,8 +342,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
>>>>>> @@ -579,11 +580,8 @@ static bool ffa_probe(void)
>>>>>> goto err_rxtx_destroy;
>>>>>>
>>>>>> ffa_notif_init();
>>>>>> - INIT_LIST_HEAD(&ffa_teardown_head);
>>>>>> - INIT_LIST_HEAD(&ffa_ctx_head);
>>>>>> - init_timer(&ffa_teardown_timer, ffa_teardown_timer_callback, NULL,
>>>>>> 0);
>>>>>>
>>>>>> - return true;
>>>>>> + goto exit;
>>>>>>
>>>>>> err_rxtx_destroy:
>>>>>> ffa_rxtx_destroy();
>>>>>> @@ -592,6 +590,22 @@ err_no_fw:
>>>>>> bitmap_zero(ffa_fw_abi_supported, FFA_ABI_BITMAP_SIZE);
>>>>>> printk(XENLOG_WARNING "ARM FF-A No firmware support\n");
>>>>>>
>>>>>> +exit:
>>>>>> + if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) || ffa_fw_version )
>>>>>> + {
>>>>>> + INIT_LIST_HEAD(&ffa_teardown_head);
>>>>>> + INIT_LIST_HEAD(&ffa_ctx_head);
>>>>>> + init_timer(&ffa_teardown_timer, ffa_teardown_timer_callback,
>>>>>> NULL, 0);
>>>>>> + }
>>>>>> +
>>>>>> + if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) )
>>>>>> + {
>>>>>> + printk(XENLOG_INFO "ARM FF-A only available between VMs\n");
>>>>>
>>>>> This should only be printed if ffa_fw_version == 0
>>>>
>>>> Right i will fix but ...
>>>>
>>>>>
>>>>>> + return true;
>>>>>> + }
>>>>>> + else if ( ffa_fw_version )
>>>>>
>>>>> The else isn't needed.
>>>>
>>>> the else is needed so that we return true and not false.
>>>
>>> I meant the "else" isn't needed, the "if" is still needed, as you explain.
>>>
>>>>
>>>> We have 3 cases:
>>>> - firmware is there: return true
>>>> - firmware not there but vm to vm enable: return true
>>>> - otherwise: return false
>>>>
>>>> I will modify it like this to make it clearer:
>>>> diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c
>>>> index 57b648a22840..768b4e9ec968 100644
>>>> --- a/xen/arch/arm/tee/ffa.c
>>>> +++ b/xen/arch/arm/tee/ffa.c
>>>> @@ -601,13 +601,13 @@ exit:
>>>> init_timer(&ffa_teardown_timer, ffa_teardown_timer_callback, NULL,
>>>> 0);
>>>> }
>>>>
>>>> - if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) )
>>>> + if ( ffa_fw_version )
>>>> + return true;
>>>> + else if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) )
>>>> {
>>>> printk(XENLOG_INFO "ARM FF-A only available between VMs\n");
>>>> return true;
>>>> }
>>>> - else if ( ffa_fw_version )
>>>> - return true;
>>>>
>>>> return false;
>>>> }
>>>>
>>>> Tell me if you agree.
>>>
>>> Yes, this is an improvement. A return at the end of an if block makes
>>> the eventual following "else" redundant. I suppose there are coding
>>> styles where it's still preferred. I'm not sure if that applies in
>>> Xen, though.
>>
>> I now get what you mean and you would like the return false to be in a else.
>>
>> Relooking at the code, i actually do not like the fact that we do so much in
>> exit and i think i can move a bit the code to be clearer:
>> - put the fw init in a sub function
>> - create a vm_to_vm init function
>> - in probe call both functions and do the common init part if at least one
>> succeded
>
> I was starting to think along those lines, too. :-)
>
>>
>> Something like this:
>> diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c
>> index 57b648a22840..42dfc71a12d7 100644
>> --- a/xen/arch/arm/tee/ffa.c
>> +++ b/xen/arch/arm/tee/ffa.c
>> @@ -478,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.
>> @@ -528,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);
>>
>> @@ -584,7 +553,7 @@ static bool ffa_probe(void)
>>
>> ffa_notif_init();
>>
>> - goto exit;
>> + return true;
>>
>> err_rxtx_destroy:
>> ffa_rxtx_destroy();
>> @@ -593,23 +562,59 @@ err_no_fw:
>> bitmap_zero(ffa_fw_abi_supported, FFA_ABI_BITMAP_SIZE);
>> printk(XENLOG_WARNING "ARM FF-A No firmware support\n");
>>
>> -exit:
>> - if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) || ffa_fw_version )
>> - {
>> - INIT_LIST_HEAD(&ffa_teardown_head);
>> - INIT_LIST_HEAD(&ffa_ctx_head);
>> - init_timer(&ffa_teardown_timer, ffa_teardown_timer_callback, NULL,
>> 0);
>> - }
>> + return false;
>> +}
>>
>> - if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) )
>> - {
>> +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");
>> - return true;
>> - }
>> - else if ( ffa_fw_version )
>> - return true;
>>
>> - return false;
>> + INIT_LIST_HEAD(&ffa_teardown_head);
>> + INIT_LIST_HEAD(&ffa_ctx_head);
>> + init_timer(&ffa_teardown_timer, ffa_teardown_timer_callback, NULL, 0);
>> +
>> + return true;
>> }
>>
>> static const struct tee_mediator_ops ffa_ops =
>>
>> I think this makes the code cleaner as we also get the proper error handling
>> with goto
>> inside the fw probe instead of the previous one which was trying to handle
>> both cases.
>>
>> What do you think ?
>
> This is good. It's much easier to follow.
Great, I will put that in v6.
Cheers
Bertrand
>
> Cheers,
> Jens
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |