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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Aug 18, 2023 at 05:50:28AM -0400,
Xiaoyao Li <xiaoyao.li@xxxxxxxxx> wrote:

> From: Isaku Yamahata <isaku.yamahata@xxxxxxxxx>
> 
> If the range for TDG.VP.VMCALL<MapGPA> 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-decui@xxxxxxxxxxxxx/

> 
> Signed-off-by: Isaku Yamahata <isaku.yamahata@xxxxxxxxx>
> Signed-off-by: Xiaoyao Li <xiaoyao.li@xxxxxxxxx>
> ---
>  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 <isaku.yamahata@xxxxxxxxxxxxxxx>



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux