Use the functions from linux/genalloc.h instead of the vbox custom HGSMIMalloc implementation.
Signed-off-by: Hans de Goede <hdego...@redhat.com> --- src/VBox/Additions/common/VBoxVideo/HGSMIGuest.cpp | 5 + src/VBox/Additions/linux/drm/HGSMIBuffers.h | 54 ++++++++++ src/VBox/Additions/linux/drm/Makefile.module.kms | 4 +- src/VBox/Additions/linux/drm/VBoxVideoIPRT.h | 16 +-- src/VBox/Additions/linux/drm/files_vboxvideo_drv | 8 +- src/VBox/Additions/linux/drm/vbox_hgsmi.c | 118 +++++++++++++++++++++ src/VBox/Additions/linux/drm/vbox_main.c | 43 +++----- 7 files changed, 206 insertions(+), 42 deletions(-) create mode 100644 src/VBox/Additions/linux/drm/HGSMIBuffers.h create mode 100644 src/VBox/Additions/linux/drm/vbox_hgsmi.c diff --git a/src/VBox/Additions/common/VBoxVideo/HGSMIGuest.cpp b/src/VBox/Additions/common/VBoxVideo/HGSMIGuest.cpp index 25c93a38..cf04934a 100644 --- a/src/VBox/Additions/common/VBoxVideo/HGSMIGuest.cpp +++ b/src/VBox/Additions/common/VBoxVideo/HGSMIGuest.cpp @@ -29,6 +29,9 @@ #include <VBoxVideoVBE.h> #include <VBoxVideoIPRT.h> +/* The linux-drm-driver provides its own version of these */ +#if !(defined(IN_RING0) && defined(RT_OS_LINUX)) + /** * Set up the HGSMI guest-to-host command context. * @returns iprt status value @@ -123,6 +126,8 @@ DECLHIDDEN(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx, return VERR_INVALID_PARAMETER; } +#endif /* !linux-drm-driver */ + /** Detect whether HGSMI is supported by the host. */ DECLHIDDEN(bool) VBoxHGSMIIsSupported(void) diff --git a/src/VBox/Additions/linux/drm/HGSMIBuffers.h b/src/VBox/Additions/linux/drm/HGSMIBuffers.h new file mode 100644 index 00000000..3c295488 --- /dev/null +++ b/src/VBox/Additions/linux/drm/HGSMIBuffers.h @@ -0,0 +1,54 @@ +/** @file + * VBox Host Guest Shared Memory Interface (HGSMI) buffer management. + */ + +/* + * Copyright (C) 2017 Oracle Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef ___VBox_Graphics_HGSMIBuffers_h___ +#define ___VBox_Graphics_HGSMIBuffers_h___ + +#include <VBoxVideoIPRT.h> +#include <HGSMIChannels.h> +#include <HGSMIChSetup.h> +#include <HGSMIDefs.h> +#include <linux/genalloc.h> + +typedef struct HGSMIGUESTCOMMANDCONTEXT { + struct gen_pool *guest_pool; +} HGSMIGUESTCOMMANDCONTEXT, *PHGSMIGUESTCOMMANDCONTEXT; + +void *hgsmi_buffer_alloc(struct gen_pool *guest_pool, size_t size, + u8 channel, u16 channel_info); +void hgsmi_buffer_free(struct gen_pool *guest_pool, void *buf); +int hgsmi_buffer_submit(struct gen_pool *guest_pool, void *buf); + +/* + * Translate CamelCase names used in osindependent code to standard + * kernel style names. + */ +#define VBoxHGSMIBufferAlloc(ctx, size, ch, ch_info) \ + hgsmi_buffer_alloc((ctx)->guest_pool, size, ch, ch_info) +#define VBoxHGSMIBufferFree(ctx, buf) hgsmi_buffer_free((ctx)->guest_pool, buf) +#define VBoxHGSMIBufferSubmit(ctx, buf) hgsmi_buffer_submit((ctx)->guest_pool, buf) + +#endif diff --git a/src/VBox/Additions/linux/drm/Makefile.module.kms b/src/VBox/Additions/linux/drm/Makefile.module.kms index 03e61841..2440711f 100644 --- a/src/VBox/Additions/linux/drm/Makefile.module.kms +++ b/src/VBox/Additions/linux/drm/Makefile.module.kms @@ -34,9 +34,9 @@ ifneq ($(KERN_VERSION),24) MOD_NAME = vboxvideo -MOD_OBJS = HGSMIGuest.o HGSMICommon.o HGSMIMemAlloc.o \ +MOD_OBJS = HGSMIGuest.o \ Modesetting.o vbox_drv.o vbox_fb.o vbox_irq.o vbox_main.o \ - vbox_mode.o vbox_ttm.o VBVABase.o vbox_prime.o + vbox_mode.o vbox_ttm.o VBVABase.o vbox_prime.o vbox_hgsmi.o MOD_CFLAGS = -Wno-declaration-after-statement -fshort-wchar -fno-pie MOD_INCL = $(addprefix -I$(KBUILD_EXTMOD),/ /include) diff --git a/src/VBox/Additions/linux/drm/VBoxVideoIPRT.h b/src/VBox/Additions/linux/drm/VBoxVideoIPRT.h index 67ab3d6a..f44fa1c9 100644 --- a/src/VBox/Additions/linux/drm/VBoxVideoIPRT.h +++ b/src/VBox/Additions/linux/drm/VBoxVideoIPRT.h @@ -28,12 +28,11 @@ #ifndef ___VBox_VBoxVideoIPRT_h #define ___VBox_VBoxVideoIPRT_h -#include <asm/atomic.h> #include <asm/io.h> #include <iprt/cdefs.h> -#include <iprt/list.h> #include <iprt/stdarg.h> #include <iprt/stdint.h> +#include <iprt/types.h> #include <linux/string.h> @@ -62,10 +61,6 @@ /** @name VirtualBox helper functions * @{ */ -#define RT_ZERO(x) memset(&(x), 0, sizeof(x)) -#define ASMAtomicCmpXchgBool(b, new_val, old_val) \ - (cmpxchg(b, old_val, new_val) == old_val) -#define ASMAtomicWriteBool(b, val) xchg(b, val) #define ASMCompilerBarrier() mb() /** @} */ @@ -112,4 +107,13 @@ extern int RTASSERTVAR[1]; /** @} */ +/** @name types for VirtualBox osindepent code + * @{ */ + +/* HGSMI uses 32 bit offsets and sizes. */ +typedef uint32_t HGSMISIZE; +typedef uint32_t HGSMIOFFSET; + +/** @} */ + #endif /* ___VBox_VBoxVideoIPRT_h */ diff --git a/src/VBox/Additions/linux/drm/files_vboxvideo_drv b/src/VBox/Additions/linux/drm/files_vboxvideo_drv index de1858ae..75304b00 100755 --- a/src/VBox/Additions/linux/drm/files_vboxvideo_drv +++ b/src/VBox/Additions/linux/drm/files_vboxvideo_drv @@ -21,22 +21,19 @@ FILES_VBOXVIDEO_DRM_NOBIN=" \ ${PATH_OUT}/revision-generated.h=>revision-generated.h \ ${PATH_OUT}/product-generated.h=>product-generated.h \ ${PATH_ROOT}/include/iprt/cdefs.h=>include/iprt/cdefs.h \ - ${PATH_ROOT}/include/iprt/list.h=>include/iprt/list.h \ ${PATH_ROOT}/include/iprt/stdarg.h=>include/iprt/stdarg.h \ ${PATH_ROOT}/include/iprt/stdint.h=>include/iprt/stdint.h \ ${PATH_ROOT}/include/iprt/types.h=>include/iprt/types.h \ ${PATH_ROOT}/include/VBox/Graphics/VBoxVideo.h=>include/VBoxVideo.h \ ${PATH_ROOT}/include/VBox/Graphics/VBoxVideoGuest.h=>include/VBoxVideoGuest.h \ - ${PATH_ROOT}/include/VBox/Graphics/HGSMI.h=>include/HGSMI.h \ - ${PATH_ROOT}/include/VBox/Graphics/HGSMIBuffers.h=>include/HGSMIBuffers.h \ ${PATH_ROOT}/include/VBox/Graphics/HGSMIChannels.h=>include/HGSMIChannels.h \ ${PATH_ROOT}/include/VBox/Graphics/HGSMIChSetup.h=>include/HGSMIChSetup.h \ ${PATH_ROOT}/include/VBox/Graphics/HGSMIDefs.h=>include/HGSMIDefs.h \ - ${PATH_ROOT}/include/VBox/Graphics/HGSMIMemAlloc.h=>include/HGSMIMemAlloc.h \ ${PATH_ROOT}/include/VBox/Graphics/VBoxVideoVBE.h=>include/VBoxVideoVBE.h \ ${PATH_ROOT}/src/VBox/Additions/common/VBoxVideo/HGSMIGuest.cpp=>HGSMIGuest.c \ ${PATH_ROOT}/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp=>Modesetting.c \ ${PATH_ROOT}/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp=>VBVABase.c \ + ${PATH_ROOT}/src/VBox/Additions/linux/drm/HGSMIBuffers.h=>include/HGSMIBuffers.h \ ${PATH_ROOT}/src/VBox/Additions/linux/drm/VBoxVideoIPRT.h=>include/VBoxVideoIPRT.h \ ${PATH_ROOT}/src/VBox/Additions/linux/drm/vbox_drv.c=>vbox_drv.c \ ${PATH_ROOT}/src/VBox/Additions/linux/drm/vbox_drv.h=>vbox_drv.h \ @@ -46,8 +43,7 @@ FILES_VBOXVIDEO_DRM_NOBIN=" \ ${PATH_ROOT}/src/VBox/Additions/linux/drm/vbox_mode.c=>vbox_mode.c \ ${PATH_ROOT}/src/VBox/Additions/linux/drm/vbox_prime.c=>vbox_prime.c \ ${PATH_ROOT}/src/VBox/Additions/linux/drm/vbox_ttm.c=>vbox_ttm.c \ - ${PATH_ROOT}/src/VBox/GuestHost/HGSMI/HGSMICommon.cpp=>HGSMICommon.c \ - ${PATH_ROOT}/src/VBox/GuestHost/HGSMI/HGSMIMemAlloc.cpp=>HGSMIMemAlloc.c \ + ${PATH_ROOT}/src/VBox/Additions/linux/drm/vbox_hgsmi.c=>vbox_hgsmi.c \ ${PATH_ROOT}/src/VBox/Installer/linux/Makefile.include.header=>Makefile.include.header \ ${PATH_ROOT}/src/VBox/Installer/linux/Makefile.include.footer=>Makefile.include.footer \ ${PATH_ROOT}/src/VBox/Additions/linux/drm/Makefile.module.kms=>Makefile \ diff --git a/src/VBox/Additions/linux/drm/vbox_hgsmi.c b/src/VBox/Additions/linux/drm/vbox_hgsmi.c new file mode 100644 index 00000000..8c72684f --- /dev/null +++ b/src/VBox/Additions/linux/drm/vbox_hgsmi.c @@ -0,0 +1,118 @@ +/** @file + * VirtualBox Additions Linux kernel video driver hgsmi interface code + */ + +/* + * Copyright (C) 2017 Oracle Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * Authors: Hans de Goede <hdego...@redhat.com> + */ + +#include <HGSMIBuffers.h> +#include <VBoxVideoVBE.h> + +/* One-at-a-Time Hash from http://www.burtleburtle.net/bob/hash/doobs.html */ +static u32 hgsmi_hash_process(u32 hash, const u8 *data, int size) +{ + while (size--) { + hash += *data++; + hash += (hash << 10); + hash ^= (hash >> 6); + } + + return hash; +} + +static u32 hgsmi_hash_end(u32 hash) +{ + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + + return hash; +} + +/* Not really a checksum but that is the naming used in all vbox code */ +static u32 hgsmi_checksum(u32 offset, + const HGSMIBUFFERHEADER *header, + const HGSMIBUFFERTAIL *tail) +{ + u32 checksum; + + checksum = hgsmi_hash_process(0, (u8 *)&offset, sizeof(offset)); + checksum = hgsmi_hash_process(checksum, (u8 *)header, sizeof(*header)); + /* 4 -> Do not checksum the checksum itself */ + checksum = hgsmi_hash_process(checksum, (u8 *)tail, 4); + + return hgsmi_hash_end(checksum); +} + +void *hgsmi_buffer_alloc(struct gen_pool *guest_pool, size_t size, + u8 channel, u16 channel_info) +{ + HGSMIBUFFERHEADER *h; + HGSMIBUFFERTAIL *t; + size_t total_size; + dma_addr_t offset; + + total_size = size + sizeof(HGSMIBUFFERHEADER) + sizeof(HGSMIBUFFERTAIL); + h = gen_pool_dma_alloc(guest_pool, total_size, &offset); + if (!h) + return NULL; + + t = (HGSMIBUFFERTAIL *)((u8 *)h + sizeof(HGSMIBUFFERHEADER) + size); + + h->u8Flags = HGSMI_BUFFER_HEADER_F_SEQ_SINGLE; + h->u32DataSize = size; + h->u8Channel = channel; + h->u16ChannelInfo = channel_info; + memset(&h->u.au8Union, 0, sizeof(h->u.au8Union)); + + t->u32Reserved = 0; + t->u32Checksum = hgsmi_checksum(offset, h, t); + + return (u8 *)h + sizeof(HGSMIBUFFERHEADER); +} + +void hgsmi_buffer_free(struct gen_pool *guest_pool, void *buf) +{ + HGSMIBUFFERHEADER *h = + (HGSMIBUFFERHEADER *)((u8 *)buf - sizeof(HGSMIBUFFERHEADER)); + size_t total_size = h->u32DataSize + sizeof(HGSMIBUFFERHEADER) + + sizeof(HGSMIBUFFERTAIL); + + gen_pool_free(guest_pool, (unsigned long)h, total_size); +} + +int hgsmi_buffer_submit(struct gen_pool *guest_pool, void *buf) +{ + phys_addr_t offset; + + offset = gen_pool_virt_to_phys(guest_pool, + (unsigned long)buf - sizeof(HGSMIBUFFERHEADER)); + outl(offset, VGA_PORT_HGSMI_GUEST); + /* Make the compiler aware that the host has changed memory. */ + mb(); + + return VINF_SUCCESS; +} diff --git a/src/VBox/Additions/linux/drm/vbox_main.c b/src/VBox/Additions/linux/drm/vbox_main.c index 4e9a3b80..e76945dd 100644 --- a/src/VBox/Additions/linux/drm/vbox_main.c +++ b/src/VBox/Additions/linux/drm/vbox_main.c @@ -258,31 +258,6 @@ static int vbox_accel_init(struct vbox_private *vbox) return 0; } -/** Allocation function for the HGSMI heap and data. */ -static DECLCALLBACK(void *) alloc_hgsmi_environ(void *environ, HGSMISIZE size) -{ - NOREF(environ); - return kmalloc(size, GFP_KERNEL); -} - - -/** Free function for the HGSMI heap and data. */ -static DECLCALLBACK(void) free_hgsmi_environ(void *environ, void *ptr) -{ - NOREF(environ); - kfree(ptr); -} - - -/** Pointers to the HGSMI heap and data manipulation functions. */ -static HGSMIENV hgsmi_environ = -{ - NULL, - alloc_hgsmi_environ, - free_hgsmi_environ -}; - - /** Do we support the 4.3 plus mode hint reporting interface? */ static bool have_hgsmi_mode_hints(struct vbox_private *vbox) { @@ -300,6 +275,8 @@ static int vbox_hw_init(struct vbox_private *vbox) { vbox->full_vram_size = VBoxVideoGetVRAMSize(); vbox->any_pitch = VBoxVideoAnyWidthAllowed(); + int ret; + DRM_INFO("VRAM %08x\n", vbox->full_vram_size); /* Map guest-heap at end of vram */ @@ -308,10 +285,18 @@ static int vbox_hw_init(struct vbox_private *vbox) if (!vbox->guest_heap) return -ENOMEM; - if (RT_FAILURE(VBoxHGSMISetupGuestContext(&vbox->submit_info, vbox->guest_heap, - GUEST_HEAP_USABLE_SIZE, GUEST_HEAP_OFFSET(vbox), - &hgsmi_environ))) + /* Create guest-heap mem-pool use 2^4 = 16 byte chunks */ + vbox->submit_info.guest_pool = gen_pool_create(4, -1); + if (!vbox->submit_info.guest_pool) return -ENOMEM; + + ret = gen_pool_add_virt(vbox->submit_info.guest_pool, + (unsigned long)vbox->guest_heap, + GUEST_HEAP_OFFSET(vbox), + GUEST_HEAP_USABLE_SIZE, -1); + if (ret) + return ret; + /* Reduce available VRAM size to reflect the guest heap. */ vbox->available_vram_size = GUEST_HEAP_OFFSET(vbox); /* Linux drm represents monitors as a 32-bit array. */ @@ -399,6 +384,8 @@ int vbox_driver_unload(struct drm_device *dev) vbox_hw_fini(vbox); vbox_mm_fini(vbox); + if (vbox->submit_info.guest_pool) + gen_pool_destroy(vbox->submit_info.guest_pool); if (vbox->guest_heap) pci_iounmap(dev->pdev, vbox->guest_heap); kfree(vbox); -- 2.12.2 _______________________________________________ vbox-dev mailing list vbox-dev@virtualbox.org https://www.virtualbox.org/mailman/listinfo/vbox-dev