From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1C40C001DE for ; Tue, 25 Jul 2023 14:35:12 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 6A7A06B0074; Tue, 25 Jul 2023 10:35:12 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 657DD6B0075; Tue, 25 Jul 2023 10:35:12 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 4F7E66B0078; Tue, 25 Jul 2023 10:35:12 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 3F8196B0074 for ; Tue, 25 Jul 2023 10:35:12 -0400 (EDT) Received: from smtpin24.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id 0F043140C24 for ; Tue, 25 Jul 2023 14:35:12 +0000 (UTC) X-FDA: 81050381664.24.2C2CCCD Received: from out-1.mta1.migadu.com (out-1.mta1.migadu.com [95.215.58.1]) by imf06.hostedemail.com (Postfix) with ESMTP id 9C14C18000C for ; Tue, 25 Jul 2023 14:35:09 +0000 (UTC) Authentication-Results: imf06.hostedemail.com; dkim=pass header.d=linux.dev header.s=key1 header.b=tX0LnmXr; dmarc=pass (policy=none) header.from=linux.dev; spf=pass (imf06.hostedemail.com: domain of liu.yun@linux.dev designates 95.215.58.1 as permitted sender) smtp.mailfrom=liu.yun@linux.dev ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1690295710; a=rsa-sha256; cv=none; b=6NpDTy7UnmFqAfTjRxzx8XiQS5syiPjadW8iEQEJkgFPDSpHJERr5qAlSjrkXUdiW47f50 YTk/2E14moaibN4NdydMOQnimUCV0JpbhCGtiqfrqz+Uon1WUqDtwqHwQWyQ0dUYtfxQGq UZd5TbhAqvCYkcs9sEfgjDQpUkC/Y/Y= ARC-Authentication-Results: i=1; imf06.hostedemail.com; dkim=pass header.d=linux.dev header.s=key1 header.b=tX0LnmXr; dmarc=pass (policy=none) header.from=linux.dev; spf=pass (imf06.hostedemail.com: domain of liu.yun@linux.dev designates 95.215.58.1 as permitted sender) smtp.mailfrom=liu.yun@linux.dev ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1690295710; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=kKHakHn9VkLzs6aBbGqhzrbFWR3GMi6GzUkvu6NHQbY=; b=Wudtrk0XHnLUawKG1B3hR6DfF98jLPtWEPwoH+kvRqX8KxwNQoPD6gh24iNGGshHMABNSs vdMQ35/T9iJJkZY/JAK81t4auYmtYRKS6njdzDf9PpNA5l9H2b6H3eSPfRk5zDqw88j3X0 KwXGcuZZadfOhBVEZ6dEQZRuf7CZkx0= Message-ID: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1690295707; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kKHakHn9VkLzs6aBbGqhzrbFWR3GMi6GzUkvu6NHQbY=; b=tX0LnmXrHX46kDroiw9rAl0gnUtUTizhEhDGBmIdolWp4MIqe1c5sYj9JE3/wz3T4Hdye1 uKKBip6WHyjV02LD82Oku0xajQhruLinLae3sZH+l2fMnGo6MwU0o6PikiSIvd/FqOWoAs +9l7hQBXCNbEoE4dF9SUOd0PnXw3zV0= Date: Tue, 25 Jul 2023 22:34:50 +0800 MIME-Version: 1.0 Subject: Re: [PATCH 4/4 v2] LoongArch: Add KFENCE support To: Enze Li , chenhuacai@kernel.org, kernel@xen0n.name, loongarch@lists.linux.dev, glider@google.com, elver@google.com, akpm@linux-foundation.org, kasan-dev@googlegroups.com, linux-mm@kvack.org Cc: zhangqing@loongson.cn, yangtiezhu@loongson.cn, dvyukov@google.com References: <20230725061451.1231480-1-lienze@kylinos.cn> <20230725061451.1231480-5-lienze@kylinos.cn> X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Jackie Liu In-Reply-To: <20230725061451.1231480-5-lienze@kylinos.cn> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT X-Rspam-User: X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: 9C14C18000C X-Stat-Signature: og8wqe3nr6ryiy6gzm673pehy3uqws75 X-HE-Tag: 1690295709-783114 X-HE-Meta: U2FsdGVkX18JBixL0HPFTNr5QB9Yfh7zU6XtTorXYHAf7oyXOeDgb51184NCproFYCqLayp1hHHrVBS8w8Sf/YqXU9ArxlImpxdy3ApPUnIwq3KcHjznrohOlIq0iFRr7PSCSUCh46WjY1fa1We1qougz/6Awj45k1cpDgMI7RwcMsXVSg5z9UZsEoy+vamrTJCVBU5x/7OTnBkHNvDjOG9nzDtXrmjV3BXGcuNszJ33wOUDQ1tSaXMn99r+nlAmTbRKbb8ixBgzN8UHpDBKIP9tZ5cBuu/NAqpb9MbLdbxBFj3NDs1t3nTTQ62L/qog+Vp0RFJSe6St2RY29RaRh6coAn8+zh2SvyEcPI5SWZyyrCeg8/G0Kx5PWFw7Vc2KiyZgy4wPZbObPv+wG/pgBcPj2BizeREuTb4Dd9wNaVdGW+CM6F6kVbqyuCbVTUbmXdWFSrQkpVRRWwb9VOgMtc3yHVV2XUdVWH+Nlc0WzHv7rcSUbEaqvzAVMlbjCpPdWq2MM2C+jfh7TI8p0GTIb98Xgtqn15T4CqvYReiAuyEvgKZWQmki9pJHyahGJlcmCVnEVQ5OX91lknlZBABzDV5WFdbjTMCOsNpXN/0letngTnrIfxb3+HM2kDulponJoo3Qq07C+cFsDx11H4fPpl9M/bc+hmkyKGl8wMmHRRtaC8SFdJ3dZ18cXMggBFv0AXajzB7Bkw+C/IV7LP/IEuigoXHt9eNxfRLWCs0tXpNRdNuyxZiLivT1AeusbsHivq8A9ovagbCPXf4hR8LoXwJ1CmPErQFRzDCp6RSm/mUD3ZcOH6BakyRtYN5JBYTxvtlU4IhOxMef3ATROQtEuvn2TmgnyHfVHtyAdEe6TuswMkutz35i00HrF0cGwb/Ng/y/d9r0hMhGhG4fUoKX5abjFRVnQqGaQUjJ9qNCLPaR0OuRR5TkDb+ffvqwwn/WnmzDSDrXRU7Ed7rxT5J eElKm9kL Haj31l8eRc8Hky5unk5A/L9qfOhnEg1RKhEAdcmmvyzol8qw8BVkjXFlBnqJSXc67Gmk3L8GiSUqLuoStMPCwRJhCEPASWaLPSIcd4dc9SgSPz4zLG2lkcP91hFt7TI20opjudN0+3ZS915uxqM68/fCzyT6uk0x+mkZRNOxBmNev2UA= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: 在 2023/7/25 14:14, Enze Li 写道: > The LoongArch architecture is quite different from other architectures. > When the allocating of KFENCE itself is done, it is mapped to the direct > mapping configuration window [1] by default on LoongArch. It means that > it is not possible to use the page table mapped mode which required by > the KFENCE system and therefore it should be remapped to the appropriate > region. > > This patch adds architecture specific implementation details for KFENCE. > In particular, this implements the required interface in . > > Tested this patch by running the testcases and all passed. > > [1] https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#virtual-address-space-and-address-translation-mode > > Signed-off-by: Enze Li > --- > arch/loongarch/Kconfig | 1 + > arch/loongarch/include/asm/kfence.h | 62 ++++++++++++++++++++++++++++ > arch/loongarch/include/asm/pgtable.h | 14 ++++++- > arch/loongarch/mm/fault.c | 22 ++++++---- > 4 files changed, 90 insertions(+), 9 deletions(-) > create mode 100644 arch/loongarch/include/asm/kfence.h > > diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig > index 70635ea3d1e4..5b63b16be49e 100644 > --- a/arch/loongarch/Kconfig > +++ b/arch/loongarch/Kconfig > @@ -91,6 +91,7 @@ config LOONGARCH > select HAVE_ARCH_AUDITSYSCALL > select HAVE_ARCH_JUMP_LABEL > select HAVE_ARCH_JUMP_LABEL_RELATIVE > + select HAVE_ARCH_KFENCE > select HAVE_ARCH_MMAP_RND_BITS if MMU > select HAVE_ARCH_SECCOMP_FILTER > select HAVE_ARCH_TRACEHOOK > diff --git a/arch/loongarch/include/asm/kfence.h b/arch/loongarch/include/asm/kfence.h > new file mode 100644 > index 000000000000..fb39076fe4d7 > --- /dev/null > +++ b/arch/loongarch/include/asm/kfence.h > @@ -0,0 +1,62 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * KFENCE support for LoongArch. > + * > + * Author: Enze Li > + * Copyright (C) 2022-2023 KylinSoft Corporation. > + */ > + > +#ifndef _ASM_LOONGARCH_KFENCE_H > +#define _ASM_LOONGARCH_KFENCE_H > + > +#include > +#include > +#include > + > +static inline bool arch_kfence_init_pool(void) > +{ > + char *kfence_pool = __kfence_pool; > + struct vm_struct *area; > + int err; > + > + area = __get_vm_area_caller(KFENCE_POOL_SIZE, VM_IOREMAP, > + KFENCE_AREA_START, KFENCE_AREA_END, > + __builtin_return_address(0)); > + if (!area) > + return false; > + > + __kfence_pool = (char *)area->addr; I think there should be something wrong here. > + err = ioremap_page_range((unsigned long)__kfence_pool, > + (unsigned long)__kfence_pool + KFENCE_POOL_SIZE, > + virt_to_phys((void *)kfence_pool), > + PAGE_KERNEL); > + if (err) { > + free_vm_area(area); If err > 0, return area->addr here, It's not correct. -- Jackie Liu > + return false; > + } > + > + return true; > +} > + > +/* Protect the given page and flush TLB. */ > +static inline bool kfence_protect_page(unsigned long addr, bool protect) > +{ > + pte_t *pte = virt_to_kpte(addr); > + > + if (WARN_ON(!pte) || pte_none(*pte)) > + return false; > + > + if (protect) > + set_pte(pte, __pte(pte_val(*pte) & ~(_PAGE_VALID | _PAGE_PRESENT))); > + else > + set_pte(pte, __pte(pte_val(*pte) | (_PAGE_VALID | _PAGE_PRESENT))); > + > + /* Flush this CPU's TLB. */ > + preempt_disable(); > + local_flush_tlb_one(addr); > + preempt_enable(); > + > + return true; > +} > + > +#endif /* _ASM_LOONGARCH_KFENCE_H */ > diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h > index 98a0c98de9d1..2702a6ba7122 100644 > --- a/arch/loongarch/include/asm/pgtable.h > +++ b/arch/loongarch/include/asm/pgtable.h > @@ -77,6 +77,13 @@ extern unsigned long zero_page_mask; > (virt_to_page((void *)(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))) > #define __HAVE_COLOR_ZERO_PAGE > > +#ifdef CONFIG_KFENCE > +#define KFENCE_AREA_SIZE \ > + (((CONFIG_KFENCE_NUM_OBJECTS + 1) * 2 + 2) * PAGE_SIZE) > +#else > +#define KFENCE_AREA_SIZE 0 > +#endif > + > /* > * TLB refill handlers may also map the vmalloc area into xkvrange. > * Avoid the first couple of pages so NULL pointer dereferences will > @@ -88,11 +95,16 @@ extern unsigned long zero_page_mask; > #define VMALLOC_START MODULES_END > #define VMALLOC_END \ > (vm_map_base + \ > - min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE) > + min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE - KFENCE_AREA_SIZE) > > #define vmemmap ((struct page *)((VMALLOC_END + PMD_SIZE) & PMD_MASK)) > #define VMEMMAP_END ((unsigned long)vmemmap + VMEMMAP_SIZE - 1) > > +#ifdef CONFIG_KFENCE > +#define KFENCE_AREA_START VMEMMAP_END > +#define KFENCE_AREA_END (KFENCE_AREA_START + KFENCE_AREA_SIZE) > +#endif > + > #define pte_ERROR(e) \ > pr_err("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e)) > #ifndef __PAGETABLE_PMD_FOLDED > diff --git a/arch/loongarch/mm/fault.c b/arch/loongarch/mm/fault.c > index da5b6d518cdb..c0319128b221 100644 > --- a/arch/loongarch/mm/fault.c > +++ b/arch/loongarch/mm/fault.c > @@ -23,6 +23,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -30,7 +31,8 @@ > > int show_unhandled_signals = 1; > > -static void __kprobes no_context(struct pt_regs *regs, unsigned long address) > +static void __kprobes no_context(struct pt_regs *regs, unsigned long address, > + unsigned long write) > { > const int field = sizeof(unsigned long) * 2; > > @@ -38,6 +40,9 @@ static void __kprobes no_context(struct pt_regs *regs, unsigned long address) > if (fixup_exception(regs)) > return; > > + if (kfence_handle_page_fault(address, write, regs)) > + return; > + > /* > * Oops. The kernel tried to access some bad page. We'll have to > * terminate things with extreme prejudice. > @@ -51,14 +56,15 @@ static void __kprobes no_context(struct pt_regs *regs, unsigned long address) > die("Oops", regs); > } > > -static void __kprobes do_out_of_memory(struct pt_regs *regs, unsigned long address) > +static void __kprobes do_out_of_memory(struct pt_regs *regs, unsigned long address, > + unsigned long write) > { > /* > * We ran out of memory, call the OOM killer, and return the userspace > * (which will retry the fault, or kill us if we got oom-killed). > */ > if (!user_mode(regs)) { > - no_context(regs, address); > + no_context(regs, address, write); > return; > } > pagefault_out_of_memory(); > @@ -69,7 +75,7 @@ static void __kprobes do_sigbus(struct pt_regs *regs, > { > /* Kernel mode? Handle exceptions or die */ > if (!user_mode(regs)) { > - no_context(regs, address); > + no_context(regs, address, write); > return; > } > > @@ -90,7 +96,7 @@ static void __kprobes do_sigsegv(struct pt_regs *regs, > > /* Kernel mode? Handle exceptions or die */ > if (!user_mode(regs)) { > - no_context(regs, address); > + no_context(regs, address, write); > return; > } > > @@ -149,7 +155,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, > */ > if (address & __UA_LIMIT) { > if (!user_mode(regs)) > - no_context(regs, address); > + no_context(regs, address, write); > else > do_sigsegv(regs, write, address, si_code); > return; > @@ -211,7 +217,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, > > if (fault_signal_pending(fault, regs)) { > if (!user_mode(regs)) > - no_context(regs, address); > + no_context(regs, address, write); > return; > } > > @@ -232,7 +238,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, > if (unlikely(fault & VM_FAULT_ERROR)) { > mmap_read_unlock(mm); > if (fault & VM_FAULT_OOM) { > - do_out_of_memory(regs, address); > + do_out_of_memory(regs, address, write); > return; > } else if (fault & VM_FAULT_SIGSEGV) { > do_sigsegv(regs, write, address, si_code);