@@ -423,13 +423,16 @@ SetupSmmuV3Cmdq (
423
423
DEBUG ((DEBUG_INFO , "%a: Total CMDQ entries: %d\n" , __FUNCTION__ , (1 << Private -> Features .CmdqEntriesLog2 )));
424
424
425
425
QBase = (EFI_PHYSICAL_ADDRESS )AllocateAlignedPages (EFI_SIZE_TO_PAGES (CmdqSize ), CmdqSize );
426
- ZeroMem ((VOID * )QBase , EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (CmdqSize )));
427
-
428
426
if (!QBase ) {
429
427
DEBUG ((DEBUG_ERROR , "%a: Failed to allocate memory for CMDQ\n" , __FUNCTION__ ));
430
428
return EFI_OUT_OF_RESOURCES ;
431
429
}
432
430
431
+ ZeroMem ((VOID * )QBase , EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (CmdqSize )));
432
+
433
+ // Perform cache maintenance to ensure SMMU sees the updated memory
434
+ WriteBackDataCacheRange ((VOID * )QBase , EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (CmdqSize )));
435
+
433
436
DEBUG ((DEBUG_INFO , "%a: Memory allocated at %lx for CMDQ\n" , __FUNCTION__ , QBase ));
434
437
Private -> CmdQueue .QBase = QBase ;
435
438
@@ -448,6 +451,9 @@ SetupSmmuV3Cmdq (
448
451
MmioWrite32 (Private -> CmdQueue .ConsRegBase , 0 );
449
452
MmioWrite32 (Private -> CmdQueue .ProdRegBase , 0 );
450
453
454
+ // Ensure memory ordering
455
+ ArmDataSynchronizationBarrier ();
456
+
451
457
return EFI_SUCCESS ;
452
458
}
453
459
@@ -481,13 +487,16 @@ SetupSmmuV3Evtq (
481
487
DEBUG ((DEBUG_INFO , "%a: Total EVTQ entries: %d\n" , __FUNCTION__ , (1 << Private -> Features .EvtqEntriesLog2 )));
482
488
483
489
QBase = (EFI_PHYSICAL_ADDRESS )AllocateAlignedPages (EFI_SIZE_TO_PAGES (EvtqSize ), EvtqSize );
484
- ZeroMem ((VOID * )QBase , EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (EvtqSize )));
485
-
486
490
if (!QBase ) {
487
491
DEBUG ((DEBUG_ERROR , "%a: Failed to allocate memory for EVTQ\n" , __FUNCTION__ ));
488
492
return EFI_OUT_OF_RESOURCES ;
489
493
}
490
494
495
+ ZeroMem ((VOID * )QBase , EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (EvtqSize )));
496
+
497
+ // Perform cache maintenance to ensure SMMU sees the updated memory
498
+ WriteBackDataCacheRange ((VOID * )QBase , EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (EvtqSize )));
499
+
491
500
DEBUG ((DEBUG_INFO , "%a: Memory allocated at %lx for EVTQ\n" , __FUNCTION__ , QBase ));
492
501
Private -> EvtQueue .QBase = QBase ;
493
502
@@ -506,6 +515,9 @@ SetupSmmuV3Evtq (
506
515
MmioWrite32 (Private -> EvtQueue .ConsRegBase , 0 );
507
516
MmioWrite32 (Private -> EvtQueue .ProdRegBase , 0 );
508
517
518
+ // Ensure memory ordering
519
+ ArmDataSynchronizationBarrier ();
520
+
509
521
return EFI_SUCCESS ;
510
522
}
511
523
@@ -559,7 +571,10 @@ WriteSte (
559
571
SteEntry [Index ] = SteData [Index ];
560
572
}
561
573
562
- // Ensure written data (STE) is observable to SMMU controller by performing DSB
574
+ // Perform cache maintenance to ensure SMMU sees the updated STE
575
+ WriteBackDataCacheRange ((VOID * )SteEntry , SMMU_V3_STRTAB_ENTRY_SIZE );
576
+
577
+ // Ensure memory ordering
563
578
ArmDataSynchronizationBarrier ();
564
579
}
565
580
@@ -839,6 +854,9 @@ PushEntryToCmdq (
839
854
CmdqEntry [Index ] = CmdDword [Index ];
840
855
}
841
856
857
+ // Perform cache maintenance to ensure SMMU sees the updated command
858
+ WriteBackDataCacheRange ((VOID * )CmdqEntry , SMMU_V3_CMD_SIZE );
859
+
842
860
// Ensure data is observable to SMMU
843
861
ArmDataSynchronizationBarrier ();
844
862
}
@@ -1723,13 +1741,11 @@ CreateStage2Ste (
1723
1741
return EFI_OUT_OF_RESOURCES ;
1724
1742
}
1725
1743
1726
- // Invalidate cache before page table setup to ensure working with
1727
- // clean memory state and prevent stale cache entries from affecting
1728
- // page table population
1729
- InvalidateDataCacheRange ((VOID * )Ttbr , EFI_PAGE_SIZE );
1730
-
1731
1744
ZeroMem ((VOID * )Ttbr , EFI_PAGE_SIZE );
1732
1745
1746
+ // Perform cache maintenance to ensure SMMU sees the updated page table
1747
+ WriteBackDataCacheRange ((VOID * )Ttbr , EFI_PAGE_SIZE );
1748
+
1733
1749
CopyMem (SteS2TtbAddr , & Ttbr , sizeof (EFI_PHYSICAL_ADDRESS ));
1734
1750
1735
1751
SteCount = (1 << Private -> Features .StreamNBits );
@@ -1743,6 +1759,9 @@ CreateStage2Ste (
1743
1759
1744
1760
Ste [3 ] |= BIT_FIELD_SET (TtbrTemp , SMMU_V3_STE_S2TTB_MASK , SMMU_V3_STE_S2TTB_SHIFT );
1745
1761
1762
+ // Perform cache maintenance to ensure SMMU sees the updated STE
1763
+ WriteBackDataCacheRange ((VOID * )Ste , SMMU_V3_STRTAB_ENTRY_SIZE );
1764
+
1746
1765
return EFI_SUCCESS ;
1747
1766
}
1748
1767
@@ -1889,7 +1908,7 @@ InstallBlockPte (
1889
1908
DEBUG ((DEBUG_INFO , "%a: L%u entry address: 0x%lx\n" , __FUNCTION__ , Level , (UINT64 )Pte ));
1890
1909
DEBUG ((DEBUG_INFO , "%a: L%u entry value: 0x%lx\n" , __FUNCTION__ , Level , * Pte ));
1891
1910
1892
- InvalidateDataCacheRange ((VOID * )Pte , sizeof (* Pte ));
1911
+ WriteBackDataCacheRange ((VOID * )Pte , sizeof (* Pte ));
1893
1912
1894
1913
DEBUG ((DEBUG_INFO , "%a: Exit Success\n" , __FUNCTION__ ));
1895
1914
return EFI_SUCCESS ;
@@ -1929,7 +1948,7 @@ InstallTablePte (
1929
1948
DEBUG ((DEBUG_INFO , "%a: L%u entry address: 0x%lx\n" , __FUNCTION__ , Level , (UINT64 )TtPte ));
1930
1949
DEBUG ((DEBUG_INFO , "%a: L%u entry value: 0x%lx\n" , __FUNCTION__ , Level , * TtPte ));
1931
1950
1932
- InvalidateDataCacheRange ((VOID * )TtPte , sizeof (* TtPte ));
1951
+ WriteBackDataCacheRange ((VOID * )TtPte , sizeof (* TtPte ));
1933
1952
1934
1953
DEBUG ((DEBUG_INFO , "%a: Exit Success\n" , __FUNCTION__ ));
1935
1954
return EFI_SUCCESS ;
@@ -2151,12 +2170,8 @@ SmmuV3EnableProtection (
2151
2170
break ;
2152
2171
}
2153
2172
2154
- // Invalidate cache before page table setup to ensure working with
2155
- // clean memory state and prevent stale cache entries from affecting
2156
- // page table population
2157
- InvalidateDataCacheRange ((VOID * )TtNext , EFI_PAGE_SIZE );
2158
-
2159
2173
ZeroMem ((VOID * )TtNext , EFI_PAGE_SIZE );
2174
+ WriteBackDataCacheRange ((VOID * )TtNext , EFI_PAGE_SIZE );
2160
2175
2161
2176
DEBUG ((DEBUG_INFO , "%a: Allocated new translation table at:0x%p\n" , __FUNCTION__ , (VOID * )TtNext ));
2162
2177
Status = InstallTablePte (TtNext , Lvl , TtPte );
0 commit comments