diff mbox series

[V7,5/9] x86/sev-es: Expose __sev_es_ghcb_hv_call() to call ghcb hv call out of sev code

Message ID 20211006063651.1124737-6-ltykernel@gmail.com (mailing list archive)
State Not Applicable
Delegated to: Netdev Maintainers
Headers show
Series x86/Hyper-V: Add Hyper-V Isolation VM support(First part) | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Tianyu Lan Oct. 6, 2021, 6:36 a.m. UTC
From: Tianyu Lan <Tianyu.Lan@microsoft.com>

Hyper-V also needs to call ghcb hv call to write/read MSR in Isolation VM.
So expose __sev_es_ghcb_hv_call() to call it in the Hyper-V code.

Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
---
 arch/x86/include/asm/sev.h   | 10 +++++++++
 arch/x86/kernel/sev-shared.c | 43 +++++++++++++++++++++++++-----------
 2 files changed, 40 insertions(+), 13 deletions(-)

Comments

Tianyu Lan Oct. 11, 2021, 2:42 p.m. UTC | #1
Hi @Tom and Borislav:
      Please have a look at this patch. If it's ok, could you give your ack.

Thanks.

On 10/6/2021 2:36 PM, Tianyu Lan wrote:
> From: Tianyu Lan <Tianyu.Lan@microsoft.com>
> 
> Hyper-V also needs to call ghcb hv call to write/read MSR in Isolation VM.
> So expose __sev_es_ghcb_hv_call() to call it in the Hyper-V code.
> 
> Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
> ---
>   arch/x86/include/asm/sev.h   | 10 +++++++++
>   arch/x86/kernel/sev-shared.c | 43 +++++++++++++++++++++++++-----------
>   2 files changed, 40 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
> index fa5cd05d3b5b..2e96869f3e9b 100644
> --- a/arch/x86/include/asm/sev.h
> +++ b/arch/x86/include/asm/sev.h
> @@ -81,12 +81,22 @@ static __always_inline void sev_es_nmi_complete(void)
>   		__sev_es_nmi_complete();
>   }
>   extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd);
> +extern enum es_result __sev_es_ghcb_hv_call(struct ghcb *ghcb,
> +					    u64 exit_code, u64 exit_info_1,
> +					    u64 exit_info_2);
>   #else
>   static inline void sev_es_ist_enter(struct pt_regs *regs) { }
>   static inline void sev_es_ist_exit(void) { }
>   static inline int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) { return 0; }
>   static inline void sev_es_nmi_complete(void) { }
>   static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; }
> +static inline enum es_result
> +__sev_es_ghcb_hv_call(struct ghcb *ghcb,
> +		      u64 exit_code, u64 exit_info_1,
> +		      u64 exit_info_2)
> +{
> +	return ES_VMM_ERROR;
> +}
>   #endif
>   
>   #endif
> diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
> index 9f90f460a28c..946c203be08c 100644
> --- a/arch/x86/kernel/sev-shared.c
> +++ b/arch/x86/kernel/sev-shared.c
> @@ -94,10 +94,13 @@ static void vc_finish_insn(struct es_em_ctxt *ctxt)
>   	ctxt->regs->ip += ctxt->insn.length;
>   }
>   
> -static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
> -					  struct es_em_ctxt *ctxt,
> -					  u64 exit_code, u64 exit_info_1,
> -					  u64 exit_info_2)
> +/*
> + * __sev_es_ghcb_hv_call() is also used in the other platform code(e.g
> + * Hyper-V).
> + */
> +enum es_result __sev_es_ghcb_hv_call(struct ghcb *ghcb,
> +				     u64 exit_code, u64 exit_info_1,
> +				     u64 exit_info_2)
>   {
>   	enum es_result ret;
>   
> @@ -109,15 +112,33 @@ static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
>   	ghcb_set_sw_exit_info_1(ghcb, exit_info_1);
>   	ghcb_set_sw_exit_info_2(ghcb, exit_info_2);
>   
> -	sev_es_wr_ghcb_msr(__pa(ghcb));
>   	VMGEXIT();
>   
> +	if (ghcb->save.sw_exit_info_1 & 0xffffffff)
> +		ret = ES_VMM_ERROR;
> +	else
> +		ret = ES_OK;
> +
> +	return ret;
> +}
> +
> +static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
> +					  struct es_em_ctxt *ctxt,
> +					  u64 exit_code, u64 exit_info_1,
> +					  u64 exit_info_2)
> +{
> +	enum es_result ret;
> +
> +	sev_es_wr_ghcb_msr(__pa(ghcb));
> +
> +	ret = __sev_es_ghcb_hv_call(ghcb, exit_code, exit_info_1,
> +					 exit_info_2);
> +	if (ret == ES_OK)
> +		return ret;
> +
>   	if ((ghcb->save.sw_exit_info_1 & 0xffffffff) == 1) {
>   		u64 info = ghcb->save.sw_exit_info_2;
> -		unsigned long v;
> -
> -		info = ghcb->save.sw_exit_info_2;
> -		v = info & SVM_EVTINJ_VEC_MASK;
> +		unsigned long v = info & SVM_EVTINJ_VEC_MASK;
>   
>   		/* Check if exception information from hypervisor is sane. */
>   		if ((info & SVM_EVTINJ_VALID) &&
> @@ -127,11 +148,7 @@ static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
>   			if (info & SVM_EVTINJ_VALID_ERR)
>   				ctxt->fi.error_code = info >> 32;
>   			ret = ES_EXCEPTION;
> -		} else {
> -			ret = ES_VMM_ERROR;
>   		}
> -	} else {
> -		ret = ES_OK;
>   	}
>   
>   	return ret;
>
Borislav Petkov Oct. 11, 2021, 5:22 p.m. UTC | #2
On Mon, Oct 11, 2021 at 10:42:18PM +0800, Tianyu Lan wrote:
> Hi @Tom and Borislav:
>      Please have a look at this patch. If it's ok, could you give your ack.

I needed to do some cleanups in that area first:

https://lore.kernel.org/r/YWRwxImd9Qcls/Yy@zn.tnic

Can you redo yours ontop so that you can show what exactly you need
exported for HyperV?

Thx.
Tianyu Lan Oct. 12, 2021, 2:13 p.m. UTC | #3
Sure. Will do that. Thanks.

On 10/12/2021 1:22 AM, Borislav Petkov wrote:
> On Mon, Oct 11, 2021 at 10:42:18PM +0800, Tianyu Lan wrote:
>> Hi @Tom and Borislav:
>>       Please have a look at this patch. If it's ok, could you give your ack.
> 
> I needed to do some cleanups in that area first:
> 
> https://lore.kernel.org/r/YWRwxImd9Qcls/Yy@zn.tnic
> 
> Can you redo yours ontop so that you can show what exactly you need
> exported for HyperV?
> 
> Thx.
>
Tianyu Lan Oct. 13, 2021, 2:24 p.m. UTC | #4
On 10/12/2021 1:22 AM, Borislav Petkov wrote:
> On Mon, Oct 11, 2021 at 10:42:18PM +0800, Tianyu Lan wrote:
>> Hi @Tom and Borislav:
>>       Please have a look at this patch. If it's ok, could you give your ack.
> 
> I needed to do some cleanups in that area first:
> 
> https://lore.kernel.org/r/YWRwxImd9Qcls/Yy@zn.tnic
> 
> Can you redo yours ontop so that you can show what exactly you need
> exported for HyperV?
> 
> Thx.

Hi Borislav :
	Please check whether the following change based on you patch is
ok for you.
---
x86/sev-es: Expose __sev_es_ghcb_hv_call() to call ghcb hv call out of 
sev code

     Hyper-V also needs to call ghcb hv call to write/read MSR in 
Isolation VM.
     So expose __sev_es_ghcb_hv_call() to call it in the Hyper-V code.

     Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>

diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index fa5cd05d3b5b..295c847c3cd4 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -81,12 +81,23 @@ static __always_inline void sev_es_nmi_complete(void)
                 __sev_es_nmi_complete();
  }
  extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd);
