From 6668ed271eaefaa63e686bdfbedaeb7b8e492722 Mon Sep 17 00:00:00 2001 From: Kumar Kartikeya Dwivedi Date: Fri, 4 Sep 2026 10:43:19 +0200 Subject: selftests/bpf: Reject graph kptr use after RCU unlock 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 Link: https://lore.kernel.org/r/20260904084325.52250-7-memxor@gmail.com Signed-off-by: Alexei Starovoitov --- drivers/pinctrl/aspeed/pinctrl-aspeed.h | 119 ++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 drivers/pinctrl/aspeed/pinctrl-aspeed.h (limited to 'drivers/pinctrl/aspeed/pinctrl-aspeed.h') diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.h b/drivers/pinctrl/aspeed/pinctrl-aspeed.h new file mode 100644 index 000000000..28f3bde25 --- /dev/null +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2016 IBM Corp. + */ + +#ifndef PINCTRL_ASPEED +#define PINCTRL_ASPEED + +#include +#include +#include +#include +#include + +#include "pinmux-aspeed.h" + +/** + * @param The pinconf parameter type + * @pins The pin range this config struct covers, [low, high] + * @reg The register housing the configuration bits + * @mask The mask to select the bits of interest in @reg + */ +struct aspeed_pin_config { + enum pin_config_param param; + unsigned int pins[2]; + unsigned int reg; + u32 mask; +}; + +#define ASPEED_PINCTRL_PIN(name_) \ + [name_] = { \ + .number = name_, \ + .name = #name_, \ + .drv_data = (void *) &(PIN_SYM(name_)) \ + } + +#define ASPEED_SB_PINCONF(param_, pin0_, pin1_, reg_, bit_) { \ + .param = param_, \ + .pins = {pin0_, pin1_}, \ + .reg = reg_, \ + .mask = BIT_MASK(bit_) \ +} + +#define ASPEED_PULL_DOWN_PINCONF(pin_, reg_, bit_) \ + ASPEED_SB_PINCONF(PIN_CONFIG_BIAS_PULL_DOWN, pin_, pin_, reg_, bit_), \ + ASPEED_SB_PINCONF(PIN_CONFIG_BIAS_DISABLE, pin_, pin_, reg_, bit_) + +#define ASPEED_PULL_UP_PINCONF(pin_, reg_, bit_) \ + ASPEED_SB_PINCONF(PIN_CONFIG_BIAS_PULL_UP, pin_, pin_, reg_, bit_), \ + ASPEED_SB_PINCONF(PIN_CONFIG_BIAS_DISABLE, pin_, pin_, reg_, bit_) +/* + * Aspeed pin configuration description. + * + * @param: pinconf configuration parameter + * @arg: The supported argument for @param, or -1 if any value is supported + * @val: The register value to write to configure @arg for @param + * @mask: The bitfield mask for @val + * + * The map is to be used in conjunction with the configuration array supplied + * by the driver implementation. + */ +struct aspeed_pin_config_map { + enum pin_config_param param; + s32 arg; + u32 val; + u32 mask; +}; + +struct aspeed_pinctrl_data { + struct regmap *scu; + + const struct pinctrl_pin_desc *pins; + const unsigned int npins; + + const struct aspeed_pin_config *configs; + const unsigned int nconfigs; + + struct aspeed_pinmux_data pinmux; + + const struct aspeed_pin_config_map *confmaps; + const unsigned int nconfmaps; +}; + +/* Aspeed pinctrl helpers */ +int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev); +const char *aspeed_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned int group); +int aspeed_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int group, const unsigned int **pins, + unsigned int *npins); +void aspeed_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, unsigned int offset); +int aspeed_pinmux_get_fn_count(struct pinctrl_dev *pctldev); +const char *aspeed_pinmux_get_fn_name(struct pinctrl_dev *pctldev, + unsigned int function); +int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev, + unsigned int function, const char * const **groups, + unsigned int * const num_groups); +int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, + unsigned int group); +int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset); +int aspeed_pinctrl_probe(struct platform_device *pdev, + const struct pinctrl_desc *pdesc, + struct aspeed_pinctrl_data *pdata); +int aspeed_pin_config_get(struct pinctrl_dev *pctldev, unsigned int offset, + unsigned long *config); +int aspeed_pin_config_set(struct pinctrl_dev *pctldev, unsigned int offset, + unsigned long *configs, unsigned int num_configs); +int aspeed_pin_config_group_get(struct pinctrl_dev *pctldev, + unsigned int selector, + unsigned long *config); +int aspeed_pin_config_group_set(struct pinctrl_dev *pctldev, + unsigned int selector, + unsigned long *configs, + unsigned int num_configs); + +#endif /* PINCTRL_ASPEED */ -- cgit v1.3.1