mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-26 20:03:54 -06:00
accel/tcg: Move cpu_memory_rw_debug() user implementation to user-exec.c
cpu_memory_rw_debug() system implementation is defined in system/physmem.c. Move the user one to accel/tcg/user-exec.c to simplify cpu-target.c maintenance. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20250217130610.18313-6-philmd@linaro.org>
This commit is contained in:
parent
eacd1f8445
commit
585d4b1229
2 changed files with 82 additions and 88 deletions
|
@ -19,6 +19,7 @@
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "accel/tcg/cpu-ops.h"
|
#include "accel/tcg/cpu-ops.h"
|
||||||
#include "disas/disas.h"
|
#include "disas/disas.h"
|
||||||
|
#include "exec/vaddr.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
#include "tcg/tcg.h"
|
#include "tcg/tcg.h"
|
||||||
#include "qemu/bitops.h"
|
#include "qemu/bitops.h"
|
||||||
|
@ -971,6 +972,85 @@ static void *cpu_mmu_lookup(CPUState *cpu, vaddr addr,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* physical memory access (slow version, mainly for debug) */
|
||||||
|
int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
|
||||||
|
void *ptr, size_t len, bool is_write)
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
vaddr l, page;
|
||||||
|
uint8_t *buf = ptr;
|
||||||
|
ssize_t written;
|
||||||
|
int ret = -1;
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
mmap_lock();
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
page = addr & TARGET_PAGE_MASK;
|
||||||
|
l = (page + TARGET_PAGE_SIZE) - addr;
|
||||||
|
if (l > len) {
|
||||||
|
l = len;
|
||||||
|
}
|
||||||
|
flags = page_get_flags(page);
|
||||||
|
if (!(flags & PAGE_VALID)) {
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
if (is_write) {
|
||||||
|
if (flags & PAGE_WRITE) {
|
||||||
|
memcpy(g2h(cpu, addr), buf, l);
|
||||||
|
} else {
|
||||||
|
/* Bypass the host page protection using ptrace. */
|
||||||
|
if (fd == -1) {
|
||||||
|
fd = open("/proc/self/mem", O_WRONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If there is a TranslationBlock and we weren't bypassing the
|
||||||
|
* host page protection, the memcpy() above would SEGV,
|
||||||
|
* ultimately leading to page_unprotect(). So invalidate the
|
||||||
|
* translations manually. Both invalidation and pwrite() must
|
||||||
|
* be under mmap_lock() in order to prevent the creation of
|
||||||
|
* another TranslationBlock in between.
|
||||||
|
*/
|
||||||
|
tb_invalidate_phys_range(addr, addr + l - 1);
|
||||||
|
written = pwrite(fd, buf, l,
|
||||||
|
(off_t)(uintptr_t)g2h_untagged(addr));
|
||||||
|
if (written != l) {
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (flags & PAGE_READ) {
|
||||||
|
memcpy(buf, g2h(cpu, addr), l);
|
||||||
|
} else {
|
||||||
|
/* Bypass the host page protection using ptrace. */
|
||||||
|
if (fd == -1) {
|
||||||
|
fd = open("/proc/self/mem", O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pread(fd, buf, l,
|
||||||
|
(off_t)(uintptr_t)g2h_untagged(addr)) != l) {
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
len -= l;
|
||||||
|
buf += l;
|
||||||
|
addr += l;
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
out_close:
|
||||||
|
if (fd != -1) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
mmap_unlock();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#include "ldst_atomicity.c.inc"
|
#include "ldst_atomicity.c.inc"
|
||||||
|
|
||||||
static uint8_t do_ld1_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
static uint8_t do_ld1_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
||||||
|
|
90
cpu-target.c
90
cpu-target.c
|
@ -19,18 +19,12 @@
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
|
||||||
#include "exec/target_page.h"
|
|
||||||
#include "exec/page-protection.h"
|
|
||||||
#include "hw/qdev-core.h"
|
#include "hw/qdev-core.h"
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/qemu-print.h"
|
#include "qemu/qemu-print.h"
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
#include "qemu.h"
|
|
||||||
#include "user/page-protection.h"
|
|
||||||
#else
|
|
||||||
#include "hw/core/sysemu-cpu-ops.h"
|
#include "hw/core/sysemu-cpu-ops.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
#include "exec/memory.h"
|
#include "exec/memory.h"
|
||||||
|
@ -43,11 +37,11 @@
|
||||||
#include "exec/cpu-common.h"
|
#include "exec/cpu-common.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
#include "exec/tb-flush.h"
|
#include "exec/tb-flush.h"
|
||||||
#include "exec/translation-block.h"
|
|
||||||
#include "exec/log.h"
|
#include "exec/log.h"
|
||||||
#include "accel/accel-cpu-target.h"
|
#include "accel/accel-cpu-target.h"
|
||||||
#include "trace/trace-root.h"
|
#include "trace/trace-root.h"
|
||||||
#include "qemu/accel.h"
|
#include "qemu/accel.h"
|
||||||
|
#include "hw/core/cpu.h"
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
static int cpu_common_post_load(void *opaque, int version_id)
|
static int cpu_common_post_load(void *opaque, int version_id)
|
||||||
|
@ -367,86 +361,6 @@ void cpu_abort(CPUState *cpu, const char *fmt, ...)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* physical memory access (slow version, mainly for debug) */
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
|
|
||||||
void *ptr, size_t len, bool is_write)
|
|
||||||
{
|
|
||||||
int flags;
|
|
||||||
vaddr l, page;
|
|
||||||
uint8_t *buf = ptr;
|
|
||||||
ssize_t written;
|
|
||||||
int ret = -1;
|
|
||||||
int fd = -1;
|
|
||||||
|
|
||||||
mmap_lock();
|
|
||||||
|
|
||||||
while (len > 0) {
|
|
||||||
page = addr & TARGET_PAGE_MASK;
|
|
||||||
l = (page + TARGET_PAGE_SIZE) - addr;
|
|
||||||
if (l > len)
|
|
||||||
l = len;
|
|
||||||
flags = page_get_flags(page);
|
|
||||||
if (!(flags & PAGE_VALID)) {
|
|
||||||
goto out_close;
|
|
||||||
}
|
|
||||||
if (is_write) {
|
|
||||||
if (flags & PAGE_WRITE) {
|
|
||||||
memcpy(g2h(cpu, addr), buf, l);
|
|
||||||
} else {
|
|
||||||
/* Bypass the host page protection using ptrace. */
|
|
||||||
if (fd == -1) {
|
|
||||||
fd = open("/proc/self/mem", O_WRONLY);
|
|
||||||
if (fd == -1) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* If there is a TranslationBlock and we weren't bypassing the
|
|
||||||
* host page protection, the memcpy() above would SEGV,
|
|
||||||
* ultimately leading to page_unprotect(). So invalidate the
|
|
||||||
* translations manually. Both invalidation and pwrite() must
|
|
||||||
* be under mmap_lock() in order to prevent the creation of
|
|
||||||
* another TranslationBlock in between.
|
|
||||||
*/
|
|
||||||
tb_invalidate_phys_range(addr, addr + l - 1);
|
|
||||||
written = pwrite(fd, buf, l,
|
|
||||||
(off_t)(uintptr_t)g2h_untagged(addr));
|
|
||||||
if (written != l) {
|
|
||||||
goto out_close;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (flags & PAGE_READ) {
|
|
||||||
memcpy(buf, g2h(cpu, addr), l);
|
|
||||||
} else {
|
|
||||||
/* Bypass the host page protection using ptrace. */
|
|
||||||
if (fd == -1) {
|
|
||||||
fd = open("/proc/self/mem", O_RDONLY);
|
|
||||||
if (fd == -1) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pread(fd, buf, l,
|
|
||||||
(off_t)(uintptr_t)g2h_untagged(addr)) != l) {
|
|
||||||
goto out_close;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
len -= l;
|
|
||||||
buf += l;
|
|
||||||
addr += l;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
out_close:
|
|
||||||
if (fd != -1) {
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
mmap_unlock();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool target_words_bigendian(void)
|
bool target_words_bigendian(void)
|
||||||
{
|
{
|
||||||
return TARGET_BIG_ENDIAN;
|
return TARGET_BIG_ENDIAN;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue