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"