diff --git a/libraries/base/src/GHC/RTS/Flags.hsc b/libraries/base/src/GHC/RTS/Flags.hsc
index 2424a4f2c4391293c999bd4adb14c92aa939bb92..0999dcbfcf9d9d2729adb2ba0173f3a0b18a816e 100644
--- a/libraries/base/src/GHC/RTS/Flags.hsc
+++ b/libraries/base/src/GHC/RTS/Flags.hsc
@@ -144,6 +144,7 @@ data GCFlags = GCFlags
     , minOldGenSize         :: Word32
     , heapSizeSuggestion    :: Word32
     , heapSizeSuggestionAuto :: Bool
+    , arbitraryHeapStart    :: Bool
     , oldGenFactor          :: Double
     , returnDecayFactor     :: Double
     , pcFreeHeap            :: Double
@@ -462,6 +463,8 @@ getGCFlags = do
           <*> #{peek GC_FLAGS, heapSizeSuggestion} ptr
           <*> (toBool <$>
                 (#{peek GC_FLAGS, heapSizeSuggestionAuto} ptr :: IO CBool))
+          <*> (toBool <$>
+                (#{peek GC_FLAGS, arbitraryHeapStart} ptr :: IO CBool))
           <*> #{peek GC_FLAGS, oldGenFactor} ptr
           <*> #{peek GC_FLAGS, returnDecayFactor} ptr
           <*> #{peek GC_FLAGS, pcFreeHeap} ptr
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c
index 8c384ad432728ab9ec8b5fc93e2a0c6fcf398870..6e841d838f9fb09490ecdf79b8c5253001a75af5 100644
--- a/rts/RtsFlags.c
+++ b/rts/RtsFlags.c
@@ -162,6 +162,7 @@ void initRtsFlagsDefaults(void)
     RtsFlags.GcFlags.heapLimitGrace     = (1024 * 1024);
     RtsFlags.GcFlags.heapSizeSuggestion = 0;    /* none */
     RtsFlags.GcFlags.heapSizeSuggestionAuto = false;
+    RtsFlags.GcFlags.arbitraryHeapStart = false;
     RtsFlags.GcFlags.pcFreeHeap         = 3;    /* 3% */
     RtsFlags.GcFlags.oldGenFactor       = 2;
     RtsFlags.GcFlags.returnDecayFactor  = 4;
@@ -1055,6 +1056,11 @@ error = true;
                        OPTION_UNSAFE;
                        RtsFlags.HpcFlags.writeTixFile = false;
                   }
+                  else if (strequal("arbitrary-heap-start",
+                               &rts_argv[arg][2])) {
+                      OPTION_UNSAFE;
+                      RtsFlags.GcFlags.arbitraryHeapStart = true;
+                  }
 #if defined(THREADED_RTS)
 #if defined(mingw32_HOST_OS)
                   else if (!strncmp("io-manager-threads",
diff --git a/rts/include/rts/Flags.h b/rts/include/rts/Flags.h
index e4405463311d625667b676ea195c6505efaa6248..5ef7273aace5465aad6493737b51383bd1500253 100644
--- a/rts/include/rts/Flags.h
+++ b/rts/include/rts/Flags.h
@@ -49,6 +49,7 @@ typedef struct _GC_FLAGS {
     uint32_t     minOldGenSize;      /* in *blocks* */
     uint32_t     heapSizeSuggestion; /* in *blocks* */
     bool heapSizeSuggestionAuto;
+    bool arbitraryHeapStart;
     double  oldGenFactor;
     double  returnDecayFactor;
     double  pcFreeHeap;
diff --git a/rts/posix/OSMem.c b/rts/posix/OSMem.c
index a6eabfcdeedc3cfd69271d74ca791bc03f01a163..c9ad67d2a7253b15782b9b4d01d56f05bae03416 100644
--- a/rts/posix/OSMem.c
+++ b/rts/posix/OSMem.c
@@ -608,9 +608,11 @@ void *osReserveHeapMemory(void *startAddressPtr, W_ *len)
             // physical memory but a 511GB ulimit). See #14492.
             *len -= *len / 8;
             // debugBelch("Limit hit, reduced len: %zu\n", *len);
-        } else if ((W_)at >= minimumAddress) {
+        } else if (RtsFlags.GcFlags.arbitraryHeapStart || (W_)at >= minimumAddress) {
             // Success! We were given a block of memory starting above the 8 GB
             // mark, which is what we were looking for.
+            // Or we allow to allocate the block anywhere by setting
+            // arbitraryHeapStart flag.
 
             break;
         } else {