On Wed, Sep 2, 2026 at 11:02 AM Michael Kelley <[email protected]> wrote:
>
> hv_apicid_to_vp_index() currently uses the per-cpu hypercall input
> and output pages. This function is called when running in VTL2 and
> when running in an SEV-SNP CoCo VM with no paravisor. In the former
> case, the output page is allocated, but in the latter case it is
> not, so the hypervisor stores the output VP index in memory that has
> not been allocated by the guest.
>
> Fix this by using the input page for both input and output. The
> hypercall has very small input and output, so sharing the same
> page for both is straightforward. An alternative fix is to
> allocate the per-cpu output page when running in an SEV-SNP CoCo
> guest, but this uses significantly more memory, particularly
> with larger vCPUs counts.
>
> Fixes: 86c48271e0d6 ("x86/hyperv: Fix APIC ID and VP index confusion in 
> hv_snp_boot_ap()")
> Signed-off-by: Michael Kelley <[email protected]>
> ---
> I'm not aware that this bug is causing any real problems because
> SEV-SNP CoCo VMs on Hyper-V are rarely, if ever, used without a
> paravisor. But it was on my list of little clean-ups to do, and
> a recent Sashiko analysis [1] flagged the issue. So the best thing
> to do is just fix it.
Reviewed-by: Tianyu Lan <[email protected]>

>
> [1] 
> https://lore.kernel.org/linux-hyperv/[email protected]/
>
> Changes in v2:
> * Make the new code a bit cleaner by dropping the unnecessary cast
>   to u32 *
>
>  arch/x86/hyperv/hv_init.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
> index d5edc8530964..2a71c70d7e27 100644
> --- a/arch/x86/hyperv/hv_init.c
> +++ b/arch/x86/hyperv/hv_init.c
> @@ -731,7 +731,8 @@ int hv_apicid_to_vp_index(u32 apic_id)
>         input->partition_id = HV_PARTITION_ID_SELF;
>         input->apic_ids[0] = apic_id;
>
> -       output = *this_cpu_ptr(hyperv_pcpu_output_arg);
> +       /* Treat input as having 2 APIC IDs so output is 64-bit aligned */
> +       output = (void *)input + struct_size(input, apic_ids, 2);
>
>         control = HV_HYPERCALL_REP_COMP_1 | HVCALL_GET_VP_INDEX_FROM_APIC_ID;
>         status = hv_do_hypercall(control, input, output);
> --
> 2.25.1
>
>


-- 
Thanks
Tianyu Lan

Reply via email to