Re: [PATCH v6 05/10] x86/tdx: Handle port I/O

From: Tom Lendacky
Date: Thu Sep 23 2021 - 13:59:51 EST


On 9/23/21 12:24 PM, Kuppuswamy, Sathyanarayanan wrote:


On 9/23/21 9:32 AM, Tom Lendacky wrote:
On 9/22/21 5:52 PM, Kuppuswamy Sathyanarayanan wrote:
From: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx>

TDX hypervisors cannot emulate instructions directly. This includes
port IO which is normally emulated in the hypervisor. All port IO
instructions inside TDX trigger the #VE exception in the guest and
would be normally emulated there.

Also string I/O is not supported in TDX guest. So, unroll the string
I/O operation into a loop operating on one element at a time. This
method is similar to AMD SEV, so just extend the support for TDX guest
platform.

Add a new confidential guest flag CC_ATTR_GUEST_UNROLL_STRING_IO to
add string unroll support in asm/io.h

Co-developed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@xxxxxxxxxxxxxxx>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@xxxxxxxxxxxxxxx>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx>
Reviewed-by: Andi Kleen <ak@xxxxxxxxxxxxxxx>
Reviewed-by: Dan Williams <dan.j.williams@xxxxxxxxx>
---

Changes since v5:
  * Changed prot_guest_has() to cc_platform_has().

Changes since v4:
  * Changed order of variable declaration in tdx_handle_io().
  * Changed tdg_* prefix with tdx_*.

Changes since v3:
  * Included PATTR_GUEST_UNROLL_STRING_IO protected guest flag
    addition change in this patch.
  * Rebased on top of Tom Lendacks protected guest change.

Changes since v2:
  * None

Changes since v1:
  * Fixed comments for tdg_handle_io().
  * Used _tdx_hypercall() instead of __tdx_hypercall() in tdg_handle_io().

  arch/x86/include/asm/io.h   |  7 +++++--
  arch/x86/kernel/cpu/intel.c |  1 +
  arch/x86/kernel/tdx.c       | 35 +++++++++++++++++++++++++++++++++++
  include/linux/cc_platform.h | 11 +++++++++++
  4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index fa6aa43e5dc3..67e0c4a0a0f4 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -40,6 +40,7 @@
  #include <linux/string.h>
  #include <linux/compiler.h>
+#include <linux/cc_platform.h>
  #include <asm/page.h>
  #include <asm/tdx.h>
  #include <asm/early_ioremap.h>
@@ -310,7 +311,8 @@ static inline unsigned type in##bwl##_p(int port)            \
                                      \
  static inline void outs##bwl(int port, const void *addr, unsigned long count) \
  {                                    \
-    if (sev_key_active()) {                        \ > +    if (sev_key_active() ||                        \
+        cc_platform_has(CC_ATTR_GUEST_UNROLL_STRING_IO)) {        \

Would it make sense to make sev_key_active() and sev_enable_key generic and just re-use those instead of adding CC_ATTR_GUEST_UNROLL_STRING_IO and having multiple conditions here?

You can set the key in the TDX init routine just like SEV does.

Any reason for using sev_enable_key over CC attribute? IMO, CC attribute exist
to generalize the common feature code. My impression is SEV is specific to AMD
code.

When the SEV series was initially submitted, it originally did an sev_active() check. For various reasons a static key and the sev_key_active() call was requested.

My suggestion was to change the name to something that doesn't have SEV/sev in it that can be used by both SEV and TDX. The sev_enable_key can be moved to a common file (maybe cc_platform.c) and renamed. Then arch/x86/include/asm/io.h can change the #ifdef from CONFIG_AMD_MEM_ENCRYPT to CONFIG_ARCH_HAS_CC_PLATFORM.

Not sure if anyone else feels the same, though, so just my suggestion.

Thanks,
Tom



Thanks,
Tom