aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mvp/pvtcpkm/pvtcp_off_linux_shim.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mvp/pvtcpkm/pvtcp_off_linux_shim.S')
-rw-r--r--arch/arm/mvp/pvtcpkm/pvtcp_off_linux_shim.S70
1 files changed, 70 insertions, 0 deletions
diff --git a/arch/arm/mvp/pvtcpkm/pvtcp_off_linux_shim.S b/arch/arm/mvp/pvtcpkm/pvtcp_off_linux_shim.S
new file mode 100644
index 0000000..824286b
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/pvtcp_off_linux_shim.S
@@ -0,0 +1,70 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief PVTCP socket destructor shim.
+ *
+ * The module reference accounting code for socket destruction in the core
+ * Linux kernel does not know about PVTCP sockets, so it does not properly
+ * increment/decrement the reference count on pvtcpkm when calling through a
+ * function pointer into our destructor. If a module unload is requested on
+ * pvtcpkm while a socket is being destroyed, it is possible for the destructor
+ * to be preempted after decrementing the module reference count but before
+ * returning to the core kernel. If the module code is unmapped before the
+ * function return, it is possible that we will attempt to execute unmapped
+ * code, resulting in a host crash.
+ *
+ * This shim proxies socket destruction requests through to the PVTCP socket
+ * destructor, then jumps directly to module_put to drop the reference count.
+ * module_put will return directly to the caller, eliminating the race.
+ */
+
+.text
+.p2align 4
+
+.global asmDestructorShim
+
+/**
+ * @brief Socket destructor callback. Calls into pvtcpkm to destroy a socket
+ * and then decrements the refcount.
+ * @param r0 pointer to struct sock
+ */
+
+asmDestructorShim:
+ push {lr}
+ ldr r1, targetAddr @ Destroy socket
+ blx r1
+ pop {lr}
+ cmp r0, #0
+ bxne lr @ We shouldn't module_put, just return.
+ ldr r0, owner
+ ldr r1, modulePutAddr @ Jump to module_put. module_put
+ bx r1 @ returns directly to caller
+
+owner:
+ .word __this_module
+
+targetAddr:
+ .word DestructCB
+
+modulePutAddr:
+ .word module_put