qemu-devel
[Top][All Lists]
Advanced

[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 */

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]