2 * arch/um/kernel/mem_user.c
4 * BRIEF MODULE DESCRIPTION
5 * user side memory routines for supporting IO memory inside user mode linux
7 * Copyright (C) 2001 RidgeRun, Inc.
8 * Author: RidgeRun, Inc.
9 * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA.
40 #include <sys/types.h>
42 #include "kern_util.h"
44 #include "user_util.h"
49 #include "kern_constants.h"
51 #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
53 static int create_tmp_file(unsigned long len
)
58 fd
= make_tempfile(TEMPNAME_TEMPLATE
, NULL
, 1);
60 os_print_error(fd
, "make_tempfile");
64 err
= os_mode_fd(fd
, 0777);
66 os_print_error(err
, "os_mode_fd");
69 err
= os_seek_file(fd
, len
);
71 os_print_error(err
, "os_seek_file");
75 err
= os_write_file(fd
, &zero
, 1);
77 os_print_error(err
, "os_write_file");
84 void check_tmpexec(void)
87 int err
, fd
= create_tmp_file(UM_KERN_PAGE_SIZE
);
89 addr
= mmap(NULL
, UM_KERN_PAGE_SIZE
,
90 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, fd
, 0);
91 printf("Checking PROT_EXEC mmap in /tmp...");
93 if(addr
== MAP_FAILED
){
97 printf("/tmp must be not mounted noexec\n");
101 munmap(addr
, UM_KERN_PAGE_SIZE
);
106 static int have_devanon
= 0;
108 void check_devanon(void)
112 printk("Checking for /dev/anon on the host...");
113 fd
= open("/dev/anon", O_RDWR
);
115 printk("Not available (open failed with errno %d)\n", errno
);
123 static int create_anon_file(unsigned long len
)
128 fd
= open("/dev/anon", O_RDWR
);
130 os_print_error(fd
, "opening /dev/anon");
134 addr
= mmap(NULL
, len
, PROT_READ
| PROT_WRITE
, MAP_PRIVATE
, fd
, 0);
135 if(addr
== MAP_FAILED
){
136 perror("mapping physmem file");
144 int create_mem_file(unsigned long len
)
149 fd
= create_anon_file(len
);
150 else fd
= create_tmp_file(len
);
152 err
= os_set_exec_close(fd
, 1);
154 os_print_error(err
, "exec_close");
158 struct iomem_region
*iomem_regions
= NULL
;
161 static int __init
parse_iomem(char *str
, int *add
)
163 struct iomem_region
*new;
169 file
= strchr(str
,',');
171 printf("parse_iomem : failed to parse iomem\n");
176 fd
= os_open_file(file
, of_rdwr(OPENFLAGS()), 0);
178 os_print_error(fd
, "parse_iomem - Couldn't open io file");
182 err
= os_stat_fd(fd
, &buf
);
184 os_print_error(err
, "parse_iomem - cannot stat_fd file");
188 new = malloc(sizeof(*new));
190 perror("Couldn't allocate iomem_region struct");
194 size
= (buf
.ust_size
+ UM_KERN_PAGE_SIZE
) & ~(UM_KERN_PAGE_SIZE
- 1);
196 *new = ((struct iomem_region
) { .next
= iomem_regions
,
203 iomem_size
+= new->size
+ UM_KERN_PAGE_SIZE
;
212 __uml_setup("iomem=", parse_iomem
,
213 "iomem=<name>,<file>\n"
214 " Configure <file> as an IO memory region named <name>.\n\n"
217 int protect_memory(unsigned long addr
, unsigned long len
, int r
, int w
, int x
,
222 err
= os_protect_memory((void *) addr
, len
, r
, w
, x
);
225 panic("protect failed, err = %d", -err
);
232 /* Debugging facility for dumping stuff out to the host, avoiding the timing
233 * problems that come with printf and breakpoints.
234 * Enable in case of emergency.
240 int logging_line
= 0;
241 char logging_buf
[512];
243 void log(char *fmt
, ...)
247 struct openflags flags
;
249 if(logging
== 0) return;
251 flags
= of_create(of_trunc(of_rdwr(OPENFLAGS())));
252 logging_fd
= os_open_file("log", flags
, 0644);
254 gettimeofday(&tv
, NULL
);
255 sprintf(logging_buf
, "%d\t %u.%u ", logging_line
++, tv
.tv_sec
,
258 vsprintf(&logging_buf
[strlen(logging_buf
)], fmt
, ap
);
260 write(logging_fd
, logging_buf
, strlen(logging_buf
));
265 * Overrides for Emacs so that we follow Linus's tabbing style.
266 * Emacs will notice this stuff at the end of the file and automatically
267 * adjust the settings for this buffer only. This must remain at the end
269 * ---------------------------------------------------------------------------
271 * c-file-style: "linux"