Fix minor inaccuracy with VMM and mutexes

This commit fixes a tiny inaccuracy with the VMM which was a problem with block insertion, The mutexes on the other hand had a minor issue regarding owner checks.
This commit is contained in:
◱ PixelyIon 2020-04-02 12:09:24 +05:30 committed by ◱ PixelyIon
parent 41ddaf7f33
commit f4968793b8
4 changed files with 16 additions and 25 deletions

View File

@ -93,6 +93,9 @@ namespace skyline::kernel {
} }
void MemoryManager::InsertBlock(ChunkDescriptor *chunk, const BlockDescriptor block) { void MemoryManager::InsertBlock(ChunkDescriptor *chunk, const BlockDescriptor block) {
if(chunk->address + chunk->size < block.address + block.size)
throw exception("InsertBlock: Inserting block past chunk end is not allowed");
for (auto iter = chunk->blockList.begin(); iter != chunk->blockList.end(); iter++) { for (auto iter = chunk->blockList.begin(); iter != chunk->blockList.end(); iter++) {
if (iter->address <= block.address) { if (iter->address <= block.address) {
if ((iter->address + iter->size) > block.address) { if ((iter->address + iter->size) > block.address) {
@ -107,25 +110,10 @@ namespace skyline::kernel {
iter->size = iter->address - block.address; iter->size = iter->address - block.address;
chunk->blockList.insert(std::next(iter), {block, endBlock}); chunk->blockList.insert(std::next(iter), {block, endBlock});
} }
} else if (std::next(iter) != chunk->blockList.end()) {
auto nextIter = std::next(iter);
auto nextEnd = nextIter->address + nextIter->size;
if(nextEnd > block.address) {
iter->size = block.address - iter->address;
nextIter->address = block.address + block.size;
nextIter->size = nextEnd - nextIter->address;
chunk->blockList.insert(nextIter, block);
} else {
throw exception("InsertBlock: Inserting block across more than one block is not allowed");
}
} else {
throw exception("InsertBlock: Inserting block with end past chunk end is not allowed");
}
return; return;
} }
} }
}
throw exception("InsertBlock: Block offset not present within current block list"); throw exception("InsertBlock: Block offset not present within current block list");
} }

View File

@ -503,7 +503,7 @@ namespace skyline::kernel::svc {
if (state.process->MutexLock(address, ownerHandle)) if (state.process->MutexLock(address, ownerHandle))
state.logger->Debug("svcArbitrateLock: Locked mutex at 0x{:X}", address); state.logger->Debug("svcArbitrateLock: Locked mutex at 0x{:X}", address);
else else
state.logger->Debug("svcArbitrateLock: Owner handle did not match current owner for mutex at 0x{:X}", address); state.logger->Debug("svcArbitrateLock: Owner handle did not match current owner for mutex or didn't have waiter flag at 0x{:X}", address);
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = constant::status::Success;
} }

View File

@ -85,7 +85,7 @@ namespace skyline::kernel::type {
Registers fregs{ Registers fregs{
.x0 = CLONE_THREAD | CLONE_SIGHAND | CLONE_PTRACE | CLONE_FS | CLONE_VM | CLONE_FILES | CLONE_IO, .x0 = CLONE_THREAD | CLONE_SIGHAND | CLONE_PTRACE | CLONE_FS | CLONE_VM | CLONE_FILES | CLONE_IO,
.x1 = stackTop, .x1 = stackTop,
.x3 = tlsMem->Map(0, size, memory::Permission{ true, true, false }), .x3 = tlsMem->Map(0, size, memory::Permission{true, true, false}),
.x8 = __NR_clone, .x8 = __NR_clone,
.x5 = reinterpret_cast<u64>(&guest::GuestEntry), .x5 = reinterpret_cast<u64>(&guest::GuestEntry),
.x6 = entryPoint, .x6 = entryPoint,
@ -203,10 +203,13 @@ namespace skyline::kernel::type {
auto mtx = GetPointer<u32>(address); auto mtx = GetPointer<u32>(address);
auto &mtxWaiters = mutexes[address]; auto &mtxWaiters = mutexes[address];
if (mtxWaiters.empty()) {
u32 mtxExpected = 0; u32 mtxExpected = 0;
if (__atomic_compare_exchange_n(mtx, &mtxExpected, (constant::MtxOwnerMask & state.thread->handle) | (mtxWaiters.empty() ? 0 : ~constant::MtxOwnerMask), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) if (__atomic_compare_exchange_n(mtx, &mtxExpected, (constant::MtxOwnerMask & state.thread->handle), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
return true; return true;
if (owner && (__atomic_load_n(mtx, __ATOMIC_SEQ_CST) != (owner | ~constant::MtxOwnerMask))) }
if (__atomic_load_n(mtx, __ATOMIC_SEQ_CST) != (owner | ~constant::MtxOwnerMask))
return false; return false;
std::shared_ptr<WaitStatus> status; std::shared_ptr<WaitStatus> status;
@ -245,7 +248,7 @@ namespace skyline::kernel::type {
u32 mtxExpected = (constant::MtxOwnerMask & state.thread->handle) | ~constant::MtxOwnerMask; u32 mtxExpected = (constant::MtxOwnerMask & state.thread->handle) | ~constant::MtxOwnerMask;
if (!__atomic_compare_exchange_n(mtx, &mtxExpected, mtxDesired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { if (!__atomic_compare_exchange_n(mtx, &mtxExpected, mtxDesired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
mtxExpected = constant::MtxOwnerMask & state.thread->handle; mtxExpected &= constant::MtxOwnerMask;
if (!__atomic_compare_exchange_n(mtx, &mtxExpected, mtxDesired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) if (!__atomic_compare_exchange_n(mtx, &mtxExpected, mtxDesired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
return false; return false;
@ -277,14 +280,15 @@ namespace skyline::kernel::type {
} }
lock.unlock(); lock.unlock();
bool timedOut{};
bool timedOut{};
auto start = utils::GetTimeNs(); auto start = utils::GetTimeNs();
while (!status->flag) while (!status->flag)
if ((utils::GetTimeNs() - start) >= timeout) if ((utils::GetTimeNs() - start) >= timeout)
timedOut = true; timedOut = true;
lock.lock(); lock.lock();
if (!status->flag) if (!status->flag)
timedOut = false; timedOut = false;
else else

View File

@ -30,6 +30,5 @@ class LicenseDialog : DialogFragment() {
license_url.text = libraryUrl license_url.text = libraryUrl
license_content.text = libraryLicense license_content.text = libraryLicense
license_content.movementMethod = ScrollingMovementMethod()
} }
} }