Revert "Fix and cleanup IPCOP_shm* ipc calls handling"
authorRiku Voipio <riku.voipio@nokia.com>
Mon, 20 Apr 2009 14:31:58 +0000 (17:31 +0300)
committerRiku Voipio <riku.voipio@nokia.com>
Mon, 20 Apr 2009 14:31:58 +0000 (17:31 +0300)
This reverts commit 58dfbf5143162fe32ca2b797828cce7b8ff89b53.

Conflicts:

linux-user/syscall.c

linux-user/syscall.c

index 6319865..e615dd0 100644 (file)
@@ -1932,12 +1932,14 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
 }
 #endif
 
+#ifdef TARGET_NR_ipc
 #define N_SHM_REGIONS  32
 
 static struct shm_region {
     abi_ulong  start;
     abi_ulong  size;
 } shm_regions[N_SHM_REGIONS];
+#endif
 
 struct target_ipc_perm
 {
@@ -2430,224 +2432,6 @@ end:
     return ret;
 }
 
-struct target_shmid_ds
-{
-    struct target_ipc_perm shm_perm;
-    abi_ulong shm_segsz;
-    abi_ulong shm_atime;
-#if TARGET_ABI_BITS == 32
-    abi_ulong __unused1;
-#endif
-    abi_ulong shm_dtime;
-#if TARGET_ABI_BITS == 32
-    abi_ulong __unused2;
-#endif
-    abi_ulong shm_ctime;
-#if TARGET_ABI_BITS == 32
-    abi_ulong __unused3;
-#endif
-    int shm_cpid;
-    int shm_lpid;
-    abi_ulong shm_nattch;
-    unsigned long int __unused4;
-    unsigned long int __unused5;
-};
-
-static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
-                                               abi_ulong target_addr)
-{
-    struct target_shmid_ds *target_sd;
-
-    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
-        return -TARGET_EFAULT;
-    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
-        return -TARGET_EFAULT;
-    __put_user(target_sd->shm_segsz, &host_sd->shm_segsz);
-    __put_user(target_sd->shm_atime, &host_sd->shm_atime);
-    __put_user(target_sd->shm_dtime, &host_sd->shm_dtime);
-    __put_user(target_sd->shm_ctime, &host_sd->shm_ctime);
-    __put_user(target_sd->shm_cpid, &host_sd->shm_cpid);
-    __put_user(target_sd->shm_lpid, &host_sd->shm_lpid);
-    __put_user(target_sd->shm_nattch, &host_sd->shm_nattch);
-    unlock_user_struct(target_sd, target_addr, 0);
-    return 0;
-}
-
-static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
-                                               struct shmid_ds *host_sd)
-{
-    struct target_shmid_ds *target_sd;
-
-    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
-        return -TARGET_EFAULT;
-    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
-        return -TARGET_EFAULT;
-    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
-    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
-    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
-    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
-    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
-    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
-    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
-    unlock_user_struct(target_sd, target_addr, 1);
-    return 0;
-}
-
-struct  target_shminfo {
-    abi_ulong shmmax;
-    abi_ulong shmmin;
-    abi_ulong shmmni;
-    abi_ulong shmseg;
-    abi_ulong shmall;
-};
-
-static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
-                                              struct shminfo *host_shminfo)
-{
-    struct target_shminfo *target_shminfo;
-    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
-        return -TARGET_EFAULT;
-    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
-    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
-    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
-    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
-    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
-    unlock_user_struct(target_shminfo, target_addr, 1);
-    return 0;
-}
-
-struct target_shm_info {
-    int used_ids;
-    abi_ulong shm_tot;
-    abi_ulong shm_rss;
-    abi_ulong shm_swp;
-    abi_ulong swap_attempts;
-    abi_ulong swap_successes;
-};
-
-static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
-                                               struct shm_info *host_shm_info)
-{
-    struct target_shm_info *target_shm_info;
-    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
-        return -TARGET_EFAULT;
-    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
-    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
-    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
-    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
-    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
-    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
-    unlock_user_struct(target_shm_info, target_addr, 1);
-    return 0;
-}
-
-static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
-{
-    struct shmid_ds dsarg;
-    struct shminfo shminfo;
-    struct shm_info shm_info;
-    abi_long ret = -TARGET_EINVAL;
-
-    cmd &= 0xff;
-
-    switch(cmd) {
-    case IPC_STAT:
-    case IPC_SET:
-    case SHM_STAT:
-        if (target_to_host_shmid_ds(&dsarg, buf))
-            return -TARGET_EFAULT;
-        ret = get_errno(shmctl(shmid, cmd, &dsarg));
-        if (host_to_target_shmid_ds(buf, &dsarg))
-            return -TARGET_EFAULT;
-        break;
-    case IPC_INFO:
-        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
-        if (host_to_target_shminfo(buf, &shminfo))
-            return -TARGET_EFAULT;
-        break;
-    case SHM_INFO:
-        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
-        if (host_to_target_shm_info(buf, &shm_info))
-            return -TARGET_EFAULT;
-        break;
-    case IPC_RMID:
-    case SHM_LOCK:
-    case SHM_UNLOCK:
-        ret = get_errno(shmctl(shmid, cmd, NULL));
-        break;
-    }
-
-    return ret;
-}
-
-static inline abi_long do_shmat(int shmid, abi_ulong shmaddr, int shmflg,
-                                unsigned long *raddr)
-{
-    abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size);
-    abi_long ret;
-    struct shmid_ds shm_info;
-    int i;
-
-    /* find out the length of the shared memory segment */
-    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
-    if (is_error(ret)) {
-        /* can't get length, bail out */
-        return get_errno(ret);
-    }
-
-    mmap_lock();
-
-    if (shmaddr)
-        *raddr = (unsigned long) shmat(shmid, g2h(shmaddr), shmflg);
-    else {
-        abi_ulong mmap_start;
-
-        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
-
-        if (mmap_start == -1) {
-            errno = ENOMEM;
-            *raddr = -1;
-        } else
-            *raddr = (unsigned long) shmat(shmid, g2h(mmap_start),
-                                           shmflg | SHM_REMAP);
-    }
-
-    if (*raddr == -1) {
-        mmap_unlock();
-        return get_errno(*raddr);
-    }
-
-    page_set_flags(h2g(*raddr), h2g(*raddr) + shm_info.shm_segsz,
-                   PAGE_VALID | PAGE_READ |
-                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
-
-    for (i = 0; i < N_SHM_REGIONS; i++) {
-        if (shm_regions[i].start == 0) {
-            shm_regions[i].start = h2g(*raddr);
-            shm_regions[i].size = shm_info.shm_segsz;
-            break;
-        }
-    }
-
-    mmap_unlock();
-    return 0;
-}
-
-static inline abi_long do_shmdt(abi_ulong shmaddr)
-{
-    int i;
-
-    for (i = 0; i < N_SHM_REGIONS; ++i) {
-        if (shm_regions[i].start == shmaddr) {
-            shm_regions[i].start = 0;
-            page_set_flags(shmaddr, shm_regions[i].size, 0);
-            break;
-        }
-    }
-
-    return get_errno(shmdt(g2h(shmaddr)));
-}
-
 #ifdef TARGET_NR_ipc
 /* ??? This only works with linear mappings.  */
 /* do_ipc() must return target values and target errnos. */
