Fix NvDrv Bugs + NACP Parsing Bug

A hotfix for a nvdrv bug where an IOCTL with no input/output buffers would crash and a major `nvmap` bug which broke the `FromId` IOCTL as it didn't write back the handle ID, another minor bug existed in `nvhost` where the `ZCullGetInfo` IOCTL was `INOUT` rather than `OUT`.

A bug with NACPs was also fixed caused by incorrect padding for the `NacpData` structure which resulted in the `saveDataOwnerId` member being read incorrectly and as a result the save data folder being incorrect.

Co-authored-by: artem8086 <artemsvyatoha@gmail.com>
This commit is contained in:
PixelyIon 2021-10-02 00:15:53 +05:30
parent afc3dda1ee
commit 02bcf98b8c
4 changed files with 11 additions and 7 deletions

View File

@ -59,7 +59,7 @@ namespace skyline::service::nvdrv {
auto fd{request.Pop<FileDescriptor>()}; auto fd{request.Pop<FileDescriptor>()};
auto ioctl{request.Pop<IoctlDescriptor>()}; auto ioctl{request.Pop<IoctlDescriptor>()};
auto buf{GetMainIoctlBuffer(ioctl, request.inputBuf.at(0), request.outputBuf.at(0))}; auto buf{GetMainIoctlBuffer(ioctl, !request.inputBuf.empty() ? request.inputBuf.at(0) : span<u8>{}, !request.outputBuf.empty() ? request.outputBuf.at(0) : span<u8>{})};
if (!buf) if (!buf)
return NVRESULT(buf); return NVRESULT(buf);
else else
@ -104,7 +104,7 @@ namespace skyline::service::nvdrv {
// Inline buffer is optional // Inline buffer is optional
auto inlineBuf{request.inputBuf.size() > 1 ? request.inputBuf.at(1) : span<u8>{}}; auto inlineBuf{request.inputBuf.size() > 1 ? request.inputBuf.at(1) : span<u8>{}};
auto buf{GetMainIoctlBuffer(ioctl, request.inputBuf.at(0), request.outputBuf.at(0))}; auto buf{GetMainIoctlBuffer(ioctl, !request.inputBuf.empty() ? request.inputBuf.at(0) : span<u8>{}, !request.outputBuf.empty() ? request.outputBuf.at(0) : span<u8>{})};
if (!buf) if (!buf)
return NVRESULT(buf); return NVRESULT(buf);
else else
@ -118,7 +118,7 @@ namespace skyline::service::nvdrv {
// Inline buffer is optional // Inline buffer is optional
auto inlineBuf{request.outputBuf.size() > 1 ? request.outputBuf.at(1) : span<u8>{}}; auto inlineBuf{request.outputBuf.size() > 1 ? request.outputBuf.at(1) : span<u8>{}};
auto buf{GetMainIoctlBuffer(ioctl, request.inputBuf.at(0), request.outputBuf.at(0))}; auto buf{GetMainIoctlBuffer(ioctl, !request.inputBuf.empty() ? request.inputBuf.at(0) : span<u8>{}, !request.outputBuf.empty() ? request.outputBuf.at(0) : span<u8>{})};
if (!buf) if (!buf)
return NVRESULT(buf); return NVRESULT(buf);
else else

View File

@ -68,7 +68,7 @@ namespace skyline::service::nvdrv::device::nvhost {
IOCTL_HANDLER_FUNC(CtrlGpu, ({ IOCTL_HANDLER_FUNC(CtrlGpu, ({
IOCTL_CASE_ARGS(OUT, SIZE(0x4), MAGIC(CtrlGpuMagic), FUNC(0x1), IOCTL_CASE_ARGS(OUT, SIZE(0x4), MAGIC(CtrlGpuMagic), FUNC(0x1),
ZCullGetCtxSize, ARGS(Out<u32>)) ZCullGetCtxSize, ARGS(Out<u32>))
IOCTL_CASE_ARGS(INOUT, SIZE(0x28), MAGIC(CtrlGpuMagic), FUNC(0x2), IOCTL_CASE_ARGS(OUT, SIZE(0x28), MAGIC(CtrlGpuMagic), FUNC(0x2),
ZCullGetInfo, ARGS(Out<ZCullInfo>)) ZCullGetInfo, ARGS(Out<ZCullInfo>))
IOCTL_CASE_ARGS(INOUT, SIZE(0xB0), MAGIC(CtrlGpuMagic), FUNC(0x5), IOCTL_CASE_ARGS(INOUT, SIZE(0xB0), MAGIC(CtrlGpuMagic), FUNC(0x5),
GetCharacteristics, ARGS(InOut<u64>, In<u64>, Out<GpuCharacteristics>)) GetCharacteristics, ARGS(InOut<u64>, In<u64>, Out<GpuCharacteristics>))

View File

@ -31,7 +31,11 @@ namespace skyline::service::nvdrv::device {
if (!handleDesc) [[unlikely]] if (!handleDesc) [[unlikely]]
return PosixResult::InvalidArgument; return PosixResult::InvalidArgument;
return handleDesc->Duplicate(ctx.internalSession); auto result{handleDesc->Duplicate(ctx.internalSession)};
if (result == PosixResult::Success)
handle = id;
return result;
} }
PosixResult NvMap::Alloc(In<NvMapCore::Handle::Id> handle, In<u32> heapMask, In<NvMapCore::Handle::Flags> flags, InOut<u32> align, In<u8> kind, In<u64> address) { PosixResult NvMap::Alloc(In<NvMapCore::Handle::Id> handle, In<u32> heapMask, In<NvMapCore::Handle::Flags> flags, InOut<u32> align, In<u8> kind, In<u64> address) {

View File

@ -27,9 +27,9 @@ namespace skyline::vfs {
std::array<ApplicationTitle, 0x10> titleEntries; //!< Title entries for each language std::array<ApplicationTitle, 0x10> titleEntries; //!< Title entries for each language
u8 _pad0_[0x2C]; u8 _pad0_[0x2C];
u32 supportedLanguageFlag; //!< A bitmask containing the game's supported languages u32 supportedLanguageFlag; //!< A bitmask containing the game's supported languages
u8 _pad1_[0x78]; u8 _pad1_[0x48];
u64 saveDataOwnerId; //!< The ID that should be used for this application's savedata u64 saveDataOwnerId; //!< The ID that should be used for this application's savedata
u8 _pad2_[0x48]; u8 _pad2_[0x78];
std::array<u8, 8> seedForPseudoDeviceId; //!< Seed that is combined with the device seed for generating the pseudo-device ID std::array<u8, 8> seedForPseudoDeviceId; //!< Seed that is combined with the device seed for generating the pseudo-device ID
u8 _pad3_[0xF00]; u8 _pad3_[0xF00];
} nacpContents{}; } nacpContents{};