]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Sun, 22 Oct 2023 13:38:08 +0000 (09:38 -0400)
committerSasha Levin <sashal@kernel.org>
Sun, 22 Oct 2023 13:38:08 +0000 (09:38 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.1/gpio-vf610-make-irq_chip-immutable.patch [new file with mode: 0644]
queue-6.1/gpio-vf610-mask-the-gpio-irq-in-system-suspend-and-s.patch [new file with mode: 0644]
queue-6.1/kallsyms-add-helper-kallsyms_on_each_match_symbol.patch [new file with mode: 0644]
queue-6.1/kallsyms-reduce-the-memory-occupied-by-kallsyms_seqs.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/tracing-kprobes-return-eaddrnotavail-when-func-match.patch [new file with mode: 0644]

diff --git a/queue-6.1/gpio-vf610-make-irq_chip-immutable.patch b/queue-6.1/gpio-vf610-make-irq_chip-immutable.patch
new file mode 100644 (file)
index 0000000..bef0b8d
--- /dev/null
@@ -0,0 +1,123 @@
+From f216efd067c1d347f5903e60a668c3bed41cd2c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 10:52:49 +0100
+Subject: gpio: vf610: make irq_chip immutable
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit e6ef4f8ede09f4af7cde000717b349b50bc62576 ]
+
+Since recently, the kernel is nagging about mutable irq_chips:
+
+    "not an immutable chip, please consider fixing it!"
+
+Drop the unneeded copy, flag it as IRQCHIP_IMMUTABLE, add the new
+helper functions and call the appropriate gpiolib functions.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Stable-dep-of: 430232619791 ("gpio: vf610: mask the gpio irq in system suspend and support wakeup")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-vf610.c | 41 ++++++++++++++++++++++-----------------
+ 1 file changed, 23 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
+index 21704eda97ae2..e8e34d648eb2a 100644
+--- a/drivers/gpio/gpio-vf610.c
++++ b/drivers/gpio/gpio-vf610.c
+@@ -30,7 +30,6 @@ struct fsl_gpio_soc_data {
+ struct vf610_gpio_port {
+       struct gpio_chip gc;
+-      struct irq_chip ic;
+       void __iomem *base;
+       void __iomem *gpio_base;
+       const struct fsl_gpio_soc_data *sdata;
+@@ -207,20 +206,24 @@ static int vf610_gpio_irq_set_type(struct irq_data *d, u32 type)
+ static void vf610_gpio_irq_mask(struct irq_data *d)
+ {
+-      struct vf610_gpio_port *port =
+-              gpiochip_get_data(irq_data_get_irq_chip_data(d));
+-      void __iomem *pcr_base = port->base + PORT_PCR(d->hwirq);
++      struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++      struct vf610_gpio_port *port = gpiochip_get_data(gc);
++      irq_hw_number_t gpio_num = irqd_to_hwirq(d);
++      void __iomem *pcr_base = port->base + PORT_PCR(gpio_num);
+       vf610_gpio_writel(0, pcr_base);
++      gpiochip_disable_irq(gc, gpio_num);
+ }
+ static void vf610_gpio_irq_unmask(struct irq_data *d)
+ {
+-      struct vf610_gpio_port *port =
+-              gpiochip_get_data(irq_data_get_irq_chip_data(d));
+-      void __iomem *pcr_base = port->base + PORT_PCR(d->hwirq);
++      struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++      struct vf610_gpio_port *port = gpiochip_get_data(gc);
++      irq_hw_number_t gpio_num = irqd_to_hwirq(d);
++      void __iomem *pcr_base = port->base + PORT_PCR(gpio_num);
+-      vf610_gpio_writel(port->irqc[d->hwirq] << PORT_PCR_IRQC_OFFSET,
++      gpiochip_enable_irq(gc, gpio_num);
++      vf610_gpio_writel(port->irqc[gpio_num] << PORT_PCR_IRQC_OFFSET,
+                         pcr_base);
+ }
+@@ -237,6 +240,17 @@ static int vf610_gpio_irq_set_wake(struct irq_data *d, u32 enable)
+       return 0;
+ }
++static const struct irq_chip vf610_irqchip = {
++      .name = "gpio-vf610",
++      .irq_ack = vf610_gpio_irq_ack,
++      .irq_mask = vf610_gpio_irq_mask,
++      .irq_unmask = vf610_gpio_irq_unmask,
++      .irq_set_type = vf610_gpio_irq_set_type,
++      .irq_set_wake = vf610_gpio_irq_set_wake,
++      .flags = IRQCHIP_IMMUTABLE,
++      GPIOCHIP_IRQ_RESOURCE_HELPERS,
++};
++
+ static void vf610_gpio_disable_clk(void *data)
+ {
+       clk_disable_unprepare(data);
+@@ -249,7 +263,6 @@ static int vf610_gpio_probe(struct platform_device *pdev)
+       struct vf610_gpio_port *port;
+       struct gpio_chip *gc;
+       struct gpio_irq_chip *girq;
+-      struct irq_chip *ic;
+       int i;
+       int ret;
+@@ -315,14 +328,6 @@ static int vf610_gpio_probe(struct platform_device *pdev)
+       gc->direction_output = vf610_gpio_direction_output;
+       gc->set = vf610_gpio_set;
+-      ic = &port->ic;
+-      ic->name = "gpio-vf610";
+-      ic->irq_ack = vf610_gpio_irq_ack;
+-      ic->irq_mask = vf610_gpio_irq_mask;
+-      ic->irq_unmask = vf610_gpio_irq_unmask;
+-      ic->irq_set_type = vf610_gpio_irq_set_type;
+-      ic->irq_set_wake = vf610_gpio_irq_set_wake;
+-
+       /* Mask all GPIO interrupts */
+       for (i = 0; i < gc->ngpio; i++)
+               vf610_gpio_writel(0, port->base + PORT_PCR(i));
+@@ -331,7 +336,7 @@ static int vf610_gpio_probe(struct platform_device *pdev)
+       vf610_gpio_writel(~0, port->base + PORT_ISFR);
+       girq = &gc->irq;
+-      girq->chip = ic;
++      gpio_irq_chip_set_chip(girq, &vf610_irqchip);
+       girq->parent_handler = vf610_gpio_irq_handler;
+       girq->num_parents = 1;
+       girq->parents = devm_kcalloc(&pdev->dev, 1,
+-- 
+2.42.0
+
diff --git a/queue-6.1/gpio-vf610-mask-the-gpio-irq-in-system-suspend-and-s.patch b/queue-6.1/gpio-vf610-mask-the-gpio-irq-in-system-suspend-and-s.patch
new file mode 100644 (file)
index 0000000..2ca39b1
--- /dev/null
@@ -0,0 +1,42 @@
+From 1d17fb0ca6822b373e00acdf113e1985e5ce3362 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Oct 2023 18:42:36 +0800
+Subject: gpio: vf610: mask the gpio irq in system suspend and support wakeup
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit 430232619791e7de95191f2cd8ebaa4c380d17d0 ]
+
+Add flag IRQCHIP_MASK_ON_SUSPEND to make sure gpio irq is masked on
+suspend, if lack this flag, current irq arctitecture will not mask
+the irq, and these unmasked gpio irq will wrongly wakeup the system
+even they are not config as wakeup source.
+
+Also add flag IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND to make sure the gpio
+irq which is configed as wakeup source can work as expect.
+
+Fixes: 7f2691a19627 ("gpio: vf610: add gpiolib/IRQ chip driver for Vybrid")
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-vf610.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
+index e8e34d648eb2a..314dfaa633857 100644
+--- a/drivers/gpio/gpio-vf610.c
++++ b/drivers/gpio/gpio-vf610.c
+@@ -247,7 +247,8 @@ static const struct irq_chip vf610_irqchip = {
+       .irq_unmask = vf610_gpio_irq_unmask,
+       .irq_set_type = vf610_gpio_irq_set_type,
+       .irq_set_wake = vf610_gpio_irq_set_wake,
+-      .flags = IRQCHIP_IMMUTABLE,
++      .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND
++                      | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND,
+       GPIOCHIP_IRQ_RESOURCE_HELPERS,
+ };
+-- 
+2.42.0
+
diff --git a/queue-6.1/kallsyms-add-helper-kallsyms_on_each_match_symbol.patch b/queue-6.1/kallsyms-add-helper-kallsyms_on_each_match_symbol.patch
new file mode 100644 (file)
index 0000000..e9ac3fa
--- /dev/null
@@ -0,0 +1,93 @@
+From f9ed37754439dd8a21af51ac73cb9252b80e1980 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 16:49:17 +0800
+Subject: kallsyms: Add helper kallsyms_on_each_match_symbol()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit 4dc533e0f2c04174e1ae4aa98e7cffc1c04b9998 ]
+
+Function kallsyms_on_each_symbol() traverses all symbols and submits each
+symbol to the hook 'fn' for judgment and processing. For some cases, the
+hook actually only handles the matched symbol, such as livepatch.
+
+Because all symbols are currently sorted by name, all the symbols with the
+same name are clustered together. Function kallsyms_lookup_names() gets
+the start and end positions of the set corresponding to the specified
+name. So we can easily and quickly traverse all the matches.
+
+The test results are as follows (twice): (x86)
+kallsyms_on_each_match_symbol:     7454,     7984
+kallsyms_on_each_symbol      : 11733809, 11785803
+
+kallsyms_on_each_match_symbol() consumes only 0.066% of
+kallsyms_on_each_symbol()'s time. In other words, 1523x better
+performance.
+
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
+Stable-dep-of: b022f0c7e404 ("tracing/kprobes: Return EADDRNOTAVAIL when func matches several symbols")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/kallsyms.h |  8 ++++++++
+ kernel/kallsyms.c        | 18 ++++++++++++++++++
+ 2 files changed, 26 insertions(+)
+
+diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
+index 649faac31ddb1..0cd33be7142ad 100644
+--- a/include/linux/kallsyms.h
++++ b/include/linux/kallsyms.h
+@@ -69,6 +69,8 @@ static inline void *dereference_symbol_descriptor(void *ptr)
+ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
+                                     unsigned long),
+                           void *data);
++int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long),
++                                const char *name, void *data);
+ /* Lookup the address for a symbol. Returns 0 if not found. */
+ unsigned long kallsyms_lookup_name(const char *name);
+@@ -168,6 +170,12 @@ static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct
+ {
+       return -EOPNOTSUPP;
+ }
++
++static inline int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long),
++                                              const char *name, void *data)
++{
++      return -EOPNOTSUPP;
++}
+ #endif /*CONFIG_KALLSYMS*/
+ static inline void print_ip_sym(const char *loglvl, unsigned long ip)
+diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
+index 32cba13eee6c4..824bcc7b5dbc3 100644
+--- a/kernel/kallsyms.c
++++ b/kernel/kallsyms.c
+@@ -303,6 +303,24 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
+       return 0;
+ }
++int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long),
++                                const char *name, void *data)
++{
++      int ret;
++      unsigned int i, start, end;
++
++      ret = kallsyms_lookup_names(name, &start, &end);
++      if (ret)
++              return 0;
++
++      for (i = start; !ret && i <= end; i++) {
++              ret = fn(data, kallsyms_sym_address(get_symbol_seq(i)));
++              cond_resched();
++      }
++
++      return ret;
++}
++
+ static unsigned long get_symbol_pos(unsigned long addr,
+                                   unsigned long *symbolsize,
+                                   unsigned long *offset)
+-- 
+2.42.0
+
diff --git a/queue-6.1/kallsyms-reduce-the-memory-occupied-by-kallsyms_seqs.patch b/queue-6.1/kallsyms-reduce-the-memory-occupied-by-kallsyms_seqs.patch
new file mode 100644 (file)
index 0000000..1754336
--- /dev/null
@@ -0,0 +1,112 @@
+From 18214a40057302d737712006a31558d84d13cb07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 16:49:16 +0800
+Subject: kallsyms: Reduce the memory occupied by kallsyms_seqs_of_names[]
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit 19bd8981dc2ee35fdc81ab1b0104b607c917d470 ]
+
+kallsyms_seqs_of_names[] records the symbol index sorted by address, the
+maximum value in kallsyms_seqs_of_names[] is the number of symbols. And
+2^24 = 16777216, which means that three bytes are enough to store the
+index. This can help us save (1 * kallsyms_num_syms) bytes of memory.
+
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
+Stable-dep-of: b022f0c7e404 ("tracing/kprobes: Return EADDRNOTAVAIL when func matches several symbols")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kallsyms.c          | 18 ++++++++++++++----
+ kernel/kallsyms_internal.h |  2 +-
+ scripts/kallsyms.c         |  5 ++++-
+ 3 files changed, 19 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
+index ad3cccb0970f8..32cba13eee6c4 100644
+--- a/kernel/kallsyms.c
++++ b/kernel/kallsyms.c
+@@ -197,6 +197,16 @@ static int compare_symbol_name(const char *name, char *namebuf)
+       return strcmp(name, namebuf);
+ }
++static unsigned int get_symbol_seq(int index)
++{
++      unsigned int i, seq = 0;
++
++      for (i = 0; i < 3; i++)
++              seq = (seq << 8) | kallsyms_seqs_of_names[3 * index + i];
++
++      return seq;
++}
++
+ static int kallsyms_lookup_names(const char *name,
+                                unsigned int *start,
+                                unsigned int *end)
+@@ -211,7 +221,7 @@ static int kallsyms_lookup_names(const char *name,
+       while (low <= high) {
+               mid = low + (high - low) / 2;
+-              seq = kallsyms_seqs_of_names[mid];
++              seq = get_symbol_seq(mid);
+               off = get_symbol_offset(seq);
+               kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
+               ret = compare_symbol_name(name, namebuf);
+@@ -228,7 +238,7 @@ static int kallsyms_lookup_names(const char *name,
+       low = mid;
+       while (low) {
+-              seq = kallsyms_seqs_of_names[low - 1];
++              seq = get_symbol_seq(low - 1);
+               off = get_symbol_offset(seq);
+               kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
+               if (compare_symbol_name(name, namebuf))
+@@ -240,7 +250,7 @@ static int kallsyms_lookup_names(const char *name,
+       if (end) {
+               high = mid;
+               while (high < kallsyms_num_syms - 1) {
+-                      seq = kallsyms_seqs_of_names[high + 1];
++                      seq = get_symbol_seq(high + 1);
+                       off = get_symbol_offset(seq);
+                       kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
+                       if (compare_symbol_name(name, namebuf))
+@@ -265,7 +275,7 @@ unsigned long kallsyms_lookup_name(const char *name)
+       ret = kallsyms_lookup_names(name, &i, NULL);
+       if (!ret)
+-              return kallsyms_sym_address(kallsyms_seqs_of_names[i]);
++              return kallsyms_sym_address(get_symbol_seq(i));
+       return module_kallsyms_lookup_name(name);
+ }
+diff --git a/kernel/kallsyms_internal.h b/kernel/kallsyms_internal.h
+index a04b7a5cb1e3e..27fabdcc40f57 100644
+--- a/kernel/kallsyms_internal.h
++++ b/kernel/kallsyms_internal.h
+@@ -26,6 +26,6 @@ extern const char kallsyms_token_table[] __weak;
+ extern const u16 kallsyms_token_index[] __weak;
+ extern const unsigned int kallsyms_markers[] __weak;
+-extern const unsigned int kallsyms_seqs_of_names[] __weak;
++extern const u8 kallsyms_seqs_of_names[] __weak;
+ #endif // LINUX_KALLSYMS_INTERNAL_H_
+diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
+index 80aab2aa72246..ff8cce1757849 100644
+--- a/scripts/kallsyms.c
++++ b/scripts/kallsyms.c
+@@ -602,7 +602,10 @@ static void write_src(void)
+       sort_symbols_by_name();
+       output_label("kallsyms_seqs_of_names");
+       for (i = 0; i < table_cnt; i++)
+-              printf("\t.long\t%u\n", table[i]->seq);
++              printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n",
++                      (unsigned char)(table[i]->seq >> 16),
++                      (unsigned char)(table[i]->seq >> 8),
++                      (unsigned char)(table[i]->seq >> 0));
+       printf("\n");
+       output_label("kallsyms_token_table");
+-- 
+2.42.0
+
index a6247e928dcc9c5c724b3d8a64fb077dc32de97c..58398e0f0f123c477216815070bce09a09512f6c 100644 (file)
@@ -197,3 +197,8 @@ asoc-pxa-fix-a-memory-leak-in-probe.patch
 drm-bridge-ti-sn65dsi86-associate-dsi-device-lifetim.patch
 drm-panel-move-aux-b116xw03-out-of-panel-edp-back-to.patch
 net-make-sure-we-never-create-ifindex-0.patch
+kallsyms-reduce-the-memory-occupied-by-kallsyms_seqs.patch
+kallsyms-add-helper-kallsyms_on_each_match_symbol.patch
+tracing-kprobes-return-eaddrnotavail-when-func-match.patch
+gpio-vf610-make-irq_chip-immutable.patch
+gpio-vf610-mask-the-gpio-irq-in-system-suspend-and-s.patch
diff --git a/queue-6.1/tracing-kprobes-return-eaddrnotavail-when-func-match.patch b/queue-6.1/tracing-kprobes-return-eaddrnotavail-when-func-match.patch
new file mode 100644 (file)
index 0000000..818f8c6
--- /dev/null
@@ -0,0 +1,146 @@
+From 9468438bbdbb8b931f03c04f94dc5fccda49e845 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 13:42:49 +0300
+Subject: tracing/kprobes: Return EADDRNOTAVAIL when func matches several
+ symbols
+
+From: Francis Laniel <flaniel@linux.microsoft.com>
+
+[ Upstream commit b022f0c7e404887a7c5229788fc99eff9f9a80d5 ]
+
+When a kprobe is attached to a function that's name is not unique (is
+static and shares the name with other functions in the kernel), the
+kprobe is attached to the first function it finds. This is a bug as the
+function that it is attaching to is not necessarily the one that the
+user wants to attach to.
+
+Instead of blindly picking a function to attach to what is ambiguous,
+error with EADDRNOTAVAIL to let the user know that this function is not
+unique, and that the user must use another unique function with an
+address offset to get to the function they want to attach to.
+
+Link: https://lore.kernel.org/all/20231020104250.9537-2-flaniel@linux.microsoft.com/
+
+Cc: stable@vger.kernel.org
+Fixes: 413d37d1eb69 ("tracing: Add kprobe-based event tracer")
+Suggested-by: Masami Hiramatsu <mhiramat@kernel.org>
+Signed-off-by: Francis Laniel <flaniel@linux.microsoft.com>
+Link: https://lore.kernel.org/lkml/20230819101105.b0c104ae4494a7d1f2eea742@kernel.org/
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_kprobe.c | 63 +++++++++++++++++++++++++++++++++++++
+ kernel/trace/trace_probe.h  |  1 +
+ 2 files changed, 64 insertions(+)
+
+diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
+index 5a75b039e5860..22852029c6924 100644
+--- a/kernel/trace/trace_kprobe.c
++++ b/kernel/trace/trace_kprobe.c
+@@ -705,6 +705,25 @@ static struct notifier_block trace_kprobe_module_nb = {
+       .priority = 1   /* Invoked after kprobe module callback */
+ };
++static int count_symbols(void *data, unsigned long unused)
++{
++      unsigned int *count = data;
++
++      (*count)++;
++
++      return 0;
++}
++
++static unsigned int number_of_same_symbols(char *func_name)
++{
++      unsigned int count;
++
++      count = 0;
++      kallsyms_on_each_match_symbol(count_symbols, func_name, &count);
++
++      return count;
++}
++
+ static int __trace_kprobe_create(int argc, const char *argv[])
+ {
+       /*
+@@ -834,6 +853,31 @@ static int __trace_kprobe_create(int argc, const char *argv[])
+               }
+       }
++      if (symbol && !strchr(symbol, ':')) {
++              unsigned int count;
++
++              count = number_of_same_symbols(symbol);
++              if (count > 1) {
++                      /*
++                       * Users should use ADDR to remove the ambiguity of
++                       * using KSYM only.
++                       */
++                      trace_probe_log_err(0, NON_UNIQ_SYMBOL);
++                      ret = -EADDRNOTAVAIL;
++
++                      goto error;
++              } else if (count == 0) {
++                      /*
++                       * We can return ENOENT earlier than when register the
++                       * kprobe.
++                       */
++                      trace_probe_log_err(0, BAD_PROBE_ADDR);
++                      ret = -ENOENT;
++
++                      goto error;
++              }
++      }
++
+       trace_probe_log_set_index(0);
+       if (event) {
+               ret = traceprobe_parse_event_name(&event, &group, gbuf,
+@@ -1744,6 +1788,7 @@ static int unregister_kprobe_event(struct trace_kprobe *tk)
+ }
+ #ifdef CONFIG_PERF_EVENTS
++
+ /* create a trace_kprobe, but don't add it to global lists */
+ struct trace_event_call *
+ create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
+@@ -1754,6 +1799,24 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
+       int ret;
+       char *event;
++      if (func) {
++              unsigned int count;
++
++              count = number_of_same_symbols(func);
++              if (count > 1)
++                      /*
++                       * Users should use addr to remove the ambiguity of
++                       * using func only.
++                       */
++                      return ERR_PTR(-EADDRNOTAVAIL);
++              else if (count == 0)
++                      /*
++                       * We can return ENOENT earlier than when register the
++                       * kprobe.
++                       */
++                      return ERR_PTR(-ENOENT);
++      }
++
+       /*
+        * local trace_kprobes are not added to dyn_event, so they are never
+        * searched in find_trace_kprobe(). Therefore, there is no concern of
+diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
+index f41c330bd60f1..f48b3ed20b095 100644
+--- a/kernel/trace/trace_probe.h
++++ b/kernel/trace/trace_probe.h
+@@ -404,6 +404,7 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call,
+       C(BAD_MAXACT,           "Invalid maxactive number"),            \
+       C(MAXACT_TOO_BIG,       "Maxactive is too big"),                \
+       C(BAD_PROBE_ADDR,       "Invalid probed address or symbol"),    \
++      C(NON_UNIQ_SYMBOL,      "The symbol is not unique"),            \
+       C(BAD_RETPROBE,         "Retprobe address must be an function entry"), \
+       C(BAD_ADDR_SUFFIX,      "Invalid probed address suffix"), \
+       C(NO_GROUP_NAME,        "Group name is not specified"),         \
+-- 
+2.42.0
+