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 /arch/mips/ralink/mt7620.c | |
| 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 'arch/mips/ralink/mt7620.c')
| -rw-r--r-- | arch/mips/ralink/mt7620.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c new file mode 100644 index 000000000..c5f1ebce0 --- /dev/null +++ b/arch/mips/ralink/mt7620.c @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * + * Parts of this file are based on Ralink's 2.6.21 BSP + * + * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> + * Copyright (C) 2013 John Crispin <john@phrozen.org> + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/bug.h> +#include <linux/slab.h> +#include <linux/sys_soc.h> + +#include <asm/mipsregs.h> +#include <asm/mach-ralink/ralink_regs.h> +#include <asm/mach-ralink/mt7620.h> + +#include "common.h" + +/* analog */ +#define PMU0_CFG 0x88 +#define PMU_SW_SET BIT(28) +#define A_DCDC_EN BIT(24) +#define A_SSC_PERI BIT(19) +#define A_SSC_GEN BIT(18) +#define A_SSC_M 0x3 +#define A_SSC_S 16 +#define A_DLY_M 0x7 +#define A_DLY_S 8 +#define A_VTUNE_M 0xff + +/* digital */ +#define PMU1_CFG 0x8C +#define DIG_SW_SEL BIT(25) + +/* EFUSE bits */ +#define EFUSE_MT7688 0x100000 + +/* DRAM type bit */ +#define DRAM_TYPE_MT7628_MASK 0x1 + +/* does the board have sdram or ddram */ +static int dram_type; + +static struct ralink_soc_info *soc_info_ptr; + +static __init void +mt7620_dram_init(struct ralink_soc_info *soc_info) +{ + switch (dram_type) { + case SYSCFG0_DRAM_TYPE_SDRAM: + pr_info("Board has SDRAM\n"); + soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN; + soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX; + break; + + case SYSCFG0_DRAM_TYPE_DDR1: + pr_info("Board has DDR1\n"); + soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; + soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; + break; + + case SYSCFG0_DRAM_TYPE_DDR2: + pr_info("Board has DDR2\n"); + soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; + soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; + break; + default: + BUG(); + } +} + +static __init void +mt7628_dram_init(struct ralink_soc_info *soc_info) +{ + switch (dram_type) { + case SYSCFG0_DRAM_TYPE_DDR1_MT7628: + pr_info("Board has DDR1\n"); + soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; + soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; + break; + + case SYSCFG0_DRAM_TYPE_DDR2_MT7628: + pr_info("Board has DDR2\n"); + soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; + soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; + break; + default: + BUG(); + } +} + +static unsigned int __init mt7620_get_soc_name0(void) +{ + return __raw_readl(MT7620_SYSC_BASE + SYSC_REG_CHIP_NAME0); +} + +static unsigned int __init mt7620_get_soc_name1(void) +{ + return __raw_readl(MT7620_SYSC_BASE + SYSC_REG_CHIP_NAME1); +} + +static bool __init mt7620_soc_valid(void) +{ + if (mt7620_get_soc_name0() == MT7620_CHIP_NAME0 && + mt7620_get_soc_name1() == MT7620_CHIP_NAME1) + return true; + else + return false; +} + +static bool __init mt7628_soc_valid(void) +{ + if (mt7620_get_soc_name0() == MT7620_CHIP_NAME0 && + mt7620_get_soc_name1() == MT7628_CHIP_NAME1) + return true; + else + return false; +} + +static unsigned int __init mt7620_get_rev(void) +{ + return __raw_readl(MT7620_SYSC_BASE + SYSC_REG_CHIP_REV); +} + +static unsigned int __init mt7620_get_bga(void) +{ + return (mt7620_get_rev() >> CHIP_REV_PKG_SHIFT) & CHIP_REV_PKG_MASK; +} + +static unsigned int __init mt7620_get_efuse(void) +{ + return __raw_readl(MT7620_SYSC_BASE + SYSC_REG_EFUSE_CFG); +} + +static unsigned int __init mt7620_get_soc_ver(void) +{ + return (mt7620_get_rev() >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK; +} + +static unsigned int __init mt7620_get_soc_eco(void) +{ + return (mt7620_get_rev() & CHIP_REV_ECO_MASK); +} + +static const char __init *mt7620_get_soc_name(struct ralink_soc_info *soc_info) +{ + if (mt7620_soc_valid()) { + u32 bga = mt7620_get_bga(); + + if (bga) { + ralink_soc = MT762X_SOC_MT7620A; + soc_info->compatible = "ralink,mt7620a-soc"; + return "MT7620A"; + } else { + ralink_soc = MT762X_SOC_MT7620N; + soc_info->compatible = "ralink,mt7620n-soc"; + return "MT7620N"; + } + } else if (mt7628_soc_valid()) { + u32 efuse = mt7620_get_efuse(); + unsigned char *name = NULL; + + if (efuse & EFUSE_MT7688) { + ralink_soc = MT762X_SOC_MT7688; + name = "MT7688"; + } else { + ralink_soc = MT762X_SOC_MT7628AN; + name = "MT7628AN"; + } + soc_info->compatible = "ralink,mt7628an-soc"; + return name; + } else { + panic("mt762x: unknown SoC, n0:%08x n1:%08x\n", + mt7620_get_soc_name0(), mt7620_get_soc_name1()); + } +} + +static const char __init *mt7620_get_soc_id_name(void) +{ + if (ralink_soc == MT762X_SOC_MT7620A) + return "mt7620a"; + else if (ralink_soc == MT762X_SOC_MT7620N) + return "mt7620n"; + else if (ralink_soc == MT762X_SOC_MT7688) + return "mt7688"; + else if (ralink_soc == MT762X_SOC_MT7628AN) + return "mt7628n"; + else + return "invalid"; +} + +static int __init mt7620_soc_dev_init(void) +{ + struct soc_device *soc_dev; + struct soc_device_attribute *soc_dev_attr; + + soc_dev_attr = kzalloc_obj(*soc_dev_attr); + if (!soc_dev_attr) + return -ENOMEM; + + soc_dev_attr->family = "Ralink"; + soc_dev_attr->soc_id = mt7620_get_soc_id_name(); + + soc_dev_attr->data = soc_info_ptr; + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr); + return PTR_ERR(soc_dev); + } + + return 0; +} +device_initcall(mt7620_soc_dev_init); + +void __init prom_soc_init(struct ralink_soc_info *soc_info) +{ + const char *name = mt7620_get_soc_name(soc_info); + u32 cfg0; + u32 pmu0; + u32 pmu1; + + snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, + "MediaTek %s ver:%u eco:%u", + name, mt7620_get_soc_ver(), mt7620_get_soc_eco()); + + cfg0 = __raw_readl(MT7620_SYSC_BASE + SYSC_REG_SYSTEM_CONFIG0); + if (is_mt76x8()) { + dram_type = cfg0 & DRAM_TYPE_MT7628_MASK; + } else { + dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & + SYSCFG0_DRAM_TYPE_MASK; + if (dram_type == SYSCFG0_DRAM_TYPE_UNKNOWN) + dram_type = SYSCFG0_DRAM_TYPE_SDRAM; + } + + soc_info->mem_base = MT7620_DRAM_BASE; + if (is_mt76x8()) + mt7628_dram_init(soc_info); + else + mt7620_dram_init(soc_info); + + pmu0 = __raw_readl(MT7620_SYSC_BASE + PMU0_CFG); + pmu1 = __raw_readl(MT7620_SYSC_BASE + PMU1_CFG); + + pr_info("Analog PMU set to %s control\n", + (pmu0 & PMU_SW_SET) ? ("sw") : ("hw")); + pr_info("Digital PMU set to %s control\n", + (pmu1 & DIG_SW_SEL) ? ("sw") : ("hw")); + + soc_info_ptr = soc_info; +} |
