@@ -128,6 +128,11 @@ static int shadow_ctor(void *obj, void *shadow_data, void *ctor_data)
128128 return 0 ;
129129}
130130
131+ /*
132+ * With more than one item to free in the list, order is not determined and
133+ * shadow_dtor will not be passed to shadow_free_all() which would make the
134+ * test fail. (see pass 6)
135+ */
131136static void shadow_dtor (void * obj , void * shadow_data )
132137{
133138 int * * sv = shadow_data ;
@@ -136,6 +141,9 @@ static void shadow_dtor(void *obj, void *shadow_data)
136141 __func__ , ptr_id (obj ), ptr_id (sv ));
137142}
138143
144+ /* number of objects we simulate that need shadow vars */
145+ #define NUM_OBJS 3
146+
139147/* dynamically created obj fields have the following shadow var id values */
140148#define SV_ID1 0x1234
141149#define SV_ID2 0x1235
@@ -157,122 +165,106 @@ struct test_object {
157165
158166static int test_klp_shadow_vars_init (void )
159167{
160- struct test_object obj1 , obj2 , obj3 ;
161- char nfield1 , nfield2 , * pnfield1 , * pnfield2 , * * sv1 , * * sv2 ;
162- int nfield3 , nfield4 , * pnfield3 , * pnfield4 , * * sv3 , * * sv4 ;
168+ struct test_object objs [NUM_OBJS ];
169+ char nfields1 [NUM_OBJS ], * pnfields1 [NUM_OBJS ], * * sv1 [NUM_OBJS ];
170+ char * pndup [NUM_OBJS ];
171+ int nfields2 [NUM_OBJS ], * pnfields2 [NUM_OBJS ], * * sv2 [NUM_OBJS ];
163172 void * * sv ;
164-
165- pnfield1 = & nfield1 ;
166- pnfield2 = & nfield2 ;
167- pnfield3 = & nfield3 ;
168- pnfield4 = & nfield4 ;
173+ int i ;
169174
170175 ptr_id (NULL );
171- ptr_id (pnfield1 );
172- ptr_id (pnfield2 );
173- ptr_id (pnfield3 );
174- ptr_id (pnfield4 );
175176
176177 /*
177178 * With an empty shadow variable hash table, expect not to find
178179 * any matches.
179180 */
180- sv = shadow_get (& obj1 , SV_ID1 );
181+ sv = shadow_get (& objs [ 0 ] , SV_ID1 );
181182 if (!sv )
182183 pr_info (" got expected NULL result\n" );
183184
184- /*
185- * Allocate a few shadow variables with different <obj> and <id>.
186- */
187- sv1 = shadow_alloc (& obj1 , SV_ID1 , sizeof (pnfield1 ), GFP_KERNEL , shadow_ctor , & pnfield1 );
188- if (!sv1 )
189- return - ENOMEM ;
190-
191- sv2 = shadow_alloc (& obj2 , SV_ID1 , sizeof (pnfield2 ), GFP_KERNEL , shadow_ctor , & pnfield2 );
192- if (!sv2 )
193- return - ENOMEM ;
194-
195- sv3 = shadow_alloc (& obj1 , SV_ID2 , sizeof (pnfield3 ), GFP_KERNEL , shadow_ctor , & pnfield3 );
196- if (!sv3 )
197- return - ENOMEM ;
198-
199- /*
200- * Verify we can find our new shadow variables and that they point
201- * to expected data.
202- */
203- sv = shadow_get (& obj1 , SV_ID1 );
204- if (!sv )
205- return - EINVAL ;
206- if ((char * * )sv == sv1 && * sv1 == pnfield1 )
207- pr_info (" got expected PTR%d -> PTR%d result\n" ,
208- ptr_id (sv1 ), ptr_id (* sv1 ));
209-
210- sv = shadow_get (& obj2 , SV_ID1 );
211- if (!sv )
212- return - EINVAL ;
213- if ((char * * )sv == sv2 && * sv2 == pnfield2 )
214- pr_info (" got expected PTR%d -> PTR%d result\n" ,
215- ptr_id (sv2 ), ptr_id (* sv2 ));
216-
217- sv = shadow_get (& obj1 , SV_ID2 );
218- if (!sv )
219- return - EINVAL ;
220- if ((int * * )sv == sv3 && * sv3 == pnfield3 )
221- pr_info (" got expected PTR%d -> PTR%d result\n" ,
222- ptr_id (sv3 ), ptr_id (* sv3 ));
223-
224- /*
225- * Allocate or get a few more, this time with the same <obj>, <id>.
226- * The second invocation should return the same shadow var.
227- */
228- sv4 = shadow_get_or_alloc (& obj3 , SV_ID1 , sizeof (pnfield4 ), GFP_KERNEL , shadow_ctor , & pnfield4 );
229- if (!sv4 )
230- return - ENOMEM ;
231-
232- sv = shadow_get_or_alloc (& obj3 , SV_ID1 , sizeof (pnfield4 ), GFP_KERNEL , shadow_ctor , & pnfield4 );
233- if (!sv )
234- return - EINVAL ;
235- if ((int * * )sv == sv4 && * sv4 == pnfield4 )
236- pr_info (" got expected PTR%d -> PTR%d result\n" ,
237- ptr_id (sv4 ), ptr_id (* sv4 ));
238-
239- /*
240- * Free the <obj=*, id> shadow variables and check that we can no
241- * longer find them.
242- */
243- shadow_free (& obj1 , SV_ID1 , shadow_dtor ); /* sv1 */
244- sv = shadow_get (& obj1 , SV_ID1 );
245- if (!sv )
246- pr_info (" got expected NULL result\n" );
185+ /* pass 1: init & alloc a char+int pair of svars for each objs */
186+ for (i = 0 ; i < NUM_OBJS ; i ++ ) {
187+ pnfields1 [i ] = & nfields1 [i ];
188+ ptr_id (pnfields1 [i ]);
189+
190+ if (i % 2 ) {
191+ sv1 [i ] = shadow_alloc (& objs [i ], SV_ID1 ,
192+ sizeof (pnfields1 [i ]), GFP_KERNEL ,
193+ shadow_ctor , & pnfields1 [i ]);
194+ } else {
195+ sv1 [i ] = shadow_get_or_alloc (& objs [i ], SV_ID1 ,
196+ sizeof (pnfields1 [i ]), GFP_KERNEL ,
197+ shadow_ctor , & pnfields1 [i ]);
198+ }
199+ if (!sv1 [i ])
200+ return - ENOMEM ;
201+
202+ pnfields2 [i ] = & nfields2 [i ];
203+ ptr_id (pnfields2 [i ]);
204+ sv2 [i ] = shadow_alloc (& objs [i ], SV_ID2 , sizeof (pnfields2 [i ]),
205+ GFP_KERNEL , shadow_ctor , & pnfields2 [i ]);
206+ if (!sv2 [i ])
207+ return - ENOMEM ;
208+ }
247209
248- shadow_free (& obj2 , SV_ID1 , shadow_dtor ); /* sv2 */
249- sv = shadow_get (& obj2 , SV_ID1 );
250- if (!sv )
251- pr_info (" got expected NULL result\n" );
210+ /* pass 2: verify we find allocated svars and where they point to */
211+ for (i = 0 ; i < NUM_OBJS ; i ++ ) {
212+ /* check the "char" svar for all objects */
213+ sv = shadow_get (& objs [i ], SV_ID1 );
214+ if (!sv )
215+ return - EINVAL ;
216+ if ((char * * )sv == sv1 [i ] && * sv1 [i ] == pnfields1 [i ])
217+ pr_info (" got expected PTR%d -> PTR%d result\n" ,
218+ ptr_id (sv1 [i ]), ptr_id (* sv1 [i ]));
219+
220+ /* check the "int" svar for all objects */
221+ sv = shadow_get (& objs [i ], SV_ID2 );
222+ if (!sv )
223+ return - EINVAL ;
224+ if ((int * * )sv == sv2 [i ] && * sv2 [i ] == pnfields2 [i ])
225+ pr_info (" got expected PTR%d -> PTR%d result\n" ,
226+ ptr_id (sv2 [i ]), ptr_id (* sv2 [i ]));
227+ }
252228
253- shadow_free (& obj3 , SV_ID1 , shadow_dtor ); /* sv4 */
254- sv = shadow_get (& obj3 , SV_ID1 );
255- if (!sv )
256- pr_info (" got expected NULL result\n" );
229+ /* pass 3: verify that 'get_or_alloc' returns already allocated svars */
230+ for (i = 0 ; i < NUM_OBJS ; i ++ ) {
231+ pndup [i ] = & nfields1 [i ];
232+ ptr_id (pndup [i ]);
233+
234+ sv = shadow_get_or_alloc (& objs [i ], SV_ID1 , sizeof (pndup [i ]),
235+ GFP_KERNEL , shadow_ctor , & pndup [i ]);
236+ if (!sv )
237+ return - EINVAL ;
238+ if ((char * * )sv == sv1 [i ] && * sv1 [i ] == pnfields1 [i ])
239+ pr_info (" got expected PTR%d -> PTR%d result\n" ,
240+ ptr_id (sv1 [i ]), ptr_id (* sv1 [i ]));
241+ }
257242
258- /*
259- * We should still find an <id+1> variable.
260- */
261- sv = shadow_get (& obj1 , SV_ID2 );
262- if (!sv )
263- return - EINVAL ;
264- if ((int * * )sv == sv3 && * sv3 == pnfield3 )
265- pr_info (" got expected PTR%d -> PTR%d result\n" ,
266- ptr_id (sv3 ), ptr_id (* sv3 ));
243+ /* pass 4: free <objs[*], SV_ID1> pairs of svars, verify removal */
244+ for (i = 0 ; i < NUM_OBJS ; i ++ ) {
245+ shadow_free (& objs [i ], SV_ID1 , shadow_dtor ); /* 'char' pairs */
246+ sv = shadow_get (& objs [i ], SV_ID1 );
247+ if (!sv )
248+ pr_info (" got expected NULL result\n" );
249+ }
267250
268- /*
269- * Free all the <id+1> variables, too.
270- */
271- shadow_free_all (SV_ID2 , shadow_dtor ); /* sv3 */
272- sv = shadow_get (& obj1 , SV_ID1 );
273- if (!sv )
274- pr_info (" shadow_get() got expected NULL result\n" );
251+ /* pass 5: check we still find <objs[*], SV_ID2> svar pairs */
252+ for (i = 0 ; i < NUM_OBJS ; i ++ ) {
253+ sv = shadow_get (& objs [i ], SV_ID2 ); /* 'int' pairs */
254+ if (!sv )
255+ return - EINVAL ;
256+ if ((int * * )sv == sv2 [i ] && * sv2 [i ] == pnfields2 [i ])
257+ pr_info (" got expected PTR%d -> PTR%d result\n" ,
258+ ptr_id (sv2 [i ]), ptr_id (* sv2 [i ]));
259+ }
275260
261+ /* pass 6: free all the <objs[*], SV_ID2> svar pairs too. */
262+ shadow_free_all (SV_ID2 , NULL ); /* 'int' pairs */
263+ for (i = 0 ; i < NUM_OBJS ; i ++ ) {
264+ sv = shadow_get (& objs [i ], SV_ID2 );
265+ if (!sv )
266+ pr_info (" got expected NULL result\n" );
267+ }
276268
277269 free_ptr_list ();
278270
0 commit comments