[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] Patch: Build acceleration module within linux kernel source
From: |
Robert Annessi |
Subject: |
[Qemu-devel] Patch: Build acceleration module within linux kernel source (builtin or as module) |
Date: |
Sun, 06 Aug 2006 17:00:40 +0200 |
User-agent: |
Thunderbird 1.5.0.5 (X11/20060801) |
Hi,
attached is a patch for the linux 2.6.16 kernel that lets you
build the qemu accelerator from within the kernel source (builtin or as
a module). Due to the restricting license the binary module is not
included of course.
I only tested it on x86, but it should also work on x86_64 (though I
didn't test it, since I don't have a x86_64 box to play with).
Please cc me in any replies - I'm not subscribed to the list.
Regards,
Robert
diff -urN linux-2.6.16/drivers/char/Kconfig
linux-2.6.16-qemu/drivers/char/Kconfig
--- linux-2.6.16/drivers/char/Kconfig 2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-qemu/drivers/char/Kconfig 2006-08-06 16:55:22.000000000
+0200
@@ -1020,5 +1020,6 @@
sysfs directory, /sys/devices/platform/telco_clock, with a number of
files for controlling the behavior of this hardware.
-endmenu
+source "drivers/char/qemu/Kconfig"
+endmenu
diff -urN linux-2.6.16/drivers/char/Makefile
linux-2.6.16-qemu/drivers/char/Makefile
--- linux-2.6.16/drivers/char/Makefile 2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-qemu/drivers/char/Makefile 2006-08-06 16:55:22.000000000
+0200
@@ -85,6 +85,7 @@
obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
obj-$(CONFIG_TANBAC_TB0219) += tb0219.o
obj-$(CONFIG_TELCLOCK) += tlclk.o
+obj-$(CONFIG_QEMU_ACCEL) += qemu/
obj-$(CONFIG_WATCHDOG) += watchdog/
obj-$(CONFIG_MWAVE) += mwave/
diff -urN linux-2.6.16/drivers/char/qemu/Kconfig
linux-2.6.16-qemu/drivers/char/qemu/Kconfig
--- linux-2.6.16/drivers/char/qemu/Kconfig 1970-01-01 01:00:00.000000000
+0100
+++ linux-2.6.16-qemu/drivers/char/qemu/Kconfig 2006-08-06 16:55:22.000000000
+0200
@@ -0,0 +1,61 @@
+config QEMU_ACCEL
+ tristate "QEMU Accelerator"
+ default n
+ depends on ((X86 || X86_64) && EXPERIMENTAL)
+ ---help---
+ QEMU is a processor emulator that is used to run an x86 Linux Kernel
+ on x86 Linux.
+
+ The QEMU Accelerator increases the speed of QEMU when a PC is
+ emulated on a PC. It runs most of the target application code
+ directly on the host processor to achieve near native performance.
+ It is very useful when you want to run another Operating System
+ (for example Windows) on a Linux desktop.
+
+ Download page:
+ http://fabrice.bellard.free.fr/qemu/download.html
+
+ The QEMU Accelerator Module (aka KQEMU) is a proprietary
+ product. It is available without charge. Commercial use of the QEMU
+ Accelerator Module is allowed.
+
+ Redistribution of the QEMU Accelerator Module: any person or
+ organisation wishing to distribute it, for example on a CD or as a
+ binary or source package, must have an explicit authorization from
+ the author.
+
+ The QEMU Accelerator Module is available without any express or
+ implied warranty. In no event will the author be held liable for
+ any damages arising from the use of this software.
+
+ The header file "kqemu.h" is released under the BSD license.
+
+ QEMU is a trademark of Fabrice Bellard.
+
+config QEMU_ACCEL_PATH
+ string "QEMU binary module directory path"
+ default ""
+ depends on QEMU_ACCEL
+ help
+ Specify the directory where the binary module (kqemu-mod-i386.o
+ or kqemu-mod-x86_64.o) is in.
+
+ Download page:
+ http://fabrice.bellard.free.fr/qemu/download.html
+
+ The QEMU Accelerator Module (aka KQEMU) is a proprietary
+ product. It is available without charge. Commercial use of the QEMU
+ Accelerator Module is allowed.
+
+ Redistribution of the QEMU Accelerator Module: any person or
+ organisation wishing to distribute it, for example on a CD or as a
+ binary or source package, must have an explicit authorization from
+ the author.
+
+ The QEMU Accelerator Module is available without any express or
+ implied warranty. In no event will the author be held liable for
+ any damages arising from the use of this software.
+
+ The header file "kqemu.h" is released under the BSD license.
+
+ QEMU is a trademark of Fabrice Bellard.
diff -urN linux-2.6.16/drivers/char/qemu/Makefile
linux-2.6.16-qemu/drivers/char/qemu/Makefile
--- linux-2.6.16/drivers/char/qemu/Makefile 1970-01-01 01:00:00.000000000
+0100
+++ linux-2.6.16-qemu/drivers/char/qemu/Makefile 2006-08-06
16:55:22.000000000 +0200
@@ -0,0 +1,7 @@
+kqemu-objs:= kqemu-linux.o kqemu-mod.o
+qemu_path := $(shell echo $(CONFIG_QEMU_ACCEL_PATH))
+
+$(obj)/kqemu-mod.o: $(qemu_path)/kqemu-mod-${ARCH}.o
+ cp $< $@
+
+obj-$(CONFIG_QEMU_ACCEL):= kqemu.o
diff -urN linux-2.6.16/drivers/char/qemu/kqemu-kernel.h
linux-2.6.16-qemu/drivers/char/qemu/kqemu-kernel.h
--- linux-2.6.16/drivers/char/qemu/kqemu-kernel.h 1970-01-01
01:00:00.000000000 +0100
+++ linux-2.6.16-qemu/drivers/char/qemu/kqemu-kernel.h 2006-08-06
16:55:22.000000000 +0200
@@ -0,0 +1,47 @@
+/*
+ * KQEMU kernel API
+ * Copyright (c) 2004-2005 Fabrice Bellard
+ */
+#ifndef KQEMU_KERNEL_H
+#define KQEMU_KERNEL_H
+
+#include "kqemu.h"
+
+struct kqemu_state;
+struct kqemu_global_state;
+
+#define CDECL __attribute__((regparm(0)))
+
+struct kqemu_global_state * CDECL kqemu_global_init(int max_locked_pages);
+void CDECL kqemu_global_delete(struct kqemu_global_state *g);
+
+struct kqemu_state * CDECL kqemu_init(struct kqemu_init *d,
+ struct kqemu_global_state *g);
+struct kqemu_cpu_state * CDECL kqemu_get_cpu_state(struct kqemu_state *s);
+long CDECL kqemu_exec(struct kqemu_state *s);
+void CDECL kqemu_delete(struct kqemu_state *s);
+
+/* callbacks */
+struct kqemu_page; /* opaque data for host page */
+struct kqemu_user_page; /* opaque data for host user page */
+
+struct kqemu_user_page *CDECL kqemu_lock_user_page(unsigned long *ppage_index,
+ unsigned long user_addr);
+void CDECL kqemu_unlock_user_page(struct kqemu_user_page *page);
+
+struct kqemu_page *CDECL kqemu_alloc_zeroed_page(unsigned long *ppage_index);
+void CDECL kqemu_free_page(struct kqemu_page *page);
+void * CDECL kqemu_page_kaddr(struct kqemu_page *page);
+
+void * CDECL kqemu_vmalloc(unsigned int size);
+void CDECL kqemu_vfree(void *ptr);
+unsigned long CDECL kqemu_vmalloc_to_phys(const void *vaddr);
+
+void * CDECL kqemu_io_map(unsigned long page_index, unsigned int size);
+void CDECL kqemu_io_unmap(void *ptr, unsigned int size);
+
+int CDECL kqemu_schedule(void);
+
+void CDECL kqemu_log(const char *fmt, ...);
+
+#endif /* KQEMU_KERNEL_H */
diff -urN linux-2.6.16/drivers/char/qemu/kqemu-linux.c
linux-2.6.16-qemu/drivers/char/qemu/kqemu-linux.c
--- linux-2.6.16/drivers/char/qemu/kqemu-linux.c 1970-01-01
01:00:00.000000000 +0100
+++ linux-2.6.16-qemu/drivers/char/qemu/kqemu-linux.c 2006-08-06
16:55:22.000000000 +0200
@@ -0,0 +1,372 @@
+/*
+ * Linux kernel wrapper for KQEMU
+ * Copyright (c) 2004-2005 Fabrice Bellard
+ */
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+#include <linux/ioctl.h>
+#include <linux/smp_lock.h>
+#include <linux/miscdevice.h>
+#include <asm/atomic.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include "kqemu-kernel.h"
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
+#error "Linux 2.4.19 or above needed"
+#endif
+
+/* The pfn_to_page() API appeared in 2.5.14 and changed to function during
2.6.x */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(pfn_to_page)
+#define page_to_pfn(page) ((page) - mem_map)
+#define pfn_to_page(pfn) (mem_map + (pfn))
+#endif
+
+#ifdef PAGE_KERNEL_EXEC
+#if defined(__i386__)
+/* problem : i386 kernels usually don't export __PAGE_KERNEL_EXEC */
+#undef PAGE_KERNEL_EXEC
+#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL & ~_PAGE_NX)
+#endif
+#else
+#define PAGE_KERNEL_EXEC PAGE_KERNEL
+#endif
+
+//#define DEBUG
+
+#ifdef DEBUG
+int lock_count;
+int page_alloc_count;
+#endif
+
+/* if 0 is used, then devfs/udev is used to automatically create the
+ device */
+int major = 250;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+module_param(major, int, 0);
+#else
+MODULE_PARM(major,"i");
+#endif
+
+/* Lock the page at virtual address 'user_addr' and return its
+ physical address (page index). Return a host OS private user page
+ identifier or NULL if error */
+struct kqemu_user_page *CDECL kqemu_lock_user_page(unsigned long *ppage_index,
+ unsigned long user_addr)
+{
+ int ret;
+ struct page *page;
+
+ ret = get_user_pages(current, current->mm,
+ user_addr,
+ 1, /* 1 page. */
+ 1, /* 'write': intent to write. */
+ 0, /* 'force': ? */
+ &page,
+ NULL);
+ if (ret != 1)
+ return NULL;
+ /* we ensure here that the page cannot be swapped out by the
+ kernel. */
+ /* XXX: This test may be incorrect for 2.6 kernels */
+ if (!page->mapping) {
+ put_page(page);
+ return NULL;
+ }
+#ifdef DEBUG
+ lock_count++;
+#endif
+ *ppage_index = page_to_pfn(page);
+ return (struct kqemu_user_page *)page;
+}
+
+void CDECL kqemu_unlock_user_page(struct kqemu_user_page *page1)
+{
+ struct page *page = (struct page *)page1;
+ set_page_dirty(page);
+ put_page(page);
+#ifdef DEBUG
+ lock_count--;
+#endif
+}
+
+/* Allocate a new page and return its physical address (page
+ index). Return a host OS private page identifier or NULL if
+ error */
+struct kqemu_page *CDECL kqemu_alloc_zeroed_page(unsigned long *ppage_index)
+{
+ unsigned long vaddr;
+ struct page *page;
+
+ vaddr = get_zeroed_page(GFP_KERNEL);
+ if (!vaddr)
+ return NULL;
+#ifdef DEBUG
+ page_alloc_count++;
+#endif
+ page = virt_to_page(vaddr);
+ *ppage_index = page_to_pfn(page);
+ return (struct kqemu_page *)page;
+}
+
+void CDECL kqemu_free_page(struct kqemu_page *page1)
+{
+ struct page *page = (struct page *)page1;
+ __free_page(page);
+#ifdef DEBUG
+ page_alloc_count--;
+#endif
+}
+
+/* Return a host kernel address of the physical page whose private
+ identifier is 'page1' */
+void * CDECL kqemu_page_kaddr(struct kqemu_page *page1)
+{
+ struct page *page = (struct page *)page1;
+ return page_address(page);
+}
+
+/* Allocate 'size' bytes of memory in host kernel address space (size
+ is a multiple of 4 KB) and return the address or NULL if error. The
+ allocated memory must be marked as executable by the host kernel
+ and must be page aligned. On i386 with PAE (but not on x86_64), it
+ must be allocated in the first 4 GB of physical memory. */
+void * CDECL kqemu_vmalloc(unsigned int size)
+{
+ return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL_EXEC);
+}
+
+void CDECL kqemu_vfree(void *ptr)
+{
+ return vfree(ptr);
+}
+
+/* Convert a page aligned address inside a memory area allocated by
+ kqemu_vmalloc() to a physical address (page index) */
+unsigned long CDECL kqemu_vmalloc_to_phys(const void *vaddr)
+{
+ struct page *page;
+ page = vmalloc_to_page((void *)vaddr);
+ if (!page)
+ return -1;
+ return page_to_pfn(page);
+}
+
+/* Map a IO area in the kernel address space and return its
+ address. Return NULL if error or not implemented. This function is
+ only used if an APIC is detected on the host CPU. */
+void * CDECL kqemu_io_map(unsigned long page_index, unsigned int size)
+{
+ return ioremap(page_index << PAGE_SHIFT, size);
+}
+
+/* Unmap the IO area */
+void CDECL kqemu_io_unmap(void *ptr, unsigned int size)
+{
+ return iounmap(ptr);
+}
+
+/* return TRUE if a signal is pending (i.e. the guest must stop
+ execution) */
+int CDECL kqemu_schedule(void)
+{
+ if (need_resched()) {
+ schedule();
+ }
+ return signal_pending(current);
+}
+
+char log_buf[4096];
+
+void CDECL kqemu_log(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vsnprintf(log_buf, sizeof(log_buf), fmt, ap);
+ printk("kqemu: %s", log_buf);
+ va_end(ap);
+}
+
+/*********************************************************/
+
+static struct kqemu_global_state *kqemu_gs;
+
+struct kqemu_instance {
+ struct semaphore sem;
+ struct kqemu_state *state;
+};
+
+static int kqemu_open(struct inode *inode, struct file *filp)
+{
+ struct kqemu_instance *ks;
+
+ ks = kmalloc(sizeof(struct kqemu_instance), GFP_KERNEL);
+ if (!ks)
+ return -ENOMEM;
+ init_MUTEX(&ks->sem);
+ ks->state = NULL;
+ filp->private_data = ks;
+ return 0;
+}
+
+static int kqemu_release(struct inode *inode, struct file *filp)
+{
+ struct kqemu_instance *ks = filp->private_data;
+
+ down(&ks->sem);
+ if (ks->state) {
+ kqemu_delete(ks->state);
+ ks->state = NULL;
+ }
+ up(&ks->sem);
+
+ kfree(ks);
+
+#ifdef DEBUG
+ printk("lock_count=%d page_alloc_count=%d\n",
+ lock_count, page_alloc_count);
+#endif
+ return 0;
+}
+
+static int kqemu_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ struct kqemu_instance *ks = filp->private_data;
+ struct kqemu_state *s = ks->state;
+ long ret;
+
+ down(&ks->sem);
+ switch(cmd) {
+ case KQEMU_INIT:
+ {
+ struct kqemu_init d1, *d = &d1;
+ if (s) {
+ ret = -EIO;
+ break;
+ }
+ if (copy_from_user(d, (void *)arg, sizeof(*d))) {
+ ret = -EFAULT;
+ break;
+ }
+ s = kqemu_init(d, kqemu_gs);
+ if (!s) {
+ ret = -ENOMEM;
+ break;
+ }
+ ks->state = s;
+ ret = 0;
+ }
+ break;
+ case KQEMU_EXEC:
+ {
+ struct kqemu_cpu_state *ctx;
+ if (!s) {
+ ret = -EIO;
+ break;
+ }
+
+ ctx = kqemu_get_cpu_state(s);
+ if (copy_from_user(ctx, (void *)arg, sizeof(*ctx))) {
+ ret = -EFAULT;
+ break;
+ }
+ unlock_kernel();
+ ret = kqemu_exec(s);
+ lock_kernel();
+ if (copy_to_user((void *)arg, ctx, sizeof(*ctx))) {
+ ret = -EFAULT;
+ break;
+ }
+ }
+ break;
+ case KQEMU_GET_VERSION:
+ {
+ if (put_user(KQEMU_VERSION, (int *)arg) < 0) {
+ ret = -EFAULT;
+ } else {
+ ret = 0;
+ }
+ }
+ break;
+ default:
+ ret = -ENOIOCTLCMD;
+ break;
+ }
+ up(&ks->sem);
+ return ret;
+}
+
+static struct file_operations kqemu_fops = {
+ owner: THIS_MODULE,
+ ioctl: kqemu_ioctl,
+ open: kqemu_open,
+ release: kqemu_release,
+};
+
+static struct miscdevice kqemu_dev =
+{
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "kqemu",
+ .fops = &kqemu_fops,
+};
+
+int init_module(void)
+{
+ int ret, max_locked_pages;
+ struct sysinfo si;
+
+ printk("QEMU Accelerator Module version %d.%d.%d, Copyright (c) 2005-2006
Fabrice Bellard\n"
+ "This is a proprietary product. Read the LICENSE file for more
information\n"
+ "Redistribution of this module is prohibited without
authorization\n",
+ (KQEMU_VERSION >> 16),
+ (KQEMU_VERSION >> 8) & 0xff,
+ (KQEMU_VERSION) & 0xff);
+ si_meminfo(&si);
+ max_locked_pages = si.totalram / 2;
+ kqemu_gs = kqemu_global_init(max_locked_pages);
+ if (!kqemu_gs)
+ return -ENOMEM;
+
+ if (major > 0) {
+ ret = register_chrdev(major, "kqemu", &kqemu_fops);
+ if (ret < 0) {
+ kqemu_global_delete(kqemu_gs);
+ printk("kqemu: could not get major %d\n", major);
+ return ret;
+ }
+ } else {
+ ret = misc_register (&kqemu_dev);
+ if (ret < 0) {
+ kqemu_global_delete(kqemu_gs);
+ printk("kqemu: could not create device\n");
+ return ret;
+ }
+ }
+ printk("KQEMU installed, max_locked_mem=%dkB.\n",
+ max_locked_pages * 4);
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ if (major > 0)
+ unregister_chrdev(major, "kqemu");
+ else
+ misc_deregister (&kqemu_dev);
+ if (kqemu_gs) {
+ kqemu_global_delete(kqemu_gs);
+ kqemu_gs = NULL;
+ }
+}
+
+MODULE_LICENSE("Proprietary");
+module_init(init_module);
+module_exit(cleanup_module);
diff -urN linux-2.6.16/drivers/char/qemu/kqemu.h
linux-2.6.16-qemu/drivers/char/qemu/kqemu.h
--- linux-2.6.16/drivers/char/qemu/kqemu.h 1970-01-01 01:00:00.000000000
+0100
+++ linux-2.6.16-qemu/drivers/char/qemu/kqemu.h 2006-08-06 16:55:22.000000000
+0200
@@ -0,0 +1,132 @@
+/*
+ * KQEMU header
+ *
+ * Copyright (c) 2004-2005 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef KQEMU_H
+#define KQEMU_H
+
+#define KQEMU_VERSION 0x010300
+
+struct kqemu_segment_cache {
+ uint32_t selector;
+ unsigned long base;
+ uint32_t limit;
+ uint32_t flags;
+};
+
+struct kqemu_cpu_state {
+#ifdef __x86_64__
+ unsigned long regs[16];
+#else
+ unsigned long regs[8];
+#endif
+ unsigned long eip;
+ unsigned long eflags;
+
+ uint32_t dummy0, dummy1, dumm2, dummy3, dummy4;
+
+ struct kqemu_segment_cache segs[6]; /* selector values */
+ struct kqemu_segment_cache ldt;
+ struct kqemu_segment_cache tr;
+ struct kqemu_segment_cache gdt; /* only base and limit are used */
+ struct kqemu_segment_cache idt; /* only base and limit are used */
+
+ unsigned long cr0;
+ unsigned long dummy5;
+ unsigned long cr2;
+ unsigned long cr3;
+ unsigned long cr4;
+ uint32_t a20_mask;
+
+ /* sysenter registers */
+ uint32_t sysenter_cs;
+ uint32_t sysenter_esp;
+ uint32_t sysenter_eip;
+ uint64_t efer __attribute__((aligned(8)));
+ uint64_t star;
+#ifdef __x86_64__
+ unsigned long lstar;
+ unsigned long cstar;
+ unsigned long fmask;
+ unsigned long kernelgsbase;
+#endif
+ uint64_t tsc_offset;
+
+ unsigned long dr0;
+ unsigned long dr1;
+ unsigned long dr2;
+ unsigned long dr3;
+ unsigned long dr6;
+ unsigned long dr7;
+
+ uint8_t cpl;
+ uint8_t user_only;
+
+ uint32_t error_code; /* error_code when exiting with an exception */
+ unsigned long next_eip; /* next eip value when exiting with an interrupt */
+ unsigned int nb_pages_to_flush; /* number of pages to flush,
+ KQEMU_FLUSH_ALL means full flush */
+#define KQEMU_MAX_PAGES_TO_FLUSH 512
+#define KQEMU_FLUSH_ALL (KQEMU_MAX_PAGES_TO_FLUSH + 1)
+
+ long retval;
+
+ /* number of ram_dirty entries to update */
+ unsigned int nb_ram_pages_to_update;
+#define KQEMU_MAX_RAM_PAGES_TO_UPDATE 512
+#define KQEMU_RAM_PAGES_UPDATE_ALL (KQEMU_MAX_RAM_PAGES_TO_UPDATE + 1)
+
+#define KQEMU_MAX_MODIFIED_RAM_PAGES 512
+ unsigned int nb_modified_ram_pages;
+};
+
+struct kqemu_init {
+ uint8_t *ram_base; /* must be page aligned */
+ unsigned long ram_size; /* must be multiple of 4 KB */
+ uint8_t *ram_dirty; /* must be page aligned */
+ uint32_t **phys_to_ram_map; /* must be page aligned */
+ unsigned long *pages_to_flush; /* must be page aligned */
+ unsigned long *ram_pages_to_update; /* must be page aligned */
+ unsigned long *modified_ram_pages; /* must be page aligned */
+};
+
+#define KQEMU_RET_ABORT (-1)
+#define KQEMU_RET_EXCEPTION 0x0000 /* 8 low order bit are the exception */
+#define KQEMU_RET_INT 0x0100 /* 8 low order bit are the interrupt */
+#define KQEMU_RET_SOFTMMU 0x0200 /* emulation needed (I/O or
+ unsupported INSN) */
+#define KQEMU_RET_INTR 0x0201 /* interrupted by a signal */
+#define KQEMU_RET_SYSCALL 0x0300 /* syscall insn */
+
+#ifdef _WIN32
+#define KQEMU_EXEC CTL_CODE(FILE_DEVICE_UNKNOWN, 1,
METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define KQEMU_INIT CTL_CODE(FILE_DEVICE_UNKNOWN, 2,
METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define KQEMU_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 3,
METHOD_BUFFERED, FILE_READ_ACCESS)
+#define KQEMU_MODIFY_RAM_PAGES CTL_CODE(FILE_DEVICE_UNKNOWN, 4,
METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#else
+#define KQEMU_EXEC _IOWR('q', 1, struct kqemu_cpu_state)
+#define KQEMU_INIT _IOW('q', 2, struct kqemu_init)
+#define KQEMU_GET_VERSION _IOR('q', 3, int)
+#define KQEMU_MODIFY_RAM_PAGES _IOW('q', 4, int)
+#endif
+
+#endif /* KQEMU_H */
signature.asc
Description: OpenPGP digital signature
- [Qemu-devel] Patch: Build acceleration module within linux kernel source (builtin or as module),
Robert Annessi <=