Skip to content

Commit aed1e72

Browse files
romkuz01Michael Schwarcz
authored andcommitted
Replace partition state FSM by channel state FSM
- fix - release channel memory in psa_connect() when connection fails - enhancement - handle cases of incorrect connection handle in psa_call() and psa_close() - replace partition state FSM by channel state FSM - fix negative SPM tests
1 parent cdf30ae commit aed1e72

File tree

8 files changed

+84
-43
lines changed

8 files changed

+84
-43
lines changed

TESTS/spm/neg_client_tests/spm_reboot.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ void spm_reboot(void)
3535
status = osSemaphoreDelete(g_spm.partitions[i].semaphore);
3636
MBED_ASSERT(status == osOK);
3737

38-
g_spm.partitions[i].partition_state = PARTITION_STATE_INVALID;
3938
g_spm.partitions[i].thread_id = NULL;
4039
for (uint32_t j = 0; j < g_spm.partitions[i].sec_funcs_count; ++j) {
4140
g_spm.partitions[i].sec_funcs[j].partition = NULL;

TESTS/spm/neg_dual_partition/spm_reboot.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ void spm_reboot(void)
3535
status = osSemaphoreDelete(g_spm.partitions[i].semaphore);
3636
MBED_ASSERT(status == osOK);
3737

38-
g_spm.partitions[i].partition_state = PARTITION_STATE_INVALID;
3938
g_spm.partitions[i].thread_id = NULL;
4039
for (uint32_t j = 0; j < g_spm.partitions[i].sec_funcs_count; ++j) {
4140
g_spm.partitions[i].sec_funcs[j].partition = NULL;

TESTS/spm/neg_server_tests/spm_reboot.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ void spm_reboot(void)
3535
status = osSemaphoreDelete(g_spm.partitions[i].semaphore);
3636
MBED_ASSERT(status == osOK);
3737

38-
g_spm.partitions[i].partition_state = PARTITION_STATE_INVALID;
3938
g_spm.partitions[i].thread_id = NULL;
4039
for (uint32_t j = 0; j < g_spm.partitions[i].sec_funcs_count; ++j) {
4140
g_spm.partitions[i].sec_funcs[j].partition = NULL;

spm/spm_client.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,6 @@ psa_handle_t psa_connect(uint32_t sfid, uint32_t minor_version)
117117
osStatus_t os_status = osMutexAcquire(dst_partition->mutex, osWaitForever);
118118
SPM_ASSERT(osOK == os_status);
119119

120-
PARTITION_STATE_ASSERT(dst_partition, PARTITION_STATE_IDLE);
121-
122120
ipc_channel_t *channel = (ipc_channel_t *)osMemoryPoolAlloc(g_spm.channel_mem_pool, 0);
123121
if (NULL == channel) {
124122
os_status = osMutexRelease(dst_partition->mutex);
@@ -127,6 +125,7 @@ psa_handle_t psa_connect(uint32_t sfid, uint32_t minor_version)
127125
}
128126

129127
memset(channel, 0, sizeof(ipc_channel_t));
128+
channel->state = CHANNEL_STATE_CONNECTING;
130129
channel->src_partition = current_part;
131130
channel->dst_sec_func = dst_sec_func;
132131
channel->rhandle = NULL;
@@ -138,27 +137,28 @@ psa_handle_t psa_connect(uint32_t sfid, uint32_t minor_version)
138137

139138
active_msg->type = PSA_IPC_MSG_TYPE_CONNECT;
140139

141-
dst_partition->partition_state = PARTITION_STATE_ACTIVE;
142-
143140
int32_t flags = (int32_t)osThreadFlagsSet(dst_partition->thread_id, dst_sec_func->mask);
144141
SPM_ASSERT(flags >= 0);
145142
PSA_UNUSED(flags);
146143

147144
os_status = osSemaphoreAcquire(dst_partition->semaphore, osWaitForever);
148145
SPM_ASSERT(osOK == os_status);
149146

150-
PARTITION_STATE_ASSERT(dst_partition, PARTITION_STATE_COMPLETED);
151-
152147
psa_handle_t handle = active_msg->rc;
153148
if (PSA_SUCCESS == active_msg->rc) {
149+
CHANNEL_STATE_ASSERT(channel->state, CHANNEL_STATE_IDLE);
150+
154151
psa_error_t status = spm_channel_handle_create(channel, PSA_HANDLE_MGR_INVALID_FRIEND_OWNER, &handle);
155152
// handle_create() is expected to pass since channel allocation has already passed,
156153
// and the channels handler manager has the same storage size as the channels pool storage size
157154
SPM_ASSERT(PSA_SUCCESS == status);
158155
PSA_UNUSED(status);
159-
}
156+
} else {
157+
CHANNEL_STATE_ASSERT(channel->state, CHANNEL_STATE_INVALID);
160158

161-
dst_partition->partition_state = PARTITION_STATE_IDLE;
159+
os_status = osMemoryPoolFree(g_spm.channel_mem_pool, channel);
160+
SPM_ASSERT(osOK == os_status);
161+
}
162162

163163
os_status = osMutexRelease(dst_partition->mutex);
164164
SPM_ASSERT(osOK == os_status);
@@ -176,6 +176,10 @@ psa_error_t psa_call(
176176
size_t out_len
177177
)
178178
{
179+
if (handle <= 0) {
180+
SPM_PANIC("handle (%d) is invalid, must be a positive number\n", handle);
181+
}
182+
179183
if (in_len != 0) {
180184
if (in_len > PSA_MAX_INVEC_LEN) {
181185
SPM_PANIC("in_len (%d) is bigger than allowed (%d)\n", in_len, PSA_MAX_INVEC_LEN);
@@ -225,7 +229,7 @@ psa_error_t psa_call(
225229
osStatus_t os_status = osMutexAcquire(dst_partition->mutex, osWaitForever);
226230
SPM_ASSERT(osOK == os_status);
227231

228-
PARTITION_STATE_ASSERT(dst_partition, PARTITION_STATE_IDLE);
232+
CHANNEL_STATE_ASSERT(channel->state, CHANNEL_STATE_IDLE);
229233

230234
active_msg_t *active_msg = &(dst_partition->active_msg);
231235
SPM_ASSERT(PSA_IPC_MSG_TYPE_INVALID == active_msg->type);
@@ -244,7 +248,7 @@ psa_error_t psa_call(
244248

245249
active_msg->type = PSA_IPC_MSG_TYPE_CALL;
246250

247-
dst_partition->partition_state = PARTITION_STATE_ACTIVE;
251+
channel->state = CHANNEL_STATE_PENDING;
248252

249253
int32_t flags = (int32_t)osThreadFlagsSet(dst_partition->thread_id, dst_sec_func->mask);
250254
SPM_ASSERT(flags >= 0);
@@ -253,9 +257,7 @@ psa_error_t psa_call(
253257
os_status = osSemaphoreAcquire(dst_partition->semaphore, osWaitForever);
254258
SPM_ASSERT(osOK == os_status);
255259

256-
PARTITION_STATE_ASSERT(dst_partition, PARTITION_STATE_COMPLETED);
257-
258-
dst_partition->partition_state = PARTITION_STATE_IDLE;
260+
CHANNEL_STATE_ASSERT(channel->state, CHANNEL_STATE_IDLE);
259261

260262
psa_error_t rc = active_msg->rc;
261263
memset(active_msg, 0, sizeof(active_msg_t));
@@ -270,7 +272,7 @@ psa_error_t psa_call(
270272

271273
psa_error_t psa_close(psa_handle_t handle)
272274
{
273-
if (handle == PSA_NULL_HANDLE) {
275+
if (handle <= 0) {
274276
return PSA_SUCCESS;
275277
}
276278

@@ -285,7 +287,7 @@ psa_error_t psa_close(psa_handle_t handle)
285287
osStatus_t os_status = osMutexAcquire(dst_partition->mutex, osWaitForever);
286288
SPM_ASSERT(osOK == os_status);
287289

288-
PARTITION_STATE_ASSERT(dst_partition, PARTITION_STATE_IDLE);
290+
CHANNEL_STATE_ASSERT(channel->state, CHANNEL_STATE_IDLE);
289291

290292
active_msg_t *active_msg = &(dst_partition->active_msg);
291293
SPM_ASSERT(PSA_IPC_MSG_TYPE_INVALID == active_msg->type);
@@ -294,7 +296,7 @@ psa_error_t psa_close(psa_handle_t handle)
294296

295297
active_msg->type = PSA_IPC_MSG_TYPE_DISCONNECT;
296298

297-
dst_partition->partition_state = PARTITION_STATE_ACTIVE;
299+
channel->state = CHANNEL_STATE_INVALID;
298300

299301
int32_t flags = (int32_t)osThreadFlagsSet(dst_partition->thread_id, dst_sec_func->mask);
300302
SPM_ASSERT(flags >= 0);
@@ -303,9 +305,7 @@ psa_error_t psa_close(psa_handle_t handle)
303305
os_status = osSemaphoreAcquire(dst_partition->semaphore, osWaitForever);
304306
SPM_ASSERT(osOK == os_status);
305307

306-
PARTITION_STATE_ASSERT(dst_partition, PARTITION_STATE_COMPLETED);
307-
308-
dst_partition->partition_state = PARTITION_STATE_IDLE;
308+
CHANNEL_STATE_ASSERT(channel->state, CHANNEL_STATE_INVALID);
309309

310310
spm_channel_handle_destroy(handle);
311311

spm/spm_internal.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,27 @@
2626
extern "C" {
2727
#endif
2828

29-
#define PARTITION_STATE_ASSERT(partition, partition_state_expected) \
30-
do { \
31-
if (partition->partition_state != partition_state_expected) { \
32-
SPM_PANIC("partition with ID 0x%x is in incorrect processing state: %d while %d is expected!\n", \
33-
partition->partition_id, partition->partition_state, partition_state_expected); \
34-
} \
29+
#define CHANNEL_STATE_ASSERT(current_state, expected_state) \
30+
do { \
31+
if (current_state != expected_state) { \
32+
SPM_PANIC("channel in incorrect processing state: %d while %d is expected!\n", \
33+
current_state, expected_state); \
34+
} \
3535
} while (0)
3636

3737
typedef struct partition partition_t;
3838
typedef struct ipc_channel ipc_channel_t;
3939

4040
/*
41-
* Enumeration for the possible Partition processing states.
41+
* Enumeration for the possible channel processing states.
4242
*/
4343
typedef enum partition_state {
44-
PARTITION_STATE_INVALID = 0,
45-
PARTITION_STATE_IDLE = 1,
46-
PARTITION_STATE_ACTIVE = 2,
47-
PARTITION_STATE_COMPLETED = 3
48-
} PartitionState;
44+
CHANNEL_STATE_INVALID = 0,
45+
CHANNEL_STATE_CONNECTING = 1,
46+
CHANNEL_STATE_IDLE = 2,
47+
CHANNEL_STATE_PENDING = 3,
48+
CHANNEL_STATE_ACTIVE = 4
49+
} ChannelState;
4950

5051
/*
5152
* Structure containing the SPM internal data.
@@ -86,7 +87,6 @@ typedef struct secure_func {
8687
*/
8788
typedef struct partition {
8889
const int32_t partition_id; /* The Partition ID.*/
89-
PartitionState partition_state; /* The current processing state of the Partition.*/
9090
osThreadId_t thread_id; /* Thread ID of the Partition thread.*/
9191
const uint32_t flags_sf; /* Mask of all the SF signals the partition supports.*/
9292
const uint32_t flags_interrupts; /* Mask of all the IRQs & doorbell which the partition supports.*/
@@ -104,6 +104,7 @@ typedef struct partition {
104104
* Structure containing Partition->Secure-Function channel information.
105105
*/
106106
typedef struct ipc_channel {
107+
ChannelState state; /* The current processing state of the channel.*/
107108
partition_t *src_partition; /* Pointer to the Partition which connects to the Secure function.*/
108109
secure_func_t *dst_sec_func; /* Pointer to the connected Secure Function.*/
109110
void *rhandle; /* Reverse handle to be used for this channel.*/

spm/spm_server.c

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,30 @@ void psa_get(psa_signal_t signum, psa_msg_t *msg)
146146
SPM_ASSERT((active_msg->channel->rhandle == NULL) ||
147147
(active_msg->type != PSA_IPC_MSG_TYPE_CONNECT));
148148

149-
PARTITION_STATE_ASSERT(curr_partition, PARTITION_STATE_ACTIVE);
149+
ChannelState expected_channel_state = CHANNEL_STATE_INVALID;
150+
ChannelState next_channel_state = CHANNEL_STATE_INVALID;
151+
switch (active_msg->type) {
152+
case PSA_IPC_MSG_TYPE_CONNECT:
153+
expected_channel_state = CHANNEL_STATE_CONNECTING;
154+
next_channel_state = CHANNEL_STATE_IDLE;
155+
break;
156+
157+
case PSA_IPC_MSG_TYPE_CALL:
158+
expected_channel_state = CHANNEL_STATE_PENDING;
159+
next_channel_state = CHANNEL_STATE_ACTIVE;
160+
break;
161+
162+
case PSA_IPC_MSG_TYPE_DISCONNECT:
163+
expected_channel_state = CHANNEL_STATE_INVALID;
164+
next_channel_state = CHANNEL_STATE_INVALID;
165+
break;
166+
167+
default:
168+
SPM_PANIC("Unexpected message type %d\n", active_msg->type);
169+
}
170+
CHANNEL_STATE_ASSERT(active_msg->channel->state, expected_channel_state);
171+
172+
active_msg->channel->state = next_channel_state;
150173

151174
if (curr_partition->msg_handle == PSA_NULL_HANDLE) {
152175
psa_error_t status = spm_msg_handle_create(
@@ -183,7 +206,7 @@ static size_t read_or_skip(psa_handle_t msg_handle, uint32_t invec_idx, void *bu
183206
SPM_ASSERT((active_msg->type > PSA_IPC_MSG_TYPE_INVALID) &&
184207
(active_msg->type <= PSA_IPC_MSG_TYPE_MAX));
185208

186-
PARTITION_STATE_ASSERT(active_msg->channel->dst_sec_func->partition, PARTITION_STATE_ACTIVE);
209+
CHANNEL_STATE_ASSERT(active_msg->channel->state, CHANNEL_STATE_ACTIVE);
187210

188211
psa_invec_t *active_iovec = &active_msg->in_vec[invec_idx];
189212

@@ -236,7 +259,7 @@ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, const void *buffer,
236259
SPM_ASSERT((active_msg->type > PSA_IPC_MSG_TYPE_INVALID) &&
237260
(active_msg->type <= PSA_IPC_MSG_TYPE_MAX));
238261

239-
PARTITION_STATE_ASSERT(active_msg->channel->dst_sec_func->partition, PARTITION_STATE_ACTIVE);
262+
CHANNEL_STATE_ASSERT(active_msg->channel->state, CHANNEL_STATE_ACTIVE);
240263

241264
psa_outvec_t *active_iovec = &active_msg->out_vec[outvec_idx];
242265

@@ -269,13 +292,35 @@ void psa_end(psa_handle_t msg_handle, psa_error_t retval)
269292

270293
secure_func_t *dst_sec_func = active_msg->channel->dst_sec_func;
271294

272-
PARTITION_STATE_ASSERT(dst_sec_func->partition, PARTITION_STATE_ACTIVE);
295+
ChannelState expected_channel_state = CHANNEL_STATE_INVALID;
296+
ChannelState next_channel_state = CHANNEL_STATE_INVALID;
297+
switch (active_msg->type) {
298+
case PSA_IPC_MSG_TYPE_CONNECT:
299+
expected_channel_state = CHANNEL_STATE_IDLE;
300+
next_channel_state = (retval < 0 ? CHANNEL_STATE_INVALID : CHANNEL_STATE_IDLE);
301+
break;
302+
303+
case PSA_IPC_MSG_TYPE_CALL:
304+
expected_channel_state = CHANNEL_STATE_ACTIVE;
305+
next_channel_state = CHANNEL_STATE_IDLE;
306+
break;
307+
308+
case PSA_IPC_MSG_TYPE_DISCONNECT:
309+
expected_channel_state = CHANNEL_STATE_INVALID;
310+
next_channel_state = CHANNEL_STATE_INVALID;
311+
break;
312+
313+
default:
314+
SPM_PANIC("Unexpected message type %d\n", active_msg->type);
315+
}
316+
317+
CHANNEL_STATE_ASSERT(active_msg->channel->state, expected_channel_state);
318+
319+
active_msg->channel->state = next_channel_state;
273320

274321
active_msg->type = PSA_IPC_MSG_TYPE_INVALID; // Invalidate active_msg
275322
active_msg->rc = retval;
276323

277-
dst_sec_func->partition->partition_state = PARTITION_STATE_COMPLETED;
278-
279324
partition_t *curr_partition = active_partition_get();
280325
SPM_ASSERT(NULL != curr_partition); // active thread in SPM must be in partition DB
281326
spm_msg_handle_destroy(curr_partition->msg_handle);

tools/spm/templates/psa_NAME_partition.c.tpl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,5 @@ void {{partition.name|lower}}_init(partition_t *partition)
125125
if (NULL == partition->thread_id) {
126126
SPM_PANIC("Failed to create start main thread of partition {{partition.name|lower}}!\n");
127127
}
128-
partition->partition_state = PARTITION_STATE_IDLE;
129128
}
130129
{# End of file #}

tools/spm/templates/psa_common.c.tpl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ partition_t g_partitions[{{partitions|count}}] = {
3737
{% for partition in partitions %}
3838
{
3939
.partition_id = {{partition.id}},
40-
.partition_state = PARTITION_STATE_INVALID,
4140
.thread_id = 0,
4241
.flags_sf = {{partition.name|upper}}_WAIT_ANY_SFID_MSK,
4342
.flags_interrupts = {{partition.name|upper}}_WAIT_ANY_IRQ_MSK | {{partition.name|upper}}_DOORBELL_MSK,

0 commit comments

Comments
 (0)