+extern enum es_result __sev_es_ghcb_hv_call(struct ghcb *ghcb,
+                                           struct es_em_ctxt *ctxt,
+                                           u64 exit_code, u64 exit_info_1,
+                                           u64 exit_info_2);
  #else
  static inline void sev_es_ist_enter(struct pt_regs *regs) { }
  static inline void sev_es_ist_exit(void) { }
  static inline int sev_es_setup_ap_jump_table(struct real_mode_header 
*rmh) { return 0; }
  static inline void sev_es_nmi_complete(void) { }
  static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; }
+static inline enum es_result
+__sev_es_ghcb_hv_call(struct ghcb *ghcb,
+                     u64 exit_code, u64 exit_info_1,
+                     u64 exit_info_2)
+{
+       return ES_VMM_ERROR;
+}
  #endif

  #endif
diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
index ea9abd69237e..08c97cb057fa 100644
--- a/arch/x86/kernel/sev-shared.c
+++ b/arch/x86/kernel/sev-shared.c
@@ -124,10 +124,14 @@ static enum es_result verify_exception_info(struct 
ghcb *ghcb, struct es_em_ctxt
         return ES_VMM_ERROR;
  }

-static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
-                                         struct es_em_ctxt *ctxt,
-                                         u64 exit_code, u64 exit_info_1,
-                                         u64 exit_info_2)
+/*
+ * __sev_es_ghcb_hv_call() is also used in the other platform code(e.g
+ * Hyper-V).
+ */
+enum es_result __sev_es_ghcb_hv_call(struct ghcb *ghcb,
+                                    struct es_em_ctxt *ctxt,
+                                    u64 exit_code, u64 exit_info_1,
+                                    u64 exit_info_2)
  {
         /* Fill in protocol and format specifiers */
         ghcb->protocol_version = GHCB_PROTOCOL_MAX;
@@ -137,12 +141,22 @@ static enum es_result sev_es_ghcb_hv_call(struct 
ghcb *ghcb,
         ghcb_set_sw_exit_info_1(ghcb, exit_info_1);
         ghcb_set_sw_exit_info_2(ghcb, exit_info_2);

-       sev_es_wr_ghcb_msr(__pa(ghcb));
         VMGEXIT();

         return verify_exception_info(ghcb, ctxt);
  }

+static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
+                                         struct es_em_ctxt *ctxt,
+                                         u64 exit_code, u64 exit_info_1,
+                                         u64 exit_info_2)
+{
+       sev_es_wr_ghcb_msr(__pa(ghcb));
+
+       return __sev_es_ghcb_hv_call(ghcb, ctxt, exit_code, exit_info_1,
+                                    exit_info_2);
+}
+
  /*
   * Boot VC Handler - This is the first VC handler during boot, there 
is no GHCB
   * page yet, so it only supports the MSR based communication with the
(END)


Thanks.
Tianyu Lan Oct. 18, 2021, 12:19 p.m. UTC | #5
Gentle Ping.

On 10/13/2021 10:24 PM, Tianyu Lan wrote:
> On 10/12/2021 1:22 AM, Borislav Petkov wrote:
>> On Mon, Oct 11, 2021 at 10:42:18PM +0800, Tianyu Lan wrote:
>>> Hi @Tom and Borislav:
>>>       Please have a look at this patch. If it's ok, could you give 
>>> your ack.
>>
>> I needed to do some cleanups in that area first:
>>
>> https://lore.kernel.org/r/YWRwxImd9Qcls/Yy@zn.tnic
>>
>> Can you redo yours ontop so that you can show what exactly you need
>> exported for HyperV?
>>
>> Thx.
> 
> Hi Borislav :
>      Please check whether the following change based on you patch is
> ok for you.
> ---
> x86/sev-es: Expose __sev_es_ghcb_hv_call() to call ghcb hv call out of 
> sev code
> 
>      Hyper-V also needs to call ghcb hv call to write/read MSR in 
> Isolation VM.
>      So expose __sev_es_ghcb_hv_call() to call it in the Hyper-V code.
> 
>      Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
> 
> diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
> index fa5cd05d3b5b..295c847c3cd4 100644
> --- a/arch/x86/include/asm/sev.h
> +++ b/arch/x86/include/asm/sev.h
> @@ -81,12 +81,23 @@ static __always_inline void sev_es_nmi_complete(void)
>                  __sev_es_nmi_complete();
>   }
>   extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd);
> +extern enum es_result __sev_es_ghcb_hv_call(struct ghcb *ghcb,
> +                                           struct es_em_ctxt *ctxt,
> +                                           u64 exit_code, u64 exit_info_1,
> +                                           u64 exit_info_2);
>   #else
>   static inline void sev_es_ist_enter(struct pt_regs *regs) { }
>   static inline void sev_es_ist_exit(void) { }
>   static inline int sev_es_setup_ap_jump_table(struct real_mode_header 
> *rmh) { return 0; }
>   static inline void sev_es_nmi_complete(void) { }
>   static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; }
> +static inline enum es_result
> +__sev_es_ghcb_hv_call(struct ghcb *ghcb,
> +                     u64 exit_code, u64 exit_info_1,
> +                     u64 exit_info_2)
> +{
> +       return ES_VMM_ERROR;
> +}
>   #endif
> 
>   #endif
> diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
> index ea9abd69237e..08c97cb057fa 100644
> --- a/arch/x86/kernel/sev-shared.c
> +++ b/arch/x86/kernel/sev-shared.c
> @@ -124,10 +124,14 @@ static enum es_result verify_exception_info(struct 
> ghcb *ghcb, struct es_em_ctxt
>          return ES_VMM_ERROR;
>   }
> 
> -static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
> -                                         struct es_em_ctxt *ctxt,
> -                                         u64 exit_code, u64 exit_info_1,
> -                                         u64 exit_info_2)
> +/*
> + * __sev_es_ghcb_hv_call() is also used in the other platform code(e.g
> + * Hyper-V).
> + */
> +enum es_result __sev_es_ghcb_hv_call(struct ghcb *ghcb,
> +                                    struct es_em_ctxt *ctxt,
> +                                    u64 exit_code, u64 exit_info_1,
> +                                    u64 exit_info_2)
>   {
>          /* Fill in protocol and format specifiers */
>          ghcb->protocol_version = GHCB_PROTOCOL_MAX;
> @@ -137,12 +141,22 @@ static enum es_result sev_es_ghcb_hv_call(struct 
> ghcb *ghcb,
>          ghcb_set_sw_exit_info_1(ghcb, exit_info_1);
>          ghcb_set_sw_exit_info_2(ghcb, exit_info_2);
> 
> -       sev_es_wr_ghcb_msr(__pa(ghcb));
>          VMGEXIT();
> 
>          return verify_exception_info(ghcb, ctxt);
>   }
> 
> +static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
> +                                         struct es_em_ctxt *ctxt,
> +                                         u64 exit_code, u64 exit_info_1,
> +                                         u64 exit_info_2)
> +{
> +       sev_es_wr_ghcb_msr(__pa(ghcb));
> +
> +       return __sev_es_ghcb_hv_call(ghcb, ctxt, exit_code, exit_info_1,
> +                                    exit_info_2);
> +}
> +
>   /*
>    * Boot VC Handler - This is the first VC handler during boot, there 
> is no GHCB
>    * page yet, so it only supports the MSR based communication with the
> (END)
> 
> 
> Thanks.
> 
>
Borislav Petkov Oct. 19, 2021, 1:57 p.m. UTC | #6
On Mon, Oct 18, 2021 at 08:19:30PM +0800, Tianyu Lan wrote:
> Gentle Ping.

$ patch -p1 --dry-run -i /tmp/ltykernel.01
checking file arch/x86/include/asm/sev.h
patch: **** malformed patch at line 128: return 0; }

Can you pls send a patch which is not mangled and I can apply?

Also, this might have some info on the matter:

Documentation/process/email-clients.rst

Thx.
diff mbox series

Patch

diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index fa5cd05d3b5b..2e96869f3e9b 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -81,12 +81,22 @@  static __always_inline void sev_es_nmi_complete(void)
 		__sev_es_nmi_complete();
 }
 extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd);
+extern enum es_result __sev_es_ghcb_hv_call(struct ghcb *ghcb,
+					    u64 exit_code, u64 exit_info_1,
+					    u64 exit_info_2);
 #else
 static inline void sev_es_ist_enter(struct pt_regs *regs) { }
 static inline void sev_es_ist_exit(void) { }
 static inline int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) { return 0; }
 static inline void sev_es_nmi_complete(void) { }
 static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; }
+static inline enum es_result
+__sev_es_ghcb_hv_call(struct ghcb *ghcb,
+		      u64 exit_code, u64 exit_info_1,
+		      u64 exit_info_2)
+{
+	return ES_VMM_ERROR;
+}
 #endif
 
 #endif
diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
index 9f90f460a28c..946c203be08c 100644
--- a/arch/x86/kernel/sev-shared.c
+++ b/arch/x86/kernel/sev-shared.c
@@ -94,10 +94,13 @@  static void vc_finish_insn(struct es_em_ctxt *ctxt)
 	ctxt->regs->ip += ctxt->insn.length;
 }
 
-static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
-					  struct es_em_ctxt *ctxt,
-					  u64 exit_code, u64 exit_info_1,
-					  u64 exit_info_2)
+/*
+ * __sev_es_ghcb_hv_call() is also used in the other platform code(e.g
+ * Hyper-V).
+ */
+enum es_result __sev_es_ghcb_hv_call(struct ghcb *ghcb,
+				     u64 exit_code, u64 exit_info_1,
+				     u64 exit_info_2)
 {
 	enum es_result ret;
 
@@ -109,15 +112,33 @@  static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
 	ghcb_set_sw_exit_info_1(ghcb, exit_info_1);
 	ghcb_set_sw_exit_info_2(ghcb, exit_info_2);
 
-	sev_es_wr_ghcb_msr(__pa(ghcb));
 	VMGEXIT();
 
+	if (ghcb->save.sw_exit_info_1 & 0xffffffff)
+		ret = ES_VMM_ERROR;
+	else
+		ret = ES_OK;
+
+	return ret;
+}
+
+static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
+					  struct es_em_ctxt *ctxt,
+					  u64 exit_code, u64 exit_info_1,
+					  u64 exit_info_2)
+{
+	enum es_result ret;
+
+	sev_es_wr_ghcb_msr(__pa(ghcb));
+
+	ret = __sev_es_ghcb_hv_call(ghcb, exit_code, exit_info_1,
+					 exit_info_2);
+	if (ret == ES_OK)
+		return ret;
+
 	if ((ghcb->save.sw_exit_info_1 & 0xffffffff) == 1) {
 		u64 info = ghcb->save.sw_exit_info_2;
-		unsigned long v;
-
-		info = ghcb->save.sw_exit_info_2;
-		v = info & SVM_EVTINJ_VEC_MASK;
+		unsigned long v = info & SVM_EVTINJ_VEC_MASK;
 
 		/* Check if exception information from hypervisor is sane. */
 		if ((info & SVM_EVTINJ_VALID) &&
@@ -127,11 +148,7 @@  static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
 			if (info & SVM_EVTINJ_VALID_ERR)
 				ctxt->fi.error_code = info >> 32;
 			ret = ES_EXCEPTION;
-		} else {
-			ret = ES_VMM_ERROR;
 		}
-	} else {
-		ret = ES_OK;
 	}
 
 	return ret;