]> Git Repo - linux.git/commitdiff
Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <[email protected]>
Mon, 4 Sep 2017 19:21:28 +0000 (12:21 -0700)
committerLinus Torvalds <[email protected]>
Mon, 4 Sep 2017 19:21:28 +0000 (12:21 -0700)
Pull x86 mm changes from Ingo Molnar:
 "PCID support, 5-level paging support, Secure Memory Encryption support

  The main changes in this cycle are support for three new, complex
  hardware features of x86 CPUs:

   - Add 5-level paging support, which is a new hardware feature on
     upcoming Intel CPUs allowing up to 128 PB of virtual address space
     and 4 PB of physical RAM space - a 512-fold increase over the old
     limits. (Supercomputers of the future forecasting hurricanes on an
     ever warming planet can certainly make good use of more RAM.)

     Many of the necessary changes went upstream in previous cycles,
     v4.14 is the first kernel that can enable 5-level paging.

     This feature is activated via CONFIG_X86_5LEVEL=y - disabled by
     default.

     (By Kirill A. Shutemov)

   - Add 'encrypted memory' support, which is a new hardware feature on
     upcoming AMD CPUs ('Secure Memory Encryption', SME) allowing system
     RAM to be encrypted and decrypted (mostly) transparently by the
     CPU, with a little help from the kernel to transition to/from
     encrypted RAM. Such RAM should be more secure against various
     attacks like RAM access via the memory bus and should make the
     radio signature of memory bus traffic harder to intercept (and
     decrypt) as well.

     This feature is activated via CONFIG_AMD_MEM_ENCRYPT=y - disabled
     by default.

     (By Tom Lendacky)

   - Enable PCID optimized TLB flushing on newer Intel CPUs: PCID is a
     hardware feature that attaches an address space tag to TLB entries
     and thus allows to skip TLB flushing in many cases, even if we
     switch mm's.

     (By Andy Lutomirski)

  All three of these features were in the works for a long time, and
  it's coincidence of the three independent development paths that they
  are all enabled in v4.14 at once"

* 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (65 commits)
  x86/mm: Enable RCU based page table freeing (CONFIG_HAVE_RCU_TABLE_FREE=y)
  x86/mm: Use pr_cont() in dump_pagetable()
  x86/mm: Fix SME encryption stack ptr handling
  kvm/x86: Avoid clearing the C-bit in rsvd_bits()
  x86/CPU: Align CR3 defines
  x86/mm, mm/hwpoison: Clear PRESENT bit for kernel 1:1 mappings of poison pages
  acpi, x86/mm: Remove encryption mask from ACPI page protection type
  x86/mm, kexec: Fix memory corruption with SME on successive kexecs
  x86/mm/pkeys: Fix typo in Documentation/x86/protection-keys.txt
  x86/mm/dump_pagetables: Speed up page tables dump for CONFIG_KASAN=y
  x86/mm: Implement PCID based optimization: try to preserve old TLB entries using PCID
  x86: Enable 5-level paging support via CONFIG_X86_5LEVEL=y
  x86/mm: Allow userspace have mappings above 47-bit
  x86/mm: Prepare to expose larger address space to userspace
  x86/mpx: Do not allow MPX if we have mappings above 47-bit
  x86/mm: Rename tasksize_32bit/64bit to task_size_32bit/64bit()
  x86/xen: Redefine XEN_ELFNOTE_INIT_P2M using PUD_SIZE * PTRS_PER_PUD
  x86/mm/dump_pagetables: Fix printout of p4d level
  x86/mm/dump_pagetables: Generalize address normalization
  x86/boot: Fix memremap() related build failure
  ...

23 files changed:
1  2 
Documentation/admin-guide/kernel-parameters.txt
arch/x86/Kconfig
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/elf.h
arch/x86/include/asm/io.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/mmu_context.h
arch/x86/include/asm/processor.h
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/setup.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/xen/enlighten_pv.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_vm.c
drivers/gpu/drm/ttm/ttm_bo_vm.c
drivers/gpu/drm/udl/udl_fb.c
drivers/iommu/amd_iommu_types.h
include/linux/compiler-gcc.h
include/linux/compiler.h
include/linux/efi.h
init/main.c

index 3a99cc96b6b15414509c6ad92511dfbd9f4047f6,372cc66bba23286c485abd8aa178abe2f3119fe7..dad6fa01af9589d954b87ecbab7033f2bbef5dd5
                        memory contents and reserves bad memory
                        regions that are detected.
  
+       mem_encrypt=    [X86-64] AMD Secure Memory Encryption (SME) control
+                       Valid arguments: on, off
+                       Default (depends on kernel configuration option):
+                         on  (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=y)
+                         off (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=n)
+                       mem_encrypt=on:         Activate SME
+                       mem_encrypt=off:        Do not activate SME
+                       Refer to Documentation/x86/amd-memory-encryption.txt
+                       for details on when memory encryption can be activated.
        mem_sleep_default=      [SUSPEND] Default system suspend mode:
                        s2idle  - Suspend-To-Idle
                        shallow - Power-On Suspend or equivalent (if supported)
                        In kernels built with CONFIG_NO_HZ_FULL=y, set
                        the specified list of CPUs whose tick will be stopped
                        whenever possible. The boot CPU will be forced outside
 -                      the range to maintain the timekeeping.
 -                      The CPUs in this range must also be included in the
 -                      rcu_nocbs= set.
 +                      the range to maintain the timekeeping.  Any CPUs
 +                      in this list will have their RCU callbacks offloaded,
 +                      just as if they had also been called out in the
 +                      rcu_nocbs= boot parameter.
  
        noiotrap        [SH] Disables trapped I/O port accesses.
  
        nopat           [X86] Disable PAT (page attribute table extension of
                        pagetables) support.
  
+       nopcid          [X86-64] Disable the PCID cpu feature.
        norandmaps      Don't use address space randomization.  Equivalent to
                        echo 0 > /proc/sys/kernel/randomize_va_space
  
diff --combined arch/x86/Kconfig
index cce15191e9e982e768da8ec52350c08c83ad6c93,87e447286c377f730c3d94ed267e136b741b01e9..b4b27ab016f682d9cca9c07529b4777fb34d1079
@@@ -55,8 -55,6 +55,8 @@@ config X8
        select ARCH_HAS_KCOV                    if X86_64
        select ARCH_HAS_MMIO_FLUSH
        select ARCH_HAS_PMEM_API                if X86_64
 +      # Causing hangs/crashes, see the commit that added this change for details.
 +      select ARCH_HAS_REFCOUNT                if BROKEN
        select ARCH_HAS_UACCESS_FLUSHCACHE      if X86_64
        select ARCH_HAS_SET_MEMORY
        select ARCH_HAS_SG_CHAIN
@@@ -75,6 -73,7 +75,6 @@@
        select ARCH_USE_QUEUED_RWLOCKS
        select ARCH_USE_QUEUED_SPINLOCKS
        select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
 -      select ARCH_WANT_FRAME_POINTERS
        select ARCH_WANTS_DYNAMIC_TASK_STRUCT
        select ARCH_WANTS_THP_SWAP              if X86_64
        select BUILDTIME_EXTABLE_SORT
        select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_MIXED_BREAKPOINTS_REGS
 +      select HAVE_MOD_ARCH_SPECIFIC
        select HAVE_NMI
        select HAVE_OPROFILE
        select HAVE_OPTPROBES
        select HAVE_HARDLOCKUP_DETECTOR_PERF    if PERF_EVENTS && HAVE_PERF_EVENTS_NMI
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
+       select HAVE_RCU_TABLE_FREE
        select HAVE_REGS_AND_STACK_ACCESS_API
 -      select HAVE_RELIABLE_STACKTRACE         if X86_64 && FRAME_POINTER && STACK_VALIDATION
 +      select HAVE_RELIABLE_STACKTRACE         if X86_64 && FRAME_POINTER_UNWINDER && STACK_VALIDATION
        select HAVE_STACK_VALIDATION            if X86_64
        select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_UNSTABLE_SCHED_CLOCK
@@@ -329,6 -328,7 +330,7 @@@ config FIX_EARLYCON_ME
  
  config PGTABLE_LEVELS
        int
+       default 5 if X86_5LEVEL
        default 4 if X86_64
        default 3 if X86_PAE
        default 2
@@@ -780,6 -780,8 +782,6 @@@ config KVM_DEBUG_F
          Statistics are displayed in debugfs filesystem. Enabling this option
          may incur significant overhead.
  
 -source "arch/x86/lguest/Kconfig"
 -
  config PARAVIRT_TIME_ACCOUNTING
        bool "Paravirtual steal time accounting"
        depends on PARAVIRT
@@@ -1399,6 -1401,24 +1401,24 @@@ config X86_PA
          has the cost of more pagetable lookup overhead, and also
          consumes more pagetable space per process.
  
+ config X86_5LEVEL
+       bool "Enable 5-level page tables support"
+       depends on X86_64
+       ---help---
+         5-level paging enables access to larger address space:
+         upto 128 PiB of virtual address space and 4 PiB of
+         physical address space.
+         It will be supported by future Intel CPUs.
+         Note: a kernel with this option enabled can only be booted
+         on machines that support the feature.
+         See Documentation/x86/x86_64/5level-paging.txt for more
+         information.
+         Say N if unsure.
  config ARCH_PHYS_ADDR_T_64BIT
        def_bool y
        depends on X86_64 || X86_PAE
