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
> 


Reply via email to