Re: [PATCH RFC 1/7] x86/virt/tdx: Add SEAMCALL wrapper to enter/exit TDX guest

From: Dave Hansen
Date: Fri Dec 13 2024 - 11:44:30 EST


On 12/13/24 08:30, Adrian Hunter wrote:
> On 13/12/24 18:16, Dave Hansen wrote:
>> On 12/11/24 10:43, Adrian Hunter wrote:
>> ...
>>> - size = tdvmcall_a0_read(vcpu);
>>> - write = tdvmcall_a1_read(vcpu);
>>> - port = tdvmcall_a2_read(vcpu);
>>> + size = tdx->vp_enter_out.io_size;
>>> + write = tdx->vp_enter_out.io_direction == TDX_WRITE;
>>> + port = tdx->vp_enter_out.io_port;
>> ...> + case TDVMCALL_IO:
>>> + out->io_size = args.r12;
>>> + out->io_direction = args.r13 ? TDX_WRITE : TDX_READ;
>>> + out->io_port = args.r14;
>>> + out->io_value = args.r15;
>>> + break;
>>
>> I honestly don't understand the need for the abstracted structure to sit
>> in the middle. It doesn't get stored or serialized or anything, right?
>> So why have _another_ structure?
>>
>> Why can't this just be (for instance):
>>
>> size = tdx->foo.r12;
>>
>> ?
>>
>> Basically, you hand around the raw arguments until you need to use them.
>
> That sounds like what we have at present? That is:
>
> u64 tdh_vp_enter(u64 tdvpr, struct tdx_module_args *args)
> {
> args->rcx = tdvpr;
>
> return __seamcall_saved_ret(TDH_VP_ENTER, args);
> }
>
> And then either add Rick's struct tdx_vp? Like so:
>
> u64 tdh_vp_enter(struct tdx_vp *vp, struct tdx_module_args *args)
> {
> args->rcx = tdx_tdvpr_pa(vp);
>
> return __seamcall_saved_ret(TDH_VP_ENTER, args);
> }
>
> Or leave it to the caller:
>
> u64 tdh_vp_enter(struct tdx_module_args *args)
> {
> return __seamcall_saved_ret(TDH_VP_ENTER, args);
> }
>
> Or forget the wrapper altogether, and let KVM call
> __seamcall_saved_ret() ?

Rick's version, please.

I don't want __seamcall_saved_ret() exported to modules. I want to at
least have a clean boundary beyond which __seamcall_saved_ret() is not
exposed.

My nit with the "u64 tdvpr" version was that there's zero type safety.

The tdvp-less tdh_vp_enter() is even *less* safe of a calling convention
and also requires that each caller do tdx_tdvpr_pa() or equivalent.

But I feel like I'm repeating myself a bit at this point.