From 9d69b0118c6c2812b89aa29ecc71f9639be03601 Mon Sep 17 00:00:00 2001
From: pineappleEA <pineaea@gmail.com>
Date: Wed, 22 Mar 2023 03:17:40 +0100
Subject: [PATCH] early-access version 3468

---
 README.md                                     |   2 +-
 src/common/CMakeLists.txt                     |   1 +
 src/common/typed_address.h                    | 337 +++++++++++++++
 src/core/CMakeLists.txt                       |   1 +
 src/core/arm/arm_interface.cpp                |  10 +-
 src/core/arm/arm_interface.h                  |   8 +-
 src/core/arm/dynarmic/arm_dynarmic_32.cpp     |   6 +-
 src/core/arm/dynarmic/arm_dynarmic_32.h       |   6 +-
 src/core/arm/dynarmic/arm_dynarmic_64.cpp     |   8 +-
 src/core/arm/dynarmic/arm_dynarmic_64.h       |   6 +-
 src/core/core.cpp                             |   4 +-
 src/core/core.h                               |   4 +-
 src/core/debugger/gdbstub.cpp                 |  36 +-
 src/core/device_memory.h                      |  14 +-
 .../board/nintendo/nx/k_memory_layout.cpp     |  12 +-
 .../board/nintendo/nx/k_memory_layout.h       |   4 +-
 .../board/nintendo/nx/k_system_control.cpp    |   2 +-
 .../board/nintendo/nx/k_system_control.h      |   4 +-
 src/core/hle/kernel/code_set.h                |   6 +-
 src/core/hle/kernel/init/init_slab_setup.cpp  |  21 +-
 src/core/hle/kernel/initial_process.h         |   2 +-
 src/core/hle/kernel/k_address_arbiter.cpp     |  32 +-
 src/core/hle/kernel/k_address_arbiter.h       |  14 +-
 src/core/hle/kernel/k_client_session.cpp      |   3 +-
 src/core/hle/kernel/k_code_memory.cpp         |  11 +-
 src/core/hle/kernel/k_code_memory.h           |  16 +-
 src/core/hle/kernel/k_condition_variable.cpp  |  22 +-
 src/core/hle/kernel/k_condition_variable.h    |   8 +-
 .../hle/kernel/k_device_address_space.cpp     |   8 +-
 src/core/hle/kernel/k_device_address_space.h  |  13 +-
 src/core/hle/kernel/k_dynamic_page_manager.h  |  19 +-
 src/core/hle/kernel/k_dynamic_slab_heap.h     |   6 +-
 src/core/hle/kernel/k_memory_block.h          |  22 +-
 .../hle/kernel/k_memory_block_manager.cpp     |  68 +--
 src/core/hle/kernel/k_memory_block_manager.h  |  32 +-
 src/core/hle/kernel/k_memory_layout.cpp       |  13 +-
 src/core/hle/kernel/k_memory_layout.h         |  78 ++--
 src/core/hle/kernel/k_memory_manager.cpp      |  51 +--
 src/core/hle/kernel/k_memory_manager.h        |  48 +--
 src/core/hle/kernel/k_memory_region.h         |   8 +-
 src/core/hle/kernel/k_page_buffer.cpp         |   4 +-
 src/core/hle/kernel/k_page_buffer.h           |   2 +-
 src/core/hle/kernel/k_page_group.h            |   2 +-
 src/core/hle/kernel/k_page_heap.cpp           |  40 +-
 src/core/hle/kernel/k_page_heap.h             |  48 ++-
 src/core/hle/kernel/k_page_table.cpp          | 392 ++++++++++--------
 src/core/hle/kernel/k_page_table.h            | 241 ++++++-----
 src/core/hle/kernel/k_page_table_manager.h    |  14 +-
 src/core/hle/kernel/k_page_table_slab_heap.h  |  12 +-
 src/core/hle/kernel/k_process.cpp             |  35 +-
 src/core/hle/kernel/k_process.h               |  43 +-
 src/core/hle/kernel/k_scheduler.cpp           |   2 +-
 src/core/hle/kernel/k_session_request.cpp     |  15 +-
 src/core/hle/kernel/k_session_request.h       |  55 +--
 src/core/hle/kernel/k_shared_memory.cpp       |   5 +-
 src/core/hle/kernel/k_shared_memory.h         |   8 +-
 src/core/hle/kernel/k_system_resource.h       |   2 +-
 src/core/hle/kernel/k_thread.cpp              |  28 +-
 src/core/hle/kernel/k_thread.h                |  58 +--
 src/core/hle/kernel/k_thread_local_page.cpp   |   6 +-
 src/core/hle/kernel/k_thread_local_page.h     |  25 +-
 src/core/hle/kernel/k_transfer_memory.cpp     |   2 +-
 src/core/hle/kernel/k_transfer_memory.h       |   6 +-
 src/core/hle/kernel/k_typed_address.h         |  12 +
 src/core/hle/kernel/kernel.cpp                | 108 ++---
 src/core/hle/kernel/kernel.h                  |   3 +-
 src/core/hle/kernel/memory_types.h            |   4 +-
 .../hle/kernel/svc/svc_address_arbiter.cpp    |   8 +-
 src/core/hle/kernel/svc/svc_code_memory.cpp   |   4 +-
 .../hle/kernel/svc/svc_condition_variable.cpp |   4 +-
 src/core/hle/kernel/svc/svc_debug_string.cpp  |   2 +-
 src/core/hle/kernel/svc/svc_exception.cpp     |   2 +-
 src/core/hle/kernel/svc/svc_info.cpp          |  10 +-
 src/core/hle/kernel/svc/svc_lock.cpp          |   4 +-
 src/core/hle/kernel/svc/svc_memory.cpp        |  13 +-
 .../hle/kernel/svc/svc_physical_memory.cpp    |   6 +-
 src/core/hle/kernel/svc/svc_port.cpp          |   2 +-
 src/core/hle/kernel/svc/svc_process.cpp       |   2 +-
 .../hle/kernel/svc/svc_process_memory.cpp     |  12 +-
 src/core/hle/kernel/svc/svc_query_memory.cpp  |   2 +-
 src/core/hle/kernel/svc/svc_shared_memory.cpp |   4 +-
 .../hle/kernel/svc/svc_synchronization.cpp    |   2 +-
 src/core/hle/kernel/svc/svc_thread.cpp        |   8 +-
 .../hle/kernel/svc/svc_transfer_memory.cpp    |   2 +-
 src/core/hle/kernel/svc_types.h               |   4 +-
 .../hid/controllers/console_sixaxis.cpp       |   2 +-
 .../service/hid/controllers/console_sixaxis.h |   6 +-
 .../hle/service/hid/controllers/palma.cpp     |   2 +-
 src/core/hle/service/hid/controllers/palma.h  |   6 +-
 .../hle/service/hid/hidbus/hidbus_base.cpp    |   2 +-
 src/core/hle/service/hid/hidbus/hidbus_base.h |   6 +-
 .../hid/irsensor/image_transfer_processor.cpp |   2 +-
 .../hid/irsensor/image_transfer_processor.h   |   6 +-
 src/core/hle/service/jit/jit.cpp              |   6 +-
 src/core/hle/service/ldr/ldr.cpp              |   5 +-
 .../loader/deconstructed_rom_directory.cpp    |   2 +-
 src/core/loader/kip.cpp                       |   2 +-
 src/core/loader/nso.cpp                       |   2 +-
 src/core/memory.cpp                           | 319 +++++++-------
 src/core/memory.h                             |  88 ++--
 src/core/memory/cheat_engine.cpp              |   6 +-
 src/core/reporter.cpp                         |   4 +-
 .../renderer_vulkan/vk_scheduler.cpp          |   9 +-
 103 files changed, 1597 insertions(+), 1107 deletions(-)
 create mode 100755 src/common/typed_address.h
 create mode 100755 src/core/hle/kernel/k_typed_address.h

diff --git a/README.md b/README.md
index 375956b4f..576a5c7cb 100755
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 yuzu emulator early access
 =============
 
-This is the source code for early-access 3467.
+This is the source code for early-access 3468.
 
 ## Legal Notice
 
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index db632f4ce..185465049 100755
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -132,6 +132,7 @@ add_library(common STATIC
     time_zone.h
     tiny_mt.h
     tree.h
+    typed_address.h
     uint128.h
     unique_function.h
     uuid.cpp
diff --git a/src/common/typed_address.h b/src/common/typed_address.h
new file mode 100755
index 000000000..c9a4946a9
--- /dev/null
+++ b/src/common/typed_address.h
@@ -0,0 +1,337 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <fmt/format.h>
+
+#include "common/common_types.h"
+
+namespace Common {
+
+template <bool Virtual, typename T>
+class TypedAddress {
+public:
+    // Constructors.
+    inline TypedAddress() : m_address(0) {}
+    constexpr inline TypedAddress(uint64_t a) : m_address(a) {}
+
+    template <typename U>
+    constexpr inline explicit TypedAddress(U* ptr) : m_address(reinterpret_cast<uint64_t>(ptr)) {}
+
+    // Copy constructor.
+    constexpr inline TypedAddress(const TypedAddress& rhs) = default;
+
+    // Assignment operator.
+    constexpr inline TypedAddress& operator=(const TypedAddress& rhs) = default;
+
+    // Arithmetic operators.
+    template <typename I>
+    constexpr inline TypedAddress operator+(I rhs) const {
+        static_assert(std::is_integral_v<I>);
+        return m_address + rhs;
+    }
+
+    constexpr inline TypedAddress operator+(TypedAddress rhs) const {
+        return m_address + rhs.m_address;
+    }
+
+    constexpr inline TypedAddress operator++() {
+        return ++m_address;
+    }
+
+    constexpr inline TypedAddress operator++(int) {
+        return m_address++;
+    }
+
+    template <typename I>
+    constexpr inline TypedAddress operator-(I rhs) const {
+        static_assert(std::is_integral_v<I>);
+        return m_address - rhs;
+    }
+
+    constexpr inline ptrdiff_t operator-(TypedAddress rhs) const {
+        return m_address - rhs.m_address;
+    }
+
+    constexpr inline TypedAddress operator--() {
+        return --m_address;
+    }
+
+    constexpr inline TypedAddress operator--(int) {
+        return m_address--;
+    }
+
+    template <typename I>
+    constexpr inline TypedAddress operator+=(I rhs) {
+        static_assert(std::is_integral_v<I>);
+        m_address += rhs;
+        return *this;
+    }
+
+    template <typename I>
+    constexpr inline TypedAddress operator-=(I rhs) {
+        static_assert(std::is_integral_v<I>);
+        m_address -= rhs;
+        return *this;
+    }
+
+    // Logical operators.
+    constexpr inline uint64_t operator&(uint64_t mask) const {
+        return m_address & mask;
+    }
+
+    constexpr inline uint64_t operator|(uint64_t mask) const {
+        return m_address | mask;
+    }
+
+    template <typename I>
+    constexpr inline TypedAddress operator|=(I rhs) {
+        static_assert(std::is_integral_v<I>);
+        m_address |= rhs;
+        return *this;
+    }
+
+    constexpr inline uint64_t operator<<(int shift) const {
+        return m_address << shift;
+    }
+
+    constexpr inline uint64_t operator>>(int shift) const {
+        return m_address >> shift;
+    }
+
+    template <typename U>
+    constexpr inline size_t operator/(U size) const {
+        return m_address / size;
+    }
+
+    constexpr inline bool operator!() const {
+        return m_address == 0;
+    }
+
+    // constexpr inline uint64_t operator%(U align) const { return m_address % align; }
+
+    // Comparison operators.
+    constexpr inline bool operator==(TypedAddress rhs) const {
+        return m_address == rhs.m_address;
+    }
+
+    constexpr inline bool operator!=(TypedAddress rhs) const {
+        return m_address != rhs.m_address;
+    }
+
+    constexpr inline bool operator<(TypedAddress rhs) const {
+        return m_address < rhs.m_address;
+    }
+
+    constexpr inline bool operator<=(TypedAddress rhs) const {
+        return m_address <= rhs.m_address;
+    }
+
+    constexpr inline bool operator>(TypedAddress rhs) const {
+        return m_address > rhs.m_address;
+    }
+
+    constexpr inline bool operator>=(TypedAddress rhs) const {
+        return m_address >= rhs.m_address;
+    }
+
+    // For convenience, also define comparison operators versus uint64_t.
+    constexpr inline bool operator==(uint64_t rhs) const {
+        return m_address == rhs;
+    }
+
+    constexpr inline bool operator!=(uint64_t rhs) const {
+        return m_address != rhs;
+    }
+
+    // Allow getting the address explicitly, for use in accessors.
+    constexpr inline uint64_t GetValue() const {
+        return m_address;
+    }
+
+private:
+    uint64_t m_address{};
+};
+
+struct PhysicalAddressTag {};
+struct VirtualAddressTag {};
+struct ProcessAddressTag {};
+
+using PhysicalAddress = TypedAddress<false, PhysicalAddressTag>;
+using VirtualAddress = TypedAddress<true, VirtualAddressTag>;
+using ProcessAddress = TypedAddress<true, ProcessAddressTag>;
+
+// Define accessors.
+template <typename T>
+concept IsTypedAddress = std::same_as<T, PhysicalAddress> || std::same_as<T, VirtualAddress> ||
+                         std::same_as<T, ProcessAddress>;
+
+template <typename T>
+constexpr inline T Null = [] {
+    if constexpr (std::is_same<T, uint64_t>::value) {
+        return 0;
+    } else {
+        static_assert(std::is_same<T, PhysicalAddress>::value ||
+                      std::is_same<T, VirtualAddress>::value ||
+                      std::is_same<T, ProcessAddress>::value);
+        return T(0);
+    }
+}();
+
+// Basic type validations.
+static_assert(sizeof(PhysicalAddress) == sizeof(uint64_t));
+static_assert(sizeof(VirtualAddress) == sizeof(uint64_t));
+static_assert(sizeof(ProcessAddress) == sizeof(uint64_t));
+
+static_assert(std::is_trivially_copyable_v<PhysicalAddress>);
+static_assert(std::is_trivially_copyable_v<VirtualAddress>);
+static_assert(std::is_trivially_copyable_v<ProcessAddress>);
+
+static_assert(std::is_trivially_copy_constructible_v<PhysicalAddress>);
+static_assert(std::is_trivially_copy_constructible_v<VirtualAddress>);
+static_assert(std::is_trivially_copy_constructible_v<ProcessAddress>);
+
+static_assert(std::is_trivially_move_constructible_v<PhysicalAddress>);
+static_assert(std::is_trivially_move_constructible_v<VirtualAddress>);
+static_assert(std::is_trivially_move_constructible_v<ProcessAddress>);
+
+static_assert(std::is_trivially_copy_assignable_v<PhysicalAddress>);
+static_assert(std::is_trivially_copy_assignable_v<VirtualAddress>);
+static_assert(std::is_trivially_copy_assignable_v<ProcessAddress>);
+
+static_assert(std::is_trivially_move_assignable_v<PhysicalAddress>);
+static_assert(std::is_trivially_move_assignable_v<VirtualAddress>);
+static_assert(std::is_trivially_move_assignable_v<ProcessAddress>);
+
+static_assert(std::is_trivially_destructible_v<PhysicalAddress>);
+static_assert(std::is_trivially_destructible_v<VirtualAddress>);
+static_assert(std::is_trivially_destructible_v<ProcessAddress>);
+
+static_assert(Null<uint64_t> == 0);
+static_assert(Null<PhysicalAddress> == Null<uint64_t>);
+static_assert(Null<VirtualAddress> == Null<uint64_t>);
+static_assert(Null<ProcessAddress> == Null<uint64_t>);
+
+// Constructor/assignment validations.
+static_assert([] {
+    const PhysicalAddress a(5);
+    PhysicalAddress b(a);
+    return b;
+}() == PhysicalAddress(5));
+static_assert([] {
+    const PhysicalAddress a(5);
+    PhysicalAddress b(10);
+    b = a;
+    return b;
+}() == PhysicalAddress(5));
+
+// Arithmetic validations.
+static_assert(PhysicalAddress(10) + 5 == PhysicalAddress(15));
+static_assert(PhysicalAddress(10) - 5 == PhysicalAddress(5));
+static_assert([] {
+    PhysicalAddress v(10);
+    v += 5;
+    return v;
+}() == PhysicalAddress(15));
+static_assert([] {
+    PhysicalAddress v(10);
+    v -= 5;
+    return v;
+}() == PhysicalAddress(5));
+static_assert(PhysicalAddress(10)++ == PhysicalAddress(10));
+static_assert(++PhysicalAddress(10) == PhysicalAddress(11));
+static_assert(PhysicalAddress(10)-- == PhysicalAddress(10));
+static_assert(--PhysicalAddress(10) == PhysicalAddress(9));
+
+// Logical validations.
+static_assert((PhysicalAddress(0b11111111) >> 1) == 0b01111111);
+static_assert((PhysicalAddress(0b10101010) >> 1) == 0b01010101);
+static_assert((PhysicalAddress(0b11111111) << 1) == 0b111111110);
+static_assert((PhysicalAddress(0b01010101) << 1) == 0b10101010);
+static_assert((PhysicalAddress(0b11111111) & 0b01010101) == 0b01010101);
+static_assert((PhysicalAddress(0b11111111) & 0b10101010) == 0b10101010);
+static_assert((PhysicalAddress(0b01010101) & 0b10101010) == 0b00000000);
+static_assert((PhysicalAddress(0b00000000) | 0b01010101) == 0b01010101);
+static_assert((PhysicalAddress(0b11111111) | 0b01010101) == 0b11111111);
+static_assert((PhysicalAddress(0b10101010) | 0b01010101) == 0b11111111);
+
+// Comparisons.
+static_assert(PhysicalAddress(0) == PhysicalAddress(0));
+static_assert(PhysicalAddress(0) != PhysicalAddress(1));
+static_assert(PhysicalAddress(0) < PhysicalAddress(1));
+static_assert(PhysicalAddress(0) <= PhysicalAddress(1));
+static_assert(PhysicalAddress(1) > PhysicalAddress(0));
+static_assert(PhysicalAddress(1) >= PhysicalAddress(0));
+
+static_assert(!(PhysicalAddress(0) == PhysicalAddress(1)));
+static_assert(!(PhysicalAddress(0) != PhysicalAddress(0)));
+static_assert(!(PhysicalAddress(1) < PhysicalAddress(0)));
+static_assert(!(PhysicalAddress(1) <= PhysicalAddress(0)));
+static_assert(!(PhysicalAddress(0) > PhysicalAddress(1)));
+static_assert(!(PhysicalAddress(0) >= PhysicalAddress(1)));
+
+} // namespace Common
+
+template <bool Virtual, typename T>
+constexpr inline uint64_t GetInteger(Common::TypedAddress<Virtual, T> address) {
+    return address.GetValue();
+}
+
+template <>
+struct fmt::formatter<Common::PhysicalAddress> {
+    constexpr auto parse(fmt::format_parse_context& ctx) {
+        return ctx.begin();
+    }
+    template <typename FormatContext>
+    auto format(const Common::PhysicalAddress& addr, FormatContext& ctx) {
+        return fmt::format_to(ctx.out(), "{:#x}", static_cast<u64>(addr.GetValue()));
+    }
+};
+
+template <>
+struct fmt::formatter<Common::ProcessAddress> {
+    constexpr auto parse(fmt::format_parse_context& ctx) {
+        return ctx.begin();
+    }
+    template <typename FormatContext>
+    auto format(const Common::ProcessAddress& addr, FormatContext& ctx) {
+        return fmt::format_to(ctx.out(), "{:#x}", static_cast<u64>(addr.GetValue()));
+    }
+};
+
+template <>
+struct fmt::formatter<Common::VirtualAddress> {
+    constexpr auto parse(fmt::format_parse_context& ctx) {
+        return ctx.begin();
+    }
+    template <typename FormatContext>
+    auto format(const Common::VirtualAddress& addr, FormatContext& ctx) {
+        return fmt::format_to(ctx.out(), "{:#x}", static_cast<u64>(addr.GetValue()));
+    }
+};
+
+namespace std {
+
+template <>
+struct hash<Common::PhysicalAddress> {
+    size_t operator()(const Common::PhysicalAddress& k) const noexcept {
+        return k.GetValue();
+    }
+};
+
+template <>
+struct hash<Common::ProcessAddress> {
+    size_t operator()(const Common::ProcessAddress& k) const noexcept {
+        return k.GetValue();
+    }
+};
+
+template <>
+struct hash<Common::VirtualAddress> {
+    size_t operator()(const Common::VirtualAddress& k) const noexcept {
+        return k.GetValue();
+    }
+};
+
+} // namespace std
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index f760927f6..605ebf704 100755
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -278,6 +278,7 @@ add_library(core STATIC
     hle/kernel/k_trace.h
     hle/kernel/k_transfer_memory.cpp
     hle/kernel/k_transfer_memory.h
+    hle/kernel/k_typed_address.h
     hle/kernel/k_worker_task.h
     hle/kernel/k_worker_task_manager.cpp
     hle/kernel/k_worker_task_manager.h
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 02ff7b82c..0656e603d 100755
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -168,21 +168,21 @@ void ARM_Interface::LoadWatchpointArray(const WatchpointArray& wp) {
 }
 
 const Kernel::DebugWatchpoint* ARM_Interface::MatchingWatchpoint(
-    VAddr addr, u64 size, Kernel::DebugWatchpointType access_type) const {
+    u64 addr, u64 size, Kernel::DebugWatchpointType access_type) const {
     if (!watchpoints) {
         return nullptr;
     }
 
-    const VAddr start_address{addr};
-    const VAddr end_address{addr + size};
+    const u64 start_address{addr};
+    const u64 end_address{addr + size};
 
     for (size_t i = 0; i < Core::Hardware::NUM_WATCHPOINTS; i++) {
         const auto& watch{(*watchpoints)[i]};
 
-        if (end_address <= watch.start_address) {
+        if (end_address <= GetInteger(watch.start_address)) {
             continue;
         }
-        if (start_address >= watch.end_address) {
+        if (start_address >= GetInteger(watch.end_address)) {
             continue;
         }
         if ((access_type & watch.type) == Kernel::DebugWatchpointType::None) {
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index ebd1d4007..6b675864d 100755
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -78,7 +78,7 @@ public:
      * @param addr Start address of the cache range to clear
      * @param size Size of the cache range to clear, starting at addr
      */
-    virtual void InvalidateCacheRange(VAddr addr, std::size_t size) = 0;
+    virtual void InvalidateCacheRange(u64 addr, std::size_t size) = 0;
 
     /**
      * Notifies CPU emulation that the current page table has changed.
@@ -149,9 +149,9 @@ public:
      */
     virtual void SetPSTATE(u32 pstate) = 0;
 
-    virtual VAddr GetTlsAddress() const = 0;
+    virtual u64 GetTlsAddress() const = 0;
 
-    virtual void SetTlsAddress(VAddr address) = 0;
+    virtual void SetTlsAddress(u64 address) = 0;
 
     /**
      * Gets the value within the TPIDR_EL0 (read/write software thread ID) register.
@@ -214,7 +214,7 @@ protected:
 
     static void SymbolicateBacktrace(Core::System& system, std::vector<BacktraceEntry>& out);
     const Kernel::DebugWatchpoint* MatchingWatchpoint(
-        VAddr addr, u64 size, Kernel::DebugWatchpointType access_type) const;
+        u64 addr, u64 size, Kernel::DebugWatchpointType access_type) const;
 
     virtual Dynarmic::HaltReason RunJit() = 0;
     virtual Dynarmic::HaltReason StepJit() = 0;
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 7e69f0689..fe20439a1 100755
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -155,7 +155,7 @@ public:
         return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0);
     }
 
-    bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) {
+    bool CheckMemoryAccess(u64 addr, u64 size, Kernel::DebugWatchpointType type) {
         if (!check_memory_access) {
             return true;
         }
@@ -397,7 +397,7 @@ u64 ARM_Dynarmic_32::GetTlsAddress() const {
     return cp15->uro;
 }
 
-void ARM_Dynarmic_32::SetTlsAddress(VAddr address) {
+void ARM_Dynarmic_32::SetTlsAddress(u64 address) {
     cp15->uro = static_cast<u32>(address);
 }
 
@@ -439,7 +439,7 @@ void ARM_Dynarmic_32::ClearInstructionCache() {
     jit.load()->ClearCache();
 }
 
-void ARM_Dynarmic_32::InvalidateCacheRange(VAddr addr, std::size_t size) {
+void ARM_Dynarmic_32::InvalidateCacheRange(u64 addr, std::size_t size) {
     jit.load()->InvalidateCacheRange(static_cast<u32>(addr), size);
 }
 
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h
index edab7d959..40fa768cf 100755
--- a/src/core/arm/dynarmic/arm_dynarmic_32.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.h
@@ -41,8 +41,8 @@ public:
     void SetVectorReg(int index, u128 value) override;
     u32 GetPSTATE() const override;
     void SetPSTATE(u32 pstate) override;
-    VAddr GetTlsAddress() const override;
-    void SetTlsAddress(VAddr address) override;
+    u64 GetTlsAddress() const override;
+    void SetTlsAddress(u64 address) override;
     void SetTPIDR_EL0(u64 value) override;
     u64 GetTPIDR_EL0() const override;
 
@@ -60,7 +60,7 @@ public:
     void ClearExclusiveState() override;
 
     void ClearInstructionCache() override;
-    void InvalidateCacheRange(VAddr addr, std::size_t size) override;
+    void InvalidateCacheRange(u64 addr, std::size_t size) override;
     void PageTableChanged(Common::PageTable& new_page_table,
                           std::size_t new_address_space_size_in_bits) override;
 
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 76feea394..b249329b6 100755
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -117,7 +117,7 @@ public:
     }
 
     void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op,
-                                         VAddr value) override {
+                                         u64 value) override {
         switch (op) {
         case Dynarmic::A64::InstructionCacheOperation::InvalidateByVAToPoU: {
             static constexpr u64 ICACHE_LINE_SIZE = 64;
@@ -199,7 +199,7 @@ public:
         return parent.system.CoreTiming().GetClockTicks();
     }
 
-    bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) {
+    bool CheckMemoryAccess(u64 addr, u64 size, Kernel::DebugWatchpointType type) {
         if (!check_memory_access) {
             return true;
         }
@@ -452,7 +452,7 @@ u64 ARM_Dynarmic_64::GetTlsAddress() const {
     return cb->tpidrro_el0;
 }
 
-void ARM_Dynarmic_64::SetTlsAddress(VAddr address) {
+void ARM_Dynarmic_64::SetTlsAddress(u64 address) {
     cb->tpidrro_el0 = address;
 }
 
@@ -500,7 +500,7 @@ void ARM_Dynarmic_64::ClearInstructionCache() {
     jit.load()->ClearCache();
 }
 
-void ARM_Dynarmic_64::InvalidateCacheRange(VAddr addr, std::size_t size) {
+void ARM_Dynarmic_64::InvalidateCacheRange(u64 addr, std::size_t size) {
     jit.load()->InvalidateCacheRange(addr, size);
 }
 
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h
index 8c312cb33..8d31616ff 100755
--- a/src/core/arm/dynarmic/arm_dynarmic_64.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.h
@@ -38,8 +38,8 @@ public:
     void SetVectorReg(int index, u128 value) override;
     u32 GetPSTATE() const override;
     void SetPSTATE(u32 pstate) override;
-    VAddr GetTlsAddress() const override;
-    void SetTlsAddress(VAddr address) override;
+    u64 GetTlsAddress() const override;
+    void SetTlsAddress(u64 address) override;
     void SetTPIDR_EL0(u64 value) override;
     u64 GetTPIDR_EL0() const override;
 
@@ -53,7 +53,7 @@ public:
     void ClearExclusiveState() override;
 
     void ClearInstructionCache() override;
-    void InvalidateCacheRange(VAddr addr, std::size_t size) override;
+    void InvalidateCacheRange(u64 addr, std::size_t size) override;
     void PageTableChanged(Common::PageTable& new_page_table,
                           std::size_t new_address_space_size_in_bits) override;
 
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 01b6598e5..04f63665e 100755
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -564,7 +564,7 @@ void System::InvalidateCpuInstructionCaches() {
     impl->kernel.InvalidateAllInstructionCaches();
 }
 
-void System::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) {
+void System::InvalidateCpuInstructionCacheRange(u64 addr, std::size_t size) {
     impl->kernel.InvalidateCpuInstructionCacheRange(addr, size);
 }
 
@@ -794,7 +794,7 @@ FileSys::VirtualFilesystem System::GetFilesystem() const {
 }
 
 void System::RegisterCheatList(const std::vector<Memory::CheatEntry>& list,
-                               const std::array<u8, 32>& build_id, VAddr main_region_begin,
+                               const std::array<u8, 32>& build_id, u64 main_region_begin,
                                u64 main_region_size) {
     impl->cheat_engine = std::make_unique<Memory::CheatEngine>(*this, list, build_id);
     impl->cheat_engine->SetMainMemoryParameters(main_region_begin, main_region_size);
diff --git a/src/core/core.h b/src/core/core.h
index dd6450dde..a6410e647 100755
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -172,7 +172,7 @@ public:
      */
     void InvalidateCpuInstructionCaches();
 
-    void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
+    void InvalidateCpuInstructionCacheRange(u64 addr, std::size_t size);
 
     /// Shutdown the main emulated process.
     void ShutdownMainProcess();
@@ -353,7 +353,7 @@ public:
     [[nodiscard]] FileSys::VirtualFilesystem GetFilesystem() const;
 
     void RegisterCheatList(const std::vector<Memory::CheatEntry>& list,
-                           const std::array<u8, 0x20>& build_id, VAddr main_region_begin,
+                           const std::array<u8, 0x20>& build_id, u64 main_region_begin,
                            u64 main_region_size);
 
     void SetAppletFrontendSet(Service::AM::Applets::AppletFrontendSet&& set);
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp
index 4943b1cd6..ef45a78c7 100755
--- a/src/core/debugger/gdbstub.cpp
+++ b/src/core/debugger/gdbstub.cpp
@@ -118,14 +118,14 @@ void GDBStub::Watchpoint(Kernel::KThread* thread, const Kernel::DebugWatchpoint&
 
     switch (watch.type) {
     case Kernel::DebugWatchpointType::Read:
-        SendReply(fmt::format("{}rwatch:{:x};", status, watch.start_address));
+        SendReply(fmt::format("{}rwatch:{:x};", status, GetInteger(watch.start_address)));
         break;
     case Kernel::DebugWatchpointType::Write:
-        SendReply(fmt::format("{}watch:{:x};", status, watch.start_address));
+        SendReply(fmt::format("{}watch:{:x};", status, GetInteger(watch.start_address)));
         break;
     case Kernel::DebugWatchpointType::ReadOrWrite:
     default:
-        SendReply(fmt::format("{}awatch:{:x};", status, watch.start_address));
+        SendReply(fmt::format("{}awatch:{:x};", status, GetInteger(watch.start_address)));
         break;
     }
 }
@@ -554,8 +554,9 @@ void GDBStub::HandleQuery(std::string_view command) {
         if (main != modules.end()) {
             SendReply(fmt::format("TextSeg={:x}", main->first));
         } else {
-            SendReply(fmt::format("TextSeg={:x}",
-                                  system.ApplicationProcess()->PageTable().GetCodeRegionStart()));
+            SendReply(fmt::format(
+                "TextSeg={:x}",
+                GetInteger(system.ApplicationProcess()->PageTable().GetCodeRegionStart())));
         }
     } else if (command.starts_with("Xfer:libraries:read::")) {
         Loader::AppLoader::Modules modules;
@@ -757,17 +758,20 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
         reply = fmt::format("Process:     {:#x} ({})\n"
                             "Program Id:  {:#018x}\n",
                             process->GetProcessId(), process->GetName(), process->GetProgramId());
-        reply +=
-            fmt::format("Layout:\n"
-                        "  Alias: {:#012x} - {:#012x}\n"
-                        "  Heap:  {:#012x} - {:#012x}\n"
-                        "  Aslr:  {:#012x} - {:#012x}\n"
-                        "  Stack: {:#012x} - {:#012x}\n"
-                        "Modules:\n",
-                        page_table.GetAliasRegionStart(), page_table.GetAliasRegionEnd(),
-                        page_table.GetHeapRegionStart(), page_table.GetHeapRegionEnd(),
-                        page_table.GetAliasCodeRegionStart(), page_table.GetAliasCodeRegionEnd(),
-                        page_table.GetStackRegionStart(), page_table.GetStackRegionEnd());
+        reply += fmt::format("Layout:\n"
+                             "  Alias: {:#012x} - {:#012x}\n"
+                             "  Heap:  {:#012x} - {:#012x}\n"
+                             "  Aslr:  {:#012x} - {:#012x}\n"
+                             "  Stack: {:#012x} - {:#012x}\n"
+                             "Modules:\n",
+                             GetInteger(page_table.GetAliasRegionStart()),
+                             GetInteger(page_table.GetAliasRegionEnd()),
+                             GetInteger(page_table.GetHeapRegionStart()),
+                             GetInteger(page_table.GetHeapRegionEnd()),
+                             GetInteger(page_table.GetAliasCodeRegionStart()),
+                             GetInteger(page_table.GetAliasCodeRegionEnd()),
+                             GetInteger(page_table.GetStackRegionStart()),
+                             GetInteger(page_table.GetStackRegionEnd()));
 
         for (const auto& [vaddr, name] : modules) {
             reply += fmt::format("  {:#012x} - {:#012x} {}\n", vaddr,
diff --git a/src/core/device_memory.h b/src/core/device_memory.h
index 5ff0d3162..fc008c32d 100755
--- a/src/core/device_memory.h
+++ b/src/core/device_memory.h
@@ -3,8 +3,8 @@
 
 #pragma once
 
-#include "common/common_types.h"
 #include "common/host_memory.h"
+#include "common/typed_address.h"
 
 namespace Core {
 
@@ -25,20 +25,22 @@ public:
     DeviceMemory(const DeviceMemory&) = delete;
 
     template <typename T>
-    PAddr GetPhysicalAddr(const T* ptr) const {
+    Common::PhysicalAddress GetPhysicalAddr(const T* ptr) const {
         return (reinterpret_cast<uintptr_t>(ptr) -
                 reinterpret_cast<uintptr_t>(buffer.BackingBasePointer())) +
                DramMemoryMap::Base;
     }
 
     template <typename T>
-    T* GetPointer(PAddr addr) {
-        return reinterpret_cast<T*>(buffer.BackingBasePointer() + (addr - DramMemoryMap::Base));
+    T* GetPointer(Common::PhysicalAddress addr) {
+        return reinterpret_cast<T*>(buffer.BackingBasePointer() +
+                                    (GetInteger(addr) - DramMemoryMap::Base));
     }
 
     template <typename T>
-    const T* GetPointer(PAddr addr) const {
-        return reinterpret_cast<T*>(buffer.BackingBasePointer() + (addr - DramMemoryMap::Base));
+    const T* GetPointer(Common::PhysicalAddress addr) const {
+        return reinterpret_cast<T*>(buffer.BackingBasePointer() +
+                                    (GetInteger(addr) - DramMemoryMap::Base));
     }
 
     Common::HostMemory buffer;
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp b/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp
index 098ba6eac..24eb3f886 100755
--- a/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp
+++ b/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp
@@ -76,22 +76,24 @@ void SetupDevicePhysicalMemoryRegions(KMemoryLayout& memory_layout) {
 
 void SetupDramPhysicalMemoryRegions(KMemoryLayout& memory_layout) {
     const size_t intended_memory_size = KSystemControl::Init::GetIntendedMemorySize();
-    const PAddr physical_memory_base_address =
+    const KPhysicalAddress physical_memory_base_address =
         KSystemControl::Init::GetKernelPhysicalBaseAddress(DramPhysicalAddress);
 
     // Insert blocks into the tree.
     ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
-        physical_memory_base_address, intended_memory_size, KMemoryRegionType_Dram));
+        GetInteger(physical_memory_base_address), intended_memory_size, KMemoryRegionType_Dram));
     ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
-        physical_memory_base_address, ReservedEarlyDramSize, KMemoryRegionType_DramReservedEarly));
+        GetInteger(physical_memory_base_address), ReservedEarlyDramSize,
+        KMemoryRegionType_DramReservedEarly));
 
     // Insert the KTrace block at the end of Dram, if KTrace is enabled.
     static_assert(!IsKTraceEnabled || KTraceBufferSize > 0);
     if constexpr (IsKTraceEnabled) {
-        const PAddr ktrace_buffer_phys_addr =
+        const KPhysicalAddress ktrace_buffer_phys_addr =
             physical_memory_base_address + intended_memory_size - KTraceBufferSize;
         ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
-            ktrace_buffer_phys_addr, KTraceBufferSize, KMemoryRegionType_KernelTraceBuffer));
+            GetInteger(ktrace_buffer_phys_addr), KTraceBufferSize,
+            KMemoryRegionType_KernelTraceBuffer));
     }
 }
 
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.h b/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.h
index ee3749dad..7945be00d 100755
--- a/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.h
+++ b/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.h
@@ -3,10 +3,10 @@
 
 #pragma once
 
-#include "common/common_types.h"
+#include "core/hle/kernel/k_typed_address.h"
 
 namespace Kernel {
 
-constexpr inline PAddr MainMemoryAddress = 0x80000000;
+constexpr inline KPhysicalAddress MainMemoryAddress = 0x80000000;
 
 } // namespace Kernel
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
index 6382db436..352f31a32 100755
--- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
+++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
@@ -61,7 +61,7 @@ size_t KSystemControl::Init::GetIntendedMemorySize() {
     }
 }
 
-PAddr KSystemControl::Init::GetKernelPhysicalBaseAddress(u64 base_address) {
+KPhysicalAddress KSystemControl::Init::GetKernelPhysicalBaseAddress(KPhysicalAddress base_address) {
     const size_t real_dram_size = KSystemControl::Init::GetRealMemorySize();
     const size_t intended_dram_size = KSystemControl::Init::GetIntendedMemorySize();
     if (intended_dram_size * 2 < real_dram_size) {
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.h b/src/core/hle/kernel/board/nintendo/nx/k_system_control.h
index 389210856..11b06aa91 100755
--- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.h
+++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.h
@@ -3,7 +3,7 @@
 
 #pragma once
 
-#include "common/common_types.h"
+#include "core/hle/kernel/k_typed_address.h"
 
 namespace Kernel::Board::Nintendo::Nx {
 
@@ -18,7 +18,7 @@ public:
         // Initialization.
         static std::size_t GetRealMemorySize();
         static std::size_t GetIntendedMemorySize();
-        static PAddr GetKernelPhysicalBaseAddress(u64 base_address);
+        static KPhysicalAddress GetKernelPhysicalBaseAddress(KPhysicalAddress base_address);
         static bool ShouldIncreaseThreadResourceLimit();
         static std::size_t GetApplicationPoolSize();
         static std::size_t GetAppletPoolSize();
diff --git a/src/core/hle/kernel/code_set.h b/src/core/hle/kernel/code_set.h
index b58c9e274..c8eef59f2 100755
--- a/src/core/hle/kernel/code_set.h
+++ b/src/core/hle/kernel/code_set.h
@@ -5,7 +5,7 @@
 
 #include <cstddef>
 
-#include "common/common_types.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/physical_memory.h"
 
 namespace Kernel {
@@ -36,7 +36,7 @@ struct CodeSet final {
         std::size_t offset = 0;
 
         /// The address to map this segment to.
-        VAddr addr = 0;
+        KProcessAddress addr = 0;
 
         /// The size of this segment in bytes.
         u32 size = 0;
@@ -82,7 +82,7 @@ struct CodeSet final {
     std::array<Segment, 3> segments;
 
     /// The entry point address for this code set.
-    VAddr entrypoint = 0;
+    KProcessAddress entrypoint = 0;
 };
 
 } // namespace Kernel
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp
index 427cdf7ca..85c756d36 100755
--- a/src/core/hle/kernel/init/init_slab_setup.cpp
+++ b/src/core/hle/kernel/init/init_slab_setup.cpp
@@ -4,7 +4,6 @@
 #include "common/alignment.h"
 #include "common/assert.h"
 #include "common/common_funcs.h"
-#include "common/common_types.h"
 #include "core/core.h"
 #include "core/device_memory.h"
 #include "core/hardware_properties.h"
@@ -30,6 +29,7 @@
 #include "core/hle/kernel/k_thread.h"
 #include "core/hle/kernel/k_thread_local_page.h"
 #include "core/hle/kernel/k_transfer_memory.h"
+#include "core/hle/kernel/k_typed_address.h"
 
 namespace Kernel::Init {
 
@@ -104,17 +104,18 @@ static_assert(KernelPageBufferAdditionalSize ==
 
 /// Helper function to translate from the slab virtual address to the reserved location in physical
 /// memory.
-static PAddr TranslateSlabAddrToPhysical(KMemoryLayout& memory_layout, VAddr slab_addr) {
-    slab_addr -= memory_layout.GetSlabRegionAddress();
-    return slab_addr + Core::DramMemoryMap::SlabHeapBase;
+static KPhysicalAddress TranslateSlabAddrToPhysical(KMemoryLayout& memory_layout,
+                                                    KVirtualAddress slab_addr) {
+    slab_addr -= GetInteger(memory_layout.GetSlabRegionAddress());
+    return GetInteger(slab_addr) + Core::DramMemoryMap::SlabHeapBase;
 }
 
 template <typename T>
-VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAddr address,
-                         size_t num_objects) {
+KVirtualAddress InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout,
+                                   KVirtualAddress address, size_t num_objects) {
 
     const size_t size = Common::AlignUp(sizeof(T) * num_objects, alignof(void*));
-    VAddr start = Common::AlignUp(address, alignof(T));
+    KVirtualAddress start = Common::AlignUp(GetInteger(address), alignof(T));
 
     // This should use the virtual memory address passed in, but currently, we do not setup the
     // kernel virtual memory layout. Instead, we simply map these at a region of physical memory
@@ -195,7 +196,7 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
     auto& kernel = system.Kernel();
 
     // Get the start of the slab region, since that's where we'll be working.
-    VAddr address = memory_layout.GetSlabRegionAddress();
+    KVirtualAddress address = memory_layout.GetSlabRegionAddress();
 
     // Initialize slab type array to be in sorted order.
     std::array<KSlabType, KSlabType_Count> slab_types;
@@ -228,7 +229,7 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
     }
 
     // Track the gaps, so that we can free them to the unused slab tree.
-    VAddr gap_start = address;
+    KVirtualAddress gap_start = address;
     size_t gap_size = 0;
 
     for (size_t i = 0; i < slab_gaps.size(); i++) {
@@ -280,7 +281,7 @@ void KPageBufferSlabHeap::Initialize(Core::System& system) {
     // Allocate memory for the slab.
     constexpr auto AllocateOption = KMemoryManager::EncodeOption(
         KMemoryManager::Pool::System, KMemoryManager::Direction::FromFront);
-    const PAddr slab_address =
+    const KPhysicalAddress slab_address =
         kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, AllocateOption);
     ASSERT(slab_address != 0);
 
diff --git a/src/core/hle/kernel/initial_process.h b/src/core/hle/kernel/initial_process.h
index c5ed4fa3f..762de49bf 100755
--- a/src/core/hle/kernel/initial_process.h
+++ b/src/core/hle/kernel/initial_process.h
@@ -14,7 +14,7 @@ using namespace Common::Literals;
 
 constexpr std::size_t InitialProcessBinarySizeMax = 12_MiB;
 
-static inline PAddr GetInitialProcessBinaryPhysicalAddress() {
+static inline KPhysicalAddress GetInitialProcessBinaryPhysicalAddress() {
     return Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetKernelPhysicalBaseAddress(
         MainMemoryAddress);
 }
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp
index eb10bdb67..a0bb3c878 100755
--- a/src/core/hle/kernel/k_address_arbiter.cpp
+++ b/src/core/hle/kernel/k_address_arbiter.cpp
@@ -8,6 +8,7 @@
 #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
 #include "core/hle/kernel/k_thread.h"
 #include "core/hle/kernel/k_thread_queue.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/svc_results.h"
 #include "core/memory.h"
@@ -20,12 +21,12 @@ KAddressArbiter::~KAddressArbiter() = default;
 
 namespace {
 
-bool ReadFromUser(Core::System& system, s32* out, VAddr address) {
-    *out = system.Memory().Read32(address);
+bool ReadFromUser(Core::System& system, s32* out, KProcessAddress address) {
+    *out = system.Memory().Read32(GetInteger(address));
     return true;
 }
 
-bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 value) {
+bool DecrementIfLessThan(Core::System& system, s32* out, KProcessAddress address, s32 value) {
     auto& monitor = system.Monitor();
     const auto current_core = system.Kernel().CurrentPhysicalCoreIndex();
 
@@ -35,7 +36,8 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu
     // TODO(bunnei): We should call CanAccessAtomic(..) here.
 
     // Load the value from the address.
-    const s32 current_value = static_cast<s32>(monitor.ExclusiveRead32(current_core, address));
+    const s32 current_value =
+        static_cast<s32>(monitor.ExclusiveRead32(current_core, GetInteger(address)));
 
     // Compare it to the desired one.
     if (current_value < value) {
@@ -43,7 +45,8 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu
         const s32 decrement_value = current_value - 1;
 
         // Decrement and try to store.
-        if (!monitor.ExclusiveWrite32(current_core, address, static_cast<u32>(decrement_value))) {
+        if (!monitor.ExclusiveWrite32(current_core, GetInteger(address),
+                                      static_cast<u32>(decrement_value))) {
             // If we failed to store, try again.
             DecrementIfLessThan(system, out, address, value);
         }
@@ -57,7 +60,8 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu
     return true;
 }
 
-bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32 new_value) {
+bool UpdateIfEqual(Core::System& system, s32* out, KProcessAddress address, s32 value,
+                   s32 new_value) {
     auto& monitor = system.Monitor();
     const auto current_core = system.Kernel().CurrentPhysicalCoreIndex();
 
@@ -67,14 +71,16 @@ bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32
     // TODO(bunnei): We should call CanAccessAtomic(..) here.
 
     // Load the value from the address.
-    const s32 current_value = static_cast<s32>(monitor.ExclusiveRead32(current_core, address));
+    const s32 current_value =
+        static_cast<s32>(monitor.ExclusiveRead32(current_core, GetInteger(address)));
 
     // Compare it to the desired one.
     if (current_value == value) {
         // If equal, we want to try to write the new value.
 
         // Try to store.
-        if (!monitor.ExclusiveWrite32(current_core, address, static_cast<u32>(new_value))) {
+        if (!monitor.ExclusiveWrite32(current_core, GetInteger(address),
+                                      static_cast<u32>(new_value))) {
             // If we failed to store, try again.
             UpdateIfEqual(system, out, address, value, new_value);
         }
@@ -110,7 +116,7 @@ private:
 
 } // namespace
 
-Result KAddressArbiter::Signal(VAddr addr, s32 count) {
+Result KAddressArbiter::Signal(uint64_t addr, s32 count) {
     // Perform signaling.
     s32 num_waiters{};
     {
@@ -133,7 +139,7 @@ Result KAddressArbiter::Signal(VAddr addr, s32 count) {
     R_SUCCEED();
 }
 
-Result KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 count) {
+Result KAddressArbiter::SignalAndIncrementIfEqual(uint64_t addr, s32 value, s32 count) {
     // Perform signaling.
     s32 num_waiters{};
     {
@@ -162,7 +168,7 @@ Result KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 cou
     R_SUCCEED();
 }
 
-Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 value, s32 count) {
+Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 value, s32 count) {
     // Perform signaling.
     s32 num_waiters{};
     {
@@ -225,7 +231,7 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 val
     R_SUCCEED();
 }
 
-Result KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout) {
+Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement, s64 timeout) {
     // Prepare to wait.
     KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
     KHardwareTimer* timer{};
@@ -280,7 +286,7 @@ Result KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s6
     return cur_thread->GetWaitResult();
 }
 
-Result KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) {
+Result KAddressArbiter::WaitIfEqual(uint64_t addr, s32 value, s64 timeout) {
     // Prepare to wait.
     KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
     KHardwareTimer* timer{};
diff --git a/src/core/hle/kernel/k_address_arbiter.h b/src/core/hle/kernel/k_address_arbiter.h
index 07d0b4641..b1c42a56f 100755
--- a/src/core/hle/kernel/k_address_arbiter.h
+++ b/src/core/hle/kernel/k_address_arbiter.h
@@ -25,7 +25,7 @@ public:
     explicit KAddressArbiter(Core::System& system);
     ~KAddressArbiter();
 
-    Result SignalToAddress(VAddr addr, Svc::SignalType type, s32 value, s32 count) {
+    Result SignalToAddress(uint64_t addr, Svc::SignalType type, s32 value, s32 count) {
         switch (type) {
         case Svc::SignalType::Signal:
             R_RETURN(this->Signal(addr, count));
@@ -38,7 +38,7 @@ public:
         }
     }
 
-    Result WaitForAddress(VAddr addr, Svc::ArbitrationType type, s32 value, s64 timeout) {
+    Result WaitForAddress(uint64_t addr, Svc::ArbitrationType type, s32 value, s64 timeout) {
         switch (type) {
         case Svc::ArbitrationType::WaitIfLessThan:
             R_RETURN(WaitIfLessThan(addr, value, false, timeout));
@@ -52,11 +52,11 @@ public:
     }
 
 private:
-    Result Signal(VAddr addr, s32 count);
-    Result SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 count);
-    Result SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 value, s32 count);
-    Result WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout);
-    Result WaitIfEqual(VAddr addr, s32 value, s64 timeout);
+    Result Signal(uint64_t addr, s32 count);
+    Result SignalAndIncrementIfEqual(uint64_t addr, s32 value, s32 count);
+    Result SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 value, s32 count);
+    Result WaitIfLessThan(uint64_t addr, s32 value, bool decrement, s64 timeout);
+    Result WaitIfEqual(uint64_t addr, s32 value, s64 timeout);
 
 private:
     ThreadTree m_tree;
diff --git a/src/core/hle/kernel/k_client_session.cpp b/src/core/hle/kernel/k_client_session.cpp
index 278cd63a1..93ce3aa16 100755
--- a/src/core/hle/kernel/k_client_session.cpp
+++ b/src/core/hle/kernel/k_client_session.cpp
@@ -29,7 +29,8 @@ Result KClientSession::SendSyncRequest() {
     SCOPE_EXIT({ request->Close(); });
 
     // Initialize the request.
-    request->Initialize(nullptr, GetCurrentThread(m_kernel).GetTlsAddress(), MessageBufferSize);
+    request->Initialize(nullptr, GetInteger(GetCurrentThread(m_kernel).GetTlsAddress()),
+                        MessageBufferSize);
 
     // Send the request.
     R_RETURN(m_parent->GetServerSession().OnRequest(request));
diff --git a/src/core/hle/kernel/k_code_memory.cpp b/src/core/hle/kernel/k_code_memory.cpp
index 5fc83d359..b0348bbb0 100755
--- a/src/core/hle/kernel/k_code_memory.cpp
+++ b/src/core/hle/kernel/k_code_memory.cpp
@@ -19,7 +19,8 @@ namespace Kernel {
 KCodeMemory::KCodeMemory(KernelCore& kernel)
     : KAutoObjectWithSlabHeapAndContainer{kernel}, m_lock(kernel) {}
 
-Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, size_t size) {
+Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, KProcessAddress addr,
+                               size_t size) {
     // Set members.
     m_owner = GetCurrentProcessPointer(m_kernel);
 
@@ -63,7 +64,7 @@ void KCodeMemory::Finalize() {
     m_owner->Close();
 }
 
-Result KCodeMemory::Map(VAddr address, size_t size) {
+Result KCodeMemory::Map(KProcessAddress address, size_t size) {
     // Validate the size.
     R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
 
@@ -83,7 +84,7 @@ Result KCodeMemory::Map(VAddr address, size_t size) {
     R_SUCCEED();
 }
 
-Result KCodeMemory::Unmap(VAddr address, size_t size) {
+Result KCodeMemory::Unmap(KProcessAddress address, size_t size) {
     // Validate the size.
     R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
 
@@ -100,7 +101,7 @@ Result KCodeMemory::Unmap(VAddr address, size_t size) {
     R_SUCCEED();
 }
 
-Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm) {
+Result KCodeMemory::MapToOwner(KProcessAddress address, size_t size, Svc::MemoryPermission perm) {
     // Validate the size.
     R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
 
@@ -134,7 +135,7 @@ Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission
     R_SUCCEED();
 }
 
-Result KCodeMemory::UnmapFromOwner(VAddr address, size_t size) {
+Result KCodeMemory::UnmapFromOwner(KProcessAddress address, size_t size) {
     // Validate the size.
     R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
 
diff --git a/src/core/hle/kernel/k_code_memory.h b/src/core/hle/kernel/k_code_memory.h
index 80c07703e..3ce0c8aa3 100755
--- a/src/core/hle/kernel/k_code_memory.h
+++ b/src/core/hle/kernel/k_code_memory.h
@@ -5,12 +5,12 @@
 
 #include <optional>
 
-#include "common/common_types.h"
 #include "core/device_memory.h"
 #include "core/hle/kernel/k_auto_object.h"
 #include "core/hle/kernel/k_light_lock.h"
 #include "core/hle/kernel/k_page_group.h"
 #include "core/hle/kernel/k_process.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/slab_helpers.h"
 #include "core/hle/kernel/svc_types.h"
 #include "core/hle/result.h"
@@ -31,13 +31,13 @@ class KCodeMemory final
 public:
     explicit KCodeMemory(KernelCore& kernel);
 
-    Result Initialize(Core::DeviceMemory& device_memory, VAddr address, size_t size);
+    Result Initialize(Core::DeviceMemory& device_memory, KProcessAddress address, size_t size);
     void Finalize() override;
 
-    Result Map(VAddr address, size_t size);
-    Result Unmap(VAddr address, size_t size);
-    Result MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm);
-    Result UnmapFromOwner(VAddr address, size_t size);
+    Result Map(KProcessAddress address, size_t size);
+    Result Unmap(KProcessAddress address, size_t size);
+    Result MapToOwner(KProcessAddress address, size_t size, Svc::MemoryPermission perm);
+    Result UnmapFromOwner(KProcessAddress address, size_t size);
 
     bool IsInitialized() const override {
         return m_is_initialized;
@@ -47,7 +47,7 @@ public:
     KProcess* GetOwner() const override {
         return m_owner;
     }
-    VAddr GetSourceAddress() const {
+    KProcessAddress GetSourceAddress() const {
         return m_address;
     }
     size_t GetSize() const {
@@ -57,7 +57,7 @@ public:
 private:
     std::optional<KPageGroup> m_page_group{};
     KProcess* m_owner{};
-    VAddr m_address{};
+    KProcessAddress m_address{};
     KLightLock m_lock;
     bool m_is_initialized{};
     bool m_is_owner_mapped{};
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp
index 4e78e2893..6f6b49677 100755
--- a/src/core/hle/kernel/k_condition_variable.cpp
+++ b/src/core/hle/kernel/k_condition_variable.cpp
@@ -18,23 +18,23 @@ namespace Kernel {
 
 namespace {
 
-bool ReadFromUser(Core::System& system, u32* out, VAddr address) {
-    *out = system.Memory().Read32(address);
+bool ReadFromUser(Core::System& system, u32* out, KProcessAddress address) {
+    *out = system.Memory().Read32(GetInteger(address));
     return true;
 }
 
-bool WriteToUser(Core::System& system, VAddr address, const u32* p) {
-    system.Memory().Write32(address, *p);
+bool WriteToUser(Core::System& system, KProcessAddress address, const u32* p) {
+    system.Memory().Write32(GetInteger(address), *p);
     return true;
 }
 
-bool UpdateLockAtomic(Core::System& system, u32* out, VAddr address, u32 if_zero,
+bool UpdateLockAtomic(Core::System& system, u32* out, KProcessAddress address, u32 if_zero,
                       u32 new_orr_mask) {
     auto& monitor = system.Monitor();
     const auto current_core = system.Kernel().CurrentPhysicalCoreIndex();
 
     // Load the value from the address.
-    const auto expected = monitor.ExclusiveRead32(current_core, address);
+    const auto expected = monitor.ExclusiveRead32(current_core, GetInteger(address));
 
     // Orr in the new mask.
     u32 value = expected | new_orr_mask;
@@ -45,7 +45,7 @@ bool UpdateLockAtomic(Core::System& system, u32* out, VAddr address, u32 if_zero
     }
 
     // Try to store.
-    if (!monitor.ExclusiveWrite32(current_core, address, value)) {
+    if (!monitor.ExclusiveWrite32(current_core, GetInteger(address), value)) {
         // If we failed to store, try again.
         return UpdateLockAtomic(system, out, address, if_zero, new_orr_mask);
     }
@@ -102,7 +102,7 @@ KConditionVariable::KConditionVariable(Core::System& system)
 
 KConditionVariable::~KConditionVariable() = default;
 
-Result KConditionVariable::SignalToAddress(VAddr addr) {
+Result KConditionVariable::SignalToAddress(KProcessAddress addr) {
     KThread* owner_thread = GetCurrentThreadPointer(m_kernel);
 
     // Signal the address.
@@ -143,7 +143,7 @@ Result KConditionVariable::SignalToAddress(VAddr addr) {
     }
 }
 
-Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value) {
+Result KConditionVariable::WaitForAddress(Handle handle, KProcessAddress addr, u32 value) {
     KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
     ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(m_kernel);
 
@@ -191,7 +191,7 @@ void KConditionVariable::SignalImpl(KThread* thread) {
     ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
 
     // Update the tag.
-    VAddr address = thread->GetAddressKey();
+    KProcessAddress address = thread->GetAddressKey();
     u32 own_tag = thread->GetAddressKeyValue();
 
     u32 prev_tag{};
@@ -262,7 +262,7 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
     }
 }
 
-Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) {
+Result KConditionVariable::Wait(KProcessAddress addr, u64 key, u32 value, s64 timeout) {
     // Prepare to wait.
     KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
     KHardwareTimer* timer{};
diff --git a/src/core/hle/kernel/k_condition_variable.h b/src/core/hle/kernel/k_condition_variable.h
index 53cfdfc68..95bed0c0e 100755
--- a/src/core/hle/kernel/k_condition_variable.h
+++ b/src/core/hle/kernel/k_condition_variable.h
@@ -4,10 +4,10 @@
 #pragma once
 
 #include "common/assert.h"
-#include "common/common_types.h"
 
 #include "core/hle/kernel/k_scheduler.h"
 #include "core/hle/kernel/k_thread.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/result.h"
 
@@ -25,12 +25,12 @@ public:
     ~KConditionVariable();
 
     // Arbitration
-    Result SignalToAddress(VAddr addr);
-    Result WaitForAddress(Handle handle, VAddr addr, u32 value);
+    Result SignalToAddress(KProcessAddress addr);
+    Result WaitForAddress(Handle handle, KProcessAddress addr, u32 value);
 
     // Condition variable
     void Signal(u64 cv_key, s32 count);
-    Result Wait(VAddr addr, u64 key, u32 value, s64 timeout);
+    Result Wait(KProcessAddress addr, u64 key, u32 value, s64 timeout);
 
 private:
     void SignalImpl(KThread* thread);
diff --git a/src/core/hle/kernel/k_device_address_space.cpp b/src/core/hle/kernel/k_device_address_space.cpp
index a2fc4fe1f..f48896715 100755
--- a/src/core/hle/kernel/k_device_address_space.cpp
+++ b/src/core/hle/kernel/k_device_address_space.cpp
@@ -54,8 +54,8 @@ Result KDeviceAddressSpace::Detach(Svc::DeviceName device_name) {
     R_SUCCEED();
 }
 
-Result KDeviceAddressSpace::Map(KPageTable* page_table, VAddr process_address, size_t size,
-                                u64 device_address, u32 option, bool is_aligned) {
+Result KDeviceAddressSpace::Map(KPageTable* page_table, KProcessAddress process_address,
+                                size_t size, u64 device_address, u32 option, bool is_aligned) {
     // Check that the address falls within the space.
     R_UNLESS((m_space_address <= device_address &&
               device_address + size - 1 <= m_space_address + m_space_size - 1),
@@ -113,8 +113,8 @@ Result KDeviceAddressSpace::Map(KPageTable* page_table, VAddr process_address, s
     R_SUCCEED();
 }
 
-Result KDeviceAddressSpace::Unmap(KPageTable* page_table, VAddr process_address, size_t size,
-                                  u64 device_address) {
+Result KDeviceAddressSpace::Unmap(KPageTable* page_table, KProcessAddress process_address,
+                                  size_t size, u64 device_address) {
     // Check that the address falls within the space.
     R_UNLESS((m_space_address <= device_address &&
               device_address + size - 1 <= m_space_address + m_space_size - 1),
diff --git a/src/core/hle/kernel/k_device_address_space.h b/src/core/hle/kernel/k_device_address_space.h
index b4a014c38..18556e3cc 100755
--- a/src/core/hle/kernel/k_device_address_space.h
+++ b/src/core/hle/kernel/k_device_address_space.h
@@ -5,8 +5,8 @@
 
 #include <string>
 
-#include "common/common_types.h"
 #include "core/hle/kernel/k_page_table.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/slab_helpers.h"
 #include "core/hle/result.h"
 
@@ -31,23 +31,24 @@ public:
     Result Attach(Svc::DeviceName device_name);
     Result Detach(Svc::DeviceName device_name);
 
-    Result MapByForce(KPageTable* page_table, VAddr process_address, size_t size,
+    Result MapByForce(KPageTable* page_table, KProcessAddress process_address, size_t size,
                       u64 device_address, u32 option) {
         R_RETURN(this->Map(page_table, process_address, size, device_address, option, false));
     }
 
-    Result MapAligned(KPageTable* page_table, VAddr process_address, size_t size,
+    Result MapAligned(KPageTable* page_table, KProcessAddress process_address, size_t size,
                       u64 device_address, u32 option) {
         R_RETURN(this->Map(page_table, process_address, size, device_address, option, true));
     }
 
-    Result Unmap(KPageTable* page_table, VAddr process_address, size_t size, u64 device_address);
+    Result Unmap(KPageTable* page_table, KProcessAddress process_address, size_t size,
+                 u64 device_address);
 
     static void Initialize();
 
 private:
-    Result Map(KPageTable* page_table, VAddr process_address, size_t size, u64 device_address,
-               u32 option, bool is_aligned);
+    Result Map(KPageTable* page_table, KProcessAddress process_address, size_t size,
+               u64 device_address, u32 option, bool is_aligned);
 
 private:
     KLightLock m_lock;
diff --git a/src/core/hle/kernel/k_dynamic_page_manager.h b/src/core/hle/kernel/k_dynamic_page_manager.h
index 6fdf0b938..5abd2b208 100755
--- a/src/core/hle/kernel/k_dynamic_page_manager.h
+++ b/src/core/hle/kernel/k_dynamic_page_manager.h
@@ -6,9 +6,9 @@
 #include <vector>
 
 #include "common/alignment.h"
-#include "common/common_types.h"
 #include "core/hle/kernel/k_page_bitmap.h"
 #include "core/hle/kernel/k_spin_lock.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/memory_types.h"
 #include "core/hle/kernel/svc_results.h"
 
@@ -26,23 +26,23 @@ public:
     KDynamicPageManager() = default;
 
     template <typename T>
-    T* GetPointer(VAddr addr) {
+    T* GetPointer(KVirtualAddress addr) {
         return reinterpret_cast<T*>(m_backing_memory.data() + (addr - m_address));
     }
 
     template <typename T>
-    const T* GetPointer(VAddr addr) const {
+    const T* GetPointer(KVirtualAddress addr) const {
         return reinterpret_cast<T*>(m_backing_memory.data() + (addr - m_address));
     }
 
-    Result Initialize(VAddr memory, size_t size, size_t align) {
+    Result Initialize(KVirtualAddress memory, size_t size, size_t align) {
         // We need to have positive size.
         R_UNLESS(size > 0, ResultOutOfMemory);
         m_backing_memory.resize(size);
 
         // Set addresses.
         m_address = memory;
-        m_aligned_address = Common::AlignDown(memory, align);
+        m_aligned_address = Common::AlignDown(GetInteger(memory), align);
 
         // Calculate extents.
         const size_t managed_size = m_address + size - m_aligned_address;
@@ -79,7 +79,7 @@ public:
         R_SUCCEED();
     }
 
-    VAddr GetAddress() const {
+    KVirtualAddress GetAddress() const {
         return m_address;
     }
     size_t GetSize() const {
@@ -145,7 +145,8 @@ public:
         KScopedSpinLock lk(m_lock);
 
         // Set the bit for the free page.
-        size_t offset = (reinterpret_cast<uintptr_t>(pb) - m_aligned_address) / sizeof(PageBuffer);
+        size_t offset =
+            (reinterpret_cast<uint64_t>(pb) - GetInteger(m_aligned_address)) / sizeof(PageBuffer);
         m_page_bitmap.SetBit(offset);
 
         // Decrement our used count.
@@ -158,8 +159,8 @@ private:
     size_t m_used{};
     size_t m_peak{};
     size_t m_count{};
-    VAddr m_address{};
-    VAddr m_aligned_address{};
+    KVirtualAddress m_address{};
+    KVirtualAddress m_aligned_address{};
     size_t m_size{};
 
     // TODO(bunnei): Back by host memory until we emulate kernel virtual address space.
diff --git a/src/core/hle/kernel/k_dynamic_slab_heap.h b/src/core/hle/kernel/k_dynamic_slab_heap.h
index 87458672a..2c5f97e00 100755
--- a/src/core/hle/kernel/k_dynamic_slab_heap.h
+++ b/src/core/hle/kernel/k_dynamic_slab_heap.h
@@ -19,7 +19,7 @@ class KDynamicSlabHeap : protected impl::KSlabHeapImpl {
 public:
     constexpr KDynamicSlabHeap() = default;
 
-    constexpr VAddr GetAddress() const {
+    constexpr KVirtualAddress GetAddress() const {
         return m_address;
     }
     constexpr size_t GetSize() const {
@@ -35,7 +35,7 @@ public:
         return m_count.load();
     }
 
-    constexpr bool IsInRange(VAddr addr) const {
+    constexpr bool IsInRange(KVirtualAddress addr) const {
         return this->GetAddress() <= addr && addr <= this->GetAddress() + this->GetSize() - 1;
     }
 
@@ -115,7 +115,7 @@ private:
     std::atomic<size_t> m_used{};
     std::atomic<size_t> m_peak{};
     std::atomic<size_t> m_count{};
-    VAddr m_address{};
+    KVirtualAddress m_address{};
     size_t m_size{};
 };
 
diff --git a/src/core/hle/kernel/k_memory_block.h b/src/core/hle/kernel/k_memory_block.h
index 2cd6c9d51..3f0003d76 100755
--- a/src/core/hle/kernel/k_memory_block.h
+++ b/src/core/hle/kernel/k_memory_block.h
@@ -5,8 +5,8 @@
 
 #include "common/alignment.h"
 #include "common/assert.h"
-#include "common/common_types.h"
 #include "common/intrusive_red_black_tree.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/memory_types.h"
 #include "core/hle/kernel/svc_types.h"
 
@@ -282,7 +282,7 @@ class KMemoryBlock : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryBlock>
 private:
     u16 m_device_disable_merge_left_count{};
     u16 m_device_disable_merge_right_count{};
-    VAddr m_address{};
+    KProcessAddress m_address{};
     size_t m_num_pages{};
     KMemoryState m_memory_state{KMemoryState::None};
     u16 m_ipc_lock_count{};
@@ -306,7 +306,7 @@ public:
     }
 
 public:
-    constexpr VAddr GetAddress() const {
+    constexpr KProcessAddress GetAddress() const {
         return m_address;
     }
 
@@ -318,11 +318,11 @@ public:
         return this->GetNumPages() * PageSize;
     }
 
-    constexpr VAddr GetEndAddress() const {
+    constexpr KProcessAddress GetEndAddress() const {
         return this->GetAddress() + this->GetSize();
     }
 
-    constexpr VAddr GetLastAddress() const {
+    constexpr KProcessAddress GetLastAddress() const {
         return this->GetEndAddress() - 1;
     }
 
@@ -348,7 +348,7 @@ public:
 
     constexpr KMemoryInfo GetMemoryInfo() const {
         return {
-            .m_address = this->GetAddress(),
+            .m_address = GetInteger(this->GetAddress()),
             .m_size = this->GetSize(),
             .m_state = m_memory_state,
             .m_device_disable_merge_left_count = m_device_disable_merge_left_count,
@@ -366,12 +366,12 @@ public:
 public:
     explicit KMemoryBlock() = default;
 
-    constexpr KMemoryBlock(VAddr addr, size_t np, KMemoryState ms, KMemoryPermission p,
+    constexpr KMemoryBlock(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p,
                            KMemoryAttribute attr)
         : Common::IntrusiveRedBlackTreeBaseNode<KMemoryBlock>(), m_address(addr), m_num_pages(np),
           m_memory_state(ms), m_permission(p), m_attribute(attr) {}
 
-    constexpr void Initialize(VAddr addr, size_t np, KMemoryState ms, KMemoryPermission p,
+    constexpr void Initialize(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p,
                               KMemoryAttribute attr) {
         m_device_disable_merge_left_count = 0;
         m_device_disable_merge_right_count = 0;
@@ -408,7 +408,7 @@ public:
                    KMemoryBlockDisableMergeAttribute::None;
     }
 
-    constexpr bool Contains(VAddr addr) const {
+    constexpr bool Contains(KProcessAddress addr) const {
         return this->GetAddress() <= addr && addr <= this->GetEndAddress();
     }
 
@@ -443,10 +443,10 @@ public:
         }
     }
 
-    constexpr void Split(KMemoryBlock* block, VAddr addr) {
+    constexpr void Split(KMemoryBlock* block, KProcessAddress addr) {
         ASSERT(this->GetAddress() < addr);
         ASSERT(this->Contains(addr));
-        ASSERT(Common::IsAligned(addr, PageSize));
+        ASSERT(Common::IsAligned(GetInteger(addr), PageSize));
 
         block->m_address = m_address;
         block->m_num_pages = (addr - this->GetAddress()) / PageSize;
diff --git a/src/core/hle/kernel/k_memory_block_manager.cpp b/src/core/hle/kernel/k_memory_block_manager.cpp
index a6fb64458..7b0d742d4 100755
--- a/src/core/hle/kernel/k_memory_block_manager.cpp
+++ b/src/core/hle/kernel/k_memory_block_manager.cpp
@@ -7,7 +7,8 @@ namespace Kernel {
 
 KMemoryBlockManager::KMemoryBlockManager() = default;
 
-Result KMemoryBlockManager::Initialize(VAddr st, VAddr nd, KMemoryBlockSlabManager* slab_manager) {
+Result KMemoryBlockManager::Initialize(KProcessAddress st, KProcessAddress nd,
+                                       KMemoryBlockSlabManager* slab_manager) {
     // Allocate a block to encapsulate the address space, insert it into the tree.
     KMemoryBlock* start_block = slab_manager->Allocate();
     R_UNLESS(start_block != nullptr, ResultOutOfResource);
@@ -15,8 +16,8 @@ Result KMemoryBlockManager::Initialize(VAddr st, VAddr nd, KMemoryBlockSlabManag
     // Set our start and end.
     m_start_address = st;
     m_end_address = nd;
-    ASSERT(Common::IsAligned(m_start_address, PageSize));
-    ASSERT(Common::IsAligned(m_end_address, PageSize));
+    ASSERT(Common::IsAligned(GetInteger(m_start_address), PageSize));
+    ASSERT(Common::IsAligned(GetInteger(m_end_address), PageSize));
 
     // Initialize and insert the block.
     start_block->Initialize(m_start_address, (m_end_address - m_start_address) / PageSize,
@@ -40,12 +41,13 @@ void KMemoryBlockManager::Finalize(KMemoryBlockSlabManager* slab_manager,
     ASSERT(m_memory_block_tree.empty());
 }
 
-VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, size_t region_num_pages,
-                                        size_t num_pages, size_t alignment, size_t offset,
-                                        size_t guard_pages) const {
+KProcessAddress KMemoryBlockManager::FindFreeArea(KProcessAddress region_start,
+                                                  size_t region_num_pages, size_t num_pages,
+                                                  size_t alignment, size_t offset,
+                                                  size_t guard_pages) const {
     if (num_pages > 0) {
-        const VAddr region_end = region_start + region_num_pages * PageSize;
-        const VAddr region_last = region_end - 1;
+        const KProcessAddress region_end = region_start + region_num_pages * PageSize;
+        const KProcessAddress region_last = region_end - 1;
         for (const_iterator it = this->FindIterator(region_start); it != m_memory_block_tree.cend();
              it++) {
             const KMemoryInfo info = it->GetMemoryInfo();
@@ -56,17 +58,19 @@ VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, size_t region_num_pa
                 continue;
             }
 
-            VAddr area = (info.GetAddress() <= region_start) ? region_start : info.GetAddress();
+            KProcessAddress area =
+                (info.GetAddress() <= GetInteger(region_start)) ? region_start : info.GetAddress();
             area += guard_pages * PageSize;
 
-            const VAddr offset_area = Common::AlignDown(area, alignment) + offset;
+            const KProcessAddress offset_area =
+                Common::AlignDown(GetInteger(area), alignment) + offset;
             area = (area <= offset_area) ? offset_area : offset_area + alignment;
 
-            const VAddr area_end = area + num_pages * PageSize + guard_pages * PageSize;
-            const VAddr area_last = area_end - 1;
+            const KProcessAddress area_end = area + num_pages * PageSize + guard_pages * PageSize;
+            const KProcessAddress area_last = area_end - 1;
 
-            if (info.GetAddress() <= area && area < area_last && area_last <= region_last &&
-                area_last <= info.GetLastAddress()) {
+            if (info.GetAddress() <= GetInteger(area) && area < area_last &&
+                area_last <= region_last && area_last <= info.GetLastAddress()) {
                 return area;
             }
         }
@@ -76,7 +80,7 @@ VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, size_t region_num_pa
 }
 
 void KMemoryBlockManager::CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* allocator,
-                                            VAddr address, size_t num_pages) {
+                                            KProcessAddress address, size_t num_pages) {
     // Find the iterator now that we've updated.
     iterator it = this->FindIterator(address);
     if (address != m_start_address) {
@@ -104,18 +108,18 @@ void KMemoryBlockManager::CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator*
     }
 }
 
-void KMemoryBlockManager::Update(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
-                                 size_t num_pages, KMemoryState state, KMemoryPermission perm,
-                                 KMemoryAttribute attr,
+void KMemoryBlockManager::Update(KMemoryBlockManagerUpdateAllocator* allocator,
+                                 KProcessAddress address, size_t num_pages, KMemoryState state,
+                                 KMemoryPermission perm, KMemoryAttribute attr,
                                  KMemoryBlockDisableMergeAttribute set_disable_attr,
                                  KMemoryBlockDisableMergeAttribute clear_disable_attr) {
     // Ensure for auditing that we never end up with an invalid tree.
     KScopedMemoryBlockManagerAuditor auditor(this);
-    ASSERT(Common::IsAligned(address, PageSize));
+    ASSERT(Common::IsAligned(GetInteger(address), PageSize));
     ASSERT((attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) ==
            KMemoryAttribute::None);
 
-    VAddr cur_address = address;
+    KProcessAddress cur_address = address;
     size_t remaining_pages = num_pages;
     iterator it = this->FindIterator(address);
 
@@ -168,17 +172,17 @@ void KMemoryBlockManager::Update(KMemoryBlockManagerUpdateAllocator* allocator,
 }
 
 void KMemoryBlockManager::UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allocator,
-                                        VAddr address, size_t num_pages, KMemoryState test_state,
-                                        KMemoryPermission test_perm, KMemoryAttribute test_attr,
-                                        KMemoryState state, KMemoryPermission perm,
-                                        KMemoryAttribute attr) {
+                                        KProcessAddress address, size_t num_pages,
+                                        KMemoryState test_state, KMemoryPermission test_perm,
+                                        KMemoryAttribute test_attr, KMemoryState state,
+                                        KMemoryPermission perm, KMemoryAttribute attr) {
     // Ensure for auditing that we never end up with an invalid tree.
     KScopedMemoryBlockManagerAuditor auditor(this);
-    ASSERT(Common::IsAligned(address, PageSize));
+    ASSERT(Common::IsAligned(GetInteger(address), PageSize));
     ASSERT((attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) ==
            KMemoryAttribute::None);
 
-    VAddr cur_address = address;
+    KProcessAddress cur_address = address;
     size_t remaining_pages = num_pages;
     iterator it = this->FindIterator(address);
 
@@ -230,18 +234,18 @@ void KMemoryBlockManager::UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allo
     this->CoalesceForUpdate(allocator, address, num_pages);
 }
 
-void KMemoryBlockManager::UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
-                                     size_t num_pages, MemoryBlockLockFunction lock_func,
-                                     KMemoryPermission perm) {
+void KMemoryBlockManager::UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator,
+                                     KProcessAddress address, size_t num_pages,
+                                     MemoryBlockLockFunction lock_func, KMemoryPermission perm) {
     // Ensure for auditing that we never end up with an invalid tree.
     KScopedMemoryBlockManagerAuditor auditor(this);
-    ASSERT(Common::IsAligned(address, PageSize));
+    ASSERT(Common::IsAligned(GetInteger(address), PageSize));
 
-    VAddr cur_address = address;
+    KProcessAddress cur_address = address;
     size_t remaining_pages = num_pages;
     iterator it = this->FindIterator(address);
 
-    const VAddr end_address = address + (num_pages * PageSize);
+    const KProcessAddress end_address = address + (num_pages * PageSize);
 
     while (remaining_pages > 0) {
         const size_t remaining_size = remaining_pages * PageSize;
diff --git a/src/core/hle/kernel/k_memory_block_manager.h b/src/core/hle/kernel/k_memory_block_manager.h
index c7226e7d4..9a823cf78 100755
--- a/src/core/hle/kernel/k_memory_block_manager.h
+++ b/src/core/hle/kernel/k_memory_block_manager.h
@@ -7,9 +7,9 @@
 #include <functional>
 
 #include "common/common_funcs.h"
-#include "common/common_types.h"
 #include "core/hle/kernel/k_dynamic_resource_manager.h"
 #include "core/hle/kernel/k_memory_block.h"
+#include "core/hle/kernel/k_typed_address.h"
 
 namespace Kernel {
 
@@ -85,9 +85,10 @@ public:
 public:
     KMemoryBlockManager();
 
-    using HostUnmapCallback = std::function<void(VAddr, u64)>;
+    using HostUnmapCallback = std::function<void(Common::ProcessAddress, u64)>;
 
-    Result Initialize(VAddr st, VAddr nd, KMemoryBlockSlabManager* slab_manager);
+    Result Initialize(KProcessAddress st, KProcessAddress nd,
+                      KMemoryBlockSlabManager* slab_manager);
     void Finalize(KMemoryBlockSlabManager* slab_manager, HostUnmapCallback&& host_unmap_callback);
 
     iterator end() {
@@ -100,27 +101,28 @@ public:
         return m_memory_block_tree.cend();
     }
 
-    VAddr FindFreeArea(VAddr region_start, size_t region_num_pages, size_t num_pages,
-                       size_t alignment, size_t offset, size_t guard_pages) const;
+    KProcessAddress FindFreeArea(KProcessAddress region_start, size_t region_num_pages,
+                                 size_t num_pages, size_t alignment, size_t offset,
+                                 size_t guard_pages) const;
 
-    void Update(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, size_t num_pages,
-                KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr,
+    void Update(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address,
+                size_t num_pages, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr,
                 KMemoryBlockDisableMergeAttribute set_disable_attr,
                 KMemoryBlockDisableMergeAttribute clear_disable_attr);
-    void UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, size_t num_pages,
-                    MemoryBlockLockFunction lock_func, KMemoryPermission perm);
+    void UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address,
+                    size_t num_pages, MemoryBlockLockFunction lock_func, KMemoryPermission perm);
 
-    void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
+    void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address,
                        size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm,
                        KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm,
                        KMemoryAttribute attr);
 
-    iterator FindIterator(VAddr address) const {
+    iterator FindIterator(KProcessAddress address) const {
         return m_memory_block_tree.find(KMemoryBlock(
             address, 1, KMemoryState::Free, KMemoryPermission::None, KMemoryAttribute::None));
     }
 
-    const KMemoryBlock* FindBlock(VAddr address) const {
+    const KMemoryBlock* FindBlock(KProcessAddress address) const {
         if (const_iterator it = this->FindIterator(address); it != m_memory_block_tree.end()) {
             return std::addressof(*it);
         }
@@ -132,12 +134,12 @@ public:
     bool CheckState() const;
 
 private:
-    void CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
+    void CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address,
                            size_t num_pages);
 
     MemoryBlockTree m_memory_block_tree;
-    VAddr m_start_address{};
-    VAddr m_end_address{};
+    KProcessAddress m_start_address{};
+    KProcessAddress m_end_address{};
 };
 
 class KScopedMemoryBlockManagerAuditor {
diff --git a/src/core/hle/kernel/k_memory_layout.cpp b/src/core/hle/kernel/k_memory_layout.cpp
index 76ae1e1a4..27f18749a 100755
--- a/src/core/hle/kernel/k_memory_layout.cpp
+++ b/src/core/hle/kernel/k_memory_layout.cpp
@@ -85,7 +85,8 @@ bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_at
     return true;
 }
 
-VAddr KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id) {
+KVirtualAddress KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment,
+                                                          u32 type_id) {
     // We want to find the total extents of the type id.
     const auto extents = this->GetDerivedRegionExtents(static_cast<KMemoryRegionType>(type_id));
 
@@ -130,11 +131,13 @@ KMemoryLayout::KMemoryLayout()
       m_virtual_linear_tree{m_memory_region_allocator}, m_physical_linear_tree{
                                                             m_memory_region_allocator} {}
 
-void KMemoryLayout::InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start,
-                                                      VAddr linear_virtual_start) {
+void KMemoryLayout::InitializeLinearMemoryRegionTrees(KPhysicalAddress aligned_linear_phys_start,
+                                                      KVirtualAddress linear_virtual_start) {
     // Set static differences.
-    m_linear_phys_to_virt_diff = linear_virtual_start - aligned_linear_phys_start;
-    m_linear_virt_to_phys_diff = aligned_linear_phys_start - linear_virtual_start;
+    m_linear_phys_to_virt_diff =
+        GetInteger(linear_virtual_start) - GetInteger(aligned_linear_phys_start);
+    m_linear_virt_to_phys_diff =
+        GetInteger(aligned_linear_phys_start) - GetInteger(linear_virtual_start);
 
     // Initialize linear trees.
     for (auto& region : GetPhysicalMemoryRegionTree()) {
diff --git a/src/core/hle/kernel/k_memory_layout.h b/src/core/hle/kernel/k_memory_layout.h
index 6ff9d2326..3348a6953 100755
--- a/src/core/hle/kernel/k_memory_layout.h
+++ b/src/core/hle/kernel/k_memory_layout.h
@@ -10,6 +10,7 @@
 #include "core/device_memory.h"
 #include "core/hle/kernel/k_memory_region.h"
 #include "core/hle/kernel/k_memory_region_type.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/memory_types.h"
 
 namespace Kernel {
@@ -69,10 +70,11 @@ constexpr std::size_t KernelResourceSize = KernelPageTableHeapSize + KernelIniti
 
 //! NB: Use KThread::GetAddressKeyIsKernel().
 //! See explanation for deviation of GetAddressKey.
-bool IsKernelAddressKey(VAddr key) = delete;
+bool IsKernelAddressKey(KProcessAddress key) = delete;
 
-constexpr bool IsKernelAddress(VAddr address) {
-    return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd;
+constexpr bool IsKernelAddress(KProcessAddress address) {
+    return KernelVirtualAddressSpaceBase <= GetInteger(address) &&
+           address < KernelVirtualAddressSpaceEnd;
 }
 
 class KMemoryLayout final {
@@ -104,38 +106,38 @@ public:
         return m_physical_linear_tree;
     }
 
-    VAddr GetLinearVirtualAddress(PAddr address) const {
-        return address + m_linear_phys_to_virt_diff;
+    KVirtualAddress GetLinearVirtualAddress(KPhysicalAddress address) const {
+        return GetInteger(address) + m_linear_phys_to_virt_diff;
     }
-    PAddr GetLinearPhysicalAddress(VAddr address) const {
-        return address + m_linear_virt_to_phys_diff;
+    KPhysicalAddress GetLinearPhysicalAddress(KVirtualAddress address) const {
+        return GetInteger(address) + m_linear_virt_to_phys_diff;
     }
 
-    const KMemoryRegion* FindVirtual(VAddr address) const {
+    const KMemoryRegion* FindVirtual(KVirtualAddress address) const {
         return Find(address, GetVirtualMemoryRegionTree());
     }
-    const KMemoryRegion* FindPhysical(PAddr address) const {
+    const KMemoryRegion* FindPhysical(KPhysicalAddress address) const {
         return Find(address, GetPhysicalMemoryRegionTree());
     }
 
-    const KMemoryRegion* FindVirtualLinear(VAddr address) const {
+    const KMemoryRegion* FindVirtualLinear(KVirtualAddress address) const {
         return Find(address, GetVirtualLinearMemoryRegionTree());
     }
-    const KMemoryRegion* FindPhysicalLinear(PAddr address) const {
+    const KMemoryRegion* FindPhysicalLinear(KPhysicalAddress address) const {
         return Find(address, GetPhysicalLinearMemoryRegionTree());
     }
 
-    VAddr GetMainStackTopAddress(s32 core_id) const {
+    KVirtualAddress GetMainStackTopAddress(s32 core_id) const {
         return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscMainStack);
     }
-    VAddr GetIdleStackTopAddress(s32 core_id) const {
+    KVirtualAddress GetIdleStackTopAddress(s32 core_id) const {
         return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscIdleStack);
     }
-    VAddr GetExceptionStackTopAddress(s32 core_id) const {
+    KVirtualAddress GetExceptionStackTopAddress(s32 core_id) const {
         return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscExceptionStack);
     }
 
-    VAddr GetSlabRegionAddress() const {
+    KVirtualAddress GetSlabRegionAddress() const {
         return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelSlab))
             .GetAddress();
     }
@@ -143,10 +145,10 @@ public:
     const KMemoryRegion& GetDeviceRegion(KMemoryRegionType type) const {
         return Dereference(GetPhysicalMemoryRegionTree().FindFirstDerived(type));
     }
-    PAddr GetDevicePhysicalAddress(KMemoryRegionType type) const {
+    KPhysicalAddress GetDevicePhysicalAddress(KMemoryRegionType type) const {
         return GetDeviceRegion(type).GetAddress();
     }
-    VAddr GetDeviceVirtualAddress(KMemoryRegionType type) const {
+    KVirtualAddress GetDeviceVirtualAddress(KMemoryRegionType type) const {
         return GetDeviceRegion(type).GetPairAddress();
     }
 
@@ -175,11 +177,11 @@ public:
             KMemoryRegionType_VirtualDramKernelSecureAppletMemory));
     }
 
-    const KMemoryRegion& GetVirtualLinearRegion(VAddr address) const {
+    const KMemoryRegion& GetVirtualLinearRegion(KVirtualAddress address) const {
         return Dereference(FindVirtualLinear(address));
     }
 
-    const KMemoryRegion& GetPhysicalLinearRegion(PAddr address) const {
+    const KMemoryRegion& GetPhysicalLinearRegion(KPhysicalAddress address) const {
         return Dereference(FindPhysicalLinear(address));
     }
 
@@ -193,29 +195,32 @@ public:
         return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DTB);
     }
 
-    bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address) const {
+    bool IsHeapPhysicalAddress(const KMemoryRegion*& region, KPhysicalAddress address) const {
         return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(),
                               KMemoryRegionType_DramUserPool);
     }
-    bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address) const {
+    bool IsHeapVirtualAddress(const KMemoryRegion*& region, KVirtualAddress address) const {
         return IsTypedAddress(region, address, GetVirtualLinearMemoryRegionTree(),
                               KMemoryRegionType_VirtualDramUserPool);
     }
 
-    bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address, size_t size) const {
+    bool IsHeapPhysicalAddress(const KMemoryRegion*& region, KPhysicalAddress address,
+                               size_t size) const {
         return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(),
                               KMemoryRegionType_DramUserPool);
     }
-    bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address, size_t size) const {
+    bool IsHeapVirtualAddress(const KMemoryRegion*& region, KVirtualAddress address,
+                              size_t size) const {
         return IsTypedAddress(region, address, size, GetVirtualLinearMemoryRegionTree(),
                               KMemoryRegionType_VirtualDramUserPool);
     }
 
-    bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address) const {
+    bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region,
+                                       KPhysicalAddress address) const {
         return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(),
                               static_cast<KMemoryRegionType>(KMemoryRegionAttr_LinearMapped));
     }
-    bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address,
+    bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, KPhysicalAddress address,
                                        size_t size) const {
         return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(),
                               static_cast<KMemoryRegionType>(KMemoryRegionAttr_LinearMapped));
@@ -234,8 +239,8 @@ public:
         return std::make_pair(total_size, kernel_size);
     }
 
-    void InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start,
-                                           VAddr linear_virtual_start);
+    void InitializeLinearMemoryRegionTrees(KPhysicalAddress aligned_linear_phys_start,
+                                           KVirtualAddress linear_virtual_start);
     static size_t GetResourceRegionSizeForInit(bool use_extra_resource);
 
     auto GetKernelRegionExtents() const {
@@ -261,8 +266,8 @@ public:
 
     auto GetLinearRegionVirtualExtents() const {
         const auto physical = GetLinearRegionPhysicalExtents();
-        return KMemoryRegion(GetLinearVirtualAddress(physical.GetAddress()),
-                             GetLinearVirtualAddress(physical.GetLastAddress()), 0,
+        return KMemoryRegion(GetInteger(GetLinearVirtualAddress(physical.GetAddress())),
+                             GetInteger(GetLinearVirtualAddress(physical.GetLastAddress())), 0,
                              KMemoryRegionType_None);
     }
 
@@ -334,12 +339,12 @@ private:
     static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address,
                                const KMemoryRegionTree& tree, KMemoryRegionType type) {
         // Check if the cached region already contains the address.
-        if (region != nullptr && region->Contains(address)) {
+        if (region != nullptr && region->Contains(GetInteger(address))) {
             return true;
         }
 
         // Find the containing region, and update the cache.
-        if (const KMemoryRegion* found = tree.Find(address);
+        if (const KMemoryRegion* found = tree.Find(GetInteger(address));
             found != nullptr && found->IsDerivedFrom(type)) {
             region = found;
             return true;
@@ -352,11 +357,12 @@ private:
     static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address, size_t size,
                                const KMemoryRegionTree& tree, KMemoryRegionType type) {
         // Get the end of the checked region.
-        const u64 last_address = address + size - 1;
+        const u64 last_address = GetInteger(address) + size - 1;
 
         // Walk the tree to verify the region is correct.
-        const KMemoryRegion* cur =
-            (region != nullptr && region->Contains(address)) ? region : tree.Find(address);
+        const KMemoryRegion* cur = (region != nullptr && region->Contains(GetInteger(address)))
+                                       ? region
+                                       : tree.Find(GetInteger(address));
         while (cur != nullptr && cur->IsDerivedFrom(type)) {
             if (last_address <= cur->GetLastAddress()) {
                 region = cur;
@@ -370,7 +376,7 @@ private:
 
     template <typename AddressType>
     static const KMemoryRegion* Find(AddressType address, const KMemoryRegionTree& tree) {
-        return tree.Find(address);
+        return tree.Find(GetInteger(address));
     }
 
     static KMemoryRegion& Dereference(KMemoryRegion* region) {
@@ -383,7 +389,7 @@ private:
         return *region;
     }
 
-    VAddr GetStackTopAddress(s32 core_id, KMemoryRegionType type) const {
+    KVirtualAddress GetStackTopAddress(s32 core_id, KMemoryRegionType type) const {
         const auto& region = Dereference(
             GetVirtualMemoryRegionTree().FindByTypeAndAttribute(type, static_cast<u32>(core_id)));
         ASSERT(region.GetEndAddress() != 0);
diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp
index 42f8c4a6c..d89246489 100755
--- a/src/core/hle/kernel/k_memory_manager.cpp
+++ b/src/core/hle/kernel/k_memory_manager.cpp
@@ -5,7 +5,6 @@
 
 #include "common/alignment.h"
 #include "common/assert.h"
-#include "common/common_types.h"
 #include "common/scope_exit.h"
 #include "core/core.h"
 #include "core/device_memory.h"
@@ -44,10 +43,10 @@ KMemoryManager::KMemoryManager(Core::System& system)
           KLightLock{system.Kernel()},
       } {}
 
-void KMemoryManager::Initialize(VAddr management_region, size_t management_region_size) {
+void KMemoryManager::Initialize(KVirtualAddress management_region, size_t management_region_size) {
 
     // Clear the management region to zero.
-    const VAddr management_region_end = management_region + management_region_size;
+    const KVirtualAddress management_region_end = management_region + management_region_size;
     // std::memset(GetVoidPointer(management_region), 0, management_region_size);
 
     // Reset our manager count.
@@ -56,7 +55,7 @@ void KMemoryManager::Initialize(VAddr management_region, size_t management_regio
     // Traverse the virtual memory layout tree, initializing each manager as appropriate.
     while (m_num_managers != MaxManagerCount) {
         // Locate the region that should initialize the current manager.
-        PAddr region_address = 0;
+        KPhysicalAddress region_address = 0;
         size_t region_size = 0;
         Pool region_pool = Pool::Count;
         for (const auto& it : m_system.Kernel().MemoryLayout().GetPhysicalMemoryRegionTree()) {
@@ -70,8 +69,8 @@ void KMemoryManager::Initialize(VAddr management_region, size_t management_regio
                 continue;
             }
 
-            const PAddr cur_start = it.GetAddress();
-            const PAddr cur_end = it.GetEndAddress();
+            const KPhysicalAddress cur_start = it.GetAddress();
+            const KPhysicalAddress cur_end = it.GetEndAddress();
 
             // Validate the region.
             ASSERT(cur_end != 0);
@@ -119,17 +118,17 @@ void KMemoryManager::Initialize(VAddr management_region, size_t management_regio
 
     // Free each region to its corresponding heap.
     size_t reserved_sizes[MaxManagerCount] = {};
-    const PAddr ini_start = GetInitialProcessBinaryPhysicalAddress();
-    const PAddr ini_end = ini_start + InitialProcessBinarySizeMax;
-    const PAddr ini_last = ini_end - 1;
+    const KPhysicalAddress ini_start = GetInitialProcessBinaryPhysicalAddress();
+    const KPhysicalAddress ini_end = ini_start + InitialProcessBinarySizeMax;
+    const KPhysicalAddress ini_last = ini_end - 1;
     for (const auto& it : m_system.Kernel().MemoryLayout().GetPhysicalMemoryRegionTree()) {
         if (it.IsDerivedFrom(KMemoryRegionType_DramUserPool)) {
             // Get the manager for the region.
             auto& manager = m_managers[it.GetAttributes()];
 
-            const PAddr cur_start = it.GetAddress();
-            const PAddr cur_last = it.GetLastAddress();
-            const PAddr cur_end = it.GetEndAddress();
+            const KPhysicalAddress cur_start = it.GetAddress();
+            const KPhysicalAddress cur_last = it.GetLastAddress();
+            const KPhysicalAddress cur_end = it.GetEndAddress();
 
             if (cur_start <= ini_start && ini_last <= cur_last) {
                 // Free memory before the ini to the heap.
@@ -175,7 +174,8 @@ void KMemoryManager::FinalizeOptimizedMemory(u64 process_id, Pool pool) {
     UNREACHABLE();
 }
 
-PAddr KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option) {
+KPhysicalAddress KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_pages,
+                                                           u32 option) {
     // Early return if we're allocating no pages.
     if (num_pages == 0) {
         return 0;
@@ -190,7 +190,7 @@ PAddr KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_p
 
     // Loop, trying to iterate from each block.
     Impl* chosen_manager = nullptr;
-    PAddr allocated_block = 0;
+    KPhysicalAddress allocated_block = 0;
     for (chosen_manager = this->GetFirstManager(pool, dir); chosen_manager != nullptr;
          chosen_manager = this->GetNextManager(chosen_manager, dir)) {
         allocated_block = chosen_manager->AllocateAligned(heap_index, num_pages, align_pages);
@@ -239,7 +239,7 @@ Result KMemoryManager::AllocatePageGroupImpl(KPageGroup* out, size_t num_pages,
              cur_manager = this->GetNextManager(cur_manager, dir)) {
             while (num_pages >= pages_per_alloc) {
                 // Allocate a block.
-                PAddr allocated_block = cur_manager->AllocateBlock(index, random);
+                KPhysicalAddress allocated_block = cur_manager->AllocateBlock(index, random);
                 if (allocated_block == 0) {
                     break;
                 }
@@ -286,7 +286,7 @@ Result KMemoryManager::AllocateAndOpen(KPageGroup* out, size_t num_pages, u32 op
 
     // Open the first reference to the pages.
     for (const auto& block : *out) {
-        PAddr cur_address = block.GetAddress();
+        KPhysicalAddress cur_address = block.GetAddress();
         size_t remaining_pages = block.GetNumPages();
         while (remaining_pages > 0) {
             // Get the manager for the current address.
@@ -337,7 +337,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
         // Iterate over the allocated blocks.
         for (const auto& block : *out) {
             // Get the block extents.
-            const PAddr block_address = block.GetAddress();
+            const KPhysicalAddress block_address = block.GetAddress();
             const size_t block_pages = block.GetNumPages();
 
             // If it has no pages, we don't need to do anything.
@@ -348,7 +348,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
             // Fill all the pages that we need to fill.
             bool any_new = false;
             {
-                PAddr cur_address = block_address;
+                KPhysicalAddress cur_address = block_address;
                 size_t remaining_pages = block_pages;
                 while (remaining_pages > 0) {
                     // Get the manager for the current address.
@@ -369,7 +369,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
             // If there are new pages, update tracking for the allocation.
             if (any_new) {
                 // Update tracking for the allocation.
-                PAddr cur_address = block_address;
+                KPhysicalAddress cur_address = block_address;
                 size_t remaining_pages = block_pages;
                 while (remaining_pages > 0) {
                     // Get the manager for the current address.
@@ -400,8 +400,9 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
     R_SUCCEED();
 }
 
-size_t KMemoryManager::Impl::Initialize(PAddr address, size_t size, VAddr management,
-                                        VAddr management_end, Pool p) {
+size_t KMemoryManager::Impl::Initialize(KPhysicalAddress address, size_t size,
+                                        KVirtualAddress management, KVirtualAddress management_end,
+                                        Pool p) {
     // Calculate management sizes.
     const size_t ref_count_size = (size / PageSize) * sizeof(u16);
     const size_t optimize_map_size = CalculateOptimizedProcessOverheadSize(size);
@@ -417,7 +418,7 @@ size_t KMemoryManager::Impl::Initialize(PAddr address, size_t size, VAddr manage
     m_management_region = management;
     m_page_reference_counts.resize(
         Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetIntendedMemorySize() / PageSize);
-    ASSERT(Common::IsAligned(m_management_region, PageSize));
+    ASSERT(Common::IsAligned(GetInteger(m_management_region), PageSize));
 
     // Initialize the manager's KPageHeap.
     m_heap.Initialize(address, size, management + manager_size, page_heap_size);
@@ -425,15 +426,15 @@ size_t KMemoryManager::Impl::Initialize(PAddr address, size_t size, VAddr manage
     return total_management_size;
 }
 
-void KMemoryManager::Impl::TrackUnoptimizedAllocation(PAddr block, size_t num_pages) {
+void KMemoryManager::Impl::TrackUnoptimizedAllocation(KPhysicalAddress block, size_t num_pages) {
     UNREACHABLE();
 }
 
-void KMemoryManager::Impl::TrackOptimizedAllocation(PAddr block, size_t num_pages) {
+void KMemoryManager::Impl::TrackOptimizedAllocation(KPhysicalAddress block, size_t num_pages) {
     UNREACHABLE();
 }
 
-bool KMemoryManager::Impl::ProcessOptimizedAllocation(PAddr block, size_t num_pages,
+bool KMemoryManager::Impl::ProcessOptimizedAllocation(KPhysicalAddress block, size_t num_pages,
                                                       u8 fill_pattern) {
     UNREACHABLE();
 }
diff --git a/src/core/hle/kernel/k_memory_manager.h b/src/core/hle/kernel/k_memory_manager.h
index ef88822cd..c6836ea0d 100755
--- a/src/core/hle/kernel/k_memory_manager.h
+++ b/src/core/hle/kernel/k_memory_manager.h
@@ -7,10 +7,10 @@
 #include <tuple>
 
 #include "common/common_funcs.h"
-#include "common/common_types.h"
 #include "core/hle/kernel/k_light_lock.h"
 #include "core/hle/kernel/k_memory_layout.h"
 #include "core/hle/kernel/k_page_heap.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/result.h"
 
 namespace Core {
@@ -50,21 +50,21 @@ public:
 
     explicit KMemoryManager(Core::System& system);
 
-    void Initialize(VAddr management_region, size_t management_region_size);
+    void Initialize(KVirtualAddress management_region, size_t management_region_size);
 
     Result InitializeOptimizedMemory(u64 process_id, Pool pool);
     void FinalizeOptimizedMemory(u64 process_id, Pool pool);
 
-    PAddr AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option);
+    KPhysicalAddress AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option);
     Result AllocateAndOpen(KPageGroup* out, size_t num_pages, u32 option);
     Result AllocateForProcess(KPageGroup* out, size_t num_pages, u32 option, u64 process_id,
                               u8 fill_pattern);
 
-    Pool GetPool(PAddr address) const {
+    Pool GetPool(KPhysicalAddress address) const {
         return this->GetManager(address).GetPool();
     }
 
-    void Open(PAddr address, size_t num_pages) {
+    void Open(KPhysicalAddress address, size_t num_pages) {
         // Repeatedly open references until we've done so for all pages.
         while (num_pages) {
             auto& manager = this->GetManager(address);
@@ -80,7 +80,7 @@ public:
         }
     }
 
-    void OpenFirst(PAddr address, size_t num_pages) {
+    void OpenFirst(KPhysicalAddress address, size_t num_pages) {
         // Repeatedly open references until we've done so for all pages.
         while (num_pages) {
             auto& manager = this->GetManager(address);
@@ -96,7 +96,7 @@ public:
         }
     }
 
-    void Close(PAddr address, size_t num_pages) {
+    void Close(KPhysicalAddress address, size_t num_pages) {
         // Repeatedly close references until we've done so for all pages.
         while (num_pages) {
             auto& manager = this->GetManager(address);
@@ -199,16 +199,16 @@ private:
     public:
         Impl() = default;
 
-        size_t Initialize(PAddr address, size_t size, VAddr management, VAddr management_end,
-                          Pool p);
+        size_t Initialize(KPhysicalAddress address, size_t size, KVirtualAddress management,
+                          KVirtualAddress management_end, Pool p);
 
-        PAddr AllocateBlock(s32 index, bool random) {
+        KPhysicalAddress AllocateBlock(s32 index, bool random) {
             return m_heap.AllocateBlock(index, random);
         }
-        PAddr AllocateAligned(s32 index, size_t num_pages, size_t align_pages) {
+        KPhysicalAddress AllocateAligned(s32 index, size_t num_pages, size_t align_pages) {
             return m_heap.AllocateAligned(index, num_pages, align_pages);
         }
-        void Free(PAddr addr, size_t num_pages) {
+        void Free(KPhysicalAddress addr, size_t num_pages) {
             m_heap.Free(addr, num_pages);
         }
 
@@ -220,10 +220,10 @@ private:
             UNIMPLEMENTED();
         }
 
-        void TrackUnoptimizedAllocation(PAddr block, size_t num_pages);
-        void TrackOptimizedAllocation(PAddr block, size_t num_pages);
+        void TrackUnoptimizedAllocation(KPhysicalAddress block, size_t num_pages);
+        void TrackOptimizedAllocation(KPhysicalAddress block, size_t num_pages);
 
-        bool ProcessOptimizedAllocation(PAddr block, size_t num_pages, u8 fill_pattern);
+        bool ProcessOptimizedAllocation(KPhysicalAddress block, size_t num_pages, u8 fill_pattern);
 
         constexpr Pool GetPool() const {
             return m_pool;
@@ -231,7 +231,7 @@ private:
         constexpr size_t GetSize() const {
             return m_heap.GetSize();
         }
-        constexpr PAddr GetEndAddress() const {
+        constexpr KPhysicalAddress GetEndAddress() const {
             return m_heap.GetEndAddress();
         }
 
@@ -243,10 +243,10 @@ private:
             UNIMPLEMENTED();
         }
 
-        constexpr size_t GetPageOffset(PAddr address) const {
+        constexpr size_t GetPageOffset(KPhysicalAddress address) const {
             return m_heap.GetPageOffset(address);
         }
-        constexpr size_t GetPageOffsetToEnd(PAddr address) const {
+        constexpr size_t GetPageOffsetToEnd(KPhysicalAddress address) const {
             return m_heap.GetPageOffsetToEnd(address);
         }
 
@@ -263,7 +263,7 @@ private:
             return m_prev;
         }
 
-        void OpenFirst(PAddr address, size_t num_pages) {
+        void OpenFirst(KPhysicalAddress address, size_t num_pages) {
             size_t index = this->GetPageOffset(address);
             const size_t end = index + num_pages;
             while (index < end) {
@@ -274,7 +274,7 @@ private:
             }
         }
 
-        void Open(PAddr address, size_t num_pages) {
+        void Open(KPhysicalAddress address, size_t num_pages) {
             size_t index = this->GetPageOffset(address);
             const size_t end = index + num_pages;
             while (index < end) {
@@ -285,7 +285,7 @@ private:
             }
         }
 
-        void Close(PAddr address, size_t num_pages) {
+        void Close(KPhysicalAddress address, size_t num_pages) {
             size_t index = this->GetPageOffset(address);
             const size_t end = index + num_pages;
 
@@ -323,18 +323,18 @@ private:
 
         KPageHeap m_heap;
         std::vector<RefCount> m_page_reference_counts;
-        VAddr m_management_region{};
+        KVirtualAddress m_management_region{};
         Pool m_pool{};
         Impl* m_next{};
         Impl* m_prev{};
     };
 
 private:
-    Impl& GetManager(PAddr address) {
+    Impl& GetManager(KPhysicalAddress address) {
         return m_managers[m_memory_layout.GetPhysicalLinearRegion(address).GetAttributes()];
     }
 
-    const Impl& GetManager(PAddr address) const {
+    const Impl& GetManager(KPhysicalAddress address) const {
         return m_managers[m_memory_layout.GetPhysicalLinearRegion(address).GetAttributes()];
     }
 
diff --git a/src/core/hle/kernel/k_memory_region.h b/src/core/hle/kernel/k_memory_region.h
index dbd6747ff..60615bfd2 100755
--- a/src/core/hle/kernel/k_memory_region.h
+++ b/src/core/hle/kernel/k_memory_region.h
@@ -5,9 +5,9 @@
 
 #include "common/assert.h"
 #include "common/common_funcs.h"
-#include "common/common_types.h"
 #include "common/intrusive_red_black_tree.h"
 #include "core/hle/kernel/k_memory_region_type.h"
+#include "core/hle/kernel/k_typed_address.h"
 
 namespace Kernel {
 
@@ -243,10 +243,10 @@ public:
     void InsertDirectly(u64 address, u64 last_address, u32 attr = 0, u32 type_id = 0);
     bool Insert(u64 address, size_t size, u32 type_id, u32 new_attr = 0, u32 old_attr = 0);
 
-    VAddr GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id);
+    KVirtualAddress GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id);
 
-    VAddr GetRandomAlignedRegionWithGuard(size_t size, size_t alignment, u32 type_id,
-                                          size_t guard_size) {
+    KVirtualAddress GetRandomAlignedRegionWithGuard(size_t size, size_t alignment, u32 type_id,
+                                                    size_t guard_size) {
         return this->GetRandomAlignedRegion(size + 2 * guard_size, alignment, type_id) + guard_size;
     }
 
diff --git a/src/core/hle/kernel/k_page_buffer.cpp b/src/core/hle/kernel/k_page_buffer.cpp
index f8022777c..d184b6700 100755
--- a/src/core/hle/kernel/k_page_buffer.cpp
+++ b/src/core/hle/kernel/k_page_buffer.cpp
@@ -10,8 +10,8 @@
 
 namespace Kernel {
 
-KPageBuffer* KPageBuffer::FromPhysicalAddress(Core::System& system, PAddr phys_addr) {
-    ASSERT(Common::IsAligned(phys_addr, PageSize));
+KPageBuffer* KPageBuffer::FromPhysicalAddress(Core::System& system, KPhysicalAddress phys_addr) {
+    ASSERT(Common::IsAligned(GetInteger(phys_addr), PageSize));
     return system.DeviceMemory().GetPointer<KPageBuffer>(phys_addr);
 }
 
diff --git a/src/core/hle/kernel/k_page_buffer.h b/src/core/hle/kernel/k_page_buffer.h
index 0cbd3c291..1a38f935d 100755
--- a/src/core/hle/kernel/k_page_buffer.h
+++ b/src/core/hle/kernel/k_page_buffer.h
@@ -26,7 +26,7 @@ public:
     explicit KPageBuffer(KernelCore&) {}
     KPageBuffer() = default;
 
-    static KPageBuffer* FromPhysicalAddress(Core::System& system, PAddr phys_addr);
+    static KPageBuffer* FromPhysicalAddress(Core::System& system, KPhysicalAddress phys_addr);
 
 private:
     alignas(PageSize) std::array<u8, PageSize> m_buffer{};
diff --git a/src/core/hle/kernel/k_page_group.h b/src/core/hle/kernel/k_page_group.h
index b0071febb..3c429594d 100755
--- a/src/core/hle/kernel/k_page_group.h
+++ b/src/core/hle/kernel/k_page_group.h
@@ -22,7 +22,7 @@ public:
     constexpr explicit KBlockInfo() : m_next(nullptr) {}
 
     constexpr void Initialize(KPhysicalAddress addr, size_t np) {
-        ASSERT(Common::IsAligned(addr, PageSize));
+        ASSERT(Common::IsAligned(GetInteger(addr), PageSize));
         ASSERT(static_cast<u32>(np) == np);
 
         m_page_index = static_cast<u32>(addr / PageSize);
diff --git a/src/core/hle/kernel/k_page_heap.cpp b/src/core/hle/kernel/k_page_heap.cpp
index b45d0226f..08ee2916c 100755
--- a/src/core/hle/kernel/k_page_heap.cpp
+++ b/src/core/hle/kernel/k_page_heap.cpp
@@ -6,14 +6,14 @@
 
 namespace Kernel {
 
-void KPageHeap::Initialize(PAddr address, size_t size, VAddr management_address,
-                           size_t management_size, const size_t* block_shifts,
-                           size_t num_block_shifts) {
+void KPageHeap::Initialize(KPhysicalAddress address, size_t size,
+                           KVirtualAddress management_address, size_t management_size,
+                           const size_t* block_shifts, size_t num_block_shifts) {
     // Check our assumptions.
-    ASSERT(Common::IsAligned(address, PageSize));
+    ASSERT(Common::IsAligned(GetInteger(address), PageSize));
     ASSERT(Common::IsAligned(size, PageSize));
     ASSERT(0 < num_block_shifts && num_block_shifts <= NumMemoryBlockPageShifts);
-    const VAddr management_end = management_address + management_size;
+    const KVirtualAddress management_end = management_address + management_size;
 
     // Set our members.
     m_heap_address = address;
@@ -31,7 +31,7 @@ void KPageHeap::Initialize(PAddr address, size_t size, VAddr management_address,
     }
 
     // Ensure we didn't overextend our bounds.
-    ASSERT(VAddr(cur_bitmap_storage) <= management_end);
+    ASSERT(KVirtualAddress(cur_bitmap_storage) <= management_end);
 }
 
 size_t KPageHeap::GetNumFreePages() const {
@@ -44,11 +44,11 @@ size_t KPageHeap::GetNumFreePages() const {
     return num_free;
 }
 
-PAddr KPageHeap::AllocateByLinearSearch(s32 index) {
+KPhysicalAddress KPageHeap::AllocateByLinearSearch(s32 index) {
     const size_t needed_size = m_blocks[index].GetSize();
 
     for (s32 i = index; i < static_cast<s32>(m_num_blocks); i++) {
-        if (const PAddr addr = m_blocks[i].PopBlock(false); addr != 0) {
+        if (const KPhysicalAddress addr = m_blocks[i].PopBlock(false); addr != 0) {
             if (const size_t allocated_size = m_blocks[i].GetSize(); allocated_size > needed_size) {
                 this->Free(addr + needed_size, (allocated_size - needed_size) / PageSize);
             }
@@ -59,7 +59,7 @@ PAddr KPageHeap::AllocateByLinearSearch(s32 index) {
     return 0;
 }
 
-PAddr KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_pages) {
+KPhysicalAddress KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_pages) {
     // Get the size and required alignment.
     const size_t needed_size = num_pages * PageSize;
     const size_t align_size = align_pages * PageSize;
@@ -110,7 +110,7 @@ PAddr KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_page
     }
 
     // Pop a block from the index we selected.
-    if (PAddr addr = m_blocks[index].PopBlock(true); addr != 0) {
+    if (KPhysicalAddress addr = m_blocks[index].PopBlock(true); addr != 0) {
         // Determine how much size we have left over.
         if (const size_t leftover_size = m_blocks[index].GetSize() - needed_size;
             leftover_size > 0) {
@@ -141,13 +141,13 @@ PAddr KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_page
     return 0;
 }
 
-void KPageHeap::FreeBlock(PAddr block, s32 index) {
+void KPageHeap::FreeBlock(KPhysicalAddress block, s32 index) {
     do {
         block = m_blocks[index++].PushBlock(block);
     } while (block != 0);
 }
 
-void KPageHeap::Free(PAddr addr, size_t num_pages) {
+void KPageHeap::Free(KPhysicalAddress addr, size_t num_pages) {
     // Freeing no pages is a no-op.
     if (num_pages == 0) {
         return;
@@ -155,16 +155,16 @@ void KPageHeap::Free(PAddr addr, size_t num_pages) {
 
     // Find the largest block size that we can free, and free as many as possible.
     s32 big_index = static_cast<s32>(m_num_blocks) - 1;
-    const PAddr start = addr;
-    const PAddr end = addr + num_pages * PageSize;
-    PAddr before_start = start;
-    PAddr before_end = start;
-    PAddr after_start = end;
-    PAddr after_end = end;
+    const KPhysicalAddress start = addr;
+    const KPhysicalAddress end = addr + num_pages * PageSize;
+    KPhysicalAddress before_start = start;
+    KPhysicalAddress before_end = start;
+    KPhysicalAddress after_start = end;
+    KPhysicalAddress after_end = end;
     while (big_index >= 0) {
         const size_t block_size = m_blocks[big_index].GetSize();
-        const PAddr big_start = Common::AlignUp(start, block_size);
-        const PAddr big_end = Common::AlignDown(end, block_size);
+        const KPhysicalAddress big_start = Common::AlignUp(GetInteger(start), block_size);
+        const KPhysicalAddress big_end = Common::AlignDown(GetInteger(end), block_size);
         if (big_start < big_end) {
             // Free as many big blocks as we can.
             for (auto block = big_start; block < big_end; block += block_size) {
diff --git a/src/core/hle/kernel/k_page_heap.h b/src/core/hle/kernel/k_page_heap.h
index 7ee606259..1edb5b419 100755
--- a/src/core/hle/kernel/k_page_heap.h
+++ b/src/core/hle/kernel/k_page_heap.h
@@ -8,8 +8,8 @@
 
 #include "common/alignment.h"
 #include "common/common_funcs.h"
-#include "common/common_types.h"
 #include "core/hle/kernel/k_page_bitmap.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/memory_types.h"
 
 namespace Kernel {
@@ -18,24 +18,24 @@ class KPageHeap {
 public:
     KPageHeap() = default;
 
-    constexpr PAddr GetAddress() const {
+    constexpr KPhysicalAddress GetAddress() const {
         return m_heap_address;
     }
     constexpr size_t GetSize() const {
         return m_heap_size;
     }
-    constexpr PAddr GetEndAddress() const {
+    constexpr KPhysicalAddress GetEndAddress() const {
         return this->GetAddress() + this->GetSize();
     }
-    constexpr size_t GetPageOffset(PAddr block) const {
+    constexpr size_t GetPageOffset(KPhysicalAddress block) const {
         return (block - this->GetAddress()) / PageSize;
     }
-    constexpr size_t GetPageOffsetToEnd(PAddr block) const {
+    constexpr size_t GetPageOffsetToEnd(KPhysicalAddress block) const {
         return (this->GetEndAddress() - block) / PageSize;
     }
 
-    void Initialize(PAddr heap_address, size_t heap_size, VAddr management_address,
-                    size_t management_size) {
+    void Initialize(KPhysicalAddress heap_address, size_t heap_size,
+                    KVirtualAddress management_address, size_t management_size) {
         return this->Initialize(heap_address, heap_size, management_address, management_size,
                                 MemoryBlockPageShifts.data(), NumMemoryBlockPageShifts);
     }
@@ -53,7 +53,7 @@ public:
         m_initial_used_size = m_heap_size - free_size - reserved_size;
     }
 
-    PAddr AllocateBlock(s32 index, bool random) {
+    KPhysicalAddress AllocateBlock(s32 index, bool random) {
         if (random) {
             const size_t block_pages = m_blocks[index].GetNumPages();
             return this->AllocateByRandom(index, block_pages, block_pages);
@@ -62,12 +62,12 @@ public:
         }
     }
 
-    PAddr AllocateAligned(s32 index, size_t num_pages, size_t align_pages) {
+    KPhysicalAddress AllocateAligned(s32 index, size_t num_pages, size_t align_pages) {
         // TODO: linear search support?
         return this->AllocateByRandom(index, num_pages, align_pages);
     }
 
-    void Free(PAddr addr, size_t num_pages);
+    void Free(KPhysicalAddress addr, size_t num_pages);
 
     static size_t CalculateManagementOverheadSize(size_t region_size) {
         return CalculateManagementOverheadSize(region_size, MemoryBlockPageShifts.data(),
@@ -125,24 +125,25 @@ private:
             return this->GetNumFreeBlocks() * this->GetNumPages();
         }
 
-        u64* Initialize(PAddr addr, size_t size, size_t bs, size_t nbs, u64* bit_storage) {
+        u64* Initialize(KPhysicalAddress addr, size_t size, size_t bs, size_t nbs,
+                        u64* bit_storage) {
             // Set shifts.
             m_block_shift = bs;
             m_next_block_shift = nbs;
 
             // Align up the address.
-            PAddr end = addr + size;
+            KPhysicalAddress end = addr + size;
             const size_t align = (m_next_block_shift != 0) ? (u64(1) << m_next_block_shift)
                                                            : (u64(1) << m_block_shift);
-            addr = Common::AlignDown(addr, align);
-            end = Common::AlignUp(end, align);
+            addr = Common::AlignDown(GetInteger(addr), align);
+            end = Common::AlignUp(GetInteger(end), align);
 
             m_heap_address = addr;
             m_end_offset = (end - addr) / (u64(1) << m_block_shift);
             return m_bitmap.Initialize(bit_storage, m_end_offset);
         }
 
-        PAddr PushBlock(PAddr address) {
+        KPhysicalAddress PushBlock(KPhysicalAddress address) {
             // Set the bit for the free block.
             size_t offset = (address - m_heap_address) >> this->GetShift();
             m_bitmap.SetBit(offset);
@@ -161,7 +162,7 @@ private:
             return {};
         }
 
-        PAddr PopBlock(bool random) {
+        KPhysicalAddress PopBlock(bool random) {
             // Find a free block.
             s64 soffset = m_bitmap.FindFreeBlock(random);
             if (soffset < 0) {
@@ -187,18 +188,19 @@ private:
 
     private:
         KPageBitmap m_bitmap;
-        PAddr m_heap_address{};
+        KPhysicalAddress m_heap_address{};
         uintptr_t m_end_offset{};
         size_t m_block_shift{};
         size_t m_next_block_shift{};
     };
 
 private:
-    void Initialize(PAddr heap_address, size_t heap_size, VAddr management_address,
-                    size_t management_size, const size_t* block_shifts, size_t num_block_shifts);
+    void Initialize(KPhysicalAddress heap_address, size_t heap_size,
+                    KVirtualAddress management_address, size_t management_size,
+                    const size_t* block_shifts, size_t num_block_shifts);
     size_t GetNumFreePages() const;
 
-    void FreeBlock(PAddr block, s32 index);
+    void FreeBlock(KPhysicalAddress block, s32 index);
 
     static constexpr size_t NumMemoryBlockPageShifts{7};
     static constexpr std::array<size_t, NumMemoryBlockPageShifts> MemoryBlockPageShifts{
@@ -206,14 +208,14 @@ private:
     };
 
 private:
-    PAddr AllocateByLinearSearch(s32 index);
-    PAddr AllocateByRandom(s32 index, size_t num_pages, size_t align_pages);
+    KPhysicalAddress AllocateByLinearSearch(s32 index);
+    KPhysicalAddress AllocateByRandom(s32 index, size_t num_pages, size_t align_pages);
 
     static size_t CalculateManagementOverheadSize(size_t region_size, const size_t* block_shifts,
                                                   size_t num_block_shifts);
 
 private:
-    PAddr m_heap_address{};
+    KPhysicalAddress m_heap_address{};
     size_t m_heap_size{};
     size_t m_initial_used_size{};
     size_t m_num_blocks{};
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index e72441a8d..74f6f3865 100755
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -106,7 +106,7 @@ KPageTable::~KPageTable() = default;
 
 Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
                                         bool enable_das_merge, bool from_back,
-                                        KMemoryManager::Pool pool, VAddr code_addr,
+                                        KMemoryManager::Pool pool, KProcessAddress code_addr,
                                         size_t code_size, KSystemResource* system_resource,
                                         KResourceLimit* resource_limit) {
 
@@ -119,8 +119,8 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
 
     //  Set our width and heap/alias sizes
     m_address_space_width = GetAddressSpaceWidthFromType(as_type);
-    const VAddr start = 0;
-    const VAddr end{1ULL << m_address_space_width};
+    const KProcessAddress start = 0;
+    const KProcessAddress end{1ULL << m_address_space_width};
     size_t alias_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Alias)};
     size_t heap_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Heap)};
 
@@ -135,8 +135,8 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
 
     // Set code regions and determine remaining
     constexpr size_t RegionAlignment{2_MiB};
-    VAddr process_code_start{};
-    VAddr process_code_end{};
+    KProcessAddress process_code_start{};
+    KProcessAddress process_code_end{};
     size_t stack_region_size{};
     size_t kernel_map_region_size{};
 
@@ -149,8 +149,8 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
         m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::Map39Bit);
         m_alias_code_region_start = m_code_region_start;
         m_alias_code_region_end = m_code_region_end;
-        process_code_start = Common::AlignDown(code_addr, RegionAlignment);
-        process_code_end = Common::AlignUp(code_addr + code_size, RegionAlignment);
+        process_code_start = Common::AlignDown(GetInteger(code_addr), RegionAlignment);
+        process_code_end = Common::AlignUp(GetInteger(code_addr) + code_size, RegionAlignment);
     } else {
         stack_region_size = 0;
         kernel_map_region_size = 0;
@@ -178,7 +178,7 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
     m_resource_limit = resource_limit;
 
     // Determine the region we can place our undetermineds in
-    VAddr alloc_start{};
+    KProcessAddress alloc_start{};
     size_t alloc_size{};
     if ((process_code_start - m_code_region_start) >= (end - process_code_end)) {
         alloc_start = m_code_region_start;
@@ -292,7 +292,7 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
                                                      : KMemoryManager::Direction::FromFront);
 
     // Ensure that we regions inside our address space
-    auto IsInAddressSpace = [&](VAddr addr) {
+    auto IsInAddressSpace = [&](KProcessAddress addr) {
         return m_address_space_start <= addr && addr <= m_address_space_end;
     };
     ASSERT(IsInAddressSpace(m_alias_region_start));
@@ -305,14 +305,14 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
     ASSERT(IsInAddressSpace(m_kernel_map_region_end));
 
     // Ensure that we selected regions that don't overlap
-    const VAddr alias_start{m_alias_region_start};
-    const VAddr alias_last{m_alias_region_end - 1};
-    const VAddr heap_start{m_heap_region_start};
-    const VAddr heap_last{m_heap_region_end - 1};
-    const VAddr stack_start{m_stack_region_start};
-    const VAddr stack_last{m_stack_region_end - 1};
-    const VAddr kmap_start{m_kernel_map_region_start};
-    const VAddr kmap_last{m_kernel_map_region_end - 1};
+    const KProcessAddress alias_start{m_alias_region_start};
+    const KProcessAddress alias_last{m_alias_region_end - 1};
+    const KProcessAddress heap_start{m_heap_region_start};
+    const KProcessAddress heap_last{m_heap_region_end - 1};
+    const KProcessAddress stack_start{m_stack_region_start};
+    const KProcessAddress stack_last{m_stack_region_end - 1};
+    const KProcessAddress kmap_start{m_kernel_map_region_start};
+    const KProcessAddress kmap_last{m_kernel_map_region_end - 1};
     ASSERT(alias_last < heap_start || heap_last < alias_start);
     ASSERT(alias_last < stack_start || stack_last < alias_start);
     ASSERT(alias_last < kmap_start || kmap_last < alias_start);
@@ -334,9 +334,10 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
 
 void KPageTable::Finalize() {
     // Finalize memory blocks.
-    m_memory_block_manager.Finalize(m_memory_block_slab_manager, [&](VAddr addr, u64 size) {
-        m_system.Memory().UnmapRegion(*m_page_table_impl, addr, size);
-    });
+    m_memory_block_manager.Finalize(
+        m_memory_block_slab_manager, [&](KProcessAddress addr, u64 size) {
+            m_system.Memory().UnmapRegion(*m_page_table_impl, addr, size);
+        });
 
     // Release any insecure mapped memory.
     if (m_mapped_insecure_memory) {
@@ -352,7 +353,7 @@ void KPageTable::Finalize() {
     m_page_table_impl.reset();
 }
 
-Result KPageTable::MapProcessCode(VAddr addr, size_t num_pages, KMemoryState state,
+Result KPageTable::MapProcessCode(KProcessAddress addr, size_t num_pages, KMemoryState state,
                                   KMemoryPermission perm) {
     const u64 size{num_pages * PageSize};
 
@@ -388,7 +389,8 @@ Result KPageTable::MapProcessCode(VAddr addr, size_t num_pages, KMemoryState sta
     R_SUCCEED();
 }
 
-Result KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, size_t size) {
+Result KPageTable::MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address,
+                                 size_t size) {
     // Validate the mapping request.
     R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode),
              ResultInvalidMemoryRegion);
@@ -473,7 +475,8 @@ Result KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, size_t si
     R_SUCCEED();
 }
 
-Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, size_t size,
+Result KPageTable::UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address,
+                                   size_t size,
                                    ICacheInvalidationStrategy icache_invalidation_strategy) {
     // Validate the mapping request.
     R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode),
@@ -525,7 +528,7 @@ Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, size_t
     SCOPE_EXIT({
         if (reprotected_pages && any_code_pages) {
             if (icache_invalidation_strategy == ICacheInvalidationStrategy::InvalidateRange) {
-                m_system.InvalidateCpuInstructionCacheRange(dst_address, size);
+                m_system.InvalidateCpuInstructionCacheRange(GetInteger(dst_address), size);
             } else {
                 m_system.InvalidateCpuInstructionCaches();
             }
@@ -575,9 +578,10 @@ Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, size_t
     R_SUCCEED();
 }
 
-VAddr KPageTable::FindFreeArea(VAddr region_start, size_t region_num_pages, size_t num_pages,
-                               size_t alignment, size_t offset, size_t guard_pages) {
-    VAddr address = 0;
+KProcessAddress KPageTable::FindFreeArea(KProcessAddress region_start, size_t region_num_pages,
+                                         size_t num_pages, size_t alignment, size_t offset,
+                                         size_t guard_pages) {
+    KProcessAddress address = 0;
 
     if (num_pages <= region_num_pages) {
         if (this->IsAslrEnabled()) {
@@ -593,7 +597,7 @@ VAddr KPageTable::FindFreeArea(VAddr region_start, size_t region_num_pages, size
     return address;
 }
 
-Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) {
+Result KPageTable::MakePageGroup(KPageGroup& pg, KProcessAddress addr, size_t num_pages) {
     ASSERT(this->IsLockedByCurrentThread());
 
     const size_t size = num_pages * PageSize;
@@ -604,11 +608,11 @@ Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) {
     // Begin traversal.
     Common::PageTable::TraversalContext context;
     Common::PageTable::TraversalEntry next_entry;
-    R_UNLESS(m_page_table_impl->BeginTraversal(next_entry, context, addr),
+    R_UNLESS(m_page_table_impl->BeginTraversal(next_entry, context, GetInteger(addr)),
              ResultInvalidCurrentMemory);
 
     // Prepare tracking variables.
-    PAddr cur_addr = next_entry.phys_addr;
+    KPhysicalAddress cur_addr = next_entry.phys_addr;
     size_t cur_size = next_entry.block_size - (cur_addr & (next_entry.block_size - 1));
     size_t tot_size = cur_size;
 
@@ -646,7 +650,7 @@ Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) {
     R_SUCCEED();
 }
 
-bool KPageTable::IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_pages) {
+bool KPageTable::IsValidPageGroup(const KPageGroup& pg, KProcessAddress addr, size_t num_pages) {
     ASSERT(this->IsLockedByCurrentThread());
 
     const size_t size = num_pages * PageSize;
@@ -659,7 +663,7 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_p
 
     // We're going to validate that the group we'd expect is the group we see.
     auto cur_it = pg.begin();
-    PAddr cur_block_address = cur_it->GetAddress();
+    KPhysicalAddress cur_block_address = cur_it->GetAddress();
     size_t cur_block_pages = cur_it->GetNumPages();
 
     auto UpdateCurrentIterator = [&]() {
@@ -677,12 +681,12 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_p
     // Begin traversal.
     Common::PageTable::TraversalContext context;
     Common::PageTable::TraversalEntry next_entry;
-    if (!m_page_table_impl->BeginTraversal(next_entry, context, addr)) {
+    if (!m_page_table_impl->BeginTraversal(next_entry, context, GetInteger(addr))) {
         return false;
     }
 
     // Prepare tracking variables.
-    PAddr cur_addr = next_entry.phys_addr;
+    KPhysicalAddress cur_addr = next_entry.phys_addr;
     size_t cur_size = next_entry.block_size - (cur_addr & (next_entry.block_size - 1));
     size_t tot_size = cur_size;
 
@@ -734,8 +738,8 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_p
     return cur_block_address == cur_addr && cur_block_pages == (cur_size / PageSize);
 }
 
-Result KPageTable::UnmapProcessMemory(VAddr dst_addr, size_t size, KPageTable& src_page_table,
-                                      VAddr src_addr) {
+Result KPageTable::UnmapProcessMemory(KProcessAddress dst_addr, size_t size,
+                                      KPageTable& src_page_table, KProcessAddress src_addr) {
     // Acquire the table locks.
     KScopedLightLockPair lk(src_page_table.m_general_lock, m_general_lock);
 
@@ -774,8 +778,8 @@ Result KPageTable::UnmapProcessMemory(VAddr dst_addr, size_t size, KPageTable& s
 }
 
 Result KPageTable::SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed,
-                                     VAddr address, size_t size, KMemoryPermission test_perm,
-                                     KMemoryState dst_state) {
+                                     KProcessAddress address, size_t size,
+                                     KMemoryPermission test_perm, KMemoryState dst_state) {
     // Validate pre-conditions.
     ASSERT(this->IsLockedByCurrentThread());
     ASSERT(test_perm == KMemoryPermission::UserReadWrite ||
@@ -790,10 +794,10 @@ Result KPageTable::SetupForIpcClient(PageLinkedList* page_list, size_t* out_bloc
                               : KMemoryPermission::UserRead;
 
     // Get aligned extents.
-    const VAddr aligned_src_start = Common::AlignDown((address), PageSize);
-    const VAddr aligned_src_end = Common::AlignUp((address) + size, PageSize);
-    const VAddr mapping_src_start = Common::AlignUp((address), PageSize);
-    const VAddr mapping_src_end = Common::AlignDown((address) + size, PageSize);
+    const KProcessAddress aligned_src_start = Common::AlignDown(GetInteger(address), PageSize);
+    const KProcessAddress aligned_src_end = Common::AlignUp(GetInteger(address) + size, PageSize);
+    const KProcessAddress mapping_src_start = Common::AlignUp(GetInteger(address), PageSize);
+    const KProcessAddress mapping_src_end = Common::AlignDown(GetInteger(address) + size, PageSize);
 
     const auto aligned_src_last = (aligned_src_end)-1;
     const auto mapping_src_last = (mapping_src_end)-1;
@@ -840,14 +844,15 @@ Result KPageTable::SetupForIpcClient(PageLinkedList* page_list, size_t* out_bloc
                                      test_attr_mask, KMemoryAttribute::None));
 
         if (mapping_src_start < mapping_src_end && (mapping_src_start) < info.GetEndAddress() &&
-            info.GetAddress() < (mapping_src_end)) {
-            const auto cur_start =
-                info.GetAddress() >= (mapping_src_start) ? info.GetAddress() : (mapping_src_start);
+            info.GetAddress() < GetInteger(mapping_src_end)) {
+            const auto cur_start = info.GetAddress() >= GetInteger(mapping_src_start)
+                                       ? info.GetAddress()
+                                       : (mapping_src_start);
             const auto cur_end = mapping_src_last >= info.GetLastAddress() ? info.GetEndAddress()
                                                                            : (mapping_src_end);
             const size_t cur_size = cur_end - cur_start;
 
-            if (info.GetAddress() < (mapping_src_start)) {
+            if (info.GetAddress() < GetInteger(mapping_src_start)) {
                 ++blocks_needed;
             }
             if (mapping_src_last < info.GetLastAddress()) {
@@ -882,30 +887,32 @@ Result KPageTable::SetupForIpcClient(PageLinkedList* page_list, size_t* out_bloc
     R_SUCCEED();
 }
 
-Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_addr,
-                                     KMemoryPermission test_perm, KMemoryState dst_state,
-                                     KPageTable& src_page_table, bool send) {
+Result KPageTable::SetupForIpcServer(KProcessAddress* out_addr, size_t size,
+                                     KProcessAddress src_addr, KMemoryPermission test_perm,
+                                     KMemoryState dst_state, KPageTable& src_page_table,
+                                     bool send) {
     ASSERT(this->IsLockedByCurrentThread());
     ASSERT(src_page_table.IsLockedByCurrentThread());
 
     // Check that we can theoretically map.
-    const VAddr region_start = m_alias_region_start;
+    const KProcessAddress region_start = m_alias_region_start;
     const size_t region_size = m_alias_region_end - m_alias_region_start;
     R_UNLESS(size < region_size, ResultOutOfAddressSpace);
 
     // Get aligned source extents.
-    const VAddr src_start = src_addr;
-    const VAddr src_end = src_addr + size;
-    const VAddr aligned_src_start = Common::AlignDown((src_start), PageSize);
-    const VAddr aligned_src_end = Common::AlignUp((src_start) + size, PageSize);
-    const VAddr mapping_src_start = Common::AlignUp((src_start), PageSize);
-    const VAddr mapping_src_end = Common::AlignDown((src_start) + size, PageSize);
+    const KProcessAddress src_start = src_addr;
+    const KProcessAddress src_end = src_addr + size;
+    const KProcessAddress aligned_src_start = Common::AlignDown(GetInteger(src_start), PageSize);
+    const KProcessAddress aligned_src_end = Common::AlignUp(GetInteger(src_start) + size, PageSize);
+    const KProcessAddress mapping_src_start = Common::AlignUp(GetInteger(src_start), PageSize);
+    const KProcessAddress mapping_src_end =
+        Common::AlignDown(GetInteger(src_start) + size, PageSize);
     const size_t aligned_src_size = aligned_src_end - aligned_src_start;
     const size_t mapping_src_size =
         (mapping_src_start < mapping_src_end) ? (mapping_src_end - mapping_src_start) : 0;
 
     // Select a random address to map at.
-    VAddr dst_addr =
+    KProcessAddress dst_addr =
         this->FindFreeArea(region_start, region_size / PageSize, aligned_src_size / PageSize,
                            PageSize, 0, this->GetNumGuardPages());
 
@@ -930,9 +937,9 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
     R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
 
     // Ensure that we manage page references correctly.
-    PAddr start_partial_page = 0;
-    PAddr end_partial_page = 0;
-    VAddr cur_mapped_addr = dst_addr;
+    KPhysicalAddress start_partial_page = 0;
+    KPhysicalAddress end_partial_page = 0;
+    KProcessAddress cur_mapped_addr = dst_addr;
 
     // If the partial pages are mapped, an extra reference will have been opened. Otherwise, they'll
     // free on scope exit.
@@ -977,11 +984,12 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
     // Begin traversal.
     Common::PageTable::TraversalContext context;
     Common::PageTable::TraversalEntry next_entry;
-    bool traverse_valid = src_impl.BeginTraversal(next_entry, context, aligned_src_start);
+    bool traverse_valid =
+        src_impl.BeginTraversal(next_entry, context, GetInteger(aligned_src_start));
     ASSERT(traverse_valid);
 
     // Prepare tracking variables.
-    PAddr cur_block_addr = next_entry.phys_addr;
+    KPhysicalAddress cur_block_addr = next_entry.phys_addr;
     size_t cur_block_size =
         next_entry.block_size - ((cur_block_addr) & (next_entry.block_size - 1));
     size_t tot_block_size = cur_block_size;
@@ -989,7 +997,7 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
     // Map the start page, if we have one.
     if (start_partial_page != 0) {
         // Ensure the page holds correct data.
-        const VAddr start_partial_virt =
+        const KVirtualAddress start_partial_virt =
             GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), start_partial_page);
         if (send) {
             const size_t partial_offset = src_start - aligned_src_start;
@@ -1002,21 +1010,23 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
                 clear_size = 0;
             }
 
-            std::memset(m_system.Memory().GetPointer<void>(start_partial_virt), fill_val,
-                        partial_offset);
+            std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt)),
+                        fill_val, partial_offset);
             std::memcpy(
-                m_system.Memory().GetPointer<void>(start_partial_virt + partial_offset),
+                m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt) + partial_offset),
                 m_system.Memory().GetPointer<void>(
-                    GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), cur_block_addr) +
+                    GetInteger(
+                        GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), cur_block_addr)) +
                     partial_offset),
                 copy_size);
             if (clear_size > 0) {
-                std::memset(m_system.Memory().GetPointer<void>(start_partial_virt + partial_offset +
-                                                               copy_size),
+                std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt) +
+                                                               partial_offset + copy_size),
                             fill_val, clear_size);
             }
         } else {
-            std::memset(m_system.Memory().GetPointer<void>(start_partial_virt), fill_val, PageSize);
+            std::memset(m_system.Memory().GetPointer<void>(GetInteger(start_partial_virt)),
+                        fill_val, PageSize);
         }
 
         // Map the page.
@@ -1061,7 +1071,8 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
     }
 
     // Handle the last direct-mapped page.
-    if (const VAddr mapped_block_end = aligned_src_start + tot_block_size - cur_block_size;
+    if (const KProcessAddress mapped_block_end =
+            aligned_src_start + tot_block_size - cur_block_size;
         mapped_block_end < mapping_src_end) {
         const size_t last_block_size = mapping_src_end - mapped_block_end;
 
@@ -1084,18 +1095,20 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
     // Map the end page, if we have one.
     if (end_partial_page != 0) {
         // Ensure the page holds correct data.
-        const VAddr end_partial_virt =
+        const KVirtualAddress end_partial_virt =
             GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), end_partial_page);
         if (send) {
             const size_t copy_size = src_end - mapping_src_end;
-            std::memcpy(m_system.Memory().GetPointer<void>(end_partial_virt),
-                        m_system.Memory().GetPointer<void>(GetHeapVirtualAddress(
-                            m_system.Kernel().MemoryLayout(), cur_block_addr)),
+            std::memcpy(m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt)),
+                        m_system.Memory().GetPointer<void>(GetInteger(GetHeapVirtualAddress(
+                            m_system.Kernel().MemoryLayout(), cur_block_addr))),
                         copy_size);
-            std::memset(m_system.Memory().GetPointer<void>(end_partial_virt + copy_size), fill_val,
-                        PageSize - copy_size);
+            std::memset(
+                m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt) + copy_size),
+                fill_val, PageSize - copy_size);
         } else {
-            std::memset(m_system.Memory().GetPointer<void>(end_partial_virt), fill_val, PageSize);
+            std::memset(m_system.Memory().GetPointer<void>(GetInteger(end_partial_virt)), fill_val,
+                        PageSize);
         }
 
         // Map the page.
@@ -1116,7 +1129,7 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
     R_SUCCEED();
 }
 
-Result KPageTable::SetupForIpc(VAddr* out_dst_addr, size_t size, VAddr src_addr,
+Result KPageTable::SetupForIpc(KProcessAddress* out_dst_addr, size_t size, KProcessAddress src_addr,
                                KPageTable& src_page_table, KMemoryPermission test_perm,
                                KMemoryState dst_state, bool send) {
     // For convenience, alias this.
@@ -1142,8 +1155,8 @@ Result KPageTable::SetupForIpc(VAddr* out_dst_addr, size_t size, VAddr src_addr,
     R_TRY(allocator_result);
 
     // Get the mapped extents.
-    const VAddr src_map_start = Common::AlignUp((src_addr), PageSize);
-    const VAddr src_map_end = Common::AlignDown((src_addr) + size, PageSize);
+    const KProcessAddress src_map_start = Common::AlignUp(GetInteger(src_addr), PageSize);
+    const KProcessAddress src_map_end = Common::AlignDown(GetInteger(src_addr) + size, PageSize);
     const size_t src_map_size = src_map_end - src_map_start;
 
     // Ensure that we clean up appropriately if we fail after this.
@@ -1172,7 +1185,8 @@ Result KPageTable::SetupForIpc(VAddr* out_dst_addr, size_t size, VAddr src_addr,
     R_SUCCEED();
 }
 
-Result KPageTable::CleanupForIpcServer(VAddr address, size_t size, KMemoryState dst_state) {
+Result KPageTable::CleanupForIpcServer(KProcessAddress address, size_t size,
+                                       KMemoryState dst_state) {
     // Validate the address.
     R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
 
@@ -1196,8 +1210,8 @@ Result KPageTable::CleanupForIpcServer(VAddr address, size_t size, KMemoryState
     KScopedPageTableUpdater updater(this);
 
     // Get aligned extents.
-    const VAddr aligned_start = Common::AlignDown((address), PageSize);
-    const VAddr aligned_end = Common::AlignUp((address) + size, PageSize);
+    const KProcessAddress aligned_start = Common::AlignDown(GetInteger(address), PageSize);
+    const KProcessAddress aligned_end = Common::AlignUp(GetInteger(address) + size, PageSize);
     const size_t aligned_size = aligned_end - aligned_start;
     const size_t aligned_num_pages = aligned_size / PageSize;
 
@@ -1211,22 +1225,23 @@ Result KPageTable::CleanupForIpcServer(VAddr address, size_t size, KMemoryState
                                   KMemoryBlockDisableMergeAttribute::Normal);
 
     // Release from the resource limit as relevant.
-    const VAddr mapping_start = Common::AlignUp((address), PageSize);
-    const VAddr mapping_end = Common::AlignDown((address) + size, PageSize);
+    const KProcessAddress mapping_start = Common::AlignUp(GetInteger(address), PageSize);
+    const KProcessAddress mapping_end = Common::AlignDown(GetInteger(address) + size, PageSize);
     const size_t mapping_size = (mapping_start < mapping_end) ? mapping_end - mapping_start : 0;
     m_resource_limit->Release(LimitableResource::PhysicalMemoryMax, aligned_size - mapping_size);
 
     R_SUCCEED();
 }
 
-Result KPageTable::CleanupForIpcClient(VAddr address, size_t size, KMemoryState dst_state) {
+Result KPageTable::CleanupForIpcClient(KProcessAddress address, size_t size,
+                                       KMemoryState dst_state) {
     // Validate the address.
     R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
 
     // Get aligned source extents.
-    const VAddr mapping_start = Common::AlignUp((address), PageSize);
-    const VAddr mapping_end = Common::AlignDown((address) + size, PageSize);
-    const VAddr mapping_last = mapping_end - 1;
+    const KProcessAddress mapping_start = Common::AlignUp(GetInteger(address), PageSize);
+    const KProcessAddress mapping_end = Common::AlignDown(GetInteger(address) + size, PageSize);
+    const KProcessAddress mapping_last = mapping_end - 1;
     const size_t mapping_size = (mapping_start < mapping_end) ? (mapping_end - mapping_start) : 0;
 
     // If nothing was mapped, we're actually done immediately.
@@ -1279,7 +1294,7 @@ Result KPageTable::CleanupForIpcClient(VAddr address, size_t size, KMemoryState
             KMemoryInfo cur_info = start_it->GetMemoryInfo();
 
             // Create tracking variables.
-            VAddr cur_address = cur_info.GetAddress();
+            KProcessAddress cur_address = cur_info.GetAddress();
             size_t cur_size = cur_info.GetSize();
             bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission();
             bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1;
@@ -1352,7 +1367,7 @@ Result KPageTable::CleanupForIpcClient(VAddr address, size_t size, KMemoryState
                    .IsSuccess());
 
         // Create tracking variables.
-        VAddr cur_address = cur_info.GetAddress();
+        KProcessAddress cur_address = cur_info.GetAddress();
         size_t cur_size = cur_info.GetSize();
         bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission();
         bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1;
@@ -1439,16 +1454,16 @@ Result KPageTable::CleanupForIpcClient(VAddr address, size_t size, KMemoryState
 }
 
 void KPageTable::CleanupForIpcClientOnServerSetupFailure([[maybe_unused]] PageLinkedList* page_list,
-                                                         VAddr address, size_t size,
+                                                         KProcessAddress address, size_t size,
                                                          KMemoryPermission prot_perm) {
     ASSERT(this->IsLockedByCurrentThread());
-    ASSERT(Common::IsAligned(address, PageSize));
+    ASSERT(Common::IsAligned(GetInteger(address), PageSize));
     ASSERT(Common::IsAligned(size, PageSize));
 
     // Get the mapped extents.
-    const VAddr src_map_start = address;
-    const VAddr src_map_end = address + size;
-    const VAddr src_map_last = src_map_end - 1;
+    const KProcessAddress src_map_start = address;
+    const KProcessAddress src_map_end = address + size;
+    const KProcessAddress src_map_last = src_map_end - 1;
 
     // This function is only invoked when there's something to do.
     ASSERT(src_map_end > src_map_start);
@@ -1458,8 +1473,9 @@ void KPageTable::CleanupForIpcClientOnServerSetupFailure([[maybe_unused]] PageLi
     while (true) {
         const KMemoryInfo info = it->GetMemoryInfo();
 
-        const auto cur_start =
-            info.GetAddress() >= src_map_start ? info.GetAddress() : src_map_start;
+        const auto cur_start = info.GetAddress() >= GetInteger(src_map_start)
+                                   ? info.GetAddress()
+                                   : GetInteger(src_map_start);
         const auto cur_end =
             src_map_last <= info.GetLastAddress() ? src_map_end : info.GetEndAddress();
 
@@ -1469,7 +1485,7 @@ void KPageTable::CleanupForIpcClientOnServerSetupFailure([[maybe_unused]] PageLi
             (info.GetIpcLockCount() != 0 &&
              (info.GetOriginalPermission() & KMemoryPermission::IpcLockChangeMask) != prot_perm)) {
             // Check if we actually need to fix the protections on the block.
-            if (cur_end == src_map_end || info.GetAddress() <= src_map_start ||
+            if (cur_end == src_map_end || info.GetAddress() <= GetInteger(src_map_start) ||
                 (info.GetPermission() & KMemoryPermission::IpcLockChangeMask) != prot_perm) {
                 ASSERT(Operate(cur_start, (cur_end - cur_start) / PageSize, info.GetPermission(),
                                OperationType::ChangePermissions)
@@ -1488,15 +1504,15 @@ void KPageTable::CleanupForIpcClientOnServerSetupFailure([[maybe_unused]] PageLi
     }
 }
 
-Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
+Result KPageTable::MapPhysicalMemory(KProcessAddress address, size_t size) {
     // Lock the physical memory lock.
     KScopedLightLock phys_lk(m_map_physical_memory_lock);
 
     // Calculate the last address for convenience.
-    const VAddr last_address = address + size - 1;
+    const KProcessAddress last_address = address + size - 1;
 
     // Define iteration variables.
-    VAddr cur_address;
+    KProcessAddress cur_address;
     size_t mapped_size;
 
     // The entire mapping process can be retried.
@@ -1528,7 +1544,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
 
                 // Track the memory if it's mapped.
                 if (info.GetState() != KMemoryState::Free) {
-                    mapped_size += VAddr(info.GetEndAddress()) - cur_address;
+                    mapped_size += KProcessAddress(info.GetEndAddress()) - cur_address;
                 }
 
                 // Advance.
@@ -1581,7 +1597,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
 
                         const bool is_free = info.GetState() == KMemoryState::Free;
                         if (is_free) {
-                            if (info.GetAddress() < address) {
+                            if (info.GetAddress() < GetInteger(address)) {
                                 ++num_allocator_blocks;
                             }
                             if (last_address < info.GetLastAddress()) {
@@ -1599,7 +1615,8 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
 
                         // Track the memory if it's mapped.
                         if (!is_free) {
-                            checked_mapped_size += VAddr(info.GetEndAddress()) - cur_address;
+                            checked_mapped_size +=
+                                KProcessAddress(info.GetEndAddress()) - cur_address;
                         }
 
                         // Advance.
@@ -1627,7 +1644,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
 
                 // Prepare to iterate over the memory.
                 auto pg_it = pg.begin();
-                PAddr pg_phys_addr = pg_it->GetAddress();
+                KPhysicalAddress pg_phys_addr = pg_it->GetAddress();
                 size_t pg_pages = pg_it->GetNumPages();
 
                 // Reset the current tracking address, and make sure we clean up on failure.
@@ -1635,7 +1652,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
                 cur_address = address;
                 ON_RESULT_FAILURE {
                     if (cur_address > address) {
-                        const VAddr last_unmap_address = cur_address - 1;
+                        const KProcessAddress last_unmap_address = cur_address - 1;
 
                         // Iterate, unmapping the pages.
                         cur_address = address;
@@ -1652,7 +1669,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
                             if (info.GetState() == KMemoryState::Free) {
                                 // Determine the range to unmap.
                                 const size_t cur_pages =
-                                    std::min(VAddr(info.GetEndAddress()) - cur_address,
+                                    std::min(KProcessAddress(info.GetEndAddress()) - cur_address,
                                              last_unmap_address + 1 - cur_address) /
                                     PageSize;
 
@@ -1695,9 +1712,10 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
                     // If it's unmapped, we need to map it.
                     if (info.GetState() == KMemoryState::Free) {
                         // Determine the range to map.
-                        size_t map_pages = std::min(VAddr(info.GetEndAddress()) - cur_address,
-                                                    last_address + 1 - cur_address) /
-                                           PageSize;
+                        size_t map_pages =
+                            std::min(KProcessAddress(info.GetEndAddress()) - cur_address,
+                                     last_address + 1 - cur_address) /
+                            PageSize;
 
                         // While we have pages to map, map them.
                         while (map_pages > 0) {
@@ -1754,7 +1772,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
     }
 }
 
-Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) {
+Result KPageTable::UnmapPhysicalMemory(KProcessAddress address, size_t size) {
     // Lock the physical memory lock.
     KScopedLightLock phys_lk(m_map_physical_memory_lock);
 
@@ -1762,13 +1780,13 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) {
     KScopedLightLock lk(m_general_lock);
 
     // Calculate the last address for convenience.
-    const VAddr last_address = address + size - 1;
+    const KProcessAddress last_address = address + size - 1;
 
     // Define iteration variables.
-    VAddr map_start_address = 0;
-    VAddr map_last_address = 0;
+    KProcessAddress map_start_address = 0;
+    KProcessAddress map_last_address = 0;
 
-    VAddr cur_address;
+    KProcessAddress cur_address;
     size_t mapped_size;
     size_t num_allocator_blocks = 0;
 
@@ -1801,7 +1819,7 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) {
                 map_last_address =
                     (last_address >= info.GetLastAddress()) ? info.GetLastAddress() : last_address;
 
-                if (info.GetAddress() < address) {
+                if (info.GetAddress() < GetInteger(address)) {
                     ++num_allocator_blocks;
                 }
                 if (last_address < info.GetLastAddress()) {
@@ -1854,7 +1872,7 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) {
         // If the memory state is normal, we need to unmap it.
         if (info.GetState() == KMemoryState::Normal) {
             // Determine the range to unmap.
-            const size_t cur_pages = std::min(VAddr(info.GetEndAddress()) - cur_address,
+            const size_t cur_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address,
                                               last_address + 1 - cur_address) /
                                      PageSize;
 
@@ -2144,13 +2162,14 @@ void KPageTable::RemapPageGroup(PageLinkedList* page_list, KProcessAddress addre
         const KMemoryInfo info = it->GetMemoryInfo();
 
         // Determine the range to map.
-        KProcessAddress map_address = std::max<VAddr>(info.GetAddress(), start_address);
-        const KProcessAddress map_end_address = std::min<VAddr>(info.GetEndAddress(), end_address);
+        KProcessAddress map_address = std::max<KProcessAddress>(info.GetAddress(), start_address);
+        const KProcessAddress map_end_address =
+            std::min<KProcessAddress>(info.GetEndAddress(), end_address);
         ASSERT(map_end_address != map_address);
 
         // Determine if we should disable head merge.
         const bool disable_head_merge =
-            info.GetAddress() >= start_address &&
+            info.GetAddress() >= GetInteger(start_address) &&
             True(info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute::Normal);
         const KPageProperties map_properties = {
             info.GetPermission(), false, false,
@@ -2214,7 +2233,7 @@ Result KPageTable::MapPages(KProcessAddress* out_addr, size_t num_pages, size_t
     KProcessAddress addr = this->FindFreeArea(region_start, region_num_pages, num_pages, alignment,
                                               0, this->GetNumGuardPages());
     R_UNLESS(addr != 0, ResultOutOfMemory);
-    ASSERT(Common::IsAligned(addr, alignment));
+    ASSERT(Common::IsAligned(GetInteger(addr), alignment));
     ASSERT(this->CanContain(addr, num_pages * PageSize, state));
     ASSERT(this->CheckMemoryState(addr, num_pages * PageSize, KMemoryState::All, KMemoryState::Free,
                                   KMemoryPermission::None, KMemoryPermission::None,
@@ -2455,7 +2474,7 @@ Result KPageTable::UnmapPageGroup(KProcessAddress address, const KPageGroup& pg,
     R_SUCCEED();
 }
 
-Result KPageTable::MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t num_pages,
+Result KPageTable::MakeAndOpenPageGroup(KPageGroup* out, KProcessAddress address, size_t num_pages,
                                         KMemoryState state_mask, KMemoryState state,
                                         KMemoryPermission perm_mask, KMemoryPermission perm,
                                         KMemoryAttribute attr_mask, KMemoryAttribute attr) {
@@ -2480,7 +2499,7 @@ Result KPageTable::MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t n
     R_SUCCEED();
 }
 
-Result KPageTable::SetProcessMemoryPermission(VAddr addr, size_t size,
+Result KPageTable::SetProcessMemoryPermission(KProcessAddress addr, size_t size,
                                               Svc::MemoryPermission svc_perm) {
     const size_t num_pages = size / PageSize;
 
@@ -2541,23 +2560,23 @@ Result KPageTable::SetProcessMemoryPermission(VAddr addr, size_t size,
 
     // Ensure cache coherency, if we're setting pages as executable.
     if (is_x) {
-        m_system.InvalidateCpuInstructionCacheRange(addr, size);
+        m_system.InvalidateCpuInstructionCacheRange(GetInteger(addr), size);
     }
 
     R_SUCCEED();
 }
 
-KMemoryInfo KPageTable::QueryInfoImpl(VAddr addr) {
+KMemoryInfo KPageTable::QueryInfoImpl(KProcessAddress addr) {
     KScopedLightLock lk(m_general_lock);
 
     return m_memory_block_manager.FindBlock(addr)->GetMemoryInfo();
 }
 
-KMemoryInfo KPageTable::QueryInfo(VAddr addr) {
+KMemoryInfo KPageTable::QueryInfo(KProcessAddress addr) {
     if (!Contains(addr, 1)) {
         return {
-            .m_address = m_address_space_end,
-            .m_size = 0 - m_address_space_end,
+            .m_address = GetInteger(m_address_space_end),
+            .m_size = 0 - GetInteger(m_address_space_end),
             .m_state = static_cast<KMemoryState>(Svc::MemoryState::Inaccessible),
             .m_device_disable_merge_left_count = 0,
             .m_device_disable_merge_right_count = 0,
@@ -2574,7 +2593,8 @@ KMemoryInfo KPageTable::QueryInfo(VAddr addr) {
     return QueryInfoImpl(addr);
 }
 
-Result KPageTable::SetMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermission svc_perm) {
+Result KPageTable::SetMemoryPermission(KProcessAddress addr, size_t size,
+                                       Svc::MemoryPermission svc_perm) {
     const size_t num_pages = size / PageSize;
 
     // Lock the table.
@@ -2611,7 +2631,7 @@ Result KPageTable::SetMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermi
     R_SUCCEED();
 }
 
-Result KPageTable::SetMemoryAttribute(VAddr addr, size_t size, u32 mask, u32 attr) {
+Result KPageTable::SetMemoryAttribute(KProcessAddress addr, size_t size, u32 mask, u32 attr) {
     const size_t num_pages = size / PageSize;
     ASSERT((static_cast<KMemoryAttribute>(mask) | KMemoryAttribute::SetMask) ==
            KMemoryAttribute::SetMask);
@@ -2666,12 +2686,12 @@ Result KPageTable::SetMaxHeapSize(size_t size) {
     R_SUCCEED();
 }
 
-Result KPageTable::SetHeapSize(VAddr* out, size_t size) {
+Result KPageTable::SetHeapSize(u64* out, size_t size) {
     // Lock the physical memory mutex.
     KScopedLightLock map_phys_mem_lk(m_map_physical_memory_lock);
 
     // Try to perform a reduction in heap, instead of an extension.
-    VAddr cur_address{};
+    KProcessAddress cur_address{};
     size_t allocation_size{};
     {
         // Lock the table.
@@ -2722,11 +2742,11 @@ Result KPageTable::SetHeapSize(VAddr* out, size_t size) {
             m_current_heap_end = m_heap_region_start + size;
 
             // Set the output.
-            *out = m_heap_region_start;
+            *out = GetInteger(m_heap_region_start);
             R_SUCCEED();
         } else if (size == GetHeapSize()) {
             // The size requested is exactly the current size.
-            *out = m_heap_region_start;
+            *out = GetInteger(m_heap_region_start);
             R_SUCCEED();
         } else {
             // We have to allocate memory. Determine how much to allocate and where while the table
@@ -2799,14 +2819,14 @@ Result KPageTable::SetHeapSize(VAddr* out, size_t size) {
         m_current_heap_end = m_heap_region_start + size;
 
         // Set the output.
-        *out = m_heap_region_start;
+        *out = GetInteger(m_heap_region_start);
         R_SUCCEED();
     }
 }
 
-Result KPageTable::LockForMapDeviceAddressSpace(bool* out_is_io, VAddr address, size_t size,
-                                                KMemoryPermission perm, bool is_aligned,
-                                                bool check_heap) {
+Result KPageTable::LockForMapDeviceAddressSpace(bool* out_is_io, KProcessAddress address,
+                                                size_t size, KMemoryPermission perm,
+                                                bool is_aligned, bool check_heap) {
     // Lightly validate the range before doing anything else.
     const size_t num_pages = size / PageSize;
     R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
@@ -2842,7 +2862,8 @@ Result KPageTable::LockForMapDeviceAddressSpace(bool* out_is_io, VAddr address,
     R_SUCCEED();
 }
 
-Result KPageTable::LockForUnmapDeviceAddressSpace(VAddr address, size_t size, bool check_heap) {
+Result KPageTable::LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size,
+                                                  bool check_heap) {
     // Lightly validate the range before doing anything else.
     const size_t num_pages = size / PageSize;
     R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
@@ -2876,7 +2897,7 @@ Result KPageTable::LockForUnmapDeviceAddressSpace(VAddr address, size_t size, bo
     R_SUCCEED();
 }
 
-Result KPageTable::UnlockForDeviceAddressSpace(VAddr address, size_t size) {
+Result KPageTable::UnlockForDeviceAddressSpace(KProcessAddress address, size_t size) {
     // Lightly validate the range before doing anything else.
     const size_t num_pages = size / PageSize;
     R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
@@ -2904,7 +2925,8 @@ Result KPageTable::UnlockForDeviceAddressSpace(VAddr address, size_t size) {
     R_SUCCEED();
 }
 
-Result KPageTable::LockForIpcUserBuffer(PAddr* out, VAddr address, size_t size) {
+Result KPageTable::LockForIpcUserBuffer(KPhysicalAddress* out, KProcessAddress address,
+                                        size_t size) {
     R_RETURN(this->LockMemoryAndOpen(
         nullptr, out, address, size, KMemoryState::FlagCanIpcUserBuffer,
         KMemoryState::FlagCanIpcUserBuffer, KMemoryPermission::All,
@@ -2913,7 +2935,7 @@ Result KPageTable::LockForIpcUserBuffer(PAddr* out, VAddr address, size_t size)
         KMemoryAttribute::Locked));
 }
 
-Result KPageTable::UnlockForIpcUserBuffer(VAddr address, size_t size) {
+Result KPageTable::UnlockForIpcUserBuffer(KProcessAddress address, size_t size) {
     R_RETURN(this->UnlockMemory(address, size, KMemoryState::FlagCanIpcUserBuffer,
                                 KMemoryState::FlagCanIpcUserBuffer, KMemoryPermission::None,
                                 KMemoryPermission::None, KMemoryAttribute::All,
@@ -2921,7 +2943,7 @@ Result KPageTable::UnlockForIpcUserBuffer(VAddr address, size_t size) {
                                 KMemoryAttribute::Locked, nullptr));
 }
 
-Result KPageTable::LockForCodeMemory(KPageGroup* out, VAddr addr, size_t size) {
+Result KPageTable::LockForCodeMemory(KPageGroup* out, KProcessAddress addr, size_t size) {
     R_RETURN(this->LockMemoryAndOpen(
         out, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory,
         KMemoryPermission::All, KMemoryPermission::UserReadWrite, KMemoryAttribute::All,
@@ -2929,17 +2951,17 @@ Result KPageTable::LockForCodeMemory(KPageGroup* out, VAddr addr, size_t size) {
         KMemoryAttribute::Locked));
 }
 
-Result KPageTable::UnlockForCodeMemory(VAddr addr, size_t size, const KPageGroup& pg) {
+Result KPageTable::UnlockForCodeMemory(KProcessAddress addr, size_t size, const KPageGroup& pg) {
     R_RETURN(this->UnlockMemory(
         addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory,
         KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::All,
         KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite, KMemoryAttribute::Locked, &pg));
 }
 
-bool KPageTable::IsRegionContiguous(VAddr addr, u64 size) const {
-    auto start_ptr = m_system.DeviceMemory().GetPointer<u8>(addr);
+bool KPageTable::IsRegionContiguous(KProcessAddress addr, u64 size) const {
+    auto start_ptr = m_system.DeviceMemory().GetPointer<u8>(GetInteger(addr));
     for (u64 offset{}; offset < size; offset += PageSize) {
-        if (start_ptr != m_system.DeviceMemory().GetPointer<u8>(addr + offset)) {
+        if (start_ptr != m_system.DeviceMemory().GetPointer<u8>(GetInteger(addr) + offset)) {
             return false;
         }
         start_ptr += PageSize;
@@ -2947,18 +2969,19 @@ bool KPageTable::IsRegionContiguous(VAddr addr, u64 size) const {
     return true;
 }
 
-void KPageTable::AddRegionToPages(VAddr start, size_t num_pages, KPageGroup& page_linked_list) {
-    VAddr addr{start};
+void KPageTable::AddRegionToPages(KProcessAddress start, size_t num_pages,
+                                  KPageGroup& page_linked_list) {
+    KProcessAddress addr{start};
     while (addr < start + (num_pages * PageSize)) {
-        const PAddr paddr{GetPhysicalAddr(addr)};
+        const KPhysicalAddress paddr{GetPhysicalAddr(addr)};
         ASSERT(paddr != 0);
         page_linked_list.AddBlock(paddr, 1);
         addr += PageSize;
     }
 }
 
-VAddr KPageTable::AllocateVirtualMemory(VAddr start, size_t region_num_pages, u64 needed_num_pages,
-                                        size_t align) {
+KProcessAddress KPageTable::AllocateVirtualMemory(KProcessAddress start, size_t region_num_pages,
+                                                  u64 needed_num_pages, size_t align) {
     if (m_enable_aslr) {
         UNIMPLEMENTED();
     }
@@ -2966,11 +2989,11 @@ VAddr KPageTable::AllocateVirtualMemory(VAddr start, size_t region_num_pages, u6
                                                IsKernel() ? 1 : 4);
 }
 
-Result KPageTable::Operate(VAddr addr, size_t num_pages, const KPageGroup& page_group,
+Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, const KPageGroup& page_group,
                            OperationType operation) {
     ASSERT(this->IsLockedByCurrentThread());
 
-    ASSERT(Common::IsAligned(addr, PageSize));
+    ASSERT(Common::IsAligned(GetInteger(addr), PageSize));
     ASSERT(num_pages > 0);
     ASSERT(num_pages == page_group.GetNumPages());
 
@@ -3001,12 +3024,12 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, const KPageGroup& page_
     R_SUCCEED();
 }
 
-Result KPageTable::Operate(VAddr addr, size_t num_pages, KMemoryPermission perm,
-                           OperationType operation, PAddr map_addr) {
+Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, KMemoryPermission perm,
+                           OperationType operation, KPhysicalAddress map_addr) {
     ASSERT(this->IsLockedByCurrentThread());
 
     ASSERT(num_pages > 0);
-    ASSERT(Common::IsAligned(addr, PageSize));
+    ASSERT(Common::IsAligned(GetInteger(addr), PageSize));
     ASSERT(ContainsPages(addr, num_pages));
 
     switch (operation) {
@@ -3022,7 +3045,7 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, KMemoryPermission perm,
     case OperationType::MapFirst:
     case OperationType::Map: {
         ASSERT(map_addr);
-        ASSERT(Common::IsAligned(map_addr, PageSize));
+        ASSERT(Common::IsAligned(GetInteger(map_addr), PageSize));
         m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr);
 
         // Open references to pages, if we should.
@@ -3060,7 +3083,7 @@ void KPageTable::FinalizeUpdate(PageLinkedList* page_list) {
     }
 }
 
-VAddr KPageTable::GetRegionAddress(KMemoryState state) const {
+KProcessAddress KPageTable::GetRegionAddress(KMemoryState state) const {
     switch (state) {
     case KMemoryState::Free:
     case KMemoryState::Kernel:
@@ -3132,11 +3155,11 @@ size_t KPageTable::GetRegionSize(KMemoryState state) const {
     }
 }
 
-bool KPageTable::CanContain(VAddr addr, size_t size, KMemoryState state) const {
-    const VAddr end = addr + size;
-    const VAddr last = end - 1;
+bool KPageTable::CanContain(KProcessAddress addr, size_t size, KMemoryState state) const {
+    const KProcessAddress end = addr + size;
+    const KProcessAddress last = end - 1;
 
-    const VAddr region_start = this->GetRegionAddress(state);
+    const KProcessAddress region_start = this->GetRegionAddress(state);
     const size_t region_size = this->GetRegionSize(state);
 
     const bool is_in_region =
@@ -3191,21 +3214,21 @@ Result KPageTable::CheckMemoryState(const KMemoryInfo& info, KMemoryState state_
     R_SUCCEED();
 }
 
-Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, VAddr addr, size_t size,
-                                              KMemoryState state_mask, KMemoryState state,
-                                              KMemoryPermission perm_mask, KMemoryPermission perm,
-                                              KMemoryAttribute attr_mask,
+Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, KProcessAddress addr,
+                                              size_t size, KMemoryState state_mask,
+                                              KMemoryState state, KMemoryPermission perm_mask,
+                                              KMemoryPermission perm, KMemoryAttribute attr_mask,
                                               KMemoryAttribute attr) const {
     ASSERT(this->IsLockedByCurrentThread());
 
     // Get information about the first block.
-    const VAddr last_addr = addr + size - 1;
+    const KProcessAddress last_addr = addr + size - 1;
     KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr);
     KMemoryInfo info = it->GetMemoryInfo();
 
     // If the start address isn't aligned, we need a block.
     const size_t blocks_for_start_align =
-        (Common::AlignDown(addr, PageSize) != info.GetAddress()) ? 1 : 0;
+        (Common::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0;
 
     while (true) {
         // Validate against the provided masks.
@@ -3224,7 +3247,7 @@ Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, VAddr a
 
     // If the end address isn't aligned, we need a block.
     const size_t blocks_for_end_align =
-        (Common::AlignUp(addr + size, PageSize) != info.GetEndAddress()) ? 1 : 0;
+        (Common::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0;
 
     if (out_blocks_needed != nullptr) {
         *out_blocks_needed = blocks_for_start_align + blocks_for_end_align;
@@ -3235,20 +3258,20 @@ Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, VAddr a
 
 Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
                                     KMemoryAttribute* out_attr, size_t* out_blocks_needed,
-                                    VAddr addr, size_t size, KMemoryState state_mask,
+                                    KProcessAddress addr, size_t size, KMemoryState state_mask,
                                     KMemoryState state, KMemoryPermission perm_mask,
                                     KMemoryPermission perm, KMemoryAttribute attr_mask,
                                     KMemoryAttribute attr, KMemoryAttribute ignore_attr) const {
     ASSERT(this->IsLockedByCurrentThread());
 
     // Get information about the first block.
-    const VAddr last_addr = addr + size - 1;
+    const KProcessAddress last_addr = addr + size - 1;
     KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr);
     KMemoryInfo info = it->GetMemoryInfo();
 
     // If the start address isn't aligned, we need a block.
     const size_t blocks_for_start_align =
-        (Common::AlignDown(addr, PageSize) != info.GetAddress()) ? 1 : 0;
+        (Common::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0;
 
     // Validate all blocks in the range have correct state.
     const KMemoryState first_state = info.m_state;
@@ -3277,7 +3300,7 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission*
 
     // If the end address isn't aligned, we need a block.
     const size_t blocks_for_end_align =
-        (Common::AlignUp(addr + size, PageSize) != info.GetEndAddress()) ? 1 : 0;
+        (Common::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0;
 
     // Write output state.
     if (out_state != nullptr) {
@@ -3295,11 +3318,12 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission*
     R_SUCCEED();
 }
 
-Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr addr, size_t size,
-                                     KMemoryState state_mask, KMemoryState state,
-                                     KMemoryPermission perm_mask, KMemoryPermission perm,
-                                     KMemoryAttribute attr_mask, KMemoryAttribute attr,
-                                     KMemoryPermission new_perm, KMemoryAttribute lock_attr) {
+Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, KPhysicalAddress* out_KPhysicalAddress,
+                                     KProcessAddress addr, size_t size, KMemoryState state_mask,
+                                     KMemoryState state, KMemoryPermission perm_mask,
+                                     KMemoryPermission perm, KMemoryAttribute attr_mask,
+                                     KMemoryAttribute attr, KMemoryPermission new_perm,
+                                     KMemoryAttribute lock_attr) {
     // Validate basic preconditions.
     ASSERT((lock_attr & attr) == KMemoryAttribute::None);
     ASSERT((lock_attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) ==
@@ -3329,8 +3353,8 @@ Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr
                                  attr_mask, attr));
 
     // Get the physical address, if we're supposed to.
-    if (out_paddr != nullptr) {
-        ASSERT(this->GetPhysicalAddressLocked(out_paddr, addr));
+    if (out_KPhysicalAddress != nullptr) {
+        ASSERT(this->GetPhysicalAddressLocked(out_KPhysicalAddress, addr));
     }
 
     // Make the page group, if we're supposed to.
@@ -3361,7 +3385,7 @@ Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr
     R_SUCCEED();
 }
 
-Result KPageTable::UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask,
+Result KPageTable::UnlockMemory(KProcessAddress addr, size_t size, KMemoryState state_mask,
                                 KMemoryState state, KMemoryPermission perm_mask,
                                 KMemoryPermission perm, KMemoryAttribute attr_mask,
                                 KMemoryAttribute attr, KMemoryPermission new_perm,
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h
index 7a623489b..602b58465 100755
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -6,7 +6,6 @@
 #include <memory>
 
 #include "common/common_funcs.h"
-#include "common/common_types.h"
 #include "common/page_table.h"
 #include "core/file_sys/program_metadata.h"
 #include "core/hle/kernel/k_dynamic_resource_manager.h"
@@ -15,6 +14,7 @@
 #include "core/hle/kernel/k_memory_block_manager.h"
 #include "core/hle/kernel/k_memory_layout.h"
 #include "core/hle/kernel/k_memory_manager.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/result.h"
 #include "core/memory.h"
 
@@ -65,45 +65,47 @@ public:
 
     Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
                                 bool enable_das_merge, bool from_back, KMemoryManager::Pool pool,
-                                VAddr code_addr, size_t code_size, KSystemResource* system_resource,
-                                KResourceLimit* resource_limit);
+                                KProcessAddress code_addr, size_t code_size,
+                                KSystemResource* system_resource, KResourceLimit* resource_limit);
 
     void Finalize();
 
-    Result MapProcessCode(VAddr addr, size_t pages_count, KMemoryState state,
+    Result MapProcessCode(KProcessAddress addr, size_t pages_count, KMemoryState state,
                           KMemoryPermission perm);
-    Result MapCodeMemory(VAddr dst_address, VAddr src_address, size_t size);
-    Result UnmapCodeMemory(VAddr dst_address, VAddr src_address, size_t size,
+    Result MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size);
+    Result UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size,
                            ICacheInvalidationStrategy icache_invalidation_strategy);
-    Result UnmapProcessMemory(VAddr dst_addr, size_t size, KPageTable& src_page_table,
-                              VAddr src_addr);
-    Result MapPhysicalMemory(VAddr addr, size_t size);
-    Result UnmapPhysicalMemory(VAddr addr, size_t size);
-    Result MapMemory(VAddr dst_addr, VAddr src_addr, size_t size);
-    Result UnmapMemory(VAddr dst_addr, VAddr src_addr, size_t size);
-    Result SetProcessMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermission svc_perm);
-    KMemoryInfo QueryInfo(VAddr addr);
-    Result SetMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermission perm);
-    Result SetMemoryAttribute(VAddr addr, size_t size, u32 mask, u32 attr);
+    Result UnmapProcessMemory(KProcessAddress dst_addr, size_t size, KPageTable& src_page_table,
+                              KProcessAddress src_addr);
+    Result MapPhysicalMemory(KProcessAddress addr, size_t size);
+    Result UnmapPhysicalMemory(KProcessAddress addr, size_t size);
+    Result MapMemory(KProcessAddress dst_addr, KProcessAddress src_addr, size_t size);
+    Result UnmapMemory(KProcessAddress dst_addr, KProcessAddress src_addr, size_t size);
+    Result SetProcessMemoryPermission(KProcessAddress addr, size_t size,
+                                      Svc::MemoryPermission svc_perm);
+    KMemoryInfo QueryInfo(KProcessAddress addr);
+    Result SetMemoryPermission(KProcessAddress addr, size_t size, Svc::MemoryPermission perm);
+    Result SetMemoryAttribute(KProcessAddress addr, size_t size, u32 mask, u32 attr);
     Result SetMaxHeapSize(size_t size);
-    Result SetHeapSize(VAddr* out, size_t size);
-    Result LockForMapDeviceAddressSpace(bool* out_is_io, VAddr address, size_t size,
+    Result SetHeapSize(u64* out, size_t size);
+    Result LockForMapDeviceAddressSpace(bool* out_is_io, KProcessAddress address, size_t size,
                                         KMemoryPermission perm, bool is_aligned, bool check_heap);
-    Result LockForUnmapDeviceAddressSpace(VAddr address, size_t size, bool check_heap);
+    Result LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size, bool check_heap);
 
-    Result UnlockForDeviceAddressSpace(VAddr addr, size_t size);
+    Result UnlockForDeviceAddressSpace(KProcessAddress addr, size_t size);
 
-    Result LockForIpcUserBuffer(PAddr* out, VAddr address, size_t size);
-    Result UnlockForIpcUserBuffer(VAddr address, size_t size);
+    Result LockForIpcUserBuffer(KPhysicalAddress* out, KProcessAddress address, size_t size);
+    Result UnlockForIpcUserBuffer(KProcessAddress address, size_t size);
 
-    Result SetupForIpc(VAddr* out_dst_addr, size_t size, VAddr src_addr, KPageTable& src_page_table,
-                       KMemoryPermission test_perm, KMemoryState dst_state, bool send);
-    Result CleanupForIpcServer(VAddr address, size_t size, KMemoryState dst_state);
-    Result CleanupForIpcClient(VAddr address, size_t size, KMemoryState dst_state);
+    Result SetupForIpc(KProcessAddress* out_dst_addr, size_t size, KProcessAddress src_addr,
+                       KPageTable& src_page_table, KMemoryPermission test_perm,
+                       KMemoryState dst_state, bool send);
+    Result CleanupForIpcServer(KProcessAddress address, size_t size, KMemoryState dst_state);
+    Result CleanupForIpcClient(KProcessAddress address, size_t size, KMemoryState dst_state);
 
-    Result LockForCodeMemory(KPageGroup* out, VAddr addr, size_t size);
-    Result UnlockForCodeMemory(VAddr addr, size_t size, const KPageGroup& pg);
-    Result MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t num_pages,
+    Result LockForCodeMemory(KPageGroup* out, KProcessAddress addr, size_t size);
+    Result UnlockForCodeMemory(KProcessAddress addr, size_t size, const KPageGroup& pg);
+    Result MakeAndOpenPageGroup(KPageGroup* out, KProcessAddress address, size_t num_pages,
                                 KMemoryState state_mask, KMemoryState state,
                                 KMemoryPermission perm_mask, KMemoryPermission perm,
                                 KMemoryAttribute attr_mask, KMemoryAttribute attr);
@@ -120,7 +122,7 @@ public:
         return m_block_info_manager;
     }
 
-    bool CanContain(VAddr addr, size_t size, KMemoryState state) const;
+    bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const;
 
     Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
                     KPhysicalAddress phys_addr, KProcessAddress region_start,
@@ -173,8 +175,8 @@ protected:
             m_root = n;
         }
 
-        void Push(Core::Memory::Memory& memory, VAddr addr) {
-            this->Push(memory.GetPointer<Node>(addr));
+        void Push(Core::Memory::Memory& memory, KVirtualAddress addr) {
+            this->Push(memory.GetPointer<Node>(GetInteger(addr)));
         }
 
         Node* Peek() const {
@@ -212,27 +214,28 @@ private:
     Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
                     KPhysicalAddress phys_addr, bool is_pa_valid, KProcessAddress region_start,
                     size_t region_num_pages, KMemoryState state, KMemoryPermission perm);
-    bool IsRegionContiguous(VAddr addr, u64 size) const;
-    void AddRegionToPages(VAddr start, size_t num_pages, KPageGroup& page_linked_list);
-    KMemoryInfo QueryInfoImpl(VAddr addr);
-    VAddr AllocateVirtualMemory(VAddr start, size_t region_num_pages, u64 needed_num_pages,
-                                size_t align);
-    Result Operate(VAddr addr, size_t num_pages, const KPageGroup& page_group,
+    bool IsRegionContiguous(KProcessAddress addr, u64 size) const;
+    void AddRegionToPages(KProcessAddress start, size_t num_pages, KPageGroup& page_linked_list);
+    KMemoryInfo QueryInfoImpl(KProcessAddress addr);
+    KProcessAddress AllocateVirtualMemory(KProcessAddress start, size_t region_num_pages,
+                                          u64 needed_num_pages, size_t align);
+    Result Operate(KProcessAddress addr, size_t num_pages, const KPageGroup& page_group,
                    OperationType operation);
-    Result Operate(VAddr addr, size_t num_pages, KMemoryPermission perm, OperationType operation,
-                   PAddr map_addr = 0);
+    Result Operate(KProcessAddress addr, size_t num_pages, KMemoryPermission perm,
+                   OperationType operation, KPhysicalAddress map_addr = 0);
     void FinalizeUpdate(PageLinkedList* page_list);
-    VAddr GetRegionAddress(KMemoryState state) const;
+    KProcessAddress GetRegionAddress(KMemoryState state) const;
     size_t GetRegionSize(KMemoryState state) const;
 
-    VAddr FindFreeArea(VAddr region_start, size_t region_num_pages, size_t num_pages,
-                       size_t alignment, size_t offset, size_t guard_pages);
+    KProcessAddress FindFreeArea(KProcessAddress region_start, size_t region_num_pages,
+                                 size_t num_pages, size_t alignment, size_t offset,
+                                 size_t guard_pages);
 
-    Result CheckMemoryStateContiguous(size_t* out_blocks_needed, VAddr addr, size_t size,
+    Result CheckMemoryStateContiguous(size_t* out_blocks_needed, KProcessAddress addr, size_t size,
                                       KMemoryState state_mask, KMemoryState state,
                                       KMemoryPermission perm_mask, KMemoryPermission perm,
                                       KMemoryAttribute attr_mask, KMemoryAttribute attr) const;
-    Result CheckMemoryStateContiguous(VAddr addr, size_t size, KMemoryState state_mask,
+    Result CheckMemoryStateContiguous(KProcessAddress addr, size_t size, KMemoryState state_mask,
                                       KMemoryState state, KMemoryPermission perm_mask,
                                       KMemoryPermission perm, KMemoryAttribute attr_mask,
                                       KMemoryAttribute attr) const {
@@ -244,12 +247,12 @@ private:
                             KMemoryPermission perm_mask, KMemoryPermission perm,
                             KMemoryAttribute attr_mask, KMemoryAttribute attr) const;
     Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
-                            KMemoryAttribute* out_attr, size_t* out_blocks_needed, VAddr addr,
-                            size_t size, KMemoryState state_mask, KMemoryState state,
-                            KMemoryPermission perm_mask, KMemoryPermission perm,
+                            KMemoryAttribute* out_attr, size_t* out_blocks_needed,
+                            KProcessAddress addr, size_t size, KMemoryState state_mask,
+                            KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
                             KMemoryAttribute attr_mask, KMemoryAttribute attr,
                             KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const;
-    Result CheckMemoryState(size_t* out_blocks_needed, VAddr addr, size_t size,
+    Result CheckMemoryState(size_t* out_blocks_needed, KProcessAddress addr, size_t size,
                             KMemoryState state_mask, KMemoryState state,
                             KMemoryPermission perm_mask, KMemoryPermission perm,
                             KMemoryAttribute attr_mask, KMemoryAttribute attr,
@@ -258,39 +261,40 @@ private:
                                   state_mask, state, perm_mask, perm, attr_mask, attr,
                                   ignore_attr));
     }
-    Result CheckMemoryState(VAddr addr, size_t size, KMemoryState state_mask, KMemoryState state,
-                            KMemoryPermission perm_mask, KMemoryPermission perm,
+    Result CheckMemoryState(KProcessAddress addr, size_t size, KMemoryState state_mask,
+                            KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
                             KMemoryAttribute attr_mask, KMemoryAttribute attr,
                             KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const {
         R_RETURN(this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm,
                                         attr_mask, attr, ignore_attr));
     }
 
-    Result LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr addr, size_t size,
-                             KMemoryState state_mask, KMemoryState state,
-                             KMemoryPermission perm_mask, KMemoryPermission perm,
-                             KMemoryAttribute attr_mask, KMemoryAttribute attr,
-                             KMemoryPermission new_perm, KMemoryAttribute lock_attr);
-    Result UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask, KMemoryState state,
-                        KMemoryPermission perm_mask, KMemoryPermission perm,
+    Result LockMemoryAndOpen(KPageGroup* out_pg, KPhysicalAddress* out_KPhysicalAddress,
+                             KProcessAddress addr, size_t size, KMemoryState state_mask,
+                             KMemoryState state, KMemoryPermission perm_mask,
+                             KMemoryPermission perm, KMemoryAttribute attr_mask,
+                             KMemoryAttribute attr, KMemoryPermission new_perm,
+                             KMemoryAttribute lock_attr);
+    Result UnlockMemory(KProcessAddress addr, size_t size, KMemoryState state_mask,
+                        KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
                         KMemoryAttribute attr_mask, KMemoryAttribute attr,
                         KMemoryPermission new_perm, KMemoryAttribute lock_attr,
                         const KPageGroup* pg);
 
-    Result MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages);
-    bool IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_pages);
+    Result MakePageGroup(KPageGroup& pg, KProcessAddress addr, size_t num_pages);
+    bool IsValidPageGroup(const KPageGroup& pg, KProcessAddress addr, size_t num_pages);
 
     bool IsLockedByCurrentThread() const {
         return m_general_lock.IsLockedByCurrentThread();
     }
 
-    bool IsHeapPhysicalAddress(const KMemoryLayout& layout, PAddr phys_addr) {
+    bool IsHeapPhysicalAddress(const KMemoryLayout& layout, KPhysicalAddress phys_addr) {
         ASSERT(this->IsLockedByCurrentThread());
 
         return layout.IsHeapPhysicalAddress(m_cached_physical_heap_region, phys_addr);
     }
 
-    bool GetPhysicalAddressLocked(PAddr* out, VAddr virt_addr) const {
+    bool GetPhysicalAddressLocked(KPhysicalAddress* out, KProcessAddress virt_addr) const {
         ASSERT(this->IsLockedByCurrentThread());
 
         *out = GetPhysicalAddr(virt_addr);
@@ -298,12 +302,13 @@ private:
         return *out != 0;
     }
 
-    Result SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed, VAddr address,
-                             size_t size, KMemoryPermission test_perm, KMemoryState dst_state);
-    Result SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_addr,
+    Result SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed,
+                             KProcessAddress address, size_t size, KMemoryPermission test_perm,
+                             KMemoryState dst_state);
+    Result SetupForIpcServer(KProcessAddress* out_addr, size_t size, KProcessAddress src_addr,
                              KMemoryPermission test_perm, KMemoryState dst_state,
                              KPageTable& src_page_table, bool send);
-    void CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list, VAddr address,
+    void CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list, KProcessAddress address,
                                                  size_t size, KMemoryPermission prot_perm);
 
     Result AllocateAndMapPagesImpl(PageLinkedList* page_list, KProcessAddress address,
@@ -315,61 +320,61 @@ private:
     mutable KLightLock m_map_physical_memory_lock;
 
 public:
-    constexpr VAddr GetAddressSpaceStart() const {
+    constexpr KProcessAddress GetAddressSpaceStart() const {
         return m_address_space_start;
     }
-    constexpr VAddr GetAddressSpaceEnd() const {
+    constexpr KProcessAddress GetAddressSpaceEnd() const {
         return m_address_space_end;
     }
     constexpr size_t GetAddressSpaceSize() const {
         return m_address_space_end - m_address_space_start;
     }
-    constexpr VAddr GetHeapRegionStart() const {
+    constexpr KProcessAddress GetHeapRegionStart() const {
         return m_heap_region_start;
     }
-    constexpr VAddr GetHeapRegionEnd() const {
+    constexpr KProcessAddress GetHeapRegionEnd() const {
         return m_heap_region_end;
     }
     constexpr size_t GetHeapRegionSize() const {
         return m_heap_region_end - m_heap_region_start;
     }
-    constexpr VAddr GetAliasRegionStart() const {
+    constexpr KProcessAddress GetAliasRegionStart() const {
         return m_alias_region_start;
     }
-    constexpr VAddr GetAliasRegionEnd() const {
+    constexpr KProcessAddress GetAliasRegionEnd() const {
         return m_alias_region_end;
     }
     constexpr size_t GetAliasRegionSize() const {
         return m_alias_region_end - m_alias_region_start;
     }
-    constexpr VAddr GetStackRegionStart() const {
+    constexpr KProcessAddress GetStackRegionStart() const {
         return m_stack_region_start;
     }
-    constexpr VAddr GetStackRegionEnd() const {
+    constexpr KProcessAddress GetStackRegionEnd() const {
         return m_stack_region_end;
     }
     constexpr size_t GetStackRegionSize() const {
         return m_stack_region_end - m_stack_region_start;
     }
-    constexpr VAddr GetKernelMapRegionStart() const {
+    constexpr KProcessAddress GetKernelMapRegionStart() const {
         return m_kernel_map_region_start;
     }
-    constexpr VAddr GetKernelMapRegionEnd() const {
+    constexpr KProcessAddress GetKernelMapRegionEnd() const {
         return m_kernel_map_region_end;
     }
-    constexpr VAddr GetCodeRegionStart() const {
+    constexpr KProcessAddress GetCodeRegionStart() const {
         return m_code_region_start;
     }
-    constexpr VAddr GetCodeRegionEnd() const {
+    constexpr KProcessAddress GetCodeRegionEnd() const {
         return m_code_region_end;
     }
-    constexpr VAddr GetAliasCodeRegionStart() const {
+    constexpr KProcessAddress GetAliasCodeRegionStart() const {
         return m_alias_code_region_start;
     }
-    constexpr VAddr GetAliasCodeRegionEnd() const {
+    constexpr KProcessAddress GetAliasCodeRegionEnd() const {
         return m_alias_code_region_end;
     }
-    constexpr VAddr GetAliasCodeRegionSize() const {
+    constexpr size_t GetAliasCodeRegionSize() const {
         return m_alias_code_region_end - m_alias_code_region_start;
     }
     size_t GetNormalMemorySize() {
@@ -382,25 +387,25 @@ public:
     constexpr size_t GetHeapSize() const {
         return m_current_heap_end - m_heap_region_start;
     }
-    constexpr bool IsInsideAddressSpace(VAddr address, size_t size) const {
+    constexpr bool IsInsideAddressSpace(KProcessAddress address, size_t size) const {
         return m_address_space_start <= address && address + size - 1 <= m_address_space_end - 1;
     }
-    constexpr bool IsOutsideAliasRegion(VAddr address, size_t size) const {
+    constexpr bool IsOutsideAliasRegion(KProcessAddress address, size_t size) const {
         return m_alias_region_start > address || address + size - 1 > m_alias_region_end - 1;
     }
-    constexpr bool IsOutsideStackRegion(VAddr address, size_t size) const {
+    constexpr bool IsOutsideStackRegion(KProcessAddress address, size_t size) const {
         return m_stack_region_start > address || address + size - 1 > m_stack_region_end - 1;
     }
-    constexpr bool IsInvalidRegion(VAddr address, size_t size) const {
+    constexpr bool IsInvalidRegion(KProcessAddress address, size_t size) const {
         return address + size - 1 > GetAliasCodeRegionStart() + GetAliasCodeRegionSize() - 1;
     }
-    constexpr bool IsInsideHeapRegion(VAddr address, size_t size) const {
+    constexpr bool IsInsideHeapRegion(KProcessAddress address, size_t size) const {
         return address + size > m_heap_region_start && m_heap_region_end > address;
     }
-    constexpr bool IsInsideAliasRegion(VAddr address, size_t size) const {
+    constexpr bool IsInsideAliasRegion(KProcessAddress address, size_t size) const {
         return address + size > m_alias_region_start && m_alias_region_end > address;
     }
-    constexpr bool IsOutsideASLRRegion(VAddr address, size_t size) const {
+    constexpr bool IsOutsideASLRRegion(KProcessAddress address, size_t size) const {
         if (IsInvalidRegion(address, size)) {
             return true;
         }
@@ -412,47 +417,53 @@ public:
         }
         return {};
     }
-    constexpr bool IsInsideASLRRegion(VAddr address, size_t size) const {
+    constexpr bool IsInsideASLRRegion(KProcessAddress address, size_t size) const {
         return !IsOutsideASLRRegion(address, size);
     }
     constexpr size_t GetNumGuardPages() const {
         return IsKernel() ? 1 : 4;
     }
-    PAddr GetPhysicalAddr(VAddr addr) const {
+    KPhysicalAddress GetPhysicalAddr(KProcessAddress addr) const {
         const auto backing_addr = m_page_table_impl->backing_addr[addr >> PageBits];
         ASSERT(backing_addr);
-        return backing_addr + addr;
+        return backing_addr + GetInteger(addr);
     }
-    constexpr bool Contains(VAddr addr) const {
+    constexpr bool Contains(KProcessAddress addr) const {
         return m_address_space_start <= addr && addr <= m_address_space_end - 1;
     }
-    constexpr bool Contains(VAddr addr, size_t size) const {
+    constexpr bool Contains(KProcessAddress addr, size_t size) const {
         return m_address_space_start <= addr && addr < addr + size &&
                addr + size - 1 <= m_address_space_end - 1;
     }
 
 public:
-    static VAddr GetLinearMappedVirtualAddress(const KMemoryLayout& layout, PAddr addr) {
+    static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout,
+                                                         KPhysicalAddress addr) {
         return layout.GetLinearVirtualAddress(addr);
     }
 
-    static PAddr GetLinearMappedPhysicalAddress(const KMemoryLayout& layout, VAddr addr) {
+    static KPhysicalAddress GetLinearMappedPhysicalAddress(const KMemoryLayout& layout,
+                                                           KVirtualAddress addr) {
         return layout.GetLinearPhysicalAddress(addr);
     }
 
-    static VAddr GetHeapVirtualAddress(const KMemoryLayout& layout, PAddr addr) {
+    static KVirtualAddress GetHeapVirtualAddress(const KMemoryLayout& layout,
+                                                 KPhysicalAddress addr) {
         return GetLinearMappedVirtualAddress(layout, addr);
     }
 
-    static PAddr GetHeapPhysicalAddress(const KMemoryLayout& layout, VAddr addr) {
+    static KPhysicalAddress GetHeapPhysicalAddress(const KMemoryLayout& layout,
+                                                   KVirtualAddress addr) {
         return GetLinearMappedPhysicalAddress(layout, addr);
     }
 
-    static VAddr GetPageTableVirtualAddress(const KMemoryLayout& layout, PAddr addr) {
+    static KVirtualAddress GetPageTableVirtualAddress(const KMemoryLayout& layout,
+                                                      KPhysicalAddress addr) {
         return GetLinearMappedVirtualAddress(layout, addr);
     }
 
-    static PAddr GetPageTablePhysicalAddress(const KMemoryLayout& layout, VAddr addr) {
+    static KPhysicalAddress GetPageTablePhysicalAddress(const KMemoryLayout& layout,
+                                                        KVirtualAddress addr) {
         return GetLinearMappedPhysicalAddress(layout, addr);
     }
 
@@ -464,7 +475,7 @@ private:
         return m_enable_aslr;
     }
 
-    constexpr bool ContainsPages(VAddr addr, size_t num_pages) const {
+    constexpr bool ContainsPages(KProcessAddress addr, size_t num_pages) const {
         return (m_address_space_start <= addr) &&
                (num_pages <= (m_address_space_end - m_address_space_start) / PageSize) &&
                (addr + num_pages * PageSize - 1 <= m_address_space_end - 1);
@@ -489,21 +500,21 @@ private:
     };
 
 private:
-    VAddr m_address_space_start{};
-    VAddr m_address_space_end{};
-    VAddr m_heap_region_start{};
-    VAddr m_heap_region_end{};
-    VAddr m_current_heap_end{};
-    VAddr m_alias_region_start{};
-    VAddr m_alias_region_end{};
-    VAddr m_stack_region_start{};
-    VAddr m_stack_region_end{};
-    VAddr m_kernel_map_region_start{};
-    VAddr m_kernel_map_region_end{};
-    VAddr m_code_region_start{};
-    VAddr m_code_region_end{};
-    VAddr m_alias_code_region_start{};
-    VAddr m_alias_code_region_end{};
+    KProcessAddress m_address_space_start{};
+    KProcessAddress m_address_space_end{};
+    KProcessAddress m_heap_region_start{};
+    KProcessAddress m_heap_region_end{};
+    KProcessAddress m_current_heap_end{};
+    KProcessAddress m_alias_region_start{};
+    KProcessAddress m_alias_region_end{};
+    KProcessAddress m_stack_region_start{};
+    KProcessAddress m_stack_region_end{};
+    KProcessAddress m_kernel_map_region_start{};
+    KProcessAddress m_kernel_map_region_end{};
+    KProcessAddress m_code_region_start{};
+    KProcessAddress m_code_region_end{};
+    KProcessAddress m_alias_code_region_start{};
+    KProcessAddress m_alias_code_region_end{};
 
     size_t m_max_heap_size{};
     size_t m_mapped_physical_memory_size{};
diff --git a/src/core/hle/kernel/k_page_table_manager.h b/src/core/hle/kernel/k_page_table_manager.h
index 91a45cde3..4b0e034d0 100755
--- a/src/core/hle/kernel/k_page_table_manager.h
+++ b/src/core/hle/kernel/k_page_table_manager.h
@@ -5,9 +5,9 @@
 
 #include <atomic>
 
-#include "common/common_types.h"
 #include "core/hle/kernel/k_dynamic_resource_manager.h"
 #include "core/hle/kernel/k_page_table_slab_heap.h"
+#include "core/hle/kernel/k_typed_address.h"
 
 namespace Kernel {
 
@@ -26,23 +26,23 @@ public:
         BaseHeap::Initialize(page_allocator, pt_heap);
     }
 
-    VAddr Allocate() {
-        return VAddr(BaseHeap::Allocate());
+    KVirtualAddress Allocate() {
+        return KVirtualAddress(BaseHeap::Allocate());
     }
 
-    RefCount GetRefCount(VAddr addr) const {
+    RefCount GetRefCount(KVirtualAddress addr) const {
         return m_pt_heap->GetRefCount(addr);
     }
 
-    void Open(VAddr addr, int count) {
+    void Open(KVirtualAddress addr, int count) {
         return m_pt_heap->Open(addr, count);
     }
 
-    bool Close(VAddr addr, int count) {
+    bool Close(KVirtualAddress addr, int count) {
         return m_pt_heap->Close(addr, count);
     }
 
-    bool IsInPageTableHeap(VAddr addr) const {
+    bool IsInPageTableHeap(KVirtualAddress addr) const {
         return m_pt_heap->IsInRange(addr);
     }
 
diff --git a/src/core/hle/kernel/k_page_table_slab_heap.h b/src/core/hle/kernel/k_page_table_slab_heap.h
index 9a8d77316..7da0ea669 100755
--- a/src/core/hle/kernel/k_page_table_slab_heap.h
+++ b/src/core/hle/kernel/k_page_table_slab_heap.h
@@ -6,8 +6,8 @@
 #include <array>
 #include <vector>
 
-#include "common/common_types.h"
 #include "core/hle/kernel/k_dynamic_slab_heap.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/slab_helpers.h"
 
 namespace Kernel {
@@ -45,12 +45,12 @@ public:
         this->Initialize(rc);
     }
 
-    RefCount GetRefCount(VAddr addr) {
+    RefCount GetRefCount(KVirtualAddress addr) {
         ASSERT(this->IsInRange(addr));
         return *this->GetRefCountPointer(addr);
     }
 
-    void Open(VAddr addr, int count) {
+    void Open(KVirtualAddress addr, int count) {
         ASSERT(this->IsInRange(addr));
 
         *this->GetRefCountPointer(addr) += static_cast<RefCount>(count);
@@ -58,7 +58,7 @@ public:
         ASSERT(this->GetRefCount(addr) > 0);
     }
 
-    bool Close(VAddr addr, int count) {
+    bool Close(KVirtualAddress addr, int count) {
         ASSERT(this->IsInRange(addr));
         ASSERT(this->GetRefCount(addr) >= count);
 
@@ -66,7 +66,7 @@ public:
         return this->GetRefCount(addr) == 0;
     }
 
-    bool IsInPageTableHeap(VAddr addr) const {
+    bool IsInPageTableHeap(KVirtualAddress addr) const {
         return this->IsInRange(addr);
     }
 
@@ -81,7 +81,7 @@ private:
         }
     }
 
-    RefCount* GetRefCountPointer(VAddr addr) {
+    RefCount* GetRefCountPointer(KVirtualAddress addr) {
         return m_ref_counts.data() + ((addr - this->GetAddress()) / PageSize);
     }
 
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 3f766ded7..7b5f546f7 100755
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -36,8 +36,9 @@ namespace {
  * @param owner_process The parent process for the main thread
  * @param priority The priority to give the main thread
  */
-void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, VAddr stack_top) {
-    const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart();
+void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
+                     KProcessAddress stack_top) {
+    const KProcessAddress entry_point = owner_process.PageTable().GetCodeRegionStart();
     ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
 
     KThread* thread = KThread::Create(system.Kernel());
@@ -219,7 +220,7 @@ void KProcess::UnpinThread(KThread* thread) {
     KScheduler::SetSchedulerUpdateNeeded(m_kernel);
 }
 
-Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr address,
+Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] KProcessAddress address,
                                  [[maybe_unused]] size_t size) {
     // Lock ourselves, to prevent concurrent access.
     KScopedLightLock lk(m_state_lock);
@@ -248,7 +249,7 @@ Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr ad
     R_SUCCEED();
 }
 
-void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr address,
+void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] KProcessAddress address,
                                   [[maybe_unused]] size_t size) {
     // Lock ourselves, to prevent concurrent access.
     KScopedLightLock lk(m_state_lock);
@@ -399,8 +400,8 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
 
     case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
         m_memory_usage_capacity =
-            m_page_table.GetHeapRegionEnd() - m_page_table.GetHeapRegionStart() +
-            m_page_table.GetAliasRegionEnd() - m_page_table.GetAliasRegionStart();
+            (m_page_table.GetHeapRegionEnd() - m_page_table.GetHeapRegionStart()) +
+            (m_page_table.GetAliasRegionEnd() - m_page_table.GetAliasRegionStart());
         break;
 
     default:
@@ -492,9 +493,9 @@ void KProcess::Finalize() {
     KSynchronizationObject::Finalize();
 }
 
-Result KProcess::CreateThreadLocalRegion(VAddr* out) {
+Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) {
     KThreadLocalPage* tlp = nullptr;
-    VAddr tlr = 0;
+    KProcessAddress tlr = 0;
 
     // See if we can get a region from a partially used TLP.
     {
@@ -543,7 +544,7 @@ Result KProcess::CreateThreadLocalRegion(VAddr* out) {
     R_SUCCEED();
 }
 
-Result KProcess::DeleteThreadLocalRegion(VAddr addr) {
+Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) {
     KThreadLocalPage* page_to_free = nullptr;
 
     // Release the region.
@@ -551,10 +552,10 @@ Result KProcess::DeleteThreadLocalRegion(VAddr addr) {
         KScopedSchedulerLock sl{m_kernel};
 
         // Try to find the page in the partially used list.
-        auto it = m_partially_used_tlp_tree.find_key(Common::AlignDown(addr, PageSize));
+        auto it = m_partially_used_tlp_tree.find_key(Common::AlignDown(GetInteger(addr), PageSize));
         if (it == m_partially_used_tlp_tree.end()) {
             // If we don't find it, it has to be in the fully used list.
-            it = m_fully_used_tlp_tree.find_key(Common::AlignDown(addr, PageSize));
+            it = m_fully_used_tlp_tree.find_key(Common::AlignDown(GetInteger(addr), PageSize));
             R_UNLESS(it != m_fully_used_tlp_tree.end(), ResultInvalidAddress);
 
             // Release the region.
@@ -591,7 +592,7 @@ Result KProcess::DeleteThreadLocalRegion(VAddr addr) {
     R_SUCCEED();
 }
 
-bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size,
+bool KProcess::InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
                                 DebugWatchpointType type) {
     const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) {
         return wp.type == DebugWatchpointType::None;
@@ -605,7 +606,8 @@ bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size,
     watch->end_address = addr + size;
     watch->type = type;
 
-    for (VAddr page = Common::AlignDown(addr, PageSize); page < addr + size; page += PageSize) {
+    for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size;
+         page += PageSize) {
         m_debug_page_refcounts[page]++;
         system.Memory().MarkRegionDebug(page, PageSize, true);
     }
@@ -613,7 +615,7 @@ bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size,
     return true;
 }
 
-bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size,
+bool KProcess::RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
                                 DebugWatchpointType type) {
     const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) {
         return wp.start_address == addr && wp.end_address == addr + size && wp.type == type;
@@ -627,7 +629,8 @@ bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size,
     watch->end_address = 0;
     watch->type = DebugWatchpointType::None;
 
-    for (VAddr page = Common::AlignDown(addr, PageSize); page < addr + size; page += PageSize) {
+    for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size;
+         page += PageSize) {
         m_debug_page_refcounts[page]--;
         if (!m_debug_page_refcounts[page]) {
             system.Memory().MarkRegionDebug(page, PageSize, false);
@@ -637,7 +640,7 @@ bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size,
     return true;
 }
 
-void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) {
+void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) {
     const auto ReprotectSegment = [&](const CodeSet::Segment& segment,
                                       Svc::MemoryPermission permission) {
         m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission);
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index e79542378..c4415936b 100755
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -8,7 +8,6 @@
 #include <list>
 #include <map>
 #include <string>
-#include "common/common_types.h"
 #include "core/hle/kernel/k_address_arbiter.h"
 #include "core/hle/kernel/k_auto_object.h"
 #include "core/hle/kernel/k_condition_variable.h"
@@ -16,6 +15,7 @@
 #include "core/hle/kernel/k_page_table.h"
 #include "core/hle/kernel/k_synchronization_object.h"
 #include "core/hle/kernel/k_thread_local_page.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/k_worker_task.h"
 #include "core/hle/kernel/process_capability.h"
 #include "core/hle/kernel/slab_helpers.h"
@@ -59,8 +59,8 @@ enum class DebugWatchpointType : u8 {
 DECLARE_ENUM_FLAG_OPERATORS(DebugWatchpointType);
 
 struct DebugWatchpoint {
-    VAddr start_address;
-    VAddr end_address;
+    KProcessAddress start_address;
+    KProcessAddress end_address;
     DebugWatchpointType type;
 };
 
@@ -135,11 +135,11 @@ public:
         return m_handle_table;
     }
 
-    Result SignalToAddress(VAddr address) {
+    Result SignalToAddress(KProcessAddress address) {
         return m_condition_var.SignalToAddress(address);
     }
 
-    Result WaitForAddress(Handle handle, VAddr address, u32 tag) {
+    Result WaitForAddress(Handle handle, KProcessAddress address, u32 tag) {
         return m_condition_var.WaitForAddress(handle, address, tag);
     }
 
@@ -147,20 +147,21 @@ public:
         return m_condition_var.Signal(cv_key, count);
     }
 
-    Result WaitConditionVariable(VAddr address, u64 cv_key, u32 tag, s64 ns) {
+    Result WaitConditionVariable(KProcessAddress address, u64 cv_key, u32 tag, s64 ns) {
         R_RETURN(m_condition_var.Wait(address, cv_key, tag, ns));
     }
 
-    Result SignalAddressArbiter(VAddr address, Svc::SignalType signal_type, s32 value, s32 count) {
+    Result SignalAddressArbiter(uint64_t address, Svc::SignalType signal_type, s32 value,
+                                s32 count) {
         R_RETURN(m_address_arbiter.SignalToAddress(address, signal_type, value, count));
     }
 
-    Result WaitAddressArbiter(VAddr address, Svc::ArbitrationType arb_type, s32 value,
+    Result WaitAddressArbiter(uint64_t address, Svc::ArbitrationType arb_type, s32 value,
                               s64 timeout) {
         R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout));
     }
 
-    VAddr GetProcessLocalRegionAddress() const {
+    KProcessAddress GetProcessLocalRegionAddress() const {
         return m_plr_address;
     }
 
@@ -352,7 +353,7 @@ public:
      */
     void PrepareForTermination();
 
-    void LoadModule(CodeSet code_set, VAddr base_addr);
+    void LoadModule(CodeSet code_set, KProcessAddress base_addr);
 
     bool IsInitialized() const override {
         return m_is_initialized;
@@ -380,26 +381,28 @@ public:
         return m_state_lock;
     }
 
-    Result AddSharedMemory(KSharedMemory* shmem, VAddr address, size_t size);
-    void RemoveSharedMemory(KSharedMemory* shmem, VAddr address, size_t size);
+    Result AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size);
+    void RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size);
 
     ///////////////////////////////////////////////////////////////////////////////////////////////
     // Thread-local storage management
 
     // Marks the next available region as used and returns the address of the slot.
-    [[nodiscard]] Result CreateThreadLocalRegion(VAddr* out);
+    [[nodiscard]] Result CreateThreadLocalRegion(KProcessAddress* out);
 
     // Frees a used TLS slot identified by the given address
-    Result DeleteThreadLocalRegion(VAddr addr);
+    Result DeleteThreadLocalRegion(KProcessAddress addr);
 
     ///////////////////////////////////////////////////////////////////////////////////////////////
     // Debug watchpoint management
 
     // Attempts to insert a watchpoint into a free slot. Returns false if none are available.
-    bool InsertWatchpoint(Core::System& system, VAddr addr, u64 size, DebugWatchpointType type);
+    bool InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
+                          DebugWatchpointType type);
 
     // Attempts to remove the watchpoint specified by the given parameters.
-    bool RemoveWatchpoint(Core::System& system, VAddr addr, u64 size, DebugWatchpointType type);
+    bool RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size,
+                          DebugWatchpointType type);
 
     const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const {
         return m_watchpoints;
@@ -457,7 +460,7 @@ private:
     /// Resource limit descriptor for this process
     KResourceLimit* m_resource_limit{};
 
-    VAddr m_system_resource_address{};
+    KVirtualAddress m_system_resource_address{};
 
     /// The ideal CPU core for this process, threads are scheduled on this core by default.
     u8 m_ideal_core = 0;
@@ -485,7 +488,7 @@ private:
     KConditionVariable m_condition_var;
 
     /// Address indicating the location of the process' dedicated TLS region.
-    VAddr m_plr_address = 0;
+    KProcessAddress m_plr_address = 0;
 
     /// Random values for svcGetInfo RandomEntropy
     std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{};
@@ -497,7 +500,7 @@ private:
     std::list<KSharedMemoryInfo*> m_shared_memory_list;
 
     /// Address of the top of the main thread's stack
-    VAddr m_main_thread_stack_top{};
+    KProcessAddress m_main_thread_stack_top{};
 
     /// Size of the main thread's stack
     std::size_t m_main_thread_stack_size{};
@@ -527,7 +530,7 @@ private:
     std::array<u64, Core::Hardware::NUM_CPU_CORES> m_running_thread_idle_counts{};
     std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{};
     std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
-    std::map<VAddr, u64> m_debug_page_refcounts;
+    std::map<KProcessAddress, u64> m_debug_page_refcounts;
 
     KThread* m_exception_thread{};
 
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index b013e0e51..106817c8d 100755
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -511,7 +511,7 @@ void KScheduler::Reload(KThread* thread) {
     auto& cpu_core = m_kernel.System().ArmInterface(m_core_id);
     cpu_core.LoadContext(thread->GetContext32());
     cpu_core.LoadContext(thread->GetContext64());
-    cpu_core.SetTlsAddress(thread->GetTlsAddress());
+    cpu_core.SetTlsAddress(GetInteger(thread->GetTlsAddress()));
     cpu_core.SetTPIDR_EL0(thread->GetTpidrEl0());
     cpu_core.LoadWatchpointArray(thread->GetOwnerProcess()->GetWatchpoints());
     cpu_core.ClearExclusiveState();
diff --git a/src/core/hle/kernel/k_session_request.cpp b/src/core/hle/kernel/k_session_request.cpp
index 7fb61d8c4..42b03ef2f 100755
--- a/src/core/hle/kernel/k_session_request.cpp
+++ b/src/core/hle/kernel/k_session_request.cpp
@@ -6,8 +6,8 @@
 
 namespace Kernel {
 
-Result KSessionRequest::SessionMappings::PushMap(VAddr client, VAddr server, size_t size,
-                                                 KMemoryState state, size_t index) {
+Result KSessionRequest::SessionMappings::PushMap(KProcessAddress client, KProcessAddress server,
+                                                 size_t size, KMemoryState state, size_t index) {
     // At most 15 buffers of each type (4-bit descriptor counts).
     ASSERT(index < ((1ul << 4) - 1) * 3);
 
@@ -33,20 +33,21 @@ Result KSessionRequest::SessionMappings::PushMap(VAddr client, VAddr server, siz
     R_SUCCEED();
 }
 
-Result KSessionRequest::SessionMappings::PushSend(VAddr client, VAddr server, size_t size,
-                                                  KMemoryState state) {
+Result KSessionRequest::SessionMappings::PushSend(KProcessAddress client, KProcessAddress server,
+                                                  size_t size, KMemoryState state) {
     ASSERT(m_num_recv == 0);
     ASSERT(m_num_exch == 0);
     R_RETURN(this->PushMap(client, server, size, state, m_num_send++));
 }
 
-Result KSessionRequest::SessionMappings::PushReceive(VAddr client, VAddr server, size_t size,
-                                                     KMemoryState state) {
+Result KSessionRequest::SessionMappings::PushReceive(KProcessAddress client, KProcessAddress server,
+                                                     size_t size, KMemoryState state) {
     ASSERT(m_num_exch == 0);
     R_RETURN(this->PushMap(client, server, size, state, m_num_send + m_num_recv++));
 }
 
-Result KSessionRequest::SessionMappings::PushExchange(VAddr client, VAddr server, size_t size,
+Result KSessionRequest::SessionMappings::PushExchange(KProcessAddress client,
+                                                      KProcessAddress server, size_t size,
                                                       KMemoryState state) {
     R_RETURN(this->PushMap(client, server, size, state, m_num_send + m_num_recv + m_num_exch++));
 }
diff --git a/src/core/hle/kernel/k_session_request.h b/src/core/hle/kernel/k_session_request.h
index b4fdbeb7b..2104995b8 100755
--- a/src/core/hle/kernel/k_session_request.h
+++ b/src/core/hle/kernel/k_session_request.h
@@ -26,17 +26,17 @@ public:
 
         class Mapping {
         public:
-            constexpr void Set(VAddr c, VAddr s, size_t sz, KMemoryState st) {
+            constexpr void Set(KProcessAddress c, KProcessAddress s, size_t sz, KMemoryState st) {
                 m_client_address = c;
                 m_server_address = s;
                 m_size = sz;
                 m_state = st;
             }
 
-            constexpr VAddr GetClientAddress() const {
+            constexpr KProcessAddress GetClientAddress() const {
                 return m_client_address;
             }
-            constexpr VAddr GetServerAddress() const {
+            constexpr KProcessAddress GetServerAddress() const {
                 return m_server_address;
             }
             constexpr size_t GetSize() const {
@@ -47,8 +47,8 @@ public:
             }
 
         private:
-            VAddr m_client_address{};
-            VAddr m_server_address{};
+            KProcessAddress m_client_address{};
+            KProcessAddress m_server_address{};
             size_t m_size{};
             KMemoryState m_state{};
         };
@@ -69,14 +69,17 @@ public:
             return m_num_exch;
         }
 
-        Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state);
-        Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state);
-        Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state);
+        Result PushSend(KProcessAddress client, KProcessAddress server, size_t size,
+                        KMemoryState state);
+        Result PushReceive(KProcessAddress client, KProcessAddress server, size_t size,
+                           KMemoryState state);
+        Result PushExchange(KProcessAddress client, KProcessAddress server, size_t size,
+                            KMemoryState state);
 
-        VAddr GetSendClientAddress(size_t i) const {
+        KProcessAddress GetSendClientAddress(size_t i) const {
             return GetSendMapping(i).GetClientAddress();
         }
-        VAddr GetSendServerAddress(size_t i) const {
+        KProcessAddress GetSendServerAddress(size_t i) const {
             return GetSendMapping(i).GetServerAddress();
         }
         size_t GetSendSize(size_t i) const {
@@ -86,10 +89,10 @@ public:
             return GetSendMapping(i).GetMemoryState();
         }
 
-        VAddr GetReceiveClientAddress(size_t i) const {
+        KProcessAddress GetReceiveClientAddress(size_t i) const {
             return GetReceiveMapping(i).GetClientAddress();
         }
-        VAddr GetReceiveServerAddress(size_t i) const {
+        KProcessAddress GetReceiveServerAddress(size_t i) const {
             return GetReceiveMapping(i).GetServerAddress();
         }
         size_t GetReceiveSize(size_t i) const {
@@ -99,10 +102,10 @@ public:
             return GetReceiveMapping(i).GetMemoryState();
         }
 
-        VAddr GetExchangeClientAddress(size_t i) const {
+        KProcessAddress GetExchangeClientAddress(size_t i) const {
             return GetExchangeMapping(i).GetClientAddress();
         }
-        VAddr GetExchangeServerAddress(size_t i) const {
+        KProcessAddress GetExchangeServerAddress(size_t i) const {
             return GetExchangeMapping(i).GetServerAddress();
         }
         size_t GetExchangeSize(size_t i) const {
@@ -113,7 +116,8 @@ public:
         }
 
     private:
-        Result PushMap(VAddr client, VAddr server, size_t size, KMemoryState state, size_t index);
+        Result PushMap(KProcessAddress client, KProcessAddress server, size_t size,
+                       KMemoryState state, size_t index);
 
         const Mapping& GetSendMapping(size_t i) const {
             ASSERT(i < m_num_send);
@@ -227,22 +231,25 @@ public:
         return m_mappings.GetExchangeCount();
     }
 
-    Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state) {
+    Result PushSend(KProcessAddress client, KProcessAddress server, size_t size,
+                    KMemoryState state) {
         return m_mappings.PushSend(client, server, size, state);
     }
 
-    Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state) {
+    Result PushReceive(KProcessAddress client, KProcessAddress server, size_t size,
+                       KMemoryState state) {
         return m_mappings.PushReceive(client, server, size, state);
     }
 
-    Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state) {
+    Result PushExchange(KProcessAddress client, KProcessAddress server, size_t size,
+                        KMemoryState state) {
         return m_mappings.PushExchange(client, server, size, state);
     }
 
-    VAddr GetSendClientAddress(size_t i) const {
+    KProcessAddress GetSendClientAddress(size_t i) const {
         return m_mappings.GetSendClientAddress(i);
     }
-    VAddr GetSendServerAddress(size_t i) const {
+    KProcessAddress GetSendServerAddress(size_t i) const {
         return m_mappings.GetSendServerAddress(i);
     }
     size_t GetSendSize(size_t i) const {
@@ -252,10 +259,10 @@ public:
         return m_mappings.GetSendMemoryState(i);
     }
 
-    VAddr GetReceiveClientAddress(size_t i) const {
+    KProcessAddress GetReceiveClientAddress(size_t i) const {
         return m_mappings.GetReceiveClientAddress(i);
     }
-    VAddr GetReceiveServerAddress(size_t i) const {
+    KProcessAddress GetReceiveServerAddress(size_t i) const {
         return m_mappings.GetReceiveServerAddress(i);
     }
     size_t GetReceiveSize(size_t i) const {
@@ -265,10 +272,10 @@ public:
         return m_mappings.GetReceiveMemoryState(i);
     }
 
-    VAddr GetExchangeClientAddress(size_t i) const {
+    KProcessAddress GetExchangeClientAddress(size_t i) const {
         return m_mappings.GetExchangeClientAddress(i);
     }
-    VAddr GetExchangeServerAddress(size_t i) const {
+    KProcessAddress GetExchangeServerAddress(size_t i) const {
         return m_mappings.GetExchangeServerAddress(i);
     }
     size_t GetExchangeSize(size_t i) const {
diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp
index ee75eebc0..d2a76a237 100755
--- a/src/core/hle/kernel/k_shared_memory.cpp
+++ b/src/core/hle/kernel/k_shared_memory.cpp
@@ -76,7 +76,7 @@ void KSharedMemory::Finalize() {
     m_resource_limit->Close();
 }
 
-Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t map_size,
+Result KSharedMemory::Map(KProcess& target_process, KProcessAddress address, std::size_t map_size,
                           Svc::MemoryPermission map_perm) {
     // Validate the size.
     R_UNLESS(m_size == map_size, ResultInvalidSize);
@@ -94,7 +94,8 @@ Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t m
                                                      ConvertToKMemoryPermission(map_perm)));
 }
 
-Result KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) {
+Result KSharedMemory::Unmap(KProcess& target_process, KProcessAddress address,
+                            std::size_t unmap_size) {
     // Validate the size.
     R_UNLESS(m_size == unmap_size, ResultInvalidSize);
 
diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h
index 203378535..e91e6e566 100755
--- a/src/core/hle/kernel/k_shared_memory.h
+++ b/src/core/hle/kernel/k_shared_memory.h
@@ -6,11 +6,11 @@
 #include <optional>
 #include <string>
 
-#include "common/common_types.h"
 #include "core/device_memory.h"
 #include "core/hle/kernel/k_memory_block.h"
 #include "core/hle/kernel/k_page_group.h"
 #include "core/hle/kernel/k_process.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/slab_helpers.h"
 #include "core/hle/result.h"
 
@@ -37,7 +37,7 @@ public:
      * @param map_size Size of the shared memory block to map
      * @param permissions Memory block map permissions (specified by SVC field)
      */
-    Result Map(KProcess& target_process, VAddr address, std::size_t map_size,
+    Result Map(KProcess& target_process, KProcessAddress address, std::size_t map_size,
                Svc::MemoryPermission permissions);
 
     /**
@@ -46,7 +46,7 @@ public:
      * @param address Address in system memory to unmap shared memory block
      * @param unmap_size Size of the shared memory block to unmap
      */
-    Result Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size);
+    Result Unmap(KProcess& target_process, KProcessAddress address, std::size_t unmap_size);
 
     /**
      * Gets a pointer to the shared memory block
@@ -79,7 +79,7 @@ private:
     std::optional<KPageGroup> m_page_group{};
     Svc::MemoryPermission m_owner_permission{};
     Svc::MemoryPermission m_user_permission{};
-    PAddr m_physical_address{};
+    KPhysicalAddress m_physical_address{};
     std::size_t m_size{};
     KResourceLimit* m_resource_limit{};
     bool m_is_initialized{};
diff --git a/src/core/hle/kernel/k_system_resource.h b/src/core/hle/kernel/k_system_resource.h
index d36aaa9bd..6ea482185 100755
--- a/src/core/hle/kernel/k_system_resource.h
+++ b/src/core/hle/kernel/k_system_resource.h
@@ -130,7 +130,7 @@ private:
     KBlockInfoSlabHeap m_block_info_heap;
     KPageTableSlabHeap m_page_table_heap;
     KResourceLimit* m_resource_limit{};
-    VAddr m_resource_address{};
+    KVirtualAddress m_resource_address{};
     size_t m_resource_size{};
 };
 
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index a95fef43a..9d7be6c0b 100755
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -48,8 +48,8 @@ static void ResetThreadContext32(Kernel::KThread::ThreadContext32& context, u32
     context.fpscr = 0;
 }
 
-static void ResetThreadContext64(Kernel::KThread::ThreadContext64& context, VAddr stack_top,
-                                 VAddr entry_point, u64 arg) {
+static void ResetThreadContext64(Kernel::KThread::ThreadContext64& context, u64 stack_top,
+                                 u64 entry_point, u64 arg) {
     context = {};
     context.cpu_registers[0] = arg;
     context.cpu_registers[18] = Kernel::KSystemControl::GenerateRandomU64() | 1;
@@ -100,8 +100,8 @@ KThread::KThread(KernelCore& kernel)
     : KAutoObjectWithSlabHeapAndContainer{kernel}, m_activity_pause_lock{kernel} {}
 KThread::~KThread() = default;
 
-Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio,
-                           s32 virt_core, KProcess* owner, ThreadType type) {
+Result KThread::Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top,
+                           s32 prio, s32 virt_core, KProcess* owner, ThreadType type) {
     // Assert parameters are valid.
     ASSERT((type == ThreadType::Main) || (type == ThreadType::Dummy) ||
            (Svc::HighestThreadPriority <= prio && prio <= Svc::LowestThreadPriority));
@@ -221,9 +221,9 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack
     }
 
     // Initialize thread context.
-    ResetThreadContext64(m_thread_context_64, user_stack_top, func, arg);
-    ResetThreadContext32(m_thread_context_32, static_cast<u32>(user_stack_top),
-                         static_cast<u32>(func), static_cast<u32>(arg));
+    ResetThreadContext64(m_thread_context_64, GetInteger(user_stack_top), GetInteger(func), arg);
+    ResetThreadContext32(m_thread_context_32, static_cast<u32>(GetInteger(user_stack_top)),
+                         static_cast<u32>(GetInteger(func)), static_cast<u32>(arg));
 
     // Setup the stack parameters.
     StackParameters& sp = this->GetStackParameters();
@@ -249,8 +249,9 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack
 }
 
 Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg,
-                                 VAddr user_stack_top, s32 prio, s32 core, KProcess* owner,
-                                 ThreadType type, std::function<void()>&& init_func) {
+                                 KProcessAddress user_stack_top, s32 prio, s32 core,
+                                 KProcess* owner, ThreadType type,
+                                 std::function<void()>&& init_func) {
     // Initialize the thread.
     R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type));
 
@@ -288,8 +289,8 @@ Result KThread::InitializeHighPriorityThread(Core::System& system, KThread* thre
 }
 
 Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func,
-                                     uintptr_t arg, VAddr user_stack_top, s32 prio, s32 virt_core,
-                                     KProcess* owner) {
+                                     uintptr_t arg, KProcessAddress user_stack_top, s32 prio,
+                                     s32 virt_core, KProcess* owner) {
     system.Kernel().GlobalSchedulerContext().AddThread(thread);
     R_RETURN(InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner,
                               ThreadType::User, system.GetCpuManager().GetGuestThreadFunc()));
@@ -951,7 +952,7 @@ void KThread::AddHeldLock(LockWithPriorityInheritanceInfo* lock_info) {
     m_held_lock_info_list.push_front(*lock_info);
 }
 
-KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(VAddr address_key,
+KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(KProcessAddress address_key,
                                                                 bool is_kernel_address_key) {
     ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
 
@@ -1087,7 +1088,8 @@ void KThread::RemoveWaiter(KThread* thread) {
     }
 }
 
-KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, VAddr key, bool is_kernel_address_key_) {
+KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key,
+                                    bool is_kernel_address_key_) {
     ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
 
     // Get the relevant lock info.
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 8fb98a0a5..b0481a614 100755
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -14,7 +14,6 @@
 
 #include <boost/intrusive/list.hpp>
 
-#include "common/common_types.h"
 #include "common/intrusive_red_black_tree.h"
 #include "common/spin_lock.h"
 #include "core/arm/arm_interface.h"
@@ -23,6 +22,7 @@
 #include "core/hle/kernel/k_spin_lock.h"
 #include "core/hle/kernel/k_synchronization_object.h"
 #include "core/hle/kernel/k_timer_task.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/k_worker_task.h"
 #include "core/hle/kernel/slab_helpers.h"
 #include "core/hle/kernel/svc_common.h"
@@ -46,7 +46,7 @@ class KProcess;
 class KScheduler;
 class KThreadQueue;
 
-using KThreadFunction = VAddr;
+using KThreadFunction = KProcessAddress;
 
 enum class ThreadType : u32 {
     Main = 0,
@@ -230,9 +230,9 @@ public:
 
     /*
      * Returns the Thread Local Storage address of the current thread
-     * @returns VAddr of the thread's TLS
+     * @returns Address of the thread's TLS
      */
-    VAddr GetTlsAddress() const {
+    KProcessAddress GetTlsAddress() const {
         return m_tls_address;
     }
 
@@ -419,8 +419,8 @@ public:
                                                KThreadFunction func, uintptr_t arg, s32 virt_core);
 
     static Result InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func,
-                                       uintptr_t arg, VAddr user_stack_top, s32 prio, s32 virt_core,
-                                       KProcess* owner);
+                                       uintptr_t arg, KProcessAddress user_stack_top, s32 prio,
+                                       s32 virt_core, KProcess* owner);
 
     static Result InitializeServiceThread(Core::System& system, KThread* thread,
                                           std::function<void()>&& thread_func, s32 prio,
@@ -565,15 +565,15 @@ public:
 
     Result GetThreadContext3(std::vector<u8>& out);
 
-    KThread* RemoveUserWaiterByKey(bool* out_has_waiters, VAddr key) {
+    KThread* RemoveUserWaiterByKey(bool* out_has_waiters, KProcessAddress key) {
         return this->RemoveWaiterByKey(out_has_waiters, key, false);
     }
 
-    KThread* RemoveKernelWaiterByKey(bool* out_has_waiters, VAddr key) {
+    KThread* RemoveKernelWaiterByKey(bool* out_has_waiters, KProcessAddress key) {
         return this->RemoveWaiterByKey(out_has_waiters, key, true);
     }
 
-    VAddr GetAddressKey() const {
+    KProcessAddress GetAddressKey() const {
         return m_address_key;
     }
 
@@ -591,14 +591,14 @@ public:
     // to cope with arbitrary host pointers making their way
     // into things.
 
-    void SetUserAddressKey(VAddr key, u32 val) {
+    void SetUserAddressKey(KProcessAddress key, u32 val) {
         ASSERT(m_waiting_lock_info == nullptr);
         m_address_key = key;
         m_address_key_value = val;
         m_is_kernel_address_key = false;
     }
 
-    void SetKernelAddressKey(VAddr key) {
+    void SetKernelAddressKey(KProcessAddress key) {
         ASSERT(m_waiting_lock_info == nullptr);
         m_address_key = key;
         m_is_kernel_address_key = true;
@@ -637,12 +637,13 @@ public:
         return m_argument;
     }
 
-    VAddr GetUserStackTop() const {
+    KProcessAddress GetUserStackTop() const {
         return m_stack_top;
     }
 
 private:
-    KThread* RemoveWaiterByKey(bool* out_has_waiters, VAddr key, bool is_kernel_address_key);
+    KThread* RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key,
+                               bool is_kernel_address_key);
 
     static constexpr size_t PriorityInheritanceCountMax = 10;
     union SyncObjectBuffer {
@@ -695,12 +696,13 @@ private:
 
     void IncreaseBasePriority(s32 priority);
 
-    Result Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio,
+    Result Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio,
                       s32 virt_core, KProcess* owner, ThreadType type);
 
     static Result InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg,
-                                   VAddr user_stack_top, s32 prio, s32 core, KProcess* owner,
-                                   ThreadType type, std::function<void()>&& init_func);
+                                   KProcessAddress user_stack_top, s32 prio, s32 core,
+                                   KProcess* owner, ThreadType type,
+                                   std::function<void()>&& init_func);
 
     // For core KThread implementation
     ThreadContext32 m_thread_context_32{};
@@ -749,7 +751,8 @@ public:
     public:
         explicit LockWithPriorityInheritanceInfo(KernelCore&) {}
 
-        static LockWithPriorityInheritanceInfo* Create(KernelCore& kernel, VAddr address_key,
+        static LockWithPriorityInheritanceInfo* Create(KernelCore& kernel,
+                                                       KProcessAddress address_key,
                                                        bool is_kernel_address_key) {
             // Create a new lock info.
             auto* new_lock = LockWithPriorityInheritanceInfo::Allocate(kernel);
@@ -797,7 +800,7 @@ public:
             return m_tree;
         }
 
-        VAddr GetAddressKey() const {
+        KProcessAddress GetAddressKey() const {
             return m_address_key;
         }
         bool GetIsKernelAddressKey() const {
@@ -812,7 +815,7 @@ public:
 
     private:
         LockWithPriorityInheritanceThreadTree m_tree{};
-        VAddr m_address_key{};
+        KProcessAddress m_address_key{};
         KThread* m_owner{};
         u32 m_waiter_count{};
         bool m_is_kernel_address_key{};
@@ -827,7 +830,8 @@ public:
     }
 
     void AddHeldLock(LockWithPriorityInheritanceInfo* lock_info);
-    LockWithPriorityInheritanceInfo* FindHeldLock(VAddr address_key, bool is_kernel_address_key);
+    LockWithPriorityInheritanceInfo* FindHeldLock(KProcessAddress address_key,
+                                                  bool is_kernel_address_key);
 
 private:
     using LockWithPriorityInheritanceInfoList =
@@ -839,11 +843,11 @@ private:
     KAffinityMask m_physical_affinity_mask{};
     u64 m_thread_id{};
     std::atomic<s64> m_cpu_time{};
-    VAddr m_address_key{};
+    KProcessAddress m_address_key{};
     KProcess* m_parent{};
-    VAddr m_kernel_stack_top{};
+    KVirtualAddress m_kernel_stack_top{};
     u32* m_light_ipc_data{};
-    VAddr m_tls_address{};
+    KProcessAddress m_tls_address{};
     KLightLock m_activity_pause_lock;
     s64 m_schedule_count{};
     s64 m_last_scheduled_tick{};
@@ -887,16 +891,16 @@ private:
 
     // For debugging
     std::vector<KSynchronizationObject*> m_wait_objects_for_debugging{};
-    VAddr m_mutex_wait_address_for_debugging{};
+    KProcessAddress m_mutex_wait_address_for_debugging{};
     ThreadWaitReasonForDebugging m_wait_reason_for_debugging{};
     uintptr_t m_argument{};
-    VAddr m_stack_top{};
+    KProcessAddress m_stack_top{};
 
 public:
     using ConditionVariableThreadTreeType = ConditionVariableThreadTree;
 
-    void SetConditionVariable(ConditionVariableThreadTree* tree, VAddr address, u64 cv_key,
-                              u32 value) {
+    void SetConditionVariable(ConditionVariableThreadTree* tree, KProcessAddress address,
+                              u64 cv_key, u32 value) {
         ASSERT(m_waiting_lock_info == nullptr);
         m_condvar_tree = tree;
         m_condvar_key = cv_key;
diff --git a/src/core/hle/kernel/k_thread_local_page.cpp b/src/core/hle/kernel/k_thread_local_page.cpp
index 136c874d4..9924dd8d6 100755
--- a/src/core/hle/kernel/k_thread_local_page.cpp
+++ b/src/core/hle/kernel/k_thread_local_page.cpp
@@ -37,7 +37,7 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) {
 
 Result KThreadLocalPage::Finalize() {
     // Get the physical address of the page.
-    const PAddr phys_addr = m_owner->PageTable().GetPhysicalAddr(m_virt_addr);
+    const KPhysicalAddress phys_addr = m_owner->PageTable().GetPhysicalAddr(m_virt_addr);
     ASSERT(phys_addr);
 
     // Unmap the page.
@@ -49,7 +49,7 @@ Result KThreadLocalPage::Finalize() {
     return ResultSuccess;
 }
 
-VAddr KThreadLocalPage::Reserve() {
+KProcessAddress KThreadLocalPage::Reserve() {
     for (size_t i = 0; i < m_is_region_free.size(); i++) {
         if (m_is_region_free[i]) {
             m_is_region_free[i] = false;
@@ -60,7 +60,7 @@ VAddr KThreadLocalPage::Reserve() {
     return 0;
 }
 
-void KThreadLocalPage::Release(VAddr addr) {
+void KThreadLocalPage::Release(KProcessAddress addr) {
     m_is_region_free[this->GetRegionIndex(addr)] = true;
 }
 
diff --git a/src/core/hle/kernel/k_thread_local_page.h b/src/core/hle/kernel/k_thread_local_page.h
index 41c9c8a76..cc01e200a 100755
--- a/src/core/hle/kernel/k_thread_local_page.h
+++ b/src/core/hle/kernel/k_thread_local_page.h
@@ -27,19 +27,20 @@ public:
     static_assert(RegionsPerPage > 0);
 
 public:
-    constexpr explicit KThreadLocalPage(KernelCore&, VAddr addr = {}) : m_virt_addr(addr) {
+    constexpr explicit KThreadLocalPage(KernelCore&, KProcessAddress addr = {})
+        : m_virt_addr(addr) {
         m_is_region_free.fill(true);
     }
 
-    constexpr VAddr GetAddress() const {
+    constexpr KProcessAddress GetAddress() const {
         return m_virt_addr;
     }
 
     Result Initialize(KernelCore& kernel, KProcess* process);
     Result Finalize();
 
-    VAddr Reserve();
-    void Release(VAddr addr);
+    KProcessAddress Reserve();
+    void Release(KProcessAddress addr);
 
     bool IsAllUsed() const {
         return std::ranges::all_of(m_is_region_free.begin(), m_is_region_free.end(),
@@ -60,7 +61,7 @@ public:
     }
 
 public:
-    using RedBlackKeyType = VAddr;
+    using RedBlackKeyType = KProcessAddress;
 
     static constexpr RedBlackKeyType GetRedBlackKey(const RedBlackKeyType& v) {
         return v;
@@ -72,8 +73,8 @@ public:
     template <typename T>
         requires(std::same_as<T, KThreadLocalPage> || std::same_as<T, RedBlackKeyType>)
     static constexpr int Compare(const T& lhs, const KThreadLocalPage& rhs) {
-        const VAddr lval = GetRedBlackKey(lhs);
-        const VAddr rval = GetRedBlackKey(rhs);
+        const KProcessAddress lval = GetRedBlackKey(lhs);
+        const KProcessAddress rval = GetRedBlackKey(rhs);
 
         if (lval < rval) {
             return -1;
@@ -85,22 +86,22 @@ public:
     }
 
 private:
-    constexpr VAddr GetRegionAddress(size_t i) const {
+    constexpr KProcessAddress GetRegionAddress(size_t i) const {
         return this->GetAddress() + i * Svc::ThreadLocalRegionSize;
     }
 
-    constexpr bool Contains(VAddr addr) const {
+    constexpr bool Contains(KProcessAddress addr) const {
         return this->GetAddress() <= addr && addr < this->GetAddress() + PageSize;
     }
 
-    constexpr size_t GetRegionIndex(VAddr addr) const {
-        ASSERT(Common::IsAligned(addr, Svc::ThreadLocalRegionSize));
+    constexpr size_t GetRegionIndex(KProcessAddress addr) const {
+        ASSERT(Common::IsAligned(GetInteger(addr), Svc::ThreadLocalRegionSize));
         ASSERT(this->Contains(addr));
         return (addr - this->GetAddress()) / Svc::ThreadLocalRegionSize;
     }
 
 private:
-    VAddr m_virt_addr{};
+    KProcessAddress m_virt_addr{};
     KProcess* m_owner{};
     KernelCore* m_kernel{};
     std::array<bool, RegionsPerPage> m_is_region_free{};
diff --git a/src/core/hle/kernel/k_transfer_memory.cpp b/src/core/hle/kernel/k_transfer_memory.cpp
index fc965bf51..7a5322f85 100755
--- a/src/core/hle/kernel/k_transfer_memory.cpp
+++ b/src/core/hle/kernel/k_transfer_memory.cpp
@@ -13,7 +13,7 @@ KTransferMemory::KTransferMemory(KernelCore& kernel)
 
 KTransferMemory::~KTransferMemory() = default;
 
-Result KTransferMemory::Initialize(VAddr address, std::size_t size,
+Result KTransferMemory::Initialize(KProcessAddress address, std::size_t size,
                                    Svc::MemoryPermission owner_perm) {
     // Set members.
     m_owner = GetCurrentProcessPointer(m_kernel);
diff --git a/src/core/hle/kernel/k_transfer_memory.h b/src/core/hle/kernel/k_transfer_memory.h
index c7c12c451..d3a1acb48 100755
--- a/src/core/hle/kernel/k_transfer_memory.h
+++ b/src/core/hle/kernel/k_transfer_memory.h
@@ -26,7 +26,7 @@ public:
     explicit KTransferMemory(KernelCore& kernel);
     ~KTransferMemory() override;
 
-    Result Initialize(VAddr address, std::size_t size, Svc::MemoryPermission owner_perm);
+    Result Initialize(KProcessAddress address, std::size_t size, Svc::MemoryPermission owner_perm);
 
     void Finalize() override;
 
@@ -44,7 +44,7 @@ public:
         return m_owner;
     }
 
-    VAddr GetSourceAddress() const {
+    KProcessAddress GetSourceAddress() const {
         return m_address;
     }
 
@@ -54,7 +54,7 @@ public:
 
 private:
     KProcess* m_owner{};
-    VAddr m_address{};
+    KProcessAddress m_address{};
     Svc::MemoryPermission m_owner_perm{};
     size_t m_size{};
     bool m_is_initialized{};
diff --git a/src/core/hle/kernel/k_typed_address.h b/src/core/hle/kernel/k_typed_address.h
new file mode 100755
index 000000000..d57535ba0
--- /dev/null
+++ b/src/core/hle/kernel/k_typed_address.h
@@ -0,0 +1,12 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/typed_address.h"
+
+namespace Kernel {
+
+using KPhysicalAddress = Common::PhysicalAddress;
+using KVirtualAddress = Common::VirtualAddress;
+using KProcessAddress = Common::ProcessAddress;
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index d46137b64..8605b8048 100755
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -271,9 +271,9 @@ struct KernelCore::Impl {
         system.CoreTiming().ScheduleLoopingEvent(time_interval, time_interval, preemption_event);
     }
 
-    void InitializeResourceManagers(KernelCore& kernel, VAddr address, size_t size) {
+    void InitializeResourceManagers(KernelCore& kernel, KVirtualAddress address, size_t size) {
         // Ensure that the buffer is suitable for our use.
-        ASSERT(Common::IsAligned(address, PageSize));
+        ASSERT(Common::IsAligned(GetInteger(address), PageSize));
         ASSERT(Common::IsAligned(size, PageSize));
 
         // Ensure that we have space for our reference counts.
@@ -462,29 +462,30 @@ struct KernelCore::Impl {
             KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceSize - 1);
 
         // Save start and end for ease of use.
-        const VAddr code_start_virt_addr = KernelVirtualAddressCodeBase;
-        const VAddr code_end_virt_addr = KernelVirtualAddressCodeEnd;
+        constexpr KVirtualAddress code_start_virt_addr = KernelVirtualAddressCodeBase;
+        constexpr KVirtualAddress code_end_virt_addr = KernelVirtualAddressCodeEnd;
 
         // Setup the containing kernel region.
         constexpr size_t KernelRegionSize = 1_GiB;
         constexpr size_t KernelRegionAlign = 1_GiB;
-        constexpr VAddr kernel_region_start =
-            Common::AlignDown(code_start_virt_addr, KernelRegionAlign);
+        constexpr KVirtualAddress kernel_region_start =
+            Common::AlignDown(GetInteger(code_start_virt_addr), KernelRegionAlign);
         size_t kernel_region_size = KernelRegionSize;
         if (!(kernel_region_start + KernelRegionSize - 1 <= KernelVirtualAddressSpaceLast)) {
-            kernel_region_size = KernelVirtualAddressSpaceEnd - kernel_region_start;
+            kernel_region_size = KernelVirtualAddressSpaceEnd - GetInteger(kernel_region_start);
         }
         ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
-            kernel_region_start, kernel_region_size, KMemoryRegionType_Kernel));
+            GetInteger(kernel_region_start), kernel_region_size, KMemoryRegionType_Kernel));
 
         // Setup the code region.
         constexpr size_t CodeRegionAlign = PageSize;
-        constexpr VAddr code_region_start =
-            Common::AlignDown(code_start_virt_addr, CodeRegionAlign);
-        constexpr VAddr code_region_end = Common::AlignUp(code_end_virt_addr, CodeRegionAlign);
+        constexpr KVirtualAddress code_region_start =
+            Common::AlignDown(GetInteger(code_start_virt_addr), CodeRegionAlign);
+        constexpr KVirtualAddress code_region_end =
+            Common::AlignUp(GetInteger(code_end_virt_addr), CodeRegionAlign);
         constexpr size_t code_region_size = code_region_end - code_region_start;
         ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
-            code_region_start, code_region_size, KMemoryRegionType_KernelCode));
+            GetInteger(code_region_start), code_region_size, KMemoryRegionType_KernelCode));
 
         // Setup board-specific device physical regions.
         Init::SetupDevicePhysicalMemoryRegions(*memory_layout);
@@ -520,11 +521,11 @@ struct KernelCore::Impl {
         ASSERT(misc_region_size > 0);
 
         // Setup the misc region.
-        const VAddr misc_region_start =
+        const KVirtualAddress misc_region_start =
             memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
                 misc_region_size, MiscRegionAlign, KMemoryRegionType_Kernel);
         ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
-            misc_region_start, misc_region_size, KMemoryRegionType_KernelMisc));
+            GetInteger(misc_region_start), misc_region_size, KMemoryRegionType_KernelMisc));
 
         // Determine if we'll use extra thread resources.
         const bool use_extra_resources = KSystemControl::Init::ShouldIncreaseThreadResourceLimit();
@@ -532,11 +533,11 @@ struct KernelCore::Impl {
         // Setup the stack region.
         constexpr size_t StackRegionSize = 14_MiB;
         constexpr size_t StackRegionAlign = KernelAslrAlignment;
-        const VAddr stack_region_start =
+        const KVirtualAddress stack_region_start =
             memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
                 StackRegionSize, StackRegionAlign, KMemoryRegionType_Kernel);
         ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
-            stack_region_start, StackRegionSize, KMemoryRegionType_KernelStack));
+            GetInteger(stack_region_start), StackRegionSize, KMemoryRegionType_KernelStack));
 
         // Determine the size of the resource region.
         const size_t resource_region_size =
@@ -548,29 +549,29 @@ struct KernelCore::Impl {
         ASSERT(slab_region_size <= resource_region_size);
 
         // Setup the slab region.
-        const PAddr code_start_phys_addr = KernelPhysicalAddressCodeBase;
-        const PAddr code_end_phys_addr = code_start_phys_addr + code_region_size;
-        const PAddr slab_start_phys_addr = code_end_phys_addr;
-        const PAddr slab_end_phys_addr = slab_start_phys_addr + slab_region_size;
+        const KPhysicalAddress code_start_phys_addr = KernelPhysicalAddressCodeBase;
+        const KPhysicalAddress code_end_phys_addr = code_start_phys_addr + code_region_size;
+        const KPhysicalAddress slab_start_phys_addr = code_end_phys_addr;
+        const KPhysicalAddress slab_end_phys_addr = slab_start_phys_addr + slab_region_size;
         constexpr size_t SlabRegionAlign = KernelAslrAlignment;
         const size_t slab_region_needed_size =
-            Common::AlignUp(code_end_phys_addr + slab_region_size, SlabRegionAlign) -
-            Common::AlignDown(code_end_phys_addr, SlabRegionAlign);
-        const VAddr slab_region_start =
+            Common::AlignUp(GetInteger(code_end_phys_addr) + slab_region_size, SlabRegionAlign) -
+            Common::AlignDown(GetInteger(code_end_phys_addr), SlabRegionAlign);
+        const KVirtualAddress slab_region_start =
             memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
                 slab_region_needed_size, SlabRegionAlign, KMemoryRegionType_Kernel) +
-            (code_end_phys_addr % SlabRegionAlign);
+            (GetInteger(code_end_phys_addr) % SlabRegionAlign);
         ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
-            slab_region_start, slab_region_size, KMemoryRegionType_KernelSlab));
+            GetInteger(slab_region_start), slab_region_size, KMemoryRegionType_KernelSlab));
 
         // Setup the temp region.
         constexpr size_t TempRegionSize = 128_MiB;
         constexpr size_t TempRegionAlign = KernelAslrAlignment;
-        const VAddr temp_region_start =
+        const KVirtualAddress temp_region_start =
             memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
                 TempRegionSize, TempRegionAlign, KMemoryRegionType_Kernel);
-        ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(temp_region_start, TempRegionSize,
-                                                                  KMemoryRegionType_KernelTemp));
+        ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
+            GetInteger(temp_region_start), TempRegionSize, KMemoryRegionType_KernelTemp));
 
         // Automatically map in devices that have auto-map attributes.
         for (auto& region : memory_layout->GetPhysicalMemoryRegionTree()) {
@@ -596,35 +597,37 @@ struct KernelCore::Impl {
             region.SetTypeAttribute(KMemoryRegionAttr_DidKernelMap);
 
             // Create a virtual pair region and insert it into the tree.
-            const PAddr map_phys_addr = Common::AlignDown(region.GetAddress(), PageSize);
+            const KPhysicalAddress map_phys_addr = Common::AlignDown(region.GetAddress(), PageSize);
             const size_t map_size =
-                Common::AlignUp(region.GetEndAddress(), PageSize) - map_phys_addr;
-            const VAddr map_virt_addr =
+                Common::AlignUp(region.GetEndAddress(), PageSize) - GetInteger(map_phys_addr);
+            const KVirtualAddress map_virt_addr =
                 memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard(
                     map_size, PageSize, KMemoryRegionType_KernelMisc, PageSize);
             ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
-                map_virt_addr, map_size, KMemoryRegionType_KernelMiscMappedDevice));
-            region.SetPairAddress(map_virt_addr + region.GetAddress() - map_phys_addr);
+                GetInteger(map_virt_addr), map_size, KMemoryRegionType_KernelMiscMappedDevice));
+            region.SetPairAddress(GetInteger(map_virt_addr) + region.GetAddress() -
+                                  GetInteger(map_phys_addr));
         }
 
         Init::SetupDramPhysicalMemoryRegions(*memory_layout);
 
         // Insert a physical region for the kernel code region.
         ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
-            code_start_phys_addr, code_region_size, KMemoryRegionType_DramKernelCode));
+            GetInteger(code_start_phys_addr), code_region_size, KMemoryRegionType_DramKernelCode));
 
         // Insert a physical region for the kernel slab region.
         ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
-            slab_start_phys_addr, slab_region_size, KMemoryRegionType_DramKernelSlab));
+            GetInteger(slab_start_phys_addr), slab_region_size, KMemoryRegionType_DramKernelSlab));
 
         // Determine size available for kernel page table heaps, requiring > 8 MB.
-        const PAddr resource_end_phys_addr = slab_start_phys_addr + resource_region_size;
+        const KPhysicalAddress resource_end_phys_addr = slab_start_phys_addr + resource_region_size;
         const size_t page_table_heap_size = resource_end_phys_addr - slab_end_phys_addr;
         ASSERT(page_table_heap_size / 4_MiB > 2);
 
         // Insert a physical region for the kernel page table heap region
         ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
-            slab_end_phys_addr, page_table_heap_size, KMemoryRegionType_DramKernelPtHeap));
+            GetInteger(slab_end_phys_addr), page_table_heap_size,
+            KMemoryRegionType_DramKernelPtHeap));
 
         // All DRAM regions that we haven't tagged by this point will be mapped under the linear
         // mapping. Tag them.
@@ -646,20 +649,21 @@ struct KernelCore::Impl {
 
         // Setup the linear mapping region.
         constexpr size_t LinearRegionAlign = 1_GiB;
-        const PAddr aligned_linear_phys_start =
+        const KPhysicalAddress aligned_linear_phys_start =
             Common::AlignDown(linear_extents.GetAddress(), LinearRegionAlign);
         const size_t linear_region_size =
             Common::AlignUp(linear_extents.GetEndAddress(), LinearRegionAlign) -
-            aligned_linear_phys_start;
-        const VAddr linear_region_start =
+            GetInteger(aligned_linear_phys_start);
+        const KVirtualAddress linear_region_start =
             memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard(
                 linear_region_size, LinearRegionAlign, KMemoryRegionType_None, LinearRegionAlign);
 
-        const u64 linear_region_phys_to_virt_diff = linear_region_start - aligned_linear_phys_start;
+        const u64 linear_region_phys_to_virt_diff =
+            GetInteger(linear_region_start) - GetInteger(aligned_linear_phys_start);
 
         // Map and create regions for all the linearly-mapped data.
         {
-            PAddr cur_phys_addr = 0;
+            KPhysicalAddress cur_phys_addr = 0;
             u64 cur_size = 0;
             for (auto& region : memory_layout->GetPhysicalMemoryRegionTree()) {
                 if (!region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) {
@@ -678,15 +682,16 @@ struct KernelCore::Impl {
                     cur_size = region.GetSize();
                 }
 
-                const VAddr region_virt_addr =
+                const KVirtualAddress region_virt_addr =
                     region.GetAddress() + linear_region_phys_to_virt_diff;
                 ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
-                    region_virt_addr, region.GetSize(),
+                    GetInteger(region_virt_addr), region.GetSize(),
                     GetTypeForVirtualLinearMapping(region.GetType())));
-                region.SetPairAddress(region_virt_addr);
+                region.SetPairAddress(GetInteger(region_virt_addr));
 
                 KMemoryRegion* virt_region =
-                    memory_layout->GetVirtualMemoryRegionTree().FindModifiable(region_virt_addr);
+                    memory_layout->GetVirtualMemoryRegionTree().FindModifiable(
+                        GetInteger(region_virt_addr));
                 ASSERT(virt_region != nullptr);
                 virt_region->SetPairAddress(region.GetAddress());
             }
@@ -694,10 +699,11 @@ struct KernelCore::Impl {
 
         // Insert regions for the initial page table region.
         ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
-            resource_end_phys_addr, KernelPageTableHeapSize, KMemoryRegionType_DramKernelInitPt));
+            GetInteger(resource_end_phys_addr), KernelPageTableHeapSize,
+            KMemoryRegionType_DramKernelInitPt));
         ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
-            resource_end_phys_addr + linear_region_phys_to_virt_diff, KernelPageTableHeapSize,
-            KMemoryRegionType_VirtualDramKernelInitPt));
+            GetInteger(resource_end_phys_addr) + linear_region_phys_to_virt_diff,
+            KernelPageTableHeapSize, KMemoryRegionType_VirtualDramKernelInitPt));
 
         // All linear-mapped DRAM regions that we haven't tagged by this point will be allocated to
         // some pool partition. Tag them.
@@ -969,12 +975,12 @@ void KernelCore::InvalidateAllInstructionCaches() {
     }
 }
 
-void KernelCore::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) {
+void KernelCore::InvalidateCpuInstructionCacheRange(KProcessAddress addr, std::size_t size) {
     for (auto& physical_core : impl->cores) {
         if (!physical_core->IsInitialized()) {
             continue;
         }
-        physical_core->ArmInterface().InvalidateCacheRange(addr, size);
+        physical_core->ArmInterface().InvalidateCacheRange(GetInteger(addr), size);
     }
 }
 
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index b9e3b3259..d035ced10 100755
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -14,6 +14,7 @@
 #include "core/hardware_properties.h"
 #include "core/hle/kernel/k_auto_object.h"
 #include "core/hle/kernel/k_slab_heap.h"
+#include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/svc_common.h"
 
 namespace Core {
@@ -185,7 +186,7 @@ public:
 
     void InvalidateAllInstructionCaches();
 
-    void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
+    void InvalidateCpuInstructionCacheRange(KProcessAddress addr, std::size_t size);
 
     /// Registers all kernel objects with the global emulation state, this is purely for tracking
     /// leaks after emulation has been shutdown.
diff --git a/src/core/hle/kernel/memory_types.h b/src/core/hle/kernel/memory_types.h
index 7d93fb484..688a7afa8 100755
--- a/src/core/hle/kernel/memory_types.h
+++ b/src/core/hle/kernel/memory_types.h
@@ -6,6 +6,7 @@
 #include <array>
 
 #include "common/common_types.h"
+#include "core/hle/kernel/k_typed_address.h"
 
 namespace Kernel {
 
@@ -14,7 +15,4 @@ constexpr std::size_t PageSize{1 << PageBits};
 
 using Page = std::array<u8, PageSize>;
 
-using KPhysicalAddress = PAddr;
-using KProcessAddress = VAddr;
-
 } // namespace Kernel
diff --git a/src/core/hle/kernel/svc/svc_address_arbiter.cpp b/src/core/hle/kernel/svc/svc_address_arbiter.cpp
index 22071731b..04cc5ea64 100755
--- a/src/core/hle/kernel/svc/svc_address_arbiter.cpp
+++ b/src/core/hle/kernel/svc/svc_address_arbiter.cpp
@@ -37,7 +37,7 @@ constexpr bool IsValidArbitrationType(Svc::ArbitrationType type) {
 } // namespace
 
 // Wait for an address (via Address Arbiter)
-Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value,
+Result WaitForAddress(Core::System& system, u64 address, ArbitrationType arb_type, s32 value,
                       s64 timeout_ns) {
     LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, arb_type=0x{:X}, value=0x{:X}, timeout_ns={}",
               address, arb_type, value, timeout_ns);
@@ -68,7 +68,7 @@ Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_t
 }
 
 // Signals to an address (via Address Arbiter)
-Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_type, s32 value,
+Result SignalToAddress(Core::System& system, u64 address, SignalType signal_type, s32 value,
                        s32 count) {
     LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, signal_type=0x{:X}, value=0x{:X}, count=0x{:X}",
               address, signal_type, value, count);
@@ -82,12 +82,12 @@ Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_ty
                  .SignalAddressArbiter(address, signal_type, value, count));
 }
 
-Result WaitForAddress64(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value,
+Result WaitForAddress64(Core::System& system, u64 address, ArbitrationType arb_type, s32 value,
                         s64 timeout_ns) {
     R_RETURN(WaitForAddress(system, address, arb_type, value, timeout_ns));
 }
 
-Result SignalToAddress64(Core::System& system, VAddr address, SignalType signal_type, s32 value,
+Result SignalToAddress64(Core::System& system, u64 address, SignalType signal_type, s32 value,
                          s32 count) {
     R_RETURN(SignalToAddress(system, address, signal_type, value, count));
 }
diff --git a/src/core/hle/kernel/svc/svc_code_memory.cpp b/src/core/hle/kernel/svc/svc_code_memory.cpp
index 43feab986..687baff82 100755
--- a/src/core/hle/kernel/svc/svc_code_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_code_memory.cpp
@@ -29,7 +29,7 @@ constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(MemoryPermission perm)
 
 } // namespace
 
-Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, uint64_t size) {
+Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t size) {
     LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, size=0x{:X}", address, size);
 
     // Get kernel instance.
@@ -64,7 +64,7 @@ Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, uint64
 }
 
 Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
-                         CodeMemoryOperation operation, VAddr address, uint64_t size,
+                         CodeMemoryOperation operation, u64 address, uint64_t size,
                          MemoryPermission perm) {
 
     LOG_TRACE(Kernel_SVC,
diff --git a/src/core/hle/kernel/svc/svc_condition_variable.cpp b/src/core/hle/kernel/svc/svc_condition_variable.cpp
index 648ed23d0..ca120d67e 100755
--- a/src/core/hle/kernel/svc/svc_condition_variable.cpp
+++ b/src/core/hle/kernel/svc/svc_condition_variable.cpp
@@ -11,7 +11,7 @@
 namespace Kernel::Svc {
 
 /// Wait process wide key atomic
-Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_key, u32 tag,
+Result WaitProcessWideKeyAtomic(Core::System& system, u64 address, u64 cv_key, u32 tag,
                                 s64 timeout_ns) {
     LOG_TRACE(Kernel_SVC, "called address={:X}, cv_key={:X}, tag=0x{:08X}, timeout_ns={}", address,
               cv_key, tag, timeout_ns);
@@ -43,7 +43,7 @@ Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_ke
 }
 
 /// Signal process wide key
-void SignalProcessWideKey(Core::System& system, VAddr cv_key, s32 count) {
+void SignalProcessWideKey(Core::System& system, u64 cv_key, s32 count) {
     LOG_TRACE(Kernel_SVC, "called, cv_key=0x{:X}, count=0x{:08X}", cv_key, count);
 
     // Signal the condition variable.
diff --git a/src/core/hle/kernel/svc/svc_debug_string.cpp b/src/core/hle/kernel/svc/svc_debug_string.cpp
index d4bf062d1..8771d2b01 100755
--- a/src/core/hle/kernel/svc/svc_debug_string.cpp
+++ b/src/core/hle/kernel/svc/svc_debug_string.cpp
@@ -8,7 +8,7 @@
 namespace Kernel::Svc {
 
 /// Used to output a message on a debug hardware unit - does nothing on a retail unit
-Result OutputDebugString(Core::System& system, VAddr address, u64 len) {
+Result OutputDebugString(Core::System& system, u64 address, u64 len) {
     R_SUCCEED_IF(len == 0);
 
     std::string str(len, '\0');
diff --git a/src/core/hle/kernel/svc/svc_exception.cpp b/src/core/hle/kernel/svc/svc_exception.cpp
index c2782908d..4ab5f471f 100755
--- a/src/core/hle/kernel/svc/svc_exception.cpp
+++ b/src/core/hle/kernel/svc/svc_exception.cpp
@@ -20,7 +20,7 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) {
     bool has_dumped_buffer{};
     std::vector<u8> debug_buffer;
 
-    const auto handle_debug_buffer = [&](VAddr addr, u64 sz) {
+    const auto handle_debug_buffer = [&](u64 addr, u64 sz) {
         if (sz == 0 || addr == 0 || has_dumped_buffer) {
             return;
         }
diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp
index 04b6d6964..2b2c878b5 100755
--- a/src/core/hle/kernel/svc/svc_info.cpp
+++ b/src/core/hle/kernel/svc/svc_info.cpp
@@ -54,7 +54,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
             R_SUCCEED();
 
         case InfoType::AliasRegionAddress:
-            *result = process->PageTable().GetAliasRegionStart();
+            *result = GetInteger(process->PageTable().GetAliasRegionStart());
             R_SUCCEED();
 
         case InfoType::AliasRegionSize:
@@ -62,7 +62,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
             R_SUCCEED();
 
         case InfoType::HeapRegionAddress:
-            *result = process->PageTable().GetHeapRegionStart();
+            *result = GetInteger(process->PageTable().GetHeapRegionStart());
             R_SUCCEED();
 
         case InfoType::HeapRegionSize:
@@ -70,7 +70,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
             R_SUCCEED();
 
         case InfoType::AslrRegionAddress:
-            *result = process->PageTable().GetAliasCodeRegionStart();
+            *result = GetInteger(process->PageTable().GetAliasCodeRegionStart());
             R_SUCCEED();
 
         case InfoType::AslrRegionSize:
@@ -78,7 +78,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
             R_SUCCEED();
 
         case InfoType::StackRegionAddress:
-            *result = process->PageTable().GetStackRegionStart();
+            *result = GetInteger(process->PageTable().GetStackRegionStart());
             R_SUCCEED();
 
         case InfoType::StackRegionSize:
@@ -107,7 +107,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
             R_SUCCEED();
 
         case InfoType::UserExceptionContextAddress:
-            *result = process->GetProcessLocalRegionAddress();
+            *result = GetInteger(process->GetProcessLocalRegionAddress());
             R_SUCCEED();
 
         case InfoType::TotalNonSystemMemorySize:
diff --git a/src/core/hle/kernel/svc/svc_lock.cpp b/src/core/hle/kernel/svc/svc_lock.cpp
index 3681279d6..1d7bc4246 100755
--- a/src/core/hle/kernel/svc/svc_lock.cpp
+++ b/src/core/hle/kernel/svc/svc_lock.cpp
@@ -9,7 +9,7 @@
 namespace Kernel::Svc {
 
 /// Attempts to locks a mutex
-Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, u32 tag) {
+Result ArbitrateLock(Core::System& system, Handle thread_handle, u64 address, u32 tag) {
     LOG_TRACE(Kernel_SVC, "called thread_handle=0x{:08X}, address=0x{:X}, tag=0x{:08X}",
               thread_handle, address, tag);
 
@@ -21,7 +21,7 @@ Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address,
 }
 
 /// Unlock a mutex
-Result ArbitrateUnlock(Core::System& system, VAddr address) {
+Result ArbitrateUnlock(Core::System& system, u64 address) {
     LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address);
 
     // Validate the input address.
diff --git a/src/core/hle/kernel/svc/svc_memory.cpp b/src/core/hle/kernel/svc/svc_memory.cpp
index 4db25a3b7..5dcb7f045 100755
--- a/src/core/hle/kernel/svc/svc_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_memory.cpp
@@ -22,15 +22,14 @@ constexpr bool IsValidSetMemoryPermission(MemoryPermission perm) {
 // Checks if address + size is greater than the given address
 // This can return false if the size causes an overflow of a 64-bit type
 // or if the given size is zero.
-constexpr bool IsValidAddressRange(VAddr address, u64 size) {
+constexpr bool IsValidAddressRange(u64 address, u64 size) {
     return address + size > address;
 }
 
 // Helper function that performs the common sanity checks for svcMapMemory
 // and svcUnmapMemory. This is doable, as both functions perform their sanitizing
 // in the same order.
-Result MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAddr src_addr,
-                                  u64 size) {
+Result MapUnmapMemorySanityChecks(const KPageTable& manager, u64 dst_addr, u64 src_addr, u64 size) {
     if (!Common::Is4KBAligned(dst_addr)) {
         LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr);
         R_THROW(ResultInvalidAddress);
@@ -99,7 +98,7 @@ Result MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAd
 
 } // namespace
 
-Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, MemoryPermission perm) {
+Result SetMemoryPermission(Core::System& system, u64 address, u64 size, MemoryPermission perm) {
     LOG_DEBUG(Kernel_SVC, "called, address=0x{:016X}, size=0x{:X}, perm=0x{:08X", address, size,
               perm);
 
@@ -120,7 +119,7 @@ Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, Memory
     R_RETURN(page_table.SetMemoryPermission(address, size, perm));
 }
 
-Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, u32 attr) {
+Result SetMemoryAttribute(Core::System& system, u64 address, u64 size, u32 mask, u32 attr) {
     LOG_DEBUG(Kernel_SVC,
               "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address,
               size, mask, attr);
@@ -145,7 +144,7 @@ Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mas
 }
 
 /// Maps a memory range into a different range.
-Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
+Result MapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) {
     LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
               src_addr, size);
 
@@ -160,7 +159,7 @@ Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size)
 }
 
 /// Unmaps a region that was previously mapped with svcMapMemory
-Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
+Result UnmapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) {
     LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
               src_addr, size);
 
diff --git a/src/core/hle/kernel/svc/svc_physical_memory.cpp b/src/core/hle/kernel/svc/svc_physical_memory.cpp
index 63196e1ed..c2fbfb59a 100755
--- a/src/core/hle/kernel/svc/svc_physical_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_physical_memory.cpp
@@ -8,7 +8,7 @@
 namespace Kernel::Svc {
 
 /// Set the process heap to a given Size. It can both extend and shrink the heap.
-Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size) {
+Result SetHeapSize(Core::System& system, u64* out_address, u64 size) {
     LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", size);
 
     // Validate size.
@@ -20,7 +20,7 @@ Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size) {
 }
 
 /// Maps memory at a desired address
-Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
+Result MapPhysicalMemory(Core::System& system, u64 addr, u64 size) {
     LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
 
     if (!Common::Is4KBAligned(addr)) {
@@ -69,7 +69,7 @@ Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
 }
 
 /// Unmaps memory previously mapped via MapPhysicalMemory
-Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
+Result UnmapPhysicalMemory(Core::System& system, u64 addr, u64 size) {
     LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
 
     if (!Common::Is4KBAligned(addr)) {
diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp
index 0b5556bc4..c6eb70422 100755
--- a/src/core/hle/kernel/svc/svc_port.cpp
+++ b/src/core/hle/kernel/svc/svc_port.cpp
@@ -12,7 +12,7 @@
 
 namespace Kernel::Svc {
 
-Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr user_name) {
+Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) {
     // Copy the provided name from user memory to kernel memory.
     auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax);
 
diff --git a/src/core/hle/kernel/svc/svc_process.cpp b/src/core/hle/kernel/svc/svc_process.cpp
index b538c37e7..3c3579947 100755
--- a/src/core/hle/kernel/svc/svc_process.cpp
+++ b/src/core/hle/kernel/svc/svc_process.cpp
@@ -50,7 +50,7 @@ Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) {
     R_SUCCEED();
 }
 
-Result GetProcessList(Core::System& system, s32* out_num_processes, VAddr out_process_ids,
+Result GetProcessList(Core::System& system, s32* out_num_processes, u64 out_process_ids,
                       int32_t out_process_ids_size) {
     LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}",
               out_process_ids, out_process_ids_size);
diff --git a/src/core/hle/kernel/svc/svc_process_memory.cpp b/src/core/hle/kernel/svc/svc_process_memory.cpp
index f9210ca1e..aee0f2f36 100755
--- a/src/core/hle/kernel/svc/svc_process_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_process_memory.cpp
@@ -8,7 +8,7 @@
 namespace Kernel::Svc {
 namespace {
 
-constexpr bool IsValidAddressRange(VAddr address, u64 size) {
+constexpr bool IsValidAddressRange(u64 address, u64 size) {
     return address + size > address;
 }
 
@@ -26,7 +26,7 @@ constexpr bool IsValidProcessMemoryPermission(Svc::MemoryPermission perm) {
 
 } // namespace
 
-Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, VAddr address,
+Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, u64 address,
                                   u64 size, Svc::MemoryPermission perm) {
     LOG_TRACE(Kernel_SVC,
               "called, process_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
@@ -56,8 +56,8 @@ Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, V
     R_RETURN(page_table.SetProcessMemoryPermission(address, size, perm));
 }
 
-Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle,
-                        VAddr src_address, u64 size) {
+Result MapProcessMemory(Core::System& system, u64 dst_address, Handle process_handle,
+                        u64 src_address, u64 size) {
     LOG_TRACE(Kernel_SVC,
               "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}",
               dst_address, process_handle, src_address, size);
@@ -97,8 +97,8 @@ Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_
                                  KMemoryPermission::UserReadWrite));
 }
 
-Result UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle,
-                          VAddr src_address, u64 size) {
+Result UnmapProcessMemory(Core::System& system, u64 dst_address, Handle process_handle,
+                          u64 src_address, u64 size) {
     LOG_TRACE(Kernel_SVC,
               "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}",
               dst_address, process_handle, src_address, size);
diff --git a/src/core/hle/kernel/svc/svc_query_memory.cpp b/src/core/hle/kernel/svc/svc_query_memory.cpp
index 457ebf950..5db5611f0 100755
--- a/src/core/hle/kernel/svc/svc_query_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_query_memory.cpp
@@ -8,7 +8,7 @@
 namespace Kernel::Svc {
 
 Result QueryMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info,
-                   VAddr query_address) {
+                   u64 query_address) {
     LOG_TRACE(Kernel_SVC,
               "called, out_memory_info=0x{:016X}, "
               "query_address=0x{:016X}",
diff --git a/src/core/hle/kernel/svc/svc_shared_memory.cpp b/src/core/hle/kernel/svc/svc_shared_memory.cpp
index 40d878f17..a698596aa 100755
--- a/src/core/hle/kernel/svc/svc_shared_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_shared_memory.cpp
@@ -26,7 +26,7 @@ constexpr bool IsValidSharedMemoryPermission(MemoryPermission perm) {
 
 } // namespace
 
-Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size,
+Result MapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, u64 size,
                        Svc::MemoryPermission map_perm) {
     LOG_TRACE(Kernel_SVC,
               "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
@@ -64,7 +64,7 @@ Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address,
     R_RETURN(shmem->Map(process, address, size, map_perm));
 }
 
-Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size) {
+Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, u64 size) {
     // Validate the address/size.
     R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
     R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp
index 660b45c23..e490a13ae 100755
--- a/src/core/hle/kernel/svc/svc_synchronization.cpp
+++ b/src/core/hle/kernel/svc/svc_synchronization.cpp
@@ -80,7 +80,7 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons
 }
 
 /// Wait for the given handles to synchronize, timeout after the specified nanoseconds
-Result WaitSynchronization(Core::System& system, int32_t* out_index, VAddr user_handles,
+Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_handles,
                            int32_t num_handles, int64_t timeout_ns) {
     LOG_TRACE(Kernel_SVC, "called user_handles={:#x}, num_handles={}, timeout_ns={}", user_handles,
               num_handles, timeout_ns);
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp
index 50991fb62..0be4858a2 100755
--- a/src/core/hle/kernel/svc/svc_thread.cpp
+++ b/src/core/hle/kernel/svc/svc_thread.cpp
@@ -19,8 +19,8 @@ constexpr bool IsValidVirtualCoreId(int32_t core_id) {
 } // Anonymous namespace
 
 /// Creates a new thread
-Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg,
-                    VAddr stack_bottom, s32 priority, s32 core_id) {
+Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u64 arg,
+                    u64 stack_bottom, s32 priority, s32 core_id) {
     LOG_DEBUG(Kernel_SVC,
               "called entry_point=0x{:08X}, arg=0x{:08X}, stack_bottom=0x{:08X}, "
               "priority=0x{:08X}, core_id=0x{:08X}",
@@ -129,7 +129,7 @@ void SleepThread(Core::System& system, s64 nanoseconds) {
 }
 
 /// Gets the thread context
-Result GetThreadContext3(Core::System& system, VAddr out_context, Handle thread_handle) {
+Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_handle) {
     LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context,
               thread_handle);
 
@@ -217,7 +217,7 @@ Result SetThreadPriority(Core::System& system, Handle thread_handle, s32 priorit
     R_SUCCEED();
 }
 
-Result GetThreadList(Core::System& system, s32* out_num_threads, VAddr out_thread_ids,
+Result GetThreadList(Core::System& system, s32* out_num_threads, u64 out_thread_ids,
                      s32 out_thread_ids_size, Handle debug_handle) {
     // TODO: Handle this case when debug events are supported.
     UNIMPLEMENTED_IF(debug_handle != InvalidHandle);
diff --git a/src/core/hle/kernel/svc/svc_transfer_memory.cpp b/src/core/hle/kernel/svc/svc_transfer_memory.cpp
index 394f06728..82d469a37 100755
--- a/src/core/hle/kernel/svc/svc_transfer_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_transfer_memory.cpp
@@ -25,7 +25,7 @@ constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) {
 } // Anonymous namespace
 
 /// Creates a TransferMemory object
-Result CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size,
+Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64 size,
                             MemoryPermission map_perm) {
     auto& kernel = system.Kernel();
 
diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h
index a3d8d891c..279fa839d 100755
--- a/src/core/hle/kernel/svc_types.h
+++ b/src/core/hle/kernel/svc_types.h
@@ -253,7 +253,7 @@ struct LastThreadContext {
 };
 
 struct PhysicalMemoryInfo {
-    PAddr physical_address;
+    u64 physical_address;
     u64 virtual_address;
     u64 size;
 };
@@ -359,7 +359,7 @@ struct LastThreadContext {
 };
 
 struct PhysicalMemoryInfo {
-    PAddr physical_address;
+    u64 physical_address;
     u32 virtual_address;
     u32 size;
 };
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
index f1b26aa84..f899a1160 100755
--- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
@@ -63,7 +63,7 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti
     system.Memory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo));
 }
 
-void Controller_ConsoleSixAxis::SetTransferMemoryAddress(VAddr t_mem) {
+void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
     transfer_memory = t_mem;
 }
 
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/console_sixaxis.h
index 4d9cc5f7e..de9b6bbcb 100755
--- a/src/core/hle/service/hid/controllers/console_sixaxis.h
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.h
@@ -5,8 +5,8 @@
 
 #include <array>
 
-#include "common/common_types.h"
 #include "common/quaternion.h"
+#include "common/typed_address.h"
 #include "core/hle/service/hid/controllers/controller_base.h"
 #include "core/hle/service/hid/ring_lifo.h"
 
@@ -34,7 +34,7 @@ public:
     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
 
     // Called on InitializeSevenSixAxisSensor
-    void SetTransferMemoryAddress(VAddr t_mem);
+    void SetTransferMemoryAddress(Common::ProcessAddress t_mem);
 
     // Called on ResetSevenSixAxisSensorTimestamp
     void ResetTimestamp();
@@ -66,7 +66,7 @@ private:
     static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size");
 
     SevenSixAxisState next_seven_sixaxis_state{};
-    VAddr transfer_memory{};
+    Common::ProcessAddress transfer_memory{};
     ConsoleSharedMemory* shared_memory = nullptr;
     Core::HID::EmulatedConsole* console = nullptr;
 
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp
index b4789f5a6..c5b05779b 100755
--- a/src/core/hle/service/hid/controllers/palma.cpp
+++ b/src/core/hle/service/hid/controllers/palma.cpp
@@ -152,7 +152,7 @@ Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandl
 }
 
 Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
-                                             VAddr t_mem, u64 size) {
+                                             Common::ProcessAddress t_mem, u64 size) {
     if (handle.npad_id != active_handle.npad_id) {
         return InvalidPalmaHandle;
     }
diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h
index ff8981267..61af6de20 100755
--- a/src/core/hle/service/hid/controllers/palma.h
+++ b/src/core/hle/service/hid/controllers/palma.h
@@ -5,7 +5,7 @@
 
 #include <array>
 #include "common/common_funcs.h"
-#include "common/common_types.h"
+#include "common/typed_address.h"
 #include "core/hle/service/hid/controllers/controller_base.h"
 #include "core/hle/service/hid/errors.h"
 
@@ -125,8 +125,8 @@ public:
     Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle);
     Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle);
     Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown);
-    Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, VAddr t_mem,
-                               u64 size);
+    Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
+                               Common::ProcessAddress t_mem, u64 size);
     Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
                                                  s32 database_id_version_);
     Result GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle);
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.cpp b/src/core/hle/service/hid/hidbus/hidbus_base.cpp
index c66ab8047..2a3aa8cd8 100755
--- a/src/core/hle/service/hid/hidbus/hidbus_base.cpp
+++ b/src/core/hle/service/hid/hidbus/hidbus_base.cpp
@@ -59,7 +59,7 @@ void HidbusBase::DisablePollingMode() {
     polling_mode_enabled = false;
 }
 
-void HidbusBase::SetTransferMemoryAddress(VAddr t_mem) {
+void HidbusBase::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
     transfer_memory = t_mem;
 }
 
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.h b/src/core/hle/service/hid/hidbus/hidbus_base.h
index 98d65c5d8..1464bbda7 100755
--- a/src/core/hle/service/hid/hidbus/hidbus_base.h
+++ b/src/core/hle/service/hid/hidbus/hidbus_base.h
@@ -5,7 +5,7 @@
 
 #include <array>
 #include <span>
-#include "common/common_types.h"
+#include "common/typed_address.h"
 #include "core/hle/result.h"
 
 namespace Core {
@@ -138,7 +138,7 @@ public:
     void DisablePollingMode();
 
     // Called on EnableJoyPollingReceiveMode
-    void SetTransferMemoryAddress(VAddr t_mem);
+    void SetTransferMemoryAddress(Common::ProcessAddress t_mem);
 
     Kernel::KReadableEvent& GetSendCommandAsycEvent() const;
 
@@ -174,7 +174,7 @@ protected:
     JoyEnableSixAxisDataAccessor enable_sixaxis_data{};
     ButtonOnlyPollingDataAccessor button_only_data{};
 
-    VAddr transfer_memory{};
+    Common::ProcessAddress transfer_memory{};
 
     Core::System& system;
     Kernel::KEvent* send_command_async_event;
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
index 467d8eab9..d78f8ec9a 100755
--- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
+++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
@@ -140,7 +140,7 @@ void ImageTransferProcessor::SetConfig(
     npad_device->SetCameraFormat(current_config.origin_format);
 }
 
-void ImageTransferProcessor::SetTransferMemoryAddress(VAddr t_mem) {
+void ImageTransferProcessor::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
     transfer_memory = t_mem;
 }
 
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.h b/src/core/hle/service/hid/irsensor/image_transfer_processor.h
index b6913efd5..ca0f607ee 100755
--- a/src/core/hle/service/hid/irsensor/image_transfer_processor.h
+++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.h
@@ -3,7 +3,7 @@
 
 #pragma once
 
-#include "common/common_types.h"
+#include "common/typed_address.h"
 #include "core/hid/irs_types.h"
 #include "core/hle/service/hid/irsensor/processor_base.h"
 
@@ -37,7 +37,7 @@ public:
     void SetConfig(Core::IrSensor::PackedImageTransferProcessorExConfig config);
 
     // Transfer memory where the image data will be stored
-    void SetTransferMemoryAddress(VAddr t_mem);
+    void SetTransferMemoryAddress(Common::ProcessAddress t_mem);
 
     Core::IrSensor::ImageTransferProcessorState GetState(std::vector<u8>& data) const;
 
@@ -72,6 +72,6 @@ private:
     int callback_key{};
 
     Core::System& system;
-    VAddr transfer_memory{};
+    Common::ProcessAddress transfer_memory{};
 };
 } // namespace Service::IRS
diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp
index 0d3afb89a..54f8ebe95 100755
--- a/src/core/hle/service/jit/jit.cpp
+++ b/src/core/hle/service/jit/jit.cpp
@@ -195,7 +195,7 @@ public:
         }
 
         // Set up the configuration with the required TransferMemory address
-        configuration.transfer_memory.offset = tmem->GetSourceAddress();
+        configuration.transfer_memory.offset = GetInteger(tmem->GetSourceAddress());
         configuration.transfer_memory.size = tmem_size;
 
         // Gather up all the callbacks from the loaded plugin
@@ -383,12 +383,12 @@ public:
         }
 
         const CodeRange user_rx{
-            .offset = rx_mem->GetSourceAddress(),
+            .offset = GetInteger(rx_mem->GetSourceAddress()),
             .size = parameters.rx_size,
         };
 
         const CodeRange user_ro{
-            .offset = ro_mem->GetSourceAddress(),
+            .offset = GetInteger(ro_mem->GetSourceAddress()),
             .size = parameters.ro_size,
         };
 
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 7d1ab9fd8..473b30df7 100755
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -337,7 +337,7 @@ public:
 
         bool succeeded = false;
         const auto map_region_end =
-            page_table.GetAliasCodeRegionStart() + page_table.GetAliasCodeRegionSize();
+            GetInteger(page_table.GetAliasCodeRegionStart()) + page_table.GetAliasCodeRegionSize();
         while (current_map_addr < map_region_end) {
             if (is_region_available(current_map_addr)) {
                 succeeded = true;
@@ -642,7 +642,8 @@ public:
         LOG_WARNING(Service_LDR, "(STUBBED) called");
 
         initialized = true;
-        current_map_addr = system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart();
+        current_map_addr =
+            GetInteger(system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart());
 
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(ResultSuccess);
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index 7fece7cb1..bfbd87a95 100755
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -153,7 +153,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
 
     // Load NSO modules
     modules.clear();
-    const VAddr base_address{process.PageTable().GetCodeRegionStart()};
+    const VAddr base_address{GetInteger(process.PageTable().GetCodeRegionStart())};
     VAddr next_load_addr{base_address};
     const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(),
                                    system.GetContentProvider()};
diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp
index 8712999da..aacdc6c26 100755
--- a/src/core/loader/kip.cpp
+++ b/src/core/loader/kip.cpp
@@ -96,7 +96,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
     }
 
     codeset.memory = std::move(program_image);
-    const VAddr base_address = process.PageTable().GetCodeRegionStart();
+    const VAddr base_address = GetInteger(process.PageTable().GetCodeRegionStart());
     process.LoadModule(std::move(codeset), base_address);
 
     LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address);
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index e80907eb9..dc949f5dd 100755
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -167,7 +167,7 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::S
     modules.clear();
 
     // Load module
-    const VAddr base_address = process.PageTable().GetCodeRegionStart();
+    const VAddr base_address = GetInteger(process.PageTable().GetCodeRegionStart());
     if (!LoadModule(process, system, *file, base_address, true, true)) {
         return {ResultStatus::ErrorLoadingNSO, {}};
     }
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index a2c695620..69be56dec 100755
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -35,31 +35,35 @@ struct Memory::Impl {
         system.ArmInterface(core_id).PageTableChanged(*current_page_table, address_space_width);
     }
 
-    void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) {
+    void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
+                         Common::PhysicalAddress target) {
         ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
-        ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", base);
-        ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}", target);
+        ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base));
+        ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}",
+                   GetInteger(target));
         MapPages(page_table, base / YUZU_PAGESIZE, size / YUZU_PAGESIZE, target,
                  Common::PageType::Memory);
 
         if (Settings::IsFastmemEnabled()) {
-            system.DeviceMemory().buffer.Map(base, target - DramMemoryMap::Base, size);
+            system.DeviceMemory().buffer.Map(GetInteger(base),
+                                             GetInteger(target) - DramMemoryMap::Base, size);
         }
     }
 
-    void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
+    void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size) {
         ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
-        ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", base);
+        ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base));
         MapPages(page_table, base / YUZU_PAGESIZE, size / YUZU_PAGESIZE, 0,
                  Common::PageType::Unmapped);
 
         if (Settings::IsFastmemEnabled()) {
-            system.DeviceMemory().buffer.Unmap(base, size);
+            system.DeviceMemory().buffer.Unmap(GetInteger(base), size);
         }
     }
 
-    [[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(VAddr vaddr) const {
-        const PAddr paddr{current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]};
+    [[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(u64 vaddr) const {
+        const Common::PhysicalAddress paddr{
+            current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]};
 
         if (!paddr) {
             return {};
@@ -68,8 +72,9 @@ struct Memory::Impl {
         return system.DeviceMemory().GetPointer<u8>(paddr) + vaddr;
     }
 
-    [[nodiscard]] u8* GetPointerFromDebugMemory(VAddr vaddr) const {
-        const PAddr paddr{current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]};
+    [[nodiscard]] u8* GetPointerFromDebugMemory(u64 vaddr) const {
+        const Common::PhysicalAddress paddr{
+            current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]};
 
         if (paddr == 0) {
             return {};
@@ -78,11 +83,11 @@ struct Memory::Impl {
         return system.DeviceMemory().GetPointer<u8>(paddr) + vaddr;
     }
 
-    u8 Read8(const VAddr addr) {
+    u8 Read8(const Common::ProcessAddress addr) {
         return Read<u8>(addr);
     }
 
-    u16 Read16(const VAddr addr) {
+    u16 Read16(const Common::ProcessAddress addr) {
         if ((addr & 1) == 0) {
             return Read<u16_le>(addr);
         } else {
@@ -92,7 +97,7 @@ struct Memory::Impl {
         }
     }
 
-    u32 Read32(const VAddr addr) {
+    u32 Read32(const Common::ProcessAddress addr) {
         if ((addr & 3) == 0) {
             return Read<u32_le>(addr);
         } else {
@@ -102,7 +107,7 @@ struct Memory::Impl {
         }
     }
 
-    u64 Read64(const VAddr addr) {
+    u64 Read64(const Common::ProcessAddress addr) {
         if ((addr & 7) == 0) {
             return Read<u64_le>(addr);
         } else {
@@ -112,11 +117,11 @@ struct Memory::Impl {
         }
     }
 
-    void Write8(const VAddr addr, const u8 data) {
+    void Write8(const Common::ProcessAddress addr, const u8 data) {
         Write<u8>(addr, data);
     }
 
-    void Write16(const VAddr addr, const u16 data) {
+    void Write16(const Common::ProcessAddress addr, const u16 data) {
         if ((addr & 1) == 0) {
             Write<u16_le>(addr, data);
         } else {
@@ -125,7 +130,7 @@ struct Memory::Impl {
         }
     }
 
-    void Write32(const VAddr addr, const u32 data) {
+    void Write32(const Common::ProcessAddress addr, const u32 data) {
         if ((addr & 3) == 0) {
             Write<u32_le>(addr, data);
         } else {
@@ -134,7 +139,7 @@ struct Memory::Impl {
         }
     }
 
-    void Write64(const VAddr addr, const u64 data) {
+    void Write64(const Common::ProcessAddress addr, const u64 data) {
         if ((addr & 7) == 0) {
             Write<u64_le>(addr, data);
         } else {
@@ -143,23 +148,23 @@ struct Memory::Impl {
         }
     }
 
-    bool WriteExclusive8(const VAddr addr, const u8 data, const u8 expected) {
+    bool WriteExclusive8(const Common::ProcessAddress addr, const u8 data, const u8 expected) {
         return WriteExclusive<u8>(addr, data, expected);
     }
 
-    bool WriteExclusive16(const VAddr addr, const u16 data, const u16 expected) {
+    bool WriteExclusive16(const Common::ProcessAddress addr, const u16 data, const u16 expected) {
         return WriteExclusive<u16_le>(addr, data, expected);
     }
 
-    bool WriteExclusive32(const VAddr addr, const u32 data, const u32 expected) {
+    bool WriteExclusive32(const Common::ProcessAddress addr, const u32 data, const u32 expected) {
         return WriteExclusive<u32_le>(addr, data, expected);
     }
 
-    bool WriteExclusive64(const VAddr addr, const u64 data, const u64 expected) {
+    bool WriteExclusive64(const Common::ProcessAddress addr, const u64 data, const u64 expected) {
         return WriteExclusive<u64_le>(addr, data, expected);
     }
 
-    std::string ReadCString(VAddr vaddr, std::size_t max_length) {
+    std::string ReadCString(Common::ProcessAddress vaddr, std::size_t max_length) {
         std::string string;
         string.reserve(max_length);
         for (std::size_t i = 0; i < max_length; ++i) {
@@ -174,8 +179,9 @@ struct Memory::Impl {
         return string;
     }
 
-    void WalkBlock(const Kernel::KProcess& process, const VAddr addr, const std::size_t size,
-                   auto on_unmapped, auto on_memory, auto on_rasterizer, auto increment) {
+    void WalkBlock(const Kernel::KProcess& process, const Common::ProcessAddress addr,
+                   const std::size_t size, auto on_unmapped, auto on_memory, auto on_rasterizer,
+                   auto increment) {
         const auto& page_table = process.PageTable().PageTableImpl();
         std::size_t remaining_size = size;
         std::size_t page_index = addr >> YUZU_PAGEBITS;
@@ -185,7 +191,7 @@ struct Memory::Impl {
             const std::size_t copy_amount =
                 std::min(static_cast<std::size_t>(YUZU_PAGESIZE) - page_offset, remaining_size);
             const auto current_vaddr =
-                static_cast<VAddr>((page_index << YUZU_PAGEBITS) + page_offset);
+                static_cast<u64>((page_index << YUZU_PAGEBITS) + page_offset);
 
             const auto [pointer, type] = page_table.pointers[page_index].PointerType();
             switch (type) {
@@ -220,24 +226,24 @@ struct Memory::Impl {
     }
 
     template <bool UNSAFE>
-    void ReadBlockImpl(const Kernel::KProcess& process, const VAddr src_addr, void* dest_buffer,
-                       const std::size_t size) {
+    void ReadBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress src_addr,
+                       void* dest_buffer, const std::size_t size) {
         WalkBlock(
             process, src_addr, size,
             [src_addr, size, &dest_buffer](const std::size_t copy_amount,
-                                           const VAddr current_vaddr) {
+                                           const Common::ProcessAddress current_vaddr) {
                 LOG_ERROR(HW_Memory,
                           "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
-                          current_vaddr, src_addr, size);
+                          GetInteger(current_vaddr), GetInteger(src_addr), size);
                 std::memset(dest_buffer, 0, copy_amount);
             },
             [&](const std::size_t copy_amount, const u8* const src_ptr) {
                 std::memcpy(dest_buffer, src_ptr, copy_amount);
             },
-            [&](const VAddr current_vaddr, const std::size_t copy_amount,
+            [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
                 const u8* const host_ptr) {
                 if constexpr (!UNSAFE) {
-                    system.GPU().FlushRegion(current_vaddr, copy_amount);
+                    system.GPU().FlushRegion(GetInteger(current_vaddr), copy_amount);
                 }
                 std::memcpy(dest_buffer, host_ptr, copy_amount);
             },
@@ -246,30 +252,34 @@ struct Memory::Impl {
             });
     }
 
-    void ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
+    void ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
+                   const std::size_t size) {
         ReadBlockImpl<false>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
     }
 
-    void ReadBlockUnsafe(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
+    void ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
+                         const std::size_t size) {
         ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
     }
 
     template <bool UNSAFE>
-    void WriteBlockImpl(const Kernel::KProcess& process, const VAddr dest_addr,
+    void WriteBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr,
                         const void* src_buffer, const std::size_t size) {
         WalkBlock(
             process, dest_addr, size,
-            [dest_addr, size](const std::size_t copy_amount, const VAddr current_vaddr) {
+            [dest_addr, size](const std::size_t copy_amount,
+                              const Common::ProcessAddress current_vaddr) {
                 LOG_ERROR(HW_Memory,
                           "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
-                          current_vaddr, dest_addr, size);
+                          GetInteger(current_vaddr), GetInteger(dest_addr), size);
             },
             [&](const std::size_t copy_amount, u8* const dest_ptr) {
                 std::memcpy(dest_ptr, src_buffer, copy_amount);
             },
-            [&](const VAddr current_vaddr, const std::size_t copy_amount, u8* const host_ptr) {
+            [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
+                u8* const host_ptr) {
                 if constexpr (!UNSAFE) {
-                    system.GPU().InvalidateRegion(current_vaddr, copy_amount);
+                    system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount);
                 }
                 std::memcpy(host_ptr, src_buffer, copy_amount);
             },
@@ -278,71 +288,77 @@ struct Memory::Impl {
             });
     }
 
-    void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t size) {
+    void WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
+                    const std::size_t size) {
         WriteBlockImpl<false>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
     }
 
-    void WriteBlockUnsafe(const VAddr dest_addr, const void* src_buffer, const std::size_t size) {
+    void WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
+                          const std::size_t size) {
         WriteBlockImpl<true>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
     }
 
-    void ZeroBlock(const Kernel::KProcess& process, const VAddr dest_addr, const std::size_t size) {
+    void ZeroBlock(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr,
+                   const std::size_t size) {
         WalkBlock(
             process, dest_addr, size,
-            [dest_addr, size](const std::size_t copy_amount, const VAddr current_vaddr) {
+            [dest_addr, size](const std::size_t copy_amount,
+                              const Common::ProcessAddress current_vaddr) {
                 LOG_ERROR(HW_Memory,
                           "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
-                          current_vaddr, dest_addr, size);
+                          GetInteger(current_vaddr), GetInteger(dest_addr), size);
             },
             [](const std::size_t copy_amount, u8* const dest_ptr) {
                 std::memset(dest_ptr, 0, copy_amount);
             },
-            [&](const VAddr current_vaddr, const std::size_t copy_amount, u8* const host_ptr) {
-                system.GPU().InvalidateRegion(current_vaddr, copy_amount);
+            [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
+                u8* const host_ptr) {
+                system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount);
                 std::memset(host_ptr, 0, copy_amount);
             },
             [](const std::size_t copy_amount) {});
     }
 
-    void CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr,
-                   const std::size_t size) {
+    void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                   Common::ProcessAddress src_addr, const std::size_t size) {
         WalkBlock(
             process, dest_addr, size,
-            [&](const std::size_t copy_amount, const VAddr current_vaddr) {
+            [&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) {
                 LOG_ERROR(HW_Memory,
                           "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
-                          current_vaddr, src_addr, size);
+                          GetInteger(current_vaddr), GetInteger(src_addr), size);
                 ZeroBlock(process, dest_addr, copy_amount);
             },
             [&](const std::size_t copy_amount, const u8* const src_ptr) {
                 WriteBlockImpl<false>(process, dest_addr, src_ptr, copy_amount);
             },
-            [&](const VAddr current_vaddr, const std::size_t copy_amount, u8* const host_ptr) {
-                system.GPU().FlushRegion(current_vaddr, copy_amount);
+            [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
+                u8* const host_ptr) {
+                system.GPU().FlushRegion(GetInteger(current_vaddr), copy_amount);
                 WriteBlockImpl<false>(process, dest_addr, host_ptr, copy_amount);
             },
             [&](const std::size_t copy_amount) {
-                dest_addr += static_cast<VAddr>(copy_amount);
-                src_addr += static_cast<VAddr>(copy_amount);
+                dest_addr += copy_amount;
+                src_addr += copy_amount;
             });
     }
 
     template <typename Callback>
-    Result PerformCacheOperation(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size,
-                                 Callback&& cb) {
+    Result PerformCacheOperation(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                                 std::size_t size, Callback&& cb) {
         class InvalidMemoryException : public std::exception {};
 
         try {
             WalkBlock(
                 process, dest_addr, size,
-                [&](const std::size_t block_size, const VAddr current_vaddr) {
-                    LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", current_vaddr);
+                [&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) {
+                    LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}",
+                              GetInteger(current_vaddr));
                     throw InvalidMemoryException();
                 },
                 [&](const std::size_t block_size, u8* const host_ptr) {},
-                [&](const VAddr current_vaddr, const std::size_t block_size, u8* const host_ptr) {
-                    cb(current_vaddr, block_size);
-                },
+                [&](const Common::ProcessAddress current_vaddr, const std::size_t block_size,
+                    u8* const host_ptr) { cb(current_vaddr, block_size); },
                 [](const std::size_t block_size) {});
         } catch (InvalidMemoryException&) {
             return Kernel::ResultInvalidCurrentMemory;
@@ -351,34 +367,40 @@ struct Memory::Impl {
         return ResultSuccess;
     }
 
-    Result InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) {
-        auto on_rasterizer = [&](const VAddr current_vaddr, const std::size_t block_size) {
+    Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                               std::size_t size) {
+        auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
+                                 const std::size_t block_size) {
             // dc ivac: Invalidate to point of coherency
             // GPU flush -> CPU invalidate
-            system.GPU().FlushRegion(current_vaddr, block_size);
+            system.GPU().FlushRegion(GetInteger(current_vaddr), block_size);
         };
         return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
     }
 
-    Result StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) {
-        auto on_rasterizer = [&](const VAddr current_vaddr, const std::size_t block_size) {
+    Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                          std::size_t size) {
+        auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
+                                 const std::size_t block_size) {
             // dc cvac: Store to point of coherency
             // CPU flush -> GPU invalidate
-            system.GPU().InvalidateRegion(current_vaddr, block_size);
+            system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
         };
         return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
     }
 
-    Result FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) {
-        auto on_rasterizer = [&](const VAddr current_vaddr, const std::size_t block_size) {
+    Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                          std::size_t size) {
+        auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
+                                 const std::size_t block_size) {
             // dc civac: Store to point of coherency, and invalidate from cache
             // CPU flush -> GPU invalidate
-            system.GPU().InvalidateRegion(current_vaddr, block_size);
+            system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
         };
         return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
     }
 
-    void MarkRegionDebug(VAddr vaddr, u64 size, bool debug) {
+    void MarkRegionDebug(u64 vaddr, u64 size, bool debug) {
         if (vaddr == 0) {
             return;
         }
@@ -434,7 +456,7 @@ struct Memory::Impl {
         }
     }
 
-    void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) {
+    void RasterizerMarkRegionCached(u64 vaddr, u64 size, bool cached) {
         if (vaddr == 0) {
             return;
         }
@@ -514,10 +536,12 @@ struct Memory::Impl {
      * @param target     The target address to begin mapping from.
      * @param type       The page type to map the memory as.
      */
-    void MapPages(Common::PageTable& page_table, VAddr base, u64 size, PAddr target,
-                  Common::PageType type) {
-        LOG_DEBUG(HW_Memory, "Mapping {:016X} onto {:016X}-{:016X}", target, base * YUZU_PAGESIZE,
-                  (base + size) * YUZU_PAGESIZE);
+    void MapPages(Common::PageTable& page_table, Common::ProcessAddress base_address, u64 size,
+                  Common::PhysicalAddress target, Common::PageType type) {
+        auto base = GetInteger(base_address);
+
+        LOG_DEBUG(HW_Memory, "Mapping {:016X} onto {:016X}-{:016X}", GetInteger(target),
+                  base * YUZU_PAGESIZE, (base + size) * YUZU_PAGESIZE);
 
         // During boot, current_page_table might not be set yet, in which case we need not flush
         if (system.IsPoweredOn()) {
@@ -530,7 +554,7 @@ struct Memory::Impl {
             }
         }
 
-        const VAddr end = base + size;
+        const Common::ProcessAddress end = base + size;
         ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}",
                    base + page_table.pointers.size());
 
@@ -548,7 +572,7 @@ struct Memory::Impl {
             while (base != end) {
                 page_table.pointers[base].Store(
                     system.DeviceMemory().GetPointer<u8>(target) - (base << YUZU_PAGEBITS), type);
-                page_table.backing_addr[base] = target - (base << YUZU_PAGEBITS);
+                page_table.backing_addr[base] = GetInteger(target) - (base << YUZU_PAGEBITS);
 
                 ASSERT_MSG(page_table.pointers[base].Pointer(),
                            "memory mapping base yield a nullptr within the table");
@@ -559,9 +583,9 @@ struct Memory::Impl {
         }
     }
 
-    [[nodiscard]] u8* GetPointerImpl(VAddr vaddr, auto on_unmapped, auto on_rasterizer) const {
+    [[nodiscard]] u8* GetPointerImpl(u64 vaddr, auto on_unmapped, auto on_rasterizer) const {
         // AARCH64 masks the upper 16 bit of all memory accesses
-        vaddr &= 0xffffffffffffULL;
+        vaddr = vaddr & 0xffffffffffffULL;
 
         if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) {
             on_unmapped();
@@ -593,15 +617,18 @@ struct Memory::Impl {
         return nullptr;
     }
 
-    [[nodiscard]] u8* GetPointer(const VAddr vaddr) const {
+    [[nodiscard]] u8* GetPointer(const Common::ProcessAddress vaddr) const {
         return GetPointerImpl(
-            vaddr, [vaddr]() { LOG_ERROR(HW_Memory, "Unmapped GetPointer @ 0x{:016X}", vaddr); },
+            GetInteger(vaddr),
+            [vaddr]() {
+                LOG_ERROR(HW_Memory, "Unmapped GetPointer @ 0x{:016X}", GetInteger(vaddr));
+            },
             []() {});
     }
 
-    [[nodiscard]] u8* GetPointerSilent(const VAddr vaddr) const {
+    [[nodiscard]] u8* GetPointerSilent(const Common::ProcessAddress vaddr) const {
         return GetPointerImpl(
-            vaddr, []() {}, []() {});
+            GetInteger(vaddr), []() {}, []() {});
     }
 
     /**
@@ -616,14 +643,15 @@ struct Memory::Impl {
      * @returns The instance of T read from the specified virtual address.
      */
     template <typename T>
-    T Read(VAddr vaddr) {
+    T Read(Common::ProcessAddress vaddr) {
         T result = 0;
         const u8* const ptr = GetPointerImpl(
-            vaddr,
+            GetInteger(vaddr),
             [vaddr]() {
-                LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:016X}", sizeof(T) * 8, vaddr);
+                LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:016X}", sizeof(T) * 8,
+                          GetInteger(vaddr));
             },
-            [&]() { system.GPU().FlushRegion(vaddr, sizeof(T)); });
+            [&]() { system.GPU().FlushRegion(GetInteger(vaddr), sizeof(T)); });
         if (ptr) {
             std::memcpy(&result, ptr, sizeof(T));
         }
@@ -640,28 +668,28 @@ struct Memory::Impl {
      *           is undefined.
      */
     template <typename T>
-    void Write(VAddr vaddr, const T data) {
+    void Write(Common::ProcessAddress vaddr, const T data) {
         u8* const ptr = GetPointerImpl(
-            vaddr,
+            GetInteger(vaddr),
             [vaddr, data]() {
                 LOG_ERROR(HW_Memory, "Unmapped Write{} @ 0x{:016X} = 0x{:016X}", sizeof(T) * 8,
-                          vaddr, static_cast<u64>(data));
+                          GetInteger(vaddr), static_cast<u64>(data));
             },
-            [&]() { system.GPU().InvalidateRegion(vaddr, sizeof(T)); });
+            [&]() { system.GPU().InvalidateRegion(GetInteger(vaddr), sizeof(T)); });
         if (ptr) {
             std::memcpy(ptr, &data, sizeof(T));
         }
     }
 
     template <typename T>
-    bool WriteExclusive(VAddr vaddr, const T data, const T expected) {
+    bool WriteExclusive(Common::ProcessAddress vaddr, const T data, const T expected) {
         u8* const ptr = GetPointerImpl(
-            vaddr,
+            GetInteger(vaddr),
             [vaddr, data]() {
                 LOG_ERROR(HW_Memory, "Unmapped WriteExclusive{} @ 0x{:016X} = 0x{:016X}",
-                          sizeof(T) * 8, vaddr, static_cast<u64>(data));
+                          sizeof(T) * 8, GetInteger(vaddr), static_cast<u64>(data));
             },
-            [&]() { system.GPU().InvalidateRegion(vaddr, sizeof(T)); });
+            [&]() { system.GPU().InvalidateRegion(GetInteger(vaddr), sizeof(T)); });
         if (ptr) {
             const auto volatile_pointer = reinterpret_cast<volatile T*>(ptr);
             return Common::AtomicCompareAndSwap(volatile_pointer, data, expected);
@@ -669,14 +697,14 @@ struct Memory::Impl {
         return true;
     }
 
-    bool WriteExclusive128(VAddr vaddr, const u128 data, const u128 expected) {
+    bool WriteExclusive128(Common::ProcessAddress vaddr, const u128 data, const u128 expected) {
         u8* const ptr = GetPointerImpl(
-            vaddr,
+            GetInteger(vaddr),
             [vaddr, data]() {
                 LOG_ERROR(HW_Memory, "Unmapped WriteExclusive128 @ 0x{:016X} = 0x{:016X}{:016X}",
-                          vaddr, static_cast<u64>(data[1]), static_cast<u64>(data[0]));
+                          GetInteger(vaddr), static_cast<u64>(data[1]), static_cast<u64>(data[0]));
             },
-            [&]() { system.GPU().InvalidateRegion(vaddr, sizeof(u128)); });
+            [&]() { system.GPU().InvalidateRegion(GetInteger(vaddr), sizeof(u128)); });
         if (ptr) {
             const auto volatile_pointer = reinterpret_cast<volatile u64*>(ptr);
             return Common::AtomicCompareAndSwap(volatile_pointer, data, expected);
@@ -702,15 +730,16 @@ void Memory::SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) {
     impl->SetCurrentPageTable(process, core_id);
 }
 
-void Memory::MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) {
+void Memory::MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
+                             Common::PhysicalAddress target) {
     impl->MapMemoryRegion(page_table, base, size, target);
 }
 
-void Memory::UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
+void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size) {
     impl->UnmapRegion(page_table, base, size);
 }
 
-bool Memory::IsValidVirtualAddress(const VAddr vaddr) const {
+bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
     const Kernel::KProcess& process = *system.ApplicationProcess();
     const auto& page_table = process.PageTable().PageTableImpl();
     const size_t page = vaddr >> YUZU_PAGEBITS;
@@ -722,9 +751,9 @@ bool Memory::IsValidVirtualAddress(const VAddr vaddr) const {
            type == Common::PageType::DebugMemory;
 }
 
-bool Memory::IsValidVirtualAddressRange(VAddr base, u64 size) const {
-    VAddr end = base + size;
-    VAddr page = Common::AlignDown(base, YUZU_PAGESIZE);
+bool Memory::IsValidVirtualAddressRange(Common::ProcessAddress base, u64 size) const {
+    Common::ProcessAddress end = base + size;
+    Common::ProcessAddress page = Common::AlignDown(GetInteger(base), YUZU_PAGESIZE);
 
     for (; page < end; page += YUZU_PAGESIZE) {
         if (!IsValidVirtualAddress(page)) {
@@ -735,131 +764,135 @@ bool Memory::IsValidVirtualAddressRange(VAddr base, u64 size) const {
     return true;
 }
 
-u8* Memory::GetPointer(VAddr vaddr) {
+u8* Memory::GetPointer(Common::ProcessAddress vaddr) {
     return impl->GetPointer(vaddr);
 }
 
-u8* Memory::GetPointerSilent(VAddr vaddr) {
+u8* Memory::GetPointerSilent(Common::ProcessAddress vaddr) {
     return impl->GetPointerSilent(vaddr);
 }
 
-const u8* Memory::GetPointer(VAddr vaddr) const {
+const u8* Memory::GetPointer(Common::ProcessAddress vaddr) const {
     return impl->GetPointer(vaddr);
 }
 
-u8 Memory::Read8(const VAddr addr) {
+u8 Memory::Read8(const Common::ProcessAddress addr) {
     return impl->Read8(addr);
 }
 
-u16 Memory::Read16(const VAddr addr) {
+u16 Memory::Read16(const Common::ProcessAddress addr) {
     return impl->Read16(addr);
 }
 
-u32 Memory::Read32(const VAddr addr) {
+u32 Memory::Read32(const Common::ProcessAddress addr) {
     return impl->Read32(addr);
 }
 
-u64 Memory::Read64(const VAddr addr) {
+u64 Memory::Read64(const Common::ProcessAddress addr) {
     return impl->Read64(addr);
 }
 
-void Memory::Write8(VAddr addr, u8 data) {
+void Memory::Write8(Common::ProcessAddress addr, u8 data) {
     impl->Write8(addr, data);
 }
 
-void Memory::Write16(VAddr addr, u16 data) {
+void Memory::Write16(Common::ProcessAddress addr, u16 data) {
     impl->Write16(addr, data);
 }
 
-void Memory::Write32(VAddr addr, u32 data) {
+void Memory::Write32(Common::ProcessAddress addr, u32 data) {
     impl->Write32(addr, data);
 }
 
-void Memory::Write64(VAddr addr, u64 data) {
+void Memory::Write64(Common::ProcessAddress addr, u64 data) {
     impl->Write64(addr, data);
 }
 
-bool Memory::WriteExclusive8(VAddr addr, u8 data, u8 expected) {
+bool Memory::WriteExclusive8(Common::ProcessAddress addr, u8 data, u8 expected) {
     return impl->WriteExclusive8(addr, data, expected);
 }
 
-bool Memory::WriteExclusive16(VAddr addr, u16 data, u16 expected) {
+bool Memory::WriteExclusive16(Common::ProcessAddress addr, u16 data, u16 expected) {
     return impl->WriteExclusive16(addr, data, expected);
 }
 
-bool Memory::WriteExclusive32(VAddr addr, u32 data, u32 expected) {
+bool Memory::WriteExclusive32(Common::ProcessAddress addr, u32 data, u32 expected) {
     return impl->WriteExclusive32(addr, data, expected);
 }
 
-bool Memory::WriteExclusive64(VAddr addr, u64 data, u64 expected) {
+bool Memory::WriteExclusive64(Common::ProcessAddress addr, u64 data, u64 expected) {
     return impl->WriteExclusive64(addr, data, expected);
 }
 
-bool Memory::WriteExclusive128(VAddr addr, u128 data, u128 expected) {
+bool Memory::WriteExclusive128(Common::ProcessAddress addr, u128 data, u128 expected) {
     return impl->WriteExclusive128(addr, data, expected);
 }
 
-std::string Memory::ReadCString(VAddr vaddr, std::size_t max_length) {
+std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_length) {
     return impl->ReadCString(vaddr, max_length);
 }
 
-void Memory::ReadBlock(const Kernel::KProcess& process, const VAddr src_addr, void* dest_buffer,
-                       const std::size_t size) {
+void Memory::ReadBlock(const Kernel::KProcess& process, const Common::ProcessAddress src_addr,
+                       void* dest_buffer, const std::size_t size) {
     impl->ReadBlockImpl<false>(process, src_addr, dest_buffer, size);
 }
 
-void Memory::ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
+void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
+                       const std::size_t size) {
     impl->ReadBlock(src_addr, dest_buffer, size);
 }
 
-void Memory::ReadBlockUnsafe(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
+void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
+                             const std::size_t size) {
     impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
 }
 
-void Memory::WriteBlock(const Kernel::KProcess& process, VAddr dest_addr, const void* src_buffer,
-                        std::size_t size) {
+void Memory::WriteBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                        const void* src_buffer, std::size_t size) {
     impl->WriteBlockImpl<false>(process, dest_addr, src_buffer, size);
 }
 
-void Memory::WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t size) {
+void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
+                        const std::size_t size) {
     impl->WriteBlock(dest_addr, src_buffer, size);
 }
 
-void Memory::WriteBlockUnsafe(const VAddr dest_addr, const void* src_buffer,
+void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
                               const std::size_t size) {
     impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
 }
 
-void Memory::CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr,
-                       const std::size_t size) {
+void Memory::CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                       Common::ProcessAddress src_addr, const std::size_t size) {
     impl->CopyBlock(process, dest_addr, src_addr, size);
 }
 
-void Memory::ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, const std::size_t size) {
+void Memory::ZeroBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                       const std::size_t size) {
     impl->ZeroBlock(process, dest_addr, size);
 }
 
-Result Memory::InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr,
-                                   const std::size_t size) {
+Result Memory::InvalidateDataCache(const Kernel::KProcess& process,
+                                   Common::ProcessAddress dest_addr, const std::size_t size) {
     return impl->InvalidateDataCache(process, dest_addr, size);
 }
 
-Result Memory::StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr,
+Result Memory::StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
                               const std::size_t size) {
     return impl->StoreDataCache(process, dest_addr, size);
 }
 
-Result Memory::FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr,
+Result Memory::FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
                               const std::size_t size) {
     return impl->FlushDataCache(process, dest_addr, size);
 }
 
-void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) {
-    impl->RasterizerMarkRegionCached(vaddr, size, cached);
+void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) {
+    impl->RasterizerMarkRegionCached(GetInteger(vaddr), size, cached);
 }
 
-void Memory::MarkRegionDebug(VAddr vaddr, u64 size, bool debug) {
-    impl->MarkRegionDebug(vaddr, size, debug);
+void Memory::MarkRegionDebug(Common::ProcessAddress vaddr, u64 size, bool debug) {
+    impl->MarkRegionDebug(GetInteger(vaddr), size, debug);
 }
 
 } // namespace Core::Memory
diff --git a/src/core/memory.h b/src/core/memory.h
index 456b49f63..c6c5999aa 100755
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -6,7 +6,7 @@
 #include <cstddef>
 #include <memory>
 #include <string>
-#include "common/common_types.h"
+#include "common/typed_address.h"
 #include "core/hle/result.h"
 
 namespace Common {
@@ -33,7 +33,7 @@ constexpr u64 YUZU_PAGESIZE = 1ULL << YUZU_PAGEBITS;
 constexpr u64 YUZU_PAGEMASK = YUZU_PAGESIZE - 1;
 
 /// Virtual user-space memory regions
-enum : VAddr {
+enum : u64 {
     /// TLS (Thread-Local Storage) related.
     TLS_ENTRY_SIZE = 0x200,
 
@@ -74,7 +74,8 @@ public:
      * @param target     Buffer with the memory backing the mapping. Must be of length at least
      *                   `size`.
      */
-    void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target);
+    void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
+                         Common::PhysicalAddress target);
 
     /**
      * Unmaps a region of the emulated process address space.
@@ -83,7 +84,7 @@ public:
      * @param base       The address to begin unmapping at.
      * @param size       The amount of bytes to unmap.
      */
-    void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size);
+    void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size);
 
     /**
      * Checks whether or not the supplied address is a valid virtual
@@ -93,7 +94,7 @@ public:
      *
      * @returns True if the given virtual address is valid, false otherwise.
      */
-    [[nodiscard]] bool IsValidVirtualAddress(VAddr vaddr) const;
+    [[nodiscard]] bool IsValidVirtualAddress(Common::ProcessAddress vaddr) const;
 
     /**
      * Checks whether or not the supplied range of addresses are all valid
@@ -104,7 +105,7 @@ public:
      *
      * @returns True if all bytes in the given range are valid, false otherwise.
      */
-    [[nodiscard]] bool IsValidVirtualAddressRange(VAddr base, u64 size) const;
+    [[nodiscard]] bool IsValidVirtualAddressRange(Common::ProcessAddress base, u64 size) const;
 
     /**
      * Gets a pointer to the given address.
@@ -114,11 +115,11 @@ public:
      * @returns The pointer to the given address, if the address is valid.
      *          If the address is not valid, nullptr will be returned.
      */
-    u8* GetPointer(VAddr vaddr);
-    u8* GetPointerSilent(VAddr vaddr);
+    u8* GetPointer(Common::ProcessAddress vaddr);
+    u8* GetPointerSilent(Common::ProcessAddress vaddr);
 
     template <typename T>
-    T* GetPointer(VAddr vaddr) {
+    T* GetPointer(Common::ProcessAddress vaddr) {
         return reinterpret_cast<T*>(GetPointer(vaddr));
     }
 
@@ -130,10 +131,10 @@ public:
      * @returns The pointer to the given address, if the address is valid.
      *          If the address is not valid, nullptr will be returned.
      */
-    [[nodiscard]] const u8* GetPointer(VAddr vaddr) const;
+    [[nodiscard]] const u8* GetPointer(Common::ProcessAddress vaddr) const;
 
     template <typename T>
-    const T* GetPointer(VAddr vaddr) const {
+    const T* GetPointer(Common::ProcessAddress vaddr) const {
         return reinterpret_cast<T*>(GetPointer(vaddr));
     }
 
@@ -145,7 +146,7 @@ public:
      *
      * @returns the read 8-bit unsigned value.
      */
-    u8 Read8(VAddr addr);
+    u8 Read8(Common::ProcessAddress addr);
 
     /**
      * Reads a 16-bit unsigned value from the current process' address space
@@ -155,7 +156,7 @@ public:
      *
      * @returns the read 16-bit unsigned value.
      */
-    u16 Read16(VAddr addr);
+    u16 Read16(Common::ProcessAddress addr);
 
     /**
      * Reads a 32-bit unsigned value from the current process' address space
@@ -165,7 +166,7 @@ public:
      *
      * @returns the read 32-bit unsigned value.
      */
-    u32 Read32(VAddr addr);
+    u32 Read32(Common::ProcessAddress addr);
 
     /**
      * Reads a 64-bit unsigned value from the current process' address space
@@ -175,7 +176,7 @@ public:
      *
      * @returns the read 64-bit value.
      */
-    u64 Read64(VAddr addr);
+    u64 Read64(Common::ProcessAddress addr);
 
     /**
      * Writes an 8-bit unsigned integer to the given virtual address in
@@ -186,7 +187,7 @@ public:
      *
      * @post The memory at the given virtual address contains the specified data value.
      */
-    void Write8(VAddr addr, u8 data);
+    void Write8(Common::ProcessAddress addr, u8 data);
 
     /**
      * Writes a 16-bit unsigned integer to the given virtual address in
@@ -197,7 +198,7 @@ public:
      *
      * @post The memory range [addr, sizeof(data)) contains the given data value.
      */
-    void Write16(VAddr addr, u16 data);
+    void Write16(Common::ProcessAddress addr, u16 data);
 
     /**
      * Writes a 32-bit unsigned integer to the given virtual address in
@@ -208,7 +209,7 @@ public:
      *
      * @post The memory range [addr, sizeof(data)) contains the given data value.
      */
-    void Write32(VAddr addr, u32 data);
+    void Write32(Common::ProcessAddress addr, u32 data);
 
     /**
      * Writes a 64-bit unsigned integer to the given virtual address in
@@ -219,7 +220,7 @@ public:
      *
      * @post The memory range [addr, sizeof(data)) contains the given data value.
      */
-    void Write64(VAddr addr, u64 data);
+    void Write64(Common::ProcessAddress addr, u64 data);
 
     /**
      * Writes a 8-bit unsigned integer to the given virtual address in
@@ -232,7 +233,7 @@ public:
      *
      * @post The memory range [addr, sizeof(data)) contains the given data value.
      */
-    bool WriteExclusive8(VAddr addr, u8 data, u8 expected);
+    bool WriteExclusive8(Common::ProcessAddress addr, u8 data, u8 expected);
 
     /**
      * Writes a 16-bit unsigned integer to the given virtual address in
@@ -245,7 +246,7 @@ public:
      *
      * @post The memory range [addr, sizeof(data)) contains the given data value.
      */
-    bool WriteExclusive16(VAddr addr, u16 data, u16 expected);
+    bool WriteExclusive16(Common::ProcessAddress addr, u16 data, u16 expected);
 
     /**
      * Writes a 32-bit unsigned integer to the given virtual address in
@@ -258,7 +259,7 @@ public:
      *
      * @post The memory range [addr, sizeof(data)) contains the given data value.
      */
-    bool WriteExclusive32(VAddr addr, u32 data, u32 expected);
+    bool WriteExclusive32(Common::ProcessAddress addr, u32 data, u32 expected);
 
     /**
      * Writes a 64-bit unsigned integer to the given virtual address in
@@ -271,7 +272,7 @@ public:
      *
      * @post The memory range [addr, sizeof(data)) contains the given data value.
      */
-    bool WriteExclusive64(VAddr addr, u64 data, u64 expected);
+    bool WriteExclusive64(Common::ProcessAddress addr, u64 data, u64 expected);
 
     /**
      * Writes a 128-bit unsigned integer to the given virtual address in
@@ -284,7 +285,7 @@ public:
      *
      * @post The memory range [addr, sizeof(data)) contains the given data value.
      */
-    bool WriteExclusive128(VAddr addr, u128 data, u128 expected);
+    bool WriteExclusive128(Common::ProcessAddress addr, u128 data, u128 expected);
 
     /**
      * Reads a null-terminated string from the given virtual address.
@@ -301,7 +302,7 @@ public:
      *
      * @returns The read string.
      */
-    std::string ReadCString(VAddr vaddr, std::size_t max_length);
+    std::string ReadCString(Common::ProcessAddress vaddr, std::size_t max_length);
 
     /**
      * Reads a contiguous block of bytes from a specified process' address space.
@@ -320,8 +321,8 @@ public:
      * @post The range [dest_buffer, size) contains the read bytes from the
      *       process' address space.
      */
-    void ReadBlock(const Kernel::KProcess& process, VAddr src_addr, void* dest_buffer,
-                   std::size_t size);
+    void ReadBlock(const Kernel::KProcess& process, Common::ProcessAddress src_addr,
+                   void* dest_buffer, std::size_t size);
 
     /**
      * Reads a contiguous block of bytes from the current process' address space.
@@ -339,7 +340,7 @@ public:
      * @post The range [dest_buffer, size) contains the read bytes from the
      *       current process' address space.
      */
-    void ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size);
+    void ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
 
     /**
      * Reads a contiguous block of bytes from the current process' address space.
@@ -358,7 +359,7 @@ public:
      * @post The range [dest_buffer, size) contains the read bytes from the
      *       current process' address space.
      */
-    void ReadBlockUnsafe(VAddr src_addr, void* dest_buffer, std::size_t size);
+    void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
 
     /**
      * Writes a range of bytes into a given process' address space at the specified
@@ -380,8 +381,8 @@ public:
      *       and will mark that region as invalidated to caches that the active
      *       graphics backend may be maintaining over the course of execution.
      */
-    void WriteBlock(const Kernel::KProcess& process, VAddr dest_addr, const void* src_buffer,
-                    std::size_t size);
+    void WriteBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                    const void* src_buffer, std::size_t size);
 
     /**
      * Writes a range of bytes into the current process' address space at the specified
@@ -402,7 +403,7 @@ public:
      *       and will mark that region as invalidated to caches that the active
      *       graphics backend may be maintaining over the course of execution.
      */
-    void WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size);
+    void WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size);
 
     /**
      * Writes a range of bytes into the current process' address space at the specified
@@ -420,7 +421,8 @@ public:
      *       will be ignored and an error will be logged.
      *
      */
-    void WriteBlockUnsafe(VAddr dest_addr, const void* src_buffer, std::size_t size);
+    void WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer,
+                          std::size_t size);
 
     /**
      * Copies data within a process' address space to another location within the
@@ -434,8 +436,8 @@ public:
      * @post The range [dest_addr, size) within the process' address space contains the
      *       same data within the range [src_addr, size).
      */
-    void CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr,
-                   std::size_t size);
+    void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                   Common::ProcessAddress src_addr, std::size_t size);
 
     /**
      * Zeros a range of bytes within the current process' address space at the specified
@@ -448,7 +450,8 @@ public:
      * @post The range [dest_addr, size) within the process' address space contains the
      *       value 0.
      */
-    void ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size);
+    void ZeroBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                   std::size_t size);
 
     /**
      * Invalidates a range of bytes within the current process' address space at the specified
@@ -459,7 +462,8 @@ public:
      * @param size      The size of the range to invalidate, in bytes.
      *
      */
-    Result InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size);
+    Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                               std::size_t size);
 
     /**
      * Stores a range of bytes within the current process' address space at the specified
@@ -470,7 +474,8 @@ public:
      * @param size      The size of the range to store, in bytes.
      *
      */
-    Result StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size);
+    Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                          std::size_t size);
 
     /**
      * Flushes a range of bytes within the current process' address space at the specified
@@ -481,7 +486,8 @@ public:
      * @param size      The size of the range to flush, in bytes.
      *
      */
-    Result FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size);
+    Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
+                          std::size_t size);
 
     /**
      * Marks each page within the specified address range as cached or uncached.
@@ -491,7 +497,7 @@ public:
      * @param cached Whether or not any pages within the address range should be
      *               marked as cached or uncached.
      */
-    void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached);
+    void RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached);
 
     /**
      * Marks each page within the specified address range as debug or non-debug.
@@ -502,7 +508,7 @@ public:
      * @param debug Whether or not any pages within the address range should be
      *              marked as debug or non-debug.
      */
-    void MarkRegionDebug(VAddr vaddr, u64 size, bool debug);
+    void MarkRegionDebug(Common::ProcessAddress vaddr, u64 size, bool debug);
 
 private:
     Core::System& system;
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index f4e6a4a6d..2cb6ce2f5 100755
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -201,17 +201,17 @@ void CheatEngine::Initialize() {
 
     const auto& page_table = system.ApplicationProcess()->PageTable();
     metadata.heap_extents = {
-        .base = page_table.GetHeapRegionStart(),
+        .base = GetInteger(page_table.GetHeapRegionStart()),
         .size = page_table.GetHeapRegionSize(),
     };
 
     metadata.address_space_extents = {
-        .base = page_table.GetAddressSpaceStart(),
+        .base = GetInteger(page_table.GetAddressSpaceStart()),
         .size = page_table.GetAddressSpaceSize(),
     };
 
     metadata.alias_extents = {
-        .base = page_table.GetAliasCodeRegionStart(),
+        .base = GetInteger(page_table.GetAliasCodeRegionStart()),
         .size = page_table.GetAliasCodeRegionSize(),
     };
 
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index d555509d3..5daab03d5 100755
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -117,8 +117,8 @@ json GetProcessorStateDataAuto(Core::System& system) {
     arm.SaveContext(context);
 
     return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32",
-                                 process->PageTable().GetCodeRegionStart(), context.sp, context.pc,
-                                 context.pstate, context.cpu_registers);
+                                 GetInteger(process->PageTable().GetCodeRegionStart()), context.sp,
+                                 context.pc, context.pstate, context.cpu_registers);
 }
 
 json GetBacktraceData(Core::System& system) {
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp
index 8fd60562e..b7cb4ba81 100755
--- a/src/video_core/renderer_vulkan/vk_scheduler.cpp
+++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp
@@ -65,12 +65,13 @@ void Scheduler::WaitWorker() {
     DispatchWork();
 
     // Ensure the queue is drained.
-    std::unique_lock ql{queue_mutex};
-    event_cv.wait(ql, [this] { return work_queue.empty(); });
+    {
+        std::unique_lock ql{queue_mutex};
+        event_cv.wait(ql, [this] { return work_queue.empty(); });
+    }
 
     // Now wait for execution to finish.
-    // This needs to be done in the same order as WorkerThread.
-    std::unique_lock el{execution_mutex};
+    std::scoped_lock el{execution_mutex};
 }
 
 void Scheduler::DispatchWork() {