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);
 | 
					    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,
 | 
					static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size,
 | 
				
			||||||
                           CPUIOTLBEntry *iotlbentry, uintptr_t retaddr)
 | 
					                           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;
 | 
					    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.  */
 | 
					/* 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);
 | 
					                                             hwaddr index, MemTxAttrs attrs);
 | 
				
			||||||
#endif
 | 
					#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
 | 
					 * @env: CPUArchState
 | 
				
			||||||
 * @addr: guest virtual address of guest code
 | 
					 * @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,
 | 
					static inline tb_page_addr_t get_page_addr_code(CPUArchState *env,
 | 
				
			||||||
                                                target_ulong addr)
 | 
					                                                target_ulong addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return addr;
 | 
					    return get_page_addr_code_hostp(env, addr, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					#if defined(CONFIG_USER_ONLY)
 | 
				
			||||||
 * get_page_addr_code_hostp() - user-mode version
 | 
					void mmap_lock(void);
 | 
				
			||||||
 * @env: CPUArchState
 | 
					void mmap_unlock(void);
 | 
				
			||||||
 * @addr: guest virtual address of guest code
 | 
					bool have_mmap_lock(void);
 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * 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;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * adjust_signal_pc:
 | 
					 * 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_lock(void) {}
 | 
				
			||||||
static inline void mmap_unlock(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_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length);
 | 
				
			||||||
void tlb_set_dirty(CPUState *cpu, target_ulong vaddr);
 | 
					void tlb_set_dirty(CPUState *cpu, target_ulong vaddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user