@@@ -1416,6 -1436,35 +1436,35 @@@ config X86_DIRECT_GBPAGE
          supports them), so don't confuse the user by printing
          that we have them enabled.
  
+ config ARCH_HAS_MEM_ENCRYPT
+       def_bool y
+ config AMD_MEM_ENCRYPT
+       bool "AMD Secure Memory Encryption (SME) support"
+       depends on X86_64 && CPU_SUP_AMD
+       ---help---
+         Say yes to enable support for the encryption of system memory.
+         This requires an AMD processor that supports Secure Memory
+         Encryption (SME).
+ config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT
+       bool "Activate AMD Secure Memory Encryption (SME) by default"
+       default y
+       depends on AMD_MEM_ENCRYPT
+       ---help---
+         Say yes to have system memory encrypted by default if running on
+         an AMD processor that supports Secure Memory Encryption (SME).
+         If set to Y, then the encryption of system memory can be
+         deactivated with the mem_encrypt=off command line option.
+         If set to N, then the encryption of system memory can be
+         activated with the mem_encrypt=on command line option.
+ config ARCH_USE_MEMREMAP_PROT
+       def_bool y
+       depends on AMD_MEM_ENCRYPT
  # Common NUMA Features
  config NUMA
        bool "Numa Memory Allocation and Scheduler Support"
index 8ea315a11fe0d4461abe7aeea2738be97a79b189,66ac08607471c4a6fcdfb919304f2fd3405458ef..42bbbf0f173d06f1658dc1122e93e25987b8d5f9
  #define X86_FEATURE_PERFCTR_NB  ( 6*32+24) /* NB performance counter extensions */
  #define X86_FEATURE_BPEXT     (6*32+26) /* data breakpoint extension */
  #define X86_FEATURE_PTSC      ( 6*32+27) /* performance time-stamp counter */
 -#define X86_FEATURE_PERFCTR_L2        ( 6*32+28) /* L2 performance counter extensions */
 +#define X86_FEATURE_PERFCTR_LLC       ( 6*32+28) /* Last Level Cache performance counter extensions */
  #define X86_FEATURE_MWAITX    ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */
  
  /*
  
  #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
  #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
+ #define X86_FEATURE_SME               ( 7*32+10) /* AMD Secure Memory Encryption */
  
  #define X86_FEATURE_INTEL_PPIN        ( 7*32+14) /* Intel Processor Inventory Number */
  #define X86_FEATURE_INTEL_PT  ( 7*32+15) /* Intel Processor Trace */
index bda9f94bcb10388edbe7c0054e685c257b31d1dd,a3de31ffb72254199d769afd9266997f563c67d5..04330c8d9af99d61c774ee166a9c0073fd99e536
@@@ -126,15 -126,15 +126,15 @@@ do {                                            
        pr_reg[4] = regs->di;                   \
        pr_reg[5] = regs->bp;                   \
        pr_reg[6] = regs->ax;                   \
 -      pr_reg[7] = regs->ds & 0xffff;          \
 -      pr_reg[8] = regs->es & 0xffff;          \
 -      pr_reg[9] = regs->fs & 0xffff;          \
 +      pr_reg[7] = regs->ds;                   \
 +      pr_reg[8] = regs->es;                   \
 +      pr_reg[9] = regs->fs;                   \
        pr_reg[11] = regs->orig_ax;             \
        pr_reg[12] = regs->ip;                  \
 -      pr_reg[13] = regs->cs & 0xffff;         \
 +      pr_reg[13] = regs->cs;                  \
        pr_reg[14] = regs->flags;               \
        pr_reg[15] = regs->sp;                  \
 -      pr_reg[16] = regs->ss & 0xffff;         \
 +      pr_reg[16] = regs->ss;                  \
  } while (0);
  
  #define ELF_CORE_COPY_REGS(pr_reg, regs)      \
@@@ -204,7 -204,6 +204,7 @@@ void set_personality_ia32(bool)
  
  #define ELF_CORE_COPY_REGS(pr_reg, regs)                      \
  do {                                                          \
 +      unsigned long base;                                     \
        unsigned v;                                             \
        (pr_reg)[0] = (regs)->r15;                              \
        (pr_reg)[1] = (regs)->r14;                              \
        (pr_reg)[18] = (regs)->flags;                           \
        (pr_reg)[19] = (regs)->sp;                              \
        (pr_reg)[20] = (regs)->ss;                              \
 -      (pr_reg)[21] = current->thread.fsbase;                  \
 -      (pr_reg)[22] = current->thread.gsbase;                  \
 +      rdmsrl(MSR_FS_BASE, base); (pr_reg)[21] = base;         \
 +      rdmsrl(MSR_KERNEL_GS_BASE, base); (pr_reg)[22] = base;  \
        asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v;       \
        asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v;       \
        asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v;       \
@@@ -305,8 -304,8 +305,8 @@@ static inline int mmap_is_ia32(void
                test_thread_flag(TIF_ADDR32));
  }
  
- extern unsigned long tasksize_32bit(void);
- extern unsigned long tasksize_64bit(void);
+ extern unsigned long task_size_32bit(void);
+ extern unsigned long task_size_64bit(int full_addr_space);
  extern unsigned long get_mmap_base(int is_legacy);
  
  #ifdef CONFIG_X86_32
index 1310e1f1cd65c90dc8a5ff3a860922a8efcc5efc,4bc6f459a8b6dd9861f078c794d6c26534db5148..c40a95c33bb8434c8b41641e57c38a79eeddb7ad
@@@ -69,9 -69,6 +69,9 @@@ build_mmio_write(__writeb, "b", unsigne
  build_mmio_write(__writew, "w", unsigned short, "r", )
  build_mmio_write(__writel, "l", unsigned int, "r", )
  
 +#define readb readb
 +#define readw readw
 +#define readl readl
  #define readb_relaxed(a) __readb(a)
  #define readw_relaxed(a) __readw(a)
  #define readl_relaxed(a) __readl(a)
@@@ -79,9 -76,6 +79,9 @@@
  #define __raw_readw __readw
  #define __raw_readl __readl
  
 +#define writeb writeb
 +#define writew writew
 +#define writel writel
  #define writeb_relaxed(v, a) __writeb(v, a)
  #define writew_relaxed(v, a) __writew(v, a)
  #define writel_relaxed(v, a) __writel(v, a)
  #ifdef CONFIG_X86_64
  
  build_mmio_read(readq, "q", unsigned long, "=r", :"memory")
 +build_mmio_read(__readq, "q", unsigned long, "=r", )
  build_mmio_write(writeq, "q", unsigned long, "r", :"memory")
 +build_mmio_write(__writeq, "q", unsigned long, "r", )
  
 -#define readq_relaxed(a)      readq(a)
 -#define writeq_relaxed(v, a)  writeq(v, a)
 +#define readq_relaxed(a)      __readq(a)
 +#define writeq_relaxed(v, a)  __writeq(v, a)
  
 -#define __raw_readq(a)                readq(a)
 -#define __raw_writeq(val, addr)       writeq(val, addr)
 +#define __raw_readq           __readq
 +#define __raw_writeq          __writeq
  
  /* Let people know that we have them */
  #define readq                 readq
@@@ -127,7 -119,6 +127,7 @@@ static inline phys_addr_t virt_to_phys(
  {
        return __pa(address);
  }
 +#define virt_to_phys virt_to_phys
  
  /**
   *    phys_to_virt    -       map physical address to virtual
@@@ -146,7 -137,6 +146,7 @@@ static inline void *phys_to_virt(phys_a
  {
        return __va(address);
  }
 +#define phys_to_virt phys_to_virt
  
  /*
   * Change "struct page" to physical address.
@@@ -179,14 -169,11 +179,14 @@@ static inline unsigned int isa_virt_to_
   * else, you probably want one of the following.
   */
  extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
 +#define ioremap_nocache ioremap_nocache
  extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size);
  #define ioremap_uc ioremap_uc
  
  extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
 +#define ioremap_cache ioremap_cache
  extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val);
 +#define ioremap_prot ioremap_prot
  
  /**
   * ioremap     -   map bus memory into CPU space
@@@ -206,10 -193,8 +206,10 @@@ static inline void __iomem *ioremap(res
  {
        return ioremap_nocache(offset, size);
  }
 +#define ioremap ioremap
  
  extern void iounmap(volatile void __iomem *addr);
 +#define iounmap iounmap
  
  extern void set_iounmap_nonlazy(void);
  
  
  #include <asm-generic/iomap.h>
  
 -/*
 - * Convert a virtual cached pointer to an uncached pointer
 - */
 -#define xlate_dev_kmem_ptr(p) p
 -
 -/**
 - * memset_io  Set a range of I/O memory to a constant value
 - * @addr:     The beginning of the I/O-memory range to set
 - * @val:      The value to set the memory to
 - * @count:    The number of bytes to set
 - *
 - * Set a range of I/O memory to a given value.
 - */
 -static inline void
 -memset_io(volatile void __iomem *addr, unsigned char val, size_t count)
 -{
 -      memset((void __force *)addr, val, count);
 -}
 -
 -/**
 - * memcpy_fromio      Copy a block of data from I/O memory
 - * @dst:              The (RAM) destination for the copy
 - * @src:              The (I/O memory) source for the data
 - * @count:            The number of bytes to copy
 - *
 - * Copy a block of data from I/O memory.
 - */
 -static inline void
 -memcpy_fromio(void *dst, const volatile void __iomem *src, size_t count)
 -{
 -      memcpy(dst, (const void __force *)src, count);
 -}
 -
 -/**
 - * memcpy_toio                Copy a block of data into I/O memory
 - * @dst:              The (I/O memory) destination for the copy
 - * @src:              The (RAM) source for the data
 - * @count:            The number of bytes to copy
 - *
 - * Copy a block of data to I/O memory.
 - */
 -static inline void
 -memcpy_toio(volatile void __iomem *dst, const void *src, size_t count)
 -{
 -      memcpy((void __force *)dst, src, count);
 -}
 -
  /*
   * ISA space is 'always mapped' on a typical x86 system, no need to
   * explicitly ioremap() it. The fact that the ISA IO space is mapped
@@@ -309,38 -341,13 +309,38 @@@ BUILDIO(b, b, char
  BUILDIO(w, w, short)
  BUILDIO(l, , int)
  
 +#define inb inb
 +#define inw inw
 +#define inl inl
 +#define inb_p inb_p
 +#define inw_p inw_p
 +#define inl_p inl_p
 +#define insb insb
 +#define insw insw
 +#define insl insl
 +
 +#define outb outb
 +#define outw outw
 +#define outl outl
 +#define outb_p outb_p
 +#define outw_p outw_p
 +#define outl_p outl_p
 +#define outsb outsb
 +#define outsw outsw
 +#define outsl outsl
 +
  extern void *xlate_dev_mem_ptr(phys_addr_t phys);
  extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
  
 +#define xlate_dev_mem_ptr xlate_dev_mem_ptr
 +#define unxlate_dev_mem_ptr unxlate_dev_mem_ptr
 +
  extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
                                enum page_cache_mode pcm);
  extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size);
 +#define ioremap_wc ioremap_wc
  extern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size);
 +#define ioremap_wt ioremap_wt
  
  extern bool is_early_ioremap_ptep(pte_t *ptep);
  
@@@ -358,9 -365,6 +358,9 @@@ extern bool xen_biovec_phys_mergeable(c
  
  #define IO_SPACE_LIMIT 0xffff
  
 +#include <asm-generic/io.h>
 +#undef PCI_IOBASE
 +
  #ifdef CONFIG_MTRR
  extern int __must_check arch_phys_wc_index(int handle);
  #define arch_phys_wc_index arch_phys_wc_index
@@@ -377,4 -381,12 +377,12 @@@ extern void arch_io_free_memtype_wc(res
  #define arch_io_reserve_memtype_wc arch_io_reserve_memtype_wc
  #endif
  
+ extern bool arch_memremap_can_ram_remap(resource_size_t offset,
+                                       unsigned long size,
+                                       unsigned long flags);
+ #define arch_memremap_can_ram_remap arch_memremap_can_ram_remap
+ extern bool phys_mem_access_encrypted(unsigned long phys_addr,
+                                     unsigned long size);
  #endif /* _ASM_X86_IO_H */
