1a422084aSMark Johnston /* $NetBSD: subr_msan.c,v 1.14 2020/09/09 16:29:59 maxv Exp $ */ 2a422084aSMark Johnston 3a422084aSMark Johnston /* 4a422084aSMark Johnston * Copyright (c) 2019-2020 Maxime Villard, m00nbsd.net 5a422084aSMark Johnston * All rights reserved. 6a422084aSMark Johnston * Copyright (c) 2021 The FreeBSD Foundation 7a422084aSMark Johnston * 8a422084aSMark Johnston * Portions of this software were developed by Mark Johnston under sponsorship 9a422084aSMark Johnston * from the FreeBSD Foundation. 10a422084aSMark Johnston * 11a422084aSMark Johnston * This code is part of the KMSAN subsystem of the NetBSD kernel. 12a422084aSMark Johnston * 13a422084aSMark Johnston * Redistribution and use in source and binary forms, with or without 14a422084aSMark Johnston * modification, are permitted provided that the following conditions 15a422084aSMark Johnston * are met: 16a422084aSMark Johnston * 1. Redistributions of source code must retain the above copyright 17a422084aSMark Johnston * notice, this list of conditions and the following disclaimer. 18a422084aSMark Johnston * 2. Redistributions in binary form must reproduce the above copyright 19a422084aSMark Johnston * notice, this list of conditions and the following disclaimer in the 20a422084aSMark Johnston * documentation and/or other materials provided with the distribution. 21a422084aSMark Johnston * 22a422084aSMark Johnston * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23a422084aSMark Johnston * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24a422084aSMark Johnston * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25a422084aSMark Johnston * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26a422084aSMark Johnston * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27a422084aSMark Johnston * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28a422084aSMark Johnston * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29a422084aSMark Johnston * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30a422084aSMark Johnston * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31a422084aSMark Johnston * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32a422084aSMark Johnston * SUCH DAMAGE. 33a422084aSMark Johnston */ 34a422084aSMark Johnston 35a422084aSMark Johnston #define SAN_RUNTIME 36a422084aSMark Johnston 37a422084aSMark Johnston #include <sys/cdefs.h> 38a422084aSMark Johnston __FBSDID("$FreeBSD$"); 39a422084aSMark Johnston #if 0 40a422084aSMark Johnston __KERNEL_RCSID(0, "$NetBSD: subr_msan.c,v 1.14 2020/09/09 16:29:59 maxv Exp $"); 41a422084aSMark Johnston #endif 42a422084aSMark Johnston 43a422084aSMark Johnston #include <sys/param.h> 44a422084aSMark Johnston #include <sys/systm.h> 45a422084aSMark Johnston #include <sys/bio.h> 46a422084aSMark Johnston #include <sys/buf.h> 47a422084aSMark Johnston #include <sys/conf.h> 48a422084aSMark Johnston #include <sys/kdb.h> 49a422084aSMark Johnston #include <sys/kernel.h> 50a422084aSMark Johnston #include <sys/linker.h> 51a422084aSMark Johnston #include <sys/malloc.h> 52a422084aSMark Johnston #include <sys/mbuf.h> 53a422084aSMark Johnston #include <sys/memdesc.h> 54a422084aSMark Johnston #include <sys/msan.h> 55a422084aSMark Johnston #include <sys/proc.h> 56a422084aSMark Johnston #include <sys/stack.h> 57a422084aSMark Johnston #include <sys/sysctl.h> 58a422084aSMark Johnston #include <sys/uio.h> 59a422084aSMark Johnston 60a422084aSMark Johnston #include <cam/cam.h> 61a422084aSMark Johnston #include <cam/cam_ccb.h> 62a422084aSMark Johnston 63a422084aSMark Johnston #include <vm/vm.h> 64a422084aSMark Johnston #include <vm/pmap.h> 65a422084aSMark Johnston 66a422084aSMark Johnston #include <machine/msan.h> 67a422084aSMark Johnston #include <machine/stdarg.h> 68a422084aSMark Johnston 69a422084aSMark Johnston void kmsan_init_arg(size_t); 70a422084aSMark Johnston void kmsan_init_ret(size_t); 71a422084aSMark Johnston 72a422084aSMark Johnston /* -------------------------------------------------------------------------- */ 73a422084aSMark Johnston 74a422084aSMark Johnston /* 75a422084aSMark Johnston * Part of the compiler ABI. 76a422084aSMark Johnston */ 77a422084aSMark Johnston 78a422084aSMark Johnston typedef struct { 79a422084aSMark Johnston uint8_t *shad; 80a422084aSMark Johnston msan_orig_t *orig; 81a422084aSMark Johnston } msan_meta_t; 82a422084aSMark Johnston 83a422084aSMark Johnston #define MSAN_PARAM_SIZE 800 84a422084aSMark Johnston #define MSAN_RETVAL_SIZE 800 85a422084aSMark Johnston typedef struct { 86a422084aSMark Johnston uint8_t param_shadow[MSAN_PARAM_SIZE]; 87a422084aSMark Johnston uint8_t retval_shadow[MSAN_RETVAL_SIZE]; 88a422084aSMark Johnston uint8_t va_arg_shadow[MSAN_PARAM_SIZE]; 89a422084aSMark Johnston uint8_t va_arg_origin[MSAN_PARAM_SIZE]; 90a422084aSMark Johnston uint64_t va_arg_overflow_size; 91a422084aSMark Johnston msan_orig_t param_origin[MSAN_PARAM_SIZE / sizeof(msan_orig_t)]; 92a422084aSMark Johnston msan_orig_t retval_origin; 93a422084aSMark Johnston } msan_tls_t; 94a422084aSMark Johnston 95a422084aSMark Johnston /* -------------------------------------------------------------------------- */ 96a422084aSMark Johnston 97a422084aSMark Johnston #define MSAN_NCONTEXT 4 98a422084aSMark Johnston #define MSAN_ORIG_MASK (~0x3) 99a422084aSMark Johnston 100a422084aSMark Johnston typedef struct kmsan_td { 101a422084aSMark Johnston size_t ctx; 102a422084aSMark Johnston msan_tls_t tls[MSAN_NCONTEXT]; 103a422084aSMark Johnston } msan_td_t; 104a422084aSMark Johnston 105a422084aSMark Johnston static msan_tls_t dummy_tls; 106a422084aSMark Johnston 107a422084aSMark Johnston /* 108a422084aSMark Johnston * Use separate dummy regions for loads and stores: stores may mark the region 109a422084aSMark Johnston * as uninitialized, and that can trigger false positives. 110a422084aSMark Johnston */ 111a422084aSMark Johnston static uint8_t msan_dummy_shad[PAGE_SIZE] __aligned(PAGE_SIZE); 112a422084aSMark Johnston static uint8_t msan_dummy_write_shad[PAGE_SIZE] __aligned(PAGE_SIZE); 113a422084aSMark Johnston static uint8_t msan_dummy_orig[PAGE_SIZE] __aligned(PAGE_SIZE); 114a422084aSMark Johnston static msan_td_t msan_thread0; 115a422084aSMark Johnston static bool kmsan_enabled __read_mostly; 116a422084aSMark Johnston 117a422084aSMark Johnston static bool kmsan_reporting = false; 118a422084aSMark Johnston 119a422084aSMark Johnston /* 120a422084aSMark Johnston * Avoid clobbering any thread-local state before we panic. 121a422084aSMark Johnston */ 122a422084aSMark Johnston #define kmsan_panic(f, ...) do { \ 123a422084aSMark Johnston kmsan_enabled = false; \ 124a422084aSMark Johnston panic(f, __VA_ARGS__); \ 125a422084aSMark Johnston } while (0) 126a422084aSMark Johnston 127a422084aSMark Johnston #define REPORT(f, ...) do { \ 128a422084aSMark Johnston if (panic_on_violation) { \ 129a422084aSMark Johnston kmsan_panic(f, __VA_ARGS__); \ 130a422084aSMark Johnston } else { \ 131a422084aSMark Johnston struct stack st; \ 132a422084aSMark Johnston \ 133a422084aSMark Johnston stack_save(&st); \ 134a422084aSMark Johnston printf(f "\n", __VA_ARGS__); \ 135a422084aSMark Johnston stack_print_ddb(&st); \ 136a422084aSMark Johnston } \ 137a422084aSMark Johnston } while (0) 138a422084aSMark Johnston 139a422084aSMark Johnston FEATURE(kmsan, "Kernel memory sanitizer"); 140a422084aSMark Johnston 141a422084aSMark Johnston static SYSCTL_NODE(_debug, OID_AUTO, kmsan, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 142a422084aSMark Johnston "KMSAN options"); 143a422084aSMark Johnston 144a422084aSMark Johnston static bool panic_on_violation = 1; 145a422084aSMark Johnston SYSCTL_BOOL(_debug_kmsan, OID_AUTO, panic_on_violation, CTLFLAG_RWTUN, 146a422084aSMark Johnston &panic_on_violation, 0, 147a422084aSMark Johnston "Panic if an invalid access is detected"); 148a422084aSMark Johnston 149a422084aSMark Johnston static MALLOC_DEFINE(M_KMSAN, "kmsan", "Kernel memory sanitizer"); 150a422084aSMark Johnston 151a422084aSMark Johnston /* -------------------------------------------------------------------------- */ 152a422084aSMark Johnston 153a422084aSMark Johnston static inline const char * 154a422084aSMark Johnston kmsan_orig_name(int type) 155a422084aSMark Johnston { 156a422084aSMark Johnston switch (type) { 157a422084aSMark Johnston case KMSAN_TYPE_STACK: 158a422084aSMark Johnston return ("stack"); 159a422084aSMark Johnston case KMSAN_TYPE_KMEM: 160a422084aSMark Johnston return ("kmem"); 161a422084aSMark Johnston case KMSAN_TYPE_MALLOC: 162a422084aSMark Johnston return ("malloc"); 163a422084aSMark Johnston case KMSAN_TYPE_UMA: 164a422084aSMark Johnston return ("UMA"); 165a422084aSMark Johnston default: 166a422084aSMark Johnston return ("unknown"); 167a422084aSMark Johnston } 168a422084aSMark Johnston } 169a422084aSMark Johnston 170a422084aSMark Johnston static void 171a422084aSMark Johnston kmsan_report_hook(const void *addr, size_t size, size_t off, const char *hook) 172a422084aSMark Johnston { 173a422084aSMark Johnston msan_orig_t *orig; 174a422084aSMark Johnston const char *typename; 175a422084aSMark Johnston char *var, *fn; 176a422084aSMark Johnston uintptr_t ptr; 177a422084aSMark Johnston long foff; 178a422084aSMark Johnston char buf[128]; 179a422084aSMark Johnston int type; 180a422084aSMark Johnston 181*35eb9b10SMitchell Horne if (__predict_false(KERNEL_PANICKED() || kdb_active || kmsan_reporting)) 182a422084aSMark Johnston return; 183a422084aSMark Johnston 184a422084aSMark Johnston kmsan_reporting = true; 185a422084aSMark Johnston __compiler_membar(); 186a422084aSMark Johnston 187a422084aSMark Johnston orig = (msan_orig_t *)kmsan_md_addr_to_orig((vm_offset_t)addr); 188a422084aSMark Johnston orig = (msan_orig_t *)((uintptr_t)orig & MSAN_ORIG_MASK); 189a422084aSMark Johnston 190a422084aSMark Johnston if (*orig == 0) { 191a422084aSMark Johnston REPORT("MSan: Uninitialized memory in %s, offset %zu", 192a422084aSMark Johnston hook, off); 193a422084aSMark Johnston goto out; 194a422084aSMark Johnston } 195a422084aSMark Johnston 196a422084aSMark Johnston kmsan_md_orig_decode(*orig, &type, &ptr); 197a422084aSMark Johnston typename = kmsan_orig_name(type); 198a422084aSMark Johnston 199a422084aSMark Johnston if (linker_ddb_search_symbol_name((caddr_t)ptr, buf, 200a422084aSMark Johnston sizeof(buf), &foff) == 0) { 201a422084aSMark Johnston REPORT("MSan: Uninitialized %s memory in %s, " 202a422084aSMark Johnston "offset %zu/%zu, addr %p, from %s+%#lx", 203a422084aSMark Johnston typename, hook, off, size, addr, buf, foff); 204a422084aSMark Johnston } else if (__builtin_memcmp((void *)ptr, "----", 4) == 0) { 205a422084aSMark Johnston /* 206a422084aSMark Johnston * The format of the string is: "----var@function". Parse it to 207a422084aSMark Johnston * display a nice warning. 208a422084aSMark Johnston */ 209a422084aSMark Johnston var = (char *)ptr + 4; 210a422084aSMark Johnston strlcpy(buf, var, sizeof(buf)); 211a422084aSMark Johnston var = buf; 212a422084aSMark Johnston fn = strchr(buf, '@'); 213a422084aSMark Johnston *fn++ = '\0'; 214a422084aSMark Johnston REPORT("MSan: Uninitialized %s memory in %s, offset %zu, " 215a422084aSMark Johnston "variable '%s' from %s", typename, hook, off, var, fn); 216a422084aSMark Johnston } else { 217a422084aSMark Johnston REPORT("MSan: Uninitialized %s memory in %s, " 218a422084aSMark Johnston "offset %zu/%zu, addr %p, PC %p", 219a422084aSMark Johnston typename, hook, off, size, addr, (void *)ptr); 220a422084aSMark Johnston } 221a422084aSMark Johnston 222a422084aSMark Johnston out: 223a422084aSMark Johnston __compiler_membar(); 224a422084aSMark Johnston kmsan_reporting = false; 225a422084aSMark Johnston } 226a422084aSMark Johnston 227a422084aSMark Johnston static void 228a422084aSMark Johnston kmsan_report_inline(msan_orig_t orig, unsigned long pc) 229a422084aSMark Johnston { 230a422084aSMark Johnston const char *typename; 231a422084aSMark Johnston char *var, *fn; 232a422084aSMark Johnston uintptr_t ptr; 233a422084aSMark Johnston char buf[128]; 234a422084aSMark Johnston long foff; 235a422084aSMark Johnston int type; 236a422084aSMark Johnston 237*35eb9b10SMitchell Horne if (__predict_false(KERNEL_PANICKED() || kdb_active || kmsan_reporting)) 238a422084aSMark Johnston return; 239a422084aSMark Johnston 240a422084aSMark Johnston kmsan_reporting = true; 241a422084aSMark Johnston __compiler_membar(); 242a422084aSMark Johnston 243a422084aSMark Johnston if (orig == 0) { 244a422084aSMark Johnston REPORT("MSan: uninitialized variable in %p", (void *)pc); 245a422084aSMark Johnston goto out; 246a422084aSMark Johnston } 247a422084aSMark Johnston 248a422084aSMark Johnston kmsan_md_orig_decode(orig, &type, &ptr); 249a422084aSMark Johnston typename = kmsan_orig_name(type); 250a422084aSMark Johnston 251a422084aSMark Johnston if (linker_ddb_search_symbol_name((caddr_t)ptr, buf, 252a422084aSMark Johnston sizeof(buf), &foff) == 0) { 253a422084aSMark Johnston REPORT("MSan: Uninitialized %s memory from %s+%#lx", 254a422084aSMark Johnston typename, buf, foff); 255a422084aSMark Johnston } else if (__builtin_memcmp((void *)ptr, "----", 4) == 0) { 256a422084aSMark Johnston /* 257a422084aSMark Johnston * The format of the string is: "----var@function". Parse it to 258a422084aSMark Johnston * display a nice warning. 259a422084aSMark Johnston */ 260a422084aSMark Johnston var = (char *)ptr + 4; 261a422084aSMark Johnston strlcpy(buf, var, sizeof(buf)); 262a422084aSMark Johnston var = buf; 263a422084aSMark Johnston fn = strchr(buf, '@'); 264a422084aSMark Johnston *fn++ = '\0'; 265a422084aSMark Johnston REPORT("MSan: Uninitialized variable '%s' from %s", var, fn); 266a422084aSMark Johnston } else { 267a422084aSMark Johnston REPORT("MSan: Uninitialized %s memory, origin %x", 268a422084aSMark Johnston typename, orig); 269a422084aSMark Johnston } 270a422084aSMark Johnston 271a422084aSMark Johnston out: 272a422084aSMark Johnston __compiler_membar(); 273a422084aSMark Johnston kmsan_reporting = false; 274a422084aSMark Johnston } 275a422084aSMark Johnston 276a422084aSMark Johnston /* -------------------------------------------------------------------------- */ 277a422084aSMark Johnston 278a422084aSMark Johnston static inline msan_meta_t 279a422084aSMark Johnston kmsan_meta_get(const void *addr, size_t size, const bool write) 280a422084aSMark Johnston { 281a422084aSMark Johnston msan_meta_t ret; 282a422084aSMark Johnston 283a422084aSMark Johnston if (__predict_false(!kmsan_enabled)) { 284a422084aSMark Johnston ret.shad = write ? msan_dummy_write_shad : msan_dummy_shad; 285a422084aSMark Johnston ret.orig = (msan_orig_t *)msan_dummy_orig; 286a422084aSMark Johnston } else if (__predict_false(kmsan_md_unsupported((vm_offset_t)addr))) { 287a422084aSMark Johnston ret.shad = write ? msan_dummy_write_shad : msan_dummy_shad; 288a422084aSMark Johnston ret.orig = (msan_orig_t *)msan_dummy_orig; 289a422084aSMark Johnston } else { 290a422084aSMark Johnston ret.shad = (void *)kmsan_md_addr_to_shad((vm_offset_t)addr); 291a422084aSMark Johnston ret.orig = 292a422084aSMark Johnston (msan_orig_t *)kmsan_md_addr_to_orig((vm_offset_t)addr); 293a422084aSMark Johnston ret.orig = (msan_orig_t *)((uintptr_t)ret.orig & 294a422084aSMark Johnston MSAN_ORIG_MASK); 295a422084aSMark Johnston } 296a422084aSMark Johnston 297a422084aSMark Johnston return (ret); 298a422084aSMark Johnston } 299a422084aSMark Johnston 300a422084aSMark Johnston static inline void 301a422084aSMark Johnston kmsan_origin_fill(const void *addr, msan_orig_t o, size_t size) 302a422084aSMark Johnston { 303a422084aSMark Johnston msan_orig_t *orig; 304a422084aSMark Johnston size_t i; 305a422084aSMark Johnston 306a422084aSMark Johnston if (__predict_false(!kmsan_enabled)) 307a422084aSMark Johnston return; 308a422084aSMark Johnston if (__predict_false(kmsan_md_unsupported((vm_offset_t)addr))) 309a422084aSMark Johnston return; 310a422084aSMark Johnston 311a422084aSMark Johnston orig = (msan_orig_t *)kmsan_md_addr_to_orig((vm_offset_t)addr); 312a422084aSMark Johnston size += ((uintptr_t)orig & (sizeof(*orig) - 1)); 313a422084aSMark Johnston orig = (msan_orig_t *)((uintptr_t)orig & MSAN_ORIG_MASK); 314a422084aSMark Johnston 315a422084aSMark Johnston for (i = 0; i < size; i += 4) { 316a422084aSMark Johnston orig[i / 4] = o; 317a422084aSMark Johnston } 318a422084aSMark Johnston } 319a422084aSMark Johnston 320a422084aSMark Johnston static inline void 321a422084aSMark Johnston kmsan_shadow_fill(uintptr_t addr, uint8_t c, size_t size) 322a422084aSMark Johnston { 323a422084aSMark Johnston uint8_t *shad; 324a422084aSMark Johnston 325a422084aSMark Johnston if (__predict_false(!kmsan_enabled)) 326a422084aSMark Johnston return; 327a422084aSMark Johnston if (__predict_false(kmsan_md_unsupported(addr))) 328a422084aSMark Johnston return; 329a422084aSMark Johnston 330a422084aSMark Johnston shad = (uint8_t *)kmsan_md_addr_to_shad(addr); 331a422084aSMark Johnston __builtin_memset(shad, c, size); 332a422084aSMark Johnston } 333a422084aSMark Johnston 334a422084aSMark Johnston static inline void 335a422084aSMark Johnston kmsan_meta_copy(void *dst, const void *src, size_t size) 336a422084aSMark Johnston { 337a422084aSMark Johnston uint8_t *orig_src, *orig_dst; 338a422084aSMark Johnston uint8_t *shad_src, *shad_dst; 339a422084aSMark Johnston msan_orig_t *_src, *_dst; 340a422084aSMark Johnston size_t i; 341a422084aSMark Johnston 342a422084aSMark Johnston if (__predict_false(!kmsan_enabled)) 343a422084aSMark Johnston return; 344a422084aSMark Johnston if (__predict_false(kmsan_md_unsupported((vm_offset_t)dst))) 345a422084aSMark Johnston return; 346a422084aSMark Johnston if (__predict_false(kmsan_md_unsupported((vm_offset_t)src))) { 347a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)dst, KMSAN_STATE_INITED, size); 348a422084aSMark Johnston return; 349a422084aSMark Johnston } 350a422084aSMark Johnston 351a422084aSMark Johnston shad_src = (uint8_t *)kmsan_md_addr_to_shad((vm_offset_t)src); 352a422084aSMark Johnston shad_dst = (uint8_t *)kmsan_md_addr_to_shad((vm_offset_t)dst); 353a422084aSMark Johnston __builtin_memmove(shad_dst, shad_src, size); 354a422084aSMark Johnston 355a422084aSMark Johnston orig_src = (uint8_t *)kmsan_md_addr_to_orig((vm_offset_t)src); 356a422084aSMark Johnston orig_dst = (uint8_t *)kmsan_md_addr_to_orig((vm_offset_t)dst); 357a422084aSMark Johnston for (i = 0; i < size; i++) { 358a422084aSMark Johnston _src = (msan_orig_t *)((uintptr_t)orig_src & MSAN_ORIG_MASK); 359a422084aSMark Johnston _dst = (msan_orig_t *)((uintptr_t)orig_dst & MSAN_ORIG_MASK); 360a422084aSMark Johnston *_dst = *_src; 361a422084aSMark Johnston orig_src++; 362a422084aSMark Johnston orig_dst++; 363a422084aSMark Johnston } 364a422084aSMark Johnston } 365a422084aSMark Johnston 366a422084aSMark Johnston static inline void 367a422084aSMark Johnston kmsan_shadow_check(uintptr_t addr, size_t size, const char *hook) 368a422084aSMark Johnston { 369a422084aSMark Johnston uint8_t *shad; 370a422084aSMark Johnston size_t i; 371a422084aSMark Johnston 372a422084aSMark Johnston if (__predict_false(!kmsan_enabled)) 373a422084aSMark Johnston return; 374a422084aSMark Johnston if (__predict_false(kmsan_md_unsupported(addr))) 375a422084aSMark Johnston return; 376a422084aSMark Johnston 377a422084aSMark Johnston shad = (uint8_t *)kmsan_md_addr_to_shad(addr); 378a422084aSMark Johnston for (i = 0; i < size; i++) { 379a422084aSMark Johnston if (__predict_true(shad[i] == 0)) 380a422084aSMark Johnston continue; 381a422084aSMark Johnston kmsan_report_hook((const char *)addr + i, size, i, hook); 382a422084aSMark Johnston break; 383a422084aSMark Johnston } 384a422084aSMark Johnston } 385a422084aSMark Johnston 386a422084aSMark Johnston void 387a422084aSMark Johnston kmsan_init_arg(size_t n) 388a422084aSMark Johnston { 389a422084aSMark Johnston msan_td_t *mtd; 390a422084aSMark Johnston uint8_t *arg; 391a422084aSMark Johnston 392a422084aSMark Johnston if (__predict_false(!kmsan_enabled)) 393a422084aSMark Johnston return; 394a422084aSMark Johnston if (__predict_false(curthread == NULL)) 395a422084aSMark Johnston return; 396a422084aSMark Johnston mtd = curthread->td_kmsan; 397a422084aSMark Johnston arg = mtd->tls[mtd->ctx].param_shadow; 398a422084aSMark Johnston __builtin_memset(arg, 0, n); 399a422084aSMark Johnston } 400a422084aSMark Johnston 401a422084aSMark Johnston void 402a422084aSMark Johnston kmsan_init_ret(size_t n) 403a422084aSMark Johnston { 404a422084aSMark Johnston msan_td_t *mtd; 405a422084aSMark Johnston uint8_t *arg; 406a422084aSMark Johnston 407a422084aSMark Johnston if (__predict_false(!kmsan_enabled)) 408a422084aSMark Johnston return; 409a422084aSMark Johnston if (__predict_false(curthread == NULL)) 410a422084aSMark Johnston return; 411a422084aSMark Johnston mtd = curthread->td_kmsan; 412a422084aSMark Johnston arg = mtd->tls[mtd->ctx].retval_shadow; 413a422084aSMark Johnston __builtin_memset(arg, 0, n); 414a422084aSMark Johnston } 415a422084aSMark Johnston 416a422084aSMark Johnston static void 417a422084aSMark Johnston kmsan_check_arg(size_t size, const char *hook) 418a422084aSMark Johnston { 419a422084aSMark Johnston msan_td_t *mtd; 420a422084aSMark Johnston uint8_t *arg; 421a422084aSMark Johnston size_t i; 422a422084aSMark Johnston 423a422084aSMark Johnston if (__predict_false(!kmsan_enabled)) 424a422084aSMark Johnston return; 425a422084aSMark Johnston if (__predict_false(curthread == NULL)) 426a422084aSMark Johnston return; 427a422084aSMark Johnston mtd = curthread->td_kmsan; 428a422084aSMark Johnston arg = mtd->tls[mtd->ctx].param_shadow; 429a422084aSMark Johnston 430a422084aSMark Johnston for (i = 0; i < size; i++) { 431a422084aSMark Johnston if (__predict_true(arg[i] == 0)) 432a422084aSMark Johnston continue; 433a422084aSMark Johnston kmsan_report_hook((const char *)arg + i, size, i, hook); 434a422084aSMark Johnston break; 435a422084aSMark Johnston } 436a422084aSMark Johnston } 437a422084aSMark Johnston 438a422084aSMark Johnston void 439a422084aSMark Johnston kmsan_thread_alloc(struct thread *td) 440a422084aSMark Johnston { 441a422084aSMark Johnston msan_td_t *mtd; 442a422084aSMark Johnston 443a422084aSMark Johnston if (!kmsan_enabled) 444a422084aSMark Johnston return; 445a422084aSMark Johnston 446a422084aSMark Johnston mtd = td->td_kmsan; 447a422084aSMark Johnston if (mtd == NULL) { 448a422084aSMark Johnston /* We might be recycling a thread. */ 449a422084aSMark Johnston kmsan_init_arg(sizeof(size_t) + sizeof(struct malloc_type *) + 450a422084aSMark Johnston sizeof(int)); 451a422084aSMark Johnston mtd = malloc(sizeof(*mtd), M_KMSAN, M_WAITOK); 452a422084aSMark Johnston } 453a422084aSMark Johnston kmsan_memset(mtd, 0, sizeof(*mtd)); 454a422084aSMark Johnston mtd->ctx = 0; 455a422084aSMark Johnston 456a422084aSMark Johnston if (td->td_kstack != 0) 457a422084aSMark Johnston kmsan_mark((void *)td->td_kstack, ptoa(td->td_kstack_pages), 458a422084aSMark Johnston KMSAN_STATE_UNINIT); 459a422084aSMark Johnston 460a422084aSMark Johnston td->td_kmsan = mtd; 461a422084aSMark Johnston } 462a422084aSMark Johnston 463a422084aSMark Johnston void 464a422084aSMark Johnston kmsan_thread_free(struct thread *td) 465a422084aSMark Johnston { 466a422084aSMark Johnston msan_td_t *mtd; 467a422084aSMark Johnston 468a422084aSMark Johnston if (!kmsan_enabled) 469a422084aSMark Johnston return; 470a422084aSMark Johnston if (__predict_false(td == curthread)) 471a422084aSMark Johnston kmsan_panic("%s: freeing KMSAN TLS for curthread", __func__); 472a422084aSMark Johnston 473a422084aSMark Johnston mtd = td->td_kmsan; 474a422084aSMark Johnston kmsan_init_arg(sizeof(void *) + sizeof(struct malloc_type *)); 475a422084aSMark Johnston free(mtd, M_KMSAN); 476a422084aSMark Johnston td->td_kmsan = NULL; 477a422084aSMark Johnston } 478a422084aSMark Johnston 479a422084aSMark Johnston void kmsan_intr_enter(void); 480a422084aSMark Johnston void kmsan_intr_leave(void); 481a422084aSMark Johnston 482a422084aSMark Johnston void 483a422084aSMark Johnston kmsan_intr_enter(void) 484a422084aSMark Johnston { 485a422084aSMark Johnston msan_td_t *mtd; 486a422084aSMark Johnston 487a422084aSMark Johnston if (__predict_false(!kmsan_enabled)) 488a422084aSMark Johnston return; 489a422084aSMark Johnston 490a422084aSMark Johnston mtd = curthread->td_kmsan; 491a422084aSMark Johnston mtd->ctx++; 492a422084aSMark Johnston if (__predict_false(mtd->ctx >= MSAN_NCONTEXT)) 493a422084aSMark Johnston kmsan_panic("%s: mtd->ctx = %zu", __func__, mtd->ctx); 494a422084aSMark Johnston } 495a422084aSMark Johnston 496a422084aSMark Johnston void 497a422084aSMark Johnston kmsan_intr_leave(void) 498a422084aSMark Johnston { 499a422084aSMark Johnston msan_td_t *mtd; 500a422084aSMark Johnston 501a422084aSMark Johnston if (__predict_false(!kmsan_enabled)) 502a422084aSMark Johnston return; 503a422084aSMark Johnston 504a422084aSMark Johnston mtd = curthread->td_kmsan; 505a422084aSMark Johnston if (__predict_false(mtd->ctx == 0)) 506a422084aSMark Johnston kmsan_panic("%s: mtd->ctx = %zu", __func__, mtd->ctx); 507a422084aSMark Johnston mtd->ctx--; 508a422084aSMark Johnston } 509a422084aSMark Johnston 510a422084aSMark Johnston /* -------------------------------------------------------------------------- */ 511a422084aSMark Johnston 512a422084aSMark Johnston void 513a422084aSMark Johnston kmsan_shadow_map(vm_offset_t addr, size_t size) 514a422084aSMark Johnston { 515a422084aSMark Johnston size_t npages, i; 516a422084aSMark Johnston vm_offset_t va; 517a422084aSMark Johnston 518a422084aSMark Johnston MPASS(addr % PAGE_SIZE == 0); 519a422084aSMark Johnston MPASS(size % PAGE_SIZE == 0); 520a422084aSMark Johnston 521a422084aSMark Johnston if (!kmsan_enabled) 522a422084aSMark Johnston return; 523a422084aSMark Johnston 524a422084aSMark Johnston npages = atop(size); 525a422084aSMark Johnston 526a422084aSMark Johnston va = kmsan_md_addr_to_shad(addr); 527a422084aSMark Johnston for (i = 0; i < npages; i++) { 528175d3380SMark Johnston pmap_san_enter(va + ptoa(i)); 529a422084aSMark Johnston } 530a422084aSMark Johnston 531a422084aSMark Johnston va = kmsan_md_addr_to_orig(addr); 532a422084aSMark Johnston for (i = 0; i < npages; i++) { 533175d3380SMark Johnston pmap_san_enter(va + ptoa(i)); 534a422084aSMark Johnston } 535a422084aSMark Johnston } 536a422084aSMark Johnston 537a422084aSMark Johnston void 538a422084aSMark Johnston kmsan_orig(const void *addr, size_t size, int type, uintptr_t pc) 539a422084aSMark Johnston { 540a422084aSMark Johnston msan_orig_t orig; 541a422084aSMark Johnston 542a422084aSMark Johnston orig = kmsan_md_orig_encode(type, pc); 543a422084aSMark Johnston kmsan_origin_fill(addr, orig, size); 544a422084aSMark Johnston } 545a422084aSMark Johnston 546a422084aSMark Johnston void 547a422084aSMark Johnston kmsan_mark(const void *addr, size_t size, uint8_t c) 548a422084aSMark Johnston { 549a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)addr, c, size); 550a422084aSMark Johnston } 551a422084aSMark Johnston 55210a8e93dSMark Johnston void 553a422084aSMark Johnston kmsan_mark_bio(const struct bio *bp, uint8_t c) 554a422084aSMark Johnston { 555a422084aSMark Johnston kmsan_mark(bp->bio_data, bp->bio_length, c); 556a422084aSMark Johnston } 557a422084aSMark Johnston 558a422084aSMark Johnston static void 559a422084aSMark Johnston kmsan_mark_ccb(const union ccb *ccb, uint8_t c) 560a422084aSMark Johnston { 561a422084aSMark Johnston if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_IN) 562a422084aSMark Johnston return; 563a422084aSMark Johnston if ((ccb->ccb_h.flags & CAM_DATA_MASK) != CAM_DATA_VADDR) 564a422084aSMark Johnston return; 565a422084aSMark Johnston 566a422084aSMark Johnston switch (ccb->ccb_h.func_code) { 567a422084aSMark Johnston case XPT_SCSI_IO: { 568a422084aSMark Johnston const struct ccb_scsiio *scsiio; 569a422084aSMark Johnston 570a422084aSMark Johnston scsiio = &ccb->ctio; 571a422084aSMark Johnston kmsan_mark(scsiio->data_ptr, scsiio->dxfer_len, c); 572a422084aSMark Johnston break; 573a422084aSMark Johnston } 574a422084aSMark Johnston case XPT_ATA_IO: { 575a422084aSMark Johnston const struct ccb_ataio *ataio; 576a422084aSMark Johnston 577a422084aSMark Johnston ataio = &ccb->ataio; 578a422084aSMark Johnston kmsan_mark(ataio->data_ptr, ataio->dxfer_len, c); 579a422084aSMark Johnston break; 580a422084aSMark Johnston } 581a422084aSMark Johnston case XPT_NVME_IO: { 582a422084aSMark Johnston const struct ccb_nvmeio *nvmeio; 583a422084aSMark Johnston 584a422084aSMark Johnston nvmeio = &ccb->nvmeio; 585a422084aSMark Johnston kmsan_mark(nvmeio->data_ptr, nvmeio->dxfer_len, c); 586a422084aSMark Johnston break; 587a422084aSMark Johnston } 588a422084aSMark Johnston default: 589a422084aSMark Johnston kmsan_panic("%s: unhandled CCB type %d", __func__, 590a422084aSMark Johnston ccb->ccb_h.func_code); 591a422084aSMark Johnston } 592a422084aSMark Johnston } 593a422084aSMark Johnston 59410a8e93dSMark Johnston void 595a422084aSMark Johnston kmsan_mark_mbuf(const struct mbuf *m, uint8_t c) 596a422084aSMark Johnston { 597a422084aSMark Johnston do { 598a422084aSMark Johnston if ((m->m_flags & M_EXTPG) == 0) 599a422084aSMark Johnston kmsan_mark(m->m_data, m->m_len, c); 600a422084aSMark Johnston m = m->m_next; 601a422084aSMark Johnston } while (m != NULL); 602a422084aSMark Johnston } 603a422084aSMark Johnston 604a422084aSMark Johnston void 605a422084aSMark Johnston kmsan_check(const void *p, size_t sz, const char *descr) 606a422084aSMark Johnston { 607a422084aSMark Johnston kmsan_shadow_check((uintptr_t)p, sz, descr); 608a422084aSMark Johnston } 609a422084aSMark Johnston 610a422084aSMark Johnston void 611a422084aSMark Johnston kmsan_check_bio(const struct bio *bp, const char *descr) 612a422084aSMark Johnston { 613a422084aSMark Johnston kmsan_shadow_check((uintptr_t)bp->bio_data, bp->bio_length, descr); 614a422084aSMark Johnston } 615a422084aSMark Johnston 616a422084aSMark Johnston void 617a422084aSMark Johnston kmsan_check_ccb(const union ccb *ccb, const char *descr) 618a422084aSMark Johnston { 619a422084aSMark Johnston if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_OUT) 620a422084aSMark Johnston return; 621a422084aSMark Johnston switch (ccb->ccb_h.func_code) { 622a422084aSMark Johnston case XPT_SCSI_IO: { 623a422084aSMark Johnston const struct ccb_scsiio *scsiio; 624a422084aSMark Johnston 625a422084aSMark Johnston scsiio = &ccb->ctio; 626a422084aSMark Johnston kmsan_check(scsiio->data_ptr, scsiio->dxfer_len, descr); 627a422084aSMark Johnston break; 628a422084aSMark Johnston } 629a422084aSMark Johnston case XPT_ATA_IO: { 630a422084aSMark Johnston const struct ccb_ataio *ataio; 631a422084aSMark Johnston 632a422084aSMark Johnston ataio = &ccb->ataio; 633a422084aSMark Johnston kmsan_check(ataio->data_ptr, ataio->dxfer_len, descr); 634a422084aSMark Johnston break; 635a422084aSMark Johnston } 636a422084aSMark Johnston case XPT_NVME_IO: { 637a422084aSMark Johnston const struct ccb_nvmeio *nvmeio; 638a422084aSMark Johnston 639a422084aSMark Johnston nvmeio = &ccb->nvmeio; 640a422084aSMark Johnston kmsan_check(nvmeio->data_ptr, nvmeio->dxfer_len, descr); 641a422084aSMark Johnston break; 642a422084aSMark Johnston } 643a422084aSMark Johnston default: 644a422084aSMark Johnston kmsan_panic("%s: unhandled CCB type %d", __func__, 645a422084aSMark Johnston ccb->ccb_h.func_code); 646a422084aSMark Johnston } 647a422084aSMark Johnston } 648a422084aSMark Johnston 649a422084aSMark Johnston void 650a422084aSMark Johnston kmsan_check_mbuf(const struct mbuf *m, const char *descr) 651a422084aSMark Johnston { 652a422084aSMark Johnston do { 653a422084aSMark Johnston kmsan_shadow_check((uintptr_t)mtod(m, void *), m->m_len, descr); 654a422084aSMark Johnston } while ((m = m->m_next) != NULL); 655a422084aSMark Johnston } 656a422084aSMark Johnston 657a422084aSMark Johnston void 658a422084aSMark Johnston kmsan_init(void) 659a422084aSMark Johnston { 660a422084aSMark Johnston int disabled; 661a422084aSMark Johnston 662a422084aSMark Johnston disabled = 0; 663a422084aSMark Johnston TUNABLE_INT_FETCH("debug.kmsan.disabled", &disabled); 664a422084aSMark Johnston if (disabled) 665a422084aSMark Johnston return; 666a422084aSMark Johnston 667a422084aSMark Johnston /* Initialize the TLS for curthread. */ 668a422084aSMark Johnston msan_thread0.ctx = 0; 669a422084aSMark Johnston thread0.td_kmsan = &msan_thread0; 670a422084aSMark Johnston 671a422084aSMark Johnston /* Now officially enabled. */ 672a422084aSMark Johnston kmsan_enabled = true; 673a422084aSMark Johnston } 674a422084aSMark Johnston 675a422084aSMark Johnston /* -------------------------------------------------------------------------- */ 676a422084aSMark Johnston 677a422084aSMark Johnston msan_meta_t __msan_metadata_ptr_for_load_n(void *, size_t); 678a422084aSMark Johnston msan_meta_t __msan_metadata_ptr_for_store_n(void *, size_t); 679a422084aSMark Johnston 680a422084aSMark Johnston msan_meta_t 681a422084aSMark Johnston __msan_metadata_ptr_for_load_n(void *addr, size_t size) 682a422084aSMark Johnston { 683a422084aSMark Johnston return (kmsan_meta_get(addr, size, false)); 684a422084aSMark Johnston } 685a422084aSMark Johnston 686a422084aSMark Johnston msan_meta_t 687a422084aSMark Johnston __msan_metadata_ptr_for_store_n(void *addr, size_t size) 688a422084aSMark Johnston { 689a422084aSMark Johnston return (kmsan_meta_get(addr, size, true)); 690a422084aSMark Johnston } 691a422084aSMark Johnston 692a422084aSMark Johnston #define MSAN_META_FUNC(size) \ 693a422084aSMark Johnston msan_meta_t __msan_metadata_ptr_for_load_##size(void *); \ 694a422084aSMark Johnston msan_meta_t __msan_metadata_ptr_for_load_##size(void *addr) \ 695a422084aSMark Johnston { \ 696a422084aSMark Johnston return (kmsan_meta_get(addr, size, false)); \ 697a422084aSMark Johnston } \ 698a422084aSMark Johnston msan_meta_t __msan_metadata_ptr_for_store_##size(void *); \ 699a422084aSMark Johnston msan_meta_t __msan_metadata_ptr_for_store_##size(void *addr) \ 700a422084aSMark Johnston { \ 701a422084aSMark Johnston return (kmsan_meta_get(addr, size, true)); \ 702a422084aSMark Johnston } 703a422084aSMark Johnston 704a422084aSMark Johnston MSAN_META_FUNC(1) 705a422084aSMark Johnston MSAN_META_FUNC(2) 706a422084aSMark Johnston MSAN_META_FUNC(4) 707a422084aSMark Johnston MSAN_META_FUNC(8) 708a422084aSMark Johnston 709a422084aSMark Johnston void __msan_instrument_asm_store(const void *, size_t); 710a422084aSMark Johnston msan_orig_t __msan_chain_origin(msan_orig_t); 711a422084aSMark Johnston void __msan_poison(const void *, size_t); 712a422084aSMark Johnston void __msan_unpoison(const void *, size_t); 713a422084aSMark Johnston void __msan_poison_alloca(const void *, uint64_t, const char *); 714a422084aSMark Johnston void __msan_unpoison_alloca(const void *, uint64_t); 715a422084aSMark Johnston void __msan_warning(msan_orig_t); 716a422084aSMark Johnston msan_tls_t *__msan_get_context_state(void); 717a422084aSMark Johnston 718a422084aSMark Johnston void 719a422084aSMark Johnston __msan_instrument_asm_store(const void *addr, size_t size) 720a422084aSMark Johnston { 721a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)addr, KMSAN_STATE_INITED, size); 722a422084aSMark Johnston } 723a422084aSMark Johnston 724a422084aSMark Johnston msan_orig_t 725a422084aSMark Johnston __msan_chain_origin(msan_orig_t origin) 726a422084aSMark Johnston { 727a422084aSMark Johnston return (origin); 728a422084aSMark Johnston } 729a422084aSMark Johnston 730a422084aSMark Johnston void 731a422084aSMark Johnston __msan_poison(const void *addr, size_t size) 732a422084aSMark Johnston { 733a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)addr, KMSAN_STATE_UNINIT, size); 734a422084aSMark Johnston } 735a422084aSMark Johnston 736a422084aSMark Johnston void 737a422084aSMark Johnston __msan_unpoison(const void *addr, size_t size) 738a422084aSMark Johnston { 739a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)addr, KMSAN_STATE_INITED, size); 740a422084aSMark Johnston } 741a422084aSMark Johnston 742a422084aSMark Johnston void 743a422084aSMark Johnston __msan_poison_alloca(const void *addr, uint64_t size, const char *descr) 744a422084aSMark Johnston { 745a422084aSMark Johnston msan_orig_t orig; 746a422084aSMark Johnston 747a422084aSMark Johnston orig = kmsan_md_orig_encode(KMSAN_TYPE_STACK, (uintptr_t)descr); 748a422084aSMark Johnston kmsan_origin_fill(addr, orig, size); 749a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)addr, KMSAN_STATE_UNINIT, size); 750a422084aSMark Johnston } 751a422084aSMark Johnston 752a422084aSMark Johnston void 753a422084aSMark Johnston __msan_unpoison_alloca(const void *addr, uint64_t size) 754a422084aSMark Johnston { 755a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)addr, KMSAN_STATE_INITED, size); 756a422084aSMark Johnston } 757a422084aSMark Johnston 758a422084aSMark Johnston void 759a422084aSMark Johnston __msan_warning(msan_orig_t origin) 760a422084aSMark Johnston { 761a422084aSMark Johnston if (__predict_false(!kmsan_enabled)) 762a422084aSMark Johnston return; 763a422084aSMark Johnston kmsan_report_inline(origin, KMSAN_RET_ADDR); 764a422084aSMark Johnston } 765a422084aSMark Johnston 766a422084aSMark Johnston msan_tls_t * 767a422084aSMark Johnston __msan_get_context_state(void) 768a422084aSMark Johnston { 769a422084aSMark Johnston msan_td_t *mtd; 770a422084aSMark Johnston 771a422084aSMark Johnston /* 772a422084aSMark Johnston * When APs are started, they execute some C code before curthread is 773a422084aSMark Johnston * set. We have to handle that here. 774a422084aSMark Johnston */ 775a422084aSMark Johnston if (__predict_false(!kmsan_enabled || curthread == NULL)) 776a422084aSMark Johnston return (&dummy_tls); 777a422084aSMark Johnston mtd = curthread->td_kmsan; 778a422084aSMark Johnston return (&mtd->tls[mtd->ctx]); 779a422084aSMark Johnston } 780a422084aSMark Johnston 781a422084aSMark Johnston /* -------------------------------------------------------------------------- */ 782a422084aSMark Johnston 783a422084aSMark Johnston /* 784a422084aSMark Johnston * Function hooks. Mostly ASM functions which need KMSAN wrappers to handle 785a422084aSMark Johnston * initialized areas properly. 786a422084aSMark Johnston */ 787a422084aSMark Johnston 788a422084aSMark Johnston void * 789a422084aSMark Johnston kmsan_memcpy(void *dst, const void *src, size_t len) 790a422084aSMark Johnston { 791a422084aSMark Johnston /* No kmsan_check_arg, because inlined. */ 792a422084aSMark Johnston kmsan_init_ret(sizeof(void *)); 793a422084aSMark Johnston if (__predict_true(len != 0)) { 794a422084aSMark Johnston kmsan_meta_copy(dst, src, len); 795a422084aSMark Johnston } 796a422084aSMark Johnston return (__builtin_memcpy(dst, src, len)); 797a422084aSMark Johnston } 798a422084aSMark Johnston 799a422084aSMark Johnston int 800a422084aSMark Johnston kmsan_memcmp(const void *b1, const void *b2, size_t len) 801a422084aSMark Johnston { 802a422084aSMark Johnston const uint8_t *_b1 = b1, *_b2 = b2; 803a422084aSMark Johnston size_t i; 804a422084aSMark Johnston 805a422084aSMark Johnston kmsan_check_arg(sizeof(b1) + sizeof(b2) + sizeof(len), 806a422084aSMark Johnston "memcmp():args"); 807a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 808a422084aSMark Johnston 809a422084aSMark Johnston for (i = 0; i < len; i++) { 810a422084aSMark Johnston if (*_b1 != *_b2) { 811a422084aSMark Johnston kmsan_shadow_check((uintptr_t)b1, i + 1, 812a422084aSMark Johnston "memcmp():arg1"); 813a422084aSMark Johnston kmsan_shadow_check((uintptr_t)b2, i + 1, 814a422084aSMark Johnston "memcmp():arg2"); 815a422084aSMark Johnston return (*_b1 - *_b2); 816a422084aSMark Johnston } 817a422084aSMark Johnston _b1++, _b2++; 818a422084aSMark Johnston } 819a422084aSMark Johnston 820a422084aSMark Johnston return (0); 821a422084aSMark Johnston } 822a422084aSMark Johnston 823a422084aSMark Johnston void * 824a422084aSMark Johnston kmsan_memset(void *dst, int c, size_t len) 825a422084aSMark Johnston { 826a422084aSMark Johnston /* No kmsan_check_arg, because inlined. */ 827a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)dst, KMSAN_STATE_INITED, len); 828a422084aSMark Johnston kmsan_init_ret(sizeof(void *)); 829a422084aSMark Johnston return (__builtin_memset(dst, c, len)); 830a422084aSMark Johnston } 831a422084aSMark Johnston 832a422084aSMark Johnston void * 833a422084aSMark Johnston kmsan_memmove(void *dst, const void *src, size_t len) 834a422084aSMark Johnston { 835a422084aSMark Johnston /* No kmsan_check_arg, because inlined. */ 836a422084aSMark Johnston if (__predict_true(len != 0)) { 837a422084aSMark Johnston kmsan_meta_copy(dst, src, len); 838a422084aSMark Johnston } 839a422084aSMark Johnston kmsan_init_ret(sizeof(void *)); 840a422084aSMark Johnston return (__builtin_memmove(dst, src, len)); 841a422084aSMark Johnston } 842a422084aSMark Johnston 843a422084aSMark Johnston __strong_reference(kmsan_memcpy, __msan_memcpy); 844a422084aSMark Johnston __strong_reference(kmsan_memset, __msan_memset); 845a422084aSMark Johnston __strong_reference(kmsan_memmove, __msan_memmove); 846a422084aSMark Johnston 847a422084aSMark Johnston char * 848a422084aSMark Johnston kmsan_strcpy(char *dst, const char *src) 849a422084aSMark Johnston { 850a422084aSMark Johnston const char *_src = src; 851a422084aSMark Johnston char *_dst = dst; 852a422084aSMark Johnston size_t len = 0; 853a422084aSMark Johnston 854a422084aSMark Johnston kmsan_check_arg(sizeof(dst) + sizeof(src), "strcpy():args"); 855a422084aSMark Johnston 856a422084aSMark Johnston while (1) { 857a422084aSMark Johnston len++; 858a422084aSMark Johnston *dst = *src; 859a422084aSMark Johnston if (*src == '\0') 860a422084aSMark Johnston break; 861a422084aSMark Johnston src++, dst++; 862a422084aSMark Johnston } 863a422084aSMark Johnston 864a422084aSMark Johnston kmsan_shadow_check((uintptr_t)_src, len, "strcpy():arg2"); 865a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)_dst, KMSAN_STATE_INITED, len); 866a422084aSMark Johnston kmsan_init_ret(sizeof(char *)); 867a422084aSMark Johnston return (_dst); 868a422084aSMark Johnston } 869a422084aSMark Johnston 870a422084aSMark Johnston int 871a422084aSMark Johnston kmsan_strcmp(const char *s1, const char *s2) 872a422084aSMark Johnston { 873a422084aSMark Johnston const char *_s1 = s1, *_s2 = s2; 874a422084aSMark Johnston size_t len = 0; 875a422084aSMark Johnston 876a422084aSMark Johnston kmsan_check_arg(sizeof(s1) + sizeof(s2), "strcmp():args"); 877a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 878a422084aSMark Johnston 879a422084aSMark Johnston while (1) { 880a422084aSMark Johnston len++; 881a422084aSMark Johnston if (*s1 != *s2) 882a422084aSMark Johnston break; 883a422084aSMark Johnston if (*s1 == '\0') { 884a422084aSMark Johnston kmsan_shadow_check((uintptr_t)_s1, len, "strcmp():arg1"); 885a422084aSMark Johnston kmsan_shadow_check((uintptr_t)_s2, len, "strcmp():arg2"); 886a422084aSMark Johnston return (0); 887a422084aSMark Johnston } 888a422084aSMark Johnston s1++, s2++; 889a422084aSMark Johnston } 890a422084aSMark Johnston 891a422084aSMark Johnston kmsan_shadow_check((uintptr_t)_s1, len, "strcmp():arg1"); 892a422084aSMark Johnston kmsan_shadow_check((uintptr_t)_s2, len, "strcmp():arg2"); 893a422084aSMark Johnston 894a422084aSMark Johnston return (*(const unsigned char *)s1 - *(const unsigned char *)s2); 895a422084aSMark Johnston } 896a422084aSMark Johnston 897a422084aSMark Johnston size_t 898a422084aSMark Johnston kmsan_strlen(const char *str) 899a422084aSMark Johnston { 900a422084aSMark Johnston const char *s; 901a422084aSMark Johnston 902a422084aSMark Johnston kmsan_check_arg(sizeof(str), "strlen():args"); 903a422084aSMark Johnston 904a422084aSMark Johnston s = str; 905a422084aSMark Johnston while (1) { 906a422084aSMark Johnston if (*s == '\0') 907a422084aSMark Johnston break; 908a422084aSMark Johnston s++; 909a422084aSMark Johnston } 910a422084aSMark Johnston 911a422084aSMark Johnston kmsan_shadow_check((uintptr_t)str, (size_t)(s - str) + 1, "strlen():arg1"); 912a422084aSMark Johnston kmsan_init_ret(sizeof(size_t)); 913a422084aSMark Johnston return (s - str); 914a422084aSMark Johnston } 915a422084aSMark Johnston 916a422084aSMark Johnston int kmsan_copyin(const void *, void *, size_t); 917a422084aSMark Johnston int kmsan_copyout(const void *, void *, size_t); 918a422084aSMark Johnston int kmsan_copyinstr(const void *, void *, size_t, size_t *); 919a422084aSMark Johnston 920a422084aSMark Johnston int 921a422084aSMark Johnston kmsan_copyin(const void *uaddr, void *kaddr, size_t len) 922a422084aSMark Johnston { 923a422084aSMark Johnston int ret; 924a422084aSMark Johnston 925a422084aSMark Johnston kmsan_check_arg(sizeof(uaddr) + sizeof(kaddr) + sizeof(len), 926a422084aSMark Johnston "copyin():args"); 927a422084aSMark Johnston ret = copyin(uaddr, kaddr, len); 928a422084aSMark Johnston if (ret == 0) 929a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)kaddr, KMSAN_STATE_INITED, len); 930a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 931a422084aSMark Johnston return (ret); 932a422084aSMark Johnston } 933a422084aSMark Johnston 934a422084aSMark Johnston int 935a422084aSMark Johnston kmsan_copyout(const void *kaddr, void *uaddr, size_t len) 936a422084aSMark Johnston { 937a422084aSMark Johnston kmsan_check_arg(sizeof(kaddr) + sizeof(uaddr) + sizeof(len), 938a422084aSMark Johnston "copyout():args"); 939a422084aSMark Johnston kmsan_shadow_check((uintptr_t)kaddr, len, "copyout():arg1"); 940a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 941a422084aSMark Johnston return (copyout(kaddr, uaddr, len)); 942a422084aSMark Johnston } 943a422084aSMark Johnston 944a422084aSMark Johnston int 945a422084aSMark Johnston kmsan_copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) 946a422084aSMark Johnston { 947a422084aSMark Johnston size_t _done; 948a422084aSMark Johnston int ret; 949a422084aSMark Johnston 950a422084aSMark Johnston kmsan_check_arg(sizeof(uaddr) + sizeof(kaddr) + 951a422084aSMark Johnston sizeof(len) + sizeof(done), "copyinstr():args"); 952a422084aSMark Johnston ret = copyinstr(uaddr, kaddr, len, &_done); 953a422084aSMark Johnston if (ret == 0) 954a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)kaddr, KMSAN_STATE_INITED, _done); 955a422084aSMark Johnston if (done != NULL) { 956a422084aSMark Johnston *done = _done; 957a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)done, KMSAN_STATE_INITED, sizeof(size_t)); 958a422084aSMark Johnston } 959a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 960a422084aSMark Johnston return (ret); 961a422084aSMark Johnston } 962a422084aSMark Johnston 963a422084aSMark Johnston /* -------------------------------------------------------------------------- */ 964a422084aSMark Johnston 965a422084aSMark Johnston int 966a422084aSMark Johnston kmsan_fubyte(volatile const void *base) 967a422084aSMark Johnston { 968a422084aSMark Johnston int ret; 969a422084aSMark Johnston 970a422084aSMark Johnston kmsan_check_arg(sizeof(base), "fubyte(): args"); 971a422084aSMark Johnston ret = fubyte(base); 972a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 973a422084aSMark Johnston return (ret); 974a422084aSMark Johnston } 975a422084aSMark Johnston 976a422084aSMark Johnston int 977a422084aSMark Johnston kmsan_fuword16(volatile const void *base) 978a422084aSMark Johnston { 979a422084aSMark Johnston int ret; 980a422084aSMark Johnston 981a422084aSMark Johnston kmsan_check_arg(sizeof(base), "fuword16(): args"); 982a422084aSMark Johnston ret = fuword16(base); 983a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 984a422084aSMark Johnston return (ret); 985a422084aSMark Johnston } 986a422084aSMark Johnston 987a422084aSMark Johnston int 988a422084aSMark Johnston kmsan_fueword(volatile const void *base, long *val) 989a422084aSMark Johnston { 990a422084aSMark Johnston int ret; 991a422084aSMark Johnston 992a422084aSMark Johnston kmsan_check_arg(sizeof(base) + sizeof(val), "fueword(): args"); 993a422084aSMark Johnston ret = fueword(base, val); 994a422084aSMark Johnston if (ret == 0) 995a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)val, KMSAN_STATE_INITED, 996a422084aSMark Johnston sizeof(*val)); 997a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 998a422084aSMark Johnston return (ret); 999a422084aSMark Johnston } 1000a422084aSMark Johnston 1001a422084aSMark Johnston int 1002a422084aSMark Johnston kmsan_fueword32(volatile const void *base, int32_t *val) 1003a422084aSMark Johnston { 1004a422084aSMark Johnston int ret; 1005a422084aSMark Johnston 1006a422084aSMark Johnston kmsan_check_arg(sizeof(base) + sizeof(val), "fueword32(): args"); 1007a422084aSMark Johnston ret = fueword32(base, val); 1008a422084aSMark Johnston if (ret == 0) 1009a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)val, KMSAN_STATE_INITED, 1010a422084aSMark Johnston sizeof(*val)); 1011a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 1012a422084aSMark Johnston return (ret); 1013a422084aSMark Johnston } 1014a422084aSMark Johnston 1015a422084aSMark Johnston int 1016a422084aSMark Johnston kmsan_fueword64(volatile const void *base, int64_t *val) 1017a422084aSMark Johnston { 1018a422084aSMark Johnston int ret; 1019a422084aSMark Johnston 1020a422084aSMark Johnston kmsan_check_arg(sizeof(base) + sizeof(val), "fueword64(): args"); 1021a422084aSMark Johnston ret = fueword64(base, val); 1022a422084aSMark Johnston if (ret == 0) 1023a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)val, KMSAN_STATE_INITED, 1024a422084aSMark Johnston sizeof(*val)); 1025a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 1026a422084aSMark Johnston return (ret); 1027a422084aSMark Johnston } 1028a422084aSMark Johnston 1029a422084aSMark Johnston int 1030a422084aSMark Johnston kmsan_subyte(volatile void *base, int byte) 1031a422084aSMark Johnston { 1032a422084aSMark Johnston int ret; 1033a422084aSMark Johnston 1034a422084aSMark Johnston kmsan_check_arg(sizeof(base) + sizeof(byte), "subyte():args"); 1035a422084aSMark Johnston ret = subyte(base, byte); 1036a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 1037a422084aSMark Johnston return (ret); 1038a422084aSMark Johnston } 1039a422084aSMark Johnston 1040a422084aSMark Johnston int 1041a422084aSMark Johnston kmsan_suword(volatile void *base, long word) 1042a422084aSMark Johnston { 1043a422084aSMark Johnston int ret; 1044a422084aSMark Johnston 1045a422084aSMark Johnston kmsan_check_arg(sizeof(base) + sizeof(word), "suword():args"); 1046a422084aSMark Johnston ret = suword(base, word); 1047a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 1048a422084aSMark Johnston return (ret); 1049a422084aSMark Johnston } 1050a422084aSMark Johnston 1051a422084aSMark Johnston int 1052a422084aSMark Johnston kmsan_suword16(volatile void *base, int word) 1053a422084aSMark Johnston { 1054a422084aSMark Johnston int ret; 1055a422084aSMark Johnston 1056a422084aSMark Johnston kmsan_check_arg(sizeof(base) + sizeof(word), "suword16():args"); 1057a422084aSMark Johnston ret = suword16(base, word); 1058a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 1059a422084aSMark Johnston return (ret); 1060a422084aSMark Johnston } 1061a422084aSMark Johnston 1062a422084aSMark Johnston int 1063a422084aSMark Johnston kmsan_suword32(volatile void *base, int32_t word) 1064a422084aSMark Johnston { 1065a422084aSMark Johnston int ret; 1066a422084aSMark Johnston 1067a422084aSMark Johnston kmsan_check_arg(sizeof(base) + sizeof(word), "suword32():args"); 1068a422084aSMark Johnston ret = suword32(base, word); 1069a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 1070a422084aSMark Johnston return (ret); 1071a422084aSMark Johnston } 1072a422084aSMark Johnston 1073a422084aSMark Johnston int 1074a422084aSMark Johnston kmsan_suword64(volatile void *base, int64_t word) 1075a422084aSMark Johnston { 1076a422084aSMark Johnston int ret; 1077a422084aSMark Johnston 1078a422084aSMark Johnston kmsan_check_arg(sizeof(base) + sizeof(word), "suword64():args"); 1079a422084aSMark Johnston ret = suword64(base, word); 1080a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 1081a422084aSMark Johnston return (ret); 1082a422084aSMark Johnston } 1083a422084aSMark Johnston 1084a422084aSMark Johnston int 1085a422084aSMark Johnston kmsan_casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp, 1086a422084aSMark Johnston uint32_t newval) 1087a422084aSMark Johnston { 1088a422084aSMark Johnston int ret; 1089a422084aSMark Johnston 1090a422084aSMark Johnston kmsan_check_arg(sizeof(base) + sizeof(oldval) + sizeof(oldvalp) + 1091a422084aSMark Johnston sizeof(newval), "casueword32(): args"); 1092a422084aSMark Johnston ret = casueword32(base, oldval, oldvalp, newval); 1093a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)oldvalp, KMSAN_STATE_INITED, 1094a422084aSMark Johnston sizeof(*oldvalp)); 1095a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 1096a422084aSMark Johnston return (ret); 1097a422084aSMark Johnston } 1098a422084aSMark Johnston 1099a422084aSMark Johnston int 1100a422084aSMark Johnston kmsan_casueword(volatile u_long *base, u_long oldval, u_long *oldvalp, 1101a422084aSMark Johnston u_long newval) 1102a422084aSMark Johnston { 1103a422084aSMark Johnston int ret; 1104a422084aSMark Johnston 1105a422084aSMark Johnston kmsan_check_arg(sizeof(base) + sizeof(oldval) + sizeof(oldvalp) + 1106a422084aSMark Johnston sizeof(newval), "casueword32(): args"); 1107a422084aSMark Johnston ret = casueword(base, oldval, oldvalp, newval); 1108a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)oldvalp, KMSAN_STATE_INITED, 1109a422084aSMark Johnston sizeof(*oldvalp)); 1110a422084aSMark Johnston kmsan_init_ret(sizeof(int)); 1111a422084aSMark Johnston return (ret); 1112a422084aSMark Johnston } 1113a422084aSMark Johnston 1114a422084aSMark Johnston /* -------------------------------------------------------------------------- */ 1115a422084aSMark Johnston 1116a422084aSMark Johnston #include <machine/atomic.h> 1117a422084aSMark Johnston #include <sys/atomic_san.h> 1118a422084aSMark Johnston 1119a422084aSMark Johnston #define _MSAN_ATOMIC_FUNC_ADD(name, type) \ 1120a422084aSMark Johnston void kmsan_atomic_add_##name(volatile type *ptr, type val) \ 1121a422084aSMark Johnston { \ 1122a422084aSMark Johnston kmsan_check_arg(sizeof(ptr) + sizeof(val), \ 1123a422084aSMark Johnston "atomic_add_" #name "():args"); \ 1124a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1125a422084aSMark Johnston "atomic_add_" #name "():ptr"); \ 1126a422084aSMark Johnston atomic_add_##name(ptr, val); \ 1127a422084aSMark Johnston } 1128a422084aSMark Johnston 1129a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_ADD(name, type) \ 1130a422084aSMark Johnston _MSAN_ATOMIC_FUNC_ADD(name, type) \ 1131a422084aSMark Johnston _MSAN_ATOMIC_FUNC_ADD(acq_##name, type) \ 1132a422084aSMark Johnston _MSAN_ATOMIC_FUNC_ADD(rel_##name, type) 1133a422084aSMark Johnston 1134a422084aSMark Johnston #define _MSAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 1135a422084aSMark Johnston void kmsan_atomic_subtract_##name(volatile type *ptr, type val) \ 1136a422084aSMark Johnston { \ 1137a422084aSMark Johnston kmsan_check_arg(sizeof(ptr) + sizeof(val), \ 1138a422084aSMark Johnston "atomic_subtract_" #name "():args"); \ 1139a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1140a422084aSMark Johnston "atomic_subtract_" #name "():ptr"); \ 1141a422084aSMark Johnston atomic_subtract_##name(ptr, val); \ 1142a422084aSMark Johnston } 1143a422084aSMark Johnston 1144a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 1145a422084aSMark Johnston _MSAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 1146a422084aSMark Johnston _MSAN_ATOMIC_FUNC_SUBTRACT(acq_##name, type) \ 1147a422084aSMark Johnston _MSAN_ATOMIC_FUNC_SUBTRACT(rel_##name, type) 1148a422084aSMark Johnston 1149a422084aSMark Johnston #define _MSAN_ATOMIC_FUNC_SET(name, type) \ 1150a422084aSMark Johnston void kmsan_atomic_set_##name(volatile type *ptr, type val) \ 1151a422084aSMark Johnston { \ 1152a422084aSMark Johnston kmsan_check_arg(sizeof(ptr) + sizeof(val), \ 1153a422084aSMark Johnston "atomic_set_" #name "():args"); \ 1154a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1155a422084aSMark Johnston "atomic_set_" #name "():ptr"); \ 1156a422084aSMark Johnston atomic_set_##name(ptr, val); \ 1157a422084aSMark Johnston } 1158a422084aSMark Johnston 1159a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_SET(name, type) \ 1160a422084aSMark Johnston _MSAN_ATOMIC_FUNC_SET(name, type) \ 1161a422084aSMark Johnston _MSAN_ATOMIC_FUNC_SET(acq_##name, type) \ 1162a422084aSMark Johnston _MSAN_ATOMIC_FUNC_SET(rel_##name, type) 1163a422084aSMark Johnston 1164a422084aSMark Johnston #define _MSAN_ATOMIC_FUNC_CLEAR(name, type) \ 1165a422084aSMark Johnston void kmsan_atomic_clear_##name(volatile type *ptr, type val) \ 1166a422084aSMark Johnston { \ 1167a422084aSMark Johnston kmsan_check_arg(sizeof(ptr) + sizeof(val), \ 1168a422084aSMark Johnston "atomic_clear_" #name "():args"); \ 1169a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1170a422084aSMark Johnston "atomic_clear_" #name "():ptr"); \ 1171a422084aSMark Johnston atomic_clear_##name(ptr, val); \ 1172a422084aSMark Johnston } 1173a422084aSMark Johnston 1174a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_CLEAR(name, type) \ 1175a422084aSMark Johnston _MSAN_ATOMIC_FUNC_CLEAR(name, type) \ 1176a422084aSMark Johnston _MSAN_ATOMIC_FUNC_CLEAR(acq_##name, type) \ 1177a422084aSMark Johnston _MSAN_ATOMIC_FUNC_CLEAR(rel_##name, type) 1178a422084aSMark Johnston 1179a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_FETCHADD(name, type) \ 1180a422084aSMark Johnston type kmsan_atomic_fetchadd_##name(volatile type *ptr, type val) \ 1181a422084aSMark Johnston { \ 1182a422084aSMark Johnston kmsan_check_arg(sizeof(ptr) + sizeof(val), \ 1183a422084aSMark Johnston "atomic_fetchadd_" #name "():args"); \ 1184a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1185a422084aSMark Johnston "atomic_fetchadd_" #name "():ptr"); \ 1186a422084aSMark Johnston kmsan_init_ret(sizeof(type)); \ 1187a422084aSMark Johnston return (atomic_fetchadd_##name(ptr, val)); \ 1188a422084aSMark Johnston } 1189a422084aSMark Johnston 1190a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_READANDCLEAR(name, type) \ 1191a422084aSMark Johnston type kmsan_atomic_readandclear_##name(volatile type *ptr) \ 1192a422084aSMark Johnston { \ 1193a422084aSMark Johnston kmsan_check_arg(sizeof(ptr), \ 1194a422084aSMark Johnston "atomic_readandclear_" #name "():args"); \ 1195a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1196a422084aSMark Johnston "atomic_readandclear_" #name "():ptr"); \ 1197a422084aSMark Johnston kmsan_init_ret(sizeof(type)); \ 1198a422084aSMark Johnston return (atomic_readandclear_##name(ptr)); \ 1199a422084aSMark Johnston } 1200a422084aSMark Johnston 1201a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_TESTANDCLEAR(name, type) \ 1202a422084aSMark Johnston int kmsan_atomic_testandclear_##name(volatile type *ptr, u_int v) \ 1203a422084aSMark Johnston { \ 1204a422084aSMark Johnston kmsan_check_arg(sizeof(ptr) + sizeof(v), \ 1205a422084aSMark Johnston "atomic_testandclear_" #name "():args"); \ 1206a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1207a422084aSMark Johnston "atomic_testandclear_" #name "():ptr"); \ 1208a422084aSMark Johnston kmsan_init_ret(sizeof(int)); \ 1209a422084aSMark Johnston return (atomic_testandclear_##name(ptr, v)); \ 1210a422084aSMark Johnston } 1211a422084aSMark Johnston 1212a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_TESTANDSET(name, type) \ 1213a422084aSMark Johnston int kmsan_atomic_testandset_##name(volatile type *ptr, u_int v) \ 1214a422084aSMark Johnston { \ 1215a422084aSMark Johnston kmsan_check_arg(sizeof(ptr) + sizeof(v), \ 1216a422084aSMark Johnston "atomic_testandset_" #name "():args"); \ 1217a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1218a422084aSMark Johnston "atomic_testandset_" #name "():ptr"); \ 1219a422084aSMark Johnston kmsan_init_ret(sizeof(int)); \ 1220a422084aSMark Johnston return (atomic_testandset_##name(ptr, v)); \ 1221a422084aSMark Johnston } 1222a422084aSMark Johnston 1223a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_SWAP(name, type) \ 1224a422084aSMark Johnston type kmsan_atomic_swap_##name(volatile type *ptr, type val) \ 1225a422084aSMark Johnston { \ 1226a422084aSMark Johnston kmsan_check_arg(sizeof(ptr) + sizeof(val), \ 1227a422084aSMark Johnston "atomic_swap_" #name "():args"); \ 1228a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1229a422084aSMark Johnston "atomic_swap_" #name "():ptr"); \ 1230a422084aSMark Johnston kmsan_init_ret(sizeof(type)); \ 1231a422084aSMark Johnston return (atomic_swap_##name(ptr, val)); \ 1232a422084aSMark Johnston } 1233a422084aSMark Johnston 1234a422084aSMark Johnston #define _MSAN_ATOMIC_FUNC_CMPSET(name, type) \ 1235a422084aSMark Johnston int kmsan_atomic_cmpset_##name(volatile type *ptr, type oval, \ 1236a422084aSMark Johnston type nval) \ 1237a422084aSMark Johnston { \ 1238a422084aSMark Johnston kmsan_check_arg(sizeof(ptr) + sizeof(oval) + \ 1239a422084aSMark Johnston sizeof(nval), "atomic_cmpset_" #name "():args"); \ 1240a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1241a422084aSMark Johnston "atomic_cmpset_" #name "():ptr"); \ 1242a422084aSMark Johnston kmsan_init_ret(sizeof(int)); \ 1243a422084aSMark Johnston return (atomic_cmpset_##name(ptr, oval, nval)); \ 1244a422084aSMark Johnston } 1245a422084aSMark Johnston 1246a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_CMPSET(name, type) \ 1247a422084aSMark Johnston _MSAN_ATOMIC_FUNC_CMPSET(name, type) \ 1248a422084aSMark Johnston _MSAN_ATOMIC_FUNC_CMPSET(acq_##name, type) \ 1249a422084aSMark Johnston _MSAN_ATOMIC_FUNC_CMPSET(rel_##name, type) 1250a422084aSMark Johnston 1251a422084aSMark Johnston #define _MSAN_ATOMIC_FUNC_FCMPSET(name, type) \ 1252a422084aSMark Johnston int kmsan_atomic_fcmpset_##name(volatile type *ptr, type *oval, \ 1253a422084aSMark Johnston type nval) \ 1254a422084aSMark Johnston { \ 1255a422084aSMark Johnston kmsan_check_arg(sizeof(ptr) + sizeof(oval) + \ 1256a422084aSMark Johnston sizeof(nval), "atomic_fcmpset_" #name "():args"); \ 1257a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1258a422084aSMark Johnston "atomic_fcmpset_" #name "():ptr"); \ 1259a422084aSMark Johnston kmsan_init_ret(sizeof(int)); \ 1260a422084aSMark Johnston return (atomic_fcmpset_##name(ptr, oval, nval)); \ 1261a422084aSMark Johnston } 1262a422084aSMark Johnston 1263a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_FCMPSET(name, type) \ 1264a422084aSMark Johnston _MSAN_ATOMIC_FUNC_FCMPSET(name, type) \ 1265a422084aSMark Johnston _MSAN_ATOMIC_FUNC_FCMPSET(acq_##name, type) \ 1266a422084aSMark Johnston _MSAN_ATOMIC_FUNC_FCMPSET(rel_##name, type) 1267a422084aSMark Johnston 1268a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_THREAD_FENCE(name) \ 1269a422084aSMark Johnston void kmsan_atomic_thread_fence_##name(void) \ 1270a422084aSMark Johnston { \ 1271a422084aSMark Johnston atomic_thread_fence_##name(); \ 1272a422084aSMark Johnston } 1273a422084aSMark Johnston 1274a422084aSMark Johnston #define _MSAN_ATOMIC_FUNC_LOAD(name, type) \ 1275a422084aSMark Johnston type kmsan_atomic_load_##name(volatile type *ptr) \ 1276a422084aSMark Johnston { \ 1277a422084aSMark Johnston kmsan_check_arg(sizeof(ptr), \ 1278a422084aSMark Johnston "atomic_load_" #name "():args"); \ 1279a422084aSMark Johnston kmsan_shadow_check((uintptr_t)ptr, sizeof(type), \ 1280a422084aSMark Johnston "atomic_load_" #name "():ptr"); \ 1281a422084aSMark Johnston kmsan_init_ret(sizeof(type)); \ 1282a422084aSMark Johnston return (atomic_load_##name(ptr)); \ 1283a422084aSMark Johnston } 1284a422084aSMark Johnston 1285a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_LOAD(name, type) \ 1286a422084aSMark Johnston _MSAN_ATOMIC_FUNC_LOAD(name, type) \ 1287a422084aSMark Johnston _MSAN_ATOMIC_FUNC_LOAD(acq_##name, type) 1288a422084aSMark Johnston 1289a422084aSMark Johnston #define _MSAN_ATOMIC_FUNC_STORE(name, type) \ 1290a422084aSMark Johnston void kmsan_atomic_store_##name(volatile type *ptr, type val) \ 1291a422084aSMark Johnston { \ 1292a422084aSMark Johnston kmsan_check_arg(sizeof(ptr) + sizeof(val), \ 1293a422084aSMark Johnston "atomic_store_" #name "():args"); \ 1294a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)ptr, KMSAN_STATE_INITED, \ 1295a422084aSMark Johnston sizeof(type)); \ 1296a422084aSMark Johnston atomic_store_##name(ptr, val); \ 1297a422084aSMark Johnston } 1298a422084aSMark Johnston 1299a422084aSMark Johnston #define MSAN_ATOMIC_FUNC_STORE(name, type) \ 1300a422084aSMark Johnston _MSAN_ATOMIC_FUNC_STORE(name, type) \ 1301a422084aSMark Johnston _MSAN_ATOMIC_FUNC_STORE(rel_##name, type) 1302a422084aSMark Johnston 1303a422084aSMark Johnston MSAN_ATOMIC_FUNC_ADD(8, uint8_t); 1304a422084aSMark Johnston MSAN_ATOMIC_FUNC_ADD(16, uint16_t); 1305a422084aSMark Johnston MSAN_ATOMIC_FUNC_ADD(32, uint32_t); 1306a422084aSMark Johnston MSAN_ATOMIC_FUNC_ADD(64, uint64_t); 1307a422084aSMark Johnston MSAN_ATOMIC_FUNC_ADD(int, u_int); 1308a422084aSMark Johnston MSAN_ATOMIC_FUNC_ADD(long, u_long); 1309a422084aSMark Johnston MSAN_ATOMIC_FUNC_ADD(ptr, uintptr_t); 1310a422084aSMark Johnston 1311a422084aSMark Johnston MSAN_ATOMIC_FUNC_SUBTRACT(8, uint8_t); 1312a422084aSMark Johnston MSAN_ATOMIC_FUNC_SUBTRACT(16, uint16_t); 1313a422084aSMark Johnston MSAN_ATOMIC_FUNC_SUBTRACT(32, uint32_t); 1314a422084aSMark Johnston MSAN_ATOMIC_FUNC_SUBTRACT(64, uint64_t); 1315a422084aSMark Johnston MSAN_ATOMIC_FUNC_SUBTRACT(int, u_int); 1316a422084aSMark Johnston MSAN_ATOMIC_FUNC_SUBTRACT(long, u_long); 1317a422084aSMark Johnston MSAN_ATOMIC_FUNC_SUBTRACT(ptr, uintptr_t); 1318a422084aSMark Johnston 1319a422084aSMark Johnston MSAN_ATOMIC_FUNC_SET(8, uint8_t); 1320a422084aSMark Johnston MSAN_ATOMIC_FUNC_SET(16, uint16_t); 1321a422084aSMark Johnston MSAN_ATOMIC_FUNC_SET(32, uint32_t); 1322a422084aSMark Johnston MSAN_ATOMIC_FUNC_SET(64, uint64_t); 1323a422084aSMark Johnston MSAN_ATOMIC_FUNC_SET(int, u_int); 1324a422084aSMark Johnston MSAN_ATOMIC_FUNC_SET(long, u_long); 1325a422084aSMark Johnston MSAN_ATOMIC_FUNC_SET(ptr, uintptr_t); 1326a422084aSMark Johnston 1327a422084aSMark Johnston MSAN_ATOMIC_FUNC_CLEAR(8, uint8_t); 1328a422084aSMark Johnston MSAN_ATOMIC_FUNC_CLEAR(16, uint16_t); 1329a422084aSMark Johnston MSAN_ATOMIC_FUNC_CLEAR(32, uint32_t); 1330a422084aSMark Johnston MSAN_ATOMIC_FUNC_CLEAR(64, uint64_t); 1331a422084aSMark Johnston MSAN_ATOMIC_FUNC_CLEAR(int, u_int); 1332a422084aSMark Johnston MSAN_ATOMIC_FUNC_CLEAR(long, u_long); 1333a422084aSMark Johnston MSAN_ATOMIC_FUNC_CLEAR(ptr, uintptr_t); 1334a422084aSMark Johnston 1335a422084aSMark Johnston MSAN_ATOMIC_FUNC_FETCHADD(32, uint32_t); 1336a422084aSMark Johnston MSAN_ATOMIC_FUNC_FETCHADD(64, uint64_t); 1337a422084aSMark Johnston MSAN_ATOMIC_FUNC_FETCHADD(int, u_int); 1338a422084aSMark Johnston MSAN_ATOMIC_FUNC_FETCHADD(long, u_long); 1339a422084aSMark Johnston 1340a422084aSMark Johnston MSAN_ATOMIC_FUNC_READANDCLEAR(32, uint32_t); 1341a422084aSMark Johnston MSAN_ATOMIC_FUNC_READANDCLEAR(64, uint64_t); 1342a422084aSMark Johnston MSAN_ATOMIC_FUNC_READANDCLEAR(int, u_int); 1343a422084aSMark Johnston MSAN_ATOMIC_FUNC_READANDCLEAR(long, u_long); 1344a422084aSMark Johnston MSAN_ATOMIC_FUNC_READANDCLEAR(ptr, uintptr_t); 1345a422084aSMark Johnston 1346a422084aSMark Johnston MSAN_ATOMIC_FUNC_TESTANDCLEAR(32, uint32_t); 1347a422084aSMark Johnston MSAN_ATOMIC_FUNC_TESTANDCLEAR(64, uint64_t); 1348a422084aSMark Johnston MSAN_ATOMIC_FUNC_TESTANDCLEAR(int, u_int); 1349a422084aSMark Johnston MSAN_ATOMIC_FUNC_TESTANDCLEAR(long, u_long); 1350a422084aSMark Johnston 1351a422084aSMark Johnston MSAN_ATOMIC_FUNC_TESTANDSET(32, uint32_t); 1352a422084aSMark Johnston MSAN_ATOMIC_FUNC_TESTANDSET(64, uint64_t); 1353a422084aSMark Johnston MSAN_ATOMIC_FUNC_TESTANDSET(int, u_int); 1354a422084aSMark Johnston MSAN_ATOMIC_FUNC_TESTANDSET(long, u_long); 1355a422084aSMark Johnston 1356a422084aSMark Johnston MSAN_ATOMIC_FUNC_SWAP(32, uint32_t); 1357a422084aSMark Johnston MSAN_ATOMIC_FUNC_SWAP(64, uint64_t); 1358a422084aSMark Johnston MSAN_ATOMIC_FUNC_SWAP(int, u_int); 1359a422084aSMark Johnston MSAN_ATOMIC_FUNC_SWAP(long, u_long); 1360a422084aSMark Johnston MSAN_ATOMIC_FUNC_SWAP(ptr, uintptr_t); 1361a422084aSMark Johnston 1362a422084aSMark Johnston MSAN_ATOMIC_FUNC_CMPSET(8, uint8_t); 1363a422084aSMark Johnston MSAN_ATOMIC_FUNC_CMPSET(16, uint16_t); 1364a422084aSMark Johnston MSAN_ATOMIC_FUNC_CMPSET(32, uint32_t); 1365a422084aSMark Johnston MSAN_ATOMIC_FUNC_CMPSET(64, uint64_t); 1366a422084aSMark Johnston MSAN_ATOMIC_FUNC_CMPSET(int, u_int); 1367a422084aSMark Johnston MSAN_ATOMIC_FUNC_CMPSET(long, u_long); 1368a422084aSMark Johnston MSAN_ATOMIC_FUNC_CMPSET(ptr, uintptr_t); 1369a422084aSMark Johnston 1370a422084aSMark Johnston MSAN_ATOMIC_FUNC_FCMPSET(8, uint8_t); 1371a422084aSMark Johnston MSAN_ATOMIC_FUNC_FCMPSET(16, uint16_t); 1372a422084aSMark Johnston MSAN_ATOMIC_FUNC_FCMPSET(32, uint32_t); 1373a422084aSMark Johnston MSAN_ATOMIC_FUNC_FCMPSET(64, uint64_t); 1374a422084aSMark Johnston MSAN_ATOMIC_FUNC_FCMPSET(int, u_int); 1375a422084aSMark Johnston MSAN_ATOMIC_FUNC_FCMPSET(long, u_long); 1376a422084aSMark Johnston MSAN_ATOMIC_FUNC_FCMPSET(ptr, uintptr_t); 1377a422084aSMark Johnston 1378a422084aSMark Johnston MSAN_ATOMIC_FUNC_LOAD(8, uint8_t); 1379a422084aSMark Johnston MSAN_ATOMIC_FUNC_LOAD(16, uint16_t); 1380a422084aSMark Johnston MSAN_ATOMIC_FUNC_LOAD(32, uint32_t); 1381a422084aSMark Johnston MSAN_ATOMIC_FUNC_LOAD(64, uint64_t); 1382a422084aSMark Johnston MSAN_ATOMIC_FUNC_LOAD(char, u_char); 1383a422084aSMark Johnston MSAN_ATOMIC_FUNC_LOAD(short, u_short); 1384a422084aSMark Johnston MSAN_ATOMIC_FUNC_LOAD(int, u_int); 1385a422084aSMark Johnston MSAN_ATOMIC_FUNC_LOAD(long, u_long); 1386a422084aSMark Johnston MSAN_ATOMIC_FUNC_LOAD(ptr, uintptr_t); 1387a422084aSMark Johnston 1388a422084aSMark Johnston MSAN_ATOMIC_FUNC_STORE(8, uint8_t); 1389a422084aSMark Johnston MSAN_ATOMIC_FUNC_STORE(16, uint16_t); 1390a422084aSMark Johnston MSAN_ATOMIC_FUNC_STORE(32, uint32_t); 1391a422084aSMark Johnston MSAN_ATOMIC_FUNC_STORE(64, uint64_t); 1392a422084aSMark Johnston MSAN_ATOMIC_FUNC_STORE(char, u_char); 1393a422084aSMark Johnston MSAN_ATOMIC_FUNC_STORE(short, u_short); 1394a422084aSMark Johnston MSAN_ATOMIC_FUNC_STORE(int, u_int); 1395a422084aSMark Johnston MSAN_ATOMIC_FUNC_STORE(long, u_long); 1396a422084aSMark Johnston MSAN_ATOMIC_FUNC_STORE(ptr, uintptr_t); 1397a422084aSMark Johnston 1398a422084aSMark Johnston MSAN_ATOMIC_FUNC_THREAD_FENCE(acq); 1399a422084aSMark Johnston MSAN_ATOMIC_FUNC_THREAD_FENCE(rel); 1400a422084aSMark Johnston MSAN_ATOMIC_FUNC_THREAD_FENCE(acq_rel); 1401a422084aSMark Johnston MSAN_ATOMIC_FUNC_THREAD_FENCE(seq_cst); 1402a422084aSMark Johnston 1403a422084aSMark Johnston void 1404a422084aSMark Johnston kmsan_atomic_interrupt_fence(void) 1405a422084aSMark Johnston { 1406a422084aSMark Johnston atomic_interrupt_fence(); 1407a422084aSMark Johnston } 1408a422084aSMark Johnston 1409a422084aSMark Johnston /* -------------------------------------------------------------------------- */ 1410a422084aSMark Johnston 1411a422084aSMark Johnston #include <sys/bus.h> 1412a422084aSMark Johnston #include <machine/bus.h> 1413a422084aSMark Johnston #include <sys/bus_san.h> 1414a422084aSMark Johnston 1415a422084aSMark Johnston int 1416a422084aSMark Johnston kmsan_bus_space_map(bus_space_tag_t tag, bus_addr_t hnd, bus_size_t size, 1417a422084aSMark Johnston int flags, bus_space_handle_t *handlep) 1418a422084aSMark Johnston { 1419a422084aSMark Johnston return (bus_space_map(tag, hnd, size, flags, handlep)); 1420a422084aSMark Johnston } 1421a422084aSMark Johnston 1422a422084aSMark Johnston void 1423a422084aSMark Johnston kmsan_bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t hnd, 1424a422084aSMark Johnston bus_size_t size) 1425a422084aSMark Johnston { 1426a422084aSMark Johnston bus_space_unmap(tag, hnd, size); 1427a422084aSMark Johnston } 1428a422084aSMark Johnston 1429a422084aSMark Johnston int 1430a422084aSMark Johnston kmsan_bus_space_subregion(bus_space_tag_t tag, bus_space_handle_t hnd, 1431a422084aSMark Johnston bus_size_t offset, bus_size_t size, bus_space_handle_t *handlep) 1432a422084aSMark Johnston { 1433a422084aSMark Johnston return (bus_space_subregion(tag, hnd, offset, size, handlep)); 1434a422084aSMark Johnston } 1435a422084aSMark Johnston 1436a422084aSMark Johnston void 1437a422084aSMark Johnston kmsan_bus_space_free(bus_space_tag_t tag, bus_space_handle_t hnd, 1438a422084aSMark Johnston bus_size_t size) 1439a422084aSMark Johnston { 1440a422084aSMark Johnston bus_space_free(tag, hnd, size); 1441a422084aSMark Johnston } 1442a422084aSMark Johnston 1443a422084aSMark Johnston void 1444a422084aSMark Johnston kmsan_bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t hnd, 1445a422084aSMark Johnston bus_size_t offset, bus_size_t size, int flags) 1446a422084aSMark Johnston { 1447a422084aSMark Johnston bus_space_barrier(tag, hnd, offset, size, flags); 1448a422084aSMark Johnston } 1449a422084aSMark Johnston 1450a422084aSMark Johnston /* XXXMJ x86-specific */ 1451a422084aSMark Johnston #define MSAN_BUS_READ_FUNC(func, width, type) \ 1452a422084aSMark Johnston type kmsan_bus_space_read##func##_##width(bus_space_tag_t tag, \ 1453a422084aSMark Johnston bus_space_handle_t hnd, bus_size_t offset) \ 1454a422084aSMark Johnston { \ 1455a422084aSMark Johnston type ret; \ 1456a422084aSMark Johnston if ((tag) != X86_BUS_SPACE_IO) \ 1457a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)(hnd + offset), \ 1458a422084aSMark Johnston KMSAN_STATE_INITED, (width)); \ 1459a422084aSMark Johnston ret = bus_space_read##func##_##width(tag, hnd, offset); \ 1460a422084aSMark Johnston kmsan_init_ret(sizeof(type)); \ 1461a422084aSMark Johnston return (ret); \ 1462a422084aSMark Johnston } \ 1463a422084aSMark Johnston 1464a422084aSMark Johnston #define MSAN_BUS_READ_PTR_FUNC(func, width, type) \ 1465a422084aSMark Johnston void kmsan_bus_space_read_##func##_##width(bus_space_tag_t tag, \ 1466a422084aSMark Johnston bus_space_handle_t hnd, bus_size_t size, type *buf, \ 1467a422084aSMark Johnston bus_size_t count) \ 1468a422084aSMark Johnston { \ 1469a422084aSMark Johnston kmsan_shadow_fill((uintptr_t)buf, KMSAN_STATE_INITED, \ 1470a422084aSMark Johnston (width) * count); \ 1471a422084aSMark Johnston bus_space_read_##func##_##width(tag, hnd, size, buf, \ 1472a422084aSMark Johnston count); \ 1473a422084aSMark Johnston } 1474a422084aSMark Johnston 1475a422084aSMark Johnston MSAN_BUS_READ_FUNC(, 1, uint8_t) 1476a422084aSMark Johnston MSAN_BUS_READ_FUNC(_stream, 1, uint8_t) 1477a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(multi, 1, uint8_t) 1478a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(multi_stream, 1, uint8_t) 1479a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(region, 1, uint8_t) 1480a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(region_stream, 1, uint8_t) 1481a422084aSMark Johnston 1482a422084aSMark Johnston MSAN_BUS_READ_FUNC(, 2, uint16_t) 1483a422084aSMark Johnston MSAN_BUS_READ_FUNC(_stream, 2, uint16_t) 1484a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(multi, 2, uint16_t) 1485a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(multi_stream, 2, uint16_t) 1486a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(region, 2, uint16_t) 1487a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(region_stream, 2, uint16_t) 1488a422084aSMark Johnston 1489a422084aSMark Johnston MSAN_BUS_READ_FUNC(, 4, uint32_t) 1490a422084aSMark Johnston MSAN_BUS_READ_FUNC(_stream, 4, uint32_t) 1491a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(multi, 4, uint32_t) 1492a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(multi_stream, 4, uint32_t) 1493a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(region, 4, uint32_t) 1494a422084aSMark Johnston MSAN_BUS_READ_PTR_FUNC(region_stream, 4, uint32_t) 1495a422084aSMark Johnston 1496a422084aSMark Johnston MSAN_BUS_READ_FUNC(, 8, uint64_t) 1497a422084aSMark Johnston 1498a422084aSMark Johnston #define MSAN_BUS_WRITE_FUNC(func, width, type) \ 1499a422084aSMark Johnston void kmsan_bus_space_write##func##_##width(bus_space_tag_t tag, \ 1500a422084aSMark Johnston bus_space_handle_t hnd, bus_size_t offset, type value) \ 1501a422084aSMark Johnston { \ 1502a422084aSMark Johnston bus_space_write##func##_##width(tag, hnd, offset, value);\ 1503a422084aSMark Johnston } \ 1504a422084aSMark Johnston 1505a422084aSMark Johnston #define MSAN_BUS_WRITE_PTR_FUNC(func, width, type) \ 1506a422084aSMark Johnston void kmsan_bus_space_write_##func##_##width(bus_space_tag_t tag,\ 1507a422084aSMark Johnston bus_space_handle_t hnd, bus_size_t size, const type *buf, \ 1508a422084aSMark Johnston bus_size_t count) \ 1509a422084aSMark Johnston { \ 1510a422084aSMark Johnston kmsan_shadow_check((uintptr_t)buf, sizeof(type) * count,\ 1511a422084aSMark Johnston "bus_space_write()"); \ 1512a422084aSMark Johnston bus_space_write_##func##_##width(tag, hnd, size, buf, \ 1513a422084aSMark Johnston count); \ 1514a422084aSMark Johnston } 1515a422084aSMark Johnston 1516a422084aSMark Johnston MSAN_BUS_WRITE_FUNC(, 1, uint8_t) 1517a422084aSMark Johnston MSAN_BUS_WRITE_FUNC(_stream, 1, uint8_t) 1518a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(multi, 1, uint8_t) 1519a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(multi_stream, 1, uint8_t) 1520a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(region, 1, uint8_t) 1521a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(region_stream, 1, uint8_t) 1522a422084aSMark Johnston 1523a422084aSMark Johnston MSAN_BUS_WRITE_FUNC(, 2, uint16_t) 1524a422084aSMark Johnston MSAN_BUS_WRITE_FUNC(_stream, 2, uint16_t) 1525a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(multi, 2, uint16_t) 1526a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(multi_stream, 2, uint16_t) 1527a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(region, 2, uint16_t) 1528a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(region_stream, 2, uint16_t) 1529a422084aSMark Johnston 1530a422084aSMark Johnston MSAN_BUS_WRITE_FUNC(, 4, uint32_t) 1531a422084aSMark Johnston MSAN_BUS_WRITE_FUNC(_stream, 4, uint32_t) 1532a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(multi, 4, uint32_t) 1533a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(multi_stream, 4, uint32_t) 1534a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(region, 4, uint32_t) 1535a422084aSMark Johnston MSAN_BUS_WRITE_PTR_FUNC(region_stream, 4, uint32_t) 1536a422084aSMark Johnston 1537a422084aSMark Johnston MSAN_BUS_WRITE_FUNC(, 8, uint64_t) 1538a422084aSMark Johnston 1539a422084aSMark Johnston #define MSAN_BUS_SET_FUNC(func, width, type) \ 1540a422084aSMark Johnston void kmsan_bus_space_set_##func##_##width(bus_space_tag_t tag, \ 1541a422084aSMark Johnston bus_space_handle_t hnd, bus_size_t offset, type value, \ 1542a422084aSMark Johnston bus_size_t count) \ 1543a422084aSMark Johnston { \ 1544a422084aSMark Johnston bus_space_set_##func##_##width(tag, hnd, offset, value, \ 1545a422084aSMark Johnston count); \ 1546a422084aSMark Johnston } 1547a422084aSMark Johnston 1548a422084aSMark Johnston MSAN_BUS_SET_FUNC(multi, 1, uint8_t) 1549a422084aSMark Johnston MSAN_BUS_SET_FUNC(region, 1, uint8_t) 1550a422084aSMark Johnston MSAN_BUS_SET_FUNC(multi_stream, 1, uint8_t) 1551a422084aSMark Johnston MSAN_BUS_SET_FUNC(region_stream, 1, uint8_t) 1552a422084aSMark Johnston 1553a422084aSMark Johnston MSAN_BUS_SET_FUNC(multi, 2, uint16_t) 1554a422084aSMark Johnston MSAN_BUS_SET_FUNC(region, 2, uint16_t) 1555a422084aSMark Johnston MSAN_BUS_SET_FUNC(multi_stream, 2, uint16_t) 1556a422084aSMark Johnston MSAN_BUS_SET_FUNC(region_stream, 2, uint16_t) 1557a422084aSMark Johnston 1558a422084aSMark Johnston MSAN_BUS_SET_FUNC(multi, 4, uint32_t) 1559a422084aSMark Johnston MSAN_BUS_SET_FUNC(region, 4, uint32_t) 1560a422084aSMark Johnston MSAN_BUS_SET_FUNC(multi_stream, 4, uint32_t) 1561a422084aSMark Johnston MSAN_BUS_SET_FUNC(region_stream, 4, uint32_t) 1562a422084aSMark Johnston 1563a422084aSMark Johnston /* -------------------------------------------------------------------------- */ 1564a422084aSMark Johnston 1565a422084aSMark Johnston void 1566a422084aSMark Johnston kmsan_bus_dmamap_sync(struct memdesc *desc, bus_dmasync_op_t op) 1567a422084aSMark Johnston { 1568a422084aSMark Johnston /* 1569a422084aSMark Johnston * Some drivers, e.g., nvme, use the same code path for loading device 1570a422084aSMark Johnston * read and write requests, and will thus specify both flags. In this 1571a422084aSMark Johnston * case we should not do any checking since it will generally lead to 1572a422084aSMark Johnston * false positives. 1573a422084aSMark Johnston */ 1574a422084aSMark Johnston if ((op & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)) == 1575a422084aSMark Johnston BUS_DMASYNC_PREWRITE) { 1576a422084aSMark Johnston switch (desc->md_type) { 1577a422084aSMark Johnston case MEMDESC_VADDR: 1578a422084aSMark Johnston kmsan_check(desc->u.md_vaddr, desc->md_opaque, 1579a422084aSMark Johnston "dmasync"); 1580a422084aSMark Johnston break; 1581a422084aSMark Johnston case MEMDESC_BIO: 1582a422084aSMark Johnston kmsan_check_bio(desc->u.md_bio, "dmasync"); 1583a422084aSMark Johnston break; 1584a422084aSMark Johnston case MEMDESC_MBUF: 1585a422084aSMark Johnston kmsan_check_mbuf(desc->u.md_mbuf, "dmasync"); 1586a422084aSMark Johnston break; 1587a422084aSMark Johnston case MEMDESC_CCB: 1588a422084aSMark Johnston kmsan_check_ccb(desc->u.md_ccb, "dmasync"); 1589a422084aSMark Johnston break; 1590a422084aSMark Johnston case 0: 1591a422084aSMark Johnston break; 1592a422084aSMark Johnston default: 1593a422084aSMark Johnston kmsan_panic("%s: unhandled memdesc type %d", __func__, 1594a422084aSMark Johnston desc->md_type); 1595a422084aSMark Johnston } 1596a422084aSMark Johnston } 1597a422084aSMark Johnston if ((op & BUS_DMASYNC_POSTREAD) != 0) { 1598a422084aSMark Johnston switch (desc->md_type) { 1599a422084aSMark Johnston case MEMDESC_VADDR: 1600a422084aSMark Johnston kmsan_mark(desc->u.md_vaddr, desc->md_opaque, 1601a422084aSMark Johnston KMSAN_STATE_INITED); 1602a422084aSMark Johnston break; 1603a422084aSMark Johnston case MEMDESC_BIO: 1604a422084aSMark Johnston kmsan_mark_bio(desc->u.md_bio, KMSAN_STATE_INITED); 1605a422084aSMark Johnston break; 1606a422084aSMark Johnston case MEMDESC_MBUF: 1607a422084aSMark Johnston kmsan_mark_mbuf(desc->u.md_mbuf, KMSAN_STATE_INITED); 1608a422084aSMark Johnston break; 1609a422084aSMark Johnston case MEMDESC_CCB: 1610a422084aSMark Johnston kmsan_mark_ccb(desc->u.md_ccb, KMSAN_STATE_INITED); 1611a422084aSMark Johnston break; 1612a422084aSMark Johnston case 0: 1613a422084aSMark Johnston break; 1614a422084aSMark Johnston default: 1615a422084aSMark Johnston kmsan_panic("%s: unhandled memdesc type %d", __func__, 1616a422084aSMark Johnston desc->md_type); 1617a422084aSMark Johnston } 1618a422084aSMark Johnston } 1619a422084aSMark Johnston } 1620