diff options
Diffstat (limited to 'sys/kern')
| -rw-r--r-- | sys/kern/kern_linker.c | 15 | ||||
| -rw-r--r-- | sys/kern/kern_poll.c | 1 | ||||
| -rw-r--r-- | sys/kern/kern_sysctl.c | 105 | ||||
| -rw-r--r-- | sys/kern/kern_uuid.c | 1 | ||||
| -rw-r--r-- | sys/kern/kern_vimage.c | 119 | ||||
| -rw-r--r-- | sys/kern/link_elf.c | 55 | ||||
| -rw-r--r-- | sys/kern/link_elf_obj.c | 43 | ||||
| -rw-r--r-- | sys/kern/uipc_domain.c | 6 |
8 files changed, 119 insertions, 226 deletions
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 9775059fd0ab..1768e69a7c40 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -1334,23 +1334,8 @@ kldsym(struct thread *td, struct kldsym_args *uap) break; } } -#ifndef VIMAGE_GLOBALS - /* - * If the symbol is not found in global namespace, - * try to look it up in the current vimage namespace. - */ - if (lf == NULL) { - CURVNET_SET(TD_TO_VNET(td)); - error = vi_symlookup(&lookup, symstr); - CURVNET_RESTORE(); - if (error == 0) - error = copyout(&lookup, uap->data, - sizeof(lookup)); - } -#else if (lf == NULL) error = ENOENT; -#endif } KLD_UNLOCK(); out: diff --git a/sys/kern/kern_poll.c b/sys/kern/kern_poll.c index d9cf49fa28ce..53962402f453 100644 --- a/sys/kern/kern_poll.c +++ b/sys/kern/kern_poll.c @@ -545,7 +545,6 @@ ether_poll_deregister(struct ifnet *ifp) static int poll_switch(SYSCTL_HANDLER_ARGS) { - INIT_VNET_NET(curvnet); struct ifnet *ifp; int error; int val = polling; diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 9e615449a7b3..94e45f13caf4 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -59,6 +59,8 @@ __FBSDID("$FreeBSD$"); #include <sys/ktrace.h> #endif +#include <net/vnet.h> + #include <security/mac/mac_framework.h> #include <vm/vm.h> @@ -936,33 +938,9 @@ sysctl_handle_int(SYSCTL_HANDLER_ARGS) return (error); } -#ifdef VIMAGE -int -sysctl_handle_v_int(SYSCTL_HANDLER_ARGS) -{ - int tmpout, error = 0; - - SYSCTL_RESOLVE_V_ARG1(); - - /* - * Attempt to get a coherent snapshot by making a copy of the data. - */ - tmpout = *(int *)arg1; - error = SYSCTL_OUT(req, &tmpout, sizeof(int)); - - if (error || !req->newptr) - return (error); - - if (!arg1) - error = EPERM; - else - error = SYSCTL_IN(req, arg1, sizeof(int)); - return (error); -} -#endif - /* * Based on on sysctl_handle_int() convert milliseconds into ticks. + * Note: this is used by TCP. */ int @@ -970,8 +948,11 @@ sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS) { int error, s, tt; - SYSCTL_RESOLVE_V_ARG1(); - +#ifdef VIMAGE + if (arg1 != NULL) + arg1 = (void *)(TD_TO_VNET(req->td)->vnet_data_base + + (uintptr_t)arg1); +#endif tt = *(int *)arg1; s = (int)((int64_t)tt * 1000 / hz); @@ -1097,47 +1078,6 @@ retry: return (error); } -#ifdef VIMAGE -int -sysctl_handle_v_string(SYSCTL_HANDLER_ARGS) -{ - int error=0; - char *tmparg; - size_t outlen; - - SYSCTL_RESOLVE_V_ARG1(); - - /* - * Attempt to get a coherent snapshot by copying to a - * temporary kernel buffer. - */ -retry: - outlen = strlen((char *)arg1)+1; - tmparg = malloc(outlen, M_SYSCTLTMP, M_WAITOK); - - if (strlcpy(tmparg, (char *)arg1, outlen) >= outlen) { - free(tmparg, M_SYSCTLTMP); - goto retry; - } - - error = SYSCTL_OUT(req, tmparg, outlen); - free(tmparg, M_SYSCTLTMP); - - if (error || !req->newptr) - return (error); - - if ((req->newlen - req->newidx) >= arg2) { - error = EINVAL; - } else { - arg2 = (req->newlen - req->newidx); - error = SYSCTL_IN(req, arg1, arg2); - ((char *)arg1)[arg2] = '\0'; - } - - return (error); -} -#endif - /* * Handle any kind of opaque data. * arg1 points to it, arg2 is the size. @@ -1175,35 +1115,6 @@ retry: return (error); } -#ifdef VIMAGE -int -sysctl_handle_v_opaque(SYSCTL_HANDLER_ARGS) -{ - int error, tries; - u_int generation; - struct sysctl_req req2; - - SYSCTL_RESOLVE_V_ARG1(); - - tries = 0; - req2 = *req; -retry: - generation = curthread->td_generation; - error = SYSCTL_OUT(req, arg1, arg2); - if (error) - return (error); - tries++; - if (generation != curthread->td_generation && tries < 3) { - *req = req2; - goto retry; - } - - error = SYSCTL_IN(req, arg1, arg2); - - return (error); -} -#endif - /* * Transfer functions to/from kernel space. * XXX: rather untested at this point diff --git a/sys/kern/kern_uuid.c b/sys/kern/kern_uuid.c index a0c26b92bd01..cd88538f7e38 100644 --- a/sys/kern/kern_uuid.c +++ b/sys/kern/kern_uuid.c @@ -89,7 +89,6 @@ MTX_SYSINIT(uuid_lock, &uuid_mutex, "UUID generator mutex lock", MTX_DEF); static void uuid_node(uint16_t *node) { - INIT_VNET_NET(curvnet); struct ifnet *ifp; struct ifaddr *ifa; struct sockaddr_dl *sdl; diff --git a/sys/kern/kern_vimage.c b/sys/kern/kern_vimage.c index 9ee3e1dc4640..daa9b9f4f96c 100644 --- a/sys/kern/kern_vimage.c +++ b/sys/kern/kern_vimage.c @@ -53,8 +53,6 @@ __FBSDID("$FreeBSD$"); #include <net/route.h> #include <net/vnet.h> -#ifndef VIMAGE_GLOBALS - MALLOC_DEFINE(M_VIMAGE, "vimage", "vimage resource container"); MALLOC_DEFINE(M_VNET, "vnet", "network stack control block"); MALLOC_DEFINE(M_VPROCG, "vprocg", "process group control block"); @@ -65,13 +63,11 @@ static void vnet_mod_complete_registration(struct vnet_modlink *); static int vnet_mod_constructor(struct vnet_modlink *); static int vnet_mod_destructor(struct vnet_modlink *); -#ifdef VIMAGE static struct vimage *vi_alloc(struct vimage *, char *); static int vi_destroy(struct vimage *); static struct vimage *vimage_get_next(struct vimage *, struct vimage *, int); static void vimage_relative_name(struct vimage *, struct vimage *, char *, int); -#endif #define VNET_LIST_WLOCK() \ mtx_lock(&vnet_list_refc_mtx); \ @@ -81,17 +77,11 @@ static void vimage_relative_name(struct vimage *, struct vimage *, #define VNET_LIST_WUNLOCK() \ mtx_unlock(&vnet_list_refc_mtx); -#ifdef VIMAGE struct vimage_list_head vimage_head; struct vnet_list_head vnet_head; struct vprocg_list_head vprocg_head; -#else -#ifndef VIMAGE_GLOBALS struct vprocg vprocg_0; -#endif -#endif -#ifdef VIMAGE struct cv vnet_list_condvar; struct mtx vnet_list_refc_mtx; int vnet_list_refc = 0; @@ -100,9 +90,7 @@ static u_int last_vi_id = 0; static u_int last_vprocg_id = 0; struct vnet *vnet0; -#endif -#ifdef VIMAGE /* * Move an ifnet to or from another vnet, specified by the jail id. If a @@ -396,8 +384,6 @@ vimage_get_next(struct vimage *top, struct vimage *where, int recurse) return (NULL); } -#endif /* VIMAGE */ /* User interface block */ - /* * Kernel interfaces and handlers. @@ -540,25 +526,11 @@ vnet_mod_constructor(struct vnet_modlink *vml) if (vml->vml_iarg) printf("/%s", vml->vml_iname); printf(": "); -#ifdef VIMAGE - if (vmi->vmi_size) - printf("malloc(%zu); ", vmi->vmi_size); -#endif if (vmi->vmi_iattach != NULL) printf("iattach()"); printf("\n"); #endif -#ifdef VIMAGE - if (vmi->vmi_size) { - void *mem = malloc(vmi->vmi_size, M_VNET, - M_NOWAIT | M_ZERO); - if (mem == NULL) /* XXX should return error, not panic. */ - panic("malloc for %s\n", vmi->vmi_name); - curvnet->mod_data[vmi->vmi_id] = mem; - } -#endif - if (vmi->vmi_iattach != NULL) vmi->vmi_iattach(vml->vml_iarg); @@ -577,63 +549,15 @@ vnet_mod_destructor(struct vnet_modlink *vml) printf(": "); if (vmi->vmi_idetach != NULL) printf("idetach(); "); -#ifdef VIMAGE - if (vmi->vmi_size) - printf("free()"); -#endif printf("\n"); #endif if (vmi->vmi_idetach) vmi->vmi_idetach(vml->vml_iarg); -#ifdef VIMAGE - if (vmi->vmi_size) { - if (curvnet->mod_data[vmi->vmi_id] == NULL) - panic("vi_destroy: %s\n", vmi->vmi_name); - free(curvnet->mod_data[vmi->vmi_id], M_VNET); - curvnet->mod_data[vmi->vmi_id] = NULL; - } -#endif - return (0); } -/* - * vi_symlookup() attempts to resolve name to address queries for - * variables which have been moved from global namespace to virtualization - * container structures, but are still directly accessed from legacy - * userspace processes via kldsym(2) and kmem(4) interfaces. - */ -int -vi_symlookup(struct kld_sym_lookup *lookup, char *symstr) -{ - struct vnet_modlink *vml; - struct vnet_symmap *mapentry; - - TAILQ_FOREACH(vml, &vnet_modlink_head, vml_mod_le) { - if (vml->vml_modinfo->vmi_symmap == NULL) - continue; - for (mapentry = vml->vml_modinfo->vmi_symmap; - mapentry->name != NULL; mapentry++) { - if (strcmp(symstr, mapentry->name) == 0) { -#ifdef VIMAGE - lookup->symvalue = - (u_long) curvnet->mod_data[ - vml->vml_modinfo->vmi_id]; - lookup->symvalue += mapentry->offset; -#else - lookup->symvalue = (u_long) mapentry->offset; -#endif - lookup->symsize = mapentry->size; - return (0); - } - } - } - return (ENOENT); -} - -#ifdef VIMAGE struct vnet * vnet_alloc(void) { @@ -642,6 +566,7 @@ vnet_alloc(void) vnet = malloc(sizeof(struct vnet), M_VNET, M_WAITOK | M_ZERO); vnet->vnet_magic_n = VNET_MAGIC_N; + vnet_data_init(vnet); /* Initialize / attach vnet module instances. */ CURVNET_SET_QUIET(vnet); @@ -669,7 +594,6 @@ vnet_destroy(struct vnet *vnet) VNET_LIST_WUNLOCK(); CURVNET_SET_QUIET(vnet); - INIT_VNET_NET(vnet); /* Return all inherited interfaces to their parent vnets. */ TAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) { @@ -685,10 +609,22 @@ vnet_destroy(struct vnet *vnet) CURVNET_RESTORE(); /* Hopefully, we are OK to free the vnet container itself. */ + vnet_data_destroy(vnet); vnet->vnet_magic_n = 0xdeadbeef; free(vnet, M_VNET); } +void +vnet_foreach(void (*vnet_foreach_fn)(struct vnet *, void *), void *arg) +{ + struct vnet *vnet; + + VNET_LIST_RLOCK(); + LIST_FOREACH(vnet, &vnet_head, vnet_le) + vnet_foreach_fn(vnet, arg); + VNET_LIST_RUNLOCK(); +} + static struct vimage * vi_alloc(struct vimage *parent, char *name) { @@ -757,7 +693,6 @@ vi_destroy(struct vimage *vip) return (0); } -#endif /* VIMAGE */ static void vi_init(void *unused) @@ -766,7 +701,6 @@ vi_init(void *unused) TAILQ_INIT(&vnet_modlink_head); TAILQ_INIT(&vnet_modpending_head); -#ifdef VIMAGE LIST_INIT(&vimage_head); LIST_INIT(&vprocg_head); LIST_INIT(&vnet_head); @@ -783,7 +717,6 @@ vi_init(void *unused) * curvnet recursions. */ curvnet = prison0.pr_vnet = vnet0 = LIST_FIRST(&vnet_head); -#endif } static void @@ -791,9 +724,7 @@ vi_init_done(void *unused) { struct vnet_modlink *vml_iter; -#ifdef VIMAGE curvnet = NULL; -#endif if (TAILQ_EMPTY(&vnet_modpending_head)) return; @@ -809,45 +740,21 @@ vi_init_done(void *unused) SYSINIT(vimage, SI_SUB_VIMAGE, SI_ORDER_FIRST, vi_init, NULL); SYSINIT(vimage_done, SI_SUB_VIMAGE_DONE, SI_ORDER_FIRST, vi_init_done, NULL); -#endif /* !VIMAGE_GLOBALS */ -#ifdef VIMAGE #ifdef DDB -static void -db_vnet_ptr(void *arg) -{ - - if (arg) - db_printf(" %p", arg); - else -#if SIZE_MAX == UINT32_MAX /* 32-bit arch */ - db_printf(" 0"); -#else /* 64-bit arch, most probaly... */ - db_printf(" 0"); -#endif -} - DB_SHOW_COMMAND(vnets, db_show_vnets) { VNET_ITERATOR_DECL(vnet_iter); #if SIZE_MAX == UINT32_MAX /* 32-bit arch */ db_printf(" vnet ifs socks"); - db_printf(" net inet inet6 ipsec netgraph\n"); #else /* 64-bit arch, most probaly... */ db_printf(" vnet ifs socks"); - db_printf(" net inet inet6 ipsec netgraph\n"); #endif VNET_FOREACH(vnet_iter) { db_printf("%p %3d %5d", vnet_iter, vnet_iter->ifcnt, vnet_iter->sockcnt); - db_vnet_ptr(vnet_iter->mod_data[VNET_MOD_NET]); - db_vnet_ptr(vnet_iter->mod_data[VNET_MOD_INET]); - db_vnet_ptr(vnet_iter->mod_data[VNET_MOD_INET6]); - db_vnet_ptr(vnet_iter->mod_data[VNET_MOD_IPSEC]); - db_vnet_ptr(vnet_iter->mod_data[VNET_MOD_NETGRAPH]); db_printf("\n"); } } #endif -#endif /* VIMAGE */ diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index cd0f3e909d5b..b389ace5bd49 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -49,6 +49,8 @@ __FBSDID("$FreeBSD$"); #include <machine/elf.h> +#include <net/vnet.h> + #include <security/mac/mac_framework.h> #include <vm/vm.h> @@ -111,6 +113,11 @@ typedef struct elf_file { Elf_Addr pcpu_start; /* Pre-relocation pcpu set start. */ Elf_Addr pcpu_stop; /* Pre-relocation pcpu set stop. */ Elf_Addr pcpu_base; /* Relocated pcpu set address. */ +#ifdef VIMAGE + Elf_Addr vnet_start; /* Pre-relocation vnet set start. */ + Elf_Addr vnet_stop; /* Pre-relocation vnet set stop. */ + Elf_Addr vnet_base; /* Relocated vnet set address. */ +#endif #ifdef GDB struct link_map gdb; /* hooks for gdb */ #endif @@ -506,6 +513,36 @@ parse_dpcpu(elf_file_t ef) return (0); } +#ifdef VIMAGE +static int +parse_vnet(elf_file_t ef) +{ + int count; + int error; + + ef->vnet_start = 0; + ef->vnet_stop = 0; + error = link_elf_lookup_set(&ef->lf, "vnet", (void ***)&ef->vnet_start, + (void ***)&ef->vnet_stop, &count); + /* Error just means there is no vnet data set to relocate. */ + if (error) + return (0); + count *= sizeof(void *); + /* + * Allocate space in the primary vnet area. Copy in our initialization + * from the data section and then initialize all per-vnet storage from + * that. + */ + ef->vnet_base = (Elf_Addr)(uintptr_t)vnet_data_alloc(count); + if (ef->vnet_base == (Elf_Addr)NULL) + return (ENOSPC); + memcpy((void *)ef->vnet_base, (void *)ef->vnet_start, count); + vnet_data_copy((void *)ef->vnet_base, count); + + return (0); +} +#endif + static int link_elf_link_preload(linker_class_t cls, const char* filename, linker_file_t *result) @@ -553,6 +590,10 @@ link_elf_link_preload(linker_class_t cls, error = parse_dynamic(ef); if (error == 0) error = parse_dpcpu(ef); +#ifdef VIMAGE + if (error == 0) + error = parse_vnet(ef); +#endif if (error) { linker_file_unload(lf, LINKER_UNLOAD_FORCE); return error; @@ -838,6 +879,11 @@ link_elf_load_file(linker_class_t cls, const char* filename, error = parse_dpcpu(ef); if (error) goto out; +#ifdef VIMAGE + error = parse_vnet(ef); + if (error) + goto out; +#endif link_elf_reloc_local(lf); VOP_UNLOCK(nd.ni_vp, 0); @@ -942,6 +988,10 @@ elf_relocaddr(linker_file_t lf, Elf_Addr x) ef = (elf_file_t)lf; if (x >= ef->pcpu_start && x < ef->pcpu_stop) return ((x - ef->pcpu_start) + ef->pcpu_base); +#ifdef VIMAGE + if (x >= ef->vnet_start && x < ef->vnet_stop) + return ((x - ef->vnet_start) + ef->vnet_base); +#endif return (x); } @@ -954,6 +1004,11 @@ link_elf_unload_file(linker_file_t file) if (ef->pcpu_base) { dpcpu_free((void *)ef->pcpu_base, ef->pcpu_stop - ef->pcpu_start); } +#ifdef VIMAGE + if (ef->vnet_base) { + vnet_data_free((void *)ef->vnet_base, ef->vnet_stop - ef->vnet_start); + } +#endif #ifdef GDB if (ef->gdb.l_ld) { GDB_STATE(RT_DELETE); diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index 9d4d70c83f2d..afcdd63a21bd 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$"); #include <machine/elf.h> +#include <net/vnet.h> + #include <security/mac/mac_framework.h> #include <vm/vm.h> @@ -346,6 +348,21 @@ link_elf_link_preload(linker_class_t cls, const char *filename, ef->progtab[pb].size); dpcpu_copy(dpcpu, shdr[i].sh_size); ef->progtab[pb].addr = dpcpu; +#ifdef VIMAGE + } else if (ef->progtab[pb].name != NULL && + !strcmp(ef->progtab[pb].name, "set_vnet")) { + void *vnet_data; + + vnet_data = vnet_data_alloc(shdr[i].sh_size); + if (vnet_data == NULL) { + error = ENOSPC; + goto out; + } + memcpy(vnet_data, ef->progtab[pb].addr, + ef->progtab[pb].size); + vnet_data_copy(vnet_data, shdr[i].sh_size); + ef->progtab[pb].addr = vnet_data; +#endif } /* Update all symbol values with the offset. */ @@ -737,6 +754,12 @@ link_elf_load_file(linker_class_t cls, const char *filename, !strcmp(ef->progtab[pb].name, "set_pcpu")) ef->progtab[pb].addr = dpcpu_alloc(shdr[i].sh_size); +#ifdef VIMAGE + else if (ef->progtab[pb].name != NULL && + !strcmp(ef->progtab[pb].name, "set_vnet")) + ef->progtab[pb].addr = + vnet_data_alloc(shdr[i].sh_size); +#endif else ef->progtab[pb].addr = (void *)(uintptr_t)mapbase; @@ -758,10 +781,21 @@ link_elf_load_file(linker_class_t cls, const char *filename, error = EINVAL; goto out; } - /* Initialize the per-cpu area. */ - if (ef->progtab[pb].addr != (void *)mapbase) + /* Initialize the per-cpu or vnet area. */ + if (ef->progtab[pb].addr != (void *)mapbase && + !strcmp(ef->progtab[pb].name, "set_pcpu")) dpcpu_copy(ef->progtab[pb].addr, shdr[i].sh_size); +#ifdef VIMAGE + else if (ef->progtab[pb].addr != + (void *)mapbase && + !strcmp(ef->progtab[pb].name, "set_vnet")) + vnet_data_copy(ef->progtab[pb].addr, + shdr[i].sh_size); +#endif + else + panic("link_elf_load_file: unexpected " + "progbits type"); } else bzero(ef->progtab[pb].addr, shdr[i].sh_size); @@ -877,6 +911,11 @@ link_elf_unload_file(linker_file_t file) if (!strcmp(ef->progtab[i].name, "set_pcpu")) dpcpu_free(ef->progtab[i].addr, ef->progtab[i].size); +#ifdef VIMAGE + else if (!strcmp(ef->progtab[i].name, "set_vnet")) + vnet_data_free(ef->progtab[i].addr, + ef->progtab[i].size); +#endif } } if (ef->preloaded) { diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 9ee6047dd2ea..88322d564484 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -106,14 +106,12 @@ struct pr_usrreqs nousrreqs = { .pru_sopoll = pru_sopoll_notsupp, }; -#ifndef VIMAGE_GLOBALS +#ifdef VIMAGE vnet_modinfo_t vnet_domain_modinfo = { .vmi_id = VNET_MOD_DOMAIN, .vmi_name = "domain", .vmi_iattach = net_init_domain, -#ifdef VIMAGE .vmi_idetach = net_detach_domain, -#endif }; #endif @@ -249,7 +247,7 @@ net_add_domain(void *data) "domainfinalize()\n", dp->dom_name); #endif mtx_unlock(&dom_mtx); -#ifndef VIMAGE_GLOBALS +#ifdef VIMAGE vnet_mod_register_multi(&vnet_domain_modinfo, dp, dp->dom_name); #else net_init_domain(dp); |