@@ -2657,6 +2441,8 @@ static abi_long do_ipc(unsigned int call, int first,
 {
     int version;
     abi_long ret = 0;
+    struct shmid_ds shm_info;
+    int i;
 
     version = call >> 16;
     call &= 0xffff;
@@ -2711,40 +2497,72 @@ static abi_long do_ipc(unsigned int call, int first,
         break;
 
     case IPCOP_shmat:
-        switch (version) {
-        default:
-            {
-                unsigned long raddr;
-
-                ret = do_shmat(first, ptr, second, &raddr);
-                if (ret)
-                    break;
-
-                ret = put_user_ual(raddr, third);
+        {
+            abi_ulong raddr;
+            void *host_addr;
+            /* SHM_* flags are the same on all linux platforms */
+            host_addr = shmat(first, (void *)g2h(ptr), second);
+            if (host_addr == (void *)-1) {
+                ret = get_errno((long)host_addr);
                 break;
             }
-        case 1:
-            ret = -TARGET_EINVAL;
-            break;
+            raddr = h2g((unsigned long)host_addr);
+            /* find out the length of the shared memory segment */
+            
+            ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
+            if (is_error(ret)) {
+                /* can't get length, bail out */
+                shmdt(host_addr);
+                break;
+            }
+            page_set_flags(raddr, raddr + shm_info.shm_segsz,
+                           PAGE_VALID | PAGE_READ |
+                           ((second & SHM_RDONLY)? 0: PAGE_WRITE));
+            for (i = 0; i < N_SHM_REGIONS; ++i) {
+                if (shm_regions[i].start == 0) {
+                    shm_regions[i].start = raddr;
+                    shm_regions[i].size = shm_info.shm_segsz;
+                    break;
+                }
+            }
+            if (put_user_ual(raddr, third))
+                return -TARGET_EFAULT;
+            ret = 0;
         }
-        break;
-
+       break;
     case IPCOP_shmdt:
-        ret = do_shmdt(ptr);
-        break;
+       for (i = 0; i < N_SHM_REGIONS; ++i) {
+           if (shm_regions[i].start == ptr) {
+               shm_regions[i].start = 0;
+               page_set_flags(ptr, shm_regions[i].size, 0);
+               break;
+           }
+       }
+       ret = get_errno(shmdt((void *)g2h(ptr)));
+       break;
 
     case IPCOP_shmget:
-        ret = get_errno(shmget(first, second, third));
-        break;
+       /* IPC_* flag values are the same on all linux platforms */
+       ret = get_errno(shmget(first, second, third));
+       break;
 
+       /* IPC_* and SHM_* command values are the same on all linux platforms */
     case IPCOP_shmctl:
-        ret = do_shmctl(first, second, third);
+        switch(second) {
+        case IPC_RMID:
+        case SHM_LOCK:
+        case SHM_UNLOCK:
+            ret = get_errno(shmctl(first, second, NULL));
+            break;
+        default:
+            goto unimplemented;
+        }
         break;
-
     default:
-        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
-        ret = -TARGET_ENOSYS;
-        break;
+    unimplemented:
+       gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
+       ret = -TARGET_ENOSYS;
+       break;
     }
     return ret;
 }