getfl and setfl for 9ns
[akaros.git] / kern / src / syscall.c
1 /* See COPYRIGHT for copyright information. */
2
3 #ifdef __SHARC__
4 #pragma nosharc
5 #endif
6
7 //#define DEBUG
8 #include <ros/common.h>
9 #include <arch/types.h>
10 #include <arch/arch.h>
11 #include <arch/mmu.h>
12 #include <arch/console.h>
13 #include <time.h>
14 #include <error.h>
15
16 #include <elf.h>
17 #include <string.h>
18 #include <assert.h>
19 #include <process.h>
20 #include <schedule.h>
21 #include <pmap.h>
22 #include <umem.h>
23 #include <mm.h>
24 #include <trap.h>
25 #include <syscall.h>
26 #include <kmalloc.h>
27 #include <stdio.h>
28 #include <frontend.h>
29 #include <colored_caches.h>
30 #include <hashtable.h>
31 #include <bitmask.h>
32 #include <vfs.h>
33 #include <devfs.h>
34 #include <smp.h>
35 #include <arsc_server.h>
36 #include <event.h>
37 #include <termios.h>
38
39 /* Tracing Globals */
40 int systrace_flags = 0;
41 struct systrace_record *systrace_buffer = 0;
42 uint32_t systrace_bufidx = 0;
43 size_t systrace_bufsize = 0;
44 struct proc *systrace_procs[MAX_NUM_TRACED] = {0};
45 spinlock_t systrace_lock = SPINLOCK_INITIALIZER_IRQSAVE;
46
47 /* Not enforcing the packing of systrace_procs yet, but don't rely on that */
48 static bool proc_is_traced(struct proc *p)
49 {
50         for (int i = 0; i < MAX_NUM_TRACED; i++)
51                 if (systrace_procs[i] == p)
52                         return true;
53         return false;
54 }
55
56 /* Helper to finish a syscall, signalling if appropriate */
57 static void finish_sysc(struct syscall *sysc, struct proc *p)
58 {
59         /* Atomically turn on the LOCK and SC_DONE flag.  The lock tells userspace
60          * we're messing with the flags and to not proceed.  We use it instead of
61          * CASing with userspace.  We need the atomics since we're racing with
62          * userspace for the event_queue registration.  The 'lock' tells userspace
63          * to not muck with the flags while we're signalling. */
64         atomic_or(&sysc->flags, SC_K_LOCK | SC_DONE);
65         __signal_syscall(sysc, p);
66         atomic_and(&sysc->flags, ~SC_K_LOCK); 
67 }
68
69 /* Helper that "finishes" the current async syscall.  This should be used with
70  * care when we are not using the normal syscall completion path.
71  *
72  * Do *NOT* complete the same syscall twice.  This is catastrophic for _Ms, and
73  * a bad idea for _S.
74  *
75  * It is possible for another user thread to see the syscall being done early -
76  * they just need to be careful with the weird proc management calls (as in,
77  * don't trust an async fork).
78  *
79  * *sysc is in user memory, and should be pinned (TODO: UMEM).  There may be
80  * issues with unpinning this if we never return. */
81 static void finish_current_sysc(int retval)
82 {
83         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
84         assert(pcpui->cur_kthread->sysc);
85         pcpui->cur_kthread->sysc->retval = retval;
86         finish_sysc(pcpui->cur_kthread->sysc, pcpui->cur_proc);
87 }
88
89 /* Callable by any function while executing a syscall (or otherwise, actually).
90  */
91 void set_errno(int errno)
92 {
93         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
94         if (pcpui->cur_kthread && pcpui->cur_kthread->sysc)
95                 pcpui->cur_kthread->sysc->err = errno;
96 }
97
98 void unset_errno(void)
99 {
100         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
101         if (!pcpui->cur_kthread || !pcpui->cur_kthread->sysc)
102                 return;
103         pcpui->cur_kthread->sysc->err = 0;
104         pcpui->cur_kthread->sysc->errstr[0] = '\0';
105 }
106
107 void set_errstr(char *fmt, ...)
108 {
109         va_list ap;
110         int rc;
111
112         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
113         if (!pcpui->cur_kthread || !pcpui->cur_kthread->sysc)
114                 return;
115
116         va_start(ap, fmt);
117         rc = vsnprintf(pcpui->cur_kthread->sysc->errstr, MAX_ERRSTR_LEN, fmt, ap);
118         va_end(ap);
119
120         /* TODO: likely not needed */
121         pcpui->cur_kthread->sysc->errstr[MAX_ERRSTR_LEN - 1] = '\0';
122 }
123
124 char *current_errstr(void)
125 {
126         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
127         if (!pcpui->cur_kthread || !pcpui->cur_kthread->sysc)
128                 return "no errstr";
129         return pcpui->cur_kthread->sysc->errstr;
130 }
131
132 struct errbuf *get_cur_errbuf(void)
133 {
134         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
135         return (struct errbuf*)pcpui->cur_kthread->errbuf;
136 }
137
138 void set_cur_errbuf(struct errbuf *ebuf)
139 {
140         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
141         pcpui->cur_kthread->errbuf = ebuf;
142 }
143
144 char *get_cur_genbuf(void)
145 {
146         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
147         assert(pcpui->cur_kthread);
148         return pcpui->cur_kthread->generic_buf;
149 }
150
151 /************** Utility Syscalls **************/
152
153 static int sys_null(void)
154 {
155         return 0;
156 }
157
158 /* Diagnostic function: blocks the kthread/syscall, to help userspace test its
159  * async I/O handling. */
160 static int sys_block(struct proc *p, unsigned int usec)
161 {
162         struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
163         struct alarm_waiter a_waiter;
164         init_awaiter(&a_waiter, 0);
165         /* Note printing takes a few ms, so your printds won't be perfect. */
166         printd("[kernel] sys_block(), sleeping at %llu\n", read_tsc());
167         set_awaiter_rel(&a_waiter, usec);
168         set_alarm(tchain, &a_waiter);
169         sleep_on_awaiter(&a_waiter);
170         printd("[kernel] sys_block(), waking up at %llu\n", read_tsc());
171         return 0;
172 }
173
174 // Writes 'val' to 'num_writes' entries of the well-known array in the kernel
175 // address space.  It's just #defined to be some random 4MB chunk (which ought
176 // to be boot_alloced or something).  Meant to grab exclusive access to cache
177 // lines, to simulate doing something useful.
178 static int sys_cache_buster(struct proc *p, uint32_t num_writes,
179                              uint32_t num_pages, uint32_t flags)
180 {
181         #define BUSTER_ADDR             0xd0000000L  // around 512 MB deep
182         #define MAX_WRITES              1048576*8
183         #define MAX_PAGES               32
184         #define INSERT_ADDR     (UINFO + 2*PGSIZE) // should be free for these tests
185         uint32_t* buster = (uint32_t*)BUSTER_ADDR;
186         static spinlock_t buster_lock = SPINLOCK_INITIALIZER;
187         uint64_t ticks = -1;
188         page_t* a_page[MAX_PAGES];
189
190         /* Strided Accesses or Not (adjust to step by cachelines) */
191         uint32_t stride = 1;
192         if (flags & BUSTER_STRIDED) {
193                 stride = 16;
194                 num_writes *= 16;
195         }
196
197         /* Shared Accesses or Not (adjust to use per-core regions)
198          * Careful, since this gives 8MB to each core, starting around 512MB.
199          * Also, doesn't separate memory for core 0 if it's an async call.
200          */
201         if (!(flags & BUSTER_SHARED))
202                 buster = (uint32_t*)(BUSTER_ADDR + core_id() * 0x00800000);
203
204         /* Start the timer, if we're asked to print this info*/
205         if (flags & BUSTER_PRINT_TICKS)
206                 ticks = start_timing();
207
208         /* Allocate num_pages (up to MAX_PAGES), to simulate doing some more
209          * realistic work.  Note we don't write to these pages, even if we pick
210          * unshared.  Mostly due to the inconvenience of having to match up the
211          * number of pages with the number of writes.  And it's unnecessary.
212          */
213         if (num_pages) {
214                 spin_lock(&buster_lock);
215                 for (int i = 0; i < MIN(num_pages, MAX_PAGES); i++) {
216                         upage_alloc(p, &a_page[i],1);
217                         page_insert(p->env_pgdir, a_page[i], (void*)INSERT_ADDR + PGSIZE*i,
218                                     PTE_USER_RW);
219                         page_decref(a_page[i]);
220                 }
221                 spin_unlock(&buster_lock);
222         }
223
224         if (flags & BUSTER_LOCKED)
225                 spin_lock(&buster_lock);
226         for (int i = 0; i < MIN(num_writes, MAX_WRITES); i=i+stride)
227                 buster[i] = 0xdeadbeef;
228         if (flags & BUSTER_LOCKED)
229                 spin_unlock(&buster_lock);
230
231         if (num_pages) {
232                 spin_lock(&buster_lock);
233                 for (int i = 0; i < MIN(num_pages, MAX_PAGES); i++) {
234                         page_remove(p->env_pgdir, (void*)(INSERT_ADDR + PGSIZE * i));
235                         page_decref(a_page[i]);
236                 }
237                 spin_unlock(&buster_lock);
238         }
239
240         /* Print info */
241         if (flags & BUSTER_PRINT_TICKS) {
242                 ticks = stop_timing(ticks);
243                 printk("%llu,", ticks);
244         }
245         return 0;
246 }
247
248 static int sys_cache_invalidate(void)
249 {
250         #ifdef CONFIG_X86
251                 wbinvd();
252         #endif
253         return 0;
254 }
255
256 /* sys_reboot(): called directly from dispatch table. */
257
258 /* Print a string to the system console. */
259 static ssize_t sys_cputs(struct proc *p, const char *DANGEROUS string,
260                          size_t strlen)
261 {
262         char *t_string;
263         t_string = user_strdup_errno(p, string, strlen);
264         if (!t_string)
265                 return -1;
266         printk("%.*s", strlen, t_string);
267         user_memdup_free(p, t_string);
268         return (ssize_t)strlen;
269 }
270
271 // Read a character from the system console.
272 // Returns the character.
273 /* TODO: remove me */
274 static uint16_t sys_cgetc(struct proc *p)
275 {
276         uint16_t c;
277
278         // The cons_get_any_char() primitive doesn't wait for a character,
279         // but the sys_cgetc() system call does.
280         while ((c = cons_get_any_char()) == 0)
281                 cpu_relax();
282
283         return c;
284 }
285
286 /* Returns the id of the physical core this syscall is executed on. */
287 static uint32_t sys_getpcoreid(void)
288 {
289         return core_id();
290 }
291
292 // TODO: Temporary hack until thread-local storage is implemented on i386 and
293 // this is removed from the user interface
294 static size_t sys_getvcoreid(struct proc *p)
295 {
296         return proc_get_vcoreid(p);
297 }
298
299 /************** Process management syscalls **************/
300
301 /* Returns the calling process's pid */
302 static pid_t sys_getpid(struct proc *p)
303 {
304         return p->pid;
305 }
306
307 /* Creates a process from the file 'path'.  The process is not runnable by
308  * default, so it needs it's status to be changed so that the next call to
309  * schedule() will try to run it.  TODO: take args/envs from userspace. */
310 static int sys_proc_create(struct proc *p, char *path, size_t path_l,
311                            struct procinfo *pi)
312 {
313         int pid = 0;
314         char *t_path;
315         struct file *program;
316         struct proc *new_p;
317
318         /* Copy in the path.  Consider putting an upper bound on path_l. */
319         t_path = user_strdup_errno(p, path, path_l);
320         if (!t_path)
321                 return -1;
322         /* TODO: 9ns support */
323         program = do_file_open(t_path, 0, 0);
324         user_memdup_free(p, t_path);
325         if (!program)
326                 return -1;                      /* presumably, errno is already set */
327         /* TODO: need to split the proc creation, since you must load after setting
328          * args/env, since auxp gets set up there. */
329         //new_p = proc_create(program, 0, 0);
330         if (proc_alloc(&new_p, current))
331                 goto mid_error;
332         /* Set the argument stuff needed by glibc */
333         if (memcpy_from_user_errno(p, new_p->procinfo->argp, pi->argp,
334                                    sizeof(pi->argp)))
335                 goto late_error;
336         if (memcpy_from_user_errno(p, new_p->procinfo->argbuf, pi->argbuf,
337                                    sizeof(pi->argbuf)))
338                 goto late_error;
339         if (load_elf(new_p, program))
340                 goto late_error;
341         kref_put(&program->f_kref);
342         /* Connect to stdin, stdout, stderr (part of proc_create()) */
343         assert(insert_file(&new_p->open_files, dev_stdin,  0) == 0);
344         assert(insert_file(&new_p->open_files, dev_stdout, 0) == 1);
345         assert(insert_file(&new_p->open_files, dev_stderr, 0) == 2);
346         __proc_ready(new_p);
347         pid = new_p->pid;
348         proc_decref(new_p);     /* give up the reference created in proc_create() */
349         return pid;
350 late_error:
351         proc_destroy(new_p);
352         proc_decref(new_p);     /* give up the reference created in proc_create() */
353 mid_error:
354         kref_put(&program->f_kref);
355         return -1;
356 }
357
358 /* Makes process PID runnable.  Consider moving the functionality to process.c */
359 static error_t sys_proc_run(struct proc *p, unsigned pid)
360 {
361         struct proc *target = pid2proc(pid);
362         error_t retval = 0;
363
364         if (!target) {
365                 set_errno(ESRCH);
366                 return -1;
367         }
368         /* make sure we have access and it's in the right state to be activated */
369         if (!proc_controls(p, target)) {
370                 set_errno(EPERM);
371                 goto out_error;
372         } else if (target->state != PROC_CREATED) {
373                 set_errno(EINVAL);
374                 goto out_error;
375         }
376         /* Note a proc can spam this for someone it controls.  Seems safe - if it
377          * isn't we can change it. */
378         proc_wakeup(target);
379         proc_decref(target);
380         return 0;
381 out_error:
382         proc_decref(target);
383         return -1;
384 }
385
386 /* Destroy proc pid.  If this is called by the dying process, it will never
387  * return.  o/w it will return 0 on success, or an error.  Errors include:
388  * - ESRCH: if there is no such process with pid
389  * - EPERM: if caller does not control pid */
390 static error_t sys_proc_destroy(struct proc *p, pid_t pid, int exitcode)
391 {
392         error_t r;
393         struct proc *p_to_die = pid2proc(pid);
394
395         if (!p_to_die) {
396                 set_errno(ESRCH);
397                 return -1;
398         }
399         if (!proc_controls(p, p_to_die)) {
400                 proc_decref(p_to_die);
401                 set_errno(EPERM);
402                 return -1;
403         }
404         if (p_to_die == p) {
405                 p->exitcode = exitcode;
406                 printd("[PID %d] proc exiting gracefully (code %d)\n", p->pid,exitcode);
407         } else {
408                 p_to_die->exitcode = exitcode;  /* so its parent has some clue */
409                 printd("[%d] destroying proc %d\n", p->pid, p_to_die->pid);
410         }
411         proc_destroy(p_to_die);
412         /* we only get here if we weren't the one to die */
413         proc_decref(p_to_die);
414         return 0;
415 }
416
417 static int sys_proc_yield(struct proc *p, bool being_nice)
418 {
419         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
420         /* proc_yield() often doesn't return - we need to set the syscall retval
421          * early.  If it doesn't return, it expects to eat our reference (for now).
422          */
423         finish_sysc(pcpui->cur_kthread->sysc, pcpui->cur_proc);
424         pcpui->cur_kthread->sysc = 0;   /* don't touch sysc again */
425         proc_incref(p, 1);
426         proc_yield(p, being_nice);
427         proc_decref(p);
428         /* Shouldn't return, to prevent the chance of mucking with cur_sysc. */
429         smp_idle();
430         assert(0);
431 }
432
433 static int sys_change_vcore(struct proc *p, uint32_t vcoreid,
434                              bool enable_my_notif)
435 {
436         /* Note retvals can be negative, but we don't mess with errno in case
437          * callers use this in low-level code and want to extract the 'errno'. */
438         return proc_change_to_vcore(p, vcoreid, enable_my_notif);
439 }
440
441 static ssize_t sys_fork(env_t* e)
442 {
443         struct proc *temp;
444         int8_t state = 0;
445         int ret;
446
447         // TODO: right now we only support fork for single-core processes
448         if (e->state != PROC_RUNNING_S) {
449                 set_errno(EINVAL);
450                 return -1;
451         }
452         env_t* env;
453         assert(!proc_alloc(&env, current));
454         assert(env != NULL);
455
456         env->heap_top = e->heap_top;
457         env->ppid = e->pid;
458         disable_irqsave(&state);        /* protect cur_ctx */
459         /* Can't really fork if we don't have a current_ctx to fork */
460         if (!current_ctx) {
461                 set_errno(EINVAL);
462                 return -1;
463         }
464         env->scp_ctx = *current_ctx;
465         enable_irqsave(&state);
466
467         env->cache_colors_map = cache_colors_map_alloc();
468         for(int i=0; i < llc_cache->num_colors; i++)
469                 if(GET_BITMASK_BIT(e->cache_colors_map,i))
470                         cache_color_alloc(llc_cache, env->cache_colors_map);
471
472         /* Make the new process have the same VMRs as the older.  This will copy the
473          * contents of non MAP_SHARED pages to the new VMRs. */
474         if (duplicate_vmrs(e, env)) {
475                 proc_destroy(env);      /* this is prob what you want, not decref by 2 */
476                 proc_decref(env);
477                 set_errno(ENOMEM);
478                 return -1;
479         }
480         /* Switch to the new proc's address space and finish the syscall.  We'll
481          * never naturally finish this syscall for the new proc, since its memory
482          * is cloned before we return for the original process.  If we ever do CoW
483          * for forked memory, this will be the first place that gets CoW'd. */
484         temp = switch_to(env);
485         finish_current_sysc(0);
486         switch_back(env, temp);
487
488         /* In general, a forked process should be a fresh process, and we copy over
489          * whatever stuff is needed between procinfo/procdata. */
490         /* Copy over the procinfo argument stuff in case they don't exec */
491         memcpy(env->procinfo->argp, e->procinfo->argp, sizeof(e->procinfo->argp));
492         memcpy(env->procinfo->argbuf, e->procinfo->argbuf,
493                sizeof(e->procinfo->argbuf));
494         #ifdef CONFIG_X86
495         /* new guy needs to know about ldt (everything else in procdata is fresh */
496         env->procdata->ldt = e->procdata->ldt;
497         #endif
498
499         clone_files(&e->open_files, &env->open_files);
500         /* FYI: once we call ready, the proc is open for concurrent usage */
501         __proc_ready(env);
502         proc_wakeup(env);
503
504         // don't decref the new process.
505         // that will happen when the parent waits for it.
506         // TODO: if the parent doesn't wait, we need to change the child's parent
507         // when the parent dies, or at least decref it
508
509         printd("[PID %d] fork PID %d\n", e->pid, env->pid);
510         ret = env->pid;
511         proc_decref(env);       /* give up the reference created in proc_alloc() */
512         return ret;
513 }
514
515 /* Load the binary "path" into the current process, and start executing it.
516  * argv and envp are magically bundled in procinfo for now.  Keep in sync with
517  * glibc's sysdeps/ros/execve.c.  Once past a certain point, this function won't
518  * return.  It assumes (and checks) that it is current.  Don't give it an extra
519  * refcnt'd *p (syscall won't do that). 
520  * Note: if someone batched syscalls with this call, they could clobber their
521  * old memory (and will likely PF and die).  Don't do it... */
522 static int sys_exec(struct proc *p, char *path, size_t path_l,
523                     struct procinfo *pi)
524 {
525         int ret = -1;
526         char *t_path;
527         struct file *program;
528         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
529         int8_t state = 0;
530
531         /* We probably want it to never be allowed to exec if it ever was _M */
532         if (p->state != PROC_RUNNING_S) {
533                 set_errno(EINVAL);
534                 return -1;
535         }
536         if (p != pcpui->cur_proc) {
537                 set_errno(EINVAL);
538                 return -1;
539         }
540         /* Copy in the path.  Consider putting an upper bound on path_l. */
541         t_path = user_strdup_errno(p, path, path_l);
542         if (!t_path)
543                 return -1;
544         disable_irqsave(&state);        /* protect cur_ctx */
545         /* Can't exec if we don't have a current_ctx to restart (if we fail).  This
546          * isn't 100% true, but I'm okay with it. */
547         if (!pcpui->cur_ctx) {
548                 enable_irqsave(&state);
549                 set_errno(EINVAL);
550                 return -1;
551         }
552         /* Preemptively copy out the cur_ctx, in case we fail later (easier on
553          * cur_ctx if we do this now) */
554         p->scp_ctx = *pcpui->cur_ctx;
555         /* Clear the current_ctx.  We won't be returning the 'normal' way.  Even if
556          * we want to return with an error, we need to go back differently in case
557          * we succeed.  This needs to be done before we could possibly block, but
558          * unfortunately happens before the point of no return. */
559         pcpui->cur_ctx = 0;
560         enable_irqsave(&state);
561         /* This could block: */
562         /* TODO: 9ns support */
563         program = do_file_open(t_path, 0, 0);
564         user_memdup_free(p, t_path);
565         if (!program)
566                 goto early_error;
567         /* Set the argument stuff needed by glibc */
568         if (memcpy_from_user_errno(p, p->procinfo->argp, pi->argp,
569                                    sizeof(pi->argp)))
570                 goto mid_error;
571         if (memcpy_from_user_errno(p, p->procinfo->argbuf, pi->argbuf,
572                                    sizeof(pi->argbuf)))
573                 goto mid_error;
574         /* This is the point of no return for the process. */
575         #ifdef CONFIG_X86
576         /* clear this, so the new program knows to get an LDT */
577         p->procdata->ldt = 0;
578         #endif
579         /* When we destroy our memory regions, accessing cur_sysc would PF */
580         pcpui->cur_kthread->sysc = 0;
581         unmap_and_destroy_vmrs(p);
582         close_9ns_files(p, TRUE);
583         close_all_files(&p->open_files, TRUE);
584         env_user_mem_free(p, 0, UMAPTOP);
585         if (load_elf(p, program)) {
586                 kref_put(&program->f_kref);
587                 /* Note this is an inedible reference, but proc_destroy now returns */
588                 proc_destroy(p);
589                 /* We don't want to do anything else - we just need to not accidentally
590                  * return to the user (hence the all_out) */
591                 goto all_out;
592         }
593         printd("[PID %d] exec %s\n", p->pid, file_name(program));
594         kref_put(&program->f_kref);
595         goto success;
596         /* These error and out paths are so we can handle the async interface, both
597          * for when we want to error/return to the proc, as well as when we succeed
598          * and want to start the newly exec'd _S */
599 mid_error:
600         /* These two error paths are for when we want to restart the process with an
601          * error value (errno is already set). */
602         kref_put(&program->f_kref);
603 early_error:
604         finish_current_sysc(-1);
605 success:
606         /* Here's how we restart the new (on success) or old (on failure) proc: */
607         spin_lock(&p->proc_lock);
608         __unmap_vcore(p, 0);    /* VC# keep in sync with proc_run_s */
609         __proc_set_state(p, PROC_WAITING);      /* fake a yield */
610         spin_unlock(&p->proc_lock);
611         proc_wakeup(p);
612 all_out:
613         /* we can't return, since we'd write retvals to the old location of the
614          * syscall struct (which has been freed and is in the old userspace) (or has
615          * already been written to).*/
616         disable_irq();                  /* abandon_core/clear_own wants irqs disabled */
617         clear_owning_proc(core_id());
618         abandon_core();
619         smp_idle();                             /* will reenable interrupts */
620 }
621
622 /* Helper, will attempt a particular wait on a proc.  Returns the pid of the
623  * process if we waited on it successfully, and the status will be passed back
624  * in ret_status (kernel memory).  Returns 0 if the wait failed and we should
625  * try again.  Returns -1 if we should abort.  Only handles DYING.  Callers
626  * need to lock to protect the children tailq and reaping bits. */
627 static pid_t try_wait(struct proc *parent, struct proc *child, int *ret_status,
628                       int options)
629 {
630         if (child->state == PROC_DYING) {
631                 /* Disown returns -1 if it's already been disowned or we should o/w
632                  * abort.  This can happen if we have concurrent waiters, both with
633                  * pointers to the child (only one should reap).  Note that if we don't
634                  * do this, we could go to sleep and never receive a cv_signal. */
635                 if (__proc_disown_child(parent, child))
636                         return -1;
637                 /* despite disowning, the child won't be freed til we drop this ref
638                  * held by this function, so it is safe to access the memory.
639                  *
640                  * Note the exit code one byte in the 0xff00 spot.  Check out glibc's
641                  * posix/sys/wait.h and bits/waitstatus.h for more info.  If we ever
642                  * deal with signalling and stopping, we'll need to do some more work
643                  * here.*/
644                 *ret_status = (child->exitcode & 0xff) << 8;
645                 return child->pid;
646         }
647         return 0;
648 }
649
650 /* Helper, like try_wait, but attempts a wait on any of the children, returning
651  * the specific PID we waited on, 0 to try again (a waitable exists), and -1 to
652  * abort (no children/waitables exist).  Callers need to lock to protect the
653  * children tailq and reaping bits.*/
654 static pid_t try_wait_any(struct proc *parent, int *ret_status, int options)
655 {
656         struct proc *i, *temp;
657         pid_t retval;
658         if (TAILQ_EMPTY(&parent->children))
659                 return -1;
660         /* Could have concurrent waiters mucking with the tailq, caller must lock */
661         TAILQ_FOREACH_SAFE(i, &parent->children, sibling_link, temp) {
662                 retval = try_wait(parent, i, ret_status, options);
663                 /* This catches a thread causing a wait to fail but not taking the
664                  * child off the list before unlocking.  Should never happen. */
665                 assert(retval != -1);
666                 /* Succeeded, return the pid of the child we waited on */
667                 if (retval)
668                         return retval;
669         }
670         assert(retval == 0);
671         return 0;
672 }
673
674 /* Waits on a particular child, returns the pid of the child waited on, and
675  * puts the ret status in *ret_status.  Returns the pid if we succeeded, 0 if
676  * the child was not waitable and WNOHANG, and -1 on error. */
677 static pid_t wait_one(struct proc *parent, struct proc *child, int *ret_status,
678                       int options)
679 {
680         pid_t retval;
681         cv_lock(&parent->child_wait);
682         /* retval == 0 means we should block */
683         retval = try_wait(parent, child, ret_status, options);
684         if ((retval == 0) && (options & WNOHANG))
685                 goto out_unlock;
686         while (!retval) {
687                 cpu_relax();
688                 cv_wait(&parent->child_wait);
689                 /* If we're dying, then we don't need to worry about waiting.  We don't
690                  * do this yet, but we'll need this outlet when we deal with orphaned
691                  * children and having init inherit them. */
692                 if (parent->state == PROC_DYING)
693                         goto out_unlock;
694                 /* Any child can wake us up, but we check for the particular child we
695                  * care about */
696                 retval = try_wait(parent, child, ret_status, options);
697         }
698         if (retval == -1) {
699                 /* Child was already waited on by a concurrent syscall. */
700                 set_errno(ECHILD);
701         }
702         /* Fallthrough */
703 out_unlock:
704         cv_unlock(&parent->child_wait);
705         return retval;
706 }
707
708 /* Waits on any child, returns the pid of the child waited on, and puts the ret
709  * status in *ret_status.  Is basically a waitpid(-1, ... );  See wait_one for
710  * more details.  Returns -1 if there are no children to wait on, and returns 0
711  * if there are children and we need to block but WNOHANG was set. */
712 static pid_t wait_any(struct proc *parent, int *ret_status, int options)
713 {
714         pid_t retval;
715         cv_lock(&parent->child_wait);
716         retval = try_wait_any(parent, ret_status, options);
717         if ((retval == 0) && (options & WNOHANG))
718                 goto out_unlock;
719         while (!retval) {
720                 cpu_relax();
721                 cv_wait(&parent->child_wait);
722                 if (parent->state == PROC_DYING)
723                         goto out_unlock;
724                 /* Any child can wake us up from the CV.  This is a linear try_wait
725                  * scan.  If we have a lot of children, we could optimize this. */
726                 retval = try_wait_any(parent, ret_status, options);
727         }
728         if (retval == -1)
729                 assert(TAILQ_EMPTY(&parent->children));
730         /* Fallthrough */
731 out_unlock:
732         cv_unlock(&parent->child_wait);
733         return retval;
734 }
735
736 /* Note: we only allow waiting on children (no such thing as threads, for
737  * instance).  Right now we only allow waiting on termination (not signals),
738  * and we don't have a way for parents to disown their children (such as
739  * ignoring SIGCHLD, see man 2 waitpid's Notes).
740  *
741  * We don't bother with stop/start signals here, though we can probably build
742  * it in the helper above.
743  *
744  * Returns the pid of who we waited on, or -1 on error, or 0 if we couldn't
745  * wait (WNOHANG). */
746 static pid_t sys_waitpid(struct proc *parent, pid_t pid, int *status,
747                          int options)
748 {
749         struct proc *child;
750         pid_t retval = 0;
751         int ret_status = 0;
752
753         /* -1 is the signal for 'any child' */
754         if (pid == -1) {
755                 retval = wait_any(parent, &ret_status, options);
756                 goto out;
757         }
758         child = pid2proc(pid);
759         if (!child) {
760                 set_errno(ECHILD);      /* ECHILD also used for no proc */
761                 retval = -1;
762                 goto out;
763         }
764         if (!(parent->pid == child->ppid)) {
765                 set_errno(ECHILD);
766                 retval = -1;
767                 goto out_decref;
768         }
769         retval = wait_one(parent, child, &ret_status, options);
770         /* fall-through */
771 out_decref:
772         proc_decref(child);
773 out:
774         /* ignoring / don't care about memcpy's retval here. */
775         if (status)
776                 memcpy_to_user(parent, status, &ret_status, sizeof(ret_status));
777         printd("[PID %d] waited for PID %d, got retval %d (status 0x%x)\n",
778                parent->pid, pid, retval, ret_status);
779         return retval;
780 }
781
782 /************** Memory Management Syscalls **************/
783
784 static void *sys_mmap(struct proc *p, uintptr_t addr, size_t len, int prot,
785                       int flags, int fd, off_t offset)
786 {
787         return mmap(p, addr, len, prot, flags, fd, offset);
788 }
789
790 static intreg_t sys_mprotect(struct proc *p, void *addr, size_t len, int prot)
791 {
792         return mprotect(p, (uintptr_t)addr, len, prot);
793 }
794
795 static intreg_t sys_munmap(struct proc *p, void *addr, size_t len)
796 {
797         return munmap(p, (uintptr_t)addr, len);
798 }
799
800 static ssize_t sys_shared_page_alloc(env_t* p1,
801                                      void**DANGEROUS _addr, pid_t p2_id,
802                                      int p1_flags, int p2_flags
803                                     )
804 {
805         printk("[kernel] shared page alloc is deprecated/unimplemented.\n");
806         return -1;
807 }
808
809 static int sys_shared_page_free(env_t* p1, void*DANGEROUS addr, pid_t p2)
810 {
811         return -1;
812 }
813
814 /* Helper, to do the actual provisioning of a resource to a proc */
815 static int prov_resource(struct proc *target, unsigned int res_type,
816                          long res_val)
817 {
818         switch (res_type) {
819                 case (RES_CORES):
820                         /* in the off chance we have a kernel scheduler that can't
821                          * provision, we'll need to change this. */
822                         return provision_core(target, res_val);
823                 default:
824                         printk("[kernel] received provisioning for unknown resource %d\n",
825                                res_type);
826                         set_errno(ENOENT);      /* or EINVAL? */
827                         return -1;
828         }
829 }
830
831 /* Rough syscall to provision res_val of type res_type to target_pid */
832 static int sys_provision(struct proc *p, int target_pid,
833                          unsigned int res_type, long res_val)
834 {
835         struct proc *target = pid2proc(target_pid);
836         int retval;
837         if (!target) {
838                 if (target_pid == 0)
839                         return prov_resource(0, res_type, res_val);
840                 /* debugging interface */
841                 if (target_pid == -1)
842                         print_prov_map();
843                 set_errno(ESRCH);
844                 return -1;
845         }
846         retval = prov_resource(target, res_type, res_val);
847         proc_decref(target);
848         return retval;
849 }
850
851 /* Untested.  Will notify the target on the given vcore, if the caller controls
852  * the target.  Will honor the target's wanted/vcoreid.  u_ne can be NULL. */
853 static int sys_notify(struct proc *p, int target_pid, unsigned int ev_type,
854                       struct event_msg *u_msg)
855 {
856         struct event_msg local_msg = {0};
857         struct proc *target = pid2proc(target_pid);
858         if (!target) {
859                 set_errno(ESRCH);
860                 return -1;
861         }
862         if (!proc_controls(p, target)) {
863                 proc_decref(target);
864                 set_errno(EPERM);
865                 return -1;
866         }
867         /* if the user provided an ev_msg, copy it in and use that */
868         if (u_msg) {
869                 if (memcpy_from_user(p, &local_msg, u_msg, sizeof(struct event_msg))) {
870                         proc_decref(target);
871                         set_errno(EINVAL);
872                         return -1;
873                 }
874         } else {
875                 local_msg.ev_type = ev_type;
876         }
877         send_kernel_event(target, &local_msg, 0);
878         proc_decref(target);
879         return 0;
880 }
881
882 /* Will notify the calling process on the given vcore, independently of WANTED
883  * or advertised vcoreid.  If you change the parameters, change pop_user_ctx().
884  */
885 static int sys_self_notify(struct proc *p, uint32_t vcoreid,
886                            unsigned int ev_type, struct event_msg *u_msg,
887                            bool priv)
888 {
889         struct event_msg local_msg = {0};
890         /* if the user provided an ev_msg, copy it in and use that */
891         if (u_msg) {
892                 if (memcpy_from_user(p, &local_msg, u_msg, sizeof(struct event_msg))) {
893                         set_errno(EINVAL);
894                         return -1;
895                 }
896         } else {
897                 local_msg.ev_type = ev_type;
898         }
899         if (local_msg.ev_type >= MAX_NR_EVENT) {
900                 printk("[kernel] received self-notify for vcoreid %d, ev_type %d, "
901                        "u_msg %p, u_msg->type %d\n", vcoreid, ev_type, u_msg,
902                        u_msg ? u_msg->ev_type : 0);
903                 return -1;
904         }
905         /* this will post a message and IPI, regardless of wants/needs/debutantes.*/
906         post_vcore_event(p, &local_msg, vcoreid, priv ? EVENT_VCORE_PRIVATE : 0);
907         proc_notify(p, vcoreid);
908         return 0;
909 }
910
911 /* Puts the calling core into vcore context, if it wasn't already, via a
912  * self-IPI / active notification.  Barring any weird unmappings, we just send
913  * ourselves a __notify. */
914 static int sys_vc_entry(struct proc *p)
915 {
916         send_kernel_message(core_id(), __notify, (long)p, 0, 0, KMSG_ROUTINE);
917         return 0;
918 }
919
920 /* This will set a local timer for usec, then shut down the core.  There's a
921  * slight race between spinner and halt.  For now, the core will wake up for
922  * other interrupts and service them, but will not process routine messages or
923  * do anything other than halt until the alarm goes off.  We could just unset
924  * the alarm and return early.  On hardware, there are a lot of interrupts that
925  * come in.  If we ever use this, we can take a closer look.  */
926 static int sys_halt_core(struct proc *p, unsigned int usec)
927 {
928         struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
929         struct alarm_waiter a_waiter;
930         bool spinner = TRUE;
931         void unblock(struct alarm_waiter *waiter)
932         {
933                 spinner = FALSE;
934         }
935         init_awaiter(&a_waiter, unblock);
936         set_awaiter_rel(&a_waiter, MAX(usec, 100));
937         set_alarm(tchain, &a_waiter);
938         enable_irq();
939         /* Could wake up due to another interrupt, but we want to sleep still. */
940         while (spinner) {
941                 cpu_halt();     /* slight race between spinner and halt */
942                 cpu_relax();
943         }
944         printd("Returning from halting\n");
945         return 0;
946 }
947
948 /* Changes a process into _M mode, or -EINVAL if it already is an mcp.
949  * __proc_change_to_m() returns and we'll eventually finish the sysc later.  The
950  * original context may restart on a remote core before we return and finish,
951  * but that's fine thanks to the async kernel interface. */
952 static int sys_change_to_m(struct proc *p)
953 {
954         int retval = proc_change_to_m(p);
955         /* convert the kernel error code into (-1, errno) */
956         if (retval) {
957                 set_errno(-retval);
958                 retval = -1;
959         }
960         return retval;
961 }
962
963 /* Pokes the ksched for the given resource for target_pid.  If the target pid
964  * == 0, we just poke for the calling process.  The common case is poking for
965  * self, so we avoid the lookup. 
966  *
967  * Not sure if you could harm someone via asking the kernel to look at them, so
968  * we'll do a 'controls' check for now.  In the future, we might have something
969  * in the ksched that limits or penalizes excessive pokes. */
970 static int sys_poke_ksched(struct proc *p, int target_pid,
971                            unsigned int res_type)
972 {
973         struct proc *target;
974         int retval = 0;
975         if (!target_pid) {
976                 poke_ksched(p, res_type);
977                 return 0;
978         }
979         target = pid2proc(target_pid);
980         if (!target) {
981                 set_errno(ESRCH);
982                 return -1;
983         }
984         if (!proc_controls(p, target)) {
985                 set_errno(EPERM);
986                 retval = -1;
987                 goto out;
988         }
989         poke_ksched(target, res_type);
990 out:
991         proc_decref(target);
992         return retval;
993 }
994
995 static int sys_abort_sysc(struct proc *p, struct syscall *sysc)
996 {
997         return abort_sysc(p, sysc);
998 }
999
1000 static intreg_t sys_read(struct proc *p, int fd, void *buf, int len)
1001 {
1002         ssize_t ret;
1003         struct file *file = get_file_from_fd(&p->open_files, fd);
1004         /* VFS */
1005         if (file) {
1006                 if (!file->f_op->read) {
1007                         kref_put(&file->f_kref);
1008                         set_errno(EINVAL);
1009                         return -1;
1010                 }
1011                 /* TODO: (UMEM) currently, read() handles user memcpy
1012                  * issues, but we probably should user_mem_check and
1013                  * pin the region here, so read doesn't worry about
1014                  * it */
1015                 ret = file->f_op->read(file, buf, len, &file->f_pos);
1016                 kref_put(&file->f_kref);
1017                 return ret;
1018         }
1019         /* plan9, should also handle errors (EBADF) */
1020     ret = sysread(fd, buf, len);
1021         return ret;
1022 }
1023
1024 static intreg_t sys_write(struct proc *p, int fd, const void *buf, int len)
1025 {
1026         ssize_t ret;
1027         struct file *file = get_file_from_fd(&p->open_files, fd);
1028         /* VFS */
1029         if (file) {
1030                 if (!file->f_op->write) {
1031                         kref_put(&file->f_kref);
1032                         set_errno(EINVAL);
1033                         return -1;
1034                 }
1035                 /* TODO: (UMEM) */
1036                 ret = file->f_op->write(file, buf, len, &file->f_pos);
1037                 kref_put(&file->f_kref);
1038                 return ret;
1039         }
1040         /* plan9, should also handle errors */
1041         ret = syswrite(fd, (void*)buf, len);
1042         return ret;
1043 }
1044
1045 /* Checks args/reads in the path, opens the file, and inserts it into the
1046  * process's open file list. */
1047 static intreg_t sys_open(struct proc *p, const char *path, size_t path_l,
1048                          int oflag, int mode)
1049 {
1050         int fd;
1051         struct file *file;
1052
1053         printd("File %s Open attempt oflag %x mode %x\n", path, oflag, mode);
1054         char *t_path = user_strdup_errno(p, path, path_l);
1055         if (!t_path)
1056                 return -1;
1057         mode &= ~p->fs_env.umask;
1058         file = do_file_open(t_path, oflag, mode);
1059         /* VFS */
1060         if (file) {
1061                 fd = insert_file(&p->open_files, file, 0);      /* stores the ref to file */
1062                 kref_put(&file->f_kref);        /* drop our ref */
1063                 if (fd < 0)
1064                         warn("File insertion failed");
1065         } else {
1066                 unset_errno();  /* Go can't handle extra errnos */
1067                 fd = sysopen(t_path, oflag);
1068                 /* successful lookup with CREATE and EXCL is an error */
1069                 if (fd != -1) {
1070                         if ((oflag & O_CREATE) && (oflag & O_EXCL)) {
1071                                 set_errno(EEXIST);
1072                                 sysclose(fd);
1073                                 user_memdup_free(p, t_path);
1074                                 return -1;
1075                         }
1076                 } else {
1077                         if (oflag & O_CREATE)
1078                                 fd = syscreate(t_path, oflag, mode);
1079                 }
1080         }
1081         user_memdup_free(p, t_path);
1082         printd("File %s Open, fd=%d\n", path, fd);
1083         return fd;
1084 }
1085
1086 static intreg_t sys_close(struct proc *p, int fd)
1087 {
1088         struct file *file = get_file_from_fd(&p->open_files, fd);
1089         int retval = 0;
1090         printd("sys_close %d\n", fd);
1091         /* VFS */
1092         if (file) {
1093                 put_file_from_fd(&p->open_files, fd);
1094                 kref_put(&file->f_kref);        /* Drop the ref from get_file */
1095                 return 0;
1096         }
1097         /* 9ns, should also handle errors (bad FD, etc) */
1098         retval = sysclose(fd);
1099         return retval;
1100 }
1101
1102 /* kept around til we remove the last ufe */
1103 #define ufe(which,a0,a1,a2,a3) \
1104         frontend_syscall_errno(p,APPSERVER_SYSCALL_##which,\
1105                            (int)(a0),(int)(a1),(int)(a2),(int)(a3))
1106
1107 static intreg_t sys_fstat(struct proc *p, int fd, struct kstat *u_stat)
1108 {
1109         struct kstat *kbuf;
1110         struct file *file;
1111         kbuf = kmalloc(sizeof(struct kstat), 0);
1112         if (!kbuf) {
1113                 set_errno(ENOMEM);
1114                 return -1;
1115         }
1116         file = get_file_from_fd(&p->open_files, fd);
1117         /* VFS */
1118         if (file) {
1119                 stat_inode(file->f_dentry->d_inode, kbuf);
1120                 kref_put(&file->f_kref);
1121         } else {
1122                 unset_errno();  /* Go can't handle extra errnos */
1123             if (sysfstat(fd, (uint8_t*)kbuf, sizeof(*kbuf)) < 0) {
1124                         kfree(kbuf);
1125                         return -1;
1126                 }
1127         }
1128         /* TODO: UMEM: pin the memory, copy directly, and skip the kernel buffer */
1129         if (memcpy_to_user_errno(p, u_stat, kbuf, sizeof(struct kstat))) {
1130                 kfree(kbuf);
1131                 return -1;
1132         }
1133         kfree(kbuf);
1134         return 0;
1135 }
1136
1137 /* sys_stat() and sys_lstat() do nearly the same thing, differing in how they
1138  * treat a symlink for the final item, which (probably) will be controlled by
1139  * the lookup flags */
1140 static intreg_t stat_helper(struct proc *p, const char *path, size_t path_l,
1141                             struct kstat *u_stat, int flags)
1142 {
1143         struct kstat *kbuf;
1144         struct dentry *path_d;
1145         char *t_path = user_strdup_errno(p, path, path_l);
1146         int retval = 0;
1147         if (!t_path)
1148                 return -1;
1149         kbuf = kmalloc(sizeof(struct kstat), 0);
1150         if (!kbuf) {
1151                 set_errno(ENOMEM);
1152                 retval = -1;
1153                 goto out_with_path;
1154         }
1155         /* Check VFS for path */
1156         path_d = lookup_dentry(t_path, flags);
1157         if (path_d) {
1158                 stat_inode(path_d->d_inode, kbuf);
1159                 kref_put(&path_d->d_kref);
1160         } else {
1161                 /* VFS failed, checking 9ns */
1162                 unset_errno();  /* Go can't handle extra errnos */
1163                 retval = sysstat(t_path, (uint8_t*)kbuf, sizeof(*kbuf));
1164                 printd("sysstat returns %d\n", retval);
1165                 /* both VFS and 9ns failed, bail out */
1166                 if (retval < 0)
1167                         goto out_with_kbuf;
1168         }
1169         /* TODO: UMEM: pin the memory, copy directly, and skip the kernel buffer */
1170         if (memcpy_to_user_errno(p, u_stat, kbuf, sizeof(struct kstat)))
1171                 retval = -1;
1172         /* Fall-through */
1173 out_with_kbuf:
1174         kfree(kbuf);
1175 out_with_path:
1176         user_memdup_free(p, t_path);
1177         return retval;
1178 }
1179
1180 /* Follow a final symlink */
1181 static intreg_t sys_stat(struct proc *p, const char *path, size_t path_l,
1182                          struct kstat *u_stat)
1183 {
1184         return stat_helper(p, path, path_l, u_stat, LOOKUP_FOLLOW);
1185 }
1186
1187 /* Don't follow a final symlink */
1188 static intreg_t sys_lstat(struct proc *p, const char *path, size_t path_l,
1189                           struct kstat *u_stat)
1190 {
1191         return stat_helper(p, path, path_l, u_stat, 0);
1192 }
1193
1194 intreg_t sys_fcntl(struct proc *p, int fd, int cmd, int arg)
1195 {
1196         int retval = 0;
1197         int newfd;
1198         struct file *file = get_file_from_fd(&p->open_files, fd);
1199
1200         if (!file) {
1201                 /* 9ns hack */
1202                 switch (cmd) {
1203                         case (F_DUPFD):
1204                                 return sysdup(fd, -1);
1205                         case (F_GETFD):
1206                         case (F_SETFD):
1207                                 return 0;
1208                         case (F_GETFL):
1209                                 return fd_getfl(fd);
1210                         case (F_SETFL):
1211                                 return fd_setfl(fd, arg);
1212                         default:
1213                                 warn("Unsupported fcntl cmd %d\n", cmd);
1214                 }
1215                 /* not really ever calling this, even for badf, due to the switch */
1216                 set_errno(EBADF);
1217                 return -1;
1218         }
1219
1220         switch (cmd) {
1221                 case (F_DUPFD):
1222                         retval = insert_file(&p->open_files, file, arg);
1223                         if (retval < 0) {
1224                                 set_errno(-retval);
1225                                 retval = -1;
1226                         }
1227                         break;
1228                 case (F_GETFD):
1229                         retval = p->open_files.fd[fd].fd_flags;
1230                         break;
1231                 case (F_SETFD):
1232                         if (arg == FD_CLOEXEC)
1233                                 file->f_flags |= O_CLOEXEC;
1234                         break;
1235                 case (F_GETFL):
1236                         retval = file->f_flags;
1237                         break;
1238                 case (F_SETFL):
1239                         /* only allowed to set certain flags. */
1240                         arg &= O_FCNTL_FLAGS;
1241                         file->f_flags = (file->f_flags & ~O_FCNTL_FLAGS) | arg;
1242                         break;
1243                 default:
1244                         warn("Unsupported fcntl cmd %d\n", cmd);
1245         }
1246         kref_put(&file->f_kref);
1247         return retval;
1248 }
1249
1250 static intreg_t sys_access(struct proc *p, const char *path, size_t path_l,
1251                            int mode)
1252 {
1253         int retval;
1254         char *t_path = user_strdup_errno(p, path, path_l);
1255         if (!t_path)
1256                 return -1;
1257         /* TODO: 9ns support */
1258         retval = do_access(t_path, mode);
1259         user_memdup_free(p, t_path);
1260         printd("Access for path: %s retval: %d\n", path, retval);
1261         if (retval < 0) {
1262                 set_errno(-retval);
1263                 return -1;
1264         }
1265         return retval;
1266 }
1267
1268 intreg_t sys_umask(struct proc *p, int mask)
1269 {
1270         int old_mask = p->fs_env.umask;
1271         p->fs_env.umask = mask & S_PMASK;
1272         return old_mask;
1273 }
1274
1275 intreg_t sys_chmod(struct proc *p, const char *path, size_t path_l, int mode)
1276 {
1277         int retval;
1278         char *t_path = user_strdup_errno(p, path, path_l);
1279         if (!t_path)
1280                 return -1;
1281         /* TODO: 9ns support */
1282         retval = do_chmod(t_path, mode);
1283         user_memdup_free(p, t_path);
1284         if (retval < 0) {
1285                 set_errno(-retval);
1286                 return -1;
1287         }
1288         return retval;
1289 }
1290
1291 /* 64 bit seek, with the off64_t passed in via two (potentially 32 bit) off_ts.
1292  * We're supporting both 32 and 64 bit kernels/userspaces, but both use the
1293  * llseek syscall with 64 bit parameters. */
1294 static intreg_t sys_llseek(struct proc *p, int fd, off_t offset_hi,
1295                            off_t offset_lo, off64_t *result, int whence)
1296 {
1297         off64_t retoff = 0;
1298         off64_t tempoff = 0;
1299         int ret = 0;
1300         struct file *file = get_file_from_fd(&p->open_files, fd);
1301         if (!file) {
1302                 set_errno(EBADF);
1303                 return -1;
1304         }
1305         tempoff = offset_hi;
1306         tempoff <<= 32;
1307         tempoff |= offset_lo;
1308         ret = file->f_op->llseek(file, tempoff, &retoff, whence);
1309         kref_put(&file->f_kref);
1310         if (ret)
1311                 return -1;
1312         if (memcpy_to_user_errno(p, result, &retoff, sizeof(off64_t)))
1313                 return -1;
1314         return 0;
1315 }
1316
1317 intreg_t sys_link(struct proc *p, char *old_path, size_t old_l,
1318                   char *new_path, size_t new_l)
1319 {
1320         int ret;
1321         char *t_oldpath = user_strdup_errno(p, old_path, old_l);
1322         if (t_oldpath == NULL)
1323                 return -1;
1324         char *t_newpath = user_strdup_errno(p, new_path, new_l);
1325         if (t_newpath == NULL) {
1326                 user_memdup_free(p, t_oldpath);
1327                 return -1;
1328         }
1329         ret = do_link(t_oldpath, t_newpath);
1330         user_memdup_free(p, t_oldpath);
1331         user_memdup_free(p, t_newpath);
1332         return ret;
1333 }
1334
1335 intreg_t sys_unlink(struct proc *p, const char *path, size_t path_l)
1336 {
1337         int retval;
1338         char *t_path = user_strdup_errno(p, path, path_l);
1339         if (!t_path)
1340                 return -1;
1341         retval = do_unlink(t_path);
1342         if (retval) {
1343                 unset_errno();
1344                 retval = sysremove(t_path);
1345         }
1346         user_memdup_free(p, t_path);
1347         return retval;
1348 }
1349
1350 intreg_t sys_symlink(struct proc *p, char *old_path, size_t old_l,
1351                      char *new_path, size_t new_l)
1352 {
1353         int ret;
1354         char *t_oldpath = user_strdup_errno(p, old_path, old_l);
1355         if (t_oldpath == NULL)
1356                 return -1;
1357         char *t_newpath = user_strdup_errno(p, new_path, new_l);
1358         if (t_newpath == NULL) {
1359                 user_memdup_free(p, t_oldpath);
1360                 return -1;
1361         }
1362         ret = do_symlink(t_newpath, t_oldpath, S_IRWXU | S_IRWXG | S_IRWXO);
1363         user_memdup_free(p, t_oldpath);
1364         user_memdup_free(p, t_newpath);
1365         return ret;
1366 }
1367
1368 intreg_t sys_readlink(struct proc *p, char *path, size_t path_l,
1369                       char *u_buf, size_t buf_l)
1370 {
1371         char *symname;
1372         ssize_t copy_amt;
1373         struct dentry *path_d;
1374         char *t_path = user_strdup_errno(p, path, path_l);
1375         if (t_path == NULL)
1376                 return -1;
1377         /* TODO: 9ns support */
1378         path_d = lookup_dentry(t_path, 0);
1379         user_memdup_free(p, t_path);
1380         if (!path_d)
1381                 return -1;
1382         symname = path_d->d_inode->i_op->readlink(path_d);
1383         copy_amt = strnlen(symname, buf_l - 1) + 1;
1384         if (memcpy_to_user_errno(p, u_buf, symname, copy_amt)) {
1385                 kref_put(&path_d->d_kref);
1386                 return -1;
1387         }
1388         kref_put(&path_d->d_kref);
1389         printd("READLINK returning %s\n", u_buf);
1390         return copy_amt;
1391 }
1392
1393 intreg_t sys_chdir(struct proc *p, const char *path, size_t path_l)
1394 {
1395         int retval;
1396         char *t_path = user_strdup_errno(p, path, path_l);
1397         if (!t_path)
1398                 return -1;
1399         /* TODO: 9ns support */
1400         retval = do_chdir(&p->fs_env, t_path);
1401         user_memdup_free(p, t_path);
1402         if (retval) {
1403                 set_errno(-retval);
1404                 return -1;
1405         }
1406         return 0;
1407 }
1408
1409 /* Note cwd_l is not a strlen, it's an absolute size */
1410 intreg_t sys_getcwd(struct proc *p, char *u_cwd, size_t cwd_l)
1411 {
1412         int retval = 0;
1413         char *kfree_this;
1414         char *k_cwd = do_getcwd(&p->fs_env, &kfree_this, cwd_l);
1415         if (!k_cwd)
1416                 return -1;              /* errno set by do_getcwd */
1417         if (memcpy_to_user_errno(p, u_cwd, k_cwd, strnlen(k_cwd, cwd_l - 1) + 1))
1418                 retval = -1;
1419         kfree(kfree_this);
1420         return retval;
1421 }
1422
1423 intreg_t sys_mkdir(struct proc *p, const char *path, size_t path_l, int mode)
1424 {
1425         int retval;
1426         char *t_path = user_strdup_errno(p, path, path_l);
1427         if (!t_path)
1428                 return -1;
1429         mode &= ~p->fs_env.umask;
1430         retval = do_mkdir(t_path, mode);
1431         if (retval) {
1432                 unset_errno();
1433                 retval = syscreate(t_path, DMDIR, mode);
1434         }
1435         user_memdup_free(p, t_path);
1436         return retval;
1437 }
1438
1439 intreg_t sys_rmdir(struct proc *p, const char *path, size_t path_l)
1440 {
1441         int retval;
1442         char *t_path = user_strdup_errno(p, path, path_l);
1443         if (!t_path)
1444                 return -1;
1445         /* TODO: 9ns support */
1446         retval = do_rmdir(t_path);
1447         user_memdup_free(p, t_path);
1448         return retval;
1449 }
1450
1451 intreg_t sys_pipe(struct proc *p, int *u_pipefd, int flags)
1452 {
1453         int pipefd[2] = {0};
1454         int retval = syspipe(pipefd);
1455
1456         if (retval)
1457                 return -1;
1458         if (memcpy_to_user_errno(p, u_pipefd, pipefd, sizeof(pipefd))) {
1459                 sysclose(pipefd[0]);
1460                 sysclose(pipefd[1]);
1461                 set_errno(EFAULT);
1462                 return -1;
1463         }
1464         return 0;
1465 }
1466
1467 intreg_t sys_gettimeofday(struct proc *p, int *buf)
1468 {
1469         static spinlock_t gtod_lock = SPINLOCK_INITIALIZER;
1470         static int t0 = 0;
1471
1472         spin_lock(&gtod_lock);
1473         if(t0 == 0)
1474
1475 #if (defined CONFIG_APPSERVER)
1476         t0 = ufe(time,0,0,0,0);
1477 #else
1478         // Nanwan's birthday, bitches!!
1479         t0 = 1242129600;
1480 #endif
1481         spin_unlock(&gtod_lock);
1482
1483         long long dt = read_tsc();
1484         /* TODO: This probably wants its own function, using a struct timeval */
1485         long kbuf[2] = {t0+dt/system_timing.tsc_freq,
1486             (dt%system_timing.tsc_freq)*1000000/system_timing.tsc_freq};
1487
1488         return memcpy_to_user_errno(p,buf,kbuf,sizeof(kbuf));
1489 }
1490
1491 intreg_t sys_tcgetattr(struct proc *p, int fd, void *termios_p)
1492 {
1493         int retval = 0;
1494         /* TODO: actually support this call on tty FDs.  Right now, we just fake
1495          * what my linux box reports for a bash pty. */
1496         struct termios *kbuf = kmalloc(sizeof(struct termios), 0);
1497         kbuf->c_iflag = 0x2d02;
1498         kbuf->c_oflag = 0x0005;
1499         kbuf->c_cflag = 0x04bf;
1500         kbuf->c_lflag = 0x8a3b;
1501         kbuf->c_line = 0x0;
1502         kbuf->c_ispeed = 0xf;
1503         kbuf->c_ospeed = 0xf;
1504         kbuf->c_cc[0] = 0x03;
1505         kbuf->c_cc[1] = 0x1c;
1506         kbuf->c_cc[2] = 0x7f;
1507         kbuf->c_cc[3] = 0x15;
1508         kbuf->c_cc[4] = 0x04;
1509         kbuf->c_cc[5] = 0x00;
1510         kbuf->c_cc[6] = 0x01;
1511         kbuf->c_cc[7] = 0xff;
1512         kbuf->c_cc[8] = 0x11;
1513         kbuf->c_cc[9] = 0x13;
1514         kbuf->c_cc[10] = 0x1a;
1515         kbuf->c_cc[11] = 0xff;
1516         kbuf->c_cc[12] = 0x12;
1517         kbuf->c_cc[13] = 0x0f;
1518         kbuf->c_cc[14] = 0x17;
1519         kbuf->c_cc[15] = 0x16;
1520         kbuf->c_cc[16] = 0xff;
1521         kbuf->c_cc[17] = 0x00;
1522         kbuf->c_cc[18] = 0x00;
1523         kbuf->c_cc[19] = 0x00;
1524         kbuf->c_cc[20] = 0x00;
1525         kbuf->c_cc[21] = 0x00;
1526         kbuf->c_cc[22] = 0x00;
1527         kbuf->c_cc[23] = 0x00;
1528         kbuf->c_cc[24] = 0x00;
1529         kbuf->c_cc[25] = 0x00;
1530         kbuf->c_cc[26] = 0x00;
1531         kbuf->c_cc[27] = 0x00;
1532         kbuf->c_cc[28] = 0x00;
1533         kbuf->c_cc[29] = 0x00;
1534         kbuf->c_cc[30] = 0x00;
1535         kbuf->c_cc[31] = 0x00;
1536
1537         if (memcpy_to_user_errno(p, termios_p, kbuf, sizeof(struct termios)))
1538                 retval = -1;
1539         kfree(kbuf);
1540         return retval;
1541 }
1542
1543 intreg_t sys_tcsetattr(struct proc *p, int fd, int optional_actions,
1544                        const void *termios_p)
1545 {
1546         /* TODO: do this properly too.  For now, we just say 'it worked' */
1547         return 0;
1548 }
1549
1550 /* TODO: we don't have any notion of UIDs or GIDs yet, but don't let that stop a
1551  * process from thinking it can do these.  The other alternative is to have
1552  * glibc return 0 right away, though someone might want to do something with
1553  * these calls.  Someday. */
1554 intreg_t sys_setuid(struct proc *p, uid_t uid)
1555 {
1556         return 0;
1557 }
1558
1559 intreg_t sys_setgid(struct proc *p, gid_t gid)
1560 {
1561         return 0;
1562 }
1563
1564 /* long bind(char* src_path, char* onto_path, int flag);
1565  *
1566  * The naming for the args in bind is messy historically.  We do:
1567  *              bind src_path onto_path
1568  * plan9 says bind NEW OLD, where new is *src*, and old is *onto*.
1569  * Linux says mount --bind OLD NEW, where OLD is *src* and NEW is *onto*. */
1570 intreg_t sys_nbind(struct proc *p,
1571                    char *src_path, size_t src_l,
1572                    char *onto_path, size_t onto_l,
1573                    unsigned int flag)
1574
1575 {
1576         int ret;
1577         char *t_srcpath = user_strdup_errno(p, src_path, src_l);
1578         if (t_srcpath == NULL) {
1579                 printd("srcpath dup failed ptr %p size %d\n", src_path, src_l);
1580                 return -1;
1581         }
1582         char *t_ontopath = user_strdup_errno(p, onto_path, onto_l);
1583         if (t_ontopath == NULL) {
1584                 user_memdup_free(p, t_srcpath);
1585                 printd("ontopath dup failed ptr %p size %d\n", onto_path, onto_l);
1586                 return -1;
1587         }
1588         printd("sys_nbind: %s -> %s flag %d\n", t_srcpath, t_ontopath, flag);
1589         ret = sysbind(t_srcpath, t_ontopath, flag);
1590         user_memdup_free(p, t_srcpath);
1591         user_memdup_free(p, t_ontopath);
1592         return ret;
1593 }
1594
1595 /* int mount(int fd, int afd, char* onto_path, int flag, char* aname); */
1596 intreg_t sys_nmount(struct proc *p,
1597                     int fd,
1598                     char *onto_path, size_t onto_l,
1599                     unsigned int flag
1600                         /* we ignore these */
1601                         /* no easy way to pass this many args anyway. *
1602                     int afd,
1603                     char *auth, size_t auth_l*/)
1604 {
1605         int ret;
1606         int afd;
1607
1608         afd = -1;
1609         char *t_ontopath = user_strdup_errno(p, onto_path, onto_l);
1610         if (t_ontopath == NULL)
1611                 return -1;
1612         ret = sysmount(fd, afd, t_ontopath, flag, /* spec or auth */"");
1613         user_memdup_free(p, t_ontopath);
1614         return ret;
1615 }
1616
1617 /* int mount(int fd, int afd, char* old, int flag, char* aname); */
1618 intreg_t sys_nunmount(struct proc *p, char *name, int name_l, char *old_path, int old_l)
1619 {
1620         int ret;
1621         char *t_oldpath = user_strdup_errno(p, old_path, old_l);
1622         if (t_oldpath == NULL)
1623                 return -1;
1624         char *t_name = user_strdup_errno(p, name, name_l);
1625         if (t_name == NULL) {
1626                 user_memdup_free(p, t_oldpath);
1627                 return -1;
1628         }
1629         ret = sysunmount(t_name, t_oldpath);
1630         printd("go do it\n");
1631         user_memdup_free(p, t_oldpath);
1632         user_memdup_free(p, t_name);
1633         return ret;
1634 }
1635
1636 static int sys_fd2path(struct proc *p, int fd, void *u_buf, size_t len)
1637 {
1638         int ret;
1639         struct chan *ch;
1640         ERRSTACK(1);
1641         /* UMEM: Check the range, can PF later and kill if the page isn't present */
1642         if (!is_user_rwaddr(u_buf, len)) {
1643                 printk("[kernel] bad user addr %p (+%p) in %s (user bug)\n", u_buf,
1644                        len, __FUNCTION__);
1645                 return -1;
1646         }
1647         /* fdtochan throws */
1648         if (waserror()) {
1649                 poperror();
1650                 return -1;
1651         }
1652         ch = fdtochan(current->fgrp, fd, -1, FALSE, TRUE);
1653         ret = snprintf(u_buf, len, "%s", "chanpath(ch)");
1654         cclose(ch);
1655         poperror();
1656         return ret;
1657 }
1658
1659 /************** Syscall Invokation **************/
1660
1661 const static struct sys_table_entry syscall_table[] = {
1662         [SYS_null] = {(syscall_t)sys_null, "null"},
1663         [SYS_block] = {(syscall_t)sys_block, "block"},
1664         [SYS_cache_buster] = {(syscall_t)sys_cache_buster, "buster"},
1665         [SYS_cache_invalidate] = {(syscall_t)sys_cache_invalidate, "wbinv"},
1666         [SYS_reboot] = {(syscall_t)reboot, "reboot!"},
1667         [SYS_cputs] = {(syscall_t)sys_cputs, "cputs"},
1668         [SYS_cgetc] = {(syscall_t)sys_cgetc, "cgetc"},
1669         [SYS_getpcoreid] = {(syscall_t)sys_getpcoreid, "getpcoreid"},
1670         [SYS_getvcoreid] = {(syscall_t)sys_getvcoreid, "getvcoreid"},
1671         [SYS_getpid] = {(syscall_t)sys_getpid, "getpid"},
1672         [SYS_proc_create] = {(syscall_t)sys_proc_create, "proc_create"},
1673         [SYS_proc_run] = {(syscall_t)sys_proc_run, "proc_run"},
1674         [SYS_proc_destroy] = {(syscall_t)sys_proc_destroy, "proc_destroy"},
1675         [SYS_yield] = {(syscall_t)sys_proc_yield, "proc_yield"},
1676         [SYS_change_vcore] = {(syscall_t)sys_change_vcore, "change_vcore"},
1677         [SYS_fork] = {(syscall_t)sys_fork, "fork"},
1678         [SYS_exec] = {(syscall_t)sys_exec, "exec"},
1679         [SYS_waitpid] = {(syscall_t)sys_waitpid, "waitpid"},
1680         [SYS_mmap] = {(syscall_t)sys_mmap, "mmap"},
1681         [SYS_munmap] = {(syscall_t)sys_munmap, "munmap"},
1682         [SYS_mprotect] = {(syscall_t)sys_mprotect, "mprotect"},
1683         [SYS_shared_page_alloc] = {(syscall_t)sys_shared_page_alloc, "pa"},
1684         [SYS_shared_page_free] = {(syscall_t)sys_shared_page_free, "pf"},
1685         [SYS_provision] = {(syscall_t)sys_provision, "provision"},
1686         [SYS_notify] = {(syscall_t)sys_notify, "notify"},
1687         [SYS_self_notify] = {(syscall_t)sys_self_notify, "self_notify"},
1688         [SYS_vc_entry] = {(syscall_t)sys_vc_entry, "vc_entry"},
1689         [SYS_halt_core] = {(syscall_t)sys_halt_core, "halt_core"},
1690 #ifdef CONFIG_ARSC_SERVER
1691         [SYS_init_arsc] = {(syscall_t)sys_init_arsc, "init_arsc"},
1692 #endif
1693         [SYS_change_to_m] = {(syscall_t)sys_change_to_m, "change_to_m"},
1694         [SYS_poke_ksched] = {(syscall_t)sys_poke_ksched, "poke_ksched"},
1695         [SYS_abort_sysc] = {(syscall_t)sys_abort_sysc, "abort_sysc"},
1696
1697         [SYS_read] = {(syscall_t)sys_read, "read"},
1698         [SYS_write] = {(syscall_t)sys_write, "write"},
1699         [SYS_open] = {(syscall_t)sys_open, "open"},
1700         [SYS_close] = {(syscall_t)sys_close, "close"},
1701         [SYS_fstat] = {(syscall_t)sys_fstat, "fstat"},
1702         [SYS_stat] = {(syscall_t)sys_stat, "stat"},
1703         [SYS_lstat] = {(syscall_t)sys_lstat, "lstat"},
1704         [SYS_fcntl] = {(syscall_t)sys_fcntl, "fcntl"},
1705         [SYS_access] = {(syscall_t)sys_access, "access"},
1706         [SYS_umask] = {(syscall_t)sys_umask, "umask"},
1707         [SYS_chmod] = {(syscall_t)sys_chmod, "chmod"},
1708         [SYS_llseek] = {(syscall_t)sys_llseek, "llseek"},
1709         [SYS_link] = {(syscall_t)sys_link, "link"},
1710         [SYS_unlink] = {(syscall_t)sys_unlink, "unlink"},
1711         [SYS_symlink] = {(syscall_t)sys_symlink, "symlink"},
1712         [SYS_readlink] = {(syscall_t)sys_readlink, "readlink"},
1713         [SYS_chdir] = {(syscall_t)sys_chdir, "chdir"},
1714         [SYS_getcwd] = {(syscall_t)sys_getcwd, "getcwd"},
1715         [SYS_mkdir] = {(syscall_t)sys_mkdir, "mkdri"},
1716         [SYS_rmdir] = {(syscall_t)sys_rmdir, "rmdir"},
1717         [SYS_pipe] = {(syscall_t)sys_pipe, "pipe"},
1718         [SYS_gettimeofday] = {(syscall_t)sys_gettimeofday, "gettime"},
1719         [SYS_tcgetattr] = {(syscall_t)sys_tcgetattr, "tcgetattr"},
1720         [SYS_tcsetattr] = {(syscall_t)sys_tcsetattr, "tcsetattr"},
1721         [SYS_setuid] = {(syscall_t)sys_setuid, "setuid"},
1722         [SYS_setgid] = {(syscall_t)sys_setgid, "setgid"},
1723         /* special! */
1724         [SYS_nbind] ={(syscall_t)sys_nbind, "nbind"},
1725         [SYS_nmount] ={(syscall_t)sys_nmount, "nmount"},
1726         [SYS_nunmount] ={(syscall_t)sys_nunmount, "nunmount"},
1727         [SYS_fd2path] ={(syscall_t)sys_fd2path, "fd2path"},
1728
1729 };
1730
1731 /* Executes the given syscall.
1732  *
1733  * Note tf is passed in, which points to the tf of the context on the kernel
1734  * stack.  If any syscall needs to block, it needs to save this info, as well as
1735  * any silly state.
1736  *
1737  * This syscall function is used by both local syscall and arsc, and should
1738  * remain oblivious of the caller. */
1739 intreg_t syscall(struct proc *p, uintreg_t sc_num, uintreg_t a0, uintreg_t a1,
1740                  uintreg_t a2, uintreg_t a3, uintreg_t a4, uintreg_t a5)
1741 {
1742         intreg_t ret = -1;
1743         ERRSTACK(1);
1744         const int max_syscall = sizeof(syscall_table)/sizeof(syscall_table[0]);
1745
1746         uint32_t coreid, vcoreid;
1747         if (systrace_flags & SYSTRACE_ON) {
1748                 if ((systrace_flags & SYSTRACE_ALLPROC) || (proc_is_traced(p))) {
1749                         coreid = core_id();
1750                         vcoreid = proc_get_vcoreid(p);
1751                         if (systrace_flags & SYSTRACE_LOUD) {
1752                                 printk("[%16llu] Syscall %3d (%12s):(%p, %p, %p, %p, "
1753                                        "%p, %p) proc: %d core: %d vcore: %d\n", read_tsc(),
1754                                        sc_num, syscall_table[sc_num].name, a0, a1, a2, a3,
1755                                        a4, a5, p->pid, coreid, vcoreid);
1756                         } else {
1757                                 struct systrace_record *trace;
1758                                 uintptr_t idx, new_idx;
1759                                 do {
1760                                         idx = systrace_bufidx;
1761                                         new_idx = (idx + 1) % systrace_bufsize;
1762                                 } while (!atomic_cas_u32(&systrace_bufidx, idx, new_idx));
1763                                 trace = &systrace_buffer[idx];
1764                                 trace->timestamp = read_tsc();
1765                                 trace->syscallno = sc_num;
1766                                 trace->arg0 = a0;
1767                                 trace->arg1 = a1;
1768                                 trace->arg2 = a2;
1769                                 trace->arg3 = a3;
1770                                 trace->arg4 = a4;
1771                                 trace->arg5 = a5;
1772                                 trace->pid = p->pid;
1773                                 trace->coreid = coreid;
1774                                 trace->vcoreid = vcoreid;
1775                         }
1776                 }
1777         }
1778         if (sc_num > max_syscall || syscall_table[sc_num].call == NULL)
1779                 panic("Invalid syscall number %d for proc %x!", sc_num, p);
1780
1781         /* N.B. This is going away. */
1782         if (waserror()){
1783                 printk("Plan 9 system call returned via waserror()\n");
1784                 printk("String: '%s'\n", current_errstr());
1785                 /* if we got here, then the errbuf was right.
1786                  * no need to check!
1787                  */
1788                 return -1;
1789         }
1790         //printd("before syscall errstack %p\n", errstack);
1791         //printd("before syscall errstack base %p\n", get_cur_errbuf());
1792         ret = syscall_table[sc_num].call(p, a0, a1, a2, a3, a4, a5);
1793         //printd("after syscall errstack base %p\n", get_cur_errbuf());
1794         if (get_cur_errbuf() != &errstack[0]) {
1795                 coreid = core_id();
1796                 vcoreid = proc_get_vcoreid(p);
1797                 printk("[%16llu] Syscall %3d (%12s):(%p, %p, %p, %p, "
1798                        "%p, %p) proc: %d core: %d vcore: %d\n", read_tsc(),
1799                        sc_num, syscall_table[sc_num].name, a0, a1, a2, a3,
1800                        a4, a5, p->pid, coreid, vcoreid);
1801                 if (sc_num != SYS_fork)
1802                         printk("YOU SHOULD PANIC: errstack mismatch");
1803         }
1804         return ret;
1805 }
1806
1807 /* Execute the syscall on the local core */
1808 void run_local_syscall(struct syscall *sysc)
1809 {
1810         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
1811
1812         /* TODO: (UMEM) assert / pin the memory for the sysc */
1813         assert(irq_is_enabled());       /* in case we proc destroy */
1814         /* Abort on mem check failure, for now */
1815         if (!user_mem_check(pcpui->cur_proc, sysc, sizeof(struct syscall),
1816                             sizeof(uintptr_t), PTE_USER_RW))
1817                 return;
1818         pcpui->cur_kthread->sysc = sysc;        /* let the core know which sysc it is */
1819         sysc->retval = syscall(pcpui->cur_proc, sysc->num, sysc->arg0, sysc->arg1,
1820                                sysc->arg2, sysc->arg3, sysc->arg4, sysc->arg5);
1821         /* Need to re-load pcpui, in case we migrated */
1822         pcpui = &per_cpu_info[core_id()];
1823         /* Some 9ns paths set errstr, but not errno.  glibc will ignore errstr.
1824          * this is somewhat hacky, since errno might get set unnecessarily */
1825         if ((current_errstr()[0] != 0) && (!sysc->err))
1826                 sysc->err = EUNSPECIFIED;
1827         finish_sysc(sysc, pcpui->cur_proc);
1828         /* Can unpin (UMEM) at this point */
1829         pcpui->cur_kthread->sysc = 0;   /* no longer working on sysc */
1830 }
1831
1832 /* A process can trap and call this function, which will set up the core to
1833  * handle all the syscalls.  a.k.a. "sys_debutante(needs, wants)".  If there is
1834  * at least one, it will run it directly. */
1835 void prep_syscalls(struct proc *p, struct syscall *sysc, unsigned int nr_syscs)
1836 {
1837         int retval;
1838         /* Careful with pcpui here, we could have migrated */
1839         if (!nr_syscs)
1840                 return;
1841         /* For all after the first call, send ourselves a KMSG (TODO). */
1842         if (nr_syscs != 1)
1843                 warn("Only one supported (Debutante calls: %d)\n", nr_syscs);
1844         /* Call the first one directly.  (we already checked to make sure there is
1845          * 1) */
1846         run_local_syscall(sysc);
1847 }
1848
1849 /* Call this when something happens on the syscall where userspace might want to
1850  * get signaled.  Passing p, since the caller should know who the syscall
1851  * belongs to (probably is current).
1852  *
1853  * You need to have SC_K_LOCK set when you call this. */
1854 void __signal_syscall(struct syscall *sysc, struct proc *p)
1855 {
1856         struct event_queue *ev_q;
1857         struct event_msg local_msg;
1858         /* User sets the ev_q then atomically sets the flag (races with SC_DONE) */
1859         if (atomic_read(&sysc->flags) & SC_UEVENT) {
1860                 rmb();  /* read the ev_q after reading the flag */
1861                 ev_q = sysc->ev_q;
1862                 if (ev_q) {
1863                         memset(&local_msg, 0, sizeof(struct event_msg));
1864                         local_msg.ev_type = EV_SYSCALL;
1865                         local_msg.ev_arg3 = sysc;
1866                         send_event(p, ev_q, &local_msg, 0);
1867                 }
1868         }
1869 }
1870
1871 /* Syscall tracing */
1872 static void __init_systrace(void)
1873 {
1874         systrace_buffer = kmalloc(MAX_SYSTRACES*sizeof(struct systrace_record), 0);
1875         if (!systrace_buffer)
1876                 panic("Unable to alloc a trace buffer\n");
1877         systrace_bufidx = 0;
1878         systrace_bufsize = MAX_SYSTRACES;
1879         /* Note we never free the buffer - it's around forever.  Feel free to change
1880          * this if you want to change the size or something dynamically. */
1881 }
1882
1883 /* If you call this while it is running, it will change the mode */
1884 void systrace_start(bool silent)
1885 {
1886         static bool init = FALSE;
1887         spin_lock_irqsave(&systrace_lock);
1888         if (!init) {
1889                 __init_systrace();
1890                 init = TRUE;
1891         }
1892         systrace_flags = silent ? SYSTRACE_ON : SYSTRACE_ON | SYSTRACE_LOUD;
1893         spin_unlock_irqsave(&systrace_lock);
1894 }
1895
1896 int systrace_reg(bool all, struct proc *p)
1897 {
1898         int retval = 0;
1899         spin_lock_irqsave(&systrace_lock);
1900         if (all) {
1901                 printk("Tracing syscalls for all processes\n");
1902                 systrace_flags |= SYSTRACE_ALLPROC;
1903                 retval = 0;
1904         } else {
1905                 for (int i = 0; i < MAX_NUM_TRACED; i++) {
1906                         if (!systrace_procs[i]) {
1907                                 printk("Tracing syscalls for process %d\n", p->pid);
1908                                 systrace_procs[i] = p;
1909                                 retval = 0;
1910                                 break;
1911                         }
1912                 }
1913         }
1914         spin_unlock_irqsave(&systrace_lock);
1915         return retval;
1916 }
1917
1918 void systrace_stop(void)
1919 {
1920         spin_lock_irqsave(&systrace_lock);
1921         systrace_flags = 0;
1922         for (int i = 0; i < MAX_NUM_TRACED; i++)
1923                 systrace_procs[i] = 0;
1924         spin_unlock_irqsave(&systrace_lock);
1925 }
1926
1927 /* If you registered a process specifically, then you need to dereg it
1928  * specifically.  Or just fully stop, which will do it for all. */
1929 int systrace_dereg(bool all, struct proc *p)
1930 {
1931         spin_lock_irqsave(&systrace_lock);
1932         if (all) {
1933                 printk("No longer tracing syscalls for all processes.\n");
1934                 systrace_flags &= ~SYSTRACE_ALLPROC;
1935         } else {
1936                 for (int i = 0; i < MAX_NUM_TRACED; i++) {
1937                         if (systrace_procs[i] == p) {
1938                                 systrace_procs[i] = 0;
1939                                 printk("No longer tracing syscalls for process %d\n", p->pid);
1940                         }
1941                 }
1942         }
1943         spin_unlock_irqsave(&systrace_lock);
1944         return 0;
1945 }
1946
1947 /* Regardless of locking, someone could be writing into the buffer */
1948 void systrace_print(bool all, struct proc *p)
1949 {
1950         spin_lock_irqsave(&systrace_lock);
1951         /* if you want to be clever, you could make this start from the earliest
1952          * timestamp and loop around.  Careful of concurrent writes. */
1953         for (int i = 0; i < systrace_bufsize; i++)
1954                 if (systrace_buffer[i].timestamp)
1955                         printk("[%16llu] Syscall %3d (%12s):(%p, %p, %p, %p, %p,"
1956                                "%p) proc: %d core: %d vcore: %d\n",
1957                                systrace_buffer[i].timestamp,
1958                                systrace_buffer[i].syscallno,
1959                                syscall_table[systrace_buffer[i].syscallno].name,
1960                                systrace_buffer[i].arg0,
1961                                systrace_buffer[i].arg1,
1962                                systrace_buffer[i].arg2,
1963                                systrace_buffer[i].arg3,
1964                                systrace_buffer[i].arg4,
1965                                systrace_buffer[i].arg5,
1966                                systrace_buffer[i].pid,
1967                                systrace_buffer[i].coreid,
1968                                systrace_buffer[i].vcoreid);
1969         spin_unlock_irqsave(&systrace_lock);
1970 }
1971
1972 void systrace_clear_buffer(void)
1973 {
1974         spin_lock_irqsave(&systrace_lock);
1975         memset(systrace_buffer, 0, sizeof(struct systrace_record) * MAX_SYSTRACES);
1976         spin_unlock_irqsave(&systrace_lock);
1977 }