1197dbaaaSGeorge Zhang /* 2197dbaaaSGeorge Zhang * VMware VMCI Driver 3197dbaaaSGeorge Zhang * 4197dbaaaSGeorge Zhang * Copyright (C) 2012 VMware, Inc. All rights reserved. 5197dbaaaSGeorge Zhang * 6197dbaaaSGeorge Zhang * This program is free software; you can redistribute it and/or modify it 7197dbaaaSGeorge Zhang * under the terms of the GNU General Public License as published by the 8197dbaaaSGeorge Zhang * Free Software Foundation version 2 and no later version. 9197dbaaaSGeorge Zhang * 10197dbaaaSGeorge Zhang * This program is distributed in the hope that it will be useful, but 11197dbaaaSGeorge Zhang * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12197dbaaaSGeorge Zhang * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13197dbaaaSGeorge Zhang * for more details. 14197dbaaaSGeorge Zhang */ 15197dbaaaSGeorge Zhang 16197dbaaaSGeorge Zhang #include <linux/vmw_vmci_defs.h> 17197dbaaaSGeorge Zhang #include <linux/vmw_vmci_api.h> 18197dbaaaSGeorge Zhang #include <linux/atomic.h> 19197dbaaaSGeorge Zhang #include <linux/kernel.h> 20197dbaaaSGeorge Zhang #include <linux/module.h> 21197dbaaaSGeorge Zhang #include <linux/init.h> 22197dbaaaSGeorge Zhang 23197dbaaaSGeorge Zhang #include "vmci_driver.h" 24197dbaaaSGeorge Zhang #include "vmci_event.h" 25197dbaaaSGeorge Zhang 26197dbaaaSGeorge Zhang static bool vmci_disable_host; 27197dbaaaSGeorge Zhang module_param_named(disable_host, vmci_disable_host, bool, 0); 28197dbaaaSGeorge Zhang MODULE_PARM_DESC(disable_host, 29197dbaaaSGeorge Zhang "Disable driver host personality (default=enabled)"); 30197dbaaaSGeorge Zhang 31197dbaaaSGeorge Zhang static bool vmci_disable_guest; 32197dbaaaSGeorge Zhang module_param_named(disable_guest, vmci_disable_guest, bool, 0); 33197dbaaaSGeorge Zhang MODULE_PARM_DESC(disable_guest, 34197dbaaaSGeorge Zhang "Disable driver guest personality (default=enabled)"); 35197dbaaaSGeorge Zhang 36197dbaaaSGeorge Zhang static bool vmci_guest_personality_initialized; 37197dbaaaSGeorge Zhang static bool vmci_host_personality_initialized; 38197dbaaaSGeorge Zhang 39197dbaaaSGeorge Zhang /* 40197dbaaaSGeorge Zhang * vmci_get_context_id() - Gets the current context ID. 41197dbaaaSGeorge Zhang * 42197dbaaaSGeorge Zhang * Returns the current context ID. Note that since this is accessed only 43197dbaaaSGeorge Zhang * from code running in the host, this always returns the host context ID. 44197dbaaaSGeorge Zhang */ 45197dbaaaSGeorge Zhang u32 vmci_get_context_id(void) 46197dbaaaSGeorge Zhang { 47197dbaaaSGeorge Zhang if (vmci_guest_code_active()) 48197dbaaaSGeorge Zhang return vmci_get_vm_context_id(); 49197dbaaaSGeorge Zhang else if (vmci_host_code_active()) 50197dbaaaSGeorge Zhang return VMCI_HOST_CONTEXT_ID; 51197dbaaaSGeorge Zhang 52197dbaaaSGeorge Zhang return VMCI_INVALID_ID; 53197dbaaaSGeorge Zhang } 54197dbaaaSGeorge Zhang EXPORT_SYMBOL_GPL(vmci_get_context_id); 55197dbaaaSGeorge Zhang 56197dbaaaSGeorge Zhang static int __init vmci_drv_init(void) 57197dbaaaSGeorge Zhang { 58197dbaaaSGeorge Zhang int vmci_err; 59197dbaaaSGeorge Zhang int error; 60197dbaaaSGeorge Zhang 61197dbaaaSGeorge Zhang vmci_err = vmci_event_init(); 62197dbaaaSGeorge Zhang if (vmci_err < VMCI_SUCCESS) { 63197dbaaaSGeorge Zhang pr_err("Failed to initialize VMCIEvent (result=%d)\n", 64197dbaaaSGeorge Zhang vmci_err); 65197dbaaaSGeorge Zhang return -EINVAL; 66197dbaaaSGeorge Zhang } 67197dbaaaSGeorge Zhang 68197dbaaaSGeorge Zhang if (!vmci_disable_guest) { 69197dbaaaSGeorge Zhang error = vmci_guest_init(); 70197dbaaaSGeorge Zhang if (error) { 71197dbaaaSGeorge Zhang pr_warn("Failed to initialize guest personality (err=%d)\n", 72197dbaaaSGeorge Zhang error); 73197dbaaaSGeorge Zhang } else { 74197dbaaaSGeorge Zhang vmci_guest_personality_initialized = true; 75197dbaaaSGeorge Zhang pr_info("Guest personality initialized and is %s\n", 76197dbaaaSGeorge Zhang vmci_guest_code_active() ? 77197dbaaaSGeorge Zhang "active" : "inactive"); 78197dbaaaSGeorge Zhang } 79197dbaaaSGeorge Zhang } 80197dbaaaSGeorge Zhang 81197dbaaaSGeorge Zhang if (!vmci_disable_host) { 82197dbaaaSGeorge Zhang error = vmci_host_init(); 83197dbaaaSGeorge Zhang if (error) { 84197dbaaaSGeorge Zhang pr_warn("Unable to initialize host personality (err=%d)\n", 85197dbaaaSGeorge Zhang error); 86197dbaaaSGeorge Zhang } else { 87197dbaaaSGeorge Zhang vmci_host_personality_initialized = true; 88197dbaaaSGeorge Zhang pr_info("Initialized host personality\n"); 89197dbaaaSGeorge Zhang } 90197dbaaaSGeorge Zhang } 91197dbaaaSGeorge Zhang 92197dbaaaSGeorge Zhang if (!vmci_guest_personality_initialized && 93197dbaaaSGeorge Zhang !vmci_host_personality_initialized) { 94197dbaaaSGeorge Zhang vmci_event_exit(); 95197dbaaaSGeorge Zhang return -ENODEV; 96197dbaaaSGeorge Zhang } 97197dbaaaSGeorge Zhang 98197dbaaaSGeorge Zhang return 0; 99197dbaaaSGeorge Zhang } 100197dbaaaSGeorge Zhang module_init(vmci_drv_init); 101197dbaaaSGeorge Zhang 102197dbaaaSGeorge Zhang static void __exit vmci_drv_exit(void) 103197dbaaaSGeorge Zhang { 104197dbaaaSGeorge Zhang if (vmci_guest_personality_initialized) 105197dbaaaSGeorge Zhang vmci_guest_exit(); 106197dbaaaSGeorge Zhang 107197dbaaaSGeorge Zhang if (vmci_host_personality_initialized) 108197dbaaaSGeorge Zhang vmci_host_exit(); 109197dbaaaSGeorge Zhang 110197dbaaaSGeorge Zhang vmci_event_exit(); 111197dbaaaSGeorge Zhang } 112197dbaaaSGeorge Zhang module_exit(vmci_drv_exit); 113197dbaaaSGeorge Zhang 114197dbaaaSGeorge Zhang MODULE_AUTHOR("VMware, Inc."); 115197dbaaaSGeorge Zhang MODULE_DESCRIPTION("VMware Virtual Machine Communication Interface."); 11611924ba5SJorgen Hansen MODULE_VERSION("1.1.6.0-k"); 117197dbaaaSGeorge Zhang MODULE_LICENSE("GPL v2"); 118