Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 May 2009 18:52:06 +0200
From:      Juergen Lock <nox@jelal.kn-bremen.de>
To:        freebsd-emulation@freebsd.org
Subject:   vbox amd64 host patch (was: Re: [Call For Testing] VirtualBox for FreeBSD!)
Message-ID:  <20090517165206.GA3068@triton.kn-bremen.de>
In-Reply-To: <20090517131939.GA1941@triton.kn-bremen.de>
References:  <20090514191237.GD70242@bsdcrew.de> <ed91d4a80905141418w52a4dcc2yf38b68b1b99e2fb6@mail.gmail.com> <ed91d4a80905141451o2b9461d1o1f4661e32e997585@mail.gmail.com> <200905152238.n4FMcqR0007682@triton.kn-bremen.de> <20090517131939.GA1941@triton.kn-bremen.de>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, May 17, 2009 at 03:19:39PM +0200, Juergen Lock wrote:
> On Sat, May 16, 2009 at 12:38:52AM +0200, Juergen Lock wrote:
> > In article <06c77d8650448aa63d9ce8d4b1a9c3e0.squirrel@webmail.itac.at> you write:
> > >On Thu, May 14, 2009 11:51 pm, Artem Belevich wrote:
> > >> Few more notes from -CURRENT/amd64
> > >>
> > >> [snip]
> > >>
> > >> * Attempt to boot new VM (64-bit FreeBSD) from -current snapshot DVD
> > >> ISO results in an error:
> > >>
> > >> Failed to start the virtual machine FreeBSD.
> > >> Failed to load VMMR0.r0 (VERR_SYMBOL_VALUE_TOO_BIG).
> > >> Unknown error creating VM (VERR_SYMBOL_VALUE_TOO_BIG).
> > >>
> > >> Result Code: NS_ERROR_FAILURE (0x80004005)
> > >> Component: Console
> > >> Interface: IConsole {a7f17a42-5b64-488d-977b-4b2c639ada27}
> > >
> > >
> > >I cannot reproduce that anymore (probably hit another problem). Could you
> > >please provide what the vbox-dev people asked for to solve that problem?
> > >
> > >VBox.log from ~/.VirtualBox/Machines/<VM name>/Logs/VBox.log
> > >
> > >and start with
> > >
> > >export VBOX_LOG=+rt_ldr.e.l2.f
> > >VirtualBox -startvm VM_NAME
> > >
> > Hi!
> > 
> >  You forgot to say this needs a debug build... :)
> > 
> > >the resulting .log file (created in the current directory!)
> > >
> > >http://vbox.innotek.de/pipermail/vbox-dev/2009-May/001411.html
> > >http://vbox.innotek.de/pipermail/vbox-dev/2009-May/001413.html
> > >
> > >Thanks!
> > 
> >  I tried to follow up to that thread on vbox-dev but it seems to be
> > subscribed-only, so I'll repost here: (-emulation only, I trimmed the
> > other lists)
> > 
> > >[...]
> > 
> > Hi!
> > 
> >  I just tried vbox here and saw the same problem, so I made a debug build
> > (diff for the wip FreeBSD port Makefile below) and got out the following
> > logs:
> > 
> > VBox.log:
> > 
> > 00:00:03.661 VirtualBox 2.2.51_OSE r19662 freebsd.amd64 (May 15 2009 21:17:12) release log
> > 00:00:03.661 Log opened 2009-05-15T19:25:52.579924000Z
> > 00:00:03.661 OS Product: FreeBSD
> > 00:00:03.661 OS Release: 7.2-STABLE
> > 00:00:03.661 OS Version: FreeBSD 7.2-STABLE #0: Sun May 10 19:06:01 CEST 2009     nox@triton.kn-bremen.de:/usr/obj/usr/home/nox/src72s/src/sys/TRITON
> > 00:00:03.661 Executable: /usr/local/lib/virtualbox/VirtualBox
> > 00:00:03.661 Process ID: 4630
> > 00:00:03.661 Package type: BSD_64BITS_GENERIC (OSE)
> > 00:00:03.706 
> > 00:00:03.706 !!Assertion Failed!!
> > 00:00:03.706 Expression: (Elf_Addr)*(int32_t *)pAddrW == Value
> > 00:00:03.706 Location  : /usr/home/nox/vbox/virtualbox/work/virtualbox-2.2.2r19673/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h(367) int rtldrELF64RelocateSection(RTLDRMODELF64RT_NOTHING*, Elf64_Addr, int (*)(RTLDRMODINTERNAL*, const char*, const char*, unsigned int, RTUINTPTR*, void*), void*, Elf64_Addr, Elf64_Size, const uint8_t*, uint8_t*, const void*, Elf64_Size)
> > 00:00:03.706 Value=fffffffe80ac87c0
> > 
> > 2009-05-15-19-25-48.089-VirtualBox-4630.log:
> > 
> > Log created: 2009-05-15T19:25:48.898420000Z
> > Executable: /usr/local/lib/virtualbox/VirtualBox
> > Arg[0]: VirtualBox
> > Arg[1]: -startvm
> > Arg[2]: fbsd72cd
> > RTLdrOpen: pszFilename=000000080810a040:{/usr/local/lib/virtualbox/VMMR0.r0} fFlags=0x0 enmArch=2 phLdrMod=00007fffffa99b48
> > rtldrELF64Open: /usr/local/lib/virtualbox/VMMR0.r0: returns VINF_SUCCESS *phLdrMod=000000080810d080
> > rtldrOpenWithReader: /usr/local/lib/virtualbox/VMMR0.r0: returns VINF_SUCCESS *phMod=000000080810d080
> > RTLdrOpen: return VINF_SUCCESS *phLdrMod
> > RTLdrSize: hLdrMod=000000080810d080
> > RTLdrSize: returns 1201440
> > RTLdrEnumSymbols: hLdrMod=000000080810d080 fFlags=0x0 pvBit=0000000000000000 BaseAddress=0000000000000000 pfnCallback=0000000800f961f0 pvUser=00007fffffa99b30
> > RTLdrEnumSymbols: returns VINF_SUCCESS
> > RTLdrGetBits: hLdrMod=000000080810d080 pvBits=0000000808700068 BaseAddress=fffffffe809df080 pfnGetImport=0000000800f99280 pvUser=00000008020de958
> > fffffffe809df4a4: R_X86_64_32S  Value=fffffffe80ac87c0 SymValue=fffffffe80ac84c0
> > 
> > !!Assertion Failed!!
> > Expression: (Elf_Addr)*(int32_t *)pAddrW == Value
> > Location  : /usr/home/nox/vbox/virtualbox/work/virtualbox-2.2.2r19673/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h(367) int rtldrELF64RelocateSection(RTLDRMODELF64RT_NOTHING*, Elf64_Addr, int (*)(RTLDRMODINTERNAL*, const char*, const char*, unsigned int, RTUINTPTR*, void*), void*, Elf64_Addr, Elf64_Size, const uint8_t*, uint8_t*, const void*, Elf64_Size)
> > Value=fffffffe80ac87c0
> > 
> >  I suspect BaseAddress=fffffffe809df080 is the problem?
> 
> Yup it was, as explained in this post: (thanx!)
> 	http://vbox.innotek.de/pipermail/vbox-dev/2009-May/001419.html
> 
>  ..and it looks like I now have a workaround for this issue too... :)
> I'll post the patch when I've finished/cleaned it up a little.
> 
>  I only did some quick tests using a few isos so far (i.e. I did not
> install anything yet), of which a FreeBSD 7.2rc i386 iso could enter
> livefs, an i386 and an amd64 sidux 2009-01 iso both booted into kde and
> could visit their homepage, only a FreeBSD 7.1 amd64 iso hung at the
> point where the booted kernel should enter userland.  [...]

