kern: implement transfer memory (and SVCs)

This commit is contained in:
Michael Scire 2020-07-23 00:44:33 -07:00 committed by SciresM
parent 28aab09b5d
commit d87a9f011c
8 changed files with 312 additions and 19 deletions

View file

@ -1665,11 +1665,11 @@ namespace ams::kern {
Result KPageTableBase::LockForIpcUserBuffer(KPhysicalAddress *out, KProcessAddress address, size_t size) {
return this->LockMemoryAndOpen(nullptr, out, address, size,
KMemoryState_FlagCanIpcUserBuffer, KMemoryState_FlagCanIpcUserBuffer,
KMemoryPermission_All, KMemoryPermission_UserReadWrite,
KMemoryAttribute_All, KMemoryAttribute_None,
static_cast<KMemoryPermission>(KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite),
KMemoryAttribute_AnyLocked | KMemoryAttribute_Locked);
KMemoryState_FlagCanIpcUserBuffer, KMemoryState_FlagCanIpcUserBuffer,
KMemoryPermission_All, KMemoryPermission_UserReadWrite,
KMemoryAttribute_All, KMemoryAttribute_None,
static_cast<KMemoryPermission>(KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite),
KMemoryAttribute_AnyLocked | KMemoryAttribute_Locked);
}
Result KPageTableBase::UnlockForIpcUserBuffer(KProcessAddress address, size_t size) {
@ -1681,6 +1681,42 @@ namespace ams::kern {
KMemoryAttribute_AnyLocked | KMemoryAttribute_Locked, nullptr);
}
Result KPageTableBase::LockForTransferMemory(KPageGroup *out, KProcessAddress address, size_t size, KMemoryPermission perm) {
return this->LockMemoryAndOpen(out, nullptr, address, size,
KMemoryState_FlagCanTransfer, KMemoryState_FlagCanTransfer,
KMemoryPermission_All, KMemoryPermission_UserReadWrite,
KMemoryAttribute_All, KMemoryAttribute_None,
perm,
KMemoryAttribute_AnyLocked | KMemoryAttribute_Locked);
}
Result KPageTableBase::UnlockForTransferMemory(KProcessAddress address, size_t size, const KPageGroup &pg) {
return this->UnlockMemory(address, size,
KMemoryState_FlagCanTransfer, KMemoryState_FlagCanTransfer,
KMemoryPermission_None, KMemoryPermission_None,
KMemoryAttribute_All, KMemoryAttribute_AnyLocked | KMemoryAttribute_Locked,
KMemoryPermission_UserReadWrite,
KMemoryAttribute_AnyLocked | KMemoryAttribute_Locked, std::addressof(pg));
}
Result KPageTableBase::LockForCodeMemory(KPageGroup *out, KProcessAddress address, size_t size, KMemoryPermission perm) {
return this->LockMemoryAndOpen(out, nullptr, address, size,
KMemoryState_FlagCanCodeMemory, KMemoryState_FlagCanCodeMemory,
KMemoryPermission_All, KMemoryPermission_UserReadWrite,
KMemoryAttribute_All, KMemoryAttribute_None,
static_cast<KMemoryPermission>(KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite),
KMemoryAttribute_AnyLocked | KMemoryAttribute_Locked);
}
Result KPageTableBase::UnlockForCodeMemory(KProcessAddress address, size_t size, const KPageGroup &pg) {
return this->UnlockMemory(address, size,
KMemoryState_FlagCanCodeMemory, KMemoryState_FlagCanCodeMemory,
KMemoryPermission_None, KMemoryPermission_None,
KMemoryAttribute_All, KMemoryAttribute_AnyLocked | KMemoryAttribute_Locked,
KMemoryPermission_UserReadWrite,
KMemoryAttribute_AnyLocked | KMemoryAttribute_Locked, std::addressof(pg));
}
Result KPageTableBase::CopyMemoryFromLinearToUser(KProcessAddress dst_addr, size_t size, KProcessAddress src_addr, u32 src_state_mask, u32 src_state, KMemoryPermission src_test_perm, u32 src_attr_mask, u32 src_attr) {
/* Lightly validate the range before doing anything else. */
R_UNLESS(this->Contains(src_addr, size), svc::ResultInvalidCurrentMemory());