1.1 --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Mon Sep 23 08:56:19 2013 -0700 1.2 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Wed Sep 25 13:58:13 2013 +0200 1.3 @@ -876,3 +876,46 @@ 1.4 #endif 1.5 } 1.6 #endif 1.7 + 1.8 + 1.9 +/* 1.10 + * IA32 only: execute code at a high address in case buggy NX emulation is present. I.e. avoid CS limit 1.11 + * updates (JDK-8023956). 1.12 + */ 1.13 +void os::workaround_expand_exec_shield_cs_limit() { 1.14 +#if defined(IA32) 1.15 + size_t page_size = os::vm_page_size(); 1.16 + /* 1.17 + * Take the highest VA the OS will give us and exec 1.18 + * 1.19 + * Although using -(pagesz) as mmap hint works on newer kernel as you would 1.20 + * think, older variants affected by this work-around don't (search forward only). 1.21 + * 1.22 + * On the affected distributions, we understand the memory layout to be: 1.23 + * 1.24 + * TASK_LIMIT= 3G, main stack base close to TASK_LIMT. 1.25 + * 1.26 + * A few pages south main stack will do it. 1.27 + * 1.28 + * If we are embedded in an app other than launcher (initial != main stack), 1.29 + * we don't have much control or understanding of the address space, just let it slide. 1.30 + */ 1.31 + char* hint = (char*) (Linux::initial_thread_stack_bottom() - 1.32 + ((StackYellowPages + StackRedPages + 1) * page_size)); 1.33 + char* codebuf = os::reserve_memory(page_size, hint); 1.34 + if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) { 1.35 + return; // No matter, we tried, best effort. 1.36 + } 1.37 + if (PrintMiscellaneous && (Verbose || WizardMode)) { 1.38 + tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf); 1.39 + } 1.40 + 1.41 + // Some code to exec: the 'ret' instruction 1.42 + codebuf[0] = 0xC3; 1.43 + 1.44 + // Call the code in the codebuf 1.45 + __asm__ volatile("call *%0" : : "r"(codebuf)); 1.46 + 1.47 + // keep the page mapped so CS limit isn't reduced. 1.48 +#endif 1.49 +}