mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
accel/tcg: Use vaddr in user/page-protection.h
Reviewed-by: Anton Johansson <anjo@rev.ng> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
e1c8eb8cfe
commit
5627d5c00a
2 changed files with 31 additions and 37 deletions
|
@ -161,7 +161,7 @@ typedef struct PageFlagsNode {
|
||||||
|
|
||||||
static IntervalTreeRoot pageflags_root;
|
static IntervalTreeRoot pageflags_root;
|
||||||
|
|
||||||
static PageFlagsNode *pageflags_find(target_ulong start, target_ulong last)
|
static PageFlagsNode *pageflags_find(vaddr start, vaddr last)
|
||||||
{
|
{
|
||||||
IntervalTreeNode *n;
|
IntervalTreeNode *n;
|
||||||
|
|
||||||
|
@ -169,8 +169,7 @@ static PageFlagsNode *pageflags_find(target_ulong start, target_ulong last)
|
||||||
return n ? container_of(n, PageFlagsNode, itree) : NULL;
|
return n ? container_of(n, PageFlagsNode, itree) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PageFlagsNode *pageflags_next(PageFlagsNode *p, target_ulong start,
|
static PageFlagsNode *pageflags_next(PageFlagsNode *p, vaddr start, vaddr last)
|
||||||
target_ulong last)
|
|
||||||
{
|
{
|
||||||
IntervalTreeNode *n;
|
IntervalTreeNode *n;
|
||||||
|
|
||||||
|
@ -215,14 +214,14 @@ static int dump_region(void *opaque, vaddr start, vaddr end, int prot)
|
||||||
/* dump memory mappings */
|
/* dump memory mappings */
|
||||||
void page_dump(FILE *f)
|
void page_dump(FILE *f)
|
||||||
{
|
{
|
||||||
const int length = sizeof(target_ulong) * 2;
|
const int length = sizeof(abi_ptr) * 2;
|
||||||
|
|
||||||
fprintf(f, "%-*s %-*s %-*s %s\n",
|
fprintf(f, "%-*s %-*s %-*s %s\n",
|
||||||
length, "start", length, "end", length, "size", "prot");
|
length, "start", length, "end", length, "size", "prot");
|
||||||
walk_memory_regions(f, dump_region);
|
walk_memory_regions(f, dump_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
int page_get_flags(target_ulong address)
|
int page_get_flags(vaddr address)
|
||||||
{
|
{
|
||||||
PageFlagsNode *p = pageflags_find(address, address);
|
PageFlagsNode *p = pageflags_find(address, address);
|
||||||
|
|
||||||
|
@ -245,7 +244,7 @@ int page_get_flags(target_ulong address)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A subroutine of page_set_flags: insert a new node for [start,last]. */
|
/* A subroutine of page_set_flags: insert a new node for [start,last]. */
|
||||||
static void pageflags_create(target_ulong start, target_ulong last, int flags)
|
static void pageflags_create(vaddr start, vaddr last, int flags)
|
||||||
{
|
{
|
||||||
PageFlagsNode *p = g_new(PageFlagsNode, 1);
|
PageFlagsNode *p = g_new(PageFlagsNode, 1);
|
||||||
|
|
||||||
|
@ -256,13 +255,13 @@ static void pageflags_create(target_ulong start, target_ulong last, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A subroutine of page_set_flags: remove everything in [start,last]. */
|
/* A subroutine of page_set_flags: remove everything in [start,last]. */
|
||||||
static bool pageflags_unset(target_ulong start, target_ulong last)
|
static bool pageflags_unset(vaddr start, vaddr last)
|
||||||
{
|
{
|
||||||
bool inval_tb = false;
|
bool inval_tb = false;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
PageFlagsNode *p = pageflags_find(start, last);
|
PageFlagsNode *p = pageflags_find(start, last);
|
||||||
target_ulong p_last;
|
vaddr p_last;
|
||||||
|
|
||||||
if (!p) {
|
if (!p) {
|
||||||
break;
|
break;
|
||||||
|
@ -301,8 +300,7 @@ static bool pageflags_unset(target_ulong start, target_ulong last)
|
||||||
* A subroutine of page_set_flags: nothing overlaps [start,last],
|
* A subroutine of page_set_flags: nothing overlaps [start,last],
|
||||||
* but check adjacent mappings and maybe merge into a single range.
|
* but check adjacent mappings and maybe merge into a single range.
|
||||||
*/
|
*/
|
||||||
static void pageflags_create_merge(target_ulong start, target_ulong last,
|
static void pageflags_create_merge(vaddr start, vaddr last, int flags)
|
||||||
int flags)
|
|
||||||
{
|
{
|
||||||
PageFlagsNode *next = NULL, *prev = NULL;
|
PageFlagsNode *next = NULL, *prev = NULL;
|
||||||
|
|
||||||
|
@ -353,11 +351,11 @@ static void pageflags_create_merge(target_ulong start, target_ulong last,
|
||||||
#define PAGE_STICKY (PAGE_ANON | PAGE_PASSTHROUGH | PAGE_TARGET_STICKY)
|
#define PAGE_STICKY (PAGE_ANON | PAGE_PASSTHROUGH | PAGE_TARGET_STICKY)
|
||||||
|
|
||||||
/* A subroutine of page_set_flags: add flags to [start,last]. */
|
/* A subroutine of page_set_flags: add flags to [start,last]. */
|
||||||
static bool pageflags_set_clear(target_ulong start, target_ulong last,
|
static bool pageflags_set_clear(vaddr start, vaddr last,
|
||||||
int set_flags, int clear_flags)
|
int set_flags, int clear_flags)
|
||||||
{
|
{
|
||||||
PageFlagsNode *p;
|
PageFlagsNode *p;
|
||||||
target_ulong p_start, p_last;
|
vaddr p_start, p_last;
|
||||||
int p_flags, merge_flags;
|
int p_flags, merge_flags;
|
||||||
bool inval_tb = false;
|
bool inval_tb = false;
|
||||||
|
|
||||||
|
@ -492,7 +490,7 @@ static bool pageflags_set_clear(target_ulong start, target_ulong last,
|
||||||
return inval_tb;
|
return inval_tb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void page_set_flags(target_ulong start, target_ulong last, int flags)
|
void page_set_flags(vaddr start, vaddr last, int flags)
|
||||||
{
|
{
|
||||||
bool reset = false;
|
bool reset = false;
|
||||||
bool inval_tb = false;
|
bool inval_tb = false;
|
||||||
|
@ -532,9 +530,9 @@ void page_set_flags(target_ulong start, target_ulong last, int flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool page_check_range(target_ulong start, target_ulong len, int flags)
|
bool page_check_range(vaddr start, vaddr len, int flags)
|
||||||
{
|
{
|
||||||
target_ulong last;
|
vaddr last;
|
||||||
int locked; /* tri-state: =0: unlocked, +1: global, -1: local */
|
int locked; /* tri-state: =0: unlocked, +1: global, -1: local */
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
|
@ -610,17 +608,16 @@ bool page_check_range(target_ulong start, target_ulong len, int flags)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool page_check_range_empty(target_ulong start, target_ulong last)
|
bool page_check_range_empty(vaddr start, vaddr last)
|
||||||
{
|
{
|
||||||
assert(last >= start);
|
assert(last >= start);
|
||||||
assert_memory_lock();
|
assert_memory_lock();
|
||||||
return pageflags_find(start, last) == NULL;
|
return pageflags_find(start, last) == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
target_ulong page_find_range_empty(target_ulong min, target_ulong max,
|
vaddr page_find_range_empty(vaddr min, vaddr max, vaddr len, vaddr align)
|
||||||
target_ulong len, target_ulong align)
|
|
||||||
{
|
{
|
||||||
target_ulong len_m1, align_m1;
|
vaddr len_m1, align_m1;
|
||||||
|
|
||||||
assert(min <= max);
|
assert(min <= max);
|
||||||
assert(max <= GUEST_ADDR_MAX);
|
assert(max <= GUEST_ADDR_MAX);
|
||||||
|
@ -661,7 +658,7 @@ target_ulong page_find_range_empty(target_ulong min, target_ulong max,
|
||||||
void tb_lock_page0(tb_page_addr_t address)
|
void tb_lock_page0(tb_page_addr_t address)
|
||||||
{
|
{
|
||||||
PageFlagsNode *p;
|
PageFlagsNode *p;
|
||||||
target_ulong start, last;
|
vaddr start, last;
|
||||||
int host_page_size = qemu_real_host_page_size();
|
int host_page_size = qemu_real_host_page_size();
|
||||||
int prot;
|
int prot;
|
||||||
|
|
||||||
|
@ -740,7 +737,7 @@ int page_unprotect(CPUState *cpu, tb_page_addr_t address, uintptr_t pc)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int host_page_size = qemu_real_host_page_size();
|
int host_page_size = qemu_real_host_page_size();
|
||||||
target_ulong start, len, i;
|
vaddr start, len, i;
|
||||||
int prot;
|
int prot;
|
||||||
|
|
||||||
if (host_page_size <= TARGET_PAGE_SIZE) {
|
if (host_page_size <= TARGET_PAGE_SIZE) {
|
||||||
|
@ -756,7 +753,7 @@ int page_unprotect(CPUState *cpu, tb_page_addr_t address, uintptr_t pc)
|
||||||
prot = 0;
|
prot = 0;
|
||||||
|
|
||||||
for (i = 0; i < len; i += TARGET_PAGE_SIZE) {
|
for (i = 0; i < len; i += TARGET_PAGE_SIZE) {
|
||||||
target_ulong addr = start + i;
|
vaddr addr = start + i;
|
||||||
|
|
||||||
p = pageflags_find(addr, addr);
|
p = pageflags_find(addr, addr);
|
||||||
if (p) {
|
if (p) {
|
||||||
|
@ -883,7 +880,7 @@ typedef struct TargetPageDataNode {
|
||||||
|
|
||||||
static IntervalTreeRoot targetdata_root;
|
static IntervalTreeRoot targetdata_root;
|
||||||
|
|
||||||
void page_reset_target_data(target_ulong start, target_ulong last)
|
void page_reset_target_data(vaddr start, vaddr last)
|
||||||
{
|
{
|
||||||
IntervalTreeNode *n, *next;
|
IntervalTreeNode *n, *next;
|
||||||
|
|
||||||
|
@ -897,7 +894,7 @@ void page_reset_target_data(target_ulong start, target_ulong last)
|
||||||
n != NULL;
|
n != NULL;
|
||||||
n = next,
|
n = next,
|
||||||
next = next ? interval_tree_iter_next(n, start, last) : NULL) {
|
next = next ? interval_tree_iter_next(n, start, last) : NULL) {
|
||||||
target_ulong n_start, n_last, p_ofs, p_len;
|
vaddr n_start, n_last, p_ofs, p_len;
|
||||||
TargetPageDataNode *t = container_of(n, TargetPageDataNode, itree);
|
TargetPageDataNode *t = container_of(n, TargetPageDataNode, itree);
|
||||||
|
|
||||||
if (n->start >= start && n->last <= last) {
|
if (n->start >= start && n->last <= last) {
|
||||||
|
@ -921,11 +918,11 @@ void page_reset_target_data(target_ulong start, target_ulong last)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *page_get_target_data(target_ulong address)
|
void *page_get_target_data(vaddr address)
|
||||||
{
|
{
|
||||||
IntervalTreeNode *n;
|
IntervalTreeNode *n;
|
||||||
TargetPageDataNode *t;
|
TargetPageDataNode *t;
|
||||||
target_ulong page, region, p_ofs;
|
vaddr page, region, p_ofs;
|
||||||
|
|
||||||
page = address & TARGET_PAGE_MASK;
|
page = address & TARGET_PAGE_MASK;
|
||||||
region = address & TBD_MASK;
|
region = address & TBD_MASK;
|
||||||
|
@ -956,7 +953,7 @@ void *page_get_target_data(target_ulong address)
|
||||||
return t->data + p_ofs * TARGET_PAGE_DATA_SIZE;
|
return t->data + p_ofs * TARGET_PAGE_DATA_SIZE;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void page_reset_target_data(target_ulong start, target_ulong last) { }
|
void page_reset_target_data(vaddr start, vaddr last) { }
|
||||||
#endif /* TARGET_PAGE_DATA_SIZE */
|
#endif /* TARGET_PAGE_DATA_SIZE */
|
||||||
|
|
||||||
/* The system-mode versions of these helpers are in cputlb.c. */
|
/* The system-mode versions of these helpers are in cputlb.c. */
|
||||||
|
|
|
@ -12,14 +12,12 @@
|
||||||
#error Cannot include this header from system emulation
|
#error Cannot include this header from system emulation
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "cpu-param.h"
|
|
||||||
#include "exec/target_long.h"
|
|
||||||
#include "exec/vaddr.h"
|
#include "exec/vaddr.h"
|
||||||
#include "exec/translation-block.h"
|
#include "exec/translation-block.h"
|
||||||
|
|
||||||
int page_unprotect(CPUState *cpu, tb_page_addr_t address, uintptr_t pc);
|
int page_unprotect(CPUState *cpu, tb_page_addr_t address, uintptr_t pc);
|
||||||
|
|
||||||
int page_get_flags(target_ulong address);
|
int page_get_flags(vaddr address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* page_set_flags:
|
* page_set_flags:
|
||||||
|
@ -32,9 +30,9 @@ int page_get_flags(target_ulong address);
|
||||||
* The flag PAGE_WRITE_ORG is positioned automatically depending
|
* The flag PAGE_WRITE_ORG is positioned automatically depending
|
||||||
* on PAGE_WRITE. The mmap_lock should already be held.
|
* on PAGE_WRITE. The mmap_lock should already be held.
|
||||||
*/
|
*/
|
||||||
void page_set_flags(target_ulong start, target_ulong last, int flags);
|
void page_set_flags(vaddr start, vaddr last, int flags);
|
||||||
|
|
||||||
void page_reset_target_data(target_ulong start, target_ulong last);
|
void page_reset_target_data(vaddr start, vaddr last);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* page_check_range
|
* page_check_range
|
||||||
|
@ -46,7 +44,7 @@ void page_reset_target_data(target_ulong start, target_ulong last);
|
||||||
* Return false if any page is unmapped. Thus testing flags == 0 is
|
* Return false if any page is unmapped. Thus testing flags == 0 is
|
||||||
* equivalent to testing for flags == PAGE_VALID.
|
* equivalent to testing for flags == PAGE_VALID.
|
||||||
*/
|
*/
|
||||||
bool page_check_range(target_ulong start, target_ulong last, int flags);
|
bool page_check_range(vaddr start, vaddr last, int flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* page_check_range_empty:
|
* page_check_range_empty:
|
||||||
|
@ -58,7 +56,7 @@ bool page_check_range(target_ulong start, target_ulong last, int flags);
|
||||||
* The memory lock must be held so that the caller will can ensure
|
* The memory lock must be held so that the caller will can ensure
|
||||||
* the result stays true until a new mapping can be installed.
|
* the result stays true until a new mapping can be installed.
|
||||||
*/
|
*/
|
||||||
bool page_check_range_empty(target_ulong start, target_ulong last);
|
bool page_check_range_empty(vaddr start, vaddr last);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* page_find_range_empty
|
* page_find_range_empty
|
||||||
|
@ -72,8 +70,7 @@ bool page_check_range_empty(target_ulong start, target_ulong last);
|
||||||
* The memory lock must be held, as the caller will want to ensure
|
* The memory lock must be held, as the caller will want to ensure
|
||||||
* the returned range stays empty until a new mapping can be installed.
|
* the returned range stays empty until a new mapping can be installed.
|
||||||
*/
|
*/
|
||||||
target_ulong page_find_range_empty(target_ulong min, target_ulong max,
|
vaddr page_find_range_empty(vaddr min, vaddr max, vaddr len, vaddr align);
|
||||||
target_ulong len, target_ulong align);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* page_get_target_data(address)
|
* page_get_target_data(address)
|
||||||
|
@ -87,7 +84,7 @@ target_ulong page_find_range_empty(target_ulong min, target_ulong max,
|
||||||
* e.g. with the munmap system call.
|
* e.g. with the munmap system call.
|
||||||
*/
|
*/
|
||||||
__attribute__((returns_nonnull))
|
__attribute__((returns_nonnull))
|
||||||
void *page_get_target_data(target_ulong address);
|
void *page_get_target_data(vaddr address);
|
||||||
|
|
||||||
typedef int (*walk_memory_regions_fn)(void *, vaddr, vaddr, int);
|
typedef int (*walk_memory_regions_fn)(void *, vaddr, vaddr, int);
|
||||||
int walk_memory_regions(void *, walk_memory_regions_fn);
|
int walk_memory_regions(void *, walk_memory_regions_fn);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue