Fix NvDrv CloseDevice Bug

The unique pointer to a device in the map was simply reset rather than deleting the entry from the map, this resulted in the device not being properly closed and when the device was reopened then the `emplace` was a NOP as the entry already existed. This resulted in a `nullptr` dereference down the line when an application attempted to issue an IOCTL to a device that was previously closed and reopened. This is known to occur in Deko3D as it recreates the context when loading an example which includes closing and reopening devices.
This commit is contained in:
PixelyIon 2021-10-03 18:02:32 +05:30
parent 7a5ca19c0b
commit d45193874e
2 changed files with 8 additions and 8 deletions

View File

@ -31,14 +31,14 @@ namespace skyline::service::nvdrv {
DEVICE_SWITCH(
DEVICE_CASE("/dev/nvmap", NvMap)
DEVICE_CASE("/dev/nvhost-ctrl", nvhost::Ctrl)
);
)
if (ctx.perms.AccessGpu) {
DEVICE_SWITCH(
DEVICE_CASE("/dev/nvhost-as-gpu", nvhost::AsGpu)
DEVICE_CASE("/dev/nvhost-ctrl-gpu", nvhost::CtrlGpu)
DEVICE_CASE("/dev/nvhost-gpu", nvhost::GpuChannel)
);
)
}
#undef DEVICE_CASE
@ -78,7 +78,7 @@ namespace skyline::service::nvdrv {
try {
return ConvertResult(devices.at(fd)->Ioctl(cmd, buffer));
} catch (const std::out_of_range &) {
throw exception("Ioctl was called with invalid file descriptor: 0x{:X}", fd);
throw exception("Ioctl was called with invalid file descriptor: {}", fd);
}
}
@ -98,15 +98,15 @@ namespace skyline::service::nvdrv {
try {
return ConvertResult(devices.at(fd)->Ioctl3(cmd, buffer, inlineBuffer));
} catch (const std::out_of_range &) {
throw exception("Ioctl3 was called with invalid file descriptor: 0x{:X}", fd);
throw exception("Ioctl3 was called with invalid file descriptor: {}", fd);
}
}
void Driver::CloseDevice(u32 fd) {
try {
devices.at(fd).reset();
devices.erase(fd);
} catch (const std::out_of_range &) {
state.logger->Warn("Trying to close non-existent FD");
state.logger->Warn("Trying to close non-existent file descriptor: {}");
}
}
@ -116,7 +116,7 @@ namespace skyline::service::nvdrv {
try {
return devices.at(fd)->QueryEvent(eventId);
} catch (const std::exception &) {
throw exception("QueryEvent was called with invalid file descriptor: 0x{:X}", fd);
throw exception("QueryEvent was called with invalid file descriptor: {}", fd);
}
}
}

View File

@ -154,7 +154,7 @@ namespace skyline::soc::gm20b {
try {
signal::SetSignalHandler({SIGINT, SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV}, signal::ExceptionalSignalHandler);
pushBuffers->Process([this](GpEntry gpEntry) {
state.logger->Warn("Processing pushbuffer: 0x{:X}", gpEntry.Address());
state.logger->Debug("Processing pushbuffer: 0x{:X}", gpEntry.Address());
Process(gpEntry);
});
} catch (const signal::SignalException &e) {