slab: Add an arena pointer to the interface
[akaros.git] / kern / src / ktest / pb_ktests.c
1 /*
2  * Postboot kernel tests: Tests to be ran after boot in kernel mode.
3  * TODO: Some of the tests here may not necessarily be tests to be ran after
4  *       boot. If that is the case, change them in
5  */
6
7 #include <arch/mmu.h>
8 #include <arch/arch.h>
9 #include <arch/uaccess.h>
10 #include <bitmask.h>
11 #include <smp.h>
12
13 #include <ros/memlayout.h>
14 #include <ros/common.h>
15 #include <ros/bcq.h>
16 #include <ros/ucq.h>
17
18 #include <atomic.h>
19 #include <stdio.h>
20 #include <assert.h>
21 #include <string.h>
22 #include <testing.h>
23 #include <trap.h>
24 #include <process.h>
25 #include <syscall.h>
26 #include <time.h>
27 #include <kfs.h>
28 #include <mm.h>
29 #include <multiboot.h>
30 #include <pmap.h>
31 #include <page_alloc.h>
32 #include <pmap.h>
33 #include <slab.h>
34 #include <kmalloc.h>
35 #include <hashtable.h>
36 #include <radix.h>
37 #include <circular_buffer.h>
38 #include <monitor.h>
39 #include <kthread.h>
40 #include <schedule.h>
41 #include <umem.h>
42 #include <init.h>
43 #include <ucq.h>
44 #include <setjmp.h>
45 #include <sort.h>
46
47 #include <apipe.h>
48 #include <rwlock.h>
49 #include <rendez.h>
50 #include <ktest.h>
51 #include <smallidpool.h>
52 #include <linker_func.h>
53
54 KTEST_SUITE("POSTBOOT")
55
56 #ifdef CONFIG_X86
57
58 // TODO: Do test if possible inside this function, and add assertions.
59 bool test_ipi_sending(void)
60 {
61         int8_t state = 0;
62
63         register_irq(I_TESTING, test_hello_world_handler, NULL,
64                      MKBUS(BusIPI, 0, 0, 0));
65         enable_irqsave(&state);
66         cprintf("\nCORE 0 sending broadcast\n");
67         send_broadcast_ipi(I_TESTING);
68         udelay(3000000);
69         cprintf("\nCORE 0 sending all others\n");
70         send_all_others_ipi(I_TESTING);
71         udelay(3000000);
72         cprintf("\nCORE 0 sending self\n");
73         send_self_ipi(I_TESTING);
74         udelay(3000000);
75         cprintf("\nCORE 0 sending ipi to physical 1\n");
76         send_ipi(0x01, I_TESTING);
77         udelay(3000000);
78         cprintf("\nCORE 0 sending ipi to physical 2\n");
79         send_ipi(0x02, I_TESTING);
80         udelay(3000000);
81         cprintf("\nCORE 0 sending ipi to physical 3\n");
82         send_ipi(0x03, I_TESTING);
83         udelay(3000000);
84         cprintf("\nCORE 0 sending ipi to physical 15\n");
85         send_ipi(0x0f, I_TESTING);
86         udelay(3000000);
87         cprintf("\nCORE 0 sending ipi to logical 2\n");
88         send_group_ipi(0x02, I_TESTING);
89         udelay(3000000);
90         cprintf("\nCORE 0 sending ipi to logical 1\n");
91         send_group_ipi(0x01, I_TESTING);
92         udelay(3000000);
93         cprintf("\nDone!\n");
94         disable_irqsave(&state);
95
96         return true;
97 }
98
99 // TODO: Refactor to make it return and add assertions.
100 // Note this never returns and will muck with any other timer work
101 bool test_pic_reception(void)
102 {
103         register_irq(IdtPIC + IrqCLOCK, test_hello_world_handler, NULL,
104                      MKBUS(BusISA, 0, 0, 0));
105         pit_set_timer(100,TIMER_RATEGEN); // totally arbitrary time
106         pic_unmask_irq(0, 0);
107         cprintf("PIC1 Mask = 0x%04x\n", inb(PIC1_DATA));
108         cprintf("PIC2 Mask = 0x%04x\n", inb(PIC2_DATA));
109         unmask_lapic_lvt(MSR_LAPIC_LVT_LINT0);
110         printk("Core %d's LINT0: 0x%08x\n", core_id(),
111                apicrget(MSR_LAPIC_LVT_TIMER));
112         enable_irq();
113         while(1);
114
115         return true;
116 }
117
118 #endif // CONFIG_X86
119
120 barrier_t test_cpu_array;
121
122 // TODO: Add assertions, try to do everything from within this same function.
123 bool test_barrier(void)
124 {
125         cprintf("Core 0 initializing barrier\n");
126         init_barrier(&test_cpu_array, num_cores);
127         cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
128         smp_call_function_all(test_barrier_handler, NULL, 0);
129
130         return true;
131 }
132
133 // TODO: Maybe remove all the printing statements and instead use the
134 //       KT_ASSERT_M macro to include a message on assertions.
135 bool test_interrupts_irqsave(void)
136 {
137         int8_t state = 0;
138         printd("Testing Nesting Enabling first, turning ints off:\n");
139         disable_irq();
140         printd("Interrupts are: %x\n", irq_is_enabled());
141         KT_ASSERT(!irq_is_enabled());
142         printd("Enabling IRQSave\n");
143         enable_irqsave(&state);
144         printd("Interrupts are: %x\n", irq_is_enabled());
145         KT_ASSERT(irq_is_enabled());
146         printd("Enabling IRQSave Again\n");
147         enable_irqsave(&state);
148         printd("Interrupts are: %x\n", irq_is_enabled());
149         KT_ASSERT(irq_is_enabled());
150         printd("Disabling IRQSave Once\n");
151         disable_irqsave(&state);
152         printd("Interrupts are: %x\n", irq_is_enabled());
153         KT_ASSERT(irq_is_enabled());
154         printd("Disabling IRQSave Again\n");
155         disable_irqsave(&state);
156         printd("Interrupts are: %x\n", irq_is_enabled());
157         KT_ASSERT(!irq_is_enabled());
158         printd("Done.  Should have been 0, 200, 200, 200, 0\n");
159
160         printd("Testing Nesting Disabling first, turning ints on:\n");
161         state = 0;
162         enable_irq();
163         printd("Interrupts are: %x\n", irq_is_enabled());
164         KT_ASSERT(irq_is_enabled());
165         printd("Disabling IRQSave Once\n");
166         disable_irqsave(&state);
167         printd("Interrupts are: %x\n", irq_is_enabled());
168         KT_ASSERT(!irq_is_enabled());
169         printd("Disabling IRQSave Again\n");
170         disable_irqsave(&state);
171         printd("Interrupts are: %x\n", irq_is_enabled());
172         KT_ASSERT(!irq_is_enabled());
173         printd("Enabling IRQSave Once\n");
174         enable_irqsave(&state);
175         printd("Interrupts are: %x\n", irq_is_enabled());
176         KT_ASSERT(!irq_is_enabled());
177         printd("Enabling IRQSave Again\n");
178         enable_irqsave(&state);
179         printd("Interrupts are: %x\n", irq_is_enabled());
180         KT_ASSERT(irq_is_enabled());
181         printd("Done.  Should have been 200, 0, 0, 0, 200 \n");
182
183         state = 0;
184         disable_irq();
185         printd("Ints are off, enabling then disabling.\n");
186         enable_irqsave(&state);
187         printd("Interrupts are: %x\n", irq_is_enabled());
188         KT_ASSERT(irq_is_enabled());
189         disable_irqsave(&state);
190         printd("Interrupts are: %x\n", irq_is_enabled());
191         KT_ASSERT(!irq_is_enabled());
192         printd("Done.  Should have been 200, 0\n");
193
194         state = 0;
195         enable_irq();
196         printd("Ints are on, enabling then disabling.\n");
197         enable_irqsave(&state);
198         printd("Interrupts are: %x\n", irq_is_enabled());
199         KT_ASSERT(irq_is_enabled());
200         disable_irqsave(&state);
201         printd("Interrupts are: %x\n", irq_is_enabled());
202         KT_ASSERT(irq_is_enabled());
203         printd("Done.  Should have been 200, 200\n");
204
205         state = 0;
206         disable_irq();
207         printd("Ints are off, disabling then enabling.\n");
208         disable_irqsave(&state);
209         printd("Interrupts are: %x\n", irq_is_enabled());
210         KT_ASSERT(!irq_is_enabled());
211         enable_irqsave(&state);
212         printd("Interrupts are: %x\n", irq_is_enabled());
213         KT_ASSERT(!irq_is_enabled());
214         printd("Done.  Should have been 0, 0\n");
215
216         state = 0;
217         enable_irq();
218         printd("Ints are on, disabling then enabling.\n");
219         disable_irqsave(&state);
220         printd("Interrupts are: %x\n", irq_is_enabled());
221         KT_ASSERT(!irq_is_enabled());
222         enable_irqsave(&state);
223         printd("Interrupts are: %x\n", irq_is_enabled());
224         KT_ASSERT(irq_is_enabled());
225         printd("Done.  Should have been 0, 200\n");
226
227         disable_irq();
228         return true;
229 }
230
231 // TODO: Maybe remove PRINT_BITMASK statements and use KT_ASSERT_M instead
232 //       somehow.
233 bool test_bitmasks(void)
234 {
235 #define masksize 67
236         DECL_BITMASK(mask, masksize);
237         CLR_BITMASK(mask, masksize);
238 //      PRINT_BITMASK(mask, masksize);
239         SET_BITMASK_BIT(mask, 0);
240         SET_BITMASK_BIT(mask, 11);
241         SET_BITMASK_BIT(mask, 17);
242         SET_BITMASK_BIT(mask, masksize-1);
243 //      PRINT_BITMASK(mask, masksize);
244         DECL_BITMASK(mask2, masksize);
245         COPY_BITMASK(mask2, mask, masksize);
246 //      printk("copy of original mask, should be the same as the prev\n");
247 //      PRINT_BITMASK(mask2, masksize);
248         CLR_BITMASK_BIT(mask, 11);
249 //      PRINT_BITMASK(mask, masksize);
250         KT_ASSERT_M("Bit 17 should be 1", 1 == GET_BITMASK_BIT(mask, 17));
251         KT_ASSERT_M("Bit 11 should be 0", 0 == GET_BITMASK_BIT(mask, 11));
252         FILL_BITMASK(mask, masksize);
253 //      PRINT_BITMASK(mask, masksize);
254         KT_ASSERT_M("Bitmask should not be clear after calling FILL_BITMASK",
255                     0 == BITMASK_IS_CLEAR(mask,masksize));
256         CLR_BITMASK(mask, masksize);
257 //      PRINT_BITMASK(mask, masksize);
258         KT_ASSERT_M("Bitmask should be clear after calling CLR_BITMASK",
259                     1 == BITMASK_IS_CLEAR(mask,masksize));
260         return true;
261 }
262
263 checklist_t *the_global_list;
264
265 static void test_checklist_handler(struct hw_trapframe *hw_tf, void *data)
266 {
267         udelay(1000000);
268         cprintf("down_checklist(%x,%d)\n", the_global_list, core_id());
269         down_checklist(the_global_list);
270 }
271
272 // TODO: Add assertions
273 bool test_checklists(void)
274 {
275         INIT_CHECKLIST(a_list, MAX_NUM_CORES);
276         the_global_list = &a_list;
277         printk("Checklist Build, mask size: %d\n", sizeof(a_list.mask.bits));
278         printk("mask\n");
279         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
280         SET_BITMASK_BIT(a_list.mask.bits, 11);
281         printk("Set bit 11\n");
282         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
283
284         CLR_BITMASK(a_list.mask.bits, a_list.mask.size);
285         INIT_CHECKLIST_MASK(a_mask, MAX_NUM_CORES);
286         FILL_BITMASK(a_mask.bits, num_cores);
287         //CLR_BITMASK_BIT(a_mask.bits, core_id());
288         //SET_BITMASK_BIT(a_mask.bits, 1);
289         //printk("New mask (1, 17, 25):\n");
290         printk("Created new mask, filled up to num_cores\n");
291         PRINT_BITMASK(a_mask.bits, a_mask.size);
292         printk("committing new mask\n");
293         commit_checklist_wait(&a_list, &a_mask);
294         printk("Old mask (copied onto):\n");
295         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
296         //smp_call_function_single(1, test_checklist_handler, 0, 0);
297
298         smp_call_function_all(test_checklist_handler, NULL, 0);
299
300         printk("Waiting on checklist\n");
301         waiton_checklist(&a_list);
302         printk("Done Waiting!\n");
303
304         return true;
305 }
306
307 atomic_t a, b, c;
308
309 static void test_incrementer_handler(struct hw_trapframe *tf, void *data)
310 {
311         assert(data);
312         atomic_inc(data);
313 }
314
315 static void test_null_handler(struct hw_trapframe *tf, void *data)
316 {
317         asm volatile("nop");
318 }
319
320 // TODO: Add assertions.
321 bool test_smp_call_functions(void)
322 {
323         int i;
324         atomic_init(&a, 0);
325         atomic_init(&b, 0);
326         atomic_init(&c, 0);
327         handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0, *waiter3 = 0,
328                           *waiter4 = 0, *waiter5 = 0;
329         uint8_t me = core_id();
330         printk("\nCore %d: SMP Call Self (nowait):\n", me);
331         printk("---------------------\n");
332         smp_call_function_self(test_hello_world_handler, NULL, 0);
333         printk("\nCore %d: SMP Call Self (wait):\n", me);
334         printk("---------------------\n");
335         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
336         smp_call_wait(waiter0);
337         printk("\nCore %d: SMP Call All (nowait):\n", me);
338         printk("---------------------\n");
339         smp_call_function_all(test_hello_world_handler, NULL, 0);
340         printk("\nCore %d: SMP Call All (wait):\n", me);
341         printk("---------------------\n");
342         smp_call_function_all(test_hello_world_handler, NULL, &waiter0);
343         smp_call_wait(waiter0);
344         printk("\nCore %d: SMP Call All-Else Individually, in order (nowait):\n", me);
345         printk("---------------------\n");
346         for(i = 1; i < num_cores; i++)
347                 smp_call_function_single(i, test_hello_world_handler, NULL, 0);
348         printk("\nCore %d: SMP Call Self (wait):\n", me);
349         printk("---------------------\n");
350         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
351         smp_call_wait(waiter0);
352         printk("\nCore %d: SMP Call All-Else Individually, in order (wait):\n", me);
353         printk("---------------------\n");
354         for(i = 1; i < num_cores; i++)
355         {
356                 smp_call_function_single(i, test_hello_world_handler, NULL, &waiter0);
357                 smp_call_wait(waiter0);
358         }
359         printk("\nTesting to see if any IPI-functions are dropped when not waiting:\n");
360         printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
361         smp_call_function_all(test_incrementer_handler, &a, 0);
362         smp_call_function_all(test_incrementer_handler, &b, 0);
363         smp_call_function_all(test_incrementer_handler, &c, 0);
364         // if i can clobber a previous IPI, the interleaving might do it
365         smp_call_function_single(1 % num_cores, test_incrementer_handler, &a, 0);
366         smp_call_function_single(2 % num_cores, test_incrementer_handler, &b, 0);
367         smp_call_function_single(3 % num_cores, test_incrementer_handler, &c, 0);
368         smp_call_function_single(4 % num_cores, test_incrementer_handler, &a, 0);
369         smp_call_function_single(5 % num_cores, test_incrementer_handler, &b, 0);
370         smp_call_function_single(6 % num_cores, test_incrementer_handler, &c, 0);
371         smp_call_function_all(test_incrementer_handler, &a, 0);
372         smp_call_function_single(3 % num_cores, test_incrementer_handler, &c, 0);
373         smp_call_function_all(test_incrementer_handler, &b, 0);
374         smp_call_function_single(1 % num_cores, test_incrementer_handler, &a, 0);
375         smp_call_function_all(test_incrementer_handler, &c, 0);
376         smp_call_function_single(2 % num_cores, test_incrementer_handler, &b, 0);
377         // wait, so we're sure the others finish before printing.
378         // without this, we could (and did) get 19,18,19, since the B_inc
379         // handler didn't finish yet
380         smp_call_function_self(test_null_handler, NULL, &waiter0);
381         // need to grab all 5 handlers (max), since the code moves to the next free.
382         smp_call_function_self(test_null_handler, NULL, &waiter1);
383         smp_call_function_self(test_null_handler, NULL, &waiter2);
384         smp_call_function_self(test_null_handler, NULL, &waiter3);
385         smp_call_function_self(test_null_handler, NULL, &waiter4);
386         smp_call_wait(waiter0);
387         smp_call_wait(waiter1);
388         smp_call_wait(waiter2);
389         smp_call_wait(waiter3);
390         smp_call_wait(waiter4);
391         printk("A: %d, B: %d, C: %d (should be 19,19,19)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
392         printk("Attempting to deadlock by smp_calling with an outstanding wait:\n");
393         smp_call_function_self(test_null_handler, NULL, &waiter0);
394         printk("Sent one\n");
395         smp_call_function_self(test_null_handler, NULL, &waiter1);
396         printk("Sent two\n");
397         smp_call_wait(waiter0);
398         printk("Wait one\n");
399         smp_call_wait(waiter1);
400         printk("Wait two\n");
401         printk("\tMade it through!\n");
402         printk("Attempting to deadlock by smp_calling more than are available:\n");
403         printk("\tShould see an Insufficient message and a kernel warning.\n");
404         if (smp_call_function_self(test_null_handler, NULL, &waiter0))
405                 printk("\tInsufficient handlers to call function (0)\n");
406         if (smp_call_function_self(test_null_handler, NULL, &waiter1))
407                 printk("\tInsufficient handlers to call function (1)\n");
408         if (smp_call_function_self(test_null_handler, NULL, &waiter2))
409                 printk("\tInsufficient handlers to call function (2)\n");
410         if (smp_call_function_self(test_null_handler, NULL, &waiter3))
411                 printk("\tInsufficient handlers to call function (3)\n");
412         if (smp_call_function_self(test_null_handler, NULL, &waiter4))
413                 printk("\tInsufficient handlers to call function (4)\n");
414         if (smp_call_function_self(test_null_handler, NULL, &waiter5))
415                 printk("\tInsufficient handlers to call function (5)\n");
416         smp_call_wait(waiter0);
417         smp_call_wait(waiter1);
418         smp_call_wait(waiter2);
419         smp_call_wait(waiter3);
420         smp_call_wait(waiter4);
421         smp_call_wait(waiter5);
422         printk("\tMade it through!\n");
423
424         printk("Done\n");
425
426         return true;
427 }
428
429 #ifdef CONFIG_X86
430 // TODO: Fix the KT_ASSERTs
431 bool test_lapic_status_bit(void)
432 {
433         register_irq(I_TESTING, test_incrementer_handler, &a,
434                      MKBUS(BusIPI, 0, 0, 0));
435         #define NUM_IPI 100000
436         atomic_set(&a,0);
437         printk("IPIs received (should be 0): %d\n", a);
438         // KT_ASSERT_M("IPIs received should be 0", (0 == a));
439         for(int i = 0; i < NUM_IPI; i++) {
440                 send_ipi(7, I_TESTING);
441         }
442         // need to wait a bit to let those IPIs get there
443         udelay(5000000);
444         printk("IPIs received (should be %d): %d\n", a, NUM_IPI);
445         // KT_ASSERT_M("IPIs received should be 100000", (NUM_IPI == a));
446         // hopefully that handler never fires again.  leaving it registered for now.
447
448         return true;
449 }
450 #endif // CONFIG_X86
451
452 /************************************************************/
453 /* ISR Handler Functions */
454
455 void test_hello_world_handler(struct hw_trapframe *hw_tf, void *data)
456 {
457         int trapno;
458         #if defined(CONFIG_X86)
459         trapno = hw_tf->tf_trapno;
460         #else
461         trapno = 0;
462         #endif
463
464         cprintf("Incoming IRQ, ISR: %d on core %d with tf at %p\n",
465                 trapno, core_id(), hw_tf);
466 }
467
468 void test_barrier_handler(struct hw_trapframe *hw_tf, void *data)
469 {
470         cprintf("Round 1: Core %d\n", core_id());
471         waiton_barrier(&test_cpu_array);
472         waiton_barrier(&test_cpu_array);
473         waiton_barrier(&test_cpu_array);
474         waiton_barrier(&test_cpu_array);
475         waiton_barrier(&test_cpu_array);
476         waiton_barrier(&test_cpu_array);
477         cprintf("Round 2: Core %d\n", core_id());
478         waiton_barrier(&test_cpu_array);
479         cprintf("Round 3: Core %d\n", core_id());
480         // uncomment to see it fucked up
481         //cprintf("Round 4: Core %d\n", core_id());
482 }
483
484 static void test_waiting_handler(struct hw_trapframe *hw_tf, void *data)
485 {
486         atomic_dec(data);
487 }
488
489 #ifdef CONFIG_X86
490 // TODO: Add assertions.
491 bool test_pit(void)
492 {
493         cprintf("Starting test for PIT now (10s)\n");
494         udelay_pit(10000000);
495         cprintf("End now\n");
496         cprintf("Starting test for TSC (if stable) now (10s)\n");
497         udelay(10000000);
498         cprintf("End now\n");
499
500         cprintf("Starting test for LAPIC (if stable) now (10s)\n");
501         enable_irq();
502         lapic_set_timer(10000000, FALSE);
503
504         atomic_t waiting;
505         atomic_init(&waiting, 1);
506         register_irq(I_TESTING, test_waiting_handler, &waiting,
507                      MKBUS(BusIPI, 0, 0, 0));
508         while(atomic_read(&waiting))
509                 cpu_relax();
510         cprintf("End now\n");
511
512         return true;
513 }
514
515 // TODO: Add assertions.
516 bool test_circ_buffer(void)
517 {
518         int arr[5] = {0, 1, 2, 3, 4};
519
520         for (int i = 0; i < 5; i++) {
521                 FOR_CIRC_BUFFER(i, 5, j)
522                         printk("Starting with current = %d, each value = %d\n", i, j);
523         }
524
525         return true;
526 }
527
528 static void test_km_handler(uint32_t srcid, long a0, long a1, long a2)
529 {
530         printk("Received KM on core %d from core %d: arg0= %p, arg1 = %p, "
531                "arg2 = %p\n", core_id(), srcid, a0, a1, a2);
532         return;
533 }
534
535 // TODO: Add assertions. Try to do everything inside this function.
536 bool test_kernel_messages(void)
537 {
538         printk("Testing Kernel Messages\n");
539         /* Testing sending multiples, sending different types, alternating, and
540          * precendence (the immediates should trump the others) */
541         printk("sending 5 IMMED to core 1, sending (#,deadbeef,0)\n");
542         for (int i = 0; i < 5; i++)
543                 send_kernel_message(1, test_km_handler, (long)i, 0xdeadbeef, 0,
544                                     KMSG_IMMEDIATE);
545         udelay(5000000);
546         printk("sending 5 routine to core 1, sending (#,cafebabe,0)\n");
547         for (int i = 0; i < 5; i++)
548                 send_kernel_message(1, test_km_handler, (long)i, 0xcafebabe, 0,
549                                     KMSG_ROUTINE);
550         udelay(5000000);
551         printk("sending 10 routine and 3 immediate to core 2\n");
552         for (int i = 0; i < 10; i++)
553                 send_kernel_message(2, test_km_handler, (long)i, 0xcafebabe, 0,
554                                     KMSG_ROUTINE);
555         for (int i = 0; i < 3; i++)
556                 send_kernel_message(2, test_km_handler, (long)i, 0xdeadbeef, 0,
557                                     KMSG_IMMEDIATE);
558         udelay(5000000);
559         printk("sending 5 ea alternating to core 2\n");
560         for (int i = 0; i < 5; i++) {
561                 send_kernel_message(2, test_km_handler, (long)i, 0xdeadbeef, 0,
562                                     KMSG_IMMEDIATE);
563                 send_kernel_message(2, test_km_handler, (long)i, 0xcafebabe, 0,
564                                     KMSG_ROUTINE);
565         }
566         udelay(5000000);
567
568         return true;
569 }
570 #endif // CONFIG_X86
571 static void test_single_cache(int iters, size_t size, int align, int flags,
572                               void (*ctor)(void *, size_t),
573                               void (*dtor)(void *, size_t))
574 {
575         struct kmem_cache *test_cache;
576         void *objects[iters];
577         test_cache = kmem_cache_create("test_cache", size, align, flags,
578                                        NULL, ctor, dtor);
579         printk("Testing Kmem Cache:\n");
580         print_kmem_cache(test_cache);
581         for (int i = 0; i < iters; i++) {
582                 objects[i] = kmem_cache_alloc(test_cache, 0);
583                 printk("Buffer %d addr = %p\n", i, objects[i]);
584         }
585         for (int i = 0; i < iters; i++) {
586                 kmem_cache_free(test_cache, objects[i]);
587         }
588         kmem_cache_destroy(test_cache);
589         printk("\n\n\n\n");
590 }
591
592 void a_ctor(void *buf, size_t size)
593 {
594         printk("constructin tests\n");
595 }
596 void a_dtor(void *buf, size_t size)
597 {
598         printk("destructin tests\n");
599 }
600
601 // TODO: Make test_single_cache return something, and then add assertions here.
602 bool test_slab(void)
603 {
604         test_single_cache(10, 128, 512, 0, 0, 0);
605         test_single_cache(10, 128, 4, 0, a_ctor, a_dtor);
606         test_single_cache(10, 1024, 16, 0, 0, 0);
607
608         return true;
609 }
610
611 // TODO: Add assertions.
612 bool test_kmalloc(void)
613 {
614         printk("Testing Kmalloc\n");
615         void *bufs[NUM_KMALLOC_CACHES + 1];
616         size_t size;
617         for (int i = 0; i < NUM_KMALLOC_CACHES + 1; i++){
618                 size = (KMALLOC_SMALLEST << i) - sizeof(struct kmalloc_tag);
619                 bufs[i] = kmalloc(size, 0);
620                 printk("Size %d, Addr = %p\n", size, bufs[i]);
621         }
622         for (int i = 0; i < NUM_KMALLOC_CACHES; i++) {
623                 printk("Freeing buffer %d\n", i);
624                 kfree(bufs[i]);
625         }
626         printk("Testing a large kmalloc\n");
627         size = (KMALLOC_LARGEST << 2);
628         bufs[0] = kmalloc(size, 0);
629         printk("Size %d, Addr = %p\n", size, bufs[0]);
630         kfree(bufs[0]);
631
632         return true;
633 }
634
635 static size_t test_hash_fn_col(void *k)
636 {
637         return (size_t)k % 2; // collisions in slots 0 and 1
638 }
639
640 bool test_hashtable(void)
641 {
642         struct test {int x; int y;};
643         struct test tstruct[10];
644
645         struct hashtable *h;
646         uintptr_t k = 5;
647         struct test *v = &tstruct[0];
648
649         h = create_hashtable(32, __generic_hash, __generic_eq);
650
651         // test inserting one item, then finding it again
652         KT_ASSERT_M("It should be possible to insert items to a hashtable",
653                     hashtable_insert(h, (void*)k, v));
654         v = NULL;
655         KT_ASSERT_M("It should be possible to find inserted stuff in a hashtable",
656                     (v = hashtable_search(h, (void*)k)));
657
658         KT_ASSERT_M("The extracted element should be the same we inserted",
659                     (v == &tstruct[0]));
660
661         v = NULL;
662
663         KT_ASSERT_M("It should be possible to remove an existing element",
664                     (v = hashtable_remove(h, (void*)k)));
665
666         KT_ASSERT_M("An element should not remain in a hashtable after deletion",
667                     !(v = hashtable_search(h, (void*)k)));
668
669         /* Testing a bunch of items, insert, search, and removal */
670         for (int i = 0; i < 10; i++) {
671                 k = i; // vary the key, we don't do KEY collisions
672                 KT_ASSERT_M("It should be possible to insert elements to a hashtable",
673                             (hashtable_insert(h, (void*)k, &tstruct[i])));
674         }
675         // read out the 10 items
676         for (int i = 0; i < 10; i++) {
677                 k = i;
678                 KT_ASSERT_M("It should be possible to find inserted stuff in a hashtable",
679                             (v = hashtable_search(h, (void*)k)));
680                 KT_ASSERT_M("The extracted element should be the same we inserted",
681                             (v == &tstruct[i]));
682         }
683
684         KT_ASSERT_M("The total count of number of elements should be 10",
685                     (10 == hashtable_count(h)));
686
687         // remove the 10 items
688         for (int i = 0; i < 10; i++) {
689                 k = i;
690                 KT_ASSERT_M("It should be possible to remove an existing element",
691                             (v = hashtable_remove(h, (void*)k)));
692
693         }
694         // make sure they are all gone
695         for (int i = 0; i < 10; i++) {
696                 k = i;
697                 KT_ASSERT_M("An element should not remain in a hashtable after deletion",
698                             !(v = hashtable_search(h, (void*)k)));
699         }
700
701         KT_ASSERT_M("The hashtable should be empty",
702                     (0 == hashtable_count(h)));
703
704         hashtable_destroy(h);
705
706         // same test of a bunch of items, but with collisions.
707         /* Testing a bunch of items with collisions, etc. */
708         h = create_hashtable(32, test_hash_fn_col, __generic_eq);
709         // insert 10 items
710         for (int i = 0; i < 10; i++) {
711                 k = i; // vary the key, we don't do KEY collisions
712
713                 KT_ASSERT_M("It should be possible to insert elements to a hashtable",
714                             (hashtable_insert(h, (void*)k, &tstruct[i])));
715         }
716         // read out the 10 items
717         for (int i = 0; i < 10; i++) {
718                 k = i;
719                 KT_ASSERT_M("It should be possible to find inserted stuff in a hashtable",
720                             (v = hashtable_search(h, (void*)k)));
721                 KT_ASSERT_M("The extracted element should be the same we inserted",
722                             (v == &tstruct[i]));
723         }
724
725         KT_ASSERT_M("The total count of number of elements should be 10",
726                     (10 == hashtable_count(h)));
727
728         // remove the 10 items
729         for (int i = 0; i < 10; i++) {
730                 k = i;
731                 KT_ASSERT_M("It should be possible to remove an existing element",
732                             (v = hashtable_remove(h, (void*)k)));
733         }
734         // make sure they are all gone
735         for (int i = 0; i < 10; i++) {
736                 k = i;
737
738                 KT_ASSERT_M("An element should not remain in a hashtable after deletion",
739                             !(v = hashtable_search(h, (void*)k)));
740         }
741
742         KT_ASSERT_M("The hashtable should be empty",
743                     (0 == hashtable_count(h)));
744
745         hashtable_destroy(h);
746
747         return true;
748 }
749
750 bool test_circular_buffer(void)
751 {
752         static const size_t cbsize = 4096;
753         struct circular_buffer cb;
754         char *bigbuf;
755         size_t csize, off, cnum, mxsize;
756         char buf[256];
757
758         KT_ASSERT_M("Failed to build the circular buffer",
759                                 circular_buffer_init(&cb, cbsize, NULL));
760
761         for (size_t i = 0; i < 8 * cbsize; i++) {
762                 size_t len = snprintf(buf, sizeof(buf), "%lu\n", i);
763
764                 KT_ASSERT_M("Circular buffer write failed",
765                                         circular_buffer_write(&cb, buf, len) == len);
766         }
767         cnum = off = 0;
768         while ((csize = circular_buffer_read(&cb, buf, sizeof(buf), off)) != 0) {
769                 char *top = buf + csize;
770                 char *ptr = buf;
771                 char *pnl;
772
773                 while ((pnl = memchr(ptr, '\n', top - ptr)) != NULL) {
774                         size_t num;
775
776                         *pnl = 0;
777                         num = strtoul(ptr, NULL, 10);
778                         KT_ASSERT_M("Numbers should be ascending", num >= cnum);
779                         cnum = num;
780                         ptr = pnl + 1;
781                 }
782
783                 off += ptr - buf;
784         }
785
786         for (size_t i = 0; i < (cbsize / sizeof(buf) + 1); i++) {
787                 memset(buf, (int) i, sizeof(buf));
788
789                 KT_ASSERT_M("Circular buffer write failed",
790                                         circular_buffer_write(&cb, buf,
791                                                                                   sizeof(buf)) == sizeof(buf));
792         }
793         cnum = off = 0;
794         while ((csize = circular_buffer_read(&cb, buf, sizeof(buf), off)) != 0) {
795                 size_t num = buf[0];
796
797                 KT_ASSERT_M("Invalid record read size", csize == sizeof(buf));
798
799                 if (off != 0)
800                         KT_ASSERT_M("Invalid record sequence number",
801                                                 num == ((cnum + 1) % 256));
802                 cnum = num;
803                 off += csize;
804         }
805
806         bigbuf = kzmalloc(cbsize, MEM_WAIT);
807         KT_ASSERT(bigbuf != NULL);
808
809         mxsize = circular_buffer_max_write_size(&cb);
810         KT_ASSERT_M("Circular buffer max write failed",
811                                 circular_buffer_write(&cb, bigbuf, mxsize) == mxsize);
812
813         memset(bigbuf, 17, cbsize);
814         csize = circular_buffer_read(&cb, bigbuf, mxsize, 0);
815         KT_ASSERT_M("Invalid max record read size", csize == mxsize);
816
817         for (size_t i = 0; i < csize; i++)
818                 KT_ASSERT_M("Invalid max record value", bigbuf[i] == 0);
819
820         kfree(bigbuf);
821
822         circular_buffer_destroy(&cb);
823
824         return TRUE;
825 }
826
827 /* Ghetto test, only tests one prod or consumer at a time */
828 // TODO: Un-guetto test, add assertions.
829 bool test_bcq(void)
830 {
831         /* Tests a basic struct */
832         struct my_struct {
833                 int x;
834                 int y;
835         };
836         struct my_struct in_struct, out_struct;
837
838         DEFINE_BCQ_TYPES(test, struct my_struct, 16);
839         struct test_bcq t_bcq;
840         bcq_init(&t_bcq, struct my_struct, 16);
841
842         in_struct.x = 4;
843         in_struct.y = 5;
844         out_struct.x = 1;
845         out_struct.y = 2;
846
847         bcq_enqueue(&t_bcq, &in_struct, 16, 5);
848         bcq_dequeue(&t_bcq, &out_struct, 16);
849         printk("out x %d. out y %d\n", out_struct.x, out_struct.y);
850
851         /* Tests the BCQ a bit more, esp with overflow */
852         #define NR_ELEM_A_BCQ 8 /* NOTE: this must be a power of 2! */
853         DEFINE_BCQ_TYPES(my, int, NR_ELEM_A_BCQ);
854         struct my_bcq a_bcq;
855         bcq_init(&a_bcq, int, NR_ELEM_A_BCQ);
856
857         int y = 2;
858         int output[100];
859         int retval[100];
860
861         /* Helpful debugger */
862         void print_a_bcq(struct my_bcq *bcq)
863         {
864                 printk("A BCQ (made of ints): %p\n", bcq);
865                 printk("\tprod_idx: %p\n", bcq->hdr.prod_idx);
866                 printk("\tcons_pub_idx: %p\n", bcq->hdr.cons_pub_idx);
867                 printk("\tcons_pvt_idx: %p\n", bcq->hdr.cons_pvt_idx);
868                 for (int i = 0; i < NR_ELEM_A_BCQ; i++) {
869                         printk("Element %d, rdy_for_cons: %02p\n", i,
870                                bcq->wraps[i].rdy_for_cons);
871                 }
872         }
873
874         /* Put in more than it can take */
875         for (int i = 0; i < 15; i++) {
876                 y = i;
877                 retval[i] = bcq_enqueue(&a_bcq, &y, NR_ELEM_A_BCQ, 10);
878                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
879         }
880         //print_a_bcq(&a_bcq);
881
882         /* Try to dequeue more than we put in */
883         for (int i = 0; i < 15; i++) {
884                 retval[i] = bcq_dequeue(&a_bcq, &output[i], NR_ELEM_A_BCQ);
885                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
886         }
887         //print_a_bcq(&a_bcq);
888
889         /* Put in some it should be able to take */
890         for (int i = 0; i < 3; i++) {
891                 y = i;
892                 retval[i] = bcq_enqueue(&a_bcq, &y, NR_ELEM_A_BCQ, 10);
893                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
894         }
895
896         /* Take those, and then a couple extra */
897         for (int i = 0; i < 5; i++) {
898                 retval[i] = bcq_dequeue(&a_bcq, &output[i], NR_ELEM_A_BCQ);
899                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
900         }
901
902         /* Try some one-for-one */
903         for (int i = 0; i < 5; i++) {
904                 y = i;
905                 retval[i] = bcq_enqueue(&a_bcq, &y, NR_ELEM_A_BCQ, 10);
906                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
907                 retval[i] = bcq_dequeue(&a_bcq, &output[i], NR_ELEM_A_BCQ);
908                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
909         }
910
911         return true;
912 }
913
914 /* Test a simple concurrent send and receive (one prod, one cons).  We spawn a
915  * process that will go into _M mode on another core, and we'll do the test from
916  * an alarm handler run on our core.  When we start up the process, we won't
917  * return so we need to defer the work with an alarm. */
918 // TODO: Check if we can add more assertions.
919 bool test_ucq(void)
920 {
921         struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
922         struct alarm_waiter *waiter = kmalloc(sizeof(struct alarm_waiter), 0);
923
924         /* Alarm handler: what we want to do after the process is up */
925         void send_msgs(struct alarm_waiter *waiter)
926         {
927                 struct timer_chain *tchain;
928                 struct proc *p = waiter->data;
929                 uintptr_t old_proc;
930                 struct ucq *ucq = (struct ucq*)USTACKTOP;
931                 struct event_msg msg;
932
933                 printk("Running the alarm handler!\n");
934                 printk("NR msg per page: %d\n", NR_MSG_PER_PAGE);
935                 /* might not be mmaped yet, if not, abort.  We used to user_mem_check,
936                  * but now we just touch it and PF. */
937                 char touch = *(char*)ucq;
938                 asm volatile ("" : : "r"(touch));
939                 /* load their address space */
940                 old_proc = switch_to(p);
941                 /* So it's mmaped, see if it is ready (note that this is dangerous) */
942                 if (!ucq->ucq_ready) {
943                         printk("Not ready yet\n");
944                         switch_back(p, old_proc);
945                         goto abort;
946                 }
947                 /* So it's ready, time to finally do the tests... */
948                 printk("[kernel] Finally starting the tests... \n");
949                 /* 1: Send a simple message */
950                 printk("[kernel] #1 Sending simple message (7, deadbeef)\n");
951                 msg.ev_type = 7;
952                 msg.ev_arg2 = 0xdeadbeef;
953                 send_ucq_msg(ucq, p, &msg);
954                 printk("nr_pages: %d\n", atomic_read(&ucq->nr_extra_pgs));
955                 /* 2: Send a bunch.  In a VM, this causes one swap, and then a bunch of
956                  * mmaps. */
957                 printk("[kernel] #2 \n");
958                 for (int i = 0; i < 5000; i++) {
959                         msg.ev_type = i;
960                         send_ucq_msg(ucq, p, &msg);
961                 }
962                 printk("nr_pages: %d\n", atomic_read(&ucq->nr_extra_pgs));
963                 printk("[kernel] #3 \n");
964                 /* 3: make sure we chained pages (assuming 1k is enough) */
965                 for (int i = 0; i < 1000; i++) {
966                         msg.ev_type = i;
967                         send_ucq_msg(ucq, p, &msg);
968                 }
969                 printk("nr_pages: %d\n", atomic_read(&ucq->nr_extra_pgs));
970                 /* other things we could do:
971                  *  - concurrent producers / consumers...  ugh.
972                  *  - would require a kmsg to another core, instead of a local alarm
973                  */
974                 /* done, switch back and free things */
975                 switch_back(p, old_proc);
976                 proc_decref(p);
977                 kfree(waiter); /* since it was kmalloc()d */
978                 return;
979         abort:
980                 tchain = &per_cpu_info[core_id()].tchain;
981                 /* Set to run again */
982                 set_awaiter_rel(waiter, 1000000);
983                 set_alarm(tchain, waiter);
984         }
985         /* Set up a handler to run the real part of the test */
986         init_awaiter(waiter, send_msgs);
987         set_awaiter_rel(waiter, 1000000);       /* 1s should be long enough */
988         set_alarm(tchain, waiter);
989         /* Just spawn the program */
990         struct file *program;
991         program = do_file_open("/bin/ucq", O_READ, 0);
992
993         KT_ASSERT_M("We should be able to find /bin/ucq",
994                     program);
995
996         struct proc *p = proc_create(program, NULL, NULL);
997         proc_wakeup(p);
998         /* instead of getting rid of the reference created in proc_create, we'll put
999          * it in the awaiter */
1000         waiter->data = p;
1001         kref_put(&program->f_kref);
1002         /* Should never return from schedule (env_pop in there) also note you may
1003          * not get the process you created, in the event there are others floating
1004          * around that are runnable */
1005         run_scheduler();
1006         smp_idle();
1007
1008         KT_ASSERT_M("We should never return from schedule",
1009                     false);
1010
1011         return true;
1012 }
1013
1014 /* rudimentary tests.  does the basics, create, merge, split, etc.  Feel free to
1015  * add more, esp for the error conditions and finding free slots.  This is also
1016  * a bit lazy with setting the caller's fields (perm, flags, etc). */
1017 // TODO: See if we could add more assertions, try to add more descriptive
1018 //       messages to assertions.
1019 bool test_vm_regions(void)
1020 {
1021         #define MAX_VMR_TESTS 10
1022         struct proc pr, *p = &pr;       /* too lazy to even create one */
1023         int n = 0;
1024         TAILQ_INIT(&p->vm_regions);
1025
1026         struct vmr_summary {
1027                 uintptr_t base;
1028                 uintptr_t end;
1029         };
1030         int check_vmrs(struct proc *p, struct vmr_summary *results, int len, int n)
1031         {
1032                 int count = 0;
1033                 struct vm_region *vmr;
1034                 TAILQ_FOREACH(vmr, &p->vm_regions, vm_link) {
1035                         if (count >= len) {
1036                                 printk("More vm_regions than expected\n");
1037                                 break;
1038                         }
1039                         if ((vmr->vm_base != results[count].base) ||
1040                             (vmr->vm_end != results[count].end)) {
1041                                 printk("VM test case %d failed!\n", n);
1042                                 print_vmrs(p);
1043                                 return -1;
1044                         }
1045                         count++;
1046                 }
1047                 return count;
1048         }
1049         struct vm_region *vmrs[MAX_VMR_TESTS];
1050         struct vmr_summary results[MAX_VMR_TESTS];
1051
1052         memset(results, 0, sizeof(results));
1053         /* Make one */
1054         vmrs[0] = create_vmr(p, 0x2000, 0x1000);
1055         results[0].base = 0x2000;
1056         results[0].end = 0x3000;
1057         check_vmrs(p, results, 1, n++);
1058         /* Grow it */
1059         grow_vmr(vmrs[0], 0x4000);
1060         results[0].base = 0x2000;
1061         results[0].end = 0x4000;
1062         check_vmrs(p, results, 1, n++);
1063         /* Grow it poorly */
1064         KT_ASSERT_M("It should pass bad grow test",
1065                     (-1 == grow_vmr(vmrs[0], 0x3000)));
1066         check_vmrs(p, results, 1, n++);
1067         /* Make another right next to it */
1068         vmrs[1] = create_vmr(p, 0x4000, 0x1000);
1069         results[1].base = 0x4000;
1070         results[1].end = 0x5000;
1071         check_vmrs(p, results, 2, n++);
1072         /* try to grow through it */
1073         KT_ASSERT_M("It should pass bad grow test",
1074                     (-1 == grow_vmr(vmrs[0], 0x5000)));
1075         check_vmrs(p, results, 2, n++);
1076         /* Merge them */
1077         merge_vmr(vmrs[0], vmrs[1]);
1078         results[0].end = 0x5000;
1079         results[1].base = 0;
1080         results[1].end = 0;
1081         check_vmrs(p, results, 1, n++);
1082         vmrs[1]= create_vmr(p, 0x6000, 0x4000);
1083         results[1].base = 0x6000;
1084         results[1].end = 0xa000;
1085         check_vmrs(p, results, 2, n++);
1086         /* try to merge unmergables (just testing ranges) */
1087         KT_ASSERT_M("It should pass bad merge test",
1088                     (-1 == merge_vmr(vmrs[0], vmrs[1])));
1089         check_vmrs(p, results, 2, n++);
1090         vmrs[2] = split_vmr(vmrs[1], 0x8000);
1091         results[1].end = 0x8000;
1092         results[2].base = 0x8000;
1093         results[2].end = 0xa000;
1094         check_vmrs(p, results, 3, n++);
1095         /* destroy one */
1096         destroy_vmr(vmrs[1]);
1097         results[1].base = 0x8000;
1098         results[1].end = 0xa000;
1099         check_vmrs(p, results, 2, n++);
1100         /* shrink */
1101         shrink_vmr(vmrs[2], 0x9000);
1102         results[1].base = 0x8000;
1103         results[1].end = 0x9000;
1104         check_vmrs(p, results, 2, n++); /* 10 */
1105         KT_ASSERT_M("We should be able to find the right vmr",
1106                     (vmrs[2] == find_vmr(p, 0x8500)));
1107         KT_ASSERT_M("We should be able to find the right vmr",
1108                     (vmrs[2] == find_first_vmr(p, 0x8500)));
1109         KT_ASSERT_M("We should be able to find the right vmr",
1110                     (vmrs[2] == find_first_vmr(p, 0x7500)));
1111         KT_ASSERT_M("We shouldn't be able to find a vmr",
1112                     !(find_first_vmr(p, 0x9500)));
1113         /* grow up to another */
1114         grow_vmr(vmrs[0], 0x8000);
1115         results[0].end = 0x8000;
1116         check_vmrs(p, results, 2, n++);
1117         vmrs[0]->vm_prot = 88;
1118         vmrs[2]->vm_prot = 77;
1119         /* should be unmergeable due to perms */
1120         KT_ASSERT_M("It should pass bad merge test",
1121                     -1 == merge_vmr(vmrs[0], vmrs[2]));
1122         check_vmrs(p, results, 2, n++);
1123         /* should merge now */
1124         vmrs[2]->vm_prot = 88;
1125         merge_vmr(vmrs[0], vmrs[2]);
1126         results[0].end = 0x9000;
1127         check_vmrs(p, results, 1, n++);
1128         destroy_vmr(vmrs[0]);
1129         check_vmrs(p, results, 0, n++);
1130         /* Check the automerge function */
1131         vmrs[0] = create_vmr(p, 0x2000, 0x1000);
1132         vmrs[1] = create_vmr(p, 0x3000, 0x1000);
1133         vmrs[2] = create_vmr(p, 0x4000, 0x1000);
1134         for (int i = 0; i < 3; i++) {
1135                 vmrs[i]->vm_prot = PROT_READ;
1136                 vmrs[i]->vm_flags = 0;
1137                 vmrs[i]->vm_file = 0; /* would like to test this, it's a pain for now */
1138         }
1139         vmrs[0] = merge_me(vmrs[1]);
1140         results[0].base = 0x2000;
1141         results[0].end = 0x5000;
1142         check_vmrs(p, results, 1, n++);
1143         destroy_vmr(vmrs[0]);
1144         check_vmrs(p, results, 0, n++);
1145         /* Check unfixed creation requests */
1146         vmrs[0] = create_vmr(p, 0x0000, 0x1000);
1147         vmrs[1] = create_vmr(p, 0x0000, 0x1000);
1148         vmrs[2] = create_vmr(p, 0x0000, 0x1000);
1149         results[0].base = 0x0000;
1150         results[0].end  = 0x1000;
1151         results[1].base = 0x1000;
1152         results[1].end  = 0x2000;
1153         results[2].base = 0x2000;
1154         results[2].end  = 0x3000;
1155         check_vmrs(p, results, 3, n++);
1156
1157         return true;
1158 }
1159
1160 bool test_radix_tree(void)
1161 {
1162         struct radix_tree real_tree = RADIX_INITIALIZER;
1163         struct radix_tree *tree = &real_tree;
1164         void *retval;
1165
1166         KT_ASSERT_M("It should be possible to insert at 0",
1167                     !radix_insert(tree, 0, (void*)0xdeadbeef, 0));
1168         radix_delete(tree, 0);
1169         KT_ASSERT_M("It should be possible to re-insert at 0",
1170                     !radix_insert(tree, 0, (void*)0xdeadbeef, 0));
1171
1172         KT_ASSERT_M("It should be possible to insert first",
1173                     !radix_insert(tree, 3, (void*)0xdeadbeef, 0));
1174         radix_insert(tree, 4, (void*)0x04040404, 0);
1175         KT_ASSERT((void*)0xdeadbeef == radix_lookup(tree, 3));
1176         for (int i = 5; i < 100; i++)
1177                 if ((retval = radix_lookup(tree, i))) {
1178                         printk("Extra item %p at slot %d in tree %p\n", retval, i,
1179                                tree);
1180                         print_radix_tree(tree);
1181                         monitor(0);
1182                 }
1183         KT_ASSERT_M("It should be possible to insert a two-tier",
1184                     !radix_insert(tree, 65, (void*)0xcafebabe, 0));
1185         KT_ASSERT_M("It should not be possible to reinsert",
1186                     radix_insert(tree, 4, (void*)0x03030303, 0));
1187         KT_ASSERT_M("It should be possible to insert a two-tier boundary",
1188                     !radix_insert(tree, 4095, (void*)0x4095, 0));
1189         KT_ASSERT_M("It should be possible to insert a three-tier",
1190                     !radix_insert(tree, 4096, (void*)0x4096, 0));
1191         //print_radix_tree(tree);
1192         radix_delete(tree, 65);
1193         radix_delete(tree, 3);
1194         radix_delete(tree, 4);
1195         radix_delete(tree, 4095);
1196         radix_delete(tree, 4096);
1197         //print_radix_tree(tree);
1198
1199         return true;
1200 }
1201
1202 /* Assorted FS tests, which were hanging around in init.c */
1203 // TODO: remove all the print statements and try to convert most into assertions
1204 bool test_random_fs(void)
1205 {
1206         int retval = do_symlink("/dir1/sym", "/bin/hello", S_IRWXU);
1207         KT_ASSERT_M("symlink1 should be created successfully",
1208                     (!retval));
1209         retval = do_symlink("/symdir", "/dir1/dir1-1", S_IRWXU);
1210         KT_ASSERT_M("symlink1 should be created successfully",
1211                     (!retval));
1212         retval = do_symlink("/dir1/test.txt", "/dir2/test2.txt", S_IRWXU);
1213         KT_ASSERT_M("symlink2 should be created successfully",
1214                     (!retval));
1215         retval = do_symlink("/dir1/dir1-1/up", "../../", S_IRWXU);
1216         KT_ASSERT_M("symlink3 should be created successfully",
1217                     (!retval));
1218         retval = do_symlink("/bin/hello-sym", "hello", S_IRWXU);
1219         KT_ASSERT_M("symlink4 should be created successfully",
1220                     (!retval));
1221
1222         struct dentry *dentry;
1223         struct nameidata nd_r = {0}, *nd = &nd_r;
1224         retval = path_lookup("/dir1/sym", 0, nd);
1225         KT_ASSERT_M("symlink lookup should work for an existing symlink",
1226                     (!retval));
1227         char *symname = nd->dentry->d_inode->i_op->readlink(nd->dentry);
1228         printk("Pathlookup got %s (sym)\n", nd->dentry->d_name.name);
1229         if (!symname)
1230                 printk("symlink reading failed\n");
1231         else
1232                 printk("Symname: %s (/bin/hello)\n", symname);
1233         path_release(nd);
1234         /* try with follow */
1235         memset(nd, 0, sizeof(struct nameidata));
1236         retval = path_lookup("/dir1/sym", LOOKUP_FOLLOW, nd);
1237
1238         KT_ASSERT_M("symlink lookup should work for an existing symlink",
1239                     (!retval));
1240         printk("Pathlookup got %s (hello)\n", nd->dentry->d_name.name);
1241         path_release(nd);
1242
1243         /* try with a directory */
1244         memset(nd, 0, sizeof(struct nameidata));
1245         retval = path_lookup("/symdir/f1-1.txt", 0, nd);
1246         KT_ASSERT_M("symlink lookup should work for an existing symlink",
1247                     (!retval));
1248         printk("Pathlookup got %s (f1-1.txt)\n", nd->dentry->d_name.name);
1249         path_release(nd);
1250
1251         /* try with a rel path */
1252         printk("Try with a rel path\n");
1253         memset(nd, 0, sizeof(struct nameidata));
1254         retval = path_lookup("/symdir/up/hello.txt", 0, nd);
1255         KT_ASSERT_M("symlink lookup should work for an existing symlink",
1256                     (!retval));
1257         printk("Pathlookup got %s (hello.txt)\n", nd->dentry->d_name.name);
1258         path_release(nd);
1259
1260         printk("Try for an ELOOP\n");
1261         memset(nd, 0, sizeof(struct nameidata));
1262         retval = path_lookup("/symdir/up/symdir/up/symdir/up/symdir/up/hello.txt", 0, nd);
1263         KT_ASSERT_M("symlink lookup should fail for a non existing symlink",
1264                     (retval));
1265         path_release(nd);
1266
1267         return true;
1268 }
1269
1270 /* Kernel message to restart our kthread */
1271 static void __test_up_sem(uint32_t srcid, long a0, long a1, long a2)
1272 {
1273         struct semaphore *sem = (struct semaphore*)a0;
1274         printk("[kmsg] Upping the sem to start the kthread, stacktop is %p\n",
1275                    get_stack_top());
1276         if (!sem_up(sem)) {
1277                 printk("[kmsg] Crap, the sem didn't have a kthread waiting!\n");
1278                 return;
1279         }
1280         printk("Kthread will restart when we handle the __launch RKM\n");
1281 }
1282
1283 /* simple test - start one, do something else, and resume it.  For lack of a
1284  * better infrastructure, we send ourselves a kmsg to run the kthread, which
1285  * we'll handle in smp_idle (which you may have to manually call).  Note this
1286  * doesn't test things like memory being leaked, or dealing with processes. */
1287 // TODO: Add assertions.
1288 bool test_kthreads(void)
1289 {
1290         struct semaphore sem = SEMAPHORE_INITIALIZER(sem, 1);
1291         printk("We're a kthread!  Stacktop is %p.  Testing suspend, etc...\n",
1292                get_stack_top());
1293         /* So we have something that will wake us up.  Routine messages won't get
1294          * serviced in the kernel right away. */
1295         send_kernel_message(core_id(), __test_up_sem, (long)&sem, 0, 0,
1296                             KMSG_ROUTINE);
1297         /* Actually block (or try to) */
1298         /* This one shouldn't block - but will test the unwind (if 1 above) */
1299         printk("About to sleep, but should unwind (signal beat us)\n");
1300         sem_down(&sem);
1301         /* This one is for real, yo.  Run and tell that. */
1302         printk("About to sleep for real\n");
1303         sem_down(&sem);
1304         printk("Kthread restarted!, Stacktop is %p.\n", get_stack_top());
1305
1306         return true;
1307 }
1308
1309 /* Second player's kmsg */
1310 static void __test_kref_2(uint32_t srcid, long a0, long a1, long a2)
1311 {
1312         struct kref *kref = (struct kref*)a0;
1313         bool *done = (bool*)a1;
1314         enable_irq();
1315         for (int i = 0; i < 10000000; i++) {
1316                 kref_get(kref, 1);
1317                 set_core_timer(1, TRUE);
1318                 udelay(2);
1319                 kref_put(kref);
1320         }
1321         *done = TRUE;
1322 }
1323
1324 /* Runs a simple test between core 0 (caller) and core 2 */
1325 // TODO: I believe we need more assertions.
1326 bool test_kref(void)
1327 {
1328         struct kref local_kref;
1329         bool done = FALSE;
1330
1331         kref_init(&local_kref, fake_release, 1);
1332         send_kernel_message(2, __test_kref_2, (long)&local_kref, (long)&done, 0,
1333                             KMSG_ROUTINE);
1334         for (int i = 0; i < 10000000; i++) {
1335                 kref_get(&local_kref, 1);
1336                 udelay(2);
1337                 kref_put(&local_kref);
1338         }
1339         while (!done)
1340                 cpu_relax();
1341         KT_ASSERT(kref_refcnt(&local_kref) == 1);
1342         printk("[TEST-KREF] Simple 2-core getting/putting passed.\n");
1343
1344         return true;
1345 }
1346
1347 // TODO: Add more descriptive assertion messages.
1348 bool test_atomics(void)
1349 {
1350         /* subtract_and_test */
1351         atomic_t num;
1352         /* Test subing to 0 */
1353         atomic_init(&num, 1);
1354         KT_ASSERT(atomic_sub_and_test(&num, 1) == 1);
1355         atomic_init(&num, 2);
1356         KT_ASSERT(atomic_sub_and_test(&num, 2) == 1);
1357         /* Test not getting to 0 */
1358         atomic_init(&num, 1);
1359         KT_ASSERT(atomic_sub_and_test(&num, 0) == 0);
1360         atomic_init(&num, 2);
1361         KT_ASSERT(atomic_sub_and_test(&num, 1) == 0);
1362         /* Test negatives */
1363         atomic_init(&num, -1);
1364         KT_ASSERT(atomic_sub_and_test(&num, 1) == 0);
1365         atomic_init(&num, -1);
1366         KT_ASSERT(atomic_sub_and_test(&num, -1) == 1);
1367         /* Test larger nums */
1368         atomic_init(&num, 265);
1369         KT_ASSERT(atomic_sub_and_test(&num, 265) == 1);
1370         atomic_init(&num, 265);
1371         KT_ASSERT(atomic_sub_and_test(&num, 2) == 0);
1372
1373         /* CAS */
1374         /* Simple test, make sure the bool retval of CAS handles failure */
1375         bool test_cas_val(long init_val)
1376         {
1377                 atomic_t actual_num;
1378                 long old_num;
1379                 int attempt;
1380                 atomic_init(&actual_num, init_val);
1381                 attempt = 0;
1382                 do {
1383                         old_num = atomic_read(&actual_num);
1384                         /* First time, try to fail */
1385                         if (attempt == 0)
1386                                 old_num++;
1387                         attempt++;
1388                 } while (!atomic_cas(&actual_num, old_num, old_num + 10));
1389                 if (atomic_read(&actual_num) != init_val + 10) {
1390                         return false;
1391                 } else {
1392                         return true;
1393                 }
1394         }
1395         KT_ASSERT_M("CAS test for 257 should be successful.",
1396                     test_cas_val(257));
1397         KT_ASSERT_M("CAS test for 1 should be successful.",
1398                     test_cas_val(1));
1399         return true;
1400 }
1401
1402 /* Helper KMSG for test_abort.  Core 1 does this, while core 0 sends an IRQ. */
1403 static void __test_try_halt(uint32_t srcid, long a0, long a1, long a2)
1404 {
1405         disable_irq();
1406         /* wait 10 sec.  should have a bunch of ints pending */
1407         udelay(10000000);
1408         printk("Core 1 is about to halt\n");
1409         cpu_halt();
1410         printk("Returned from halting on core 1\n");
1411 }
1412
1413 /* x86 test, making sure our cpu_halt() and handle_irq() work.  If you want to
1414  * see it fail, you'll probably need to put a nop in the asm for cpu_halt(), and
1415  * comment out abort_halt() in handle_irq(). */
1416 // TODO: Add assertions.
1417 bool test_abort_halt(void)
1418 {
1419 #ifdef CONFIG_X86
1420         send_kernel_message(1, __test_try_halt, 0, 0, 0, KMSG_ROUTINE);
1421         /* wait 1 sec, enough time to for core 1 to be in its KMSG */
1422         udelay(1000000);
1423         /* Send an IPI */
1424         send_ipi(0x01, I_TESTING);
1425         printk("Core 0 sent the IPI\n");
1426 #endif /* CONFIG_X86 */
1427         return true;
1428 }
1429
1430 /* Funcs and global vars for test_cv() */
1431 static struct cond_var local_cv;
1432 static atomic_t counter;
1433 static struct cond_var *cv = &local_cv;
1434 static volatile bool state = FALSE;             /* for test 3 */
1435
1436 void __test_cv_signal(uint32_t srcid, long a0, long a1, long a2)
1437 {
1438         if (atomic_read(&counter) % 4)
1439                 cv_signal(cv);
1440         else
1441                 cv_broadcast(cv);
1442         atomic_dec(&counter);
1443 }
1444
1445 void __test_cv_waiter(uint32_t srcid, long a0, long a1, long a2)
1446 {
1447         cv_lock(cv);
1448         /* check state, etc */
1449         cv_wait_and_unlock(cv);
1450         atomic_dec(&counter);
1451 }
1452
1453 void __test_cv_waiter_t3(uint32_t srcid, long a0, long a1, long a2)
1454 {
1455         udelay(a0);
1456         /* if state == false, we haven't seen the signal yet */
1457         cv_lock(cv);
1458         while (!state) {
1459                 cpu_relax();
1460                 cv_wait(cv);    /* unlocks and relocks */
1461         }
1462         cv_unlock(cv);
1463         /* Make sure we are done, tell the controller we are done */
1464         cmb();
1465         assert(state);
1466         atomic_dec(&counter);
1467 }
1468
1469 // TODO: Add more assertions.
1470 bool test_cv(void)
1471 {
1472         int nr_msgs;
1473
1474         cv_init(cv);
1475         /* Test 0: signal without waiting */
1476         cv_broadcast(cv);
1477         cv_signal(cv);
1478         kthread_yield();
1479         printk("test_cv: signal without waiting complete\n");
1480
1481         /* Test 1: single / minimal shit */
1482         nr_msgs = num_cores - 1; /* not using cpu 0 */
1483         atomic_init(&counter, nr_msgs);
1484         for (int i = 1; i < num_cores; i++)
1485                 send_kernel_message(i, __test_cv_waiter, 0, 0, 0, KMSG_ROUTINE);
1486         udelay(1000000);
1487         cv_signal(cv);
1488         kthread_yield();
1489         while (atomic_read(&counter) != nr_msgs - 1)
1490                 cpu_relax();
1491         printk("test_cv: single signal complete\n");
1492         cv_broadcast(cv);
1493         /* broadcast probably woke up the waiters on our core.  since we want to
1494          * spin on their completion, we need to yield for a bit. */
1495         kthread_yield();
1496         while (atomic_read(&counter))
1497                 cpu_relax();
1498         printk("test_cv: broadcast signal complete\n");
1499
1500         /* Test 2: shitloads of waiters and signalers */
1501         nr_msgs = 0x500;        /* any more than 0x20000 could go OOM */
1502         atomic_init(&counter, nr_msgs);
1503         for (int i = 0; i < nr_msgs; i++) {
1504                 int cpu = (i % (num_cores - 1)) + 1;
1505                 if (atomic_read(&counter) % 5)
1506                         send_kernel_message(cpu, __test_cv_waiter, 0, 0, 0, KMSG_ROUTINE);
1507                 else
1508                         send_kernel_message(cpu, __test_cv_signal, 0, 0, 0, KMSG_ROUTINE);
1509         }
1510         kthread_yield();        /* run whatever messages we sent to ourselves */
1511         while (atomic_read(&counter)) {
1512                 cpu_relax();
1513                 cv_broadcast(cv);
1514                 udelay(1000000);
1515                 kthread_yield();        /* run whatever messages we sent to ourselves */
1516         }
1517         KT_ASSERT(!cv->nr_waiters);
1518         printk("test_cv: massive message storm complete\n");
1519
1520         /* Test 3: basic one signaller, one receiver.  we want to vary the amount of
1521          * time the sender and receiver delays, starting with (1ms, 0ms) and ending
1522          * with (0ms, 1ms).  At each extreme, such as with the sender waiting 1ms,
1523          * the receiver/waiter should hit the "check and wait" point well before the
1524          * sender/signaller hits the "change state and signal" point. */
1525         for (int i = 0; i < 1000; i++) {
1526                 for (int j = 0; j < 10; j++) {  /* some extra chances at each point */
1527                         state = FALSE;
1528                         atomic_init(&counter, 1);       /* signal that the client is done */
1529                         /* client waits for i usec */
1530                         send_kernel_message(2, __test_cv_waiter_t3, i, 0, 0, KMSG_ROUTINE);
1531                         cmb();
1532                         udelay(1000 - i);       /* senders wait time: 1000..0 */
1533                         state = TRUE;
1534                         cv_signal(cv);
1535                         /* signal might have unblocked a kthread, let it run */
1536                         kthread_yield();
1537                         /* they might not have run at all yet (in which case they lost the
1538                          * race and don't need the signal).  but we need to wait til they're
1539                          * done */
1540                         while (atomic_read(&counter))
1541                                 cpu_relax();
1542                         KT_ASSERT(!cv->nr_waiters);
1543                 }
1544         }
1545         printk("test_cv: single sender/receiver complete\n");
1546
1547         return true;
1548 }
1549
1550 /* Based on a bug I noticed.  TODO: actual memset test... */
1551 bool test_memset(void)
1552 {
1553         #define ARR_SZ 256
1554
1555         void print_array(char *c, size_t len)
1556         {
1557                 for (int i = 0; i < len; i++)
1558                         printk("%04d: %02x\n", i, *c++);
1559         }
1560
1561         bool check_array(char *c, char x, size_t len)
1562         {
1563                 for (int i = 0; i < len; i++) {
1564                         #define ASSRT_SIZE 64
1565                         char *assrt_msg = (char*) kmalloc(ASSRT_SIZE, 0);
1566                         snprintf(assrt_msg, ASSRT_SIZE,
1567                                      "Char %d is %c (%02x), should be %c (%02x)", i, *c, *c,
1568                                      x, x);
1569                         KT_ASSERT_M(assrt_msg, (*c == x));
1570                         c++;
1571                 }
1572                 return true;
1573         }
1574
1575         bool run_check(char *arr, int ch, size_t len)
1576         {
1577                 char *c = arr;
1578                 for (int i = 0; i < ARR_SZ; i++)
1579                         *c++ = 0x0;
1580                 memset(arr, ch, len - 4);
1581                 if (check_array(arr, ch, len - 4) &&
1582                     check_array(arr + len - 4, 0x0, 4)) {
1583                         return true;
1584                 } else {
1585                         return false;
1586                 }
1587         }
1588
1589         char bytes[ARR_SZ];
1590
1591         if (!run_check(bytes, 0xfe, 20) || !run_check(bytes, 0xc0fe, 20)) {
1592                 return false;
1593         }
1594
1595         return true;
1596 }
1597
1598 void __attribute__((noinline)) __longjmp_wrapper(struct jmpbuf* jb)
1599 {
1600         asm ("");
1601         printk("Starting: %s\n", __FUNCTION__);
1602         longjmp(jb, 1);
1603         // Should never get here
1604         printk("Exiting: %s\n", __FUNCTION__);
1605 }
1606
1607 // TODO: Add assertions.
1608 bool test_setjmp()
1609 {
1610         struct jmpbuf jb;
1611         printk("Starting: %s\n", __FUNCTION__);
1612         if (setjmp(&jb)) {
1613           printk("After second setjmp return: %s\n", __FUNCTION__);
1614     }
1615     else {
1616           printk("After first setjmp return: %s\n", __FUNCTION__);
1617       __longjmp_wrapper(&jb);
1618     }
1619         printk("Exiting: %s\n", __FUNCTION__);
1620
1621         return true;
1622 }
1623
1624 // TODO: add assertions.
1625 bool test_apipe(void)
1626 {
1627         static struct atomic_pipe test_pipe;
1628
1629         struct some_struct {
1630                 long x;
1631                 int y;
1632         };
1633         /* Don't go too big, or you'll run off the stack */
1634         #define MAX_BATCH 100
1635
1636         void __test_apipe_writer(uint32_t srcid, long a0, long a1, long a2)
1637         {
1638                 int ret, count_todo;
1639                 int total = 0;
1640                 struct some_struct local_str[MAX_BATCH];
1641                 for (int i = 0; i < MAX_BATCH; i++) {
1642                         local_str[i].x = 0xf00;
1643                         local_str[i].y = 0xba5;
1644                 }
1645                 /* testing 0, and max out at 50. [0, ... 50] */
1646                 for (int i = 0; i < MAX_BATCH + 1; i++) {
1647                         count_todo = i;
1648                         while (count_todo) {
1649                                 ret = apipe_write(&test_pipe, &local_str, count_todo);
1650                                 /* Shouldn't break, based on the loop counters */
1651                                 if (!ret) {
1652                                         printk("Writer breaking with %d left\n", count_todo);
1653                                         break;
1654                                 }
1655                                 total += ret;
1656                                 count_todo -= ret;
1657                         }
1658                 }
1659                 printk("Writer done, added %d elems\n", total);
1660                 apipe_close_writer(&test_pipe);
1661         }
1662
1663         void __test_apipe_reader(uint32_t srcid, long a0, long a1, long a2)
1664         {
1665                 int ret, count_todo;
1666                 int total = 0;
1667                 struct some_struct local_str[MAX_BATCH] = {{0}};
1668                 /* reversed loop compared to the writer [50, ... 0] */
1669                 for (int i = MAX_BATCH; i >= 0; i--) {
1670                         count_todo = i;
1671                         while (count_todo) {
1672                                 ret = apipe_read(&test_pipe, &local_str, count_todo);
1673                                 if (!ret) {
1674                                         printk("Reader breaking with %d left\n", count_todo);
1675                                         break;
1676                                 }
1677                                 total += ret;
1678                                 count_todo -= ret;
1679                         }
1680                 }
1681                 printk("Reader done, took %d elems\n", total);
1682                 for (int i = 0; i < MAX_BATCH; i++) {
1683                         assert(local_str[i].x == 0xf00);
1684                         assert(local_str[i].y == 0xba5);
1685                 }
1686                 apipe_close_reader(&test_pipe);
1687         }
1688
1689         void *pipe_buf = kpage_alloc_addr();
1690         KT_ASSERT(pipe_buf);
1691         apipe_init(&test_pipe, pipe_buf, PGSIZE, sizeof(struct some_struct));
1692         printd("*ap_buf %p\n", test_pipe.ap_buf);
1693         printd("ap_ring_sz %p\n", test_pipe.ap_ring_sz);
1694         printd("ap_elem_sz %p\n", test_pipe.ap_elem_sz);
1695         printd("ap_rd_off %p\n", test_pipe.ap_rd_off);
1696         printd("ap_wr_off %p\n", test_pipe.ap_wr_off);
1697         printd("ap_nr_readers %p\n", test_pipe.ap_nr_readers);
1698         printd("ap_nr_writers %p\n", test_pipe.ap_nr_writers);
1699         send_kernel_message(0, __test_apipe_writer, 0, 0, 0, KMSG_ROUTINE);
1700         /* Once we start synchronizing with a kmsg / kthread that could be on a
1701          * different core, we run the chance of being migrated when we block. */
1702         __test_apipe_reader(0, 0, 0, 0);
1703         /* Wait til the first test is done */
1704         while (test_pipe.ap_nr_writers) {
1705                 kthread_yield();
1706                 cpu_relax();
1707         }
1708         /* Try cross core (though CV wake ups schedule on the waking core) */
1709         apipe_open_reader(&test_pipe);
1710         apipe_open_writer(&test_pipe);
1711         send_kernel_message(1, __test_apipe_writer, 0, 0, 0, KMSG_ROUTINE);
1712         __test_apipe_reader(0, 0, 0, 0);
1713         /* We could be on core 1 now.  If we were called from core0, our caller
1714          * might expect us to return while being on core 0 (like if we were kfunc'd
1715          * from the monitor.  Be careful if you copy this code. */
1716
1717         return true;
1718 }
1719
1720 static struct rwlock rwlock, *rwl = &rwlock;
1721 static atomic_t rwlock_counter;
1722 // TODO: Add assertions.
1723 bool test_rwlock(void)
1724 {
1725         bool ret;
1726         rwinit(rwl);
1727         /* Basic: can i lock twice, recursively? */
1728         rlock(rwl);
1729         ret = canrlock(rwl);
1730         KT_ASSERT(ret);
1731         runlock(rwl);
1732         runlock(rwl);
1733         /* Other simply tests */
1734         wlock(rwl);
1735         wunlock(rwl);
1736
1737         /* Just some half-assed different operations */
1738         void __test_rwlock(uint32_t srcid, long a0, long a1, long a2)
1739         {
1740                 int rand = read_tsc() & 0xff;
1741                 for (int i = 0; i < 10000; i++) {
1742                         switch ((rand * i) % 5) {
1743                                 case 0:
1744                                 case 1:
1745                                         rlock(rwl);
1746                                         runlock(rwl);
1747                                         break;
1748                                 case 2:
1749                                 case 3:
1750                                         if (canrlock(rwl))
1751                                                 runlock(rwl);
1752                                         break;
1753                                 case 4:
1754                                         wlock(rwl);
1755                                         wunlock(rwl);
1756                                         break;
1757                         }
1758                 }
1759                 /* signal to allow core 0 to finish */
1760                 atomic_dec(&rwlock_counter);
1761         }
1762
1763         /* send 4 messages to each non core 0 */
1764         atomic_init(&rwlock_counter, (num_cores - 1) * 4);
1765         for (int i = 1; i < num_cores; i++)
1766                 for (int j = 0; j < 4; j++)
1767                         send_kernel_message(i, __test_rwlock, 0, 0, 0, KMSG_ROUTINE);
1768         while (atomic_read(&rwlock_counter))
1769                 cpu_relax();
1770         printk("rwlock test complete\n");
1771
1772         return true;
1773 }
1774
1775 /* Funcs and global vars for test_rv() */
1776 static struct rendez local_rv;
1777 static struct rendez *rv = &local_rv;
1778 /* reusing state and counter from test_cv... */
1779
1780 static int __rendez_cond(void *arg)
1781 {
1782         return *(bool*)arg;
1783 }
1784
1785 void __test_rv_wakeup(uint32_t srcid, long a0, long a1, long a2)
1786 {
1787         if (atomic_read(&counter) % 4)
1788                 cv_signal(cv);
1789         else
1790                 cv_broadcast(cv);
1791         atomic_dec(&counter);
1792 }
1793
1794 void __test_rv_sleeper(uint32_t srcid, long a0, long a1, long a2)
1795 {
1796         rendez_sleep(rv, __rendez_cond, (void*)&state);
1797         atomic_dec(&counter);
1798 }
1799
1800 void __test_rv_sleeper_timeout(uint32_t srcid, long a0, long a1, long a2)
1801 {
1802         /* half-assed amount of time. */
1803         rendez_sleep_timeout(rv, __rendez_cond, (void*)&state, a0);
1804         atomic_dec(&counter);
1805 }
1806
1807 // TODO: Add more assertions.
1808 bool test_rv(void)
1809 {
1810         int nr_msgs;
1811
1812         rendez_init(rv);
1813         /* Test 0: signal without waiting */
1814         rendez_wakeup(rv);
1815         kthread_yield();
1816         printk("test_rv: wakeup without sleeping complete\n");
1817
1818         /* Test 1: a few sleepers */
1819         nr_msgs = num_cores - 1; /* not using cpu 0 */
1820         atomic_init(&counter, nr_msgs);
1821         state = FALSE;
1822         for (int i = 1; i < num_cores; i++)
1823                 send_kernel_message(i, __test_rv_sleeper, 0, 0, 0, KMSG_ROUTINE);
1824         udelay(1000000);
1825         cmb();
1826         state = TRUE;
1827         rendez_wakeup(rv);
1828         /* broadcast probably woke up the waiters on our core.  since we want to
1829          * spin on their completion, we need to yield for a bit. */
1830         kthread_yield();
1831         while (atomic_read(&counter))
1832                 cpu_relax();
1833         printk("test_rv: bulk wakeup complete\n");
1834
1835         /* Test 2: different types of sleepers / timeouts */
1836         state = FALSE;
1837         nr_msgs = 0x500;        /* any more than 0x20000 could go OOM */
1838         atomic_init(&counter, nr_msgs);
1839         for (int i = 0; i < nr_msgs; i++) {
1840                 int cpu = (i % (num_cores - 1)) + 1;
1841                 /* timeouts from 0ms ..5000ms (enough that they should wake via cond */
1842                 if (atomic_read(&counter) % 5)
1843                         send_kernel_message(cpu, __test_rv_sleeper_timeout, i * 4000, 0, 0,
1844                                             KMSG_ROUTINE);
1845                 else
1846                         send_kernel_message(cpu, __test_rv_sleeper, 0, 0, 0, KMSG_ROUTINE);
1847         }
1848         kthread_yield();        /* run whatever messages we sent to ourselves */
1849         state = TRUE;
1850         while (atomic_read(&counter)) {
1851                 cpu_relax();
1852                 rendez_wakeup(rv);
1853                 udelay(1000000);
1854                 kthread_yield();        /* run whatever messages we sent to ourselves */
1855         }
1856         KT_ASSERT(!rv->cv.nr_waiters);
1857         printk("test_rv: lots of sleepers/timeouts complete\n");
1858
1859         return true;
1860 }
1861
1862 /* Cheap test for the alarm internal management */
1863 // TODO: Add assertions.
1864 bool test_alarm(void)
1865 {
1866         uint64_t now = tsc2usec(read_tsc());
1867         struct alarm_waiter await1, await2;
1868         struct timer_chain *tchain = &per_cpu_info[0].tchain;
1869         void shouldnt_run(struct alarm_waiter *awaiter)
1870         {
1871                 printk("Crap, %p ran!\n", awaiter);
1872         }
1873         void empty_run(struct alarm_waiter *awaiter)
1874         {
1875                 printk("Yay, %p ran (hopefully twice)!\n", awaiter);
1876         }
1877         /* Test basic insert, move, remove */
1878         init_awaiter(&await1, shouldnt_run);
1879         set_awaiter_abs(&await1, now + 1000000000);
1880         set_alarm(tchain, &await1);
1881         reset_alarm_abs(tchain, &await1, now + 1000000000 - 50);
1882         reset_alarm_abs(tchain, &await1, now + 1000000000 + 50);
1883         unset_alarm(tchain, &await1);
1884         /* Test insert of one that fired already */
1885         init_awaiter(&await2, empty_run);
1886         set_awaiter_rel(&await2, 1);
1887         set_alarm(tchain, &await2);
1888         enable_irq();
1889         udelay(1000);
1890         reset_alarm_abs(tchain, &await2, now + 10);
1891         udelay(1000);
1892         unset_alarm(tchain, &await2);
1893
1894         printk("%s complete\n", __FUNCTION__);
1895
1896         return true;
1897 }
1898
1899 bool test_kmalloc_incref(void)
1900 {
1901         /* this test is a bit invasive of the kmalloc internals */
1902         void *__get_unaligned_orig_buf(void *buf)
1903         {
1904                 int *tag_flags = (int*)(buf - sizeof(int));
1905                 if ((*tag_flags & KMALLOC_FLAG_MASK) == KMALLOC_TAG_UNALIGN)
1906                         return (buf - (*tag_flags >> KMALLOC_ALIGN_SHIFT));
1907                 else
1908                         return 0;
1909         }
1910
1911         bool test_buftag(void *b, struct kmalloc_tag *btag, char *str)
1912         {
1913                 KT_ASSERT_M(str, kref_refcnt(&btag->kref) == 1);
1914                 kmalloc_incref(b);
1915                 KT_ASSERT_M(str, kref_refcnt(&btag->kref) == 2);
1916                 kfree(b);
1917                 KT_ASSERT_M(str, kref_refcnt(&btag->kref) == 1);
1918                 kfree(b);
1919                 /* dangerous read, it's been freed */
1920                 KT_ASSERT_M(str, kref_refcnt(&btag->kref) == 0);
1921                 return TRUE;
1922         }
1923
1924         void *b1, *b2, *b2o;
1925         struct kmalloc_tag *b1tag, *b2tag;
1926
1927         /* no realigned case */
1928         b1 = kmalloc(55, 0);
1929         KT_ASSERT(!__get_unaligned_orig_buf(b1));
1930         b1tag = (struct kmalloc_tag*)(b1 - sizeof(struct kmalloc_tag));
1931
1932         /* realigned case.  alloc'd before b1's test, so we know we get different
1933          * buffers. */
1934         b2 = kmalloc_align(55, 0, 64);
1935         b2o = __get_unaligned_orig_buf(b2);
1936         KT_ASSERT(b2o);
1937         b2tag = (struct kmalloc_tag*)(b2o - sizeof(struct kmalloc_tag));
1938
1939         test_buftag(b1, b1tag, "b1, no realign");
1940         test_buftag(b2, b2tag, "b2, realigned");
1941
1942         return TRUE;
1943 }
1944
1945 /* Some ghetto things:
1946  * - ASSERT_M only lets you have a string, not a format string.
1947  * - put doesn't return, so we have a "loud" test for that.  alternatively, we
1948  *   could have put panic, but then we couldn't test it at all.  and i don't
1949  *   particularly want it to have a return value.
1950  * - ASSERT_M just blindly returns.  we're leaking memory.
1951  */
1952 bool test_u16pool(void)
1953 {
1954         #define AMT 4096
1955         int *t;
1956         struct u16_pool *id = create_u16_pool(AMT);
1957         int i, x, y;
1958         int numalloc;
1959         KT_ASSERT(id);
1960
1961         t = kzmalloc(sizeof(int) * (AMT + 1), MEM_WAIT);
1962         for (x = 0; x < 1024; x++) {
1963                 KT_ASSERT_M("Should be empty", id->tos == 0);
1964                 for (i = 0; i < id->size; i++) {
1965                         int p = get_u16(id);
1966                         if (p < 0)
1967                                 KT_ASSERT_M("Couldn't get enough", 0);
1968                         t[i] = p;
1969                 }
1970                 numalloc = i;
1971                 // free them at random. With luck, we don't get too many duplicate
1972                 // hits.
1973                 for (y = i = 0; i < numalloc; y++) {
1974                         /* could read genrand, but that could be offline */
1975                         int f = (uint16_t)read_tsc() % numalloc;
1976                         if (!t[f])
1977                                 continue;
1978                         put_u16(id, t[f]);
1979                         t[f] = 0;
1980                         i++;
1981                         /* that's long enough... */
1982                         if (y > 2 * id->size)
1983                                 break;
1984                 }
1985                 /* grab the leftovers */
1986                 for (i = 0; i < id->size; i++) {
1987                         if (!t[i])
1988                                 continue;
1989                         put_u16(id, t[i]);
1990                         t[i] = 0;
1991                 }
1992                 /* all of our previous checks failed to give back 0 */
1993                 put_u16(id, 0);
1994         }
1995
1996         // pop too many.
1997         bool we_broke = FALSE;
1998         for (i = 0; i < id->size * 2; i++) {
1999                 x = get_u16(id);
2000                 if (x == -1) {
2001                         we_broke = TRUE;
2002                         break;
2003                 }
2004                 t[i] = x;
2005         }
2006         KT_ASSERT_M("Should have failed to get too many", we_broke);
2007
2008         numalloc = i;
2009
2010         printd("Allocated %d items\n", numalloc);
2011         for (i = 0; i < numalloc; i++) {
2012                 put_u16(id, t[i]);
2013                 t[i] = 0;
2014         }
2015         KT_ASSERT_M("Should be empty", id->tos == 0);
2016
2017         printk("Ignore next BAD, testing bad alloc\n");
2018         put_u16(id, 25);        // should get an error.
2019         for (i = 0; i < id->size; i++) {
2020                 int v = get_u16(id);
2021                 if (t[v])
2022                         printd("BAD: %d pops twice!\n", v);
2023                 KT_ASSERT_M("Popped twice!", t[v] == 0);
2024                 t[v] = 1;
2025                 //printk("%d,", v);
2026         }
2027
2028         for (i = 1; i < id->size; i++) {
2029                 if (!t[i])
2030                         printd("BAD: %d was not set\n", i);
2031                 KT_ASSERT_M("Wasn't set!", t[i]);
2032         }
2033
2034         kfree(t);
2035         return FALSE;
2036 }
2037
2038 static bool uaccess_mapped(void *addr, char *buf, char *buf2)
2039 {
2040         KT_ASSERT_M(
2041                 "Copy to user (u8) to mapped address should not fail",
2042                 copy_to_user(addr, buf, 1) == 0);
2043         KT_ASSERT_M(
2044                 "Copy to user (u16) to mapped address should not fail",
2045                 copy_to_user(addr, buf, 2) == 0);
2046         KT_ASSERT_M(
2047                 "Copy to user (u32) to mapped address should not fail",
2048                 copy_to_user(addr, buf, 4) == 0);
2049         KT_ASSERT_M(
2050                 "Copy to user (u64) to mapped address should not fail",
2051                 copy_to_user(addr, buf, 8) == 0);
2052         KT_ASSERT_M(
2053                 "Copy to user (mem) to mapped address should not fail",
2054                 copy_to_user(addr, buf, sizeof(buf)) == 0);
2055
2056         KT_ASSERT_M(
2057                 "Copy from user (u8) to mapped address should not fail",
2058                 copy_from_user(buf, addr, 1) == 0);
2059         KT_ASSERT_M(
2060                 "Copy from user (u16) to mapped address should not fail",
2061                 copy_from_user(buf, addr, 2) == 0);
2062         KT_ASSERT_M(
2063                 "Copy from user (u32) to mapped address should not fail",
2064                 copy_from_user(buf, addr, 4) == 0);
2065         KT_ASSERT_M(
2066                 "Copy from user (u64) to mapped address should not fail",
2067                 copy_from_user(buf, addr, 8) == 0);
2068         KT_ASSERT_M(
2069                 "Copy from user (mem) to mapped address should not fail",
2070                 copy_from_user(buf, addr, sizeof(buf)) == 0);
2071
2072         KT_ASSERT_M(
2073                 "String copy to user to mapped address should not fail",
2074                 strcpy_to_user(current, addr, "Akaros") == 0);
2075         KT_ASSERT_M(
2076                 "String copy from user to mapped address should not fail",
2077                 strcpy_from_user(current, buf, addr) == 0);
2078         KT_ASSERT_M("The copied string content should be matching",
2079                                 memcmp(buf, "Akaros", 7) == 0);
2080
2081         return TRUE;
2082 }
2083
2084 static bool uaccess_unmapped(void *addr, char *buf, char *buf2)
2085 {
2086         KT_ASSERT_M("Copy to user (u8) to not mapped address should fail",
2087                                 copy_to_user(addr, buf, 1) == -EFAULT);
2088         KT_ASSERT_M("Copy to user (u16) to not mapped address should fail",
2089                                 copy_to_user(addr, buf, 2) == -EFAULT);
2090         KT_ASSERT_M("Copy to user (u32) to not mapped address should fail",
2091                                 copy_to_user(addr, buf, 4) == -EFAULT);
2092         KT_ASSERT_M("Copy to user (u64) to not mapped address should fail",
2093                                 copy_to_user(addr, buf, 8) == -EFAULT);
2094         KT_ASSERT_M("Copy to user (mem) to not mapped address should fail",
2095                                 copy_to_user(addr, buf, sizeof(buf)) == -EFAULT);
2096
2097         KT_ASSERT_M("Copy from user (u8) to not mapped address should fail",
2098                                 copy_from_user(buf, addr, 1) == -EFAULT);
2099         KT_ASSERT_M("Copy from user (u16) to not mapped address should fail",
2100                                 copy_from_user(buf, addr, 2) == -EFAULT);
2101         KT_ASSERT_M("Copy from user (u32) to not mapped address should fail",
2102                                 copy_from_user(buf, addr, 4) == -EFAULT);
2103         KT_ASSERT_M("Copy from user (u64) to not mapped address should fail",
2104                                 copy_from_user(buf, addr, 8) == -EFAULT);
2105         KT_ASSERT_M("Copy from user (mem) to not mapped address should fail",
2106                                 copy_from_user(buf, addr, sizeof(buf)) == -EFAULT);
2107
2108         KT_ASSERT_M(
2109                 "String copy to user to not mapped address should fail",
2110                 strcpy_to_user(NULL, addr, "Akaros") == -EFAULT);
2111         KT_ASSERT_M(
2112                 "String copy from user to not mapped address should fail",
2113                 strcpy_from_user(NULL, buf, addr) == -EFAULT);
2114
2115         KT_ASSERT_M("Copy from user with kernel side source pointer should fail",
2116                                 copy_from_user(buf, buf2, sizeof(buf)) == -EFAULT);
2117         KT_ASSERT_M("Copy to user with kernel side source pointer should fail",
2118                                 copy_to_user(buf, buf2, sizeof(buf)) == -EFAULT);
2119
2120         return TRUE;
2121 }
2122
2123 bool test_uaccess(void)
2124 {
2125         char buf[128] = { 0 };
2126         char buf2[128] = { 0 };
2127         struct proc *tmp;
2128         uintptr_t switch_tmp;
2129         int err;
2130         static const size_t mmap_size = 4096;
2131         void *addr;
2132         bool passed = FALSE;
2133
2134         err = proc_alloc(&tmp, 0, 0);
2135         KT_ASSERT_M("Failed to alloc a temp proc", err == 0);
2136         /* Tell everyone we're ready in case some ops don't work on PROC_CREATED */
2137         __proc_set_state(tmp, PROC_RUNNABLE_S);
2138         switch_tmp = switch_to(tmp);
2139         addr = mmap(tmp, 0, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, -1, 0);
2140         if (addr == MAP_FAILED)
2141                 goto out;
2142         passed = uaccess_mapped(addr, buf, buf2);
2143         munmap(tmp, (uintptr_t) addr, mmap_size);
2144         if (!passed)
2145                 goto out;
2146         passed = uaccess_unmapped(addr, buf, buf2);
2147 out:
2148         switch_back(tmp, switch_tmp);
2149         proc_decref(tmp);
2150         return passed;
2151 }
2152
2153 bool test_sort(void)
2154 {
2155         int cmp_longs_asc(const void *p1, const void *p2)
2156         {
2157                 const long v1 = *(const long *) p1;
2158                 const long v2 = *(const long *) p2;
2159
2160                 return v1 < v2 ? -1 : (v1 > v2 ? 1 : 0);
2161         }
2162
2163         int cmp_longs_desc(const void *p1, const void *p2)
2164         {
2165                 const long v1 = *(const long *) p1;
2166                 const long v2 = *(const long *) p2;
2167
2168                 return v1 < v2 ? 1 : (v1 > v2 ? -1 : 0);
2169         }
2170
2171         size_t i;
2172         long long_set_1[] = {
2173                 -9, 11, 0, 23, 123, -99, 3, 11, 23, -999, 872, 17, 21
2174         };
2175         long long_set_2[] = {
2176                 31, 77, -1, 2, 0, 64, 11, 19, 69, 111, -89, 17, 21, 44, 77
2177         };
2178
2179         sort(long_set_1, ARRAY_SIZE(long_set_1), sizeof(long), cmp_longs_asc);
2180         for (i = 1; i < ARRAY_SIZE(long_set_1); i++)
2181                 KT_ASSERT(long_set_1[i - 1] <= long_set_1[i]);
2182
2183         sort(long_set_2, ARRAY_SIZE(long_set_2), sizeof(long), cmp_longs_desc);
2184         for (i = 1; i < ARRAY_SIZE(long_set_2); i++)
2185                 KT_ASSERT(long_set_2[i - 1] >= long_set_2[i]);
2186
2187         return TRUE;
2188 }
2189
2190 bool test_cmdline_parse(void)
2191 {
2192         static const char *fake_cmdline =
2193                 "kernel -root=/foo -simple -num=123 -quoted='abc \\'' -dup=311 "
2194                 "-dup='akaros' -empty='' -inner=-outer -outer=-inner=xyz";
2195         const char *opt;
2196         char param[128];
2197
2198         /* Note that the get_boot_option() API should be passed NULL the first time
2199          * it is called, in normal cases, and should be passed the value returned by
2200          * previous call to get_boot_option(), in case multiple options with same
2201          * name have to be fetched.
2202          */
2203         opt = get_boot_option(fake_cmdline, "-root", param, sizeof(param));
2204         KT_ASSERT_M("Unable to parse -root option", opt);
2205         KT_ASSERT_M("Invalid -root option value", strcmp(param, "/foo") == 0);
2206
2207         opt = get_boot_option(fake_cmdline, "-root", NULL, 0);
2208         KT_ASSERT_M("Unable to parse -root option when param not provided", opt);
2209
2210         opt = get_boot_option(fake_cmdline, "-simple", param, sizeof(param));
2211         KT_ASSERT_M("Unable to parse -simple option", opt);
2212         KT_ASSERT_M("Invalid -simple option value", strcmp(param, "") == 0);
2213
2214         opt = get_boot_option(fake_cmdline, "-num", param, sizeof(param));
2215         KT_ASSERT_M("Unable to parse -num option", opt);
2216         KT_ASSERT_M("Invalid -num option value", strcmp(param, "123") == 0);
2217
2218         opt = get_boot_option(fake_cmdline, "-quoted", param, sizeof(param));
2219         KT_ASSERT_M("Unable to parse -quoted option", opt);
2220         KT_ASSERT_M("Invalid -quoted option value", strcmp(param, "abc '") == 0);
2221
2222         opt = get_boot_option(fake_cmdline, "-dup", param, sizeof(param));
2223         KT_ASSERT_M("Unable to parse -dup option", opt);
2224         KT_ASSERT_M("Invalid -dup option first value", strcmp(param, "311") == 0);
2225
2226         opt = get_boot_option(opt, "-dup", param, sizeof(param));
2227         KT_ASSERT_M("Unable to parse -dup option", opt);
2228         KT_ASSERT_M("Invalid -dup option second value",
2229                                 strcmp(param, "akaros") == 0);
2230
2231         opt = get_boot_option(fake_cmdline, "-inner", param, sizeof(param));
2232         KT_ASSERT_M("Unable to parse -inner option", opt);
2233         KT_ASSERT_M("Invalid -inner option value", strcmp(param, "-outer") == 0);
2234
2235         opt = get_boot_option(opt, "-inner", param, sizeof(param));
2236         KT_ASSERT_M("Should not be parsing -inner as value", !opt);
2237
2238         opt = get_boot_option(fake_cmdline, "-outer", param, sizeof(param));
2239         KT_ASSERT_M("Unable to parse -outer option", opt);
2240         KT_ASSERT_M("Invalid -outer option value",
2241                                 strcmp(param, "-inner=xyz") == 0);
2242
2243         opt = get_boot_option(fake_cmdline, "-missing", param, sizeof(param));
2244         KT_ASSERT_M("Should not be parsing -missing option", !opt);
2245
2246         opt = get_boot_option(fake_cmdline, "-inne", NULL, 0);
2247         KT_ASSERT_M("Should not be parsing -inne option", !opt);
2248
2249         opt = get_boot_option(fake_cmdline, "-outera", NULL, 0);
2250         KT_ASSERT_M("Should not be parsing -outera option", !opt);
2251
2252         opt = get_boot_option(fake_cmdline, "-empty", param, sizeof(param));
2253         KT_ASSERT_M("Unable to parse -empty option", opt);
2254         KT_ASSERT_M("Invalid -empty option value", strcmp(param, "") == 0);
2255
2256         return TRUE;
2257 }
2258
2259 static struct ktest ktests[] = {
2260 #ifdef CONFIG_X86
2261         KTEST_REG(ipi_sending,        CONFIG_TEST_ipi_sending),
2262         KTEST_REG(pic_reception,      CONFIG_TEST_pic_reception),
2263         KTEST_REG(lapic_status_bit,   CONFIG_TEST_lapic_status_bit),
2264         KTEST_REG(pit,                CONFIG_TEST_pit),
2265         KTEST_REG(circ_buffer,        CONFIG_TEST_circ_buffer),
2266         KTEST_REG(kernel_messages,    CONFIG_TEST_kernel_messages),
2267 #endif // CONFIG_X86
2268         KTEST_REG(barrier,            CONFIG_TEST_barrier),
2269         KTEST_REG(interrupts_irqsave, CONFIG_TEST_interrupts_irqsave),
2270         KTEST_REG(bitmasks,           CONFIG_TEST_bitmasks),
2271         KTEST_REG(checklists,         CONFIG_TEST_checklists),
2272         KTEST_REG(smp_call_functions, CONFIG_TEST_smp_call_functions),
2273         KTEST_REG(slab,               CONFIG_TEST_slab),
2274         KTEST_REG(kmalloc,            CONFIG_TEST_kmalloc),
2275         KTEST_REG(hashtable,          CONFIG_TEST_hashtable),
2276         KTEST_REG(circular_buffer,    CONFIG_TEST_circular_buffer),
2277         KTEST_REG(bcq,                CONFIG_TEST_bcq),
2278         KTEST_REG(ucq,                CONFIG_TEST_ucq),
2279         KTEST_REG(vm_regions,         CONFIG_TEST_vm_regions),
2280         KTEST_REG(radix_tree,         CONFIG_TEST_radix_tree),
2281         KTEST_REG(random_fs,          CONFIG_TEST_random_fs),
2282         KTEST_REG(kthreads,           CONFIG_TEST_kthreads),
2283         KTEST_REG(kref,               CONFIG_TEST_kref),
2284         KTEST_REG(atomics,            CONFIG_TEST_atomics),
2285         KTEST_REG(abort_halt,         CONFIG_TEST_abort_halt),
2286         KTEST_REG(cv,                 CONFIG_TEST_cv),
2287         KTEST_REG(memset,             CONFIG_TEST_memset),
2288         KTEST_REG(setjmp,             CONFIG_TEST_setjmp),
2289         KTEST_REG(apipe,              CONFIG_TEST_apipe),
2290         KTEST_REG(rwlock,             CONFIG_TEST_rwlock),
2291         KTEST_REG(rv,                 CONFIG_TEST_rv),
2292         KTEST_REG(alarm,              CONFIG_TEST_alarm),
2293         KTEST_REG(kmalloc_incref,     CONFIG_TEST_kmalloc_incref),
2294         KTEST_REG(u16pool,            CONFIG_TEST_u16pool),
2295         KTEST_REG(uaccess,            CONFIG_TEST_uaccess),
2296         KTEST_REG(sort,               CONFIG_TEST_sort),
2297         KTEST_REG(cmdline_parse,      CONFIG_TEST_cmdline_parse),
2298 };
2299 static int num_ktests = sizeof(ktests) / sizeof(struct ktest);
2300 linker_func_1(register_pb_ktests)
2301 {
2302         REGISTER_KTESTS(ktests, num_ktests);
2303 }
2304
2305 /* Linker function tests.  Keep them commented, etc. */
2306 #if 0
2307 linker_func_1(xme11)
2308 {
2309         printk("xme11\n");
2310 }
2311
2312 linker_func_1(xme12)
2313 {
2314         printk("xme12\n");
2315 }
2316
2317 linker_func_1(xme13)
2318 {
2319         printk("xme13\n");
2320 }
2321
2322 linker_func_1(xme14)
2323 {
2324         printk("xme14\n");
2325 }
2326
2327 linker_func_1(xme15)
2328 {
2329         printk("xme15\n");
2330 }
2331
2332 linker_func_2(xme21)
2333 {
2334         printk("xme21\n");
2335 }
2336
2337 linker_func_2(xme22)
2338 {
2339         printk("xme22\n");
2340 }
2341
2342 linker_func_2(xme23)
2343 {
2344         printk("xme23\n");
2345 }
2346
2347 linker_func_2(xme24)
2348 {
2349         printk("xme24\n");
2350 }
2351
2352 linker_func_2(xme25)
2353 {
2354         printk("xme25\n");
2355 }
2356
2357 linker_func_3(xme31)
2358 {
2359         printk("xme31\n");
2360 }
2361
2362 linker_func_3(xme32)
2363 {
2364         printk("xme32\n");
2365 }
2366
2367 linker_func_3(xme33)
2368 {
2369         printk("xme33\n");
2370 }
2371
2372 linker_func_3(xme34)
2373 {
2374         printk("xme34\n");
2375 }
2376
2377 linker_func_3(xme35)
2378 {
2379         printk("xme35\n");
2380 }
2381
2382 linker_func_4(xme41)
2383 {
2384         printk("xme41\n");
2385 }
2386
2387 linker_func_4(xme42)
2388 {
2389         printk("xme42\n");
2390 }
2391
2392 linker_func_4(xme43)
2393 {
2394         printk("xme43\n");
2395 }
2396
2397 linker_func_4(xme44)
2398 {
2399         printk("xme44\n");
2400 }
2401
2402 linker_func_4(xme45)
2403 {
2404         printk("xme45\n");
2405 }
2406 #endif /* linker func tests */