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:
Richard Henderson 2022-08-10 13:52:50 -07:00
parent f3b2b81b6f
commit cdf7130851
3 changed files with 42 additions and 62 deletions

View File

@ -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)
{ {

View File

@ -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. */
/* /*

View File

@ -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);