From e96ac42b2e8f8ded790fd156ef5a5d55ac088acb Mon Sep 17 00:00:00 2001 From: "Takacs, Philipp" Date: Mon, 13 Feb 2023 15:07:40 +0100 Subject: [PATCH] Remove MMU hacks Unicorn has included some ugly hacks to provide a envirement where vaddr == paddr. These hacks where to use the full 64 bit mappings on x86 without init the mmu and some memory redirect for MIPS. The UC_TLB_CPU mode defaults to vaddr == paddr, therfor these hacks aren't required anymore. --- include/uc_priv.h | 4 --- qemu/target/arm/cpu.c | 1 - qemu/target/i386/cpu.c | 1 - qemu/target/i386/excp_helper.c | 7 +----- qemu/target/m68k/cpu.c | 1 - qemu/target/mips/cpu.c | 1 - qemu/target/mips/unicorn.c | 16 ------------ qemu/target/ppc/translate_init.inc.c | 1 - qemu/target/ppc/unicorn.c | 16 ------------ qemu/target/riscv/cpu.c | 1 - qemu/target/s390x/cpu.c | 1 - qemu/target/sparc/cpu.c | 1 - qemu/target/tricore/cpu.c | 1 - tests/unit/test_arm64.c | 1 + tests/unit/test_riscv.c | 1 + tests/unit/test_x86.c | 2 ++ uc.c | 37 ++++------------------------ 17 files changed, 10 insertions(+), 83 deletions(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index 1eb8f1a9..5b2bfed0 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -119,9 +119,6 @@ typedef MemoryRegion *(*uc_memory_map_io_t)(struct uc_struct *uc, // which interrupt should make emulation stop? typedef bool (*uc_args_int_t)(struct uc_struct *uc, int intno); -// some architecture redirect virtual memory to physical memory like Mips -typedef uint64_t (*uc_mem_redirect_t)(uint64_t address); - // validate if Unicorn supports hooking a given instruction typedef bool (*uc_insn_hook_validate)(uint32_t insn_enum); @@ -287,7 +284,6 @@ struct uc_struct { uc_args_uc_ram_size_ptr_t memory_map_ptr; uc_mem_unmap_t memory_unmap; uc_readonly_mem_t readonly_mem; - uc_mem_redirect_t mem_redirect; uc_cpus_init cpus_init; uc_target_page_init target_page; uc_softfloat_initialize softfloat_initialize; diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index 9bff7fff..bbcbe83f 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -2080,7 +2080,6 @@ void arm_cpu_class_init(struct uc_struct *uc, CPUClass *oc) cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug; cc->asidx_from_attrs = arm_asidx_from_attrs; cc->tcg_initialize = arm_translate_init; - cc->tlb_fill = arm_cpu_tlb_fill; cc->tlb_fill_cpu = arm_cpu_tlb_fill; cc->debug_excp_handler = arm_debug_excp_handler; cc->do_unaligned_access = arm_cpu_do_unaligned_access; diff --git a/qemu/target/i386/cpu.c b/qemu/target/i386/cpu.c index 56a0603c..826a89f8 100644 --- a/qemu/target/i386/cpu.c +++ b/qemu/target/i386/cpu.c @@ -5066,7 +5066,6 @@ static void x86_cpu_common_class_init(struct uc_struct *uc, CPUClass *oc, void * cc->cpu_exec_enter = x86_cpu_exec_enter; cc->cpu_exec_exit = x86_cpu_exec_exit; cc->tcg_initialize = tcg_x86_init; - cc->tlb_fill = x86_cpu_tlb_fill; cc->tlb_fill_cpu = x86_cpu_tlb_fill; } diff --git a/qemu/target/i386/excp_helper.c b/qemu/target/i386/excp_helper.c index 9a773bbb..cca25d32 100644 --- a/qemu/target/i386/excp_helper.c +++ b/qemu/target/i386/excp_helper.c @@ -635,12 +635,7 @@ do_check_protect_pse36: /* align to page_size */ pte &= PG_ADDRESS_MASK & ~(page_size - 1); page_offset = addr & (page_size - 1); - /* HACK allow full 64 bit mapping in u64 without paging */ - if (env->cr[0] & CR0_PG_MASK) { - paddr = get_hphys(cs, pte + page_offset, is_write1, &prot); - } else { - paddr = addr; - } + paddr = get_hphys(cs, pte + page_offset, is_write1, &prot); /* Even if 4MB pages, we map only one 4KB page in the cache to avoid filling it too fast */ diff --git a/qemu/target/m68k/cpu.c b/qemu/target/m68k/cpu.c index 19b31d93..e3dc9484 100644 --- a/qemu/target/m68k/cpu.c +++ b/qemu/target/m68k/cpu.c @@ -231,7 +231,6 @@ static void m68k_cpu_class_init(CPUClass *c) cc->do_interrupt = m68k_cpu_do_interrupt; cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt; cc->set_pc = m68k_cpu_set_pc; - cc->tlb_fill = m68k_cpu_tlb_fill; cc->tlb_fill_cpu = m68k_cpu_tlb_fill; cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug; cc->tcg_initialize = m68k_tcg_init; diff --git a/qemu/target/mips/cpu.c b/qemu/target/mips/cpu.c index 63c5cfa3..27ad1199 100644 --- a/qemu/target/mips/cpu.c +++ b/qemu/target/mips/cpu.c @@ -147,7 +147,6 @@ static void mips_cpu_class_init(CPUClass *c) cc->do_unaligned_access = mips_cpu_do_unaligned_access; cc->get_phys_page_debug = mips_cpu_get_phys_page_debug; cc->tcg_initialize = mips_tcg_init; - cc->tlb_fill = mips_cpu_tlb_fill; cc->tlb_fill_cpu = mips_cpu_tlb_fill; } diff --git a/qemu/target/mips/unicorn.c b/qemu/target/mips/unicorn.c index 792fb45e..fb91e9c1 100644 --- a/qemu/target/mips/unicorn.c +++ b/qemu/target/mips/unicorn.c @@ -17,21 +17,6 @@ typedef uint32_t mipsreg_t; MIPSCPU *cpu_mips_init(struct uc_struct *uc); -static uint64_t mips_mem_redirect(uint64_t address) -{ - // kseg0 range masks off high address bit - if (address >= 0x80000000 && address <= 0x9fffffff) - return address & 0x7fffffff; - - // kseg1 range masks off top 3 address bits - if (address >= 0xa0000000 && address <= 0xbfffffff) { - return address & 0x1fffffff; - } - - // no redirect - return address; -} - static void mips_set_pc(struct uc_struct *uc, uint64_t address) { ((CPUMIPSState *)uc->cpu->env_ptr)->active_tc.PC = address; @@ -272,7 +257,6 @@ void mipsel_uc_init(struct uc_struct *uc) uc->release = mips_release; uc->set_pc = mips_set_pc; uc->get_pc = mips_get_pc; - uc->mem_redirect = mips_mem_redirect; uc->cpus_init = mips_cpus_init; uc->cpu_context_size = offsetof(CPUMIPSState, end_reset_fields); uc_common_init(uc); diff --git a/qemu/target/ppc/translate_init.inc.c b/qemu/target/ppc/translate_init.inc.c index 02eaee0a..acedd2d1 100644 --- a/qemu/target/ppc/translate_init.inc.c +++ b/qemu/target/ppc/translate_init.inc.c @@ -10253,7 +10253,6 @@ static void ppc_cpu_class_init(struct uc_struct *uc, CPUClass *oc) cc->do_unaligned_access = ppc_cpu_do_unaligned_access; cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug; cc->tcg_initialize = ppc_translate_init; - cc->tlb_fill = ppc_cpu_tlb_fill; cc->tlb_fill_cpu = ppc_cpu_tlb_fill; cc->cpu_exec_enter = ppc_cpu_exec_enter; cc->cpu_exec_exit = ppc_cpu_exec_exit; diff --git a/qemu/target/ppc/unicorn.c b/qemu/target/ppc/unicorn.c index fc8e24f1..b3e75f7d 100644 --- a/qemu/target/ppc/unicorn.c +++ b/qemu/target/ppc/unicorn.c @@ -77,21 +77,6 @@ static inline int uc_ppc_store_msr(CPUPPCState *env, target_ulong value, return 0; } -static uint64_t ppc_mem_redirect(uint64_t address) -{ - /* // kseg0 range masks off high address bit - if (address >= 0x80000000 && address <= 0x9fffffff) - return address & 0x7fffffff; - - // kseg1 range masks off top 3 address bits - if (address >= 0xa0000000 && address <= 0xbfffffff) { - return address & 0x1fffffff; - }*/ - - // no redirect - return address; -} - static void ppc_set_pc(struct uc_struct *uc, uint64_t address) { ((CPUPPCState *)uc->cpu->env_ptr)->nip = address; @@ -435,7 +420,6 @@ void ppc_uc_init(struct uc_struct *uc) uc->release = ppc_release; uc->set_pc = ppc_set_pc; uc->get_pc = ppc_get_pc; - uc->mem_redirect = ppc_mem_redirect; uc->cpus_init = ppc_cpus_init; uc->cpu_context_size = offsetof(CPUPPCState, uc); uc_common_init(uc); diff --git a/qemu/target/riscv/cpu.c b/qemu/target/riscv/cpu.c index 6197abd0..6405abd4 100644 --- a/qemu/target/riscv/cpu.c +++ b/qemu/target/riscv/cpu.c @@ -307,7 +307,6 @@ static void riscv_cpu_class_init(struct uc_struct *uc, CPUClass *c, void *data) cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb; cc->do_unaligned_access = riscv_cpu_do_unaligned_access; cc->tcg_initialize = riscv_translate_init; - cc->tlb_fill = riscv_cpu_tlb_fill; cc->tlb_fill_cpu = riscv_cpu_tlb_fill; } diff --git a/qemu/target/s390x/cpu.c b/qemu/target/s390x/cpu.c index 00e50831..a9068715 100644 --- a/qemu/target/s390x/cpu.c +++ b/qemu/target/s390x/cpu.c @@ -233,7 +233,6 @@ static void s390_cpu_class_init(struct uc_struct *uc, CPUClass *oc) cc->debug_excp_handler = s390x_cpu_debug_excp_handler; cc->do_unaligned_access = s390x_cpu_do_unaligned_access; cc->tcg_initialize = s390x_translate_init; - cc->tlb_fill = s390_cpu_tlb_fill; cc->tlb_fill_cpu = s390_cpu_tlb_fill; // s390_cpu_model_class_register_props(oc); diff --git a/qemu/target/sparc/cpu.c b/qemu/target/sparc/cpu.c index 87b531f7..e1386a15 100644 --- a/qemu/target/sparc/cpu.c +++ b/qemu/target/sparc/cpu.c @@ -504,7 +504,6 @@ static void sparc_cpu_class_init(struct uc_struct *uc, CPUClass *oc) cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt; cc->set_pc = sparc_cpu_set_pc; cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; - cc->tlb_fill = sparc_cpu_tlb_fill; cc->tlb_fill_cpu = sparc_cpu_tlb_fill; cc->do_unaligned_access = sparc_cpu_do_unaligned_access; cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug; diff --git a/qemu/target/tricore/cpu.c b/qemu/target/tricore/cpu.c index b016c1a4..8a871f45 100644 --- a/qemu/target/tricore/cpu.c +++ b/qemu/target/tricore/cpu.c @@ -137,7 +137,6 @@ static void tricore_cpu_class_init(CPUClass *c) cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb; cc->get_phys_page_debug = tricore_cpu_get_phys_page_debug; - cc->tlb_fill = tricore_cpu_tlb_fill; cc->tlb_fill_cpu = tricore_cpu_tlb_fill; cc->tcg_initialize = tricore_tcg_init; } diff --git a/tests/unit/test_arm64.c b/tests/unit/test_arm64.c index 8fcc9f04..8a03945c 100644 --- a/tests/unit/test_arm64.c +++ b/tests/unit/test_arm64.c @@ -416,6 +416,7 @@ static void test_arm64_mmu(void) TEST_CHECK(data != NULL); OK(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); + OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU)); OK(uc_mem_map(uc, 0, 0x2000, UC_PROT_ALL)); OK(uc_mem_write(uc, 0, code, sizeof(code) - 1)); diff --git a/tests/unit/test_riscv.c b/tests/unit/test_riscv.c index 00dbc08d..7c66f89d 100644 --- a/tests/unit/test_riscv.c +++ b/tests/unit/test_riscv.c @@ -689,6 +689,7 @@ static void test_riscv_mmu(void) char code_s[] = "\xb7\x42\x41\x41" "\x9b\x82\x12\x14" "\x37\x63\x01\x00" "\x23\x20\x53\x00" "\x13\x00\x00\x00"; OK(uc_open(UC_ARCH_RISCV, UC_MODE_RISCV64, &uc)); + OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU)); OK(uc_hook_add(uc, &h, UC_HOOK_CODE, test_riscv_mmu_hook_code, NULL, 1, 0)); OK(uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL)); OK(uc_mem_map(uc, code_address, 0x1000, UC_PROT_ALL)); diff --git a/tests/unit/test_x86.c b/tests/unit/test_x86.c index 9edb5db7..e1cc9a5c 100644 --- a/tests/unit/test_x86.c +++ b/tests/unit/test_x86.c @@ -1090,6 +1090,7 @@ static void test_x86_correct_address_in_long_jump_hook(void) uc_hook hook; uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1); + OK(uc_ctl_tlb_mode(uc, UC_TLB_VIRTUAL)); OK(uc_hook_add(uc, &hook, UC_HOOK_MEM_UNMAPPED, test_x86_correct_address_in_long_jump_hook_callback, NULL, 1, 0)); @@ -1348,6 +1349,7 @@ static void test_x86_mmu(void) char code[] = "\xB8\x39\x00\x00\x00\x0F\x05\x48\x85\xC0\x74\x0F\xB8\x3C\x00\x00\x00\x48\x89\x04\x25\x00\x40\x00\x00\x0F\x05\xB9\x2A\x00\x00\x00\x48\x89\x0C\x25\x00\x40\x00\x00\xB8\x3C\x00\x00\x00\x0F\x05"; OK(uc_open(UC_ARCH_X86, UC_MODE_64, &uc)); + OK(uc_ctl_tlb_mode(uc, UC_TLB_CPU)); OK(uc_hook_add(uc, &h1, UC_HOOK_INSN, &test_x86_mmu_callback, &parrent_done, 1, 0, UC_X86_INS_SYSCALL)); OK(uc_context_alloc(uc, &context)); diff --git a/uc.c b/uc.c index da576f9f..b0326a01 100644 --- a/uc.c +++ b/uc.c @@ -230,6 +230,11 @@ static uc_err uc_init(uc_engine *uc) return UC_ERR_RESOURCE; } + // init tlb function + if (!uc->cpu->cc->tlb_fill) { + uc->set_tlb(uc, UC_TLB_CPU); + } + // init fpu softfloat uc->softfloat_initialize(); @@ -577,10 +582,6 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size) if (size > INT_MAX) return UC_ERR_ARG; - if (uc->mem_redirect) { - address = uc->mem_redirect(address); - } - if (!check_mem_area(uc, address, size)) { return UC_ERR_READ_UNMAPPED; } @@ -622,10 +623,6 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes, if (size > INT_MAX) return UC_ERR_ARG; - if (uc->mem_redirect) { - address = uc->mem_redirect(address); - } - if (!check_mem_area(uc, address, size)) { return UC_ERR_WRITE_UNMAPPED; } @@ -1039,10 +1036,6 @@ uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms) UC_INIT(uc); - if (uc->mem_redirect) { - address = uc->mem_redirect(address); - } - res = mem_map_check(uc, address, size, perms); if (res) { return res; @@ -1063,10 +1056,6 @@ uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, return UC_ERR_ARG; } - if (uc->mem_redirect) { - address = uc->mem_redirect(address); - } - res = mem_map_check(uc, address, size, perms); if (res) { return res; @@ -1084,10 +1073,6 @@ uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size, UC_INIT(uc); - if (uc->mem_redirect) { - address = uc->mem_redirect(address); - } - res = mem_map_check(uc, address, size, UC_PROT_ALL); if (res) return res; @@ -1387,10 +1372,6 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, return UC_ERR_ARG; } - if (uc->mem_redirect) { - address = uc->mem_redirect(address); - } - // check that user's entire requested block is mapped if (!check_mem_area(uc, address, size)) { return UC_ERR_NOMEM; @@ -1467,10 +1448,6 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size) return UC_ERR_ARG; } - if (uc->mem_redirect) { - address = uc->mem_redirect(address); - } - // check that user's entire requested block is mapped if (!check_mem_area(uc, address, size)) { return UC_ERR_NOMEM; @@ -1515,10 +1492,6 @@ MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address) return NULL; } - if (uc->mem_redirect) { - address = uc->mem_redirect(address); - } - // try with the cache index first i = uc->mapped_block_cache_index;