linux_dsm_epyc7002/kernel
akpm@osdl.org 838cd153a5 [PATCH] N32 sigset and __COMPAT_ENDIAN_SWAP__
I'm testing glibc on MIPS64, little-endian, N32, O32 and N64 multilibs.

Among the NPTL test failures seen are some arising from sigsuspend problems
for N32: it blocks the wrong signals, so SIGCANCEL (SIGRTMIN) is blocked
despite glibc's carefully excluding it from sets of signals to block.
Specifically, testing suggests it blocks signal N^32 instead of signal N,
so (in the example tested) blocking SIGUSR1 (17) blocks signal 49 instead.

glibc's sigset_t uses an array of unsigned long, as does the kernel.
In both cases, signal N+1 is represented as
(1UL << (N % (8 * sizeof (unsigned long)))) in word number
(N / (8 * sizeof (unsigned long))).

Thus the N32 glibc uses an array of 32-bit words and the N64 kernel uses an
array of 64-bit words.  For little-endian, the layout is the same, with
signals 1-32 in the first 4 bytes, signals 33-64 in the second, etc.; for
big-endian, userspace has that layout while in the kernel each 8 bytes have
the two halves swapped from the userspace layout.

The N32 sigsuspend syscall uses sigset_from_compat to convert the userspace
sigset to kernel format.  If __COMPAT_ENDIAN_SWAP__ is *not* set, this uses
logic of the form

  set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32 )

to convert the userspace sigset to a kernel one.  This looks correct to me
for both big and little endian, given that in userspace compat->sig[1] will
represent signals 33-64, and so will the high 32 bits of set->sig[0] in the
kernel.  If however __COMPAT_ENDIAN_SWAP__ *is* set, as it is for
__MIPSEL__, it uses

  set->sig[0] = compat->sig[1] | (((long)compat->sig[0]) << 32 );

which seems incorrect for both big and little endian, and would
explain the observed symptoms.

This code is the only use of __COMPAT_ENDIAN_SWAP__, so if incorrect
then that macro serves no purpose, in which case something like the
following patch would seem appropriate to remove it.

Signed-off-by: Joseph Myers <joseph@codesourcery.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-06-25 10:01:15 -07:00
..
irq [PATCH] adjust handle_IRR_event() return type 2006-06-23 07:43:08 -07:00
power [PATCH] constify parts of kernel/power/ 2006-06-25 10:01:08 -07:00
.gitignore
acct.c [PATCH] Remove unecessary NULL check in kernel/acct.c 2006-06-25 10:01:09 -07:00
audit.c [PATCH] log more info for directory entry change events 2006-06-20 05:25:28 -04:00
audit.h [PATCH] log more info for directory entry change events 2006-06-20 05:25:28 -04:00
auditfilter.c [PATCH] log more info for directory entry change events 2006-06-20 05:25:28 -04:00
auditsc.c [PATCH] Doc: add audit & acct to DocBook 2006-06-23 07:43:07 -07:00
capability.c
compat.c [PATCH] N32 sigset and __COMPAT_ENDIAN_SWAP__ 2006-06-25 10:01:15 -07:00
configs.c
cpu.c
cpuset.c [PATCH] SELinux: add security hook call to mediate attach_task (kernel/cpuset.c) 2006-06-23 07:42:54 -07:00
dma.c
exec_domain.c
exit.c [PATCH] kernel/sys.c: cleanups 2006-06-25 10:01:06 -07:00
extable.c
fork.c [PATCH] dup fd error fix 2006-06-23 07:43:04 -07:00
futex_compat.c
futex.c [PATCH] VFS: Permit filesystem to override root dentry on mount 2006-06-23 07:42:45 -07:00
hrtimer.c [PATCH] Define __raw_get_cpu_var and use it 2006-06-25 10:01:01 -07:00
itimer.c
kallsyms.c
Kconfig.hz
Kconfig.preempt
kexec.c [PATCH] Add a sysfs file to determine if a kexec kernel is loaded 2006-06-23 07:43:02 -07:00
kfifo.c
kmod.c
kprobes.c
ksysfs.c [PATCH] Add a sysfs file to determine if a kexec kernel is loaded 2006-06-23 07:43:02 -07:00
kthread.c
Makefile
module.c [PATCH] ensure NULL deref can't possibly happen in is_exported() 2006-06-25 10:00:59 -07:00
mutex-debug.c
mutex-debug.h
mutex.c
mutex.h
panic.c
params.c
pid.c
posix-cpu-timers.c [PATCH] arm_timer: remove a racy and obsolete PF_EXITING check 2006-06-17 10:52:13 -07:00
posix-timers.c
printk.c [PATCH] printk time parameter 2006-06-25 10:01:13 -07:00
profile.c
ptrace.c
rcupdate.c [PATCH] Make RCU API inaccessible to non-GPL Linux kernel modules 2006-06-23 07:43:07 -07:00
rcutorture.c
relay.c
resource.c
sched.c [PATCH] Define __raw_get_cpu_var and use it 2006-06-25 10:01:01 -07:00
seccomp.c
signal.c [PATCH] collect sid of those who send signals to auditd 2006-06-20 05:25:21 -04:00
softirq.c
softlockup.c [PATCH] Define __raw_get_cpu_var and use it 2006-06-25 10:01:01 -07:00
spinlock.c
stop_machine.c
sys_ni.c [PATCH] sys_move_pages: 32bit support (i386, x86_64) 2006-06-23 07:42:53 -07:00
sys.c [PATCH] kernel/sys.c: cleanups 2006-06-25 10:01:06 -07:00
sysctl.c [PATCH] Get rid of /proc/sys/proc 2006-06-25 10:01:15 -07:00
time.c
timer.c [PATCH] Define __raw_get_cpu_var and use it 2006-06-25 10:01:01 -07:00
uid16.c
user.c [PATCH] selinux: add hooks for key subsystem 2006-06-22 15:05:55 -07:00
wait.c
workqueue.c [PATCH] schedule_on_each_cpu(): reduce kmalloc() size 2006-06-25 10:01:07 -07:00