Merge remote-tracking branch 'tip/x86/cc' into hyperv-next
authorWei Liu <wei.liu@kernel.org>
Thu, 28 Oct 2021 10:45:57 +0000 (10:45 +0000)
committerWei Liu <wei.liu@kernel.org>
Thu, 28 Oct 2021 10:46:03 +0000 (10:46 +0000)
1  2 
arch/x86/Kconfig
arch/x86/kernel/sev.c
arch/x86/mm/mem_encrypt_identity.c

diff --combined arch/x86/Kconfig
@@@ -1405,7 -1405,7 +1405,7 @@@ config HIGHMEM4
  
  config HIGHMEM64G
        bool "64GB"
 -      depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6
 +      depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !MWINCHIP3D && !MK6
        select X86_PAE
        help
          Select this if you have a 32-bit processor and more than 4
@@@ -1518,6 -1518,7 +1518,7 @@@ config AMD_MEM_ENCRYP
        select ARCH_HAS_FORCE_DMA_UNENCRYPTED
        select INSTRUCTION_DECODER
        select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
+       select ARCH_HAS_CC_PLATFORM
        help
          Say yes to enable support for the encryption of system memory.
          This requires an AMD processor that supports Secure Memory
@@@ -2832,6 -2833,8 +2833,6 @@@ config HAVE_ATOMIC_IOMA
        def_bool y
        depends on X86_32
  
 -source "drivers/firmware/Kconfig"
 -
  source "arch/x86/kvm/Kconfig"
  
  source "arch/x86/Kconfig.assembler"
diff --combined arch/x86/kernel/sev.c
@@@ -11,7 -11,7 +11,7 @@@
  
  #include <linux/sched/debug.h>        /* For show_regs() */
  #include <linux/percpu-defs.h>
- #include <linux/mem_encrypt.h>
+ #include <linux/cc_platform.h>
  #include <linux/printk.h>
  #include <linux/mm_types.h>
  #include <linux/set_memory.h>
@@@ -615,7 -615,7 +615,7 @@@ int __init sev_es_efi_map_ghcbs(pgd_t *
        int cpu;
        u64 pfn;
  
-       if (!sev_es_active())
+       if (!cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT))
                return 0;
  
        pflags = _PAGE_NX | _PAGE_RW;
@@@ -648,8 -648,7 +648,8 @@@ static enum es_result vc_handle_msr(str
                ghcb_set_rdx(ghcb, regs->dx);
        }
  
 -      ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_MSR, exit_info_1, 0);
 +      ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_MSR,
 +                                exit_info_1, 0);
  
        if ((ret == ES_OK) && (!exit_info_1)) {
                regs->ax = ghcb->save.rax;
@@@ -775,7 -774,7 +775,7 @@@ void __init sev_es_init_vc_handling(voi
  
        BUILD_BUG_ON(offsetof(struct sev_es_runtime_data, ghcb_page) % PAGE_SIZE);
  
-       if (!sev_es_active())
+       if (!cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT))
                return;
  
        if (!sev_es_check_cpu_features())
@@@ -868,7 -867,7 +868,7 @@@ static enum es_result vc_do_mmio(struc
  
        ghcb_set_sw_scratch(ghcb, ghcb_pa + offsetof(struct ghcb, shared_buffer));
  
 -      return sev_es_ghcb_hv_call(ghcb, ctxt, exit_code, exit_info_1, exit_info_2);
 +      return sev_es_ghcb_hv_call(ghcb, true, ctxt, exit_code, exit_info_1, exit_info_2);
  }
  
  static enum es_result vc_handle_mmio_twobyte_ops(struct ghcb *ghcb,
@@@ -1118,7 -1117,7 +1118,7 @@@ static enum es_result vc_handle_dr7_wri
  
        /* Using a value of 0 for ExitInfo1 means RAX holds the value */
        ghcb_set_rax(ghcb, val);
 -      ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_WRITE_DR7, 0, 0);
 +      ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_WRITE_DR7, 0, 0);
        if (ret != ES_OK)
                return ret;
  
