Linux Hexagon architecture development
 help / color / mirror / Atom feed
* [PATCH 0/7] Hexagon build/syscall/etc fixes
@ 2026-09-06  2:17 Brian Cain
  2026-09-06  2:17 ` [PATCH 1/7] hexagon: disable the LLVM packetizer Brian Cain
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Brian Cain @ 2026-09-06  2:17 UTC (permalink / raw)
  To: linux-hexagon; +Cc: sid.manning, pierrick.bouvier, Brian Cain

While working on the qemu boot configuration, several issues were uncovered,
this series contains fixes for the bugs that were found.

Brian Cain (7):
  hexagon: disable the LLVM packetizer
  hexagon: define ELF_CORE_EFLAGS for V4-and-later architectures
  hexagon: stop passing -mv${CONFIG_HEXAGON_ARCH_VERSION} to the linker
  hexagon: read the thread-info register with a volatile asm
  hexagon: let do_work_pending return without pending work
  hexagon: set the user stack pointer in start_thread
  hexagon: return -ENOSYS for unimplemented syscalls

 arch/hexagon/Makefile                  |  7 +++++--
 arch/hexagon/include/asm/elf.h         |  2 +-
 arch/hexagon/include/asm/thread_info.h | 12 +++++++++---
 arch/hexagon/kernel/process.c          | 10 +++-------
 arch/hexagon/kernel/traps.c            | 13 +++++++++----
 5 files changed, 27 insertions(+), 17 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/7] hexagon: disable the LLVM packetizer
  2026-09-06  2:17 [PATCH 0/7] Hexagon build/syscall/etc fixes Brian Cain
@ 2026-09-06  2:17 ` Brian Cain
  2026-09-06  2:17 ` [PATCH 2/7] hexagon: define ELF_CORE_EFLAGS for V4-and-later architectures Brian Cain
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Cain @ 2026-09-06  2:17 UTC (permalink / raw)
  To: linux-hexagon; +Cc: sid.manning, pierrick.bouvier, Brian Cain

The Hexagon packetizer can emit invalid instruction packets at runtime.

There's multiple distinct bugs.  We'll re-evaluate after 23.1.0 to see
if this can be version-gated in the future.

Disable the packetizer and new-value jumps unconditionally.

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 arch/hexagon/Makefile | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/hexagon/Makefile b/arch/hexagon/Makefile
index ff172cbe5881..4d393bd8163a 100644
--- a/arch/hexagon/Makefile
+++ b/arch/hexagon/Makefile
@@ -7,6 +7,11 @@ KBUILD_DEFCONFIG = comet_defconfig
 KBUILD_CFLAGS += -G0
 LDFLAGS_vmlinux += -G0
 
+# Workaround for the packetizer generating invalid instruction encodings:
+# https://github.com/llvm/llvm-project/issues/178338
+# https://github.com/llvm/llvm-project/issues/218083
+KBUILD_CFLAGS += -mllvm --disable-packetizer -mllvm -disable-nvjump
+
 # Do not use single-byte enums; these will overflow.
 KBUILD_CFLAGS += -fno-short-enums
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/7] hexagon: define ELF_CORE_EFLAGS for V4-and-later architectures
  2026-09-06  2:17 [PATCH 0/7] Hexagon build/syscall/etc fixes Brian Cain
  2026-09-06  2:17 ` [PATCH 1/7] hexagon: disable the LLVM packetizer Brian Cain
@ 2026-09-06  2:17 ` Brian Cain
  2026-09-06  2:17 ` [PATCH 3/7] hexagon: stop passing -mv${CONFIG_HEXAGON_ARCH_VERSION} to the linker Brian Cain
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Cain @ 2026-09-06  2:17 UTC (permalink / raw)
  To: linux-hexagon; +Cc: sid.manning, pierrick.bouvier, Brian Cain

