summaryrefslogtreecommitdiff
path: root/OvmfPkg
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2014-03-13 17:35:03 +0000
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2014-03-13 17:35:03 +0000
commit1c9135a288234d15086a5b6f267dd4822d044064 (patch)
treed6df38a8ea55b105a91f01cb611aa6d6adc2a060 /OvmfPkg
parentde5ae37bb23a67f936a9671e8a78c40f06fd5392 (diff)
downloadedk2-platforms-1c9135a288234d15086a5b6f267dd4822d044064.tar.xz
OvmfPkg: BDS: QemuBootOrder: don't leak unreferenced boot options
The Boot#### variables that have become unreferenced in the new BootOrder variable won't ever be automatically reused for booting. They are "unreachable" resources that take up room in the variable store. Make an effort to remove them. This should plug the leak which, given sufficient reboots, exhausts the variable store with stale Boot#### variables and renders the VM unbootable. Reported-by: Michael Chang <mchang@suse.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15327 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'OvmfPkg')
-rw-r--r--OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c54
1 files changed, 48 insertions, 6 deletions
diff --git a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c b/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c
index c8379b8fca..7f81fc35a0 100644
--- a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c
+++ b/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c
@@ -1121,6 +1121,47 @@ BootOrderComplete (
/**
+ Delete Boot#### variables that stand for such active boot options that have
+ been dropped (ie. have not been selected by either matching or "survival
+ policy").
+
+ @param[in] ActiveOption The array of active boot options to scan. Each
+ entry not marked as appended will trigger the
+ deletion of the matching Boot#### variable.
+
+ @param[in] ActiveCount Number of elements in ActiveOption.
+**/
+STATIC
+VOID
+PruneBootVariables (
+ IN CONST ACTIVE_OPTION *ActiveOption,
+ IN UINTN ActiveCount
+ )
+{
+ UINTN Idx;
+
+ for (Idx = 0; Idx < ActiveCount; ++Idx) {
+ if (!ActiveOption[Idx].Appended) {
+ CHAR16 VariableName[9];
+
+ UnicodeSPrintAsciiFormat (VariableName, sizeof VariableName, "Boot%04x",
+ ActiveOption[Idx].BootOption->BootCurrent);
+
+ //
+ // "The space consumed by the deleted variable may not be available until
+ // the next power cycle", but that's good enough.
+ //
+ gRT->SetVariable (VariableName, &gEfiGlobalVariableGuid,
+ 0, // Attributes, 0 means deletion
+ 0, // DataSize, 0 means deletion
+ NULL // Data
+ );
+ }
+ }
+}
+
+
+/**
Set the boot order based on configuration retrieved from QEMU.
@@ -1269,12 +1310,13 @@ SetBootOrderFromQemu (
BootOrder.Produced * sizeof (*BootOrder.Data),
BootOrder.Data
);
- DEBUG ((
- DEBUG_INFO,
- "%a: setting BootOrder: %a\n",
- __FUNCTION__,
- Status == EFI_SUCCESS ? "success" : "error"
- ));
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: setting BootOrder: %r\n", __FUNCTION__, Status));
+ goto ErrorFreeActiveOption;
+ }
+
+ DEBUG ((DEBUG_INFO, "%a: setting BootOrder: success\n", __FUNCTION__));
+ PruneBootVariables (ActiveOption, ActiveCount);
}
ErrorFreeActiveOption: