diff --git a/repos/base/src/core/ram_dataspace_factory.cc b/repos/base/src/core/ram_dataspace_factory.cc index 04911289a0..691b9f1b6a 100644 --- a/repos/base/src/core/ram_dataspace_factory.cc +++ b/repos/base/src/core/ram_dataspace_factory.cc @@ -40,16 +40,24 @@ Ram_dataspace_factory::try_alloc(size_t ds_size, Cache cache) */ Range_allocator::Alloc_result allocated_range = Allocator::Alloc_error::DENIED; - /* - * If no physical constraint exists, try to allocate physical memory at - * high locations (3G for 32-bit / 4G for 64-bit platforms) in order to - * preserve lower physical regions for device drivers, which may have DMA - * constraints. - */ - if (_phys_range.start == 0 && _phys_range.end == ~0UL) { + /* apply constraints */ + if (_phys_range.start != 0 || _phys_range.end != ~0UL) { + for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { + allocated_range = _phys_alloc.alloc_aligned(ds_size, (unsigned)align_log2, _phys_range); + if (allocated_range.ok()) + break; + } + } + /* + * If no physical constraint exists or constraints failed, try to allocate + * physical memory at high locations (3G for 32-bit / 4G for 64-bit platforms) + * in order to preserve lower physical regions for device drivers, which may + * have DMA constraints. + */ + if (!allocated_range.ok()) { addr_t const high_start = (sizeof(void *) == 4 ? 3UL : 4UL) << 30; - Phys_range const range { .start = high_start, .end = _phys_range.end }; + Phys_range const range { .start = high_start, .end = ~0UL }; for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { allocated_range = _phys_alloc.alloc_aligned(ds_size, (unsigned)align_log2, range); @@ -58,7 +66,7 @@ Ram_dataspace_factory::try_alloc(size_t ds_size, Cache cache) } } - /* apply constraints, or retry if larger memory allocation failed */ + /* retry if larger non-constrained memory allocation failed */ if (!allocated_range.ok()) { for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { allocated_range = _phys_alloc.alloc_aligned(ds_size, (unsigned)align_log2, _phys_range);