diff --git a/thermosphere/src/gdb/hvisor_gdb_mem.cpp b/thermosphere/src/gdb/hvisor_gdb_mem.cpp
index b0d44e880..52575f28d 100644
--- a/thermosphere/src/gdb/hvisor_gdb_mem.cpp
+++ b/thermosphere/src/gdb/hvisor_gdb_mem.cpp
@@ -24,7 +24,7 @@
#include "hvisor_gdb_defines_internal.hpp"
#include "hvisor_gdb_packet_data.hpp"
-#include "../guest_memory.h"
+#include "../hvisor_guest_memory.hpp"
namespace ams::hvisor::gdb {
@@ -40,7 +40,7 @@ namespace ams::hvisor::gdb {
return prefixLen == 0 ? ReplyErrno(ENOMEM) : -1;
}
- size_t total = guestReadMemory(addr, len, membuf);
+ size_t total = GuestReadMemory(addr, len, membuf);
if (total == 0) {
return prefixLen == 0 ? ReplyErrno(EFAULT) : -EFAULT;
@@ -73,7 +73,7 @@ namespace ams::hvisor::gdb {
return ReplyErrno(EILSEQ);
}
- size_t total = guestWriteMemory(addr, len, workbuf);
+ size_t total = GuestWriteMemory(addr, len, workbuf);
return total == len ? ReplyOk() : ReplyErrno(EFAULT);
}
diff --git a/thermosphere/src/guest_memory.c b/thermosphere/src/guest_memory.c
deleted file mode 100644
index 69c7d3a17..000000000
--- a/thermosphere/src/guest_memory.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 2019 Atmosphère-NX
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include
-
-#include "guest_memory.h"
-#include "memory_map.h"
-#include "mmu.h"
-#include "spinlock.h"
-#include "core_ctx.h"
-#include "sysreg.h"
-#include "vgic.h"
-#include "irq.h"
-#include "caches.h"
-
-static size_t guestReadWriteGicd(size_t offset, size_t size, void *readBuf, const void *writeBuf)
-{
- recursiveSpinlockLock(&g_irqManager.lock);
-
- if (readBuf != NULL) {
- size_t readOffset = 0;
- size_t rem = size;
- while (rem > 0) {
- if ((offset + readOffset) % 4 == 0 && rem >= 4) {
- // All accesses of this kind are valid
- *(u32 *)((uintptr_t)readBuf + readOffset) = vgicReadGicdRegister(offset + readOffset, 4);
- readOffset += 4;
- rem -= 4;
- } else if ((offset + readOffset) % 2 == 0 && rem >= 2) {
- // All accesses of this kind would be translated to ldrh and are thus invalid. Abort.
- size = readOffset;
- goto end;
- } else if (vgicValidateGicdRegisterAccess(offset + readOffset, 1)) {
- // Valid byte access
- *(u8 *)((uintptr_t)readBuf + readOffset) = vgicReadGicdRegister(offset + readOffset, 1);
- readOffset += 1;
- rem -= 1;
- } else {
- // Invalid byte access
- size = readOffset;
- goto end;
- }
- }
- }
-
- if (writeBuf != NULL) {
- size_t writeOffset = 0;
- size_t rem = size;
- while (rem > 0) {
- if ((offset + writeOffset) % 4 == 0 && rem >= 4) {
- // All accesses of this kind are valid
- vgicWriteGicdRegister(*(u32 *)((uintptr_t)writeBuf + writeOffset), offset + writeOffset, 4);
- writeOffset += 4;
- rem -= 4;
- } else if ((offset + writeOffset) % 2 == 0 && rem >= 2) {
- // All accesses of this kind would be translated to ldrh and are thus invalid. Abort.
- size = writeOffset;
- goto end;
- } else if (vgicValidateGicdRegisterAccess(offset + writeOffset, 1)) {
- // Valid byte access
- vgicWriteGicdRegister(*(u32 *)((uintptr_t)writeBuf + writeOffset), offset + writeOffset, 1);
- writeOffset += 1;
- rem -= 1;
- } else {
- // Invalid byte access
- size = writeOffset;
- goto end;
- }
- }
- }
-
-end:
- recursiveSpinlockUnlock(&g_irqManager.lock);
- return size;
-}
-
-static size_t guestReadWriteDeviceMemory(void *addr, size_t size, void *readBuf, const void *writeBuf)
-{
- // We might trigger bus errors... ignore the exception and return early if that's the case
-
- CoreCtx *curCtxBackup = currentCoreCtx;
- __compiler_barrier();
- currentCoreCtx = NULL;
- __compiler_barrier();
-
- uintptr_t addri = (uintptr_t)addr;
-
- if (readBuf != NULL) {
- size_t readOffset = 0;
- size_t rem = size;
- while (rem > 0 && (__compiler_barrier(), currentCoreCtx == NULL)) {
- if ((addri + readOffset) % 4 == 0 && rem >= 4) {
- *(vu32 *)((uintptr_t)readBuf + readOffset) = *(vu32 *)(addri + readOffset);
- readOffset += 4;
- rem -= 4;
- } else if (readOffset % 2 == 0 && rem >= 2) {
- *(vu16 *)((uintptr_t)readBuf + readOffset) = *(vu16 *)(addri + readOffset);
- readOffset += 2;
- rem -= 2;
- } else {
- *(vu8 *)((uintptr_t)readBuf + readOffset) = *(vu8 *)(addri + readOffset);
- readOffset += 1;
- rem -= 1;
- }
- }
- if (rem != 0) {
- size = readOffset;
- goto end;
- }
- }
-
- if (writeBuf != NULL) {
- size_t writeOffset = 0;
- size_t rem = size;
- while (rem > 0 && (__compiler_barrier(), currentCoreCtx == NULL)) {
- if ((addri + writeOffset) % 4 == 0 && rem >= 4) {
- *(vu32 *)(addri + writeOffset) = *(vu32 *)((uintptr_t)writeBuf + writeOffset);
- writeOffset += 4;
- rem -= 4;
- } else if (writeOffset % 2 == 0 && rem >= 2) {
- *(vu16 *)(addri + writeOffset) = *(vu16 *)((uintptr_t)writeBuf + writeOffset);
- writeOffset += 2;
- rem -= 2;
- } else {
- *(vu8 *)(addri + writeOffset) = *(vu8 *)((uintptr_t)writeBuf + writeOffset);
- writeOffset += 1;
- rem -= 1;
- }
- }
- if (rem != 0) {
- size = writeOffset;
- goto end;
- }
- }
-
-end:
- __compiler_barrier();
- currentCoreCtx = curCtxBackup;
- __compiler_barrier();
- return size;
-}
-
-static size_t guestReadWriteNormalMemory(void *addr, size_t size, void *readBuf, const void *writeBuf)
-{
- if (readBuf != NULL) {
- memcpy(readBuf, addr, size);
- }
-
- if (writeBuf != NULL) {
- memcpy(addr, writeBuf, size);
-
- // We may have written to executable memory or to translation tables...
- // & the page may have various aliases.
- // We need to ensure cache & TLB coherency.
- cacheCleanDataCacheRangePoU(addr, size);
- u32 policy = cacheGetInstructionCachePolicy();
- if (policy == 1 || policy == 2) {
- // AVIVT, VIVT
- cacheInvalidateInstructionCache();
- } else {
- // VPIPT, PIPT
- // Ez coherency, just do range operations...
- cacheInvalidateInstructionCacheRangePoU(addr, size);
- }
- __tlb_invalidate_el1();
- __dsb();
- __isb();
- }
-
- return size;
-}
-
-static size_t guestReadWriteMemoryPage(uintptr_t addr, size_t size, void *readBuf, const void *writeBuf)
-{
- u64 irqFlags = maskIrq();
- size_t offset = addr & 0xFFFull;
-
- // Translate the VA, stages 1&2
- __asm__ __volatile__ ("at s12e1r, %0" :: "r"(addr) : "memory");
- u64 par = GET_SYSREG(par_el1);
- if (par & PAR_F) {
- // The translation failed. Why?
- if (par & PAR_S) {
- // Stage 2 fault. Could be an attempt to access the GICD, let's see what the IPA is...
- __asm__ __volatile__ ("at s1e1r, %0" :: "r"(addr) : "memory");
- par = GET_SYSREG(par_el1);
- if ((par & PAR_F) != 0 || (par & PAR_PA_MASK) != MEMORY_MAP_VA_GICD) {
- // The guest doesn't have access to it...
- // Read as 0, write ignored
- if (readBuf != NULL) {
- memset(readBuf, 0, size);
- }
- } else {
- // GICD mmio
- size = guestReadWriteGicd(offset, size, readBuf, writeBuf);
- }
- } else {
- // Oops, couldn't read/write anything (stage 1 fault)
- size = 0;
- }
- } else {
- /*
- Translation didn't fail.
-
- To avoid "B2.8 Mismatched memory attributes" we must use the same effective
- attributes & shareability as the guest.
-
- Note that par_el1 reports the effective shareablity of device and noncacheable memory as inner shareable.
- In fact, the VMSAv8-64 section in the Armv8 ARM reads:
- "The shareability field is only relevant if the memory is a Normal Cacheable memory type. All Device and Normal
- Non-cacheable memory regions are always treated as Outer Shareable, regardless of the translation table
- shareability attributes."
-
- There's one corner case where we can't avoid it: another core is running,
- changes the attributes (other than permissions) of the page, and issues
- a broadcasting TLB maintenance instructions and/or accesses the page with the altered
- attribute itself. We don't handle this corner case -- just don't read/write that kind of memory...
- */
- u64 memAttribs = (par >> PAR_ATTR_SHIFT) & PAR_ATTR_MASK;
- u32 shrb = (par >> PAR_SH_SHIFT) & PAR_SH_MASK;
- uintptr_t pa = par & PAR_PA_MASK;
- uintptr_t va = MEMORY_MAP_VA_GUEST_MEM + 0x2000 * currentCoreCtx->coreId;
-
- u64 mair = GET_SYSREG(mair_el2);
- mair |= memAttribs << (8 * MEMORY_MAP_MEMTYPE_NORMAL_GUEST_SLOT);
- SET_SYSREG(mair_el2, mair);
- __isb();
-
- u64 attribs = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_SH(shrb) | MMU_PTE_BLOCK_MEMTYPE(MEMORY_MAP_MEMTYPE_NORMAL_GUEST_SLOT);
- mmu_map_page((uintptr_t *)MEMORY_MAP_VA_TTBL, va, pa, attribs);
- // Note: no need to broadcast here
- __tlb_invalidate_el2_page_local(pa);
- __dsb_local();
-
- void *vaddr = (void *)(va + offset);
- if (memAttribs & 0xF0) {
- // Normal memory, or unpredictable
- size = guestReadWriteNormalMemory(vaddr, size, readBuf, writeBuf);
- } else {
- // Device memory, or unpredictable
- size = guestReadWriteDeviceMemory(vaddr, size, readBuf, writeBuf);
- }
-
- __dsb_local();
- __isb();
- mmu_unmap_page((uintptr_t *)MEMORY_MAP_VA_TTBL, va);
- // Note: no need to broadcast here
- __tlb_invalidate_el2_page_local(pa);
- __dsb_local();
-
- mair &= ~(0xFFul << (8 * MEMORY_MAP_MEMTYPE_NORMAL_GUEST_SLOT));
- SET_SYSREG(mair_el2, mair);
- __isb();
- }
-
- restoreInterruptFlags(irqFlags);
- return size;
-}
-
-size_t guestReadWriteMemory(uintptr_t addr, size_t size, void *readBuf, const void *writeBuf)
-{
- uintptr_t curAddr = addr;
- size_t remainingAmount = size;
- u8 *rb8 = (u8 *)readBuf;
- const u8 *wb8 = (const u8*)writeBuf;
- while (remainingAmount > 0) {
- size_t expectedAmount = ((curAddr & ~0xFFFul) + 0x1000) - curAddr;
- expectedAmount = expectedAmount > remainingAmount ? remainingAmount : expectedAmount;
- size_t actualAmount = guestReadWriteMemoryPage(curAddr, expectedAmount, rb8, wb8);
- curAddr += actualAmount;
- rb8 += actualAmount;
- wb8 += actualAmount;
- remainingAmount -= actualAmount;
- if (actualAmount != expectedAmount) {
- break;
- }
- }
- return curAddr - addr;
-}
diff --git a/thermosphere/src/hvisor_guest_memory.cpp b/thermosphere/src/hvisor_guest_memory.cpp
new file mode 100644
index 000000000..59adda320
--- /dev/null
+++ b/thermosphere/src/hvisor_guest_memory.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2019-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "hvisor_virtual_gic.hpp"
+#include "hvisor_safe_io_copy.hpp"
+#include "cpu/hvisor_cpu_caches.hpp"
+#include "cpu/hvisor_cpu_interrupt_mask_guard.hpp"
+
+using namespace ams::hvisor;
+using namespace ams::hvisor::cpu;
+
+namespace {
+
+ template
+ T ReadBufferValue(const void *buf, size_t off)
+ {
+ static_assert(std::is_unsigned_v && sizeof(T) <= 4);
+ T ret;
+ std::memcpy(&ret, reinterpret_cast(buf) + off, sizeof(T));
+ return ret;
+ }
+
+ template
+ void WriteBufferValue(void *buf, size_t off, T val)
+ {
+ static_assert(std::is_unsigned_v && sizeof(T) <= 4);
+ std::memcpy(reinterpret_cast(buf) + off, T, sizeof(T));
+ }
+
+ size_t GuestReadWriteGicd(size_t offset, size_t size, void *readBuf, const void *writeBuf)
+ {
+ auto &vgic = VirtualGic::GetInstance();
+ if (readBuf != nullptr) {
+ size_t readOffset = 0;
+ size_t rem = size;
+ while (rem > 0) {
+ if ((offset + readOffset) % 4 == 0 && rem >= 4) {
+ // All accesses of this kind are valid
+ WriteBufferValue(readBuf, readOffset, vgic.ReadGicdRegister(offset + readOffset, 4));
+ readOffset += 4;
+ rem -= 4;
+ } else if ((offset + readOffset) % 2 == 0 && rem >= 2) {
+ // All accesses of this kind would be translated to ldrh and are thus invalid. Abort.
+ return readOffset;
+ } else if (VirtualGic::ValidateGicdRegisterAccess(offset + readOffset, 1)) {
+ // Valid byte access
+ WriteBufferValue(readBuf, readOffset, vgic.ReadGicdRegister(offset + readOffset, 1));
+ readOffset += 1;
+ rem -= 1;
+ } else {
+ // Invalid byte access
+ return readOffset;
+ }
+ }
+ }
+
+ if (writeBuf != nullptr) {
+ size_t writeOffset = 0;
+ size_t rem = size;
+ while (rem > 0) {
+ if ((offset + writeOffset) % 4 == 0 && rem >= 4) {
+ // All accesses of this kind are valid
+ vgic.WriteGicdRegister(ReadBufferValue(writeBuf, writeOffset), offset + writeOffset, 4);
+ writeOffset += 4;
+ rem -= 4;
+ } else if ((offset + writeOffset) % 2 == 0 && rem >= 2) {
+ // All accesses of this kind would be translated to ldrh and are thus invalid. Abort.
+ return writeOffset;
+ } else if (VirtualGic::ValidateGicdRegisterAccess(offset + writeOffset, 1)) {
+ // Valid byte access
+ vgic.WriteGicdRegister(ReadBufferValue(writeBuf, writeOffset), offset + writeOffset, 1);
+ writeOffset += 1;
+ rem -= 1;
+ } else {
+ // Invalid byte access
+ return writeOffset;
+ }
+ }
+ }
+
+ return size;
+ }
+
+ size_t GuestReadWriteDeviceMemory(void *addr, size_t size, void *readBuf, const void *writeBuf)
+ {
+ if (readBuf != nullptr) {
+ size_t sz = SafeIoCopy(readBuf, addr, size);
+ if (sz < size) {
+ return sz;
+ }
+ }
+
+ if (writeBuf != nullptr) {
+ size_t sz = SafeIoCopy(addr, writeBuf, size);
+ if (sz < size) {
+ return sz;
+ }
+ }
+
+ // Translation tables must be on Normal memory & Device memory isn't cacheable, so we don't have
+ // that kind of thing to handle...
+
+ return size;
+ }
+
+ size_t GuestReadWriteNormalMemory(void *addr, size_t size, void *readBuf, const void *writeBuf)
+ {
+ if (readBuf != nullptr) {
+ std::memcpy(readBuf, addr, size);
+ }
+
+ if (writeBuf != nullptr) {
+ std::memcpy(addr, writeBuf, size);
+
+ // We may have written to executable memory or to translation tables...
+ // & the page may have various aliases.
+ // We need to ensure cache & TLB coherency.
+ CleanDataCacheRangePoU(addr, size);
+ u32 policy = GetInstructionCachePolicy();
+ if (policy == 1 || policy == 2) {
+ // AVIVT, VIVT
+ InvalidateInstructionCache();
+ } else {
+ // VPIPT, PIPT
+ // Ez coherency, just do range operations...
+ InvalidateInstructionCacheRangePoU(addr, size);
+ }
+ TlbInvalidateEl1();
+ dsb();
+ isb();
+ }
+
+ return size;
+ }
+
+ size_t GuestReadWriteMemoryPage(uintptr_t addr, size_t size, void *readBuf, const void *writeBuf)
+ {
+ InterruptMaskGuard ig{};
+ size_t offset = addr & 0xFFFul;
+
+ // Translate the VA, stages 1&2
+ __asm__ __volatile__ ("at s12e1r, %0" :: "r"(addr) : "memory");
+ u64 par = THERMOSPHERE_GET_SYSREG(par_el1);
+ if (par & PAR_F) {
+ // The translation failed. Why?
+ if (par & PAR_S) {
+ // Stage 2 fault. Could be an attempt to access the GICD, let's see what the IPA is...
+ __asm__ __volatile__ ("at s1e1r, %0" :: "r"(addr) : "memory");
+ par = THERMOSPHERE_GET_SYSREG(par_el1);
+ if ((par & PAR_F) != 0 || (par & PAR_PA_MASK) != VirtualGic::gicdPhysicalAddress) {
+ // The guest doesn't have access to it...
+ // Read as 0, write ignored
+ if (readBuf != NULL) {
+ std::memset(readBuf, 0, size);
+ }
+ } else {
+ // GICD mmio
+ size = GuestReadWriteGicd(offset, size, readBuf, writeBuf);
+ }
+ } else {
+ // Oops, couldn't read/write anything (stage 1 fault)
+ size = 0;
+ }
+ } else {
+ /*
+ Translation didn't fail.
+
+ To avoid "B2.8 Mismatched memory attributes" we must use the same effective
+ attributes & shareability as the guest.
+
+ Note that par_el1 reports the effective shareablity of device and noncacheable memory as inner shareable.
+ In fact, the VMSAv8-64 section in the Armv8 ARM reads:
+ "The shareability field is only relevant if the memory is a Normal Cacheable memory type. All Device and Normal
+ Non-cacheable memory regions are always treated as Outer Shareable, regardless of the translation table
+ shareability attributes."
+
+ There's one corner case where we can't avoid it: another core is running,
+ changes the attributes (other than permissions) of the page, and issues
+ a broadcasting TLB maintenance instructions and/or accesses the page with the altered
+ attribute itself. We don't handle this corner case -- just don't read/write that kind of memory...
+ */
+ u64 memAttribs = (par >> PAR_ATTR_SHIFT) & PAR_ATTR_MASK;
+ u64 shrb = (par >> PAR_SH_SHIFT) & PAR_SH_MASK;
+ uintptr_t pa = par & PAR_PA_MASK;
+
+ uintptr_t va = MemoryMap::MapGuestPage(pa, memAttribs, shrb);
+ void *vaddr = reinterpret_cast(va + offset);
+ if (memAttribs & 0xF0) {
+ // Normal memory, or unpredictable
+ size = GuestReadWriteNormalMemory(vaddr, size, readBuf, writeBuf);
+ } else {
+ // Device memory, or unpredictable
+ size = GuestReadWriteDeviceMemory(vaddr, size, readBuf, writeBuf);
+ }
+
+ MemoryMap::UnmapGuestPage();
+ }
+
+ return size;
+ }
+
+}
+
+namespace ams::hvisor {
+
+ size_t GuestReadWriteMemory(uintptr_t addr, size_t size, void *readBuf, const void *writeBuf)
+ {
+ uintptr_t curAddr = addr;
+ size_t remainingAmount = size;
+ u8 *rb8 = reinterpret_cast(readBuf);
+ const u8 *wb8 = reinterpret_cast(writeBuf);
+ while (remainingAmount > 0) {
+ size_t expectedAmount = ((curAddr & ~0xFFFul) + 0x1000) - curAddr;
+ expectedAmount = expectedAmount > remainingAmount ? remainingAmount : expectedAmount;
+ size_t actualAmount = GuestReadWriteMemoryPage(curAddr, expectedAmount, rb8, wb8);
+ curAddr += actualAmount;
+ rb8 += actualAmount;
+ wb8 += actualAmount;
+ remainingAmount -= actualAmount;
+ if (actualAmount != expectedAmount) {
+ break;
+ }
+ }
+ return curAddr - addr;
+ }
+
+}
diff --git a/thermosphere/src/guest_memory.h b/thermosphere/src/hvisor_guest_memory.hpp
similarity index 56%
rename from thermosphere/src/guest_memory.h
rename to thermosphere/src/hvisor_guest_memory.hpp
index a071b87e6..884aa233d 100644
--- a/thermosphere/src/guest_memory.h
+++ b/thermosphere/src/hvisor_guest_memory.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 Atmosphère-NX
+ * Copyright (c) 2019-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -16,16 +16,20 @@
#pragma once
-#include "utils.h"
+#include "defines.hpp"
-size_t guestReadWriteMemory(uintptr_t addr, size_t size, void *readBuf, const void *writeBuf);
+namespace ams::hvisor {
+
+ size_t GuestReadWriteMemory(uintptr_t addr, size_t size, void *readBuf, const void *writeBuf);
+
+ inline size_t GuestReadMemory(uintptr_t addr, size_t size, void *buf)
+ {
+ return GuestReadWriteMemory(addr, size, buf, NULL);
+ }
+
+ inline size_t GuestWriteMemory(uintptr_t addr, size_t size, const void *buf)
+ {
+ return GuestReadWriteMemory(addr, size, NULL, buf);
+ }
-static inline size_t guestReadMemory(uintptr_t addr, size_t size, void *buf)
-{
- return guestReadWriteMemory(addr, size, buf, NULL);
-}
-
-static inline size_t guestWriteMemory(uintptr_t addr, size_t size, const void *buf)
-{
- return guestReadWriteMemory(addr, size, NULL, buf);
}
diff --git a/thermosphere/src/hvisor_memory_map.cpp b/thermosphere/src/hvisor_memory_map.cpp
index f2e661dc1..d6f672a43 100644
--- a/thermosphere/src/hvisor_memory_map.cpp
+++ b/thermosphere/src/hvisor_memory_map.cpp
@@ -21,8 +21,6 @@
#include "cpu/hvisor_cpu_mmu.hpp"
#include "cpu/hvisor_cpu_instructions.hpp"
-#include "platform/interrupt_config.h" // TODO remove
-
namespace ams::hvisor {
uintptr_t MemoryMap::currentPlatformMmioPage = MemoryMap::mmioPlatBaseVa;
@@ -176,7 +174,7 @@ namespace ams::hvisor {
isb();
}
- uintptr_t MemoryMap::UnmapGuestPage()
+ void MemoryMap::UnmapGuestPage()
{
using namespace cpu;
using Builder = MmuTableBuilder<3, addressSpaceSize, true>;
diff --git a/thermosphere/src/hvisor_memory_map.hpp b/thermosphere/src/hvisor_memory_map.hpp
index 9676e6979..28127c638 100644
--- a/thermosphere/src/hvisor_memory_map.hpp
+++ b/thermosphere/src/hvisor_memory_map.hpp
@@ -85,7 +85,7 @@ namespace ams::hvisor {
// Caller is expected to disable interrupts, etc, etc.
static uintptr_t MapGuestPage(uintptr_t pa, u64 memAttribs, u64 shareability);
- static uintptr_t UnmapGuestPage();
+ static void UnmapGuestPage();
public:
constexpr MemoryMap() = delete;
diff --git a/thermosphere/src/hvisor_sw_breakpoint_manager.cpp b/thermosphere/src/hvisor_sw_breakpoint_manager.cpp
index 18c7fb4a3..84bd875ec 100644
--- a/thermosphere/src/hvisor_sw_breakpoint_manager.cpp
+++ b/thermosphere/src/hvisor_sw_breakpoint_manager.cpp
@@ -16,13 +16,12 @@
#include "hvisor_sw_breakpoint_manager.hpp"
#include "hvisor_core_context.hpp"
+#include "hvisor_guest_memory.hpp"
#include "cpu/hvisor_cpu_instructions.hpp"
#include "cpu/hvisor_cpu_interrupt_mask_guard.hpp"
#include
-#include "guest_memory.h"
-
#define _REENT_ONLY
#include
@@ -59,7 +58,7 @@ namespace ams::hvisor {
Breakpoint &bp = m_breakpoints[id];
u32 brkInst = 0xD4200000 | (bp.uid << 5);
- size_t sz = guestReadWriteMemory(bp.address, 4, &bp.savedInstruction, &brkInst);
+ size_t sz = GuestReadWriteMemory(bp.address, 4, &bp.savedInstruction, &brkInst);
bp.applied = sz == 4;
return sz == 4;
}
@@ -67,7 +66,7 @@ namespace ams::hvisor {
bool SwBreakpointManager::DoRevert(size_t id)
{
Breakpoint &bp = m_breakpoints[id];
- size_t sz = guestWriteMemory(bp.address, 4, &bp.savedInstruction);
+ size_t sz = GuestWriteMemory(bp.address, 4, &bp.savedInstruction);
bp.applied = sz != 4;
return sz == 4;
}