[PATCH] test: self: mmu: skip false positive test fail when no RAM at address 0

2023-11-09 Thread Ahmad Fatoum
Testing zero_page_access only makes sense if we actually have RAM at
address 0 that we may read from. If it happens to I/O memory, the SoC
may hang or a data abort may be raised, which would make the test fail.

Avoid this by explicitly checking for that case and skipping the test
without running.

Signed-off-by: Ahmad Fatoum 
---
 test/self/mmu.c | 33 ++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/test/self/mmu.c b/test/self/mmu.c
index ca58d718ffb3..58961daaab95 100644
--- a/test/self/mmu.c
+++ b/test/self/mmu.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define TEST_BUFFER_SIZE   SZ_1M
 #define TEST_BUFFER_ALIGN  SZ_4K
@@ -171,6 +172,34 @@ static void test_remap(void)
free(mirror);
 }
 
+static bool zero_page_access_ok(void)
+{
+   struct memory_bank *bank;
+   const char *reason;
+   struct resource null_res = {
+   .name = "null",
+   .flags = IORESOURCE_MEM,
+   .start = 0,
+   .end = sizeof(int) - 1,
+   };
+
+   if (!IS_ENABLED(CONFIG_ARCH_HAS_ZERO_PAGE)) {
+   reason = "CONFIG_ARCH_HAS_ZERO_PAGE=n";
+   goto not_ok;
+   }
+
+   for_each_memory_bank(bank) {
+   if (resource_contains(bank->res, &null_res))
+   return true;
+   }
+
+   reason = "no memory at address zero";
+
+not_ok:
+   pr_info("skipping rest of zero page tests because %s\n", reason);
+   return false;
+}
+
 static void test_zero_page(void)
 {
void __iomem *null = NULL;
@@ -197,9 +226,7 @@ static void test_zero_page(void)
failed_tests++;
}
 
