RE: [EXTERNAL] [RFC PATCH V5 09/15] x86/hyperv: Add smp support for sev-snp guest

From: Saurabh Singh Sengar
Date: Mon May 01 2023 - 06:32:55 EST




> -----Original Message-----
> From: Tianyu Lan <ltykernel@xxxxxxxxx>
> Sent: Monday, May 1, 2023 2:27 PM
> To: luto@xxxxxxxxxx; tglx@xxxxxxxxxxxxx; mingo@xxxxxxxxxx; bp@xxxxxxxxx;
> dave.hansen@xxxxxxxxxxxxxxx; x86@xxxxxxxxxx; hpa@xxxxxxxxx;
> seanjc@xxxxxxxxxx; pbonzini@xxxxxxxxxx; jgross@xxxxxxxx; Tianyu Lan
> <Tianyu.Lan@xxxxxxxxxxxxx>; kirill@xxxxxxxxxxxxx;
> jiangshan.ljs@xxxxxxxxxxxx; peterz@xxxxxxxxxxxxx; ashish.kalra@xxxxxxx;
> srutherford@xxxxxxxxxx; akpm@xxxxxxxxxxxxxxxxxxxx;
> anshuman.khandual@xxxxxxx; pawan.kumar.gupta@xxxxxxxxxxxxxxx;
> adrian.hunter@xxxxxxxxx; daniel.sneddon@xxxxxxxxxxxxxxx;
> alexander.shishkin@xxxxxxxxxxxxxxx; sandipan.das@xxxxxxx;
> ray.huang@xxxxxxx; brijesh.singh@xxxxxxx; michael.roth@xxxxxxx;
> thomas.lendacky@xxxxxxx; venu.busireddy@xxxxxxxxxx;
> sterritt@xxxxxxxxxx; tony.luck@xxxxxxxxx; samitolvanen@xxxxxxxxxx;
> fenghua.yu@xxxxxxxxx
> Cc: pangupta@xxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; kvm@xxxxxxxxxxxxxxx;
> linux-hyperv@xxxxxxxxxxxxxxx; linux-arch@xxxxxxxxxxxxxxx
> Subject: [EXTERNAL] [RFC PATCH V5 09/15] x86/hyperv: Add smp support for
> sev-snp guest
>
> From: Tianyu Lan <tiala@xxxxxxxxxxxxx>
>
> The wakeup_secondary_cpu callback was populated with wakeup_
> cpu_via_vmgexit() which doesn't work for Hyper-V and Hyper-V requires to
> call Hyper-V specific hvcall to start APs. So override it with Hyper-V specific
> hook to start AP sev_es_save_area data structure.
>
> Signed-off-by: Tianyu Lan <tiala@xxxxxxxxxxxxx>
> ---
> Change sicne RFC v3:
> * Replace struct sev_es_save_area with struct
> vmcb_save_area
> * Move code from mshyperv.c to ivm.c
>
> Change since RFC v2:
> * Add helper function to initialize segment
> * Fix some coding style
> ---
> arch/x86/hyperv/ivm.c | 89 +++++++++++++++++++++++++++++++
> arch/x86/include/asm/mshyperv.h | 18 +++++++
> arch/x86/include/asm/sev.h | 13 +++++
> arch/x86/include/asm/svm.h | 15 +++++-
> arch/x86/kernel/cpu/mshyperv.c | 13 ++++-
> arch/x86/kernel/sev.c | 4 +-
> include/asm-generic/hyperv-tlfs.h | 19 +++++++
> 7 files changed, 166 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c index
> 522eab55c0dd..0ef46f1874e6 100644
> --- a/arch/x86/hyperv/ivm.c
> +++ b/arch/x86/hyperv/ivm.c
> @@ -22,11 +22,15 @@
> #include <asm/sev.h>
> #include <asm/realmode.h>
> #include <asm/e820/api.h>
> +#include <asm/desc.h>
>
> #ifdef CONFIG_AMD_MEM_ENCRYPT
>
> #define GHCB_USAGE_HYPERV_CALL 1
>
> +static u8 ap_start_input_arg[PAGE_SIZE] __bss_decrypted
> +__aligned(PAGE_SIZE); static u8 ap_start_stack[PAGE_SIZE]
> +__aligned(PAGE_SIZE);
> +
> union hv_ghcb {
> struct ghcb ghcb;
> struct {
> @@ -442,6 +446,91 @@ __init void hv_sev_init_mem_and_cpu(void)
> }
> }
>
> +#define hv_populate_vmcb_seg(seg, gdtr_base) \
> +do { \
> + if (seg.selector) { \
> + seg.base = 0; \
> + seg.limit = HV_AP_SEGMENT_LIMIT; \
> + seg.attrib = *(u16 *)(gdtr_base + seg.selector + 5); \

<snip>

> generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h
> index f4e4cc4f965f..959b075591b2 100644
> --- a/include/asm-generic/hyperv-tlfs.h
> +++ b/include/asm-generic/hyperv-tlfs.h
> @@ -149,6 +149,7 @@ union hv_reference_tsc_msr {
> #define HVCALL_ENABLE_VP_VTL 0x000f
> #define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
> #define HVCALL_SEND_IPI 0x000b
> +#define HVCALL_ENABLE_VP_VTL 0x000f

HVCALL_ENABLE_VP_VTL is already defined.

> #define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
> #define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
> #define HVCALL_SEND_IPI_EX 0x0015
> @@ -168,6 +169,7 @@ union hv_reference_tsc_msr {
> #define HVCALL_RETARGET_INTERRUPT 0x007e
> #define HVCALL_START_VP 0x0099
> #define HVCALL_GET_VP_ID_FROM_APIC_ID 0x009a
> +#define HVCALL_START_VIRTUAL_PROCESSOR 0x0099

We already have HVCALL_START_VP no need of defining HVCALL_START_VIRTUAL_PROCESSOR.
- Saurabh

> #define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af #define
> HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0 #define
> HVCALL_MODIFY_SPARSE_GPA_PAGE_HOST_VISIBILITY 0x00db @@ -223,6
> +225,7 @@ enum HV_GENERIC_SET_FORMAT {
> #define HV_STATUS_INVALID_PORT_ID 17
> #define HV_STATUS_INVALID_CONNECTION_ID 18
> #define HV_STATUS_INSUFFICIENT_BUFFERS 19
> +#define HV_STATUS_TIME_OUT 120
> #define HV_STATUS_VTL_ALREADY_ENABLED 134
>
> /*
> @@ -783,6 +786,22 @@ struct hv_input_unmap_device_interrupt {
> struct hv_interrupt_entry interrupt_entry; } __packed;
>
> +struct hv_enable_vp_vtl_input {
> + u64 partitionid;
> + u32 vpindex;
> + u8 targetvtl;
> + u8 padding[3];
> + u8 context[0xe0];
> +} __packed;
> +
> +struct hv_start_virtual_processor_input {
> + u64 partitionid;
> + u32 vpindex;
> + u8 targetvtl;
> + u8 padding[3];
> + u8 context[0xe0];
> +} __packed;
> +
> #define HV_SOURCE_SHADOW_NONE 0x0
> #define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE 0x1
>
> --
> 2.25.1