From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (NAM11-CO1-obe.outbound.protection.outlook.com [40.107.220.74]) by mx.groups.io with SMTP id smtpd.web11.95.1627384628071996791 for ; Tue, 27 Jul 2021 04:17:08 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@amd.com header.s=selector1 header.b=sllS/UPN; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: amd.com, ip: 40.107.220.74, mailfrom: brijesh.singh@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ZHllXxpLtrkHGzhAIv38RzuNIZr8Z3IiRNXWYz9sd5d6GQu5to1fbU2mNHsIK9423pu4nNU5mJjo8KVmvU4o1umCxr/YyF0T4C+mqG6Gv72qefiK5ZokfU6x7PqYDH/7fQ+ix+u+W5hrp1WMuSK0I6ePbPcElyH4weaCmuQ8BMTQ8Ek4NoULesHP7djrUIyzY1SfieRAcacapgqUxoKc4VqIqgze1Kw9vZ/iNDNIqdaeOd3oCIoUIn1Sk2GwDoEaSvJ/egvliWs6BJ+GwmZI5Ohko/yzXfwlQVM5eZbhWBI3PSobQvu8liQu9tQ2U4FR6ptTi+HOcSknAYWOufm7Jg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LSvqNuT0TDYhkD3uCrZhTz5JCpcSwLVH2r97WDIr1S4=; b=ezUvgfkOuWM0m98lCjIKpI/TpNaLsOdtgI8VKkKcMw4L3G3OSNjlqm5/NtY5dpbJrm37jokyFDfypZKzieBd2h2CdOUtnaCvOPG+qh5g3M+S4Ruo5BOuiflW268ks/whRfz3UOxy7nE7boZTEQsRXKh3/r5bAWM69ejunkt5Xe+Z1oFmTN9cL48RaN24bSSb2dhFboUmeL/pvvXu8KwavvrRpOZ2hLOeFhofy4+O1seKF2aQtmj+uwPrTAwjGsU3/SwnYTdWjCJpkc2WVD8KPX7Q4UlwMp/rk9g/Y24RHOVh6L4nnM3cRX9CYS6oYVuk0Gpc0r0B0gPjGH/mngH15g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LSvqNuT0TDYhkD3uCrZhTz5JCpcSwLVH2r97WDIr1S4=; b=sllS/UPNg1G+g7jg4EqnaPwNj4p0yaNTbD1lCPoatvqjHO/keEzS9Y4vauxb0efaab5/VeD4gRI5EB9UtpDBeGp2zeF1kyqXL8d9z4KhvEdeJWfAG4KJa2tUhqPu3CqXNj2Bzz0qi+f7G0pvorSgjmeXf3eBPQU1qcmt1lvErWw= Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=amd.com; Received: from SN6PR12MB2718.namprd12.prod.outlook.com (2603:10b6:805:6f::22) by SN1PR12MB2415.namprd12.prod.outlook.com (2603:10b6:802:26::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4352.26; Tue, 27 Jul 2021 11:17:06 +0000 Received: from SN6PR12MB2718.namprd12.prod.outlook.com ([fe80::a8a9:2aac:4fd1:88fa]) by SN6PR12MB2718.namprd12.prod.outlook.com ([fe80::a8a9:2aac:4fd1:88fa%3]) with mapi id 15.20.4352.031; Tue, 27 Jul 2021 11:17:06 +0000 From: "Brijesh Singh" To: devel@edk2.groups.io CC: Brijesh Singh , James Bottomley , Min Xu , Jiewen Yao , Tom Lendacky , Jordan Justen , Ard Biesheuvel , Laszlo Ersek , Erdem Aktas Subject: [PATCH 1/3] OvmfPkg/ResetVector: move SEV specific code in a separate file Date: Tue, 27 Jul 2021 06:16:42 -0500 Message-ID: <20210727111644.26332-2-brijesh.singh@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210727111644.26332-1-brijesh.singh@amd.com> References: <20210727111644.26332-1-brijesh.singh@amd.com> X-ClientProxiedBy: SN7PR04CA0014.namprd04.prod.outlook.com (2603:10b6:806:f2::19) To SN6PR12MB2718.namprd12.prod.outlook.com (2603:10b6:805:6f::22) Return-Path: brijesh.singh@amd.com MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from sbrijesh-desktop.amd.com (165.204.77.1) by SN7PR04CA0014.namprd04.prod.outlook.com (2603:10b6:806:f2::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4352.25 via Frontend Transport; Tue, 27 Jul 2021 11:17:05 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2350263e-518e-447e-7039-08d950f0111f X-MS-TrafficTypeDiagnostic: SN1PR12MB2415: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:6108; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: IX+h6TaqdPZx0XaL5R1XMI2fNBc9PgIvUbCWHuMdXjAO3ZEFe2PqPwQ4lBe9rw9Xg7ILzTfV+qPcmIdVoB4JRGWIGdoAA7S1sexqlJ4Kix3b3Vlc+HyHNUyL5a4wHwS7dUBQ3dSMHGL1eJzCBxe/do8RTVANm8I2pqzGIXwbfOvTnMo6/bgzc/u1mWcSVJVgoLtnfv/m1jAYEzDqns6ipAePvOGOutF4j7DbI0nFGZ0V9QzgrEH04co0c6iqQ760m0t12VP+URP6wKNu7Kq/BJvA6zraYpqMTy2tudF6gECPnFGO3ZXYTTkQMUgkx43/VMihhIlC9fbZJLAnjRtybO/H+Xua8lResEbcK0en84jDP4UEgdpD7NfWWyuvkZcveYYgXDXg9RUk/2uzlnvw6/OgXGr6oKCbB9NJZifTp4bFsLPP/IW07vmXaDB1WJCgGsPNglpNeMHuJc5fyFlaeMFrZSBsHtS7vRt/jKGNokQX+vTpwCgoy6l+V29eLXVL5+XOzhkAKRPTbun3NKKlFms4SDFg0E6DAF4BqGMH0X7ywDRuU44JZp9oVp2D4Wpp1OlewUCXAhf4wQMYVSfBIcyqVO+IY6mLBlL8+RGFFY50QO0z8IiXTM1FA1W7/c+MGKVGfNkSIlNpQEl6HhW90s9Y5pR6f6oBKEuaj/mVxhrPgi8JshxyD3F4STSlBStjDOCa+l20vEhC69WPFadFxSoULWVA0f57etbm8tMZ0X9wPLbz82KesdrLaaxNo2rtGDRTG4JHx0RMfzi6prbJeA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SN6PR12MB2718.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(8676002)(186003)(966005)(2616005)(7696005)(6916009)(956004)(316002)(5660300002)(6486002)(52116002)(38350700002)(38100700002)(508600001)(1076003)(30864003)(36756003)(66476007)(19627235002)(26005)(2906002)(66556008)(54906003)(8936002)(6666004)(4326008)(86362001)(83380400001)(44832011)(66946007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?S/yIPLRhEaSPzaQEf1w/9BolZ0xejJDcT8awLrix7xT7IvWvLZHVU1l5hsgc?= =?us-ascii?Q?6GREIi6yqP5IT5aIVl/8vT0tMkypiD/uyRR2ERAl1oiKoANRz36UpAL8diVX?= =?us-ascii?Q?lY3daL0aaOLoIf9HbzRri4PiM8x9OQfCVv/bwoMjye1hYCNsuApmp/LKI8Xx?= =?us-ascii?Q?nUWg2Qo0RsTYLtMnW/ZjsNC36vWXJv/urIuftgHWmjqX05AMVQdsns/XbLCG?= =?us-ascii?Q?mMMKDVUjwoWccHQunZhnYkd9swbe69+K3zpdWVtvUlhcHOauyOt6MrQyxfDD?= =?us-ascii?Q?rvDNXgsmpbRGR79ERSPNsyuzUyF9KUZbohMb8Bd9xq8z1rBUTP41AzwIQ/FE?= =?us-ascii?Q?NunMbx5DoLmlDQgsNKljVa4BRGLBI/uzIezIUtZV5N++lrvbB4xTRvo2oAi3?= =?us-ascii?Q?6rtFHhFQztZaUPzjA59q9Id9BL67lMdwvIjHN2XM/5zowCNbzeOTBfwjrPDG?= =?us-ascii?Q?deAvvMPXhAkf+FINmrIMCDBTEkx2Ukw4rt9CJFut21J8rYeE+8oNeRKAGaM/?= =?us-ascii?Q?18UC+Ggvb66RhhdAvBqi0ZmgD0iPj6Xwolu8b0lRfJGhi7tG9LdzoefB9Z6I?= =?us-ascii?Q?uOEzTdzBcPZ7M7jMK2/Gyk9Jh9bHyKY9BkpSJfcziXwxRKkgW8qZpyObO04w?= =?us-ascii?Q?PEbB+SeN+zPMNeGUHKt8Hy0VuVvO6IkFcxzLt99NkTyAzmWiOy8W/9B5ITDL?= =?us-ascii?Q?D5VYYrfBMOkezcL1SuTVWFk7W376tYGW2tRVJYJS0pPRZILSmCvN9CNiXKZ4?= =?us-ascii?Q?upoZAu3aP46/6kyqAGW7QHvITYOyc/NDCp3cjOXtXx17tgwO+n78xEiA+yLb?= =?us-ascii?Q?oUipBSL9wWbiiN2+QjHwrvMlzIJmUbbuS+nx7B1tJ8MawtujAnj46HXS2mDl?= =?us-ascii?Q?mgnVDU4vZzUH8B/pgm6I5se98my6AAPJ1aAzD+6SWmqerdScg7xkGhdpnJ39?= =?us-ascii?Q?ZYv3B3NkwndlKUGzokFIQjjdYIf4cA/QgCm7wxOkltVt1M0rGJsuUmEDqJOG?= =?us-ascii?Q?ZKb1JjIHR9WBBMJAYOpUWEoPVlxAGjOig9X1KXFFrGGplOUkRWj41x6q2p2m?= =?us-ascii?Q?PnPqLz3j9bNRJ1rCP34mLZrRMlFq8FQa3Yt8sJmtexXV69UBL8qp6RR0fR1W?= =?us-ascii?Q?6SNb8SlRFaVxy4uKpvQJXmY0n1+AbgC7qpB7jgZRPKcAm6jvroLXPhUb0CMs?= =?us-ascii?Q?+ZEGB9tY0NdD3HHlxVR86yqNmOs71i4Wf6EKIMlm4FhPwsymnw2NXQqCxUi2?= =?us-ascii?Q?+flFf4XaV1qEK9RM/nipIMzQ2W8cFDQW29Vn+2ykmhmL/Eq40aB0ct5z68pr?= =?us-ascii?Q?yqRYOHct9zvAfOywSACJa5JH?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2350263e-518e-447e-7039-08d950f0111f X-MS-Exchange-CrossTenant-AuthSource: SN6PR12MB2718.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jul 2021 11:17:06.1920 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 9lh4t4FW68X+i3EiSGx0gSX3Ze3J0IKLn4+mIlPwq1HIt2aOMCsv4Yi57v/HyH17vM/ejLYhx6zjsnMsRlr33A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB2415 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3275 The PageTables64.asm was created to provide routines to set the CR3 register for 64-bit paging. During the SEV support, it grew to include a lot of the SEV stuff. Before adding more SEV features, let's move all the SEV-specific routines into a separate file. No functionality change intended. Cc: James Bottomley Cc: Min Xu Cc: Jiewen Yao Cc: Tom Lendacky Cc: Jordan Justen Cc: Ard Biesheuvel Cc: Laszlo Ersek Cc: Erdem Aktas Suggested-by: Laszlo Ersek Signed-off-by: Brijesh Singh --- .../Ia32/{PageTables64.asm =3D> AmdSev.asm} | 140 ------- OvmfPkg/ResetVector/Ia32/PageTables64.asm | 391 ------------------ OvmfPkg/ResetVector/ResetVector.nasmb | 1 + 3 files changed, 1 insertion(+), 531 deletions(-) copy OvmfPkg/ResetVector/Ia32/{PageTables64.asm =3D> AmdSev.asm} (71%) diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVecto= r/Ia32/AmdSev.asm similarity index 71% copy from OvmfPkg/ResetVector/Ia32/PageTables64.asm copy to OvmfPkg/ResetVector/Ia32/AmdSev.asm index 5fae8986d9da..b32dd3b5d656 100644 --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm +++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm @@ -10,33 +10,6 @@ =20 BITS 32 =20 -%define PAGE_PRESENT 0x01 -%define PAGE_READ_WRITE 0x02 -%define PAGE_USER_SUPERVISOR 0x04 -%define PAGE_WRITE_THROUGH 0x08 -%define PAGE_CACHE_DISABLE 0x010 -%define PAGE_ACCESSED 0x020 -%define PAGE_DIRTY 0x040 -%define PAGE_PAT 0x080 -%define PAGE_GLOBAL 0x0100 -%define PAGE_2M_MBO 0x080 -%define PAGE_2M_PAT 0x01000 - -%define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \ - PAGE_DIRTY + \ - PAGE_READ_WRITE + \ - PAGE_PRESENT) - -%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \ - PAGE_ACCESSED + \ - PAGE_DIRTY + \ - PAGE_READ_WRITE + \ - PAGE_PRESENT) - -%define PAGE_PDP_ATTR (PAGE_ACCESSED + \ - PAGE_READ_WRITE + \ - PAGE_PRESENT) - ; ; SEV-ES #VC exception handler support ; @@ -213,119 +186,6 @@ IsSevEsEnabled: SevEsDisabled: OneTimeCallRet IsSevEsEnabled =20 -; -; Modified: EAX, EBX, ECX, EDX -; -SetCr3ForPageTables64: - - OneTimeCall CheckSevFeatures - xor edx, edx - test eax, eax - jz SevNotActive - - ; If SEV is enabled, C-bit is always above 31 - sub eax, 32 - bts edx, eax - -SevNotActive: - - ; - ; For OVMF, build some initial page tables at - ; PcdOvmfSecPageTablesBase - (PcdOvmfSecPageTablesBase + 0x6000). - ; - ; This range should match with PcdOvmfSecPageTablesSize which is - ; declared in the FDF files. - ; - ; At the end of PEI, the pages tables will be rebuilt into a - ; more permanent location by DxeIpl. - ; - - mov ecx, 6 * 0x1000 / 4 - xor eax, eax -clearPageTablesMemoryLoop: - mov dword[ecx * 4 + PT_ADDR (0) - 4], eax - loop clearPageTablesMemoryLoop - - ; - ; Top level Page Directory Pointers (1 * 512GB entry) - ; - mov dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDP_ATTR - mov dword[PT_ADDR (4)], edx - - ; - ; Next level Page Directory Pointers (4 * 1GB entries =3D> 4GB) - ; - mov dword[PT_ADDR (0x1000)], PT_ADDR (0x2000) + PAGE_PDP_ATTR - mov dword[PT_ADDR (0x1004)], edx - mov dword[PT_ADDR (0x1008)], PT_ADDR (0x3000) + PAGE_PDP_ATTR - mov dword[PT_ADDR (0x100C)], edx - mov dword[PT_ADDR (0x1010)], PT_ADDR (0x4000) + PAGE_PDP_ATTR - mov dword[PT_ADDR (0x1014)], edx - mov dword[PT_ADDR (0x1018)], PT_ADDR (0x5000) + PAGE_PDP_ATTR - mov dword[PT_ADDR (0x101C)], edx - - ; - ; Page Table Entries (2048 * 2MB entries =3D> 4GB) - ; - mov ecx, 0x800 -pageTableEntriesLoop: - mov eax, ecx - dec eax - shl eax, 21 - add eax, PAGE_2M_PDE_ATTR - mov [ecx * 8 + PT_ADDR (0x2000 - 8)], eax - mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx - loop pageTableEntriesLoop - - OneTimeCall IsSevEsEnabled - test eax, eax - jz SetCr3 - - ; - ; The initial GHCB will live at GHCB_BASE and needs to be un-encrypted= . - ; This requires the 2MB page for this range be broken down into 512 4K= B - ; pages. All will be marked encrypted, except for the GHCB. - ; - mov ecx, (GHCB_BASE >> 21) - mov eax, GHCB_PT_ADDR + PAGE_PDP_ATTR - mov [ecx * 8 + PT_ADDR (0x2000)], eax - - ; - ; Page Table Entries (512 * 4KB entries =3D> 2MB) - ; - mov ecx, 512 -pageTableEntries4kLoop: - mov eax, ecx - dec eax - shl eax, 12 - add eax, GHCB_BASE & 0xFFE0_0000 - add eax, PAGE_4K_PDE_ATTR - mov [ecx * 8 + GHCB_PT_ADDR - 8], eax - mov [(ecx * 8 + GHCB_PT_ADDR - 8) + 4], edx - loop pageTableEntries4kLoop - - ; - ; Clear the encryption bit from the GHCB entry - ; - mov ecx, (GHCB_BASE & 0x1F_FFFF) >> 12 - mov [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0 - - mov ecx, GHCB_SIZE / 4 - xor eax, eax -clearGhcbMemoryLoop: - mov dword[ecx * 4 + GHCB_BASE - 4], eax - loop clearGhcbMemoryLoop - -SetCr3: - ; - ; Set CR3 now that the paging structures are available - ; - mov eax, PT_ADDR (0) - mov cr3, eax - - OneTimeCallRet SetCr3ForPageTables64 - -; ; Start of #VC exception handling routines ; =20 diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVecto= r/Ia32/PageTables64.asm index 5fae8986d9da..eacdb69ddb9f 100644 --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm @@ -37,182 +37,6 @@ BITS 32 PAGE_READ_WRITE + \ PAGE_PRESENT) =20 -; -; SEV-ES #VC exception handler support -; -; #VC handler local variable locations -; -%define VC_CPUID_RESULT_EAX 0 -%define VC_CPUID_RESULT_EBX 4 -%define VC_CPUID_RESULT_ECX 8 -%define VC_CPUID_RESULT_EDX 12 -%define VC_GHCB_MSR_EDX 16 -%define VC_GHCB_MSR_EAX 20 -%define VC_CPUID_REQUEST_REGISTER 24 -%define VC_CPUID_FUNCTION 28 - -; #VC handler total local variable size -; -%define VC_VARIABLE_SIZE 32 - -; #VC handler GHCB CPUID request/response protocol values -; -%define GHCB_CPUID_REQUEST 4 -%define GHCB_CPUID_RESPONSE 5 -%define GHCB_CPUID_REGISTER_SHIFT 30 -%define CPUID_INSN_LEN 2 - - -; Check if Secure Encrypted Virtualization (SEV) features are enabled. -; -; Register usage is tight in this routine, so multiple calls for the -; same CPUID and MSR data are performed to keep things simple. -; -; Modified: EAX, EBX, ECX, EDX, ESP -; -; If SEV is enabled then EAX will be at least 32. -; If SEV is disabled then EAX will be zero. -; -CheckSevFeatures: - ; Set the first byte of the workarea to zero to communicate to the SEC - ; phase that SEV-ES is not enabled. If SEV-ES is enabled, the CPUID - ; instruction will trigger a #VC exception where the first byte of the - ; workarea will be set to one or, if CPUID is not being intercepted, - ; the MSR check below will set the first byte of the workarea to one. - mov byte[SEV_ES_WORK_AREA], 0 - - ; - ; Set up exception handlers to check for SEV-ES - ; Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for - ; stack usage) - ; Establish exception handlers - ; - mov esp, SEV_ES_VC_TOP_OF_STACK - mov eax, ADDR_OF(Idtr) - lidt [cs:eax] - - ; Check if we have a valid (0x8000_001F) CPUID leaf - ; CPUID raises a #VC exception if running as an SEV-ES guest - mov eax, 0x80000000 - cpuid - - ; This check should fail on Intel or Non SEV AMD CPUs. In future if - ; Intel CPUs supports this CPUID leaf then we are guranteed to have ex= act - ; same bit definition. - cmp eax, 0x8000001f - jl NoSev - - ; Check for SEV memory encryption feature: - ; CPUID Fn8000_001F[EAX] - Bit 1 - ; CPUID raises a #VC exception if running as an SEV-ES guest - mov eax, 0x8000001f - cpuid - bt eax, 1 - jnc NoSev - - ; Check if SEV memory encryption is enabled - ; MSR_0xC0010131 - Bit 0 (SEV enabled) - mov ecx, 0xc0010131 - rdmsr - bt eax, 0 - jnc NoSev - - ; Check for SEV-ES memory encryption feature: - ; CPUID Fn8000_001F[EAX] - Bit 3 - ; CPUID raises a #VC exception if running as an SEV-ES guest - mov eax, 0x8000001f - cpuid - bt eax, 3 - jnc GetSevEncBit - - ; Check if SEV-ES is enabled - ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled) - mov ecx, 0xc0010131 - rdmsr - bt eax, 1 - jnc GetSevEncBit - - ; Set the first byte of the workarea to one to communicate to the SEC - ; phase that SEV-ES is enabled. - mov byte[SEV_ES_WORK_AREA], 1 - -GetSevEncBit: - ; Get pte bit position to enable memory encryption - ; CPUID Fn8000_001F[EBX] - Bits 5:0 - ; - and ebx, 0x3f - mov eax, ebx - - ; The encryption bit position is always above 31 - sub ebx, 32 - jns SevSaveMask - - ; Encryption bit was reported as 31 or below, enter a HLT loop -SevEncBitLowHlt: - cli - hlt - jmp SevEncBitLowHlt - -SevSaveMask: - xor edx, edx - bts edx, ebx - - mov dword[SEV_ES_WORK_AREA_ENC_MASK], 0 - mov dword[SEV_ES_WORK_AREA_ENC_MASK + 4], edx - jmp SevExit - -NoSev: - ; - ; Perform an SEV-ES sanity check by seeing if a #VC exception occurred= . - ; - cmp byte[SEV_ES_WORK_AREA], 0 - jz NoSevPass - - ; - ; A #VC was received, yet CPUID indicates no SEV-ES support, something - ; isn't right. - ; -NoSevEsVcHlt: - cli - hlt - jmp NoSevEsVcHlt - -NoSevPass: - xor eax, eax - -SevExit: - ; - ; Clear exception handlers and stack - ; - push eax - mov eax, ADDR_OF(IdtrClear) - lidt [cs:eax] - pop eax - mov esp, 0 - - OneTimeCallRet CheckSevFeatures - -; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feat= ure -; is enabled. -; -; Modified: EAX -; -; If SEV-ES is enabled then EAX will be non-zero. -; If SEV-ES is disabled then EAX will be zero. -; -IsSevEsEnabled: - xor eax, eax - - ; During CheckSevFeatures, the SEV_ES_WORK_AREA was set to 1 if - ; SEV-ES is enabled. - cmp byte[SEV_ES_WORK_AREA], 1 - jne SevEsDisabled - - mov eax, 1 - -SevEsDisabled: - OneTimeCallRet IsSevEsEnabled - ; ; Modified: EAX, EBX, ECX, EDX ; @@ -324,218 +148,3 @@ SetCr3: mov cr3, eax =20 OneTimeCallRet SetCr3ForPageTables64 - -; -; Start of #VC exception handling routines -; - -SevEsIdtNotCpuid: - ; - ; Use VMGEXIT to request termination. - ; 1 - #VC was not for CPUID - ; - mov eax, 1 - jmp SevEsIdtTerminate - -SevEsIdtNoCpuidResponse: - ; - ; Use VMGEXIT to request termination. - ; 2 - GHCB_CPUID_RESPONSE not received - ; - mov eax, 2 - -SevEsIdtTerminate: - ; - ; Use VMGEXIT to request termination. At this point the reason code is - ; located in EAX, so shift it left 16 bits to the proper location. - ; - ; EAX[11:0] =3D> 0x100 - request termination - ; EAX[15:12] =3D> 0x1 - OVMF - ; EAX[23:16] =3D> 0xXX - REASON CODE - ; - shl eax, 16 - or eax, 0x1100 - xor edx, edx - mov ecx, 0xc0010130 - wrmsr - ; - ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-b= it - ; mode, so work around this by temporarily switching to 64-bit mode. - ; -BITS 64 - rep vmmcall -BITS 32 - - ; - ; We shouldn't come back from the VMGEXIT, but if we do, just loop. - ; -SevEsIdtHlt: - hlt - jmp SevEsIdtHlt - iret - - ; - ; Total stack usage for the #VC handler is 44 bytes: - ; - 12 bytes for the exception IRET (after popping error code) - ; - 32 bytes for the local variables. - ; -SevEsIdtVmmComm: - ; - ; If we're here, then we are an SEV-ES guest and this - ; was triggered by a CPUID instruction - ; - ; Set the first byte of the workarea to one to communicate that - ; a #VC was taken. - mov byte[SEV_ES_WORK_AREA], 1 - - pop ecx ; Error code - cmp ecx, 0x72 ; Be sure it was CPUID - jne SevEsIdtNotCpuid - - ; Set up local variable room on the stack - ; CPUID function : + 28 - ; CPUID request register : + 24 - ; GHCB MSR (EAX) : + 20 - ; GHCB MSR (EDX) : + 16 - ; CPUID result (EDX) : + 12 - ; CPUID result (ECX) : + 8 - ; CPUID result (EBX) : + 4 - ; CPUID result (EAX) : + 0 - sub esp, VC_VARIABLE_SIZE - - ; Save the CPUID function being requested - mov [esp + VC_CPUID_FUNCTION], eax - - ; The GHCB CPUID protocol uses the following mapping to request - ; a specific register: - ; 0 =3D> EAX, 1 =3D> EBX, 2 =3D> ECX, 3 =3D> EDX - ; - ; Set EAX as the first register to request. This will also be used as = a - ; loop variable to request all register values (EAX to EDX). - xor eax, eax - mov [esp + VC_CPUID_REQUEST_REGISTER], eax - - ; Save current GHCB MSR value - mov ecx, 0xc0010130 - rdmsr - mov [esp + VC_GHCB_MSR_EAX], eax - mov [esp + VC_GHCB_MSR_EDX], edx - -NextReg: - ; - ; Setup GHCB MSR - ; GHCB_MSR[63:32] =3D CPUID function - ; GHCB_MSR[31:30] =3D CPUID register - ; GHCB_MSR[11:0] =3D CPUID request protocol - ; - mov eax, [esp + VC_CPUID_REQUEST_REGISTER] - cmp eax, 4 - jge VmmDone - - shl eax, GHCB_CPUID_REGISTER_SHIFT - or eax, GHCB_CPUID_REQUEST - mov edx, [esp + VC_CPUID_FUNCTION] - mov ecx, 0xc0010130 - wrmsr - - ; - ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-b= it - ; mode, so work around this by temporarily switching to 64-bit mode. - ; -BITS 64 - rep vmmcall -BITS 32 - - ; - ; Read GHCB MSR - ; GHCB_MSR[63:32] =3D CPUID register value - ; GHCB_MSR[31:30] =3D CPUID register - ; GHCB_MSR[11:0] =3D CPUID response protocol - ; - mov ecx, 0xc0010130 - rdmsr - mov ecx, eax - and ecx, 0xfff - cmp ecx, GHCB_CPUID_RESPONSE - jne SevEsIdtNoCpuidResponse - - ; Save returned value - shr eax, GHCB_CPUID_REGISTER_SHIFT - mov [esp + eax * 4], edx - - ; Next register - inc word [esp + VC_CPUID_REQUEST_REGISTER] - - jmp NextReg - -VmmDone: - ; - ; At this point we have all CPUID register values. Restore the GHCB MS= R, - ; set the return register values and return. - ; - mov eax, [esp + VC_GHCB_MSR_EAX] - mov edx, [esp + VC_GHCB_MSR_EDX] - mov ecx, 0xc0010130 - wrmsr - - mov eax, [esp + VC_CPUID_RESULT_EAX] - mov ebx, [esp + VC_CPUID_RESULT_EBX] - mov ecx, [esp + VC_CPUID_RESULT_ECX] - mov edx, [esp + VC_CPUID_RESULT_EDX] - - add esp, VC_VARIABLE_SIZE - - ; Update the EIP value to skip over the now handled CPUID instruction - ; (the CPUID instruction has a length of 2) - add word [esp], CPUID_INSN_LEN - iret - -ALIGN 2 - -Idtr: - dw IDT_END - IDT_BASE - 1 ; Limit - dd ADDR_OF(IDT_BASE) ; Base - -IdtrClear: - dw 0 ; Limit - dd 0 ; Base - -ALIGN 16 - -; -; The Interrupt Descriptor Table (IDT) -; This will be used to determine if SEV-ES is enabled. Upon execution -; of the CPUID instruction, a VMM Communication Exception will occur. -; This will tell us if SEV-ES is enabled. We can use the current value -; of the GHCB MSR to determine the SEV attributes. -; -IDT_BASE: -; -; Vectors 0 - 28 (No handlers) -; -%rep 29 - dw 0 ; Offset low bits 15..0 - dw 0x10 ; Selector - db 0 ; Reserved - db 0x8E ; Gate Type (IA32_IDT_GAT= E_TYPE_INTERRUPT_32) - dw 0 ; Offset high bits 31..16 -%endrep -; -; Vector 29 (VMM Communication Exception) -; - dw (ADDR_OF(SevEsIdtVmmComm) & 0xffff) ; Offset low bits 15..0 - dw 0x10 ; Selector - db 0 ; Reserved - db 0x8E ; Gate Type (IA32_IDT_GAT= E_TYPE_INTERRUPT_32) - dw (ADDR_OF(SevEsIdtVmmComm) >> 16) ; Offset high bits 31..16 -; -; Vectors 30 - 31 (No handlers) -; -%rep 2 - dw 0 ; Offset low bits 15..0 - dw 0x10 ; Selector - db 0 ; Reserved - db 0x8E ; Gate Type (IA32_IDT_GAT= E_TYPE_INTERRUPT_32) - dw 0 ; Offset high bits 31..16 -%endrep -IDT_END: diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/Re= setVector.nasmb index 5fbacaed5f9d..8a3269cfc212 100644 --- a/OvmfPkg/ResetVector/ResetVector.nasmb +++ b/OvmfPkg/ResetVector/ResetVector.nasmb @@ -77,6 +77,7 @@ %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) = + 16) %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase)= + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) %include "Ia32/Flat32ToFlat64.asm" +%include "Ia32/AmdSev.asm" %include "Ia32/PageTables64.asm" %endif =20 --=20 2.17.1