xref: /optee_os/core/pta/tests/lockdep.c (revision 963051aae2b2c144feed2a82080cab35109de9b8)
1*963051aaSJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2*963051aaSJerome Forissier /*
3*963051aaSJerome Forissier  * Copyright (c) 2018, Linaro Limited
4*963051aaSJerome Forissier  */
5*963051aaSJerome Forissier 
6*963051aaSJerome Forissier /*
7*963051aaSJerome Forissier  * Test lockdep with hypothetical thread and lock objects
8*963051aaSJerome Forissier  */
9*963051aaSJerome Forissier 
10*963051aaSJerome Forissier #include <assert.h>
11*963051aaSJerome Forissier #include <kernel/lockdep.h>
12*963051aaSJerome Forissier 
13*963051aaSJerome Forissier #include "misc.h"
14*963051aaSJerome Forissier 
self_test_lockdep1(void)15*963051aaSJerome Forissier static int self_test_lockdep1(void)
16*963051aaSJerome Forissier {
17*963051aaSJerome Forissier 	TEE_Result res = TEE_ERROR_GENERIC;
18*963051aaSJerome Forissier 	struct lockdep_node_head graph;
19*963051aaSJerome Forissier 	struct lockdep_lock_head thread1;
20*963051aaSJerome Forissier 	int count = 1;
21*963051aaSJerome Forissier 
22*963051aaSJerome Forissier 	DMSG("");
23*963051aaSJerome Forissier 
24*963051aaSJerome Forissier 	TAILQ_INIT(&thread1);
25*963051aaSJerome Forissier 	TAILQ_INIT(&graph);
26*963051aaSJerome Forissier 
27*963051aaSJerome Forissier 	/* Not locked, expect failure */
28*963051aaSJerome Forissier 	res = __lockdep_lock_release(&thread1, 1);
29*963051aaSJerome Forissier 	if (!res)
30*963051aaSJerome Forissier 		return count;
31*963051aaSJerome Forissier 	count++;
32*963051aaSJerome Forissier 
33*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread1, 1);
34*963051aaSJerome Forissier 	if (res)
35*963051aaSJerome Forissier 		return count;
36*963051aaSJerome Forissier 	count++;
37*963051aaSJerome Forissier 
38*963051aaSJerome Forissier 	res = __lockdep_lock_release(&thread1, 1);
39*963051aaSJerome Forissier 	if (res)
40*963051aaSJerome Forissier 		return count;
41*963051aaSJerome Forissier 	count++;
42*963051aaSJerome Forissier 
43*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread1, 1);
44*963051aaSJerome Forissier 	if (res)
45*963051aaSJerome Forissier 		return count;
46*963051aaSJerome Forissier 	count++;
47*963051aaSJerome Forissier 
48*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread1, 3);
49*963051aaSJerome Forissier 	if (res)
50*963051aaSJerome Forissier 		return count;
51*963051aaSJerome Forissier 	count++;
52*963051aaSJerome Forissier 
53*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread1, 2);
54*963051aaSJerome Forissier 	if (res)
55*963051aaSJerome Forissier 		return count;
56*963051aaSJerome Forissier 	count++;
57*963051aaSJerome Forissier 
58*963051aaSJerome Forissier 	res = __lockdep_lock_release(&thread1, 3);
59*963051aaSJerome Forissier 	if (res)
60*963051aaSJerome Forissier 		return count;
61*963051aaSJerome Forissier 	count++;
62*963051aaSJerome Forissier 
63*963051aaSJerome Forissier 	/* Already locked */
64*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread1, 2);
65*963051aaSJerome Forissier 	if (!res)
66*963051aaSJerome Forissier 		return count;
67*963051aaSJerome Forissier 
68*963051aaSJerome Forissier 	lockdep_graph_delete(&graph);
69*963051aaSJerome Forissier 	lockdep_queue_delete(&thread1);
70*963051aaSJerome Forissier 
71*963051aaSJerome Forissier 	return 0;
72*963051aaSJerome Forissier }
73*963051aaSJerome Forissier 
self_test_lockdep2(void)74*963051aaSJerome Forissier static int self_test_lockdep2(void)
75*963051aaSJerome Forissier {
76*963051aaSJerome Forissier 	TEE_Result res = TEE_ERROR_GENERIC;
77*963051aaSJerome Forissier 	struct lockdep_node_head graph;
78*963051aaSJerome Forissier 	struct lockdep_lock_head thread1;
79*963051aaSJerome Forissier 	struct lockdep_lock_head thread2;
80*963051aaSJerome Forissier 	struct lockdep_lock_head thread3;
81*963051aaSJerome Forissier 	int count = 1;
82*963051aaSJerome Forissier 
83*963051aaSJerome Forissier 	DMSG("");
84*963051aaSJerome Forissier 
85*963051aaSJerome Forissier 	TAILQ_INIT(&thread1);
86*963051aaSJerome Forissier 	TAILQ_INIT(&thread2);
87*963051aaSJerome Forissier 	TAILQ_INIT(&thread3);
88*963051aaSJerome Forissier 	TAILQ_INIT(&graph);
89*963051aaSJerome Forissier 
90*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread1, 1);
91*963051aaSJerome Forissier 	if (res)
92*963051aaSJerome Forissier 		return count;
93*963051aaSJerome Forissier 	count++;
94*963051aaSJerome Forissier 
95*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread2, 2);
96*963051aaSJerome Forissier 	if (res)
97*963051aaSJerome Forissier 		return count;
98*963051aaSJerome Forissier 	count++;
99*963051aaSJerome Forissier 
100*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread1, 2);
101*963051aaSJerome Forissier 	if (res)
102*963051aaSJerome Forissier 		return count;
103*963051aaSJerome Forissier 	count++;
104*963051aaSJerome Forissier 
105*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread3, 3);
106*963051aaSJerome Forissier 	if (res)
107*963051aaSJerome Forissier 		return count;
108*963051aaSJerome Forissier 	count++;
109*963051aaSJerome Forissier 
110*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread2, 3);
111*963051aaSJerome Forissier 	if (res)
112*963051aaSJerome Forissier 		return count;
113*963051aaSJerome Forissier 	count++;
114*963051aaSJerome Forissier 
115*963051aaSJerome Forissier 	/* Deadlock 1-2-3 */
116*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread3, 1);
117*963051aaSJerome Forissier 	if (!res)
118*963051aaSJerome Forissier 		return count;
119*963051aaSJerome Forissier 
120*963051aaSJerome Forissier 	lockdep_graph_delete(&graph);
121*963051aaSJerome Forissier 	lockdep_queue_delete(&thread1);
122*963051aaSJerome Forissier 	lockdep_queue_delete(&thread2);
123*963051aaSJerome Forissier 	lockdep_queue_delete(&thread3);
124*963051aaSJerome Forissier 
125*963051aaSJerome Forissier 	return 0;
126*963051aaSJerome Forissier }
127*963051aaSJerome Forissier 
self_test_lockdep3(void)128*963051aaSJerome Forissier static int self_test_lockdep3(void)
129*963051aaSJerome Forissier {
130*963051aaSJerome Forissier 	TEE_Result res = TEE_ERROR_GENERIC;
131*963051aaSJerome Forissier 	struct lockdep_node_head graph;
132*963051aaSJerome Forissier 	struct lockdep_lock_head thread1;
133*963051aaSJerome Forissier 	struct lockdep_lock_head thread2;
134*963051aaSJerome Forissier 	int count = 1;
135*963051aaSJerome Forissier 
136*963051aaSJerome Forissier 	DMSG("");
137*963051aaSJerome Forissier 
138*963051aaSJerome Forissier 	TAILQ_INIT(&thread1);
139*963051aaSJerome Forissier 	TAILQ_INIT(&thread2);
140*963051aaSJerome Forissier 	TAILQ_INIT(&graph);
141*963051aaSJerome Forissier 
142*963051aaSJerome Forissier 	res = __lockdep_lock_tryacquire(&graph, &thread1, 1);
143*963051aaSJerome Forissier 	if (res)
144*963051aaSJerome Forissier 		return count;
145*963051aaSJerome Forissier 	count++;
146*963051aaSJerome Forissier 
147*963051aaSJerome Forissier 	res = __lockdep_lock_release(&thread1, 1);
148*963051aaSJerome Forissier 	if (res)
149*963051aaSJerome Forissier 		return count;
150*963051aaSJerome Forissier 	count++;
151*963051aaSJerome Forissier 
152*963051aaSJerome Forissier 	res = __lockdep_lock_tryacquire(&graph, &thread1, 1);
153*963051aaSJerome Forissier 	if (res)
154*963051aaSJerome Forissier 		return count;
155*963051aaSJerome Forissier 	count++;
156*963051aaSJerome Forissier 
157*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread2, 2);
158*963051aaSJerome Forissier 	if (res)
159*963051aaSJerome Forissier 		return count;
160*963051aaSJerome Forissier 	count++;
161*963051aaSJerome Forissier 
162*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread1, 2);
163*963051aaSJerome Forissier 	if (res)
164*963051aaSJerome Forissier 		return count;
165*963051aaSJerome Forissier 	count++;
166*963051aaSJerome Forissier 
167*963051aaSJerome Forissier 	/* Deadlock 1-2 */
168*963051aaSJerome Forissier 	res = __lockdep_lock_acquire(&graph, &thread2, 1);
169*963051aaSJerome Forissier 	if (!res)
170*963051aaSJerome Forissier 		return count;
171*963051aaSJerome Forissier 
172*963051aaSJerome Forissier 	lockdep_graph_delete(&graph);
173*963051aaSJerome Forissier 	lockdep_queue_delete(&thread1);
174*963051aaSJerome Forissier 	lockdep_queue_delete(&thread2);
175*963051aaSJerome Forissier 
176*963051aaSJerome Forissier 	return 0;
177*963051aaSJerome Forissier }
178*963051aaSJerome Forissier 
core_lockdep_tests(uint32_t nParamTypes __unused,TEE_Param pParams[TEE_NUM_PARAMS]__unused)179*963051aaSJerome Forissier TEE_Result core_lockdep_tests(uint32_t nParamTypes __unused,
180*963051aaSJerome Forissier 			      TEE_Param pParams[TEE_NUM_PARAMS] __unused)
181*963051aaSJerome Forissier 
182*963051aaSJerome Forissier {
183*963051aaSJerome Forissier 	int count = 0;
184*963051aaSJerome Forissier 
185*963051aaSJerome Forissier 	count = self_test_lockdep1();
186*963051aaSJerome Forissier 	if (count)
187*963051aaSJerome Forissier 		goto out;
188*963051aaSJerome Forissier 	count = self_test_lockdep2();
189*963051aaSJerome Forissier 	if (count)
190*963051aaSJerome Forissier 		goto out;
191*963051aaSJerome Forissier 	count = self_test_lockdep3();
192*963051aaSJerome Forissier 	if (count)
193*963051aaSJerome Forissier 		goto out;
194*963051aaSJerome Forissier out:
195*963051aaSJerome Forissier 	if (count) {
196*963051aaSJerome Forissier 		DMSG("count=%d", count);
197*963051aaSJerome Forissier 		return TEE_ERROR_GENERIC;
198*963051aaSJerome Forissier 	}
199*963051aaSJerome Forissier 
200*963051aaSJerome Forissier 	return TEE_SUCCESS;
201*963051aaSJerome Forissier }
202