| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
 Re: [UNIKRAFT PATCH v2 1/4] plat/kvm: toggle PKE bit if HAVE_X86PKU is enabled
 
 În vin., 11 dec. 2020 la 18:35, Hugo Lefeuvre <hle@xxxxxxxxxx > a scris:Provided that PKU is advertised by cpuid (EAX=7, ECX=0, ECX bit 4),Memory Protection Keys can be enabled by setting bit 22 (PKE) in CR4
 (see Intel 64 and IA-32 Architectures Software Developer's Manual Vol.
 3A, Section 2.5 'Control Registers').
 
 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
 
 
 
 |