..and that was just because io-apic was disabled for some reason.

 Anyway, I think I have done what was most necessary to the patch now,
it sure does not yet conform to vbox' style (that one is just _too_
different... :) - but at least it seems to do what it's supposed to.
Oh, its possible there's still a vm_object_deallocate() missing
after vm_map_remove(), but the code I used as guideline (in
/sys/kern/link_elf_obj.c) doesn't do one at that stage either so I
was not sure.

 Anyway, here it comes, you can put it in files/patch-amd64-r0-exec-alloc

 Enjoy,
	Juergen

Index: src/VBox/Runtime/r0drv/alloc-r0drv.h
@@ -50,6 +50,8 @@
     uint32_t    cb;
     /** The request allocation size. */
     uint32_t    cbReq;
+    /** XXX to be used by the FreeBSD/amd64 implementation. */
+    void	*opaque;
 } RTMEMHDR, *PRTMEMHDR;
 
 
Index: src/VBox/Runtime/r0drv/freebsd/alloc-r0drv-freebsd.c
@@ -48,12 +48,22 @@
 MALLOC_DEFINE(M_IPRTHEAP, "iprtheap", "IPRT - heap");
 MALLOC_DEFINE(M_IPRTCONT, "iprtcont", "IPRT - contiguous");
 
+#if defined(RT_ARCH_AMD64) || defined(__DOXYGEN__)
+PRTMEMHDR malloc32(unsigned long size, struct malloc_type *mtp, int flags);
+void free32(PRTMEMHDR pHdr, struct malloc_type *mtp);
+#endif /* defined(RT_ARCH_AMD64) || defined(__DOXYGEN__) */
 
 PRTMEMHDR rtMemAlloc(size_t cb, uint32_t fFlags)
 {
     PRTMEMHDR pHdr;
 
     /** @todo Just like OS/2, FreeBSD doesn't need this header. */
+    /* XXX actually its needed on amd64 for now... */
+#if defined(RT_ARCH_AMD64) || defined(__DOXYGEN__)
+    if (fFlags == RTMEMHDR_FLAG_EXEC) {
+        pHdr = malloc32(cb + sizeof(RTMEMHDR), M_IPRTHEAP, M_ZERO);
+    } else
+#endif
     pHdr = (PRTMEMHDR)malloc(cb + sizeof(RTMEMHDR), M_IPRTHEAP,
                              fFlags & RTMEMHDR_FLAG_ZEROED ? M_NOWAIT | M_ZERO : M_NOWAIT);
     if (pHdr)
@@ -71,6 +81,12 @@
 void rtMemFree(PRTMEMHDR pHdr)
 {
     pHdr->u32Magic += 1;
+#if defined(RT_ARCH_AMD64) || defined(__DOXYGEN__)
+    if (pHdr->fFlags == RTMEMHDR_FLAG_EXEC) {
+        free32(pHdr, M_IPRTHEAP);
+        return;
+    }
+#endif
     free(pHdr, M_IPRTHEAP);
 }
 
@@ -114,3 +130,61 @@
     }
 }
 
