From 34b24a47e9515a6a80d1961fc2e83bcfc84b7889 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 14 Dec 2018 18:19:12 -0500 Subject: vm_manager: Add backing functionality for memory attributes Adds the barebones enumeration constants and functions in place to handle memory attributes, while also essentially leaving the attribute itself non-functional. --- src/core/hle/kernel/vm_manager.h | 83 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'src/core/hle/kernel/vm_manager.h') diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 10bacac3e..99eeeffaa 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -43,6 +43,88 @@ enum class VMAPermission : u8 { ReadWriteExecute = Read | Write | Execute, }; +constexpr VMAPermission operator|(VMAPermission lhs, VMAPermission rhs) { + return static_cast(u32(lhs) | u32(rhs)); +} + +constexpr VMAPermission operator&(VMAPermission lhs, VMAPermission rhs) { + return static_cast(u32(lhs) & u32(rhs)); +} + +constexpr VMAPermission operator^(VMAPermission lhs, VMAPermission rhs) { + return static_cast(u32(lhs) ^ u32(rhs)); +} + +constexpr VMAPermission operator~(VMAPermission permission) { + return static_cast(~u32(permission)); +} + +constexpr VMAPermission& operator|=(VMAPermission& lhs, VMAPermission rhs) { + lhs = lhs | rhs; + return lhs; +} + +constexpr VMAPermission& operator&=(VMAPermission& lhs, VMAPermission rhs) { + lhs = lhs & rhs; + return lhs; +} + +constexpr VMAPermission& operator^=(VMAPermission& lhs, VMAPermission rhs) { + lhs = lhs ^ rhs; + return lhs; +} + +/// Attribute flags that can be applied to a VMA +enum class MemoryAttribute : u32 { + Mask = 0xFF, + + /// No particular qualities + None = 0, + /// Memory locked/borrowed for use. e.g. This would be used by transfer memory. + Locked = 1, + /// Memory locked for use by IPC-related internals. + LockedForIPC = 2, + /// Mapped as part of the device address space. + DeviceMapped = 4, + /// Uncached memory + Uncached = 8, +}; + +constexpr MemoryAttribute operator|(MemoryAttribute lhs, MemoryAttribute rhs) { + return static_cast(u32(lhs) | u32(rhs)); +} + +constexpr MemoryAttribute operator&(MemoryAttribute lhs, MemoryAttribute rhs) { + return static_cast(u32(lhs) & u32(rhs)); +} + +constexpr MemoryAttribute operator^(MemoryAttribute lhs, MemoryAttribute rhs) { + return static_cast(u32(lhs) ^ u32(rhs)); +} + +constexpr MemoryAttribute operator~(MemoryAttribute attribute) { + return static_cast(~u32(attribute)); +} + +constexpr MemoryAttribute& operator|=(MemoryAttribute& lhs, MemoryAttribute rhs) { + lhs = lhs | rhs; + return lhs; +} + +constexpr MemoryAttribute& operator&=(MemoryAttribute& lhs, MemoryAttribute rhs) { + lhs = lhs & rhs; + return lhs; +} + +constexpr MemoryAttribute& operator^=(MemoryAttribute& lhs, MemoryAttribute rhs) { + lhs = lhs ^ rhs; + return lhs; +} + +constexpr u32 ToSvcMemoryAttribute(MemoryAttribute attribute) { + return static_cast(attribute & MemoryAttribute::Mask); +} + // clang-format off /// Represents memory states and any relevant flags, as used by the kernel. /// svcQueryMemory interprets these by masking away all but the first eight @@ -183,6 +265,7 @@ struct VirtualMemoryArea { VMAPermission permissions = VMAPermission::None; /// Tag returned by svcQueryMemory. Not otherwise used. MemoryState meminfo_state = MemoryState::Unmapped; + MemoryAttribute attribute = MemoryAttribute::None; // Settings for type = AllocatedMemoryBlock /// Memory block backing this VMA. -- cgit v1.2.3 From 4dc8a7da3f8ee53ba8a812141c03bec7b27b67bc Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 14 Dec 2018 20:59:08 -0500 Subject: vm_manager: Rename meminfo_state to state This is shorter and more concise. This also removes the now-innaccurate comment, as it's not returned wholesale to svcQueryMemory anymore. --- src/core/hle/kernel/vm_manager.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/core/hle/kernel/vm_manager.h') diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 99eeeffaa..e2614cd4c 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -263,8 +263,7 @@ struct VirtualMemoryArea { VMAType type = VMAType::Free; VMAPermission permissions = VMAPermission::None; - /// Tag returned by svcQueryMemory. Not otherwise used. - MemoryState meminfo_state = MemoryState::Unmapped; + MemoryState state = MemoryState::Unmapped; MemoryAttribute attribute = MemoryAttribute::None; // Settings for type = AllocatedMemoryBlock -- cgit v1.2.3 From 603cc72168b2165a0aa77a39a14ca63a879cf8f9 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 15 Dec 2018 13:49:40 -0500 Subject: vm_manager: Add member function for checking a memory range adheres to certain attributes, permissions and states --- src/core/hle/kernel/vm_manager.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'src/core/hle/kernel/vm_manager.h') diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index e2614cd4c..9fa9a18fb 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -6,6 +6,7 @@ #include #include +#include #include #include "common/common_types.h" #include "core/hle/result.h" @@ -256,6 +257,16 @@ struct PageInfo { * also backed by a single host memory allocation. */ struct VirtualMemoryArea { + /// Gets the starting (base) address of this VMA. + VAddr StartAddress() const { + return base; + } + + /// Gets the ending address of this VMA. + VAddr EndAddress() const { + return base + size - 1; + } + /// Virtual base address of the region. VAddr base = 0; /// Size of the region. @@ -517,6 +528,35 @@ private: /// Clears out the page table void ClearPageTable(); + using CheckResults = ResultVal>; + + /// Checks if an address range adheres to the specified states provided. + /// + /// @param address The starting address of the address range. + /// @param size The size of the address range. + /// @param state_mask The memory state mask. + /// @param state The state to compare the individual VMA states against, + /// which is done in the form of: (vma.state & state_mask) != state. + /// @param permission_mask The memory permissions mask. + /// @param permissions The permission to compare the individual VMA permissions against, + /// which is done in the form of: + /// (vma.permission & permission_mask) != permission. + /// @param attribute_mask The memory attribute mask. + /// @param attribute The memory attributes to compare the individual VMA attributes + /// against, which is done in the form of: + /// (vma.attributes & attribute_mask) != attribute. + /// @param ignore_mask The memory attributes to ignore during the check. + /// + /// @returns If successful, returns a tuple containing the memory attributes + /// (with ignored bits specified by ignore_mask unset), memory permissions, and + /// memory state across the memory range. + /// @returns If not successful, returns ERR_INVALID_ADDRESS_STATE. + /// + CheckResults CheckRangeState(VAddr address, u64 size, MemoryState state_mask, MemoryState state, + VMAPermission permission_mask, VMAPermission permissions, + MemoryAttribute attribute_mask, MemoryAttribute attribute, + MemoryAttribute ignore_mask) const; + /** * A map covering the entirety of the managed address space, keyed by the `base` field of each * VMA. It must always be modified by splitting or merging VMAs, so that the invariant -- cgit v1.2.3 From 622242e3451fd562425f67317f3f0d7855eb5741 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 15 Dec 2018 14:29:39 -0500 Subject: vm_manager: Add member function for setting memory attributes across an address range This puts the backing functionality for svcSetMemoryAttribute in place, which will be utilized in a following change. --- src/core/hle/kernel/vm_manager.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/core/hle/kernel/vm_manager.h') diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 9fa9a18fb..6091533bc 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -392,6 +392,19 @@ public: /// MemoryInfo QueryMemory(VAddr address) const; + /// Sets an attribute across the given address range. + /// + /// @param address The starting address + /// @param size The size of the range to set the attribute on. + /// @param mask The attribute mask + /// @param attribute The attribute to set across the given address range + /// + /// @returns RESULT_SUCCESS if successful + /// @returns ERR_INVALID_ADDRESS_STATE if the attribute could not be set. + /// + ResultCode SetMemoryAttribute(VAddr address, u64 size, MemoryAttribute mask, + MemoryAttribute attribute); + /** * Scans all VMAs and updates the page table range of any that use the given vector as backing * memory. This should be called after any operation that causes reallocation of the vector. -- cgit v1.2.3