1 /** @addtogroup MCD_IMPL_LIB 2 * @{ 3 * @file 4 * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 --> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote 15 * products derived from this software without specific prior 16 * written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 #include <stdint.h> 31 #include <vector> 32 33 #include "mc_linux.h" 34 35 #include "Session.h" 36 37 #include "log.h" 38 #include <assert.h> 39 40 41 //------------------------------------------------------------------------------ 42 Session::Session( 43 uint32_t sessionId, 44 CMcKMod *mcKMod, 45 Connection *connection) 46 { 47 this->sessionId = sessionId; 48 this->mcKMod = mcKMod; 49 this->notificationConnection = connection; 50 51 sessionInfo.lastErr = SESSION_ERR_NO; 52 sessionInfo.state = SESSION_STATE_INITIAL; 53 } 54 55 56 //------------------------------------------------------------------------------ 57 Session::~Session(void) 58 { 59 BulkBufferDescriptor *pBlkBufDescr; 60 61 // Unmap still mapped buffers 62 for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin(); 63 iterator != bulkBufferDescriptors.end(); 64 ++iterator) { 65 pBlkBufDescr = *iterator; 66 67 LOG_I("removeBulkBuf - Physical Address of L2 Table = 0x%X, handle= %d", 68 (unsigned int)pBlkBufDescr->physAddrWsmL2, 69 pBlkBufDescr->handle); 70 71 // ignore any error, as we cannot do anything in this case. 72 int ret = mcKMod->unregisterWsmL2(pBlkBufDescr->handle); 73 if (ret != 0) { 74 LOG_E("removeBulkBuf(): mcKModUnregisterWsmL2 failed: %d", ret); 75 } 76 77 //iterator = bulkBufferDescriptors.erase(iterator); 78 delete(pBlkBufDescr); 79 } 80 81 // Finally delete notification connection 82 delete notificationConnection; 83 84 unlock(); 85 } 86 87 88 //------------------------------------------------------------------------------ 89 void Session::setErrorInfo( 90 int32_t err 91 ) 92 { 93 sessionInfo.lastErr = err; 94 } 95 96 97 //------------------------------------------------------------------------------ 98 int32_t Session::getLastErr( 99 void 100 ) 101 { 102 return sessionInfo.lastErr; 103 } 104 105 106 //------------------------------------------------------------------------------ 107 mcResult_t Session::addBulkBuf(addr_t buf, uint32_t len, BulkBufferDescriptor **blkBuf) 108 { 109 addr_t pPhysWsmL2; 110 uint32_t handle; 111 112 assert(blkBuf != NULL); 113 114 // Search bulk buffer descriptors for existing vAddr 115 // At the moment a virtual address can only be added one time 116 for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin(); 117 iterator != bulkBufferDescriptors.end(); 118 ++iterator) { 119 if ((*iterator)->virtAddr == buf) { 120 LOG_E("Cannot map a buffer to multiple locations in one Trustlet."); 121 return MC_DRV_ERR_BUFFER_ALREADY_MAPPED; 122 } 123 } 124 125 // Prepare the interface structure for memory registration in Kernel Module 126 mcResult_t ret = mcKMod->registerWsmL2(buf, len, 0, &handle, &pPhysWsmL2); 127 128 if (ret != MC_DRV_OK) { 129 LOG_V(" mcKMod->registerWsmL2() failed with %x", ret); 130 return ret; 131 } 132 133 LOG_V(" addBulkBuf - Handle of L2 Table = %u", handle); 134 135 // Create new descriptor - secure virtual virtual set to 0, unknown! 136 *blkBuf = new BulkBufferDescriptor(buf, 0x0, len, handle, pPhysWsmL2); 137 138 // Add to vector of descriptors 139 bulkBufferDescriptors.push_back(*blkBuf); 140 141 return MC_DRV_OK; 142 } 143 144 //------------------------------------------------------------------------------ 145 uint32_t Session::getBufHandle(addr_t sVirtAddr) 146 { 147 LOG_V("getBufHandle(): Virtual Address = 0x%X", (unsigned int) virtAddr); 148 149 // Search and remove bulk buffer descriptor 150 for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin(); 151 iterator != bulkBufferDescriptors.end(); 152 ++iterator ) { 153 if ((*iterator)->sVirtualAddr == sVirtAddr) { 154 return (*iterator)->handle; 155 } 156 } 157 return 0; 158 } 159 160 //------------------------------------------------------------------------------ 161 mcResult_t Session::removeBulkBuf(addr_t virtAddr) 162 { 163 BulkBufferDescriptor *pBlkBufDescr = NULL; 164 165 LOG_V("removeBulkBuf(): Virtual Address = 0x%X", (unsigned int) virtAddr); 166 167 // Search and remove bulk buffer descriptor 168 for ( bulkBufferDescrIterator_t iterator = bulkBufferDescriptors.begin(); 169 iterator != bulkBufferDescriptors.end(); 170 ++iterator 171 ) { 172 173 if ((*iterator)->virtAddr == virtAddr) { 174 pBlkBufDescr = *iterator; 175 iterator = bulkBufferDescriptors.erase(iterator); 176 break; 177 } 178 } 179 180 if (pBlkBufDescr == NULL) { 181 LOG_E("%p not registered in session %d.", virtAddr, sessionId); 182 return MC_DRV_ERR_BLK_BUFF_NOT_FOUND; 183 } 184 LOG_V("removeBulkBuf():handle=%u", pBlkBufDescr->handle); 185 186 // ignore any error, as we cannot do anything 187 mcResult_t ret = mcKMod->unregisterWsmL2(pBlkBufDescr->handle); 188 if (ret != MC_DRV_OK) { 189 LOG_E("mcKMod->unregisterWsmL2 failed: %x", ret); 190 return ret; 191 } 192 193 delete (pBlkBufDescr); 194 195 return MC_DRV_OK; 196 } 197 198 /** @} */ 199