RFR 8224676: Java crash if VSYSCALL is missing

Mikael Vidstedt mikael.vidstedt at oracle.com
Thu May 23 17:16:01 UTC 2019


Is this really correct? I think the CPU index needs to be extracted from the number, because not all bits are CPU index..?

Do we know that all relevant versions of linux support this? Is it always available on those versions?

Cheers,
Mikael

> On May 23, 2019, at 8:23 AM, Vladimir Kempik <vkempik at azul.com> wrote:
> 
> Hello,
> 
> Please review the following patch to address the issue:
> 
> Bug: https://bugs.openjdk.java.net/browse/JDK-8224676
> 
> Webrev: http://cr.openjdk.java.net/~vkempik/8224676/webrev.00/
> 
> Summary:
> Java (and epecially ZGC) is using VSYSCALL linux kernel functionality to get cpu-id for a thread, basically to know on which cpu current thread is running.
> A relevant peace of code:
> 
> 
> int os::Linux::sched_getcpu_syscall(void) {
>  unsigned int cpu = 0;
>  int retval = -1;
> 
> #if defined(IA32)
>  #ifndef SYS_getcpu
>    #define SYS_getcpu 318
>  #endif
>  retval = syscall(SYS_getcpu, &cpu, NULL, NULL);
> #elif defined(AMD64)
> // Unfortunately we have to bring all these macros here from vsyscall.h
> // to be able to compile on old linuxes.
>  #define __NR_vgetcpu 2
>  #define VSYSCALL_START (-10UL << 20)
>  #define VSYSCALL_SIZE 1024
>  #define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr))
>  typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache);
>  vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu);
>  retval = vgetcpu(&cpu, NULL, NULL);
> #endif
> 
> 
> In x86 linux it’s going syscall way, which is a bit slow due to context switching.
> on linux x86_64 it’s using VSYSCALL functionality, which is basically a page at fixed address which can execute 3 different syscalls (their analogues in user space) without context switch, in a very fast way.
> 
> VSYSCALL functionality is known to be insecure when ASLR is used, hence it’s being disabled sometimes.
> For example in alpine linux it’s disabled by default and even its emulation (via a trap) by kernel is disabled. So one can’t use VSYSCALL at all and java crashes.
> 
> There is two ways to work it around: unify x86 and x86_64 routines and go syscall always (could be slow) or use functionality similar to vdso (it’s similar to VSYSCALL but the page is at different address on every app launch).
> 
> There is no low cost way to find out if VSYSCALL functionality is present  or not.
> This patch remove VSYSCALL functionality and does perform simple asm instruction to get cpu id.
> it’s very imilar to what happens in vgetcpu function in vdso: https://elixir.bootlin.com/linux/v4.4/source/arch/x86/include/asm/vgtod.h#L77
> 
> Regards, Vladimir



More information about the hotspot-runtime-dev mailing list