diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index e0a403b26f8..641a1652bbd 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -1590,10 +1590,13 @@ static char* reserve_shmated_memory (size_t bytes, char* requested_addr) { } // Now attach the shared segment. - // Note that I attach with SHM_RND - which means that the requested address is rounded down, if - // needed, to the next lowest segment boundary. Otherwise the attach would fail if the address - // were not a segment boundary. - char* const addr = (char*) shmat(shmid, requested_addr, SHM_RND); + // Note that we deliberately *don't* pass SHM_RND. The contract of os::attempt_reserve_memory_at() - + // which invokes this function with a request address != NULL - is to map at the specified address + // excactly, or to fail. If the caller passed us an address that is not usable (aka not a valid segment + // boundary), shmat should not round down the address, or think up a completely new one. + // (In places where this matters, e.g. when reserving the heap, we take care of passing segment-aligned + // addresses on Aix. See, e.g., ReservedHeapSpace. + char* const addr = (char*) shmat(shmid, requested_addr, 0); const int errno_shmat = errno; // (A) Right after shmat and before handing shmat errors delete the shm segment. diff --git a/test/hotspot/gtest/runtime/test_os.cpp b/test/hotspot/gtest/runtime/test_os.cpp index 9956956423c..be6e22f5f4e 100644 --- a/test/hotspot/gtest/runtime/test_os.cpp +++ b/test/hotspot/gtest/runtime/test_os.cpp @@ -25,6 +25,7 @@ #include "memory/allocation.hpp" #include "memory/resourceArea.hpp" #include "runtime/frame.inline.hpp" +#include "runtime/globals.hpp" #include "runtime/os.inline.hpp" #include "runtime/thread.hpp" #include "runtime/threads.hpp" @@ -948,6 +949,18 @@ TEST_VM(os, reserve_at_wish_address_shall_not_replace_mappings_largepages) { } } +#ifdef AIX +// On Aix, we should fail attach attempts not aligned to segment boundaries (256m) +TEST_VM(os, aix_reserve_at_non_shmlba_aligned_address) { + if (Use64KPages && Use64KPagesThreshold == 0) { + char* p = os::attempt_reserve_memory_at((char*)0x1f00000, M); + ASSERT_EQ(p, nullptr); // should have failed + p = os::attempt_reserve_memory_at((char*)((64 * G) + M), M); + ASSERT_EQ(p, nullptr); // should have failed + } +} +#endif // AIX + TEST_VM(os, vm_min_address) { size_t s = os::vm_min_address(); ASSERT_GE(s, M);