1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2023-2025 Ruslan Bukin <br@bsdpad.com> 5 * 6 * This work was supported by Innovate UK project 105694, "Digital Security 7 * by Design (DSbD) Technology Platform Prototype". 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/param.h> 32 #include <sys/kernel.h> 33 #include <sys/malloc.h> 34 #include <sys/mman.h> 35 #include <sys/mutex.h> 36 #include <sys/rwlock.h> 37 #include <sys/hwt.h> 38 39 #include <dev/hwt/hwt_owner.h> 40 #include <dev/hwt/hwt_ownerhash.h> 41 42 #define HWT_DEBUG 43 #undef HWT_DEBUG 44 45 #ifdef HWT_DEBUG 46 #define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__) 47 #else 48 #define dprintf(fmt, ...) 49 #endif 50 51 #define HWT_OWNERHASH_SIZE 1024 52 53 static MALLOC_DEFINE(M_HWT_OWNERHASH, "hwt_ohash", "Hardware Trace"); 54 55 /* 56 * Hash function. Discard the lower 2 bits of the pointer since 57 * these are always zero for our uses. The hash multiplier is 58 * round((2^LONG_BIT) * ((sqrt(5)-1)/2)). 59 */ 60 61 #define _HWT_HM 11400714819323198486u /* hash multiplier */ 62 #define HWT_HASH_PTR(P, M) ((((unsigned long) (P) >> 2) * _HWT_HM) & (M)) 63 64 static struct mtx hwt_ownerhash_mtx; 65 static u_long hwt_ownerhashmask; 66 static LIST_HEAD(hwt_ownerhash, hwt_owner) *hwt_ownerhash; 67 68 struct hwt_owner * 69 hwt_ownerhash_lookup(struct proc *p) 70 { 71 struct hwt_ownerhash *hoh; 72 struct hwt_owner *ho; 73 int hindex; 74 75 hindex = HWT_HASH_PTR(p, hwt_ownerhashmask); 76 hoh = &hwt_ownerhash[hindex]; 77 78 HWT_OWNERHASH_LOCK(); 79 LIST_FOREACH(ho, hoh, next) { 80 if (ho->p == p) { 81 HWT_OWNERHASH_UNLOCK(); 82 return (ho); 83 } 84 } 85 HWT_OWNERHASH_UNLOCK(); 86 87 return (NULL); 88 } 89 90 void 91 hwt_ownerhash_insert(struct hwt_owner *ho) 92 { 93 struct hwt_ownerhash *hoh; 94 int hindex; 95 96 hindex = HWT_HASH_PTR(ho->p, hwt_ownerhashmask); 97 hoh = &hwt_ownerhash[hindex]; 98 99 HWT_OWNERHASH_LOCK(); 100 LIST_INSERT_HEAD(hoh, ho, next); 101 HWT_OWNERHASH_UNLOCK(); 102 } 103 104 void 105 hwt_ownerhash_remove(struct hwt_owner *ho) 106 { 107 108 /* Destroy hwt owner. */ 109 HWT_OWNERHASH_LOCK(); 110 LIST_REMOVE(ho, next); 111 HWT_OWNERHASH_UNLOCK(); 112 } 113 114 void 115 hwt_ownerhash_load(void) 116 { 117 118 hwt_ownerhash = hashinit(HWT_OWNERHASH_SIZE, M_HWT_OWNERHASH, 119 &hwt_ownerhashmask); 120 mtx_init(&hwt_ownerhash_mtx, "hwt-owner-hash", "hwt-owner", MTX_DEF); 121 } 122 123 void 124 hwt_ownerhash_unload(void) 125 { 126 struct hwt_ownerhash *hoh; 127 struct hwt_owner *ho, *tmp; 128 129 HWT_OWNERHASH_LOCK(); 130 for (hoh = hwt_ownerhash; 131 hoh <= &hwt_ownerhash[hwt_ownerhashmask]; 132 hoh++) { 133 LIST_FOREACH_SAFE(ho, hoh, next, tmp) { 134 /* TODO: module is in use ? */ 135 } 136 } 137 HWT_OWNERHASH_UNLOCK(); 138 139 mtx_destroy(&hwt_ownerhash_mtx); 140 hashdestroy(hwt_ownerhash, M_HWT_OWNERHASH, hwt_ownerhashmask); 141 } 142