summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2022-01-11 16:26:17 -0800
committerGravatar GitHub2022-01-11 16:26:17 -0800
commit599c0763e50cd48c0ba0fb24566c59dffefbb906 (patch)
treea42647f8c7d195ec55e942263c95a23b048e6af9 /src/core/hle/kernel/svc.cpp
parentMerge pull request #7633 from german77/hotkeys (diff)
parentcore: hle: kernel: svc: Updates to SetMemoryAttribute and SetMemoryPermission. (diff)
downloadyuzu-599c0763e50cd48c0ba0fb24566c59dffefbb906.tar.gz
yuzu-599c0763e50cd48c0ba0fb24566c59dffefbb906.tar.xz
yuzu-599c0763e50cd48c0ba0fb24566c59dffefbb906.zip
Merge pull request #7684 from bunnei/set-mem-perm-attr
Kernel Memory Updates (Part 1): SetMemoryAttribute, and other minor changes.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp50
1 files changed, 20 insertions, 30 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 250ef9042..4362508a3 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -168,6 +168,9 @@ constexpr bool IsValidSetMemoryPermission(MemoryPermission perm) {
168 168
169static ResultCode SetMemoryPermission(Core::System& system, VAddr address, u64 size, 169static ResultCode SetMemoryPermission(Core::System& system, VAddr address, u64 size,
170 MemoryPermission perm) { 170 MemoryPermission perm) {
171 LOG_DEBUG(Kernel_SVC, "called, address=0x{:016X}, size=0x{:X}, perm=0x{:08X", address, size,
172 perm);
173
171 // Validate address / size. 174 // Validate address / size.
172 R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); 175 R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
173 R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); 176 R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
@@ -186,46 +189,33 @@ static ResultCode SetMemoryPermission(Core::System& system, VAddr address, u64 s
186} 189}
187 190
188static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, 191static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask,
189 u32 attribute) { 192 u32 attr) {
190 LOG_DEBUG(Kernel_SVC, 193 LOG_DEBUG(Kernel_SVC,
191 "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, 194 "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address,
192 size, mask, attribute); 195 size, mask, attr);
193
194 if (!Common::Is4KBAligned(address)) {
195 LOG_ERROR(Kernel_SVC, "Address not page aligned (0x{:016X})", address);
196 return ResultInvalidAddress;
197 }
198 196
199 if (size == 0 || !Common::Is4KBAligned(size)) { 197 // Validate address / size.
200 LOG_ERROR(Kernel_SVC, "Invalid size (0x{:X}). Size must be non-zero and page aligned.", 198 R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
201 size); 199 R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
202 return ResultInvalidAddress; 200 R_UNLESS(size > 0, ResultInvalidSize);
203 } 201 R_UNLESS((address < address + size), ResultInvalidCurrentMemory);
204
205 if (!IsValidAddressRange(address, size)) {
206 LOG_ERROR(Kernel_SVC, "Address range overflowed (Address: 0x{:016X}, Size: 0x{:016X})",
207 address, size);
208 return ResultInvalidCurrentMemory;
209 }
210 202
211 const auto attributes{static_cast<MemoryAttribute>(mask | attribute)}; 203 // Validate the attribute and mask.
212 if (attributes != static_cast<MemoryAttribute>(mask) || 204 constexpr u32 SupportedMask = static_cast<u32>(MemoryAttribute::Uncached);
213 (attributes | MemoryAttribute::Uncached) != MemoryAttribute::Uncached) { 205 R_UNLESS((mask | attr) == mask, ResultInvalidCombination);
214 LOG_ERROR(Kernel_SVC, 206 R_UNLESS((mask | attr | SupportedMask) == SupportedMask, ResultInvalidCombination);
215 "Memory attribute doesn't match the given mask (Attribute: 0x{:X}, Mask: {:X}",
216 attribute, mask);
217 return ResultInvalidCombination;
218 }
219 207
208 // Validate that the region is in range for the current process.
220 auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; 209 auto& page_table{system.Kernel().CurrentProcess()->PageTable()};
210 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
221 211
222 return page_table.SetMemoryAttribute(address, size, static_cast<KMemoryAttribute>(mask), 212 // Set the memory attribute.
223 static_cast<KMemoryAttribute>(attribute)); 213 return page_table.SetMemoryAttribute(address, size, mask, attr);
224} 214}
225 215
226static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, 216static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask,
227 u32 attribute) { 217 u32 attr) {
228 return SetMemoryAttribute(system, address, size, mask, attribute); 218 return SetMemoryAttribute(system, address, size, mask, attr);
229} 219}
230 220
231/// Maps a memory range into a different range. 221/// Maps a memory range into a different range.