From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.86]) by mx.groups.io with SMTP id smtpd.web09.9199.1614789130177071792 for ; Wed, 03 Mar 2021 08:32:10 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@amd.com header.s=selector1 header.b=klOWOZOb; 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.93.86, mailfrom: ashish.kalra@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=VPKFndBTbEmt2QppwM7sm/FQ5j8IOd+5VXXSWzB80TJm6isf6OmeSm8x+TaVbBBuVkDsH3Dvc0S2teQ9cM9ATxGXsAFau9uQwVXKMJImFw9FyHSpfR+Fh9iLNLDXA96EKyRlhfzTzZXpFXG2d0MXgS8GyEGan8V+NkUH+Sq7t61Bc9ur4ACYFitOOZviiEbhe6wLwNuO3v69SB/2VsvqEn+PFcsOYbhTVF//s0vmpO0uuL/v3Y7x4zGUdtAP5omdGrS25JWAAwsfJwIxHuM/4fs450qe+ETaZPg3oW42UKm/l88tIdAFGJCx6f9VXKOJfouI4gfvpy5+C0MazNYipA== 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=DyqAwoWzsYzWdKSUuWKEB6WU5u+qD7zSzGivBekKgzE=; b=kED5D1Ybv6h7w4E6BE3X1C81Zn2RtONADxoExFwQyNrdzsksiFk5nysNMXvlAUrW221pRBcMNh1BrJHXTghbqJznE+VAuJGLpbHuADAvd7nd6oHv/AYUCWj9zkqh4r/l4xbUDZevEmmPvrN7B3rihEx6HJr/BYRfOIPmoJBLDk9irrn2i73qeaAXQ0FQMQhBnavsfpTr7J7y6aPKoYGxRqk2vjTHKFQzHY3f4MI2cPiWonWc8EB4qfBJ53c93UOwQzZXn3uOyfdMWKsIV5/IPZPXSq2eW/9SVP5b2hIHXb5NuOx5kppVxrlWq6Mr++e03pJ44CwVeeWThq4aqvVc+g== 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=DyqAwoWzsYzWdKSUuWKEB6WU5u+qD7zSzGivBekKgzE=; b=klOWOZOb20h+zs+oSgp1nUqak2m2pSHiLv5rrIGeoLxmwH8Rdtgrjwyden+atEEHHTgd14Maqflw9jtF7hEkLIbE8jD/jJRyxQtp5/lFwhi5b8RtLAe2vFLQdjQ13h6TWlWMDKxHqXImdIEgp4zilPzXJS6VUn5RNy07UfC5UbI= Authentication-Results: linux.ibm.com; dkim=none (message not signed) header.d=none;linux.ibm.com; dmarc=none action=none header.from=amd.com; Received: from SN6PR12MB2767.namprd12.prod.outlook.com (2603:10b6:805:75::23) by SA0PR12MB4384.namprd12.prod.outlook.com (2603:10b6:806:9f::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3912.17; Wed, 3 Mar 2021 16:32:08 +0000 Received: from SN6PR12MB2767.namprd12.prod.outlook.com ([fe80::24bb:3e53:c95e:cb8e]) by SN6PR12MB2767.namprd12.prod.outlook.com ([fe80::24bb:3e53:c95e:cb8e%7]) with mapi id 15.20.3912.018; Wed, 3 Mar 2021 16:32:08 +0000 Date: Wed, 3 Mar 2021 16:32:02 +0000 From: "Ashish Kalra" To: Tobin Feldman-Fitzthum Cc: devel@edk2.groups.io, Dov Murik , Tobin Feldman-Fitzthum , James Bottomley , Hubertus Franke , Brijesh Singh , Jon Grimm , Tom Lendacky Subject: Re: [RFC PATCH 11/14] OvmfPkg/AmdSev: Build page table for migration handler Message-ID: <20210303163202.GA31638@ashkalra_ubuntu_server> References: <20210302204839.82042-1-tobin@linux.ibm.com> <20210302204839.82042-12-tobin@linux.ibm.com> In-Reply-To: <20210302204839.82042-12-tobin@linux.ibm.com> User-Agent: Mutt/1.9.4 (2018-02-28) X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: SN1PR12CA0058.namprd12.prod.outlook.com (2603:10b6:802:20::29) To SN6PR12MB2767.namprd12.prod.outlook.com (2603:10b6:805:75::23) Return-Path: ashish.kalra@amd.com MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from ashkalra_ubuntu_server (165.204.77.1) by SN1PR12CA0058.namprd12.prod.outlook.com (2603:10b6:802:20::29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3912.17 via Frontend Transport; Wed, 3 Mar 2021 16:32:07 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 158fcf9a-e85b-4957-7f5c-08d8de61e375 X-MS-TrafficTypeDiagnostic: SA0PR12MB4384: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:10000; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: J0K0MJq4s8/cvV4XVc11Jax7EOzIITAJ9P6mheVyczdC9jSpu2clLsIOGwiFem0NQNN/qQdoTwwtNyTgXjQq4F+SrxN5wDJ0mzugi9Lg0juOKBUzSkZRTOfx2/Cgq+iDYTHXxdHwe8wjuEd68Gbfw+6yjEIFLk2SZ2FSncG0dLd09lC5k+2ClSEYPRYKJUc0JqDBwMOv8MigOKlaAEZS4pVPmsqD6OPaBuimlanDaSqFc4D7peu0oASunOeb8IYrU5mTq/J4WkjYv/7yu+HGTnQegTMlqfSiCSIxyl/vj3pgadMojkcU4Z2i9vEjv2SCe11QstmxbNAxzrEV37o+NnHbB05f4S8rGHubkfqNDL+nZpqykP2oN2gmSmR1CCR0GTW8FpZ5tEMje90lDiVOROXMwYKHdZUyzWnz10xFD/zwsYP5N0hWYThbug3nUabr+yekdCiZxldXLyDCq3IwxD97At/ljFS8An9g+NBHon0/5CH8z9y6MoTi8P+KCmM0VPxqg0LRp4O1iBlucQOeLQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SN6PR12MB2767.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(376002)(396003)(136003)(366004)(346002)(39860400002)(83380400001)(6496006)(54906003)(66556008)(66476007)(6916009)(66946007)(5660300002)(316002)(1076003)(33716001)(55016002)(16526019)(2906002)(478600001)(44832011)(186003)(26005)(52116002)(86362001)(956004)(8676002)(6666004)(4326008)(9686003)(8936002)(19627235002)(33656002)(30864003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?zlXI8mkGMUE+H7s/jx5njh2VD6fRIMcAoJLP76yT/yVmPWo3GiUcZUBjsSkF?= =?us-ascii?Q?oNI5PikSaeblivFUS3vUT7fNKT2MNrGTqKLYdSTOVdWB0jHXZEZjZwyCQfkr?= =?us-ascii?Q?MLLK2/PXEwWcuUcp/GQlPNC0PUapjVq/z0e/eY28UVW7eYONeZv80T6YZCFi?= =?us-ascii?Q?Dyll38aTAIw2lUpv9R5wi+tN0f65w1r+o6rDvbshDPmS7Q+1iFU8ucxqVb13?= =?us-ascii?Q?HMUhlk2lY8eb0Hs/UrqNHTbl1C59R0tC0VcfjsZS1jER+rG860tT99einR3o?= =?us-ascii?Q?Y8mISBDR0n1TSS2IEgCx5siA5ILnXZ89Mhs/EccQWmyJuJLveHFP1W2z82RO?= =?us-ascii?Q?vZT9ilIZxuMNKnGRJuQUfkrL85vTaM6eUr4bZxdU7+uPw3SwUOBC6RWkiMkC?= =?us-ascii?Q?/JVqyUY3OGtnUHSBSrMFVUAkthR6ZEllFzfdLfBj1eYcS1G0o/0sIQTb79QA?= =?us-ascii?Q?Y63Hqt//QXv6nV4wdpZib8Ko3WPT/tpJdUmXC98bjZTbb6y8NxO9y0YeFDIx?= =?us-ascii?Q?nGgOOV4GQzRG2+b9apjQrGEgonKRcQ8JnQmQHS8TyoOQ6DOAQeNRAHtIYEeu?= =?us-ascii?Q?rCrbY2cIJbGJlzDCUTpBYoB4YAwmU1OWDxE9qokWPmImHzg2nfXLLBQ+vB8N?= =?us-ascii?Q?rboue3OEq6zLaWmdA9SxgTfv2+wmcSQyLnc0G8swhAZH2jhJC9GsLhuAznEL?= =?us-ascii?Q?84DL86j7kHrBU7T7Tb61cZQWnaXEFs3RkDGDbvdZWOGPUeO5goIRkvaGZBnS?= =?us-ascii?Q?uHNJlXOxUmDf4pjTgyPQr7AYJFiU9x+S8aD8PVlPcMj7ASq/VPNPZIKbHpfS?= =?us-ascii?Q?sol6+xgXsg59/zCp3Kg6yAx0Zy8MM9d7uRRqQK/RopxaO9/I6g4K6XzC6mlV?= =?us-ascii?Q?ip1wHcRmjMcXMzOs1iUHDISxiVAsq5RRZ/Ls+2845BXuyrjrnmtr5GFlN2Fd?= =?us-ascii?Q?pW4QPAC7jfOzQpUkLQP8i4WKVxkO7Yb+CCOlyBWUrwXdcSOXYsMxWDFA6k4N?= =?us-ascii?Q?fTWfeuKwLUhHiKPxrVa4t+nnf6ns+VMp9BNGU51Up9BPr7sRyNFPfVxXmlXk?= =?us-ascii?Q?wuK03JVuqWJu+jHPzqgq1DaAJ3cIzi9ViDm77/4Hy3acJ326dnKA04SAaVqI?= =?us-ascii?Q?BFIEXHugwiZh0OirnD2fByyPD1H5bABlGeCfThB3VWyXbDBxno/UjZkebuV3?= =?us-ascii?Q?33R+38H3CuvLeOGFSF13U+Edq75L/CoGM2xHXh1w2uMPmO5EQyxKMdoiKiuk?= =?us-ascii?Q?czBpeVXHpxDAZIb+IGgpO7IqErCu6GPiArIpVWuTTtfGmMH/YMq9Z8/nYfnQ?= =?us-ascii?Q?uumtqi181M4V8lGqtPne7LGu?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: 158fcf9a-e85b-4957-7f5c-08d8de61e375 X-MS-Exchange-CrossTenant-AuthSource: SN6PR12MB2767.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Mar 2021 16:32:08.4646 (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: trwFsovHpvt4yBc9SNPljjYb5cBjYpbeYx7zVrkMitiR/+ixLroSnhlSy1G0oW1HGQesAeIzs9gaKFiM6mCKyQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB4384 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, Mar 02, 2021 at 03:48:36PM -0500, Tobin Feldman-Fitzthum wrote: > From: Dov Murik > > The migration handler builds its own page tables and switches > to them. The MH pagetables are reserved as runtime memory. > > When the hypervisor asks the MH to import/export a page, the HV > writes the guest physical address of the page in question to the > mailbox. The MH uses an identity mapping so that it can read/write > whatever GPA is requested by the HV. The hypervisor only asks the > MH to import/export encrypted pages. Thus, the C-Bit can be set > for every page in the identity map. > > The MH also needs to read shared pages, such as the mailbox. > These are mapped at an offset. The offset must be added to > the physical address before it can be resolved. > > Signed-off-by: Tobin Feldman-Fitzthum > Signed-off-by: Dov Murik > --- > .../ConfidentialMigrationDxe.inf | 1 + > .../ConfidentialMigration/VirtualMemory.h | 177 ++++++++++++++++++ > .../ConfidentialMigrationDxe.c | 88 ++++++++- > 3 files changed, 265 insertions(+), 1 deletion(-) > create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h > > diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf > index 49457d5d17..8dadfd1d13 100644 > --- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf > +++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf > @@ -15,6 +15,7 @@ > > [Sources] > ConfidentialMigrationDxe.c > + VirtualMemory.h > > [Packages] > MdePkg/MdePkg.dec > diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h b/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h > new file mode 100644 > index 0000000000..c50cb64c63 > --- /dev/null > +++ b/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h > @@ -0,0 +1,177 @@ > +/** @file > + Virtual Memory Management Services to set or clear the memory encryption bit > + Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
> + Copyright (c) 2017, AMD Incorporated. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + Code is derived from OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h > + > +**/ > + > +#ifndef __VIRTUAL_MEMORY__ > +#define __VIRTUAL_MEMORY__ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define SYS_CODE64_SEL 0x38 > + > +#pragma pack(1) > + > +// > +// Page-Map Level-4 Offset (PML4) and > +// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB > +// > + > +typedef union { > + struct { > + UINT64 Present:1; // 0 = Not present in memory, > + // 1 = Present in memory > + UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write > + UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User > + UINT64 WriteThrough:1; // 0 = Write-Back caching, > + // 1 = Write-Through caching > + UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached > + UINT64 Accessed:1; // 0 = Not accessed, > + // 1 = Accessed (set by CPU) > + UINT64 Reserved:1; // Reserved > + UINT64 MustBeZero:2; // Must Be Zero > + UINT64 Available:3; // Available for use by system software > + UINT64 PageTableBaseAddress:40; // Page Table Base Address > + UINT64 AvabilableHigh:11; // Available for use by system software > + UINT64 Nx:1; // No Execute bit > + } Bits; > + UINT64 Uint64; > +} PAGE_MAP_AND_DIRECTORY_POINTER; > + > +// > +// Page Table Entry 4KB > +// > +typedef union { > + struct { > + UINT64 Present:1; // 0 = Not present in memory, > + // 1 = Present in memory > + UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write > + UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User > + UINT64 WriteThrough:1; // 0 = Write-Back caching, > + // 1 = Write-Through caching > + UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached > + UINT64 Accessed:1; // 0 = Not accessed, > + // 1 = Accessed (set by CPU) > + UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by > + // processor on access to page > + UINT64 PAT:1; // > + UINT64 Global:1; // 0 = Not global page, 1 = global page > + // TLB not cleared on CR3 write > + UINT64 Available:3; // Available for use by system software > + UINT64 PageTableBaseAddress:40; // Page Table Base Address > + UINT64 AvabilableHigh:11; // Available for use by system software > + UINT64 Nx:1; // 0 = Execute Code, > + // 1 = No Code Execution > + } Bits; > + UINT64 Uint64; > +} PAGE_TABLE_4K_ENTRY; > + > +// > +// Page Table Entry 2MB > +// > +typedef union { > + struct { > + UINT64 Present:1; // 0 = Not present in memory, > + // 1 = Present in memory > + UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write > + UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User > + UINT64 WriteThrough:1; // 0 = Write-Back caching, > + // 1=Write-Through caching > + UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached > + UINT64 Accessed:1; // 0 = Not accessed, > + // 1 = Accessed (set by CPU) > + UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by > + // processor on access to page > + UINT64 MustBe1:1; // Must be 1 > + UINT64 Global:1; // 0 = Not global page, 1 = global page > + // TLB not cleared on CR3 write > + UINT64 Available:3; // Available for use by system software > + UINT64 PAT:1; // > + UINT64 MustBeZero:8; // Must be zero; > + UINT64 PageTableBaseAddress:31; // Page Table Base Address > + UINT64 AvabilableHigh:11; // Available for use by system software > + UINT64 Nx:1; // 0 = Execute Code, > + // 1 = No Code Execution > + } Bits; > + UINT64 Uint64; > +} PAGE_TABLE_ENTRY; > + > +// > +// Page Table Entry 1GB > +// > +typedef union { > + struct { > + UINT64 Present:1; // 0 = Not present in memory, > + // 1 = Present in memory > + UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write > + UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User > + UINT64 WriteThrough:1; // 0 = Write-Back caching, > + // 1 = Write-Through caching > + UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached > + UINT64 Accessed:1; // 0 = Not accessed, > + // 1 = Accessed (set by CPU) > + UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by > + // processor on access to page > + UINT64 MustBe1:1; // Must be 1 > + UINT64 Global:1; // 0 = Not global page, 1 = global page > + // TLB not cleared on CR3 write > + UINT64 Available:3; // Available for use by system software > + UINT64 PAT:1; // > + UINT64 MustBeZero:17; // Must be zero; > + UINT64 PageTableBaseAddress:22; // Page Table Base Address > + UINT64 AvabilableHigh:11; // Available for use by system software > + UINT64 Nx:1; // 0 = Execute Code, > + // 1 = No Code Execution > + } Bits; > + UINT64 Uint64; > +} PAGE_TABLE_1G_ENTRY; > + > +#pragma pack() > + > +#define IA32_PG_P BIT0 > +#define IA32_PG_RW BIT1 > +#define IA32_PG_PS BIT7 > + > +#define PAGING_PAE_INDEX_MASK 0x1FF > + > +#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull > +#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull > +#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull > + > +#define PAGING_L1_ADDRESS_SHIFT 12 > +#define PAGING_L2_ADDRESS_SHIFT 21 > +#define PAGING_L3_ADDRESS_SHIFT 30 > +#define PAGING_L4_ADDRESS_SHIFT 39 > + > +#define PAGING_PML4E_NUMBER 4 > + > +#define PAGETABLE_ENTRY_MASK ((1UL << 9) - 1) > +#define PML4_OFFSET(x) ( (x >> 39) & PAGETABLE_ENTRY_MASK) > +#define PDP_OFFSET(x) ( (x >> 30) & PAGETABLE_ENTRY_MASK) > +#define PDE_OFFSET(x) ( (x >> 21) & PAGETABLE_ENTRY_MASK) > +#define PTE_OFFSET(x) ( (x >> 12) & PAGETABLE_ENTRY_MASK) > +#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull > + > +#define PAGE_TABLE_POOL_ALIGNMENT BASE_2MB > +#define PAGE_TABLE_POOL_UNIT_SIZE SIZE_2MB > +#define PAGE_TABLE_POOL_UNIT_PAGES \ > + EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE) > +#define PAGE_TABLE_POOL_ALIGN_MASK \ > + (~(EFI_PHYSICAL_ADDRESS)(PAGE_TABLE_POOL_ALIGNMENT - 1)) > + > +typedef struct { > + VOID *NextPool; > + UINTN Offset; > + UINTN FreePages; > +} PAGE_TABLE_POOL; > + > +#endif > diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c > index 8402fcc4fa..3df3b09732 100644 > --- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c > +++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c > @@ -11,6 +11,7 @@ > #include > #include > > +#include "VirtualMemory.h" > // > // Functions implemented by the migration handler > // > @@ -43,6 +44,83 @@ typedef volatile struct { > UINT32 done; > } MH_COMMAND_PARAMETERS; > > +// > +// Addresses for MH page table. > +// > +STATIC PAGE_TABLE_POOL *mPageTablePool = NULL; > +STATIC PHYSICAL_ADDRESS mMigrationHelperPageTables = 0; > + > +// > +// Offset for non-cbit mapping. > +// > +#define UNENC_VIRT_ADDR_BASE 0xffffff8000000000ULL > + > + > +/** > + Allocates and fills in custom page tables for Migration Handler. > + The MH must be able to write to any encrypted page. Thus, it > + uses an identity map where the C-bit is set for every page. The > + HV should never ask the MH to import/export a shared page. The > + MH must also be able to read some shared pages. The first 1GB > + of memory is mapped at offset UNENC_VIRT_ADDR_BASE. > + > +**/ > +VOID > +PrepareMigrationHandlerPageTables ( > + VOID > + ) > +{ > + UINTN PoolPages; > + VOID *Buffer; > + VOID *Start; > + PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry; > + PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; > + PAGE_TABLE_1G_ENTRY *Unenc1GEntry; > + UINT64 AddressEncMask; > + > + PoolPages = 1 + 10; > + Buffer = AllocateAlignedRuntimePages (PoolPages, PAGE_TABLE_POOL_ALIGNMENT); > + mPageTablePool = Buffer; > + mPageTablePool->NextPool = mPageTablePool; > + mPageTablePool->FreePages = PoolPages - 1; > + mPageTablePool->Offset = EFI_PAGES_TO_SIZE (1); > + > + Start = (UINT8 *)mPageTablePool + mPageTablePool->Offset; > + ZeroMem(Start, mPageTablePool->FreePages * EFI_PAGE_SIZE); > + > + AddressEncMask = 1ULL << 47; > + Preferably getting the encryption bit location from SEV CPUID information. > + PageMapLevel4Entry = Start; > + PageDirectory1GEntry = (PAGE_TABLE_1G_ENTRY*)((UINT8*)Start + EFI_PAGE_SIZE); > + Unenc1GEntry = (PAGE_TABLE_1G_ENTRY*)((UINT8*)Start + 2 * EFI_PAGE_SIZE); > + > + PageMapLevel4Entry = Start; > + PageMapLevel4Entry += PML4_OFFSET(0x0ULL); > + PageMapLevel4Entry->Uint64 = (UINT64)PageDirectory1GEntry | AddressEncMask | 0x23; > + > + PageMapLevel4Entry = Start; > + PageMapLevel4Entry += PML4_OFFSET(UNENC_VIRT_ADDR_BASE); // should be 511 > + PageMapLevel4Entry->Uint64 = (UINT64)Unenc1GEntry | AddressEncMask | 0x23; > + > + UINT64 PageAddr = 0; > + for (int i = 0; i < 512; i++, PageAddr += SIZE_1GB) { > + PAGE_TABLE_1G_ENTRY *e = PageDirectory1GEntry + i; > + e->Uint64 = PageAddr | AddressEncMask | 0xe3; // 1GB page > + } > + Changing encryption attributes of a page requires to flush it from the caches, you may need to do a clflush here. Thanks, Ashish > + UINT64 UnencPageAddr = 0; > + Unenc1GEntry->Uint64 = UnencPageAddr | 0xe3; // 1GB page unencrypted > + > + mMigrationHelperPageTables = (UINT64)Start | AddressEncMask; > +} > + > +VOID > +SwitchToMigrationHelperPageTables(VOID) > +{ > + AsmWriteCr3(mMigrationHelperPageTables); > +} > + > + > > VOID > EFIAPI > @@ -56,7 +134,12 @@ MigrationHandlerMain ( > > DebugPrint (DEBUG_INFO,"MIGRATION Handler Started\n"); > > - params_base = PcdGet32 (PcdConfidentialMigrationMailboxBase); > + SwitchToMigrationHelperPageTables(); > + > + // > + // Shared pages must be offset by UNENC_VIRT_ADDR_BASE. > + // > + params_base = PcdGet32 (PcdConfidentialMigrationMailboxBase) + UNENC_VIRT_ADDR_BASE; > params = (VOID *)params_base; > page_va = (VOID *)params_base + 0x1000; > > @@ -134,6 +217,8 @@ LaunchMigrationHandler ( > > MigrationHandlerCpuIndex = NumProc - 1; > > + PrepareMigrationHandlerPageTables(); > + > EFI_EVENT Event; > MpProto->GetProcessorInfo (MpProto, MigrationHandlerCpuIndex, &Tcb); > if (Tcb.StatusFlag != 7) { > @@ -154,6 +239,7 @@ LaunchMigrationHandler ( > if (PcdGetBool(PcdIsConfidentialMigrationTarget)) { > DebugPrint (DEBUG_INFO,"Waiting for incoming confidential migration.\n"); > DisableInterrupts (); > + SwitchToMigrationHelperPageTables(); > CpuDeadLoop (); > } > > -- > 2.20.1 >