src/os_cpu/linux_x86/vm/os_linux_x86.cpp

changeset 5781
899ecf76b570
parent 5426
af21010d1062
child 6198
55fb97c4c58d
     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 +}

mercurial