diff options
| author | Philippe Mathieu-Daudé <philmd@linaro.org> | 2025-02-17 12:13:16 +0100 |
|---|---|---|
| committer | Philippe Mathieu-Daudé <philmd@linaro.org> | 2025-03-06 15:46:18 +0100 |
| commit | 585d4b122914b7be170eef147a0269cc233f0adc (patch) | |
| tree | 34373286e5b44ef5e9555abb766fe28188454061 /accel/tcg/user-exec.c | |
| parent | eacd1f8445fd033c3ce927e543be2818d0564130 (diff) | |
| download | focaccia-qemu-585d4b122914b7be170eef147a0269cc233f0adc.tar.gz focaccia-qemu-585d4b122914b7be170eef147a0269cc233f0adc.zip | |
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>
Diffstat (limited to 'accel/tcg/user-exec.c')
| -rw-r--r-- | accel/tcg/user-exec.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 9d53c9440e..2322181b15 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "accel/tcg/cpu-ops.h" #include "disas/disas.h" +#include "exec/vaddr.h" #include "exec/exec-all.h" #include "tcg/tcg.h" #include "qemu/bitops.h" @@ -971,6 +972,85 @@ static void *cpu_mmu_lookup(CPUState *cpu, vaddr addr, 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" static uint8_t do_ld1_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi, |