From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by mx.groups.io with SMTP id smtpd.web09.14216.1583156661043435967 for ; Mon, 02 Mar 2020 05:44:21 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=Tn6gvgje; spf=pass (domain: linaro.org, ip: 209.85.128.68, mailfrom: ard.biesheuvel@linaro.org) Received: by mail-wm1-f68.google.com with SMTP id p9so11264780wmc.2 for ; Mon, 02 Mar 2020 05:44:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=Ms3R4ssbv2fQ59v3M3BVcMXonghwgQsBjgqykHRJJ8I=; b=Tn6gvgjeHXq1bWAYmRmEJIUQOHDAY+4/eafs7sPdguLadl0JdiP7TpPyECQdyqptwS /kC9cHmJCi+Dyl5nIXrcvVDyjwlvTgxB+4qWDxjilsmX40EVJ58GlBeNwQFS46zXit/p 34l+arIYbm86j5sD6UklfBKdmIsvaezvfzwk4iJIm7/1IOnsPlh6c6pd0n7Ncj0Me8Tf Z1nqbcfWxp9lQMNyRa+QIHcGae+PyyRY3bCM4r03xqsxawgim0lZZuu0wppcEYfyUK36 ir/D5iJ2KhqHui6CUk6glfIqVul/snjdc6+YxBfzI9exBxhudYfgcLYL0rDV8mJRTOAt lOHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=Ms3R4ssbv2fQ59v3M3BVcMXonghwgQsBjgqykHRJJ8I=; b=s8Cv5XifpU8rwMX7OT6EWUUrQUuSsCsmf1e+if8S6df9Z7TbRFivoD8ix5HKBrCNnr Ec8EgKbePtPNeVGCpecM91G6O75FT4Svnu5GXj0zjNUPQxuZ0ZOPWqPoaCZcVkZoEu1m x1Z2r9mIRhpFj8FIUv4a9ERlPAUhvFMtdR6xoaX62XFwYBnLLsvpzNIkKgSiC77k6y97 SfGgWTGpPvA9dEbHOWxGCvptuXXmSzGiriEV+KHz0d/Nyxqgn11mVL/IE9MwA0ILKlMw qkqwetmEyB/ha9kWyN+wWT6InIVVrag1X7SlWo2wFIj/nUUKvi38yQsjAsTRz4qKnfqo SX8g== X-Gm-Message-State: APjAAAXVk2+QAWBpKKf2jpCgDMXeEGvyghNFj1fQhvrmwbGGgqkq2Uq0 asyY8lGQhFB+McHmWdcJw2KkGfJdyoTQu0HuhFx7Cg== X-Google-Smtp-Source: APXvYqxbEKSYlfCzg9s1WtqO1TE5yYnuOvtke2zq5webk7UolM1qyTcwSg00OmhKdgNK5+hlSW9L/e/KMIgu6dRzH2g= X-Received: by 2002:a7b:cb93:: with SMTP id m19mr20880060wmi.133.1583156659278; Mon, 02 Mar 2020 05:44:19 -0800 (PST) MIME-Version: 1.0 References: <20200226221156.29589-1-lersek@redhat.com> <20200226221156.29589-7-lersek@redhat.com> In-Reply-To: <20200226221156.29589-7-lersek@redhat.com> From: "Ard Biesheuvel" Date: Mon, 2 Mar 2020 14:44:08 +0100 Message-ID: Subject: Re: [PATCH v2 06/16] OvmfPkg/CpuHotplugSmm: introduce skeleton for CPU Hotplug SMM driver To: Laszlo Ersek Cc: edk2-devel-groups-io , Igor Mammedov , Jiewen Yao , Jordan Justen , Michael Kinney , =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, 26 Feb 2020 at 23:12, Laszlo Ersek wrote: > > Add a new SMM driver skeleton that registers a root SMI handler, and > checks if the SMI control value (written to 0xB2) indicates a CPU hotplug > SMI. > > QEMU's ACPI payload will cause the OS to raise a broadcast SMI when a CPU > hotplug event occurs, namely by writing value 4 to IO Port 0xB2. In other > words, control value 4 is now allocated for this purpose; introduce the > ICH9_APM_CNT_CPU_HOTPLUG macro for it. > > The standard identifiers in this driver use the new MM (Management Mode) > terminology from the PI spec, not the earlier SMM (System Management Mode= ) > terms. > > Cc: Ard Biesheuvel > Cc: Igor Mammedov > Cc: Jiewen Yao > Cc: Jordan Justen > Cc: Michael Kinney > Cc: Philippe Mathieu-Daud=C3=A9 > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3D1512 > Signed-off-by: Laszlo Ersek > Acked-by: Ard Biesheuvel Reviewed-by: Ard Biesheuvel > --- > > Notes: > v2: > > - Pick up Ard's Acked-by, which is conditional on approval from Intel > reviewers on Cc. (I'd like to save Ard the churn of re-acking > unmodified patches.) > > OvmfPkg/OvmfPkgIa32.dsc | 1 + > OvmfPkg/OvmfPkgIa32X64.dsc | 1 + > OvmfPkg/OvmfPkgX64.dsc | 1 + > OvmfPkg/OvmfPkgIa32.fdf | 1 + > OvmfPkg/OvmfPkgIa32X64.fdf | 1 + > OvmfPkg/OvmfPkgX64.fdf | 1 + > OvmfPkg/Include/IndustryStandard/Q35MchIch9.h | 5 +- > OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf | 48 +++++ > OvmfPkg/CpuHotplugSmm/CpuHotplug.c | 191 ++++++++++++++++++++ > 9 files changed, 248 insertions(+), 2 deletions(-) > > diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc > index 8c065ca7cec9..78310da44a5f 100644 > --- a/OvmfPkg/OvmfPkgIa32.dsc > +++ b/OvmfPkg/OvmfPkgIa32.dsc > @@ -851,44 +851,45 @@ [Components] > > OvmfPkg/PlatformDxe/Platform.inf > OvmfPkg/IoMmuDxe/IoMmuDxe.inf > > !if $(SMM_REQUIRE) =3D=3D TRUE > OvmfPkg/SmmAccess/SmmAccess2Dxe.inf > OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf > UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf > > # > # SMM Initial Program Load (a DXE_RUNTIME_DRIVER) > # > MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf > > # > # SMM_CORE > # > MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf > > # > # Privileged drivers (DXE_SMM_DRIVER modules) > # > + OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf > UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf > MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf { > > LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf > } > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf { > > SmmCpuPlatformHookLib|OvmfPkg/Library/SmmCpuPlatformHookLibQemu/Sm= mCpuPlatformHookLibQemu.inf > SmmCpuFeaturesLib|OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeatures= Lib.inf > } > > # > # Variable driver stack (SMM) > # > OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf > MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf { > > NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf > } > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf > > diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc > index 944b785e61a9..428578a4f839 100644 > --- a/OvmfPkg/OvmfPkgIa32X64.dsc > +++ b/OvmfPkg/OvmfPkgIa32X64.dsc > @@ -865,44 +865,45 @@ [Components.X64] > OvmfPkg/PlatformDxe/Platform.inf > OvmfPkg/AmdSevDxe/AmdSevDxe.inf > OvmfPkg/IoMmuDxe/IoMmuDxe.inf > > !if $(SMM_REQUIRE) =3D=3D TRUE > OvmfPkg/SmmAccess/SmmAccess2Dxe.inf > OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf > UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf > > # > # SMM Initial Program Load (a DXE_RUNTIME_DRIVER) > # > MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf > > # > # SMM_CORE > # > MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf > > # > # Privileged drivers (DXE_SMM_DRIVER modules) > # > + OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf > UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf > MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf { > > LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf > } > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf { > > SmmCpuPlatformHookLib|OvmfPkg/Library/SmmCpuPlatformHookLibQemu/Sm= mCpuPlatformHookLibQemu.inf > SmmCpuFeaturesLib|OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeatures= Lib.inf > } > > # > # Variable driver stack (SMM) > # > OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf > MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf { > > NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf > } > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf > > diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc > index 8de0f7179784..73b92f259201 100644 > --- a/OvmfPkg/OvmfPkgX64.dsc > +++ b/OvmfPkg/OvmfPkgX64.dsc > @@ -863,44 +863,45 @@ [Components] > OvmfPkg/PlatformDxe/Platform.inf > OvmfPkg/AmdSevDxe/AmdSevDxe.inf > OvmfPkg/IoMmuDxe/IoMmuDxe.inf > > !if $(SMM_REQUIRE) =3D=3D TRUE > OvmfPkg/SmmAccess/SmmAccess2Dxe.inf > OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf > UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf > > # > # SMM Initial Program Load (a DXE_RUNTIME_DRIVER) > # > MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf > > # > # SMM_CORE > # > MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf > > # > # Privileged drivers (DXE_SMM_DRIVER modules) > # > + OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf > UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf > MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf { > > LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf > } > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf { > > SmmCpuPlatformHookLib|OvmfPkg/Library/SmmCpuPlatformHookLibQemu/Sm= mCpuPlatformHookLibQemu.inf > SmmCpuFeaturesLib|OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeatures= Lib.inf > } > > # > # Variable driver stack (SMM) > # > OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf > MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf { > > NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf > } > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf > > diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf > index 63607551ed75..61b891765c56 100644 > --- a/OvmfPkg/OvmfPkgIa32.fdf > +++ b/OvmfPkg/OvmfPkgIa32.fdf > @@ -301,44 +301,45 @@ [FV.DXEFV] > INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf > INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf > > !ifdef $(CSM_ENABLE) > INF OvmfPkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf > INF OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf > INF RuleOverride=3DCSM OvmfPkg/Csm/Csm16/Csm16.inf > !else > INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf > !endif > > INF OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf > INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf > INF OvmfPkg/PlatformDxe/Platform.inf > INF OvmfPkg/IoMmuDxe/IoMmuDxe.inf > > !if $(SMM_REQUIRE) =3D=3D TRUE > INF OvmfPkg/SmmAccess/SmmAccess2Dxe.inf > INF OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf > INF UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf > INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf > INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf > +INF OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf > INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf > INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf > INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > > # > # Variable driver stack (SMM) > # > INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf > INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.= inf > INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.in= f > > !else > > # > # Variable driver stack (non-SMM) > # > INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf > INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf > INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.= inf > INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > !endif > diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf > index 0488e5d95ffe..501b4fcb7b67 100644 > --- a/OvmfPkg/OvmfPkgIa32X64.fdf > +++ b/OvmfPkg/OvmfPkgIa32X64.fdf > @@ -308,44 +308,45 @@ [FV.DXEFV] > INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf > > !ifdef $(CSM_ENABLE) > INF OvmfPkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf > INF OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf > INF RuleOverride=3DCSM OvmfPkg/Csm/Csm16/Csm16.inf > !else > INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf > !endif > > INF OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf > INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf > INF OvmfPkg/PlatformDxe/Platform.inf > INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf > INF OvmfPkg/IoMmuDxe/IoMmuDxe.inf > > !if $(SMM_REQUIRE) =3D=3D TRUE > INF OvmfPkg/SmmAccess/SmmAccess2Dxe.inf > INF OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf > INF UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf > INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf > INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf > +INF OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf > INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf > INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf > INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > > # > # Variable driver stack (SMM) > # > INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf > INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.= inf > INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.in= f > > !else > > # > # Variable driver stack (non-SMM) > # > INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf > INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf > INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.= inf > INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > !endif > diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf > index 0488e5d95ffe..501b4fcb7b67 100644 > --- a/OvmfPkg/OvmfPkgX64.fdf > +++ b/OvmfPkg/OvmfPkgX64.fdf > @@ -308,44 +308,45 @@ [FV.DXEFV] > INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf > > !ifdef $(CSM_ENABLE) > INF OvmfPkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf > INF OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf > INF RuleOverride=3DCSM OvmfPkg/Csm/Csm16/Csm16.inf > !else > INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf > !endif > > INF OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf > INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf > INF OvmfPkg/PlatformDxe/Platform.inf > INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf > INF OvmfPkg/IoMmuDxe/IoMmuDxe.inf > > !if $(SMM_REQUIRE) =3D=3D TRUE > INF OvmfPkg/SmmAccess/SmmAccess2Dxe.inf > INF OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf > INF UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf > INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf > INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf > +INF OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf > INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf > INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf > INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > > # > # Variable driver stack (SMM) > # > INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf > INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.= inf > INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.in= f > > !else > > # > # Variable driver stack (non-SMM) > # > INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf > INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf > INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.= inf > INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > !endif > diff --git a/OvmfPkg/Include/IndustryStandard/Q35MchIch9.h b/OvmfPkg/Incl= ude/IndustryStandard/Q35MchIch9.h > index cb705fee92ca..73db4b59a111 100644 > --- a/OvmfPkg/Include/IndustryStandard/Q35MchIch9.h > +++ b/OvmfPkg/Include/IndustryStandard/Q35MchIch9.h > @@ -90,37 +90,38 @@ > #define POWER_MGMT_REGISTER_Q35(Offset) \ > PCI_LIB_ADDRESS (0, 0x1f, 0, (Offset)) > > #define POWER_MGMT_REGISTER_Q35_EFI_PCI_ADDRESS(Offset) \ > EFI_PCI_ADDRESS (0, 0x1f, 0, (Offset)) > > #define ICH9_PMBASE 0x40 > #define ICH9_PMBASE_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT= 11 | \ > BIT10 | BIT9 | BIT8 | BIT7) > > #define ICH9_ACPI_CNTL 0x44 > #define ICH9_ACPI_CNTL_ACPI_EN BIT7 > > #define ICH9_GEN_PMCON_1 0xA0 > #define ICH9_GEN_PMCON_1_SMI_LOCK BIT4 > > #define ICH9_RCBA 0xF0 > #define ICH9_RCBA_EN BIT0 > > // > // IO ports > // > -#define ICH9_APM_CNT 0xB2 > -#define ICH9_APM_STS 0xB3 > +#define ICH9_APM_CNT 0xB2 > +#define ICH9_APM_CNT_CPU_HOTPLUG 0x04 > +#define ICH9_APM_STS 0xB3 > > #define ICH9_CPU_HOTPLUG_BASE 0x0CD8 > > // > // IO ports relative to PMBASE > // > #define ICH9_PMBASE_OFS_SMI_EN 0x30 > #define ICH9_SMI_EN_APMC_EN BIT5 > #define ICH9_SMI_EN_GBL_SMI_EN BIT0 > > #define ICH9_ROOT_COMPLEX_BASE 0xFED1C000 > > #endif > diff --git a/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf b/OvmfPkg/CpuHotplug= Smm/CpuHotplugSmm.inf > new file mode 100644 > index 000000000000..fa70858a8dab > --- /dev/null > +++ b/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf > @@ -0,0 +1,48 @@ > +## @file > +# Root SMI handler for VCPU hotplug SMIs. > +# > +# Copyright (c) 2020, Red Hat, Inc. > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > + > +[Defines] > + INF_VERSION =3D 1.29 > + PI_SPECIFICATION_VERSION =3D 0x00010046 #= PI-1.7.0 > + BASE_NAME =3D CpuHotplugSmm > + FILE_GUID =3D 84EEA114-C6BE-4445-8F90-51D97863E363 > + MODULE_TYPE =3D DXE_SMM_DRIVER > + ENTRY_POINT =3D CpuHotplugEntry > + > +# > +# The following information is for reference only and not required by th= e build > +# tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 > +# > + > +[Sources] > + CpuHotplug.c > + > +[Packages] > + MdePkg/MdePkg.dec > + OvmfPkg/OvmfPkg.dec > + > +[LibraryClasses] > + BaseLib > + DebugLib > + MmServicesTableLib > + PcdLib > + UefiDriverEntryPoint > + > +[Protocols] > + gEfiMmCpuIoProtocolGuid ## C= ONSUMES > + > +[Pcd] > + gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase ## C= ONSUMES > + > +[FeaturePcd] > + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire ## C= ONSUMES > + > +[Depex] > + gEfiMmCpuIoProtocolGuid > diff --git a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c b/OvmfPkg/CpuHotplugSmm/C= puHotplug.c > new file mode 100644 > index 000000000000..fd09403eabf3 > --- /dev/null > +++ b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c > @@ -0,0 +1,191 @@ > +/** @file > + Root SMI handler for VCPU hotplug SMIs. > + > + Copyright (c) 2020, Red Hat, Inc. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include // ICH9_APM_CNT > +#include // CpuDeadLoop() > +#include // ASSERT() > +#include // gMmst > +#include // PcdGetBool() > +#include // EFI_MM_CPU_IO_PROTOCOL > +#include // EFI_STATUS > + > +// > +// We use this protocol for accessing IO Ports. > +// > +STATIC EFI_MM_CPU_IO_PROTOCOL *mMmCpuIo; > +// > +// Represents the registration of the CPU Hotplug MMI handler. > +// > +STATIC EFI_HANDLE mDispatchHandle; > + > + > +/** > + CPU Hotplug MMI handler function. > + > + This is a root MMI handler. > + > + @param[in] DispatchHandle The unique handle assigned to this hand= ler by > + EFI_MM_SYSTEM_TABLE.MmiHandlerRegister(= ). > + > + @param[in] Context Context passed in by > + EFI_MM_SYSTEM_TABLE.MmiManage(). Due to > + CpuHotplugMmi() being a root MMI handle= r, > + Context is ASSERT()ed to be NULL. > + > + @param[in,out] CommBuffer Ignored, due to CpuHotplugMmi() being a= root > + MMI handler. > + > + @param[in,out] CommBufferSize Ignored, due to CpuHotplugMmi() being a= root > + MMI handler. > + > + @retval EFI_SUCCESS The MMI was handled and the = MMI > + source was quiesced. When re= turned > + by a non-root MMI handler, > + EFI_SUCCESS terminates the > + processing of MMI handlers i= n > + EFI_MM_SYSTEM_TABLE.MmiManag= e(). > + For a root MMI handler (i.e.= , for > + the present function too), > + EFI_SUCCESS behaves identica= lly to > + EFI_WARN_INTERRUPT_SOURCE_QU= IESCED, > + as further root MMI handlers= are > + going to be called by > + EFI_MM_SYSTEM_TABLE.MmiManag= e() > + anyway. > + > + @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The MMI source has been qu= iesced, > + but other handlers should = still > + be called. > + > + @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The MMI source is still pe= nding, > + and other handlers should = still > + be called. > + > + @retval EFI_INTERRUPT_PENDING The MMI source could not b= e > + quiesced. > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +CpuHotplugMmi ( > + IN EFI_HANDLE DispatchHandle, > + IN CONST VOID *Context OPTIONAL, > + IN OUT VOID *CommBuffer OPTIONAL, > + IN OUT UINTN *CommBufferSize OPTIONAL > + ) > +{ > + EFI_STATUS Status; > + UINT8 ApmControl; > + > + // > + // Assert that we are entering this function due to our root MMI handl= er > + // registration. > + // > + ASSERT (DispatchHandle =3D=3D mDispatchHandle); > + // > + // When MmiManage() is invoked to process root MMI handlers, the calle= r (the > + // MM Core) is expected to pass in a NULL Context. MmiManage() then pa= sses > + // the same NULL Context to individual handlers. > + // > + ASSERT (Context =3D=3D NULL); > + // > + // Read the MMI command value from the APM Control Port, to see if thi= s is an > + // MMI we should care about. > + // > + Status =3D mMmCpuIo->Io.Read (mMmCpuIo, MM_IO_UINT8, ICH9_APM_CNT, 1, > + &ApmControl); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to read ICH9_APM_CNT: %r\n", __FUNC= TION__, > + Status)); > + // > + // We couldn't even determine if the MMI was for us or not. > + // > + goto Fatal; > + } > + > + if (ApmControl !=3D ICH9_APM_CNT_CPU_HOTPLUG) { > + // > + // The MMI is not for us. > + // > + return EFI_WARN_INTERRUPT_SOURCE_QUIESCED; > + } > + > + // > + // We've handled this MMI. > + // > + return EFI_SUCCESS; > + > +Fatal: > + ASSERT (FALSE); > + CpuDeadLoop (); > + // > + // We couldn't handle this MMI. > + // > + return EFI_INTERRUPT_PENDING; > +} > + > + > +// > +// Entry point function of this driver. > +// > +EFI_STATUS > +EFIAPI > +CpuHotplugEntry ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + // > + // This module should only be included when SMM support is required. > + // > + ASSERT (FeaturePcdGet (PcdSmmSmramRequire)); > + // > + // This driver depends on the dynamically detected "SMRAM at default S= MBASE" > + // feature. > + // > + if (!PcdGetBool (PcdQ35SmramAtDefaultSmbase)) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Errors from here on are fatal; we cannot allow the boot to proceed = if we > + // can't set up this driver to handle CPU hotplug. > + // > + // First, collect the protocols needed later. All of these protocols a= re > + // listed in our module DEPEX. > + // > + Status =3D gMmst->MmLocateProtocol (&gEfiMmCpuIoProtocolGuid, > + NULL /* Registration */, (VOID **)&mMmCpuIo); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: locate MmCpuIo: %r\n", __FUNCTION__, Statu= s)); > + goto Fatal; > + } > + > + // > + // Register the handler for the CPU Hotplug MMI. > + // > + Status =3D gMmst->MmiHandlerRegister ( > + CpuHotplugMmi, > + NULL, // HandlerType: root MMI handler > + &mDispatchHandle > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: MmiHandlerRegister(): %r\n", __FUNCTION__, > + Status)); > + goto Fatal; > + } > + > + return EFI_SUCCESS; > + > +Fatal: > + ASSERT (FALSE); > + CpuDeadLoop (); > + return Status; > +} > -- > 2.19.1.3.g30247aa5d201 > >