Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Asynchronous notifications #4601

Merged
merged 5 commits into from
Dec 28, 2021
Merged

Conversation

jenswi-linaro
Copy link
Contributor

@jenswi-linaro jenswi-linaro commented May 10, 2021

This is a preview and RFC of the asynchronous notifications feature.

Note this is tested on QEMU virt (v7) together with the kernel patches in PR linaro-swg/linux#93

I'm in particular interested in feedback on this from a SCMI point of view.
Other aspects to keep in mind is how this harmonizes with asynchronous notifications in FF-A 1.1

Copy link
Contributor

@jforissier jforissier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments already, although I have not looked at everything.

core/arch/arm/include/sm/optee_smc.h Outdated Show resolved Hide resolved
core/arch/arm/include/sm/optee_smc.h Outdated Show resolved Hide resolved
core/arch/arm/include/sm/optee_smc.h Outdated Show resolved Hide resolved
core/arch/arm/include/sm/optee_smc.h Show resolved Hide resolved
core/arch/arm/include/sm/optee_smc.h Outdated Show resolved Hide resolved
core/arch/arm/kernel/link_dummies_paged.c Outdated Show resolved Hide resolved
@@ -181,6 +190,22 @@ void __weak tee_entry_fast(struct thread_smc_args *args)
__tee_entry_fast(args);
}

#if CFG_CORE_ASYNC_NOTIF_INTID
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (CFG_CORE_ASYNC_NOTIF_INTID) { ... } in the function body instead?

core/arch/arm/tee/entry_fast.c Outdated Show resolved Hide resolved
core/include/kernel/notif.h Outdated Show resolved Hide resolved
core/include/kernel/notif.h Show resolved Hide resolved
@jenswi-linaro jenswi-linaro force-pushed the async_notif branch 2 times, most recently from de23615 to 393ab15 Compare May 10, 2021 19:43
@jenswi-linaro
Copy link
Contributor Author

Rebased on master on top the commits merged already. Split up a bit as requested.

Copy link
Contributor

@jforissier jforissier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple more things. This looks quite useful to me, especially as a remember past discussions with people requesting that kind of functionality.

core/arch/arm/include/sm/optee_smc.h Outdated Show resolved Hide resolved
core/kernel/notif.c Outdated Show resolved Hide resolved
core/include/kernel/notif.h Show resolved Hide resolved
@jenswi-linaro
Copy link
Contributor Author

Update

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only minor comments

* Retrieve a value of notifications pended since the last call of this
* function.
*
* OP-TEE keeps a records of all posted values. When an interrupts is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/records/record/
s/interrupts/interrupt/

*
* OP-TEE keeps a records of all posted values. When an interrupts is
* received which indicates that there are posted values this function
* should be called until all pended values has been retrieved. When a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/has/have/

* should be called until all pended values has been retrieved. When a
* value is retrieved it's cleared from the record in secure world.
*
* It is expected that this function is called from and interrupt handler
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/and/an/

@@ -240,6 +263,19 @@ void __tee_entry_fast(struct thread_smc_args *args)
break;
#endif

case OPTEE_SMC_ENABLE_ASYNC_NOTIF:
if (notif_async_is_enabled())
notif_deliver_atomic_event(NOTIF_EVENT_STARTED);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should set args->a0.

* NOTIF_VALUE_MAX for mutex and condvar wait/wakeup
*
* Any value can be signalled with notif_send_sync() while only the ones
* <= CFG_CORE_ASYNC_NOTIF_MAX can be signalled with notif_send_async().
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/CFG_CORE_ASYNC_NOTIF_MAX/NOTIF_ASYNC_VALUE_MAX/

* has been delivered again.
*
* Note that while a @NOTIF_EVENT_STOPPED is being delivered at the same
* time may a @NOTIF_EVENT_STARTED be delivered again so a driver is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe replace a driver with non-secure world?
(or did I misunderstood?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A driver is an OP-TEE driver in this case.
I'll remove "shared" from "shared internal state" since I guess that's what put you on the wrong track.

}
#endif

