]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
parisc: entry: set W bit for !compat tasks in syscall_restore_rfi()
authorSven Schnelle <svens@stackframe.org>
Wed, 15 Oct 2025 21:21:41 +0000 (23:21 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 19 Jan 2026 12:11:57 +0000 (13:11 +0100)
commit 5fb1d3ce3e74a4530042795e1e065422295f1371 upstream.

When the kernel leaves to userspace via syscall_restore_rfi(), the
W bit is not set in the new PSW. This doesn't cause any problems
because there's no 64 bit userspace for parisc. Simple static binaries
are usually loaded at addresses way below the 32 bit limit so the W bit
doesn't matter.

Fix this by setting the W bit when TIF_32BIT is not set.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/parisc/kernel/asm-offsets.c
arch/parisc/kernel/entry.S

index cd2cc1b1648c0a27b814c078e28db8e73038df44..39fac62a8b12d6f3985e2a2d4f410a50e82a9bd5 100644 (file)
@@ -262,6 +262,8 @@ int main(void)
        BLANK();
        DEFINE(TIF_BLOCKSTEP_PA_BIT, 31-TIF_BLOCKSTEP);
        DEFINE(TIF_SINGLESTEP_PA_BIT, 31-TIF_SINGLESTEP);
+       DEFINE(TIF_32BIT_PA_BIT, 31-TIF_32BIT);
+
        BLANK();
        DEFINE(ASM_PMD_SHIFT, PMD_SHIFT);
        DEFINE(ASM_PGDIR_SHIFT, PGDIR_SHIFT);
index aa86c101f2eb8fe3c12d1311f303fb6d671be21f..d9dc751b91be4d42eaefaffa656da6e4e95a2d34 100644 (file)
@@ -1913,6 +1913,10 @@ syscall_restore_rfi:
        extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
        depi    -1,7,1,%r20                        /* T bit */
 
+#ifdef CONFIG_64BIT
+       extru,<> %r19,TIF_32BIT_PA_BIT,1,%r0
+       depi    -1,4,1,%r20                        /* W bit */
+#endif
        STREG   %r20,TASK_PT_PSW(%r1)
 
        /* Always store space registers, since sr3 can be changed (e.g. fork) */
@@ -1926,7 +1930,6 @@ syscall_restore_rfi:
        STREG   %r25,TASK_PT_IASQ0(%r1)
        STREG   %r25,TASK_PT_IASQ1(%r1)
 
-       /* XXX W bit??? */
        /* Now if old D bit is clear, it means we didn't save all registers
         * on syscall entry, so do that now.  This only happens on TRACEME
         * calls, or if someone attached to us while we were on a syscall.