ELF_CORE_EFLAGS was only defined for CONFIG_HEXAGON_ARCH_VERSION
values of exactly 2, 3, or 4, unlike CS_COPYREGS just above it, which
already treats V4 as a ">= 4" floor rather than an exact match. Any
version newer than V4 left ELF_CORE_EFLAGS undefined and ptrace.c's
use of it in the hexagon_user_view initializer failed to build.
Extend the V4 case to match V4 and later, using the same core-dump
e_flags value V4 used.

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 arch/hexagon/include/asm/elf.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h
index 5bfdd9b147fd..960602ff7bb5 100644
--- a/arch/hexagon/include/asm/elf.h
+++ b/arch/hexagon/include/asm/elf.h
@@ -168,7 +168,7 @@ do {					\
 #define ELF_CORE_EFLAGS 0x2
 #endif
 
-#if CONFIG_HEXAGON_ARCH_VERSION == 4
+#if CONFIG_HEXAGON_ARCH_VERSION >= 4
 #define ELF_CORE_EFLAGS 0x3
 #endif
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/7] hexagon: stop passing -mv${CONFIG_HEXAGON_ARCH_VERSION} to the linker
  2026-09-06  2:17 [PATCH 0/7] Hexagon build/syscall/etc fixes Brian Cain
  2026-09-06  2:17 ` [PATCH 1/7] hexagon: disable the LLVM packetizer Brian Cain
  2026-09-06  2:17 ` [PATCH 2/7] hexagon: define ELF_CORE_EFLAGS for V4-and-later architectures Brian Cain
@ 2026-09-06  2:17 ` Brian Cain
  2026-09-06  2:17 ` [PATCH 4/7] hexagon: read the thread-info register with a volatile asm Brian Cain
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Cain @ 2026-09-06  2:17 UTC (permalink / raw)
  To: linux-hexagon; +Cc: sid.manning, pierrick.bouvier, Brian Cain

ldflags-y is probed with cc-option, which checks whether the compiler
accepts the flag, then the result is appended to KBUILD_LDFLAGS, which
is passed straight to $(LD) -- the linker, not the compiler. This
presumed the linker was ld.qcld (aka ld.eld), which does accept the
-mvNN flags. ld.lld does not: it parses "-mvNN" as "-m vNN", i.e. a
request for an emulation named "vNN", which does not exist, and fails
with "unknown emulation: vNN".

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 arch/hexagon/Makefile | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/hexagon/Makefile b/arch/hexagon/Makefile
index 4d393bd8163a..86c96d11b329 100644
--- a/arch/hexagon/Makefile
+++ b/arch/hexagon/Makefile
@@ -26,11 +26,9 @@ KBUILD_CFLAGS_MODULE += -mlong-calls
 
 cflags-y += $(call cc-option,-mv${CONFIG_HEXAGON_ARCH_VERSION})
 aflags-y += $(call cc-option,-mv${CONFIG_HEXAGON_ARCH_VERSION})
-ldflags-y += $(call cc-option,-mv${CONFIG_HEXAGON_ARCH_VERSION})
 
 KBUILD_CFLAGS += $(cflags-y)
 KBUILD_AFLAGS += $(aflags-y)
-KBUILD_LDFLAGS += $(ldflags-y)
 
 # Thread-info register will be r19.  This value is not configureable;
 # it is hard-coded in several files.
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/7] hexagon: read the thread-info register with a volatile asm
  2026-09-06  2:17 [PATCH 0/7] Hexagon build/syscall/etc fixes Brian Cain
                   ` (2 preceding siblings ...)
  2026-09-06  2:17 ` [PATCH 3/7] hexagon: stop passing -mv${CONFIG_HEXAGON_ARCH_VERSION} to the linker Brian Cain
@ 2026-09-06  2:17 ` Brian Cain
  2026-09-06  2:17 ` [PATCH 5/7] hexagon: let do_work_pending return without pending work Brian Cain
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Cain @ 2026-09-06  2:17 UTC (permalink / raw)
  To: linux-hexagon; +Cc: sid.manning, pierrick.bouvier, Brian Cain

