Rev 2007 | Rev 2015 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2007 | Rev 2009 | ||
|---|---|---|---|
| Line 76... | Line 76... | ||
| 76 | #include <arch/types.h> |
76 | #include <arch/types.h> |
| 77 | #include <typedefs.h> |
77 | #include <typedefs.h> |
| 78 | #include <syscall/copy.h> |
78 | #include <syscall/copy.h> |
| 79 | #include <arch/interrupt.h> |
79 | #include <arch/interrupt.h> |
| 80 | 80 | ||
| - | 81 | #ifdef CONFIG_VIRT_IDX_DCACHE |
|
| - | 82 | #include <arch/mm/cache.h> |
|
| - | 83 | #endif /* CONFIG_VIRT_IDX_DCACHE */ |
|
| - | 84 | ||
| 81 | /** |
85 | /** |
| 82 | * Each architecture decides what functions will be used to carry out |
86 | * Each architecture decides what functions will be used to carry out |
| 83 | * address space operations such as creating or locking page tables. |
87 | * address space operations such as creating or locking page tables. |
| 84 | */ |
88 | */ |
| 85 | as_operations_t *as_operations = NULL; |
89 | as_operations_t *as_operations = NULL; |
| Line 160... | Line 164... | ||
| 160 | 164 | ||
| 161 | as->refcount = 0; |
165 | as->refcount = 0; |
| 162 | as->cpu_refcount = 0; |
166 | as->cpu_refcount = 0; |
| 163 | as->page_table = page_table_create(flags); |
167 | as->page_table = page_table_create(flags); |
| 164 | 168 | ||
| - | 169 | #ifdef CONFIG_VIRT_IDX_DCACHE |
|
| - | 170 | as->dcache_flush_on_install = false; |
|
| - | 171 | as->dcache_flush_on_deinstall = false; |
|
| - | 172 | #endif /* CONFIG_VIRT_IDX_DCACHE */ |
|
| - | 173 | ||
| 165 | return as; |
174 | return as; |
| 166 | } |
175 | } |
| 167 | 176 | ||
| 168 | /** Destroy adress space. |
177 | /** Destroy adress space. |
| 169 | * |
178 | * |
| Line 267... | Line 276... | ||
| 267 | if (backend_data) |
276 | if (backend_data) |
| 268 | a->backend_data = *backend_data; |
277 | a->backend_data = *backend_data; |
| 269 | else |
278 | else |
| 270 | memsetb((uintptr_t) &a->backend_data, sizeof(a->backend_data), 0); |
279 | memsetb((uintptr_t) &a->backend_data, sizeof(a->backend_data), 0); |
| 271 | 280 | ||
| - | 281 | #ifdef CONFIG_VIRT_IDX_DCACHE |
|
| - | 282 | /* |
|
| - | 283 | * When the area is being created with the AS_AREA_ATTR_PARTIAL flag, the |
|
| - | 284 | * orig_color is probably wrong until the flag is reset. In other words, it is |
|
| - | 285 | * initialized with the color of the area being created and not with the color |
|
| - | 286 | * of the original address space area at the beginning of the share chain. Of |
|
| - | 287 | * course, the correct color is set by as_area_share() before the flag is |
|
| - | 288 | * reset. |
|
| - | 289 | */ |
|
| - | 290 | a->orig_color = PAGE_COLOR(base); |
|
| - | 291 | #endif /* CONFIG_VIRT_IDX_DCACHE */ |
|
| - | 292 | ||
| 272 | btree_create(&a->used_space); |
293 | btree_create(&a->used_space); |
| 273 | 294 | ||
| 274 | btree_insert(&as->as_area_btree, base, (void *) a, NULL); |
295 | btree_insert(&as->as_area_btree, base, (void *) a, NULL); |
| 275 | 296 | ||
| 276 | mutex_unlock(&as->lock); |
297 | mutex_unlock(&as->lock); |
| Line 552... | Line 573... | ||
| 552 | * |
573 | * |
| 553 | * @return Zero on success or ENOENT if there is no such task or if there is no |
574 | * @return Zero on success or ENOENT if there is no such task or if there is no |
| 554 | * such address space area, EPERM if there was a problem in accepting the area |
575 | * such address space area, EPERM if there was a problem in accepting the area |
| 555 | * or ENOMEM if there was a problem in allocating destination address space |
576 | * or ENOMEM if there was a problem in allocating destination address space |
| 556 | * area. ENOTSUP is returned if the address space area backend does not support |
577 | * area. ENOTSUP is returned if the address space area backend does not support |
| 557 | * sharing. It can be also returned if the architecture uses virtually indexed |
- | |
| 558 | * caches and the source and destination areas start at pages with different |
- | |
| 559 | * page colors. |
578 | * sharing. |
| 560 | */ |
579 | */ |
| 561 | int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size, |
580 | int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size, |
| 562 | as_t *dst_as, uintptr_t dst_base, int dst_flags_mask) |
581 | as_t *dst_as, uintptr_t dst_base, int dst_flags_mask) |
| 563 | { |
582 | { |
| 564 | ipl_t ipl; |
583 | ipl_t ipl; |
| 565 | int src_flags; |
584 | int src_flags; |
| 566 | size_t src_size; |
585 | size_t src_size; |
| - | 586 | int src_orig_color; |
|
| 567 | as_area_t *src_area, *dst_area; |
587 | as_area_t *src_area, *dst_area; |
| 568 | share_info_t *sh_info; |
588 | share_info_t *sh_info; |
| 569 | mem_backend_t *src_backend; |
589 | mem_backend_t *src_backend; |
| 570 | mem_backend_data_t src_backend_data; |
590 | mem_backend_data_t src_backend_data; |
| 571 | 591 | ||
| Line 579... | Line 599... | ||
| 579 | mutex_unlock(&src_as->lock); |
599 | mutex_unlock(&src_as->lock); |
| 580 | interrupts_restore(ipl); |
600 | interrupts_restore(ipl); |
| 581 | return ENOENT; |
601 | return ENOENT; |
| 582 | } |
602 | } |
| 583 | 603 | ||
| 584 | #if 0 /* disable the check for now */ |
- | |
| 585 | #ifdef CONFIG_VIRT_IDX_CACHE |
- | |
| 586 | if (PAGE_COLOR(src_area->base) != PAGE_COLOR(dst_base)) { |
- | |
| 587 | /* |
- | |
| 588 | * Refuse to create illegal address alias. |
- | |
| 589 | */ |
- | |
| 590 | mutex_unlock(&src_area->lock); |
- | |
| 591 | mutex_unlock(&src_as->lock); |
- | |
| 592 | interrupts_restore(ipl); |
- | |
| 593 | return ENOTSUP; |
- | |
| 594 | } |
- | |
| 595 | #endif /* CONFIG_VIRT_IDX_CACHE */ |
- | |
| 596 | #endif |
- | |
| 597 | 604 | ||
| 598 | if (!src_area->backend || !src_area->backend->share) { |
605 | if (!src_area->backend || !src_area->backend->share) { |
| 599 | /* |
606 | /* |
| 600 | * There is no backend or the backend does not |
607 | * There is no backend or the backend does not |
| 601 | * know how to share the area. |
608 | * know how to share the area. |
| Line 608... | Line 615... | ||
| 608 | 615 | ||
| 609 | src_size = src_area->pages * PAGE_SIZE; |
616 | src_size = src_area->pages * PAGE_SIZE; |
| 610 | src_flags = src_area->flags; |
617 | src_flags = src_area->flags; |
| 611 | src_backend = src_area->backend; |
618 | src_backend = src_area->backend; |
| 612 | src_backend_data = src_area->backend_data; |
619 | src_backend_data = src_area->backend_data; |
| - | 620 | src_orig_color = src_area->orig_color; |
|
| 613 | 621 | ||
| 614 | /* Share the cacheable flag from the original mapping */ |
622 | /* Share the cacheable flag from the original mapping */ |
| 615 | if (src_flags & AS_AREA_CACHEABLE) |
623 | if (src_flags & AS_AREA_CACHEABLE) |
| 616 | dst_flags_mask |= AS_AREA_CACHEABLE; |
624 | dst_flags_mask |= AS_AREA_CACHEABLE; |
| 617 | 625 | ||
| Line 662... | Line 670... | ||
| 662 | sh_info_remove_reference(sh_info); |
670 | sh_info_remove_reference(sh_info); |
| 663 | 671 | ||
| 664 | interrupts_restore(ipl); |
672 | interrupts_restore(ipl); |
| 665 | return ENOMEM; |
673 | return ENOMEM; |
| 666 | } |
674 | } |
| 667 | 675 | ||
| 668 | /* |
676 | /* |
| 669 | * Now the destination address space area has been |
677 | * Now the destination address space area has been |
| 670 | * fully initialized. Clear the AS_AREA_ATTR_PARTIAL |
678 | * fully initialized. Clear the AS_AREA_ATTR_PARTIAL |
| 671 | * attribute and set the sh_info. |
679 | * attribute and set the sh_info. |
| 672 | */ |
680 | */ |
| - | 681 | mutex_lock(&dst_as->lock); |
|
| 673 | mutex_lock(&dst_area->lock); |
682 | mutex_lock(&dst_area->lock); |
| 674 | dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL; |
683 | dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL; |
| 675 | dst_area->sh_info = sh_info; |
684 | dst_area->sh_info = sh_info; |
| - | 685 | dst_area->orig_color = src_orig_color; |
|
| - | 686 | #ifdef CONFIG_VIRT_IDX_DCACHE |
|
| - | 687 | if (src_orig_color != PAGE_COLOR(dst_base)) { |
|
| - | 688 | /* |
|
| - | 689 | * We have just detected an attempt to create an invalid address |
|
| - | 690 | * alias. We allow this and set a special flag that tells the |
|
| - | 691 | * architecture specific code to flush the D-cache when the |
|
| - | 692 | * offending address space is installed and deinstalled |
|
| - | 693 | * (cleanup). |
|
| - | 694 | * |
|
| - | 695 | * In order for the flags to take effect immediately, we also |
|
| - | 696 | * perform a global D-cache shootdown. |
|
| - | 697 | */ |
|
| - | 698 | dcache_shootdown_start(); |
|
| - | 699 | dst_as->dcache_flush_on_install = true; |
|
| - | 700 | dst_as->dcache_flush_on_deinstall = true; |
|
| - | 701 | dcache_flush(); |
|
| - | 702 | dcache_shootdown_finalize(); |
|
| - | 703 | } |
|
| - | 704 | #endif /* CONFIG_VIRT_IDX_DCACHE */ |
|
| 676 | mutex_unlock(&dst_area->lock); |
705 | mutex_unlock(&dst_area->lock); |
| - | 706 | mutex_unlock(&dst_as->lock); |
|
| 677 | 707 | ||
| 678 | interrupts_restore(ipl); |
708 | interrupts_restore(ipl); |
| 679 | 709 | ||
| 680 | return 0; |
710 | return 0; |
| 681 | } |
711 | } |
| 682 | 712 | ||