Rev 2007 | Rev 2015 | Go to most recent revision | Show entire file | Regard 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 668... | Line 676... | ||
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 | } |