Skip to content

Commit 232bb01

Browse files
davejiangvinodkoul
authored andcommitted
x86/asm: add iosubmit_cmds512() based on MOVDIR64B CPU instruction
With the introduction of MOVDIR64B instruction, there is now an instruction that can write 64 bytes of data atomically. Quoting from Intel SDM: "There is no atomicity guarantee provided for the 64-byte load operation from source address, and processor implementations may use multiple load operations to read the 64-bytes. The 64-byte direct-store issued by MOVDIR64B guarantees 64-byte write-completion atomicity. This means that the data arrives at the destination in a single undivided 64-byte write transaction." We have identified at least 3 different use cases for this instruction in the format of func(dst, src, count): 1) Clear poison / Initialize MKTME memory @dst is normal memory. @src in normal memory. Does not increment. (Copy same line to all targets) @count (to clear/init multiple lines) 2) Submit command(s) to new devices @dst is a special MMIO region for a device. Does not increment. @src is normal memory. Increments. @count usually is 1, but can be multiple. 3) Copy to iomem in big chunks @dst is iomem and increments @src in normal memory and increments @count is number of chunks to copy Add support for case #2 to support device that will accept commands via this instruction. We provide a @count in order to submit a batch of preprogrammed descriptors in virtually contiguous memory. This allows the caller to submit multiple descriptors to a device with a single submission. The special device requires the entire 64bytes descriptor to be written atomically and will accept MOVDIR64B instruction. Signed-off-by: Dave Jiang <[email protected]> Acked-by: Borislav Petkov <[email protected]> Link: https://lore.kernel.org/r/157965022175.73301.10174614665472962675.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul <[email protected]>
1 parent 6c0157b commit 232bb01

File tree

1 file changed

+36
-0
lines changed
  • arch/x86/include/asm

1 file changed

+36
-0
lines changed

arch/x86/include/asm/io.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,4 +399,40 @@ extern bool arch_memremap_can_ram_remap(resource_size_t offset,
399399
extern bool phys_mem_access_encrypted(unsigned long phys_addr,
400400
unsigned long size);
401401

402+
/**
403+
* iosubmit_cmds512 - copy data to single MMIO location, in 512-bit units
404+
* @__dst: destination, in MMIO space (must be 512-bit aligned)
405+
* @src: source
406+
* @count: number of 512 bits quantities to submit
407+
*
408+
* Submit data from kernel space to MMIO space, in units of 512 bits at a
409+
* time. Order of access is not guaranteed, nor is a memory barrier
410+
* performed afterwards.
411+
*
412+
* Warning: Do not use this helper unless your driver has checked that the CPU
413+
* instruction is supported on the platform.
414+
*/
415+
static inline void iosubmit_cmds512(void __iomem *__dst, const void *src,
416+
size_t count)
417+
{
418+
/*
419+
* Note that this isn't an "on-stack copy", just definition of "dst"
420+
* as a pointer to 64-bytes of stuff that is going to be overwritten.
421+
* In the MOVDIR64B case that may be needed as you can use the
422+
* MOVDIR64B instruction to copy arbitrary memory around. This trick
423+
* lets the compiler know how much gets clobbered.
424+
*/
425+
volatile struct { char _[64]; } *dst = __dst;
426+
const u8 *from = src;
427+
const u8 *end = from + count * 64;
428+
429+
while (from < end) {
430+
/* MOVDIR64B [rdx], rax */
431+
asm volatile(".byte 0x66, 0x0f, 0x38, 0xf8, 0x02"
432+
: "=m" (dst)
433+
: "d" (from), "a" (dst));
434+
from += 64;
435+
}
436+
}
437+
402438
#endif /* _ASM_X86_IO_H */

0 commit comments

Comments
 (0)