-   if (!IS_ENABLED(CONFIG_ARCH_HAS_ZERO_PAGE)) {
-   pr_info("skipping %s because %s=n\n",
-   "CONFIG_ARCH_HAS_ZERO_PAGE", __func__);
+   if (!zero_page_access_ok()) {
skipped_tests += 2;
return;
}
-- 
2.39.2




[PATCH] test: self: malloc: hide allocation size from compiler

2023-11-09 Thread Ahmad Fatoum
Once we start annotating malloc with __attribute((alloc_size)), GCC will
detect that we intentionally buffers that are too big.

Avoid the warning by hiding the size using the RELOC_HIDE macro.

Signed-off-by: Ahmad Fatoum 
---
 test/self/malloc.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/test/self/malloc.c b/test/self/malloc.c
index 47c225ac6a10..0feec810185f 100644
--- a/test/self/malloc.c
+++ b/test/self/malloc.c
@@ -85,11 +85,11 @@ static void test_malloc(void)
free(p);
 
if (mem_malloc_size) {
-   tmp = expect_alloc_fail(malloc(SIZE_MAX));
+   tmp = expect_alloc_fail(malloc(RELOC_HIDE(SIZE_MAX, 0)));
free(tmp);
 
if (0xf000 > mem_malloc_size) {
-   tmp = expect_alloc_fail(malloc(0xf000));
+   tmp = expect_alloc_fail(malloc(RELOC_HIDE(0xf000, 
0)));
free(tmp);
}
} else {
@@ -111,11 +111,11 @@ static void test_malloc(void)
free(tmp);
 
if (0xf000 > mem_malloc_size) {
-   tmp = expect_alloc_fail(realloc(p, 0xf000));
+   tmp = expect_alloc_fail(realloc(p, 
RELOC_HIDE(0xf000, 0)));
free(tmp);
}
 
-   tmp = expect_alloc_fail(realloc(p, SIZE_MAX));
+   tmp = expect_alloc_fail(realloc(p, RELOC_HIDE(SIZE_MAX, 0)));
free(tmp);
 
} else {
-- 
2.39.2




[PATCH] ARM: stm32mp: fix typo in STM32MP135-DK prompt

2023-11-09 Thread Ahmad Fatoum
The board is called STM32MP135 and there is currently no STM32MP137.
The typo was likely caused by copy-pasting from the STM32MP15x, which
has STM32MP157.

Signed-off-by: Ahmad Fatoum 
---
 arch/arm/mach-stm32mp/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index bc0a48d64c82..524d282a1db8 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -16,7 +16,7 @@ config ARCH_STM32MP157
 
 config MACH_STM32MP13XX_DK
select ARCH_STM32MP13
-   bool "STM32MP137F DK board"
+   bool "STM32MP135F DK board"
 
 config MACH_STM32MP15XX_DKX
select ARCH_STM32MP157
-- 
2.39.2




[PATCH] console: move ARCH_HAS_CTRLC into Kconfig

2023-11-09 Thread Ahmad Fatoum
We should do away altogether with , so prepare for doing
that in the future by moing the only content it has on sandbox into
Kconfig.

Signed-off-by: Ahmad Fatoum 
---
 Kconfig   |  2 +-
 arch/Kconfig  | 13 +
 arch/sandbox/Kconfig  |  1 +
 arch/sandbox/include/asm/common.h |  2 --
 common/console.c  |  2 +-
 common/console_simple.c   |  2 +-
 include/stdio.h   |  4 ++--
 7 files changed, 19 insertions(+), 7 deletions(-)
 create mode 100644 arch/Kconfig

diff --git a/Kconfig b/Kconfig
index 49bd17c89f33..4c076026b0c9 100644
--- a/Kconfig
+++ b/Kconfig
@@ -8,7 +8,7 @@ mainmenu "Barebox/$(ARCH) $(KERNELVERSION) Configuration"
 
 source "scripts/Kconfig.include"
 
-source "arch/$(SRCARCH)/Kconfig"
+source "arch/Kconfig"
 
 source "common/Kconfig"
 source "commands/Kconfig"
diff --git a/arch/Kconfig b/arch/Kconfig
new file mode 100644
index ..1a9d32370422
--- /dev/null
+++ b/arch/Kconfig
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# General architecture dependent options
+#
+
+#
+# Note: arch/$(SRCARCH)/Kconfig needs to be included first so that it can
+# override the default values in this file.
+#
+source "arch/$(SRCARCH)/Kconfig"
+
+config ARCH_HAS_CTRLC
+   bool
diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index 88da35a955ee..136a97b1ad30 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -16,6 +16,7 @@ config SANDBOX
select ARCH_HAS_STACK_DUMP if ASAN
select GENERIC_FIND_NEXT_BIT
select ARCH_HAS_SJLJ
+   select ARCH_HAS_CTRLC
select HAS_DEBUG_LL
default y
 
diff --git a/arch/sandbox/include/asm/common.h 
b/arch/sandbox/include/asm/common.h
index 66ed2f5e9c52..002dfb52b513 100644
--- a/arch/sandbox/include/asm/common.h
+++ b/arch/sandbox/include/asm/common.h
@@ -3,6 +3,4 @@
 #ifndef ASM_COMMON_H
 #define ASM_COMMON_H
 
-#define ARCH_HAS_CTRLC
-
 #endif /* ASM_COMMON_H */
diff --git a/common/console.c b/common/console.c
index 7e43a9b5fc0e..03b76b122b2b 100644
--- a/common/console.c
+++ b/common/console.c
@@ -625,7 +625,7 @@ int ctrlc(void)
if (ctrlc_abort)
return 1;
 
-#ifdef ARCH_HAS_CTRLC
+#ifdef CONFIG_ARCH_HAS_CTRLC
ret = arch_ctrlc();
 #else
if (tstc() && getchar() == 3)
diff --git a/common/console_simple.c b/common/console_simple.c
index afa9a0f186fb..702087bd23d7 100644
--- a/common/console_simple.c
+++ b/common/console_simple.c
@@ -70,7 +70,7 @@ EXPORT_SYMBOL(console_flush);
 int ctrlc (void)
 {
int ret = 0;
-#ifdef ARCH_HAS_CTRLC
+#ifdef CONFIG_ARCH_HAS_CTRLC
ret = arch_ctrlc();
 #else
if (tstc() && getchar() == 3)
diff --git a/include/stdio.h b/include/stdio.h
index 49f3d0cf77b3..b6ded805cc21 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -60,13 +60,13 @@ static inline int vprintf(const char *fmt, va_list args)
return 0;
 }
 
-#ifndef ARCH_HAS_CTRLC
+#ifndef CONFIG_ARCH_HAS_CTRLC
 /* test if ctrl-c was pressed */
 static inline int ctrlc (void)
 {
return 0;
 }
-#endif /* ARCH_HAS_CTRLC */
+#endif /* CONFIG_ARCH_HAS_CTRLC */
 
 #endif
 
-- 
2.39.2




[PATCH] include: spinlock.h: mark DEFINE_SPINLOCK with __always_unused

2023-11-09 Thread Ahmad Fatoum
The spinlock stubs don't actually do anything with the spinlock_t.
To avoid the compiler warning about it add an __always_unused annotation
to the spinlock.

Signed-off-by: Ahmad Fatoum 
---
 include/linux/spinlock.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index a604e0fd090f..6f90fb1cad43 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -12,6 +12,6 @@ typedef int   spinlock_t;
 #define spin_lock_irqsave(lock, flags) do { flags = 0; } while (0)
 #define spin_unlock_irqrestore(lock, flags) do { flags = flags; } while (0)
 
-#define DEFINE_SPINLOCK(lock) spinlock_t lock
+#define DEFINE_SPINLOCK(lock) spinlock_t __always_unused lock
 
 #endif /* __LINUX_SPINLOCK_H */
-- 
2.39.2




[PATCH v2 2/3] complete: add support for spaces in completions

2023-11-09 Thread Ahmad Fatoum
Drivers have spaces inside their names, which makes tab completion
tricky as it restarts for every separate argument.

Support for doing this in readline and hush landed in commits
1498093ccd11 ("readline: Complete strings containing whitespaces correctly")
and 70e0885229d2 ("hush: Fix handling '\ '") respectively.

This only goes one way though, escape a completion suggestion. The
suggestion needs to be unescaped again, so repeated  usage after
modifying the prompt is understood.

For this to work, skip backslashes in the argument being completed.

Signed-off-by: Ahmad Fatoum 
---
v1 -> v2:
  - new patch to prepare completing driver names with spaces
---
 common/complete.c | 70 +++
 1 file changed, 52 insertions(+), 18 deletions(-)

diff --git a/common/complete.c b/common/complete.c
index 4137bb3084fc..ef31a36faf5f 100644
--- a/common/complete.c
+++ b/common/complete.c
@@ -14,6 +14,27 @@
 #include 
 #include 
 
+static bool is_valid_escape(const char *str)
+{
+   return str[0] == '\\' && (str[1] == ' ' || str[1] == '\\');
+}
+
+static bool strstarts_escaped(const char *whole, const char *prefix_escaped)
+{
+   if (!prefix_escaped)
+   return true;
+
+   while (*prefix_escaped) {
+   if (is_valid_escape(prefix_escaped))
+   prefix_escaped++;
+
+   if (*whole++ != *prefix_escaped++)
+   return false;
+   }
+
+   return true;
+}
+
 static int file_complete(struct string_list *sl, char *instr,
 const char *dirn, int exec)
 {
@@ -35,7 +56,7 @@ static int file_complete(struct string_list *sl, char *instr,
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
 
-   if (strncmp(base, d->d_name, strlen(base)))
+   if (!strstarts_escaped(d->d_name, base))
continue;
 
strcpy(tmp, instr);
@@ -94,7 +115,7 @@ static int path_command_complete(struct string_list *sl, 
char *instr)
!strcmp(d->d_name, ".."))
continue;
 
-   if (!strncmp(instr, d->d_name, strlen(instr))) {
+   if (strstarts_escaped(d->d_name, instr)) {
strcpy(tmp, d->d_name);
if (!stat(tmp, &s) &&
S_ISDIR(s.st_mode))
@@ -136,15 +157,9 @@ EXPORT_SYMBOL(command_complete);
 int device_complete(struct string_list *sl, char *instr)
 {
struct device *dev;
-   int len;
-
-   if (!instr)
-   instr = "";
-
-   len = strlen(instr);
 
for_each_device(dev) {
-   if (strncmp(instr, dev_name(dev), len))
+   if (!strstarts_escaped(dev_name(dev), instr))
continue;
 
string_list_add_asprintf(sl, "%s ", dev_name(dev));
@@ -158,12 +173,9 @@ static int device_param_complete(struct device *dev, const 
char *devname,
 struct string_list *sl, char *instr, int eval)
 {
struct param_d *param;
-   int len;
-
-   len = strlen(instr);
 
list_for_each_entry(param, &dev->parameters, list) {
-   if (strncmp(instr, param->name, len))
+   if (!strstarts_escaped(param->name, instr))
continue;
 
string_list_add_asprintf(sl, "%s%s.%s%c",
@@ -340,21 +352,43 @@ void complete_reset(void)
tab_pressed = 0;
 }
 
+static char *skip_to_last_unescaped_space(char *instr)
+{
+   char *t;
+
+   t = strrchr(instr, ' ');
+   if (t && (instr == t || t[-1] != '\\'))
+   return t + 1;
+
+   return instr;
+}
+
+static size_t strlen_escaped(char *instr)
+{
+   size_t count = 0;
+
+   for (; *instr; instr++) {
+   if (is_valid_escape(instr))
+   instr++;
+
+   count++;
+   }
+
+   return count;
+}
+
 static char* cmd_complete_lookup(struct string_list *sl, char *instr)
 {
struct command *cmdtp;
int len;
int ret = COMPLETE_END;
char *res = NULL;
-   char *t;
 
for_each_command(cmdtp) {
len = strlen(cmdtp->name);
if (!strncmp(instr, cmdtp->name, len) && instr[len] == ' ') {
instr += len + 1;
-   t = strrchr(instr, ' ');
-   if (t)
-   instr = t + 1;
+   instr = skip_to_last_unescaped_space(instr);
 
if (cmdtp->complete) {
ret = cmdtp->complete(sl, instr);
@@ -414,7 +448,7 @@ int complete(char *instr, char **outstr)
env_param_complete(&sl, instr + 1, 1);
}
 
-   pos = strlen(instr);
+   pos = strlen_escaped(instr);
 
*o

[PATCH v2 1/3] glob: drop needless ifdeffery in {glob,fnmatch}.h

2023-11-09 Thread Ahmad Fatoum
The implementation of the glob and fnmatch functions is taken from glibc
and it shows in the amount of #ifdefs. We don't need that in barebox and
can even get the glob_t size down by dropping unused members, so let's
do that.

Cc: Christian Melki 
Signed-off-by: Ahmad Fatoum 
---
v1 -> v2:
  - new patch
---
 include/fnmatch.h |  58 ++---
 include/glob.h| 201 +-
 lib/Makefile  |   2 +-
 lib/fnmatch.c |  45 +--
 lib/glob.c| 105 
 5 files changed, 45 insertions(+), 366 deletions(-)

diff --git a/include/fnmatch.h b/include/fnmatch.h
index c13beb9011fb..1bc2cf87391a 100644
--- a/include/fnmatch.h
+++ b/include/fnmatch.h
@@ -4,69 +4,21 @@
 */
 
 #ifndef_FNMATCH_H
-#define_FNMATCH_H  1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
-# if !defined __GLIBC__ || !defined __P
-#  undef   __P
-#  define __P(protos)  protos
-# endif
-#else /* Not C++ or ANSI C.  */
-# undef__P
-# define __P(protos)   ()
-/* We can get away without defining `const' here only because in this file
-   it is used only inside the prototype for `fnmatch', which is elided in
-   non-ANSI C where `const' is problematical.  */
-#endif /* C++ or ANSI C.  */
-
-#ifndef const
-# if (defined __STDC__ && __STDC__) || defined __cplusplus
-#  define __const  const
-# else
-#  define __const
-# endif
-#endif
-
-/* We #undef these before defining them because some losing systems
-   (HP-UX A.08.07 for example) define these in .  */
-#undef FNM_PATHNAME
-#undef FNM_NOESCAPE
-#undef FNM_PERIOD
+#define_FNMATCH_H
 
 /* Bits set in the FLAGS argument to `fnmatch'.  */
 #defineFNM_PATHNAME(1 << 0) /* No wildcard can ever match `/'.  */
 #defineFNM_NOESCAPE(1 << 1) /* Backslashes don't quote special 
chars.  */
 #defineFNM_PERIOD  (1 << 2) /* Leading `.' is matched only 
explicitly.  */
-
-#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
-# define FNM_FILE_NAME  FNM_PATHNAME   /* Preferred GNU name.  */
-# define FNM_LEADING_DIR (1 << 3)  /* Ignore `/...' after a match.  */
-# define FNM_CASEFOLD   (1 << 4)   /* Compare without regard to case.  */
-# define FNM_EXTMATCH   (1 << 5)   /* Use ksh-like extended matching. */
-#endif
+#define FNM_FILE_NAME   FNM_PATHNAME   /* Preferred GNU name.  */
+#define FNM_LEADING_DIR(1 << 3)/* Ignore `/...' after a match. 
 */
+#define FNM_CASEFOLD   (1 << 4)/* Compare without regard to case.  */
 
 /* Value returned by `fnmatch' if STRING does not match PATTERN.  */
 #defineFNM_NOMATCH 1
 
-/* This value is returned if the implementation does not support
-   `fnmatch'.  Since this is not the case here it will never be
-   returned but the conformance test suites still require the symbol
-   to be defined.  */
-#ifdef _XOPEN_SOURCE
-# define FNM_NOSYS (-1)
-#endif
-
 /* Match NAME against the filename pattern PATTERN,
returning zero if it matches, FNM_NOMATCH if not.  */
-extern int fnmatch __P ((__const char *__pattern, __const char *__name,
-int __flags));
-
-#ifdef __cplusplus
-}
-#endif
+extern int fnmatch(const char *pattern, const char *name, int flags);
 
 #endif /* fnmatch.h */
diff --git a/include/glob.h b/include/glob.h
index ec0ac66f8765..67816c9cf0ad 100644
--- a/include/glob.h
+++ b/include/glob.h
@@ -4,54 +4,9 @@
 */
 
 #ifndef_GLOB_H
-#define_GLOB_H 1
+#define_GLOB_H
 
-#define _FILE_OFFSET_BITS 32
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#undef __ptr_t
-#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
-# if !defined __GLIBC__ || !defined __P
-#  undef __P
-#  undef __PMT
-#  define __P(protos)  protos
-#  define __PMT(protos)protos
-#  if !defined __GNUC__ || __GNUC__ < 2
-#   undef __const
-#   define __const const
-#  endif
-# endif
-# define __ptr_t   void *
-#else /* Not C++ or ANSI C.  */
-# undef__P
-# undef __PMT
-# define __P(protos)   ()
-# define __PMT(protos) ()
-# undef__const
-# define __const
-# define __ptr_t   char *
-#endif /* C++ or ANSI C.  */
-
-/* We need `size_t' for the following definitions.  */
-#ifndef __size_t
-# if defined __GNUC__ && __GNUC__ >= 2
-typedef __SIZE_TYPE__ __size_t;
-#  ifdef _XOPEN_SOURCE
-typedef __SIZE_TYPE__ size_t;
-#  endif
-# else
-/* This is a guess.  */
-typedef unsigned long int __size_t;
-# endif
-#else
-/* The GNU CC stddef.h version defines __size_t as empty.  We need a real
-   definition.  */
-# undef __size_t
-# define __size_t size_t
-#endif
+#include 
 
 /* Bits set in the FLAGS argument to `glob'.  */
 #defineGLOB_ERR(1 << 0)/* Return on read errors.  */
@@ -62,163 +17,49 @@ typedef unsigned long int __size_t;
 #defineGLOB_APPEND (1 << 5)/* Append to results of a prev

[PATCH v2 3/3] commands: drvinfo: support filtering by driver

2023-11-09 Thread Ahmad Fatoum
drvinfo can be very long especially for the in-tree defconfigs.

Make it more convenient to use by add optional filtering support:

  barebox@board:/ drvinfo '*imx7d*'
  Driver  Device(s)
  
  imx7d-src
  3039.reset-control...@3039.of
  imx7d_adc
  3061@3061.of
  3062@3062.of

  Use 'devinfo DEVICE' for more information

Furthermore, tab completion for driver names is now supported as well.

Signed-off-by: Ahmad Fatoum 
---
v1 -> v2:
  - use fnmatch to support glob patterns for driver names (Sascha)
  - add functional autocomplete despite spaces (Sascha)

Signed-off-by: Ahmad Fatoum 
---
 commands/drvinfo.c |  8 
 common/complete.c  | 15 +++
 include/complete.h |  1 +
 3 files changed, 24 insertions(+)

diff --git a/commands/drvinfo.c b/commands/drvinfo.c
index b984b9472585..e13b04870ee4 100644
--- a/commands/drvinfo.c
+++ b/commands/drvinfo.c
@@ -5,15 +5,21 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 static int do_drvinfo(int argc, char *argv[])
 {
+   char *pattern = argv[1];
struct driver *drv;
struct device *dev;
 
printf("Driver\tDevice(s)\n");
printf("\n");
for_each_driver(drv) {
+   if (pattern && fnmatch(pattern, drv->name, 0))
+   continue;
+
printf("%s\n",drv->name);
for_each_device(dev) {
if (dev->driver == drv)
@@ -31,5 +37,7 @@ static int do_drvinfo(int argc, char *argv[])
 BAREBOX_CMD_START(drvinfo)
.cmd= do_drvinfo,
BAREBOX_CMD_DESC("list compiled-in device drivers")
+   BAREBOX_CMD_OPTS("[DRIVER]")
BAREBOX_CMD_GROUP(CMD_GRP_INFO)
+   BAREBOX_CMD_COMPLETE(driver_complete)
 BAREBOX_CMD_END
diff --git a/common/complete.c b/common/complete.c
index ef31a36faf5f..3911535621b1 100644
--- a/common/complete.c
+++ b/common/complete.c
@@ -186,6 +186,21 @@ static int device_param_complete(struct device *dev, const 
char *devname,
return 0;
 }
 
+int driver_complete(struct string_list *sl, char *instr)
+{
+   struct driver_d *drv;
+
+   for_each_driver(drv) {
+   if (!strstarts_escaped(drv->name, instr))
+   continue;
+
+   string_list_add_asprintf(sl, "%s ", drv->name);
+   }
+
+   return COMPLETE_CONTINUE;
+}
+EXPORT_SYMBOL(driver_complete);
+
 int empty_complete(struct string_list *sl, char *instr)
 {
return COMPLETE_END;
diff --git a/include/complete.h b/include/complete.h
index b0e675b5599f..2068760ac235 100644
--- a/include/complete.h
+++ b/include/complete.h
@@ -14,6 +14,7 @@ void complete_reset(void);
 
 int command_complete(struct string_list *sl, char *instr);
 int device_complete(struct string_list *sl, char *instr);
+int driver_complete(struct string_list *sl, char *instr);
 int empty_complete(struct string_list *sl, char *instr);
 int eth_complete(struct string_list *sl, char *instr);
 int command_var_complete(struct string_list *sl, char *instr);
-- 
2.39.2




[PATCH] include: pm_domain.h: make header self-contained

2023-11-09 Thread Ahmad Fatoum
pm_domain.h so far included no headers and only worked, because it was
included in a "correct" order in other files. Fix this by including the
header it depends on.

Signed-off-by: Ahmad Fatoum 
---
 include/pm_domain.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/pm_domain.h b/include/pm_domain.h
index a7e46c86b9cb..ac0ec477b6b1 100644
--- a/include/pm_domain.h
+++ b/include/pm_domain.h
@@ -3,6 +3,9 @@
 #ifndef _PM_DOMAIN_H
 #define _PM_DOMAIN_H
 
+#include 
+#include 
+
 enum gpd_status {
GPD_STATE_ACTIVE = 0,   /* PM domain is active */
GPD_STATE_POWER_OFF,/* PM domain is off */
-- 
2.39.2




[PATCH master] phy: stm32-usbphyc: fix unbalanced phy exit

2023-11-09 Thread Ahmad Fatoum
On the STM32MP1, shutting down barebox can result in a

  ERROR: phy1: phy exit failed --> -22

message printed to the console. This is because the regulator is disabled
more often than it was enabled, because stm32_usbphyc_pll_disable
is called twice:

  - Once from stm32_usbphyc_remove calling stm32_usbphyc_phy_exit
  - Once from dwc2_remove calling phy_exit -> stm32_usbphyc_phy_exit

The code is taken from Linux and likely causes no issues there, because
devices are removed in reverse probe order, which barebox doesn't
enforce. Properly solving this would be a larger endeavour, so for now
just fix the stm32-usbphyc driver to ignore reference count dropping
below zero and only call __stm32_usbphyc_pll_disable once.

Signed-off-by: Ahmad Fatoum 
---
 drivers/phy/phy-stm32-usbphyc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c
index ac82b019f44c..91f4e7f7e08d 100644
--- a/drivers/phy/phy-stm32-usbphyc.c
+++ b/drivers/phy/phy-stm32-usbphyc.c
@@ -277,7 +277,7 @@ static int __stm32_usbphyc_pll_disable(struct stm32_usbphyc 
*usbphyc)
 static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
 {
/* Check if a phy port is still active or clk48 in use */
-   if (atomic_dec_return(&usbphyc->n_pll_cons) > 0)
+   if (atomic_dec_return(&usbphyc->n_pll_cons) != 1)
return 0;
 
return __stm32_usbphyc_pll_disable(usbphyc);
-- 
2.39.2




[PATCH] barebox-wrapper: define stub for MODULE_VERSION

2023-11-09 Thread Ahmad Fatoum
We already stub out a number of MODULE_* macros to save porters the
hassle of deleting them. Let's add MODULE_VERSION to the list as well.

Signed-off-by: Ahmad Fatoum 
---
 include/linux/barebox-wrapper.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/barebox-wrapper.h b/include/linux/barebox-wrapper.h
index ed237877fc75..5d311e1d70f4 100644
--- a/include/linux/barebox-wrapper.h
+++ b/include/linux/barebox-wrapper.h
@@ -19,6 +19,7 @@ static inline void vfree(const void *addr)
 #define MODULE_AUTHOR(x)
 #define MODULE_DESCRIPTION(x)
 #define MODULE_LICENSE(x)
+#define MODULE_VERSION(x)
 #define MODULE_ALIAS(x)
 #define MODULE_DEVICE_TABLE(bus, table)
 #define MODULE_ALIAS_DSA_TAG_DRIVER(drv)
-- 
2.39.2




[PATCH master] efi: acpi: fix printf format specifier mismatch

2023-11-09 Thread Ahmad Fatoum
entry_count has type size_t and not long as the format string wrongly
suggested.

Signed-off-by: Ahmad Fatoum 
---
 drivers/bus/acpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bus/acpi.c b/drivers/bus/acpi.c
index f69789200633..ac034cce4569 100644
--- a/drivers/bus/acpi.c
+++ b/drivers/bus/acpi.c
@@ -186,7 +186,7 @@ static int acpi_register_devices(struct bus_type *bus)
return -EIO;
}
 
-   dev_info(bus->dev, "Found %s (OEM: %.8s) with %lu entries\n",
+   dev_info(bus->dev, "Found %s (OEM: %.8s) with %zu entries\n",
sig, root->sdt.oem_id, entry_count);
 
for (i = 0; i < entry_count; i++) {
-- 
2.39.2




[PATCH master] mfd: syscon: don't register clocked syscon if geting clock fails

2023-11-09 Thread Ahmad Fatoum
When of_syscon_register is called with check_clk=true, it will attempt
to attach the clock. If that fails, the newly allocated syscon is freed,
but a dangling pointer remained in the syscon_list.

Fix this by only registering the syscon in the successful case.

Fixes: b36b7b727192 ("mfd: syscon: clock peripheral if specified in device 
tree")
Signed-off-by: Ahmad Fatoum 
---
 drivers/mfd/syscon.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 3e12123b572e..3c2e1241fdff 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -74,8 +74,6 @@ static struct syscon *of_syscon_register(struct device_node 
*np, bool check_clk)
syscon_config.val_bits = reg_io_width * 8;
syscon_config.max_register = resource_size(&res) - reg_io_width;
 
-   list_add_tail(&syscon->list, &syscon_list);
-
syscon->regmap = regmap_init_mmio_clk(NULL, NULL, syscon->base,
  &syscon_config);
 
@@ -93,6 +91,8 @@ static struct syscon *of_syscon_register(struct device_node 
*np, bool check_clk)
}
}
 
+   list_add_tail(&syscon->list, &syscon_list);
+
return syscon;
 
 err_map:
-- 
2.39.2




[PATCH] usb: dwc2: use linux/spinlock.h for stubs

2023-11-09 Thread Ahmad Fatoum
We already have dummy definitions for common spin lock operations,
so reuse them instead of defining them in the driver.

Signed-off-by: Ahmad Fatoum 
---
 drivers/usb/dwc2/gadget.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 00323d2d9029..3c06c438b65d 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -1,18 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 #include 
 #include 
+#include 
 #include "dwc2.h"
 
 #define to_dwc2 gadget_to_dwc2
 #define dwc2_set_bit(d, r, b)  dwc2_writel(d, (b) | dwc2_readl(d, r), r)
 #define dwc2_clear_bit(d, r, b)dwc2_writel(d, ~(b) & dwc2_readl(d, r), 
r)
 
-#define spin_lock(lock)
-#define spin_unlock(lock)
 #define local_irq_save(flags)(void)(flags)
 #define local_irq_restore(flags) (void)(flags)
-#define spin_lock_irqsave(lock, flags) (void)(flags)
-#define spin_unlock_irqrestore(lock, flags) (void)(flags)
 
 static void kill_all_requests(struct dwc2 *, struct dwc2_ep *, int);
 
-- 
2.39.2




[PATCH 2/2] serial: stm32: support probing with missing clock provider

2023-11-09 Thread Ahmad Fatoum
The STM32MP135F-DK support in barebox has bitrotted, because of changes
to the upstream device tree: The root of the clock tree is now provided
by OP-TEE over SCMI for which no support exists in barebox, so drivers
requesting clocks will defer indefinitely, including the console device.

A series adding OP-TEE SCMI support will follow, but for now, let's
ensure that console registration isn't deferred in such a case.

Signed-off-by: Ahmad Fatoum 
---
 drivers/serial/serial_stm32.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c
index 4a67408f44f6..3e18a2c152af 100644
--- a/drivers/serial/serial_stm32.c
+++ b/drivers/serial/serial_stm32.c
@@ -165,7 +165,7 @@ static int stm32_serial_probe(struct device *dev)
stm32->stm32f4 = info->stm32f4;
stm32->uart_enable_bit = info->uart_enable_bit;
 
-   stm32->clk = clk_get(dev, NULL);
+   stm32->clk = clk_get_for_console(dev, NULL);
if (IS_ERR(stm32->clk)) {
ret = PTR_ERR(stm32->clk);
dev_err(dev, "Failed to get UART clock %d\n", ret);
@@ -183,7 +183,7 @@ static int stm32_serial_probe(struct device *dev)
cdev->putc   = stm32_serial_putc;
cdev->getc   = stm32_serial_getc;
cdev->flush  = stm32_serial_flush;
-   cdev->setbrg = stm32_serial_setbaudrate;
+   cdev->setbrg = stm32->clk ? stm32_serial_setbaudrate : NULL;
cdev->linux_console_name = "ttySTM";
 
if (dev->of_node) {
-- 
2.39.2




[PATCH 1/2] console: provide best-effort clk_get_for_console helper

2023-11-09 Thread Ahmad Fatoum
From: Ahmad Fatoum 

clk_get will return -EPROBE_DEFER if clock provider hasn't yet been
probed. In a system with deep probe enabled, dependencies are probed
on demand, so a -EPROBE_DEFER return is final and the console probe
will never succeed.

CONFIG_DEBUG_LL is often used to debug this, but because the low-level
console is not interactive, it's a bit cumbersome. Improve upon this a
bit, by providing a clk_get_for_console helper that returns NULL if and
only if we are sure that a clock provider will not be probed.

In that case, the driver can skip code paths initialization code and
baud rate setting dependent on having access to the clock and still
register a console that reuses what was set up by CONFIG_DEBUG_LL.

Signed-off-by: Ahmad Fatoum 
---
 include/console.h   | 26 ++
 include/linux/clk.h | 21 +
 2 files changed, 47 insertions(+)

diff --git a/include/console.h b/include/console.h
index 586b68f73301..b8c901801e9f 100644
--- a/include/console.h
+++ b/include/console.h
@@ -8,6 +8,7 @@
 #define _CONSOLE_H_
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -208,4 +209,29 @@ static inline void console_ctrlc_allow(void) { }
 static inline void console_ctrlc_forbid(void) { }
 #endif
 
+/**
+ * clk_get_for_console - get clock, ignoring known unavailable clock controller
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Return: a struct clk corresponding to the clock producer, a
+ * valid IS_ERR() condition containing errno or NULL if it could
+ * be determined that the clock producer will never be probed in
+ * absence of modules. The NULL return allows serial drivers to
+ * skip clock handling and rely on CONFIG_DEBUG_LL.
+ */
+static inline struct clk *clk_get_for_console(struct device *dev, const char 
*id)
+{
+   struct clk *clk;
+
+   if (!IS_ENABLED(CONFIG_DEBUG_LL))
+   return clk_get(dev, id);
+
+   clk = clk_get_if_available(dev, id);
+   if (clk == NULL)
+   dev_warn(dev, "couldn't get clock (ignoring)\n");
+
+   return clk;
+}
+
 #endif
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 61b4ff3127cf..f505f18a75c0 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 struct device;
@@ -982,4 +983,24 @@ static inline struct clk *clk_get_enabled(struct device 
*dev, const char *id)
return clk;
 }
 
+/**
+ * clk_get_if_available - get clock, ignoring known unavailable clock 
controller
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Return: a struct clk corresponding to the clock producer, a
+ * valid IS_ERR() condition containing errno or NULL if it could
+ * be determined that the clock producer will never be probed in
+ * absence of modules.
+ */
+static inline struct clk *clk_get_if_available(struct device *dev, const char 
*id)
+{
+   struct clk *clk = clk_get(dev, id);
+
+   if (clk == ERR_PTR(-EPROBE_DEFER) && deep_probe_is_supported())
+   return NULL;
+
+   return clk;
+}
+
 #endif
-- 
2.39.2




[PATCH master] scripts: setlocalversion: sync with Linux

2023-11-09 Thread Ahmad Fatoum
We are using an older version of setlocalversion that sources the
config. This is wrong as there's no guarantee that it's ok to source the
config, e.g.:

  CONFIG_DEFAULT_ENVIRONMENT_PATH="$(objtree)/.ptxdist-defaultenv"

when sourced will lead to:

  scripts/setlocalversion: 15: include/config/auto.conf: objtree: not found

Fix this by grepping the file instead.

Signed-off-by: Ahmad Fatoum 
---
 scripts/setlocalversion | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 6b54e46a0f12..cbd3883df9ae 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -111,13 +111,14 @@ if $scm_only; then
exit
 fi
 
-if test -e include/config/auto.conf; then
-   . include/config/auto.conf
-else
+if ! test -e include/config/auto.conf; then
echo "Error: kernelrelease not valid - run 'make prepare' to update it" 
>&2
exit 1
 fi
 
+# version string from CONFIG_LOCALVERSION
+config_localversion=$(sed -n 's/^CONFIG_LOCALVERSION=\(.*\)$/\1/p' 
include/config/auto.conf)
+
 # localversion* files in the build and source directory
 res="$(collect_files localversion*)"
 if test ! "$srctree" -ef .; then
@@ -125,10 +126,10 @@ if test ! "$srctree" -ef .; then
 fi
 
 # CONFIG_LOCALVERSION and LOCALVERSION (if set)
-res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
+res="${res}${config_localversion}${LOCALVERSION}"
 
 # scm version string if not at a tagged commit
-if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
+if grep -q "^CONFIG_LOCALVERSION_AUTO=y$" include/config/auto.conf; then
# full scm version string
res="$res$(scm_version)"
 elif [ "${LOCALVERSION+set}" != "set" ]; then
-- 
2.39.2




[PATCH 2/2] malloc: use __attribute((alloc_size)) for dynamic memory allocation

2023-11-09 Thread Ahmad Fatoum
Adorning functions allocating dynamic memory with __alloc_size allows
GCC to warn about heap overflows it notices during normal compilation.

Import the definitions from Linux and switch over barebox 
to make use of it.

Signed-off-by: Ahmad Fatoum 
---
 include/linux/compiler-gcc.h   |  8 
 include/linux/compiler_types.h | 24 
 include/malloc.h   |  9 +
 3 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 4d36b27214fd..2534386d040f 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -234,3 +234,11 @@
 #else
 #define __diag_GCC_8(s)
 #endif
+
+/*
+ * Prior to 9.1, -Wno-alloc-size-larger-than (and therefore the "alloc_size"
+ * attribute) do not work, and must be disabled.
+ */
+#if GCC_VERSION < 90100
+#undef __alloc_size__
+#endif
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 800bc518feea..9ef8115a396f 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -56,6 +56,16 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 
 #ifdef __KERNEL__
 
+/*
+ * Note: do not use this directly. Instead, use __alloc_size() since it is 
conditionally
+ * available and includes other attributes. For GCC < 9.1, __alloc_size__ gets 
undefined
+ * in compiler-gcc.h, due to misbehaviors.
+ *
+ *   gcc: 
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#alloc-size
+ */
+#define __alloc_size__(x, ...) __attribute__((__alloc_size__(x, ## 
__VA_ARGS__)))
+
 /* Compiler specific macros. */
 #ifdef __clang__
 #include 
@@ -188,6 +198,20 @@ struct ftrace_likely_data {
 #define __assume_aligned(a, ...)
 #endif
 
+/*
+ * Any place that could be marked with the "alloc_size" attribute is also
+ * a place to be marked with the "malloc" attribute, except those that may
+ * be performing a _reallocation_, as that may alias the existing pointer.
+ * For these, use __realloc_size().
+ */
+#ifdef __alloc_size__
+# define __alloc_size(x, ...)  __alloc_size__(x, ## __VA_ARGS__) __malloc
+# define __realloc_size(x, ...)__alloc_size__(x, ## __VA_ARGS__)
+#else
+# define __alloc_size(x, ...)  __malloc
+# define __realloc_size(x, ...)
+#endif
+
 /* Are two types/vars the same type (ignoring qualifiers)? */
 #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
 
diff --git a/include/malloc.h b/include/malloc.h
index 971fc4058bc6..d63853b91e91 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -2,13 +2,14 @@
 #ifndef __MALLOC_H
 #define __MALLOC_H
 
+#include 
 #include 
 
-void *malloc(size_t);
+void *malloc(size_t) __alloc_size(1);
 void free(void *);
-void *realloc(void *, size_t);
-void *memalign(size_t, size_t);
-void *calloc(size_t, size_t);
+void *realloc(void *, size_t) __realloc_size(2);
+void *memalign(size_t, size_t) __alloc_size(2);
+void *calloc(size_t, size_t) __alloc_size(1, 2);
 void malloc_stats(void);
 void *sbrk(ptrdiff_t increment);
 
-- 
2.39.2




[PATCH 1/2] KASan: test_kasan: hide buggy accesses from compiler

2023-11-09 Thread Ahmad Fatoum
Once we add __alloc_size attributes to allocations, GCC will complain
about violation of memory safety in test_kasan.c.

That memory violation is intended though as test_kasan is meant to
trigger kasan at runtime to verify correct operation.

Silence the warnings by hiding the origin of ptr, so the compiler loses
context about the size of the allocation.

Signed-off-by: Ahmad Fatoum 
---
 lib/kasan/test_kasan.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/lib/kasan/test_kasan.c b/lib/kasan/test_kasan.c
index 14511cdb80bd..a74251a6d9ad 100644
--- a/lib/kasan/test_kasan.c
+++ b/lib/kasan/test_kasan.c
@@ -38,6 +38,8 @@ static noinline void malloc_oob_right(void)
return;
}
 
+   OPTIMIZER_HIDE_VAR(ptr);
+
ptr[size] = 'x';
 
free(ptr);
@@ -55,6 +57,8 @@ static noinline void malloc_oob_left(void)
return;
}
 
+   OPTIMIZER_HIDE_VAR(ptr);
+
*ptr = *(ptr - 1);
free(ptr);
 }
@@ -75,6 +79,8 @@ static noinline void malloc_oob_realloc_more(void)
return;
}
 
+   OPTIMIZER_HIDE_VAR(ptr2);
+
ptr2[size2] = 'x';
 
free(ptr2);
@@ -95,6 +101,8 @@ static noinline void malloc_oob_realloc_less(void)
return;
}
 
+   OPTIMIZER_HIDE_VAR(ptr2);
+
ptr2[size2] = 'x';
 
free(ptr2);
@@ -115,6 +123,9 @@ static noinline void malloc_oob_16(void)
free(ptr2);
return;
}
+
+   OPTIMIZER_HIDE_VAR(ptr1);
+
*ptr1 = *ptr2;
free(ptr1);
free(ptr2);
-- 
2.39.2




[PATCH master] resource: align memory reservation to page boundaries

2023-11-09 Thread Ahmad Fatoum
barebox remaps all reserved entries as uncached to avoid speculative
access into the described regions using remap_range.

The ARM implementation requires buffers to be page aligned, which we
can't assume unconditionally. For this reason, reserve_sdram_region
will align region start and size before mapping uncached.

__mmu_init called later on, will remap everything outside the reserved
entries cached, e.g. to cache additional DRAM not known at PBL time.
No realignment will happen then though triggering the BUG(!IS_ALIGNED)
in ARM's arch_remap_range.

By moving the realignment before __request_sdram_region(), we ensure
that no misaligned memory regions will be passed to arch_remap_range by
core code.

This fixes chainloading barebox from an older barebox[1] that reserves
the FDT prior to relocation.

[1]: anything prior to 0b6b146a5508 ("fdt: Do not reserve device tree blob")

Reported-by: Uwe Kleine-König 
Signed-off-by: Ahmad Fatoum 
---
 common/memory.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/common/memory.c b/common/memory.c
index d560d444b0a8..300320f85344 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -218,10 +218,6 @@ struct resource *reserve_sdram_region(const char *name, 
resource_size_t start,
 {
struct resource *res;
 
-   res = __request_sdram_region(name, IORESOURCE_BUSY, start, size);
-   if (IS_ERR(res))
-   return ERR_CAST(res);
-
if (!IS_ALIGNED(start, PAGE_SIZE)) {
pr_err("%s: %s start is not page aligned\n", __func__, name);
start = ALIGN_DOWN(start, PAGE_SIZE);
@@ -232,6 +228,10 @@ struct resource *reserve_sdram_region(const char *name, 
resource_size_t start,
size = ALIGN(size, PAGE_SIZE);
}
 
+   res = __request_sdram_region(name, IORESOURCE_BUSY, start, size);
+   if (IS_ERR(res))
+   return ERR_CAST(res);
+
remap_range((void *)start, size, MAP_UNCACHED);
 
return res;
-- 
2.39.2