Create a memory chunk for the stack shared memory

As the stack is automatically mapped in the guest by `clone` we do not
need to explicitly map it. This adds a flag to solve the issue.

Also mark the stack as stack rather than reserved.
This commit is contained in:
Billy Laws 2020-07-05 19:45:35 +01:00 committed by ◱ PixelyIon
parent 7884a60679
commit 670a80d2c4
3 changed files with 24 additions and 3 deletions

View File

@ -9,7 +9,7 @@
#include "KProcess.h" #include "KProcess.h"
namespace skyline::kernel::type { namespace skyline::kernel::type {
KSharedMemory::KSharedMemory(const DeviceState &state, u64 address, size_t size, memory::Permission permission, memory::MemoryState memState, int mmapFlags) : initialState(memState), KMemory(state, KType::KSharedMemory) { KSharedMemory::KSharedMemory(const DeviceState &state, u64 address, size_t size, memory::Permission permission, memory::MemoryState memState, int mmapFlags, bool shared) : initialState(memState), KMemory(state, KType::KSharedMemory) {
if (address && !util::PageAligned(address)) if (address && !util::PageAligned(address))
throw exception("KSharedMemory was created with non-page-aligned address: 0x{:X}", address); throw exception("KSharedMemory was created with non-page-aligned address: 0x{:X}", address);
@ -22,6 +22,26 @@ namespace skyline::kernel::type {
throw exception("An occurred while mapping shared memory: {}", strerror(errno)); throw exception("An occurred while mapping shared memory: {}", strerror(errno));
kernel = {.address = address, .size = size, .permission = permission}; kernel = {.address = address, .size = size, .permission = permission};
if (shared) {
guest = kernel;
BlockDescriptor block{
.address = address,
.size = size,
.permission = permission,
};
ChunkDescriptor chunk{
.address = address,
.host = address,
.size = size,
.state = initialState,
.blockList = {block},
};
state.os->memory.InsertChunk(chunk);
}
} }
u64 KSharedMemory::Map(const u64 address, const u64 size, memory::Permission permission) { u64 KSharedMemory::Map(const u64 address, const u64 size, memory::Permission permission) {

View File

@ -38,7 +38,7 @@ namespace skyline::kernel::type {
* @param memState The MemoryState of the chunk of memory * @param memState The MemoryState of the chunk of memory
* @param mmapFlags Additional flags to pass to mmap * @param mmapFlags Additional flags to pass to mmap
*/ */
KSharedMemory(const DeviceState &state, u64 address, size_t size, memory::Permission permission, memory::MemoryState memState = memory::states::SharedMemory, int mmapFlags = 0); KSharedMemory(const DeviceState &state, u64 address, size_t size, memory::Permission permission, memory::MemoryState memState = memory::states::SharedMemory, int mmapFlags = 0, bool shared = false);
/** /**
* @brief Maps the shared memory in the guest * @brief Maps the shared memory in the guest

View File

@ -36,8 +36,9 @@ namespace skyline::kernel {
} }
std::shared_ptr<type::KProcess> OS::CreateProcess(u64 entry, u64 argument, size_t stackSize) { std::shared_ptr<type::KProcess> OS::CreateProcess(u64 entry, u64 argument, size_t stackSize) {
auto stack = std::make_shared<type::KSharedMemory>(state, 0, stackSize, memory::Permission{true, true, false}, memory::states::Reserved, MAP_NORESERVE | MAP_STACK); auto stack = std::make_shared<type::KSharedMemory>(state, memory.stack.address, stackSize, memory::Permission{true, true, false}, memory::states::Stack, MAP_NORESERVE | MAP_STACK, true);
stack->guest = stack->kernel; stack->guest = stack->kernel;
if (mprotect(reinterpret_cast<void *>(stack->guest.address), PAGE_SIZE, PROT_NONE)) if (mprotect(reinterpret_cast<void *>(stack->guest.address), PAGE_SIZE, PROT_NONE))
throw exception("Failed to create guard pages"); throw exception("Failed to create guard pages");