]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
plat/kvm: enable XSAVE for PKRU register
authorHugo Lefeuvre <hle@owl.eu.com>
Fri, 11 Dec 2020 16:35:14 +0000 (16:35 +0000)
committerSimon Kuenzer <simon.kuenzer@neclab.eu>
Mon, 21 Dec 2020 16:21:28 +0000 (17:21 +0100)
According to Intel 64 and IA-32 Architectures Software Developer’s
Manual Vol. 1, Section 13.5.7 'PKRU State':

software can use the XSAVE feature set to manage PKRU state
only if XCR0[9] = 1

This patch sets XCR0[9] if PKU is available (and enabled via
CONFIG_HAVE_X86PKU).

Note: we do not support PKU without XSAVE. If CONFIG_HAVE_X86PKU is
selected but XSAVE is not available, we simply don't initialize PKU
and let the boot process gracefully abort later.

Signed-off-by: Hugo Lefeuvre <hugo.lefeuvre@manchester.ac.uk>
Reviewed-by: Mocanu Gabriel <gabi.mocanu98@gmail.com>
plat/common/include/x86/cpu_defs.h
plat/kvm/x86/entry64.S

index 74cff459dbdbd071a9166dd39ec78eb183ef53bb..1cf5367db6e8ae36379c904565759603278552bf 100644 (file)
 #define X86_XCR0_X87            (1 << 0)
 #define X86_XCR0_SSE            (1 << 1)
 #define X86_XCR0_AVX            (1 << 2)
+#define X86_XCR0_PKRU          (1 << 9)
 
 /*
  * Model-specific register addresses
index ef5e0e778ee49ebb43b52ca387b946b243683c5b..287f902978b35b908f1f60f5d3c468233251eb28 100644 (file)
@@ -196,18 +196,19 @@ ENTRY(_libkvmplat_start64)
        movq %rdi, %cr4
        ldmxcsr (mxcsr_ptr)
 #endif /* __SSE__ */
+#if (__AVX__ || CONFIG_HAVE_X86PKU)
        /* Check capabilities subject to availability as indicated by cpuid.
         * First, start off with "standard features" */
        movl $0x1, %eax
        cpuid
-#if __AVX__
        /* ecx and edx now contain capability information, so we can now
         * enable capabilities based on the indicated features */
-       /* OSXSAVE needs to be enabled before AVX */
+       /* note: OSXSAVE needs to be enabled before AVX and PKU */
        testl $(X86_CPUID1_ECX_XSAVE), %ecx
        jz noxsave
        orl $(X86_CR4_OSXSAVE), %edi
        movq %rdi, %cr4
+#if __AVX__
        /* now enable AVX. This needs to be last checking cpuid features from
         * the eax=1 cpuid call, because it clobbers ecx */
        testl $(X86_CPUID1_ECX_AVX), %ecx
@@ -217,8 +218,10 @@ ENTRY(_libkvmplat_start64)
        orl $(X86_XCR0_SSE | X86_XCR0_AVX), %eax
        xsetbv
 noavx:
-noxsave:
 #endif /* __AVX__ */
+/* Do not enable AVX without XSAVE, otherwise we'll get #UD */
+noxsave:
+#endif /* __AVX__ || CONFIG_HAVE_X86PKU */
        /* Now, check for extended features. */
        movl $0x7, %eax
        movl $0x0, %ecx
@@ -234,9 +237,17 @@ nofsgsbase:
        /* check for Memory Protection Keys (PKU) */
        testl $(X86_CPUID7_ECX_PKU), %ecx
        jz nopku
-       /* if PKU is supported, enable it via CR4 */
+       /* only enable PKU if we support XSAVE */
+       testl $(X86_CR4_OSXSAVE), %edi
+       jz nopku
+       /* PKU is supported, enable it via CR4 */
        orl $(X86_CR4_PKE), %edi
        movq %rdi, %cr4
+       /* also enable XSAVE for the PKRU */
+       xorl %ecx, %ecx
+       xgetbv
+       orl $(X86_XCR0_PKRU), %eax
+       xsetbv
 nopku:
 #endif /* CONFIG_HAVE_X86PKU */
        /* done setting up CPU capabilities */