1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation;
5  * version 2.1 of the License.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; If not, see <http://www.gnu.org/licenses/>.
14  *
15  * Split out from xc_linus_osdep.c:
16  *
17  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
18  */
19 
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 
24 #include <stdlib.h>
25 #include <assert.h>
26 #include <stdio.h>
27 
28 #include <sys/mman.h>
29 #include <sys/ioctl.h>
30 
31 #include "private.h"
32 
33 #ifndef O_CLOEXEC
34 #define O_CLOEXEC 0
35 #endif
36 
osdep_xencall_open(xencall_handle * xcall)37 int osdep_xencall_open(xencall_handle *xcall)
38 {
39     int fd;
40 
41     /*
42      * Prefer the newer interface.
43      */
44     fd = open("/dev/xen/privcmd", O_RDWR|O_CLOEXEC);
45 
46     if ( fd == -1 && ( errno == ENOENT || errno == ENXIO || errno == ENODEV ))
47     {
48         /* Fallback to /proc/xen/privcmd */
49         fd = open("/proc/xen/privcmd", O_RDWR|O_CLOEXEC);
50     }
51 
52     if ( fd == -1 )
53     {
54         PERROR("Could not obtain handle on privileged command interface");
55         return -1;
56     }
57 
58     xcall->fd = fd;
59     return 0;
60 }
61 
osdep_xencall_close(xencall_handle * xcall)62 int osdep_xencall_close(xencall_handle *xcall)
63 {
64     int fd = xcall->fd;
65     if (fd == -1)
66         return 0;
67     return close(fd);
68 }
69 
osdep_hypercall(xencall_handle * xcall,privcmd_hypercall_t * hypercall)70 int osdep_hypercall(xencall_handle *xcall, privcmd_hypercall_t *hypercall)
71 {
72     return ioctl(xcall->fd, IOCTL_PRIVCMD_HYPERCALL, hypercall);
73 }
74 
osdep_alloc_pages(xencall_handle * xcall,size_t npages)75 void *osdep_alloc_pages(xencall_handle *xcall, size_t npages)
76 {
77     size_t size = npages * PAGE_SIZE;
78     void *p;
79     int rc, i, saved_errno;
80 
81     /* Address returned by mmap is page aligned. */
82     p = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED, -1, 0);
83     if ( p == MAP_FAILED )
84     {
85         PERROR("alloc_pages: mmap failed");
86         return NULL;
87     }
88 
89     /* Do not copy the VMA to child process on fork. Avoid the page being COW
90         on hypercall. */
91     rc = madvise(p, npages * PAGE_SIZE, MADV_DONTFORK);
92     if ( rc < 0 )
93     {
94         PERROR("alloc_pages: madvise failed");
95         goto out;
96     }
97 
98     /*
99      * Touch each page in turn to force them to be un-CoWed, in case a
100      * fork happened in another thread at an inopportune moment
101      * above. The madvise() will prevent any subsequent fork calls from
102      * causing the same problem.
103      */
104     for ( i = 0; i < npages ; i++ )
105     {
106         char *c = (char *)p + (i*PAGE_SIZE);
107         *c = 0;
108     }
109 
110     return p;
111 
112 out:
113     saved_errno = errno;
114     (void)munmap(p, size);
115     errno = saved_errno;
116     return NULL;
117 }
118 
osdep_free_pages(xencall_handle * xcall,void * ptr,size_t npages)119 void osdep_free_pages(xencall_handle *xcall, void *ptr, size_t npages)
120 {
121     int saved_errno = errno;
122     /* Recover the VMA flags. Maybe it's not necessary */
123     madvise(ptr, npages * PAGE_SIZE, MADV_DOFORK);
124 
125     munmap(ptr, npages * PAGE_SIZE);
126     /* We MUST propagate the hypercall errno, not unmap call's. */
127     errno = saved_errno;
128 }
129 
130 /*
131  * Local variables:
132  * mode: C
133  * c-file-style: "BSD"
134  * c-basic-offset: 4
135  * tab-width: 4
136  * indent-tabs-mode: nil
137  * End:
138  */
139