10cb53570SAndrew Turner /* $NetBSD: subr_csan.c,v 1.5 2019/11/15 08:11:37 maxv Exp $ */ 20cb53570SAndrew Turner 30cb53570SAndrew Turner /* 40cb53570SAndrew Turner * Copyright (c) 2019 The NetBSD Foundation, Inc. 50cb53570SAndrew Turner * All rights reserved. 6*849aef49SAndrew Turner * Copyright (c) 2019 Andrew Turner 70cb53570SAndrew Turner * 80cb53570SAndrew Turner * This code is derived from software contributed to The NetBSD Foundation 90cb53570SAndrew Turner * by Maxime Villard. 100cb53570SAndrew Turner * 110cb53570SAndrew Turner * Redistribution and use in source and binary forms, with or without 120cb53570SAndrew Turner * modification, are permitted provided that the following conditions 130cb53570SAndrew Turner * are met: 140cb53570SAndrew Turner * 1. Redistributions of source code must retain the above copyright 150cb53570SAndrew Turner * notice, this list of conditions and the following disclaimer. 160cb53570SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright 170cb53570SAndrew Turner * notice, this list of conditions and the following disclaimer in the 180cb53570SAndrew Turner * documentation and/or other materials provided with the distribution. 190cb53570SAndrew Turner * 200cb53570SAndrew Turner * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 210cb53570SAndrew Turner * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 220cb53570SAndrew Turner * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 230cb53570SAndrew Turner * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 240cb53570SAndrew Turner * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 250cb53570SAndrew Turner * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 260cb53570SAndrew Turner * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 270cb53570SAndrew Turner * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 280cb53570SAndrew Turner * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 290cb53570SAndrew Turner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 300cb53570SAndrew Turner * POSSIBILITY OF SUCH DAMAGE. 310cb53570SAndrew Turner */ 320cb53570SAndrew Turner 33*849aef49SAndrew Turner #define KCSAN_RUNTIME 34*849aef49SAndrew Turner 35*849aef49SAndrew Turner #include "opt_ddb.h" 36*849aef49SAndrew Turner 370cb53570SAndrew Turner #include <sys/cdefs.h> 38*849aef49SAndrew Turner __FBSDID("$FreeBSD$"); 390cb53570SAndrew Turner 400cb53570SAndrew Turner #include <sys/param.h> 410cb53570SAndrew Turner #include <sys/kernel.h> 42*849aef49SAndrew Turner #include <sys/bus.h> 430cb53570SAndrew Turner #include <sys/conf.h> 440cb53570SAndrew Turner #include <sys/cpu.h> 45*849aef49SAndrew Turner #include <sys/csan.h> 46*849aef49SAndrew Turner #include <sys/proc.h> 47*849aef49SAndrew Turner #include <sys/smp.h> 48*849aef49SAndrew Turner #include <sys/systm.h> 49*849aef49SAndrew Turner 50*849aef49SAndrew Turner #include <ddb/ddb.h> 51*849aef49SAndrew Turner #include <ddb/db_sym.h> 520cb53570SAndrew Turner 530cb53570SAndrew Turner #ifdef KCSAN_PANIC 540cb53570SAndrew Turner #define REPORT panic 550cb53570SAndrew Turner #else 560cb53570SAndrew Turner #define REPORT printf 570cb53570SAndrew Turner #endif 580cb53570SAndrew Turner 590cb53570SAndrew Turner typedef struct { 600cb53570SAndrew Turner uintptr_t addr; 610cb53570SAndrew Turner uint32_t size; 620cb53570SAndrew Turner bool write:1; 630cb53570SAndrew Turner bool atomic:1; 640cb53570SAndrew Turner uintptr_t pc; 650cb53570SAndrew Turner } csan_cell_t; 660cb53570SAndrew Turner 670cb53570SAndrew Turner typedef struct { 680cb53570SAndrew Turner bool inited; 690cb53570SAndrew Turner uint32_t cnt; 700cb53570SAndrew Turner csan_cell_t cell; 710cb53570SAndrew Turner } csan_cpu_t; 720cb53570SAndrew Turner 73*849aef49SAndrew Turner static csan_cpu_t kcsan_cpus[MAXCPU]; 740cb53570SAndrew Turner static bool kcsan_enabled __read_mostly; 750cb53570SAndrew Turner 760cb53570SAndrew Turner #define __RET_ADDR (uintptr_t)__builtin_return_address(0) 770cb53570SAndrew Turner 780cb53570SAndrew Turner #define KCSAN_NACCESSES 1024 790cb53570SAndrew Turner #define KCSAN_DELAY 10 /* 10 microseconds */ 800cb53570SAndrew Turner 810cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 820cb53570SAndrew Turner 830cb53570SAndrew Turner /* The MD code. */ 840cb53570SAndrew Turner #include <machine/csan.h> 850cb53570SAndrew Turner 860cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 870cb53570SAndrew Turner 88*849aef49SAndrew Turner static void 89*849aef49SAndrew Turner kcsan_enable(void *dummy __unused) 900cb53570SAndrew Turner { 91*849aef49SAndrew Turner 92*849aef49SAndrew Turner printf("Enabling KCSCAN, expect reduced performance.\n"); 930cb53570SAndrew Turner kcsan_enabled = true; 940cb53570SAndrew Turner } 95*849aef49SAndrew Turner SYSINIT(kcsan_enable, SI_SUB_SMP, SI_ORDER_SECOND, kcsan_enable, NULL); 960cb53570SAndrew Turner 970cb53570SAndrew Turner void 98*849aef49SAndrew Turner kcsan_cpu_init(u_int cpu) 990cb53570SAndrew Turner { 100*849aef49SAndrew Turner kcsan_cpus[cpu].inited = true; 1010cb53570SAndrew Turner } 1020cb53570SAndrew Turner 1030cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 1040cb53570SAndrew Turner 1050cb53570SAndrew Turner static inline void 106*849aef49SAndrew Turner kcsan_report(csan_cell_t *new, u_int newcpu, csan_cell_t *old, u_int oldcpu) 1070cb53570SAndrew Turner { 1080cb53570SAndrew Turner const char *newsym, *oldsym; 109*849aef49SAndrew Turner #ifdef DDB 110*849aef49SAndrew Turner c_db_sym_t sym; 111*849aef49SAndrew Turner db_expr_t offset; 1120cb53570SAndrew Turner 113*849aef49SAndrew Turner sym = db_search_symbol((vm_offset_t)new->pc, DB_STGY_PROC, &offset); 114*849aef49SAndrew Turner db_symbol_values(sym, &newsym, NULL); 115*849aef49SAndrew Turner 116*849aef49SAndrew Turner sym = db_search_symbol((vm_offset_t)old->pc, DB_STGY_PROC, &offset); 117*849aef49SAndrew Turner db_symbol_values(sym, &oldsym, NULL); 118*849aef49SAndrew Turner #else 119*849aef49SAndrew Turner newsym = ""; 120*849aef49SAndrew Turner oldsym = ""; 121*849aef49SAndrew Turner #endif 1220cb53570SAndrew Turner REPORT("CSan: Racy Access " 123*849aef49SAndrew Turner "[Cpu%u %s%s Addr=%p Size=%u PC=%p<%s>] " 124*849aef49SAndrew Turner "[Cpu%u %s%s Addr=%p Size=%u PC=%p<%s>]\n", 1250cb53570SAndrew Turner newcpu, 1260cb53570SAndrew Turner (new->atomic ? "Atomic " : ""), (new->write ? "Write" : "Read"), 1270cb53570SAndrew Turner (void *)new->addr, new->size, (void *)new->pc, newsym, 1280cb53570SAndrew Turner oldcpu, 1290cb53570SAndrew Turner (old->atomic ? "Atomic " : ""), (old->write ? "Write" : "Read"), 1300cb53570SAndrew Turner (void *)old->addr, old->size, (void *)old->pc, oldsym); 1310cb53570SAndrew Turner kcsan_md_unwind(); 1320cb53570SAndrew Turner } 1330cb53570SAndrew Turner 1340cb53570SAndrew Turner static inline bool 1350cb53570SAndrew Turner kcsan_access_is_atomic(csan_cell_t *new, csan_cell_t *old) 1360cb53570SAndrew Turner { 1370cb53570SAndrew Turner if (new->write && !new->atomic) 1380cb53570SAndrew Turner return false; 1390cb53570SAndrew Turner if (old->write && !old->atomic) 1400cb53570SAndrew Turner return false; 1410cb53570SAndrew Turner return true; 1420cb53570SAndrew Turner } 1430cb53570SAndrew Turner 1440cb53570SAndrew Turner static inline void 1450cb53570SAndrew Turner kcsan_access(uintptr_t addr, size_t size, bool write, bool atomic, uintptr_t pc) 1460cb53570SAndrew Turner { 1470cb53570SAndrew Turner csan_cell_t old, new; 1480cb53570SAndrew Turner csan_cpu_t *cpu; 1490cb53570SAndrew Turner uint64_t intr; 1500cb53570SAndrew Turner size_t i; 1510cb53570SAndrew Turner 1520cb53570SAndrew Turner if (__predict_false(!kcsan_enabled)) 1530cb53570SAndrew Turner return; 1540cb53570SAndrew Turner 1550cb53570SAndrew Turner new.addr = addr; 1560cb53570SAndrew Turner new.size = size; 1570cb53570SAndrew Turner new.write = write; 1580cb53570SAndrew Turner new.atomic = atomic; 1590cb53570SAndrew Turner new.pc = pc; 1600cb53570SAndrew Turner 161*849aef49SAndrew Turner CPU_FOREACH(i) { 1620cb53570SAndrew Turner __builtin_memcpy(&old, &kcsan_cpus[i].cell, sizeof(old)); 1630cb53570SAndrew Turner 1640cb53570SAndrew Turner if (old.addr + old.size <= new.addr) 1650cb53570SAndrew Turner continue; 1660cb53570SAndrew Turner if (new.addr + new.size <= old.addr) 1670cb53570SAndrew Turner continue; 1680cb53570SAndrew Turner if (__predict_true(!old.write && !new.write)) 1690cb53570SAndrew Turner continue; 1700cb53570SAndrew Turner if (__predict_true(kcsan_access_is_atomic(&new, &old))) 1710cb53570SAndrew Turner continue; 1720cb53570SAndrew Turner 173*849aef49SAndrew Turner kcsan_report(&new, PCPU_GET(cpuid), &old, i); 1740cb53570SAndrew Turner break; 1750cb53570SAndrew Turner } 1760cb53570SAndrew Turner 1770cb53570SAndrew Turner if (__predict_false(!kcsan_md_is_avail())) 1780cb53570SAndrew Turner return; 1790cb53570SAndrew Turner 1800cb53570SAndrew Turner kcsan_md_disable_intrs(&intr); 1810cb53570SAndrew Turner 182*849aef49SAndrew Turner cpu = &kcsan_cpus[PCPU_GET(cpuid)]; 1830cb53570SAndrew Turner if (__predict_false(!cpu->inited)) 1840cb53570SAndrew Turner goto out; 1850cb53570SAndrew Turner cpu->cnt = (cpu->cnt + 1) % KCSAN_NACCESSES; 1860cb53570SAndrew Turner if (__predict_true(cpu->cnt != 0)) 1870cb53570SAndrew Turner goto out; 1880cb53570SAndrew Turner 1890cb53570SAndrew Turner __builtin_memcpy(&cpu->cell, &new, sizeof(new)); 1900cb53570SAndrew Turner kcsan_md_delay(KCSAN_DELAY); 1910cb53570SAndrew Turner __builtin_memset(&cpu->cell, 0, sizeof(new)); 1920cb53570SAndrew Turner 1930cb53570SAndrew Turner out: 1940cb53570SAndrew Turner kcsan_md_enable_intrs(&intr); 1950cb53570SAndrew Turner } 1960cb53570SAndrew Turner 1970cb53570SAndrew Turner #define CSAN_READ(size) \ 1980cb53570SAndrew Turner void __tsan_read##size(uintptr_t); \ 1990cb53570SAndrew Turner void __tsan_read##size(uintptr_t addr) \ 2000cb53570SAndrew Turner { \ 2010cb53570SAndrew Turner kcsan_access(addr, size, false, false, __RET_ADDR); \ 202*849aef49SAndrew Turner } \ 203*849aef49SAndrew Turner void __tsan_unaligned_read##size(uintptr_t); \ 204*849aef49SAndrew Turner void __tsan_unaligned_read##size(uintptr_t addr) \ 205*849aef49SAndrew Turner { \ 206*849aef49SAndrew Turner kcsan_access(addr, size, false, false, __RET_ADDR); \ 2070cb53570SAndrew Turner } 2080cb53570SAndrew Turner 2090cb53570SAndrew Turner CSAN_READ(1) 2100cb53570SAndrew Turner CSAN_READ(2) 2110cb53570SAndrew Turner CSAN_READ(4) 2120cb53570SAndrew Turner CSAN_READ(8) 2130cb53570SAndrew Turner CSAN_READ(16) 2140cb53570SAndrew Turner 2150cb53570SAndrew Turner #define CSAN_WRITE(size) \ 2160cb53570SAndrew Turner void __tsan_write##size(uintptr_t); \ 2170cb53570SAndrew Turner void __tsan_write##size(uintptr_t addr) \ 2180cb53570SAndrew Turner { \ 2190cb53570SAndrew Turner kcsan_access(addr, size, true, false, __RET_ADDR); \ 220*849aef49SAndrew Turner } \ 221*849aef49SAndrew Turner void __tsan_unaligned_write##size(uintptr_t); \ 222*849aef49SAndrew Turner void __tsan_unaligned_write##size(uintptr_t addr) \ 223*849aef49SAndrew Turner { \ 224*849aef49SAndrew Turner kcsan_access(addr, size, true, false, __RET_ADDR); \ 2250cb53570SAndrew Turner } 2260cb53570SAndrew Turner 2270cb53570SAndrew Turner CSAN_WRITE(1) 2280cb53570SAndrew Turner CSAN_WRITE(2) 2290cb53570SAndrew Turner CSAN_WRITE(4) 2300cb53570SAndrew Turner CSAN_WRITE(8) 2310cb53570SAndrew Turner CSAN_WRITE(16) 2320cb53570SAndrew Turner 2330cb53570SAndrew Turner void __tsan_read_range(uintptr_t, size_t); 2340cb53570SAndrew Turner void __tsan_write_range(uintptr_t, size_t); 2350cb53570SAndrew Turner 2360cb53570SAndrew Turner void 2370cb53570SAndrew Turner __tsan_read_range(uintptr_t addr, size_t size) 2380cb53570SAndrew Turner { 2390cb53570SAndrew Turner kcsan_access(addr, size, false, false, __RET_ADDR); 2400cb53570SAndrew Turner } 2410cb53570SAndrew Turner 2420cb53570SAndrew Turner void 2430cb53570SAndrew Turner __tsan_write_range(uintptr_t addr, size_t size) 2440cb53570SAndrew Turner { 2450cb53570SAndrew Turner kcsan_access(addr, size, true, false, __RET_ADDR); 2460cb53570SAndrew Turner } 2470cb53570SAndrew Turner 2480cb53570SAndrew Turner void __tsan_init(void); 2490cb53570SAndrew Turner void __tsan_func_entry(void *); 2500cb53570SAndrew Turner void __tsan_func_exit(void); 2510cb53570SAndrew Turner 2520cb53570SAndrew Turner void 2530cb53570SAndrew Turner __tsan_init(void) 2540cb53570SAndrew Turner { 2550cb53570SAndrew Turner } 2560cb53570SAndrew Turner 2570cb53570SAndrew Turner void 2580cb53570SAndrew Turner __tsan_func_entry(void *call_pc) 2590cb53570SAndrew Turner { 2600cb53570SAndrew Turner } 2610cb53570SAndrew Turner 2620cb53570SAndrew Turner void 2630cb53570SAndrew Turner __tsan_func_exit(void) 2640cb53570SAndrew Turner { 2650cb53570SAndrew Turner } 2660cb53570SAndrew Turner 2670cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 2680cb53570SAndrew Turner 2690cb53570SAndrew Turner void * 2700cb53570SAndrew Turner kcsan_memcpy(void *dst, const void *src, size_t len) 2710cb53570SAndrew Turner { 2720cb53570SAndrew Turner kcsan_access((uintptr_t)src, len, false, false, __RET_ADDR); 2730cb53570SAndrew Turner kcsan_access((uintptr_t)dst, len, true, false, __RET_ADDR); 2740cb53570SAndrew Turner return __builtin_memcpy(dst, src, len); 2750cb53570SAndrew Turner } 2760cb53570SAndrew Turner 2770cb53570SAndrew Turner int 2780cb53570SAndrew Turner kcsan_memcmp(const void *b1, const void *b2, size_t len) 2790cb53570SAndrew Turner { 2800cb53570SAndrew Turner kcsan_access((uintptr_t)b1, len, false, false, __RET_ADDR); 2810cb53570SAndrew Turner kcsan_access((uintptr_t)b2, len, false, false, __RET_ADDR); 2820cb53570SAndrew Turner return __builtin_memcmp(b1, b2, len); 2830cb53570SAndrew Turner } 2840cb53570SAndrew Turner 2850cb53570SAndrew Turner void * 2860cb53570SAndrew Turner kcsan_memset(void *b, int c, size_t len) 2870cb53570SAndrew Turner { 2880cb53570SAndrew Turner kcsan_access((uintptr_t)b, len, true, false, __RET_ADDR); 2890cb53570SAndrew Turner return __builtin_memset(b, c, len); 2900cb53570SAndrew Turner } 2910cb53570SAndrew Turner 2920cb53570SAndrew Turner void * 2930cb53570SAndrew Turner kcsan_memmove(void *dst, const void *src, size_t len) 2940cb53570SAndrew Turner { 2950cb53570SAndrew Turner kcsan_access((uintptr_t)src, len, false, false, __RET_ADDR); 2960cb53570SAndrew Turner kcsan_access((uintptr_t)dst, len, true, false, __RET_ADDR); 2970cb53570SAndrew Turner return __builtin_memmove(dst, src, len); 2980cb53570SAndrew Turner } 2990cb53570SAndrew Turner 3000cb53570SAndrew Turner char * 3010cb53570SAndrew Turner kcsan_strcpy(char *dst, const char *src) 3020cb53570SAndrew Turner { 3030cb53570SAndrew Turner char *save = dst; 3040cb53570SAndrew Turner 3050cb53570SAndrew Turner while (1) { 3060cb53570SAndrew Turner kcsan_access((uintptr_t)src, 1, false, false, __RET_ADDR); 3070cb53570SAndrew Turner kcsan_access((uintptr_t)dst, 1, true, false, __RET_ADDR); 3080cb53570SAndrew Turner *dst = *src; 3090cb53570SAndrew Turner if (*src == '\0') 3100cb53570SAndrew Turner break; 3110cb53570SAndrew Turner src++, dst++; 3120cb53570SAndrew Turner } 3130cb53570SAndrew Turner 3140cb53570SAndrew Turner return save; 3150cb53570SAndrew Turner } 3160cb53570SAndrew Turner 3170cb53570SAndrew Turner int 3180cb53570SAndrew Turner kcsan_strcmp(const char *s1, const char *s2) 3190cb53570SAndrew Turner { 3200cb53570SAndrew Turner while (1) { 3210cb53570SAndrew Turner kcsan_access((uintptr_t)s1, 1, false, false, __RET_ADDR); 3220cb53570SAndrew Turner kcsan_access((uintptr_t)s2, 1, false, false, __RET_ADDR); 3230cb53570SAndrew Turner if (*s1 != *s2) 3240cb53570SAndrew Turner break; 3250cb53570SAndrew Turner if (*s1 == '\0') 3260cb53570SAndrew Turner return 0; 3270cb53570SAndrew Turner s1++, s2++; 3280cb53570SAndrew Turner } 3290cb53570SAndrew Turner 3300cb53570SAndrew Turner return (*(const unsigned char *)s1 - *(const unsigned char *)s2); 3310cb53570SAndrew Turner } 3320cb53570SAndrew Turner 3330cb53570SAndrew Turner size_t 3340cb53570SAndrew Turner kcsan_strlen(const char *str) 3350cb53570SAndrew Turner { 3360cb53570SAndrew Turner const char *s; 3370cb53570SAndrew Turner 3380cb53570SAndrew Turner s = str; 3390cb53570SAndrew Turner while (1) { 3400cb53570SAndrew Turner kcsan_access((uintptr_t)s, 1, false, false, __RET_ADDR); 3410cb53570SAndrew Turner if (*s == '\0') 3420cb53570SAndrew Turner break; 3430cb53570SAndrew Turner s++; 3440cb53570SAndrew Turner } 3450cb53570SAndrew Turner 3460cb53570SAndrew Turner return (s - str); 3470cb53570SAndrew Turner } 3480cb53570SAndrew Turner 3490cb53570SAndrew Turner #undef copystr 3500cb53570SAndrew Turner #undef copyin 351*849aef49SAndrew Turner #undef copyin_nofault 352*849aef49SAndrew Turner #undef copyinstr 3530cb53570SAndrew Turner #undef copyout 354*849aef49SAndrew Turner #undef copyout_nofault 3550cb53570SAndrew Turner 3560cb53570SAndrew Turner int 3570cb53570SAndrew Turner kcsan_copystr(const void *kfaddr, void *kdaddr, size_t len, size_t *done) 3580cb53570SAndrew Turner { 3590cb53570SAndrew Turner kcsan_access((uintptr_t)kdaddr, len, true, false, __RET_ADDR); 3600cb53570SAndrew Turner return copystr(kfaddr, kdaddr, len, done); 3610cb53570SAndrew Turner } 3620cb53570SAndrew Turner 3630cb53570SAndrew Turner int 3640cb53570SAndrew Turner kcsan_copyin(const void *uaddr, void *kaddr, size_t len) 3650cb53570SAndrew Turner { 3660cb53570SAndrew Turner kcsan_access((uintptr_t)kaddr, len, true, false, __RET_ADDR); 3670cb53570SAndrew Turner return copyin(uaddr, kaddr, len); 3680cb53570SAndrew Turner } 3690cb53570SAndrew Turner 3700cb53570SAndrew Turner int 3710cb53570SAndrew Turner kcsan_copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) 3720cb53570SAndrew Turner { 3730cb53570SAndrew Turner kcsan_access((uintptr_t)kaddr, len, true, false, __RET_ADDR); 3740cb53570SAndrew Turner return copyinstr(uaddr, kaddr, len, done); 3750cb53570SAndrew Turner } 3760cb53570SAndrew Turner 3770cb53570SAndrew Turner int 378*849aef49SAndrew Turner kcsan_copyout(const void *kaddr, void *uaddr, size_t len) 3790cb53570SAndrew Turner { 3800cb53570SAndrew Turner kcsan_access((uintptr_t)kaddr, len, false, false, __RET_ADDR); 381*849aef49SAndrew Turner return copyout(kaddr, uaddr, len); 3820cb53570SAndrew Turner } 3830cb53570SAndrew Turner 3840cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 3850cb53570SAndrew Turner 386*849aef49SAndrew Turner #include <machine/atomic.h> 387*849aef49SAndrew Turner #include <sys/_cscan_atomic.h> 3880cb53570SAndrew Turner 389*849aef49SAndrew Turner #define _CSAN_ATOMIC_FUNC_ADD(name, type) \ 390*849aef49SAndrew Turner void kcsan_atomic_add_##name(volatile type *ptr, type val) \ 3910cb53570SAndrew Turner { \ 392*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 3930cb53570SAndrew Turner __RET_ADDR); \ 3940cb53570SAndrew Turner atomic_add_##name(ptr, val); \ 3950cb53570SAndrew Turner } 3960cb53570SAndrew Turner 397*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_ADD(name, type) \ 398*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_ADD(name, type) \ 399*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_ADD(acq_##name, type) \ 400*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_ADD(rel_##name, type) 401*849aef49SAndrew Turner 402*849aef49SAndrew Turner #define _CSAN_ATOMIC_FUNC_CLEAR(name, type) \ 403*849aef49SAndrew Turner void kcsan_atomic_clear_##name(volatile type *ptr, type val) \ 4040cb53570SAndrew Turner { \ 405*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 4060cb53570SAndrew Turner __RET_ADDR); \ 407*849aef49SAndrew Turner atomic_clear_##name(ptr, val); \ 4080cb53570SAndrew Turner } 4090cb53570SAndrew Turner 410*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_CLEAR(name, type) \ 411*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_CLEAR(name, type) \ 412*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_CLEAR(acq_##name, type) \ 413*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_CLEAR(rel_##name, type) 414*849aef49SAndrew Turner 415*849aef49SAndrew Turner #define _CSAN_ATOMIC_FUNC_CMPSET(name, type) \ 416*849aef49SAndrew Turner int kcsan_atomic_cmpset_##name(volatile type *ptr, type val1, \ 417*849aef49SAndrew Turner type val2) \ 4180cb53570SAndrew Turner { \ 419*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 4200cb53570SAndrew Turner __RET_ADDR); \ 421*849aef49SAndrew Turner return (atomic_cmpset_##name(ptr, val1, val2)); \ 4220cb53570SAndrew Turner } 4230cb53570SAndrew Turner 424*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_CMPSET(name, type) \ 425*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_CMPSET(name, type) \ 426*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_CMPSET(acq_##name, type) \ 427*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_CMPSET(rel_##name, type) 428*849aef49SAndrew Turner 429*849aef49SAndrew Turner #define _CSAN_ATOMIC_FUNC_FCMPSET(name, type) \ 430*849aef49SAndrew Turner int kcsan_atomic_fcmpset_##name(volatile type *ptr, type *val1, \ 431*849aef49SAndrew Turner type val2) \ 4320cb53570SAndrew Turner { \ 433*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 4340cb53570SAndrew Turner __RET_ADDR); \ 435*849aef49SAndrew Turner return (atomic_fcmpset_##name(ptr, val1, val2)); \ 4360cb53570SAndrew Turner } 4370cb53570SAndrew Turner 438*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_FCMPSET(name, type) \ 439*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_FCMPSET(name, type) \ 440*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_FCMPSET(acq_##name, type) \ 441*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_FCMPSET(rel_##name, type) 442*849aef49SAndrew Turner 443*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_FETCHADD(name, type) \ 444*849aef49SAndrew Turner type kcsan_atomic_fetchadd_##name(volatile type *ptr, type val) \ 4450cb53570SAndrew Turner { \ 446*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 4470cb53570SAndrew Turner __RET_ADDR); \ 448*849aef49SAndrew Turner return (atomic_fetchadd_##name(ptr, val)); \ 4490cb53570SAndrew Turner } 4500cb53570SAndrew Turner 451*849aef49SAndrew Turner #define _CSAN_ATOMIC_FUNC_LOAD(name, type) \ 452*849aef49SAndrew Turner type kcsan_atomic_load_##name(volatile type *ptr) \ 4530cb53570SAndrew Turner { \ 454*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), false, true, \ 4550cb53570SAndrew Turner __RET_ADDR); \ 456*849aef49SAndrew Turner return (atomic_load_##name(ptr)); \ 4570cb53570SAndrew Turner } 4580cb53570SAndrew Turner 459*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_LOAD(name, type) \ 460*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_LOAD(name, type) \ 461*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_LOAD(acq_##name, type) \ 462*849aef49SAndrew Turner 463*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_READANDCLEAR(name, type) \ 464*849aef49SAndrew Turner type kcsan_atomic_readandclear_##name(volatile type *ptr) \ 4650cb53570SAndrew Turner { \ 466*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 4670cb53570SAndrew Turner __RET_ADDR); \ 468*849aef49SAndrew Turner return (atomic_readandclear_##name(ptr)); \ 4690cb53570SAndrew Turner } 4700cb53570SAndrew Turner 471*849aef49SAndrew Turner #define _CSAN_ATOMIC_FUNC_SET(name, type) \ 472*849aef49SAndrew Turner void kcsan_atomic_set_##name(volatile type *ptr, type val) \ 473*849aef49SAndrew Turner { \ 474*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 475*849aef49SAndrew Turner __RET_ADDR); \ 476*849aef49SAndrew Turner atomic_set_##name(ptr, val); \ 477*849aef49SAndrew Turner } 4780cb53570SAndrew Turner 479*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_SET(name, type) \ 480*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_SET(name, type) \ 481*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_SET(acq_##name, type) \ 482*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_SET(rel_##name, type) 4830cb53570SAndrew Turner 484*849aef49SAndrew Turner #define _CSAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 485*849aef49SAndrew Turner void kcsan_atomic_subtract_##name(volatile type *ptr, type val) \ 486*849aef49SAndrew Turner { \ 487*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 488*849aef49SAndrew Turner __RET_ADDR); \ 489*849aef49SAndrew Turner atomic_subtract_##name(ptr, val); \ 490*849aef49SAndrew Turner } 4910cb53570SAndrew Turner 4920cb53570SAndrew Turner 493*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 494*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_SUBTRACT(name, type) \ 495*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_SUBTRACT(acq_##name, type) \ 496*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_SUBTRACT(rel_##name, type) 4970cb53570SAndrew Turner 498*849aef49SAndrew Turner #define _CSAN_ATOMIC_FUNC_STORE(name, type) \ 499*849aef49SAndrew Turner void kcsan_atomic_store_##name(volatile type *ptr, type val) \ 500*849aef49SAndrew Turner { \ 501*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 502*849aef49SAndrew Turner __RET_ADDR); \ 503*849aef49SAndrew Turner atomic_store_##name(ptr, val); \ 504*849aef49SAndrew Turner } 5050cb53570SAndrew Turner 506*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_STORE(name, type) \ 507*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_STORE(name, type) \ 508*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_STORE(rel_##name, type) 509*849aef49SAndrew Turner 510*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_SWAP(name, type) \ 511*849aef49SAndrew Turner type kcsan_atomic_swap_##name(volatile type *ptr, type val) \ 512*849aef49SAndrew Turner { \ 513*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 514*849aef49SAndrew Turner __RET_ADDR); \ 515*849aef49SAndrew Turner return(atomic_swap_##name(ptr, val)); \ 516*849aef49SAndrew Turner } 517*849aef49SAndrew Turner 518*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_TESTANDCLEAR(name, type) \ 519*849aef49SAndrew Turner int kcsan_atomic_testandclear_##name(volatile type *ptr, u_int val) \ 520*849aef49SAndrew Turner { \ 521*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 522*849aef49SAndrew Turner __RET_ADDR); \ 523*849aef49SAndrew Turner return(atomic_testandclear_##name(ptr, val)); \ 524*849aef49SAndrew Turner } 525*849aef49SAndrew Turner 526*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_TESTANDSET(name, type) \ 527*849aef49SAndrew Turner int kcsan_atomic_testandset_##name(volatile type *ptr, u_int val) \ 528*849aef49SAndrew Turner { \ 529*849aef49SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(type), true, true, \ 530*849aef49SAndrew Turner __RET_ADDR); \ 531*849aef49SAndrew Turner return (atomic_testandset_##name(ptr, val)); \ 532*849aef49SAndrew Turner } 533*849aef49SAndrew Turner 534*849aef49SAndrew Turner 535*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_ADD(8, uint8_t) 536*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CLEAR(8, uint8_t) 537*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CMPSET(8, uint8_t) 538*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FCMPSET(8, uint8_t) 539*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_LOAD(8, uint8_t) 540*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SET(8, uint8_t) 541*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SUBTRACT(8, uint8_t) 542*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_STORE(8, uint8_t) 543*849aef49SAndrew Turner #if 0 544*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FETCHADD(8, uint8_t) 545*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_READANDCLEAR(8, uint8_t) 546*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(8, uint8_t) 547*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDCLEAR(8, uint8_t) 548*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDSET(8, uint8_t) 549*849aef49SAndrew Turner #endif 550*849aef49SAndrew Turner 551*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_ADD(16, uint16_t) 552*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CLEAR(16, uint16_t) 553*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CMPSET(16, uint16_t) 554*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FCMPSET(16, uint16_t) 555*849aef49SAndrew Turner #if defined(__aarch64__) 556*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_LOAD(16, uint16_t) 557*849aef49SAndrew Turner #else 558*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_LOAD(16, uint16_t) 559*849aef49SAndrew Turner #endif 560*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SET(16, uint16_t) 561*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SUBTRACT(16, uint16_t) 562*849aef49SAndrew Turner _CSAN_ATOMIC_FUNC_STORE(16, uint16_t) 563*849aef49SAndrew Turner #if 0 564*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FETCHADD(16, uint16_t) 565*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_READANDCLEAR(16, uint16_t) 566*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(16, uint16_t) 567*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDCLEAR(16, uint16_t) 568*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDSET(16, uint16_t) 569*849aef49SAndrew Turner #endif 570*849aef49SAndrew Turner 571*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_ADD(32, uint32_t) 572*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CLEAR(32, uint32_t) 573*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CMPSET(32, uint32_t) 574*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FCMPSET(32, uint32_t) 575*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FETCHADD(32, uint32_t) 576*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_LOAD(32, uint32_t) 577*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_READANDCLEAR(32, uint32_t) 578*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SET(32, uint32_t) 579*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SUBTRACT(32, uint32_t) 580*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_STORE(32, uint32_t) 581*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(32, uint32_t) 582*849aef49SAndrew Turner #if !defined(__aarch64__) 583*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDCLEAR(32, uint32_t) 584*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDSET(32, uint32_t) 585*849aef49SAndrew Turner #endif 586*849aef49SAndrew Turner 587*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_ADD(64, uint64_t) 588*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CLEAR(64, uint64_t) 589*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CMPSET(64, uint64_t) 590*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FCMPSET(64, uint64_t) 591*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FETCHADD(64, uint64_t) 592*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_LOAD(64, uint64_t) 593*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_READANDCLEAR(64, uint64_t) 594*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SET(64, uint64_t) 595*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SUBTRACT(64, uint64_t) 596*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_STORE(64, uint64_t) 597*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(64, uint64_t) 598*849aef49SAndrew Turner #if !defined(__aarch64__) 599*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDCLEAR(64, uint64_t) 600*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDSET(64, uint64_t) 601*849aef49SAndrew Turner #endif 602*849aef49SAndrew Turner 603*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_ADD(int, u_int) 604*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CLEAR(int, u_int) 605*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CMPSET(int, u_int) 606*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FCMPSET(int, u_int) 607*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FETCHADD(int, u_int) 608*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_LOAD(int, u_int) 609*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_READANDCLEAR(int, u_int) 610*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SET(int, u_int) 611*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SUBTRACT(int, u_int) 612*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_STORE(int, u_int) 613*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(int, u_int) 614*849aef49SAndrew Turner #if !defined(__aarch64__) 615*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDCLEAR(int, u_int) 616*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDSET(int, u_int) 617*849aef49SAndrew Turner #endif 618*849aef49SAndrew Turner 619*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_ADD(long, u_long) 620*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CLEAR(long, u_long) 621*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CMPSET(long, u_long) 622*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FCMPSET(long, u_long) 623*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FETCHADD(long, u_long) 624*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_LOAD(long, u_long) 625*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_READANDCLEAR(long, u_long) 626*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SET(long, u_long) 627*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SUBTRACT(long, u_long) 628*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_STORE(long, u_long) 629*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(long, u_long) 630*849aef49SAndrew Turner #if !defined(__aarch64__) 631*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDCLEAR(long, u_long) 632*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDSET(long, u_long) 633*849aef49SAndrew Turner #endif 634*849aef49SAndrew Turner 635*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_ADD(ptr, uintptr_t) 636*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CLEAR(ptr, uintptr_t) 637*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_CMPSET(ptr, uintptr_t) 638*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FCMPSET(ptr, uintptr_t) 639*849aef49SAndrew Turner #if !defined(__amd64__) 640*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_FETCHADD(ptr, uintptr_t) 641*849aef49SAndrew Turner #endif 642*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_LOAD(ptr, uintptr_t) 643*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_READANDCLEAR(ptr, uintptr_t) 644*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SET(ptr, uintptr_t) 645*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SUBTRACT(ptr, uintptr_t) 646*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_STORE(ptr, uintptr_t) 647*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(ptr, uintptr_t) 648*849aef49SAndrew Turner #if 0 649*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDCLEAR(ptr, uintptr_t) 650*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_TESTANDSET(ptr, uintptr_t) 651*849aef49SAndrew Turner #endif 652*849aef49SAndrew Turner 653*849aef49SAndrew Turner #define CSAN_ATOMIC_FUNC_THREAD_FENCE(name) \ 654*849aef49SAndrew Turner void kcsan_atomic_thread_fence_##name(void) \ 655*849aef49SAndrew Turner { \ 656*849aef49SAndrew Turner atomic_thread_fence_##name(); \ 657*849aef49SAndrew Turner } 658*849aef49SAndrew Turner 659*849aef49SAndrew Turner 660*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_THREAD_FENCE(acq) 661*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_THREAD_FENCE(acq_rel) 662*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_THREAD_FENCE(rel) 663*849aef49SAndrew Turner CSAN_ATOMIC_FUNC_THREAD_FENCE(seq_cst) 6640cb53570SAndrew Turner 6650cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 6660cb53570SAndrew Turner 6670cb53570SAndrew Turner #include <sys/bus.h> 668*849aef49SAndrew Turner #include <machine/bus.h> 669*849aef49SAndrew Turner #include <sys/_cscan_bus.h> 6700cb53570SAndrew Turner 671*849aef49SAndrew Turner int 672*849aef49SAndrew Turner kcsan_bus_space_map(bus_space_tag_t tag, bus_addr_t hnd, bus_size_t size, 673*849aef49SAndrew Turner int flags, bus_space_handle_t *handlep) 674*849aef49SAndrew Turner { 6750cb53570SAndrew Turner 676*849aef49SAndrew Turner return (bus_space_map(tag, hnd, size, flags, handlep)); 6770cb53570SAndrew Turner } 6780cb53570SAndrew Turner 679*849aef49SAndrew Turner void 680*849aef49SAndrew Turner kcsan_bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t hnd, 681*849aef49SAndrew Turner bus_size_t size) 682*849aef49SAndrew Turner { 683*849aef49SAndrew Turner 684*849aef49SAndrew Turner bus_space_unmap(tag, hnd, size); 6850cb53570SAndrew Turner } 6860cb53570SAndrew Turner 687*849aef49SAndrew Turner int 688*849aef49SAndrew Turner kcsan_bus_space_subregion(bus_space_tag_t tag, bus_space_handle_t hnd, 689*849aef49SAndrew Turner bus_size_t offset, bus_size_t size, bus_space_handle_t *handlep) 690*849aef49SAndrew Turner { 6910cb53570SAndrew Turner 692*849aef49SAndrew Turner return (bus_space_subregion(tag, hnd, offset, size, handlep)); 693*849aef49SAndrew Turner } 694*849aef49SAndrew Turner 695*849aef49SAndrew Turner #if !defined(__amd64__) 696*849aef49SAndrew Turner int 697*849aef49SAndrew Turner kcsan_bus_space_alloc(bus_space_tag_t tag, bus_addr_t reg_start, 698*849aef49SAndrew Turner bus_addr_t reg_end, bus_size_t size, bus_size_t alignment, 699*849aef49SAndrew Turner bus_size_t boundary, int flags, bus_addr_t *addrp, 700*849aef49SAndrew Turner bus_space_handle_t *handlep) 701*849aef49SAndrew Turner { 702*849aef49SAndrew Turner 703*849aef49SAndrew Turner return (bus_space_alloc(tag, reg_start, reg_end, size, alignment, 704*849aef49SAndrew Turner boundary, flags, addrp, handlep)); 705*849aef49SAndrew Turner } 706*849aef49SAndrew Turner #endif 707*849aef49SAndrew Turner 708*849aef49SAndrew Turner void 709*849aef49SAndrew Turner kcsan_bus_space_free(bus_space_tag_t tag, bus_space_handle_t hnd, 710*849aef49SAndrew Turner bus_size_t size) 711*849aef49SAndrew Turner { 712*849aef49SAndrew Turner 713*849aef49SAndrew Turner bus_space_free(tag, hnd, size); 714*849aef49SAndrew Turner } 715*849aef49SAndrew Turner 716*849aef49SAndrew Turner void 717*849aef49SAndrew Turner kcsan_bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t hnd, 718*849aef49SAndrew Turner bus_size_t offset, bus_size_t size, int flags) 719*849aef49SAndrew Turner { 720*849aef49SAndrew Turner 721*849aef49SAndrew Turner bus_space_barrier(tag, hnd, offset, size, flags); 722*849aef49SAndrew Turner } 723*849aef49SAndrew Turner 724*849aef49SAndrew Turner #define CSAN_BUS_READ_FUNC(func, width, type) \ 725*849aef49SAndrew Turner type kcsan_bus_space_read##func##_##width(bus_space_tag_t tag, \ 726*849aef49SAndrew Turner bus_space_handle_t hnd, bus_size_t offset) \ 727*849aef49SAndrew Turner { \ 728*849aef49SAndrew Turner return (bus_space_read##func##_##width(tag, hnd, \ 729*849aef49SAndrew Turner offset)); \ 730*849aef49SAndrew Turner } \ 731*849aef49SAndrew Turner 732*849aef49SAndrew Turner #define CSAN_BUS_READ_PTR_FUNC(func, width, type) \ 733*849aef49SAndrew Turner void kcsan_bus_space_read_##func##_##width(bus_space_tag_t tag, \ 734*849aef49SAndrew Turner bus_space_handle_t hnd, bus_size_t size, type *buf, \ 735*849aef49SAndrew Turner bus_size_t count) \ 736*849aef49SAndrew Turner { \ 737*849aef49SAndrew Turner kcsan_access((uintptr_t)buf, sizeof(type) * count, \ 738*849aef49SAndrew Turner false, false, __RET_ADDR); \ 739*849aef49SAndrew Turner bus_space_read_##func##_##width(tag, hnd, size, buf, \ 740*849aef49SAndrew Turner count); \ 741*849aef49SAndrew Turner } 742*849aef49SAndrew Turner 743*849aef49SAndrew Turner CSAN_BUS_READ_FUNC(, 1, uint8_t) 744*849aef49SAndrew Turner CSAN_BUS_READ_FUNC(_stream, 1, uint8_t) 745*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(multi, 1, uint8_t) 746*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(multi_stream, 1, uint8_t) 747*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(region, 1, uint8_t) 748*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(region_stream, 1, uint8_t) 749*849aef49SAndrew Turner 750*849aef49SAndrew Turner CSAN_BUS_READ_FUNC(, 2, uint16_t) 751*849aef49SAndrew Turner CSAN_BUS_READ_FUNC(_stream, 2, uint16_t) 752*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(multi, 2, uint16_t) 753*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(multi_stream, 2, uint16_t) 754*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(region, 2, uint16_t) 755*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(region_stream, 2, uint16_t) 756*849aef49SAndrew Turner 757*849aef49SAndrew Turner CSAN_BUS_READ_FUNC(, 4, uint32_t) 758*849aef49SAndrew Turner CSAN_BUS_READ_FUNC(_stream, 4, uint32_t) 759*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(multi, 4, uint32_t) 760*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(multi_stream, 4, uint32_t) 761*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(region, 4, uint32_t) 762*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(region_stream, 4, uint32_t) 763*849aef49SAndrew Turner 764*849aef49SAndrew Turner CSAN_BUS_READ_FUNC(, 8, uint64_t) 765*849aef49SAndrew Turner #if defined(__aarch64__) 766*849aef49SAndrew Turner CSAN_BUS_READ_FUNC(_stream, 8, uint64_t) 767*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(multi, 8, uint64_t) 768*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(multi_stream, 8, uint64_t) 769*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(region, 8, uint64_t) 770*849aef49SAndrew Turner CSAN_BUS_READ_PTR_FUNC(region_stream, 8, uint64_t) 771*849aef49SAndrew Turner #endif 772*849aef49SAndrew Turner 773*849aef49SAndrew Turner #define CSAN_BUS_WRITE_FUNC(func, width, type) \ 774*849aef49SAndrew Turner void kcsan_bus_space_write##func##_##width(bus_space_tag_t tag, \ 775*849aef49SAndrew Turner bus_space_handle_t hnd, bus_size_t offset, type value) \ 776*849aef49SAndrew Turner { \ 777*849aef49SAndrew Turner bus_space_write##func##_##width(tag, hnd, offset, value); \ 778*849aef49SAndrew Turner } \ 779*849aef49SAndrew Turner 780*849aef49SAndrew Turner #define CSAN_BUS_WRITE_PTR_FUNC(func, width, type) \ 781*849aef49SAndrew Turner void kcsan_bus_space_write_##func##_##width(bus_space_tag_t tag, \ 782*849aef49SAndrew Turner bus_space_handle_t hnd, bus_size_t size, const type *buf, \ 783*849aef49SAndrew Turner bus_size_t count) \ 784*849aef49SAndrew Turner { \ 785*849aef49SAndrew Turner kcsan_access((uintptr_t)buf, sizeof(type) * count, \ 786*849aef49SAndrew Turner true, false, __RET_ADDR); \ 787*849aef49SAndrew Turner bus_space_write_##func##_##width(tag, hnd, size, buf, \ 788*849aef49SAndrew Turner count); \ 789*849aef49SAndrew Turner } 790*849aef49SAndrew Turner 791*849aef49SAndrew Turner CSAN_BUS_WRITE_FUNC(, 1, uint8_t) 792*849aef49SAndrew Turner CSAN_BUS_WRITE_FUNC(_stream, 1, uint8_t) 793*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(multi, 1, uint8_t) 794*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(multi_stream, 1, uint8_t) 795*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(region, 1, uint8_t) 796*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(region_stream, 1, uint8_t) 797*849aef49SAndrew Turner 798*849aef49SAndrew Turner CSAN_BUS_WRITE_FUNC(, 2, uint16_t) 799*849aef49SAndrew Turner CSAN_BUS_WRITE_FUNC(_stream, 2, uint16_t) 800*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(multi, 2, uint16_t) 801*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(multi_stream, 2, uint16_t) 802*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(region, 2, uint16_t) 803*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(region_stream, 2, uint16_t) 804*849aef49SAndrew Turner 805*849aef49SAndrew Turner CSAN_BUS_WRITE_FUNC(, 4, uint32_t) 806*849aef49SAndrew Turner CSAN_BUS_WRITE_FUNC(_stream, 4, uint32_t) 807*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(multi, 4, uint32_t) 808*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(multi_stream, 4, uint32_t) 809*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(region, 4, uint32_t) 810*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(region_stream, 4, uint32_t) 811*849aef49SAndrew Turner 812*849aef49SAndrew Turner CSAN_BUS_WRITE_FUNC(, 8, uint64_t) 813*849aef49SAndrew Turner #if defined(__aarch64__) 814*849aef49SAndrew Turner CSAN_BUS_WRITE_FUNC(_stream, 8, uint64_t) 815*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(multi, 8, uint64_t) 816*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(multi_stream, 8, uint64_t) 817*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(region, 8, uint64_t) 818*849aef49SAndrew Turner CSAN_BUS_WRITE_PTR_FUNC(region_stream, 8, uint64_t) 819*849aef49SAndrew Turner #endif 820*849aef49SAndrew Turner 821*849aef49SAndrew Turner #define CSAN_BUS_SET_FUNC(func, width, type) \ 822*849aef49SAndrew Turner void kcsan_bus_space_set_##func##_##width(bus_space_tag_t tag, \ 823*849aef49SAndrew Turner bus_space_handle_t hnd, bus_size_t offset, type value, \ 824*849aef49SAndrew Turner bus_size_t count) \ 825*849aef49SAndrew Turner { \ 826*849aef49SAndrew Turner bus_space_set_##func##_##width(tag, hnd, offset, value, \ 827*849aef49SAndrew Turner count); \ 828*849aef49SAndrew Turner } 829*849aef49SAndrew Turner 830*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(multi, 1, uint8_t) 831*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(multi_stream, 1, uint8_t) 832*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(region, 1, uint8_t) 833*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(region_stream, 1, uint8_t) 834*849aef49SAndrew Turner 835*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(multi, 2, uint16_t) 836*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(multi_stream, 2, uint16_t) 837*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(region, 2, uint16_t) 838*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(region_stream, 2, uint16_t) 839*849aef49SAndrew Turner 840*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(multi, 4, uint32_t) 841*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(multi_stream, 4, uint32_t) 842*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(region, 4, uint32_t) 843*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(region_stream, 4, uint32_t) 844*849aef49SAndrew Turner 845*849aef49SAndrew Turner #if !defined(__amd64__) 846*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(multi, 8, uint64_t) 847*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(multi_stream, 8, uint64_t) 848*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(region, 8, uint64_t) 849*849aef49SAndrew Turner CSAN_BUS_SET_FUNC(region_stream, 8, uint64_t) 850*849aef49SAndrew Turner #endif 851*849aef49SAndrew Turner 852