~ubuntu-branches/ubuntu/trusty/virtualbox-lts-xenial/trusty-proposed

« back to all changes in this revision

Viewing changes to src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c

  • Committer: Package Import Robot
  • Author(s): Gianfranco Costamagna
  • Date: 2016-02-23 14:28:26 UTC
  • Revision ID: package-import@ubuntu.com-20160223142826-bdu69el2z6wa2a44
Tags: upstream-4.3.36-dfsg
ImportĀ upstreamĀ versionĀ 4.3.36-dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 
 
3
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
 
4
 
 
5
This program and the accompanying materials
 
6
are licensed and made available under the terms and conditions
 
7
of the BSD License which accompanies this distribution.  The
 
8
full text of the license may be found at
 
9
http://opensource.org/licenses/bsd-license.php
 
10
 
 
11
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 
12
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
13
 
 
14
**/
 
15
 
 
16
#include <PiSmm.h>
 
17
#include <Library/UefiDriverEntryPoint.h>
 
18
#include <Library/UefiBootServicesTableLib.h>
 
19
#include <Library/UefiRuntimeServicesTableLib.h>
 
20
#include <Library/SmmServicesTableLib.h>
 
21
#include <Library/BaseLib.h>
 
22
#include <Library/BaseMemoryLib.h>
 
23
#include <Library/DebugLib.h>
 
24
#include <Library/LockBoxLib.h>
 
25
#include <Protocol/SmmReadyToLock.h>
 
26
#include <Protocol/SmmCommunication.h>
 
27
#include <Protocol/SmmAccess2.h>
 
28
#include <Protocol/LockBox.h>
 
29
#include <Guid/SmmLockBox.h>
 
30
 
 
31
BOOLEAN              mLocked = FALSE;
 
32
 
 
33
EFI_SMRAM_DESCRIPTOR *mSmramRanges;
 
34
UINTN                mSmramRangeCount;
 
35
 
 
36
/**
 
37
  This function check if the address is in SMRAM.
 
38
 
 
39
  @param Buffer  the buffer address to be checked.
 
40
  @param Length  the buffer length to be checked.
 
41
 
 
42
  @retval TRUE  this address is in SMRAM.
 
43
  @retval FALSE this address is NOT in SMRAM.
 
44
**/
 
45
BOOLEAN
 
46
IsAddressInSmram (
 
47
  IN EFI_PHYSICAL_ADDRESS  Buffer,
 
48
  IN UINT64                Length
 
49
  )
 
50
{
 
51
  UINTN  Index;
 
52
 
 
53
  for (Index = 0; Index < mSmramRangeCount; Index ++) {
 
54
    if (((Buffer >= mSmramRanges[Index].CpuStart) && (Buffer < mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize)) ||
 
55
        ((mSmramRanges[Index].CpuStart >= Buffer) && (mSmramRanges[Index].CpuStart < Buffer + Length))) {
 
56
      return TRUE;
 
57
    }
 
58
  }
 
59
 
 
60
  return FALSE;
 
61
}
 
62
 
 
63
/**
 
64
  Dispatch function for SMM lock box save.
 
65
 
 
66
  @param LockBoxParameterSave  parameter of lock box save 
 
67
**/
 
68
VOID
 
69
SmmLockBoxSave (
 
70
  IN EFI_SMM_LOCK_BOX_PARAMETER_SAVE *LockBoxParameterSave
 
71
  )
 
72
{
 
73
  EFI_STATUS                  Status;
 
74
 
 
75
  //
 
76
  // Sanity check
 
77
  //
 
78
  if (mLocked) {
 
79
    DEBUG ((EFI_D_ERROR, "SmmLockBox Locked!\n"));
 
80
    LockBoxParameterSave->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
 
81
    return ;
 
82
  }
 
83
 
 
84
  //
 
85
  // Save data
 
86
  //
 
87
  Status = SaveLockBox (
 
88
             &LockBoxParameterSave->Guid,
 
89
             (VOID *)(UINTN)LockBoxParameterSave->Buffer,
 
90
             (UINTN)LockBoxParameterSave->Length
 
91
             );
 
92
  LockBoxParameterSave->Header.ReturnStatus = (UINT64)Status;
 
93
  return ;
 
94
}
 
