diff options
| author | Haojie Li <lihaojie@kylinos.cn> | 2026-08-25 18:08:45 +0800 |
|---|---|---|
| committer | Chun-Kuang Hu <chunkuang.hu@kernel.org> | 2026-09-28 23:20:55 +0000 |
| commit | bce7698e2e6565bb765bd0522337f29f5f312624 (patch) | |
| tree | 0b735b7b4a27369cb4d75d9431b3ee59ce7e5bcc /tools/perf/util/parse-branch-options.c | |
| download | linux-stable-bce7698e2e6565bb765bd0522337f29f5f312624.tar.gz linux-stable-bce7698e2e6565bb765bd0522337f29f5f312624.zip | |
drm/mediatek: Add missing IS_ERR check for ovl_adaptor platform devicegrafted
platform_device_register_data() can fail and return an ERR_PTR, but the
return value is used without checking, leading to an invalid pointer
being stored in ddp_comp[].dev and passed to component_match_add() and
mtk_ddp_comp_init(), which could result in a kernel crash.
Add an IS_ERR() check to jump to the error handling path on failure.
Fixes: 0d9eee9118b7 ("drm/mediatek: Add drm ovl_adaptor sub driver for MT8195")
Cc: stable@vger.kernel.org
Signed-off-by: Haojie Li <lihaojie@kylinos.cn>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20260825100845.438893-1-lihaojie@kylinos.cn/
Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Diffstat (limited to 'tools/perf/util/parse-branch-options.c')
| -rw-r--r-- | tools/perf/util/parse-branch-options.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c new file mode 100644 index 000000000..f7f7aff3d --- /dev/null +++ b/tools/perf/util/parse-branch-options.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "util/debug.h" +#include "util/event.h" +#include <subcmd/parse-options.h> +#include "util/parse-branch-options.h" +#include <stdlib.h> +#include <string.h> + +#define BRANCH_OPT(n, m) \ + { .name = n, .mode = (m) } + +#define BRANCH_END { .name = NULL } + +struct branch_mode { + const char *name; + int mode; +}; + +static const struct branch_mode branch_modes[] = { + BRANCH_OPT("u", PERF_SAMPLE_BRANCH_USER), + BRANCH_OPT("k", PERF_SAMPLE_BRANCH_KERNEL), + BRANCH_OPT("hv", PERF_SAMPLE_BRANCH_HV), + BRANCH_OPT("any", PERF_SAMPLE_BRANCH_ANY), + BRANCH_OPT("any_call", PERF_SAMPLE_BRANCH_ANY_CALL), + BRANCH_OPT("any_ret", PERF_SAMPLE_BRANCH_ANY_RETURN), + BRANCH_OPT("ind_call", PERF_SAMPLE_BRANCH_IND_CALL), + BRANCH_OPT("abort_tx", PERF_SAMPLE_BRANCH_ABORT_TX), + BRANCH_OPT("in_tx", PERF_SAMPLE_BRANCH_IN_TX), + BRANCH_OPT("no_tx", PERF_SAMPLE_BRANCH_NO_TX), + BRANCH_OPT("cond", PERF_SAMPLE_BRANCH_COND), + BRANCH_OPT("ind_jmp", PERF_SAMPLE_BRANCH_IND_JUMP), + BRANCH_OPT("call", PERF_SAMPLE_BRANCH_CALL), + BRANCH_OPT("no_flags", PERF_SAMPLE_BRANCH_NO_FLAGS), + BRANCH_OPT("no_cycles", PERF_SAMPLE_BRANCH_NO_CYCLES), + BRANCH_OPT("save_type", PERF_SAMPLE_BRANCH_TYPE_SAVE), + BRANCH_OPT("stack", PERF_SAMPLE_BRANCH_CALL_STACK), + BRANCH_OPT("hw_index", PERF_SAMPLE_BRANCH_HW_INDEX), + BRANCH_OPT("priv", PERF_SAMPLE_BRANCH_PRIV_SAVE), + BRANCH_OPT("counter", PERF_SAMPLE_BRANCH_COUNTERS), + BRANCH_END +}; + +int parse_branch_str(const char *str, __u64 *mode) +{ +#define ONLY_PLM \ + (PERF_SAMPLE_BRANCH_USER |\ + PERF_SAMPLE_BRANCH_KERNEL |\ + PERF_SAMPLE_BRANCH_HV) + + int ret = 0; + char *p, *s; + char *os = NULL; + const struct branch_mode *br; + + if (str == NULL) { + *mode = PERF_SAMPLE_BRANCH_ANY; + return 0; + } + + /* because str is read-only */ + s = os = strdup(str); + if (!s) + return -1; + + for (;;) { + p = strchr(s, ','); + if (p) + *p = '\0'; + + for (br = branch_modes; br->name; br++) { + if (!strcasecmp(s, br->name)) + break; + } + if (!br->name) { + ret = -1; + pr_warning("unknown branch filter %s," + " check man page\n", s); + goto error; + } + + *mode |= br->mode; + + if (!p) + break; + + s = p + 1; + } + + /* default to any branch */ + if ((*mode & ~ONLY_PLM) == 0) { + *mode = PERF_SAMPLE_BRANCH_ANY; + } +error: + free(os); + return ret; +} + +int +parse_branch_stack(const struct option *opt, const char *str, int unset) +{ + __u64 *mode = (__u64 *)opt->value; + + if (unset) + return 0; + + /* + * cannot set it twice, -b + --branch-filter for instance + */ + if (*mode) { + pr_err("Error: Can't use --branch-any (-b) with --branch-filter (-j).\n"); + return -1; + } + + return parse_branch_str(str, mode); +} |
