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