1 // Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "address_mapper.h" 6 7 #include <algorithm> 8 #include <memory> 9 10 #include "base/logging.h" 11 #include "base/macros.h" 12 13 #include "compat/test.h" 14 15 namespace quipper { 16 17 namespace { 18 19 struct Range { 20 uint64_t addr; 21 uint64_t size; 22 uint64_t id; 23 uint64_t base_offset; 24 25 Range() : addr(0), size(0), id(0), base_offset(0) {} 26 27 Range(uint64_t addr, uint64_t size, uint64_t id, uint64_t base_offset) 28 : addr(addr), size(size), id(id), base_offset(base_offset) {} 29 30 bool contains(const uint64_t check_addr) const { 31 return (check_addr >= addr && check_addr < addr + size); 32 } 33 }; 34 35 // Some address ranges to map. It is important that none of these overlap with 36 // each other, nor are any two of them contiguous. 37 const Range kMapRanges[] = { 38 Range(0xff000000, 0x100000, 0xdeadbeef, 0), 39 Range(0x00a00000, 0x10000, 0xcafebabe, 0), 40 Range(0x0c000000, 0x1000000, 0x900df00d, 0), 41 Range(0x00001000, 0x30000, 0x9000091e, 0), 42 }; 43 44 // List of real addresses that are not in the above ranges. 45 const uint64_t kAddressesNotInRanges[] = { 46 0x00000000, 0x00000100, 0x00038000, 0x00088888, 0x00100000, 0x004fffff, 47 0x00a20000, 0x00cc0000, 0x00ffffff, 0x03e00000, 0x0b000000, 0x0d100000, 48 0x0fffffff, 0x1fffffff, 0x7ffffff0, 0xdffffff0, 0xfe000000, 0xffffffff, 49 }; 50 51 // Number of regularly-spaced intervals within a mapped range to test. 52 const int kNumRangeTestIntervals = 8; 53 54 // A simple test function to convert a real address to a mapped address. 55 // Address ranges in |ranges| are mapped starting at address 0. 56 uint64_t GetMappedAddressFromRanges(const Range* ranges, 57 const unsigned int num_ranges, 58 const uint64_t addr) { 59 unsigned int i; 60 uint64_t mapped_range_addr; 61 for (i = 0, mapped_range_addr = 0; i < num_ranges; 62 mapped_range_addr += ranges[i].size, ++i) { 63 const Range& range = ranges[i]; 64 if (range.contains(addr)) return (addr - range.addr) + mapped_range_addr; 65 } 66 return static_cast<uint64_t>(-1); 67 } 68 69 } // namespace 70 71 // The unit test class for AddressMapper. 72 class AddressMapperTest : public ::testing::Test { 73 public: 74 AddressMapperTest() {} 75 ~AddressMapperTest() {} 76 77 virtual void SetUp() { mapper_.reset(new AddressMapper); } 78 79 protected: 80 // Maps a range using the AddressMapper and makes sure that it was successful. 81 // Uses all fields of |range|, including id and base_offset. 82 bool MapRange(const Range& range, bool remove_old_mappings) { 83 VLOG(1) << "Mapping range at " << std::hex << range.addr 84 << " with length of " << range.size << " and id " << range.id; 85 return mapper_->MapWithID(range.addr, range.size, range.id, 86 range.base_offset, remove_old_mappings); 87 } 88 89 // Tests a range that has been mapped. |expected_mapped_addr| is the starting 90 // address that it should have been mapped to. This mapper will test the start 91 // and end addresses of the range, as well as a bunch of addresses inside it. 92 // Also checks lookup of ID and offset. 93 void TestMappedRange(const Range& range, uint64_t expected_mapped_addr) { 94 uint64_t mapped_addr = UINT64_MAX; 95 AddressMapper::MappingList::const_iterator addr_iter; 96 97 VLOG(1) << "Testing range at " << std::hex << range.addr 98 << " with length of " << std::hex << range.size; 99 100 // Check address at the beginning of the range and at subsequent intervals. 101 for (int i = 0; i < kNumRangeTestIntervals; ++i) { 102 const uint64_t offset = i * (range.size / kNumRangeTestIntervals); 103 uint64_t addr = range.addr + offset; 104 EXPECT_TRUE(mapper_->GetMappedAddressAndListIterator(addr, &mapped_addr, 105 &addr_iter)); 106 EXPECT_EQ(expected_mapped_addr + offset, mapped_addr); 107 108 uint64_t mapped_offset; 109 uint64_t mapped_id; 110 mapper_->GetMappedIDAndOffset(addr, addr_iter, &mapped_id, 111 &mapped_offset); 112 EXPECT_EQ(range.base_offset + offset, mapped_offset); 113 EXPECT_EQ(range.id, mapped_id); 114 } 115 116 // Check address at end of the range. 117 EXPECT_TRUE(mapper_->GetMappedAddressAndListIterator( 118 range.addr + range.size - 1, &mapped_addr, &addr_iter)); 119 EXPECT_EQ(expected_mapped_addr + range.size - 1, mapped_addr); 120 } 121 122 std::unique_ptr<AddressMapper> mapper_; 123 }; 124 125 // Map one range at a time and test looking up addresses. 126 TEST_F(AddressMapperTest, MapSingle) { 127 for (const Range& range : kMapRanges) { 128 mapper_.reset(new AddressMapper); 129 ASSERT_TRUE(MapRange(range, false)); 130 EXPECT_EQ(1U, mapper_->GetNumMappedRanges()); 131 TestMappedRange(range, 0); 132 133 // Check addresses before the mapped range, should be invalid. 134 uint64_t mapped_addr; 135 AddressMapper::MappingList::const_iterator iter; 136 EXPECT_FALSE(mapper_->GetMappedAddressAndListIterator(range.addr - 1, 137 &mapped_addr, &iter)); 138 EXPECT_FALSE(mapper_->GetMappedAddressAndListIterator(range.addr - 0x100, 139 &mapped_addr, &iter)); 140 EXPECT_FALSE(mapper_->GetMappedAddressAndListIterator( 141 range.addr + range.size, &mapped_addr, &iter)); 142 EXPECT_FALSE(mapper_->GetMappedAddressAndListIterator( 143 range.addr + range.size + 0x100, &mapped_addr, &iter)); 144 EXPECT_EQ(range.size, mapper_->GetMaxMappedLength()); 145 } 146 } 147 148 // Map all the ranges at once and test looking up addresses. 149 TEST_F(AddressMapperTest, MapAll) { 150 uint64_t size_mapped = 0; 151 for (const Range& range : kMapRanges) { 152 ASSERT_TRUE(MapRange(range, false)); 153 size_mapped += range.size; 154 } 155 EXPECT_EQ(arraysize(kMapRanges), mapper_->GetNumMappedRanges()); 156 157 // Check the max mapped length in quipper space. 158 EXPECT_EQ(size_mapped, mapper_->GetMaxMappedLength()); 159 160 // For each mapped range, test addresses at the start, middle, and end. 161 // Also test the address right before and after each range. 162 uint64_t mapped_addr; 163 AddressMapper::MappingList::const_iterator iter; 164 for (const Range& range : kMapRanges) { 165 TestMappedRange(range, GetMappedAddressFromRanges( 166 kMapRanges, arraysize(kMapRanges), range.addr)); 167 168 // Check addresses before and after the mapped range, should be invalid. 169 EXPECT_FALSE(mapper_->GetMappedAddressAndListIterator(range.addr - 1, 170 &mapped_addr, &iter)); 171 EXPECT_FALSE(mapper_->GetMappedAddressAndListIterator(range.addr - 0x100, 172 &mapped_addr, &iter)); 173 EXPECT_FALSE(mapper_->GetMappedAddressAndListIterator( 174 range.addr + range.size, &mapped_addr, &iter)); 175 EXPECT_FALSE(mapper_->GetMappedAddressAndListIterator( 176 range.addr + range.size + 0x100, &mapped_addr, &iter)); 177 } 178 179 // Test some addresses that are out of these ranges, should not be able to 180 // get mapped addresses. 181 for (uint64_t addr : kAddressesNotInRanges) 182 EXPECT_FALSE( 183 mapper_->GetMappedAddressAndListIterator(addr, &mapped_addr, &iter)); 184 } 185 186 // Map all the ranges at once and test looking up IDs and offsets. 187 TEST_F(AddressMapperTest, MapAllWithIDsAndOffsets) { 188 for (const Range& range : kMapRanges) { 189 LOG(INFO) << "Mapping range at " << std::hex << range.addr 190 << " with length of " << std::hex << range.size; 191 ASSERT_TRUE(mapper_->MapWithID(range.addr, range.size, range.id, 0, false)); 192 } 193 EXPECT_EQ(arraysize(kMapRanges), mapper_->GetNumMappedRanges()); 194 195 // For each mapped range, test addresses at the start, middle, and end. 196 // Also test the address right before and after each range. 197 for (const Range& range : kMapRanges) { 198 TestMappedRange(range, GetMappedAddressFromRanges( 199 kMapRanges, arraysize(kMapRanges), range.addr)); 200 } 201 } 202 203 // Test overlap detection. 204 TEST_F(AddressMapperTest, OverlapSimple) { 205 // Map all the ranges first. 206 for (const Range& range : kMapRanges) ASSERT_TRUE(MapRange(range, false)); 207 208 // Attempt to re-map each range, but offset by size / 2. 209 for (const Range& range : kMapRanges) { 210 Range new_range; 211 new_range.addr = range.addr + range.size / 2; 212 new_range.size = range.size; 213 // The maps should fail because of overlap with an existing mapping. 214 EXPECT_FALSE(MapRange(new_range, false)); 215 } 216 217 // Re-map each range with the same offset. Only this time, remove any old 218 // mapped range that overlaps with it. 219 for (const Range& range : kMapRanges) { 220 Range new_range; 221 new_range.addr = range.addr + range.size / 2; 222 new_range.size = range.size; 223 EXPECT_TRUE(MapRange(new_range, true)); 224 // Make sure the number of ranges is unchanged (one deleted, one added). 225 EXPECT_EQ(arraysize(kMapRanges), mapper_->GetNumMappedRanges()); 226 227 // The range is shifted in real space but should still be the same in 228 // quipper space. 229 TestMappedRange( 230 new_range, GetMappedAddressFromRanges(kMapRanges, arraysize(kMapRanges), 231 range.addr)); 232 } 233 } 234 235 // Test mapping of a giant map that overlaps with all existing ranges. 236 TEST_F(AddressMapperTest, OverlapBig) { 237 // A huge region that overlaps with all ranges in |kMapRanges|. 238 const Range kBigRegion(0xa00, 0xff000000, 0x1234, 0); 239 240 // Map all the ranges first. 241 for (const Range& range : kMapRanges) ASSERT_TRUE(MapRange(range, false)); 242 243 // Make sure overlap is detected before removing old ranges. 244 ASSERT_FALSE(MapRange(kBigRegion, false)); 245 ASSERT_TRUE(MapRange(kBigRegion, true)); 246 EXPECT_EQ(1U, mapper_->GetNumMappedRanges()); 247 248 TestMappedRange(kBigRegion, 0); 249 250 // Given the list of previously unmapped addresses, test that the ones within 251 // |kBigRegion| are now mapped; for the ones that are not, test that they are 252 // not mapped. 253 for (uint64_t addr : kAddressesNotInRanges) { 254 uint64_t mapped_addr = UINT64_MAX; 255 AddressMapper::MappingList::const_iterator addr_iter; 256 bool map_success = mapper_->GetMappedAddressAndListIterator( 257 addr, &mapped_addr, &addr_iter); 258 if (kBigRegion.contains(addr)) { 259 EXPECT_TRUE(map_success); 260 EXPECT_EQ(addr - kBigRegion.addr, mapped_addr); 261 } else { 262 EXPECT_FALSE(map_success); 263 } 264 } 265 266 // Check that addresses in the originally mapped ranges no longer map to the 267 // same addresses if they fall within |kBigRegion|, and don't map at all if 268 // they are not within |kBigRegion|. 269 for (const Range& range : kMapRanges) { 270 for (uint64_t addr = range.addr; addr < range.addr + range.size; 271 addr += range.size / kNumRangeTestIntervals) { 272 uint64_t mapped_addr = UINT64_MAX; 273 AddressMapper::MappingList::const_iterator addr_iter; 274 bool map_success = mapper_->GetMappedAddressAndListIterator( 275 addr, &mapped_addr, &addr_iter); 276 if (kBigRegion.contains(addr)) { 277 EXPECT_TRUE(map_success); 278 EXPECT_EQ(addr - kBigRegion.addr, mapped_addr); 279 } else { 280 EXPECT_FALSE(map_success); 281 } 282 } 283 } 284 285 EXPECT_EQ(kBigRegion.size, mapper_->GetMaxMappedLength()); 286 } 287 288 // Test a mapping at the end of memory space. 289 TEST_F(AddressMapperTest, EndOfMemory) { 290 // A region that extends to the end of the address space. 291 const Range kEndRegion(0xffffffff00000000, 0x100000000, 0x3456, 0); 292 293 ASSERT_TRUE(MapRange(kEndRegion, true)); 294 EXPECT_EQ(1U, mapper_->GetNumMappedRanges()); 295 TestMappedRange(kEndRegion, 0); 296 } 297 298 // Test mapping of an out-of-bounds mapping. 299 TEST_F(AddressMapperTest, OutOfBounds) { 300 // A region toward the end of address space that overruns the end of the 301 // address space. 302 const Range kOutOfBoundsRegion(0xffffffff00000000, 0x00000000, 0xccddeeff, 0); 303 304 ASSERT_FALSE(MapRange(kOutOfBoundsRegion, false)); 305 ASSERT_FALSE(MapRange(kOutOfBoundsRegion, true)); 306 EXPECT_EQ(0, mapper_->GetNumMappedRanges()); 307 uint64_t mapped_addr; 308 AddressMapper::MappingList::const_iterator iter; 309 EXPECT_FALSE(mapper_->GetMappedAddressAndListIterator( 310 kOutOfBoundsRegion.addr + 0x100, &mapped_addr, &iter)); 311 } 312 313 // Test mapping of a region that covers the entire memory space. Then map other 314 // regions over it. 315 TEST_F(AddressMapperTest, FullRange) { 316 // A huge region that covers all of the available space. 317 const Range kFullRegion(0, UINT64_MAX, 0xaabbccdd, 0); 318 319 ASSERT_TRUE(MapRange(kFullRegion, false)); 320 size_t num_expected_ranges = 1; 321 EXPECT_EQ(num_expected_ranges, mapper_->GetNumMappedRanges()); 322 323 TestMappedRange(kFullRegion, 0); 324 325 // Map some smaller ranges. 326 for (const Range& range : kMapRanges) { 327 // Check for collision first. 328 ASSERT_FALSE(MapRange(range, false)); 329 ASSERT_TRUE(MapRange(range, true)); 330 331 // Make sure the number of mapped ranges has increased by two. The mapping 332 // should have split an existing range. 333 num_expected_ranges += 2; 334 EXPECT_EQ(num_expected_ranges, mapper_->GetNumMappedRanges()); 335 } 336 } 337 338 // Test mapping of one range in the middle of an existing range. The existing 339 // range should be split into two to accommodate it. Also tests the use of base 340 // offsets. 341 TEST_F(AddressMapperTest, SplitRangeWithOffsetBase) { 342 // Define the two ranges, with distinct IDs. 343 const Range kFirstRange(0x10000, 0x4000, 0x11223344, 0x5000); 344 const Range kSecondRange(0x12000, 0x1000, 0x55667788, 0); 345 346 // As a sanity check, make sure the second range is fully contained within the 347 // first range. 348 EXPECT_LT(kFirstRange.addr, kSecondRange.addr); 349 EXPECT_GT(kFirstRange.addr + kFirstRange.size, 350 kSecondRange.addr + kSecondRange.size); 351 352 // Map the two ranges. 353 ASSERT_TRUE(MapRange(kFirstRange, true)); 354 ASSERT_TRUE(MapRange(kSecondRange, true)); 355 356 // The first range should have been split into two parts to make way for the 357 // second range. There should be a total of three ranges. 358 EXPECT_EQ(3U, mapper_->GetNumMappedRanges()); 359 360 // Now make sure the mappings are correct. 361 362 // The first range has been split up. Define the expected ranges here. 363 const Range kFirstRangeHead(0x10000, 0x2000, kFirstRange.id, 0x5000); 364 const Range kFirstRangeTail(0x13000, 0x1000, kFirstRange.id, 0x8000); 365 366 // Test the two remaining parts of the first range. 367 TestMappedRange(kFirstRangeHead, 0); 368 TestMappedRange(kFirstRangeTail, kFirstRangeTail.addr - kFirstRangeHead.addr); 369 370 // Test the second range normally. 371 TestMappedRange(kSecondRange, kSecondRange.addr - kFirstRange.addr); 372 } 373 374 // Test mappings that are not aligned to mmap page boundaries. 375 TEST_F(AddressMapperTest, NotPageAligned) { 376 mapper_->set_page_alignment(0x1000); 377 378 // Some address ranges that do not begin on a page boundary. 379 const Range kUnalignedRanges[] = { 380 Range(0xff000100, 0x1fff00, 0xdeadbeef, 0x100), 381 Range(0x00a00180, 0x10000, 0xcafebabe, 0x180), 382 Range(0x0c000300, 0x1000800, 0x900df00d, 0x4300), 383 Range(0x000017f0, 0x30000, 0x9000091e, 0x7f0), 384 }; 385 386 // Map the ranges. 387 for (const Range& range : kUnalignedRanges) 388 ASSERT_TRUE(MapRange(range, true)); 389 390 EXPECT_EQ(4U, mapper_->GetNumMappedRanges()); 391 392 // Now make sure the mappings are correct. 393 394 // First region is mapped as usual, except it does not start at the page 395 // boundary. 396 TestMappedRange(kUnalignedRanges[0], 0x00000100); 397 398 // Second region follows at the end of the first, but notice that its length 399 // is a full number of pages, which means... 400 TestMappedRange(kUnalignedRanges[1], 0x00200180); 401 402 // ... the third region starts beyond the next page boundary: 0x211000 instead 403 // of 0x210000. 404 TestMappedRange(kUnalignedRanges[2], 0x00211300); 405 406 // Similarly, the fourth region starts beyond the next page boundary: 407 // 0x1212000 instead of 0x1211000. 408 TestMappedRange(kUnalignedRanges[3], 0x012127f0); 409 } 410 411 // Have one mapping in the middle of another, with a nonzero page alignment 412 // parameter. 413 TEST_F(AddressMapperTest, SplitRangeWithPageAlignment) { 414 mapper_->set_page_alignment(0x1000); 415 416 // These should map just fine. 417 const Range kRange0(0x3000, 0x8000, 0xdeadbeef, 0); 418 const Range kRange1(0x5000, 0x2000, 0xfeedbabe, 0); 419 420 EXPECT_TRUE(MapRange(kRange0, true)); 421 EXPECT_TRUE(MapRange(kRange1, true)); 422 423 EXPECT_EQ(3U, mapper_->GetNumMappedRanges()); 424 425 // Determine the expected split mappings. 426 const Range kRange0Head(0x3000, 0x2000, 0xdeadbeef, 0); 427 const Range kRange0Tail(0x7000, 0x4000, 0xdeadbeef, 0x4000); 428 429 // Everything should be mapped and split as usual. 430 TestMappedRange(kRange0Head, 0); 431 TestMappedRange(kRange0Tail, 0x4000); 432 TestMappedRange(kRange1, 0x2000); 433 } 434 435 // Have one mapping in the middle of another, with a nonzero page alignment 436 // parameter. The overlapping region will not be aligned to page boundaries. 437 TEST_F(AddressMapperTest, MisalignedSplitRangeWithPageAlignment) { 438 mapper_->set_page_alignment(0x1000); 439 440 const Range kRange0(0x3000, 0x8000, 0xdeadbeef, 0); 441 const Range kMisalignedRange(0x4800, 0x2000, 0xfeedbabe, 0); 442 443 EXPECT_TRUE(MapRange(kRange0, true)); 444 // The misaligned mapping should not find enough space to split the existing 445 // range. It is not allowed to move the existing mapping. 446 EXPECT_FALSE(MapRange(kMisalignedRange, true)); 447 } 448 449 } // namespace quipper 450