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.64]) by mx.groups.io with SMTP id smtpd.web12.5354.1627409458599534602 for ; Tue, 27 Jul 2021 11:10:58 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@amd.com header.s=selector1 header.b=RytXk8in; 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.64, mailfrom: brijesh.singh@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Fi4S97TLs9dy0OXoyAfh7u9gIOqsdVFuUH8gmLlKrXdjWkV07SCc21XjHqTjutfZpoTmHb0lw9tqF7ECDSjtpcyjmimTxj+VpI/V8pBsOnIjHBP9d2qPPm4OznRHFI4yy80WwCp1Xs/fQK7SA9+YmTTOtcitf4gnXgGwZH0TvR+m9prBmcAEB+NyoRAZCDOjOsBZHxZAvSz8qK+rUJmCLQMCKezeRFZ+ht+RjeBtwodW6C6i2BX4phmu9Zg1sdAbMvsMtLcqJItmw7Yq/h+xU21Kl1GpmljDWFZfcc7pEQ4TMHGWYCTqEj8WqSjSJNBAivBLsrkPuaoGEwXYSR2Z8w== 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=bOPKG7JiKafe1qVJsZi/Q2izihbfC8LwZGn92X5PiBw=; b=A7WLneb1JZvT7CWG9il/gAqAB03MjxgzRAqbUpTFg0Fgo7G5TwJ61BepV0YvjxImLTCy5DZU1Jl48f7I8CGfw13zWIfVz1X4nfxBI+h9ZGMQifRJjB3rL57rYC2i7gf8XYKV92xxqJ2vmRloZk2ssEhnHMfQETNdEanS9IJQmrGrTe5XvmPbvPvWoPqCIazCYKhUUvsB0no+UjTVuRb1T7HqgO4zWFul3j3kRxPnvMxe/YIA/oLlIlRnlPpWvoEhAbPsntm8vS1aXRKQlfExhl5V6li0Y7pbZRMVWW9FEPmO/DcnyrEW2yL1BBuMX0HQZGny3tsKkp+6HZYcbgiXSg== 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=bOPKG7JiKafe1qVJsZi/Q2izihbfC8LwZGn92X5PiBw=; b=RytXk8inqLEODmstvPUlD4tekTFaHfDee5cb4wIy3LRPMyRggux6AdTJjeOZR9pWtpRPdfT+7H1bOCInTe5qZ3GWS6vF6GXDR62jPhlStMPdZwJh3IxKKRhwbNPbj8/S1ra5JbKBlD6MG70Vnu03+4hqJ5+8eMeMJJXEO7qY8W4= 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 SA0PR12MB4349.namprd12.prod.outlook.com (2603:10b6:806:98::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4373.18; Tue, 27 Jul 2021 18:10:57 +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 18:10:57 +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 v2 1/3] OvmfPkg/ResetVector: move SEV specific code in a separate file Date: Tue, 27 Jul 2021 13:10:22 -0500 Message-ID: <20210727181024.28770-2-brijesh.singh@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210727181024.28770-1-brijesh.singh@amd.com> References: <20210727181024.28770-1-brijesh.singh@amd.com> X-ClientProxiedBy: SA9PR13CA0162.namprd13.prod.outlook.com (2603:10b6:806:28::17) 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 SA9PR13CA0162.namprd13.prod.outlook.com (2603:10b6:806:28::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4373.7 via Frontend Transport; Tue, 27 Jul 2021 18:10:56 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 6f8f2dc1-d471-430a-4f63-08d95129e16b X-MS-TrafficTypeDiagnostic: SA0PR12MB4349: 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: fxBEZ/lhhLoD5Wf6+NJap39dA9Q40PdVU69Xt8IbGEaIpiN8v6MCw9FUNnqcOYp0kWVHp1PRd8VKdMx17Z/xbS80gj7+9JoCko5g1+qpKF9olZBPUYFKeSON3Ze0w4idgGhFHsk4H3Fq2mCSHfZn7XdzXPOmVslAI7Ok9xTcapWQwNQf1YULkV1K94QpTSJDGb0hD3ItE2V2JSTF0S2J9POCgUFfLUet32MKXdmhQM7Dvr2L2A43jma3NaVGqLLAxf2iPBH0SgpFuuk818T7KrnP7ROGKOsLlLyOuDRMxqCMGpdFDc9XWLu+1oYErTXoNcpMu5OnO/wI8KA/c7ZseZLJmsmfrZgFyX06mYyY2lwNMfoBZaS8nAptz4D2ByKi//qWtV0/IgqW7efncT7l+JekjOMKLW4qjRJW0PyxrRrMTilD1BaKpDfGIJCqVW4hxnWfkZfHZLQsHtukW28BrYd864dLKV0sHJzmYHG9HC6Gaxge8pqF6lEfr63U6BcOOK/OGvahHHM6qhxS4o06KZUVHU7PB20H5db+fbAsHn2fBfX1wf3VxgByCtP9USsVv+DWIk5BJTXRoGooY4gnzWhtd7Me701heycJCZkKyVj/tuxS7km84YdANvsinizWUKZ7GC8ai8cQhcBAiu3A1XQKDwThrF+47lHiUtPFRG5g3x+BpmqBPPx7MDR0/jZ7kwWmsk9m5AWePrSn9FXZxYnKrQemDiDAEnVH6LyQBGqZ4HME5iXC3furiEy0v9y5wPe0vKEUnvklGao091uLUV1gzkNcjFvCnU6uJXPvRCs= 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)(136003)(366004)(376002)(346002)(39860400002)(396003)(2616005)(1076003)(4326008)(86362001)(966005)(36756003)(8676002)(19627235002)(6916009)(38350700002)(38100700002)(6666004)(44832011)(316002)(2906002)(956004)(66476007)(66556008)(66946007)(5660300002)(6486002)(54906003)(7696005)(52116002)(478600001)(8936002)(30864003)(83380400001)(26005)(186003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?LVul5oe9hg+tS4wm+gxfHduhOQuoufPz8t7/5IMjAgJm0mMHbRJHogF+teKL?= =?us-ascii?Q?HmUz0fPJ297uJmwbBS+oPM4MU6r6nx2WOo9TyLWUKZfgI310RJ2LcrWL5jvm?= =?us-ascii?Q?m8LGMBg7tecuiPzfRFShjkONm74medn6uN0b4H2WxmvIiT+3ckGNvjbN62cS?= =?us-ascii?Q?MZAy/zXdf1k98/0cw69dUbKMd+GakrPdPUVz0JYMElShsmI0OZjSxSrdmYCD?= =?us-ascii?Q?J/krxo68YwBSF6WEPYpWuTgD+/+3j5wxhSasRTqsXMoR9Nw7y00EEioT2hZH?= =?us-ascii?Q?ArfhTwTBVZvbPO4P3dPMZ7XG3fxxUfWT9XD5uga8bz15B0OwDHX3ZBn2DmZ/?= =?us-ascii?Q?W8VXrUznPnIv7VErPd9yBDgWkwrGmgnzp/YSPjQ5qw60Ia0mIVJGHhoTvOhn?= =?us-ascii?Q?Cz/IiV69lKvmP0bv03xXvBllQrX+civrYRjDffYAk+lp7iyHWi6kZcwi5Yyw?= =?us-ascii?Q?5WRHNiccG6a0ZA5u4R9E8gdwtdwmglL1Wt8Zv3RrDHUPev9I2Vp57mjDDel+?= =?us-ascii?Q?csW7PiIQOEOg28mZe2EhGC6eCwW9PQJWunVCdEq1zhE7bIV3AT0Fttsjzb9U?= =?us-ascii?Q?3L8a59QiGto3bpP/BLkeO41LKdo5/3iu7A+sZ4yVqomcBtSPPdhFb1fCWdo8?= =?us-ascii?Q?ojz+AvEmfyOQdD1c/PCFqhOi3sfn+EUcE0IDPwrk6NjXlCSmysFUQD9tjamO?= =?us-ascii?Q?q8DcvDZ5ZQR2E5N2I9JVpOxHvtwfIIOaI98qjIRks4KRdxXF2CwnG15qEb1w?= =?us-ascii?Q?t3F8quCbCWxyoai10thLJfIMDXZ/LQFqnpO4lMPsuOIITQwUnw9z4OEpy1jS?= =?us-ascii?Q?RHg4AzqufYqpERDKnnyUqDMPWt1EMzwMBG3oQf/ziYv+eYwPBJ6VkvoBKdYA?= =?us-ascii?Q?uuL6B8jdWtObJfiOPzMgyVaseViXGfFUTEM5TkAPDweX1vQxHkswVOnYQWFi?= =?us-ascii?Q?y8xEkXRE4WFZwZIqa+FqfQHvEyLt0SoJ0RBjbtWUxiReG8SAUllUbhKwt2bl?= =?us-ascii?Q?Hdusckeb9+8flrQ5r+iX/EWDxdmKjlV0g2MmYPT5mLk8qBRRIIH2zvj1o+J3?= =?us-ascii?Q?uyakI7mtVL56OW66/zSJqXKx/hd7imxXnrStvuSNQcD2w7ALgYq8XGEL//Yo?= =?us-ascii?Q?fdQawBopR1nqowyTJsYrWRS/JJHOMJVc9H5dzKkk7BXIO7h+lgswipO4JlRN?= =?us-ascii?Q?rsWGJvIFFXt1CziTVJ74DnND8IQ3u0kkPpJx5SP2LPmyk//An9IQmKvQ4kov?= =?us-ascii?Q?6mbpAOS3T/TwwCPp05lS7d4muNEb1Cmf7lzSpAYfGv2dJfxaqMLltej9RaA8?= =?us-ascii?Q?P48M2iprdHmmN/ZLRDDgh6Or?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6f8f2dc1-d471-430a-4f63-08d95129e16b X-MS-Exchange-CrossTenant-AuthSource: SN6PR12MB2718.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jul 2021 18:10:56.9349 (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: 0wA4HDL+EqyR2bDus7Q/z86E6Nk8eOUSbbmXwvkALfHwHjKUuo/IUoBc2fQWrDcznsTGCQw1rydpLcRBYPeHew== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB4349 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 Reviewed-by: Jiewen Yao Acked-by: Ard Biesheuvel Suggested-by: Laszlo Ersek Signed-off-by: Brijesh Singh --- .../Ia32/{PageTables64.asm =3D> AmdSev.asm} | 145 +------ OvmfPkg/ResetVector/Ia32/PageTables64.asm | 391 ------------------ OvmfPkg/ResetVector/ResetVector.nasmb | 1 + 3 files changed, 3 insertions(+), 534 deletions(-) copy OvmfPkg/ResetVector/Ia32/{PageTables64.asm =3D> AmdSev.asm} (70%) diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVecto= r/Ia32/AmdSev.asm similarity index 70% copy from OvmfPkg/ResetVector/Ia32/PageTables64.asm copy to OvmfPkg/ResetVector/Ia32/AmdSev.asm index 5fae8986d9da..2c9d990af55f 100644 --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm +++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm @@ -1,42 +1,14 @@ ;-------------------------------------------------------------------------= ----- ; @file -; Sets the CR3 register for 64-bit paging +; Provide the functions to check whether SEV and SEV-ES is enabled. ; -; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.
-; Copyright (c) 2017 - 2020, Advanced Micro Devices, Inc. All rights reser= ved.
+; Copyright (c) 2017 - 2021, Advanced Micro Devices, Inc. All rights reser= ved.
; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;-------------------------------------------------------------------------= ----- =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 +185,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