@@@ -1148,7 -1147,7 +1148,7 @@@ static enum es_result vc_handle_dr7_rea
  static enum es_result vc_handle_wbinvd(struct ghcb *ghcb,
                                       struct es_em_ctxt *ctxt)
  {
 -      return sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_WBINVD, 0, 0);
 +      return sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_WBINVD, 0, 0);
  }
  
  static enum es_result vc_handle_rdpmc(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
  
        ghcb_set_rcx(ghcb, ctxt->regs->cx);
  
 -      ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_RDPMC, 0, 0);
 +      ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_RDPMC, 0, 0);
        if (ret != ES_OK)
                return ret;
  
@@@ -1198,7 -1197,7 +1198,7 @@@ static enum es_result vc_handle_vmmcall
        if (x86_platform.hyper.sev_es_hcall_prepare)
                x86_platform.hyper.sev_es_hcall_prepare(ghcb, ctxt->regs);
  
 -      ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_VMMCALL, 0, 0);
 +      ret = sev_es_ghcb_hv_call(ghcb, true, ctxt, SVM_EXIT_VMMCALL, 0, 0);
        if (ret != ES_OK)
                return ret;
  
@@@ -1320,26 -1319,13 +1320,26 @@@ static __always_inline void vc_forward_
        }
  }
  
 -static __always_inline bool on_vc_fallback_stack(struct pt_regs *regs)
 +static __always_inline bool is_vc2_stack(unsigned long sp)
  {
 -      unsigned long sp = (unsigned long)regs;
 -
        return (sp >= __this_cpu_ist_bottom_va(VC2) && sp < __this_cpu_ist_top_va(VC2));
  }
  
 +static __always_inline bool vc_from_invalid_context(struct pt_regs *regs)
 +{
 +      unsigned long sp, prev_sp;
 +
 +      sp      = (unsigned long)regs;
 +      prev_sp = regs->sp;
 +
 +      /*
 +       * If the code was already executing on the VC2 stack when the #VC
 +       * happened, let it proceed to the normal handling routine. This way the
 +       * code executing on the VC2 stack can cause #VC exceptions to get handled.
 +       */
 +      return is_vc2_stack(sp) && !is_vc2_stack(prev_sp);
 +}
 +
  static bool vc_raw_handle_exception(struct pt_regs *regs, unsigned long error_code)
  {
        struct ghcb_state state;
@@@ -1420,7 -1406,7 +1420,7 @@@ DEFINE_IDTENTRY_VC_KERNEL(exc_vmm_commu
         * But keep this here in case the noinstr annotations are violated due
         * to bug elsewhere.
         */
 -      if (unlikely(on_vc_fallback_stack(regs))) {
 +      if (unlikely(vc_from_invalid_context(regs))) {
                instrumentation_begin();
                panic("Can't handle #VC exception from unsupported context\n");
                instrumentation_end();
  #undef CONFIG_PARAVIRT_XXL
  #undef CONFIG_PARAVIRT_SPINLOCKS
  
 +/*
 + * This code runs before CPU feature bits are set. By default, the
 + * pgtable_l5_enabled() function uses bit X86_FEATURE_LA57 to determine if
 + * 5-level paging is active, so that won't work here. USE_EARLY_PGTABLE_L5
 + * is provided to handle this situation and, instead, use a variable that
 + * has been set by the early boot code.
 + */
 +#define USE_EARLY_PGTABLE_L5
 +
  #include <linux/kernel.h>
  #include <linux/mm.h>
  #include <linux/mem_encrypt.h>
+ #include <linux/cc_platform.h>
  
  #include <asm/setup.h>
  #include <asm/sections.h>
@@@ -296,7 -288,13 +297,13 @@@ void __init sme_encrypt_kernel(struct b
        unsigned long pgtable_area_len;
        unsigned long decrypted_base;
  
-       if (!sme_active())
+       /*
+        * This is early code, use an open coded check for SME instead of
+        * using cc_platform_has(). This eliminates worries about removing
+        * instrumentation or checking boot_cpu_data in the cc_platform_has()
+        * function.
+        */
+       if (!sme_get_me_mask() || sev_status & MSR_AMD64_SEV_ENABLED)
                return;
  
        /*