From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bartosz Golaszewski Subject: [PATCH v5 3/4] devres: provide devm_kstrdup_const() Date: Fri, 28 Sep 2018 09:14:13 +0200 Message-ID: <20180928071414.30703-4-brgl@bgdev.pl> References: <20180928071414.30703-1-brgl@bgdev.pl> Return-path: In-Reply-To: <20180928071414.30703-1-brgl@bgdev.pl> Sender: linux-kernel-owner@vger.kernel.org To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Jassi Brar , Thierry Reding , Jonathan Hunter , Arnd Bergmann , Andy Shevchenko , Geert Uytterhoeven , Rasmus Villemoes Cc: linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-arch@vger.kernel.org, linux-mm@kvack.org, Bartosz Golaszewski List-Id: linux-arch.vger.kernel.org Provide a resource managed version of kstrdup_const(). This variant internally calls devm_kstrdup() on pointers that are outside of .rodata section and returns the string as is otherwise. Make devm_kfree() check if the passed pointer doesn't point to .rodata and if so - don't actually destroy the resource. Signed-off-by: Bartosz Golaszewski Reviewed-by: Bjorn Andersson Acked-by: Mike Rapoport --- drivers/base/devres.c | 31 +++++++++++++++++++++++++++++++ include/linux/device.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 438c91a43508..00c70f0fcdcd 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -11,6 +11,8 @@ #include #include +#include + #include "base.h" struct devres_node { @@ -822,6 +824,28 @@ char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) } EXPORT_SYMBOL_GPL(devm_kstrdup); +/** + * devm_kstrdup_const - resource managed conditional string duplication + * @dev: device for which to duplicate the string + * @s: the string to duplicate + * @gfp: the GFP mask used in the kmalloc() call when allocating memory + * + * Strings allocated by devm_kstrdup_const will be automatically freed when + * the associated device is detached. + * + * RETURNS: + * Source string if it is in .rodata section otherwise it falls back to + * devm_kstrdup. + */ +const char *devm_kstrdup_const(struct device *dev, const char *s, gfp_t gfp) +{ + if (is_kernel_rodata((unsigned long)s)) + return s; + + return devm_kstrdup(dev, s, gfp); +} +EXPORT_SYMBOL(devm_kstrdup_const); + /** * devm_kvasprintf - Allocate resource managed space and format a string * into that. @@ -889,6 +913,13 @@ void devm_kfree(struct device *dev, const void *p) { int rc; + /* + * Special case: pointer to a string in .rodata returned by + * devm_kstrdup_const(). + */ + if (unlikely(is_kernel_rodata((unsigned long)p))) + return; + rc = devres_destroy(dev, devm_kmalloc_release, devm_kmalloc_match, (void *)p); WARN_ON(rc); diff --git a/include/linux/device.h b/include/linux/device.h index 33f7cb271fbb..e626acb93ef5 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -694,6 +694,8 @@ static inline void *devm_kcalloc(struct device *dev, } extern void devm_kfree(struct device *dev, const void *p); extern char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) __malloc; +extern const char *devm_kstrdup_const(struct device *dev, + const char *s, gfp_t gfp); extern void *devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp); -- 2.18.0 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-f67.google.com ([209.85.221.67]:43164 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728951AbeI1Ngr (ORCPT ); Fri, 28 Sep 2018 09:36:47 -0400 Received: by mail-wr1-f67.google.com with SMTP id z14-v6so5144758wrs.10 for ; Fri, 28 Sep 2018 00:14:26 -0700 (PDT) From: Bartosz Golaszewski Subject: [PATCH v5 3/4] devres: provide devm_kstrdup_const() Date: Fri, 28 Sep 2018 09:14:13 +0200 Message-ID: <20180928071414.30703-4-brgl@bgdev.pl> In-Reply-To: <20180928071414.30703-1-brgl@bgdev.pl> References: <20180928071414.30703-1-brgl@bgdev.pl> Sender: linux-arch-owner@vger.kernel.org List-ID: To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Jassi Brar , Thierry Reding , Jonathan Hunter , Arnd Bergmann , Andy Shevchenko , Geert Uytterhoeven , Rasmus Villemoes Cc: linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-arch@vger.kernel.org, linux-mm@kvack.org, Bartosz Golaszewski Message-ID: <20180928071413.LvVgKrt3LXfuf0wthEUn1aN8tpPvO7_--0VCGJ0TYuE@z> Provide a resource managed version of kstrdup_const(). This variant internally calls devm_kstrdup() on pointers that are outside of .rodata section and returns the string as is otherwise. Make devm_kfree() check if the passed pointer doesn't point to .rodata and if so - don't actually destroy the resource. Signed-off-by: Bartosz Golaszewski Reviewed-by: Bjorn Andersson Acked-by: Mike Rapoport --- drivers/base/devres.c | 31 +++++++++++++++++++++++++++++++ include/linux/device.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 438c91a43508..00c70f0fcdcd 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -11,6 +11,8 @@ #include #include +#include + #include "base.h" struct devres_node { @@ -822,6 +824,28 @@ char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) } EXPORT_SYMBOL_GPL(devm_kstrdup); +/** + * devm_kstrdup_const - resource managed conditional string duplication + * @dev: device for which to duplicate the string + * @s: the string to duplicate + * @gfp: the GFP mask used in the kmalloc() call when allocating memory + * + * Strings allocated by devm_kstrdup_const will be automatically freed when + * the associated device is detached. + * + * RETURNS: + * Source string if it is in .rodata section otherwise it falls back to + * devm_kstrdup. + */ +const char *devm_kstrdup_const(struct device *dev, const char *s, gfp_t gfp) +{ + if (is_kernel_rodata((unsigned long)s)) + return s; + + return devm_kstrdup(dev, s, gfp); +} +EXPORT_SYMBOL(devm_kstrdup_const); + /** * devm_kvasprintf - Allocate resource managed space and format a string * into that. @@ -889,6 +913,13 @@ void devm_kfree(struct device *dev, const void *p) { int rc; + /* + * Special case: pointer to a string in .rodata returned by + * devm_kstrdup_const(). + */ + if (unlikely(is_kernel_rodata((unsigned long)p))) + return; + rc = devres_destroy(dev, devm_kmalloc_release, devm_kmalloc_match, (void *)p); WARN_ON(rc); diff --git a/include/linux/device.h b/include/linux/device.h index 33f7cb271fbb..e626acb93ef5 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -694,6 +694,8 @@ static inline void *devm_kcalloc(struct device *dev, } extern void devm_kfree(struct device *dev, const void *p); extern char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) __malloc; +extern const char *devm_kstrdup_const(struct device *dev, + const char *s, gfp_t gfp); extern void *devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp); -- 2.18.0