[Midnightbsd-cvs] mports: emulators/kqemu-kmod: Fix a few bugs with kqemu

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Thu Jan 1 19:59:49 EST 2009


Log Message:
-----------
Fix a few bugs with kqemu

Modified Files:
--------------
    mports/emulators/kqemu-kmod:
        Makefile (r1.3 -> r1.4)
    mports/emulators/kqemu-kmod/files:
        patch-kqemu-freebsd.c (r1.1 -> r1.2)

Added Files:
-----------
    mports/emulators/kqemu-kmod/files:
        patch-common-Makefile (r1.1)
        patch-fpucontext (r1.1)
        patch-tssworkaround (r1.1)

-------------- next part --------------
Index: Makefile
===================================================================
RCS file: /home/cvs/mports/emulators/kqemu-kmod/Makefile,v
retrieving revision 1.3
retrieving revision 1.4
diff -L emulators/kqemu-kmod/Makefile -L emulators/kqemu-kmod/Makefile -u -r1.3 -r1.4
--- emulators/kqemu-kmod/Makefile
+++ emulators/kqemu-kmod/Makefile
@@ -8,10 +8,10 @@
 
 PORTNAME=	kqemu
 PORTVERSION=	1.3.0.p11
+PORTREVISION=	1
 CATEGORIES=	emulators
-MASTER_SITES=	http://qemu.org/ \
-		http://fabrice.bellard.free.fr/qemu/ \
-		${MASTER_SITE_LOCAL}
+MASTER_SITES=	http://bellard.org/qemu/ \
+		${MASTER_SITE_FREEBSD_LOCAL}
 MASTER_SITE_SUBDIR=	nox
 PKGNAMESUFFIX=	-kmod
 DISTNAME=	${PORTNAME}-${PORTVERSION:C/.p/pre/}
@@ -24,10 +24,8 @@
 ONLY_FOR_ARCHS=	i386 amd64
 HAS_CONFIGURE=	yes
 USE_GMAKE=	yes
-USE_GCC=	3.4
 CONFIGURE_ARGS+=	--prefix=${PREFIX} --cc=${CC}
 
-
 USE_RC_SUBR=	kqemu
 
 .include <bsd.port.pre.mk>
