1 /******************************************************************************
2  *
3  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
4  * Use is subject to license terms.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation;
9  * version 2.1 of the License.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <sys/mman.h>
23 
24 #include "private.h"
25 
osdep_xenforeignmemory_open(xenforeignmemory_handle * fmem)26 int osdep_xenforeignmemory_open(xenforeignmemory_handle *fmem)
27 {
28     int flags, saved_errno;
29     int fd = open("/kern/xen/privcmd", O_RDWR);
30 
31     if ( fd == -1 )
32     {
33         PERROR("Could not obtain handle on privileged command interface");
34         return -1;
35     }
36 
37     /* Although we return the file handle as the 'xc handle' the API
38        does not specify / guarentee that this integer is in fact
39        a file handle. Thus we must take responsiblity to ensure
40        it doesn't propagate (ie leak) outside the process */
41     if ( (flags = fcntl(fd, F_GETFD)) < 0 )
42     {
43         PERROR("Could not get file handle flags");
44         goto error;
45     }
46     flags |= FD_CLOEXEC;
47     if ( fcntl(fd, F_SETFD, flags) < 0 )
48     {
49         PERROR("Could not set file handle flags");
50         goto error;
51     }
52 
53     fmem->fd = fd;
54     return 0;
55 
56  error:
57     saved_errno = errno;
58     close(fd);
59     errno = saved_errno;
60     return -1;
61 }
62 
osdep_xenforeignmemory_close(xenforeignmemory_handle * fmem)63 int osdep_xenforeignmemory_close(xenforeignmemory_handle *fmem)
64 {
65     int fd = fmem->fd;
66     return close(fd);
67 }
68 
osdep_map_foreign_batch(xenforeignmem_handle * fmem,uint32_t dom,void * addr,int prot,int flags,xen_pfn_t * arr,int num)69 void *osdep_map_foreign_batch(xenforeignmem_handle *fmem, uint32_t dom,
70                               void *addr, int prot, int flags,
71                               xen_pfn_t *arr, int num)
72 {
73     int fd = fmem->fd;
74     privcmd_mmapbatch_t ioctlx;
75     addr = mmap(addr, num*XC_PAGE_SIZE, prot, flags | MAP_ANON | MAP_SHARED, -1, 0);
76     if ( addr == MAP_FAILED ) {
77         PERROR("osdep_map_foreign_batch: mmap failed");
78         return NULL;
79     }
80 
81     ioctlx.num=num;
82     ioctlx.dom=dom;
83     ioctlx.addr=(unsigned long)addr;
84     ioctlx.arr=arr;
85     if ( ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx) < 0 )
86     {
87         int saved_errno = errno;
88         PERROR("osdep_map_foreign_batch: ioctl failed");
89         (void)munmap(addr, num*XC_PAGE_SIZE);
90         errno = saved_errno;
91         return NULL;
92     }
93     return addr;
94 
95 }
96 
osdep_xenforeignmemory_unmap(xenforeignmemory_handle * fmem,void * addr,size_t num)97 int osdep_xenforeignmemory_unmap(xenforeignmemory_handle *fmem,
98                                  void *addr, size_t num)
99 {
100     return munmap(addr, num*XC_PAGE_SIZE);
101 }
102 
osdep_xenforeignmemory_restrict(xenforeignmemory_handle * fmem,domid_t domid)103 int osdep_xenforeignmemory_restrict(xenforeignmemory_handle *fmem,
104                                     domid_t domid)
105 {
106     errno = -EOPNOTSUPP;
107     return -1;
108 }
109 
110 /*
111  * Local variables:
112  * mode: C
113  * c-file-style: "BSD"
114  * c-basic-offset: 4
115  * tab-width: 4
116  * indent-tabs-mode: nil
117  * End:
118  */
119