From nobody Fri Apr 26 10:56:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+64926+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+64926+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1599007441; cv=none; d=zohomail.com; s=zohoarc; b=Bkv1iTHY1v3WbassbeYM0dQQZz1Z5UhqGeuq5dIccEVnV/k+farf4fXvYl2hDyNc7eAHzzS5cuLgT6bqu0MV6nIT2f+jAZ6Bhb6+wwwSNDngzTYUUYaJFB65hA6LqeMHadtby8vML5WX2f1masy05K/a5rCATHJZyZ9zO+zs77I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1599007441; h=Content-Transfer-Encoding:Cc:Date:From:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To; bh=hKMPdjFcZmlA4TtIVEIjB26ISwc7NkKdgnOgdAb+xjU=; b=Se3oK9ftodkHYZ1pd0T15MEiS5jFQqMqlgczqHrq/oKdZvms0jTphGPq/Eoj6s/BJMDkjLHgG0QQJD0O/zp2y8daMs5+CYd458cHEjqpSyD/zKoYgAoiKXRRcMxktL4Vl9PyavXOjsAEoC3D8pTPI4VJok8/0+DIS5VDqKiup6Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+64926+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1599007441244284.59246531250835; Tue, 1 Sep 2020 17:44:01 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id qPnBYY1788612xgYR9HSX2rg; Tue, 01 Sep 2020 17:44:00 -0700 X-Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web11.10693.1599007439067585208 for ; Tue, 01 Sep 2020 17:43:59 -0700 IronPort-SDR: IQ4Cgk+t3SXXH+OCmwbahvpnDE3nd5bJ3d11Dmflu9wEmm4lXY0Bg5Z0johgZYIBz1OxpcONqn +ttIkd1KG1YA== X-IronPort-AV: E=McAfee;i="6000,8403,9731"; a="158289599" X-IronPort-AV: E=Sophos;i="5.76,381,1592895600"; d="scan'208";a="158289599" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2020 17:43:57 -0700 IronPort-SDR: j3dwDUAY8hIPfjceJjPfDU+tbHBr+P9rvQBSsV5dYgQpZjfTNma1jq+pD+W0gimhbHdI6/Dp8W EgDqxUQVKirQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,381,1592895600"; d="scan'208";a="502458441" X-Received: from ydong10-desktop.ccr.corp.intel.com ([10.239.154.145]) by fmsmga005.fm.intel.com with ESMTP; 01 Sep 2020 17:43:55 -0700 From: "Dong, Eric" To: devel@edk2.groups.io Cc: Ray Ni , Laszlo Ersek Subject: [edk2-devel] [PATCH] UefiCpuPkg/MpInitLib: Add check for CR3/GDT/IDT. Date: Wed, 2 Sep 2020 08:43:53 +0800 Message-Id: <20200902004353.1515-1-eric.dong@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,eric.dong@intel.com X-Gm-Message-State: i8YRqpQvjlHZuW4ZimlJIXqDx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1599007440; bh=t+qg2nOrt2dVI4pEasr0aSFZkddtc8EWpoAFniK+bEI=; h=Cc:Date:From:Reply-To:Subject:To; b=fluyhwO1udwuG/3ytafx982xY5pH6fSofJZ1/yzwoIkHdAT5VsCowfUfrpy8KQIQyUh bSnVdg3CeVeDzHPAOmdG3yWjLlfDOZgO2sFeLkOOCnRFi5FRHBtLeKWyeoOTs8jUK2i1l 95NbQrUySoaxE35OBbOkfNEjujInS/Rhm2k= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" AP needs to run from real mode to 32bit mode to LONG mode. Page table (pointed by CR3) and GDT are necessary to set up to correct value when CPU execution mode is switched to LONG mode. AP uses the same location page table (CR3) and GDT as what BSP uses. But when the page table or GDT is above 4GB, it's impossible for CPU to use because GDTR.base and CR3 are 32bits before switching to LONG mode. This patch adds check for the CR3, GDT.Base and IDT.Base to not above 32 bits restriction. Signed-off-by: Eric Dong Cc: Ray Ni Cc: Laszlo Ersek --- UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 8 +- UefiCpuPkg/Library/MpInitLib/MpLib.c | 108 +++++++++++++++++++----- UefiCpuPkg/Library/MpInitLib/MpLib.h | 6 +- 3 files changed, 97 insertions(+), 25 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/M= pInitLib/DxeMpLib.c index 2c00d72dde..27f12a75a8 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -393,13 +393,19 @@ MpInitChangeApLoopCallback ( ) { CPU_MP_DATA *CpuMpData; + EFI_STATUS Status; =20 CpuMpData =3D GetCpuMpData (); CpuMpData->PmCodeSegment =3D GetProtectedModeCS (); CpuMpData->Pm16CodeSegment =3D GetProtectedMode16CS (); CpuMpData->ApLoopMode =3D PcdGet8 (PcdCpuApLoopMode); mNumberToFinish =3D CpuMpData->CpuCount - 1; - WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE); + Status =3D WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR :: %a() Change Ap Loop Mode failed!\n", __= FUNCTION__)); + return; + } + while (mNumberToFinish > 0) { CpuPause (); } diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpIn= itLib/MpLib.c index 07426274f6..21b17a7b40 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -470,7 +470,7 @@ GetProcessorNumber ( =20 @return CPU count detected **/ -UINTN +EFI_STATUS CollectProcessorCount ( IN CPU_MP_DATA *CpuMpData ) @@ -478,12 +478,17 @@ CollectProcessorCount ( UINTN Index; CPU_INFO_IN_HOB *CpuInfoInHob; BOOLEAN X2Apic; + EFI_STATUS Status; =20 // // Send 1st broadcast IPI to APs to wakeup APs // CpuMpData->InitFlag =3D ApInitConfig; - WakeUpAP (CpuMpData, TRUE, 0, NULL, NULL, TRUE); + Status =3D WakeUpAP (CpuMpData, TRUE, 0, NULL, NULL, TRUE); + if (EFI_ERROR (Status)) { + return Status; + } + CpuMpData->InitFlag =3D ApInitDone; ASSERT (CpuMpData->CpuCount <=3D PcdGet32 (PcdCpuMaxLogicalProcessorNumb= er)); // @@ -520,7 +525,11 @@ CollectProcessorCount ( // // Wakeup all APs to enable x2APIC mode // - WakeUpAP (CpuMpData, TRUE, 0, ApFuncEnableX2Apic, NULL, TRUE); + Status =3D WakeUpAP (CpuMpData, TRUE, 0, ApFuncEnableX2Apic, NULL, TRU= E); + if (EFI_ERROR (Status)) { + return Status; + } + // // Wait for all known APs finished // @@ -546,7 +555,7 @@ CollectProcessorCount ( =20 DEBUG ((DEBUG_INFO, "MpInitLib: Find %d processors in system.\n", CpuMpD= ata->CpuCount)); =20 - return CpuMpData->CpuCount; + return EFI_SUCCESS; } =20 /** @@ -990,7 +999,7 @@ WaitApWakeup ( @param[in] CpuMpData Pointer to CPU MP Data =20 **/ -VOID +EFI_STATUS FillExchangeInfoData ( IN CPU_MP_DATA *CpuMpData ) @@ -1001,6 +1010,35 @@ FillExchangeInfoData ( IA32_CR4 Cr4; =20 ExchangeInfo =3D CpuMpData->MpCpuExchangeInfo; + ExchangeInfo->Cr3 =3D AsmReadCr3 (); + if (ExchangeInfo->Cr3 > 0xFFFFFFFF) { + // + // AP needs to run from real mode to 32bit mode to LONG mode. Page tab= le + // (pointed by CR3) and GDT are necessary to set up to correct value w= hen + // CPU execution mode is switched to LONG mode. + // AP uses the same location page table (CR3) and GDT as what BSP uses. + // But when the page table or GDT is above 4GB, it's impossible for CPU + // to use because GDTR.base and CR3 are 32bits before switching to LONG + // mode. + // Here add check for the CR3, GDT.Base and IDT.Base to not above 32 b= its + // limitation. + // + return EFI_UNSUPPORTED; + } + + // + // Get the BSP's data of GDT and IDT + // + AsmReadGdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->GdtrProfile); + if (ExchangeInfo->GdtrProfile.Base > 0xFFFFFFFF) { + return EFI_UNSUPPORTED; + } + + AsmReadIdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->IdtrProfile); + if (ExchangeInfo->IdtrProfile.Base > 0xFFFFFFFF) { + return EFI_UNSUPPORTED; + } + ExchangeInfo->Lock =3D 0; ExchangeInfo->StackStart =3D CpuMpData->Buffer; ExchangeInfo->StackSize =3D CpuMpData->CpuApStackSize; @@ -1009,9 +1047,6 @@ FillExchangeInfoData ( =20 ExchangeInfo->CodeSegment =3D AsmReadCs (); ExchangeInfo->DataSegment =3D AsmReadDs (); - - ExchangeInfo->Cr3 =3D AsmReadCr3 (); - ExchangeInfo->CFunction =3D (UINTN) ApWakeupFunction; ExchangeInfo->ApIndex =3D 0; ExchangeInfo->NumApsExecuting =3D 0; @@ -1037,13 +1072,6 @@ FillExchangeInfoData ( =20 ExchangeInfo->SevEsIsEnabled =3D CpuMpData->SevEsIsEnabled; ExchangeInfo->GhcbBase =3D (UINTN) CpuMpData->GhcbBase; - - // - // Get the BSP's data of GDT and IDT - // - AsmReadGdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->GdtrProfile); - AsmReadIdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->IdtrProfile); - // // Find a 32-bit code segment // @@ -1084,6 +1112,8 @@ FillExchangeInfoData ( (UINT32)ExchangeInfo->ModeOffset - (UINT32)CpuMpData->AddressMap.ModeTransitionOffse= t; ExchangeInfo->ModeHighSegment =3D (UINT16)ExchangeInfo->CodeSegment; + + return EFI_SUCCESS; } =20 /** @@ -1308,8 +1338,12 @@ SetSevEsJumpTable ( @param[in] Procedure The function to be invoked by AP @param[in] ProcedureArgument The argument to be passed into AP function @param[in] WakeUpDisabledAps Whether need to wake up disabled APs in br= oadcast mode. + + @retval EFI_SUCCESS Wake up the AP success. + @retval EFI_UNSUPPORTED Invalid CR3, IDT, GDT value caused fail to= wake up AP. + **/ -VOID +EFI_STATUS WakeUpAP ( IN CPU_MP_DATA *CpuMpData, IN BOOLEAN Broadcast, @@ -1324,6 +1358,7 @@ WakeUpAP ( CPU_AP_DATA *CpuData; BOOLEAN ResetVectorRequired; CPU_INFO_IN_HOB *CpuInfoInHob; + EFI_STATUS Status; =20 CpuMpData->FinishedCount =3D 0; ResetVectorRequired =3D FALSE; @@ -1333,7 +1368,10 @@ WakeUpAP ( ResetVectorRequired =3D TRUE; AllocateResetVector (CpuMpData); AllocateSevEsAPMemory (CpuMpData); - FillExchangeInfoData (CpuMpData); + Status =3D FillExchangeInfoData (CpuMpData); + if (EFI_ERROR (Status)) { + return Status; + } SaveLocalApicTimerSetting (CpuMpData); } =20 @@ -1500,6 +1538,8 @@ WakeUpAP ( // S3SmmInitDone Ppi. // CpuMpData->WakeUpByInitSipiSipi =3D (CpuMpData->ApLoopMode =3D=3D ApInHl= tLoop); + + return EFI_SUCCESS; } =20 /** @@ -1945,6 +1985,7 @@ MpInitLibInitialize ( UINTN ApResetVectorSize; UINTN BackupBufferAddr; UINTN ApIdtBase; + EFI_STATUS Status; =20 OldCpuMpData =3D GetCpuMpDataFromGuidedHob (); if (OldCpuMpData =3D=3D NULL) { @@ -2067,7 +2108,10 @@ MpInitLibInitialize ( // // Wakeup all APs and calculate the processor count in system // - CollectProcessorCount (CpuMpData); + Status =3D CollectProcessorCount (CpuMpData); + if (EFI_ERROR (Status)) { + return Status; + } } } else { // @@ -2118,7 +2162,11 @@ MpInitLibInitialize ( // CpuMpData->InitFlag =3D ApInitReconfig; } - WakeUpAP (CpuMpData, TRUE, 0, ApInitializeSync, CpuMpData, TRUE); + Status =3D WakeUpAP (CpuMpData, TRUE, 0, ApInitializeSync, CpuMpData, = TRUE); + if (EFI_ERROR (Status)) { + return Status; + } + // // Wait for all APs finished initialization // @@ -2262,6 +2310,7 @@ SwitchBSPWorker ( MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; BOOLEAN OldInterruptState; BOOLEAN OldTimerInterruptState; + EFI_STATUS Status; =20 // // Save and Disable Local APIC timer interrupt @@ -2333,7 +2382,10 @@ SwitchBSPWorker ( // // Need to wakeUp AP (future BSP). // - WakeUpAP (CpuMpData, FALSE, ProcessorNumber, FutureBSPProc, CpuMpData, T= RUE); + Status =3D WakeUpAP (CpuMpData, FALSE, ProcessorNumber, FutureBSPProc, C= puMpData, TRUE); + if (EFI_ERROR (Status)) { + return Status; + } =20 AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo); =20 @@ -2669,14 +2721,21 @@ StartupAllCPUsWorker ( CpuMpData->WaitEvent =3D WaitEvent; =20 if (!SingleThread) { - WakeUpAP (CpuMpData, TRUE, 0, Procedure, ProcedureArgument, FALSE); + Status =3D WakeUpAP (CpuMpData, TRUE, 0, Procedure, ProcedureArgument,= FALSE); + if (EFI_ERROR (Status)) { + return Status; + } } else { for (ProcessorNumber =3D 0; ProcessorNumber < ProcessorCount; Processo= rNumber++) { if (ProcessorNumber =3D=3D CallerNumber) { continue; } if (CpuMpData->CpuData[ProcessorNumber].Waiting) { - WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureA= rgument, TRUE); + Status =3D WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure,= ProcedureArgument, TRUE); + if (EFI_ERROR (Status)) { + return Status; + } + break; } } @@ -2795,7 +2854,10 @@ StartupThisAPWorker ( CpuData->ExpectedTime =3D CalculateTimeout (TimeoutInMicroseconds, &CpuD= ata->CurrentTime); CpuData->TotalTime =3D 0; =20 - WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgumen= t, TRUE); + Status =3D WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure, Proce= dureArgument, TRUE); + if (EFI_ERROR (Status)) { + return Status; + } =20 // // If WaitEvent is NULL, execute in blocking mode. diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpIn= itLib/MpLib.h index 02652eaae1..9cf5c0f9b4 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -459,8 +459,12 @@ GetSevEsAPMemory ( @param[in] Procedure The function to be invoked by AP @param[in] ProcedureArgument The argument to be passed into AP function @param[in] WakeUpDisabledAps Whether need to wake up disabled APs in br= oadcast mode. + + @retval EFI_SUCCESS Wake up the AP success. + @retval EFI_UNSUPPORTED Invalid CR3, IDT, GDT value caused fail to= wake up AP. + **/ -VOID +EFI_STATUS WakeUpAP ( IN CPU_MP_DATA *CpuMpData, IN BOOLEAN Broadcast, --=20 2.23.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#64926): https://edk2.groups.io/g/devel/message/64926 Mute This Topic: https://groups.io/mt/76573401/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-