blob: c4448cad904fd54eab7158ff130061459a0e2681 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <sys/mman.h>
#include "partition_alloc/aarch64_support.h"
#include "partition_alloc/build_config.h"
#include "partition_alloc/page_allocator.h"
#include "partition_alloc/partition_alloc_base/cpu.h"
#include "partition_alloc/partition_alloc_base/notreached.h"
#include "partition_alloc/partition_alloc_buildflags.h"
// PA_PROT_BTI requests a page that supports BTI landing pads.
#define PA_PROT_BTI 0x10
// PA_PROT_MTE requests a page that's suitable for memory tagging.
#define PA_PROT_MTE 0x20
namespace partition_alloc::internal {
namespace {
int GetAccessFlags(PageAccessibilityConfiguration accessibility,
bool mte_enabled,
bool bti_enabled) {
switch (accessibility.permissions) {
case PageAccessibilityConfiguration::kRead:
return PROT_READ;
case PageAccessibilityConfiguration::kReadWriteTagged:
return PROT_READ | PROT_WRITE | (mte_enabled ? PA_PROT_MTE : 0);
case PageAccessibilityConfiguration::kReadWrite:
return PROT_READ | PROT_WRITE;
case PageAccessibilityConfiguration::kReadExecuteProtected:
return PROT_READ | PROT_EXEC | (bti_enabled ? PA_PROT_BTI : 0);
case PageAccessibilityConfiguration::kReadExecute:
return PROT_READ | PROT_EXEC;
case PageAccessibilityConfiguration::kReadWriteExecute:
return PROT_READ | PROT_WRITE | PROT_EXEC;
case PageAccessibilityConfiguration::kReadWriteExecuteProtected:
return PROT_READ | PROT_WRITE | PROT_EXEC |
(bti_enabled ? PA_PROT_BTI : 0);
case PageAccessibilityConfiguration::kInaccessible:
case PageAccessibilityConfiguration::kInaccessibleWillJitLater:
return PROT_NONE;
}
}
template <bool MteEnabled, bool BtiEnabled>
int GetAccessFlags(PageAccessibilityConfiguration accessibility) {
return GetAccessFlags(accessibility, MteEnabled, BtiEnabled);
}
} // namespace
using GetAccessFlagsInternalFn = int(PageAccessibilityConfiguration);
extern "C" GetAccessFlagsInternalFn* ResolveGetAccessFlags(
uint64_t hwcap,
struct __ifunc_arg_t* hw) {
if (IsMteEnabled(hwcap, hw)) {
if (IsBtiEnabled(hwcap, hw)) {
return GetAccessFlags<true, true>;
} else {
return GetAccessFlags<true, false>;
}
} else {
if (IsBtiEnabled(hwcap, hw)) {
return GetAccessFlags<false, true>;
} else {
return GetAccessFlags<false, false>;
}
}
}
// Resolve the implementation for GetAccessFlags using an iFunc.
int GetAccessFlags(PageAccessibilityConfiguration accessibility)
__attribute__((ifunc("ResolveGetAccessFlags")));
} // namespace partition_alloc::internal