On 02/03/2022 08:10, Jan Beulich wrote: > On 01.03.2022 15:58, Andrew Cooper wrote: >> On 25/02/2022 08:24, Jan Beulich wrote: >>> On 22.02.2022 12:47, Andrew Cooper wrote: >>>> --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c >>>> +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c >>>> @@ -628,7 +628,7 @@ static void cf_check amd_dump_page_tables(struct >>>> domain *d) >>>> hd->arch.amd.paging_mode, 0, 0); >>>> } >>>> >>>> -static const struct iommu_ops __initconstrel _iommu_ops = { >>>> +static const struct iommu_ops __initconst_cf_clobber _iommu_ops = { >>> Following my initcall related remark on x86'es time.c I'm afraid I don't >>> see how this and ... >>> >>>> @@ -2794,7 +2793,7 @@ static int __init cf_check >>>> intel_iommu_quarantine_init(struct domain *d) >>>> return rc; >>>> } >>>> >>>> -static struct iommu_ops __initdata vtd_ops = { >>>> +static const struct iommu_ops __initconst_cf_clobber vtd_ops = { >>> ... this actually works. But I guess I must be overlooking something, as >>> I'm sure that you did test the change. >>> >>> Both ops structures reference a function, through .adjust_irq_affinities, >>> which isn't __init but which is used (besides here) for an initcall. With >>> the ENDBR removed by the time initcalls are run, these should cause #CP. >> This doesn't explode because the indirect calls are resolved to direct >> calls before the ENDBR's are clobbered to NOP4. > I'm afraid I don't understand: The problematic call is in do_initcalls(): > > for ( call = __presmp_initcall_end; call < __initcall_end; call++ ) > (*call)(); > > I don't see how this could be converted to a direct call.
Oh. iov_adjust_irq_affinities()'s double use is hiding here. The safety rule for cf_clobber is that there must not be any non-alt-called callers. We need to fix it: diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c index 657c7f619a51..b1af5085efda 100644 --- a/xen/drivers/passthrough/amd/iommu_init.c +++ b/xen/drivers/passthrough/amd/iommu_init.c @@ -831,7 +831,12 @@ int cf_check iov_adjust_irq_affinities(void) return 0; } -__initcall(iov_adjust_irq_affinities); + +int cf_check __init initcall_iov_adjust_irq_affinities(void) +{ + return iommu_call(&iommu_ops, adjust_irq_affinities); +} +__initcall(initcall_iov_adjust_irq_affinities); /* * Family15h Model 10h-1fh erratum 746 (IOMMU Logging May Stall Translations) > Afaics only pre-SMP initcalls are safe in this regard: do_presmp_initcalls() > is called immediately ahead of alternative_branches(). > > Isn't this (previously?) working related to your "x86/spec-ctrl: Disable > retpolines with CET-IBT"? No. It's because AMD CPUs don't have CET-IBT at this juncture, and will never encounter a faulting situation. This is exactly what the UD1 adjustment in Linux are intended to spot, because that would cause all AMD hardware to explode, not just the IBT-enabled ones. ~Andrew