Driver core patches for 4.20-rc1
Driver core patches for 4.20-rc1 Here is a small number of driver core patches for 4.20-rc1. Not much happened here this merge window, only a very tiny number of patches that do: - add BUS_ATTR_WO() for use by drivers - component error path fixes - kernfs range check fix - other tiny error path fixes and const changes All of these have been in linux-next with no reported issues for a while. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCW9Lhtw8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ykHTgCguaJ3SgRefuC/WijjqboTC/SikCoAnRVTUxfU v8BisSN22kR3jmxwsXud =/IvY -----END PGP SIGNATURE----- Merge tag 'driver-core-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core Pull driver core updates from Greg KH: "Here is a small number of driver core patches for 4.20-rc1. Not much happened here this merge window, only a very tiny number of patches that do: - add BUS_ATTR_WO() for use by drivers - component error path fixes - kernfs range check fix - other tiny error path fixes and const changes All of these have been in linux-next with no reported issues for a while" * tag 'driver-core-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: devres: provide devm_kstrdup_const() mm: move is_kernel_rodata() to asm-generic/sections.h devres: constify p in devm_kfree() driver core: add BUS_ATTR_WO() macro kernfs: Fix range checks in kernfs_get_target_path component: fix loop condition to call unbind() if bind() fails drivers/base/devtmpfs.c: don't pretend path is const in delete_path kernfs: update comment about kernfs_path() return value
This commit is contained in:
commit
26873acacb
@ -536,9 +536,9 @@ int component_bind_all(struct device *master_dev, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
for (; i--; )
|
for (; i > 0; i--)
|
||||||
if (!master->match->compare[i].duplicate) {
|
if (!master->match->compare[i - 1].duplicate) {
|
||||||
c = master->match->compare[i].component;
|
c = master->match->compare[i - 1].component;
|
||||||
component_unbind(c, master, data);
|
component_unbind(c, master, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/percpu.h>
|
#include <linux/percpu.h>
|
||||||
|
|
||||||
|
#include <asm/sections.h>
|
||||||
|
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
|
|
||||||
struct devres_node {
|
struct devres_node {
|
||||||
@ -822,6 +824,28 @@ char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(devm_kstrdup);
|
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_GPL(devm_kstrdup_const);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* devm_kvasprintf - Allocate resource managed space and format a string
|
* devm_kvasprintf - Allocate resource managed space and format a string
|
||||||
* into that.
|
* into that.
|
||||||
@ -885,11 +909,19 @@ EXPORT_SYMBOL_GPL(devm_kasprintf);
|
|||||||
*
|
*
|
||||||
* Free memory allocated with devm_kmalloc().
|
* Free memory allocated with devm_kmalloc().
|
||||||
*/
|
*/
|
||||||
void devm_kfree(struct device *dev, void *p)
|
void devm_kfree(struct device *dev, const void *p)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = devres_destroy(dev, devm_kmalloc_release, devm_kmalloc_match, p);
|
/*
|
||||||
|
* 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);
|
WARN_ON(rc);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(devm_kfree);
|
EXPORT_SYMBOL_GPL(devm_kfree);
|
||||||
|
@ -252,7 +252,7 @@ static int dev_rmdir(const char *name)
|
|||||||
|
|
||||||
static int delete_path(const char *nodepath)
|
static int delete_path(const char *nodepath)
|
||||||
{
|
{
|
||||||
const char *path;
|
char *path;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
path = kstrdup(nodepath, GFP_KERNEL);
|
path = kstrdup(nodepath, GFP_KERNEL);
|
||||||
|
@ -72,6 +72,9 @@ static int kernfs_get_target_path(struct kernfs_node *parent,
|
|||||||
if (base == kn)
|
if (base == kn)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if ((s - path) + 3 >= PATH_MAX)
|
||||||
|
return -ENAMETOOLONG;
|
||||||
|
|
||||||
strcpy(s, "../");
|
strcpy(s, "../");
|
||||||
s += 3;
|
s += 3;
|
||||||
base = base->parent;
|
base = base->parent;
|
||||||
@ -88,7 +91,7 @@ static int kernfs_get_target_path(struct kernfs_node *parent,
|
|||||||
if (len < 2)
|
if (len < 2)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
len--;
|
len--;
|
||||||
if ((s - path) + len > PATH_MAX)
|
if ((s - path) + len >= PATH_MAX)
|
||||||
return -ENAMETOOLONG;
|
return -ENAMETOOLONG;
|
||||||
|
|
||||||
/* reverse fillup of target string from target to base */
|
/* reverse fillup of target string from target to base */
|
||||||
|
@ -141,4 +141,18 @@ static inline bool init_section_intersects(void *virt, size_t size)
|
|||||||
return memory_intersects(__init_begin, __init_end, virt, size);
|
return memory_intersects(__init_begin, __init_end, virt, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is_kernel_rodata - checks if the pointer address is located in the
|
||||||
|
* .rodata section
|
||||||
|
*
|
||||||
|
* @addr: address to check
|
||||||
|
*
|
||||||
|
* Returns: true if the address is located in .rodata, false otherwise.
|
||||||
|
*/
|
||||||
|
static inline bool is_kernel_rodata(unsigned long addr)
|
||||||
|
{
|
||||||
|
return addr >= (unsigned long)__start_rodata &&
|
||||||
|
addr < (unsigned long)__end_rodata;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _ASM_GENERIC_SECTIONS_H_ */
|
#endif /* _ASM_GENERIC_SECTIONS_H_ */
|
||||||
|
@ -55,6 +55,8 @@ struct bus_attribute {
|
|||||||
struct bus_attribute bus_attr_##_name = __ATTR_RW(_name)
|
struct bus_attribute bus_attr_##_name = __ATTR_RW(_name)
|
||||||
#define BUS_ATTR_RO(_name) \
|
#define BUS_ATTR_RO(_name) \
|
||||||
struct bus_attribute bus_attr_##_name = __ATTR_RO(_name)
|
struct bus_attribute bus_attr_##_name = __ATTR_RO(_name)
|
||||||
|
#define BUS_ATTR_WO(_name) \
|
||||||
|
struct bus_attribute bus_attr_##_name = __ATTR_WO(_name)
|
||||||
|
|
||||||
extern int __must_check bus_create_file(struct bus_type *,
|
extern int __must_check bus_create_file(struct bus_type *,
|
||||||
struct bus_attribute *);
|
struct bus_attribute *);
|
||||||
@ -692,8 +694,10 @@ static inline void *devm_kcalloc(struct device *dev,
|
|||||||
{
|
{
|
||||||
return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
|
return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
|
||||||
}
|
}
|
||||||
extern void devm_kfree(struct device *dev, void *p);
|
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 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,
|
extern void *devm_kmemdup(struct device *dev, const void *src, size_t len,
|
||||||
gfp_t gfp);
|
gfp_t gfp);
|
||||||
|
|
||||||
|
@ -477,10 +477,11 @@ static inline void kernfs_init(void) { }
|
|||||||
* @buf: buffer to copy @kn's name into
|
* @buf: buffer to copy @kn's name into
|
||||||
* @buflen: size of @buf
|
* @buflen: size of @buf
|
||||||
*
|
*
|
||||||
* Builds and returns the full path of @kn in @buf of @buflen bytes. The
|
* If @kn is NULL result will be "(null)".
|
||||||
* path is built from the end of @buf so the returned pointer usually
|
*
|
||||||
* doesn't match @buf. If @buf isn't long enough, @buf is nul terminated
|
* Returns the length of the full path. If the full length is equal to or
|
||||||
* and %NULL is returned.
|
* greater than @buflen, @buf contains the truncated path with the trailing
|
||||||
|
* '\0'. On error, -errno is returned.
|
||||||
*/
|
*/
|
||||||
static inline int kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen)
|
static inline int kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
|
@ -15,17 +15,10 @@
|
|||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/userfaultfd_k.h>
|
#include <linux/userfaultfd_k.h>
|
||||||
|
|
||||||
#include <asm/sections.h>
|
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
static inline int is_kernel_rodata(unsigned long addr)
|
|
||||||
{
|
|
||||||
return addr >= (unsigned long)__start_rodata &&
|
|
||||||
addr < (unsigned long)__end_rodata;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kfree_const - conditionally free memory
|
* kfree_const - conditionally free memory
|
||||||
* @x: pointer to the memory
|
* @x: pointer to the memory
|
||||||
|
Loading…
x
Reference in New Issue
Block a user