Skip to content

Commit

Permalink
PartitionPage: Add direct map tag member
Browse files Browse the repository at this point in the history
Direct map buckets (and the associated super pages) do not need nearly
as many tags as normal buckets. Rather than upend the general structure
of direct map extents, we elect to stuff tags for MTECheckedPtr (when
used on direct map reservations) into the `SubsequentPageMetadata`
struct instead.

This CL also trivially renames `mtecheckedptr.md` to
`raw_ptr_mtecheckedptr.md` to bring it under the ownership of the
MiraclePtr OWNERS.

Bug: 1307514
Change-Id: I3dc9adbbddf4c90ec01bfc06164c75e1507a88f5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3809714
Reviewed-by: Francois Pierre Doray <fdoray@chromium.org>
Reviewed-by: Bartek Nowierski <bartekn@chromium.org>
Commit-Queue: Kalvin Lee <kdlee@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1033349}
  • Loading branch information
Kalvin Lee authored and Chromium LUCI CQ committed Aug 10, 2022
1 parent e6c490a commit e760b83
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
20 changes: 20 additions & 0 deletions base/allocator/partition_allocator/partition_page.h
Expand Up @@ -25,6 +25,7 @@
#include "base/allocator/partition_allocator/partition_bucket.h"
#include "base/allocator/partition_allocator/partition_freelist_entry.h"
#include "base/allocator/partition_allocator/partition_tag_bitmap.h"
#include "base/allocator/partition_allocator/partition_tag_types.h"
#include "base/allocator/partition_allocator/reservation_offset_table.h"
#include "base/allocator/partition_allocator/starscan/state_bitmap.h"
#include "base/allocator/partition_allocator/tagging.h"
Expand Down Expand Up @@ -221,6 +222,10 @@ struct SlotSpanMetadata {
PA_ALWAYS_INLINE void SetRawSize(size_t raw_size);
PA_ALWAYS_INLINE size_t GetRawSize() const;

// Only meaningful when `this` refers to a slot span in a direct map
// bucket.
PA_ALWAYS_INLINE PartitionTag* DirectMapMTETag();

PA_ALWAYS_INLINE PartitionFreelistEntry* get_freelist_head() const {
return freelist_head;
}
Expand Down Expand Up @@ -334,6 +339,13 @@ struct SubsequentPageMetadata {
// the first one is used to store slot information, but the second one is
// available for extra information)
size_t raw_size;

// Specific to when `this` is used in a direct map bucket. Since direct
// maps don't have as many tags as the typical normal bucket slot span,
// we can get away with just hiding the sole tag in here.
//
// See `//base/memory/mtecheckedptr.md` for details.
PartitionTag direct_map_tag;
};

// Each partition page has metadata associated with it. The metadata of the
Expand Down Expand Up @@ -678,6 +690,14 @@ PA_ALWAYS_INLINE size_t SlotSpanMetadata<thread_safe>::GetRawSize() const {
return the_next_page->subsequent_page_metadata.raw_size;
}

template <bool thread_safe>
PA_ALWAYS_INLINE PartitionTag*
SlotSpanMetadata<thread_safe>::DirectMapMTETag() {
PA_DCHECK(bucket->is_direct_mapped());
auto* the_next_page = reinterpret_cast<PartitionPage<thread_safe>*>(this) + 1;
return &the_next_page->subsequent_page_metadata.direct_map_tag;
}

template <bool thread_safe>
PA_ALWAYS_INLINE void SlotSpanMetadata<thread_safe>::SetFreelistHead(
PartitionFreelistEntry* new_head) {
Expand Down
2 changes: 1 addition & 1 deletion base/allocator/partition_allocator/partition_tag_types.h
Expand Up @@ -8,7 +8,7 @@
#include <cstdint>

// This header defines the types for MTECheckedPtr. Canonical
// documentation available at `//base/memory/mtecheckedptr.md`.
// documentation available at `//base/memory/raw_ptr_mtecheckedptr.md`.

namespace partition_alloc {

Expand Down
Expand Up @@ -20,6 +20,14 @@ This is the brief version. Googlers can search internally for further
reading.
***

*** aside
MTECheckedPtr is one particular incarnation of `raw_ptr`, and so the
primary documentation is kept here in `//base/memory/`. However, the
implementation is woven deeply into PartitionAlloc, and inevitably
some dirty PA-internal details may bubble up here when discussing
how MTECheckedPtr works.
***

MTECheckedPtr is a Chromium-specific implementation of ARM's
[MTE concept][arm-mte]. When MTECheckedPtr is enabled,

Expand Down Expand Up @@ -84,4 +92,22 @@ When MTECheckedPtr *is* enabled (not the default for anybody),
both of the above degrade the `raw_ptr<T, D>` into the no-op version
of `raw_ptr`.

## Appendix: PA-Internal Tag Locations

[The top-level PartitionAlloc documentation][pa-readme]
mentions the space in which
MTECheckedPtr's tags reside - in the space labeled "Bitmaps(?)" in the
super page diagram, before the first usable slot span. This diagram
only applies to *normal* buckets and not to *direct map* buckets.

While direct map super pages also cordon off the first partition page
and offer access to the core metadata within, reservations are always
permissible immediately after, and there are no bitmaps (whether
from *Scan or MTECheckedPtr) following that first partition page.
In implementing MTECheckedPtr support for direct maps, we decided
not to add this extra headroom for bitmaps; instead, the tag is
placed directly in `SubsequentPageMetadata`, colocated with the core
metadata in the first partition page.

[arm-mte]: https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/enhancing-memory-safety
[pa-readme]: ../allocator/partition_allocator/PartitionAlloc.md#layout-in-memory

0 comments on commit e760b83

Please sign in to comment.