[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |