File Index
Files and directories
Sign in
FILE

smap.h

File preview with syntax highlighting.

linux-6.19.14/arch/x86/include/asm/smap.h C
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Supervisor Mode Access Prevention support
  4 *
  5 * Copyright (C) 2012 Intel Corporation
  6 * Author: H. Peter Anvin <hpa@linux.intel.com>
  7 */
  8
  9#ifndef _ASM_X86_SMAP_H
 10#define _ASM_X86_SMAP_H
 11
 12#include <asm/nops.h>
 13#include <asm/cpufeatures.h>
 14#include <asm/alternative.h>
 15
 16#ifdef __ASSEMBLER__
 17
 18#define ASM_CLAC \
 19	ALTERNATIVE "", "clac", X86_FEATURE_SMAP
 20
 21#define ASM_STAC \
 22	ALTERNATIVE "", "stac", X86_FEATURE_SMAP
 23
 24#else /* __ASSEMBLER__ */
 25
 26/*
 27 * The CLAC/STAC instructions toggle the enforcement of
 28 * X86_FEATURE_SMAP along with X86_FEATURE_LASS.
 29 *
 30 * SMAP enforcement is based on the _PAGE_BIT_USER bit in the page
 31 * tables. The kernel is not allowed to touch pages with that bit set
 32 * unless the AC bit is set.
 33 *
 34 * Use stac()/clac() when accessing userspace (_PAGE_USER) mappings,
 35 * regardless of location.
 36 *
 37 * Note: a barrier is implicit in alternative().
 38 */
 39
 40static __always_inline void clac(void)
 41{
 42	alternative("", "clac", X86_FEATURE_SMAP);
 43}
 44
 45static __always_inline void stac(void)
 46{
 47	alternative("", "stac", X86_FEATURE_SMAP);
 48}
 49
 50/*
 51 * LASS enforcement is based on bit 63 of the virtual address. The
 52 * kernel is not allowed to touch memory in the lower half of the
 53 * virtual address space.
 54 *
 55 * Use lass_stac()/lass_clac() to toggle the AC bit for kernel data
 56 * accesses (!_PAGE_USER) that are blocked by LASS, but not by SMAP.
 57 *
 58 * Even with the AC bit set, LASS will continue to block instruction
 59 * fetches from the user half of the address space. To allow those,
 60 * clear CR4.LASS to disable the LASS mechanism entirely.
 61 *
 62 * Note: a barrier is implicit in alternative().
 63 */
 64
 65static __always_inline void lass_clac(void)
 66{
 67	alternative("", "clac", X86_FEATURE_LASS);
 68}
 69
 70static __always_inline void lass_stac(void)
 71{
 72	alternative("", "stac", X86_FEATURE_LASS);
 73}
 74
 75static __always_inline unsigned long smap_save(void)
 76{
 77	unsigned long flags;
 78
 79	asm volatile ("# smap_save\n\t"
 80		      ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "\n\t"
 81				  "", "pushf; pop %0; clac",
 82				  X86_FEATURE_SMAP)
 83		      : "=rm" (flags) : : "memory", "cc");
 84
 85	return flags;
 86}
 87
 88static __always_inline void smap_restore(unsigned long flags)
 89{
 90	asm volatile ("# smap_restore\n\t"
 91		      ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "\n\t"
 92				  "", "push %0; popf",
 93				  X86_FEATURE_SMAP)
 94		      : : "g" (flags) : "memory", "cc");
 95}
 96
 97/* These macros can be used in asm() statements */
 98#define ASM_CLAC \
 99	ALTERNATIVE("", "clac", X86_FEATURE_SMAP)
100#define ASM_STAC \
101	ALTERNATIVE("", "stac", X86_FEATURE_SMAP)
102
103#define ASM_CLAC_UNSAFE \
104	ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "\n\t" "clac", X86_FEATURE_SMAP)
105#define ASM_STAC_UNSAFE \
106	ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "\n\t" "stac", X86_FEATURE_SMAP)
107
108#endif /* __ASSEMBLER__ */
109
110#endif /* _ASM_X86_SMAP_H */
~/ Read-only file preview.