95
 
 
96
/**
 
97
  Dispatch function for SMM lock box set attributes.
 
98
 
 
99
  @param LockBoxParameterSetAttributes  parameter of lock box set attributes
 
100
**/
 
101
VOID
 
102
SmmLockBoxSetAttributes (
 
103
  IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *LockBoxParameterSetAttributes
 
104
  )
 
105
{
 
106
  EFI_STATUS                    Status;
 
107
 
 
108
  //
 
109
  // Sanity check
 
110
  //
 
111
  if (mLocked) {
 
112
    DEBUG ((EFI_D_ERROR, "SmmLockBox Locked!\n"));
 
113
    LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
 
114
    return ;
 
115
  }
 
116
 
 
117
  //
 
118
  // Update data
 
119
  //
 
120
  Status = SetLockBoxAttributes (
 
121
             &LockBoxParameterSetAttributes->Guid,
 
122
             LockBoxParameterSetAttributes->Attributes
 
123
             );
 
124
  LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)Status;
 
125
  return ;
 
126
}
 
127
 
 
128
/**
 
129
  Dispatch function for SMM lock box update.
 
130
 
 
131
  @param LockBoxParameterUpdate  parameter of lock box update 
 
132
**/
 
133
VOID
 
134
SmmLockBoxUpdate (
 
135
  IN EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *LockBoxParameterUpdate
 
136
  )
 
137
{
 
138
  EFI_STATUS                    Status;
 
139
 
 
140
  //
 
141
  // Sanity check
 
142
  //
 
143
  if (mLocked) {
 
144
    DEBUG ((EFI_D_ERROR, "SmmLockBox Locked!\n"));
 
145
    LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
 
146
    return ;
 
147
  }
 
148
 
 
149
  //
 
150
  // Update data
 
151
  //
 
152
  Status = UpdateLockBox (
 
153
             &LockBoxParameterUpdate->Guid,
 
154
             (UINTN)LockBoxParameterUpdate->Offset,
 
155
             (VOID *)(UINTN)LockBoxParameterUpdate->Buffer,
 
156
             (UINTN)LockBoxParameterUpdate->Length
 
157
             );
 
158
  LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)Status;
 
159
  return ;
 
160
}
 
161
 
 
162
/**
 
163
  Dispatch function for SMM lock box restore.
 
164
 
 
165
  @param LockBoxParameterRestore  parameter of lock box restore 
 
166
**/
 
167
VOID
 
168
SmmLockBoxRestore (
 
169
  IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *LockBoxParameterRestore
 
170
  )
 
171
{
 
172
  EFI_STATUS                     Status;
 
173
 
 
174
  //
 
175
  // Sanity check
 
176
  //
 
177
  if (IsAddressInSmram (LockBoxParameterRestore->Buffer, LockBoxParameterRestore->Length)) {
 
178
    DEBUG ((EFI_D_ERROR, "SmmLockBox Restore address in SMRAM!\n"));
 
179
    LockBoxParameterRestore->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
 
180
    return ;
 
181
  }
 
182
 
 
183
  //
 
184
  // Restore data
 
185
  //
 
186
  if ((LockBoxParameterRestore->Length == 0) && (LockBoxParameterRestore->Buffer == 0)) {
 
187
    Status = RestoreLockBox (
 
188
               &LockBoxParameterRestore->Guid,
 
189
               NULL,
 
190
               NULL
 
191
               );
 
192
  } else {
 
193
    Status = RestoreLockBox (
 
194
               &LockBoxParameterRestore->Guid,
 
195
               (VOID *)(UINTN)LockBoxParameterRestore->Buffer,
 
196
               (UINTN *)&LockBoxParameterRestore->Length
 
197
               );
 
198
  }
 
199
  LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status;
 
200
  return ;
 
201
}
 
