mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-07 13:39:55 +00:00
test(agc): check the stamps of a store into partly watched memory
A driver store and an own store across a watched block and an unwatched one must stamp the watched block and no other. On Linux, a store across the halves of a split block must stamp it, and a store into its unwatched half alone must not.
This commit is contained in:
1 parent
ae920cb206
commit
7fc9e201df
1 file changed
+34
@@ -280,6 +280,39 @@ void CheckNewestStamp() {
|
||||
Require(NewestStamp(base + 3 * Block - 8, Block + 8) > partial, "a CPU store into the watched part of a partly watched range did not advance its stamp");
|
||||
}
|
||||
|
||||
void CheckPartlyWatchedStore() {
|
||||
void* memory = AllocateWatched(3 * Block);
|
||||
const auto base = reinterpret_cast<std::uint64_t>(memory);
|
||||
const auto stored = base + Block;
|
||||
const auto unwatched = base + 2 * Block;
|
||||
std::memset(memory, 0x11, 3 * Block);
|
||||
BumpCollectEpoch();
|
||||
Unwatch(unwatched, Block);
|
||||
const auto before = CollectWrites(base, 2 * Block);
|
||||
Require(before != 0 && UnchangedSince(base, 2 * Block, before), "the watched blocks were not collected");
|
||||
Require(MarkWritten(unwatched - 64, 128) == 0, "a driver store into partly watched memory is trusted");
|
||||
Require(!UnchangedSince(stored, Block, before), "a driver store into partly watched memory left its watched block unchanged");
|
||||
Require(StoredOver(unwatched - 64, 64, before), "a driver store into partly watched memory is not seen over its watched bytes");
|
||||
Require(!StoredOver(stored, Block - 64, before), "a driver store into partly watched memory is seen over watched bytes it did not store");
|
||||
Require(UnchangedSince(base, Block, before), "a driver store into partly watched memory stamped a block it did not store into");
|
||||
const auto beforeOwn = TrackerGeneration();
|
||||
Require(StoreOwnBytes(unwatched - 64, 128, [&] { std::memset(reinterpret_cast<void*>(unwatched - 64), 0x22, 128); }) == 0, "an own store into partly watched memory is trusted");
|
||||
Require(!UnchangedSince(stored, Block, beforeOwn), "an own store into partly watched memory left its watched block unchanged");
|
||||
Require(UnchangedSince(base, Block, beforeOwn), "an own store into partly watched memory stamped a block it did not store into");
|
||||
#ifndef _WIN32
|
||||
void* split = AllocateWatched(Block);
|
||||
const auto splitBase = reinterpret_cast<std::uint64_t>(split);
|
||||
const auto watchedHalf = splitBase + Block / 2;
|
||||
std::memset(split, 0x11, Block);
|
||||
Unwatch(splitBase, Block / 2);
|
||||
const auto beforeSplit = CollectWrites(watchedHalf, Block / 2);
|
||||
Require(beforeSplit != 0 && UnchangedSince(watchedHalf, Block / 2, beforeSplit), "the watched half of a split block was not collected");
|
||||
Require(MarkWritten(splitBase + 64, 128) == 0 && UnchangedSince(watchedHalf, Block / 2, beforeSplit), "a driver store into the unwatched half of a split block stamped its watched half");
|
||||
Require(MarkWritten(watchedHalf - 64, 128) == 0, "a driver store across the halves of a split block is trusted");
|
||||
Require(!UnchangedSince(watchedHalf, Block / 2, beforeSplit), "a driver store across the halves of a split block left its watched half unchanged");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void CheckDeferredSharedImports() {
|
||||
constexpr std::size_t bytes = 4 * Block;
|
||||
@@ -935,6 +968,7 @@ int main() {
|
||||
CheckOwnStore();
|
||||
CheckUnwatch();
|
||||
CheckNewestStamp();
|
||||
CheckPartlyWatchedStore();
|
||||
#ifdef _WIN32
|
||||
CheckDeferredSharedImports();
|
||||
CheckPrivateMappingReuse();
|
||||
|
||||
Reference in new issue
Block a user