Subversion Repositories HelenOS-historic

Rev

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

Rev 1248 Rev 1288
Line 55... Line 55...
55
#include <arch/mm/asid.h>
55
#include <arch/mm/asid.h>
56
#include <synch/spinlock.h>
56
#include <synch/spinlock.h>
57
#include <adt/list.h>
57
#include <adt/list.h>
58
#include <adt/btree.h>
58
#include <adt/btree.h>
59
#include <proc/task.h>
59
#include <proc/task.h>
-
 
60
#include <proc/thread.h>
60
#include <arch/asm.h>
61
#include <arch/asm.h>
61
#include <panic.h>
62
#include <panic.h>
62
#include <debug.h>
63
#include <debug.h>
63
#include <print.h>
64
#include <print.h>
64
#include <memstr.h>
65
#include <memstr.h>
Line 66... Line 67...
66
#include <arch.h>
67
#include <arch.h>
67
#include <errno.h>
68
#include <errno.h>
68
#include <config.h>
69
#include <config.h>
69
#include <arch/types.h>
70
#include <arch/types.h>
70
#include <typedefs.h>
71
#include <typedefs.h>
-
 
72
#include <syscall/copy.h>
-
 
73
#include <arch/interrupt.h>
71
 
74
 
72
as_operations_t *as_operations = NULL;
75
as_operations_t *as_operations = NULL;
73
 
76
 
74
/** Address space lock. It protects inactive_as_with_asid_head. */
77
/** Address space lock. It protects inactive_as_with_asid_head. */
75
SPINLOCK_INITIALIZE(as_lock);
78
SPINLOCK_INITIALIZE(as_lock);
Line 475... Line 478...
475
 *
478
 *
476
 * This is the high-level page fault handler.
479
 * This is the high-level page fault handler.
477
 * Interrupts are assumed disabled.
480
 * Interrupts are assumed disabled.
478
 *
481
 *
479
 * @param page Faulting page.
482
 * @param page Faulting page.
-
 
483
 * @param istate Pointer to interrupted state.
480
 *
484
 *
481
 * @return 0 on page fault, 1 on success.
485
 * @return 0 on page fault, 1 on success or 2 if the fault was caused by copy_to_uspace() or copy_from_uspace().
482
 */
486
 */
483
int as_page_fault(__address page)
487
int as_page_fault(__address page, istate_t *istate)
484
{
488
{
485
    pte_t *pte;
489
    pte_t *pte;
486
    as_area_t *area;
490
    as_area_t *area;
487
    __address frame;
491
    __address frame;
488
   
492
   
Line 494... Line 498...
494
        /*
498
        /*
495
         * No area contained mapping for 'page'.
499
         * No area contained mapping for 'page'.
496
         * Signal page fault to low-level handler.
500
         * Signal page fault to low-level handler.
497
         */
501
         */
498
        spinlock_unlock(&AS->lock);
502
        spinlock_unlock(&AS->lock);
499
        return 0;
503
        goto page_fault;
500
    }
504
    }
501
 
505
 
502
    if (area->attributes & AS_AREA_ATTR_PARTIAL) {
506
    if (area->attributes & AS_AREA_ATTR_PARTIAL) {
503
        /*
507
        /*
504
         * The address space area is not fully initialized.
508
         * The address space area is not fully initialized.
505
         * Avoid possible race by returning error.
509
         * Avoid possible race by returning error.
506
         */
510
         */
507
        spinlock_unlock(&area->lock);
511
        spinlock_unlock(&area->lock);
508
        spinlock_unlock(&AS->lock);
512
        spinlock_unlock(&AS->lock);
509
        return 0;      
513
        goto page_fault;       
510
    }
514
    }
511
 
515
 
512
    ASSERT(!(area->flags & AS_AREA_DEVICE));
516
    ASSERT(!(area->flags & AS_AREA_DEVICE));
513
 
517
 
514
    page_table_lock(AS, false);
518
    page_table_lock(AS, false);
Line 552... Line 556...
552
    page_mapping_insert(AS, page, frame, get_area_flags(area));
556
    page_mapping_insert(AS, page, frame, get_area_flags(area));
553
    page_table_unlock(AS, false);
557
    page_table_unlock(AS, false);
554
   
558
   
555
    spinlock_unlock(&area->lock);
559
    spinlock_unlock(&area->lock);
556
    spinlock_unlock(&AS->lock);
560
    spinlock_unlock(&AS->lock);
557
    return 1;
561
    return AS_PF_OK;
-
 
562
 
-
 
563
page_fault:
-
 
564
    if (!THREAD)
-
 
565
        return AS_PF_FAULT;
-
 
566
   
-
 
567
    if (THREAD->in_copy_from_uspace) {
-
 
568
        THREAD->in_copy_from_uspace = false;
-
 
569
        istate_set_retaddr(istate, (__address) &memcpy_from_uspace_failover_address);
-
 
570
    } else if (THREAD->in_copy_to_uspace) {
-
 
571
        THREAD->in_copy_to_uspace = false;
-
 
572
        istate_set_retaddr(istate, (__address) &memcpy_to_uspace_failover_address);
-
 
573
    } else {
-
 
574
        return AS_PF_FAULT;
-
 
575
    }
-
 
576
 
-
 
577
    return AS_PF_DEFER;
558
}
578
}
559
 
579
 
560
/** Switch address spaces.
580
/** Switch address spaces.
561
 *
581
 *
562
 * @param old Old address space or NULL.
582
 * @param old Old address space or NULL.
Line 882... Line 902...
882
 *     TASK. Otherwise zero is returned.
902
 *     TASK. Otherwise zero is returned.
883
 */
903
 */
884
__native sys_as_area_accept(as_area_acptsnd_arg_t *uspace_accept_arg)
904
__native sys_as_area_accept(as_area_acptsnd_arg_t *uspace_accept_arg)
885
{
905
{
886
    as_area_acptsnd_arg_t arg;
906
    as_area_acptsnd_arg_t arg;
-
 
907
    int rc;
887
   
908
   
888
    copy_from_uspace(&arg, uspace_accept_arg, sizeof(as_area_acptsnd_arg_t));
909
    rc = copy_from_uspace(&arg, uspace_accept_arg, sizeof(as_area_acptsnd_arg_t));
-
 
910
    if (rc != 0)
-
 
911
        return rc;
889
   
912
   
890
    if (!arg.size)
913
    if (!arg.size)
891
        return (__native) EPERM;
914
        return (__native) EPERM;
892
   
915
   
893
    if (arg.task_id == TASK->taskid) {
916
    if (arg.task_id == TASK->taskid) {
Line 904... Line 927...
904
 
927
 
905
/** Wrapper for as_area_send. */
928
/** Wrapper for as_area_send. */
906
__native sys_as_area_send(as_area_acptsnd_arg_t *uspace_send_arg)
929
__native sys_as_area_send(as_area_acptsnd_arg_t *uspace_send_arg)
907
{
930
{
908
    as_area_acptsnd_arg_t arg;
931
    as_area_acptsnd_arg_t arg;
-
 
932
    int rc;
909
   
933
   
910
    copy_from_uspace(&arg, uspace_send_arg, sizeof(as_area_acptsnd_arg_t));
934
    rc = copy_from_uspace(&arg, uspace_send_arg, sizeof(as_area_acptsnd_arg_t));
-
 
935
    if (rc != 0)
-
 
936
        return rc;
911
 
937
 
912
    if (!arg.size)
938
    if (!arg.size)
913
        return (__native) EPERM;
939
        return (__native) EPERM;
914
   
940
   
915
    if (arg.task_id == TASK->taskid) {
941
    if (arg.task_id == TASK->taskid) {