Merge tag 'x86_tdx_for_6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 26 Jun 2023 23:32:47 +0000 (16:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 26 Jun 2023 23:32:47 +0000 (16:32 -0700)
Pull x86 tdx updates from Dave Hansen:

 - Fix a race window where load_unaligned_zeropad() could cause a fatal
   shutdown during TDX private<=>shared conversion

   The race has never been observed in practice but might allow
   load_unaligned_zeropad() to catch a TDX page in the middle of its
   conversion process which would lead to a fatal and unrecoverable
   guest shutdown.

 - Annotate sites where VM "exit reasons" are reused as hypercall
   numbers.

* tag 'x86_tdx_for_6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mm: Fix enc_status_change_finish_noop()
  x86/tdx: Fix race between set_memory_encrypted() and load_unaligned_zeropad()
  x86/mm: Allow guest.enc_status_change_prepare() to fail
  x86/tdx: Wrap exit reason with hcall_func()

1  2 
arch/x86/coco/tdx/tdx.c
arch/x86/include/asm/shared/tdx.h
arch/x86/include/asm/x86_init.h
arch/x86/kernel/x86_init.c
arch/x86/mm/mem_encrypt_amd.c
arch/x86/mm/pat/set_memory.c

@@@ -771,20 -880,30 +784,41 @@@ void __init tdx_early_init(void
         */
        physical_mask &= cc_mask - 1;
  
-       x86_platform.guest.enc_cache_flush_required = tdx_cache_flush_required;
-       x86_platform.guest.enc_tlb_flush_required   = tdx_tlb_flush_required;
-       x86_platform.guest.enc_status_change_finish = tdx_enc_status_changed;
+       /*
+        * The kernel mapping should match the TDX metadata for the page.
+        * load_unaligned_zeropad() can touch memory *adjacent* to that which is
+        * owned by the caller and can catch even _momentary_ mismatches.  Bad
+        * things happen on mismatch:
+        *
+        *   - Private mapping => Shared Page  == Guest shutdown
+          *   - Shared mapping  => Private Page == Recoverable #VE
+        *
+        * guest.enc_status_change_prepare() converts the page from
+        * shared=>private before the mapping becomes private.
+        *
+        * guest.enc_status_change_finish() converts the page from
+        * private=>shared after the mapping becomes private.
+        *
+        * In both cases there is a temporary shared mapping to a private page,
+        * which can result in a #VE.  But, there is never a private mapping to
+        * a shared page.
+        */
+       x86_platform.guest.enc_status_change_prepare = tdx_enc_status_change_prepare;
+       x86_platform.guest.enc_status_change_finish  = tdx_enc_status_change_finish;
+       x86_platform.guest.enc_cache_flush_required  = tdx_cache_flush_required;
+       x86_platform.guest.enc_tlb_flush_required    = tdx_tlb_flush_required;
  
 +      /*
 +       * TDX intercepts the RDMSR to read the X2APIC ID in the parallel
 +       * bringup low level code. That raises #VE which cannot be handled
 +       * there.
 +       *
 +       * Intel-TDX has a secure RDMSR hypercall, but that needs to be
 +       * implemented seperately in the low level startup ASM code.
 +       * Until that is in place, disable parallel bringup for TDX.
 +       */
 +      x86_cpuinit.parallel_bringup = false;
 +
        pr_info("Guest detected\n");
  }
@@@ -74,24 -41,15 +74,35 @@@ static inline u64 _tdx_hypercall(u64 fn
  void __tdx_hypercall_failed(void);
  
  /*
 + * Used in __tdx_module_call() to gather the output registers' values of the
 + * TDCALL instruction when requesting services from the TDX module. This is a
 + * software only structure and not part of the TDX module/VMM ABI
 + */
 +struct tdx_module_output {
 +      u64 rcx;
 +      u64 rdx;
 +      u64 r8;
 +      u64 r9;
 +      u64 r10;
 +      u64 r11;
 +};
 +
 +/* Used to communicate with the TDX module */
 +u64 __tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
 +                    struct tdx_module_output *out);
 +
 +bool tdx_accept_memory(phys_addr_t start, phys_addr_t end);
 +
++/*
+  * The TDG.VP.VMCALL-Instruction-execution sub-functions are defined
+  * independently from but are currently matched 1:1 with VMX EXIT_REASONs.
+  * Reusing the KVM EXIT_REASON macros makes it easier to connect the host and
+  * guest sides of these calls.
+  */
+ static __always_inline u64 hcall_func(u64 exit_reason)
+ {
+         return exit_reason;
+ }
  #endif /* !__ASSEMBLY__ */
  #endif /* _ASM_X86_SHARED_TDX_H */
Simple merge
Simple merge
Simple merge
Simple merge