1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2017, Linaro Limited
4  */
5 
6 #include <atomic.h>
7 #include <kernel/mutex.h>
8 #include <pta_invoke_tests.h>
9 #include <trace.h>
10 
11 #include "misc.h"
12 
13 static uint32_t before_lock_readers;
14 static uint32_t before_lock_writers;
15 static uint32_t during_lock_readers;
16 static uint32_t during_lock_writers;
17 
18 static uint64_t val0;
19 static uint64_t val1;
20 
21 struct mutex test_mutex = MUTEX_INITIALIZER;
22 
mutex_test_writer(TEE_Param params[TEE_NUM_PARAMS])23 static TEE_Result mutex_test_writer(TEE_Param params[TEE_NUM_PARAMS])
24 {
25 	size_t n;
26 
27 	params[1].value.a = atomic_inc32(&before_lock_writers);
28 
29 	mutex_lock(&test_mutex);
30 
31 	atomic_dec32(&before_lock_writers);
32 
33 	params[1].value.b = atomic_inc32(&during_lock_writers);
34 
35 	for (n = 0; n < params[0].value.b; n++) {
36 		val0++;
37 		val1++;
38 		val1++;
39 	}
40 
41 	atomic_dec32(&during_lock_writers);
42 	mutex_unlock(&test_mutex);
43 
44 	return TEE_SUCCESS;
45 }
46 
mutex_test_reader(TEE_Param params[TEE_NUM_PARAMS])47 static TEE_Result mutex_test_reader(TEE_Param params[TEE_NUM_PARAMS])
48 {
49 	TEE_Result res = TEE_SUCCESS;
50 	size_t n;
51 
52 	params[1].value.a = atomic_inc32(&before_lock_readers);
53 
54 	mutex_read_lock(&test_mutex);
55 
56 	atomic_dec32(&before_lock_readers);
57 
58 	params[1].value.b = atomic_inc32(&during_lock_readers);
59 
60 	for (n = 0; n < params[0].value.b; n++) {
61 		if (val0 * 2 != val1)
62 			res = TEE_ERROR_BAD_STATE;
63 	}
64 
65 	atomic_dec32(&during_lock_readers);
66 	mutex_read_unlock(&test_mutex);
67 
68 	return res;
69 }
70 
core_mutex_tests(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])71 TEE_Result core_mutex_tests(uint32_t param_types,
72 			    TEE_Param params[TEE_NUM_PARAMS])
73 {
74 	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
75 					  TEE_PARAM_TYPE_VALUE_OUTPUT,
76 					  TEE_PARAM_TYPE_NONE,
77 					  TEE_PARAM_TYPE_NONE);
78 
79 	if (exp_pt != param_types) {
80 		DMSG("bad parameter types");
81 		return TEE_ERROR_BAD_PARAMETERS;
82 	}
83 
84 	switch (params[0].value.a) {
85 	case PTA_MUTEX_TEST_WRITER:
86 		return mutex_test_writer(params);
87 	case PTA_MUTEX_TEST_READER:
88 		return mutex_test_reader(params);
89 	default:
90 		return TEE_ERROR_BAD_PARAMETERS;
91 	}
92 }
93