mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-23 18:56:03 +00:00
Fix user page mmu mapping and naming scheme
This commit is contained in:
parent
ab38217720
commit
4c7aa566f0
2 changed files with 31 additions and 30 deletions
|
@ -1,65 +1,70 @@
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "userpage.h"
|
#include "userpage.h"
|
||||||
#include "memory_map.h"
|
#include "memory_map.h"
|
||||||
|
#include "cache.h"
|
||||||
|
|
||||||
uint64_t g_secure_page_user_address = NULL;
|
static uintptr_t g_user_page_user_address = NULL;
|
||||||
|
|
||||||
|
static inline uintptr_t get_page_for_address(void *address) {
|
||||||
|
return ((uintptr_t)(address)) & ~0xFFF;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a user page reference for the desired address. */
|
/* Create a user page reference for the desired address. */
|
||||||
/* Returns 1 on success, 0 on failure. */
|
/* Returns 1 on success, 0 on failure. */
|
||||||
bool upage_init(upage_ref_t *upage, void *user_address) {
|
bool upage_init(upage_ref_t *upage, void *user_address) {
|
||||||
upage->user_page = get_page_for_address(user_address);
|
upage->user_address = get_page_for_address(user_address);
|
||||||
upage->secure_page = 0ULL;
|
upage->secure_monitor_address = 0ULL;
|
||||||
|
|
||||||
if (g_secure_page_user_address != NULL) {
|
if (g_user_page_user_address != NULL) {
|
||||||
/* Different physical address indicate SPL was rebooted, or another process got access to svcCallSecureMonitor. Panic. */
|
/* Different physical address indicate SPL was rebooted, or another process got access to svcCallSecureMonitor. Panic. */
|
||||||
if (g_secure_page_user_address != upage->user_page) {
|
if (g_user_page_user_address != upage->user_address) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
upage->secure_page = SECURE_USER_PAGE_ADDR;
|
upage->secure_monitor_address = USER_PAGE_SECURE_MONITOR_ADDR;
|
||||||
} else {
|
} else {
|
||||||
/* Weakly validate SPL's physically random address is in DRAM. */
|
/* Weakly validate SPL's physically random address is in DRAM. */
|
||||||
if (upage->user_page >> 31) {
|
if (upage->user_address >> 31) {
|
||||||
g_secure_page_user_address = upage->user_page;
|
static const userpage_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_NORMAL;
|
||||||
mmu_map_page_range(mmu_l3_tbl, tzram_get_segment_address(TZRAM_SEGMENT_ID_USERPAGE), upage->user_page, 0x1000, MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_NORMAL);
|
g_user_page_user_address = upage->user_address;
|
||||||
/* TODO: Invalidate the TLB to make this page readable. */
|
mmu_map_page(mmu_l3_tbl, USER_PAGE_SECURE_MONITOR_ADDR, upage->user_address, userpage_attributes);
|
||||||
upage->secure_page = SECURE_USER_PAGE_ADDR;
|
tlb_invalidate_page_inner_shareable((void *)USER_PAGE_SECURE_MONITOR_ADDR);
|
||||||
|
upage->secure_monitor_address = USER_PAGE_SECURE_MONITOR_ADDR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return upage->secure_page != 0ULL;
|
return upage->secure_monitor_address != 0ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool user_copy_to_secure(upage_ref_t *upage, void *secure_dst, void *user_src, size_t size) {
|
bool user_copy_to_secure(upage_ref_t *upage, void *secure_dst, void *user_src, size_t size) {
|
||||||
/* Fail if the page doesn't match. */
|
/* Fail if the page doesn't match. */
|
||||||
if (get_page_for_address(user_src) != upage->user_page) {
|
if (get_page_for_address(user_src) != upage->user_address) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fail if we go past the page boundary. */
|
/* Fail if we go past the page boundary. */
|
||||||
if (size != 0 && get_page_for_address(user_src + size - 1) != upage->user_page) {
|
if (size != 0 && get_page_for_address(user_src + size - 1) != upage->user_address) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *secure_src = (void *)(upage->secure_page + ((uint64_t)user_src - upage->user_page));
|
void *secure_src = (void *)(upage->secure_monitor_address + ((uintptr_t)user_src - upage->user_address));
|
||||||
memcpy(secure_dst, secure_src, size);
|
memcpy(secure_dst, secure_src, size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool secure_copy_to_user(upage_ref_t *upage, void *user_dst, void *secure_src, size_t size) {
|
bool secure_copy_to_user(upage_ref_t *upage, void *user_dst, void *secure_src, size_t size) {
|
||||||
/* Fail if the page doesn't match. */
|
/* Fail if the page doesn't match. */
|
||||||
if (get_page_for_address(user_dst) != upage->user_page) {
|
if (get_page_for_address(user_dst) != upage->user_address) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fail if we go past the page boundary. */
|
/* Fail if we go past the page boundary. */
|
||||||
if (size != 0 && get_page_for_address(user_dst + size - 1) != upage->user_page) {
|
if (size != 0 && get_page_for_address(user_dst + size - 1) != upage->user_address) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *secure_dst = (void *)(upage->secure_page + ((uint64_t)user_dst - upage->user_page));
|
void *secure_dst = (void *)(upage->secure_monitor_address + ((uintptr_t)user_dst - upage->user_address));
|
||||||
memcpy(secure_dst, secure_src, size);
|
memcpy(secure_dst, secure_src, size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
#ifndef EXOSPHERE_USERPAGE_H
|
#ifndef EXOSPHERE_USERPAGE_H
|
||||||
#define EXOSPHERE_USERPAGE_H
|
#define EXOSPHERE_USERPAGE_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include "utils.h"
|
||||||
#include <stdint.h>
|
#include "memory_map.h"
|
||||||
|
|
||||||
#define SECURE_USER_PAGE_ADDR (0x1F01F4000ULL)
|
#define USER_PAGE_SECURE_MONITOR_ADDR (tzram_get_segment_address(TZRAM_SEGMENT_ID_USERPAGE))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t user_page;
|
uintptr_t user_address;
|
||||||
uint64_t secure_page;
|
uintptr_t secure_monitor_address;
|
||||||
} upage_ref_t;
|
} upage_ref_t;
|
||||||
|
|
||||||
bool upage_init(upage_ref_t *user_page, void *user_address);
|
bool upage_init(upage_ref_t *user_page, void *user_address);
|
||||||
|
@ -16,8 +16,4 @@ bool upage_init(upage_ref_t *user_page, void *user_address);
|
||||||
bool user_copy_to_secure(upage_ref_t *user_page, void *secure_dst, void *user_src, size_t size);
|
bool user_copy_to_secure(upage_ref_t *user_page, void *secure_dst, void *user_src, size_t size);
|
||||||
bool secure_copy_to_user(upage_ref_t *user_page, void *user_dst, void *secure_src, size_t size);
|
bool secure_copy_to_user(upage_ref_t *user_page, void *user_dst, void *secure_src, size_t size);
|
||||||
|
|
||||||
static inline uint64_t get_page_for_address(void *address) {
|
|
||||||
return ((uint64_t)(address)) & 0xFFFFFFFFFFFFF000ULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in a new issue