Changeset e3c762cd in mainline


Ignore:
Timestamp:
2006-05-05T11:59:19Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
de07bcf
Parents:
22cf454d
Message:

Complete implementation of copy_from_uspace() and copy_to_uspace()
for amd64 and ia32. Other architectures still compile and run,
but need to implement their own assembly-only memcpy(), memcpy_from_uspace(),
memcpy_to_uspace() and their failover parts. For these architectures
only dummy implementations are provided.

Files:
2 added
34 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    r22cf454d re3c762cd  
    129129        generic/src/proc/the.c \
    130130        generic/src/syscall/syscall.c \
     131        generic/src/syscall/copy.c \
    131132        generic/src/mm/buddy.c \
    132133        generic/src/mm/frame.c \
  • arch/amd64/include/interrupt.h

    r22cf454d re3c762cd  
    8787};
    8888
     89static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     90{
     91        istate->rip = retaddr;
     92}
     93
    8994extern void (* disable_irqs_function)(__u16 irqmask);
    9095extern void (* enable_irqs_function)(__u16 irqmask);
  • arch/amd64/src/asm_utils.S

    r22cf454d re3c762cd  
    6161        jmp printf
    6262
    63 .global memcpy
    64 memcpy:
    65         jmp _memcpy
    66        
    6763.global cpuid
    6864.global has_cpuid
     
    7066.global read_efer_flag
    7167.global set_efer_flag
    72        
     68.global memcpy
     69.global memcpy_from_uspace
     70.global memcpy_to_uspace
     71.global memcpy_from_uspace_failover_address
     72.global memcpy_to_uspace_failover_address
     73
     74#define MEMCPY_DST      %rdi
     75#define MEMCPY_SRC      %rsi
     76#define MEMCPY_SIZE     %rdx
     77
     78/**
     79 * Copy memory from/to userspace.
     80 *
     81 * This is almost conventional memcpy().
     82 * The difference is that there is a failover part
     83 * to where control is returned from a page fault if
     84 * the page fault occurs during copy_from_uspace()
     85 * or copy_to_uspace().
     86 *
     87 * @param MEMCPY_DST    Destination address.
     88 * @param MEMCPY_SRC    Source address.
     89 * @param MEMCPY_SIZE   Number of bytes to copy.
     90 *
     91 * @retrun MEMCPY_SRC on success, 0 on failure.
     92 */
     93memcpy:
     94memcpy_from_uspace:
     95memcpy_to_uspace:
     96        movq MEMCPY_SRC, %rax
     97
     98        movq MEMCPY_SIZE, %rcx
     99        shrq $3, %rcx                   /* size / 8 */
     100       
     101        rep movsq                       /* copy as much as possible word by word */
     102
     103        movq MEMCPY_SIZE, %rcx
     104        andq $7, %rcx                   /* size % 8 */
     105        jz 0f
     106       
     107        rep movsb                       /* copy the rest byte by byte */
     108       
     1090:
     110        ret                             /* return MEMCPY_SRC, success */
     111
     112memcpy_from_uspace_failover_address:
     113memcpy_to_uspace_failover_address:
     114        xorq %rax, %rax                 /* return 0, failure */
     115        ret
     116
    73117## Determine CPUID support
    74118#
  • arch/amd64/src/mm/page.c

    r22cf454d re3c762cd  
    167167       
    168168        page = read_cr2();
    169         if (!as_page_fault(page)) {
     169        if (as_page_fault(page, istate) == AS_PF_FAULT) {
    170170                print_info_errcode(n, istate);
    171171                printf("Page fault address: %llX\n", page);
  • arch/ia32/include/interrupt.h

    r22cf454d re3c762cd  
    8484};
    8585
     86static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     87{
     88        istate->eip = retaddr;
     89}
     90
    8691extern void (* disable_irqs_function)(__u16 irqmask);
    8792extern void (* enable_irqs_function)(__u16 irqmask);
  • arch/ia32/src/asm.S

    r22cf454d re3c762cd  
    3838.global enable_l_apic_in_msr
    3939.global interrupt_handlers
     40.global memcpy
     41.global memcpy_from_uspace
     42.global memcpy_from_uspace_failover_address
     43.global memcpy_to_uspace
     44.global memcpy_to_uspace_failover_address
     45
     46
     47#define MEMCPY_DST      4
     48#define MEMCPY_SRC      8
     49#define MEMCPY_SIZE     12
     50
     51/** Copy memory to/from userspace.
     52 *
     53 * This is almost conventional memcpy().
     54 * The difference is that there is a failover part
     55 * to where control is returned from a page fault
     56 * if the page fault occurs during copy_from_uspace()
     57 * or copy_to_uspace().
     58 *
     59 * @param MEMCPY_DST(%esp)      Destination address.
     60 * @param MEMCPY_SRC(%esp)      Source address.
     61 * @param MEMCPY_SIZE(%esp)     Size.
     62 *
     63 * @return MEMCPY_SRC(%esp) on success and 0 on failure.
     64 */
     65memcpy:
     66memcpy_from_uspace:
     67memcpy_to_uspace:
     68        movl %edi, %edx                         /* save %edi */
     69        movl %esi, %eax                         /* save %esi */
     70       
     71        movl MEMCPY_SIZE(%esp), %ecx
     72        shrl $2, %ecx                           /* size / 4 */
     73       
     74        movl MEMCPY_DST(%esp), %edi
     75        movl MEMCPY_SRC(%esp), %esi
     76       
     77        rep movsl                               /* copy as much as possible word by word */
     78
     79        movl MEMCPY_SIZE(%esp), %ecx
     80        andl $3, %ecx                           /* size % 4 */
     81        jz 0f
     82       
     83        rep movsb                               /* copy the rest byte by byte */
     84
     850:
     86        movl %edx, %edi
     87        movl %eax, %esi
     88        movl MEMCPY_SRC(%esp), %eax             /* MEMCPY_SRC(%esp), success */
     89        ret
     90       
     91/*
     92 * We got here from as_page_fault() after the memory operations
     93 * above had caused a page fault.
     94 */
     95memcpy_from_uspace_failover_address:
     96memcpy_to_uspace_failover_address:
     97        movl %edx, %edi
     98        movl %eax, %esi
     99        xorl %eax, %eax                         /* return 0, failure */
     100        ret
    40101
    41102## Turn paging on
  • arch/ia32/src/boot/boot.S

    r22cf454d re3c762cd  
    3535#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
    3636
    37 
    38 
    39 
    40 
    41 
    42 
    43 
    44 
    4537.section K_TEXT_START, "ax"
    4638
     
    436428#endif 
    437429
    438 
    439 
    440430.section K_DATA_START, "aw", @progbits
    441 
    442 
    443431
    444432.align 4096
  • arch/ia32/src/interrupt.c

    r22cf454d re3c762cd  
    145145
    146146        page = read_cr2();
    147         if (!as_page_fault(page)) {
     147        if (as_page_fault(page, istate) == AS_PF_FAULT) {
    148148                PRINT_INFO_ERRCODE(istate);
    149149                printf("page fault address: %#x\n", page);
  • arch/ia64/include/interrupt.h

    r22cf454d re3c762cd  
    107107};
    108108
     109static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     110{
     111        /* TODO */
     112}
     113
    109114extern void *ivt;
    110115
  • arch/ia64/src/asm.S

    r22cf454d re3c762cd  
    3131.text
    3232
     33/** Copy memory from/to userspace.
     34 *
     35 * @param in0 Destination address.
     36 * @param in1 Source address.
     37 * @param in2 Number of byte to copy.
     38 */
    3339.global memcpy
     40.global memcpy_from_uspace
     41.global memcpy_to_uspace
     42.global memcpy_from_uspace_failover_address
     43.global memcpy_to_uspace_failover_address
    3444memcpy:
     45memcpy_from_uspace:
     46memcpy_to_uspace:
    3547        br _memcpy
     48       
     49memcpy_from_uspace_failover_address:
     50memcpy_to_uspace_failover_address:
     51        br memcpy_from_uspace_failover_address
    3652
    3753.global memsetb
  • arch/ia64/src/mm/tlb.c

    r22cf454d re3c762cd  
    448448                 */
    449449                page_table_unlock(AS, true);
    450                 if (!as_page_fault(va)) {
     450                if (as_page_fault(va, istate) == AS_PF_FAULT) {
    451451                        panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, istate->cr_ifa, rr.map.rid, istate->cr_iip);
    452452                }
     
    494494                 */
    495495                page_table_unlock(AS, true);
    496                 if (!as_page_fault(va)) {
     496                if (as_page_fault(va, istate) == AS_PF_FAULT) {
    497497                        panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
    498498                }
     
    609609        } else {
    610610                page_table_unlock(AS, true);
    611                 if (!as_page_fault(va)) {
     611                if (as_page_fault(va, istate) == AS_PF_FAULT) {
    612612                        panic("%s: va=%p, rid=%d\n", __FUNCTION__, va, rr.map.rid);
    613613                }
  • arch/mips32/include/exception.h

    r22cf454d re3c762cd  
    9494};
    9595
     96static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     97{
     98        /* TODO */
     99}
     100
    96101extern void exception(istate_t *istate);
    97102extern void tlb_refill_entry(void);
  • arch/mips32/src/asm.S

    r22cf454d re3c762cd  
    5858        nop
    5959
     60
    6061.global memcpy
     62.global memcpy_from_uspace
     63.global memcpy_to_uspace
     64.global memcpy_from_uspace_failover_address
     65.global memcpy_to_uspace_failover_address
    6166memcpy:
     67memcpy_from_uspace:
     68memcpy_to_uspace:
    6269        j _memcpy
    6370        nop
     71
     72memcpy_from_uspace_failover_address:
     73memcpy_to_uspace_failover_address:
     74        j memcpy_from_uspace_failover_address
     75        nop
     76
     77
    6478
    6579.macro fpu_gp_save reg ctx
  • arch/mips32/src/mm/tlb.c

    r22cf454d re3c762cd  
    4545static void tlb_modified_fail(istate_t *istate);
    4646
    47 static pte_t *find_mapping_and_check(__address badvaddr);
     47static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfrc);
    4848
    4949static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn);
     
    9292        __address badvaddr;
    9393        pte_t *pte;
     94        int pfrc;
    9495
    9596        badvaddr = cp0_badvaddr_read();
     
    101102        page_table_lock(AS, true);
    102103
    103         pte = find_mapping_and_check(badvaddr);
    104         if (!pte)
    105                 goto fail;
     104        pte = find_mapping_and_check(badvaddr, istate, &pfrc);
     105        if (!pte) {
     106                switch (pfrc) {
     107                case AS_PF_FAULT:
     108                        goto fail;
     109                        break;
     110                case AS_PF_DEFER:
     111                        /*
     112                         * The page fault came during copy_from_uspace()
     113                         * or copy_to_uspace().
     114                         */
     115                        page_table_unlock(AS, true);
     116                        return;
     117                default:
     118                        panic("unexpected pfrc (%d)\n", pfrc);
     119                }
     120        }
    106121
    107122        /*
     
    149164        entry_hi_t hi;
    150165        pte_t *pte;
     166        int pfrc;
    151167
    152168        badvaddr = cp0_badvaddr_read();
     
    171187        }
    172188
    173         pte = find_mapping_and_check(badvaddr);
    174         if (!pte)
    175                 goto fail;
     189        pte = find_mapping_and_check(badvaddr, istate, &pfrc);
     190        if (!pte) {
     191                switch (pfrc) {
     192                case AS_PF_FAULT:
     193                        goto fail;
     194                        break;
     195                case AS_PF_DEFER:
     196                        /*
     197                         * The page fault came during copy_from_uspace()
     198                         * or copy_to_uspace().
     199                         */
     200                        page_table_unlock(AS, true);                     
     201                        return;
     202                default:
     203                        panic("unexpected pfrc (%d)\n", pfrc);
     204                }
     205        }
    176206
    177207        /*
     
    218248        entry_hi_t hi;
    219249        pte_t *pte;
     250        int pfrc;
    220251
    221252        badvaddr = cp0_badvaddr_read();
     
    240271        }
    241272
    242         pte = find_mapping_and_check(badvaddr);
    243         if (!pte)
    244                 goto fail;
     273        pte = find_mapping_and_check(badvaddr, istate, &pfrc);
     274        if (!pte) {
     275                switch (pfrc) {
     276                case AS_PF_FAULT:
     277                        goto fail;
     278                        break;
     279                case AS_PF_DEFER:
     280                        /*
     281                         * The page fault came during copy_from_uspace()
     282                         * or copy_to_uspace().
     283                         */
     284                        page_table_unlock(AS, true);                     
     285                        return;
     286                default:
     287                        panic("unexpected pfrc (%d)\n", pfrc);
     288                }
     289        }
    245290
    246291        /*
     
    322367 *
    323368 * @param badvaddr Faulting virtual address.
     369 * @param istate Pointer to interrupted state.
     370 * @param pfrc Pointer to variable where as_page_fault() return code will be stored.
    324371 *
    325372 * @return PTE on success, NULL otherwise.
    326373 */
    327 pte_t *find_mapping_and_check(__address badvaddr)
     374pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfrc)
    328375{
    329376        entry_hi_t hi;
     
    351398                return pte;
    352399        } else {
     400                int rc;
     401               
    353402                /*
    354403                 * Mapping not found in page tables.
     
    356405                 */
    357406                page_table_unlock(AS, true);
    358                 if (as_page_fault(badvaddr)) {
     407                switch (rc = as_page_fault(badvaddr, istate)) {
     408                case AS_PF_OK:
    359409                        /*
    360410                         * The higher-level page fault handler succeeded,
     
    365415                        ASSERT(pte && pte->p);
    366416                        return pte;
    367                 } else {
     417                        break;
     418                case AS_PF_DEFER:
     419                        page_table_lock(AS, true);
     420                        *pfrc = AS_PF_DEFER;
     421                        return NULL;
     422                        break;
     423                case AS_PF_FAULT:
    368424                        page_table_lock(AS, true);
    369425                        printf("Page fault.\n");
     426                        *pfrc = AS_PF_FAULT;
    370427                        return NULL;
     428                        break;
     429                default:
     430                        panic("unexpected rc (%d)\n", rc);
    371431                }
    372432               
  • arch/ppc32/include/exception.h

    r22cf454d re3c762cd  
    7777};
    7878
     79static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     80{
     81        /* TODO */
     82}
     83
    7984#endif
  • arch/ppc32/include/interrupt.h

    r22cf454d re3c762cd  
    3030#define __ppc32_INTERRUPT_H__
    3131
     32#include <arch/exception.h>
     33
    3234#define IRQ_COUNT       1
    3335#define IVT_ITEMS   15
  • arch/ppc32/src/asm.S

    r22cf454d re3c762cd  
    3636.global memsetb
    3737.global memcpy
     38.global memcpy_from_uspace
     39.global memcpy_to_uspace
     40.global memcpy_from_uspace_failover_address
     41.global memcpy_to_uspace_failover_address
    3842
    3943userspace_asm:
     
    234238
    235239memcpy:
     240memcpy_from_uspace:
     241memcpy_to_uspace:
     242
    236243        srwi. r7, r5, 3
    237244        addi r6, r3, -4
     
    294301        mtctr r7
    295302        b 1b
     303
     304memcpy_from_uspace_failover_address:
     305memcpy_to_uspace_failover_address:
     306        b memcpy_from_uspace_failover_address
  • arch/ppc32/src/mm/tlb.c

    r22cf454d re3c762cd  
    6969 *
    7070 * @param badvaddr Faulting virtual address.
     71 * @param istate Pointer to interrupted state.
     72 * @param pfrc Pointer to variable where as_page_fault() return code will be stored.
    7173 * @return         PTE on success, NULL otherwise.
    7274 *
    7375 */
    74 static pte_t *find_mapping_and_check(__address badvaddr)
     76static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
    7577{
    7678        /*
     
    8587                return pte;
    8688        } else {
     89                int rc;
     90       
    8791                /*
    8892                 * Mapping not found in page tables.
     
    9094                 */
    9195                page_table_unlock(AS, true);
    92                 if (as_page_fault(badvaddr)) {
     96                switch (rc = as_page_fault(badvaddr, istate)) {
     97                case AS_PF_OK:
    9398                        /*
    9499                         * The higher-level page fault handler succeeded,
     
    99104                        ASSERT((pte) && (pte->p));
    100105                        return pte;
    101                 } else {
     106                        break;
     107                case AS_PF_DEFER:
     108                        page_table_lock(AS, true);
     109                        *pfcr = rc;
     110                        return NULL;
     111                        break;
     112                case AS_PF_FAULT:
    102113                        page_table_lock(AS, true);
    103114                        printf("Page fault.\n");
     115                        *pfcr = rc;
    104116                        return NULL;
    105                 }
    106                
     117                        break;
     118                default:
     119                        panic("unexpected rc (%d)\n", rc);
     120                        break;
     121                }       
    107122        }
    108123}
     
    140155        __u32 hash;
    141156        __u32 i;
     157        int pfcr;
    142158       
    143159        if (data) {
     
    155171        page_table_lock(AS, true);
    156172       
    157         pte = find_mapping_and_check(badvaddr);
    158         if (!pte)
    159                 goto fail;
     173        pte = find_mapping_and_check(badvaddr, istate, &pfcr);
     174        if (!pte) {
     175                switch (pfcr) {
     176                case AS_PF_FAULT:
     177                        goto fail;
     178                        break;
     179                case AS_PF_DEFER:
     180                        /*
     181                         * The page fault came during copy_from_uspace()
     182                         * or copy_to_uspace().
     183                         */
     184                        page_table_unlock(AS, true);
     185                        return;
     186                default:
     187                        panic("Unexpected pfrc (%d)\n", pfcr);
     188                        break;
     189                }
     190        }
    160191
    161192        /* Record access to PTE */
  • arch/sparc64/include/interrupt.h

    r22cf454d re3c762cd  
    3131
    3232#include <typedefs.h>
     33#include <arch/types.h>
    3334
    3435#define IRQ_COUNT       1       /* TODO */
     
    4445#define trap_virtual_eoi()
    4546
     47struct istate {
     48};
     49
     50static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     51{
     52        /* TODO */
     53}
     54
    4655extern void interrupt_register(int n, const char *name, iroutine f);
    4756
  • arch/sparc64/src/asm.S

    r22cf454d re3c762cd  
    3030
    3131.global memcpy
     32.global memcpy_from_uspace
     33.global memcpy_to_uspace
     34.global memcpy_from_uspace_failover_address
     35.global memcpy_to_uspace_failover_address
    3236.global memsetb
    3337
    3438memcpy:
     39memcpy_from_uspace:
     40memcpy_to_uspace:
     41
    3542        b _memcpy
     43        nop
     44
     45memcpy_from_uspace_failover_address:
     46memcpy_to_uspace_failover_address:
     47        b memcpy_from_uspace_failover_address
    3648        nop
    3749
  • generic/include/interrupt.h

    r22cf454d re3c762cd  
    3232#include <arch/interrupt.h>
    3333#include <typedefs.h>
     34#include <arch/types.h>
    3435
    3536#ifndef IVT_ITEMS
  • generic/include/mm/as.h

    r22cf454d re3c762cd  
    6464#define AS_AREA_ATTR_PARTIAL    1       /* Not fully initialized area. */
    6565
     66#define AS_PF_FAULT             0       /**< The page fault was not resolved by asp_page_fault(). */
     67#define AS_PF_OK                1       /**< The page fault was resolved by as_page_fault(). */
     68#define AS_PF_DEFER             2       /**< The page fault was caused by memcpy_from_uspace(). */
     69
    6670/** Address space area structure.
    6771 *
     
    122126int as_area_send(task_id_t dst_id, __address base);
    123127extern void as_set_mapping(as_t *as, __address page, __address frame);
    124 extern int as_page_fault(__address page);
     128extern int as_page_fault(__address page, istate_t *istate);
    125129extern void as_switch(as_t *old, as_t *new);
    126130extern void as_free(as_t *as);
  • generic/include/mm/page.h

    r22cf454d re3c762cd  
    6161#define PAGE_GLOBAL             (1<<PAGE_GLOBAL_SHIFT)
    6262
    63 /* TODO - check that userspace is OK, platform specific functions etc */
    64 static inline void copy_to_uspace(void *dst, void *src, count_t cnt)
    65 {
    66         memcpy(dst, src, cnt);
    67 }
    68 
    69 static inline void copy_from_uspace(void *dst, void *src, count_t cnt)
    70 {
    71         memcpy(dst, src, cnt);
    72 }
    73 
    7463/** Operations to manipulate page mappings. */
    7564struct page_mapping_operations {
  • generic/include/proc/thread.h

    r22cf454d re3c762cd  
    9292        volatile int timeout_pending;           /**< Flag signalling sleep timeout in progress. */
    9393
     94        /** True if this thread is executing copy_from_uspace(). False otherwise. */
     95        bool in_copy_from_uspace;
     96        /** True if this thread is executing copy_to_uspace(). False otherwise. */
     97        bool in_copy_to_uspace;
     98
     99
    94100        fpu_context_t *saved_fpu_context;
    95101        int fpu_context_exists;
  • generic/src/ddi/ddi.c

    r22cf454d re3c762cd  
    4141#include <security/cap.h>
    4242#include <mm/frame.h>
    43 #include <mm/page.h>
    4443#include <mm/as.h>
    4544#include <synch/spinlock.h>
     45#include <syscall/copy.h>
    4646#include <arch.h>
    4747#include <align.h>
     
    184184{
    185185        ddi_memarg_t arg;
    186        
    187         copy_from_uspace(&arg, uspace_mem_arg, sizeof(ddi_memarg_t));
     186        int rc;
     187       
     188        rc = copy_from_uspace(&arg, uspace_mem_arg, sizeof(ddi_memarg_t));
     189        if (rc != 0)
     190                return (__native) rc;
     191               
    188192        return (__native) ddi_physmem_map((task_id_t) arg.task_id, ALIGN_DOWN((__address) arg.phys_base, FRAME_SIZE),
    189193                                          ALIGN_DOWN((__address) arg.virt_base, PAGE_SIZE), (count_t) arg.pages,
     
    200204{
    201205        ddi_ioarg_t arg;
    202        
    203         copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
     206        int rc;
     207       
     208        rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
     209        if (rc != 0)
     210                return (__native) rc;
     211               
    204212        return (__native) ddi_iospace_enable((task_id_t) arg.task_id, (__address) arg.ioaddr, (size_t) arg.size);
    205213}
  • generic/src/ipc/irq.c

    r22cf454d re3c762cd  
    4848#include <ipc/irq.h>
    4949#include <atomic.h>
     50#include <syscall/copy.h>
    5051
    5152typedef struct {
     
    121122        irq_code_t *code;
    122123        irq_cmd_t *ucmds;
     124        int rc;
    123125
    124126        code = malloc(sizeof(*code), 0);
    125         copy_from_uspace(code, ucode, sizeof(*code));
     127        rc = copy_from_uspace(code, ucode, sizeof(*code));
     128        if (rc != 0) {
     129                free(code);
     130                return NULL;
     131        }
    126132       
    127133        if (code->cmdcount > IRQ_MAX_PROG_SIZE) {
     
    131137        ucmds = code->cmds;
    132138        code->cmds = malloc(sizeof(code->cmds[0]) * (code->cmdcount), 0);
    133         copy_from_uspace(code->cmds, ucmds, sizeof(code->cmds[0]) * (code->cmdcount));
     139        rc = copy_from_uspace(code->cmds, ucmds, sizeof(code->cmds[0]) * (code->cmdcount));
     140        if (rc != 0) {
     141                free(code->cmds);
     142                free(code);
     143                return NULL;
     144        }
    134145
    135146        return code;
  • generic/src/ipc/sysipc.c

    r22cf454d re3c762cd  
    2929#include <arch.h>
    3030#include <proc/task.h>
    31 
     31#include <proc/thread.h>
    3232#include <errno.h>
    33 #include <mm/page.h>
    3433#include <memstr.h>
    3534#include <debug.h>
     
    3938#include <ipc/ipcrsc.h>
    4039#include <arch/interrupt.h>
    41 
    4240#include <print.h>
    43 #include <arch.h>
    44 #include <proc/thread.h>
     41#include <syscall/copy.h>
    4542
    4643#define GET_CHECK_PHONE(phone,phoneid,err) { \
     
    229226        phone_t *phone;
    230227        int res;
     228        int rc;
    231229
    232230        ipc_call_static_init(&call);
    233         copy_from_uspace(&call.data.args, &question->args, sizeof(call.data.args));
     231        rc = copy_from_uspace(&call.data.args, &question->args, sizeof(call.data.args));
     232        if (rc != 0)
     233                return (__native) rc;
    234234
    235235        GET_CHECK_PHONE(phone, phoneid, return ENOENT);
     
    241241                IPC_SET_RETVAL(call.data, res);
    242242
    243         STRUCT_TO_USPACE(&reply->args, &call.data.args);
     243        rc = STRUCT_TO_USPACE(&reply->args, &call.data.args);
     244        if (rc != 0)
     245                return rc;
    244246
    245247        return 0;
     
    298300        phone_t *phone;
    299301        int res;
     302        int rc;
    300303
    301304        if (check_call_limit())
     
    305308
    306309        call = ipc_call_alloc(0);
    307         copy_from_uspace(&call->data.args, &data->args, sizeof(call->data.args));
     310        rc = copy_from_uspace(&call->data.args, &data->args, sizeof(call->data.args));
     311        if (rc != 0)
     312                return (__native) rc;
    308313        if (!(res=request_preprocess(call)))
    309314                ipc_call(phone, call);
     
    394399        ipc_data_t saved_data;
    395400        int saveddata = 0;
     401        int rc;
    396402
    397403        call = get_call(callid);
     
    403409                saveddata = 1;
    404410        }
    405         copy_from_uspace(&call->data.args, &data->args,
     411        rc = copy_from_uspace(&call->data.args, &data->args,
    406412                         sizeof(call->data.args));
     413        if (rc != 0)
     414                return rc;
    407415
    408416        answer_preprocess(call, saveddata ? &saved_data : NULL);
  • generic/src/mm/as.c

    r22cf454d re3c762cd  
    5858#include <adt/btree.h>
    5959#include <proc/task.h>
     60#include <proc/thread.h>
    6061#include <arch/asm.h>
    6162#include <panic.h>
     
    6970#include <arch/types.h>
    7071#include <typedefs.h>
     72#include <syscall/copy.h>
     73#include <arch/interrupt.h>
    7174
    7275as_operations_t *as_operations = NULL;
     
    478481 *
    479482 * @param page Faulting page.
    480  *
    481  * @return 0 on page fault, 1 on success.
    482  */
    483 int as_page_fault(__address page)
     483 * @param istate Pointer to interrupted state.
     484 *
     485 * @return 0 on page fault, 1 on success or 2 if the fault was caused by copy_to_uspace() or copy_from_uspace().
     486 */
     487int as_page_fault(__address page, istate_t *istate)
    484488{
    485489        pte_t *pte;
     
    497501                 */
    498502                spinlock_unlock(&AS->lock);
    499                 return 0;
     503                goto page_fault;
    500504        }
    501505
     
    507511                spinlock_unlock(&area->lock);
    508512                spinlock_unlock(&AS->lock);
    509                 return 0;               
     513                goto page_fault;               
    510514        }
    511515
     
    555559        spinlock_unlock(&area->lock);
    556560        spinlock_unlock(&AS->lock);
    557         return 1;
     561        return AS_PF_OK;
     562
     563page_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;
    558578}
    559579
     
    885905{
    886906        as_area_acptsnd_arg_t arg;
    887        
    888         copy_from_uspace(&arg, uspace_accept_arg, sizeof(as_area_acptsnd_arg_t));
     907        int rc;
     908       
     909        rc = copy_from_uspace(&arg, uspace_accept_arg, sizeof(as_area_acptsnd_arg_t));
     910        if (rc != 0)
     911                return rc;
    889912       
    890913        if (!arg.size)
     
    907930{
    908931        as_area_acptsnd_arg_t arg;
    909        
    910         copy_from_uspace(&arg, uspace_send_arg, sizeof(as_area_acptsnd_arg_t));
     932        int rc;
     933       
     934        rc = copy_from_uspace(&arg, uspace_send_arg, sizeof(as_area_acptsnd_arg_t));
     935        if (rc != 0)
     936                return rc;
    911937
    912938        if (!arg.size)
  • generic/src/mm/slab.c

    r22cf454d re3c762cd  
    176176                slab = data + fsize - sizeof(*slab);
    177177        }
    178                
     178       
    179179        /* Fill in slab structures */
    180180        for (i=0; i < (1 << cache->order); i++)
     
    278278                /* Allow recursion and reclaiming
    279279                 * - this should work, as the slab control structures
    280                  *   are small and do not need to allocte with anything
    281                  *   other ten frame_alloc when they are allocating,
     280                 *   are small and do not need to allocate with anything
     281                 *   other than frame_alloc when they are allocating,
    282282                 *   that's why we should get recursion at most 1-level deep
    283283                 */
     
    880880
    881881        ASSERT(_slab_initialized);
    882         ASSERT( size && size <= (1 << SLAB_MAX_MALLOC_W));
     882        ASSERT(size && size <= (1 << SLAB_MAX_MALLOC_W));
    883883       
    884884        if (size < (1 << SLAB_MIN_MALLOC_W))
     
    890890}
    891891
    892 
    893892void free(void *obj)
    894893{
  • generic/src/printf/vsnprintf.c

    r22cf454d re3c762cd  
    4040
    4141/** Write string to given buffer.
    42  * Write at most data->size characters including trailing zero. According to C99 has snprintf to return number
     42 * Write at most data->size characters including trailing zero. According to C99, snprintf() has to return number
    4343 * of characters that would have been written if enough space had been available. Hence the return value is not
    44  * number of really printed characters but size of input string. Number of really used characters
     44 * number of really printed characters but size of the input string. Number of really used characters
    4545 * is stored in data->len.
    4646 * @param str source string to print
     
    9191        return printf_core(fmt, &ps, ap);
    9292}
    93 
    94 
  • generic/src/proc/task.c

    r22cf454d re3c762cd  
    4949#include <print.h>
    5050#include <elf.h>
    51 
     51#include <syscall/copy.h>
    5252
    5353#ifndef LOADED_PROG_STACK_PAGES_NO
     
    171171 * @param uspace_task_id Userspace address of 8-byte buffer where to store current task ID.
    172172 *
    173  * @return Always returns 0.
     173 * @return 0 on success or an error code from @ref errno.h.
    174174 */
    175175__native sys_task_get_id(task_id_t *uspace_task_id)
     
    179179         * remains constant for the lifespan of the task.
    180180         */
    181         copy_to_uspace(uspace_task_id, &TASK->taskid, sizeof(TASK->taskid));
    182 
    183         return 0;
     181        return (__native) copy_to_uspace(uspace_task_id, &TASK->taskid, sizeof(TASK->taskid));
    184182}
    185183
  • generic/src/proc/thread.c

    r22cf454d re3c762cd  
    6161#include <debug.h>
    6262#include <main/uinit.h>
     63#include <syscall/copy.h>
     64#include <errno.h>
    6365
    6466char *thread_states[] = {"Invalid", "Running", "Sleeping", "Ready", "Entering", "Exiting"}; /**< Thread states */
     
    304306        t->sleep_queue = NULL;
    305307        t->timeout_pending = 0;
     308
     309        t->in_copy_from_uspace = false;
     310        t->in_copy_to_uspace = false;
    306311       
    307312        t->rwlock_holder_type = RWLOCK_NONE;
     
    463468        uspace_arg_t *kernel_uarg;
    464469        __u32 tid;
    465 
    466         copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN);
     470        int rc;
     471
     472        rc = copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN);
     473        if (rc != 0)
     474                return (__native) rc;
    467475
    468476        kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
    469         copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t));
     477        rc = copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t));
     478        if (rc != 0) {
     479                free(kernel_uarg);
     480                return (__native) rc;
     481        }
    470482
    471483        if ((t = thread_create(uinit, kernel_uarg, TASK, 0, namebuf))) {
     
    477489        }
    478490
    479         return (__native) -1;
     491        return (__native) ENOMEM;
    480492}
    481493
  • generic/src/smp/ipi.c

    r22cf454d re3c762cd  
    4444 * @param ipi Message to broadcast.
    4545 *
    46  * @bugs The decision whether to actually send the IPI must be based
    47  *       on a different criterion. The current version has
    48  *       problems when some of the detected CPUs are marked
    49  *       disabled in machine configuration.
     46 * @bug The decision whether to actually send the IPI must be based
     47 *      on a different criterion. The current version has
     48 *      problems when some of the detected CPUs are marked
     49 *      disabled in machine configuration.
    5050 */
    5151void ipi_broadcast(int ipi)
  • generic/src/synch/waitq.c

    r22cf454d re3c762cd  
    3131 * @brief       Wait queue.
    3232 *
    33  * Wait queue is the basic synchronization primitive upon all
     33 * Wait queue is the basic synchronization primitive upon which all
    3434 * other synchronization primitives build.
    3535 *
Note: See TracChangeset for help on using the changeset viewer.