xref: /f-stack/lib/ff_glue.c (revision 7cf85aba)
1 /*
2  * Copyright (c) 2010 Kip Macy. All rights reserved.
3  * Copyright (C) 2017 THL A29 Limited, a Tencent company.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this
10  *   list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  *   this list of conditions and the following disclaimer in the documentation
13  *   and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * Derived in part from libplebnet's pn_glue.c.
27  */
28 
29 #include <sys/cdefs.h>
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/kernel.h>
33 #include <sys/kthread.h>
34 #include <sys/event.h>
35 #include <sys/jail.h>
36 #include <sys/limits.h>
37 #include <sys/malloc.h>
38 #include <sys/refcount.h>
39 #include <sys/resourcevar.h>
40 #include <sys/sysctl.h>
41 #include <sys/sysent.h>
42 #include <sys/systm.h>
43 #include <sys/proc.h>
44 #include <sys/priv.h>
45 #include <sys/time.h>
46 #include <sys/ucred.h>
47 #include <sys/uio.h>
48 #include <sys/param.h>
49 #include <sys/bus.h>
50 #include <sys/buf.h>
51 #include <sys/file.h>
52 #include <sys/vmem.h>
53 #include <sys/mbuf.h>
54 #include <sys/smp.h>
55 #include <sys/sched.h>
56 
57 #include <vm/vm.h>
58 #include <vm/vm_param.h>
59 #include <vm/pmap.h>
60 #include <vm/vm_object.h>
61 #include <vm/vm_map.h>
62 #include <vm/vm_extern.h>
63 
64 #include "ff_host_interface.h"
65 
66 int kstack_pages = KSTACK_PAGES;
67 SYSCTL_INT(_kern, OID_AUTO, kstack_pages, CTLFLAG_RD, &kstack_pages, 0,
68     "Kernel stack size in pages");
69 
70 int bootverbose;
71 
72 SYSCTL_ROOT_NODE(0, sysctl, CTLFLAG_RW, 0, "Sysctl internal magic");
73 
74 SYSCTL_ROOT_NODE(CTL_VFS, vfs, CTLFLAG_RW, 0, "File system");
75 
76 SYSCTL_ROOT_NODE(CTL_KERN, kern, CTLFLAG_RW, 0, "High kernel, proc, limits &c");
77 
78 SYSCTL_ROOT_NODE(CTL_NET, net, CTLFLAG_RW, 0, "Network, (see socket.h)");
79 
80 SYSCTL_ROOT_NODE(CTL_MACHDEP, machdep, CTLFLAG_RW, 0, "machine dependent");
81 
82 SYSCTL_ROOT_NODE(CTL_VM, vm, CTLFLAG_RW, 0, "Virtual memory");
83 
84 SYSCTL_ROOT_NODE(CTL_DEBUG, debug, CTLFLAG_RW, 0, "Debugging");
85 
86 SYSCTL_ROOT_NODE(OID_AUTO, security, CTLFLAG_RW, 0, "Security");
87 
88 SYSCTL_NODE(_kern, OID_AUTO, features, CTLFLAG_RD, 0, "Kernel Features");
89 
90 SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD,  0, "Process table");
91 
92 MALLOC_DEFINE(M_DEVBUF, "devbuf", "device driver memory");
93 MALLOC_DEFINE(M_TEMP, "temp", "misc temporary data buffers");
94 static MALLOC_DEFINE(M_CRED, "cred", "credentials");
95 static MALLOC_DEFINE(M_PLIMIT, "plimit", "plimit structures");
96 
97 MALLOC_DEFINE(M_IP6OPT, "ip6opt", "IPv6 options");
98 
99 static void configure_final(void *dummy);
100 
101 SYSINIT(configure3, SI_SUB_CONFIGURE, SI_ORDER_ANY, configure_final, NULL);
102 
103 volatile int ticks;
104 int cpu_disable_deep_sleep;
105 
106 static int sysctl_kern_smp_active(SYSCTL_HANDLER_ARGS);
107 
108 /* This is used in modules that need to work in both SMP and UP. */
109 cpuset_t all_cpus;
110 
111 int mp_ncpus = 1;
112 /* export this for libkvm consumers. */
113 int mp_maxcpus = MAXCPU;
114 
115 volatile int smp_started;
116 u_int mp_maxid;
117 
118 static SYSCTL_NODE(_kern, OID_AUTO, smp, CTLFLAG_RD|CTLFLAG_CAPRD, NULL,
119     "Kernel SMP");
120 
121 SYSCTL_INT(_kern_smp, OID_AUTO, maxid, CTLFLAG_RD|CTLFLAG_CAPRD, &mp_maxid, 0,
122     "Max CPU ID.");
123 
124 SYSCTL_INT(_kern_smp, OID_AUTO, maxcpus, CTLFLAG_RD|CTLFLAG_CAPRD, &mp_maxcpus,
125     0, "Max number of CPUs that the system was compiled for.");
126 
127 SYSCTL_PROC(_kern_smp, OID_AUTO, active, CTLFLAG_RD | CTLTYPE_INT, NULL, 0,
128     sysctl_kern_smp_active, "I", "Indicates system is running in SMP mode");
129 
130 int smp_disabled = 0;	/* has smp been disabled? */
131 SYSCTL_INT(_kern_smp, OID_AUTO, disabled, CTLFLAG_RDTUN|CTLFLAG_CAPRD,
132     &smp_disabled, 0, "SMP has been disabled from the loader");
133 
134 int smp_cpus = 1;	/* how many cpu's running */
135 SYSCTL_INT(_kern_smp, OID_AUTO, cpus, CTLFLAG_RD|CTLFLAG_CAPRD, &smp_cpus, 0,
136     "Number of CPUs online");
137 
138 int smp_topology = 0;	/* Which topology we're using. */
139 SYSCTL_INT(_kern_smp, OID_AUTO, topology, CTLFLAG_RDTUN, &smp_topology, 0,
140     "Topology override setting; 0 is default provided by hardware.");
141 
142 
143 long first_page = 0;
144 
145 struct vmmeter vm_cnt;
146 vm_map_t kernel_map=0;
147 vm_map_t kmem_map=0;
148 
149 vmem_t *kernel_arena = NULL;
150 vmem_t *kmem_arena = NULL;
151 
152 struct vm_object kernel_object_store;
153 struct vm_object kmem_object_store;
154 
155 struct filterops fs_filtops;
156 struct filterops sig_filtops;
157 
158 int cold = 1;
159 
160 int unmapped_buf_allowed = 1;
161 
162 int cpu_deepest_sleep = 0;    /* Deepest Cx state available. */
163 int cpu_disable_c2_sleep = 0; /* Timer dies in C2. */
164 int cpu_disable_c3_sleep = 0; /* Timer dies in C3. */
165 
166 static void timevalfix(struct timeval *);
167 
168 /* Extra care is taken with this sysctl because the data type is volatile */
169 static int
170 sysctl_kern_smp_active(SYSCTL_HANDLER_ARGS)
171 {
172 	int error, active;
173 
174 	active = smp_started;
175 	error = SYSCTL_OUT(req, &active, sizeof(active));
176 	return (error);
177 }
178 
179 void
180 procinit()
181 {
182     sx_init(&allproc_lock, "allproc");
183     LIST_INIT(&allproc);
184 }
185 
186 
187 /*
188  * Find a prison that is a descendant of mypr.  Returns a locked prison or NULL.
189  */
190 struct prison *
191 prison_find_child(struct prison *mypr, int prid)
192 {
193     return (NULL);
194 }
195 
196 void
197 prison_free(struct prison *pr)
198 {
199 
200 }
201 
202 void
203 prison_hold_locked(struct prison *pr)
204 {
205 
206 }
207 
208 int
209 prison_if(struct ucred *cred, struct sockaddr *sa)
210 {
211     return (0);
212 }
213 
214 int
215 prison_check_af(struct ucred *cred, int af)
216 {
217     return (0);
218 }
219 
220 int
221 prison_check_ip4(const struct ucred *cred, const struct in_addr *ia)
222 {
223     return (0);
224 }
225 
226 int
227 prison_equal_ip4(struct prison *pr1, struct prison *pr2)
228 {
229     return (1);
230 }
231 
232 #ifdef INET6
233 int
234 prison_check_ip6(struct ucred *cred, struct in6_addr *ia)
235 {
236     return (0);
237 }
238 
239 int
240 prison_equal_ip6(struct prison *pr1, struct prison *pr2)
241 {
242     return (1);
243 }
244 #endif
245 
246 /*
247  * See if a prison has the specific flag set.
248  */
249 int
250 prison_flag(struct ucred *cred, unsigned flag)
251 {
252     /* This is an atomic read, so no locking is necessary. */
253     return (flag & PR_HOST);
254 }
255 
256 int
257 prison_get_ip4(struct ucred *cred, struct in_addr *ia)
258 {
259     return (0);
260 }
261 
262 int
263 prison_local_ip4(struct ucred *cred, struct in_addr *ia)
264 {
265     return (0);
266 }
267 
268 int
269 prison_remote_ip4(struct ucred *cred, struct in_addr *ia)
270 {
271     return (0);
272 }
273 
274 #ifdef INET6
275 int
276 prison_get_ip6(struct ucred *cred, struct in6_addr *ia)
277 {
278     return (0);
279 }
280 
281 int
282 prison_local_ip6(struct ucred *cred, struct in6_addr *ia, int other)
283 {
284     return (0);
285 }
286 
287 int
288 prison_remote_ip6(struct ucred *cred, struct in6_addr *ia)
289 {
290     return (0);
291 }
292 #endif
293 
294 int
295 prison_saddrsel_ip4(struct ucred *cred, struct in_addr *ia)
296 {
297     /* not jailed */
298     return (1);
299 }
300 
301 #ifdef INET6
302 int
303 prison_saddrsel_ip6(struct ucred *cred, struct in6_addr *ia)
304 {
305     /* not jailed */
306     return (1);
307 }
308 #endif
309 
310 int
311 jailed(struct ucred *cred)
312 {
313     return (0);
314 }
315 
316 /*
317  * Return 1 if the passed credential is in a jail and that jail does not
318  * have its own virtual network stack, otherwise 0.
319  */
320 int
321 jailed_without_vnet(struct ucred *cred)
322 {
323     return (0);
324 }
325 
326 int
327 priv_check(struct thread *td, int priv)
328 {
329     return (0);
330 }
331 
332 int
333 priv_check_cred(struct ucred *cred, int priv, int flags)
334 {
335     return (0);
336 }
337 
338 
339 int
340 vslock(void *addr, size_t len)
341 {
342     return (0);
343 }
344 
345 void
346 vsunlock(void *addr, size_t len)
347 {
348 
349 }
350 
351 
352 /*
353  * Check that a proposed value to load into the .it_value or
354  * .it_interval part of an interval timer is acceptable, and
355  * fix it to have at least minimal value (i.e. if it is less
356  * than the resolution of the clock, round it up.)
357  */
358 int
359 itimerfix(struct timeval *tv)
360 {
361 
362     if (tv->tv_sec < 0 || tv->tv_usec < 0 || tv->tv_usec >= 1000000)
363         return (EINVAL);
364     if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick)
365         tv->tv_usec = tick;
366     return (0);
367 }
368 
369 /*
370  * Decrement an interval timer by a specified number
371  * of microseconds, which must be less than a second,
372  * i.e. < 1000000.  If the timer expires, then reload
373  * it.  In this case, carry over (usec - old value) to
374  * reduce the value reloaded into the timer so that
375  * the timer does not drift.  This routine assumes
376  * that it is called in a context where the timers
377  * on which it is operating cannot change in value.
378  */
379 int
380 itimerdecr(struct itimerval *itp, int usec)
381 {
382     if (itp->it_value.tv_usec < usec) {
383         if (itp->it_value.tv_sec == 0) {
384             /* expired, and already in next interval */
385             usec -= itp->it_value.tv_usec;
386             goto expire;
387         }
388         itp->it_value.tv_usec += 1000000;
389         itp->it_value.tv_sec--;
390     }
391     itp->it_value.tv_usec -= usec;
392     usec = 0;
393     if (timevalisset(&itp->it_value))
394         return (1);
395     /* expired, exactly at end of interval */
396 expire:
397     if (timevalisset(&itp->it_interval)) {
398         itp->it_value = itp->it_interval;
399         itp->it_value.tv_usec -= usec;
400         if (itp->it_value.tv_usec < 0) {
401             itp->it_value.tv_usec += 1000000;
402             itp->it_value.tv_sec--;
403         }
404     } else
405         itp->it_value.tv_usec = 0;        /* sec is already 0 */
406     return (0);
407 }
408 
409 /*
410  * Add and subtract routines for timevals.
411  * N.B.: subtract routine doesn't deal with
412  * results which are before the beginning,
413  * it just gets very confused in this case.
414  * Caveat emptor.
415  */
416 void
417 timevaladd(struct timeval *t1, const struct timeval *t2)
418 {
419     t1->tv_sec += t2->tv_sec;
420     t1->tv_usec += t2->tv_usec;
421     timevalfix(t1);
422 }
423 
424 void
425 timevalsub(struct timeval *t1, const struct timeval *t2)
426 {
427     t1->tv_sec -= t2->tv_sec;
428     t1->tv_usec -= t2->tv_usec;
429     timevalfix(t1);
430 }
431 
432 static void
433 timevalfix(struct timeval *t1)
434 {
435     if (t1->tv_usec < 0) {
436         t1->tv_sec--;
437         t1->tv_usec += 1000000;
438     }
439     if (t1->tv_usec >= 1000000) {
440         t1->tv_sec++;
441         t1->tv_usec -= 1000000;
442     }
443 }
444 
445 /*
446  * ratecheck(): simple time-based rate-limit checking.
447  */
448 int
449 ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
450 {
451     struct timeval tv, delta;
452     int rv = 0;
453 
454     getmicrouptime(&tv);        /* NB: 10ms precision */
455     delta = tv;
456     timevalsub(&delta, lasttime);
457 
458     /*
459      * check for 0,0 is so that the message will be seen at least once,
460      * even if interval is huge.
461      */
462     if (timevalcmp(&delta, mininterval, >=) ||
463         (lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) {
464         *lasttime = tv;
465         rv = 1;
466     }
467 
468     return (rv);
469 }
470 
471 /*
472  * ppsratecheck(): packets (or events) per second limitation.
473  *
474  * Return 0 if the limit is to be enforced (e.g. the caller
475  * should drop a packet because of the rate limitation).
476  *
477  * maxpps of 0 always causes zero to be returned.  maxpps of -1
478  * always causes 1 to be returned; this effectively defeats rate
479  * limiting.
480  *
481  * Note that we maintain the struct timeval for compatibility
482  * with other bsd systems.  We reuse the storage and just monitor
483  * clock ticks for minimal overhead.
484  */
485 int
486 ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
487 {
488     int now;
489 
490     /*
491      * Reset the last time and counter if this is the first call
492      * or more than a second has passed since the last update of
493      * lasttime.
494      */
495     now = ticks;
496     if (lasttime->tv_sec == 0 || (u_int)(now - lasttime->tv_sec) >= hz) {
497         lasttime->tv_sec = now;
498         *curpps = 1;
499         return (maxpps != 0);
500     } else {
501         (*curpps)++;        /* NB: ignore potential overflow */
502         return (maxpps < 0 || *curpps < maxpps);
503     }
504 }
505 
506 /*
507  * Compute number of ticks in the specified amount of time.
508  */
509 int
510 tvtohz(tv)
511     struct timeval *tv;
512 {
513     register unsigned long ticks;
514     register long sec, usec;
515 
516     /*
517      * If the number of usecs in the whole seconds part of the time
518      * difference fits in a long, then the total number of usecs will
519      * fit in an unsigned long.  Compute the total and convert it to
520      * ticks, rounding up and adding 1 to allow for the current tick
521      * to expire.  Rounding also depends on unsigned long arithmetic
522      * to avoid overflow.
523      *
524      * Otherwise, if the number of ticks in the whole seconds part of
525      * the time difference fits in a long, then convert the parts to
526      * ticks separately and add, using similar rounding methods and
527      * overflow avoidance.  This method would work in the previous
528      * case but it is slightly slower and assumes that hz is integral.
529      *
530      * Otherwise, round the time difference down to the maximum
531      * representable value.
532      *
533      * If ints have 32 bits, then the maximum value for any timeout in
534      * 10ms ticks is 248 days.
535      */
536     sec = tv->tv_sec;
537     usec = tv->tv_usec;
538     if (usec < 0) {
539         sec--;
540         usec += 1000000;
541     }
542     if (sec < 0) {
543 #ifdef DIAGNOSTIC
544         if (usec > 0) {
545             sec++;
546             usec -= 1000000;
547         }
548         printf("tvotohz: negative time difference %ld sec %ld usec\n",
549                sec, usec);
550 #endif
551         ticks = 1;
552     } else if (sec <= LONG_MAX / 1000000)
553         ticks = (sec * 1000000 + (unsigned long)usec + (tick - 1))
554             / tick + 1;
555     else if (sec <= LONG_MAX / hz)
556         ticks = sec * hz
557             + ((unsigned long)usec + (tick - 1)) / tick + 1;
558     else
559         ticks = LONG_MAX;
560     if (ticks > INT_MAX)
561         ticks = INT_MAX;
562     return ((int)ticks);
563 }
564 
565 int
566 copyin(const void *uaddr, void *kaddr, size_t len)
567 {
568     memcpy(kaddr, uaddr, len);
569     return (0);
570 }
571 
572 int
573 copyout(const void *kaddr, void *uaddr, size_t len)
574 {
575     memcpy(uaddr, kaddr, len);
576     return (0);
577 }
578 
579 int
580 copystr(const void *kfaddr, void *kdaddr, size_t len, size_t *done)
581 {
582     size_t bytes;
583 
584     bytes = strlcpy(kdaddr, kfaddr, len);
585     if (done != NULL)
586         *done = bytes;
587 
588     return (0);
589 }
590 
591 
592 
593 int
594 copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done)
595 {
596     size_t bytes;
597 
598     bytes = strlcpy(kaddr, uaddr, len);
599     if (done != NULL)
600         *done = bytes;
601 
602     return (0);
603 }
604 
605 int
606 copyiniov(const struct iovec *iovp, u_int iovcnt, struct iovec **iov, int error)
607 {
608     u_int iovlen;
609 
610     *iov = NULL;
611     if (iovcnt > UIO_MAXIOV)
612         return (error);
613     iovlen = iovcnt * sizeof (struct iovec);
614     *iov = malloc(iovlen, M_IOV, M_WAITOK);
615     error = copyin(iovp, *iov, iovlen);
616     if (error) {
617         free(*iov, M_IOV);
618         *iov = NULL;
619     }
620     return (error);
621 }
622 
623 int
624 subyte(volatile void *base, int byte)
625 {
626     *(volatile char *)base = (uint8_t)byte;
627     return (0);
628 }
629 
630 static inline int
631 chglimit(struct uidinfo *uip, long *limit, int diff, rlim_t max, const char *name)
632 {
633     /* Don't allow them to exceed max, but allow subtraction. */
634     if (diff > 0 && max != 0) {
635         if (atomic_fetchadd_long(limit, (long)diff) + diff > max) {
636             atomic_subtract_long(limit, (long)diff);
637             return (0);
638         }
639     } else {
640         atomic_add_long(limit, (long)diff);
641         if (*limit < 0)
642             printf("negative %s for uid = %d\n", name, uip->ui_uid);
643     }
644     return (1);
645 }
646 
647 /*
648  * Change the count associated with number of processes
649  * a given user is using.  When 'max' is 0, don't enforce a limit
650  */
651 int
652 chgproccnt(struct uidinfo *uip, int diff, rlim_t max)
653 {
654     return (chglimit(uip, &uip->ui_proccnt, diff, max, "proccnt"));
655 }
656 
657 /*
658  * Change the total socket buffer size a user has used.
659  */
660 int
661 chgsbsize(struct uidinfo *uip, u_int *hiwat, u_int to, rlim_t max)
662 {
663     int diff, rv;
664 
665     diff = to - *hiwat;
666     if (diff > 0 && max == 0) {
667         rv = 0;
668     } else {
669         rv = chglimit(uip, &uip->ui_sbsize, diff, max, "sbsize");
670         if (rv != 0)
671             *hiwat = to;
672     }
673     return (rv);
674 }
675 
676 /*
677  * Change the count associated with number of pseudo-terminals
678  * a given user is using.  When 'max' is 0, don't enforce a limit
679  */
680 int
681 chgptscnt(struct uidinfo *uip, int diff, rlim_t max)
682 {
683     return (chglimit(uip, &uip->ui_ptscnt, diff, max, "ptscnt"));
684 }
685 
686 int
687 chgkqcnt(struct uidinfo *uip, int diff, rlim_t max)
688 {
689     return (chglimit(uip, &uip->ui_kqcnt, diff, max, "kqcnt"));
690 }
691 
692 int
693 chgumtxcnt(struct uidinfo *uip, int diff, rlim_t max)
694 {
695     return (chglimit(uip, &uip->ui_umtxcnt, diff, max, "umtxcnt"));
696 }
697 
698 /*
699  * Allocate a new resource limits structure and initialize its
700  * reference count and mutex pointer.
701  */
702 struct plimit *
703 lim_alloc()
704 {
705     struct plimit *limp;
706 
707     limp = malloc(sizeof(struct plimit), M_PLIMIT, M_WAITOK);
708     refcount_init(&limp->pl_refcnt, 1);
709     return (limp);
710 }
711 
712 struct plimit *
713 lim_hold(struct plimit *limp)
714 {
715     refcount_acquire(&limp->pl_refcnt);
716     return (limp);
717 }
718 
719 /*
720  * Return the current (soft) limit for a particular system resource.
721  * The which parameter which specifies the index into the rlimit array
722  */
723 rlim_t
724 lim_cur(struct thread *td, int which)
725 {
726     struct rlimit rl;
727 
728     lim_rlimit(td, which, &rl);
729     return (rl.rlim_cur);
730 }
731 
732 rlim_t
733 lim_cur_proc(struct proc *p, int which)
734 {
735     struct rlimit rl;
736 
737     lim_rlimit_proc(p, which, &rl);
738     return (rl.rlim_cur);
739 }
740 
741 /*
742  * Return a copy of the entire rlimit structure for the system limit
743  * specified by 'which' in the rlimit structure pointed to by 'rlp'.
744  */
745 void
746 lim_rlimit(struct thread *td, int which, struct rlimit *rlp)
747 {
748     struct proc *p = td->td_proc;
749 
750     MPASS(td == curthread);
751     KASSERT(which >= 0 && which < RLIM_NLIMITS,
752         ("request for invalid resource limit"));
753     *rlp = p->p_limit->pl_rlimit[which];
754     if (p->p_sysent->sv_fixlimit != NULL)
755         p->p_sysent->sv_fixlimit(rlp, which);
756 }
757 
758 void
759 lim_rlimit_proc(struct proc *p, int which, struct rlimit *rlp)
760 {
761     PROC_LOCK_ASSERT(p, MA_OWNED);
762     KASSERT(which >= 0 && which < RLIM_NLIMITS,
763         ("request for invalid resource limit"));
764     *rlp = p->p_limit->pl_rlimit[which];
765     if (p->p_sysent->sv_fixlimit != NULL)
766         p->p_sysent->sv_fixlimit(rlp, which);
767 }
768 
769 int
770 useracc(void *addr, int len, int rw)
771 {
772     return (1);
773 }
774 
775 struct pgrp *
776 pgfind(pid_t pgid)
777 {
778     return (NULL);
779 }
780 
781 struct proc *
782 zpfind(pid_t pid)
783 {
784     return (NULL);
785 }
786 
787 
788 int
789 p_cansee(struct thread *td, struct proc *p)
790 {
791     return (0);
792 }
793 
794 struct proc *
795 pfind(pid_t pid)
796 {
797     return (NULL);
798 }
799 
800 int
801 pget(pid_t pid, int flags, struct proc **pp)
802 {
803     return (ESRCH);
804 }
805 
806 struct uidinfo uid0;
807 
808 struct uidinfo *
809 uifind(uid_t uid)
810 {
811     return (&uid0);
812 }
813 
814 /*
815  * Allocate a zeroed cred structure.
816  */
817 struct ucred *
818 crget(void)
819 {
820     register struct ucred *cr;
821 
822     cr = malloc(sizeof(*cr), M_CRED, M_WAITOK | M_ZERO);
823     refcount_init(&cr->cr_ref, 1);
824 
825     return (cr);
826 }
827 
828 /*
829  * Claim another reference to a ucred structure.
830  */
831 struct ucred *
832 crhold(struct ucred *cr)
833 {
834     refcount_acquire(&cr->cr_ref);
835     return (cr);
836 }
837 
838 /*
839  * Free a cred structure.  Throws away space when ref count gets to 0.
840  */
841 void
842 crfree(struct ucred *cr)
843 {
844     KASSERT(cr->cr_ref > 0, ("bad ucred refcount: %d", cr->cr_ref));
845     KASSERT(cr->cr_ref != 0xdeadc0de, ("dangling reference to ucred"));
846     if (refcount_release(&cr->cr_ref)) {
847 
848         free(cr, M_CRED);
849     }
850 }
851 
852 /*
853  * Fill in a struct xucred based on a struct ucred.
854  */
855 
856 void
857 cru2x(struct ucred *cr, struct xucred *xcr)
858 {
859 #if 0
860     int ngroups;
861 
862     bzero(xcr, sizeof(*xcr));
863     xcr->cr_version = XUCRED_VERSION;
864     xcr->cr_uid = cr->cr_uid;
865 
866     ngroups = MIN(cr->cr_ngroups, XU_NGROUPS);
867     xcr->cr_ngroups = ngroups;
868     bcopy(cr->cr_groups, xcr->cr_groups,
869         ngroups * sizeof(*cr->cr_groups));
870 #endif
871 }
872 
873 
874 int
875 cr_cansee(struct ucred *u1, struct ucred *u2)
876 {
877     return (0);
878 }
879 
880 int
881 cr_canseesocket(struct ucred *cred, struct socket *so)
882 {
883     return (0);
884 }
885 
886 int
887 cr_canseeinpcb(struct ucred *cred, struct inpcb *inp)
888 {
889     return (0);
890 }
891 
892 int
893 securelevel_gt(struct ucred *cr, int level)
894 {
895     return (0);
896 }
897 
898 int
899 securelevel_ge(struct ucred *cr, int level)
900 {
901         return (0);
902 }
903 
904 /**
905  * @brief Send a 'notification' to userland, using standard ways
906  */
907 void
908 devctl_notify(const char *system, const char *subsystem, const char *type,
909     const char *data)
910 {
911 
912 }
913 
914 void
915 cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
916 {
917 
918 }
919 
920 static void
921 configure_final(void *dummy)
922 {
923     cold = 0;
924 }
925 
926 /*
927  * Send a SIGIO or SIGURG signal to a process or process group using stored
928  * credentials rather than those of the current process.
929  */
930 void
931 pgsigio(sigiop, sig, checkctty)
932     struct sigio **sigiop;
933     int sig, checkctty;
934 {
935     panic("SIGIO not supported yet\n");
936 #ifdef notyet
937     ksiginfo_t ksi;
938     struct sigio *sigio;
939 
940     ksiginfo_init(&ksi);
941     ksi.ksi_signo = sig;
942     ksi.ksi_code = SI_KERNEL;
943 
944     SIGIO_LOCK();
945     sigio = *sigiop;
946     if (sigio == NULL) {
947         SIGIO_UNLOCK();
948         return;
949     }
950     if (sigio->sio_pgid > 0) {
951         PROC_LOCK(sigio->sio_proc);
952         if (CANSIGIO(sigio->sio_ucred, sigio->sio_proc->p_ucred))
953             psignal(sigio->sio_proc, sig);
954         PROC_UNLOCK(sigio->sio_proc);
955     } else if (sigio->sio_pgid < 0) {
956         struct proc *p;
957 
958         PGRP_LOCK(sigio->sio_pgrp);
959         LIST_FOREACH(p, &sigio->sio_pgrp->pg_members, p_pglist) {
960             PROC_LOCK(p);
961             if (CANSIGIO(sigio->sio_ucred, p->p_ucred) &&
962                 (checkctty == 0 || (p->p_flag & P_CONTROLT)))
963                 psignal(p, sig);
964             PROC_UNLOCK(p);
965         }
966         PGRP_UNLOCK(sigio->sio_pgrp);
967     }
968     SIGIO_UNLOCK();
969 #endif
970 }
971 
972 void
973 kproc_exit(int ecode)
974 {
975     panic("kproc_exit unsupported");
976 }
977 
978 vm_offset_t
979 kmem_malloc(struct vmem *vmem, vm_size_t bytes, int flags)
980 {
981     void *alloc = ff_mmap(NULL, bytes, ff_PROT_READ|ff_PROT_WRITE, ff_MAP_ANON|ff_MAP_PRIVATE, -1, 0);
982     if ((flags & M_ZERO) && alloc != NULL)
983         bzero(alloc, bytes);
984     return ((vm_offset_t)alloc);
985 }
986 
987 void
988 kmem_free(struct vmem *vmem, vm_offset_t addr, vm_size_t size)
989 {
990     ff_munmap((void *)addr, size);
991 }
992 
993 vm_offset_t
994 kmem_alloc_contig(struct vmem *vmem, vm_size_t size, int flags, vm_paddr_t low,
995     vm_paddr_t high, u_long alignment, vm_paddr_t boundary, vm_memattr_t memattr)
996 {
997     return (kmem_malloc(vmem, size, flags));
998 }
999 
1000 void
1001 malloc_init(void *data)
1002 {
1003     /* Nothing to do here */
1004 }
1005 
1006 
1007 void
1008 malloc_uninit(void *data)
1009 {
1010     /* Nothing to do here */
1011 }
1012 
1013 
1014 void *
1015 malloc(unsigned long size, struct malloc_type *type, int flags)
1016 {
1017     void *alloc;
1018 
1019     do {
1020         alloc = ff_malloc(size);
1021         if (alloc || !(flags & M_WAITOK))
1022             break;
1023 
1024         pause("malloc", hz/100);
1025     } while (alloc == NULL);
1026 
1027     if ((flags & M_ZERO) && alloc != NULL)
1028         bzero(alloc, size);
1029     return (alloc);
1030 }
1031 
1032 void
1033 free(void *addr, struct malloc_type *type)
1034 {
1035     ff_free(addr);
1036 }
1037 
1038 
1039 void *
1040 realloc(void *addr, unsigned long size, struct malloc_type *type,
1041     int flags)
1042 {
1043     return (ff_realloc(addr, size));
1044 }
1045 
1046 void *
1047 reallocf(void *addr, unsigned long size, struct malloc_type *type,
1048      int flags)
1049 {
1050     void *mem;
1051 
1052     if ((mem = ff_realloc(addr, size)) == NULL)
1053         ff_free(addr);
1054 
1055     return (mem);
1056 }
1057 
1058 void
1059 DELAY(int delay)
1060 {
1061     struct timespec rqt;
1062 
1063     if (delay < 1000)
1064         return;
1065 
1066     rqt.tv_nsec = 1000*((unsigned long)delay);
1067     rqt.tv_sec = 0;
1068     /*
1069      * FIXME: We shouldn't sleep in dpdk apps.
1070      */
1071     //nanosleep(&rqt, NULL);
1072 }
1073 
1074 void
1075 bwillwrite(void)
1076 {
1077 
1078 }
1079 
1080 off_t
1081 foffset_lock(struct file *fp, int flags)
1082 {
1083     struct mtx *mtxp;
1084     off_t res;
1085 
1086     KASSERT((flags & FOF_OFFSET) == 0, ("FOF_OFFSET passed"));
1087 
1088 #if OFF_MAX <= LONG_MAX
1089     /*
1090      * Caller only wants the current f_offset value.  Assume that
1091      * the long and shorter integer types reads are atomic.
1092      */
1093     if ((flags & FOF_NOLOCK) != 0)
1094         return (fp->f_offset);
1095 #endif
1096 
1097     /*
1098      * According to McKusick the vn lock was protecting f_offset here.
1099      * It is now protected by the FOFFSET_LOCKED flag.
1100      */
1101     mtxp = mtx_pool_find(mtxpool_sleep, fp);
1102     mtx_lock(mtxp);
1103     /*
1104     if ((flags & FOF_NOLOCK) == 0) {
1105         while (fp->f_vnread_flags & FOFFSET_LOCKED) {
1106             fp->f_vnread_flags |= FOFFSET_LOCK_WAITING;
1107             msleep(&fp->f_vnread_flags, mtxp, PUSER -1,
1108                 "vofflock", 0);
1109         }
1110         fp->f_vnread_flags |= FOFFSET_LOCKED;
1111     }
1112     */
1113     res = fp->f_offset;
1114     mtx_unlock(mtxp);
1115     return (res);
1116 }
1117 
1118 void
1119 sf_ext_free(void *arg1, void *arg2)
1120 {
1121     panic("sf_ext_free not implemented.\n");
1122 }
1123 
1124 void
1125 sf_ext_free_nocache(void *arg1, void *arg2)
1126 {
1127     panic("sf_ext_free_nocache not implemented.\n");
1128 }
1129 
1130 void
1131 sched_bind(struct thread *td, int cpu)
1132 {
1133 
1134 }
1135 
1136 void
1137 sched_unbind(struct thread* td)
1138 {
1139 
1140 }
1141 
1142 void
1143 getcredhostid(struct ucred *cred, unsigned long *hostid)
1144 {
1145     *hostid = 0;
1146 }
1147 
1148 /*
1149  * Check if gid is a member of the group set.
1150  */
1151 int
1152 groupmember(gid_t gid, struct ucred *cred)
1153 {
1154 	int l;
1155 	int h;
1156 	int m;
1157 
1158 	if (cred->cr_groups[0] == gid)
1159 		return(1);
1160 
1161 	/*
1162 	 * If gid was not our primary group, perform a binary search
1163 	 * of the supplemental groups.  This is possible because we
1164 	 * sort the groups in crsetgroups().
1165 	 */
1166 	l = 1;
1167 	h = cred->cr_ngroups;
1168 	while (l < h) {
1169 		m = l + ((h - l) / 2);
1170 		if (cred->cr_groups[m] < gid)
1171 			l = m + 1;
1172 		else
1173 			h = m;
1174 	}
1175 	if ((l < cred->cr_ngroups) && (cred->cr_groups[l] == gid))
1176 		return (1);
1177 
1178 	return (0);
1179 }
1180 
1181