Skip to content

Commit 4521642

Browse files
committed
ArmPkg/Library: optimise StandaloneMmMmuLib with FF-A v1.3
commit 4ca452c ("ArmPkg/Library: Update StandaloneMmuLib with FF-A v1.2 with page granularity") introduced page-granular memory permission updates to fix the StandaloneMm load failure. However, this approach results in issuing an SMC call per page when updating permissions over a region. Since FF-A Memory Management Protocol v1.3 [0], FFA_MEM_PERM_GET has been updated to return the number of contiguous pages that share the same memory permission starting from a base address. With this change, update memory permissions in bulk (per contiguous page range) to reduce the number of SMC calls, leveraging FF-A Memory Management Protocol v1.3 [0]. Link: https://developer.arm.com/documentation/den0140/latest [0] Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
1 parent 76406ef commit 4521642

File tree

1 file changed

+102
-19
lines changed

1 file changed

+102
-19
lines changed

ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.c

Lines changed: 102 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
StMM Core invokes this library before constructors are called and before the
3636
StMM image itself is relocated.
3737
38+
@param[out] MajorVersion Major Version of ABI.
39+
@param[out] MinorVersion Minor Version of ABI.
40+
3841
@retval TRUE Use FF-A MemPerm ABIs.
3942
@retval FALSE Use MM MemPerm ABIs.
4043
@@ -43,20 +46,21 @@ STATIC
4346
BOOLEAN
4447
EFIAPI
4548
IsFfaMemoryAbiSupported (
46-
IN VOID
49+
OUT UINT16 *MajorVersion,
50+
OUT UINT16 *MinorVersion
4751
)
4852
{
4953
EFI_STATUS Status;
50-
UINT16 CurrentMajorVersion;
51-
UINT16 CurrentMinorVersion;
54+
55+
*MajorVersion = 0;
56+
*MinorVersion = 0;
5257

5358
Status = ArmFfaLibGetVersion (
5459
ARM_FFA_MAJOR_VERSION,
5560
ARM_FFA_MINOR_VERSION,
56-
&CurrentMajorVersion,
57-
&CurrentMinorVersion
61+
MajorVersion,
62+
MinorVersion
5863
);
59-
6064
if (EFI_ERROR (Status)) {
6165
return FALSE;
6266
}
@@ -147,8 +151,13 @@ SendMemoryPermissionRequest (
147151
/** Request the permission attributes of a memory region from S-EL0.
148152
149153
@param [in] UseFfaAbis Use FF-A abis or not.
154+
@param [in] AbiMajorVersion ABI Major Version
155+
@param [in] AbiMinorVersion ABI Minor Version
150156
@param [in] BaseAddress Base address for the memory region.
157+
@param [in] Length Size of memory region.
151158
@param [out] MemoryAttributes Pointer to return the memory attributes.
159+
@param [out] PageCount Number of page sharing the same attribute from
160+
BaseAddress
152161
153162
@retval EFI_SUCCESS Request successfull.
154163
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@@ -165,8 +174,12 @@ STATIC
165174
EFI_STATUS
166175
GetMemoryPermissions (
167176
IN BOOLEAN UseFfaAbis,
177+
IN UINT16 AbiMajorVersion,
178+
IN UINT16 AbiMinorVersion,
168179
IN EFI_PHYSICAL_ADDRESS BaseAddress,
169-
OUT UINT32 *MemoryAttributes
180+
IN UINT64 Length,
181+
OUT UINT32 *MemoryAttributes,
182+
OUT UINT32 *PageCount
170183
)
171184
{
172185
EFI_STATUS Status;
@@ -187,11 +200,33 @@ GetMemoryPermissions (
187200
SvcArgs.Arg0 = Fid;
188201
SvcArgs.Arg1 = BaseAddress;
189202

203+
if (UseFfaAbis && ((AbiMajorVersion > 1) || (AbiMinorVersion > 2))) {
204+
/*
205+
* The input page count is encoded as (page count - 1),
206+
* so subtract 1 from the actual page count.
207+
* See the FF-A Memory Management Protocol Spec version 1.3-ALP1
208+
* 2.8 FFA_MEM_PERM_GET
209+
*/
210+
SvcArgs.Arg2 = EFI_SIZE_TO_PAGES (Length) - 1;
211+
}
212+
190213
Status = SendMemoryPermissionRequest (UseFfaAbis, &SvcArgs, &Ret);
191214
if (EFI_ERROR (Status)) {
192215
*MemoryAttributes = 0;
216+
*PageCount = 0;
193217
} else {
194218
*MemoryAttributes = Ret;
219+
if (UseFfaAbis && ((AbiMajorVersion > 1) || (AbiMinorVersion > 2))) {
220+
/*
221+
* The output page count is encoded as (page count - 1),
222+
* so add 1 to get the actual page count.
223+
* See the FF-A Memory Management Protocol Spec version 1.3-ALP1
224+
* 2.8 FFA_MEM_PERM_GET
225+
*/
226+
*PageCount = SvcArgs.Arg3 + 1;
227+
} else {
228+
*PageCount = 1;
229+
}
195230
}
196231

197232
return Status;
@@ -253,17 +288,29 @@ ArmSetMemoryRegionNoExec (
253288
UINT32 MemoryAttributes;
254289
UINT32 PermissionRequest;
255290
BOOLEAN UseFfaAbis;
291+
UINT16 MajorVersion;
292+
UINT16 MinorVersion;
256293
UINTN Size;
294+
UINT32 PageCount;
257295

258-
UseFfaAbis = IsFfaMemoryAbiSupported ();
259-
Size = EFI_PAGE_SIZE;
296+
UseFfaAbis = IsFfaMemoryAbiSupported (&MajorVersion, &MinorVersion);
260297

261298
while (Length > 0) {
262-
Status = GetMemoryPermissions (UseFfaAbis, BaseAddress, &MemoryAttributes);
299+
Status = GetMemoryPermissions (
300+
UseFfaAbis,
301+
MajorVersion,
302+
MinorVersion,
303+
BaseAddress,
304+
Length,
305+
&MemoryAttributes,
306+
&PageCount
307+
);
263308
if (EFI_ERROR (Status)) {
264309
break;
265310
}
266311

312+
Size = EFI_PAGES_TO_SIZE (PageCount);
313+
267314
if (UseFfaAbis) {
268315
PermissionRequest = ARM_FFA_SET_MEM_ATTR_MAKE_PERM_REQUEST (
269316
MemoryAttributes,
@@ -307,17 +354,29 @@ ArmClearMemoryRegionNoExec (
307354
UINT32 MemoryAttributes;
308355
UINT32 PermissionRequest;
309356
BOOLEAN UseFfaAbis;
357+
UINT16 MajorVersion;
358+
UINT16 MinorVersion;
310359
UINTN Size;
360+
UINT32 PageCount;
311361

312-
UseFfaAbis = IsFfaMemoryAbiSupported ();
313-
Size = EFI_PAGE_SIZE;
362+
UseFfaAbis = IsFfaMemoryAbiSupported (&MajorVersion, &MinorVersion);
314363

315364
while (Length > 0) {
316-
Status = GetMemoryPermissions (UseFfaAbis, BaseAddress, &MemoryAttributes);
365+
Status = GetMemoryPermissions (
366+
UseFfaAbis,
367+
MajorVersion,
368+
MinorVersion,
369+
BaseAddress,
370+
Length,
371+
&MemoryAttributes,
372+
&PageCount
373+
);
317374
if (EFI_ERROR (Status)) {
318375
break;
319376
}
320377

378+
Size = EFI_PAGES_TO_SIZE (PageCount);
379+
321380
if (UseFfaAbis) {
322381
PermissionRequest = ARM_FFA_SET_MEM_ATTR_MAKE_PERM_REQUEST (
323382
MemoryAttributes,
@@ -361,17 +420,29 @@ ArmSetMemoryRegionReadOnly (
361420
UINT32 MemoryAttributes;
362421
UINT32 PermissionRequest;
363422
BOOLEAN UseFfaAbis;
423+
UINT16 MajorVersion;
424+
UINT16 MinorVersion;
364425
UINTN Size;
426+
UINT32 PageCount;
365427

366-
UseFfaAbis = IsFfaMemoryAbiSupported ();
367-
Size = EFI_PAGE_SIZE;
428+
UseFfaAbis = IsFfaMemoryAbiSupported (&MajorVersion, &MinorVersion);
368429

369430
while (Length > 0) {
370-
Status = GetMemoryPermissions (UseFfaAbis, BaseAddress, &MemoryAttributes);
431+
Status = GetMemoryPermissions (
432+
UseFfaAbis,
433+
MajorVersion,
434+
MinorVersion,
435+
BaseAddress,
436+
Length,
437+
&MemoryAttributes,
438+
&PageCount
439+
);
371440
if (EFI_ERROR (Status)) {
372441
break;
373442
}
374443

444+
Size = EFI_PAGES_TO_SIZE (PageCount);
445+
375446
if (UseFfaAbis) {
376447
PermissionRequest = ARM_FFA_SET_MEM_ATTR_MAKE_PERM_REQUEST (
377448
ARM_FFA_SET_MEM_ATTR_DATA_PERM_RO,
@@ -415,17 +486,29 @@ ArmClearMemoryRegionReadOnly (
415486
UINT32 MemoryAttributes;
416487
UINT32 PermissionRequest;
417488
BOOLEAN UseFfaAbis;
489+
UINT16 MajorVersion;
490+
UINT16 MinorVersion;
418491
UINTN Size;
492+
UINT32 PageCount;
419493

420-
UseFfaAbis = IsFfaMemoryAbiSupported ();
421-
Size = EFI_PAGE_SIZE;
494+
UseFfaAbis = IsFfaMemoryAbiSupported (&MajorVersion, &MinorVersion);
422495

423496
while (Length > 0) {
424-
Status = GetMemoryPermissions (UseFfaAbis, BaseAddress, &MemoryAttributes);
497+
Status = GetMemoryPermissions (
498+
UseFfaAbis,
499+
MajorVersion,
500+
MinorVersion,
501+
BaseAddress,
502+
Length,
503+
&MemoryAttributes,
504+
&PageCount
505+
);
425506
if (EFI_ERROR (Status)) {
426507
break;
427508
}
428509

510+
Size = EFI_PAGES_TO_SIZE (PageCount);
511+
429512
if (UseFfaAbis) {
430513
PermissionRequest = ARM_FFA_SET_MEM_ATTR_MAKE_PERM_REQUEST (
431514
ARM_FFA_SET_MEM_ATTR_DATA_PERM_RW,

0 commit comments

Comments
 (0)