--- a/sys/dev/virtual/hyperv/x86_64/hyperv_machdep.c +++ b/sys/dev/virtual/hyperv/x86_64/hyperv_machdep.c @@ -219,9 +219,13 @@ hyperv_md_uninit(void) val = rdmsr(MSR_HV_REFERENCE_TSC); wrmsr(MSR_HV_REFERENCE_TSC, val & MSR_HV_REFTSC_RSVD_MASK); - hyperv_dmamem_free(&hyperv_ref_tsc.tsc_ref_dma, - hyperv_ref_tsc.tsc_ref); + /* + * NOTE: Do not free the reference-TSC page here. CPUs + * that entered hyperv_tsc_{l,m}fence() before the + * tc64 pointer swap above may still be reading the + * page; nothing quiesces them before the free. + * This code only runs at system shutdown (builtin + * SYSUNINIT), so leaking one page is harmless. + */ hyperv_ref_tsc.tsc_ref = NULL; } }