Received: by 2002:a25:e74b:0:0:0:0:0 with SMTP id e72csp467834ybh; Sat, 18 Jul 2020 09:30:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwpRxVHtjwlSXFWJe2TexX16NLkpfitXAFouFrWQc/qH0a2TFHkh8UHIbRDZ49GdHchgQq1 X-Received: by 2002:a17:906:284e:: with SMTP id s14mr13644100ejc.498.1595089846476; Sat, 18 Jul 2020 09:30:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595089846; cv=none; d=google.com; s=arc-20160816; b=iqdSrmuAiceitd5DfAHK+furQcO0SBfzvAP2LyxcLLrUoYR9XyjemU594aFTXH41O+ O+X2kHtE8HZRL7v/mB0S3NAna6IbrzqPABc8IfP8v9Gqtf04LhSDxsSkBT4eeb3fiAKS CocWoCp3lfA9mutnRg0s/KUOOf/QqwSwNW2I9saeRQSaC/c4au9+IbL4kcoKyCXJ9sL9 g8UhAy77hnmsNUkLlCg7d5pNeFm8K7bxu2Nk/4sbQIMXPjem+2bNnJfiBwuTeJHqM+Ho KLWoQxA+LDq1wrbzqCcjPvKXQm7zkROktT5DAmEpIPqcok6xDC65pV2RyDpxfjQ3JvWQ ASpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :dkim-signature; bh=Njnm91FxKApRm8Js/cfz62iVYMGTSjzyIj5YtoGTDaw=; b=Oq0bXpI8aYUU/VEWU9Hv0zrHArhOb4jN5Ls8kctcbqQa1tDWwvwn7OX2RkVaFIHLvP Vd55zWeqq5T3+M2I0pYRwShBZBaLYzUq0OwaITcXMieqJOiSysUmB2zQXxLHgvCEcNKK n0teqT0HXrYzfOnZHYw8+6fx3mp0bCTqe2k+YBO0uQaQBV/jZ4xfSjxF+GBZF2gkQh/4 2LZK6YrqdEB0kwc0aIc5ZJ0TejVkCPcwXAAli3UJ/nqb/10u1/t0tykv8tROxUT1DQU1 s6pwB14tFaTkNO5PYb3x2yE0o21B5cvf97xOeb/IjJbo48GRBejf1lX5PX6Lu1wp0ez3 pp9A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=jqNDWhd3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id lf11si7826734ejb.475.2020.07.18.09.30.23; Sat, 18 Jul 2020 09:30:46 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=jqNDWhd3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727025AbgGRQYK (ORCPT + 99 others); Sat, 18 Jul 2020 12:24:10 -0400 Received: from mail.kernel.org ([198.145.29.99]:35110 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726604AbgGRQYK (ORCPT ); Sat, 18 Jul 2020 12:24:10 -0400 Received: from kernel.org (unknown [87.71.40.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 0150720734; Sat, 18 Jul 2020 16:24:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1595089449; bh=km2mzwtZ+FjNhtaMQXEWg0EuxYlrDbyzGAdxsGPwbwA=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=jqNDWhd3xFmC2b0tXUdXJ+AsInllep5JA5RNocblgXsd5dYIBfk8+dsh/L9QtLvr6 PxfXaJqz2AzdvusBty/jfjCgQXcEKmdIAyUNDx2kZTWPlS0ugCCv6BBH8z0iOnvY87 dDkXVwEogi7zB+ISmYgs1VjILf79dte4Umo1ONJs= Date: Sat, 18 Jul 2020 19:23:59 +0300 From: Mike Rapoport To: Jarkko Sakkinen Cc: linux-kernel@vger.kernel.org, Andi Kleen , Masami Hiramatsu , Peter Zijlstra , Andrew Morton , "open list:MEMORY MANAGEMENT" Subject: Re: [PATCH v4 3/7] vmalloc: Add text_alloc() and text_free() Message-ID: <20200718162359.GA2919062@kernel.org> References: <20200717030422.679972-1-jarkko.sakkinen@linux.intel.com> <20200717030422.679972-4-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200717030422.679972-4-jarkko.sakkinen@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Jul 17, 2020 at 06:04:17AM +0300, Jarkko Sakkinen wrote: > Introduce functions for allocating memory for dynamic trampolines, such > as kprobes. An arch can promote the availability of these functions with > CONFIG_ARCH_HAS_TEXT_ALLOC. Provide default/fallback implementation > wrapping module_alloc() and module_memfree(). > > Cc: Andi Kleen > Cc: Masami Hiramatsu > Suggested-by: Peter Zijlstra > Signed-off-by: Jarkko Sakkinen > --- > include/linux/vmalloc.h | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > > diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h > index 0221f852a7e1..e981436e30b6 100644 > --- a/include/linux/vmalloc.h > +++ b/include/linux/vmalloc.h > @@ -9,6 +9,7 @@ > #include /* pgprot_t */ > #include > #include > +#include > > #include > > @@ -249,4 +250,26 @@ pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms) > int register_vmap_purge_notifier(struct notifier_block *nb); > int unregister_vmap_purge_notifier(struct notifier_block *nb); > > +#ifdef CONFIG_ARCH_HAS_TEXT_ALLOC > +/* > + * Allocate memory to be used for dynamic trampoline code. > + */ > +void *text_alloc(unsigned long size); > + > +/* > + * Free memory returned from text_alloc(). > + */ > +void text_free(void *region); > +#else > +static inline void *text_alloc(unsigned long size) > +{ > + return module_alloc(size); > +} > + > +static inline void text_free(void *region) > +{ > + module_memfree(region); > +} Using module_alloc() as the default implementation of generic text_alloc() does not sound right to me. I would suggest rename module_alloc() to text_alloc() on x86, as Peter proposed and then add text_alloc_kprobes() that can be overridden by the architectures. x86 could use text_alloc(), arm64 vmalloc() with options of their choice and the fallback would remain module_alloc(). Something like (untested) patch below: From 928b6903e76ebf5790fc415f9eed390e400e5bc3 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Sat, 18 Jul 2020 19:13:02 +0300 Subject: [PATCH] kprobes: introduce text_alloc_kprobes() and text_free_kprobes() Signed-off-by: Mike Rapoport --- arch/Kconfig | 5 ++++- arch/arm64/Kconfig | 1 + arch/arm64/kernel/probes/kprobes.c | 10 ++++++++-- arch/x86/Kconfig | 3 ++- arch/x86/kernel/kprobes/core.c | 9 ++++----- include/linux/kprobes.h | 17 +++++++++++++++-- kernel/kprobes.c | 8 ++++---- 7 files changed, 38 insertions(+), 15 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 8cc35dc556c7..c0589b3b3225 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -61,7 +61,7 @@ config OPROFILE_NMI_TIMER config KPROBES bool "Kprobes" - depends on MODULES + depends on MODULES || HAVE_KPROBES_TEXT_ALLOC depends on HAVE_KPROBES select KALLSYMS help @@ -186,6 +186,9 @@ config HAVE_IOREMAP_PROT config HAVE_KPROBES bool +config HAVE_KPROBES_TEXT_ALLOC + bool + config HAVE_KRETPROBES bool diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 66dc41fd49f2..abc0538b13ef 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -177,6 +177,7 @@ config ARM64 select HAVE_STACKPROTECTOR select HAVE_SYSCALL_TRACEPOINTS select HAVE_KPROBES + select HAVE_KPROBES_TEXT_ALLOC select HAVE_KRETPROBES select HAVE_GENERIC_VDSO select IOMMU_DMA if IOMMU_SUPPORT diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index 5290f17a4d80..fac8c6020040 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c @@ -118,13 +118,19 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) return 0; } -void *alloc_insn_page(void) +void *text_alloc_kprobes(unsigned long size) { - return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END, + return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS, NUMA_NO_NODE, __builtin_return_address(0)); } +void text_free_kprobes(void *mem) +{ + lockdep_assert_irqs_enabled(); + vfree(mem); +} + /* arm kprobe: install breakpoint in text */ void __kprobes arch_arm_kprobe(struct kprobe *p) { diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 883da0abf779..d08b92f91531 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -190,6 +190,7 @@ config X86 select HAVE_KERNEL_XZ select HAVE_KPROBES select HAVE_KPROBES_ON_FTRACE + select HAVE_KPROBES_TEXT_ALLOC select HAVE_FUNCTION_ERROR_INJECTION select HAVE_KRETPROBES select HAVE_KVM diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index ada39ddbc922..a3e8f01c62d4 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -418,12 +418,11 @@ static int prepare_boost(kprobe_opcode_t *buf, struct kprobe *p, return len; } -/* Make page to RO mode when allocate it */ -void *alloc_insn_page(void) +void *text_alloc_kprobes(unsigned long size) { void *page; - page = module_alloc(PAGE_SIZE); + page = text_alloc(size); if (!page) return NULL; @@ -444,9 +443,9 @@ void *alloc_insn_page(void) } /* Recover page to RW mode before releasing it */ -void free_insn_page(void *page) +void text_free_kprobes(void *page) { - module_memfree(page); + text_free(page); } static int arch_copy_kprobe(struct kprobe *p) diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 6adf90f248d7..dbc9c71d4ec4 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #ifdef CONFIG_KPROBES @@ -374,8 +375,20 @@ int enable_kprobe(struct kprobe *kp); void dump_kprobe(struct kprobe *kp); -void *alloc_insn_page(void); -void free_insn_page(void *page); +#ifdef CONFIG_HAVE_KPROBES_TEXT_ALLOC +void *text_alloc_kprobes(unsigned long size); +void text_free_kprobes(void *page); +#else +static inline void *text_alloc_kprobes(unsigned long size) +{ + return module_alloc(size); +} + +static inline void text_free_kprobes(void *page) +{ + module_memfree(page); +} +#endif #else /* !CONFIG_KPROBES: */ diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 2e97febeef77..c4f107682250 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -109,14 +109,14 @@ enum kprobe_slot_state { SLOT_USED = 2, }; -void __weak *alloc_insn_page(void) +static void *alloc_insn_page(void) { - return module_alloc(PAGE_SIZE); + return text_alloc_kprobes(PAGE_SIZE); } -void __weak free_insn_page(void *page) +static void free_insn_page(void *page) { - module_memfree(page); + text_free_kprobes(page); } struct kprobe_insn_cache kprobe_insn_slots = { -- 2.26.2 > +#endif > + > #endif /* _LINUX_VMALLOC_H */ > -- > 2.25.1 > -- Sincerely yours, Mike.