Merge tag 'x86_pasid_for_5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 12 Oct 2020 17:40:34 +0000 (10:40 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 12 Oct 2020 17:40:34 +0000 (10:40 -0700)
Pull x86 PASID updates from Borislav Petkov:
 "Initial support for sharing virtual addresses between the CPU and
  devices which doesn't need pinning of pages for DMA anymore.

  Add support for the command submission to devices using new x86
  instructions like ENQCMD{,S} and MOVDIR64B. In addition, add support
  for process address space identifiers (PASIDs) which are referenced by
  those command submission instructions along with the handling of the
  PASID state on context switch as another extended state.

  Work by Fenghua Yu, Ashok Raj, Yu-cheng Yu and Dave Jiang"

* tag 'x86_pasid_for_5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/asm: Add an enqcmds() wrapper for the ENQCMDS instruction
  x86/asm: Carve out a generic movdir64b() helper for general usage
  x86/mmu: Allocate/free a PASID
  x86/cpufeatures: Mark ENQCMD as disabled when configured out
  mm: Add a pasid member to struct mm_struct
  x86/msr-index: Define an IA32_PASID MSR
  x86/fpu/xstate: Add supervisor PASID state for ENQCMD
  x86/cpufeatures: Enumerate ENQCMD and ENQCMDS instructions
  Documentation/x86: Add documentation for SVA (Shared Virtual Addressing)
  iommu/vt-d: Change flags type to unsigned int in binding mm
  drm, iommu: Change type of pasid to u32

1  2 
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/fpu/internal.h
arch/x86/include/asm/special_insns.h
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
drivers/iommu/amd/iommu.c
drivers/iommu/intel/iommu.c
include/linux/mm_types.h

Simple merge
Simple merge
@@@ -234,12 -234,70 +234,76 @@@ static inline void clwb(volatile void *
  
  #define nop() asm volatile ("nop")
  
 +static inline void serialize(void)
 +{
 +      /* Instruction opcode for SERIALIZE; supported in binutils >= 2.35. */
 +      asm volatile(".byte 0xf, 0x1, 0xe8" ::: "memory");
 +}
 +
+ /* The dst parameter must be 64-bytes aligned */
+ static inline void movdir64b(void *dst, const void *src)
+ {
+       const struct { char _[64]; } *__src = src;
+       struct { char _[64]; } *__dst = dst;
+       /*
+        * MOVDIR64B %(rdx), rax.
+        *
+        * Both __src and __dst must be memory constraints in order to tell the
+        * compiler that no other memory accesses should be reordered around
+        * this one.
+        *
+        * Also, both must be supplied as lvalues because this tells
+        * the compiler what the object is (its size) the instruction accesses.
+        * I.e., not the pointers but what they point to, thus the deref'ing '*'.
+        */
+       asm volatile(".byte 0x66, 0x0f, 0x38, 0xf8, 0x02"
+                    : "+m" (*__dst)
+                    :  "m" (*__src), "a" (__dst), "d" (__src));
+ }
+ /**
+  * enqcmds - Enqueue a command in supervisor (CPL0) mode
+  * @dst: destination, in MMIO space (must be 512-bit aligned)
+  * @src: 512 bits memory operand
+  *
+  * The ENQCMDS instruction allows software to write a 512-bit command to
+  * a 512-bit-aligned special MMIO region that supports the instruction.
+  * A return status is loaded into the ZF flag in the RFLAGS register.
+  * ZF = 0 equates to success, and ZF = 1 indicates retry or error.
+  *
+  * This function issues the ENQCMDS instruction to submit data from
+  * kernel space to MMIO space, in a unit of 512 bits. Order of data access
+  * is not guaranteed, nor is a memory barrier performed afterwards. It
+  * returns 0 on success and -EAGAIN on failure.
+  *
+  * Warning: Do not use this helper unless your driver has checked that the
+  * ENQCMDS instruction is supported on the platform and the device accepts
+  * ENQCMDS.
+  */
+ static inline int enqcmds(void __iomem *dst, const void *src)
+ {
+       const struct { char _[64]; } *__src = src;
+       struct { char _[64]; } *__dst = dst;
+       int zf;
+       /*
+        * ENQCMDS %(rdx), rax
+        *
+        * See movdir64b()'s comment on operand specification.
+        */
+       asm volatile(".byte 0xf3, 0x0f, 0x38, 0xf8, 0x02, 0x66, 0x90"
+                    CC_SET(z)
+                    : CC_OUT(z) (zf), "+m" (*__dst)
+                    : "m" (*__src), "a" (__dst), "d" (__src));
+       /* Submission failure is indicated via EFLAGS.ZF=1 */
+       if (zf)
+               return -EAGAIN;
+       return 0;
+ }
  #endif /* __KERNEL__ */
  
  #endif /* _ASM_X86_SPECIAL_INSNS_H */
Simple merge
Simple merge
Simple merge