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/lock.h> 34 #include <sys/malloc.h> 35 #include <sys/mutex.h> 36 #include <sys/refcount.h> 37 #include <sys/hwt.h> 38 39 #include <dev/hwt/hwt_context.h> 40 #include <dev/hwt/hwt_contexthash.h> 41 #include <dev/hwt/hwt_config.h> 42 43 #define HWT_DEBUG 44 #undef HWT_DEBUG 45 46 #ifdef HWT_DEBUG 47 #define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__) 48 #else 49 #define dprintf(fmt, ...) 50 #endif 51 52 #define HWT_CONTEXTHASH_SIZE 1024 53 54 static MALLOC_DEFINE(M_HWT_CONTEXTHASH, "hwt_chash", "Hardware Trace"); 55 56 /* 57 * Hash function. Discard the lower 2 bits of the pointer since 58 * these are always zero for our uses. The hash multiplier is 59 * round((2^LONG_BIT) * ((sqrt(5)-1)/2)). 60 */ 61 62 #define _HWT_HM 11400714819323198486u /* hash multiplier */ 63 #define HWT_HASH_PTR(P, M) ((((unsigned long) (P) >> 2) * _HWT_HM) & (M)) 64 65 static struct mtx hwt_contexthash_mtx; 66 static u_long hwt_contexthashmask; 67 static LIST_HEAD(hwt_contexthash, hwt_context) *hwt_contexthash; 68 69 /* 70 * To use by hwt_switch_in/out() and hwt_record() only. 71 * This function returns with refcnt acquired. 72 */ 73 struct hwt_context * 74 hwt_contexthash_lookup(struct proc *p) 75 { 76 struct hwt_contexthash *hch; 77 struct hwt_context *ctx; 78 int hindex; 79 80 hindex = HWT_HASH_PTR(p, hwt_contexthashmask); 81 hch = &hwt_contexthash[hindex]; 82 83 HWT_CTXHASH_LOCK(); 84 LIST_FOREACH(ctx, hch, next_hch) { 85 if (ctx->proc == p) { 86 refcount_acquire(&ctx->refcnt); 87 HWT_CTXHASH_UNLOCK(); 88 return (ctx); 89 } 90 } 91 HWT_CTXHASH_UNLOCK(); 92 93 return (NULL); 94 } 95 96 void 97 hwt_contexthash_insert(struct hwt_context *ctx) 98 { 99 struct hwt_contexthash *hch; 100 int hindex; 101 102 hindex = HWT_HASH_PTR(ctx->proc, hwt_contexthashmask); 103 hch = &hwt_contexthash[hindex]; 104 105 HWT_CTXHASH_LOCK(); 106 LIST_INSERT_HEAD(hch, ctx, next_hch); 107 HWT_CTXHASH_UNLOCK(); 108 } 109 110 void 111 hwt_contexthash_remove(struct hwt_context *ctx) 112 { 113 114 HWT_CTXHASH_LOCK(); 115 LIST_REMOVE(ctx, next_hch); 116 HWT_CTXHASH_UNLOCK(); 117 } 118 119 void 120 hwt_contexthash_load(void) 121 { 122 123 hwt_contexthash = hashinit(HWT_CONTEXTHASH_SIZE, M_HWT_CONTEXTHASH, 124 &hwt_contexthashmask); 125 mtx_init(&hwt_contexthash_mtx, "hwt ctx hash", "hwt ctx", MTX_SPIN); 126 } 127 128 void 129 hwt_contexthash_unload(void) 130 { 131 132 mtx_destroy(&hwt_contexthash_mtx); 133 hashdestroy(hwt_contexthash, M_HWT_CONTEXTHASH, hwt_contexthashmask); 134 } 135