Merge tag 'x86_seves_for_v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 14 Oct 2020 17:21:34 +0000 (10:21 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 14 Oct 2020 17:21:34 +0000 (10:21 -0700)
Pull x86 SEV-ES support from Borislav Petkov:
 "SEV-ES enhances the current guest memory encryption support called SEV
  by also encrypting the guest register state, making the registers
  inaccessible to the hypervisor by en-/decrypting them on world
  switches. Thus, it adds additional protection to Linux guests against
  exfiltration, control flow and rollback attacks.

  With SEV-ES, the guest is in full control of what registers the
  hypervisor can access. This is provided by a guest-host exchange
  mechanism based on a new exception vector called VMM Communication
  Exception (#VC), a new instruction called VMGEXIT and a shared
  Guest-Host Communication Block which is a decrypted page shared
  between the guest and the hypervisor.

  Intercepts to the hypervisor become #VC exceptions in an SEV-ES guest
  so in order for that exception mechanism to work, the early x86 init
  code needed to be made able to handle exceptions, which, in itself,
  brings a bunch of very nice cleanups and improvements to the early
  boot code like an early page fault handler, allowing for on-demand
  building of the identity mapping. With that, !KASLR configurations do
  not use the EFI page table anymore but switch to a kernel-controlled
  one.

  The main part of this series adds the support for that new exchange
  mechanism. The goal has been to keep this as much as possibly separate
  from the core x86 code by concentrating the machinery in two
  SEV-ES-specific files:

    arch/x86/kernel/sev-es-shared.c
    arch/x86/kernel/sev-es.c

  Other interaction with core x86 code has been kept at minimum and
  behind static keys to minimize the performance impact on !SEV-ES
  setups.

  Work by Joerg Roedel and Thomas Lendacky and others"

* tag 'x86_seves_for_v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (73 commits)
  x86/sev-es: Use GHCB accessor for setting the MMIO scratch buffer
  x86/sev-es: Check required CPU features for SEV-ES
  x86/efi: Add GHCB mappings when SEV-ES is active
  x86/sev-es: Handle NMI State
  x86/sev-es: Support CPU offline/online
  x86/head/64: Don't call verify_cpu() on starting APs
  x86/smpboot: Load TSS and getcpu GDT entry before loading IDT
  x86/realmode: Setup AP jump table
  x86/realmode: Add SEV-ES specific trampoline entry point
  x86/vmware: Add VMware-specific handling for VMMCALL under SEV-ES
  x86/kvm: Add KVM-specific VMMCALL handling under SEV-ES
  x86/paravirt: Allow hypervisor-specific VMMCALL handling under SEV-ES
  x86/sev-es: Handle #DB Events
  x86/sev-es: Handle #AC Events
  x86/sev-es: Handle VMMCALL Events
  x86/sev-es: Handle MWAIT/MWAITX Events
  x86/sev-es: Handle MONITOR/MONITORX Events
  x86/sev-es: Handle INVD Events
  x86/sev-es: Handle RDPMC Events
  x86/sev-es: Handle RDTSC(P) Events
  ...

24 files changed:
1  2 
arch/x86/Kconfig
arch/x86/boot/compressed/Makefile
arch/x86/boot/compressed/head_64.S
arch/x86/entry/entry_64.S
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/fpu/internal.h
arch/x86/include/asm/idtentry.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/pgtable.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/segment.h
arch/x86/include/asm/traps.h
arch/x86/include/asm/x86_init.h
arch/x86/kernel/Makefile
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/scattered.c
arch/x86/kernel/dumpstack.c
arch/x86/kernel/idt.c
arch/x86/kernel/kvm.c
arch/x86/kernel/nmi.c
arch/x86/kernel/traps.c
arch/x86/kvm/svm/nested.c
arch/x86/kvm/svm/svm.c
arch/x86/mm/extable.c

Simple merge
@@@ -29,10 -29,10 +29,10 @@@ targets := vmlinux vmlinux.bin vmlinux.
        vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 vmlinux.bin.zst
  
  KBUILD_CFLAGS := -m$(BITS) -O2
 -KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC)
 +KBUILD_CFLAGS += -fno-strict-aliasing -fPIE
  KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
  cflags-$(CONFIG_X86_32) := -march=i386
- cflags-$(CONFIG_X86_64) := -mcmodel=small
+ cflags-$(CONFIG_X86_64) := -mcmodel=small -mno-red-zone
  KBUILD_CFLAGS += $(cflags-y)
  KBUILD_CFLAGS += -mno-mmx -mno-sse
  KBUILD_CFLAGS += -ffreestanding
@@@ -43,10 -43,12 +43,15 @@@ KBUILD_CFLAGS += -Wno-pointer-sig
  KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=)
  KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
  KBUILD_CFLAGS += -D__DISABLE_EXPORTS
 +# Disable relocation relaxation in case the link is not PIE.
 +KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no)
 +KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h
  
