Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 10 Sep 2005 18:45:38 +0200 (CEST)
From:      Juergen Lock <nox@jelal.kn-bremen.de>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/85947: update emulators/qemu to 20050909 snapshot
Message-ID:  <200509101645.j8AGjcOe033388@saturn.kn-bremen.de>
Resent-Message-ID: <200509101650.j8AGoBNO002730@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         85947
>Category:       ports
>Synopsis:       update emulators/qemu to 20050909 snapshot
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          maintainer-update
>Submitter-Id:   current-users
>Arrival-Date:   Sat Sep 10 16:50:11 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Juergen Lock
>Release:        FreeBSD 5.4-RELEASE-p6 amd64
>Organization:
me?  organized??
>Environment:
System: FreeBSD titan 5.4-RELEASE-p6 FreeBSD 5.4-RELEASE-p6 #1: Thu Aug 11 15:07:07 CEST 2005     nox@titan:/usr/home/nox/usrsrc/src/sys/amd64/compile/TITAN  amd64


>Description:

- kqemu device cloning support on >= 5.x, 4.x merge (I got no failure
reports in several weeks so i assume it is working :), max_locked_pages
calculation
- moved kqemu debug messages under debug.kqemu_debug sysctl
(do `sysctl debug.kqemu_debug=1' to enable)
- added kqemu free fns, allocate kernel memory in kqemu_vmalloc
- added notes about net.link.tap.user_open sysctl and about PREEMPTION
problems with >= 6.x guests

fixed VIA irq register access, sparc64 fixes (Blue Swirl),
x86_64 fixes (initial patch by Filip Navara), prevent window resizing,
IOAPIC support (initial patch by Filip Navara), added overflow
exceptions in divisions, EXTINT delivery mode support for I/O APIC
(Filip Navara), open OSS audio device as write only (malc),
64 bit virtual addressing fix, allow more than 32 bit of physical memory,
fscale fix (bug noticed by Kuwanger, fix by malc), do not export fls_bit,
monitor kqemu info, ide PCI ident fix, aka FreeBSD/amd64 bug fix
(Jung-uk Kim), CLFLUSH cpuid fix (aka Linux 2.6 hang on x86_64),
16/32 stack operations fix on x86_64 (aka win2000 startup bug),
merge self modifying code handling in dirty ram page mecanism,
kqemu fixes - new API support, kqemu profiling, RSP update fix for
x86_64 in iret, Fix MIPS counter / compare interrupt (Ralf Baechle),
Add i8259 PIT to MIPS (Ralf Baechle), Fix interrupt masking
(Ralf Baechle), CR4.TSD flag support (Matt Schulkind),
TSS error code push fix (malc), dirty ram page handling fixes,
kqemu_set_notdirty() opt, improved user net performances,
avoid losing chars in serial console, SYSENTER fix for x86_64 CPUs,
kqemu_enabled test, disabled LDT test (kqemu 0.7.2 no longer needs it),
div64 fix (aka ssh bug)

>How-To-Repeat:
	n/a
>Fix:

Removed files: files/BSDmakefile files/kmod_bsd.c
New files: files/kqemu-freebsd-patch files/patch-libmath2
	files/patch-vl.c

Index: Makefile
===================================================================
RCS file: /home/ncvs/ports/emulators/qemu/Makefile,v
retrieving revision 1.27
diff -u -r1.27 Makefile
--- Makefile	19 Jul 2005 06:06:56 -0000	1.27
+++ Makefile	10 Sep 2005 16:15:55 -0000
@@ -6,12 +6,12 @@
 #
 
 PORTNAME=	qemu
-PORTVERSION=	0.7.0s.20050717
+PORTVERSION=	0.7.2s.20050909
 CATEGORIES=	emulators
 MASTER_SITES=	http://www.qemu.org/ \
 		http://people.fruitsalad.org/nox/qemu/ \
 		http://dad-answers.com/qemu/
-DISTNAME=	${PORTNAME}-snapshot-2005-07-17_23
+DISTNAME=	${PORTNAME}-snapshot-2005-09-09_23
 EXTRACT_ONLY=	${DISTNAME}${EXTRACT_SUFX}
 
 MAINTAINER=	nox@jelal.kn-bremen.de
@@ -23,8 +23,9 @@
 .endif
 
 .if defined(WITH_KQEMU)
-DISTKQEMU=	kqemu-0.6.2-1.tar.gz
+DISTKQEMU=	kqemu-0.7.2.tar.gz
 DISTFILES=	${EXTRACT_ONLY} ${DISTKQEMU}
+EXTRA_PATCHES=	${FILESDIR}/kqemu-freebsd-patch
 .endif
 
 HAS_CONFIGURE=	yes
@@ -40,9 +41,11 @@
 ONLY_FOR_ARCHS=	amd64 i386
 .if defined(WITH_KQEMU)
 NO_PACKAGE=	Depends on kernel, and module not redistributable
+CONFIGURE_ARGS+=	--enable-kqemu
 PLIST_SUB=	WITH_KQEMU=""
 PLIST_SUB+=	KMODDIR=${KMODDIR}
 .else
+CONFIGURE_ARGS+=	--disable-kqemu
 PLIST_SUB=	WITH_KQEMU="@comment "
 .endif
 
@@ -52,7 +55,7 @@
 
 .if ${ARCH} == "amd64"
 ARCH=		x86_64
-.if ${OSVERSION} >= 502126
+.if ${OSVERSION} >= 502126 && ${OSVERSION} <= 600029
 BUILD_DEPENDS+=	gcc34:${PORTSDIR}/lang/gcc34
 GCCVERSION=	030402
 CC=		gcc34
@@ -63,16 +66,12 @@
 USE_GCC=	3.4
 .endif
 
-.if defined(WITH_KQEMU) && ${ARCH} != "i386"
-IGNORE=		kqemu only supported on i386
-.endif
-
 .if defined(WITH_KQEMU) && !exists(${SRC_BASE}/sys/Makefile)
 IGNORE=		kqemu requires kernel source to be installed
 .endif
 
 pre-everything::
-.if !defined(WITH_KQEMU) && ${ARCH} == "i386"
+.if !defined(WITH_KQEMU)
 	@${ECHO_MSG} "Notice: you can build qemu with the (alpha!) kqemu accelerator kernel module"
 	@${ECHO_MSG} "by defining WITH_KQEMU."
 .endif
@@ -85,7 +84,7 @@
 .if defined(WITH_KQEMU)
 post-extract:
 	@cd ${WRKSRC} && ${TAR} xfz ${_DISTDIR}/${DISTKQEMU}
-	@${CP} ${FILESDIR}/BSDmakefile ${FILESDIR}/kmod_bsd.c ${WRKSRC}/kqemu
+	@${LN} -s Makefile.freebsd ${WRKSRC}/kqemu/BSDmakefile
 .endif
 
 pre-patch:
Index: distinfo
===================================================================
RCS file: /home/ncvs/ports/emulators/qemu/distinfo,v
retrieving revision 1.20
diff -u -r1.20 distinfo
--- distinfo	19 Jul 2005 06:06:56 -0000	1.20
+++ distinfo	10 Sep 2005 16:16:39 -0000
@@ -1,4 +1,4 @@
-MD5 (qemu-snapshot-2005-07-17_23.tar.bz2) = 5d21295c1f328ea00de19a54715ee7c3
-SIZE (qemu-snapshot-2005-07-17_23.tar.bz2) = 1114748
-MD5 (kqemu-0.6.2-1.tar.gz) = c6bb3b40fb3d526d731eb0f1f9dee7ee
-SIZE (kqemu-0.6.2-1.tar.gz) = 21002
+MD5 (qemu-snapshot-2005-09-09_23.tar.bz2) = db4ffeb081666c7352f5c0231e3f09c7
+SIZE (qemu-snapshot-2005-09-09_23.tar.bz2) = 1122120
+MD5 (kqemu-0.7.2.tar.gz) = 02cfdecda90458d6393781496ec6b48b
+SIZE (kqemu-0.7.2.tar.gz) = 79314
Index: pkg-message
===================================================================
RCS file: /home/ncvs/ports/emulators/qemu/pkg-message,v
retrieving revision 1.8
diff -u -r1.8 pkg-message
--- pkg-message	1 May 2005 07:39:10 -0000	1.8
+++ pkg-message	6 Sep 2005 18:23:22 -0000
@@ -1,6 +1,9 @@
 ====
 FreeBSD host notes:
 - needs to run as root in order to use /dev/tap* networking (why?)
+(actually RELENG_6 and above now has a sysctl net.link.tap.user_open
+to allow users to use it too.  don't forget to adjust device node
+permissions in /etc/devfs.rules.)
 - slirp (usermode networking) is fixed now in cvs, on FreeSBIE 1.0 guests
 you still have to manually do:
 	echo nameserver 10.0.2.3 >/etc/resolv.conf
@@ -18,4 +21,9 @@
 ioctl.)
 - the -smb option (smb-export local dir to guest) needs the net/samba
 port/package installed in addition to qemu.
+- RELENG_6 and up guests often crash while accessing the emulated cdrom
+(see kern/84102, http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/84102),
+using a kernel without PREEMPTION has been reported to fix this problem.
+(or do an ftp install instead of installing from the emulated cdrom, and
+then make a new kernel.)
 ====
Index: files/patch-fbsd
===================================================================
RCS file: /home/ncvs/ports/emulators/qemu/files/patch-fbsd,v
retrieving revision 1.2
diff -u -r1.2 patch-fbsd
--- files/patch-fbsd	5 May 2005 12:41:10 -0000	1.2
+++ files/patch-fbsd	11 Aug 2005 16:38:42 -0000
@@ -13,7 +13,7 @@
  	$(MAKE) -C kqemu -f Makefile.winnt
  else
 -	$(MAKE) -C kqemu
-+	cd kqemu && $(BSD_MAKE)
++	( cd kqemu && $(BSD_MAKE) )
  endif
  endif
  
Index: files/kqemu-freebsd-patch
@@ -0,0 +1,506 @@
+Index: qemu/kqemu/Makefile.freebsd
+@@ -1,9 +1,13 @@
++# $Id: Makefile.freebsd,v 1.1 2005/04/17 17:21:31 bellard Exp $
+ KMOD=	kqemu
+ SRCS=	kqemu-freebsd.c
+ .if ${MACHINE_ARCH} == "i386"
+ OBJS=	kqemu-mod-i386.o
+ .elif ${MACHINE_ARCH} == "amd64"
+ OBJS=	kqemu-mod-x86_64.o
++.endif
++.if ${OSVERSION} >= 500000
++CC=	cc
+ .endif
+ WERROR=
+ 
+Index: qemu/kqemu/kqemu-freebsd.c
+@@ -3,20 +3,33 @@
+ #include <sys/param.h>
+ #include <sys/systm.h>
+ #include <sys/conf.h>
++#include <sys/ctype.h>
++#include <sys/fcntl.h>
+ #include <sys/ioccom.h>
+ #include <sys/malloc.h>
+ #include <sys/module.h>
+ #include <sys/mutex.h>
+ #include <sys/proc.h>
++#include <sys/resourcevar.h>
++#if __FreeBSD_version >= 500000
+ #include <sys/sched.h>
++#endif
+ #include <sys/signalvar.h>
+ #include <sys/kernel.h>
++#include <sys/sysctl.h>
++#include <sys/uio.h>
++#if __FreeBSD_version < 500000
++#include <sys/buf.h>
++#endif
++
+ #include <vm/vm.h>
+ #include <vm/vm_param.h>
+ #include <vm/vm_extern.h>
+ #include <vm/pmap.h>
+ #include <vm/vm_map.h>
+ #include <vm/vm_kern.h>
++#include <vm/vm_page.h>
++
+ #include <machine/vmparam.h>
+ #include <machine/stdarg.h>
+ 
+@@ -25,10 +38,14 @@
+ MALLOC_DECLARE(M_KQEMU);
+ MALLOC_DEFINE(M_KQEMU, "kqemu", "kqemu buffers");
+ 
++int kqemu_debug;
++SYSCTL_INT(_debug, OID_AUTO, kqemu_debug, CTLFLAG_RW, &kqemu_debug, 0,
++        "kqemu debug flag");
++
+ #define	USER_BASE	0x1000
+ 
+ /* lock the page at virtual address 'user_addr' and return its
+-   physical page index. Return -1 if error */
++   physical page index. Return NULL if error */
+ struct kqemu_user_page *CDECL kqemu_lock_user_page(unsigned long *ppage_index,
+                                                    unsigned long user_addr)
+ {
+@@ -37,14 +54,18 @@
+     vm_paddr_t pa = 0;
+     int ret;
+     pmap_t pmap;
++#if __FreeBSD_version >= 500000
+     ret = vm_map_wire(&vm->vm_map, va, va+PAGE_SIZE, VM_MAP_WIRE_USER);
++#else
++    ret = vm_map_user_pageable(&vm->vm_map, va, va+PAGE_SIZE, FALSE);
++#endif
+     if (ret != KERN_SUCCESS) {
+-	printf("kqemu_lock_user_page(%08lx) failed, ret=%d\n", user_addr, ret);
++	kqemu_log("kqemu_lock_user_page(%08lx) failed, ret=%d\n", user_addr, ret);
+ 	return NULL;
+     }
+     pmap = vm_map_pmap(&vm->vm_map);
+     pa = pmap_extract(pmap, va);
+-    // printf("kqemu_lock_user_page(%08lx) va=%08x pa=%08x\n", user_addr, va, pa);
++    // kqemu_log("kqemu_lock_user_page(%08lx) va=%08x pa=%08x\n", user_addr, va, pa);
+     *ppage_index = pa >> PAGE_SHIFT;
+     return (struct kqemu_user_page *)va;
+ }
+@@ -54,12 +75,16 @@
+     struct vmspace *vm = curproc->p_vmspace;
+     vm_offset_t va;
+     int ret;
+-    // printf("kqemu_unlock_user_page(%08lx)\n", page_index);
++    // kqemu_log("kqemu_unlock_user_page(%08lx)\n", page_index);
+     va = (vm_offset_t)page;
++#if __FreeBSD_version >= 500000
+     ret = vm_map_unwire(&vm->vm_map, va, va+PAGE_SIZE, VM_MAP_WIRE_USER);
++#else
++    ret = vm_map_user_pageable(&vm->vm_map, va, va+PAGE_SIZE, TRUE);
++#endif
+ #if 0
+     if (ret != KERN_SUCCESS) {
+-	printf("kqemu_unlock_user_page(%08lx) failed, ret=%d\n", page_index, ret);
++	kqemu_log("kqemu_unlock_user_page(%08lx) failed, ret=%d\n", page_index, ret);
+     }
+ #endif
+ }
+@@ -76,20 +101,21 @@
+ 
+     va = kmem_alloc(kernel_map, PAGE_SIZE);
+     if (va == 0) {
+-	printf("kqemu_alloc_zeroed_page: NULL\n");
+-	return -1;
++	kqemu_log("kqemu_alloc_zeroed_page: NULL\n");
++	return NULL;
+     }
+     pmap = vm_map_pmap(kernel_map);
+     pa = pmap_extract(pmap, va);
+-    // printf("kqemu_alloc_zeroed_page: %08x\n", pa);
++    // kqemu_log("kqemu_alloc_zeroed_page: %08x\n", pa);
+     *ppage_index = pa >> PAGE_SHIFT;
+     return (struct kqemu_page *)va;
+ }
+ 
+ void CDECL kqemu_free_page(struct kqemu_page *page)
+ {
+-    //    printf("kqemu_free_page(%08lx)\n", page_index);
+-    /* XXX: do it */
++    if (kqemu_debug > 0)
++    	kqemu_log("kqemu_free_page(%p)\n", page);
++    kmem_free(kernel_map, (vm_offset_t) page, PAGE_SIZE);
+ }
+ 
+ /* return kernel address of the physical page page_index */
+@@ -103,42 +129,29 @@
+    GB of physical memory */
+ void * CDECL kqemu_vmalloc(unsigned int size)
+ {
+-    struct vmspace *vm = curproc->p_vmspace;
+-    vm_offset_t va = USER_BASE;
+-    int rv;
+-    if (size % PAGE_SIZE != 0) {
+-	printf("kqemu_vmalloc(%d) not a multiple of page size\n", size);
+-	return NULL;
+-    }
+-    rv = vm_map_find(&vm->vm_map, NULL, 0, &va, size, 1,
+-		     VM_PROT_ALL, VM_PROT_ALL, 0);
+-    if (rv != KERN_SUCCESS) {
+-	printf("kqemu_vmalloc(%d) failed rv=%d\n", size, rv);
+-	return NULL;
+-    }
+-    printf("kqemu_vmalloc(%d): %08x\n", size, va);
+-    return (void *)va;
++    void *ptr = malloc(size, M_KQEMU, M_WAITOK);
++    if (kqemu_debug > 0)
++	kqemu_log("kqemu_vmalloc(%d): %p\n", size, ptr);
++    return ptr;
+ }
+ 
+ void CDECL kqemu_vfree(void *ptr)
+ {
+-    printf("kqemu_vfree(%p)\n", ptr);
++    if (kqemu_debug > 0)
++	kqemu_log("kqemu_vfree(%p)\n", ptr);
++    free(ptr, M_KQEMU);
+ }
+ 
+ /* return the physical page index for a given virtual page */
+ unsigned long CDECL kqemu_vmalloc_to_phys(const void *vaddr)
+ {
+-    struct vmspace *vm = curproc->p_vmspace;
+-    vm_paddr_t pa;
+-    pmap_t pmap;
+-
+-    pmap = vm_map_pmap(&vm->vm_map);
+-    pa = pmap_extract(pmap, (vm_offset_t)vaddr);
++    vm_paddr_t pa = vtophys(vaddr);
+     if (pa == 0) {
+-	printf("kqemu_vmalloc_to_phys(%p)->error\n", vaddr);
++	kqemu_log("kqemu_vmalloc_to_phys(%p)->error\n", vaddr);
+ 	return -1;
+     }
+-    printf("kqemu_vmalloc_to_phys(%p)->%08x\n", vaddr, pa);
++    if (kqemu_debug > 0)
++	kqemu_log("kqemu_vmalloc_to_phys(%p)->%08x\n", vaddr, pa);
+     return pa >> PAGE_SHIFT;
+ }
+ 
+@@ -154,16 +167,48 @@
+ {
+ }
+ 
++#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)
+ {
+-    // printf("kqemu_schedule\n");
++    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)
++{
++    // kqemu_log("kqemu_schedule\n");
+     mtx_lock_spin(&sched_lock);
+     mi_switch(SW_VOL, NULL);
+     mtx_unlock_spin(&sched_lock);
+     return SIGPENDING(curthread);
+ }
++#endif
+ 
+ static char log_buf[4096];
+ 
+@@ -176,47 +221,154 @@
+     va_end(ap);
+ }
+ 
++#define KQEMU_MAX_INSTANCES 4
++
+ struct kqemu_instance { 
++#if __FreeBSD_version >= 500000
++    TAILQ_ENTRY(kqemu_instance) kqemu_ent;
++    struct cdev *kqemu_dev;
++#endif
+     //    struct semaphore sem;  
+     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 clonedevs *kqemuclones;
++static TAILQ_HEAD(,kqemu_instance) kqemuhead = TAILQ_HEAD_INITIALIZER(kqemuhead);
++static eventhandler_tag clonetag;
++#endif
++
+ static d_close_t kqemu_close;
+ static d_open_t kqemu_open;
+ 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_flags =	D_NEEDGIANT,
+ 	.d_open =	kqemu_open,
+ 	.d_ioctl =	kqemu_ioctl,
+ 	.d_close =	kqemu_close,
+ 	.d_name =	"kqemu"
++#endif
+ };
+ 
+-/* For use with make_dev(9)/destroy_dev(9). */
+-static struct cdev *kqemu_dev;
++#if __FreeBSD_version >= 500000
++static void
++#if __FreeBSD_version >= 600034
++kqemu_clone(void *arg, struct ucred *cred, char *name, int namelen,
++struct cdev **dev)
++#else
++kqemu_clone(void *arg, char *name, int namelen, struct cdev **dev)
++#endif
++{
++    int unit, r;
++    if (*dev != NULL)
++	return;
++
++    if (strcmp(name, "kqemu") == 0)
++	unit = -1;
++    else if (dev_stdclone(name, NULL, "kqemu", &unit) != 1)
++	return;         /* Bad name */
++    if (unit != -1 && unit > KQEMU_MAX_INSTANCES)
++	return;
++
++    r = clone_create(&kqemuclones, &kqemu_cdevsw, &unit, dev, 0);
++    if (r) {
++	*dev = make_dev(&kqemu_cdevsw, unit2minor(unit),
++	    UID_ROOT, GID_WHEEL, 0660, "kqemu%d", unit);
++	if (*dev != NULL) {
++	    dev_ref(*dev);
++	    (*dev)->si_flags |= SI_CHEAPCLONE;
++	}
++    }
++}
++#endif
++
++static void kqemu_destroy(struct kqemu_instance *ks)
++{
++    struct cdev *dev = ks->kqemu_dev;
++
++    if (ks->state) {
++        kqemu_delete(ks->state);
++        ks->state = NULL;
++    }
++
++    free(ks, M_KQEMU);
++    dev->si_drv1 = NULL;
++#if __FreeBSD_version >= 500000
++    TAILQ_REMOVE(&kqemuhead, ks, kqemu_ent);
++    destroy_dev(dev);
++#endif
++    --kqemu_ref_count;
++}
+ 
+ /* ARGSUSED */
+ static int
++#if __FreeBSD_version < 500000
++kqemu_open(dev_t dev, int flags, int fmt __unused, struct proc *p)
++{
++#else
+ kqemu_open(struct cdev *dev, int flags, int fmt __unused,
+     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 = malloc(sizeof(struct kqemu_instance), M_KQEMU, M_WAITOK);
+     if (ks == NULL) {
+-	printf("malloc failed\n");
++	kqemu_log("malloc failed\n");
+ 	return ENOMEM;
+     }
+-    ks->state = NULL;
++    memset(ks, 0, sizeof *ks);
++#if __FreeBSD_version >= 500000
++    ks->kqemu_dev = dev;
++    TAILQ_INSERT_TAIL(&kqemuhead, ks, kqemu_ent);
++#endif
++    kqemu_ref_count++;
++
+     dev->si_drv1 = ks;
++    if (kqemu_debug > 0)
++	kqemu_log("opened by pid=%d\n", p->p_pid);
+     return 0;
+ }
+ 
+ /* ARGSUSED */
+ static int
++#if __FreeBSD_version < 500000
++kqemu_ioctl(dev_t dev, u_long cmd, caddr_t addr,
++    int flags __unused, struct proc *p)
++#else
+ kqemu_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, 
+     int flags __unused, struct thread *td)
++#endif
+ {
+     int error = 0;
+     int ret;
+@@ -231,8 +383,9 @@
+ 	    break;
+ 	}
+ 	d1 = *(struct kqemu_init *)addr;
+-	printf("ram_base=%p ram_size=%ld\n", d1.ram_base, d1.ram_size);
+-	s = kqemu_init(d, 16000);
++	if (kqemu_debug > 0)
++	    kqemu_log("ram_base=%p ram_size=%ld\n", d1.ram_base, d1.ram_size);
++	s = kqemu_init(d, max_locked_pages);
+ 	if (s == NULL) {
+ 	    error = ENOMEM;
+ 	    break;
+@@ -248,9 +401,16 @@
+ 	}
+ 	ctx = kqemu_get_cpu_state(s);
+ 	*ctx = *(struct kqemu_cpu_state *)addr;
++#if __FreeBSD_version >= 500000
+ 	DROP_GIANT();
++#endif
+ 	ret = kqemu_exec(s);
++#if __FreeBSD_version >= 500000
+ 	PICKUP_GIANT();
++	td->td_retval[0] = ret;
++#else
++	p->p_retval[0] = ret;
++#endif
+ 	*(struct kqemu_cpu_state *)addr = *ctx;
+ 	break;
+     }
+@@ -265,10 +425,22 @@
+ 
+ /* ARGSUSED */
+ static int
++#if __FreeBSD_version < 500000
++kqemu_close(dev_t dev, int flags, int fmt __unused, struct proc *p)
++{
++#else
+ kqemu_close(struct cdev *dev __unused, int flags, int fmt __unused,
+     struct thread *td)
+ {
+-	return 0;
++    struct proc     *p = td->td_proc;
++#endif
++    struct kqemu_instance *ks = (struct kqemu_instance *) dev->si_drv1;
++
++    kqemu_destroy(ks);
++
++    if (kqemu_debug > 0)
++	kqemu_log("closed by pid=%d\n", p->p_pid);
++    return 0;
+ }
+ 
+ /* ARGSUSED */
+@@ -276,15 +448,55 @@
+ kqemu_modevent(module_t mod __unused, int type, void *data __unused)
+ {
+     int error = 0;
++#if __FreeBSD_version < 500000
++    int rc;
++#else
++    struct kqemu_instance *ks;
++#endif
+ 
+     switch (type) {
+     case MOD_LOAD:
+ 	printf("kqemu version 0x%08x\n", KQEMU_VERSION);
++	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);
++            error = ENOENT;
++            break;
++	}
+ 	kqemu_dev = make_dev(&kqemu_cdevsw, 0,
+-			     UID_ROOT, GID_WHEEL, 0666, "kqemu");
++			     UID_ROOT, GID_WHEEL, 0660, "kqemu");
++#else
++	clone_setup(&kqemuclones);
++	clonetag = EVENTHANDLER_REGISTER(dev_clone, kqemu_clone, 0, 1000);
++	if (!clonetag) {
++            error = ENOMEM;
++	    break;
++	}
++#endif
++	kqemu_log("KQEMU installed, max_instances=%d max_locked_mem=%dkB.\n",
++		  KQEMU_MAX_INSTANCES, max_locked_pages * 4);
++
++	kqemu_ref_count = 0;
+ 	break;
+     case MOD_UNLOAD:
++	if (kqemu_ref_count > 0) {
++            error = EBUSY;
++            break;
++        }
++#if __FreeBSD_version < 500000
+ 	destroy_dev(kqemu_dev);
++	if ((rc = cdevsw_remove(&kqemu_cdevsw)))
++	    kqemu_log("error unregistering, rc=%d\n", rc);
++#else
++	EVENTHANDLER_DEREGISTER(dev_clone, clonetag);
++	while ((ks = TAILQ_FIRST(&kqemuhead)) != NULL) {
++	    kqemu_destroy(ks);
++	}
++	clone_cleanup(&kqemuclones);
++#endif
+ 	break;
+     case MOD_SHUTDOWN:
+ 	break;
Index: files/patch-libmath2
@@ -0,0 +1,67 @@
+Index: qemu/bsd/Makefile
+@@ -16,7 +16,8 @@
+ 	${MACHINE_ARCH}/s_rintl.c	\
+ 	${MACHINE_ARCH}/s_round.c	\
+ 	${MACHINE_ARCH}/s_sinl.S	\
+-	${MACHINE_ARCH}/s_tanl.S
++	${MACHINE_ARCH}/s_tanl.S	\
++	${MACHINE_ARCH}/s_ldexpl.c
+ 
+ OBJS=	${SRCS:R:S/$/.o/}
+ 
+Index: qemu/bsd/i386/s_ldexpl.c
+@@ -0,0 +1,21 @@
++#include <math.h>
++#include <errno.h>
++#include <sysdep.h>
++
++long double __ldexpl(long double x, int expn)
++{
++  long double res;
++  if (!isfinite (x) || x == 0.0L)
++    return x;
++
++  __asm__ ("fscale"
++  	    : "=t" (res)
++	    : "0" (x), "u" ((long double) expn));
++
++  if (!isfinite (res) || res == 0.0L)
++    errno = ERANGE;
++
++  return res;
++}
++
++weak_alias(__ldexpl,ldexpl)
+Index: qemu/bsd/amd64/s_ldexpl.c
+@@ -0,0 +1,21 @@
++#include <math.h>
++#include <errno.h>
++#include <sysdep.h>
++
++long double __ldexpl(long double x, int expn)
++{
++  long double res;
++  if (!isfinite (x) || x == 0.0L)
++    return x;
++
++  __asm__ ("fscale"
++  	    : "=t" (res)
++	    : "0" (x), "u" ((long double) expn));
++
++  if (!isfinite (res) || res == 0.0L)
++    errno = ERANGE;
++
++  return res;
++}
++
++weak_alias(__ldexpl,ldexpl)
+Index: qemu/target-i386/helper.c
+@@ -2886,6 +2886,8 @@
+     ST0 = floatx_round_to_int(ST0, &env->fp_status);
+ }
+ 
++long double	ldexpl(long double, int);
++
+ void helper_fscale(void)
+ {
+     ST0 = ldexp (ST0, (int)(ST1)); 
Index: files/patch-vl.c
@@ -0,0 +1,21 @@
+Index: qemu/vl.c
+@@ -40,6 +40,10 @@
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <dirent.h>
++#ifdef __FreeBSD__
++#include <sys/types.h>
++#include <libutil.h>
++#endif
+ #ifdef _BSD
+ #include <sys/stat.h>
+ #ifndef __APPLE__
+@@ -1280,7 +1284,7 @@
+     return chr;
+ }
+ 
+-#if defined(__linux__)
++#if defined(__linux__) || defined(__FreeBSD__)
+ CharDriverState *qemu_chr_open_pty(void)
+ {
+     char slave_name[1024];
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200509101645.j8AGjcOe033388>