[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