On 8/8/22 15:18, Tom Lendacky wrote:
+/* Flag to indicate when the first per-CPU GHCB is registered */
+static bool ghcb_percpu_ready __section(".data");
So, there's a code path that can't be entered until this is set? Seems
like the least we can do it annotate that path with a
WARN_ON_ONCE(!ghcb_percpu_ready).
Sure, that can be added. Right now the only function that calls
vmgexit_psc() is covered (set_pages_state()/__set_pages_state()) and is
doing the right thing. But I guess if anything is added in the future,
that will provide details on what happened.
Also, how does having _one_ global variable work for indicating the
state of multiple per-cpu structures? The code doesn't seem to delay
setting this variable until after _all_ of the per-cpu state is ready.
All of the per-CPU GHCBs are allocated during the BSP boot, before any
AP is started. The APs only ever run the kernel_exc_vmm_communication()
#VC handler and only ever use the per-CPU version of the GHCB, never the
early boot version. This is based on the initial_vc_handler being
switched to the runtime #VC handler, kernel_exc_vmm_communication.
The trigger for the switch over for the BSP from the early boot GHCB to
the per-CPU GHCB is during setup_ghcb() after the initial_vc_handler has
been switched to kernel_exc_vmm_communication, which is just after the
per-CPU allocations. By putting the setting of the ghcb_percpu_ready in
setup_ghcb(), it indicates that the BSP per-CPU GHCB has been registered
and can be used.
That description makes the proposed comment even more confusing:
/* Flag to indicate when the first per-CPU GHCB is registered */
The important thing is that this variable is only _useful_ for the boot
CPU. After the boot CPU has allocated space for _itself_, it can then
go and stop using the MSR-based method.
The reason it's set after "the first" is because "the first" is also the
boot CPU, but referring to it as the "the first" is a bit oblique.
Maybe something like this:
/*
* Set after the boot CPU's GHCB is registered. At that point,
* it can be used for calls instead of MSRs.
*/