202
 
 
203
/**
 
204
  Dispatch function for SMM lock box restore all in place.
 
205
 
 
206
  @param LockBoxParameterRestoreAllInPlace  parameter of lock box restore all in place
 
207
**/
 
208
VOID
 
209
SmmLockBoxRestoreAllInPlace (
 
210
  IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *LockBoxParameterRestoreAllInPlace
 
211
  )
 
212
{
 
213
  EFI_STATUS                     Status;
 
214
 
 
215
  Status = RestoreAllLockBoxInPlace ();
 
216
  LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)Status;
 
217
  return ;
 
218
}
 
219
 
 
220
/**
 
221
  Dispatch function for a Software SMI handler.
 
222
 
 
223
  @param DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().
 
224
  @param Context         Points to an optional handler context which was specified when the
 
225
                         handler was registered.
 
226
  @param CommBuffer      A pointer to a collection of data in memory that will
 
227
                         be conveyed from a non-SMM environment into an SMM environment.
 
228
  @param CommBufferSize  The size of the CommBuffer.
 
229
 
 
230
  @retval EFI_SUCCESS Command is handled successfully.
 
231
 
 
232
**/
 
233
EFI_STATUS
 
234
EFIAPI
 
235
SmmLockBoxHandler (
 
236
  IN EFI_HANDLE  DispatchHandle,
 
237
  IN CONST VOID  *Context         OPTIONAL,
 
238
  IN OUT VOID    *CommBuffer      OPTIONAL,
 
239
  IN OUT UINTN   *CommBufferSize  OPTIONAL
 
240
  )
 
241
{
 
242
  EFI_SMM_LOCK_BOX_PARAMETER_HEADER *LockBoxParameterHeader;
 
243
 
 
244
  DEBUG ((EFI_D_ERROR, "SmmLockBox SmmLockBoxHandler Enter\n"));
 
245
 
 
246
  LockBoxParameterHeader = (EFI_SMM_LOCK_BOX_PARAMETER_HEADER *)((UINTN)CommBuffer);
 
247
 
 
248
  LockBoxParameterHeader->ReturnStatus = (UINT64)-1;
 
249
 
 
250
  DEBUG ((EFI_D_ERROR, "SmmLockBox LockBoxParameterHeader - %x\n", (UINTN)LockBoxParameterHeader));
 
251
 
 
252
  DEBUG ((EFI_D_ERROR, "SmmLockBox Command - %x\n", (UINTN)LockBoxParameterHeader->Command));
 
253
 
 
254
  switch (LockBoxParameterHeader->Command) {
 
255
  case EFI_SMM_LOCK_BOX_COMMAND_SAVE:
 
256
    SmmLockBoxSave ((EFI_SMM_LOCK_BOX_PARAMETER_SAVE *)(UINTN)LockBoxParameterHeader);
 
257
    break;
 
258
  case EFI_SMM_LOCK_BOX_COMMAND_UPDATE:
 
259
    SmmLockBoxUpdate ((EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *)(UINTN)LockBoxParameterHeader);
 
260
    break;
 
261
  case EFI_SMM_LOCK_BOX_COMMAND_RESTORE:
 
262
    SmmLockBoxRestore ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)(UINTN)LockBoxParameterHeader);
 
263
    break;
 
264
  case EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES:
 
265
    SmmLockBoxSetAttributes ((EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *)(UINTN)LockBoxParameterHeader);
 
266
    break;
 
267
  case EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE:
 
268
    SmmLockBoxRestoreAllInPlace ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)(UINTN)LockBoxParameterHeader);
 
269
    break;
 
270
  default:
 
271
    break;
 
272
  }
 
273
 
 
274
  LockBoxParameterHeader->Command = (UINT32)-1;
 
275
 
 
276
  DEBUG ((EFI_D_ERROR, "SmmLockBox SmmLockBoxHandler Exit\n"));
 
