[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 UTC 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