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