TEE_Result notif_alloc_async_value(uint32_t *val);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/val/value/g ?


cpu_spin_unlock_xrestore(&notif_lock, old_itr_status);

if (bit < 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe a DMSG() trace here to help identifying the out-of-mem reporter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that helps much. This is likely to happen when the drivers are initializing so there's bound some more interesting print or perhaps even a panic.

bool notif_async_is_started(void)
{
uint32_t old_itr_status = 0;
bool ret;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

= false;

if (notif_async_is_enabled())
notif_deliver_event(NOTIF_EVENT_DO_BOTTOM_HALF);
else
goto err;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not rv = OPTEE_SMC_RETURN_EBADCMD; straight?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it nice to get the "Unknown cmd..." print in such a case.

@jenswi-linaro
Copy link
Contributor Author

Update

@jforissier
Copy link
Contributor

Reviewed-by: Jerome Forissier <jerome@forissier.org>

@jenswi-linaro
Copy link
Contributor Author

Squashed and tags applied

@jforissier
Copy link
Contributor

@etienne-lms do you want to provide a review or ack tag?

@etienne-lms
Copy link
Contributor

Sorry. Yes, Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org> with a late minor comment for commit "core: add asynchronous notifications".

@jenswi-linaro
Copy link
Contributor Author

Sorry. Yes, Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org> with a late minor comment for commit "core: add asynchronous notifications".

I'm sorry, which comment?

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops! this one.


COMPILE_TIME_ASSERT(NOTIF_VALUE_DO_BOTTOM_HALF ==
OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF);
COMPILE_TIME_ASSERT(!CFG_CORE_ASYNC_NOTIF_INTID ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: this function mandates CFG_CORE_ASYNC_NOTIF_INTID!=0
note it is already embedded only upon CFG_CORE_ASYNC_NOTIF_INTID!=0 (line 16)

@jenswi-linaro jenswi-linaro force-pushed the async_notif branch 2 times, most recently from ca25df6 to 14cf2f9 Compare June 14, 2021 12:08
@jenswi-linaro
Copy link
Contributor Author

Addressed comment, applied tag and rebased on master. We should wait with the merging this until we have made some more progress with upstreaming the kernel patches.

@jforissier
Copy link
Contributor

We should wait with the merging this until we have made some more progress with upstreaming the kernel patches.

Sure.

@JensVankeirsbilck
Copy link

I know and understand this is not high up the priority list, but any idea when this functionality would become available? I would like to test it, to see if it provides the functionality I seek (i.e. periodic tasks, largely independent of the REE).

@jenswi-linaro
Copy link
Contributor Author

Rebased, "core: drivers: gic.h: define PPI and SPI bases" moved closer to the top, and added two "review" commits.

@jenswi-linaro
Copy link
Contributor Author

I know and understand this is not high up the priority list, but any idea when this functionality would become available? I would like to test it, to see if it provides the functionality I seek (i.e. periodic tasks, largely independent of the REE).

I'm aiming for the v5.17 Linux kernel with the kernel driver counterpart of this (it seems we're going to be too close to the v5.16 merge window). I expect we can merge this earlier than that though. You can help out by testing this and replying on the kernel mailing list where the patches are posted. I expect to post the v7 patchset later this week so if you can do you test based on that it would be great. I can add you in CC if you like, which address should I use in that case?

@jforissier
Copy link
Contributor

For commit "core: drivers: gic.h: define PPI and SPI bases":
Reviewed-by: Jerome Forissier <jerome@forissier.org>

@JensVankeirsbilck
Copy link

I'm aiming for the v5.17 Linux kernel with the kernel driver counterpart of this (it seems we're going to be too close to the v5.16 merge window). I expect we can merge this earlier than that though. You can help out by testing this and replying on the kernel mailing list where the patches are posted. I expect to post the v7 patchset later this week so if you can do you test based on that it would be great. I can add you in CC if you like, which address should I use in that case?

Not sure I fully understand what you mean here, but I'm glad to help where I can. Since this is work-related for me, feel free to use my work-email: jens.vankeirsbilck at kuleuven.be . Will I be able to test this by just updating my QEMUv7 repo (which I'm using now) ?

