From: [email protected] <[email protected]> Sent: Wednesday, July 29, 2026 5:50 PM > > Microsoft Hypervisor delivers three vectors to the NT HAL running in the > root partition and refuses to map a device interrupt to any of them when > interrupt remapping is not available in the system. As of writing, the
s/of writing/of this writing/ > nested MSHV setup has no interrupt remapping capability. > > The three vectors are: > > HAL_NT_APC_VECTOR 0x1F > HAL_NT_DPC_VECTOR 0x2F > HAL_NT_CLOCK_IPI_VECTOR 0xD2 > > 0x1F is below FIRST_EXTERNAL_VECTOR so the vector allocator never hands > it out, but 0x2F and 0xD2 are both inside the allocatable range and are > handed out once enough vectors are in use. Mapping such an interrupt > then fails with HV_STATUS_INVALID_PARAMETER, and the interrupt is never > delivered. > > Reserve all three next to the hypervisor debug vectors that are already > kept out of the allocator's hands. > > Signed-off-by: Wei Liu <[email protected]> > --- > arch/x86/kernel/cpu/mshyperv.c | 21 ++++++++++++++++++--- > 1 file changed, 18 insertions(+), 3 deletions(-) > > diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c > index 185d4f677ec0..229c7377a980 100644 > --- a/arch/x86/kernel/cpu/mshyperv.c > +++ b/arch/x86/kernel/cpu/mshyperv.c > @@ -502,17 +502,32 @@ static void hv_reserve_irq_vectors(void) > #define HYPERV_DBG_ASSERT_VECTOR 0x2C > #define HYPERV_DBG_SERVICE_VECTOR 0x2D > > + /* > + * The hypervisor delivers these three to the NT HAL and refuses to > + * map a device interrupt to any of them. > + * > + * The hypervisor will provide a hint in the future when these > + * vectors become available to use. > + */ > + #define HAL_NT_APC_VECTOR 0x1F > + #define HAL_NT_DPC_VECTOR 0x2F > + #define HAL_NT_CLOCK_IPI_VECTOR 0xD2 > + > if (cpu_feature_enabled(X86_FEATURE_FRED)) > return; > > if (test_and_set_bit(HYPERV_DBG_ASSERT_VECTOR, system_vectors) || > test_and_set_bit(HYPERV_DBG_SERVICE_VECTOR, system_vectors) || > - test_and_set_bit(HYPERV_DBG_FASTFAIL_VECTOR, system_vectors)) > + test_and_set_bit(HYPERV_DBG_FASTFAIL_VECTOR, system_vectors) || > + test_and_set_bit(HAL_NT_APC_VECTOR, system_vectors) || > + test_and_set_bit(HAL_NT_DPC_VECTOR, system_vectors) || > + test_and_set_bit(HAL_NT_CLOCK_IPI_VECTOR, system_vectors)) Calling test_and_set_bit() explicitly for each of the 6 vectors seems right on the border of where it would be better to declare a static array with the vectors and loop through the array. The loop could also populate the string to be output in the pr_info() statement below. But leaving it explicit as you have done is probably simpler unless the vector list grows again. Reviewed-by: Michael Kelley <[email protected]> > BUG(); > > - pr_info("Hyper-V: reserve vectors: 0x%x 0x%x 0x%x\n", > + pr_info("Hyper-V: reserve vectors: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", > HYPERV_DBG_ASSERT_VECTOR, HYPERV_DBG_SERVICE_VECTOR, > - HYPERV_DBG_FASTFAIL_VECTOR); > + HYPERV_DBG_FASTFAIL_VECTOR, HAL_NT_APC_VECTOR, > + HAL_NT_DPC_VECTOR, HAL_NT_CLOCK_IPI_VECTOR); > } > > static void __init ms_hyperv_init_platform(void) > -- > 2.53.0 >

