Re: [PATCH v2 45/58] i386/tdx: Limit the range size for MapGPA

2023-08-21 Thread Isaku Yamahata
On Fri, Aug 18, 2023 at 05:50:28AM -0400,
Xiaoyao Li  wrote:

> From: Isaku Yamahata 
> 
> If the range for TDG.VP.VMCALL is too large, process the limited
> size and return retry error.  It's bad for VMM to take too long time,
> e.g. second order, with blocking vcpu execution.  It results in too many
> missing timer interrupts.

This patch requires the guest side patch. [1]
Unless with large guest memory, it's unlikely to hit the limit with KVM/qemu,
though.

[1] https://lore.kernel.org/all/20230811021246.821-1-de...@microsoft.com/

> 
> Signed-off-by: Isaku Yamahata 
> Signed-off-by: Xiaoyao Li 
> ---
>  target/i386/kvm/tdx.c | 19 ++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c
> index 0c43c1f7759f..ced55be506d1 100644
> --- a/target/i386/kvm/tdx.c
> +++ b/target/i386/kvm/tdx.c
> @@ -994,12 +994,16 @@ static hwaddr tdx_shared_bit(X86CPU *cpu)
>  return (cpu->phys_bits > 48) ? BIT_ULL(51) : BIT_ULL(47);
>  }
>  
> +/* 64MB at most in one call. What value is appropriate? */
> +#define TDX_MAP_GPA_MAX_LEN (64 * 1024 * 1024)
> +
>  static void tdx_handle_map_gpa(X86CPU *cpu, struct kvm_tdx_vmcall *vmcall)
>  {
>  hwaddr shared_bit = tdx_shared_bit(cpu);
>  hwaddr gpa = vmcall->in_r12 & ~shared_bit;
>  bool private = !(vmcall->in_r12 & shared_bit);
>  hwaddr size = vmcall->in_r13;
> +bool retry = false;
>  int ret = 0;
>  
>  vmcall->status_code = TDG_VP_VMCALL_INVALID_OPERAND;
> @@ -1018,12 +1022,25 @@ static void tdx_handle_map_gpa(X86CPU *cpu, struct 
> kvm_tdx_vmcall *vmcall)
>  return;
>  }
>  
> +if (size > TDX_MAP_GPA_MAX_LEN) {
> +retry = true;
> +size = TDX_MAP_GPA_MAX_LEN;
> +}
> +
>  if (size > 0) {
>  ret = kvm_convert_memory(gpa, size, private);
>  }
>  
>  if (!ret) {
> -vmcall->status_code = TDG_VP_VMCALL_SUCCESS;
> +if (retry) {
> +vmcall->status_code = TDG_VP_VMCALL_RETRY;
> +vmcall->out_r11 = gpa + size;
> +if (!private) {
> +vmcall->out_r11 |= shared_bit;
> +}
> +} else {
> +vmcall->status_code = TDG_VP_VMCALL_SUCCESS;
> +}
>  }
>  }
>  
> -- 
> 2.34.1
> 
> 

-- 
Isaku Yamahata 



[PATCH v2 45/58] i386/tdx: Limit the range size for MapGPA

2023-08-18 Thread Xiaoyao Li
From: Isaku Yamahata 

If the range for TDG.VP.VMCALL is too large, process the limited
size and return retry error.  It's bad for VMM to take too long time,
e.g. second order, with blocking vcpu execution.  It results in too many
missing timer interrupts.

Signed-off-by: Isaku Yamahata 
Signed-off-by: Xiaoyao Li 
---
 target/i386/kvm/tdx.c | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c
index 0c43c1f7759f..ced55be506d1 100644
--- a/target/i386/kvm/tdx.c
+++ b/target/i386/kvm/tdx.c
@@ -994,12 +994,16 @@ static hwaddr tdx_shared_bit(X86CPU *cpu)
 return (cpu->phys_bits > 48) ? BIT_ULL(51) : BIT_ULL(47);
 }
 
+/* 64MB at most in one call. What value is appropriate? */
+#define TDX_MAP_GPA_MAX_LEN (64 * 1024 * 1024)
+
 static void tdx_handle_map_gpa(X86CPU *cpu, struct kvm_tdx_vmcall *vmcall)
 {
 hwaddr shared_bit = tdx_shared_bit(cpu);
 hwaddr gpa = vmcall->in_r12 & ~shared_bit;
 bool private = !(vmcall->in_r12 & shared_bit);
 hwaddr size = vmcall->in_r13;
+bool retry = false;
 int ret = 0;
 
 vmcall->status_code = TDG_VP_VMCALL_INVALID_OPERAND;
@@ -1018,12 +1022,25 @@ static void tdx_handle_map_gpa(X86CPU *cpu, struct 
kvm_tdx_vmcall *vmcall)
 return;
 }
 
+if (size > TDX_MAP_GPA_MAX_LEN) {
+retry = true;
+size = TDX_MAP_GPA_MAX_LEN;
+}
+
 if (size > 0) {
 ret = kvm_convert_memory(gpa, size, private);
 }
 
 if (!ret) {
-vmcall->status_code = TDG_VP_VMCALL_SUCCESS;
+if (retry) {
+vmcall->status_code = TDG_VP_VMCALL_RETRY;
+vmcall->out_r11 = gpa + size;
+if (!private) {
+vmcall->out_r11 |= shared_bit;
+}
+} else {
+vmcall->status_code = TDG_VP_VMCALL_SUCCESS;
+}
 }
 }
 
-- 
2.34.1