index 92c9032502d87b3291268f2c98b04ec4cb59854d,7cbaab523f22dcd91812dc269021d1e884ec0df2..369e41c23f0719895a205e1707aca04d3a4cda03
@@@ -492,7 -492,6 +492,7 @@@ struct kvm_vcpu_arch 
        unsigned long cr4;
        unsigned long cr4_guest_owned_bits;
        unsigned long cr8;
 +      u32 pkru;
        u32 hflags;
        u64 efer;
        u64 apic_base;
@@@ -1079,7 -1078,7 +1079,7 @@@ void kvm_mmu_init_vm(struct kvm *kvm)
  void kvm_mmu_uninit_vm(struct kvm *kvm);
  void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
                u64 dirty_mask, u64 nx_mask, u64 x_mask, u64 p_mask,
-               u64 acc_track_mask);
+               u64 acc_track_mask, u64 me_mask);
  
  void kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
  void kvm_mmu_slot_remove_write_access(struct kvm *kvm,
@@@ -1375,6 -1374,8 +1375,6 @@@ int kvm_arch_interrupt_allowed(struct k
  int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
  void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event);
  void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu);
 -void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
 -                                         unsigned long address);
  
  void kvm_define_shared_msr(unsigned index, u32 msr);
  int kvm_set_shared_msr(unsigned index, u64 val, u64 mask);
index 7a234be7e29846618cbdafb0153705cb8a8566b3,d25d9f4abb15a1e06e83e6e4ebac1ef9f2c70c04..7ae318c340d9b5d0fca2697dbb7e977b0bda3892
@@@ -12,6 -12,9 +12,9 @@@
  #include <asm/tlbflush.h>
  #include <asm/paravirt.h>
  #include <asm/mpx.h>
+ extern atomic64_t last_mm_ctx_id;
  #ifndef CONFIG_PARAVIRT
  static inline void paravirt_activate_mm(struct mm_struct *prev,
                                        struct mm_struct *next)
