Re: [PATCH v3 06/35] x86/bugs: Restructure mmio mitigation

Josh Poimboeuf
2025-02-12T23:16:48Z

On Wed, Feb 12, 2025 at 05:28:23PM +0000, Kaplan, David wrote:
> > > > Right here it does the following:
> > > >
> > > > /*
> > > > * Enable CPU buffer clear mitigation for host and VMM, if also affected
> > > > * by MDS or TAA. Otherwise, enable mitigation for VMM only.
> > > > */
> > > > if (boot_cpu_has_bug(X86_BUG_MDS) ||
> > > > (boot_cpu_has_bug(X86_BUG_TAA) &&
> > > > boot_cpu_has(X86_FEATURE_RTM)))
> > > > setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
> > > >
> > > > Isn't that a cross-mitigation dependency? i.e. if
> > > > X86_FEATURE_CLEAR_CPU_BUF gets enabled here then the other
> > > > mitigations would need to update their mitigation reporting?
> > >
> > > I don't think so, nobody should be looking at
> > > X86_FEATURE_CLEAR_CPU_BUF to determine their mitigation selection,
> > > they should only be looking at the other variables like taa_mitigation
> > > as done in the verw_mitigation_enabled() function.
> >
> > But isn't that a bug in the reporting? AFAICT one of the main motivations for the
> > cross dependencies (and the *_update_mitigation()
> > functions) is to fix the reporting if something actually ends up getting mitigated by
> > something else.
> >
> > For example, "mds=off tsx_async_abort=full" results in both MDS and TAA being
> > reported "Mitigated", because they share the same VERW mitigation.
> >
> > But in the above case, with X86_BUG_MDS, "mds=off mmio_stale_data=full"
> > shows MDS as vulnerable despite it actually being mitigated by VERW.
>
> Does it? In that case, mds_update_mitigation() will see that
> verw_mitigation_enabled() is true (because
> mmio_mitigation!=MMIO_MITIGATION_OFF) and then enable the mds
> mitigation.

Hrmmm, that's a bit of a maze.

static bool __init verw_mitigation_enabled(void)
{
return (mds_mitigation != MDS_MITIGATION_OFF ||
(taa_mitigation != TAA_MITIGATION_OFF &&
taa_mitigation != TAA_MITIGATION_TSX_DISABLED) ||
mmio_mitigation != MMIO_MITIGATION_OFF ||
rfds_mitigation != RFDS_MITIGATION_OFF);
}

That seems to work by accident. And I haven't managed to convince
myself it works for all edge cases.

Technically, checking !MMIO_MITIGATION_OFF alone isn't enough: MMIO only
needs global VERW if the MDS or TAA bugs are present.

Also, without ucode, the RFDS mitigation doesn't even attempt VERW for
some unknown reason, so just checking !RFDS_MITIGATION_OFF isn't
sufficient.

I'm thinking it should be something like

static bool __init taa_vulnerable(void)
{
boot_cpu_has_bug(X86_BUG_TAA) && boot_cpu_has(X86_FEATURE_RTM);
}

static bool __init mmio_needs_verw(void)
{
return boot_cpu_has_bug(X86_BUG_MDS) || taa_vulnerable();
}

static bool __init rfds_needs_ucode(void)
{
return !(x86_arch_cap_msr & ARCH_CAP_RFDS_CLEAR);
}

static bool __init verw_mitigation_enabled(void)
{
return mds_mitigation != MDS_MITIGATION_OFF ||
(taa_mitigation != TAA_MITIGATION_OFF && taa_vulnerable()) ||
(mmio_mitigation != MMIO_MITIGATION_OFF && mmio_needs_verw());
(rfds_mitigation != RFDS_MITIGATION_OFF && !rfds_needs_ucode());
}

--
Josh