vbox amd64 host patch (was: Re: [Call For Testing] VirtualBox for
FreeBSD!)
Juergen Lock
nox at jelal.kn-bremen.de
Sun May 17 16:54:11 UTC 2009
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 at 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 at 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
More information about the freebsd-emulation
mailing list