+ # sev-es.c indirectly inludes inat-table.h which is generated during
+ # compilation and stored in $(objtree). Add the directory to the includes so
+ # that the compiler finds it even with out-of-tree builds (make O=/some/path).
+ CFLAGS_sev-es.o += -I$(objtree)/arch/x86/lib/
  KBUILD_AFLAGS  := $(KBUILD_CFLAGS) -D__ASSEMBLY__
  GCOV_PROFILE := n
  UBSAN_SANITIZE :=n
Simple merge
Simple merge
Simple merge
@@@ -583,42 -584,6 +584,13 @@@ static inline void switch_fpu_finish(st
                        pkru_val = pk->pkru;
        }
        __write_pkru(pkru_val);
 +
 +      /*
 +       * Expensive PASID MSR write will be avoided in update_pasid() because
 +       * TIF_NEED_FPU_LOAD was set. And the PASID state won't be updated
 +       * unless it's different from mm->pasid to reduce overhead.
 +       */
 +      update_pasid();
  }
  
- /*
-  * MXCSR and XCR definitions:
-  */
- static inline void ldmxcsr(u32 mxcsr)
- {
-       asm volatile("ldmxcsr %0" :: "m" (mxcsr));
- }
- extern unsigned int mxcsr_feature_mask;
- #define XCR_XFEATURE_ENABLED_MASK     0x00000000
- static inline u64 xgetbv(u32 index)
- {
-       u32 eax, edx;
-       asm volatile("xgetbv" : "=a" (eax), "=d" (edx) : "c" (index));
-       return eax + ((u64)edx << 32);
- }
- static inline void xsetbv(u32 index, u64 value)
- {
-       u32 eax = value;
-       u32 edx = value >> 32;
-       asm volatile("xsetbv" :: "a" (eax), "d" (edx), "c" (index));
- }
  #endif /* _ASM_X86_FPU_INTERNAL_H */
Simple merge
  #define MSR_AMD64_IBSOP_REG_MASK      ((1UL<<MSR_AMD64_IBSOP_REG_COUNT)-1)
  #define MSR_AMD64_IBSCTL              0xc001103a
  #define MSR_AMD64_IBSBRTARGET         0xc001103b
 +#define MSR_AMD64_ICIBSEXTDCTL                0xc001103c
  #define MSR_AMD64_IBSOPDATA4          0xc001103d
  #define MSR_AMD64_IBS_REG_COUNT_MAX   8 /* includes MSR_AMD64_IBSBRTARGET */
+ #define MSR_AMD64_SEV_ES_GHCB         0xc0010130
  #define MSR_AMD64_SEV                 0xc0010131
  #define MSR_AMD64_SEV_ENABLED_BIT     0
+ #define MSR_AMD64_SEV_ES_ENABLED_BIT  1
  #define MSR_AMD64_SEV_ENABLED         BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT)
+ #define MSR_AMD64_SEV_ES_ENABLED      BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT)
  
  #define MSR_AMD64_VIRT_SPEC_CTRL      0xc001011f
  
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -4,11 -4,12 +4,13 @@@
  
  #include <asm/bootparam.h>
  
+ struct ghcb;
  struct mpc_bus;
  struct mpc_cpu;
+ struct pt_regs;
  struct mpc_table;
  struct cpuinfo_x86;
 +struct irq_domain;
  
  /**
   * struct x86_init_mpparse - platform specific mpparse ops
Simple merge
Simple merge
@@@ -42,7 -41,7 +42,8 @@@ static const struct cpuid_bit cpuid_bit
        { X86_FEATURE_MBA,              CPUID_EBX,  6, 0x80000008, 0 },
        { X86_FEATURE_SME,              CPUID_EAX,  0, 0x8000001f, 0 },
        { X86_FEATURE_SEV,              CPUID_EAX,  1, 0x8000001f, 0 },
+       { X86_FEATURE_SEV_ES,           CPUID_EAX,  3, 0x8000001f, 0 },
 +      { X86_FEATURE_SME_COHERENT,     CPUID_EAX, 10, 0x8000001f, 0 },
        { 0, 0, 0, 0, 0 }
  };
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1128,18 -1139,21 +1141,24 @@@ static int svm_set_nested_state(struct 
         * contains saved L1 state.
         */
        copy_vmcb_control_area(&hsave->control, &svm->vmcb->control);
-       hsave->save = save;
+       hsave->save = *save;
  
        svm->nested.vmcb = kvm_state->hdr.svm.vmcb_pa;
-       load_nested_vmcb_control(svm, &ctl);
+       load_nested_vmcb_control(svm, ctl);
        nested_prepare_vmcb_control(svm);
  
 +      if (!nested_svm_vmrun_msrpm(svm))
 +              return -EINVAL;
 +
  out_set_gif:
        svm_set_gif(svm, !!(kvm_state->flags & KVM_STATE_NESTED_GIF_SET));
-       return 0;
+       ret = 0;
+ out_free:
+       kfree(save);
+       kfree(ctl);
+       return ret;
  }
  
  struct kvm_x86_nested_ops svm_nested_ops = {
Simple merge
Simple merge