mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-31 04:44:26 +01:00
vm: use virtual address range from orbis config
This commit is contained in:
parent
3b57880040
commit
89c1601d49
|
|
@ -792,7 +792,7 @@ orbis::SysResult orbis::sys_get_authinfo(Thread *thread, pid_t pid,
|
|||
orbis::SysResult orbis::sys_mname(Thread *thread, uint64_t addr, uint64_t len,
|
||||
ptr<const char[32]> name) {
|
||||
ORBIS_LOG_NOTICE(__FUNCTION__, addr, len, name);
|
||||
if (addr < 0x40000 || addr >= 0x100'0000'0000 || 0x100'0000'0000 - addr < len)
|
||||
if (addr < kMinAddress || addr >= kMaxAddress || kMaxAddress - addr < len)
|
||||
return ErrorCode::INVAL;
|
||||
char _name[32];
|
||||
if (auto result = ureadString(_name, sizeof(_name), (const char *)name);
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
#include "amdgpu/tiler.hpp"
|
||||
#include "gnm/constants.hpp"
|
||||
#include "gnm/pm4.hpp"
|
||||
#include "orbis-config.hpp"
|
||||
#include "orbis/KernelContext.hpp"
|
||||
#include "orbis/note.hpp"
|
||||
#include "rx/AddressRange.hpp"
|
||||
#include "rx/Config.hpp"
|
||||
#include "rx/bits.hpp"
|
||||
#include "rx/die.hpp"
|
||||
|
|
@ -61,10 +63,13 @@ static vk::Context createVkContext(Device *device) {
|
|||
std::vector<const char *> optionalLayers;
|
||||
bool enableValidation = rx::g_config.validateGpu;
|
||||
|
||||
std::uint64_t minAddress = 0x40000;
|
||||
if (!rx::mem::reserve(reinterpret_cast<void *>(minAddress),
|
||||
0x600'0000'0000 - minAddress)) {
|
||||
rx::die("failed to reserve userspace memory");
|
||||
for (std::size_t process = 0; process < 6; ++process) {
|
||||
if (!rx::mem::reserve(
|
||||
reinterpret_cast<void *>(orbis::kMinAddress +
|
||||
orbis::kMaxAddress * process),
|
||||
orbis::kMaxAddress - orbis::kMinAddress)) {
|
||||
rx::die("failed to reserve userspace memory");
|
||||
}
|
||||
}
|
||||
|
||||
auto createWindow = [=] {
|
||||
|
|
@ -256,10 +261,10 @@ Device::Device() : vkContext(createVkContext(this)) {
|
|||
|
||||
commandPipe.device = this;
|
||||
commandPipe.ring = {
|
||||
.base = cmdRing,
|
||||
.base = std::data(cmdRing),
|
||||
.size = std::size(cmdRing),
|
||||
.rptr = cmdRing,
|
||||
.wptr = cmdRing,
|
||||
.rptr = std::data(cmdRing),
|
||||
.wptr = std::data(cmdRing),
|
||||
};
|
||||
|
||||
for (auto &pipe : computePipes) {
|
||||
|
|
@ -509,6 +514,12 @@ void Device::start() {
|
|||
}
|
||||
|
||||
void Device::submitCommand(Ring &ring, std::span<const std::uint32_t> command) {
|
||||
if (ring.size < command.size()) {
|
||||
std::println(stderr, "too big command: ring size {}, command size {}",
|
||||
ring.size, command.size());
|
||||
std::abort();
|
||||
}
|
||||
|
||||
std::scoped_lock lock(writeCommandMtx);
|
||||
if (ring.wptr + command.size() > ring.base + ring.size) {
|
||||
while (ring.wptr != ring.rptr) {
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) {
|
|||
|
||||
if (orbis::g_currentThread != nullptr &&
|
||||
orbis::g_currentThread->tproc->vmId >= 0 && sig == SIGSEGV &&
|
||||
signalAddress >= 0x40000 && signalAddress < 0x100'0000'0000) {
|
||||
signalAddress >= orbis::kMinAddress &&
|
||||
signalAddress < orbis::kMaxAddress) {
|
||||
auto vmid = orbis::g_currentThread->tproc->vmId;
|
||||
auto ctx = reinterpret_cast<ucontext_t *>(ucontext);
|
||||
bool isWrite = (ctx->uc_mcontext.gregs[REG_ERR] & 0x2) != 0;
|
||||
|
|
@ -93,7 +94,8 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) {
|
|||
continue;
|
||||
}
|
||||
|
||||
gpuContext.gpuCacheCommandIdle.fetch_add(1, std::memory_order::release);
|
||||
gpuContext.gpuCacheCommandIdle.fetch_add(
|
||||
1, std::memory_order::release);
|
||||
gpuContext.gpuCacheCommandIdle.notify_all();
|
||||
|
||||
while (!gpuContext.cachePages[vmid][page].compare_exchange_weak(
|
||||
|
|
|
|||
|
|
@ -41,11 +41,14 @@ template <typename T> using cptr = T *const;
|
|||
|
||||
using caddr_t = ptr<char>;
|
||||
|
||||
static constexpr auto kMinAddress = 0x400000;
|
||||
static constexpr auto kMaxAddress = 0x100'0000'0000;
|
||||
|
||||
[[nodiscard]] inline ErrorCode
|
||||
ureadRaw(void *kernelAddress, ptr<const void> userAddress, size_t size) {
|
||||
if (size != 0) {
|
||||
auto addr = reinterpret_cast<std::uintptr_t>(userAddress);
|
||||
if (addr < 0x40000 || addr + size > 0x100'0000'0000 || addr + size < addr)
|
||||
if (addr < kMinAddress || addr + size >= kMaxAddress || addr + size < addr)
|
||||
return ErrorCode::FAULT;
|
||||
std::memcpy(kernelAddress, userAddress, size);
|
||||
}
|
||||
|
|
@ -56,7 +59,7 @@ ureadRaw(void *kernelAddress, ptr<const void> userAddress, size_t size) {
|
|||
uwriteRaw(ptr<void> userAddress, const void *kernelAddress, size_t size) {
|
||||
if (size != 0) {
|
||||
auto addr = reinterpret_cast<std::uintptr_t>(userAddress);
|
||||
if (addr < 0x40000 || addr + size > 0x100'0000'0000 || addr + size < addr)
|
||||
if (addr < kMinAddress || addr + size > kMaxAddress || addr + size < addr)
|
||||
return ErrorCode::FAULT;
|
||||
std::memcpy(userAddress, kernelAddress, size);
|
||||
}
|
||||
|
|
@ -66,7 +69,7 @@ uwriteRaw(ptr<void> userAddress, const void *kernelAddress, size_t size) {
|
|||
[[nodiscard]] inline ErrorCode ureadString(char *kernelAddress, size_t size,
|
||||
ptr<const char> userAddress) {
|
||||
auto addr = reinterpret_cast<std::uintptr_t>(userAddress);
|
||||
if (addr < 0x40000 || addr + size > 0x100'0000'0000 || addr + size < addr)
|
||||
if (addr < kMinAddress || addr + size > kMaxAddress || addr + size < addr)
|
||||
return ErrorCode::FAULT;
|
||||
std::strncpy(kernelAddress, userAddress, size);
|
||||
if (kernelAddress[size - 1] != '\0') {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "thread.hpp"
|
||||
#include "orbis-config.hpp"
|
||||
#include "orbis/sys/sysentry.hpp"
|
||||
#include "orbis/thread/Process.hpp"
|
||||
#include "orbis/thread/Thread.hpp"
|
||||
|
|
@ -268,7 +269,7 @@ void rx::thread::setupThisThread() {
|
|||
}
|
||||
|
||||
if (prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_ON,
|
||||
(void *)0x100'0000'0000, ~0ull - 0x100'0000'0000, nullptr)) {
|
||||
(void *)orbis::kMaxAddress, ~0ull - orbis::kMaxAddress, nullptr)) {
|
||||
perror("prctl failed\n");
|
||||
std::exit(-1);
|
||||
}
|
||||
|
|
|
|||
13
rpcsx/vm.cpp
13
rpcsx/vm.cpp
|
|
@ -2,6 +2,7 @@
|
|||
#include "gpu/DeviceCtl.hpp"
|
||||
#include "io-device.hpp"
|
||||
#include "iodev/dmem.hpp"
|
||||
#include "orbis-config.hpp"
|
||||
#include "orbis/KernelContext.hpp"
|
||||
#include "orbis/thread/Process.hpp"
|
||||
#include "orbis/thread/Thread.hpp"
|
||||
|
|
@ -240,11 +241,12 @@ static constexpr std::uint64_t kBlockCount = kLastBlock - kFirstBlock + 1;
|
|||
static constexpr std::uint64_t kGroupSize = 64;
|
||||
static constexpr std::uint64_t kGroupMask = kGroupSize - 1;
|
||||
static constexpr std::uint64_t kGroupsInBlock = kPagesInBlock / kGroupSize;
|
||||
static constexpr std::uint64_t kMinAddress =
|
||||
kFirstBlock * kBlockSize + vm::kPageSize * 0x100;
|
||||
static constexpr std::uint64_t kMaxAddress = (kLastBlock + 1) * kBlockSize - 1;
|
||||
static constexpr std::uint64_t kMinAddress = orbis::kMinAddress;
|
||||
static constexpr std::uint64_t kMaxAddress = orbis::kMaxAddress;
|
||||
static constexpr std::uint64_t kMemorySize = kBlockCount * kBlockSize;
|
||||
|
||||
static_assert((kLastBlock + 1) * kBlockSize == orbis::kMaxAddress);
|
||||
|
||||
static int gMemoryShm = -1;
|
||||
|
||||
struct Group {
|
||||
|
|
@ -964,7 +966,7 @@ bool vm::unmap(void *addr, std::uint64_t size) {
|
|||
auto pages = (size + (kPageSize - 1)) >> kPageShift;
|
||||
auto address = reinterpret_cast<std::uint64_t>(addr);
|
||||
|
||||
if (address < kMinAddress || address >= kMaxAddress || size > kMaxAddress ||
|
||||
if (address < kMinAddress || address >= kMaxAddress || size >= kMaxAddress ||
|
||||
address > kMaxAddress - size) {
|
||||
std::println(stderr, "Memory error: unmap out of memory");
|
||||
return false;
|
||||
|
|
@ -994,6 +996,7 @@ bool vm::unmap(void *addr, std::uint64_t size) {
|
|||
std::println(stderr, "ignoring unmapping {:x}-{:x}", address,
|
||||
address + size);
|
||||
}
|
||||
gMapInfo.unmap(address, address + size);
|
||||
return rx::mem::unmap(addr, size);
|
||||
}
|
||||
|
||||
|
|
@ -1007,7 +1010,7 @@ bool vm::protect(void *addr, std::uint64_t size, std::int32_t prot) {
|
|||
endAddress = rx::alignUp(endAddress, kPageSize);
|
||||
size = endAddress - address;
|
||||
auto pages = size >> kPageShift;
|
||||
if (address < kMinAddress || address >= kMaxAddress || size > kMaxAddress ||
|
||||
if (address < kMinAddress || address >= kMaxAddress || size >= kMaxAddress ||
|
||||
address > kMaxAddress - size) {
|
||||
std::println(stderr, "Memory error: protect out of memory");
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Reference in a new issue