From: VMware, Inc <> Date: Tue, 29 Mar 2011 20:05:29 +0000 (-0700) Subject: This is part 14 of a change to support Nested VMs. X-Git-Tag: 2011.03.28-387002~53 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ea3008a6023e83c4066e12976d8357eae384764;p=thirdparty%2Fopen-vm-tools.git This is part 14 of a change to support Nested VMs. This part adds more support for the host device in the guest driver. You can now add a host device to a guest. The VMX IOCTLs will still fail, but at least we do the access checking now. This also adds all the new device names, along with the general interface, which allows things like getting the CID, attaching to vsock etc. One final change is to the wrapper for allocating kernel memory. See the comment in vmci_kernel_if for a full explanation. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/modules/linux/shared/vmci_iocontrols.h b/open-vm-tools/modules/linux/shared/vmci_iocontrols.h index 6ba42f006..4ba42d1d5 100644 --- a/open-vm-tools/modules/linux/shared/vmci_iocontrols.h +++ b/open-vm-tools/modules/linux/shared/vmci_iocontrols.h @@ -308,18 +308,26 @@ enum IOCTLCmd_VMCIMacOS { * Windows VMCI ioctl definitions. */ -/* - * The first is the device name in user-mode. The next two are for registering - * or opening the device in kernel-mode, and are always in UNICODE. - */ -#define VMCI_DEVICE_NAME TEXT("\\\\.\\VMCI") -#define VMCI_DEVICE_NAME_NT L"\\??\\VMCI" -#define VMCI_DEVICE_NAME_PATH L"\\Device\\vmci" -#define VMCI_DEVICE_LINK_PATH L"\\DosDevices\\vmci" +/* PUBLIC: For VMCISockets user-mode clients that use CreateFile(). */ +#define VMCI_INTERFACE_VSOCK_PUBLIC_NAME TEXT("\\\\.\\VMCI") + +/* PUBLIC: For VMCISockets user-mode clients that use NtCreateFile(). */ +#define VMCI_INTERFACE_VSOCK_PUBLIC_NAME_NT L"\\??\\VMCI" + +/* PUBLIC: For the VMX, which uses CreateFile(). */ +#define VMCI_INTERFACE_VMX_PUBLIC_NAME TEXT("\\\\.\\VMCIHostDev\\VMX") + +/* PRIVATE NAMES */ +#define VMCI_DEVICE_VSOCK_NAME_PATH L"\\Device\\vmci" +#define VMCI_DEVICE_VSOCK_LINK_PATH L"\\DosDevices\\vmci" +#define VMCI_DEVICE_HOST_NAME_PATH L"\\Device\\VMCIHostDev" +#define VMCI_DEVICE_HOST_LINK_PATH L"\\DosDevice\\VMCIHostDev" +#define VMCI_DEVICE_GUEST_NAME_PATH L"\\Device\\VMCIGuestDev" +/* PRIVATE NAMES */ /* These values cannot be changed since some of the ioctl values are public. */ -#define FILE_DEVICE_VMCI 0x8103 -#define VMCI_IOCTL_BASE_INDEX 0x801 +#define FILE_DEVICE_VMCI 0x8103 +#define VMCI_IOCTL_BASE_INDEX 0x801 #define VMCIIOCTL_BUFFERED(name) \ CTL_CODE(FILE_DEVICE_VMCI, \ VMCI_IOCTL_BASE_INDEX + IOCTLCMD_VMCI_ ## name, \ @@ -436,8 +444,8 @@ typedef struct VMCIInitBlock { typedef struct VMCISharedMemInfo { VMCIHandle handle; uint32 size; - uint32 result; - VA64 va; /* Currently only used in the guest. */ + uint32 result; + VA64 va; /* Currently only used in the guest. */ char pageFileName[VMCI_PATH_MAX]; } VMCISharedMemInfo; @@ -451,7 +459,7 @@ typedef struct VMCIQueuePairAllocInfo { VA64 producePageFile; /* User VA. */ VA64 consumePageFile; /* User VA. */ uint64 producePageFileSize; /* Size of the file name array. */ - uint64 consumePageFileSize; /* Size of the file name array. */ + uint64 consumePageFileSize; /* Size of the file name array. */ #else PPN * PPNs; uint64 numPPNs; @@ -550,12 +558,12 @@ typedef struct VMCISetNotifyInfo { uint32 _pad; } VMCISetNotifyInfo; -#define VMCI_NOTIFY_RESOURCE_QUEUE_PAIR 0 +#define VMCI_NOTIFY_RESOURCE_QUEUE_PAIR 0 #define VMCI_NOTIFY_RESOURCE_DOOR_BELL 1 -#define VMCI_NOTIFY_RESOURCE_ACTION_NOTIFY 0 -#define VMCI_NOTIFY_RESOURCE_ACTION_CREATE 1 -#define VMCI_NOTIFY_RESOURCE_ACTION_DESTROY 2 +#define VMCI_NOTIFY_RESOURCE_ACTION_NOTIFY 0 +#define VMCI_NOTIFY_RESOURCE_ACTION_CREATE 1 +#define VMCI_NOTIFY_RESOURCE_ACTION_DESTROY 2 /* * Used to create and destroy doorbells, and generate a notification @@ -662,13 +670,13 @@ enum VMCrossTalkSockOpt { VMCI_SO_QUEUEPAIR_SETPAGEFILE = IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE, VMCI_SO_QUEUEPAIR_DETACH = IOCTL_VMCI_QUEUEPAIR_DETACH, VMCI_SO_DATAGRAM_SEND = IOCTL_VMCI_DATAGRAM_SEND, - VMCI_SO_DATAGRAM_RECEIVE = IOCTL_VMCI_DATAGRAM_RECEIVE, + VMCI_SO_DATAGRAM_RECEIVE = IOCTL_VMCI_DATAGRAM_RECEIVE, VMCI_SO_DATAGRAM_REQUEST_MAP = IOCTL_VMCI_DATAGRAM_REQUEST_MAP, - VMCI_SO_DATAGRAM_REMOVE_MAP = IOCTL_VMCI_DATAGRAM_REMOVE_MAP, - VMCI_SO_CTX_ADD_NOTIFICATION = IOCTL_VMCI_CTX_ADD_NOTIFICATION, - VMCI_SO_CTX_REMOVE_NOTIFICATION = IOCTL_VMCI_CTX_REMOVE_NOTIFICATION, - VMCI_SO_CTX_GET_CPT_STATE = IOCTL_VMCI_CTX_GET_CPT_STATE, - VMCI_SO_CTX_SET_CPT_STATE = IOCTL_VMCI_CTX_SET_CPT_STATE, + VMCI_SO_DATAGRAM_REMOVE_MAP = IOCTL_VMCI_DATAGRAM_REMOVE_MAP, + VMCI_SO_CTX_ADD_NOTIFICATION = IOCTL_VMCI_CTX_ADD_NOTIFICATION, + VMCI_SO_CTX_REMOVE_NOTIFICATION = IOCTL_VMCI_CTX_REMOVE_NOTIFICATION, + VMCI_SO_CTX_GET_CPT_STATE = IOCTL_VMCI_CTX_GET_CPT_STATE, + VMCI_SO_CTX_SET_CPT_STATE = IOCTL_VMCI_CTX_SET_CPT_STATE, VMCI_SO_GET_CONTEXT_ID = IOCTL_VMCI_GET_CONTEXT_ID, VMCI_SO_USERFD, }; diff --git a/open-vm-tools/modules/linux/shared/vmci_kernel_if.h b/open-vm-tools/modules/linux/shared/vmci_kernel_if.h index a7a64746e..a5f4b24c1 100644 --- a/open-vm-tools/modules/linux/shared/vmci_kernel_if.h +++ b/open-vm-tools/modules/linux/shared/vmci_kernel_if.h @@ -71,7 +71,6 @@ #include "vm_basic_types.h" #include "vmci_defs.h" -#include "vmci_infrastructure.h" #if defined(VMKERNEL) # include "list.h" @@ -255,18 +254,6 @@ typedef struct VMCIHost { void VMCI_ReadPortBytes(VMCIIoHandle handle, VMCIIoPort port, uint8 *buffer, size_t bufferLength); -/* - * Guest device handle (FsCtx). Not used on VMK, but we use an empty type to - * keep offsetchecker happy. - */ - -typedef struct VMCIGuestDeviceHandle { -#if !defined(VMKERNEL) - void *obj; - VMCIObjType objType; -#endif // VMKERNEL -} VMCIGuestDeviceHandle; - void VMCI_InitLock(VMCILock *lock, char *name, VMCILockRank rank); void VMCI_CleanupLock(VMCILock *lock); @@ -294,8 +281,22 @@ uintptr_t VMCIHost_GetActiveHnd(VMCIHost *hostContext); void VMCIHost_SignalBitmap(VMCIHost *hostContext); #endif +#if defined(_WIN32) + /* + * On Windows, Driver Verifier will panic() if we leak memory when we are + * unloaded. It dumps the leaked blocks for us along with callsites, which + * it handily tracks, but if we embed ExAllocate() inside a function, then + * the callsite is useless. So make this a macro on this platform only. + */ +# define VMCI_AllocKernelMem(_sz, _f) \ + ExAllocatePoolWithTag((((_f) & VMCI_MEMORY_NONPAGED) ? \ + NonPagedPool : PagedPool), \ + (_sz), 'MMTC') +#else // _WIN32 void *VMCI_AllocKernelMem(size_t size, int flags); +#endif // _WIN32 void VMCI_FreeKernelMem(void *ptr, size_t size); + int VMCI_CopyToUser(VA64 dst, const void *src, size_t len); Bool VMCIWellKnownID_AllowMap(VMCIId wellKnownID, VMCIPrivilegeFlags privFlags); diff --git a/open-vm-tools/modules/linux/vmci/vmciDriver.c b/open-vm-tools/modules/linux/vmci/vmciDriver.c index 81e8fc04d..ff074c086 100644 --- a/open-vm-tools/modules/linux/vmci/vmciDriver.c +++ b/open-vm-tools/modules/linux/vmci/vmciDriver.c @@ -47,9 +47,6 @@ #define LGPFX "VMCI: " static Atomic_uint32 vmContextID = { VMCI_INVALID_ID }; - -#if !defined(VMX86_TOOLS) - static VMCIContext *hostContext; @@ -128,6 +125,8 @@ VMCI_HostCleanup(void) } +#if !defined(VMX86_TOOLS) + /* *---------------------------------------------------------------------- * diff --git a/open-vm-tools/modules/linux/vmci/vmci_drv.c b/open-vm-tools/modules/linux/vmci/vmci_drv.c index ba53d96be..25cefd945 100644 --- a/open-vm-tools/modules/linux/vmci/vmci_drv.c +++ b/open-vm-tools/modules/linux/vmci/vmci_drv.c @@ -597,7 +597,7 @@ static int vmci_open(struct inode *inode, // IN struct file *file) // IN { - VMCIGuestDeviceHandle *devHndl; + VMCIObj *devHndl; int errcode; printk(KERN_INFO "Opening vmci device\n"); @@ -620,8 +620,8 @@ vmci_open(struct inode *inode, // IN errcode = -ENOMEM; goto unlock; } - devHndl->obj = NULL; - devHndl->objType = VMCIOBJ_NOT_SET; + devHndl->ptr = NULL; + devHndl->type = VMCIOBJ_NOT_SET; file->private_data = devHndl; compat_mutex_unlock(&vmci_dev.lock); @@ -654,8 +654,7 @@ static int vmci_close(struct inode *inode, // IN struct file *file) // IN { - VMCIGuestDeviceHandle *devHndl = - (VMCIGuestDeviceHandle *) file->private_data; + VMCIObj *devHndl = (VMCIObj *)file->private_data; if (devHndl) { VMCI_FreeKernelMem(devHndl, sizeof *devHndl);