From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
To: Borislav Petkov <bp@alien8.de>
Cc: tglx@linutronix.de, mingo@redhat.com, dave.hansen@intel.com,
luto@kernel.org, peterz@infradead.org,
sathyanarayanan.kuppuswamy@linux.intel.com, aarcange@redhat.com,
ak@linux.intel.com, dan.j.williams@intel.com, david@redhat.com,
hpa@zytor.com, jgross@suse.com, jmattson@google.com,
joro@8bytes.org, jpoimboe@redhat.com, knsathya@kernel.org,
pbonzini@redhat.com, sdeep@vmware.com, seanjc@google.com,
tony.luck@intel.com, vkuznets@redhat.com, wanpengli@tencent.com,
thomas.lendacky@amd.com, brijesh.singh@amd.com, x86@kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCHv5 03/30] x86/tdx: Add __tdx_module_call() and __tdx_hypercall() helper functions
Date: Fri, 11 Mar 2022 00:20:59 +0300 [thread overview]
Message-ID: <20220310212059.6abpmnsgodqqqnfm@black.fi.intel.com> (raw)
In-Reply-To: <YioZnTYahkoy2Mxz@zn.tnic>
On Thu, Mar 10, 2022 at 04:30:57PM +0100, Borislav Petkov wrote:
> On Wed, Mar 02, 2022 at 05:27:39PM +0300, Kirill A. Shutemov wrote:
> > From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> >
> > Guests communicate with VMMs with hypercalls. Historically, these
> > are implemented using instructions that are known to cause VMEXITs
> > like VMCALL, VMLAUNCH, etc. However, with TDX, VMEXITs no longer
> > expose the guest state to the host. This prevents the old hypercall
> > mechanisms from working. So, to communicate with VMM, TDX
> > specification defines a new instruction called TDCALL.
> >
> > In a TDX based VM, since the VMM is an untrusted entity, an intermediary
> > layer -- TDX module -- facilitates secure communication between the host
> > and the guest. TDX module is loaded like a firmware into a special CPU
> > mode called SEAM. TDX guests communicate with the TDX module using the
> > TDCALL instruction.
> >
> > A guest uses TDCALL to communicate with both the TDX module and VMM.
> > The value of the RAX register when executing the TDCALL instruction is
> > used to determine the TDCALL type. A variant of TDCALL used to communicate
> > with the VMM is called TDVMCALL.
> >
> > Add generic interfaces to communicate with the TDX module and VMM
> > (using the TDCALL instruction).
> >
> > __tdx_hypercall() - Used by the guest to request services from the
> > VMM (via TDVMCALL).
> > __tdx_module_call() - Used to communicate with the TDX module (via
> > TDCALL).
>
> Ok, you need to fix this: this sounds to me like there are two insns:
> TDCALL and TDVMCALL. But there's only TDCALL.
>
> And I'm not even clear on how the differentiation is done - I guess
> with %r11 which contains the VMCALL subfunction number in the
> __tdx_hypercall() case but I'm not sure.
TDVMCALL is a leaf of TDCALL. The leaf number is encoded in RAX: RAX==0 is
TDVMCALL.
I'm not completely sure what has to be fixed. Make it clear that TDVMCALL
is leaf of TDCALL? Something like this:
__tdx_module_call() - Used to communicate with the TDX module (via
TDCALL instruction).
__tdx_hypercall() - Used by the guest to request services from the
VMM (via TDVMCALL leaf of TDCALL).
?
> And when explaining this, pls put it in the comment over the function so
> that it is clear how the distinction is made.
But it's already there:
/*
* __tdx_module_call() - Used by TDX guests to request services from
* the TDX module (does not include VMM services).
*
* Transforms function call register arguments into the TDCALL
* register ABI. After TDCALL operation, TDX module output is saved
* in @out (if it is provided by the user)
*
...
*/
and
/*
* __tdx_hypercall() - Make hypercalls to a TDX VMM.
*
* Transforms values in function call argument struct tdx_hypercall_args @args
* into the TDCALL register ABI. After TDCALL operation, VMM output is saved
* back in @args.
*
*-------------------------------------------------------------------------
* TD VMCALL ABI:
*-------------------------------------------------------------------------
*
* Input Registers:
*
* RAX - TDCALL instruction leaf number (0 - TDG.VP.VMCALL)
.....
*/
Hm?
> > Also define an additional wrapper _tdx_hypercall(), which adds error
> > handling support for the TDCALL failure.
> >
> > The __tdx_module_call() and __tdx_hypercall() helper functions are
> > implemented in assembly in a .S file. The TDCALL ABI requires
> > shuffling arguments in and out of registers, which proved to be
> > awkward with inline assembly.
> >
> > Just like syscalls, not all TDVMCALL use cases need to use the same
> > number of argument registers. The implementation here picks the current
> > worst-case scenario for TDCALL (4 registers). For TDCALLs with fewer
> > than 4 arguments, there will end up being a few superfluous (cheap)
> > instructions. But, this approach maximizes code reuse.
> >
> > For registers used by the TDCALL instruction, please check TDX GHCI
> > specification, the section titled "TDCALL instruction" and "TDG.VP.VMCALL
> > Interface".
> >
> > Based on previous patch by Sean Christopherson.
> >
> > Reviewed-by: Tony Luck <tony.luck@intel.com>
> > Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> > Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> > ---
> > arch/x86/coco/Makefile | 2 +-
> > arch/x86/coco/tdcall.S | 188 ++++++++++++++++++++++++++++++++++
> > arch/x86/coco/tdx.c | 18 ++++
>
> Those should be
>
> arch/x86/coco/tdx/tdcall.S
> arch/x86/coco/tdx/tdx.c
>
> like we said:
>
> "- confidential computing guest stuff: arch/x86/coco/{sev,tdx}"
Okay, will change. But it is not what we agreed about before:
https://lore.kernel.org/all/Yg5q742GsjCRHXZL@zn.tnic
> > arch/x86/include/asm/tdx.h | 27 +++++
> > arch/x86/kernel/asm-offsets.c | 10 ++
> > 5 files changed, 244 insertions(+), 1 deletion(-)
> > create mode 100644 arch/x86/coco/tdcall.S
>
> ...
>
> > +SYM_FUNC_START(__tdx_hypercall)
> > + FRAME_BEGIN
> > +
> > + /* Save callee-saved GPRs as mandated by the x86_64 ABI */
> > + push %r15
> > + push %r14
> > + push %r13
> > + push %r12
> > +
> > + /* Mangle function call ABI into TDCALL ABI: */
> > + /* Set TDCALL leaf ID (TDVMCALL (0)) in RAX */
> > + xor %eax, %eax
> > +
> > + /* Copy hypercall registers from arg struct: */
> > + movq TDX_HYPERCALL_r10(%rdi), %r10
> > + movq TDX_HYPERCALL_r11(%rdi), %r11
> > + movq TDX_HYPERCALL_r12(%rdi), %r12
> > + movq TDX_HYPERCALL_r13(%rdi), %r13
> > + movq TDX_HYPERCALL_r14(%rdi), %r14
> > + movq TDX_HYPERCALL_r15(%rdi), %r15
> > +
> > + movl $TDVMCALL_EXPOSE_REGS_MASK, %ecx
> > +
> > + tdcall
> > +
> > + /*
> > + * RAX==0 indicates a failure of the TDVMCALL mechanism itself and that
> > + * something has gone horribly wrong with the TDX module.
> > + *
> > + * The return status of the hypercall operation is in a separate
> > + * register (in R10). Hypercall errors are a part of normal operation
> > + * and are handled by callers.
> > + */
> > + testq %rax, %rax
> > + jne .Lpanic
>
> Hm, can this call a C function which does the panic so that a proper
> error message is dumped to the user so that at least she knows where the
> panic comes from?
Sure we can. But it would look somewhat clunky.
Wouldn't backtrace be enough for this (never to be seen) case?
So far the panic would look like this:
invalid opcode: 0000 [#1] PREEMPT SMP
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.17.0-rc5-00181-geb9d1dde679a-dirty #1883
RIP: 0010:__tdx_hypercall+0x6d/0x70
Code: 00 00 74 17 4c 89 17 4c 89 5f 08 4c 89 67 10 4c 89 6f 18 4c 89 77 20 4c 89 7f 28 45 31 d2 45 31 db 41 5c 41 5d 41 5e 41 5f c3 <0f> 0b 00 55 53 41 54 41 55 41 56 41 57 48 89 a7 98 1b 00 00 48 8b
RSP: 0000:ffffffff82803e80 EFLAGS: 00010002
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 000000000000fc00
RDX: ff11000004c3d448 RSI: 0000000000000002 RDI: ffffffff82803ea8
RBP: ffffffff8283e840 R08: 0000000000000000 R09: 000000005eee98b1
R10: 0000000000000000 R11: 000000000000000c R12: 0000000000000000
R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ff1100001c400000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ff1100001c9ff000 CR3: 0000000002834001 CR4: 0000000000771ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
<TASK>
tdx_safe_halt+0x46/0x80
default_idle_call+0x4f/0x90
do_idle+0xeb/0x250
cpu_startup_entry+0x15/0x20
start_kernel+0x372/0x3d1
secondary_startup_64_no_verify+0xe5/0xeb
</TASK>
To me "invalid opcode" at "RIP: 0010:__tdx_hypercall+0x6d/0x70" is pretty
clear where it comes from, no?
> > +
> > + /* TDVMCALL leaf return code is in R10 */
> > + movq %r10, %rax
> > +
> > + /* Copy hypercall result registers to arg struct if needed */
> > + testq $TDX_HCALL_HAS_OUTPUT, %rsi
> > + jz .Lout
> > +
> > + movq %r10, TDX_HYPERCALL_r10(%rdi)
> > + movq %r11, TDX_HYPERCALL_r11(%rdi)
> > + movq %r12, TDX_HYPERCALL_r12(%rdi)
> > + movq %r13, TDX_HYPERCALL_r13(%rdi)
> > + movq %r14, TDX_HYPERCALL_r14(%rdi)
> > + movq %r15, TDX_HYPERCALL_r15(%rdi)
> > +.Lout:
> > + /*
> > + * Zero out registers exposed to the VMM to avoid speculative execution
> > + * with VMM-controlled values. This needs to include all registers
> > + * present in TDVMCALL_EXPOSE_REGS_MASK (except R12-R15). R12-R15
> > + * context will be restored.
> > + */
> > + xor %r10d, %r10d
> > + xor %r11d, %r11d
> > +
> > + /* Restore callee-saved GPRs as mandated by the x86_64 ABI */
> > + pop %r12
> > + pop %r13
> > + pop %r14
> > + pop %r15
> > +
> > + FRAME_END
> > +
> > + retq
> > +.Lpanic:
> > + ud2
> > +SYM_FUNC_END(__tdx_hypercall)
>
> ...
>
> > diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
> > index 7dca52f5cfc6..0b465e7d0a2f 100644
> > --- a/arch/x86/kernel/asm-offsets.c
> > +++ b/arch/x86/kernel/asm-offsets.c
> > @@ -74,6 +74,16 @@ static void __used common(void)
> > OFFSET(TDX_MODULE_r10, tdx_module_output, r10);
> > OFFSET(TDX_MODULE_r11, tdx_module_output, r11);
> >
> > +#ifdef CONFIG_INTEL_TDX_GUEST
>
> Those have ifdeffery around them - why don't the TDX_MODULE_* ones need
> it too?
I will drop the #ifdef. There's no harm in generating it for !TDX build.
> > + BLANK();
> > + OFFSET(TDX_HYPERCALL_r10, tdx_hypercall_args, r10);
> > + OFFSET(TDX_HYPERCALL_r11, tdx_hypercall_args, r11);
> > + OFFSET(TDX_HYPERCALL_r12, tdx_hypercall_args, r12);
> > + OFFSET(TDX_HYPERCALL_r13, tdx_hypercall_args, r13);
> > + OFFSET(TDX_HYPERCALL_r14, tdx_hypercall_args, r14);
> > + OFFSET(TDX_HYPERCALL_r15, tdx_hypercall_args, r15);
> > +#endif
> > +
>
> --
> Regards/Gruss,
> Boris.
>
> https://people.kernel.org/tglx/notes-about-netiquette
--
Kirill A. Shutemov
next prev parent reply other threads:[~2022-03-10 21:20 UTC|newest]
Thread overview: 84+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-02 14:27 [PATCHv5 00/30] TDX Guest: TDX core support Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 01/30] x86/tdx: Detect running as a TDX guest in early boot Kirill A. Shutemov
2022-03-04 15:43 ` Borislav Petkov
2022-03-04 15:47 ` Dave Hansen
2022-03-04 16:02 ` Borislav Petkov
2022-03-07 22:24 ` [PATCHv5.1 " Kirill A. Shutemov
2022-03-09 18:22 ` Borislav Petkov
2022-03-02 14:27 ` [PATCHv5 02/30] x86/tdx: Provide common base for SEAMCALL and TDCALL C wrappers Kirill A. Shutemov
2022-03-08 19:56 ` Dave Hansen
2022-03-10 12:32 ` Borislav Petkov
2022-03-10 14:44 ` Kirill A. Shutemov
2022-03-10 14:51 ` Borislav Petkov
2022-03-02 14:27 ` [PATCHv5 03/30] x86/tdx: Add __tdx_module_call() and __tdx_hypercall() helper functions Kirill A. Shutemov
2022-03-08 20:03 ` Dave Hansen
2022-03-10 15:30 ` Borislav Petkov
2022-03-10 21:20 ` Kirill A. Shutemov [this message]
2022-03-10 21:48 ` Kirill A. Shutemov
2022-03-15 15:56 ` Borislav Petkov
2022-03-12 10:41 ` Borislav Petkov
2022-03-02 14:27 ` [PATCHv5 04/30] x86/tdx: Extend the confidential computing API to support TDX guests Kirill A. Shutemov
2022-03-08 20:17 ` Dave Hansen
2022-03-09 16:01 ` [PATCHv5.1 " Kirill A. Shutemov
2022-03-09 18:36 ` Dave Hansen
2022-03-09 23:51 ` [PATCHv5.2 " Kirill A. Shutemov
2022-03-10 0:07 ` Dave Hansen
2022-03-15 19:41 ` Borislav Petkov
2022-03-02 14:27 ` [PATCHv5 05/30] x86/tdx: Exclude shared bit from __PHYSICAL_MASK Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 06/30] x86/traps: Refactor exc_general_protection() Kirill A. Shutemov
2022-03-08 20:18 ` Dave Hansen
2022-03-02 14:27 ` [PATCHv5 07/30] x86/traps: Add #VE support for TDX guest Kirill A. Shutemov
2022-03-08 20:29 ` Dave Hansen
2022-03-02 14:27 ` [PATCHv5 08/30] x86/tdx: Add HLT support for TDX guests Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 09/30] x86/tdx: Add MSR " Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 10/30] x86/tdx: Handle CPUID via #VE Kirill A. Shutemov
2022-03-08 20:33 ` Dave Hansen
2022-03-09 16:15 ` [PATCH] " Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 11/30] x86/tdx: Handle in-kernel MMIO Kirill A. Shutemov
2022-03-08 21:26 ` Dave Hansen
2022-03-10 0:51 ` Kirill A. Shutemov
2022-03-10 1:06 ` Dave Hansen
2022-03-10 16:48 ` Kirill A. Shutemov
2022-03-10 17:53 ` Dave Hansen
2022-03-11 17:18 ` Kirill A. Shutemov
2022-03-11 17:22 ` Dave Hansen
2022-03-11 18:01 ` Dave Hansen
2022-03-02 14:27 ` [PATCHv5 12/30] x86/tdx: Detect TDX at early kernel decompression time Kirill A. Shutemov
2022-03-07 22:27 ` [PATCHv5.1 " Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 13/30] x86: Adjust types used in port I/O helpers Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 14/30] x86: Consolidate " Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 15/30] x86/boot: Port I/O: allow to hook up alternative helpers Kirill A. Shutemov
2022-03-02 17:42 ` Josh Poimboeuf
2022-03-02 19:41 ` Dave Hansen
2022-03-02 20:02 ` Josh Poimboeuf
2022-03-02 14:27 ` [PATCHv5 16/30] x86/boot: Port I/O: add decompression-time support for TDX Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 17/30] x86/tdx: Port I/O: add runtime hypercalls Kirill A. Shutemov
2022-03-08 21:30 ` Dave Hansen
2022-03-02 14:27 ` [PATCHv5 18/30] x86/tdx: Port I/O: add early boot support Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 19/30] x86/tdx: Wire up KVM hypercalls Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 20/30] x86/boot: Add a trampoline for booting APs via firmware handoff Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 21/30] x86/acpi, x86/boot: Add multiprocessor wake-up support Kirill A. Shutemov
2022-03-02 14:27 ` [PATCHv5 22/30] x86/boot: Set CR0.NE early and keep it set during the boot Kirill A. Shutemov
2022-03-08 21:37 ` Dave Hansen
2022-03-02 14:27 ` [PATCHv5 23/30] x86/boot: Avoid #VE during boot for TDX platforms Kirill A. Shutemov
2022-03-07 9:29 ` Xiaoyao Li
2022-03-07 22:33 ` Kirill A. Shutemov
2022-03-08 1:19 ` Xiaoyao Li
2022-03-08 16:41 ` Kirill A. Shutemov
2022-03-07 22:36 ` [PATCHv5.1 " Kirill A. Shutemov
2022-03-02 14:28 ` [PATCHv5 24/30] x86/topology: Disable CPU online/offline control for TDX guests Kirill A. Shutemov
2022-03-02 14:28 ` [PATCHv5 25/30] x86/tdx: Make pages shared in ioremap() Kirill A. Shutemov
2022-03-08 22:02 ` Dave Hansen
2022-03-02 14:28 ` [PATCHv5 26/30] x86/mm/cpa: Add support for TDX shared memory Kirill A. Shutemov
2022-03-09 19:44 ` Dave Hansen
2022-03-02 14:28 ` [PATCHv5 27/30] x86/kvm: Use bounce buffers for TD guest Kirill A. Shutemov
2022-03-09 20:07 ` Dave Hansen
2022-03-10 14:29 ` Tom Lendacky
2022-03-10 14:51 ` Christoph Hellwig
2022-03-02 14:28 ` [PATCHv5 28/30] x86/tdx: ioapic: Add shared bit for IOAPIC base address Kirill A. Shutemov
2022-03-09 20:39 ` Dave Hansen
2022-03-02 14:28 ` [PATCHv5 29/30] ACPICA: Avoid cache flush inside virtual machines Kirill A. Shutemov
2022-03-02 16:13 ` Dan Williams
2022-03-09 20:56 ` Dave Hansen
2022-03-02 14:28 ` [PATCHv5 30/30] Documentation/x86: Document TDX kernel architecture Kirill A. Shutemov
2022-03-09 21:49 ` Dave Hansen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220310212059.6abpmnsgodqqqnfm@black.fi.intel.com \
--to=kirill.shutemov@linux.intel.com \
--cc=aarcange@redhat.com \
--cc=ak@linux.intel.com \
--cc=bp@alien8.de \
--cc=brijesh.singh@amd.com \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@intel.com \
--cc=david@redhat.com \
--cc=hpa@zytor.com \
--cc=jgross@suse.com \
--cc=jmattson@google.com \
--cc=joro@8bytes.org \
--cc=jpoimboe@redhat.com \
--cc=knsathya@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=sathyanarayanan.kuppuswamy@linux.intel.com \
--cc=sdeep@vmware.com \
--cc=seanjc@google.com \
--cc=tglx@linutronix.de \
--cc=thomas.lendacky@amd.com \
--cc=tony.luck@intel.com \
--cc=vkuznets@redhat.com \
--cc=wanpengli@tencent.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®