summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2021-04-17 00:52:53 -0700
committerGravatar bunnei2021-05-05 16:40:51 -0700
commitc7d8b7421cd6bdb64410bbb0094ce540f0280c27 (patch)
tree0b24ec86f194395fac5f5688a6e14fc5dec0b7dd /src/core/hle/kernel/svc.cpp
parenthle: kernel: Migrate KSession, KClientSession, and KServerSession to KAutoObj... (diff)
downloadyuzu-c7d8b7421cd6bdb64410bbb0094ce540f0280c27.tar.gz
yuzu-c7d8b7421cd6bdb64410bbb0094ce540f0280c27.tar.xz
yuzu-c7d8b7421cd6bdb64410bbb0094ce540f0280c27.zip
hle: kernel: Migrate KTransferMemory to KAutoObject.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp93
1 files changed, 48 insertions, 45 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 28c45e8a3..0b7eb0740 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -38,6 +38,7 @@
38#include "core/hle/kernel/k_shared_memory.h" 38#include "core/hle/kernel/k_shared_memory.h"
39#include "core/hle/kernel/k_synchronization_object.h" 39#include "core/hle/kernel/k_synchronization_object.h"
40#include "core/hle/kernel/k_thread.h" 40#include "core/hle/kernel/k_thread.h"
41#include "core/hle/kernel/k_transfer_memory.h"
41#include "core/hle/kernel/k_writable_event.h" 42#include "core/hle/kernel/k_writable_event.h"
42#include "core/hle/kernel/kernel.h" 43#include "core/hle/kernel/kernel.h"
43#include "core/hle/kernel/physical_core.h" 44#include "core/hle/kernel/physical_core.h"
@@ -47,7 +48,6 @@
47#include "core/hle/kernel/svc_types.h" 48#include "core/hle/kernel/svc_types.h"
48#include "core/hle/kernel/svc_wrap.h" 49#include "core/hle/kernel/svc_wrap.h"
49#include "core/hle/kernel/time_manager.h" 50#include "core/hle/kernel/time_manager.h"
50#include "core/hle/kernel/transfer_memory.h"
51#include "core/hle/lock.h" 51#include "core/hle/lock.h"
52#include "core/hle/result.h" 52#include "core/hle/result.h"
53#include "core/hle/service/service.h" 53#include "core/hle/service/service.h"
@@ -1868,65 +1868,68 @@ static ResultCode ResetSignal32(Core::System& system, Handle handle) {
1868 return ResetSignal(system, handle); 1868 return ResetSignal(system, handle);
1869} 1869}
1870 1870
1871/// Creates a TransferMemory object 1871static constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) {
1872static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size, 1872 switch (perm) {
1873 u32 permissions) { 1873 case MemoryPermission::None:
1874 std::lock_guard lock{HLE::g_hle_lock}; 1874 case MemoryPermission::Read:
1875 LOG_DEBUG(Kernel_SVC, "called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size, 1875 case MemoryPermission::ReadWrite:
1876 permissions); 1876 return true;
1877 1877 default:
1878 if (!Common::Is4KBAligned(addr)) { 1878 return false;
1879 LOG_ERROR(Kernel_SVC, "Address ({:016X}) is not page aligned!", addr);
1880 return ResultInvalidAddress;
1881 } 1879 }
1880}
1882 1881
1883 if (!Common::Is4KBAligned(size) || size == 0) { 1882/// Creates a TransferMemory object
1884 LOG_ERROR(Kernel_SVC, "Size ({:016X}) is not page aligned or equal to zero!", size); 1883static ResultCode CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size,
1885 return ResultInvalidAddress; 1884 MemoryPermission map_perm) {
1886 } 1885 auto& kernel = system.Kernel();
1887 1886
1888 if (!IsValidAddressRange(addr, size)) { 1887 // Validate the size.
1889 LOG_ERROR(Kernel_SVC, "Address and size cause overflow! (address={:016X}, size={:016X})", 1888 R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
1890 addr, size); 1889 R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
1891 return ResultInvalidCurrentMemory; 1890 R_UNLESS(size > 0, ResultInvalidSize);
1892 } 1891 R_UNLESS((address < address + size), ResultInvalidCurrentMemory);
1893 1892
1894 const auto perms{static_cast<MemoryPermission>(permissions)}; 1893 // Validate the permissions.
1895 if (perms > MemoryPermission::ReadWrite || perms == MemoryPermission::Write) { 1894 R_UNLESS(IsValidTransferMemoryPermission(map_perm), ResultInvalidNewMemoryPermission);
1896 LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", 1895
1897 permissions); 1896 // Get the current process and handle table.
1898 return ResultInvalidNewMemoryPermission; 1897 auto& process = *kernel.CurrentProcess();
1899 } 1898 auto& handle_table = process.GetHandleTable();
1900 1899
1901 auto& kernel = system.Kernel();
1902 // Reserve a new transfer memory from the process resource limit. 1900 // Reserve a new transfer memory from the process resource limit.
1903 KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(), 1901 KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(),
1904 LimitableResource::TransferMemory); 1902 LimitableResource::TransferMemory);
1905 if (!trmem_reservation.Succeeded()) { 1903 R_UNLESS(trmem_reservation.Succeeded(), ResultLimitReached);
1906 LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory");
1907 return ResultLimitReached;
1908 }
1909 auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size,
1910 static_cast<KMemoryPermission>(perms));
1911 1904
1912 if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) { 1905 // Create the transfer memory.
1913 return reserve_result; 1906 KTransferMemory* trmem = KTransferMemory::Create(kernel);
1914 } 1907 R_UNLESS(trmem != nullptr, ResultOutOfResource);
1915 1908
1916 auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); 1909 // Ensure the only reference is in the handle table when we're done.
1917 const auto result{handle_table.Create(transfer_mem_handle.get())}; 1910 SCOPE_EXIT({ trmem->Close(); });
1918 if (result.Failed()) { 1911
1919 return result.Code(); 1912 // Ensure that the region is in range.
1920 } 1913 R_UNLESS(process.PageTable().Contains(address, size), ResultInvalidCurrentMemory);
1914
1915 // Initialize the transfer memory.
1916 R_TRY(trmem->Initialize(address, size, map_perm));
1917
1918 // Commit the reservation.
1921 trmem_reservation.Commit(); 1919 trmem_reservation.Commit();
1922 1920
1923 *handle = *result; 1921 // Register the transfer memory.
1922 KTransferMemory::Register(kernel, trmem);
1923
1924 // Add the transfer memory to the handle table.
1925 R_TRY(handle_table.Add(out, trmem));
1926
1924 return RESULT_SUCCESS; 1927 return RESULT_SUCCESS;
1925} 1928}
1926 1929
1927static ResultCode CreateTransferMemory32(Core::System& system, Handle* handle, u32 addr, u32 size, 1930static ResultCode CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size,
1928 u32 permissions) { 1931 MemoryPermission map_perm) {
1929 return CreateTransferMemory(system, handle, addr, size, permissions); 1932 return CreateTransferMemory(system, out, address, size, map_perm);
1930} 1933}
1931 1934
1932static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, 1935static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id,