From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (NAM10-MW2-obe.outbound.protection.outlook.com [40.107.94.57]) by mx.groups.io with SMTP id smtpd.web12.5467.1626438579177505691 for ; Fri, 16 Jul 2021 05:29:39 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@amd.com header.s=selector1 header.b=FRVYfOki; 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.94.57, mailfrom: ashish.kalra@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LAhgBJYzlyL4b9sg1Yec+YpVTDTGSGRjEdH7/HaCsW9ptkpwe8zFWtVQVHO4cgyGbNe6J/BdOC6AYr7r6GpsTz+t0dXSbV0N/jYXOYRrl09u++6tQ/vHk6l/fqMvB5bZTPbGRpQbpb6Xz+9BV5pI3ClhrH6hM8iTH0zX8/QwPuhrYn2pcnc4L9qu3ryavdl1HByHGKTtAPfCdWi4gw5OtGzqccBFvOFnOl4HHNmQQlNdRxJ//tig7C7poGaSiQk55DXjyJ1xMjdMcinLoKdCX/U5ARdWkWsRZu/1MNFdC86LbMmfNV9h5bKGCU3Qa+KtYaq2X2ja8tygKhTDlXxjgQ== 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=8mr/4xcjtUHOmXZiqXkHuKHGcvSoGr5fkccSgaXm7Wc=; b=Fi5OOAF07/KO0Zg11w+okDKPSCdQAxm4oDp6kjw+/T/3dSwtqshYJ/ou/p/iXiEcoYtOITqSPQMIcC9NEkYvlXeKgDjAvRhuK3ljDN9kW5uRgFYv8iTNCSaVvr9cHbSunLFRG4iRrQh4xfbrw35DRRRgfq8nJcnSX7yVFWLT5WmtmicpBffRd7LAuhq9G+JVusTvz2oOCWYFRGmDYbLgRwXJeAYSRI3sC//kLClt7JZiOVHKC0VstTKWvw9kZTWm7SfkllhAfaETo9AralZqO7YH70JBfwdSBeAmb0ZAKzGDDu4Noki42Ei+64wuPhdT9T3irR1IJ0SeEDNLG7z/+w== 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=8mr/4xcjtUHOmXZiqXkHuKHGcvSoGr5fkccSgaXm7Wc=; b=FRVYfOkicqbgCIKKCiJDDb2Iup6L76DofvRaiS1tVqUbJpcrxXGWi2/ndpM7yiRZvxB102FtR4aQCfoi9rj7idn5TLVf6EDQb4HHj7dVZ75MiS0VRxN5CwP+sSdIQQMDPapJv6NMTpSNIjCrVQ7kTURpzKh25kCFRehvnKfNFdw= 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 SN6PR12MB2781.namprd12.prod.outlook.com (2603:10b6:805:67::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4308.23; Fri, 16 Jul 2021 12:29:33 +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.4308.027; Fri, 16 Jul 2021 12:29:32 +0000 Date: Fri, 16 Jul 2021 12:29:25 +0000 From: "Ashish Kalra" To: Dov Murik Cc: devel@edk2.groups.io, dovmurik@linux.vnet.ibm.com, brijesh.singh@amd.com, tobin@ibm.com, Thomas.Lendacky@amd.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: <20210716122925.GA17576@ashkalra_ubuntu_server> References: <332172b262929880ef753a3bef36228115b7051a.1625687246.git.ashish.kalra@amd.com> In-Reply-To: User-Agent: Mutt/1.9.4 (2018-02-28) X-ClientProxiedBy: SA9PR13CA0101.namprd13.prod.outlook.com (2603:10b6:806:24::16) 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 SA9PR13CA0101.namprd13.prod.outlook.com (2603:10b6:806:24::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4352.13 via Frontend Transport; Fri, 16 Jul 2021 12:29:32 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b9ec4dbf-1792-4acc-f919-08d948555d4f X-MS-TrafficTypeDiagnostic: SN6PR12MB2781: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8882; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: P65txX7kbfnz0XLovwZb4NWKONNdKfbjxyMydyjVPjNGEAuAER6Wb9D00XckfGOx2yw9ppzt1wqIirw55gLP2jh06Qu/N1PgG0o2U5FX8SIk/rN9HYJM0riqlAKRW7T9R+vD8Gfm3LxMXnRlgBZffuSDAjW8zhUE+k/td1oPDZ9xWIWodFq8qkKrcNQBhUCORUAEVGJMMR75TWhRLM/JqtGcX6s//mzMffd8m5+dYJXjyDztx9RoyYGQ7Ig3zc7q24cYGpTZj291p/ABs8Q3hWiKczkUdB/i7dSJMBjo0ZHdewqHnF83alEdHA351xl+4mE9jwq8Z6p+U0bTtRp0iP/Ip1x/07mhLss6pBp9MMbrSJsunNGEiwFlWUsNtfU7gYNaoutsn2UJNFCBFpBEJ4IVI/XS/5AXax4H0gQYRQPUcdr8YGb1q2Or2q8udm3zM1NNqcD5UvQzRWi9RwCsr0qBmihJqwa56pUc4AgwW5+XgMjIQIAZNdUYObjlCnpAqLDcRvWxakIf08t6BOW/4g4l1I6gZh5dVFzRECnnehKhFmTWs0gGwwWiH0fjSnX/IpD+ExDr4/S2KKvfMmsRDeqKQSMBa/y7ypLS1b/ANxKaRyMCsrL6lzpSb5cR6rwrmV5hI8t+60nV0L5XRXm4IfMTeZv1krt2raHPxdK2vEUU5nwVS33RadW8gM93mxjRx85Q6b5XMgT2X+YUCtRzLg== 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)(366004)(39860400002)(346002)(136003)(66476007)(86362001)(66556008)(6916009)(44832011)(478600001)(6496006)(66946007)(8936002)(33656002)(55016002)(30864003)(316002)(7416002)(33716001)(6666004)(9686003)(53546011)(2906002)(5660300002)(19627235002)(38100700002)(38350700002)(4326008)(8676002)(83380400001)(26005)(956004)(52116002)(186003)(1076003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?2OeDwDxoSLwbzxbKiQXflSs1hpCK0DOgJAnsMF2ccfzqF8JPF8D2PThUbCoE?= =?us-ascii?Q?e3iyHhD1ZhtbKWW+dOYAY6XE1iw0JPS71zpZV1XDDv7QPIXPFfSpcygJZ12o?= =?us-ascii?Q?1grJEq0AvjlhjLbQDYXdYFDKsa83WtvZa26SRzzahuufPAF+lXlfIUN8cFjk?= =?us-ascii?Q?Ux/D4hlriv8xlf682fDARgb2RWA8iJMjZE6kkWH1XT5QNJANL1sRDegFbhJV?= =?us-ascii?Q?cnlnKup+A+OF5wEj3zTSqmcJzdquce4mcAV/JBErivR/VxrrC28kEAxJwauM?= =?us-ascii?Q?kJnZbLWzSqe9F07lNOmLyyI6AA+nUkbFlTgcYUabyL89x2x7GIuMQvBk9t1I?= =?us-ascii?Q?ZVwna9tOv6jXWayOC1fbjtjvNkrV9JtegoMvG3Mje08OnruTstgEuob8qJYY?= =?us-ascii?Q?WCgBhu0Qa51thZ564d1lHH4Q+jMKLZAciedFGwMfIKU06sunytezwL/pC1Ou?= =?us-ascii?Q?YWRDZce73z3hq2M6GW7fN87fufOLKDWbB0+x0altarxyRKqe4ULG/Qj7fsoe?= =?us-ascii?Q?KuqIIPXB5nTiPjWG+5L2vzLHoIGwyDCm6GraN2UE4qe+M2BkdKwZMLZ0Bpwo?= =?us-ascii?Q?k2R4rOMBR8LhoIC/IppKA0zmKqys1HMkQ+dWB9spq5BzP1s6mfEYAwtMs1o5?= =?us-ascii?Q?sZBS63nhzqtUd+tFZYCj5t7DErxEOirI2/eY1K5CFcLG/zxaS9O6UPpfd4/H?= =?us-ascii?Q?vJ+gKiK3ytF92RuszjkWRwm6nmXwDEqctWhmp7VrgipDpjpb3BQy4FtQ9TS4?= =?us-ascii?Q?ZfhAhv4zBwGkQDwYBBtGzj48Kw8cR14ducv5SvnlQWwck5gFqAVnL2dUYfka?= =?us-ascii?Q?sYRgQrVIKGmqUYHcV8l2VNfsi69k0azrvIlU+7MUuyxHJem8TGRVuyGAgUKJ?= =?us-ascii?Q?ynitjPlXMG4IHZrm+u2icW/JRAsTCQl9a2nPiVr5s5HKK//qt7Lyw/oRr1au?= =?us-ascii?Q?8AR22fG9FAEDC2WleRqNZJu7SOHHPf6vgq+KI0lZXVymRQCl++aXe3pIOtqA?= =?us-ascii?Q?6p+ln7RM7nlLfy1ddKDX+2rAUqWyAJOOZeKYpm0Q8d4QLzAT4pbgHMwdx9ob?= =?us-ascii?Q?quG0lWUwoQmny4AukYMKFs78+GrDwDlYEMpUQvAsjO7dlIN71J1f6cjLyWrH?= =?us-ascii?Q?wBQPzD28Z3D1gOYaVI73++IG4L6+P8CkH3G9Ut+wLmyn+6N0xCtp6GMO8+Zm?= =?us-ascii?Q?U0jvxLQ5urC7F2W6Y07em9dNlui5qkFW0Em4EEpZWFJOm9pExGrClcHZcXB5?= =?us-ascii?Q?G5aUJGJETz+E2iakUlfBNK7yXAuDJ6lVWKA9pGpnJ6R9HqwhjsXdQEBpsZPw?= =?us-ascii?Q?HqHq0N0Njf5p03ltP2qbw5F7?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: b9ec4dbf-1792-4acc-f919-08d948555d4f X-MS-Exchange-CrossTenant-AuthSource: SN6PR12MB2767.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Jul 2021 12:29:32.6866 (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: Xt011cGvt6qUQo9WbuCK6LivB11exwdnyHs7ZvhcVhFi5rCUgriwd3Jv7ZiNJCL+ZMOT/xb7LzpZwcTb35Rkjw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN6PR12MB2781 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hello Dov, On Thu, Jul 15, 2021 at 11:58:17PM +0300, Dov Murik wrote: > Hi Ashish, > > On 08/07/2021 17:07, Ashish Kalra wrote: > > From: Ashish Kalra > > > > 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. > > > > 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. > > +**/ > > +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) > > + > > +#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) { > > I assume this will also match if Signature is "KVMKVMKVM\0YZ". I don't > know if that matters. > I don't understand what do you mean by "KVMKVMKVM\0YZ", this is comparing for "KVMKVMKVM\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", > > I'd write: "%a: SEV Live Migration feature supported\n" > Ok. > > > + __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 > > Comment: s/Arg2/Arg3/ > Yes. > > + 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. > > or RETURN_UNSUPPORTED or RETURN_NO_MAPPING. > Ok. > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +SetMemoryEncDecHypercall3 ( > > + IN UINTN PhysicalAddress, > > + IN UINTN Pages, > > + IN UINTN Status > > Consider: > > IN BOOL IsEncrypted > > or: > > IN MAP_RANGE_MODE EncMode > > (it's not a Status in the EFI_STATUS sense that appears all around edk2). > Ok, i think i will prefer something like a MAP_RANGE_MODE. > > > + ) > > +{ > > + RETURN_STATUS Ret; > > + INTN Error; > > + > > Add assert for the expected alignment of PhysicalAddress, and then > you don't need to round it down when calling SetMemoryEncDecHypercall3AsmStub. > Cannot really use an assert here, as when the GCD map is being walked and the c-bit being cleared from MMIO and NonExistent memory spaces, the physical address range being passed may not be page-aligned, so adding an assert here prevents booting. Hence, rounding it down when calling SetMemoryEncDecHypercall3AsmStub below. > > > + Ret = RETURN_UNSUPPORTED; > > + > > + if (MemEncryptSevLiveMigrationIsEnabled ()) { > > + Ret = EFI_SUCCESS; > > + // > > + // 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))), > > Simpler: > > PhysicalAddress & ~EFI_PAGE_MASK > > Ok. > > + Pages, > > + KVM_MAP_GPA_RANGE_PAGE_SZ_4K | KVM_MAP_GPA_RANGE_ENC_STAT(Status) > > + ); > > + > > + 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 > > Here you pass !Mode (which is 0 or 1) as the third argument to > SetMemoryEncDecHypercall3 . > > But on patch 3/4 you pass KVM_MAP_GPA_RANGE_DECRYPTED (which is 0<<4); > but that hints that you expect either 0<<4 or 1<<4 as this third argument. > If this is the case, then here it should be: > > (Mode == SetCBit) ? KVM_MAP_GPA_RANGE_ENCRYPTED : KVM_MAP_GPA_RANGE_DECRYPTED > > If it's the other way around, then patch 3/4 needs to pass a simple 0 as > the third argument. > Yes, i need to pass a 0 (decrypted) as the third argument in that patch. Thanks, Ashish > > > > > + ); > > + } > > + > > Done: > > // > > // Restore page table write protection, if any. > >