Re: [PATCH v6 2/5] x86/asm: Add enqcmds() to support ENQCMDS instruction

From: Borislav Petkov
Date: Thu Sep 24 2020 - 14:58:33 EST


On Thu, Sep 24, 2020 at 11:00:38AM -0700, Dave Jiang wrote:
> +/**
> + * enqcmds - copy a 512 bits data unit to single MMIO location

You forgot to fix this.

> + * @dst: destination, in MMIO space (must be 512-bit aligned)
> + * @src: source
> + *
> + * The ENQCMDS instruction allows software to write a 512 bits command to
> + * a 512 bits 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.
> + *
> + * The enqcmds() function uses 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. The
> + * function returns 0 on success and -EAGAIN on failure.
> + *
> + * Warning: Do not use this helper unless your driver has checked that the CPU
> + * instruction is supported on the platform and the device accepts ENQCMDS.
> + */
> +static inline int enqcmds(void __iomem *dst, const void *src)
> +{
> + int zf;
> +
> + /* ENQCMDS [rdx], rax */
> + asm volatile(".byte 0xf3, 0x0f, 0x38, 0xf8, 0x02, 0x66, 0x90"
> + CC_SET(z)
> + : CC_OUT(z) (zf)
> + : "a" (dst), "d" (src));

Those operands need to be specified the same way as for movdir64b.

I've done that to save roundtrip time - simply replace yours with this
one after having tested it on actual hardware, of course.

---