Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp5081162ybg; Mon, 21 Oct 2019 20:32:29 -0700 (PDT) X-Google-Smtp-Source: APXvYqyTFyVoXlb7+Fq3PfL8rYlQAiVWuK68eZab+9jrzo6yoS3QIUy+DogYYB1CNofu10s30J2y X-Received: by 2002:a05:6402:290:: with SMTP id l16mr895413edv.190.1571715149036; Mon, 21 Oct 2019 20:32:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571715149; cv=none; d=google.com; s=arc-20160816; b=gPXIgL/mMzrYqF2Pk+jqV35QrviAyBylKfyONisGQ3RlSaJ24FUpHkX58B6sDti9+y /Lx0AAOygS2Z8M+5YTN4JbeK+4XWFWdJE52GCkl855Q3PLeEbuymO3GvQeikAwG83uhY IG314tzoECb7sfcDhTBpGpDV/6M5FNqPG78d8qcgV+CMbeDSuoxAkPDzbjk3IdZbXapL QYGtnT0cnhzp7Yo6b+iNRQswNox5MryrQT0S69hpNV2Hi/kEnP9vUhAVpOgPgRvW9gaD DglHvh2uZ0/NDHiUa5JajYG/wKqZ6X3UD2CeUzY4YEX52a3ge6gdwjYEaTXmc7yDbe2V vHNw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-transfer-encoding:content-disposition:mime-version :references:message-id:subject:cc:to:from:date; bh=69XEKp27c61OT7Lg41c962iGrCFu3j35e92znfdIaxg=; b=gtvHdMo22KMUNgXbRIXWVCufSg9CCMphMAHaTXO/7LoasL0GMpq3Me1ILF7cbqjrph 61BZjNjchchkdHRrNs9gxZCgg10POOe/n3e8qyLlBK20B7Q9Z7+U4ZqOcdYtTlK/5Z8m OKErG3FJ7nNrsMKIBPsjsBzMX3q2RlEWVx5dFoU9qzGdd/c+7rvW02mqVA6pGMfpY9eq ymHW8tcmYukBCj1SxMPVBM93xKtIGCUXC0l5nZo0QuyMs+C1YYpyMwSSpRFceXaHk7G/ VA6LygeDaWvql33X2ng8qDEpJdwsVEdeX9QeBHYSm60GYBTYX/NjXHxdiSmN0aaf7biC WwQw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k50si2554252ede.224.2019.10.21.20.32.03; Mon, 21 Oct 2019 20:32:29 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387489AbfJVDcA (ORCPT + 99 others); Mon, 21 Oct 2019 23:32:00 -0400 Received: from 59-120-53-16.HINET-IP.hinet.net ([59.120.53.16]:31949 "EHLO ATCSQR.andestech.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730370AbfJVDcA (ORCPT ); Mon, 21 Oct 2019 23:32:00 -0400 Received: from mail.andestech.com (atcpcs16.andestech.com [10.0.1.222]) by ATCSQR.andestech.com with ESMTP id x9M3DoXs081015; Tue, 22 Oct 2019 11:13:50 +0800 (GMT-8) (envelope-from nickhu@andestech.com) Received: from andestech.com (10.0.15.65) by ATCPCS16.andestech.com (10.0.1.222) with Microsoft SMTP Server id 14.3.123.3; Tue, 22 Oct 2019 11:30:51 +0800 Date: Tue, 22 Oct 2019 11:30:51 +0800 From: Nick Hu To: Greentime Hu CC: Greentime Hu , Alan Quey-Liang =?utf-8?B?S2FvKOmrmOmtgeiJryk=?= , Paul Walmsley , Palmer Dabbelt , Albert Ou , "aryabinin@virtuozzo.com" , "glider@google.com" , "dvyukov@google.com" , "corbet@lwn.net" , "alexios.zavras@intel.com" , "allison@lohutok.net" , "Anup.Patel@wdc.com" , "Thomas Gleixner" , "gregkh@linuxfoundation.org" , "atish.patra@wdc.com" , Kate Stewart , "linux-doc@vger.kernel.org" , "linux-riscv@lists.infradead.org" , Linux Kernel Mailing List , "kasan-dev@googlegroups.com" , "linux-mm@kvack.org" Subject: Re: [PATCH v3 2/3] riscv: Add KASAN support Message-ID: <20191022033051.GB29285@andestech.com> References: <8d86d53e904bece0623cb8969cdc70f782fa2bae.1570514544.git.nickhu@andestech.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) X-Originating-IP: [10.0.15.65] X-DNSRBL: X-MAIL: ATCSQR.andestech.com x9M3DoXs081015 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Oct 21, 2019 at 05:33:31PM +0800, Greentime Hu wrote: > Nick Hu 於 2019年10月8日 週二 下午2:17寫道: > > > > This patch ports the feature Kernel Address SANitizer (KASAN). > > > > Note: The start address of shadow memory is at the beginning of kernel > > space, which is 2^64 - (2^39 / 2) in SV39. The size of the kernel space is > > 2^38 bytes so the size of shadow memory should be 2^38 / 8. Thus, the > > shadow memory would not overlap with the fixmap area. > > > > There are currently two limitations in this port, > > > > 1. RV64 only: KASAN need large address space for extra shadow memory > > region. > > > > 2. KASAN can't debug the modules since the modules are allocated in VMALLOC > > area. We mapped the shadow memory, which corresponding to VMALLOC area, to > > the kasan_early_shadow_page because we don't have enough physical space for > > all the shadow memory corresponding to VMALLOC area. > > > > Signed-off-by: Nick Hu > > --- > > arch/riscv/Kconfig | 1 + > > arch/riscv/include/asm/kasan.h | 27 ++++++++ > > arch/riscv/include/asm/pgtable-64.h | 5 ++ > > arch/riscv/include/asm/string.h | 9 +++ > > arch/riscv/kernel/head.S | 3 + > > arch/riscv/kernel/riscv_ksyms.c | 2 + > > arch/riscv/kernel/setup.c | 5 ++ > > arch/riscv/kernel/vmlinux.lds.S | 1 + > > arch/riscv/lib/memcpy.S | 5 +- > > arch/riscv/lib/memset.S | 5 +- > > arch/riscv/mm/Makefile | 6 ++ > > arch/riscv/mm/kasan_init.c | 104 ++++++++++++++++++++++++++++ > > 12 files changed, 169 insertions(+), 4 deletions(-) > > create mode 100644 arch/riscv/include/asm/kasan.h > > create mode 100644 arch/riscv/mm/kasan_init.c > > > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > > index 8eebbc8860bb..ca2fc8ba8550 100644 > > --- a/arch/riscv/Kconfig > > +++ b/arch/riscv/Kconfig > > @@ -61,6 +61,7 @@ config RISCV > > select SPARSEMEM_STATIC if 32BIT > > select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU > > select HAVE_ARCH_MMAP_RND_BITS > > + select HAVE_ARCH_KASAN if MMU && 64BIT > > > > config ARCH_MMAP_RND_BITS_MIN > > default 18 if 64BIT > > diff --git a/arch/riscv/include/asm/kasan.h b/arch/riscv/include/asm/kasan.h > > new file mode 100644 > > index 000000000000..eb9b1a2f641c > > --- /dev/null > > +++ b/arch/riscv/include/asm/kasan.h > > @@ -0,0 +1,27 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* Copyright (C) 2019 Andes Technology Corporation */ > > + > > +#ifndef __ASM_KASAN_H > > +#define __ASM_KASAN_H > > + > > +#ifndef __ASSEMBLY__ > > + > > +#ifdef CONFIG_KASAN > > + > > +#include > > + > > +#define KASAN_SHADOW_SCALE_SHIFT 3 > > + > > +#define KASAN_SHADOW_SIZE (UL(1) << (38 - KASAN_SHADOW_SCALE_SHIFT)) > > +#define KASAN_SHADOW_START 0xffffffc000000000 // 2^64 - 2^38 > > +#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE) > > + > > +#define KASAN_SHADOW_OFFSET (KASAN_SHADOW_END - (1ULL << \ > > + (64 - KASAN_SHADOW_SCALE_SHIFT))) > > + > > +void kasan_init(void); > > +asmlinkage void kasan_early_init(void); > > + > > +#endif > > +#endif > > +#endif /* __ASM_KASAN_H */ > > diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h > > index 7df8daa66cc8..777a1dddb3df 100644 > > --- a/arch/riscv/include/asm/pgtable-64.h > > +++ b/arch/riscv/include/asm/pgtable-64.h > > @@ -59,6 +59,11 @@ static inline unsigned long pud_page_vaddr(pud_t pud) > > return (unsigned long)pfn_to_virt(pud_val(pud) >> _PAGE_PFN_SHIFT); > > } > > > > +static inline struct page *pud_page(pud_t pud) > > +{ > > + return pfn_to_page(pud_val(pud) >> _PAGE_PFN_SHIFT); > > +} > > + > > #define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) > > > > static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) > > diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h > > index 1b5d44585962..a4451f768826 100644 > > --- a/arch/riscv/include/asm/string.h > > +++ b/arch/riscv/include/asm/string.h > > @@ -11,8 +11,17 @@ > > > > #define __HAVE_ARCH_MEMSET > > extern asmlinkage void *memset(void *, int, size_t); > > +extern asmlinkage void *__memset(void *, int, size_t); > > > > #define __HAVE_ARCH_MEMCPY > > extern asmlinkage void *memcpy(void *, const void *, size_t); > > +extern asmlinkage void *__memcpy(void *, const void *, size_t); > > > > +// For those files which don't want to check by kasan. > > +#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) > > + > > +#define memcpy(dst, src, len) __memcpy(dst, src, len) > > +#define memset(s, c, n) __memset(s, c, n) > > + > > +#endif > > #endif /* _ASM_RISCV_STRING_H */ > > diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S > > index 72f89b7590dd..95eca23cd811 100644 > > --- a/arch/riscv/kernel/head.S > > +++ b/arch/riscv/kernel/head.S > > @@ -102,6 +102,9 @@ clear_bss_done: > > sw zero, TASK_TI_CPU(tp) > > la sp, init_thread_union + THREAD_SIZE > > > > +#ifdef CONFIG_KASAN > > + call kasan_early_init > > +#endif > > /* Start the kernel */ > > call parse_dtb > > tail start_kernel > > diff --git a/arch/riscv/kernel/riscv_ksyms.c b/arch/riscv/kernel/riscv_ksyms.c > > index 4800cf703186..376bba7f65ce 100644 > > --- a/arch/riscv/kernel/riscv_ksyms.c > > +++ b/arch/riscv/kernel/riscv_ksyms.c > > @@ -14,3 +14,5 @@ EXPORT_SYMBOL(__asm_copy_to_user); > > EXPORT_SYMBOL(__asm_copy_from_user); > > EXPORT_SYMBOL(memset); > > EXPORT_SYMBOL(memcpy); > > +EXPORT_SYMBOL(__memset); > > +EXPORT_SYMBOL(__memcpy); > > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c > > index a990a6cb184f..41f7eae9bc4d 100644 > > --- a/arch/riscv/kernel/setup.c > > +++ b/arch/riscv/kernel/setup.c > > @@ -23,6 +23,7 @@ > > #include > > #include > > #include > > +#include > > > > #ifdef CONFIG_DUMMY_CONSOLE > > struct screen_info screen_info = { > > @@ -70,6 +71,10 @@ void __init setup_arch(char **cmdline_p) > > swiotlb_init(1); > > #endif > > > > +#ifdef CONFIG_KASAN > > + kasan_init(); > > +#endif > > + > > #ifdef CONFIG_SMP > > setup_smp(); > > #endif > > diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S > > index 23cd1a9e52a1..97009803ba9f 100644 > > --- a/arch/riscv/kernel/vmlinux.lds.S > > +++ b/arch/riscv/kernel/vmlinux.lds.S > > @@ -46,6 +46,7 @@ SECTIONS > > KPROBES_TEXT > > ENTRY_TEXT > > IRQENTRY_TEXT > > + SOFTIRQENTRY_TEXT > > *(.fixup) > > _etext = .; > > } > > diff --git a/arch/riscv/lib/memcpy.S b/arch/riscv/lib/memcpy.S > > index b4c477846e91..51ab716253fa 100644 > > --- a/arch/riscv/lib/memcpy.S > > +++ b/arch/riscv/lib/memcpy.S > > @@ -7,7 +7,8 @@ > > #include > > > > /* void *memcpy(void *, const void *, size_t) */ > > -ENTRY(memcpy) > > +ENTRY(__memcpy) > > +WEAK(memcpy) > > move t6, a0 /* Preserve return value */ > > > > /* Defer to byte-oriented copy for small sizes */ > > @@ -104,4 +105,4 @@ ENTRY(memcpy) > > bltu a1, a3, 5b > > 6: > > ret > > -END(memcpy) > > +END(__memcpy) > > diff --git a/arch/riscv/lib/memset.S b/arch/riscv/lib/memset.S > > index 5a7386b47175..34c5360c6705 100644 > > --- a/arch/riscv/lib/memset.S > > +++ b/arch/riscv/lib/memset.S > > @@ -8,7 +8,8 @@ > > #include > > > > /* void *memset(void *, int, size_t) */ > > -ENTRY(memset) > > +ENTRY(__memset) > > +WEAK(memset) > > move t0, a0 /* Preserve return value */ > > > > /* Defer to byte-oriented fill for small sizes */ > > @@ -109,4 +110,4 @@ ENTRY(memset) > > bltu t0, a3, 5b > > 6: > > ret > > -END(memset) > > +END(__memset) > > diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile > > index 9d9a17335686..b8a8ca71f86e 100644 > > --- a/arch/riscv/mm/Makefile > > +++ b/arch/riscv/mm/Makefile > > @@ -17,3 +17,9 @@ ifeq ($(CONFIG_MMU),y) > > obj-$(CONFIG_SMP) += tlbflush.o > > endif > > obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o > > +obj-$(CONFIG_KASAN) += kasan_init.o > > + > > +ifdef CONFIG_KASAN > > +KASAN_SANITIZE_kasan_init.o := n > > +KASAN_SANITIZE_init.o := n > > +endif > > diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c > > new file mode 100644 > > index 000000000000..c3152768cdbe > > --- /dev/null > > +++ b/arch/riscv/mm/kasan_init.c > > @@ -0,0 +1,104 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +// Copyright (C) 2019 Andes Technology Corporation > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +extern pgd_t early_pg_dir[PTRS_PER_PGD]; > > +asmlinkage void __init kasan_early_init(void) > > +{ > > + uintptr_t i; > > + pgd_t *pgd = early_pg_dir + pgd_index(KASAN_SHADOW_START); > > + > > + for (i = 0; i < PTRS_PER_PTE; ++i) > > + set_pte(kasan_early_shadow_pte + i, > > + mk_pte(virt_to_page(kasan_early_shadow_page), > > + PAGE_KERNEL)); > > + > > + for (i = 0; i < PTRS_PER_PMD; ++i) > > + set_pmd(kasan_early_shadow_pmd + i, > > + pfn_pmd(PFN_DOWN(__pa((uintptr_t)kasan_early_shadow_pte)), > > + __pgprot(_PAGE_TABLE))); > > + > > + for (i = KASAN_SHADOW_START; i < KASAN_SHADOW_END; > > + i += PGDIR_SIZE, ++pgd) > > + set_pgd(pgd, > > + pfn_pgd(PFN_DOWN(__pa(((uintptr_t)kasan_early_shadow_pmd))), > > + __pgprot(_PAGE_TABLE))); > > + > > + // init for swapper_pg_dir > > + pgd = pgd_offset_k(KASAN_SHADOW_START); > > + > > + for (i = KASAN_SHADOW_START; i < KASAN_SHADOW_END; > > + i += PGDIR_SIZE, ++pgd) > > + set_pgd(pgd, > > + pfn_pgd(PFN_DOWN(__pa(((uintptr_t)kasan_early_shadow_pmd))), > > + __pgprot(_PAGE_TABLE))); > > + > > + flush_tlb_all(); > > +} > > + > > +static void __init populate(void *start, void *end) > > +{ > > + unsigned long i; > > + unsigned long vaddr = (unsigned long)start & PAGE_MASK; > > + unsigned long vend = PAGE_ALIGN((unsigned long)end); > > + unsigned long n_pages = (vend - vaddr) / PAGE_SIZE; > > + unsigned long n_pmds = > > + (n_pages % PTRS_PER_PTE) ? n_pages / PTRS_PER_PTE + 1 : > > + n_pages / PTRS_PER_PTE; > > + pgd_t *pgd = pgd_offset_k(vaddr); > > + pmd_t *pmd = memblock_alloc(n_pmds * sizeof(pmd_t), PAGE_SIZE); > > + pte_t *pte = memblock_alloc(n_pages * sizeof(pte_t), PAGE_SIZE); > > + > > + for (i = 0; i < n_pages; i++) { > > + phys_addr_t phys = memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); > > + > > + set_pte(pte + i, pfn_pte(PHYS_PFN(phys), PAGE_KERNEL)); > > + } > > + > > + for (i = 0; i < n_pages; ++pmd, i += PTRS_PER_PTE) > > + set_pmd(pmd, pfn_pmd(PFN_DOWN(__pa((uintptr_t)(pte + i))), > > + __pgprot(_PAGE_TABLE))); > > + > > + for (i = vaddr; i < vend; i += PGDIR_SIZE, ++pgd) > > + set_pgd(pgd, pfn_pgd(PFN_DOWN(__pa(((uintptr_t)pmd))), > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > + __pgprot(_PAGE_TABLE))); > > + > > Hi Nick, > > I verify this patch in Qemu and Unleashed board. > I found it works well if DRAM size is less than 4GB. > It will get an access fault if the DRAM size is larger than 4GB. > > I spend some time to debug this case and I found it hang in the > following memset(). > It is because the mapping is not created correctly. I check the page > table creating logic again and I found it always sets the last pmd > here. Hi Greentime, Thanks! I would fix it in v4 patch. Nick.