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