LCOV - code coverage report
Current view: top level - uvm - uvm_io.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 39 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: uvm_io.c,v 1.26 2016/01/09 11:34:27 kettenis Exp $    */
       2             : /*      $NetBSD: uvm_io.c,v 1.12 2000/06/27 17:29:23 mrg Exp $  */
       3             : 
       4             : /*
       5             :  * Copyright (c) 1997 Charles D. Cranor and Washington University.
       6             :  * All rights reserved.
       7             :  *
       8             :  * Redistribution and use in source and binary forms, with or without
       9             :  * modification, are permitted provided that the following conditions
      10             :  * are met:
      11             :  * 1. Redistributions of source code must retain the above copyright
      12             :  *    notice, this list of conditions and the following disclaimer.
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      18             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      19             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      20             :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      21             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      22             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      26             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             :  *
      28             :  * from: Id: uvm_io.c,v 1.1.2.2 1997/12/30 12:02:00 mrg Exp
      29             :  */
      30             : 
      31             : /*
      32             :  * uvm_io.c: uvm i/o ops
      33             :  */
      34             : 
      35             : #include <sys/param.h>
      36             : #include <sys/systm.h>
      37             : #include <sys/mman.h>
      38             : #include <sys/uio.h>
      39             : 
      40             : #include <uvm/uvm.h>
      41             : 
      42             : /*
      43             :  * functions
      44             :  */
      45             : 
      46             : /*
      47             :  * uvm_io: perform I/O on a map
      48             :  *
      49             :  * => caller must have a reference to "map" so that it doesn't go away
      50             :  *    while we are working.
      51             :  */
      52             : 
      53             : int
      54           0 : uvm_io(vm_map_t map, struct uio *uio, int flags)
      55             : {
      56           0 :         vaddr_t baseva, endva, pageoffset, kva;
      57             :         vsize_t chunksz, togo, sz;
      58           0 :         struct uvm_map_deadq dead_entries;
      59             :         int error, extractflags;
      60             : 
      61             :         /*
      62             :          * step 0: sanity checks and set up for copy loop.  start with a
      63             :          * large chunk size.  if we have trouble finding vm space we will
      64             :          * reduce it.
      65             :          */
      66           0 :         if (uio->uio_resid == 0)
      67           0 :                 return(0);
      68             :         togo = uio->uio_resid;
      69             : 
      70           0 :         baseva = (vaddr_t) uio->uio_offset;
      71           0 :         endva = baseva + (togo - 1);
      72             : 
      73           0 :         if (endva < baseva)   /* wrap around? */
      74           0 :                 return(EIO);
      75             : 
      76           0 :         if (baseva >= VM_MAXUSER_ADDRESS)
      77           0 :                 return(0);
      78           0 :         if (endva >= VM_MAXUSER_ADDRESS)
      79             :                 /* EOF truncate */
      80           0 :                 togo = togo - (endva - VM_MAXUSER_ADDRESS + 1);
      81           0 :         pageoffset = baseva & PAGE_MASK;
      82           0 :         baseva = trunc_page(baseva);
      83           0 :         chunksz = min(round_page(togo + pageoffset), MAXBSIZE);
      84             :         error = 0;
      85             : 
      86             :         extractflags = 0;
      87           0 :         if (flags & UVM_IO_FIXPROT)
      88           0 :                 extractflags |= UVM_EXTRACT_FIXPROT;
      89             : 
      90             :         /* step 1: main loop...  while we've got data to move */
      91           0 :         for (/*null*/; togo > 0 ; pageoffset = 0) {
      92             :                 /* step 2: extract mappings from the map into kernel_map */
      93           0 :                 error = uvm_map_extract(map, baseva, chunksz, &kva,
      94             :                     extractflags);
      95           0 :                 if (error) {
      96             : 
      97             :                         /* retry with a smaller chunk... */
      98           0 :                         if (error == ENOMEM && chunksz > PAGE_SIZE) {
      99           0 :                                 chunksz = trunc_page(chunksz / 2);
     100           0 :                                 if (chunksz < PAGE_SIZE)
     101             :                                         chunksz = PAGE_SIZE;
     102           0 :                                 continue;
     103             :                         }
     104             : 
     105             :                         break;
     106             :                 }
     107             : 
     108             :                 /* step 3: move a chunk of data */
     109           0 :                 sz = chunksz - pageoffset;
     110           0 :                 if (sz > togo)
     111           0 :                         sz = togo;
     112           0 :                 error = uiomove((caddr_t) (kva + pageoffset), sz, uio);
     113           0 :                 togo -= sz;
     114           0 :                 baseva += chunksz;
     115             : 
     116             :                 /* step 4: unmap the area of kernel memory */
     117           0 :                 vm_map_lock(kernel_map);
     118           0 :                 TAILQ_INIT(&dead_entries);
     119           0 :                 uvm_unmap_remove(kernel_map, kva, kva+chunksz,
     120             :                     &dead_entries, FALSE, TRUE);
     121           0 :                 vm_map_unlock(kernel_map);
     122           0 :                 uvm_unmap_detach(&dead_entries, AMAP_REFALL);
     123             : 
     124             :                 /*
     125             :                  * We defer checking the error return from uiomove until
     126             :                  * here so that we won't leak memory.
     127             :                  */
     128           0 :                 if (error)
     129             :                         break;
     130             :         }
     131             : 
     132           0 :         return (error);
     133           0 : }

Generated by: LCOV version 1.13