From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM04-BN8-obe.outbound.protection.outlook.com (NAM04-BN8-obe.outbound.protection.outlook.com [40.107.100.62]) by mx.groups.io with SMTP id smtpd.web08.935.1626726265029353666 for ; Mon, 19 Jul 2021 13:24:25 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@amd.com header.s=selector1 header.b=iHD3ib16; 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.100.62, mailfrom: ashish.kalra@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LKNCVqDX1jOk3BX9jXivpnKN1xQ+G3t7hLu8W6lu7EgV1J6wfsmP/+Tx51K/8ftx+mxBwGrq5/ODyVI7A7qxGnT7e9hKUuYdp9yvFolCUshZu5ViZT0q2rTst/ss7hH9LlReTrRpW8hL3X7Wq4OlmAkLgIC+vHIHmecxqsdxGRvvtBCuE7Ud+eQRtKeTCTY5mW+sCWR3ceHG8lW683wblLk7JNvPWSplV315VJpVozzYAhttRnZ6Ep/OwiO1m7stfZS3LNpYg9+BVf3SSitxiV1QMGQJTHirXcz3S3JjTJGJ0mcY5/Yzgv3LGT8wQ8aRHnd/Y9bBjzQobsSm+1VqUg== 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=hsGShfYUtFcR5v26twbbxvlI1N7OdwJNAOYuoM0E800=; b=Xpg4qA2ARoOf8eXbmocnhh6nHCYaSCjs8LijsqfHpZWw5F5Y0W9pMrufJuuatV9hBqESIMF7AWoC5kDv2QzOnavA8SBkxr1VVujotU4SiZXsmlnpT2n7DFefasfu4krkoYGq2qHuSz0iWh4y6ylbO65DvKq/G5Zu9tdiVuUg+YbOHiBTX5BCdWWNg/Ss8QUSW3cPEmQ/0Ei0XsCoNrPMb8zhTiqIRBUYdoVR8LyXIpTQS78CpKs/CJDRHoiwlLI1OB/lqbrWlIzVxF1Ggz9AnBJkz0rOpzAt+ozUNjqVDIJt0+9WG3lBmAxZKKp1JLGIF9vgjur6RuAMXQ3fXSUagA== 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=hsGShfYUtFcR5v26twbbxvlI1N7OdwJNAOYuoM0E800=; b=iHD3ib16ycbbhHTQQ4N6FmHK2d8ryUmzF4mh/I7+TJ0gpa4aLspOmGg5sQJEwDk1zcIITjC+AMhMBjsKbD0vG9K+WTd4ggGUqA4at/2+Wt56PhE5tV8XyyiwYdOvP9joaAwVBJ0kUUfEFASg3D3RVMOgVAn45lV5avm0MJf1xhQ= Authentication-Results: amd.com; dkim=none (message not signed) header.d=none;amd.com; dmarc=none action=none header.from=amd.com; Received: from SN6PR12MB2767.namprd12.prod.outlook.com (2603:10b6:805:75::23) by SA0PR12MB4413.namprd12.prod.outlook.com (2603:10b6:806:9e::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4331.25; Mon, 19 Jul 2021 20:24:23 +0000 Received: from SN6PR12MB2767.namprd12.prod.outlook.com ([fe80::e8b2:38db:240f:b3ec]) by SN6PR12MB2767.namprd12.prod.outlook.com ([fe80::e8b2:38db:240f:b3ec%7]) with mapi id 15.20.4331.033; Mon, 19 Jul 2021 20:24:23 +0000 Date: Mon, 19 Jul 2021 20:24:16 +0000 From: "Ashish Kalra" To: Tom Lendacky Cc: devel@edk2.groups.io, dovmurik@linux.vnet.ibm.com, brijesh.singh@amd.com, tobin@ibm.com, jejb@linux.ibm.com, lersek@redhat.com, jordan.l.justen@intel.com, ard.biesheuvel@arm.com, erdemaktas@google.com, jiewen.yao@intel.com, min.m.xu@intel.com Subject: Re: [PATCH v5 1/4] OvmfPkg/BaseMemEncryptLib: Support to issue unencrypted hypercall Message-ID: <20210719202416.GA24481@ashkalra_ubuntu_server> References: <332172b262929880ef753a3bef36228115b7051a.1625687246.git.ashish.kalra@amd.com> <8a307c55-337d-b93f-b77c-a33846b8f965@amd.com> In-Reply-To: <8a307c55-337d-b93f-b77c-a33846b8f965@amd.com> User-Agent: Mutt/1.9.4 (2018-02-28) X-ClientProxiedBy: SN7PR04CA0107.namprd04.prod.outlook.com (2603:10b6:806:122::22) 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 SN7PR04CA0107.namprd04.prod.outlook.com (2603:10b6:806:122::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4331.21 via Frontend Transport; Mon, 19 Jul 2021 20:24:22 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 4c38678d-2622-4835-ae7a-08d94af33225 X-MS-TrafficTypeDiagnostic: SA0PR12MB4413: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:10000; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: CnShoqz6jtVVMG/piapjAVIMqBUr/wSFd1oJtJcTXsO/Kfo0ShOy+45Ub0Rkyrr3oUHB45aaNqbyb4u598tD4QkS3alOusPq2xkBvx3HSPUAPu5QC7rbvFELY2xEQNFevjrFQaIr7G0veu2UIdr7G3i4w7xWjRdUyzEOYEI0kzgWMZBEFSdGELufw4CY+mAlF7FGXLXcRRxrCQTEOPlNO5dIFAyRrpTFmy4GTN9EsX97OaXU7lzgDTngdVnhEEjp+gJRMX0aFK9ixpMp5U0Ajwyl6mOSLYzjSIiDHuzVvxA3p0Gu7tArQFN9iM3tJWW0SPSwAskIWrGC435evQS7TTbS6OWAr62ecKrrNEtaTW83wfwcFpw6T/yxJgsc1goSti6HmOqtXbuQizksF5T6hTf0a3W45D9NyT+E9c8s84eW/mCT7Hn6jxvC/C8MdYldpSmbv2/dQ3fhx6ZMGO3KniWwgXFuZBx7E6t1eHA/nUPZyMXuv7ovM51HEyWwyf+4BZ0i/ovet0T0ZyEhUxtqZJufcQFkH4qcgCipmBEj4zpNSAa2TbrHvP88OmY7NzQRUqb1sCqzV5tfL9VxYUf2BUKayBn46mHg5b+wTdZ642L7tcUYUefhqoP5RRl/jrPoZclIjwgfTxyDiN46tGUNj6Q6NnZShdy9hEI3vJ9OKzhTgGpRRk40GOz2jX5EB5VJQ7woat7QznYlwrsyc9jIbw== 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)(136003)(396003)(39860400002)(376002)(366004)(346002)(33656002)(4326008)(8676002)(6862004)(86362001)(316002)(8936002)(6666004)(53546011)(26005)(186003)(66556008)(66476007)(66946007)(55016002)(9686003)(478600001)(19627235002)(6496006)(52116002)(7416002)(5660300002)(956004)(6636002)(30864003)(1076003)(33716001)(83380400001)(2906002)(38350700002)(38100700002)(44832011);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?N/+r1JRTIcJHJFMhnKXOhtuc2A4oaFJRkgGdmxU1sOGFy/BpddDxpgnYMj1W?= =?us-ascii?Q?wfvYsqy7HWk9cZbmKxzRt6drQmyQQhbkFtmrpYH9573LlNPA0b42pH2xFFde?= =?us-ascii?Q?lWAqRYbTGwf+ZHxAoFSj1fsJNCKPPFaycc59nQmF9CW+brd036hLi7/ZW6XO?= =?us-ascii?Q?obHeMtuD6GetH69wb2/uJP3qRUj5u266aYhx9Ptju/uwVYOBmIziCLFgvkJR?= =?us-ascii?Q?RT8gJuohvqO6WGef++6ZrNB6OLNjOIC4+sbIh03Y5RtShcxeJ/9nyGVHJGMy?= =?us-ascii?Q?H67cUjzfXa1q/48/B4FNJ6hMXQpG3is0ML2Snc7NrtDetwW2Bg6Ue/FVwHii?= =?us-ascii?Q?QXy4HHxu4GTG5C5EQNZshWtHpQaJHS1m7TbS4sEQZ8g0ojbhTJaUunO4BaO5?= =?us-ascii?Q?yUgp+bN+kFKB6LHdLl0964RbOfPdU8htJLbm0aI6909qjKnWRM8kO5mn5gwI?= =?us-ascii?Q?GSNGtVyfs8czoViONYKn53h3DJZVFSXWWxfrrEqL1kt0v2Ihuuz14StU17EA?= =?us-ascii?Q?PXXSQiwsQbP4yQ93GHshMQQTAiYfXYxiVGzf3Pv2n70H24xknh9IBOCWpQ78?= =?us-ascii?Q?kOg+olyW8BYzm9w1h0qL/HH1OZdUQvG2S6n8cIh4Uc+09Y6cJO8jzw4Y5LEk?= =?us-ascii?Q?8WX271TfoJny2H+o3J1ZWwoJ3yRdH1udplatwArLJq+E1w0DwUUIZEAbJJP4?= =?us-ascii?Q?laugS27BQtmML/s7qsDL355B+xcaKHxn/3ZdySBhviSJ6VmaizA1TGhUDCq3?= =?us-ascii?Q?qb2z6qvbzpyeB0yC/44ax53/cLOzKbpqUx1nJ35UiPugJZi06Uln6RVtbo4q?= =?us-ascii?Q?DtlzkI5e0qwfJ4UtgNBkz/uLJeWjXeEHpWq5zxFE3kqnsH0t+XTue8LqBrjU?= =?us-ascii?Q?63SLBkoQToCx9qAz6OOo/u8k4YgWu/t6X++X+KE/ahAJkbcPBJv+Mrv+m0lV?= =?us-ascii?Q?Rwcaq78NJfodJIJ5QwW3bGq+7kITUsA6tJXhXfb6bCPnObYD7v3mGr40CpeE?= =?us-ascii?Q?6KQLzcjx6IGyXyxzqsI6DsO892WFXvm0RGtzde5jBAx7F9TSTsB/oyikE1jA?= =?us-ascii?Q?yZsQCXdITq1MSKENXDnCUV/XzyJoNjqkZAskyk2l6cVZnCNvJe+8GTTTna2W?= =?us-ascii?Q?wKUrfuBYXG21mdJIWKv3MATXGMOjjRUUy3c4RyIN1MWdapAFc5ufDgFlK4QZ?= =?us-ascii?Q?J4prq9AewOL/N+n/oymMp2NEVwER1B7hoK3zoYgfq571IQDzfDB5eiUGzR7D?= =?us-ascii?Q?1///vsXhFU7ES75TLJOxSYOm3r2WjslJM0sG4eLBxp/OJ0uGgPdsEJBiiAAo?= =?us-ascii?Q?/YmFRTvbqI1sPy9eONdgi+LB?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4c38678d-2622-4835-ae7a-08d94af33225 X-MS-Exchange-CrossTenant-AuthSource: SN6PR12MB2767.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Jul 2021 20:24:22.9873 (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: 3W/FP2S5TqU2R8CoEjpVA+Q/qBGU+3Y7oNkhZNMKlbewHRkNhIXCnyQ0kMD/XXrnD4KfnVxGEJ0joddbNPYFoQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB4413 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hello Tom, On Fri, Jul 16, 2021 at 09:11:23AM -0500, Tom Lendacky wrote: > On 7/8/21 9:07 AM, Ashish Kalra wrote: > > From: Ashish Kalra > > > > The patch subject is a bit confusing. Something more like "Add API to > issue hypercall on page encryption state change" or similar, since this is > issued for changes to shared and private, not just shared. > > > By default all the SEV guest memory regions are considered encrypted, > > if a guest changes the encryption attribute of the page (e.g mark a > > page as decrypted) then notify hypervisor. Hypervisor will need to > > track the unencrypted pages. The information will be used during > > guest live migration, guest page migration and guest debugging. > > > > This hypercall is used to notify hypervisor when the page's > > encryption state changes. > > This is a large patch. It looks like this should be split into a few patches. > - one patch for the MemEncryptSevLiveMigrationIsEnabled() API > - one patch for the SetMemoryEncDecHypercall3() API > - one patch to make use of the SetMemoryEncDecHypercall3() API. > Ok. > > > > Cc: Jordan Justen > > Cc: Laszlo Ersek > > Cc: Ard Biesheuvel > > Signed-off-by: Brijesh Singh > > Signed-off-by: Ashish Kalra > > --- > > OvmfPkg/Include/Library/MemEncryptSevLib.h | 69 ++++++++++++++++++++ > > OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf | 1 + > > OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c | 39 +++++++++++ > > OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c | 27 ++++++++ > > OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c | 51 +++++++++++++++ > > OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf | 1 + > > OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c | 39 +++++++++++ > > OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c | 38 +++++++++++ > > OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm | 33 ++++++++++ > > OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c | 54 +++++++++++++++ > > OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c | 22 ++++++- > > 11 files changed, 373 insertions(+), 1 deletion(-) > > > > diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h > > index 76d06c206c..c2b2a99a08 100644 > > --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h > > +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h > > @@ -90,6 +90,18 @@ MemEncryptSevIsEnabled ( > > VOID > > ); > > > > +/** > > + Returns a boolean to indicate whether SEV live migration is enabled. > > + > > + @retval TRUE SEV live migration is enabled > > + @retval FALSE SEV live migration is not enabled > > +**/ > > +BOOLEAN > > +EFIAPI > > +MemEncryptSevLiveMigrationIsEnabled ( > > + VOID > > + ); > > + > > /** > > This function clears memory encryption bit for the memory region specified by > > BaseAddress and NumPages from the current page table context. > > @@ -222,4 +234,61 @@ MemEncryptSevClearMmioPageEncMask ( > > IN UINTN NumPages > > ); > > > > +/** > > + This hypercall is used to notify hypervisor when the page's encryption > > + state changes. > > + > > + @param[in] PhysicalAddress The physical address that is the start address > > + of a memory region. The PhysicalAddress is > > + expected to be PAGE_SIZE aligned. > > + @param[in] Pages Number of pages in memory region. > > + @param[in] Status Encrypted(1) or Decrypted(0). > > + > > +@retval RETURN_SUCCESS Hypercall returned success. > > It looks like RETURN_UNSUPPORTED is also possible. > > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +SetMemoryEncDecHypercall3 ( > > + IN UINTN PhysicalAddress, > > + IN UINTN Pages, > > + IN UINTN Status > > + ); > > + > > +#define KVM_HC_MAP_GPA_RANGE 12 > > +#define KVM_MAP_GPA_RANGE_PAGE_SZ_4K 0 > > +#define KVM_MAP_GPA_RANGE_PAGE_SZ_2M BIT0 > > +#define KVM_MAP_GPA_RANGE_PAGE_SZ_1G BIT1 > > +#define KVM_MAP_GPA_RANGE_ENC_STAT(n) ((n) << 4) > > +#define KVM_MAP_GPA_RANGE_ENCRYPTED KVM_MAP_GPA_RANGE_ENC_STAT(1) > > +#define KVM_MAP_GPA_RANGE_DECRYPTED KVM_MAP_GPA_RANGE_ENC_STAT(0) > > You define these but don't use them (and you should). > Used later in another patch. > > + > > +#define KVM_FEATURE_MIGRATION_CONTROL BIT17 > > + > > +/** > > + Figures out if we are running inside KVM HVM and > > + KVM HVM supports SEV Live Migration feature. > > + > > + @retval TRUE SEV live migration is supported. > > + @retval FALSE SEV live migration is not supported. > > +**/ > > +BOOLEAN > > +EFIAPI > > +KvmDetectSevLiveMigrationFeature( > > + VOID > > + ); > > + > > +/** > > + Interface exposed by the ASM implementation of the core hypercall > > + > > + @retval Hypercall returned status. > > +**/ > > +UINTN > > +EFIAPI > > +SetMemoryEncDecHypercall3AsmStub ( > > + IN UINTN HypercallNum, > > + IN UINTN PhysicalAddress, > > + IN UINTN Pages, > > + IN UINTN Attributes > > + ); > > + > > #endif // _MEM_ENCRYPT_SEV_LIB_H_ > > diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf > > index f2e162d680..0c28afadee 100644 > > --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf > > +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf > > @@ -38,6 +38,7 @@ > > X64/PeiDxeVirtualMemory.c > > X64/VirtualMemory.c > > X64/VirtualMemory.h > > + X64/AsmHelperStub.nasm > > > > [Sources.IA32] > > Ia32/MemEncryptSevLib.c > > diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c > > index 2816f859a0..ead754cd7b 100644 > > --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c > > +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c > > @@ -20,6 +20,8 @@ > > STATIC BOOLEAN mSevStatus = FALSE; > > STATIC BOOLEAN mSevEsStatus = FALSE; > > STATIC BOOLEAN mSevStatusChecked = FALSE; > > +STATIC BOOLEAN mSevLiveMigrationStatus = FALSE; > > +STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE; > > > > STATIC UINT64 mSevEncryptionMask = 0; > > STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE; > > @@ -87,6 +89,24 @@ InternalMemEncryptSevStatus ( > > mSevStatusChecked = TRUE; > > } > > > > +/** > > + Figures out if we are running inside KVM HVM and > > + KVM HVM supports SEV Live Migration feature. > > +**/ > > +STATIC > > +VOID > > +EFIAPI > > +InternalDetectSevLiveMigrationFeature( > > + VOID > > + ) > > +{ > > + if (KvmDetectSevLiveMigrationFeature()) { > > + mSevLiveMigrationStatus = TRUE; > > + } > > + > > + mSevLiveMigrationStatusChecked = TRUE; > > +} > > + > > /** > > Returns a boolean to indicate whether SEV-ES is enabled. > > > > @@ -125,6 +145,25 @@ MemEncryptSevIsEnabled ( > > return mSevStatus; > > } > > > > +/** > > + Returns a boolean to indicate whether SEV live migration is enabled. > > + > > + @retval TRUE SEV live migration is enabled > > + @retval FALSE SEV live migration is not enabled > > +**/ > > +BOOLEAN > > +EFIAPI > > +MemEncryptSevLiveMigrationIsEnabled ( > > + VOID > > + ) > > +{ > > + if (!mSevLiveMigrationStatusChecked) { > > + InternalDetectSevLiveMigrationFeature (); > > + } > > + > > + return mSevLiveMigrationStatus; > > +} > > + > > /** > > Returns the SEV encryption mask. > > > > diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c > > index be260e0d10..62392309fe 100644 > > --- a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c > > +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c > > @@ -136,3 +136,30 @@ MemEncryptSevClearMmioPageEncMask ( > > // > > return RETURN_UNSUPPORTED; > > } > > + > > +/** > > + This hyercall is used to notify hypervisor when the page's encryption > > + state changes. > > + > > + @param[in] PhysicalAddress The physical address that is the start address > > + of a memory region. The physical address is > > + expected to be PAGE_SIZE aligned. > > + @param[in] Pages Number of Pages in the memory region. > > + @param[in] Status Encrypted(1) or Decrypted(0). > > + > > +@retval RETURN_SUCCESS Hypercall returned success. > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +SetMemoryEncDecHypercall3 ( > > + IN UINTN PhysicalAddress, > > + IN UINTN Pages, > > + IN UINTN Status > > + ) > > +{ > > + // > > + // Memory encryption bit is not accessible in 32-bit mode > > + // > > + return RETURN_UNSUPPORTED; > > +} > > + > > diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c > > index b4a9f464e2..0c9f7e17ba 100644 > > --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c > > +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c > > @@ -61,3 +61,54 @@ MemEncryptSevLocateInitialSmramSaveStateMapPages ( > > > > return RETURN_SUCCESS; > > } > > + > > +/** > > + Figures out if we are running inside KVM HVM and > > + KVM HVM supports SEV Live Migration feature. > > + > > + @retval TRUE SEV live migration is supported. > > + @retval FALSE SEV live migration is not supported. > > +**/ > > +BOOLEAN > > +EFIAPI > > +KvmDetectSevLiveMigrationFeature( > > + VOID > > + ) > > +{ > > + CHAR8 Signature[13]; > > + UINT32 mKvmLeaf; > > + UINT32 RegEax, RegEbx, RegEcx, RegEdx; > > + > > + Signature[12] = '\0'; > > + for (mKvmLeaf = 0x40000000; mKvmLeaf < 0x40010000; mKvmLeaf += 0x100) { > > + AsmCpuid (mKvmLeaf, > > + NULL, > > + (UINT32 *) &Signature[0], > > + (UINT32 *) &Signature[4], > > + (UINT32 *) &Signature[8]); > > + > > + if (AsciiStrCmp ((CHAR8 *) Signature, "KVMKVMKVM\0\0\0") == 0) { > > + DEBUG (( > > + DEBUG_INFO, > > + "%a: KVM Detected, signature = %s\n", > > + __FUNCTION__, > > + Signature > > + )); > > + > > + RegEax = mKvmLeaf + 1; > > + RegEcx = 0; > > + AsmCpuid (mKvmLeaf + 1, &RegEax, &RegEbx, &RegEcx, &RegEdx); > > + if ((RegEax & KVM_FEATURE_MIGRATION_CONTROL) != 0) { > > + DEBUG (( > > + DEBUG_INFO, > > + "%a: Live Migration feature supported\n", > > + __FUNCTION__ > > + )); > > + > > + return TRUE; > > + } > > + } > > + } > > + > > + return FALSE; > > +} > > diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf > > index 03a78c32df..3233ca7979 100644 > > --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf > > +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf > > @@ -38,6 +38,7 @@ > > X64/PeiDxeVirtualMemory.c > > X64/VirtualMemory.c > > X64/VirtualMemory.h > > + X64/AsmHelperStub.nasm > > > > [Sources.IA32] > > Ia32/MemEncryptSevLib.c > > diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c > > index e2fd109d12..9db6c2ef71 100644 > > --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c > > +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c > > @@ -20,6 +20,8 @@ > > STATIC BOOLEAN mSevStatus = FALSE; > > STATIC BOOLEAN mSevEsStatus = FALSE; > > STATIC BOOLEAN mSevStatusChecked = FALSE; > > +STATIC BOOLEAN mSevLiveMigrationStatus = FALSE; > > +STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE; > > > > STATIC UINT64 mSevEncryptionMask = 0; > > STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE; > > @@ -87,6 +89,24 @@ InternalMemEncryptSevStatus ( > > mSevStatusChecked = TRUE; > > } > > > > +/** > > + Figures out if we are running inside KVM HVM and > > + KVM HVM supports SEV Live Migration feature. > > +**/ > > +STATIC > > +VOID > > +EFIAPI > > +InternalDetectSevLiveMigrationFeature( > > + VOID > > + ) > > +{ > > + if (KvmDetectSevLiveMigrationFeature()) { > > + mSevLiveMigrationStatus = TRUE; > > + } > > + > > + mSevLiveMigrationStatusChecked = TRUE; > > +} > > + > > /** > > Returns a boolean to indicate whether SEV-ES is enabled. > > > > @@ -125,6 +145,25 @@ MemEncryptSevIsEnabled ( > > return mSevStatus; > > } > > > > +/** > > + Returns a boolean to indicate whether SEV live migration is enabled. > > + > > + @retval TRUE SEV live migration is enabled > > + @retval FALSE SEV live migration is not enabled > > +**/ > > +BOOLEAN > > +EFIAPI > > +MemEncryptSevLiveMigrationIsEnabled ( > > + VOID > > + ) > > +{ > > + if (!mSevLiveMigrationStatusChecked) { > > + InternalDetectSevLiveMigrationFeature (); > > + } > > + > > + return mSevLiveMigrationStatus; > > +} > > + > > /** > > Returns the SEV encryption mask. > > > > diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c > > index 56d8f3f318..b926c7b786 100644 > > --- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c > > +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c > > @@ -100,6 +100,44 @@ MemEncryptSevIsEnabled ( > > return Msr.Bits.SevBit ? TRUE : FALSE; > > } > > > > +/** > > + Interface exposed by the ASM implementation of the core hypercall > > + > > + @retval Hypercall returned status. > > +**/ > > +UINTN > > +EFIAPI > > +SetMemoryEncDecHypercall3AsmStub ( > > + IN UINTN HypercallNum, > > + IN UINTN PhysicalAddress, > > + IN UINTN Pages, > > + IN UINTN Attributes > > + ) > > +{ > > + // > > + // Not used in SEC phase. > > + // > > + return RETURN_UNSUPPORTED; > > +} > > + > > +/** > > + Returns a boolean to indicate whether SEV live migration is enabled. > > + > > + @retval TRUE SEV live migration is enabled > > + @retval FALSE SEV live migration is not enabled > > +**/ > > +BOOLEAN > > +EFIAPI > > +MemEncryptSevLiveMigrationIsEnabled ( > > + VOID > > + ) > > +{ > > + // > > + // Not used in SEC phase. > > + // > > + return FALSE; > > +} > > + > > /** > > Returns the SEV encryption mask. > > > > diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm > > new file mode 100644 > > index 0000000000..c7c11f77f1 > > --- /dev/null > > +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm > > @@ -0,0 +1,33 @@ > > +/** @file > > + > > + ASM helper stub to invoke hypercall > > + > > + Copyright (c) 2021, AMD Incorporated. All rights reserved.
> > + > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +DEFAULT REL > > +SECTION .text > > + > > +; UINTN > > +; EFIAPI > > +; SetMemoryEncDecHypercall3AsmStub ( > > +; IN UINTN HypercallNum, > > +; IN UINTN Arg1, > > +; IN UINTN Arg2, > > +; IN UINTN Arg3 > > +; ); > > +global ASM_PFX(SetMemoryEncDecHypercall3AsmStub) > > +ASM_PFX(SetMemoryEncDecHypercall3AsmStub): > > + ; UEFI calling conventions require RBX to > > + ; be nonvolatile/callee-saved. > > + push rbx > > + mov rax, rcx ; Copy HypercallNumber to rax > > + mov rbx, rdx ; Copy Arg1 to the register expected by KVM > > + mov rcx, r8 ; Copy Arg2 to register expected by KVM > > + mov rdx, r9 ; Copy Arg2 to register expected by KVM > > + vmmcall ; Call VMMCALL > > + pop rbx > > + ret > > diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c > > index a57e8fd37f..57447e69dc 100644 > > --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c > > +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c > > @@ -143,3 +143,57 @@ MemEncryptSevClearMmioPageEncMask ( > > ); > > > > } > > + > > +/** > > + This hyercall is used to notify hypervisor when the page's encryption > > + state changes. > > + > > + @param[in] PhysicalAddress The physical address that is the start address > > + of a memory region. The physical address is > > + expected to be PAGE_SIZE aligned. > > + @param[in] Pages Number of Pages in the memory region. > > + @param[in] Status Encrypted(1) or Decrypted(0). > > + > > +@retval RETURN_SUCCESS Hypercall returned success. > > I see RETURN_NO_MAPPING also, so you'll need to update the retvals everywhere. > Yes. > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +SetMemoryEncDecHypercall3 ( > > + IN UINTN PhysicalAddress, > > + IN UINTN Pages, > > + IN UINTN Status > > + ) > > +{ > > + RETURN_STATUS Ret; > > + INTN Error; > > Should be UINTN. > > > + > > + Ret = RETURN_UNSUPPORTED; > > + > > + if (MemEncryptSevLiveMigrationIsEnabled ()) { > > + Ret = EFI_SUCCESS; > > RETURN_SUCCESS since Ret is type RETURN_STATUS. Ok. > > + // > > + // The encryption bit is set/clear on the smallest page size, hence > > + // use the 4k page size in MAP_GPA_RANGE hypercall below. > > + // Also, the hypercall expects the guest physical address to be > > + // page-aligned. > > + // > > + Error = SetMemoryEncDecHypercall3AsmStub ( > > + KVM_HC_MAP_GPA_RANGE, > > + (PhysicalAddress & (~(EFI_PAGE_SIZE-1))), > > + Pages, > > + KVM_MAP_GPA_RANGE_PAGE_SZ_4K | KVM_MAP_GPA_RANGE_ENC_STAT(Status) > > Status is UINTN, but is passed from an enum variable. If for any reason > that enum should change in the future, this may break. So you should fixup > your call to explicitly pass 0 or 1 and then you can safely use that value > here. > > Maybe add an "ASSERT (Status == 0 || Status == 1)" to catch bad input values. > Ok. > > + ); > > + > > + if (Error != 0) { > > + DEBUG ((DEBUG_ERROR, > > + "SetMemoryEncDecHypercall3 failed, Phys = %Lx, Pages = %Ld, Err = %Ld\n", > > + PhysicalAddress, > > + Pages, > > + (INT64)Error)); > > + > > + Ret = RETURN_NO_MAPPING; > > + } > > + } > > + > > + return Ret; > > +} > > diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c > > index c696745f9d..0b1588a4c1 100644 > > --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c > > +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c > > @@ -536,7 +536,6 @@ EnableReadOnlyPageWriteProtect ( > > AsmWriteCr0 (AsmReadCr0() | BIT16); > > } > > > > - > > /** > > This function either sets or clears memory encryption bit for the memory > > region specified by PhysicalAddress and Length from the current page table > > @@ -585,6 +584,9 @@ SetMemoryEncDec ( > > UINT64 AddressEncMask; > > BOOLEAN IsWpEnabled; > > RETURN_STATUS Status; > > + UINTN Size; > > + BOOLEAN CBitChanged; > > + PHYSICAL_ADDRESS OrigPhysicalAddress; > > > > // > > // Set PageMapLevel4Entry to suppress incorrect compiler/analyzer warnings. > > @@ -636,6 +638,10 @@ SetMemoryEncDec ( > > > > Status = EFI_SUCCESS; > > > > + Size = Length; > > + CBitChanged = FALSE; > > + OrigPhysicalAddress = PhysicalAddress; > > + > > while (Length != 0) > > { > > // > > @@ -695,6 +701,7 @@ SetMemoryEncDec ( > > )); > > PhysicalAddress += BIT30; > > Length -= BIT30; > > + CBitChanged = TRUE; > > } else { > > // > > // We must split the page > > @@ -749,6 +756,7 @@ SetMemoryEncDec ( > > SetOrClearCBit (&PageDirectory2MEntry->Uint64, Mode); > > PhysicalAddress += BIT21; > > Length -= BIT21; > > + CBitChanged = TRUE; > > } else { > > // > > // We must split up this page into 4K pages > > @@ -791,6 +799,7 @@ SetMemoryEncDec ( > > SetOrClearCBit (&PageTableEntry->Uint64, Mode); > > PhysicalAddress += EFI_PAGE_SIZE; > > Length -= EFI_PAGE_SIZE; > > + CBitChanged = TRUE; > > } > > } > > } > > @@ -808,6 +817,17 @@ SetMemoryEncDec ( > > // > > CpuFlushTlb(); > > > > + // > > + // Notify Hypervisor on C-bit status > > + // > > + if (CBitChanged) { > > + Status = SetMemoryEncDecHypercall3 ( > > + OrigPhysicalAddress, > > + EFI_SIZE_TO_PAGES(Size), > > + !Mode > > "Mode" is a MAP_RANGE_MODE enum that is local to this file. So you need to > either move this to a common header file so you can use it with > SetMemoryEncDecHypercall3() or set a 0 or 1 based on Mode and pass that. > > Ok. Thanks, Ashish > > + ); > > + } > > + > > Done: > > // > > // Restore page table write protection, if any. > >