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 //------------------------------------------------------------------------------
Session(uint32_t sessionId,CMcKMod * mcKMod,Connection * connection)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 //------------------------------------------------------------------------------
~Session(void)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 //------------------------------------------------------------------------------
setErrorInfo(int32_t err)89 void Session::setErrorInfo(
90 int32_t err
91 )
92 {
93 sessionInfo.lastErr = err;
94 }
95
96
97 //------------------------------------------------------------------------------
getLastErr(void)98 int32_t Session::getLastErr(
99 void
100 )
101 {
102 return sessionInfo.lastErr;
103 }
104
105
106 //------------------------------------------------------------------------------
addBulkBuf(addr_t buf,uint32_t len,BulkBufferDescriptor ** blkBuf)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 //------------------------------------------------------------------------------
getBufHandle(addr_t sVirtAddr)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 //------------------------------------------------------------------------------
removeBulkBuf(addr_t virtAddr)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