@@@ -125,13 -128,18 +128,18 @@@ static inline void switch_ldt(struct mm
  
  static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
  {
-       if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
-               this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
+       int cpu = smp_processor_id();
+       if (cpumask_test_cpu(cpu, mm_cpumask(mm)))
+               cpumask_clear_cpu(cpu, mm_cpumask(mm));
  }
  
  static inline int init_new_context(struct task_struct *tsk,
                                   struct mm_struct *mm)
  {
+       mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id);
+       atomic64_set(&mm->context.tlb_gen, 0);
        #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
        if (cpu_feature_enabled(X86_FEATURE_OSPKE)) {
                /* pkey 0 is the default and always allocated */
                mm->context.execute_only_pkey = -1;
        }
        #endif
 -      init_new_context_ldt(tsk, mm);
 -
 -      return 0;
 +      return init_new_context_ldt(tsk, mm);
  }
  static inline void destroy_context(struct mm_struct *mm)
  {
@@@ -290,6 -300,9 +298,9 @@@ static inline unsigned long __get_curre
  {
        unsigned long cr3 = __pa(this_cpu_read(cpu_tlbstate.loaded_mm)->pgd);
  
+       if (static_cpu_has(X86_FEATURE_PCID))
+               cr3 |= this_cpu_read(cpu_tlbstate.loaded_mm_asid);
        /* For now, be very restrictive about when this can be called. */
        VM_WARN_ON(in_nmi() || preemptible());
  
index abc99b9c7ffdc3f84811481d8ca4467e7085f3e9,c61bab07a84e05a0a21afc9e166db6e37fa15442..3fa26a61eabcef0dc95b19221ca5e76a6ba2a01a
@@@ -22,7 -22,6 +22,7 @@@ struct vm86
  #include <asm/nops.h>
  #include <asm/special_insns.h>
  #include <asm/fpu/types.h>
 +#include <asm/unwind_hints.h>
  
  #include <linux/personality.h>
  #include <linux/cache.h>
@@@ -30,6 -29,7 +30,7 @@@
  #include <linux/math64.h>
  #include <linux/err.h>
  #include <linux/irqflags.h>
+ #include <linux/mem_encrypt.h>
  
  /*
   * We handle most unaligned accesses in hardware.  On the other hand
@@@ -240,9 -240,14 +241,14 @@@ static inline unsigned long read_cr3_pa
        return __read_cr3() & CR3_ADDR_MASK;
  }
  
+ static inline unsigned long native_read_cr3_pa(void)
+ {
+       return __native_read_cr3() & CR3_ADDR_MASK;
+ }
  static inline void load_cr3(pgd_t *pgdir)
  {
-       write_cr3(__pa(pgdir));
+       write_cr3(__sme_pa(pgdir));
  }
  
  #ifdef CONFIG_X86_32
@@@ -662,7 -667,7 +668,7 @@@ static inline void sync_core(void
         * In case NMI unmasking or performance ever becomes a problem,
         * the next best option appears to be MOV-to-CR2 and an
         * unconditional jump.  That sequence also works on all CPUs,
 -       * but it will fault at CPL3 (i.e. Xen PV and lguest).
 +       * but it will fault at CPL3 (i.e. Xen PV).
         *
         * CPUID is the conventional way, but it's nasty: it doesn't
         * exist on some 486-like CPUs, and it usually exits to a
        unsigned int tmp;
  
        asm volatile (
 +              UNWIND_HINT_SAVE
                "mov %%ss, %0\n\t"
                "pushq %q0\n\t"
                "pushq %%rsp\n\t"
                "pushq %q0\n\t"
                "pushq $1f\n\t"
                "iretq\n\t"
 +              UNWIND_HINT_RESTORE
                "1:"
                : "=&r" (tmp), "+r" (__sp) : : "cc", "memory");
  #endif
@@@ -805,7 -808,9 +811,9 @@@ static inline void spin_lock_prefetch(c
   */
  #define IA32_PAGE_OFFSET      PAGE_OFFSET
  #define TASK_SIZE             PAGE_OFFSET
+ #define TASK_SIZE_LOW         TASK_SIZE
  #define TASK_SIZE_MAX         TASK_SIZE
+ #define DEFAULT_MAP_WINDOW    TASK_SIZE
  #define STACK_TOP             TASK_SIZE
  #define STACK_TOP_MAX         STACK_TOP
  
   * particular problem by preventing anything from being mapped
   * at the maximum canonical address.
   */
- #define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)
+ #define TASK_SIZE_MAX ((1UL << __VIRTUAL_MASK_SHIFT) - PAGE_SIZE)
+ #define DEFAULT_MAP_WINDOW    ((1UL << 47) - PAGE_SIZE)
  
  /* This decides where the kernel will search for a free chunk of vm
   * space during mmap's.
  #define IA32_PAGE_OFFSET      ((current->personality & ADDR_LIMIT_3GB) ? \
                                        0xc0000000 : 0xFFFFe000)
  
+ #define TASK_SIZE_LOW         (test_thread_flag(TIF_ADDR32) ? \
+                                       IA32_PAGE_OFFSET : DEFAULT_MAP_WINDOW)
  #define TASK_SIZE             (test_thread_flag(TIF_ADDR32) ? \
                                        IA32_PAGE_OFFSET : TASK_SIZE_MAX)
  #define TASK_SIZE_OF(child)   ((test_tsk_thread_flag(child, TIF_ADDR32)) ? \
                                        IA32_PAGE_OFFSET : TASK_SIZE_MAX)
  
- #define STACK_TOP             TASK_SIZE
+ #define STACK_TOP             TASK_SIZE_LOW
  #define STACK_TOP_MAX         TASK_SIZE_MAX
  
  #define INIT_THREAD  {                                                \
@@@ -879,7 -888,7 +891,7 @@@ extern void start_thread(struct pt_reg
   * space during mmap's.
   */
  #define __TASK_UNMAPPED_BASE(task_size)       (PAGE_ALIGN(task_size / 3))
- #define TASK_UNMAPPED_BASE            __TASK_UNMAPPED_BASE(TASK_SIZE)
+ #define TASK_UNMAPPED_BASE            __TASK_UNMAPPED_BASE(TASK_SIZE_LOW)
  
  #define KSTK_EIP(task)                (task_pt_regs(task)->ip)
  
index e44338dd62dd8fe26707ce39b98223fdbf2fa1c2,110ca5d2bb872a7f15cffe4349ffab74b03a4c86..9862e2cd6d93da331052f664f49fd4ce1edb8d6b
@@@ -297,29 -297,13 +297,29 @@@ static int nearby_node(int apicid
  }
  #endif
  
 +#ifdef CONFIG_SMP
 +/*
 + * Fix up cpu_core_id for pre-F17h systems to be in the
 + * [0 .. cores_per_node - 1] range. Not really needed but
 + * kept so as not to break existing setups.
 + */
 +static void legacy_fixup_core_id(struct cpuinfo_x86 *c)
 +{
 +      u32 cus_per_node;
 +
 +      if (c->x86 >= 0x17)
 +              return;
 +
 +      cus_per_node = c->x86_max_cores / nodes_per_socket;
 +      c->cpu_core_id %= cus_per_node;
 +}
 +
  /*
   * Fixup core topology information for
   * (1) AMD multi-node processors
   *     Assumption: Number of cores in each internal node is the same.
   * (2) AMD processors supporting compute units
   */
 -#ifdef CONFIG_SMP
  static void amd_get_topology(struct cpuinfo_x86 *c)
  {
        u8 node_id;
        } else
                return;
  
 -      /* fixup multi-node processor information */
        if (nodes_per_socket > 1) {
 -              u32 cus_per_node;
 -
                set_cpu_cap(c, X86_FEATURE_AMD_DCM);
 -              cus_per_node = c->x86_max_cores / nodes_per_socket;
 -
 -              /* core id has to be in the [0 .. cores_per_node - 1] range */
 -              c->cpu_core_id %= cus_per_node;
 +              legacy_fixup_core_id(c);
        }
  }
  #endif
@@@ -558,8 -548,12 +558,12 @@@ static void bsp_init_amd(struct cpuinfo
  
  static void early_init_amd(struct cpuinfo_x86 *c)
  {
+       u32 dummy;
        early_init_amd_mc(c);
  
+       rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
        /*
         * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate
         * with P/T states and does not stop in deep C-states
         */
        if (cpu_has_amd_erratum(c, amd_erratum_400))
                set_cpu_bug(c, X86_BUG_AMD_E400);
+       /*
+        * BIOS support is required for SME. If BIOS has enabled SME then
+        * adjust x86_phys_bits by the SME physical address space reduction
+        * value. If BIOS has not enabled SME then don't advertise the
+        * feature (set in scattered.c). Also, since the SME support requires
+        * long mode, don't advertise the feature under CONFIG_X86_32.
+        */
+       if (cpu_has(c, X86_FEATURE_SME)) {
+               u64 msr;
+               /* Check if SME is enabled */
+               rdmsrl(MSR_K8_SYSCFG, msr);
+               if (msr & MSR_K8_SYSCFG_MEM_ENCRYPT) {
+                       c->x86_phys_bits -= (cpuid_ebx(0x8000001f) >> 6) & 0x3f;
+                       if (IS_ENABLED(CONFIG_X86_32))
+                               clear_cpu_cap(c, X86_FEATURE_SME);
+               } else {
+                       clear_cpu_cap(c, X86_FEATURE_SME);
+               }
+       }
  }
  
  static void init_amd_k8(struct cpuinfo_x86 *c)
@@@ -740,8 -755,6 +765,6 @@@ static void init_amd_bd(struct cpuinfo_
  
  static void init_amd(struct cpuinfo_x86 *c)
  {
-       u32 dummy;
        early_init_amd(c);
  
        /*
        if (c->x86 > 0x11)
                set_cpu_cap(c, X86_FEATURE_ARAT);
  
-       rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
        /* 3DNow or LM implies PREFETCHW */
        if (!cpu_has(c, X86_FEATURE_3DNOWPREFETCH))
                if (cpu_has(c, X86_FEATURE_3DNOW) || cpu_has(c, X86_FEATURE_LM))
diff --combined arch/x86/kernel/setup.c
index ecab32282f0f4ac606c415a8d2ef99f8a3345f04,0bfe0c1628f638a0ae7b1ab69e9414485fbae147..022ebddb3734e6cdf528f47393c62195b29a0834
@@@ -69,6 -69,7 +69,7 @@@
  #include <linux/crash_dump.h>
  #include <linux/tboot.h>
  #include <linux/jiffies.h>
+ #include <linux/mem_encrypt.h>
  
  #include <linux/usb/xhci-dbgp.h>
  #include <video/edid.h>
  #include <asm/microcode.h>
  #include <asm/mmu_context.h>
  #include <asm/kaslr.h>
 +#include <asm/unwind.h>
  
  /*
   * max_low_pfn_mapped: highest direct mapped pfn under 4GB
@@@ -375,6 -375,14 +376,14 @@@ static void __init reserve_initrd(void
            !ramdisk_image || !ramdisk_size)
                return;         /* No initrd provided by bootloader */
  
+       /*
+        * If SME is active, this memory will be marked encrypted by the
+        * kernel when it is accessed (including relocation). However, the
+        * ramdisk image was loaded decrypted by the bootloader, so make
+        * sure that it is encrypted before accessing it.
+        */
+       sme_early_encrypt(ramdisk_image, ramdisk_end - ramdisk_image);
        initrd_start = 0;
  
        mapped_size = memblock_mem_size(max_pfn_mapped);
@@@ -1311,8 -1319,6 +1320,8 @@@ void __init setup_arch(char **cmdline_p
        if (efi_enabled(EFI_BOOT))
                efi_apply_memmap_quirks();
  #endif
 +
 +      unwind_init();
  }
  
  #ifdef CONFIG_X86_32
diff --combined arch/x86/kvm/svm.c
index af256b786a70cccd14906fe926e2b790156967a4,099ff08b4aff9c7ca4a1ea0a3a14a02c3891f506..8dbd8dbc83eb8b0ccc8fc2f6f7d9662bcc8e600d
@@@ -1167,9 -1167,9 +1167,9 @@@ static void avic_init_vmcb(struct vcpu_
  {
        struct vmcb *vmcb = svm->vmcb;
        struct kvm_arch *vm_data = &svm->vcpu.kvm->arch;
-       phys_addr_t bpa = page_to_phys(svm->avic_backing_page);
-       phys_addr_t lpa = page_to_phys(vm_data->avic_logical_id_table_page);
-       phys_addr_t ppa = page_to_phys(vm_data->avic_physical_id_table_page);
+       phys_addr_t bpa = __sme_set(page_to_phys(svm->avic_backing_page));
+       phys_addr_t lpa = __sme_set(page_to_phys(vm_data->avic_logical_id_table_page));
+       phys_addr_t ppa = __sme_set(page_to_phys(vm_data->avic_physical_id_table_page));
  
        vmcb->control.avic_backing_page = bpa & AVIC_HPA_MASK;
        vmcb->control.avic_logical_id = lpa & AVIC_HPA_MASK;
@@@ -1232,8 -1232,8 +1232,8 @@@ static void init_vmcb(struct vcpu_svm *
                set_intercept(svm, INTERCEPT_MWAIT);
        }
  
-       control->iopm_base_pa = iopm_base;
-       control->msrpm_base_pa = __pa(svm->msrpm);
+       control->iopm_base_pa = __sme_set(iopm_base);
+       control->msrpm_base_pa = __sme_set(__pa(svm->msrpm));
        control->int_ctl = V_INTR_MASKING_MASK;
  
        init_seg(&save->es);
@@@ -1377,9 -1377,9 +1377,9 @@@ static int avic_init_backing_page(struc
                return -EINVAL;
  
        new_entry = READ_ONCE(*entry);
-       new_entry = (page_to_phys(svm->avic_backing_page) &
-                    AVIC_PHYSICAL_ID_ENTRY_BACKING_PAGE_MASK) |
-                    AVIC_PHYSICAL_ID_ENTRY_VALID_MASK;
+       new_entry = __sme_set((page_to_phys(svm->avic_backing_page) &
+                             AVIC_PHYSICAL_ID_ENTRY_BACKING_PAGE_MASK) |
+                             AVIC_PHYSICAL_ID_ENTRY_VALID_MASK);
        WRITE_ONCE(*entry, new_entry);
  
        svm->avic_physical_id_cache = entry;
@@@ -1647,7 -1647,7 +1647,7 @@@ static struct kvm_vcpu *svm_create_vcpu
  
        svm->vmcb = page_address(page);
        clear_page(svm->vmcb);
-       svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
+       svm->vmcb_pa = __sme_set(page_to_pfn(page) << PAGE_SHIFT);
        svm->asid_generation = 0;
        init_vmcb(svm);
  
@@@ -1675,7 -1675,7 +1675,7 @@@ static void svm_free_vcpu(struct kvm_vc
  {
        struct vcpu_svm *svm = to_svm(vcpu);
  
-       __free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT));
+       __free_page(pfn_to_page(__sme_clr(svm->vmcb_pa) >> PAGE_SHIFT));
        __free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER);
        __free_page(virt_to_page(svm->nested.hsave));
        __free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER);
@@@ -1777,6 -1777,11 +1777,6 @@@ static void svm_set_rflags(struct kvm_v
        to_svm(vcpu)->vmcb->save.rflags = rflags;
  }
  
 -static u32 svm_get_pkru(struct kvm_vcpu *vcpu)
 -{
 -      return 0;
 -}
 -
  static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
  {
        switch (reg) {
@@@ -2330,7 -2335,7 +2330,7 @@@ static u64 nested_svm_get_tdp_pdptr(str
        u64 pdpte;
        int ret;
  
-       ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(cr3), &pdpte,
+       ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(__sme_clr(cr3)), &pdpte,
                                       offset_in_page(cr3) + index * 8, 8);
        if (ret)
                return 0;
@@@ -2342,7 -2347,7 +2342,7 @@@ static void nested_svm_set_tdp_cr3(stru
  {
        struct vcpu_svm *svm = to_svm(vcpu);
  
-       svm->vmcb->control.nested_cr3 = root;
+       svm->vmcb->control.nested_cr3 = __sme_set(root);
        mark_dirty(svm->vmcb, VMCB_NPT);
        svm_flush_tlb(vcpu);
  }
@@@ -2873,7 -2878,7 +2873,7 @@@ static bool nested_svm_vmrun_msrpm(stru
                svm->nested.msrpm[p] = svm->msrpm[p] | value;
        }
  
-       svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm);
+       svm->vmcb->control.msrpm_base_pa = __sme_set(__pa(svm->nested.msrpm));
  
        return true;
  }
@@@ -4506,7 -4511,7 +4506,7 @@@ get_pi_vcpu_info(struct kvm *kvm, struc
        pr_debug("SVM: %s: use GA mode for irq %u\n", __func__,
                 irq.vector);
        *svm = to_svm(vcpu);
-       vcpu_info->pi_desc_addr = page_to_phys((*svm)->avic_backing_page);
+       vcpu_info->pi_desc_addr = __sme_set(page_to_phys((*svm)->avic_backing_page));
        vcpu_info->vector = irq.vector;
  
        return 0;
@@@ -4557,7 -4562,8 +4557,8 @@@ static int svm_update_pi_irte(struct kv
                        struct amd_iommu_pi_data pi;
  
                        /* Try to enable guest_mode in IRTE */
-                       pi.base = page_to_phys(svm->avic_backing_page) & AVIC_HPA_MASK;
+                       pi.base = __sme_set(page_to_phys(svm->avic_backing_page) &
+                                           AVIC_HPA_MASK);
                        pi.ga_tag = AVIC_GATAG(kvm->arch.avic_vm_id,
                                                     svm->vcpu.vcpu_id);
                        pi.is_guest_mode = true;
@@@ -5006,7 -5012,7 +5007,7 @@@ static void svm_set_cr3(struct kvm_vcp
  {
        struct vcpu_svm *svm = to_svm(vcpu);
  
-       svm->vmcb->save.cr3 = root;
+       svm->vmcb->save.cr3 = __sme_set(root);
        mark_dirty(svm->vmcb, VMCB_CR);
        svm_flush_tlb(vcpu);
  }
@@@ -5015,7 -5021,7 +5016,7 @@@ static void set_tdp_cr3(struct kvm_vcp
  {
        struct vcpu_svm *svm = to_svm(vcpu);
  
-       svm->vmcb->control.nested_cr3 = root;
+       svm->vmcb->control.nested_cr3 = __sme_set(root);
        mark_dirty(svm->vmcb, VMCB_NPT);
  
        /* Also sync guest cr3 here in case we live migrate */
@@@ -5408,6 -5414,8 +5409,6 @@@ static struct kvm_x86_ops svm_x86_ops _
        .get_rflags = svm_get_rflags,
        .set_rflags = svm_set_rflags,
  
 -      .get_pkru = svm_get_pkru,
 -
        .tlb_flush = svm_flush_tlb,
  
        .run = svm_vcpu_run,
diff --combined arch/x86/kvm/vmx.c
index c6ef2940119bfdfb00f0547c321697280ebae0fa,416d5ed320b605ef361b96db01c53ba6d09bff7a..d40900914a72b04a329e64b829e2988e00d71eb3
@@@ -636,6 -636,8 +636,6 @@@ struct vcpu_vmx 
  
        u64 current_tsc_ratio;
  
 -      bool guest_pkru_valid;
 -      u32 guest_pkru;
        u32 host_pkru;
  
        /*
@@@ -2381,6 -2383,11 +2381,6 @@@ static void vmx_set_rflags(struct kvm_v
                to_vmx(vcpu)->emulation_required = emulation_required(vcpu);
  }
  
 -static u32 vmx_get_pkru(struct kvm_vcpu *vcpu)
 -{
 -      return to_vmx(vcpu)->guest_pkru;
 -}
 -
  static u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu)
  {
        u32 interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
@@@ -6556,7 -6563,7 +6556,7 @@@ void vmx_enable_tdp(void
                enable_ept_ad_bits ? VMX_EPT_DIRTY_BIT : 0ull,
                0ull, VMX_EPT_EXECUTABLE_MASK,
                cpu_has_vmx_ept_execute_only() ? 0ull : VMX_EPT_READABLE_MASK,
-               VMX_EPT_RWX_MASK);
+               VMX_EPT_RWX_MASK, 0ull);
  
        ept_set_mmio_spte_mask();
        kvm_enable_tdp();
@@@ -9013,10 -9020,8 +9013,10 @@@ static void __noclone vmx_vcpu_run(stru
        if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
                vmx_set_interrupt_shadow(vcpu, 0);
  
 -      if (vmx->guest_pkru_valid)
 -              __write_pkru(vmx->guest_pkru);
 +      if (static_cpu_has(X86_FEATURE_PKU) &&
 +          kvm_read_cr4_bits(vcpu, X86_CR4_PKE) &&
 +          vcpu->arch.pkru != vmx->host_pkru)
 +              __write_pkru(vcpu->arch.pkru);
  
        atomic_switch_perf_msrs(vmx);
        debugctlmsr = get_debugctlmsr();
         * back on host, so it is safe to read guest PKRU from current
         * XSAVE.
         */
 -      if (boot_cpu_has(X86_FEATURE_OSPKE)) {
 -              vmx->guest_pkru = __read_pkru();
 -              if (vmx->guest_pkru != vmx->host_pkru) {
 -                      vmx->guest_pkru_valid = true;
 +      if (static_cpu_has(X86_FEATURE_PKU) &&
 +          kvm_read_cr4_bits(vcpu, X86_CR4_PKE)) {
 +              vcpu->arch.pkru = __read_pkru();
 +              if (vcpu->arch.pkru != vmx->host_pkru)
                        __write_pkru(vmx->host_pkru);
 -              } else
 -                      vmx->guest_pkru_valid = false;
        }
  
        /*
@@@ -11675,6 -11682,8 +11675,6 @@@ static struct kvm_x86_ops vmx_x86_ops _
        .get_rflags = vmx_get_rflags,
        .set_rflags = vmx_set_rflags,
  
 -      .get_pkru = vmx_get_pkru,
 -
        .tlb_flush = vmx_flush_tlb,
  
        .run = vmx_vcpu_run,
diff --combined arch/x86/kvm/x86.c
index 272320eb328c9bc8c2d0cf839a097a30ca27491f,eda4bdbd7e5e1cb722de3c2c00fd6ed2323aa8a0..ef5102f804976086d04e23173edf3345e8a7d01f
@@@ -54,6 -54,7 +54,7 @@@
  #include <linux/kvm_irqfd.h>
  #include <linux/irqbypass.h>
  #include <linux/sched/stat.h>
+ #include <linux/mem_encrypt.h>
  
  #include <trace/events/kvm.h>
  
@@@ -3245,12 -3246,7 +3246,12 @@@ static void fill_xsave(u8 *dest, struc
                        u32 size, offset, ecx, edx;
                        cpuid_count(XSTATE_CPUID, index,
                                    &size, &offset, &ecx, &edx);
 -                      memcpy(dest + offset, src, size);
 +                      if (feature == XFEATURE_MASK_PKRU)
 +                              memcpy(dest + offset, &vcpu->arch.pkru,
 +                                     sizeof(vcpu->arch.pkru));
 +                      else
 +                              memcpy(dest + offset, src, size);
 +
                }
  
                valid -= feature;
@@@ -3288,11 -3284,7 +3289,11 @@@ static void load_xsave(struct kvm_vcpu 
                        u32 size, offset, ecx, edx;
                        cpuid_count(XSTATE_CPUID, index,
                                    &size, &offset, &ecx, &edx);
 -                      memcpy(dest, src + offset, size);
 +                      if (feature == XFEATURE_MASK_PKRU)
 +                              memcpy(&vcpu->arch.pkru, src + offset,
 +                                     sizeof(vcpu->arch.pkru));
 +                      else
 +                              memcpy(dest, src + offset, size);
                }
  
                valid -= feature;
@@@ -6125,7 -6117,7 +6126,7 @@@ int kvm_arch_init(void *opaque
  
        kvm_mmu_set_mask_ptes(PT_USER_MASK, PT_ACCESSED_MASK,
                        PT_DIRTY_MASK, PT64_NX_MASK, 0,
-                       PT_PRESENT_MASK, 0);
+                       PT_PRESENT_MASK, 0, sme_me_mask);
        kvm_timer_init();
  
        perf_register_guest_info_callbacks(&kvm_guest_cbs);
@@@ -6734,6 -6726,17 +6735,6 @@@ void kvm_vcpu_reload_apic_access_page(s
  }
  EXPORT_SYMBOL_GPL(kvm_vcpu_reload_apic_access_page);
  
 -void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
 -                                         unsigned long address)
 -{
 -      /*
 -       * The physical address of apic access page is stored in the VMCS.
 -       * Update it when it becomes invalid.
 -       */
 -      if (address == gfn_to_hva(kvm, APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT))
 -              kvm_make_all_cpus_request(kvm, KVM_REQ_APIC_PAGE_RELOAD);
 -}
 -
  /*
   * Returns 1 to let vcpu_run() continue the guest execution loop without
   * exiting to the userspace.  Otherwise, the value will be returned to the
@@@ -7631,9 -7634,7 +7632,9 @@@ void kvm_load_guest_fpu(struct kvm_vcp
         */
        vcpu->guest_fpu_loaded = 1;
        __kernel_fpu_begin();
 -      __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state);
 +      /* PKRU is separately restored in kvm_x86_ops->run.  */
 +      __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state,
 +                              ~XFEATURE_MASK_PKRU);
        trace_kvm_fpu(1);
  }
  
index 98491521bb434063f0a9a502915e8679268e7579,df1921751aa5cc03f9b0b54f1fa559dfc2d64b28..6c279c8f0a0efd07c3954d83509788287e58021e
@@@ -263,6 -263,13 +263,13 @@@ static void __init xen_init_capabilitie
        setup_clear_cpu_cap(X86_FEATURE_MTRR);
        setup_clear_cpu_cap(X86_FEATURE_ACC);
        setup_clear_cpu_cap(X86_FEATURE_X2APIC);
+       setup_clear_cpu_cap(X86_FEATURE_SME);
+       /*
+        * Xen PV would need some work to support PCID: CR3 handling as well
+        * as xen_flush_tlb_others() would need updating.
+        */
+       setup_clear_cpu_cap(X86_FEATURE_PCID);
  
        if (!xen_initial_domain())
                setup_clear_cpu_cap(X86_FEATURE_ACPI);
@@@ -981,6 -988,59 +988,6 @@@ void __ref xen_setup_vcpu_info_placemen
        }
  }
  
 -static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
 -                        unsigned long addr, unsigned len)
 -{
 -      char *start, *end, *reloc;
 -      unsigned ret;
 -
 -      start = end = reloc = NULL;
 -
 -#define SITE(op, x)                                                   \
 -      case PARAVIRT_PATCH(op.x):                                      \
 -      if (xen_have_vcpu_info_placement) {                             \
 -              start = (char *)xen_##x##_direct;                       \
 -              end = xen_##x##_direct_end;                             \
 -              reloc = xen_##x##_direct_reloc;                         \
 -      }                                                               \
 -      goto patch_site
 -
 -      switch (type) {
 -              SITE(pv_irq_ops, irq_enable);
 -              SITE(pv_irq_ops, irq_disable);
 -              SITE(pv_irq_ops, save_fl);
 -              SITE(pv_irq_ops, restore_fl);
 -#undef SITE
 -
 -      patch_site:
 -              if (start == NULL || (end-start) > len)
 -                      goto default_patch;
 -
 -              ret = paravirt_patch_insns(insnbuf, len, start, end);
 -
 -              /* Note: because reloc is assigned from something that
 -                 appears to be an array, gcc assumes it's non-null,
 -                 but doesn't know its relationship with start and
 -                 end. */
 -              if (reloc > start && reloc < end) {
 -                      int reloc_off = reloc - start;
 -                      long *relocp = (long *)(insnbuf + reloc_off);
 -                      long delta = start - (char *)addr;
 -
 -                      *relocp += delta;
 -              }
 -              break;
 -
 -      default_patch:
 -      default:
 -              ret = paravirt_patch_default(type, clobbers, insnbuf,
 -                                           addr, len);
 -              break;
 -      }
 -
 -      return ret;
 -}
 -
  static const struct pv_info xen_info __initconst = {
        .shared_kernel_pmd = 0,
  
        .name = "Xen",
  };
  
 -static const struct pv_init_ops xen_init_ops __initconst = {
 -      .patch = xen_patch,
 -};
 -
  static const struct pv_cpu_ops xen_cpu_ops __initconst = {
        .cpuid = xen_cpuid,
  
@@@ -1187,7 -1251,7 +1194,7 @@@ asmlinkage __visible void __init xen_st
  
        /* Install Xen paravirt ops */
        pv_info = xen_info;
 -      pv_init_ops = xen_init_ops;
 +      pv_init_ops.patch = paravirt_patch_default;
        pv_cpu_ops = xen_cpu_ops;
  
        x86_platform.get_nmi_reason = xen_get_nmi_reason;
index 88c6d78ee2d59d94f291b5b8cfdd6503ff581d42,7a61a07ac4de97643199b09cbdaf185e80b9edaf..c55f338e380b9d0d86da89012cd9109689ff6bd2
@@@ -36,6 -36,7 +36,7 @@@
  #include <linux/pagemap.h>
  #include <linux/shmem_fs.h>
  #include <linux/dma-buf.h>
+ #include <linux/mem_encrypt.h>
  #include <drm/drmP.h>
  #include <drm/drm_vma_manager.h>
  #include <drm/drm_gem.h>
@@@ -255,13 -256,13 +256,13 @@@ drm_gem_object_release_handle(int id, v
        struct drm_gem_object *obj = ptr;
        struct drm_device *dev = obj->dev;
  
 +      if (dev->driver->gem_close_object)
 +              dev->driver->gem_close_object(obj, file_priv);
 +
        if (drm_core_check_feature(dev, DRIVER_PRIME))
                drm_gem_remove_prime_handles(obj, file_priv);
        drm_vma_node_revoke(&obj->vma_node, file_priv);
  
 -      if (dev->driver->gem_close_object)
 -              dev->driver->gem_close_object(obj, file_priv);
 -
        drm_gem_object_handle_put_unlocked(obj);
  
        return 0;
@@@ -310,41 -311,6 +311,41 @@@ drm_gem_handle_delete(struct drm_file *
  }
  EXPORT_SYMBOL(drm_gem_handle_delete);
  
 +/**
 + * drm_gem_dumb_map_offset - return the fake mmap offset for a gem object
 + * @file: drm file-private structure containing the gem object
 + * @dev: corresponding drm_device
 + * @handle: gem object handle
 + * @offset: return location for the fake mmap offset
 + *
 + * This implements the &drm_driver.dumb_map_offset kms driver callback for
 + * drivers which use gem to manage their backing storage.
 + *
 + * Returns:
 + * 0 on success or a negative error code on failure.
 + */
 +int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
 +                          u32 handle, u64 *offset)
 +{
 +      struct drm_gem_object *obj;
 +      int ret;
 +
 +      obj = drm_gem_object_lookup(file, handle);
 +      if (!obj)
 +              return -ENOENT;
 +
 +      ret = drm_gem_create_mmap_offset(obj);
 +      if (ret)
 +              goto out;
 +
 +      *offset = drm_vma_node_offset_addr(&obj->vma_node);
 +out:
 +      drm_gem_object_put_unlocked(obj);
 +
 +      return ret;
 +}
 +EXPORT_SYMBOL_GPL(drm_gem_dumb_map_offset);
 +
  /**
   * drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers
   * @file: drm file-private structure to remove the dumb handle from
@@@ -861,15 -827,13 +862,15 @@@ drm_gem_object_put_unlocked(struct drm_
                return;
  
        dev = obj->dev;
 -      might_lock(&dev->struct_mutex);
  
 -      if (dev->driver->gem_free_object_unlocked)
 +      if (dev->driver->gem_free_object_unlocked) {
                kref_put(&obj->refcount, drm_gem_object_free);
 -      else if (kref_put_mutex(&obj->refcount, drm_gem_object_free,
 +      } else {
 +              might_lock(&dev->struct_mutex);
 +              if (kref_put_mutex(&obj->refcount, drm_gem_object_free,
                                &dev->struct_mutex))
 -              mutex_unlock(&dev->struct_mutex);
 +                      mutex_unlock(&dev->struct_mutex);
 +      }
  }
  EXPORT_SYMBOL(drm_gem_object_put_unlocked);
  
@@@ -965,6 -929,7 +966,7 @@@ int drm_gem_mmap_obj(struct drm_gem_obj
        vma->vm_ops = dev->driver->gem_vm_ops;
        vma->vm_private_data = obj;
        vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
  
        /* Take a ref for this mapping of the object, so that the fault
         * handler can dereference the mmap offset's pointer to the object.
@@@ -1001,7 -966,7 +1003,7 @@@ int drm_gem_mmap(struct file *filp, str
        struct drm_vma_offset_node *node;
        int ret;
  
 -      if (drm_device_is_unplugged(dev))
 +      if (drm_dev_is_unplugged(dev))
                return -ENODEV;
  
        drm_vma_offset_lock_lookup(dev->vma_offset_manager);
diff --combined drivers/gpu/drm/drm_vm.c
index 13a59ed2afbc4112568a62aba71d9857aadf940a,ed4bcbfd60864ca46064620cd1c9b83e0b1c8c25..2660543ad86a571dab759a45370369d43fbb16c0
@@@ -40,6 -40,7 +40,7 @@@
  #include <linux/efi.h>
  #include <linux/slab.h>
  #endif
+ #include <linux/mem_encrypt.h>
  #include <asm/pgtable.h>
  #include "drm_internal.h"
  #include "drm_legacy.h"
@@@ -58,6 -59,9 +59,9 @@@ static pgprot_t drm_io_prot(struct drm_
  {
        pgprot_t tmp = vm_get_page_prot(vma->vm_flags);
  
+       /* We don't want graphics memory to be mapped encrypted */
+       tmp = pgprot_decrypted(tmp);
  #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__)
        if (map->type == _DRM_REGISTERS && !(map->flags & _DRM_WRITE_COMBINING))
                tmp = pgprot_noncached(tmp);
@@@ -631,7 -635,7 +635,7 @@@ int drm_legacy_mmap(struct file *filp, 
        struct drm_device *dev = priv->minor->dev;
        int ret;
  
 -      if (drm_device_is_unplugged(dev))
 +      if (drm_dev_is_unplugged(dev))
                return -ENODEV;
  
        mutex_lock(&dev->struct_mutex);
index a01e5c90fd87cb548990757bf4bd17b3978f6ab9,84fb009d4eb045eeafb1e731faf418107613c69e..c8ebb757e36b524f2074d67067888b61a012d9cd
@@@ -39,6 -39,7 +39,7 @@@
  #include <linux/rbtree.h>
  #include <linux/module.h>
  #include <linux/uaccess.h>
+ #include <linux/mem_encrypt.h>
  
  #define TTM_BO_VM_NUM_PREFAULT 16
  
@@@ -230,9 -231,11 +231,11 @@@ static int ttm_bo_vm_fault(struct vm_fa
         * first page.
         */
        for (i = 0; i < TTM_BO_VM_NUM_PREFAULT; ++i) {
-               if (bo->mem.bus.is_iomem)
+               if (bo->mem.bus.is_iomem) {
+                       /* Iomem should not be marked encrypted */
+                       cvma.vm_page_prot = pgprot_decrypted(cvma.vm_page_prot);
                        pfn = bdev->driver->io_mem_pfn(bo, page_offset);
-               else {
+               else {
                        page = ttm->pages[page_offset];
                        if (unlikely(!page && i == 0)) {
                                retval = VM_FAULT_OOM;
@@@ -294,87 -297,10 +297,87 @@@ static void ttm_bo_vm_close(struct vm_a
        vma->vm_private_data = NULL;
  }
  
 +static int ttm_bo_vm_access_kmap(struct ttm_buffer_object *bo,
 +                               unsigned long offset,
 +                               void *buf, int len, int write)
 +{
 +      unsigned long page = offset >> PAGE_SHIFT;
 +      unsigned long bytes_left = len;
 +      int ret;
 +
 +      /* Copy a page at a time, that way no extra virtual address
 +       * mapping is needed
 +       */
 +      offset -= page << PAGE_SHIFT;
 +      do {
 +              unsigned long bytes = min(bytes_left, PAGE_SIZE - offset);
 +              struct ttm_bo_kmap_obj map;
 +              void *ptr;
 +              bool is_iomem;
 +
 +              ret = ttm_bo_kmap(bo, page, 1, &map);
 +              if (ret)
 +                      return ret;
 +
 +              ptr = (uint8_t *)ttm_kmap_obj_virtual(&map, &is_iomem) + offset;
 +              WARN_ON_ONCE(is_iomem);
 +              if (write)
 +                      memcpy(ptr, buf, bytes);
 +              else
 +                      memcpy(buf, ptr, bytes);
 +              ttm_bo_kunmap(&map);
 +
 +              page++;
 +              bytes_left -= bytes;
 +              offset = 0;
 +      } while (bytes_left);
 +
 +      return len;
 +}
 +
 +static int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr,
 +                          void *buf, int len, int write)
 +{
 +      unsigned long offset = (addr) - vma->vm_start;
 +      struct ttm_buffer_object *bo = vma->vm_private_data;
 +      int ret;
 +
 +      if (len < 1 || (offset + len) >> PAGE_SHIFT > bo->num_pages)
 +              return -EIO;
 +
 +      ret = ttm_bo_reserve(bo, true, false, NULL);
 +      if (ret)
 +              return ret;
 +
 +      switch (bo->mem.mem_type) {
 +      case TTM_PL_SYSTEM:
 +              if (unlikely(bo->ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) {
 +                      ret = ttm_tt_swapin(bo->ttm);
 +                      if (unlikely(ret != 0))
 +                              return ret;
 +              }
 +              /* fall through */
 +      case TTM_PL_TT:
 +              ret = ttm_bo_vm_access_kmap(bo, offset, buf, len, write);
 +              break;
 +      default:
 +              if (bo->bdev->driver->access_memory)
 +                      ret = bo->bdev->driver->access_memory(
 +                              bo, offset, buf, len, write);
 +              else
 +                      ret = -EIO;
 +      }
 +
 +      ttm_bo_unreserve(bo);
 +
 +      return ret;
 +}
 +
  static const struct vm_operations_struct ttm_bo_vm_ops = {
        .fault = ttm_bo_vm_fault,
        .open = ttm_bo_vm_open,
 -      .close = ttm_bo_vm_close
 +      .close = ttm_bo_vm_close,
 +      .access = ttm_bo_vm_access
  };
  
  static struct ttm_buffer_object *ttm_bo_vm_lookup(struct ttm_bo_device *bdev,
index b7ca90db4e8044c17f47f2f678ce9ada3e3f5570,92e1690e28de90faf99d3fb0d2eec7308aa9d693..b5b335c9b2bbe504fdddf47246820e1e64199d18
@@@ -14,6 -14,7 +14,7 @@@
  #include <linux/slab.h>
  #include <linux/fb.h>
  #include <linux/dma-buf.h>
+ #include <linux/mem_encrypt.h>
  
  #include <drm/drmP.h>
  #include <drm/drm_crtc.h>
@@@ -169,6 -170,9 +170,9 @@@ static int udl_fb_mmap(struct fb_info *
        pr_notice("mmap() framebuffer addr:%lu size:%lu\n",
                  pos, size);
  
+       /* We don't want the framebuffer to be mapped encrypted */
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
        while (size > 0) {
                page = vmalloc_to_pfn((void *)pos);
                if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
@@@ -198,7 -202,7 +202,7 @@@ static int udl_fb_open(struct fb_info *
        struct udl_device *udl = dev->dev_private;
  
        /* If the USB device is gone, we don't accept new opens */
 -      if (drm_device_is_unplugged(udl->ddev))
 +      if (drm_dev_is_unplugged(udl->ddev))
                return -ENODEV;
  
        ufbdev->fb_count++;
@@@ -309,7 -313,7 +313,7 @@@ static void udl_user_framebuffer_destro
        struct udl_framebuffer *ufb = to_udl_fb(fb);
  
        if (ufb->obj)
 -              drm_gem_object_unreference_unlocked(&ufb->obj->base);
 +              drm_gem_object_put_unlocked(&ufb->obj->base);
  
        drm_framebuffer_cleanup(fb);
        kfree(ufb);
@@@ -393,6 -397,7 +397,6 @@@ static int udlfb_create(struct drm_fb_h
        info->fix.smem_len = size;
        info->fix.smem_start = (unsigned long)ufbdev->ufb.obj->vmapping;
  
 -      info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
        info->fbops = &udlfb_ops;
        drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
        drm_fb_helper_fill_var(info, &ufbdev->helper, sizes->fb_width, sizes->fb_height);
  
        return ret;
  out_gfree:
 -      drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base);
 +      drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base);
  out:
        return ret;
  }
@@@ -419,7 -424,7 +423,7 @@@ static void udl_fbdev_destroy(struct dr
        drm_fb_helper_fini(&ufbdev->helper);
        drm_framebuffer_unregister_private(&ufbdev->ufb.base);
        drm_framebuffer_cleanup(&ufbdev->ufb.base);
 -      drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base);
 +      drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base);
  }
  
  int udl_fbdev_init(struct drm_device *dev)
index d6b873b57054b44d2f0227630798cda83a637256,8591f43c467c9c93aa1c3dcf5d8e64d2f3bcdbd5..8e3a8575924293f46a1b3243d64b2db757ee3377
  
  #define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL)
  #define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P)
- #define IOMMU_PTE_PAGE(pte) (phys_to_virt((pte) & IOMMU_PAGE_MASK))
+ #define IOMMU_PTE_PAGE(pte) (iommu_phys_to_virt((pte) & IOMMU_PAGE_MASK))
  #define IOMMU_PTE_MODE(pte) (((pte) >> 9) & 0x07)
  
  #define IOMMU_PROT_MASK 0x03
@@@ -574,9 -574,7 +574,9 @@@ struct amd_iommu 
  
  static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
  {
 -      return container_of(dev, struct amd_iommu, iommu.dev);
 +      struct iommu_device *iommu = dev_to_iommu_device(dev);
 +
 +      return container_of(iommu, struct amd_iommu, iommu);
  }
  
  #define ACPIHID_UID_LEN 256
index 310f51d42550f15503a96987a2d694f902430e57,71b86a5d3061dda87c7ab3ee95211c9512adbea0..16d41de92ee3a7799c873d479f3f2770bf87ba4c
  
  #if GCC_VERSION >= 40100
  # define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
+ #define __nostackprotector    __attribute__((__optimize__("no-stack-protector")))
  #endif
  
  #if GCC_VERSION >= 40300
  #endif
  #endif
  
 -#ifdef CONFIG_STACK_VALIDATION
 -#define annotate_unreachable() ({                                     \
 -      asm("%c0:\t\n"                                                  \
 -          ".pushsection .discard.unreachable\t\n"                     \
 -          ".long %c0b - .\t\n"                                        \
 -          ".popsection\t\n" : : "i" (__LINE__));                      \
 -})
 -#else
 -#define annotate_unreachable()
 -#endif
 -
  /*
   * Mark a position in code as unreachable.  This can be used to
   * suppress control flow warnings after asm blocks that transfer
diff --combined include/linux/compiler.h
index e786337cf5a7ee5cdc7b38488315e6db180912a4,43cac547f773d2af821f69cd03610861d33bc571..e95a2631e54561d8981a9e849802ba9f9f65f998
@@@ -185,34 -185,8 +185,34 @@@ void ftrace_likely_update(struct ftrace
  #endif
  
  /* Unreachable code */
 +#ifdef CONFIG_STACK_VALIDATION
 +#define annotate_reachable() ({                                               \
 +      asm("%c0:\n\t"                                                  \
 +          ".pushsection .discard.reachable\n\t"                       \
 +          ".long %c0b - .\n\t"                                        \
 +          ".popsection\n\t" : : "i" (__LINE__));                      \
 +})
 +#define annotate_unreachable() ({                                     \
 +      asm("%c0:\n\t"                                                  \
 +          ".pushsection .discard.unreachable\n\t"                     \
 +          ".long %c0b - .\n\t"                                        \
 +          ".popsection\n\t" : : "i" (__LINE__));                      \
 +})
 +#define ASM_UNREACHABLE                                                       \
 +      "999:\n\t"                                                      \
 +      ".pushsection .discard.unreachable\n\t"                         \
 +      ".long 999b - .\n\t"                                            \
 +      ".popsection\n\t"
 +#else
 +#define annotate_reachable()
 +#define annotate_unreachable()
 +#endif
 +
 +#ifndef ASM_UNREACHABLE
 +# define ASM_UNREACHABLE
 +#endif
  #ifndef unreachable
 -# define unreachable() do { } while (1)
 +# define unreachable() do { annotate_reachable(); do { } while (1); } while (0)
  #endif
  
  /*
@@@ -501,6 -475,10 +501,10 @@@ static __always_inline void __write_onc
  #define __visible
  #endif
  
+ #ifndef __nostackprotector
+ # define __nostackprotector
+ #endif
  /*
   * Assume alignment of return value.
   */
  # define __compiletime_error_fallback(condition) do { } while (0)
  #endif
  
 -#define __compiletime_assert(condition, msg, prefix, suffix)          \
 +#ifdef __OPTIMIZE__
 +# define __compiletime_assert(condition, msg, prefix, suffix)         \
        do {                                                            \
                bool __cond = !(condition);                             \
                extern void prefix ## suffix(void) __compiletime_error(msg); \
                        prefix ## suffix();                             \
                __compiletime_error_fallback(__cond);                   \
        } while (0)
 +#else
 +# define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0)
 +#endif
  
  #define _compiletime_assert(condition, msg, prefix, suffix) \
        __compiletime_assert(condition, msg, prefix, suffix)
diff --combined include/linux/efi.h
index a686ca9a7e5ca76ffe9ccf643ee19a456f5a6d0b,4e47f78430bece2a3015f2fe1a74c88ae339f9e7..4102b85217d5bea0d5079aa9007956ea6c96a2cd
@@@ -985,7 -985,7 +985,7 @@@ static inline void efi_esrt_init(void) 
  extern int efi_config_parse_tables(void *config_tables, int count, int sz,
                                   efi_config_table_type_t *arch_tables);
  extern u64 efi_get_iobase (void);
- extern u32 efi_mem_type (unsigned long phys_addr);
+ extern int efi_mem_type(unsigned long phys_addr);
  extern u64 efi_mem_attributes (unsigned long phys_addr);
  extern u64 efi_mem_attribute (unsigned long phys_addr, unsigned long size);
  extern int __init efi_uart_console_only (void);
@@@ -1020,28 -1020,6 +1020,28 @@@ extern int efi_memattr_init(void)
  extern int efi_memattr_apply_permissions(struct mm_struct *mm,
                                         efi_memattr_perm_setter fn);
  
 +/*
 + * efi_early_memdesc_ptr - get the n-th EFI memmap descriptor
 + * @map: the start of efi memmap
 + * @desc_size: the size of space for each EFI memmap descriptor
 + * @n: the index of efi memmap descriptor
 + *
 + * EFI boot service provides the GetMemoryMap() function to get a copy of the
 + * current memory map which is an array of memory descriptors, each of
 + * which describes a contiguous block of memory. It also gets the size of the
 + * map, and the size of each descriptor, etc.
 + *
 + * Note that per section 6.2 of UEFI Spec 2.6 Errata A, the returned size of
 + * each descriptor might not be equal to sizeof(efi_memory_memdesc_t),
 + * since efi_memory_memdesc_t may be extended in the future. Thus the OS
 + * MUST use the returned size of the descriptor to find the start of each
 + * efi_memory_memdesc_t in the memory map array. This should only be used
 + * during bootup since for_each_efi_memory_desc_xxx() is available after the
 + * kernel initializes the EFI subsystem to set up struct efi_memory_map.
 + */
 +#define efi_early_memdesc_ptr(map, desc_size, n)                      \
 +      (efi_memory_desc_t *)((void *)(map) + ((n) * (desc_size)))
 +
  /* Iterate through an efi_memory_map */
  #define for_each_efi_memory_desc_in_map(m, md)                                   \
        for ((md) = (m)->map;                                              \
@@@ -1113,6 -1091,8 +1113,8 @@@ static inline bool efi_enabled(int feat
        return test_bit(feature, &efi.flags) != 0;
  }
  extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
+ extern bool efi_is_table_address(unsigned long phys_addr);
  #else
  static inline bool efi_enabled(int feature)
  {
@@@ -1126,6 -1106,11 +1128,11 @@@ efi_capsule_pending(int *reset_type
  {
        return false;
  }
+ static inline bool efi_is_table_address(unsigned long phys_addr)
+ {
+       return false;
+ }
  #endif
  
  extern int efi_status_to_err(efi_status_t status);
diff --combined init/main.c
index b78f63c30b1718d5683e992ab264d421b8888e5b,9789ab7fe85e14f7434be3b0298a9ebf920242e0..8828fc148670df6dc81b07b03ea8070c7424a349
@@@ -430,6 -430,7 +430,6 @@@ static noinline void __ref rest_init(vo
         * The boot idle thread must execute schedule()
         * at least once to get things moving:
         */
 -      init_idle_bootup_task(current);
        schedule_preempt_disabled();
        /* Call into cpu_idle with preempt disabled */
        cpu_startup_entry(CPUHP_ONLINE);
@@@ -487,6 -488,8 +487,8 @@@ void __init __weak thread_stack_cache_i
  }
  #endif
  
+ void __init __weak mem_encrypt_init(void) { }
  /*
   * Set up kernel memory allocators
   */
@@@ -640,6 -643,14 +642,14 @@@ asmlinkage __visible void __init start_
         */
        locking_selftest();
  
+       /*
+        * This needs to be called before any devices perform DMA
+        * operations that might use the SWIOTLB bounce buffers. It will
+        * mark the bounce buffers as decrypted so that their usage will
+        * not cause "plain-text" data to be decrypted when accessed.
+        */
+       mem_encrypt_init();
  #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_start && !initrd_below_start_ok &&
            page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
        }
  #endif
        page_ext_init();
 -      debug_objects_mem_init();
        kmemleak_init();
 +      debug_objects_mem_init();
        setup_per_cpu_pageset();
        numa_policy_init();
        if (late_time_init)
This page took 0.214807 seconds and 4 git commands to generate.