We'd like to avoid committing to a specific size of virtual address
space (i.e. the value of VM_AARCH64_T0SZ) on AArch64. While the current
version of GNU Mach still exports VM_MAX_ADDRESS for compatibility, we
should try to avoid relying on it when we can. This piece of logic in
_hurdsig_getenv () doesn't actually care about the size of user-
accessible virtual address space, it just wants to preempt faults on any
addresses starting from the value of the P pointer and above. So, use
(unsigned long int) -1 instead of VM_MAX_ADDRESS.
While at it, change the casts to (unsigned long int) and not just
(long int), since the type of struct hurd_signal_preemptor.{first,last}
is unsigned long int.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-ID: <20240323173301.151066-3-bugaevc@gmail.com>
These symbols are internal and never exported; make sure the compiler
realizes that when compiling hurdsig.c and does not try to emit GOT
reads.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
...instead of mach_setup_thread (), which is unsuitable for setting up
function calls.
Checked on x86_64-gnu: the signal thread no longer crashes upon trying
to process a message.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-Id: <20230517191436.73636-6-bugaevc@gmail.com>
If we're trying to interrupt an interruptible RPC, but the server fails
to respond to our __interrupt_operation () call, we instead destroy the
reply port we were expecting the reply to the RPC on.
Instead of deallocating the name completely, replace it with a dead
name, so the name won't get reused for some other right, and deallocate
it in _hurd_intr_rpc_mach_msg once we return from the signal handler.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-Id: <20230429201822.2605207-4-bugaevc@gmail.com>
Each libc_hidden_def should be placed immediately next to its function,
not in some random unrelated place.
No functional change.
Fixes: 653d74f12a
"hurd: Global signal disposition"
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-Id: <20230429131354.2507443-2-bugaevc@gmail.com>
Also, fix a couple of typos. No functional change.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-Id: <20230301162355.426887-2-bugaevc@gmail.com>
"We don't need it any more"
The INTR_MSG_TRAP macro in intr-msg.h used to play little trick with
the stack pointer: it would temporarily save the "real" stack pointer
into ecx, while setting esp to point to just before the message buffer,
and then invoke the mach_msg trap. This way, INTR_MSG_TRAP reused the
on-stack arguments laid out for the containing call of
_hurd_intr_rpc_mach_msg (), passing them to the mach_msg trap directly.
This, however, required special support in hurdsig.c and trampoline.c,
since they now had to recognize when a thread is inside the piece of
code where esp doesn't point to the real tip of the stack, and handle
this situation specially.
Commit 1d20f33ff4 has removed the actual
temporary change of esp by actually re-pushing mach_msg arguments onto
the stack, and popping them back at end. It did not, however, deal with
the rest of "the ecx kludge" code in other files, resulting in potential
crashes if a signal arrives in the middle of pushing arguments onto the
stack.
Fix that by removing "the ecx kludge". Instead, when we want a thread
to skip the RPC, but cannot make just make it jump to after the trap
since it's not done adjusting the stack yet, set the SYSRETURN register
to MACH_SEND_INTERRUPTED (as we do anyway), and rely on the thread
itself for detecting this case and skipping the RPC.
This simplifies things somewhat and paves the way for a future x86_64
port of this code.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-Id: <20230301162355.426887-1-bugaevc@gmail.com>
Fix a few more cases of build errors caused by mismatched types. This is a
continuation of f4315054b4.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-Id: <20230218203717.373211-3-bugaevc@gmail.com>
I used these shell commands:
../glibc/scripts/update-copyrights $PWD/../gnulib/build-aux/update-copyright
(cd ../glibc && git commit -am"[this commit message]")
and then ignored the output, which consisted lines saying "FOO: warning:
copyright statement not found" for each of 7061 files FOO.
I then removed trailing white space from math/tgmath.h,
support/tst-support-open-dev-null-range.c, and
sysdeps/x86_64/multiarch/strlen-vec.S, to work around the following
obscure pre-commit check failure diagnostics from Savannah. I don't
know why I run into these diagnostics whereas others evidently do not.
remote: *** 912-#endif
remote: *** 913:
remote: *** 914-
remote: *** error: lines with trailing whitespace found
...
remote: *** error: sysdeps/unix/sysv/linux/statx_cp.c: trailing lines
I used these shell commands:
../glibc/scripts/update-copyrights $PWD/../gnulib/build-aux/update-copyright
(cd ../glibc && git commit -am"[this commit message]")
and then ignored the output, which consisted lines saying "FOO: warning:
copyright statement not found" for each of 6694 files FOO.
I then removed trailing white space from benchtests/bench-pthread-locks.c
and iconvdata/tst-iconv-big5-hkscs-to-2ucs4.c, to work around this
diagnostic from Savannah:
remote: *** pre-commit check failed ...
remote: *** error: lines with trailing whitespace found
remote: error: hook declined to update refs/heads/master
Instead of having the arch-specific trampoline setup code detect whether
preemption happened or not, we'd rather pass it the sigaction. In the
future, this may also allow to change sa_flags from post_signal().
This change is required in order to correctly release per-thread
resources. Directly reusing the threading library reference isn't
possible since the sigstate is also used early in the main thread,
before threading is initialized.
* hurd/hurd/signal.h (_hurd_self_sigstate): Drop thread reference after
calling _hurd_thread_sigstate.
(_hurd_critical_section_lock): Likewise.
* hurd/hurdsig.c (_hurd_thread_sigstate): Add a reference on the thread.
(_hurd_sigstate_delete): Drop thread reference.
SA_SIGINFO is actually just another way of expressing what we were
already passing over with struct sigcontext. This just introduces the
SIGINFO interface and fixes the posix values when that interface is
requested by the application.
This fixes various build errors due to deprecation warnings.
Fixes commit 02802fafcf
("signal: Deprecate additional legacy signal handling functions").
Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
In case the signal arrives before the __mach_msg call, we need to catch
between the sigprocmask call and the __mach_msg call. Let's just reuse
the support for sigsuspend to make the signal send a message that
our __mach_msg call will just receive.
* hurd/hurdselect.c (_hurd_select): Add sigport and ss variables. When
sigmask is not NULL, create a sigport port and register as
ss->suspended. Add it to the portset. When we receive a message on it,
set error to EINTR. Clean up sigport and portset appropriately.
* hurd/hurdsig.c (wake_sigsuspend): Note that pselect also uses it.
This adds _hurd_sigstate_set_global_rcv used by libpthread to enable
POSIX-confirming behavior of signals on a per-thread basis.
This also provides a sigstate destructor _hurd_sigstate_delete, and a
global process signal state, which needs to be locked and check when
global disposition is enabled, thus the addition of _hurd_sigstate_lock
_hurd_sigstate_actions _hurd_sigstate_pending _hurd_sigstate_unlock helpers.
This also updates all the glibc code accordingly.
This also drops support for get_int(INIT_SIGMASK), which did not make sense
any more since we do not have a single signal thread any more.
During fork/spawn, this also reinitializes the child global sigstate's
lock. That cures an issue that would very rarely cause a deadlock in the
child in fork, tries to unlock ss' critical section lock at the end of
fork. This will typically (always?) be observed in /bin/sh, which is not
surprising as that is the foremost caller of fork.
To reproduce an intermediate state, add an endless loop if
_hurd_global_sigstate is locked after __proc_dostop (cast through
volatile); that is, while still being in the fork's parent process.
When that triggers (use the libtool testsuite), the signal thread has
already locked ss (which is _hurd_global_sigstate), and is stuck at
hurdsig.c:685 in post_signal, trying to lock _hurd_siglock (which the
main thread already has locked and keeps locked until after
__task_create). This is the case that ss->thread == MACH_PORT_NULL, that
is, a global signal. In the main thread, between __proc_dostop and
__task_create is the __thread_abort call on the signal thread which would
abort any current kernel operation (but leave ss locked). Later in fork,
in the parent, when _hurd_siglock is unlocked in fork, the parent's
signal thread can proceed and will unlock eventually the global sigstate.
In the client, _hurd_siglock will likewise be unlocked, but the global
sigstate never will be, as the client's signal thread has been configured
to restart execution from _hurd_msgport_receive. Thus, when the child
tries to unlock ss' critical section lock at the end of fork, it will
first lock the global sigstate, will spin trying to lock it, which can
never be successful, and we get our deadlock.
Options seem to be:
* Move the locking of _hurd_siglock earlier in post_signal -- but that
may generally impact performance, if this locking isn't generally
needed anyway?
On the other hand, would it actually make sense to wait here until we
are not any longer in a critical section (which is meant to disable
signal delivery anyway (but not for preempted signals?))?
* Clear the global sigstate in the fork's child with the rationale that
we're anyway restarting the signal thread from a clean state. This
has now been implemented.
Why has this problem not been observed before Jérémie's patches? (Or has
it? Perhaps even more rarely?) In _S_msg_sig_post, the signal is now
posted to a *global receiver thread*, whereas previously it was posted to
the *designated signal-receiving thread*. The latter one was in a
critical section in fork, so didn't try to handle the signal until after
leaving the critical section? (Not completely analyzed and verified.)
Another question is what the signal is that is being received
during/around the time __proc_dostop executes.
This should not change the current behavior, although this fixes a few
minor bugs which were made apparent in the process of global signal
disposition work:
- Split into more functions
- Scope variables more restrictively
- Split out inner functions
- refactor check_pending_signals
- make sigsuspend POSIX-conformant.
- fix uninitialized act value.
* sysdeps/mach/hurd/i386/intr-msg.h (INTR_MSG_TRAP): Make
_hurd_intr_rpc_msg_about_to global point to start of controlled
assembly snippet. Make it check canceled flag.
* hurd/hurdsig.c (_hurdsig_abort_rpcs): Only mutate thread if it passed
the _hurd_intr_rpc_msg_about_to point.
* hurd/intr-msg.c (_hurd_intr_rpc_mach_msg): Remove comment on mutation
issue, remove cancel flag check.
Seeing a server not able to get interrupted for 3s is not so surprising when
e.g. a lot of writes are happening. 1 minute allows to actually notice the
issue and be able to debug it.
* hurd/hurdsig.c (_hurd_interrupted_rpc_timeout): Set to 60000.
Exec needs that mach_setup_thread does *not* set up TLS since it works on
another task, so we have to split this into mach_setup_tls.
* mach/mach.h (__mach_setup_tls, mach_setup_tls): Add prototypes.
* mach/setup-thread.c (__mach_setup_thread): Move TLS setup to...
(__mach_setup_tls): ... new function.
(mach_setup_tls): New alias.
* hurd/hurdsig.c (_hurdsig_init): Call __mach_setup_tls after
__mach_setup_thread.
* sysdeps/mach/hurd/profil.c (update_waiter): Likewise.
* sysdeps/mach/hurd/setitimer.c (setitimer_locked): Likewise.
* mach/Versions [libc] (mach_setup_tls): Add symbol.
* sysdeps/mach/hurd/i386/libc.abilist (mach_setup_tls): Likewise.
* hurd/Makefile (routines): Add hurdlock.
* hurd/Versions (GLIBC_PRIVATE): Added new entry to export the above
interface.
(HURD_CTHREADS_0.3): Remove __libc_getspecific.
* hurd/hurdpid.c: Include <lowlevellock.h>
(_S_msg_proc_newids): Use lll_wait to synchronize.
* hurd/hurdsig.c: (reauth_proc): Use __mutex_lock and __mutex_unlock.
* hurd/setauth.c: Include <hurdlock.h>, use integer for synchronization.
* mach/Makefile (lock-headers): Remove machine-lock.h.
* mach/lock-intern.h: Include <lowlevellock.h> instead of
<machine-lock.h>.
(__spin_lock_t): New type.
(__SPIN_LOCK_INITIALIZER): New macro.
(__spin_lock, __spin_unlock, __spin_try_lock, __spin_lock_locked,
__mutex_init, __mutex_lock_solid, __mutex_unlock_solid, __mutex_lock,
__mutex_unlock, __mutex_trylock): Use lll to implement locks.
* mach/mutex-init.c: Include <lowlevellock.h> instead of <cthreads.h>.
(__mutex_init): Initialize with lll.
* manual/errno.texi (EOWNERDEAD, ENOTRECOVERABLE): New errno values.
* sysdeps/mach/Makefile: Add libmachuser as dependencies for libs
needing lll.
* sysdeps/mach/hurd/bits/errno.h: Regenerate.
* sysdeps/mach/hurd/cthreads.c (__libc_getspecific): Remove function.
* sysdeps/mach/hurd/bits/libc-lock.h: Remove file.
* sysdeps/mach/hurd/setpgid.c: Include <lowlevellock.h>.
(__setpgid): Use lll for synchronization.
* sysdeps/mach/hurd/setsid.c: Likewise with __setsid.
* sysdeps/mach/bits/libc-lock.h: Include <tls.h> and <lowlevellock.h>
instead of <cthreads.h>.
(_IO_lock_inexpensive): New macro
(__libc_lock_recursive_t, __rtld_lock_recursive_t): New structures.
(__libc_lock_self0): New declaration.
(__libc_lock_owner_self): New macro.
(__libc_key_t): Remove type.
(_LIBC_LOCK_INITIALIZER): New macro.
(__libc_lock_define_initialized, __libc_lock_init, __libc_lock_fini,
__libc_lock_fini_recursive, __rtld_lock_fini_recursive,
__libc_lock_lock, __libc_lock_trylock, __libc_lock_unlock,
__libc_lock_define_initialized_recursive,
__rtld_lock_define_initialized_recursive,
__libc_lock_init_recursive, __libc_lock_trylock_recursive,
__libc_lock_lock_recursive, __libc_lock_unlock_recursive,
__rtld_lock_initialize, __rtld_lock_trylock_recursive,
__rtld_lock_lock_recursive, __rtld_lock_unlock_recursive
__libc_once_define, __libc_mutex_unlock): Reimplement with lll.
(__libc_lock_define_recursive, __rtld_lock_define_recursive,
_LIBC_LOCK_RECURSIVE_INITIALIZER, _RTLD_LOCK_RECURSIVE_INITIALIZER):
New macros.
Include <libc-lockP.h> to reimplement libc_key* with pthread_key*.
* hurd/hurdlock.c: New file.
* hurd/hurdlock.h: New file.
* mach/lowlevellock.h: New file
This gets rid of a lot of kludge and gets closer to other ports.
* hurd/Makefile (headers): Remove threadvar.h.
(inline-headers): Remove threadvar.h.
* hurd/Versions (GLIBC_2.0: Remove __hurd_sigthread_stack_base,
__hurd_sigthread_stack_end, __hurd_sigthread_variables,
__hurd_threadvar_max, __hurd_errno_location.
(HURD_CTHREADS_0.3): Add pthread_getattr_np, pthread_attr_getstack.
* hurd/hurd/signal.h: Do not include <hurd/threadvar.h>.
(_hurd_self_sigstate): Use THREAD_SELF to get _hurd_sigstate.
(_HURD_SIGNAL_H_EXTERN_INLINE): Use THREAD_SELF to get _hurd_sigstate,
unless TLS is not initialized yet, in which case we do not need a
critical section yet anyway.
* hurd/hurd/threadvar.h: Include <tls.h>, do not include
<machine-sp.h>.
(__hurd_sigthread_variables, __hurd_threadvar_max): Remove variables
declarations.
(__hurd_threadvar_index): Remove enum.
(_HURD_THREADVAR_H_EXTERN_INLINE): Remove macro.
(__hurd_threadvar_location_from_sp,__hurd_threadvar_location): Remove
inlines.
(__hurd_reply_port0): New variable declaration.
(__hurd_local_reply_port): New macro.
* hurd/hurdsig.c (__hurd_sigthread_variables): Remove variable.
(interrupted_reply_port_location): Add thread_t parameter. Use it
with THREAD_TCB to access thread-local variables.
(_hurdsig_abort_rpcs): Pass ss->thread to
interrupted_reply_port_location.
(_hurd_internal_post_signal): Likewise.
(_hurdsig_init): Use presence of cthread_fork instead of
__hurd_threadvar_stack_mask to start signal thread by hand.
Remove signal thread threadvar initialization.
* hurd/hurdstartup.c: Do not include <hurd/threadvar.h>
* hurd/sigunwind.c: Include <hurd/threadvar.h>
(_hurdsig_longjmp_from_handler): Use __hurd_local_reply_port instead
of threadvar.
* sysdeps/mach/hurd/Versions (libc.GLIBC_PRIVATE): Add
__libc_lock_self0.
(ld.GLIBC_2.0): Remove __hurd_sigthread_stack_base,
__hurd_sigthread_stack_end, __hurd_sigthread_variables.
(ld.GLIBC_PRIVATE): Add __libc_lock_self0.
* sysdeps/mach/hurd/cthreads.c: Add __libc_lock_self0.
* sysdeps/mach/hurd/dl-sysdep.c (errno, __hurd_sigthread_stack_base,
__hurd_sigthread_stack_end, __hurd_sigthread_variables, threadvars,
__hurd_threadvar_stack_offset, __hurd_threadvar_stack_mask): Do not
define variables.
* sysdeps/mach/hurd/errno-loc.c: Do not include <errno.h> and
<hurd/threadvar.h>.
[IS_IN(rtld)] (rtld_errno): New variable.
[IS_IN(rtld)] (__errno_location): New weak function.
[!IS_IN(rtld)]: Include "../../../csu/errno-loc.c".
* sysdeps/mach/hurd/errno.c: Remove file.
* sysdeps/mach/hurd/fork.c: Include <hurd/threadvar.h>
(__fork): Remove THREADVAR_SPACE macro and its use.
* sysdeps/mach/hurd/i386/init-first.c (__hurd_threadvar_max): Remove
variable.
(init): Do not initialize threadvar.
* sysdeps/mach/hurd/i386/libc.abilist (__hurd_threadvar_max): Remove
symbol.
* sysdeps/mach/hurd/i386/sigreturn.c (__sigreturn): Use
__hurd_local_reply_port instead of threadvar.
* sysdeps/mach/hurd/i386/tls.h (tcbhead_t): Add reply_port and
_hurd_sigstate fields.
(HURD_DESC_TLS, __LIBC_NO_TLS, THREAD_TCB): New macro.
* sysdeps/mach/hurd/i386/trampoline.c: Remove outdated comment.
* sysdeps/mach/hurd/libc-lock.h: Do not include <hurd/threadvar.h>.
(__libc_lock_owner_self): Use &__libc_lock_self0 and THREAD_SELF
instead of threadvar.
* sysdeps/mach/hurd/libc-tsd.h: Remove file.
* sysdeps/mach/hurd/mig-reply.c (GETPORT, reply_port): Remove macros.
(use_threadvar, global_reply_port): Remove variables.
(__hurd_reply_port0): New variable.
(__mig_get_reply_port): Use __hurd_local_reply_port and
__hurd_reply_port0 instead of threadvar.
(__mig_dealloc_reply_port): Likewise.
(__mig_init): Do not initialize threadvar.
* sysdeps/mach/hurd/profil.c: Fix comment.
Add net/ethernet.h net/if_arp.h net/if_ether.h net/if_ppp.h
net/route.h.
* hurd/report-wait.c (describe_number): Use __stpcpy to prepend
flavor to description only when flavor is not NULL.
* hurd/hurdsig.c (signal_allowed): Unlock _hurd_dtable_lock
mutex after SIGIO/SIGURG lookup loop.
ignore a signal that came from a machine exception, treat it as a
fatal core-dump signal instead.
Reported by Samuel Thibault <samuel.thibault@ens-lyon.org>.