277
 
 
278
  return EFI_SUCCESS;
 
279
}
 
280
 
 
281
/**
 
282
  Smm Ready To Lock event notification handler.
 
283
 
 
284
  It sets a flag indicating that SMRAM has been locked.
 
285
  
 
286
  @param[in] Protocol   Points to the protocol's unique identifier.
 
287
  @param[in] Interface  Points to the interface instance.
 
288
  @param[in] Handle     The handle on which the interface was installed.
 
289
 
 
290
  @retval EFI_SUCCESS   Notification handler runs successfully.
 
291
 **/
 
292
EFI_STATUS
 
293
EFIAPI
 
294
SmmReadyToLockEventNotify (
 
295
  IN CONST EFI_GUID  *Protocol,
 
296
  IN VOID            *Interface,
 
297
  IN EFI_HANDLE      Handle
 
298
  )
 
299
{
 
300
  mLocked = TRUE;
 
301
  return EFI_SUCCESS;
 
302
}
 
303
 
 
304
/**
 
305
  Entry Point for LockBox SMM driver.
 
306
 
 
307
  @param[in] ImageHandle  Image handle of this driver.
 
308
  @param[in] SystemTable  A Pointer to the EFI System Table.
 
309
 
 
310
  @retval EFI_SUCEESS     
 
311
  @return Others          Some error occurs.
 
312
**/
 
313
EFI_STATUS
 
314
EFIAPI
 
315
SmmLockBoxEntryPoint (
 
316
  IN EFI_HANDLE        ImageHandle,
 
317
  IN EFI_SYSTEM_TABLE  *SystemTable
 
318
  )
 
319
{
 
320
  EFI_STATUS                    Status;
 
321
  EFI_HANDLE                    DispatchHandle;
 
322
  VOID                          *Registration;
 
323
  EFI_SMM_ACCESS2_PROTOCOL      *SmmAccess;
 
324
  UINTN                         Size;
 
325
 
 
326
  //
 
327
  // Get SMRAM information
 
328
  //
 
329
  Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);
 
330
  ASSERT_EFI_ERROR (Status);
 
331
 
 
332
  Size = 0;
 
333
  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);
 
334
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
 
335
 
 
336
  Status = gSmst->SmmAllocatePool (
 
337
                    EfiRuntimeServicesData,
 
338
                    Size,
 
339
                    (VOID **)&mSmramRanges
 
340
                    );
 
341
  ASSERT_EFI_ERROR (Status);
 
342
 
 
343
  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);
 
344
  ASSERT_EFI_ERROR (Status);
 
345
 
 
346
  mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
 
347
 
 
348
  //
 
349
  // Register LockBox communication handler
 
350
  //
 
351
  Status = gSmst->SmiHandlerRegister (
 
352
                    SmmLockBoxHandler,
 
353
                    &gEfiSmmLockBoxCommunicationGuid,
 
354
                    &DispatchHandle
 
355
                    );
 
356
  ASSERT_EFI_ERROR (Status);
 
357
 
 
358
  //
 
359
  // Register SMM Ready To Lock Protocol notification
 
360
  //
 
361
  Status = gSmst->SmmRegisterProtocolNotify (
 
362
                    &gEfiSmmReadyToLockProtocolGuid,
 
363
                    SmmReadyToLockEventNotify,
 
364
                    &Registration
 
365
                    );
 
366
  ASSERT_EFI_ERROR (Status);
 
367
 
 
368
  //
 
369
  // Install NULL to DXE data base as notify
 
370
  //
 
371
  ImageHandle = NULL;
 
372
  Status = gBS->InstallProtocolInterface (
 
373
                  &ImageHandle,
 
374
                  &gEfiLockBoxProtocolGuid,
 
375
                  EFI_NATIVE_INTERFACE,
 
376
                  NULL
 
377
                  );
 
378
  ASSERT_EFI_ERROR (Status);
 
379
 
 
380
  return Status;
 
381
}