RE: [PATCH] x86/hyperv: reserve more vectors
From: Michael Kelley
Date: Mon Aug 10 2026 - 12:03:18 EST
From: wei.liu@xxxxxxxxxx <wei.liu@xxxxxxxxxx> 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 <wei.liu@xxxxxxxxxx>
> ---
> 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 <mhklinux@xxxxxxxxxxx>
> 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
>