[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 6/7] linux-user: handle POWERPC_EXCP_STCX
From: |
Nathan Froyd |
Subject: |
[Qemu-devel] [PATCH 6/7] linux-user: handle POWERPC_EXCP_STCX |
Date: |
Thu, 4 Jun 2009 11:52:01 -0700 |
We handle conditional stores as an exception so we can ensure that no
other thread is changing memory out from underneath us.
Signed-off-by: Nathan Froyd <address@hidden>
---
linux-user/main.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/linux-user/main.c b/linux-user/main.c
index dc39b05..7797e7f 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1088,6 +1088,63 @@ do {
\
log_cpu_state(env, 0);
\
} while (0)
+static int do_store_exclusive(CPUPPCState *env)
+{
+ target_ulong addr;
+ target_ulong page_addr;
+ target_ulong val;
+ int flags;
+ int segv = 0;
+
+ addr = env->reserve_ea;
+ page_addr = addr & TARGET_PAGE_MASK;
+ start_exclusive();
+ mmap_lock();
+ flags = page_get_flags(page_addr);
+ if ((flags & PAGE_READ) == 0) {
+ segv = 1;
+ } else {
+ int reg = env->reserve_info & 0x1f;
+ int size = (env->reserve_info >> 5) & 0xf;
+ int stored = 0;
+
+ if (addr == env->reserve_addr) {
+ switch (size) {
+ case 1: segv = get_user_u8(val, addr); break;
+ case 2: segv = get_user_u16(val, addr); break;
+ case 4: segv = get_user_u32(val, addr); break;
+#if defined(TARGET_PPC64)
+ case 8: segv = get_user_u64(val, addr); break;
+#endif
+ default: abort();
+ }
+ if (!segv && val == env->reserve_val) {
+ val = env->gpr[reg];
+ switch (size) {
+ case 1: segv = put_user_u8(val, addr); break;
+ case 2: segv = put_user_u16(val, addr); break;
+ case 4: segv = put_user_u32(val, addr); break;
+#if defined(TARGET_PPC64)
+ case 8: segv = put_user_u64(val, addr); break;
+#endif
+ default: abort();
+ }
+ if (!segv) {
+ stored = 1;
+ }
+ }
+ }
+ env->crf[0] = (stored << 1) | xer_so;
+ env->reserve_addr = (target_ulong)-1;
+ }
+ if (!segv) {
+ env->nip += 4;
+ }
+ mmap_unlock();
+ end_exclusive();
+ return segv;
+}
+
void cpu_loop(CPUPPCState *env)
{
target_siginfo_t info;
@@ -1095,7 +1152,9 @@ void cpu_loop(CPUPPCState *env)
uint32_t ret;
for(;;) {
+ cpu_exec_start(env);
trapnr = cpu_ppc_exec(env);
+ cpu_exec_end(env);
switch(trapnr) {
case POWERPC_EXCP_NONE:
/* Just go on */
@@ -1470,6 +1529,15 @@ void cpu_loop(CPUPPCState *env)
printf("syscall returned 0x%08x (%d)\n", ret, ret);
#endif
break;
+ case POWERPC_EXCP_STCX:
+ if (do_store_exclusive(env)) {
+ info.si_signo = TARGET_SIGSEGV;
+ info.si_errno = 0;
+ info.si_code = TARGET_SEGV_MAPERR;
+ info._sifields._sigfault._addr = env->nip;
+ queue_signal(env, info.si_signo, &info);
+ }
+ break;
case EXCP_DEBUG:
{
int sig;
--
1.6.3.2
- [Qemu-devel] [PATCH 0/7] target-ppc/linux-user: NPTL support, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 7/7] enable NPTL for ppc-linux-user targets in configure, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 2/7] target-ppc: fix cpu_clone_regs, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 1/7] linux-user: initialize mmap_mutex properly, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 5/7] target-ppc: add exceptions for conditional stores, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 3/7] target-ppc: add cpu_set_tls, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 6/7] linux-user: handle POWERPC_EXCP_STCX,
Nathan Froyd <=
- [Qemu-devel] [PATCH 4/7] target-ppc: retain l{w,d}arx loaded value, Nathan Froyd, 2009/06/04
- Re: [Qemu-devel] [PATCH 0/7] target-ppc/linux-user: NPTL support, malc, 2009/06/05
- Re: [Qemu-devel] [PATCH 0/7] target-ppc/linux-user: NPTL support, Miklos Vajna, 2009/06/09
- Re: [Qemu-devel] [PATCH 0/7] target-ppc/linux-user: NPTL support, Laurent Vivier, 2009/06/09