Skip to content

Commit

Permalink
pta: test: invoke: add interrupt during interrupt test
Browse files Browse the repository at this point in the history
Test when OP-TEE raises an interrupt notification from the interrupt
context of the normal world. This test is based on the fact Linux OS
is masking interrupts that have no consumers but where caught. Mask
operation is called from Linux optee irqchip driver, from the interrupt
context, after interrupts events have been retrieved. Raising an
interrupt notification from that context helps testing if the notification
was well received by normal OS or if the interrupt event are still pending,
needing another async notif to be retrieved.

Signed-off-by: Etienne Carriere <[email protected]>
  • Loading branch information
etienne-lms committed Jan 25, 2023
1 parent 70eeb1c commit 4a9b534
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions core/pta/tests/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,87 @@ static TEE_Result test1_it_notif_do(void)
return res;
}

/*
* Test1: test interrupt event during REE interrupt context
*/

static void test2_notif_set_mask(struct notif_it *notif_it, bool do_mask)
{
if (!do_mask)
return;

if (notif_it->id == idx2id(0))
notif_it_raise_event(test_it_notif + 1);
else if (notif_it->id == idx2id(1))
notif_it_raise_event(test_it_notif + 2);
else if (notif_it->id == idx2id(2))
notif_it_raise_event(test_it_notif + 3);
}
DECLARE_KEEP_PAGER(test2_notif_set_mask);

const struct notif_it_ops test2_notif_ops = {
.set_mask = test2_notif_set_mask,
};

static TEE_Result test2_it_notif_do(void)
{
TEE_Result res = TEE_SUCCESS;
size_t n = 0;

static_assert(TEST_IT_NOTIF_CNT >= 4);

for (n = 0; n <= 3; n++) {
res = register_test_it_notif(n, &test2_notif_ops);
if (res)
goto out;
}

IMSG("It-notif: test interrupt during interrupt ");

for (n = 0; n <= 3; n++)
notif_it_set_mask(idx2id(n), 0);

/*
* This test simulates cases where an interrupt is notified and
* under processing in REE, in an interrupt context, while another
* OP-TEE event raises a notification. The goal is to check the 2nd
* notification is well signaled to REE and not pending.
*
* Raise test interrupt #0. In return, REE will mask it because
* it has no consumer in Linux kernel. During mask opertion,
* test interrupt #0 raises #1, #1 raises #2, #2 raises #3.
* So raising #n makes #n to #3 be raised and masked back by REE.
*
* Check that all interrupts are consumed, with 2, 3 or 4 linked
* interrupts.
*/
notif_it_raise_event(test_it_notif + 0);
mdelay(10);

for (n = 0; n <= 3; n++)
if (test_it_is_pending(n))
break;

if (n < 4) {
EMSG("Test ITs notif are still pending");
res = TEE_ERROR_GENERIC;
goto out;
}

for (n = 0; n <= 3; n++)
notif_it_set_mask(idx2id(n), 1);

out:
unregister_test_all_notif();

if (res)
EMSG("Test it-notif failed: %#"PRIx32, res);
else
IMSG("It-notif: test successful");

return res;
}

static TEE_Result test_it_notif_do(void)
{
TEE_Result res = TEE_ERROR_GENERIC;
Expand Down

0 comments on commit 4a9b534

Please sign in to comment.