Subversion Repositories HelenOS

Rev

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
}