current_thread_info() was a global register variable.  Replace it with an
explicit read of the same register, marked volatile: the register changes
under us at every context switch, so the read must not be treated as a
pure expression the compiler is free to hoist out of a loop or reuse
across a call to switch_to().

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 arch/hexagon/include/asm/thread_info.h | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/hexagon/include/asm/thread_info.h b/arch/hexagon/include/asm/thread_info.h
index e90f280b9ce3..3d4a40091a5a 100644
--- a/arch/hexagon/include/asm/thread_info.h
+++ b/arch/hexagon/include/asm/thread_info.h
@@ -70,8 +70,14 @@ struct thread_info {
 #define qstr(s) #s
 #define QUOTED_THREADINFO_REG qqstr(THREADINFO_REG)
 
-register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG);
-#define current_thread_info()  __current_thread_info
+static inline struct thread_info *current_thread_info(void)
+{
+	struct thread_info *ti;
+
+	asm volatile("%0 = " QUOTED_THREADINFO_REG : "=r"(ti));
+
+	return ti;
+}
 
 #endif /* __ASSEMBLY__ */
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/7] hexagon: let do_work_pending return without pending work
  2026-09-06  2:17 [PATCH 0/7] Hexagon build/syscall/etc fixes Brian Cain
                   ` (3 preceding siblings ...)
  2026-09-06  2:17 ` [PATCH 4/7] hexagon: read the thread-info register with a volatile asm Brian Cain
@ 2026-09-06  2:17 ` Brian Cain
  2026-09-06  2:17 ` [PATCH 6/7] hexagon: set the user stack pointer in start_thread Brian Cain
  2026-09-06  2:17 ` [PATCH 7/7] hexagon: return -ENOSYS for unimplemented syscalls Brian Cain
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Cain @ 2026-09-06  2:17 UTC (permalink / raw)
  To: linux-hexagon; +Cc: sid.manning, pierrick.bouvier, Brian Cain

do_work_pending() panicked if it was entered with no work bit set, but
the event exit path re-checks flags after enabling interrupts, so a
signal that has since been handled legitimately leaves nothing to do.
Return zero instead, and stop treating single-step as pending work.

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 arch/hexagon/include/asm/thread_info.h | 2 +-
 arch/hexagon/kernel/process.c          | 8 +-------
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/hexagon/include/asm/thread_info.h b/arch/hexagon/include/asm/thread_info.h
index 3d4a40091a5a..d4a005d43e31 100644
--- a/arch/hexagon/include/asm/thread_info.h
+++ b/arch/hexagon/include/asm/thread_info.h
@@ -107,7 +107,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_NOTIFY_SIGNAL	(1 << TIF_NOTIFY_SIGNAL)
 
 /* work to do on interrupt/exception return - All but TIF_SYSCALL_TRACE */
-#define _TIF_WORK_MASK          (0x0000FFFF & ~_TIF_SYSCALL_TRACE)
+#define _TIF_WORK_MASK          (0x0000FFFF & ~_TIF_SYSCALL_TRACE & ~_TIF_SINGLESTEP)
 
 /* work to do on any return to u-space */
 #define _TIF_ALLWORK_MASK       0x0000FFFF
diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c
index 15b4992bfa29..f5e9934c36e3 100644
--- a/arch/hexagon/kernel/process.c
+++ b/arch/hexagon/kernel/process.c
@@ -156,10 +156,6 @@ unsigned long __get_wchan(struct task_struct *p)
 int do_work_pending(struct pt_regs *regs, u32 thread_info_flags);
 int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
 {
-	if (!(thread_info_flags & _TIF_WORK_MASK)) {
-		return 0;
-	}  /* shortcut -- no work to be done */
-
 	local_irq_enable();
 
 	if (thread_info_flags & _TIF_NEED_RESCHED) {
@@ -177,7 +173,5 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
 		return 1;
 	}
 
-	/* Should not even reach here */
-	panic("%s: bad thread_info flags 0x%08x\n", __func__,
-		thread_info_flags);
+	return 0;
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/7] hexagon: set the user stack pointer in start_thread
  2026-09-06  2:17 [PATCH 0/7] Hexagon build/syscall/etc fixes Brian Cain
                   ` (4 preceding siblings ...)
  2026-09-06  2:17 ` [PATCH 5/7] hexagon: let do_work_pending return without pending work Brian Cain
@ 2026-09-06  2:17 ` Brian Cain
  2026-09-06  2:17 ` [PATCH 7/7] hexagon: return -ENOSYS for unimplemented syscalls Brian Cain
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Cain @ 2026-09-06  2:17 UTC (permalink / raw)
  To: linux-hexagon; +Cc: sid.manning, pierrick.bouvier, Brian Cain

start_thread() set only the stack pointer that vmrte restores on the way
back to user mode, leaving the copy in pt_regs holding whatever the
previous thread had.  A ptrace stop between execve() and the first return
to user mode therefore reported a stale r29.  Set both.

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 arch/hexagon/kernel/process.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c
index f5e9934c36e3..6953c4b1fd5c 100644
--- a/arch/hexagon/kernel/process.c
+++ b/arch/hexagon/kernel/process.c
@@ -16,6 +16,7 @@
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/resume_user_mode.h>
+#include <asm/hexagon_vm.h>
 
 /*
  * Program thread launch.  Often defined as a macro in processor.h,
@@ -33,6 +34,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
 	/* We might want to also zero all Processor registers here */
 	pt_set_usermode(regs);
 	pt_set_elr(regs, pc);
+	regs->r29 = sp;
 	pt_set_rte_sp(regs, sp);
 }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 7/7] hexagon: return -ENOSYS for unimplemented syscalls
  2026-09-06  2:17 [PATCH 0/7] Hexagon build/syscall/etc fixes Brian Cain
                   ` (5 preceding siblings ...)
  2026-09-06  2:17 ` [PATCH 6/7] hexagon: set the user stack pointer in start_thread Brian Cain
@ 2026-09-06  2:17 ` Brian Cain
  6 siblings, 0 replies; 8+ messages in thread
