class ProtectedRangesCoreControl

Defined at line 227 of file ../../src/sysmem/server/protected_ranges.h

Interface used by ProtectedRanges to query properties and control lower-layer HW ranges. This

interface is sub-classed by ProtectedRangesControl which adds on UseRange() and UnUseRange().

The interfaces are separate because ProtectedRangesCoreControl and the methods added by

ProtectedRangesControl are implemented at different layers, and it's convenient for the lower

layer to only implement ProtectedRangesCoreControl not ProtectedRangesControl.

Public Methods

bool IsDynamic ()

True means calls to DelRange() and ModRange() are allowed, and more than one call to AddRange()

is allowed. False means only one call to AddRange() is allowed, and no other calls to

AddRange(), DelRange(), ModRage() will happen.

uint64_t MaxRangeCount ()

If !IsDynamic(), assumed to be 1.

uint64_t GetRangeGranularity ()

Still called even if !IsDynamic().

bool HasModProtectedRange ()

Only called if IsDynamic().

void AddProtectedRange (const Range & range)

AddProtectedRange (required)

If the system is too broken to add a range, ZX_PANIC() instead of returning. A hard reboot

will result (after which all ranges are cleared).

TODO(https://fxbug.dev/42178137): When possible, configure sysmem to trigger reboot on driver

remove.

Add a range, which may overlap with existing ranges, but which will have a unique (begin, end).

By the time this returns, the new range is usable. Any portions of this range which overlap

existing ranges must remain continuously usable during this call.

Outside of tests, this will pin the range and HW-protect the range.

Only called once if IsDynamic().

void DelProtectedRange (const Range & range)

DelProtectedRange (required)

Delete a range uniquely identified by its unique (begin, end). All portions of the range which

overlap with other extant ranges must remain continuously usable.

This is not allowed to fail. If the system is too broken to delete a protected range,

ZX_PANIC() instead of returning. A hard reboot will result (after which all ranges are

cleared).

TODO(https://fxbug.dev/42178137): When possible, configure sysmem to trigger reboot on driver

remove.

It is acceptable for the entire range to become unusable during delete iff any portion of the

range is not covered by any other range(s). This applies even if some of the range is also

covered by another range. This is to permit range permissions to be restricted while at least

1 byte of the range being deleted is being zeroed and the range is being deleted in HW.

Outside of tests, this will HW-deprotect the range and un-pin. Other ranges may still protect

some of the pages, in which case those pages will still have non-zero pin_count.

Never called if !IsDynamic().

void ModProtectedRange (const Range & old_range, const Range & new_range)

ModProtectedRange

If !HasModProtectedRange(), this won't get called ever and should not be overridden in the

sub-class. If HasModProtectedRange(), this can get called and must be overridden in the

sub-class.

Modify an old range to become a new range, identifying the old range by its unique (begin,

end).

The modification will only ever modify one end of the range at a time. In other words, either

old_range.begin() == new_range.begin(), or old_range.end() == new_range.end().

If the system is too broken to modify a range, ZX_PANIC() instead of returning. A hard reboot

will result (after which all ranges are cleared).

TODO(https://fxbug.dev/42178137): When possible, configure sysmem to trigger reboot on driver

remove.

If a range is being shortened, it is acceptable for the entire old range to become temporarily

unusable during the shortening iff any offsets no longer covered by this range are also not

covered by any other range. This is to permit range permissions to be restricted while the

portion being removed from the range is being zeroed by the TEE and the range is being

shortened in HW.

We only bother to use ModProtectedRange() (at this layer) when it makes the difference between

2 transient ranges and 1 transient ranges.

The securemem driver layer automatically uses range modification for any range deletion, to

ensure that we never zero too much per call to the TEE.

Outside of tests, this will pin the new range, modify the HW protection, and un-pin the old

range.

Never called if !IsDynamic() (or !HasModProtectedRange()).

Defined at line 317 of file ../../src/sysmem/server/protected_ranges.h

void ZeroProtectedSubRange (bool is_covering_range_explicit, const Range & range)

Zero a sub-range of a current range. The sub-range must be fully covered by exactly one

protected range, and not overlap with any other protected range.

Zero the newly requested range using the TEE. This way, any protected mode devices will see

the new buffer as filled with zeroes, instead of whatever REE-written zeroes might end up

looking like post-scramble. In testing situations we pretend as if this is allowed at

arbitrary granularity, but in actual use (so far) this will assert that range is aligned at

page boundaries (partly because that's the smallest zeroing granularity that the TEE allows, by

design).

We don't currently have the ability to temporarily de-protected a sub-range in order to zero

that sub-range outside the TEE. As necessary we could add that. However, that zeroing

wouldn't necessarily really be zeroing from the point of view of a device in protected mode

reading a page in the protected range due to some HW using a scramble. That zeroing however

would avoid any possibility of bits from a different collection ending up effectively sent

downstream of a decoder, for example. As long as we have actual zeroing of a protected

sub-range, let's just use that, since it's more rigorously actually logically zero and also

prevents any potential for mixing bits across collections.

Never called if !IsDynamic() (at least for now).