Merge pull request #1479 from ogniK5377/nmap-revamped

Added error codes for nvmap
master
bunnei 2018-10-12 12:06:22 +07:00 committed by GitHub
commit dc328440c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 60 additions and 12 deletions

@ -11,6 +11,13 @@
namespace Service::Nvidia::Devices { namespace Service::Nvidia::Devices {
namespace NvErrCodes {
enum {
OperationNotPermitted = -1,
InvalidValue = -22,
};
}
nvmap::nvmap() = default; nvmap::nvmap() = default;
nvmap::~nvmap() = default; nvmap::~nvmap() = default;
@ -44,7 +51,11 @@ u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& o
u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
IocCreateParams params; IocCreateParams params;
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
if (!params.size) {
return static_cast<u32>(NvErrCodes::InvalidValue);
}
// Create a new nvmap object and obtain a handle to it. // Create a new nvmap object and obtain a handle to it.
auto object = std::make_shared<Object>(); auto object = std::make_shared<Object>();
object->id = next_id++; object->id = next_id++;
@ -55,8 +66,6 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
u32 handle = next_handle++; u32 handle = next_handle++;
handles[handle] = std::move(object); handles[handle] = std::move(object);
LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
params.handle = handle; params.handle = handle;
std::memcpy(output.data(), &params, sizeof(params)); std::memcpy(output.data(), &params, sizeof(params));
@ -66,9 +75,29 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
IocAllocParams params; IocAllocParams params;
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
if (!params.handle) {
return static_cast<u32>(NvErrCodes::InvalidValue);
}
if ((params.align - 1) & params.align) {
return static_cast<u32>(NvErrCodes::InvalidValue);
}
const u32 min_alignment = 0x1000;
if (params.align < min_alignment) {
params.align = min_alignment;
}
auto object = GetObject(params.handle); auto object = GetObject(params.handle);
ASSERT(object); if (!object) {
return static_cast<u32>(NvErrCodes::InvalidValue);
}
if (object->status == Object::Status::Allocated) {
return static_cast<u32>(NvErrCodes::OperationNotPermitted);
}
object->flags = params.flags; object->flags = params.flags;
object->align = params.align; object->align = params.align;
@ -76,8 +105,6 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
object->addr = params.addr; object->addr = params.addr;
object->status = Object::Status::Allocated; object->status = Object::Status::Allocated;
LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
std::memcpy(output.data(), &params, sizeof(params)); std::memcpy(output.data(), &params, sizeof(params));
return 0; return 0;
} }
@ -88,8 +115,14 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_WARNING(Service_NVDRV, "called"); LOG_WARNING(Service_NVDRV, "called");
if (!params.handle) {
return static_cast<u32>(NvErrCodes::InvalidValue);
}
auto object = GetObject(params.handle); auto object = GetObject(params.handle);
ASSERT(object); if (!object) {
return static_cast<u32>(NvErrCodes::OperationNotPermitted);
}
params.id = object->id; params.id = object->id;
@ -105,7 +138,14 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) {
auto itr = std::find_if(handles.begin(), handles.end(), auto itr = std::find_if(handles.begin(), handles.end(),
[&](const auto& entry) { return entry.second->id == params.id; }); [&](const auto& entry) { return entry.second->id == params.id; });
ASSERT(itr != handles.end()); if (itr == handles.end()) {
return static_cast<u32>(NvErrCodes::InvalidValue);
}
auto& object = itr->second;
if (object->status != Object::Status::Allocated) {
return static_cast<u32>(NvErrCodes::InvalidValue);
}
itr->second->refcount++; itr->second->refcount++;
@ -125,8 +165,13 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param); LOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param);
auto object = GetObject(params.handle); auto object = GetObject(params.handle);
ASSERT(object); if (!object) {
ASSERT(object->status == Object::Status::Allocated); return static_cast<u32>(NvErrCodes::InvalidValue);
}
if (object->status != Object::Status::Allocated) {
return static_cast<u32>(NvErrCodes::OperationNotPermitted);
}
switch (static_cast<ParamTypes>(params.param)) { switch (static_cast<ParamTypes>(params.param)) {
case ParamTypes::Size: case ParamTypes::Size:
@ -163,9 +208,12 @@ u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called"); LOG_WARNING(Service_NVDRV, "(STUBBED) called");
auto itr = handles.find(params.handle); auto itr = handles.find(params.handle);
ASSERT(itr != handles.end()); if (itr == handles.end()) {
return static_cast<u32>(NvErrCodes::InvalidValue);
ASSERT(itr->second->refcount > 0); }
if (!itr->second->refcount) {
return static_cast<u32>(NvErrCodes::InvalidValue);
}
itr->second->refcount--; itr->second->refcount--;