brintos

brintos / llvm-project-archived public Read only

0
0
Text · 1.7 KiB · cb65775 Raw
62 lines · c
1//===---------- x86_64-specific implementations for pkey_{get,set}. -------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_SYS_MMAN_LINUX_X86_64_PKEY_COMMON_H_10#define LLVM_SYS_MMAN_LINUX_X86_64_PKEY_COMMON_H_11 12#include <immintrin.h>13 14#include "hdr/errno_macros.h" // For ENOSYS15#include "hdr/stdint_proxy.h"16#include "src/__support/common.h"17#include "src/__support/error_or.h"18 19#if !defined(LIBC_TARGET_ARCH_IS_X86_64)20#error "Invalid include"21#endif22 23namespace LIBC_NAMESPACE_DECL {24namespace pkey_common {25 26constexpr int KEY_COUNT = 16;27constexpr int KEY_MASK = 0x3;28constexpr int BITS_PER_KEY = 2;29 30// x86_64 implementation of pkey_get.31// Returns the access rights for the given pkey on success, errno otherwise.32[[gnu::target("pku")]]33LIBC_INLINE ErrorOr<int> pkey_get(int pkey) {34  if (pkey < 0 || pkey >= KEY_COUNT) {35    return Error(EINVAL);36  }37 38  uint32_t pkru = _rdpkru_u32();39  return (pkru >> (pkey * BITS_PER_KEY)) & KEY_MASK;40}41 42// x86_64 implementation of pkey_set.43// Returns 0 on success, errno otherwise.44[[gnu::target("pku")]]45LIBC_INLINE ErrorOr<int> pkey_set(int pkey, unsigned int access_rights) {46  if (pkey < 0 || pkey >= KEY_COUNT || access_rights > KEY_MASK) {47    return Error(EINVAL);48  }49 50  uint32_t pkru = _rdpkru_u32();51  pkru &= ~(KEY_MASK << (pkey * BITS_PER_KEY));52  pkru |= ((access_rights & KEY_MASK) << (pkey * BITS_PER_KEY));53  _wrpkru(pkru);54 55  return 0;56}57 58} // namespace pkey_common59} // namespace LIBC_NAMESPACE_DECL60 61#endif // LLVM_SYS_MMAN_LINUX_X86_64_PKEY_COMMON_H_62