1/*	$NetBSD: kern.h,v 1.5 2020/11/01 20:58:38 christos Exp $	*/
2
3/*
4 * Copyright (c) 2007-2011 Antti Kantee.  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
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16 * 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 AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#ifndef _SYS_RUMP_PRIVATE_H_
29#define _SYS_RUMP_PRIVATE_H_
30
31#include <sys/param.h>
32#include <sys/cpu.h>
33#include <sys/device.h>
34#include <sys/lwp.h>
35#include <sys/proc.h>
36#include <sys/systm.h>
37#include <sys/types.h>
38
39#include <uvm/uvm.h>
40#include <uvm/uvm_object.h>
41#include <uvm/uvm_page.h>
42
43#include <rump/rump.h>
44#include <rump/rumpuser.h>
45
46#include <rump-sys/kern_if.h>
47
48extern struct rumpuser_mtx *rump_giantlock;
49
50extern int rump_threads;
51extern struct device rump_rootdev;
52
53extern struct sysent rump_sysent[];
54extern const uint32_t rump_sysent_nomodbits[];
55
56enum rump_component_type {
57	RUMP_COMPONENT_DEV,
58		RUMP_COMPONENT_DEV_AFTERMAINBUS,
59	RUMP_COMPONENT_NET,
60		RUMP_COMPONENT_NET_ROUTE,
61		RUMP_COMPONENT_NET_IF,
62		RUMP_COMPONENT_NET_IFCFG,
63	RUMP_COMPONENT_VFS,
64	RUMP_COMPONENT_KERN,
65		RUMP_COMPONENT_KERN_VFS,
66	RUMP_COMPONENT_POSTINIT,
67	RUMP_COMPONENT_SYSCALL,
68
69	RUMP__FACTION_DEV,
70	RUMP__FACTION_VFS,
71	RUMP__FACTION_NET,
72
73	RUMP_COMPONENT_MAX,
74};
75struct rump_component {
76	enum rump_component_type rc_type;
77	void (*rc_init)(void);
78	LIST_ENTRY(rump_component) rc_entries;
79};
80
81/*
82 * If RUMP_USE_CTOR is defined, we use __attribute__((constructor)) to
83 * determine which components are present when rump_init() is called.
84 * Otherwise, we use link sets and the __start/__stop symbols generated
85 * by the toolchain.
86 */
87
88#ifdef RUMP_USE_CTOR
89#define _RUMP_COMPONENT_REGISTER(type)					\
90static void rumpcomp_ctor##type(void) __attribute__((constructor));	\
91static void rumpcomp_ctor##type(void)					\
92{									\
93	rump_component_load(&rumpcomp##type);				\
94}									\
95static void rumpcomp_dtor##type(void) __attribute__((destructor));	\
96static void rumpcomp_dtor##type(void)					\
97{									\
98	rump_component_unload(&rumpcomp##type);				\
99}
100
101#else /* RUMP_USE_CTOR */
102
103#define _RUMP_COMPONENT_REGISTER(type)					\
104__link_set_add_rodata(rump_components, rumpcomp##type);
105#endif /* RUMP_USE_CTOR */
106
107#define RUMP_COMPONENT(type)				\
108static void rumpcompinit##type(void);			\
109static struct rump_component rumpcomp##type = {	\
110	.rc_type = type,				\
111	.rc_init = rumpcompinit##type,			\
112};							\
113_RUMP_COMPONENT_REGISTER(type)				\
114static void rumpcompinit##type(void)
115
116#define FLAWLESSCALL(call)						\
117do {									\
118	int att_error;							\
119	if ((att_error = call) != 0)					\
120		panic("\"%s\" failed", #call);				\
121} while (/*CONSTCOND*/0)
122
123#define RUMPMEM_UNLIMITED ((unsigned long)-1)
124extern unsigned long rump_physmemlimit;
125
126extern struct vmspace *rump_vmspace_local;
127extern struct pmap rump_pmap_local;
128#define RUMP_LOCALPROC_P(p) \
129    (p->p_vmspace == vmspace_kernel() || p->p_vmspace == rump_vmspace_local)
130
131/* vm bundle for remote clients.  the last member is the hypercall cookie */
132struct rump_spctl {
133	struct vmspace spctl_vm;
134	void *spctl;
135};
136#define RUMP_SPVM2CTL(vm) (((struct rump_spctl *)vm)->spctl)
137
138void		rump_component_load(const struct rump_component *);
139void		rump_component_unload(struct rump_component *);
140void		rump_component_init(enum rump_component_type);
141int		rump_component_count(enum rump_component_type);
142
143typedef void	(*rump_proc_vfs_init_fn)(struct proc *);
144typedef void	(*rump_proc_vfs_release_fn)(struct proc *);
145extern rump_proc_vfs_init_fn rump_proc_vfs_init;
146extern rump_proc_vfs_release_fn rump_proc_vfs_release;
147
148extern struct cpu_info rump_bootcpu;
149
150extern bool rump_ttycomponent;
151
152struct lwp *	rump__lwproc_alloclwp(struct proc *);
153void		rump__lwproc_lwphold(void);
154void		rump__lwproc_lwprele(void);
155
156void	rump_cpus_bootstrap(int *);
157void	rump_biglock_init(void);
158void	rump_scheduler_init(int);
159void	rump_schedule(void);
160void	rump_unschedule(void);
161void 	rump_schedule_cpu(struct lwp *);
162void 	rump_schedule_cpu_interlock(struct lwp *, void *);
163void	rump_unschedule_cpu(struct lwp *);
164void	rump_unschedule_cpu_interlock(struct lwp *, void *);
165void	rump_unschedule_cpu1(struct lwp *, void *);
166int	rump_syscall(int, void *, size_t, register_t *);
167
168struct rump_onesyscall {
169	int ros_num;
170	sy_call_t *ros_handler;
171};
172void	rump_syscall_boot_establish(const struct rump_onesyscall *, size_t);
173
174void	rump_schedlock_cv_wait(struct rumpuser_cv *);
175int	rump_schedlock_cv_timedwait(struct rumpuser_cv *,
176				    const struct timespec *);
177void	rump_schedlock_cv_signal(struct cpu_info *, struct rumpuser_cv *);
178
179void	rump_user_schedule(int, void *);
180void	rump_user_unschedule(int, int *, void *);
181
182void	rump_cpu_attach(struct cpu_info *);
183
184struct clockframe *rump_cpu_makeclockframe(void);
185
186void	rump_kernel_bigwrap(int *);
187void	rump_kernel_bigunwrap(int);
188
189void	rump_tsleep_init(void);
190
191void	rump_intr_init(int);
192void	rump_softint_run(struct cpu_info *);
193
194void	*rump_hypermalloc(size_t, int, bool, const char *);
195void	rump_hyperfree(void *, size_t);
196
197void	rump_xc_highpri(struct cpu_info *);
198
199void	rump_thread_init(void);
200void	rump_thread_allow(struct lwp *);
201
202void	rump_consdev_init(void);
203
204void	rump_hyperentropy_init(void);
205
206void	rump_lwproc_init(void);
207void	rump_lwproc_curlwp_set(struct lwp *);
208void	rump_lwproc_curlwp_clear(struct lwp *);
209int	rump_lwproc_rfork_vmspace(struct vmspace *, int);
210
211/*
212 * sysproxy is an optional component.  The interfaces with "hyp"
213 * in the name come into the rump kernel from the client or sysproxy
214 * stub, the rest go out of the rump kernel.
215 */
216struct rump_sysproxy_ops {
217	int (*rspo_copyin)(void *, const void *, void *, size_t);
218	int (*rspo_copyinstr)(void *, const void *, void *, size_t *);
219	int (*rspo_copyout)(void *, const void *, void *, size_t);
220	int (*rspo_copyoutstr)(void *, const void *, void *, size_t *);
221	int (*rspo_anonmmap)(void *, size_t, void **);
222	int (*rspo_raise)(void *, int);
223	void (*rspo_fini)(void *);
224
225	pid_t (*rspo_hyp_getpid)(void);
226	int (*rspo_hyp_syscall)(int, void *, long *);
227	int (*rspo_hyp_rfork)(void *, int, const char *);
228	void (*rspo_hyp_lwpexit)(void);
229	void (*rspo_hyp_execnotify)(const char *);
230};
231extern struct rump_sysproxy_ops rump_sysproxy_ops;
232#define rump_sysproxy_copyin(arg, raddr, laddr, len)			\
233	rump_sysproxy_ops.rspo_copyin(arg, raddr, laddr, len)
234#define rump_sysproxy_copyinstr(arg, raddr, laddr, lenp)		\
235	rump_sysproxy_ops.rspo_copyinstr(arg, raddr, laddr, lenp)
236#define rump_sysproxy_copyout(arg, laddr, raddr, len)			\
237	rump_sysproxy_ops.rspo_copyout(arg, laddr, raddr, len)
238#define rump_sysproxy_copyoutstr(arg, laddr, raddr, lenp)		\
239	rump_sysproxy_ops.rspo_copyoutstr(arg, laddr, raddr, lenp)
240#define rump_sysproxy_anonmmap(arg, howmuch, addr)			\
241	rump_sysproxy_ops.rspo_anonmmap(arg, howmuch, addr)
242#define rump_sysproxy_raise(arg, signo)					\
243	rump_sysproxy_ops.rspo_raise(arg, signo)
244#define rump_sysproxy_fini(arg)						\
245	rump_sysproxy_ops.rspo_fini(arg)
246#define rump_sysproxy_hyp_getpid()					\
247	rump_sysproxy_ops.rspo_hyp_getpid()
248#define rump_sysproxy_hyp_syscall(num, arg, retval)			\
249	rump_sysproxy_ops.rspo_hyp_syscall(num, arg, retval)
250#define rump_sysproxy_hyp_rfork(priv, flag, comm)			\
251	rump_sysproxy_ops.rspo_hyp_rfork(priv, flag, comm)
252#define rump_sysproxy_hyp_lwpexit()					\
253	rump_sysproxy_ops.rspo_hyp_lwpexit()
254#define rump_sysproxy_hyp_execnotify(comm)				\
255	rump_sysproxy_ops.rspo_hyp_execnotify(comm)
256
257#endif /* _SYS_RUMP_PRIVATE_H_ */
258