diff options
| author | Kumar Kartikeya Dwivedi <memxor@gmail.com> | 2026-09-04 10:43:19 +0200 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-09-04 07:58:36 -0700 |
| commit | 6668ed271eaefaa63e686bdfbedaeb7b8e492722 (patch) | |
| tree | 58e8288fead484f6755ad0815fc74c3742663761 /drivers/pinctrl/pinmux.h | |
| download | linux-stable-6668ed271eaefaa63e686bdfbedaeb7b8e492722.tar.gz linux-stable-6668ed271eaefaa63e686bdfbedaeb7b8e492722.zip | |
selftests/bpf: Reject graph kptr use after RCU unlockgrafted
Add a sleepable verifier test that loads a graph-node local kptr in an
explicit RCU read-side critical section, then passes its node to
bpf_rbtree_remove() after the section ends.
Before the verifier fix, the stale NON_OWN_REF flag makes the node look like
a live borrowed reference and the program is accepted. After the fix, the
pointer is demoted without NON_OWN_REF and the graph kfunc argument is
rejected.
Also exercise a graph kptr loaded while a spin lock provides implicit RCU
protection. The pointer must be invalidated when the lock is released, which
guards the required ordering between non-owning-reference invalidation and
RCU demotion.
Update the existing fault-protected load test state description. The
post-unlock pointer no longer carries NON_OWN_REF, but remains readable
because the load is rewritten to use BPF_PROBE_MEM.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260904084325.52250-7-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'drivers/pinctrl/pinmux.h')
| -rw-r--r-- | drivers/pinctrl/pinmux.h | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h new file mode 100644 index 000000000..4e826c1a5 --- /dev/null +++ b/drivers/pinctrl/pinmux.h @@ -0,0 +1,181 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Internal interface between the core pin control system and the + * pinmux portions + * + * Copyright (C) 2011 ST-Ericsson SA + * Written on behalf of Linaro for ST-Ericsson + * Based on bits of regulator core, gpio core and clk core + * + * Author: Linus Walleij <linus.walleij@linaro.org> + */ + +#include <linux/types.h> + +struct dentry; +struct seq_file; + +struct pinctrl_dev; +struct pinctrl_gpio_range; +struct pinctrl_map; +struct pinctrl_setting; + +#ifdef CONFIG_PINMUX + +int pinmux_check_ops(struct pinctrl_dev *pctldev); + +int pinmux_validate_map(const struct pinctrl_map *map, int i); + +bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev, unsigned int pin); + +int pinmux_request_gpio(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin, unsigned int gpio); +void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned int pin, + struct pinctrl_gpio_range *range); +int pinmux_gpio_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin, bool input); + +int pinmux_map_to_setting(const struct pinctrl_map *map, + struct pinctrl_setting *setting); +void pinmux_free_setting(const struct pinctrl_setting *setting); +int pinmux_enable_setting(const struct pinctrl_setting *setting); +void pinmux_disable_setting(const struct pinctrl_setting *setting); + +#else + +static inline int pinmux_check_ops(struct pinctrl_dev *pctldev) +{ + return 0; +} + +static inline int pinmux_validate_map(const struct pinctrl_map *map, int i) +{ + return 0; +} + +static inline bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev, + unsigned int pin) +{ + return true; +} + +static inline int pinmux_request_gpio(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin, unsigned int gpio) +{ + return 0; +} + +static inline void pinmux_free_gpio(struct pinctrl_dev *pctldev, + unsigned int pin, + struct pinctrl_gpio_range *range) +{ +} + +static inline int pinmux_gpio_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin, bool input) +{ + return 0; +} + +static inline int pinmux_map_to_setting(const struct pinctrl_map *map, + struct pinctrl_setting *setting) +{ + return 0; +} + +static inline void pinmux_free_setting(const struct pinctrl_setting *setting) +{ +} + +static inline int pinmux_enable_setting(const struct pinctrl_setting *setting) +{ + return 0; +} + +static inline void pinmux_disable_setting(const struct pinctrl_setting *setting) +{ +} + +#endif + +#if defined(CONFIG_PINMUX) && defined(CONFIG_DEBUG_FS) + +void pinmux_show_map(struct seq_file *s, const struct pinctrl_map *map); +void pinmux_show_setting(struct seq_file *s, + const struct pinctrl_setting *setting); +void pinmux_init_device_debugfs(struct dentry *devroot, + struct pinctrl_dev *pctldev); + +#else + +static inline void pinmux_show_map(struct seq_file *s, + const struct pinctrl_map *map) +{ +} + +static inline void pinmux_show_setting(struct seq_file *s, + const struct pinctrl_setting *setting) +{ +} + +static inline void pinmux_init_device_debugfs(struct dentry *devroot, + struct pinctrl_dev *pctldev) +{ +} + +#endif + +#ifdef CONFIG_GENERIC_PINMUX_FUNCTIONS + +/** + * struct function_desc - generic function descriptor + * @func: generic data of the pin function (name and groups of pins) + * @data: pin controller driver specific data + */ +struct function_desc { + const struct pinfunction *func; + void *data; +}; + +int pinmux_generic_get_function_count(struct pinctrl_dev *pctldev); + +const char * +pinmux_generic_get_function_name(struct pinctrl_dev *pctldev, + unsigned int selector); + +int pinmux_generic_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned int * const ngroups); + +const struct function_desc * +pinmux_generic_get_function(struct pinctrl_dev *pctldev, unsigned int selector); + +int pinmux_generic_add_function(struct pinctrl_dev *pctldev, + const char *name, + const char * const *groups, + unsigned int const ngroups, + void *data); + +int pinmux_generic_add_pinfunction(struct pinctrl_dev *pctldev, + const struct pinfunction *func, void *data); + +int pinmux_generic_remove_function(struct pinctrl_dev *pctldev, + unsigned int selector); + +void pinmux_generic_free_functions(struct pinctrl_dev *pctldev); + +bool pinmux_generic_function_is_gpio(struct pinctrl_dev *pctldev, + unsigned int selector); + +#else + +static inline void pinmux_generic_free_functions(struct pinctrl_dev *pctldev) +{ +} + +#endif /* CONFIG_GENERIC_PINMUX_FUNCTIONS */ |