--- /dev/null
+++ emulators/kqemu-kmod/files/patch-tssworkaround
@@ -0,0 +1,112 @@
+Index: kqemu-freebsd.c
+@@ -38,6 +38,14 @@
+ #else
+ #include <machine/npx.h>
+ #endif
++#ifdef __x86_64__
++#include <sys/smp.h>
++#include <sys/pcpu.h>
++#include <machine/pcb.h>
++#include <machine/specialreg.h>
++#include <machine/segments.h>
++#include <machine/tss.h>
++#endif
+ 
+ #include "kqemu-kernel.h"
+ 
+@@ -248,6 +256,57 @@
+     va_end(ap);
+ }
+ 
++#ifdef __x86_64__
++int kqemu_cpu0gdtfixed;
++int kqemu_gdts_used;
++struct user_segment_descriptor *kqemu_gdts;
++struct region_descriptor kqemu_r_newgdt;
++extern  struct pcpu __pcpu[];
++
++/* called with interrupts disabled */
++void CDECL kqemu_tss_fixup(unsigned long kerngdtbase)
++{
++    int gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
++    unsigned cpuid = PCPU_GET(cpuid);
++    struct user_segment_descriptor *newgdt = gdt;
++
++    if (mp_ncpus <= 1 || kerngdtbase != (unsigned long)gdt)
++	/* UP host or gdt already moved, nothing to do */
++	return;
++    if (cpuid) {
++	/* move gdts of all but first cpu */
++	if (!kqemu_gdts)
++	    /*
++	     * XXX gdt is allocated as
++	     *	struct user_segment_descriptor gdt[NGDT * MAXCPU];
++	     * so it has room for the moved copies; need to allocate at
++	     * kldload (and only free if kqemu_gdts_used is zero) should this
++	     * change in the future
++	     */
++	    kqemu_gdts = &gdt[NGDT];
++	++kqemu_gdts_used;
++	newgdt = &kqemu_gdts[NGDT * (cpuid - 1)];
++	bcopy(gdt, newgdt, NGDT * sizeof(gdt[0]));
++	kqemu_r_newgdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
++	kqemu_r_newgdt.rd_base = (long) newgdt;
++    } else {
++	if (kqemu_cpu0gdtfixed)
++	    return;
++	++kqemu_cpu0gdtfixed;
++    }
++    gdt_segs[GPROC0_SEL].ssd_base = (long) &common_tss[cpuid];
++    ssdtosyssd(&gdt_segs[GPROC0_SEL],
++       (struct system_segment_descriptor *)&newgdt[GPROC0_SEL]);
++    if (cpuid) {
++	lgdt(&kqemu_r_newgdt);
++	wrmsr(MSR_GSBASE, (u_int64_t)&__pcpu[cpuid]);
++	wrmsr(MSR_KGSBASE, curthread->td_pcb->pcb_gsbase);
++	wrmsr(MSR_FSBASE, curthread->td_pcb->pcb_fsbase);
++    }
++    ltr(gsel_tss);
++}
++#endif
++
+ struct kqemu_instance { 
+ #if __FreeBSD_version >= 500000
+     TAILQ_ENTRY(kqemu_instance) kqemu_ent;
+Index: common/kernel.c
+@@ -1025,6 +1025,9 @@
+ #ifdef __x86_64__
+     uint16_t saved_ds, saved_es;
+     unsigned long fs_base, gs_base;
++#ifdef __FreeBSD__
++    struct kqemu_global_state *g = s->global_state;
++#endif
+ #endif
+     
+ #ifdef PROFILE
+@@ -1096,6 +1099,14 @@
+             apic_nmi_mask = apic_save_and_disable_nmi(s);
+         }
+ 
++#ifdef __FreeBSD__
++#ifdef __x86_64__
++        spin_lock(&g->lock);
++        asm volatile ("sgdt %0" : : "m" (s->kernel_gdt));
++        kqemu_tss_fixup(s->kernel_gdt.base);
++        spin_unlock(&g->lock);
++#endif
++#endif
+         /* load breakpoint registers and avoid setting them if in the
+            monitor address space. We suppose that no breakpoints are
+            set by the host OS for this process */
+Index: kqemu-kernel.h
+@@ -48,4 +48,10 @@
+ 
+ void CDECL kqemu_log(const char *fmt, ...);
+ 
++#ifdef __FreeBSD__
++#ifdef __x86_64__
++void CDECL kqemu_tss_fixup(unsigned long kerngdtbase);
++#endif
++#endif
++
+ #endif /* KQEMU_KERNEL_H */
--- /dev/null
+++ emulators/kqemu-kmod/files/patch-common-Makefile
@@ -0,0 +1,22 @@
+Index: common/Makefile
+@@ -47,9 +47,9 @@
+ ifeq ($(ARCH), x86_64)
+ COMMON_CFLAGS+=-mno-red-zone
+ endif
+-CFLAGS=$(COMMON_CFLAGS)
++CFLAGS=$(COMMON_CFLAGS) ${DEBUG_FLAGS}
+ MON_CFLAGS=$(COMMON_CFLAGS)
+-KERNEL_CFLAGS=$(COMMON_CFLAGS)
++KERNEL_CFLAGS=$(COMMON_CFLAGS) ${DEBUG_FLAGS}
+ 
+ # Disable SSP if GCC supports it
+ MON_CFLAGS+=$(call cc-option,$(MON_CC),-fno-stack-protector,)
+@@ -119,7 +119,7 @@
+ 	$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -c -o $@ $<
+ 
+ %.o: %.S
+-	$(CC) $(DEFINES) $(INCLUDES) -D__ASSEMBLY__ -c -o $@ $<
++	$(CC) ${DEBUG_FLAGS} $(DEFINES) $(INCLUDES) -D__ASSEMBLY__ -c -o $@ $<
+ 
+ clean:
+ 	rm -f *.o *~ monitor-image.h genoffsets genmon monitor_def.h \
--- /dev/null
+++ emulators/kqemu-kmod/files/patch-fpucontext
@@ -0,0 +1,78 @@
+Index: common/kernel.c
+@@ -1240,6 +1240,11 @@
+             case MON_REQ_EXCEPTION:
+                 exec_exception(s->arg0);
+                 break;
++#ifdef __FreeBSD__
++            case MON_REQ_LOADFPUCONTEXT:
++                kqemu_loadfpucontext(s->arg0);
++                break;
++#endif
+             default:
+                 kqemu_log("invalid mon request: %d\n", s->mon_req);
+                 break;
+Index: common/kqemu_int.h
+@@ -523,6 +523,7 @@
+     MON_REQ_LOCK_USER_PAGE,
+     MON_REQ_UNLOCK_USER_PAGE,
+     MON_REQ_EXCEPTION,
++    MON_REQ_LOADFPUCONTEXT,
+ } MonitorRequest;
+ 
+ #define INTERRUPT_ENTRY_SIZE 16
+Index: common/monitor.c
+@@ -1995,8 +1995,13 @@
+         raise_exception_err(s, EXCP07_PREX, 0);
+     } else {
+         /* the host needs to restore the FPU state for us */
++#ifndef __FreeBSD__
+         s->mon_req = MON_REQ_EXCEPTION;
+         s->arg0 = 0x07;
++#else
++        s->mon_req = MON_REQ_LOADFPUCONTEXT;
++        s->arg0 = (unsigned long)s->cpu_state.cpl;
++#endif
+         monitor2kernel1(s);
+     }
+ }
+Index: kqemu-freebsd.c
+@@ -33,6 +33,11 @@
+ 
+ #include <machine/vmparam.h>
+ #include <machine/stdarg.h>
++#ifdef __x86_64__
++#include <machine/fpu.h>
++#else
++#include <machine/npx.h>
++#endif
+ 
+ #include "kqemu-kernel.h"
+ 
+@@ -172,6 +177,15 @@
+ {
+ }
+ 
++void CDECL kqemu_loadfpucontext(unsigned long cpl)
++{
++#ifdef __x86_64__
++    fpudna();
++#else
++    npxdna();
++#endif
++}
++
+ #if __FreeBSD_version < 500000
+ static int
+ curpriority_cmp(struct proc *p)
+Index: kqemu-kernel.h
+@@ -40,6 +40,10 @@
+ void * CDECL kqemu_io_map(unsigned long page_index, unsigned int size);
+ void CDECL kqemu_io_unmap(void *ptr, unsigned int size);
+ 
++#ifdef __FreeBSD__
++void CDECL kqemu_loadfpucontext(unsigned long cpl);
++#endif
++
+ int CDECL kqemu_schedule(void);
+ 
+ void CDECL kqemu_log(const char *fmt, ...);
Index: patch-kqemu-freebsd.c
===================================================================
RCS file: /home/cvs/mports/emulators/kqemu-kmod/files/patch-kqemu-freebsd.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -L emulators/kqemu-kmod/files/patch-kqemu-freebsd.c -L emulators/kqemu-kmod/files/patch-kqemu-freebsd.c -u -r1.1 -r1.2
--- emulators/kqemu-kmod/files/patch-kqemu-freebsd.c
+++ emulators/kqemu-kmod/files/patch-kqemu-freebsd.c
@@ -1,12 +1,69 @@
 Index: kqemu-freebsd.c
