[edk2-devel] [RFC PATCH 8/9] OvmfPkg/AmdSev: Add Migration Handler entry point
Tobin Feldman-Fitzthum
tobin at linux.ibm.com
Wed Aug 18 21:20:47 UTC 2021
The Migration Handler runs in the mirror VM. The MH is started
directly by the hypervisor. SetupMigrationHandler runs in the main
VM and sets up the migration entry point. The HV starts execution
of the mirror vCPU at the entry point, which trampolines to
MigrationHandlerMain
Signed-off-by: Tobin Feldman-Fitzthum <tobin at linux.ibm.com>
---
OvmfPkg/OvmfPkg.dec | 3 ++
OvmfPkg/AmdSev/AmdSevX64.fdf | 3 ++
.../ConfidentialMigrationDxe.inf | 2 +
.../ConfidentialMigrationPei.inf | 2 +
.../ConfidentialMigrationDxe.c | 48 +++++++++++++++++
.../ConfidentialMigrationPei.c | 6 +++
.../MigrationEntryPoint.nasm | 51 +++++++++++++++++++
7 files changed, 115 insertions(+)
create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/MigrationEntryPoint.nasm
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 1252582c99..c6e07accf6 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -336,6 +336,9 @@
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase|0x0|UINT32|0x4b
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize|0x0|UINT32|0x4c
+ gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntryBase|0x0|UINT32|0x4d
+ gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntrySize|0x0|UINT32|0x4e
+
[PcdsDynamic, PcdsDynamicEx]
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index a8e296e641..8687fadfcc 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -74,6 +74,9 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.P
0x020000|0x003000
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase|gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize
+0x023000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntryBase|gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntrySize
+
0x120000|0x0E0000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
FV = PEIFV
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index 42875095fc..b879037586 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -16,6 +16,7 @@
[Sources]
ConfidentialMigrationDxe.c
VirtualMemory.h
+ MigrationEntryPoint.nasm
[Packages]
MdePkg/MdePkg.dec
@@ -31,6 +32,7 @@
gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntryBase
[Depex]
TRUE
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
index 918cf22abd..6233b82cc2 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
@@ -30,6 +30,8 @@
[FixedPcd]
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntryBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntrySize
[Depex]
TRUE
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index 2de35a7bb1..5e96206d17 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -38,11 +38,23 @@ typedef volatile struct {
UINT32 Done;
} MH_COMMAND_PARAMETERS;
+//
+// Addresses to be used in the entry point
+//
+typedef struct {
+ UINT32 Cr3;
+ UINT64 StackBase;
+ UINT64 MhBase;
+} ENTRY_ADDRS;
+
//
// Offset for non-cbit mapping.
//
#define UNENC_VIRT_ADDR_BASE 0xffffff8000000000ULL
+void MigrationHandlerEntryPoint(void);
+void MigrationHandlerEntryPoint64(void);
+
STATIC PAGE_TABLE_POOL *mPageTablePool = NULL;
PHYSICAL_ADDRESS mMigrationHandlerPageTables = 0;
PHYSICAL_ADDRESS mMigrationHandlerStackBase = 0;
@@ -193,6 +205,16 @@ SetupMigrationHandler (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
+ UINT32 LongModeOffset;
+ UINT32 EntryAddrsOffset;
+ UINT32 GdtOffset;
+ IA32_DESCRIPTOR GdtPtr;
+ UINT64 EntryPoint;
+ ENTRY_ADDRS *EntryData;
+
+ LongModeOffset = 0x200;
+ EntryAddrsOffset = 0x400;
+ GdtOffset = 0x600;
if (!PcdGetBool(PcdStartConfidentialMigrationHandler)) {
return 0;
@@ -205,6 +227,32 @@ SetupMigrationHandler (
PrepareMigrationHandlerPageTables ();
+ //
+ // Copy Migration Handler entry point to a known location.
+ //
+ EntryPoint = PcdGet32 (PcdConfidentialMigrationEntryBase);
+ CopyMem ((void *)EntryPoint, MigrationHandlerEntryPoint, 0x50);
+
+ CopyMem ((void *)(EntryPoint + LongModeOffset),
+ MigrationHandlerEntryPoint64, 0x50);
+
+ //
+ // Copy Migration Handler GDT to a known location.
+ //
+ AsmReadGdtr (&GdtPtr);
+ CopyMem ((void *)(EntryPoint + GdtOffset), (void *)GdtPtr.Base,
+ GdtPtr.Limit);
+
+ //
+ // Populate entry point with address of page tables, stack,
+ // and MigrationHandlerMain
+ //
+ EntryData = (void *)(EntryPoint + EntryAddrsOffset);
+
+ EntryData->Cr3 = mMigrationHandlerPageTables;
+ EntryData->StackBase = mMigrationHandlerStackBase;
+ EntryData->MhBase = (UINT64)MigrationHandlerMain;
+
//
// If VM is migration target, wait until hypervisor modifies CPU state
// and restarts execution.
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c
index ce304bc07b..5371ef23a9 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c
@@ -21,5 +21,11 @@ InitializeConfidentialMigrationPei (
EfiRuntimeServicesData
);
+ BuildMemoryAllocationHob (
+ PcdGet32 (PcdConfidentialMigrationEntryBase),
+ PcdGet32 (PcdConfidentialMigrationEntrySize),
+ EfiRuntimeServicesData
+ );
+
return EFI_SUCCESS;
}
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/MigrationEntryPoint.nasm b/OvmfPkg/AmdSev/ConfidentialMigration/MigrationEntryPoint.nasm
new file mode 100644
index 0000000000..9375771b88
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/MigrationEntryPoint.nasm
@@ -0,0 +1,51 @@
+; Entrypoint for Migration Handler
+
+ DEFAULT REL
+ SECTION .text
+
+%define ENABLE_DEBUG 1
+%define X86_CR0_PG BIT31
+%define X86_EFER_LME BIT8
+%define X86_CR4_PAE BIT5
+
+%define ENTRY_BASE FixedPcdGet32 (PcdConfidentialMigrationEntryBase)
+
+%define LONG_MODE_OFFSET 0x200;
+%define ENTRY_ADDRS_OFFSET 0x400
+%define GDT_OFFSET 0x600
+
+%define LONG_MODE_ADDR ENTRY_BASE + LONG_MODE_OFFSET
+%define LINEAR_CODE64_SEL 0x38
+
+BITS 32
+
+global ASM_PFX(MigrationHandlerEntryPoint)
+ASM_PFX(MigrationHandlerEntryPoint):
+
+ ; CR3
+ mov edi, [ENTRY_BASE + ENTRY_ADDRS_OFFSET]
+ mov cr3, edi
+
+ ; EFER.LME
+ mov ecx, 0xc0000080
+ rdmsr
+ bts eax, 8
+ wrmsr
+
+ ; CR0.PG
+ mov eax, cr0
+ bts eax, 31
+ mov cr0, eax
+
+ ; Far jump to enter long mode
+ jmp LINEAR_CODE64_SEL:LONG_MODE_ADDR
+
+BITS 64
+global ASM_PFX(MigrationHandlerEntryPoint64)
+ASM_PFX(MigrationHandlerEntryPoint64):
+
+ ; RSP
+ mov rsp, [ENTRY_BASE + ENTRY_ADDRS_OFFSET + 0x8]
+
+ ; Jump to MH
+ jmp [ENTRY_BASE + ENTRY_ADDRS_OFFSET + 0x10]
--
2.20.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#79526): https://edk2.groups.io/g/devel/message/79526
Mute This Topic: https://groups.io/mt/84983099/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-
More information about the edk2-devel-archive
mailing list