Subversion Repositories HelenOS

Rev

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

Rev 2787 Rev 3013
Line 959... Line 959...
959
    spinlock_unlock(&asidlock);
959
    spinlock_unlock(&asidlock);
960
   
960
   
961
    AS = new_as;
961
    AS = new_as;
962
}
962
}
963
 
963
 
-
 
964
/** Write directly into a page, bypassing area flags.
-
 
965
 *
-
 
966
 * This allows a debugger to write into a page that is mapped read-only
-
 
967
 * (such as the text segment). Naturally, this is only possible if the
-
 
968
 * correspoinding area is not shared and anonymous.
-
 
969
 *
-
 
970
 * FIXME: doesn't take into account that it isn't a good idea to write
-
 
971
 * into the frame if the area is shared or isn't anonymous
-
 
972
 */
-
 
973
static int debug_write_inside_page(uintptr_t va, void *data, size_t n)
-
 
974
{
-
 
975
    uintptr_t page;
-
 
976
    pte_t *pte;
-
 
977
    as_area_t *area;
-
 
978
    uintptr_t frame;
-
 
979
    ipl_t ipl;
-
 
980
    int rc;
-
 
981
 
-
 
982
    page = ALIGN_DOWN(va, PAGE_SIZE);
-
 
983
    ASSERT(ALIGN_DOWN(va + n - 1, PAGE_SIZE) == page);
-
 
984
 
-
 
985
restart:
-
 
986
    mutex_lock(&AS->lock);
-
 
987
    ipl = interrupts_disable();
-
 
988
    area = find_area_and_lock(AS, page);
-
 
989
 
-
 
990
    pte = page_mapping_find(AS, page);
-
 
991
    if (! (pte && PTE_VALID(pte) && PTE_PRESENT(pte)) ) {
-
 
992
        mutex_unlock(&area->lock);
-
 
993
        mutex_unlock(&AS->lock);
-
 
994
        interrupts_restore(ipl);
-
 
995
 
-
 
996
        rc = as_page_fault(page, PF_ACCESS_WRITE, NULL);
-
 
997
        if (rc == AS_PF_FAULT) return EINVAL;
-
 
998
 
-
 
999
        goto restart;
-
 
1000
    }
-
 
1001
 
-
 
1002
    frame = PTE_GET_FRAME(pte);
-
 
1003
    memcpy((void *)(PA2KA(frame) + (va - page)), data, n);
-
 
1004
 
-
 
1005
    mutex_unlock(&area->lock);
-
 
1006
    mutex_unlock(&AS->lock);
-
 
1007
    interrupts_restore(ipl);
-
 
1008
 
-
 
1009
    return EOK;
-
 
1010
}
-
 
1011
 
-
 
1012
/** Write data bypassing area flags.
-
 
1013
 *
-
 
1014
 * See debug_write_inside_page().
-
 
1015
 */
-
 
1016
int as_debug_write(uintptr_t va, void *data, size_t n)
-
 
1017
{
-
 
1018
    size_t now;
-
 
1019
    int rc;
-
 
1020
 
-
 
1021
    while (n > 0) {
-
 
1022
        now = ALIGN_UP(va, PAGE_SIZE) - va;
-
 
1023
        if (now > n) now = n;
-
 
1024
 
-
 
1025
        rc = debug_write_inside_page(va, data, now);
-
 
1026
        if (rc != EOK) return rc;
-
 
1027
 
-
 
1028
        va += now;
-
 
1029
        data += now;
-
 
1030
        n -= now;
-
 
1031
    }
-
 
1032
 
-
 
1033
    return EOK;
-
 
1034
}
-
 
1035
 
964
/** Convert address space area flags to page flags.
1036
/** Convert address space area flags to page flags.
965
 *
1037
 *
966
 * @param aflags Flags of some address space area.
1038
 * @param aflags Flags of some address space area.
967
 *
1039
 *
968
 * @return Flags to be passed to page_mapping_insert().
1040
 * @return Flags to be passed to page_mapping_insert().