MdeModulePkg/CapsuleRuntimeDxe: clean the capsule payload to DRAM
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 12 Jun 2018 10:37:08 +0000 (12:37 +0200)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Fri, 15 Jun 2018 16:17:44 +0000 (18:17 +0200)
commite077a93dc6441dcac3b48b7d793e367c6fa177ed
tree24a5b8c00f34a9d72727ea20f60d600d34bae543
parent488aab257f7072717a0b376d14bd2d41fe475030
MdeModulePkg/CapsuleRuntimeDxe: clean the capsule payload to DRAM

When capsule updates are staged for processing after a warm reboot,
they are copied into memory with the MMU and caches enabled. When
the capsule PEI gets around to coalescing the capsule, the MMU and
caches may still be disabled, and so on architectures where uncached
accesses are incoherent with the caches (such as ARM and AARCH64),
we need to ensure that the data passed into UpdateCapsule() is
written back to main memory before performing the warm reboot.

Unfortunately, on ARM, the only type of cache maintenance instructions
that are suitable for this purpose operate on virtual addresses only,
and given that the UpdateCapsule() prototype includes the physical
address of a linked list of scatter/gather data structures that are
mapped at an address that is unknown to the firmware (and may not even
be mapped at all when UpdateCapsule() is invoked), we can only perform
this cache maintenance at boot time. Fortunately, both Windows and Linux
only invoke UpdateCapsule() before calling ExitBootServices(), so this
is not a problem in practice.

In the future, we may propose adding a secure firmware service that
permits performing the cache maintenance at OS runtime, in which case
this code may be enhanced to call that service if available. For now,
we just fail any UpdateCapsule() calls performed at OS runtime on ARM.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CapsuleReset.c [new file with mode: 0644]
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleReset.c [new file with mode: 0644]
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.h [new file with mode: 0644]