1*0cb53570SAndrew Turner /* $NetBSD: subr_csan.c,v 1.5 2019/11/15 08:11:37 maxv Exp $ */ 2*0cb53570SAndrew Turner 3*0cb53570SAndrew Turner /* 4*0cb53570SAndrew Turner * Copyright (c) 2019 The NetBSD Foundation, Inc. 5*0cb53570SAndrew Turner * All rights reserved. 6*0cb53570SAndrew Turner * 7*0cb53570SAndrew Turner * This code is derived from software contributed to The NetBSD Foundation 8*0cb53570SAndrew Turner * by Maxime Villard. 9*0cb53570SAndrew Turner * 10*0cb53570SAndrew Turner * Redistribution and use in source and binary forms, with or without 11*0cb53570SAndrew Turner * modification, are permitted provided that the following conditions 12*0cb53570SAndrew Turner * are met: 13*0cb53570SAndrew Turner * 1. Redistributions of source code must retain the above copyright 14*0cb53570SAndrew Turner * notice, this list of conditions and the following disclaimer. 15*0cb53570SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright 16*0cb53570SAndrew Turner * notice, this list of conditions and the following disclaimer in the 17*0cb53570SAndrew Turner * documentation and/or other materials provided with the distribution. 18*0cb53570SAndrew Turner * 19*0cb53570SAndrew Turner * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20*0cb53570SAndrew Turner * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21*0cb53570SAndrew Turner * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22*0cb53570SAndrew Turner * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23*0cb53570SAndrew Turner * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24*0cb53570SAndrew Turner * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25*0cb53570SAndrew Turner * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*0cb53570SAndrew Turner * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27*0cb53570SAndrew Turner * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28*0cb53570SAndrew Turner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*0cb53570SAndrew Turner * POSSIBILITY OF SUCH DAMAGE. 30*0cb53570SAndrew Turner */ 31*0cb53570SAndrew Turner 32*0cb53570SAndrew Turner #include <sys/cdefs.h> 33*0cb53570SAndrew Turner __KERNEL_RCSID(0, "$NetBSD: subr_csan.c,v 1.5 2019/11/15 08:11:37 maxv Exp $"); 34*0cb53570SAndrew Turner 35*0cb53570SAndrew Turner #include <sys/param.h> 36*0cb53570SAndrew Turner #include <sys/device.h> 37*0cb53570SAndrew Turner #include <sys/kernel.h> 38*0cb53570SAndrew Turner #include <sys/param.h> 39*0cb53570SAndrew Turner #include <sys/conf.h> 40*0cb53570SAndrew Turner #include <sys/systm.h> 41*0cb53570SAndrew Turner #include <sys/types.h> 42*0cb53570SAndrew Turner #include <sys/csan.h> 43*0cb53570SAndrew Turner #include <sys/cpu.h> 44*0cb53570SAndrew Turner 45*0cb53570SAndrew Turner #ifdef KCSAN_PANIC 46*0cb53570SAndrew Turner #define REPORT panic 47*0cb53570SAndrew Turner #else 48*0cb53570SAndrew Turner #define REPORT printf 49*0cb53570SAndrew Turner #endif 50*0cb53570SAndrew Turner 51*0cb53570SAndrew Turner typedef struct { 52*0cb53570SAndrew Turner uintptr_t addr; 53*0cb53570SAndrew Turner uint32_t size; 54*0cb53570SAndrew Turner bool write:1; 55*0cb53570SAndrew Turner bool atomic:1; 56*0cb53570SAndrew Turner uintptr_t pc; 57*0cb53570SAndrew Turner } csan_cell_t; 58*0cb53570SAndrew Turner 59*0cb53570SAndrew Turner typedef struct { 60*0cb53570SAndrew Turner bool inited; 61*0cb53570SAndrew Turner uint32_t cnt; 62*0cb53570SAndrew Turner csan_cell_t cell; 63*0cb53570SAndrew Turner } csan_cpu_t; 64*0cb53570SAndrew Turner 65*0cb53570SAndrew Turner static csan_cpu_t kcsan_cpus[MAXCPUS]; 66*0cb53570SAndrew Turner static bool kcsan_enabled __read_mostly; 67*0cb53570SAndrew Turner 68*0cb53570SAndrew Turner #define __RET_ADDR (uintptr_t)__builtin_return_address(0) 69*0cb53570SAndrew Turner 70*0cb53570SAndrew Turner #define KCSAN_NACCESSES 1024 71*0cb53570SAndrew Turner #define KCSAN_DELAY 10 /* 10 microseconds */ 72*0cb53570SAndrew Turner 73*0cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 74*0cb53570SAndrew Turner 75*0cb53570SAndrew Turner /* The MD code. */ 76*0cb53570SAndrew Turner #include <machine/csan.h> 77*0cb53570SAndrew Turner 78*0cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 79*0cb53570SAndrew Turner 80*0cb53570SAndrew Turner void 81*0cb53570SAndrew Turner kcsan_init(void) 82*0cb53570SAndrew Turner { 83*0cb53570SAndrew Turner kcsan_enabled = true; 84*0cb53570SAndrew Turner } 85*0cb53570SAndrew Turner 86*0cb53570SAndrew Turner void 87*0cb53570SAndrew Turner kcsan_cpu_init(struct cpu_info *ci) 88*0cb53570SAndrew Turner { 89*0cb53570SAndrew Turner kcsan_cpus[cpu_index(ci)].inited = true; 90*0cb53570SAndrew Turner } 91*0cb53570SAndrew Turner 92*0cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 93*0cb53570SAndrew Turner 94*0cb53570SAndrew Turner static inline void 95*0cb53570SAndrew Turner kcsan_report(csan_cell_t *new, cpuid_t newcpu, csan_cell_t *old, cpuid_t oldcpu) 96*0cb53570SAndrew Turner { 97*0cb53570SAndrew Turner const char *newsym, *oldsym; 98*0cb53570SAndrew Turner 99*0cb53570SAndrew Turner if (ksyms_getname(NULL, &newsym, (vaddr_t)new->pc, KSYMS_PROC) != 0) { 100*0cb53570SAndrew Turner newsym = "Unknown"; 101*0cb53570SAndrew Turner } 102*0cb53570SAndrew Turner if (ksyms_getname(NULL, &oldsym, (vaddr_t)old->pc, KSYMS_PROC) != 0) { 103*0cb53570SAndrew Turner oldsym = "Unknown"; 104*0cb53570SAndrew Turner } 105*0cb53570SAndrew Turner REPORT("CSan: Racy Access " 106*0cb53570SAndrew Turner "[Cpu%lu %s%s Addr=%p Size=%u PC=%p<%s>] " 107*0cb53570SAndrew Turner "[Cpu%lu %s%s Addr=%p Size=%u PC=%p<%s>]\n", 108*0cb53570SAndrew Turner newcpu, 109*0cb53570SAndrew Turner (new->atomic ? "Atomic " : ""), (new->write ? "Write" : "Read"), 110*0cb53570SAndrew Turner (void *)new->addr, new->size, (void *)new->pc, newsym, 111*0cb53570SAndrew Turner oldcpu, 112*0cb53570SAndrew Turner (old->atomic ? "Atomic " : ""), (old->write ? "Write" : "Read"), 113*0cb53570SAndrew Turner (void *)old->addr, old->size, (void *)old->pc, oldsym); 114*0cb53570SAndrew Turner kcsan_md_unwind(); 115*0cb53570SAndrew Turner } 116*0cb53570SAndrew Turner 117*0cb53570SAndrew Turner static inline bool 118*0cb53570SAndrew Turner kcsan_access_is_atomic(csan_cell_t *new, csan_cell_t *old) 119*0cb53570SAndrew Turner { 120*0cb53570SAndrew Turner if (new->write && !new->atomic) 121*0cb53570SAndrew Turner return false; 122*0cb53570SAndrew Turner if (old->write && !old->atomic) 123*0cb53570SAndrew Turner return false; 124*0cb53570SAndrew Turner return true; 125*0cb53570SAndrew Turner } 126*0cb53570SAndrew Turner 127*0cb53570SAndrew Turner static inline void 128*0cb53570SAndrew Turner kcsan_access(uintptr_t addr, size_t size, bool write, bool atomic, uintptr_t pc) 129*0cb53570SAndrew Turner { 130*0cb53570SAndrew Turner csan_cell_t old, new; 131*0cb53570SAndrew Turner csan_cpu_t *cpu; 132*0cb53570SAndrew Turner uint64_t intr; 133*0cb53570SAndrew Turner size_t i; 134*0cb53570SAndrew Turner 135*0cb53570SAndrew Turner if (__predict_false(!kcsan_enabled)) 136*0cb53570SAndrew Turner return; 137*0cb53570SAndrew Turner if (__predict_false(kcsan_md_unsupported((vaddr_t)addr))) 138*0cb53570SAndrew Turner return; 139*0cb53570SAndrew Turner 140*0cb53570SAndrew Turner new.addr = addr; 141*0cb53570SAndrew Turner new.size = size; 142*0cb53570SAndrew Turner new.write = write; 143*0cb53570SAndrew Turner new.atomic = atomic; 144*0cb53570SAndrew Turner new.pc = pc; 145*0cb53570SAndrew Turner 146*0cb53570SAndrew Turner for (i = 0; i < ncpu; i++) { 147*0cb53570SAndrew Turner __builtin_memcpy(&old, &kcsan_cpus[i].cell, sizeof(old)); 148*0cb53570SAndrew Turner 149*0cb53570SAndrew Turner if (old.addr + old.size <= new.addr) 150*0cb53570SAndrew Turner continue; 151*0cb53570SAndrew Turner if (new.addr + new.size <= old.addr) 152*0cb53570SAndrew Turner continue; 153*0cb53570SAndrew Turner if (__predict_true(!old.write && !new.write)) 154*0cb53570SAndrew Turner continue; 155*0cb53570SAndrew Turner if (__predict_true(kcsan_access_is_atomic(&new, &old))) 156*0cb53570SAndrew Turner continue; 157*0cb53570SAndrew Turner 158*0cb53570SAndrew Turner kcsan_report(&new, cpu_number(), &old, i); 159*0cb53570SAndrew Turner break; 160*0cb53570SAndrew Turner } 161*0cb53570SAndrew Turner 162*0cb53570SAndrew Turner if (__predict_false(!kcsan_md_is_avail())) 163*0cb53570SAndrew Turner return; 164*0cb53570SAndrew Turner 165*0cb53570SAndrew Turner kcsan_md_disable_intrs(&intr); 166*0cb53570SAndrew Turner 167*0cb53570SAndrew Turner cpu = &kcsan_cpus[cpu_number()]; 168*0cb53570SAndrew Turner if (__predict_false(!cpu->inited)) 169*0cb53570SAndrew Turner goto out; 170*0cb53570SAndrew Turner cpu->cnt = (cpu->cnt + 1) % KCSAN_NACCESSES; 171*0cb53570SAndrew Turner if (__predict_true(cpu->cnt != 0)) 172*0cb53570SAndrew Turner goto out; 173*0cb53570SAndrew Turner 174*0cb53570SAndrew Turner __builtin_memcpy(&cpu->cell, &new, sizeof(new)); 175*0cb53570SAndrew Turner kcsan_md_delay(KCSAN_DELAY); 176*0cb53570SAndrew Turner __builtin_memset(&cpu->cell, 0, sizeof(new)); 177*0cb53570SAndrew Turner 178*0cb53570SAndrew Turner out: 179*0cb53570SAndrew Turner kcsan_md_enable_intrs(&intr); 180*0cb53570SAndrew Turner } 181*0cb53570SAndrew Turner 182*0cb53570SAndrew Turner #define CSAN_READ(size) \ 183*0cb53570SAndrew Turner void __tsan_read##size(uintptr_t); \ 184*0cb53570SAndrew Turner void __tsan_read##size(uintptr_t addr) \ 185*0cb53570SAndrew Turner { \ 186*0cb53570SAndrew Turner kcsan_access(addr, size, false, false, __RET_ADDR); \ 187*0cb53570SAndrew Turner } 188*0cb53570SAndrew Turner 189*0cb53570SAndrew Turner CSAN_READ(1) 190*0cb53570SAndrew Turner CSAN_READ(2) 191*0cb53570SAndrew Turner CSAN_READ(4) 192*0cb53570SAndrew Turner CSAN_READ(8) 193*0cb53570SAndrew Turner CSAN_READ(16) 194*0cb53570SAndrew Turner 195*0cb53570SAndrew Turner #define CSAN_WRITE(size) \ 196*0cb53570SAndrew Turner void __tsan_write##size(uintptr_t); \ 197*0cb53570SAndrew Turner void __tsan_write##size(uintptr_t addr) \ 198*0cb53570SAndrew Turner { \ 199*0cb53570SAndrew Turner kcsan_access(addr, size, true, false, __RET_ADDR); \ 200*0cb53570SAndrew Turner } 201*0cb53570SAndrew Turner 202*0cb53570SAndrew Turner CSAN_WRITE(1) 203*0cb53570SAndrew Turner CSAN_WRITE(2) 204*0cb53570SAndrew Turner CSAN_WRITE(4) 205*0cb53570SAndrew Turner CSAN_WRITE(8) 206*0cb53570SAndrew Turner CSAN_WRITE(16) 207*0cb53570SAndrew Turner 208*0cb53570SAndrew Turner void __tsan_read_range(uintptr_t, size_t); 209*0cb53570SAndrew Turner void __tsan_write_range(uintptr_t, size_t); 210*0cb53570SAndrew Turner 211*0cb53570SAndrew Turner void 212*0cb53570SAndrew Turner __tsan_read_range(uintptr_t addr, size_t size) 213*0cb53570SAndrew Turner { 214*0cb53570SAndrew Turner kcsan_access(addr, size, false, false, __RET_ADDR); 215*0cb53570SAndrew Turner } 216*0cb53570SAndrew Turner 217*0cb53570SAndrew Turner void 218*0cb53570SAndrew Turner __tsan_write_range(uintptr_t addr, size_t size) 219*0cb53570SAndrew Turner { 220*0cb53570SAndrew Turner kcsan_access(addr, size, true, false, __RET_ADDR); 221*0cb53570SAndrew Turner } 222*0cb53570SAndrew Turner 223*0cb53570SAndrew Turner void __tsan_init(void); 224*0cb53570SAndrew Turner void __tsan_func_entry(void *); 225*0cb53570SAndrew Turner void __tsan_func_exit(void); 226*0cb53570SAndrew Turner 227*0cb53570SAndrew Turner void 228*0cb53570SAndrew Turner __tsan_init(void) 229*0cb53570SAndrew Turner { 230*0cb53570SAndrew Turner } 231*0cb53570SAndrew Turner 232*0cb53570SAndrew Turner void 233*0cb53570SAndrew Turner __tsan_func_entry(void *call_pc) 234*0cb53570SAndrew Turner { 235*0cb53570SAndrew Turner } 236*0cb53570SAndrew Turner 237*0cb53570SAndrew Turner void 238*0cb53570SAndrew Turner __tsan_func_exit(void) 239*0cb53570SAndrew Turner { 240*0cb53570SAndrew Turner } 241*0cb53570SAndrew Turner 242*0cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 243*0cb53570SAndrew Turner 244*0cb53570SAndrew Turner void * 245*0cb53570SAndrew Turner kcsan_memcpy(void *dst, const void *src, size_t len) 246*0cb53570SAndrew Turner { 247*0cb53570SAndrew Turner kcsan_access((uintptr_t)src, len, false, false, __RET_ADDR); 248*0cb53570SAndrew Turner kcsan_access((uintptr_t)dst, len, true, false, __RET_ADDR); 249*0cb53570SAndrew Turner return __builtin_memcpy(dst, src, len); 250*0cb53570SAndrew Turner } 251*0cb53570SAndrew Turner 252*0cb53570SAndrew Turner int 253*0cb53570SAndrew Turner kcsan_memcmp(const void *b1, const void *b2, size_t len) 254*0cb53570SAndrew Turner { 255*0cb53570SAndrew Turner kcsan_access((uintptr_t)b1, len, false, false, __RET_ADDR); 256*0cb53570SAndrew Turner kcsan_access((uintptr_t)b2, len, false, false, __RET_ADDR); 257*0cb53570SAndrew Turner return __builtin_memcmp(b1, b2, len); 258*0cb53570SAndrew Turner } 259*0cb53570SAndrew Turner 260*0cb53570SAndrew Turner void * 261*0cb53570SAndrew Turner kcsan_memset(void *b, int c, size_t len) 262*0cb53570SAndrew Turner { 263*0cb53570SAndrew Turner kcsan_access((uintptr_t)b, len, true, false, __RET_ADDR); 264*0cb53570SAndrew Turner return __builtin_memset(b, c, len); 265*0cb53570SAndrew Turner } 266*0cb53570SAndrew Turner 267*0cb53570SAndrew Turner void * 268*0cb53570SAndrew Turner kcsan_memmove(void *dst, const void *src, size_t len) 269*0cb53570SAndrew Turner { 270*0cb53570SAndrew Turner kcsan_access((uintptr_t)src, len, false, false, __RET_ADDR); 271*0cb53570SAndrew Turner kcsan_access((uintptr_t)dst, len, true, false, __RET_ADDR); 272*0cb53570SAndrew Turner return __builtin_memmove(dst, src, len); 273*0cb53570SAndrew Turner } 274*0cb53570SAndrew Turner 275*0cb53570SAndrew Turner char * 276*0cb53570SAndrew Turner kcsan_strcpy(char *dst, const char *src) 277*0cb53570SAndrew Turner { 278*0cb53570SAndrew Turner char *save = dst; 279*0cb53570SAndrew Turner 280*0cb53570SAndrew Turner while (1) { 281*0cb53570SAndrew Turner kcsan_access((uintptr_t)src, 1, false, false, __RET_ADDR); 282*0cb53570SAndrew Turner kcsan_access((uintptr_t)dst, 1, true, false, __RET_ADDR); 283*0cb53570SAndrew Turner *dst = *src; 284*0cb53570SAndrew Turner if (*src == '\0') 285*0cb53570SAndrew Turner break; 286*0cb53570SAndrew Turner src++, dst++; 287*0cb53570SAndrew Turner } 288*0cb53570SAndrew Turner 289*0cb53570SAndrew Turner return save; 290*0cb53570SAndrew Turner } 291*0cb53570SAndrew Turner 292*0cb53570SAndrew Turner int 293*0cb53570SAndrew Turner kcsan_strcmp(const char *s1, const char *s2) 294*0cb53570SAndrew Turner { 295*0cb53570SAndrew Turner while (1) { 296*0cb53570SAndrew Turner kcsan_access((uintptr_t)s1, 1, false, false, __RET_ADDR); 297*0cb53570SAndrew Turner kcsan_access((uintptr_t)s2, 1, false, false, __RET_ADDR); 298*0cb53570SAndrew Turner if (*s1 != *s2) 299*0cb53570SAndrew Turner break; 300*0cb53570SAndrew Turner if (*s1 == '\0') 301*0cb53570SAndrew Turner return 0; 302*0cb53570SAndrew Turner s1++, s2++; 303*0cb53570SAndrew Turner } 304*0cb53570SAndrew Turner 305*0cb53570SAndrew Turner return (*(const unsigned char *)s1 - *(const unsigned char *)s2); 306*0cb53570SAndrew Turner } 307*0cb53570SAndrew Turner 308*0cb53570SAndrew Turner size_t 309*0cb53570SAndrew Turner kcsan_strlen(const char *str) 310*0cb53570SAndrew Turner { 311*0cb53570SAndrew Turner const char *s; 312*0cb53570SAndrew Turner 313*0cb53570SAndrew Turner s = str; 314*0cb53570SAndrew Turner while (1) { 315*0cb53570SAndrew Turner kcsan_access((uintptr_t)s, 1, false, false, __RET_ADDR); 316*0cb53570SAndrew Turner if (*s == '\0') 317*0cb53570SAndrew Turner break; 318*0cb53570SAndrew Turner s++; 319*0cb53570SAndrew Turner } 320*0cb53570SAndrew Turner 321*0cb53570SAndrew Turner return (s - str); 322*0cb53570SAndrew Turner } 323*0cb53570SAndrew Turner 324*0cb53570SAndrew Turner #undef kcopy 325*0cb53570SAndrew Turner #undef copystr 326*0cb53570SAndrew Turner #undef copyinstr 327*0cb53570SAndrew Turner #undef copyoutstr 328*0cb53570SAndrew Turner #undef copyin 329*0cb53570SAndrew Turner #undef copyout 330*0cb53570SAndrew Turner 331*0cb53570SAndrew Turner int kcsan_kcopy(const void *, void *, size_t); 332*0cb53570SAndrew Turner int kcsan_copystr(const void *, void *, size_t, size_t *); 333*0cb53570SAndrew Turner int kcsan_copyinstr(const void *, void *, size_t, size_t *); 334*0cb53570SAndrew Turner int kcsan_copyoutstr(const void *, void *, size_t, size_t *); 335*0cb53570SAndrew Turner int kcsan_copyin(const void *, void *, size_t); 336*0cb53570SAndrew Turner int kcsan_copyout(const void *, void *, size_t); 337*0cb53570SAndrew Turner int kcopy(const void *, void *, size_t); 338*0cb53570SAndrew Turner int copystr(const void *, void *, size_t, size_t *); 339*0cb53570SAndrew Turner int copyinstr(const void *, void *, size_t, size_t *); 340*0cb53570SAndrew Turner int copyoutstr(const void *, void *, size_t, size_t *); 341*0cb53570SAndrew Turner int copyin(const void *, void *, size_t); 342*0cb53570SAndrew Turner int copyout(const void *, void *, size_t); 343*0cb53570SAndrew Turner 344*0cb53570SAndrew Turner int 345*0cb53570SAndrew Turner kcsan_kcopy(const void *src, void *dst, size_t len) 346*0cb53570SAndrew Turner { 347*0cb53570SAndrew Turner kcsan_access((uintptr_t)src, len, false, false, __RET_ADDR); 348*0cb53570SAndrew Turner kcsan_access((uintptr_t)dst, len, true, false, __RET_ADDR); 349*0cb53570SAndrew Turner return kcopy(src, dst, len); 350*0cb53570SAndrew Turner } 351*0cb53570SAndrew Turner 352*0cb53570SAndrew Turner int 353*0cb53570SAndrew Turner kcsan_copystr(const void *kfaddr, void *kdaddr, size_t len, size_t *done) 354*0cb53570SAndrew Turner { 355*0cb53570SAndrew Turner kcsan_access((uintptr_t)kdaddr, len, true, false, __RET_ADDR); 356*0cb53570SAndrew Turner return copystr(kfaddr, kdaddr, len, done); 357*0cb53570SAndrew Turner } 358*0cb53570SAndrew Turner 359*0cb53570SAndrew Turner int 360*0cb53570SAndrew Turner kcsan_copyin(const void *uaddr, void *kaddr, size_t len) 361*0cb53570SAndrew Turner { 362*0cb53570SAndrew Turner kcsan_access((uintptr_t)kaddr, len, true, false, __RET_ADDR); 363*0cb53570SAndrew Turner return copyin(uaddr, kaddr, len); 364*0cb53570SAndrew Turner } 365*0cb53570SAndrew Turner 366*0cb53570SAndrew Turner int 367*0cb53570SAndrew Turner kcsan_copyout(const void *kaddr, void *uaddr, size_t len) 368*0cb53570SAndrew Turner { 369*0cb53570SAndrew Turner kcsan_access((uintptr_t)kaddr, len, false, false, __RET_ADDR); 370*0cb53570SAndrew Turner return copyout(kaddr, uaddr, len); 371*0cb53570SAndrew Turner } 372*0cb53570SAndrew Turner 373*0cb53570SAndrew Turner int 374*0cb53570SAndrew Turner kcsan_copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) 375*0cb53570SAndrew Turner { 376*0cb53570SAndrew Turner kcsan_access((uintptr_t)kaddr, len, true, false, __RET_ADDR); 377*0cb53570SAndrew Turner return copyinstr(uaddr, kaddr, len, done); 378*0cb53570SAndrew Turner } 379*0cb53570SAndrew Turner 380*0cb53570SAndrew Turner int 381*0cb53570SAndrew Turner kcsan_copyoutstr(const void *kaddr, void *uaddr, size_t len, size_t *done) 382*0cb53570SAndrew Turner { 383*0cb53570SAndrew Turner kcsan_access((uintptr_t)kaddr, len, false, false, __RET_ADDR); 384*0cb53570SAndrew Turner return copyoutstr(kaddr, uaddr, len, done); 385*0cb53570SAndrew Turner } 386*0cb53570SAndrew Turner 387*0cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 388*0cb53570SAndrew Turner 389*0cb53570SAndrew Turner #undef atomic_add_32 390*0cb53570SAndrew Turner #undef atomic_add_int 391*0cb53570SAndrew Turner #undef atomic_add_long 392*0cb53570SAndrew Turner #undef atomic_add_ptr 393*0cb53570SAndrew Turner #undef atomic_add_64 394*0cb53570SAndrew Turner #undef atomic_add_32_nv 395*0cb53570SAndrew Turner #undef atomic_add_int_nv 396*0cb53570SAndrew Turner #undef atomic_add_long_nv 397*0cb53570SAndrew Turner #undef atomic_add_ptr_nv 398*0cb53570SAndrew Turner #undef atomic_add_64_nv 399*0cb53570SAndrew Turner #undef atomic_and_32 400*0cb53570SAndrew Turner #undef atomic_and_uint 401*0cb53570SAndrew Turner #undef atomic_and_ulong 402*0cb53570SAndrew Turner #undef atomic_and_64 403*0cb53570SAndrew Turner #undef atomic_and_32_nv 404*0cb53570SAndrew Turner #undef atomic_and_uint_nv 405*0cb53570SAndrew Turner #undef atomic_and_ulong_nv 406*0cb53570SAndrew Turner #undef atomic_and_64_nv 407*0cb53570SAndrew Turner #undef atomic_or_32 408*0cb53570SAndrew Turner #undef atomic_or_uint 409*0cb53570SAndrew Turner #undef atomic_or_ulong 410*0cb53570SAndrew Turner #undef atomic_or_64 411*0cb53570SAndrew Turner #undef atomic_or_32_nv 412*0cb53570SAndrew Turner #undef atomic_or_uint_nv 413*0cb53570SAndrew Turner #undef atomic_or_ulong_nv 414*0cb53570SAndrew Turner #undef atomic_or_64_nv 415*0cb53570SAndrew Turner #undef atomic_cas_32 416*0cb53570SAndrew Turner #undef atomic_cas_uint 417*0cb53570SAndrew Turner #undef atomic_cas_ulong 418*0cb53570SAndrew Turner #undef atomic_cas_ptr 419*0cb53570SAndrew Turner #undef atomic_cas_64 420*0cb53570SAndrew Turner #undef atomic_cas_32_ni 421*0cb53570SAndrew Turner #undef atomic_cas_uint_ni 422*0cb53570SAndrew Turner #undef atomic_cas_ulong_ni 423*0cb53570SAndrew Turner #undef atomic_cas_ptr_ni 424*0cb53570SAndrew Turner #undef atomic_cas_64_ni 425*0cb53570SAndrew Turner #undef atomic_swap_32 426*0cb53570SAndrew Turner #undef atomic_swap_uint 427*0cb53570SAndrew Turner #undef atomic_swap_ulong 428*0cb53570SAndrew Turner #undef atomic_swap_ptr 429*0cb53570SAndrew Turner #undef atomic_swap_64 430*0cb53570SAndrew Turner #undef atomic_dec_32 431*0cb53570SAndrew Turner #undef atomic_dec_uint 432*0cb53570SAndrew Turner #undef atomic_dec_ulong 433*0cb53570SAndrew Turner #undef atomic_dec_ptr 434*0cb53570SAndrew Turner #undef atomic_dec_64 435*0cb53570SAndrew Turner #undef atomic_dec_32_nv 436*0cb53570SAndrew Turner #undef atomic_dec_uint_nv 437*0cb53570SAndrew Turner #undef atomic_dec_ulong_nv 438*0cb53570SAndrew Turner #undef atomic_dec_ptr_nv 439*0cb53570SAndrew Turner #undef atomic_dec_64_nv 440*0cb53570SAndrew Turner #undef atomic_inc_32 441*0cb53570SAndrew Turner #undef atomic_inc_uint 442*0cb53570SAndrew Turner #undef atomic_inc_ulong 443*0cb53570SAndrew Turner #undef atomic_inc_ptr 444*0cb53570SAndrew Turner #undef atomic_inc_64 445*0cb53570SAndrew Turner #undef atomic_inc_32_nv 446*0cb53570SAndrew Turner #undef atomic_inc_uint_nv 447*0cb53570SAndrew Turner #undef atomic_inc_ulong_nv 448*0cb53570SAndrew Turner #undef atomic_inc_ptr_nv 449*0cb53570SAndrew Turner #undef atomic_inc_64_nv 450*0cb53570SAndrew Turner 451*0cb53570SAndrew Turner #define CSAN_ATOMIC_FUNC_ADD(name, tret, targ1, targ2) \ 452*0cb53570SAndrew Turner void atomic_add_##name(volatile targ1 *, targ2); \ 453*0cb53570SAndrew Turner void kcsan_atomic_add_##name(volatile targ1 *, targ2); \ 454*0cb53570SAndrew Turner void kcsan_atomic_add_##name(volatile targ1 *ptr, targ2 val) \ 455*0cb53570SAndrew Turner { \ 456*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 457*0cb53570SAndrew Turner __RET_ADDR); \ 458*0cb53570SAndrew Turner atomic_add_##name(ptr, val); \ 459*0cb53570SAndrew Turner } \ 460*0cb53570SAndrew Turner tret atomic_add_##name##_nv(volatile targ1 *, targ2); \ 461*0cb53570SAndrew Turner tret kcsan_atomic_add_##name##_nv(volatile targ1 *, targ2); \ 462*0cb53570SAndrew Turner tret kcsan_atomic_add_##name##_nv(volatile targ1 *ptr, targ2 val) \ 463*0cb53570SAndrew Turner { \ 464*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 465*0cb53570SAndrew Turner __RET_ADDR); \ 466*0cb53570SAndrew Turner return atomic_add_##name##_nv(ptr, val); \ 467*0cb53570SAndrew Turner } 468*0cb53570SAndrew Turner 469*0cb53570SAndrew Turner #define CSAN_ATOMIC_FUNC_AND(name, tret, targ1, targ2) \ 470*0cb53570SAndrew Turner void atomic_and_##name(volatile targ1 *, targ2); \ 471*0cb53570SAndrew Turner void kcsan_atomic_and_##name(volatile targ1 *, targ2); \ 472*0cb53570SAndrew Turner void kcsan_atomic_and_##name(volatile targ1 *ptr, targ2 val) \ 473*0cb53570SAndrew Turner { \ 474*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 475*0cb53570SAndrew Turner __RET_ADDR); \ 476*0cb53570SAndrew Turner atomic_and_##name(ptr, val); \ 477*0cb53570SAndrew Turner } \ 478*0cb53570SAndrew Turner tret atomic_and_##name##_nv(volatile targ1 *, targ2); \ 479*0cb53570SAndrew Turner tret kcsan_atomic_and_##name##_nv(volatile targ1 *, targ2); \ 480*0cb53570SAndrew Turner tret kcsan_atomic_and_##name##_nv(volatile targ1 *ptr, targ2 val) \ 481*0cb53570SAndrew Turner { \ 482*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 483*0cb53570SAndrew Turner __RET_ADDR); \ 484*0cb53570SAndrew Turner return atomic_and_##name##_nv(ptr, val); \ 485*0cb53570SAndrew Turner } 486*0cb53570SAndrew Turner 487*0cb53570SAndrew Turner #define CSAN_ATOMIC_FUNC_OR(name, tret, targ1, targ2) \ 488*0cb53570SAndrew Turner void atomic_or_##name(volatile targ1 *, targ2); \ 489*0cb53570SAndrew Turner void kcsan_atomic_or_##name(volatile targ1 *, targ2); \ 490*0cb53570SAndrew Turner void kcsan_atomic_or_##name(volatile targ1 *ptr, targ2 val) \ 491*0cb53570SAndrew Turner { \ 492*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 493*0cb53570SAndrew Turner __RET_ADDR); \ 494*0cb53570SAndrew Turner atomic_or_##name(ptr, val); \ 495*0cb53570SAndrew Turner } \ 496*0cb53570SAndrew Turner tret atomic_or_##name##_nv(volatile targ1 *, targ2); \ 497*0cb53570SAndrew Turner tret kcsan_atomic_or_##name##_nv(volatile targ1 *, targ2); \ 498*0cb53570SAndrew Turner tret kcsan_atomic_or_##name##_nv(volatile targ1 *ptr, targ2 val) \ 499*0cb53570SAndrew Turner { \ 500*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 501*0cb53570SAndrew Turner __RET_ADDR); \ 502*0cb53570SAndrew Turner return atomic_or_##name##_nv(ptr, val); \ 503*0cb53570SAndrew Turner } 504*0cb53570SAndrew Turner 505*0cb53570SAndrew Turner #define CSAN_ATOMIC_FUNC_CAS(name, tret, targ1, targ2) \ 506*0cb53570SAndrew Turner tret atomic_cas_##name(volatile targ1 *, targ2, targ2); \ 507*0cb53570SAndrew Turner tret kcsan_atomic_cas_##name(volatile targ1 *, targ2, targ2); \ 508*0cb53570SAndrew Turner tret kcsan_atomic_cas_##name(volatile targ1 *ptr, targ2 exp, targ2 new) \ 509*0cb53570SAndrew Turner { \ 510*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 511*0cb53570SAndrew Turner __RET_ADDR); \ 512*0cb53570SAndrew Turner return atomic_cas_##name(ptr, exp, new); \ 513*0cb53570SAndrew Turner } \ 514*0cb53570SAndrew Turner tret atomic_cas_##name##_ni(volatile targ1 *, targ2, targ2); \ 515*0cb53570SAndrew Turner tret kcsan_atomic_cas_##name##_ni(volatile targ1 *, targ2, targ2); \ 516*0cb53570SAndrew Turner tret kcsan_atomic_cas_##name##_ni(volatile targ1 *ptr, targ2 exp, targ2 new) \ 517*0cb53570SAndrew Turner { \ 518*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 519*0cb53570SAndrew Turner __RET_ADDR); \ 520*0cb53570SAndrew Turner return atomic_cas_##name##_ni(ptr, exp, new); \ 521*0cb53570SAndrew Turner } 522*0cb53570SAndrew Turner 523*0cb53570SAndrew Turner #define CSAN_ATOMIC_FUNC_SWAP(name, tret, targ1, targ2) \ 524*0cb53570SAndrew Turner tret atomic_swap_##name(volatile targ1 *, targ2); \ 525*0cb53570SAndrew Turner tret kcsan_atomic_swap_##name(volatile targ1 *, targ2); \ 526*0cb53570SAndrew Turner tret kcsan_atomic_swap_##name(volatile targ1 *ptr, targ2 val) \ 527*0cb53570SAndrew Turner { \ 528*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 529*0cb53570SAndrew Turner __RET_ADDR); \ 530*0cb53570SAndrew Turner return atomic_swap_##name(ptr, val); \ 531*0cb53570SAndrew Turner } 532*0cb53570SAndrew Turner 533*0cb53570SAndrew Turner #define CSAN_ATOMIC_FUNC_DEC(name, tret, targ1) \ 534*0cb53570SAndrew Turner void atomic_dec_##name(volatile targ1 *); \ 535*0cb53570SAndrew Turner void kcsan_atomic_dec_##name(volatile targ1 *); \ 536*0cb53570SAndrew Turner void kcsan_atomic_dec_##name(volatile targ1 *ptr) \ 537*0cb53570SAndrew Turner { \ 538*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 539*0cb53570SAndrew Turner __RET_ADDR); \ 540*0cb53570SAndrew Turner atomic_dec_##name(ptr); \ 541*0cb53570SAndrew Turner } \ 542*0cb53570SAndrew Turner tret atomic_dec_##name##_nv(volatile targ1 *); \ 543*0cb53570SAndrew Turner tret kcsan_atomic_dec_##name##_nv(volatile targ1 *); \ 544*0cb53570SAndrew Turner tret kcsan_atomic_dec_##name##_nv(volatile targ1 *ptr) \ 545*0cb53570SAndrew Turner { \ 546*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 547*0cb53570SAndrew Turner __RET_ADDR); \ 548*0cb53570SAndrew Turner return atomic_dec_##name##_nv(ptr); \ 549*0cb53570SAndrew Turner } 550*0cb53570SAndrew Turner 551*0cb53570SAndrew Turner #define CSAN_ATOMIC_FUNC_INC(name, tret, targ1) \ 552*0cb53570SAndrew Turner void atomic_inc_##name(volatile targ1 *); \ 553*0cb53570SAndrew Turner void kcsan_atomic_inc_##name(volatile targ1 *); \ 554*0cb53570SAndrew Turner void kcsan_atomic_inc_##name(volatile targ1 *ptr) \ 555*0cb53570SAndrew Turner { \ 556*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 557*0cb53570SAndrew Turner __RET_ADDR); \ 558*0cb53570SAndrew Turner atomic_inc_##name(ptr); \ 559*0cb53570SAndrew Turner } \ 560*0cb53570SAndrew Turner tret atomic_inc_##name##_nv(volatile targ1 *); \ 561*0cb53570SAndrew Turner tret kcsan_atomic_inc_##name##_nv(volatile targ1 *); \ 562*0cb53570SAndrew Turner tret kcsan_atomic_inc_##name##_nv(volatile targ1 *ptr) \ 563*0cb53570SAndrew Turner { \ 564*0cb53570SAndrew Turner kcsan_access((uintptr_t)ptr, sizeof(tret), true, true, \ 565*0cb53570SAndrew Turner __RET_ADDR); \ 566*0cb53570SAndrew Turner return atomic_inc_##name##_nv(ptr); \ 567*0cb53570SAndrew Turner } 568*0cb53570SAndrew Turner 569*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_ADD(32, uint32_t, uint32_t, int32_t); 570*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_ADD(64, uint64_t, uint64_t, int64_t); 571*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_ADD(int, unsigned int, unsigned int, int); 572*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_ADD(long, unsigned long, unsigned long, long); 573*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_ADD(ptr, void *, void, ssize_t); 574*0cb53570SAndrew Turner 575*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_AND(32, uint32_t, uint32_t, uint32_t); 576*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_AND(64, uint64_t, uint64_t, uint64_t); 577*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_AND(uint, unsigned int, unsigned int, unsigned int); 578*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_AND(ulong, unsigned long, unsigned long, unsigned long); 579*0cb53570SAndrew Turner 580*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_OR(32, uint32_t, uint32_t, uint32_t); 581*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_OR(64, uint64_t, uint64_t, uint64_t); 582*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_OR(uint, unsigned int, unsigned int, unsigned int); 583*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_OR(ulong, unsigned long, unsigned long, unsigned long); 584*0cb53570SAndrew Turner 585*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_CAS(32, uint32_t, uint32_t, uint32_t); 586*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_CAS(64, uint64_t, uint64_t, uint64_t); 587*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_CAS(uint, unsigned int, unsigned int, unsigned int); 588*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_CAS(ulong, unsigned long, unsigned long, unsigned long); 589*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_CAS(ptr, void *, void, void *); 590*0cb53570SAndrew Turner 591*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(32, uint32_t, uint32_t, uint32_t); 592*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(64, uint64_t, uint64_t, uint64_t); 593*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(uint, unsigned int, unsigned int, unsigned int); 594*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(ulong, unsigned long, unsigned long, unsigned long); 595*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_SWAP(ptr, void *, void, void *); 596*0cb53570SAndrew Turner 597*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_DEC(32, uint32_t, uint32_t) 598*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_DEC(64, uint64_t, uint64_t) 599*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_DEC(uint, unsigned int, unsigned int); 600*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_DEC(ulong, unsigned long, unsigned long); 601*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_DEC(ptr, void *, void); 602*0cb53570SAndrew Turner 603*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_INC(32, uint32_t, uint32_t) 604*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_INC(64, uint64_t, uint64_t) 605*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_INC(uint, unsigned int, unsigned int); 606*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_INC(ulong, unsigned long, unsigned long); 607*0cb53570SAndrew Turner CSAN_ATOMIC_FUNC_INC(ptr, void *, void); 608*0cb53570SAndrew Turner 609*0cb53570SAndrew Turner /* -------------------------------------------------------------------------- */ 610*0cb53570SAndrew Turner 611*0cb53570SAndrew Turner #include <sys/bus.h> 612*0cb53570SAndrew Turner 613*0cb53570SAndrew Turner #undef bus_space_read_multi_1 614*0cb53570SAndrew Turner #undef bus_space_read_multi_2 615*0cb53570SAndrew Turner #undef bus_space_read_multi_4 616*0cb53570SAndrew Turner #undef bus_space_read_multi_8 617*0cb53570SAndrew Turner #undef bus_space_read_multi_stream_1 618*0cb53570SAndrew Turner #undef bus_space_read_multi_stream_2 619*0cb53570SAndrew Turner #undef bus_space_read_multi_stream_4 620*0cb53570SAndrew Turner #undef bus_space_read_multi_stream_8 621*0cb53570SAndrew Turner #undef bus_space_read_region_1 622*0cb53570SAndrew Turner #undef bus_space_read_region_2 623*0cb53570SAndrew Turner #undef bus_space_read_region_4 624*0cb53570SAndrew Turner #undef bus_space_read_region_8 625*0cb53570SAndrew Turner #undef bus_space_read_region_stream_1 626*0cb53570SAndrew Turner #undef bus_space_read_region_stream_2 627*0cb53570SAndrew Turner #undef bus_space_read_region_stream_4 628*0cb53570SAndrew Turner #undef bus_space_read_region_stream_8 629*0cb53570SAndrew Turner #undef bus_space_write_multi_1 630*0cb53570SAndrew Turner #undef bus_space_write_multi_2 631*0cb53570SAndrew Turner #undef bus_space_write_multi_4 632*0cb53570SAndrew Turner #undef bus_space_write_multi_8 633*0cb53570SAndrew Turner #undef bus_space_write_multi_stream_1 634*0cb53570SAndrew Turner #undef bus_space_write_multi_stream_2 635*0cb53570SAndrew Turner #undef bus_space_write_multi_stream_4 636*0cb53570SAndrew Turner #undef bus_space_write_multi_stream_8 637*0cb53570SAndrew Turner #undef bus_space_write_region_1 638*0cb53570SAndrew Turner #undef bus_space_write_region_2 639*0cb53570SAndrew Turner #undef bus_space_write_region_4 640*0cb53570SAndrew Turner #undef bus_space_write_region_8 641*0cb53570SAndrew Turner #undef bus_space_write_region_stream_1 642*0cb53570SAndrew Turner #undef bus_space_write_region_stream_2 643*0cb53570SAndrew Turner #undef bus_space_write_region_stream_4 644*0cb53570SAndrew Turner #undef bus_space_write_region_stream_8 645*0cb53570SAndrew Turner 646*0cb53570SAndrew Turner #define CSAN_BUS_READ_FUNC(bytes, bits) \ 647*0cb53570SAndrew Turner void bus_space_read_multi_##bytes(bus_space_tag_t, bus_space_handle_t, \ 648*0cb53570SAndrew Turner bus_size_t, uint##bits##_t *, bus_size_t); \ 649*0cb53570SAndrew Turner void kcsan_bus_space_read_multi_##bytes(bus_space_tag_t, \ 650*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 651*0cb53570SAndrew Turner void kcsan_bus_space_read_multi_##bytes(bus_space_tag_t tag, \ 652*0cb53570SAndrew Turner bus_space_handle_t hnd, bus_size_t size, uint##bits##_t *buf, \ 653*0cb53570SAndrew Turner bus_size_t count) \ 654*0cb53570SAndrew Turner { \ 655*0cb53570SAndrew Turner kcsan_access((uintptr_t)buf, sizeof(uint##bits##_t) * count, \ 656*0cb53570SAndrew Turner false, false, __RET_ADDR); \ 657*0cb53570SAndrew Turner bus_space_read_multi_##bytes(tag, hnd, size, buf, count); \ 658*0cb53570SAndrew Turner } \ 659*0cb53570SAndrew Turner void bus_space_read_multi_stream_##bytes(bus_space_tag_t, \ 660*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 661*0cb53570SAndrew Turner void kcsan_bus_space_read_multi_stream_##bytes(bus_space_tag_t, \ 662*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 663*0cb53570SAndrew Turner void kcsan_bus_space_read_multi_stream_##bytes(bus_space_tag_t tag, \ 664*0cb53570SAndrew Turner bus_space_handle_t hnd, bus_size_t size, uint##bits##_t *buf, \ 665*0cb53570SAndrew Turner bus_size_t count) \ 666*0cb53570SAndrew Turner { \ 667*0cb53570SAndrew Turner kcsan_access((uintptr_t)buf, sizeof(uint##bits##_t) * count, \ 668*0cb53570SAndrew Turner false, false, __RET_ADDR); \ 669*0cb53570SAndrew Turner bus_space_read_multi_stream_##bytes(tag, hnd, size, buf, count);\ 670*0cb53570SAndrew Turner } \ 671*0cb53570SAndrew Turner void bus_space_read_region_##bytes(bus_space_tag_t, bus_space_handle_t, \ 672*0cb53570SAndrew Turner bus_size_t, uint##bits##_t *, bus_size_t); \ 673*0cb53570SAndrew Turner void kcsan_bus_space_read_region_##bytes(bus_space_tag_t, \ 674*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 675*0cb53570SAndrew Turner void kcsan_bus_space_read_region_##bytes(bus_space_tag_t tag, \ 676*0cb53570SAndrew Turner bus_space_handle_t hnd, bus_size_t size, uint##bits##_t *buf, \ 677*0cb53570SAndrew Turner bus_size_t count) \ 678*0cb53570SAndrew Turner { \ 679*0cb53570SAndrew Turner kcsan_access((uintptr_t)buf, sizeof(uint##bits##_t) * count, \ 680*0cb53570SAndrew Turner false, false, __RET_ADDR); \ 681*0cb53570SAndrew Turner bus_space_read_region_##bytes(tag, hnd, size, buf, count); \ 682*0cb53570SAndrew Turner } \ 683*0cb53570SAndrew Turner void bus_space_read_region_stream_##bytes(bus_space_tag_t, \ 684*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 685*0cb53570SAndrew Turner void kcsan_bus_space_read_region_stream_##bytes(bus_space_tag_t, \ 686*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, uint##bits##_t *, bus_size_t); \ 687*0cb53570SAndrew Turner void kcsan_bus_space_read_region_stream_##bytes(bus_space_tag_t tag, \ 688*0cb53570SAndrew Turner bus_space_handle_t hnd, bus_size_t size, uint##bits##_t *buf, \ 689*0cb53570SAndrew Turner bus_size_t count) \ 690*0cb53570SAndrew Turner { \ 691*0cb53570SAndrew Turner kcsan_access((uintptr_t)buf, sizeof(uint##bits##_t) * count, \ 692*0cb53570SAndrew Turner false, false, __RET_ADDR); \ 693*0cb53570SAndrew Turner bus_space_read_region_stream_##bytes(tag, hnd, size, buf, count);\ 694*0cb53570SAndrew Turner } 695*0cb53570SAndrew Turner 696*0cb53570SAndrew Turner #define CSAN_BUS_WRITE_FUNC(bytes, bits) \ 697*0cb53570SAndrew Turner void bus_space_write_multi_##bytes(bus_space_tag_t, bus_space_handle_t, \ 698*0cb53570SAndrew Turner bus_size_t, const uint##bits##_t *, bus_size_t); \ 699*0cb53570SAndrew Turner void kcsan_bus_space_write_multi_##bytes(bus_space_tag_t, \ 700*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 701*0cb53570SAndrew Turner void kcsan_bus_space_write_multi_##bytes(bus_space_tag_t tag, \ 702*0cb53570SAndrew Turner bus_space_handle_t hnd, bus_size_t size, const uint##bits##_t *buf, \ 703*0cb53570SAndrew Turner bus_size_t count) \ 704*0cb53570SAndrew Turner { \ 705*0cb53570SAndrew Turner kcsan_access((uintptr_t)buf, sizeof(uint##bits##_t) * count, \ 706*0cb53570SAndrew Turner true, false, __RET_ADDR); \ 707*0cb53570SAndrew Turner bus_space_write_multi_##bytes(tag, hnd, size, buf, count); \ 708*0cb53570SAndrew Turner } \ 709*0cb53570SAndrew Turner void bus_space_write_multi_stream_##bytes(bus_space_tag_t, \ 710*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 711*0cb53570SAndrew Turner void kcsan_bus_space_write_multi_stream_##bytes(bus_space_tag_t, \ 712*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 713*0cb53570SAndrew Turner void kcsan_bus_space_write_multi_stream_##bytes(bus_space_tag_t tag, \ 714*0cb53570SAndrew Turner bus_space_handle_t hnd, bus_size_t size, const uint##bits##_t *buf, \ 715*0cb53570SAndrew Turner bus_size_t count) \ 716*0cb53570SAndrew Turner { \ 717*0cb53570SAndrew Turner kcsan_access((uintptr_t)buf, sizeof(uint##bits##_t) * count, \ 718*0cb53570SAndrew Turner true, false, __RET_ADDR); \ 719*0cb53570SAndrew Turner bus_space_write_multi_stream_##bytes(tag, hnd, size, buf, count);\ 720*0cb53570SAndrew Turner } \ 721*0cb53570SAndrew Turner void bus_space_write_region_##bytes(bus_space_tag_t, bus_space_handle_t,\ 722*0cb53570SAndrew Turner bus_size_t, const uint##bits##_t *, bus_size_t); \ 723*0cb53570SAndrew Turner void kcsan_bus_space_write_region_##bytes(bus_space_tag_t, \ 724*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 725*0cb53570SAndrew Turner void kcsan_bus_space_write_region_##bytes(bus_space_tag_t tag, \ 726*0cb53570SAndrew Turner bus_space_handle_t hnd, bus_size_t size, const uint##bits##_t *buf, \ 727*0cb53570SAndrew Turner bus_size_t count) \ 728*0cb53570SAndrew Turner { \ 729*0cb53570SAndrew Turner kcsan_access((uintptr_t)buf, sizeof(uint##bits##_t) * count, \ 730*0cb53570SAndrew Turner true, false, __RET_ADDR); \ 731*0cb53570SAndrew Turner bus_space_write_region_##bytes(tag, hnd, size, buf, count); \ 732*0cb53570SAndrew Turner } \ 733*0cb53570SAndrew Turner void bus_space_write_region_stream_##bytes(bus_space_tag_t, \ 734*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 735*0cb53570SAndrew Turner void kcsan_bus_space_write_region_stream_##bytes(bus_space_tag_t, \ 736*0cb53570SAndrew Turner bus_space_handle_t, bus_size_t, const uint##bits##_t *, bus_size_t);\ 737*0cb53570SAndrew Turner void kcsan_bus_space_write_region_stream_##bytes(bus_space_tag_t tag, \ 738*0cb53570SAndrew Turner bus_space_handle_t hnd, bus_size_t size, const uint##bits##_t *buf, \ 739*0cb53570SAndrew Turner bus_size_t count) \ 740*0cb53570SAndrew Turner { \ 741*0cb53570SAndrew Turner kcsan_access((uintptr_t)buf, sizeof(uint##bits##_t) * count, \ 742*0cb53570SAndrew Turner true, false, __RET_ADDR); \ 743*0cb53570SAndrew Turner bus_space_write_region_stream_##bytes(tag, hnd, size, buf, count);\ 744*0cb53570SAndrew Turner } 745*0cb53570SAndrew Turner 746*0cb53570SAndrew Turner CSAN_BUS_READ_FUNC(1, 8) 747*0cb53570SAndrew Turner CSAN_BUS_READ_FUNC(2, 16) 748*0cb53570SAndrew Turner CSAN_BUS_READ_FUNC(4, 32) 749*0cb53570SAndrew Turner CSAN_BUS_READ_FUNC(8, 64) 750*0cb53570SAndrew Turner 751*0cb53570SAndrew Turner CSAN_BUS_WRITE_FUNC(1, 8) 752*0cb53570SAndrew Turner CSAN_BUS_WRITE_FUNC(2, 16) 753*0cb53570SAndrew Turner CSAN_BUS_WRITE_FUNC(4, 32) 754*0cb53570SAndrew Turner CSAN_BUS_WRITE_FUNC(8, 64) 755