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>