Subject: Re: 32 bit linux java solution?
To: None <port-amd64@netbsd.org>
From: Arto Huusko <arto.huusko@pp2.inet.fi>
List: port-amd64
Date: 11/21/2007 00:46:53
I think I have found the reason why 32 bit linux java eventually
ends up in the state where one thread keeps faulting, and another
thread keeps on calling sched_yield. (BTW, 64 bit java is not
functional even on AMD processors in -current, but that's beside
the point here...)

It has to do with some JVM feature called safepointing, which is
implemented by a thread manipulating protection of one page,
and then yielding until other threads notice the situation
by getting SIGSEGV, and doing whatever they need to do.

On NetBSD, the thread getting SIGSEGV doesn't notice that the
signal was received due to safepointing (and apparently ends up
restarting the instruction over and over again), because

  - for some reason JVM inspects the fault address from cr2 field
    of mcontext of ucontext (instead of si_addr of sigcontext)

    see JVM_handle_linux_signal in
	hotspot/src/os_cpu/linux_i486/os_linux_i486.cpp

  - NetBSD linux32 emul does not set this field

    see linux32_save_sigcontext in
	sys/compat/linux32/arch/amd64/linux32_machdep.c
    in revision 1.12, on line 389:

	/* sc->sc_cr2 = l->l_addr->u_pcb.pcb_cr2; */ /* XXX */

I unfortunately have no idea where a suitable value for cr2 is
available at that point...