Changeset 35a3d950 in mainline
- Timestamp:
- 2012-11-01T18:11:04Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 082b7f1
- Parents:
- a582dff
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
abi/include/mm/as.h
ra582dff r35a3d950 37 37 38 38 /** Address space area flags. */ 39 #define AS_AREA_READ 1 40 #define AS_AREA_WRITE 2 41 #define AS_AREA_EXEC 4 42 #define AS_AREA_CACHEABLE 8 39 #define AS_AREA_READ 0x01 40 #define AS_AREA_WRITE 0x02 41 #define AS_AREA_EXEC 0x04 42 #define AS_AREA_CACHEABLE 0x08 43 #define AS_AREA_GUARD 0x10 43 44 44 45 /** Address space area info exported to uspace. */ -
kernel/generic/src/mm/as.c
ra582dff r35a3d950 285 285 /** Check area conflicts with other areas. 286 286 * 287 * @param as Address space. 288 * @param addr Starting virtual address of the area being tested. 289 * @param count Number of pages in the area being tested. 290 * @param avoid Do not touch this area. 287 * @param as Address space. 288 * @param addr Starting virtual address of the area being tested. 289 * @param count Number of pages in the area being tested. 290 * @param guarded True if the area being tested is protected by guard pages. 291 * @param avoid Do not touch this area. 291 292 * 292 293 * @return True if there is no conflict, false otherwise. … … 294 295 */ 295 296 NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t addr, 296 size_t count, as_area_t *avoid)297 size_t count, bool guarded, as_area_t *avoid) 297 298 { 298 299 ASSERT((addr % PAGE_SIZE) == 0); … … 304 305 if (overlaps(addr, P2SZ(count), (uintptr_t) NULL, PAGE_SIZE)) 305 306 return false; 306 307 307 308 /* 308 309 * The leaf node is found in O(log n), where n is proportional to … … 328 329 if (area != avoid) { 329 330 mutex_lock(&area->lock); 331 332 /* If at least one of the two areas are protected 333 * by the AS_AREA_GUARD flag then we must be sure 334 * that they are separated by at least one unmapped 335 * page. 336 */ 337 int const gp = (guarded || 338 (area->flags & AS_AREA_GUARD)) ? 1 : 0; 330 339 331 340 if (overlaps(addr, P2SZ(count), area->base, 341 P2SZ(area->pages + gp))) { 342 mutex_unlock(&area->lock); 343 return false; 344 } 345 346 mutex_unlock(&area->lock); 347 } 348 } 349 350 node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf); 351 if (node) { 352 area = (as_area_t *) node->value[0]; 353 354 if (area != avoid) { 355 mutex_lock(&area->lock); 356 357 int const gp = (guarded || 358 (area->flags & AS_AREA_GUARD)) ? 1 : 0; 359 360 if (overlaps(addr, P2SZ(count + gp), area->base, 332 361 P2SZ(area->pages))) { 333 362 mutex_unlock(&area->lock); … … 339 368 } 340 369 341 node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);342 if (node) {343 area = (as_area_t *) node->value[0];344 345 if (area != avoid) {346 mutex_lock(&area->lock);347 348 if (overlaps(addr, P2SZ(count), area->base,349 P2SZ(area->pages))) {350 mutex_unlock(&area->lock);351 return false;352 }353 354 mutex_unlock(&area->lock);355 }356 }357 358 370 /* Second, check the leaf node. */ 359 371 btree_key_t i; … … 365 377 366 378 mutex_lock(&area->lock); 367 368 if (overlaps(addr, P2SZ(count), area->base, 369 P2SZ(area->pages))) { 379 380 int const gp = (guarded || 381 (area->flags & AS_AREA_GUARD)) ? 1 : 0; 382 383 if (overlaps(addr, P2SZ(count + gp), area->base, 384 P2SZ(area->pages + gp))) { 370 385 mutex_unlock(&area->lock); 371 386 return false; … … 392 407 * this function. 393 408 * 394 * @param as Address space. 395 * @param bound Lowest address bound. 396 * @param size Requested size of the allocation. 409 * @param as Address space. 410 * @param bound Lowest address bound. 411 * @param size Requested size of the allocation. 412 * @param guarded True if the allocation must be protected by guard pages. 397 413 * 398 414 * @return Address of the beginning of unmapped address space area. … … 401 417 */ 402 418 NO_TRACE static uintptr_t as_get_unmapped_area(as_t *as, uintptr_t bound, 403 size_t size )419 size_t size, bool guarded) 404 420 { 405 421 ASSERT(mutex_locked(&as->lock)); … … 423 439 /* First check the bound address itself */ 424 440 uintptr_t addr = ALIGN_UP(bound, PAGE_SIZE); 425 if ((addr >= bound) && 426 (check_area_conflicts(as, addr, pages, NULL))) 427 return addr; 441 if (addr >= bound) { 442 if (guarded) { 443 /* Leave an unmapped page between the lower 444 * bound and the area's start address. 445 */ 446 addr += P2SZ(1); 447 } 448 449 if (check_area_conflicts(as, addr, pages, guarded, NULL)) 450 return addr; 451 } 428 452 429 453 /* Eventually check the addresses behind each area */ … … 439 463 addr = 440 464 ALIGN_UP(area->base + P2SZ(area->pages), PAGE_SIZE); 465 466 if (guarded || area->flags & AS_AREA_GUARD) { 467 /* We must leave an unmapped page 468 * between the two areas. 469 */ 470 addr += P2SZ(1); 471 } 472 441 473 bool avail = 442 474 ((addr >= bound) && (addr >= area->base) && 443 (check_area_conflicts(as, addr, pages, area)));475 (check_area_conflicts(as, addr, pages, guarded, area))); 444 476 445 477 mutex_unlock(&area->lock); … … 487 519 if ((flags & AS_AREA_EXEC) && (flags & AS_AREA_WRITE)) 488 520 return NULL; 521 522 bool const guarded = flags & AS_AREA_GUARD; 489 523 490 524 mutex_lock(&as->lock); 491 525 492 526 if (*base == (uintptr_t) -1) { 493 *base = as_get_unmapped_area(as, bound, size );527 *base = as_get_unmapped_area(as, bound, size, guarded); 494 528 if (*base == (uintptr_t) -1) { 495 529 mutex_unlock(&as->lock); … … 497 531 } 498 532 } 499 500 if (!check_area_conflicts(as, *base, pages, NULL)) {533 534 if (!check_area_conflicts(as, *base, pages, guarded, NULL)) { 501 535 mutex_unlock(&as->lock); 502 536 return NULL; … … 778 812 * Check for overlaps with other address space areas. 779 813 */ 780 if (!check_area_conflicts(as, address, pages, area)) { 814 bool const guarded = area->flags & AS_AREA_GUARD; 815 if (!check_area_conflicts(as, address, pages, guarded, area)) { 781 816 mutex_unlock(&area->lock); 782 817 mutex_unlock(&as->lock);
Note:
See TracChangeset
for help on using the changeset viewer.