lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240322001652.GW1994522@ls.amr.corp.intel.com>
Date: Thu, 21 Mar 2024 17:16:52 -0700
From: Isaku Yamahata <isaku.yamahata@...el.com>
To: "Huang, Kai" <kai.huang@...el.com>
Cc: Isaku Yamahata <isaku.yamahata@...el.com>, kvm@...r.kernel.org,
	linux-kernel@...r.kernel.org, isaku.yamahata@...il.com,
	Paolo Bonzini <pbonzini@...hat.com>, erdemaktas@...gle.com,
	Sean Christopherson <seanjc@...gle.com>,
	Sagi Shahar <sagis@...gle.com>, chen.bo@...el.com,
	hang.yuan@...el.com, tina.zhang@...el.com,
	Sean Christopherson <sean.j.christopherson@...el.com>,
	Binbin Wu <binbin.wu@...ux.intel.com>,
	Yuan Yao <yuan.yao@...el.com>, isaku.yamahata@...ux.intel.com
Subject: Re: [PATCH v19 029/130] KVM: TDX: Add C wrapper functions for
 SEAMCALLs to the TDX module

On Thu, Mar 21, 2024 at 11:37:58AM +1300,
"Huang, Kai" <kai.huang@...el.com> wrote:

> 
> 
> On 21/03/2024 10:36 am, Isaku Yamahata wrote:
> > On Wed, Mar 20, 2024 at 01:03:21PM +1300,
> > "Huang, Kai" <kai.huang@...el.com> wrote:
> > 
> > > > +static inline u64 tdx_seamcall(u64 op, struct tdx_module_args *in,
> > > > +			       struct tdx_module_args *out)
> > > > +{
> > > > +	u64 ret;
> > > > +
> > > > +	if (out) {
> > > > +		*out = *in;
> > > > +		ret = seamcall_ret(op, out);
> > > > +	} else
> > > > +		ret = seamcall(op, in);
> > > 
> > > I think it's silly to have the @out argument in this way.
> > > 
> > > What is the main reason to still have it?
> > > 
> > > Yeah we used to have the @out in __seamcall() assembly function.  The
> > > assembly code checks the @out and skips copying registers to @out when it is
> > > NULL.
> > > 
> > > But it got removed when we tried to unify the assembly for TDCALL/TDVMCALL
> > > and SEAMCALL to have a *SINGLE* assembly macro.
> > > 
> > > https://lore.kernel.org/lkml/cover.1692096753.git.kai.huang@intel.com/
> > > 
> > > To me that means we should just accept the fact we will always have a valid
> > > @out.
> > > 
> > > But there might be some case that you _obviously_ need the @out and I
> > > missed?
> > 
> > As I replied at [1], those four wrappers need to return values.
> > The first three on error, the last one on success.
> > 
> >    [1] https://lore.kernel.org/kvm/20240320202040.GH1994522@ls.amr.corp.intel.com/
> > 
> >    tdh_mem_sept_add(kvm_tdx, gpa, tdx_level, hpa, &entry, &level_state);
> >    tdh_mem_page_aug(kvm_tdx, gpa, hpa, &entry, &level_state);
> >    tdh_mem_page_remove(kvm_tdx, gpa, tdx_level, &entry, &level_state);
> >    u64 tdh_vp_rd(struct vcpu_tdx *tdx, u64 field, u64 *value)
> > 
> > We can delete out from other wrappers.
> 
> Ah, OK.  I got you don't want to invent separate wrappers for each
> seamcall() variants like:
> 
>  - tdx_seamcall(u64 fn, struct tdx_module_args *args);
>  - tdx_seamcall_ret(u64 fn, struct tdx_module_args *args);
>  - tdx_seamcall_saved_ret(u64 fn, struct tdx_module_args *args);
> 
> To be honest I found they were kinda annoying myself during the "unify
> TDCALL/SEAMCALL and TDVMCALL assembly" patchset.
> 
> But life is hard...
> 
> And given (it seems) we are going to remove kvm_spurious_fault(), I think
> the tdx_seamcall() variants are just very simple wrapper of plain seamcall()
> variants.
> 
> So how about we have some macros:
> 
> static inline bool is_seamcall_err_kernel_defined(u64 err)
> {
> 	return err & TDX_SW_ERROR;
> }
> 
> #define TDX_KVM_SEAMCALL(_kvm, _seamcall_func, _fn, _args)	\
> 	({				\
> 		u64 _ret = _seamcall_func(_fn, _args);
> 		KVM_BUG_ON(_kvm, is_seamcall_err_kernel_defined(_ret));
> 		_ret;
> 	})

As we can move out KVM_BUG_ON() to the call site, we can simply have
seamcall() or seamcall_ret().
The call site has to check error. whether it is TDX_SW_ERROR or not.
And if it hit the unexpected error, it will mark the guest bugged.


> #define tdx_kvm_seamcall(_kvm, _fn, _args)	\
> 	TDX_KVM_SEAMCALL(_kvm, seamcall, _fn, _args)
> 
> #define tdx_kvm_seamcall_ret(_kvm, _fn, _args)	\
> 	TDX_KVM_SEAMCALL(_kvm, seamcall_ret, _fn, _args)
> 
> #define tdx_kvm_seamcall_saved_ret(_kvm, _fn, _args)	\
> 	TDX_KVM_SEAMCALL(_kvm, seamcall_saved_ret, _fn, _args)
> 
> This is consistent with what we have in TDX host code, and this handles
> NO_ENTROPY error internally.
> 
> Or, maybe we can just use the seamcall_ret() for ALL SEAMCALLs, except using
> seamcall_saved_ret() for TDH.VP.ENTER.
> 
> u64 tdx_kvm_seamcall(sruct kvm*kvm, u64 fn,
> 			struct tdx_module_args *args)
> {
> 	u64 ret = seamcall_ret(fn, args);
> 
> 	KVM_BUG_ON(kvm, is_seamcall_err_kernel_defined(ret);
> 
> 	return ret;
> }
> 
> IIUC this at least should give us a single tdx_kvm_seamcall() API for
> majority (99%) code sites?

We can eleiminate tdx_kvm_seamcall() and use seamcall() or seamcall_ret()
directly.


> And obviously I'd like other people to weigh in too.
> 
> > Because only TDH.MNG.CREATE() and TDH.MNG.ADDCX() can return TDX_RND_NO_ENTROPY, > we can use __seamcall().  The TDX spec doesn't guarantee such error code
> > convention.  It's very unlikely, though.
> 
> I don't quite follow the "convention" part.  Can you elaborate?
> 
> NO_ENTROPY is already handled in seamcall() variants.  Can we just use them
> directly?

I intended for bad code generation.  If the loop on NO_ENTRY error harms the
code generation, we might be able to use __seamcall() or __seamcall_ret()
instead of seamcall(), seamcall_ret().
-- 
Isaku Yamahata <isaku.yamahata@...el.com>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