accel/tcg: Properly implement get_page_addr_code for user-only
The current implementation is a no-op, simply returning addr. This is incorrect, because we ought to be checking the page permissions for execution. Make get_page_addr_code inline for both implementations. Acked-by: Ilya Leoshkevich <iii@linux.ibm.com> Tested-by: Ilya Leoshkevich <iii@linux.ibm.com> Acked-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
		| @@ -1544,11 +1544,6 @@ tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr, | ||||
|     return qemu_ram_addr_from_host_nofail(p); | ||||
| } | ||||
|  | ||||
| tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr) | ||||
| { | ||||
|     return get_page_addr_code_hostp(env, addr, NULL); | ||||
| } | ||||
|  | ||||
| static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size, | ||||
|                            CPUIOTLBEntry *iotlbentry, uintptr_t retaddr) | ||||
| { | ||||
|   | ||||
| @@ -199,6 +199,20 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size, | ||||
|     return size ? g2h(env_cpu(env), addr) : NULL; | ||||
| } | ||||
|  | ||||
| tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr, | ||||
|                                         void **hostp) | ||||
| { | ||||
|     int flags; | ||||
|  | ||||
|     flags = probe_access_internal(env, addr, 1, MMU_INST_FETCH, false, 0); | ||||
|     g_assert(flags == 0); | ||||
|  | ||||
|     if (hostp) { | ||||
|         *hostp = g2h_untagged(addr); | ||||
|     } | ||||
|     return addr; | ||||
| } | ||||
|  | ||||
| /* The softmmu versions of these helpers are in cputlb.c.  */ | ||||
|  | ||||
| /* | ||||
|   | ||||
| @@ -598,43 +598,44 @@ struct MemoryRegionSection *iotlb_to_section(CPUState *cpu, | ||||
|                                              hwaddr index, MemTxAttrs attrs); | ||||
| #endif | ||||
|  | ||||
| #if defined(CONFIG_USER_ONLY) | ||||
| void mmap_lock(void); | ||||
| void mmap_unlock(void); | ||||
| bool have_mmap_lock(void); | ||||
|  | ||||
| /** | ||||
|  * get_page_addr_code() - user-mode version | ||||
|  * get_page_addr_code_hostp() | ||||
|  * @env: CPUArchState | ||||
|  * @addr: guest virtual address of guest code | ||||
|  * | ||||
|  * Returns @addr. | ||||
|  * See get_page_addr_code() (full-system version) for documentation on the | ||||
|  * return value. | ||||
|  * | ||||
|  * Sets *@hostp (when @hostp is non-NULL) as follows. | ||||
|  * If the return value is -1, sets *@hostp to NULL. Otherwise, sets *@hostp | ||||
|  * to the host address where @addr's content is kept. | ||||
|  * | ||||
|  * Note: this function can trigger an exception. | ||||
|  */ | ||||
| tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr, | ||||
|                                         void **hostp); | ||||
|  | ||||
| /** | ||||
|  * get_page_addr_code() | ||||
|  * @env: CPUArchState | ||||
|  * @addr: guest virtual address of guest code | ||||
|  * | ||||
|  * If we cannot translate and execute from the entire RAM page, or if | ||||
|  * the region is not backed by RAM, returns -1. Otherwise, returns the | ||||
|  * ram_addr_t corresponding to the guest code at @addr. | ||||
|  * | ||||
|  * Note: this function can trigger an exception. | ||||
|  */ | ||||
| static inline tb_page_addr_t get_page_addr_code(CPUArchState *env, | ||||
|                                                 target_ulong addr) | ||||
| { | ||||
|     return addr; | ||||
|     return get_page_addr_code_hostp(env, addr, NULL); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * get_page_addr_code_hostp() - user-mode version | ||||
|  * @env: CPUArchState | ||||
|  * @addr: guest virtual address of guest code | ||||
|  * | ||||
|  * Returns @addr. | ||||
|  * | ||||
|  * If @hostp is non-NULL, sets *@hostp to the host address where @addr's content | ||||
|  * is kept. | ||||
|  */ | ||||
| static inline tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, | ||||
|                                                       target_ulong addr, | ||||
|                                                       void **hostp) | ||||
| { | ||||
|     if (hostp) { | ||||
|         *hostp = g2h_untagged(addr); | ||||
|     } | ||||
|     return addr; | ||||
| } | ||||
| #if defined(CONFIG_USER_ONLY) | ||||
| void mmap_lock(void); | ||||
| void mmap_unlock(void); | ||||
| bool have_mmap_lock(void); | ||||
|  | ||||
| /** | ||||
|  * adjust_signal_pc: | ||||
| @@ -691,36 +692,6 @@ G_NORETURN void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr, | ||||
| static inline void mmap_lock(void) {} | ||||
| static inline void mmap_unlock(void) {} | ||||
|  | ||||
| /** | ||||
|  * get_page_addr_code() - full-system version | ||||
|  * @env: CPUArchState | ||||
|  * @addr: guest virtual address of guest code | ||||
|  * | ||||
|  * If we cannot translate and execute from the entire RAM page, or if | ||||
|  * the region is not backed by RAM, returns -1. Otherwise, returns the | ||||
|  * ram_addr_t corresponding to the guest code at @addr. | ||||
|  * | ||||
|  * Note: this function can trigger an exception. | ||||
|  */ | ||||
| tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr); | ||||
|  | ||||
| /** | ||||
|  * get_page_addr_code_hostp() - full-system version | ||||
|  * @env: CPUArchState | ||||
|  * @addr: guest virtual address of guest code | ||||
|  * | ||||
|  * See get_page_addr_code() (full-system version) for documentation on the | ||||
|  * return value. | ||||
|  * | ||||
|  * Sets *@hostp (when @hostp is non-NULL) as follows. | ||||
|  * If the return value is -1, sets *@hostp to NULL. Otherwise, sets *@hostp | ||||
|  * to the host address where @addr's content is kept. | ||||
|  * | ||||
|  * Note: this function can trigger an exception. | ||||
|  */ | ||||
| tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr, | ||||
|                                         void **hostp); | ||||
|  | ||||
| void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length); | ||||
| void tlb_set_dirty(CPUState *cpu, target_ulong vaddr); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user