diff options
author | Xiao Guangrong <guangrong.xiao@linux.intel.com> | 2016-03-22 16:51:17 +0800 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-03-22 16:21:05 +0100 |
commit | 9e90199c25aec31b4509213881511948f6c763c8 (patch) | |
tree | e2cf6063637ff350c97664d1f1fc4075584b67f4 /arch/x86/include | |
parent | 17a511f878505d31f298de443269b3070c134163 (diff) | |
download | linux-9e90199c25aec31b4509213881511948f6c763c8.tar.gz linux-9e90199c25aec31b4509213881511948f6c763c8.tar.bz2 linux-9e90199c25aec31b4509213881511948f6c763c8.zip |
x86: pkey: introduce write_pkru() for KVM
KVM will use it to switch pkru between guest and host.
CC: Ingo Molnar <mingo@redhat.com>
CC: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
Signed-off-by: Huaitong Han <huaitong.han@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/include')
-rw-r--r-- | arch/x86/include/asm/pgtable.h | 6 | ||||
-rw-r--r-- | arch/x86/include/asm/special_insns.h | 16 |
2 files changed, 22 insertions, 0 deletions
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 1ff49ec29ece..97f3242e133c 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -107,6 +107,12 @@ static inline u32 read_pkru(void) return 0; } +static inline void write_pkru(u32 pkru) +{ + if (boot_cpu_has(X86_FEATURE_OSPKE)) + __write_pkru(pkru); +} + static inline int pte_young(pte_t pte) { return pte_flags(pte) & _PAGE_ACCESSED; diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index aee6e76e561e..d96d04377765 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h @@ -113,11 +113,27 @@ static inline u32 __read_pkru(void) : "c" (ecx)); return pkru; } + +static inline void __write_pkru(u32 pkru) +{ + u32 ecx = 0, edx = 0; + + /* + * "wrpkru" instruction. Loads contents in EAX to PKRU, + * requires that ecx = edx = 0. + */ + asm volatile(".byte 0x0f,0x01,0xef\n\t" + : : "a" (pkru), "c"(ecx), "d"(edx)); +} #else static inline u32 __read_pkru(void) { return 0; } + +static inline void __write_pkru(u32 pkru) +{ +} #endif static inline void native_wbinvd(void) |