0.8.0-alt1
[qemu] / kqemu / kqemu-linux.c
1 /*
2  * Linux kernel wrapper for KQEMU
3  * Copyright (c) 2004-2005 Fabrice Bellard
4  */
5 #include <linux/module.h>
6 #include <linux/types.h>
7 #include <linux/errno.h>
8 #include <linux/fs.h>
9 #include <linux/mm.h>
10 #include <linux/proc_fs.h>
11 #include <linux/version.h>
12 #include <linux/ioctl.h>
13 #include <linux/smp_lock.h>
14 #include <linux/miscdevice.h>
15 #include <asm/atomic.h>
16 #include <asm/processor.h>
17 #include <asm/uaccess.h>
18 #include <asm/io.h>
19
20 #include "kqemu-kernel.h"
21
22 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
23 #error "Linux 2.4.19 or above needed"
24 #endif
25
26 #ifndef page_to_pfn
27 #define page_to_pfn(page) ((page) - mem_map)
28 #define pfn_to_page(pfn) (mem_map + (pfn))
29 #endif
30
31 #ifdef PAGE_KERNEL_EXEC
32 #if defined(__i386__)
33 /* problem : i386 kernels usually don't export __PAGE_KERNEL_EXEC */
34 #undef PAGE_KERNEL_EXEC
35 #define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL & ~_PAGE_NX)
36 #endif
37 #else
38 #define PAGE_KERNEL_EXEC PAGE_KERNEL
39 #endif
40
41 //#define DEBUG
42
43 #ifdef DEBUG
44 int lock_count;
45 int page_alloc_count;
46 #endif
47
48 /* if 0 is used, then devfs/udev is used to automatically create the
49    device */
50 int major = 250;
51 MODULE_PARM(major,"i");
52
53 /* configurable max_instances */
54 int max_instances = 4;
55 MODULE_PARM(max_instances,"i");
56
57 /* lock the page at virtual address 'user_addr' and return its
58    page index. Return -1 if error */
59 struct kqemu_user_page *CDECL kqemu_lock_user_page(unsigned long *ppage_index,
60                                                    unsigned long user_addr)
61 {
62     int ret;
63     struct page *page;
64
65     ret = get_user_pages(current, current->mm,
66                          user_addr,
67                          1, /* 1 page. */
68                          1, /* 'write': intent to write. */
69                          0, /* 'force': ? */
70                          &page,
71                          NULL);
72     if (ret != 1)
73         return NULL;
74     /* we ensure here that the page cannot be swapped out by the
75        kernel. */
76     /* XXX: This test may be incorrect for 2.6 kernels */
77     if (!page->mapping) {
78         put_page(page);
79         return NULL;
80     }
81 #ifdef DEBUG
82     lock_count++;
83 #endif
84     *ppage_index = page_to_pfn(page);
85     return (struct kqemu_user_page *)page;
86 }
87
88 void CDECL kqemu_unlock_user_page(struct kqemu_user_page *page1)
89 {
90     struct page *page = (struct page *)page1;
91     set_page_dirty(page);
92     put_page(page);
93 #ifdef DEBUG
94     lock_count--;
95 #endif
96 }
97
98 /* Allocate a new page. The page must be mapped in the kernel
99    space. Return the page_index or -1 if error */
100 struct kqemu_page *CDECL kqemu_alloc_zeroed_page(unsigned long *ppage_index)
101 {
102     unsigned long vaddr;
103     struct page *page;
104
105     vaddr = get_zeroed_page(GFP_KERNEL);
106     if (!vaddr)
107         return NULL;
108 #ifdef DEBUG
109     page_alloc_count++;
110 #endif
111     page = virt_to_page(vaddr);
112     *ppage_index = page_to_pfn(page);
113     return (struct kqemu_page *)page;
114 }
115
116 void CDECL kqemu_free_page(struct kqemu_page *page1)
117 {
118     struct page *page = (struct page *)page1;
119     __free_page(page);
120 #ifdef DEBUG
121     page_alloc_count--;
122 #endif
123 }
124
125 /* return a kernel address of the physical page page_index */
126 void * CDECL kqemu_page_kaddr(struct kqemu_page *page1)
127 {
128     struct page *page = (struct page *)page1;
129     return page_address(page);
130 }
131
132 /* contraint: each page of the vmalloced area must be in the first 4
133    GB of physical memory. Moreover, execution of code should be
134    enabled in the allocated area. */
135 void * CDECL kqemu_vmalloc(unsigned int size)
136 {
137     return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL_EXEC);
138 }
139
140 void CDECL kqemu_vfree(void *ptr)
141 {
142     return vfree(ptr);
143 }
144
145 unsigned long CDECL kqemu_vmalloc_to_phys(const void *vaddr)
146 {
147     struct page *page;
148     page = vmalloc_to_page((void *)vaddr);
149     if (!page)
150         return -1;
151     return page_to_pfn(page);
152 }
153
154 /* Map a IO area in the kernel address space and return its
155    address. Return NULL if error or not implemented.  */
156 void * CDECL kqemu_io_map(unsigned long page_index, unsigned int size)
157 {
158     return ioremap(page_index << PAGE_SHIFT, size);
159 }
160
161 /* Unmap the IO area */
162 void CDECL kqemu_io_unmap(void *ptr, unsigned int size)
163 {
164     return iounmap(ptr);
165 }
166
167 /* return TRUE if a signal is pending (i.e. the guest must stop
168    execution) */
169 int CDECL kqemu_schedule(void)
170 {
171     if (need_resched()) {
172         schedule();
173     }
174     return signal_pending(current);
175 }
176
177 char log_buf[4096];
178
179 void CDECL kqemu_log(const char *fmt, ...)
180 {
181     va_list ap;
182     va_start(ap, fmt);
183     vsnprintf(log_buf, sizeof(log_buf), fmt, ap);
184     printk("kqemu: %s", log_buf);
185     va_end(ap);
186 }
187
188 /*********************************************************/
189
190 static int kqemu_nb_instances = 0;
191 static spinlock_t kqemu_lock = SPIN_LOCK_UNLOCKED;
192 static int max_locked_pages;
193
194 struct kqemu_instance {
195     struct semaphore sem; 
196     struct kqemu_state *state;
197 };
198
199 static int kqemu_open(struct inode *inode, struct file *filp)
200 {
201     struct kqemu_instance *ks;
202     
203     spin_lock(&kqemu_lock);
204     if (kqemu_nb_instances >= max_instances) {
205         spin_unlock(&kqemu_lock);
206         return -ENOMEM;
207     }
208     kqemu_nb_instances++;
209     spin_unlock(&kqemu_lock);
210     
211     ks = kmalloc(sizeof(struct kqemu_instance), GFP_KERNEL);
212     if (!ks)
213         return -ENOMEM;
214     init_MUTEX(&ks->sem);
215     ks->state = NULL;
216     filp->private_data = ks;
217     return 0;
218 }
219
220 static int kqemu_release(struct inode *inode, struct file *filp)
221 {
222     struct kqemu_instance *ks = filp->private_data;
223
224     down(&ks->sem);
225     if (ks->state) {
226         kqemu_delete(ks->state);
227         ks->state = NULL;
228     }
229     up(&ks->sem);
230
231     kfree(ks);
232
233     spin_lock(&kqemu_lock);
234     kqemu_nb_instances--;
235     spin_unlock(&kqemu_lock);
236
237 #ifdef DEBUG
238     printk("lock_count=%d page_alloc_count=%d\n",
239            lock_count, page_alloc_count);
240 #endif
241     return 0;
242 }
243
244 static int kqemu_ioctl(struct inode *inode, struct file *filp,
245                        unsigned int cmd, unsigned long arg)
246 {
247     struct kqemu_instance *ks = filp->private_data;
248     struct kqemu_state *s = ks->state;
249     long ret;
250
251     down(&ks->sem);
252     switch(cmd) {
253     case KQEMU_INIT:
254         {
255             struct kqemu_init d1, *d = &d1;
256             if (s) {
257                 ret = -EIO;
258                 break;
259             }
260             if (copy_from_user(d, (void *)arg, sizeof(*d))) {
261                 ret = -EFAULT;
262                 break;
263             }
264             s = kqemu_init(d, max_locked_pages);
265             if (!s) {
266                 ret = -ENOMEM;
267                 break;
268             }
269             ks->state = s;
270             ret = 0;
271         }
272         break;
273     case KQEMU_EXEC:
274         {
275             struct kqemu_cpu_state *ctx;
276             if (!s) {
277                 ret = -EIO;
278                 break;
279             }
280             
281             ctx = kqemu_get_cpu_state(s);
282             if (copy_from_user(ctx, (void *)arg, sizeof(*ctx))) {
283                 ret = -EFAULT;
284                 break;
285             }
286             unlock_kernel();
287             ret = kqemu_exec(s);
288             lock_kernel();
289             if (copy_to_user((void *)arg, ctx, sizeof(*ctx))) {
290                 ret = -EFAULT;
291                 break;
292             }
293         }
294         break;
295     case KQEMU_GET_VERSION:
296         {
297             if (put_user(KQEMU_VERSION, (int *)arg) < 0) {
298                 ret = -EFAULT;
299             } else {
300                 ret = 0;
301             }
302         }
303         break;
304     default:
305         ret = -ENOIOCTLCMD;
306         break;
307     }
308     up(&ks->sem);
309     return ret;
310 }
311
312 static struct file_operations kqemu_fops = {
313     owner:    THIS_MODULE,
314     ioctl:    kqemu_ioctl,
315     open:     kqemu_open,
316     release:  kqemu_release,
317 };
318
319 static struct miscdevice kqemu_dev =
320 {
321     .minor      = MISC_DYNAMIC_MINOR,
322     .name       = "kqemu",
323     .fops       = &kqemu_fops,
324 };
325
326 int init_module(void)
327 {
328     int ret;
329     struct sysinfo si;
330
331     printk("QEMU Accelerator Module version %d.%d.%d, Copyright (c) 2005 Fabrice Bellard\n"
332            "This is a proprietary product. Read the LICENSE file for more information\n"
333            "Redistribution of this module is prohibited without authorization\n",
334            (KQEMU_VERSION >> 16),
335            (KQEMU_VERSION >> 8) & 0xff,
336            (KQEMU_VERSION) & 0xff);
337     si_meminfo(&si);
338     max_locked_pages = si.totalram / (2 * max_instances);
339     if (max_locked_pages > 32768)
340         max_locked_pages = 32768;
341
342     if (major > 0) {
343         ret = register_chrdev(major, "kqemu", &kqemu_fops);
344         if (ret < 0) {
345             printk("kqemu: could not get major %d\n", major);
346             return ret;
347         }
348     } else {
349         ret = misc_register (&kqemu_dev);
350         if (ret < 0) {
351             printk("kqemu: could not create device\n");
352             return ret;
353         }
354     }
355     printk("KQEMU installed, max_instances=%d max_locked_mem=%dkB.\n",
356            max_instances, 
357            max_locked_pages * 4);
358     return 0;
359 }
360
361 void cleanup_module(void)
362 {
363     if (major > 0) 
364         unregister_chrdev(major, "kqemu");
365     else
366         misc_deregister (&kqemu_dev);
367 }