@jenswi-linaro
Copy link
Contributor Author

Will I be able to test this by just updating my QEMUv7 repo (which I'm using now) ?

Yes, just switch to this branch for optee_os with this and update linux with this branch https://git.linaro.org/people/jens.wiklander/linux-tee.git/log/?h=async_notif_v6

Build as usual and you should get something like:

D/TC:0   notif_send_async:105 0x0
D/TC:? 1 read_console:112 got 0x20

on the secure uart when pressing space bar.

Copy link
Contributor

@jforissier jforissier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For commit "core: add asynchronous notifications":

Minor comments below, once addressed:
Reviewed-by: Jerome Forissier <jerome@forissier.org>

core/arch/arm/include/sm/optee_smc.h Outdated Show resolved Hide resolved
core/arch/arm/tee/entry_fast.c Outdated Show resolved Hide resolved
core/include/kernel/notif.h Outdated Show resolved Hide resolved
core/include/optee_rpc_cmd.h Outdated Show resolved Hide resolved
mk/config.mk Outdated Show resolved Hide resolved
core/kernel/notif.c Outdated Show resolved Hide resolved
@jenswi-linaro
Copy link
Contributor Author

jenswi-linaro commented Oct 25, 2021

Squashed in the update and applied Jerome's R-B on "core: add asynchronous notifications"
There are some old R-B's in this PR, but I've skipped those for now since you might want to take another look first.

@jenswi-linaro
Copy link
Contributor Author

Update

@panda-balarka
Copy link

@jenswi-linaro Is there any way I can test this before its upstreamed. I'm anyway trying to bring up periodic tasks on OPTEE as mentioned in issues #4910 and #4920. I could test it out and try to merge some changes on an actual HW if possible.

@jenswi-linaro
Copy link
Contributor Author

@jenswi-linaro Is there any way I can test this before its upstreamed. I'm anyway trying to bring up periodic tasks on OPTEE as mentioned in issues #4910 and #4920. I could test it out and try to merge some changes on an actual HW if possible.

#4601 (comment)

@JensVankeirsbilck
Copy link

Yes, just switch to this branch for optee_os with this and update linux with this branch https://git.linaro.org/people/jens.wiklander/linux-tee.git/log/?h=async_notif_v6

Build as usual and you should get something like:

D/TC:0   notif_send_async:105 0x0
D/TC:? 1 read_console:112 got 0x20

on the secure uart when pressing space bar.

@jenswi-linaro , indeed. Because I didn't want to overwrite my existing QEMU project, I created a new one using a local default.xml manifest for the repo tool, pointing to your repositories. @panda-balarka I've attached my manifest here, maybe it helps you set up a project too. Due to upload restrictions I renamed the file to .txt extension, to use it with repo, just revert it back to .xml
default.txt

I'll know have a look at the code that produces that output to figure out how to connect it to a timer interrupt and take it from there. Thanks for expediting this so I can play around with it.

@JensVankeirsbilck
Copy link

@jenswi-linaro I've been going through the code, and as far as I can see, the code for that UART Notif test is located in /core/arch/arm/plat-vexpress/main.c

While I understand that code, I'm struggling seeing how OPTEE / the notification code differentiates between different notifications, especially to launch the bottom half of the driver.
For example, let's say I want to use these notifications for a Timer. In the Timer ISR, I would execute some functionality and then would need to launch the bottom half, so that means calling notif_send_async with NOTIF_VALUE_DO_BOTTOM_HALF. But I only want to trigger my Timer bottom half of course, and not the UART driver bottom half. So how should this be done? The documentation page about notifications https://optee.readthedocs.io/en/latest/architecture/core.html#notifications doesn't really help in this regard.
Am I missing something?

@jenswi-linaro
Copy link
Contributor Author

All drivers which has registered for bottom half processing will be called each time. I don't expect that many callbacks registered that it will be a performance problem. It should be noted that entering secure world is much more expensive than calling a registered callback. I suppose we could have multiple queues for idle and triggered callbacks, but it seems more trouble than it's worth today.

A registered callback should be capable of telling if it has any work to do when called.

Clarifies the responsibilities of the caller when calling with struct
optee_msg_arg as argument.

Reviewed-by: Jerome Forissier <jerome@forissier.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Adds the two defines GIC_PPI_BASE and GIC_SPI_BASE to tell the base of
the ranges for PPIs and SPIs respectively.

Reviewed-by: Jerome Forissier <jerome@forissier.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Adds a new interface for synchronous notifications. The old RPC
interface based on OPTEE_RPC_CMD_WAIT_QUEUE is renamed to
OPTEE_RPC_CMD_NOTIFICATION in order to match the new interface.

Reviewed-by: Jerome Forissier <jerome@forissier.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Adds support for asynchronous notifications from secure world to normal
world. This allows a design with a top half and bottom half type of
driver where the top half runs in secure interrupt context and a
notifications tells normal world to schedule a yielding call to do the
bottom half processing.

The protocol is defined in optee_msg.h optee_rpc_cmd.h and optee_smc.h.

A notification consists of a 32-bit value which normal world can
retrieve using a fastcall into secure world. OP-TEE is currently only
supporting the value 0-63 where 0 has a special meaning. When 0 is sent
it means that normal world is supposed to make a yielding call
OPTEE_MSG_CMD_DO_BOTTOM_HALF.

The notification framework in OP-TEE defines an interface where drivers
can register a callback which is called on each yielding bottom half
call.

Notification capability is negotiated with the normal world while it
initializes its driver. If both sides supports these notifications then
they are enabled.

CFG_CORE_ASYNC_NOTIF_GIC_INTID is added to define the hardware interrupt
used to notify normal world. This is added to the DTB in case OP-TEE can
is configured with CFG_DT=y. Other cases requires the normal world DTB
to be kept in sync with this.

Reviewed-by: Jerome Forissier <jerome@forissier.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
When asynchronous notifications are enabled the console driver in qemu
is configured as a top half and bottom half driver allowing basic
testing of the notification framework.

Reviewed-by: Jerome Forissier <jerome@forissier.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
@jenswi-linaro
Copy link
Contributor Author

Rebased on master.
The Linux kernel pull request has been merged into the arm-soc tree, see https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/commit/?id=c6e5bdae04a3

We've now reached a point where we can merge this.

@jforissier
Copy link
Contributor

We've now reached a point where we can merge this.

Absolutely, thanks!

@jforissier jforissier merged commit 7b06f6c into OP-TEE:master Dec 28, 2021
@jenswi-linaro jenswi-linaro deleted the async_notif branch December 28, 2021 22:32
@th0ma5b
Copy link

th0ma5b commented May 19, 2022

Could you help clarifying a few points:

  1. Regarding

    nd->yielding_cb(nd, ev);

    Is yielding_cb() intentionally called in the case of a NOTIF_EVENT_STOPPED event?

  2. Could you confirm that if a bottom half "A" blocks/waits, then the remaining driver bottom halves will not run until bottom half "A" call-back has resumed and returned?

@jenswi-linaro
Copy link
Contributor Author

Yes, and yes.

abuzarra pushed a commit to digi-embedded/linux that referenced this pull request Nov 30, 2022
OP-TEE community is working on asynchronous notification support ([1]
and [2]) and is likely to merge TEE_GEN_CAP_ASYNC_NOTIF as 1 << 4.
This change moves OCALL capability bit position bit field to upper
half. We shall sync back with Linux once TEE_GEN_CAP_OCALL is officially
upstream.

Link: [1] OP-TEE/optee_os#4601
Link: [2] linaro-swg/linux#93

Change-Id: I8b2f3ca3d2f288990d420f4d8071c9fca88f561c
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants