Subversion Repositories HelenOS

Rev

Rev 2009 | Rev 2069 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2009 Rev 2015
Line 164... Line 164...
164
   
164
   
165
    as->refcount = 0;
165
    as->refcount = 0;
166
    as->cpu_refcount = 0;
166
    as->cpu_refcount = 0;
167
    as->page_table = page_table_create(flags);
167
    as->page_table = page_table_create(flags);
168
 
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
 
-
 
174
    return as;
169
    return as;
175
}
170
}
176
 
171
 
177
/** Destroy adress space.
172
/** Destroy adress space.
178
 *
173
 *
Line 276... Line 271...
276
    if (backend_data)
271
    if (backend_data)
277
        a->backend_data = *backend_data;
272
        a->backend_data = *backend_data;
278
    else
273
    else
279
        memsetb((uintptr_t) &a->backend_data, sizeof(a->backend_data), 0);
274
        memsetb((uintptr_t) &a->backend_data, sizeof(a->backend_data), 0);
280
 
275
 
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
 
-
 
293
    btree_create(&a->used_space);
276
    btree_create(&a->used_space);
294
   
277
   
295
    btree_insert(&as->as_area_btree, base, (void *) a, NULL);
278
    btree_insert(&as->as_area_btree, base, (void *) a, NULL);
296
 
279
 
297
    mutex_unlock(&as->lock);
280
    mutex_unlock(&as->lock);
Line 573... Line 556...
573
 *
556
 *
574
 * @return Zero on success or ENOENT if there is no such task or if there is no
557
 * @return Zero on success or ENOENT if there is no such task or if there is no
575
 * such address space area, EPERM if there was a problem in accepting the area
558
 * such address space area, EPERM if there was a problem in accepting the area
576
 * or ENOMEM if there was a problem in allocating destination address space
559
 * or ENOMEM if there was a problem in allocating destination address space
577
 * area. ENOTSUP is returned if the address space area backend does not support
560
 * area. ENOTSUP is returned if the address space area backend does not support
-
 
561
 * sharing or if the kernel detects an attempt to create an illegal address
578
 * sharing.
562
 * alias.
579
 */
563
 */
580
int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
564
int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
581
          as_t *dst_as, uintptr_t dst_base, int dst_flags_mask)
565
          as_t *dst_as, uintptr_t dst_base, int dst_flags_mask)
582
{
566
{
583
    ipl_t ipl;
567
    ipl_t ipl;
584
    int src_flags;
568
    int src_flags;
585
    size_t src_size;
569
    size_t src_size;
586
    int src_orig_color;
-
 
587
    as_area_t *src_area, *dst_area;
570
    as_area_t *src_area, *dst_area;
588
    share_info_t *sh_info;
571
    share_info_t *sh_info;
589
    mem_backend_t *src_backend;
572
    mem_backend_t *src_backend;
590
    mem_backend_data_t src_backend_data;
573
    mem_backend_data_t src_backend_data;
591
   
574
   
Line 598... Line 581...
598
         */
581
         */
599
        mutex_unlock(&src_as->lock);
582
        mutex_unlock(&src_as->lock);
600
        interrupts_restore(ipl);
583
        interrupts_restore(ipl);
601
        return ENOENT;
584
        return ENOENT;
602
    }
585
    }
603
   
-
 
604
 
586
 
605
    if (!src_area->backend || !src_area->backend->share) {
587
    if (!src_area->backend || !src_area->backend->share) {
606
        /*
588
        /*
607
         * There is no backend or the backend does not
589
         * There is no backend or the backend does not
608
         * know how to share the area.
590
         * know how to share the area.
Line 615... Line 597...
615
   
597
   
616
    src_size = src_area->pages * PAGE_SIZE;
598
    src_size = src_area->pages * PAGE_SIZE;
617
    src_flags = src_area->flags;
599
    src_flags = src_area->flags;
618
    src_backend = src_area->backend;
600
    src_backend = src_area->backend;
619
    src_backend_data = src_area->backend_data;
601
    src_backend_data = src_area->backend_data;
620
    src_orig_color = src_area->orig_color;
-
 
621
 
602
 
622
    /* Share the cacheable flag from the original mapping */
603
    /* Share the cacheable flag from the original mapping */
623
    if (src_flags & AS_AREA_CACHEABLE)
604
    if (src_flags & AS_AREA_CACHEABLE)
624
        dst_flags_mask |= AS_AREA_CACHEABLE;
605
        dst_flags_mask |= AS_AREA_CACHEABLE;
625
 
606
 
Line 628... Line 609...
628
        mutex_unlock(&src_as->lock);
609
        mutex_unlock(&src_as->lock);
629
        interrupts_restore(ipl);
610
        interrupts_restore(ipl);
630
        return EPERM;
611
        return EPERM;
631
    }
612
    }
632
 
613
 
-
 
614
#ifdef CONFIG_VIRT_IDX_DCACHE
-
 
615
    if (!(dst_flags_mask & AS_AREA_EXEC)) {
-
 
616
        if (PAGE_COLOR(src_area->base) != PAGE_COLOR(dst_base)) {
-
 
617
            /*
-
 
618
             * Refuse to create an illegal address alias.
-
 
619
             */
-
 
620
            mutex_unlock(&src_area->lock);
-
 
621
            mutex_unlock(&src_as->lock);
-
 
622
            interrupts_restore(ipl);
-
 
623
            return ENOTSUP;
-
 
624
        }
-
 
625
    }
-
 
626
#endif /* CONFIG_VIRT_IDX_DCACHE */
-
 
627
 
633
    /*
628
    /*
634
     * Now we are committed to sharing the area.
629
     * Now we are committed to sharing the area.
635
     * First, prepare the area for sharing.
630
     * First, prepare the area for sharing.
636
     * Then it will be safe to unlock it.
631
     * Then it will be safe to unlock it.
637
     */
632
     */
Line 680... Line 675...
680
     */
675
     */
681
    mutex_lock(&dst_as->lock); 
676
    mutex_lock(&dst_as->lock); 
682
    mutex_lock(&dst_area->lock);
677
    mutex_lock(&dst_area->lock);
683
    dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
678
    dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
684
    dst_area->sh_info = sh_info;
679
    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 */
-
 
705
    mutex_unlock(&dst_area->lock);
680
    mutex_unlock(&dst_area->lock);
706
    mutex_unlock(&dst_as->lock);   
681
    mutex_unlock(&dst_as->lock);   
707
 
682
 
708
    interrupts_restore(ipl);
683
    interrupts_restore(ipl);
709
   
684