From: Brian Cain @ 2026-09-06  2:17 UTC (permalink / raw)
  To: linux-hexagon; +Cc: sid.manning, pierrick.bouvier, Brian Cain

An out-of-range syscall number returned -1 (-EPERM) and a NULL entry in
the table was called anyway, crashing the kernel.  Return -ENOSYS for
both.

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 arch/hexagon/kernel/traps.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c
index 6fe0c1b62c1b..5cafd194fa48 100644
--- a/arch/hexagon/kernel/traps.c
+++ b/arch/hexagon/kernel/traps.c
@@ -372,13 +372,18 @@ void do_trap0(struct pt_regs *regs)
 		regs->restart_r0 = regs->r00;
 
 		if ((unsigned long) regs->syscall_nr >= __NR_syscalls) {
-			regs->r00 = -1;
+			regs->r00 = -ENOSYS;
 		} else {
 			syscall = (syscall_fn)
 				  (sys_call_table[regs->syscall_nr]);
-			regs->r00 = syscall(regs->r00, regs->r01,
-				   regs->r02, regs->r03,
-				   regs->r04, regs->r05);
+
+			if (!syscall) {
+				regs->r00 = -ENOSYS;
+			} else {
+				regs->r00 = syscall(regs->r00, regs->r01,
+						    regs->r02, regs->r03,
+						    regs->r04, regs->r05);
+			}
 		}
 
 		/* allow strace to get the syscall return state  */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-09-06  2:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-06  2:17 [PATCH 0/7] Hexagon build/syscall/etc fixes Brian Cain
2026-09-06  2:17 ` [PATCH 1/7] hexagon: disable the LLVM packetizer Brian Cain
2026-09-06  2:17 ` [PATCH 2/7] hexagon: define ELF_CORE_EFLAGS for V4-and-later architectures Brian Cain
2026-09-06  2:17 ` [PATCH 3/7] hexagon: stop passing -mv${CONFIG_HEXAGON_ARCH_VERSION} to the linker Brian Cain
2026-09-06  2:17 ` [PATCH 4/7] hexagon: read the thread-info register with a volatile asm Brian Cain
2026-09-06  2:17 ` [PATCH 5/7] hexagon: let do_work_pending return without pending work Brian Cain
2026-09-06  2:17 ` [PATCH 6/7] hexagon: set the user stack pointer in start_thread Brian Cain
2026-09-06  2:17 ` [PATCH 7/7] hexagon: return -ENOSYS for unimplemented syscalls Brian Cain

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox