Pass a data size argument to do_unaligned_access(). It is unable to find if an access spans two pages without the data size in the call back function.
Signed-off-by: Yongbok Kim <yongbok....@imgtec.com> --- include/qom/cpu.h | 7 ++++--- softmmu_template.h | 24 ++++++++++++------------ target-alpha/cpu-qom.h | 3 ++- target-alpha/mem_helper.c | 3 ++- target-mips/cpu-qom.h | 3 ++- target-mips/op_helper.c | 2 +- target-sparc/cpu-qom.h | 3 ++- target-sparc/ldst_helper.c | 3 ++- target-xtensa/cpu-qom.h | 3 ++- target-xtensa/op_helper.c | 2 +- 10 files changed, 30 insertions(+), 23 deletions(-) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 39f0f19..6ba2dad 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -134,7 +134,8 @@ typedef struct CPUClass { void (*do_interrupt)(CPUState *cpu); CPUUnassignedAccess do_unassigned_access; void (*do_unaligned_access)(CPUState *cpu, vaddr addr, - int is_write, int is_user, uintptr_t retaddr); + int is_write, int is_user, uintptr_t retaddr, + unsigned size); bool (*virtio_is_big_endian)(CPUState *cpu); int (*memory_rw_debug)(CPUState *cpu, vaddr addr, uint8_t *buf, int len, bool is_write); @@ -591,11 +592,11 @@ static inline void cpu_unassigned_access(CPUState *cpu, hwaddr addr, static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr, int is_write, int is_user, - uintptr_t retaddr) + uintptr_t retaddr, unsigned size) { CPUClass *cc = CPU_GET_CLASS(cpu); - cc->do_unaligned_access(cpu, addr, is_write, is_user, retaddr); + cc->do_unaligned_access(cpu, addr, is_write, is_user, retaddr, size); } #endif diff --git a/softmmu_template.h b/softmmu_template.h index 16b0852..d896b9c 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -185,7 +185,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); } #endif if (!VICTIM_TLB_HIT(ADDR_READ)) { @@ -220,7 +220,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, do_unaligned_access: #ifdef ALIGNED_ONLY cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); #endif addr1 = addr & ~(DATA_SIZE - 1); addr2 = addr1 + DATA_SIZE; @@ -239,7 +239,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); } #endif @@ -273,7 +273,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); } #endif if (!VICTIM_TLB_HIT(ADDR_READ)) { @@ -308,7 +308,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, do_unaligned_access: #ifdef ALIGNED_ONLY cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); #endif addr1 = addr & ~(DATA_SIZE - 1); addr2 = addr1 + DATA_SIZE; @@ -327,7 +327,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); } #endif @@ -401,7 +401,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); } #endif if (!VICTIM_TLB_HIT(addr_write)) { @@ -433,7 +433,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, do_unaligned_access: #ifdef ALIGNED_ONLY cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); #endif /* XXX: not efficient, but simple */ /* Note: relies on the fact that tlb_fill() does not remove the @@ -453,7 +453,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); } #endif @@ -482,7 +482,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); } #endif if (!VICTIM_TLB_HIT(addr_write)) { @@ -514,7 +514,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, do_unaligned_access: #ifdef ALIGNED_ONLY cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); #endif /* XXX: not efficient, but simple */ /* Note: relies on the fact that tlb_fill() does not remove the @@ -534,7 +534,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE, - mmu_idx, retaddr); + mmu_idx, retaddr, DATA_SIZE); } #endif diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h index b01c6c8..273a8ed 100644 --- a/target-alpha/cpu-qom.h +++ b/target-alpha/cpu-qom.h @@ -86,6 +86,7 @@ hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); int alpha_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, - int is_write, int is_user, uintptr_t retaddr); + int is_write, int is_user, uintptr_t retaddr, + unsigned size); #endif diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c index fc4f57a..1d4666a 100644 --- a/target-alpha/mem_helper.c +++ b/target-alpha/mem_helper.c @@ -97,7 +97,8 @@ uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v) } void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr, - int is_write, int is_user, uintptr_t retaddr) + int is_write, int is_user, uintptr_t retaddr, + unsigned size) { AlphaCPU *cpu = ALPHA_CPU(cs); CPUAlphaState *env = &cpu->env; diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h index 4d6f9de..6d54314 100644 --- a/target-mips/cpu-qom.h +++ b/target-mips/cpu-qom.h @@ -86,6 +86,7 @@ hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); int mips_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); int mips_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, - int is_write, int is_user, uintptr_t retaddr); + int is_write, int is_user, uintptr_t retaddr, + unsigned size); #endif diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 73a8e45..ca5fe43 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -2208,7 +2208,7 @@ void helper_wait(CPUMIPSState *env) void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr, int access_type, int is_user, - uintptr_t retaddr) + uintptr_t retaddr, unsigned size) { MIPSCPU *cpu = MIPS_CPU(cs); CPUMIPSState *env = &cpu->env; diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h index 477c4d5..4bfbb84 100644 --- a/target-sparc/cpu-qom.h +++ b/target-sparc/cpu-qom.h @@ -83,6 +83,7 @@ int sparc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); int sparc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, int is_write, - int is_user, uintptr_t retaddr); + int is_user, uintptr_t retaddr, + unsigned size); #endif diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c index c7ad47d..7837d64 100644 --- a/target-sparc/ldst_helper.c +++ b/target-sparc/ldst_helper.c @@ -2420,7 +2420,8 @@ void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr, #if !defined(CONFIG_USER_ONLY) void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cs, vaddr addr, int is_write, - int is_user, uintptr_t retaddr) + int is_user, uintptr_t retaddr, + unsigned size) { SPARCCPU *cpu = SPARC_CPU(cs); CPUSPARCState *env = &cpu->env; diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h index 2258224..2508228 100644 --- a/target-xtensa/cpu-qom.h +++ b/target-xtensa/cpu-qom.h @@ -94,6 +94,7 @@ hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); int xtensa_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, - int is_write, int is_user, uintptr_t retaddr); + int is_write, int is_user, + uintptr_t retaddr, unsigned size); #endif diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index be657e6..0804791 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -33,7 +33,7 @@ #include "qemu/timer.h" void xtensa_cpu_do_unaligned_access(CPUState *cs, - vaddr addr, int is_write, int is_user, uintptr_t retaddr) + vaddr addr, int is_write, int is_user, uintptr_t retaddr, unsigned size) { XtensaCPU *cpu = XTENSA_CPU(cs); CPUXtensaState *env = &cpu->env; -- 1.7.5.4