2019-06-01 10:08:55 +02:00
/* SPDX-License-Identifier: GPL-2.0-only */
2012-09-21 12:43:10 -07:00
/*
* Supervisor Mode Access Prevention support
*
* Copyright ( C ) 2012 Intel Corporation
* Author : H . Peter Anvin < hpa @ linux . intel . com >
*/
# ifndef _ASM_X86_SMAP_H
# define _ASM_X86_SMAP_H
# include <asm/nops.h>
2016-01-26 22:12:04 +01:00
# include <asm/cpufeatures.h>
2021-03-11 15:23:06 +01:00
# include <asm/alternative.h>
2012-09-21 12:43:10 -07:00
/* "Raw" instruction opcodes */
2019-03-07 14:44:44 +01:00
# define __ASM_CLAC ".byte 0x0f,0x01,0xca"
# define __ASM_STAC ".byte 0x0f,0x01,0xcb"
2012-09-21 12:43:10 -07:00
# ifdef __ASSEMBLY__
2015-01-15 09:17:12 +01:00
# define ASM_CLAC \
2019-03-07 14:44:44 +01:00
ALTERNATIVE " " , __ASM_CLAC , X86_FEATURE_SMAP
2015-01-15 09:17:12 +01:00
# define ASM_STAC \
2019-03-07 14:44:44 +01:00
ALTERNATIVE " " , __ASM_STAC , X86_FEATURE_SMAP
2012-09-21 12:43:10 -07:00
# else /* __ASSEMBLY__ */
2012-09-21 12:43:12 -07:00
static __always_inline void clac ( void )
2012-09-21 12:43:10 -07:00
{
/* Note: a barrier is implicit in alternative() */
2019-03-07 14:44:44 +01:00
alternative ( " " , __ASM_CLAC , X86_FEATURE_SMAP ) ;
2012-09-21 12:43:10 -07:00
}
2012-09-21 12:43:12 -07:00
static __always_inline void stac ( void )
2012-09-21 12:43:10 -07:00
{
/* Note: a barrier is implicit in alternative() */
2019-03-07 14:44:44 +01:00
alternative ( " " , __ASM_STAC , X86_FEATURE_SMAP ) ;
2012-09-21 12:43:10 -07:00
}
2019-04-03 09:39:48 +02:00
static __always_inline unsigned long smap_save ( void )
{
unsigned long flags ;
2020-04-28 19:57:59 +02:00
asm volatile ( " # smap_save \n \t "
2021-03-08 15:46:04 +01:00
ALTERNATIVE ( " " , " pushf; pop %0; " __ASM_CLAC " \n \t " ,
X86_FEATURE_SMAP )
2019-04-03 09:39:48 +02:00
: " =rm " ( flags ) : : " memory " , " cc " ) ;
return flags ;
}
static __always_inline void smap_restore ( unsigned long flags )
{
2020-04-28 19:57:59 +02:00
asm volatile ( " # smap_restore \n \t "
2021-03-08 15:46:04 +01:00
ALTERNATIVE ( " " , " push %0; popf \n \t " ,
X86_FEATURE_SMAP )
2019-04-03 09:39:48 +02:00
: : " g " ( flags ) : " memory " , " cc " ) ;
}
2012-09-21 12:43:10 -07:00
/* These macros can be used in asm() statements */
# define ASM_CLAC \
2019-03-07 14:44:44 +01:00
ALTERNATIVE ( " " , __ASM_CLAC , X86_FEATURE_SMAP )
2012-09-21 12:43:10 -07:00
# define ASM_STAC \
2019-03-07 14:44:44 +01:00
ALTERNATIVE ( " " , __ASM_STAC , X86_FEATURE_SMAP )
2012-09-21 12:43:10 -07:00
# endif /* __ASSEMBLY__ */
# endif /* _ASM_X86_SMAP_H */