From d45193874e465b0a6f6f0b54e6b55e400eaa331d Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Sun, 3 Oct 2021 18:02:32 +0530 Subject: [PATCH] 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. --- app/src/main/cpp/skyline/services/nvdrv/driver.cpp | 14 +++++++------- app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/cpp/skyline/services/nvdrv/driver.cpp b/app/src/main/cpp/skyline/services/nvdrv/driver.cpp index dd564e8c..010c737f 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/driver.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/driver.cpp @@ -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); } } } diff --git a/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp b/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp index e1d5883d..bf32f1c4 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp +++ b/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp @@ -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) {