diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-02-17 11:04:00 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-02-17 11:04:01 +0000 |
commit | 65d6ae4927d2974bcfe9326c3fdfa0fac5c6295b (patch) | |
tree | 776b9e34b1d6916a9672b8af112c1c03dc65acad /accel | |
parent | 18543229fd7a2c79dcd6818c7b1f0f62512b5220 (diff) | |
parent | 59c7a187dd8bd8ef675768dd8af9de11528ea7e2 (diff) |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20210217' into staging
target-arm queue:
* Support ARMv8.5-MemTag for linux-user
* ncpm7xx: Support SMBus
* MAINTAINERS: add section for Clock framework
# gpg: Signature made Wed 17 Feb 2021 11:01:45 GMT
# gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg: issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE
* remotes/pmaydell/tags/pull-target-arm-20210217: (37 commits)
MAINTAINERS: add myself maintainer for the clock framework
hw/i2c: Implement NPCM7XX SMBus Module FIFO Mode
hw/i2c: Add a QTest for NPCM7XX SMBus Device
hw/arm: Add I2C sensors and EEPROM for GSJ machine
hw/arm: Add I2C sensors for NPCM750 eval board
hw/i2c: Implement NPCM7XX SMBus Module Single Mode
tests/tcg/aarch64: Add mte smoke tests
target/arm: Enable MTE for user-only
target/arm: Add allocation tag storage for user mode
linux-user/aarch64: Signal SEGV_MTEAERR for async tag check error
linux-user/aarch64: Signal SEGV_MTESERR for sync tag check fault
linux-user/aarch64: Pass syndrome to EXC_*_ABORT
target/arm: Split out syndrome.h from internals.h
linux-user/aarch64: Implement PROT_MTE
linux-user/aarch64: Implement PR_MTE_TCF and PR_MTE_TAG
target/arm: Use the proper TBI settings for linux-user
target/arm: Improve gen_top_byte_ignore
linux-user/aarch64: Implement PR_TAGGED_ADDR_ENABLE
linux-user: Handle tags in lock_user/unlock_user
linux-user: Fix types in uaccess.c
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'accel')
-rw-r--r-- | accel/tcg/translate-all.c | 32 | ||||
-rw-r--r-- | accel/tcg/user-exec.c | 51 |
2 files changed, 56 insertions, 27 deletions
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 81d4c83f22..2c34adccce 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -114,6 +114,7 @@ typedef struct PageDesc { unsigned int code_write_count; #else unsigned long flags; + void *target_data; #endif #ifndef CONFIG_USER_ONLY QemuSpin lock; @@ -1761,7 +1762,7 @@ static inline void tb_page_add(PageDesc *p, TranslationBlock *tb, prot |= p2->flags; p2->flags &= ~PAGE_WRITE; } - mprotect(g2h(page_addr), qemu_host_page_size, + mprotect(g2h_untagged(page_addr), qemu_host_page_size, (prot & PAGE_BITS) & ~PAGE_WRITE); if (DEBUG_TB_INVALIDATE_GATE) { printf("protecting code page: 0x" TB_PAGE_ADDR_FMT "\n", page_addr); @@ -2740,6 +2741,7 @@ int page_get_flags(target_ulong address) void page_set_flags(target_ulong start, target_ulong end, int flags) { target_ulong addr, len; + bool reset_target_data; /* This function should never be called with addresses outside the guest address space. If this assert fires, it probably indicates @@ -2754,6 +2756,8 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) if (flags & PAGE_WRITE) { flags |= PAGE_WRITE_ORG; } + reset_target_data = !(flags & PAGE_VALID) || (flags & PAGE_RESET); + flags &= ~PAGE_RESET; for (addr = start, len = end - start; len != 0; @@ -2767,10 +2771,34 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) p->first_tb) { tb_invalidate_phys_page(addr, 0); } + if (reset_target_data && p->target_data) { + g_free(p->target_data); + p->target_data = NULL; + } p->flags = flags; } } +void *page_get_target_data(target_ulong address) +{ + PageDesc *p = page_find(address >> TARGET_PAGE_BITS); + return p ? p->target_data : NULL; +} + +void *page_alloc_target_data(target_ulong address, size_t size) +{ + PageDesc *p = page_find(address >> TARGET_PAGE_BITS); + void *ret = NULL; + + if (p->flags & PAGE_VALID) { + ret = p->target_data; + if (!ret) { + p->target_data = ret = g_malloc0(size); + } + } + return ret; +} + int page_check_range(target_ulong start, target_ulong len, int flags) { PageDesc *p; @@ -2884,7 +2912,7 @@ int page_unprotect(target_ulong address, uintptr_t pc) } #endif } - mprotect((void *)g2h(host_start), qemu_host_page_size, + mprotect((void *)g2h_untagged(host_start), qemu_host_page_size, prot & PAGE_BITS); } mmap_unlock(); diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 0b6f56ca40..0d8cc27b21 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -213,7 +213,8 @@ static int probe_access_internal(CPUArchState *env, target_ulong addr, g_assert_not_reached(); } - if (!guest_addr_valid(addr) || page_check_range(addr, 1, flags) < 0) { + if (!guest_addr_valid_untagged(addr) || + page_check_range(addr, 1, flags) < 0) { if (nonfault) { return TLB_INVALID_MASK; } else { @@ -234,7 +235,7 @@ int probe_access_flags(CPUArchState *env, target_ulong addr, int flags; flags = probe_access_internal(env, addr, 0, access_type, nonfault, ra); - *phost = flags ? NULL : g2h(addr); + *phost = flags ? NULL : g2h(env_cpu(env), addr); return flags; } @@ -247,7 +248,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size, flags = probe_access_internal(env, addr, size, access_type, false, ra); g_assert(flags == 0); - return size ? g2h(addr) : NULL; + return size ? g2h(env_cpu(env), addr) : NULL; } #if defined(__i386__) @@ -842,7 +843,7 @@ uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr ptr) uint16_t meminfo = trace_mem_get_info(MO_UB, MMU_USER_IDX, false); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - ret = ldub_p(g2h(ptr)); + ret = ldub_p(g2h(env_cpu(env), ptr)); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); return ret; } @@ -853,7 +854,7 @@ int cpu_ldsb_data(CPUArchState *env, abi_ptr ptr) uint16_t meminfo = trace_mem_get_info(MO_SB, MMU_USER_IDX, false); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - ret = ldsb_p(g2h(ptr)); + ret = ldsb_p(g2h(env_cpu(env), ptr)); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); return ret; } @@ -864,7 +865,7 @@ uint32_t cpu_lduw_be_data(CPUArchState *env, abi_ptr ptr) uint16_t meminfo = trace_mem_get_info(MO_BEUW, MMU_USER_IDX, false); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - ret = lduw_be_p(g2h(ptr)); + ret = lduw_be_p(g2h(env_cpu(env), ptr)); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); return ret; } @@ -875,7 +876,7 @@ int cpu_ldsw_be_data(CPUArchState *env, abi_ptr ptr) uint16_t meminfo = trace_mem_get_info(MO_BESW, MMU_USER_IDX, false); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - ret = ldsw_be_p(g2h(ptr)); + ret = ldsw_be_p(g2h(env_cpu(env), ptr)); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); return ret; } @@ -886,7 +887,7 @@ uint32_t cpu_ldl_be_data(CPUArchState *env, abi_ptr ptr) uint16_t meminfo = trace_mem_get_info(MO_BEUL, MMU_USER_IDX, false); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - ret = ldl_be_p(g2h(ptr)); + ret = ldl_be_p(g2h(env_cpu(env), ptr)); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); return ret; } @@ -897,7 +898,7 @@ uint64_t cpu_ldq_be_data(CPUArchState *env, abi_ptr ptr) uint16_t meminfo = trace_mem_get_info(MO_BEQ, MMU_USER_IDX, false); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - ret = ldq_be_p(g2h(ptr)); + ret = ldq_be_p(g2h(env_cpu(env), ptr)); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); return ret; } @@ -908,7 +909,7 @@ uint32_t cpu_lduw_le_data(CPUArchState *env, abi_ptr ptr) uint16_t meminfo = trace_mem_get_info(MO_LEUW, MMU_USER_IDX, false); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - ret = lduw_le_p(g2h(ptr)); + ret = lduw_le_p(g2h(env_cpu(env), ptr)); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); return ret; } @@ -919,7 +920,7 @@ int cpu_ldsw_le_data(CPUArchState *env, abi_ptr ptr) uint16_t meminfo = trace_mem_get_info(MO_LESW, MMU_USER_IDX, false); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - ret = ldsw_le_p(g2h(ptr)); + ret = ldsw_le_p(g2h(env_cpu(env), ptr)); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); return ret; } @@ -930,7 +931,7 @@ uint32_t cpu_ldl_le_data(CPUArchState *env, abi_ptr ptr) uint16_t meminfo = trace_mem_get_info(MO_LEUL, MMU_USER_IDX, false); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - ret = ldl_le_p(g2h(ptr)); + ret = ldl_le_p(g2h(env_cpu(env), ptr)); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); return ret; } @@ -941,7 +942,7 @@ uint64_t cpu_ldq_le_data(CPUArchState *env, abi_ptr ptr) uint16_t meminfo = trace_mem_get_info(MO_LEQ, MMU_USER_IDX, false); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - ret = ldq_le_p(g2h(ptr)); + ret = ldq_le_p(g2h(env_cpu(env), ptr)); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); return ret; } @@ -1051,7 +1052,7 @@ void cpu_stb_data(CPUArchState *env, abi_ptr ptr, uint32_t val) uint16_t meminfo = trace_mem_get_info(MO_UB, MMU_USER_IDX, true); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - stb_p(g2h(ptr), val); + stb_p(g2h(env_cpu(env), ptr), val); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); } @@ -1060,7 +1061,7 @@ void cpu_stw_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val) uint16_t meminfo = trace_mem_get_info(MO_BEUW, MMU_USER_IDX, true); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - stw_be_p(g2h(ptr), val); + stw_be_p(g2h(env_cpu(env), ptr), val); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); } @@ -1069,7 +1070,7 @@ void cpu_stl_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val) uint16_t meminfo = trace_mem_get_info(MO_BEUL, MMU_USER_IDX, true); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - stl_be_p(g2h(ptr), val); + stl_be_p(g2h(env_cpu(env), ptr), val); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); } @@ -1078,7 +1079,7 @@ void cpu_stq_be_data(CPUArchState *env, abi_ptr ptr, uint64_t val) uint16_t meminfo = trace_mem_get_info(MO_BEQ, MMU_USER_IDX, true); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - stq_be_p(g2h(ptr), val); + stq_be_p(g2h(env_cpu(env), ptr), val); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); } @@ -1087,7 +1088,7 @@ void cpu_stw_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val) uint16_t meminfo = trace_mem_get_info(MO_LEUW, MMU_USER_IDX, true); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - stw_le_p(g2h(ptr), val); + stw_le_p(g2h(env_cpu(env), ptr), val); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); } @@ -1096,7 +1097,7 @@ void cpu_stl_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val) uint16_t meminfo = trace_mem_get_info(MO_LEUL, MMU_USER_IDX, true); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - stl_le_p(g2h(ptr), val); + stl_le_p(g2h(env_cpu(env), ptr), val); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); } @@ -1105,7 +1106,7 @@ void cpu_stq_le_data(CPUArchState *env, abi_ptr ptr, uint64_t val) uint16_t meminfo = trace_mem_get_info(MO_LEQ, MMU_USER_IDX, true); trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo); - stq_le_p(g2h(ptr), val); + stq_le_p(g2h(env_cpu(env), ptr), val); qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo); } @@ -1170,7 +1171,7 @@ uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr ptr) uint32_t ret; set_helper_retaddr(1); - ret = ldub_p(g2h(ptr)); + ret = ldub_p(g2h_untagged(ptr)); clear_helper_retaddr(); return ret; } @@ -1180,7 +1181,7 @@ uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr ptr) uint32_t ret; set_helper_retaddr(1); - ret = lduw_p(g2h(ptr)); + ret = lduw_p(g2h_untagged(ptr)); clear_helper_retaddr(); return ret; } @@ -1190,7 +1191,7 @@ uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr ptr) uint32_t ret; set_helper_retaddr(1); - ret = ldl_p(g2h(ptr)); + ret = ldl_p(g2h_untagged(ptr)); clear_helper_retaddr(); return ret; } @@ -1200,7 +1201,7 @@ uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr ptr) uint64_t ret; set_helper_retaddr(1); - ret = ldq_p(g2h(ptr)); + ret = ldq_p(g2h_untagged(ptr)); clear_helper_retaddr(); return ret; } @@ -1213,7 +1214,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr, if (unlikely(addr & (size - 1))) { cpu_loop_exit_atomic(env_cpu(env), retaddr); } - void *ret = g2h(addr); + void *ret = g2h(env_cpu(env), addr); set_helper_retaddr(retaddr); return ret; } |