From dbce1a4c1d8a6b099bee5f5136622289349ff7f5 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 9 Jan 2021 00:55:11 +0700 Subject: [PATCH 1/3] Prevent access violation when running out of userMemory due to piling up AdhocMatching events. --- Core/HLE/proAdhoc.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 9e13eecf2388..5a0ec169a707 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1203,18 +1203,24 @@ void notifyAdhocctlHandlers(u32 flag, u32 error) { // Note: Must not lock peerlock within this function to prevent race-condition with other thread whos owning peerlock and trying to lock context->eventlock owned by this thread void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * msg, void * opt, u32_le &bufAddr, u32_le &bufLen, u32_le * args) { // Don't share buffer address space with other mipscall in the queue since mipscalls aren't immediately executed - MatchingArgs argsNew; + MatchingArgs argsNew = { 0 }; u32_le dataBufLen = msg->optlen + 8; //max(bufLen, msg->optlen + 8); u32_le dataBufAddr = userMemory.Alloc(dataBufLen); // We will free this memory after returning from mipscall uint8_t * dataPtr = Memory::GetPointer(dataBufAddr); - memcpy(dataPtr, &msg->mac, sizeof(msg->mac)); - if (msg->optlen > 0) - memcpy(dataPtr + 8, opt, msg->optlen); - argsNew.data[0] = context->id; - argsNew.data[1] = msg->opcode; - argsNew.data[2] = dataBufAddr; - argsNew.data[3] = msg->optlen; - argsNew.data[4] = dataBufAddr + 8; // OptData Addr + if (dataPtr) { + memcpy(dataPtr, &msg->mac, sizeof(msg->mac)); + if (msg->optlen > 0) + memcpy(dataPtr + 8, opt, msg->optlen); + + argsNew.data[1] = msg->opcode; + argsNew.data[2] = dataBufAddr; + argsNew.data[3] = msg->optlen; + argsNew.data[4] = dataBufAddr + 8; // OptData Addr + } + else { + argsNew.data[1] = PSP_ADHOC_MATCHING_EVENT_ERROR; // not sure where to put the error code for EVENT_ERROR tho + } + argsNew.data[0] = context->id; argsNew.data[5] = context->handler.entryPoint; //not part of callback argument, just borrowing a space to store callback address so i don't need to search the context first later // ScheduleEvent_Threadsafe_Immediate seems to get mixed up with interrupt (returning from mipscall inside an interrupt) and getting invalid address before returning from interrupt From 72549443e4d95ed8b18d57b0c775531e1cc94fd0 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 9 Jan 2021 01:52:29 +0700 Subject: [PATCH 2/3] Send AdhocMatching Data from within HLE whenever possible instead of through matchingEvent Thread. --- Core/HLE/sceNetAdhoc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 72ef4f0dc9f9..e575449b0c58 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -103,6 +103,7 @@ u32_le matchingThreadCode[3]; int matchingEventThread(int matchingId); int matchingInputThread(int matchingId); +void sendBulkDataPacket(SceNetAdhocMatchingContext* context, SceNetEtherAddr* mac, int datalen, void* data); int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEtherAddr* addr, u16_le* port); int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout, int nonblock); int FlushPtpSocket(int socketId); @@ -5279,7 +5280,7 @@ int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u3 peer->sending = 1; // Send Data to Peer - sendBulkData(context, peer, dataLen, data); + sendBulkDataPacket(context, &peer->mac, dataLen, data); // Return Success return 0; From 228d17ef0c4c6985d49bb3e4784848c7a8037c6a Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 9 Jan 2021 01:54:47 +0700 Subject: [PATCH 3/3] Reducing AdhocMatching events delay to prevent matchingEvents from piling up on Lord of Arcana. --- Core/HLE/sceNetAdhoc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index e575449b0c58..ebf72e35dfff 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -5519,7 +5519,7 @@ void __NetMatchingCallbacks() //(int matchingId) after->SetData(args[0], args[1], args[2]); hleEnqueueCall(args[5], 5, args, after); matchingEvents.pop_front(); - delayus = (adhocMatchingEventDelay + adhocExtraDelay); // Added an extra delay to prevent I/O Timing method from causing disconnection + delayus = adhocMatchingEventDelay; // Add extra delay to prevent I/O Timing method from causing disconnection, but delaying too long may cause matchingEvents to pile up } // Must be delayed long enough whenever there is a pending callback. Should it be 10-100ms for Matching Events? or Not Less than the delays on sceNetAdhocMatching HLE?