gpu: match complete NOP marker tags and ignore opaque payloads

Co-authored-by: Ali Almohaya <AliAlmohaya@gmail.com>
This commit is contained in:
nmzik 2026-10-13 04:04:19 +02:00
parent 31b7be9ff2
commit 717c54e085
2 changed files with 27 additions and 11 deletions

View File

@ -2142,27 +2142,23 @@ KYTY_CP_OP_PARSER(CpOpIndirectUcRegs) {
KYTY_CP_OP_PARSER(CpOpMarker) {
KYTY_PROFILER_FUNCTION();
// EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0001000);
uint32_t id = buffer[0] & 0xfffu;
uint32_t len_dw = ((cmd_id >> 16u) & 0x3fffu);
switch (id) {
case 0x0: break;
case 0x4: cp.SetUserDataMarker(HW::UserSgprType::Vsharp); break;
case 0xd: cp.SetUserDataMarker(HW::UserSgprType::Region); break;
case 0x777: {
switch (buffer[0]) {
case 0x68750004: cp.SetUserDataMarker(HW::UserSgprType::Vsharp); break;
case 0x6875000d: cp.SetUserDataMarker(HW::UserSgprType::Region); break;
case 0x68750777: {
cp.Flip();
break;
}
case 0x778: {
case 0x68750778: {
auto* addr =
reinterpret_cast<void*>(buffer[1] | (static_cast<uint64_t>(buffer[2]) << 32u));
uint32_t value = buffer[3];
cp.Flip(addr, value);
break;
}
case 0x781: {
case 0x68750781: {
auto* addr =
reinterpret_cast<void*>(buffer[1] | (static_cast<uint64_t>(buffer[2]) << 32u));
uint32_t value = buffer[3];
@ -2171,7 +2167,8 @@ KYTY_CP_OP_PARSER(CpOpMarker) {
cp.FlipWithInterrupt(eop_event_type, cache_action, addr, value);
break;
}
default: EXIT("unknown marker at %05" PRIx32 ": 0x%" PRIx32 "\n", num_dw - dw, id);
// NOP payloads are caller-owned data; only complete known marker tags execute.
default: break;
}
return len_dw + 1;

View File

@ -44129,6 +44129,25 @@ void CheckPm4IndirectControlFlow(RenderContext &renderer) {
Gen5::AgcCbNop(reinterpret_cast<Gen5::CommandBuffer*>(&payload_dcb), 3) == payload.data() &&
payload == std::array<uint32_t, 3>{0xc0011000u, 0x12345678u, 0x9abcdef0u},
"NOP emitter overwrote the caller's reserved payload");
for (const uint32_t value : {0x68750820u, 0x68751777u, 0x68751004u}) {
std::array<uint32_t, 8> commands{KYTY_PM4(3, Pm4::IT_NOP, Pm4::R_ZERO), value, 0x12345678u};
std::copy(completion.begin(), completion.end(), commands.begin() + 3);
processor.SetUserDataMarker(HW::UserSgprType::Unknown);
selected = 0;
Pm4Execution execution;
Require(name, "opaque NOP payload",
processor.Process(execution, commands) == Pm4ProcessResult::Complete && selected == 7 &&
processor.GetUserDataMarker() == HW::UserSgprType::Unknown && commands[1] == value,
"a NOP payload prefix executed a marker or blocked the following packet");
}
const std::array<uint32_t, 2> vsharp_marker{
KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_ZERO), 0x68750004u};
Pm4Execution marker_execution;
Require(name, "exact user-data marker",
processor.Process(marker_execution, vsharp_marker) == Pm4ProcessResult::Complete &&
processor.GetUserDataMarker() == HW::UserSgprType::Vsharp,
"exact marker dispatch lost the existing user-data annotation");
processor.SetUserDataMarker(HW::UserSgprType::Unknown);
alignas(8) uint64_t released = 0;
std::array<uint32_t, 20> disabled_commands{};
const auto disabled_write = write(&returned, 99);