From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from userp2130.oracle.com (userp2130.oracle.com [156.151.31.86]) by mx.groups.io with SMTP id smtpd.web10.976.1610696749786138966 for ; Thu, 14 Jan 2021 23:45:50 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@oracle.com header.s=corp-2020-01-29 header.b=zzH3kdvU; spf=pass (domain: oracle.com, ip: 156.151.31.86, mailfrom: ankur.a.arora@oracle.com) Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 10F7jaB9124772; Fri, 15 Jan 2021 07:45:46 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2020-01-29; bh=n7P3u3jzo0DcLxpUv8U3/Ggw4mwlVxdRQQmz3/7OVVg=; b=zzH3kdvU9lPgAcsW2XI9OAtn0fCK0tJmjlsu2kXaXUS45+C1+Xk2GP4gRC0NIKDXiuoF B9TG7t8kzu5DNJW10At9K5qjscO8xHpxsnJjBGhCuHWgNglSkCVbx4AY4YGdiSrHXRJc x796vkCtxUfSd2axJWDOF54OkoJ2EWWYGo5MDPpR3vaLA/bNVppF2fZVenTMmMzmxMpr zhsvo3FMOYm22efdwQR3NVp1H6aHNENgxvhSWwua2Zu8KLljC0VbJ6WbEm3CKfiXYXrL Xb9xkyUXuKDAwN0+6A8cr8NR0d11ZJ1s+/NGfSoaDTELhco1mK3ZvoVAOQLQErAyVqmx Rg== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by userp2130.oracle.com with ESMTP id 360kvkbnhm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 15 Jan 2021 07:45:46 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 10F7dkjH132042; Fri, 15 Jan 2021 07:45:46 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserp3020.oracle.com with ESMTP id 360keavre8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 15 Jan 2021 07:45:45 +0000 Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id 10F7jjx9008882; Fri, 15 Jan 2021 07:45:45 GMT Received: from localhost.localdomain (/70.36.60.91) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 14 Jan 2021 23:45:45 -0800 From: "Ankur Arora" To: devel@edk2.groups.io Cc: imammedo@redhat.com, lersek@redhat.com, Ankur Arora , Jordan Justen , Ard Biesheuvel , Boris Ostrovsky , Aaron Young Subject: [PATCH v3 06/10] OvmfPkg/CpuHotplugSmm: support CPU eject Date: Thu, 14 Jan 2021 23:45:29 -0800 Message-Id: <20210115074533.277448-7-ankur.a.arora@oracle.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210115074533.277448-1-ankur.a.arora@oracle.com> References: <20210115074533.277448-1-ankur.a.arora@oracle.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9864 signatures=668683 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 adultscore=0 suspectscore=0 spamscore=0 mlxlogscore=999 malwarescore=0 bulkscore=0 mlxscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2101150044 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9864 signatures=668683 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 lowpriorityscore=0 bulkscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 impostorscore=0 spamscore=0 mlxscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2101150044 Content-Transfer-Encoding: quoted-printable PiSmmCpuDxeSmm exposes CPU_HOT_EJECT_DATA in SMRAM which we use as a communication channel between the two CPU hot-unplug phases. The first phase, unplug, happens by way of CpuHotplugMmi() where we collect CPUs that need to be unplugged and mark them for removal in SMM data structures. The second phase, eject, via SmmCpuFeaturesRendezvousExit() does the actual ejection once the CPU to be ejected is in the tail end of its SMI handling. This commit does not contain any of the ejection machinery, only sets up state to enable us to do that. Cc: Laszlo Ersek Cc: Jordan Justen Cc: Ard Biesheuvel Cc: Igor Mammedov Cc: Boris Ostrovsky Cc: Aaron Young Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3132 Signed-off-by: Ankur Arora --- OvmfPkg/CpuHotplugSmm/CpuHotplug.c | 49 +++++++++++++++++++++++++++++= ++-- OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf | 1 + 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c b/OvmfPkg/CpuHotplugSmm/Cpu= Hotplug.c index 38c71bc11864..f088049c7aef 100644 --- a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c +++ b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c @@ -32,11 +32,12 @@ STATIC EFI_MM_CPU_IO_PROTOCOL *mMmCpuIo; //=0D STATIC EFI_SMM_CPU_SERVICE_PROTOCOL *mMmCpuService;=0D //=0D -// This structure is a communication side-channel between the=0D +// These structures are communication side-channels between the // EFI_SMM_CPU_SERVICE_PROTOCOL consumer (i.e., this driver) and provider= =0D // (i.e., PiSmmCpuDxeSmm).=0D //=0D STATIC CPU_HOT_PLUG_DATA *mCpuHotPlugData;=0D +STATIC CPU_HOT_EJECT_DATA *mCpuHotEjectData; //=0D // SMRAM arrays for fetching the APIC IDs of processors with pending event= s (of=0D // known event types), for the time of just one MMI.=0D @@ -317,6 +318,23 @@ Fatal: return EFI_INTERRUPT_PENDING;=0D }=0D =0D +VOID +EFIAPI +CpuEject( + IN UINTN ProcessorNum + ) +{ + // + // APIC ID is UINT32, but mCpuHotEjectData->ApicIdMap[] is UINT64 + // so use UINT64 throughout. + // + UINT64 ApicId; + + ApicId =3D mCpuHotEjectData->ApicIdMap[ProcessorNum]; + if (ApicId =3D=3D CPU_EJECT_INVALID) { + return; + } +} =0D //=0D // Entry point function of this driver.=0D @@ -368,8 +386,14 @@ CpuHotplugEntry ( // Our DEPEX on EFI_SMM_CPU_SERVICE_PROTOCOL guarantees that PiSmmCpuDxe= Smm=0D // has pointed PcdCpuHotPlugDataAddress to CPU_HOT_PLUG_DATA in SMRAM.=0D //=0D + // Additionally, CPU HotUnplug is available only if CPU HotPlug is, so t= he + // same DEPEX also guarantees that PcdCpuHotEjectDataAddress points + // to CPU_HOT_EJECT_DATA in SMRAM. + // mCpuHotPlugData =3D (VOID *)(UINTN)PcdGet64 (PcdCpuHotPlugDataAddress);= =0D - if (mCpuHotPlugData =3D=3D NULL) {=0D + mCpuHotEjectData =3D (VOID *)(UINTN)PcdGet64 (PcdCpuHotEjectDataAddress); + + if (mCpuHotPlugData =3D=3D NULL) { Status =3D EFI_NOT_FOUND;=0D DEBUG ((DEBUG_ERROR, "%a: CPU_HOT_PLUG_DATA: %r\n", __FUNCTION__, Stat= us));=0D goto Fatal;=0D @@ -380,6 +404,9 @@ CpuHotplugEntry ( if (mCpuHotPlugData->ArrayLength =3D=3D 1) {=0D return EFI_UNSUPPORTED;=0D }=0D + ASSERT (mCpuHotEjectData && + (mCpuHotPlugData->ArrayLength =3D=3D mCpuHotEjectData->ArrayLeng= th)); + //=0D // Allocate the data structures that depend on the possible CPU count.=0D //=0D @@ -462,6 +489,24 @@ CpuHotplugEntry ( //=0D SmbaseInstallFirstSmiHandler ();=0D =0D + if (mCpuHotEjectData) { + UINT32 Idx; + // + // To do CPU eject we need to map ProcessorNum -> APIC_ID. However, by= the + // time CpuEject() is called (via SmmCpuFeaturesRendezvousExit()), we'= ve + // already called RemoveProcessor() and so the APIC ID cannot be looke= d up + // from SMM data structures. + // + // So use mCpuHotEjectData->ApicIdMap to map from ProcessorNum -> APIC= _ID. + // + // Initialize to known invalid values before installing the handler. + // + for (Idx =3D 0; Idx < mCpuHotEjectData->ArrayLength; Idx++) { + mCpuHotEjectData->ApicIdMap[Idx] =3D CPU_EJECT_INVALID; + } + mCpuHotEjectData->Handler =3D CpuEject; + } + return EFI_SUCCESS;=0D =0D ReleasePostSmmPen:=0D diff --git a/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf b/OvmfPkg/CpuHotplugSm= m/CpuHotplugSmm.inf index 04322b0d7855..51d022e10416 100644 --- a/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf +++ b/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf @@ -54,6 +54,7 @@ =0D [Pcd]=0D gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## CON= SUMES=0D + gUefiCpuPkgTokenSpaceGuid.PcdCpuHotEjectDataAddress ## CON= SUMES gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase ## CON= SUMES=0D =0D [FeaturePcd]=0D --=20 2.9.3