Skip to content

Commit 6dda84d

Browse files
committed
Java stack guard pages
Signed-off-by: tajila <atobia@ca.ibm.com>
1 parent 5a147ad commit 6dda84d

File tree

5 files changed

+87
-9
lines changed

5 files changed

+87
-9
lines changed

runtime/oti/j9consts.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ extern "C" {
377377
#define J9_EXTENDED_RUNTIME3_DISCLAIM_ROM_CLASS_MEMORY 0x10
378378
#define J9_EXTENDED_RUNTIME3_DISCLAIM_RAM_CLASS_MEMORY 0x20
379379
#define J9_EXTENDED_RUNTIME3_USE_DEBUG_LOCAL_MAP 0x40
380+
#define J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES 0x80
380381

381382
#define J9_OBJECT_HEADER_AGE_DEFAULT 0xA /* OBJECT_HEADER_AGE_DEFAULT */
382383
#define J9_OBJECT_HEADER_SHAPE_MASK 0xE /* OBJECT_HEADER_SHAPE_MASK */

runtime/oti/j9nonbuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3177,6 +3177,8 @@ typedef struct J9JavaStack {
31773177
#if JAVA_SPEC_VERSION >= 19
31783178
BOOLEAN isVirtual;
31793179
#endif /* JAVA_SPEC_VERSION >= 19 */
3180+
UDATA *guardedPage;
3181+
UDATA defaultProtection;
31803182
} J9JavaStack;
31813183

31823184
/* @ddr_namespace: map_to_type=J9Object */
@@ -6584,6 +6586,7 @@ typedef struct J9JavaVM {
65846586
int64_t prevProcTimestamp;
65856587
omrthread_monitor_t cpuUtilCacheMutex;
65866588
#endif /* defined(OMR_THR_YIELD_ALG) */
6589+
UDATA defaultPageSize;
65876590
} J9JavaVM;
65886591

65896592
#define J9JFR_SAMPLER_STATE_UNINITIALIZED 0

runtime/oti/jvminit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,8 @@ enum INIT_STAGE {
417417
#define VMOPT_XXDISABLEEXTENDEDHCR "-XX:-EnableExtendedHCR"
418418
#define VMOPT_XXUSEDEBUGLOCALMAP "-XX:+UseDebugLocalMap"
419419
#define VMOPT_XXNOUSEDEBUGLOCALMAP "-XX:-UseDebugLocalMap"
420+
#define VMOPT_XXGUARDPAGEONJAVASTACK "-XX:+GuardPageOnJavaStack"
421+
#define VMOPT_XXNOGUARDPAGEONJAVASTACK "-XX:-GuardPageOnJavaStack"
420422

421423
#if defined(J9VM_ZOS_3164_INTEROPERABILITY)
422424
#define VMOPT_XXENABLE3164INTEROPERABILITY "-XX:+Enable3164Interoperability"

runtime/vm/jvminit.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,7 @@ initializeJavaVM(void * osMainThread, J9JavaVM ** vmPtr, J9CreateJavaVMParams *c
11931193
vm->loadedClassCount = 0;
11941194
vm->jfrState.blobFileDescriptor = -1;
11951195
#endif /* defined(J9VM_OPT_JFR) */
1196-
1196+
vm->defaultPageSize = j9vmem_supported_page_sizes()[0];
11971197
#if JAVA_SPEC_VERSION >= 19
11981198
/* tid 1 will be use by main thread, first usable tid starts at 2 */
11991199
vm->nextTID = 2;
@@ -4250,6 +4250,17 @@ processVMArgsFromFirstToLast(J9JavaVM * vm)
42504250
vm->extendedRuntimeFlags2 &= ~(UDATA)J9_EXTENDED_RUNTIME2_LEGACY_MANGLING;
42514251
}
42524252
}
4253+
{
4254+
IDATA enableGuardPages = FIND_AND_CONSUME_VMARG(EXACT_MATCH, VMOPT_XXGUARDPAGEONJAVASTACK, NULL);
4255+
IDATA disableGuardPages = FIND_AND_CONSUME_VMARG(EXACT_MATCH, VMOPT_XXNOGUARDPAGEONJAVASTACK, NULL);
4256+
if (enableGuardPages > disableGuardPages) {
4257+
vm->extendedRuntimeFlags3 |= J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES;
4258+
} else if (enableGuardPages <= disableGuardPages) {
4259+
vm->extendedRuntimeFlags3 &= ~(UDATA)J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES;
4260+
}
4261+
/* test */
4262+
vm->extendedRuntimeFlags3 |= J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES;
4263+
}
42534264

42544265
#if defined(J9VM_ZOS_3164_INTEROPERABILITY)
42554266
{

runtime/vm/vmthread.cpp

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424

2525
#include <string.h>
2626

27+
#if defined(LINUX)
28+
#include <sys/mman.h>
29+
#elif defined(WINDOWS)
30+
#include <windows.h>
31+
#endif
32+
2733
#include "omrcfg.h"
2834
#include "j9.h"
2935
#include "j9cfg.h"
@@ -1565,24 +1571,65 @@ J9JavaStack *
15651571
allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
15661572
{
15671573
PORT_ACCESS_FROM_JAVAVM(vm);
1568-
J9JavaStack * stack;
1569-
UDATA mallocSize;
1574+
J9JavaStack *stack = NULL;
1575+
UDATA mallocSize = 0;
1576+
UDATA pageSize = vm->defaultPageSize;
1577+
bool pageGuards = J9_ARE_ALL_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES);
1578+
UDATA stackMemory = 0;
15701579

15711580
/* Allocate the stack, adding the header and overflow area size.
15721581
* Add one slot for possible double-slot alignment.
15731582
* If stagger is in use, add the maximum stagger value to account for that alignment.
15741583
*/
15751584

15761585
mallocSize = J9_STACK_OVERFLOW_AND_HEADER_SIZE + (stackSize + sizeof(UDATA)) + vm->thrStaggerMax;
1586+
if (pageGuards) {
1587+
mallocSize += (pageSize * 2);
1588+
}
1589+
15771590
if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) {
1578-
stack = (J9JavaStack*)j9mem_allocate_memory32(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK);
1591+
stack = (J9JavaStack *)j9mem_allocate_memory32(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK);
15791592
} else {
1580-
stack = (J9JavaStack*)j9mem_allocate_memory(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK);
1593+
stack = (J9JavaStack *)j9mem_allocate_memory(mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK);
1594+
}
1595+
1596+
if (pageGuards) {
1597+
stackMemory = (UDATA)(stack + 1);
1598+
stackMemory = ROUND_UP_TO_POWEROF2(stackMemory, pageSize);
1599+
1600+
#if defined(LINUX)
1601+
if (0 == mprotect((void *)stackMemory, pageSize, PROT_NONE)) {
1602+
#elif defined(WINDOWS)
1603+
if (0 != VirtualProtect(stackMemory, pageSize, PAGE_NOACCESS, &stack->defaultProtection)) {
1604+
#endif
1605+
stack->guardedPage = (UDATA *)stackMemory;
1606+
stackMemory += pageSize;
1607+
} else {
1608+
if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) {
1609+
j9mem_free_memory32(stack);
1610+
} else {
1611+
j9mem_free_memory(stack);
1612+
}
1613+
stack = NULL;
1614+
}
15811615
}
1616+
15821617
if (stack != NULL) {
15831618
/* for hyperthreading platforms, make sure that stacks are relatively misaligned */
1584-
UDATA end = ((UDATA) stack) + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize;
1619+
UDATA end = 0;
15851620
UDATA stagger = vm->thrStagger;
1621+
1622+
if (pageGuards) {
1623+
end = stackMemory + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize;
1624+
if (end > ((UDATA)stack + mallocSize)) {
1625+
printf("corruption\n");
1626+
__asm__("int3");
1627+
1628+
}
1629+
} else {
1630+
end = ((UDATA) stack) + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize;
1631+
}
1632+
15861633
stagger += vm->thrStaggerStep;
15871634
vm->thrStagger = stagger = stagger >= vm->thrStaggerMax ? 0 : stagger;
15881635
if (vm->thrStaggerMax != 0) {
@@ -1613,7 +1660,12 @@ allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
16131660

16141661
#if defined (J9VM_INTERP_VERBOSE) || defined (J9VM_PROF_EVENT_REPORTING)
16151662
if (vm->runtimeFlags & J9_RUNTIME_PAINT_STACK) {
1616-
UDATA * currentSlot = (UDATA *) (stack + 1);
1663+
UDATA *currentSlot = NULL;
1664+
if (pageGuards) {
1665+
currentSlot = (UDATA *)stackMemory;
1666+
} else {
1667+
currentSlot = (UDATA *)(stack + 1);
1668+
}
16171669

16181670
while (currentSlot != stack->end)
16191671
*currentSlot++ = J9_RUNTIME_STACK_FILL;
@@ -1626,10 +1678,19 @@ allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
16261678

16271679

16281680
void
1629-
freeJavaStack(J9JavaVM * vm, J9JavaStack * stack)
1681+
freeJavaStack(J9JavaVM *vm, J9JavaStack *stack)
16301682
{
16311683
PORT_ACCESS_FROM_JAVAVM(vm);
1632-
1684+
if (J9_ARE_ALL_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES)) {
1685+
UDATA pageSize = vm->defaultPageSize;
1686+
#if defined(LINUX)
1687+
if (0 != mprotect((void *)stack->guardedPage, pageSize, PROT_READ|PROT_WRITE)) {
1688+
#elif defined(WINDOWS)
1689+
if (0 == VirtualProtect(stack->guardedPage, pageSize, 0, NULL)) {
1690+
#endif
1691+
Assert_VM_unreachable();
1692+
}
1693+
}
16331694
if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) {
16341695
j9mem_free_memory32(stack);
16351696
} else {

0 commit comments

Comments
 (0)