diff mbox series

[V2,01/12] x86/virt/tdx: Make tdh_vp_enter() noinstr

Message ID 20250129095902.16391-2-adrian.hunter@intel.com (mailing list archive)
State New, archived
Headers show
Series KVM: TDX: TD vcpu enter/exit | expand

Commit Message

Adrian Hunter Jan. 29, 2025, 9:58 a.m. UTC
Make tdh_vp_enter() noinstr because KVM requires VM entry to be noinstr
for 2 reasons:
 1. The use of context tracking via guest_state_enter_irqoff() and
    guest_state_exit_irqoff()
 2. The need to avoid IRET between VM-exit and NMI handling in order to
    avoid prematurely releasing NMI inhibit.

Consequently make __seamcall_saved_ret() noinstr also. Currently
tdh_vp_enter() is the only caller of __seamcall_saved_ret().

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
TD vcpu enter/exit v2:
 - New patch
---
 arch/x86/virt/vmx/tdx/seamcall.S | 3 +++
 arch/x86/virt/vmx/tdx/tdx.c      | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

Comments

Paolo Bonzini Feb. 16, 2025, 6:26 p.m. UTC | #1
On 1/29/25 10:58, Adrian Hunter wrote:
> Make tdh_vp_enter() noinstr because KVM requires VM entry to be noinstr
> for 2 reasons:
>   1. The use of context tracking via guest_state_enter_irqoff() and
>      guest_state_exit_irqoff()
>   2. The need to avoid IRET between VM-exit and NMI handling in order to
>      avoid prematurely releasing NMI inhibit.
> 
> Consequently make __seamcall_saved_ret() noinstr also. Currently
> tdh_vp_enter() is the only caller of __seamcall_saved_ret().
> 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>

This can be squashed into "x86/virt/tdx: Add SEAMCALL wrapper to 
enter/exit TDX guest"; I did that in kvm-coco-queue.

Paolo

> ---
> TD vcpu enter/exit v2:
>   - New patch
> ---
>   arch/x86/virt/vmx/tdx/seamcall.S | 3 +++
>   arch/x86/virt/vmx/tdx/tdx.c      | 2 +-
>   2 files changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/virt/vmx/tdx/seamcall.S b/arch/x86/virt/vmx/tdx/seamcall.S
> index 5b1f2286aea9..6854c52c374b 100644
> --- a/arch/x86/virt/vmx/tdx/seamcall.S
> +++ b/arch/x86/virt/vmx/tdx/seamcall.S
> @@ -41,6 +41,9 @@ SYM_FUNC_START(__seamcall_ret)
>   	TDX_MODULE_CALL host=1 ret=1
>   SYM_FUNC_END(__seamcall_ret)
>   
> +/* KVM requires non-instrumentable __seamcall_saved_ret() for TDH.VP.ENTER */
> +.section .noinstr.text, "ax"
> +
>   /*
>    * __seamcall_saved_ret() - Host-side interface functions to SEAM software
>    * (the P-SEAMLDR or the TDX module), with saving output registers to the
> diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
> index 4a010e65276d..1515c467dd86 100644
> --- a/arch/x86/virt/vmx/tdx/tdx.c
> +++ b/arch/x86/virt/vmx/tdx/tdx.c
> @@ -1511,7 +1511,7 @@ static void tdx_clflush_page(struct page *page)
>   	clflush_cache_range(page_to_virt(page), PAGE_SIZE);
>   }
>   
> -u64 tdh_vp_enter(struct tdx_vp *td, struct tdx_module_args *args)
> +noinstr u64 tdh_vp_enter(struct tdx_vp *td, struct tdx_module_args *args)
>   {
>   	args->rcx = tdx_tdvpr_pa(td);
>
Adrian Hunter Feb. 27, 2025, 2:13 p.m. UTC | #2
On 16/02/25 20:26, Paolo Bonzini wrote:
> On 1/29/25 10:58, Adrian Hunter wrote:
>> Make tdh_vp_enter() noinstr because KVM requires VM entry to be noinstr
>> for 2 reasons:
>>   1. The use of context tracking via guest_state_enter_irqoff() and
>>      guest_state_exit_irqoff()
>>   2. The need to avoid IRET between VM-exit and NMI handling in order to
>>      avoid prematurely releasing NMI inhibit.
>>
>> Consequently make __seamcall_saved_ret() noinstr also. Currently
>> tdh_vp_enter() is the only caller of __seamcall_saved_ret().
>>
>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> 
> This can be squashed into "x86/virt/tdx: Add SEAMCALL wrapper to enter/exit TDX guest"; I did that in kvm-coco-queue.

We have re-based on kvm-coco-queue so we in-sync on this.
diff mbox series

Patch

diff --git a/arch/x86/virt/vmx/tdx/seamcall.S b/arch/x86/virt/vmx/tdx/seamcall.S
index 5b1f2286aea9..6854c52c374b 100644
--- a/arch/x86/virt/vmx/tdx/seamcall.S
+++ b/arch/x86/virt/vmx/tdx/seamcall.S
@@ -41,6 +41,9 @@  SYM_FUNC_START(__seamcall_ret)
 	TDX_MODULE_CALL host=1 ret=1
 SYM_FUNC_END(__seamcall_ret)
 
+/* KVM requires non-instrumentable __seamcall_saved_ret() for TDH.VP.ENTER */
+.section .noinstr.text, "ax"
+
 /*
  * __seamcall_saved_ret() - Host-side interface functions to SEAM software
  * (the P-SEAMLDR or the TDX module), with saving output registers to the
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 4a010e65276d..1515c467dd86 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1511,7 +1511,7 @@  static void tdx_clflush_page(struct page *page)
 	clflush_cache_range(page_to_virt(page), PAGE_SIZE);
 }
 
-u64 tdh_vp_enter(struct tdx_vp *td, struct tdx_module_args *args)
+noinstr u64 tdh_vp_enter(struct tdx_vp *td, struct tdx_module_args *args)
 {
 	args->rcx = tdx_tdvpr_pa(td);