-@@ -321,6 +321,9 @@
+@@ -222,9 +222,17 @@
+ int CDECL kqemu_schedule(void)
+ {
+     /* kqemu_log("kqemu_schedule\n"); */
++#if __FreeBSD_version < 700044
+     mtx_lock_spin(&sched_lock);
+     mi_switch(SW_VOL, NULL);
+     mtx_unlock_spin(&sched_lock);
++#else
++    /* -current no longer uses sched_lock */
++    struct thread *td = curthread;
++    thread_lock(td);
++    mi_switch(SW_VOL, NULL);
++    thread_unlock(td);
++#endif
+     return SIGPENDING(curthread);
+ }
+ #endif
+@@ -258,6 +266,10 @@
+ static struct clonedevs *kqemuclones;
+ static TAILQ_HEAD(,kqemu_instance) kqemuhead = TAILQ_HEAD_INITIALIZER(kqemuhead);
+ static eventhandler_tag clonetag;
++#ifndef D_NEEDMINOR
++/* see http://svn.freebsd.org/viewvc/base?view=revision&revision=179726 */
++#define D_NEEDMINOR 0
++#endif
+ #endif
+ 
+ static d_close_t kqemu_close;
+@@ -282,7 +294,7 @@
+ 	/* bmaj */	-1
+ #else
+ 	.d_version =	D_VERSION,
+-	.d_flags =	D_NEEDGIANT,
++	.d_flags =	D_NEEDGIANT | D_NEEDMINOR,
+ 	.d_open =	kqemu_open,
+ 	.d_ioctl =	kqemu_ioctl,
+ 	.d_close =	kqemu_close,
+@@ -334,8 +346,15 @@
  #if __FreeBSD_version >= 500000
      dev->si_drv1 = NULL;
      TAILQ_REMOVE(&kqemuhead, ks, kqemu_ent);
++#if __FreeBSD_version >= 700051
++    destroy_dev_sched(dev);
++#else
 +#if __FreeBSD_version >= 700024
 +    dev_relthread(dev); 
 +#endif
      destroy_dev(dev);
  #endif
++#endif
      free(ks, M_KQEMU);
-
+     --kqemu_ref_count;
+ }
+@@ -514,7 +533,13 @@
+ 	while ((ks = TAILQ_FIRST(&kqemuhead)) != NULL) {
+ 	    kqemu_destroy(ks);
+ 	}
++#if __FreeBSD_version >= 700051
++	drain_dev_clone_events();
++#endif
+ 	clone_cleanup(&kqemuclones);
++#if __FreeBSD_version >= 700051
++	destroy_dev_drain(&kqemu_cdevsw);
++#endif
+ #endif
+         kqemu_global_delete(kqemu_gs);
+         kqemu_gs = NULL;


More information about the Midnightbsd-cvs mailing list