* [Qemu-devel] Accelerator for FreeBSD? @ 2005-03-21 1:42 Ryan Rempel 2005-03-21 4:22 ` Mikko Työläjärvi 2005-03-21 14:57 ` KQEMU on FreeBSD partially works. (Was: [Qemu-devel] Accelerator for FreeBSD?) Antony T Curtis 0 siblings, 2 replies; 6+ messages in thread From: Ryan Rempel @ 2005-03-21 1:42 UTC (permalink / raw) To: qemu-devel There is a reference here [1] to the possibility of porting the Accelerator to *BSD by porting a small "C stub". Is anyone working on this at the moment? If not, would it be possible to make the "C stub" available so that someone could give it a try? I'd be interested in taking a crack at it myself, but there may be others better situated (I've not done FreeBSD kernel development before, but I have done some Darwin kernel development). That's assuming that the reference is at all accurate :-) [1] http://www.dad-answers.com/qemu-forum/viewtopic.php?t=333 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] Accelerator for FreeBSD? 2005-03-21 1:42 [Qemu-devel] Accelerator for FreeBSD? Ryan Rempel @ 2005-03-21 4:22 ` Mikko Työläjärvi 2005-03-21 14:57 ` KQEMU on FreeBSD partially works. (Was: [Qemu-devel] Accelerator for FreeBSD?) Antony T Curtis 1 sibling, 0 replies; 6+ messages in thread From: Mikko Työläjärvi @ 2005-03-21 4:22 UTC (permalink / raw) To: Ryan Rempel, qemu-devel On Sun, 20 Mar 2005, Ryan Rempel wrote: > There is a reference here [1] to the possibility of porting the > Accelerator to *BSD by porting a small "C stub". That would be "kmod.c". > Is anyone working on this at the moment? If not, would it be possible > to make the "C stub" available so that someone could give it a try? > I'd be interested in taking a crack at it myself, but there may be > others better situated (I've not done FreeBSD kernel development > before, but I have done some Darwin kernel development). > > That's assuming that the reference is at all accurate :-) > > [1] http://www.dad-answers.com/qemu-forum/viewtopic.php?t=333 I've only seen this attempt: <http://lists.gnu.org/archive/html/qemu-devel/2005-03/msg00049.html> Which apparently needs a little more work. $.02, /Mikko ^ permalink raw reply [flat|nested] 6+ messages in thread
* KQEMU on FreeBSD partially works. (Was: [Qemu-devel] Accelerator for FreeBSD?) 2005-03-21 1:42 [Qemu-devel] Accelerator for FreeBSD? Ryan Rempel 2005-03-21 4:22 ` Mikko Työläjärvi @ 2005-03-21 14:57 ` Antony T Curtis 2005-03-23 1:27 ` Ryan Rempel 1 sibling, 1 reply; 6+ messages in thread From: Antony T Curtis @ 2005-03-21 14:57 UTC (permalink / raw) To: Ryan Rempel, qemu-devel [-- Attachment #1: Type: text/plain, Size: 1371 bytes --] On Sun, 2005-03-20 at 19:42 -0600, Ryan Rempel wrote: > There is a reference here [1] to the possibility of porting the > Accelerator to *BSD by porting a small "C stub". > > Is anyone working on this at the moment? If not, would it be possible > to make the "C stub" available so that someone could give it a try? > I'd be interested in taking a crack at it myself, but there may be > others better situated (I've not done FreeBSD kernel development > before, but I have done some Darwin kernel development). > > That's assuming that the reference is at all accurate :-) > > [1] http://www.dad-answers.com/qemu-forum/viewtopic.php?t=333 I have made some headway... The attached stub appears to work but in my limited testing so far, it may be a bit unstable. The driver stub is for FreeBSD 4 (tested on 4.9) and I may work on a 5.3+ one soon. YMMV. Use with caution... Simply copy the attached files into the same directory that the kqemu distribution is untarred and build with # make -f Makefile.bsd Install with # make -f Makefile.bsd # kldload kqemu You will need to create the /dev nodes # mknod /dev/kqemu c 250 0 root:wheel # chmod ug+rw /dev/kqemu -- Antony T Curtis, BSc. UNIX, Linux, *BSD, Networking antony.t.curtis@ntlworld.com C++, J2EE, Perl, MySQL, Apache IT Consultancy. [-- Attachment #2: Makefile.bsd --] [-- Type: text/plain, Size: 89 bytes --] # KMOD= kqemu SRCS= kqemu.h kmod_bsd.c kqemu-mod-i386.o NOMAN= .include <bsd.kmod.mk> [-- Attachment #3: kmod_bsd.c --] [-- Type: text/x-csrc, Size: 8450 bytes --] /* * FreeBSD kernel wrapper for KQEMU * Copyright (c) 2005 Antony T Curtis * * Based upon the Linux wrapper by Fabrice Bellard */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/buf.h> #include <sys/uio.h> #include <sys/conf.h> #include <sys/ctype.h> #include <sys/fcntl.h> #include <sys/malloc.h> #include <sys/proc.h> #include <sys/ioccom.h> #include <sys/signalvar.h> #include <sys/resourcevar.h> #include <vm/vm.h> #include <vm/vm_param.h> #include <vm/pmap.h> #include <vm/vm_map.h> #include <vm/vm_page.h> #include <vm/vm_kern.h> #include <vm/vm_extern.h> #include <machine/stdarg.h> #define __KERNEL__ #include "kqemu.h" static MALLOC_DEFINE(M_KQEMU, "KQEMU", "KQEMU Resources"); /* lock the page at virtual address 'user_addr' and return its page index. Return -1 if error */ unsigned long CDECL kqemu_lock_user_page(unsigned long user_addr) { int rc; caddr_t addr = (caddr_t) user_addr; vm_page_t m; vm_offset_t paddr; /*kqemu_log("kqemu_lock_user_page(0x%08x)\n", addr);*/ rc = vm_fault_quick(addr, VM_PROT_READ|VM_PROT_WRITE); if (rc < 0) { /*kqemu_log("vm_fault_quick failed rc=%d\n",rc);*/ return -1; } paddr = vtophys(addr); m = PHYS_TO_VM_PAGE(paddr); vm_page_wire(m); return (long)(paddr >> PAGE_SHIFT); } void CDECL kqemu_unlock_user_page(unsigned long page_index) { vm_page_t m; vm_offset_t paddr; /*kqemu_log("kqemu_unlock_user_page(0x%08x)\n",page_index);*/ paddr = (vm_offset_t)(page_index << PAGE_SHIFT); m = PHYS_TO_VM_PAGE(paddr); vm_page_unwire(m, 1); } unsigned long CDECL kqemu_alloc_zeroed_page(void) { void *addr; /*kqemu_log("kqemu_alloc_zeroed_page()\n");*/ addr = contigmalloc(PAGE_SIZE, M_KQEMU, M_WAITOK, 0, ~0ul, PAGE_SIZE, 0); if (!addr) { /*kqemu_log("contigmalloc failed\n");*/ return -1; } memset(addr, 0, PAGE_SIZE); return ((long) addr) >> PAGE_SHIFT; } void CDECL kqemu_free_page(unsigned long page_index) { /*kqemu_log("kqemu_free_page(0x%08x)\n", page_index);*/ contigfree((void *)(page_index << PAGE_SHIFT), PAGE_SIZE, M_KQEMU); } void * CDECL kqemu_page_kaddr(unsigned long page_index) { caddr_t addr; /*kqemu_log("kqemu_page_kaddr(0x%08x)\n", page_index);*/ addr = (caddr_t)(page_index << PAGE_SHIFT); return (void *)addr; } /* contraint: each page of the vmalloced area must be in the first 4 GB of physical memory */ void * CDECL kqemu_vmalloc(unsigned int size) { /*kqemu_log("kqemu_vmalloc(0x%08x)\n", size);*/ return malloc(size, M_KQEMU, M_WAITOK); } void CDECL kqemu_vfree(void *ptr) { /*kqemu_log("kqemu_vfree(0x%08x)\n", ptr);*/ return free(ptr, M_KQEMU); } unsigned long CDECL kqemu_vmalloc_to_phys(const void *vaddr) { vm_offset_t paddr = (vm_offset_t)vaddr; return (long)(paddr >> PAGE_SHIFT); } static int curpriority_cmp(struct proc *p) { int c_class, p_class; c_class = RTP_PRIO_BASE(curproc->p_rtprio.type); p_class = RTP_PRIO_BASE(p->p_rtprio.type); if (p_class != c_class) return (p_class - c_class); if (p_class == RTP_PRIO_NORMAL) return (((int)p->p_priority - (int)curpriority) / PPQ); return ((int)p->p_rtprio.prio - (int)curproc->p_rtprio.prio); } /* return TRUE if a signal is pending (i.e. the guest must stop execution) */ int CDECL kqemu_schedule(void) { struct proc *p = curproc; if (curpriority_cmp(p) > 0) { int s = splhigh(); p->p_priority = MAXPRI; setrunqueue(p); p->p_stats->p_ru.ru_nvcsw++; mi_switch(); splx(s); } return issignal(curproc) != 0; } static 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); printf("kqemu: %s", log_buf); va_end(ap); } /*********************************************************/ #define KQEMU_MAX_INSTANCES 4 struct kqemu_instance { struct kqemu_state *state; }; static int kqemu_ref_count = 0; static int max_locked_pages; static dev_t kqemu_dev; static d_open_t kqemu_open; static d_close_t kqemu_close; static d_ioctl_t kqemu_ioctl; static struct cdevsw kqemu_cdevsw = { /* open */ kqemu_open, /* close */ kqemu_close, /* read */ noread, /* write */ nowrite, /* ioctl */ kqemu_ioctl, /* poll */ nopoll, /* mmap */ nommap, /* strategy */ nostrategy, /* name */ "kqemu", /* maj */ KQEMU_MAJOR, /* dump */ nodump, /* psize */ nopsize, /* flags */ 0, /* bmaj */ -1 }; int kqemu_open(dev, flags, fmt, p) dev_t dev; int flags, fmt; struct proc *p; { struct kqemu_instance *ks; if (dev->si_drv1 || kqemu_ref_count >= KQEMU_MAX_INSTANCES) return(EBUSY); if ((flags & (FREAD|FWRITE)) == FREAD) return(EPERM); ks = (struct kqemu_instance *) malloc(sizeof(*ks), M_KQEMU, M_WAITOK); if (ks == NULL) return(ENOMEM); memset(ks, 0, sizeof *ks); dev->si_drv1 = ks; kqemu_ref_count++; kqemu_log("opened by pid=%d\n", p->p_pid); return(0); } int kqemu_close(dev, flags, fmt, p) dev_t dev; int flags, fmt; struct proc *p; { struct kqemu_instance *ks = (struct kqemu_instance *) dev->si_drv1; if (ks->state) { kqemu_delete(ks->state); ks->state = NULL; } free(ks, M_KQEMU); dev->si_drv1 = NULL; kqemu_ref_count--; kqemu_log("closed by pid=%d\n", p->p_pid); return(0); } int kqemu_ioctl(dev, cmd, cmdarg, flags, p) dev_t dev; unsigned long cmd; caddr_t cmdarg; int flags; struct proc *p; { struct kqemu_instance *ks = (struct kqemu_instance *) dev->si_drv1; struct kqemu_state *s = ks->state; long ret; /*int error;*/ switch (cmd) { case KQEMU_INIT: /*kqemu_log("KQEMU_INIT data=0x%08x\n",cmdarg);*/ { if (s) return(EIO); if (!(s = kqemu_init((struct kqemu_init *)cmdarg, max_locked_pages))) return(ENOMEM); ks->state = s; ret = 0; break; } case KQEMU_EXEC: /*kqemu_log("KQEMU_EXEC data=0x%08x\n",cmdarg);*/ { struct kqemu_cpu_state *ctx; if (!s) return(EIO); ctx = kqemu_get_cpu_state(s); memcpy((void *)ctx, (void *)cmdarg, sizeof(struct kqemu_cpu_state)); ret = kqemu_exec(s); memcpy((void *)cmdarg, (void *)ctx, sizeof(struct kqemu_cpu_state)); break; } case KQEMU_GET_VERSION: /*kqemu_log("KQEMU_GET_VERSION data=0x%08x\n",cmdarg);*/ { *(int *)cmdarg = KQEMU_VERSION; ret = 0; break; } default: /*kqemu_log("ioctl unknown 0x%08x\n",cmd);*/ return(ENXIO); } return(ret); } static int init_module(void) { int rc; printf("QEMU Accelerator Module version %d.%d.%d, Copyright (c) 2005 Fabrice Bellard\n" "FreeBSD wrapper port, Copyright (c) 2005 Antony T Curtis\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); max_locked_pages = physmem / (2 * KQEMU_MAX_INSTANCES); if (max_locked_pages > 32768) max_locked_pages = 32768; if ((rc = cdevsw_add(&kqemu_cdevsw))) { kqemu_log("error registering cdevsw, rc=%d\n", rc); return(ENOENT); } kqemu_dev = make_dev(&kqemu_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "kqemu"); kqemu_log("KQEMU installed, max_instances=%d max_locked_mem=%dkB.\n", KQEMU_MAX_INSTANCES, max_locked_pages * 4); kqemu_ref_count = 0; return 0; } static void cleanup_module(void) { int rc; destroy_dev(kqemu_dev); if ((rc = cdevsw_remove(&kqemu_cdevsw))) kqemu_log("error unregistering, rc=%d\n", rc); } static int kqemu_modevent(module_t mod, int type, void *data) { int err = 0; switch (type) { case MOD_LOAD: err = init_module(); break; case MOD_UNLOAD: if (kqemu_ref_count > 0) { err = EBUSY; break; } /* fall through */ case MOD_SHUTDOWN: cleanup_module(); break; default: err = EINVAL; break; } return(err); } static moduledata_t kqemu_mod = { "kqemu_driver", kqemu_modevent, NULL }; DECLARE_MODULE(kqemu, kqemu_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: KQEMU on FreeBSD partially works. (Was: [Qemu-devel] Accelerator for FreeBSD?) 2005-03-21 14:57 ` KQEMU on FreeBSD partially works. (Was: [Qemu-devel] Accelerator for FreeBSD?) Antony T Curtis @ 2005-03-23 1:27 ` Ryan Rempel 2005-03-23 12:15 ` Antony T Curtis 2005-03-23 13:58 ` Antony T Curtis 0 siblings, 2 replies; 6+ messages in thread From: Ryan Rempel @ 2005-03-23 1:27 UTC (permalink / raw) To: Antony T Curtis; +Cc: qemu-devel On Mon, 21 Mar 2005 14:57:33 +0000, Antony T Curtis <antony.t.curtis@ntlworld.com> wrote: > On Sun, 2005-03-20 at 19:42 -0600, Ryan Rempel wrote: > > There is a reference here [1] to the possibility of porting the > > Accelerator to *BSD by porting a small "C stub". > > > > Is anyone working on this at the moment? > I have made some headway... The attached stub appears to work but in my > limited testing so far, it may be a bit unstable. The driver stub is for > FreeBSD 4 (tested on 4.9) and I may work on a 5.3+ one soon. Thanks! I would need one that works with 5.3 -- I'll take a look when I get a chance and see what I can figure out. When you say "a bit unstable", do you mean unstable for the guest OS or unstable for the host as well? Just curious ... ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: KQEMU on FreeBSD partially works. (Was: [Qemu-devel] Accelerator for FreeBSD?) 2005-03-23 1:27 ` Ryan Rempel @ 2005-03-23 12:15 ` Antony T Curtis 2005-03-23 13:58 ` Antony T Curtis 1 sibling, 0 replies; 6+ messages in thread From: Antony T Curtis @ 2005-03-23 12:15 UTC (permalink / raw) To: Ryan Rempel; +Cc: qemu-devel On Tue, 2005-03-22 at 19:27 -0600, Ryan Rempel wrote: > On Mon, 21 Mar 2005 14:57:33 +0000, Antony T Curtis > <antony.t.curtis@ntlworld.com> wrote: > > > On Sun, 2005-03-20 at 19:42 -0600, Ryan Rempel wrote: > > > There is a reference here [1] to the possibility of porting the > > > Accelerator to *BSD by porting a small "C stub". > > > > > > Is anyone working on this at the moment? > > > I have made some headway... The attached stub appears to work but in my > > limited testing so far, it may be a bit unstable. The driver stub is for > > FreeBSD 4 (tested on 4.9) and I may work on a 5.3+ one soon. > > Thanks! I would need one that works with 5.3 -- I'll take a look when > I get a chance and see what I can figure out. > > When you say "a bit unstable", do you mean unstable for the guest OS > or unstable for the host as well? Just curious ... Unstable for the host - but since I am using a fairly old FreeBSD, it could be partly to blame. I'll need to see if it misbehaves as much on 4-STABLE. It seems to work fine, until the guest tries to change video mode (going from text to graphics) - this behaviour happens with Windows, Linux and OS/2 as guest - at which time, the host experiences a sudden reset. I have FreeBSD 5 which I will get up to date and then try out... I am also going to try setting up the guest as a text-only setup and use xdm... -- Antony T Curtis, BSc. UNIX, Linux, *BSD, Networking antony.t.curtis@ntlworld.com C++, J2EE, Perl, MySQL, Apache IT Consultancy. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: KQEMU on FreeBSD partially works. (Was: [Qemu-devel] Accelerator for FreeBSD?) 2005-03-23 1:27 ` Ryan Rempel 2005-03-23 12:15 ` Antony T Curtis @ 2005-03-23 13:58 ` Antony T Curtis 1 sibling, 0 replies; 6+ messages in thread From: Antony T Curtis @ 2005-03-23 13:58 UTC (permalink / raw) To: Ryan Rempel; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 1028 bytes --] On Tue, 2005-03-22 at 19:27 -0600, Ryan Rempel wrote: > On Mon, 21 Mar 2005 14:57:33 +0000, Antony T Curtis > <antony.t.curtis@ntlworld.com> wrote: > > > On Sun, 2005-03-20 at 19:42 -0600, Ryan Rempel wrote: > > > There is a reference here [1] to the possibility of porting the > > > Accelerator to *BSD by porting a small "C stub". > > > > > > Is anyone working on this at the moment? > > > I have made some headway... The attached stub appears to work but in my > > limited testing so far, it may be a bit unstable. The driver stub is for > > FreeBSD 4 (tested on 4.9) and I may work on a 5.3+ one soon. > > Thanks! I would need one that works with 5.3 -- I'll take a look when > I get a chance and see what I can figure out. Okay - the new files compile on both 4.9 and 5.3, currently untested on 5.3. YMMV. Enjoy! -- Antony T Curtis, BSc. UNIX, Linux, *BSD, Networking antony.t.curtis@ntlworld.com C++, J2EE, Perl, MySQL, Apache IT Consultancy. [-- Attachment #2: Makefile.bsd --] [-- Type: text/plain, Size: 89 bytes --] # KMOD= kqemu SRCS= kqemu.h kmod_bsd.c kqemu-mod-i386.o NOMAN= .include <bsd.kmod.mk> [-- Attachment #3: kmod_bsd.c --] [-- Type: text/x-csrc, Size: 9898 bytes --] /* * FreeBSD kernel wrapper for KQEMU * Copyright (c) 2005 Antony T Curtis * * Based upon the Linux wrapper by Fabrice Bellard */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #if __FreeBSD_version < 500000 #include <sys/buf.h> #endif #include <sys/uio.h> #include <sys/conf.h> #include <sys/ctype.h> #include <sys/fcntl.h> #include <sys/malloc.h> #include <sys/proc.h> #include <sys/ioccom.h> #include <sys/signalvar.h> #include <sys/resourcevar.h> #include <sys/module.h> #include <vm/vm.h> #include <vm/vm_param.h> #include <vm/pmap.h> #include <vm/vm_map.h> #include <vm/vm_page.h> #include <vm/vm_kern.h> #include <vm/vm_extern.h> #include <machine/stdarg.h> #define __KERNEL__ #include "kqemu.h" static MALLOC_DEFINE(M_KQEMU, "KQEMU", "KQEMU Resources"); /* lock the page at virtual address 'user_addr' and return its page index. Return -1 if error */ unsigned long CDECL kqemu_lock_user_page(unsigned long user_addr) { int rc; caddr_t addr = (caddr_t) user_addr; vm_page_t m; vm_offset_t paddr; /*kqemu_log("kqemu_lock_user_page(0x%08x)\n", addr);*/ rc = vm_fault_quick(addr, VM_PROT_READ|VM_PROT_WRITE); if (rc < 0) { /*kqemu_log("vm_fault_quick failed rc=%d\n",rc);*/ return -1; } paddr = vtophys(addr); m = PHYS_TO_VM_PAGE(paddr); vm_page_wire(m); return (long)(paddr >> PAGE_SHIFT); } void CDECL kqemu_unlock_user_page(unsigned long page_index) { vm_page_t m; vm_offset_t paddr; /*kqemu_log("kqemu_unlock_user_page(0x%08x)\n",page_index);*/ paddr = (vm_offset_t)(page_index << PAGE_SHIFT); m = PHYS_TO_VM_PAGE(paddr); vm_page_unwire(m, 1); } unsigned long CDECL kqemu_alloc_zeroed_page(void) { void *addr; /*kqemu_log("kqemu_alloc_zeroed_page()\n");*/ addr = contigmalloc(PAGE_SIZE, M_KQEMU, M_WAITOK, 0, ~0ul, PAGE_SIZE, 0); if (!addr) { /*kqemu_log("contigmalloc failed\n");*/ return -1; } memset(addr, 0, PAGE_SIZE); return ((long) addr) >> PAGE_SHIFT; } void CDECL kqemu_free_page(unsigned long page_index) { /*kqemu_log("kqemu_free_page(0x%08x)\n", page_index);*/ contigfree((void *)(page_index << PAGE_SHIFT), PAGE_SIZE, M_KQEMU); } void * CDECL kqemu_page_kaddr(unsigned long page_index) { caddr_t addr; /*kqemu_log("kqemu_page_kaddr(0x%08x)\n", page_index);*/ addr = (caddr_t)(page_index << PAGE_SHIFT); return (void *)addr; } /* contraint: each page of the vmalloced area must be in the first 4 GB of physical memory */ void * CDECL kqemu_vmalloc(unsigned int size) { /*kqemu_log("kqemu_vmalloc(0x%08x)\n", size);*/ return malloc(size, M_KQEMU, M_WAITOK); } void CDECL kqemu_vfree(void *ptr) { /*kqemu_log("kqemu_vfree(0x%08x)\n", ptr);*/ return free(ptr, M_KQEMU); } unsigned long CDECL kqemu_vmalloc_to_phys(const void *vaddr) { vm_offset_t paddr = (vm_offset_t)vaddr; return (long)(paddr >> PAGE_SHIFT); } #if __FreeBSD_version < 500000 static int curpriority_cmp(struct proc *p) { int c_class, p_class; c_class = RTP_PRIO_BASE(curproc->p_rtprio.type); p_class = RTP_PRIO_BASE(p->p_rtprio.type); if (p_class != c_class) return (p_class - c_class); if (p_class == RTP_PRIO_NORMAL) return (((int)p->p_priority - (int)curpriority) / PPQ); return ((int)p->p_rtprio.prio - (int)curproc->p_rtprio.prio); } /* return TRUE if a signal is pending (i.e. the guest must stop execution) */ int CDECL kqemu_schedule(void) { struct proc *p = curproc; if (curpriority_cmp(p) > 0) { int s = splhigh(); p->p_priority = MAXPRI; setrunqueue(p); p->p_stats->p_ru.ru_nvcsw++; mi_switch(); splx(s); } return issignal(curproc) != 0; } #else /* return TRUE if a signal is pending (i.e. the guest must stop execution) */ int CDECL kqemu_schedule(void) { struct thread *td = curthread; struct proc *p = td->td_proc; int rc = 0, sig; PROC_LOCK(p); mtx_lock(&p->p_sigacts->ps_mtx); if ((rc = ((sig= cursig(td)) != 0))) { do { postsig(sig); } while ((sig= cursig(td))); } mtx_unlock(&p->p_sigacts->ps_mtx); PROC_UNLOCK(p); return rc; } #endif static 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); printf("kqemu: %s", log_buf); va_end(ap); } /*********************************************************/ #define KQEMU_MAX_INSTANCES 4 struct kqemu_instance { struct kqemu_state *state; }; static int kqemu_ref_count = 0; static int max_locked_pages; #if __FreeBSD_version < 500000 static dev_t kqemu_dev; #else static struct cdev *kqemu_dev; #endif static d_open_t kqemu_open; static d_close_t kqemu_close; static d_ioctl_t kqemu_ioctl; static struct cdevsw kqemu_cdevsw = { #if __FreeBSD_version < 500000 /* open */ kqemu_open, /* close */ kqemu_close, /* read */ noread, /* write */ nowrite, /* ioctl */ kqemu_ioctl, /* poll */ nopoll, /* mmap */ nommap, /* strategy */ nostrategy, /* name */ "kqemu", /* maj */ KQEMU_MAJOR, /* dump */ nodump, /* psize */ nopsize, /* flags */ 0, /* bmaj */ -1 #else .d_version = D_VERSION, .d_open = kqemu_open, .d_close = kqemu_close, .d_ioctl = kqemu_ioctl, .d_name = "kqemu", #endif }; int #if __FreeBSD_version < 500000 kqemu_open(dev, flags, fmt, p) dev_t dev; int flags, fmt; struct proc *p; { #else kqemu_open(dev, flags, fmt, td) struct cdev *dev; int flags, fmt; struct thread *td; { struct proc *p = td->td_proc; #endif struct kqemu_instance *ks; if (dev->si_drv1 || kqemu_ref_count >= KQEMU_MAX_INSTANCES) return(EBUSY); if ((flags & (FREAD|FWRITE)) == FREAD) return(EPERM); ks = (struct kqemu_instance *) malloc(sizeof(*ks), M_KQEMU, M_WAITOK); if (ks == NULL) return(ENOMEM); memset(ks, 0, sizeof *ks); dev->si_drv1 = ks; kqemu_ref_count++; kqemu_log("opened by pid=%d\n", p->p_pid); return(0); } int #if __FreeBSD_version < 500000 kqemu_close(dev, flags, fmt, p) dev_t dev; int flags, fmt; struct proc *p; { #else kqemu_close(dev, flags, fmt, td) struct cdev *dev; int flags, fmt; struct thread *td; { struct proc *p = td->td_proc; #endif struct kqemu_instance *ks = (struct kqemu_instance *) dev->si_drv1; if (ks->state) { kqemu_delete(ks->state); ks->state = NULL; } free(ks, M_KQEMU); dev->si_drv1 = NULL; kqemu_ref_count--; kqemu_log("closed by pid=%d\n", p->p_pid); return(0); } int #if __FreeBSD_version < 500000 kqemu_ioctl(dev, cmd, cmdarg, flags, p) dev_t dev; unsigned long cmd; caddr_t cmdarg; int flags; struct proc *p; { #else kqemu_ioctl(dev, cmd, cmdarg, flags, td) struct cdev *dev; unsigned long cmd; caddr_t cmdarg; int flags; struct thread *td; { #endif struct kqemu_instance *ks = (struct kqemu_instance *) dev->si_drv1; struct kqemu_state *s = ks->state; long ret; /*int error;*/ switch (cmd) { case KQEMU_INIT: /*kqemu_log("KQEMU_INIT data=0x%08x\n",cmdarg);*/ { if (s) return(EIO); if (!(s = kqemu_init((struct kqemu_init *)cmdarg, max_locked_pages))) return(ENOMEM); ks->state = s; ret = 0; break; } case KQEMU_EXEC: /*kqemu_log("KQEMU_EXEC data=0x%08x\n",cmdarg);*/ { struct kqemu_cpu_state *ctx; if (!s) return(EIO); ctx = kqemu_get_cpu_state(s); memcpy((void *)ctx, (void *)cmdarg, sizeof(struct kqemu_cpu_state)); ret = kqemu_exec(s); memcpy((void *)cmdarg, (void *)ctx, sizeof(struct kqemu_cpu_state)); break; } case KQEMU_GET_VERSION: /*kqemu_log("KQEMU_GET_VERSION data=0x%08x\n",cmdarg);*/ { *(int *)cmdarg = KQEMU_VERSION; ret = 0; break; } default: /*kqemu_log("ioctl unknown 0x%08x\n",cmd);*/ return(ENXIO); } return(ret); } static int init_module(void) { #if __FreeBSD_version < 500000 int rc; #endif printf("QEMU Accelerator Module version %d.%d.%d, Copyright (c) 2005 Fabrice Bellard\n" "FreeBSD wrapper port, Copyright (c) 2005 Antony T Curtis\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); max_locked_pages = physmem / (2 * KQEMU_MAX_INSTANCES); if (max_locked_pages > 32768) max_locked_pages = 32768; #if __FreeBSD_version < 500000 if ((rc = cdevsw_add(&kqemu_cdevsw))) { kqemu_log("error registering cdevsw, rc=%d\n", rc); return(ENOENT); } #endif kqemu_dev = make_dev(&kqemu_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "kqemu"); kqemu_log("KQEMU installed, max_instances=%d max_locked_mem=%dkB.\n", KQEMU_MAX_INSTANCES, max_locked_pages * 4); kqemu_ref_count = 0; return 0; } static void cleanup_module(void) { #if __FreeBSD_version < 500000 int rc; #endif destroy_dev(kqemu_dev); #if __FreeBSD_version < 500000 if ((rc = cdevsw_remove(&kqemu_cdevsw))) kqemu_log("error unregistering, rc=%d\n", rc); #endif } static int kqemu_modevent(module_t mod, int type, void *data) { int err = 0; switch (type) { case MOD_LOAD: err = init_module(); break; case MOD_UNLOAD: if (kqemu_ref_count > 0) { err = EBUSY; break; } /* fall through */ case MOD_SHUTDOWN: cleanup_module(); break; default: err = EINVAL; break; } return(err); } static moduledata_t kqemu_mod = { "kqemu_driver", kqemu_modevent, NULL }; DECLARE_MODULE(kqemu, kqemu_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2005-03-23 14:19 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-03-21 1:42 [Qemu-devel] Accelerator for FreeBSD? Ryan Rempel 2005-03-21 4:22 ` Mikko Työläjärvi 2005-03-21 14:57 ` KQEMU on FreeBSD partially works. (Was: [Qemu-devel] Accelerator for FreeBSD?) Antony T Curtis 2005-03-23 1:27 ` Ryan Rempel 2005-03-23 12:15 ` Antony T Curtis 2005-03-23 13:58 ` Antony T Curtis
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).