003 File Manager
Current Path:
/usr/src/sys/kern
usr
/
src
/
sys
/
kern
/
📁
..
📄
Make.tags.inc
(2.13 KB)
📄
Makefile
(302 B)
📄
bus_if.m
(26.31 KB)
📄
capabilities.conf
(13.67 KB)
📄
clock_if.m
(1.7 KB)
📄
cpufreq_if.m
(2.27 KB)
📄
device_if.m
(10.41 KB)
📄
firmw.S
(2.15 KB)
📄
genassym.sh
(1.11 KB)
📄
genoffset.c
(1.68 KB)
📄
genoffset.sh
(3.58 KB)
📄
imgact_aout.c
(9.45 KB)
📄
imgact_binmisc.c
(18.64 KB)
📄
imgact_elf.c
(76.32 KB)
📄
imgact_elf32.c
(1.47 KB)
📄
imgact_elf64.c
(1.47 KB)
📄
imgact_shell.c
(8.41 KB)
📄
init_main.c
(24.31 KB)
📄
init_sysent.c
(95.3 KB)
📄
kern_acct.c
(19.03 KB)
📄
kern_alq.c
(24.97 KB)
📄
kern_clock.c
(21.12 KB)
📄
kern_clocksource.c
(23.34 KB)
📄
kern_condvar.c
(11.28 KB)
📄
kern_conf.c
(36.14 KB)
📄
kern_cons.c
(15.75 KB)
📄
kern_context.c
(3.59 KB)
📄
kern_cpu.c
(30.77 KB)
📄
kern_cpuset.c
(59.78 KB)
📄
kern_ctf.c
(8.73 KB)
📄
kern_descrip.c
(112.87 KB)
📄
kern_dtrace.c
(2.94 KB)
📄
kern_dump.c
(8.51 KB)
📄
kern_environment.c
(22.75 KB)
📄
kern_et.c
(7.1 KB)
📄
kern_event.c
(62.49 KB)
📄
kern_exec.c
(46.67 KB)
📄
kern_exit.c
(34.61 KB)
📄
kern_fail.c
(29.32 KB)
📄
kern_ffclock.c
(12.66 KB)
📄
kern_fork.c
(28.29 KB)
📄
kern_hhook.c
(13.58 KB)
📄
kern_idle.c
(2.74 KB)
📄
kern_intr.c
(40.44 KB)
📄
kern_jail.c
(112.67 KB)
📄
kern_kcov.c
(15.32 KB)
📄
kern_khelp.c
(9.45 KB)
📄
kern_kthread.c
(11.8 KB)
📄
kern_ktr.c
(11.93 KB)
📄
kern_ktrace.c
(31.41 KB)
📄
kern_linker.c
(54.3 KB)
📄
kern_lock.c
(46.99 KB)
📄
kern_lockf.c
(64.46 KB)
📄
kern_lockstat.c
(3.8 KB)
📄
kern_loginclass.c
(6.69 KB)
📄
kern_malloc.c
(37.09 KB)
📄
kern_mbuf.c
(43.16 KB)
📄
kern_mib.c
(24.26 KB)
📄
kern_module.c
(11.05 KB)
📄
kern_mtxpool.c
(5.82 KB)
📄
kern_mutex.c
(33.62 KB)
📄
kern_ntptime.c
(32.49 KB)
📄
kern_osd.c
(12.37 KB)
📄
kern_physio.c
(5.74 KB)
📄
kern_pmc.c
(8.89 KB)
📄
kern_poll.c
(15.86 KB)
📄
kern_priv.c
(9.14 KB)
📄
kern_proc.c
(80.01 KB)
📄
kern_procctl.c
(19.48 KB)
📄
kern_prot.c
(57.94 KB)
📄
kern_racct.c
(34.01 KB)
📄
kern_rangelock.c
(8.67 KB)
📄
kern_rctl.c
(53.87 KB)
📄
kern_resource.c
(36.66 KB)
📄
kern_rmlock.c
(28.27 KB)
📄
kern_rwlock.c
(40.72 KB)
📄
kern_sdt.c
(2.05 KB)
📄
kern_sema.c
(4.85 KB)
📄
kern_sendfile.c
(33.97 KB)
📄
kern_sharedpage.c
(10.37 KB)
📄
kern_shutdown.c
(43.34 KB)
📄
kern_sig.c
(101.89 KB)
📄
kern_switch.c
(13.85 KB)
📄
kern_sx.c
(40.27 KB)
📄
kern_synch.c
(18.17 KB)
📄
kern_syscalls.c
(6.74 KB)
📄
kern_sysctl.c
(67.24 KB)
📄
kern_tc.c
(55.73 KB)
📄
kern_thr.c
(14.14 KB)
📄
kern_thread.c
(41.75 KB)
📄
kern_time.c
(40.89 KB)
📄
kern_timeout.c
(43.08 KB)
📄
kern_tslog.c
(3.44 KB)
📄
kern_ubsan.c
(50.74 KB)
📄
kern_umtx.c
(107.14 KB)
📄
kern_uuid.c
(11.68 KB)
📄
kern_xxx.c
(10.44 KB)
📄
ksched.c
(6.56 KB)
📄
link_elf.c
(47.99 KB)
📄
link_elf_obj.c
(44.41 KB)
📄
linker_if.m
(3.96 KB)
📄
makesyscalls.sh
(23.57 KB)
📄
md4c.c
(7.89 KB)
📄
md5c.c
(9.56 KB)
📄
msi_if.m
(2.48 KB)
📄
p1003_1b.c
(8.84 KB)
📄
pic_if.m
(3.9 KB)
📄
posix4_mib.c
(5.59 KB)
📄
sched_4bsd.c
(45.03 KB)
📄
sched_ule.c
(82.65 KB)
📄
serdev_if.m
(3.49 KB)
📄
stack_protector.c
(613 B)
📄
subr_acl_nfs4.c
(37.42 KB)
📄
subr_acl_posix1e.c
(17.71 KB)
📄
subr_atomic64.c
(3.97 KB)
📄
subr_autoconf.c
(7.7 KB)
📄
subr_blist.c
(31.88 KB)
📄
subr_boot.c
(5.8 KB)
📄
subr_bufring.c
(2.21 KB)
📄
subr_bus.c
(145.4 KB)
📄
subr_bus_dma.c
(19.67 KB)
📄
subr_busdma_bufalloc.c
(5.24 KB)
📄
subr_capability.c
(11.93 KB)
📄
subr_clock.c
(10.61 KB)
📄
subr_compressor.c
(13.11 KB)
📄
subr_counter.c
(4.44 KB)
📄
subr_coverage.c
(6.17 KB)
📄
subr_csan.c
(25.39 KB)
📄
subr_devmap.c
(9.8 KB)
📄
subr_devstat.c
(16.21 KB)
📄
subr_disk.c
(8.54 KB)
📄
subr_dummy_vdso_tc.c
(1.7 KB)
📄
subr_early.c
(2.26 KB)
📄
subr_epoch.c
(25.02 KB)
📄
subr_eventhandler.c
(9.17 KB)
📄
subr_fattime.c
(9.98 KB)
📄
subr_filter.c
(12.2 KB)
📄
subr_firmware.c
(13.88 KB)
📄
subr_gtaskqueue.c
(20.19 KB)
📄
subr_hash.c
(4.8 KB)
📄
subr_hints.c
(12.87 KB)
📄
subr_intr.c
(40.61 KB)
📄
subr_kdb.c
(16.13 KB)
📄
subr_kobj.c
(7.1 KB)
📄
subr_lock.c
(18.81 KB)
📄
subr_log.c
(7.64 KB)
📄
subr_mchain.c
(11.06 KB)
📄
subr_module.c
(12.98 KB)
📄
subr_msgbuf.c
(10.6 KB)
📄
subr_param.c
(10.93 KB)
📄
subr_pcpu.c
(10.18 KB)
📄
subr_pctrie.c
(20.99 KB)
📄
subr_physmem.c
(11.52 KB)
📄
subr_pidctrl.c
(5.43 KB)
📄
subr_power.c
(3.13 KB)
📄
subr_prf.c
(27.42 KB)
📄
subr_prng.c
(3.36 KB)
📄
subr_prof.c
(15.43 KB)
📄
subr_rangeset.c
(8.5 KB)
📄
subr_rman.c
(27.61 KB)
📄
subr_rtc.c
(11.42 KB)
📄
subr_sbuf.c
(20.53 KB)
📄
subr_scanf.c
(15.59 KB)
📄
subr_sfbuf.c
(6.17 KB)
📄
subr_sglist.c
(22.83 KB)
📄
subr_sleepqueue.c
(39.43 KB)
📄
subr_smp.c
(31.62 KB)
📄
subr_smr.c
(20.17 KB)
📄
subr_stack.c
(6.47 KB)
📄
subr_stats.c
(103.01 KB)
📄
subr_syscall.c
(7.98 KB)
📄
subr_taskqueue.c
(21.1 KB)
📄
subr_terminal.c
(15.52 KB)
📄
subr_trap.c
(10.87 KB)
📄
subr_turnstile.c
(35.58 KB)
📄
subr_uio.c
(11.38 KB)
📄
subr_unit.c
(22.97 KB)
📄
subr_vmem.c
(43.25 KB)
📄
subr_witness.c
(84.59 KB)
📄
sys_capability.c
(15.06 KB)
📄
sys_eventfd.c
(8.42 KB)
📄
sys_generic.c
(44.22 KB)
📄
sys_getrandom.c
(4.21 KB)
📄
sys_pipe.c
(45.14 KB)
📄
sys_procdesc.c
(14.57 KB)
📄
sys_process.c
(30.73 KB)
📄
sys_socket.c
(20.11 KB)
📄
syscalls.c
(22.73 KB)
📄
syscalls.master
(60.26 KB)
📄
systrace_args.c
(178.49 KB)
📄
sysv_ipc.c
(6.53 KB)
📄
sysv_msg.c
(48.65 KB)
📄
sysv_sem.c
(49.85 KB)
📄
sysv_shm.c
(43.93 KB)
📄
tty.c
(55.14 KB)
📄
tty_compat.c
(11.46 KB)
📄
tty_info.c
(9.93 KB)
📄
tty_inq.c
(12.22 KB)
📄
tty_outq.c
(8.74 KB)
📄
tty_pts.c
(19.74 KB)
📄
tty_tty.c
(2.83 KB)
📄
tty_ttydisc.c
(28.6 KB)
📄
uipc_accf.c
(8.07 KB)
📄
uipc_debug.c
(12.42 KB)
📄
uipc_domain.c
(13.13 KB)
📄
uipc_ktls.c
(55.7 KB)
📄
uipc_mbuf.c
(52.45 KB)
📄
uipc_mbuf2.c
(12.64 KB)
📄
uipc_mbufhash.c
(4.9 KB)
📄
uipc_mqueue.c
(64.64 KB)
📄
uipc_sem.c
(25.18 KB)
📄
uipc_shm.c
(50.47 KB)
📄
uipc_sockbuf.c
(42.9 KB)
📄
uipc_socket.c
(110.61 KB)
📄
uipc_syscalls.c
(35.94 KB)
📄
uipc_usrreq.c
(75.11 KB)
📄
vfs_acl.c
(14.5 KB)
📄
vfs_aio.c
(76.32 KB)
📄
vfs_bio.c
(145.39 KB)
📄
vfs_cache.c
(143.09 KB)
📄
vfs_cluster.c
(28.36 KB)
📄
vfs_default.c
(33.16 KB)
📄
vfs_export.c
(14.55 KB)
📄
vfs_extattr.c
(17.91 KB)
📄
vfs_hash.c
(6 KB)
📄
vfs_init.c
(15.86 KB)
📄
vfs_lookup.c
(45.48 KB)
📄
vfs_mount.c
(62.58 KB)
📄
vfs_mountroot.c
(26.23 KB)
📄
vfs_subr.c
(167.52 KB)
📄
vfs_syscalls.c
(106.86 KB)
📄
vfs_vnops.c
(86.28 KB)
📄
vnode_if.src
(13.66 KB)
Editing: kern_hhook.c
/*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2010,2013 Lawrence Stewart <lstewart@freebsd.org> * Copyright (c) 2010 The FreeBSD Foundation * All rights reserved. * * This software was developed by Lawrence Stewart while studying at the Centre * for Advanced Internet Architectures, Swinburne University of Technology, * made possible in part by grants from the FreeBSD Foundation and Cisco * University Research Program Fund at Community Foundation Silicon Valley. * * Portions of this software were developed at the Centre for Advanced * Internet Architectures, Swinburne University of Technology, Melbourne, * Australia by Lawrence Stewart under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/kernel.h> #include <sys/hhook.h> #include <sys/khelp.h> #include <sys/malloc.h> #include <sys/module.h> #include <sys/module_khelp.h> #include <sys/osd.h> #include <sys/queue.h> #include <sys/refcount.h> #include <sys/systm.h> #include <net/vnet.h> struct hhook { hhook_func_t hhk_func; struct helper *hhk_helper; void *hhk_udata; STAILQ_ENTRY(hhook) hhk_next; }; static MALLOC_DEFINE(M_HHOOK, "hhook", "Helper hooks are linked off hhook_head lists"); LIST_HEAD(hhookheadhead, hhook_head); struct hhookheadhead hhook_head_list; VNET_DEFINE(struct hhookheadhead, hhook_vhead_list); #define V_hhook_vhead_list VNET(hhook_vhead_list) static struct mtx hhook_head_list_lock; MTX_SYSINIT(hhookheadlistlock, &hhook_head_list_lock, "hhook_head list lock", MTX_DEF); /* Protected by hhook_head_list_lock. */ static uint32_t n_hhookheads; /* Private function prototypes. */ static void hhook_head_destroy(struct hhook_head *hhh); void khelp_new_hhook_registered(struct hhook_head *hhh, uint32_t flags); #define HHHLIST_LOCK() mtx_lock(&hhook_head_list_lock) #define HHHLIST_UNLOCK() mtx_unlock(&hhook_head_list_lock) #define HHHLIST_LOCK_ASSERT() mtx_assert(&hhook_head_list_lock, MA_OWNED) #define HHH_LOCK_INIT(hhh) rm_init(&(hhh)->hhh_lock, "hhook_head rm lock") #define HHH_LOCK_DESTROY(hhh) rm_destroy(&(hhh)->hhh_lock) #define HHH_WLOCK(hhh) rm_wlock(&(hhh)->hhh_lock) #define HHH_WUNLOCK(hhh) rm_wunlock(&(hhh)->hhh_lock) #define HHH_RLOCK(hhh, rmpt) rm_rlock(&(hhh)->hhh_lock, (rmpt)) #define HHH_RUNLOCK(hhh, rmpt) rm_runlock(&(hhh)->hhh_lock, (rmpt)) /* * Run all helper hook functions for a given hook point. */ void hhook_run_hooks(struct hhook_head *hhh, void *ctx_data, struct osd *hosd) { struct hhook *hhk; void *hdata; struct rm_priotracker rmpt; KASSERT(hhh->hhh_refcount > 0, ("hhook_head %p refcount is 0", hhh)); HHH_RLOCK(hhh, &rmpt); STAILQ_FOREACH(hhk, &hhh->hhh_hooks, hhk_next) { if (hhk->hhk_helper != NULL && hhk->hhk_helper->h_flags & HELPER_NEEDS_OSD) { hdata = osd_get(OSD_KHELP, hosd, hhk->hhk_helper->h_id); if (hdata == NULL) continue; } else hdata = NULL; /* * XXXLAS: We currently ignore the int returned by the hook, * but will likely want to handle it in future to allow hhook to * be used like pfil and effect changes at the hhook calling * site e.g. we could define a new hook type of HHOOK_TYPE_PFIL * and standardise what particular return values mean and set * the context data to pass exactly the same information as pfil * hooks currently receive, thus replicating pfil with hhook. */ hhk->hhk_func(hhh->hhh_type, hhh->hhh_id, hhk->hhk_udata, ctx_data, hdata, hosd); } HHH_RUNLOCK(hhh, &rmpt); } /* * Register a new helper hook function with a helper hook point. */ int hhook_add_hook(struct hhook_head *hhh, struct hookinfo *hki, uint32_t flags) { struct hhook *hhk, *tmp; int error; error = 0; if (hhh == NULL) return (ENOENT); hhk = malloc(sizeof(struct hhook), M_HHOOK, M_ZERO | ((flags & HHOOK_WAITOK) ? M_WAITOK : M_NOWAIT)); if (hhk == NULL) return (ENOMEM); hhk->hhk_helper = hki->hook_helper; hhk->hhk_func = hki->hook_func; hhk->hhk_udata = hki->hook_udata; HHH_WLOCK(hhh); STAILQ_FOREACH(tmp, &hhh->hhh_hooks, hhk_next) { if (tmp->hhk_func == hki->hook_func && tmp->hhk_udata == hki->hook_udata) { /* The helper hook function is already registered. */ error = EEXIST; break; } } if (!error) { STAILQ_INSERT_TAIL(&hhh->hhh_hooks, hhk, hhk_next); hhh->hhh_nhooks++; } else free(hhk, M_HHOOK); HHH_WUNLOCK(hhh); return (error); } /* * Register a helper hook function with a helper hook point (including all * virtual instances of the hook point if it is virtualised). * * The logic is unfortunately far more complex than for * hhook_remove_hook_lookup() because hhook_add_hook() can call malloc() with * M_WAITOK and thus we cannot call hhook_add_hook() with the * hhook_head_list_lock held. * * The logic assembles an array of hhook_head structs that correspond to the * helper hook point being hooked and bumps the refcount on each (all done with * the hhook_head_list_lock held). The hhook_head_list_lock is then dropped, and * hhook_add_hook() is called and the refcount dropped for each hhook_head * struct in the array. */ int hhook_add_hook_lookup(struct hookinfo *hki, uint32_t flags) { struct hhook_head **heads_to_hook, *hhh; int error, i, n_heads_to_hook; tryagain: error = i = 0; /* * Accessing n_hhookheads without hhook_head_list_lock held opens up a * race with hhook_head_register() which we are unlikely to lose, but * nonetheless have to cope with - hence the complex goto logic. */ n_heads_to_hook = n_hhookheads; heads_to_hook = malloc(n_heads_to_hook * sizeof(struct hhook_head *), M_HHOOK, flags & HHOOK_WAITOK ? M_WAITOK : M_NOWAIT); if (heads_to_hook == NULL) return (ENOMEM); HHHLIST_LOCK(); LIST_FOREACH(hhh, &hhook_head_list, hhh_next) { if (hhh->hhh_type == hki->hook_type && hhh->hhh_id == hki->hook_id) { if (i < n_heads_to_hook) { heads_to_hook[i] = hhh; refcount_acquire(&heads_to_hook[i]->hhh_refcount); i++; } else { /* * We raced with hhook_head_register() which * inserted a hhook_head that we need to hook * but did not malloc space for. Abort this run * and try again. */ for (i--; i >= 0; i--) refcount_release(&heads_to_hook[i]->hhh_refcount); free(heads_to_hook, M_HHOOK); HHHLIST_UNLOCK(); goto tryagain; } } } HHHLIST_UNLOCK(); for (i--; i >= 0; i--) { if (!error) error = hhook_add_hook(heads_to_hook[i], hki, flags); refcount_release(&heads_to_hook[i]->hhh_refcount); } free(heads_to_hook, M_HHOOK); return (error); } /* * Remove a helper hook function from a helper hook point. */ int hhook_remove_hook(struct hhook_head *hhh, struct hookinfo *hki) { struct hhook *tmp; if (hhh == NULL) return (ENOENT); HHH_WLOCK(hhh); STAILQ_FOREACH(tmp, &hhh->hhh_hooks, hhk_next) { if (tmp->hhk_func == hki->hook_func && tmp->hhk_udata == hki->hook_udata) { STAILQ_REMOVE(&hhh->hhh_hooks, tmp, hhook, hhk_next); free(tmp, M_HHOOK); hhh->hhh_nhooks--; break; } } HHH_WUNLOCK(hhh); return (0); } /* * Remove a helper hook function from a helper hook point (including all * virtual instances of the hook point if it is virtualised). */ int hhook_remove_hook_lookup(struct hookinfo *hki) { struct hhook_head *hhh; HHHLIST_LOCK(); LIST_FOREACH(hhh, &hhook_head_list, hhh_next) { if (hhh->hhh_type == hki->hook_type && hhh->hhh_id == hki->hook_id) hhook_remove_hook(hhh, hki); } HHHLIST_UNLOCK(); return (0); } /* * Register a new helper hook point. */ int hhook_head_register(int32_t hhook_type, int32_t hhook_id, struct hhook_head **hhh, uint32_t flags) { struct hhook_head *tmphhh; tmphhh = hhook_head_get(hhook_type, hhook_id); if (tmphhh != NULL) { /* Hook point previously registered. */ hhook_head_release(tmphhh); return (EEXIST); } tmphhh = malloc(sizeof(struct hhook_head), M_HHOOK, M_ZERO | ((flags & HHOOK_WAITOK) ? M_WAITOK : M_NOWAIT)); if (tmphhh == NULL) return (ENOMEM); tmphhh->hhh_type = hhook_type; tmphhh->hhh_id = hhook_id; tmphhh->hhh_nhooks = 0; STAILQ_INIT(&tmphhh->hhh_hooks); HHH_LOCK_INIT(tmphhh); refcount_init(&tmphhh->hhh_refcount, 1); HHHLIST_LOCK(); if (flags & HHOOK_HEADISINVNET) { tmphhh->hhh_flags |= HHH_ISINVNET; #ifdef VIMAGE KASSERT(curvnet != NULL, ("curvnet is NULL")); tmphhh->hhh_vid = (uintptr_t)curvnet; LIST_INSERT_HEAD(&V_hhook_vhead_list, tmphhh, hhh_vnext); #endif } LIST_INSERT_HEAD(&hhook_head_list, tmphhh, hhh_next); n_hhookheads++; HHHLIST_UNLOCK(); khelp_new_hhook_registered(tmphhh, flags); if (hhh != NULL) *hhh = tmphhh; else refcount_release(&tmphhh->hhh_refcount); return (0); } static void hhook_head_destroy(struct hhook_head *hhh) { struct hhook *tmp, *tmp2; HHHLIST_LOCK_ASSERT(); KASSERT(n_hhookheads > 0, ("n_hhookheads should be > 0")); LIST_REMOVE(hhh, hhh_next); #ifdef VIMAGE if (hhook_head_is_virtualised(hhh) == HHOOK_HEADISINVNET) LIST_REMOVE(hhh, hhh_vnext); #endif HHH_WLOCK(hhh); STAILQ_FOREACH_SAFE(tmp, &hhh->hhh_hooks, hhk_next, tmp2) free(tmp, M_HHOOK); HHH_WUNLOCK(hhh); HHH_LOCK_DESTROY(hhh); free(hhh, M_HHOOK); n_hhookheads--; } /* * Remove a helper hook point. */ int hhook_head_deregister(struct hhook_head *hhh) { int error; error = 0; HHHLIST_LOCK(); if (hhh == NULL) error = ENOENT; else if (hhh->hhh_refcount > 1) error = EBUSY; else hhook_head_destroy(hhh); HHHLIST_UNLOCK(); return (error); } /* * Remove a helper hook point via a hhook_head lookup. */ int hhook_head_deregister_lookup(int32_t hhook_type, int32_t hhook_id) { struct hhook_head *hhh; int error; hhh = hhook_head_get(hhook_type, hhook_id); error = hhook_head_deregister(hhh); if (error == EBUSY) hhook_head_release(hhh); return (error); } /* * Lookup and return the hhook_head struct associated with the specified type * and id, or NULL if not found. If found, the hhook_head's refcount is bumped. */ struct hhook_head * hhook_head_get(int32_t hhook_type, int32_t hhook_id) { struct hhook_head *hhh; HHHLIST_LOCK(); LIST_FOREACH(hhh, &hhook_head_list, hhh_next) { if (hhh->hhh_type == hhook_type && hhh->hhh_id == hhook_id) { #ifdef VIMAGE if (hhook_head_is_virtualised(hhh) == HHOOK_HEADISINVNET) { KASSERT(curvnet != NULL, ("curvnet is NULL")); if (hhh->hhh_vid != (uintptr_t)curvnet) continue; } #endif refcount_acquire(&hhh->hhh_refcount); break; } } HHHLIST_UNLOCK(); return (hhh); } void hhook_head_release(struct hhook_head *hhh) { refcount_release(&hhh->hhh_refcount); } /* * Check the hhook_head private flags and return the appropriate public * representation of the flag to the caller. The function is implemented in a * way that allows us to cope with other subsystems becoming virtualised in the * future. */ uint32_t hhook_head_is_virtualised(struct hhook_head *hhh) { uint32_t ret; ret = 0; if (hhh != NULL) { if (hhh->hhh_flags & HHH_ISINVNET) ret = HHOOK_HEADISINVNET; } return (ret); } uint32_t hhook_head_is_virtualised_lookup(int32_t hook_type, int32_t hook_id) { struct hhook_head *hhh; uint32_t ret; hhh = hhook_head_get(hook_type, hook_id); if (hhh == NULL) return (0); ret = hhook_head_is_virtualised(hhh); hhook_head_release(hhh); return (ret); } /* * Vnet created and being initialised. */ static void hhook_vnet_init(const void *unused __unused) { LIST_INIT(&V_hhook_vhead_list); } /* * Vnet being torn down and destroyed. */ static void hhook_vnet_uninit(const void *unused __unused) { struct hhook_head *hhh, *tmphhh; /* * If subsystems which export helper hook points use the hhook KPI * correctly, the loop below should have no work to do because the * subsystem should have already called hhook_head_deregister(). */ HHHLIST_LOCK(); LIST_FOREACH_SAFE(hhh, &V_hhook_vhead_list, hhh_vnext, tmphhh) { printf("%s: hhook_head type=%d, id=%d cleanup required\n", __func__, hhh->hhh_type, hhh->hhh_id); hhook_head_destroy(hhh); } HHHLIST_UNLOCK(); } /* * When a vnet is created and being initialised, init the V_hhook_vhead_list. */ VNET_SYSINIT(hhook_vnet_init, SI_SUB_INIT_IF, SI_ORDER_FIRST, hhook_vnet_init, NULL); /* * The hhook KPI provides a mechanism for subsystems which export helper hook * points to clean up on vnet tear down, but in case the KPI is misused, * provide a function to clean up and free memory for a vnet being destroyed. */ VNET_SYSUNINIT(hhook_vnet_uninit, SI_SUB_INIT_IF, SI_ORDER_FIRST, hhook_vnet_uninit, NULL);
Upload File
Create Folder