On 10/13/2015 11:49 AM, Laszlo Ersek wrote:
On 10/13/15 18:35, Brian J. Johnson wrote:
On 10/13/2015 08:26 AM, Laszlo Ersek wrote:

First of all, if the edk2 reference code (in the SMM core and in
PiSmmCpuDxeSmm) depends on such behavior justifiedly, then I think we
have a bug in the PI specification. Namely, version 1.4 thereof does not
seem to require that EFI_SMM_CONTROL2_PROTOCOL.Trigger() raise an SMI on
*all* processors. (See volume 4, section 5.4.)

In particular, the EFI_SMM_CONTROL2_PROTOCOL.Trigger() specification
makes many references to SMI handling and dispatching. But I cannot make
a mental connection between an SMI "broadcast", and "handling and
dispatching" in edk2, since all "handling and dispatching" code in edk2
that is exposed via protocols, is non-reentrant with regard to multiple
VCPUs, to my knowledge.

One could argue that whatever code handles the SMI on the BP is
responsible for bringing the APs into SMM as well, before doing any
sensitive work. I'm not sure.

Traditionally, SMI handling has been global.  If the h/w didn't
broadcast the SMI to all CPUs, the SMI handler did so itself.  The BSP
would wait for all APs to "check in" to SMM, then it would do whatever
work the SMI required, and signal the APs to resume.  That ensured that
the OS wasn't active on the machine while the BSP was handling the SMI,
which was required for certain uses of SMI.

However, this (obviously) doesn't scale well, so Intel has been moving
towards signaling SMI to only a single processor, and avoiding the
machine-wide rendezvous when it isn't necessary.  BIOS implementations
may be lagging behind.

But... when is it necessary? Paolo implied it might not be necessary for
us because MTRR changes are not relevant on our virtual platform --
otherwise all CPUs would have to agree on the MTRR settings --, but
isn't there a security aspect to it as well?

Sometimes the hardware requires it. For instance, there have been situations where a platform needed a periodic SMI to allow the BIOS to kick a buggy I/O controller. The "kick" was not atomic, and normal OS driver activity could interfere with it. So BIOS used a system-wide SMI rendezvous to make sure that the OS wasn't running while it tweaked the hardware.

Security can be an aspect of it too. For instance, modern platforms support write protecting the system flash, with a bypass for operations initiated from SMM. If flash needs to be updated (eg. by a BIOS flash utility, or the EFI variable driver) the code doing the write uses a SMI to pass the request to a driver in SMM. The SMM driver validates the request, unlocks the flash, and performs the update. However, it would be a security hole if the OS was allowed to continue executing while the flash was unlocked. So the SMM code triggers a global rendezvous to make sure no unknown code is running.

But there are plenty of situations where a global rendezvous isn't necessary. For example, logging and clearing various non-fatal hardware errors (think corrected memory errors) can be done by a single thread while the rest of the system continues running. Avoiding the rendezvous in those cases saves a *ton* of time in the SMI handler, reducing the system-wide performance impact. As long as the SMI handler is quick enough, the OS doesn't mind losing a few cycles on one CPU.

(Or something like that. SMM isn't my specialty, so I may be off on the details. But that's the general idea.)
--

                                                Brian J. Johnson

--------------------------------------------------------------------

  My statements are my own, are not authorized by SGI, and do not
  necessarily represent SGI’s positions.
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to