+#if defined(RT_ARCH_AMD64) || defined(__DOXYGEN__)
+/* see 7.2-stable /sys/kern/link_elf_obj.c:link_elf_load_file()
+ */
+PRTMEMHDR
+malloc32(unsigned long size, struct malloc_type *mtp, int flags)
+{
+	vm_object_t	object;		/* VM object to hold data */
+	vm_offset_t	mapbase;
+	int error = 0;
+
+	size = roundup(size, PAGE_SIZE);
+	object = vm_object_allocate(OBJT_DEFAULT, size >> PAGE_SHIFT);
+	if (object == NULL)
+		return (0);
+
+	/*
+	 * In order to satisfy amd64's architectural requirements on the
+	 * location of code and data in the kernel's address space, request a
+	 * mapping that is above the kernel.  
+	 */
+	mapbase = KERNBASE;
+	error = vm_map_find(kernel_map, object, 0, &mapbase,
+	    size, TRUE, VM_PROT_ALL, VM_PROT_ALL, FALSE);
+	if (error) {
+		vm_object_deallocate(object);
+		object = 0;
+		return (0);
+	}
+
+	/* Wire the pages */
+	error = vm_map_wire(kernel_map, mapbase,
+	    mapbase + size,
+	    VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES);
+	if (error != KERN_SUCCESS) {
+		return (0);
+	}
+	if (flags & M_ZERO)
+		memset((void *)mapbase, 0, size);
+
+	/* XXX need to store the vm_object_t somewhere... */
+	((PRTMEMHDR)mapbase)->opaque = (void *)object;
+	return ((PRTMEMHDR)mapbase);
+}
+
+/* see 7.2-stable /sys/kern/link_elf_obj.c:link_elf_unload_file()
+ */
+void
+free32(PRTMEMHDR pHdr, struct malloc_type *mtp)
+{
+	vm_object_t     object = (vm_object_t)pHdr->opaque;
+
+	if (object) {
+		vm_map_remove(kernel_map, (vm_offset_t) pHdr,
+		    ((vm_offset_t) pHdr) +
+		    (object->size << PAGE_SHIFT));
+	}
+}
+#endif



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