Changeset 92778f2 in mainline for kernel/generic/src/mm/as.c


Ignore:
Timestamp:
2006-12-04T21:14:07Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4b43f86
Parents:
3d76996
Message:

Initial support for handling illegal virtual aliases on sparc64.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/mm/as.c

    r3d76996 r92778f2  
    7979#include <arch/interrupt.h>
    8080
     81#ifdef CONFIG_VIRT_IDX_DCACHE
     82#include <arch/mm/cache.h>
     83#endif /* CONFIG_VIRT_IDX_DCACHE */
     84
    8185/**
    8286 * Each architecture decides what functions will be used to carry out
     
    162166        as->cpu_refcount = 0;
    163167        as->page_table = page_table_create(flags);
     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 */
    164173
    165174        return as;
     
    269278        else
    270279                memsetb((uintptr_t) &a->backend_data, sizeof(a->backend_data), 0);
     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 */
    271292
    272293        btree_create(&a->used_space);
     
    555576 * or ENOMEM if there was a problem in allocating destination address space
    556577 * 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.
    560579 */
    561580int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
     
    565584        int src_flags;
    566585        size_t src_size;
     586        int src_orig_color;
    567587        as_area_t *src_area, *dst_area;
    568588        share_info_t *sh_info;
     
    582602        }
    583603       
    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.
     604
     605        if (!src_area->backend || !src_area->backend->share) {
     606                /*
     607                 * There is no backend or the backend does not
     608                 * know how to share the area.
    589609                 */
    590610                mutex_unlock(&src_area->lock);
     
    593613                return ENOTSUP;
    594614        }
    595 #endif /* CONFIG_VIRT_IDX_CACHE */
    596 #endif
    597 
    598         if (!src_area->backend || !src_area->backend->share) {
    599                 /*
    600                  * There is no backend or the backend does not
    601                  * know how to share the area.
    602                  */
    603                 mutex_unlock(&src_area->lock);
    604                 mutex_unlock(&src_as->lock);
    605                 interrupts_restore(ipl);
    606                 return ENOTSUP;
    607         }
    608615       
    609616        src_size = src_area->pages * PAGE_SIZE;
     
    611618        src_backend = src_area->backend;
    612619        src_backend_data = src_area->backend_data;
     620        src_orig_color = src_area->orig_color;
    613621
    614622        /* Share the cacheable flag from the original mapping */
     
    665673                return ENOMEM;
    666674        }
    667        
     675
    668676        /*
    669677         * Now the destination address space area has been
     
    671679         * attribute and set the sh_info.
    672680         */     
     681        mutex_lock(&dst_as->lock);     
    673682        mutex_lock(&dst_area->lock);
    674683        dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
    675684        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 */
    676705        mutex_unlock(&dst_area->lock);
    677        
     706        mutex_unlock(&dst_as->lock);   
     707
    678708        interrupts_restore(ipl);
    679709       
Note: See TracChangeset for help on using the changeset viewer.