Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2008 → Rev 2009

/trunk/kernel/generic/src/mm/as.c
78,6 → 78,10
#include <syscall/copy.h>
#include <arch/interrupt.h>
 
#ifdef CONFIG_VIRT_IDX_DCACHE
#include <arch/mm/cache.h>
#endif /* CONFIG_VIRT_IDX_DCACHE */
 
/**
* Each architecture decides what functions will be used to carry out
* address space operations such as creating or locking page tables.
162,6 → 166,11
as->cpu_refcount = 0;
as->page_table = page_table_create(flags);
 
#ifdef CONFIG_VIRT_IDX_DCACHE
as->dcache_flush_on_install = false;
as->dcache_flush_on_deinstall = false;
#endif /* CONFIG_VIRT_IDX_DCACHE */
 
return as;
}
 
269,6 → 278,18
else
memsetb((uintptr_t) &a->backend_data, sizeof(a->backend_data), 0);
 
#ifdef CONFIG_VIRT_IDX_DCACHE
/*
* When the area is being created with the AS_AREA_ATTR_PARTIAL flag, the
* orig_color is probably wrong until the flag is reset. In other words, it is
* initialized with the color of the area being created and not with the color
* of the original address space area at the beginning of the share chain. Of
* course, the correct color is set by as_area_share() before the flag is
* reset.
*/
a->orig_color = PAGE_COLOR(base);
#endif /* CONFIG_VIRT_IDX_DCACHE */
 
btree_create(&a->used_space);
btree_insert(&as->as_area_btree, base, (void *) a, NULL);
554,9 → 575,7
* such address space area, EPERM if there was a problem in accepting the area
* or ENOMEM if there was a problem in allocating destination address space
* area. ENOTSUP is returned if the address space area backend does not support
* sharing. It can be also returned if the architecture uses virtually indexed
* caches and the source and destination areas start at pages with different
* page colors.
* sharing.
*/
int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
as_t *dst_as, uintptr_t dst_base, int dst_flags_mask)
564,6 → 583,7
ipl_t ipl;
int src_flags;
size_t src_size;
int src_orig_color;
as_area_t *src_area, *dst_area;
share_info_t *sh_info;
mem_backend_t *src_backend;
581,19 → 601,6
return ENOENT;
}
#if 0 /* disable the check for now */
#ifdef CONFIG_VIRT_IDX_CACHE
if (PAGE_COLOR(src_area->base) != PAGE_COLOR(dst_base)) {
/*
* Refuse to create illegal address alias.
*/
mutex_unlock(&src_area->lock);
mutex_unlock(&src_as->lock);
interrupts_restore(ipl);
return ENOTSUP;
}
#endif /* CONFIG_VIRT_IDX_CACHE */
#endif
 
if (!src_area->backend || !src_area->backend->share) {
/*
610,6 → 617,7
src_flags = src_area->flags;
src_backend = src_area->backend;
src_backend_data = src_area->backend_data;
src_orig_color = src_area->orig_color;
 
/* Share the cacheable flag from the original mapping */
if (src_flags & AS_AREA_CACHEABLE)
664,17 → 672,39
interrupts_restore(ipl);
return ENOMEM;
}
 
/*
* Now the destination address space area has been
* fully initialized. Clear the AS_AREA_ATTR_PARTIAL
* attribute and set the sh_info.
*/
mutex_lock(&dst_as->lock);
mutex_lock(&dst_area->lock);
dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
dst_area->sh_info = sh_info;
dst_area->orig_color = src_orig_color;
#ifdef CONFIG_VIRT_IDX_DCACHE
if (src_orig_color != PAGE_COLOR(dst_base)) {
/*
* We have just detected an attempt to create an invalid address
* alias. We allow this and set a special flag that tells the
* architecture specific code to flush the D-cache when the
* offending address space is installed and deinstalled
* (cleanup).
*
* In order for the flags to take effect immediately, we also
* perform a global D-cache shootdown.
*/
dcache_shootdown_start();
dst_as->dcache_flush_on_install = true;
dst_as->dcache_flush_on_deinstall = true;
dcache_flush();
dcache_shootdown_finalize();
}
#endif /* CONFIG_VIRT_IDX_DCACHE */
mutex_unlock(&dst_area->lock);
mutex_unlock(&dst_as->lock);
 
interrupts_restore(ipl);
return 0;