[vbox-dev] [PATCH 1/3] additions/linux/drm: Replace HGSMICommon.c and HGSMIMalloc.c with kernel functions

Hans de Goede hdegoede at redhat.com
Wed May 17 14:59:41 GMT 2017


Use the functions from linux/genalloc.h instead of the vbox custom
HGSMIMalloc implementation.

Signed-off-by: Hans de Goede <hdegoede at 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 <hdegoede at 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




More information about the vbox-dev mailing list