Serialize multiline printks
[akaros.git] / kern / src / monitor.c
1 // Simple command-line kernel monitor useful for
2 // controlling the kernel and exploring the system interactively.
3
4 #include <arch/arch.h>
5 #include <stab.h>
6 #include <smp.h>
7 #include <arch/console.h>
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <assert.h>
12 #include <monitor.h>
13 #include <trap.h>
14 #include <pmap.h>
15 #include <kdebug.h>
16 #include <testing.h>
17 #include <manager.h>
18 #include <schedule.h>
19 #include <kdebug.h>
20 #include <syscall.h>
21 #include <kmalloc.h>
22 #include <elf.h>
23 #include <event.h>
24 #include <trap.h>
25 #include <time.h>
26 #include <percpu.h>
27
28 #include <ros/memlayout.h>
29 #include <ros/event.h>
30
31 #define CMDBUF_SIZE     80      // enough for one VGA text line
32
33 typedef struct command {
34         const char *name;
35         const char *desc;
36         // return -1 to force monitor to exit
37         int (*func)(int argc, char **argv, struct hw_trapframe *hw_tf);
38 } command_t;
39
40 static command_t commands[] = {
41         { "help", "Display this list of commands", mon_help },
42         { "kerninfo", "Display information about the kernel", mon_kerninfo },
43         { "backtrace", "Dump a backtrace", mon_backtrace },
44         { "bt", "Dump a backtrace", mon_backtrace },
45         { "reboot", "Take a ride to the South Bay", mon_reboot },
46         { "showmapping", "Shows VA->PA mappings", mon_showmapping},
47         { "sm", "Shows VA->PA mappings", mon_sm},
48         { "cpuinfo", "Prints CPU diagnostics", mon_cpuinfo},
49         { "ps", "Prints process list", mon_ps},
50         { "nanwan", "Meet Nanwan!!", mon_nanwan},
51         { "bin_run", "Create and run a program from /bin", mon_bin_run},
52         { "manager", "Run the manager", mon_manager},
53         { "procinfo", "Show information about processes", mon_procinfo},
54         { "pip", "Shorthand for procinfo pid", mon_pip},
55         { "kill", "Kills a process", mon_kill},
56         { "exit", "Leave the monitor", mon_exit},
57         { "e", "Leave the monitor", mon_exit},
58         { "kfunc", "Run a kernel function directly (!!!)", mon_kfunc},
59         { "notify", "Notify a process.  Vcoreid will skip their prefs", mon_notify},
60         { "measure", "Run a specific measurement", mon_measure},
61         { "trace", "Run some tracing functions", mon_trace},
62         { "monitor", "Run the monitor on another core", mon_monitor},
63         { "sh", "Try to run a shell (bash)", mon_shell},
64         { "bash", "Try to run a shell (bash)", mon_shell},
65         { "bb", "Try to run a shell (bash)", mon_shell},
66         { "alarm", "Alarm Diagnostics", mon_alarm},
67         { "msr", "read/write msr: msr msr [value]", mon_msr},
68         { "db", "Misc debugging", mon_db},
69         { "px", "Toggle printx", mon_px},
70         { "kpfret", "Attempt to idle after a kernel fault", mon_kpfret},
71         { "ks", "Kernel scheduler hacks", mon_ks},
72         { "coreinfo", "Print diagnostics for a core", mon_coreinfo},
73         { "hexdump", "Hexdump PID's memory (0 for kernel)", mon_hexdump},
74         { "hd", "Hexdump PID's memory (0 for kernel)", mon_hexdump},
75         { "pahexdump", "Hexdump physical memory", mon_pahexdump},
76         { "phd", "Hexdump physical memory", mon_pahexdump},
77 };
78 #define NCOMMANDS (sizeof(commands)/sizeof(commands[0]))
79
80 /***** Implementations of basic kernel monitor commands *****/
81
82 int mon_help(int argc, char **argv, struct hw_trapframe *hw_tf)
83 {
84         int i;
85
86         for (i = 0; i < NCOMMANDS; i++)
87                 cprintf("%s - %s\n", commands[i].name, commands[i].desc);
88         return 0;
89 }
90
91 int mon_ps(int argc, char** argv, struct hw_trapframe *hw_tf)
92 {
93         print_allpids();
94         return 0;
95 }
96
97 int mon_kerninfo(int argc, char **argv, struct hw_trapframe *hw_tf)
98 {
99         extern char _start[], etext[], end[];
100
101         cprintf("Special kernel symbols:\n");
102         cprintf("  _start %016x (virt)  %016x (phys)\n", _start, (uintptr_t)(_start - KERNBASE));
103         cprintf("  etext  %016x (virt)  %016x (phys)\n", etext, (uintptr_t)(etext - KERNBASE));
104         cprintf("  end    %016x (virt)  %016x (phys)\n", end, (uintptr_t)(end - KERNBASE));
105         cprintf("Kernel executable memory footprint: %dKB\n",
106                 (uint32_t)(end-_start+1023)/1024);
107         return 0;
108 }
109
110 static int __backtrace(int argc, char **argv, struct hw_trapframe *hw_tf)
111 {
112         uintptr_t pc, fp;
113         if (argc == 1) {
114                 backtrace();
115                 return 0;
116         }
117         if (argc != 3) {
118                 printk("Need either no arguments, or two (PC and FP) in hex\n");
119                 return 1;
120         }
121         pc = strtol(argv[1], 0, 16);
122         fp = strtol(argv[2], 0, 16);
123         print_lock();
124         printk("Backtrace from instruction %p, with frame pointer %p\n", pc, fp);
125         backtrace_frame(pc, fp);
126         print_unlock();
127         return 0;
128 }
129
130 int mon_backtrace(int argc, char **argv, struct hw_trapframe *hw_tf)
131 {
132         return __backtrace(argc, argv, hw_tf);
133 }
134
135 int mon_reboot(int argc, char **argv, struct hw_trapframe *hw_tf)
136 {
137         cprintf("[Scottish Accent]: She's goin' down, Cap'n!\n");
138         reboot();
139
140         // really, should never see this
141         cprintf("Sigh....\n");
142         return 0;
143 }
144
145 static int __showmapping(int argc, char **argv, struct hw_trapframe *hw_tf)
146 {
147         struct proc *p = NULL;
148         uintptr_t start;
149         size_t size;
150         pgdir_t pgdir;
151         pid_t pid;
152
153         if (argc < 3) {
154                 printk("Shows virtual -> physical mappings for a virt addr range.\n");
155                 printk("Usage: showmapping PID START_ADDR [END_ADDR]\n");
156                 printk("    PID == 0 for the boot pgdir\n");
157                 return 1;
158         }
159         pid = strtol(argv[1], 0, 10);
160         if (!pid) {
161                 pgdir = boot_pgdir;
162         } else {
163                 p = pid2proc(pid);
164                 if (!p) {
165                         printk("No proc with pid %d\n", pid);
166                         return 1;
167                 }
168                 pgdir = p->env_pgdir;
169         }
170         start = ROUNDDOWN(strtol(argv[2], 0, 16), PGSIZE);
171         size = (argc == 3) ? 1 : strtol(argv[3], 0, 16) - start;
172         if (size/PGSIZE > 512) {
173                 cprintf("Not going to do this for more than 512 items\n");
174                 return 1;
175         }
176         show_mapping(pgdir, start, size);
177         if (p)
178                 proc_decref(p);
179         return 0;
180 }
181
182 int mon_showmapping(int argc, char **argv, struct hw_trapframe *hw_tf)
183 {
184         return __showmapping(argc, argv, hw_tf);
185 }
186
187 int mon_sm(int argc, char **argv, struct hw_trapframe *hw_tf)
188 {
189         return __showmapping(argc, argv, hw_tf);
190 }
191
192 static void print_info_handler(struct hw_trapframe *hw_tf, void *data)
193 {
194         uint64_t tsc = read_tsc();
195
196         print_lock();
197         cprintf("----------------------------\n");
198         cprintf("This is Core %d\n", core_id());
199         cprintf("Timestamp = %lld\n", tsc);
200 #ifdef CONFIG_X86
201         cprintf("Hardware core %d\n", hw_core_id());
202         cprintf("MTRR_DEF_TYPE = 0x%08x\n", read_msr(IA32_MTRR_DEF_TYPE));
203         cprintf("MTRR Phys0 Base = 0x%016llx, Mask = 0x%016llx\n",
204                 read_msr(0x200), read_msr(0x201));
205         cprintf("MTRR Phys1 Base = 0x%016llx, Mask = 0x%016llx\n",
206                 read_msr(0x202), read_msr(0x203));
207         cprintf("MTRR Phys2 Base = 0x%016llx, Mask = 0x%016llx\n",
208                 read_msr(0x204), read_msr(0x205));
209         cprintf("MTRR Phys3 Base = 0x%016llx, Mask = 0x%016llx\n",
210                 read_msr(0x206), read_msr(0x207));
211         cprintf("MTRR Phys4 Base = 0x%016llx, Mask = 0x%016llx\n",
212                 read_msr(0x208), read_msr(0x209));
213         cprintf("MTRR Phys5 Base = 0x%016llx, Mask = 0x%016llx\n",
214                 read_msr(0x20a), read_msr(0x20b));
215         cprintf("MTRR Phys6 Base = 0x%016llx, Mask = 0x%016llx\n",
216                 read_msr(0x20c), read_msr(0x20d));
217         cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
218                 read_msr(0x20e), read_msr(0x20f));
219 #endif // CONFIG_X86
220         cprintf("----------------------------\n");
221         print_unlock();
222 }
223
224 static bool print_all_info(void)
225 {
226         cprintf("\nCORE 0 asking all cores to print info:\n");
227         smp_call_function_all(print_info_handler, NULL, 0);
228         cprintf("\nDone!\n");
229         return true;
230 }
231
232 int mon_cpuinfo(int argc, char **argv, struct hw_trapframe *hw_tf)
233 {
234         cprintf("Number of Cores detected: %d\n", num_cores);
235         cprintf("Calling CPU's ID: 0x%08x\n", core_id());
236
237         if (argc < 2)
238                 smp_call_function_self(print_info_handler, NULL, 0);
239         else
240                 smp_call_function_single(strtol(argv[1], 0, 10),
241                                          print_info_handler, NULL, 0);
242         return 0;
243 }
244
245 int mon_manager(int argc, char** argv, struct hw_trapframe *hw_tf)
246 {
247         manager();
248         panic("should never get here");
249         return 0;
250 }
251
252 int mon_nanwan(int argc, char **argv, struct hw_trapframe *hw_tf)
253 {
254         /* Borrowed with love from http://www.geocities.com/SoHo/7373/zoo.htm
255          * (http://www.ascii-art.com/).  Slightly modified to make it 25 lines tall.
256          */
257         print_lock();
258         printk("\n");
259         printk("             .-.  .-.\n");
260         printk("             |  \\/  |\n");
261         printk("            /,   ,_  `'-.\n");
262         printk("          .-|\\   /`\\     '. \n");
263         printk("        .'  0/   | 0\\  \\_  `\".  \n");
264         printk("     .-'  _,/    '--'.'|#''---'\n");
265         printk("      `--'  |       /   \\#\n");
266         printk("            |      /     \\#\n");
267         printk("            \\     ;|\\    .\\#\n");
268         printk("            |' ' //  \\   ::\\# \n");
269         printk("            \\   /`    \\   ':\\#\n");
270         printk("             `\"`       \\..   \\#\n");
271         printk("                        \\::.  \\#\n");
272         printk("                         \\::   \\#\n");
273         printk("                          \\'  .:\\#\n");
274         printk("                           \\  :::\\#\n");
275         printk("                            \\  '::\\#\n");
276         printk("                             \\     \\#\n");
277         printk("                              \\:.   \\#\n");
278         printk("                               \\::   \\#\n");
279         printk("                                \\'   .\\#\n");
280         printk("                             jgs \\   ::\\#\n");
281         printk("                                  \\      \n");
282         print_unlock();
283         return 0;
284 }
285
286 int mon_bin_run(int argc, char **argv, struct hw_trapframe *hw_tf)
287 {
288         if (argc < 2) {
289                 printk("Usage: bin_run FILENAME\n");
290                 return 1;
291         }
292         struct file_or_chan *program;
293         int retval = 0;
294         char buf[5 + MAX_FILENAME_SZ + 1] = "/bin/";    /* /bin/ + max + \0 */
295
296         strlcpy(buf, "/bin/", sizeof(buf));
297         if (strlcat(buf, argv[1], sizeof(buf)) > sizeof(buf)) {
298                 printk("Filename '%s' too long!\n", argv[1]);
299                 return 1;
300         }
301         program = foc_open(buf, O_EXEC | O_READ, 0);
302         if (!program) {
303                 printk("No such program!\n");
304                 return 1;
305         }
306         char **p_argv = kmalloc(sizeof(char*) * argc, 0);       /* bin_run's argc */
307         for (int i = 0; i < argc - 1; i++)
308                 p_argv[i] = argv[i + 1];
309         p_argv[argc - 1] = 0;
310         /* super ugly: we need to stash current, so that proc_create doesn't pick up
311          * on random processes running here and assuming they are the parent */
312         struct proc *old_cur = current;
313         current = 0;
314         struct proc *p = proc_create(program, p_argv, NULL);
315         current = old_cur;
316         kfree(p_argv);
317         proc_wakeup(p);
318         proc_decref(p); /* let go of the reference created in proc_create() */
319         foc_decref(program);
320         /* Make a scheduling decision.  You might not get the process you created,
321          * in the event there are others floating around that are runnable */
322         run_scheduler();
323         /* want to idle, so we un the process we just selected.  this is a bit
324          * hackish, but so is the monitor. */
325         smp_idle();
326         assert(0);
327         return 0;
328 }
329
330 int mon_procinfo(int argc, char **argv, struct hw_trapframe *hw_tf)
331 {
332         int verbosity = 0;
333
334         if (argc < 2) {
335                 printk("Usage: procinfo OPTION\n");
336                 printk("\tall: show all active pids\n");
337                 printk("\tpid NUM: show a lot of info for proc NUM\n");
338                 printk("\tunlock: unlock the lock for the ADDR (OMG!!!)\n");
339                 printk("\tkill NUM: destroy proc NUM\n");
340                 return 1;
341         }
342         if (!strcmp(argv[1], "all")) {
343                 print_allpids();
344         } else if (!strcmp(argv[1], "pid")) {
345                 if (argc < 3) {
346                         printk("Give me a pid number.\n");
347                         return 1;
348                 }
349                 if (argc >= 4)
350                         verbosity = strtol(argv[3], 0, 0);
351                 print_proc_info(strtol(argv[2], 0, 0), verbosity);
352         } else if (!strcmp(argv[1], "unlock")) {
353                 if (argc != 3) {
354                         printk("Gimme lock address!  Me want lock address!.\n");
355                         return 1;
356                 }
357                 spinlock_t *lock = (spinlock_t*)strtol(argv[2], 0, 16);
358                 if (!lock) {
359                         printk("Null address...\n");
360                         return 1;
361                 }
362                 spin_unlock(lock);
363         } else if (!strcmp(argv[1], "kill")) {
364                 if (argc != 3) {
365                         printk("Give me a pid number.\n");
366                         return 1;
367                 }
368                 struct proc *p = pid2proc(strtol(argv[2], 0, 0));
369                 if (!p) {
370                         printk("No such proc\n");
371                         return 1;
372                 }
373                 proc_destroy(p);
374                 proc_decref(p);
375         } else {
376                 printk("Bad option\n");
377                 return 1;
378         }
379         return 0;
380 }
381
382 int mon_pip(int argc, char **argv, struct hw_trapframe *hw_tf)
383 {
384         int verbosity = 0;
385
386         if (argc < 2) {
387                 printk("Give me a pid number.\n");
388                 return 1;
389         }
390         if (argc >= 3)
391                 verbosity = strtol(argv[2], 0, 0);
392         print_proc_info(strtol(argv[1], 0, 0), verbosity);
393         return 0;
394 }
395
396 int mon_kill(int argc, char **argv, struct hw_trapframe *hw_tf)
397 {
398         struct proc *p;
399
400         if (argc < 2) {
401                 printk("Usage: kill PID\n");
402                 return 1;
403         }
404         p = pid2proc(strtol(argv[1], 0, 0));
405         if (!p) {
406                 printk("No such proc\n");
407                 return 1;
408         }
409         p->exitcode = 1;        /* typical EXIT_FAILURE */
410         proc_destroy(p);
411         proc_decref(p);
412         return 0;
413 }
414
415 int mon_exit(int argc, char **argv, struct hw_trapframe *hw_tf)
416 {
417         return -1;
418 }
419
420 int mon_kfunc(int argc, char **argv, struct hw_trapframe *hw_tf)
421 {
422         long ret;
423         long (*func)(void *arg, ...);
424
425         if (argc < 2) {
426                 printk("Usage: kfunc FUNCTION [arg1] [arg2] [etc]\n");
427                 printk("Use 0x with hex arguments.  Can take 6 args.\n");
428                 return 1;
429         }
430         func = (void*)get_symbol_addr(argv[1]);
431         if (!func) {
432                 printk("Function not found.\n");
433                 return 1;
434         }
435         /* Not elegant, but whatever.  maybe there's a better syntax, or we can do
436          * it with asm magic. */
437         switch (argc) {
438         case 2: /* have to fake one arg */
439                 ret = func((void*)0);
440                 break;
441         case 3: /* the real first arg */
442                 ret = func((void*)strtol(argv[2], 0, 0));
443                 break;
444         case 4:
445                 ret = func((void*)strtol(argv[2], 0, 0),
446                                   strtol(argv[3], 0, 0));
447                 break;
448         case 5:
449                 ret = func((void*)strtol(argv[2], 0, 0),
450                                   strtol(argv[3], 0, 0),
451                                   strtol(argv[4], 0, 0));
452                 break;
453         case 6:
454                 ret = func((void*)strtol(argv[2], 0, 0),
455                                   strtol(argv[3], 0, 0),
456                                   strtol(argv[4], 0, 0),
457                                   strtol(argv[5], 0, 0));
458                 break;
459         case 7:
460                 ret = func((void*)strtol(argv[2], 0, 0),
461                                   strtol(argv[3], 0, 0),
462                                   strtol(argv[4], 0, 0),
463                                   strtol(argv[5], 0, 0),
464                                   strtol(argv[6], 0, 0));
465                 break;
466         case 8:
467                 ret = func((void*)strtol(argv[2], 0, 0),
468                                   strtol(argv[3], 0, 0),
469                                   strtol(argv[4], 0, 0),
470                                   strtol(argv[5], 0, 0),
471                                   strtol(argv[6], 0, 0),
472                                   strtol(argv[7], 0, 0));
473                 break;
474         default:
475                 printk("Bad number of arguments.\n");
476                 return -1;
477         }
478         printk("%s (might have) returned %p\n", argv[1], ret);
479         return 0;
480 }
481
482 /* Sending a vcoreid forces an event and an IPI/notification */
483 int mon_notify(int argc, char **argv, struct hw_trapframe *hw_tf)
484 {
485         struct proc *p;
486         uint32_t vcoreid;
487         struct event_msg msg = {0};
488
489         if (argc < 3) {
490                 printk("Usage: notify PID NUM [VCOREID]\n");
491                 return 1;
492         }
493         p = pid2proc(strtol(argv[1], 0, 0));
494         if (!p) {
495                 printk("No such proc\n");
496                 return 1;
497         }
498         msg.ev_type = strtol(argv[2], 0, 0);
499         if (argc == 4) {
500                 vcoreid = strtol(argv[3], 0, 0);
501                 /* This will go to the private mbox */
502                 post_vcore_event(p, &msg, vcoreid, EVENT_VCORE_PRIVATE);
503                 proc_notify(p, vcoreid);
504         } else {
505                 /* o/w, try and do what they want */
506                 send_kernel_event(p, &msg, 0);
507         }
508         proc_decref(p);
509         return 0;
510 }
511
512 /* Micro-benchmarky Measurements.  This is really fragile code that probably
513  * won't work perfectly, esp as the kernel evolves. */
514 int mon_measure(int argc, char **argv, struct hw_trapframe *hw_tf)
515 {
516         uint64_t begin = 0, diff = 0;
517         uint32_t end_refcnt = 0;
518
519         if (argc < 2) {
520                 printk("Usage: measure OPTION\n");
521                 printk("\tkill PID : kill proc PID\n");
522                 printk("\tpreempt PID : preempt proc PID (no delay)\n");
523                 printk("\tpreempt PID [pcore] : preempt PID's pcore (no delay)\n");
524                 printk("\tpreempt-warn PID : warn-preempt proc PID (pending)\n");
525                 printk("\tpreempt-warn PID [pcore] : warn-preempt proc PID's pcore\n");
526                 printk("\tpreempt-raw PID : raw-preempt proc PID\n");
527                 printk("\tpreempt-raw PID [pcore] : raw-preempt proc PID's pcore\n");
528                 return 1;
529         }
530         if (!strcmp(argv[1], "kill")) {
531                 if (argc < 3) {
532                         printk("Give me a pid number.\n");
533                         return 1;
534                 }
535                 struct proc *p = pid2proc(strtol(argv[2], 0, 0));
536                 if (!p) {
537                         printk("No such proc\n");
538                         return 1;
539                 }
540                 begin = start_timing();
541 #ifdef CONFIG_APPSERVER
542                 printk("Warning: this will be inaccurate due to the appserver.\n");
543                 end_refcnt = kref_refcnt(&p->p_kref) - p->procinfo->num_vcores - 1;
544 #endif /* CONFIG_APPSERVER */
545                 proc_destroy(p);
546                 proc_decref(p);
547 #ifdef CONFIG_APPSERVER
548                 /* Won't be that accurate, since it's not actually going through the
549                  * __proc_free() path. */
550                 spin_on(kref_refcnt(&p->p_kref) != end_refcnt);
551 #else
552                 /* this is a little ghetto. it's not fully free yet, but we are also
553                  * slowing it down by messing with it, esp with the busy waiting on a
554                  * hyperthreaded core. */
555                 spin_on(p->env_cr3);
556 #endif /* CONFIG_APPSERVER */
557                 /* No noticeable difference using stop_timing instead of read_tsc() */
558                 diff = stop_timing(begin);
559         } else if (!strcmp(argv[1], "preempt")) {
560                 if (argc < 3) {
561                         printk("Give me a pid number.\n");
562                         return 1;
563                 }
564                 struct proc *p = pid2proc(strtol(argv[2], 0, 0));
565                 if (!p) {
566                         printk("No such proc\n");
567                         return 1;
568                 }
569                 if (argc == 4) { /* single core being preempted, warned but no delay */
570                         uint32_t pcoreid = strtol(argv[3], 0, 0);
571                         begin = start_timing();
572                         if (proc_preempt_core(p, pcoreid, 1000000)) {
573                                 __sched_put_idle_core(p, pcoreid);
574                                 /* done when unmapped (right before abandoning) */
575                                 spin_on(p->procinfo->pcoremap[pcoreid].valid);
576                         } else {
577                                 printk("Core %d was not mapped to proc\n", pcoreid);
578                         }
579                         diff = stop_timing(begin);
580                 } else { /* preempt all cores, warned but no delay */
581                         end_refcnt = kref_refcnt(&p->p_kref) - p->procinfo->num_vcores;
582                         begin = start_timing();
583                         proc_preempt_all(p, 1000000);
584                         /* a little ghetto, implies no one is using p */
585                         spin_on(kref_refcnt(&p->p_kref) != end_refcnt);
586                         diff = stop_timing(begin);
587                 }
588                 proc_decref(p);
589         } else if (!strcmp(argv[1], "preempt-warn")) {
590                 if (argc < 3) {
591                         printk("Give me a pid number.\n");
592                         return 1;
593                 }
594                 struct proc *p = pid2proc(strtol(argv[2], 0, 0));
595                 if (!p) {
596                         printk("No such proc\n");
597                         return 1;
598                 }
599                 printk("Careful: if this hangs, then the process isn't responding.\n");
600                 if (argc == 4) { /* single core being preempted-warned */
601                         uint32_t pcoreid = strtol(argv[3], 0, 0);
602                         spin_lock(&p->proc_lock);
603                         uint32_t vcoreid = p->procinfo->pcoremap[pcoreid].vcoreid;
604                         if (!p->procinfo->pcoremap[pcoreid].valid) {
605                                 printk("Pick a mapped pcore\n");
606                                 spin_unlock(&p->proc_lock);
607                                 return 1;
608                         }
609                         begin = start_timing();
610                         __proc_preempt_warn(p, vcoreid, 1000000); // 1 sec
611                         spin_unlock(&p->proc_lock);
612                         /* done when unmapped (right before abandoning) */
613                         spin_on(p->procinfo->pcoremap[pcoreid].valid);
614                         diff = stop_timing(begin);
615                 } else { /* preempt-warn all cores */
616                         printk("Warning, this won't work if they can't yield their "
617                                "last vcore, will stop at 1!\n");
618                         spin_lock(&p->proc_lock);
619                         begin = start_timing();
620                         __proc_preempt_warnall(p, 1000000);
621                         spin_unlock(&p->proc_lock);
622                         /* target cores do the unmapping / changing of the num_vcores */
623                         spin_on(p->procinfo->num_vcores > 1);
624                         diff = stop_timing(begin);
625                 }
626                 proc_decref(p);
627         } else if (!strcmp(argv[1], "preempt-raw")) {
628                 if (argc < 3) {
629                         printk("Give me a pid number.\n");
630                         return 1;
631                 }
632                 struct proc *p = pid2proc(strtol(argv[2], 0, 0));
633                 if (!p) {
634                         printk("No such proc\n");
635                         return 1;
636                 }
637                 if (argc == 4) { /* single core preempted, no warning or waiting */
638                         uint32_t pcoreid = strtol(argv[3], 0, 0);
639                         spin_lock(&p->proc_lock);
640                         if (!p->procinfo->pcoremap[pcoreid].valid) {
641                                 printk("Pick a mapped pcore\n");
642                                 spin_unlock(&p->proc_lock);
643                                 return 1;
644                         }
645                         begin = start_timing();
646                         __proc_preempt_core(p, pcoreid);
647                         if (!p->procinfo->num_vcores)
648                                 __proc_set_state(p, PROC_RUNNABLE_M);
649                         spin_unlock(&p->proc_lock);
650                         /* ghetto, since the ksched should be calling all of this */
651                         __sched_put_idle_core(p, pcoreid);
652                         /* done when unmapped (right before abandoning) */
653                         spin_on(p->procinfo->pcoremap[pcoreid].valid);
654                         diff = stop_timing(begin);
655                 } else { /* preempt all cores, no warning or waiting */
656                         spin_lock(&p->proc_lock);
657                         uint32_t pc_arr[p->procinfo->num_vcores];
658                         uint32_t num_revoked;
659                         end_refcnt = kref_refcnt(&p->p_kref) - p->procinfo->num_vcores;
660                         begin = start_timing();
661                         num_revoked = __proc_preempt_all(p, pc_arr);
662                         __proc_set_state(p, PROC_RUNNABLE_M);
663                         spin_unlock(&p->proc_lock);
664                         if (num_revoked)
665                                 __sched_put_idle_cores(p, pc_arr, num_revoked);
666                         /* a little ghetto, implies no one else is using p */
667                         spin_on(kref_refcnt(&p->p_kref) != end_refcnt);
668                         diff = stop_timing(begin);
669                 }
670                 proc_decref(p);
671         } else {
672                 printk("Bad option\n");
673                 return 1;
674         }
675         printk("[Tired Giraffe Accent] Took %llu usec (%llu nsec) to finish.\n",
676                tsc2usec(diff), tsc2nsec(diff));
677         return 0;
678 }
679
680 static bool mon_verbose_trace = FALSE;
681 static DEFINE_PERCPU(bool, mon_nmi_trace);
682
683 static void emit_hwtf_backtrace(struct hw_trapframe *hw_tf)
684 {
685         if (mon_verbose_trace) {
686                 printk("\n");
687                 print_trapframe(hw_tf);
688                 backtrace_hwtf(hw_tf);
689         }
690         printk("Core %d is at %p (%s)\n", core_id(), get_hwtf_pc(hw_tf),
691                get_fn_name(get_hwtf_pc(hw_tf)));
692 }
693
694 static void emit_vmtf_backtrace(struct vm_trapframe *vm_tf)
695 {
696         if (mon_verbose_trace) {
697                 printk("\n");
698                 print_vmtrapframe(vm_tf);
699         }
700         printk("Core %d is at %p\n", core_id(), get_vmtf_pc(vm_tf));
701 }
702
703 /* This is dangerous and could cause a deadlock, since it runs in NMI context.
704  * It's only for monitor debugging, so YMMV.  We pass the type since the kernel
705  * doesn't deal in contexts (yet) */
706 void emit_monitor_backtrace(int type, void *tf)
707 {
708         if (!PERCPU_VAR(mon_nmi_trace))
709                 return;
710         /* To prevent a spew of output during a lot of perf NMIs, we'll turn off the
711          * monitor output as soon as any NMI hits our core. */
712         PERCPU_VAR(mon_nmi_trace) = FALSE;
713         print_lock();
714         if (type == ROS_HW_CTX)
715                 emit_hwtf_backtrace((struct hw_trapframe*)tf);
716         else
717                 emit_vmtf_backtrace((struct vm_trapframe*)tf);
718         print_kmsgs(core_id());
719         print_unlock();
720 }
721
722
723 int mon_trace(int argc, char **argv, struct hw_trapframe *hw_tf)
724 {
725         int core;
726         if (argc < 2) {
727                 printk("Usage: trace OPTION\n");
728                 printk("\tsyscall start [silent (0 or non-zero, NOT the word silent)] [pid]: starts tracing\n");
729                 printk("\tsyscall stop: stops tracing.\n");
730                 printk("\tcoretf COREID: prints PC, -1 for all cores, verbose => TF\n");
731                 printk("\tpcpui [type [coreid]]: runs pcpui trace ring handlers\n");
732                 printk("\tpcpui-reset [noclear]: resets/clears pcpui trace ring\n");
733                 printk("\tverbose: toggles verbosity, depends on trace command\n");
734                 return 1;
735         }
736         if (!strcmp(argv[1], "syscall")) {
737                 if (argc < 3) {
738                         printk("Need a start or stop.\n");
739                         return 1;
740                 }
741                 if (!strcmp(argv[2], "start")) {
742                         systrace_loud = TRUE;
743                 } else if (!strcmp(argv[2], "stop")) {
744                         systrace_loud = FALSE;
745                 } else {
746                         printk("Need a start or stop.\n");
747                         return 1;
748                 }
749         } else if (!strcmp(argv[1], "coretf")) {
750                 if (argc != 3) {
751                         printk("Need a coreid, fool.\n");
752                         return 1;
753                 }
754                 core = strtol(argv[2], 0, 0);
755                 if (core < 0) {
756                         printk("Sending NMIs to all cores:\n");
757                         for (int i = 0; i < num_cores; i++) {
758                                 _PERCPU_VAR(mon_nmi_trace, i) = TRUE;
759                                 send_nmi(i);
760                                 udelay(1000000);
761                         }
762                 } else {
763                         printk("Sending NMI core %d:\n", core);
764                         if (core >= num_cores) {
765                                 printk("No such core!  Maybe it's in another cell...\n");
766                                 return 1;
767                         }
768                         _PERCPU_VAR(mon_nmi_trace, core) = TRUE;
769                         send_nmi(core);
770                 }
771                 udelay(1000000);
772         } else if (!strcmp(argv[1], "pcpui")) {
773                 int pcpui_type, pcpui_coreid;
774                 if (argc >= 3)
775                         pcpui_type = strtol(argv[2], 0, 0);
776                 else
777                         pcpui_type = 0;
778                 printk("\nRunning PCPUI Trace Ring handlers for type %d\n", pcpui_type);
779                 if (argc >= 4) {
780                         pcpui_coreid = strtol(argv[3], 0, 0);
781                         pcpui_tr_foreach(pcpui_coreid, pcpui_type);
782                 } else {
783                         pcpui_tr_foreach_all(pcpui_type);
784                 }
785         } else if (!strcmp(argv[1], "pcpui-reset")) {
786                 if (argc >= 3) {
787                         printk("\nResetting all PCPUI Trace Rings\n");
788                         pcpui_tr_reset_all();
789                 } else {
790                         printk("\nResetting and clearing all PCPUI Trace Rings\n");
791                         pcpui_tr_reset_and_clear_all();
792                 }
793         } else if (!strcmp(argv[1], "verbose")) {
794                 if (mon_verbose_trace) {
795                         printk("Turning trace verbosity off\n");
796                         mon_verbose_trace = FALSE;
797                 } else {
798                         printk("Turning trace verbosity on\n");
799                         mon_verbose_trace = TRUE;
800                 }
801         } else if (!strcmp(argv[1], "opt2")) {
802                 if (argc != 3) {
803                         printk("ERRRRRRRRRR.\n");
804                         return 1;
805                 }
806                 print_proc_info(strtol(argv[2], 0, 0), 0);
807         } else {
808                 printk("Bad option\n");
809                 return 1;
810         }
811         return 0;
812 }
813
814 int mon_monitor(int argc, char **argv, struct hw_trapframe *hw_tf)
815 {
816         if (argc < 2) {
817                 printk("Usage: monitor COREID\n");
818                 return 1;
819         }
820         uint32_t core = strtol(argv[1], 0, 0);
821         if (core >= num_cores) {
822                 printk("No such core!  Maybe it's in another cell...\n");
823                 return 1;
824         }
825         send_kernel_message(core, __run_mon, 0, 0, 0, KMSG_ROUTINE);
826         return 0;
827 }
828
829 /***** Kernel monitor command interpreter *****/
830
831 #define WHITESPACE "\t\r\n "
832 #define MAXARGS 16
833
834
835 int onecmd(int argc, char *argv[], struct hw_trapframe *hw_tf) {
836         int i;
837         if (!argc)
838                 return -1;
839         for (i = 0; i < NCOMMANDS; i++) {
840                 if (strcmp(argv[0], commands[i].name) == 0)
841                         return commands[i].func(argc, argv, hw_tf);
842         }
843         return -1;
844 }
845
846 void __run_mon(uint32_t srcid, long a0, long a1, long a2)
847 {
848         monitor(0);
849 }
850
851 static int runcmd(char *real_buf, struct hw_trapframe *hw_tf) {
852         char * buf = real_buf;
853         int argc;
854         char *argv[MAXARGS];
855         int i;
856
857         // Parse the command buffer into whitespace-separated arguments
858         argc = 0;
859         argv[argc] = 0;
860         /* Discard initial 'm ', which is a common mistake when using 'm' a lot */
861         if ((buf[0] == 'm') && (buf[1] == ' '))
862                 buf += 2;
863         while (1) {
864                 // gobble whitespace
865                 while (*buf && strchr(WHITESPACE, *buf))
866                         *buf++ = 0;
867                 if (*buf == 0)
868                         break;
869
870                 // save and scan past next arg
871                 if (argc == MAXARGS-1) {
872                         cprintf("Too many arguments (max %d)\n", MAXARGS);
873                         return 0;
874                 }
875                 //This will get fucked at runtime..... in the ASS
876                 argv[argc++] = buf;
877                 while (*buf && !strchr(WHITESPACE, *buf))
878                         buf++;
879         }
880         argv[argc] = 0;
881
882         // Lookup and invoke the command
883         if (argc == 0)
884                 return 0;
885         for (i = 0; i < NCOMMANDS; i++) {
886                 if (strcmp(argv[0], commands[i].name) == 0)
887                         return commands[i].func(argc, argv, hw_tf);
888         }
889         cprintf("Unknown command '%s'\n", argv[0]);
890         return 0;
891 }
892
893 void monitor(struct hw_trapframe *hw_tf)
894 {
895         #define MON_CMD_LENGTH 256
896         char buf[MON_CMD_LENGTH];
897         int cnt;
898         int coreid = core_id_early();
899
900         /* they are always disabled, since we have this irqsave lock */
901         if (irq_is_enabled())
902                 printk("Entering Nanwan's Dungeon on Core %d (Ints on):\n", coreid);
903         else
904                 printk("Entering Nanwan's Dungeon on Core %d (Ints off):\n", coreid);
905         printk("Type 'help' for a list of commands.\n");
906
907         if (hw_tf != NULL)
908                 print_trapframe(hw_tf);
909
910         while (1) {
911                 /* on occasion, the kernel monitor can migrate (like if you run
912                  * something that blocks / syncs and wakes up on another core) */
913                 cmb();
914                 cnt = readline(buf, MON_CMD_LENGTH, "ROS(Core %d)> ", core_id_early());
915                 if (cnt > 0) {
916                         buf[cnt] = 0;
917                         if (runcmd(buf, hw_tf) < 0)
918                                 break;
919                 }
920         }
921 }
922
923 int mon_shell(int argc, char **argv, struct hw_trapframe *hw_tf)
924 {
925         char *l_argv[2] = {"/bin/bash", "bash"};
926         return mon_bin_run(2, l_argv, hw_tf);
927 }
928
929 int mon_alarm(int argc, char **argv, struct hw_trapframe *hw_tf)
930 {
931         if (argc < 2) {
932                 printk("Usage: alarm OPTION\n");
933                 printk("\tpcpu: print full alarm tchains from every core\n");
934                 return 1;
935         }
936         if (!strcmp(argv[1], "pcpu")) {
937                 print_pcpu_chains();
938         } else {
939                 printk("Bad option\n");
940                 return 1;
941         }
942         return 0;
943 }
944
945 static void show_msr(struct hw_trapframe *unused, void *v)
946 {
947         int core = core_id();
948         uint64_t val;
949         uint32_t msr = *(uint32_t *)v;
950         val = read_msr(msr);
951         printk("%d: %08x: %016llx\n", core, msr, val);
952 }
953
954 struct set {
955         uint32_t msr;
956         uint64_t val;
957 };
958
959 static void set_msr(struct hw_trapframe *unused, void *v)
960 {
961         int core = core_id();
962         struct set *s = v;
963         uint32_t msr = s->msr;
964         uint64_t val = s->val;
965         write_msr(msr, val);
966         val = read_msr(msr);
967         printk("%d: %08x: %016llx\n", core, msr, val);
968 }
969
970 int mon_msr(int argc, char **argv, struct hw_trapframe *hw_tf)
971 {
972 #ifndef CONFIG_X86
973         cprintf("Not on this architecture\n");
974         return 1;
975 #else
976         uint64_t val;
977         uint32_t msr;
978         if (argc < 2 || argc > 3) {
979                 printk("Usage: msr register [value]\n");
980                 return 1;
981         }
982         msr = strtoul(argv[1], 0, 16);
983         handler_wrapper_t *w;
984         smp_call_function_all(show_msr, &msr, &w);
985         smp_call_wait(w);
986
987         if (argc < 3)
988                 return 0;
989         /* somewhat bogus on 32 bit. */
990         val = strtoul(argv[2], 0, 16);
991
992         struct set set;
993         set.msr = msr;
994         set.val = val;
995         smp_call_function_all(set_msr, &set, &w);
996         smp_call_wait(w);
997         return 0;
998 #endif
999 }
1000
1001 int mon_db(int argc, char **argv, struct hw_trapframe *hw_tf)
1002 {
1003         pid_t pid = -1;
1004
1005         if (argc < 2) {
1006                 printk("Usage: db OPTION\n");
1007                 printk("\tsem [PID]: print all semaphore info\n");
1008                 printk("\taddr PID 0xADDR: for PID lookup ADDR's file/vmr info\n");
1009                 return 1;
1010         }
1011         if (!strcmp(argv[1], "sem")) {
1012                 if (argc > 2)
1013                         pid = strtol(argv[2], 0, 0);
1014                 print_all_sem_info(pid);
1015         } else if (!strcmp(argv[1], "addr")) {
1016                 if (argc < 4) {
1017                         printk("Usage: db addr PID 0xADDR\n");
1018                         return 1;
1019                 }
1020                 debug_addr_pid(strtol(argv[2], 0, 10), strtol(argv[3], 0, 16));
1021         } else {
1022                 printk("Bad option\n");
1023                 return 1;
1024         }
1025         return 0;
1026 }
1027
1028 int mon_px(int argc, char **argv, struct hw_trapframe *hw_tf)
1029 {
1030         pid_t pid = 0;
1031         struct proc *p;
1032
1033         if (argc == 2)
1034                 pid = strtol(argv[1], 0, 0);
1035         if (!pid) {
1036                 set_printx(2);
1037                 printk("Printxing is now %sabled\n", printx_on ? "en" : "dis");
1038                 return 0;
1039         }
1040         p = pid2proc(pid);
1041         if (!p) {
1042                 printk("No proc with pid %d\n", pid);
1043                 return 1;
1044         }
1045         p->procdata->printx_on = !p->procdata->printx_on;
1046         proc_decref(p);
1047         return 0;
1048 }
1049
1050 /* Super hack.  Given a kernel hw_tf, we hack the RIP to smp_idle, then return
1051  * to it.  Any locks or other stuff being done is completely lost, so you could
1052  * deadlock.  This gets out of the "we're totall screwed, but don't want to
1053  * reboot right now", typically caused by screw-ups from the monitor. */
1054 int mon_kpfret(int argc, char **argv, struct hw_trapframe *hw_tf)
1055 {
1056         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
1057
1058         /* if monitor had a TF, try to use that */
1059         if (!hw_tf) {
1060                 if (argc < 2) {
1061                         printk("Usage: kpfret HW_TF\n");
1062                         return 1;
1063                 }
1064                 /* the hw_tf passed in is the one we got from monitor, which is 0 from
1065                  * panics. */
1066                 hw_tf = (struct hw_trapframe*)strtol(argv[1], 0, 16);
1067         }
1068
1069         if (!in_kernel(hw_tf)) {
1070                 printk("hw_tf %p was not a kernel tf!\n", hw_tf);
1071                 return -1;
1072         }
1073
1074 #ifdef CONFIG_X86
1075         hw_tf->tf_rip = (uintptr_t)smp_idle;
1076         dec_ktrap_depth(pcpui);
1077
1078         asm volatile("mov %0, %%rsp;"
1079                      "addq $0x10, %%rsp;"
1080                      "popq %%rax;"
1081                      "popq %%rbx;"
1082                      "popq %%rcx;"
1083                      "popq %%rdx;"
1084                      "popq %%rbp;"
1085                      "popq %%rsi;"
1086                      "popq %%rdi;"
1087                      "popq %%r8;"
1088                      "popq %%r9;"
1089                      "popq %%r10;"
1090                      "popq %%r11;"
1091                      "popq %%r12;"
1092                      "popq %%r13;"
1093                      "popq %%r14;"
1094                      "popq %%r15;"
1095                      "addq $0x10, %%rsp;"
1096                      "iretq;"
1097                                  : : "r"(hw_tf));
1098         assert(0);
1099 #else
1100         printk("KPF return not supported\n");
1101         return -1;
1102 #endif /* CONFIG_X86 */
1103 }
1104
1105 int mon_ks(int argc, char **argv, struct hw_trapframe *hw_tf)
1106 {
1107         if (argc < 2) {
1108 usage:
1109                 printk("Usage: ks OPTION\n");
1110                 printk("\tidles: show idle core map\n");
1111                 printk("\tdiag: scheduler diagnostic report\n");
1112                 printk("\tresources: show resources wanted/granted for all procs\n");
1113                 printk("\tsort: sorts the idlecoremap, 1..n\n");
1114                 printk("\tnc PCOREID: sets the next CG core allocated\n");
1115                 return 1;
1116         }
1117         if (!strcmp(argv[1], "idles")) {
1118                 print_idle_core_map();
1119         } else if (!strcmp(argv[1], "diag")) {
1120                 sched_diag();
1121         } else if (!strcmp(argv[1], "resources")) {
1122                 print_all_resources();
1123         } else if (!strcmp(argv[1], "sort")) {
1124                 sort_idle_cores();
1125         } else if (!strcmp(argv[1], "nc")) {
1126                 if (argc != 3) {
1127                         printk("Need a pcore number.\n");
1128                         return 1;
1129                 }
1130                 next_core_to_alloc(strtol(argv[2], 0, 0));
1131         } else {
1132                 printk("Bad option %s\n", argv[1]);
1133                 goto usage;
1134         }
1135         return 0;
1136 }
1137
1138 /* Prints info about a core.  Optional first arg == coreid. */
1139 int mon_coreinfo(int argc, char **argv, struct hw_trapframe *hw_tf)
1140 {
1141         struct per_cpu_info *pcpui;
1142         struct kthread *kth;
1143         int coreid = core_id();
1144
1145         if (argc >= 2)
1146                 coreid = strtol(argv[1], 0, 0);
1147         pcpui = &per_cpu_info[coreid];
1148         printk("Core %d:\n\tcur_proc %d\n\towning proc %d, owning vc %d\n",
1149                coreid, pcpui->cur_proc ? pcpui->cur_proc->pid : 0,
1150                pcpui->owning_proc ? pcpui->owning_proc->pid : 0,
1151                pcpui->owning_vcoreid != 0xdeadbeef ? pcpui->owning_vcoreid : 0);
1152         kth = pcpui->cur_kthread;
1153         if (kth) {
1154                 /* kth->proc is only used when the kthread is sleeping.  when it's
1155                  * running, we care about cur_proc.  if we're here, proc should be 0
1156                  * unless the kth is concurrently sleeping (we called this remotely) */
1157                 printk("\tkthread %p (%s), sysc %p (%d)\n", kth, kth->name,
1158                        kth->sysc, kth->sysc ? kth->sysc->num : -1);
1159         } else {
1160                 /* Can happen during early boot */
1161                 printk("\tNo kthread!\n");
1162         }
1163         return 0;
1164 }
1165
1166 int mon_hexdump(int argc, char **argv, struct hw_trapframe *hw_tf)
1167 {
1168         struct proc *p = NULL;
1169         uintptr_t switch_state;
1170         pid_t pid;
1171         uintptr_t start;
1172         size_t len;
1173
1174         assert(argc >= 1);
1175         if (argc < 4) {
1176                 printk("Usage: %s PID ADDR LEN\n", argv[0]);
1177                 printk("    PID == 0 for kernel / don't care\n");
1178                 return 1;
1179         }
1180         pid = strtol(argv[1], 0, 0);
1181         start = strtoul(argv[2], 0, 0);
1182         len = strtoul(argv[3], 0, 0);
1183         if (pid) {
1184                 p = pid2proc(pid);
1185                 if (!p) {
1186                         printk("No proc with pid %d\n", pid);
1187                         return 1;
1188                 }
1189                 switch_state = switch_to(p);
1190         }
1191         hexdump((void*)start, len);
1192         if (p) {
1193                 switch_back(p, switch_state);
1194                 proc_decref(p);
1195         }
1196         return 0;
1197 }
1198
1199 int mon_pahexdump(int argc, char **argv, struct hw_trapframe *hw_tf)
1200 {
1201         uintptr_t start;
1202         size_t len;
1203
1204         assert(argc >= 1);
1205         if (argc < 3) {
1206                 printk("Usage: %s PHYS_ADDR LEN\n", argv[0]);
1207                 return 1;
1208         }
1209         start = strtoul(argv[1], 0, 0);
1210         len = strtoul(argv[2], 0, 0);
1211         pahexdump(start, len);
1212         return 0;
1213 }