Module Name: src Committed By: maxv Date: Sat Aug 1 06:35:00 UTC 2020
Modified Files: src/sys/arch/aarch64/include: asan.h Log Message: Use large pages for the KASAN shadow, same as amd64, discussed with ryo@. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/sys/arch/aarch64/include/asan.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/aarch64/include/asan.h diff -u src/sys/arch/aarch64/include/asan.h:1.8 src/sys/arch/aarch64/include/asan.h:1.9 --- src/sys/arch/aarch64/include/asan.h:1.8 Thu Jul 16 11:36:35 2020 +++ src/sys/arch/aarch64/include/asan.h Sat Aug 1 06:35:00 2020 @@ -1,7 +1,7 @@ -/* $NetBSD: asan.h,v 1.8 2020/07/16 11:36:35 skrll Exp $ */ +/* $NetBSD: asan.h,v 1.9 2020/08/01 06:35:00 maxv Exp $ */ /* - * Copyright (c) 2018 The NetBSD Foundation, Inc. + * Copyright (c) 2018-2020 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -72,9 +72,28 @@ __md_palloc(void) else pa = pmap_alloc_pdp(pmap_kernel(), NULL, 0, false); + /* The page is zeroed. */ return pa; } +static inline paddr_t +__md_palloc_large(void) +{ + struct pglist pglist; + int ret; + + if (!uvm.page_init_done) + return 0; + + ret = uvm_pglistalloc(L2_SIZE, 0, ~0UL, L2_SIZE, 0, + &pglist, 1, 0); + if (ret != 0) + return 0; + + /* The page may not be zeroed. */ + return VM_PAGE_TO_PHYS(TAILQ_FIRST(&pglist)); +} + static void kasan_md_shadow_map_page(vaddr_t va) { @@ -121,8 +140,20 @@ kasan_md_shadow_map_page(vaddr_t va) idx = l2pde_index(va); pde = l2[idx]; if (!l2pde_valid(pde)) { + /* If possible, use L2_BLOCK to map it in advance. */ + if ((pa = __md_palloc_large()) != 0) { + atomic_swap_64(&l2[idx], pa | L2_BLOCK | + LX_BLKPAG_UXN | LX_BLKPAG_PXN | LX_BLKPAG_AF | + LX_BLKPAG_SH_IS | LX_BLKPAG_AP_RW); + aarch64_tlbi_by_va(va); + __builtin_memset((void *)va, 0, L2_SIZE); + return; + } pa = __md_palloc(); atomic_swap_64(&l2[idx], pa | L2_TABLE); + } else if (l2pde_is_block(pde)) { + /* This VA is already mapped as a block. */ + return; } else { pa = l2pde_pa(pde); }