* [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation @ 2011-04-09 11:02 Khansa Butt 2011-04-12 21:32 ` Aurelien Jarno 0 siblings, 1 reply; 9+ messages in thread From: Khansa Butt @ 2011-04-09 11:02 UTC (permalink / raw) To: qemu-devel; +Cc: aurelien, Nathan Froyd [-- Attachment #1: Type: text/plain, Size: 6011 bytes --] >From e96e20e50cada1c9e1b65de5925281cdd5659746 Mon Sep 17 00:00:00 2001 From: Ehsan-ul-Haq & Khansa Butt <khansa@kics.edu.pk> Date: Sat, 9 Apr 2011 10:51:22 +0500 Subject: [PATCH 1/2] Support for MIPS64 user mode emulation Signed-off-by: Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt < khansa@kics.edu.pk> --- configure | 1 + default-configs/mips64-linux-user.mak | 1 + linux-user/elfload.c | 2 +- linux-user/main.c | 29 +++++++++++++++++++++++++++-- linux-user/mips64/syscall.h | 3 +++ linux-user/signal.c | 3 ++- target-mips/translate.c | 1 + 7 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 default-configs/mips64-linux-user.mak diff --git a/configure b/configure index ae97e11..d1f7867 100755 --- a/configure +++ b/configure @@ -1039,6 +1039,7 @@ m68k-linux-user \ microblaze-linux-user \ microblazeel-linux-user \ mips-linux-user \ +mips64-linux-user \ mipsel-linux-user \ ppc-linux-user \ ppc64-linux-user \ diff --git a/default-configs/mips64-linux-user.mak b/default-configs/mips64-linux-user.mak new file mode 100644 index 0000000..1598bfc --- /dev/null +++ b/default-configs/mips64-linux-user.mak @@ -0,0 +1 @@ +# Default configuration for mips64-linux-user diff --git a/linux-user/elfload.c b/linux-user/elfload.c index fe5410e..2832a33 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1384,7 +1384,7 @@ static void load_elf_image(const char *image_name, int image_fd, vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr); vaddr_ps = TARGET_ELF_PAGESTART(vaddr); - error = target_mmap(vaddr_ps, eppnt->p_filesz + vaddr_po, + error = target_mmap(vaddr_ps, eppnt->p_memsz + vaddr_po, elf_prot, MAP_PRIVATE | MAP_FIXED, image_fd, eppnt->p_offset - vaddr_po); if (error == -1) { diff --git a/linux-user/main.c b/linux-user/main.c index e651bfd..a7f4955 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1937,6 +1937,14 @@ static int do_store_exclusive(CPUMIPSState *env) int d; addr = env->lladdr; +#if defined(TARGET_MIPS64) +/* For MIPS64 on 32 bit host there is a need to make +* the page accessible to which the above 'addr' is belonged */ +#if HOST_LONG_BITS == 32 + int flag = PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_WRITE_ORG; + page_set_flags(addr, addr + 4096, flag); +#endif +#endif page_addr = addr & TARGET_PAGE_MASK; start_exclusive(); mmap_lock(); @@ -1978,7 +1986,8 @@ static int do_store_exclusive(CPUMIPSState *env) void cpu_loop(CPUMIPSState *env) { target_siginfo_t info; - int trapnr, ret; + int trapnr; + abi_long ret; unsigned int syscall_num; for(;;) { @@ -1987,7 +1996,11 @@ void cpu_loop(CPUMIPSState *env) cpu_exec_end(env); switch(trapnr) { case EXCP_SYSCALL: +#if defined(TARGET_MIPS64) + syscall_num = env->active_tc.gpr[2] - 5000; +#else syscall_num = env->active_tc.gpr[2] - 4000; +#endif env->active_tc.PC += 4; if (syscall_num >= sizeof(mips_syscall_args)) { ret = -ENOSYS; @@ -2008,12 +2021,22 @@ void cpu_loop(CPUMIPSState *env) default: break; } +#if defined(TARGET_MIPS64) + ret = do_syscall(env, env->active_tc.gpr[2], + env->active_tc.gpr[4], + env->active_tc.gpr[5], + env->active_tc.gpr[6], + env->active_tc.gpr[7], + env->active_tc.gpr[8], + env->active_tc.gpr[9]); +#else ret = do_syscall(env, env->active_tc.gpr[2], env->active_tc.gpr[4], env->active_tc.gpr[5], env->active_tc.gpr[6], env->active_tc.gpr[7], arg5, arg6/*, arg7, arg8*/); +#endif } if (ret == -TARGET_QEMU_ESIGRETURN) { /* Returning from a successful sigreturn syscall. @@ -2935,7 +2958,9 @@ int main(int argc, char **argv, char **envp) #endif #elif defined(TARGET_MIPS) #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) - cpu_model = "20Kc"; + /* we use this model so that we can decode MIPS64r2 + reserved instruction */ + cpu_model = "MIPS64R2-generic"; #else cpu_model = "24Kf"; #endif diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h index 668a2b9..ec65653 100644 --- a/linux-user/mips64/syscall.h +++ b/linux-user/mips64/syscall.h @@ -218,4 +218,7 @@ struct target_pt_regs { +/* Nasty hack: define a fake errno value for use by sigreturn. */ +#define TARGET_QEMU_ESIGRETURN 255 + #define UNAME_MACHINE "mips64" diff --git a/linux-user/signal.c b/linux-user/signal.c index ce033e9..a3d49dd 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -2413,7 +2413,8 @@ void sparc64_get_context(CPUSPARCState *env) #endif #elif defined(TARGET_ABI_MIPSN64) -# warning signal handling not implemented +/* This line is commented out to avoid compile time error */ +/* # warning signal handling not implemented */ static void setup_frame(int sig, struct target_sigaction *ka, target_sigset_t *set, CPUState *env) diff --git a/target-mips/translate.c b/target-mips/translate.c index 0f93e2a..63c2563 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -12694,6 +12694,7 @@ void cpu_reset (CPUMIPSState *env) env->hflags |= MIPS_HFLAG_FPU; } #ifdef TARGET_MIPS64 + env->hflags |= MIPS_HFLAG_UX; if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { env->hflags |= MIPS_HFLAG_F64; } -- 1.7.3.4 [-- Attachment #2: Type: text/html, Size: 8107 bytes --] ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation 2011-04-09 11:02 [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation Khansa Butt @ 2011-04-12 21:32 ` Aurelien Jarno 2011-04-25 11:54 ` Khansa Butt 0 siblings, 1 reply; 9+ messages in thread From: Aurelien Jarno @ 2011-04-12 21:32 UTC (permalink / raw) To: Khansa Butt; +Cc: qemu-devel, Nathan Froyd [I don't know very well linux-user, it would be nice to Cc: Riku Voipio, the linux-user maintainer for the next version.] On Sat, Apr 09, 2011 at 04:02:31PM +0500, Khansa Butt wrote: > From e96e20e50cada1c9e1b65de5925281cdd5659746 Mon Sep 17 00:00:00 2001 > From: Ehsan-ul-Haq & Khansa Butt <khansa@kics.edu.pk> > Date: Sat, 9 Apr 2011 10:51:22 +0500 > Subject: [PATCH 1/2] Support for MIPS64 user mode emulation > > > Signed-off-by: Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt < > khansa@kics.edu.pk> > --- > configure | 1 + > default-configs/mips64-linux-user.mak | 1 + > linux-user/elfload.c | 2 +- > linux-user/main.c | 29 +++++++++++++++++++++++++++-- > linux-user/mips64/syscall.h | 3 +++ > linux-user/signal.c | 3 ++- > target-mips/translate.c | 1 + > 7 files changed, 36 insertions(+), 4 deletions(-) > create mode 100644 default-configs/mips64-linux-user.mak > > diff --git a/configure b/configure > index ae97e11..d1f7867 100755 > --- a/configure > +++ b/configure > @@ -1039,6 +1039,7 @@ m68k-linux-user \ > microblaze-linux-user \ > microblazeel-linux-user \ > mips-linux-user \ > +mips64-linux-user \ > mipsel-linux-user \ > ppc-linux-user \ > ppc64-linux-user \ > diff --git a/default-configs/mips64-linux-user.mak > b/default-configs/mips64-linux-user.mak > new file mode 100644 > index 0000000..1598bfc > --- /dev/null > +++ b/default-configs/mips64-linux-user.mak > @@ -0,0 +1 @@ > +# Default configuration for mips64-linux-user > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > index fe5410e..2832a33 100644 > --- a/linux-user/elfload.c > +++ b/linux-user/elfload.c > @@ -1384,7 +1384,7 @@ static void load_elf_image(const char *image_name, int > image_fd, > vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr); > vaddr_ps = TARGET_ELF_PAGESTART(vaddr); > > - error = target_mmap(vaddr_ps, eppnt->p_filesz + vaddr_po, > + error = target_mmap(vaddr_ps, eppnt->p_memsz + vaddr_po, What is the goal of this change? If the mmapped aread is bigger than the file size rounded up to te page size, it will cause a SIGBUS. > elf_prot, MAP_PRIVATE | MAP_FIXED, > image_fd, eppnt->p_offset - vaddr_po); > if (error == -1) { > diff --git a/linux-user/main.c b/linux-user/main.c > index e651bfd..a7f4955 100644 > --- a/linux-user/main.c > +++ b/linux-user/main.c > @@ -1937,6 +1937,14 @@ static int do_store_exclusive(CPUMIPSState *env) > int d; > > addr = env->lladdr; > +#if defined(TARGET_MIPS64) > +/* For MIPS64 on 32 bit host there is a need to make > +* the page accessible to which the above 'addr' is belonged */ > +#if HOST_LONG_BITS == 32 > + int flag = PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_WRITE_ORG; > + page_set_flags(addr, addr + 4096, flag); > +#endif > +#endif I don't really see the reason why this should be done that way. Are you trying to run MIPS32 binaries compiled for 8kB page size? > page_addr = addr & TARGET_PAGE_MASK; > start_exclusive(); > mmap_lock(); > @@ -1978,7 +1986,8 @@ static int do_store_exclusive(CPUMIPSState *env) > void cpu_loop(CPUMIPSState *env) > { > target_siginfo_t info; > - int trapnr, ret; > + int trapnr; > + abi_long ret; > unsigned int syscall_num; > > for(;;) { > @@ -1987,7 +1996,11 @@ void cpu_loop(CPUMIPSState *env) > cpu_exec_end(env); > switch(trapnr) { > case EXCP_SYSCALL: > +#if defined(TARGET_MIPS64) > + syscall_num = env->active_tc.gpr[2] - 5000; > +#else > syscall_num = env->active_tc.gpr[2] - 4000; > +#endif > env->active_tc.PC += 4; > if (syscall_num >= sizeof(mips_syscall_args)) { I don't think you can do it like that. mips_syscall_args corresponds to a table of 32-bit syscalls, which have totally different numbers than 64-bit syscalls. It's not a simple shift by 1000. See for example pread64 is 4200 is 32-bit, 5016 in 64-bit. > ret = -ENOSYS; > @@ -2008,12 +2021,22 @@ void cpu_loop(CPUMIPSState *env) > default: > break; > } > +#if defined(TARGET_MIPS64) > + ret = do_syscall(env, env->active_tc.gpr[2], > + env->active_tc.gpr[4], > + env->active_tc.gpr[5], > + env->active_tc.gpr[6], > + env->active_tc.gpr[7], > + env->active_tc.gpr[8], > + env->active_tc.gpr[9]); > +#else > ret = do_syscall(env, env->active_tc.gpr[2], > env->active_tc.gpr[4], > env->active_tc.gpr[5], > env->active_tc.gpr[6], > env->active_tc.gpr[7], > arg5, arg6/*, arg7, arg8*/); > +#endif > } > if (ret == -TARGET_QEMU_ESIGRETURN) { > /* Returning from a successful sigreturn syscall. > @@ -2935,7 +2958,9 @@ int main(int argc, char **argv, char **envp) > #endif > #elif defined(TARGET_MIPS) > #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) > - cpu_model = "20Kc"; > + /* we use this model so that we can decode MIPS64r2 > + reserved instruction */ > + cpu_model = "MIPS64R2-generic"; > #else > cpu_model = "24Kf"; > #endif > diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h > index 668a2b9..ec65653 100644 > --- a/linux-user/mips64/syscall.h > +++ b/linux-user/mips64/syscall.h > @@ -218,4 +218,7 @@ struct target_pt_regs { > > > > +/* Nasty hack: define a fake errno value for use by sigreturn. */ > +#define TARGET_QEMU_ESIGRETURN 255 > + > #define UNAME_MACHINE "mips64" > diff --git a/linux-user/signal.c b/linux-user/signal.c > index ce033e9..a3d49dd 100644 > --- a/linux-user/signal.c > +++ b/linux-user/signal.c > @@ -2413,7 +2413,8 @@ void sparc64_get_context(CPUSPARCState *env) > #endif > #elif defined(TARGET_ABI_MIPSN64) > > -# warning signal handling not implemented > +/* This line is commented out to avoid compile time error */ > +/* # warning signal handling not implemented */ Wouldn't it be possible to implement signal handling instead? > static void setup_frame(int sig, struct target_sigaction *ka, > target_sigset_t *set, CPUState *env) > diff --git a/target-mips/translate.c b/target-mips/translate.c > index 0f93e2a..63c2563 100644 > --- a/target-mips/translate.c > +++ b/target-mips/translate.c > @@ -12694,6 +12694,7 @@ void cpu_reset (CPUMIPSState *env) > env->hflags |= MIPS_HFLAG_FPU; > } > #ifdef TARGET_MIPS64 > + env->hflags |= MIPS_HFLAG_UX; > if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { > env->hflags |= MIPS_HFLAG_F64; > } > -- > 1.7.3.4 -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurelien@aurel32.net http://www.aurel32.net ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation 2011-04-12 21:32 ` Aurelien Jarno @ 2011-04-25 11:54 ` Khansa Butt 2011-04-29 9:01 ` Aurelien Jarno 0 siblings, 1 reply; 9+ messages in thread From: Khansa Butt @ 2011-04-25 11:54 UTC (permalink / raw) To: Aurelien Jarno, Riku Voipio; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 8830 bytes --] please see inline comments highlighted in red color. On Wed, Apr 13, 2011 at 2:32 AM, Aurelien Jarno <aurelien@aurel32.net>wrote: > [I don't know very well linux-user, it would be nice to Cc: Riku Voipio, > the linux-user maintainer for the next version.] > > On Sat, Apr 09, 2011 at 04:02:31PM +0500, Khansa Butt wrote: > > From e96e20e50cada1c9e1b65de5925281cdd5659746 Mon Sep 17 00:00:00 2001 > > From: Ehsan-ul-Haq & Khansa Butt <khansa@kics.edu.pk> > > Date: Sat, 9 Apr 2011 10:51:22 +0500 > > Subject: [PATCH 1/2] Support for MIPS64 user mode emulation > > > > > > Signed-off-by: Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt < > > khansa@kics.edu.pk> > > --- > > configure | 1 + > > default-configs/mips64-linux-user.mak | 1 + > > linux-user/elfload.c | 2 +- > > linux-user/main.c | 29 > +++++++++++++++++++++++++++-- > > linux-user/mips64/syscall.h | 3 +++ > > linux-user/signal.c | 3 ++- > > target-mips/translate.c | 1 + > > 7 files changed, 36 insertions(+), 4 deletions(-) > > create mode 100644 default-configs/mips64-linux-user.mak > > > > diff --git a/configure b/configure > > index ae97e11..d1f7867 100755 > > --- a/configure > > +++ b/configure > > @@ -1039,6 +1039,7 @@ m68k-linux-user \ > > microblaze-linux-user \ > > microblazeel-linux-user \ > > mips-linux-user \ > > +mips64-linux-user \ > > mipsel-linux-user \ > > ppc-linux-user \ > > ppc64-linux-user \ > > diff --git a/default-configs/mips64-linux-user.mak > > b/default-configs/mips64-linux-user.mak > > new file mode 100644 > > index 0000000..1598bfc > > --- /dev/null > > +++ b/default-configs/mips64-linux-user.mak > > @@ -0,0 +1 @@ > > +# Default configuration for mips64-linux-user > > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > > index fe5410e..2832a33 100644 > > --- a/linux-user/elfload.c > > +++ b/linux-user/elfload.c > > @@ -1384,7 +1384,7 @@ static void load_elf_image(const char *image_name, > int > > image_fd, > > vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr); > > vaddr_ps = TARGET_ELF_PAGESTART(vaddr); > > > > - error = target_mmap(vaddr_ps, eppnt->p_filesz + vaddr_po, > > + error = target_mmap(vaddr_ps, eppnt->p_memsz + vaddr_po, > > What is the goal of this change? If the mmapped aread is bigger than the > file size rounded up to te page size, it will cause a SIGBUS. > > > elf_prot, MAP_PRIVATE | MAP_FIXED, > > image_fd, eppnt->p_offset - vaddr_po); > > if (error == -1) { > > diff --git a/linux-user/main.c b/linux-user/main.c > > index e651bfd..a7f4955 100644 > > --- a/linux-user/main.c > > +++ b/linux-user/main.c > > @@ -1937,6 +1937,14 @@ static int do_store_exclusive(CPUMIPSState *env) > > int d; > > > > addr = env->lladdr; > > +#if defined(TARGET_MIPS64) > > +/* For MIPS64 on 32 bit host there is a need to make > > +* the page accessible to which the above 'addr' is belonged */ > > +#if HOST_LONG_BITS == 32 > > + int flag = PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_WRITE_ORG; > > + page_set_flags(addr, addr + 4096, flag); > > +#endif > > +#endif > > I don't really see the reason why this should be done that way. Are you > trying to run MIPS32 binaries compiled for 8kB page size? > this change is needed when we run MIPS64 ELF on 32 bit x86 host. MIPS64 ELF contains 36 bit address. load_elf_image() at /home/khansa/testpatch/qemu/linux-user/elfload.c: QEMU contains these lines /* Round addresses to page boundaries. */ loaddr &= qemu_host_page_mask; hiaddr = HOST_PAGE_ALIGN(hiaddr); when QEMU run on 32 bit x86 the above two variables are rounded to 32 bit value while these should be 36 bits as these come from MIPS64 ELF.and then for these rounded address l1_map is initialized in page_find_alloc(). in case of SCD(store condition double ) instruction of MIPS64r2 when we have to check load linked address its again 36 bit so it will make an index(addr >> TARGET_PAGE_BITS) for which l1_map is no valid entry, returning 0 value and we got segmentation fault. this is the reason we did following changes in main.c do_store_exclusive() +#if HOST_LONG_BITS == 32 > + int flag = PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_WRITE_ORG; > + page_set_flags(addr, addr + 4096, flag); > +#endif Please give comments on this > > > page_addr = addr & TARGET_PAGE_MASK; > > start_exclusive(); > > mmap_lock(); > > @@ -1978,7 +1986,8 @@ static int do_store_exclusive(CPUMIPSState *env) > > void cpu_loop(CPUMIPSState *env) > > { > > target_siginfo_t info; > > - int trapnr, ret; > > + int trapnr; > > + abi_long ret; > > unsigned int syscall_num; > > > > for(;;) { > > @@ -1987,7 +1996,11 @@ void cpu_loop(CPUMIPSState *env) > > cpu_exec_end(env); > > switch(trapnr) { > > case EXCP_SYSCALL: > > +#if defined(TARGET_MIPS64) > > + syscall_num = env->active_tc.gpr[2] - 5000; > > +#else > > syscall_num = env->active_tc.gpr[2] - 4000; > > +#endif > > env->active_tc.PC += 4; > > if (syscall_num >= sizeof(mips_syscall_args)) { > > I don't think you can do it like that. mips_syscall_args corresponds to > a table of 32-bit syscalls, which have totally different numbers than > 64-bit syscalls. It's not a simple shift by 1000. See for example > pread64 is 4200 is 32-bit, 5016 in 64-bit. > > > ret = -ENOSYS; > > @@ -2008,12 +2021,22 @@ void cpu_loop(CPUMIPSState *env) > > default: > > break; > > } > > +#if defined(TARGET_MIPS64) > > + ret = do_syscall(env, env->active_tc.gpr[2], > > + env->active_tc.gpr[4], > > + env->active_tc.gpr[5], > > + env->active_tc.gpr[6], > > + env->active_tc.gpr[7], > > + env->active_tc.gpr[8], > > + env->active_tc.gpr[9]); > > +#else > > ret = do_syscall(env, env->active_tc.gpr[2], > > env->active_tc.gpr[4], > > env->active_tc.gpr[5], > > env->active_tc.gpr[6], > > env->active_tc.gpr[7], > > arg5, arg6/*, arg7, arg8*/); > > +#endif > > } > > if (ret == -TARGET_QEMU_ESIGRETURN) { > > /* Returning from a successful sigreturn syscall. > > @@ -2935,7 +2958,9 @@ int main(int argc, char **argv, char **envp) > > #endif > > #elif defined(TARGET_MIPS) > > #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) > > - cpu_model = "20Kc"; > > + /* we use this model so that we can decode MIPS64r2 > > + reserved instruction */ > > + cpu_model = "MIPS64R2-generic"; > > #else > > cpu_model = "24Kf"; > > #endif > > diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h > > index 668a2b9..ec65653 100644 > > --- a/linux-user/mips64/syscall.h > > +++ b/linux-user/mips64/syscall.h > > @@ -218,4 +218,7 @@ struct target_pt_regs { > > > > > > > > +/* Nasty hack: define a fake errno value for use by sigreturn. */ > > +#define TARGET_QEMU_ESIGRETURN 255 > > + > > #define UNAME_MACHINE "mips64" > > diff --git a/linux-user/signal.c b/linux-user/signal.c > > index ce033e9..a3d49dd 100644 > > --- a/linux-user/signal.c > > +++ b/linux-user/signal.c > > @@ -2413,7 +2413,8 @@ void sparc64_get_context(CPUSPARCState *env) > > #endif > > #elif defined(TARGET_ABI_MIPSN64) > > > > -# warning signal handling not implemented > > +/* This line is commented out to avoid compile time error */ > > +/* # warning signal handling not implemented */ > > Wouldn't it be possible to implement signal handling instead? > > > static void setup_frame(int sig, struct target_sigaction *ka, > > target_sigset_t *set, CPUState *env) > > diff --git a/target-mips/translate.c b/target-mips/translate.c > > index 0f93e2a..63c2563 100644 > > --- a/target-mips/translate.c > > +++ b/target-mips/translate.c > > @@ -12694,6 +12694,7 @@ void cpu_reset (CPUMIPSState *env) > > env->hflags |= MIPS_HFLAG_FPU; > > } > > #ifdef TARGET_MIPS64 > > + env->hflags |= MIPS_HFLAG_UX; > > if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { > > env->hflags |= MIPS_HFLAG_F64; > > } > > -- > > 1.7.3.4 > > > -- > Aurelien Jarno GPG: 1024D/F1BCDB73 > aurelien@aurel32.net http://www.aurel32.net > [-- Attachment #2: Type: text/html, Size: 11687 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation 2011-04-25 11:54 ` Khansa Butt @ 2011-04-29 9:01 ` Aurelien Jarno 2011-04-30 5:25 ` Khansa Butt ` (3 more replies) 0 siblings, 4 replies; 9+ messages in thread From: Aurelien Jarno @ 2011-04-29 9:01 UTC (permalink / raw) To: Khansa Butt; +Cc: Riku Voipio, qemu-devel On Mon, Apr 25, 2011 at 04:54:19PM +0500, Khansa Butt wrote: > please see inline comments highlighted in red color. > > On Wed, Apr 13, 2011 at 2:32 AM, Aurelien Jarno <aurelien@aurel32.net>wrote: > > > [I don't know very well linux-user, it would be nice to Cc: Riku Voipio, > > the linux-user maintainer for the next version.] > > > > On Sat, Apr 09, 2011 at 04:02:31PM +0500, Khansa Butt wrote: > > > From e96e20e50cada1c9e1b65de5925281cdd5659746 Mon Sep 17 00:00:00 2001 > > > From: Ehsan-ul-Haq & Khansa Butt <khansa@kics.edu.pk> > > > Date: Sat, 9 Apr 2011 10:51:22 +0500 > > > Subject: [PATCH 1/2] Support for MIPS64 user mode emulation > > > > > > > > > Signed-off-by: Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt < > > > khansa@kics.edu.pk> > > > --- > > > configure | 1 + > > > default-configs/mips64-linux-user.mak | 1 + > > > linux-user/elfload.c | 2 +- > > > linux-user/main.c | 29 > > +++++++++++++++++++++++++++-- > > > linux-user/mips64/syscall.h | 3 +++ > > > linux-user/signal.c | 3 ++- > > > target-mips/translate.c | 1 + > > > 7 files changed, 36 insertions(+), 4 deletions(-) > > > create mode 100644 default-configs/mips64-linux-user.mak > > > > > > diff --git a/configure b/configure > > > index ae97e11..d1f7867 100755 > > > --- a/configure > > > +++ b/configure > > > @@ -1039,6 +1039,7 @@ m68k-linux-user \ > > > microblaze-linux-user \ > > > microblazeel-linux-user \ > > > mips-linux-user \ > > > +mips64-linux-user \ > > > mipsel-linux-user \ > > > ppc-linux-user \ > > > ppc64-linux-user \ > > > diff --git a/default-configs/mips64-linux-user.mak > > > b/default-configs/mips64-linux-user.mak > > > new file mode 100644 > > > index 0000000..1598bfc > > > --- /dev/null > > > +++ b/default-configs/mips64-linux-user.mak > > > @@ -0,0 +1 @@ > > > +# Default configuration for mips64-linux-user > > > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > > > index fe5410e..2832a33 100644 > > > --- a/linux-user/elfload.c > > > +++ b/linux-user/elfload.c > > > @@ -1384,7 +1384,7 @@ static void load_elf_image(const char *image_name, > > int > > > image_fd, > > > vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr); > > > vaddr_ps = TARGET_ELF_PAGESTART(vaddr); > > > > > > - error = target_mmap(vaddr_ps, eppnt->p_filesz + vaddr_po, > > > + error = target_mmap(vaddr_ps, eppnt->p_memsz + vaddr_po, > > > > What is the goal of this change? If the mmapped aread is bigger than the > > file size rounded up to te page size, it will cause a SIGBUS. > > > > > elf_prot, MAP_PRIVATE | MAP_FIXED, > > > image_fd, eppnt->p_offset - vaddr_po); > > > if (error == -1) { > > > diff --git a/linux-user/main.c b/linux-user/main.c > > > index e651bfd..a7f4955 100644 > > > --- a/linux-user/main.c > > > +++ b/linux-user/main.c > > > @@ -1937,6 +1937,14 @@ static int do_store_exclusive(CPUMIPSState *env) > > > int d; > > > > > > addr = env->lladdr; > > > +#if defined(TARGET_MIPS64) > > > +/* For MIPS64 on 32 bit host there is a need to make > > > +* the page accessible to which the above 'addr' is belonged */ > > > +#if HOST_LONG_BITS == 32 > > > + int flag = PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_WRITE_ORG; > > > + page_set_flags(addr, addr + 4096, flag); > > > +#endif > > > +#endif > > > > I don't really see the reason why this should be done that way. Are you > > trying to run MIPS32 binaries compiled for 8kB page size? > > > > > > this change is needed when we run MIPS64 ELF on 32 bit x86 host. MIPS64 ELF > contains 36 bit address. Actually it can contains up to 62-bit address there (all the user mapped space). > load_elf_image() at /home/khansa/testpatch/qemu/linux-user/elfload.c: QEMU > contains these lines > /* Round addresses to page boundaries. */ > loaddr &= qemu_host_page_mask; > hiaddr = HOST_PAGE_ALIGN(hiaddr); > when QEMU run on 32 bit x86 the above two variables are rounded to 32 bit > value while these should be 36 bits as these come from MIPS64 ELF.and then It is correct to truncate them, as the address space of the host is smaller. It's just based on the fact that programs only need a subset of the 62 bit address space. > for these rounded address l1_map is initialized in page_find_alloc(). > in case of SCD(store condition double ) instruction of MIPS64r2 when we have > to check load linked address its again 36 bit so it will make an index(addr > >> TARGET_PAGE_BITS) for which l1_map is no valid entry, returning 0 value > and we got segmentation fault. this is the reason we did following changes > in main.c do_store_exclusive() No, the load linked address register size, as well as the shift is actually implementation dependent. On old 64-bit MIPS implementation and MIPS32 core it is a 32-bit register and a 4-bit shift, where as on MIPS64 cores it is a 64-bit register and a 0-bit shift. In any case this value is the *physical address*, not the *virtual address*, hence we have to workaround that by saving the virtual address in the linux-user code. For linux-user, the full 64-bit address is saved in env->lladdr. What I don't understand is why the address passed to the scd instruction is not an address rounder to 32-bit, it should match the rounded address from elfload.c. Anyway, I don't doubt there is a problem, but clearly the solution of creating a fake page at this address is clearly the wrong way to go. -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurelien@aurel32.net http://www.aurel32.net ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation 2011-04-29 9:01 ` Aurelien Jarno @ 2011-04-30 5:25 ` Khansa Butt 2011-05-03 11:38 ` Khansa Butt ` (2 subsequent siblings) 3 siblings, 0 replies; 9+ messages in thread From: Khansa Butt @ 2011-04-30 5:25 UTC (permalink / raw) To: Aurelien Jarno; +Cc: Riku Voipio, qemu-devel [-- Attachment #1: Type: text/plain, Size: 6760 bytes --] Please see comments highlighted in green. On Fri, Apr 29, 2011 at 2:01 PM, Aurelien Jarno <aurelien@aurel32.net>wrote: > On Mon, Apr 25, 2011 at 04:54:19PM +0500, Khansa Butt wrote: > > please see inline comments highlighted in red color. > > > > On Wed, Apr 13, 2011 at 2:32 AM, Aurelien Jarno <aurelien@aurel32.net > >wrote: > > > > > [I don't know very well linux-user, it would be nice to Cc: Riku > Voipio, > > > the linux-user maintainer for the next version.] > > > > > > On Sat, Apr 09, 2011 at 04:02:31PM +0500, Khansa Butt wrote: > > > > From e96e20e50cada1c9e1b65de5925281cdd5659746 Mon Sep 17 00:00:00 > 2001 > > > > From: Ehsan-ul-Haq & Khansa Butt <khansa@kics.edu.pk> > > > > Date: Sat, 9 Apr 2011 10:51:22 +0500 > > > > Subject: [PATCH 1/2] Support for MIPS64 user mode emulation > > > > > > > > > > > > Signed-off-by: Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt > < > > > > khansa@kics.edu.pk> > > > > --- > > > > configure | 1 + > > > > default-configs/mips64-linux-user.mak | 1 + > > > > linux-user/elfload.c | 2 +- > > > > linux-user/main.c | 29 > > > +++++++++++++++++++++++++++-- > > > > linux-user/mips64/syscall.h | 3 +++ > > > > linux-user/signal.c | 3 ++- > > > > target-mips/translate.c | 1 + > > > > 7 files changed, 36 insertions(+), 4 deletions(-) > > > > create mode 100644 default-configs/mips64-linux-user.mak > > > > > > > > diff --git a/configure b/configure > > > > index ae97e11..d1f7867 100755 > > > > --- a/configure > > > > +++ b/configure > > > > @@ -1039,6 +1039,7 @@ m68k-linux-user \ > > > > microblaze-linux-user \ > > > > microblazeel-linux-user \ > > > > mips-linux-user \ > > > > +mips64-linux-user \ > > > > mipsel-linux-user \ > > > > ppc-linux-user \ > > > > ppc64-linux-user \ > > > > diff --git a/default-configs/mips64-linux-user.mak > > > > b/default-configs/mips64-linux-user.mak > > > > new file mode 100644 > > > > index 0000000..1598bfc > > > > --- /dev/null > > > > +++ b/default-configs/mips64-linux-user.mak > > > > @@ -0,0 +1 @@ > > > > +# Default configuration for mips64-linux-user > > > > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > > > > index fe5410e..2832a33 100644 > > > > --- a/linux-user/elfload.c > > > > +++ b/linux-user/elfload.c > > > > @@ -1384,7 +1384,7 @@ static void load_elf_image(const char > *image_name, > > > int > > > > image_fd, > > > > vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr); > > > > vaddr_ps = TARGET_ELF_PAGESTART(vaddr); > > > > > > > > - error = target_mmap(vaddr_ps, eppnt->p_filesz + > vaddr_po, > > > > + error = target_mmap(vaddr_ps, eppnt->p_memsz + vaddr_po, > > > > > > What is the goal of this change? If the mmapped aread is bigger than > the > > > file size rounded up to te page size, it will cause a SIGBUS. > > > > > > > elf_prot, MAP_PRIVATE | MAP_FIXED, > > > > image_fd, eppnt->p_offset - > vaddr_po); > > > > if (error == -1) { > > > > diff --git a/linux-user/main.c b/linux-user/main.c > > > > index e651bfd..a7f4955 100644 > > > > --- a/linux-user/main.c > > > > +++ b/linux-user/main.c > > > > @@ -1937,6 +1937,14 @@ static int do_store_exclusive(CPUMIPSState > *env) > > > > int d; > > > > > > > > addr = env->lladdr; > > > > +#if defined(TARGET_MIPS64) > > > > +/* For MIPS64 on 32 bit host there is a need to make > > > > +* the page accessible to which the above 'addr' is belonged */ > > > > +#if HOST_LONG_BITS == 32 > > > > + int flag = PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_WRITE_ORG; > > > > + page_set_flags(addr, addr + 4096, flag); > > > > +#endif > > > > +#endif > > > > > > I don't really see the reason why this should be done that way. Are you > > > trying to run MIPS32 binaries compiled for 8kB page size? > > > > > > > > > > > this change is needed when we run MIPS64 ELF on 32 bit x86 host. MIPS64 > ELF > > contains 36 bit address. > > Actually it can contains up to 62-bit address there (all the user mapped > space). > > > load_elf_image() at /home/khansa/testpatch/qemu/linux-user/elfload.c: > QEMU > > contains these lines > > /* Round addresses to page boundaries. */ > > loaddr &= qemu_host_page_mask; > > hiaddr = HOST_PAGE_ALIGN(hiaddr); > > when QEMU run on 32 bit x86 the above two variables are rounded to 32 bit > > value while these should be 36 bits as these come from MIPS64 ELF.and > then > > It is correct to truncate them, as the address space of the host is > smaller. It's just based on the fact that programs only need a subset of > the 62 bit address space. > > > for these rounded address l1_map is initialized in page_find_alloc(). > > in case of SCD(store condition double ) instruction of MIPS64r2 when we > have > > to check load linked address its again 36 bit so it will make an > index(addr > > >> TARGET_PAGE_BITS) for which l1_map is no valid entry, returning 0 > value > > and we got segmentation fault. this is the reason we did following > changes > > in main.c do_store_exclusive() > > No, the load linked address register size, as well as the shift is > actually implementation dependent. On old 64-bit MIPS implementation > and MIPS32 core it is a 32-bit register and a 4-bit shift, where as > on MIPS64 cores it is a 64-bit register and a 0-bit shift. > > In any case this value is the *physical address*, not the *virtual > address*, hence we have to workaround that by saving the virtual > address in the linux-user code. For linux-user, the full 64-bit address > is saved in env->lladdr. > > What I don't understand is why the address passed to the scd instruction > is not an address rounder to 32-bit, it should match the rounded address > from elfload.c. > It is the load linked address which is causing problem as it is full 64 bit address following is the QEMU code snippet, main.c:do_store_exclusive() addr = env->lladdr; page_addr = addr & TARGET_PAGE_MASK; start_exclusive(); mmap_lock(); flags = page_get_flags(page_addr); when 64 bit page_addr is sent to page_get_flags(), l1_map has zero entry for this address and it returns flags=0. what we can do is we can rounded lladdr to 32 bit as a workaround addr = env->lladdr; addr &= qemu_host_page_mask; Is this solution acceptable for you?? please give your comments. > > Anyway, I don't doubt there is a problem, but clearly the solution of > creating a fake page at this address is clearly the wrong way to go. > > -- > Aurelien Jarno GPG: 1024D/F1BCDB73 > aurelien@aurel32.net http://www.aurel32.net > [-- Attachment #2: Type: text/html, Size: 9748 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation 2011-04-29 9:01 ` Aurelien Jarno 2011-04-30 5:25 ` Khansa Butt @ 2011-05-03 11:38 ` Khansa Butt 2011-06-08 11:55 ` Khansa Butt 2011-06-16 6:14 ` Khansa Butt 3 siblings, 0 replies; 9+ messages in thread From: Khansa Butt @ 2011-05-03 11:38 UTC (permalink / raw) To: Aurelien Jarno, qemu-devel; +Cc: Riku Voipio [-- Attachment #1: Type: text/plain, Size: 7416 bytes --] I have made following changes addr = env->lladdr; addr &= qemu_host_page_mask; page_addr = addr & TARGET_PAGE_MASK; start_exclusive(); mmap_lock(); flags = page_get_flags(page_addr); now return to elfload.c I have a simple hello world mips64 binary for which I have two loadable segments so following rounded off address ranges passed to page_set_flags() in target_mmap() 1) 0x20000000 - 0x2008d000 2) 0x2009c000 - 0x200a6000 the last addresses of these ranges are not included in l1_map because of the for loop condition in page_set_flags() > for (addr = start, len = end - start; > len != 0; len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) { while env->lladdr after rounding off belong to 0x200a6000 so in order to include last address of above range i made following change error = target_mmap(vaddr_ps, eppnt->p_memsz + v addr_po, elf_prot, MAP_PRIVATE | MAP_FIXED, image_fd, eppnt->p_offset - vaddr_po); as mem size of a segment is greater than its file size but you told me that it will cause SIGBUS please suggest some solution for me in order to avoid target_mmap() change(i.e. filesz to memsz) or can I change condition of for loop some how so that one more iteration will run for the last address. On Fri, Apr 29, 2011 at 2:01 PM, Aurelien Jarno <aurelien@aurel32.net>wrote: > On Mon, Apr 25, 2011 at 04:54:19PM +0500, Khansa Butt wrote: > > please see inline comments highlighted in red color. > > > > On Wed, Apr 13, 2011 at 2:32 AM, Aurelien Jarno <aurelien@aurel32.net > >wrote: > > > > > [I don't know very well linux-user, it would be nice to Cc: Riku > Voipio, > > > the linux-user maintainer for the next version.] > > > > > > On Sat, Apr 09, 2011 at 04:02:31PM +0500, Khansa Butt wrote: > > > > From e96e20e50cada1c9e1b65de5925281cdd5659746 Mon Sep 17 00:00:00 > 2001 > > > > From: Ehsan-ul-Haq & Khansa Butt <khansa@kics.edu.pk> > > > > Date: Sat, 9 Apr 2011 10:51:22 +0500 > > > > Subject: [PATCH 1/2] Support for MIPS64 user mode emulation > > > > > > > > > > > > Signed-off-by: Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt > < > > > > khansa@kics.edu.pk> > > > > --- > > > > configure | 1 + > > > > default-configs/mips64-linux-user.mak | 1 + > > > > linux-user/elfload.c | 2 +- > > > > linux-user/main.c | 29 > > > +++++++++++++++++++++++++++-- > > > > linux-user/mips64/syscall.h | 3 +++ > > > > linux-user/signal.c | 3 ++- > > > > target-mips/translate.c | 1 + > > > > 7 files changed, 36 insertions(+), 4 deletions(-) > > > > create mode 100644 default-configs/mips64-linux-user.mak > > > > > > > > diff --git a/configure b/configure > > > > index ae97e11..d1f7867 100755 > > > > --- a/configure > > > > +++ b/configure > > > > @@ -1039,6 +1039,7 @@ m68k-linux-user \ > > > > microblaze-linux-user \ > > > > microblazeel-linux-user \ > > > > mips-linux-user \ > > > > +mips64-linux-user \ > > > > mipsel-linux-user \ > > > > ppc-linux-user \ > > > > ppc64-linux-user \ > > > > diff --git a/default-configs/mips64-linux-user.mak > > > > b/default-configs/mips64-linux-user.mak > > > > new file mode 100644 > > > > index 0000000..1598bfc > > > > --- /dev/null > > > > +++ b/default-configs/mips64-linux-user.mak > > > > @@ -0,0 +1 @@ > > > > +# Default configuration for mips64-linux-user > > > > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > > > > index fe5410e..2832a33 100644 > > > > --- a/linux-user/elfload.c > > > > +++ b/linux-user/elfload.c > > > > @@ -1384,7 +1384,7 @@ static void load_elf_image(const char > *image_name, > > > int > > > > image_fd, > > > > vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr); > > > > vaddr_ps = TARGET_ELF_PAGESTART(vaddr); > > > > > > > > - error = target_mmap(vaddr_ps, eppnt->p_filesz + > vaddr_po, > > > > + error = target_mmap(vaddr_ps, eppnt->p_memsz + vaddr_po, > > > > > > What is the goal of this change? If the mmapped aread is bigger than > the > > > file size rounded up to te page size, it will cause a SIGBUS. > > > > > > > elf_prot, MAP_PRIVATE | MAP_FIXED, > > > > image_fd, eppnt->p_offset - > vaddr_po); > > > > if (error == -1) { > > > > diff --git a/linux-user/main.c b/linux-user/main.c > > > > index e651bfd..a7f4955 100644 > > > > --- a/linux-user/main.c > > > > +++ b/linux-user/main.c > > > > @@ -1937,6 +1937,14 @@ static int do_store_exclusive(CPUMIPSState > *env) > > > > int d; > > > > > > > > addr = env->lladdr; > > > > +#if defined(TARGET_MIPS64) > > > > +/* For MIPS64 on 32 bit host there is a need to make > > > > +* the page accessible to which the above 'addr' is belonged */ > > > > +#if HOST_LONG_BITS == 32 > > > > + int flag = PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_WRITE_ORG; > > > > + page_set_flags(addr, addr + 4096, flag); > > > > +#endif > > > > +#endif > > > > > > I don't really see the reason why this should be done that way. Are you > > > trying to run MIPS32 binaries compiled for 8kB page size? > > > > > > > > > > > this change is needed when we run MIPS64 ELF on 32 bit x86 host. MIPS64 > ELF > > contains 36 bit address. > > Actually it can contains up to 62-bit address there (all the user mapped > space). > > > load_elf_image() at /home/khansa/testpatch/qemu/linux-user/elfload.c: > QEMU > > contains these lines > > /* Round addresses to page boundaries. */ > > loaddr &= qemu_host_page_mask; > > hiaddr = HOST_PAGE_ALIGN(hiaddr); > > when QEMU run on 32 bit x86 the above two variables are rounded to 32 bit > > value while these should be 36 bits as these come from MIPS64 ELF.and > then > > It is correct to truncate them, as the address space of the host is > smaller. It's just based on the fact that programs only need a subset of > the 62 bit address space. > > > for these rounded address l1_map is initialized in page_find_alloc(). > > in case of SCD(store condition double ) instruction of MIPS64r2 when we > have > > to check load linked address its again 36 bit so it will make an > index(addr > > >> TARGET_PAGE_BITS) for which l1_map is no valid entry, returning 0 > value > > and we got segmentation fault. this is the reason we did following > changes > > in main.c do_store_exclusive() > > No, the load linked address register size, as well as the shift is > actually implementation dependent. On old 64-bit MIPS implementation > and MIPS32 core it is a 32-bit register and a 4-bit shift, where as > on MIPS64 cores it is a 64-bit register and a 0-bit shift. > > In any case this value is the *physical address*, not the *virtual > address*, hence we have to workaround that by saving the virtual > address in the linux-user code. For linux-user, the full 64-bit address > is saved in env->lladdr. > > What I don't understand is why the address passed to the scd instruction > is not an address rounder to 32-bit, it should match the rounded address > from elfload.c. > > Anyway, I don't doubt there is a problem, but clearly the solution of > creating a fake page at this address is clearly the wrong way to go. > > -- > Aurelien Jarno GPG: 1024D/F1BCDB73 > aurelien@aurel32.net http://www.aurel32.net > [-- Attachment #2: Type: text/html, Size: 10884 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation 2011-04-29 9:01 ` Aurelien Jarno 2011-04-30 5:25 ` Khansa Butt 2011-05-03 11:38 ` Khansa Butt @ 2011-06-08 11:55 ` Khansa Butt 2011-06-16 6:14 ` Khansa Butt 3 siblings, 0 replies; 9+ messages in thread From: Khansa Butt @ 2011-06-08 11:55 UTC (permalink / raw) To: Aurelien Jarno; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 6493 bytes --] please see inline comments at the end. On Fri, Apr 29, 2011 at 2:01 PM, Aurelien Jarno <aurelien@aurel32.net>wrote: > On Mon, Apr 25, 2011 at 04:54:19PM +0500, Khansa Butt wrote: > > please see inline comments highlighted in red color. > > > > On Wed, Apr 13, 2011 at 2:32 AM, Aurelien Jarno <aurelien@aurel32.net > >wrote: > > > > > [I don't know very well linux-user, it would be nice to Cc: Riku > Voipio, > > > the linux-user maintainer for the next version.] > > > > > > On Sat, Apr 09, 2011 at 04:02:31PM +0500, Khansa Butt wrote: > > > > From e96e20e50cada1c9e1b65de5925281cdd5659746 Mon Sep 17 00:00:00 > 2001 > > > > From: Ehsan-ul-Haq & Khansa Butt <khansa@kics.edu.pk> > > > > Date: Sat, 9 Apr 2011 10:51:22 +0500 > > > > Subject: [PATCH 1/2] Support for MIPS64 user mode emulation > > > > > > > > > > > > Signed-off-by: Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt > < > > > > khansa@kics.edu.pk> > > > > --- > > > > configure | 1 + > > > > default-configs/mips64-linux-user.mak | 1 + > > > > linux-user/elfload.c | 2 +- > > > > linux-user/main.c | 29 > > > +++++++++++++++++++++++++++-- > > > > linux-user/mips64/syscall.h | 3 +++ > > > > linux-user/signal.c | 3 ++- > > > > target-mips/translate.c | 1 + > > > > 7 files changed, 36 insertions(+), 4 deletions(-) > > > > create mode 100644 default-configs/mips64-linux-user.mak > > > > > > > > diff --git a/configure b/configure > > > > index ae97e11..d1f7867 100755 > > > > --- a/configure > > > > +++ b/configure > > > > @@ -1039,6 +1039,7 @@ m68k-linux-user \ > > > > microblaze-linux-user \ > > > > microblazeel-linux-user \ > > > > mips-linux-user \ > > > > +mips64-linux-user \ > > > > mipsel-linux-user \ > > > > ppc-linux-user \ > > > > ppc64-linux-user \ > > > > diff --git a/default-configs/mips64-linux-user.mak > > > > b/default-configs/mips64-linux-user.mak > > > > new file mode 100644 > > > > index 0000000..1598bfc > > > > --- /dev/null > > > > +++ b/default-configs/mips64-linux-user.mak > > > > @@ -0,0 +1 @@ > > > > +# Default configuration for mips64-linux-user > > > > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > > > > index fe5410e..2832a33 100644 > > > > --- a/linux-user/elfload.c > > > > +++ b/linux-user/elfload.c > > > > @@ -1384,7 +1384,7 @@ static void load_elf_image(const char > *image_name, > > > int > > > > image_fd, > > > > vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr); > > > > vaddr_ps = TARGET_ELF_PAGESTART(vaddr); > > > > > > > > - error = target_mmap(vaddr_ps, eppnt->p_filesz + > vaddr_po, > > > > + error = target_mmap(vaddr_ps, eppnt->p_memsz + vaddr_po, > > > > > > What is the goal of this change? If the mmapped aread is bigger than > the > > > file size rounded up to te page size, it will cause a SIGBUS. > > > > > > > elf_prot, MAP_PRIVATE | MAP_FIXED, > > > > image_fd, eppnt->p_offset - > vaddr_po); > > > > if (error == -1) { > > > > diff --git a/linux-user/main.c b/linux-user/main.c > > > > index e651bfd..a7f4955 100644 > > > > --- a/linux-user/main.c > > > > +++ b/linux-user/main.c > > > > @@ -1937,6 +1937,14 @@ static int do_store_exclusive(CPUMIPSState > *env) > > > > int d; > > > > > > > > addr = env->lladdr; > > > > +#if defined(TARGET_MIPS64) > > > > +/* For MIPS64 on 32 bit host there is a need to make > > > > +* the page accessible to which the above 'addr' is belonged */ > > > > +#if HOST_LONG_BITS == 32 > > > > + int flag = PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_WRITE_ORG; > > > > + page_set_flags(addr, addr + 4096, flag); > > > > +#endif > > > > +#endif > > > > > > I don't really see the reason why this should be done that way. Are you > > > trying to run MIPS32 binaries compiled for 8kB page size? > > > > > > > > > > > this change is needed when we run MIPS64 ELF on 32 bit x86 host. MIPS64 > ELF > > contains 36 bit address. > > Actually it can contains up to 62-bit address there (all the user mapped > space). > > > load_elf_image() at /home/khansa/testpatch/qemu/linux-user/elfload.c: > QEMU > > contains these lines > > /* Round addresses to page boundaries. */ > > loaddr &= qemu_host_page_mask; > > hiaddr = HOST_PAGE_ALIGN(hiaddr); > > when QEMU run on 32 bit x86 the above two variables are rounded to 32 bit > > value while these should be 36 bits as these come from MIPS64 ELF.and > then > > It is correct to truncate them, as the address space of the host is > smaller. It's just based on the fact that programs only need a subset of > the 62 bit address space. > > > for these rounded address l1_map is initialized in page_find_alloc(). > > in case of SCD(store condition double ) instruction of MIPS64r2 when we > have > > to check load linked address its again 36 bit so it will make an > index(addr > > >> TARGET_PAGE_BITS) for which l1_map is no valid entry, returning 0 > value > > and we got segmentation fault. this is the reason we did following > changes > > in main.c do_store_exclusive() > > No, the load linked address register size, as well as the shift is > actually implementation dependent. On old 64-bit MIPS implementation > and MIPS32 core it is a 32-bit register and a 4-bit shift, where as > on MIPS64 cores it is a 64-bit register and a 0-bit shift. > > In any case this value is the *physical address*, not the *virtual > address*, hence we have to workaround that by saving the virtual > address in the linux-user code. For linux-user, the full 64-bit address > is saved in env->lladdr. > > What I don't understand is why the address passed to the scd instruction > is not an address rounder to 32-bit, it should match the rounded address > from elfload.c. > > Anyway, I don't doubt there is a problem, but clearly the solution of > creating a fake page at this address is clearly the wrong way to go. > if creating a fake page at this address is wrong way then tell me the following code snippet is acceptable to you as another workaround addr = env->lladdr; addr &= qemu_host_page_mask; page_addr = addr & TARGET_PAGE_MASK; start_exclusive(); now addr is rounded to 32 bit value! what would you like to say? > > -- > Aurelien Jarno GPG: 1024D/F1BCDB73 > aurelien@aurel32.net http://www.aurel32.net > [-- Attachment #2: Type: text/html, Size: 8555 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation 2011-04-29 9:01 ` Aurelien Jarno ` (2 preceding siblings ...) 2011-06-08 11:55 ` Khansa Butt @ 2011-06-16 6:14 ` Khansa Butt 2011-06-16 14:49 ` Richard Henderson 3 siblings, 1 reply; 9+ messages in thread From: Khansa Butt @ 2011-06-16 6:14 UTC (permalink / raw) To: Aurelien Jarno, Riku Voipio; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 3278 bytes --] This is the case for 64 bit guest user mode static binary on 32 bit host. Dynamically linked binary has not this problem see in elfload.c:load_elf_image() for (i = 0; i < ehdr->e_phnum; ++i) { if(phdr[i].p_type == PT_INTERP) dyn_link = 1; if (phdr[i].p_type == PT_LOAD) { abi_ulong a = phdr[i].p_vaddr; if (a < loaddr) { loaddr = a; } a += phdr[i].p_memsz; if (a > hiaddr) { hiaddr = a; } #ifdef CONFIG_USE_FDPIC ++info->nsegs; #endif } } load_addr = loaddr; at this point load_addr has 64 bit value. if (!have_guest_base && !reserved_va) { unsigned long host_start, real_start, host_size; /* Round addresses to page boundaries. */ loaddr &= qemu_host_page_mask; hiaddr = HOST_PAGE_ALIGN(hiaddr); because of above loaddr is rounded to 32 bit value and load_bias = load_addr - loaddr; now load_addr has a big value which is added to entry point address which causes problem. for my MIPS64 bit statically linked ELF the variables loaddr and hiaddr have 36 bit values. for probing guest_base these values are rounded to 32 bit as my underlying OS is 32 bit Fedore13 because of this load_bais has value = 0x100000000 this load_bias is then added to entry point address and mem and file size of the segment. and the addresses which are starting from 0x120000000 are now changed to 0x220000000. because of this when lladdr comes to SCD instruction in do_store_exclusive() it does not get valid l1_map entry. and because of which we made a fake page which was not correct way to do although it was working. so we did another workaround as follows linux-user/elfload.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index dcfeb7a..9ab3296 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1307,7 +1307,7 @@ static void load_elf_image(const char *image_name, int image_fd, struct elfhdr *ehdr = (struct elfhdr *)bprm_buf; struct elf_phdr *phdr; abi_ulong load_addr, load_bias, loaddr, hiaddr, error; - int i, retval; + int i, retval, dyn_link; const char *errmsg; /* First of all, some simple consistency checks */ @@ -1341,6 +1341,8 @@ static void load_elf_image(const char *image_name, int image_fd, amount of memory to handle that. */ loaddr = -1, hiaddr = 0; for (i = 0; i < ehdr->e_phnum; ++i) { + if(phdr[i].p_type == PT_INTERP) /* Is the ELF dynamically linked? + dyn_link = 1; if (phdr[i].p_type == PT_LOAD) { abi_ulong a = phdr[i].p_vaddr; if (a < loaddr) { @@ -1395,6 +1397,8 @@ static void load_elf_image(const char *image_name, int image_fd, } } host_size = hiaddr - loaddr; + if (!dyn_link) + /* ELF is statically linked */ + load_addr = loaddr; while (1) { /* Do not use mmap_find_vma here because that is limited to the guest address space. We are going to make the -- 1.7.0.1 please give some comments regarding this workaround [-- Attachment #2: Type: text/html, Size: 5593 bytes --] ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation 2011-06-16 6:14 ` Khansa Butt @ 2011-06-16 14:49 ` Richard Henderson 0 siblings, 0 replies; 9+ messages in thread From: Richard Henderson @ 2011-06-16 14:49 UTC (permalink / raw) To: Khansa Butt; +Cc: Riku Voipio, qemu-devel, Aurelien Jarno On 06/15/2011 11:14 PM, Khansa Butt wrote: > for my MIPS64 bit statically linked ELF the variables loaddr and hiaddr have 36 bit values. > for probing guest_base these values are rounded to 32 bit as my underlying OS is 32 bit Fedore13 Those last 8 words are the Real Problem. We don't support 64-bit address spaces in user mode from a 32-bit host. Some 64-bit guest tests accidentally work, but that's about all. Try again with a proper 64-bit host. r~ ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-06-16 14:50 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-04-09 11:02 [Qemu-devel] [PATCH 1/2] Support for MIPS64 user mode emulation Khansa Butt 2011-04-12 21:32 ` Aurelien Jarno 2011-04-25 11:54 ` Khansa Butt 2011-04-29 9:01 ` Aurelien Jarno 2011-04-30 5:25 ` Khansa Butt 2011-05-03 11:38 ` Khansa Butt 2011-06-08 11:55 ` Khansa Butt 2011-06-16 6:14 ` Khansa Butt 2011-06-16 14:49 ` Richard Henderson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).