[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [UNIKRAFT PATCH 1/2] plat/kvm: support PKE bit on x86



On Thu, Dec 03, 2020 at 11:16:36AM +0000, Hugo Lefeuvre wrote:
> From: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxxx>

My bad, this from should not be there. I can resend after the review, or we
can remove it while upstreaming.

> Provided that PKU is advertised by cpuid (EAX=7, ECX=0, EXC bit 3),
> Memory Protection Keys can be enabled by setting bit 22 (PKE) in CR4.
> 
> Since we do not want to pay the cost of MPK-related code when MPK is
> not enabled, we introduce a new HAVE_X86PKU property; MPK code is
> compile-guarded so that it does not get compiled in without
> HAVE_X86PKU. HAVE_X86PKU will be set by PKU kernel libraries later on.
> 
> At boot time, if HAVE_X86PKU is enabled, the kernel now checks whether
> PKU is advertised by cpuid. If not, it aborts the boot process. The
> underlying idea is that images compiled with HAVE_X86PKU are
> *specialized* to be executed on PKU-enabled hardware. Hence, provided
> that HAVE_X86PKU is set, there is a guarantee that PKU is supported
> *and* enabled, effectively removing the need for checks later at
> runtime. This might benefit performance when the domain switching rate
> is high.
> 
> Signed-off-by: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxxxxxxxxx>
> ---
>  lib/Config.uk                      |  4 ++++
>  plat/common/include/x86/cpu.h      | 15 +++++++++++++++
>  plat/common/include/x86/cpu_defs.h |  3 +++
>  plat/kvm/x86/entry64.S             | 12 ++++++++++++
>  plat/kvm/x86/setup.c               |  4 ++++
>  5 files changed, 38 insertions(+)
> 
> diff --git a/lib/Config.uk b/lib/Config.uk
> index e83ed30b..dac2d2fa 100644
> --- a/lib/Config.uk
> +++ b/lib/Config.uk
> @@ -28,3 +28,7 @@ config HAVE_NW_STACK
>  config HAVE_SYSCALL
>         bool
>         default n
> +
> +config HAVE_X86PKU
> +     bool
> +     default n
> diff --git a/plat/common/include/x86/cpu.h b/plat/common/include/x86/cpu.h
> index 5f1a35e4..d4c02e08 100644
> --- a/plat/common/include/x86/cpu.h
> +++ b/plat/common/include/x86/cpu.h
> @@ -341,4 +341,19 @@ static inline void _init_syscall(void)
>  }
>  #endif /* CONFIG_HAVE_SYSCALL */
>  
> +#if CONFIG_HAVE_X86PKU
> +static inline void _check_ospke(void)
> +{
> +     __u32 eax, ebx, ecx, edx;
> +     cpuid(0x7, 0, &eax, &ebx, &ecx, &edx);
> +     if (!(ecx & X86_CPUID7_ECX_OSPKE)) {
> +             /* if PKU is not enabled, abort the boot process. Images
> +              * compiled with HAVE_X86PKU are *specialized* to be executed on
> +              * PKU-enabled hardware. This allows us to avoid checks later at
> +              * runtime. */
> +             UK_CRASH("CPU does not support PKU!\n");
> +     }
> +}
> +#endif /* CONFIG_HAVE_X86PKU */
> +
>  #endif /* __PLAT_COMMON_X86_CPU_H__ */
> diff --git a/plat/common/include/x86/cpu_defs.h 
> b/plat/common/include/x86/cpu_defs.h
> index dcbe2c65..74cff459 100644
> --- a/plat/common/include/x86/cpu_defs.h
> +++ b/plat/common/include/x86/cpu_defs.h
> @@ -71,6 +71,7 @@
>  #define X86_CR4_OSXMMEXCPT      (1 << 10)   /* OS support for FP exceptions 
> */
>  #define X86_CR4_FSGSBASE        (1 << 16)   /* enable FSGSBASE*/
>  #define X86_CR4_OSXSAVE         (1 << 18)   /* enable XSAVE, extended states 
> */
> +#define X86_CR4_PKE             (1 << 22)   /* enable protection keys */
>  
>  /*
>   * Intel CPU features in EFER
> @@ -86,6 +87,8 @@
>  #define X86_CPUID1_EDX_SSE      (1 << 25)
>  /* CPUID feature bits in EBX and ECX when EAX=7, ECX=0 */
>  #define X86_CPUID7_EBX_FSGSBASE (1 << 0)
> +#define X86_CPUID7_ECX_PKU   (1 << 3)
> +#define X86_CPUID7_ECX_OSPKE (1 << 4)
>  /* CPUID feature bits when EAX=0xd, ECX=1 */
>  #define X86_CPUIDD1_EAX_XSAVEOPT (1<<0)
>  /* CPUID 80000001H:EDX feature list */
> diff --git a/plat/kvm/x86/entry64.S b/plat/kvm/x86/entry64.S
> index 169f4c82..ef5e0e77 100644
> --- a/plat/kvm/x86/entry64.S
> +++ b/plat/kvm/x86/entry64.S
> @@ -31,6 +31,9 @@
>  #include <kvm-x86/traps.h>
>  #include <kvm-x86/multiboot_defs.h>
>  
> +/* necessary for CONFIG_ macros to be accessible */
> +#include <uk/config.h>
> +
>  #define ENTRY(x) .globl x; .type x,%function; x:
>  #define END(x)   .size x, . - x
>  
> @@ -227,6 +230,15 @@ noxsave:
>       orl $(X86_CR4_FSGSBASE), %edi
>       movq %rdi, %cr4
>  nofsgsbase:
> +#if CONFIG_HAVE_X86PKU
> +     /* check for Memory Protection Keys (PKU) */
> +     testl $(X86_CPUID7_ECX_PKU), %ecx
> +     jz nopku
> +     /* if PKU is supported, enable it via CR4 */
> +     orl $(X86_CR4_PKE), %edi
> +     movq %rdi, %cr4
> +nopku:
> +#endif /* CONFIG_HAVE_X86PKU */
>       /* done setting up CPU capabilities */
>  
>       /* read multiboot info pointer */
> diff --git a/plat/kvm/x86/setup.c b/plat/kvm/x86/setup.c
> index 284ec793..e8c44a93 100644
> --- a/plat/kvm/x86/setup.c
> +++ b/plat/kvm/x86/setup.c
> @@ -329,6 +329,10 @@ void _libkvmplat_entry(void *arg)
>       _init_syscall();
>  #endif /* CONFIG_HAVE_SYSCALL */
>  
> +#if CONFIG_HAVE_X86PKU
> +     _check_ospke();
> +#endif /* CONFIG_HAVE_X86PKU */
> +
>       /*
>        * Switch away from the bootstrap stack as early as possible.
>        */
> -- 
> 2.20.1
> 
> 

-- 
                Hugo Lefeuvre (hle)    |    www.owl.eu.com
RSA4096_ 360B 03B3 BF27 4F4D 7A3F D5E8 14AA 1EB8 A247 3DFD
ed25519_ 37B2 6D38 0B25 B8A2 6B9F 3A65 A36F 5357 5F2D DC4C



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.