From patchwork Thu Mar 16 15:10:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhenhua Huang X-Patchwork-Id: 13177768 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 11A4BC6FD1F for ; Thu, 16 Mar 2023 15:11:03 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id A34A4900003; Thu, 16 Mar 2023 11:11:02 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 9E4E0900002; Thu, 16 Mar 2023 11:11:02 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 885EC900003; Thu, 16 Mar 2023 11:11:02 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 795EA900002 for ; Thu, 16 Mar 2023 11:11:02 -0400 (EDT) Received: from smtpin24.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id 4933D1C6D63 for ; Thu, 16 Mar 2023 15:11:02 +0000 (UTC) X-FDA: 80575099164.24.EC24B0D Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by imf06.hostedemail.com (Postfix) with ESMTP id 62DD818001D for ; Thu, 16 Mar 2023 15:10:58 +0000 (UTC) Authentication-Results: imf06.hostedemail.com; dkim=pass header.d=quicinc.com header.s=qcppdkim1 header.b="V/90ROiP"; spf=pass (imf06.hostedemail.com: domain of quic_zhenhuah@quicinc.com designates 205.220.180.131 as permitted sender) smtp.mailfrom=quic_zhenhuah@quicinc.com; dmarc=pass (policy=none) header.from=quicinc.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1678979458; 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:in-reply-to: references:dkim-signature; bh=eHdTtV0lBgYizUaeyP96VkwCxTWvoPj/T5orJccIOJQ=; b=d7XEVhLyr9dLaVNLbzn8EFjm7vpgSACmKQEqrMGX7Ea2MFdst24f2hRcHE56PuB+erbpL6 YX2VMNQS5nAOUG1R2eXbf9hQSZ80JY+xKKUeh2DiQFNaNumwZ+GZvhU91o9iZMDT5YpKn+ Tjt8OXhKC0mPpaxccarNI/2dj4A7KIA= ARC-Authentication-Results: i=1; imf06.hostedemail.com; dkim=pass header.d=quicinc.com header.s=qcppdkim1 header.b="V/90ROiP"; spf=pass (imf06.hostedemail.com: domain of quic_zhenhuah@quicinc.com designates 205.220.180.131 as permitted sender) smtp.mailfrom=quic_zhenhuah@quicinc.com; dmarc=pass (policy=none) header.from=quicinc.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1678979458; a=rsa-sha256; cv=none; b=waHS1Y2iHiGQj2wcoDIzfULNq0vIXCb1F8BZc9ptId+HB7Lfk3nwWXhu3kzJiZYcRoINiw KXgv2d4MATuTHe0SIt5M3Twnt/TPr1M70qrEypOIuJXE99VIOAQZmhLhDNtqOD0nzGAEWP 5maS1l478yuGJhskLMtxNr4qzaTk9g8= Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 32G24u4Z014889; Thu, 16 Mar 2023 15:10:42 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : mime-version : content-type; s=qcppdkim1; bh=eHdTtV0lBgYizUaeyP96VkwCxTWvoPj/T5orJccIOJQ=; b=V/90ROiPXmgbonPsMlR9HjhJihYeRyPM6PmNu5BE5ytFXRmo6P0AgWqC3bP89XLqy00j hsJ7BBMyS1+1+lrcDb1kaAv6wSo+bImZKoWTgCG7+NhLVf4mCByC/BIVHQ8fh3HsoXrz l6F/eMaoyyEmXhllAThK63DusVKH7vBp9SzyqCnRVSWNn93c31szfJW4MdgR6nvPG42y iYK1mdeWWfCCnnrV/RnATtZF3B2QDutqHKXaOZki5xhxwVvOhx99/iiN6OUXBpdSewa0 qZ/ecnMLhtSP9HGw60k/aYM7pgBdgZeL8x/ulyU2eZ8yX/a2y/NEWwXv0o1lQwBdM+GV Ig== Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3pbpy9j8ay-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 16 Mar 2023 15:10:42 +0000 Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 32GFAfSv019229 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 16 Mar 2023 15:10:41 GMT Received: from zhenhuah-gv.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.41; Thu, 16 Mar 2023 08:10:36 -0700 From: Zhenhua Huang To: , , , , , , , , , , CC: Zhenhua Huang , , , , , , Subject: [PATCH v11] mm,kfence: decouple kfence from page granularity mapping judgement Date: Thu, 16 Mar 2023 23:10:29 +0800 Message-ID: <1678979429-25815-1-git-send-email-quic_zhenhuah@quicinc.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: 64gGpA0whIXuddshqb5pVFaTvAnN2oM3 X-Proofpoint-GUID: 64gGpA0whIXuddshqb5pVFaTvAnN2oM3 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-03-16_10,2023-03-16_01,2023-02-09_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 clxscore=1015 mlxlogscore=999 suspectscore=0 spamscore=0 malwarescore=0 mlxscore=0 priorityscore=1501 bulkscore=0 adultscore=0 phishscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2303150002 definitions=main-2303160122 X-Rspam-User: X-Rspamd-Server: rspam03 X-Stat-Signature: 7899etdxkspzpmjdwah1ouxdx39x3qka X-Rspamd-Queue-Id: 62DD818001D X-HE-Tag: 1678979458-83421 X-HE-Meta: U2FsdGVkX18loRPdLmTahn+F6100cC9sD4kaT8RTyo3jUljjrb9H9zd9ZbV8sGNGgLol8JqID7pcTuyf0YLeOnuhmJLdsGyAf1/ZNLFkNZy456sJOkIJffmtACiBxGcJa997D2C2qFA+2683uDEyDeJpdy/b5G1hhlSoN666p4dv5ZwpZqYK3U7YH2H69H6RmWLsQbTqzkpFbpFvTczU6S8/msxPCrCJzlbnRzgsOPowb36aFWMIm+0s0HwRfAyXny9zeaWlbWTtZIdFXKm3Z91ANmZMc4e4UGpf8zVg/2A6zo82zFR3hhU/xgjDwC7srQaG9lfMIfYKN3mJw3iMzoF4txVgOmP8dYrvH7S0dzIgAC1HNpT8eNdwyRglKdh1oDAVf4pWjaQUrLZf+IoWp2PWoGyZM6sAOeq5kJwoCWc1XdQ6HKvlQaeBlzmKOVf5f/6Gx9yfOXE2CJG8+/jolKJbxj7JzbL5ATjESuAARQEN9S1oohn6Ofw5DFDi+tOeXh6aXWU542QsuwdnCl8LGpeSjj44gvOOoWysMKPJEwWEmH4xGEFSIe/FYcT2C/slL61lohTD5rOQFwptyo2xgekwFFNAGMiMHBJ5mnBLcvqmEu7SFskcyRpAxUstGNovgJpwSCGRYFkL+qBrKGPVlodaVUDIno0cMi1/vMiyQuoOyMArlcc4w/UAQgAWfeBKFtFMiAr3gdX/fglcK4J/lrmyqvSv49k76945l+MNjPTCeK1GWEdN9V/8hg3GOEPsJU4okC4eJ/6Vgyrz3ZZjWVuJj0yc2fGjc81vCEa7YvsiO+BABN06vV3DYGWVcdpXE4T4wPULR7q4vHZoUSr7d8pzjevE+Ac3uCk9XtMx9KGzS6llRvjXSgv3sVATEoTRlEKDlbZ0DQ6Af9/Y8eFZnYYvGCqMHRcpXI3Kgj440rkQ/MR/I759peSc4LIMGmaMdwel8uo34CGdKrqmqmR OGHwtHfC Wi23+3Uec0xy7cVtx30l2KWSBIz9Y05nGWEfpHIVm7yqn4nsZy0rY+jUGDB0qqaTQhnjSALLcQ6abmjdswreizKahZ+AaCKzCcVzqkBr8ktjg7AvJmkgOs3TjYEWxwutbIfqYu0vn9wXEUVwnsgzx0FU3f+rQJcJB4wsZ75NSAuxJiKXQWaulsKJbS1MgGr7JbvvZucse1PnRnkYCKX7d77DMh9viUsbCXSlzE0ELphC1lrqN2nCQX8czZaKtzNKOCl7/5h9Eu9SFVWCV2pHzuAgXd5uRqIENdMbOJxsauGxiAdNJGW34qNH2IR+nXdMaXTZidUenH9TlToLM8bOHJ4M6eGHXuteq37adPoV3VBWkGpxWzuvhD6Tv1oq7oPx38xrt 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: Kfence only needs its pool to be mapped as page granularity, if it is inited early. Previous judgement was a bit over protected. From [1], Mark suggested to "just map the KFENCE region a page granularity". So I decouple it from judgement and do page granularity mapping for kfence pool only. Need to be noticed that late init of kfence pool still requires page granularity mapping. Page granularity mapping in theory cost more(2M per 1GB) memory on arm64 platform. Like what I've tested on QEMU(emulated 1GB RAM) with gki_defconfig, also turning off rodata protection: Before: [root@liebao ]# cat /proc/meminfo MemTotal: 999484 kB After: [root@liebao ]# cat /proc/meminfo MemTotal: 1001480 kB To implement this, also relocate the kfence pool allocation before the linear mapping setting up, arm64_kfence_alloc_pool is to allocate phys addr, __kfence_pool is to be set after linear mapping set up. LINK: [1] https://lore.kernel.org/linux-arm-kernel/Y+IsdrvDNILA59UN@FVFF77S0Q05N/ Suggested-by: Mark Rutland Signed-off-by: Zhenhua Huang Reviewed-by: Kefeng Wang Reviewed-by: Marco Elver --- arch/arm64/include/asm/kfence.h | 10 +++++++ arch/arm64/mm/mmu.c | 61 +++++++++++++++++++++++++++++++++++++++++ arch/arm64/mm/pageattr.c | 7 +++-- mm/kfence/core.c | 4 +++ 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kfence.h b/arch/arm64/include/asm/kfence.h index aa855c6..a81937f 100644 --- a/arch/arm64/include/asm/kfence.h +++ b/arch/arm64/include/asm/kfence.h @@ -19,4 +19,14 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect) return true; } +#ifdef CONFIG_KFENCE +extern bool kfence_early_init; +static inline bool arm64_kfence_can_set_direct_map(void) +{ + return !kfence_early_init; +} +#else /* CONFIG_KFENCE */ +static inline bool arm64_kfence_can_set_direct_map(void) { return false; } +#endif /* CONFIG_KFENCE */ + #endif /* __ASM_KFENCE_H */ diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 6f9d889..9813f2a 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,7 @@ #include #include #include +#include #define NO_BLOCK_MAPPINGS BIT(0) #define NO_CONT_MAPPINGS BIT(1) @@ -525,12 +527,67 @@ static int __init enable_crash_mem_map(char *arg) } early_param("crashkernel", enable_crash_mem_map); +#ifdef CONFIG_KFENCE + +bool __ro_after_init kfence_early_init = !!CONFIG_KFENCE_SAMPLE_INTERVAL; + +/* early_param() will be parsed before map_mem() below. */ +static int __init parse_kfence_early_init(char *arg) +{ + int val; + + if (get_option(&arg, &val)) + kfence_early_init = !!val; + return 0; +} +early_param("kfence.sample_interval", parse_kfence_early_init); + +static phys_addr_t __init arm64_kfence_alloc_pool(void) +{ + phys_addr_t kfence_pool; + + if (!kfence_early_init) + return 0; + + kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE); + if (!kfence_pool) { + pr_err("failed to allocate kfence pool\n"); + kfence_early_init = false; + return 0; + } + + /* Temporarily mark as NOMAP. */ + memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE); + + return kfence_pool; +} + +static void __init arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) +{ + if (!kfence_pool) + return; + + /* KFENCE pool needs page-level mapping. */ + __map_memblock(pgdp, kfence_pool, kfence_pool + KFENCE_POOL_SIZE, + pgprot_tagged(PAGE_KERNEL), + NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS); + memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE); + __kfence_pool = phys_to_virt(kfence_pool); +} +#else /* CONFIG_KFENCE */ + +static inline phys_addr_t arm64_kfence_alloc_pool(void) { return 0; } +static inline void arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) { } + +#endif /* CONFIG_KFENCE */ + static void __init map_mem(pgd_t *pgdp) { static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN); phys_addr_t kernel_start = __pa_symbol(_stext); phys_addr_t kernel_end = __pa_symbol(__init_begin); phys_addr_t start, end; + phys_addr_t early_kfence_pool; int flags = NO_EXEC_MAPPINGS; u64 i; @@ -543,6 +600,8 @@ static void __init map_mem(pgd_t *pgdp) */ BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end)); + early_kfence_pool = arm64_kfence_alloc_pool(); + if (can_set_direct_map()) flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; @@ -608,6 +667,8 @@ static void __init map_mem(pgd_t *pgdp) } } #endif + + arm64_kfence_map_pool(early_kfence_pool, pgdp); } void mark_rodata_ro(void) diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c index 79dd201..8e2017b 100644 --- a/arch/arm64/mm/pageattr.c +++ b/arch/arm64/mm/pageattr.c @@ -11,6 +11,7 @@ #include #include #include +#include struct page_change_data { pgprot_t set_mask; @@ -22,12 +23,14 @@ bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED bool can_set_direct_map(void) { /* - * rodata_full, DEBUG_PAGEALLOC and KFENCE require linear map to be + * rodata_full and DEBUG_PAGEALLOC require linear map to be * mapped at page granularity, so that it is possible to * protect/unprotect single pages. + * + * KFENCE pool requires page-granular mapping if initialized late. */ return (rodata_enabled && rodata_full) || debug_pagealloc_enabled() || - IS_ENABLED(CONFIG_KFENCE); + arm64_kfence_can_set_direct_map(); } static int change_page_range(pte_t *ptep, unsigned long addr, void *data) diff --git a/mm/kfence/core.c b/mm/kfence/core.c index 5349c37..5abc79f 100644 --- a/mm/kfence/core.c +++ b/mm/kfence/core.c @@ -814,6 +814,10 @@ void __init kfence_alloc_pool(void) if (!kfence_sample_interval) return; + /* if the pool has already been initialized by arch, skip the below. */ + if (__kfence_pool) + return; + __kfence_pool = memblock_alloc(KFENCE_POOL_SIZE, PAGE_SIZE); if (!__kfence_pool)